gsd-pi 2.29.0-dev.49d972f → 2.29.0-dev.4c155ee
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 +24 -17
- package/dist/headless.js +4 -0
- package/dist/resources/extensions/bg-shell/process-manager.ts +13 -0
- package/dist/resources/extensions/gsd/auto-dashboard.ts +217 -65
- package/dist/resources/extensions/gsd/auto-dispatch.ts +32 -3
- package/dist/resources/extensions/gsd/auto-post-unit.ts +44 -12
- package/dist/resources/extensions/gsd/auto-prompts.ts +40 -17
- package/dist/resources/extensions/gsd/auto-recovery.ts +2 -1
- package/dist/resources/extensions/gsd/auto-start.ts +18 -32
- package/dist/resources/extensions/gsd/auto-worktree.ts +21 -182
- package/dist/resources/extensions/gsd/auto.ts +2 -9
- package/dist/resources/extensions/gsd/captures.ts +4 -10
- package/dist/resources/extensions/gsd/commands-handlers.ts +2 -1
- package/dist/resources/extensions/gsd/commands-prefs-wizard.ts +44 -14
- package/dist/resources/extensions/gsd/commands-workflow-templates.ts +544 -0
- package/dist/resources/extensions/gsd/commands.ts +55 -2
- package/dist/resources/extensions/gsd/detection.ts +2 -1
- package/dist/resources/extensions/gsd/doctor-checks.ts +49 -1
- package/dist/resources/extensions/gsd/doctor-types.ts +3 -1
- package/dist/resources/extensions/gsd/forensics.ts +2 -2
- package/dist/resources/extensions/gsd/git-service.ts +3 -2
- package/dist/resources/extensions/gsd/gitignore.ts +9 -63
- package/dist/resources/extensions/gsd/gsd-db.ts +1 -165
- package/dist/resources/extensions/gsd/guided-flow.ts +8 -5
- package/dist/resources/extensions/gsd/index.ts +3 -3
- package/dist/resources/extensions/gsd/md-importer.ts +3 -2
- package/dist/resources/extensions/gsd/mechanical-completion.ts +430 -0
- package/dist/resources/extensions/gsd/migrate/command.ts +3 -2
- package/dist/resources/extensions/gsd/migrate/writer.ts +2 -1
- package/dist/resources/extensions/gsd/migrate-external.ts +123 -0
- package/dist/resources/extensions/gsd/paths.ts +24 -2
- package/dist/resources/extensions/gsd/post-unit-hooks.ts +6 -5
- package/dist/resources/extensions/gsd/preferences-models.ts +7 -1
- package/dist/resources/extensions/gsd/preferences-validation.ts +2 -1
- package/dist/resources/extensions/gsd/preferences.ts +10 -5
- package/dist/resources/extensions/gsd/prompts/discuss-headless.md +4 -2
- package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
- package/dist/resources/extensions/gsd/prompts/plan-milestone.md +26 -2
- package/dist/resources/extensions/gsd/prompts/plan-slice.md +15 -1
- package/dist/resources/extensions/gsd/prompts/workflow-start.md +28 -0
- package/dist/resources/extensions/gsd/repo-identity.ts +148 -0
- package/dist/resources/extensions/gsd/resource-version.ts +99 -0
- package/dist/resources/extensions/gsd/session-forensics.ts +4 -3
- package/dist/resources/extensions/gsd/tests/activity-log.test.ts +2 -2
- package/dist/resources/extensions/gsd/tests/auto-recovery.test.ts +3 -3
- package/dist/resources/extensions/gsd/tests/auto-worktree.test.ts +0 -58
- package/dist/resources/extensions/gsd/tests/doctor-runtime.test.ts +3 -4
- package/dist/resources/extensions/gsd/tests/extension-selector-separator.test.ts +60 -38
- package/dist/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +5 -18
- package/dist/resources/extensions/gsd/tests/git-service.test.ts +10 -37
- package/dist/resources/extensions/gsd/tests/knowledge.test.ts +4 -4
- package/dist/resources/extensions/gsd/tests/mechanical-completion.test.ts +356 -0
- package/dist/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +1 -0
- package/dist/resources/extensions/gsd/tests/token-profile.test.ts +14 -16
- package/dist/resources/extensions/gsd/tests/workflow-templates.test.ts +173 -0
- package/dist/resources/extensions/gsd/triage-resolution.ts +2 -1
- package/dist/resources/extensions/gsd/types.ts +2 -0
- package/dist/resources/extensions/gsd/workflow-templates/bugfix.md +87 -0
- package/dist/resources/extensions/gsd/workflow-templates/dep-upgrade.md +74 -0
- package/dist/resources/extensions/gsd/workflow-templates/full-project.md +41 -0
- package/dist/resources/extensions/gsd/workflow-templates/hotfix.md +45 -0
- package/dist/resources/extensions/gsd/workflow-templates/refactor.md +83 -0
- package/dist/resources/extensions/gsd/workflow-templates/registry.json +85 -0
- package/dist/resources/extensions/gsd/workflow-templates/security-audit.md +73 -0
- package/dist/resources/extensions/gsd/workflow-templates/small-feature.md +81 -0
- package/dist/resources/extensions/gsd/workflow-templates/spike.md +69 -0
- package/dist/resources/extensions/gsd/workflow-templates.ts +241 -0
- package/dist/resources/extensions/gsd/worktree-command.ts +1 -11
- package/dist/resources/extensions/gsd/worktree-manager.ts +3 -2
- package/dist/resources/extensions/gsd/worktree.ts +42 -5
- package/dist/resources/extensions/mcp-client/index.ts +459 -0
- package/dist/resources/skills/create-gsd-extension/SKILL.md +87 -0
- package/dist/resources/skills/create-gsd-extension/references/compaction-session-control.md +77 -0
- package/dist/resources/skills/create-gsd-extension/references/custom-commands.md +139 -0
- package/dist/resources/skills/create-gsd-extension/references/custom-rendering.md +108 -0
- package/dist/resources/skills/create-gsd-extension/references/custom-tools.md +183 -0
- package/dist/resources/skills/create-gsd-extension/references/custom-ui.md +490 -0
- package/dist/resources/skills/create-gsd-extension/references/events-reference.md +126 -0
- package/dist/resources/skills/create-gsd-extension/references/extension-lifecycle.md +64 -0
- package/dist/resources/skills/create-gsd-extension/references/extensionapi-reference.md +75 -0
- package/dist/resources/skills/create-gsd-extension/references/extensioncontext-reference.md +53 -0
- package/dist/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +36 -0
- package/dist/resources/skills/create-gsd-extension/references/mode-behavior.md +32 -0
- package/dist/resources/skills/create-gsd-extension/references/model-provider-management.md +89 -0
- package/dist/resources/skills/create-gsd-extension/references/packaging-distribution.md +55 -0
- package/dist/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +90 -0
- package/dist/resources/skills/create-gsd-extension/references/state-management.md +70 -0
- package/dist/resources/skills/create-gsd-extension/references/system-prompt-modification.md +52 -0
- package/dist/resources/skills/create-gsd-extension/templates/extension-skeleton.ts +51 -0
- package/dist/resources/skills/create-gsd-extension/templates/stateful-tool-skeleton.ts +143 -0
- package/dist/resources/skills/create-gsd-extension/workflows/add-capability.md +57 -0
- package/dist/resources/skills/create-gsd-extension/workflows/create-extension.md +156 -0
- package/dist/resources/skills/create-gsd-extension/workflows/debug-extension.md +74 -0
- package/dist/resources/skills/create-skill/SKILL.md +184 -0
- package/dist/resources/skills/create-skill/references/api-security.md +226 -0
- package/dist/resources/skills/create-skill/references/be-clear-and-direct.md +531 -0
- package/dist/resources/skills/create-skill/references/common-patterns.md +595 -0
- package/dist/resources/skills/create-skill/references/core-principles.md +437 -0
- package/dist/resources/skills/create-skill/references/executable-code.md +175 -0
- package/dist/resources/skills/create-skill/references/gsd-skill-ecosystem.md +68 -0
- package/dist/resources/skills/create-skill/references/iteration-and-testing.md +474 -0
- package/dist/resources/skills/create-skill/references/recommended-structure.md +168 -0
- package/dist/resources/skills/create-skill/references/skill-structure.md +372 -0
- package/dist/resources/skills/create-skill/references/use-xml-tags.md +466 -0
- package/dist/resources/skills/create-skill/references/using-scripts.md +113 -0
- package/dist/resources/skills/create-skill/references/using-templates.md +112 -0
- package/dist/resources/skills/create-skill/references/workflows-and-validation.md +510 -0
- package/dist/resources/skills/create-skill/templates/router-skill.md +73 -0
- package/dist/resources/skills/create-skill/templates/simple-skill.md +33 -0
- package/dist/resources/skills/create-skill/workflows/add-reference.md +96 -0
- package/dist/resources/skills/create-skill/workflows/add-script.md +93 -0
- package/dist/resources/skills/create-skill/workflows/add-template.md +74 -0
- package/dist/resources/skills/create-skill/workflows/add-workflow.md +120 -0
- package/dist/resources/skills/create-skill/workflows/audit-skill.md +148 -0
- package/dist/resources/skills/create-skill/workflows/create-new-skill.md +196 -0
- package/dist/resources/skills/create-skill/workflows/get-guidance.md +121 -0
- package/dist/resources/skills/create-skill/workflows/upgrade-to-router.md +161 -0
- package/dist/resources/skills/create-skill/workflows/verify-skill.md +204 -0
- package/dist/resources/skills/react-best-practices/SKILL.md +1 -1
- package/package.json +1 -1
- package/packages/native/dist/native.d.ts +2 -0
- package/packages/native/dist/native.js +19 -5
- package/packages/native/src/native.ts +23 -9
- package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/extensions/loader.js +13 -0
- package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/client.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/lsp/client.js +3 -0
- package/packages/pi-coding-agent/dist/core/lsp/client.js.map +1 -1
- package/packages/pi-coding-agent/src/core/extensions/loader.ts +13 -0
- package/packages/pi-coding-agent/src/core/lsp/client.ts +3 -0
- package/src/resources/extensions/bg-shell/process-manager.ts +13 -0
- package/src/resources/extensions/gsd/auto-dashboard.ts +217 -65
- package/src/resources/extensions/gsd/auto-dispatch.ts +32 -3
- package/src/resources/extensions/gsd/auto-post-unit.ts +44 -12
- package/src/resources/extensions/gsd/auto-prompts.ts +40 -17
- package/src/resources/extensions/gsd/auto-recovery.ts +2 -1
- package/src/resources/extensions/gsd/auto-start.ts +18 -32
- package/src/resources/extensions/gsd/auto-worktree.ts +21 -182
- package/src/resources/extensions/gsd/auto.ts +2 -9
- package/src/resources/extensions/gsd/captures.ts +4 -10
- package/src/resources/extensions/gsd/commands-handlers.ts +2 -1
- package/src/resources/extensions/gsd/commands-prefs-wizard.ts +44 -14
- package/src/resources/extensions/gsd/commands-workflow-templates.ts +544 -0
- package/src/resources/extensions/gsd/commands.ts +55 -2
- package/src/resources/extensions/gsd/detection.ts +2 -1
- package/src/resources/extensions/gsd/doctor-checks.ts +49 -1
- package/src/resources/extensions/gsd/doctor-types.ts +3 -1
- package/src/resources/extensions/gsd/forensics.ts +2 -2
- package/src/resources/extensions/gsd/git-service.ts +3 -2
- package/src/resources/extensions/gsd/gitignore.ts +9 -63
- package/src/resources/extensions/gsd/gsd-db.ts +1 -165
- package/src/resources/extensions/gsd/guided-flow.ts +8 -5
- package/src/resources/extensions/gsd/index.ts +3 -3
- package/src/resources/extensions/gsd/md-importer.ts +3 -2
- package/src/resources/extensions/gsd/mechanical-completion.ts +430 -0
- package/src/resources/extensions/gsd/migrate/command.ts +3 -2
- package/src/resources/extensions/gsd/migrate/writer.ts +2 -1
- package/src/resources/extensions/gsd/migrate-external.ts +123 -0
- package/src/resources/extensions/gsd/paths.ts +24 -2
- package/src/resources/extensions/gsd/post-unit-hooks.ts +6 -5
- package/src/resources/extensions/gsd/preferences-models.ts +7 -1
- package/src/resources/extensions/gsd/preferences-validation.ts +2 -1
- package/src/resources/extensions/gsd/preferences.ts +10 -5
- package/src/resources/extensions/gsd/prompts/discuss-headless.md +4 -2
- package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +1 -1
- package/src/resources/extensions/gsd/prompts/plan-milestone.md +26 -2
- package/src/resources/extensions/gsd/prompts/plan-slice.md +15 -1
- package/src/resources/extensions/gsd/prompts/workflow-start.md +28 -0
- package/src/resources/extensions/gsd/repo-identity.ts +148 -0
- package/src/resources/extensions/gsd/resource-version.ts +99 -0
- package/src/resources/extensions/gsd/session-forensics.ts +4 -3
- package/src/resources/extensions/gsd/tests/activity-log.test.ts +2 -2
- package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +3 -3
- package/src/resources/extensions/gsd/tests/auto-worktree.test.ts +0 -58
- package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +3 -4
- package/src/resources/extensions/gsd/tests/extension-selector-separator.test.ts +60 -38
- package/src/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +5 -18
- package/src/resources/extensions/gsd/tests/git-service.test.ts +10 -37
- package/src/resources/extensions/gsd/tests/knowledge.test.ts +4 -4
- package/src/resources/extensions/gsd/tests/mechanical-completion.test.ts +356 -0
- package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +1 -0
- package/src/resources/extensions/gsd/tests/token-profile.test.ts +14 -16
- package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +173 -0
- package/src/resources/extensions/gsd/triage-resolution.ts +2 -1
- package/src/resources/extensions/gsd/types.ts +2 -0
- package/src/resources/extensions/gsd/workflow-templates/bugfix.md +87 -0
- package/src/resources/extensions/gsd/workflow-templates/dep-upgrade.md +74 -0
- package/src/resources/extensions/gsd/workflow-templates/full-project.md +41 -0
- package/src/resources/extensions/gsd/workflow-templates/hotfix.md +45 -0
- package/src/resources/extensions/gsd/workflow-templates/refactor.md +83 -0
- package/src/resources/extensions/gsd/workflow-templates/registry.json +85 -0
- package/src/resources/extensions/gsd/workflow-templates/security-audit.md +73 -0
- package/src/resources/extensions/gsd/workflow-templates/small-feature.md +81 -0
- package/src/resources/extensions/gsd/workflow-templates/spike.md +69 -0
- package/src/resources/extensions/gsd/workflow-templates.ts +241 -0
- package/src/resources/extensions/gsd/worktree-command.ts +1 -11
- package/src/resources/extensions/gsd/worktree-manager.ts +3 -2
- package/src/resources/extensions/gsd/worktree.ts +42 -5
- package/src/resources/extensions/mcp-client/index.ts +459 -0
- package/src/resources/skills/create-gsd-extension/SKILL.md +87 -0
- package/src/resources/skills/create-gsd-extension/references/compaction-session-control.md +77 -0
- package/src/resources/skills/create-gsd-extension/references/custom-commands.md +139 -0
- package/src/resources/skills/create-gsd-extension/references/custom-rendering.md +108 -0
- package/src/resources/skills/create-gsd-extension/references/custom-tools.md +183 -0
- package/src/resources/skills/create-gsd-extension/references/custom-ui.md +490 -0
- package/src/resources/skills/create-gsd-extension/references/events-reference.md +126 -0
- package/src/resources/skills/create-gsd-extension/references/extension-lifecycle.md +64 -0
- package/src/resources/skills/create-gsd-extension/references/extensionapi-reference.md +75 -0
- package/src/resources/skills/create-gsd-extension/references/extensioncontext-reference.md +53 -0
- package/src/resources/skills/create-gsd-extension/references/key-rules-gotchas.md +36 -0
- package/src/resources/skills/create-gsd-extension/references/mode-behavior.md +32 -0
- package/src/resources/skills/create-gsd-extension/references/model-provider-management.md +89 -0
- package/src/resources/skills/create-gsd-extension/references/packaging-distribution.md +55 -0
- package/src/resources/skills/create-gsd-extension/references/remote-execution-overrides.md +90 -0
- package/src/resources/skills/create-gsd-extension/references/state-management.md +70 -0
- package/src/resources/skills/create-gsd-extension/references/system-prompt-modification.md +52 -0
- package/src/resources/skills/create-gsd-extension/templates/extension-skeleton.ts +51 -0
- package/src/resources/skills/create-gsd-extension/templates/stateful-tool-skeleton.ts +143 -0
- package/src/resources/skills/create-gsd-extension/workflows/add-capability.md +57 -0
- package/src/resources/skills/create-gsd-extension/workflows/create-extension.md +156 -0
- package/src/resources/skills/create-gsd-extension/workflows/debug-extension.md +74 -0
- package/src/resources/skills/create-skill/SKILL.md +184 -0
- package/src/resources/skills/create-skill/references/api-security.md +226 -0
- package/src/resources/skills/create-skill/references/be-clear-and-direct.md +531 -0
- package/src/resources/skills/create-skill/references/common-patterns.md +595 -0
- package/src/resources/skills/create-skill/references/core-principles.md +437 -0
- package/src/resources/skills/create-skill/references/executable-code.md +175 -0
- package/src/resources/skills/create-skill/references/gsd-skill-ecosystem.md +68 -0
- package/src/resources/skills/create-skill/references/iteration-and-testing.md +474 -0
- package/src/resources/skills/create-skill/references/recommended-structure.md +168 -0
- package/src/resources/skills/create-skill/references/skill-structure.md +372 -0
- package/src/resources/skills/create-skill/references/use-xml-tags.md +466 -0
- package/src/resources/skills/create-skill/references/using-scripts.md +113 -0
- package/src/resources/skills/create-skill/references/using-templates.md +112 -0
- package/src/resources/skills/create-skill/references/workflows-and-validation.md +510 -0
- package/src/resources/skills/create-skill/templates/router-skill.md +73 -0
- package/src/resources/skills/create-skill/templates/simple-skill.md +33 -0
- package/src/resources/skills/create-skill/workflows/add-reference.md +96 -0
- package/src/resources/skills/create-skill/workflows/add-script.md +93 -0
- package/src/resources/skills/create-skill/workflows/add-template.md +74 -0
- package/src/resources/skills/create-skill/workflows/add-workflow.md +120 -0
- package/src/resources/skills/create-skill/workflows/audit-skill.md +148 -0
- package/src/resources/skills/create-skill/workflows/create-new-skill.md +196 -0
- package/src/resources/skills/create-skill/workflows/get-guidance.md +121 -0
- package/src/resources/skills/create-skill/workflows/upgrade-to-router.md +161 -0
- package/src/resources/skills/create-skill/workflows/verify-skill.md +204 -0
- package/src/resources/skills/react-best-practices/SKILL.md +1 -1
- package/dist/resources/extensions/gsd/auto-worktree-sync.ts +0 -199
- package/dist/resources/extensions/gsd/tests/worktree-db-integration.test.ts +0 -205
- package/dist/resources/extensions/gsd/tests/worktree-db.test.ts +0 -442
- package/dist/resources/extensions/mcporter/index.ts +0 -525
- package/src/resources/extensions/gsd/auto-worktree-sync.ts +0 -199
- package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +0 -205
- package/src/resources/extensions/gsd/tests/worktree-db.test.ts +0 -442
- package/src/resources/extensions/mcporter/index.ts +0 -525
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
<overview>
|
|
2
|
+
Custom slash commands — registration, argument completions, subcommand patterns, and the extended command context.
|
|
3
|
+
</overview>
|
|
4
|
+
|
|
5
|
+
<basic_registration>
|
|
6
|
+
```typescript
|
|
7
|
+
pi.registerCommand("deploy", {
|
|
8
|
+
description: "Deploy to an environment",
|
|
9
|
+
handler: async (args, ctx) => {
|
|
10
|
+
// args = everything after "/deploy "
|
|
11
|
+
// ctx = ExtensionCommandContext (has session control methods)
|
|
12
|
+
ctx.ui.notify(`Deploying to ${args || "production"}`, "info");
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
```
|
|
16
|
+
</basic_registration>
|
|
17
|
+
|
|
18
|
+
<argument_completions>
|
|
19
|
+
Add tab-completion for command arguments:
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import type { AutocompleteItem } from "@mariozechner/pi-tui";
|
|
23
|
+
|
|
24
|
+
pi.registerCommand("deploy", {
|
|
25
|
+
description: "Deploy to an environment",
|
|
26
|
+
getArgumentCompletions: (prefix: string): AutocompleteItem[] | null => {
|
|
27
|
+
const envs = ["dev", "staging", "prod"];
|
|
28
|
+
const items = envs.map(e => ({ value: e, label: e }));
|
|
29
|
+
const filtered = items.filter(i => i.value.startsWith(prefix));
|
|
30
|
+
return filtered.length > 0 ? filtered : null;
|
|
31
|
+
},
|
|
32
|
+
handler: async (args, ctx) => {
|
|
33
|
+
ctx.ui.notify(`Deploying to ${args}`, "info");
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
</argument_completions>
|
|
38
|
+
|
|
39
|
+
<subcommand_pattern>
|
|
40
|
+
Fake nested commands via first-argument parsing. Used by `/wt new|ls|switch|merge|rm`.
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
pi.registerCommand("foo", {
|
|
44
|
+
description: "Manage foo items: /foo new|list|delete [name]",
|
|
45
|
+
|
|
46
|
+
getArgumentCompletions: (prefix: string) => {
|
|
47
|
+
const parts = prefix.trim().split(/\s+/);
|
|
48
|
+
|
|
49
|
+
// First arg: subcommand
|
|
50
|
+
if (parts.length <= 1) {
|
|
51
|
+
return ["new", "list", "delete"]
|
|
52
|
+
.filter(cmd => cmd.startsWith(parts[0] ?? ""))
|
|
53
|
+
.map(cmd => ({ value: cmd, label: cmd }));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Second arg: depends on subcommand
|
|
57
|
+
if (parts[0] === "delete") {
|
|
58
|
+
const items = getItemsSomehow();
|
|
59
|
+
return items
|
|
60
|
+
.filter(name => name.startsWith(parts[1] ?? ""))
|
|
61
|
+
.map(name => ({ value: `delete ${name}`, label: name }));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return [];
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
handler: async (args, ctx) => {
|
|
68
|
+
const parts = args.trim().split(/\s+/);
|
|
69
|
+
const sub = parts[0];
|
|
70
|
+
|
|
71
|
+
switch (sub) {
|
|
72
|
+
case "new": /* ... */ return;
|
|
73
|
+
case "list": /* ... */ return;
|
|
74
|
+
case "delete": /* handle parts[1] */ return;
|
|
75
|
+
default:
|
|
76
|
+
ctx.ui.notify("Usage: /foo <new|list|delete> [name]", "info");
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**Gotcha:** `"".trim().split(/\s+/)` produces `['']`, not `[]`. That's why `parts.length <= 1` handles both empty and partial first arg.
|
|
83
|
+
</subcommand_pattern>
|
|
84
|
+
|
|
85
|
+
<command_context>
|
|
86
|
+
Command handlers get `ExtensionCommandContext` which extends `ExtensionContext` with session control methods:
|
|
87
|
+
|
|
88
|
+
| Method | Purpose |
|
|
89
|
+
|--------|---------|
|
|
90
|
+
| `ctx.waitForIdle()` | Wait for agent to finish streaming |
|
|
91
|
+
| `ctx.newSession(options?)` | Create a new session |
|
|
92
|
+
| `ctx.fork(entryId)` | Fork from an entry |
|
|
93
|
+
| `ctx.navigateTree(targetId, options?)` | Navigate session tree |
|
|
94
|
+
| `ctx.reload()` | Hot-reload everything |
|
|
95
|
+
|
|
96
|
+
**⚠️ These methods are ONLY available in command handlers.** Calling them from event handlers causes deadlocks.
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
pi.registerCommand("handoff", {
|
|
100
|
+
handler: async (args, ctx) => {
|
|
101
|
+
await ctx.waitForIdle();
|
|
102
|
+
await ctx.newSession({
|
|
103
|
+
setup: async (sm) => {
|
|
104
|
+
sm.appendMessage({
|
|
105
|
+
role: "user",
|
|
106
|
+
content: [{ type: "text", text: `Context: ${args}` }],
|
|
107
|
+
timestamp: Date.now(),
|
|
108
|
+
});
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
```
|
|
114
|
+
</command_context>
|
|
115
|
+
|
|
116
|
+
<reload_pattern>
|
|
117
|
+
Expose reload as both a command and a tool the LLM can call:
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
pi.registerCommand("reload-runtime", {
|
|
121
|
+
description: "Reload extensions, skills, prompts, and themes",
|
|
122
|
+
handler: async (_args, ctx) => {
|
|
123
|
+
await ctx.reload();
|
|
124
|
+
return; // Treat reload as terminal
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
pi.registerTool({
|
|
129
|
+
name: "reload_runtime",
|
|
130
|
+
label: "Reload Runtime",
|
|
131
|
+
description: "Reload extensions, skills, prompts, and themes",
|
|
132
|
+
parameters: Type.Object({}),
|
|
133
|
+
async execute() {
|
|
134
|
+
pi.sendUserMessage("/reload-runtime", { deliverAs: "followUp" });
|
|
135
|
+
return { content: [{ type: "text", text: "Queued /reload-runtime as follow-up." }] };
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
```
|
|
139
|
+
</reload_pattern>
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
<overview>
|
|
2
|
+
Custom rendering for tools and messages — control how they appear in the TUI.
|
|
3
|
+
</overview>
|
|
4
|
+
|
|
5
|
+
<tool_rendering>
|
|
6
|
+
Tools can provide `renderCall` (how the call looks) and `renderResult` (how the result looks):
|
|
7
|
+
|
|
8
|
+
```typescript
|
|
9
|
+
import { Text } from "@mariozechner/pi-tui";
|
|
10
|
+
import { keyHint } from "@mariozechner/pi-coding-agent";
|
|
11
|
+
|
|
12
|
+
pi.registerTool({
|
|
13
|
+
name: "my_tool",
|
|
14
|
+
// ...
|
|
15
|
+
|
|
16
|
+
renderCall(args, theme) {
|
|
17
|
+
let text = theme.fg("toolTitle", theme.bold("my_tool "));
|
|
18
|
+
text += theme.fg("muted", args.action);
|
|
19
|
+
if (args.text) text += " " + theme.fg("dim", `"${args.text}"`);
|
|
20
|
+
return new Text(text, 0, 0); // 0,0 padding — Box handles it
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
renderResult(result, { expanded, isPartial }, theme) {
|
|
24
|
+
// isPartial = true during streaming (onUpdate was called)
|
|
25
|
+
if (isPartial) {
|
|
26
|
+
return new Text(theme.fg("warning", "Processing..."), 0, 0);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// expanded = user toggled expand (Ctrl+O)
|
|
30
|
+
if (result.details?.error) {
|
|
31
|
+
return new Text(theme.fg("error", `Error: ${result.details.error}`), 0, 0);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
let text = theme.fg("success", "✓ Done");
|
|
35
|
+
if (!expanded) {
|
|
36
|
+
text += ` (${keyHint("expandTools", "to expand")})`;
|
|
37
|
+
}
|
|
38
|
+
if (expanded && result.details?.items) {
|
|
39
|
+
for (const item of result.details.items) {
|
|
40
|
+
text += "\n " + theme.fg("dim", item);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return new Text(text, 0, 0);
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
If you omit `renderCall`/`renderResult`, the built-in renderer is used. Useful for tool overrides where you just wrap logic without reimplementing UI.
|
|
49
|
+
|
|
50
|
+
**Fallback:** If render methods throw, `renderCall` shows tool name, `renderResult` shows raw `content` text.
|
|
51
|
+
</tool_rendering>
|
|
52
|
+
|
|
53
|
+
<key_hints>
|
|
54
|
+
Key hint helpers for showing keybinding info in render output:
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
import { keyHint, appKeyHint, editorKey, rawKeyHint } from "@mariozechner/pi-coding-agent";
|
|
58
|
+
|
|
59
|
+
// Editor action hint (respects user keybinding config)
|
|
60
|
+
keyHint("expandTools", "to expand") // e.g., "Ctrl+O to expand"
|
|
61
|
+
keyHint("selectConfirm", "to select")
|
|
62
|
+
|
|
63
|
+
// Raw key hint (always shows literal key)
|
|
64
|
+
rawKeyHint("Ctrl+O", "to expand")
|
|
65
|
+
```
|
|
66
|
+
</key_hints>
|
|
67
|
+
|
|
68
|
+
<message_rendering>
|
|
69
|
+
Register a renderer for custom message types:
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
import { Text } from "@mariozechner/pi-tui";
|
|
73
|
+
|
|
74
|
+
pi.registerMessageRenderer("my-extension", (message, options, theme) => {
|
|
75
|
+
const { expanded } = options;
|
|
76
|
+
let text = theme.fg("accent", `[${message.customType}] `) + message.content;
|
|
77
|
+
if (expanded && message.details) {
|
|
78
|
+
text += "\n" + theme.fg("dim", JSON.stringify(message.details, null, 2));
|
|
79
|
+
}
|
|
80
|
+
return new Text(text, 0, 0);
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// Send messages that use this renderer:
|
|
84
|
+
pi.sendMessage({
|
|
85
|
+
customType: "my-extension", // Matches renderer name
|
|
86
|
+
content: "Status update",
|
|
87
|
+
display: true,
|
|
88
|
+
details: { foo: "bar" },
|
|
89
|
+
});
|
|
90
|
+
```
|
|
91
|
+
</message_rendering>
|
|
92
|
+
|
|
93
|
+
<syntax_highlighting>
|
|
94
|
+
```typescript
|
|
95
|
+
import { highlightCode, getLanguageFromPath } from "@mariozechner/pi-coding-agent";
|
|
96
|
+
|
|
97
|
+
const lang = getLanguageFromPath("/path/to/file.rs"); // "rust"
|
|
98
|
+
const highlighted = highlightCode(code, lang, theme);
|
|
99
|
+
```
|
|
100
|
+
</syntax_highlighting>
|
|
101
|
+
|
|
102
|
+
<best_practices>
|
|
103
|
+
- Return `Text` with padding `(0, 0)` — the wrapping `Box` handles padding
|
|
104
|
+
- Support `expanded` for detail on demand
|
|
105
|
+
- Handle `isPartial` for streaming progress
|
|
106
|
+
- Keep collapsed view compact
|
|
107
|
+
- Use `\n` for multi-line content within a single `Text`
|
|
108
|
+
</best_practices>
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
<overview>
|
|
2
|
+
Complete custom tools reference — registration, parameters, execution, output truncation, overrides, rendering, and dynamic registration.
|
|
3
|
+
</overview>
|
|
4
|
+
|
|
5
|
+
<registration>
|
|
6
|
+
```typescript
|
|
7
|
+
import { Type } from "@sinclair/typebox";
|
|
8
|
+
import { StringEnum } from "@mariozechner/pi-ai";
|
|
9
|
+
|
|
10
|
+
pi.registerTool({
|
|
11
|
+
name: "my_tool", // Unique identifier (snake_case)
|
|
12
|
+
label: "My Tool", // Display name in TUI
|
|
13
|
+
description: "What this does", // Full description shown to LLM
|
|
14
|
+
|
|
15
|
+
// Optional: one-liner for system prompt "Available tools" section
|
|
16
|
+
promptSnippet: "Manage project todo items",
|
|
17
|
+
|
|
18
|
+
// Optional: bullets added to system prompt "Guidelines" when tool is active
|
|
19
|
+
promptGuidelines: [
|
|
20
|
+
"Use my_tool for task management instead of file edits."
|
|
21
|
+
],
|
|
22
|
+
|
|
23
|
+
// Parameter schema (MUST use TypeBox)
|
|
24
|
+
parameters: Type.Object({
|
|
25
|
+
action: StringEnum(["list", "add", "remove"] as const),
|
|
26
|
+
text: Type.Optional(Type.String({ description: "Item text" })),
|
|
27
|
+
id: Type.Optional(Type.Number({ description: "Item ID" })),
|
|
28
|
+
}),
|
|
29
|
+
|
|
30
|
+
async execute(toolCallId, params, signal, onUpdate, ctx) {
|
|
31
|
+
// 1. Check cancellation
|
|
32
|
+
if (signal?.aborted) {
|
|
33
|
+
return { content: [{ type: "text", text: "Cancelled" }] };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// 2. Stream progress (optional)
|
|
37
|
+
onUpdate?.({
|
|
38
|
+
content: [{ type: "text", text: "Working..." }],
|
|
39
|
+
details: { progress: 50 },
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// 3. Do the work
|
|
43
|
+
const result = await doWork(params);
|
|
44
|
+
|
|
45
|
+
// 4. Return result
|
|
46
|
+
return {
|
|
47
|
+
content: [{ type: "text", text: "Result text for LLM" }], // Sent to LLM context
|
|
48
|
+
details: { data: result }, // For rendering & state
|
|
49
|
+
};
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
// Optional: custom TUI rendering
|
|
53
|
+
renderCall(args, theme) { ... },
|
|
54
|
+
renderResult(result, { expanded, isPartial }, theme) { ... },
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
</registration>
|
|
58
|
+
|
|
59
|
+
<critical_stringenum>
|
|
60
|
+
**⚠️ MUST use `StringEnum` for string enum parameters:**
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
import { StringEnum } from "@mariozechner/pi-ai";
|
|
64
|
+
|
|
65
|
+
// ✅ Correct — works with all providers including Google
|
|
66
|
+
action: StringEnum(["list", "add", "remove"] as const)
|
|
67
|
+
|
|
68
|
+
// ❌ BROKEN with Google's API
|
|
69
|
+
action: Type.Union([Type.Literal("list"), Type.Literal("add")])
|
|
70
|
+
```
|
|
71
|
+
</critical_stringenum>
|
|
72
|
+
|
|
73
|
+
<output_truncation>
|
|
74
|
+
Tools MUST truncate output to avoid context overflow. Built-in limit: 50KB / 2000 lines.
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
import {
|
|
78
|
+
truncateHead, truncateTail, formatSize,
|
|
79
|
+
DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES,
|
|
80
|
+
} from "@mariozechner/pi-coding-agent";
|
|
81
|
+
|
|
82
|
+
async execute(toolCallId, params, signal, onUpdate, ctx) {
|
|
83
|
+
const output = await runCommand();
|
|
84
|
+
const truncation = truncateHead(output, {
|
|
85
|
+
maxLines: DEFAULT_MAX_LINES,
|
|
86
|
+
maxBytes: DEFAULT_MAX_BYTES,
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
let result = truncation.content;
|
|
90
|
+
if (truncation.truncated) {
|
|
91
|
+
const tempFile = writeTempFile(output);
|
|
92
|
+
result += `\n\n[Output truncated: ${truncation.outputLines}/${truncation.totalLines} lines`;
|
|
93
|
+
result += ` (${formatSize(truncation.outputBytes)}/${formatSize(truncation.totalBytes)}).`;
|
|
94
|
+
result += ` Full output: ${tempFile}]`;
|
|
95
|
+
}
|
|
96
|
+
return { content: [{ type: "text", text: result }] };
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Use `truncateHead` when beginning matters (search results, file reads). Use `truncateTail` when end matters (logs, command output).
|
|
101
|
+
</output_truncation>
|
|
102
|
+
|
|
103
|
+
<signaling_errors>
|
|
104
|
+
Throw to signal an error (sets `isError: true`). Returning a value never sets error flag.
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
async execute(toolCallId, params) {
|
|
108
|
+
if (!isValid(params.input)) {
|
|
109
|
+
throw new Error(`Invalid input: ${params.input}`);
|
|
110
|
+
}
|
|
111
|
+
return { content: [{ type: "text", text: "OK" }], details: {} };
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
</signaling_errors>
|
|
115
|
+
|
|
116
|
+
<dynamic_registration>
|
|
117
|
+
Tools can be registered at any time — during load, in `session_start`, in command handlers. Available immediately without `/reload`.
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
pi.on("session_start", async (_event, ctx) => {
|
|
121
|
+
pi.registerTool({ name: "dynamic_tool", ... });
|
|
122
|
+
});
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Use `pi.setActiveTools(names)` to enable/disable tools at runtime.
|
|
126
|
+
</dynamic_registration>
|
|
127
|
+
|
|
128
|
+
<overriding_builtins>
|
|
129
|
+
Register a tool with the same name as a built-in (`read`, `bash`, `edit`, `write`, `grep`, `find`, `ls`) to override it. **Must match exact result shape including `details` type.**
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
import { createReadTool } from "@mariozechner/pi-coding-agent";
|
|
133
|
+
|
|
134
|
+
pi.registerTool({
|
|
135
|
+
name: "read",
|
|
136
|
+
label: "Read (Logged)",
|
|
137
|
+
description: "Read file contents with logging",
|
|
138
|
+
parameters: Type.Object({
|
|
139
|
+
path: Type.String(),
|
|
140
|
+
offset: Type.Optional(Type.Number()),
|
|
141
|
+
limit: Type.Optional(Type.Number()),
|
|
142
|
+
}),
|
|
143
|
+
async execute(toolCallId, params, signal, onUpdate, ctx) {
|
|
144
|
+
console.log(`[AUDIT] Reading: ${params.path}`);
|
|
145
|
+
const builtIn = createReadTool(ctx.cwd);
|
|
146
|
+
return builtIn.execute(toolCallId, params, signal, onUpdate);
|
|
147
|
+
},
|
|
148
|
+
// Omit renderCall/renderResult to use built-in renderer
|
|
149
|
+
});
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Start with no built-in tools: `gsd --no-tools -e ./my-extension.ts`
|
|
153
|
+
</overriding_builtins>
|
|
154
|
+
|
|
155
|
+
<multiple_tools>
|
|
156
|
+
One extension can register multiple tools with shared state:
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
export default function (pi: ExtensionAPI) {
|
|
160
|
+
let connection = null;
|
|
161
|
+
|
|
162
|
+
pi.registerTool({ name: "db_connect", ... });
|
|
163
|
+
pi.registerTool({ name: "db_query", ... });
|
|
164
|
+
pi.registerTool({ name: "db_close", ... });
|
|
165
|
+
|
|
166
|
+
pi.on("session_shutdown", async () => {
|
|
167
|
+
connection?.close();
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
```
|
|
171
|
+
</multiple_tools>
|
|
172
|
+
|
|
173
|
+
<path_normalization>
|
|
174
|
+
Some models add `@` prefix to path arguments. Strip it:
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
async execute(toolCallId, params, signal, onUpdate, ctx) {
|
|
178
|
+
let path = params.path;
|
|
179
|
+
if (path.startsWith("@")) path = path.slice(1);
|
|
180
|
+
// ...
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
</path_normalization>
|