gsd-pi 2.72.0 → 2.73.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -2
- package/dist/cli.js +59 -3
- package/dist/onboarding.js +10 -0
- package/dist/resources/extensions/async-jobs/await-tool.js +7 -4
- package/dist/resources/extensions/async-jobs/job-manager.js +28 -3
- package/dist/resources/extensions/claude-code-cli/partial-builder.js +40 -12
- package/dist/resources/extensions/claude-code-cli/stream-adapter.js +48 -23
- package/dist/resources/extensions/gsd/auto/loop.js +84 -1
- package/dist/resources/extensions/gsd/auto-post-unit.js +6 -0
- package/dist/resources/extensions/gsd/auto-recovery.js +11 -0
- package/dist/resources/extensions/gsd/auto.js +25 -19
- package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +9 -11
- package/dist/resources/extensions/gsd/commands-handlers.js +4 -1
- package/dist/resources/extensions/gsd/context-injector.js +1 -1
- package/dist/resources/extensions/gsd/custom-workflow-engine.js +3 -7
- package/dist/resources/extensions/gsd/definition-io.js +15 -0
- package/dist/resources/extensions/gsd/dispatch-guard.js +4 -0
- package/dist/resources/extensions/gsd/doctor-runtime-checks.js +6 -3
- package/dist/resources/extensions/gsd/git-service.js +11 -8
- package/dist/resources/extensions/gsd/gitignore.js +12 -6
- package/dist/resources/extensions/gsd/gsd-db.js +49 -6
- package/dist/resources/extensions/gsd/key-manager.js +2 -0
- package/dist/resources/extensions/gsd/preferences-skills.js +2 -34
- package/dist/resources/extensions/gsd/preferences-types.js +15 -0
- package/dist/resources/extensions/gsd/preferences.js +16 -3
- package/dist/resources/extensions/gsd/prompt-loader.js +4 -1
- package/dist/resources/extensions/gsd/prompts/discuss.md +122 -13
- package/dist/resources/extensions/gsd/prompts/system.md +1 -1
- package/dist/resources/extensions/gsd/state.js +21 -1
- package/dist/resources/extensions/gsd/workflow-projections.js +7 -0
- package/dist/resources/extensions/gsd/worktree-manager.js +30 -3
- package/dist/resources/extensions/gsd/write-intercept.js +10 -1
- package/dist/resources/extensions/ollama/index.js +4 -5
- package/dist/resources/extensions/ollama/ollama-client.js +35 -6
- package/dist/resources/extensions/ollama/ollama-discovery.js +32 -6
- package/dist/web/standalone/.next/BUILD_ID +1 -1
- package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
- package/dist/web/standalone/.next/build-manifest.json +2 -2
- package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
- package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
- package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
- package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
- package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
- package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
- package/dist/web/standalone/.next/server/app/index.html +1 -1
- package/dist/web/standalone/.next/server/app/index.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dist/web/standalone/.next/server/app/page.js +2 -2
- package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
- package/dist/web/standalone/.next/server/chunks/2331.js +16 -16
- package/dist/web/standalone/.next/server/chunks/4741.js +12 -12
- package/dist/web/standalone/.next/server/chunks/5822.js +2 -2
- package/dist/web/standalone/.next/server/chunks/63.js +8 -8
- package/dist/web/standalone/.next/server/chunks/6897.js +3 -3
- package/dist/web/standalone/.next/server/edge-runtime-webpack.js +2 -0
- package/dist/web/standalone/.next/server/functions-config-manifest.json +0 -9
- package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
- package/dist/web/standalone/.next/server/middleware-manifest.json +29 -2
- package/dist/web/standalone/.next/server/middleware.js +4 -12
- package/dist/web/standalone/.next/server/pages/404.html +1 -1
- package/dist/web/standalone/.next/server/pages/500.html +1 -1
- package/dist/web/standalone/.next/server/webpack-runtime.js +1 -1
- package/package.json +1 -1
- package/packages/pi-ai/dist/env-api-keys.js +1 -0
- package/packages/pi-ai/dist/env-api-keys.js.map +1 -1
- package/packages/pi-ai/dist/models.custom.d.ts +105 -0
- package/packages/pi-ai/dist/models.custom.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.custom.js +97 -0
- package/packages/pi-ai/dist/models.custom.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.d.ts +648 -140
- package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
- package/packages/pi-ai/dist/models.generated.js +867 -370
- package/packages/pi-ai/dist/models.generated.js.map +1 -1
- package/packages/pi-ai/dist/models.generated.test.d.ts +2 -0
- package/packages/pi-ai/dist/models.generated.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/models.generated.test.js +334 -0
- package/packages/pi-ai/dist/models.generated.test.js.map +1 -0
- package/packages/pi-ai/dist/models.test.js +105 -0
- package/packages/pi-ai/dist/models.test.js.map +1 -1
- package/packages/pi-ai/dist/types.d.ts +1 -1
- package/packages/pi-ai/dist/types.d.ts.map +1 -1
- package/packages/pi-ai/dist/types.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/github-copilot.js +5 -1
- package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
- package/packages/pi-ai/dist/utils/oauth/github-copilot.test.d.ts +2 -0
- package/packages/pi-ai/dist/utils/oauth/github-copilot.test.d.ts.map +1 -0
- package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js +57 -0
- package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js.map +1 -0
- package/packages/pi-ai/src/env-api-keys.ts +1 -0
- package/packages/pi-ai/src/models.custom.ts +98 -0
- package/packages/pi-ai/src/models.generated.test.ts +373 -0
- package/packages/pi-ai/src/models.generated.ts +867 -370
- package/packages/pi-ai/src/models.test.ts +135 -0
- package/packages/pi-ai/src/types.ts +1 -0
- package/packages/pi-ai/src/utils/oauth/github-copilot.test.ts +71 -0
- package/packages/pi-ai/src/utils/oauth/github-copilot.ts +4 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -0
- package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/core/sdk.js +9 -0
- package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +36 -0
- package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +87 -12
- package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/packages/pi-coding-agent/package.json +1 -1
- package/packages/pi-coding-agent/src/core/model-resolver.ts +1 -0
- package/packages/pi-coding-agent/src/core/sdk.ts +10 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +72 -0
- package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +84 -12
- package/packages/pi-tui/dist/components/__tests__/editor.test.js +12 -0
- package/packages/pi-tui/dist/components/__tests__/editor.test.js.map +1 -1
- package/packages/pi-tui/dist/components/__tests__/input.test.js +12 -0
- package/packages/pi-tui/dist/components/__tests__/input.test.js.map +1 -1
- package/packages/pi-tui/dist/keys.d.ts.map +1 -1
- package/packages/pi-tui/dist/keys.js +27 -0
- package/packages/pi-tui/dist/keys.js.map +1 -1
- package/packages/pi-tui/src/components/__tests__/editor.test.ts +18 -0
- package/packages/pi-tui/src/components/__tests__/input.test.ts +18 -0
- package/packages/pi-tui/src/keys.ts +32 -0
- package/pkg/package.json +1 -1
- package/src/resources/extensions/async-jobs/await-tool.test.ts +40 -7
- package/src/resources/extensions/async-jobs/await-tool.ts +7 -4
- package/src/resources/extensions/async-jobs/job-manager.ts +33 -3
- package/src/resources/extensions/claude-code-cli/partial-builder.ts +45 -12
- package/src/resources/extensions/claude-code-cli/stream-adapter.ts +49 -24
- package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +91 -2
- package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +112 -0
- package/src/resources/extensions/gsd/auto/loop.ts +89 -1
- package/src/resources/extensions/gsd/auto-post-unit.ts +7 -0
- package/src/resources/extensions/gsd/auto-recovery.ts +10 -0
- package/src/resources/extensions/gsd/auto.ts +25 -20
- package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +8 -10
- package/src/resources/extensions/gsd/commands-handlers.ts +5 -1
- package/src/resources/extensions/gsd/context-injector.ts +1 -1
- package/src/resources/extensions/gsd/custom-workflow-engine.ts +4 -8
- package/src/resources/extensions/gsd/definition-io.ts +18 -0
- package/src/resources/extensions/gsd/dispatch-guard.ts +5 -0
- package/src/resources/extensions/gsd/doctor-runtime-checks.ts +6 -3
- package/src/resources/extensions/gsd/git-service.ts +11 -8
- package/src/resources/extensions/gsd/gitignore.ts +12 -6
- package/src/resources/extensions/gsd/gsd-db.ts +54 -6
- package/src/resources/extensions/gsd/key-manager.ts +2 -0
- package/src/resources/extensions/gsd/preferences-skills.ts +2 -36
- package/src/resources/extensions/gsd/preferences-types.ts +16 -0
- package/src/resources/extensions/gsd/preferences.ts +19 -6
- package/src/resources/extensions/gsd/prompt-loader.ts +6 -1
- package/src/resources/extensions/gsd/prompts/discuss.md +122 -13
- package/src/resources/extensions/gsd/prompts/system.md +1 -1
- package/src/resources/extensions/gsd/state.ts +20 -0
- package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +27 -0
- package/src/resources/extensions/gsd/tests/block-db-writes.test.ts +63 -0
- package/src/resources/extensions/gsd/tests/definition-io.test.ts +57 -0
- package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +26 -0
- package/src/resources/extensions/gsd/tests/doctor-heal-fixable-warnings.test.ts +14 -0
- package/src/resources/extensions/gsd/tests/false-degraded-mode-warning.test.ts +104 -0
- package/src/resources/extensions/gsd/tests/gsd-db.test.ts +107 -5
- package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +8 -6
- package/src/resources/extensions/gsd/tests/key-manager.test.ts +63 -0
- package/src/resources/extensions/gsd/tests/memory-pressure-stuck-state.test.ts +54 -0
- package/src/resources/extensions/gsd/tests/plan-milestone-artifact-verification.test.ts +62 -0
- package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +34 -0
- package/src/resources/extensions/gsd/tests/preferences-formatting.test.ts +87 -0
- package/src/resources/extensions/gsd/tests/preferences.test.ts +53 -0
- package/src/resources/extensions/gsd/tests/projection-regression.test.ts +96 -1
- package/src/resources/extensions/gsd/tests/prompt-loader-working-directory.test.ts +19 -0
- package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +97 -0
- package/src/resources/extensions/gsd/tests/stale-slice-rows.test.ts +41 -0
- package/src/resources/extensions/gsd/workflow-projections.ts +8 -0
- package/src/resources/extensions/gsd/worktree-manager.ts +29 -3
- package/src/resources/extensions/gsd/write-intercept.ts +10 -1
- package/src/resources/extensions/ollama/index.ts +4 -5
- package/src/resources/extensions/ollama/ollama-client.ts +35 -6
- package/src/resources/extensions/ollama/ollama-discovery.ts +37 -6
- package/src/resources/extensions/ollama/tests/ollama-discovery.test.ts +54 -0
- package/dist/resources/extensions/gsd/auto-observability.js +0 -54
- package/dist/resources/extensions/gsd/file-watcher.js +0 -80
- package/dist/resources/extensions/gsd/rtk-status.js +0 -43
- package/src/resources/extensions/gsd/auto-observability.ts +0 -72
- package/src/resources/extensions/gsd/file-watcher.ts +0 -100
- package/src/resources/extensions/gsd/rtk-status.ts +0 -53
- /package/dist/web/standalone/.next/static/{Y0I7CjXJl-tWoV__KidV4 → KSZ2dcC3p4z6lOmUpPpzr}/_buildManifest.js +0 -0
- /package/dist/web/standalone/.next/static/{Y0I7CjXJl-tWoV__KidV4 → KSZ2dcC3p4z6lOmUpPpzr}/_ssgManifest.js +0 -0
|
@@ -219,6 +219,16 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
219
219
|
time("resourceLoader.reload");
|
|
220
220
|
}
|
|
221
221
|
|
|
222
|
+
// Flush provider registrations queued during extension loading so that
|
|
223
|
+
// extension models (e.g. pi-claude-cli) are visible in the registry before
|
|
224
|
+
// findInitialModel() runs. bindCore() repeats this flush as a safety net
|
|
225
|
+
// for any late-arriving registrations.
|
|
226
|
+
const { runtime: extensionRuntime } = resourceLoader.getExtensions();
|
|
227
|
+
for (const { name, config } of extensionRuntime.pendingProviderRegistrations) {
|
|
228
|
+
modelRegistry.registerProvider(name, config);
|
|
229
|
+
}
|
|
230
|
+
extensionRuntime.pendingProviderRegistrations = [];
|
|
231
|
+
|
|
222
232
|
// Check if session has existing data to restore
|
|
223
233
|
const existingSession = sessionManager.buildSessionContext();
|
|
224
234
|
const hasExistingSession = existingSession.messages.length > 0;
|
package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts
CHANGED
|
@@ -27,6 +27,26 @@ function renderTool(
|
|
|
27
27
|
return stripAnsi(component.render(120).join("\n"));
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
function renderToolCollapsed(
|
|
31
|
+
toolName: string,
|
|
32
|
+
args: Record<string, unknown>,
|
|
33
|
+
result?: {
|
|
34
|
+
content: Array<{ type: string; text?: string }>;
|
|
35
|
+
isError: boolean;
|
|
36
|
+
details?: Record<string, unknown>;
|
|
37
|
+
},
|
|
38
|
+
): string {
|
|
39
|
+
const component = new ToolExecutionComponent(
|
|
40
|
+
toolName,
|
|
41
|
+
args,
|
|
42
|
+
{},
|
|
43
|
+
undefined,
|
|
44
|
+
{ requestRender() {} } as any,
|
|
45
|
+
);
|
|
46
|
+
if (result) component.updateResult(result);
|
|
47
|
+
return stripAnsi(component.render(120).join("\n"));
|
|
48
|
+
}
|
|
49
|
+
|
|
30
50
|
describe("ToolExecutionComponent", () => {
|
|
31
51
|
test("renders capitalized Claude Code Bash tool names with bash output instead of generic args JSON", () => {
|
|
32
52
|
const rendered = renderTool(
|
|
@@ -51,4 +71,56 @@ describe("ToolExecutionComponent", () => {
|
|
|
51
71
|
assert.match(rendered, /hello/);
|
|
52
72
|
assert.match(rendered, /world/);
|
|
53
73
|
});
|
|
74
|
+
|
|
75
|
+
test("generic fallback strips mcp__<server>__ prefix and shows server·tool title", () => {
|
|
76
|
+
const rendered = renderTool(
|
|
77
|
+
"mcp__context7__resolve_library_id",
|
|
78
|
+
{ name: "react" },
|
|
79
|
+
{ content: [{ type: "text", text: "react@18.3.1" }], isError: false },
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
assert.match(rendered, /context7\u00b7resolve_library_id/);
|
|
83
|
+
assert.doesNotMatch(rendered, /mcp__/);
|
|
84
|
+
assert.match(rendered, /name="react"/);
|
|
85
|
+
assert.match(rendered, /react@18\.3\.1/);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
test("generic fallback renders compact key=value args for primitive args", () => {
|
|
89
|
+
const rendered = renderTool(
|
|
90
|
+
"some_unknown_tool",
|
|
91
|
+
{ count: 3, enabled: true, label: "hello" },
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
assert.match(rendered, /some_unknown_tool/);
|
|
95
|
+
assert.match(rendered, /count=3/);
|
|
96
|
+
assert.match(rendered, /enabled=true/);
|
|
97
|
+
assert.match(rendered, /label="hello"/);
|
|
98
|
+
assert.doesNotMatch(rendered, /^\{$/m);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
test("generic fallback truncates long output when collapsed", () => {
|
|
102
|
+
const longOutput = Array.from({ length: 25 }, (_, i) => `line ${i + 1}`).join("\n");
|
|
103
|
+
const rendered = renderToolCollapsed(
|
|
104
|
+
"mcp__demo__do_thing",
|
|
105
|
+
{ ok: true },
|
|
106
|
+
{ content: [{ type: "text", text: longOutput }], isError: false },
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
assert.match(rendered, /line 1\b/);
|
|
110
|
+
assert.match(rendered, /line 10\b/);
|
|
111
|
+
assert.doesNotMatch(rendered, /line 20\b/);
|
|
112
|
+
assert.match(rendered, /\(15 more lines/);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
test("generic fallback falls back to truncated JSON for complex args", () => {
|
|
116
|
+
const rendered = renderTool(
|
|
117
|
+
"mcp__demo__nested",
|
|
118
|
+
{ payload: { nested: { deeply: ["a", "b", "c"] } }, name: "x" },
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
assert.match(rendered, /demo\u00b7nested/);
|
|
122
|
+
// Multi-line JSON dump for the complex payload
|
|
123
|
+
assert.match(rendered, /"payload"/);
|
|
124
|
+
assert.match(rendered, /"nested"/);
|
|
125
|
+
});
|
|
54
126
|
});
|
|
@@ -51,6 +51,60 @@ function str(value: unknown): string | null {
|
|
|
51
51
|
return null; // Invalid type
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
/**
|
|
55
|
+
* Split a Claude Code MCP tool name (`mcp__<server>__<tool>`) into its parts.
|
|
56
|
+
* Returns null for non-prefixed names. Duplicated from the claude-code-cli
|
|
57
|
+
* extension (parseMcpToolName) so this package doesn't have to import across
|
|
58
|
+
* the resources/extensions boundary.
|
|
59
|
+
*/
|
|
60
|
+
function parseMcpToolName(name: string): { server: string; tool: string } | null {
|
|
61
|
+
if (!name.startsWith("mcp__")) return null;
|
|
62
|
+
const rest = name.slice("mcp__".length);
|
|
63
|
+
const delim = rest.indexOf("__");
|
|
64
|
+
if (delim <= 0 || delim === rest.length - 2) return null;
|
|
65
|
+
return { server: rest.slice(0, delim), tool: rest.slice(delim + 2) };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const COMPACT_ARG_VALUE_LIMIT = 60;
|
|
69
|
+
const GENERIC_OUTPUT_PREVIEW_LINES = 10;
|
|
70
|
+
const GENERIC_ARGS_JSON_PREVIEW_LINES = 10;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Format tool args for the generic-renderer fallback. Produces a one-line
|
|
74
|
+
* `k=v, k=v` summary when every value is a primitive that fits inline; falls
|
|
75
|
+
* back to a truncated JSON dump for structurally complex args.
|
|
76
|
+
*/
|
|
77
|
+
function formatCompactArgs(args: unknown, expanded: boolean): string {
|
|
78
|
+
if (args == null) return "";
|
|
79
|
+
if (typeof args !== "object") return String(args);
|
|
80
|
+
|
|
81
|
+
const entries = Object.entries(args as Record<string, unknown>);
|
|
82
|
+
if (entries.length === 0) return "";
|
|
83
|
+
|
|
84
|
+
const allPrimitive = entries.every(([, value]) => {
|
|
85
|
+
const t = typeof value;
|
|
86
|
+
if (t === "number" || t === "boolean") return true;
|
|
87
|
+
if (t === "string") return (value as string).length <= COMPACT_ARG_VALUE_LIMIT;
|
|
88
|
+
return value == null;
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
if (allPrimitive) {
|
|
92
|
+
return entries
|
|
93
|
+
.map(([key, value]) => {
|
|
94
|
+
if (typeof value === "string") return `${key}=${JSON.stringify(value)}`;
|
|
95
|
+
if (value == null) return `${key}=null`;
|
|
96
|
+
return `${key}=${String(value)}`;
|
|
97
|
+
})
|
|
98
|
+
.join(", ");
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Complex args: show truncated JSON.
|
|
102
|
+
const lines = JSON.stringify(args, null, 2).split("\n");
|
|
103
|
+
const maxLines = expanded ? lines.length : GENERIC_ARGS_JSON_PREVIEW_LINES;
|
|
104
|
+
if (lines.length <= maxLines) return lines.join("\n");
|
|
105
|
+
return lines.slice(0, maxLines).join("\n") + "\n...";
|
|
106
|
+
}
|
|
107
|
+
|
|
54
108
|
export interface ToolExecutionOptions {
|
|
55
109
|
showImages?: boolean; // default: true (only used if terminal supports images)
|
|
56
110
|
}
|
|
@@ -990,19 +1044,37 @@ export class ToolExecutionComponent extends Container {
|
|
|
990
1044
|
}
|
|
991
1045
|
}
|
|
992
1046
|
} else {
|
|
993
|
-
// Generic tool
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
const
|
|
999
|
-
|
|
1000
|
-
|
|
1047
|
+
// Generic tool / MCP tool without a registered renderer.
|
|
1048
|
+
// MCP tool names from Claude Code arrive as `mcp__<server>__<tool>`;
|
|
1049
|
+
// render the server prefix in muted style so the tool name reads
|
|
1050
|
+
// cleanly. GSD-registered MCP tools have already had their prefix
|
|
1051
|
+
// stripped upstream in partial-builder.ts and won't reach this branch.
|
|
1052
|
+
const parsed = parseMcpToolName(this.toolName);
|
|
1053
|
+
const displayName = parsed ? parsed.tool : this.toolName;
|
|
1054
|
+
const serverPrefix = parsed ? theme.fg("muted", `${parsed.server}\u00b7`) : "";
|
|
1055
|
+
text = serverPrefix + theme.fg("toolTitle", theme.bold(displayName));
|
|
1056
|
+
|
|
1057
|
+
const argsText = formatCompactArgs(this.args, this.expanded);
|
|
1058
|
+
if (argsText) {
|
|
1059
|
+
if (argsText.includes("\n")) {
|
|
1060
|
+
text += `\n\n${theme.fg("toolOutput", argsText)}`;
|
|
1061
|
+
} else {
|
|
1062
|
+
text += " " + theme.fg("toolOutput", argsText);
|
|
1063
|
+
}
|
|
1001
1064
|
}
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1065
|
+
|
|
1066
|
+
if (this.result) {
|
|
1067
|
+
const output = this.getTextOutput().trim();
|
|
1068
|
+
if (output) {
|
|
1069
|
+
const lines = output.split("\n");
|
|
1070
|
+
const maxLines = this.expanded ? lines.length : GENERIC_OUTPUT_PREVIEW_LINES;
|
|
1071
|
+
const displayLines = lines.slice(0, maxLines);
|
|
1072
|
+
const remaining = lines.length - maxLines;
|
|
1073
|
+
text += `\n\n${displayLines.map((line: string) => theme.fg("toolOutput", line)).join("\n")}`;
|
|
1074
|
+
if (remaining > 0) {
|
|
1075
|
+
text += `${theme.fg("muted", `\n... (${remaining} more lines,`)} ${keyHint("expandTools", "to expand")})`;
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1006
1078
|
}
|
|
1007
1079
|
}
|
|
1008
1080
|
|
|
@@ -50,5 +50,17 @@ describe("Editor", () => {
|
|
|
50
50
|
const rendered = editor.render(40).join("\n");
|
|
51
51
|
assert.ok(rendered.includes(CURSOR_MARKER));
|
|
52
52
|
});
|
|
53
|
+
it("maps kitty keypad digits to plain editor text", () => {
|
|
54
|
+
const editor = new Editor(new TUI(makeTerminal()), theme);
|
|
55
|
+
editor.focused = true;
|
|
56
|
+
editor.handleInput("\x1b[57404;129u");
|
|
57
|
+
assert.equal(editor.getText(), "5");
|
|
58
|
+
});
|
|
59
|
+
it("does not insert kitty keypad navigation private-use glyphs into the editor", () => {
|
|
60
|
+
const editor = new Editor(new TUI(makeTerminal()), theme);
|
|
61
|
+
editor.focused = true;
|
|
62
|
+
editor.handleInput("\x1b[57419u");
|
|
63
|
+
assert.equal(editor.getText(), "");
|
|
64
|
+
});
|
|
53
65
|
});
|
|
54
66
|
//# sourceMappingURL=editor.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor.test.js","sourceRoot":"","sources":["../../../src/components/__tests__/editor.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,EAAE,MAAM,EAAoB,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAGlD,SAAS,YAAY;IACpB,OAAO;QACN,KAAK,EAAE,IAAI;QACX,OAAO,EAAE,EAAE;QACX,IAAI,EAAE,EAAE;QACR,mBAAmB,EAAE,KAAK;QAC1B,KAAK,KAAI,CAAC;QACV,IAAI,KAAI,CAAC;QACT,UAAU,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QAC1B,KAAK,KAAI,CAAC;QACV,MAAM,KAAI,CAAC;QACX,UAAU,KAAI,CAAC;QACf,UAAU,KAAI,CAAC;QACf,SAAS,KAAI,CAAC;QACd,eAAe,KAAI,CAAC;QACpB,WAAW,KAAI,CAAC;QAChB,QAAQ,KAAI,CAAC;KACb,CAAC;AACH,CAAC;AAED,MAAM,KAAK,GAAgB;IAC1B,WAAW,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI;IAC3B,UAAU,EAAE;QACX,cAAc,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI;QAC9B,YAAY,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI;QAC5B,WAAW,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI;QAC3B,UAAU,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI;QAC1B,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI;KACvB;CACD,CAAC;AAEF,QAAQ,CAAC,QAAQ,EAAE,GAAG,EAAE;IACvB,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QAC1D,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,GAAG,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;QAC1D,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;QAEtB,MAAM,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC;QACvC,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC;QACvB,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;QACtB,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAE5B,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qEAAqE,EAAE,GAAG,EAAE;QAC9E,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,GAAG,CAAC,YAAY,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;QAC1D,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;QACtB,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAErB,MAAc,CAAC,iBAAiB,GAAG,SAAS,CAAC;QAC7C,MAAc,CAAC,gBAAgB,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAExD,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAE9C,MAAM,CAAC,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC;IAC7C,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["import assert from \"node:assert/strict\";\nimport { describe, it } from \"node:test\";\n\nimport { Editor, type EditorTheme } from \"../editor.js\";\nimport { CURSOR_MARKER, TUI } from \"../../tui.js\";\nimport type { Terminal } from \"../../terminal.js\";\n\nfunction makeTerminal(): Terminal {\n\treturn {\n\t\tisTTY: true,\n\t\tcolumns: 80,\n\t\trows: 24,\n\t\tkittyProtocolActive: false,\n\t\tstart() {},\n\t\tstop() {},\n\t\tdrainInput: async () => {},\n\t\twrite() {},\n\t\tmoveBy() {},\n\t\thideCursor() {},\n\t\tshowCursor() {},\n\t\tclearLine() {},\n\t\tclearFromCursor() {},\n\t\tclearScreen() {},\n\t\tsetTitle() {},\n\t};\n}\n\nconst theme: EditorTheme = {\n\tborderColor: (text) => text,\n\tselectList: {\n\t\tselectedPrefix: (text) => text,\n\t\tselectedText: (text) => text,\n\t\tdescription: (text) => text,\n\t\tscrollInfo: (text) => text,\n\t\tnoMatch: (text) => text,\n\t},\n};\n\ndescribe(\"Editor\", () => {\n\tit(\"clears bracketed paste state when focus is lost\", () => {\n\t\tconst editor = new Editor(new TUI(makeTerminal()), theme);\n\t\teditor.focused = true;\n\n\t\teditor.handleInput(\"\\x1b[200~partial\");\n\t\teditor.focused = false;\n\t\teditor.focused = true;\n\t\teditor.handleInput(\"hello\");\n\n\t\tassert.equal(editor.getText(), \"hello\");\n\t});\n\n\tit(\"keeps the hardware cursor marker visible while autocomplete is open\", () => {\n\t\tconst editor = new Editor(new TUI(makeTerminal()), theme);\n\t\teditor.focused = true;\n\t\teditor.setText(\"/se\");\n\n\t\t(editor as any).autocompleteState = \"regular\";\n\t\t(editor as any).autocompleteList = { render: () => [] };\n\n\t\tconst rendered = editor.render(40).join(\"\\n\");\n\n\t\tassert.ok(rendered.includes(CURSOR_MARKER));\n\t});\n});\n"]}
|
|
1
|
+
{"version":3,"file":"editor.test.js","sourceRoot":"","sources":["../../../src/components/__tests__/editor.test.ts"],"names":[],"mappings":"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","sourcesContent":["import assert from \"node:assert/strict\";\nimport { describe, it } from \"node:test\";\n\nimport { Editor, type EditorTheme } from \"../editor.js\";\nimport { CURSOR_MARKER, TUI } from \"../../tui.js\";\nimport type { Terminal } from \"../../terminal.js\";\n\nfunction makeTerminal(): Terminal {\n\treturn {\n\t\tisTTY: true,\n\t\tcolumns: 80,\n\t\trows: 24,\n\t\tkittyProtocolActive: false,\n\t\tstart() {},\n\t\tstop() {},\n\t\tdrainInput: async () => {},\n\t\twrite() {},\n\t\tmoveBy() {},\n\t\thideCursor() {},\n\t\tshowCursor() {},\n\t\tclearLine() {},\n\t\tclearFromCursor() {},\n\t\tclearScreen() {},\n\t\tsetTitle() {},\n\t};\n}\n\nconst theme: EditorTheme = {\n\tborderColor: (text) => text,\n\tselectList: {\n\t\tselectedPrefix: (text) => text,\n\t\tselectedText: (text) => text,\n\t\tdescription: (text) => text,\n\t\tscrollInfo: (text) => text,\n\t\tnoMatch: (text) => text,\n\t},\n};\n\ndescribe(\"Editor\", () => {\n\tit(\"clears bracketed paste state when focus is lost\", () => {\n\t\tconst editor = new Editor(new TUI(makeTerminal()), theme);\n\t\teditor.focused = true;\n\n\t\teditor.handleInput(\"\\x1b[200~partial\");\n\t\teditor.focused = false;\n\t\teditor.focused = true;\n\t\teditor.handleInput(\"hello\");\n\n\t\tassert.equal(editor.getText(), \"hello\");\n\t});\n\n\tit(\"keeps the hardware cursor marker visible while autocomplete is open\", () => {\n\t\tconst editor = new Editor(new TUI(makeTerminal()), theme);\n\t\teditor.focused = true;\n\t\teditor.setText(\"/se\");\n\n\t\t(editor as any).autocompleteState = \"regular\";\n\t\t(editor as any).autocompleteList = { render: () => [] };\n\n\t\tconst rendered = editor.render(40).join(\"\\n\");\n\n\t\tassert.ok(rendered.includes(CURSOR_MARKER));\n\t});\n\n\tit(\"maps kitty keypad digits to plain editor text\", () => {\n\t\tconst editor = new Editor(new TUI(makeTerminal()), theme);\n\t\teditor.focused = true;\n\n\t\teditor.handleInput(\"\\x1b[57404;129u\");\n\n\t\tassert.equal(editor.getText(), \"5\");\n\t});\n\n\tit(\"does not insert kitty keypad navigation private-use glyphs into the editor\", () => {\n\t\tconst editor = new Editor(new TUI(makeTerminal()), theme);\n\t\teditor.focused = true;\n\n\t\teditor.handleInput(\"\\x1b[57419u\");\n\n\t\tassert.equal(editor.getText(), \"\");\n\t});\n});\n"]}
|
|
@@ -34,5 +34,17 @@ describe("Input", () => {
|
|
|
34
34
|
assert.ok(!line.includes("secret123"), "rendered line must not expose raw secret text");
|
|
35
35
|
assert.ok(line.includes("*********"), "rendered line should include masked characters");
|
|
36
36
|
});
|
|
37
|
+
it("maps kitty keypad digits to text instead of inserting private-use glyphs", () => {
|
|
38
|
+
const input = new Input();
|
|
39
|
+
input.focused = true;
|
|
40
|
+
input.handleInput("\x1b[57400;129u");
|
|
41
|
+
assert.equal(input.getValue(), "1");
|
|
42
|
+
});
|
|
43
|
+
it("ignores kitty keypad navigation keys in text input", () => {
|
|
44
|
+
const input = new Input();
|
|
45
|
+
input.focused = true;
|
|
46
|
+
input.handleInput("\x1b[57417u");
|
|
47
|
+
assert.equal(input.getValue(), "");
|
|
48
|
+
});
|
|
37
49
|
});
|
|
38
50
|
//# sourceMappingURL=input.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"input.test.js","sourceRoot":"","sources":["../../../src/components/__tests__/input.test.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,4DAA4D;AAE5D,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE;IACtB,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACrD,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE,CAAC;QAC1B,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;QAErB,yDAAyD;QACzD,KAAK,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC;QAEtC,2BAA2B;QAC3B,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC;QAEtB,mDAAmD;QACnD,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;QAErB,iEAAiE;QACjE,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAC3B,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAChD,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE,CAAC;QAC1B,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACnC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;QACrB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAClC,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC;QACtB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QACjE,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE,CAAC;QAC1B,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC;QACpB,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;QACrB,KAAK,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;QAE/B,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACvC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,+CAA+C,CAAC,CAAC;QACxF,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,gDAAgD,CAAC,CAAC;IACzF,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["// pi-tui Input component regression tests\n// Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>\n\nimport { describe, it } from \"node:test\";\nimport assert from \"node:assert/strict\";\nimport { Input } from \"../input.js\";\n\ndescribe(\"Input\", () => {\n\tit(\"paste buffer is cleared when focus is lost\", () => {\n\t\tconst input = new Input();\n\t\tinput.focused = true;\n\n\t\t// Simulate starting a paste (bracket paste start marker)\n\t\tinput.handleInput(\"\\x1b[200~partial\");\n\n\t\t// Now lose focus mid-paste\n\t\tinput.focused = false;\n\n\t\t// Regain focus — should not have stale paste state\n\t\tinput.focused = true;\n\n\t\t// Typing normal text should work without paste buffer corruption\n\t\tinput.handleInput(\"hello\");\n\t\tassert.equal(input.getValue(), \"hello\");\n\t});\n\n\tit(\"focused getter/setter works correctly\", () => {\n\t\tconst input = new Input();\n\t\tassert.equal(input.focused, false);\n\t\tinput.focused = true;\n\t\tassert.equal(input.focused, true);\n\t\tinput.focused = false;\n\t\tassert.equal(input.focused, false);\n\t});\n\n\tit(\"secure mode obscures typed characters in render output\", () => {\n\t\tconst input = new Input();\n\t\tinput.secure = true;\n\t\tinput.focused = true;\n\t\tinput.handleInput(\"secret123\");\n\n\t\tconst line = input.render(40)[0] ?? \"\";\n\t\tassert.ok(!line.includes(\"secret123\"), \"rendered line must not expose raw secret text\");\n\t\tassert.ok(line.includes(\"*********\"), \"rendered line should include masked characters\");\n\t});\n});\n"]}
|
|
1
|
+
{"version":3,"file":"input.test.js","sourceRoot":"","sources":["../../../src/components/__tests__/input.test.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,4DAA4D;AAE5D,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAEpC,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE;IACtB,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACrD,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE,CAAC;QAC1B,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;QAErB,yDAAyD;QACzD,KAAK,CAAC,WAAW,CAAC,kBAAkB,CAAC,CAAC;QAEtC,2BAA2B;QAC3B,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC;QAEtB,mDAAmD;QACnD,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;QAErB,iEAAiE;QACjE,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAC3B,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,OAAO,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAChD,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE,CAAC;QAC1B,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACnC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;QACrB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAClC,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC;QACtB,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QACjE,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE,CAAC;QAC1B,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC;QACpB,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;QACrB,KAAK,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;QAE/B,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACvC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,+CAA+C,CAAC,CAAC;QACxF,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,gDAAgD,CAAC,CAAC;IACzF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0EAA0E,EAAE,GAAG,EAAE;QACnF,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE,CAAC;QAC1B,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;QAErB,KAAK,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAC;QAErC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,GAAG,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC7D,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE,CAAC;QAC1B,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;QAErB,KAAK,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;QAEjC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["// pi-tui Input component regression tests\n// Copyright (c) 2026 Jeremy McSpadden <jeremy@fluxlabs.net>\n\nimport { describe, it } from \"node:test\";\nimport assert from \"node:assert/strict\";\nimport { Input } from \"../input.js\";\n\ndescribe(\"Input\", () => {\n\tit(\"paste buffer is cleared when focus is lost\", () => {\n\t\tconst input = new Input();\n\t\tinput.focused = true;\n\n\t\t// Simulate starting a paste (bracket paste start marker)\n\t\tinput.handleInput(\"\\x1b[200~partial\");\n\n\t\t// Now lose focus mid-paste\n\t\tinput.focused = false;\n\n\t\t// Regain focus — should not have stale paste state\n\t\tinput.focused = true;\n\n\t\t// Typing normal text should work without paste buffer corruption\n\t\tinput.handleInput(\"hello\");\n\t\tassert.equal(input.getValue(), \"hello\");\n\t});\n\n\tit(\"focused getter/setter works correctly\", () => {\n\t\tconst input = new Input();\n\t\tassert.equal(input.focused, false);\n\t\tinput.focused = true;\n\t\tassert.equal(input.focused, true);\n\t\tinput.focused = false;\n\t\tassert.equal(input.focused, false);\n\t});\n\n\tit(\"secure mode obscures typed characters in render output\", () => {\n\t\tconst input = new Input();\n\t\tinput.secure = true;\n\t\tinput.focused = true;\n\t\tinput.handleInput(\"secret123\");\n\n\t\tconst line = input.render(40)[0] ?? \"\";\n\t\tassert.ok(!line.includes(\"secret123\"), \"rendered line must not expose raw secret text\");\n\t\tassert.ok(line.includes(\"*********\"), \"rendered line should include masked characters\");\n\t});\n\n\tit(\"maps kitty keypad digits to text instead of inserting private-use glyphs\", () => {\n\t\tconst input = new Input();\n\t\tinput.focused = true;\n\n\t\tinput.handleInput(\"\\x1b[57400;129u\");\n\n\t\tassert.equal(input.getValue(), \"1\");\n\t});\n\n\tit(\"ignores kitty keypad navigation keys in text input\", () => {\n\t\tconst input = new Input();\n\t\tinput.focused = true;\n\n\t\tinput.handleInput(\"\\x1b[57417u\");\n\n\t\tassert.equal(input.getValue(), \"\");\n\t});\n});\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../src/keys.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../src/keys.ts"],"names":[],"mappings":"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"}
|
|
@@ -171,6 +171,26 @@ const CODEPOINTS = {
|
|
|
171
171
|
backspace: 127,
|
|
172
172
|
kpEnter: 57414, // Numpad Enter (Kitty protocol)
|
|
173
173
|
};
|
|
174
|
+
const KITTY_PRIVATE_USE_RANGE = { start: 57344, end: 63743 };
|
|
175
|
+
const KITTY_KEYPAD_PRINTABLES = new Map([
|
|
176
|
+
[57399, "0"], // KP_0
|
|
177
|
+
[57400, "1"], // KP_1
|
|
178
|
+
[57401, "2"], // KP_2
|
|
179
|
+
[57402, "3"], // KP_3
|
|
180
|
+
[57403, "4"], // KP_4
|
|
181
|
+
[57404, "5"], // KP_5
|
|
182
|
+
[57405, "6"], // KP_6
|
|
183
|
+
[57406, "7"], // KP_7
|
|
184
|
+
[57407, "8"], // KP_8
|
|
185
|
+
[57408, "9"], // KP_9
|
|
186
|
+
[57409, "."], // KP_DECIMAL
|
|
187
|
+
[57410, "/"], // KP_DIVIDE
|
|
188
|
+
[57411, "*"], // KP_MULTIPLY
|
|
189
|
+
[57412, "-"], // KP_SUBTRACT
|
|
190
|
+
[57413, "+"], // KP_ADD
|
|
191
|
+
[57415, "="], // KP_EQUAL
|
|
192
|
+
[57416, ","], // KP_SEPARATOR
|
|
193
|
+
]);
|
|
174
194
|
const ARROW_CODEPOINTS = {
|
|
175
195
|
up: -1,
|
|
176
196
|
down: -2,
|
|
@@ -968,6 +988,13 @@ export function decodeKittyPrintable(data) {
|
|
|
968
988
|
// Drop control characters or invalid codepoints.
|
|
969
989
|
if (!Number.isFinite(effectiveCodepoint) || effectiveCodepoint < 32)
|
|
970
990
|
return undefined;
|
|
991
|
+
const keypadPrintable = KITTY_KEYPAD_PRINTABLES.get(effectiveCodepoint);
|
|
992
|
+
if (keypadPrintable !== undefined)
|
|
993
|
+
return keypadPrintable;
|
|
994
|
+
if (effectiveCodepoint >= KITTY_PRIVATE_USE_RANGE.start &&
|
|
995
|
+
effectiveCodepoint <= KITTY_PRIVATE_USE_RANGE.end) {
|
|
996
|
+
return undefined;
|
|
997
|
+
}
|
|
971
998
|
try {
|
|
972
999
|
return String.fromCodePoint(effectiveCodepoint);
|
|
973
1000
|
}
|