@yemi33/minions 0.1.2448 → 0.1.2449
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/bin/cli-api-client.js +1 -1
- package/bin/install-internal-minions.js +1382 -44
- package/bin/install-layout.js +150 -0
- package/bin/minions.js +460 -167
- package/dashboard/docs/typography.md +65 -12
- package/dashboard/js/command-center.js +58 -4
- package/dashboard/js/detail-panel.js +36 -0
- package/dashboard/js/memory-panel.js +59 -12
- package/dashboard/js/qa.js +179 -20
- package/dashboard/js/refresh.js +148 -12
- package/dashboard/js/render-dispatch.js +3 -4
- package/dashboard/js/render-inbox.js +2 -2
- package/dashboard/js/render-other.js +3 -3
- package/dashboard/js/render-pipelines.js +14 -0
- package/dashboard/js/render-plans.js +57 -9
- package/dashboard/js/render-prd.js +132 -23
- package/dashboard/js/render-prs.js +195 -166
- package/dashboard/js/render-schedules.js +63 -3
- package/dashboard/js/render-utils.js +3 -3
- package/dashboard/js/render-watches.js +19 -3
- package/dashboard/js/render-work-items.js +238 -30
- package/dashboard/js/settings.js +205 -54
- package/dashboard/js/utils.js +51 -1
- package/dashboard/pages/home.html +1 -1
- package/dashboard/pages/qa.html +1 -16
- package/dashboard/pages/work.html +40 -0
- package/dashboard/shared/cc-limits.js +79 -0
- package/dashboard/shared/pr-filters.js +21 -38
- package/dashboard/shared/project-git-summary.js +1 -1
- package/dashboard/shared/record-filters.js +169 -0
- package/dashboard/shared/watches-source.js +1 -1
- package/dashboard/shared/welcome-popup.js +1 -1
- package/dashboard/shared/wi-filters.js +302 -0
- package/dashboard/slim/body.html +1 -0
- package/dashboard/slim/js/command-send.js +26 -0
- package/dashboard/slim/js/modals-tiles.js +380 -39
- package/dashboard/slim/js/status.js +13 -21
- package/dashboard/slim/layout.html +1 -0
- package/dashboard/slim/panel-bootstrap.js +6 -2
- package/dashboard/slim/styles.css +38 -0
- package/dashboard/styles.css +159 -55
- package/dashboard-build.js +13 -2
- package/dashboard.js +956 -423
- package/docs/README.md +11 -6
- package/docs/api-errors.md +2 -2
- package/docs/architecture-review-2026-07-09.md +1 -1
- package/docs/architecture.excalidraw +2 -2
- package/docs/auto-discovery.md +18 -9
- package/docs/branch-derivation.md +4 -4
- package/docs/capture-demos.js +39 -2
- package/docs/ci-runner-canary.md +123 -0
- package/docs/claude-md-propagation.md +2 -2
- package/docs/cloud-agent-dispatch.md +204 -0
- package/docs/command-center.md +7 -7
- package/docs/completion-reports.md +43 -20
- package/docs/constants.md +10 -3
- package/docs/constellation-bridge.md +134 -6
- package/docs/constellation-style-telemetry.md +4 -4
- package/docs/contracts/capability-protocol.v1.json +165 -0
- package/docs/cooldown-merge-semantics.md +12 -12
- package/docs/copilot-cli-schema.md +7 -7
- package/docs/cross-repo-plans.md +10 -10
- package/docs/dead-code-audit-retractions.md +5 -5
- package/docs/default-branch-ci.md +173 -0
- package/docs/deprecated.json +31 -31
- package/docs/design-inbox-entries-schema.md +3 -3
- package/docs/design-language.md +1051 -0
- package/docs/design-state-storage.md +11 -11
- package/docs/diagnostics-crash-reports.md +9 -9
- package/docs/diagnostics-memory.md +5 -5
- package/docs/documentation-audit-2026-07-09.md +7 -7
- package/docs/engine-restart.md +90 -5
- package/docs/harness-mode.md +1 -1
- package/docs/internal-install.md +338 -39
- package/docs/kb-dedup-duplicate-pair-investigation.md +5 -5
- package/docs/kb-pr3223-cascade-archiving.md +1 -1
- package/docs/kb-pr696-merge-conflict-docs.md +6 -6
- package/docs/kb-sweep.md +35 -35
- package/docs/keep-processes.md +1 -1
- package/docs/live-checkout-mode.md +30 -30
- package/docs/managed-spawn.md +18 -14
- package/docs/named-agents.md +7 -7
- package/docs/plan-lifecycle.md +69 -2
- package/docs/pr-author-identity.md +114 -0
- package/docs/pr-auto-fix-dispatch.md +19 -4
- package/docs/pr-comment-followup.md +6 -6
- package/docs/pr-review-fix-loop.md +59 -10
- package/docs/process-termination.md +40 -0
- package/docs/proposals/repo-pool-for-live-checkout.md +13 -13
- package/docs/qa-runbook-lifecycle.md +367 -17
- package/docs/qa-runbooks.md +3 -3
- package/docs/rfc-completion-json.md +18 -18
- package/docs/runtime-adapters.md +26 -21
- package/docs/security.md +6 -6
- package/docs/self-improvement.md +4 -4
- package/docs/shared-lifecycle-module-map.md +473 -472
- package/docs/skills.md +52 -3
- package/docs/slim-ux/concepts.md +121 -116
- package/docs/specs/agent-configurability.md +18 -18
- package/docs/specs/agent-rename.md +18 -18
- package/docs/team-memory.md +38 -21
- package/docs/timeouts-and-liveness.md +118 -10
- package/docs/tutorials/01-install-and-connect.md +1 -1
- package/docs/watches.md +40 -39
- package/docs/workspace-manifests.md +4 -4
- package/docs/worktree-lifecycle.md +293 -14
- package/engine/README.md +46 -0
- package/engine/{ado-comment.js → ado/comment.js} +8 -8
- package/engine/{ado-git-auth.js → ado/git-auth.js} +4 -4
- package/engine/{ado.js → ado/index.js} +417 -63
- package/engine/{ado-status.js → ado/status.js} +6 -8
- package/engine/{ado-token.js → ado/token.js} +1 -1
- package/engine/{acp-transport.js → agents/acp-transport.js} +62 -22
- package/engine/{agent-worker-pool.js → agents/agent-worker-pool.js} +17 -8
- package/engine/{cc-worker-pool.js → agents/cc-worker-pool.js} +16 -6
- package/engine/{claude-md-context.js → agents/claude-md-context.js} +5 -5
- package/engine/{harness-context.js → agents/harness-context.js} +5 -5
- package/engine/{harness.js → agents/harness.js} +3 -3
- package/engine/{llm.js → agents/llm.js} +18 -14
- package/engine/{model-discovery.js → agents/model-discovery.js} +2 -2
- package/engine/{playbook.js → agents/playbook.js} +155 -22
- package/engine/{pooled-agent-process.js → agents/pooled-agent-process.js} +14 -12
- package/engine/{preflight.js → agents/preflight.js} +29 -10
- package/engine/{spawn-agent.js → agents/spawn-agent.js} +25 -14
- package/engine/{spawn-phase-watchdog.js → agents/spawn-phase-watchdog.js} +16 -7
- package/engine/{steering.js → agents/steering.js} +5 -5
- package/engine/{tools-inventory.js → agents/tools-inventory.js} +2 -2
- package/engine/{agent-api-validation.js → api/agent-api-validation.js} +2 -2
- package/engine/{api-validation.js → api/api-validation.js} +1 -1
- package/engine/api/bridge.js +787 -0
- package/engine/{cc-api-validation.js → api/cc-api-validation.js} +1 -1
- package/engine/api/companion.js +560 -0
- package/engine/{content-api-validation.js → api/content-api-validation.js} +2 -2
- package/engine/{pr-issue-validation.js → api/pr-issue-validation.js} +33 -6
- package/engine/{settings-validation.js → api/settings-validation.js} +32 -4
- package/engine/api-contracts/agent-content.js +4 -4
- package/engine/api-contracts/capability-manifest.js +236 -0
- package/engine/api-contracts/capability-protocol.js +333 -0
- package/engine/api-contracts/cc-ops.js +1 -1
- package/engine/api-contracts/config-runtime.js +5 -0
- package/engine/api-contracts/core.js +28 -1
- package/engine/api-contracts/index.js +100 -0
- package/engine/api-contracts/orchestration.js +18 -5
- package/engine/api-contracts/pull-requests.js +37 -6
- package/engine/api-contracts/qa-process.js +29 -6
- package/engine/api-contracts/work-plan-prd.js +21 -1
- package/engine/cloud/contract.js +212 -0
- package/engine/cloud/index.js +159 -0
- package/engine/{execution-model.js → core/execution-model.js} +1 -1
- package/engine/{features.js → core/features.js} +4 -4
- package/engine/{operator-identity.js → core/operator-identity.js} +1 -1
- package/engine/{queries.js → core/queries.js} +201 -36
- package/engine/{safe-expr.js → core/safe-expr.js} +1 -1
- package/engine/{shared.js → core/shared.js} +1637 -175
- package/engine/{stdio-timestamps.js → core/stdio-timestamps.js} +1 -1
- package/engine/{untrusted-fence.js → core/untrusted-fence.js} +3 -3
- package/engine/db/index.js +11 -2
- package/engine/db/migrations/002-dispatches.js +3 -3
- package/engine/db/migrations/003-work-items.js +1 -1
- package/engine/db/migrations/004-pull-requests.js +1 -1
- package/engine/db/migrations/006-metrics.js +1 -1
- package/engine/db/migrations/007-watches.js +2 -2
- package/engine/db/migrations/008-small-state.js +1 -1
- package/engine/db/migrations/009-qa.js +1 -1
- package/engine/db/migrations/010-pr-links.js +1 -1
- package/engine/db/migrations/011-remaining-state.js +1 -1
- package/engine/db/migrations/012-steering-deliveries.js +2 -2
- package/engine/db/migrations/013-backfill-broken-note-links.js +1 -1
- package/engine/db/migrations/014-pr-fix-target-prefs.js +2 -2
- package/engine/db/migrations/015-plans-prds.js +0 -0
- package/engine/db/migrations/018-sql-only-cutover.js +2 -2
- package/engine/db/migrations/021-archived-work-items.js +1 -1
- package/engine/db/migrations/022-global-cc-session.js +1 -1
- package/engine/db/migrations/023-engine-state.js +1 -1
- package/engine/db/migrations/025-malformed-work-item-phantoms.js +1 -1
- package/engine/db/migrations/027-review-learning-lifecycle.js +1 -1
- package/engine/db/migrations/029-repair-reused-versions.js +20 -0
- package/engine/db/migrations/031-pr-author-identity.js +137 -0
- package/engine/{consolidation.js → memory/consolidation.js} +6 -6
- package/engine/{kb-sweep-runner.js → memory/kb-sweep-runner.js} +2 -2
- package/engine/{kb-sweep.js → memory/kb-sweep.js} +9 -7
- package/engine/{memory-retrieval.js → memory/memory-retrieval.js} +46 -4
- package/engine/{memory-store.js → memory/memory-store.js} +3 -3
- package/engine/{promotion.js → memory/promotion.js} +3 -3
- package/engine/{review-learning-backfill.js → memory/review-learning-backfill.js} +6 -6
- package/engine/{review-learning.js → memory/review-learning.js} +10 -5
- package/engine/{diagnostics-memory.js → observability/diagnostics-memory.js} +1 -1
- package/engine/{logs-store.js → observability/logs-store.js} +5 -5
- package/engine/{metrics-store.js → observability/metrics-store.js} +4 -4
- package/engine/{check-status.js → operations/check-status.js} +3 -3
- package/engine/{cli.js → operations/cli.js} +271 -113
- package/engine/{distribution.js → operations/distribution.js} +5 -6
- package/engine/{cleanup.js → orchestration/cleanup.js} +72 -45
- package/engine/{cooldown.js → orchestration/cooldown.js} +5 -5
- package/engine/{dispatch-events.js → orchestration/dispatch-events.js} +2 -2
- package/engine/{dispatch.js → orchestration/dispatch.js} +129 -36
- package/engine/orchestration/failed-scheduled-cleanup.js +274 -0
- package/engine/{lifecycle.js → orchestration/lifecycle.js} +198 -90
- package/engine/{meeting.js → orchestration/meeting.js} +6 -16
- package/engine/{pipeline.js → orchestration/pipeline.js} +12 -12
- package/engine/{pre-dispatch-eval.js → orchestration/pre-dispatch-eval.js} +10 -9
- package/engine/{routing.js → orchestration/routing.js} +3 -3
- package/engine/{schedule-bootstrap.js → orchestration/schedule-bootstrap.js} +4 -4
- package/engine/{scheduler.js → orchestration/scheduler.js} +38 -8
- package/engine/{timeout.js → orchestration/timeout.js} +158 -109
- package/engine/{db-events.js → persistence/db-events.js} +2 -2
- package/engine/{dispatch-store.js → persistence/dispatch-store.js} +7 -7
- package/engine/{inbox-store.js → persistence/inbox-store.js} +2 -2
- package/engine/{note-link-backfill.js → persistence/note-link-backfill.js} +4 -4
- package/engine/{pr-fix-target-store.js → persistence/pr-fix-target-store.js} +8 -8
- package/engine/{pull-requests-store.js → persistence/pull-requests-store.js} +21 -7
- package/engine/{small-state-store.js → persistence/small-state-store.js} +31 -31
- package/engine/persistence/state-operations.js +350 -0
- package/engine/{steering-store.js → persistence/steering-store.js} +6 -6
- package/engine/{issues.js → planning/issues.js} +2 -2
- package/engine/{plan-prd-validation.js → planning/plan-prd-validation.js} +8 -2
- package/engine/planning/prd-result-sidecar.js +190 -0
- package/engine/{prd-store.js → planning/prd-store.js} +17 -17
- package/engine/{project-discovery.js → planning/project-discovery.js} +5 -5
- package/engine/{projects.js → planning/projects.js} +10 -10
- package/engine/{resolve-area.js → planning/resolve-area.js} +1 -1
- package/engine/{work-item-validation.js → planning/work-item-validation.js} +39 -3
- package/engine/{work-items-store.js → planning/work-items-store.js} +29 -21
- package/engine/{keep-process-sweep.js → processes/keep-process-sweep.js} +57 -17
- package/engine/{managed-spawn-launcher.js → processes/managed-spawn-launcher.js} +3 -3
- package/engine/{managed-spawn.js → processes/managed-spawn.js} +97 -46
- package/engine/{process-utils.js → processes/process-utils.js} +599 -55
- package/engine/{abandoned-pr-reconciliation.js → providers/abandoned-pr-reconciliation.js} +17 -7
- package/engine/{comment-classifier.js → providers/comment-classifier.js} +85 -17
- package/engine/{comment-format.js → providers/comment-format.js} +5 -5
- package/engine/{gh-comment.js → providers/gh-comment.js} +15 -15
- package/engine/{gh-token.js → providers/gh-token.js} +4 -4
- package/engine/{github.js → providers/github.js} +131 -54
- package/engine/{pr-action.js → providers/pr-action.js} +13 -12
- package/engine/{pr-clone-keep.js → providers/pr-clone-keep.js} +7 -7
- package/engine/{pr-devbox.js → providers/pr-devbox.js} +6 -6
- package/engine/{pr-fix-target.js → providers/pr-fix-target.js} +13 -13
- package/engine/{pr-remote-patch.js → providers/pr-remote-patch.js} +4 -4
- package/engine/{pr-resolve.js → providers/pr-resolve.js} +7 -7
- package/engine/{pr-temp-clone.js → providers/pr-temp-clone.js} +5 -5
- package/engine/{pr-track.js → providers/pr-track.js} +11 -13
- package/engine/{shared-branch-pr-reconcile.js → providers/shared-branch-pr-reconcile.js} +4 -4
- package/engine/qa/auto-prd-qa.js +313 -0
- package/engine/{qa-from-prd.js → qa/from-prd.js} +42 -12
- package/engine/qa/prd-session.js +240 -0
- package/engine/{qa-process-validation.js → qa/process-validation.js} +14 -9
- package/engine/{qa-runbooks.js → qa/runbooks.js} +1 -1
- package/engine/{qa-runs.js → qa/runs.js} +286 -15
- package/engine/{qa-sessions.js → qa/sessions.js} +595 -49
- package/engine/qa/visual-journey.js +654 -0
- package/engine/{qa-runners.js → qa-runners/index.js} +7 -7
- package/engine/qa-runners/maestro.js +3 -3
- package/engine/qa-runners/playwright.js +2 -2
- package/engine/{restart-health.js → recovery/restart-health.js} +48 -4
- package/engine/recovery/stop-stack.js +607 -0
- package/engine/{supervisor.js → recovery/supervisor.js} +105 -175
- package/engine/{watchdog.js → recovery/watchdog.js} +136 -13
- package/engine/runtimes/claude.js +14 -12
- package/engine/runtimes/codex.js +8 -6
- package/engine/runtimes/copilot.js +17 -16
- package/engine/{watch-actions.js → watches/actions.js} +13 -13
- package/engine/{watches.js → watches/index.js} +43 -32
- package/engine/{watches-store.js → watches/store.js} +4 -4
- package/engine/{create-pr-worktree.js → worktrees/create-pr.js} +1 -1
- package/engine/{worktree-gc.js → worktrees/gc.js} +70 -22
- package/engine/worktrees/inventory.js +671 -0
- package/engine/{live-checkout.js → worktrees/live-checkout.js} +4 -4
- package/engine/{worktree-pool.js → worktrees/pool.js} +2 -2
- package/engine/{worktree-preflight.js → worktrees/preflight.js} +1 -0
- package/engine/worktrees/quarantine-refs.js +173 -0
- package/engine.js +1137 -208
- package/minions.js +147 -77
- package/package.json +10 -6
- package/playbooks/_pr-description-audit.md +110 -78
- package/playbooks/build-fix-complex.md +2 -0
- package/playbooks/fix.md +16 -12
- package/playbooks/implement-shared.md +2 -0
- package/playbooks/implement.md +19 -20
- package/playbooks/plan-to-prd.md +18 -3
- package/playbooks/qa-session-draft.md +136 -1
- package/playbooks/qa-session-execute.md +80 -2
- package/playbooks/qa-session-setup.md +17 -1
- package/playbooks/qa-validate.md +1 -1
- package/playbooks/setup.md +2 -0
- package/playbooks/shared-rules.md +25 -32
- package/playbooks/templates/followup-dispatch.md +4 -3
- package/playbooks/verify.md +1 -1
- package/prompts/cc-system.md +19 -27
- package/watch-plugins/README.md +92 -0
- package/watch-plugins/ado-author-prs.js +336 -0
- package/watch-plugins/gh-author-prs.js +375 -0
- package/watch-plugins/http.js +474 -0
- package/watch-plugins/teams-channel.js +869 -0
- package/docs/dev-composite-workflow.md +0 -101
- package/docs/pr-screenshots/pr-886/after-single-header.png +0 -0
- package/docs/pr-screenshots/pr-886/before-duplicate-header.png +0 -0
- package/docs/pr-screenshots/pr-895/01-cancellation-reason-detail.png +0 -0
- package/docs/pr-screenshots/pr-899/worker-pool-worktrees-AFTER.png +0 -0
- package/docs/pr-screenshots/pr-899/worker-pool-worktrees-BEFORE.png +0 -0
- package/docs/pr-screenshots/pr-901/projects-tab-default.png +0 -0
- package/docs/pr-screenshots/pr-901/projects-tab-fmf-selected.png +0 -0
- package/docs/pr-screenshots/pr-916/model-picker-AFTER-crop.png +0 -0
- package/docs/pr-screenshots/pr-916/model-picker-AFTER.png +0 -0
- package/docs/pr-screenshots/pr-916/model-picker-BEFORE-crop.png +0 -0
- package/docs/pr-screenshots/pr-916/model-picker-BEFORE.png +0 -0
- package/docs/pr-screenshots/pr-916/model-picker-dropdown-AFTER.png +0 -0
- package/docs/pr-screenshots/pr-979/auto-fix-pane-AFTER.png +0 -0
- package/docs/pr-screenshots/pr-979/auto-fix-pane-BEFORE.png +0 -0
- package/docs/pr-screenshots/pr-985/pr-column-em-dash-AFTER.png +0 -0
- package/docs/pr-screenshots/pr-985/pr-column-em-dash-BEFORE.png +0 -0
- package/docs/visual-evidence-ci.md +0 -103
- package/engine/bridge.js +0 -379
- package/engine/quarantine-refs.js +0 -103
- package/engine/state-operations.js +0 -178
- /package/engine/{steering-constraints.js → agents/steering-constraints.js} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
// engine/distribution.js — identity of the *installed* Minions distribution.
|
|
1
|
+
// engine/operations/distribution.js — identity of the *installed* Minions distribution.
|
|
2
2
|
//
|
|
3
|
-
// Minions ships from one source tree as two npm packages (
|
|
3
|
+
// Minions ships from one source tree as two npm packages (scripts/prepare-package.js):
|
|
4
4
|
// • public → `@yemi33/minions` (npmjs, yemi33/minions)
|
|
5
5
|
// • internal → `@yemishin_microsoft/minions` (GitHub Packages; overridable
|
|
6
6
|
// at publish time via INTERNAL_PACKAGE_NAME)
|
|
@@ -34,9 +34,8 @@ const INTERNAL_WELCOME_MESSAGE = 'Welcome to the internal Minions!';
|
|
|
34
34
|
const INSTALLATION_ID_KEY = 'installationId';
|
|
35
35
|
const INTERNAL_WELCOME_ACK_KEY = 'internalWelcome';
|
|
36
36
|
|
|
37
|
-
// The installed package root
|
|
38
|
-
|
|
39
|
-
const PACKAGE_ROOT = path.join(__dirname, '..');
|
|
37
|
+
// The installed package root is two levels above this domain module.
|
|
38
|
+
const PACKAGE_ROOT = path.join(__dirname, '..', '..');
|
|
40
39
|
|
|
41
40
|
function _packageJsonPath(opts) {
|
|
42
41
|
if (opts && opts.packageJsonPath) return opts.packageJsonPath;
|
|
@@ -88,7 +87,7 @@ function resolveDistribution(opts) {
|
|
|
88
87
|
}
|
|
89
88
|
|
|
90
89
|
function _smallState() {
|
|
91
|
-
return require('
|
|
90
|
+
return require('../persistence/small-state-store');
|
|
92
91
|
}
|
|
93
92
|
|
|
94
93
|
function _newInstallationId() {
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* engine/cleanup.js — Periodic cleanup: temp files, worktrees, zombies, migrations.
|
|
2
|
+
* engine/orchestration/cleanup.js — Periodic cleanup: temp files, worktrees, zombies, migrations.
|
|
3
3
|
* Extracted from engine.js for modularity. No logic changes.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
const fs = require('fs');
|
|
7
7
|
const path = require('path');
|
|
8
|
-
const shared = require('
|
|
9
|
-
const queries = require('
|
|
10
|
-
const smallStateStore = require('
|
|
8
|
+
const shared = require('../core/shared');
|
|
9
|
+
const queries = require('../core/queries');
|
|
10
|
+
const smallStateStore = require('../persistence/small-state-store');
|
|
11
11
|
|
|
12
12
|
const { exec, execAsync, execSilent, log, ts, ENGINE_DEFAULTS } = shared;
|
|
13
13
|
const { safeJson, safeJsonArr, safeJsonNoRestore, safeWrite, safeReadDir, readWorkItems, readPullRequests, mutateCooldowns, mutateMetrics, mutateWorkItems, getProjects,
|
|
@@ -22,7 +22,7 @@ const PLANS_DIR = queries.PLANS_DIR;
|
|
|
22
22
|
// Lazy require to break circular dependency with engine.js
|
|
23
23
|
// Only needed for engine().activeProcesses — log/ts come from shared.js
|
|
24
24
|
let _engine = null;
|
|
25
|
-
function engine() { if (!_engine) _engine = require('
|
|
25
|
+
function engine() { if (!_engine) _engine = require('../../engine'); return _engine; }
|
|
26
26
|
|
|
27
27
|
// Lazy require for dispatch module
|
|
28
28
|
let _dispatch = null;
|
|
@@ -32,7 +32,7 @@ function dispatchModule() { if (!_dispatch) _dispatch = require('./dispatch'); r
|
|
|
32
32
|
// protected; idle-entry TTL cleanup remains owned by worktree-pool.pruneStale.
|
|
33
33
|
let _worktreePool = null;
|
|
34
34
|
function worktreePool() {
|
|
35
|
-
if (!_worktreePool) _worktreePool = require('
|
|
35
|
+
if (!_worktreePool) _worktreePool = require('../worktrees/pool');
|
|
36
36
|
return _worktreePool;
|
|
37
37
|
}
|
|
38
38
|
|
|
@@ -179,7 +179,7 @@ function cleanupMergedPrLocalBranch(root, project, pr) {
|
|
|
179
179
|
* Sweep leaked test-fixture meetings from a `meetings/` directory.
|
|
180
180
|
*
|
|
181
181
|
* Meeting unit/integration tests don't all honor MINIONS_TEST_DIR
|
|
182
|
-
* (engine/meeting.js is in ISOLATED_MODULES, but tests that load it after the
|
|
182
|
+
* (engine/orchestration/meeting.js is in ISOLATED_MODULES, but tests that load it after the
|
|
183
183
|
* env var is unset, or that fail before cleanup, leave `.json` + `.json.backup`
|
|
184
184
|
* sidecars behind). The engine's tick loop then re-discovers these fixtures
|
|
185
185
|
* every tick, fails playbook validation ("missing required template variables:
|
|
@@ -422,7 +422,7 @@ function pruneOrphanManagedLogs(opts = {}) {
|
|
|
422
422
|
const now = Number.isFinite(Number(opts.now)) ? Number(opts.now) : Date.now();
|
|
423
423
|
const specs = Array.isArray(opts.specs)
|
|
424
424
|
? opts.specs
|
|
425
|
-
: require('
|
|
425
|
+
: require('../processes/managed-spawn').listManagedSpecs();
|
|
426
426
|
const normalize = value => {
|
|
427
427
|
const resolved = path.resolve(String(value || ''));
|
|
428
428
|
return process.platform === 'win32' ? resolved.toLowerCase() : resolved;
|
|
@@ -640,7 +640,7 @@ async function runCleanup(config, verbose = false) {
|
|
|
640
640
|
cleaned.orphanWorktreeDirs = 0;
|
|
641
641
|
cleaned.worktreeReconcileFailed = 0;
|
|
642
642
|
try {
|
|
643
|
-
const reconcile = require('
|
|
643
|
+
const reconcile = require('../worktrees/gc').reconcileStaleWorktreeDirectories({
|
|
644
644
|
projects,
|
|
645
645
|
dispatchSnap: getDispatch(),
|
|
646
646
|
worktreeRootRel: config.engine?.worktreeRoot || ENGINE_DEFAULTS.worktreeRoot,
|
|
@@ -660,7 +660,7 @@ async function runCleanup(config, verbose = false) {
|
|
|
660
660
|
const _reapedScratchRoots = new Set(); // reap each worktree root's .agent-temp once per cleanup
|
|
661
661
|
let activeSharedBranchPlans = [];
|
|
662
662
|
try {
|
|
663
|
-
activeSharedBranchPlans = require('
|
|
663
|
+
activeSharedBranchPlans = require('../planning/prd-store').listPrdRows()
|
|
664
664
|
.map(row => row.plan)
|
|
665
665
|
.filter(plan => plan?.branch_strategy === 'shared-branch' && plan.feature_branch && plan.status !== 'completed');
|
|
666
666
|
} catch { /* optional */ }
|
|
@@ -773,7 +773,7 @@ async function runCleanup(config, verbose = false) {
|
|
|
773
773
|
// Sequential probing was the dominant cost in the cleanup phase
|
|
774
774
|
// (5–15s tick stall every 10 ticks at 50+ worktrees), but unbounded
|
|
775
775
|
// Promise.all would spawn 50+ concurrent git children — bad on Windows
|
|
776
|
-
// where each fork pays AV-scan overhead. Mirrors engine/ado.js:611.
|
|
776
|
+
// where each fork pays AV-scan overhead. Mirrors engine/ado/index.js:611.
|
|
777
777
|
const BRANCH_PROBE_CONCURRENCY = 5;
|
|
778
778
|
const branchMap = new Map();
|
|
779
779
|
for (let i = 0; i < allDirs.length; i += BRANCH_PROBE_CONCURRENCY) {
|
|
@@ -789,7 +789,7 @@ async function runCleanup(config, verbose = false) {
|
|
|
789
789
|
const _anchoredProcessCwds = [];
|
|
790
790
|
let _anchorProbeFailed = false;
|
|
791
791
|
try {
|
|
792
|
-
const _ms = require('
|
|
792
|
+
const _ms = require('../processes/managed-spawn');
|
|
793
793
|
for (const rec of _ms.listManagedSpecs()) {
|
|
794
794
|
if (rec && typeof rec.cwd === 'string' && rec.cwd.length > 0) {
|
|
795
795
|
try { _anchoredProcessCwds.push(shared.realPathForComparison(rec.cwd)); }
|
|
@@ -801,7 +801,7 @@ async function runCleanup(config, verbose = false) {
|
|
|
801
801
|
log('warn', `managed-spawn cwd anchor lookup failed: ${e.message}`);
|
|
802
802
|
}
|
|
803
803
|
try {
|
|
804
|
-
const _kp = require('
|
|
804
|
+
const _kp = require('../processes/keep-process-sweep');
|
|
805
805
|
_anchoredProcessCwds.push(..._kp.getActiveKeepProcessCwds());
|
|
806
806
|
} catch (e) {
|
|
807
807
|
_anchorProbeFailed = true;
|
|
@@ -1022,6 +1022,10 @@ async function runCleanup(config, verbose = false) {
|
|
|
1022
1022
|
}
|
|
1023
1023
|
} catch (e) { log('warn', 'worktree-pool prune: ' + e.message); }
|
|
1024
1024
|
|
|
1025
|
+
let processSnapshot = [];
|
|
1026
|
+
try { processSnapshot = shared.listAllProcesses(); }
|
|
1027
|
+
catch (e) { log('warn', 'cleanup process snapshot: ' + e.message); }
|
|
1028
|
+
|
|
1025
1029
|
// 4. Kill zombie agent processes not tracked by the engine
|
|
1026
1030
|
// List all node processes, check if any are running spawn-agent.js for our minions
|
|
1027
1031
|
try {
|
|
@@ -1043,11 +1047,12 @@ async function runCleanup(config, verbose = false) {
|
|
|
1043
1047
|
let pid;
|
|
1044
1048
|
try { pid = Number(fs.readFileSync(pidFilePath, 'utf8').trim()); } catch { return; }
|
|
1045
1049
|
if (activePids.has(pid)) return;
|
|
1046
|
-
if (
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1050
|
+
if (shared.terminateProcess('engine.cleanup.stale-agent-pid', { pid }, {
|
|
1051
|
+
recordedAtMs: stat.mtimeMs,
|
|
1052
|
+
processes: processSnapshot,
|
|
1053
|
+
skewMs: 2000,
|
|
1054
|
+
})) {
|
|
1055
|
+
cleaned.zombies++;
|
|
1051
1056
|
}
|
|
1052
1057
|
if (layout === 'dispatch-dir') {
|
|
1053
1058
|
try { shared.removeDispatchTmpDir(path.dirname(pidFilePath)); } catch {}
|
|
@@ -1056,24 +1061,22 @@ async function runCleanup(config, verbose = false) {
|
|
|
1056
1061
|
}
|
|
1057
1062
|
cleaned.stalePidFiles++;
|
|
1058
1063
|
});
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
}
|
|
1065
|
-
}
|
|
1064
|
+
cleaned.zombies += require('./timeout').cancelTrackedProcessesWithoutDispatch(
|
|
1065
|
+
activeProcesses,
|
|
1066
|
+
dispatch.active,
|
|
1067
|
+
{ processes: processSnapshot },
|
|
1068
|
+
);
|
|
1066
1069
|
} catch (e) { log('warn', 'cleanup zombie processes: ' + e.message); }
|
|
1067
1070
|
|
|
1068
|
-
// 4b.
|
|
1071
|
+
// 4b. Detect stray MCP descendants. Spawn-agent.js reaps its descendants on
|
|
1069
1072
|
// close, but a hard kill (engine restart, OS crash) can skip that path and
|
|
1070
1073
|
// leave orphan node.exe processes running MCP servers (Azure, Playwright,
|
|
1071
|
-
// Loop, etc.) reparented away from the Minions tree.
|
|
1072
|
-
//
|
|
1073
|
-
//
|
|
1074
|
+
// Loop, etc.) reparented away from the Minions tree. We cannot prove that an
|
|
1075
|
+
// unanchored global process belongs to this runtime, so report it without
|
|
1076
|
+
// killing it; leaking is safer than terminating another checkout's process.
|
|
1074
1077
|
cleaned.strayMcps = 0;
|
|
1075
1078
|
try {
|
|
1076
|
-
const allProcs =
|
|
1079
|
+
const allProcs = processSnapshot;
|
|
1077
1080
|
if (allProcs.length) {
|
|
1078
1081
|
const anchorPids = [process.pid];
|
|
1079
1082
|
for (const info of activeProcesses.values()) {
|
|
@@ -1093,8 +1096,8 @@ async function runCleanup(config, verbose = false) {
|
|
|
1093
1096
|
// any agents/<id>/keep-pids.json file are anchors, so the reachability
|
|
1094
1097
|
// walk treats them (and their MCP grandchildren) as legitimate.
|
|
1095
1098
|
try {
|
|
1096
|
-
const keepProcessSweep = require('
|
|
1097
|
-
for (const pid of keepProcessSweep.getActiveAnchorPids()) anchorPids.push(pid);
|
|
1099
|
+
const keepProcessSweep = require('../processes/keep-process-sweep');
|
|
1100
|
+
for (const pid of keepProcessSweep.getActiveAnchorPids({ processes: allProcs })) anchorPids.push(pid);
|
|
1098
1101
|
} catch (e) { log('warn', `cleanup: keep-process anchor lookup failed: ${e.message}`); }
|
|
1099
1102
|
const reach = shared.listProcessReachable(anchorPids, allProcs);
|
|
1100
1103
|
// MCP server commandlines. Matches scoped (@modelcontextprotocol/*,
|
|
@@ -1112,8 +1115,7 @@ async function runCleanup(config, verbose = false) {
|
|
|
1112
1115
|
strayPids.push(p.pid);
|
|
1113
1116
|
}
|
|
1114
1117
|
if (strayPids.length) {
|
|
1115
|
-
|
|
1116
|
-
log('info', `Cleanup: ${cleaned.strayMcps}/${strayPids.length} stray MCP descendants reaped`);
|
|
1118
|
+
log('warn', `Cleanup: detected ${strayPids.length} unanchored MCP process(es); leaving them running because ownership is unproven`);
|
|
1117
1119
|
}
|
|
1118
1120
|
}
|
|
1119
1121
|
} catch (e) { log('warn', 'cleanup stray MCPs: ' + e.message); }
|
|
@@ -1342,7 +1344,7 @@ async function runCleanup(config, verbose = false) {
|
|
|
1342
1344
|
// changes clobbered by this pass's stale in-memory copy (lost-update race —
|
|
1343
1345
|
// writePrd's _upsertPrd does a full-column data=? replace, not a merge).
|
|
1344
1346
|
try {
|
|
1345
|
-
const prdStore = require('
|
|
1347
|
+
const prdStore = require('../planning/prd-store');
|
|
1346
1348
|
const prdFiles = prdStore.listPrdRows().filter(row => !row.archived).map(row => row.filename);
|
|
1347
1349
|
for (const pf of prdFiles) {
|
|
1348
1350
|
// Cheap out-of-transaction peek to skip PRDs that clearly need no work;
|
|
@@ -1381,7 +1383,7 @@ async function runCleanup(config, verbose = false) {
|
|
|
1381
1383
|
queries.getWorkItems(config, { enrich: false }).map(wi => wi?.id).filter(Boolean)
|
|
1382
1384
|
);
|
|
1383
1385
|
|
|
1384
|
-
const prdStore = require('
|
|
1386
|
+
const prdStore = require('../planning/prd-store');
|
|
1385
1387
|
const orphanPrdEntries = prdStore.listPrdRows().filter(row => !row.archived).map(row => row.filename);
|
|
1386
1388
|
for (const pf of orphanPrdEntries) {
|
|
1387
1389
|
const peek = prdStore.readPrd(pf);
|
|
@@ -1598,7 +1600,7 @@ async function runCleanup(config, verbose = false) {
|
|
|
1598
1600
|
cleaned.expiredReviewCandidates = 0;
|
|
1599
1601
|
cleaned.prunedLifecycleEvents = 0;
|
|
1600
1602
|
try {
|
|
1601
|
-
const memoryStore = require('
|
|
1603
|
+
const memoryStore = require('../memory/memory-store');
|
|
1602
1604
|
cleaned.expiredReviewCandidates = memoryStore.expireStaleReviewLearningCandidates();
|
|
1603
1605
|
cleaned.prunedLifecycleEvents = memoryStore.pruneMemoryLifecycleEvents();
|
|
1604
1606
|
if (cleaned.expiredReviewCandidates > 0 || cleaned.prunedLifecycleEvents > 0) {
|
|
@@ -1608,20 +1610,45 @@ async function runCleanup(config, verbose = false) {
|
|
|
1608
1610
|
|
|
1609
1611
|
// 20. Recovery refs outlive the 24-hour quarantine-directory window so an
|
|
1610
1612
|
// operator can still recover preserved commits/WIP after directory cleanup.
|
|
1611
|
-
//
|
|
1613
|
+
// W-ms87rbe601a66d13 — bound that window at the SAME retention the protected
|
|
1614
|
+
// quarantine-DIRECTORY sweep uses (`engine.worktreeProtectedQuarantineRetentionMs`,
|
|
1615
|
+
// default `shared.QUARANTINE_REF_RETENTION_MS`) rather than the built-in
|
|
1616
|
+
// constant, so lowering the setting moves both sides together and `0` keeps
|
|
1617
|
+
// refs indefinitely exactly like the directories.
|
|
1612
1618
|
cleaned.quarantineRefs = 0;
|
|
1613
1619
|
try {
|
|
1614
|
-
const { pruneExpiredQuarantineRefs } = require('
|
|
1615
|
-
const
|
|
1620
|
+
const { pruneExpiredQuarantineRefs } = require('../worktrees/quarantine-refs');
|
|
1621
|
+
const retentionMs = shared.resolveQuarantineRetentionMs(config);
|
|
1622
|
+
const retentionDays = retentionMs / (24 * 60 * 60 * 1000);
|
|
1623
|
+
const result = await pruneExpiredQuarantineRefs(projects, { retentionMs });
|
|
1616
1624
|
cleaned.quarantineRefs = result.removed;
|
|
1617
|
-
|
|
1618
|
-
|
|
1625
|
+
cleaned.quarantineRefsMalformed = result.malformed;
|
|
1626
|
+
cleaned.quarantineRefFailures = result.failed;
|
|
1627
|
+
if (result.removed > 0 || result.failed > 0) {
|
|
1628
|
+
log('info', `cleanup: pruned ${result.removed}/${result.scanned} quarantine recovery ref(s) older than ${retentionDays} days (retained ${result.retained}, failed ${result.failed})`);
|
|
1629
|
+
}
|
|
1630
|
+
if (result.malformed > 0) {
|
|
1631
|
+
const sample = result.malformedRefs.slice(0, 5).map(entry => entry.ref).join(', ');
|
|
1632
|
+
log('warn', `quarantine-ref retention: preserved ${result.malformed} ref(s) with an unparseable timestamp: ${sample}`);
|
|
1619
1633
|
}
|
|
1620
1634
|
for (const failure of result.errors) {
|
|
1621
|
-
log('warn', `quarantine-ref retention (${failure.project || 'unknown project'}): ${failure.error}`);
|
|
1635
|
+
log('warn', `quarantine-ref retention (${failure.project || 'unknown project'}${failure.ref ? ` ${failure.ref}` : ''}): ${failure.error}`);
|
|
1622
1636
|
}
|
|
1623
1637
|
} catch (e) { log('warn', `quarantine-ref retention: ${e.message}`); }
|
|
1624
1638
|
|
|
1639
|
+
// 21. Superseded failed-scheduled work-item retention (W-msckn1lp002xdf6b).
|
|
1640
|
+
// Machine-generated scheduled-run failures (hourly review/fetch sweeps, etc.)
|
|
1641
|
+
// otherwise accumulate indefinitely. This daily sweep keeps the newest failure
|
|
1642
|
+
// per schedule for diagnosis and prunes older superseded failures past the 24h
|
|
1643
|
+
// window; human-authored / non-scheduled failures are never touched. Its own
|
|
1644
|
+
// cadence gate makes it a near no-op on most cleanup ticks.
|
|
1645
|
+
cleaned.failedScheduledPruned = 0;
|
|
1646
|
+
try {
|
|
1647
|
+
const { pruneSupersededFailedScheduledItems } = require('./failed-scheduled-cleanup');
|
|
1648
|
+
const result = pruneSupersededFailedScheduledItems(config);
|
|
1649
|
+
cleaned.failedScheduledPruned = (result && result.pruned) || 0;
|
|
1650
|
+
} catch (e) { log('warn', `failed-scheduled retention: ${e.message}`); }
|
|
1651
|
+
|
|
1625
1652
|
return cleaned;
|
|
1626
1653
|
}
|
|
1627
1654
|
|
|
@@ -1644,7 +1671,7 @@ function scrubStaleMetrics() {
|
|
|
1644
1671
|
|
|
1645
1672
|
/**
|
|
1646
1673
|
* Periodic per-tick worktree sweep. Aggregates the two pruners in
|
|
1647
|
-
* `engine/
|
|
1674
|
+
* `engine/worktrees/gc.js` so a long-lived engine catches orphans the
|
|
1648
1675
|
* boot-only reconcile would miss:
|
|
1649
1676
|
*
|
|
1650
1677
|
* - `pruneOrphanWorktrees`: walks `<localPath>/<worktreeRoot>` and reaps
|
|
@@ -1664,7 +1691,7 @@ function scrubStaleMetrics() {
|
|
|
1664
1691
|
* resolves with the same object after its final counters are refreshed.
|
|
1665
1692
|
*/
|
|
1666
1693
|
function runPeriodicWorktreeSweep(config) {
|
|
1667
|
-
const worktreeGc = require('
|
|
1694
|
+
const worktreeGc = require('../worktrees/gc');
|
|
1668
1695
|
const allProjects = getProjects(config);
|
|
1669
1696
|
// PL-live-checkout-reliability-hardening — EXCLUDE live-checkout projects from
|
|
1670
1697
|
// registry-derived destructive pruners. Filesystem reconciliation below still
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* engine/cooldown.js — Dispatch cooldowns, deduplication, and context coalescing.
|
|
2
|
+
* engine/orchestration/cooldown.js — Dispatch cooldowns, deduplication, and context coalescing.
|
|
3
3
|
* Extracted from engine.js.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
const shared = require('
|
|
7
|
-
const queries = require('
|
|
8
|
-
const smallStateStore = require('
|
|
6
|
+
const shared = require('../core/shared');
|
|
7
|
+
const queries = require('../core/queries');
|
|
8
|
+
const smallStateStore = require('../persistence/small-state-store');
|
|
9
9
|
|
|
10
10
|
const { mutateCooldowns, log, ENGINE_DEFAULTS } = shared;
|
|
11
11
|
|
|
@@ -274,7 +274,7 @@ function isAlreadyDispatched(key) {
|
|
|
274
274
|
*/
|
|
275
275
|
function isBranchActive(branch) {
|
|
276
276
|
if (!branch) return null;
|
|
277
|
-
const { sanitizeBranch } = require('
|
|
277
|
+
const { sanitizeBranch } = require('../core/shared');
|
|
278
278
|
const normalized = sanitizeBranch(branch);
|
|
279
279
|
const dispatch = queries.getDispatch();
|
|
280
280
|
return (dispatch.active || []).find(d => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* engine/dispatch-events.js — Single source of truth for dispatch terminal events.
|
|
2
|
+
* engine/orchestration/dispatch-events.js — Single source of truth for dispatch terminal events.
|
|
3
3
|
*
|
|
4
4
|
* W-mpob4nyk0006580e: The live view banner ("✓ Task complete" / "✗ Task ended
|
|
5
5
|
* with …") must mirror `dispatch.result` exactly. Previously the banner was
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
const fs = require('fs');
|
|
30
30
|
const path = require('path');
|
|
31
31
|
const { EventEmitter } = require('events');
|
|
32
|
-
const shared = require('
|
|
32
|
+
const shared = require('../core/shared');
|
|
33
33
|
|
|
34
34
|
const MAX_RING_ENTRIES = 50; // bound file size + memory; dev tool
|
|
35
35
|
const REPLAY_TTL_MS = 5 * 60 * 1000; // 5 min — long enough for tab refresh
|