@mindfoldhq/trellis 0.6.0-beta.2 → 0.6.0-beta.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cli/index.d.ts +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +58 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/commands/channel/adapters/claude.d.ts +29 -0
- package/dist/commands/channel/adapters/claude.d.ts.map +1 -0
- package/dist/commands/channel/adapters/claude.js +203 -0
- package/dist/commands/channel/adapters/claude.js.map +1 -0
- package/dist/commands/channel/adapters/codex.d.ts +85 -0
- package/dist/commands/channel/adapters/codex.d.ts.map +1 -0
- package/dist/commands/channel/adapters/codex.js +505 -0
- package/dist/commands/channel/adapters/codex.js.map +1 -0
- package/dist/commands/channel/adapters/index.d.ts +84 -0
- package/dist/commands/channel/adapters/index.d.ts.map +1 -0
- package/dist/commands/channel/adapters/index.js +115 -0
- package/dist/commands/channel/adapters/index.js.map +1 -0
- package/dist/commands/channel/adapters/types.d.ts +33 -0
- package/dist/commands/channel/adapters/types.d.ts.map +1 -0
- package/dist/commands/channel/adapters/types.js +2 -0
- package/dist/commands/channel/adapters/types.js.map +1 -0
- package/dist/commands/channel/agent-loader.d.ts +32 -0
- package/dist/commands/channel/agent-loader.d.ts.map +1 -0
- package/dist/commands/channel/agent-loader.js +154 -0
- package/dist/commands/channel/agent-loader.js.map +1 -0
- package/dist/commands/channel/context-loader.d.ts +26 -0
- package/dist/commands/channel/context-loader.d.ts.map +1 -0
- package/dist/commands/channel/context-loader.js +290 -0
- package/dist/commands/channel/context-loader.js.map +1 -0
- package/dist/commands/channel/context.d.ts +16 -0
- package/dist/commands/channel/context.d.ts.map +1 -0
- package/dist/commands/channel/context.js +83 -0
- package/dist/commands/channel/context.js.map +1 -0
- package/dist/commands/channel/create.d.ts +27 -0
- package/dist/commands/channel/create.d.ts.map +1 -0
- package/dist/commands/channel/create.js +39 -0
- package/dist/commands/channel/create.js.map +1 -0
- package/dist/commands/channel/dev-parse-trace.d.ts +14 -0
- package/dist/commands/channel/dev-parse-trace.d.ts.map +1 -0
- package/dist/commands/channel/dev-parse-trace.js +70 -0
- package/dist/commands/channel/dev-parse-trace.js.map +1 -0
- package/dist/commands/channel/guard.d.ts +150 -0
- package/dist/commands/channel/guard.d.ts.map +1 -0
- package/dist/commands/channel/guard.js +474 -0
- package/dist/commands/channel/guard.js.map +1 -0
- package/dist/commands/channel/index.d.ts +3 -0
- package/dist/commands/channel/index.d.ts.map +1 -0
- package/dist/commands/channel/index.js +531 -0
- package/dist/commands/channel/index.js.map +1 -0
- package/dist/commands/channel/interrupt.d.ts +10 -0
- package/dist/commands/channel/interrupt.d.ts.map +1 -0
- package/dist/commands/channel/interrupt.js +22 -0
- package/dist/commands/channel/interrupt.js.map +1 -0
- package/dist/commands/channel/kill.d.ts +7 -0
- package/dist/commands/channel/kill.d.ts.map +1 -0
- package/dist/commands/channel/kill.js +121 -0
- package/dist/commands/channel/kill.js.map +1 -0
- package/dist/commands/channel/list.d.ts +17 -0
- package/dist/commands/channel/list.d.ts.map +1 -0
- package/dist/commands/channel/list.js +233 -0
- package/dist/commands/channel/list.js.map +1 -0
- package/dist/commands/channel/messages.d.ts +15 -0
- package/dist/commands/channel/messages.d.ts.map +1 -0
- package/dist/commands/channel/messages.js +245 -0
- package/dist/commands/channel/messages.js.map +1 -0
- package/dist/commands/channel/rm.d.ts +27 -0
- package/dist/commands/channel/rm.d.ts.map +1 -0
- package/dist/commands/channel/rm.js +216 -0
- package/dist/commands/channel/rm.js.map +1 -0
- package/dist/commands/channel/run.d.ts +30 -0
- package/dist/commands/channel/run.d.ts.map +1 -0
- package/dist/commands/channel/run.js +130 -0
- package/dist/commands/channel/run.js.map +1 -0
- package/dist/commands/channel/send.d.ts +11 -0
- package/dist/commands/channel/send.d.ts.map +1 -0
- package/dist/commands/channel/send.js +24 -0
- package/dist/commands/channel/send.js.map +1 -0
- package/dist/commands/channel/spawn.d.ts +40 -0
- package/dist/commands/channel/spawn.d.ts.map +1 -0
- package/dist/commands/channel/spawn.js +244 -0
- package/dist/commands/channel/spawn.js.map +1 -0
- package/dist/commands/channel/store/events.d.ts +39 -0
- package/dist/commands/channel/store/events.d.ts.map +1 -0
- package/dist/commands/channel/store/events.js +87 -0
- package/dist/commands/channel/store/events.js.map +1 -0
- package/dist/commands/channel/store/filter.d.ts +3 -0
- package/dist/commands/channel/store/filter.d.ts.map +1 -0
- package/dist/commands/channel/store/filter.js +2 -0
- package/dist/commands/channel/store/filter.js.map +1 -0
- package/dist/commands/channel/store/lock.d.ts +23 -0
- package/dist/commands/channel/store/lock.d.ts.map +1 -0
- package/dist/commands/channel/store/lock.js +99 -0
- package/dist/commands/channel/store/lock.js.map +1 -0
- package/dist/commands/channel/store/paths.d.ts +63 -0
- package/dist/commands/channel/store/paths.d.ts.map +1 -0
- package/dist/commands/channel/store/paths.js +246 -0
- package/dist/commands/channel/store/paths.js.map +1 -0
- package/dist/commands/channel/store/schema.d.ts +27 -0
- package/dist/commands/channel/store/schema.d.ts.map +1 -0
- package/dist/commands/channel/store/schema.js +34 -0
- package/dist/commands/channel/store/schema.js.map +1 -0
- package/dist/commands/channel/store/thread-state.d.ts +5 -0
- package/dist/commands/channel/store/thread-state.d.ts.map +1 -0
- package/dist/commands/channel/store/thread-state.js +16 -0
- package/dist/commands/channel/store/thread-state.js.map +1 -0
- package/dist/commands/channel/store/watch.d.ts +19 -0
- package/dist/commands/channel/store/watch.d.ts.map +1 -0
- package/dist/commands/channel/store/watch.js +146 -0
- package/dist/commands/channel/store/watch.js.map +1 -0
- package/dist/commands/channel/supervisor/idle.d.ts +46 -0
- package/dist/commands/channel/supervisor/idle.d.ts.map +1 -0
- package/dist/commands/channel/supervisor/idle.js +72 -0
- package/dist/commands/channel/supervisor/idle.js.map +1 -0
- package/dist/commands/channel/supervisor/inbox.d.ts +30 -0
- package/dist/commands/channel/supervisor/inbox.d.ts.map +1 -0
- package/dist/commands/channel/supervisor/inbox.js +160 -0
- package/dist/commands/channel/supervisor/inbox.js.map +1 -0
- package/dist/commands/channel/supervisor/shutdown.d.ts +68 -0
- package/dist/commands/channel/supervisor/shutdown.d.ts.map +1 -0
- package/dist/commands/channel/supervisor/shutdown.js +146 -0
- package/dist/commands/channel/supervisor/shutdown.js.map +1 -0
- package/dist/commands/channel/supervisor/stdout.d.ts +51 -0
- package/dist/commands/channel/supervisor/stdout.d.ts.map +1 -0
- package/dist/commands/channel/supervisor/stdout.js +121 -0
- package/dist/commands/channel/supervisor/stdout.js.map +1 -0
- package/dist/commands/channel/supervisor/turns.d.ts +31 -0
- package/dist/commands/channel/supervisor/turns.d.ts.map +1 -0
- package/dist/commands/channel/supervisor/turns.js +45 -0
- package/dist/commands/channel/supervisor/turns.js.map +1 -0
- package/dist/commands/channel/supervisor/warning.d.ts +48 -0
- package/dist/commands/channel/supervisor/warning.d.ts.map +1 -0
- package/dist/commands/channel/supervisor/warning.js +77 -0
- package/dist/commands/channel/supervisor/warning.js.map +1 -0
- package/dist/commands/channel/supervisor.d.ts +59 -0
- package/dist/commands/channel/supervisor.d.ts.map +1 -0
- package/dist/commands/channel/supervisor.js +344 -0
- package/dist/commands/channel/supervisor.js.map +1 -0
- package/dist/commands/channel/text-body.d.ts +13 -0
- package/dist/commands/channel/text-body.d.ts.map +1 -0
- package/dist/commands/channel/text-body.js +47 -0
- package/dist/commands/channel/text-body.js.map +1 -0
- package/dist/commands/channel/threads.d.ts +39 -0
- package/dist/commands/channel/threads.d.ts.map +1 -0
- package/dist/commands/channel/threads.js +106 -0
- package/dist/commands/channel/threads.js.map +1 -0
- package/dist/commands/channel/title.d.ts +12 -0
- package/dist/commands/channel/title.d.ts.map +1 -0
- package/dist/commands/channel/title.js +24 -0
- package/dist/commands/channel/title.js.map +1 -0
- package/dist/commands/channel/wait.d.ts +17 -0
- package/dist/commands/channel/wait.d.ts.map +1 -0
- package/dist/commands/channel/wait.js +75 -0
- package/dist/commands/channel/wait.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +97 -42
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/mem.d.ts +13 -117
- package/dist/commands/mem.d.ts.map +1 -1
- package/dist/commands/mem.js +168 -1074
- package/dist/commands/mem.js.map +1 -1
- package/dist/commands/uninstall.d.ts.map +1 -1
- package/dist/commands/uninstall.js +28 -2
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +31 -111
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/upgrade.d.ts +28 -0
- package/dist/commands/upgrade.d.ts.map +1 -0
- package/dist/commands/upgrade.js +84 -0
- package/dist/commands/upgrade.js.map +1 -0
- package/dist/commands/workflow.d.ts +35 -0
- package/dist/commands/workflow.d.ts.map +1 -0
- package/dist/commands/workflow.js +219 -0
- package/dist/commands/workflow.js.map +1 -0
- package/dist/configurators/claude.d.ts.map +1 -1
- package/dist/configurators/claude.js +1 -0
- package/dist/configurators/claude.js.map +1 -1
- package/dist/configurators/codex.d.ts.map +1 -1
- package/dist/configurators/codex.js +5 -3
- package/dist/configurators/codex.js.map +1 -1
- package/dist/configurators/shared.js +4 -4
- package/dist/configurators/shared.js.map +1 -1
- package/dist/configurators/workflow.d.ts +8 -0
- package/dist/configurators/workflow.d.ts.map +1 -1
- package/dist/configurators/workflow.js +3 -2
- package/dist/configurators/workflow.js.map +1 -1
- package/dist/migrations/manifests/0.5.10.json +9 -0
- package/dist/migrations/manifests/0.5.11.json +16 -0
- package/dist/migrations/manifests/0.5.12.json +9 -0
- package/dist/migrations/manifests/0.5.13.json +9 -0
- package/dist/migrations/manifests/0.5.14.json +9 -0
- package/dist/migrations/manifests/0.5.15.json +9 -0
- package/dist/migrations/manifests/0.5.16.json +9 -0
- package/dist/migrations/manifests/0.5.17.json +9 -0
- package/dist/migrations/manifests/0.5.18.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.10.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.11.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.12.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.13.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.14.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.15.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.16.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.17.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.18.json +16 -0
- package/dist/migrations/manifests/0.6.0-beta.19.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.20.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.3.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.4.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.5.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.6.json +16 -0
- package/dist/migrations/manifests/0.6.0-beta.7.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.8.json +9 -0
- package/dist/migrations/manifests/0.6.0-beta.9.json +9 -0
- package/dist/templates/claude/agents/trellis-check.md +13 -7
- package/dist/templates/claude/agents/trellis-implement.md +8 -7
- package/dist/templates/claude/settings.json +4 -4
- package/dist/templates/codebuddy/agents/trellis-check.md +13 -7
- package/dist/templates/codebuddy/agents/trellis-implement.md +8 -7
- package/dist/templates/codebuddy/settings.json +4 -4
- package/dist/templates/codex/agents/trellis-check.toml +4 -4
- package/dist/templates/codex/agents/trellis-implement.toml +4 -4
- package/dist/templates/codex/config.toml +5 -3
- package/dist/templates/codex/hooks/session-start.py +205 -119
- package/dist/templates/codex/hooks.json +2 -2
- package/dist/templates/codex/skills/before-dev/SKILL.md +12 -6
- package/dist/templates/codex/skills/brainstorm/SKILL.md +69 -457
- package/dist/templates/codex/skills/check/SKILL.md +86 -18
- package/dist/templates/codex/skills/start/SKILL.md +33 -323
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-context-loading.md +7 -4
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-spec-structure.md +1 -1
- package/dist/templates/common/bundled-skills/trellis-meta/references/customize-local/change-workflow.md +3 -2
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/context-injection.md +5 -5
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/spec-system.md +1 -1
- package/dist/templates/common/bundled-skills/trellis-meta/references/local-architecture/task-system.md +35 -6
- package/dist/templates/common/bundled-skills/trellis-meta/references/platform-files/agents.md +5 -4
- package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/SKILL.md +41 -0
- package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/references/mcp-setup.md +90 -0
- package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/references/repository-analysis.md +59 -0
- package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/references/spec-task-planning.md +61 -0
- package/dist/templates/common/bundled-skills/trellis-spec-bootstarp/references/spec-writing.md +70 -0
- package/dist/templates/common/commands/continue.md +6 -5
- package/dist/templates/common/commands/start.md +9 -6
- package/dist/templates/common/skills/before-dev.md +12 -6
- package/dist/templates/common/skills/brainstorm.md +68 -504
- package/dist/templates/common/skills/check.md +7 -1
- package/dist/templates/copilot/hooks/session-start.py +219 -101
- package/dist/templates/copilot/hooks.json +2 -2
- package/dist/templates/copilot/prompts/before-dev.prompt.md +12 -6
- package/dist/templates/copilot/prompts/brainstorm.prompt.md +69 -457
- package/dist/templates/copilot/prompts/check.prompt.md +86 -18
- package/dist/templates/copilot/prompts/parallel.prompt.md +16 -8
- package/dist/templates/copilot/prompts/start.prompt.md +33 -367
- package/dist/templates/cursor/agents/trellis-check.md +13 -7
- package/dist/templates/cursor/agents/trellis-implement.md +8 -7
- package/dist/templates/cursor/hooks.json +1 -7
- package/dist/templates/droid/droids/trellis-check.md +13 -7
- package/dist/templates/droid/droids/trellis-implement.md +8 -7
- package/dist/templates/droid/settings.json +4 -4
- package/dist/templates/gemini/agents/trellis-check.md +11 -5
- package/dist/templates/gemini/agents/trellis-implement.md +7 -6
- package/dist/templates/gemini/settings.json +2 -2
- package/dist/templates/kiro/agents/trellis-check.json +1 -1
- package/dist/templates/kiro/agents/trellis-implement.json +1 -1
- package/dist/templates/markdown/spec/guides/code-reuse-thinking-guide.md.txt +127 -9
- package/dist/templates/markdown/spec/guides/cross-layer-thinking-guide.md.txt +171 -6
- package/dist/templates/markdown/spec/guides/cross-platform-thinking-guide.md.txt +333 -43
- package/dist/templates/markdown/spec/guides/index.md.txt +18 -0
- package/dist/templates/opencode/agents/trellis-check.md +13 -7
- package/dist/templates/opencode/agents/trellis-implement.md +9 -8
- package/dist/templates/opencode/lib/session-utils.js +212 -123
- package/dist/templates/opencode/lib/trellis-context.js +73 -11
- package/dist/templates/opencode/plugins/inject-subagent-context.js +131 -29
- package/dist/templates/opencode/plugins/inject-workflow-state.js +9 -5
- package/dist/templates/opencode/plugins/session-start.js +9 -1
- package/dist/templates/pi/agents/trellis-check.md +5 -4
- package/dist/templates/pi/agents/trellis-implement.md +5 -4
- package/dist/templates/pi/extensions/trellis/index.ts.txt +1357 -754
- package/dist/templates/qoder/agents/trellis-check.md +11 -5
- package/dist/templates/qoder/agents/trellis-implement.md +7 -6
- package/dist/templates/qoder/settings.json +4 -4
- package/dist/templates/shared-hooks/index.d.ts.map +1 -1
- package/dist/templates/shared-hooks/index.js +0 -1
- package/dist/templates/shared-hooks/index.js.map +1 -1
- package/dist/templates/shared-hooks/inject-subagent-context.py +36 -14
- package/dist/templates/shared-hooks/inject-workflow-state.py +40 -42
- package/dist/templates/shared-hooks/session-start.py +222 -171
- package/dist/templates/trellis/config.yaml +38 -0
- package/dist/templates/trellis/index.d.ts +1 -0
- package/dist/templates/trellis/index.d.ts.map +1 -1
- package/dist/templates/trellis/index.js +2 -0
- package/dist/templates/trellis/index.js.map +1 -1
- package/dist/templates/trellis/scripts/add_session.py +50 -24
- package/dist/templates/trellis/scripts/common/config.py +57 -1
- package/dist/templates/trellis/scripts/common/safe_commit.py +285 -0
- package/dist/templates/trellis/scripts/common/session_context.py +384 -137
- package/dist/templates/trellis/scripts/common/task_context.py +3 -3
- package/dist/templates/trellis/scripts/common/task_store.py +161 -15
- package/dist/templates/trellis/scripts/common/workflow_phase.py +7 -10
- package/dist/templates/trellis/scripts/task.py +3 -3
- package/dist/templates/trellis/workflow.md +119 -98
- package/dist/utils/cwd-guard.d.ts +38 -0
- package/dist/utils/cwd-guard.d.ts.map +1 -0
- package/dist/utils/cwd-guard.js +62 -0
- package/dist/utils/cwd-guard.js.map +1 -0
- package/dist/utils/file-writer.d.ts +13 -0
- package/dist/utils/file-writer.d.ts.map +1 -1
- package/dist/utils/file-writer.js +59 -1
- package/dist/utils/file-writer.js.map +1 -1
- package/dist/utils/manifest-prune.d.ts +61 -0
- package/dist/utils/manifest-prune.d.ts.map +1 -0
- package/dist/utils/manifest-prune.js +136 -0
- package/dist/utils/manifest-prune.js.map +1 -0
- package/dist/utils/task-json.d.ts +9 -42
- package/dist/utils/task-json.d.ts.map +1 -1
- package/dist/utils/task-json.js +8 -45
- package/dist/utils/task-json.js.map +1 -1
- package/dist/utils/template-hash.d.ts +32 -6
- package/dist/utils/template-hash.d.ts.map +1 -1
- package/dist/utils/template-hash.js +53 -31
- package/dist/utils/template-hash.js.map +1 -1
- package/dist/utils/uninstall-scrubbers.d.ts +1 -0
- package/dist/utils/uninstall-scrubbers.d.ts.map +1 -1
- package/dist/utils/uninstall-scrubbers.js +21 -0
- package/dist/utils/uninstall-scrubbers.js.map +1 -1
- package/dist/utils/workflow-resolver.d.ts +86 -0
- package/dist/utils/workflow-resolver.d.ts.map +1 -0
- package/dist/utils/workflow-resolver.js +265 -0
- package/dist/utils/workflow-resolver.js.map +1 -0
- package/package.json +9 -8
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Channel worker OOM guard policy.
|
|
3
|
+
*
|
|
4
|
+
* Resolves idle-cleanup TTL and live-worker budget from CLI flag /
|
|
5
|
+
* environment / project config / built-in defaults (in that precedence
|
|
6
|
+
* order), then scans the live worker registry inside a project bucket
|
|
7
|
+
* to enforce both constraints at spawn time.
|
|
8
|
+
*
|
|
9
|
+
* Boundary: this module lives in the CLI runtime layer. Core owns
|
|
10
|
+
* worker activity / `idleSince` projection; the supervisor owns process
|
|
11
|
+
* launch + signals. The guard only consumes that durable state and
|
|
12
|
+
* sends OS signals through pid files.
|
|
13
|
+
*/
|
|
14
|
+
import { type WorkerState } from "@mindfoldhq/trellis-core/channel";
|
|
15
|
+
/** Built-in default idle-cleanup TTL for spawned workers (5 minutes). */
|
|
16
|
+
export declare const DEFAULT_IDLE_TTL_MS: number;
|
|
17
|
+
/** Built-in default live-worker budget per project/scope. */
|
|
18
|
+
export declare const DEFAULT_MAX_LIVE_WORKERS = 6;
|
|
19
|
+
/** Env var override for the idle-cleanup TTL. */
|
|
20
|
+
export declare const ENV_IDLE_TIMEOUT = "TRELLIS_CHANNEL_WORKER_IDLE_TIMEOUT";
|
|
21
|
+
/** Env var override for the live-worker budget. */
|
|
22
|
+
export declare const ENV_MAX_LIVE_WORKERS = "TRELLIS_CHANNEL_MAX_LIVE_WORKERS";
|
|
23
|
+
export interface WorkerGuardConfig {
|
|
24
|
+
/** Idle-cleanup TTL in ms. `0` disables idle cleanup for new spawns. */
|
|
25
|
+
idleTimeoutMs: number;
|
|
26
|
+
/** Live-worker budget. `0` disables the spawn-time budget check. */
|
|
27
|
+
maxLiveWorkers: number;
|
|
28
|
+
}
|
|
29
|
+
export interface ResolveGuardOptions {
|
|
30
|
+
/** CLI `--idle-timeout` value (already millisecond-parsed). */
|
|
31
|
+
flagIdleTimeoutMs?: number;
|
|
32
|
+
/** CLI `--max-live-workers` value. */
|
|
33
|
+
flagMaxLiveWorkers?: number;
|
|
34
|
+
/** Override cwd for config lookup (default `process.cwd()`). */
|
|
35
|
+
cwd?: string;
|
|
36
|
+
/** Override env source (default `process.env`). */
|
|
37
|
+
env?: NodeJS.ProcessEnv;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Resolve the effective guard policy. Precedence:
|
|
41
|
+
* 1. CLI flag (`flag*Ms` / `flagMaxLiveWorkers`)
|
|
42
|
+
* 2. environment variable
|
|
43
|
+
* 3. `.trellis/config.yaml` `channel.worker_guard`
|
|
44
|
+
* 4. built-in default constant
|
|
45
|
+
*/
|
|
46
|
+
export declare function resolveWorkerGuardConfig(opts?: ResolveGuardOptions): WorkerGuardConfig;
|
|
47
|
+
interface ProjectGuardConfig {
|
|
48
|
+
idleTimeoutMs?: number;
|
|
49
|
+
maxLiveWorkers?: number;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Parse the `channel.worker_guard` section out of `.trellis/config.yaml`.
|
|
53
|
+
* Mirrors the lightweight line-scanner used elsewhere in update.ts so we
|
|
54
|
+
* don't pull in a YAML dependency just for this two-field section.
|
|
55
|
+
*/
|
|
56
|
+
export declare function loadWorkerGuardConfig(cwd: string): ProjectGuardConfig | undefined;
|
|
57
|
+
/** Exposed for unit tests. */
|
|
58
|
+
export declare function parseWorkerGuardSection(content: string): ProjectGuardConfig | undefined;
|
|
59
|
+
/**
|
|
60
|
+
* Live worker observed inside the spawn-time guard scan.
|
|
61
|
+
*/
|
|
62
|
+
export interface LiveWorker {
|
|
63
|
+
channel: string;
|
|
64
|
+
workerId: string;
|
|
65
|
+
state: WorkerState;
|
|
66
|
+
/** Supervisor pid that owns this worker, when readable + alive. */
|
|
67
|
+
supervisorPid?: number;
|
|
68
|
+
/** True when the OS command line still looks like this worker's supervisor. */
|
|
69
|
+
supervisorVerified?: boolean;
|
|
70
|
+
/** Worker child pid, when readable. */
|
|
71
|
+
workerPid?: number;
|
|
72
|
+
}
|
|
73
|
+
export interface ScanLiveWorkersOptions {
|
|
74
|
+
/** Project bucket key (default current). */
|
|
75
|
+
projectKey?: string;
|
|
76
|
+
/** Override channel root scan (default uses real channelRoot()). */
|
|
77
|
+
root?: string;
|
|
78
|
+
/** Override supervisor process verification (used by tests). */
|
|
79
|
+
isSupervisorProcess?: (pid: number, channel: string, worker: string) => boolean;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Enumerate live (non-terminal + supervisor-pid alive) workers across
|
|
83
|
+
* every channel in the given project bucket.
|
|
84
|
+
*/
|
|
85
|
+
export declare function scanLiveWorkers(opts?: ScanLiveWorkersOptions): LiveWorker[];
|
|
86
|
+
export declare function isSupervisorProcess(pid: number, channel: string, worker: string): boolean;
|
|
87
|
+
/**
|
|
88
|
+
* Pure predicate: is this live worker eligible for idle-cleanup right
|
|
89
|
+
* now? Mid-turn workers and workers without `idleSince` (e.g. they
|
|
90
|
+
* never spawned cleanly) are never killed by the guard.
|
|
91
|
+
*/
|
|
92
|
+
export declare function isIdleCleanupEligible(live: LiveWorker, idleTimeoutMs: number, now: number): boolean;
|
|
93
|
+
export interface CleanupResult {
|
|
94
|
+
killed: LiveWorker[];
|
|
95
|
+
failed: {
|
|
96
|
+
worker: LiveWorker;
|
|
97
|
+
error: string;
|
|
98
|
+
}[];
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Kill workers whose idle TTL has expired. Writes a one-shot shutdown
|
|
102
|
+
* reason sidecar before signalling the supervisor so the supervisor's
|
|
103
|
+
* existing shutdown funnel emits the single terminal `killed` event.
|
|
104
|
+
*
|
|
105
|
+
* Returns the workers that were signalled. Failures are collected — a
|
|
106
|
+
* dead pid or read race is not fatal; the next scan re-evaluates.
|
|
107
|
+
*/
|
|
108
|
+
export declare function cleanupExpiredIdleWorkers(candidates: LiveWorker[], idleTimeoutMs: number, opts?: {
|
|
109
|
+
project?: string;
|
|
110
|
+
now?: number;
|
|
111
|
+
}): Promise<CleanupResult>;
|
|
112
|
+
export interface EnforceBudgetInput {
|
|
113
|
+
/** Project bucket key (default current). */
|
|
114
|
+
projectKey?: string;
|
|
115
|
+
/** Override channel root scan path (used by tests). */
|
|
116
|
+
root?: string;
|
|
117
|
+
/** Effective guard policy. */
|
|
118
|
+
policy: WorkerGuardConfig;
|
|
119
|
+
/** Override `now` for deterministic tests. */
|
|
120
|
+
now?: number;
|
|
121
|
+
/** Override supervisor process verification (used by tests). */
|
|
122
|
+
isSupervisorProcess?: ScanLiveWorkersOptions["isSupervisorProcess"];
|
|
123
|
+
}
|
|
124
|
+
export interface EnforceBudgetResult {
|
|
125
|
+
/** Workers killed by expired-idle cleanup during this enforcement. */
|
|
126
|
+
cleaned: LiveWorker[];
|
|
127
|
+
/** Live workers remaining after cleanup. */
|
|
128
|
+
remaining: LiveWorker[];
|
|
129
|
+
/** True when a new spawn is allowed; false when budget is exceeded. */
|
|
130
|
+
allowed: boolean;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Run the spawn-time guard for a project bucket. Cleans expired idle
|
|
134
|
+
* workers, re-scans, then decides whether the live worker budget has
|
|
135
|
+
* room for one more spawn.
|
|
136
|
+
*/
|
|
137
|
+
export declare function enforceSpawnBudget(input: EnforceBudgetInput): Promise<EnforceBudgetResult>;
|
|
138
|
+
/** Build a multi-line, actionable overflow error string. */
|
|
139
|
+
export declare function formatBudgetOverflowError(args: {
|
|
140
|
+
projectKey: string;
|
|
141
|
+
live: LiveWorker[];
|
|
142
|
+
limit: number;
|
|
143
|
+
}): string;
|
|
144
|
+
/**
|
|
145
|
+
* Convenience helper: ensure `channelRoot()` is initialised before scan
|
|
146
|
+
* (otherwise the project dir may not yet exist on first spawn).
|
|
147
|
+
*/
|
|
148
|
+
export declare function ensureRootExists(): void;
|
|
149
|
+
export {};
|
|
150
|
+
//# sourceMappingURL=guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../../../src/commands/channel/guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH,OAAO,EAIL,KAAK,WAAW,EACjB,MAAM,kCAAkC,CAAC;AAY1C,yEAAyE;AACzE,eAAO,MAAM,mBAAmB,QAAgB,CAAC;AAEjD,6DAA6D;AAC7D,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAE1C,iDAAiD;AACjD,eAAO,MAAM,gBAAgB,wCAAwC,CAAC;AAEtE,mDAAmD;AACnD,eAAO,MAAM,oBAAoB,qCAAqC,CAAC;AAEvE,MAAM,WAAW,iBAAiB;IAChC,wEAAwE;IACxE,aAAa,EAAE,MAAM,CAAC;IACtB,oEAAoE;IACpE,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,+DAA+D;IAC/D,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,sCAAsC;IACtC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,gEAAgE;IAChE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CACzB;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,GAAE,mBAAwB,GAC7B,iBAAiB,CAmBnB;AAsDD,UAAU,kBAAkB;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,MAAM,GACV,kBAAkB,GAAG,SAAS,CAUhC;AAED,8BAA8B;AAC9B,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,GACd,kBAAkB,GAAG,SAAS,CAsDhC;AA+BD;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,WAAW,CAAC;IACnB,mEAAmE;IACnE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,+EAA+E;IAC/E,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,uCAAuC;IACvC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,sBAAsB;IACrC,4CAA4C;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,oEAAoE;IACpE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gEAAgE;IAChE,mBAAmB,CAAC,EAAE,CACpB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,KACX,OAAO,CAAC;CACd;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,IAAI,GAAE,sBAA2B,GAChC,UAAU,EAAE,CAiFd;AA+DD,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,GACb,OAAO,CAqBT;AAMD;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,UAAU,EAChB,aAAa,EAAE,MAAM,EACrB,GAAG,EAAE,MAAM,GACV,OAAO,CAST;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,MAAM,EAAE;QAAE,MAAM,EAAE,UAAU,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACjD;AAED;;;;;;;GAOG;AACH,wBAAsB,yBAAyB,CAC7C,UAAU,EAAE,UAAU,EAAE,EACxB,aAAa,EAAE,MAAM,EACrB,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAO,GAC5C,OAAO,CAAC,aAAa,CAAC,CA0CxB;AAED,MAAM,WAAW,kBAAkB;IACjC,4CAA4C;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8BAA8B;IAC9B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,8CAA8C;IAC9C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,mBAAmB,CAAC,EAAE,sBAAsB,CAAC,qBAAqB,CAAC,CAAC;CACrE;AAED,MAAM,WAAW,mBAAmB;IAClC,sEAAsE;IACtE,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,4CAA4C;IAC5C,SAAS,EAAE,UAAU,EAAE,CAAC;IACxB,uEAAuE;IACvE,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC,mBAAmB,CAAC,CAmC9B;AAED,4DAA4D;AAC5D,wBAAgB,yBAAyB,CAAC,IAAI,EAAE;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf,GAAG,MAAM,CAsBT;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC"}
|
|
@@ -0,0 +1,474 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Channel worker OOM guard policy.
|
|
3
|
+
*
|
|
4
|
+
* Resolves idle-cleanup TTL and live-worker budget from CLI flag /
|
|
5
|
+
* environment / project config / built-in defaults (in that precedence
|
|
6
|
+
* order), then scans the live worker registry inside a project bucket
|
|
7
|
+
* to enforce both constraints at spawn time.
|
|
8
|
+
*
|
|
9
|
+
* Boundary: this module lives in the CLI runtime layer. Core owns
|
|
10
|
+
* worker activity / `idleSince` projection; the supervisor owns process
|
|
11
|
+
* launch + signals. The guard only consumes that durable state and
|
|
12
|
+
* sends OS signals through pid files.
|
|
13
|
+
*/
|
|
14
|
+
import { execFileSync } from "node:child_process";
|
|
15
|
+
import fs from "node:fs";
|
|
16
|
+
import path from "node:path";
|
|
17
|
+
import { isTerminalLifecycle, reduceWorkerRegistry, } from "@mindfoldhq/trellis-core/channel";
|
|
18
|
+
import { DIR_NAMES } from "../../constants/paths.js";
|
|
19
|
+
import { channelRoot, currentProjectKey, projectDir, workerFile, } from "./store/paths.js";
|
|
20
|
+
import { parseDuration } from "./wait.js";
|
|
21
|
+
/** Built-in default idle-cleanup TTL for spawned workers (5 minutes). */
|
|
22
|
+
export const DEFAULT_IDLE_TTL_MS = 5 * 60 * 1000;
|
|
23
|
+
/** Built-in default live-worker budget per project/scope. */
|
|
24
|
+
export const DEFAULT_MAX_LIVE_WORKERS = 6;
|
|
25
|
+
/** Env var override for the idle-cleanup TTL. */
|
|
26
|
+
export const ENV_IDLE_TIMEOUT = "TRELLIS_CHANNEL_WORKER_IDLE_TIMEOUT";
|
|
27
|
+
/** Env var override for the live-worker budget. */
|
|
28
|
+
export const ENV_MAX_LIVE_WORKERS = "TRELLIS_CHANNEL_MAX_LIVE_WORKERS";
|
|
29
|
+
/**
|
|
30
|
+
* Resolve the effective guard policy. Precedence:
|
|
31
|
+
* 1. CLI flag (`flag*Ms` / `flagMaxLiveWorkers`)
|
|
32
|
+
* 2. environment variable
|
|
33
|
+
* 3. `.trellis/config.yaml` `channel.worker_guard`
|
|
34
|
+
* 4. built-in default constant
|
|
35
|
+
*/
|
|
36
|
+
export function resolveWorkerGuardConfig(opts = {}) {
|
|
37
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
38
|
+
const env = opts.env ?? process.env;
|
|
39
|
+
const fromConfig = loadWorkerGuardConfig(cwd);
|
|
40
|
+
const idleTimeoutMs = pickNonNegativeMs(opts.flagIdleTimeoutMs, parseEnvDuration(env[ENV_IDLE_TIMEOUT], ENV_IDLE_TIMEOUT), fromConfig?.idleTimeoutMs, DEFAULT_IDLE_TTL_MS);
|
|
41
|
+
const maxLiveWorkers = pickNonNegativeInt(opts.flagMaxLiveWorkers, parseEnvInt(env[ENV_MAX_LIVE_WORKERS], ENV_MAX_LIVE_WORKERS), fromConfig?.maxLiveWorkers, DEFAULT_MAX_LIVE_WORKERS);
|
|
42
|
+
return { idleTimeoutMs, maxLiveWorkers };
|
|
43
|
+
}
|
|
44
|
+
function pickNonNegativeMs(...candidates) {
|
|
45
|
+
for (const c of candidates) {
|
|
46
|
+
if (c === undefined)
|
|
47
|
+
continue;
|
|
48
|
+
if (!Number.isFinite(c) || c < 0) {
|
|
49
|
+
throw new Error(`Idle timeout must be a non-negative duration (got ${c})`);
|
|
50
|
+
}
|
|
51
|
+
return c;
|
|
52
|
+
}
|
|
53
|
+
return DEFAULT_IDLE_TTL_MS;
|
|
54
|
+
}
|
|
55
|
+
function pickNonNegativeInt(...candidates) {
|
|
56
|
+
for (const c of candidates) {
|
|
57
|
+
if (c === undefined)
|
|
58
|
+
continue;
|
|
59
|
+
if (!Number.isInteger(c) || c < 0) {
|
|
60
|
+
throw new Error(`Max live workers must be a non-negative integer (got ${c})`);
|
|
61
|
+
}
|
|
62
|
+
return c;
|
|
63
|
+
}
|
|
64
|
+
return DEFAULT_MAX_LIVE_WORKERS;
|
|
65
|
+
}
|
|
66
|
+
function parseEnvDuration(raw, envName) {
|
|
67
|
+
if (raw === undefined || raw === "")
|
|
68
|
+
return undefined;
|
|
69
|
+
try {
|
|
70
|
+
return parseDuration(raw);
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
throw new Error(`${envName}: ${err instanceof Error ? err.message : String(err)}`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function parseEnvInt(raw, envName) {
|
|
77
|
+
if (raw === undefined || raw === "")
|
|
78
|
+
return undefined;
|
|
79
|
+
const n = Number(raw);
|
|
80
|
+
if (!Number.isInteger(n) || n < 0) {
|
|
81
|
+
throw new Error(`${envName} must be a non-negative integer (got '${raw}')`);
|
|
82
|
+
}
|
|
83
|
+
return n;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Parse the `channel.worker_guard` section out of `.trellis/config.yaml`.
|
|
87
|
+
* Mirrors the lightweight line-scanner used elsewhere in update.ts so we
|
|
88
|
+
* don't pull in a YAML dependency just for this two-field section.
|
|
89
|
+
*/
|
|
90
|
+
export function loadWorkerGuardConfig(cwd) {
|
|
91
|
+
const configPath = path.join(cwd, DIR_NAMES.WORKFLOW, "config.yaml");
|
|
92
|
+
if (!fs.existsSync(configPath))
|
|
93
|
+
return undefined;
|
|
94
|
+
let content;
|
|
95
|
+
try {
|
|
96
|
+
content = fs.readFileSync(configPath, "utf-8");
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
return parseWorkerGuardSection(content);
|
|
102
|
+
}
|
|
103
|
+
/** Exposed for unit tests. */
|
|
104
|
+
export function parseWorkerGuardSection(content) {
|
|
105
|
+
const lines = content.split("\n");
|
|
106
|
+
let inChannel = false;
|
|
107
|
+
let inGuard = false;
|
|
108
|
+
const found = {};
|
|
109
|
+
let any = false;
|
|
110
|
+
for (const raw of lines) {
|
|
111
|
+
const line = raw.replace(/\r$/, "");
|
|
112
|
+
const trimmed = line.trimEnd();
|
|
113
|
+
if (trimmed === "" || trimmed.trimStart().startsWith("#"))
|
|
114
|
+
continue;
|
|
115
|
+
if (/^channel:\s*$/.test(trimmed)) {
|
|
116
|
+
inChannel = true;
|
|
117
|
+
inGuard = false;
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
if (inChannel && /^ {2}worker_guard:\s*$/.test(trimmed)) {
|
|
121
|
+
inGuard = true;
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
if (inGuard) {
|
|
125
|
+
const idle = trimmed.match(/^ {4}idle_timeout:\s*(.+)$/);
|
|
126
|
+
if (idle) {
|
|
127
|
+
const val = stripValue(idle[1]);
|
|
128
|
+
found.idleTimeoutMs = parseGuardDuration(val, "idle_timeout");
|
|
129
|
+
any = true;
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
const max = trimmed.match(/^ {4}max_live_workers:\s*(.+)$/);
|
|
133
|
+
if (max) {
|
|
134
|
+
const val = stripValue(max[1]);
|
|
135
|
+
const n = Number(val);
|
|
136
|
+
if (!Number.isInteger(n) || n < 0) {
|
|
137
|
+
throw new Error(`channel.worker_guard.max_live_workers must be a non-negative integer (got '${val}')`);
|
|
138
|
+
}
|
|
139
|
+
found.maxLiveWorkers = n;
|
|
140
|
+
any = true;
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
// Anything else at the same indent (or shallower) ends the section.
|
|
144
|
+
if (!/^ {4}\S/.test(line)) {
|
|
145
|
+
inGuard = false;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
if (inChannel && !/^ {2}\S/.test(line) && /^\S/.test(line)) {
|
|
149
|
+
inChannel = false;
|
|
150
|
+
inGuard = false;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return any ? found : undefined;
|
|
154
|
+
}
|
|
155
|
+
function stripValue(s) {
|
|
156
|
+
return s
|
|
157
|
+
.trim()
|
|
158
|
+
.replace(/\s*#.*$/, "")
|
|
159
|
+
.trim()
|
|
160
|
+
.replace(/^['"]|['"]$/g, "");
|
|
161
|
+
}
|
|
162
|
+
function parseGuardDuration(raw, key) {
|
|
163
|
+
// Allow bare integer = milliseconds (so `0` disables cleanly).
|
|
164
|
+
const asInt = Number(raw);
|
|
165
|
+
if (Number.isFinite(asInt) && /^\d+$/.test(raw)) {
|
|
166
|
+
if (asInt < 0) {
|
|
167
|
+
throw new Error(`channel.worker_guard.${key} must be non-negative (got '${raw}')`);
|
|
168
|
+
}
|
|
169
|
+
// Bare integer 0 = disabled; >0 with no unit = milliseconds.
|
|
170
|
+
return asInt;
|
|
171
|
+
}
|
|
172
|
+
try {
|
|
173
|
+
return parseDuration(raw) ?? 0;
|
|
174
|
+
}
|
|
175
|
+
catch (err) {
|
|
176
|
+
throw new Error(`channel.worker_guard.${key}: ${err instanceof Error ? err.message : String(err)}`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Enumerate live (non-terminal + supervisor-pid alive) workers across
|
|
181
|
+
* every channel in the given project bucket.
|
|
182
|
+
*/
|
|
183
|
+
export function scanLiveWorkers(opts = {}) {
|
|
184
|
+
const project = opts.projectKey ?? currentProjectKey();
|
|
185
|
+
const bucket = opts.root
|
|
186
|
+
? path.join(opts.root, project)
|
|
187
|
+
: projectDir(project);
|
|
188
|
+
if (!fs.existsSync(bucket))
|
|
189
|
+
return [];
|
|
190
|
+
let entries;
|
|
191
|
+
try {
|
|
192
|
+
entries = fs.readdirSync(bucket);
|
|
193
|
+
}
|
|
194
|
+
catch {
|
|
195
|
+
return [];
|
|
196
|
+
}
|
|
197
|
+
const out = [];
|
|
198
|
+
for (const entry of entries) {
|
|
199
|
+
if (entry.startsWith("."))
|
|
200
|
+
continue;
|
|
201
|
+
const dir = path.join(bucket, entry);
|
|
202
|
+
try {
|
|
203
|
+
if (!fs.statSync(dir).isDirectory())
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
catch {
|
|
207
|
+
continue;
|
|
208
|
+
}
|
|
209
|
+
const events = path.join(dir, "events.jsonl");
|
|
210
|
+
if (!fs.existsSync(events))
|
|
211
|
+
continue;
|
|
212
|
+
let workers;
|
|
213
|
+
try {
|
|
214
|
+
const all = readFileEventsSync(events);
|
|
215
|
+
workers = reduceWorkerRegistry(all).workers;
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
for (const state of workers) {
|
|
221
|
+
if (state.terminal || isTerminalLifecycle(state.lifecycle))
|
|
222
|
+
continue;
|
|
223
|
+
const supervisorPid = readPid(workerFile(entry, state.workerId, "pid", project));
|
|
224
|
+
if (supervisorPid === undefined || !pidAlive(supervisorPid)) {
|
|
225
|
+
// Supervisor pid file missing or dead → not a live OS process,
|
|
226
|
+
// even if durable state still shows running. Reconciler / future
|
|
227
|
+
// CLI cleanup will catch up; the guard ignores it.
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
const supervisorVerified = opts.isSupervisorProcess
|
|
231
|
+
? opts.isSupervisorProcess(supervisorPid, entry, state.workerId)
|
|
232
|
+
: isSupervisorProcess(supervisorPid, entry, state.workerId);
|
|
233
|
+
const workerPid = readPid(workerFile(entry, state.workerId, "worker-pid", project));
|
|
234
|
+
out.push({
|
|
235
|
+
channel: entry,
|
|
236
|
+
workerId: state.workerId,
|
|
237
|
+
state,
|
|
238
|
+
supervisorPid,
|
|
239
|
+
supervisorVerified,
|
|
240
|
+
...(workerPid !== undefined ? { workerPid } : {}),
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
for (const state of readReservationWorkers(entry, project)) {
|
|
244
|
+
if (out.some((w) => w.channel === entry && w.workerId === state.workerId)) {
|
|
245
|
+
continue;
|
|
246
|
+
}
|
|
247
|
+
const supervisorPid = readPid(workerFile(entry, state.workerId, "pid", project));
|
|
248
|
+
if (supervisorPid === undefined || !pidAlive(supervisorPid))
|
|
249
|
+
continue;
|
|
250
|
+
const supervisorVerified = opts.isSupervisorProcess
|
|
251
|
+
? opts.isSupervisorProcess(supervisorPid, entry, state.workerId)
|
|
252
|
+
: isSupervisorProcess(supervisorPid, entry, state.workerId);
|
|
253
|
+
out.push({
|
|
254
|
+
channel: entry,
|
|
255
|
+
workerId: state.workerId,
|
|
256
|
+
state,
|
|
257
|
+
supervisorPid,
|
|
258
|
+
supervisorVerified,
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return out;
|
|
263
|
+
}
|
|
264
|
+
function readReservationWorkers(channel, project) {
|
|
265
|
+
const dir = path.join(projectDir(project), channel);
|
|
266
|
+
let files;
|
|
267
|
+
try {
|
|
268
|
+
files = fs.readdirSync(dir);
|
|
269
|
+
}
|
|
270
|
+
catch {
|
|
271
|
+
return [];
|
|
272
|
+
}
|
|
273
|
+
const workers = [];
|
|
274
|
+
for (const file of files) {
|
|
275
|
+
if (!file.endsWith(".reservation"))
|
|
276
|
+
continue;
|
|
277
|
+
const worker = file.slice(0, -".reservation".length);
|
|
278
|
+
workers.push({
|
|
279
|
+
workerId: worker,
|
|
280
|
+
lifecycle: "starting",
|
|
281
|
+
terminal: false,
|
|
282
|
+
activity: "idle",
|
|
283
|
+
pendingMessageCount: 0,
|
|
284
|
+
inboxPolicy: "explicitOnly",
|
|
285
|
+
updatedAt: new Date(0).toISOString(),
|
|
286
|
+
lastSeq: 0,
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
return workers;
|
|
290
|
+
}
|
|
291
|
+
function readFileEventsSync(file) {
|
|
292
|
+
const text = fs.readFileSync(file, "utf-8");
|
|
293
|
+
const events = [];
|
|
294
|
+
for (const line of text.split("\n")) {
|
|
295
|
+
if (!line.trim())
|
|
296
|
+
continue;
|
|
297
|
+
try {
|
|
298
|
+
events.push(JSON.parse(line));
|
|
299
|
+
}
|
|
300
|
+
catch {
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
return events;
|
|
305
|
+
}
|
|
306
|
+
function readPid(p) {
|
|
307
|
+
try {
|
|
308
|
+
const n = Number(fs.readFileSync(p, "utf-8").trim());
|
|
309
|
+
return Number.isFinite(n) && n > 0 ? n : undefined;
|
|
310
|
+
}
|
|
311
|
+
catch {
|
|
312
|
+
return undefined;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
function pidAlive(pid) {
|
|
316
|
+
try {
|
|
317
|
+
process.kill(pid, 0);
|
|
318
|
+
return true;
|
|
319
|
+
}
|
|
320
|
+
catch {
|
|
321
|
+
return false;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
export function isSupervisorProcess(pid, channel, worker) {
|
|
325
|
+
if (process.platform === "win32")
|
|
326
|
+
return false;
|
|
327
|
+
try {
|
|
328
|
+
const command = execFileSync("ps", ["-p", String(pid), "-o", "command="], {
|
|
329
|
+
encoding: "utf-8",
|
|
330
|
+
timeout: 1000,
|
|
331
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
332
|
+
}).trim();
|
|
333
|
+
const pattern = new RegExp([
|
|
334
|
+
"(?:^|\\s)channel\\s+__supervisor\\s+",
|
|
335
|
+
escapeRegExp(channel),
|
|
336
|
+
"\\s+",
|
|
337
|
+
escapeRegExp(worker),
|
|
338
|
+
"(?:\\s|$)",
|
|
339
|
+
].join(""));
|
|
340
|
+
return pattern.test(command);
|
|
341
|
+
}
|
|
342
|
+
catch {
|
|
343
|
+
return false;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
function escapeRegExp(s) {
|
|
347
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Pure predicate: is this live worker eligible for idle-cleanup right
|
|
351
|
+
* now? Mid-turn workers and workers without `idleSince` (e.g. they
|
|
352
|
+
* never spawned cleanly) are never killed by the guard.
|
|
353
|
+
*/
|
|
354
|
+
export function isIdleCleanupEligible(live, idleTimeoutMs, now) {
|
|
355
|
+
if (idleTimeoutMs <= 0)
|
|
356
|
+
return false;
|
|
357
|
+
const { state } = live;
|
|
358
|
+
if (state.activity !== "idle")
|
|
359
|
+
return false;
|
|
360
|
+
if (!state.idleSince)
|
|
361
|
+
return false;
|
|
362
|
+
if (state.terminal)
|
|
363
|
+
return false;
|
|
364
|
+
const idleSinceMs = Date.parse(state.idleSince);
|
|
365
|
+
if (!Number.isFinite(idleSinceMs))
|
|
366
|
+
return false;
|
|
367
|
+
return now - idleSinceMs >= idleTimeoutMs;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Kill workers whose idle TTL has expired. Writes a one-shot shutdown
|
|
371
|
+
* reason sidecar before signalling the supervisor so the supervisor's
|
|
372
|
+
* existing shutdown funnel emits the single terminal `killed` event.
|
|
373
|
+
*
|
|
374
|
+
* Returns the workers that were signalled. Failures are collected — a
|
|
375
|
+
* dead pid or read race is not fatal; the next scan re-evaluates.
|
|
376
|
+
*/
|
|
377
|
+
export async function cleanupExpiredIdleWorkers(candidates, idleTimeoutMs, opts = {}) {
|
|
378
|
+
const result = { killed: [], failed: [] };
|
|
379
|
+
if (idleTimeoutMs <= 0)
|
|
380
|
+
return result;
|
|
381
|
+
const now = opts.now ?? Date.now();
|
|
382
|
+
for (const live of candidates) {
|
|
383
|
+
if (!isIdleCleanupEligible(live, idleTimeoutMs, now))
|
|
384
|
+
continue;
|
|
385
|
+
try {
|
|
386
|
+
const project = opts.project ?? currentProjectKey();
|
|
387
|
+
if (live.supervisorPid === undefined ||
|
|
388
|
+
live.supervisorVerified !== true ||
|
|
389
|
+
!pidAlive(live.supervisorPid)) {
|
|
390
|
+
continue;
|
|
391
|
+
}
|
|
392
|
+
const reasonFile = workerFile(live.channel, live.workerId, "shutdown-reason", project);
|
|
393
|
+
fs.writeFileSync(reasonFile, "idle-timeout\n", "utf-8");
|
|
394
|
+
try {
|
|
395
|
+
process.kill(live.supervisorPid, "SIGTERM");
|
|
396
|
+
}
|
|
397
|
+
catch (err) {
|
|
398
|
+
try {
|
|
399
|
+
fs.unlinkSync(reasonFile);
|
|
400
|
+
}
|
|
401
|
+
catch {
|
|
402
|
+
// already gone
|
|
403
|
+
}
|
|
404
|
+
throw err;
|
|
405
|
+
}
|
|
406
|
+
result.killed.push(live);
|
|
407
|
+
}
|
|
408
|
+
catch (err) {
|
|
409
|
+
result.failed.push({
|
|
410
|
+
worker: live,
|
|
411
|
+
error: err instanceof Error ? err.message : String(err),
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
return result;
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Run the spawn-time guard for a project bucket. Cleans expired idle
|
|
419
|
+
* workers, re-scans, then decides whether the live worker budget has
|
|
420
|
+
* room for one more spawn.
|
|
421
|
+
*/
|
|
422
|
+
export async function enforceSpawnBudget(input) {
|
|
423
|
+
const project = input.projectKey ?? currentProjectKey();
|
|
424
|
+
const scanOpts = {
|
|
425
|
+
projectKey: project,
|
|
426
|
+
...(input.root !== undefined ? { root: input.root } : {}),
|
|
427
|
+
...(input.isSupervisorProcess !== undefined
|
|
428
|
+
? { isSupervisorProcess: input.isSupervisorProcess }
|
|
429
|
+
: {}),
|
|
430
|
+
};
|
|
431
|
+
const initial = scanLiveWorkers(scanOpts);
|
|
432
|
+
const cleanup = await cleanupExpiredIdleWorkers(initial, input.policy.idleTimeoutMs, { project, ...(input.now !== undefined ? { now: input.now } : {}) });
|
|
433
|
+
// Re-probe after cleanup so we don't double-count workers that have
|
|
434
|
+
// been signalled but haven't actually torn down their pid files yet.
|
|
435
|
+
// Wait briefly for the SIGTERM to translate into pid-file removal; if
|
|
436
|
+
// a worker is taking its grace period, just exclude killed workers
|
|
437
|
+
// from the count.
|
|
438
|
+
const killedIds = new Set(cleanup.killed.map((w) => `${w.channel}::${w.workerId}`));
|
|
439
|
+
const remaining = scanLiveWorkers(scanOpts).filter((w) => !killedIds.has(`${w.channel}::${w.workerId}`));
|
|
440
|
+
const allowed = input.policy.maxLiveWorkers <= 0 ||
|
|
441
|
+
remaining.length < input.policy.maxLiveWorkers;
|
|
442
|
+
return { cleaned: cleanup.killed, remaining, allowed };
|
|
443
|
+
}
|
|
444
|
+
/** Build a multi-line, actionable overflow error string. */
|
|
445
|
+
export function formatBudgetOverflowError(args) {
|
|
446
|
+
const { projectKey, live, limit } = args;
|
|
447
|
+
const header = `Live worker budget exhausted for project '${projectKey}': ${live.length}/${limit} live worker(s).`;
|
|
448
|
+
const rows = live
|
|
449
|
+
.map((w) => {
|
|
450
|
+
const provider = w.state.provider ?? "?";
|
|
451
|
+
const lifecycle = w.state.lifecycle;
|
|
452
|
+
const activity = w.state.activity;
|
|
453
|
+
const pid = w.supervisorPid ?? "?";
|
|
454
|
+
const verified = w.supervisorVerified === false ? " supervisor=unverified" : "";
|
|
455
|
+
return ` • channel='${w.channel}' worker='${w.workerId}' provider=${provider} lifecycle=${lifecycle} activity=${activity} pid=${pid}${verified}`;
|
|
456
|
+
})
|
|
457
|
+
.join("\n");
|
|
458
|
+
const hint = [
|
|
459
|
+
"Free a slot before spawning, e.g.:",
|
|
460
|
+
` trellis channel kill <channel> --as <worker>`,
|
|
461
|
+
"Or override per spawn:",
|
|
462
|
+
` trellis channel spawn ... --max-live-workers ${live.length + 1}`,
|
|
463
|
+
"Or raise the default in .trellis/config.yaml under channel.worker_guard.max_live_workers.",
|
|
464
|
+
].join("\n");
|
|
465
|
+
return [header, rows, hint].join("\n");
|
|
466
|
+
}
|
|
467
|
+
/**
|
|
468
|
+
* Convenience helper: ensure `channelRoot()` is initialised before scan
|
|
469
|
+
* (otherwise the project dir may not yet exist on first spawn).
|
|
470
|
+
*/
|
|
471
|
+
export function ensureRootExists() {
|
|
472
|
+
fs.mkdirSync(channelRoot(), { recursive: true });
|
|
473
|
+
}
|
|
474
|
+
//# sourceMappingURL=guard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guard.js","sourceRoot":"","sources":["../../../src/commands/channel/guard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/channel/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAwB,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AAuC/D,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAo4B7D"}
|