@namzu/sdk 0.1.7 → 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 +23 -5
- package/README.md +14 -9
- 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,319 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Boot-time filesystem re-layout — `.namzu/threads/{thd_X}/` →
|
|
3
|
+
* `.namzu/projects/{prj_legacy_<X>}/sessions/ses_legacy_default/runs/...`.
|
|
4
|
+
*
|
|
5
|
+
* Trigger: first {@link RunContextFactory.build} call per process. The
|
|
6
|
+
* factory invokes {@link DefaultFilesystemMigrator.migrate} before resolving
|
|
7
|
+
* any path so legacy runs are never orphaned by the new layout.
|
|
8
|
+
*
|
|
9
|
+
* See session-hierarchy.md §13.4.1 for the detection / trigger / atomicity
|
|
10
|
+
* contract. Concurrency model:
|
|
11
|
+
*
|
|
12
|
+
* 1. Main marker present → short-circuit `already_migrated`. Idempotent.
|
|
13
|
+
* 2. Legacy `.namzu/threads/` absent → write the main marker and return
|
|
14
|
+
* `noop_no_legacy`. This plants the marker on fresh installs so the
|
|
15
|
+
* `threads/` detection branch is only ever entered once.
|
|
16
|
+
* 3. Legacy layout detected → acquire the `.tmp` lock via `wx`; on
|
|
17
|
+
* EEXIST another boot is mid-migration. The loser waits 100ms and
|
|
18
|
+
* re-checks the main marker — cooperating, not competing. Roadmap
|
|
19
|
+
* Risk #4 mitigation.
|
|
20
|
+
* 4. Per-legacy-thread: rename the whole `runs/` subtree in a single
|
|
21
|
+
* `fs.rename` call (cross-OS atomic on the same filesystem; different
|
|
22
|
+
* filesystems fall back to copy-then-unlink via Node's default — a
|
|
23
|
+
* known limitation documented below).
|
|
24
|
+
* 5. Synthesize `project.json` + `session.json` via write-tmp-rename
|
|
25
|
+
* (Convention #8) so partial crashes leave no half-serialised state.
|
|
26
|
+
* 6. Write main marker last — presence of the marker is the canonical
|
|
27
|
+
* "migration done" signal.
|
|
28
|
+
*
|
|
29
|
+
* Known limitations:
|
|
30
|
+
* - Cross-filesystem moves: Node's `fs.rename` rejects with `EXDEV` when
|
|
31
|
+
* source and target live on different filesystems. This migrator does
|
|
32
|
+
* NOT fall back to copy-then-unlink; the error surfaces as
|
|
33
|
+
* {@link FilesystemMigrationError} with op `'rename_runs'`. Consumers
|
|
34
|
+
* running `.namzu/threads` and `.namzu/projects` on different mounts
|
|
35
|
+
* must migrate manually (documented INTERP flag).
|
|
36
|
+
* - `UNKNOWN_TENANT_ID`: legacy threads have no tenant denormalisation on
|
|
37
|
+
* disk. The synthesised project.json carries the sentinel so consumers
|
|
38
|
+
* know these are legacy-rehomed and can either tag-then-retain or
|
|
39
|
+
* reject until a real tenant is assigned (policy is consumer-owned).
|
|
40
|
+
*/
|
|
41
|
+
import { mkdir, readdir, rename, stat } from 'node:fs/promises';
|
|
42
|
+
import { join } from 'node:path';
|
|
43
|
+
import { UNKNOWN_TENANT_ID } from '../../types/ids/index.js';
|
|
44
|
+
import { FilesystemMigrationError } from './errors.js';
|
|
45
|
+
import { acquireMigrationLock, readMarker, releaseMigrationLock, writeMarker } from './marker.js';
|
|
46
|
+
/**
|
|
47
|
+
* Sentinel SessionId used for legacy pre-0.2.0 runs that pre-date the
|
|
48
|
+
* Session entity. Every migrated thread collapses into this single session
|
|
49
|
+
* so consumers can still address the runs through the new layout.
|
|
50
|
+
*/
|
|
51
|
+
export const LEGACY_DEFAULT_SESSION_ID = 'ses_legacy_default';
|
|
52
|
+
/** Prefix for projects synthesised from legacy `thd_*` folders. */
|
|
53
|
+
export const LEGACY_DEFAULT_PROJECT_PREFIX = 'prj_legacy_';
|
|
54
|
+
/** Marker version string persisted at `.migration/v0.2.0`. */
|
|
55
|
+
export const MIGRATION_VERSION = '0.2.0';
|
|
56
|
+
/** Marker file path relative to rootDir. */
|
|
57
|
+
export const MARKER_REL_PATH = join('.migration', 'v0.2.0');
|
|
58
|
+
/** In-flight lock file path relative to rootDir. */
|
|
59
|
+
export const LOCK_REL_PATH = join('.migration', 'v0.2.0.tmp');
|
|
60
|
+
/** Delay before the loser re-checks the main marker on lock contention. */
|
|
61
|
+
const LOCK_WAIT_MS = 100;
|
|
62
|
+
export const NOOP_FILESYSTEM_MIGRATION_SINK = {
|
|
63
|
+
emit() { },
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Default implementation. Migration is driven by the contract documented in
|
|
67
|
+
* the module header — readers should trace concerns to this comment rather
|
|
68
|
+
* than re-deriving from code.
|
|
69
|
+
*/
|
|
70
|
+
export class DefaultFilesystemMigrator {
|
|
71
|
+
sink;
|
|
72
|
+
constructor(sink = NOOP_FILESYSTEM_MIGRATION_SINK) {
|
|
73
|
+
this.sink = sink;
|
|
74
|
+
}
|
|
75
|
+
async migrate(rootDir) {
|
|
76
|
+
const markerPath = join(rootDir, MARKER_REL_PATH);
|
|
77
|
+
const lockPath = join(rootDir, LOCK_REL_PATH);
|
|
78
|
+
const threadsDir = join(rootDir, 'threads');
|
|
79
|
+
const projectsDir = join(rootDir, 'projects');
|
|
80
|
+
// Step 1: completed-marker short-circuit (cheapest idempotency check).
|
|
81
|
+
const existing = await readMarker(markerPath);
|
|
82
|
+
if (existing) {
|
|
83
|
+
return {
|
|
84
|
+
kind: 'already_migrated',
|
|
85
|
+
migratedThreads: [],
|
|
86
|
+
markerPath,
|
|
87
|
+
at: existing.at,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
// Step 2: legacy absent → no-op. Plant the marker so subsequent boots
|
|
91
|
+
// do not re-enter this branch. Fresh installs fall through here.
|
|
92
|
+
const threadsExists = await directoryExists(threadsDir);
|
|
93
|
+
if (!threadsExists) {
|
|
94
|
+
const at = new Date();
|
|
95
|
+
try {
|
|
96
|
+
await writeMarker(markerPath, {
|
|
97
|
+
version: MIGRATION_VERSION,
|
|
98
|
+
at,
|
|
99
|
+
migratedThreads: [],
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
catch (cause) {
|
|
103
|
+
throw new FilesystemMigrationError({
|
|
104
|
+
op: 'write_marker',
|
|
105
|
+
path: markerPath,
|
|
106
|
+
cause,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
kind: 'noop_no_legacy',
|
|
111
|
+
migratedThreads: [],
|
|
112
|
+
markerPath,
|
|
113
|
+
at,
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
// Step 3: cooperate on the tmp lock.
|
|
117
|
+
try {
|
|
118
|
+
await acquireMigrationLock(lockPath);
|
|
119
|
+
}
|
|
120
|
+
catch (err) {
|
|
121
|
+
const code = err.code;
|
|
122
|
+
if (code === 'EEXIST') {
|
|
123
|
+
// Another boot is mid-migration — wait and re-read the main marker.
|
|
124
|
+
await sleep(LOCK_WAIT_MS);
|
|
125
|
+
const follow = await readMarker(markerPath);
|
|
126
|
+
if (follow) {
|
|
127
|
+
return {
|
|
128
|
+
kind: 'already_migrated',
|
|
129
|
+
migratedThreads: [],
|
|
130
|
+
markerPath,
|
|
131
|
+
at: follow.at,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
// Main marker still absent — the winning boot is still going OR
|
|
135
|
+
// crashed. We re-throw so the caller sees a contention surface
|
|
136
|
+
// rather than silently assuming success.
|
|
137
|
+
throw new FilesystemMigrationError({
|
|
138
|
+
op: 'acquire_lock',
|
|
139
|
+
path: lockPath,
|
|
140
|
+
cause: err,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
throw new FilesystemMigrationError({
|
|
144
|
+
op: 'acquire_lock',
|
|
145
|
+
path: lockPath,
|
|
146
|
+
cause: err,
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
try {
|
|
150
|
+
// Step 4a: enumerate legacy thread dirs.
|
|
151
|
+
let entries;
|
|
152
|
+
try {
|
|
153
|
+
entries = await readdir(threadsDir);
|
|
154
|
+
}
|
|
155
|
+
catch (cause) {
|
|
156
|
+
throw new FilesystemMigrationError({
|
|
157
|
+
op: 'enumerate_threads',
|
|
158
|
+
path: threadsDir,
|
|
159
|
+
cause,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
const migrated = [];
|
|
163
|
+
const now = new Date();
|
|
164
|
+
for (const entry of entries) {
|
|
165
|
+
// Accept only `thd_*` (and tolerate `prj_*` legacy in case of
|
|
166
|
+
// rerun after a partial-crash-with-renamed-but-no-marker).
|
|
167
|
+
if (!entry.startsWith('thd_'))
|
|
168
|
+
continue;
|
|
169
|
+
const legacyThreadId = entry;
|
|
170
|
+
const suffix = legacyThreadId.slice('thd_'.length);
|
|
171
|
+
const newProjectId = `${LEGACY_DEFAULT_PROJECT_PREFIX}${suffix}`;
|
|
172
|
+
const legacyRunsDir = join(threadsDir, legacyThreadId, 'runs');
|
|
173
|
+
const newProjectDir = join(projectsDir, newProjectId);
|
|
174
|
+
const newSessionDir = join(newProjectDir, 'sessions', LEGACY_DEFAULT_SESSION_ID);
|
|
175
|
+
const newRunsDir = join(newSessionDir, 'runs');
|
|
176
|
+
// Ensure parent path exists for the atomic rename of `runs/`.
|
|
177
|
+
try {
|
|
178
|
+
await mkdir(newSessionDir, { recursive: true });
|
|
179
|
+
}
|
|
180
|
+
catch (cause) {
|
|
181
|
+
throw new FilesystemMigrationError({
|
|
182
|
+
op: 'mkdir_session',
|
|
183
|
+
path: newSessionDir,
|
|
184
|
+
cause,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
// Move the whole `runs/` subtree in a single rename — atomic on
|
|
188
|
+
// same-filesystem, EXDEV on cross-mount (documented limitation).
|
|
189
|
+
const legacyRunsExists = await directoryExists(legacyRunsDir);
|
|
190
|
+
if (legacyRunsExists) {
|
|
191
|
+
try {
|
|
192
|
+
await rename(legacyRunsDir, newRunsDir);
|
|
193
|
+
}
|
|
194
|
+
catch (cause) {
|
|
195
|
+
throw new FilesystemMigrationError({
|
|
196
|
+
op: 'rename_runs',
|
|
197
|
+
path: legacyRunsDir,
|
|
198
|
+
cause,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
// Step 4b: synthesize project.json via write-tmp-rename.
|
|
203
|
+
const projectJson = {
|
|
204
|
+
id: newProjectId,
|
|
205
|
+
tenantId: UNKNOWN_TENANT_ID,
|
|
206
|
+
name: `legacy ${legacyThreadId}`,
|
|
207
|
+
config: {
|
|
208
|
+
maxDelegationDepth: 4,
|
|
209
|
+
maxDelegationWidth: 8,
|
|
210
|
+
maxInterventionDepth: 10,
|
|
211
|
+
},
|
|
212
|
+
createdAt: now.toISOString(),
|
|
213
|
+
updatedAt: now.toISOString(),
|
|
214
|
+
_legacy: true,
|
|
215
|
+
};
|
|
216
|
+
const projectJsonPath = join(newProjectDir, 'project.json');
|
|
217
|
+
try {
|
|
218
|
+
await atomicWriteJson(projectJsonPath, projectJson);
|
|
219
|
+
}
|
|
220
|
+
catch (cause) {
|
|
221
|
+
throw new FilesystemMigrationError({
|
|
222
|
+
op: 'write_project_json',
|
|
223
|
+
path: projectJsonPath,
|
|
224
|
+
cause,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
// Step 4c: synthesize session.json for the legacy-default session.
|
|
228
|
+
const sessionJson = {
|
|
229
|
+
id: LEGACY_DEFAULT_SESSION_ID,
|
|
230
|
+
projectId: newProjectId,
|
|
231
|
+
tenantId: UNKNOWN_TENANT_ID,
|
|
232
|
+
status: 'idle',
|
|
233
|
+
currentActor: null,
|
|
234
|
+
previousActors: [],
|
|
235
|
+
workspaceId: null,
|
|
236
|
+
ownerVersion: 0,
|
|
237
|
+
createdAt: now.toISOString(),
|
|
238
|
+
updatedAt: now.toISOString(),
|
|
239
|
+
_legacy: true,
|
|
240
|
+
};
|
|
241
|
+
const sessionJsonPath = join(newSessionDir, 'session.json');
|
|
242
|
+
try {
|
|
243
|
+
await atomicWriteJson(sessionJsonPath, sessionJson);
|
|
244
|
+
}
|
|
245
|
+
catch (cause) {
|
|
246
|
+
throw new FilesystemMigrationError({
|
|
247
|
+
op: 'write_session_json',
|
|
248
|
+
path: sessionJsonPath,
|
|
249
|
+
cause,
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
migrated.push({ legacyThreadId, newProjectId });
|
|
253
|
+
}
|
|
254
|
+
// Step 5: write the completion marker last. Presence = done.
|
|
255
|
+
try {
|
|
256
|
+
await writeMarker(markerPath, {
|
|
257
|
+
version: MIGRATION_VERSION,
|
|
258
|
+
at: now,
|
|
259
|
+
migratedThreads: migrated,
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
catch (cause) {
|
|
263
|
+
throw new FilesystemMigrationError({
|
|
264
|
+
op: 'write_marker',
|
|
265
|
+
path: markerPath,
|
|
266
|
+
cause,
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
const result = {
|
|
270
|
+
kind: 'migrated',
|
|
271
|
+
migratedThreads: migrated,
|
|
272
|
+
markerPath,
|
|
273
|
+
at: now,
|
|
274
|
+
};
|
|
275
|
+
// Step 6: emit event.
|
|
276
|
+
this.sink.emit({ type: 'filesystem.migrated', result });
|
|
277
|
+
return result;
|
|
278
|
+
}
|
|
279
|
+
finally {
|
|
280
|
+
// Always release the lock — even on failure, a crashed run with the
|
|
281
|
+
// main marker absent will retry on the next boot; the stale `.tmp`
|
|
282
|
+
// would otherwise wedge that retry.
|
|
283
|
+
await releaseMigrationLock(lockPath).catch(() => undefined);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Shared atomic-write helper. Mirrors `store/session/disk.ts:atomicWriteJson`
|
|
289
|
+
* — intentionally duplicated so `session/migration/` has no inbound
|
|
290
|
+
* dependency on the store layer (Convention #4 dependency direction).
|
|
291
|
+
*/
|
|
292
|
+
async function atomicWriteJson(filePath, value) {
|
|
293
|
+
const { writeFile, rename: renameFile, unlink } = await import('node:fs/promises');
|
|
294
|
+
const tmp = `${filePath}.tmp`;
|
|
295
|
+
try {
|
|
296
|
+
await writeFile(tmp, JSON.stringify(value, null, 2), 'utf-8');
|
|
297
|
+
await renameFile(tmp, filePath);
|
|
298
|
+
}
|
|
299
|
+
catch (err) {
|
|
300
|
+
await unlink(tmp).catch(() => undefined);
|
|
301
|
+
throw err;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
async function directoryExists(path) {
|
|
305
|
+
try {
|
|
306
|
+
const s = await stat(path);
|
|
307
|
+
return s.isDirectory();
|
|
308
|
+
}
|
|
309
|
+
catch (err) {
|
|
310
|
+
const code = err.code;
|
|
311
|
+
if (code === 'ENOENT')
|
|
312
|
+
return false;
|
|
313
|
+
throw err;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
function sleep(ms) {
|
|
317
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
318
|
+
}
|
|
319
|
+
//# sourceMappingURL=filesystem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filesystem.js","sourceRoot":"","sources":["../../../src/session/migration/filesystem.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ID-prefix migration window — read-side compat for legacy `thd_*` IDs.
|
|
3
|
+
*
|
|
4
|
+
* Phase 1 already ships {@link parseThreadId} in `utils/id.ts` that accepts
|
|
5
|
+
* either `thd_*` or `prj_*` silently. This module formalises the warning
|
|
6
|
+
* emission path called out in session-hierarchy.md §13.3.1:
|
|
7
|
+
*
|
|
8
|
+
* | Version | Reader accepts | Writer emits | Legacy read behaviour |
|
|
9
|
+
* |---------|---------------------|--------------|-------------------------------|
|
|
10
|
+
* | 0.2.x | `thd_*` AND `prj_*` | `prj_*` only | emits `MigrationWarning` once |
|
|
11
|
+
* | 0.3.x | `prj_*` only | `prj_*` only | rejects `StalePrefixError` |
|
|
12
|
+
*
|
|
13
|
+
* Consumers that touch raw legacy IDs (filesystem migrator, wire decoders,
|
|
14
|
+
* CLI imports) route through {@link acceptLegacyThreadId} so the warning
|
|
15
|
+
* signal is structured rather than ad-hoc console output (Convention #18).
|
|
16
|
+
*
|
|
17
|
+
* The `WINDOW_OPEN` constant is the single switch that flips this module
|
|
18
|
+
* from soft-accept to hard-reject when 0.3.0 cuts. Convention #0: no silent
|
|
19
|
+
* long-lived compat — the window is explicit, dated, and fails closed when
|
|
20
|
+
* the clock runs out.
|
|
21
|
+
*/
|
|
22
|
+
import type { ProjectId } from '../../types/session/ids.js';
|
|
23
|
+
/**
|
|
24
|
+
* Structured event emitted when the reader accepts a legacy `thd_*` ID.
|
|
25
|
+
*
|
|
26
|
+
* Shape is stable across the 0.2.x window — platform consumers can wire
|
|
27
|
+
* this into their observability pipeline (metrics, audit log) without
|
|
28
|
+
* string parsing (Convention #18).
|
|
29
|
+
*/
|
|
30
|
+
export interface MigrationWarning {
|
|
31
|
+
kind: 'id_prefix_legacy_read';
|
|
32
|
+
legacyId: string;
|
|
33
|
+
normalizedId: ProjectId;
|
|
34
|
+
at: Date;
|
|
35
|
+
emittedOncePerProcess: true;
|
|
36
|
+
}
|
|
37
|
+
/** Sink contract — one `emit` method so callers can swap implementations. */
|
|
38
|
+
export interface MigrationWarningSink {
|
|
39
|
+
emit(warning: MigrationWarning): void;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Default sink used when consumers do not inject one. Drops warnings on the
|
|
43
|
+
* floor — migration still runs; observers just lose the signal. Convention
|
|
44
|
+
* #5 deny-by-default applies to behaviour, not telemetry; missing a warning
|
|
45
|
+
* sink is not a failure mode.
|
|
46
|
+
*/
|
|
47
|
+
export declare const NOOP_MIGRATION_WARNING_SINK: MigrationWarningSink;
|
|
48
|
+
/**
|
|
49
|
+
* Raised when the reader encounters a string that is neither a valid
|
|
50
|
+
* `prj_*` nor `thd_*` prefix. In the 0.3.x window the legacy branch will
|
|
51
|
+
* also throw this error — flip {@link WINDOW_OPEN} to `false` to cut over.
|
|
52
|
+
*/
|
|
53
|
+
export declare class StalePrefixError extends Error {
|
|
54
|
+
readonly details: {
|
|
55
|
+
rawId: string;
|
|
56
|
+
kind: 'thd_rejected' | 'unknown_prefix';
|
|
57
|
+
};
|
|
58
|
+
constructor(details: {
|
|
59
|
+
rawId: string;
|
|
60
|
+
kind: 'thd_rejected' | 'unknown_prefix';
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* 0.2.x: compat window OPEN — `thd_*` coerces to `prj_*` with a warning.
|
|
65
|
+
* 0.3.x: flip to `false` — legacy branch becomes throw-only.
|
|
66
|
+
*/
|
|
67
|
+
export declare const WINDOW_OPEN = true;
|
|
68
|
+
/**
|
|
69
|
+
* Accept-on-read for legacy `thd_*` IDs during the 0.2.x window.
|
|
70
|
+
*
|
|
71
|
+
* Contract:
|
|
72
|
+
* - `prj_*` inputs return as-is; no warning emitted.
|
|
73
|
+
* - `thd_*` inputs normalize to `prj_<suffix>` and emit a single
|
|
74
|
+
* {@link MigrationWarning} per distinct input string per process.
|
|
75
|
+
* - Everything else throws {@link StalePrefixError}.
|
|
76
|
+
* - When {@link WINDOW_OPEN} flips to `false`, the `thd_*` branch throws
|
|
77
|
+
* too — single knob, single commit.
|
|
78
|
+
*
|
|
79
|
+
* Testing hook: {@link __resetSeenLegacyForTests} clears the dedup Set so
|
|
80
|
+
* each test starts with a clean emission history.
|
|
81
|
+
*/
|
|
82
|
+
export declare function acceptLegacyThreadId(raw: string, sink: MigrationWarningSink): ProjectId;
|
|
83
|
+
/**
|
|
84
|
+
* Writer guard: reject emission of `thd_*` at encode time. Phase 1's
|
|
85
|
+
* {@link generateProjectId} already emits `prj_*` only; this helper exists
|
|
86
|
+
* so write paths that handle raw strings (e.g. synthesis during filesystem
|
|
87
|
+
* migration) can fail fast on accidental legacy re-emission. Convention #0:
|
|
88
|
+
* no silent back-sliding to the old prefix.
|
|
89
|
+
*/
|
|
90
|
+
export declare function rejectLegacyPrefix(id: string): void;
|
|
91
|
+
/**
|
|
92
|
+
* Test-only: clear the process-level dedup Set so subsequent
|
|
93
|
+
* {@link acceptLegacyThreadId} calls emit warnings again. Production code
|
|
94
|
+
* must never call this — the whole point is one warning per distinct
|
|
95
|
+
* legacy id per process.
|
|
96
|
+
*/
|
|
97
|
+
export declare function __resetSeenLegacyForTests(): void;
|
|
98
|
+
//# sourceMappingURL=id-prefix.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"id-prefix.d.ts","sourceRoot":"","sources":["../../../src/session/migration/id-prefix.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AAE3D;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAChC,IAAI,EAAE,uBAAuB,CAAA;IAC7B,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,SAAS,CAAA;IACvB,EAAE,EAAE,IAAI,CAAA;IACR,qBAAqB,EAAE,IAAI,CAAA;CAC3B;AAED,6EAA6E;AAC7E,MAAM,WAAW,oBAAoB;IACpC,IAAI,CAAC,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAA;CACrC;AAED;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B,EAAE,oBAEzC,CAAA;AAED;;;;GAIG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;IAC1C,QAAQ,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,cAAc,GAAG,gBAAgB,CAAA;KAAE,CAAA;gBAEhE,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,cAAc,GAAG,gBAAgB,CAAA;KAAE;CAS/E;AAED;;;GAGG;AACH,eAAO,MAAM,WAAW,OAAO,CAAA;AAS/B;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,oBAAoB,GAAG,SAAS,CAsBvF;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAInD;AAED;;;;;GAKG;AACH,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ID-prefix migration window — read-side compat for legacy `thd_*` IDs.
|
|
3
|
+
*
|
|
4
|
+
* Phase 1 already ships {@link parseThreadId} in `utils/id.ts` that accepts
|
|
5
|
+
* either `thd_*` or `prj_*` silently. This module formalises the warning
|
|
6
|
+
* emission path called out in session-hierarchy.md §13.3.1:
|
|
7
|
+
*
|
|
8
|
+
* | Version | Reader accepts | Writer emits | Legacy read behaviour |
|
|
9
|
+
* |---------|---------------------|--------------|-------------------------------|
|
|
10
|
+
* | 0.2.x | `thd_*` AND `prj_*` | `prj_*` only | emits `MigrationWarning` once |
|
|
11
|
+
* | 0.3.x | `prj_*` only | `prj_*` only | rejects `StalePrefixError` |
|
|
12
|
+
*
|
|
13
|
+
* Consumers that touch raw legacy IDs (filesystem migrator, wire decoders,
|
|
14
|
+
* CLI imports) route through {@link acceptLegacyThreadId} so the warning
|
|
15
|
+
* signal is structured rather than ad-hoc console output (Convention #18).
|
|
16
|
+
*
|
|
17
|
+
* The `WINDOW_OPEN` constant is the single switch that flips this module
|
|
18
|
+
* from soft-accept to hard-reject when 0.3.0 cuts. Convention #0: no silent
|
|
19
|
+
* long-lived compat — the window is explicit, dated, and fails closed when
|
|
20
|
+
* the clock runs out.
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* Default sink used when consumers do not inject one. Drops warnings on the
|
|
24
|
+
* floor — migration still runs; observers just lose the signal. Convention
|
|
25
|
+
* #5 deny-by-default applies to behaviour, not telemetry; missing a warning
|
|
26
|
+
* sink is not a failure mode.
|
|
27
|
+
*/
|
|
28
|
+
export const NOOP_MIGRATION_WARNING_SINK = {
|
|
29
|
+
emit() { },
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Raised when the reader encounters a string that is neither a valid
|
|
33
|
+
* `prj_*` nor `thd_*` prefix. In the 0.3.x window the legacy branch will
|
|
34
|
+
* also throw this error — flip {@link WINDOW_OPEN} to `false` to cut over.
|
|
35
|
+
*/
|
|
36
|
+
export class StalePrefixError extends Error {
|
|
37
|
+
details;
|
|
38
|
+
constructor(details) {
|
|
39
|
+
const reason = details.kind === 'thd_rejected'
|
|
40
|
+
? `Stale ThreadId prefix '${details.rawId.slice(0, 4)}…' — run 'namzu sdk migrate-ids' before 0.3.0`
|
|
41
|
+
: `Unknown ID prefix '${details.rawId.slice(0, 4)}…' — expected 'prj_' or 'thd_'`;
|
|
42
|
+
super(reason);
|
|
43
|
+
this.name = 'StalePrefixError';
|
|
44
|
+
this.details = details;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* 0.2.x: compat window OPEN — `thd_*` coerces to `prj_*` with a warning.
|
|
49
|
+
* 0.3.x: flip to `false` — legacy branch becomes throw-only.
|
|
50
|
+
*/
|
|
51
|
+
export const WINDOW_OPEN = true;
|
|
52
|
+
/**
|
|
53
|
+
* Process-lifetime dedup map. Keyed by raw legacy ID so each distinct legacy
|
|
54
|
+
* string emits exactly one warning — spamming observability on a hot loop
|
|
55
|
+
* of reads is the anti-goal.
|
|
56
|
+
*/
|
|
57
|
+
const seenLegacy = new Set();
|
|
58
|
+
/**
|
|
59
|
+
* Accept-on-read for legacy `thd_*` IDs during the 0.2.x window.
|
|
60
|
+
*
|
|
61
|
+
* Contract:
|
|
62
|
+
* - `prj_*` inputs return as-is; no warning emitted.
|
|
63
|
+
* - `thd_*` inputs normalize to `prj_<suffix>` and emit a single
|
|
64
|
+
* {@link MigrationWarning} per distinct input string per process.
|
|
65
|
+
* - Everything else throws {@link StalePrefixError}.
|
|
66
|
+
* - When {@link WINDOW_OPEN} flips to `false`, the `thd_*` branch throws
|
|
67
|
+
* too — single knob, single commit.
|
|
68
|
+
*
|
|
69
|
+
* Testing hook: {@link __resetSeenLegacyForTests} clears the dedup Set so
|
|
70
|
+
* each test starts with a clean emission history.
|
|
71
|
+
*/
|
|
72
|
+
export function acceptLegacyThreadId(raw, sink) {
|
|
73
|
+
if (raw.startsWith('prj_')) {
|
|
74
|
+
return raw;
|
|
75
|
+
}
|
|
76
|
+
if (raw.startsWith('thd_')) {
|
|
77
|
+
if (!WINDOW_OPEN) {
|
|
78
|
+
throw new StalePrefixError({ rawId: raw, kind: 'thd_rejected' });
|
|
79
|
+
}
|
|
80
|
+
const normalized = `prj_${raw.slice('thd_'.length)}`;
|
|
81
|
+
if (!seenLegacy.has(raw)) {
|
|
82
|
+
seenLegacy.add(raw);
|
|
83
|
+
sink.emit({
|
|
84
|
+
kind: 'id_prefix_legacy_read',
|
|
85
|
+
legacyId: raw,
|
|
86
|
+
normalizedId: normalized,
|
|
87
|
+
at: new Date(),
|
|
88
|
+
emittedOncePerProcess: true,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
return normalized;
|
|
92
|
+
}
|
|
93
|
+
throw new StalePrefixError({ rawId: raw, kind: 'unknown_prefix' });
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Writer guard: reject emission of `thd_*` at encode time. Phase 1's
|
|
97
|
+
* {@link generateProjectId} already emits `prj_*` only; this helper exists
|
|
98
|
+
* so write paths that handle raw strings (e.g. synthesis during filesystem
|
|
99
|
+
* migration) can fail fast on accidental legacy re-emission. Convention #0:
|
|
100
|
+
* no silent back-sliding to the old prefix.
|
|
101
|
+
*/
|
|
102
|
+
export function rejectLegacyPrefix(id) {
|
|
103
|
+
if (id.startsWith('thd_')) {
|
|
104
|
+
throw new StalePrefixError({ rawId: id, kind: 'thd_rejected' });
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Test-only: clear the process-level dedup Set so subsequent
|
|
109
|
+
* {@link acceptLegacyThreadId} calls emit warnings again. Production code
|
|
110
|
+
* must never call this — the whole point is one warning per distinct
|
|
111
|
+
* legacy id per process.
|
|
112
|
+
*/
|
|
113
|
+
export function __resetSeenLegacyForTests() {
|
|
114
|
+
seenLegacy.clear();
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=id-prefix.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"id-prefix.js","sourceRoot":"","sources":["../../../src/session/migration/id-prefix.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAwBH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAyB;IAChE,IAAI,KAAI,CAAC;CACT,CAAA;AAED;;;;GAIG;AACH,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IACjC,OAAO,CAA4D;IAE5E,YAAY,OAAmE;QAC9E,MAAM,MAAM,GACX,OAAO,CAAC,IAAI,KAAK,cAAc;YAC9B,CAAC,CAAC,0BAA0B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,+CAA+C;YACpG,CAAC,CAAC,sBAAsB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,gCAAgC,CAAA;QACnF,KAAK,CAAC,MAAM,CAAC,CAAA;QACb,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAA;QAC9B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IACvB,CAAC;CACD;AAED;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAA;AAE/B;;;;GAIG;AACH,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAA;AAEpC;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,oBAAoB,CAAC,GAAW,EAAE,IAA0B;IAC3E,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5B,OAAO,GAAgB,CAAA;IACxB,CAAC;IACD,IAAI,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5B,IAAI,CAAC,WAAW,EAAE,CAAC;YAClB,MAAM,IAAI,gBAAgB,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAA;QACjE,CAAC;QACD,MAAM,UAAU,GAAG,OAAO,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,EAAe,CAAA;QACjE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1B,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YACnB,IAAI,CAAC,IAAI,CAAC;gBACT,IAAI,EAAE,uBAAuB;gBAC7B,QAAQ,EAAE,GAAG;gBACb,YAAY,EAAE,UAAU;gBACxB,EAAE,EAAE,IAAI,IAAI,EAAE;gBACd,qBAAqB,EAAE,IAAI;aAC3B,CAAC,CAAA;QACH,CAAC;QACD,OAAO,UAAU,CAAA;IAClB,CAAC;IACD,MAAM,IAAI,gBAAgB,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC,CAAA;AACnE,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,EAAU;IAC5C,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,MAAM,IAAI,gBAAgB,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,CAAA;IAChE,CAAC;AACF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,yBAAyB;IACxC,UAAU,CAAC,KAAK,EAAE,CAAA;AACnB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { acceptLegacyThreadId, rejectLegacyPrefix, NOOP_MIGRATION_WARNING_SINK, StalePrefixError, WINDOW_OPEN, } from './id-prefix.js';
|
|
2
|
+
export type { MigrationWarning, MigrationWarningSink } from './id-prefix.js';
|
|
3
|
+
export { DefaultFilesystemMigrator, NOOP_FILESYSTEM_MIGRATION_SINK, LEGACY_DEFAULT_SESSION_ID, LEGACY_DEFAULT_PROJECT_PREFIX, MIGRATION_VERSION, MARKER_REL_PATH, LOCK_REL_PATH, } from './filesystem.js';
|
|
4
|
+
export type { FilesystemMigrator, FilesystemMigrationResult, FilesystemMigrationEvent, FilesystemMigrationSink, } from './filesystem.js';
|
|
5
|
+
export { readMarker, writeMarker, acquireMigrationLock, releaseMigrationLock, } from './marker.js';
|
|
6
|
+
export type { MigrationMarker } from './marker.js';
|
|
7
|
+
export { FilesystemMigrationError } from './errors.js';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/session/migration/index.ts"],"names":[],"mappings":"AAIA,OAAO,EACN,oBAAoB,EACpB,kBAAkB,EAClB,2BAA2B,EAC3B,gBAAgB,EAChB,WAAW,GACX,MAAM,gBAAgB,CAAA;AACvB,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAE5E,OAAO,EACN,yBAAyB,EACzB,8BAA8B,EAC9B,yBAAyB,EACzB,6BAA6B,EAC7B,iBAAiB,EACjB,eAAe,EACf,aAAa,GACb,MAAM,iBAAiB,CAAA;AACxB,YAAY,EACX,kBAAkB,EAClB,yBAAyB,EACzB,wBAAwB,EACxB,uBAAuB,GACvB,MAAM,iBAAiB,CAAA;AAExB,OAAO,EACN,UAAU,EACV,WAAW,EACX,oBAAoB,EACpB,oBAAoB,GACpB,MAAM,aAAa,CAAA;AACpB,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAElD,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAA"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// Sub-barrel for the migration module (Convention #4).
|
|
2
|
+
// Public surface for boot-time FS re-layout + ID-prefix read-accept.
|
|
3
|
+
// See session-hierarchy.md §13.3.1 (ID prefix) + §13.4.1 (filesystem).
|
|
4
|
+
export { acceptLegacyThreadId, rejectLegacyPrefix, NOOP_MIGRATION_WARNING_SINK, StalePrefixError, WINDOW_OPEN, } from './id-prefix.js';
|
|
5
|
+
export { DefaultFilesystemMigrator, NOOP_FILESYSTEM_MIGRATION_SINK, LEGACY_DEFAULT_SESSION_ID, LEGACY_DEFAULT_PROJECT_PREFIX, MIGRATION_VERSION, MARKER_REL_PATH, LOCK_REL_PATH, } from './filesystem.js';
|
|
6
|
+
export { readMarker, writeMarker, acquireMigrationLock, releaseMigrationLock, } from './marker.js';
|
|
7
|
+
export { FilesystemMigrationError } from './errors.js';
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/session/migration/index.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,qEAAqE;AACrE,uEAAuE;AAEvE,OAAO,EACN,oBAAoB,EACpB,kBAAkB,EAClB,2BAA2B,EAC3B,gBAAgB,EAChB,WAAW,GACX,MAAM,gBAAgB,CAAA;AAGvB,OAAO,EACN,yBAAyB,EACzB,8BAA8B,EAC9B,yBAAyB,EACzB,6BAA6B,EAC7B,iBAAiB,EACjB,eAAe,EACf,aAAa,GACb,MAAM,iBAAiB,CAAA;AAQxB,OAAO,EACN,UAAU,EACV,WAAW,EACX,oBAAoB,EACpB,oBAAoB,GACpB,MAAM,aAAa,CAAA;AAGpB,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAA"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migration marker file I/O — ensures the boot-time v0.2.0 re-layout is
|
|
3
|
+
* idempotent and race-safe.
|
|
4
|
+
*
|
|
5
|
+
* Layout:
|
|
6
|
+
* {rootDir}/.migration/v0.2.0 — completion marker (JSON body)
|
|
7
|
+
* {rootDir}/.migration/v0.2.0.tmp — in-flight lock (O_EXCL / `wx` flag)
|
|
8
|
+
*
|
|
9
|
+
* Atomicity contract (Convention #8):
|
|
10
|
+
* - `writeMarker` goes through write-tmp-rename so readers never see a
|
|
11
|
+
* partially serialized body.
|
|
12
|
+
* - `acquireMigrationLock` uses the `wx` flag (O_CREAT | O_EXCL) so
|
|
13
|
+
* concurrent boots detect each other rather than overwriting. Loser
|
|
14
|
+
* cooperates (see filesystem.ts — waits and re-checks the main marker).
|
|
15
|
+
* - `readMarker` tolerates missing / corrupt files: missing → null,
|
|
16
|
+
* corrupt JSON → null (not throw). The migrator treats either as "run
|
|
17
|
+
* again"; a corrupt marker is safer to retry than to honor as valid.
|
|
18
|
+
*/
|
|
19
|
+
import type { ProjectId } from '../../types/session/ids.js';
|
|
20
|
+
/**
|
|
21
|
+
* Marker payload. `migratedThreads` preserves the legacy → new mapping so
|
|
22
|
+
* later tooling (e.g. `namzu sdk migrate-ids`) can cross-reference.
|
|
23
|
+
*/
|
|
24
|
+
export interface MigrationMarker {
|
|
25
|
+
version: string;
|
|
26
|
+
at: Date;
|
|
27
|
+
migratedThreads: readonly {
|
|
28
|
+
legacyThreadId: string;
|
|
29
|
+
newProjectId: ProjectId;
|
|
30
|
+
}[];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Read a marker file. Returns `null` when the file is absent OR when the
|
|
34
|
+
* contents fail JSON.parse — corruption is treated as "migration did not
|
|
35
|
+
* complete cleanly", so the caller re-runs rather than honoring stale data.
|
|
36
|
+
*/
|
|
37
|
+
export declare function readMarker(path: string): Promise<MigrationMarker | null>;
|
|
38
|
+
/**
|
|
39
|
+
* Write a marker atomically via write-tmp-rename. Parent directory is
|
|
40
|
+
* created on demand so callers do not have to mkdir separately.
|
|
41
|
+
*/
|
|
42
|
+
export declare function writeMarker(path: string, marker: MigrationMarker): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Acquire an exclusive lock by creating `tmpPath` with the `wx` flag.
|
|
45
|
+
* EEXIST means another process is mid-migration — callers must treat that
|
|
46
|
+
* as "wait and re-check the main marker" rather than overwriting.
|
|
47
|
+
*
|
|
48
|
+
* Returns on success; throws the raw `NodeJS.ErrnoException` on EEXIST or
|
|
49
|
+
* any other FS failure so the caller can branch on `code`.
|
|
50
|
+
*/
|
|
51
|
+
export declare function acquireMigrationLock(tmpPath: string): Promise<void>;
|
|
52
|
+
/**
|
|
53
|
+
* Release the lock. Missing file is tolerated — lock release is idempotent
|
|
54
|
+
* by design so crashed mid-migrations do not wedge subsequent boots.
|
|
55
|
+
*/
|
|
56
|
+
export declare function releaseMigrationLock(tmpPath: string): Promise<void>;
|
|
57
|
+
//# sourceMappingURL=marker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"marker.d.ts","sourceRoot":"","sources":["../../../src/session/migration/marker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAA;AAE3D;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC/B,OAAO,EAAE,MAAM,CAAA;IACf,EAAE,EAAE,IAAI,CAAA;IACR,eAAe,EAAE,SAAS;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,SAAS,CAAA;KAAE,EAAE,CAAA;CAC/E;AAQD;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAmC9E;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBtF;AAED;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAGzE;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQzE"}
|