@chainingintention/pi-web-cn 1.202608.5 → 1.202608.7

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.
Files changed (74) hide show
  1. package/dist/cli.js +8 -0
  2. package/dist/cli.js.map +1 -1
  3. package/dist/client/assets/{CodeViewer-BUT2Idcq.js → CodeViewer-CWKEeX0r.js} +1 -1
  4. package/dist/client/assets/{TerminalPanel-b8CZY7en.js → TerminalPanel-BmA7Ayzk.js} +1 -1
  5. package/dist/client/assets/{UnifiedDiffViewer-CXY7AXrD.js → UnifiedDiffViewer-2DACwxFY.js} +1 -1
  6. package/dist/client/assets/{index-80SI7dCz.js → index-D6j67Izj.js} +491 -300
  7. package/dist/client/index.html +1 -1
  8. package/dist/config.js +86 -0
  9. package/dist/config.js.map +1 -1
  10. package/dist/pi-web-plugins/relays/relaysPanelElement.js +112 -46
  11. package/dist/server/app.js +4 -1
  12. package/dist/server/app.js.map +1 -1
  13. package/dist/server/audit/managementAuditStore.js +211 -0
  14. package/dist/server/audit/managementAuditStore.js.map +1 -0
  15. package/dist/server/audit/normalToolAuditCli.js +143 -0
  16. package/dist/server/audit/normalToolAuditCli.js.map +1 -0
  17. package/dist/server/audit/normalToolAuditStore.js +264 -0
  18. package/dist/server/audit/normalToolAuditStore.js.map +1 -0
  19. package/dist/server/managementEmbed.js +19 -1
  20. package/dist/server/managementEmbed.js.map +1 -1
  21. package/dist/server/piWebStatus.js +7 -1
  22. package/dist/server/piWebStatus.js.map +1 -1
  23. package/dist/server/requestLogging.js +10 -7
  24. package/dist/server/requestLogging.js.map +1 -1
  25. package/dist/server/sessiond/sessionProxyRoutes.js +13 -7
  26. package/dist/server/sessiond/sessionProxyRoutes.js.map +1 -1
  27. package/dist/server/sessiond/sessionServiceDependencies.js +1 -0
  28. package/dist/server/sessiond/sessionServiceDependencies.js.map +1 -1
  29. package/dist/server/sessiond.js +91 -4
  30. package/dist/server/sessiond.js.map +1 -1
  31. package/dist/server/sessions/extensionDialogWaiters.js +76 -0
  32. package/dist/server/sessions/extensionDialogWaiters.js.map +1 -0
  33. package/dist/server/sessions/managementPermissionSystem.js +8 -8
  34. package/dist/server/sessions/managementPermissionSystem.js.map +1 -1
  35. package/dist/server/sessions/pendingExtensionDialogStore.js +196 -0
  36. package/dist/server/sessions/pendingExtensionDialogStore.js.map +1 -0
  37. package/dist/server/sessions/piSessionService.js +493 -78
  38. package/dist/server/sessions/piSessionService.js.map +1 -1
  39. package/dist/server/sessions/sessionRoutes.js +54 -27
  40. package/dist/server/sessions/sessionRoutes.js.map +1 -1
  41. package/dist/server/sessions/sessionUiEvents.js +9 -2
  42. package/dist/server/sessions/sessionUiEvents.js.map +1 -1
  43. package/dist/server/sessions/spawnSessionTool.js +8 -1
  44. package/dist/server/sessions/spawnSessionTool.js.map +1 -1
  45. package/dist/server/sessions/spawnSubsessionTool.js +7 -1
  46. package/dist/server/sessions/spawnSubsessionTool.js.map +1 -1
  47. package/dist/server/workbench/accessStateRoutes.js +30 -0
  48. package/dist/server/workbench/accessStateRoutes.js.map +1 -0
  49. package/dist/server/workbench/accessStateStore.js +29 -0
  50. package/dist/server/workbench/accessStateStore.js.map +1 -0
  51. package/dist/server/workbench/capabilitySearch.js +62 -0
  52. package/dist/server/workbench/capabilitySearch.js.map +1 -0
  53. package/dist/server/workbench/gatewayIntegration.js +56 -0
  54. package/dist/server/workbench/gatewayIntegration.js.map +1 -0
  55. package/dist/server/workbench/mcpClient.js +148 -0
  56. package/dist/server/workbench/mcpClient.js.map +1 -0
  57. package/dist/server/workbench/skillSync.js +375 -0
  58. package/dist/server/workbench/skillSync.js.map +1 -0
  59. package/dist/server/workbench/types.js +2 -0
  60. package/dist/server/workbench/types.js.map +1 -0
  61. package/dist/server/workbench/workbenchClient.js +136 -0
  62. package/dist/server/workbench/workbenchClient.js.map +1 -0
  63. package/dist/server/workbench/workbenchTools.js +145 -0
  64. package/dist/server/workbench/workbenchTools.js.map +1 -0
  65. package/dist/shared/apiTypes.d.ts +141 -1
  66. package/dist/shared/apiTypes.js +8 -0
  67. package/dist/shared/apiTypes.js.map +1 -1
  68. package/dist/shared/federatedRoutes.js +2 -0
  69. package/dist/shared/federatedRoutes.js.map +1 -1
  70. package/dist/shared/piWebConfigParsing.js +94 -0
  71. package/dist/shared/piWebConfigParsing.js.map +1 -1
  72. package/docs/config.md +86 -1
  73. package/docs/plugins.md +14 -0
  74. package/package.json +7 -3
@@ -0,0 +1,62 @@
1
+ export function searchAuthorizedCapabilities(resources, input) {
2
+ const keyword = input.keyword?.trim().toLocaleLowerCase() ?? "";
3
+ const limit = Math.max(1, Math.min(input.limit ?? 8, 20));
4
+ const candidates = resources
5
+ .filter(isAuthorizedL0Capability)
6
+ .filter((item) => input.bizDomain === undefined || metadataString(item, "biz_domain") === input.bizDomain)
7
+ .filter((item) => input.packName === undefined || metadataString(item, "pack_name") === input.packName)
8
+ .map((item) => ({ item, score: capabilityScore(item, keyword) }))
9
+ .filter((candidate) => keyword === "" || candidate.score > 0)
10
+ .sort((left, right) => right.score - left.score || left.item.resourceName.localeCompare(right.item.resourceName));
11
+ return { items: candidates.slice(0, limit).map((candidate) => toCapabilitySummary(candidate.item)), total: candidates.length };
12
+ }
13
+ export function requireAuthorizedL0Capability(resources, name) {
14
+ const item = resources.find((resource) => resource.resourceName === name && isAuthorizedL0Capability(resource));
15
+ if (item === undefined)
16
+ throw new Error("当前账号未获授权使用该L0能力");
17
+ return item;
18
+ }
19
+ function isAuthorizedL0Capability(item) {
20
+ return item.resourceType === "capability" && item.status === "published" && item.riskLevel === "L0";
21
+ }
22
+ function capabilityScore(item, keyword) {
23
+ if (keyword === "")
24
+ return 1;
25
+ const exactName = item.resourceName.toLocaleLowerCase() === keyword ? 1_000 : 0;
26
+ const fields = [item.displayName, item.description, metadataString(item, "pack_name"), metadataString(item, "biz_domain"), ...metadataStrings(item, "tags")]
27
+ .filter((field) => field !== undefined);
28
+ return exactName + fields.reduce((score, field, index) => score + (field.toLocaleLowerCase().includes(keyword) ? 100 - index : 0), 0);
29
+ }
30
+ function toCapabilitySummary(item) {
31
+ const packName = metadataString(item, "pack_name");
32
+ const bizDomain = metadataString(item, "biz_domain");
33
+ return {
34
+ name: item.resourceName,
35
+ version: item.resourceVersion,
36
+ displayName: item.displayName,
37
+ description: item.description,
38
+ inputSchema: metadataRecord(item, "inputSchema"),
39
+ outputSchema: metadataRecord(item, "outputSchema"),
40
+ examples: Array.isArray(item.metadata["examples"]) ? item.metadata["examples"] : [],
41
+ ...(packName === undefined ? {} : { packName }),
42
+ ...(bizDomain === undefined ? {} : { bizDomain }),
43
+ tags: metadataStrings(item, "tags"),
44
+ riskLevel: "L0",
45
+ };
46
+ }
47
+ function metadataString(item, key) {
48
+ const value = item.metadata[key];
49
+ return typeof value === "string" && value !== "" ? value : undefined;
50
+ }
51
+ function metadataStrings(item, key) {
52
+ const value = item.metadata[key];
53
+ return Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : [];
54
+ }
55
+ function metadataRecord(item, key) {
56
+ const value = item.metadata[key];
57
+ return isRecord(value) ? value : {};
58
+ }
59
+ function isRecord(value) {
60
+ return typeof value === "object" && value !== null && !Array.isArray(value);
61
+ }
62
+ //# sourceMappingURL=capabilitySearch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilitySearch.js","sourceRoot":"","sources":["../../../src/server/workbench/capabilitySearch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ import { createHash, randomBytes } from "node:crypto";
2
+ import { WorkbenchClient } from "./workbenchClient.js";
3
+ import { WORKBENCH_ACCESS_STATE_ROUTE } from "./accessStateRoutes.js";
4
+ export function createWorkbenchManagementRuntime(base, config, daemon) {
5
+ if (base === undefined || config === undefined)
6
+ return base;
7
+ const handles = new WeakMap();
8
+ const bindings = new Map();
9
+ const client = new WorkbenchClient({ baseUrl: config.baseUrl, requestTimeoutMs: config.requestTimeoutMs ?? 10_000 });
10
+ return {
11
+ ...base,
12
+ async authenticate(token) {
13
+ const context = await base.authenticate(token);
14
+ const now = Date.now();
15
+ for (const [key, binding] of bindings) {
16
+ if (binding.expiresAt <= now)
17
+ bindings.delete(key);
18
+ }
19
+ const key = createHash("sha256").update(token).digest("base64url");
20
+ let cached = bindings.get(key);
21
+ if (cached === undefined) {
22
+ const projectId = context.projects[0]?.id ?? "personal-project";
23
+ const pending = createWorkbenchBinding(client, daemon, token, projectId, context.expiresAt);
24
+ const created = { expiresAt: expiryTime(context.expiresAt), pending };
25
+ cached = created;
26
+ bindings.set(key, created);
27
+ void pending.then((binding) => { created.expiresAt = Math.min(created.expiresAt, binding.expiresAt); }, () => { if (bindings.get(key) === created)
28
+ bindings.delete(key); });
29
+ }
30
+ const binding = await cached.pending;
31
+ handles.set(context, binding.handle);
32
+ return context;
33
+ },
34
+ resourceHandle(context) {
35
+ return handles.get(context);
36
+ },
37
+ };
38
+ }
39
+ async function createWorkbenchBinding(client, daemon, token, projectId, entryExpiresAt) {
40
+ const state = await client.createAgentAccessState(token, projectId);
41
+ const handle = randomBytes(32).toString("base64url");
42
+ const response = await daemon.request("PUT", `${WORKBENCH_ACCESS_STATE_ROUTE}/${encodeURIComponent(handle)}`, state);
43
+ if (response.statusCode !== 204) {
44
+ await client.revoke(state).catch(() => undefined);
45
+ throw new Error("Session daemon rejected the workbench resource state");
46
+ }
47
+ return {
48
+ handle,
49
+ expiresAt: Math.min(expiryTime(entryExpiresAt), expiryTime(state.expiresAt)),
50
+ };
51
+ }
52
+ function expiryTime(value) {
53
+ const parsed = value === undefined ? Number.NaN : Date.parse(value);
54
+ return Number.isFinite(parsed) ? parsed : Number.POSITIVE_INFINITY;
55
+ }
56
+ //# sourceMappingURL=gatewayIntegration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gatewayIntegration.js","sourceRoot":"","sources":["../../../src/server/workbench/gatewayIntegration.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,148 @@
1
+ import { isRecord, record, stringField } from "./workbenchClient.js";
2
+ export class McpHttpError extends Error {
3
+ constructor(status, message) {
4
+ super(message);
5
+ this.status = status;
6
+ }
7
+ }
8
+ export class WorkbenchMcpClient {
9
+ constructor(options) {
10
+ this.options = options;
11
+ this.fetchImpl = options.fetch ?? fetch;
12
+ }
13
+ async callCapability(token, capabilityName, args, idempotencyKey) {
14
+ const initialized = await this.rpc(token, undefined, {
15
+ jsonrpc: "2.0",
16
+ id: 1,
17
+ method: "initialize",
18
+ params: { protocolVersion: "2025-06-18", capabilities: {}, clientInfo: { name: "pi-web-workbench-adapter", version: "1.0.0" } },
19
+ });
20
+ const sessionId = initialized.headers.get("mcp-session-id");
21
+ if (sessionId === null || sessionId.trim() === "")
22
+ throw new Error("MCP initialize response did not include mcp-session-id");
23
+ await this.rpc(token, sessionId, { jsonrpc: "2.0", method: "notifications/initialized" }, false);
24
+ const response = await this.rpc(token, sessionId, {
25
+ jsonrpc: "2.0",
26
+ id: 2,
27
+ method: "tools/call",
28
+ params: {
29
+ name: "icnoc_call_capability",
30
+ arguments: {
31
+ capability_name: capabilityName,
32
+ arguments: args,
33
+ ...(idempotencyKey === undefined ? {} : { idempotency_key: idempotencyKey }),
34
+ },
35
+ },
36
+ });
37
+ return parseStableCapabilityResult(response.value);
38
+ }
39
+ async rpc(token, sessionId, body, expectBody = true) {
40
+ const headers = {
41
+ authorization: `Bearer ${token}`,
42
+ accept: "application/json, text/event-stream",
43
+ "content-type": "application/json",
44
+ ...(sessionId === undefined ? {} : { "mcp-session-id": sessionId }),
45
+ };
46
+ const response = await this.fetchImpl(this.options.mcpUrl, {
47
+ method: "POST",
48
+ headers,
49
+ body: JSON.stringify(body),
50
+ signal: AbortSignal.timeout(this.options.timeoutMs),
51
+ });
52
+ const text = await response.text();
53
+ if (!response.ok)
54
+ throw new McpHttpError(response.status, mcpErrorMessage(text, response.status));
55
+ return { headers: response.headers, value: expectBody ? parseMcpPayload(text, response.headers.get("content-type")) : undefined };
56
+ }
57
+ }
58
+ export function parseMcpPayload(text, contentType) {
59
+ if (contentType?.toLocaleLowerCase().includes("text/event-stream") === true) {
60
+ const messages = text.split(/\r?\n\r?\n/u).flatMap((event) => {
61
+ const data = event.split(/\r?\n/u)
62
+ .filter((line) => line.startsWith("data:"))
63
+ .map((line) => line.slice(5).trim())
64
+ .join("\n");
65
+ return data === "" ? [] : [parseJson(data)];
66
+ });
67
+ const message = messages.find((value) => isRecord(value) && (value["result"] !== undefined || value["error"] !== undefined));
68
+ if (message === undefined)
69
+ throw new Error("MCP SSE response did not contain a JSON-RPC result");
70
+ return message;
71
+ }
72
+ try {
73
+ return parseJson(text);
74
+ }
75
+ catch {
76
+ throw new Error("MCP response was not valid JSON");
77
+ }
78
+ }
79
+ export function parseStableCapabilityResult(payload) {
80
+ const envelope = record(payload, "MCP JSON-RPC response");
81
+ if (envelope["error"] !== undefined)
82
+ throw new Error(jsonRpcError(envelope["error"]));
83
+ const result = record(envelope["result"], "MCP tool result");
84
+ const content = result["content"];
85
+ if (!Array.isArray(content))
86
+ throw new Error("MCP tool result content must be an array");
87
+ const text = content.map((entry) => isRecord(entry) && entry["type"] === "text" && typeof entry["text"] === "string" ? entry["text"] : undefined)
88
+ .find((entry) => entry !== undefined);
89
+ if (text === undefined)
90
+ throw new Error("MCP tool result did not include text content");
91
+ let value;
92
+ try {
93
+ value = JSON.parse(text);
94
+ }
95
+ catch {
96
+ throw new Error("MCP capability result text was not valid JSON");
97
+ }
98
+ const stable = record(value, "MCP capability result");
99
+ const errorValue = stable["error"];
100
+ const meta = record(stable["meta"], "MCP capability result meta");
101
+ return {
102
+ ok: booleanField(stable, "ok"),
103
+ capability_name: stringField(stable, "capability_name"),
104
+ status_code: integerField(stable, "status_code"),
105
+ data: stable["data"],
106
+ error: errorValue === null ? null : parseCapabilityError(errorValue),
107
+ meta: {
108
+ trace_id: stringField(meta, "trace_id"),
109
+ duration_ms: integerField(meta, "duration_ms"),
110
+ truncated: booleanField(meta, "truncated"),
111
+ },
112
+ };
113
+ }
114
+ function parseCapabilityError(value) {
115
+ const error = record(value, "MCP capability error");
116
+ return { code: stringField(error, "code"), message: stringField(error, "message"), retryable: booleanField(error, "retryable") };
117
+ }
118
+ function mcpErrorMessage(text, status) {
119
+ try {
120
+ const value = parseJson(text);
121
+ if (isRecord(value) && typeof value["error"] === "string")
122
+ return `MCP HTTP ${String(status)}: ${value["error"]}`;
123
+ }
124
+ catch { /* response is not JSON */ }
125
+ return `MCP HTTP ${String(status)}`;
126
+ }
127
+ function jsonRpcError(value) {
128
+ if (!isRecord(value))
129
+ return "MCP returned a JSON-RPC error";
130
+ return typeof value["message"] === "string" ? `MCP JSON-RPC error: ${value["message"]}` : "MCP returned a JSON-RPC error";
131
+ }
132
+ function integerField(value, key) {
133
+ const field = value[key];
134
+ if (typeof field !== "number" || !Number.isInteger(field))
135
+ throw new Error(`${key} must be an integer`);
136
+ return field;
137
+ }
138
+ function parseJson(text) {
139
+ const value = JSON.parse(text);
140
+ return value;
141
+ }
142
+ function booleanField(value, key) {
143
+ const field = value[key];
144
+ if (typeof field !== "boolean")
145
+ throw new Error(`${key} must be a boolean`);
146
+ return field;
147
+ }
148
+ //# sourceMappingURL=mcpClient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcpClient.js","sourceRoot":"","sources":["../../../src/server/workbench/mcpClient.ts"],"names":[],"mappings":"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"}