refactor: unify directory structure — watchers/rules/executors (closes #39)

This commit is contained in:
2026-04-14 15:39:59 +00:00
parent 21a8c38040
commit 0e1e77177f
14 changed files with 74 additions and 65 deletions
+41 -41
View File
@@ -1,43 +1,43 @@
{
"$schema": "https://biomejs.dev/schemas/2.4.11/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true
},
"files": {
"ignoreUnknown": true,
"includes": ["packages/**/*.ts"]
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"suspicious": {
"noExplicitAny": "off"
},
"style": {
"noNonNullAssertion": "off"
}
}
},
"javascript": {
"formatter": {
"quoteStyle": "single",
"semicolons": "always"
}
},
"assist": {
"enabled": true,
"actions": {
"source": {
"organizeImports": "on"
}
}
}
"$schema": "https://biomejs.dev/schemas/2.4.11/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true
},
"files": {
"ignoreUnknown": true,
"includes": ["packages/**/*.ts"]
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"suspicious": {
"noExplicitAny": "off"
},
"style": {
"noNonNullAssertion": "off"
}
}
},
"javascript": {
"formatter": {
"quoteStyle": "single",
"semicolons": "always"
}
},
"assist": {
"enabled": true,
"actions": {
"source": {
"organizeImports": "on"
}
}
}
}
+3 -3
View File
@@ -18,15 +18,15 @@ import {
import {
MAX_RESTART_COUNT,
ROLLBACK_ERROR_THRESHOLD,
} from '../survival/constants.js';
import { rebuildHealth, survivalRules } from '../survival/index.js';
} from '../rules/constants.js';
import { rebuildHealth, survivalRules } from '../rules/index.js';
import {
autoRollback,
llmWatchdog,
processWatchdog,
resourceGuard,
type SurvivalSnapshot,
} from '../survival/rules.js';
} from '../rules/survival.js';
// ── Helpers ────────────────────────────────────────────────────
+6
View File
@@ -5,3 +5,9 @@ export {
type CursorEffect,
createCursorExecutor,
} from './cursor-agent.js';
export {
executeSurvivalEffect,
type SurvivalEffect,
type SurvivalExecDeps,
} from './survival.js';
@@ -5,7 +5,7 @@
import { beforeEach, describe, expect, jest, test } from 'bun:test';
import * as os from 'node:os';
import * as path from 'node:path';
import { executeSurvivalEffect, type SurvivalExecDeps } from './executors';
import { executeSurvivalEffect, type SurvivalExecDeps } from './survival.js';
// All mocks via dependency injection — NO global jest.mock to avoid cross-file pollution
const mockExecSync = jest.fn();
@@ -13,7 +13,7 @@ import * as os from 'node:os';
import * as path from 'node:path';
/** Allowlist pattern for safe shell arguments (service names, git refs, etc.) */
const SAFE_ARG = /^[a-zA-Z0-9._\/@:-]+$/;
const SAFE_ARG = /^[a-zA-Z0-9._/@:-]+$/;
export interface SurvivalEffect {
type: string;
+7 -2
View File
@@ -366,7 +366,12 @@ export {
// ── Built-in Rules ─────────────────────────────────────────────
export { adaptiveInterval, clampTick, dedup, errorBackoff } from './rules.js';
export {
adaptiveInterval,
clampTick,
dedup,
errorBackoff,
} from './rules/builtin.js';
// ── Watcher ────────────────────────────────────────────────────
@@ -384,7 +389,7 @@ export * from './watchers/index.js';
// ── Survival Layer ──────────────────────────────────────────────
export * from './survival/index.js';
export * from './rules/index.js';
// ── Executors ─────────────────────────────────────────────────
@@ -4,7 +4,7 @@
import { describe, expect, it } from 'bun:test';
import { adaptiveInterval, clampTick, dedup, errorBackoff } from './rules.js';
import { adaptiveInterval, clampTick, dedup, errorBackoff } from './builtin.js';
// Helper to apply rule with new onion middleware signature
async function apply<S, E>(
@@ -5,7 +5,7 @@
* adaptive intervals, effect deduplication.
*/
import type { Rule } from './index.js';
import type { Rule } from '../index.js';
/**
* Clamp tickMs within [min, max].
+10
View File
@@ -0,0 +1,10 @@
export { adaptiveInterval, clampTick, dedup, errorBackoff } from './builtin.js';
export {
ESSENTIAL_PROCESSES,
IDEMPOTENT_WINDOW_MS,
MAX_RESTART_COUNT,
ROLLBACK_ERROR_THRESHOLD,
ROLLBACK_WINDOW_MS,
} from './constants.js';
export { type HealthSnapshot, rebuildHealth } from './health.js';
export { type SurvivalSnapshot, survivalRules } from './survival.js';
@@ -3,7 +3,7 @@
*/
import { beforeEach, describe, expect, jest, test } from 'bun:test';
import { MAX_RESTART_COUNT, ROLLBACK_ERROR_THRESHOLD } from './constants';
import { MAX_RESTART_COUNT, ROLLBACK_ERROR_THRESHOLD } from './constants.js';
import {
autoRollback,
errorEscalate,
@@ -13,7 +13,7 @@ import {
panicRollback,
processWatchdog,
resourceGuard,
} from './rules';
} from './survival.js';
// Mock inner function
const mockInner = jest.fn(async () => [[], 15000]);
@@ -5,6 +5,7 @@
* Rules are applied in array order (first element is outermost layer).
*/
import type { SurvivalEffect } from '../executors/survival.js';
import type { Rule, Sensed } from '../index.js';
import type { ErrorLogData } from '../watchers/error-log.js';
import type { GatewayHealthData } from '../watchers/gateway-health.js';
@@ -18,7 +19,6 @@ import {
ROLLBACK_ERROR_THRESHOLD,
ROLLBACK_WINDOW_MS,
} from './constants.js';
import type { SurvivalEffect } from './executors.js';
import type { HealthSnapshot } from './health.js';
// Define proper type for survival snapshot
-12
View File
@@ -1,12 +0,0 @@
/**
* Survival layer exports
*/
export {
ESSENTIAL_PROCESSES,
IDEMPOTENT_WINDOW_MS,
MAX_RESTART_COUNT,
} from './constants.js';
export { executeSurvivalEffect, type SurvivalEffect } from './executors.js';
export { type HealthSnapshot, rebuildHealth } from './health.js';
export { type SurvivalSnapshot, survivalRules } from './rules.js';