@namzu/sdk 0.1.8 → 0.2.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/CHANGELOG.md +16 -0
- package/dist/agents/ReactiveAgent.d.ts.map +1 -1
- package/dist/agents/ReactiveAgent.js +5 -3
- package/dist/agents/ReactiveAgent.js.map +1 -1
- package/dist/agents/RouterAgent.d.ts.map +1 -1
- package/dist/agents/RouterAgent.js +3 -0
- package/dist/agents/RouterAgent.js.map +1 -1
- package/dist/agents/SupervisorAgent.d.ts.map +1 -1
- package/dist/agents/SupervisorAgent.js +18 -5
- package/dist/agents/SupervisorAgent.js.map +1 -1
- package/dist/bridge/a2a/mapper.d.ts.map +1 -1
- package/dist/bridge/a2a/mapper.js +6 -0
- package/dist/bridge/a2a/mapper.js.map +1 -1
- package/dist/bridge/a2a/task.d.ts +2 -2
- package/dist/bridge/a2a/task.d.ts.map +1 -1
- package/dist/bridge/a2a/task.js.map +1 -1
- package/dist/bridge/sse/mapper.d.ts.map +1 -1
- package/dist/bridge/sse/mapper.js +6 -0
- package/dist/bridge/sse/mapper.js.map +1 -1
- package/dist/constants/a2a/index.d.ts +2 -2
- package/dist/constants/a2a/index.d.ts.map +1 -1
- package/dist/constants/a2a/index.js.map +1 -1
- package/dist/contracts/api.d.ts +22 -3
- package/dist/contracts/api.d.ts.map +1 -1
- package/dist/contracts/index.d.ts +3 -1
- package/dist/contracts/index.d.ts.map +1 -1
- package/dist/contracts/index.js.map +1 -1
- package/dist/gateway/local.d.ts.map +1 -1
- package/dist/gateway/local.js +6 -0
- package/dist/gateway/local.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/manager/agent/__tests__/lifecycle.test.d.ts +2 -0
- package/dist/manager/agent/__tests__/lifecycle.test.d.ts.map +1 -0
- package/dist/manager/agent/__tests__/lifecycle.test.js +302 -0
- package/dist/manager/agent/__tests__/lifecycle.test.js.map +1 -0
- package/dist/manager/agent/lifecycle.d.ts +58 -3
- package/dist/manager/agent/lifecycle.d.ts.map +1 -1
- package/dist/manager/agent/lifecycle.js +311 -12
- package/dist/manager/agent/lifecycle.js.map +1 -1
- package/dist/manager/run/persistence.d.ts +8 -1
- package/dist/manager/run/persistence.d.ts.map +1 -1
- package/dist/manager/run/persistence.js +15 -0
- package/dist/manager/run/persistence.js.map +1 -1
- package/dist/run/reporter.d.ts.map +1 -1
- package/dist/run/reporter.js +25 -0
- package/dist/run/reporter.js.map +1 -1
- package/dist/runtime/query/__tests__/context.test.d.ts +2 -0
- package/dist/runtime/query/__tests__/context.test.d.ts.map +1 -0
- package/dist/runtime/query/__tests__/context.test.js +84 -0
- package/dist/runtime/query/__tests__/context.test.js.map +1 -0
- package/dist/runtime/query/context.d.ts +55 -2
- package/dist/runtime/query/context.d.ts.map +1 -1
- package/dist/runtime/query/context.js +48 -8
- package/dist/runtime/query/context.js.map +1 -1
- package/dist/runtime/query/events.d.ts.map +1 -1
- package/dist/runtime/query/events.js +8 -0
- package/dist/runtime/query/events.js.map +1 -1
- package/dist/runtime/query/index.d.ts +25 -2
- package/dist/runtime/query/index.d.ts.map +1 -1
- package/dist/runtime/query/index.js +11 -1
- package/dist/runtime/query/index.js.map +1 -1
- package/dist/session/__tests__/integration/_fixtures.d.ts +115 -0
- package/dist/session/__tests__/integration/_fixtures.d.ts.map +1 -0
- package/dist/session/__tests__/integration/_fixtures.js +198 -0
- package/dist/session/__tests__/integration/_fixtures.js.map +1 -0
- package/dist/session/__tests__/integration/capacity-caps.test.d.ts +13 -0
- package/dist/session/__tests__/integration/capacity-caps.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/capacity-caps.test.js +116 -0
- package/dist/session/__tests__/integration/capacity-caps.test.js.map +1 -0
- package/dist/session/__tests__/integration/e2e-spawn.test.d.ts +18 -0
- package/dist/session/__tests__/integration/e2e-spawn.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/e2e-spawn.test.js +226 -0
- package/dist/session/__tests__/integration/e2e-spawn.test.js.map +1 -0
- package/dist/session/__tests__/integration/event-stream-ordering.test.d.ts +15 -0
- package/dist/session/__tests__/integration/event-stream-ordering.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/event-stream-ordering.test.js +323 -0
- package/dist/session/__tests__/integration/event-stream-ordering.test.js.map +1 -0
- package/dist/session/__tests__/integration/handoff-broadcast-e2e.test.d.ts +12 -0
- package/dist/session/__tests__/integration/handoff-broadcast-e2e.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/handoff-broadcast-e2e.test.js +170 -0
- package/dist/session/__tests__/integration/handoff-broadcast-e2e.test.js.map +1 -0
- package/dist/session/__tests__/integration/handoff-illegal-transition.test.d.ts +18 -0
- package/dist/session/__tests__/integration/handoff-illegal-transition.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/handoff-illegal-transition.test.js +146 -0
- package/dist/session/__tests__/integration/handoff-illegal-transition.test.js.map +1 -0
- package/dist/session/__tests__/integration/handoff-single-e2e.test.d.ts +15 -0
- package/dist/session/__tests__/integration/handoff-single-e2e.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/handoff-single-e2e.test.js +163 -0
- package/dist/session/__tests__/integration/handoff-single-e2e.test.js.map +1 -0
- package/dist/session/__tests__/integration/hierarchy-lifecycle.test.d.ts +12 -0
- package/dist/session/__tests__/integration/hierarchy-lifecycle.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/hierarchy-lifecycle.test.js +157 -0
- package/dist/session/__tests__/integration/hierarchy-lifecycle.test.js.map +1 -0
- package/dist/session/__tests__/integration/migration-filesystem.test.d.ts +11 -0
- package/dist/session/__tests__/integration/migration-filesystem.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/migration-filesystem.test.js +140 -0
- package/dist/session/__tests__/integration/migration-filesystem.test.js.map +1 -0
- package/dist/session/__tests__/integration/migration-id-prefix.test.d.ts +13 -0
- package/dist/session/__tests__/integration/migration-id-prefix.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/migration-id-prefix.test.js +84 -0
- package/dist/session/__tests__/integration/migration-id-prefix.test.js.map +1 -0
- package/dist/session/__tests__/integration/prev-artifact-dag.test.d.ts +14 -0
- package/dist/session/__tests__/integration/prev-artifact-dag.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/prev-artifact-dag.test.js +241 -0
- package/dist/session/__tests__/integration/prev-artifact-dag.test.js.map +1 -0
- package/dist/session/__tests__/integration/retention-archive.test.d.ts +12 -0
- package/dist/session/__tests__/integration/retention-archive.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/retention-archive.test.js +186 -0
- package/dist/session/__tests__/integration/retention-archive.test.js.map +1 -0
- package/dist/session/__tests__/integration/summary-materialization-e2e.test.d.ts +18 -0
- package/dist/session/__tests__/integration/summary-materialization-e2e.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/summary-materialization-e2e.test.js +200 -0
- package/dist/session/__tests__/integration/summary-materialization-e2e.test.js.map +1 -0
- package/dist/session/__tests__/integration/tenant-isolation.test.d.ts +14 -0
- package/dist/session/__tests__/integration/tenant-isolation.test.d.ts.map +1 -0
- package/dist/session/__tests__/integration/tenant-isolation.test.js +180 -0
- package/dist/session/__tests__/integration/tenant-isolation.test.js.map +1 -0
- package/dist/session/errors.d.ts +60 -0
- package/dist/session/errors.d.ts.map +1 -0
- package/dist/session/errors.js +50 -0
- package/dist/session/errors.js.map +1 -0
- package/dist/session/events/index.d.ts +4 -0
- package/dist/session/events/index.d.ts.map +1 -0
- package/dist/session/events/index.js +8 -0
- package/dist/session/events/index.js.map +1 -0
- package/dist/session/events/schema-version.d.ts +13 -0
- package/dist/session/events/schema-version.d.ts.map +1 -0
- package/dist/session/events/schema-version.js +12 -0
- package/dist/session/events/schema-version.js.map +1 -0
- package/dist/session/events/types.d.ts +64 -0
- package/dist/session/events/types.d.ts.map +1 -0
- package/dist/session/events/types.js +2 -0
- package/dist/session/events/types.js.map +1 -0
- package/dist/session/handoff/__tests__/broadcast.test.d.ts +2 -0
- package/dist/session/handoff/__tests__/broadcast.test.d.ts.map +1 -0
- package/dist/session/handoff/__tests__/broadcast.test.js +243 -0
- package/dist/session/handoff/__tests__/broadcast.test.js.map +1 -0
- package/dist/session/handoff/__tests__/capacity.test.d.ts +2 -0
- package/dist/session/handoff/__tests__/capacity.test.d.ts.map +1 -0
- package/dist/session/handoff/__tests__/capacity.test.js +100 -0
- package/dist/session/handoff/__tests__/capacity.test.js.map +1 -0
- package/dist/session/handoff/__tests__/single.test.d.ts +2 -0
- package/dist/session/handoff/__tests__/single.test.d.ts.map +1 -0
- package/dist/session/handoff/__tests__/single.test.js +230 -0
- package/dist/session/handoff/__tests__/single.test.js.map +1 -0
- package/dist/session/handoff/assignment.d.ts +59 -0
- package/dist/session/handoff/assignment.d.ts.map +1 -0
- package/dist/session/handoff/assignment.js +11 -0
- package/dist/session/handoff/assignment.js.map +1 -0
- package/dist/session/handoff/broadcast.d.ts +47 -0
- package/dist/session/handoff/broadcast.d.ts.map +1 -0
- package/dist/session/handoff/broadcast.js +296 -0
- package/dist/session/handoff/broadcast.js.map +1 -0
- package/dist/session/handoff/capacity.d.ts +66 -0
- package/dist/session/handoff/capacity.d.ts.map +1 -0
- package/dist/session/handoff/capacity.js +60 -0
- package/dist/session/handoff/capacity.js.map +1 -0
- package/dist/session/handoff/events.d.ts +66 -0
- package/dist/session/handoff/events.d.ts.map +1 -0
- package/dist/session/handoff/events.js +13 -0
- package/dist/session/handoff/events.js.map +1 -0
- package/dist/session/handoff/index.d.ts +12 -0
- package/dist/session/handoff/index.d.ts.map +1 -0
- package/dist/session/handoff/index.js +9 -0
- package/dist/session/handoff/index.js.map +1 -0
- package/dist/session/handoff/single.d.ts +62 -0
- package/dist/session/handoff/single.d.ts.map +1 -0
- package/dist/session/handoff/single.js +217 -0
- package/dist/session/handoff/single.js.map +1 -0
- package/dist/session/handoff/version.d.ts +52 -0
- package/dist/session/handoff/version.d.ts.map +1 -0
- package/dist/session/handoff/version.js +36 -0
- package/dist/session/handoff/version.js.map +1 -0
- package/dist/session/hierarchy/__tests__/session.test.d.ts +2 -0
- package/dist/session/hierarchy/__tests__/session.test.d.ts.map +1 -0
- package/dist/session/hierarchy/__tests__/session.test.js +67 -0
- package/dist/session/hierarchy/__tests__/session.test.js.map +1 -0
- package/dist/session/hierarchy/actor.d.ts +26 -0
- package/dist/session/hierarchy/actor.d.ts.map +1 -0
- package/dist/session/hierarchy/actor.js +2 -0
- package/dist/session/hierarchy/actor.js.map +1 -0
- package/dist/session/hierarchy/index.d.ts +8 -0
- package/dist/session/hierarchy/index.d.ts.map +1 -0
- package/dist/session/hierarchy/index.js +4 -0
- package/dist/session/hierarchy/index.js.map +1 -0
- package/dist/session/hierarchy/lineage.d.ts +15 -0
- package/dist/session/hierarchy/lineage.d.ts.map +1 -0
- package/dist/session/hierarchy/lineage.js +2 -0
- package/dist/session/hierarchy/lineage.js.map +1 -0
- package/dist/session/hierarchy/project.d.ts +40 -0
- package/dist/session/hierarchy/project.d.ts.map +1 -0
- package/dist/session/hierarchy/project.js +2 -0
- package/dist/session/hierarchy/project.js.map +1 -0
- package/dist/session/hierarchy/session.d.ts +59 -0
- package/dist/session/hierarchy/session.d.ts.map +1 -0
- package/dist/session/hierarchy/session.js +51 -0
- package/dist/session/hierarchy/session.js.map +1 -0
- package/dist/session/hierarchy/sub-session.d.ts +76 -0
- package/dist/session/hierarchy/sub-session.d.ts.map +1 -0
- package/dist/session/hierarchy/sub-session.js +2 -0
- package/dist/session/hierarchy/sub-session.js.map +1 -0
- package/dist/session/hierarchy/tenant.d.ts +13 -0
- package/dist/session/hierarchy/tenant.d.ts.map +1 -0
- package/dist/session/hierarchy/tenant.js +2 -0
- package/dist/session/hierarchy/tenant.js.map +1 -0
- package/dist/session/index.d.ts +10 -0
- package/dist/session/index.d.ts.map +1 -0
- package/dist/session/index.js +15 -0
- package/dist/session/index.js.map +1 -0
- package/dist/session/intervention/__tests__/prev-artifact.test.d.ts +2 -0
- package/dist/session/intervention/__tests__/prev-artifact.test.d.ts.map +1 -0
- package/dist/session/intervention/__tests__/prev-artifact.test.js +179 -0
- package/dist/session/intervention/__tests__/prev-artifact.test.js.map +1 -0
- package/dist/session/intervention/index.d.ts +3 -0
- package/dist/session/intervention/index.d.ts.map +1 -0
- package/dist/session/intervention/index.js +8 -0
- package/dist/session/intervention/index.js.map +1 -0
- package/dist/session/intervention/prev-artifact.d.ts +103 -0
- package/dist/session/intervention/prev-artifact.d.ts.map +1 -0
- package/dist/session/intervention/prev-artifact.js +112 -0
- package/dist/session/intervention/prev-artifact.js.map +1 -0
- package/dist/session/migration/__tests__/filesystem.test.d.ts +2 -0
- package/dist/session/migration/__tests__/filesystem.test.d.ts.map +1 -0
- package/dist/session/migration/__tests__/filesystem.test.js +188 -0
- package/dist/session/migration/__tests__/filesystem.test.js.map +1 -0
- package/dist/session/migration/__tests__/id-prefix.test.d.ts +2 -0
- package/dist/session/migration/__tests__/id-prefix.test.d.ts.map +1 -0
- package/dist/session/migration/__tests__/id-prefix.test.js +83 -0
- package/dist/session/migration/__tests__/id-prefix.test.js.map +1 -0
- package/dist/session/migration/__tests__/marker.test.d.ts +2 -0
- package/dist/session/migration/__tests__/marker.test.d.ts.map +1 -0
- package/dist/session/migration/__tests__/marker.test.js +75 -0
- package/dist/session/migration/__tests__/marker.test.js.map +1 -0
- package/dist/session/migration/errors.d.ts +26 -0
- package/dist/session/migration/errors.d.ts.map +1 -0
- package/dist/session/migration/errors.js +22 -0
- package/dist/session/migration/errors.js.map +1 -0
- package/dist/session/migration/filesystem.d.ts +94 -0
- package/dist/session/migration/filesystem.d.ts.map +1 -0
- package/dist/session/migration/filesystem.js +319 -0
- package/dist/session/migration/filesystem.js.map +1 -0
- package/dist/session/migration/id-prefix.d.ts +98 -0
- package/dist/session/migration/id-prefix.d.ts.map +1 -0
- package/dist/session/migration/id-prefix.js +116 -0
- package/dist/session/migration/id-prefix.js.map +1 -0
- package/dist/session/migration/index.d.ts +8 -0
- package/dist/session/migration/index.d.ts.map +1 -0
- package/dist/session/migration/index.js +8 -0
- package/dist/session/migration/index.js.map +1 -0
- package/dist/session/migration/marker.d.ts +57 -0
- package/dist/session/migration/marker.d.ts.map +1 -0
- package/dist/session/migration/marker.js +111 -0
- package/dist/session/migration/marker.js.map +1 -0
- package/dist/session/retention/__tests__/archive.test.d.ts +2 -0
- package/dist/session/retention/__tests__/archive.test.d.ts.map +1 -0
- package/dist/session/retention/__tests__/archive.test.js +252 -0
- package/dist/session/retention/__tests__/archive.test.js.map +1 -0
- package/dist/session/retention/__tests__/disk-backend.test.d.ts +2 -0
- package/dist/session/retention/__tests__/disk-backend.test.d.ts.map +1 -0
- package/dist/session/retention/__tests__/disk-backend.test.js +154 -0
- package/dist/session/retention/__tests__/disk-backend.test.js.map +1 -0
- package/dist/session/retention/archive-backend-ref.d.ts +18 -0
- package/dist/session/retention/archive-backend-ref.d.ts.map +1 -0
- package/dist/session/retention/archive-backend-ref.js +2 -0
- package/dist/session/retention/archive-backend-ref.js.map +1 -0
- package/dist/session/retention/archive.d.ts +130 -0
- package/dist/session/retention/archive.d.ts.map +1 -0
- package/dist/session/retention/archive.js +203 -0
- package/dist/session/retention/archive.js.map +1 -0
- package/dist/session/retention/backend.d.ts +101 -0
- package/dist/session/retention/backend.d.ts.map +1 -0
- package/dist/session/retention/backend.js +15 -0
- package/dist/session/retention/backend.js.map +1 -0
- package/dist/session/retention/disk-backend.d.ts +59 -0
- package/dist/session/retention/disk-backend.d.ts.map +1 -0
- package/dist/session/retention/disk-backend.js +236 -0
- package/dist/session/retention/disk-backend.js.map +1 -0
- package/dist/session/retention/index.d.ts +9 -0
- package/dist/session/retention/index.d.ts.map +1 -0
- package/dist/session/retention/index.js +6 -0
- package/dist/session/retention/index.js.map +1 -0
- package/dist/session/retention/policy.d.ts +49 -0
- package/dist/session/retention/policy.d.ts.map +1 -0
- package/dist/session/retention/policy.js +21 -0
- package/dist/session/retention/policy.js.map +1 -0
- package/dist/session/summary/__tests__/materialize.test.d.ts +2 -0
- package/dist/session/summary/__tests__/materialize.test.d.ts.map +1 -0
- package/dist/session/summary/__tests__/materialize.test.js +269 -0
- package/dist/session/summary/__tests__/materialize.test.js.map +1 -0
- package/dist/session/summary/deliverable.d.ts +74 -0
- package/dist/session/summary/deliverable.d.ts.map +1 -0
- package/dist/session/summary/deliverable.js +20 -0
- package/dist/session/summary/deliverable.js.map +1 -0
- package/dist/session/summary/index.d.ts +6 -0
- package/dist/session/summary/index.d.ts.map +1 -0
- package/dist/session/summary/index.js +9 -0
- package/dist/session/summary/index.js.map +1 -0
- package/dist/session/summary/materialize.d.ts +82 -0
- package/dist/session/summary/materialize.d.ts.map +1 -0
- package/dist/session/summary/materialize.js +117 -0
- package/dist/session/summary/materialize.js.map +1 -0
- package/dist/session/summary/ref.d.ts +91 -0
- package/dist/session/summary/ref.d.ts.map +1 -0
- package/dist/session/summary/ref.js +51 -0
- package/dist/session/summary/ref.js.map +1 -0
- package/dist/session/workspace/__tests__/git-worktree.test.d.ts +2 -0
- package/dist/session/workspace/__tests__/git-worktree.test.d.ts.map +1 -0
- package/dist/session/workspace/__tests__/git-worktree.test.js +244 -0
- package/dist/session/workspace/__tests__/git-worktree.test.js.map +1 -0
- package/dist/session/workspace/__tests__/path-builder.test.d.ts +2 -0
- package/dist/session/workspace/__tests__/path-builder.test.d.ts.map +1 -0
- package/dist/session/workspace/__tests__/path-builder.test.js +37 -0
- package/dist/session/workspace/__tests__/path-builder.test.js.map +1 -0
- package/dist/session/workspace/driver.d.ts +55 -0
- package/dist/session/workspace/driver.d.ts.map +1 -0
- package/dist/session/workspace/driver.js +12 -0
- package/dist/session/workspace/driver.js.map +1 -0
- package/dist/session/workspace/git-worktree.d.ts +65 -0
- package/dist/session/workspace/git-worktree.d.ts.map +1 -0
- package/dist/session/workspace/git-worktree.js +156 -0
- package/dist/session/workspace/git-worktree.js.map +1 -0
- package/dist/session/workspace/index.d.ts +8 -0
- package/dist/session/workspace/index.d.ts.map +1 -0
- package/dist/session/workspace/index.js +7 -0
- package/dist/session/workspace/index.js.map +1 -0
- package/dist/session/workspace/path-builder.d.ts +50 -0
- package/dist/session/workspace/path-builder.d.ts.map +1 -0
- package/dist/session/workspace/path-builder.js +50 -0
- package/dist/session/workspace/path-builder.js.map +1 -0
- package/dist/session/workspace/ref.d.ts +46 -0
- package/dist/session/workspace/ref.d.ts.map +1 -0
- package/dist/session/workspace/ref.js +11 -0
- package/dist/session/workspace/ref.js.map +1 -0
- package/dist/session/workspace/registry.d.ts +26 -0
- package/dist/session/workspace/registry.d.ts.map +1 -0
- package/dist/session/workspace/registry.js +35 -0
- package/dist/session/workspace/registry.js.map +1 -0
- package/dist/store/conversation/memory.d.ts +22 -0
- package/dist/store/conversation/memory.d.ts.map +1 -1
- package/dist/store/conversation/memory.js +22 -0
- package/dist/store/conversation/memory.js.map +1 -1
- package/dist/store/session/__tests__/disk.test.d.ts +2 -0
- package/dist/store/session/__tests__/disk.test.d.ts.map +1 -0
- package/dist/store/session/__tests__/disk.test.js +240 -0
- package/dist/store/session/__tests__/disk.test.js.map +1 -0
- package/dist/store/session/__tests__/memory.test.d.ts +2 -0
- package/dist/store/session/__tests__/memory.test.d.ts.map +1 -0
- package/dist/store/session/__tests__/memory.test.js +217 -0
- package/dist/store/session/__tests__/memory.test.js.map +1 -0
- package/dist/store/session/disk.d.ts +85 -0
- package/dist/store/session/disk.d.ts.map +1 -0
- package/dist/store/session/disk.js +757 -0
- package/dist/store/session/disk.js.map +1 -0
- package/dist/store/session/index.d.ts +7 -0
- package/dist/store/session/index.d.ts.map +1 -0
- package/dist/store/session/index.js +11 -0
- package/dist/store/session/index.js.map +1 -0
- package/dist/store/session/linkage.d.ts +38 -0
- package/dist/store/session/linkage.d.ts.map +1 -0
- package/dist/store/session/linkage.js +64 -0
- package/dist/store/session/linkage.js.map +1 -0
- package/dist/store/session/memory.d.ts +48 -0
- package/dist/store/session/memory.d.ts.map +1 -0
- package/dist/store/session/memory.js +322 -0
- package/dist/store/session/memory.js.map +1 -0
- package/dist/store/session/messages.d.ts +20 -0
- package/dist/store/session/messages.d.ts.map +1 -0
- package/dist/store/session/messages.js +12 -0
- package/dist/store/session/messages.js.map +1 -0
- package/dist/tools/builtins/__tests__/structuredOutput.example.d.ts +1 -1
- package/dist/types/agent/base.d.ts +28 -1
- package/dist/types/agent/base.d.ts.map +1 -1
- package/dist/types/agent/task.d.ts +50 -2
- package/dist/types/agent/task.d.ts.map +1 -1
- package/dist/types/agent/task.js.map +1 -1
- package/dist/types/conversation/index.d.ts +7 -0
- package/dist/types/conversation/index.d.ts.map +1 -1
- package/dist/types/ids/index.d.ts +26 -3
- package/dist/types/ids/index.d.ts.map +1 -1
- package/dist/types/ids/index.js +8 -1
- package/dist/types/ids/index.js.map +1 -1
- package/dist/types/invocation/__tests__/state.test.js +36 -29
- package/dist/types/invocation/__tests__/state.test.js.map +1 -1
- package/dist/types/invocation/index.d.ts +20 -4
- package/dist/types/invocation/index.d.ts.map +1 -1
- package/dist/types/invocation/index.js +10 -7
- package/dist/types/invocation/index.js.map +1 -1
- package/dist/types/run/config.d.ts +11 -1
- package/dist/types/run/config.d.ts.map +1 -1
- package/dist/types/run/events.d.ts +26 -1
- package/dist/types/run/events.d.ts.map +1 -1
- package/dist/types/run/index.d.ts.map +1 -1
- package/dist/types/run/index.js +8 -0
- package/dist/types/run/index.js.map +1 -1
- package/dist/types/run/metadata.d.ts +24 -1
- package/dist/types/run/metadata.d.ts.map +1 -1
- package/dist/types/run/status.d.ts +26 -0
- package/dist/types/run/status.d.ts.map +1 -0
- package/dist/types/run/status.js +2 -0
- package/dist/types/run/status.js.map +1 -0
- package/dist/types/session/ids.d.ts +18 -0
- package/dist/types/session/ids.d.ts.map +1 -0
- package/dist/types/session/ids.js +12 -0
- package/dist/types/session/ids.js.map +1 -0
- package/dist/types/session/index.d.ts +3 -0
- package/dist/types/session/index.d.ts.map +1 -0
- package/dist/types/session/index.js +5 -0
- package/dist/types/session/index.js.map +1 -0
- package/dist/types/session/store.d.ts +188 -0
- package/dist/types/session/store.d.ts.map +1 -0
- package/dist/types/session/store.js +14 -0
- package/dist/types/session/store.js.map +1 -0
- package/dist/utils/id.d.ts +18 -1
- package/dist/utils/id.d.ts.map +1 -1
- package/dist/utils/id.js +42 -4
- package/dist/utils/id.js.map +1 -1
- package/package.json +1 -1
- package/src/agents/ReactiveAgent.ts +7 -3
- package/src/agents/RouterAgent.ts +5 -0
- package/src/agents/SupervisorAgent.ts +26 -6
- package/src/bridge/a2a/mapper.ts +7 -0
- package/src/bridge/a2a/task.ts +2 -2
- package/src/bridge/sse/mapper.ts +8 -1
- package/src/constants/a2a/index.ts +2 -2
- package/src/contracts/api.ts +23 -3
- package/src/contracts/index.ts +2 -0
- package/src/gateway/local.ts +6 -0
- package/src/index.ts +14 -0
- package/src/manager/agent/__tests__/lifecycle.test.ts +452 -0
- package/src/manager/agent/lifecycle.ts +434 -19
- package/src/manager/run/persistence.ts +20 -1
- package/src/run/reporter.ts +28 -0
- package/src/runtime/query/__tests__/context.test.ts +101 -0
- package/src/runtime/query/context.ts +106 -10
- package/src/runtime/query/events.ts +8 -0
- package/src/runtime/query/index.ts +41 -3
- package/src/session/__tests__/integration/_fixtures.ts +282 -0
- package/src/session/__tests__/integration/capacity-caps.test.ts +164 -0
- package/src/session/__tests__/integration/e2e-spawn.test.ts +278 -0
- package/src/session/__tests__/integration/event-stream-ordering.test.ts +403 -0
- package/src/session/__tests__/integration/handoff-broadcast-e2e.test.ts +245 -0
- package/src/session/__tests__/integration/handoff-illegal-transition.test.ts +179 -0
- package/src/session/__tests__/integration/handoff-single-e2e.test.ts +220 -0
- package/src/session/__tests__/integration/hierarchy-lifecycle.test.ts +237 -0
- package/src/session/__tests__/integration/migration-filesystem.test.ts +209 -0
- package/src/session/__tests__/integration/migration-id-prefix.test.ts +101 -0
- package/src/session/__tests__/integration/prev-artifact-dag.test.ts +318 -0
- package/src/session/__tests__/integration/retention-archive.test.ts +231 -0
- package/src/session/__tests__/integration/summary-materialization-e2e.test.ts +237 -0
- package/src/session/__tests__/integration/tenant-isolation.test.ts +282 -0
- package/src/session/errors.ts +70 -0
- package/src/session/events/index.ts +16 -0
- package/src/session/events/schema-version.ts +13 -0
- package/src/session/events/types.ts +71 -0
- package/src/session/handoff/__tests__/broadcast.test.ts +350 -0
- package/src/session/handoff/__tests__/capacity.test.ts +123 -0
- package/src/session/handoff/__tests__/single.test.ts +316 -0
- package/src/session/handoff/assignment.ts +62 -0
- package/src/session/handoff/broadcast.ts +381 -0
- package/src/session/handoff/capacity.ts +121 -0
- package/src/session/handoff/events.ts +72 -0
- package/src/session/handoff/index.ts +29 -0
- package/src/session/handoff/single.ts +288 -0
- package/src/session/handoff/version.ts +59 -0
- package/src/session/hierarchy/__tests__/session.test.ts +92 -0
- package/src/session/hierarchy/actor.ts +17 -0
- package/src/session/hierarchy/index.ts +17 -0
- package/src/session/hierarchy/lineage.ts +15 -0
- package/src/session/hierarchy/project.ts +41 -0
- package/src/session/hierarchy/session.ts +97 -0
- package/src/session/hierarchy/sub-session.ts +92 -0
- package/src/session/hierarchy/tenant.ts +13 -0
- package/src/session/index.ts +15 -0
- package/src/session/intervention/__tests__/prev-artifact.test.ts +234 -0
- package/src/session/intervention/index.ts +16 -0
- package/src/session/intervention/prev-artifact.ts +180 -0
- package/src/session/migration/__tests__/filesystem.test.ts +263 -0
- package/src/session/migration/__tests__/id-prefix.test.ts +101 -0
- package/src/session/migration/__tests__/marker.test.ts +84 -0
- package/src/session/migration/errors.ts +23 -0
- package/src/session/migration/filesystem.ts +401 -0
- package/src/session/migration/id-prefix.ts +146 -0
- package/src/session/migration/index.ts +38 -0
- package/src/session/migration/marker.ts +131 -0
- package/src/session/retention/__tests__/archive.test.ts +316 -0
- package/src/session/retention/__tests__/disk-backend.test.ts +180 -0
- package/src/session/retention/archive-backend-ref.ts +17 -0
- package/src/session/retention/archive.ts +281 -0
- package/src/session/retention/backend.ts +107 -0
- package/src/session/retention/disk-backend.ts +304 -0
- package/src/session/retention/index.ts +16 -0
- package/src/session/retention/policy.ts +53 -0
- package/src/session/summary/__tests__/materialize.test.ts +341 -0
- package/src/session/summary/deliverable.ts +84 -0
- package/src/session/summary/index.ts +31 -0
- package/src/session/summary/materialize.ts +169 -0
- package/src/session/summary/ref.ts +104 -0
- package/src/session/workspace/__tests__/git-worktree.test.ts +258 -0
- package/src/session/workspace/__tests__/path-builder.test.ts +51 -0
- package/src/session/workspace/driver.ts +60 -0
- package/src/session/workspace/git-worktree.ts +209 -0
- package/src/session/workspace/index.ts +25 -0
- package/src/session/workspace/path-builder.ts +71 -0
- package/src/session/workspace/ref.ts +50 -0
- package/src/session/workspace/registry.ts +42 -0
- package/src/store/conversation/memory.ts +23 -0
- package/src/store/session/__tests__/disk.test.ts +346 -0
- package/src/store/session/__tests__/memory.test.ts +327 -0
- package/src/store/session/disk.ts +920 -0
- package/src/store/session/index.ts +14 -0
- package/src/store/session/linkage.ts +80 -0
- package/src/store/session/memory.ts +400 -0
- package/src/store/session/messages.ts +21 -0
- package/src/types/agent/base.ts +31 -1
- package/src/types/agent/task.ts +58 -2
- package/src/types/conversation/index.ts +7 -0
- package/src/types/ids/index.ts +41 -3
- package/src/types/invocation/__tests__/state.test.ts +37 -29
- package/src/types/invocation/index.ts +26 -10
- package/src/types/run/config.ts +12 -1
- package/src/types/run/events.ts +36 -1
- package/src/types/run/index.ts +8 -0
- package/src/types/run/metadata.ts +24 -1
- package/src/types/run/status.ts +33 -0
- package/src/types/session/ids.ts +34 -0
- package/src/types/session/index.ts +28 -0
- package/src/types/session/store.ts +229 -0
- package/src/utils/id.ts +55 -4
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Sub-barrel for the workspace module (Convention #4).
|
|
2
|
+
// Concrete types + driver implementation live in sibling files; re-export
|
|
3
|
+
// them here so other modules import via `../session/workspace/index.js`.
|
|
4
|
+
|
|
5
|
+
export type {
|
|
6
|
+
WorkspaceRef,
|
|
7
|
+
WorkspaceBackendMeta,
|
|
8
|
+
WorkspaceBackendKind,
|
|
9
|
+
GitWorktreeBackendMeta,
|
|
10
|
+
} from './ref.js'
|
|
11
|
+
|
|
12
|
+
export type {
|
|
13
|
+
WorkspaceBackendDriver,
|
|
14
|
+
CreateWorkspaceParams,
|
|
15
|
+
BranchWorkspaceParams,
|
|
16
|
+
WorkspaceInspection,
|
|
17
|
+
} from './driver.js'
|
|
18
|
+
|
|
19
|
+
export { DefaultPathBuilder } from './path-builder.js'
|
|
20
|
+
export type { PathBuilder } from './path-builder.js'
|
|
21
|
+
|
|
22
|
+
export { WorkspaceBackendRegistry } from './registry.js'
|
|
23
|
+
|
|
24
|
+
export { GitWorktreeDriver, parseWorktreeList } from './git-worktree.js'
|
|
25
|
+
export type { ExecFile, ExecFileResult, GitWorktreeDriverConfig } from './git-worktree.js'
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PathBuilder — canonical filesystem layout generator for the session
|
|
3
|
+
* hierarchy.
|
|
4
|
+
*
|
|
5
|
+
* Replaces the hardcoded `.namzu/threads/{threadId}/runs` path at
|
|
6
|
+
* `runtime/query/context.ts:60-64`. Phase 3 ships the abstraction; wiring
|
|
7
|
+
* into the factory happens in Phase 6 (sub-session spawn refactor) so the
|
|
8
|
+
* cutover is atomic with the new `projectId` / `sessionId` requirements
|
|
9
|
+
* (Convention #0: no dual paths).
|
|
10
|
+
*
|
|
11
|
+
* Layout matches session-hierarchy.md §13.4 (on-disk layout after migration):
|
|
12
|
+
*
|
|
13
|
+
* {rootDir}/projects/{projectId}/
|
|
14
|
+
* project.json
|
|
15
|
+
* sessions/{sessionId}/
|
|
16
|
+
* session.json
|
|
17
|
+
* messages.jsonl
|
|
18
|
+
* subsessions/{subSessionId}/
|
|
19
|
+
* subsession.json
|
|
20
|
+
* runs/{runId}/
|
|
21
|
+
* ... (Run-pattern owned; unchanged internally)
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
import { join } from 'node:path'
|
|
25
|
+
import type { ProjectId, RunId, SessionId } from '../../types/ids/index.js'
|
|
26
|
+
import type { SubSessionId } from '../../types/session/ids.js'
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Canonical filesystem layout contract. All paths returned are absolute
|
|
30
|
+
* when `root` is absolute (recommended); consumers treat them as opaque.
|
|
31
|
+
*/
|
|
32
|
+
export interface PathBuilder {
|
|
33
|
+
rootDir(): string
|
|
34
|
+
projectDir(projectId: ProjectId): string
|
|
35
|
+
sessionDir(projectId: ProjectId, sessionId: SessionId): string
|
|
36
|
+
subSessionDir(projectId: ProjectId, sessionId: SessionId, subSessionId: SubSessionId): string
|
|
37
|
+
runDir(projectId: ProjectId, sessionId: SessionId, runId: RunId): string
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Default implementation over `node:path.join`. The `root` constructor
|
|
42
|
+
* argument is injected by the consumer (e.g. `join(cwd, '.namzu')`); no
|
|
43
|
+
* process-global fallback — the kernel refuses to guess paths.
|
|
44
|
+
*/
|
|
45
|
+
export class DefaultPathBuilder implements PathBuilder {
|
|
46
|
+
private readonly root: string
|
|
47
|
+
|
|
48
|
+
constructor(root: string) {
|
|
49
|
+
this.root = root
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
rootDir(): string {
|
|
53
|
+
return this.root
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
projectDir(projectId: ProjectId): string {
|
|
57
|
+
return join(this.root, 'projects', projectId)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
sessionDir(projectId: ProjectId, sessionId: SessionId): string {
|
|
61
|
+
return join(this.projectDir(projectId), 'sessions', sessionId)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
subSessionDir(projectId: ProjectId, sessionId: SessionId, subSessionId: SubSessionId): string {
|
|
65
|
+
return join(this.sessionDir(projectId, sessionId), 'subsessions', subSessionId)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
runDir(projectId: ProjectId, sessionId: SessionId, runId: RunId): string {
|
|
69
|
+
return join(this.sessionDir(projectId, sessionId), 'runs', runId)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WorkspaceRef + backend metadata.
|
|
3
|
+
*
|
|
4
|
+
* See session-hierarchy.md §4.9 (WorkspaceRef) and §7 (Workspace and
|
|
5
|
+
* Worktree). The `meta` field is a discriminated union on `backend` — Phase 3
|
|
6
|
+
* ships the `git-worktree` variant; `tmpfs`, `container`, and `shared` land
|
|
7
|
+
* in a later phase of the overall roadmap (post-MVP) without breaking
|
|
8
|
+
* existing consumers (Convention #6).
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type { WorkspaceId } from '../../types/session/ids.js'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Supported backend kinds. Additional variants are append-only; existing
|
|
15
|
+
* consumers switch with an `_exhaustive` never-guard and will fail to compile
|
|
16
|
+
* when the union grows — paired with the update at the discriminated
|
|
17
|
+
* {@link WorkspaceBackendMeta} site (Convention #6).
|
|
18
|
+
*/
|
|
19
|
+
export type WorkspaceBackendKind = 'git-worktree' | 'tmpfs' | 'container' | 'shared'
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Git-worktree backend metadata. Matches session-hierarchy.md §4.9 /§7.2.
|
|
23
|
+
*/
|
|
24
|
+
export interface GitWorktreeBackendMeta {
|
|
25
|
+
backend: 'git-worktree'
|
|
26
|
+
/** Absolute path to the canonical repo (`.git` directory). */
|
|
27
|
+
repoRoot: string
|
|
28
|
+
/** Branch / ref the worktree tracks. */
|
|
29
|
+
branch: string
|
|
30
|
+
/** Absolute path to the worktree directory. */
|
|
31
|
+
worktreePath: string
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Discriminated union of backend-specific metadata. Only `git-worktree` is
|
|
36
|
+
* populated in Phase 3. Future variants (tmpfs, container, shared) must be
|
|
37
|
+
* added here and to every exhaustive consumer.
|
|
38
|
+
*/
|
|
39
|
+
export type WorkspaceBackendMeta = GitWorktreeBackendMeta
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Persisted ref to a provisioned workspace. Every {@link Session} with a
|
|
43
|
+
* running Run persists a {@link WorkspaceRef} so recovery after process
|
|
44
|
+
* restart is possible (session-hierarchy.md §7.1).
|
|
45
|
+
*/
|
|
46
|
+
export interface WorkspaceRef {
|
|
47
|
+
id: WorkspaceId
|
|
48
|
+
meta: WorkspaceBackendMeta
|
|
49
|
+
createdAt: Date
|
|
50
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WorkspaceBackendRegistry — deny-by-default driver lookup.
|
|
3
|
+
*
|
|
4
|
+
* Convention #9 (Registry + Manager + Store): this is the Registry for
|
|
5
|
+
* {@link WorkspaceBackendDriver} implementations. Unknown kinds throw
|
|
6
|
+
* — no silent fallback (Convention #5).
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { WorkspaceBackendDriver, WorkspaceBackendKind } from './driver.js'
|
|
10
|
+
|
|
11
|
+
export class WorkspaceBackendRegistry {
|
|
12
|
+
private readonly drivers = new Map<WorkspaceBackendKind, WorkspaceBackendDriver>()
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Registers a driver. A second registration for the same kind replaces the
|
|
16
|
+
* previous entry (test ergonomics); production code should register each
|
|
17
|
+
* backend exactly once at boot.
|
|
18
|
+
*/
|
|
19
|
+
register(driver: WorkspaceBackendDriver): void {
|
|
20
|
+
this.drivers.set(driver.kind, driver)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Returns the driver for `kind`. Throws when no driver is registered —
|
|
25
|
+
* deny-by-default per Convention #5; the caller must register every
|
|
26
|
+
* backend their workload can reach before invoking this.
|
|
27
|
+
*/
|
|
28
|
+
get(kind: WorkspaceBackendKind): WorkspaceBackendDriver {
|
|
29
|
+
const driver = this.drivers.get(kind)
|
|
30
|
+
if (!driver) {
|
|
31
|
+
throw new Error(
|
|
32
|
+
`No WorkspaceBackendDriver registered for kind "${kind}". Register one before use.`,
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
return driver
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** True iff a driver for `kind` has been registered. */
|
|
39
|
+
has(kind: WorkspaceBackendKind): boolean {
|
|
40
|
+
return this.drivers.has(kind)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @deprecated Use `InMemorySessionStore` from
|
|
3
|
+
* `@namzu/sdk/store/session`. This class implements the deprecated
|
|
4
|
+
* `ConversationStore` contract (thread-scoped, no tenantId) and is kept
|
|
5
|
+
* for one migration window per session-hierarchy.md §13.1; it will be
|
|
6
|
+
* removed in 0.3.0.
|
|
7
|
+
*
|
|
8
|
+
* INTERPRETATION (Phase 3): the old class exposes helpers
|
|
9
|
+
* (`addUserMessage`, `createThread`, `hasThread`, `deleteThread`,
|
|
10
|
+
* `messageCount`, `clear`) that are not part of `ConversationStore` and
|
|
11
|
+
* whose signatures rely on `ThreadId` + `Message` without `TenantId`.
|
|
12
|
+
* Those signatures are structurally incompatible with the new
|
|
13
|
+
* `SessionStore` surface, so a strict alias re-export would lose API
|
|
14
|
+
* (roadmap §2 Phase 3 option (a)). We pick option (b) — retain the
|
|
15
|
+
* original class body verbatim with a deprecation banner — to preserve
|
|
16
|
+
* existing consumers during the migration window without polluting the
|
|
17
|
+
* new `InMemorySessionStore` with thread-scoped helpers.
|
|
18
|
+
*/
|
|
19
|
+
|
|
1
20
|
import { findSafeTrimIndex } from '../../compaction/dangling.js'
|
|
2
21
|
import type { ConversationStore } from '../../types/conversation/index.js'
|
|
3
22
|
import type { MessageId, RunId, ThreadId } from '../../types/ids/index.js'
|
|
@@ -27,6 +46,10 @@ export interface InMemoryConversationStoreConfig {
|
|
|
27
46
|
readonly maxMessages?: number
|
|
28
47
|
}
|
|
29
48
|
|
|
49
|
+
/**
|
|
50
|
+
* @deprecated See module banner. Use `InMemorySessionStore` from
|
|
51
|
+
* `@namzu/sdk/store/session`.
|
|
52
|
+
*/
|
|
30
53
|
export class InMemoryConversationStore implements ConversationStore {
|
|
31
54
|
private readonly threads = new Map<ThreadId, ConversationMessage[]>()
|
|
32
55
|
private readonly maxMessages: number
|
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
import { mkdtempSync, rmSync } from 'node:fs'
|
|
2
|
+
import { readFile, readdir } from 'node:fs/promises'
|
|
3
|
+
import { tmpdir } from 'node:os'
|
|
4
|
+
import { join } from 'node:path'
|
|
5
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest'
|
|
6
|
+
import { TenantIsolationError } from '../../../session/errors.js'
|
|
7
|
+
import type { ActorRef } from '../../../session/hierarchy/actor.js'
|
|
8
|
+
import type { AgentId, TenantId, UserId } from '../../../types/ids/index.js'
|
|
9
|
+
import { createUserMessage } from '../../../types/message/index.js'
|
|
10
|
+
import { DiskSessionStore } from '../disk.js'
|
|
11
|
+
|
|
12
|
+
const tenantA = 'tnt_alpha' as TenantId
|
|
13
|
+
const tenantB = 'tnt_beta' as TenantId
|
|
14
|
+
|
|
15
|
+
function userActor(tenantId: TenantId): ActorRef {
|
|
16
|
+
return { kind: 'user', userId: 'usr_a' as UserId, tenantId }
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function agentActor(tenantId: TenantId): ActorRef {
|
|
20
|
+
return { kind: 'agent', agentId: 'agt_a' as AgentId, tenantId }
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
async function seed(store: DiskSessionStore, tenantId: TenantId) {
|
|
24
|
+
const project = await store.createProject({ tenantId, name: 'p1' }, tenantId)
|
|
25
|
+
const session = await store.createSession(
|
|
26
|
+
{ projectId: project.id, currentActor: userActor(tenantId) },
|
|
27
|
+
tenantId,
|
|
28
|
+
)
|
|
29
|
+
return { project, session }
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
describe('DiskSessionStore', () => {
|
|
33
|
+
let rootDir: string
|
|
34
|
+
let store: DiskSessionStore
|
|
35
|
+
|
|
36
|
+
beforeEach(() => {
|
|
37
|
+
rootDir = mkdtempSync(join(tmpdir(), 'namzu-session-disk-'))
|
|
38
|
+
store = new DiskSessionStore({ rootDir })
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
afterEach(() => {
|
|
42
|
+
rmSync(rootDir, { recursive: true, force: true })
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
it('writes the canonical directory layout (projects/.../sessions/.../subsessions)', async () => {
|
|
46
|
+
const { project, session } = await seed(store, tenantA)
|
|
47
|
+
const child = await store.createSession(
|
|
48
|
+
{ projectId: project.id, currentActor: agentActor(tenantA) },
|
|
49
|
+
tenantA,
|
|
50
|
+
)
|
|
51
|
+
const sub = await store.createSubSession(
|
|
52
|
+
{
|
|
53
|
+
parentSessionId: session.id,
|
|
54
|
+
childSessionId: child.id,
|
|
55
|
+
kind: 'agent_spawn',
|
|
56
|
+
spawnedBy: userActor(tenantA),
|
|
57
|
+
},
|
|
58
|
+
tenantA,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
const projectJson = join(rootDir, 'projects', project.id, 'project.json')
|
|
62
|
+
const sessionJson = join(
|
|
63
|
+
rootDir,
|
|
64
|
+
'projects',
|
|
65
|
+
project.id,
|
|
66
|
+
'sessions',
|
|
67
|
+
session.id,
|
|
68
|
+
'session.json',
|
|
69
|
+
)
|
|
70
|
+
const subJson = join(
|
|
71
|
+
rootDir,
|
|
72
|
+
'projects',
|
|
73
|
+
project.id,
|
|
74
|
+
'sessions',
|
|
75
|
+
session.id,
|
|
76
|
+
'subsessions',
|
|
77
|
+
sub.id,
|
|
78
|
+
'subsession.json',
|
|
79
|
+
)
|
|
80
|
+
expect(JSON.parse(await readFile(projectJson, 'utf-8')).id).toBe(project.id)
|
|
81
|
+
expect(JSON.parse(await readFile(sessionJson, 'utf-8')).id).toBe(session.id)
|
|
82
|
+
expect(JSON.parse(await readFile(subJson, 'utf-8')).id).toBe(sub.id)
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
it('round-trips a session across store instances (cold read)', async () => {
|
|
86
|
+
const { project, session } = await seed(store, tenantA)
|
|
87
|
+
|
|
88
|
+
// Construct a fresh store against the same rootDir — must find the session.
|
|
89
|
+
const fresh = new DiskSessionStore({ rootDir })
|
|
90
|
+
const reloaded = await fresh.getSession(session.id, tenantA)
|
|
91
|
+
expect(reloaded).not.toBeNull()
|
|
92
|
+
expect(reloaded?.id).toBe(session.id)
|
|
93
|
+
expect(reloaded?.projectId).toBe(project.id)
|
|
94
|
+
expect(reloaded?.currentActor?.kind).toBe('user')
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
it('writes are atomic: no *.tmp file remains after mutation', async () => {
|
|
98
|
+
const { project, session } = await seed(store, tenantA)
|
|
99
|
+
await store.updateSession({ ...session, status: 'active' }, tenantA)
|
|
100
|
+
|
|
101
|
+
// Recursively list everything under rootDir and ensure no lingering .tmp
|
|
102
|
+
async function walk(dir: string, out: string[]): Promise<void> {
|
|
103
|
+
for (const entry of await readdir(dir, { withFileTypes: true })) {
|
|
104
|
+
const path = join(dir, entry.name)
|
|
105
|
+
out.push(path)
|
|
106
|
+
if (entry.isDirectory()) await walk(path, out)
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
const files: string[] = []
|
|
110
|
+
await walk(rootDir, files)
|
|
111
|
+
expect(files.some((p) => p.endsWith('.tmp'))).toBe(false)
|
|
112
|
+
expect(files).toContain(
|
|
113
|
+
join(rootDir, 'projects', project.id, 'sessions', session.id, 'session.json'),
|
|
114
|
+
)
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
it('rejects cross-tenant reads of persisted sessions', async () => {
|
|
118
|
+
const { session } = await seed(store, tenantA)
|
|
119
|
+
await expect(store.getSession(session.id, tenantB)).rejects.toBeInstanceOf(TenantIsolationError)
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
it('appendMessage + loadMessages round-trips via messages.jsonl', async () => {
|
|
123
|
+
const { project, session } = await seed(store, tenantA)
|
|
124
|
+
await store.appendMessage(session.id, createUserMessage('hello'), tenantA)
|
|
125
|
+
await store.appendMessage(session.id, createUserMessage('world'), tenantA)
|
|
126
|
+
|
|
127
|
+
const loaded = await store.loadMessages(session.id, tenantA)
|
|
128
|
+
expect(loaded.map((m) => m.content)).toEqual(['hello', 'world'])
|
|
129
|
+
|
|
130
|
+
const jsonl = await readFile(
|
|
131
|
+
join(rootDir, 'projects', project.id, 'sessions', session.id, 'messages.jsonl'),
|
|
132
|
+
'utf-8',
|
|
133
|
+
)
|
|
134
|
+
const lines = jsonl.split('\n').filter((l) => l.length > 0)
|
|
135
|
+
expect(lines).toHaveLength(2)
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
it('loadMessages returns [] when no messages yet persisted', async () => {
|
|
139
|
+
const { session } = await seed(store, tenantA)
|
|
140
|
+
expect(await store.loadMessages(session.id, tenantA)).toEqual([])
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
it('drill returns children and ancestry after a cold reload', async () => {
|
|
144
|
+
const { project, session: root } = await seed(store, tenantA)
|
|
145
|
+
const child = await store.createSession(
|
|
146
|
+
{ projectId: project.id, currentActor: agentActor(tenantA) },
|
|
147
|
+
tenantA,
|
|
148
|
+
)
|
|
149
|
+
await store.createSubSession(
|
|
150
|
+
{
|
|
151
|
+
parentSessionId: root.id,
|
|
152
|
+
childSessionId: child.id,
|
|
153
|
+
kind: 'agent_spawn',
|
|
154
|
+
spawnedBy: userActor(tenantA),
|
|
155
|
+
},
|
|
156
|
+
tenantA,
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
const fresh = new DiskSessionStore({ rootDir })
|
|
160
|
+
const rootView = await fresh.drill(root.id, tenantA)
|
|
161
|
+
expect(rootView?.children.map((c) => c.childSessionId)).toEqual([child.id])
|
|
162
|
+
|
|
163
|
+
const childView = await fresh.drill(child.id, tenantA)
|
|
164
|
+
expect(childView?.ancestry).toEqual([root.id, child.id])
|
|
165
|
+
})
|
|
166
|
+
|
|
167
|
+
it('missing session returns null rather than throwing', async () => {
|
|
168
|
+
const fresh = new DiskSessionStore({ rootDir })
|
|
169
|
+
expect(await fresh.getSession('ses_missing' as SessionId, tenantA)).toBeNull()
|
|
170
|
+
})
|
|
171
|
+
|
|
172
|
+
// Summary (§4.7 / §8.1) ---------------------------------------------------
|
|
173
|
+
|
|
174
|
+
it('recordSummary persists summary.json and flips session status atomically', async () => {
|
|
175
|
+
const { project, session } = await seed(store, tenantA)
|
|
176
|
+
await store.updateSession({ ...session, status: 'active' }, tenantA)
|
|
177
|
+
|
|
178
|
+
const summary: SessionSummaryRef & { materializedBy: 'kernel' } = {
|
|
179
|
+
id: 'sum_disk1' as SummaryId,
|
|
180
|
+
sessionRef: session.id,
|
|
181
|
+
tenantId: tenantA,
|
|
182
|
+
outcome: { status: 'succeeded' },
|
|
183
|
+
deliverables: [],
|
|
184
|
+
agentSummary: 'done',
|
|
185
|
+
keyDecisions: [],
|
|
186
|
+
at: new Date('2026-04-17T00:00:00Z'),
|
|
187
|
+
materializedBy: 'kernel',
|
|
188
|
+
}
|
|
189
|
+
await store.recordSummary(summary, tenantA)
|
|
190
|
+
|
|
191
|
+
const summaryJson = join(
|
|
192
|
+
rootDir,
|
|
193
|
+
'projects',
|
|
194
|
+
project.id,
|
|
195
|
+
'sessions',
|
|
196
|
+
session.id,
|
|
197
|
+
'summary.json',
|
|
198
|
+
)
|
|
199
|
+
const rawSummary = JSON.parse(await readFile(summaryJson, 'utf-8'))
|
|
200
|
+
expect(rawSummary.id).toBe('sum_disk1')
|
|
201
|
+
expect(rawSummary.materializedBy).toBe('kernel')
|
|
202
|
+
|
|
203
|
+
const reloadedSession = await store.getSession(session.id, tenantA)
|
|
204
|
+
expect(reloadedSession?.status).toBe('idle')
|
|
205
|
+
})
|
|
206
|
+
|
|
207
|
+
it('recordSummary is idempotent when replaying the same summary (recovery)', async () => {
|
|
208
|
+
const { session } = await seed(store, tenantA)
|
|
209
|
+
await store.updateSession({ ...session, status: 'active' }, tenantA)
|
|
210
|
+
|
|
211
|
+
const summary: SessionSummaryRef & { materializedBy: 'kernel' } = {
|
|
212
|
+
id: 'sum_disk2' as SummaryId,
|
|
213
|
+
sessionRef: session.id,
|
|
214
|
+
tenantId: tenantA,
|
|
215
|
+
outcome: { status: 'succeeded' },
|
|
216
|
+
deliverables: [],
|
|
217
|
+
agentSummary: '',
|
|
218
|
+
keyDecisions: [],
|
|
219
|
+
at: new Date('2026-04-17T00:00:00Z'),
|
|
220
|
+
materializedBy: 'kernel',
|
|
221
|
+
}
|
|
222
|
+
await store.recordSummary(summary, tenantA)
|
|
223
|
+
|
|
224
|
+
// Force session back to active (simulating a crash mid-flip).
|
|
225
|
+
const mid = await store.getSession(session.id, tenantA)
|
|
226
|
+
if (!mid) throw new Error('mid session missing')
|
|
227
|
+
await store.updateSession({ ...mid, status: 'active' }, tenantA)
|
|
228
|
+
|
|
229
|
+
// Replay with the same summary — no throw, status flips again.
|
|
230
|
+
await store.recordSummary(summary, tenantA)
|
|
231
|
+
const after = await store.getSession(session.id, tenantA)
|
|
232
|
+
expect(after?.status).toBe('idle')
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
it('recordSummary rejects a different summary for an already-summarized session', async () => {
|
|
236
|
+
const { session } = await seed(store, tenantA)
|
|
237
|
+
const first: SessionSummaryRef & { materializedBy: 'kernel' } = {
|
|
238
|
+
id: 'sum_disk3a' as SummaryId,
|
|
239
|
+
sessionRef: session.id,
|
|
240
|
+
tenantId: tenantA,
|
|
241
|
+
outcome: { status: 'succeeded' },
|
|
242
|
+
deliverables: [],
|
|
243
|
+
agentSummary: '',
|
|
244
|
+
keyDecisions: [],
|
|
245
|
+
at: new Date(),
|
|
246
|
+
materializedBy: 'kernel',
|
|
247
|
+
}
|
|
248
|
+
await store.recordSummary(first, tenantA)
|
|
249
|
+
|
|
250
|
+
const second = { ...first, id: 'sum_disk3b' as SummaryId }
|
|
251
|
+
await expect(store.recordSummary(second, tenantA)).rejects.toMatchObject({
|
|
252
|
+
name: 'SessionAlreadySummarizedError',
|
|
253
|
+
})
|
|
254
|
+
})
|
|
255
|
+
|
|
256
|
+
it('deleteSession removes the session directory recursively', async () => {
|
|
257
|
+
const { project, session } = await seed(store, tenantA)
|
|
258
|
+
await store.appendMessage(session.id, createUserMessage('hi'), tenantA)
|
|
259
|
+
|
|
260
|
+
await store.deleteSession(session.id, tenantA)
|
|
261
|
+
|
|
262
|
+
const sessionDir = join(rootDir, 'projects', project.id, 'sessions', session.id)
|
|
263
|
+
// Directory should be gone.
|
|
264
|
+
const sessionsDirListing = await readdir(join(rootDir, 'projects', project.id, 'sessions'))
|
|
265
|
+
expect(sessionsDirListing).not.toContain(session.id)
|
|
266
|
+
// Session read returns null.
|
|
267
|
+
expect(await store.getSession(session.id, tenantA)).toBeNull()
|
|
268
|
+
// Path sanity: no ghost file at the session path.
|
|
269
|
+
void sessionDir
|
|
270
|
+
})
|
|
271
|
+
|
|
272
|
+
it('deleteSession tolerates missing session directory (idempotent)', async () => {
|
|
273
|
+
await expect(
|
|
274
|
+
store.deleteSession('ses_nonexistent' as SessionId, tenantA),
|
|
275
|
+
).resolves.toBeUndefined()
|
|
276
|
+
})
|
|
277
|
+
|
|
278
|
+
it('deleteSession rejects if sub-sessions are still attached', async () => {
|
|
279
|
+
const { project, session: root } = await seed(store, tenantA)
|
|
280
|
+
const child = await store.createSession(
|
|
281
|
+
{ projectId: project.id, currentActor: agentActor(tenantA) },
|
|
282
|
+
tenantA,
|
|
283
|
+
)
|
|
284
|
+
await store.createSubSession(
|
|
285
|
+
{
|
|
286
|
+
parentSessionId: root.id,
|
|
287
|
+
childSessionId: child.id,
|
|
288
|
+
kind: 'agent_spawn',
|
|
289
|
+
spawnedBy: userActor(tenantA),
|
|
290
|
+
},
|
|
291
|
+
tenantA,
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
await expect(store.deleteSession(root.id, tenantA)).rejects.toThrow(/attached sub-sessions/)
|
|
295
|
+
})
|
|
296
|
+
|
|
297
|
+
it('deleteSubSession removes the sub-session directory and is idempotent', async () => {
|
|
298
|
+
const { project, session: root } = await seed(store, tenantA)
|
|
299
|
+
const child = await store.createSession(
|
|
300
|
+
{ projectId: project.id, currentActor: agentActor(tenantA) },
|
|
301
|
+
tenantA,
|
|
302
|
+
)
|
|
303
|
+
const sub = await store.createSubSession(
|
|
304
|
+
{
|
|
305
|
+
parentSessionId: root.id,
|
|
306
|
+
childSessionId: child.id,
|
|
307
|
+
kind: 'agent_spawn',
|
|
308
|
+
spawnedBy: userActor(tenantA),
|
|
309
|
+
},
|
|
310
|
+
tenantA,
|
|
311
|
+
)
|
|
312
|
+
|
|
313
|
+
await store.deleteSubSession(sub.id, tenantA)
|
|
314
|
+
expect(await store.getSubSession(sub.id, tenantA)).toBeNull()
|
|
315
|
+
|
|
316
|
+
const subsDir = join(rootDir, 'projects', project.id, 'sessions', root.id, 'subsessions')
|
|
317
|
+
const listing = await readdir(subsDir).catch(() => [] as string[])
|
|
318
|
+
expect(listing).not.toContain(sub.id)
|
|
319
|
+
|
|
320
|
+
// Idempotent.
|
|
321
|
+
await expect(store.deleteSubSession(sub.id, tenantA)).resolves.toBeUndefined()
|
|
322
|
+
})
|
|
323
|
+
|
|
324
|
+
it('getSummary rejects cross-tenant reads', async () => {
|
|
325
|
+
const { session } = await seed(store, tenantA)
|
|
326
|
+
const summary: SessionSummaryRef & { materializedBy: 'kernel' } = {
|
|
327
|
+
id: 'sum_disk4' as SummaryId,
|
|
328
|
+
sessionRef: session.id,
|
|
329
|
+
tenantId: tenantA,
|
|
330
|
+
outcome: { status: 'succeeded' },
|
|
331
|
+
deliverables: [],
|
|
332
|
+
agentSummary: '',
|
|
333
|
+
keyDecisions: [],
|
|
334
|
+
at: new Date(),
|
|
335
|
+
materializedBy: 'kernel',
|
|
336
|
+
}
|
|
337
|
+
await store.recordSummary(summary, tenantA)
|
|
338
|
+
|
|
339
|
+
await expect(store.getSummary(session.id, tenantB)).rejects.toBeInstanceOf(TenantIsolationError)
|
|
340
|
+
})
|
|
341
|
+
})
|
|
342
|
+
|
|
343
|
+
import type { SessionSummaryRef } from '../../../session/summary/ref.js'
|
|
344
|
+
// Import after use so tests are self-contained w.r.t. types we already use.
|
|
345
|
+
import type { SessionId } from '../../../types/ids/index.js'
|
|
346
|
+
import type { SummaryId } from '../../../types/session/ids.js'
|