opencode-agent-skill 15.1.0 → 15.1.2
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 +5 -5
- package/docs/V15-MANAGED-RUNTIME.md +18 -0
- package/global-config/agents/verifier.md +6 -2
- package/lib/affected-tests.mjs +28 -7
- package/lib/capability-fabric.mjs +107 -48
- package/lib/code-intelligence/index.mjs +50 -24
- package/lib/code-intelligence/lsp-pool.mjs +831 -0
- package/lib/code-intelligence/lsp-provider.mjs +197 -20
- package/lib/compaction-resume-guard.mjs +76 -4
- package/lib/completion-auditor.mjs +20 -0
- package/lib/context-manifest.mjs +88 -36
- package/lib/decision-policy.mjs +40 -2
- package/lib/evidence-store.mjs +121 -31
- package/lib/executable-probe.mjs +69 -0
- package/lib/execution-contract.mjs +2 -2
- package/lib/hierarchical-context.mjs +31 -3
- package/lib/learning-engine.mjs +164 -65
- package/lib/memory-engine.mjs +177 -95
- package/lib/model-config.mjs +86 -7
- package/lib/performance-fabric.mjs +92 -0
- package/lib/permission-policy.mjs +232 -0
- package/lib/pi-rpc-pool.mjs +220 -24
- package/lib/provider-recovery.mjs +51 -0
- package/lib/repo-graph.mjs +40 -7
- package/lib/repo-inspect.mjs +3 -2
- package/lib/runtime-events.mjs +31 -10
- package/lib/semantic-index.mjs +69 -21
- package/lib/skill-compiler.mjs +84 -18
- package/lib/task-engine.mjs +28 -9
- package/lib/task-policy.mjs +80 -7
- package/lib/trajectory.mjs +25 -1
- package/lib/untrusted-output.mjs +106 -0
- package/lib/workspace-fingerprint.mjs +17 -9
- package/lib/workspace-hygiene.mjs +2 -2
- package/lib/worktree-sandbox.mjs +14 -8
- package/package.json +8 -6
- package/pi/extensions/ues-child-runtime.ts +116 -5
- package/pi/extensions/ues.ts +780 -81
- package/scripts/benchmark-lsp-pool.mjs +128 -0
- package/scripts/check-release-consistency.mjs +16 -4
- package/scripts/check-source-integrity.mjs +118 -6
- package/scripts/run-test-suite.mjs +143 -0
- package/scripts/smoke-package-closure.mjs +4 -0
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
2
2
|
import { Type } from "typebox";
|
|
3
3
|
import { readFile, stat } from "node:fs/promises";
|
|
4
|
+
import path from "node:path";
|
|
4
5
|
import { compactReversibleOutput } from "../../lib/performance-fabric.mjs";
|
|
5
6
|
import { getEvidenceSelected } from "../../lib/evidence-store.mjs";
|
|
6
7
|
import { recordVerification } from "../../lib/verification-broker.mjs";
|
|
7
8
|
import { runtimeWorkspaceFingerprint } from "../../lib/workspace-fingerprint.mjs";
|
|
8
9
|
import { destructiveShellRisk } from "../../lib/safety.mjs";
|
|
10
|
+
import { getUesConfigDir } from "../../lib/runtime-config.mjs";
|
|
11
|
+
import { PermissionPolicyStore, permissionRecoveryHint, toolPermissionRequest } from "../../lib/permission-policy.mjs";
|
|
12
|
+
import { analyzeUntrustedOutput, renderUntrustedOutputWarning } from "../../lib/untrusted-output.mjs";
|
|
13
|
+
import { mcpExecutionPolicy } from "../../lib/mcp-tool-policy.mjs";
|
|
9
14
|
import { crossToolTempPathRisk, isLocalEnvPath, localEnvWriteRisk } from "../../lib/execution-contract.mjs";
|
|
10
15
|
import {
|
|
11
16
|
canonicalVerificationCommand,
|
|
@@ -18,6 +23,7 @@ import {
|
|
|
18
23
|
probeCodeIntelligence,
|
|
19
24
|
readAnchoredCode,
|
|
20
25
|
searchCodeIntelligence,
|
|
26
|
+
shutdownLspPool,
|
|
21
27
|
} from "../../lib/code-intelligence/index.mjs";
|
|
22
28
|
import { ingestDocument } from "../../lib/document-ingestion.mjs";
|
|
23
29
|
import { compactContext, expandContext, searchContext } from "../../lib/reversible-context.mjs";
|
|
@@ -32,6 +38,16 @@ import {
|
|
|
32
38
|
waitForService,
|
|
33
39
|
} from "../../lib/service-manager.mjs";
|
|
34
40
|
|
|
41
|
+
const PERMISSION_POLICY = new PermissionPolicyStore(
|
|
42
|
+
path.join(getUesConfigDir(), ".ues", "permissions.json"),
|
|
43
|
+
);
|
|
44
|
+
const EXTERNAL_TOOL_NAMES = new Set(
|
|
45
|
+
String(process.env.UES_CHILD_EXTERNAL_TOOL_NAMES || "")
|
|
46
|
+
.split(",")
|
|
47
|
+
.map((value) => value.trim())
|
|
48
|
+
.filter(Boolean),
|
|
49
|
+
);
|
|
50
|
+
|
|
35
51
|
const toolExecutionState = new Map<string, {
|
|
36
52
|
startedAt: number;
|
|
37
53
|
workspaceBefore?: string;
|
|
@@ -102,12 +118,45 @@ export default function (pi: ExtensionAPI) {
|
|
|
102
118
|
pi.on("session_start", clearExecutionState);
|
|
103
119
|
pi.on("session_shutdown", async (_event, ctx) => {
|
|
104
120
|
clearExecutionState();
|
|
105
|
-
await
|
|
121
|
+
await Promise.all([
|
|
122
|
+
stopAllServices(ctx.cwd).catch(() => []),
|
|
123
|
+
shutdownLspPool(ctx.cwd).catch(() => ({ stopped: 0, remaining: 0 })),
|
|
124
|
+
]);
|
|
106
125
|
});
|
|
107
126
|
|
|
108
127
|
pi.on("tool_call", async (event, ctx) => {
|
|
109
128
|
const toolName = String(event.toolName || "");
|
|
110
129
|
const input: any = event.input || {};
|
|
130
|
+
const permissionRequest = toolPermissionRequest(toolName, input);
|
|
131
|
+
const configuredPermission: any = await PERMISSION_POLICY.evaluate(
|
|
132
|
+
permissionRequest,
|
|
133
|
+
{ agent: String(process.env.UES_CHILD_AGENT || "ues-child") },
|
|
134
|
+
).catch((error) => ({
|
|
135
|
+
configured: true,
|
|
136
|
+
decision: null,
|
|
137
|
+
error: error instanceof Error ? error.message : String(error),
|
|
138
|
+
}));
|
|
139
|
+
if (configuredPermission.error) {
|
|
140
|
+
toolExecutionState.delete(String(event.toolCallId || ""));
|
|
141
|
+
return {
|
|
142
|
+
block: true,
|
|
143
|
+
reason: "UES permission policy is invalid: " + configuredPermission.error,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
if (configuredPermission?.decision?.effect === "deny") {
|
|
147
|
+
toolExecutionState.delete(String(event.toolCallId || ""));
|
|
148
|
+
return {
|
|
149
|
+
block: true,
|
|
150
|
+
reason: permissionRecoveryHint(permissionRequest, configuredPermission.decision, { effect: "deny" }),
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
if (configuredPermission?.decision?.effect === "ask") {
|
|
154
|
+
toolExecutionState.delete(String(event.toolCallId || ""));
|
|
155
|
+
return {
|
|
156
|
+
block: true,
|
|
157
|
+
reason: permissionRecoveryHint(permissionRequest, configuredPermission.decision, { effect: "ask" }),
|
|
158
|
+
};
|
|
159
|
+
}
|
|
111
160
|
const localEnvAllowed = String(process.env.UES_CHILD_ALLOW_LOCAL_ENV_WRITE || "") === "1";
|
|
112
161
|
const writeTool = ["edit", "write", "write_file", "apply_patch", "ues_code_edit"].includes(toolName);
|
|
113
162
|
const fileTool = ["read", "edit", "write", "write_file", "apply_patch", "ues_code", "ues_code_edit"].includes(toolName);
|
|
@@ -186,11 +235,37 @@ export default function (pi: ExtensionAPI) {
|
|
|
186
235
|
|
|
187
236
|
pi.on("tool_result", async (event, ctx) => {
|
|
188
237
|
const toolName = String(event.toolName || "");
|
|
238
|
+
const shownText = visibleText(event);
|
|
239
|
+
const allTools = typeof (pi as any).getAllTools === "function" ? (pi as any).getAllTools() : [];
|
|
240
|
+
const descriptor = allTools.find((tool: any) => String(tool?.name || "") === toolName);
|
|
241
|
+
const externalPolicy = mcpExecutionPolicy(descriptor || { name: toolName });
|
|
242
|
+
const externalBoundary =
|
|
243
|
+
EXTERNAL_TOOL_NAMES.has(toolName) ||
|
|
244
|
+
externalPolicy.externalEvidenceBoundary === true;
|
|
245
|
+
if (externalBoundary && shownText) {
|
|
246
|
+
const analysis = analyzeUntrustedOutput(shownText, { source: toolName });
|
|
247
|
+
if (analysis.flagged) {
|
|
248
|
+
const originalContent = Array.isArray(event.content)
|
|
249
|
+
? event.content
|
|
250
|
+
: [{ type: "text", text: shownText }];
|
|
251
|
+
return {
|
|
252
|
+
content: [
|
|
253
|
+
{ type: "text", text: renderUntrustedOutputWarning(analysis, { source: toolName }) },
|
|
254
|
+
...originalContent,
|
|
255
|
+
],
|
|
256
|
+
details: {
|
|
257
|
+
...(event.details && typeof event.details === "object" ? event.details : {}),
|
|
258
|
+
uesUntrustedOutputBoundary: analysis,
|
|
259
|
+
},
|
|
260
|
+
isError: event.isError,
|
|
261
|
+
usage: event.usage,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
189
266
|
if (!["bash", "powershell", "grep", "find", "ls"].includes(toolName)) {
|
|
190
267
|
return undefined;
|
|
191
268
|
}
|
|
192
|
-
|
|
193
|
-
const shownText = visibleText(event);
|
|
194
269
|
const capture = await capturedText(event, shownText);
|
|
195
270
|
const rawText = capture.text;
|
|
196
271
|
const images = (event.content || []).filter((part: any) => part?.type !== "text");
|
|
@@ -375,9 +450,45 @@ export default function (pi: ExtensionAPI) {
|
|
|
375
450
|
throw new Error("unsupported ues_code action");
|
|
376
451
|
}
|
|
377
452
|
const encoded = JSON.stringify(result, null, 2);
|
|
453
|
+
const bounded = encoded.length > 32000;
|
|
454
|
+
let contextRef: string | null = null;
|
|
455
|
+
let visible = encoded;
|
|
456
|
+
if (bounded) {
|
|
457
|
+
const preserved = await compactContext(ctx.cwd, encoded, {
|
|
458
|
+
kind: "ues-code-result",
|
|
459
|
+
source: `ues_code:${params.action}`,
|
|
460
|
+
summary: `Full child code-intelligence result for ${params.action}; preserve exact JSON before model-visible bounding`,
|
|
461
|
+
}).catch(() => null);
|
|
462
|
+
contextRef = preserved?.ref || null;
|
|
463
|
+
const metadataFirst = {
|
|
464
|
+
schemaVersion: result?.schemaVersion || 1,
|
|
465
|
+
action: params.action,
|
|
466
|
+
file: result?.file || null,
|
|
467
|
+
available: result?.available ?? null,
|
|
468
|
+
provider: result?.provider || null,
|
|
469
|
+
operation: result?.operation || null,
|
|
470
|
+
reason: result?.reason || null,
|
|
471
|
+
persistent: result?.persistent ?? null,
|
|
472
|
+
pool: result?.pool || result?.lsp?.persistentPool || null,
|
|
473
|
+
bounded: true,
|
|
474
|
+
originalChars: encoded.length,
|
|
475
|
+
contextRef,
|
|
476
|
+
preview: encoded.slice(0, 22000),
|
|
477
|
+
};
|
|
478
|
+
visible = JSON.stringify(metadataFirst, null, 2) +
|
|
479
|
+
"\n...[full result preserved; use ues_code context-expand with contextRef when more evidence is needed]";
|
|
480
|
+
}
|
|
378
481
|
return {
|
|
379
|
-
content: [{ type: "text", text:
|
|
380
|
-
details: {
|
|
482
|
+
content: [{ type: "text", text: visible }],
|
|
483
|
+
details: {
|
|
484
|
+
action: params.action,
|
|
485
|
+
bounded,
|
|
486
|
+
originalChars: encoded.length,
|
|
487
|
+
contextRef,
|
|
488
|
+
provider: result?.provider || null,
|
|
489
|
+
persistent: result?.persistent ?? null,
|
|
490
|
+
pool: result?.pool || result?.lsp?.persistentPool || null,
|
|
491
|
+
},
|
|
381
492
|
};
|
|
382
493
|
} catch (error) {
|
|
383
494
|
return {
|