pi-soly 1.9.3 → 1.11.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/ask/index.ts +12 -11
- package/ask/picker.ts +356 -76
- package/ask/prompt.ts +6 -2
- package/ask/tests/picker.test.ts +273 -82
- package/codemap.ts +276 -0
- package/hotreload.ts +239 -0
- package/init.ts +302 -0
- package/mcp/CHANGELOG.md +384 -0
- package/mcp/LICENSE +21 -0
- package/mcp/OAUTH.md +355 -0
- package/mcp/README.md +410 -0
- package/mcp/__tests__/agent-dir-paths.upstream-test.ts +80 -0
- package/mcp/__tests__/cli.upstream-test.ts +97 -0
- package/mcp/__tests__/commands-onboarding.upstream-test.ts +157 -0
- package/mcp/__tests__/config.upstream-test.ts +303 -0
- package/mcp/__tests__/consent-manager.upstream-test.ts +151 -0
- package/mcp/__tests__/direct-tools-auto-auth.upstream-test.ts +218 -0
- package/mcp/__tests__/direct-tools.upstream-test.ts +299 -0
- package/mcp/__tests__/elicitation-handler.upstream-test.ts +346 -0
- package/mcp/__tests__/elicitation-sdk-integration.upstream-test.ts +140 -0
- package/mcp/__tests__/errors.upstream-test.ts +218 -0
- package/mcp/__tests__/fixtures/elicitation-server.mjs +98 -0
- package/mcp/__tests__/host-html-template.upstream-test.ts +278 -0
- package/mcp/__tests__/index-lifecycle.upstream-test.ts +484 -0
- package/mcp/__tests__/init-elicitation.upstream-test.ts +86 -0
- package/mcp/__tests__/interactive-visualizer-server.upstream-test.ts +28 -0
- package/mcp/__tests__/logger.upstream-test.ts +175 -0
- package/mcp/__tests__/mcp-auth-flow-client-credentials.upstream-test.ts +612 -0
- package/mcp/__tests__/mcp-auth-storage.upstream-test.ts +47 -0
- package/mcp/__tests__/mcp-callback-server-unref.upstream-test.ts +264 -0
- package/mcp/__tests__/mcp-oauth-provider.upstream-test.ts +216 -0
- package/mcp/__tests__/mcp-panel-auth.upstream-test.ts +206 -0
- package/mcp/__tests__/mcp-panel-exclude-tools.upstream-test.ts +69 -0
- package/mcp/__tests__/mcp-panel-keybindings.upstream-test.ts +186 -0
- package/mcp/__tests__/npx-resolver.upstream-test.ts +54 -0
- package/mcp/__tests__/oauth-handler.upstream-test.ts +77 -0
- package/mcp/__tests__/onboarding-state.upstream-test.ts +52 -0
- package/mcp/__tests__/package-manifest.upstream-test.ts +22 -0
- package/mcp/__tests__/proxy-modes-auto-auth.upstream-test.ts +253 -0
- package/mcp/__tests__/proxy-modes-discovery.upstream-test.ts +84 -0
- package/mcp/__tests__/proxy-modes-manual-auth.upstream-test.ts +91 -0
- package/mcp/__tests__/proxy-modes-ui-messages.upstream-test.ts +72 -0
- package/mcp/__tests__/sampling-handler.upstream-test.ts +285 -0
- package/mcp/__tests__/server-manager-http-auth.upstream-test.ts +144 -0
- package/mcp/__tests__/server-manager-sampling.upstream-test.ts +236 -0
- package/mcp/__tests__/tool-metadata.upstream-test.ts +111 -0
- package/mcp/__tests__/tool-result-renderer.upstream-test.ts +147 -0
- package/mcp/__tests__/ui-integration.upstream-test.ts +551 -0
- package/mcp/__tests__/ui-resource-handler.upstream-test.ts +303 -0
- package/mcp/__tests__/ui-server.upstream-test.ts +967 -0
- package/mcp/__tests__/ui-session-messages.upstream-test.ts +72 -0
- package/mcp/__tests__/ui-streaming.upstream-test.ts +543 -0
- package/mcp/agent-dir.ts +20 -0
- package/mcp/app-bridge.bundle.js +67 -0
- package/mcp/cli.js +184 -0
- package/mcp/commands.ts +422 -0
- package/mcp/config.ts +666 -0
- package/mcp/consent-manager.ts +64 -0
- package/mcp/direct-tools.ts +439 -0
- package/mcp/elicitation-handler.ts +347 -0
- package/mcp/errors.ts +219 -0
- package/mcp/glimpse-ui.ts +80 -0
- package/mcp/host-html-template.ts +427 -0
- package/mcp/index.ts +362 -0
- package/mcp/init.ts +362 -0
- package/mcp/lifecycle.ts +93 -0
- package/mcp/logger.ts +169 -0
- package/mcp/mcp-auth-flow.ts +559 -0
- package/mcp/mcp-auth-flow.upstream-test.ts +259 -0
- package/mcp/mcp-auth.ts +302 -0
- package/mcp/mcp-auth.upstream-test.ts +373 -0
- package/mcp/mcp-callback-server.ts +372 -0
- package/mcp/mcp-callback-server.upstream-test.ts +416 -0
- package/mcp/mcp-oauth-provider.ts +369 -0
- package/mcp/mcp-oauth-provider.upstream-test.ts +518 -0
- package/mcp/mcp-panel.ts +829 -0
- package/mcp/mcp-setup-panel.ts +580 -0
- package/mcp/metadata-cache.ts +201 -0
- package/mcp/notify.ts +111 -0
- package/mcp/npx-resolver.ts +424 -0
- package/mcp/oauth-handler.ts +57 -0
- package/mcp/onboarding-state.ts +68 -0
- package/mcp/package.json +106 -0
- package/mcp/panel-keys.ts +37 -0
- package/mcp/proxy-modes.ts +949 -0
- package/mcp/resource-tools.ts +17 -0
- package/mcp/sampling-handler.ts +268 -0
- package/mcp/server-manager.ts +545 -0
- package/mcp/state.ts +41 -0
- package/mcp/tool-metadata.ts +216 -0
- package/mcp/tool-registrar.ts +46 -0
- package/mcp/tool-result-renderer.ts +161 -0
- package/mcp/types.ts +448 -0
- package/mcp/ui-resource-handler.ts +146 -0
- package/mcp/ui-server.ts +623 -0
- package/mcp/ui-session.ts +386 -0
- package/mcp/ui-stream-types.ts +89 -0
- package/mcp/utils.ts +129 -0
- package/mcp/vitest.config.ts +14 -0
- package/migrate.ts +258 -0
- package/notification.ts +218 -0
- package/notifications-log.ts +83 -0
- package/package.json +20 -3
- package/status.ts +140 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { formatSchema } from "../tool-metadata.ts";
|
|
3
|
+
|
|
4
|
+
describe("formatSchema", () => {
|
|
5
|
+
it("keeps simple object schemas compact", () => {
|
|
6
|
+
const schema = {
|
|
7
|
+
type: "object",
|
|
8
|
+
properties: {
|
|
9
|
+
query: { type: "string", description: "Search term", default: "all" },
|
|
10
|
+
limit: { type: ["number", "null"] },
|
|
11
|
+
mode: { enum: ["fast", "safe"] },
|
|
12
|
+
},
|
|
13
|
+
required: ["query"],
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
expect(formatSchema(schema)).toBe([
|
|
17
|
+
" query (string) *required* - Search term [default: \"all\"]",
|
|
18
|
+
" limit (number | null)",
|
|
19
|
+
" mode (enum: \"fast\", \"safe\")",
|
|
20
|
+
].join("\n"));
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it("expands union branches with const discriminator fields", () => {
|
|
24
|
+
const schema = {
|
|
25
|
+
type: "object",
|
|
26
|
+
properties: {
|
|
27
|
+
document: {
|
|
28
|
+
anyOf: [
|
|
29
|
+
{
|
|
30
|
+
type: "object",
|
|
31
|
+
properties: {
|
|
32
|
+
type: { const: "text" },
|
|
33
|
+
content: { type: "string", minLength: 1 },
|
|
34
|
+
},
|
|
35
|
+
required: ["type", "content"],
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
type: "object",
|
|
39
|
+
properties: {
|
|
40
|
+
type: { const: "file" },
|
|
41
|
+
path: { type: "string", minLength: 1 },
|
|
42
|
+
},
|
|
43
|
+
required: ["type", "path"],
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
required: ["document"],
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
expect(formatSchema(schema)).toBe([
|
|
52
|
+
" document *required*",
|
|
53
|
+
" anyOf:",
|
|
54
|
+
" - object",
|
|
55
|
+
" type (const \"text\") *required*",
|
|
56
|
+
" content (string) *required* [minLength: 1]",
|
|
57
|
+
" - object",
|
|
58
|
+
" type (const \"file\") *required*",
|
|
59
|
+
" path (string) *required* [minLength: 1]",
|
|
60
|
+
].join("\n"));
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it("formats oneOf branches", () => {
|
|
64
|
+
const schema = {
|
|
65
|
+
type: "object",
|
|
66
|
+
properties: {
|
|
67
|
+
target: {
|
|
68
|
+
oneOf: [
|
|
69
|
+
{ const: "draft" },
|
|
70
|
+
{ const: "published" },
|
|
71
|
+
],
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
expect(formatSchema(schema)).toBe([
|
|
77
|
+
" target",
|
|
78
|
+
" oneOf:",
|
|
79
|
+
" - const \"draft\"",
|
|
80
|
+
" - const \"published\"",
|
|
81
|
+
].join("\n"));
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it("formats nested object properties and array items", () => {
|
|
85
|
+
const schema = {
|
|
86
|
+
type: "object",
|
|
87
|
+
properties: {
|
|
88
|
+
config: {
|
|
89
|
+
type: "object",
|
|
90
|
+
properties: {
|
|
91
|
+
enabled: { type: "boolean" },
|
|
92
|
+
tags: {
|
|
93
|
+
type: "array",
|
|
94
|
+
items: { enum: ["alpha", "beta"] },
|
|
95
|
+
minItems: 1,
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
required: ["enabled"],
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
required: ["config"],
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
expect(formatSchema(schema)).toBe([
|
|
105
|
+
" config (object) *required*",
|
|
106
|
+
" enabled (boolean) *required*",
|
|
107
|
+
" tags (array) [minItems: 1]",
|
|
108
|
+
" items (enum: \"alpha\", \"beta\")",
|
|
109
|
+
].join("\n"));
|
|
110
|
+
});
|
|
111
|
+
});
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import type { AgentToolResult, ToolRenderResultOptions } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
import {
|
|
4
|
+
formatMcpDirectToolCallLines,
|
|
5
|
+
formatMcpProxyToolCallLines,
|
|
6
|
+
formatMcpToolResultLines,
|
|
7
|
+
renderMcpToolResult,
|
|
8
|
+
} from "../tool-result-renderer.ts";
|
|
9
|
+
|
|
10
|
+
type TestDetails = Record<string, unknown> & { error?: unknown };
|
|
11
|
+
type TestResult = AgentToolResult<TestDetails>;
|
|
12
|
+
|
|
13
|
+
const collapsedOptions: ToolRenderResultOptions = { expanded: false, isPartial: false };
|
|
14
|
+
const plainTheme = { fg: (_name: string, text: string) => text };
|
|
15
|
+
|
|
16
|
+
function result(content: TestResult["content"], details: TestDetails = {}): TestResult {
|
|
17
|
+
return { content, details };
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
describe("MCP tool call renderer", () => {
|
|
21
|
+
it("shows proxy tool calls with parsed JSON arguments", () => {
|
|
22
|
+
const display = formatMcpProxyToolCallLines({
|
|
23
|
+
tool: "cf-portal_list_worker_tail_events",
|
|
24
|
+
server: "cf-portal",
|
|
25
|
+
args: JSON.stringify({ accountId: "abc", scriptName: "worker" }),
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
expect(display).toEqual([
|
|
29
|
+
"mcp call cf-portal_list_worker_tail_events @ cf-portal",
|
|
30
|
+
'{\n "accountId": "abc",\n "scriptName": "worker"\n}',
|
|
31
|
+
]);
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it("shows proxy discovery operations", () => {
|
|
35
|
+
expect(formatMcpProxyToolCallLines({ search: "tail events", server: "cf-portal", regex: true })).toEqual([
|
|
36
|
+
"mcp search tail events @ cf-portal (regex)",
|
|
37
|
+
]);
|
|
38
|
+
expect(formatMcpProxyToolCallLines({ connect: "cf-portal" })).toEqual(["mcp connect cf-portal"]);
|
|
39
|
+
expect(formatMcpProxyToolCallLines({ server: "cf-portal" })).toEqual(["mcp list cf-portal"]);
|
|
40
|
+
expect(formatMcpProxyToolCallLines({})).toEqual(["mcp status"]);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it("renders ui-messages with execution precedence", () => {
|
|
44
|
+
expect(formatMcpProxyToolCallLines({ action: "ui-messages", server: "cf-portal" })).toEqual(["mcp ui-messages"]);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it("shows direct tool calls with JSON arguments", () => {
|
|
48
|
+
const display = formatMcpDirectToolCallLines("cf-portal_list_worker_tail_events", {
|
|
49
|
+
accountId: "abc",
|
|
50
|
+
scriptName: "worker",
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
expect(display).toEqual([
|
|
54
|
+
"cf-portal_list_worker_tail_events",
|
|
55
|
+
'{\n "accountId": "abc",\n "scriptName": "worker"\n}',
|
|
56
|
+
]);
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
it("omits empty direct tool arguments", () => {
|
|
60
|
+
expect(formatMcpDirectToolCallLines("cf-portal_status", {})).toEqual(["cf-portal_status"]);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
describe("MCP tool result renderer", () => {
|
|
65
|
+
it("shows the first three lines and an ellipsis for collapsed long text", () => {
|
|
66
|
+
const display = formatMcpToolResultLines(result([
|
|
67
|
+
{ type: "text", text: "one\ntwo\nthree\nfour" },
|
|
68
|
+
]), false);
|
|
69
|
+
|
|
70
|
+
expect(display).toEqual({
|
|
71
|
+
lines: ["one", "two", "three", "…"],
|
|
72
|
+
truncated: true,
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it("does not add an ellipsis when collapsed text is three lines or fewer", () => {
|
|
77
|
+
const display = formatMcpToolResultLines(result([
|
|
78
|
+
{ type: "text", text: "one\ntwo\nthree" },
|
|
79
|
+
]), false);
|
|
80
|
+
|
|
81
|
+
expect(display).toEqual({
|
|
82
|
+
lines: ["one", "two", "three"],
|
|
83
|
+
truncated: false,
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it("shows full text when expanded", () => {
|
|
88
|
+
const display = formatMcpToolResultLines(result([
|
|
89
|
+
{ type: "text", text: "one\ntwo\nthree\nfour" },
|
|
90
|
+
]), true);
|
|
91
|
+
|
|
92
|
+
expect(display).toEqual({
|
|
93
|
+
lines: ["one", "two", "three", "four"],
|
|
94
|
+
truncated: false,
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
it("uses placeholders for images", () => {
|
|
99
|
+
const display = formatMcpToolResultLines(result([
|
|
100
|
+
{ type: "text", text: "before" },
|
|
101
|
+
{ type: "image", mimeType: "image/png", data: "abc" },
|
|
102
|
+
]), true);
|
|
103
|
+
|
|
104
|
+
expect(display.lines).toEqual(["before", "[image: image/png]"]);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it("uses an empty-result placeholder when content is empty", () => {
|
|
108
|
+
const display = formatMcpToolResultLines(result([]), false);
|
|
109
|
+
|
|
110
|
+
expect(display).toEqual({ lines: ["(empty result)"], truncated: false });
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it("keeps error text visible", () => {
|
|
114
|
+
const display = formatMcpToolResultLines(result([
|
|
115
|
+
{ type: "text", text: "Error: upstream failed\nExpected parameters:\n{}" },
|
|
116
|
+
]), false);
|
|
117
|
+
|
|
118
|
+
expect(display.lines).toEqual(["Error: upstream failed", "Expected parameters:", "{}"]);
|
|
119
|
+
expect(display.truncated).toBe(false);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it("renders long error results expanded even when the row is collapsed", () => {
|
|
123
|
+
const output = renderMcpToolResult(
|
|
124
|
+
result([{ type: "text", text: "Error: failed\nline 2\nline 3\nline 4" }]),
|
|
125
|
+
collapsedOptions,
|
|
126
|
+
plainTheme,
|
|
127
|
+
{ isError: true },
|
|
128
|
+
).render(80).join("\n");
|
|
129
|
+
|
|
130
|
+
expect(output).toContain("line 4");
|
|
131
|
+
expect(output).not.toContain("Ctrl+O to expand");
|
|
132
|
+
expect(output).not.toContain("…");
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it("renders adapter error details expanded even when Pi context is not marked as an error", () => {
|
|
136
|
+
const output = renderMcpToolResult(
|
|
137
|
+
result([{ type: "text", text: "Error: failed\nline 2\nline 3\nline 4" }], { error: "tool_error" }),
|
|
138
|
+
collapsedOptions,
|
|
139
|
+
plainTheme,
|
|
140
|
+
{ isError: false },
|
|
141
|
+
).render(80).join("\n");
|
|
142
|
+
|
|
143
|
+
expect(output).toContain("line 4");
|
|
144
|
+
expect(output).not.toContain("Ctrl+O to expand");
|
|
145
|
+
expect(output).not.toContain("…");
|
|
146
|
+
});
|
|
147
|
+
});
|