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
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: opentasks
|
|
3
|
+
description: Use when managing work items, linking external data (Slack, docs, URLs) to tasks, querying task dependencies or blockers, leaving cross-system feedback on specs or issues, or coordinating work across multiple task systems. Use when the agent has access to the `opentasks` CLI.
|
|
4
|
+
user-invocable: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# OpenTasks
|
|
8
|
+
|
|
9
|
+
OpenTasks is a graph connector that adds a relationship layer across task systems. It does not replace those systems — it provides cross-system edges, feedback, and dependency tracking.
|
|
10
|
+
|
|
11
|
+
## CLI Commands
|
|
12
|
+
|
|
13
|
+
All operations go through the `opentasks` CLI, which talks to the daemon over IPC.
|
|
14
|
+
|
|
15
|
+
### Link — create or remove edges
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
opentasks link --from t-x7k9 --to c-a2b3 --type implements
|
|
19
|
+
opentasks link --from t-x7k9 --to t-m4n5 --type blocks
|
|
20
|
+
opentasks link --from t-x7k9 --to e-k7m2 --type references --metadata '{"context":"bug report"}'
|
|
21
|
+
opentasks link --from t-aaa --to t-bbb --type blocks --remove
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Returns `{ success, edgeId? }`. Idempotent. `blocks` edges are cycle-checked.
|
|
25
|
+
|
|
26
|
+
### Query — search nodes, edges, blockers, ready work
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
opentasks query '{"ready": {}}'
|
|
30
|
+
opentasks query '{"blockers": {"nodeId": "t-r8s9", "activeOnly": true}}'
|
|
31
|
+
opentasks query '{"blocking": {"nodeId": "t-x7k9", "transitive": true}}'
|
|
32
|
+
opentasks query '{"edges": {"from_id": "t-x7k9", "type": "references"}}'
|
|
33
|
+
opentasks query '{"tasks": {"specId": "c-a2b3"}}'
|
|
34
|
+
opentasks query '{"feedback": {"nodeId": "c-a2b3", "resolved": false}}'
|
|
35
|
+
opentasks query '{"unresolvedFeedback": {}}'
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Exactly one query key per call. Returns `{ items, total?, hasMore }`.
|
|
39
|
+
|
|
40
|
+
| Key | Purpose |
|
|
41
|
+
|-----|---------|
|
|
42
|
+
| `nodes` | Filter nodes by type, status, tags, search |
|
|
43
|
+
| `edges` | Filter edges by from_id, to_id, type |
|
|
44
|
+
| `ready` | Unblocked open tasks (tags?, priority?, assignee?) |
|
|
45
|
+
| `blockers` | What blocks a node (transitive?, activeOnly?) |
|
|
46
|
+
| `blocking` | What a node blocks (transitive?) |
|
|
47
|
+
| `feedback` | Feedback on a node (type?, resolved?) |
|
|
48
|
+
| `unresolvedFeedback` | All unresolved feedback (targetId?) |
|
|
49
|
+
| `tasks` | Tasks implementing a context (specId) |
|
|
50
|
+
| `specs` | Specs a task implements (issueId) |
|
|
51
|
+
|
|
52
|
+
### Annotate — feedback lifecycle
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Create feedback
|
|
56
|
+
opentasks annotate '{"targetId":"c-a2b3","create":{"content":"Implemented OAuth.","type":"comment"}}'
|
|
57
|
+
|
|
58
|
+
# With source issue link
|
|
59
|
+
opentasks annotate '{"targetId":"c-a2b3","fromId":"t-x7k9","create":{"content":"Done.","type":"comment"}}'
|
|
60
|
+
|
|
61
|
+
# Anchored suggestion
|
|
62
|
+
opentasks annotate '{"targetId":"c-a2b3","create":{"content":"Add rate limiting","type":"suggestion","anchor":{"line":15}}}'
|
|
63
|
+
|
|
64
|
+
# Resolve / dismiss / reopen
|
|
65
|
+
opentasks annotate '{"targetId":"c-a2b3","resolve":"f-t1u2"}'
|
|
66
|
+
opentasks annotate '{"targetId":"c-a2b3","dismiss":"f-t1u2"}'
|
|
67
|
+
opentasks annotate '{"targetId":"c-a2b3","reopen":"f-t1u2"}'
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Create — add nodes
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
opentasks create --type task --title "Fix SSO redirect" --status open --tags auth,bug --priority 1
|
|
74
|
+
opentasks create --type context --title "OAuth2 for API" --status active --content "## Requirements\n..."
|
|
75
|
+
opentasks create --type external --title "Slack: SSO bug" --uri "slack://C04ABCD/p123" --source slack --metadata '{"author":"alex"}'
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Get / Update / Delete
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
opentasks get t-x7k9
|
|
82
|
+
opentasks update t-x7k9 --status closed
|
|
83
|
+
opentasks update t-x7k9 --title "New title" --metadata '{"key":"val"}'
|
|
84
|
+
opentasks delete t-x7k9
|
|
85
|
+
opentasks delete t-x7k9 --hard
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Node Types
|
|
89
|
+
|
|
90
|
+
| Type | Prefix | Required | Purpose |
|
|
91
|
+
|------|--------|----------|---------|
|
|
92
|
+
| `context` | `c-` | title | Requirements, specs, intent (inline or file-backed) |
|
|
93
|
+
| `task` | `t-` | title, status | Actionable work items |
|
|
94
|
+
| `feedback` | `f-` | title, target_id, feedback_type | Comments, suggestions, requests |
|
|
95
|
+
| `external` | `e-` | title, uri, source | References to external systems |
|
|
96
|
+
|
|
97
|
+
All nodes support optional: `content`, `priority` (0-4), `tags[]`, `parent_id`, `metadata`.
|
|
98
|
+
|
|
99
|
+
## Context Sources
|
|
100
|
+
|
|
101
|
+
Context nodes support multiple content source types. The source type determines how content is stored and resolved.
|
|
102
|
+
|
|
103
|
+
| Source | Stored in node? | How content is accessed |
|
|
104
|
+
|--------|-----------------|------------------------|
|
|
105
|
+
| inline (default) | Yes, in `content` field | Read directly from the node |
|
|
106
|
+
| file | No (pointer only) | Resolved from the working tree or a pinned git commit |
|
|
107
|
+
| snippet | No (pointer only) | Resolved from specific line range in a file |
|
|
108
|
+
|
|
109
|
+
### Inline context (default)
|
|
110
|
+
|
|
111
|
+
Content is stored directly in the node. Use for design decisions, requirements written by agents, meeting notes, etc.
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
# CLI
|
|
115
|
+
opentasks create --type context --title "OAuth2 for API" --content "## Requirements\n..."
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
```json
|
|
119
|
+
// MCP: create_context
|
|
120
|
+
{ "title": "OAuth2 for API", "content": "## Requirements\n..." }
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### File-backed context
|
|
124
|
+
|
|
125
|
+
References a codebase file. Content is NOT stored — it's resolved on access from the working tree or at a specific git commit. Includes drift detection (has the file changed since it was captured?).
|
|
126
|
+
|
|
127
|
+
```json
|
|
128
|
+
// MCP: create_context with source
|
|
129
|
+
{
|
|
130
|
+
"title": "Auth Middleware",
|
|
131
|
+
"source": { "type": "file", "path": "src/auth/middleware.ts" },
|
|
132
|
+
"tags": ["auth"]
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Pin to a specific commit
|
|
136
|
+
{
|
|
137
|
+
"source": { "type": "file", "path": "src/auth/middleware.ts", "commit": "abc123" }
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Snippet context
|
|
142
|
+
|
|
143
|
+
References specific lines in a file. Like file-backed, but scoped to a line range.
|
|
144
|
+
|
|
145
|
+
```json
|
|
146
|
+
// MCP: create_context with snippet source
|
|
147
|
+
{
|
|
148
|
+
"title": "Token validation logic",
|
|
149
|
+
"source": { "type": "snippet", "path": "src/auth/middleware.ts", "startLine": 42, "endLine": 58 }
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Resolving content
|
|
154
|
+
|
|
155
|
+
File and snippet contexts don't store content. Use `get_context` with `resolve: true` to fetch the current file content.
|
|
156
|
+
|
|
157
|
+
```json
|
|
158
|
+
// MCP: get_context — lightweight (metadata only, no file I/O)
|
|
159
|
+
{ "id": "c-x7k9" }
|
|
160
|
+
|
|
161
|
+
// MCP: get_context — with file content resolved
|
|
162
|
+
{ "id": "c-x7k9", "resolve": true }
|
|
163
|
+
|
|
164
|
+
// MCP: get_context — content at the originally captured commit
|
|
165
|
+
{ "id": "c-x7k9", "resolve": true, "atCapturedCommit": true }
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
The response includes `_resolved.drifted: true/false` indicating whether the file has changed since capture.
|
|
169
|
+
|
|
170
|
+
### Syncing and drift detection
|
|
171
|
+
|
|
172
|
+
```json
|
|
173
|
+
// MCP: update_context — re-pin to current HEAD
|
|
174
|
+
{ "id": "c-x7k9", "sync": true }
|
|
175
|
+
|
|
176
|
+
// MCP: update_context — force re-pin even if unchanged
|
|
177
|
+
{ "id": "c-x7k9", "sync": true, "force": true }
|
|
178
|
+
|
|
179
|
+
// MCP: list_contexts — check drift for all file-backed contexts
|
|
180
|
+
{ "checkDrift": true }
|
|
181
|
+
|
|
182
|
+
// MCP: list_contexts — only file-backed contexts
|
|
183
|
+
{ "filesOnly": true, "checkDrift": true }
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Edge Types
|
|
187
|
+
|
|
188
|
+
| Type | Semantics | Cycle-checked |
|
|
189
|
+
|------|-----------|---------------|
|
|
190
|
+
| `blocks` | from must complete before to can start | Yes |
|
|
191
|
+
| `implements` | task implements context | No |
|
|
192
|
+
| `references` | general reference | No |
|
|
193
|
+
| `related` | loose association | No |
|
|
194
|
+
| `child-of` | hierarchical containment | No |
|
|
195
|
+
| `parent-of` | inverse of child-of | No |
|
|
196
|
+
| `depends-on` | soft dependency (informational, not used by `ready`) | No |
|
|
197
|
+
| `discovered-from` | found while working on | No |
|
|
198
|
+
| `duplicates` | from is duplicate of to | No |
|
|
199
|
+
| `supersedes` | from replaces to | No |
|
|
200
|
+
|
|
201
|
+
Edge types are extensible via string.
|
|
202
|
+
|
|
203
|
+
## URI Conventions
|
|
204
|
+
|
|
205
|
+
Nodes across systems are identified by URIs:
|
|
206
|
+
|
|
207
|
+
```
|
|
208
|
+
native://c-a2b3 # OpenTasks native node
|
|
209
|
+
beads://./bd-x7k9 # Beads issue
|
|
210
|
+
taskmaster://./auth-prd # Taskmaster spec
|
|
211
|
+
claude://current/t-abc # Claude task
|
|
212
|
+
slack://C04ABCD/p1234567890 # Slack message (custom)
|
|
213
|
+
github://owner/repo/pull/42 # GitHub PR (custom)
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
The `uri` field on ExternalNodes is freeform. Use consistent schemes for deduplication.
|
|
217
|
+
|
|
218
|
+
## Specialized Workflows
|
|
219
|
+
|
|
220
|
+
**Linking external data** (Slack messages, docs, URLs): See [linking-external-data.md](linking-external-data.md)
|
|
221
|
+
|
|
222
|
+
**Spec to implementation** (create spec, break into issues, track to completion): See [spec-to-implementation.md](spec-to-implementation.md)
|
|
223
|
+
|
|
224
|
+
**Feedback and review** (cross-system feedback, suggestion lifecycle): See [feedback-and-review.md](feedback-and-review.md)
|
|
225
|
+
|
|
226
|
+
**Dependency management** (blockers, ready queries, work loops): See [dependency-management.md](dependency-management.md)
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# Dependency Management
|
|
2
|
+
|
|
3
|
+
Set up dependency chains, query what's blocked and ready, manage work ordering.
|
|
4
|
+
|
|
5
|
+
## blocks vs depends-on
|
|
6
|
+
|
|
7
|
+
| Edge | Used by `ready` query | Cycle-checked | Use when |
|
|
8
|
+
|------|----------------------|---------------|----------|
|
|
9
|
+
| `blocks` | Yes | Yes | Work genuinely can't start until blocker closes |
|
|
10
|
+
| `depends-on` | No | No | "Nice to have first" but not strictly required |
|
|
11
|
+
|
|
12
|
+
## Setting Up Dependencies
|
|
13
|
+
|
|
14
|
+
### Linear chain: A → B → C → D
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
opentasks link --from t-aaa --to t-bbb --type blocks
|
|
18
|
+
opentasks link --from t-bbb --to t-ccc --type blocks
|
|
19
|
+
opentasks link --from t-ccc --to t-ddd --type blocks
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### Diamond: A blocks B+C, both block D
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
opentasks link --from t-aaa --to t-bbb --type blocks
|
|
26
|
+
opentasks link --from t-aaa --to t-ccc --type blocks
|
|
27
|
+
opentasks link --from t-bbb --to t-ddd --type blocks
|
|
28
|
+
opentasks link --from t-ccc --to t-ddd --type blocks
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
B and C can run in parallel once A closes. D waits for both.
|
|
32
|
+
|
|
33
|
+
### Cycle detection
|
|
34
|
+
|
|
35
|
+
Creating a `blocks` edge that would form a cycle returns an error:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# Given: A blocks B, B blocks C
|
|
39
|
+
opentasks link --from t-ccc --to t-aaa --type blocks
|
|
40
|
+
# → { success: false, error: "Would create circular dependency" }
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Removing dependencies
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
opentasks link --from t-aaa --to t-bbb --type blocks --remove
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Querying
|
|
50
|
+
|
|
51
|
+
### What blocks a node?
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# Direct blockers
|
|
55
|
+
opentasks query '{"blockers": {"nodeId": "t-ddd"}}'
|
|
56
|
+
|
|
57
|
+
# Full chain (transitive)
|
|
58
|
+
opentasks query '{"blockers": {"nodeId": "t-ddd", "transitive": true}}'
|
|
59
|
+
|
|
60
|
+
# Only active (non-closed, non-archived)
|
|
61
|
+
opentasks query '{"blockers": {"nodeId": "t-ddd", "activeOnly": true}}'
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### What does a node block?
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
opentasks query '{"blocking": {"nodeId": "t-aaa", "transitive": true}}'
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### What's ready to work on?
|
|
71
|
+
|
|
72
|
+
Returns open tasks with zero active blockers.
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
# All ready work
|
|
76
|
+
opentasks query '{"ready": {}}'
|
|
77
|
+
|
|
78
|
+
# Filtered
|
|
79
|
+
opentasks query '{"ready": {"tags": ["auth"], "priority": {"min": 0, "max": 2}, "limit": 5}}'
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Agent Work Loop
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
loop:
|
|
86
|
+
1. opentasks query '{"ready": {"limit": 1}}' → pick highest-priority unblocked issue
|
|
87
|
+
2. If empty, stop.
|
|
88
|
+
3. opentasks update t-x7k9 --status in_progress
|
|
89
|
+
4. Do the work.
|
|
90
|
+
5. opentasks update t-x7k9 --status closed
|
|
91
|
+
6. opentasks query '{"blocking": {"nodeId": "t-x7k9"}}' → see what's now unblocked
|
|
92
|
+
7. Repeat.
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Cross-System Dependencies
|
|
96
|
+
|
|
97
|
+
`blocks` edges work across systems. The `ready` query evaluates them uniformly.
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
opentasks link --from "beads://./bd-setup" --to t-x7k9 --type blocks
|
|
101
|
+
opentasks link --from t-x7k9 --to "claude://current/t-abc" --type blocks
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Discovering Work During Implementation
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# Create the discovered task
|
|
108
|
+
opentasks create --type task --title "Token refresh fails for expired sessions" --status open --tags auth,bug --priority 1
|
|
109
|
+
# → t-new1
|
|
110
|
+
|
|
111
|
+
# Link to where it was discovered
|
|
112
|
+
opentasks link --from t-new1 --to t-x7k9 --type discovered-from
|
|
113
|
+
|
|
114
|
+
# If it blocks current work:
|
|
115
|
+
opentasks link --from t-new1 --to t-x7k9 --type blocks
|
|
116
|
+
|
|
117
|
+
# Update original to blocked
|
|
118
|
+
opentasks update t-x7k9 --status blocked
|
|
119
|
+
```
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# Feedback and Review
|
|
2
|
+
|
|
3
|
+
Leave feedback on context and tasks, manage suggestion lifecycles, query unresolved items.
|
|
4
|
+
|
|
5
|
+
## Feedback Types
|
|
6
|
+
|
|
7
|
+
| Type | Use For |
|
|
8
|
+
|------|---------|
|
|
9
|
+
| `comment` | Status updates, implementation notes, observations |
|
|
10
|
+
| `suggestion` | Proposed changes to target content |
|
|
11
|
+
| `request` | Action needed — blocking questions, approvals |
|
|
12
|
+
|
|
13
|
+
## Creating Feedback
|
|
14
|
+
|
|
15
|
+
### Basic comment
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
opentasks annotate '{"targetId":"c-a2b3","create":{"content":"Implemented OAuth. Deferred SAML to follow-up.","type":"comment"}}'
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### Implementation feedback (linked to source issue)
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
opentasks annotate '{"targetId":"c-a2b3","fromId":"t-x7k9","create":{"content":"Google OAuth requires access_type=offline for refresh tokens — added to config.","type":"comment"}}'
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
`fromId` creates a link from the task to the feedback for traceability.
|
|
28
|
+
|
|
29
|
+
### Anchored suggestion
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
opentasks annotate '{"targetId":"c-a2b3","create":{"content":"Rate limiting needed here — OAuth endpoints are brute-force targets.","type":"suggestion","anchor":{"line":15,"text":"OAuth2 endpoints"}}}'
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Anchors use `line` (exact), `text` (fuzzy match), or both. Text anchors survive content edits better.
|
|
36
|
+
|
|
37
|
+
### Blocking request
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
opentasks annotate '{"targetId":"c-a2b3","create":{"content":"Which GitHub OAuth scopes? Spec says user profile but integration may need repo access.","type":"request"}}'
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Querying Feedback
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# All feedback on a node
|
|
47
|
+
opentasks query '{"feedback": {"nodeId": "c-a2b3"}}'
|
|
48
|
+
|
|
49
|
+
# Unresolved suggestions only
|
|
50
|
+
opentasks query '{"feedback": {"nodeId": "c-a2b3", "type": "suggestion", "resolved": false}}'
|
|
51
|
+
|
|
52
|
+
# All unresolved feedback globally
|
|
53
|
+
opentasks query '{"unresolvedFeedback": {}}'
|
|
54
|
+
|
|
55
|
+
# Unresolved feedback for a specific target
|
|
56
|
+
opentasks query '{"unresolvedFeedback": {"targetId": "c-a2b3"}}'
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Lifecycle Management
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
# Resolve (addressed)
|
|
63
|
+
opentasks annotate '{"targetId":"c-a2b3","resolve":"f-t1u2"}'
|
|
64
|
+
|
|
65
|
+
# Dismiss (not applicable)
|
|
66
|
+
opentasks annotate '{"targetId":"c-a2b3","dismiss":"f-t1u2"}'
|
|
67
|
+
|
|
68
|
+
# Reopen
|
|
69
|
+
opentasks annotate '{"targetId":"c-a2b3","reopen":"f-t1u2"}'
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Review Workflow
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
# 1. Read spec
|
|
76
|
+
opentasks get c-a2b3
|
|
77
|
+
|
|
78
|
+
# 2. Check existing feedback
|
|
79
|
+
opentasks query '{"feedback": {"nodeId": "c-a2b3"}}'
|
|
80
|
+
|
|
81
|
+
# 3. Leave feedback
|
|
82
|
+
opentasks annotate '{"targetId":"c-a2b3","create":{"content":"...","type":"comment"}}'
|
|
83
|
+
|
|
84
|
+
# 4. Before implementing — check unresolved
|
|
85
|
+
opentasks query '{"feedback": {"nodeId": "c-a2b3", "resolved": false}}'
|
|
86
|
+
|
|
87
|
+
# 5. After addressing — resolve
|
|
88
|
+
opentasks annotate '{"targetId":"c-a2b3","resolve":"f-abc1"}'
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Cross-System Feedback
|
|
92
|
+
|
|
93
|
+
When source and target are in different systems, OpenTasks stores the feedback (native systems can't handle cross-refs).
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
# Beads issue commenting on Taskmaster spec
|
|
97
|
+
opentasks annotate '{"targetId":"taskmaster://./auth-prd","fromId":"beads://./bd-x7k9","create":{"content":"Sections 1-3 done. Section 4 descoped.","type":"comment"}}'
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Same-system feedback routes to native comments when the provider supports them.
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# Linking External Data
|
|
2
|
+
|
|
3
|
+
Bind non-task artifacts — Slack messages, Google Docs, Notion pages, emails, URLs — to context and tasks in the graph.
|
|
4
|
+
|
|
5
|
+
## Pattern
|
|
6
|
+
|
|
7
|
+
Two steps: create an ExternalNode, then link it.
|
|
8
|
+
|
|
9
|
+
### 1. Create the ExternalNode
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
opentasks create --type external \
|
|
13
|
+
--title "Alex: SSO redirect loop after IdP response" \
|
|
14
|
+
--uri "slack://C04ABCD/p1234567890" \
|
|
15
|
+
--source slack \
|
|
16
|
+
--metadata '{"channel_name":"#engineering","permalink":"https://workspace.slack.com/archives/C04ABCD/p1234567890","author":"alex","text":"auth flow is broken for SSO users — getting redirect loop after IdP response"}'
|
|
17
|
+
# → { id: "e-k7m2", ... }
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### 2. Link to the relevant node
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
opentasks link --from t-x7k9 --to e-k7m2 --type references \
|
|
24
|
+
--metadata '{"context":"Original bug report from #engineering"}'
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## URI Conventions
|
|
28
|
+
|
|
29
|
+
The `uri` field is freeform. Consistent schemes enable deduplication.
|
|
30
|
+
|
|
31
|
+
| Source | Format | Example |
|
|
32
|
+
|--------|--------|---------|
|
|
33
|
+
| Slack message | `slack://[channel]/p[ts]` | `slack://C04ABCD/p1234567890` |
|
|
34
|
+
| Slack thread | `slack://[channel]/t[thread_ts]` | `slack://C04ABCD/t1234567880` |
|
|
35
|
+
| Google Doc | `gdoc://[doc-id]` | `gdoc://1BxiMVs0XRA5nF...` |
|
|
36
|
+
| Notion page | `notion://[page-id]` | `notion://a1b2c3d4-e5f6-...` |
|
|
37
|
+
| Figma file | `figma://[file-key]` | `figma://abc123DEF456` |
|
|
38
|
+
| GitHub PR | `github://[owner]/[repo]/pull/[num]` | `github://org/repo/pull/42` |
|
|
39
|
+
| Generic URL | `web://[url]` | `web://example.com/page` |
|
|
40
|
+
|
|
41
|
+
## Edge Type Selection
|
|
42
|
+
|
|
43
|
+
| Situation | Edge Type |
|
|
44
|
+
|-----------|-----------|
|
|
45
|
+
| Bug report, source document | `references` |
|
|
46
|
+
| Found during investigation | `discovered-from` |
|
|
47
|
+
| Loosely related context | `related` |
|
|
48
|
+
|
|
49
|
+
Direction: typically `issue → external` or `spec → external`.
|
|
50
|
+
|
|
51
|
+
## Deduplication
|
|
52
|
+
|
|
53
|
+
Check before creating:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
opentasks query '{"nodes": {"type": "external", "search": "slack://C04ABCD/p1234567890"}}'
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
If a node with that URI exists, skip creation and link to the existing node.
|
|
60
|
+
|
|
61
|
+
## Phantom Nodes (URL only)
|
|
62
|
+
|
|
63
|
+
If the agent only has a URL and can't fetch content:
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
opentasks create --type external \
|
|
67
|
+
--title "Related Slack thread" \
|
|
68
|
+
--uri "slack://C04ABCD/t1234567880" \
|
|
69
|
+
--source slack \
|
|
70
|
+
--metadata '{"permalink":"https://workspace.slack.com/archives/C04ABCD/p1234567880"}'
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
An agent with access to the external system can later enrich via `opentasks update`.
|
|
74
|
+
|
|
75
|
+
## Querying Linked Data
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# All references from a task
|
|
79
|
+
opentasks query '{"edges": {"from_id": "t-x7k9", "type": "references"}}'
|
|
80
|
+
|
|
81
|
+
# All external nodes from Slack
|
|
82
|
+
opentasks query '{"nodes": {"type": "external", "search": "slack"}}'
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Complete Example
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
Agent working on "Fix SSO redirect loop":
|
|
89
|
+
|
|
90
|
+
1. Search Slack via MCP → find 3 relevant messages
|
|
91
|
+
|
|
92
|
+
2. For each, create ExternalNode:
|
|
93
|
+
opentasks create --type external --title "..." --uri "slack://..." --source slack --metadata '{...}'
|
|
94
|
+
|
|
95
|
+
3. Link each to the task:
|
|
96
|
+
opentasks link --from t-x7k9 --to e-k7m2 --type references
|
|
97
|
+
opentasks link --from t-x7k9 --to e-k7m3 --type references
|
|
98
|
+
opentasks link --from t-x7k9 --to e-k7m4 --type discovered-from
|
|
99
|
+
|
|
100
|
+
4. Later, another agent queries context:
|
|
101
|
+
opentasks query '{"edges": {"from_id": "t-x7k9", "type": ["references", "discovered-from"]}}'
|
|
102
|
+
→ Gets back ExternalNodes with Slack content in metadata
|
|
103
|
+
```
|