@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
package/docs/providers.md
CHANGED
|
@@ -70,7 +70,7 @@ pi
|
|
|
70
70
|
| MiniMax | `MINIMAX_API_KEY` | `minimax` |
|
|
71
71
|
| MiniMax (China) | `MINIMAX_CN_API_KEY` | `minimax-cn` |
|
|
72
72
|
|
|
73
|
-
Reference for environment variables and `auth.json` keys: [`const envMap`](https://github.com/
|
|
73
|
+
Reference for environment variables and `auth.json` keys: [`const envMap`](https://github.com/draht-dev/draht/blob/main/packages/ai/src/env-api-keys.ts) in [`packages/ai/src/env-api-keys.ts`](https://github.com/draht-dev/draht/blob/main/packages/ai/src/env-api-keys.ts).
|
|
74
74
|
|
|
75
75
|
#### Auth File
|
|
76
76
|
|
package/docs/rpc.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
RPC mode enables headless operation of the coding agent via a JSON protocol over stdin/stdout. This is useful for embedding the agent in other applications, IDEs, or custom UIs.
|
|
4
4
|
|
|
5
|
-
**Note for Node.js/TypeScript users**: If you're building a Node.js application, consider using `AgentSession` directly from `@
|
|
5
|
+
**Note for Node.js/TypeScript users**: If you're building a Node.js application, consider using `AgentSession` directly from `@draht/coding-agent` instead of spawning a subprocess. See [`src/core/agent-session.ts`](../src/core/agent-session.ts) for the API. For a subprocess-based TypeScript client, see [`src/modes/rpc/rpc-client.ts`](../src/modes/rpc/rpc-client.ts).
|
|
6
6
|
|
|
7
7
|
## Starting RPC Mode
|
|
8
8
|
|
package/docs/sdk.md
CHANGED
|
@@ -16,7 +16,7 @@ See [examples/sdk/](../examples/sdk/) for working examples from minimal to full
|
|
|
16
16
|
## Quick Start
|
|
17
17
|
|
|
18
18
|
```typescript
|
|
19
|
-
import { AuthStorage, createAgentSession, ModelRegistry, SessionManager } from "@
|
|
19
|
+
import { AuthStorage, createAgentSession, ModelRegistry, SessionManager } from "@draht/coding-agent";
|
|
20
20
|
|
|
21
21
|
// Set up credential storage and model registry
|
|
22
22
|
const authStorage = AuthStorage.create();
|
|
@@ -40,7 +40,7 @@ await session.prompt("What files are in the current directory?");
|
|
|
40
40
|
## Installation
|
|
41
41
|
|
|
42
42
|
```bash
|
|
43
|
-
npm install @
|
|
43
|
+
npm install @draht/coding-agent
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
The SDK is included in the main package. No separate installation needed.
|
|
@@ -54,7 +54,7 @@ The main factory function. Creates an `AgentSession` with configurable options.
|
|
|
54
54
|
`createAgentSession()` uses a `ResourceLoader` to supply extensions, skills, prompt templates, themes, and context files. If you do not provide one, it uses `DefaultResourceLoader` with standard discovery.
|
|
55
55
|
|
|
56
56
|
```typescript
|
|
57
|
-
import { createAgentSession } from "@
|
|
57
|
+
import { createAgentSession } from "@draht/coding-agent";
|
|
58
58
|
|
|
59
59
|
// Minimal: defaults with DefaultResourceLoader
|
|
60
60
|
const { session } = await createAgentSession();
|
|
@@ -161,7 +161,7 @@ Both `steer()` and `followUp()` expand file-based prompt templates but error on
|
|
|
161
161
|
|
|
162
162
|
### Agent and AgentState
|
|
163
163
|
|
|
164
|
-
The `Agent` class (from `@
|
|
164
|
+
The `Agent` class (from `@draht/agent-core-core`) handles the core LLM interaction. Access it via `session.agent`.
|
|
165
165
|
|
|
166
166
|
```typescript
|
|
167
167
|
// Access current state
|
|
@@ -282,8 +282,8 @@ When you pass a custom `ResourceLoader`, `cwd` and `agentDir` no longer control
|
|
|
282
282
|
### Model
|
|
283
283
|
|
|
284
284
|
```typescript
|
|
285
|
-
import { getModel } from "@
|
|
286
|
-
import { AuthStorage, ModelRegistry } from "@
|
|
285
|
+
import { getModel } from "@draht/ai";
|
|
286
|
+
import { AuthStorage, ModelRegistry } from "@draht/coding-agent";
|
|
287
287
|
|
|
288
288
|
const authStorage = AuthStorage.create();
|
|
289
289
|
const modelRegistry = new ModelRegistry(authStorage);
|
|
@@ -330,7 +330,7 @@ API key resolution priority (handled by AuthStorage):
|
|
|
330
330
|
4. Fallback resolver (for custom provider keys from `models.json`)
|
|
331
331
|
|
|
332
332
|
```typescript
|
|
333
|
-
import { AuthStorage, ModelRegistry } from "@
|
|
333
|
+
import { AuthStorage, ModelRegistry } from "@draht/coding-agent";
|
|
334
334
|
|
|
335
335
|
// Default: uses ~/.pi/agent/auth.json and ~/.pi/agent/models.json
|
|
336
336
|
const authStorage = AuthStorage.create();
|
|
@@ -366,7 +366,7 @@ const simpleRegistry = new ModelRegistry(authStorage);
|
|
|
366
366
|
Use a `ResourceLoader` to override the system prompt:
|
|
367
367
|
|
|
368
368
|
```typescript
|
|
369
|
-
import { createAgentSession, DefaultResourceLoader } from "@
|
|
369
|
+
import { createAgentSession, DefaultResourceLoader } from "@draht/coding-agent";
|
|
370
370
|
|
|
371
371
|
const loader = new DefaultResourceLoader({
|
|
372
372
|
systemPromptOverride: () => "You are a helpful assistant.",
|
|
@@ -386,7 +386,7 @@ import {
|
|
|
386
386
|
readOnlyTools, // read, grep, find, ls
|
|
387
387
|
readTool, bashTool, editTool, writeTool,
|
|
388
388
|
grepTool, findTool, lsTool,
|
|
389
|
-
} from "@
|
|
389
|
+
} from "@draht/coding-agent";
|
|
390
390
|
|
|
391
391
|
// Use built-in tool set
|
|
392
392
|
const { session } = await createAgentSession({
|
|
@@ -414,7 +414,7 @@ import {
|
|
|
414
414
|
createGrepTool,
|
|
415
415
|
createFindTool,
|
|
416
416
|
createLsTool,
|
|
417
|
-
} from "@
|
|
417
|
+
} from "@draht/coding-agent";
|
|
418
418
|
|
|
419
419
|
const cwd = "/path/to/project";
|
|
420
420
|
|
|
@@ -444,7 +444,7 @@ const { session } = await createAgentSession({
|
|
|
444
444
|
|
|
445
445
|
```typescript
|
|
446
446
|
import { Type } from "@sinclair/typebox";
|
|
447
|
-
import { createAgentSession, type ToolDefinition } from "@
|
|
447
|
+
import { createAgentSession, type ToolDefinition } from "@draht/coding-agent";
|
|
448
448
|
|
|
449
449
|
// Inline custom tool
|
|
450
450
|
const myTool: ToolDefinition = {
|
|
@@ -475,7 +475,7 @@ Custom tools passed via `customTools` are combined with extension-registered too
|
|
|
475
475
|
Extensions are loaded by the `ResourceLoader`. `DefaultResourceLoader` discovers extensions from `~/.pi/agent/extensions/`, `.pi/extensions/`, and settings.json extension sources.
|
|
476
476
|
|
|
477
477
|
```typescript
|
|
478
|
-
import { createAgentSession, DefaultResourceLoader } from "@
|
|
478
|
+
import { createAgentSession, DefaultResourceLoader } from "@draht/coding-agent";
|
|
479
479
|
|
|
480
480
|
const loader = new DefaultResourceLoader({
|
|
481
481
|
additionalExtensionPaths: ["/path/to/my-extension.ts"],
|
|
@@ -497,7 +497,7 @@ Extensions can register tools, subscribe to events, add commands, and more. See
|
|
|
497
497
|
**Event Bus:** Extensions can communicate via `pi.events`. Pass a shared `eventBus` to `DefaultResourceLoader` if you need to emit or listen from outside:
|
|
498
498
|
|
|
499
499
|
```typescript
|
|
500
|
-
import { createEventBus, DefaultResourceLoader } from "@
|
|
500
|
+
import { createEventBus, DefaultResourceLoader } from "@draht/coding-agent";
|
|
501
501
|
|
|
502
502
|
const eventBus = createEventBus();
|
|
503
503
|
const loader = new DefaultResourceLoader({
|
|
@@ -517,7 +517,7 @@ import {
|
|
|
517
517
|
createAgentSession,
|
|
518
518
|
DefaultResourceLoader,
|
|
519
519
|
type Skill,
|
|
520
|
-
} from "@
|
|
520
|
+
} from "@draht/coding-agent";
|
|
521
521
|
|
|
522
522
|
const customSkill: Skill = {
|
|
523
523
|
name: "my-skill",
|
|
@@ -543,7 +543,7 @@ const { session } = await createAgentSession({ resourceLoader: loader });
|
|
|
543
543
|
### Context Files
|
|
544
544
|
|
|
545
545
|
```typescript
|
|
546
|
-
import { createAgentSession, DefaultResourceLoader } from "@
|
|
546
|
+
import { createAgentSession, DefaultResourceLoader } from "@draht/coding-agent";
|
|
547
547
|
|
|
548
548
|
const loader = new DefaultResourceLoader({
|
|
549
549
|
agentsFilesOverride: (current) => ({
|
|
@@ -567,7 +567,7 @@ import {
|
|
|
567
567
|
createAgentSession,
|
|
568
568
|
DefaultResourceLoader,
|
|
569
569
|
type PromptTemplate,
|
|
570
|
-
} from "@
|
|
570
|
+
} from "@draht/coding-agent";
|
|
571
571
|
|
|
572
572
|
const customCommand: PromptTemplate = {
|
|
573
573
|
name: "deploy",
|
|
@@ -594,7 +594,7 @@ const { session } = await createAgentSession({ resourceLoader: loader });
|
|
|
594
594
|
Sessions use a tree structure with `id`/`parentId` linking, enabling in-place branching.
|
|
595
595
|
|
|
596
596
|
```typescript
|
|
597
|
-
import { createAgentSession, SessionManager } from "@
|
|
597
|
+
import { createAgentSession, SessionManager } from "@draht/coding-agent";
|
|
598
598
|
|
|
599
599
|
// In-memory (no persistence)
|
|
600
600
|
const { session } = await createAgentSession({
|
|
@@ -665,7 +665,7 @@ sm.createBranchedSession(leafId); // Extract path to new file
|
|
|
665
665
|
### Settings Management
|
|
666
666
|
|
|
667
667
|
```typescript
|
|
668
|
-
import { createAgentSession, SettingsManager, SessionManager } from "@
|
|
668
|
+
import { createAgentSession, SettingsManager, SessionManager } from "@draht/coding-agent";
|
|
669
669
|
|
|
670
670
|
// Default: loads from files (global + project merged)
|
|
671
671
|
const { session } = await createAgentSession({
|
|
@@ -721,7 +721,7 @@ Use `DefaultResourceLoader` to discover extensions, skills, prompts, themes, and
|
|
|
721
721
|
import {
|
|
722
722
|
DefaultResourceLoader,
|
|
723
723
|
getAgentDir,
|
|
724
|
-
} from "@
|
|
724
|
+
} from "@draht/coding-agent";
|
|
725
725
|
|
|
726
726
|
const loader = new DefaultResourceLoader({
|
|
727
727
|
cwd,
|
|
@@ -762,7 +762,7 @@ interface LoadExtensionsResult {
|
|
|
762
762
|
## Complete Example
|
|
763
763
|
|
|
764
764
|
```typescript
|
|
765
|
-
import { getModel } from "@
|
|
765
|
+
import { getModel } from "@draht/ai";
|
|
766
766
|
import { Type } from "@sinclair/typebox";
|
|
767
767
|
import {
|
|
768
768
|
AuthStorage,
|
|
@@ -774,7 +774,7 @@ import {
|
|
|
774
774
|
readTool,
|
|
775
775
|
bashTool,
|
|
776
776
|
type ToolDefinition,
|
|
777
|
-
} from "@
|
|
777
|
+
} from "@draht/coding-agent";
|
|
778
778
|
|
|
779
779
|
// Set up auth storage (custom location)
|
|
780
780
|
const authStorage = AuthStorage.create("/custom/agent/auth.json");
|
|
@@ -851,7 +851,7 @@ The SDK exports run mode utilities for building custom interfaces on top of `cre
|
|
|
851
851
|
Full TUI interactive mode with editor, chat history, and all built-in commands:
|
|
852
852
|
|
|
853
853
|
```typescript
|
|
854
|
-
import { createAgentSession, InteractiveMode } from "@
|
|
854
|
+
import { createAgentSession, InteractiveMode } from "@draht/coding-agent";
|
|
855
855
|
|
|
856
856
|
const { session } = await createAgentSession({ /* ... */ });
|
|
857
857
|
|
|
@@ -872,7 +872,7 @@ await mode.run(); // Blocks until exit
|
|
|
872
872
|
Single-shot mode: send prompts, output result, exit:
|
|
873
873
|
|
|
874
874
|
```typescript
|
|
875
|
-
import { createAgentSession, runPrintMode } from "@
|
|
875
|
+
import { createAgentSession, runPrintMode } from "@draht/coding-agent";
|
|
876
876
|
|
|
877
877
|
const { session } = await createAgentSession({ /* ... */ });
|
|
878
878
|
|
|
@@ -889,7 +889,7 @@ await runPrintMode(session, {
|
|
|
889
889
|
JSON-RPC mode for subprocess integration:
|
|
890
890
|
|
|
891
891
|
```typescript
|
|
892
|
-
import { createAgentSession, runRpcMode } from "@
|
|
892
|
+
import { createAgentSession, runRpcMode } from "@draht/coding-agent";
|
|
893
893
|
|
|
894
894
|
const { session } = await createAgentSession({ /* ... */ });
|
|
895
895
|
|
package/docs/session.md
CHANGED
|
@@ -28,13 +28,13 @@ Existing sessions are automatically migrated to the current version (v3) when lo
|
|
|
28
28
|
|
|
29
29
|
## Source Files
|
|
30
30
|
|
|
31
|
-
Source on GitHub ([pi-mono](https://github.com/
|
|
32
|
-
- [`packages/coding-agent/src/core/session-manager.ts`](https://github.com/
|
|
33
|
-
- [`packages/coding-agent/src/core/messages.ts`](https://github.com/
|
|
34
|
-
- [`packages/ai/src/types.ts`](https://github.com/
|
|
35
|
-
- [`packages/agent/src/types.ts`](https://github.com/
|
|
31
|
+
Source on GitHub ([pi-mono](https://github.com/draht-dev/draht)):
|
|
32
|
+
- [`packages/coding-agent/src/core/session-manager.ts`](https://github.com/draht-dev/draht/blob/main/packages/coding-agent/src/core/session-manager.ts) - Session entry types and SessionManager
|
|
33
|
+
- [`packages/coding-agent/src/core/messages.ts`](https://github.com/draht-dev/draht/blob/main/packages/coding-agent/src/core/messages.ts) - Extended message types (BashExecutionMessage, CustomMessage, etc.)
|
|
34
|
+
- [`packages/ai/src/types.ts`](https://github.com/draht-dev/draht/blob/main/packages/ai/src/types.ts) - Base message types (UserMessage, AssistantMessage, ToolResultMessage)
|
|
35
|
+
- [`packages/agent/src/types.ts`](https://github.com/draht-dev/draht/blob/main/packages/agent/src/types.ts) - AgentMessage union type
|
|
36
36
|
|
|
37
|
-
For TypeScript definitions in your project, inspect `node_modules/@
|
|
37
|
+
For TypeScript definitions in your project, inspect `node_modules/@draht/coding-agent/dist/` and `node_modules/@draht/ai/dist/`.
|
|
38
38
|
|
|
39
39
|
## Message Types
|
|
40
40
|
|
package/docs/termux.md
CHANGED
package/docs/themes.md
CHANGED
|
@@ -52,7 +52,7 @@ vim ~/.pi/agent/themes/my-theme.json
|
|
|
52
52
|
|
|
53
53
|
```json
|
|
54
54
|
{
|
|
55
|
-
"$schema": "https://raw.githubusercontent.com/
|
|
55
|
+
"$schema": "https://raw.githubusercontent.com/draht-dev/draht/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
|
|
56
56
|
"name": "my-theme",
|
|
57
57
|
"vars": {
|
|
58
58
|
"primary": "#00aaff",
|
|
@@ -122,7 +122,7 @@ vim ~/.pi/agent/themes/my-theme.json
|
|
|
122
122
|
|
|
123
123
|
```json
|
|
124
124
|
{
|
|
125
|
-
"$schema": "https://raw.githubusercontent.com/
|
|
125
|
+
"$schema": "https://raw.githubusercontent.com/draht-dev/draht/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
|
|
126
126
|
"name": "my-theme",
|
|
127
127
|
"vars": {
|
|
128
128
|
"blue": "#0066cc",
|
package/docs/tui.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
Extensions and custom tools can render custom TUI components for interactive user interfaces. This page covers the component system and available building blocks.
|
|
6
6
|
|
|
7
|
-
**Source:** [`@
|
|
7
|
+
**Source:** [`@draht/tui`](https://github.com/draht-dev/draht/tree/main/packages/tui)
|
|
8
8
|
|
|
9
9
|
## Component Interface
|
|
10
10
|
|
|
@@ -33,7 +33,7 @@ The TUI appends a full SGR reset and OSC 8 reset at the end of each rendered lin
|
|
|
33
33
|
Components that display a text cursor and need IME (Input Method Editor) support should implement the `Focusable` interface:
|
|
34
34
|
|
|
35
35
|
```typescript
|
|
36
|
-
import { CURSOR_MARKER, type Component, type Focusable } from "@
|
|
36
|
+
import { CURSOR_MARKER, type Component, type Focusable } from "@draht/tui";
|
|
37
37
|
|
|
38
38
|
class MyInput implements Component, Focusable {
|
|
39
39
|
focused: boolean = false; // Set by TUI when focus changes
|
|
@@ -59,7 +59,7 @@ This enables IME candidate windows to appear at the correct position for CJK inp
|
|
|
59
59
|
When a container component (dialog, selector, etc.) contains an `Input` or `Editor` child, the container must implement `Focusable` and propagate the focus state to the child. Otherwise, the hardware cursor won't be positioned correctly for IME input.
|
|
60
60
|
|
|
61
61
|
```typescript
|
|
62
|
-
import { Container, type Focusable, Input } from "@
|
|
62
|
+
import { Container, type Focusable, Input } from "@draht/tui";
|
|
63
63
|
|
|
64
64
|
class SearchDialog extends Container implements Focusable {
|
|
65
65
|
private searchInput: Input;
|
|
@@ -179,10 +179,10 @@ See [overlay-qa-tests.ts](../examples/extensions/overlay-qa-tests.ts) for compre
|
|
|
179
179
|
|
|
180
180
|
## Built-in Components
|
|
181
181
|
|
|
182
|
-
Import from `@
|
|
182
|
+
Import from `@draht/tui`:
|
|
183
183
|
|
|
184
184
|
```typescript
|
|
185
|
-
import { Text, Box, Container, Spacer, Markdown } from "@
|
|
185
|
+
import { Text, Box, Container, Spacer, Markdown } from "@draht/tui";
|
|
186
186
|
```
|
|
187
187
|
|
|
188
188
|
### Text
|
|
@@ -264,7 +264,7 @@ const image = new Image(
|
|
|
264
264
|
Use `matchesKey()` for key detection:
|
|
265
265
|
|
|
266
266
|
```typescript
|
|
267
|
-
import { matchesKey, Key } from "@
|
|
267
|
+
import { matchesKey, Key } from "@draht/tui";
|
|
268
268
|
|
|
269
269
|
handleInput(data: string) {
|
|
270
270
|
if (matchesKey(data, Key.up)) {
|
|
@@ -290,7 +290,7 @@ handleInput(data: string) {
|
|
|
290
290
|
**Critical:** Each line from `render()` must not exceed the `width` parameter.
|
|
291
291
|
|
|
292
292
|
```typescript
|
|
293
|
-
import { visibleWidth, truncateToWidth } from "@
|
|
293
|
+
import { visibleWidth, truncateToWidth } from "@draht/tui";
|
|
294
294
|
|
|
295
295
|
render(width: number): string[] {
|
|
296
296
|
// Truncate long lines
|
|
@@ -311,7 +311,7 @@ Example: Interactive selector
|
|
|
311
311
|
import {
|
|
312
312
|
matchesKey, Key,
|
|
313
313
|
truncateToWidth, visibleWidth
|
|
314
|
-
} from "@
|
|
314
|
+
} from "@draht/tui";
|
|
315
315
|
|
|
316
316
|
class MySelector {
|
|
317
317
|
private items: string[];
|
|
@@ -425,8 +425,8 @@ renderResult(result, options, theme) {
|
|
|
425
425
|
**For Markdown**, use `getMarkdownTheme()`:
|
|
426
426
|
|
|
427
427
|
```typescript
|
|
428
|
-
import { getMarkdownTheme } from "@
|
|
429
|
-
import { Markdown } from "@
|
|
428
|
+
import { getMarkdownTheme } from "@draht/coding-agent";
|
|
429
|
+
import { Markdown } from "@draht/tui";
|
|
430
430
|
|
|
431
431
|
renderResult(result, options, theme) {
|
|
432
432
|
const mdTheme = getMarkdownTheme();
|
|
@@ -587,12 +587,12 @@ These patterns cover the most common UI needs in extensions. **Copy these patter
|
|
|
587
587
|
|
|
588
588
|
### Pattern 1: Selection Dialog (SelectList)
|
|
589
589
|
|
|
590
|
-
For letting users pick from a list of options. Use `SelectList` from `@
|
|
590
|
+
For letting users pick from a list of options. Use `SelectList` from `@draht/tui` with `DynamicBorder` for framing.
|
|
591
591
|
|
|
592
592
|
```typescript
|
|
593
|
-
import type { ExtensionAPI } from "@
|
|
594
|
-
import { DynamicBorder } from "@
|
|
595
|
-
import { Container, type SelectItem, SelectList, Text } from "@
|
|
593
|
+
import type { ExtensionAPI } from "@draht/coding-agent";
|
|
594
|
+
import { DynamicBorder } from "@draht/coding-agent";
|
|
595
|
+
import { Container, type SelectItem, SelectList, Text } from "@draht/tui";
|
|
596
596
|
|
|
597
597
|
pi.registerCommand("pick", {
|
|
598
598
|
handler: async (_args, ctx) => {
|
|
@@ -650,7 +650,7 @@ pi.registerCommand("pick", {
|
|
|
650
650
|
For operations that take time and should be cancellable. `BorderedLoader` shows a spinner and handles escape to cancel.
|
|
651
651
|
|
|
652
652
|
```typescript
|
|
653
|
-
import { BorderedLoader } from "@
|
|
653
|
+
import { BorderedLoader } from "@draht/coding-agent";
|
|
654
654
|
|
|
655
655
|
pi.registerCommand("fetch", {
|
|
656
656
|
handler: async (_args, ctx) => {
|
|
@@ -679,11 +679,11 @@ pi.registerCommand("fetch", {
|
|
|
679
679
|
|
|
680
680
|
### Pattern 3: Settings/Toggles (SettingsList)
|
|
681
681
|
|
|
682
|
-
For toggling multiple settings. Use `SettingsList` from `@
|
|
682
|
+
For toggling multiple settings. Use `SettingsList` from `@draht/tui` with `getSettingsListTheme()`.
|
|
683
683
|
|
|
684
684
|
```typescript
|
|
685
|
-
import { getSettingsListTheme } from "@
|
|
686
|
-
import { Container, type SettingItem, SettingsList, Text } from "@
|
|
685
|
+
import { getSettingsListTheme } from "@draht/coding-agent";
|
|
686
|
+
import { Container, type SettingItem, SettingsList, Text } from "@draht/tui";
|
|
687
687
|
|
|
688
688
|
pi.registerCommand("settings", {
|
|
689
689
|
handler: async (_args, ctx) => {
|
|
@@ -792,8 +792,8 @@ Token stats available via `ctx.sessionManager.getBranch()` and `ctx.model`.
|
|
|
792
792
|
Replace the main input editor with a custom implementation. Useful for modal editing (vim), different keybindings (emacs), or specialized input handling.
|
|
793
793
|
|
|
794
794
|
```typescript
|
|
795
|
-
import { CustomEditor, type ExtensionAPI } from "@
|
|
796
|
-
import { matchesKey, truncateToWidth } from "@
|
|
795
|
+
import { CustomEditor, type ExtensionAPI } from "@draht/coding-agent";
|
|
796
|
+
import { matchesKey, truncateToWidth } from "@draht/tui";
|
|
797
797
|
|
|
798
798
|
type Mode = "normal" | "insert";
|
|
799
799
|
|
|
@@ -9,7 +9,7 @@ Example extensions for pi-coding-agent.
|
|
|
9
9
|
pi --extension examples/extensions/permission-gate.ts
|
|
10
10
|
|
|
11
11
|
# Or copy to extensions directory for auto-discovery
|
|
12
|
-
cp permission-gate.ts ~/.
|
|
12
|
+
cp permission-gate.ts ~/.draht/agent/extensions/
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
## Examples
|
|
@@ -91,7 +91,7 @@ cp permission-gate.ts ~/.pi/agent/extensions/
|
|
|
91
91
|
|
|
92
92
|
| Extension | Description |
|
|
93
93
|
|-----------|-------------|
|
|
94
|
-
| `mac-system-theme.ts` | Syncs
|
|
94
|
+
| `mac-system-theme.ts` | Syncs draht theme with macOS dark/light mode |
|
|
95
95
|
|
|
96
96
|
### Resources
|
|
97
97
|
|
|
@@ -133,7 +133,7 @@ cp permission-gate.ts ~/.pi/agent/extensions/
|
|
|
133
133
|
See [docs/extensions.md](../../docs/extensions.md) for full documentation.
|
|
134
134
|
|
|
135
135
|
```typescript
|
|
136
|
-
import type { ExtensionAPI } from "@
|
|
136
|
+
import type { ExtensionAPI } from "@draht/coding-agent";
|
|
137
137
|
import { Type } from "@sinclair/typebox";
|
|
138
138
|
|
|
139
139
|
export default function (pi: ExtensionAPI) {
|
|
@@ -175,7 +175,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
175
175
|
|
|
176
176
|
**Use StringEnum for string parameters** (required for Google API compatibility):
|
|
177
177
|
```typescript
|
|
178
|
-
import { StringEnum } from "@
|
|
178
|
+
import { StringEnum } from "@draht/ai";
|
|
179
179
|
|
|
180
180
|
// Good
|
|
181
181
|
action: StringEnum(["list", "add"] as const)
|
|
@@ -43,4 +43,4 @@ Height is calculated from width to maintain DOOM's 3.2:1 aspect ratio (accountin
|
|
|
43
43
|
|
|
44
44
|
- [id Software](https://github.com/id-Software/DOOM) for the original DOOM
|
|
45
45
|
- [doomgeneric](https://github.com/ozkl/doomgeneric) for the portable DOOM implementation
|
|
46
|
-
- [pi-doom](https://github.com/badlogic/pi-doom) for the original
|
|
46
|
+
- [pi-doom](https://github.com/badlogic/pi-doom) for the original draht integration
|
|
@@ -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": "dynamic-resources",
|
|
4
4
|
"vars": {
|
|
5
5
|
"cyan": "#00d7ff",
|
|
@@ -35,20 +35,20 @@ From the repository root, symlink the files:
|
|
|
35
35
|
|
|
36
36
|
```bash
|
|
37
37
|
# Symlink the extension (must be in a subdirectory with index.ts)
|
|
38
|
-
mkdir -p ~/.
|
|
39
|
-
ln -sf "$(pwd)/packages/coding-agent/examples/extensions/subagent/index.ts" ~/.
|
|
40
|
-
ln -sf "$(pwd)/packages/coding-agent/examples/extensions/subagent/agents.ts" ~/.
|
|
38
|
+
mkdir -p ~/.draht/agent/extensions/subagent
|
|
39
|
+
ln -sf "$(pwd)/packages/coding-agent/examples/extensions/subagent/index.ts" ~/.draht/agent/extensions/subagent/index.ts
|
|
40
|
+
ln -sf "$(pwd)/packages/coding-agent/examples/extensions/subagent/agents.ts" ~/.draht/agent/extensions/subagent/agents.ts
|
|
41
41
|
|
|
42
42
|
# Symlink agents
|
|
43
|
-
mkdir -p ~/.
|
|
43
|
+
mkdir -p ~/.draht/agent/agents
|
|
44
44
|
for f in packages/coding-agent/examples/extensions/subagent/agents/*.md; do
|
|
45
|
-
ln -sf "$(pwd)/$f" ~/.
|
|
45
|
+
ln -sf "$(pwd)/$f" ~/.draht/agent/agents/$(basename "$f")
|
|
46
46
|
done
|
|
47
47
|
|
|
48
48
|
# Symlink workflow prompts
|
|
49
|
-
mkdir -p ~/.
|
|
49
|
+
mkdir -p ~/.draht/agent/prompts
|
|
50
50
|
for f in packages/coding-agent/examples/extensions/subagent/prompts/*.md; do
|
|
51
|
-
ln -sf "$(pwd)/$f" ~/.
|
|
51
|
+
ln -sf "$(pwd)/$f" ~/.draht/agent/prompts/$(basename "$f")
|
|
52
52
|
done
|
|
53
53
|
```
|
|
54
54
|
|
|
@@ -56,9 +56,9 @@ done
|
|
|
56
56
|
|
|
57
57
|
This tool executes a separate `pi` subprocess with a delegated system prompt and tool/model configuration.
|
|
58
58
|
|
|
59
|
-
**Project-local agents** (`.
|
|
59
|
+
**Project-local agents** (`.draht/agents/*.md`) are repo-controlled prompts that can instruct the model to read files, run bash commands, etc.
|
|
60
60
|
|
|
61
|
-
**Default behavior:** Only loads **user-level agents** from `~/.
|
|
61
|
+
**Default behavior:** Only loads **user-level agents** from `~/.draht/agent/agents`.
|
|
62
62
|
|
|
63
63
|
To enable project-local agents, pass `agentScope: "both"` (or `"project"`). Only do this for repositories you trust.
|
|
64
64
|
|
|
@@ -136,8 +136,8 @@ System prompt for the agent goes here.
|
|
|
136
136
|
```
|
|
137
137
|
|
|
138
138
|
**Locations:**
|
|
139
|
-
- `~/.
|
|
140
|
-
- `.
|
|
139
|
+
- `~/.draht/agent/agents/*.md` - User-level (always loaded)
|
|
140
|
+
- `.draht/agents/*.md` - Project-level (only with `agentScope: "project"` or `"both"`)
|
|
141
141
|
|
|
142
142
|
Project agents override user agents with the same name when `agentScope: "both"`.
|
|
143
143
|
|
package/examples/sdk/README.md
CHANGED
|
@@ -29,7 +29,7 @@ npx tsx examples/sdk/01-minimal.ts
|
|
|
29
29
|
## Quick Reference
|
|
30
30
|
|
|
31
31
|
```typescript
|
|
32
|
-
import { getModel } from "@
|
|
32
|
+
import { getModel } from "@draht/ai";
|
|
33
33
|
import {
|
|
34
34
|
AuthStorage,
|
|
35
35
|
createAgentSession,
|
|
@@ -40,7 +40,7 @@ import {
|
|
|
40
40
|
codingTools,
|
|
41
41
|
readOnlyTools,
|
|
42
42
|
readTool, bashTool, editTool, writeTool,
|
|
43
|
-
} from "@
|
|
43
|
+
} from "@draht/coding-agent";
|
|
44
44
|
|
|
45
45
|
// Auth and models setup
|
|
46
46
|
const authStorage = AuthStorage.create();
|
|
@@ -111,7 +111,7 @@ await session.prompt("Hello");
|
|
|
111
111
|
| `authStorage` | `AuthStorage.create()` | Credential storage |
|
|
112
112
|
| `modelRegistry` | `new ModelRegistry(authStorage)` | Model registry |
|
|
113
113
|
| `cwd` | `process.cwd()` | Working directory |
|
|
114
|
-
| `agentDir` | `~/.
|
|
114
|
+
| `agentDir` | `~/.draht/agent` | Config directory |
|
|
115
115
|
| `model` | From settings/first available | Model to use |
|
|
116
116
|
| `thinkingLevel` | From settings/"off" | off, low, medium, high |
|
|
117
117
|
| `tools` | `codingTools` | Built-in tools |
|
|
@@ -13,8 +13,9 @@
|
|
|
13
13
|
* /review <scope> — ad-hoc code review + security audit
|
|
14
14
|
* /fix <issue> — targeted fix plan for a failing task
|
|
15
15
|
* /quick <task> — one-shot implement + commit (skip full GSD)
|
|
16
|
-
* /
|
|
16
|
+
* /continue — pick up interrupted work from CONTINUE-HERE.md
|
|
17
17
|
* /status — show .planning/STATE.md overview
|
|
18
|
+
* /next-milestone — plan next milestone after current one is complete
|
|
18
19
|
* /new-project <name> [path] — create project dir, git init, scaffold .draht/
|
|
19
20
|
* /init-project — scaffold .draht/ in existing project
|
|
20
21
|
*/
|
|
@@ -183,9 +184,9 @@ After both complete, merge into a single prioritized findings report.`,
|
|
|
183
184
|
},
|
|
184
185
|
});
|
|
185
186
|
|
|
186
|
-
// ── /
|
|
187
|
-
pi.registerCommand("
|
|
188
|
-
description: "
|
|
187
|
+
// ── /continue ────────────────────────────────────────────────────────────
|
|
188
|
+
pi.registerCommand("continue", {
|
|
189
|
+
description: "Continue interrupted work — reads CONTINUE-HERE.md and picks up where we left off",
|
|
189
190
|
handler: async (_args, ctx) => {
|
|
190
191
|
if (isBusy(ctx, ctx.ui)) return;
|
|
191
192
|
|
|
@@ -241,6 +242,70 @@ After both complete, merge into a single prioritized findings report.`,
|
|
|
241
242
|
},
|
|
242
243
|
});
|
|
243
244
|
|
|
245
|
+
// ── /next-milestone ──────────────────────────────────────────────────────
|
|
246
|
+
pi.registerCommand("next-milestone", {
|
|
247
|
+
description: "Plan the next milestone after the current one is complete — review progress, update requirements, create new phases",
|
|
248
|
+
handler: async (_args, ctx) => {
|
|
249
|
+
if (isBusy(ctx, ctx.ui)) return;
|
|
250
|
+
|
|
251
|
+
const planningDir = path.join(ctx.cwd, ".planning");
|
|
252
|
+
const roadmapFile = path.join(planningDir, "ROADMAP.md");
|
|
253
|
+
const stateFile = path.join(planningDir, "STATE.md");
|
|
254
|
+
const requirementsFile = path.join(planningDir, "REQUIREMENTS.md");
|
|
255
|
+
|
|
256
|
+
if (!fs.existsSync(roadmapFile)) {
|
|
257
|
+
ctx.ui.notify("No .planning/ROADMAP.md found. Run /new-project first.", "warning");
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
let context = `\nROADMAP.md:\n${fs.readFileSync(roadmapFile, "utf-8")}`;
|
|
262
|
+
if (fs.existsSync(stateFile)) {
|
|
263
|
+
context += `\nSTATE.md:\n${fs.readFileSync(stateFile, "utf-8")}`;
|
|
264
|
+
}
|
|
265
|
+
if (fs.existsSync(requirementsFile)) {
|
|
266
|
+
context += `\nREQUIREMENTS.md:\n${fs.readFileSync(requirementsFile, "utf-8")}`;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Collect UAT and summary files for completed phases
|
|
270
|
+
const phasesDir = path.join(planningDir, "phases");
|
|
271
|
+
if (fs.existsSync(phasesDir)) {
|
|
272
|
+
for (const dir of fs.readdirSync(phasesDir)) {
|
|
273
|
+
const phaseDir = path.join(phasesDir, dir);
|
|
274
|
+
if (!fs.statSync(phaseDir).isDirectory()) continue;
|
|
275
|
+
for (const file of fs.readdirSync(phaseDir)) {
|
|
276
|
+
if (file.endsWith("-UAT.md") || file.endsWith("-SUMMARY.md")) {
|
|
277
|
+
context += `\n${dir}/${file}:\n${fs.readFileSync(path.join(phaseDir, file), "utf-8")}`;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
pi.sendUserMessage(
|
|
284
|
+
`Use the subagent tool to delegate to the architect agent with this task:
|
|
285
|
+
|
|
286
|
+
"We have completed a milestone. Your job is to plan the NEXT milestone.
|
|
287
|
+
|
|
288
|
+
1. Read the current ROADMAP.md and identify the completed milestone and its phases
|
|
289
|
+
2. Review all UAT reports and summaries to understand what was built
|
|
290
|
+
3. Review REQUIREMENTS.md — identify which v1 requirements are now satisfied and which remain
|
|
291
|
+
4. Assess if any v2 requirements should be promoted to the next milestone based on what we learned
|
|
292
|
+
5. Propose the next milestone with new phases:
|
|
293
|
+
- Each phase has a clear goal (outcome, not activity)
|
|
294
|
+
- Phases are ordered by dependency
|
|
295
|
+
- Map phases to remaining/new requirements
|
|
296
|
+
6. Update ROADMAP.md with the new milestone and phases
|
|
297
|
+
7. Update STATE.md to reflect milestone transition
|
|
298
|
+
8. Update REQUIREMENTS.md if requirements changed based on learnings
|
|
299
|
+
|
|
300
|
+
Present the proposed milestone for user approval before writing files.
|
|
301
|
+
|
|
302
|
+
Project context:${context}"
|
|
303
|
+
|
|
304
|
+
Set agentScope to "project".`,
|
|
305
|
+
);
|
|
306
|
+
},
|
|
307
|
+
});
|
|
308
|
+
|
|
244
309
|
// ── /new-project ─────────────────────────────────────────────────────────
|
|
245
310
|
pi.registerCommand("new-project", {
|
|
246
311
|
description: "Create a new project: mkdir, git init, scaffold .draht/. Usage: /new-project <name> [/base/path]",
|