@draht/coding-agent 2026.3.2 → 2026.3.3
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/CHANGELOG.md +74 -13
- package/README.md +89 -106
- package/agents/architect.md +45 -0
- package/agents/debugger.md +57 -0
- package/agents/git-committer.md +46 -0
- package/agents/implementer.md +25 -0
- package/agents/reviewer.md +52 -0
- package/agents/security-auditor.md +61 -0
- package/agents/verifier.md +44 -0
- package/bin/draht-tools.cjs +20 -20
- package/dist/agents/architect.md +45 -0
- package/dist/agents/debugger.md +57 -0
- package/dist/agents/git-committer.md +46 -0
- package/dist/agents/implementer.md +25 -0
- package/dist/agents/reviewer.md +52 -0
- package/dist/agents/security-auditor.md +61 -0
- package/dist/agents/verifier.md +44 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +2 -2
- package/dist/config.js.map +1 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +10 -1
- package/dist/core/package-manager.js.map +1 -1
- package/dist/extensions/gsd-commands.ts +69 -4
- package/dist/extensions/subagent.ts +212 -9
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/migrations.d.ts +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +3 -3
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +1 -1
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/dark.json +1 -1
- package/dist/modes/interactive/theme/light.json +1 -1
- package/dist/prompts/commands/discuss-phase.md +3 -3
- package/dist/prompts/commands/execute-phase.md +9 -9
- package/dist/prompts/commands/map-codebase.md +2 -2
- package/dist/prompts/commands/new-project.md +9 -9
- package/dist/prompts/commands/pause-work.md +2 -2
- package/dist/prompts/commands/plan-phase.md +5 -5
- package/dist/prompts/commands/progress.md +1 -1
- package/dist/prompts/commands/quick.md +4 -4
- package/dist/prompts/commands/resume-work.md +1 -1
- package/dist/prompts/commands/verify-work.md +4 -4
- package/docs/compaction.md +14 -14
- package/docs/custom-provider.md +9 -9
- package/docs/development.md +1 -1
- package/docs/extensions.md +32 -32
- package/docs/json.md +4 -4
- package/docs/packages.md +1 -1
- package/docs/providers.md +1 -1
- package/docs/rpc.md +1 -1
- package/docs/sdk.md +24 -24
- package/docs/session.md +6 -6
- package/docs/termux.md +1 -1
- package/docs/themes.md +2 -2
- package/docs/tui.md +20 -20
- package/examples/extensions/README.md +4 -4
- package/examples/extensions/doom-overlay/README.md +1 -1
- package/examples/extensions/dynamic-resources/dynamic.json +1 -1
- package/examples/extensions/subagent/README.md +11 -11
- package/examples/sdk/README.md +3 -3
- package/extensions/gsd-commands.ts +69 -4
- package/extensions/subagent.ts +212 -9
- package/package.json +9 -7
- package/prompts/commands/discuss-phase.md +3 -3
- package/prompts/commands/execute-phase.md +9 -9
- package/prompts/commands/map-codebase.md +2 -2
- package/prompts/commands/new-project.md +9 -9
- package/prompts/commands/pause-work.md +2 -2
- package/prompts/commands/plan-phase.md +5 -5
- package/prompts/commands/progress.md +1 -1
- package/prompts/commands/quick.md +4 -4
- package/prompts/commands/resume-work.md +1 -1
- package/prompts/commands/verify-work.md +4 -4
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$schema": "https://raw.githubusercontent.com/
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/draht-dev/draht/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
|
|
3
3
|
"name": "dark",
|
|
4
4
|
"vars": {
|
|
5
5
|
"cyan": "#00d7ff",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$schema": "https://raw.githubusercontent.com/
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/draht-dev/draht/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
|
|
3
3
|
"name": "light",
|
|
4
4
|
"vars": {
|
|
5
5
|
"teal": "#5a8080",
|
|
@@ -8,12 +8,12 @@ Capture implementation decisions before planning a phase.
|
|
|
8
8
|
```
|
|
9
9
|
|
|
10
10
|
## Steps
|
|
11
|
-
1. Run `draht phase-info N` to load phase context
|
|
11
|
+
1. Run `draht-tools phase-info N` to load phase context
|
|
12
12
|
2. Identify gray areas based on what's being built
|
|
13
13
|
3. Present 1-2 questions at a time about preferences
|
|
14
14
|
4. If `.planning/DOMAIN.md` exists, load it and validate discovered terms against the glossary. Add any new domain terms found during discussion.
|
|
15
|
-
5. Record decisions with `draht save-context N`
|
|
16
|
-
6. Commit: `draht commit-docs "capture phase N context"`
|
|
15
|
+
5. Record decisions with `draht-tools save-context N`
|
|
16
|
+
6. Commit: `draht-tools commit-docs "capture phase N context"`
|
|
17
17
|
|
|
18
18
|
## Gray Area Categories
|
|
19
19
|
- **Visual features** → Layout, density, interactions, empty states
|
|
@@ -8,36 +8,36 @@ Execute all plans in a phase with atomic commits.
|
|
|
8
8
|
```
|
|
9
9
|
|
|
10
10
|
## Steps
|
|
11
|
-
1. Run `draht discover-plans N` to find and order plans
|
|
11
|
+
1. Run `draht-tools discover-plans N` to find and order plans
|
|
12
12
|
2. For each plan in dependency order:
|
|
13
|
-
a. Load plan: `draht read-plan N P`
|
|
13
|
+
a. Load plan: `draht-tools read-plan N P`
|
|
14
14
|
b. Execute each task in strict TDD cycle:
|
|
15
15
|
|
|
16
16
|
**🔴 RED — Write failing tests first**
|
|
17
17
|
- Write the test cases from `<test>`
|
|
18
18
|
- Run tests — confirm they FAIL (if they pass, the test is wrong)
|
|
19
|
-
- Commit failing tests: `draht commit-task N P T "red: test description"`
|
|
19
|
+
- Commit failing tests: `draht-tools commit-task N P T "red: test description"`
|
|
20
20
|
|
|
21
21
|
**🟢 GREEN — Minimal implementation**
|
|
22
22
|
- Write the minimum code from `<action>` to make tests pass
|
|
23
23
|
- Use domain language from `<context>` and `<domain>` for all names
|
|
24
24
|
- Run tests — confirm they PASS
|
|
25
|
-
- Commit: `draht commit-task N P T "green: task name"`
|
|
25
|
+
- Commit: `draht-tools commit-task N P T "green: task name"`
|
|
26
26
|
|
|
27
27
|
**🔵 REFACTOR — Clean up with safety net**
|
|
28
28
|
- Apply improvements from `<refactor>` (if any)
|
|
29
29
|
- Run tests after each change — must stay green
|
|
30
30
|
- Verify domain language compliance (names match DOMAIN.md)
|
|
31
|
-
- Commit: `draht commit-task N P T "refactor: description"`
|
|
31
|
+
- Commit: `draht-tools commit-task N P T "refactor: description"`
|
|
32
32
|
|
|
33
33
|
**✅ VERIFY**
|
|
34
34
|
- Run the `<verify>` step
|
|
35
35
|
- Confirm `<done>` criteria met
|
|
36
36
|
|
|
37
|
-
c. Write summary: `draht write-summary N P`
|
|
38
|
-
3. Phase verification: `draht verify-phase N`
|
|
39
|
-
4. Update state: `draht update-state`
|
|
40
|
-
5. Final commit: `draht commit-docs "complete phase N execution"`
|
|
37
|
+
c. Write summary: `draht-tools write-summary N P`
|
|
38
|
+
3. Phase verification: `draht-tools verify-phase N`
|
|
39
|
+
4. Update state: `draht-tools update-state`
|
|
40
|
+
5. Final commit: `draht-tools commit-docs "complete phase N execution"`
|
|
41
41
|
|
|
42
42
|
## TDD Rules
|
|
43
43
|
- Never write implementation before a failing test exists
|
|
@@ -8,7 +8,7 @@ Analyze existing codebase before planning.
|
|
|
8
8
|
```
|
|
9
9
|
|
|
10
10
|
## Steps
|
|
11
|
-
1. Run `draht map-codebase [dir]`
|
|
11
|
+
1. Run `draht-tools map-codebase [dir]`
|
|
12
12
|
2. Tool generates: STACK.md, ARCHITECTURE.md, CONVENTIONS.md, CONCERNS.md
|
|
13
13
|
3. Review output, supplement with your own analysis if needed
|
|
14
14
|
4. Identify implicit bounded contexts from directory structure:
|
|
@@ -29,4 +29,4 @@ Analyze existing codebase before planning.
|
|
|
29
29
|
- Existing coverage configuration and goals (if any)
|
|
30
30
|
- Which layers have tests today (unit, integration, e2e)
|
|
31
31
|
- Gaps and recommendations
|
|
32
|
-
8. Commit: `draht commit-docs "map existing codebase"`
|
|
32
|
+
8. Commit: `draht-tools commit-docs "map existing codebase"`
|
|
@@ -8,11 +8,11 @@ Initialize a new GSD project: questioning → research → requirements → road
|
|
|
8
8
|
```
|
|
9
9
|
|
|
10
10
|
## Steps
|
|
11
|
-
1. Run `draht init` to check preconditions
|
|
12
|
-
2. If existing code detected, run `draht map-codebase` first
|
|
11
|
+
1. Run `draht-tools init` to check preconditions
|
|
12
|
+
2. If existing code detected, run `draht-tools map-codebase` first
|
|
13
13
|
3. Deep questioning phase (3-7 rounds, 1-2 questions at a time)
|
|
14
|
-
4. Run `draht create-project` with gathered info
|
|
15
|
-
5. Run `draht create-domain-model` to define bounded contexts, entities, and ubiquitous language
|
|
14
|
+
4. Run `draht-tools create-project` with gathered info
|
|
15
|
+
5. Run `draht-tools create-domain-model` to define bounded contexts, entities, and ubiquitous language
|
|
16
16
|
6. Create `.planning/DOMAIN.md` with:
|
|
17
17
|
- `## Bounded Contexts` — each context with name, responsibility, and brief description
|
|
18
18
|
- `## Ubiquitous Language` — glossary of domain terms agreed with the user (term → definition)
|
|
@@ -25,11 +25,11 @@ Initialize a new GSD project: questioning → research → requirements → road
|
|
|
25
25
|
- `## Coverage Goals` — target coverage percentage and which paths are critical
|
|
26
26
|
- `## Testing Levels` — what is tested at unit level vs integration vs e2e, with examples
|
|
27
27
|
- `## Excluded` — what is explicitly not tested and why (config files, generated code, etc.)
|
|
28
|
-
8. Optional research phase via `draht research`
|
|
29
|
-
9. Run `draht create-requirements` with v1/v2/out-of-scope (map requirements to bounded contexts)
|
|
30
|
-
10. Run `draht create-roadmap` with phases
|
|
31
|
-
11. Run `draht init-state`
|
|
32
|
-
12. Git commit via `draht commit-docs "initialize GSD project"`
|
|
28
|
+
8. Optional research phase via `draht-tools research`
|
|
29
|
+
9. Run `draht-tools create-requirements` with v1/v2/out-of-scope (map requirements to bounded contexts)
|
|
30
|
+
10. Run `draht-tools create-roadmap` with phases
|
|
31
|
+
11. Run `draht-tools init-state`
|
|
32
|
+
12. Git commit via `draht-tools commit-docs "initialize GSD project"`
|
|
33
33
|
|
|
34
34
|
## Rules
|
|
35
35
|
- Ask 1-2 questions at a time, never dump 10 at once
|
|
@@ -8,5 +8,5 @@ Create a handoff document for session continuity.
|
|
|
8
8
|
```
|
|
9
9
|
|
|
10
10
|
## Steps
|
|
11
|
-
1. Run `draht pause` — creates CONTINUE-HERE.md
|
|
12
|
-
2. Commit: `draht commit-docs "pause work"`
|
|
11
|
+
1. Run `draht-tools pause` — creates CONTINUE-HERE.md
|
|
12
|
+
2. Commit: `draht-tools commit-docs "pause work"`
|
|
@@ -8,17 +8,17 @@ Create atomic execution plans for a roadmap phase.
|
|
|
8
8
|
```
|
|
9
9
|
|
|
10
10
|
## Steps
|
|
11
|
-
1. Run `draht load-phase-context N` to gather all context
|
|
12
|
-
2. Optional: `draht research-phase N` for domain research
|
|
11
|
+
1. Run `draht-tools load-phase-context N` to gather all context
|
|
12
|
+
2. Optional: `draht-tools research-phase N` for domain research
|
|
13
13
|
3. Goal-backward planning:
|
|
14
14
|
a. State the goal (outcome, not activity)
|
|
15
15
|
b. Derive observable truths (3-7 from user perspective)
|
|
16
16
|
c. From each observable truth, derive the test scenarios that would prove it (specific inputs → expected outputs or state changes)
|
|
17
17
|
d. Map to required artifacts (files, endpoints, schemas)
|
|
18
18
|
e. Break into atomic tasks (2-5 per plan)
|
|
19
|
-
4. Write plans: `draht create-plan N P`
|
|
20
|
-
5. Validate: `draht validate-plans N`
|
|
21
|
-
6. Commit: `draht commit-docs "create phase N plans"`
|
|
19
|
+
4. Write plans: `draht-tools create-plan N P`
|
|
20
|
+
5. Validate: `draht-tools validate-plans N`
|
|
21
|
+
6. Commit: `draht-tools commit-docs "create phase N plans"`
|
|
22
22
|
|
|
23
23
|
## Plan Format
|
|
24
24
|
Plans use XML task format:
|
|
@@ -8,12 +8,12 @@ Execute a small ad-hoc task with GSD tracking.
|
|
|
8
8
|
```
|
|
9
9
|
|
|
10
10
|
## Steps
|
|
11
|
-
1. Run `draht next-quick-number` to get task number
|
|
12
|
-
2. Create quick plan: `draht create-quick-plan NNN "description"`
|
|
11
|
+
1. Run `draht-tools next-quick-number` to get task number
|
|
12
|
+
2. Create quick plan: `draht-tools create-quick-plan NNN "description"`
|
|
13
13
|
3. Execute tasks following the TDD cycle:
|
|
14
14
|
- **🔴 RED** — Write a failing test that describes the desired behaviour
|
|
15
15
|
- **🟢 GREEN** — Write the minimum implementation to make it pass
|
|
16
16
|
- **🔵 REFACTOR** — Clean up while keeping the test green
|
|
17
17
|
- *Exception: skip the TDD cycle only for pure config or documentation-only tasks that have no testable behaviour*
|
|
18
|
-
4. Write summary: `draht write-quick-summary NNN`
|
|
19
|
-
5. Update state: `draht update-state`
|
|
18
|
+
4. Write summary: `draht-tools write-quick-summary NNN`
|
|
19
|
+
5. Update state: `draht-tools update-state`
|
|
@@ -8,6 +8,6 @@ Resume from last session state.
|
|
|
8
8
|
```
|
|
9
9
|
|
|
10
10
|
## Steps
|
|
11
|
-
1. Run `draht resume` — loads CONTINUE-HERE.md or STATE.md
|
|
11
|
+
1. Run `draht-tools resume` — loads CONTINUE-HERE.md or STATE.md
|
|
12
12
|
2. Display context and ask to continue
|
|
13
13
|
3. Delete CONTINUE-HERE.md after confirmation
|
|
@@ -15,13 +15,13 @@ Walk through acceptance testing of completed phase work.
|
|
|
15
15
|
- Load `.planning/DOMAIN.md` and extract all defined terms
|
|
16
16
|
- Scan source files for PascalCase identifiers not present in the glossary
|
|
17
17
|
- Flag any bounded context boundary violations (cross-context direct imports)
|
|
18
|
-
3. Run quality gate: `draht quality-gate --strict`
|
|
19
|
-
4. Run `draht extract-deliverables N` to get testable items
|
|
18
|
+
3. Run quality gate: `draht-tools quality-gate --strict`
|
|
19
|
+
4. Run `draht-tools extract-deliverables N` to get testable items
|
|
20
20
|
5. Walk user through each deliverable one at a time
|
|
21
21
|
6. Record results (pass/fail/partially/skip)
|
|
22
|
-
7. For failures: diagnose and create fix plans via `draht create-fix-plan N P`
|
|
22
|
+
7. For failures: diagnose and create fix plans via `draht-tools create-fix-plan N P`
|
|
23
23
|
- Fix plans MUST include a reproducing test that demonstrates the failure before any implementation
|
|
24
|
-
8. Write UAT report: `draht write-uat N`
|
|
24
|
+
8. Write UAT report: `draht-tools write-uat N`
|
|
25
25
|
- Report must include: test health summary (pass/fail/coverage), domain model status (any glossary violations), deliverable results
|
|
26
26
|
9. If all passed: mark phase complete
|
|
27
27
|
10. If failures: route to `execute-phase N --gaps-only`
|
package/docs/compaction.md
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
LLMs have limited context windows. When conversations grow too long, pi uses compaction to summarize older content while preserving recent work. This page covers both auto-compaction and branch summarization.
|
|
4
4
|
|
|
5
|
-
**Source files** ([pi-mono](https://github.com/
|
|
6
|
-
- [`packages/coding-agent/src/core/compaction/compaction.ts`](https://github.com/
|
|
7
|
-
- [`packages/coding-agent/src/core/compaction/branch-summarization.ts`](https://github.com/
|
|
8
|
-
- [`packages/coding-agent/src/core/compaction/utils.ts`](https://github.com/
|
|
9
|
-
- [`packages/coding-agent/src/core/session-manager.ts`](https://github.com/
|
|
10
|
-
- [`packages/coding-agent/src/core/extensions/types.ts`](https://github.com/
|
|
5
|
+
**Source files** ([pi-mono](https://github.com/draht-dev/draht)):
|
|
6
|
+
- [`packages/coding-agent/src/core/compaction/compaction.ts`](https://github.com/draht-dev/draht/blob/main/packages/coding-agent/src/core/compaction/compaction.ts) - Auto-compaction logic
|
|
7
|
+
- [`packages/coding-agent/src/core/compaction/branch-summarization.ts`](https://github.com/draht-dev/draht/blob/main/packages/coding-agent/src/core/compaction/branch-summarization.ts) - Branch summarization
|
|
8
|
+
- [`packages/coding-agent/src/core/compaction/utils.ts`](https://github.com/draht-dev/draht/blob/main/packages/coding-agent/src/core/compaction/utils.ts) - Shared utilities (file tracking, serialization)
|
|
9
|
+
- [`packages/coding-agent/src/core/session-manager.ts`](https://github.com/draht-dev/draht/blob/main/packages/coding-agent/src/core/session-manager.ts) - Entry types (`CompactionEntry`, `BranchSummaryEntry`)
|
|
10
|
+
- [`packages/coding-agent/src/core/extensions/types.ts`](https://github.com/draht-dev/draht/blob/main/packages/coding-agent/src/core/extensions/types.ts) - Extension event types
|
|
11
11
|
|
|
12
|
-
For TypeScript definitions in your project, inspect `node_modules/@
|
|
12
|
+
For TypeScript definitions in your project, inspect `node_modules/@draht/coding-agent/dist/`.
|
|
13
13
|
|
|
14
14
|
## Overview
|
|
15
15
|
|
|
@@ -116,7 +116,7 @@ Never cut at tool results (they must stay with their tool call).
|
|
|
116
116
|
|
|
117
117
|
### CompactionEntry Structure
|
|
118
118
|
|
|
119
|
-
Defined in [`session-manager.ts`](https://github.com/
|
|
119
|
+
Defined in [`session-manager.ts`](https://github.com/draht-dev/draht/blob/main/packages/coding-agent/src/core/session-manager.ts):
|
|
120
120
|
|
|
121
121
|
```typescript
|
|
122
122
|
interface CompactionEntry<T = unknown> {
|
|
@@ -140,7 +140,7 @@ interface CompactionDetails {
|
|
|
140
140
|
|
|
141
141
|
Extensions can store any JSON-serializable data in `details`. The default compaction tracks file operations, but custom extension implementations can use their own structure.
|
|
142
142
|
|
|
143
|
-
See [`prepareCompaction()`](https://github.com/
|
|
143
|
+
See [`prepareCompaction()`](https://github.com/draht-dev/draht/blob/main/packages/coding-agent/src/core/compaction/compaction.ts) and [`compact()`](https://github.com/draht-dev/draht/blob/main/packages/coding-agent/src/core/compaction/compaction.ts) for the implementation.
|
|
144
144
|
|
|
145
145
|
## Branch Summarization
|
|
146
146
|
|
|
@@ -183,7 +183,7 @@ This means file tracking accumulates across multiple compactions or nested branc
|
|
|
183
183
|
|
|
184
184
|
### BranchSummaryEntry Structure
|
|
185
185
|
|
|
186
|
-
Defined in [`session-manager.ts`](https://github.com/
|
|
186
|
+
Defined in [`session-manager.ts`](https://github.com/draht-dev/draht/blob/main/packages/coding-agent/src/core/session-manager.ts):
|
|
187
187
|
|
|
188
188
|
```typescript
|
|
189
189
|
interface BranchSummaryEntry<T = unknown> {
|
|
@@ -206,7 +206,7 @@ interface BranchSummaryDetails {
|
|
|
206
206
|
|
|
207
207
|
Same as compaction, extensions can store custom data in `details`.
|
|
208
208
|
|
|
209
|
-
See [`collectEntriesForBranchSummary()`](https://github.com/
|
|
209
|
+
See [`collectEntriesForBranchSummary()`](https://github.com/draht-dev/draht/blob/main/packages/coding-agent/src/core/compaction/branch-summarization.ts), [`prepareBranchEntries()`](https://github.com/draht-dev/draht/blob/main/packages/coding-agent/src/core/compaction/branch-summarization.ts), and [`generateBranchSummary()`](https://github.com/draht-dev/draht/blob/main/packages/coding-agent/src/core/compaction/branch-summarization.ts) for the implementation.
|
|
210
210
|
|
|
211
211
|
## Summary Format
|
|
212
212
|
|
|
@@ -250,7 +250,7 @@ path/to/changed.ts
|
|
|
250
250
|
|
|
251
251
|
### Message Serialization
|
|
252
252
|
|
|
253
|
-
Before summarization, messages are serialized to text via [`serializeConversation()`](https://github.com/
|
|
253
|
+
Before summarization, messages are serialized to text via [`serializeConversation()`](https://github.com/draht-dev/draht/blob/main/packages/coding-agent/src/core/compaction/utils.ts):
|
|
254
254
|
|
|
255
255
|
```
|
|
256
256
|
[User]: What they said
|
|
@@ -264,7 +264,7 @@ This prevents the model from treating it as a conversation to continue.
|
|
|
264
264
|
|
|
265
265
|
## Custom Summarization via Extensions
|
|
266
266
|
|
|
267
|
-
Extensions can intercept and customize both compaction and branch summarization. See [`extensions/types.ts`](https://github.com/
|
|
267
|
+
Extensions can intercept and customize both compaction and branch summarization. See [`extensions/types.ts`](https://github.com/draht-dev/draht/blob/main/packages/coding-agent/src/core/extensions/types.ts) for event type definitions.
|
|
268
268
|
|
|
269
269
|
### session_before_compact
|
|
270
270
|
|
|
@@ -305,7 +305,7 @@ pi.on("session_before_compact", async (event, ctx) => {
|
|
|
305
305
|
To generate a summary with your own model, convert messages to text using `serializeConversation`:
|
|
306
306
|
|
|
307
307
|
```typescript
|
|
308
|
-
import { convertToLlm, serializeConversation } from "@
|
|
308
|
+
import { convertToLlm, serializeConversation } from "@draht/coding-agent";
|
|
309
309
|
|
|
310
310
|
pi.on("session_before_compact", async (event, ctx) => {
|
|
311
311
|
const { preparation } = event;
|
package/docs/custom-provider.md
CHANGED
|
@@ -31,7 +31,7 @@ See these complete provider examples:
|
|
|
31
31
|
## Quick Reference
|
|
32
32
|
|
|
33
33
|
```typescript
|
|
34
|
-
import type { ExtensionAPI } from "@
|
|
34
|
+
import type { ExtensionAPI } from "@draht/coding-agent";
|
|
35
35
|
|
|
36
36
|
export default function (pi: ExtensionAPI) {
|
|
37
37
|
// Override baseUrl for existing provider
|
|
@@ -200,7 +200,7 @@ pi.registerProvider("custom-api", {
|
|
|
200
200
|
Add OAuth/SSO authentication that integrates with `/login`:
|
|
201
201
|
|
|
202
202
|
```typescript
|
|
203
|
-
import type { OAuthCredentials, OAuthLoginCallbacks } from "@
|
|
203
|
+
import type { OAuthCredentials, OAuthLoginCallbacks } from "@draht/ai";
|
|
204
204
|
|
|
205
205
|
pi.registerProvider("corporate-ai", {
|
|
206
206
|
baseUrl: "https://ai.corp.com/v1",
|
|
@@ -293,11 +293,11 @@ interface OAuthCredentials {
|
|
|
293
293
|
For providers with non-standard APIs, implement `streamSimple`. Study the existing provider implementations before writing your own:
|
|
294
294
|
|
|
295
295
|
**Reference implementations:**
|
|
296
|
-
- [anthropic.ts](https://github.com/
|
|
297
|
-
- [openai-completions.ts](https://github.com/
|
|
298
|
-
- [openai-responses.ts](https://github.com/
|
|
299
|
-
- [google.ts](https://github.com/
|
|
300
|
-
- [amazon-bedrock.ts](https://github.com/
|
|
296
|
+
- [anthropic.ts](https://github.com/draht-dev/draht/blob/main/packages/ai/src/providers/anthropic.ts) - Anthropic Messages API
|
|
297
|
+
- [openai-completions.ts](https://github.com/draht-dev/draht/blob/main/packages/ai/src/providers/openai-completions.ts) - OpenAI Chat Completions
|
|
298
|
+
- [openai-responses.ts](https://github.com/draht-dev/draht/blob/main/packages/ai/src/providers/openai-responses.ts) - OpenAI Responses API
|
|
299
|
+
- [google.ts](https://github.com/draht-dev/draht/blob/main/packages/ai/src/providers/google.ts) - Google Generative AI
|
|
300
|
+
- [amazon-bedrock.ts](https://github.com/draht-dev/draht/blob/main/packages/ai/src/providers/amazon-bedrock.ts) - AWS Bedrock
|
|
301
301
|
|
|
302
302
|
### Stream Pattern
|
|
303
303
|
|
|
@@ -312,7 +312,7 @@ import {
|
|
|
312
312
|
type SimpleStreamOptions,
|
|
313
313
|
calculateCost,
|
|
314
314
|
createAssistantMessageEventStream,
|
|
315
|
-
} from "@
|
|
315
|
+
} from "@draht/ai";
|
|
316
316
|
|
|
317
317
|
function streamMyProvider(
|
|
318
318
|
model: Model<any>,
|
|
@@ -469,7 +469,7 @@ pi.registerProvider("my-provider", {
|
|
|
469
469
|
|
|
470
470
|
## Testing Your Implementation
|
|
471
471
|
|
|
472
|
-
Test your provider against the same test suites used by built-in providers. Copy and adapt these test files from [packages/ai/test/](https://github.com/
|
|
472
|
+
Test your provider against the same test suites used by built-in providers. Copy and adapt these test files from [packages/ai/test/](https://github.com/draht-dev/draht/tree/main/packages/ai/test):
|
|
473
473
|
|
|
474
474
|
| Test | Purpose |
|
|
475
475
|
|------|---------|
|
package/docs/development.md
CHANGED
package/docs/extensions.md
CHANGED
|
@@ -55,7 +55,7 @@ See [examples/extensions/](../examples/extensions/) for working implementations.
|
|
|
55
55
|
Create `~/.pi/agent/extensions/my-extension.ts`:
|
|
56
56
|
|
|
57
57
|
```typescript
|
|
58
|
-
import type { ExtensionAPI } from "@
|
|
58
|
+
import type { ExtensionAPI } from "@draht/coding-agent";
|
|
59
59
|
import { Type } from "@sinclair/typebox";
|
|
60
60
|
|
|
61
61
|
export default function (pi: ExtensionAPI) {
|
|
@@ -137,10 +137,10 @@ To share extensions via npm or git as pi packages, see [packages.md](packages.md
|
|
|
137
137
|
|
|
138
138
|
| Package | Purpose |
|
|
139
139
|
|---------|---------|
|
|
140
|
-
| `@
|
|
140
|
+
| `@draht/coding-agent` | Extension types (`ExtensionAPI`, `ExtensionContext`, events) |
|
|
141
141
|
| `@sinclair/typebox` | Schema definitions for tool parameters |
|
|
142
|
-
| `@
|
|
143
|
-
| `@
|
|
142
|
+
| `@draht/ai` | AI utilities (`StringEnum` for Google-compatible enums) |
|
|
143
|
+
| `@draht/tui` | TUI components for custom rendering |
|
|
144
144
|
|
|
145
145
|
npm dependencies work too. Add a `package.json` next to your extension (or in a parent directory), run `npm install`, and imports from `node_modules/` are resolved automatically.
|
|
146
146
|
|
|
@@ -151,7 +151,7 @@ Node.js built-ins (`node:fs`, `node:path`, etc.) are also available.
|
|
|
151
151
|
An extension exports a default function that receives `ExtensionAPI`:
|
|
152
152
|
|
|
153
153
|
```typescript
|
|
154
|
-
import type { ExtensionAPI } from "@
|
|
154
|
+
import type { ExtensionAPI } from "@draht/coding-agent";
|
|
155
155
|
|
|
156
156
|
export default function (pi: ExtensionAPI) {
|
|
157
157
|
// Subscribe to events
|
|
@@ -519,7 +519,7 @@ Use this to update UI elements (status bars, footers) or perform model-specific
|
|
|
519
519
|
Fired before tool executes. **Can block.** Use `isToolCallEventType` to narrow and get typed inputs.
|
|
520
520
|
|
|
521
521
|
```typescript
|
|
522
|
-
import { isToolCallEventType } from "@
|
|
522
|
+
import { isToolCallEventType } from "@draht/coding-agent";
|
|
523
523
|
|
|
524
524
|
pi.on("tool_call", async (event, ctx) => {
|
|
525
525
|
// event.toolName - "bash", "read", "write", "edit", etc.
|
|
@@ -553,7 +553,7 @@ export type MyToolInput = Static<typeof myToolSchema>;
|
|
|
553
553
|
Use `isToolCallEventType` with explicit type parameters:
|
|
554
554
|
|
|
555
555
|
```typescript
|
|
556
|
-
import { isToolCallEventType } from "@
|
|
556
|
+
import { isToolCallEventType } from "@draht/coding-agent";
|
|
557
557
|
import type { MyToolInput } from "my-extension";
|
|
558
558
|
|
|
559
559
|
pi.on("tool_call", (event) => {
|
|
@@ -573,7 +573,7 @@ Fired after tool executes. **Can modify result.**
|
|
|
573
573
|
- Handlers can return partial patches (`content`, `details`, or `isError`); omitted fields keep their current values
|
|
574
574
|
|
|
575
575
|
```typescript
|
|
576
|
-
import { isBashToolResult } from "@
|
|
576
|
+
import { isBashToolResult } from "@draht/coding-agent";
|
|
577
577
|
|
|
578
578
|
pi.on("tool_result", async (event, ctx) => {
|
|
579
579
|
// event.toolName, event.toolCallId, event.input
|
|
@@ -843,7 +843,7 @@ Tools run with `ExtensionContext`, so they cannot call `ctx.reload()` directly.
|
|
|
843
843
|
Example tool the LLM can call to trigger reload:
|
|
844
844
|
|
|
845
845
|
```typescript
|
|
846
|
-
import type { ExtensionAPI } from "@
|
|
846
|
+
import type { ExtensionAPI } from "@draht/coding-agent";
|
|
847
847
|
import { Type } from "@sinclair/typebox";
|
|
848
848
|
|
|
849
849
|
export default function (pi: ExtensionAPI) {
|
|
@@ -882,7 +882,7 @@ Register a custom tool callable by the LLM. See [Custom Tools](#custom-tools) fo
|
|
|
882
882
|
|
|
883
883
|
```typescript
|
|
884
884
|
import { Type } from "@sinclair/typebox";
|
|
885
|
-
import { StringEnum } from "@
|
|
885
|
+
import { StringEnum } from "@draht/ai";
|
|
886
886
|
|
|
887
887
|
pi.registerTool({
|
|
888
888
|
name: "my_tool",
|
|
@@ -1030,7 +1030,7 @@ pi.registerCommand("stats", {
|
|
|
1030
1030
|
Optional: add argument auto-completion for `/command ...`:
|
|
1031
1031
|
|
|
1032
1032
|
```typescript
|
|
1033
|
-
import type { AutocompleteItem } from "@
|
|
1033
|
+
import type { AutocompleteItem } from "@draht/tui";
|
|
1034
1034
|
|
|
1035
1035
|
pi.registerCommand("deploy", {
|
|
1036
1036
|
description: "Deploy to an environment",
|
|
@@ -1282,8 +1282,8 @@ Note: Some models are idiots and include the @ prefix in tool path arguments. Bu
|
|
|
1282
1282
|
|
|
1283
1283
|
```typescript
|
|
1284
1284
|
import { Type } from "@sinclair/typebox";
|
|
1285
|
-
import { StringEnum } from "@
|
|
1286
|
-
import { Text } from "@
|
|
1285
|
+
import { StringEnum } from "@draht/ai";
|
|
1286
|
+
import { Text } from "@draht/tui";
|
|
1287
1287
|
|
|
1288
1288
|
pi.registerTool({
|
|
1289
1289
|
name: "my_tool",
|
|
@@ -1322,7 +1322,7 @@ pi.registerTool({
|
|
|
1322
1322
|
});
|
|
1323
1323
|
```
|
|
1324
1324
|
|
|
1325
|
-
**Important:** Use `StringEnum` from `@
|
|
1325
|
+
**Important:** Use `StringEnum` from `@draht/ai` for string enums. `Type.Union`/`Type.Literal` doesn't work with Google's API.
|
|
1326
1326
|
|
|
1327
1327
|
### Overriding Built-in Tools
|
|
1328
1328
|
|
|
@@ -1346,20 +1346,20 @@ See [examples/extensions/tool-override.ts](../examples/extensions/tool-override.
|
|
|
1346
1346
|
**Your implementation must match the exact result shape**, including the `details` type. The UI and session logic depend on these shapes for rendering and state tracking.
|
|
1347
1347
|
|
|
1348
1348
|
Built-in tool implementations:
|
|
1349
|
-
- [read.ts](https://github.com/
|
|
1350
|
-
- [bash.ts](https://github.com/
|
|
1351
|
-
- [edit.ts](https://github.com/
|
|
1352
|
-
- [write.ts](https://github.com/
|
|
1353
|
-
- [grep.ts](https://github.com/
|
|
1354
|
-
- [find.ts](https://github.com/
|
|
1355
|
-
- [ls.ts](https://github.com/
|
|
1349
|
+
- [read.ts](https://github.com/draht-dev/draht/blob/main/packages/coding-agent/src/core/tools/read.ts) - `ReadToolDetails`
|
|
1350
|
+
- [bash.ts](https://github.com/draht-dev/draht/blob/main/packages/coding-agent/src/core/tools/bash.ts) - `BashToolDetails`
|
|
1351
|
+
- [edit.ts](https://github.com/draht-dev/draht/blob/main/packages/coding-agent/src/core/tools/edit.ts)
|
|
1352
|
+
- [write.ts](https://github.com/draht-dev/draht/blob/main/packages/coding-agent/src/core/tools/write.ts)
|
|
1353
|
+
- [grep.ts](https://github.com/draht-dev/draht/blob/main/packages/coding-agent/src/core/tools/grep.ts) - `GrepToolDetails`
|
|
1354
|
+
- [find.ts](https://github.com/draht-dev/draht/blob/main/packages/coding-agent/src/core/tools/find.ts) - `FindToolDetails`
|
|
1355
|
+
- [ls.ts](https://github.com/draht-dev/draht/blob/main/packages/coding-agent/src/core/tools/ls.ts) - `LsToolDetails`
|
|
1356
1356
|
|
|
1357
1357
|
### Remote Execution
|
|
1358
1358
|
|
|
1359
1359
|
Built-in tools support pluggable operations for delegating to remote systems (SSH, containers, etc.):
|
|
1360
1360
|
|
|
1361
1361
|
```typescript
|
|
1362
|
-
import { createReadTool, createBashTool, type ReadOperations } from "@
|
|
1362
|
+
import { createReadTool, createBashTool, type ReadOperations } from "@draht/coding-agent";
|
|
1363
1363
|
|
|
1364
1364
|
// Create tool with custom operations
|
|
1365
1365
|
const remoteRead = createReadTool(cwd, {
|
|
@@ -1388,7 +1388,7 @@ pi.registerTool({
|
|
|
1388
1388
|
The bash tool also supports a spawn hook to adjust the command, cwd, or env before execution:
|
|
1389
1389
|
|
|
1390
1390
|
```typescript
|
|
1391
|
-
import { createBashTool } from "@
|
|
1391
|
+
import { createBashTool } from "@draht/coding-agent";
|
|
1392
1392
|
|
|
1393
1393
|
const bashTool = createBashTool(cwd, {
|
|
1394
1394
|
spawnHook: ({ command, cwd, env }) => ({
|
|
@@ -1418,7 +1418,7 @@ import {
|
|
|
1418
1418
|
formatSize, // Human-readable size (e.g., "50KB", "1.5MB")
|
|
1419
1419
|
DEFAULT_MAX_BYTES, // 50KB
|
|
1420
1420
|
DEFAULT_MAX_LINES, // 2000
|
|
1421
|
-
} from "@
|
|
1421
|
+
} from "@draht/coding-agent";
|
|
1422
1422
|
|
|
1423
1423
|
async execute(toolCallId, params, signal, onUpdate, ctx) {
|
|
1424
1424
|
const output = await runCommand();
|
|
@@ -1473,7 +1473,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
1473
1473
|
|
|
1474
1474
|
### Custom Rendering
|
|
1475
1475
|
|
|
1476
|
-
Tools can provide `renderCall` and `renderResult` for custom TUI display. See [tui.md](tui.md) for the full component API and [tool-execution.ts](https://github.com/
|
|
1476
|
+
Tools can provide `renderCall` and `renderResult` for custom TUI display. See [tui.md](tui.md) for the full component API and [tool-execution.ts](https://github.com/draht-dev/draht/blob/main/packages/coding-agent/src/modes/interactive/components/tool-execution.ts) for how built-in tools render.
|
|
1477
1477
|
|
|
1478
1478
|
Tool output is wrapped in a `Box` that handles padding and background. Your render methods return `Component` instances (typically `Text`).
|
|
1479
1479
|
|
|
@@ -1482,7 +1482,7 @@ Tool output is wrapped in a `Box` that handles padding and background. Your rend
|
|
|
1482
1482
|
Renders the tool call (before/during execution):
|
|
1483
1483
|
|
|
1484
1484
|
```typescript
|
|
1485
|
-
import { Text } from "@
|
|
1485
|
+
import { Text } from "@draht/tui";
|
|
1486
1486
|
|
|
1487
1487
|
renderCall(args, theme) {
|
|
1488
1488
|
let text = theme.fg("toolTitle", theme.bold("my_tool "));
|
|
@@ -1526,7 +1526,7 @@ renderResult(result, { expanded, isPartial }, theme) {
|
|
|
1526
1526
|
Use `keyHint()` to display keybinding hints that respect user's keybinding configuration:
|
|
1527
1527
|
|
|
1528
1528
|
```typescript
|
|
1529
|
-
import { keyHint } from "@
|
|
1529
|
+
import { keyHint } from "@draht/coding-agent";
|
|
1530
1530
|
|
|
1531
1531
|
renderResult(result, { expanded }, theme) {
|
|
1532
1532
|
let text = theme.fg("success", "✓ Done");
|
|
@@ -1700,7 +1700,7 @@ ctx.ui.theme.fg("accent", "styled text"); // Access current theme
|
|
|
1700
1700
|
For complex UI, use `ctx.ui.custom()`. This temporarily replaces the editor with your component until `done()` is called:
|
|
1701
1701
|
|
|
1702
1702
|
```typescript
|
|
1703
|
-
import { Text, Component } from "@
|
|
1703
|
+
import { Text, Component } from "@draht/tui";
|
|
1704
1704
|
|
|
1705
1705
|
const result = await ctx.ui.custom<boolean>((tui, theme, keybindings, done) => {
|
|
1706
1706
|
const text = new Text("Press Enter to confirm, Escape to cancel", 1, 1);
|
|
@@ -1758,8 +1758,8 @@ See [tui.md](tui.md) for the full `OverlayOptions` API and [overlay-qa-tests.ts]
|
|
|
1758
1758
|
Replace the main input editor with a custom implementation (vim mode, emacs mode, etc.):
|
|
1759
1759
|
|
|
1760
1760
|
```typescript
|
|
1761
|
-
import { CustomEditor, type ExtensionAPI } from "@
|
|
1762
|
-
import { matchesKey } from "@
|
|
1761
|
+
import { CustomEditor, type ExtensionAPI } from "@draht/coding-agent";
|
|
1762
|
+
import { matchesKey } from "@draht/tui";
|
|
1763
1763
|
|
|
1764
1764
|
class VimEditor extends CustomEditor {
|
|
1765
1765
|
private mode: "normal" | "insert" = "insert";
|
|
@@ -1799,7 +1799,7 @@ See [tui.md](tui.md) Pattern 7 for a complete example with mode indicator.
|
|
|
1799
1799
|
Register a custom renderer for messages with your `customType`:
|
|
1800
1800
|
|
|
1801
1801
|
```typescript
|
|
1802
|
-
import { Text } from "@
|
|
1802
|
+
import { Text } from "@draht/tui";
|
|
1803
1803
|
|
|
1804
1804
|
pi.registerMessageRenderer("my-extension", (message, options, theme) => {
|
|
1805
1805
|
const { expanded } = options;
|
|
@@ -1848,7 +1848,7 @@ theme.strikethrough(text)
|
|
|
1848
1848
|
For syntax highlighting in custom tool renderers:
|
|
1849
1849
|
|
|
1850
1850
|
```typescript
|
|
1851
|
-
import { highlightCode, getLanguageFromPath } from "@
|
|
1851
|
+
import { highlightCode, getLanguageFromPath } from "@draht/coding-agent";
|
|
1852
1852
|
|
|
1853
1853
|
// Highlight code with explicit language
|
|
1854
1854
|
const highlighted = highlightCode("const x = 1;", "typescript", theme);
|
package/docs/json.md
CHANGED
|
@@ -8,7 +8,7 @@ Outputs all session events as JSON lines to stdout. Useful for integrating pi in
|
|
|
8
8
|
|
|
9
9
|
## Event Types
|
|
10
10
|
|
|
11
|
-
Events are defined in [`AgentSessionEvent`](https://github.com/
|
|
11
|
+
Events are defined in [`AgentSessionEvent`](https://github.com/draht-dev/draht/blob/main/packages/coding-agent/src/core/agent-session.ts#L102):
|
|
12
12
|
|
|
13
13
|
```typescript
|
|
14
14
|
type AgentSessionEvent =
|
|
@@ -19,7 +19,7 @@ type AgentSessionEvent =
|
|
|
19
19
|
| { type: "auto_retry_end"; success: boolean; attempt: number; finalError?: string };
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
Base events from [`AgentEvent`](https://github.com/
|
|
22
|
+
Base events from [`AgentEvent`](https://github.com/draht-dev/draht/blob/main/packages/agent/src/types.ts#L179):
|
|
23
23
|
|
|
24
24
|
```typescript
|
|
25
25
|
type AgentEvent =
|
|
@@ -41,12 +41,12 @@ type AgentEvent =
|
|
|
41
41
|
|
|
42
42
|
## Message Types
|
|
43
43
|
|
|
44
|
-
Base messages from [`packages/ai/src/types.ts`](https://github.com/
|
|
44
|
+
Base messages from [`packages/ai/src/types.ts`](https://github.com/draht-dev/draht/blob/main/packages/ai/src/types.ts#L134):
|
|
45
45
|
- `UserMessage` (line 134)
|
|
46
46
|
- `AssistantMessage` (line 140)
|
|
47
47
|
- `ToolResultMessage` (line 152)
|
|
48
48
|
|
|
49
|
-
Extended messages from [`packages/coding-agent/src/core/messages.ts`](https://github.com/
|
|
49
|
+
Extended messages from [`packages/coding-agent/src/core/messages.ts`](https://github.com/draht-dev/draht/blob/main/packages/coding-agent/src/core/messages.ts#L29):
|
|
50
50
|
- `BashExecutionMessage` (line 29)
|
|
51
51
|
- `CustomMessage` (line 46)
|
|
52
52
|
- `BranchSummaryMessage` (line 55)
|
package/docs/packages.md
CHANGED
|
@@ -149,7 +149,7 @@ If no `pi` manifest is present, pi auto-discovers resources from these directori
|
|
|
149
149
|
|
|
150
150
|
Third party runtime dependencies belong in `dependencies` in `package.json`. Dependencies that do not register extensions, skills, prompt templates, or themes also belong in `dependencies`. When pi installs a package from npm or git, it runs `npm install`, so those dependencies are installed automatically.
|
|
151
151
|
|
|
152
|
-
Pi bundles core packages for extensions and skills. If you import any of these, list them in `peerDependencies` with a `"*"` range and do not bundle them: `@
|
|
152
|
+
Pi bundles core packages for extensions and skills. If you import any of these, list them in `peerDependencies` with a `"*"` range and do not bundle them: `@draht/ai`, `@draht/agent-core-core`, `@draht/coding-agent`, `@draht/tui`, `@sinclair/typebox`.
|
|
153
153
|
|
|
154
154
|
Other pi packages must be bundled in your tarball. Add them to `dependencies` and `bundledDependencies`, then reference their resources through `node_modules/` paths. Pi loads packages with separate module roots, so separate installs do not collide or share modules.
|
|
155
155
|
|