opentasks 0.1.3 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +174 -49
- package/dist/cli.d.ts +20 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +451 -15
- package/dist/cli.js.map +1 -1
- package/dist/client/client.d.ts +54 -0
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/client.js +148 -4
- package/dist/client/client.js.map +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/core/discover.d.ts.map +1 -1
- package/dist/core/discover.js +7 -2
- package/dist/core/discover.js.map +1 -1
- package/dist/core/hash.d.ts.map +1 -1
- package/dist/core/hash.js +7 -0
- package/dist/core/hash.js.map +1 -1
- package/dist/core/id.d.ts +1 -1
- package/dist/core/id.d.ts.map +1 -1
- package/dist/core/id.js +2 -0
- package/dist/core/id.js.map +1 -1
- package/dist/core/worktree.js +4 -4
- package/dist/core/worktree.js.map +1 -1
- package/dist/daemon/events.d.ts +82 -0
- package/dist/daemon/events.d.ts.map +1 -0
- package/dist/daemon/events.js +71 -0
- package/dist/daemon/events.js.map +1 -0
- package/dist/daemon/flush.d.ts.map +1 -1
- package/dist/daemon/flush.js +12 -2
- package/dist/daemon/flush.js.map +1 -1
- package/dist/daemon/health-counters.d.ts +38 -0
- package/dist/daemon/health-counters.d.ts.map +1 -0
- package/dist/daemon/health-counters.js +42 -0
- package/dist/daemon/health-counters.js.map +1 -0
- package/dist/daemon/idempotency.d.ts +50 -0
- package/dist/daemon/idempotency.d.ts.map +1 -0
- package/dist/daemon/idempotency.js +104 -0
- package/dist/daemon/idempotency.js.map +1 -0
- package/dist/daemon/ipc.d.ts +32 -2
- package/dist/daemon/ipc.d.ts.map +1 -1
- package/dist/daemon/ipc.js +54 -3
- package/dist/daemon/ipc.js.map +1 -1
- package/dist/daemon/lifecycle.d.ts.map +1 -1
- package/dist/daemon/lifecycle.js +145 -9
- package/dist/daemon/lifecycle.js.map +1 -1
- package/dist/daemon/location-state.d.ts +60 -1
- package/dist/daemon/location-state.d.ts.map +1 -1
- package/dist/daemon/location-state.js +136 -31
- package/dist/daemon/location-state.js.map +1 -1
- package/dist/daemon/methods/context-files.d.ts.map +1 -1
- package/dist/daemon/methods/context-files.js +4 -3
- package/dist/daemon/methods/context-files.js.map +1 -1
- package/dist/daemon/methods/events.d.ts +22 -0
- package/dist/daemon/methods/events.d.ts.map +1 -0
- package/dist/daemon/methods/events.js +30 -0
- package/dist/daemon/methods/events.js.map +1 -0
- package/dist/daemon/methods/graph.d.ts +7 -0
- package/dist/daemon/methods/graph.d.ts.map +1 -1
- package/dist/daemon/methods/graph.js +24 -14
- package/dist/daemon/methods/graph.js.map +1 -1
- package/dist/daemon/methods/lifecycle.d.ts +16 -0
- package/dist/daemon/methods/lifecycle.d.ts.map +1 -1
- package/dist/daemon/methods/lifecycle.js +3 -1
- package/dist/daemon/methods/lifecycle.js.map +1 -1
- package/dist/daemon/methods/location.js.map +1 -1
- package/dist/daemon/methods/sync.d.ts +48 -2
- package/dist/daemon/methods/sync.d.ts.map +1 -1
- package/dist/daemon/methods/sync.js +106 -3
- package/dist/daemon/methods/sync.js.map +1 -1
- package/dist/daemon/methods/tools.d.ts.map +1 -1
- package/dist/daemon/methods/tools.js +42 -8
- package/dist/daemon/methods/tools.js.map +1 -1
- package/dist/daemon/methods/watch.d.ts +24 -0
- package/dist/daemon/methods/watch.d.ts.map +1 -1
- package/dist/daemon/methods/watch.js +178 -88
- package/dist/daemon/methods/watch.js.map +1 -1
- package/dist/graph/EdgeTypeRegistry.d.ts.map +1 -1
- package/dist/graph/EdgeTypeRegistry.js +32 -0
- package/dist/graph/EdgeTypeRegistry.js.map +1 -1
- package/dist/graph/FederatedGraph.d.ts.map +1 -1
- package/dist/graph/GraphologyAdapter.d.ts.map +1 -1
- package/dist/graph/GraphologyAdapter.js.map +1 -1
- package/dist/graph/HydratingFederatedGraph.d.ts.map +1 -1
- package/dist/graph/HydratingFederatedGraph.js +1 -1
- package/dist/graph/HydratingFederatedGraph.js.map +1 -1
- package/dist/graph/attempts.d.ts +50 -0
- package/dist/graph/attempts.d.ts.map +1 -0
- package/dist/graph/attempts.js +51 -0
- package/dist/graph/attempts.js.map +1 -0
- package/dist/graph/coordination.d.ts +4 -2
- package/dist/graph/coordination.d.ts.map +1 -1
- package/dist/graph/coordination.js +77 -85
- package/dist/graph/coordination.js.map +1 -1
- package/dist/graph/expansion.d.ts.map +1 -1
- package/dist/graph/expansion.js +1 -1
- package/dist/graph/expansion.js.map +1 -1
- package/dist/graph/git-graph-syncer.d.ts +24 -0
- package/dist/graph/git-graph-syncer.d.ts.map +1 -1
- package/dist/graph/git-graph-syncer.js +95 -28
- package/dist/graph/git-graph-syncer.js.map +1 -1
- package/dist/graph/provider-store.d.ts +12 -1
- package/dist/graph/provider-store.d.ts.map +1 -1
- package/dist/graph/provider-store.js +35 -8
- package/dist/graph/provider-store.js.map +1 -1
- package/dist/graph/query.d.ts.map +1 -1
- package/dist/graph/query.js +18 -2
- package/dist/graph/query.js.map +1 -1
- package/dist/graph/store.d.ts +18 -2
- package/dist/graph/store.d.ts.map +1 -1
- package/dist/graph/store.js +43 -0
- package/dist/graph/store.js.map +1 -1
- package/dist/graph/sync.js +1 -1
- package/dist/graph/sync.js.map +1 -1
- package/dist/graph/types.d.ts +9 -1
- package/dist/graph/types.d.ts.map +1 -1
- package/dist/graph/types.js.map +1 -1
- package/dist/graph/validation.d.ts.map +1 -1
- package/dist/graph/validation.js +20 -2
- package/dist/graph/validation.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/materialization/archiver.d.ts.map +1 -1
- package/dist/materialization/archiver.js.map +1 -1
- package/dist/materialization/snapshot.d.ts.map +1 -1
- package/dist/materialization/snapshot.js +1 -1
- package/dist/materialization/snapshot.js.map +1 -1
- package/dist/materialization/types.d.ts +7 -5
- package/dist/materialization/types.d.ts.map +1 -1
- package/dist/materialization/types.js.map +1 -1
- package/dist/mcp/server.d.ts +2 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +308 -11
- package/dist/mcp/server.js.map +1 -1
- package/dist/providers/beads.d.ts.map +1 -1
- package/dist/providers/beads.js +2 -0
- package/dist/providers/beads.js.map +1 -1
- package/dist/providers/claude-tasks.d.ts.map +1 -1
- package/dist/providers/claude-tasks.js.map +1 -1
- package/dist/providers/global.js +1 -1
- package/dist/providers/global.js.map +1 -1
- package/dist/providers/location.d.ts.map +1 -1
- package/dist/providers/location.js.map +1 -1
- package/dist/providers/map-client-factory.d.ts.map +1 -1
- package/dist/providers/map-client-factory.js +1 -1
- package/dist/providers/map-client-factory.js.map +1 -1
- package/dist/providers/map-connector.js +1 -1
- package/dist/providers/map-connector.js.map +1 -1
- package/dist/providers/map-event-bridge.d.ts.map +1 -1
- package/dist/providers/map-event-bridge.js +1 -0
- package/dist/providers/map-event-bridge.js.map +1 -1
- package/dist/providers/map.d.ts.map +1 -1
- package/dist/providers/map.js +5 -2
- package/dist/providers/map.js.map +1 -1
- package/dist/providers/native.d.ts.map +1 -1
- package/dist/providers/native.js +21 -8
- package/dist/providers/native.js.map +1 -1
- package/dist/providers/registry.js +1 -1
- package/dist/providers/registry.js.map +1 -1
- package/dist/providers/sudocode.d.ts.map +1 -1
- package/dist/providers/sudocode.js +5 -11
- package/dist/providers/sudocode.js.map +1 -1
- package/dist/providers/traits/Reconcilable.d.ts.map +1 -1
- package/dist/providers/traits/TaskManageable.d.ts +15 -1
- package/dist/providers/traits/TaskManageable.d.ts.map +1 -1
- package/dist/providers/traits/TaskManageable.js +26 -0
- package/dist/providers/traits/TaskManageable.js.map +1 -1
- package/dist/providers/traits/Watchable.d.ts +6 -0
- package/dist/providers/traits/Watchable.d.ts.map +1 -1
- package/dist/providers/traits/Watchable.js.map +1 -1
- package/dist/providers/types.d.ts +1 -1
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/schema/edges.d.ts +5 -1
- package/dist/schema/edges.d.ts.map +1 -1
- package/dist/schema/index.d.ts +2 -2
- package/dist/schema/index.d.ts.map +1 -1
- package/dist/schema/index.js +1 -1
- package/dist/schema/index.js.map +1 -1
- package/dist/schema/nodes.d.ts +55 -2
- package/dist/schema/nodes.d.ts.map +1 -1
- package/dist/schema/storage.d.ts +2 -0
- package/dist/schema/storage.d.ts.map +1 -1
- package/dist/schema/validation.d.ts +6 -2
- package/dist/schema/validation.d.ts.map +1 -1
- package/dist/schema/validation.js +18 -1
- package/dist/schema/validation.js.map +1 -1
- package/dist/sessionlog/agent/registry.js.map +1 -1
- package/dist/sessionlog/agent/session-types.d.ts.map +1 -1
- package/dist/sessionlog/agent/types.d.ts.map +1 -1
- package/dist/sessionlog/commands/clean.js +1 -1
- package/dist/sessionlog/commands/clean.js.map +1 -1
- package/dist/sessionlog/commands/disable.d.ts.map +1 -1
- package/dist/sessionlog/commands/disable.js.map +1 -1
- package/dist/sessionlog/commands/doctor.js +1 -1
- package/dist/sessionlog/commands/doctor.js.map +1 -1
- package/dist/sessionlog/commands/enable.js +1 -1
- package/dist/sessionlog/commands/enable.js.map +1 -1
- package/dist/sessionlog/commands/resume.js +1 -1
- package/dist/sessionlog/commands/resume.js.map +1 -1
- package/dist/sessionlog/commands/rewind.d.ts.map +1 -1
- package/dist/sessionlog/commands/rewind.js +1 -1
- package/dist/sessionlog/commands/rewind.js.map +1 -1
- package/dist/sessionlog/commands/status.d.ts.map +1 -1
- package/dist/sessionlog/commands/status.js.map +1 -1
- package/dist/sessionlog/hooks/lifecycle.d.ts.map +1 -1
- package/dist/sessionlog/hooks/lifecycle.js +3 -3
- package/dist/sessionlog/hooks/lifecycle.js.map +1 -1
- package/dist/sessionlog/security/redaction.js +1 -1
- package/dist/sessionlog/security/redaction.js.map +1 -1
- package/dist/sessionlog/store/checkpoint-store.d.ts.map +1 -1
- package/dist/sessionlog/store/checkpoint-store.js +2 -2
- package/dist/sessionlog/store/checkpoint-store.js.map +1 -1
- package/dist/sessionlog/store/native-store.d.ts.map +1 -1
- package/dist/sessionlog/store/native-store.js.map +1 -1
- package/dist/sessionlog/store/session-store.d.ts.map +1 -1
- package/dist/sessionlog/store/session-store.js +1 -1
- package/dist/sessionlog/store/session-store.js.map +1 -1
- package/dist/sessionlog/strategy/attribution.js +2 -2
- package/dist/sessionlog/strategy/attribution.js.map +1 -1
- package/dist/sessionlog/strategy/common.d.ts +1 -1
- package/dist/sessionlog/strategy/common.d.ts.map +1 -1
- package/dist/sessionlog/strategy/common.js +3 -3
- package/dist/sessionlog/strategy/common.js.map +1 -1
- package/dist/sessionlog/strategy/content-overlap.d.ts.map +1 -1
- package/dist/sessionlog/strategy/content-overlap.js +1 -1
- package/dist/sessionlog/strategy/content-overlap.js.map +1 -1
- package/dist/sessionlog/strategy/manual-commit.d.ts.map +1 -1
- package/dist/sessionlog/strategy/manual-commit.js +6 -16
- package/dist/sessionlog/strategy/manual-commit.js.map +1 -1
- package/dist/sessionlog/utils/preview-rewind.d.ts.map +1 -1
- package/dist/sessionlog/utils/preview-rewind.js +1 -1
- package/dist/sessionlog/utils/preview-rewind.js.map +1 -1
- package/dist/sessionlog/utils/trailers.d.ts.map +1 -1
- package/dist/sessionlog/utils/trailers.js +0 -1
- package/dist/sessionlog/utils/trailers.js.map +1 -1
- package/dist/storage/interface.d.ts +64 -0
- package/dist/storage/interface.d.ts.map +1 -1
- package/dist/storage/interface.js.map +1 -1
- package/dist/storage/jsonl.js +2 -2
- package/dist/storage/jsonl.js.map +1 -1
- package/dist/storage/sqlite-schema.d.ts +8 -2
- package/dist/storage/sqlite-schema.d.ts.map +1 -1
- package/dist/storage/sqlite-schema.js +10 -1
- package/dist/storage/sqlite-schema.js.map +1 -1
- package/dist/storage/sqlite.d.ts +16 -1
- package/dist/storage/sqlite.d.ts.map +1 -1
- package/dist/storage/sqlite.js +134 -2
- package/dist/storage/sqlite.js.map +1 -1
- package/dist/tools/link.js +1 -1
- package/dist/tools/link.js.map +1 -1
- package/dist/tools/query.d.ts.map +1 -1
- package/dist/tools/query.js +8 -29
- package/dist/tools/query.js.map +1 -1
- package/dist/tools/task.d.ts.map +1 -1
- package/dist/tools/task.js +115 -5
- package/dist/tools/task.js.map +1 -1
- package/dist/tools/types.d.ts +84 -3
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/types.js.map +1 -1
- package/dist/version.d.ts +14 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +44 -0
- package/dist/version.js.map +1 -0
- package/package.json +32 -7
- package/skills/opentasks/SKILL.md +226 -0
- package/skills/opentasks/dependency-management.md +119 -0
- package/skills/opentasks/feedback-and-review.md +100 -0
- package/skills/opentasks/linking-external-data.md +103 -0
- package/skills/opentasks/spec-to-implementation.md +171 -0
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Builds self-contained MaterializationSnapshots from GraphStore nodes and edges.
|
|
5
5
|
* Snapshots contain everything needed to reconstruct the node in a fresh graph.
|
|
6
6
|
*/
|
|
7
|
-
import { resolveGitDir, getGitRemoteUrl, getGitBranch, getGitHead
|
|
7
|
+
import { resolveGitDir, getGitRemoteUrl, getGitBranch, getGitHead } from './graph-id.js';
|
|
8
8
|
// ============================================================================
|
|
9
9
|
// Provenance Resolution
|
|
10
10
|
// ============================================================================
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/materialization/snapshot.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,OAAO,
|
|
1
|
+
{"version":3,"file":"snapshot.js","sourceRoot":"","sources":["../../src/materialization/snapshot.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAYH,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEzF,+EAA+E;AAC/E,wBAAwB;AACxB,+EAA+E;AAE/E;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,OAG/B;IACC,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC;IAC3C,MAAM,MAAM,GAAG,aAAa,CAAC,aAAa,CAAC,CAAC;IAE5C,OAAO;QACL,OAAO;QACP,SAAS,EAAE,aAAa;QACxB,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS;QACtE,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS;QACnE,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS;KAChE,CAAC;AACJ,CAAC;AAED,+EAA+E;AAC/E,sBAAsB;AACtB,+EAA+E;AAE/E;;;GAGG;AACH,KAAK,UAAU,cAAc,CAAC,MAAc,EAAE,KAAiB;IAC7D,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC;YACpC,MAAM,EAAE,MAAM;YACd,KAAK,EAAE,CAAC;SACT,CAAC,CAAC;QAEH,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAuC,CAAC;YAC5D,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;gBACzC,OAAO,IAAI,CAAC,GAAa,CAAC;YAC5B,CAAC;YACD,OAAO,eAAe,IAAI,CAAC,EAAE,EAAE,CAAC;QAClC,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,eAAe;IACjB,CAAC;IACD,OAAO,eAAe,MAAM,EAAE,CAAC;AACjC,CAAC;AAED,+EAA+E;AAC/E,yBAAyB;AACzB,+EAA+E;AAE/E;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,MAAc,EACd,KAAiB;IAEjB,MAAM,SAAS,GAAmB,EAAE,CAAC;IAErC,IAAI,CAAC;QACH,sDAAsD;QACtD,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QAC3D,MAAM,aAAa,GAAG,MAAM,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACjE,MAAM,QAAQ,GAAW,CAAC,GAAG,KAAK,EAAE,GAAG,aAAa,CAAC,CAAC;QAEtD,yBAAyB;QACzB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;YAC5B,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBAAE,SAAS;YAChC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAElB,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;YAC1D,MAAM,KAAK,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YAEtD,SAAS,CAAC,IAAI,CAAC;gBACb,OAAO;gBACP,KAAK;gBACL,QAAQ,EAAE,IAAI,CAAC,IAAI;gBACnB,QAAQ,EAAE,IAAI,CAAC,QAAQ;aACxB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,2BAA2B;IAC7B,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,+EAA+E;AAC/E,oBAAoB;AACpB,+EAA+E;AAE/E;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,IAAkB,EAClB,KAAiB,EACjB,UAA8B;IAE9B,MAAM,KAAK,GAAG,MAAM,kBAAkB,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IAEvD,+CAA+C;IAC/C,MAAM,aAAa,GAAG,KAAK;SACxB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,UAAU,CAAC;SACxC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;QAC/D,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IACpC,CAAC,CAAC,CAAC;IAEL,OAAO;QACL,OAAO,EAAE,CAAC;QACV,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,YAAY;QACnC,UAAU,EAAE,SAAS;QACrB,SAAS,EAAE,IAAI,CAAC,UAAU;QAC1B,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACpC,IAAI,EAAE;YACJ,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,MAAM,EAAG,IAA2C,CAAC,MAA4B;YACjF,eAAe,EAAE,IAAI,CAAC,eAAe;YACrC,aAAa,EAAE,IAAI,CAAC,aAAa,IAAK,IAAI,CAAC,QAAoC,IAAI,EAAE;YACrF,IAAI,EAAE,IAAI,CAAC,IAAI;SAChB;QACD,UAAU;QACV,KAAK;QACL,aAAa;KACd,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,IAAkB,EAClB,KAAiB,EACjB,UAA8B;IAE9B,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,IAAK,IAAI,CAAC,QAAoC,IAAI,EAAE,CAAC;IAE5F,OAAO;QACL,OAAO,EAAE,CAAC;QACV,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,YAAY;QACnC,UAAU,EAAE,YAAY;QACxB,SAAS,EAAE,IAAI,CAAC,UAAU;QAC1B,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACpC,IAAI,EAAE;YACJ,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,MAAM,EAAG,IAA2C,CAAC,MAA4B;YACjF,eAAe,EAAE,IAAI,CAAC,eAAe;YACrC,aAAa,EAAE,YAAY;YAC3B,IAAI,EAAE,IAAI,CAAC,IAAI;SAChB;QACD,UAAU;QACV,UAAU,EAAE,YAAY,CAAC,UAAgC;QACzD,UAAU,EAAE,YAAY,CAAC,SAAS,CAAC,CAAC,CAAC,wBAAwB,YAAY,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE;KAC3F,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,IAAkB,EAClB,KAAiB,EACjB,UAA8B;IAE9B,MAAM,QAAQ,GAAG,IAAI,CAAC,QAA+C,CAAC;IACtE,MAAM,UAAU,GAAG,QAAQ,EAAE,UAAgC,CAAC;IAE9D,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,oBAAoB,CAAC,IAAI,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;IACvD,CAAC;IACD,IAAI,UAAU,KAAK,YAAY,EAAE,CAAC;QAChC,OAAO,uBAAuB,CAAC,IAAI,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;IAC1D,CAAC;IAED,iCAAiC;IACjC,OAAO;QACL,OAAO,EAAE,CAAC;QACV,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,SAAS;QAChC,UAAU,EAAE,UAAU,IAAI,SAAS;QACnC,SAAS,EAAE,IAAI,CAAC,UAAU;QAC1B,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACpC,IAAI,EAAE;YACJ,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,MAAM,EAAG,IAA2C,CAAC,MAA4B;YACjF,eAAe,EAAE,IAAI,CAAC,eAAe;YACrC,aAAa,EAAE,IAAI,CAAC,aAAa,IAAI,QAAQ,IAAI,EAAE;YACnD,IAAI,EAAE,IAAI,CAAC,IAAI;SAChB;QACD,UAAU;KACX,CAAC;AACJ,CAAC"}
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
* Type definitions for the pluggable archival layer that captures
|
|
5
5
|
* materialized external node snapshots to durable storage.
|
|
6
6
|
*/
|
|
7
|
+
import type { GraphStore } from '../graph/store.js';
|
|
8
|
+
import type { ExternalNode } from '../schema/nodes.js';
|
|
7
9
|
/**
|
|
8
10
|
* Provenance — where a snapshot's data originated
|
|
9
11
|
*/
|
|
@@ -253,13 +255,13 @@ export interface RematerializeAllResult {
|
|
|
253
255
|
*/
|
|
254
256
|
export interface MaterializationArchiver {
|
|
255
257
|
/** Called by the auto-linker when a session lifecycle event occurs */
|
|
256
|
-
onSessionEvent(eventType: string, sessionUri: string, store:
|
|
258
|
+
onSessionEvent(eventType: string, sessionUri: string, store: GraphStore): Promise<ArchiveEventResult>;
|
|
257
259
|
/** Manually archive a specific node by URI */
|
|
258
|
-
archiveNode(uri: string, store:
|
|
260
|
+
archiveNode(uri: string, store: GraphStore): Promise<ArchiveEventResult>;
|
|
259
261
|
/** Rematerialize a node from the archive into the graph */
|
|
260
|
-
rematerialize(uri: string, store:
|
|
262
|
+
rematerialize(uri: string, store: GraphStore): Promise<boolean>;
|
|
261
263
|
/** Rematerialize all missing nodes */
|
|
262
|
-
rematerializeAll(store:
|
|
264
|
+
rematerializeAll(store: GraphStore): Promise<RematerializeAllResult>;
|
|
263
265
|
/** List all archived sessions */
|
|
264
266
|
listArchived(filter?: ArchiveFilter): Promise<ArchiveListEntry[]>;
|
|
265
267
|
/** Set the materialization provider (for materializeBeforeArchive) */
|
|
@@ -274,7 +276,7 @@ export interface MaterializationArchiver {
|
|
|
274
276
|
* Matches the materializeNode method on ProviderAwareStore.
|
|
275
277
|
*/
|
|
276
278
|
export interface MaterializationProvider {
|
|
277
|
-
materializeNode(uri: string): Promise<
|
|
279
|
+
materializeNode(uri: string): Promise<ExternalNode>;
|
|
278
280
|
}
|
|
279
281
|
/**
|
|
280
282
|
* Configuration for the MaterializationArchiver
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/materialization/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/materialization/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAMvD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAC;IAEhB,6DAA6D;IAC7D,SAAS,EAAE,MAAM,CAAC;IAElB,oCAAoC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,yCAAyC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,qCAAqC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC,+CAA+C;IAC/C,OAAO,EAAE,CAAC,CAAC;IAEX,2CAA2C;IAC3C,GAAG,EAAE,MAAM,CAAC;IAEZ,sBAAsB;IACtB,MAAM,EAAE,MAAM,CAAC;IAEf,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAC;IAEnB,2CAA2C;IAC3C,SAAS,EAAE,MAAM,CAAC;IAElB,sCAAsC;IACtC,UAAU,EAAE,MAAM,CAAC;IAEnB,4CAA4C;IAC5C,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACvC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;KACjB,CAAC;IAEF,6CAA6C;IAC7C,UAAU,EAAE,kBAAkB,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,eAAgB,SAAQ,uBAAuB;IAC9D,UAAU,EAAE,SAAS,CAAC;IAEtB,oCAAoC;IACpC,KAAK,EAAE,YAAY,EAAE,CAAC;IAEtB,iDAAiD;IACjD,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAmB,SAAQ,uBAAuB;IACjE,UAAU,EAAE,YAAY,CAAC;IAEzB,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,6CAA6C;IAC7C,UAAU,EAAE,MAAM,CAAC;CACpB;AAMD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,qDAAqD;IACrD,cAAc,EAAE,OAAO,CAAC;IAExB,4DAA4D;IAC5D,mBAAmB,EAAE,OAAO,CAAC;IAE7B,kDAAkD;IAClD,YAAY,EAAE,OAAO,CAAC;IAEtB;;;;OAIG;IACH,wBAAwB,EAAE,OAAO,CAAC;CACnC;AAED,eAAO,MAAM,sBAAsB,EAAE,aAKpC,CAAC;AAMF;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAC;IAEf,8DAA8D;IAC9D,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,6BAA6B;IAC7B,UAAU,EAAE,WAAW,GAAG,gBAAgB,GAAG,QAAQ,CAAC;IAEtD,qDAAqD;IACrD,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,0BAA0B,EAAE,IAAI,CAAC,qBAAqB,EAAE,gBAAgB,CAGpF,CAAC;AAMF;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,OAAO,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,uBAAuB;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,iBAAiB;IACjB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,8CAA8C;IAC9C,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAE1B,gCAAgC;IAChC,OAAO,CAAC,QAAQ,EAAE,uBAAuB,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAEnE,iCAAiC;IACjC,YAAY,CAAC,SAAS,EAAE,uBAAuB,EAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAEhF,iCAAiC;IACjC,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,GAAG,IAAI,CAAC,CAAC;IAE/D,+BAA+B;IAC/B,IAAI,CAAC,MAAM,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;IAE1D,2BAA2B;IAC3B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5B,2BAA2B;IAC3B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAEvB,mBAAmB;IACnB,MAAM,IAAI,OAAO,CAAC,WAAW,CAAC,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,uBAAwB,SAAQ,oBAAoB;IACnE,0DAA0D;IAC1D,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IAExE,qDAAqD;IACrD,YAAY,CACV,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE;QAAE,eAAe,EAAE,MAAM,CAAA;KAAE,GACnC,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;IAEnC,iDAAiD;IACjD,UAAU,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAEhC,+DAA+D;IAC/D,iBAAiB,CACf,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,OAAO,CACR,KAAK,CAAC;QACJ,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC,CACH,CAAC;CACH;AAMD;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,WAAY,SAAQ,oBAAoB;IACvD,6CAA6C;IAC7C,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;CAC3B;AAMD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,KAAK,CAAC;QACZ,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,OAAO,CAAC;QAChB,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC,CAAC;CACJ;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC/C;AAED;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC,sEAAsE;IACtE,cAAc,CACZ,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,UAAU,GAChB,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAE/B,8CAA8C;IAC9C,WAAW,CACT,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,UAAU,GAChB,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAE/B,2DAA2D;IAC3D,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEhE,sCAAsC;IACtC,gBAAgB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;IAErE,iCAAiC;IACjC,YAAY,CAAC,MAAM,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;IAElE,sEAAsE;IACtE,0BAA0B,CAAC,QAAQ,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAEpE,4BAA4B;IAC5B,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5B,2BAA2B;IAC3B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CACrD;AAED;;GAEG;AACH,MAAM,WAAW,6BAA6B;IAC5C,+EAA+E;IAC/E,QAAQ,EAAE,oBAAoB,CAAC;IAE/B,+BAA+B;IAC/B,YAAY,EAAE,WAAW,EAAE,CAAC;IAE5B,qBAAqB;IACrB,MAAM,EAAE,aAAa,CAAC;IAEtB,+BAA+B;IAC/B,OAAO,EAAE,MAAM,CAAC;IAEhB,oCAAoC;IACpC,SAAS,EAAE,MAAM,CAAC;IAElB;;;;OAIG;IACH,uBAAuB,CAAC,EAAE,uBAAuB,CAAC;CACnD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/materialization/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/materialization/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA+HH,MAAM,CAAC,MAAM,sBAAsB,GAAkB;IACnD,cAAc,EAAE,KAAK;IACrB,mBAAmB,EAAE,IAAI;IACzB,YAAY,EAAE,IAAI;IAClB,wBAAwB,EAAE,IAAI;CAC/B,CAAC;AA6BF,MAAM,CAAC,MAAM,0BAA0B,GAAkD;IACvF,MAAM,EAAE,mBAAmB;IAC3B,UAAU,EAAE,gBAAgB;CAC7B,CAAC"}
|
package/dist/mcp/server.d.ts
CHANGED
|
@@ -11,11 +11,12 @@
|
|
|
11
11
|
* - graph: Full graph operations — link, query (all node types, edges, blockers)
|
|
12
12
|
* - annotate: Feedback lifecycle — create, resolve, dismiss, reopen
|
|
13
13
|
* - context: Context/spec CRUD — create, get, update, list
|
|
14
|
+
* - attempts: Attempt/verify coordination — record_attempt, list_attempts (verifies edges via link)
|
|
14
15
|
*/
|
|
15
16
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
16
17
|
import { type ClientOptions } from '../client/client.js';
|
|
17
18
|
/** Available MCP scopes */
|
|
18
|
-
export type MCPScope = 'tasks' | 'graph' | 'annotate' | 'context';
|
|
19
|
+
export type MCPScope = 'tasks' | 'graph' | 'annotate' | 'context' | 'attempts';
|
|
19
20
|
export interface MCPServerOptions {
|
|
20
21
|
/** Options for the OpenTasks client */
|
|
21
22
|
clientOptions?: ClientOptions;
|
package/dist/mcp/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAmB,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAgB1E,2BAA2B;AAC3B,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,CAAC;AAE/E,MAAM,WAAW,gBAAgB;IAC/B,uCAAuC;IACvC,aAAa,CAAC,EAAE,aAAa,CAAC;IAE9B;;;OAGG;IACH,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC;CACrB;AAMD;;;;;;;;GAQG;AACH,eAAO,MAAM,UAAU,EAAE,QAAQ,EAA0D,CAAC;AAE5F,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,SAAS,CA+BrE"}
|
package/dist/mcp/server.js
CHANGED
|
@@ -11,10 +11,14 @@
|
|
|
11
11
|
* - graph: Full graph operations — link, query (all node types, edges, blockers)
|
|
12
12
|
* - annotate: Feedback lifecycle — create, resolve, dismiss, reopen
|
|
13
13
|
* - context: Context/spec CRUD — create, get, update, list
|
|
14
|
+
* - attempts: Attempt/verify coordination — record_attempt, list_attempts (verifies edges via link)
|
|
14
15
|
*/
|
|
15
16
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
16
17
|
import { z } from 'zod';
|
|
17
18
|
import { OpenTasksClient } from '../client/client.js';
|
|
19
|
+
import { VERSION } from '../version.js';
|
|
20
|
+
import { TASK_ACTIONS } from '../providers/traits/TaskManageable.js';
|
|
21
|
+
import { attemptOutcome, isUnevidencedCompletion, } from '../graph/attempts.js';
|
|
18
22
|
// ============================================================================
|
|
19
23
|
// Server Factory
|
|
20
24
|
// ============================================================================
|
|
@@ -27,13 +31,13 @@ import { OpenTasksClient } from '../client/client.js';
|
|
|
27
31
|
* Additional scopes can be opted in:
|
|
28
32
|
* --scope tasks,graph,annotate,context
|
|
29
33
|
*/
|
|
30
|
-
export const ALL_SCOPES = ['tasks', 'graph', 'annotate', 'context'];
|
|
34
|
+
export const ALL_SCOPES = ['tasks', 'graph', 'annotate', 'context', 'attempts'];
|
|
31
35
|
export function createMCPServer(options) {
|
|
32
36
|
const client = new OpenTasksClient(options?.clientOptions);
|
|
33
37
|
const scopes = new Set(options?.scopes ?? ['tasks']);
|
|
34
38
|
const server = new McpServer({
|
|
35
39
|
name: 'opentasks',
|
|
36
|
-
version:
|
|
40
|
+
version: VERSION,
|
|
37
41
|
});
|
|
38
42
|
// Always register tasks scope
|
|
39
43
|
if (scopes.has('tasks')) {
|
|
@@ -48,6 +52,9 @@ export function createMCPServer(options) {
|
|
|
48
52
|
if (scopes.has('context')) {
|
|
49
53
|
registerContextTools(server, client);
|
|
50
54
|
}
|
|
55
|
+
if (scopes.has('attempts')) {
|
|
56
|
+
registerAttemptTools(server, client);
|
|
57
|
+
}
|
|
51
58
|
return server;
|
|
52
59
|
}
|
|
53
60
|
// ============================================================================
|
|
@@ -64,10 +71,11 @@ function registerTaskTools(server, client) {
|
|
|
64
71
|
parent_id: z.string().optional().describe('Parent node ID'),
|
|
65
72
|
metadata: z.record(z.string(), z.unknown()).optional().describe('Additional metadata'),
|
|
66
73
|
scheme: z.string().optional().describe('Provider scheme to route creation to (e.g. beads, sudocode)'),
|
|
74
|
+
idempotency_key: z.string().optional().describe('Dedup key: retrying create with the same key returns the original task instead of a duplicate'),
|
|
67
75
|
}, async (args) => {
|
|
68
76
|
try {
|
|
69
|
-
const { scheme, ...params } = args;
|
|
70
|
-
const result = await client.createNode({ type: 'task', ...params }, scheme ? { scheme } : undefined);
|
|
77
|
+
const { scheme, idempotency_key, status = 'open', ...params } = args;
|
|
78
|
+
const result = await client.createNode({ type: 'task', status, ...params }, scheme || idempotency_key ? { scheme, idempotencyKey: idempotency_key } : undefined);
|
|
71
79
|
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
72
80
|
}
|
|
73
81
|
catch (error) {
|
|
@@ -103,8 +111,8 @@ function registerTaskTools(server, client) {
|
|
|
103
111
|
archived: z.boolean().optional().describe('Archive/unarchive'),
|
|
104
112
|
metadata: z.record(z.string(), z.unknown()).optional().describe('Update metadata (merged)'),
|
|
105
113
|
// Semantic transitions
|
|
106
|
-
transition: z.enum(
|
|
107
|
-
.describe('Semantic status transition (alternative to setting status directly)'),
|
|
114
|
+
transition: z.enum(TASK_ACTIONS).optional()
|
|
115
|
+
.describe('Semantic status transition (alternative to setting status directly). fail/abandon are terminal outcomes distinct from complete/close.'),
|
|
108
116
|
// Blocker management
|
|
109
117
|
addBlockedBy: z.array(z.string()).optional().describe('Add blocker task IDs (these block this task)'),
|
|
110
118
|
removeBlockedBy: z.array(z.string()).optional().describe('Remove blocker task IDs'),
|
|
@@ -112,7 +120,7 @@ function registerTaskTools(server, client) {
|
|
|
112
120
|
removeBlocks: z.array(z.string()).optional().describe('Remove task IDs that this task blocks'),
|
|
113
121
|
}, async (args) => {
|
|
114
122
|
const results = [];
|
|
115
|
-
const { id, transition, addBlockedBy, removeBlockedBy, addBlocks, removeBlocks, tags, ...fieldUpdates } = args;
|
|
123
|
+
const { id, transition, addBlockedBy, removeBlockedBy, addBlocks, removeBlocks, tags: _tags, ...fieldUpdates } = args;
|
|
116
124
|
const hasFieldUpdates = Object.values(fieldUpdates).some((v) => v !== undefined);
|
|
117
125
|
// 1. Apply field updates if any
|
|
118
126
|
if (hasFieldUpdates) {
|
|
@@ -262,21 +270,74 @@ function registerTaskTools(server, client) {
|
|
|
262
270
|
priority: typeof filters.priority === 'number' ? filters.priority : undefined,
|
|
263
271
|
},
|
|
264
272
|
});
|
|
265
|
-
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
273
|
+
return { content: [{ type: 'text', text: JSON.stringify(withTaskListHints(result), null, 2) }] };
|
|
266
274
|
}
|
|
267
275
|
// Blocker queries
|
|
268
276
|
if (blockersOf) {
|
|
269
277
|
const result = await client.query({ blockers: { nodeId: blockersOf } });
|
|
270
|
-
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
278
|
+
return { content: [{ type: 'text', text: JSON.stringify(withTaskListHints(result), null, 2) }] };
|
|
271
279
|
}
|
|
272
280
|
if (blockedBy) {
|
|
273
281
|
const result = await client.query({ blocking: { nodeId: blockedBy } });
|
|
274
|
-
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
282
|
+
return { content: [{ type: 'text', text: JSON.stringify(withTaskListHints(result), null, 2) }] };
|
|
275
283
|
}
|
|
276
284
|
// General task list
|
|
277
285
|
const result = await client.query({
|
|
278
286
|
nodes: { type: 'task', ...filters },
|
|
279
287
|
});
|
|
288
|
+
return { content: [{ type: 'text', text: JSON.stringify(withTaskListHints(result), null, 2) }] };
|
|
289
|
+
}
|
|
290
|
+
catch (error) {
|
|
291
|
+
return errorResult(error);
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
server.tool('claim_task', 'Atomically claim a task for an agent (lease-based, race-free). Returns claimed:false (not an error) when another agent already holds it. Use the returned fence with release_task/renew_claim.', {
|
|
295
|
+
id: z.string().describe('Task ID (native tasks only)'),
|
|
296
|
+
agentId: z.string().describe('Agent acquiring the claim'),
|
|
297
|
+
durationMs: z.number().optional().describe('Lease duration in ms (default: 30 min)'),
|
|
298
|
+
force: z.boolean().optional().describe('Claim even if held by another, unexpired agent'),
|
|
299
|
+
}, async (args) => {
|
|
300
|
+
try {
|
|
301
|
+
const result = await client.task({ claim: args });
|
|
302
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
303
|
+
}
|
|
304
|
+
catch (error) {
|
|
305
|
+
return errorResult(error);
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
server.tool('claim_next', 'Atomically claim the next ready, unclaimed task for an agent (fused ready-query + claim). Returns claimed:false when nothing is available.', {
|
|
309
|
+
agentId: z.string().describe('Agent acquiring the claim'),
|
|
310
|
+
durationMs: z.number().optional().describe('Lease duration in ms (default: 30 min)'),
|
|
311
|
+
}, async (args) => {
|
|
312
|
+
try {
|
|
313
|
+
const result = await client.task({ claimNext: args });
|
|
314
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
315
|
+
}
|
|
316
|
+
catch (error) {
|
|
317
|
+
return errorResult(error);
|
|
318
|
+
}
|
|
319
|
+
});
|
|
320
|
+
server.tool('release_task', 'Release a claim on a task. Pass the fence from claim_task to reject a stale/superseded release.', {
|
|
321
|
+
id: z.string().describe('Task ID (native tasks only)'),
|
|
322
|
+
agentId: z.string().describe('Agent that holds the claim'),
|
|
323
|
+
fence: z.number().optional().describe('Fence token from the claim'),
|
|
324
|
+
}, async (args) => {
|
|
325
|
+
try {
|
|
326
|
+
const result = await client.task({ release: args });
|
|
327
|
+
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
328
|
+
}
|
|
329
|
+
catch (error) {
|
|
330
|
+
return errorResult(error);
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
server.tool('renew_claim', "Renew/extend a claim's lease (heartbeat). Pass the fence from claim_task to reject a stale/superseded renew.", {
|
|
334
|
+
id: z.string().describe('Task ID (native tasks only)'),
|
|
335
|
+
agentId: z.string().describe('Agent that holds the claim'),
|
|
336
|
+
durationMs: z.number().optional().describe('New lease duration in ms (default: 30 min)'),
|
|
337
|
+
fence: z.number().optional().describe('Fence token from the claim'),
|
|
338
|
+
}, async (args) => {
|
|
339
|
+
try {
|
|
340
|
+
const result = await client.task({ renew: args });
|
|
280
341
|
return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] };
|
|
281
342
|
}
|
|
282
343
|
catch (error) {
|
|
@@ -291,7 +352,7 @@ function registerGraphTools(server, client) {
|
|
|
291
352
|
server.tool('link', 'Create or remove an edge between two nodes. Supports local IDs (e.g. t-abc1) and provider URIs (e.g. beads://project/i-123).', {
|
|
292
353
|
fromId: z.string().describe('Source node ID or provider URI'),
|
|
293
354
|
toId: z.string().describe('Target node ID or provider URI'),
|
|
294
|
-
type: z.string().describe('Relationship type: blocks, implements, references, depends-on, related, parent-of, child-of, duplicates, supersedes, discovered-from'),
|
|
355
|
+
type: z.string().describe('Relationship type: blocks, implements, references, depends-on, related, parent-of, child-of, duplicates, supersedes, discovered-from, verifies, reproduces'),
|
|
295
356
|
remove: z.boolean().optional().describe('Remove the edge instead of creating (default: false)'),
|
|
296
357
|
metadata: z.record(z.string(), z.unknown()).optional().describe('Additional metadata'),
|
|
297
358
|
}, async (args) => {
|
|
@@ -341,6 +402,7 @@ function registerGraphTools(server, client) {
|
|
|
341
402
|
priority: z.union([z.number(), z.object({ min: z.number().optional(), max: z.number().optional() })]).optional(),
|
|
342
403
|
assignee: z.string().optional(),
|
|
343
404
|
limit: z.number().optional(),
|
|
405
|
+
excludeClaimed: z.boolean().optional().describe('Exclude tasks under a live claim (lease). Off by default; set when dispatching directly off ready.'),
|
|
344
406
|
}).optional(),
|
|
345
407
|
blockers: z.object({
|
|
346
408
|
nodeId: z.string(),
|
|
@@ -399,6 +461,55 @@ function registerGraphTools(server, client) {
|
|
|
399
461
|
return errorResult(error);
|
|
400
462
|
}
|
|
401
463
|
});
|
|
464
|
+
server.tool('events_since', `Pull graph change events since a cursor (token-cheap polling — get just what changed instead of re-querying the world).
|
|
465
|
+
Pass back the { epoch, seq } cursor from a previous call; omit both to get a baseline cursor from the current head (no events).
|
|
466
|
+
Returns { events, nextCursor }. If the cursor is too old or the daemon restarted, returns { resync: true, nextCursor } — re-query state and adopt nextCursor.`, {
|
|
467
|
+
epoch: z.string().optional().describe('Cursor epoch from a prior call (omit for a baseline)'),
|
|
468
|
+
seq: z.number().optional().describe('Cursor seq from a prior call (omit for a baseline)'),
|
|
469
|
+
}, async (args) => {
|
|
470
|
+
try {
|
|
471
|
+
// No cursor → hand back the current head as a baseline to poll from.
|
|
472
|
+
if (args.epoch === undefined || args.seq === undefined) {
|
|
473
|
+
const cursor = await client.eventsCurrent();
|
|
474
|
+
return {
|
|
475
|
+
content: [
|
|
476
|
+
{
|
|
477
|
+
type: 'text',
|
|
478
|
+
text: JSON.stringify({ events: [], nextCursor: cursor }, null, 2),
|
|
479
|
+
},
|
|
480
|
+
],
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
const result = await client.eventsSince({ epoch: args.epoch, seq: args.seq });
|
|
484
|
+
if ('resync' in result && result.resync) {
|
|
485
|
+
const cursor = await client.eventsCurrent();
|
|
486
|
+
return {
|
|
487
|
+
content: [
|
|
488
|
+
{
|
|
489
|
+
type: 'text',
|
|
490
|
+
text: JSON.stringify({ resync: true, nextCursor: cursor }, null, 2),
|
|
491
|
+
},
|
|
492
|
+
],
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
const events = result.events;
|
|
496
|
+
const last = events.length > 0 ? events[events.length - 1] : null;
|
|
497
|
+
const nextCursor = last
|
|
498
|
+
? { epoch: last.epoch, seq: last.seq }
|
|
499
|
+
: { epoch: args.epoch, seq: args.seq };
|
|
500
|
+
return {
|
|
501
|
+
content: [
|
|
502
|
+
{
|
|
503
|
+
type: 'text',
|
|
504
|
+
text: JSON.stringify({ events, nextCursor }, null, 2),
|
|
505
|
+
},
|
|
506
|
+
],
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
catch (error) {
|
|
510
|
+
return errorResult(error);
|
|
511
|
+
}
|
|
512
|
+
});
|
|
402
513
|
}
|
|
403
514
|
// ============================================================================
|
|
404
515
|
// Scope: annotate (opt-in)
|
|
@@ -687,11 +798,197 @@ By default returns the node metadata (lightweight). Use resolve: true to include
|
|
|
687
798
|
});
|
|
688
799
|
}
|
|
689
800
|
// ============================================================================
|
|
801
|
+
// Scope: attempts (opt-in)
|
|
802
|
+
// ============================================================================
|
|
803
|
+
const ATTEMPT_OUTCOMES = ['pending', 'success', 'failure', 'abandoned', 'inconclusive'];
|
|
804
|
+
const TERMINAL_OUTCOMES = new Set(['success', 'failure', 'abandoned', 'inconclusive']);
|
|
805
|
+
function registerAttemptTools(server, client) {
|
|
806
|
+
const evidenceSchema = z
|
|
807
|
+
.object({
|
|
808
|
+
kind: z.enum(['test', 'command', 'commit', 'context', 'external', 'url']),
|
|
809
|
+
ref: z.string().describe('test-suite id / command / git sha / context node id / uri'),
|
|
810
|
+
detail: z.string().optional().describe('exit code, "12/12 passed", metric value'),
|
|
811
|
+
hash: z.string().optional().describe('content hash for tamper-evidence'),
|
|
812
|
+
})
|
|
813
|
+
.describe('Pointer to an independently checkable artifact — the Commitment lever');
|
|
814
|
+
server.tool('record_attempt', "Record (create or update) an attempt at a task — one agent's effort, with outcome + evidence. " +
|
|
815
|
+
'Omit `id` to start a new attempt; pass `id` to update. A terminal outcome ' +
|
|
816
|
+
'(success/failure/abandoned/inconclusive) closes the attempt; the parent task is left open ' +
|
|
817
|
+
'(a retry is a new attempt). Claiming for exclusivity is separate — use claim_task.', {
|
|
818
|
+
taskId: z.string().describe('The task being attempted (the attempt target)'),
|
|
819
|
+
agent: z.string().describe('Agent making the attempt'),
|
|
820
|
+
id: z.string().optional().describe('Existing attempt ID to update; omit to create'),
|
|
821
|
+
outcome: z
|
|
822
|
+
.enum(ATTEMPT_OUTCOMES)
|
|
823
|
+
.optional()
|
|
824
|
+
.describe('Result (default: pending on create). Terminal values close the attempt.'),
|
|
825
|
+
summary: z
|
|
826
|
+
.string()
|
|
827
|
+
.optional()
|
|
828
|
+
.describe('What was tried / what happened — name files or areas touched so partners see overlap'),
|
|
829
|
+
evidence: evidenceSchema.optional(),
|
|
830
|
+
failureReason: z
|
|
831
|
+
.string()
|
|
832
|
+
.optional()
|
|
833
|
+
.describe('Why it failed / was abandoned — the negative-result record'),
|
|
834
|
+
fromId: z
|
|
835
|
+
.string()
|
|
836
|
+
.optional()
|
|
837
|
+
.describe('Prior attempt this follows (creates a discovered-from link)'),
|
|
838
|
+
}, async (args) => {
|
|
839
|
+
try {
|
|
840
|
+
const { taskId, agent, id, outcome, summary, evidence: ev, failureReason, fromId } = args;
|
|
841
|
+
// Build the metadata.attempt patch from the provided fields only.
|
|
842
|
+
const patch = {};
|
|
843
|
+
if (outcome !== undefined)
|
|
844
|
+
patch.outcome = outcome;
|
|
845
|
+
if (summary !== undefined)
|
|
846
|
+
patch.summary = summary;
|
|
847
|
+
if (ev !== undefined)
|
|
848
|
+
patch.evidence = ev;
|
|
849
|
+
if (failureReason !== undefined)
|
|
850
|
+
patch.failureReason = failureReason;
|
|
851
|
+
// CREATE
|
|
852
|
+
if (!id) {
|
|
853
|
+
const oc = outcome ?? 'pending';
|
|
854
|
+
const node = await client.createNode({
|
|
855
|
+
type: 'attempt',
|
|
856
|
+
title: summary ? summary.slice(0, 120) : `Attempt at ${taskId} by ${agent}`,
|
|
857
|
+
target_id: taskId,
|
|
858
|
+
assignee: agent,
|
|
859
|
+
status: TERMINAL_OUTCOMES.has(oc) ? 'closed' : 'in_progress',
|
|
860
|
+
metadata: { attempt: { outcome: oc, ...patch } },
|
|
861
|
+
});
|
|
862
|
+
const createdId = node.id;
|
|
863
|
+
if (fromId && createdId) {
|
|
864
|
+
await client.link({ fromId: createdId, toId: fromId, type: 'discovered-from' });
|
|
865
|
+
}
|
|
866
|
+
return { content: [{ type: 'text', text: JSON.stringify(node, null, 2) }] };
|
|
867
|
+
}
|
|
868
|
+
// UPDATE — merge into the existing metadata.attempt (the tool is its sole writer).
|
|
869
|
+
const existing = (await client.getNode(id));
|
|
870
|
+
if (!existing) {
|
|
871
|
+
return {
|
|
872
|
+
content: [{ type: 'text', text: JSON.stringify({ error: 'Attempt not found', id }) }],
|
|
873
|
+
isError: true,
|
|
874
|
+
};
|
|
875
|
+
}
|
|
876
|
+
const mergedAttempt = { ...(existing.metadata?.attempt ?? {}), ...patch };
|
|
877
|
+
const updates = { metadata: { attempt: mergedAttempt } };
|
|
878
|
+
if (outcome !== undefined) {
|
|
879
|
+
updates.status = TERMINAL_OUTCOMES.has(outcome) ? 'closed' : 'in_progress';
|
|
880
|
+
}
|
|
881
|
+
if (fromId) {
|
|
882
|
+
await client.link({ fromId: id, toId: fromId, type: 'discovered-from' });
|
|
883
|
+
}
|
|
884
|
+
const node = await client.updateNode(id, updates);
|
|
885
|
+
return { content: [{ type: 'text', text: JSON.stringify(node, null, 2) }] };
|
|
886
|
+
}
|
|
887
|
+
catch (error) {
|
|
888
|
+
return errorResult(error);
|
|
889
|
+
}
|
|
890
|
+
});
|
|
891
|
+
server.tool('list_attempts', 'List attempts and their verification state — the coordination read: what every agent is doing ' +
|
|
892
|
+
"now, and which completions are unevidenced. Verification edges are created via `link` (type 'verifies').", {
|
|
893
|
+
taskId: z.string().optional().describe('Only attempts of this task'),
|
|
894
|
+
agent: z.string().optional().describe("Only this agent's attempts"),
|
|
895
|
+
status: z.enum(['in_progress', 'closed']).optional(),
|
|
896
|
+
outcome: z.enum(ATTEMPT_OUTCOMES).optional(),
|
|
897
|
+
inProgress: z
|
|
898
|
+
.boolean()
|
|
899
|
+
.optional()
|
|
900
|
+
.describe('Shortcut for status=in_progress — "what is everyone doing right now"'),
|
|
901
|
+
unverified: z
|
|
902
|
+
.boolean()
|
|
903
|
+
.optional()
|
|
904
|
+
.describe('Only success attempts that are unevidenced (no checkable evidence, no passing verifies edge)'),
|
|
905
|
+
includeVerifications: z
|
|
906
|
+
.boolean()
|
|
907
|
+
.optional()
|
|
908
|
+
.describe("Attach each attempt's verifies edges (default: true)"),
|
|
909
|
+
}, async (args) => {
|
|
910
|
+
try {
|
|
911
|
+
const { taskId, agent, status, outcome, inProgress, unverified, includeVerifications } = args;
|
|
912
|
+
const effStatus = inProgress ? 'in_progress' : status;
|
|
913
|
+
const nodeResult = await client.query({
|
|
914
|
+
nodes: { type: 'attempt', ...(effStatus ? { status: effStatus } : {}) },
|
|
915
|
+
verbose: true,
|
|
916
|
+
});
|
|
917
|
+
let items = (nodeResult.items ?? []).filter((n) => n.type === 'attempt');
|
|
918
|
+
if (taskId)
|
|
919
|
+
items = items.filter((n) => n.target_id === taskId);
|
|
920
|
+
if (agent)
|
|
921
|
+
items = items.filter((n) => n.assignee === agent);
|
|
922
|
+
if (outcome)
|
|
923
|
+
items = items.filter((n) => attemptOutcome(n) === outcome);
|
|
924
|
+
// Verification edges are needed for the unverified filter or to attach them.
|
|
925
|
+
const needEdges = Boolean(unverified) || includeVerifications !== false;
|
|
926
|
+
let edges = [];
|
|
927
|
+
if (needEdges) {
|
|
928
|
+
const edgeResult = await client.query({ edges: { type: 'verifies' }, verbose: true });
|
|
929
|
+
edges = edgeResult.items ?? [];
|
|
930
|
+
}
|
|
931
|
+
if (unverified)
|
|
932
|
+
items = items.filter((n) => isUnevidencedCompletion(n, edges));
|
|
933
|
+
const out = includeVerifications === false
|
|
934
|
+
? items
|
|
935
|
+
: items.map((n) => ({ ...n, verifications: edges.filter((e) => e.to_id === n.id) }));
|
|
936
|
+
return {
|
|
937
|
+
content: [
|
|
938
|
+
{ type: 'text', text: JSON.stringify({ items: out, count: out.length }, null, 2) },
|
|
939
|
+
],
|
|
940
|
+
};
|
|
941
|
+
}
|
|
942
|
+
catch (error) {
|
|
943
|
+
return errorResult(error);
|
|
944
|
+
}
|
|
945
|
+
});
|
|
946
|
+
}
|
|
947
|
+
// ============================================================================
|
|
690
948
|
// Helpers
|
|
691
949
|
// ============================================================================
|
|
692
950
|
function errorMessage(error) {
|
|
693
951
|
return error instanceof Error ? error.message : String(error);
|
|
694
952
|
}
|
|
953
|
+
function withTaskListHints(result) {
|
|
954
|
+
if (!isRecord(result))
|
|
955
|
+
return result;
|
|
956
|
+
const output = { ...result };
|
|
957
|
+
if (Array.isArray(output.items)) {
|
|
958
|
+
output.items = output.items.map(withTaskItemHints);
|
|
959
|
+
output.listHint =
|
|
960
|
+
'list_tasks returns summaries. If a task may have more instructions than the title shows, call get_task with the id and read content before acting.';
|
|
961
|
+
}
|
|
962
|
+
const data = output.data;
|
|
963
|
+
if (isRecord(data) && Array.isArray(data.items)) {
|
|
964
|
+
output.data = {
|
|
965
|
+
...data,
|
|
966
|
+
items: data.items.map(withTaskItemHints),
|
|
967
|
+
listHint: 'list_tasks returns summaries. If a task may have more instructions than the title shows, call get_task with the id and read content before acting.',
|
|
968
|
+
};
|
|
969
|
+
}
|
|
970
|
+
return output;
|
|
971
|
+
}
|
|
972
|
+
function withTaskItemHints(item) {
|
|
973
|
+
if (!isRecord(item))
|
|
974
|
+
return item;
|
|
975
|
+
const id = typeof item.id === 'string' ? item.id : undefined;
|
|
976
|
+
const content = typeof item.content === 'string' ? item.content : undefined;
|
|
977
|
+
return {
|
|
978
|
+
...item,
|
|
979
|
+
contentPreview: content ? previewText(content, 360) : undefined,
|
|
980
|
+
contentLength: content?.length ?? undefined,
|
|
981
|
+
fullContentAvailableViaGetTask: Boolean(id),
|
|
982
|
+
getTaskHint: id ? `Call get_task with id "${id}" to read the full task content before acting.` : undefined,
|
|
983
|
+
};
|
|
984
|
+
}
|
|
985
|
+
function previewText(text, max) {
|
|
986
|
+
const compact = text.replace(/\s+/g, ' ').trim();
|
|
987
|
+
return compact.length <= max ? compact : `${compact.slice(0, max - 1).trimEnd()}…`;
|
|
988
|
+
}
|
|
989
|
+
function isRecord(value) {
|
|
990
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
991
|
+
}
|
|
695
992
|
function errorResult(error) {
|
|
696
993
|
return {
|
|
697
994
|
content: [{ type: 'text', text: JSON.stringify({ error: errorMessage(error) }) }],
|