claude-code-swarm 0.3.4 → 0.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +22 -1
- package/.claude-plugin/run-agent-inbox-mcp.sh +95 -0
- package/.claude-plugin/run-minimem-mcp.sh +98 -0
- package/.claude-plugin/run-opentasks-mcp.sh +65 -0
- package/.gitattributes +3 -0
- package/.opentasks/config.json +9 -0
- package/.opentasks/graph.jsonl +0 -0
- package/CLAUDE.md +196 -36
- package/e2e/helpers/cleanup.mjs +17 -3
- package/e2e/helpers/map-mock-server.mjs +201 -25
- package/e2e/helpers/opentasks-daemon.mjs +149 -0
- package/e2e/helpers/sidecar.mjs +222 -0
- package/e2e/helpers/workspace.mjs +2 -1
- package/e2e/tier5-sidecar-inbox.test.mjs +900 -0
- package/e2e/tier6-inbox-mcp.test.mjs +173 -0
- package/e2e/tier6-live-agent.test.mjs +759 -0
- package/e2e/tier6-live-inbox-flow.test.mjs +938 -0
- package/e2e/tier7-hooks.test.mjs +992 -0
- package/e2e/tier7-minimem.test.mjs +461 -0
- package/e2e/tier7-opentasks.test.mjs +513 -0
- package/e2e/tier7-skilltree.test.mjs +506 -0
- package/e2e/vitest.config.e2e.mjs +1 -1
- package/hooks/hooks.json +15 -8
- package/package.json +17 -1
- package/references/agent-inbox/CLAUDE.md +151 -0
- package/references/agent-inbox/README.md +238 -0
- package/references/agent-inbox/docs/CLAUDE-CODE-SWARM-PROPOSAL.md +137 -0
- package/references/agent-inbox/docs/DESIGN.md +1156 -0
- package/references/agent-inbox/hooks/inbox-hook.mjs +119 -0
- package/references/agent-inbox/hooks/register-hook.mjs +69 -0
- package/references/agent-inbox/package-lock.json +3347 -0
- package/references/agent-inbox/package.json +58 -0
- package/references/agent-inbox/rules/agent-inbox.md +78 -0
- package/references/agent-inbox/src/federation/address.ts +61 -0
- package/references/agent-inbox/src/federation/connection-manager.ts +573 -0
- package/references/agent-inbox/src/federation/delivery-queue.ts +222 -0
- package/references/agent-inbox/src/federation/index.ts +6 -0
- package/references/agent-inbox/src/federation/routing-engine.ts +188 -0
- package/references/agent-inbox/src/federation/trust.ts +71 -0
- package/references/agent-inbox/src/index.ts +404 -0
- package/references/agent-inbox/src/ipc/ipc-server.ts +265 -0
- package/references/agent-inbox/src/jsonrpc/mail-server.ts +382 -0
- package/references/agent-inbox/src/map/map-client.ts +414 -0
- package/references/agent-inbox/src/mcp/mcp-proxy.ts +326 -0
- package/references/agent-inbox/src/mcp/mcp-server.ts +272 -0
- package/references/agent-inbox/src/mesh/delivery-bridge.ts +110 -0
- package/references/agent-inbox/src/mesh/mesh-connector.ts +41 -0
- package/references/agent-inbox/src/mesh/mesh-transport.ts +157 -0
- package/references/agent-inbox/src/mesh/type-mapper.ts +239 -0
- package/references/agent-inbox/src/push/notifier.ts +233 -0
- package/references/agent-inbox/src/registry/warm-registry.ts +255 -0
- package/references/agent-inbox/src/router/message-router.ts +175 -0
- package/references/agent-inbox/src/storage/interface.ts +48 -0
- package/references/agent-inbox/src/storage/memory.ts +145 -0
- package/references/agent-inbox/src/storage/sqlite.ts +671 -0
- package/references/agent-inbox/src/traceability/traceability.ts +183 -0
- package/references/agent-inbox/src/types.ts +329 -0
- package/references/agent-inbox/test/federation/address.test.ts +101 -0
- package/references/agent-inbox/test/federation/connection-manager.test.ts +546 -0
- package/references/agent-inbox/test/federation/delivery-queue.test.ts +159 -0
- package/references/agent-inbox/test/federation/integration.test.ts +857 -0
- package/references/agent-inbox/test/federation/routing-engine.test.ts +117 -0
- package/references/agent-inbox/test/federation/sdk-integration.test.ts +744 -0
- package/references/agent-inbox/test/federation/trust.test.ts +89 -0
- package/references/agent-inbox/test/ipc-jsonrpc.test.ts +113 -0
- package/references/agent-inbox/test/ipc-new-commands.test.ts +200 -0
- package/references/agent-inbox/test/ipc-server.test.ts +197 -0
- package/references/agent-inbox/test/mail-server.test.ts +285 -0
- package/references/agent-inbox/test/map-client.test.ts +408 -0
- package/references/agent-inbox/test/mcp-proxy.test.ts +191 -0
- package/references/agent-inbox/test/mesh/delivery-bridge.test.ts +178 -0
- package/references/agent-inbox/test/mesh/e2e-mesh.test.ts +527 -0
- package/references/agent-inbox/test/mesh/e2e-real-meshpeer.test.ts +629 -0
- package/references/agent-inbox/test/mesh/federation-mesh.test.ts +269 -0
- package/references/agent-inbox/test/mesh/mesh-connector.test.ts +66 -0
- package/references/agent-inbox/test/mesh/mesh-transport.test.ts +191 -0
- package/references/agent-inbox/test/mesh/meshpeer-integration.test.ts +442 -0
- package/references/agent-inbox/test/mesh/mock-mesh.ts +125 -0
- package/references/agent-inbox/test/mesh/mock-meshpeer.ts +266 -0
- package/references/agent-inbox/test/mesh/type-mapper.test.ts +226 -0
- package/references/agent-inbox/test/message-router.test.ts +184 -0
- package/references/agent-inbox/test/push-notifier.test.ts +139 -0
- package/references/agent-inbox/test/registry/warm-registry.test.ts +171 -0
- package/references/agent-inbox/test/sqlite-prefix.test.ts +192 -0
- package/references/agent-inbox/test/sqlite-storage.test.ts +243 -0
- package/references/agent-inbox/test/storage.test.ts +196 -0
- package/references/agent-inbox/test/traceability.test.ts +123 -0
- package/references/agent-inbox/test/wake.test.ts +330 -0
- package/references/agent-inbox/tsconfig.json +20 -0
- package/references/agent-inbox/tsup.config.ts +10 -0
- package/references/agent-inbox/vitest.config.ts +8 -0
- package/references/minimem/.claude/settings.json +7 -0
- package/references/minimem/.sudocode/issues.jsonl +18 -0
- package/references/minimem/.sudocode/specs.jsonl +1 -0
- package/references/minimem/CLAUDE.md +329 -0
- package/references/minimem/README.md +565 -0
- package/references/minimem/claude-plugin/.claude-plugin/plugin.json +10 -0
- package/references/minimem/claude-plugin/.mcp.json +7 -0
- package/references/minimem/claude-plugin/README.md +158 -0
- package/references/minimem/claude-plugin/commands/recall.md +47 -0
- package/references/minimem/claude-plugin/commands/remember.md +41 -0
- package/references/minimem/claude-plugin/hooks/__tests__/hooks.test.ts +272 -0
- package/references/minimem/claude-plugin/hooks/hooks.json +27 -0
- package/references/minimem/claude-plugin/hooks/session-end.sh +86 -0
- package/references/minimem/claude-plugin/hooks/session-start.sh +85 -0
- package/references/minimem/claude-plugin/skills/memory/SKILL.md +108 -0
- package/references/minimem/media/banner.png +0 -0
- package/references/minimem/package-lock.json +5373 -0
- package/references/minimem/package.json +76 -0
- package/references/minimem/scripts/postbuild.js +49 -0
- package/references/minimem/src/__tests__/edge-cases.test.ts +371 -0
- package/references/minimem/src/__tests__/errors.test.ts +265 -0
- package/references/minimem/src/__tests__/helpers.ts +199 -0
- package/references/minimem/src/__tests__/internal.test.ts +407 -0
- package/references/minimem/src/__tests__/knowledge-frontmatter.test.ts +148 -0
- package/references/minimem/src/__tests__/knowledge.test.ts +148 -0
- package/references/minimem/src/__tests__/minimem.integration.test.ts +1127 -0
- package/references/minimem/src/__tests__/session.test.ts +190 -0
- package/references/minimem/src/cli/__tests__/commands.test.ts +760 -0
- package/references/minimem/src/cli/__tests__/contained-layout.test.ts +286 -0
- package/references/minimem/src/cli/commands/__tests__/conflicts.test.ts +141 -0
- package/references/minimem/src/cli/commands/append.ts +76 -0
- package/references/minimem/src/cli/commands/config.ts +262 -0
- package/references/minimem/src/cli/commands/conflicts.ts +415 -0
- package/references/minimem/src/cli/commands/daemon.ts +169 -0
- package/references/minimem/src/cli/commands/index.ts +12 -0
- package/references/minimem/src/cli/commands/init.ts +166 -0
- package/references/minimem/src/cli/commands/mcp.ts +221 -0
- package/references/minimem/src/cli/commands/push-pull.ts +213 -0
- package/references/minimem/src/cli/commands/search.ts +223 -0
- package/references/minimem/src/cli/commands/status.ts +84 -0
- package/references/minimem/src/cli/commands/store.ts +189 -0
- package/references/minimem/src/cli/commands/sync-init.ts +290 -0
- package/references/minimem/src/cli/commands/sync.ts +70 -0
- package/references/minimem/src/cli/commands/upsert.ts +197 -0
- package/references/minimem/src/cli/config.ts +611 -0
- package/references/minimem/src/cli/index.ts +299 -0
- package/references/minimem/src/cli/shared.ts +189 -0
- package/references/minimem/src/cli/sync/__tests__/central.test.ts +152 -0
- package/references/minimem/src/cli/sync/__tests__/conflicts.test.ts +209 -0
- package/references/minimem/src/cli/sync/__tests__/daemon.test.ts +118 -0
- package/references/minimem/src/cli/sync/__tests__/detection.test.ts +207 -0
- package/references/minimem/src/cli/sync/__tests__/integration.test.ts +476 -0
- package/references/minimem/src/cli/sync/__tests__/registry.test.ts +363 -0
- package/references/minimem/src/cli/sync/__tests__/state.test.ts +255 -0
- package/references/minimem/src/cli/sync/__tests__/validation.test.ts +193 -0
- package/references/minimem/src/cli/sync/__tests__/watcher.test.ts +178 -0
- package/references/minimem/src/cli/sync/central.ts +292 -0
- package/references/minimem/src/cli/sync/conflicts.ts +205 -0
- package/references/minimem/src/cli/sync/daemon.ts +407 -0
- package/references/minimem/src/cli/sync/detection.ts +138 -0
- package/references/minimem/src/cli/sync/index.ts +107 -0
- package/references/minimem/src/cli/sync/operations.ts +373 -0
- package/references/minimem/src/cli/sync/registry.ts +279 -0
- package/references/minimem/src/cli/sync/state.ts +358 -0
- package/references/minimem/src/cli/sync/validation.ts +206 -0
- package/references/minimem/src/cli/sync/watcher.ts +237 -0
- package/references/minimem/src/cli/version.ts +34 -0
- package/references/minimem/src/core/index.ts +9 -0
- package/references/minimem/src/core/indexer.ts +628 -0
- package/references/minimem/src/core/searcher.ts +221 -0
- package/references/minimem/src/db/schema.ts +183 -0
- package/references/minimem/src/db/sqlite-vec.ts +24 -0
- package/references/minimem/src/embeddings/__tests__/embeddings.test.ts +431 -0
- package/references/minimem/src/embeddings/batch-gemini.ts +392 -0
- package/references/minimem/src/embeddings/batch-openai.ts +409 -0
- package/references/minimem/src/embeddings/embeddings.ts +434 -0
- package/references/minimem/src/index.ts +132 -0
- package/references/minimem/src/internal.ts +299 -0
- package/references/minimem/src/minimem.ts +1291 -0
- package/references/minimem/src/search/__tests__/hybrid.test.ts +247 -0
- package/references/minimem/src/search/graph.ts +234 -0
- package/references/minimem/src/search/hybrid.ts +151 -0
- package/references/minimem/src/search/search.ts +256 -0
- package/references/minimem/src/server/__tests__/mcp.test.ts +347 -0
- package/references/minimem/src/server/__tests__/tools.test.ts +364 -0
- package/references/minimem/src/server/mcp.ts +326 -0
- package/references/minimem/src/server/tools.ts +720 -0
- package/references/minimem/src/session.ts +460 -0
- package/references/minimem/src/store/__tests__/manifest.test.ts +177 -0
- package/references/minimem/src/store/__tests__/materialize.test.ts +52 -0
- package/references/minimem/src/store/__tests__/store-graph.test.ts +228 -0
- package/references/minimem/src/store/index.ts +27 -0
- package/references/minimem/src/store/manifest.ts +203 -0
- package/references/minimem/src/store/materialize.ts +185 -0
- package/references/minimem/src/store/store-graph.ts +252 -0
- package/references/minimem/tsconfig.json +19 -0
- package/references/minimem/tsup.config.ts +26 -0
- package/references/minimem/vitest.config.ts +29 -0
- package/references/multi-agent-protocol/.sudocode/issues.jsonl +120 -0
- package/references/multi-agent-protocol/.sudocode/specs.jsonl +15 -0
- package/references/multi-agent-protocol/LICENSE +21 -0
- package/references/multi-agent-protocol/README.md +113 -0
- package/references/multi-agent-protocol/docs/00-design-specification.md +496 -0
- package/references/multi-agent-protocol/docs/01-open-questions.md +1050 -0
- package/references/multi-agent-protocol/docs/02-wire-protocol.md +296 -0
- package/references/multi-agent-protocol/docs/03-streaming-semantics.md +252 -0
- package/references/multi-agent-protocol/docs/04-error-handling.md +231 -0
- package/references/multi-agent-protocol/docs/05-connection-model.md +244 -0
- package/references/multi-agent-protocol/docs/06-visibility-permissions.md +243 -0
- package/references/multi-agent-protocol/docs/07-federation.md +335 -0
- package/references/multi-agent-protocol/docs/08-macro-agent-migration.md +253 -0
- package/references/multi-agent-protocol/docs/09-authentication.md +748 -0
- package/references/multi-agent-protocol/docs/10-environment-awareness.md +242 -0
- package/references/multi-agent-protocol/docs/10-mail-protocol.md +553 -0
- package/references/multi-agent-protocol/docs/11-anp-inspired-improvements.md +1079 -0
- package/references/multi-agent-protocol/docs/11-trajectory-protocol.md +292 -0
- package/references/multi-agent-protocol/docs/12-anp-implementation-plan.md +641 -0
- package/references/multi-agent-protocol/docs/agent-iam-integration.md +877 -0
- package/references/multi-agent-protocol/docs/agentic-mesh-integration-draft.md +459 -0
- package/references/multi-agent-protocol/docs/git-transport-draft.md +251 -0
- package/references/multi-agent-protocol/docs-site/Gemfile +22 -0
- package/references/multi-agent-protocol/docs-site/README.md +82 -0
- package/references/multi-agent-protocol/docs-site/_config.yml +91 -0
- package/references/multi-agent-protocol/docs-site/_includes/head_custom.html +20 -0
- package/references/multi-agent-protocol/docs-site/_sass/color_schemes/map.scss +42 -0
- package/references/multi-agent-protocol/docs-site/_sass/custom/custom.scss +34 -0
- package/references/multi-agent-protocol/docs-site/examples/full-integration.md +510 -0
- package/references/multi-agent-protocol/docs-site/examples/index.md +138 -0
- package/references/multi-agent-protocol/docs-site/examples/simple-chat.md +282 -0
- package/references/multi-agent-protocol/docs-site/examples/task-queue.md +399 -0
- package/references/multi-agent-protocol/docs-site/getting-started/index.md +98 -0
- package/references/multi-agent-protocol/docs-site/getting-started/installation.md +219 -0
- package/references/multi-agent-protocol/docs-site/getting-started/overview.md +172 -0
- package/references/multi-agent-protocol/docs-site/getting-started/quickstart.md +237 -0
- package/references/multi-agent-protocol/docs-site/index.md +136 -0
- package/references/multi-agent-protocol/docs-site/protocol/authentication.md +391 -0
- package/references/multi-agent-protocol/docs-site/protocol/connection-model.md +376 -0
- package/references/multi-agent-protocol/docs-site/protocol/design.md +284 -0
- package/references/multi-agent-protocol/docs-site/protocol/error-handling.md +312 -0
- package/references/multi-agent-protocol/docs-site/protocol/federation.md +449 -0
- package/references/multi-agent-protocol/docs-site/protocol/index.md +129 -0
- package/references/multi-agent-protocol/docs-site/protocol/permissions.md +398 -0
- package/references/multi-agent-protocol/docs-site/protocol/streaming.md +353 -0
- package/references/multi-agent-protocol/docs-site/protocol/wire-protocol.md +369 -0
- package/references/multi-agent-protocol/docs-site/sdk/api/agent.md +357 -0
- package/references/multi-agent-protocol/docs-site/sdk/api/client.md +380 -0
- package/references/multi-agent-protocol/docs-site/sdk/api/index.md +62 -0
- package/references/multi-agent-protocol/docs-site/sdk/api/server.md +453 -0
- package/references/multi-agent-protocol/docs-site/sdk/api/types.md +468 -0
- package/references/multi-agent-protocol/docs-site/sdk/guides/agent.md +375 -0
- package/references/multi-agent-protocol/docs-site/sdk/guides/authentication.md +405 -0
- package/references/multi-agent-protocol/docs-site/sdk/guides/client.md +352 -0
- package/references/multi-agent-protocol/docs-site/sdk/guides/index.md +89 -0
- package/references/multi-agent-protocol/docs-site/sdk/guides/server.md +360 -0
- package/references/multi-agent-protocol/docs-site/sdk/guides/testing.md +446 -0
- package/references/multi-agent-protocol/docs-site/sdk/guides/transports.md +363 -0
- package/references/multi-agent-protocol/docs-site/sdk/index.md +206 -0
- package/references/multi-agent-protocol/package-lock.json +4230 -0
- package/references/multi-agent-protocol/package.json +56 -0
- package/references/multi-agent-protocol/schema/meta.json +584 -0
- package/references/multi-agent-protocol/schema/schema.json +3067 -0
- package/references/openhive/.claude/settings.json +6 -0
- package/references/openhive/.dockerignore +54 -0
- package/references/openhive/.github/workflows/docker.yml +52 -0
- package/references/openhive/.sudocode/issues.jsonl +24 -0
- package/references/openhive/.sudocode/specs.jsonl +4 -0
- package/references/openhive/CLAUDE.md +88 -0
- package/references/openhive/Dockerfile +105 -0
- package/references/openhive/README.md +745 -0
- package/references/openhive/bin/openhive.js +6 -0
- package/references/openhive/cloudbuild.yaml +80 -0
- package/references/openhive/deploy/cloud-run.sh +106 -0
- package/references/openhive/deploy/openhive.env.example +80 -0
- package/references/openhive/deploy/openhive.service +91 -0
- package/references/openhive/docker-compose.yml +67 -0
- package/references/openhive/docker-entrypoint.sh +117 -0
- package/references/openhive/docs/API_MIGRATION.md +176 -0
- package/references/openhive/docs/DEPLOYMENT.md +847 -0
- package/references/openhive/docs/DESIGN_v1.md +489 -0
- package/references/openhive/docs/DESIGN_v2.md +564 -0
- package/references/openhive/docs/HEADSCALE_HOSTING_SPEC.md +513 -0
- package/references/openhive/docs/HIVE_SYNC_DESIGN.md +2362 -0
- package/references/openhive/docs/HIVE_SYNC_IMPLEMENTATION_PLAN.md +1169 -0
- package/references/openhive/docs/HOSTING.md +601 -0
- package/references/openhive/docs/IMPLEMENTATION_PLAN.md +428 -0
- package/references/openhive/docs/LOCAL_SETUP.md +506 -0
- package/references/openhive/docs/MACRO_AGENT_ATLAS_EXTENSION.md +351 -0
- package/references/openhive/docs/MEMORY_BANK_SYNC_SPEC.md +909 -0
- package/references/openhive/docs/PLAN_v1.md +471 -0
- package/references/openhive/docs/PLAN_v2.md +623 -0
- package/references/openhive/docs/WEBSOCKET.md +267 -0
- package/references/openhive/docs/openswarm-bootstrap-token-spec.md +240 -0
- package/references/openhive/ecosystem.config.cjs +76 -0
- package/references/openhive/fly.toml +63 -0
- package/references/openhive/package-lock.json +17640 -0
- package/references/openhive/package.json +128 -0
- package/references/openhive/packages/openhive-types/package-lock.json +1473 -0
- package/references/openhive/packages/openhive-types/package.json +42 -0
- package/references/openhive/packages/openhive-types/src/index.ts +36 -0
- package/references/openhive/packages/openhive-types/src/map-coordination.ts +92 -0
- package/references/openhive/packages/openhive-types/src/map-session-sync.ts +50 -0
- package/references/openhive/packages/openhive-types/src/map-sync.ts +68 -0
- package/references/openhive/packages/openhive-types/tsconfig.json +15 -0
- package/references/openhive/packages/openhive-types/tsconfig.tsbuildinfo +1 -0
- package/references/openhive/packages/openhive-types/tsup.config.ts +12 -0
- package/references/openhive/railway.json +13 -0
- package/references/openhive/railway.toml +24 -0
- package/references/openhive/render.yaml +51 -0
- package/references/openhive/src/__tests__/auth.test.ts +148 -0
- package/references/openhive/src/__tests__/bridge/credentials.test.ts +65 -0
- package/references/openhive/src/__tests__/bridge/dal.test.ts +279 -0
- package/references/openhive/src/__tests__/bridge/inbound.test.ts +349 -0
- package/references/openhive/src/__tests__/bridge/manager.test.ts +419 -0
- package/references/openhive/src/__tests__/bridge/mentions.test.ts +83 -0
- package/references/openhive/src/__tests__/bridge/outbound.test.ts +209 -0
- package/references/openhive/src/__tests__/bridge/slack-adapter.test.ts +276 -0
- package/references/openhive/src/__tests__/cli.test.ts +342 -0
- package/references/openhive/src/__tests__/config.test.ts +205 -0
- package/references/openhive/src/__tests__/coordination/coordination.test.ts +1072 -0
- package/references/openhive/src/__tests__/coordination/cross-instance.test.ts +540 -0
- package/references/openhive/src/__tests__/coordination/e2e.test.ts +780 -0
- package/references/openhive/src/__tests__/data-dir.test.ts +332 -0
- package/references/openhive/src/__tests__/db.test.ts +258 -0
- package/references/openhive/src/__tests__/discovery.test.ts +288 -0
- package/references/openhive/src/__tests__/events/dal.test.ts +371 -0
- package/references/openhive/src/__tests__/events/dispatch.test.ts +202 -0
- package/references/openhive/src/__tests__/events/e2e.test.ts +528 -0
- package/references/openhive/src/__tests__/events/normalizers.test.ts +263 -0
- package/references/openhive/src/__tests__/events/router.test.ts +314 -0
- package/references/openhive/src/__tests__/events/routes.test.ts +407 -0
- package/references/openhive/src/__tests__/follows.test.ts +328 -0
- package/references/openhive/src/__tests__/helpers/test-dirs.ts +44 -0
- package/references/openhive/src/__tests__/ingest-keys.test.ts +925 -0
- package/references/openhive/src/__tests__/map/sync-client-content.test.ts +288 -0
- package/references/openhive/src/__tests__/map/sync-client.test.ts +500 -0
- package/references/openhive/src/__tests__/map/sync-listener.test.ts +504 -0
- package/references/openhive/src/__tests__/middleware/hostname-guard.test.ts +73 -0
- package/references/openhive/src/__tests__/migrations.test.ts +260 -0
- package/references/openhive/src/__tests__/opentasks/client.test.ts +497 -0
- package/references/openhive/src/__tests__/opentasks/discovery.test.ts +283 -0
- package/references/openhive/src/__tests__/opentasks/e2e.test.ts +767 -0
- package/references/openhive/src/__tests__/routes/agents.test.ts +417 -0
- package/references/openhive/src/__tests__/routes/opentasks-content.test.ts +493 -0
- package/references/openhive/src/__tests__/routes/resource-content.test.ts +1741 -0
- package/references/openhive/src/__tests__/sessions/adapters.test.ts +524 -0
- package/references/openhive/src/__tests__/sessions/routes.test.ts +1053 -0
- package/references/openhive/src/__tests__/sessions/storage.test.ts +545 -0
- package/references/openhive/src/__tests__/sessions/trajectory-checkpoints.test.ts +349 -0
- package/references/openhive/src/__tests__/sessions/trajectory-routes.test.ts +290 -0
- package/references/openhive/src/__tests__/swarm/config.test.ts +125 -0
- package/references/openhive/src/__tests__/swarm/credentials.test.ts +254 -0
- package/references/openhive/src/__tests__/swarm/dal.test.ts +290 -0
- package/references/openhive/src/__tests__/swarm/e2e.test.ts +827 -0
- package/references/openhive/src/__tests__/swarm/fixtures/exit-immediately.js +3 -0
- package/references/openhive/src/__tests__/swarm/fixtures/map-server.js +147 -0
- package/references/openhive/src/__tests__/swarm/fixtures/sleep-server.js +52 -0
- package/references/openhive/src/__tests__/swarm/local-provider.test.ts +279 -0
- package/references/openhive/src/__tests__/swarm/manager.test.ts +305 -0
- package/references/openhive/src/__tests__/swarm/routes.test.ts +396 -0
- package/references/openhive/src/__tests__/swarm/workspace.test.ts +257 -0
- package/references/openhive/src/__tests__/swarmhub/client.test.ts +324 -0
- package/references/openhive/src/__tests__/swarmhub/config.test.ts +213 -0
- package/references/openhive/src/__tests__/swarmhub/connector.test.ts +581 -0
- package/references/openhive/src/__tests__/swarmhub/routes.test.ts +639 -0
- package/references/openhive/src/__tests__/swarmhub/slack-client.test.ts +164 -0
- package/references/openhive/src/__tests__/swarmhub/slack-connector.test.ts +164 -0
- package/references/openhive/src/__tests__/swarmhub/slack-routes.test.ts +373 -0
- package/references/openhive/src/__tests__/swarmhub/webhook-handler.test.ts +295 -0
- package/references/openhive/src/__tests__/sync/resource-sync.test.ts +1418 -0
- package/references/openhive/src/__tests__/sync/sync.test.ts +800 -0
- package/references/openhive/src/api/index.ts +65 -0
- package/references/openhive/src/api/middleware/auth.ts +227 -0
- package/references/openhive/src/api/middleware/hostname-guard.ts +38 -0
- package/references/openhive/src/api/routes/admin.ts +366 -0
- package/references/openhive/src/api/routes/agents.ts +223 -0
- package/references/openhive/src/api/routes/auth.ts +164 -0
- package/references/openhive/src/api/routes/bridges.ts +384 -0
- package/references/openhive/src/api/routes/comments.ts +294 -0
- package/references/openhive/src/api/routes/coordination.ts +312 -0
- package/references/openhive/src/api/routes/events.ts +158 -0
- package/references/openhive/src/api/routes/federation.ts +367 -0
- package/references/openhive/src/api/routes/feed.ts +212 -0
- package/references/openhive/src/api/routes/hives.ts +264 -0
- package/references/openhive/src/api/routes/map.ts +674 -0
- package/references/openhive/src/api/routes/memory-banks.ts +971 -0
- package/references/openhive/src/api/routes/posts.ts +342 -0
- package/references/openhive/src/api/routes/resource-content.ts +727 -0
- package/references/openhive/src/api/routes/resources.ts +1013 -0
- package/references/openhive/src/api/routes/search.ts +45 -0
- package/references/openhive/src/api/routes/sessions.ts +1187 -0
- package/references/openhive/src/api/routes/swarm-hosting.ts +313 -0
- package/references/openhive/src/api/routes/sync-protocol.ts +168 -0
- package/references/openhive/src/api/routes/sync.ts +279 -0
- package/references/openhive/src/api/routes/uploads.ts +174 -0
- package/references/openhive/src/api/routes/webhooks.ts +603 -0
- package/references/openhive/src/api/schemas/agents.ts +26 -0
- package/references/openhive/src/api/schemas/comments.ts +22 -0
- package/references/openhive/src/api/schemas/hives.ts +33 -0
- package/references/openhive/src/api/schemas/posts.ts +37 -0
- package/references/openhive/src/api/schemas/sync.ts +56 -0
- package/references/openhive/src/auth/index.ts +2 -0
- package/references/openhive/src/auth/jwks.ts +58 -0
- package/references/openhive/src/bridge/adapters/slack.ts +306 -0
- package/references/openhive/src/bridge/credentials.ts +72 -0
- package/references/openhive/src/bridge/inbound.ts +288 -0
- package/references/openhive/src/bridge/index.ts +42 -0
- package/references/openhive/src/bridge/manager.ts +425 -0
- package/references/openhive/src/bridge/mentions.ts +42 -0
- package/references/openhive/src/bridge/outbound.ts +103 -0
- package/references/openhive/src/bridge/schema.ts +82 -0
- package/references/openhive/src/bridge/types.ts +238 -0
- package/references/openhive/src/cli/network.ts +480 -0
- package/references/openhive/src/cli.ts +620 -0
- package/references/openhive/src/config.ts +611 -0
- package/references/openhive/src/coordination/index.ts +43 -0
- package/references/openhive/src/coordination/listener.ts +92 -0
- package/references/openhive/src/coordination/schema.ts +79 -0
- package/references/openhive/src/coordination/service.ts +233 -0
- package/references/openhive/src/coordination/types.ts +177 -0
- package/references/openhive/src/data-dir.ts +105 -0
- package/references/openhive/src/db/adapters/index.ts +21 -0
- package/references/openhive/src/db/adapters/postgres.ts +310 -0
- package/references/openhive/src/db/adapters/sqlite.ts +56 -0
- package/references/openhive/src/db/adapters/types.ts +65 -0
- package/references/openhive/src/db/dal/agents.ts +430 -0
- package/references/openhive/src/db/dal/bridge.ts +336 -0
- package/references/openhive/src/db/dal/comments.ts +213 -0
- package/references/openhive/src/db/dal/coordination.ts +361 -0
- package/references/openhive/src/db/dal/events.ts +381 -0
- package/references/openhive/src/db/dal/follows.ts +96 -0
- package/references/openhive/src/db/dal/hives.ts +198 -0
- package/references/openhive/src/db/dal/ingest-keys.ts +176 -0
- package/references/openhive/src/db/dal/instances.ts +196 -0
- package/references/openhive/src/db/dal/invites.ts +123 -0
- package/references/openhive/src/db/dal/map.ts +750 -0
- package/references/openhive/src/db/dal/posts.ts +274 -0
- package/references/openhive/src/db/dal/remote-agents.ts +56 -0
- package/references/openhive/src/db/dal/search.ts +238 -0
- package/references/openhive/src/db/dal/sync-events.ts +160 -0
- package/references/openhive/src/db/dal/sync-groups.ts +100 -0
- package/references/openhive/src/db/dal/sync-peer-configs.ts +216 -0
- package/references/openhive/src/db/dal/sync-peers.ts +145 -0
- package/references/openhive/src/db/dal/syncable-resources.ts +888 -0
- package/references/openhive/src/db/dal/trajectory-checkpoints.ts +291 -0
- package/references/openhive/src/db/dal/uploads.ts +124 -0
- package/references/openhive/src/db/dal/votes.ts +124 -0
- package/references/openhive/src/db/index.ts +293 -0
- package/references/openhive/src/db/providers/index.ts +75 -0
- package/references/openhive/src/db/providers/postgres.ts +529 -0
- package/references/openhive/src/db/providers/sqlite.ts +1383 -0
- package/references/openhive/src/db/providers/turso.ts +1360 -0
- package/references/openhive/src/db/providers/types.ts +516 -0
- package/references/openhive/src/db/schema.ts +641 -0
- package/references/openhive/src/discovery/index.ts +403 -0
- package/references/openhive/src/events/dispatch.ts +106 -0
- package/references/openhive/src/events/index.ts +17 -0
- package/references/openhive/src/events/normalizers/github.ts +133 -0
- package/references/openhive/src/events/normalizers/index.ts +62 -0
- package/references/openhive/src/events/normalizers/slack.ts +50 -0
- package/references/openhive/src/events/router.ts +156 -0
- package/references/openhive/src/events/schema.ts +66 -0
- package/references/openhive/src/events/types.ts +130 -0
- package/references/openhive/src/federation/index.ts +1 -0
- package/references/openhive/src/federation/service.ts +776 -0
- package/references/openhive/src/headscale/client.ts +256 -0
- package/references/openhive/src/headscale/config.ts +212 -0
- package/references/openhive/src/headscale/index.ts +23 -0
- package/references/openhive/src/headscale/manager.ts +249 -0
- package/references/openhive/src/headscale/sync.ts +272 -0
- package/references/openhive/src/headscale/types.ts +231 -0
- package/references/openhive/src/index.ts +225 -0
- package/references/openhive/src/map/client-entry.ts +26 -0
- package/references/openhive/src/map/index.ts +76 -0
- package/references/openhive/src/map/schema.ts +119 -0
- package/references/openhive/src/map/service.ts +323 -0
- package/references/openhive/src/map/sync-client.ts +696 -0
- package/references/openhive/src/map/sync-listener.ts +409 -0
- package/references/openhive/src/map/types.ts +290 -0
- package/references/openhive/src/network/factory.ts +118 -0
- package/references/openhive/src/network/headscale-provider.ts +437 -0
- package/references/openhive/src/network/index.ts +43 -0
- package/references/openhive/src/network/tailscale-client.ts +289 -0
- package/references/openhive/src/network/tailscale-provider.ts +287 -0
- package/references/openhive/src/network/types.ts +178 -0
- package/references/openhive/src/opentasks-client/client.ts +374 -0
- package/references/openhive/src/opentasks-client/index.ts +7 -0
- package/references/openhive/src/realtime/index.ts +282 -0
- package/references/openhive/src/server.ts +1069 -0
- package/references/openhive/src/services/email.ts +177 -0
- package/references/openhive/src/services/sitemap.ts +135 -0
- package/references/openhive/src/sessions/adapters/claude.ts +466 -0
- package/references/openhive/src/sessions/adapters/codex.ts +265 -0
- package/references/openhive/src/sessions/adapters/index.ts +263 -0
- package/references/openhive/src/sessions/adapters/raw.ts +144 -0
- package/references/openhive/src/sessions/adapters/types.ts +83 -0
- package/references/openhive/src/sessions/index.ts +50 -0
- package/references/openhive/src/sessions/storage/adapters/gcs.ts +277 -0
- package/references/openhive/src/sessions/storage/adapters/local.ts +240 -0
- package/references/openhive/src/sessions/storage/adapters/s3.ts +321 -0
- package/references/openhive/src/sessions/storage/index.ts +231 -0
- package/references/openhive/src/sessions/storage/types.ts +189 -0
- package/references/openhive/src/sessions/types.ts +415 -0
- package/references/openhive/src/shared/types/index.ts +45 -0
- package/references/openhive/src/shared/types/map-coordination.ts +92 -0
- package/references/openhive/src/shared/types/map-session-sync.ts +170 -0
- package/references/openhive/src/shared/types/map-sync.ts +68 -0
- package/references/openhive/src/skill.ts +203 -0
- package/references/openhive/src/storage/adapters/local.ts +169 -0
- package/references/openhive/src/storage/adapters/s3.ts +195 -0
- package/references/openhive/src/storage/index.ts +64 -0
- package/references/openhive/src/storage/types.ts +69 -0
- package/references/openhive/src/swarm/credentials.ts +98 -0
- package/references/openhive/src/swarm/dal.ts +206 -0
- package/references/openhive/src/swarm/index.ts +28 -0
- package/references/openhive/src/swarm/manager.ts +917 -0
- package/references/openhive/src/swarm/providers/local.ts +338 -0
- package/references/openhive/src/swarm/providers/sandboxed-local.ts +478 -0
- package/references/openhive/src/swarm/providers/workspace.ts +52 -0
- package/references/openhive/src/swarm/schema.ts +43 -0
- package/references/openhive/src/swarm/types.ts +333 -0
- package/references/openhive/src/swarmhub/client.ts +279 -0
- package/references/openhive/src/swarmhub/connector.ts +463 -0
- package/references/openhive/src/swarmhub/index.ts +43 -0
- package/references/openhive/src/swarmhub/routes.ts +296 -0
- package/references/openhive/src/swarmhub/types.ts +213 -0
- package/references/openhive/src/swarmhub/webhook-handler.ts +126 -0
- package/references/openhive/src/sync/compaction.ts +193 -0
- package/references/openhive/src/sync/coordination-hooks.ts +154 -0
- package/references/openhive/src/sync/crypto.ts +79 -0
- package/references/openhive/src/sync/gossip.ts +136 -0
- package/references/openhive/src/sync/hooks.ts +202 -0
- package/references/openhive/src/sync/materializer-repo.ts +256 -0
- package/references/openhive/src/sync/materializer.ts +682 -0
- package/references/openhive/src/sync/middleware.ts +140 -0
- package/references/openhive/src/sync/peer-resolver.ts +157 -0
- package/references/openhive/src/sync/resource-hooks.ts +161 -0
- package/references/openhive/src/sync/schema.ts +158 -0
- package/references/openhive/src/sync/service.ts +990 -0
- package/references/openhive/src/sync/types.ts +369 -0
- package/references/openhive/src/terminal/index.ts +4 -0
- package/references/openhive/src/terminal/pty-manager.ts +337 -0
- package/references/openhive/src/terminal/resolve-tui.ts +44 -0
- package/references/openhive/src/terminal/terminal-ws.ts +251 -0
- package/references/openhive/src/types.ts +442 -0
- package/references/openhive/src/utils/git-remote.ts +329 -0
- package/references/openhive/src/web/App.tsx +77 -0
- package/references/openhive/src/web/__tests__/components/dashboard/RecentActivity.test.tsx +77 -0
- package/references/openhive/src/web/__tests__/components/dashboard/StatsOverview.test.tsx +62 -0
- package/references/openhive/src/web/__tests__/components/dashboard/SwarmStatusSummary.test.tsx +122 -0
- package/references/openhive/src/web/__tests__/components/dashboard/SyncResourcesStatus.test.tsx +104 -0
- package/references/openhive/src/web/__tests__/components/layout/Sidebar.test.tsx +110 -0
- package/references/openhive/src/web/__tests__/components/swarm/StatusBadges.test.tsx +65 -0
- package/references/openhive/src/web/__tests__/components/terminal/query-responses.test.ts +143 -0
- package/references/openhive/src/web/__tests__/components/terminal/terminal-mouse.test.ts +509 -0
- package/references/openhive/src/web/__tests__/hooks/useEventsApi.test.ts +378 -0
- package/references/openhive/src/web/__tests__/pages/Dashboard.test.tsx +57 -0
- package/references/openhive/src/web/__tests__/pages/Events.test.tsx +886 -0
- package/references/openhive/src/web/__tests__/pages/Explore.test.tsx +63 -0
- package/references/openhive/src/web/__tests__/routing.test.tsx +79 -0
- package/references/openhive/src/web/__tests__/setup.ts +37 -0
- package/references/openhive/src/web/__tests__/stores/dashboard.test.ts +49 -0
- package/references/openhive/src/web/components/common/AgentBadge.tsx +58 -0
- package/references/openhive/src/web/components/common/Avatar.tsx +78 -0
- package/references/openhive/src/web/components/common/ErrorBoundary.tsx +76 -0
- package/references/openhive/src/web/components/common/Highlight.tsx +79 -0
- package/references/openhive/src/web/components/common/ImageUpload.tsx +209 -0
- package/references/openhive/src/web/components/common/LoadingSpinner.tsx +37 -0
- package/references/openhive/src/web/components/common/Logo.tsx +21 -0
- package/references/openhive/src/web/components/common/Markdown.tsx +53 -0
- package/references/openhive/src/web/components/common/ProtectedRoute.tsx +18 -0
- package/references/openhive/src/web/components/common/ThemeToggle.tsx +38 -0
- package/references/openhive/src/web/components/common/TimeAgo.tsx +17 -0
- package/references/openhive/src/web/components/common/Toast.tsx +70 -0
- package/references/openhive/src/web/components/common/VoteButtons.tsx +100 -0
- package/references/openhive/src/web/components/dashboard/RecentActivity.tsx +100 -0
- package/references/openhive/src/web/components/dashboard/StatsOverview.tsx +40 -0
- package/references/openhive/src/web/components/dashboard/SwarmStatusSummary.tsx +89 -0
- package/references/openhive/src/web/components/dashboard/SyncResourcesStatus.tsx +81 -0
- package/references/openhive/src/web/components/feed/FeedControls.tsx +38 -0
- package/references/openhive/src/web/components/feed/NewPostsIndicator.tsx +75 -0
- package/references/openhive/src/web/components/feed/PostCard.tsx +129 -0
- package/references/openhive/src/web/components/feed/PostList.tsx +83 -0
- package/references/openhive/src/web/components/layout/Footer.tsx +5 -0
- package/references/openhive/src/web/components/layout/Layout.tsx +29 -0
- package/references/openhive/src/web/components/layout/Sidebar.tsx +348 -0
- package/references/openhive/src/web/components/post/CommentForm.tsx +59 -0
- package/references/openhive/src/web/components/post/CommentTree.tsx +145 -0
- package/references/openhive/src/web/components/resources/MemoryBrowser.tsx +208 -0
- package/references/openhive/src/web/components/resources/OpenTasksSummary.tsx +138 -0
- package/references/openhive/src/web/components/resources/SkillBrowser.tsx +284 -0
- package/references/openhive/src/web/components/swarm/StatusBadges.tsx +56 -0
- package/references/openhive/src/web/components/terminal/TerminalPanel.tsx +485 -0
- package/references/openhive/src/web/components/terminal/index.ts +2 -0
- package/references/openhive/src/web/components/terminal/query-responses.ts +70 -0
- package/references/openhive/src/web/components/terminal/terminal-mouse.ts +222 -0
- package/references/openhive/src/web/hooks/useApi.ts +740 -0
- package/references/openhive/src/web/hooks/useDocumentTitle.ts +49 -0
- package/references/openhive/src/web/hooks/useInfiniteScroll.ts +58 -0
- package/references/openhive/src/web/hooks/useRealtimeUpdates.ts +154 -0
- package/references/openhive/src/web/hooks/useWebSocket.ts +225 -0
- package/references/openhive/src/web/index.html +73 -0
- package/references/openhive/src/web/lib/api.ts +518 -0
- package/references/openhive/src/web/main.tsx +32 -0
- package/references/openhive/src/web/pages/About.tsx +131 -0
- package/references/openhive/src/web/pages/Agent.tsx +130 -0
- package/references/openhive/src/web/pages/Agents.tsx +69 -0
- package/references/openhive/src/web/pages/AuthCallback.tsx +75 -0
- package/references/openhive/src/web/pages/Dashboard.tsx +41 -0
- package/references/openhive/src/web/pages/Events.tsx +1025 -0
- package/references/openhive/src/web/pages/Explore.tsx +43 -0
- package/references/openhive/src/web/pages/Hive.tsx +134 -0
- package/references/openhive/src/web/pages/Hives.tsx +64 -0
- package/references/openhive/src/web/pages/Home.tsx +43 -0
- package/references/openhive/src/web/pages/Login.tsx +122 -0
- package/references/openhive/src/web/pages/Post.tsx +216 -0
- package/references/openhive/src/web/pages/ResourceDetail.tsx +426 -0
- package/references/openhive/src/web/pages/Resources.tsx +276 -0
- package/references/openhive/src/web/pages/Search.tsx +234 -0
- package/references/openhive/src/web/pages/SessionDetail.tsx +703 -0
- package/references/openhive/src/web/pages/Sessions.tsx +129 -0
- package/references/openhive/src/web/pages/Settings.tsx +826 -0
- package/references/openhive/src/web/pages/SwarmCraft.tsx +16 -0
- package/references/openhive/src/web/pages/Swarms.tsx +981 -0
- package/references/openhive/src/web/pages/Terminal.tsx +69 -0
- package/references/openhive/src/web/postcss.config.js +5 -0
- package/references/openhive/src/web/public/favicon.svg +11 -0
- package/references/openhive/src/web/public/manifest.json +21 -0
- package/references/openhive/src/web/stores/auth.ts +207 -0
- package/references/openhive/src/web/stores/dashboard.ts +23 -0
- package/references/openhive/src/web/stores/realtime.ts +90 -0
- package/references/openhive/src/web/stores/theme.ts +70 -0
- package/references/openhive/src/web/stores/toast.ts +63 -0
- package/references/openhive/src/web/styles/globals.css +503 -0
- package/references/openhive/src/web/sw.ts +228 -0
- package/references/openhive/src/web/utils/serviceWorker.ts +86 -0
- package/references/openhive/src/web/vite.config.ts +81 -0
- package/references/openhive/tsconfig.json +32 -0
- package/references/openhive/tsup.config.ts +17 -0
- package/references/openhive/vitest.config.ts +30 -0
- package/references/openhive/vitest.web.config.ts +20 -0
- package/references/opentasks/.claude/settings.json +6 -0
- package/references/opentasks/.claude-plugin/plugin.json +20 -0
- package/references/opentasks/.lintstagedrc.json +4 -0
- package/references/opentasks/.prettierignore +4 -0
- package/references/opentasks/.prettierrc.json +11 -0
- package/references/opentasks/.sudocode/issues.jsonl +89 -0
- package/references/opentasks/.sudocode/specs.jsonl +24 -0
- package/references/opentasks/README.md +401 -0
- package/references/opentasks/docs/ARCHITECTURE.md +841 -0
- package/references/opentasks/docs/DESIGN.md +689 -0
- package/references/opentasks/docs/INTERFACE.md +670 -0
- package/references/opentasks/docs/PERSISTENCE.md +1638 -0
- package/references/opentasks/docs/PROVIDERS.md +1412 -0
- package/references/opentasks/docs/SCHEMA.md +815 -0
- package/references/opentasks/docs/TESTING.md +1081 -0
- package/references/opentasks/eslint.config.js +58 -0
- package/references/opentasks/package-lock.json +4348 -0
- package/references/opentasks/package.json +81 -0
- package/references/opentasks/skills/opentasks/SKILL.md +139 -0
- package/references/opentasks/skills/opentasks/dependency-management.md +119 -0
- package/references/opentasks/skills/opentasks/feedback-and-review.md +100 -0
- package/references/opentasks/skills/opentasks/linking-external-data.md +103 -0
- package/references/opentasks/skills/opentasks/spec-to-implementation.md +98 -0
- package/references/opentasks/src/__tests__/cli-tools.test.ts +800 -0
- package/references/opentasks/src/__tests__/cli.test.ts +97 -0
- package/references/opentasks/src/__tests__/p1-p3-gaps.test.ts +635 -0
- package/references/opentasks/src/cli.ts +929 -0
- package/references/opentasks/src/client/__tests__/client-crud.test.ts +546 -0
- package/references/opentasks/src/client/__tests__/client.test.ts +658 -0
- package/references/opentasks/src/client/__tests__/socket-discovery.test.ts +122 -0
- package/references/opentasks/src/client/client.ts +560 -0
- package/references/opentasks/src/client/index.ts +32 -0
- package/references/opentasks/src/config/__tests__/defaults.test.ts +66 -0
- package/references/opentasks/src/config/__tests__/env.test.ts +155 -0
- package/references/opentasks/src/config/__tests__/index.test.ts +148 -0
- package/references/opentasks/src/config/__tests__/loader.test.ts +173 -0
- package/references/opentasks/src/config/__tests__/merge.test.ts +121 -0
- package/references/opentasks/src/config/__tests__/schema.test.ts +446 -0
- package/references/opentasks/src/config/defaults.ts +18 -0
- package/references/opentasks/src/config/env.ts +170 -0
- package/references/opentasks/src/config/errors.ts +33 -0
- package/references/opentasks/src/config/index.ts +63 -0
- package/references/opentasks/src/config/loader.ts +90 -0
- package/references/opentasks/src/config/merge.ts +64 -0
- package/references/opentasks/src/config/schema.ts +767 -0
- package/references/opentasks/src/core/__tests__/conditional-redirects.test.ts +116 -0
- package/references/opentasks/src/core/__tests__/connections.test.ts +194 -0
- package/references/opentasks/src/core/__tests__/hash.test.ts +161 -0
- package/references/opentasks/src/core/__tests__/id.test.ts +175 -0
- package/references/opentasks/src/core/__tests__/init.test.ts +115 -0
- package/references/opentasks/src/core/__tests__/location.test.ts +94 -0
- package/references/opentasks/src/core/__tests__/merge-driver.test.ts +300 -0
- package/references/opentasks/src/core/__tests__/redirects.test.ts +169 -0
- package/references/opentasks/src/core/__tests__/resolve-location-target.test.ts +468 -0
- package/references/opentasks/src/core/__tests__/uri.test.ts +228 -0
- package/references/opentasks/src/core/__tests__/worktree.test.ts +160 -0
- package/references/opentasks/src/core/conditional-redirects.ts +100 -0
- package/references/opentasks/src/core/connections.ts +217 -0
- package/references/opentasks/src/core/discover.ts +195 -0
- package/references/opentasks/src/core/hash.ts +74 -0
- package/references/opentasks/src/core/id.ts +174 -0
- package/references/opentasks/src/core/index.ts +108 -0
- package/references/opentasks/src/core/init.ts +66 -0
- package/references/opentasks/src/core/location.ts +139 -0
- package/references/opentasks/src/core/merge-driver.ts +280 -0
- package/references/opentasks/src/core/redirects.ts +182 -0
- package/references/opentasks/src/core/uri.ts +270 -0
- package/references/opentasks/src/core/worktree.ts +504 -0
- package/references/opentasks/src/daemon/__tests__/e2e-live-agent.test.ts +344 -0
- package/references/opentasks/src/daemon/__tests__/e2e-session-pipeline.test.ts +447 -0
- package/references/opentasks/src/daemon/__tests__/e2e-watch.test.ts +279 -0
- package/references/opentasks/src/daemon/__tests__/entire-linker.test.ts +1074 -0
- package/references/opentasks/src/daemon/__tests__/entire-watcher.test.ts +659 -0
- package/references/opentasks/src/daemon/__tests__/flush.test.ts +306 -0
- package/references/opentasks/src/daemon/__tests__/integration.test.ts +338 -0
- package/references/opentasks/src/daemon/__tests__/ipc.test.ts +406 -0
- package/references/opentasks/src/daemon/__tests__/lifecycle.test.ts +378 -0
- package/references/opentasks/src/daemon/__tests__/lock.test.ts +240 -0
- package/references/opentasks/src/daemon/__tests__/methods/graph.test.ts +372 -0
- package/references/opentasks/src/daemon/__tests__/methods/provider.test.ts +238 -0
- package/references/opentasks/src/daemon/__tests__/methods/tools.test.ts +690 -0
- package/references/opentasks/src/daemon/__tests__/multi-location.test.ts +945 -0
- package/references/opentasks/src/daemon/__tests__/registry.test.ts +268 -0
- package/references/opentasks/src/daemon/__tests__/watcher.test.ts +329 -0
- package/references/opentasks/src/daemon/entire-linker.ts +615 -0
- package/references/opentasks/src/daemon/entire-watcher.ts +415 -0
- package/references/opentasks/src/daemon/factory.ts +133 -0
- package/references/opentasks/src/daemon/flush.ts +168 -0
- package/references/opentasks/src/daemon/index.ts +120 -0
- package/references/opentasks/src/daemon/ipc.ts +491 -0
- package/references/opentasks/src/daemon/lifecycle.ts +1106 -0
- package/references/opentasks/src/daemon/location-state.ts +481 -0
- package/references/opentasks/src/daemon/lock.ts +168 -0
- package/references/opentasks/src/daemon/methods/__tests__/graph.test.ts +359 -0
- package/references/opentasks/src/daemon/methods/__tests__/provider.test.ts +227 -0
- package/references/opentasks/src/daemon/methods/__tests__/tools.test.ts +360 -0
- package/references/opentasks/src/daemon/methods/__tests__/watch.test.ts +656 -0
- package/references/opentasks/src/daemon/methods/archive.ts +193 -0
- package/references/opentasks/src/daemon/methods/graph.ts +274 -0
- package/references/opentasks/src/daemon/methods/lifecycle.ts +112 -0
- package/references/opentasks/src/daemon/methods/location.ts +118 -0
- package/references/opentasks/src/daemon/methods/provider.ts +159 -0
- package/references/opentasks/src/daemon/methods/tools.ts +221 -0
- package/references/opentasks/src/daemon/methods/watch.ts +206 -0
- package/references/opentasks/src/daemon/registry.ts +244 -0
- package/references/opentasks/src/daemon/types.ts +163 -0
- package/references/opentasks/src/daemon/watcher.ts +248 -0
- package/references/opentasks/src/entire/__tests__/agent-registry.test.ts +127 -0
- package/references/opentasks/src/entire/__tests__/claude-generator.test.ts +49 -0
- package/references/opentasks/src/entire/__tests__/commit-msg.test.ts +89 -0
- package/references/opentasks/src/entire/__tests__/cursor-agent.test.ts +224 -0
- package/references/opentasks/src/entire/__tests__/flush-sentinel.test.ts +93 -0
- package/references/opentasks/src/entire/__tests__/gemini-agent.test.ts +375 -0
- package/references/opentasks/src/entire/__tests__/git-hooks.test.ts +85 -0
- package/references/opentasks/src/entire/__tests__/hook-managers.test.ts +128 -0
- package/references/opentasks/src/entire/__tests__/opencode-agent.test.ts +329 -0
- package/references/opentasks/src/entire/__tests__/redaction.test.ts +143 -0
- package/references/opentasks/src/entire/__tests__/session-store.test.ts +83 -0
- package/references/opentasks/src/entire/__tests__/summarize.test.ts +346 -0
- package/references/opentasks/src/entire/__tests__/transcript-timestamp.test.ts +127 -0
- package/references/opentasks/src/entire/__tests__/types.test.ts +112 -0
- package/references/opentasks/src/entire/__tests__/utils.test.ts +296 -0
- package/references/opentasks/src/entire/__tests__/validation.test.ts +103 -0
- package/references/opentasks/src/entire/__tests__/worktree.test.ts +66 -0
- package/references/opentasks/src/entire/agent/registry.ts +143 -0
- package/references/opentasks/src/entire/agent/session-types.ts +117 -0
- package/references/opentasks/src/entire/agent/types.ts +217 -0
- package/references/opentasks/src/entire/commands/clean.ts +134 -0
- package/references/opentasks/src/entire/commands/disable.ts +85 -0
- package/references/opentasks/src/entire/commands/doctor.ts +152 -0
- package/references/opentasks/src/entire/commands/enable.ts +149 -0
- package/references/opentasks/src/entire/commands/explain.ts +271 -0
- package/references/opentasks/src/entire/commands/reset.ts +105 -0
- package/references/opentasks/src/entire/commands/resume.ts +194 -0
- package/references/opentasks/src/entire/commands/rewind.ts +204 -0
- package/references/opentasks/src/entire/commands/status.ts +150 -0
- package/references/opentasks/src/entire/config.ts +153 -0
- package/references/opentasks/src/entire/git-operations.ts +485 -0
- package/references/opentasks/src/entire/hooks/git-hooks.ts +171 -0
- package/references/opentasks/src/entire/hooks/lifecycle.ts +224 -0
- package/references/opentasks/src/entire/index.ts +644 -0
- package/references/opentasks/src/entire/security/redaction.ts +263 -0
- package/references/opentasks/src/entire/session/state-machine.ts +463 -0
- package/references/opentasks/src/entire/store/checkpoint-store.ts +489 -0
- package/references/opentasks/src/entire/store/native-store.ts +178 -0
- package/references/opentasks/src/entire/store/provider-types.ts +99 -0
- package/references/opentasks/src/entire/store/session-store.ts +233 -0
- package/references/opentasks/src/entire/strategy/attribution.ts +300 -0
- package/references/opentasks/src/entire/strategy/common.ts +222 -0
- package/references/opentasks/src/entire/strategy/content-overlap.ts +242 -0
- package/references/opentasks/src/entire/strategy/manual-commit.ts +1008 -0
- package/references/opentasks/src/entire/strategy/types.ts +285 -0
- package/references/opentasks/src/entire/summarize/claude-generator.ts +119 -0
- package/references/opentasks/src/entire/summarize/summarize.ts +432 -0
- package/references/opentasks/src/entire/types.ts +408 -0
- package/references/opentasks/src/entire/utils/chunk-files.ts +49 -0
- package/references/opentasks/src/entire/utils/commit-message.ts +65 -0
- package/references/opentasks/src/entire/utils/detect-agent.ts +36 -0
- package/references/opentasks/src/entire/utils/hook-managers.ts +118 -0
- package/references/opentasks/src/entire/utils/ide-tags.ts +32 -0
- package/references/opentasks/src/entire/utils/paths.ts +59 -0
- package/references/opentasks/src/entire/utils/preview-rewind.ts +86 -0
- package/references/opentasks/src/entire/utils/rewind-conflict.ts +121 -0
- package/references/opentasks/src/entire/utils/shadow-branch.ts +113 -0
- package/references/opentasks/src/entire/utils/string-utils.ts +46 -0
- package/references/opentasks/src/entire/utils/todo-extract.ts +193 -0
- package/references/opentasks/src/entire/utils/trailers.ts +190 -0
- package/references/opentasks/src/entire/utils/transcript-parse.ts +177 -0
- package/references/opentasks/src/entire/utils/transcript-timestamp.ts +61 -0
- package/references/opentasks/src/entire/utils/tree-ops.ts +227 -0
- package/references/opentasks/src/entire/utils/tty.ts +72 -0
- package/references/opentasks/src/entire/utils/validation.ts +67 -0
- package/references/opentasks/src/entire/utils/worktree.ts +58 -0
- package/references/opentasks/src/graph/EdgeTypeRegistry.ts +330 -0
- package/references/opentasks/src/graph/FederatedGraph.ts +796 -0
- package/references/opentasks/src/graph/GraphologyAdapter.ts +374 -0
- package/references/opentasks/src/graph/HydratingFederatedGraph.ts +533 -0
- package/references/opentasks/src/graph/__tests__/EdgeTypeRegistry.test.ts +263 -0
- package/references/opentasks/src/graph/__tests__/FederatedGraph.test.ts +821 -0
- package/references/opentasks/src/graph/__tests__/GraphologyAdapter.test.ts +408 -0
- package/references/opentasks/src/graph/__tests__/HydratingFederatedGraph.test.ts +735 -0
- package/references/opentasks/src/graph/__tests__/debounce.test.ts +276 -0
- package/references/opentasks/src/graph/__tests__/e2e-store-roundtrip.test.ts +349 -0
- package/references/opentasks/src/graph/__tests__/edge-cases.test.ts +595 -0
- package/references/opentasks/src/graph/__tests__/expansion.test.ts +304 -0
- package/references/opentasks/src/graph/__tests__/git-graph-syncer.test.ts +572 -0
- package/references/opentasks/src/graph/__tests__/provider-store.test.ts +1091 -0
- package/references/opentasks/src/graph/__tests__/query.test.ts +991 -0
- package/references/opentasks/src/graph/__tests__/store.test.ts +998 -0
- package/references/opentasks/src/graph/__tests__/sync.test.ts +178 -0
- package/references/opentasks/src/graph/__tests__/validation.test.ts +657 -0
- package/references/opentasks/src/graph/coordination.ts +454 -0
- package/references/opentasks/src/graph/debounce.ts +154 -0
- package/references/opentasks/src/graph/expansion.ts +364 -0
- package/references/opentasks/src/graph/git-graph-syncer.ts +321 -0
- package/references/opentasks/src/graph/history.ts +438 -0
- package/references/opentasks/src/graph/index.ts +145 -0
- package/references/opentasks/src/graph/provider-store.ts +1077 -0
- package/references/opentasks/src/graph/query.ts +651 -0
- package/references/opentasks/src/graph/store.ts +861 -0
- package/references/opentasks/src/graph/sync.ts +116 -0
- package/references/opentasks/src/graph/types.ts +420 -0
- package/references/opentasks/src/graph/validation.ts +520 -0
- package/references/opentasks/src/index.ts +270 -0
- package/references/opentasks/src/materialization/CLAUDE.md +88 -0
- package/references/opentasks/src/materialization/README.md +187 -0
- package/references/opentasks/src/materialization/__tests__/archive-methods.test.ts +194 -0
- package/references/opentasks/src/materialization/__tests__/archiver.test.ts +528 -0
- package/references/opentasks/src/materialization/__tests__/config.test.ts +123 -0
- package/references/opentasks/src/materialization/__tests__/git-remote-store.test.ts +533 -0
- package/references/opentasks/src/materialization/__tests__/graph-id.test.ts +82 -0
- package/references/opentasks/src/materialization/__tests__/http-remote-store.test.ts +263 -0
- package/references/opentasks/src/materialization/__tests__/materialize-before-archive.test.ts +246 -0
- package/references/opentasks/src/materialization/__tests__/remote-store-factory.test.ts +152 -0
- package/references/opentasks/src/materialization/__tests__/snapshot.test.ts +209 -0
- package/references/opentasks/src/materialization/archiver.ts +318 -0
- package/references/opentasks/src/materialization/git-archive-store.ts +568 -0
- package/references/opentasks/src/materialization/git-remote-store.ts +551 -0
- package/references/opentasks/src/materialization/graph-id.ts +173 -0
- package/references/opentasks/src/materialization/http-remote-store.ts +190 -0
- package/references/opentasks/src/materialization/index.ts +62 -0
- package/references/opentasks/src/materialization/remote-store-factory.ts +55 -0
- package/references/opentasks/src/materialization/snapshot.ts +230 -0
- package/references/opentasks/src/materialization/types.ts +410 -0
- package/references/opentasks/src/providers/__tests__/beads.test.ts +752 -0
- package/references/opentasks/src/providers/__tests__/claude-tasks.test.ts +485 -0
- package/references/opentasks/src/providers/__tests__/entire-e2e.test.ts +692 -0
- package/references/opentasks/src/providers/__tests__/entire-sessionlog-e2e.test.ts +1113 -0
- package/references/opentasks/src/providers/__tests__/entire.test.ts +1016 -0
- package/references/opentasks/src/providers/__tests__/from-config.test.ts +183 -0
- package/references/opentasks/src/providers/__tests__/global.test.ts +515 -0
- package/references/opentasks/src/providers/__tests__/materialization.test.ts +567 -0
- package/references/opentasks/src/providers/__tests__/native.test.ts +693 -0
- package/references/opentasks/src/providers/__tests__/registry.test.ts +232 -0
- package/references/opentasks/src/providers/beads.ts +1155 -0
- package/references/opentasks/src/providers/claude-tasks.ts +402 -0
- package/references/opentasks/src/providers/entire.ts +608 -0
- package/references/opentasks/src/providers/from-config.ts +210 -0
- package/references/opentasks/src/providers/global.ts +460 -0
- package/references/opentasks/src/providers/index.ts +147 -0
- package/references/opentasks/src/providers/location.ts +237 -0
- package/references/opentasks/src/providers/materialization.ts +346 -0
- package/references/opentasks/src/providers/native.ts +725 -0
- package/references/opentasks/src/providers/registry.ts +114 -0
- package/references/opentasks/src/providers/sudocode.ts +1292 -0
- package/references/opentasks/src/providers/sync.ts +485 -0
- package/references/opentasks/src/providers/traits/RelationshipQueryable.ts +169 -0
- package/references/opentasks/src/providers/traits/TaskManageable.ts +211 -0
- package/references/opentasks/src/providers/traits/Watchable.ts +260 -0
- package/references/opentasks/src/providers/traits/__tests__/RelationshipQueryable.test.ts +217 -0
- package/references/opentasks/src/providers/traits/__tests__/TaskManageable.test.ts +241 -0
- package/references/opentasks/src/providers/traits/index.ts +42 -0
- package/references/opentasks/src/providers/types.ts +439 -0
- package/references/opentasks/src/schema/__tests__/validation.test.ts +283 -0
- package/references/opentasks/src/schema/base.ts +88 -0
- package/references/opentasks/src/schema/edges.ts +78 -0
- package/references/opentasks/src/schema/index.ts +37 -0
- package/references/opentasks/src/schema/nodes.ts +119 -0
- package/references/opentasks/src/schema/storage.ts +130 -0
- package/references/opentasks/src/schema/validation.ts +209 -0
- package/references/opentasks/src/storage/__tests__/atomic-write.test.ts +227 -0
- package/references/opentasks/src/storage/__tests__/file-lock.test.ts +120 -0
- package/references/opentasks/src/storage/__tests__/jsonl.test.ts +267 -0
- package/references/opentasks/src/storage/__tests__/locked-writer.test.ts +134 -0
- package/references/opentasks/src/storage/__tests__/sqlite.test.ts +572 -0
- package/references/opentasks/src/storage/atomic-write.ts +86 -0
- package/references/opentasks/src/storage/file-lock.ts +215 -0
- package/references/opentasks/src/storage/index.ts +24 -0
- package/references/opentasks/src/storage/interface.ts +289 -0
- package/references/opentasks/src/storage/jsonl.ts +264 -0
- package/references/opentasks/src/storage/locked-writer.ts +140 -0
- package/references/opentasks/src/storage/sqlite-schema.ts +177 -0
- package/references/opentasks/src/storage/sqlite.ts +791 -0
- package/references/opentasks/src/tools/__tests__/annotate.test.ts +381 -0
- package/references/opentasks/src/tools/__tests__/link.test.ts +299 -0
- package/references/opentasks/src/tools/__tests__/query.test.ts +350 -0
- package/references/opentasks/src/tools/__tests__/task.test.ts +218 -0
- package/references/opentasks/src/tools/annotate.ts +277 -0
- package/references/opentasks/src/tools/index.ts +57 -0
- package/references/opentasks/src/tools/link.ts +163 -0
- package/references/opentasks/src/tools/query.ts +468 -0
- package/references/opentasks/src/tools/task.ts +213 -0
- package/references/opentasks/src/tools/types.ts +451 -0
- package/references/opentasks/src/tracking/__tests__/claude-tool-categorizer.test.ts +223 -0
- package/references/opentasks/src/tracking/__tests__/transcript-extractor.test.ts +262 -0
- package/references/opentasks/src/tracking/claude-tool-categorizer.ts +155 -0
- package/references/opentasks/src/tracking/index.ts +32 -0
- package/references/opentasks/src/tracking/skill-tracker.ts +322 -0
- package/references/opentasks/src/tracking/transcript-extractor.ts +225 -0
- package/references/opentasks/tests/e2e/helpers/assertions.ts +211 -0
- package/references/opentasks/tests/e2e/helpers/beads-helpers.ts +487 -0
- package/references/opentasks/tests/e2e/helpers/fixtures.ts +236 -0
- package/references/opentasks/tests/e2e/helpers/index.ts +122 -0
- package/references/opentasks/tests/e2e/helpers/sudocode-helpers.ts +341 -0
- package/references/opentasks/tests/e2e/helpers/system-setup.ts +504 -0
- package/references/opentasks/tests/e2e/helpers/test-agent.ts +504 -0
- package/references/opentasks/tests/e2e/infrastructure.e2e.test.ts +521 -0
- package/references/opentasks/tests/e2e/skill-tracking.e2e.test.ts +625 -0
- package/references/opentasks/tests/e2e/workflows/feedback-loop.e2e.test.ts +279 -0
- package/references/opentasks/tests/e2e/workflows/multi-agent.e2e.test.ts +304 -0
- package/references/opentasks/tests/e2e/workflows/provider-sync/background-sync.e2e.test.ts +292 -0
- package/references/opentasks/tests/e2e/workflows/provider-sync/beads-provider-compat.e2e.test.ts +249 -0
- package/references/opentasks/tests/e2e/workflows/provider-sync/cross-provider-edges.e2e.test.ts +407 -0
- package/references/opentasks/tests/e2e/workflows/provider-sync/federated-ready.e2e.test.ts +504 -0
- package/references/opentasks/tests/e2e/workflows/provider-sync/hydration.e2e.test.ts +340 -0
- package/references/opentasks/tests/e2e/workflows/provider-sync/materialization.e2e.test.ts +370 -0
- package/references/opentasks/tests/e2e/workflows/provider-sync/sudocode-provider-compat.e2e.test.ts +683 -0
- package/references/opentasks/tests/e2e/workflows/provider-sync/watchable-beads.e2e.test.ts +573 -0
- package/references/opentasks/tests/e2e/workflows/spec-driven.e2e.test.ts +244 -0
- package/references/opentasks/tests/e2e/worktree-location.e2e.test.ts +699 -0
- package/references/opentasks/tests/integration/daemon/helpers.ts +147 -0
- package/references/opentasks/tests/integration/daemon/ipc.integration.test.ts +343 -0
- package/references/opentasks/tests/integration/daemon/lifecycle.integration.test.ts +407 -0
- package/references/opentasks/tests/integration/graph/federated-graph.integration.test.ts +660 -0
- package/references/opentasks/tests/integration/helpers/flags.ts +28 -0
- package/references/opentasks/tests/integration/helpers/index.ts +47 -0
- package/references/opentasks/tests/integration/helpers/process.ts +133 -0
- package/references/opentasks/tests/integration/helpers/temp.ts +105 -0
- package/references/opentasks/tests/integration/helpers/wait.ts +133 -0
- package/references/opentasks/tests/integration/helpers.test.ts +120 -0
- package/references/opentasks/tests/integration/providers/beads-task-manageable.integration.test.ts +450 -0
- package/references/opentasks/tests/integration/providers/beads.integration.test.ts +388 -0
- package/references/opentasks/tests/integration/providers/native-task-manageable.integration.test.ts +667 -0
- package/references/opentasks/tests/integration/providers/sudocode-task-manageable.integration.test.ts +406 -0
- package/references/opentasks/tests/integration/providers/sudocode.integration.test.ts +342 -0
- package/references/opentasks/tests/integration/storage/jsonl-durability.integration.test.ts +390 -0
- package/references/opentasks/tests/integration/storage/sqlite-durability.integration.test.ts +527 -0
- package/references/opentasks/tests/integration/worktree/redirect-location-resolution.integration.test.ts +578 -0
- package/references/opentasks/tests/integration/worktree/worktree-flow.integration.test.ts +656 -0
- package/references/opentasks/tsconfig.json +18 -0
- package/references/opentasks/vitest.config.ts +27 -0
- package/references/opentasks/vitest.e2e.config.ts +35 -0
- package/references/opentasks/vitest.integration.config.ts +19 -0
- package/references/openteams/.claude/settings.json +6 -0
- package/references/openteams/CLAUDE.md +98 -0
- package/references/openteams/README.md +508 -0
- package/references/openteams/SKILL.md +198 -0
- package/references/openteams/design.md +250 -0
- package/references/openteams/docs/visual-editor-design.md +1225 -0
- package/references/openteams/editor/index.html +15 -0
- package/references/openteams/editor/package.json +39 -0
- package/references/openteams/editor/src/App.tsx +48 -0
- package/references/openteams/editor/src/components/canvas/Canvas.tsx +131 -0
- package/references/openteams/editor/src/components/canvas/QuickAddMenu.tsx +134 -0
- package/references/openteams/editor/src/components/edges/PeerRouteEdge.tsx +82 -0
- package/references/openteams/editor/src/components/edges/SignalFlowEdge.tsx +77 -0
- package/references/openteams/editor/src/components/edges/SpawnEdge.tsx +54 -0
- package/references/openteams/editor/src/components/inspector/ChannelInspector.tsx +158 -0
- package/references/openteams/editor/src/components/inspector/EdgeInspector.tsx +168 -0
- package/references/openteams/editor/src/components/inspector/Inspector.tsx +46 -0
- package/references/openteams/editor/src/components/inspector/RoleInspector.tsx +508 -0
- package/references/openteams/editor/src/components/inspector/TeamInspector.tsx +126 -0
- package/references/openteams/editor/src/components/nodes/ChannelNode.tsx +103 -0
- package/references/openteams/editor/src/components/nodes/RoleNode.tsx +157 -0
- package/references/openteams/editor/src/components/nodes/node-styles.ts +101 -0
- package/references/openteams/editor/src/components/sidebar/Sidebar.tsx +227 -0
- package/references/openteams/editor/src/components/toolbar/ExportModal.tsx +110 -0
- package/references/openteams/editor/src/components/toolbar/ImportModal.tsx +139 -0
- package/references/openteams/editor/src/components/toolbar/Toolbar.tsx +190 -0
- package/references/openteams/editor/src/hooks/use-autosave.ts +126 -0
- package/references/openteams/editor/src/hooks/use-keyboard.ts +106 -0
- package/references/openteams/editor/src/hooks/use-validation.ts +45 -0
- package/references/openteams/editor/src/index.css +245 -0
- package/references/openteams/editor/src/lib/auto-layout.ts +51 -0
- package/references/openteams/editor/src/lib/bundled-templates.ts +42 -0
- package/references/openteams/editor/src/lib/compiler.ts +75 -0
- package/references/openteams/editor/src/lib/load-template.ts +103 -0
- package/references/openteams/editor/src/lib/rebuild-edges.ts +104 -0
- package/references/openteams/editor/src/lib/serializer.ts +408 -0
- package/references/openteams/editor/src/lib/signal-catalog.ts +50 -0
- package/references/openteams/editor/src/lib/validator.ts +172 -0
- package/references/openteams/editor/src/main.tsx +10 -0
- package/references/openteams/editor/src/stores/canvas-store.ts +80 -0
- package/references/openteams/editor/src/stores/config-store.ts +243 -0
- package/references/openteams/editor/src/stores/history-store.ts +143 -0
- package/references/openteams/editor/src/stores/theme-store.ts +66 -0
- package/references/openteams/editor/src/stores/ui-store.ts +46 -0
- package/references/openteams/editor/src/stores/validation-store.ts +27 -0
- package/references/openteams/editor/src/types/editor.ts +74 -0
- package/references/openteams/editor/src/vite-env.d.ts +1 -0
- package/references/openteams/editor/tests/compiler.test.ts +151 -0
- package/references/openteams/editor/tests/e2e-add-remove.test.ts +386 -0
- package/references/openteams/editor/tests/e2e-components.test.tsx +424 -0
- package/references/openteams/editor/tests/e2e-export-roundtrip.test.ts +299 -0
- package/references/openteams/editor/tests/e2e-template-load.test.ts +204 -0
- package/references/openteams/editor/tests/e2e-ui-store.test.ts +126 -0
- package/references/openteams/editor/tests/e2e-undo-redo.test.ts +203 -0
- package/references/openteams/editor/tests/e2e-validation.test.ts +307 -0
- package/references/openteams/editor/tests/serializer.test.ts +142 -0
- package/references/openteams/editor/tests/setup.ts +52 -0
- package/references/openteams/editor/tests/validator.test.ts +92 -0
- package/references/openteams/editor/tsconfig.json +21 -0
- package/references/openteams/editor/tsconfig.tsbuildinfo +1 -0
- package/references/openteams/editor/vite.config.ts +28 -0
- package/references/openteams/examples/bmad-method/prompts/analyst/ROLE.md +16 -0
- package/references/openteams/examples/bmad-method/prompts/analyst/SOUL.md +5 -0
- package/references/openteams/examples/bmad-method/prompts/architect/ROLE.md +24 -0
- package/references/openteams/examples/bmad-method/prompts/architect/SOUL.md +5 -0
- package/references/openteams/examples/bmad-method/prompts/developer/ROLE.md +25 -0
- package/references/openteams/examples/bmad-method/prompts/developer/SOUL.md +5 -0
- package/references/openteams/examples/bmad-method/prompts/master/ROLE.md +21 -0
- package/references/openteams/examples/bmad-method/prompts/master/SOUL.md +5 -0
- package/references/openteams/examples/bmad-method/prompts/pm/ROLE.md +20 -0
- package/references/openteams/examples/bmad-method/prompts/pm/SOUL.md +5 -0
- package/references/openteams/examples/bmad-method/prompts/qa/ROLE.md +17 -0
- package/references/openteams/examples/bmad-method/prompts/qa/SOUL.md +5 -0
- package/references/openteams/examples/bmad-method/prompts/quick-flow-dev/ROLE.md +23 -0
- package/references/openteams/examples/bmad-method/prompts/quick-flow-dev/SOUL.md +5 -0
- package/references/openteams/examples/bmad-method/prompts/scrum-master/ROLE.md +27 -0
- package/references/openteams/examples/bmad-method/prompts/scrum-master/SOUL.md +5 -0
- package/references/openteams/examples/bmad-method/prompts/tech-writer/ROLE.md +21 -0
- package/references/openteams/examples/bmad-method/prompts/tech-writer/SOUL.md +5 -0
- package/references/openteams/examples/bmad-method/prompts/ux-designer/ROLE.md +16 -0
- package/references/openteams/examples/bmad-method/prompts/ux-designer/SOUL.md +5 -0
- package/references/openteams/examples/bmad-method/roles/analyst.yaml +9 -0
- package/references/openteams/examples/bmad-method/roles/architect.yaml +9 -0
- package/references/openteams/examples/bmad-method/roles/developer.yaml +8 -0
- package/references/openteams/examples/bmad-method/roles/master.yaml +8 -0
- package/references/openteams/examples/bmad-method/roles/pm.yaml +9 -0
- package/references/openteams/examples/bmad-method/roles/qa.yaml +8 -0
- package/references/openteams/examples/bmad-method/roles/quick-flow-dev.yaml +8 -0
- package/references/openteams/examples/bmad-method/roles/scrum-master.yaml +9 -0
- package/references/openteams/examples/bmad-method/roles/tech-writer.yaml +8 -0
- package/references/openteams/examples/bmad-method/roles/ux-designer.yaml +8 -0
- package/references/openteams/examples/bmad-method/team.yaml +161 -0
- package/references/openteams/examples/bug-fix-pipeline/roles/fixer.yaml +9 -0
- package/references/openteams/examples/bug-fix-pipeline/roles/investigator.yaml +8 -0
- package/references/openteams/examples/bug-fix-pipeline/roles/pr-creator.yaml +6 -0
- package/references/openteams/examples/bug-fix-pipeline/roles/triager.yaml +7 -0
- package/references/openteams/examples/bug-fix-pipeline/roles/verifier.yaml +8 -0
- package/references/openteams/examples/bug-fix-pipeline/team.yaml +88 -0
- package/references/openteams/examples/codebase-migration/roles/assessor.yaml +7 -0
- package/references/openteams/examples/codebase-migration/roles/migrator.yaml +9 -0
- package/references/openteams/examples/codebase-migration/roles/planner.yaml +5 -0
- package/references/openteams/examples/codebase-migration/roles/test-extractor.yaml +9 -0
- package/references/openteams/examples/codebase-migration/roles/validator.yaml +7 -0
- package/references/openteams/examples/codebase-migration/team.yaml +81 -0
- package/references/openteams/examples/docs-sync/roles/adr-writer.yaml +7 -0
- package/references/openteams/examples/docs-sync/roles/api-doc-writer.yaml +7 -0
- package/references/openteams/examples/docs-sync/roles/change-detector.yaml +7 -0
- package/references/openteams/examples/docs-sync/roles/doc-reviewer.yaml +7 -0
- package/references/openteams/examples/docs-sync/roles/guide-writer.yaml +7 -0
- package/references/openteams/examples/docs-sync/team.yaml +84 -0
- package/references/openteams/examples/gsd/prompts/codebase-mapper/ROLE.md +17 -0
- package/references/openteams/examples/gsd/prompts/codebase-mapper/SOUL.md +5 -0
- package/references/openteams/examples/gsd/prompts/debugger/ROLE.md +25 -0
- package/references/openteams/examples/gsd/prompts/debugger/SOUL.md +5 -0
- package/references/openteams/examples/gsd/prompts/executor/ROLE.md +34 -0
- package/references/openteams/examples/gsd/prompts/executor/SOUL.md +5 -0
- package/references/openteams/examples/gsd/prompts/integration-checker/ROLE.md +18 -0
- package/references/openteams/examples/gsd/prompts/integration-checker/SOUL.md +3 -0
- package/references/openteams/examples/gsd/prompts/orchestrator/ROLE.md +42 -0
- package/references/openteams/examples/gsd/prompts/orchestrator/SOUL.md +5 -0
- package/references/openteams/examples/gsd/prompts/phase-researcher/ROLE.md +15 -0
- package/references/openteams/examples/gsd/prompts/phase-researcher/SOUL.md +3 -0
- package/references/openteams/examples/gsd/prompts/plan-checker/ROLE.md +17 -0
- package/references/openteams/examples/gsd/prompts/plan-checker/SOUL.md +3 -0
- package/references/openteams/examples/gsd/prompts/planner/ROLE.md +28 -0
- package/references/openteams/examples/gsd/prompts/planner/SOUL.md +5 -0
- package/references/openteams/examples/gsd/prompts/project-researcher/ROLE.md +16 -0
- package/references/openteams/examples/gsd/prompts/project-researcher/SOUL.md +3 -0
- package/references/openteams/examples/gsd/prompts/research-synthesizer/ROLE.md +13 -0
- package/references/openteams/examples/gsd/prompts/research-synthesizer/SOUL.md +3 -0
- package/references/openteams/examples/gsd/prompts/roadmapper/ROLE.md +14 -0
- package/references/openteams/examples/gsd/prompts/roadmapper/SOUL.md +3 -0
- package/references/openteams/examples/gsd/prompts/verifier/ROLE.md +19 -0
- package/references/openteams/examples/gsd/prompts/verifier/SOUL.md +5 -0
- package/references/openteams/examples/gsd/roles/codebase-mapper.yaml +8 -0
- package/references/openteams/examples/gsd/roles/debugger.yaml +8 -0
- package/references/openteams/examples/gsd/roles/executor.yaml +8 -0
- package/references/openteams/examples/gsd/roles/integration-checker.yaml +8 -0
- package/references/openteams/examples/gsd/roles/orchestrator.yaml +9 -0
- package/references/openteams/examples/gsd/roles/phase-researcher.yaml +7 -0
- package/references/openteams/examples/gsd/roles/plan-checker.yaml +8 -0
- package/references/openteams/examples/gsd/roles/planner.yaml +8 -0
- package/references/openteams/examples/gsd/roles/project-researcher.yaml +8 -0
- package/references/openteams/examples/gsd/roles/research-synthesizer.yaml +7 -0
- package/references/openteams/examples/gsd/roles/roadmapper.yaml +7 -0
- package/references/openteams/examples/gsd/roles/verifier.yaml +8 -0
- package/references/openteams/examples/gsd/team.yaml +154 -0
- package/references/openteams/examples/incident-response/roles/communicator.yaml +5 -0
- package/references/openteams/examples/incident-response/roles/fix-proposer.yaml +7 -0
- package/references/openteams/examples/incident-response/roles/incident-triager.yaml +8 -0
- package/references/openteams/examples/incident-response/roles/investigator.yaml +8 -0
- package/references/openteams/examples/incident-response/team.yaml +68 -0
- package/references/openteams/examples/pr-review-checks/roles/code-reviewer.yaml +7 -0
- package/references/openteams/examples/pr-review-checks/roles/security-scanner.yaml +6 -0
- package/references/openteams/examples/pr-review-checks/roles/summarizer.yaml +6 -0
- package/references/openteams/examples/pr-review-checks/roles/test-checker.yaml +8 -0
- package/references/openteams/examples/pr-review-checks/team.yaml +64 -0
- package/references/openteams/examples/security-audit/roles/code-analyzer.yaml +6 -0
- package/references/openteams/examples/security-audit/roles/dep-scanner.yaml +7 -0
- package/references/openteams/examples/security-audit/roles/fixer.yaml +9 -0
- package/references/openteams/examples/security-audit/roles/pr-creator.yaml +6 -0
- package/references/openteams/examples/security-audit/roles/prioritizer.yaml +6 -0
- package/references/openteams/examples/security-audit/roles/secrets-scanner.yaml +6 -0
- package/references/openteams/examples/security-audit/roles/verifier.yaml +8 -0
- package/references/openteams/examples/security-audit/team.yaml +102 -0
- package/references/openteams/media/banner.png +0 -0
- package/references/openteams/media/editor.png +0 -0
- package/references/openteams/package-lock.json +4804 -0
- package/references/openteams/package.json +58 -0
- package/references/openteams/schema/role.schema.json +147 -0
- package/references/openteams/schema/team.schema.json +311 -0
- package/references/openteams/src/cli/editor.ts +170 -0
- package/references/openteams/src/cli/generate.test.ts +191 -0
- package/references/openteams/src/cli/generate.ts +242 -0
- package/references/openteams/src/cli/prompt-utils.ts +42 -0
- package/references/openteams/src/cli/template.test.ts +365 -0
- package/references/openteams/src/cli/template.ts +205 -0
- package/references/openteams/src/cli.ts +22 -0
- package/references/openteams/src/generators/agent-prompt-generator.test.ts +426 -0
- package/references/openteams/src/generators/agent-prompt-generator.ts +556 -0
- package/references/openteams/src/generators/package-generator.test.ts +129 -0
- package/references/openteams/src/generators/package-generator.ts +110 -0
- package/references/openteams/src/generators/skill-generator.test.ts +274 -0
- package/references/openteams/src/generators/skill-generator.ts +394 -0
- package/references/openteams/src/index.ts +84 -0
- package/references/openteams/src/template/builtins.test.ts +74 -0
- package/references/openteams/src/template/builtins.ts +108 -0
- package/references/openteams/src/template/install-service.test.ts +452 -0
- package/references/openteams/src/template/install-service.ts +332 -0
- package/references/openteams/src/template/loader.test.ts +1696 -0
- package/references/openteams/src/template/loader.ts +804 -0
- package/references/openteams/src/template/resolver.test.ts +304 -0
- package/references/openteams/src/template/resolver.ts +251 -0
- package/references/openteams/src/template/types.ts +229 -0
- package/references/openteams/tsconfig.cjs.json +7 -0
- package/references/openteams/tsconfig.esm.json +8 -0
- package/references/openteams/tsconfig.json +16 -0
- package/references/openteams/vitest.config.ts +9 -0
- package/references/sessionlog/.husky/pre-commit +1 -0
- package/references/sessionlog/.lintstagedrc.json +4 -0
- package/references/sessionlog/.prettierignore +4 -0
- package/references/sessionlog/.prettierrc.json +11 -0
- package/references/sessionlog/LICENSE +21 -0
- package/references/sessionlog/README.md +453 -0
- package/references/sessionlog/eslint.config.js +58 -0
- package/references/sessionlog/package-lock.json +3672 -0
- package/references/sessionlog/package.json +65 -0
- package/references/sessionlog/src/__tests__/agent-hooks.test.ts +570 -0
- package/references/sessionlog/src/__tests__/agent-registry.test.ts +127 -0
- package/references/sessionlog/src/__tests__/claude-code-hooks.test.ts +225 -0
- package/references/sessionlog/src/__tests__/claude-generator.test.ts +46 -0
- package/references/sessionlog/src/__tests__/commit-msg.test.ts +86 -0
- package/references/sessionlog/src/__tests__/cursor-agent.test.ts +224 -0
- package/references/sessionlog/src/__tests__/e2e-live.test.ts +890 -0
- package/references/sessionlog/src/__tests__/event-log.test.ts +183 -0
- package/references/sessionlog/src/__tests__/flush-sentinel.test.ts +105 -0
- package/references/sessionlog/src/__tests__/gemini-agent.test.ts +375 -0
- package/references/sessionlog/src/__tests__/git-hooks.test.ts +78 -0
- package/references/sessionlog/src/__tests__/hook-managers.test.ts +121 -0
- package/references/sessionlog/src/__tests__/lifecycle-tasks.test.ts +759 -0
- package/references/sessionlog/src/__tests__/opencode-agent.test.ts +338 -0
- package/references/sessionlog/src/__tests__/redaction.test.ts +136 -0
- package/references/sessionlog/src/__tests__/session-repo.test.ts +353 -0
- package/references/sessionlog/src/__tests__/session-store.test.ts +166 -0
- package/references/sessionlog/src/__tests__/setup-ccweb.test.ts +466 -0
- package/references/sessionlog/src/__tests__/skill-live.test.ts +461 -0
- package/references/sessionlog/src/__tests__/summarize.test.ts +348 -0
- package/references/sessionlog/src/__tests__/task-plan-e2e.test.ts +610 -0
- package/references/sessionlog/src/__tests__/task-plan-live.test.ts +632 -0
- package/references/sessionlog/src/__tests__/transcript-timestamp.test.ts +121 -0
- package/references/sessionlog/src/__tests__/types.test.ts +166 -0
- package/references/sessionlog/src/__tests__/utils.test.ts +333 -0
- package/references/sessionlog/src/__tests__/validation.test.ts +103 -0
- package/references/sessionlog/src/__tests__/worktree.test.ts +57 -0
- package/references/sessionlog/src/agent/registry.ts +143 -0
- package/references/sessionlog/src/agent/session-types.ts +113 -0
- package/references/sessionlog/src/agent/types.ts +220 -0
- package/references/sessionlog/src/cli.ts +597 -0
- package/references/sessionlog/src/commands/clean.ts +133 -0
- package/references/sessionlog/src/commands/disable.ts +84 -0
- package/references/sessionlog/src/commands/doctor.ts +145 -0
- package/references/sessionlog/src/commands/enable.ts +202 -0
- package/references/sessionlog/src/commands/explain.ts +261 -0
- package/references/sessionlog/src/commands/reset.ts +105 -0
- package/references/sessionlog/src/commands/resume.ts +180 -0
- package/references/sessionlog/src/commands/rewind.ts +195 -0
- package/references/sessionlog/src/commands/setup-ccweb.ts +275 -0
- package/references/sessionlog/src/commands/status.ts +172 -0
- package/references/sessionlog/src/config.ts +165 -0
- package/references/sessionlog/src/events/event-log.ts +126 -0
- package/references/sessionlog/src/git-operations.ts +558 -0
- package/references/sessionlog/src/hooks/git-hooks.ts +165 -0
- package/references/sessionlog/src/hooks/lifecycle.ts +391 -0
- package/references/sessionlog/src/index.ts +650 -0
- package/references/sessionlog/src/security/redaction.ts +283 -0
- package/references/sessionlog/src/session/state-machine.ts +452 -0
- package/references/sessionlog/src/store/checkpoint-store.ts +509 -0
- package/references/sessionlog/src/store/native-store.ts +173 -0
- package/references/sessionlog/src/store/provider-types.ts +99 -0
- package/references/sessionlog/src/store/session-store.ts +266 -0
- package/references/sessionlog/src/strategy/attribution.ts +296 -0
- package/references/sessionlog/src/strategy/common.ts +207 -0
- package/references/sessionlog/src/strategy/content-overlap.ts +228 -0
- package/references/sessionlog/src/strategy/manual-commit.ts +988 -0
- package/references/sessionlog/src/strategy/types.ts +279 -0
- package/references/sessionlog/src/summarize/claude-generator.ts +115 -0
- package/references/sessionlog/src/summarize/summarize.ts +432 -0
- package/references/sessionlog/src/types.ts +508 -0
- package/references/sessionlog/src/utils/chunk-files.ts +49 -0
- package/references/sessionlog/src/utils/commit-message.ts +65 -0
- package/references/sessionlog/src/utils/detect-agent.ts +36 -0
- package/references/sessionlog/src/utils/hook-managers.ts +125 -0
- package/references/sessionlog/src/utils/ide-tags.ts +32 -0
- package/references/sessionlog/src/utils/paths.ts +79 -0
- package/references/sessionlog/src/utils/preview-rewind.ts +80 -0
- package/references/sessionlog/src/utils/rewind-conflict.ts +121 -0
- package/references/sessionlog/src/utils/shadow-branch.ts +109 -0
- package/references/sessionlog/src/utils/string-utils.ts +46 -0
- package/references/sessionlog/src/utils/todo-extract.ts +188 -0
- package/references/sessionlog/src/utils/trailers.ts +187 -0
- package/references/sessionlog/src/utils/transcript-parse.ts +177 -0
- package/references/sessionlog/src/utils/transcript-timestamp.ts +59 -0
- package/references/sessionlog/src/utils/tree-ops.ts +219 -0
- package/references/sessionlog/src/utils/tty.ts +72 -0
- package/references/sessionlog/src/utils/validation.ts +65 -0
- package/references/sessionlog/src/utils/worktree.ts +58 -0
- package/references/sessionlog/src/wire-types.ts +59 -0
- package/references/sessionlog/templates/setup-env.sh +153 -0
- package/references/sessionlog/tsconfig.json +18 -0
- package/references/sessionlog/vitest.config.ts +12 -0
- package/references/skill-tree/.claude/settings.json +6 -0
- package/references/skill-tree/.sudocode/issues.jsonl +19 -0
- package/references/skill-tree/.sudocode/specs.jsonl +3 -0
- package/references/skill-tree/CLAUDE.md +132 -0
- package/references/skill-tree/README.md +396 -0
- package/references/skill-tree/docs/GAPS_v1.md +221 -0
- package/references/skill-tree/docs/INTEGRATION_PLAN.md +467 -0
- package/references/skill-tree/docs/TODOS.md +91 -0
- package/references/skill-tree/docs/anthropic_skill_guide.md +1364 -0
- package/references/skill-tree/docs/design/federated-skill-trees.md +524 -0
- package/references/skill-tree/docs/design/multi-agent-sync.md +759 -0
- package/references/skill-tree/docs/scraper/BRAINSTORM.md +583 -0
- package/references/skill-tree/docs/scraper/POC_PLAN.md +420 -0
- package/references/skill-tree/docs/scraper/README.md +170 -0
- package/references/skill-tree/examples/basic-usage.ts +157 -0
- package/references/skill-tree/package-lock.json +1852 -0
- package/references/skill-tree/package.json +66 -0
- package/references/skill-tree/plan.md +78 -0
- package/references/skill-tree/scraper/README.md +123 -0
- package/references/skill-tree/scraper/docs/DESIGN.md +683 -0
- package/references/skill-tree/scraper/docs/PLAN.md +336 -0
- package/references/skill-tree/scraper/drizzle.config.ts +10 -0
- package/references/skill-tree/scraper/package-lock.json +6329 -0
- package/references/skill-tree/scraper/package.json +68 -0
- package/references/skill-tree/scraper/test/fixtures/invalid-skill/missing-description.md +7 -0
- package/references/skill-tree/scraper/test/fixtures/invalid-skill/missing-name.md +7 -0
- package/references/skill-tree/scraper/test/fixtures/minimal-skill/SKILL.md +27 -0
- package/references/skill-tree/scraper/test/fixtures/skill-json/SKILL.json +21 -0
- package/references/skill-tree/scraper/test/fixtures/skill-with-meta/SKILL.md +54 -0
- package/references/skill-tree/scraper/test/fixtures/skill-with-meta/_meta.json +24 -0
- package/references/skill-tree/scraper/test/fixtures/valid-skill/SKILL.md +93 -0
- package/references/skill-tree/scraper/test/fixtures/valid-skill/_meta.json +22 -0
- package/references/skill-tree/scraper/tsup.config.ts +14 -0
- package/references/skill-tree/scraper/vitest.config.ts +17 -0
- package/references/skill-tree/scripts/convert-to-vitest.ts +166 -0
- package/references/skill-tree/skills/skill-writer/SKILL.md +339 -0
- package/references/skill-tree/skills/skill-writer/references/examples.md +326 -0
- package/references/skill-tree/skills/skill-writer/references/patterns.md +210 -0
- package/references/skill-tree/skills/skill-writer/references/quality-checklist.md +123 -0
- package/references/skill-tree/test/run-all.ts +106 -0
- package/references/skill-tree/test/utils.ts +128 -0
- package/references/skill-tree/vitest.config.ts +16 -0
- package/references/swarmkit/LICENSE +21 -0
- package/references/swarmkit/README.md +130 -0
- package/references/swarmkit/docs/design.md +453 -0
- package/references/swarmkit/docs/package-setup-reference.md +519 -0
- package/references/swarmkit/package-lock.json +1938 -0
- package/references/swarmkit/package.json +43 -0
- package/references/swarmkit/src/cli.ts +41 -0
- package/references/swarmkit/src/commands/add.ts +126 -0
- package/references/swarmkit/src/commands/doctor.ts +117 -0
- package/references/swarmkit/src/commands/hive.ts +279 -0
- package/references/swarmkit/src/commands/init/phases/configure.ts +74 -0
- package/references/swarmkit/src/commands/init/phases/global-setup.ts +104 -0
- package/references/swarmkit/src/commands/init/phases/packages.ts +44 -0
- package/references/swarmkit/src/commands/init/phases/project.ts +81 -0
- package/references/swarmkit/src/commands/init/phases/use-case.ts +47 -0
- package/references/swarmkit/src/commands/init/state.test.ts +23 -0
- package/references/swarmkit/src/commands/init/state.ts +22 -0
- package/references/swarmkit/src/commands/init/wizard.ts +160 -0
- package/references/swarmkit/src/commands/init.ts +17 -0
- package/references/swarmkit/src/commands/login.ts +106 -0
- package/references/swarmkit/src/commands/logout.ts +22 -0
- package/references/swarmkit/src/commands/remove.ts +72 -0
- package/references/swarmkit/src/commands/status.ts +101 -0
- package/references/swarmkit/src/commands/update.ts +62 -0
- package/references/swarmkit/src/commands/whoami.ts +41 -0
- package/references/swarmkit/src/config/global.test.ts +258 -0
- package/references/swarmkit/src/config/global.ts +141 -0
- package/references/swarmkit/src/config/keys.test.ts +109 -0
- package/references/swarmkit/src/config/keys.ts +49 -0
- package/references/swarmkit/src/doctor/checks.test.ts +366 -0
- package/references/swarmkit/src/doctor/checks.ts +292 -0
- package/references/swarmkit/src/doctor/types.ts +33 -0
- package/references/swarmkit/src/hub/auth-flow.test.ts +127 -0
- package/references/swarmkit/src/hub/auth-flow.ts +144 -0
- package/references/swarmkit/src/hub/client.test.ts +224 -0
- package/references/swarmkit/src/hub/client.ts +185 -0
- package/references/swarmkit/src/hub/credentials.test.ts +132 -0
- package/references/swarmkit/src/hub/credentials.ts +51 -0
- package/references/swarmkit/src/index.ts +116 -0
- package/references/swarmkit/src/packages/installer.test.ts +365 -0
- package/references/swarmkit/src/packages/installer.ts +206 -0
- package/references/swarmkit/src/packages/plugin.test.ts +141 -0
- package/references/swarmkit/src/packages/plugin.ts +46 -0
- package/references/swarmkit/src/packages/registry.test.ts +235 -0
- package/references/swarmkit/src/packages/registry.ts +209 -0
- package/references/swarmkit/src/packages/setup.test.ts +1395 -0
- package/references/swarmkit/src/packages/setup.ts +671 -0
- package/references/swarmkit/src/utils/ui.test.ts +115 -0
- package/references/swarmkit/src/utils/ui.ts +62 -0
- package/references/swarmkit/tsconfig.json +17 -0
- package/references/swarmkit/vitest.config.ts +9 -0
- package/scripts/bootstrap.mjs +33 -1
- package/scripts/generate-agents.mjs +5 -1
- package/scripts/map-hook.mjs +100 -63
- package/scripts/map-sidecar.mjs +198 -25
- package/scripts/team-loader.mjs +26 -48
- package/skills/swarm/SKILL.md +85 -27
- package/src/__tests__/agent-generator.test.mjs +15 -23
- package/src/__tests__/bootstrap.test.mjs +124 -1
- package/src/__tests__/config.test.mjs +72 -27
- package/src/__tests__/context-output.test.mjs +13 -14
- package/src/__tests__/e2e-inbox-integration.test.mjs +732 -0
- package/src/__tests__/e2e-live-inbox.test.mjs +597 -0
- package/src/__tests__/e2e-live-map.test.mjs +536 -0
- package/src/__tests__/e2e-mesh-sidecar.test.mjs +570 -0
- package/src/__tests__/e2e-native-task-hooks.test.mjs +376 -0
- package/src/__tests__/e2e-sidecar-bridge.test.mjs +477 -0
- package/src/__tests__/helpers.mjs +13 -0
- package/src/__tests__/inbox-integration.test.mjs +298 -0
- package/src/__tests__/inbox.test.mjs +22 -89
- package/src/__tests__/index.test.mjs +33 -9
- package/src/__tests__/integration.test.mjs +514 -0
- package/src/__tests__/map-events.test.mjs +514 -150
- package/src/__tests__/mesh-connection.test.mjs +308 -0
- package/src/__tests__/opentasks-client.test.mjs +517 -0
- package/src/__tests__/paths.test.mjs +185 -54
- package/src/__tests__/sidecar-client.test.mjs +35 -0
- package/src/__tests__/sidecar-server.test.mjs +124 -0
- package/src/__tests__/skilltree-client.test.mjs +126 -0
- package/src/agent-generator.mjs +129 -67
- package/src/bootstrap.mjs +174 -13
- package/src/config.mjs +35 -1
- package/src/context-output.mjs +254 -30
- package/src/inbox.mjs +9 -54
- package/src/index.mjs +38 -7
- package/src/map-connection.mjs +1 -0
- package/src/map-events.mjs +350 -80
- package/src/mesh-connection.mjs +148 -0
- package/src/opentasks-client.mjs +269 -0
- package/src/paths.mjs +178 -28
- package/src/sessionlog.mjs +14 -9
- package/src/sidecar-client.mjs +79 -25
- package/src/sidecar-server.mjs +205 -16
- package/src/skilltree-client.mjs +218 -0
- package/src/template.mjs +68 -4
- package/vitest.config.mjs +1 -0
|
@@ -0,0 +1,1638 @@
|
|
|
1
|
+
# OpenTasks Persistence Layer
|
|
2
|
+
|
|
3
|
+
This document describes the persistence architecture for OpenTasks. The design enables flexible, pluggable storage while maintaining a consistent graph data model.
|
|
4
|
+
|
|
5
|
+
**See also:** [DESIGN.md](./DESIGN.md) (vision) · [SCHEMA.md](./SCHEMA.md) (data model) · [ARCHITECTURE.md](./ARCHITECTURE.md) (hierarchy, daemon) · [PROVIDERS.md](./PROVIDERS.md) (integrations) · [INTERFACE.md](./INTERFACE.md) (API)
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Design Goals
|
|
10
|
+
|
|
11
|
+
1. **Modular persisters** — Pluggable storage backends (like [TinyBase](https://tinybase.org/guides/persistence/))
|
|
12
|
+
2. **Git-native source of truth** — JSONL files for version control (like beads/sudocode)
|
|
13
|
+
3. **Fast queries** — SQLite cache layer for complex queries
|
|
14
|
+
4. **Agent-friendly editing** — Markdown file expansion for direct file editing
|
|
15
|
+
5. **Incremental sync** — Dirty tracking to minimize writes
|
|
16
|
+
6. **Multi-location support** — Worktrees, redirects, delegated storage
|
|
17
|
+
7. **Provider integration** — Delegate to underlying systems (beads, etc.)
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Architecture Overview
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
25
|
+
│ Application Layer │
|
|
26
|
+
│ (Graph operations, queries, mutations) │
|
|
27
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
28
|
+
↓
|
|
29
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
30
|
+
│ Persistence Manager │
|
|
31
|
+
│ - Coordinates persisters │
|
|
32
|
+
│ - Manages dirty tracking │
|
|
33
|
+
│ - Handles flush scheduling │
|
|
34
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
35
|
+
↓
|
|
36
|
+
┌─────────────────────────────────────────────────────────────────┐
|
|
37
|
+
│ Persister Interface │
|
|
38
|
+
│ getPersisted() | setPersisted() | subscribe() | unsubscribe() │
|
|
39
|
+
└─────────────────────────────────────────────────────────────────┘
|
|
40
|
+
↓ ↓ ↓
|
|
41
|
+
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────────┐
|
|
42
|
+
│ JSONL Persister │ │ SQLite Persister│ │ Markdown Persister │
|
|
43
|
+
│ (source of truth)│ │ (query cache) │ │ (file expansion) │
|
|
44
|
+
└─────────────────┘ └─────────────────┘ └─────────────────────────┘
|
|
45
|
+
↓ ↓ ↓
|
|
46
|
+
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────────┐
|
|
47
|
+
│ graph.jsonl │ │ cache.db │ │ context/*.md, tasks/*.md│
|
|
48
|
+
│ (git-tracked) │ │ (gitignored) │ │ (git-tracked) │
|
|
49
|
+
└─────────────────┘ └─────────────────┘ └─────────────────────────┘
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Persister Interface
|
|
55
|
+
|
|
56
|
+
Inspired by [TinyBase's persister model](https://tinybase.org/guides/persistence/custom-persistence/), OpenTasks uses a modular interface for storage backends.
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
/**
|
|
60
|
+
* Core persister interface
|
|
61
|
+
* Each persister handles one storage format/location
|
|
62
|
+
*/
|
|
63
|
+
interface Persister<ListenerHandle = unknown> {
|
|
64
|
+
/** Unique identifier for this persister */
|
|
65
|
+
readonly id: string
|
|
66
|
+
|
|
67
|
+
/** Human-readable name */
|
|
68
|
+
readonly name: string
|
|
69
|
+
|
|
70
|
+
/** Persister capabilities */
|
|
71
|
+
readonly capabilities: PersisterCapabilities
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Load graph data from persistence layer
|
|
75
|
+
* Returns null/undefined if no data exists
|
|
76
|
+
*/
|
|
77
|
+
getPersisted(): Promise<PersistedGraph | null | undefined>
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Save graph data to persistence layer
|
|
81
|
+
* @param getContent - Function to get current graph state
|
|
82
|
+
* @param changes - Optional incremental changes (for dirty tracking)
|
|
83
|
+
*/
|
|
84
|
+
setPersisted(
|
|
85
|
+
getContent: () => PersistedGraph,
|
|
86
|
+
changes?: GraphChanges
|
|
87
|
+
): Promise<void>
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Subscribe to external changes in persistence layer
|
|
91
|
+
* @param listener - Called when external changes detected
|
|
92
|
+
* @returns Handle for unsubscribing
|
|
93
|
+
*/
|
|
94
|
+
subscribe(listener: PersisterListener): ListenerHandle
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Unsubscribe from external changes
|
|
98
|
+
*/
|
|
99
|
+
unsubscribe(handle: ListenerHandle): void
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Optional: Destroy/cleanup resources
|
|
103
|
+
*/
|
|
104
|
+
destroy?(): Promise<void>
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
interface PersisterCapabilities {
|
|
108
|
+
/** Can read data */
|
|
109
|
+
read: boolean
|
|
110
|
+
/** Can write data */
|
|
111
|
+
write: boolean
|
|
112
|
+
/** Can watch for external changes */
|
|
113
|
+
watch: boolean
|
|
114
|
+
/** Supports incremental updates (vs full rewrite) */
|
|
115
|
+
incremental: boolean
|
|
116
|
+
/** Is source of truth (vs cache) */
|
|
117
|
+
authoritative: boolean
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
interface PersistedGraph {
|
|
121
|
+
nodes: StoredNode[]
|
|
122
|
+
edges: StoredEdge[]
|
|
123
|
+
metadata?: GraphMetadata
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
interface GraphChanges {
|
|
127
|
+
/** Nodes that were added/modified */
|
|
128
|
+
dirtyNodes: string[]
|
|
129
|
+
/** Nodes that were deleted */
|
|
130
|
+
deletedNodes: string[]
|
|
131
|
+
/** Edges that were added/modified */
|
|
132
|
+
dirtyEdges: string[]
|
|
133
|
+
/** Edges that were deleted */
|
|
134
|
+
deletedEdges: string[]
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
type PersisterListener = (changes?: GraphChanges) => void
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Built-in Persisters
|
|
143
|
+
|
|
144
|
+
### 1. JSONL Persister (Source of Truth)
|
|
145
|
+
|
|
146
|
+
Primary storage format, git-tracked and merge-friendly.
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
interface JSONLPersisterConfig {
|
|
150
|
+
/** Path to JSONL file(s) */
|
|
151
|
+
path: string | {
|
|
152
|
+
nodes: string // e.g., "graph.jsonl" or split files
|
|
153
|
+
edges?: string // e.g., "edges.jsonl"
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/** Whether to split by node type */
|
|
157
|
+
splitByType?: boolean // context.jsonl, tasks.jsonl, etc.
|
|
158
|
+
|
|
159
|
+
/** Atomic write strategy */
|
|
160
|
+
atomicWrite?: 'rename' | 'write-sync' | 'none'
|
|
161
|
+
|
|
162
|
+
/** Content hashing for dedup */
|
|
163
|
+
contentHashing?: boolean
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
const jsonlPersister = createJSONLPersister({
|
|
167
|
+
path: '.opentasks/graph.jsonl',
|
|
168
|
+
atomicWrite: 'rename',
|
|
169
|
+
contentHashing: true,
|
|
170
|
+
})
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**Features:**
|
|
174
|
+
- **Append-only writes** — updates append a new line with the same ID and newer `updated_at` (never overwrite in-place)
|
|
175
|
+
- Content hashing to detect actual changes
|
|
176
|
+
- On load, deduplicate by keeping latest `updated_at` per ID
|
|
177
|
+
- Custom merge driver for conflict-free git merges (see [plans/PHASE-3.md](./plans/PHASE-3.md))
|
|
178
|
+
- Periodic compaction to remove duplicate entries
|
|
179
|
+
|
|
180
|
+
**File Format:**
|
|
181
|
+
```jsonl
|
|
182
|
+
{"id":"c-a2b3","type":"context","title":"Auth requirements",...}
|
|
183
|
+
{"id":"t-x7k9","type":"task","title":"Implement login",...}
|
|
184
|
+
{"id":"x-r8s9","type":"edge","from_id":"t-x7k9","to_id":"c-a2b3",...}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### 2. SQLite Persister (Query Cache)
|
|
188
|
+
|
|
189
|
+
Fast query layer, rebuilt from JSONL.
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
interface SQLitePersisterConfig {
|
|
193
|
+
/** Path to database file */
|
|
194
|
+
path: string // e.g., ".opentasks/cache.db"
|
|
195
|
+
|
|
196
|
+
/** WAL mode for better concurrency */
|
|
197
|
+
walMode?: boolean
|
|
198
|
+
|
|
199
|
+
/** Rebuild triggers */
|
|
200
|
+
rebuildOn?: ('startup' | 'jsonl-change' | 'manual')[]
|
|
201
|
+
|
|
202
|
+
/** Indexes to create */
|
|
203
|
+
indexes?: IndexConfig[]
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const sqlitePersister = createSQLitePersister({
|
|
207
|
+
path: '.opentasks/cache.db',
|
|
208
|
+
walMode: true,
|
|
209
|
+
rebuildOn: ['startup', 'jsonl-change'],
|
|
210
|
+
})
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**Features:**
|
|
214
|
+
- Indexes on common query patterns (status, priority, type, etc.)
|
|
215
|
+
- Views for computed queries (ready_issues, blocked_issues)
|
|
216
|
+
- Dirty tracking table for incremental export
|
|
217
|
+
- Content hash table for dedup
|
|
218
|
+
- Gitignored (ephemeral cache)
|
|
219
|
+
|
|
220
|
+
**Schema:**
|
|
221
|
+
```sql
|
|
222
|
+
-- Core tables
|
|
223
|
+
CREATE TABLE nodes (
|
|
224
|
+
id TEXT PRIMARY KEY,
|
|
225
|
+
uuid TEXT UNIQUE,
|
|
226
|
+
type TEXT NOT NULL,
|
|
227
|
+
title TEXT NOT NULL,
|
|
228
|
+
content TEXT,
|
|
229
|
+
status TEXT,
|
|
230
|
+
priority INTEGER,
|
|
231
|
+
-- ... other fields
|
|
232
|
+
content_hash TEXT,
|
|
233
|
+
created_at TEXT,
|
|
234
|
+
updated_at TEXT
|
|
235
|
+
);
|
|
236
|
+
|
|
237
|
+
CREATE TABLE edges (
|
|
238
|
+
id TEXT PRIMARY KEY,
|
|
239
|
+
from_id TEXT NOT NULL,
|
|
240
|
+
to_id TEXT NOT NULL,
|
|
241
|
+
type TEXT NOT NULL,
|
|
242
|
+
created_at TEXT
|
|
243
|
+
);
|
|
244
|
+
|
|
245
|
+
-- Dirty tracking
|
|
246
|
+
CREATE TABLE dirty_nodes (
|
|
247
|
+
node_id TEXT PRIMARY KEY,
|
|
248
|
+
marked_at TEXT NOT NULL
|
|
249
|
+
);
|
|
250
|
+
|
|
251
|
+
CREATE TABLE export_hashes (
|
|
252
|
+
node_id TEXT PRIMARY KEY,
|
|
253
|
+
content_hash TEXT NOT NULL
|
|
254
|
+
);
|
|
255
|
+
|
|
256
|
+
-- Metadata
|
|
257
|
+
CREATE TABLE metadata (
|
|
258
|
+
key TEXT PRIMARY KEY,
|
|
259
|
+
value TEXT
|
|
260
|
+
);
|
|
261
|
+
|
|
262
|
+
-- Views
|
|
263
|
+
CREATE VIEW ready_issues AS
|
|
264
|
+
SELECT i.* FROM nodes i
|
|
265
|
+
WHERE i.type = 'issue'
|
|
266
|
+
AND i.status = 'open'
|
|
267
|
+
AND i.archived IS NOT TRUE
|
|
268
|
+
AND NOT EXISTS (
|
|
269
|
+
SELECT 1 FROM edges e
|
|
270
|
+
JOIN nodes blocker ON e.from_id = blocker.id
|
|
271
|
+
WHERE e.to_id = i.id
|
|
272
|
+
AND e.type = 'blocks'
|
|
273
|
+
AND blocker.status != 'closed'
|
|
274
|
+
);
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### 3. Markdown Persister (File Expansion)
|
|
278
|
+
|
|
279
|
+
Expands nodes to individual markdown files for agent editing.
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
interface MarkdownPersisterConfig {
|
|
283
|
+
/** Base directory for markdown files */
|
|
284
|
+
basePath: string // e.g., ".opentasks/"
|
|
285
|
+
|
|
286
|
+
/** Directory structure */
|
|
287
|
+
structure: {
|
|
288
|
+
context?: string // e.g., "context/" → .opentasks/context/*.md
|
|
289
|
+
tasks?: string // e.g., "tasks/"
|
|
290
|
+
feedback?: string // e.g., "feedback/"
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/** Filename pattern */
|
|
294
|
+
filenamePattern?: 'id' | 'id-title' | 'title-slug'
|
|
295
|
+
|
|
296
|
+
/** Frontmatter format */
|
|
297
|
+
frontmatter?: 'yaml' | 'toml' | 'json'
|
|
298
|
+
|
|
299
|
+
/** Which node types to expand */
|
|
300
|
+
expandTypes?: NodeType[]
|
|
301
|
+
|
|
302
|
+
/** Bidirectional sync */
|
|
303
|
+
watchFiles?: boolean
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
const markdownPersister = createMarkdownPersister({
|
|
307
|
+
basePath: '.opentasks/',
|
|
308
|
+
structure: {
|
|
309
|
+
context: 'context/',
|
|
310
|
+
tasks: 'tasks/',
|
|
311
|
+
},
|
|
312
|
+
filenamePattern: 'id-title',
|
|
313
|
+
frontmatter: 'yaml',
|
|
314
|
+
watchFiles: true,
|
|
315
|
+
})
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
**Features:**
|
|
319
|
+
- Bidirectional sync (JSONL ↔ Markdown)
|
|
320
|
+
- Frontmatter for metadata, body for content
|
|
321
|
+
- File watcher for external changes
|
|
322
|
+
- Agents can edit markdown directly with standard tools
|
|
323
|
+
- Git-tracked alongside JSONL
|
|
324
|
+
|
|
325
|
+
**File Format:**
|
|
326
|
+
```markdown
|
|
327
|
+
---
|
|
328
|
+
id: c-a2b3
|
|
329
|
+
type: context
|
|
330
|
+
title: Authentication Requirements
|
|
331
|
+
status: active
|
|
332
|
+
priority: 1
|
|
333
|
+
tags:
|
|
334
|
+
- auth
|
|
335
|
+
- security
|
|
336
|
+
created_at: 2025-01-26T10:00:00Z
|
|
337
|
+
updated_at: 2025-01-26T10:00:00Z
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## Overview
|
|
341
|
+
|
|
342
|
+
Users should be able to authenticate using OAuth2...
|
|
343
|
+
|
|
344
|
+
## Requirements
|
|
345
|
+
|
|
346
|
+
1. Support Google and GitHub OAuth providers
|
|
347
|
+
2. Session management with secure cookies
|
|
348
|
+
3. ...
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
### 4. Provider Persister (Delegated Storage)
|
|
352
|
+
|
|
353
|
+
Delegates storage to an underlying system (beads, sudocode, etc.).
|
|
354
|
+
|
|
355
|
+
```typescript
|
|
356
|
+
interface ProviderPersisterConfig {
|
|
357
|
+
/** Provider integration to use */
|
|
358
|
+
provider: Integration
|
|
359
|
+
|
|
360
|
+
/** Sync direction */
|
|
361
|
+
direction: 'read-only' | 'write-through' | 'bidirectional'
|
|
362
|
+
|
|
363
|
+
/** Conflict resolution */
|
|
364
|
+
conflictStrategy: 'local-wins' | 'remote-wins' | 'manual'
|
|
365
|
+
|
|
366
|
+
/** Node filter (which nodes to delegate) */
|
|
367
|
+
filter?: (node: Node) => boolean
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
const beadsPersister = createProviderPersister({
|
|
371
|
+
provider: beadsIntegration,
|
|
372
|
+
direction: 'bidirectional',
|
|
373
|
+
conflictStrategy: 'remote-wins',
|
|
374
|
+
filter: (node) => node.source === 'beads',
|
|
375
|
+
})
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
**Features:**
|
|
379
|
+
- Routes operations to underlying provider
|
|
380
|
+
- Respects provider's native storage format
|
|
381
|
+
- Syncs changes bidirectionally
|
|
382
|
+
- Can filter which nodes are delegated
|
|
383
|
+
|
|
384
|
+
---
|
|
385
|
+
|
|
386
|
+
## Persistence Manager
|
|
387
|
+
|
|
388
|
+
Coordinates multiple persisters with priority and sync logic.
|
|
389
|
+
|
|
390
|
+
```typescript
|
|
391
|
+
interface PersistenceManagerConfig {
|
|
392
|
+
/** Ordered list of persisters (first = highest priority for reads) */
|
|
393
|
+
persisters: Persister[]
|
|
394
|
+
|
|
395
|
+
/** Flush configuration */
|
|
396
|
+
flush: {
|
|
397
|
+
/** Debounce delay for batching writes */
|
|
398
|
+
debounceMs: number // e.g., 5000 (5 seconds)
|
|
399
|
+
|
|
400
|
+
/** Maximum delay before forced flush */
|
|
401
|
+
maxDelayMs: number // e.g., 30000 (30 seconds)
|
|
402
|
+
|
|
403
|
+
/** Flush on shutdown */
|
|
404
|
+
flushOnShutdown: boolean
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/** Sync configuration */
|
|
408
|
+
sync: {
|
|
409
|
+
/** Auto-import on external changes */
|
|
410
|
+
autoImport: boolean
|
|
411
|
+
|
|
412
|
+
/** Auto-export dirty nodes */
|
|
413
|
+
autoExport: boolean
|
|
414
|
+
|
|
415
|
+
/** Incremental threshold (full export if more dirty) */
|
|
416
|
+
incrementalThreshold: number // e.g., 1000
|
|
417
|
+
incrementalRatio: number // e.g., 0.2 (20%)
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
class PersistenceManager {
|
|
422
|
+
constructor(config: PersistenceManagerConfig)
|
|
423
|
+
|
|
424
|
+
/** Load graph from persisters (merges with priority) */
|
|
425
|
+
async load(): Promise<Graph>
|
|
426
|
+
|
|
427
|
+
/** Mark nodes as dirty (triggers flush scheduling) */
|
|
428
|
+
markDirty(nodeIds: string[]): void
|
|
429
|
+
|
|
430
|
+
/** Force immediate flush */
|
|
431
|
+
async flush(): Promise<void>
|
|
432
|
+
|
|
433
|
+
/** Shutdown with final flush */
|
|
434
|
+
async shutdown(): Promise<void>
|
|
435
|
+
|
|
436
|
+
/** Subscribe to graph changes (from any persister) */
|
|
437
|
+
subscribe(listener: GraphListener): () => void
|
|
438
|
+
}
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
### Flush Manager
|
|
442
|
+
|
|
443
|
+
Event-driven flush coordination (inspired by beads' FlushManager).
|
|
444
|
+
|
|
445
|
+
```typescript
|
|
446
|
+
/**
|
|
447
|
+
* FlushManager handles debounced, batched writes
|
|
448
|
+
* Single goroutine/async loop owns all state (no locks needed)
|
|
449
|
+
*/
|
|
450
|
+
class FlushManager {
|
|
451
|
+
private dirtyNodes: Set<string> = new Set()
|
|
452
|
+
private debounceTimer: Timer | null = null
|
|
453
|
+
private maxDelayTimer: Timer | null = null
|
|
454
|
+
|
|
455
|
+
/** Mark node as dirty, schedule flush */
|
|
456
|
+
markDirty(nodeId: string): void {
|
|
457
|
+
this.dirtyNodes.add(nodeId)
|
|
458
|
+
this.scheduleFlush()
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/** Schedule debounced flush */
|
|
462
|
+
private scheduleFlush(): void {
|
|
463
|
+
// Reset debounce timer
|
|
464
|
+
if (this.debounceTimer) clearTimeout(this.debounceTimer)
|
|
465
|
+
this.debounceTimer = setTimeout(() => this.flush(), this.debounceMs)
|
|
466
|
+
|
|
467
|
+
// Start max delay timer if not running
|
|
468
|
+
if (!this.maxDelayTimer) {
|
|
469
|
+
this.maxDelayTimer = setTimeout(() => this.flush(), this.maxDelayMs)
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/** Execute flush */
|
|
474
|
+
private async flush(): Promise<void> {
|
|
475
|
+
if (this.dirtyNodes.size === 0) return
|
|
476
|
+
|
|
477
|
+
const toFlush = new Set(this.dirtyNodes)
|
|
478
|
+
this.dirtyNodes.clear()
|
|
479
|
+
this.clearTimers()
|
|
480
|
+
|
|
481
|
+
// Determine full vs incremental export
|
|
482
|
+
const totalNodes = await this.getTotalNodeCount()
|
|
483
|
+
const dirtyRatio = toFlush.size / totalNodes
|
|
484
|
+
const useIncremental =
|
|
485
|
+
totalNodes > this.incrementalThreshold &&
|
|
486
|
+
dirtyRatio < this.incrementalRatio
|
|
487
|
+
|
|
488
|
+
// Execute flush on each persister
|
|
489
|
+
for (const persister of this.persisters) {
|
|
490
|
+
if (persister.capabilities.write) {
|
|
491
|
+
await persister.setPersisted(
|
|
492
|
+
() => this.getGraphContent(),
|
|
493
|
+
useIncremental ? { dirtyNodes: [...toFlush] } : undefined
|
|
494
|
+
)
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
---
|
|
502
|
+
|
|
503
|
+
## Dirty Tracking
|
|
504
|
+
|
|
505
|
+
Track which nodes have changed for incremental sync.
|
|
506
|
+
|
|
507
|
+
```typescript
|
|
508
|
+
interface DirtyTracker {
|
|
509
|
+
/** Mark node as dirty */
|
|
510
|
+
markDirty(nodeId: string): void
|
|
511
|
+
|
|
512
|
+
/** Mark multiple nodes as dirty */
|
|
513
|
+
markDirtyBatch(nodeIds: string[]): void
|
|
514
|
+
|
|
515
|
+
/** Get all dirty node IDs */
|
|
516
|
+
getDirtyNodes(): string[]
|
|
517
|
+
|
|
518
|
+
/** Clear dirty status for exported nodes */
|
|
519
|
+
clearDirty(nodeIds: string[]): void
|
|
520
|
+
|
|
521
|
+
/** Clear all dirty status */
|
|
522
|
+
clearAll(): void
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
interface ContentHashTracker {
|
|
526
|
+
/** Get last exported hash for node */
|
|
527
|
+
getExportHash(nodeId: string): string | null
|
|
528
|
+
|
|
529
|
+
/** Set export hash after successful export */
|
|
530
|
+
setExportHash(nodeId: string, hash: string): void
|
|
531
|
+
|
|
532
|
+
/** Check if node content has changed */
|
|
533
|
+
hasChanged(nodeId: string, currentHash: string): boolean
|
|
534
|
+
|
|
535
|
+
/** Clear all hashes (forces full re-export) */
|
|
536
|
+
clearAll(): void
|
|
537
|
+
}
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
**Integration with SQLite cache:**
|
|
541
|
+
```sql
|
|
542
|
+
-- Mark node dirty
|
|
543
|
+
INSERT OR REPLACE INTO dirty_nodes (node_id, marked_at)
|
|
544
|
+
VALUES (?, datetime('now'));
|
|
545
|
+
|
|
546
|
+
-- Get dirty nodes (ordered by marked time)
|
|
547
|
+
SELECT node_id FROM dirty_nodes ORDER BY marked_at;
|
|
548
|
+
|
|
549
|
+
-- Clear dirty after export
|
|
550
|
+
DELETE FROM dirty_nodes WHERE node_id IN (?);
|
|
551
|
+
|
|
552
|
+
-- Track export hashes
|
|
553
|
+
INSERT OR REPLACE INTO export_hashes (node_id, content_hash)
|
|
554
|
+
VALUES (?, ?);
|
|
555
|
+
|
|
556
|
+
-- Check if changed
|
|
557
|
+
SELECT content_hash FROM export_hashes WHERE node_id = ?;
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
---
|
|
561
|
+
|
|
562
|
+
## Multi-Location Support
|
|
563
|
+
|
|
564
|
+
### Location Identity
|
|
565
|
+
|
|
566
|
+
Each `.opentasks/` directory has a deterministic identity. See [plans/PHASE-2.md](./plans/PHASE-2.md) for full specification.
|
|
567
|
+
|
|
568
|
+
```typescript
|
|
569
|
+
interface Location {
|
|
570
|
+
/** Deterministic hash: SHA256(git_remote_url + ":" + repo_relative_path) → 8-char base36 */
|
|
571
|
+
hash: string
|
|
572
|
+
|
|
573
|
+
/** Random UUID v4 for uniqueness guarantee */
|
|
574
|
+
uuid: string
|
|
575
|
+
|
|
576
|
+
/** Human-readable name */
|
|
577
|
+
name: string
|
|
578
|
+
}
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
### Explicit Connections (Not Discovery)
|
|
582
|
+
|
|
583
|
+
Locations declare connections explicitly in `config.json`. No filesystem discovery at runtime.
|
|
584
|
+
|
|
585
|
+
```typescript
|
|
586
|
+
interface Connection {
|
|
587
|
+
/** Location hash of the target */
|
|
588
|
+
hash: string
|
|
589
|
+
|
|
590
|
+
/** Relative or absolute path to target's .opentasks/ */
|
|
591
|
+
path: string
|
|
592
|
+
|
|
593
|
+
/** Relationship: peer, parent, worker, manager */
|
|
594
|
+
role: string
|
|
595
|
+
|
|
596
|
+
/** Human-readable name */
|
|
597
|
+
name?: string
|
|
598
|
+
}
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
### Redirect Support (Role-Based)
|
|
602
|
+
|
|
603
|
+
For worktree and multi-location scenarios. Redirects use **roles** (set by orchestrator in config), not agent identity.
|
|
604
|
+
|
|
605
|
+
```typescript
|
|
606
|
+
interface RedirectRule {
|
|
607
|
+
/** Operations to redirect */
|
|
608
|
+
operations: ('read' | 'write')[]
|
|
609
|
+
|
|
610
|
+
/** Pattern for node IDs (glob): "*", "i-*", "s-*" */
|
|
611
|
+
pattern: string
|
|
612
|
+
|
|
613
|
+
/** Target location (hash URI or relative path) */
|
|
614
|
+
target: string
|
|
615
|
+
|
|
616
|
+
/** Lower = higher priority, default 100 */
|
|
617
|
+
priority: number
|
|
618
|
+
|
|
619
|
+
/** What to do if target unreachable */
|
|
620
|
+
fallback: 'local' | 'error'
|
|
621
|
+
|
|
622
|
+
/** Conditions (optional) */
|
|
623
|
+
when?: {
|
|
624
|
+
role?: string // from config.json role field (trusted)
|
|
625
|
+
branch?: string // git branch glob pattern
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
Rule evaluation: sorted by priority (ascending), first match wins. Max redirect depth: 3 hops.
|
|
631
|
+
|
|
632
|
+
### Worktree Registration (Explicit, Not Passive)
|
|
633
|
+
|
|
634
|
+
Worktrees are registered explicitly via `opentasks worktree setup`, not auto-detected from `.git` files. This stores actual paths and avoids assumptions about directory layout.
|
|
635
|
+
|
|
636
|
+
```typescript
|
|
637
|
+
interface RegisteredWorktree {
|
|
638
|
+
/** Worktree root path */
|
|
639
|
+
path: string
|
|
640
|
+
|
|
641
|
+
/** Path to .opentasks/ directory */
|
|
642
|
+
opentasksPath: string
|
|
643
|
+
|
|
644
|
+
/** Location hash */
|
|
645
|
+
hash: string
|
|
646
|
+
|
|
647
|
+
/** Git branch */
|
|
648
|
+
branch: string
|
|
649
|
+
|
|
650
|
+
/** Role: manager or worker */
|
|
651
|
+
role: 'manager' | 'worker'
|
|
652
|
+
|
|
653
|
+
/** Location hash of redirect target (if worker) */
|
|
654
|
+
redirectTarget?: string
|
|
655
|
+
}
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
Registry stored at `.git/opentasks/worktrees.json` (shared across worktrees, daemon is sole writer).
|
|
659
|
+
|
|
660
|
+
See [plans/PHASE-3.md](./plans/PHASE-3.md) for worktree CLI specification.
|
|
661
|
+
|
|
662
|
+
---
|
|
663
|
+
|
|
664
|
+
## Sync Strategies
|
|
665
|
+
|
|
666
|
+
### Import Strategy
|
|
667
|
+
|
|
668
|
+
```typescript
|
|
669
|
+
interface ImportStrategy {
|
|
670
|
+
/** Detect if import needed */
|
|
671
|
+
needsImport(): Promise<boolean>
|
|
672
|
+
|
|
673
|
+
/** Execute import */
|
|
674
|
+
import(): Promise<ImportResult>
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
interface ImportResult {
|
|
678
|
+
imported: number
|
|
679
|
+
conflicts: ConflictInfo[]
|
|
680
|
+
errors: Error[]
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
// Content-hash based detection (git-proof)
|
|
684
|
+
class ContentHashImportStrategy implements ImportStrategy {
|
|
685
|
+
async needsImport(): Promise<boolean> {
|
|
686
|
+
const currentHash = await this.computeJSONLHash()
|
|
687
|
+
const storedHash = await this.getStoredJSONLHash()
|
|
688
|
+
return currentHash !== storedHash
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
```
|
|
692
|
+
|
|
693
|
+
### Export Strategy
|
|
694
|
+
|
|
695
|
+
```typescript
|
|
696
|
+
interface ExportStrategy {
|
|
697
|
+
/** Determine export mode */
|
|
698
|
+
getMode(): 'full' | 'incremental'
|
|
699
|
+
|
|
700
|
+
/** Execute export */
|
|
701
|
+
export(mode: 'full' | 'incremental'): Promise<ExportResult>
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
interface ExportResult {
|
|
705
|
+
exported: number
|
|
706
|
+
mode: 'full' | 'incremental'
|
|
707
|
+
duration: number
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
// Incremental with fallback to full
|
|
711
|
+
class HybridExportStrategy implements ExportStrategy {
|
|
712
|
+
getMode(): 'full' | 'incremental' {
|
|
713
|
+
const dirtyCount = this.getDirtyCount()
|
|
714
|
+
const totalCount = this.getTotalCount()
|
|
715
|
+
|
|
716
|
+
if (totalCount < this.incrementalThreshold) return 'full'
|
|
717
|
+
if (dirtyCount / totalCount > this.incrementalRatio) return 'full'
|
|
718
|
+
return 'incremental'
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
```
|
|
722
|
+
|
|
723
|
+
### Conflict Resolution
|
|
724
|
+
|
|
725
|
+
```typescript
|
|
726
|
+
interface ConflictResolver {
|
|
727
|
+
/** Detect conflicts */
|
|
728
|
+
detectConflicts(local: Node, remote: Node): Conflict | null
|
|
729
|
+
|
|
730
|
+
/** Resolve conflict */
|
|
731
|
+
resolve(conflict: Conflict, strategy: ConflictStrategy): Node
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
type ConflictStrategy =
|
|
735
|
+
| 'local-wins'
|
|
736
|
+
| 'remote-wins'
|
|
737
|
+
| 'newer-wins'
|
|
738
|
+
| 'merge'
|
|
739
|
+
| 'manual'
|
|
740
|
+
|
|
741
|
+
interface Conflict {
|
|
742
|
+
nodeId: string
|
|
743
|
+
local: Node
|
|
744
|
+
remote: Node
|
|
745
|
+
type: 'update-update' | 'update-delete' | 'delete-update'
|
|
746
|
+
}
|
|
747
|
+
```
|
|
748
|
+
|
|
749
|
+
---
|
|
750
|
+
|
|
751
|
+
## Atomic Operations
|
|
752
|
+
|
|
753
|
+
### Atomic File Writes
|
|
754
|
+
|
|
755
|
+
```typescript
|
|
756
|
+
/**
|
|
757
|
+
* Atomic write using temp file + rename
|
|
758
|
+
* Prevents partial writes on crash
|
|
759
|
+
*/
|
|
760
|
+
async function atomicWrite(
|
|
761
|
+
path: string,
|
|
762
|
+
content: string | Buffer
|
|
763
|
+
): Promise<void> {
|
|
764
|
+
const tempPath = `${path}.${process.pid}.tmp`
|
|
765
|
+
|
|
766
|
+
try {
|
|
767
|
+
await fs.writeFile(tempPath, content)
|
|
768
|
+
await fs.rename(tempPath, path)
|
|
769
|
+
} catch (error) {
|
|
770
|
+
// Clean up temp file on failure
|
|
771
|
+
await fs.unlink(tempPath).catch(() => {})
|
|
772
|
+
throw error
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
```
|
|
776
|
+
|
|
777
|
+
### Transaction Support
|
|
778
|
+
|
|
779
|
+
```typescript
|
|
780
|
+
interface Transaction {
|
|
781
|
+
/** Begin transaction */
|
|
782
|
+
begin(): Promise<void>
|
|
783
|
+
|
|
784
|
+
/** Commit transaction */
|
|
785
|
+
commit(): Promise<void>
|
|
786
|
+
|
|
787
|
+
/** Rollback transaction */
|
|
788
|
+
rollback(): Promise<void>
|
|
789
|
+
|
|
790
|
+
/** Execute in transaction */
|
|
791
|
+
execute<T>(fn: () => Promise<T>): Promise<T>
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
// Two-phase commit for multi-persister writes
|
|
795
|
+
class MultiPersisterTransaction implements Transaction {
|
|
796
|
+
async execute<T>(fn: () => Promise<T>): Promise<T> {
|
|
797
|
+
await this.begin()
|
|
798
|
+
try {
|
|
799
|
+
const result = await fn()
|
|
800
|
+
await this.commit()
|
|
801
|
+
return result
|
|
802
|
+
} catch (error) {
|
|
803
|
+
await this.rollback()
|
|
804
|
+
throw error
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
```
|
|
809
|
+
|
|
810
|
+
---
|
|
811
|
+
|
|
812
|
+
## Configuration
|
|
813
|
+
|
|
814
|
+
### Default Configuration
|
|
815
|
+
|
|
816
|
+
```typescript
|
|
817
|
+
const defaultPersistenceConfig: PersistenceManagerConfig = {
|
|
818
|
+
persisters: [
|
|
819
|
+
createJSONLPersister({
|
|
820
|
+
path: '.opentasks/graph.jsonl',
|
|
821
|
+
atomicWrite: 'rename',
|
|
822
|
+
contentHashing: true,
|
|
823
|
+
}),
|
|
824
|
+
createSQLitePersister({
|
|
825
|
+
path: '.opentasks/cache.db',
|
|
826
|
+
walMode: true,
|
|
827
|
+
rebuildOn: ['startup', 'jsonl-change'],
|
|
828
|
+
}),
|
|
829
|
+
],
|
|
830
|
+
|
|
831
|
+
flush: {
|
|
832
|
+
debounceMs: 5000,
|
|
833
|
+
maxDelayMs: 30000,
|
|
834
|
+
flushOnShutdown: true,
|
|
835
|
+
},
|
|
836
|
+
|
|
837
|
+
sync: {
|
|
838
|
+
autoImport: true,
|
|
839
|
+
autoExport: true,
|
|
840
|
+
incrementalThreshold: 1000,
|
|
841
|
+
incrementalRatio: 0.2,
|
|
842
|
+
},
|
|
843
|
+
}
|
|
844
|
+
```
|
|
845
|
+
|
|
846
|
+
### With Markdown Expansion
|
|
847
|
+
|
|
848
|
+
```typescript
|
|
849
|
+
const withMarkdownConfig: PersistenceManagerConfig = {
|
|
850
|
+
persisters: [
|
|
851
|
+
createJSONLPersister({ /* ... */ }),
|
|
852
|
+
createSQLitePersister({ /* ... */ }),
|
|
853
|
+
createMarkdownPersister({
|
|
854
|
+
basePath: '.opentasks/',
|
|
855
|
+
structure: {
|
|
856
|
+
context: 'context/',
|
|
857
|
+
tasks: 'tasks/',
|
|
858
|
+
},
|
|
859
|
+
watchFiles: true,
|
|
860
|
+
}),
|
|
861
|
+
],
|
|
862
|
+
// ...
|
|
863
|
+
}
|
|
864
|
+
```
|
|
865
|
+
|
|
866
|
+
### With Provider Delegation
|
|
867
|
+
|
|
868
|
+
```typescript
|
|
869
|
+
const withBeadsConfig: PersistenceManagerConfig = {
|
|
870
|
+
persisters: [
|
|
871
|
+
// Local storage for opentasks-native nodes
|
|
872
|
+
createJSONLPersister({ /* ... */ }),
|
|
873
|
+
createSQLitePersister({ /* ... */ }),
|
|
874
|
+
|
|
875
|
+
// Delegate to beads for beads-sourced nodes
|
|
876
|
+
createProviderPersister({
|
|
877
|
+
provider: beadsIntegration,
|
|
878
|
+
direction: 'bidirectional',
|
|
879
|
+
filter: (node) => node.source === 'beads',
|
|
880
|
+
}),
|
|
881
|
+
],
|
|
882
|
+
// ...
|
|
883
|
+
}
|
|
884
|
+
```
|
|
885
|
+
|
|
886
|
+
---
|
|
887
|
+
|
|
888
|
+
## File Structure
|
|
889
|
+
|
|
890
|
+
```
|
|
891
|
+
.opentasks/
|
|
892
|
+
├── graph.jsonl # Source of truth: nodes + edges, append-only (git-tracked)
|
|
893
|
+
├── tombstones.jsonl # Soft-deleted nodes (configurable gitignore)
|
|
894
|
+
├── cache.db # SQLite cache in WAL mode (gitignored, can be rebuilt)
|
|
895
|
+
├── config.json # Configuration, connections, role, redirects
|
|
896
|
+
├── write.lock # Advisory lock for JSONL writes (gitignored)
|
|
897
|
+
├── context/ # Optional: markdown expansion
|
|
898
|
+
│ ├── c-a2b3-auth-requirements.md
|
|
899
|
+
│ └── c-c4d5-api-design.md
|
|
900
|
+
└── tasks/ # Optional: markdown expansion
|
|
901
|
+
├── t-x7k9-implement-login.md
|
|
902
|
+
└── i-y8z0-add-tests.md
|
|
903
|
+
|
|
904
|
+
.git/opentasks/ # Shared across all worktrees (Phase 3)
|
|
905
|
+
├── daemon.sock # Single daemon socket
|
|
906
|
+
├── daemon.lock # Daemon PID lock
|
|
907
|
+
└── worktrees.json # Registered worktrees
|
|
908
|
+
```
|
|
909
|
+
|
|
910
|
+
See [plans/CORE-ARCHITECTURE.md](./plans/CORE-ARCHITECTURE.md) for cross-location architecture and daemon details.
|
|
911
|
+
|
|
912
|
+
**.gitignore:**
|
|
913
|
+
```gitignore
|
|
914
|
+
# Cache files (rebuilt from JSONL)
|
|
915
|
+
.opentasks/cache.db
|
|
916
|
+
.opentasks/cache.db-*
|
|
917
|
+
|
|
918
|
+
# Write lock
|
|
919
|
+
.opentasks/write.lock
|
|
920
|
+
|
|
921
|
+
# Temp files
|
|
922
|
+
.opentasks/*.tmp
|
|
923
|
+
|
|
924
|
+
# Optional: tombstones (user choice)
|
|
925
|
+
# .opentasks/tombstones.jsonl
|
|
926
|
+
```
|
|
927
|
+
|
|
928
|
+
**.gitattributes:**
|
|
929
|
+
```gitattributes
|
|
930
|
+
# Custom merge driver for conflict-free JSONL merges
|
|
931
|
+
.opentasks/graph.jsonl merge=opentasks
|
|
932
|
+
```
|
|
933
|
+
|
|
934
|
+
---
|
|
935
|
+
|
|
936
|
+
## Open Questions
|
|
937
|
+
|
|
938
|
+
- [ ] **Split vs single JSONL**: One `graph.jsonl` or split by type?
|
|
939
|
+
- [ ] **Cross-persister transactions**: How to ensure atomicity across JSONL + SQLite + Markdown?
|
|
940
|
+
- [ ] **Compaction trigger**: Automatic vs manual compaction scheduling?
|
|
941
|
+
|
|
942
|
+
---
|
|
943
|
+
|
|
944
|
+
## Markdown Sync Design
|
|
945
|
+
|
|
946
|
+
Bidirectional sync between JSONL (source of truth) and Markdown files (agent-editable).
|
|
947
|
+
|
|
948
|
+
### The Challenge
|
|
949
|
+
|
|
950
|
+
```
|
|
951
|
+
┌─────────────────┐
|
|
952
|
+
│ git pull │
|
|
953
|
+
│ git checkout │
|
|
954
|
+
└────────┬────────┘
|
|
955
|
+
↓
|
|
956
|
+
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
|
957
|
+
│ graph.jsonl │←──→│ Daemon │←──→│ context/*.md │
|
|
958
|
+
│ (git-tracked) │ │ (mediator) │ │ (git-tracked) │
|
|
959
|
+
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
|
960
|
+
↑ ↑
|
|
961
|
+
│ │
|
|
962
|
+
git operations user/agent edits
|
|
963
|
+
(merge, rebase) (random access)
|
|
964
|
+
```
|
|
965
|
+
|
|
966
|
+
**Conflict scenarios:**
|
|
967
|
+
1. **Git updates JSONL** → markdown files need refresh
|
|
968
|
+
2. **User edits markdown** → JSONL needs update
|
|
969
|
+
3. **Both change simultaneously** → conflict resolution needed
|
|
970
|
+
4. **Git updates both** → merge may create inconsistencies
|
|
971
|
+
|
|
972
|
+
### Content Hash Tracking
|
|
973
|
+
|
|
974
|
+
Track hashes at multiple levels to detect changes:
|
|
975
|
+
|
|
976
|
+
```typescript
|
|
977
|
+
interface SyncState {
|
|
978
|
+
/** Per-node tracking */
|
|
979
|
+
nodes: Map<string, NodeSyncState>
|
|
980
|
+
|
|
981
|
+
/** File-level tracking */
|
|
982
|
+
files: Map<string, FileSyncState>
|
|
983
|
+
|
|
984
|
+
/** Last successful sync timestamp */
|
|
985
|
+
lastSync: string
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
interface NodeSyncState {
|
|
989
|
+
nodeId: string
|
|
990
|
+
|
|
991
|
+
/** Hash of node content in JSONL */
|
|
992
|
+
jsonlHash: string
|
|
993
|
+
|
|
994
|
+
/** Hash of node content in markdown (if expanded) */
|
|
995
|
+
markdownHash?: string
|
|
996
|
+
|
|
997
|
+
/** Hash at last successful sync */
|
|
998
|
+
lastSyncHash: string
|
|
999
|
+
|
|
1000
|
+
/** Sync status */
|
|
1001
|
+
status: 'synced' | 'jsonl-ahead' | 'markdown-ahead' | 'conflict'
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
interface FileSyncState {
|
|
1005
|
+
path: string
|
|
1006
|
+
|
|
1007
|
+
/** File content hash */
|
|
1008
|
+
contentHash: string
|
|
1009
|
+
|
|
1010
|
+
/** File mtime (for quick dirty check) */
|
|
1011
|
+
mtime: number
|
|
1012
|
+
|
|
1013
|
+
/** Associated node ID */
|
|
1014
|
+
nodeId: string
|
|
1015
|
+
}
|
|
1016
|
+
```
|
|
1017
|
+
|
|
1018
|
+
### Sync Algorithm
|
|
1019
|
+
|
|
1020
|
+
```typescript
|
|
1021
|
+
class MarkdownSyncManager {
|
|
1022
|
+
/**
|
|
1023
|
+
* Detect and categorize changes
|
|
1024
|
+
*/
|
|
1025
|
+
async detectChanges(): Promise<SyncChanges> {
|
|
1026
|
+
const changes: SyncChanges = {
|
|
1027
|
+
jsonlUpdated: [], // JSONL changed, markdown needs update
|
|
1028
|
+
markdownUpdated: [], // Markdown changed, JSONL needs update
|
|
1029
|
+
conflicts: [], // Both changed differently
|
|
1030
|
+
newInJsonl: [], // New nodes to expand to markdown
|
|
1031
|
+
deletedInJsonl: [], // Nodes removed, delete markdown files
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
for (const [nodeId, state] of this.syncState.nodes) {
|
|
1035
|
+
const currentJsonlHash = await this.computeJsonlHash(nodeId)
|
|
1036
|
+
const currentMarkdownHash = await this.computeMarkdownHash(nodeId)
|
|
1037
|
+
|
|
1038
|
+
const jsonlChanged = currentJsonlHash !== state.jsonlHash
|
|
1039
|
+
const markdownChanged = currentMarkdownHash !== state.markdownHash
|
|
1040
|
+
|
|
1041
|
+
if (jsonlChanged && markdownChanged) {
|
|
1042
|
+
// Both changed - potential conflict
|
|
1043
|
+
if (currentJsonlHash === currentMarkdownHash) {
|
|
1044
|
+
// Same content - no conflict, just update state
|
|
1045
|
+
changes.jsonlUpdated.push(nodeId) // or markdownUpdated, same result
|
|
1046
|
+
} else {
|
|
1047
|
+
changes.conflicts.push({
|
|
1048
|
+
nodeId,
|
|
1049
|
+
jsonlHash: currentJsonlHash,
|
|
1050
|
+
markdownHash: currentMarkdownHash,
|
|
1051
|
+
})
|
|
1052
|
+
}
|
|
1053
|
+
} else if (jsonlChanged) {
|
|
1054
|
+
changes.jsonlUpdated.push(nodeId)
|
|
1055
|
+
} else if (markdownChanged) {
|
|
1056
|
+
changes.markdownUpdated.push(nodeId)
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
return changes
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
/**
|
|
1064
|
+
* Apply sync with conflict resolution
|
|
1065
|
+
*/
|
|
1066
|
+
async sync(strategy: SyncStrategy): Promise<SyncResult> {
|
|
1067
|
+
const changes = await this.detectChanges()
|
|
1068
|
+
|
|
1069
|
+
// Handle non-conflicting changes
|
|
1070
|
+
for (const nodeId of changes.jsonlUpdated) {
|
|
1071
|
+
await this.updateMarkdownFromJsonl(nodeId)
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
for (const nodeId of changes.markdownUpdated) {
|
|
1075
|
+
await this.updateJsonlFromMarkdown(nodeId)
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
// Handle conflicts based on strategy
|
|
1079
|
+
for (const conflict of changes.conflicts) {
|
|
1080
|
+
await this.resolveConflict(conflict, strategy)
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
// Update sync state
|
|
1084
|
+
await this.updateSyncState()
|
|
1085
|
+
|
|
1086
|
+
return { /* results */ }
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
```
|
|
1090
|
+
|
|
1091
|
+
### Conflict Resolution Strategies
|
|
1092
|
+
|
|
1093
|
+
```typescript
|
|
1094
|
+
type SyncStrategy =
|
|
1095
|
+
| 'jsonl-wins' // JSONL is authoritative
|
|
1096
|
+
| 'markdown-wins' // Markdown edits take priority
|
|
1097
|
+
| 'newer-wins' // Compare timestamps
|
|
1098
|
+
| 'merge-content' // Attempt content merge
|
|
1099
|
+
| 'manual' // Create .conflict file for user
|
|
1100
|
+
| 'interactive' // Prompt user/agent
|
|
1101
|
+
|
|
1102
|
+
interface ConflictResolution {
|
|
1103
|
+
strategy: SyncStrategy
|
|
1104
|
+
|
|
1105
|
+
/** For merge-content: how to merge */
|
|
1106
|
+
mergeOptions?: {
|
|
1107
|
+
/** Merge frontmatter (metadata) */
|
|
1108
|
+
frontmatter: 'jsonl' | 'markdown' | 'merge-fields'
|
|
1109
|
+
|
|
1110
|
+
/** Merge body (content) */
|
|
1111
|
+
body: 'jsonl' | 'markdown' | 'diff3'
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
/** For manual: where to write conflict file */
|
|
1115
|
+
conflictFilePattern?: string // e.g., "{path}.conflict"
|
|
1116
|
+
}
|
|
1117
|
+
```
|
|
1118
|
+
|
|
1119
|
+
### Recommended Default Strategy
|
|
1120
|
+
|
|
1121
|
+
```typescript
|
|
1122
|
+
const defaultSyncStrategy: ConflictResolution = {
|
|
1123
|
+
strategy: 'merge-content',
|
|
1124
|
+
mergeOptions: {
|
|
1125
|
+
// Metadata: JSONL wins (more structured, less likely user-edited)
|
|
1126
|
+
frontmatter: 'merge-fields', // Per-field: newer timestamp wins
|
|
1127
|
+
|
|
1128
|
+
// Content: Markdown wins (user/agent edits are intentional)
|
|
1129
|
+
body: 'markdown',
|
|
1130
|
+
},
|
|
1131
|
+
}
|
|
1132
|
+
```
|
|
1133
|
+
|
|
1134
|
+
**Rationale:**
|
|
1135
|
+
- **Frontmatter/metadata**: JSONL is structured, edits there are programmatic
|
|
1136
|
+
- **Body/content**: Markdown edits are intentional (user or agent writing)
|
|
1137
|
+
- **Fallback**: If merge fails, create `.conflict` file
|
|
1138
|
+
|
|
1139
|
+
### Git Operation Handling
|
|
1140
|
+
|
|
1141
|
+
```typescript
|
|
1142
|
+
interface GitEventHandler {
|
|
1143
|
+
/**
|
|
1144
|
+
* Called after git pull/merge/checkout
|
|
1145
|
+
* JSONL may have changed, need to refresh markdown
|
|
1146
|
+
*/
|
|
1147
|
+
async onGitUpdate(): Promise<void> {
|
|
1148
|
+
// 1. Detect JSONL changes via content hash
|
|
1149
|
+
const jsonlChanged = await this.hasJsonlChanged()
|
|
1150
|
+
|
|
1151
|
+
if (jsonlChanged) {
|
|
1152
|
+
// 2. Check for uncommitted markdown changes
|
|
1153
|
+
const uncommittedMd = await this.getUncommittedMarkdownChanges()
|
|
1154
|
+
|
|
1155
|
+
if (uncommittedMd.length > 0) {
|
|
1156
|
+
// 3. Stash markdown changes, apply JSONL, re-apply markdown
|
|
1157
|
+
await this.stashMarkdownChanges(uncommittedMd)
|
|
1158
|
+
await this.refreshMarkdownFromJsonl()
|
|
1159
|
+
await this.reapplyMarkdownChanges(uncommittedMd)
|
|
1160
|
+
} else {
|
|
1161
|
+
// Simple case: just refresh markdown
|
|
1162
|
+
await this.refreshMarkdownFromJsonl()
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
/**
|
|
1168
|
+
* Called before git commit
|
|
1169
|
+
* Ensure JSONL is up-to-date with markdown changes
|
|
1170
|
+
*/
|
|
1171
|
+
async onPreCommit(): Promise<void> {
|
|
1172
|
+
// Sync markdown changes to JSONL before commit
|
|
1173
|
+
await this.syncMarkdownToJsonl()
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
```
|
|
1177
|
+
|
|
1178
|
+
### File Watcher Integration
|
|
1179
|
+
|
|
1180
|
+
```typescript
|
|
1181
|
+
interface FileWatcher {
|
|
1182
|
+
/** Watch markdown directory for changes */
|
|
1183
|
+
watch(paths: string[], callback: WatchCallback): WatchHandle
|
|
1184
|
+
|
|
1185
|
+
/** Debounce rapid changes */
|
|
1186
|
+
debounceMs: number // e.g., 500ms
|
|
1187
|
+
|
|
1188
|
+
/** Ignore patterns */
|
|
1189
|
+
ignore: string[] // e.g., ['*.tmp', '*.conflict']
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
class MarkdownFileWatcher {
|
|
1193
|
+
private watcher: FSWatcher
|
|
1194
|
+
private pending: Map<string, NodeJS.Timeout> = new Map()
|
|
1195
|
+
|
|
1196
|
+
constructor(private syncManager: MarkdownSyncManager) {}
|
|
1197
|
+
|
|
1198
|
+
async onFileChange(path: string, event: 'change' | 'add' | 'unlink') {
|
|
1199
|
+
// Debounce rapid changes
|
|
1200
|
+
if (this.pending.has(path)) {
|
|
1201
|
+
clearTimeout(this.pending.get(path))
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
this.pending.set(path, setTimeout(async () => {
|
|
1205
|
+
this.pending.delete(path)
|
|
1206
|
+
|
|
1207
|
+
switch (event) {
|
|
1208
|
+
case 'change':
|
|
1209
|
+
await this.syncManager.onMarkdownChanged(path)
|
|
1210
|
+
break
|
|
1211
|
+
case 'add':
|
|
1212
|
+
await this.syncManager.onMarkdownCreated(path)
|
|
1213
|
+
break
|
|
1214
|
+
case 'unlink':
|
|
1215
|
+
await this.syncManager.onMarkdownDeleted(path)
|
|
1216
|
+
break
|
|
1217
|
+
}
|
|
1218
|
+
}, this.debounceMs))
|
|
1219
|
+
}
|
|
1220
|
+
}
|
|
1221
|
+
```
|
|
1222
|
+
|
|
1223
|
+
---
|
|
1224
|
+
|
|
1225
|
+
## Compaction Strategy
|
|
1226
|
+
|
|
1227
|
+
Prevent JSONL files from growing unbounded. Inspired by beads' tiered compaction.
|
|
1228
|
+
|
|
1229
|
+
### The Problem
|
|
1230
|
+
|
|
1231
|
+
```
|
|
1232
|
+
graph.jsonl grows over time:
|
|
1233
|
+
- New nodes added
|
|
1234
|
+
- Node updates append (for merge-friendliness)
|
|
1235
|
+
- Deleted nodes become tombstones
|
|
1236
|
+
- Old closed issues accumulate
|
|
1237
|
+
|
|
1238
|
+
Without compaction:
|
|
1239
|
+
- File size grows linearly
|
|
1240
|
+
- Parse time increases
|
|
1241
|
+
- Git history bloats
|
|
1242
|
+
```
|
|
1243
|
+
|
|
1244
|
+
### Compaction Levels
|
|
1245
|
+
|
|
1246
|
+
```typescript
|
|
1247
|
+
interface CompactionConfig {
|
|
1248
|
+
/** Enable automatic compaction */
|
|
1249
|
+
enabled: boolean
|
|
1250
|
+
|
|
1251
|
+
/** Tier 1: Basic compaction */
|
|
1252
|
+
tier1: {
|
|
1253
|
+
/** Days after close before eligible */
|
|
1254
|
+
afterDays: number // default: 30
|
|
1255
|
+
|
|
1256
|
+
/** Don't compact if has open dependents within N levels */
|
|
1257
|
+
dependencyLevels: number // default: 2
|
|
1258
|
+
|
|
1259
|
+
/** Summarization approach */
|
|
1260
|
+
summarize: 'truncate' | 'llm' | 'none'
|
|
1261
|
+
|
|
1262
|
+
/** Target size reduction */
|
|
1263
|
+
targetReduction: number // default: 0.7 (70%)
|
|
1264
|
+
}
|
|
1265
|
+
|
|
1266
|
+
/** Tier 2: Aggressive compaction */
|
|
1267
|
+
tier2: {
|
|
1268
|
+
afterDays: number // default: 90
|
|
1269
|
+
dependencyLevels: number // default: 5
|
|
1270
|
+
targetReduction: number // default: 0.95 (95%)
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
/** Tombstone cleanup */
|
|
1274
|
+
tombstones: {
|
|
1275
|
+
/** TTL before hard delete */
|
|
1276
|
+
ttlDays: number // default: 30
|
|
1277
|
+
|
|
1278
|
+
/** Minimum TTL (safety) */
|
|
1279
|
+
minTtlDays: number // default: 7
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1282
|
+
/** JSONL file management */
|
|
1283
|
+
file: {
|
|
1284
|
+
/** Max entries before triggering compaction */
|
|
1285
|
+
maxEntries: number // default: 10000
|
|
1286
|
+
|
|
1287
|
+
/** Max file size before triggering */
|
|
1288
|
+
maxSizeMb: number // default: 10
|
|
1289
|
+
|
|
1290
|
+
/** Compact on daemon startup */
|
|
1291
|
+
compactOnStartup: boolean
|
|
1292
|
+
}
|
|
1293
|
+
}
|
|
1294
|
+
```
|
|
1295
|
+
|
|
1296
|
+
### Compaction Operations
|
|
1297
|
+
|
|
1298
|
+
```typescript
|
|
1299
|
+
interface Compactor {
|
|
1300
|
+
/**
|
|
1301
|
+
* Analyze compaction candidates
|
|
1302
|
+
*/
|
|
1303
|
+
analyze(): Promise<CompactionAnalysis>
|
|
1304
|
+
|
|
1305
|
+
/**
|
|
1306
|
+
* Execute compaction
|
|
1307
|
+
*/
|
|
1308
|
+
compact(options: CompactOptions): Promise<CompactionResult>
|
|
1309
|
+
|
|
1310
|
+
/**
|
|
1311
|
+
* Prune expired tombstones
|
|
1312
|
+
*/
|
|
1313
|
+
pruneTombstones(): Promise<PruneResult>
|
|
1314
|
+
|
|
1315
|
+
/**
|
|
1316
|
+
* Rewrite JSONL (dedupe entries, remove old versions)
|
|
1317
|
+
*/
|
|
1318
|
+
rewriteJsonl(): Promise<RewriteResult>
|
|
1319
|
+
}
|
|
1320
|
+
|
|
1321
|
+
interface CompactionAnalysis {
|
|
1322
|
+
/** Nodes eligible for Tier 1 */
|
|
1323
|
+
tier1Candidates: NodeSummary[]
|
|
1324
|
+
|
|
1325
|
+
/** Nodes eligible for Tier 2 */
|
|
1326
|
+
tier2Candidates: NodeSummary[]
|
|
1327
|
+
|
|
1328
|
+
/** Expired tombstones */
|
|
1329
|
+
expiredTombstones: string[]
|
|
1330
|
+
|
|
1331
|
+
/** Duplicate entries (same node, multiple versions) */
|
|
1332
|
+
duplicateEntries: number
|
|
1333
|
+
|
|
1334
|
+
/** Current file size */
|
|
1335
|
+
currentSizeMb: number
|
|
1336
|
+
|
|
1337
|
+
/** Estimated size after compaction */
|
|
1338
|
+
estimatedSizeMb: number
|
|
1339
|
+
}
|
|
1340
|
+
```
|
|
1341
|
+
|
|
1342
|
+
### JSONL Rewrite Strategy
|
|
1343
|
+
|
|
1344
|
+
```typescript
|
|
1345
|
+
/**
|
|
1346
|
+
* Rewrite JSONL to remove duplicates and old versions
|
|
1347
|
+
* Only keeps latest version of each node
|
|
1348
|
+
*/
|
|
1349
|
+
async function rewriteJsonl(path: string): Promise<void> {
|
|
1350
|
+
const nodes = new Map<string, StoredNode>()
|
|
1351
|
+
const edges = new Map<string, StoredEdge>()
|
|
1352
|
+
|
|
1353
|
+
// Read all entries, keep only latest
|
|
1354
|
+
for await (const line of readLines(path)) {
|
|
1355
|
+
const entry = JSON.parse(line)
|
|
1356
|
+
|
|
1357
|
+
if (entry.type === 'edge' || entry.id?.startsWith('x-')) {
|
|
1358
|
+
edges.set(entry.id, entry)
|
|
1359
|
+
} else {
|
|
1360
|
+
// Compare timestamps, keep newer
|
|
1361
|
+
const existing = nodes.get(entry.id)
|
|
1362
|
+
if (!existing || entry.updated_at > existing.updated_at) {
|
|
1363
|
+
nodes.set(entry.id, entry)
|
|
1364
|
+
}
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
|
|
1368
|
+
// Filter out archived/deleted beyond retention
|
|
1369
|
+
const retained = [...nodes.values()].filter(node => {
|
|
1370
|
+
if (node.deleted_at) {
|
|
1371
|
+
const age = Date.now() - new Date(node.deleted_at).getTime()
|
|
1372
|
+
return age < TOMBSTONE_TTL_MS
|
|
1373
|
+
}
|
|
1374
|
+
return true
|
|
1375
|
+
})
|
|
1376
|
+
|
|
1377
|
+
// Atomic rewrite
|
|
1378
|
+
const tempPath = `${path}.${process.pid}.tmp`
|
|
1379
|
+
const output = fs.createWriteStream(tempPath)
|
|
1380
|
+
|
|
1381
|
+
for (const node of retained) {
|
|
1382
|
+
output.write(JSON.stringify(node) + '\n')
|
|
1383
|
+
}
|
|
1384
|
+
for (const edge of edges.values()) {
|
|
1385
|
+
output.write(JSON.stringify(edge) + '\n')
|
|
1386
|
+
}
|
|
1387
|
+
|
|
1388
|
+
await output.close()
|
|
1389
|
+
await fs.rename(tempPath, path)
|
|
1390
|
+
}
|
|
1391
|
+
```
|
|
1392
|
+
|
|
1393
|
+
### Content Summarization
|
|
1394
|
+
|
|
1395
|
+
For Tier 1+ compaction, optionally summarize content:
|
|
1396
|
+
|
|
1397
|
+
```typescript
|
|
1398
|
+
interface ContentSummarizer {
|
|
1399
|
+
/**
|
|
1400
|
+
* Summarize node content
|
|
1401
|
+
* Can use LLM or simple truncation
|
|
1402
|
+
*/
|
|
1403
|
+
summarize(node: Node): Promise<SummarizedNode>
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1406
|
+
interface SummarizedNode {
|
|
1407
|
+
/** Compressed content */
|
|
1408
|
+
content: string
|
|
1409
|
+
|
|
1410
|
+
/** Original content size */
|
|
1411
|
+
originalSize: number
|
|
1412
|
+
|
|
1413
|
+
/** Compressed content size */
|
|
1414
|
+
compressedSize: number
|
|
1415
|
+
|
|
1416
|
+
/** Reduction percentage */
|
|
1417
|
+
reductionPct: number
|
|
1418
|
+
}
|
|
1419
|
+
|
|
1420
|
+
// Simple truncation summarizer
|
|
1421
|
+
class TruncateSummarizer implements ContentSummarizer {
|
|
1422
|
+
async summarize(node: Node): Promise<SummarizedNode> {
|
|
1423
|
+
const original = node.content || ''
|
|
1424
|
+
const maxLength = 500
|
|
1425
|
+
|
|
1426
|
+
const compressed = original.length > maxLength
|
|
1427
|
+
? original.slice(0, maxLength) + '\n\n[Content truncated during compaction]'
|
|
1428
|
+
: original
|
|
1429
|
+
|
|
1430
|
+
return {
|
|
1431
|
+
content: compressed,
|
|
1432
|
+
originalSize: original.length,
|
|
1433
|
+
compressedSize: compressed.length,
|
|
1434
|
+
reductionPct: 1 - (compressed.length / original.length),
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
}
|
|
1438
|
+
|
|
1439
|
+
// LLM-based summarizer (like beads' Haiku integration)
|
|
1440
|
+
class LLMSummarizer implements ContentSummarizer {
|
|
1441
|
+
async summarize(node: Node): Promise<SummarizedNode> {
|
|
1442
|
+
const prompt = `
|
|
1443
|
+
Summarize this completed task for archival:
|
|
1444
|
+
|
|
1445
|
+
Title: ${node.title}
|
|
1446
|
+
Content: ${node.content}
|
|
1447
|
+
|
|
1448
|
+
Provide:
|
|
1449
|
+
- Summary: 2-3 sentences on what was done
|
|
1450
|
+
- Key Decisions: Important technical choices
|
|
1451
|
+
- Resolution: One sentence on outcome
|
|
1452
|
+
|
|
1453
|
+
Keep it shorter than the original.
|
|
1454
|
+
`
|
|
1455
|
+
|
|
1456
|
+
const summary = await this.llm.complete(prompt)
|
|
1457
|
+
|
|
1458
|
+
return {
|
|
1459
|
+
content: summary,
|
|
1460
|
+
originalSize: (node.content || '').length,
|
|
1461
|
+
compressedSize: summary.length,
|
|
1462
|
+
reductionPct: 1 - (summary.length / (node.content || '').length),
|
|
1463
|
+
}
|
|
1464
|
+
}
|
|
1465
|
+
}
|
|
1466
|
+
```
|
|
1467
|
+
|
|
1468
|
+
### Snapshot for Recovery
|
|
1469
|
+
|
|
1470
|
+
Before compaction, save original for potential recovery:
|
|
1471
|
+
|
|
1472
|
+
```typescript
|
|
1473
|
+
interface CompactionSnapshot {
|
|
1474
|
+
/** Node ID */
|
|
1475
|
+
nodeId: string
|
|
1476
|
+
|
|
1477
|
+
/** Compaction level applied */
|
|
1478
|
+
level: number
|
|
1479
|
+
|
|
1480
|
+
/** Full original content */
|
|
1481
|
+
originalContent: string
|
|
1482
|
+
|
|
1483
|
+
/** Original metadata */
|
|
1484
|
+
originalMetadata: Record<string, unknown>
|
|
1485
|
+
|
|
1486
|
+
/** When compacted */
|
|
1487
|
+
compactedAt: string
|
|
1488
|
+
|
|
1489
|
+
/** Git commit at compaction (for recovery) */
|
|
1490
|
+
gitCommit?: string
|
|
1491
|
+
}
|
|
1492
|
+
|
|
1493
|
+
// Store in SQLite (not JSONL - too large)
|
|
1494
|
+
// Can be pruned after longer retention (e.g., 1 year)
|
|
1495
|
+
```
|
|
1496
|
+
|
|
1497
|
+
### Pinned Nodes
|
|
1498
|
+
|
|
1499
|
+
Protect important nodes from compaction:
|
|
1500
|
+
|
|
1501
|
+
```typescript
|
|
1502
|
+
interface Node {
|
|
1503
|
+
// ... other fields
|
|
1504
|
+
|
|
1505
|
+
/** Protected from compaction */
|
|
1506
|
+
pinned?: boolean
|
|
1507
|
+
|
|
1508
|
+
/** Why pinned */
|
|
1509
|
+
pinReason?: string
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
// Compactor skips pinned nodes
|
|
1513
|
+
function isCompactionEligible(node: Node): boolean {
|
|
1514
|
+
if (node.pinned) return false
|
|
1515
|
+
if (node.status !== 'closed') return false
|
|
1516
|
+
if (hasOpenDependents(node)) return false
|
|
1517
|
+
// ... other checks
|
|
1518
|
+
}
|
|
1519
|
+
```
|
|
1520
|
+
|
|
1521
|
+
---
|
|
1522
|
+
|
|
1523
|
+
## Daemon Architecture
|
|
1524
|
+
|
|
1525
|
+
### Phased Approach
|
|
1526
|
+
|
|
1527
|
+
- **Phase 2**: No daemon. SQLite WAL mode handles concurrent reads. Advisory file lock (`write.lock`) serializes JSONL writes. Direct file access only.
|
|
1528
|
+
- **Phase 3**: Single daemon per git repository at `.git/opentasks/daemon.sock`. Manages all registered worktrees.
|
|
1529
|
+
|
|
1530
|
+
### Why a Single Daemon per Git Repo? (Phase 3)
|
|
1531
|
+
|
|
1532
|
+
1. **File watching** — Monitor JSONL and markdown for changes across all worktrees
|
|
1533
|
+
2. **Debounced writes** — Batch rapid changes before persisting
|
|
1534
|
+
3. **Cross-location coordination** — Multiple agents sharing state via in-process function calls (not IPC hops)
|
|
1535
|
+
4. **Background sync** — Provider sync, remote fetch
|
|
1536
|
+
5. **Compaction** — Periodic cleanup without blocking operations
|
|
1537
|
+
6. **Branch caching** — Watch `.git/HEAD` for branch changes
|
|
1538
|
+
|
|
1539
|
+
**Why NOT one daemon per location (previous design):**
|
|
1540
|
+
- N+1 processes for agent swarms is wasteful
|
|
1541
|
+
- Cross-location queries require IPC between daemons (latency)
|
|
1542
|
+
- Claim atomicity requires distributed coordination
|
|
1543
|
+
- Process lifecycle management is complex (orphaned daemons)
|
|
1544
|
+
|
|
1545
|
+
### Daemon Location
|
|
1546
|
+
|
|
1547
|
+
```
|
|
1548
|
+
.git/opentasks/
|
|
1549
|
+
├── daemon.sock # Unix socket (shared by all worktrees)
|
|
1550
|
+
├── daemon.lock # PID lock
|
|
1551
|
+
└── worktrees.json # Registered worktrees
|
|
1552
|
+
```
|
|
1553
|
+
|
|
1554
|
+
Socket lives in `.git/opentasks/` because `.git/` is shared across all worktrees. No global registry needed — any worktree finds the daemon at the same path.
|
|
1555
|
+
|
|
1556
|
+
### IPC Protocol
|
|
1557
|
+
|
|
1558
|
+
```typescript
|
|
1559
|
+
interface DaemonRequest {
|
|
1560
|
+
id: string
|
|
1561
|
+
method: DaemonMethod
|
|
1562
|
+
params?: unknown
|
|
1563
|
+
}
|
|
1564
|
+
|
|
1565
|
+
interface DaemonResponse {
|
|
1566
|
+
id: string
|
|
1567
|
+
result?: unknown
|
|
1568
|
+
error?: { code: number; message: string }
|
|
1569
|
+
}
|
|
1570
|
+
|
|
1571
|
+
type DaemonMethod =
|
|
1572
|
+
// Graph operations (include location parameter)
|
|
1573
|
+
| 'graph.get'
|
|
1574
|
+
| 'graph.query'
|
|
1575
|
+
| 'graph.create'
|
|
1576
|
+
| 'graph.update'
|
|
1577
|
+
| 'graph.delete'
|
|
1578
|
+
|
|
1579
|
+
// Sync operations
|
|
1580
|
+
| 'sync.flush'
|
|
1581
|
+
| 'sync.import'
|
|
1582
|
+
|
|
1583
|
+
// Lifecycle
|
|
1584
|
+
| 'daemon.ping'
|
|
1585
|
+
| 'daemon.health'
|
|
1586
|
+
| 'daemon.status'
|
|
1587
|
+
| 'daemon.shutdown'
|
|
1588
|
+
|
|
1589
|
+
// Worktree management
|
|
1590
|
+
| 'worktree.register'
|
|
1591
|
+
| 'worktree.unregister'
|
|
1592
|
+
| 'worktree.list'
|
|
1593
|
+
| 'worktree.find'
|
|
1594
|
+
|
|
1595
|
+
// Connections
|
|
1596
|
+
| 'connection.health'
|
|
1597
|
+
```
|
|
1598
|
+
|
|
1599
|
+
See [plans/PHASE-3.md](./plans/PHASE-3.md) for full daemon specification, auto-start behavior, and lifecycle.
|
|
1600
|
+
|
|
1601
|
+
---
|
|
1602
|
+
|
|
1603
|
+
## Open Questions (Resolved)
|
|
1604
|
+
|
|
1605
|
+
| Question | Resolution |
|
|
1606
|
+
|----------|------------|
|
|
1607
|
+
| Split vs single JSONL | **Single `graph.jsonl`** with compaction to manage size |
|
|
1608
|
+
| Markdown sync priority | **Merge strategy**: frontmatter from JSONL, body from markdown |
|
|
1609
|
+
| Compaction strategy | **Tiered**: 30 days → Tier 1, 90 days → Tier 2, with LLM summarization option |
|
|
1610
|
+
| Daemon model | **Single daemon per git repo** (Phase 3 only); Phase 2 uses WAL + file locks |
|
|
1611
|
+
| JSONL write mode | **Append-only** — updates append new line, never overwrite in-place |
|
|
1612
|
+
| Git merge conflicts | **Custom merge driver** with field-level three-way merge |
|
|
1613
|
+
| Location discovery | **One-time setup aid** (`opentasks discover`), not runtime; explicit connections |
|
|
1614
|
+
| Worktree detection | **Explicit registration** via `opentasks worktree setup`, not passive detection |
|
|
1615
|
+
| Redirect conditions | **Role-based** (set in config by orchestrator), not agent-identity-based |
|
|
1616
|
+
| Global registry | **Eliminated** — socket at `.git/opentasks/daemon.sock` + explicit connections |
|
|
1617
|
+
|
|
1618
|
+
---
|
|
1619
|
+
|
|
1620
|
+
## References
|
|
1621
|
+
|
|
1622
|
+
### Beads Persistence Patterns
|
|
1623
|
+
- **FlushManager**: Event-driven, single-goroutine flush coordination with debouncing
|
|
1624
|
+
- **Dirty tracking**: Per-node dirty flags with `marked_at` ordering
|
|
1625
|
+
- **Content hashing**: SHA256 of substantive fields for dedup
|
|
1626
|
+
- **Atomic writes**: Temp file with PID suffix + rename
|
|
1627
|
+
- **Multi-repo export**: Filter by prefix, route to separate files
|
|
1628
|
+
- **Worktree redirect**: `.beads/redirect` file for shared state
|
|
1629
|
+
|
|
1630
|
+
### TinyBase Persister Model
|
|
1631
|
+
- [Custom Persistence Guide](https://tinybase.org/guides/persistence/custom-persistence/)
|
|
1632
|
+
- [Persister Interface](https://tinybase.org/api/persisters/interfaces/persister/persister/)
|
|
1633
|
+
- Four core methods: `getPersisted`, `setPersisted`, `subscribe`, `unsubscribe`
|
|
1634
|
+
|
|
1635
|
+
### Sudocode Three-Layer Model
|
|
1636
|
+
- Markdown ↔ JSONL ↔ SQLite with bidirectional sync
|
|
1637
|
+
- File watcher for markdown changes
|
|
1638
|
+
- Frontmatter for metadata, body for content
|