@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.
- package/README.md +263 -0
- package/dist/acp/client.d.ts +159 -0
- package/dist/acp/client.d.ts.map +1 -0
- package/dist/acp/client.js +255 -0
- package/dist/acp/client.js.map +1 -0
- package/dist/acp/framing.d.ts +119 -0
- package/dist/acp/framing.d.ts.map +1 -0
- package/dist/acp/framing.js +302 -0
- package/dist/acp/framing.js.map +1 -0
- package/dist/acp/index.d.ts +14 -0
- package/dist/acp/index.d.ts.map +1 -0
- package/dist/acp/index.js +13 -0
- package/dist/acp/index.js.map +1 -0
- package/dist/acp/types.d.ts +89 -0
- package/dist/acp/types.d.ts.map +1 -0
- package/dist/acp/types.js +99 -0
- package/dist/acp/types.js.map +1 -0
- package/dist/agents/adapters.d.ts +55 -0
- package/dist/agents/adapters.d.ts.map +1 -0
- package/dist/agents/adapters.js +84 -0
- package/dist/agents/adapters.js.map +1 -0
- package/dist/agents/index.d.ts +8 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.js +10 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/spawner.d.ts +53 -0
- package/dist/agents/spawner.d.ts.map +1 -0
- package/dist/agents/spawner.js +83 -0
- package/dist/agents/spawner.js.map +1 -0
- package/dist/cli/batch.d.ts +82 -0
- package/dist/cli/batch.d.ts.map +1 -0
- package/dist/cli/batch.js +162 -0
- package/dist/cli/batch.js.map +1 -0
- package/dist/cli/commands/clone-for-testing.d.ts +6 -0
- package/dist/cli/commands/clone-for-testing.d.ts.map +1 -0
- package/dist/cli/commands/clone-for-testing.js +176 -0
- package/dist/cli/commands/clone-for-testing.js.map +1 -0
- package/dist/cli/commands/derive.d.ts +6 -0
- package/dist/cli/commands/derive.d.ts.map +1 -0
- package/dist/cli/commands/derive.js +450 -0
- package/dist/cli/commands/derive.js.map +1 -0
- package/dist/cli/commands/help.d.ts +6 -0
- package/dist/cli/commands/help.d.ts.map +1 -0
- package/dist/cli/commands/help.js +196 -0
- package/dist/cli/commands/help.js.map +1 -0
- package/dist/cli/commands/inbox.d.ts +6 -0
- package/dist/cli/commands/inbox.d.ts.map +1 -0
- package/dist/cli/commands/inbox.js +235 -0
- package/dist/cli/commands/inbox.js.map +1 -0
- package/dist/cli/commands/index.d.ts +20 -0
- package/dist/cli/commands/index.d.ts.map +1 -0
- package/dist/cli/commands/index.js +21 -0
- package/dist/cli/commands/index.js.map +1 -0
- package/dist/cli/commands/init.d.ts +6 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +245 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/item.d.ts +6 -0
- package/dist/cli/commands/item.d.ts.map +1 -0
- package/dist/cli/commands/item.js +1311 -0
- package/dist/cli/commands/item.js.map +1 -0
- package/dist/cli/commands/link.d.ts +6 -0
- package/dist/cli/commands/link.d.ts.map +1 -0
- package/dist/cli/commands/link.js +288 -0
- package/dist/cli/commands/link.js.map +1 -0
- package/dist/cli/commands/log.d.ts +16 -0
- package/dist/cli/commands/log.d.ts.map +1 -0
- package/dist/cli/commands/log.js +291 -0
- package/dist/cli/commands/log.js.map +1 -0
- package/dist/cli/commands/meta.d.ts +15 -0
- package/dist/cli/commands/meta.d.ts.map +1 -0
- package/dist/cli/commands/meta.js +1378 -0
- package/dist/cli/commands/meta.js.map +1 -0
- package/dist/cli/commands/module.d.ts +6 -0
- package/dist/cli/commands/module.d.ts.map +1 -0
- package/dist/cli/commands/module.js +102 -0
- package/dist/cli/commands/module.js.map +1 -0
- package/dist/cli/commands/ralph.d.ts +9 -0
- package/dist/cli/commands/ralph.d.ts.map +1 -0
- package/dist/cli/commands/ralph.js +465 -0
- package/dist/cli/commands/ralph.js.map +1 -0
- package/dist/cli/commands/search.d.ts +6 -0
- package/dist/cli/commands/search.d.ts.map +1 -0
- package/dist/cli/commands/search.js +134 -0
- package/dist/cli/commands/search.js.map +1 -0
- package/dist/cli/commands/session.d.ts +164 -0
- package/dist/cli/commands/session.d.ts.map +1 -0
- package/dist/cli/commands/session.js +745 -0
- package/dist/cli/commands/session.js.map +1 -0
- package/dist/cli/commands/setup.d.ts +26 -0
- package/dist/cli/commands/setup.d.ts.map +1 -0
- package/dist/cli/commands/setup.js +586 -0
- package/dist/cli/commands/setup.js.map +1 -0
- package/dist/cli/commands/shadow.d.ts +6 -0
- package/dist/cli/commands/shadow.d.ts.map +1 -0
- package/dist/cli/commands/shadow.js +299 -0
- package/dist/cli/commands/shadow.js.map +1 -0
- package/dist/cli/commands/task.d.ts +6 -0
- package/dist/cli/commands/task.d.ts.map +1 -0
- package/dist/cli/commands/task.js +1514 -0
- package/dist/cli/commands/task.js.map +1 -0
- package/dist/cli/commands/tasks.d.ts +6 -0
- package/dist/cli/commands/tasks.d.ts.map +1 -0
- package/dist/cli/commands/tasks.js +347 -0
- package/dist/cli/commands/tasks.js.map +1 -0
- package/dist/cli/commands/trait.d.ts +10 -0
- package/dist/cli/commands/trait.d.ts.map +1 -0
- package/dist/cli/commands/trait.js +295 -0
- package/dist/cli/commands/trait.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +6 -0
- package/dist/cli/commands/validate.d.ts.map +1 -0
- package/dist/cli/commands/validate.js +626 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/exit-codes.d.ts +62 -0
- package/dist/cli/exit-codes.d.ts.map +1 -0
- package/dist/cli/exit-codes.js +65 -0
- package/dist/cli/exit-codes.js.map +1 -0
- package/dist/cli/help/content.d.ts +35 -0
- package/dist/cli/help/content.d.ts.map +1 -0
- package/dist/cli/help/content.js +312 -0
- package/dist/cli/help/content.js.map +1 -0
- package/dist/cli/index.d.ts +5 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +85 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/introspection.d.ts +87 -0
- package/dist/cli/introspection.d.ts.map +1 -0
- package/dist/cli/introspection.js +127 -0
- package/dist/cli/introspection.js.map +1 -0
- package/dist/cli/output.d.ts +56 -0
- package/dist/cli/output.d.ts.map +1 -0
- package/dist/cli/output.js +467 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/cli/suggest.d.ts +16 -0
- package/dist/cli/suggest.d.ts.map +1 -0
- package/dist/cli/suggest.js +72 -0
- package/dist/cli/suggest.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/parser/alignment.d.ts +113 -0
- package/dist/parser/alignment.d.ts.map +1 -0
- package/dist/parser/alignment.js +261 -0
- package/dist/parser/alignment.js.map +1 -0
- package/dist/parser/assess.d.ts +81 -0
- package/dist/parser/assess.d.ts.map +1 -0
- package/dist/parser/assess.js +197 -0
- package/dist/parser/assess.js.map +1 -0
- package/dist/parser/convention-validation.d.ts +48 -0
- package/dist/parser/convention-validation.d.ts.map +1 -0
- package/dist/parser/convention-validation.js +167 -0
- package/dist/parser/convention-validation.js.map +1 -0
- package/dist/parser/fix.d.ts +38 -0
- package/dist/parser/fix.d.ts.map +1 -0
- package/dist/parser/fix.js +185 -0
- package/dist/parser/fix.js.map +1 -0
- package/dist/parser/index.d.ts +12 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +13 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/items.d.ts +138 -0
- package/dist/parser/items.d.ts.map +1 -0
- package/dist/parser/items.js +321 -0
- package/dist/parser/items.js.map +1 -0
- package/dist/parser/meta.d.ts +120 -0
- package/dist/parser/meta.d.ts.map +1 -0
- package/dist/parser/meta.js +441 -0
- package/dist/parser/meta.js.map +1 -0
- package/dist/parser/refs.d.ts +185 -0
- package/dist/parser/refs.d.ts.map +1 -0
- package/dist/parser/refs.js +404 -0
- package/dist/parser/refs.js.map +1 -0
- package/dist/parser/shadow.d.ts +253 -0
- package/dist/parser/shadow.d.ts.map +1 -0
- package/dist/parser/shadow.js +1053 -0
- package/dist/parser/shadow.js.map +1 -0
- package/dist/parser/traits.d.ts +72 -0
- package/dist/parser/traits.d.ts.map +1 -0
- package/dist/parser/traits.js +120 -0
- package/dist/parser/traits.js.map +1 -0
- package/dist/parser/validate.d.ts +89 -0
- package/dist/parser/validate.d.ts.map +1 -0
- package/dist/parser/validate.js +817 -0
- package/dist/parser/validate.js.map +1 -0
- package/dist/parser/yaml.d.ts +326 -0
- package/dist/parser/yaml.d.ts.map +1 -0
- package/dist/parser/yaml.js +1383 -0
- package/dist/parser/yaml.js.map +1 -0
- package/dist/ralph/cli-renderer.d.ts +20 -0
- package/dist/ralph/cli-renderer.d.ts.map +1 -0
- package/dist/ralph/cli-renderer.js +179 -0
- package/dist/ralph/cli-renderer.js.map +1 -0
- package/dist/ralph/events.d.ts +65 -0
- package/dist/ralph/events.d.ts.map +1 -0
- package/dist/ralph/events.js +397 -0
- package/dist/ralph/events.js.map +1 -0
- package/dist/ralph/index.d.ts +8 -0
- package/dist/ralph/index.d.ts.map +1 -0
- package/dist/ralph/index.js +10 -0
- package/dist/ralph/index.js.map +1 -0
- package/dist/schema/common.d.ts +46 -0
- package/dist/schema/common.d.ts.map +1 -0
- package/dist/schema/common.js +71 -0
- package/dist/schema/common.js.map +1 -0
- package/dist/schema/inbox.d.ts +90 -0
- package/dist/schema/inbox.d.ts.map +1 -0
- package/dist/schema/inbox.js +30 -0
- package/dist/schema/inbox.js.map +1 -0
- package/dist/schema/index.d.ts +6 -0
- package/dist/schema/index.d.ts.map +1 -0
- package/dist/schema/index.js +7 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/schema/meta.d.ts +762 -0
- package/dist/schema/meta.d.ts.map +1 -0
- package/dist/schema/meta.js +144 -0
- package/dist/schema/meta.js.map +1 -0
- package/dist/schema/spec.d.ts +912 -0
- package/dist/schema/spec.d.ts.map +1 -0
- package/dist/schema/spec.js +104 -0
- package/dist/schema/spec.js.map +1 -0
- package/dist/schema/task.d.ts +664 -0
- package/dist/schema/task.d.ts.map +1 -0
- package/dist/schema/task.js +130 -0
- package/dist/schema/task.js.map +1 -0
- package/dist/sessions/index.d.ts +11 -0
- package/dist/sessions/index.d.ts.map +1 -0
- package/dist/sessions/index.js +13 -0
- package/dist/sessions/index.js.map +1 -0
- package/dist/sessions/store.d.ts +144 -0
- package/dist/sessions/store.d.ts.map +1 -0
- package/dist/sessions/store.js +325 -0
- package/dist/sessions/store.js.map +1 -0
- package/dist/sessions/types.d.ts +157 -0
- package/dist/sessions/types.d.ts.map +1 -0
- package/dist/sessions/types.js +90 -0
- package/dist/sessions/types.js.map +1 -0
- package/dist/strings/errors.d.ts +420 -0
- package/dist/strings/errors.d.ts.map +1 -0
- package/dist/strings/errors.js +282 -0
- package/dist/strings/errors.js.map +1 -0
- package/dist/strings/guidance.d.ts +65 -0
- package/dist/strings/guidance.d.ts.map +1 -0
- package/dist/strings/guidance.js +66 -0
- package/dist/strings/guidance.js.map +1 -0
- package/dist/strings/index.d.ts +12 -0
- package/dist/strings/index.d.ts.map +1 -0
- package/dist/strings/index.js +12 -0
- package/dist/strings/index.js.map +1 -0
- package/dist/strings/labels.d.ts +74 -0
- package/dist/strings/labels.d.ts.map +1 -0
- package/dist/strings/labels.js +75 -0
- package/dist/strings/labels.js.map +1 -0
- package/dist/strings/validation.d.ts +126 -0
- package/dist/strings/validation.d.ts.map +1 -0
- package/dist/strings/validation.js +135 -0
- package/dist/strings/validation.js.map +1 -0
- package/dist/utils/commit.d.ts +23 -0
- package/dist/utils/commit.d.ts.map +1 -0
- package/dist/utils/commit.js +67 -0
- package/dist/utils/commit.js.map +1 -0
- package/dist/utils/git.d.ts +57 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +192 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/grep.d.ts +28 -0
- package/dist/utils/grep.d.ts.map +1 -0
- package/dist/utils/grep.js +86 -0
- package/dist/utils/grep.js.map +1 -0
- package/dist/utils/index.d.ts +8 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +6 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/time.d.ts +18 -0
- package/dist/utils/time.d.ts.map +1 -0
- package/dist/utils/time.js +61 -0
- package/dist/utils/time.js.map +1 -0
- 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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"}
|