iosm-cli 0.2.14 → 0.2.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +50 -0
- package/README.md +18 -1
- package/dist/cli/args.d.ts +2 -1
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +16 -3
- package/dist/cli/args.js.map +1 -1
- package/dist/core/agent-profiles.d.ts.map +1 -1
- package/dist/core/agent-profiles.js +3 -0
- package/dist/core/agent-profiles.js.map +1 -1
- package/dist/core/agent-session.d.ts +2 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +26 -10
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/agent-teams.d.ts.map +1 -1
- package/dist/core/agent-teams.js +12 -9
- package/dist/core/agent-teams.js.map +1 -1
- package/dist/core/checkpoint/fs-checkpoint.d.ts +14 -0
- package/dist/core/checkpoint/fs-checkpoint.d.ts.map +1 -0
- package/dist/core/checkpoint/fs-checkpoint.js +211 -0
- package/dist/core/checkpoint/fs-checkpoint.js.map +1 -0
- package/dist/core/command-dispatcher.d.ts +2 -0
- package/dist/core/command-dispatcher.d.ts.map +1 -1
- package/dist/core/command-dispatcher.js +78 -13
- package/dist/core/command-dispatcher.js.map +1 -1
- package/dist/core/mcp/cli.d.ts.map +1 -1
- package/dist/core/mcp/cli.js +26 -0
- package/dist/core/mcp/cli.js.map +1 -1
- package/dist/core/mcp/config.d.ts.map +1 -1
- package/dist/core/mcp/config.js +55 -0
- package/dist/core/mcp/config.js.map +1 -1
- package/dist/core/mcp/index.d.ts +1 -1
- package/dist/core/mcp/index.d.ts.map +1 -1
- package/dist/core/mcp/index.js.map +1 -1
- package/dist/core/mcp/runtime.d.ts +3 -1
- package/dist/core/mcp/runtime.d.ts.map +1 -1
- package/dist/core/mcp/runtime.js +21 -2
- package/dist/core/mcp/runtime.js.map +1 -1
- package/dist/core/mcp/types.d.ts +30 -2
- package/dist/core/mcp/types.d.ts.map +1 -1
- package/dist/core/mcp/types.js.map +1 -1
- package/dist/core/package-manager.d.ts +10 -0
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +100 -2
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/policy/engine.d.ts +77 -0
- package/dist/core/policy/engine.d.ts.map +1 -0
- package/dist/core/policy/engine.js +614 -0
- package/dist/core/policy/engine.js.map +1 -0
- package/dist/core/policy/index.d.ts +2 -0
- package/dist/core/policy/index.d.ts.map +1 -0
- package/dist/core/policy/index.js +2 -0
- package/dist/core/policy/index.js.map +1 -0
- package/dist/core/sandbox/executor.d.ts +13 -0
- package/dist/core/sandbox/executor.d.ts.map +1 -0
- package/dist/core/sandbox/executor.js +64 -0
- package/dist/core/sandbox/executor.js.map +1 -0
- package/dist/core/sdk.d.ts +2 -2
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +3 -3
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/security/index.d.ts +3 -0
- package/dist/core/security/index.d.ts.map +1 -0
- package/dist/core/security/index.js +3 -0
- package/dist/core/security/index.js.map +1 -0
- package/dist/core/security/source-security.d.ts +43 -0
- package/dist/core/security/source-security.d.ts.map +1 -0
- package/dist/core/security/source-security.js +94 -0
- package/dist/core/security/source-security.js.map +1 -0
- package/dist/core/security/trust-ledger.d.ts +24 -0
- package/dist/core/security/trust-ledger.d.ts.map +1 -0
- package/dist/core/security/trust-ledger.js +66 -0
- package/dist/core/security/trust-ledger.js.map +1 -0
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +128 -15
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +6 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +22 -1
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +9 -2
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/core/task-plan.d.ts +1 -0
- package/dist/core/task-plan.d.ts.map +1 -1
- package/dist/core/task-plan.js +103 -0
- package/dist/core/task-plan.js.map +1 -1
- package/dist/core/tools/apply-patch.d.ts +29 -0
- package/dist/core/tools/apply-patch.d.ts.map +1 -0
- package/dist/core/tools/apply-patch.js +167 -0
- package/dist/core/tools/apply-patch.js.map +1 -0
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +15 -1
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/git-common.d.ts.map +1 -1
- package/dist/core/tools/git-common.js +15 -1
- package/dist/core/tools/git-common.js.map +1 -1
- package/dist/core/tools/index.d.ts +20 -2
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +85 -25
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/permissions.d.ts +16 -0
- package/dist/core/tools/permissions.d.ts.map +1 -1
- package/dist/core/tools/permissions.js +34 -1
- package/dist/core/tools/permissions.js.map +1 -1
- package/dist/core/tools/task.d.ts.map +1 -1
- package/dist/core/tools/task.js +68 -24
- package/dist/core/tools/task.js.map +1 -1
- package/dist/core/tools/tool-search.d.ts +24 -0
- package/dist/core/tools/tool-search.d.ts.map +1 -0
- package/dist/core/tools/tool-search.js +85 -0
- package/dist/core/tools/tool-search.js.map +1 -0
- package/dist/core/tools/tool-suggest.d.ts +18 -0
- package/dist/core/tools/tool-suggest.d.ts.map +1 -0
- package/dist/core/tools/tool-suggest.js +94 -0
- package/dist/core/tools/tool-suggest.js.map +1 -0
- package/dist/core/tools/verification-runner.d.ts.map +1 -1
- package/dist/core/tools/verification-runner.js +15 -1
- package/dist/core/tools/verification-runner.js.map +1 -1
- package/dist/core/unified-exec.d.ts +39 -0
- package/dist/core/unified-exec.d.ts.map +1 -0
- package/dist/core/unified-exec.js +286 -0
- package/dist/core/unified-exec.js.map +1 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +93 -11
- package/dist/main.js.map +1 -1
- package/dist/modes/acp/acp-mode.d.ts +17 -0
- package/dist/modes/acp/acp-mode.d.ts.map +1 -0
- package/dist/modes/acp/acp-mode.js +352 -0
- package/dist/modes/acp/acp-mode.js.map +1 -0
- package/dist/modes/index.d.ts +2 -1
- package/dist/modes/index.d.ts.map +1 -1
- package/dist/modes/index.js +1 -0
- package/dist/modes/index.js.map +1 -1
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
- package/dist/modes/interactive/components/tool-execution.js +217 -0
- package/dist/modes/interactive/components/tool-execution.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +8 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +159 -72
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +25 -1
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +33 -0
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts +13 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js +189 -28
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +54 -1
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/modes/telegram/telegram-bridge-mode.js +51 -22
- package/dist/modes/telegram/telegram-bridge-mode.js.map +1 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +96 -9
- package/dist/utils/tools-manager.js.map +1 -1
- package/docs/README.md +2 -0
- package/docs/acp-rpc-mapping.md +38 -0
- package/docs/configuration.generated.md +81 -0
- package/docs/configuration.md +7 -0
- package/package.json +4 -1
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { AgentTool } from "@mariozechner/pi-agent-core";
|
|
2
|
+
import { type Static } from "@sinclair/typebox";
|
|
3
|
+
export interface ToolSearchCatalogEntry {
|
|
4
|
+
name: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
active?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface ToolSearchOptions {
|
|
9
|
+
resolveCatalog?: () => ToolSearchCatalogEntry[];
|
|
10
|
+
}
|
|
11
|
+
declare const toolSearchSchema: import("@sinclair/typebox").TObject<{
|
|
12
|
+
query: import("@sinclair/typebox").TString;
|
|
13
|
+
limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
14
|
+
includeInactive: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
15
|
+
}>;
|
|
16
|
+
export type ToolSearchInput = Static<typeof toolSearchSchema>;
|
|
17
|
+
export declare function createToolSearchTool(options?: ToolSearchOptions): AgentTool<typeof toolSearchSchema>;
|
|
18
|
+
export declare const toolSearchTool: AgentTool<import("@sinclair/typebox").TObject<{
|
|
19
|
+
query: import("@sinclair/typebox").TString;
|
|
20
|
+
limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
21
|
+
includeInactive: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TBoolean>;
|
|
22
|
+
}>, any>;
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=tool-search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-search.d.ts","sourceRoot":"","sources":["../../../src/core/tools/tool-search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,KAAK,MAAM,EAAQ,MAAM,mBAAmB,CAAC;AAEtD,MAAM,WAAW,sBAAsB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IACjC,cAAc,CAAC,EAAE,MAAM,sBAAsB,EAAE,CAAC;CAChD;AAED,QAAA,MAAM,gBAAgB;;;;EAIpB,CAAC;AAEH,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAgC9D,wBAAgB,oBAAoB,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,SAAS,CAAC,OAAO,gBAAgB,CAAC,CAkDpG;AAED,eAAO,MAAM,cAAc;;;;QAAyB,CAAC"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { Type } from "@sinclair/typebox";
|
|
2
|
+
const toolSearchSchema = Type.Object({
|
|
3
|
+
query: Type.String({ description: "Search query for tool names or descriptions." }),
|
|
4
|
+
limit: Type.Optional(Type.Number({ description: "Maximum number of matches to return (default 10)." })),
|
|
5
|
+
includeInactive: Type.Optional(Type.Boolean({ description: "Include inactive tools in results (default true)." })),
|
|
6
|
+
});
|
|
7
|
+
function tokenize(value) {
|
|
8
|
+
return value
|
|
9
|
+
.toLowerCase()
|
|
10
|
+
.split(/[^a-z0-9_]+/g)
|
|
11
|
+
.filter((token) => token.length > 0);
|
|
12
|
+
}
|
|
13
|
+
function scoreEntry(entry, query, queryTokens) {
|
|
14
|
+
const name = entry.name.toLowerCase();
|
|
15
|
+
const description = (entry.description ?? "").toLowerCase();
|
|
16
|
+
let score = 0;
|
|
17
|
+
if (name === query)
|
|
18
|
+
score += 120;
|
|
19
|
+
if (name.startsWith(query))
|
|
20
|
+
score += 80;
|
|
21
|
+
if (name.includes(query))
|
|
22
|
+
score += 50;
|
|
23
|
+
if (description.includes(query))
|
|
24
|
+
score += 35;
|
|
25
|
+
for (const token of queryTokens) {
|
|
26
|
+
if (name === token)
|
|
27
|
+
score += 35;
|
|
28
|
+
if (name.startsWith(token))
|
|
29
|
+
score += 20;
|
|
30
|
+
if (name.includes(token))
|
|
31
|
+
score += 12;
|
|
32
|
+
if (description.includes(token))
|
|
33
|
+
score += 8;
|
|
34
|
+
}
|
|
35
|
+
if (entry.active)
|
|
36
|
+
score += 2;
|
|
37
|
+
return score;
|
|
38
|
+
}
|
|
39
|
+
const DEFAULT_CATALOG = [];
|
|
40
|
+
export function createToolSearchTool(options) {
|
|
41
|
+
return {
|
|
42
|
+
name: "tool_search",
|
|
43
|
+
label: "tool_search",
|
|
44
|
+
description: "Search available tools by name/description and return ranked matches with active/inactive status.",
|
|
45
|
+
parameters: toolSearchSchema,
|
|
46
|
+
execute: async (_toolCallId, input) => {
|
|
47
|
+
const query = input.query.trim().toLowerCase();
|
|
48
|
+
if (!query) {
|
|
49
|
+
return {
|
|
50
|
+
content: [{ type: "text", text: "Provide a non-empty search query." }],
|
|
51
|
+
details: { count: 0 },
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
const limit = Math.max(1, Math.min(50, Math.floor(input.limit ?? 10)));
|
|
55
|
+
const includeInactive = input.includeInactive ?? true;
|
|
56
|
+
const catalog = (options?.resolveCatalog?.() ?? DEFAULT_CATALOG).filter((entry) => includeInactive || entry.active === true);
|
|
57
|
+
const queryTokens = tokenize(query);
|
|
58
|
+
const ranked = catalog
|
|
59
|
+
.map((entry) => ({
|
|
60
|
+
entry,
|
|
61
|
+
score: scoreEntry(entry, query, queryTokens),
|
|
62
|
+
}))
|
|
63
|
+
.filter((item) => item.score > 0)
|
|
64
|
+
.sort((a, b) => b.score - a.score || a.entry.name.localeCompare(b.entry.name))
|
|
65
|
+
.slice(0, limit);
|
|
66
|
+
if (ranked.length === 0) {
|
|
67
|
+
return {
|
|
68
|
+
content: [{ type: "text", text: `No tools matched "${input.query}".` }],
|
|
69
|
+
details: { count: 0 },
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
const lines = ranked.map(({ entry }) => {
|
|
73
|
+
const status = entry.active ? "active" : "inactive";
|
|
74
|
+
const desc = entry.description?.trim() ? ` - ${entry.description.trim()}` : "";
|
|
75
|
+
return `- ${entry.name} [${status}]${desc}`;
|
|
76
|
+
});
|
|
77
|
+
return {
|
|
78
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
79
|
+
details: { count: ranked.length },
|
|
80
|
+
};
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
export const toolSearchTool = createToolSearchTool();
|
|
85
|
+
//# sourceMappingURL=tool-search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-search.js","sourceRoot":"","sources":["../../../src/core/tools/tool-search.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentTool } from \"@mariozechner/pi-agent-core\";\nimport { type Static, Type } from \"@sinclair/typebox\";\n\nexport interface ToolSearchCatalogEntry {\n\tname: string;\n\tdescription?: string;\n\tactive?: boolean;\n}\n\nexport interface ToolSearchOptions {\n\tresolveCatalog?: () => ToolSearchCatalogEntry[];\n}\n\nconst toolSearchSchema = Type.Object({\n\tquery: Type.String({ description: \"Search query for tool names or descriptions.\" }),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of matches to return (default 10).\" })),\n\tincludeInactive: Type.Optional(Type.Boolean({ description: \"Include inactive tools in results (default true).\" })),\n});\n\nexport type ToolSearchInput = Static<typeof toolSearchSchema>;\n\nfunction tokenize(value: string): string[] {\n\treturn value\n\t\t.toLowerCase()\n\t\t.split(/[^a-z0-9_]+/g)\n\t\t.filter((token) => token.length > 0);\n}\n\nfunction scoreEntry(entry: ToolSearchCatalogEntry, query: string, queryTokens: string[]): number {\n\tconst name = entry.name.toLowerCase();\n\tconst description = (entry.description ?? \"\").toLowerCase();\n\n\tlet score = 0;\n\tif (name === query) score += 120;\n\tif (name.startsWith(query)) score += 80;\n\tif (name.includes(query)) score += 50;\n\tif (description.includes(query)) score += 35;\n\n\tfor (const token of queryTokens) {\n\t\tif (name === token) score += 35;\n\t\tif (name.startsWith(token)) score += 20;\n\t\tif (name.includes(token)) score += 12;\n\t\tif (description.includes(token)) score += 8;\n\t}\n\n\tif (entry.active) score += 2;\n\treturn score;\n}\n\nconst DEFAULT_CATALOG: ToolSearchCatalogEntry[] = [];\n\nexport function createToolSearchTool(options?: ToolSearchOptions): AgentTool<typeof toolSearchSchema> {\n\treturn {\n\t\tname: \"tool_search\",\n\t\tlabel: \"tool_search\",\n\t\tdescription: \"Search available tools by name/description and return ranked matches with active/inactive status.\",\n\t\tparameters: toolSearchSchema,\n\t\texecute: async (_toolCallId: string, input: ToolSearchInput) => {\n\t\t\tconst query = input.query.trim().toLowerCase();\n\t\t\tif (!query) {\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\", text: \"Provide a non-empty search query.\" }],\n\t\t\t\t\tdetails: { count: 0 },\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst limit = Math.max(1, Math.min(50, Math.floor(input.limit ?? 10)));\n\t\t\tconst includeInactive = input.includeInactive ?? true;\n\t\t\tconst catalog = (options?.resolveCatalog?.() ?? DEFAULT_CATALOG).filter(\n\t\t\t\t(entry) => includeInactive || entry.active === true,\n\t\t\t);\n\n\t\t\tconst queryTokens = tokenize(query);\n\t\t\tconst ranked = catalog\n\t\t\t\t.map((entry) => ({\n\t\t\t\t\tentry,\n\t\t\t\t\tscore: scoreEntry(entry, query, queryTokens),\n\t\t\t\t}))\n\t\t\t\t.filter((item) => item.score > 0)\n\t\t\t\t.sort((a, b) => b.score - a.score || a.entry.name.localeCompare(b.entry.name))\n\t\t\t\t.slice(0, limit);\n\n\t\t\tif (ranked.length === 0) {\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\", text: `No tools matched \"${input.query}\".` }],\n\t\t\t\t\tdetails: { count: 0 },\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst lines = ranked.map(({ entry }) => {\n\t\t\t\tconst status = entry.active ? \"active\" : \"inactive\";\n\t\t\t\tconst desc = entry.description?.trim() ? ` - ${entry.description.trim()}` : \"\";\n\t\t\t\treturn `- ${entry.name} [${status}]${desc}`;\n\t\t\t});\n\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: lines.join(\"\\n\") }],\n\t\t\t\tdetails: { count: ranked.length },\n\t\t\t};\n\t\t},\n\t};\n}\n\nexport const toolSearchTool = createToolSearchTool();\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { AgentTool } from "@mariozechner/pi-agent-core";
|
|
2
|
+
import { type Static } from "@sinclair/typebox";
|
|
3
|
+
import type { ToolSearchCatalogEntry } from "./tool-search.js";
|
|
4
|
+
export interface ToolSuggestOptions {
|
|
5
|
+
resolveCatalog?: () => ToolSearchCatalogEntry[];
|
|
6
|
+
}
|
|
7
|
+
declare const toolSuggestSchema: import("@sinclair/typebox").TObject<{
|
|
8
|
+
task: import("@sinclair/typebox").TString;
|
|
9
|
+
limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
10
|
+
}>;
|
|
11
|
+
export type ToolSuggestInput = Static<typeof toolSuggestSchema>;
|
|
12
|
+
export declare function createToolSuggestTool(options?: ToolSuggestOptions): AgentTool<typeof toolSuggestSchema>;
|
|
13
|
+
export declare const toolSuggestTool: AgentTool<import("@sinclair/typebox").TObject<{
|
|
14
|
+
task: import("@sinclair/typebox").TString;
|
|
15
|
+
limit: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TNumber>;
|
|
16
|
+
}>, any>;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=tool-suggest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-suggest.d.ts","sourceRoot":"","sources":["../../../src/core/tools/tool-suggest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAAE,KAAK,MAAM,EAAQ,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE/D,MAAM,WAAW,kBAAkB;IAClC,cAAc,CAAC,EAAE,MAAM,sBAAsB,EAAE,CAAC;CAChD;AAED,QAAA,MAAM,iBAAiB;;;EAGrB,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,OAAO,iBAAiB,CAAC,CAAC;AA8ChE,wBAAgB,qBAAqB,CAAC,OAAO,CAAC,EAAE,kBAAkB,GAAG,SAAS,CAAC,OAAO,iBAAiB,CAAC,CA+CvG;AAED,eAAO,MAAM,eAAe;;;QAA0B,CAAC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { Type } from "@sinclair/typebox";
|
|
2
|
+
const toolSuggestSchema = Type.Object({
|
|
3
|
+
task: Type.String({ description: "Describe the task to get the most relevant tools." }),
|
|
4
|
+
limit: Type.Optional(Type.Number({ description: "Maximum number of tool suggestions (default 5)." })),
|
|
5
|
+
});
|
|
6
|
+
const KEYWORD_TOOL_HINTS = [
|
|
7
|
+
{ keywords: ["patch", "diff", "bulk", "hunk"], tools: ["apply_patch", "edit", "git_read"] },
|
|
8
|
+
{ keywords: ["search", "find", "grep", "pattern"], tools: ["tool_search", "grep", "rg", "find"] },
|
|
9
|
+
{ keywords: ["http", "api", "request", "endpoint", "url"], tools: ["fetch", "web_search"] },
|
|
10
|
+
{ keywords: ["test", "unit", "integration", "spec"], tools: ["test_run", "lint_run", "typecheck_run"] },
|
|
11
|
+
{ keywords: ["git", "branch", "commit", "stash", "push"], tools: ["git_read", "git_write"] },
|
|
12
|
+
{ keywords: ["database", "sql", "query", "migration"], tools: ["db_run"] },
|
|
13
|
+
{ keywords: ["file", "rename", "move", "copy", "delete"], tools: ["fs_ops", "write", "edit"] },
|
|
14
|
+
{ keywords: ["command", "shell", "terminal", "repl"], tools: ["bash"] },
|
|
15
|
+
];
|
|
16
|
+
function tokenize(value) {
|
|
17
|
+
return value
|
|
18
|
+
.toLowerCase()
|
|
19
|
+
.split(/[^a-z0-9_]+/g)
|
|
20
|
+
.filter((token) => token.length > 0);
|
|
21
|
+
}
|
|
22
|
+
function scoreByText(entry, tokens) {
|
|
23
|
+
const haystack = `${entry.name} ${entry.description ?? ""}`.toLowerCase();
|
|
24
|
+
let score = 0;
|
|
25
|
+
for (const token of tokens) {
|
|
26
|
+
if (entry.name.toLowerCase() === token)
|
|
27
|
+
score += 40;
|
|
28
|
+
if (entry.name.toLowerCase().startsWith(token))
|
|
29
|
+
score += 22;
|
|
30
|
+
if (haystack.includes(token))
|
|
31
|
+
score += 10;
|
|
32
|
+
}
|
|
33
|
+
if (entry.active)
|
|
34
|
+
score += 3;
|
|
35
|
+
return score;
|
|
36
|
+
}
|
|
37
|
+
function scoreByHints(entry, tokens) {
|
|
38
|
+
let score = 0;
|
|
39
|
+
for (const hint of KEYWORD_TOOL_HINTS) {
|
|
40
|
+
const matched = hint.keywords.some((keyword) => tokens.includes(keyword));
|
|
41
|
+
if (!matched)
|
|
42
|
+
continue;
|
|
43
|
+
if (hint.tools.includes(entry.name)) {
|
|
44
|
+
score += 35;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return score;
|
|
48
|
+
}
|
|
49
|
+
const DEFAULT_CATALOG = [];
|
|
50
|
+
export function createToolSuggestTool(options) {
|
|
51
|
+
return {
|
|
52
|
+
name: "tool_suggest",
|
|
53
|
+
label: "tool_suggest",
|
|
54
|
+
description: "Suggest the best tools for a described task, ranking by task keywords and available tool metadata.",
|
|
55
|
+
parameters: toolSuggestSchema,
|
|
56
|
+
execute: async (_toolCallId, input) => {
|
|
57
|
+
const task = input.task.trim();
|
|
58
|
+
if (!task) {
|
|
59
|
+
return {
|
|
60
|
+
content: [{ type: "text", text: "Provide a non-empty task description." }],
|
|
61
|
+
details: { count: 0 },
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
const limit = Math.max(1, Math.min(20, Math.floor(input.limit ?? 5)));
|
|
65
|
+
const tokens = tokenize(task);
|
|
66
|
+
const catalog = options?.resolveCatalog?.() ?? DEFAULT_CATALOG;
|
|
67
|
+
const ranked = catalog
|
|
68
|
+
.map((entry) => ({
|
|
69
|
+
entry,
|
|
70
|
+
score: scoreByText(entry, tokens) + scoreByHints(entry, tokens),
|
|
71
|
+
}))
|
|
72
|
+
.filter((item) => item.score > 0)
|
|
73
|
+
.sort((a, b) => b.score - a.score || a.entry.name.localeCompare(b.entry.name))
|
|
74
|
+
.slice(0, limit);
|
|
75
|
+
if (ranked.length === 0) {
|
|
76
|
+
return {
|
|
77
|
+
content: [{ type: "text", text: "No strong tool suggestion found. Use tool_search to explore available tools." }],
|
|
78
|
+
details: { count: 0 },
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
const lines = ranked.map(({ entry }, idx) => {
|
|
82
|
+
const status = entry.active ? "active" : "inactive";
|
|
83
|
+
const desc = entry.description?.trim() ? ` - ${entry.description.trim()}` : "";
|
|
84
|
+
return `${idx + 1}. ${entry.name} [${status}]${desc}`;
|
|
85
|
+
});
|
|
86
|
+
return {
|
|
87
|
+
content: [{ type: "text", text: lines.join("\n") }],
|
|
88
|
+
details: { count: ranked.length },
|
|
89
|
+
};
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
export const toolSuggestTool = createToolSuggestTool();
|
|
94
|
+
//# sourceMappingURL=tool-suggest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-suggest.js","sourceRoot":"","sources":["../../../src/core/tools/tool-suggest.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentTool } from \"@mariozechner/pi-agent-core\";\nimport { type Static, Type } from \"@sinclair/typebox\";\nimport type { ToolSearchCatalogEntry } from \"./tool-search.js\";\n\nexport interface ToolSuggestOptions {\n\tresolveCatalog?: () => ToolSearchCatalogEntry[];\n}\n\nconst toolSuggestSchema = Type.Object({\n\ttask: Type.String({ description: \"Describe the task to get the most relevant tools.\" }),\n\tlimit: Type.Optional(Type.Number({ description: \"Maximum number of tool suggestions (default 5).\" })),\n});\n\nexport type ToolSuggestInput = Static<typeof toolSuggestSchema>;\n\nconst KEYWORD_TOOL_HINTS: Array<{ keywords: string[]; tools: string[] }> = [\n\t{ keywords: [\"patch\", \"diff\", \"bulk\", \"hunk\"], tools: [\"apply_patch\", \"edit\", \"git_read\"] },\n\t{ keywords: [\"search\", \"find\", \"grep\", \"pattern\"], tools: [\"tool_search\", \"grep\", \"rg\", \"find\"] },\n\t{ keywords: [\"http\", \"api\", \"request\", \"endpoint\", \"url\"], tools: [\"fetch\", \"web_search\"] },\n\t{ keywords: [\"test\", \"unit\", \"integration\", \"spec\"], tools: [\"test_run\", \"lint_run\", \"typecheck_run\"] },\n\t{ keywords: [\"git\", \"branch\", \"commit\", \"stash\", \"push\"], tools: [\"git_read\", \"git_write\"] },\n\t{ keywords: [\"database\", \"sql\", \"query\", \"migration\"], tools: [\"db_run\"] },\n\t{ keywords: [\"file\", \"rename\", \"move\", \"copy\", \"delete\"], tools: [\"fs_ops\", \"write\", \"edit\"] },\n\t{ keywords: [\"command\", \"shell\", \"terminal\", \"repl\"], tools: [\"bash\"] },\n];\n\nfunction tokenize(value: string): string[] {\n\treturn value\n\t\t.toLowerCase()\n\t\t.split(/[^a-z0-9_]+/g)\n\t\t.filter((token) => token.length > 0);\n}\n\nfunction scoreByText(entry: ToolSearchCatalogEntry, tokens: string[]): number {\n\tconst haystack = `${entry.name} ${entry.description ?? \"\"}`.toLowerCase();\n\tlet score = 0;\n\tfor (const token of tokens) {\n\t\tif (entry.name.toLowerCase() === token) score += 40;\n\t\tif (entry.name.toLowerCase().startsWith(token)) score += 22;\n\t\tif (haystack.includes(token)) score += 10;\n\t}\n\tif (entry.active) score += 3;\n\treturn score;\n}\n\nfunction scoreByHints(entry: ToolSearchCatalogEntry, tokens: string[]): number {\n\tlet score = 0;\n\tfor (const hint of KEYWORD_TOOL_HINTS) {\n\t\tconst matched = hint.keywords.some((keyword) => tokens.includes(keyword));\n\t\tif (!matched) continue;\n\t\tif (hint.tools.includes(entry.name)) {\n\t\t\tscore += 35;\n\t\t}\n\t}\n\treturn score;\n}\n\nconst DEFAULT_CATALOG: ToolSearchCatalogEntry[] = [];\n\nexport function createToolSuggestTool(options?: ToolSuggestOptions): AgentTool<typeof toolSuggestSchema> {\n\treturn {\n\t\tname: \"tool_suggest\",\n\t\tlabel: \"tool_suggest\",\n\t\tdescription: \"Suggest the best tools for a described task, ranking by task keywords and available tool metadata.\",\n\t\tparameters: toolSuggestSchema,\n\t\texecute: async (_toolCallId: string, input: ToolSuggestInput) => {\n\t\t\tconst task = input.task.trim();\n\t\t\tif (!task) {\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\", text: \"Provide a non-empty task description.\" }],\n\t\t\t\t\tdetails: { count: 0 },\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst limit = Math.max(1, Math.min(20, Math.floor(input.limit ?? 5)));\n\t\t\tconst tokens = tokenize(task);\n\t\t\tconst catalog = options?.resolveCatalog?.() ?? DEFAULT_CATALOG;\n\n\t\t\tconst ranked = catalog\n\t\t\t\t.map((entry) => ({\n\t\t\t\t\tentry,\n\t\t\t\t\tscore: scoreByText(entry, tokens) + scoreByHints(entry, tokens),\n\t\t\t\t}))\n\t\t\t\t.filter((item) => item.score > 0)\n\t\t\t\t.sort((a, b) => b.score - a.score || a.entry.name.localeCompare(b.entry.name))\n\t\t\t\t.slice(0, limit);\n\n\t\t\tif (ranked.length === 0) {\n\t\t\t\treturn {\n\t\t\t\t\tcontent: [{ type: \"text\", text: \"No strong tool suggestion found. Use tool_search to explore available tools.\" }],\n\t\t\t\t\tdetails: { count: 0 },\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tconst lines = ranked.map(({ entry }, idx) => {\n\t\t\t\tconst status = entry.active ? \"active\" : \"inactive\";\n\t\t\t\tconst desc = entry.description?.trim() ? ` - ${entry.description.trim()}` : \"\";\n\t\t\t\treturn `${idx + 1}. ${entry.name} [${status}]${desc}`;\n\t\t\t});\n\n\t\t\treturn {\n\t\t\t\tcontent: [{ type: \"text\", text: lines.join(\"\\n\") }],\n\t\t\t\tdetails: { count: ranked.length },\n\t\t\t};\n\t\t},\n\t};\n}\n\nexport const toolSuggestTool = createToolSuggestTool();\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verification-runner.d.ts","sourceRoot":"","sources":["../../../src/core/tools/verification-runner.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"verification-runner.d.ts","sourceRoot":"","sources":["../../../src/core/tools/verification-runner.ts"],"names":[],"mappings":"AAIA,OAAO,EAIN,KAAK,gBAAgB,EAErB,MAAM,eAAe,CAAC;AAEvB,eAAO,MAAM,kCAAkC,QAAa,CAAC;AAE7D,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAE7D,MAAM,WAAW,eAAe;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,yBAAyB;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,wBAAwB;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC9B;AAED,MAAM,WAAW,2BAA2B;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,qBAAsB,SAAQ,2BAA2B;IACzE,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,uBAAuB;IACvC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,qBAAqB,CAAC;IAC7B,MAAM,EAAE,yBAAyB,CAAC;CAClC;AAoBD,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAQtD;AAED,wBAAgB,uBAAuB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,CAOhF;AAED,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAMhE;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS,CA8BxE;AAED,wBAAgB,kCAAkC,CACjD,cAAc,EAAE,cAAc,EAC9B,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAAE,GAClB;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAuBrC;AAED,wBAAgB,mCAAmC,CAClD,cAAc,EAAE,cAAc,EAC9B,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAAE,GAClB;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAcrC;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAMzE;AAED,wBAAsB,sBAAsB,CAAC,KAAK,EAAE,2BAA2B,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAwGnH;AAED,wBAAsB,2BAA2B,CAAC,KAAK,EAAE,qBAAqB,EAAE,GAAG,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAWpH;AAED,wBAAgB,wBAAwB,CACvC,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,gBAAgB,EAAE,OAAO,EACzB,kBAAkB,EAAE,MAAM,GACxB,wBAAwB,CA0B1B"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { spawn, spawnSync } from "node:child_process";
|
|
4
|
+
import { isSandboxEnabledFromEnv, wrapCommandWithSandbox } from "../sandbox/executor.js";
|
|
4
5
|
import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize, truncateHead, } from "./truncate.js";
|
|
5
6
|
export const DEFAULT_VERIFICATION_CAPTURE_BYTES = 512 * 1024;
|
|
6
7
|
function captureChunk(chunk, chunks, currentBytes, maxCaptureBytes) {
|
|
@@ -125,7 +126,20 @@ export async function runVerificationCommand(input) {
|
|
|
125
126
|
return;
|
|
126
127
|
}
|
|
127
128
|
const startedAt = Date.now();
|
|
128
|
-
|
|
129
|
+
let wrapped;
|
|
130
|
+
try {
|
|
131
|
+
wrapped = wrapCommandWithSandbox({
|
|
132
|
+
command: input.command,
|
|
133
|
+
args: input.args,
|
|
134
|
+
cwd: input.cwd,
|
|
135
|
+
enabled: isSandboxEnabledFromEnv(),
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
reject(error instanceof Error ? error : new Error(String(error)));
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
const child = spawn(wrapped.command, wrapped.args, {
|
|
129
143
|
cwd: input.cwd,
|
|
130
144
|
stdio: ["pipe", "pipe", "pipe"],
|
|
131
145
|
env: input.env ? { ...process.env, ...input.env } : process.env,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verification-runner.js","sourceRoot":"","sources":["../../../src/core/tools/verification-runner.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { spawn, spawnSync } from \"node:child_process\";\nimport {\n\tDEFAULT_MAX_BYTES,\n\tDEFAULT_MAX_LINES,\n\tformatSize,\n\ttype TruncationResult,\n\ttruncateHead,\n} from \"./truncate.js\";\n\nexport const DEFAULT_VERIFICATION_CAPTURE_BYTES = 512 * 1024;\n\nexport type PackageManager = \"npm\" | \"pnpm\" | \"yarn\" | \"bun\";\n\nexport interface PackageJsonInfo {\n\tpath: string;\n\traw: Record<string, unknown>;\n\tscripts: Record<string, string>;\n}\n\nexport interface VerificationCommandResult {\n\tstdout: string;\n\tstderr: string;\n\texitCode: number;\n\tcaptureTruncated: boolean;\n\tdurationMs: number;\n}\n\nexport interface VerificationOutputFormat {\n\ttext: string;\n\ttruncation?: TruncationResult;\n}\n\nexport interface RunVerificationCommandInput {\n\tcommand: string;\n\targs: string[];\n\tcwd: string;\n\ttimeoutMs: number;\n\tsignal?: AbortSignal;\n\tenv?: NodeJS.ProcessEnv;\n\tstdin?: string;\n}\n\nexport interface VerificationBatchItem extends RunVerificationCommandInput {\n\tkey?: string;\n}\n\nexport interface VerificationBatchResult {\n\tkey?: string;\n\tinput: VerificationBatchItem;\n\tresult: VerificationCommandResult;\n}\n\nfunction captureChunk(\n\tchunk: Buffer,\n\tchunks: Buffer[],\n\tcurrentBytes: number,\n\tmaxCaptureBytes: number,\n): { nextBytes: number; truncated: boolean } {\n\tif (currentBytes >= maxCaptureBytes) {\n\t\treturn { nextBytes: currentBytes, truncated: true };\n\t}\n\tconst remaining = maxCaptureBytes - currentBytes;\n\tif (chunk.length <= remaining) {\n\t\tchunks.push(chunk);\n\t\treturn { nextBytes: currentBytes + chunk.length, truncated: false };\n\t}\n\tchunks.push(chunk.subarray(0, remaining));\n\treturn { nextBytes: maxCaptureBytes, truncated: true };\n}\n\nexport function commandExists(command: string): boolean {\n\ttry {\n\t\tconst result = spawnSync(command, [\"--version\"], { stdio: \"pipe\" });\n\t\tconst err = result.error as NodeJS.ErrnoException | undefined;\n\t\treturn !err || err.code !== \"ENOENT\";\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport function resolveCommandCandidate(candidates: string[]): string | undefined {\n\tfor (const candidate of candidates) {\n\t\tif (commandExists(candidate)) {\n\t\t\treturn candidate;\n\t\t}\n\t}\n\treturn undefined;\n}\n\nexport function detectPackageManager(cwd: string): PackageManager {\n\tif (existsSync(join(cwd, \"pnpm-lock.yaml\"))) return \"pnpm\";\n\tif (existsSync(join(cwd, \"yarn.lock\"))) return \"yarn\";\n\tif (existsSync(join(cwd, \"bun.lockb\")) || existsSync(join(cwd, \"bun.lock\"))) return \"bun\";\n\tif (existsSync(join(cwd, \"package-lock.json\")) || existsSync(join(cwd, \"npm-shrinkwrap.json\"))) return \"npm\";\n\treturn \"npm\";\n}\n\nexport function readPackageJson(cwd: string): PackageJsonInfo | undefined {\n\tconst packageJsonPath = join(cwd, \"package.json\");\n\tif (!existsSync(packageJsonPath)) {\n\t\treturn undefined;\n\t}\n\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tthrow new Error(`Failed to parse package.json at ${packageJsonPath}: ${message}`);\n\t}\n\n\tif (!parsed || typeof parsed !== \"object\") {\n\t\tthrow new Error(`package.json at ${packageJsonPath} must contain a JSON object.`);\n\t}\n\n\tconst raw = parsed as Record<string, unknown>;\n\tconst scriptsRaw = raw.scripts;\n\tconst scripts: Record<string, string> = {};\n\tif (scriptsRaw && typeof scriptsRaw === \"object\") {\n\t\tfor (const [key, value] of Object.entries(scriptsRaw as Record<string, unknown>)) {\n\t\t\tif (typeof value === \"string\") {\n\t\t\t\tscripts[key] = value;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { path: packageJsonPath, raw, scripts };\n}\n\nexport function resolvePackageManagerRunInvocation(\n\tpackageManager: PackageManager,\n\tscript: string,\n\tscriptArgs: string[],\n): { command: string; args: string[] } {\n\tif (packageManager === \"npm\") {\n\t\treturn {\n\t\t\tcommand: \"npm\",\n\t\t\targs: scriptArgs.length > 0 ? [\"run\", script, \"--\", ...scriptArgs] : [\"run\", script],\n\t\t};\n\t}\n\tif (packageManager === \"pnpm\") {\n\t\treturn {\n\t\t\tcommand: \"pnpm\",\n\t\t\targs: scriptArgs.length > 0 ? [\"run\", script, \"--\", ...scriptArgs] : [\"run\", script],\n\t\t};\n\t}\n\tif (packageManager === \"yarn\") {\n\t\treturn {\n\t\t\tcommand: \"yarn\",\n\t\t\targs: [\"run\", script, ...scriptArgs],\n\t\t};\n\t}\n\treturn {\n\t\tcommand: \"bun\",\n\t\targs: [\"run\", script, ...scriptArgs],\n\t};\n}\n\nexport function resolvePackageManagerExecInvocation(\n\tpackageManager: PackageManager,\n\tbinary: string,\n\tbinaryArgs: string[],\n): { command: string; args: string[] } {\n\tif (packageManager === \"npm\") {\n\t\treturn { command: \"npm\", args: [\"exec\", \"--\", binary, ...binaryArgs] };\n\t}\n\tif (packageManager === \"pnpm\") {\n\t\treturn { command: \"pnpm\", args: [\"exec\", binary, ...binaryArgs] };\n\t}\n\tif (packageManager === \"yarn\") {\n\t\treturn { command: \"yarn\", args: [\"exec\", binary, ...binaryArgs] };\n\t}\n\tif (commandExists(\"bunx\")) {\n\t\treturn { command: \"bunx\", args: [binary, ...binaryArgs] };\n\t}\n\treturn { command: \"bun\", args: [\"x\", binary, ...binaryArgs] };\n}\n\nexport function ensureCommandOrThrow(command: string, hint?: string): void {\n\tif (commandExists(command)) {\n\t\treturn;\n\t}\n\tconst message = hint ? `${hint}` : `Command \"${command}\" is not available in PATH.`;\n\tthrow new Error(message);\n}\n\nexport async function runVerificationCommand(input: RunVerificationCommandInput): Promise<VerificationCommandResult> {\n\treturn new Promise((resolve, reject) => {\n\t\tif (input.signal?.aborted) {\n\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\treturn;\n\t\t}\n\n\t\tconst startedAt = Date.now();\n\t\tconst child = spawn(input.command, input.args, {\n\t\t\tcwd: input.cwd,\n\t\t\tstdio: [\"pipe\", \"pipe\", \"pipe\"],\n\t\t\tenv: input.env ? { ...process.env, ...input.env } : process.env,\n\t\t});\n\n\t\tlet stdoutBytes = 0;\n\t\tlet stderrBytes = 0;\n\t\tlet captureTruncated = false;\n\t\tlet timedOut = false;\n\t\tlet aborted = false;\n\t\tlet settled = false;\n\n\t\tconst stdoutChunks: Buffer[] = [];\n\t\tconst stderrChunks: Buffer[] = [];\n\n\t\tconst settle = (fn: () => void) => {\n\t\t\tif (!settled) {\n\t\t\t\tsettled = true;\n\t\t\t\tfn();\n\t\t\t}\n\t\t};\n\n\t\tconst timeoutHandle = setTimeout(() => {\n\t\t\ttimedOut = true;\n\t\t\tchild.kill(\"SIGTERM\");\n\t\t}, Math.max(1_000, input.timeoutMs));\n\n\t\tconst onAbort = () => {\n\t\t\taborted = true;\n\t\t\tchild.kill(\"SIGTERM\");\n\t\t};\n\t\tinput.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n\t\tconst cleanup = () => {\n\t\t\tclearTimeout(timeoutHandle);\n\t\t\tinput.signal?.removeEventListener(\"abort\", onAbort);\n\t\t};\n\n\t\tchild.stdout.on(\"data\", (chunk: Buffer) => {\n\t\t\tconst captured = captureChunk(chunk, stdoutChunks, stdoutBytes, DEFAULT_VERIFICATION_CAPTURE_BYTES);\n\t\t\tstdoutBytes = captured.nextBytes;\n\t\t\tcaptureTruncated = captureTruncated || captured.truncated;\n\t\t});\n\n\t\tchild.stderr.on(\"data\", (chunk: Buffer) => {\n\t\t\tconst captured = captureChunk(chunk, stderrChunks, stderrBytes, DEFAULT_VERIFICATION_CAPTURE_BYTES);\n\t\t\tstderrBytes = captured.nextBytes;\n\t\t\tcaptureTruncated = captureTruncated || captured.truncated;\n\t\t});\n\n\t\tif (input.stdin !== undefined) {\n\t\t\tchild.stdin.write(input.stdin);\n\t\t}\n\t\tchild.stdin.end();\n\n\t\tchild.on(\"error\", (error) => {\n\t\t\tcleanup();\n\t\t\tsettle(() => reject(new Error(`Failed to run ${input.command}: ${error.message}`)));\n\t\t});\n\n\t\tchild.on(\"close\", (code) => {\n\t\t\tcleanup();\n\t\t\tif (aborted) {\n\t\t\t\tsettle(() => reject(new Error(\"Operation aborted\")));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (timedOut) {\n\t\t\t\tsettle(() => reject(new Error(`Command timed out after ${Math.round(input.timeoutMs / 1000)}s`)));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsettle(() =>\n\t\t\t\tresolve({\n\t\t\t\t\tstdout: Buffer.concat(stdoutChunks).toString(\"utf-8\"),\n\t\t\t\t\tstderr: Buffer.concat(stderrChunks).toString(\"utf-8\"),\n\t\t\t\t\texitCode: code ?? -1,\n\t\t\t\t\tcaptureTruncated,\n\t\t\t\t\tdurationMs: Date.now() - startedAt,\n\t\t\t\t}),\n\t\t\t);\n\t\t});\n\t});\n}\n\nexport async function runVerificationCommandBatch(items: VerificationBatchItem[]): Promise<VerificationBatchResult[]> {\n\tconst results: VerificationBatchResult[] = [];\n\tfor (const item of items) {\n\t\tconst result = await runVerificationCommand(item);\n\t\tresults.push({\n\t\t\tkey: item.key,\n\t\t\tinput: item,\n\t\t\tresult,\n\t\t});\n\t}\n\treturn results;\n}\n\nexport function formatVerificationOutput(\n\tstdout: string,\n\tstderr: string,\n\tcaptureTruncated: boolean,\n\temptyOutputMessage: string,\n): VerificationOutputFormat {\n\tlet output = stdout.trimEnd();\n\tif (!output && stderr.trim().length > 0) {\n\t\toutput = stderr.trimEnd();\n\t}\n\tif (!output) {\n\t\toutput = emptyOutputMessage;\n\t}\n\n\tconst truncation = truncateHead(output);\n\tlet text = truncation.content;\n\tconst notices: string[] = [];\n\tif (truncation.truncated) {\n\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} output limit reached`);\n\t}\n\tif (captureTruncated) {\n\t\tnotices.push(`capture limit reached (${formatSize(DEFAULT_VERIFICATION_CAPTURE_BYTES)})`);\n\t}\n\tif (notices.length > 0) {\n\t\ttext += `\\n\\n[${notices.join(\". \")} · showing up to ${DEFAULT_MAX_LINES} lines]`;\n\t}\n\n\treturn {\n\t\ttext,\n\t\ttruncation: truncation.truncated ? truncation : undefined,\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"verification-runner.js","sourceRoot":"","sources":["../../../src/core/tools/verification-runner.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { spawn, spawnSync } from \"node:child_process\";\nimport { isSandboxEnabledFromEnv, wrapCommandWithSandbox } from \"../sandbox/executor.js\";\nimport {\n\tDEFAULT_MAX_BYTES,\n\tDEFAULT_MAX_LINES,\n\tformatSize,\n\ttype TruncationResult,\n\ttruncateHead,\n} from \"./truncate.js\";\n\nexport const DEFAULT_VERIFICATION_CAPTURE_BYTES = 512 * 1024;\n\nexport type PackageManager = \"npm\" | \"pnpm\" | \"yarn\" | \"bun\";\n\nexport interface PackageJsonInfo {\n\tpath: string;\n\traw: Record<string, unknown>;\n\tscripts: Record<string, string>;\n}\n\nexport interface VerificationCommandResult {\n\tstdout: string;\n\tstderr: string;\n\texitCode: number;\n\tcaptureTruncated: boolean;\n\tdurationMs: number;\n}\n\nexport interface VerificationOutputFormat {\n\ttext: string;\n\ttruncation?: TruncationResult;\n}\n\nexport interface RunVerificationCommandInput {\n\tcommand: string;\n\targs: string[];\n\tcwd: string;\n\ttimeoutMs: number;\n\tsignal?: AbortSignal;\n\tenv?: NodeJS.ProcessEnv;\n\tstdin?: string;\n}\n\nexport interface VerificationBatchItem extends RunVerificationCommandInput {\n\tkey?: string;\n}\n\nexport interface VerificationBatchResult {\n\tkey?: string;\n\tinput: VerificationBatchItem;\n\tresult: VerificationCommandResult;\n}\n\nfunction captureChunk(\n\tchunk: Buffer,\n\tchunks: Buffer[],\n\tcurrentBytes: number,\n\tmaxCaptureBytes: number,\n): { nextBytes: number; truncated: boolean } {\n\tif (currentBytes >= maxCaptureBytes) {\n\t\treturn { nextBytes: currentBytes, truncated: true };\n\t}\n\tconst remaining = maxCaptureBytes - currentBytes;\n\tif (chunk.length <= remaining) {\n\t\tchunks.push(chunk);\n\t\treturn { nextBytes: currentBytes + chunk.length, truncated: false };\n\t}\n\tchunks.push(chunk.subarray(0, remaining));\n\treturn { nextBytes: maxCaptureBytes, truncated: true };\n}\n\nexport function commandExists(command: string): boolean {\n\ttry {\n\t\tconst result = spawnSync(command, [\"--version\"], { stdio: \"pipe\" });\n\t\tconst err = result.error as NodeJS.ErrnoException | undefined;\n\t\treturn !err || err.code !== \"ENOENT\";\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport function resolveCommandCandidate(candidates: string[]): string | undefined {\n\tfor (const candidate of candidates) {\n\t\tif (commandExists(candidate)) {\n\t\t\treturn candidate;\n\t\t}\n\t}\n\treturn undefined;\n}\n\nexport function detectPackageManager(cwd: string): PackageManager {\n\tif (existsSync(join(cwd, \"pnpm-lock.yaml\"))) return \"pnpm\";\n\tif (existsSync(join(cwd, \"yarn.lock\"))) return \"yarn\";\n\tif (existsSync(join(cwd, \"bun.lockb\")) || existsSync(join(cwd, \"bun.lock\"))) return \"bun\";\n\tif (existsSync(join(cwd, \"package-lock.json\")) || existsSync(join(cwd, \"npm-shrinkwrap.json\"))) return \"npm\";\n\treturn \"npm\";\n}\n\nexport function readPackageJson(cwd: string): PackageJsonInfo | undefined {\n\tconst packageJsonPath = join(cwd, \"package.json\");\n\tif (!existsSync(packageJsonPath)) {\n\t\treturn undefined;\n\t}\n\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(readFileSync(packageJsonPath, \"utf-8\"));\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tthrow new Error(`Failed to parse package.json at ${packageJsonPath}: ${message}`);\n\t}\n\n\tif (!parsed || typeof parsed !== \"object\") {\n\t\tthrow new Error(`package.json at ${packageJsonPath} must contain a JSON object.`);\n\t}\n\n\tconst raw = parsed as Record<string, unknown>;\n\tconst scriptsRaw = raw.scripts;\n\tconst scripts: Record<string, string> = {};\n\tif (scriptsRaw && typeof scriptsRaw === \"object\") {\n\t\tfor (const [key, value] of Object.entries(scriptsRaw as Record<string, unknown>)) {\n\t\t\tif (typeof value === \"string\") {\n\t\t\t\tscripts[key] = value;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { path: packageJsonPath, raw, scripts };\n}\n\nexport function resolvePackageManagerRunInvocation(\n\tpackageManager: PackageManager,\n\tscript: string,\n\tscriptArgs: string[],\n): { command: string; args: string[] } {\n\tif (packageManager === \"npm\") {\n\t\treturn {\n\t\t\tcommand: \"npm\",\n\t\t\targs: scriptArgs.length > 0 ? [\"run\", script, \"--\", ...scriptArgs] : [\"run\", script],\n\t\t};\n\t}\n\tif (packageManager === \"pnpm\") {\n\t\treturn {\n\t\t\tcommand: \"pnpm\",\n\t\t\targs: scriptArgs.length > 0 ? [\"run\", script, \"--\", ...scriptArgs] : [\"run\", script],\n\t\t};\n\t}\n\tif (packageManager === \"yarn\") {\n\t\treturn {\n\t\t\tcommand: \"yarn\",\n\t\t\targs: [\"run\", script, ...scriptArgs],\n\t\t};\n\t}\n\treturn {\n\t\tcommand: \"bun\",\n\t\targs: [\"run\", script, ...scriptArgs],\n\t};\n}\n\nexport function resolvePackageManagerExecInvocation(\n\tpackageManager: PackageManager,\n\tbinary: string,\n\tbinaryArgs: string[],\n): { command: string; args: string[] } {\n\tif (packageManager === \"npm\") {\n\t\treturn { command: \"npm\", args: [\"exec\", \"--\", binary, ...binaryArgs] };\n\t}\n\tif (packageManager === \"pnpm\") {\n\t\treturn { command: \"pnpm\", args: [\"exec\", binary, ...binaryArgs] };\n\t}\n\tif (packageManager === \"yarn\") {\n\t\treturn { command: \"yarn\", args: [\"exec\", binary, ...binaryArgs] };\n\t}\n\tif (commandExists(\"bunx\")) {\n\t\treturn { command: \"bunx\", args: [binary, ...binaryArgs] };\n\t}\n\treturn { command: \"bun\", args: [\"x\", binary, ...binaryArgs] };\n}\n\nexport function ensureCommandOrThrow(command: string, hint?: string): void {\n\tif (commandExists(command)) {\n\t\treturn;\n\t}\n\tconst message = hint ? `${hint}` : `Command \"${command}\" is not available in PATH.`;\n\tthrow new Error(message);\n}\n\nexport async function runVerificationCommand(input: RunVerificationCommandInput): Promise<VerificationCommandResult> {\n\treturn new Promise((resolve, reject) => {\n\t\tif (input.signal?.aborted) {\n\t\t\treject(new Error(\"Operation aborted\"));\n\t\t\treturn;\n\t\t}\n\n\t\tconst startedAt = Date.now();\n\t\tlet wrapped;\n\t\ttry {\n\t\t\twrapped = wrapCommandWithSandbox({\n\t\t\t\tcommand: input.command,\n\t\t\t\targs: input.args,\n\t\t\t\tcwd: input.cwd,\n\t\t\t\tenabled: isSandboxEnabledFromEnv(),\n\t\t\t});\n\t\t} catch (error) {\n\t\t\treject(error instanceof Error ? error : new Error(String(error)));\n\t\t\treturn;\n\t\t}\n\n\t\tconst child = spawn(wrapped.command, wrapped.args, {\n\t\t\tcwd: input.cwd,\n\t\t\tstdio: [\"pipe\", \"pipe\", \"pipe\"],\n\t\t\tenv: input.env ? { ...process.env, ...input.env } : process.env,\n\t\t});\n\n\t\tlet stdoutBytes = 0;\n\t\tlet stderrBytes = 0;\n\t\tlet captureTruncated = false;\n\t\tlet timedOut = false;\n\t\tlet aborted = false;\n\t\tlet settled = false;\n\n\t\tconst stdoutChunks: Buffer[] = [];\n\t\tconst stderrChunks: Buffer[] = [];\n\n\t\tconst settle = (fn: () => void) => {\n\t\t\tif (!settled) {\n\t\t\t\tsettled = true;\n\t\t\t\tfn();\n\t\t\t}\n\t\t};\n\n\t\tconst timeoutHandle = setTimeout(() => {\n\t\t\ttimedOut = true;\n\t\t\tchild.kill(\"SIGTERM\");\n\t\t}, Math.max(1_000, input.timeoutMs));\n\n\t\tconst onAbort = () => {\n\t\t\taborted = true;\n\t\t\tchild.kill(\"SIGTERM\");\n\t\t};\n\t\tinput.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\n\t\tconst cleanup = () => {\n\t\t\tclearTimeout(timeoutHandle);\n\t\t\tinput.signal?.removeEventListener(\"abort\", onAbort);\n\t\t};\n\n\t\tchild.stdout.on(\"data\", (chunk: Buffer) => {\n\t\t\tconst captured = captureChunk(chunk, stdoutChunks, stdoutBytes, DEFAULT_VERIFICATION_CAPTURE_BYTES);\n\t\t\tstdoutBytes = captured.nextBytes;\n\t\t\tcaptureTruncated = captureTruncated || captured.truncated;\n\t\t});\n\n\t\tchild.stderr.on(\"data\", (chunk: Buffer) => {\n\t\t\tconst captured = captureChunk(chunk, stderrChunks, stderrBytes, DEFAULT_VERIFICATION_CAPTURE_BYTES);\n\t\t\tstderrBytes = captured.nextBytes;\n\t\t\tcaptureTruncated = captureTruncated || captured.truncated;\n\t\t});\n\n\t\tif (input.stdin !== undefined) {\n\t\t\tchild.stdin.write(input.stdin);\n\t\t}\n\t\tchild.stdin.end();\n\n\t\tchild.on(\"error\", (error) => {\n\t\t\tcleanup();\n\t\t\tsettle(() => reject(new Error(`Failed to run ${input.command}: ${error.message}`)));\n\t\t});\n\n\t\tchild.on(\"close\", (code) => {\n\t\t\tcleanup();\n\t\t\tif (aborted) {\n\t\t\t\tsettle(() => reject(new Error(\"Operation aborted\")));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (timedOut) {\n\t\t\t\tsettle(() => reject(new Error(`Command timed out after ${Math.round(input.timeoutMs / 1000)}s`)));\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tsettle(() =>\n\t\t\t\tresolve({\n\t\t\t\t\tstdout: Buffer.concat(stdoutChunks).toString(\"utf-8\"),\n\t\t\t\t\tstderr: Buffer.concat(stderrChunks).toString(\"utf-8\"),\n\t\t\t\t\texitCode: code ?? -1,\n\t\t\t\t\tcaptureTruncated,\n\t\t\t\t\tdurationMs: Date.now() - startedAt,\n\t\t\t\t}),\n\t\t\t);\n\t\t});\n\t});\n}\n\nexport async function runVerificationCommandBatch(items: VerificationBatchItem[]): Promise<VerificationBatchResult[]> {\n\tconst results: VerificationBatchResult[] = [];\n\tfor (const item of items) {\n\t\tconst result = await runVerificationCommand(item);\n\t\tresults.push({\n\t\t\tkey: item.key,\n\t\t\tinput: item,\n\t\t\tresult,\n\t\t});\n\t}\n\treturn results;\n}\n\nexport function formatVerificationOutput(\n\tstdout: string,\n\tstderr: string,\n\tcaptureTruncated: boolean,\n\temptyOutputMessage: string,\n): VerificationOutputFormat {\n\tlet output = stdout.trimEnd();\n\tif (!output && stderr.trim().length > 0) {\n\t\toutput = stderr.trimEnd();\n\t}\n\tif (!output) {\n\t\toutput = emptyOutputMessage;\n\t}\n\n\tconst truncation = truncateHead(output);\n\tlet text = truncation.content;\n\tconst notices: string[] = [];\n\tif (truncation.truncated) {\n\t\tnotices.push(`${formatSize(DEFAULT_MAX_BYTES)} output limit reached`);\n\t}\n\tif (captureTruncated) {\n\t\tnotices.push(`capture limit reached (${formatSize(DEFAULT_VERIFICATION_CAPTURE_BYTES)})`);\n\t}\n\tif (notices.length > 0) {\n\t\ttext += `\\n\\n[${notices.join(\". \")} · showing up to ${DEFAULT_MAX_LINES} lines]`;\n\t}\n\n\treturn {\n\t\ttext,\n\t\ttruncation: truncation.truncated ? truncation : undefined,\n\t};\n}\n"]}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export interface UnifiedExecRunInput {
|
|
2
|
+
command: string;
|
|
3
|
+
cwd?: string;
|
|
4
|
+
tty?: boolean;
|
|
5
|
+
shell?: string;
|
|
6
|
+
login?: boolean;
|
|
7
|
+
yieldTimeMs?: number;
|
|
8
|
+
maxOutputChars?: number;
|
|
9
|
+
}
|
|
10
|
+
export interface UnifiedExecWriteInput {
|
|
11
|
+
sessionId: number;
|
|
12
|
+
chars?: string;
|
|
13
|
+
yieldTimeMs?: number;
|
|
14
|
+
maxOutputChars?: number;
|
|
15
|
+
}
|
|
16
|
+
export interface UnifiedExecPollResult {
|
|
17
|
+
output: string;
|
|
18
|
+
running: boolean;
|
|
19
|
+
sessionId?: number;
|
|
20
|
+
exitCode?: number | null;
|
|
21
|
+
}
|
|
22
|
+
export declare class UnifiedExecManager {
|
|
23
|
+
private sessions;
|
|
24
|
+
private nextSessionId;
|
|
25
|
+
execCommand(input: UnifiedExecRunInput): Promise<UnifiedExecPollResult>;
|
|
26
|
+
writeStdin(input: UnifiedExecWriteInput): Promise<UnifiedExecPollResult>;
|
|
27
|
+
dispose(): void;
|
|
28
|
+
private createSession;
|
|
29
|
+
private appendOutput;
|
|
30
|
+
private notify;
|
|
31
|
+
private waitForUpdate;
|
|
32
|
+
private waitForExitGrace;
|
|
33
|
+
private waitForClose;
|
|
34
|
+
private drainOutput;
|
|
35
|
+
private buildPollResult;
|
|
36
|
+
private resolveInvocation;
|
|
37
|
+
private buildShellArgs;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=unified-exec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unified-exec.d.ts","sourceRoot":"","sources":["../../src/core/unified-exec.ts"],"names":[],"mappings":"AAmEA,MAAM,WAAW,mBAAmB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACrC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,qBAAqB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAwBD,qBAAa,kBAAkB;IAC9B,OAAO,CAAC,QAAQ,CAAyC;IACzD,OAAO,CAAC,aAAa,CAAK;IAEpB,WAAW,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAYvE,UAAU,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAmB9E,OAAO,IAAI,IAAI;IAcf,OAAO,CAAC,aAAa;IAkDrB,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,MAAM;YASA,aAAa;YAiBb,gBAAgB;YAKhB,YAAY;IAkB1B,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,eAAe;IAqBvB,OAAO,CAAC,iBAAiB;IA4BzB,OAAO,CAAC,cAAc;CAStB"}
|