macro-agent 0.2.5 → 0.2.6
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/LICENSE +1 -1
- package/README.md +30 -56
- package/dist/acp/websocket-server.d.ts +6 -0
- package/dist/acp/websocket-server.d.ts.map +1 -1
- package/dist/acp/websocket-server.js +13 -0
- package/dist/acp/websocket-server.js.map +1 -1
- package/dist/acp/websocket-stream.d.ts +30 -0
- package/dist/acp/websocket-stream.d.ts.map +1 -0
- package/dist/acp/websocket-stream.js +118 -0
- package/dist/acp/websocket-stream.js.map +1 -0
- package/dist/activity/deduplication.d.ts +85 -0
- package/dist/activity/deduplication.d.ts.map +1 -0
- package/dist/activity/deduplication.js +149 -0
- package/dist/activity/deduplication.js.map +1 -0
- package/dist/activity/index.d.ts +16 -0
- package/dist/activity/index.d.ts.map +1 -0
- package/dist/activity/index.js +17 -0
- package/dist/activity/index.js.map +1 -0
- package/dist/activity/relevance.d.ts +81 -0
- package/dist/activity/relevance.d.ts.map +1 -0
- package/dist/activity/relevance.js +161 -0
- package/dist/activity/relevance.js.map +1 -0
- package/dist/activity/types.d.ts +169 -0
- package/dist/activity/types.d.ts.map +1 -0
- package/dist/activity/types.js +33 -0
- package/dist/activity/types.js.map +1 -0
- package/dist/activity/watcher.d.ts +64 -0
- package/dist/activity/watcher.d.ts.map +1 -0
- package/dist/activity/watcher.js +212 -0
- package/dist/activity/watcher.js.map +1 -0
- package/dist/adapters/federation.d.ts +8 -1
- package/dist/adapters/federation.d.ts.map +1 -1
- package/dist/adapters/federation.js +33 -2
- package/dist/adapters/federation.js.map +1 -1
- package/dist/agent/agent-manager-v2.d.ts.map +1 -1
- package/dist/agent/agent-manager-v2.js +7 -24
- package/dist/agent/agent-manager-v2.js.map +1 -1
- package/dist/agent/wake.d.ts +85 -0
- package/dist/agent/wake.d.ts.map +1 -0
- package/dist/agent/wake.js +278 -0
- package/dist/agent/wake.js.map +1 -0
- package/dist/api/server.d.ts.map +1 -1
- package/dist/api/server.js +41 -25
- package/dist/api/server.js.map +1 -1
- package/dist/api/types.d.ts +6 -0
- package/dist/api/types.d.ts.map +1 -1
- package/dist/auth/server-auth.d.ts +43 -0
- package/dist/auth/server-auth.d.ts.map +1 -0
- package/dist/auth/server-auth.js +80 -0
- package/dist/auth/server-auth.js.map +1 -0
- package/dist/auth/token.d.ts +4 -0
- package/dist/auth/token.d.ts.map +1 -1
- package/dist/auth/token.js +7 -6
- package/dist/auth/token.js.map +1 -1
- package/dist/boot-v2.d.ts +6 -3
- package/dist/boot-v2.d.ts.map +1 -1
- package/dist/boot-v2.js +44 -25
- package/dist/boot-v2.js.map +1 -1
- package/dist/cognitive/team-lifecycle.d.ts +82 -0
- package/dist/cognitive/team-lifecycle.d.ts.map +1 -0
- package/dist/cognitive/team-lifecycle.js +121 -0
- package/dist/cognitive/team-lifecycle.js.map +1 -0
- package/dist/cognitive/trajectory-extractor.d.ts +25 -0
- package/dist/cognitive/trajectory-extractor.d.ts.map +1 -0
- package/dist/cognitive/trajectory-extractor.js +134 -0
- package/dist/cognitive/trajectory-extractor.js.map +1 -0
- package/dist/control/control-server.d.ts.map +1 -1
- package/dist/control/control-server.js +10 -0
- package/dist/control/control-server.js.map +1 -1
- package/dist/dispatch/mail-inbound-consumer.d.ts.map +1 -1
- package/dist/dispatch/mail-inbound-consumer.js +43 -10
- package/dist/dispatch/mail-inbound-consumer.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -1
- package/dist/index.js.map +1 -1
- package/dist/lifecycle/handlers/generic.d.ts +27 -0
- package/dist/lifecycle/handlers/generic.d.ts.map +1 -0
- package/dist/lifecycle/handlers/generic.js +56 -0
- package/dist/lifecycle/handlers/generic.js.map +1 -0
- package/dist/lifecycle/handlers/index.d.ts +51 -0
- package/dist/lifecycle/handlers/index.d.ts.map +1 -0
- package/dist/lifecycle/handlers/index.js +110 -0
- package/dist/lifecycle/handlers/index.js.map +1 -0
- package/dist/lifecycle/handlers/integrator.d.ts +81 -0
- package/dist/lifecycle/handlers/integrator.d.ts.map +1 -0
- package/dist/lifecycle/handlers/integrator.js +451 -0
- package/dist/lifecycle/handlers/integrator.js.map +1 -0
- package/dist/lifecycle/handlers/monitor.d.ts +29 -0
- package/dist/lifecycle/handlers/monitor.d.ts.map +1 -0
- package/dist/lifecycle/handlers/monitor.js +79 -0
- package/dist/lifecycle/handlers/monitor.js.map +1 -0
- package/dist/lifecycle/handlers/worker.d.ts +56 -0
- package/dist/lifecycle/handlers/worker.d.ts.map +1 -0
- package/dist/lifecycle/handlers/worker.js +381 -0
- package/dist/lifecycle/handlers/worker.js.map +1 -0
- package/dist/lifecycle/handlers-v2.d.ts +0 -2
- package/dist/lifecycle/handlers-v2.d.ts.map +1 -1
- package/dist/lifecycle/handlers-v2.js +4 -55
- package/dist/lifecycle/handlers-v2.js.map +1 -1
- package/dist/mail/conversation-map.d.ts +33 -0
- package/dist/mail/conversation-map.d.ts.map +1 -0
- package/dist/mail/conversation-map.js +61 -0
- package/dist/mail/conversation-map.js.map +1 -0
- package/dist/mail/index.d.ts +11 -0
- package/dist/mail/index.d.ts.map +1 -0
- package/dist/mail/index.js +11 -0
- package/dist/mail/index.js.map +1 -0
- package/dist/mail/mail-service.d.ts +85 -0
- package/dist/mail/mail-service.d.ts.map +1 -0
- package/dist/mail/mail-service.js +121 -0
- package/dist/mail/mail-service.js.map +1 -0
- package/dist/mail/stores/eventstore-conversation-store.d.ts +40 -0
- package/dist/mail/stores/eventstore-conversation-store.d.ts.map +1 -0
- package/dist/mail/stores/eventstore-conversation-store.js +131 -0
- package/dist/mail/stores/eventstore-conversation-store.js.map +1 -0
- package/dist/mail/stores/eventstore-participant-store.d.ts +43 -0
- package/dist/mail/stores/eventstore-participant-store.d.ts.map +1 -0
- package/dist/mail/stores/eventstore-participant-store.js +145 -0
- package/dist/mail/stores/eventstore-participant-store.js.map +1 -0
- package/dist/mail/stores/eventstore-thread-store.d.ts +46 -0
- package/dist/mail/stores/eventstore-thread-store.d.ts.map +1 -0
- package/dist/mail/stores/eventstore-thread-store.js +118 -0
- package/dist/mail/stores/eventstore-thread-store.js.map +1 -0
- package/dist/mail/stores/eventstore-turn-store.d.ts +47 -0
- package/dist/mail/stores/eventstore-turn-store.d.ts.map +1 -0
- package/dist/mail/stores/eventstore-turn-store.js +153 -0
- package/dist/mail/stores/eventstore-turn-store.js.map +1 -0
- package/dist/mail/stores/index.d.ts +12 -0
- package/dist/mail/stores/index.d.ts.map +1 -0
- package/dist/mail/stores/index.js +12 -0
- package/dist/mail/stores/index.js.map +1 -0
- package/dist/mail/stores/types.d.ts +146 -0
- package/dist/mail/stores/types.d.ts.map +1 -0
- package/dist/mail/stores/types.js +13 -0
- package/dist/mail/stores/types.js.map +1 -0
- package/dist/mail/turn-recorder.d.ts +30 -0
- package/dist/mail/turn-recorder.d.ts.map +1 -0
- package/dist/mail/turn-recorder.js +98 -0
- package/dist/mail/turn-recorder.js.map +1 -0
- package/dist/map/adapter/acp-over-map.d.ts +115 -0
- package/dist/map/adapter/acp-over-map.d.ts.map +1 -0
- package/dist/map/adapter/acp-over-map.js +1024 -0
- package/dist/map/adapter/acp-over-map.js.map +1 -0
- package/dist/map/adapter/connection-manager.d.ts +150 -0
- package/dist/map/adapter/connection-manager.d.ts.map +1 -0
- package/dist/map/adapter/connection-manager.js +207 -0
- package/dist/map/adapter/connection-manager.js.map +1 -0
- package/dist/map/adapter/event-log.d.ts +87 -0
- package/dist/map/adapter/event-log.d.ts.map +1 -0
- package/dist/map/adapter/event-log.js +122 -0
- package/dist/map/adapter/event-log.js.map +1 -0
- package/dist/map/adapter/event-translator.d.ts +85 -0
- package/dist/map/adapter/event-translator.d.ts.map +1 -0
- package/dist/map/adapter/event-translator.js +295 -0
- package/dist/map/adapter/event-translator.js.map +1 -0
- package/dist/map/adapter/extensions/agent-detection.d.ts +49 -0
- package/dist/map/adapter/extensions/agent-detection.d.ts.map +1 -0
- package/dist/map/adapter/extensions/agent-detection.js +91 -0
- package/dist/map/adapter/extensions/agent-detection.js.map +1 -0
- package/dist/map/adapter/extensions/agent-lifecycle.d.ts +82 -0
- package/dist/map/adapter/extensions/agent-lifecycle.d.ts.map +1 -0
- package/dist/map/adapter/extensions/agent-lifecycle.js +164 -0
- package/dist/map/adapter/extensions/agent-lifecycle.js.map +1 -0
- package/dist/map/adapter/extensions/cognitive.d.ts +27 -0
- package/dist/map/adapter/extensions/cognitive.d.ts.map +1 -0
- package/dist/map/adapter/extensions/cognitive.js +158 -0
- package/dist/map/adapter/extensions/cognitive.js.map +1 -0
- package/dist/map/adapter/extensions/index.d.ts +95 -0
- package/dist/map/adapter/extensions/index.d.ts.map +1 -0
- package/dist/map/adapter/extensions/index.js +228 -0
- package/dist/map/adapter/extensions/index.js.map +1 -0
- package/dist/map/adapter/extensions/mcp-bridge.d.ts +57 -0
- package/dist/map/adapter/extensions/mcp-bridge.d.ts.map +1 -0
- package/dist/map/adapter/extensions/mcp-bridge.js +745 -0
- package/dist/map/adapter/extensions/mcp-bridge.js.map +1 -0
- package/dist/map/adapter/extensions/resume.d.ts +47 -0
- package/dist/map/adapter/extensions/resume.d.ts.map +1 -0
- package/dist/map/adapter/extensions/resume.js +59 -0
- package/dist/map/adapter/extensions/resume.js.map +1 -0
- package/dist/map/adapter/extensions/streams.d.ts +95 -0
- package/dist/map/adapter/extensions/streams.d.ts.map +1 -0
- package/dist/map/adapter/extensions/streams.js +515 -0
- package/dist/map/adapter/extensions/streams.js.map +1 -0
- package/dist/map/adapter/extensions/task.d.ts +40 -0
- package/dist/map/adapter/extensions/task.d.ts.map +1 -0
- package/dist/map/adapter/extensions/task.js +197 -0
- package/dist/map/adapter/extensions/task.js.map +1 -0
- package/dist/map/adapter/extensions/update-metadata.d.ts +29 -0
- package/dist/map/adapter/extensions/update-metadata.d.ts.map +1 -0
- package/dist/map/adapter/extensions/update-metadata.js +67 -0
- package/dist/map/adapter/extensions/update-metadata.js.map +1 -0
- package/dist/map/adapter/extensions/wake.d.ts +60 -0
- package/dist/map/adapter/extensions/wake.d.ts.map +1 -0
- package/dist/map/adapter/extensions/wake.js +144 -0
- package/dist/map/adapter/extensions/wake.js.map +1 -0
- package/dist/map/adapter/extensions/workspace-files.d.ts +42 -0
- package/dist/map/adapter/extensions/workspace-files.d.ts.map +1 -0
- package/dist/map/adapter/extensions/workspace-files.js +338 -0
- package/dist/map/adapter/extensions/workspace-files.js.map +1 -0
- package/dist/map/adapter/extensions/workspace.d.ts +57 -0
- package/dist/map/adapter/extensions/workspace.d.ts.map +1 -0
- package/dist/map/adapter/extensions/workspace.js +81 -0
- package/dist/map/adapter/extensions/workspace.js.map +1 -0
- package/dist/map/adapter/index.d.ts +20 -0
- package/dist/map/adapter/index.d.ts.map +1 -0
- package/dist/map/adapter/index.js +40 -0
- package/dist/map/adapter/index.js.map +1 -0
- package/dist/map/adapter/interface.d.ts +450 -0
- package/dist/map/adapter/interface.d.ts.map +1 -0
- package/dist/map/adapter/interface.js +24 -0
- package/dist/map/adapter/interface.js.map +1 -0
- package/dist/map/adapter/mail-handler-adapter.d.ts +27 -0
- package/dist/map/adapter/mail-handler-adapter.d.ts.map +1 -0
- package/dist/map/adapter/mail-handler-adapter.js +292 -0
- package/dist/map/adapter/mail-handler-adapter.js.map +1 -0
- package/dist/map/adapter/map-adapter.d.ts +200 -0
- package/dist/map/adapter/map-adapter.d.ts.map +1 -0
- package/dist/map/adapter/map-adapter.js +1199 -0
- package/dist/map/adapter/map-adapter.js.map +1 -0
- package/dist/map/adapter/rpc-handler.d.ts +263 -0
- package/dist/map/adapter/rpc-handler.d.ts.map +1 -0
- package/dist/map/adapter/rpc-handler.js +365 -0
- package/dist/map/adapter/rpc-handler.js.map +1 -0
- package/dist/map/adapter/subscription-manager.d.ts +174 -0
- package/dist/map/adapter/subscription-manager.d.ts.map +1 -0
- package/dist/map/adapter/subscription-manager.js +248 -0
- package/dist/map/adapter/subscription-manager.js.map +1 -0
- package/dist/map/adapter/types.d.ts +194 -0
- package/dist/map/adapter/types.d.ts.map +1 -0
- package/dist/map/adapter/types.js +27 -0
- package/dist/map/adapter/types.js.map +1 -0
- package/dist/map/adapter/websocket-integration.d.ts +113 -0
- package/dist/map/adapter/websocket-integration.d.ts.map +1 -0
- package/dist/map/adapter/websocket-integration.js +134 -0
- package/dist/map/adapter/websocket-integration.js.map +1 -0
- package/dist/map/cascade-action-handler.d.ts.map +1 -1
- package/dist/map/cascade-action-handler.js +19 -5
- package/dist/map/cascade-action-handler.js.map +1 -1
- package/dist/map/federation/envelope.d.ts +98 -0
- package/dist/map/federation/envelope.d.ts.map +1 -0
- package/dist/map/federation/envelope.js +160 -0
- package/dist/map/federation/envelope.js.map +1 -0
- package/dist/map/federation/federation-handler.d.ts +50 -0
- package/dist/map/federation/federation-handler.d.ts.map +1 -0
- package/dist/map/federation/federation-handler.js +306 -0
- package/dist/map/federation/federation-handler.js.map +1 -0
- package/dist/map/federation/index.d.ts +14 -0
- package/dist/map/federation/index.d.ts.map +1 -0
- package/dist/map/federation/index.js +13 -0
- package/dist/map/federation/index.js.map +1 -0
- package/dist/map/federation/types.d.ts +239 -0
- package/dist/map/federation/types.d.ts.map +1 -0
- package/dist/map/federation/types.js +23 -0
- package/dist/map/federation/types.js.map +1 -0
- package/dist/map/server.d.ts.map +1 -1
- package/dist/map/server.js +17 -2
- package/dist/map/server.js.map +1 -1
- package/dist/map/types.d.ts +6 -0
- package/dist/map/types.d.ts.map +1 -1
- package/dist/mcp/map-client.d.ts +39 -0
- package/dist/mcp/map-client.d.ts.map +1 -0
- package/dist/mcp/map-client.js +129 -0
- package/dist/mcp/map-client.js.map +1 -0
- package/dist/mcp/mcp-server.d.ts +72 -0
- package/dist/mcp/mcp-server.d.ts.map +1 -0
- package/dist/mcp/mcp-server.js +1027 -0
- package/dist/mcp/mcp-server.js.map +1 -0
- package/dist/mcp/tools/claim_task.d.ts +35 -0
- package/dist/mcp/tools/claim_task.d.ts.map +1 -0
- package/dist/mcp/tools/claim_task.js +58 -0
- package/dist/mcp/tools/claim_task.js.map +1 -0
- package/dist/mcp/tools/done-v2.d.ts +0 -1
- package/dist/mcp/tools/done-v2.d.ts.map +1 -1
- package/dist/mcp/tools/done-v2.js +0 -1
- package/dist/mcp/tools/done-v2.js.map +1 -1
- package/dist/mcp/tools/done.d.ts +102 -0
- package/dist/mcp/tools/done.d.ts.map +1 -0
- package/dist/mcp/tools/done.js +253 -0
- package/dist/mcp/tools/done.js.map +1 -0
- package/dist/mcp/tools/inject_context.d.ts +61 -0
- package/dist/mcp/tools/inject_context.d.ts.map +1 -0
- package/dist/mcp/tools/inject_context.js +123 -0
- package/dist/mcp/tools/inject_context.js.map +1 -0
- package/dist/mcp/tools/list_claimable_tasks.d.ts +38 -0
- package/dist/mcp/tools/list_claimable_tasks.d.ts.map +1 -0
- package/dist/mcp/tools/list_claimable_tasks.js +63 -0
- package/dist/mcp/tools/list_claimable_tasks.js.map +1 -0
- package/dist/mcp/tools/unclaim_task.d.ts +31 -0
- package/dist/mcp/tools/unclaim_task.d.ts.map +1 -0
- package/dist/mcp/tools/unclaim_task.js +47 -0
- package/dist/mcp/tools/unclaim_task.js.map +1 -0
- package/dist/mcp/tools/wait_for_activity.d.ts +60 -0
- package/dist/mcp/tools/wait_for_activity.d.ts.map +1 -0
- package/dist/mcp/tools/wait_for_activity.js +135 -0
- package/dist/mcp/tools/wait_for_activity.js.map +1 -0
- package/dist/monitor/health-check-service.d.ts +143 -0
- package/dist/monitor/health-check-service.d.ts.map +1 -0
- package/dist/monitor/health-check-service.js +240 -0
- package/dist/monitor/health-check-service.js.map +1 -0
- package/dist/monitor/index.d.ts +14 -0
- package/dist/monitor/index.d.ts.map +1 -0
- package/dist/monitor/index.js +14 -0
- package/dist/monitor/index.js.map +1 -0
- package/dist/monitor/stall-detector.d.ts +109 -0
- package/dist/monitor/stall-detector.d.ts.map +1 -0
- package/dist/monitor/stall-detector.js +152 -0
- package/dist/monitor/stall-detector.js.map +1 -0
- package/dist/peer/capability-manager.d.ts +56 -0
- package/dist/peer/capability-manager.d.ts.map +1 -0
- package/dist/peer/capability-manager.js +186 -0
- package/dist/peer/capability-manager.js.map +1 -0
- package/dist/peer/encapsulation-manager.d.ts +190 -0
- package/dist/peer/encapsulation-manager.d.ts.map +1 -0
- package/dist/peer/encapsulation-manager.js +486 -0
- package/dist/peer/encapsulation-manager.js.map +1 -0
- package/dist/peer/federation-manager.d.ts +223 -0
- package/dist/peer/federation-manager.d.ts.map +1 -0
- package/dist/peer/federation-manager.js +528 -0
- package/dist/peer/federation-manager.js.map +1 -0
- package/dist/peer/hierarchy-errors.d.ts +208 -0
- package/dist/peer/hierarchy-errors.d.ts.map +1 -0
- package/dist/peer/hierarchy-errors.js +268 -0
- package/dist/peer/hierarchy-errors.js.map +1 -0
- package/dist/peer/hierarchy-protocol.d.ts +159 -0
- package/dist/peer/hierarchy-protocol.d.ts.map +1 -0
- package/dist/peer/hierarchy-protocol.js +142 -0
- package/dist/peer/hierarchy-protocol.js.map +1 -0
- package/dist/peer/index.d.ts +15 -0
- package/dist/peer/index.d.ts.map +1 -0
- package/dist/peer/index.js +15 -0
- package/dist/peer/index.js.map +1 -0
- package/dist/peer/peer-manager.d.ts +99 -0
- package/dist/peer/peer-manager.d.ts.map +1 -0
- package/dist/peer/peer-manager.js +333 -0
- package/dist/peer/peer-manager.js.map +1 -0
- package/dist/peer/task-delegation.d.ts +189 -0
- package/dist/peer/task-delegation.d.ts.map +1 -0
- package/dist/peer/task-delegation.js +303 -0
- package/dist/peer/task-delegation.js.map +1 -0
- package/dist/peer/transports/index.d.ts +8 -0
- package/dist/peer/transports/index.d.ts.map +1 -0
- package/dist/peer/transports/index.js +8 -0
- package/dist/peer/transports/index.js.map +1 -0
- package/dist/peer/transports/local-transport.d.ts +56 -0
- package/dist/peer/transports/local-transport.d.ts.map +1 -0
- package/dist/peer/transports/local-transport.js +263 -0
- package/dist/peer/transports/local-transport.js.map +1 -0
- package/dist/peer/transports/websocket-transport.d.ts +86 -0
- package/dist/peer/transports/websocket-transport.d.ts.map +1 -0
- package/dist/peer/transports/websocket-transport.js +338 -0
- package/dist/peer/transports/websocket-transport.js.map +1 -0
- package/dist/peer/types.d.ts +268 -0
- package/dist/peer/types.d.ts.map +1 -0
- package/dist/peer/types.js +36 -0
- package/dist/peer/types.js.map +1 -0
- package/dist/router/address-resolver.d.ts +102 -0
- package/dist/router/address-resolver.d.ts.map +1 -0
- package/dist/router/address-resolver.js +198 -0
- package/dist/router/address-resolver.js.map +1 -0
- package/dist/router/broadcast.d.ts +53 -0
- package/dist/router/broadcast.d.ts.map +1 -0
- package/dist/router/broadcast.js +75 -0
- package/dist/router/broadcast.js.map +1 -0
- package/dist/router/channels.d.ts +148 -0
- package/dist/router/channels.d.ts.map +1 -0
- package/dist/router/channels.js +126 -0
- package/dist/router/channels.js.map +1 -0
- package/dist/router/index.d.ts +21 -0
- package/dist/router/index.d.ts.map +1 -0
- package/dist/router/index.js +18 -0
- package/dist/router/index.js.map +1 -0
- package/dist/router/message-router.d.ts +197 -0
- package/dist/router/message-router.d.ts.map +1 -0
- package/dist/router/message-router.js +903 -0
- package/dist/router/message-router.js.map +1 -0
- package/dist/router/message-types.d.ts +183 -0
- package/dist/router/message-types.d.ts.map +1 -0
- package/dist/router/message-types.js +79 -0
- package/dist/router/message-types.js.map +1 -0
- package/dist/router/role-resolver.d.ts +67 -0
- package/dist/router/role-resolver.d.ts.map +1 -0
- package/dist/router/role-resolver.js +106 -0
- package/dist/router/role-resolver.js.map +1 -0
- package/dist/router/signals.d.ts +253 -0
- package/dist/router/signals.d.ts.map +1 -0
- package/dist/router/signals.js +53 -0
- package/dist/router/signals.js.map +1 -0
- package/dist/router/types.d.ts +191 -0
- package/dist/router/types.d.ts.map +1 -0
- package/dist/router/types.js +34 -0
- package/dist/router/types.js.map +1 -0
- package/dist/router/wake.d.ts +111 -0
- package/dist/router/wake.d.ts.map +1 -0
- package/dist/router/wake.js +180 -0
- package/dist/router/wake.js.map +1 -0
- package/dist/server/combined-server.d.ts +95 -0
- package/dist/server/combined-server.d.ts.map +1 -0
- package/dist/server/combined-server.js +335 -0
- package/dist/server/combined-server.js.map +1 -0
- package/dist/steering/index.d.ts +11 -0
- package/dist/steering/index.d.ts.map +1 -0
- package/dist/steering/index.js +11 -0
- package/dist/steering/index.js.map +1 -0
- package/dist/steering/inject.d.ts +39 -0
- package/dist/steering/inject.d.ts.map +1 -0
- package/dist/steering/inject.js +197 -0
- package/dist/steering/inject.js.map +1 -0
- package/dist/steering/types.d.ts +100 -0
- package/dist/steering/types.d.ts.map +1 -0
- package/dist/steering/types.js +11 -0
- package/dist/steering/types.js.map +1 -0
- package/dist/store/backends/index.d.ts +11 -0
- package/dist/store/backends/index.d.ts.map +1 -0
- package/dist/store/backends/index.js +15 -0
- package/dist/store/backends/index.js.map +1 -0
- package/dist/store/backends/json-backend.d.ts +23 -0
- package/dist/store/backends/json-backend.d.ts.map +1 -0
- package/dist/store/backends/json-backend.js +220 -0
- package/dist/store/backends/json-backend.js.map +1 -0
- package/dist/store/backends/memory-backend.d.ts +12 -0
- package/dist/store/backends/memory-backend.d.ts.map +1 -0
- package/dist/store/backends/memory-backend.js +205 -0
- package/dist/store/backends/memory-backend.js.map +1 -0
- package/dist/store/backends/sqlite-backend.d.ts +27 -0
- package/dist/store/backends/sqlite-backend.d.ts.map +1 -0
- package/dist/store/backends/sqlite-backend.js +231 -0
- package/dist/store/backends/sqlite-backend.js.map +1 -0
- package/dist/store/backends/tinybase-backend.d.ts +22 -0
- package/dist/store/backends/tinybase-backend.d.ts.map +1 -0
- package/dist/store/backends/tinybase-backend.js +203 -0
- package/dist/store/backends/tinybase-backend.js.map +1 -0
- package/dist/store/backends/types.d.ts +175 -0
- package/dist/store/backends/types.d.ts.map +1 -0
- package/dist/store/backends/types.js +28 -0
- package/dist/store/backends/types.js.map +1 -0
- package/dist/store/event-store.d.ts +128 -0
- package/dist/store/event-store.d.ts.map +1 -0
- package/dist/store/event-store.js +1751 -0
- package/dist/store/event-store.js.map +1 -0
- package/dist/store/instance.d.ts +290 -0
- package/dist/store/instance.d.ts.map +1 -0
- package/dist/store/instance.js +363 -0
- package/dist/store/instance.js.map +1 -0
- package/dist/store/migrations.d.ts +41 -0
- package/dist/store/migrations.d.ts.map +1 -0
- package/dist/store/migrations.js +79 -0
- package/dist/store/migrations.js.map +1 -0
- package/dist/store/test-utils.d.ts +63 -0
- package/dist/store/test-utils.d.ts.map +1 -0
- package/dist/store/test-utils.js +63 -0
- package/dist/store/test-utils.js.map +1 -0
- package/dist/store/types/config.d.ts +16 -0
- package/dist/store/types/config.d.ts.map +1 -0
- package/dist/store/types/config.js +8 -0
- package/dist/store/types/config.js.map +1 -0
- package/dist/store/types/conversations.d.ts +91 -0
- package/dist/store/types/conversations.d.ts.map +1 -0
- package/dist/store/types/conversations.js +8 -0
- package/dist/store/types/conversations.js.map +1 -0
- package/dist/store/types/sessions.d.ts +44 -0
- package/dist/store/types/sessions.d.ts.map +1 -0
- package/dist/store/types/sessions.js +9 -0
- package/dist/store/types/sessions.js.map +1 -0
- package/dist/store/types.d.ts +115 -0
- package/dist/store/types.d.ts.map +1 -0
- package/dist/store/types.js +6 -0
- package/dist/store/types.js.map +1 -0
- package/dist/task/backend/index.d.ts +93 -0
- package/dist/task/backend/index.d.ts.map +1 -0
- package/dist/task/backend/index.js +178 -0
- package/dist/task/backend/index.js.map +1 -0
- package/dist/task/backend/memory.d.ts +70 -0
- package/dist/task/backend/memory.d.ts.map +1 -0
- package/dist/task/backend/memory.js +621 -0
- package/dist/task/backend/memory.js.map +1 -0
- package/dist/task/backend/opentasks/backend.d.ts +140 -0
- package/dist/task/backend/opentasks/backend.d.ts.map +1 -0
- package/dist/task/backend/opentasks/backend.js +1023 -0
- package/dist/task/backend/opentasks/backend.js.map +1 -0
- package/dist/task/backend/opentasks/client.d.ts +337 -0
- package/dist/task/backend/opentasks/client.d.ts.map +1 -0
- package/dist/task/backend/opentasks/client.js +225 -0
- package/dist/task/backend/opentasks/client.js.map +1 -0
- package/dist/task/backend/opentasks/daemon-manager.d.ts +89 -0
- package/dist/task/backend/opentasks/daemon-manager.d.ts.map +1 -0
- package/dist/task/backend/opentasks/daemon-manager.js +195 -0
- package/dist/task/backend/opentasks/daemon-manager.js.map +1 -0
- package/dist/task/backend/opentasks/index.d.ts +21 -0
- package/dist/task/backend/opentasks/index.d.ts.map +1 -0
- package/dist/task/backend/opentasks/index.js +21 -0
- package/dist/task/backend/opentasks/index.js.map +1 -0
- package/dist/task/backend/opentasks/mapping.d.ts +48 -0
- package/dist/task/backend/opentasks/mapping.d.ts.map +1 -0
- package/dist/task/backend/opentasks/mapping.js +77 -0
- package/dist/task/backend/opentasks/mapping.js.map +1 -0
- package/dist/task/backend/sudocode/__tests__/integration/test-utils.d.ts +54 -0
- package/dist/task/backend/sudocode/__tests__/integration/test-utils.d.ts.map +1 -0
- package/dist/task/backend/sudocode/__tests__/integration/test-utils.js +88 -0
- package/dist/task/backend/sudocode/__tests__/integration/test-utils.js.map +1 -0
- package/dist/task/backend/sudocode/backend.d.ts +155 -0
- package/dist/task/backend/sudocode/backend.d.ts.map +1 -0
- package/dist/task/backend/sudocode/backend.js +942 -0
- package/dist/task/backend/sudocode/backend.js.map +1 -0
- package/dist/task/backend/sudocode/client.d.ts +303 -0
- package/dist/task/backend/sudocode/client.d.ts.map +1 -0
- package/dist/task/backend/sudocode/client.js +101 -0
- package/dist/task/backend/sudocode/client.js.map +1 -0
- package/dist/task/backend/sudocode/index.d.ts +19 -0
- package/dist/task/backend/sudocode/index.d.ts.map +1 -0
- package/dist/task/backend/sudocode/index.js +17 -0
- package/dist/task/backend/sudocode/index.js.map +1 -0
- package/dist/task/backend/sudocode/mapping.d.ts +51 -0
- package/dist/task/backend/sudocode/mapping.d.ts.map +1 -0
- package/dist/task/backend/sudocode/mapping.js +86 -0
- package/dist/task/backend/sudocode/mapping.js.map +1 -0
- package/dist/task/backend/sudocode/server-client.d.ts +56 -0
- package/dist/task/backend/sudocode/server-client.d.ts.map +1 -0
- package/dist/task/backend/sudocode/server-client.js +367 -0
- package/dist/task/backend/sudocode/server-client.js.map +1 -0
- package/dist/task/backend/sudocode/standalone-client.d.ts +91 -0
- package/dist/task/backend/sudocode/standalone-client.d.ts.map +1 -0
- package/dist/task/backend/sudocode/standalone-client.js +476 -0
- package/dist/task/backend/sudocode/standalone-client.js.map +1 -0
- package/dist/task/backend/sudocode/sync-policy.d.ts +166 -0
- package/dist/task/backend/sudocode/sync-policy.d.ts.map +1 -0
- package/dist/task/backend/sudocode/sync-policy.js +221 -0
- package/dist/task/backend/sudocode/sync-policy.js.map +1 -0
- package/dist/task/backend/sudocode/tools.d.ts +87 -0
- package/dist/task/backend/sudocode/tools.d.ts.map +1 -0
- package/dist/task/backend/sudocode/tools.js +743 -0
- package/dist/task/backend/sudocode/tools.js.map +1 -0
- package/dist/task/backend/tool-provider.d.ts +56 -0
- package/dist/task/backend/tool-provider.d.ts.map +1 -0
- package/dist/task/backend/tool-provider.js +424 -0
- package/dist/task/backend/tool-provider.js.map +1 -0
- package/dist/task/backend/types.d.ts +297 -0
- package/dist/task/backend/types.d.ts.map +1 -0
- package/dist/task/backend/types.js +27 -0
- package/dist/task/backend/types.js.map +1 -0
- package/dist/task/backend/unified-tool-provider.d.ts +57 -0
- package/dist/task/backend/unified-tool-provider.d.ts.map +1 -0
- package/dist/task/backend/unified-tool-provider.js +623 -0
- package/dist/task/backend/unified-tool-provider.js.map +1 -0
- package/dist/task/index.d.ts +7 -0
- package/dist/task/index.d.ts.map +1 -0
- package/dist/task/index.js +7 -0
- package/dist/task/index.js.map +1 -0
- package/dist/task/retry-policy.d.ts +89 -0
- package/dist/task/retry-policy.d.ts.map +1 -0
- package/dist/task/retry-policy.js +160 -0
- package/dist/task/retry-policy.js.map +1 -0
- package/dist/task/task-manager.d.ts +70 -0
- package/dist/task/task-manager.d.ts.map +1 -0
- package/dist/task/task-manager.js +319 -0
- package/dist/task/task-manager.js.map +1 -0
- package/dist/task/types.d.ts +72 -0
- package/dist/task/types.d.ts.map +1 -0
- package/dist/task/types.js +33 -0
- package/dist/task/types.js.map +1 -0
- package/dist/teams/team-loader.d.ts +2 -1
- package/dist/teams/team-loader.d.ts.map +1 -1
- package/dist/teams/team-loader.js +2 -1
- package/dist/teams/team-loader.js.map +1 -1
- package/dist/teams/team-manager.d.ts +101 -0
- package/dist/teams/team-manager.d.ts.map +1 -0
- package/dist/teams/team-manager.js +260 -0
- package/dist/teams/team-manager.js.map +1 -0
- package/dist/teams/team-runtime-v2.d.ts +0 -3
- package/dist/teams/team-runtime-v2.d.ts.map +1 -1
- package/dist/teams/team-runtime-v2.js +8 -87
- package/dist/teams/team-runtime-v2.js.map +1 -1
- package/dist/teams/team-runtime.d.ts +245 -0
- package/dist/teams/team-runtime.d.ts.map +1 -0
- package/dist/teams/team-runtime.js +1023 -0
- package/dist/teams/team-runtime.js.map +1 -0
- package/dist/trigger/router/index.d.ts +11 -0
- package/dist/trigger/router/index.d.ts.map +1 -0
- package/dist/trigger/router/index.js +10 -0
- package/dist/trigger/router/index.js.map +1 -0
- package/dist/trigger/router/strategies/ai-router-strategy.d.ts +34 -0
- package/dist/trigger/router/strategies/ai-router-strategy.d.ts.map +1 -0
- package/dist/trigger/router/strategies/ai-router-strategy.js +359 -0
- package/dist/trigger/router/strategies/ai-router-strategy.js.map +1 -0
- package/dist/trigger/router/strategies/direct-strategy.d.ts +32 -0
- package/dist/trigger/router/strategies/direct-strategy.d.ts.map +1 -0
- package/dist/trigger/router/strategies/direct-strategy.js +119 -0
- package/dist/trigger/router/strategies/direct-strategy.js.map +1 -0
- package/dist/trigger/router/strategies/index.d.ts +11 -0
- package/dist/trigger/router/strategies/index.d.ts.map +1 -0
- package/dist/trigger/router/strategies/index.js +11 -0
- package/dist/trigger/router/strategies/index.js.map +1 -0
- package/dist/trigger/router/strategies/role-strategy.d.ts +39 -0
- package/dist/trigger/router/strategies/role-strategy.d.ts.map +1 -0
- package/dist/trigger/router/strategies/role-strategy.js +207 -0
- package/dist/trigger/router/strategies/role-strategy.js.map +1 -0
- package/dist/trigger/router/trigger-router.d.ts +54 -0
- package/dist/trigger/router/trigger-router.d.ts.map +1 -0
- package/dist/trigger/router/trigger-router.js +362 -0
- package/dist/trigger/router/trigger-router.js.map +1 -0
- package/dist/trigger/router/types.d.ts +225 -0
- package/dist/trigger/router/types.d.ts.map +1 -0
- package/dist/trigger/router/types.js +10 -0
- package/dist/trigger/router/types.js.map +1 -0
- package/dist/trigger/sources/cron/cron-service.d.ts.map +1 -1
- package/dist/trigger/sources/cron/cron-service.js +6 -3
- package/dist/trigger/sources/cron/cron-service.js.map +1 -1
- package/dist/trigger/trigger-system.d.ts +77 -0
- package/dist/trigger/trigger-system.d.ts.map +1 -0
- package/dist/trigger/trigger-system.js +84 -0
- package/dist/trigger/trigger-system.js.map +1 -0
- package/dist/util/git-safety.d.ts +33 -0
- package/dist/util/git-safety.d.ts.map +1 -0
- package/dist/util/git-safety.js +94 -0
- package/dist/util/git-safety.js.map +1 -0
- package/dist/workspace/dataplane-adapter.d.ts +260 -0
- package/dist/workspace/dataplane-adapter.d.ts.map +1 -0
- package/dist/workspace/dataplane-adapter.js +416 -0
- package/dist/workspace/dataplane-adapter.js.map +1 -0
- package/dist/workspace/index.d.ts +0 -1
- package/dist/workspace/index.d.ts.map +1 -1
- package/dist/workspace/index.js +0 -2
- package/dist/workspace/index.js.map +1 -1
- package/dist/workspace/landing/direct-push.d.ts.map +1 -1
- package/dist/workspace/landing/direct-push.js +22 -7
- package/dist/workspace/landing/direct-push.js.map +1 -1
- package/dist/workspace/landing/queue-to-branch.d.ts.map +1 -1
- package/dist/workspace/landing/queue-to-branch.js +1 -3
- package/dist/workspace/landing/queue-to-branch.js.map +1 -1
- package/dist/workspace/types.d.ts +0 -13
- package/dist/workspace/types.d.ts.map +1 -1
- package/dist/workspace/workspace-manager.d.ts +0 -11
- package/dist/workspace/workspace-manager.d.ts.map +1 -1
- package/dist/workspace/workspace-manager.js +0 -30
- package/dist/workspace/workspace-manager.js.map +1 -1
- package/package.json +28 -2
- package/templates/teams/self-driving/prompts/grinder.md +1 -0
- package/templates/teams/self-driving/prompts/judge.md +1 -0
- package/templates/teams/self-driving/prompts/planner.md +1 -0
- package/templates/teams/self-driving/roles/grinder.yaml +15 -0
- package/templates/teams/self-driving/roles/judge.yaml +10 -0
- package/templates/teams/self-driving/roles/planner.yaml +16 -0
- package/.claude/commands/openspec/apply.md +0 -23
- package/.claude/commands/openspec/archive.md +0 -27
- package/.claude/commands/openspec/proposal.md +0 -28
- package/.claude/settings.json +0 -133
- package/.gitattributes +0 -3
- package/.opentasks/config.json +0 -9
- package/.opentasks/graph.jsonl +0 -0
- package/.sessionlog/settings.json +0 -4
- package/.sudocode/issues.jsonl +0 -183
- package/.sudocode/specs.jsonl +0 -56
- package/AGENTS.md +0 -18
- package/CLAUDE.md +0 -923
- package/docs/architecture.md +0 -508
- package/docs/configuration.md +0 -323
- package/docs/conflict-recovery.md +0 -472
- package/docs/design/task-dispatcher.md +0 -880
- package/docs/design-subsystem-extraction.md +0 -627
- package/docs/git-cascade-integration-gaps.md +0 -678
- package/docs/implementation-details.md +0 -1127
- package/docs/implementation-summary.md +0 -448
- package/docs/lifecycle-events-design.md +0 -111
- package/docs/mail-integration.md +0 -608
- package/docs/openhive-capability-summary.md +0 -415
- package/docs/openhive-integration.md +0 -415
- package/docs/plan-self-driving-support.md +0 -433
- package/docs/roadmap-v2-gaps.md +0 -216
- package/docs/spec-self-driving-support.md +0 -462
- package/docs/team-templates.md +0 -860
- package/docs/teams.md +0 -306
- package/docs/trigger-system-design.md +0 -333
- package/docs/troubleshooting.md +0 -489
- package/docs/workspace-interfaces.md +0 -731
- package/docs/workspace-redesign-plan.md +0 -302
- package/examples/distributed-peer-communication.ts +0 -202
- package/examples/local-peer-communication.ts +0 -165
- package/index.js +0 -2
- package/mvp_docs/agent-execution-system.md +0 -347
- package/mvp_docs/agent-interface.md +0 -580
- package/mvp_docs/data-structures.md +0 -701
- package/mvp_docs/dynamic-meta-orchestration.md +0 -116
- package/mvp_docs/multi-agent-interaction-design.md +0 -779
- package/mvp_docs/mvp-implementation-plan.md +0 -1148
- package/renovate.json5 +0 -6
- package/scripts/test-acp-integration.ts +0 -422
- package/src/__tests__/boot-v2.test.ts +0 -631
- package/src/__tests__/e2e/acp-over-map-live.e2e.test.ts +0 -496
- package/src/__tests__/e2e/acp-over-map.e2e.test.ts +0 -457
- package/src/__tests__/e2e/agent-lifecycle.e2e.test.ts +0 -770
- package/src/__tests__/e2e/auto-sync.e2e.test.ts +0 -257
- package/src/__tests__/e2e/bootstrap.e2e.test.ts +0 -319
- package/src/__tests__/e2e/cascade-rebase.e2e.test.ts +0 -254
- package/src/__tests__/e2e/cc-swarm-bridge.e2e.test.ts +0 -253
- package/src/__tests__/e2e/cli-run.e2e.test.ts +0 -167
- package/src/__tests__/e2e/cognitive-workspace.e2e.test.ts +0 -282
- package/src/__tests__/e2e/dispatch-coordination.e2e.test.ts +0 -495
- package/src/__tests__/e2e/dispatch-live.e2e.test.ts +0 -564
- package/src/__tests__/e2e/dispatch-opentasks.e2e.test.ts +0 -496
- package/src/__tests__/e2e/dispatch-phase2-live.e2e.test.ts +0 -456
- package/src/__tests__/e2e/dispatch-phase2.e2e.test.ts +0 -386
- package/src/__tests__/e2e/dispatch.e2e.test.ts +0 -376
- package/src/__tests__/e2e/done-scenarios.e2e.test.ts +0 -322
- package/src/__tests__/e2e/live-agent.e2e.test.ts +0 -1330
- package/src/__tests__/e2e/map-server.e2e.test.ts +0 -128
- package/src/__tests__/e2e/map-sidecar.e2e.test.ts +0 -139
- package/src/__tests__/e2e/opentasks-integration.e2e.test.ts +0 -280
- package/src/__tests__/e2e/pull-mode.e2e.test.ts +0 -632
- package/src/__tests__/e2e/resume-continue.e2e.test.ts +0 -312
- package/src/__tests__/e2e/self-driving-v3.e2e.test.ts +0 -197
- package/src/__tests__/e2e/spawn-resolver.e2e.test.ts +0 -200
- package/src/__tests__/e2e/swarmkit-integration.e2e.test.ts +0 -562
- package/src/__tests__/e2e/swarmkit-live.e2e.test.ts +0 -1049
- package/src/__tests__/e2e/trajectory-tracking.e2e.test.ts +0 -258
- package/src/__tests__/e2e/trigger-wake.e2e.test.ts +0 -257
- package/src/__tests__/e2e/workspace-lifecycle.e2e.test.ts +0 -383
- package/src/__tests__/e2e/workspace-v3.e2e.test.ts +0 -413
- package/src/acp/__tests__/claude-code-replay.test.ts +0 -225
- package/src/acp/__tests__/macro-agent.test.ts +0 -387
- package/src/acp/__tests__/session-mapper.test.ts +0 -152
- package/src/acp/__tests__/websocket-server.test.ts +0 -194
- package/src/acp/claude-code-replay.ts +0 -208
- package/src/acp/index.ts +0 -32
- package/src/acp/macro-agent.ts +0 -995
- package/src/acp/map-bridge.ts +0 -193
- package/src/acp/session-mapper.ts +0 -116
- package/src/acp/types.ts +0 -99
- package/src/acp/websocket-server.ts +0 -213
- package/src/adapters/__tests__/federation.test.ts +0 -256
- package/src/adapters/__tests__/inbox-adapter.test.ts +0 -316
- package/src/adapters/__tests__/tasks-adapter.test.ts +0 -270
- package/src/adapters/federation.ts +0 -185
- package/src/adapters/inbox-adapter.ts +0 -292
- package/src/adapters/inbox-client-adapter.ts +0 -173
- package/src/adapters/index.ts +0 -44
- package/src/adapters/opentasks-daemon.ts +0 -252
- package/src/adapters/tasks-adapter.ts +0 -330
- package/src/adapters/types.ts +0 -286
- package/src/agent/__tests__/agent-manager-topology.test.ts +0 -73
- package/src/agent/__tests__/agent-manager-v2.completion-signal.test.ts +0 -284
- package/src/agent/__tests__/agent-manager-v2.permission-interception.test.ts +0 -296
- package/src/agent/__tests__/agent-manager-v2.permissions.test.ts +0 -233
- package/src/agent/__tests__/agent-manager-v2.test.ts +0 -614
- package/src/agent/__tests__/agent-store.test.ts +0 -465
- package/src/agent/__tests__/task-ref-resolution.test.ts +0 -231
- package/src/agent/agent-manager-v2.ts +0 -2187
- package/src/agent/agent-manager.ts +0 -403
- package/src/agent/agent-store.ts +0 -409
- package/src/agent/index.ts +0 -7
- package/src/agent/prompts/coordinator-signals.ts +0 -115
- package/src/agent/prompts/index.ts +0 -7
- package/src/agent/system-prompt.ts +0 -298
- package/src/agent/types.ts +0 -480
- package/src/agent-detection/__tests__/command-builder.test.ts +0 -336
- package/src/agent-detection/__tests__/detector.test.ts +0 -768
- package/src/agent-detection/__tests__/registry.test.ts +0 -254
- package/src/agent-detection/command-builder.ts +0 -90
- package/src/agent-detection/detector.ts +0 -307
- package/src/agent-detection/index.ts +0 -36
- package/src/agent-detection/registry.ts +0 -200
- package/src/agent-detection/types.ts +0 -184
- package/src/api/__tests__/server.test.ts +0 -292
- package/src/api/index.ts +0 -8
- package/src/api/server.ts +0 -380
- package/src/api/types.ts +0 -39
- package/src/auth/__tests__/token.test.ts +0 -100
- package/src/auth/index.ts +0 -1
- package/src/auth/token.ts +0 -82
- package/src/boot-v2.ts +0 -1343
- package/src/cli/__tests__/stable-instance-id.test.ts +0 -57
- package/src/cli/acp.ts +0 -101
- package/src/cli/inbox-mcp-proxy.ts +0 -56
- package/src/cli/index.ts +0 -566
- package/src/cli/mcp.ts +0 -305
- package/src/cli/parse-args.ts +0 -54
- package/src/cli/stable-instance-id.ts +0 -14
- package/src/cognitive/__tests__/macro-agent-backend.test.ts +0 -673
- package/src/cognitive/__tests__/session-converter.test.ts +0 -423
- package/src/cognitive/__tests__/workspace-handler.test.ts +0 -221
- package/src/cognitive/analyst-role.ts +0 -59
- package/src/cognitive/index.ts +0 -49
- package/src/cognitive/macro-agent-backend.ts +0 -402
- package/src/cognitive/session-converter.ts +0 -151
- package/src/cognitive/types.ts +0 -187
- package/src/cognitive/workspace-handler.ts +0 -163
- package/src/config/index.ts +0 -9
- package/src/config/project-config.ts +0 -294
- package/src/control/__tests__/control-resilience.test.ts +0 -251
- package/src/control/__tests__/control-socket.test.ts +0 -240
- package/src/control/control-client.ts +0 -337
- package/src/control/control-server.ts +0 -298
- package/src/control/index.ts +0 -17
- package/src/control/types.ts +0 -95
- package/src/dispatch/CLAUDE.md +0 -129
- package/src/dispatch/__tests__/loadout-translation.test.ts +0 -141
- package/src/dispatch/__tests__/mail-inbound-consumer.integration.test.ts +0 -519
- package/src/dispatch/__tests__/mail-inbound-consumer.test.ts +0 -800
- package/src/dispatch/__tests__/mail-inbound-reuse-consumer.test.ts +0 -575
- package/src/dispatch/__tests__/permission-evaluator.test.ts +0 -196
- package/src/dispatch/__tests__/permission-overlay.test.ts +0 -56
- package/src/dispatch/__tests__/permissions-handler.test.ts +0 -168
- package/src/dispatch/__tests__/spawn-agent-handler.test.ts +0 -282
- package/src/dispatch/loadout-translation.ts +0 -138
- package/src/dispatch/mail-inbound-consumer.ts +0 -560
- package/src/dispatch/mail-inbound-reuse-consumer.ts +0 -479
- package/src/dispatch/permission-evaluator.ts +0 -191
- package/src/dispatch/permission-overlay.ts +0 -89
- package/src/dispatch/permissions-handler.ts +0 -112
- package/src/dispatch/spawn-agent-handler.ts +0 -160
- package/src/index.ts +0 -117
- package/src/integrations/__tests__/context-builder.test.ts +0 -218
- package/src/integrations/__tests__/sessionlog.test.ts +0 -498
- package/src/integrations/__tests__/skilltree.test.ts +0 -136
- package/src/integrations/context-builder.ts +0 -280
- package/src/integrations/sessionlog.ts +0 -194
- package/src/integrations/skilltree.ts +0 -184
- package/src/lifecycle/__tests__/cascade-consolidation.test.ts +0 -240
- package/src/lifecycle/__tests__/handlers-v2.test.ts +0 -565
- package/src/lifecycle/cascade.ts +0 -335
- package/src/lifecycle/cleanup.ts +0 -373
- package/src/lifecycle/handlers-v2.ts +0 -508
- package/src/lifecycle/index.ts +0 -76
- package/src/lifecycle/types.ts +0 -260
- package/src/map/__tests__/cascade-bridge.test.ts +0 -229
- package/src/map/__tests__/cascade-diff-server.test.ts +0 -434
- package/src/map/__tests__/emit-event.test.ts +0 -71
- package/src/map/__tests__/lifecycle-bridge.test.ts +0 -430
- package/src/map/__tests__/mail-bridge.test.ts +0 -321
- package/src/map/__tests__/permission-forwarding.test.ts +0 -143
- package/src/map/__tests__/sidecar-diff-install-smoke.test.ts +0 -90
- package/src/map/__tests__/sidecar-integration.test.ts +0 -190
- package/src/map/__tests__/task-bridge.test.ts +0 -153
- package/src/map/__tests__/trajectory-reporter.test.ts +0 -173
- package/src/map/acp-bridge.ts +0 -293
- package/src/map/cascade-action-handler.ts +0 -205
- package/src/map/cascade-bridge.ts +0 -339
- package/src/map/cascade-diff-server.ts +0 -404
- package/src/map/cc-swarm-hooks.ts +0 -242
- package/src/map/coordination-handler.ts +0 -232
- package/src/map/index.ts +0 -18
- package/src/map/lifecycle-bridge.ts +0 -236
- package/src/map/mail-bridge.ts +0 -263
- package/src/map/repo-workspace.ts +0 -82
- package/src/map/server.ts +0 -758
- package/src/map/sidecar.ts +0 -826
- package/src/map/task-bridge.ts +0 -89
- package/src/map/trajectory-reporter.ts +0 -124
- package/src/map/types.ts +0 -304
- package/src/mcp/__tests__/mcp-server-v2.test.ts +0 -236
- package/src/mcp/index.ts +0 -6
- package/src/mcp/mcp-server-v2.ts +0 -485
- package/src/mcp/tools/done-v2.ts +0 -213
- package/src/mcp/types.ts +0 -432
- package/src/metrics/__tests__/metrics.test.ts +0 -205
- package/src/metrics/index.ts +0 -13
- package/src/metrics/metrics.ts +0 -151
- package/src/metrics/types.ts +0 -63
- package/src/roles/__tests__/config-loader.test.ts +0 -540
- package/src/roles/builtin/coordinator.ts +0 -75
- package/src/roles/builtin/generic.ts +0 -39
- package/src/roles/builtin/index.ts +0 -51
- package/src/roles/builtin/integrator.ts +0 -62
- package/src/roles/builtin/monitor.ts +0 -65
- package/src/roles/builtin/worker.ts +0 -134
- package/src/roles/capabilities.ts +0 -257
- package/src/roles/config-loader.ts +0 -405
- package/src/roles/index.ts +0 -141
- package/src/roles/registry.ts +0 -713
- package/src/roles/types.ts +0 -344
- package/src/store/index.ts +0 -8
- package/src/store/types/agents.ts +0 -69
- package/src/store/types/events.ts +0 -91
- package/src/store/types/index.ts +0 -9
- package/src/store/types/messages.ts +0 -32
- package/src/store/types/primitives.ts +0 -9
- package/src/store/types/tasks.ts +0 -124
- package/src/teams/__tests__/team-manager-v2.test.ts +0 -425
- package/src/teams/__tests__/team-runtime-v2.test.ts +0 -402
- package/src/teams/index.ts +0 -29
- package/src/teams/seed-defaults.ts +0 -83
- package/src/teams/team-loader.ts +0 -476
- package/src/teams/team-manager-v2.ts +0 -343
- package/src/teams/team-runtime-v2.ts +0 -943
- package/src/teams/types.ts +0 -276
- package/src/trigger/__tests__/cron-service.test.ts +0 -548
- package/src/trigger/__tests__/scheduler.test.ts +0 -371
- package/src/trigger/__tests__/system-event-queue.test.ts +0 -147
- package/src/trigger/__tests__/trigger-system-v2.test.ts +0 -257
- package/src/trigger/__tests__/wake-manager.test.ts +0 -356
- package/src/trigger/__tests__/webhook-handler.test.ts +0 -567
- package/src/trigger/index.ts +0 -110
- package/src/trigger/queue/index.ts +0 -21
- package/src/trigger/queue/system-event-queue.ts +0 -232
- package/src/trigger/queue/types.ts +0 -149
- package/src/trigger/sources/cron/cron-service.ts +0 -499
- package/src/trigger/sources/cron/index.ts +0 -41
- package/src/trigger/sources/cron/scheduler.ts +0 -344
- package/src/trigger/sources/cron/types.ts +0 -333
- package/src/trigger/sources/index.ts +0 -10
- package/src/trigger/sources/webhook/index.ts +0 -25
- package/src/trigger/sources/webhook/types.ts +0 -205
- package/src/trigger/sources/webhook/webhook-handler.ts +0 -410
- package/src/trigger/strategies/ai-router.ts +0 -170
- package/src/trigger/trigger-system-v2.ts +0 -536
- package/src/trigger/types.ts +0 -228
- package/src/trigger/wake/index.ts +0 -22
- package/src/trigger/wake/types.ts +0 -162
- package/src/trigger/wake/wake-manager.ts +0 -390
- package/src/workspace/__tests__/git-cascade-adapter.test.ts +0 -563
- package/src/workspace/__tests__/land-dispatch.test.ts +0 -214
- package/src/workspace/__tests__/self-driving-yaml.test.ts +0 -122
- package/src/workspace/__tests__/shared-worktree-refcount.test.ts +0 -154
- package/src/workspace/__tests__/standalone-mode.test.ts +0 -118
- package/src/workspace/__tests__/workspace-manager-v3.test.ts +0 -245
- package/src/workspace/__tests__/yaml-schema.test.ts +0 -210
- package/src/workspace/config.ts +0 -165
- package/src/workspace/git-cascade-adapter.ts +0 -1213
- package/src/workspace/index.ts +0 -110
- package/src/workspace/landing/__tests__/strategies.test.ts +0 -184
- package/src/workspace/landing/direct-push.ts +0 -91
- package/src/workspace/landing/index.ts +0 -40
- package/src/workspace/landing/merge-to-parent.ts +0 -229
- package/src/workspace/landing/optimistic-push.ts +0 -36
- package/src/workspace/landing/queue-to-branch.ts +0 -108
- package/src/workspace/merge-queue/__tests__/conflict-resolution-git.e2e.test.ts +0 -641
- package/src/workspace/merge-queue/__tests__/conflict-resolution.test.ts +0 -707
- package/src/workspace/merge-queue/__tests__/merge-queue-concurrent.test.ts +0 -628
- package/src/workspace/merge-queue/__tests__/merge-queue-edge-cases.test.ts +0 -1217
- package/src/workspace/merge-queue/__tests__/merge-queue.test.ts +0 -506
- package/src/workspace/merge-queue/__tests__/real-git-operations.e2e.test.ts +0 -556
- package/src/workspace/merge-queue/__tests__/resolver-flow.test.ts +0 -472
- package/src/workspace/merge-queue/index.ts +0 -38
- package/src/workspace/merge-queue/merge-queue.ts +0 -585
- package/src/workspace/merge-queue/schema.ts +0 -98
- package/src/workspace/merge-queue/types.ts +0 -316
- package/src/workspace/pool/__tests__/worktree-pool.integration.test.ts +0 -1281
- package/src/workspace/pool/__tests__/worktree-pool.test.ts +0 -590
- package/src/workspace/pool/index.ts +0 -26
- package/src/workspace/pool/types.ts +0 -276
- package/src/workspace/pool/worktree-pool.ts +0 -659
- package/src/workspace/recovery/__tests__/auto-resolve-integration.test.ts +0 -127
- package/src/workspace/recovery/__tests__/spawn-resolver.test.ts +0 -139
- package/src/workspace/recovery/__tests__/strategies.test.ts +0 -145
- package/src/workspace/recovery/abandon.ts +0 -51
- package/src/workspace/recovery/auto-resolve.ts +0 -119
- package/src/workspace/recovery/defer.ts +0 -23
- package/src/workspace/recovery/escalate.ts +0 -30
- package/src/workspace/recovery/index.ts +0 -58
- package/src/workspace/recovery/spawn-resolver.ts +0 -152
- package/src/workspace/recovery/types.ts +0 -54
- package/src/workspace/strategies/index.ts +0 -18
- package/src/workspace/strategies/optimistic.ts +0 -139
- package/src/workspace/strategies/queue.ts +0 -81
- package/src/workspace/strategies/registry.ts +0 -89
- package/src/workspace/strategies/trunk.ts +0 -123
- package/src/workspace/strategies/types.ts +0 -145
- package/src/workspace/topology/__tests__/yaml-driven.test.ts +0 -345
- package/src/workspace/topology/index.ts +0 -18
- package/src/workspace/topology/no-workspace.ts +0 -39
- package/src/workspace/topology/types.ts +0 -116
- package/src/workspace/topology/yaml-driven.ts +0 -316
- package/src/workspace/types-v3.ts +0 -162
- package/src/workspace/types.ts +0 -541
- package/src/workspace/workspace-manager.ts +0 -1577
- package/src/workspace/yaml-schema.ts +0 -216
- package/test_fixtures/README.md +0 -425
- package/test_fixtures/fixtures/behaviors/coordinators.ts +0 -196
- package/test_fixtures/fixtures/behaviors/index.ts +0 -62
- package/test_fixtures/fixtures/behaviors/integrators.ts +0 -143
- package/test_fixtures/fixtures/behaviors/monitors.ts +0 -199
- package/test_fixtures/fixtures/behaviors/workers.ts +0 -348
- package/test_fixtures/fixtures/index.ts +0 -7
- package/test_fixtures/fixtures/projects/index.ts +0 -23
- package/test_fixtures/fixtures/projects/project-with-specs.ts +0 -44
- package/test_fixtures/fixtures/projects/typescript-project.ts +0 -200
- package/test_fixtures/fixtures/repos/index.ts +0 -6
- package/test_fixtures/fixtures/repos/temp-repo-factory.ts +0 -299
- package/test_fixtures/fixtures/repos/types.ts +0 -174
- package/test_fixtures/harness/assertions/harness-assertions.ts +0 -752
- package/test_fixtures/harness/assertions/index.ts +0 -8
- package/test_fixtures/harness/index.ts +0 -15
- package/test_fixtures/harness/simulator/agent-simulator.ts +0 -768
- package/test_fixtures/harness/simulator/behavior-executor.ts +0 -580
- package/test_fixtures/harness/simulator/index.ts +0 -14
- package/test_fixtures/harness/simulator/types.ts +0 -459
- package/test_fixtures/harness/test-harness.ts +0 -770
- package/test_fixtures/harness/timing/event-stepper.ts +0 -344
- package/test_fixtures/harness/timing/index.ts +0 -8
- package/tsconfig.json +0 -21
- package/vitest.config.ts +0 -30
- package/vitest.e2e.config.ts +0 -28
- package/vitest.setup.ts +0 -12
|
@@ -1,1577 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WorkspaceManager Implementation
|
|
3
|
-
*
|
|
4
|
-
* Bridges macro-agent roles to git-cascade streams and worktrees.
|
|
5
|
-
* Provides a higher-level API for workspace management.
|
|
6
|
-
*
|
|
7
|
-
* @module workspace/workspace-manager
|
|
8
|
-
* @implements [[s-7ktd]] WorkspaceManager API section
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import type { Stream, WorkerTask, StartTaskResult, AgentWorktree, CleanupWorkerBranchesOptions, CleanupResult } from 'git-cascade';
|
|
12
|
-
import { GitCascadeAdapter } from './git-cascade-adapter.js';
|
|
13
|
-
import type { GitCascadeConfig, WorktreePoolConfig } from './config.js';
|
|
14
|
-
import { DEFAULT_POOL_CONFIG } from './config.js';
|
|
15
|
-
import { WorktreePool } from './pool/worktree-pool.js';
|
|
16
|
-
import type { AllocationStrategy, AcquireOptions } from './pool/types.js';
|
|
17
|
-
import type {
|
|
18
|
-
AgentId,
|
|
19
|
-
StreamId,
|
|
20
|
-
TaskId,
|
|
21
|
-
Workspace,
|
|
22
|
-
WorkerWorkspace,
|
|
23
|
-
IntegratorWorkspace,
|
|
24
|
-
CoordinatorWorkspace,
|
|
25
|
-
WorkspaceManager,
|
|
26
|
-
StreamConfig,
|
|
27
|
-
CreateTaskOptions,
|
|
28
|
-
WorkspaceEvent,
|
|
29
|
-
WorkspaceEventCallback,
|
|
30
|
-
} from './types.js';
|
|
31
|
-
import type { MergeQueueInterface } from './merge-queue/types.js';
|
|
32
|
-
import { MergeQueue } from './merge-queue/merge-queue.js';
|
|
33
|
-
import { execSync } from 'child_process';
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Configuration options for DefaultWorkspaceManager.
|
|
37
|
-
*/
|
|
38
|
-
export interface WorkspaceManagerConfig extends GitCascadeConfig {
|
|
39
|
-
/**
|
|
40
|
-
* Base directory for worktrees.
|
|
41
|
-
* Defaults to `<repoPath>/.worktrees`.
|
|
42
|
-
*/
|
|
43
|
-
worktreeBaseDir?: string;
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Configuration for the shared worktree pool.
|
|
47
|
-
* When enabled, worktrees are managed by the pool and reused.
|
|
48
|
-
*/
|
|
49
|
-
pool?: Partial<WorktreePoolConfig>;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* DefaultWorkspaceManager implements the WorkspaceManager interface.
|
|
54
|
-
*
|
|
55
|
-
* Responsibilities:
|
|
56
|
-
* - Wraps GitCascadeAdapter for stream/worktree operations
|
|
57
|
-
* - Maintains agentId → workspace mappings
|
|
58
|
-
* - Emits events on workspace lifecycle changes
|
|
59
|
-
*
|
|
60
|
-
* @see [[s-7ktd]] WorkspaceManager section
|
|
61
|
-
*/
|
|
62
|
-
export class DefaultWorkspaceManager implements WorkspaceManager {
|
|
63
|
-
private readonly adapter: GitCascadeAdapter;
|
|
64
|
-
private readonly config: Required<Pick<WorkspaceManagerConfig, 'worktreeBaseDir'>>;
|
|
65
|
-
private readonly poolConfig: WorktreePoolConfig;
|
|
66
|
-
private readonly workspaces: Map<AgentId, Workspace> = new Map();
|
|
67
|
-
private readonly agentToStream: Map<AgentId, StreamId> = new Map();
|
|
68
|
-
private readonly eventListeners: Set<WorkspaceEventCallback> = new Set();
|
|
69
|
-
private mergeQueue: MergeQueue | null = null;
|
|
70
|
-
private pool: WorktreePool | null = null;
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Create a new DefaultWorkspaceManager.
|
|
74
|
-
*
|
|
75
|
-
* @param adapter - GitCascadeAdapter instance
|
|
76
|
-
* @param config - Configuration options
|
|
77
|
-
*/
|
|
78
|
-
constructor(adapter: GitCascadeAdapter, config?: Partial<WorkspaceManagerConfig>) {
|
|
79
|
-
this.adapter = adapter;
|
|
80
|
-
this.config = {
|
|
81
|
-
worktreeBaseDir: config?.worktreeBaseDir ?? `${adapter.repoPath}/.worktrees`,
|
|
82
|
-
};
|
|
83
|
-
this.poolConfig = {
|
|
84
|
-
...DEFAULT_POOL_CONFIG,
|
|
85
|
-
...config?.pool,
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Access the underlying GitCascadeAdapter. Exposed for bridges that
|
|
91
|
-
* subscribe to the cascade event stream (e.g., the MAP cascade-bridge
|
|
92
|
-
* that forwards events to an OpenHive hub).
|
|
93
|
-
*
|
|
94
|
-
* Most callers should use the WorkspaceManager API surface. Use this only
|
|
95
|
-
* when direct access to the adapter's event stream or primitives is
|
|
96
|
-
* required.
|
|
97
|
-
*/
|
|
98
|
-
getGitCascadeAdapter(): GitCascadeAdapter {
|
|
99
|
-
return this.adapter;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
103
|
-
// Event System
|
|
104
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Subscribe to workspace events.
|
|
108
|
-
*
|
|
109
|
-
* @param callback - Function called when events occur
|
|
110
|
-
* @returns Unsubscribe function
|
|
111
|
-
*/
|
|
112
|
-
onEvent(callback: WorkspaceEventCallback): () => void {
|
|
113
|
-
this.eventListeners.add(callback);
|
|
114
|
-
return () => this.eventListeners.delete(callback);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Emit an event to all listeners.
|
|
119
|
-
*/
|
|
120
|
-
private emit(
|
|
121
|
-
type: WorkspaceEvent['type'],
|
|
122
|
-
data: Record<string, unknown>
|
|
123
|
-
): void {
|
|
124
|
-
const event: WorkspaceEvent = {
|
|
125
|
-
type,
|
|
126
|
-
timestamp: Date.now(),
|
|
127
|
-
data,
|
|
128
|
-
};
|
|
129
|
-
for (const listener of this.eventListeners) {
|
|
130
|
-
try {
|
|
131
|
-
listener(event);
|
|
132
|
-
} catch (error) {
|
|
133
|
-
console.error('[WorkspaceManager] Event listener error:', error);
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
139
|
-
// Stream Management
|
|
140
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* Create an integration stream for a coordinator.
|
|
144
|
-
*
|
|
145
|
-
* @param coordinatorId - ID of the coordinator agent
|
|
146
|
-
* @param config - Stream configuration
|
|
147
|
-
* @returns Stream ID
|
|
148
|
-
*/
|
|
149
|
-
createIntegrationStream(coordinatorId: AgentId, config: StreamConfig): StreamId {
|
|
150
|
-
const streamId = this.adapter.createStream({
|
|
151
|
-
name: config.name,
|
|
152
|
-
agentId: coordinatorId,
|
|
153
|
-
base: config.forkFrom ?? 'main',
|
|
154
|
-
metadata: config.metadata,
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
// Track agent → stream mapping
|
|
158
|
-
this.agentToStream.set(coordinatorId, streamId);
|
|
159
|
-
|
|
160
|
-
return streamId;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* Get a stream by ID.
|
|
165
|
-
*
|
|
166
|
-
* @param streamId - Stream ID
|
|
167
|
-
* @returns Stream or null if not found
|
|
168
|
-
*/
|
|
169
|
-
getStream(streamId: StreamId): Stream | null {
|
|
170
|
-
return this.adapter.getStream(streamId);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
174
|
-
// Worktree Management
|
|
175
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Create a workspace for a worker agent.
|
|
179
|
-
*
|
|
180
|
-
* Workers get isolated worktrees with task-specific branches.
|
|
181
|
-
* Branch format: worker/<agentId>/<taskId>@<timestamp>
|
|
182
|
-
*
|
|
183
|
-
* @param workerId - ID of the worker agent
|
|
184
|
-
* @param taskId - ID of the task to work on
|
|
185
|
-
* @param streamId - ID of the integration stream
|
|
186
|
-
* @returns Worker workspace
|
|
187
|
-
*/
|
|
188
|
-
createWorkerWorkspace(
|
|
189
|
-
workerId: AgentId,
|
|
190
|
-
taskId: TaskId,
|
|
191
|
-
streamId: StreamId
|
|
192
|
-
): WorkerWorkspace {
|
|
193
|
-
const stream = this.adapter.getStream(streamId);
|
|
194
|
-
if (!stream) {
|
|
195
|
-
throw new Error(`Stream ${streamId} not found`);
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
// Build worktree path
|
|
199
|
-
const worktreePath = this.buildWorktreePath('worker', workerId);
|
|
200
|
-
|
|
201
|
-
// Create worktree without specifying a branch (creates detached HEAD).
|
|
202
|
-
// This avoids conflicts with coordinator/other workers on the stream branch.
|
|
203
|
-
// The worker branch is created later by claimTask() via startTask().
|
|
204
|
-
const worktree = this.adapter.createWorktree({
|
|
205
|
-
agentId: workerId,
|
|
206
|
-
path: worktreePath,
|
|
207
|
-
// No branch specified - creates detached HEAD at current HEAD
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
// Create workspace record
|
|
211
|
-
const workspace: WorkerWorkspace = {
|
|
212
|
-
agentId: workerId,
|
|
213
|
-
path: worktree.path,
|
|
214
|
-
branch: worktree.currentStream
|
|
215
|
-
? `stream/${worktree.currentStream}`
|
|
216
|
-
: 'unknown',
|
|
217
|
-
streamId,
|
|
218
|
-
role: 'worker',
|
|
219
|
-
createdAt: worktree.createdAt,
|
|
220
|
-
taskId,
|
|
221
|
-
baseBranch: stream.baseCommit,
|
|
222
|
-
};
|
|
223
|
-
|
|
224
|
-
// Store workspace
|
|
225
|
-
this.workspaces.set(workerId, workspace);
|
|
226
|
-
this.agentToStream.set(workerId, streamId);
|
|
227
|
-
|
|
228
|
-
// Emit event
|
|
229
|
-
this.emit('workspace:created', {
|
|
230
|
-
agentId: workerId,
|
|
231
|
-
role: 'worker',
|
|
232
|
-
streamId,
|
|
233
|
-
taskId,
|
|
234
|
-
path: worktreePath,
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
return workspace;
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
/**
|
|
241
|
-
* Create a workspace for an integrator agent.
|
|
242
|
-
*
|
|
243
|
-
* Integrators get worktrees on a merge branch for processing the merge queue.
|
|
244
|
-
* Branch format: integrator/<coordinatorId>@<timestamp>
|
|
245
|
-
*
|
|
246
|
-
* @param integratorId - ID of the integrator agent
|
|
247
|
-
* @param streamId - ID of the integration stream
|
|
248
|
-
* @returns Integrator workspace
|
|
249
|
-
*/
|
|
250
|
-
createIntegratorWorkspace(
|
|
251
|
-
integratorId: AgentId,
|
|
252
|
-
streamId: StreamId
|
|
253
|
-
): IntegratorWorkspace {
|
|
254
|
-
const stream = this.adapter.getStream(streamId);
|
|
255
|
-
if (!stream) {
|
|
256
|
-
throw new Error(`Stream ${streamId} not found`);
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
// Build worktree path
|
|
260
|
-
const worktreePath = this.buildWorktreePath('integrator', integratorId);
|
|
261
|
-
|
|
262
|
-
// Build integrator merge branch name: integrator/<coordinatorId>@<timestamp>
|
|
263
|
-
// Per s-7ktd spec, integrators get their own merge branch separate from coordinator
|
|
264
|
-
const timestamp = Date.now();
|
|
265
|
-
const integratorBranch = `integrator/${stream.agentId}@${timestamp}`;
|
|
266
|
-
const streamBranchName = this.adapter.getStreamBranchName(streamId);
|
|
267
|
-
|
|
268
|
-
// Create worktree without specifying a branch (creates detached HEAD).
|
|
269
|
-
// This avoids conflicts with coordinator on the stream branch.
|
|
270
|
-
const worktree = this.adapter.createWorktree({
|
|
271
|
-
agentId: integratorId,
|
|
272
|
-
path: worktreePath,
|
|
273
|
-
// No branch specified - creates detached HEAD
|
|
274
|
-
});
|
|
275
|
-
|
|
276
|
-
// Create and checkout the integrator branch from the stream branch
|
|
277
|
-
// This gives the integrator its own merge branch per s-7ktd spec
|
|
278
|
-
try {
|
|
279
|
-
// Fetch the stream branch commit
|
|
280
|
-
const streamCommit = execSync(`git rev-parse ${streamBranchName}`, {
|
|
281
|
-
cwd: this.adapter.repoPath,
|
|
282
|
-
encoding: 'utf8',
|
|
283
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
284
|
-
}).trim();
|
|
285
|
-
|
|
286
|
-
// Create and checkout the integrator branch at the stream commit
|
|
287
|
-
execSync(`git checkout -b ${integratorBranch} ${streamCommit}`, {
|
|
288
|
-
cwd: worktree.path,
|
|
289
|
-
encoding: 'utf8',
|
|
290
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
291
|
-
});
|
|
292
|
-
} catch (error) {
|
|
293
|
-
console.error(`[WorkspaceManager] Failed to create integrator branch: ${error}`);
|
|
294
|
-
// Fall back to current state
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
// Create workspace record
|
|
298
|
-
const workspace: IntegratorWorkspace = {
|
|
299
|
-
agentId: integratorId,
|
|
300
|
-
path: worktree.path,
|
|
301
|
-
branch: integratorBranch,
|
|
302
|
-
streamId,
|
|
303
|
-
role: 'integrator',
|
|
304
|
-
createdAt: worktree.createdAt,
|
|
305
|
-
coordinatorId: stream.agentId,
|
|
306
|
-
integrationBranch: streamBranchName,
|
|
307
|
-
};
|
|
308
|
-
|
|
309
|
-
// Store workspace
|
|
310
|
-
this.workspaces.set(integratorId, workspace);
|
|
311
|
-
this.agentToStream.set(integratorId, streamId);
|
|
312
|
-
|
|
313
|
-
// Emit event
|
|
314
|
-
this.emit('workspace:created', {
|
|
315
|
-
agentId: integratorId,
|
|
316
|
-
role: 'integrator',
|
|
317
|
-
streamId,
|
|
318
|
-
coordinatorId: stream.agentId,
|
|
319
|
-
path: worktreePath,
|
|
320
|
-
});
|
|
321
|
-
|
|
322
|
-
return workspace;
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
/**
|
|
326
|
-
* Create a workspace for a coordinator agent.
|
|
327
|
-
*
|
|
328
|
-
* Coordinators get worktrees on the integration branch.
|
|
329
|
-
* Branch format: feature/<name>-<coordinatorId> (via stream)
|
|
330
|
-
*
|
|
331
|
-
* @param coordinatorId - ID of the coordinator agent
|
|
332
|
-
* @param streamId - ID of the integration stream
|
|
333
|
-
* @returns Coordinator workspace
|
|
334
|
-
*/
|
|
335
|
-
createCoordinatorWorkspace(
|
|
336
|
-
coordinatorId: AgentId,
|
|
337
|
-
streamId: StreamId
|
|
338
|
-
): CoordinatorWorkspace {
|
|
339
|
-
const stream = this.adapter.getStream(streamId);
|
|
340
|
-
if (!stream) {
|
|
341
|
-
throw new Error(`Stream ${streamId} not found`);
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
// Build worktree path
|
|
345
|
-
const worktreePath = this.buildWorktreePath('coordinator', coordinatorId);
|
|
346
|
-
|
|
347
|
-
// Coordinator works on the stream branch
|
|
348
|
-
const worktree = this.adapter.createWorktree({
|
|
349
|
-
agentId: coordinatorId,
|
|
350
|
-
path: worktreePath,
|
|
351
|
-
branch: this.adapter.getStreamBranchName(streamId),
|
|
352
|
-
});
|
|
353
|
-
|
|
354
|
-
// Create workspace record
|
|
355
|
-
const workspace: CoordinatorWorkspace = {
|
|
356
|
-
agentId: coordinatorId,
|
|
357
|
-
path: worktree.path,
|
|
358
|
-
branch: this.adapter.getStreamBranchName(streamId),
|
|
359
|
-
streamId,
|
|
360
|
-
role: 'coordinator',
|
|
361
|
-
createdAt: worktree.createdAt,
|
|
362
|
-
childWorkspacePaths: new Map(),
|
|
363
|
-
};
|
|
364
|
-
|
|
365
|
-
// Store workspace
|
|
366
|
-
this.workspaces.set(coordinatorId, workspace);
|
|
367
|
-
this.agentToStream.set(coordinatorId, streamId);
|
|
368
|
-
|
|
369
|
-
// Emit event
|
|
370
|
-
this.emit('workspace:created', {
|
|
371
|
-
agentId: coordinatorId,
|
|
372
|
-
role: 'coordinator',
|
|
373
|
-
streamId,
|
|
374
|
-
path: worktreePath,
|
|
375
|
-
});
|
|
376
|
-
|
|
377
|
-
return workspace;
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
/**
|
|
381
|
-
* Deallocate a workspace and release resources.
|
|
382
|
-
*
|
|
383
|
-
* @param agentId - ID of the agent whose workspace to deallocate
|
|
384
|
-
*/
|
|
385
|
-
deallocateWorkspace(agentId: AgentId): void {
|
|
386
|
-
// Case 1: agentId is a sharer on someone else's worktree. Decrement
|
|
387
|
-
// the ref-count; only tear down if this was the last sharer AND the
|
|
388
|
-
// owner had previously departed.
|
|
389
|
-
for (const [path, entry] of this.sharedWorktreeRefs) {
|
|
390
|
-
if (entry.sharers.has(agentId)) {
|
|
391
|
-
entry.sharers.delete(agentId);
|
|
392
|
-
this.emit('worktree:released', {
|
|
393
|
-
agentId,
|
|
394
|
-
path,
|
|
395
|
-
kind: 'sharer',
|
|
396
|
-
});
|
|
397
|
-
if (entry.ownerDeparted && entry.sharers.size === 0) {
|
|
398
|
-
// Last sharer exiting after owner departed — finalize teardown
|
|
399
|
-
// under the original owner's id.
|
|
400
|
-
this.adapter.deallocateWorktree(entry.ownerId);
|
|
401
|
-
this.sharedWorktreeRefs.delete(path);
|
|
402
|
-
this.emit('workspace:deallocated', {
|
|
403
|
-
agentId: entry.ownerId,
|
|
404
|
-
path,
|
|
405
|
-
deferredUntilLastSharer: true,
|
|
406
|
-
});
|
|
407
|
-
}
|
|
408
|
-
return;
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
const workspace = this.workspaces.get(agentId);
|
|
413
|
-
if (!workspace) {
|
|
414
|
-
return; // Already deallocated
|
|
415
|
-
}
|
|
416
|
-
|
|
417
|
-
// Case 2: agentId is an owner of a shared worktree with active sharers.
|
|
418
|
-
// Defer git-cascade teardown until the last sharer leaves.
|
|
419
|
-
const sharedEntry = this.sharedWorktreeRefs.get(workspace.path);
|
|
420
|
-
if (
|
|
421
|
-
sharedEntry &&
|
|
422
|
-
sharedEntry.ownerId === agentId &&
|
|
423
|
-
sharedEntry.sharers.size > 0
|
|
424
|
-
) {
|
|
425
|
-
sharedEntry.ownerDeparted = true;
|
|
426
|
-
this.workspaces.delete(agentId);
|
|
427
|
-
this.agentToStream.delete(agentId);
|
|
428
|
-
this.emit('worktree:released', {
|
|
429
|
-
agentId,
|
|
430
|
-
path: workspace.path,
|
|
431
|
-
kind: 'owner-departed',
|
|
432
|
-
remainingSharers: sharedEntry.sharers.size,
|
|
433
|
-
});
|
|
434
|
-
return;
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
// Case 3: normal teardown — owner with no sharers (or no sharing involved).
|
|
438
|
-
|
|
439
|
-
// Remove from coordinator's child workspace map if this is a child
|
|
440
|
-
if (workspace.role === 'worker' || workspace.role === 'integrator') {
|
|
441
|
-
const streamId = workspace.streamId;
|
|
442
|
-
const stream = this.adapter.getStream(streamId);
|
|
443
|
-
if (stream) {
|
|
444
|
-
const coordinatorWorkspace = this.workspaces.get(
|
|
445
|
-
stream.agentId
|
|
446
|
-
) as CoordinatorWorkspace | undefined;
|
|
447
|
-
coordinatorWorkspace?.childWorkspacePaths?.delete(agentId);
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
// Deallocate via git-cascade adapter
|
|
452
|
-
this.adapter.deallocateWorktree(agentId);
|
|
453
|
-
|
|
454
|
-
// Clean up mappings
|
|
455
|
-
this.workspaces.delete(agentId);
|
|
456
|
-
this.agentToStream.delete(agentId);
|
|
457
|
-
|
|
458
|
-
// Also clean up any stale entry (owner with zero sharers at deallocation time)
|
|
459
|
-
if (sharedEntry && sharedEntry.ownerId === agentId) {
|
|
460
|
-
this.sharedWorktreeRefs.delete(workspace.path);
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
this.emit('workspace:deallocated', {
|
|
464
|
-
agentId,
|
|
465
|
-
role: workspace.role,
|
|
466
|
-
streamId: workspace.streamId,
|
|
467
|
-
});
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
471
|
-
// Task Management
|
|
472
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
473
|
-
|
|
474
|
-
/**
|
|
475
|
-
* Create a task under a stream.
|
|
476
|
-
*
|
|
477
|
-
* @param streamId - ID of the integration stream
|
|
478
|
-
* @param options - Task creation options
|
|
479
|
-
* @returns Task ID
|
|
480
|
-
*/
|
|
481
|
-
createTask(streamId: StreamId, options: CreateTaskOptions): TaskId {
|
|
482
|
-
return this.adapter.createTask({
|
|
483
|
-
streamId,
|
|
484
|
-
title: options.title,
|
|
485
|
-
priority: options.priority,
|
|
486
|
-
metadata: options.metadata,
|
|
487
|
-
});
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
/**
|
|
491
|
-
* Claim a task for a worker.
|
|
492
|
-
*
|
|
493
|
-
* Starts the task - creates worker branch and checks it out.
|
|
494
|
-
*
|
|
495
|
-
* @param taskId - ID of the task to claim
|
|
496
|
-
* @param workerId - ID of the worker agent
|
|
497
|
-
* @param worktree - Path to the worker's worktree
|
|
498
|
-
* @returns Start task result with branch info
|
|
499
|
-
*/
|
|
500
|
-
claimTask(
|
|
501
|
-
taskId: TaskId,
|
|
502
|
-
workerId: AgentId,
|
|
503
|
-
worktree: string
|
|
504
|
-
): StartTaskResult {
|
|
505
|
-
return this.adapter.startTask({
|
|
506
|
-
taskId,
|
|
507
|
-
agentId: workerId,
|
|
508
|
-
worktree,
|
|
509
|
-
});
|
|
510
|
-
}
|
|
511
|
-
|
|
512
|
-
/**
|
|
513
|
-
* Get the next available task for a stream.
|
|
514
|
-
*
|
|
515
|
-
* Returns the highest priority (lowest number), oldest task with status 'open'.
|
|
516
|
-
*
|
|
517
|
-
* @param streamId - ID of the integration stream
|
|
518
|
-
* @returns Next task or null if none available
|
|
519
|
-
*/
|
|
520
|
-
getNextTask(streamId: StreamId): WorkerTask | null {
|
|
521
|
-
const tasks = this.adapter.listTasks(streamId, { status: 'open' });
|
|
522
|
-
return tasks.length > 0 ? tasks[0] : null;
|
|
523
|
-
}
|
|
524
|
-
|
|
525
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
526
|
-
// Queries
|
|
527
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
528
|
-
|
|
529
|
-
/**
|
|
530
|
-
* Get workspace for an agent.
|
|
531
|
-
*
|
|
532
|
-
* @param agentId - ID of the agent
|
|
533
|
-
* @returns Workspace or null if not found
|
|
534
|
-
*/
|
|
535
|
-
getWorkspace(agentId: AgentId): Workspace | null {
|
|
536
|
-
return this.workspaces.get(agentId) ?? null;
|
|
537
|
-
}
|
|
538
|
-
|
|
539
|
-
/**
|
|
540
|
-
* Get the stream ID for an agent.
|
|
541
|
-
*
|
|
542
|
-
* @param agentId - ID of the agent
|
|
543
|
-
* @returns Stream ID or null if not found
|
|
544
|
-
*/
|
|
545
|
-
getStreamForAgent(agentId: AgentId): StreamId | null {
|
|
546
|
-
return this.agentToStream.get(agentId) ?? null;
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
/**
|
|
550
|
-
* Register a child workspace path with a coordinator.
|
|
551
|
-
*
|
|
552
|
-
* @param coordinatorId - ID of the coordinator
|
|
553
|
-
* @param childId - ID of the child agent
|
|
554
|
-
* @param childPath - Filesystem path to child's workspace
|
|
555
|
-
*/
|
|
556
|
-
registerChildWorkspace(
|
|
557
|
-
coordinatorId: AgentId,
|
|
558
|
-
childId: AgentId,
|
|
559
|
-
childPath: string
|
|
560
|
-
): void {
|
|
561
|
-
const workspace = this.workspaces.get(coordinatorId) as
|
|
562
|
-
| CoordinatorWorkspace
|
|
563
|
-
| undefined;
|
|
564
|
-
if (!workspace || workspace.role !== 'coordinator') {
|
|
565
|
-
throw new Error(`No coordinator workspace found for ${coordinatorId}`);
|
|
566
|
-
}
|
|
567
|
-
|
|
568
|
-
workspace.childWorkspacePaths.set(childId, childPath);
|
|
569
|
-
|
|
570
|
-
// Emit event
|
|
571
|
-
this.emit('child:registered', {
|
|
572
|
-
coordinatorId,
|
|
573
|
-
childId,
|
|
574
|
-
childPath,
|
|
575
|
-
});
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
/**
|
|
579
|
-
* Get the underlying GitCascadeAdapter.
|
|
580
|
-
*
|
|
581
|
-
* Use with caution - prefer manager methods for operations.
|
|
582
|
-
*/
|
|
583
|
-
get rawAdapter(): GitCascadeAdapter {
|
|
584
|
-
return this.adapter;
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
588
|
-
// Merge Queue
|
|
589
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
590
|
-
|
|
591
|
-
/**
|
|
592
|
-
* Get the merge queue for coordinating worker merges.
|
|
593
|
-
*
|
|
594
|
-
* The merge queue is lazily initialized on first access and uses
|
|
595
|
-
* the same database as the git-cascade adapter.
|
|
596
|
-
*
|
|
597
|
-
* @returns MergeQueue instance
|
|
598
|
-
*/
|
|
599
|
-
getMergeQueue(): MergeQueueInterface {
|
|
600
|
-
if (!this.mergeQueue) {
|
|
601
|
-
this.mergeQueue = new MergeQueue({
|
|
602
|
-
db: this.adapter.db,
|
|
603
|
-
tablePrefix: 'macro_', // Use different prefix from git-cascade tables
|
|
604
|
-
initSchema: true,
|
|
605
|
-
});
|
|
606
|
-
}
|
|
607
|
-
return this.mergeQueue;
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
611
|
-
// Worktree Pool
|
|
612
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
613
|
-
|
|
614
|
-
/**
|
|
615
|
-
* Get the worktree pool for managing shared worktrees.
|
|
616
|
-
*
|
|
617
|
-
* The pool is lazily initialized on first access. Returns null if
|
|
618
|
-
* pool is not enabled in configuration.
|
|
619
|
-
*
|
|
620
|
-
* @returns WorktreePool instance or null if not enabled
|
|
621
|
-
*/
|
|
622
|
-
getPool(): WorktreePool | null {
|
|
623
|
-
if (!this.poolConfig.enabled) {
|
|
624
|
-
return null;
|
|
625
|
-
}
|
|
626
|
-
|
|
627
|
-
if (!this.pool) {
|
|
628
|
-
this.pool = new WorktreePool(this.adapter.repoPath, {
|
|
629
|
-
worktreeBaseDir: this.config.worktreeBaseDir,
|
|
630
|
-
maxSize: this.poolConfig.maxSize ?? 50,
|
|
631
|
-
useThemedNames: this.poolConfig.useThemedNames,
|
|
632
|
-
themedNames: this.poolConfig.themedNames,
|
|
633
|
-
recoverOrphans: this.poolConfig.recoverOrphans,
|
|
634
|
-
defaultStrategy: this.poolConfig.defaultStrategy,
|
|
635
|
-
});
|
|
636
|
-
}
|
|
637
|
-
|
|
638
|
-
return this.pool;
|
|
639
|
-
}
|
|
640
|
-
|
|
641
|
-
/**
|
|
642
|
-
* Check if the worktree pool is enabled.
|
|
643
|
-
*
|
|
644
|
-
* @returns true if pool is enabled
|
|
645
|
-
*/
|
|
646
|
-
isPoolEnabled(): boolean {
|
|
647
|
-
return this.poolConfig.enabled;
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
/**
|
|
651
|
-
* Acquire a worktree from the pool for an agent.
|
|
652
|
-
*
|
|
653
|
-
* This is a lower-level method - prefer using createWorkerWorkspace,
|
|
654
|
-
* createIntegratorWorkspace, or createCoordinatorWorkspace which
|
|
655
|
-
* handle pool allocation automatically when enabled.
|
|
656
|
-
*
|
|
657
|
-
* @param options - Acquisition options
|
|
658
|
-
* @returns Worktree path or null if allocation failed
|
|
659
|
-
* @throws Error if pool is not enabled
|
|
660
|
-
*/
|
|
661
|
-
async acquireFromPool(options: AcquireOptions): Promise<string | null> {
|
|
662
|
-
const pool = this.getPool();
|
|
663
|
-
if (!pool) {
|
|
664
|
-
throw new Error('Worktree pool is not enabled');
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
const result = await pool.acquire(options);
|
|
668
|
-
if (result.success && result.worktree) {
|
|
669
|
-
return result.worktree.path;
|
|
670
|
-
}
|
|
671
|
-
|
|
672
|
-
return null;
|
|
673
|
-
}
|
|
674
|
-
|
|
675
|
-
/**
|
|
676
|
-
* Release a worktree back to the pool.
|
|
677
|
-
*
|
|
678
|
-
* This is called automatically by deallocateWorkspace when pool is enabled.
|
|
679
|
-
*
|
|
680
|
-
* @param agentId - Agent releasing the worktree
|
|
681
|
-
* @param clean - Whether to clean the worktree (default: true)
|
|
682
|
-
* @throws Error if pool is not enabled
|
|
683
|
-
*/
|
|
684
|
-
async releaseToPool(agentId: AgentId, clean = true): Promise<void> {
|
|
685
|
-
const pool = this.getPool();
|
|
686
|
-
if (!pool) {
|
|
687
|
-
throw new Error('Worktree pool is not enabled');
|
|
688
|
-
}
|
|
689
|
-
|
|
690
|
-
await pool.release(agentId, { clean });
|
|
691
|
-
}
|
|
692
|
-
|
|
693
|
-
/**
|
|
694
|
-
* Create a workspace for a worker using the pool.
|
|
695
|
-
*
|
|
696
|
-
* Pool-aware variant of createWorkerWorkspace. Uses the shared worktree
|
|
697
|
-
* pool for allocation when enabled.
|
|
698
|
-
*
|
|
699
|
-
* @param workerId - ID of the worker agent
|
|
700
|
-
* @param taskId - ID of the task to work on
|
|
701
|
-
* @param streamId - ID of the integration stream
|
|
702
|
-
* @param strategy - Allocation strategy if pool is exhausted
|
|
703
|
-
* @returns Worker workspace
|
|
704
|
-
* @throws Error if pool is exhausted and strategy is 'reject'
|
|
705
|
-
*/
|
|
706
|
-
async createWorkerWorkspaceFromPool(
|
|
707
|
-
workerId: AgentId,
|
|
708
|
-
taskId: TaskId,
|
|
709
|
-
streamId: StreamId,
|
|
710
|
-
strategy?: AllocationStrategy
|
|
711
|
-
): Promise<WorkerWorkspace> {
|
|
712
|
-
const pool = this.getPool();
|
|
713
|
-
if (!pool) {
|
|
714
|
-
// Fall back to non-pooled allocation
|
|
715
|
-
return this.createWorkerWorkspace(workerId, taskId, streamId);
|
|
716
|
-
}
|
|
717
|
-
|
|
718
|
-
const stream = this.adapter.getStream(streamId);
|
|
719
|
-
if (!stream) {
|
|
720
|
-
throw new Error(`Stream ${streamId} not found`);
|
|
721
|
-
}
|
|
722
|
-
|
|
723
|
-
// Acquire worktree from pool
|
|
724
|
-
const result = await pool.acquire({
|
|
725
|
-
agentId: workerId,
|
|
726
|
-
role: 'worker',
|
|
727
|
-
strategy: strategy ?? this.poolConfig.defaultStrategy,
|
|
728
|
-
});
|
|
729
|
-
|
|
730
|
-
if (!result.success || !result.worktree) {
|
|
731
|
-
throw new Error(result.error ?? 'Failed to acquire worktree from pool');
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
const worktreePath = result.worktree.path;
|
|
735
|
-
|
|
736
|
-
// Create workspace record
|
|
737
|
-
const workspace: WorkerWorkspace = {
|
|
738
|
-
agentId: workerId,
|
|
739
|
-
path: worktreePath,
|
|
740
|
-
branch: 'detached', // Will be updated by claimTask
|
|
741
|
-
streamId,
|
|
742
|
-
role: 'worker',
|
|
743
|
-
createdAt: Date.now(),
|
|
744
|
-
taskId,
|
|
745
|
-
baseBranch: stream.baseCommit,
|
|
746
|
-
};
|
|
747
|
-
|
|
748
|
-
// Store workspace
|
|
749
|
-
this.workspaces.set(workerId, workspace);
|
|
750
|
-
this.agentToStream.set(workerId, streamId);
|
|
751
|
-
|
|
752
|
-
// Emit event
|
|
753
|
-
this.emit('workspace:created', {
|
|
754
|
-
agentId: workerId,
|
|
755
|
-
role: 'worker',
|
|
756
|
-
streamId,
|
|
757
|
-
taskId,
|
|
758
|
-
path: worktreePath,
|
|
759
|
-
pooled: true,
|
|
760
|
-
});
|
|
761
|
-
|
|
762
|
-
return workspace;
|
|
763
|
-
}
|
|
764
|
-
|
|
765
|
-
/**
|
|
766
|
-
* Create a workspace for an integrator using the pool.
|
|
767
|
-
*
|
|
768
|
-
* Pool-aware variant of createIntegratorWorkspace. Uses the shared worktree
|
|
769
|
-
* pool for allocation when enabled.
|
|
770
|
-
*
|
|
771
|
-
* @param integratorId - ID of the integrator agent
|
|
772
|
-
* @param streamId - ID of the integration stream
|
|
773
|
-
* @param strategy - Allocation strategy if pool is exhausted
|
|
774
|
-
* @returns Integrator workspace
|
|
775
|
-
* @throws Error if pool is exhausted and strategy is 'reject'
|
|
776
|
-
*/
|
|
777
|
-
async createIntegratorWorkspaceFromPool(
|
|
778
|
-
integratorId: AgentId,
|
|
779
|
-
streamId: StreamId,
|
|
780
|
-
strategy?: AllocationStrategy
|
|
781
|
-
): Promise<IntegratorWorkspace> {
|
|
782
|
-
const pool = this.getPool();
|
|
783
|
-
if (!pool) {
|
|
784
|
-
// Fall back to non-pooled allocation
|
|
785
|
-
return this.createIntegratorWorkspace(integratorId, streamId);
|
|
786
|
-
}
|
|
787
|
-
|
|
788
|
-
const stream = this.adapter.getStream(streamId);
|
|
789
|
-
if (!stream) {
|
|
790
|
-
throw new Error(`Stream ${streamId} not found`);
|
|
791
|
-
}
|
|
792
|
-
|
|
793
|
-
// Acquire worktree from pool
|
|
794
|
-
const result = await pool.acquire({
|
|
795
|
-
agentId: integratorId,
|
|
796
|
-
role: 'integrator',
|
|
797
|
-
strategy: strategy ?? this.poolConfig.defaultStrategy,
|
|
798
|
-
});
|
|
799
|
-
|
|
800
|
-
if (!result.success || !result.worktree) {
|
|
801
|
-
throw new Error(result.error ?? 'Failed to acquire worktree from pool');
|
|
802
|
-
}
|
|
803
|
-
|
|
804
|
-
const worktreePath = result.worktree.path;
|
|
805
|
-
|
|
806
|
-
// Build integrator merge branch name
|
|
807
|
-
const timestamp = Date.now();
|
|
808
|
-
const integratorBranch = `integrator/${stream.agentId}@${timestamp}`;
|
|
809
|
-
const streamBranchName = this.adapter.getStreamBranchName(streamId);
|
|
810
|
-
|
|
811
|
-
// Create and checkout the integrator branch from the stream branch
|
|
812
|
-
try {
|
|
813
|
-
const streamCommit = execSync(`git rev-parse ${streamBranchName}`, {
|
|
814
|
-
cwd: this.adapter.repoPath,
|
|
815
|
-
encoding: 'utf8',
|
|
816
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
817
|
-
}).trim();
|
|
818
|
-
|
|
819
|
-
execSync(`git checkout -b ${integratorBranch} ${streamCommit}`, {
|
|
820
|
-
cwd: worktreePath,
|
|
821
|
-
encoding: 'utf8',
|
|
822
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
823
|
-
});
|
|
824
|
-
} catch (error) {
|
|
825
|
-
console.error(`[WorkspaceManager] Failed to create integrator branch: ${error}`);
|
|
826
|
-
}
|
|
827
|
-
|
|
828
|
-
// Create workspace record
|
|
829
|
-
const workspace: IntegratorWorkspace = {
|
|
830
|
-
agentId: integratorId,
|
|
831
|
-
path: worktreePath,
|
|
832
|
-
branch: integratorBranch,
|
|
833
|
-
streamId,
|
|
834
|
-
role: 'integrator',
|
|
835
|
-
createdAt: Date.now(),
|
|
836
|
-
coordinatorId: stream.agentId,
|
|
837
|
-
integrationBranch: streamBranchName,
|
|
838
|
-
};
|
|
839
|
-
|
|
840
|
-
// Store workspace
|
|
841
|
-
this.workspaces.set(integratorId, workspace);
|
|
842
|
-
this.agentToStream.set(integratorId, streamId);
|
|
843
|
-
|
|
844
|
-
// Emit event
|
|
845
|
-
this.emit('workspace:created', {
|
|
846
|
-
agentId: integratorId,
|
|
847
|
-
role: 'integrator',
|
|
848
|
-
streamId,
|
|
849
|
-
coordinatorId: stream.agentId,
|
|
850
|
-
path: worktreePath,
|
|
851
|
-
pooled: true,
|
|
852
|
-
});
|
|
853
|
-
|
|
854
|
-
return workspace;
|
|
855
|
-
}
|
|
856
|
-
|
|
857
|
-
/**
|
|
858
|
-
* Create a workspace for a coordinator using the pool.
|
|
859
|
-
*
|
|
860
|
-
* Pool-aware variant of createCoordinatorWorkspace. Uses the shared worktree
|
|
861
|
-
* pool for allocation when enabled.
|
|
862
|
-
*
|
|
863
|
-
* @param coordinatorId - ID of the coordinator agent
|
|
864
|
-
* @param streamId - ID of the integration stream
|
|
865
|
-
* @param strategy - Allocation strategy if pool is exhausted
|
|
866
|
-
* @returns Coordinator workspace
|
|
867
|
-
* @throws Error if pool is exhausted and strategy is 'reject'
|
|
868
|
-
*/
|
|
869
|
-
async createCoordinatorWorkspaceFromPool(
|
|
870
|
-
coordinatorId: AgentId,
|
|
871
|
-
streamId: StreamId,
|
|
872
|
-
strategy?: AllocationStrategy
|
|
873
|
-
): Promise<CoordinatorWorkspace> {
|
|
874
|
-
const pool = this.getPool();
|
|
875
|
-
if (!pool) {
|
|
876
|
-
// Fall back to non-pooled allocation
|
|
877
|
-
return this.createCoordinatorWorkspace(coordinatorId, streamId);
|
|
878
|
-
}
|
|
879
|
-
|
|
880
|
-
const stream = this.adapter.getStream(streamId);
|
|
881
|
-
if (!stream) {
|
|
882
|
-
throw new Error(`Stream ${streamId} not found`);
|
|
883
|
-
}
|
|
884
|
-
|
|
885
|
-
// Acquire worktree from pool
|
|
886
|
-
const result = await pool.acquire({
|
|
887
|
-
agentId: coordinatorId,
|
|
888
|
-
role: 'coordinator',
|
|
889
|
-
strategy: strategy ?? this.poolConfig.defaultStrategy,
|
|
890
|
-
});
|
|
891
|
-
|
|
892
|
-
if (!result.success || !result.worktree) {
|
|
893
|
-
throw new Error(result.error ?? 'Failed to acquire worktree from pool');
|
|
894
|
-
}
|
|
895
|
-
|
|
896
|
-
const worktreePath = result.worktree.path;
|
|
897
|
-
const streamBranchName = this.adapter.getStreamBranchName(streamId);
|
|
898
|
-
|
|
899
|
-
// Checkout the stream branch
|
|
900
|
-
try {
|
|
901
|
-
execSync(`git checkout ${streamBranchName}`, {
|
|
902
|
-
cwd: worktreePath,
|
|
903
|
-
encoding: 'utf8',
|
|
904
|
-
stdio: ['pipe', 'pipe', 'pipe'],
|
|
905
|
-
});
|
|
906
|
-
} catch (error) {
|
|
907
|
-
console.error(`[WorkspaceManager] Failed to checkout stream branch: ${error}`);
|
|
908
|
-
}
|
|
909
|
-
|
|
910
|
-
// Create workspace record
|
|
911
|
-
const workspace: CoordinatorWorkspace = {
|
|
912
|
-
agentId: coordinatorId,
|
|
913
|
-
path: worktreePath,
|
|
914
|
-
branch: streamBranchName,
|
|
915
|
-
streamId,
|
|
916
|
-
role: 'coordinator',
|
|
917
|
-
createdAt: Date.now(),
|
|
918
|
-
childWorkspacePaths: new Map(),
|
|
919
|
-
};
|
|
920
|
-
|
|
921
|
-
// Store workspace
|
|
922
|
-
this.workspaces.set(coordinatorId, workspace);
|
|
923
|
-
this.agentToStream.set(coordinatorId, streamId);
|
|
924
|
-
|
|
925
|
-
// Emit event
|
|
926
|
-
this.emit('workspace:created', {
|
|
927
|
-
agentId: coordinatorId,
|
|
928
|
-
role: 'coordinator',
|
|
929
|
-
streamId,
|
|
930
|
-
path: worktreePath,
|
|
931
|
-
pooled: true,
|
|
932
|
-
});
|
|
933
|
-
|
|
934
|
-
return workspace;
|
|
935
|
-
}
|
|
936
|
-
|
|
937
|
-
/**
|
|
938
|
-
* Deallocate a workspace and release resources.
|
|
939
|
-
*
|
|
940
|
-
* Async variant that properly releases pooled worktrees.
|
|
941
|
-
*
|
|
942
|
-
* @param agentId - ID of the agent whose workspace to deallocate
|
|
943
|
-
* @param clean - Whether to clean the worktree (default: true)
|
|
944
|
-
*/
|
|
945
|
-
async deallocateWorkspaceAsync(agentId: AgentId, clean = true): Promise<void> {
|
|
946
|
-
const workspace = this.workspaces.get(agentId);
|
|
947
|
-
if (!workspace) {
|
|
948
|
-
return; // Already deallocated
|
|
949
|
-
}
|
|
950
|
-
|
|
951
|
-
// Remove from coordinator's child workspace map if this is a child
|
|
952
|
-
if (workspace.role === 'worker' || workspace.role === 'integrator') {
|
|
953
|
-
const streamId = workspace.streamId;
|
|
954
|
-
const stream = this.adapter.getStream(streamId);
|
|
955
|
-
if (stream) {
|
|
956
|
-
const coordinatorWorkspace = this.workspaces.get(
|
|
957
|
-
stream.agentId
|
|
958
|
-
) as CoordinatorWorkspace | undefined;
|
|
959
|
-
coordinatorWorkspace?.childWorkspacePaths?.delete(agentId);
|
|
960
|
-
}
|
|
961
|
-
}
|
|
962
|
-
|
|
963
|
-
// Release to pool if enabled, otherwise deallocate via git-cascade
|
|
964
|
-
const pool = this.getPool();
|
|
965
|
-
if (pool) {
|
|
966
|
-
await pool.release(agentId, { clean });
|
|
967
|
-
} else {
|
|
968
|
-
this.adapter.deallocateWorktree(agentId);
|
|
969
|
-
}
|
|
970
|
-
|
|
971
|
-
// Clean up mappings
|
|
972
|
-
this.workspaces.delete(agentId);
|
|
973
|
-
this.agentToStream.delete(agentId);
|
|
974
|
-
|
|
975
|
-
// Emit event
|
|
976
|
-
this.emit('workspace:deallocated', {
|
|
977
|
-
agentId,
|
|
978
|
-
role: workspace.role,
|
|
979
|
-
streamId: workspace.streamId,
|
|
980
|
-
pooled: !!pool,
|
|
981
|
-
});
|
|
982
|
-
}
|
|
983
|
-
|
|
984
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
985
|
-
// Maintenance / Cleanup
|
|
986
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
987
|
-
|
|
988
|
-
/**
|
|
989
|
-
* Clean up old worker branches.
|
|
990
|
-
*
|
|
991
|
-
* Deletes branches for:
|
|
992
|
-
* - Completed tasks older than threshold (default 24h)
|
|
993
|
-
* - Abandoned tasks
|
|
994
|
-
* - Orphaned branches (no task record)
|
|
995
|
-
*
|
|
996
|
-
* @param options - Cleanup options
|
|
997
|
-
* @returns Deleted branches and any errors
|
|
998
|
-
*/
|
|
999
|
-
cleanupWorkerBranches(options?: CleanupWorkerBranchesOptions): CleanupResult {
|
|
1000
|
-
const result = this.adapter.cleanupWorkerBranches(options);
|
|
1001
|
-
|
|
1002
|
-
// Emit event if any branches were deleted
|
|
1003
|
-
if (result.deleted.length > 0) {
|
|
1004
|
-
this.emit('branches:cleaned', {
|
|
1005
|
-
deleted: result.deleted,
|
|
1006
|
-
errors: result.errors,
|
|
1007
|
-
});
|
|
1008
|
-
}
|
|
1009
|
-
|
|
1010
|
-
return result;
|
|
1011
|
-
}
|
|
1012
|
-
|
|
1013
|
-
/**
|
|
1014
|
-
* Delete a specific worker branch.
|
|
1015
|
-
*
|
|
1016
|
-
* Useful for immediate cleanup after task completion.
|
|
1017
|
-
*
|
|
1018
|
-
* @param branchName - Branch name to delete
|
|
1019
|
-
* @returns true if deleted, false if branch didn't exist
|
|
1020
|
-
*/
|
|
1021
|
-
deleteWorkerBranch(branchName: string): boolean {
|
|
1022
|
-
const result = this.adapter.deleteWorkerBranch(branchName);
|
|
1023
|
-
|
|
1024
|
-
if (result) {
|
|
1025
|
-
this.emit('branch:deleted', { branchName });
|
|
1026
|
-
}
|
|
1027
|
-
|
|
1028
|
-
return result;
|
|
1029
|
-
}
|
|
1030
|
-
|
|
1031
|
-
// ═════════════════════════════════════════════════════════════════════════════
|
|
1032
|
-
// V3 — Stream-first surface
|
|
1033
|
-
//
|
|
1034
|
-
// Additive with the role-shaped methods above. Callers migrate piecewise
|
|
1035
|
-
// during Phases 3-4; Phase 9 removes the legacy methods. See
|
|
1036
|
-
// docs/workspace-interfaces.md §5 and docs/workspace-redesign-plan.md.
|
|
1037
|
-
// ═════════════════════════════════════════════════════════════════════════════
|
|
1038
|
-
|
|
1039
|
-
private readonly landingStrategies: Map<string, import('./types-v3.js').LandingStrategy> = new Map();
|
|
1040
|
-
|
|
1041
|
-
/**
|
|
1042
|
-
* Ref-counted sharing state keyed by worktree path.
|
|
1043
|
-
*
|
|
1044
|
-
* - `ownerId`: the principal that originally allocated the worktree (the
|
|
1045
|
-
* id that git-cascade's tracker associates with the worktree).
|
|
1046
|
-
* - `sharers`: other agents that allocated via `sharedWithAgent`.
|
|
1047
|
-
* - `ownerDeparted`: set when the owner deallocates but sharers remain —
|
|
1048
|
-
* the actual git-cascade teardown is deferred until `sharers` is empty.
|
|
1049
|
-
*/
|
|
1050
|
-
private readonly sharedWorktreeRefs: Map<
|
|
1051
|
-
string,
|
|
1052
|
-
{ ownerId: import('./types-v3.js').Principal; sharers: Set<AgentId>; ownerDeparted: boolean }
|
|
1053
|
-
> = new Map();
|
|
1054
|
-
|
|
1055
|
-
createStreamV3(spec: import('./types-v3.js').StreamSpec): StreamId {
|
|
1056
|
-
let streamId: StreamId;
|
|
1057
|
-
if (spec.parent) {
|
|
1058
|
-
streamId = this.adapter.forkStream({
|
|
1059
|
-
parentStreamId: spec.parent,
|
|
1060
|
-
name: spec.name,
|
|
1061
|
-
agentId: spec.ownerId,
|
|
1062
|
-
});
|
|
1063
|
-
// git-cascade's ForkStreamOptions doesn't accept metadata; apply via update.
|
|
1064
|
-
if (spec.metadata) {
|
|
1065
|
-
this.adapter.updateStream(streamId, { metadata: spec.metadata });
|
|
1066
|
-
}
|
|
1067
|
-
} else {
|
|
1068
|
-
streamId = this.adapter.createStream({
|
|
1069
|
-
name: spec.name,
|
|
1070
|
-
agentId: spec.ownerId,
|
|
1071
|
-
base: spec.forkFrom ?? 'main',
|
|
1072
|
-
metadata: spec.metadata,
|
|
1073
|
-
});
|
|
1074
|
-
}
|
|
1075
|
-
this.emit(spec.parent ? 'stream:forked' : 'stream:created', {
|
|
1076
|
-
streamId,
|
|
1077
|
-
ownerId: spec.ownerId,
|
|
1078
|
-
parentStreamId: spec.parent,
|
|
1079
|
-
});
|
|
1080
|
-
return streamId;
|
|
1081
|
-
}
|
|
1082
|
-
|
|
1083
|
-
forkStream(opts: {
|
|
1084
|
-
parentStreamId: StreamId;
|
|
1085
|
-
name: string;
|
|
1086
|
-
ownerId: import('./types-v3.js').Principal;
|
|
1087
|
-
metadata?: Record<string, unknown>;
|
|
1088
|
-
}): StreamId {
|
|
1089
|
-
const streamId = this.adapter.forkStream({
|
|
1090
|
-
parentStreamId: opts.parentStreamId,
|
|
1091
|
-
name: opts.name,
|
|
1092
|
-
agentId: opts.ownerId,
|
|
1093
|
-
});
|
|
1094
|
-
if (opts.metadata) {
|
|
1095
|
-
this.adapter.updateStream(streamId, { metadata: opts.metadata });
|
|
1096
|
-
}
|
|
1097
|
-
this.emit('stream:forked', {
|
|
1098
|
-
streamId,
|
|
1099
|
-
parentStreamId: opts.parentStreamId,
|
|
1100
|
-
ownerId: opts.ownerId,
|
|
1101
|
-
});
|
|
1102
|
-
return streamId;
|
|
1103
|
-
}
|
|
1104
|
-
|
|
1105
|
-
mergeStream(opts: {
|
|
1106
|
-
sourceStreamId: StreamId;
|
|
1107
|
-
targetStreamId: StreamId;
|
|
1108
|
-
agentId: import('./types-v3.js').Principal;
|
|
1109
|
-
worktree: string;
|
|
1110
|
-
/**
|
|
1111
|
-
* Free-form metadata forwarded into the `x-cascade/stream.merged` emit.
|
|
1112
|
-
* The canonical binding is `{ task_ref: { resource_id, node_id } }` —
|
|
1113
|
-
* landing strategies thread `LandingContext.taskRef` through here so the
|
|
1114
|
-
* hub's cascade_merges projection records which task drove the merge.
|
|
1115
|
-
*/
|
|
1116
|
-
metadata?: import('git-cascade/events').EventMetadata;
|
|
1117
|
-
}): import('./types-v3.js').MergeResult {
|
|
1118
|
-
// git-cascade's MergeStreamOptions uses `sourceStream`/`targetStream` and
|
|
1119
|
-
// doesn't accept an opts.metadata field — the tagging is our concern, not
|
|
1120
|
-
// the tracker's. Carry `opts.metadata` through on the emitted event
|
|
1121
|
-
// instead, which is what the hub's cascade_merges projection reads.
|
|
1122
|
-
const result = this.adapter.mergeStream({
|
|
1123
|
-
sourceStream: opts.sourceStreamId,
|
|
1124
|
-
targetStream: opts.targetStreamId,
|
|
1125
|
-
agentId: opts.agentId,
|
|
1126
|
-
worktree: opts.worktree,
|
|
1127
|
-
});
|
|
1128
|
-
if (result.success) {
|
|
1129
|
-
this.emit('stream:merged', {
|
|
1130
|
-
sourceStreamId: opts.sourceStreamId,
|
|
1131
|
-
targetStreamId: opts.targetStreamId,
|
|
1132
|
-
mergeCommit: result.newHead,
|
|
1133
|
-
...(opts.metadata ? { metadata: opts.metadata } : {}),
|
|
1134
|
-
});
|
|
1135
|
-
} else {
|
|
1136
|
-
this.emit('stream:conflicted', {
|
|
1137
|
-
streamId: opts.sourceStreamId,
|
|
1138
|
-
conflicts: result.conflicts,
|
|
1139
|
-
error: result.error,
|
|
1140
|
-
});
|
|
1141
|
-
}
|
|
1142
|
-
return result;
|
|
1143
|
-
}
|
|
1144
|
-
|
|
1145
|
-
syncWithParent(opts: {
|
|
1146
|
-
streamId: StreamId;
|
|
1147
|
-
agentId: import('./types-v3.js').Principal;
|
|
1148
|
-
worktree: string;
|
|
1149
|
-
onConflict?: import('./types-v3.js').ConflictStrategy;
|
|
1150
|
-
}): import('./types-v3.js').RebaseResult {
|
|
1151
|
-
return this.adapter.syncWithParent(
|
|
1152
|
-
opts.streamId,
|
|
1153
|
-
opts.agentId,
|
|
1154
|
-
opts.worktree,
|
|
1155
|
-
opts.onConflict
|
|
1156
|
-
);
|
|
1157
|
-
}
|
|
1158
|
-
|
|
1159
|
-
// abandonStream, pauseStream, resumeStream are inherited-by-name from the
|
|
1160
|
-
// adapter calls; expose thin wrappers that emit workspace-level events.
|
|
1161
|
-
|
|
1162
|
-
abandonStream(streamId: StreamId, opts?: { cascade?: boolean; reason?: string }): void {
|
|
1163
|
-
this.adapter.abandonStream(streamId, opts);
|
|
1164
|
-
this.emit('stream:abandoned', { streamId, ...opts });
|
|
1165
|
-
}
|
|
1166
|
-
|
|
1167
|
-
pauseStream(streamId: StreamId, reason?: string): void {
|
|
1168
|
-
this.adapter.pauseStream(streamId, reason);
|
|
1169
|
-
this.emit('stream:paused', { streamId, reason });
|
|
1170
|
-
}
|
|
1171
|
-
|
|
1172
|
-
resumeStream(streamId: StreamId): void {
|
|
1173
|
-
this.adapter.resumeStream(streamId);
|
|
1174
|
-
this.emit('stream:resumed', { streamId });
|
|
1175
|
-
}
|
|
1176
|
-
|
|
1177
|
-
listStreams(filter?: {
|
|
1178
|
-
ownerId?: import('./types-v3.js').Principal;
|
|
1179
|
-
status?: import('./types-v3.js').Stream['status'];
|
|
1180
|
-
}): import('./types-v3.js').Stream[] {
|
|
1181
|
-
return this.adapter.listStreams({
|
|
1182
|
-
agentId: filter?.ownerId,
|
|
1183
|
-
status: filter?.status,
|
|
1184
|
-
});
|
|
1185
|
-
}
|
|
1186
|
-
|
|
1187
|
-
commitChanges(opts: {
|
|
1188
|
-
agentId: import('./types-v3.js').Principal;
|
|
1189
|
-
streamId: StreamId;
|
|
1190
|
-
worktree: string;
|
|
1191
|
-
message: string;
|
|
1192
|
-
}): { commit: string; changeId: import('./types-v3.js').ChangeId } {
|
|
1193
|
-
const result = this.adapter.commitChanges(opts);
|
|
1194
|
-
this.emit('stream:committed', {
|
|
1195
|
-
streamId: opts.streamId,
|
|
1196
|
-
commit: result.commit,
|
|
1197
|
-
changeId: result.changeId,
|
|
1198
|
-
agentId: opts.agentId,
|
|
1199
|
-
});
|
|
1200
|
-
return result;
|
|
1201
|
-
}
|
|
1202
|
-
|
|
1203
|
-
markChangesMerged(changeIds: import('./types-v3.js').ChangeId[]): void {
|
|
1204
|
-
this.adapter.markChangesMerged(changeIds);
|
|
1205
|
-
for (const id of changeIds) {
|
|
1206
|
-
this.emit('change:merged', { changeId: id });
|
|
1207
|
-
}
|
|
1208
|
-
}
|
|
1209
|
-
|
|
1210
|
-
getChange(changeId: import('./types-v3.js').ChangeId): import('./types-v3.js').Change | null {
|
|
1211
|
-
return this.adapter.getChange(changeId);
|
|
1212
|
-
}
|
|
1213
|
-
|
|
1214
|
-
getChangeByCommit(commit: string): import('./types-v3.js').Change | null {
|
|
1215
|
-
return this.adapter.getChangeByCommit(commit);
|
|
1216
|
-
}
|
|
1217
|
-
|
|
1218
|
-
allocateWorktree(
|
|
1219
|
-
opts: import('./types-v3.js').AllocateWorktreeOpts
|
|
1220
|
-
): import('./types-v3.js').Worktree {
|
|
1221
|
-
// Ref-counted sharing: if sharedWithAgent is set, reuse that agent's worktree
|
|
1222
|
-
if (opts.sharedWithAgent) {
|
|
1223
|
-
const owner = this.adapter.getWorktree(opts.sharedWithAgent);
|
|
1224
|
-
if (!owner) {
|
|
1225
|
-
throw new Error(
|
|
1226
|
-
`Cannot share worktree: agent ${opts.sharedWithAgent} has no allocated worktree`
|
|
1227
|
-
);
|
|
1228
|
-
}
|
|
1229
|
-
let entry = this.sharedWorktreeRefs.get(owner.path);
|
|
1230
|
-
if (!entry) {
|
|
1231
|
-
entry = {
|
|
1232
|
-
ownerId: opts.sharedWithAgent,
|
|
1233
|
-
sharers: new Set<AgentId>(),
|
|
1234
|
-
ownerDeparted: false,
|
|
1235
|
-
};
|
|
1236
|
-
this.sharedWorktreeRefs.set(owner.path, entry);
|
|
1237
|
-
}
|
|
1238
|
-
if (entry.ownerDeparted && entry.sharers.size === 0) {
|
|
1239
|
-
// Edge case: owner already left and all sharers left, but someone
|
|
1240
|
-
// is still trying to share. Reject — the teardown has been staged
|
|
1241
|
-
// but this would resurrect a dead reference.
|
|
1242
|
-
throw new Error(
|
|
1243
|
-
`Cannot share worktree at ${owner.path}: owner has departed and no active sharers`
|
|
1244
|
-
);
|
|
1245
|
-
}
|
|
1246
|
-
entry.sharers.add(opts.agentId);
|
|
1247
|
-
this.emit('worktree:shared', {
|
|
1248
|
-
path: owner.path,
|
|
1249
|
-
ownerAgentId: opts.sharedWithAgent,
|
|
1250
|
-
sharingAgentId: opts.agentId,
|
|
1251
|
-
});
|
|
1252
|
-
return owner;
|
|
1253
|
-
}
|
|
1254
|
-
|
|
1255
|
-
// Fresh worktree
|
|
1256
|
-
const baseDir = opts.baseDir ?? this.config.worktreeBaseDir;
|
|
1257
|
-
const sanitizedId = opts.agentId.replace(/[^a-zA-Z0-9_-]/g, '_');
|
|
1258
|
-
const path = `${baseDir}/${sanitizedId}`;
|
|
1259
|
-
|
|
1260
|
-
const worktreeArgs: import('git-cascade').CreateWorktreeOptions = {
|
|
1261
|
-
agentId: opts.agentId,
|
|
1262
|
-
path,
|
|
1263
|
-
};
|
|
1264
|
-
if (opts.streamId) {
|
|
1265
|
-
worktreeArgs.branch = opts.branch ?? this.adapter.getStreamBranchName(opts.streamId);
|
|
1266
|
-
} else if (opts.branch) {
|
|
1267
|
-
worktreeArgs.branch = opts.branch;
|
|
1268
|
-
}
|
|
1269
|
-
|
|
1270
|
-
const worktree = this.adapter.createWorktree(worktreeArgs);
|
|
1271
|
-
|
|
1272
|
-
if (opts.streamId) {
|
|
1273
|
-
this.agentToStream.set(opts.agentId, opts.streamId);
|
|
1274
|
-
}
|
|
1275
|
-
|
|
1276
|
-
// Track in workspaces map so legacy deallocateWorkspace can find this
|
|
1277
|
-
// V3-allocated worktree. Use role='v3' to bypass the legacy
|
|
1278
|
-
// worker/integrator coordinator-map cleanup path.
|
|
1279
|
-
this.workspaces.set(opts.agentId as AgentId, {
|
|
1280
|
-
agentId: opts.agentId as AgentId,
|
|
1281
|
-
path: worktree.path,
|
|
1282
|
-
branch: worktree.currentStream
|
|
1283
|
-
? `stream/${worktree.currentStream}`
|
|
1284
|
-
: (opts.branch ?? 'unknown'),
|
|
1285
|
-
streamId: opts.streamId ?? '',
|
|
1286
|
-
role: 'v3',
|
|
1287
|
-
createdAt: worktree.createdAt,
|
|
1288
|
-
});
|
|
1289
|
-
|
|
1290
|
-
this.emit('worktree:allocated', {
|
|
1291
|
-
agentId: opts.agentId,
|
|
1292
|
-
path: worktree.path,
|
|
1293
|
-
streamId: opts.streamId,
|
|
1294
|
-
});
|
|
1295
|
-
return worktree;
|
|
1296
|
-
}
|
|
1297
|
-
|
|
1298
|
-
getWorktreeForAgent(
|
|
1299
|
-
agentId: import('./types-v3.js').Principal
|
|
1300
|
-
): import('./types-v3.js').Worktree | null {
|
|
1301
|
-
return this.adapter.getWorktree(agentId);
|
|
1302
|
-
}
|
|
1303
|
-
|
|
1304
|
-
registerLandingStrategy(strategy: import('./types-v3.js').LandingStrategy): void {
|
|
1305
|
-
this.landingStrategies.set(strategy.name, strategy);
|
|
1306
|
-
}
|
|
1307
|
-
|
|
1308
|
-
async land(
|
|
1309
|
-
ctx: import('./types-v3.js').LandingContext,
|
|
1310
|
-
): Promise<import('./types-v3.js').MergeResult> {
|
|
1311
|
-
const internalName = resolveLandingStrategyName(ctx.strategyName);
|
|
1312
|
-
if (internalName === 'none') {
|
|
1313
|
-
return { success: true, alreadyMerged: true } as import('./types-v3.js').MergeResult;
|
|
1314
|
-
}
|
|
1315
|
-
const strategy = this.landingStrategies.get(internalName);
|
|
1316
|
-
if (!strategy) {
|
|
1317
|
-
throw new Error(
|
|
1318
|
-
`No landing strategy registered for "${internalName}" (from ctx.strategyName="${ctx.strategyName ?? 'merge-to-parent'}"). Registered: ${Array.from(this.landingStrategies.keys()).join(', ') || '<none>'}.`,
|
|
1319
|
-
);
|
|
1320
|
-
}
|
|
1321
|
-
const resolved: import('./types-v3.js').LandingContext = {
|
|
1322
|
-
...ctx,
|
|
1323
|
-
workspaceManager: this,
|
|
1324
|
-
};
|
|
1325
|
-
if (strategy.canLand && !strategy.canLand(resolved)) {
|
|
1326
|
-
throw new Error(
|
|
1327
|
-
`Landing strategy "${internalName}" rejected context for agent ${ctx.agentId}, stream ${ctx.streamId}`,
|
|
1328
|
-
);
|
|
1329
|
-
}
|
|
1330
|
-
return strategy.land(resolved);
|
|
1331
|
-
}
|
|
1332
|
-
|
|
1333
|
-
reconcileV3(): import('./types-v3.js').MacroReconcileResult {
|
|
1334
|
-
const result: import('./types-v3.js').MacroReconcileResult = {
|
|
1335
|
-
streamsChecked: 0,
|
|
1336
|
-
streamsFixed: 0,
|
|
1337
|
-
worktreesOrphaned: 0,
|
|
1338
|
-
worktreesCleaned: 0,
|
|
1339
|
-
poolEntriesPurged: 0,
|
|
1340
|
-
errors: [],
|
|
1341
|
-
};
|
|
1342
|
-
|
|
1343
|
-
// Delegate stream↔git sync to git-cascade
|
|
1344
|
-
try {
|
|
1345
|
-
const gcResult = this.adapter.reconcile();
|
|
1346
|
-
result.streamsChecked = (gcResult.updated?.length ?? 0) +
|
|
1347
|
-
(gcResult.branchesCreated?.length ?? 0) +
|
|
1348
|
-
(gcResult.failed?.length ?? 0);
|
|
1349
|
-
result.streamsFixed = (gcResult.updated?.length ?? 0) +
|
|
1350
|
-
(gcResult.branchesCreated?.length ?? 0);
|
|
1351
|
-
for (const f of gcResult.failed ?? []) {
|
|
1352
|
-
result.errors.push({
|
|
1353
|
-
context: `stream ${f.streamId}`,
|
|
1354
|
-
message: f.error,
|
|
1355
|
-
});
|
|
1356
|
-
}
|
|
1357
|
-
} catch (err) {
|
|
1358
|
-
result.errors.push({
|
|
1359
|
-
context: 'git-cascade reconcile',
|
|
1360
|
-
message: err instanceof Error ? err.message : String(err),
|
|
1361
|
-
});
|
|
1362
|
-
}
|
|
1363
|
-
|
|
1364
|
-
// Worktree pool and orphan cleanup deferred to Phase 3 (when TopologyPolicy
|
|
1365
|
-
// owns worktree lifecycle). For now, just count what git-cascade knows about.
|
|
1366
|
-
try {
|
|
1367
|
-
const worktrees = this.adapter.listWorktrees();
|
|
1368
|
-
// An "orphan" is a worktree without a corresponding record in our tracking
|
|
1369
|
-
// map. Count only; don't delete here — that's reserved for Phase 3.
|
|
1370
|
-
for (const wt of worktrees) {
|
|
1371
|
-
if (!this.workspaces.has(wt.agentId) && !this.agentToStream.has(wt.agentId)) {
|
|
1372
|
-
result.worktreesOrphaned++;
|
|
1373
|
-
}
|
|
1374
|
-
}
|
|
1375
|
-
} catch (err) {
|
|
1376
|
-
result.errors.push({
|
|
1377
|
-
context: 'worktree orphan scan',
|
|
1378
|
-
message: err instanceof Error ? err.message : String(err),
|
|
1379
|
-
});
|
|
1380
|
-
}
|
|
1381
|
-
|
|
1382
|
-
return result;
|
|
1383
|
-
}
|
|
1384
|
-
|
|
1385
|
-
resolveConflict(opts: {
|
|
1386
|
-
conflictId: string;
|
|
1387
|
-
resolvedBy: import('./types-v3.js').Principal;
|
|
1388
|
-
resolutionCommit?: string;
|
|
1389
|
-
/**
|
|
1390
|
-
* How the conflict was resolved. Defaults to 'agent' for the legacy
|
|
1391
|
-
* call shape; recovery strategies should pass an explicit method so
|
|
1392
|
-
* the OpenHive hub records the right resolution.
|
|
1393
|
-
*/
|
|
1394
|
-
method?: import('git-cascade').ConflictResolution['method'] | 'auto-resolve' | 'spawn-resolver' | 'abandoned';
|
|
1395
|
-
/** Human-readable resolution summary (e.g., 'merged with -X ours'). */
|
|
1396
|
-
summary?: string;
|
|
1397
|
-
}): void {
|
|
1398
|
-
const conflict = this.adapter.getConflict(opts.conflictId);
|
|
1399
|
-
const method = opts.method ?? 'agent';
|
|
1400
|
-
|
|
1401
|
-
// Drive git-cascade's resolveConflict so the underlying conflict record
|
|
1402
|
-
// moves to status='resolved' AND the tracker emits stream.conflict_resolved.
|
|
1403
|
-
// Hub observers (cascade-bridge → OpenHive) update cascade_conflicts.status
|
|
1404
|
-
// accordingly. Falls back gracefully if cascade is older than 0.0.6.
|
|
1405
|
-
const trackerHasResolve = typeof (
|
|
1406
|
-
this.adapter as { resolveConflict?: unknown }
|
|
1407
|
-
).resolveConflict === 'function';
|
|
1408
|
-
if (trackerHasResolve) {
|
|
1409
|
-
try {
|
|
1410
|
-
(
|
|
1411
|
-
this.adapter as unknown as {
|
|
1412
|
-
resolveConflict(args: {
|
|
1413
|
-
conflictId: string;
|
|
1414
|
-
resolution: import('git-cascade').ConflictResolution & { summary?: string };
|
|
1415
|
-
metadata?: Record<string, unknown>;
|
|
1416
|
-
}): void;
|
|
1417
|
-
}
|
|
1418
|
-
).resolveConflict({
|
|
1419
|
-
conflictId: opts.conflictId,
|
|
1420
|
-
resolution: {
|
|
1421
|
-
method:
|
|
1422
|
-
method === 'auto-resolve' ||
|
|
1423
|
-
method === 'spawn-resolver' ||
|
|
1424
|
-
method === 'abandoned'
|
|
1425
|
-
? 'agent'
|
|
1426
|
-
: method,
|
|
1427
|
-
resolvedBy: opts.resolvedBy,
|
|
1428
|
-
details: opts.summary,
|
|
1429
|
-
},
|
|
1430
|
-
metadata: {
|
|
1431
|
-
resolution_method_actual: method,
|
|
1432
|
-
resolution_commit: opts.resolutionCommit,
|
|
1433
|
-
},
|
|
1434
|
-
});
|
|
1435
|
-
} catch {
|
|
1436
|
-
// Best-effort; legacy resume path below remains.
|
|
1437
|
-
}
|
|
1438
|
-
}
|
|
1439
|
-
|
|
1440
|
-
if (conflict?.streamId) {
|
|
1441
|
-
try {
|
|
1442
|
-
this.adapter.resumeStream(conflict.streamId);
|
|
1443
|
-
} catch {
|
|
1444
|
-
// Stream may not be paused; safe to ignore.
|
|
1445
|
-
}
|
|
1446
|
-
}
|
|
1447
|
-
|
|
1448
|
-
this.emit('conflict:resolved', {
|
|
1449
|
-
conflictId: opts.conflictId,
|
|
1450
|
-
resolvedBy: opts.resolvedBy,
|
|
1451
|
-
resolutionCommit: opts.resolutionCommit,
|
|
1452
|
-
streamId: conflict?.streamId,
|
|
1453
|
-
});
|
|
1454
|
-
}
|
|
1455
|
-
|
|
1456
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
1457
|
-
// Lifecycle
|
|
1458
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
1459
|
-
|
|
1460
|
-
/**
|
|
1461
|
-
* Close the workspace manager and release resources.
|
|
1462
|
-
*/
|
|
1463
|
-
close(): void {
|
|
1464
|
-
this.eventListeners.clear();
|
|
1465
|
-
this.workspaces.clear();
|
|
1466
|
-
this.agentToStream.clear();
|
|
1467
|
-
// Close merge queue if it was initialized
|
|
1468
|
-
if (this.mergeQueue) {
|
|
1469
|
-
this.mergeQueue.close();
|
|
1470
|
-
this.mergeQueue = null;
|
|
1471
|
-
}
|
|
1472
|
-
// Close pool if it was initialized
|
|
1473
|
-
if (this.pool) {
|
|
1474
|
-
this.pool.close().catch((error: unknown) => {
|
|
1475
|
-
console.error('[WorkspaceManager] Error closing pool:', error);
|
|
1476
|
-
});
|
|
1477
|
-
this.pool = null;
|
|
1478
|
-
}
|
|
1479
|
-
// Note: We don't close the adapter here since it may be shared
|
|
1480
|
-
}
|
|
1481
|
-
|
|
1482
|
-
/**
|
|
1483
|
-
* Close the workspace manager and release resources (async).
|
|
1484
|
-
*
|
|
1485
|
-
* Prefer this over close() when using the pool, as it properly
|
|
1486
|
-
* awaits pool cleanup.
|
|
1487
|
-
*/
|
|
1488
|
-
async closeAsync(): Promise<void> {
|
|
1489
|
-
this.eventListeners.clear();
|
|
1490
|
-
this.workspaces.clear();
|
|
1491
|
-
this.agentToStream.clear();
|
|
1492
|
-
// Close merge queue if it was initialized
|
|
1493
|
-
if (this.mergeQueue) {
|
|
1494
|
-
this.mergeQueue.close();
|
|
1495
|
-
this.mergeQueue = null;
|
|
1496
|
-
}
|
|
1497
|
-
// Close pool if it was initialized
|
|
1498
|
-
if (this.pool) {
|
|
1499
|
-
await this.pool.close();
|
|
1500
|
-
this.pool = null;
|
|
1501
|
-
}
|
|
1502
|
-
// Note: We don't close the adapter here since it may be shared
|
|
1503
|
-
}
|
|
1504
|
-
|
|
1505
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
1506
|
-
// Private Helpers
|
|
1507
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
1508
|
-
|
|
1509
|
-
/**
|
|
1510
|
-
* Build a worktree path for an agent.
|
|
1511
|
-
*
|
|
1512
|
-
* @param role - Agent role
|
|
1513
|
-
* @param agentId - Agent ID
|
|
1514
|
-
* @returns Worktree path
|
|
1515
|
-
*/
|
|
1516
|
-
private buildWorktreePath(
|
|
1517
|
-
role: 'worker' | 'integrator' | 'coordinator',
|
|
1518
|
-
agentId: AgentId
|
|
1519
|
-
): string {
|
|
1520
|
-
// Use agentId with a unique suffix to avoid collisions
|
|
1521
|
-
// The full agentId ensures uniqueness even when many workers have similar names
|
|
1522
|
-
// We sanitize the path to remove characters that might cause issues
|
|
1523
|
-
const sanitizedId = agentId.replace(/[^a-zA-Z0-9_-]/g, '_');
|
|
1524
|
-
return `${this.config.worktreeBaseDir}/${role}-${sanitizedId}`;
|
|
1525
|
-
}
|
|
1526
|
-
}
|
|
1527
|
-
|
|
1528
|
-
/**
|
|
1529
|
-
* Create a WorkspaceManager instance.
|
|
1530
|
-
*
|
|
1531
|
-
* @param config - Configuration options
|
|
1532
|
-
* @returns WorkspaceManager instance
|
|
1533
|
-
*/
|
|
1534
|
-
export function createWorkspaceManager(
|
|
1535
|
-
config: WorkspaceManagerConfig
|
|
1536
|
-
): DefaultWorkspaceManager {
|
|
1537
|
-
const adapter = new GitCascadeAdapter(config);
|
|
1538
|
-
return new DefaultWorkspaceManager(adapter, config);
|
|
1539
|
-
}
|
|
1540
|
-
|
|
1541
|
-
/**
|
|
1542
|
-
* Create a WorkspaceManager with an existing GitCascadeAdapter.
|
|
1543
|
-
*
|
|
1544
|
-
* @param adapter - GitCascadeAdapter instance
|
|
1545
|
-
* @param config - Configuration options
|
|
1546
|
-
* @returns WorkspaceManager instance
|
|
1547
|
-
*/
|
|
1548
|
-
export function createWorkspaceManagerWithAdapter(
|
|
1549
|
-
adapter: GitCascadeAdapter,
|
|
1550
|
-
config?: Partial<WorkspaceManagerConfig>
|
|
1551
|
-
): DefaultWorkspaceManager {
|
|
1552
|
-
return new DefaultWorkspaceManager(adapter, config);
|
|
1553
|
-
}
|
|
1554
|
-
|
|
1555
|
-
// ═════════════════════════════════════════════════════════════════════════════
|
|
1556
|
-
// Landing strategy name resolution
|
|
1557
|
-
// ═════════════════════════════════════════════════════════════════════════════
|
|
1558
|
-
//
|
|
1559
|
-
// YAML uses snake_case (`merge_to_parent_stream`, `queue_to_branch`, …) to
|
|
1560
|
-
// match the team-config naming convention. Strategy classes expose
|
|
1561
|
-
// kebab-case internal names (`merge-to-parent`, …). `WorkspaceManager.land()`
|
|
1562
|
-
// accepts either and normalizes before dispatch so AgentManagerV2 can pass
|
|
1563
|
-
// `roleConfig.landing` directly without another translation layer.
|
|
1564
|
-
|
|
1565
|
-
const YAML_TO_INTERNAL_LANDING: Record<string, string> = {
|
|
1566
|
-
merge_to_parent_stream: 'merge-to-parent',
|
|
1567
|
-
queue_to_branch: 'queue-to-branch',
|
|
1568
|
-
direct_push: 'direct-push',
|
|
1569
|
-
optimistic_push: 'optimistic-push',
|
|
1570
|
-
cherry_pick_stack: 'cherry-pick-stack',
|
|
1571
|
-
none: 'none',
|
|
1572
|
-
};
|
|
1573
|
-
|
|
1574
|
-
export function resolveLandingStrategyName(input?: string): string {
|
|
1575
|
-
if (!input) return 'merge-to-parent';
|
|
1576
|
-
return YAML_TO_INTERNAL_LANDING[input] ?? input;
|
|
1577
|
-
}
|