@cleocode/core 2026.3.74 → 2026.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/agents/agent-schema.d.ts.map +1 -1
- package/dist/agents/retry.js +26 -21
- package/dist/agents/retry.js.map +1 -1
- package/dist/cant/approval.d.ts +110 -0
- package/dist/cant/approval.d.ts.map +1 -0
- package/dist/cant/approval.js +185 -0
- package/dist/cant/approval.js.map +1 -0
- package/dist/cant/context-builder.d.ts +79 -0
- package/dist/cant/context-builder.d.ts.map +1 -0
- package/dist/cant/context-builder.js +117 -0
- package/dist/cant/context-builder.js.map +1 -0
- package/dist/cant/discretion.d.ts +95 -0
- package/dist/cant/discretion.d.ts.map +1 -0
- package/dist/cant/discretion.js +116 -0
- package/dist/cant/discretion.js.map +1 -0
- package/dist/cant/index.d.ts +25 -0
- package/dist/cant/index.d.ts.map +1 -0
- package/dist/cant/index.js +23 -0
- package/dist/cant/index.js.map +1 -0
- package/dist/cant/parallel-runner.d.ts +38 -0
- package/dist/cant/parallel-runner.d.ts.map +1 -0
- package/dist/cant/parallel-runner.js +173 -0
- package/dist/cant/parallel-runner.js.map +1 -0
- package/dist/cant/types.d.ts +127 -0
- package/dist/cant/types.d.ts.map +1 -0
- package/dist/cant/types.js +11 -0
- package/dist/cant/types.js.map +1 -0
- package/dist/cant/workflow-executor.d.ts +105 -0
- package/dist/cant/workflow-executor.d.ts.map +1 -0
- package/dist/cant/workflow-executor.js +440 -0
- package/dist/cant/workflow-executor.js.map +1 -0
- package/dist/cleo.js +21 -1
- package/dist/cleo.js.map +1 -1
- package/dist/code/index.d.ts +10 -0
- package/dist/code/index.d.ts.map +1 -0
- package/dist/code/outline.d.ts +51 -0
- package/dist/code/outline.d.ts.map +1 -0
- package/dist/code/parser.d.ts +30 -0
- package/dist/code/parser.d.ts.map +1 -0
- package/dist/code/search.d.ts +42 -0
- package/dist/code/search.d.ts.map +1 -0
- package/dist/code/unfold.d.ts +44 -0
- package/dist/code/unfold.d.ts.map +1 -0
- package/dist/conduit/conduit-client.d.ts +35 -0
- package/dist/conduit/conduit-client.d.ts.map +1 -0
- package/dist/conduit/conduit-client.js +94 -0
- package/dist/conduit/conduit-client.js.map +1 -0
- package/dist/conduit/factory.d.ts +15 -0
- package/dist/conduit/factory.d.ts.map +1 -0
- package/dist/conduit/factory.js +35 -0
- package/dist/conduit/factory.js.map +1 -0
- package/dist/conduit/http-transport.d.ts +44 -0
- package/dist/conduit/http-transport.d.ts.map +1 -0
- package/dist/conduit/http-transport.js +165 -0
- package/dist/conduit/http-transport.js.map +1 -0
- package/dist/conduit/index.d.ts +15 -0
- package/dist/conduit/index.d.ts.map +1 -0
- package/dist/conduit/index.js +12 -0
- package/dist/conduit/index.js.map +1 -0
- package/dist/conduit/local-transport.d.ts +91 -0
- package/dist/conduit/local-transport.d.ts.map +1 -0
- package/dist/conduit/sse-transport.d.ts +68 -0
- package/dist/conduit/sse-transport.d.ts.map +1 -0
- package/dist/config.js +4 -3
- package/dist/config.js.map +1 -1
- package/dist/crypto/credentials.d.ts +40 -0
- package/dist/crypto/credentials.d.ts.map +1 -0
- package/dist/crypto/credentials.js +144 -0
- package/dist/crypto/credentials.js.map +1 -0
- package/dist/engine-result.d.ts +1 -1
- package/dist/engine-result.d.ts.map +1 -1
- package/dist/error-catalog.d.ts +1 -1
- package/dist/error-catalog.d.ts.map +1 -1
- package/dist/error-registry.d.ts +1 -1
- package/dist/error-registry.d.ts.map +1 -1
- package/dist/errors.d.ts +1 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/hooks/handlers/agent-hooks.d.ts.map +1 -1
- package/dist/hooks/handlers/agent-hooks.js +106 -0
- package/dist/hooks/handlers/agent-hooks.js.map +1 -0
- package/dist/hooks/handlers/context-hooks.d.ts.map +1 -1
- package/dist/hooks/handlers/context-hooks.js +111 -0
- package/dist/hooks/handlers/context-hooks.js.map +1 -0
- package/dist/hooks/handlers/error-hooks.d.ts +14 -5
- package/dist/hooks/handlers/error-hooks.d.ts.map +1 -1
- package/dist/hooks/handlers/error-hooks.js +15 -6
- package/dist/hooks/handlers/error-hooks.js.map +1 -1
- package/dist/hooks/handlers/file-hooks.d.ts.map +1 -1
- package/dist/hooks/handlers/file-hooks.js +35 -11
- package/dist/hooks/handlers/file-hooks.js.map +1 -1
- package/dist/hooks/handlers/handler-helpers.d.ts +41 -0
- package/dist/hooks/handlers/handler-helpers.d.ts.map +1 -0
- package/dist/hooks/handlers/handler-helpers.js +61 -0
- package/dist/hooks/handlers/handler-helpers.js.map +1 -0
- package/dist/hooks/handlers/index.js +10 -1
- package/dist/hooks/handlers/index.js.map +1 -1
- package/dist/hooks/handlers/mcp-hooks.d.ts.map +1 -1
- package/dist/hooks/handlers/mcp-hooks.js +88 -21
- package/dist/hooks/handlers/mcp-hooks.js.map +1 -1
- package/dist/hooks/handlers/session-hooks.d.ts.map +1 -1
- package/dist/hooks/handlers/session-hooks.js +5 -10
- package/dist/hooks/handlers/session-hooks.js.map +1 -1
- package/dist/hooks/handlers/task-hooks.d.ts.map +1 -1
- package/dist/hooks/handlers/task-hooks.js +5 -10
- package/dist/hooks/handlers/task-hooks.js.map +1 -1
- package/dist/hooks/handlers/work-capture-hooks.d.ts.map +1 -1
- package/dist/hooks/handlers/work-capture-hooks.js +165 -0
- package/dist/hooks/handlers/work-capture-hooks.js.map +1 -0
- package/dist/hooks/payload-schemas.js +83 -26
- package/dist/hooks/payload-schemas.js.map +1 -1
- package/dist/hooks/provider-hooks.js +37 -5
- package/dist/hooks/provider-hooks.js.map +1 -1
- package/dist/hooks/registry.js +76 -23
- package/dist/hooks/registry.js.map +1 -1
- package/dist/hooks/types.js +17 -13
- package/dist/hooks/types.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6452 -3371
- package/dist/index.js.map +4 -4
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +12 -0
- package/dist/init.js.map +1 -1
- package/dist/internal.d.ts +11 -1
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +10 -0
- package/dist/internal.js.map +1 -1
- package/dist/lib/index.d.ts +1 -0
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/tree-sitter-languages.d.ts +29 -0
- package/dist/lib/tree-sitter-languages.d.ts.map +1 -0
- package/dist/memory/brain-links.d.ts.map +1 -1
- package/dist/memory/brain-maintenance.d.ts +13 -0
- package/dist/memory/brain-maintenance.d.ts.map +1 -1
- package/dist/memory/brain-retrieval.d.ts +3 -0
- package/dist/memory/brain-retrieval.d.ts.map +1 -1
- package/dist/memory/brain-retrieval.js +5 -0
- package/dist/memory/brain-retrieval.js.map +1 -1
- package/dist/memory/decisions.d.ts.map +1 -1
- package/dist/mvi-helpers.d.ts +52 -0
- package/dist/mvi-helpers.d.ts.map +1 -0
- package/dist/mvi-helpers.js +74 -0
- package/dist/mvi-helpers.js.map +1 -0
- package/dist/nexus/index.js +2 -0
- package/dist/nexus/index.js.map +1 -1
- package/dist/nexus/workspace.d.ts.map +1 -1
- package/dist/nexus/workspace.js +355 -0
- package/dist/nexus/workspace.js.map +1 -0
- package/dist/orchestration/hierarchy.d.ts +32 -0
- package/dist/orchestration/hierarchy.d.ts.map +1 -0
- package/dist/orchestration/index.d.ts +1 -0
- package/dist/orchestration/index.d.ts.map +1 -1
- package/dist/output.d.ts +2 -2
- package/dist/output.d.ts.map +1 -1
- package/dist/output.js +40 -8
- package/dist/output.js.map +1 -1
- package/dist/pagination.d.ts +1 -1
- package/dist/pagination.d.ts.map +1 -1
- package/dist/sessions/find.d.ts +3 -0
- package/dist/sessions/find.d.ts.map +1 -1
- package/dist/sessions/find.js +3 -1
- package/dist/sessions/find.js.map +1 -1
- package/dist/sessions/index.d.ts.map +1 -1
- package/dist/sessions/index.js +11 -4
- package/dist/sessions/index.js.map +1 -1
- package/dist/sessions/snapshot.js +213 -0
- package/dist/sessions/snapshot.js.map +1 -0
- package/dist/store/agent-registry-accessor.d.ts +31 -0
- package/dist/store/agent-registry-accessor.d.ts.map +1 -0
- package/dist/store/agent-registry-accessor.js +169 -0
- package/dist/store/agent-registry-accessor.js.map +1 -0
- package/dist/store/converters.d.ts.map +1 -1
- package/dist/store/converters.js +2 -0
- package/dist/store/converters.js.map +1 -1
- package/dist/store/cross-db-cleanup.d.ts +34 -0
- package/dist/store/cross-db-cleanup.d.ts.map +1 -1
- package/dist/store/db-helpers.d.ts.map +1 -1
- package/dist/store/db-helpers.js +1 -0
- package/dist/store/db-helpers.js.map +1 -1
- package/dist/store/json.js +2 -2
- package/dist/store/safety-data-accessor.d.ts +7 -0
- package/dist/store/safety-data-accessor.d.ts.map +1 -1
- package/dist/store/safety-data-accessor.js +14 -0
- package/dist/store/safety-data-accessor.js.map +1 -1
- package/dist/store/signaldock-sqlite.d.ts +48 -0
- package/dist/store/signaldock-sqlite.d.ts.map +1 -0
- package/dist/store/signaldock-sqlite.js +178 -0
- package/dist/store/signaldock-sqlite.js.map +1 -0
- package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
- package/dist/store/sqlite-data-accessor.js +50 -0
- package/dist/store/sqlite-data-accessor.js.map +1 -1
- package/dist/store/sqlite.d.ts.map +1 -1
- package/dist/store/sqlite.js +30 -1
- package/dist/store/sqlite.js.map +1 -1
- package/dist/store/task-store.d.ts.map +1 -1
- package/dist/store/task-store.js +2 -0
- package/dist/store/task-store.js.map +1 -1
- package/dist/store/tasks-schema.d.ts +16 -0
- package/dist/store/tasks-schema.d.ts.map +1 -1
- package/dist/store/tasks-schema.js +33 -0
- package/dist/store/tasks-schema.js.map +1 -1
- package/dist/store/validation-schemas.d.ts +32 -0
- package/dist/store/validation-schemas.d.ts.map +1 -1
- package/dist/system/health.d.ts +1 -1
- package/dist/system/health.d.ts.map +1 -1
- package/dist/system/health.js +35 -0
- package/dist/system/health.js.map +1 -1
- package/dist/task-work/index.d.ts.map +1 -1
- package/dist/task-work/index.js +8 -4
- package/dist/task-work/index.js.map +1 -1
- package/dist/tasks/complete.js +5 -2
- package/dist/tasks/complete.js.map +1 -1
- package/dist/tasks/find.d.ts +3 -0
- package/dist/tasks/find.d.ts.map +1 -1
- package/dist/tasks/find.js +7 -1
- package/dist/tasks/find.js.map +1 -1
- package/dist/tasks/list.d.ts +5 -2
- package/dist/tasks/list.d.ts.map +1 -1
- package/dist/tasks/list.js +9 -2
- package/dist/tasks/list.js.map +1 -1
- package/dist/tasks/show.d.ts +3 -0
- package/dist/tasks/show.d.ts.map +1 -1
- package/dist/tasks/show.js +2 -0
- package/dist/tasks/show.js.map +1 -1
- package/dist/upgrade.d.ts.map +1 -1
- package/dist/upgrade.js +15 -0
- package/dist/upgrade.js.map +1 -1
- package/migrations/drizzle-tasks/20260324000000_assignee-column/migration.sql +6 -0
- package/migrations/drizzle-tasks/20260324000000_assignee-column/snapshot.json +9 -0
- package/migrations/drizzle-tasks/20260327000000_agent-credentials/migration.sql +23 -0
- package/package.json +17 -7
- package/src/__tests__/cli-parity.test.js +11 -1
- package/src/__tests__/cli-parity.test.js.map +1 -1
- package/src/__tests__/cli-parity.test.ts +17 -1
- package/src/__tests__/human-output.test.js +11 -1
- package/src/__tests__/human-output.test.js.map +1 -1
- package/src/__tests__/human-output.test.ts +18 -1
- package/src/__tests__/injection-chain.test.js +3 -2
- package/src/__tests__/injection-chain.test.js.map +1 -1
- package/src/__tests__/injection-mvi-tiers.test.d.ts +2 -2
- package/src/__tests__/injection-mvi-tiers.test.js +15 -15
- package/src/__tests__/injection-mvi-tiers.test.js.map +1 -1
- package/src/__tests__/lafs-conformance.test.d.ts +1 -1
- package/src/__tests__/lafs-conformance.test.js +2 -2
- package/src/__tests__/sharing.test.js +19 -0
- package/src/__tests__/sharing.test.js.map +1 -1
- package/src/agents/__tests__/agent-registry.test.d.ts +12 -0
- package/src/agents/__tests__/agent-registry.test.d.ts.map +1 -0
- package/src/agents/__tests__/agent-registry.test.js +262 -0
- package/src/agents/__tests__/agent-registry.test.js.map +1 -0
- package/src/agents/__tests__/execution-learning.test.d.ts +14 -0
- package/src/agents/__tests__/execution-learning.test.d.ts.map +1 -0
- package/src/agents/__tests__/execution-learning.test.js +533 -0
- package/src/agents/__tests__/execution-learning.test.js.map +1 -0
- package/src/agents/__tests__/health-monitor.test.d.ts +10 -0
- package/src/agents/__tests__/health-monitor.test.d.ts.map +1 -0
- package/src/agents/__tests__/health-monitor.test.js +259 -0
- package/src/agents/__tests__/health-monitor.test.js.map +1 -0
- package/src/agents/__tests__/registry.test.js +27 -2
- package/src/agents/__tests__/registry.test.js.map +1 -1
- package/src/agents/agent-schema.ts +2 -5
- package/src/cant/__tests__/cant-agent-parse.test.ts +94 -0
- package/src/cant/approval.ts +218 -0
- package/src/cant/context-builder.ts +135 -0
- package/src/cant/discretion.ts +149 -0
- package/src/cant/index.ts +58 -0
- package/src/cant/parallel-runner.ts +205 -0
- package/src/cant/types.ts +158 -0
- package/src/cant/workflow-executor.ts +618 -0
- package/src/code/index.ts +10 -0
- package/src/code/outline.ts +214 -0
- package/src/code/parser.ts +299 -0
- package/src/code/search.ts +173 -0
- package/src/code/unfold.ts +204 -0
- package/src/conduit/__tests__/dual-api-e2e.test.ts +212 -0
- package/src/conduit/__tests__/local-credential-flow.test.ts +230 -0
- package/src/conduit/__tests__/local-transport.test.ts +320 -0
- package/src/conduit/__tests__/sse-transport.test.ts +344 -0
- package/src/conduit/conduit-client.ts +123 -0
- package/src/conduit/factory.ts +49 -0
- package/src/conduit/http-transport.ts +201 -0
- package/src/conduit/index.ts +15 -0
- package/src/conduit/local-transport.ts +309 -0
- package/src/conduit/sse-transport.ts +382 -0
- package/src/crypto/credentials.ts +166 -0
- package/src/engine-result.ts +1 -1
- package/src/error-catalog.ts +1 -1
- package/src/error-registry.ts +1 -1
- package/src/errors.ts +1 -1
- package/src/hooks/handlers/__tests__/hook-automation-e2e.test.d.ts +13 -0
- package/src/hooks/handlers/__tests__/hook-automation-e2e.test.d.ts.map +1 -0
- package/src/hooks/handlers/__tests__/hook-automation-e2e.test.js +501 -0
- package/src/hooks/handlers/__tests__/hook-automation-e2e.test.js.map +1 -0
- package/src/hooks/handlers/agent-hooks.ts +1 -30
- package/src/hooks/handlers/context-hooks.ts +1 -30
- package/src/hooks/handlers/error-hooks.ts +14 -5
- package/src/hooks/handlers/file-hooks.ts +1 -6
- package/src/hooks/handlers/handler-helpers.ts +62 -0
- package/src/hooks/handlers/mcp-hooks.ts +2 -14
- package/src/hooks/handlers/session-hooks.ts +1 -6
- package/src/hooks/handlers/task-hooks.ts +1 -6
- package/src/hooks/handlers/work-capture-hooks.ts +1 -10
- package/src/index.ts +12 -1
- package/src/init.ts +12 -0
- package/src/intelligence/__tests__/adaptive-validation.test.d.ts +11 -0
- package/src/intelligence/__tests__/adaptive-validation.test.d.ts.map +1 -0
- package/src/intelligence/__tests__/adaptive-validation.test.js +517 -0
- package/src/intelligence/__tests__/adaptive-validation.test.js.map +1 -0
- package/src/intelligence/__tests__/impact.test.d.ts +1 -0
- package/src/intelligence/__tests__/impact.test.d.ts.map +1 -1
- package/src/intelligence/__tests__/impact.test.js +132 -1
- package/src/intelligence/__tests__/impact.test.js.map +1 -1
- package/src/internal.ts +22 -0
- package/src/lib/__tests__/retry.test.d.ts +7 -0
- package/src/lib/__tests__/retry.test.d.ts.map +1 -0
- package/src/lib/__tests__/retry.test.js +225 -0
- package/src/lib/__tests__/retry.test.js.map +1 -0
- package/src/lib/index.ts +8 -0
- package/src/lib/tree-sitter-languages.ts +88 -0
- package/src/lifecycle/__tests__/chain-store.test.js +6 -0
- package/src/lifecycle/__tests__/chain-store.test.js.map +1 -1
- package/src/lifecycle/__tests__/tessera-engine.test.js +52 -0
- package/src/lifecycle/__tests__/tessera-engine.test.js.map +1 -1
- package/src/memory/__tests__/brain-automation.test.d.ts +11 -0
- package/src/memory/__tests__/brain-automation.test.d.ts.map +1 -0
- package/src/memory/__tests__/brain-automation.test.js +730 -0
- package/src/memory/__tests__/brain-automation.test.js.map +1 -0
- package/src/memory/__tests__/brain-links.test.ts +14 -0
- package/src/memory/__tests__/brain-retrieval.test.ts +10 -0
- package/src/memory/__tests__/session-memory.test.ts +17 -0
- package/src/memory/brain-links.ts +17 -0
- package/src/memory/brain-maintenance.ts +33 -1
- package/src/memory/brain-retrieval.ts +27 -2
- package/src/memory/decisions.ts +18 -2
- package/src/mvi-helpers.ts +81 -0
- package/src/nexus/workspace.ts +19 -7
- package/src/orchestration/hierarchy.ts +202 -0
- package/src/orchestration/index.ts +1 -0
- package/src/output.ts +43 -10
- package/src/pagination.ts +1 -1
- package/src/sessions/__tests__/session-edge-cases.test.js +20 -1
- package/src/sessions/__tests__/session-edge-cases.test.js.map +1 -1
- package/src/sessions/__tests__/session-find.test.js +1 -1
- package/src/sessions/__tests__/session-find.test.js.map +1 -1
- package/src/sessions/__tests__/session-find.test.ts +1 -1
- package/src/sessions/find.ts +6 -1
- package/src/sessions/index.ts +9 -0
- package/src/store/__tests__/migration-safety.test.js +3 -0
- package/src/store/__tests__/migration-safety.test.js.map +1 -1
- package/src/store/__tests__/session-store.test.js +128 -1
- package/src/store/__tests__/session-store.test.js.map +1 -1
- package/src/store/__tests__/task-store.test.js +18 -1
- package/src/store/__tests__/task-store.test.js.map +1 -1
- package/src/store/__tests__/test-db-helper.d.ts.map +1 -1
- package/src/store/__tests__/test-db-helper.js +12 -0
- package/src/store/__tests__/test-db-helper.js.map +1 -1
- package/src/store/agent-registry-accessor.ts +375 -0
- package/src/store/converters.ts +2 -0
- package/src/store/cross-db-cleanup.ts +175 -1
- package/src/store/db-helpers.ts +1 -0
- package/src/store/safety-data-accessor.ts +23 -0
- package/src/store/signaldock-sqlite.ts +429 -0
- package/src/store/sqlite-data-accessor.ts +72 -0
- package/src/store/sqlite.ts +4 -1
- package/src/store/task-store.ts +9 -1
- package/src/store/tasks-schema.ts +7 -0
- package/src/system/__tests__/health.test.ts +2 -2
- package/src/system/health.ts +54 -2
- package/src/task-work/index.ts +5 -0
- package/src/tasks/__tests__/add.test.js +19 -1
- package/src/tasks/__tests__/add.test.js.map +1 -1
- package/src/tasks/__tests__/assignee.test.d.ts +14 -0
- package/src/tasks/__tests__/assignee.test.d.ts.map +1 -0
- package/src/tasks/__tests__/assignee.test.js +125 -0
- package/src/tasks/__tests__/assignee.test.js.map +1 -0
- package/src/tasks/__tests__/assignee.test.ts +162 -0
- package/src/tasks/__tests__/complete-unblocks.test.js +13 -1
- package/src/tasks/__tests__/complete-unblocks.test.js.map +1 -1
- package/src/tasks/__tests__/complete.test.js +28 -7
- package/src/tasks/__tests__/complete.test.js.map +1 -1
- package/src/tasks/__tests__/epic-enforcement.test.d.ts +15 -0
- package/src/tasks/__tests__/epic-enforcement.test.d.ts.map +1 -0
- package/src/tasks/__tests__/epic-enforcement.test.js +669 -0
- package/src/tasks/__tests__/epic-enforcement.test.js.map +1 -0
- package/src/tasks/__tests__/hierarchy-policy.test.js +5 -0
- package/src/tasks/__tests__/hierarchy-policy.test.js.map +1 -1
- package/src/tasks/__tests__/minimal-test.test.d.ts +2 -0
- package/src/tasks/__tests__/minimal-test.test.d.ts.map +1 -0
- package/src/tasks/__tests__/minimal-test.test.js +25 -0
- package/src/tasks/__tests__/minimal-test.test.js.map +1 -0
- package/src/tasks/__tests__/pipeline-stage.test.d.ts +14 -0
- package/src/tasks/__tests__/pipeline-stage.test.d.ts.map +1 -0
- package/src/tasks/__tests__/pipeline-stage.test.js +277 -0
- package/src/tasks/__tests__/pipeline-stage.test.js.map +1 -0
- package/src/tasks/__tests__/update.test.js +43 -6
- package/src/tasks/__tests__/update.test.js.map +1 -1
- package/src/tasks/find.ts +11 -1
- package/src/tasks/list.ts +14 -3
- package/src/tasks/show.ts +6 -0
- package/src/upgrade.ts +16 -0
- package/dist/tasks/reparent.d.ts +0 -38
- package/dist/tasks/reparent.d.ts.map +0 -1
- package/dist/ui/injection-legacy.d.ts +0 -26
- package/dist/ui/injection-legacy.d.ts.map +0 -1
- package/dist/ui/injection-legacy.js +0 -42
- package/dist/ui/injection-legacy.js.map +0 -1
- package/src/signaldock/__tests__/claude-code-transport.test.d.ts +0 -7
- package/src/signaldock/__tests__/claude-code-transport.test.d.ts.map +0 -1
- package/src/signaldock/__tests__/claude-code-transport.test.js +0 -147
- package/src/signaldock/__tests__/claude-code-transport.test.js.map +0 -1
- package/src/signaldock/__tests__/claude-code-transport.test.ts +0 -180
- package/src/signaldock/__tests__/factory.test.d.ts +0 -7
- package/src/signaldock/__tests__/factory.test.d.ts.map +0 -1
- package/src/signaldock/__tests__/factory.test.js +0 -55
- package/src/signaldock/__tests__/factory.test.js.map +0 -1
- package/src/signaldock/__tests__/factory.test.ts +0 -61
- package/src/signaldock/__tests__/signaldock-transport.test.d.ts +0 -9
- package/src/signaldock/__tests__/signaldock-transport.test.d.ts.map +0 -1
- package/src/signaldock/__tests__/signaldock-transport.test.js +0 -321
- package/src/signaldock/__tests__/signaldock-transport.test.js.map +0 -1
- package/src/signaldock/__tests__/signaldock-transport.test.ts +0 -421
- package/src/signaldock/claude-code-transport.ts +0 -137
- package/src/signaldock/factory.ts +0 -39
- package/src/signaldock/index.ts +0 -28
- package/src/signaldock/signaldock-transport.ts +0 -194
- package/src/signaldock/transport.ts +0 -78
- package/src/signaldock/types.ts +0 -100
|
@@ -0,0 +1,618 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CANT workflow executor — orchestrates workflow statement execution.
|
|
3
|
+
*
|
|
4
|
+
* Walks the statement list of a `WorkflowDef` AST node, dispatching to
|
|
5
|
+
* appropriate handlers for each statement type: sessions, pipelines,
|
|
6
|
+
* parallel blocks, conditionals, loops, try/catch, approval gates,
|
|
7
|
+
* bindings, directives, and output statements.
|
|
8
|
+
*
|
|
9
|
+
* Pipelines are delegated to the Rust executor via napi-rs bridge.
|
|
10
|
+
* Sessions invoke the CLEO session machinery. Discretion conditions
|
|
11
|
+
* are evaluated by a pluggable evaluator.
|
|
12
|
+
*
|
|
13
|
+
* @see docs/specs/CANT-DSL-SPEC.md Section 7.2 (Workflow Execution)
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { ApprovalManager } from './approval.js';
|
|
17
|
+
import { createChildScope, createScope, flattenScope, setVariable } from './context-builder.js';
|
|
18
|
+
import type { DiscretionEvaluator } from './discretion.js';
|
|
19
|
+
import { DefaultDiscretionEvaluator, RateLimitedDiscretionEvaluator } from './discretion.js';
|
|
20
|
+
import type { ParallelArm as ParallelArmRunner } from './parallel-runner.js';
|
|
21
|
+
import { executeParallel } from './parallel-runner.js';
|
|
22
|
+
import type {
|
|
23
|
+
DiscretionContext,
|
|
24
|
+
ExecutionResult,
|
|
25
|
+
ExecutionScope,
|
|
26
|
+
JoinStrategy,
|
|
27
|
+
StepResult,
|
|
28
|
+
} from './types.js';
|
|
29
|
+
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
// Configuration
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
|
|
34
|
+
/** Configuration options for the workflow executor. */
|
|
35
|
+
export interface WorkflowExecutorConfig {
|
|
36
|
+
/** Maximum number of discretion evaluations per workflow run (default: 100). */
|
|
37
|
+
maxDiscretionEvaluations?: number;
|
|
38
|
+
/** The session ID for this execution. */
|
|
39
|
+
sessionId?: string;
|
|
40
|
+
/** The agent ID performing the execution. */
|
|
41
|
+
agentId?: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
// Statement type discriminators (from cant-core AST)
|
|
46
|
+
//
|
|
47
|
+
// These are lightweight type guards for the AST Statement enum variants.
|
|
48
|
+
// The real AST types come from the Rust parser; here we use structural
|
|
49
|
+
// matching to avoid tight coupling with the napi binding shape.
|
|
50
|
+
// ---------------------------------------------------------------------------
|
|
51
|
+
|
|
52
|
+
/** Loose AST statement shape — mirrors cant-core Statement variants. */
|
|
53
|
+
interface AstStatement {
|
|
54
|
+
type?: string;
|
|
55
|
+
[key: string]: unknown;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** A workflow definition with a name, params, and body statements. */
|
|
59
|
+
interface WorkflowDef {
|
|
60
|
+
name: { value: string };
|
|
61
|
+
params: Array<{ name: { value: string } }>;
|
|
62
|
+
body: AstStatement[];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// ---------------------------------------------------------------------------
|
|
66
|
+
// Workflow Executor
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Executes CANT workflow definitions.
|
|
71
|
+
*
|
|
72
|
+
* The executor processes each statement in the workflow body sequentially,
|
|
73
|
+
* maintaining an execution scope for variable bindings and dispatching to
|
|
74
|
+
* the appropriate handler based on statement type.
|
|
75
|
+
*/
|
|
76
|
+
export class WorkflowExecutor {
|
|
77
|
+
private readonly discretionEvaluator: DiscretionEvaluator;
|
|
78
|
+
private readonly approvalManager: ApprovalManager;
|
|
79
|
+
private readonly config: WorkflowExecutorConfig;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Creates a new workflow executor.
|
|
83
|
+
*
|
|
84
|
+
* @param discretionEvaluator - Custom discretion evaluator (default: stub that returns true).
|
|
85
|
+
* @param approvalManager - Approval token manager (default: new instance).
|
|
86
|
+
* @param config - Executor configuration.
|
|
87
|
+
*/
|
|
88
|
+
constructor(
|
|
89
|
+
discretionEvaluator: DiscretionEvaluator = new DefaultDiscretionEvaluator(),
|
|
90
|
+
approvalManager: ApprovalManager = new ApprovalManager(),
|
|
91
|
+
config: WorkflowExecutorConfig = {},
|
|
92
|
+
) {
|
|
93
|
+
const maxEvals = config.maxDiscretionEvaluations ?? 100;
|
|
94
|
+
this.discretionEvaluator = new RateLimitedDiscretionEvaluator(discretionEvaluator, maxEvals);
|
|
95
|
+
this.approvalManager = approvalManager;
|
|
96
|
+
this.config = config;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Executes a workflow definition with the given parameter values.
|
|
101
|
+
*
|
|
102
|
+
* @param workflow - The parsed workflow AST node.
|
|
103
|
+
* @param context - Parameter values and initial context.
|
|
104
|
+
* @returns Execution result with outputs and step results.
|
|
105
|
+
*/
|
|
106
|
+
async execute(
|
|
107
|
+
workflow: WorkflowDef,
|
|
108
|
+
context: Record<string, unknown> = {},
|
|
109
|
+
): Promise<ExecutionResult> {
|
|
110
|
+
const start = Date.now();
|
|
111
|
+
const scope = createScope(context);
|
|
112
|
+
const steps: StepResult[] = [];
|
|
113
|
+
const outputs: Record<string, unknown> = {};
|
|
114
|
+
|
|
115
|
+
// Bind workflow parameters to scope
|
|
116
|
+
for (const param of workflow.params) {
|
|
117
|
+
const value = context[param.name.value];
|
|
118
|
+
if (value !== undefined) {
|
|
119
|
+
setVariable(scope, param.name.value, value);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
let success = true;
|
|
124
|
+
|
|
125
|
+
for (const statement of workflow.body) {
|
|
126
|
+
const stepStart = Date.now();
|
|
127
|
+
|
|
128
|
+
try {
|
|
129
|
+
const result = await this.executeStatement(statement, scope, outputs);
|
|
130
|
+
if (result) {
|
|
131
|
+
steps.push({ ...result, duration: Date.now() - stepStart });
|
|
132
|
+
if (!result.success) {
|
|
133
|
+
success = false;
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
} catch (err) {
|
|
138
|
+
const error = err instanceof Error ? err.message : String(err);
|
|
139
|
+
steps.push({
|
|
140
|
+
name: getStatementName(statement),
|
|
141
|
+
type: getStatementType(statement),
|
|
142
|
+
success: false,
|
|
143
|
+
error,
|
|
144
|
+
duration: Date.now() - stepStart,
|
|
145
|
+
});
|
|
146
|
+
success = false;
|
|
147
|
+
break;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return {
|
|
152
|
+
success,
|
|
153
|
+
outputs,
|
|
154
|
+
steps,
|
|
155
|
+
duration: Date.now() - start,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Dispatches a single statement to the appropriate handler.
|
|
161
|
+
*/
|
|
162
|
+
private async executeStatement(
|
|
163
|
+
statement: AstStatement,
|
|
164
|
+
scope: ExecutionScope,
|
|
165
|
+
outputs: Record<string, unknown>,
|
|
166
|
+
): Promise<StepResult | null> {
|
|
167
|
+
const stmtType = detectStatementType(statement);
|
|
168
|
+
|
|
169
|
+
switch (stmtType) {
|
|
170
|
+
case 'Binding':
|
|
171
|
+
return this.executeBinding(statement, scope);
|
|
172
|
+
case 'Output':
|
|
173
|
+
return this.executeOutput(statement, scope, outputs);
|
|
174
|
+
case 'Conditional':
|
|
175
|
+
return this.executeConditional(statement, scope, outputs);
|
|
176
|
+
case 'Parallel':
|
|
177
|
+
return this.executeParallelBlock(statement, scope, outputs);
|
|
178
|
+
case 'Session':
|
|
179
|
+
return this.executeSession(statement, scope);
|
|
180
|
+
case 'Pipeline':
|
|
181
|
+
return this.executePipeline(statement, scope);
|
|
182
|
+
case 'ApprovalGate':
|
|
183
|
+
return this.executeApprovalGate(statement, scope);
|
|
184
|
+
case 'Repeat':
|
|
185
|
+
return this.executeRepeat(statement, scope, outputs);
|
|
186
|
+
case 'ForLoop':
|
|
187
|
+
return this.executeForLoop(statement, scope, outputs);
|
|
188
|
+
case 'LoopUntil':
|
|
189
|
+
return this.executeLoopUntil(statement, scope, outputs);
|
|
190
|
+
case 'TryCatch':
|
|
191
|
+
return this.executeTryCatch(statement, scope, outputs);
|
|
192
|
+
case 'Directive':
|
|
193
|
+
return this.executeDirective(statement, scope);
|
|
194
|
+
case 'Comment':
|
|
195
|
+
return null; // Comments are no-ops
|
|
196
|
+
default:
|
|
197
|
+
return {
|
|
198
|
+
name: getStatementName(statement),
|
|
199
|
+
type: 'binding',
|
|
200
|
+
success: true,
|
|
201
|
+
duration: 0,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/** Execute a let binding statement. */
|
|
207
|
+
private async executeBinding(
|
|
208
|
+
statement: AstStatement,
|
|
209
|
+
scope: ExecutionScope,
|
|
210
|
+
): Promise<StepResult> {
|
|
211
|
+
const name = (statement as { name?: { value: string } }).name?.value ?? 'binding';
|
|
212
|
+
const value = (statement as { value?: unknown }).value;
|
|
213
|
+
setVariable(scope, name, value);
|
|
214
|
+
return { name, type: 'binding', success: true, output: value, duration: 0 };
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/** Execute an output binding statement. */
|
|
218
|
+
private async executeOutput(
|
|
219
|
+
statement: AstStatement,
|
|
220
|
+
scope: ExecutionScope,
|
|
221
|
+
outputs: Record<string, unknown>,
|
|
222
|
+
): Promise<StepResult> {
|
|
223
|
+
const name = (statement as { name?: { value: string } }).name?.value ?? 'output';
|
|
224
|
+
const value = (statement as { value?: unknown }).value;
|
|
225
|
+
outputs[name] = value;
|
|
226
|
+
setVariable(scope, name, value);
|
|
227
|
+
return { name, type: 'output', success: true, output: value, duration: 0 };
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/** Execute an if/elif/else conditional. */
|
|
231
|
+
private async executeConditional(
|
|
232
|
+
statement: AstStatement,
|
|
233
|
+
scope: ExecutionScope,
|
|
234
|
+
outputs: Record<string, unknown>,
|
|
235
|
+
): Promise<StepResult> {
|
|
236
|
+
const conditional = statement as {
|
|
237
|
+
condition?: { Discretion?: { prose: string }; Expression?: unknown };
|
|
238
|
+
then_body?: AstStatement[];
|
|
239
|
+
elif_branches?: Array<{
|
|
240
|
+
condition: { Discretion?: { prose: string }; Expression?: unknown };
|
|
241
|
+
body: AstStatement[];
|
|
242
|
+
}>;
|
|
243
|
+
else_body?: AstStatement[];
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
// Evaluate the if condition
|
|
247
|
+
const ifResult = await this.evaluateCondition(conditional.condition, scope);
|
|
248
|
+
|
|
249
|
+
if (ifResult) {
|
|
250
|
+
for (const stmt of conditional.then_body ?? []) {
|
|
251
|
+
await this.executeStatement(stmt, scope, outputs);
|
|
252
|
+
}
|
|
253
|
+
return { name: 'if', type: 'conditional', success: true, output: true, duration: 0 };
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
// Check elif branches
|
|
257
|
+
for (const elif of conditional.elif_branches ?? []) {
|
|
258
|
+
const elifResult = await this.evaluateCondition(elif.condition, scope);
|
|
259
|
+
if (elifResult) {
|
|
260
|
+
for (const stmt of elif.body) {
|
|
261
|
+
await this.executeStatement(stmt, scope, outputs);
|
|
262
|
+
}
|
|
263
|
+
return { name: 'elif', type: 'conditional', success: true, output: true, duration: 0 };
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Execute else branch
|
|
268
|
+
if (conditional.else_body) {
|
|
269
|
+
for (const stmt of conditional.else_body) {
|
|
270
|
+
await this.executeStatement(stmt, scope, outputs);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return { name: 'else', type: 'conditional', success: true, output: false, duration: 0 };
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/** Execute a parallel block with arms. */
|
|
278
|
+
private async executeParallelBlock(
|
|
279
|
+
statement: AstStatement,
|
|
280
|
+
scope: ExecutionScope,
|
|
281
|
+
_outputs: Record<string, unknown>,
|
|
282
|
+
): Promise<StepResult> {
|
|
283
|
+
const parallel = statement as {
|
|
284
|
+
modifier?: string;
|
|
285
|
+
arms?: Array<{ name: string; body: AstStatement }>;
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
const strategy: JoinStrategy =
|
|
289
|
+
parallel.modifier === 'Race' ? 'race' : parallel.modifier === 'Settle' ? 'settle' : 'all';
|
|
290
|
+
|
|
291
|
+
const arms: ParallelArmRunner[] = (parallel.arms ?? []).map((arm) => ({
|
|
292
|
+
name: arm.name,
|
|
293
|
+
execute: async () => {
|
|
294
|
+
const childScope = createChildScope(scope);
|
|
295
|
+
const armOutputs: Record<string, unknown> = {};
|
|
296
|
+
const result = await this.executeStatement(arm.body, childScope, armOutputs);
|
|
297
|
+
return result?.output;
|
|
298
|
+
},
|
|
299
|
+
}));
|
|
300
|
+
|
|
301
|
+
const result = await executeParallel(arms, strategy);
|
|
302
|
+
|
|
303
|
+
// Bind arm results to the parent scope
|
|
304
|
+
for (const [name, value] of Object.entries(result.results)) {
|
|
305
|
+
setVariable(scope, name, value);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
return {
|
|
309
|
+
name: 'parallel',
|
|
310
|
+
type: 'parallel',
|
|
311
|
+
success: result.success,
|
|
312
|
+
output: result.results,
|
|
313
|
+
duration: 0,
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
/** Execute a session invocation (stub — real session dispatch is a separate integration). */
|
|
318
|
+
private async executeSession(
|
|
319
|
+
statement: AstStatement,
|
|
320
|
+
_scope: ExecutionScope,
|
|
321
|
+
): Promise<StepResult> {
|
|
322
|
+
const session = statement as {
|
|
323
|
+
target?: { Prompt?: string; Agent?: string };
|
|
324
|
+
};
|
|
325
|
+
const targetName = session.target?.Prompt ?? session.target?.Agent ?? 'session';
|
|
326
|
+
// Stub: real session dispatch integrates with CLEO session machinery
|
|
327
|
+
return {
|
|
328
|
+
name: targetName,
|
|
329
|
+
type: 'session',
|
|
330
|
+
success: true,
|
|
331
|
+
output: { stub: true, target: targetName },
|
|
332
|
+
duration: 0,
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
/** Execute a pipeline definition (stub — real pipeline calls Rust via napi-rs). */
|
|
337
|
+
private async executePipeline(
|
|
338
|
+
statement: AstStatement,
|
|
339
|
+
_scope: ExecutionScope,
|
|
340
|
+
): Promise<StepResult> {
|
|
341
|
+
const pipeline = statement as { name?: { value: string } };
|
|
342
|
+
const name = pipeline.name?.value ?? 'pipeline';
|
|
343
|
+
// Stub: real implementation calls Rust pipeline executor via napi-rs bridge
|
|
344
|
+
return {
|
|
345
|
+
name,
|
|
346
|
+
type: 'pipeline',
|
|
347
|
+
success: true,
|
|
348
|
+
output: { stub: true },
|
|
349
|
+
duration: 0,
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/** Execute an approval gate. */
|
|
354
|
+
private async executeApprovalGate(
|
|
355
|
+
statement: AstStatement,
|
|
356
|
+
_scope: ExecutionScope,
|
|
357
|
+
): Promise<StepResult> {
|
|
358
|
+
const gate = statement as {
|
|
359
|
+
properties?: Array<{ key: { value: string }; value: { raw?: string } }>;
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
const message =
|
|
363
|
+
gate.properties?.find((p) => p.key.value === 'message')?.value?.raw ?? 'Approval required';
|
|
364
|
+
const gateName = 'approval-gate';
|
|
365
|
+
|
|
366
|
+
const workflowHash = ApprovalManager.computeWorkflowHash(JSON.stringify(statement));
|
|
367
|
+
const token = this.approvalManager.generateToken(
|
|
368
|
+
this.config.sessionId ?? 'unknown-session',
|
|
369
|
+
'workflow',
|
|
370
|
+
gateName,
|
|
371
|
+
message,
|
|
372
|
+
workflowHash,
|
|
373
|
+
this.config.agentId ?? 'unknown-agent',
|
|
374
|
+
);
|
|
375
|
+
|
|
376
|
+
// In production, the executor would suspend the session here and
|
|
377
|
+
// wait for a /approve directive. For now, return the token info.
|
|
378
|
+
return {
|
|
379
|
+
name: gateName,
|
|
380
|
+
type: 'approval',
|
|
381
|
+
success: true,
|
|
382
|
+
output: { tokenId: token.token, message, status: token.status },
|
|
383
|
+
duration: 0,
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/** Execute a repeat N loop. */
|
|
388
|
+
private async executeRepeat(
|
|
389
|
+
statement: AstStatement,
|
|
390
|
+
scope: ExecutionScope,
|
|
391
|
+
outputs: Record<string, unknown>,
|
|
392
|
+
): Promise<StepResult> {
|
|
393
|
+
const repeat = statement as { count?: { value?: number }; body?: AstStatement[] };
|
|
394
|
+
const count = repeat.count?.value ?? 1;
|
|
395
|
+
|
|
396
|
+
for (let i = 0; i < count; i++) {
|
|
397
|
+
const iterScope = createChildScope(scope, { _iteration: i });
|
|
398
|
+
for (const stmt of repeat.body ?? []) {
|
|
399
|
+
await this.executeStatement(stmt, iterScope, outputs);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
return { name: `repeat(${count})`, type: 'loop', success: true, output: count, duration: 0 };
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/** Execute a for-in loop. */
|
|
407
|
+
private async executeForLoop(
|
|
408
|
+
statement: AstStatement,
|
|
409
|
+
scope: ExecutionScope,
|
|
410
|
+
outputs: Record<string, unknown>,
|
|
411
|
+
): Promise<StepResult> {
|
|
412
|
+
const forLoop = statement as {
|
|
413
|
+
variable?: { value: string };
|
|
414
|
+
iterable?: unknown;
|
|
415
|
+
body?: AstStatement[];
|
|
416
|
+
};
|
|
417
|
+
|
|
418
|
+
const varName = forLoop.variable?.value ?? 'item';
|
|
419
|
+
const iterable = forLoop.iterable;
|
|
420
|
+
const items = Array.isArray(iterable) ? iterable : [];
|
|
421
|
+
|
|
422
|
+
for (const item of items) {
|
|
423
|
+
const iterScope = createChildScope(scope, { [varName]: item });
|
|
424
|
+
for (const stmt of forLoop.body ?? []) {
|
|
425
|
+
await this.executeStatement(stmt, iterScope, outputs);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
return {
|
|
430
|
+
name: `for(${varName})`,
|
|
431
|
+
type: 'loop',
|
|
432
|
+
success: true,
|
|
433
|
+
output: items.length,
|
|
434
|
+
duration: 0,
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
/** Execute a loop-until block. */
|
|
439
|
+
private async executeLoopUntil(
|
|
440
|
+
statement: AstStatement,
|
|
441
|
+
scope: ExecutionScope,
|
|
442
|
+
outputs: Record<string, unknown>,
|
|
443
|
+
): Promise<StepResult> {
|
|
444
|
+
const loop = statement as { body?: AstStatement[]; condition?: unknown };
|
|
445
|
+
let iterations = 0;
|
|
446
|
+
const maxIterations = 10000;
|
|
447
|
+
let conditionMet = false;
|
|
448
|
+
|
|
449
|
+
do {
|
|
450
|
+
iterations++;
|
|
451
|
+
if (iterations > maxIterations) {
|
|
452
|
+
throw new Error(`Loop exceeded maximum iterations (${maxIterations})`);
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
for (const stmt of loop.body ?? []) {
|
|
456
|
+
await this.executeStatement(stmt, scope, outputs);
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
conditionMet = await this.evaluateCondition(loop.condition, scope);
|
|
460
|
+
} while (!conditionMet);
|
|
461
|
+
|
|
462
|
+
return {
|
|
463
|
+
name: 'loop-until',
|
|
464
|
+
type: 'loop',
|
|
465
|
+
success: true,
|
|
466
|
+
output: iterations,
|
|
467
|
+
duration: 0,
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
/** Execute a try/catch/finally block. */
|
|
472
|
+
private async executeTryCatch(
|
|
473
|
+
statement: AstStatement,
|
|
474
|
+
scope: ExecutionScope,
|
|
475
|
+
outputs: Record<string, unknown>,
|
|
476
|
+
): Promise<StepResult> {
|
|
477
|
+
const tryCatch = statement as {
|
|
478
|
+
try_body?: AstStatement[];
|
|
479
|
+
catch_name?: string;
|
|
480
|
+
catch_body?: AstStatement[];
|
|
481
|
+
finally_body?: AstStatement[];
|
|
482
|
+
};
|
|
483
|
+
|
|
484
|
+
let success = true;
|
|
485
|
+
let error: string | undefined;
|
|
486
|
+
|
|
487
|
+
try {
|
|
488
|
+
for (const stmt of tryCatch.try_body ?? []) {
|
|
489
|
+
await this.executeStatement(stmt, scope, outputs);
|
|
490
|
+
}
|
|
491
|
+
} catch (err) {
|
|
492
|
+
success = false;
|
|
493
|
+
error = err instanceof Error ? err.message : String(err);
|
|
494
|
+
|
|
495
|
+
if (tryCatch.catch_body) {
|
|
496
|
+
const catchScope = createChildScope(scope, {
|
|
497
|
+
[tryCatch.catch_name ?? 'err']: error,
|
|
498
|
+
});
|
|
499
|
+
for (const stmt of tryCatch.catch_body) {
|
|
500
|
+
await this.executeStatement(stmt, catchScope, outputs);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
} finally {
|
|
504
|
+
if (tryCatch.finally_body) {
|
|
505
|
+
for (const stmt of tryCatch.finally_body) {
|
|
506
|
+
await this.executeStatement(stmt, scope, outputs);
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
return { name: 'try-catch', type: 'conditional', success, error, duration: 0 };
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
/** Execute a CANT directive statement. */
|
|
515
|
+
private async executeDirective(
|
|
516
|
+
statement: AstStatement,
|
|
517
|
+
_scope: ExecutionScope,
|
|
518
|
+
): Promise<StepResult> {
|
|
519
|
+
const directive = statement as {
|
|
520
|
+
verb?: string;
|
|
521
|
+
addresses?: string[];
|
|
522
|
+
task_refs?: string[];
|
|
523
|
+
};
|
|
524
|
+
|
|
525
|
+
// Stub: real implementation dispatches via CLEO operations
|
|
526
|
+
return {
|
|
527
|
+
name: `/${directive.verb ?? 'unknown'}`,
|
|
528
|
+
type: 'directive',
|
|
529
|
+
success: true,
|
|
530
|
+
output: {
|
|
531
|
+
verb: directive.verb,
|
|
532
|
+
addresses: directive.addresses,
|
|
533
|
+
taskRefs: directive.task_refs,
|
|
534
|
+
},
|
|
535
|
+
duration: 0,
|
|
536
|
+
};
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
/**
|
|
540
|
+
* Evaluate a condition (regular expression or discretion).
|
|
541
|
+
*/
|
|
542
|
+
private async evaluateCondition(condition: unknown, scope: ExecutionScope): Promise<boolean> {
|
|
543
|
+
if (!condition) return true;
|
|
544
|
+
|
|
545
|
+
const cond = condition as {
|
|
546
|
+
Discretion?: { prose: string };
|
|
547
|
+
Expression?: unknown;
|
|
548
|
+
};
|
|
549
|
+
|
|
550
|
+
if (cond.Discretion) {
|
|
551
|
+
const context: DiscretionContext = {
|
|
552
|
+
sessionId: this.config.sessionId ?? '',
|
|
553
|
+
taskRefs: [],
|
|
554
|
+
agentId: this.config.agentId ?? '',
|
|
555
|
+
variables: flattenScope(scope),
|
|
556
|
+
condition: cond.Discretion.prose,
|
|
557
|
+
precedingResults: {},
|
|
558
|
+
};
|
|
559
|
+
return this.discretionEvaluator.evaluate(cond.Discretion.prose, context);
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
// For regular expressions, return true as a stub
|
|
563
|
+
// Real implementation would evaluate the expression against the scope
|
|
564
|
+
return true;
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
// ---------------------------------------------------------------------------
|
|
569
|
+
// Helpers
|
|
570
|
+
// ---------------------------------------------------------------------------
|
|
571
|
+
|
|
572
|
+
/** Detect the statement type from an AST statement object. */
|
|
573
|
+
function detectStatementType(statement: AstStatement): string {
|
|
574
|
+
if ('Binding' in statement) return 'Binding';
|
|
575
|
+
if ('Output' in statement) return 'Output';
|
|
576
|
+
if ('Conditional' in statement || ('condition' in statement && 'then_body' in statement))
|
|
577
|
+
return 'Conditional';
|
|
578
|
+
if ('Parallel' in statement || 'arms' in statement) return 'Parallel';
|
|
579
|
+
if ('Session' in statement || 'target' in statement) return 'Session';
|
|
580
|
+
if ('Pipeline' in statement || ('steps' in statement && 'name' in statement)) return 'Pipeline';
|
|
581
|
+
if ('ApprovalGate' in statement) return 'ApprovalGate';
|
|
582
|
+
if ('Repeat' in statement || 'count' in statement) return 'Repeat';
|
|
583
|
+
if ('ForLoop' in statement || ('variable' in statement && 'iterable' in statement))
|
|
584
|
+
return 'ForLoop';
|
|
585
|
+
if ('LoopUntil' in statement) return 'LoopUntil';
|
|
586
|
+
if ('TryCatch' in statement || 'try_body' in statement) return 'TryCatch';
|
|
587
|
+
if ('Directive' in statement || 'verb' in statement) return 'Directive';
|
|
588
|
+
if ('Comment' in statement || 'text' in statement) return 'Comment';
|
|
589
|
+
return statement.type ?? 'unknown';
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
/** Extract a human-readable name from a statement. */
|
|
593
|
+
function getStatementName(statement: AstStatement): string {
|
|
594
|
+
const named = statement as { name?: { value: string } | string; verb?: string };
|
|
595
|
+
if (typeof named.name === 'object' && named.name?.value) return named.name.value;
|
|
596
|
+
if (typeof named.name === 'string') return named.name;
|
|
597
|
+
if (named.verb) return `/${named.verb}`;
|
|
598
|
+
return detectStatementType(statement);
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
/** Map a statement to a StepResult type category. */
|
|
602
|
+
function getStatementType(statement: AstStatement): StepResult['type'] {
|
|
603
|
+
const t = detectStatementType(statement);
|
|
604
|
+
const mapping: Record<string, StepResult['type']> = {
|
|
605
|
+
Session: 'session',
|
|
606
|
+
Pipeline: 'pipeline',
|
|
607
|
+
Parallel: 'parallel',
|
|
608
|
+
Conditional: 'conditional',
|
|
609
|
+
Repeat: 'loop',
|
|
610
|
+
ForLoop: 'loop',
|
|
611
|
+
LoopUntil: 'loop',
|
|
612
|
+
ApprovalGate: 'approval',
|
|
613
|
+
Binding: 'binding',
|
|
614
|
+
Output: 'output',
|
|
615
|
+
Directive: 'directive',
|
|
616
|
+
};
|
|
617
|
+
return mapping[t] ?? 'binding';
|
|
618
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code analysis via tree-sitter AST parsing.
|
|
3
|
+
*
|
|
4
|
+
* @module code
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export { type OutlineNode, type SmartOutlineResult, smartOutline } from './outline.js';
|
|
8
|
+
export { batchParse, parseFile } from './parser.js';
|
|
9
|
+
export { type SmartSearchOptions, type SmartSearchResult, smartSearch } from './search.js';
|
|
10
|
+
export { type SmartUnfoldResult, smartUnfold } from './unfold.js';
|