@kynetic-ai/spec 0.1.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.
Files changed (278) hide show
  1. package/README.md +263 -0
  2. package/dist/acp/client.d.ts +159 -0
  3. package/dist/acp/client.d.ts.map +1 -0
  4. package/dist/acp/client.js +255 -0
  5. package/dist/acp/client.js.map +1 -0
  6. package/dist/acp/framing.d.ts +119 -0
  7. package/dist/acp/framing.d.ts.map +1 -0
  8. package/dist/acp/framing.js +302 -0
  9. package/dist/acp/framing.js.map +1 -0
  10. package/dist/acp/index.d.ts +14 -0
  11. package/dist/acp/index.d.ts.map +1 -0
  12. package/dist/acp/index.js +13 -0
  13. package/dist/acp/index.js.map +1 -0
  14. package/dist/acp/types.d.ts +89 -0
  15. package/dist/acp/types.d.ts.map +1 -0
  16. package/dist/acp/types.js +99 -0
  17. package/dist/acp/types.js.map +1 -0
  18. package/dist/agents/adapters.d.ts +55 -0
  19. package/dist/agents/adapters.d.ts.map +1 -0
  20. package/dist/agents/adapters.js +84 -0
  21. package/dist/agents/adapters.js.map +1 -0
  22. package/dist/agents/index.d.ts +8 -0
  23. package/dist/agents/index.d.ts.map +1 -0
  24. package/dist/agents/index.js +10 -0
  25. package/dist/agents/index.js.map +1 -0
  26. package/dist/agents/spawner.d.ts +53 -0
  27. package/dist/agents/spawner.d.ts.map +1 -0
  28. package/dist/agents/spawner.js +83 -0
  29. package/dist/agents/spawner.js.map +1 -0
  30. package/dist/cli/batch.d.ts +82 -0
  31. package/dist/cli/batch.d.ts.map +1 -0
  32. package/dist/cli/batch.js +162 -0
  33. package/dist/cli/batch.js.map +1 -0
  34. package/dist/cli/commands/clone-for-testing.d.ts +6 -0
  35. package/dist/cli/commands/clone-for-testing.d.ts.map +1 -0
  36. package/dist/cli/commands/clone-for-testing.js +176 -0
  37. package/dist/cli/commands/clone-for-testing.js.map +1 -0
  38. package/dist/cli/commands/derive.d.ts +6 -0
  39. package/dist/cli/commands/derive.d.ts.map +1 -0
  40. package/dist/cli/commands/derive.js +450 -0
  41. package/dist/cli/commands/derive.js.map +1 -0
  42. package/dist/cli/commands/help.d.ts +6 -0
  43. package/dist/cli/commands/help.d.ts.map +1 -0
  44. package/dist/cli/commands/help.js +196 -0
  45. package/dist/cli/commands/help.js.map +1 -0
  46. package/dist/cli/commands/inbox.d.ts +6 -0
  47. package/dist/cli/commands/inbox.d.ts.map +1 -0
  48. package/dist/cli/commands/inbox.js +235 -0
  49. package/dist/cli/commands/inbox.js.map +1 -0
  50. package/dist/cli/commands/index.d.ts +20 -0
  51. package/dist/cli/commands/index.d.ts.map +1 -0
  52. package/dist/cli/commands/index.js +21 -0
  53. package/dist/cli/commands/index.js.map +1 -0
  54. package/dist/cli/commands/init.d.ts +6 -0
  55. package/dist/cli/commands/init.d.ts.map +1 -0
  56. package/dist/cli/commands/init.js +245 -0
  57. package/dist/cli/commands/init.js.map +1 -0
  58. package/dist/cli/commands/item.d.ts +6 -0
  59. package/dist/cli/commands/item.d.ts.map +1 -0
  60. package/dist/cli/commands/item.js +1311 -0
  61. package/dist/cli/commands/item.js.map +1 -0
  62. package/dist/cli/commands/link.d.ts +6 -0
  63. package/dist/cli/commands/link.d.ts.map +1 -0
  64. package/dist/cli/commands/link.js +288 -0
  65. package/dist/cli/commands/link.js.map +1 -0
  66. package/dist/cli/commands/log.d.ts +16 -0
  67. package/dist/cli/commands/log.d.ts.map +1 -0
  68. package/dist/cli/commands/log.js +291 -0
  69. package/dist/cli/commands/log.js.map +1 -0
  70. package/dist/cli/commands/meta.d.ts +15 -0
  71. package/dist/cli/commands/meta.d.ts.map +1 -0
  72. package/dist/cli/commands/meta.js +1378 -0
  73. package/dist/cli/commands/meta.js.map +1 -0
  74. package/dist/cli/commands/module.d.ts +6 -0
  75. package/dist/cli/commands/module.d.ts.map +1 -0
  76. package/dist/cli/commands/module.js +102 -0
  77. package/dist/cli/commands/module.js.map +1 -0
  78. package/dist/cli/commands/ralph.d.ts +9 -0
  79. package/dist/cli/commands/ralph.d.ts.map +1 -0
  80. package/dist/cli/commands/ralph.js +465 -0
  81. package/dist/cli/commands/ralph.js.map +1 -0
  82. package/dist/cli/commands/search.d.ts +6 -0
  83. package/dist/cli/commands/search.d.ts.map +1 -0
  84. package/dist/cli/commands/search.js +134 -0
  85. package/dist/cli/commands/search.js.map +1 -0
  86. package/dist/cli/commands/session.d.ts +164 -0
  87. package/dist/cli/commands/session.d.ts.map +1 -0
  88. package/dist/cli/commands/session.js +745 -0
  89. package/dist/cli/commands/session.js.map +1 -0
  90. package/dist/cli/commands/setup.d.ts +26 -0
  91. package/dist/cli/commands/setup.d.ts.map +1 -0
  92. package/dist/cli/commands/setup.js +586 -0
  93. package/dist/cli/commands/setup.js.map +1 -0
  94. package/dist/cli/commands/shadow.d.ts +6 -0
  95. package/dist/cli/commands/shadow.d.ts.map +1 -0
  96. package/dist/cli/commands/shadow.js +299 -0
  97. package/dist/cli/commands/shadow.js.map +1 -0
  98. package/dist/cli/commands/task.d.ts +6 -0
  99. package/dist/cli/commands/task.d.ts.map +1 -0
  100. package/dist/cli/commands/task.js +1514 -0
  101. package/dist/cli/commands/task.js.map +1 -0
  102. package/dist/cli/commands/tasks.d.ts +6 -0
  103. package/dist/cli/commands/tasks.d.ts.map +1 -0
  104. package/dist/cli/commands/tasks.js +347 -0
  105. package/dist/cli/commands/tasks.js.map +1 -0
  106. package/dist/cli/commands/trait.d.ts +10 -0
  107. package/dist/cli/commands/trait.d.ts.map +1 -0
  108. package/dist/cli/commands/trait.js +295 -0
  109. package/dist/cli/commands/trait.js.map +1 -0
  110. package/dist/cli/commands/validate.d.ts +6 -0
  111. package/dist/cli/commands/validate.d.ts.map +1 -0
  112. package/dist/cli/commands/validate.js +626 -0
  113. package/dist/cli/commands/validate.js.map +1 -0
  114. package/dist/cli/exit-codes.d.ts +62 -0
  115. package/dist/cli/exit-codes.d.ts.map +1 -0
  116. package/dist/cli/exit-codes.js +65 -0
  117. package/dist/cli/exit-codes.js.map +1 -0
  118. package/dist/cli/help/content.d.ts +35 -0
  119. package/dist/cli/help/content.d.ts.map +1 -0
  120. package/dist/cli/help/content.js +312 -0
  121. package/dist/cli/help/content.js.map +1 -0
  122. package/dist/cli/index.d.ts +5 -0
  123. package/dist/cli/index.d.ts.map +1 -0
  124. package/dist/cli/index.js +85 -0
  125. package/dist/cli/index.js.map +1 -0
  126. package/dist/cli/introspection.d.ts +87 -0
  127. package/dist/cli/introspection.d.ts.map +1 -0
  128. package/dist/cli/introspection.js +127 -0
  129. package/dist/cli/introspection.js.map +1 -0
  130. package/dist/cli/output.d.ts +56 -0
  131. package/dist/cli/output.d.ts.map +1 -0
  132. package/dist/cli/output.js +467 -0
  133. package/dist/cli/output.js.map +1 -0
  134. package/dist/cli/suggest.d.ts +16 -0
  135. package/dist/cli/suggest.d.ts.map +1 -0
  136. package/dist/cli/suggest.js +72 -0
  137. package/dist/cli/suggest.js.map +1 -0
  138. package/dist/index.d.ts +3 -0
  139. package/dist/index.d.ts.map +1 -0
  140. package/dist/index.js +5 -0
  141. package/dist/index.js.map +1 -0
  142. package/dist/parser/alignment.d.ts +113 -0
  143. package/dist/parser/alignment.d.ts.map +1 -0
  144. package/dist/parser/alignment.js +261 -0
  145. package/dist/parser/alignment.js.map +1 -0
  146. package/dist/parser/assess.d.ts +81 -0
  147. package/dist/parser/assess.d.ts.map +1 -0
  148. package/dist/parser/assess.js +197 -0
  149. package/dist/parser/assess.js.map +1 -0
  150. package/dist/parser/convention-validation.d.ts +48 -0
  151. package/dist/parser/convention-validation.d.ts.map +1 -0
  152. package/dist/parser/convention-validation.js +167 -0
  153. package/dist/parser/convention-validation.js.map +1 -0
  154. package/dist/parser/fix.d.ts +38 -0
  155. package/dist/parser/fix.d.ts.map +1 -0
  156. package/dist/parser/fix.js +185 -0
  157. package/dist/parser/fix.js.map +1 -0
  158. package/dist/parser/index.d.ts +12 -0
  159. package/dist/parser/index.d.ts.map +1 -0
  160. package/dist/parser/index.js +13 -0
  161. package/dist/parser/index.js.map +1 -0
  162. package/dist/parser/items.d.ts +138 -0
  163. package/dist/parser/items.d.ts.map +1 -0
  164. package/dist/parser/items.js +321 -0
  165. package/dist/parser/items.js.map +1 -0
  166. package/dist/parser/meta.d.ts +120 -0
  167. package/dist/parser/meta.d.ts.map +1 -0
  168. package/dist/parser/meta.js +441 -0
  169. package/dist/parser/meta.js.map +1 -0
  170. package/dist/parser/refs.d.ts +185 -0
  171. package/dist/parser/refs.d.ts.map +1 -0
  172. package/dist/parser/refs.js +404 -0
  173. package/dist/parser/refs.js.map +1 -0
  174. package/dist/parser/shadow.d.ts +253 -0
  175. package/dist/parser/shadow.d.ts.map +1 -0
  176. package/dist/parser/shadow.js +1053 -0
  177. package/dist/parser/shadow.js.map +1 -0
  178. package/dist/parser/traits.d.ts +72 -0
  179. package/dist/parser/traits.d.ts.map +1 -0
  180. package/dist/parser/traits.js +120 -0
  181. package/dist/parser/traits.js.map +1 -0
  182. package/dist/parser/validate.d.ts +89 -0
  183. package/dist/parser/validate.d.ts.map +1 -0
  184. package/dist/parser/validate.js +817 -0
  185. package/dist/parser/validate.js.map +1 -0
  186. package/dist/parser/yaml.d.ts +326 -0
  187. package/dist/parser/yaml.d.ts.map +1 -0
  188. package/dist/parser/yaml.js +1383 -0
  189. package/dist/parser/yaml.js.map +1 -0
  190. package/dist/ralph/cli-renderer.d.ts +20 -0
  191. package/dist/ralph/cli-renderer.d.ts.map +1 -0
  192. package/dist/ralph/cli-renderer.js +179 -0
  193. package/dist/ralph/cli-renderer.js.map +1 -0
  194. package/dist/ralph/events.d.ts +65 -0
  195. package/dist/ralph/events.d.ts.map +1 -0
  196. package/dist/ralph/events.js +397 -0
  197. package/dist/ralph/events.js.map +1 -0
  198. package/dist/ralph/index.d.ts +8 -0
  199. package/dist/ralph/index.d.ts.map +1 -0
  200. package/dist/ralph/index.js +10 -0
  201. package/dist/ralph/index.js.map +1 -0
  202. package/dist/schema/common.d.ts +46 -0
  203. package/dist/schema/common.d.ts.map +1 -0
  204. package/dist/schema/common.js +71 -0
  205. package/dist/schema/common.js.map +1 -0
  206. package/dist/schema/inbox.d.ts +90 -0
  207. package/dist/schema/inbox.d.ts.map +1 -0
  208. package/dist/schema/inbox.js +30 -0
  209. package/dist/schema/inbox.js.map +1 -0
  210. package/dist/schema/index.d.ts +6 -0
  211. package/dist/schema/index.d.ts.map +1 -0
  212. package/dist/schema/index.js +7 -0
  213. package/dist/schema/index.js.map +1 -0
  214. package/dist/schema/meta.d.ts +762 -0
  215. package/dist/schema/meta.d.ts.map +1 -0
  216. package/dist/schema/meta.js +144 -0
  217. package/dist/schema/meta.js.map +1 -0
  218. package/dist/schema/spec.d.ts +912 -0
  219. package/dist/schema/spec.d.ts.map +1 -0
  220. package/dist/schema/spec.js +104 -0
  221. package/dist/schema/spec.js.map +1 -0
  222. package/dist/schema/task.d.ts +664 -0
  223. package/dist/schema/task.d.ts.map +1 -0
  224. package/dist/schema/task.js +130 -0
  225. package/dist/schema/task.js.map +1 -0
  226. package/dist/sessions/index.d.ts +11 -0
  227. package/dist/sessions/index.d.ts.map +1 -0
  228. package/dist/sessions/index.js +13 -0
  229. package/dist/sessions/index.js.map +1 -0
  230. package/dist/sessions/store.d.ts +144 -0
  231. package/dist/sessions/store.d.ts.map +1 -0
  232. package/dist/sessions/store.js +325 -0
  233. package/dist/sessions/store.js.map +1 -0
  234. package/dist/sessions/types.d.ts +157 -0
  235. package/dist/sessions/types.d.ts.map +1 -0
  236. package/dist/sessions/types.js +90 -0
  237. package/dist/sessions/types.js.map +1 -0
  238. package/dist/strings/errors.d.ts +420 -0
  239. package/dist/strings/errors.d.ts.map +1 -0
  240. package/dist/strings/errors.js +282 -0
  241. package/dist/strings/errors.js.map +1 -0
  242. package/dist/strings/guidance.d.ts +65 -0
  243. package/dist/strings/guidance.d.ts.map +1 -0
  244. package/dist/strings/guidance.js +66 -0
  245. package/dist/strings/guidance.js.map +1 -0
  246. package/dist/strings/index.d.ts +12 -0
  247. package/dist/strings/index.d.ts.map +1 -0
  248. package/dist/strings/index.js +12 -0
  249. package/dist/strings/index.js.map +1 -0
  250. package/dist/strings/labels.d.ts +74 -0
  251. package/dist/strings/labels.d.ts.map +1 -0
  252. package/dist/strings/labels.js +75 -0
  253. package/dist/strings/labels.js.map +1 -0
  254. package/dist/strings/validation.d.ts +126 -0
  255. package/dist/strings/validation.d.ts.map +1 -0
  256. package/dist/strings/validation.js +135 -0
  257. package/dist/strings/validation.js.map +1 -0
  258. package/dist/utils/commit.d.ts +23 -0
  259. package/dist/utils/commit.d.ts.map +1 -0
  260. package/dist/utils/commit.js +67 -0
  261. package/dist/utils/commit.js.map +1 -0
  262. package/dist/utils/git.d.ts +57 -0
  263. package/dist/utils/git.d.ts.map +1 -0
  264. package/dist/utils/git.js +192 -0
  265. package/dist/utils/git.js.map +1 -0
  266. package/dist/utils/grep.d.ts +28 -0
  267. package/dist/utils/grep.d.ts.map +1 -0
  268. package/dist/utils/grep.js +86 -0
  269. package/dist/utils/grep.js.map +1 -0
  270. package/dist/utils/index.d.ts +8 -0
  271. package/dist/utils/index.d.ts.map +1 -0
  272. package/dist/utils/index.js +6 -0
  273. package/dist/utils/index.js.map +1 -0
  274. package/dist/utils/time.d.ts +18 -0
  275. package/dist/utils/time.d.ts.map +1 -0
  276. package/dist/utils/time.js +61 -0
  277. package/dist/utils/time.js.map +1 -0
  278. package/package.json +62 -0
package/README.md ADDED
@@ -0,0 +1,263 @@
1
+ # Kynetic Spec (kspec)
2
+
3
+ > **Warning: Experimental Software**
4
+ >
5
+ > This project is a work-in-progress and is not ready for production use. APIs, file formats, and CLI commands may change without notice. Use at your own risk.
6
+ >
7
+ > If you're interested in the project, feel free to explore the code and design docs, but please don't depend on it for real work yet.
8
+
9
+ A structured specification and task management system designed for AI-assisted development. kspec provides a YAML-based format for defining project specifications that can be programmatically manipulated, with a task system to track implementation progress.
10
+
11
+ **Key feature**: kspec is self-hosting - it tracks its own development using itself.
12
+
13
+ ## Installation
14
+
15
+ ### Quick Start (Development)
16
+
17
+ ```bash
18
+ # Clone and install
19
+ git clone <repo-url>
20
+ cd kynetic-spec
21
+ npm install
22
+
23
+ # Run with npm (recommended - works from any project directory)
24
+ npm run dev -- <command>
25
+ ```
26
+
27
+ ### Build and Link Globally
28
+
29
+ ```bash
30
+ npm run build
31
+ npm link
32
+
33
+ # Now available as 'kspec' globally
34
+ kspec tasks ready
35
+ ```
36
+
37
+ ## Basic Usage
38
+
39
+ ```bash
40
+ # See what tasks are ready to work on
41
+ kspec tasks ready
42
+
43
+ # Get task details
44
+ kspec task get @task-slug
45
+
46
+ # Task lifecycle
47
+ kspec task start @task-slug
48
+ kspec task note @task-slug "What you're doing..."
49
+ kspec task complete @task-slug --reason "Summary"
50
+
51
+ # Create a new task
52
+ kspec task add --title "My task" --priority 2 --slug my-task
53
+ ```
54
+
55
+ ## Agent Integration
56
+
57
+ kspec is agent-agnostic but designed to work well with AI coding assistants. The key integration point is **author attribution** for notes.
58
+
59
+ ### Quick Setup
60
+
61
+ Run the setup command to auto-configure your agent environment:
62
+
63
+ ```bash
64
+ kspec setup # Auto-detect and configure
65
+ kspec setup --dry-run # Preview what would be done
66
+ ```
67
+
68
+ The setup command detects which agent you're running in and installs the appropriate configuration.
69
+
70
+ **Supported agents:**
71
+ - Claude Code (`CLAUDE_PROJECT_DIR`)
72
+ - Cline (`CLINE_ACTIVE`)
73
+ - Gemini CLI (`GEMINI_CLI`)
74
+ - Codex CLI (`CODEX_SANDBOX`)
75
+ - Aider (`AIDER_MODEL`)
76
+ - OpenCode (`OPENCODE_CONFIG_DIR`)
77
+ - Amp (`AMP_API_KEY`)
78
+ - GitHub Copilot CLI
79
+
80
+ ### How Author Detection Works
81
+
82
+ When adding notes, kspec auto-detects the author using this fallback chain:
83
+
84
+ 1. `KSPEC_AUTHOR` environment variable (explicit config)
85
+ 2. `git config user.name` (developer identity)
86
+ 3. `USER`/`USERNAME` env var (system user)
87
+
88
+ ### Manual Setup
89
+
90
+ If auto-setup doesn't work, configure manually:
91
+
92
+ **Claude Code** - Add to `~/.claude/settings.json`:
93
+ ```json
94
+ {
95
+ "env": {
96
+ "KSPEC_AUTHOR": "@claude"
97
+ }
98
+ }
99
+ ```
100
+
101
+ **Aider** - Add to `~/.aider.conf.yml`:
102
+ ```yaml
103
+ env:
104
+ KSPEC_AUTHOR: "@aider"
105
+ ```
106
+
107
+ **Other agents** - Set in shell profile:
108
+ ```bash
109
+ export KSPEC_AUTHOR="@agent-name"
110
+ ```
111
+
112
+ Convention: Use `@` prefix for agent authors (e.g., `@claude`, `@copilot`) to distinguish from human authors.
113
+
114
+ ## Task Management
115
+
116
+ ### Task States
117
+
118
+ ```
119
+ pending → in_progress → completed
120
+
121
+ blocked → (unblock) → in_progress
122
+
123
+ cancelled
124
+ ```
125
+
126
+ ### Commands
127
+
128
+ ```bash
129
+ # List tasks
130
+ kspec tasks list # All tasks
131
+ kspec tasks list --status pending # Filter by status
132
+ kspec tasks ready # Tasks ready to work on
133
+ kspec tasks next # Highest priority ready task
134
+ kspec tasks blocked # Blocked tasks
135
+ kspec tasks in-progress # Active tasks
136
+
137
+ # Task operations
138
+ kspec task get <ref> # View details
139
+ kspec task start <ref> # Begin work
140
+ kspec task complete <ref> # Mark done
141
+ kspec task block <ref> --reason "..." # Block with reason
142
+ kspec task unblock <ref> # Remove block
143
+ kspec task cancel <ref> # Cancel task
144
+
145
+ # Notes (work log)
146
+ kspec task note <ref> "message" # Add note
147
+ kspec task notes <ref> # View notes
148
+ ```
149
+
150
+ ### References
151
+
152
+ Tasks can be referenced by:
153
+ - **Full ULID**: `01KEYQSD2QJCNGRKSR38V0E3BM`
154
+ - **Short ULID**: `01KEYQSD` (unique prefix)
155
+ - **Slug**: `@my-task-slug`
156
+
157
+ ## Task File Format
158
+
159
+ Tasks are stored in YAML files (`*.tasks.yaml`):
160
+
161
+ ```yaml
162
+ - _ulid: 01KEYQSD2QJCNGRKSR38V0E3BM
163
+ slugs: [my-task]
164
+ title: My task title
165
+ type: task # task, epic, bug, spike, infra
166
+ status: pending
167
+ priority: 2 # 1 (highest) to 5 (lowest)
168
+ depends_on: ["@other-task"]
169
+ tags: [mvp]
170
+ notes:
171
+ - _ulid: 01KEYRJ953HRYWJ0W4XEG6J9FB
172
+ created_at: "2026-01-14T17:00:00Z"
173
+ author: "@claude"
174
+ content: |
175
+ Started implementing feature X...
176
+ ```
177
+
178
+ ## JSON Output
179
+
180
+ Add `--json` flag for machine-readable output:
181
+
182
+ ```bash
183
+ kspec --json tasks ready
184
+ kspec --json task get @my-task
185
+ ```
186
+
187
+ ## Project Structure
188
+
189
+ ```
190
+ kynetic-spec/
191
+ ├── .kspec/ # kspec's own spec (shadow branch worktree)
192
+ │ ├── kynetic.yaml # Root manifest
193
+ │ ├── project.tasks.yaml # Active tasks
194
+ │ ├── project.inbox.yaml # Inbox items
195
+ │ └── modules/ # Spec items by domain
196
+ ├── src/ # TypeScript implementation
197
+ │ ├── schema/ # Zod schemas
198
+ │ ├── parser/ # YAML loading
199
+ │ └── cli/ # Command handlers
200
+ └── tests/ # Vitest tests
201
+ ```
202
+
203
+ ## Development
204
+
205
+ ```bash
206
+ # Run tests
207
+ npm test
208
+ npm run test:watch
209
+
210
+ # Type check
211
+ npm run build
212
+
213
+ # Run CLI in dev mode
214
+ npm run dev -- tasks ready
215
+ ```
216
+
217
+ ### Troubleshooting: ESM + npm link
218
+
219
+ When using `npm link` to develop kspec globally, ESM module detection can break without proper symlink resolution. This manifests as the CLI executing twice or commands not working correctly.
220
+
221
+ **Symptoms:**
222
+ - Commands execute twice
223
+ - CLI seems to hang or behave unexpectedly
224
+ - "Cannot find module" errors when using `npm link`
225
+
226
+ **Why it happens:**
227
+ - `npm link` creates symlinks for global CLI binaries
228
+ - Node.js ESM uses `import.meta.url` to detect if a module is the main entry point
229
+ - Without symlink resolution, `import.meta.url` doesn't match the symlinked path
230
+ - This causes the module to be imported but not executed, or executed multiple times
231
+
232
+ **The fix:**
233
+ kspec uses `fs.realpathSync()` to resolve symlinks before comparing paths:
234
+
235
+ ```javascript
236
+ // src/cli/index.ts
237
+ const scriptPath = realpathSync(process.argv[1]);
238
+ if (import.meta.url === `file://${scriptPath}`) {
239
+ program.parse();
240
+ }
241
+ ```
242
+
243
+ This ensures the CLI works correctly whether run via:
244
+ - `npm run dev` (direct TypeScript execution)
245
+ - `npm link` (symlinked global binary)
246
+ - `node dist/cli/index.js` (built code)
247
+
248
+ **For contributors:** If you encounter similar issues in ESM CLIs, remember to resolve symlinks before path comparisons. The pattern is:
249
+ 1. Import `realpathSync` from `fs`
250
+ 2. Resolve `process.argv[1]` before comparing with `import.meta.url`
251
+ 3. This makes the CLI work correctly in all installation modes
252
+
253
+ ## Design Decisions
254
+
255
+ - **Library-first**: Core parsing logic is separate from CLI for reuse
256
+ - **Zod schemas**: TypeScript-native validation
257
+ - **YAML format**: Human-readable, git-friendly, supports comments
258
+ - **ULID identifiers**: Time-sortable, globally unique, shortenable
259
+ - **Slug aliases**: Human-friendly names that map to ULIDs
260
+
261
+ ## License
262
+
263
+ MIT
@@ -0,0 +1,159 @@
1
+ /**
2
+ * ACP (Agent Communication Protocol) Client
3
+ *
4
+ * Manages agent lifecycle and communication over JSON-RPC 2.0 stdio.
5
+ * This is a simplified client focused on core operations:
6
+ * - Initialize agent connection
7
+ * - Create sessions
8
+ * - Send prompts and receive responses
9
+ * - Handle streaming updates
10
+ * - Cancel operations (optional)
11
+ */
12
+ import { EventEmitter } from 'node:events';
13
+ import type { JsonRpcFramingOptions } from './framing.js';
14
+ import type { AgentCapabilities, ClientCapabilities, NewSessionRequest, PromptRequest, PromptResponse, RequestPermissionResponse, SessionUpdate } from './types.js';
15
+ /**
16
+ * Session state tracked by the client
17
+ */
18
+ export interface SessionState {
19
+ id: string;
20
+ status: 'idle' | 'prompting' | 'cancelled';
21
+ }
22
+ /**
23
+ * Options for ACPClient
24
+ */
25
+ export interface ACPClientOptions extends JsonRpcFramingOptions {
26
+ /** Client capabilities to advertise */
27
+ capabilities?: ClientCapabilities;
28
+ /** Client info */
29
+ clientInfo?: {
30
+ name: string;
31
+ version?: string;
32
+ };
33
+ }
34
+ export interface ACPClientEvents {
35
+ update: (sessionId: string, update: SessionUpdate) => void;
36
+ request: (id: string | number, method: string, params: unknown) => void;
37
+ close: () => void;
38
+ error: (error: Error) => void;
39
+ }
40
+ /**
41
+ * ACP Client
42
+ *
43
+ * Manages agent communication over JSON-RPC 2.0 stdio transport.
44
+ * Handles initialization, session lifecycle, prompts, and streaming updates.
45
+ *
46
+ * Events:
47
+ * - 'update': Emitted when session updates arrive (sessionId, update)
48
+ * - 'close': Emitted when the connection is closed
49
+ * - 'error': Emitted on errors
50
+ */
51
+ export declare class ACPClient extends EventEmitter {
52
+ private framing;
53
+ private sessions;
54
+ private agentCapabilities;
55
+ private clientCapabilities;
56
+ private clientInfo?;
57
+ private initialized;
58
+ constructor(options?: ACPClientOptions);
59
+ /**
60
+ * Initialize the agent connection
61
+ *
62
+ * @returns Agent capabilities including supported features
63
+ * @throws If already initialized or connection fails
64
+ */
65
+ initialize(): Promise<AgentCapabilities>;
66
+ /**
67
+ * Create a new session
68
+ *
69
+ * @param params Session parameters including cwd and optional metadata
70
+ * @returns Session ID
71
+ * @throws If not initialized or session creation fails
72
+ */
73
+ newSession(params: NewSessionRequest): Promise<string>;
74
+ /**
75
+ * Send a prompt to the agent
76
+ *
77
+ * @param params Prompt request parameters including sessionId and prompt content
78
+ * @returns Prompt response with stopReason
79
+ * @throws If not initialized, session not found, or already prompting
80
+ */
81
+ prompt(params: PromptRequest): Promise<PromptResponse>;
82
+ /**
83
+ * Cancel an ongoing prompt
84
+ *
85
+ * Note: session/cancel is an optional ACP method. If the agent doesn't
86
+ * support it (returns "Method not found"), we silently ignore the error.
87
+ * The caller should fall back to process termination (SIGTERM) if needed.
88
+ *
89
+ * @param sessionId The session to cancel
90
+ * @throws If not initialized or session not found
91
+ */
92
+ cancel(sessionId: string): Promise<void>;
93
+ /**
94
+ * Get session state
95
+ *
96
+ * @param sessionId The session to get
97
+ * @returns Session state or undefined if not found
98
+ */
99
+ getSession(sessionId: string): SessionState | undefined;
100
+ /**
101
+ * Get all sessions
102
+ *
103
+ * @returns Array of all session states
104
+ */
105
+ getAllSessions(): SessionState[];
106
+ /**
107
+ * Get agent capabilities (available after initialize)
108
+ *
109
+ * @returns Agent capabilities
110
+ */
111
+ getCapabilities(): AgentCapabilities;
112
+ /**
113
+ * Check if client is initialized
114
+ *
115
+ * @returns true if initialize() has been called successfully
116
+ */
117
+ isInitialized(): boolean;
118
+ /**
119
+ * Check if the client connection is closed
120
+ *
121
+ * @returns true if the connection is closed
122
+ */
123
+ isClosed(): boolean;
124
+ /**
125
+ * Send a response to an agent request (tool call)
126
+ *
127
+ * Prefer typed response methods (respondPermission, etc.) when available.
128
+ *
129
+ * @param id - The request ID to respond to
130
+ * @param result - The result to send back
131
+ */
132
+ respond(id: string | number, result: unknown): void;
133
+ /**
134
+ * Send a typed response to a permission request
135
+ *
136
+ * @param id - The request ID to respond to
137
+ * @param response - The permission response
138
+ */
139
+ respondPermission(id: string | number, response: RequestPermissionResponse): void;
140
+ /**
141
+ * Send an error response to an agent request
142
+ *
143
+ * @param id - The request ID to respond to
144
+ * @param code - Error code
145
+ * @param message - Error message
146
+ */
147
+ respondError(id: string | number, code: number, message: string): void;
148
+ /**
149
+ * Close the client connection
150
+ *
151
+ * Rejects any pending requests and cleans up resources.
152
+ */
153
+ close(): void;
154
+ /**
155
+ * Handle incoming notifications from the agent
156
+ */
157
+ private handleNotification;
158
+ }
159
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/acp/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAG1D,OAAO,KAAK,EACV,iBAAiB,EACjB,kBAAkB,EAKlB,iBAAiB,EAEjB,aAAa,EACb,cAAc,EACd,yBAAyB,EAEzB,aAAa,EACd,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,WAAW,CAAC;CAC5C;AAED;;GAEG;AACH,MAAM,WAAW,gBAAiB,SAAQ,qBAAqB;IAC7D,uCAAuC;IACvC,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAClC,kBAAkB;IAClB,UAAU,CAAC,EAAE;QACX,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAGD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,KAAK,IAAI,CAAC;IAC3D,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACxE,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,KAAK,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAC/B;AAED;;;;;;;;;;GAUG;AACH,qBAAa,SAAU,SAAQ,YAAY;IACzC,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,QAAQ,CAAmC;IACnD,OAAO,CAAC,iBAAiB,CAAyB;IAClD,OAAO,CAAC,kBAAkB,CAAqB;IAC/C,OAAO,CAAC,UAAU,CAAC,CAAqC;IACxD,OAAO,CAAC,WAAW,CAAS;gBAEhB,OAAO,GAAE,gBAAqB;IAyB1C;;;;;OAKG;IACG,UAAU,IAAI,OAAO,CAAC,iBAAiB,CAAC;IA2B9C;;;;;;OAMG;IACG,UAAU,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC;IAmB5D;;;;;;OAMG;IACG,MAAM,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;IAsC5D;;;;;;;;;OASG;IACG,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA+B9C;;;;;OAKG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS;IAIvD;;;;OAIG;IACH,cAAc,IAAI,YAAY,EAAE;IAIhC;;;;OAIG;IACH,eAAe,IAAI,iBAAiB;IAIpC;;;;OAIG;IACH,aAAa,IAAI,OAAO;IAIxB;;;;OAIG;IACH,QAAQ,IAAI,OAAO;IAInB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,MAAM,EAAE,OAAO,GAAG,IAAI;IAInD;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,yBAAyB,GAAG,IAAI;IAIjF;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAItE;;;;OAIG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,OAAO,CAAC,kBAAkB;CAU3B"}
@@ -0,0 +1,255 @@
1
+ /**
2
+ * ACP (Agent Communication Protocol) Client
3
+ *
4
+ * Manages agent lifecycle and communication over JSON-RPC 2.0 stdio.
5
+ * This is a simplified client focused on core operations:
6
+ * - Initialize agent connection
7
+ * - Create sessions
8
+ * - Send prompts and receive responses
9
+ * - Handle streaming updates
10
+ * - Cancel operations (optional)
11
+ */
12
+ import { EventEmitter } from 'node:events';
13
+ import { JsonRpcFraming } from './framing.js';
14
+ /**
15
+ * ACP Client
16
+ *
17
+ * Manages agent communication over JSON-RPC 2.0 stdio transport.
18
+ * Handles initialization, session lifecycle, prompts, and streaming updates.
19
+ *
20
+ * Events:
21
+ * - 'update': Emitted when session updates arrive (sessionId, update)
22
+ * - 'close': Emitted when the connection is closed
23
+ * - 'error': Emitted on errors
24
+ */
25
+ export class ACPClient extends EventEmitter {
26
+ framing;
27
+ sessions = new Map();
28
+ agentCapabilities = {};
29
+ clientCapabilities;
30
+ clientInfo;
31
+ initialized = false;
32
+ constructor(options = {}) {
33
+ super();
34
+ // Default capabilities - we don't handle file/terminal in this simplified client
35
+ this.clientCapabilities = options.capabilities ?? {};
36
+ this.clientInfo = options.clientInfo;
37
+ // Create framing layer
38
+ this.framing = new JsonRpcFraming(options);
39
+ // Wire up notification handler for session updates
40
+ this.framing.on('notification', (notification) => {
41
+ this.handleNotification(notification);
42
+ });
43
+ // Forward request events for tool calls
44
+ this.framing.on('request', (request) => {
45
+ this.emit('request', request.id, request.method, request.params);
46
+ });
47
+ // Forward framing events
48
+ this.framing.on('close', () => this.emit('close'));
49
+ this.framing.on('error', (err) => this.emit('error', err));
50
+ }
51
+ /**
52
+ * Initialize the agent connection
53
+ *
54
+ * @returns Agent capabilities including supported features
55
+ * @throws If already initialized or connection fails
56
+ */
57
+ async initialize() {
58
+ if (this.initialized) {
59
+ throw new Error('Client already initialized');
60
+ }
61
+ const params = {
62
+ protocolVersion: 1,
63
+ clientCapabilities: this.clientCapabilities,
64
+ ...(this.clientInfo && {
65
+ clientInfo: {
66
+ name: this.clientInfo.name,
67
+ version: this.clientInfo.version ?? '0.0.0',
68
+ },
69
+ }),
70
+ };
71
+ const result = (await this.framing.sendRequest('initialize', params));
72
+ this.agentCapabilities = result.agentCapabilities ?? {};
73
+ this.initialized = true;
74
+ return this.agentCapabilities;
75
+ }
76
+ /**
77
+ * Create a new session
78
+ *
79
+ * @param params Session parameters including cwd and optional metadata
80
+ * @returns Session ID
81
+ * @throws If not initialized or session creation fails
82
+ */
83
+ async newSession(params) {
84
+ if (!this.initialized) {
85
+ throw new Error('Client not initialized');
86
+ }
87
+ const result = (await this.framing.sendRequest('session/new', params));
88
+ // Track session state
89
+ this.sessions.set(result.sessionId, {
90
+ id: result.sessionId,
91
+ status: 'idle',
92
+ });
93
+ return result.sessionId;
94
+ }
95
+ /**
96
+ * Send a prompt to the agent
97
+ *
98
+ * @param params Prompt request parameters including sessionId and prompt content
99
+ * @returns Prompt response with stopReason
100
+ * @throws If not initialized, session not found, or already prompting
101
+ */
102
+ async prompt(params) {
103
+ if (!this.initialized) {
104
+ throw new Error('Client not initialized');
105
+ }
106
+ const session = this.sessions.get(params.sessionId);
107
+ if (!session) {
108
+ throw new Error(`Session not found: ${params.sessionId}`);
109
+ }
110
+ if (session.status === 'prompting') {
111
+ throw new Error(`Session already prompting: ${params.sessionId}`);
112
+ }
113
+ // Update session state
114
+ session.status = 'prompting';
115
+ try {
116
+ const result = (await this.framing.sendRequest('session/prompt', params));
117
+ // Update session state based on stop reason
118
+ if (result.stopReason === 'cancelled') {
119
+ session.status = 'cancelled';
120
+ }
121
+ else {
122
+ session.status = 'idle';
123
+ }
124
+ return result;
125
+ }
126
+ catch (err) {
127
+ // Reset to idle on error
128
+ session.status = 'idle';
129
+ throw err;
130
+ }
131
+ }
132
+ /**
133
+ * Cancel an ongoing prompt
134
+ *
135
+ * Note: session/cancel is an optional ACP method. If the agent doesn't
136
+ * support it (returns "Method not found"), we silently ignore the error.
137
+ * The caller should fall back to process termination (SIGTERM) if needed.
138
+ *
139
+ * @param sessionId The session to cancel
140
+ * @throws If not initialized or session not found
141
+ */
142
+ async cancel(sessionId) {
143
+ if (!this.initialized) {
144
+ throw new Error('Client not initialized');
145
+ }
146
+ const session = this.sessions.get(sessionId);
147
+ if (!session) {
148
+ throw new Error(`Session not found: ${sessionId}`);
149
+ }
150
+ try {
151
+ // Use silentMethodNotFound since not all agents implement session/cancel
152
+ await this.framing.sendRequest('session/cancel', { sessionId }, { silentMethodNotFound: true });
153
+ // Update session state
154
+ session.status = 'cancelled';
155
+ }
156
+ catch (err) {
157
+ // Ignore "Method not found" errors - agent doesn't support cancel
158
+ const error = err;
159
+ if (error.code === -32601) {
160
+ // Agent doesn't support session/cancel, caller should use SIGTERM
161
+ return;
162
+ }
163
+ throw err;
164
+ }
165
+ }
166
+ /**
167
+ * Get session state
168
+ *
169
+ * @param sessionId The session to get
170
+ * @returns Session state or undefined if not found
171
+ */
172
+ getSession(sessionId) {
173
+ return this.sessions.get(sessionId);
174
+ }
175
+ /**
176
+ * Get all sessions
177
+ *
178
+ * @returns Array of all session states
179
+ */
180
+ getAllSessions() {
181
+ return Array.from(this.sessions.values());
182
+ }
183
+ /**
184
+ * Get agent capabilities (available after initialize)
185
+ *
186
+ * @returns Agent capabilities
187
+ */
188
+ getCapabilities() {
189
+ return this.agentCapabilities;
190
+ }
191
+ /**
192
+ * Check if client is initialized
193
+ *
194
+ * @returns true if initialize() has been called successfully
195
+ */
196
+ isInitialized() {
197
+ return this.initialized;
198
+ }
199
+ /**
200
+ * Check if the client connection is closed
201
+ *
202
+ * @returns true if the connection is closed
203
+ */
204
+ isClosed() {
205
+ return this.framing.isClosed();
206
+ }
207
+ /**
208
+ * Send a response to an agent request (tool call)
209
+ *
210
+ * Prefer typed response methods (respondPermission, etc.) when available.
211
+ *
212
+ * @param id - The request ID to respond to
213
+ * @param result - The result to send back
214
+ */
215
+ respond(id, result) {
216
+ this.framing.sendResponse(id, result);
217
+ }
218
+ /**
219
+ * Send a typed response to a permission request
220
+ *
221
+ * @param id - The request ID to respond to
222
+ * @param response - The permission response
223
+ */
224
+ respondPermission(id, response) {
225
+ this.framing.sendResponse(id, response);
226
+ }
227
+ /**
228
+ * Send an error response to an agent request
229
+ *
230
+ * @param id - The request ID to respond to
231
+ * @param code - Error code
232
+ * @param message - Error message
233
+ */
234
+ respondError(id, code, message) {
235
+ this.framing.sendError(id, { code, message });
236
+ }
237
+ /**
238
+ * Close the client connection
239
+ *
240
+ * Rejects any pending requests and cleans up resources.
241
+ */
242
+ close() {
243
+ this.framing.close();
244
+ }
245
+ /**
246
+ * Handle incoming notifications from the agent
247
+ */
248
+ handleNotification(notification) {
249
+ if (notification.method === 'session/update') {
250
+ const sessionNotification = notification.params;
251
+ this.emit('update', sessionNotification.sessionId, sessionNotification.update);
252
+ }
253
+ }
254
+ }
255
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/acp/client.ts"],"names":[],"mappings":"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"}