@mclawnet/swarm 0.1.12 → 0.1.14
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/dist/__tests__/always-on-activity-reader.test.d.ts +2 -0
- package/dist/__tests__/always-on-activity-reader.test.d.ts.map +1 -0
- package/dist/__tests__/always-on-activity-reader.test.js +193 -0
- package/dist/__tests__/always-on-activity-reader.test.js.map +1 -0
- package/dist/__tests__/always-on-config.test.d.ts +2 -0
- package/dist/__tests__/always-on-config.test.d.ts.map +1 -0
- package/dist/__tests__/always-on-config.test.js +285 -0
- package/dist/__tests__/always-on-config.test.js.map +1 -0
- package/dist/__tests__/always-on-manager.test.d.ts +2 -0
- package/dist/__tests__/always-on-manager.test.d.ts.map +1 -0
- package/dist/__tests__/always-on-manager.test.js +797 -0
- package/dist/__tests__/always-on-manager.test.js.map +1 -0
- package/dist/__tests__/always-on-parity.test.d.ts +2 -0
- package/dist/__tests__/always-on-parity.test.d.ts.map +1 -0
- package/dist/__tests__/always-on-parity.test.js +20 -0
- package/dist/__tests__/always-on-parity.test.js.map +1 -0
- package/dist/__tests__/cascade-picker.test.d.ts +2 -0
- package/dist/__tests__/cascade-picker.test.d.ts.map +1 -0
- package/dist/__tests__/cascade-picker.test.js +122 -0
- package/dist/__tests__/cascade-picker.test.js.map +1 -0
- package/dist/__tests__/coordinator-shipment.test.d.ts +2 -0
- package/dist/__tests__/coordinator-shipment.test.d.ts.map +1 -0
- package/dist/__tests__/coordinator-shipment.test.js +280 -0
- package/dist/__tests__/coordinator-shipment.test.js.map +1 -0
- package/dist/__tests__/coordinator-workspace-recover.test.d.ts +2 -0
- package/dist/__tests__/coordinator-workspace-recover.test.d.ts.map +1 -0
- package/dist/__tests__/coordinator-workspace-recover.test.js +140 -0
- package/dist/__tests__/coordinator-workspace-recover.test.js.map +1 -0
- package/dist/__tests__/coordinator-workspace.test.d.ts +2 -0
- package/dist/__tests__/coordinator-workspace.test.d.ts.map +1 -0
- package/dist/__tests__/coordinator-workspace.test.js +135 -0
- package/dist/__tests__/coordinator-workspace.test.js.map +1 -0
- package/dist/__tests__/default-runner-epipe.test.d.ts +2 -0
- package/dist/__tests__/default-runner-epipe.test.d.ts.map +1 -0
- package/dist/__tests__/default-runner-epipe.test.js +43 -0
- package/dist/__tests__/default-runner-epipe.test.js.map +1 -0
- package/dist/__tests__/discovery-scheduler.test.d.ts +2 -0
- package/dist/__tests__/discovery-scheduler.test.d.ts.map +1 -0
- package/dist/__tests__/discovery-scheduler.test.js +367 -0
- package/dist/__tests__/discovery-scheduler.test.js.map +1 -0
- package/dist/__tests__/env-forward-e2e.test.d.ts +2 -0
- package/dist/__tests__/env-forward-e2e.test.d.ts.map +1 -0
- package/dist/__tests__/env-forward-e2e.test.js +57 -0
- package/dist/__tests__/env-forward-e2e.test.js.map +1 -0
- package/dist/__tests__/gh-pr-creator.test.d.ts +2 -0
- package/dist/__tests__/gh-pr-creator.test.d.ts.map +1 -0
- package/dist/__tests__/gh-pr-creator.test.js +107 -0
- package/dist/__tests__/gh-pr-creator.test.js.map +1 -0
- package/dist/__tests__/git-worktree-provider.test.d.ts +2 -0
- package/dist/__tests__/git-worktree-provider.test.d.ts.map +1 -0
- package/dist/__tests__/git-worktree-provider.test.js +98 -0
- package/dist/__tests__/git-worktree-provider.test.js.map +1 -0
- package/dist/__tests__/gitignore-check.test.d.ts +2 -0
- package/dist/__tests__/gitignore-check.test.d.ts.map +1 -0
- package/dist/__tests__/gitignore-check.test.js +39 -0
- package/dist/__tests__/gitignore-check.test.js.map +1 -0
- package/dist/__tests__/idea-research-source.test.d.ts +2 -0
- package/dist/__tests__/idea-research-source.test.d.ts.map +1 -0
- package/dist/__tests__/idea-research-source.test.js +425 -0
- package/dist/__tests__/idea-research-source.test.js.map +1 -0
- package/dist/__tests__/idea-todo-source.test.d.ts +2 -0
- package/dist/__tests__/idea-todo-source.test.d.ts.map +1 -0
- package/dist/__tests__/idea-todo-source.test.js +258 -0
- package/dist/__tests__/idea-todo-source.test.js.map +1 -0
- package/dist/__tests__/inbox-store-notbefore.test.d.ts +2 -0
- package/dist/__tests__/inbox-store-notbefore.test.d.ts.map +1 -0
- package/dist/__tests__/inbox-store-notbefore.test.js +47 -0
- package/dist/__tests__/inbox-store-notbefore.test.js.map +1 -0
- package/dist/__tests__/inbox-store-swarmid-validation.test.d.ts +2 -0
- package/dist/__tests__/inbox-store-swarmid-validation.test.d.ts.map +1 -0
- package/dist/__tests__/inbox-store-swarmid-validation.test.js +32 -0
- package/dist/__tests__/inbox-store-swarmid-validation.test.js.map +1 -0
- package/dist/__tests__/introspection-dedupe.test.d.ts +2 -0
- package/dist/__tests__/introspection-dedupe.test.d.ts.map +1 -0
- package/dist/__tests__/introspection-dedupe.test.js +484 -0
- package/dist/__tests__/introspection-dedupe.test.js.map +1 -0
- package/dist/__tests__/introspection-source.test.d.ts +2 -0
- package/dist/__tests__/introspection-source.test.d.ts.map +1 -0
- package/dist/__tests__/introspection-source.test.js +1051 -0
- package/dist/__tests__/introspection-source.test.js.map +1 -0
- package/dist/__tests__/migration-roles.test.js +1 -22
- package/dist/__tests__/migration-roles.test.js.map +1 -1
- package/dist/__tests__/reconcile-researching.test.d.ts +2 -0
- package/dist/__tests__/reconcile-researching.test.d.ts.map +1 -0
- package/dist/__tests__/reconcile-researching.test.js +224 -0
- package/dist/__tests__/reconcile-researching.test.js.map +1 -0
- package/dist/__tests__/role-loader-editor.test.js +40 -10
- package/dist/__tests__/role-loader-editor.test.js.map +1 -1
- package/dist/__tests__/role-loader-preamble-all.test.js +3 -1
- package/dist/__tests__/role-loader-preamble-all.test.js.map +1 -1
- package/dist/__tests__/role-loader.test.js +95 -0
- package/dist/__tests__/role-loader.test.js.map +1 -1
- package/dist/__tests__/role-prompt-no-legacy-protocol.test.js +3 -1
- package/dist/__tests__/role-prompt-no-legacy-protocol.test.js.map +1 -1
- package/dist/__tests__/secret-scrub.test.d.ts +2 -0
- package/dist/__tests__/secret-scrub.test.d.ts.map +1 -0
- package/dist/__tests__/secret-scrub.test.js +55 -0
- package/dist/__tests__/secret-scrub.test.js.map +1 -0
- package/dist/__tests__/shipment-actions.test.d.ts +2 -0
- package/dist/__tests__/shipment-actions.test.d.ts.map +1 -0
- package/dist/__tests__/shipment-actions.test.js +378 -0
- package/dist/__tests__/shipment-actions.test.js.map +1 -0
- package/dist/__tests__/shipment-persistence.test.d.ts +2 -0
- package/dist/__tests__/shipment-persistence.test.d.ts.map +1 -0
- package/dist/__tests__/shipment-persistence.test.js +120 -0
- package/dist/__tests__/shipment-persistence.test.js.map +1 -0
- package/dist/__tests__/shipment-pipeline.test.d.ts +2 -0
- package/dist/__tests__/shipment-pipeline.test.d.ts.map +1 -0
- package/dist/__tests__/shipment-pipeline.test.js +392 -0
- package/dist/__tests__/shipment-pipeline.test.js.map +1 -0
- package/dist/__tests__/shipment-report.test.d.ts +2 -0
- package/dist/__tests__/shipment-report.test.d.ts.map +1 -0
- package/dist/__tests__/shipment-report.test.js +78 -0
- package/dist/__tests__/shipment-report.test.js.map +1 -0
- package/dist/__tests__/shipment-stdin-integration.test.d.ts +2 -0
- package/dist/__tests__/shipment-stdin-integration.test.d.ts.map +1 -0
- package/dist/__tests__/shipment-stdin-integration.test.js +49 -0
- package/dist/__tests__/shipment-stdin-integration.test.js.map +1 -0
- package/dist/__tests__/shipment-type-parity.test.d.ts +2 -0
- package/dist/__tests__/shipment-type-parity.test.d.ts.map +1 -0
- package/dist/__tests__/shipment-type-parity.test.js +10 -0
- package/dist/__tests__/shipment-type-parity.test.js.map +1 -0
- package/dist/__tests__/snapshot-copy-provider.test.d.ts +2 -0
- package/dist/__tests__/snapshot-copy-provider.test.d.ts.map +1 -0
- package/dist/__tests__/snapshot-copy-provider.test.js +88 -0
- package/dist/__tests__/snapshot-copy-provider.test.js.map +1 -0
- package/dist/__tests__/swarm-coordinator-backend.test.js +153 -0
- package/dist/__tests__/swarm-coordinator-backend.test.js.map +1 -1
- package/dist/__tests__/swarm-coordinator-complete-intercept.test.d.ts +2 -0
- package/dist/__tests__/swarm-coordinator-complete-intercept.test.d.ts.map +1 -0
- package/dist/__tests__/swarm-coordinator-complete-intercept.test.js +111 -0
- package/dist/__tests__/swarm-coordinator-complete-intercept.test.js.map +1 -0
- package/dist/__tests__/task-store-source.test.d.ts +2 -0
- package/dist/__tests__/task-store-source.test.d.ts.map +1 -0
- package/dist/__tests__/task-store-source.test.js +56 -0
- package/dist/__tests__/task-store-source.test.js.map +1 -0
- package/dist/__tests__/template-loader-editor.test.js +28 -13
- package/dist/__tests__/template-loader-editor.test.js.map +1 -1
- package/dist/__tests__/transport-detect.test.d.ts +2 -0
- package/dist/__tests__/transport-detect.test.d.ts.map +1 -0
- package/dist/__tests__/transport-detect.test.js +92 -0
- package/dist/__tests__/transport-detect.test.js.map +1 -0
- package/dist/__tests__/wakeup-end-to-end.test.d.ts +2 -0
- package/dist/__tests__/wakeup-end-to-end.test.d.ts.map +1 -0
- package/dist/__tests__/wakeup-end-to-end.test.js +80 -0
- package/dist/__tests__/wakeup-end-to-end.test.js.map +1 -0
- package/dist/__tests__/wakeup-scheduler-restore-fires.test.d.ts +2 -0
- package/dist/__tests__/wakeup-scheduler-restore-fires.test.d.ts.map +1 -0
- package/dist/__tests__/wakeup-scheduler-restore-fires.test.js +33 -0
- package/dist/__tests__/wakeup-scheduler-restore-fires.test.js.map +1 -0
- package/dist/__tests__/wakeup-scheduler-restore.test.d.ts +2 -0
- package/dist/__tests__/wakeup-scheduler-restore.test.d.ts.map +1 -0
- package/dist/__tests__/wakeup-scheduler-restore.test.js +62 -0
- package/dist/__tests__/wakeup-scheduler-restore.test.js.map +1 -0
- package/dist/__tests__/wakeup-scheduler.test.d.ts +2 -0
- package/dist/__tests__/wakeup-scheduler.test.d.ts.map +1 -0
- package/dist/__tests__/wakeup-scheduler.test.js +65 -0
- package/dist/__tests__/wakeup-scheduler.test.js.map +1 -0
- package/dist/__tests__/watch-manager.test.d.ts +2 -0
- package/dist/__tests__/watch-manager.test.d.ts.map +1 -0
- package/dist/__tests__/watch-manager.test.js +203 -0
- package/dist/__tests__/watch-manager.test.js.map +1 -0
- package/dist/__tests__/workcycle-runner-cascade.test.d.ts +2 -0
- package/dist/__tests__/workcycle-runner-cascade.test.d.ts.map +1 -0
- package/dist/__tests__/workcycle-runner-cascade.test.js +203 -0
- package/dist/__tests__/workcycle-runner-cascade.test.js.map +1 -0
- package/dist/__tests__/workcycle-runner.test.d.ts +2 -0
- package/dist/__tests__/workcycle-runner.test.d.ts.map +1 -0
- package/dist/__tests__/workcycle-runner.test.js +369 -0
- package/dist/__tests__/workcycle-runner.test.js.map +1 -0
- package/dist/__tests__/workspace-diff.test.d.ts +2 -0
- package/dist/__tests__/workspace-diff.test.d.ts.map +1 -0
- package/dist/__tests__/workspace-diff.test.js +62 -0
- package/dist/__tests__/workspace-diff.test.js.map +1 -0
- package/dist/__tests__/workspace-manager.test.d.ts +2 -0
- package/dist/__tests__/workspace-manager.test.d.ts.map +1 -0
- package/dist/__tests__/workspace-manager.test.js +120 -0
- package/dist/__tests__/workspace-manager.test.js.map +1 -0
- package/dist/__tests__/workspace-types.test.d.ts +2 -0
- package/dist/__tests__/workspace-types.test.d.ts.map +1 -0
- package/dist/__tests__/workspace-types.test.js +37 -0
- package/dist/__tests__/workspace-types.test.js.map +1 -0
- package/dist/__tests__/worktree-gc.test.d.ts +2 -0
- package/dist/__tests__/worktree-gc.test.d.ts.map +1 -0
- package/dist/__tests__/worktree-gc.test.js +183 -0
- package/dist/__tests__/worktree-gc.test.js.map +1 -0
- package/dist/always-on/activity-reader.d.ts +27 -0
- package/dist/always-on/activity-reader.d.ts.map +1 -0
- package/dist/always-on/activity-reader.js +95 -0
- package/dist/always-on/activity-reader.js.map +1 -0
- package/dist/always-on/always-on-manager.d.ts +170 -0
- package/dist/always-on/always-on-manager.d.ts.map +1 -0
- package/dist/always-on/always-on-manager.js +538 -0
- package/dist/always-on/always-on-manager.js.map +1 -0
- package/dist/always-on/config.d.ts +141 -0
- package/dist/always-on/config.d.ts.map +1 -0
- package/dist/always-on/config.js +324 -0
- package/dist/always-on/config.js.map +1 -0
- package/dist/always-on/discovery-scheduler.d.ts +60 -0
- package/dist/always-on/discovery-scheduler.d.ts.map +1 -0
- package/dist/always-on/discovery-scheduler.js +287 -0
- package/dist/always-on/discovery-scheduler.js.map +1 -0
- package/dist/always-on/ideas-client.d.ts +23 -0
- package/dist/always-on/ideas-client.d.ts.map +1 -0
- package/dist/always-on/ideas-client.js +13 -0
- package/dist/always-on/ideas-client.js.map +1 -0
- package/dist/always-on/reconcile-researching.d.ts +42 -0
- package/dist/always-on/reconcile-researching.d.ts.map +1 -0
- package/dist/always-on/reconcile-researching.js +133 -0
- package/dist/always-on/reconcile-researching.js.map +1 -0
- package/dist/always-on/task-sources/cascade-picker.d.ts +42 -0
- package/dist/always-on/task-sources/cascade-picker.d.ts.map +1 -0
- package/dist/always-on/task-sources/cascade-picker.js +65 -0
- package/dist/always-on/task-sources/cascade-picker.js.map +1 -0
- package/dist/always-on/task-sources/idea-dedupe.d.ts +62 -0
- package/dist/always-on/task-sources/idea-dedupe.d.ts.map +1 -0
- package/dist/always-on/task-sources/idea-dedupe.js +130 -0
- package/dist/always-on/task-sources/idea-dedupe.js.map +1 -0
- package/dist/always-on/task-sources/idea-research-source.d.ts +46 -0
- package/dist/always-on/task-sources/idea-research-source.d.ts.map +1 -0
- package/dist/always-on/task-sources/idea-research-source.js +308 -0
- package/dist/always-on/task-sources/idea-research-source.js.map +1 -0
- package/dist/always-on/task-sources/idea-sort.d.ts +3 -0
- package/dist/always-on/task-sources/idea-sort.d.ts.map +1 -0
- package/dist/always-on/task-sources/idea-sort.js +25 -0
- package/dist/always-on/task-sources/idea-sort.js.map +1 -0
- package/dist/always-on/task-sources/idea-todo-source.d.ts +48 -0
- package/dist/always-on/task-sources/idea-todo-source.d.ts.map +1 -0
- package/dist/always-on/task-sources/idea-todo-source.js +226 -0
- package/dist/always-on/task-sources/idea-todo-source.js.map +1 -0
- package/dist/always-on/task-sources/introspection-source.d.ts +101 -0
- package/dist/always-on/task-sources/introspection-source.d.ts.map +1 -0
- package/dist/always-on/task-sources/introspection-source.js +695 -0
- package/dist/always-on/task-sources/introspection-source.js.map +1 -0
- package/dist/always-on/task-sources/task-store-source.d.ts +15 -0
- package/dist/always-on/task-sources/task-store-source.d.ts.map +1 -0
- package/dist/always-on/task-sources/task-store-source.js +59 -0
- package/dist/always-on/task-sources/task-store-source.js.map +1 -0
- package/dist/always-on/task-sources/types.d.ts +108 -0
- package/dist/always-on/task-sources/types.d.ts.map +1 -0
- package/dist/always-on/task-sources/types.js +13 -0
- package/dist/always-on/task-sources/types.js.map +1 -0
- package/dist/always-on/types.d.ts +76 -0
- package/dist/always-on/types.d.ts.map +1 -0
- package/dist/always-on/types.js +17 -0
- package/dist/always-on/types.js.map +1 -0
- package/dist/always-on/workcycle-runner.d.ts +115 -0
- package/dist/always-on/workcycle-runner.d.ts.map +1 -0
- package/dist/always-on/workcycle-runner.js +285 -0
- package/dist/always-on/workcycle-runner.js.map +1 -0
- package/dist/always-on/worktree-gc.d.ts +41 -0
- package/dist/always-on/worktree-gc.d.ts.map +1 -0
- package/dist/always-on/worktree-gc.js +167 -0
- package/dist/always-on/worktree-gc.js.map +1 -0
- package/dist/inbox-store.d.ts +7 -0
- package/dist/inbox-store.d.ts.map +1 -1
- package/dist/inbox-store.js +8 -1
- package/dist/inbox-store.js.map +1 -1
- package/dist/index.d.ts +29 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +27 -2
- package/dist/index.js.map +1 -1
- package/dist/persistence.d.ts +37 -1
- package/dist/persistence.d.ts.map +1 -1
- package/dist/persistence.js +48 -0
- package/dist/persistence.js.map +1 -1
- package/dist/retrospective.d.ts.map +1 -1
- package/dist/retrospective.js +6 -0
- package/dist/retrospective.js.map +1 -1
- package/dist/roles/role-loader.d.ts +31 -6
- package/dist/roles/role-loader.d.ts.map +1 -1
- package/dist/roles/role-loader.js +58 -32
- package/dist/roles/role-loader.js.map +1 -1
- package/dist/roles/types.d.ts +12 -0
- package/dist/roles/types.d.ts.map +1 -1
- package/dist/shipment/gh-pr-creator.d.ts +28 -0
- package/dist/shipment/gh-pr-creator.d.ts.map +1 -0
- package/dist/shipment/gh-pr-creator.js +80 -0
- package/dist/shipment/gh-pr-creator.js.map +1 -0
- package/dist/shipment/report.d.ts +27 -0
- package/dist/shipment/report.d.ts.map +1 -0
- package/dist/shipment/report.js +41 -0
- package/dist/shipment/report.js.map +1 -0
- package/dist/shipment/secret-scrub.d.ts +12 -0
- package/dist/shipment/secret-scrub.d.ts.map +1 -0
- package/dist/shipment/secret-scrub.js +30 -0
- package/dist/shipment/secret-scrub.js.map +1 -0
- package/dist/shipment/shipment-actions.d.ts +85 -0
- package/dist/shipment/shipment-actions.d.ts.map +1 -0
- package/dist/shipment/shipment-actions.js +190 -0
- package/dist/shipment/shipment-actions.js.map +1 -0
- package/dist/shipment/shipment-pipeline.d.ts +48 -0
- package/dist/shipment/shipment-pipeline.d.ts.map +1 -0
- package/dist/shipment/shipment-pipeline.js +256 -0
- package/dist/shipment/shipment-pipeline.js.map +1 -0
- package/dist/shipment/transport-detect.d.ts +16 -0
- package/dist/shipment/transport-detect.d.ts.map +1 -0
- package/dist/shipment/transport-detect.js +54 -0
- package/dist/shipment/transport-detect.js.map +1 -0
- package/dist/shipment/workspace-diff.d.ts +39 -0
- package/dist/shipment/workspace-diff.d.ts.map +1 -0
- package/dist/shipment/workspace-diff.js +64 -0
- package/dist/shipment/workspace-diff.js.map +1 -0
- package/dist/swarm-coordinator.d.ts +20 -1
- package/dist/swarm-coordinator.d.ts.map +1 -1
- package/dist/swarm-coordinator.js +193 -10
- package/dist/swarm-coordinator.js.map +1 -1
- package/dist/templates/template-loader.d.ts +23 -9
- package/dist/templates/template-loader.d.ts.map +1 -1
- package/dist/templates/template-loader.js +33 -26
- package/dist/templates/template-loader.js.map +1 -1
- package/dist/types.d.ts +62 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/wakeup-scheduler.d.ts +36 -0
- package/dist/wakeup-scheduler.d.ts.map +1 -0
- package/dist/wakeup-scheduler.js +107 -0
- package/dist/wakeup-scheduler.js.map +1 -0
- package/dist/watch-manager.d.ts +32 -0
- package/dist/watch-manager.d.ts.map +1 -0
- package/dist/watch-manager.js +153 -0
- package/dist/watch-manager.js.map +1 -0
- package/dist/workspace/git-worktree-provider.d.ts +11 -0
- package/dist/workspace/git-worktree-provider.d.ts.map +1 -0
- package/dist/workspace/git-worktree-provider.js +123 -0
- package/dist/workspace/git-worktree-provider.js.map +1 -0
- package/dist/workspace/gitignore-check.d.ts +10 -0
- package/dist/workspace/gitignore-check.d.ts.map +1 -0
- package/dist/workspace/gitignore-check.js +25 -0
- package/dist/workspace/gitignore-check.js.map +1 -0
- package/dist/workspace/index.d.ts +5 -0
- package/dist/workspace/index.d.ts.map +1 -0
- package/dist/workspace/index.js +5 -0
- package/dist/workspace/index.js.map +1 -0
- package/dist/workspace/snapshot-copy-provider.d.ts +11 -0
- package/dist/workspace/snapshot-copy-provider.d.ts.map +1 -0
- package/dist/workspace/snapshot-copy-provider.js +66 -0
- package/dist/workspace/snapshot-copy-provider.js.map +1 -0
- package/dist/workspace/types.d.ts +36 -0
- package/dist/workspace/types.d.ts.map +1 -0
- package/dist/workspace/types.js +2 -0
- package/dist/workspace/types.js.map +1 -0
- package/dist/workspace/workspace-manager.d.ts +30 -0
- package/dist/workspace/workspace-manager.d.ts.map +1 -0
- package/dist/workspace/workspace-manager.js +104 -0
- package/dist/workspace/workspace-manager.js.map +1 -0
- package/package.json +5 -5
- package/roles/queen.md +1 -0
- package/templates/introspection.md +64 -0
- package/templates/research-only.md +58 -0
- package/roles/preset-analyst-simons.md +0 -39
- package/roles/preset-architect-knuth.md +0 -39
- package/roles/preset-designer-norman.md +0 -39
- package/roles/preset-designer.md +0 -39
- package/roles/preset-dev-carmack.md +0 -39
- package/roles/preset-dev-gosling.md +0 -39
- package/roles/preset-developer.md +0 -52
- package/roles/preset-manager-grove.md +0 -39
- package/roles/preset-manager-musk.md +0 -39
- package/roles/preset-pm.md +0 -78
- package/roles/preset-researcher-feynman.md +0 -39
- package/roles/preset-reviewer.md +0 -46
- package/roles/preset-strategist-buffett.md +0 -39
- package/roles/preset-strategist-munger.md +0 -39
- package/roles/preset-strategist-sunzi.md +0 -39
- package/roles/preset-tester-beck.md +0 -40
- package/roles/preset-tester.md +0 -47
- package/roles/preset-writer-orwell.md +0 -39
- package/roles/preset-writer.md +0 -39
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
describe("WorkspaceProvider types", () => {
|
|
3
|
+
it("WorkspaceHandle has the expected shape (compile-time + runtime sanity)", () => {
|
|
4
|
+
const h = {
|
|
5
|
+
swarmId: "s1",
|
|
6
|
+
projectRoot: "/proj",
|
|
7
|
+
strategy: "git-worktree",
|
|
8
|
+
cwd: "/proj/.worktrees/s1",
|
|
9
|
+
metadata: { repoRoot: "/proj", baseCommit: "abc123", branchName: "clawnet/swarm-s1" },
|
|
10
|
+
};
|
|
11
|
+
expect(h.strategy).toBe("git-worktree");
|
|
12
|
+
expect(h.metadata.branchName).toBe("clawnet/swarm-s1");
|
|
13
|
+
});
|
|
14
|
+
it("WorkspaceStrategy union admits both variants", () => {
|
|
15
|
+
const a = "git-worktree";
|
|
16
|
+
const b = "snapshot-copy";
|
|
17
|
+
expect([a, b]).toHaveLength(2);
|
|
18
|
+
});
|
|
19
|
+
it("WorkspaceProvider interface enforces the four members", () => {
|
|
20
|
+
// Compile-time only: this fake implementation must satisfy the interface.
|
|
21
|
+
const fake = {
|
|
22
|
+
id: "git-worktree",
|
|
23
|
+
priority: 1,
|
|
24
|
+
isApplicable: async () => true,
|
|
25
|
+
prepare: async (input) => ({
|
|
26
|
+
swarmId: input.swarmId,
|
|
27
|
+
projectRoot: input.projectRoot,
|
|
28
|
+
strategy: "git-worktree",
|
|
29
|
+
cwd: "/x",
|
|
30
|
+
metadata: {},
|
|
31
|
+
}),
|
|
32
|
+
dispose: async () => { },
|
|
33
|
+
};
|
|
34
|
+
expect(fake.id).toBe("git-worktree");
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
//# sourceMappingURL=workspace-types.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace-types.test.js","sourceRoot":"","sources":["../../src/__tests__/workspace-types.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAG9C,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACvC,EAAE,CAAC,wEAAwE,EAAE,GAAG,EAAE;QAChF,MAAM,CAAC,GAAoB;YACzB,OAAO,EAAE,IAAI;YACb,WAAW,EAAE,OAAO;YACpB,QAAQ,EAAE,cAAc;YACxB,GAAG,EAAE,qBAAqB;YAC1B,QAAQ,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,kBAAkB,EAAE;SACtF,CAAC;QACF,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACxC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACtD,MAAM,CAAC,GAAsB,cAAc,CAAC;QAC5C,MAAM,CAAC,GAAsB,eAAe,CAAC;QAC7C,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,0EAA0E;QAC1E,MAAM,IAAI,GAAsB;YAC9B,EAAE,EAAE,cAAc;YAClB,QAAQ,EAAE,CAAC;YACX,YAAY,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI;YAC9B,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;gBACzB,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,QAAQ,EAAE,cAAc;gBACxB,GAAG,EAAE,IAAI;gBACT,QAAQ,EAAE,EAAE;aACb,CAAC;YACF,OAAO,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;SACxB,CAAC;QACF,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worktree-gc.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/worktree-gc.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
2
|
+
import { mkdirSync, mkdtempSync, rmSync, writeFileSync, existsSync, utimesSync, } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { projectRoot } from "@mclawnet/task";
|
|
6
|
+
import { gcWorktrees, DEFAULT_WORKTREE_GC_AGE_MS } from "../always-on/worktree-gc.js";
|
|
7
|
+
let WORK;
|
|
8
|
+
let HOME;
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
WORK = mkdtempSync(join(tmpdir(), "wgc-work-"));
|
|
11
|
+
HOME = mkdtempSync(join(tmpdir(), "wgc-home-"));
|
|
12
|
+
mkdirSync(join(WORK, ".worktrees"), { recursive: true });
|
|
13
|
+
});
|
|
14
|
+
afterEach(() => {
|
|
15
|
+
try {
|
|
16
|
+
rmSync(WORK, { recursive: true, force: true });
|
|
17
|
+
}
|
|
18
|
+
catch { /* ignore */ }
|
|
19
|
+
try {
|
|
20
|
+
rmSync(HOME, { recursive: true, force: true });
|
|
21
|
+
}
|
|
22
|
+
catch { /* ignore */ }
|
|
23
|
+
});
|
|
24
|
+
/** Create a fake worktree dir with one file; back-date its mtime by `ageMs`. */
|
|
25
|
+
function seedWorktree(name, ageMs, fileBytes = 100) {
|
|
26
|
+
const dir = join(WORK, ".worktrees", name);
|
|
27
|
+
mkdirSync(dir, { recursive: true });
|
|
28
|
+
const fp = join(dir, "fake-file.txt");
|
|
29
|
+
writeFileSync(fp, "x".repeat(fileBytes));
|
|
30
|
+
const past = new Date(Date.now() - ageMs);
|
|
31
|
+
utimesSync(dir, past, past);
|
|
32
|
+
utimesSync(fp, past, past);
|
|
33
|
+
return dir;
|
|
34
|
+
}
|
|
35
|
+
/** Create a swarm snapshot at the conventional path with `status`. */
|
|
36
|
+
function seedSnapshot(swarmId, status) {
|
|
37
|
+
const dir = join(projectRoot(WORK, HOME), "swarms", swarmId);
|
|
38
|
+
mkdirSync(dir, { recursive: true });
|
|
39
|
+
writeFileSync(join(dir, "recovery.json"), JSON.stringify({ id: swarmId, workDir: WORK, status }));
|
|
40
|
+
}
|
|
41
|
+
describe("gcWorktrees (PR-B Sub-PR-B4)", () => {
|
|
42
|
+
it("retains active swarms regardless of age", async () => {
|
|
43
|
+
// An old dir but its swarm is still running → must NOT delete
|
|
44
|
+
seedWorktree("active-old", 48 * 3600 * 1000); // 48h ago
|
|
45
|
+
seedSnapshot("active-old", "running");
|
|
46
|
+
const r = gcWorktrees({ workDir: WORK, home: HOME });
|
|
47
|
+
expect(r.scanned).toBe(1);
|
|
48
|
+
expect(r.removed).toBe(0);
|
|
49
|
+
expect(r.retained).toBe(1);
|
|
50
|
+
expect(r.decisions[0]).toMatchObject({ name: "active-old", action: "retained-active" });
|
|
51
|
+
expect(existsSync(join(WORK, ".worktrees", "active-old"))).toBe(true);
|
|
52
|
+
});
|
|
53
|
+
it("retains young dirs (within 24h debug window) even when swarm is terminal", async () => {
|
|
54
|
+
seedWorktree("young-failed", 1 * 3600 * 1000); // 1h ago
|
|
55
|
+
seedSnapshot("young-failed", "failed");
|
|
56
|
+
const r = gcWorktrees({ workDir: WORK, home: HOME });
|
|
57
|
+
expect(r.removed).toBe(0);
|
|
58
|
+
expect(r.retained).toBe(1);
|
|
59
|
+
expect(r.decisions[0].action).toBe("retained-young");
|
|
60
|
+
expect(existsSync(join(WORK, ".worktrees", "young-failed"))).toBe(true);
|
|
61
|
+
});
|
|
62
|
+
it("removes old dirs whose swarm is terminal (completed/failed/cancelled)", async () => {
|
|
63
|
+
seedWorktree("old-completed", 48 * 3600 * 1000);
|
|
64
|
+
seedSnapshot("old-completed", "completed");
|
|
65
|
+
const r = gcWorktrees({ workDir: WORK, home: HOME });
|
|
66
|
+
expect(r.removed).toBe(1);
|
|
67
|
+
expect(r.retained).toBe(0);
|
|
68
|
+
expect(r.decisions[0].action).toBe("removed");
|
|
69
|
+
expect(existsSync(join(WORK, ".worktrees", "old-completed"))).toBe(false);
|
|
70
|
+
});
|
|
71
|
+
it("removes old dirs with NO matching snapshot at all (snapshot already cleaned up)", async () => {
|
|
72
|
+
seedWorktree("orphan-old", 48 * 3600 * 1000);
|
|
73
|
+
// No snapshot seeded — coordinator already evicted it
|
|
74
|
+
const r = gcWorktrees({ workDir: WORK, home: HOME });
|
|
75
|
+
expect(r.removed).toBe(1);
|
|
76
|
+
expect(existsSync(join(WORK, ".worktrees", "orphan-old"))).toBe(false);
|
|
77
|
+
});
|
|
78
|
+
it("treats paused as ACTIVE (D14 runner will promote it next tick)", async () => {
|
|
79
|
+
seedWorktree("paused-old", 48 * 3600 * 1000);
|
|
80
|
+
seedSnapshot("paused-old", "paused");
|
|
81
|
+
const r = gcWorktrees({ workDir: WORK, home: HOME });
|
|
82
|
+
expect(r.removed).toBe(0);
|
|
83
|
+
expect(r.retained).toBe(1);
|
|
84
|
+
expect(r.decisions[0].action).toBe("retained-active");
|
|
85
|
+
});
|
|
86
|
+
it("scans + reaps multiple entries without touching worktree contents", async () => {
|
|
87
|
+
// PR-B follow-up — replaces the original "reports total bytes" case.
|
|
88
|
+
// Size telemetry was deleted because the recursive readdirSync/statSync
|
|
89
|
+
// walk it required pegged the agent at 99% CPU for ~15min per tick
|
|
90
|
+
// when worktrees contained node_modules (~70k files each). The reap
|
|
91
|
+
// decision only needs scanned/removed/retained — never the byte total.
|
|
92
|
+
seedWorktree("a-active", 1000, 200);
|
|
93
|
+
seedSnapshot("a-active", "running");
|
|
94
|
+
seedWorktree("b-removed", 48 * 3600 * 1000, 500);
|
|
95
|
+
seedSnapshot("b-removed", "completed");
|
|
96
|
+
seedWorktree("c-young", 1000, 300);
|
|
97
|
+
const r = gcWorktrees({ workDir: WORK, home: HOME });
|
|
98
|
+
expect(r.scanned).toBe(3);
|
|
99
|
+
expect(r.removed).toBe(1);
|
|
100
|
+
expect(r.retained).toBe(2);
|
|
101
|
+
// Size telemetry intentionally absent — re-introducing it MUST NOT
|
|
102
|
+
// walk worktree contents. See the doc comment at the top of
|
|
103
|
+
// worktree-gc.ts. Type-level + runtime double guard: ts-expect-error
|
|
104
|
+
// catches the regression at `tsc` time (no need to run vitest),
|
|
105
|
+
// toHaveProperty catches it at runtime in case someone adds the
|
|
106
|
+
// field via index signature / Record cast.
|
|
107
|
+
// @ts-expect-error — totalBytesBefore intentionally removed; see worktree-gc.ts header
|
|
108
|
+
void r.totalBytesBefore;
|
|
109
|
+
// @ts-expect-error — totalBytesAfter intentionally removed; see worktree-gc.ts header
|
|
110
|
+
void r.totalBytesAfter;
|
|
111
|
+
// @ts-expect-error — decisions[i].bytes intentionally removed; see worktree-gc.ts header
|
|
112
|
+
void r.decisions[0].bytes;
|
|
113
|
+
expect(r).not.toHaveProperty("totalBytesBefore");
|
|
114
|
+
expect(r).not.toHaveProperty("totalBytesAfter");
|
|
115
|
+
expect(r.decisions[0]).not.toHaveProperty("bytes");
|
|
116
|
+
});
|
|
117
|
+
it("dryRun=true counts but doesn't actually delete", async () => {
|
|
118
|
+
seedWorktree("dry-old", 48 * 3600 * 1000);
|
|
119
|
+
seedSnapshot("dry-old", "completed");
|
|
120
|
+
const r = gcWorktrees({ workDir: WORK, home: HOME, dryRun: true });
|
|
121
|
+
expect(r.removed).toBe(1);
|
|
122
|
+
expect(r.decisions[0].action).toBe("removed");
|
|
123
|
+
// BUT the dir still exists
|
|
124
|
+
expect(existsSync(join(WORK, ".worktrees", "dry-old"))).toBe(true);
|
|
125
|
+
});
|
|
126
|
+
it("no .worktrees/ dir → empty result, no error", () => {
|
|
127
|
+
const fresh = mkdtempSync(join(tmpdir(), "wgc-empty-"));
|
|
128
|
+
try {
|
|
129
|
+
const r = gcWorktrees({ workDir: fresh, home: HOME });
|
|
130
|
+
expect(r.scanned).toBe(0);
|
|
131
|
+
expect(r.removed).toBe(0);
|
|
132
|
+
expect(r.retained).toBe(0);
|
|
133
|
+
expect(r.decisions).toEqual([]);
|
|
134
|
+
}
|
|
135
|
+
finally {
|
|
136
|
+
rmSync(fresh, { recursive: true, force: true });
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
it("default maxAgeMs is 24h", () => {
|
|
140
|
+
expect(DEFAULT_WORKTREE_GC_AGE_MS).toBe(24 * 60 * 60 * 1000);
|
|
141
|
+
});
|
|
142
|
+
// PR-B follow-up regression — the original safeDirBytes walked every
|
|
143
|
+
// file under every worktree synchronously, including node_modules. In
|
|
144
|
+
// production this issued ~1M sync stat syscalls per tick, pegged the
|
|
145
|
+
// agent at 99% CPU for ~15min, and froze the Node event loop (silent
|
|
146
|
+
// log, agent_timeout from hub, InboxWatcher fs.watch never fires,
|
|
147
|
+
// swarm_complete_request stays delivered=false). The fix deleted the
|
|
148
|
+
// recursive walker entirely. This test pins that door shut: even when
|
|
149
|
+
// a worktree contains a fake node_modules tree, the result shape MUST
|
|
150
|
+
// NOT carry per-entry byte counts. Anyone re-introducing the walker
|
|
151
|
+
// would have to re-add the fields too, which fails the structural
|
|
152
|
+
// assertions below.
|
|
153
|
+
it("retains heavy worktree without exposing per-entry byte fields", () => {
|
|
154
|
+
const wtName = "fake-heavy";
|
|
155
|
+
const wtDir = join(WORK, ".worktrees", wtName);
|
|
156
|
+
mkdirSync(wtDir, { recursive: true });
|
|
157
|
+
seedSnapshot(wtName, "running"); // mark active → retained-active branch
|
|
158
|
+
// Realistic-shape fake node_modules under the worktree: 200 files
|
|
159
|
+
// across 20 sub-dirs. Detail doesn't matter to the assertion — it's
|
|
160
|
+
// here purely to fail-fast if any code re-adds a recursive walker
|
|
161
|
+
// that would inflate per-tick wall clock.
|
|
162
|
+
const nm = join(wtDir, "node_modules");
|
|
163
|
+
for (let i = 0; i < 20; i++) {
|
|
164
|
+
const pkg = join(nm, `pkg-${i}`);
|
|
165
|
+
mkdirSync(pkg, { recursive: true });
|
|
166
|
+
for (let j = 0; j < 10; j++) {
|
|
167
|
+
writeFileSync(join(pkg, `f-${j}.js`), "x".repeat(50));
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
const r = gcWorktrees({ workDir: WORK, home: HOME });
|
|
171
|
+
expect(r.scanned).toBe(1);
|
|
172
|
+
expect(r.retained).toBe(1);
|
|
173
|
+
expect(r.decisions[0].action).toBe("retained-active");
|
|
174
|
+
// The structural guard: byte counts are gone. If a future change
|
|
175
|
+
// re-introduces safeDirBytes (or any sync recursive walk over
|
|
176
|
+
// worktree contents), it'll need to add these fields back AND
|
|
177
|
+
// update consumers — these assertions force the conversation.
|
|
178
|
+
expect(r).not.toHaveProperty("totalBytesBefore");
|
|
179
|
+
expect(r).not.toHaveProperty("totalBytesAfter");
|
|
180
|
+
expect(r.decisions[0]).not.toHaveProperty("bytes");
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
//# sourceMappingURL=worktree-gc.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worktree-gc.test.js","sourceRoot":"","sources":["../../src/__tests__/worktree-gc.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { AlwaysOnActivityRecord } from "@mclawnet/shared";
|
|
2
|
+
export interface ReadActivityOptions {
|
|
3
|
+
/** Clamped to [1, 500] by readAlwaysOnActivity. Default 100. */
|
|
4
|
+
limit?: number;
|
|
5
|
+
/** Default 0. */
|
|
6
|
+
skip?: number;
|
|
7
|
+
/** Optional filter on tick decision. */
|
|
8
|
+
decision?: "fired" | "skipped" | "halted";
|
|
9
|
+
}
|
|
10
|
+
export interface ReadActivityResult {
|
|
11
|
+
ticks: AlwaysOnActivityRecord[];
|
|
12
|
+
hasMore: boolean;
|
|
13
|
+
/** Total count AFTER decision filter, BEFORE pagination. */
|
|
14
|
+
total: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Parse the always-on.log file under <projectRoot> and return a paginated
|
|
18
|
+
* newest-first slice.
|
|
19
|
+
*
|
|
20
|
+
* Tolerant by design:
|
|
21
|
+
* - Missing file → empty result (NOT an error).
|
|
22
|
+
* - Blank lines → skipped.
|
|
23
|
+
* - JSON.parse errors → that line is skipped (NOT thrown), so a single
|
|
24
|
+
* corrupt line never 500s the endpoint.
|
|
25
|
+
*/
|
|
26
|
+
export declare function readAlwaysOnActivity(workDir: string, home: string, opts?: ReadActivityOptions): ReadActivityResult;
|
|
27
|
+
//# sourceMappingURL=activity-reader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activity-reader.d.ts","sourceRoot":"","sources":["../../src/always-on/activity-reader.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAI/D,MAAM,WAAW,mBAAmB;IAClC,gEAAgE;IAChE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iBAAiB;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAC;CAC3C;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,sBAAsB,EAAE,CAAC;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,4DAA4D;IAC5D,KAAK,EAAE,MAAM,CAAC;CACf;AAKD;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,mBAAwB,GAC7B,kBAAkB,CAuCpB"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
// Always-on activity log reader (M9 t1).
|
|
2
|
+
//
|
|
3
|
+
// Pure read-path over `<projectRoot>/always-on.log` (JSONL, one tick per
|
|
4
|
+
// line). Written by AlwaysOnManager.appendLog; this module never touches
|
|
5
|
+
// the writer. Returns wire-shape records (AlwaysOnActivityRecord) so the
|
|
6
|
+
// Hub REST layer can pass them through verbatim.
|
|
7
|
+
//
|
|
8
|
+
// Known limitations (MVP):
|
|
9
|
+
// - Reads only `always-on.log`; the rotated `.log.1` backup is ignored.
|
|
10
|
+
// - Whole-file read + reverse: fine at ≤10MB cap; revisit if cap grows.
|
|
11
|
+
import { readFileSync } from "node:fs";
|
|
12
|
+
import { join } from "node:path";
|
|
13
|
+
import { projectRoot } from "@mclawnet/task";
|
|
14
|
+
const LOG_FILENAME = "always-on.log";
|
|
15
|
+
const DEFAULT_LIMIT = 100;
|
|
16
|
+
const MAX_LIMIT = 500;
|
|
17
|
+
/**
|
|
18
|
+
* Parse the always-on.log file under <projectRoot> and return a paginated
|
|
19
|
+
* newest-first slice.
|
|
20
|
+
*
|
|
21
|
+
* Tolerant by design:
|
|
22
|
+
* - Missing file → empty result (NOT an error).
|
|
23
|
+
* - Blank lines → skipped.
|
|
24
|
+
* - JSON.parse errors → that line is skipped (NOT thrown), so a single
|
|
25
|
+
* corrupt line never 500s the endpoint.
|
|
26
|
+
*/
|
|
27
|
+
export function readAlwaysOnActivity(workDir, home, opts = {}) {
|
|
28
|
+
const limit = clampLimit(opts.limit);
|
|
29
|
+
const skip = Math.max(0, Math.floor(opts.skip ?? 0));
|
|
30
|
+
const decision = opts.decision;
|
|
31
|
+
const path = join(projectRoot(workDir, home), LOG_FILENAME);
|
|
32
|
+
let raw;
|
|
33
|
+
try {
|
|
34
|
+
raw = readFileSync(path, "utf-8");
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
if (err?.code === "ENOENT") {
|
|
38
|
+
return { ticks: [], hasMore: false, total: 0 };
|
|
39
|
+
}
|
|
40
|
+
throw err;
|
|
41
|
+
}
|
|
42
|
+
const records = [];
|
|
43
|
+
for (const line of raw.split("\n")) {
|
|
44
|
+
const trimmed = line.trim();
|
|
45
|
+
if (!trimmed)
|
|
46
|
+
continue;
|
|
47
|
+
let parsed;
|
|
48
|
+
try {
|
|
49
|
+
parsed = JSON.parse(trimmed);
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
// Corrupt line — skip silently. Don't fail the whole read.
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
if (!isActivityRecord(parsed))
|
|
56
|
+
continue;
|
|
57
|
+
if (decision && parsed.decision !== decision)
|
|
58
|
+
continue;
|
|
59
|
+
records.push(parsed);
|
|
60
|
+
}
|
|
61
|
+
// Newest-first. JSONL is append-only chronological, so reversing is enough.
|
|
62
|
+
records.reverse();
|
|
63
|
+
const total = records.length;
|
|
64
|
+
const slice = records.slice(skip, skip + limit);
|
|
65
|
+
const hasMore = skip + slice.length < total;
|
|
66
|
+
return { ticks: slice, hasMore, total };
|
|
67
|
+
}
|
|
68
|
+
function clampLimit(input) {
|
|
69
|
+
if (input == null || !Number.isFinite(input))
|
|
70
|
+
return DEFAULT_LIMIT;
|
|
71
|
+
const n = Math.floor(input);
|
|
72
|
+
if (n < 1)
|
|
73
|
+
return 1;
|
|
74
|
+
if (n > MAX_LIMIT)
|
|
75
|
+
return MAX_LIMIT;
|
|
76
|
+
return n;
|
|
77
|
+
}
|
|
78
|
+
function isActivityRecord(value) {
|
|
79
|
+
if (!value || typeof value !== "object")
|
|
80
|
+
return false;
|
|
81
|
+
const obj = value;
|
|
82
|
+
if (typeof obj.at !== "string")
|
|
83
|
+
return false;
|
|
84
|
+
if (obj.decision !== "fired" &&
|
|
85
|
+
obj.decision !== "skipped" &&
|
|
86
|
+
obj.decision !== "halted") {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
if (!Array.isArray(obj.gateBreakdown))
|
|
90
|
+
return false;
|
|
91
|
+
if (typeof obj.durationMs !== "number")
|
|
92
|
+
return false;
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=activity-reader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"activity-reader.js","sourceRoot":"","sources":["../../src/always-on/activity-reader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import type { AlwaysOnSnapshot, AlwaysOnTickRecord } from "@mclawnet/shared";
|
|
2
|
+
import { WorkCycleRunner, type TaskRef } from "./workcycle-runner.js";
|
|
3
|
+
import type { TaskSource } from "./task-sources/types.js";
|
|
4
|
+
import type { TaskStore } from "@mclawnet/task";
|
|
5
|
+
import { type AlwaysOnConfig, type AlwaysOnPersistedConfig } from "./config.js";
|
|
6
|
+
import type { SwarmCoordinator } from "../swarm-coordinator.js";
|
|
7
|
+
export interface AlwaysOnManagerOptions {
|
|
8
|
+
home: string;
|
|
9
|
+
swarmCoordinator: SwarmCoordinator;
|
|
10
|
+
/**
|
|
11
|
+
* Picks the next task for a given project; null = nothing actionable.
|
|
12
|
+
* Backwards-compat (M7) single-source DI. When `taskSources` is also
|
|
13
|
+
* provided the cascade picker takes precedence — `pickNextTask` is then
|
|
14
|
+
* ignored, but kept in the type for callers that still pass it.
|
|
15
|
+
*/
|
|
16
|
+
pickNextTask?: (projectRoot: string) => Promise<TaskRef | null>;
|
|
17
|
+
/**
|
|
18
|
+
* M8.0 cascade source list. When provided the manager builds a
|
|
19
|
+
* CascadePicker over these sources and wires it into the runner with the
|
|
20
|
+
* source lifecycle hooks active. When omitted, falls back to the M7
|
|
21
|
+
* single-source `pickNextTask` DI above (or a TaskStore-backed source
|
|
22
|
+
* when `taskStore` is provided).
|
|
23
|
+
*/
|
|
24
|
+
taskSources?: TaskSource[];
|
|
25
|
+
/**
|
|
26
|
+
* Convenience: when neither `pickNextTask` nor `taskSources` is provided
|
|
27
|
+
* but a TaskStore factory is, the manager auto-wraps it into a default
|
|
28
|
+
* single-source cascade. Lets the agent pass just the store factory and
|
|
29
|
+
* get the same picking behaviour as M7.
|
|
30
|
+
*/
|
|
31
|
+
taskStore?: (projectRoot: string) => TaskStore | undefined;
|
|
32
|
+
/** Optional clock injection for tests. */
|
|
33
|
+
now?: () => Date;
|
|
34
|
+
/** Override the user-active window (tests). */
|
|
35
|
+
userActiveWindowMs?: number;
|
|
36
|
+
/** Override the log rotation byte cap (tests). */
|
|
37
|
+
logRotateBytes?: number;
|
|
38
|
+
/**
|
|
39
|
+
* Construct a WorkCycleRunner. Defaults to a real runner bound to the
|
|
40
|
+
* shared SwarmCoordinator + provided pickNextTask. Test-only override.
|
|
41
|
+
*/
|
|
42
|
+
runnerFactory?: (workDir: string) => WorkCycleRunner;
|
|
43
|
+
}
|
|
44
|
+
export declare class AlwaysOnManager {
|
|
45
|
+
private readonly home;
|
|
46
|
+
private readonly swarmCoordinator;
|
|
47
|
+
private readonly pickNextTask;
|
|
48
|
+
private readonly cascadePicker;
|
|
49
|
+
/**
|
|
50
|
+
* R3 I-B — kept around so `drainPending(workDir)` can iterate sources
|
|
51
|
+
* BEFORE the cascade runs each tick. The cascade picker itself only
|
|
52
|
+
* exposes filtered-pick semantics; the drain must bypass the filter so
|
|
53
|
+
* a source whose toggle was flipped off mid-flight still gets to reap
|
|
54
|
+
* its in-flight work.
|
|
55
|
+
*/
|
|
56
|
+
private readonly taskSources;
|
|
57
|
+
private readonly now;
|
|
58
|
+
private readonly userActiveWindowMs;
|
|
59
|
+
private readonly logRotateBytes;
|
|
60
|
+
private readonly runnerFactory?;
|
|
61
|
+
private readonly entries;
|
|
62
|
+
constructor(opts: AlwaysOnManagerOptions);
|
|
63
|
+
/**
|
|
64
|
+
* Boot (or rebuild) the scheduler for one project. Loads config from disk;
|
|
65
|
+
* restores ticksToday/lastFireAt when the persisted date matches today; if
|
|
66
|
+
* mode === "off", the scheduler is created but left stopped (cheap, lets
|
|
67
|
+
* `applyConfig` flip the switch later without re-instantiating).
|
|
68
|
+
*
|
|
69
|
+
* Idempotent: calling start() twice for the same project rebuilds; the old
|
|
70
|
+
* scheduler is stopped first to avoid duplicate timers.
|
|
71
|
+
*/
|
|
72
|
+
start(workDir: string): Promise<void>;
|
|
73
|
+
/** Stop the scheduler for a project and drop the entry. Idempotent. */
|
|
74
|
+
stop(workDir: string): Promise<void>;
|
|
75
|
+
/**
|
|
76
|
+
* Returns the live snapshot serialised to the wire format (Date → ISO),
|
|
77
|
+
* or null when no scheduler is booted for the project.
|
|
78
|
+
*/
|
|
79
|
+
snapshot(workDir: string): AlwaysOnSnapshot | null;
|
|
80
|
+
/**
|
|
81
|
+
* Re-sync the live scheduler with whatever's on disk right now (M7.3).
|
|
82
|
+
* The M7.2 projects-handler already does load→merge→save, then calls our
|
|
83
|
+
* hook with the new config. Rather than re-doing the persistence here we
|
|
84
|
+
* just pull the canonical state off disk and push it into the scheduler.
|
|
85
|
+
* Auto-boots if the project never started; idempotent otherwise.
|
|
86
|
+
*/
|
|
87
|
+
refreshFromDisk(workDir: string): Promise<void>;
|
|
88
|
+
/**
|
|
89
|
+
* Apply a config patch: merges over the persisted baseline, writes it back,
|
|
90
|
+
* updates the live scheduler in place. Auto-boots the scheduler when the
|
|
91
|
+
* project has never been started (UI may flip a mode on a fresh project).
|
|
92
|
+
*
|
|
93
|
+
* Returns the merged config and the post-update snapshot so callers can
|
|
94
|
+
* hand both back to the UI in one round trip.
|
|
95
|
+
*/
|
|
96
|
+
applyConfig(workDir: string, patch: Omit<Partial<AlwaysOnConfig>, "pausedUntil"> & {
|
|
97
|
+
pausedUntil?: string | null;
|
|
98
|
+
lastIntrospectionAt?: string | null;
|
|
99
|
+
lastIntrospectionRejected?: boolean | null;
|
|
100
|
+
pendingIntrospectionSwarmId?: string | null;
|
|
101
|
+
pendingIntrospectionWorkspaceCwd?: string | null;
|
|
102
|
+
}): Promise<{
|
|
103
|
+
config: AlwaysOnPersistedConfig;
|
|
104
|
+
snapshot: AlwaysOnSnapshot;
|
|
105
|
+
}>;
|
|
106
|
+
/**
|
|
107
|
+
* Record agent activity for the userActive gate. S1 hotfix: scoped per
|
|
108
|
+
* project. Pass `workDir` to update one project only; omit (or pass null)
|
|
109
|
+
* to broadcast to every entry — preserves the old global behaviour for
|
|
110
|
+
* callers that can't resolve a workDir from an inbound hub frame.
|
|
111
|
+
*/
|
|
112
|
+
recordActivity(workDir?: string | null): void;
|
|
113
|
+
/**
|
|
114
|
+
* B6 — force a tick immediately, clearing the per-project userActive
|
|
115
|
+
* timestamp first so the gate cascade doesn't skip on "user active <30min
|
|
116
|
+
* ago". Dev-only entrypoint: the hub gates the corresponding HTTP route on
|
|
117
|
+
* `NODE_ENV !== "production"` so this never reaches the agent in prod.
|
|
118
|
+
*
|
|
119
|
+
* Returns the TickRecord (decision + gateBreakdown + durationMs) and the
|
|
120
|
+
* post-tick snapshot in one call so the caller can show in dev tooling
|
|
121
|
+
* whether the force-tick fired or still skipped (e.g. on a real
|
|
122
|
+
* pausedUntil that genuinely should block).
|
|
123
|
+
*
|
|
124
|
+
* Note: only `lastActivityAt` is cleared. Other gates (pausedUntil,
|
|
125
|
+
* dailyBudget) intentionally still apply — force-tick is for bypassing
|
|
126
|
+
* the "I'm typing, don't fire" UX gate, not the user's explicit pause or
|
|
127
|
+
* the daily budget. Throws when no scheduler is booted for the project.
|
|
128
|
+
*/
|
|
129
|
+
forceTick(workDir: string): Promise<{
|
|
130
|
+
record: AlwaysOnTickRecord;
|
|
131
|
+
snapshot: AlwaysOnSnapshot;
|
|
132
|
+
}>;
|
|
133
|
+
/** Stop every per-project scheduler. Called on agent shutdown. */
|
|
134
|
+
disposeAll(): Promise<void>;
|
|
135
|
+
/**
|
|
136
|
+
* R3 I-B — public test/ops hook. Invokes `drainPending(workDir)` on every
|
|
137
|
+
* TaskSource that defines it, regardless of whether its toggle is on. This
|
|
138
|
+
* is the same drain that runs automatically inside `onFire` before each
|
|
139
|
+
* tick; exposed publicly so:
|
|
140
|
+
* - tests can simulate "user toggled off mid-flight → next tick reaps
|
|
141
|
+
* cleanly" without driving the scheduler timer, and
|
|
142
|
+
* - future ops surfaces (admin reseed, manual reconcile) can request a
|
|
143
|
+
* drain pass without firing a work cycle.
|
|
144
|
+
* Failures inside a single source are logged and swallowed — one source's
|
|
145
|
+
* drain must not break the manager's tick loop.
|
|
146
|
+
*/
|
|
147
|
+
drainAllSources(workDir: string): Promise<void>;
|
|
148
|
+
/**
|
|
149
|
+
* Hotfix C1 — map a TaskSource onto its taskSources toggle flag and
|
|
150
|
+
* resolve against the project's persisted config. Unknown source names
|
|
151
|
+
* default to enabled so non-standard sources (e.g. tests, future M9
|
|
152
|
+
* sources not yet listed in `AlwaysOnTaskSourcesConfig`) aren't silently
|
|
153
|
+
* dropped. Called fresh per pick by the cascade picker filter, so toggling
|
|
154
|
+
* a source on/off in the UI takes effect on the very next tick — no
|
|
155
|
+
* scheduler/picker rebuild required (the JSON read is cheap compared to a
|
|
156
|
+
* swarm spawn).
|
|
157
|
+
*/
|
|
158
|
+
private isSourceEnabledForProject;
|
|
159
|
+
/** User-facing gates: pausedUntil + userActive. */
|
|
160
|
+
private buildGates;
|
|
161
|
+
/**
|
|
162
|
+
* Persist ticksToday/lastFireAt AND append a jsonl line to always-on.log.
|
|
163
|
+
* Hooked into DiscoveryScheduler.onTick so every fired / skipped / halted
|
|
164
|
+
* decision is captured. Best-effort — write failures are logged but never
|
|
165
|
+
* thrown back into the scheduler tick loop.
|
|
166
|
+
*/
|
|
167
|
+
private onTick;
|
|
168
|
+
private appendLog;
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=always-on-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"always-on-manager.d.ts","sourceRoot":"","sources":["../../src/always-on/always-on-manager.ts"],"names":[],"mappings":"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"}
|