@kodax-ai/kodax 0.7.95 → 0.7.96-alpha.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/CHANGELOG.md +178 -1
- package/LICENSE +158 -158
- package/README.md +149 -24
- package/README_CN.md +117 -24
- package/config-templates/config.example.jsonc +2 -1
- package/config-templates/integrations/a2a.example.jsonc +91 -91
- package/config-templates/integrations/extensions.example.jsonc +7 -7
- package/config-templates/integrations/mcp.example.jsonc +16 -16
- package/dist/builtin/code-review/SKILL.md +82 -82
- package/dist/builtin/git-workflow/SKILL.md +84 -84
- package/dist/builtin/skill-creator/SKILL.md +127 -127
- package/dist/builtin/skill-creator/agents/analyzer.md +12 -12
- package/dist/builtin/skill-creator/agents/comparator.md +13 -13
- package/dist/builtin/skill-creator/agents/grader.md +13 -13
- package/dist/builtin/skill-creator/references/schemas.md +227 -227
- package/dist/builtin/skill-creator/scripts/aggregate-benchmark.d.ts +46 -46
- package/dist/builtin/skill-creator/scripts/aggregate-benchmark.js +208 -208
- package/dist/builtin/skill-creator/scripts/analyze-benchmark.d.ts +46 -46
- package/dist/builtin/skill-creator/scripts/analyze-benchmark.js +286 -286
- package/dist/builtin/skill-creator/scripts/compare-runs.d.ts +62 -62
- package/dist/builtin/skill-creator/scripts/compare-runs.js +330 -330
- package/dist/builtin/skill-creator/scripts/generate-review.d.ts +33 -33
- package/dist/builtin/skill-creator/scripts/generate-review.js +414 -414
- package/dist/builtin/skill-creator/scripts/grade-evals.d.ts +73 -73
- package/dist/builtin/skill-creator/scripts/grade-evals.js +402 -402
- package/dist/builtin/skill-creator/scripts/improve-description.d.ts +23 -23
- package/dist/builtin/skill-creator/scripts/improve-description.js +160 -160
- package/dist/builtin/skill-creator/scripts/init-skill.d.ts +14 -14
- package/dist/builtin/skill-creator/scripts/init-skill.js +155 -155
- package/dist/builtin/skill-creator/scripts/install-skill.d.ts +29 -29
- package/dist/builtin/skill-creator/scripts/install-skill.js +173 -173
- package/dist/builtin/skill-creator/scripts/package-skill.d.ts +38 -38
- package/dist/builtin/skill-creator/scripts/package-skill.js +121 -121
- package/dist/builtin/skill-creator/scripts/quick-validate.d.ts +8 -8
- package/dist/builtin/skill-creator/scripts/quick-validate.js +163 -163
- package/dist/builtin/skill-creator/scripts/run-eval.d.ts +66 -66
- package/dist/builtin/skill-creator/scripts/run-eval.js +353 -353
- package/dist/builtin/skill-creator/scripts/run-loop.d.ts +49 -49
- package/dist/builtin/skill-creator/scripts/run-loop.js +242 -242
- package/dist/builtin/skill-creator/scripts/run-trigger-eval.d.ts +58 -58
- package/dist/builtin/skill-creator/scripts/run-trigger-eval.js +224 -224
- package/dist/builtin/tdd/SKILL.md +56 -56
- package/dist/chunks/agent-4FABF6WK.js +2 -0
- package/dist/chunks/argument-completer-72VHB2VL.js +2 -0
- package/dist/chunks/{chunk-7JXA3533.js → chunk-4OIQZWA5.js} +223 -226
- package/dist/chunks/{chunk-BNVSKIAB.js → chunk-6BVF3HZ7.js} +136 -136
- package/dist/chunks/chunk-7JZZIFZH.js +501 -0
- package/dist/chunks/chunk-AC7Z2OIY.js +2 -0
- package/dist/chunks/{chunk-JS452J2F.js → chunk-C4KYZAFU.js} +2 -2
- package/dist/chunks/chunk-CHUPIWIF.js +251 -0
- package/dist/chunks/{chunk-C4DTUKTR.js → chunk-GYUU7XLH.js} +5 -4
- package/dist/chunks/{chunk-OK4AXDC5.js → chunk-HAX55GOQ.js} +1 -1
- package/dist/chunks/chunk-JKTJCGO2.js +418 -0
- package/dist/chunks/{chunk-O743AJ5V.js → chunk-LQYETRFK.js} +171 -175
- package/dist/chunks/{chunk-2PEDBGKN.js → chunk-LTUZTQ6W.js} +1 -1
- package/dist/chunks/chunk-LYWDUSKO.js +2 -0
- package/dist/chunks/chunk-NGH6T4FD.js +92 -0
- package/dist/chunks/{chunk-SRIJX5ZP.js → chunk-NVRWCSA5.js} +1 -1
- package/dist/chunks/chunk-O4DS7RIQ.js +384 -0
- package/dist/chunks/chunk-ORXU6OWZ.js +2 -0
- package/dist/chunks/chunk-POTW3O65.js +124 -0
- package/dist/chunks/{chunk-2TM3W3GK.js → chunk-RIQSS56Y.js} +1 -1
- package/dist/chunks/chunk-U27XKEN5.js +407 -0
- package/dist/chunks/{chunk-6ABQJUK6.js → chunk-XUX6OUCA.js} +2 -2
- package/dist/chunks/{client-JDOS3YJR.js → client-4C456K4O.js} +1 -1
- package/dist/chunks/compaction-config-3VQRDFF4.js +2 -0
- package/dist/chunks/{construction-bootstrap-YCWHHUYO.js → construction-bootstrap-AHN7EDGG.js} +1 -1
- package/dist/chunks/dist-BCBQXAGI.js +2 -0
- package/dist/chunks/dist-QK2YDWU6.js +2 -0
- package/dist/chunks/host-VIHV7ADG.js +2 -0
- package/dist/chunks/run-manager-NBVMU3KV.js +2 -0
- package/dist/chunks/utils-MEJZ2IGI.js +2 -0
- package/dist/index.d.ts +22 -21
- package/dist/index.js +7 -7
- package/dist/kodax_bootstrap.js +26 -26
- package/dist/kodax_cli.js +1905 -1882
- package/dist/native/darwin-arm64/LICENSE-APACHE.txt +13 -0
- package/dist/native/darwin-arm64/kodax-text-transaction.node +0 -0
- package/dist/native/darwin-arm64/manifest.json +16 -0
- package/dist/native/darwin-x64/LICENSE-APACHE.txt +13 -0
- package/dist/native/darwin-x64/kodax-text-transaction.node +0 -0
- package/dist/native/darwin-x64/manifest.json +16 -0
- package/dist/native/linux-arm64/LICENSE-APACHE.txt +13 -0
- package/dist/native/linux-arm64/kodax-text-transaction.node +0 -0
- package/dist/native/linux-arm64/manifest.json +16 -0
- package/dist/native/linux-x64/LICENSE-APACHE.txt +13 -0
- package/dist/native/linux-x64/kodax-text-transaction.node +0 -0
- package/dist/native/linux-x64/manifest.json +16 -0
- package/dist/native/win32-x64/LICENSE-APACHE.txt +13 -0
- package/dist/native/win32-x64/NOTICE-windows-sandbox.txt +8 -0
- package/dist/native/win32-x64/kodax-windows-sandbox.exe +0 -0
- package/dist/native/win32-x64/kodax-windows-text-transaction.node +0 -0
- package/dist/native/win32-x64/manifest.json +30 -0
- package/dist/provider-capabilities.json +108 -2
- package/dist/runtime-worker.js +1745 -1727
- package/dist/sandbox-network-broker.js +1715 -0
- package/dist/sdk-a2a.d.ts +13 -12
- package/dist/sdk-a2a.js +1 -1
- package/dist/sdk-agent.d.ts +27 -18
- package/dist/sdk-agent.js +1 -1
- package/dist/sdk-coding.d.ts +107 -58
- package/dist/sdk-coding.js +1 -1
- package/dist/sdk-experimental-memory.d.ts +4 -4
- package/dist/sdk-experimental-memory.js +1 -1
- package/dist/sdk-llm.d.ts +9 -10
- package/dist/sdk-llm.js +1 -1
- package/dist/sdk-mcp.js +1 -1
- package/dist/sdk-media.d.ts +1 -1
- package/dist/sdk-media.js +1 -1
- package/dist/sdk-repl.d.ts +25 -17
- package/dist/sdk-repl.js +1 -1
- package/dist/sdk-runtime.d.ts +41 -17
- package/dist/sdk-runtime.js +1 -1
- package/dist/sdk-sandbox.d.ts +17 -3
- package/dist/sdk-sandbox.js +1 -1
- package/dist/sdk-session.d.ts +8 -7
- package/dist/sdk-session.js +1 -1
- package/dist/sdk-skills.js +1 -1
- package/dist/semantic-worker.js +61 -61
- package/dist/types-chunks/{base.d-vopO1rml.d.ts → base.d-COo8E2dk.d.ts} +18 -27
- package/dist/types-chunks/{bash-prefix-extractor.d-B2rxNI4L.d.ts → bash-prefix-extractor.d-DQOlA8cy.d.ts} +72 -52
- package/dist/types-chunks/{capability-learning.d-CE1tm29C.d.ts → capability-learning.d-lRPgA3Or.d.ts} +1 -1
- package/dist/types-chunks/{capsule.d-Y7QRS4J2.d.ts → capsule.d-0zxsgXg_.d.ts} +3 -3
- package/dist/types-chunks/{controller.d-BR-UVeUR.d.ts → controller.d-BTtyIIC1.d.ts} +1 -1
- package/dist/types-chunks/{controller.d-C5noq5-w.d.ts → controller.d-C7tXUcXo.d.ts} +2 -2
- package/dist/types-chunks/{guardrail.d-DqHD-61O.d.ts → guardrail.d-DKTyEHJa.d.ts} +5 -5
- package/dist/types-chunks/{history-retrieval.d-CKU8zmt_.d.ts → history-retrieval.d-CHnL99S7.d.ts} +2 -2
- package/dist/types-chunks/{public-api.d-D7fXaWW8.d.ts → public-api.d-Dx3L3W4Z.d.ts} +7 -4
- package/dist/types-chunks/{repl.d-BYDb14s6.d.ts → repl.d-mO01olIa.d.ts} +5 -5
- package/dist/types-chunks/{resolver.d-CwHUwbdE.d.ts → resolver.d-DlXPjeyx.d.ts} +38 -6
- package/dist/types-chunks/{review-inbox.d-BSgFewyj.d.ts → review-inbox.d-WDSe1nze.d.ts} +1 -1
- package/dist/types-chunks/{run-manager.d-BVJSntpS.d.ts → run-manager.d-DENbbzgR.d.ts} +1 -1
- package/dist/types-chunks/{sdk-session-CqEG84oP.d.ts → sdk-session-DYHGXXH4.d.ts} +3 -3
- package/dist/types-chunks/{shell-command-sets.d-DqaaBwhU.d.ts → shell-command-sets.d-CjFqS4dp.d.ts} +1 -1
- package/dist/types-chunks/{side-query.d-iH0P9ASy.d.ts → side-query.d-j8A3sFv_.d.ts} +2 -2
- package/dist/types-chunks/{types.d-rUOjXych.d.ts → types.d-BbZjR0Wr.d.ts} +1 -1
- package/dist/types-chunks/{types.d-CaTXAW_Q.d.ts → types.d-BkTIKdH6.d.ts} +2 -2
- package/dist/types-chunks/{types.d-C5xQEFcj.d.ts → types.d-DncLrpu_.d.ts} +4 -4
- package/dist/types-chunks/{types.d-CK9A9rpP.d.ts → types.d-Xy0f3x4i.d.ts} +9 -0
- package/dist/types-chunks/{utils.d-CWUyLiXo.d.ts → utils.d-CnxefMos.d.ts} +6 -6
- package/package.json +10 -3
- package/public_docs/README.md +130 -0
- package/public_docs/configuration/sandbox.md +289 -0
- package/public_docs/sdk/embedder-guide.md +6674 -0
- package/scripts/kodax-bin.cjs +28 -28
- package/scripts/production-env.cjs +25 -25
- package/dist/chunks/agent-XXZMXKKA.js +0 -2
- package/dist/chunks/argument-completer-KCYDGTQW.js +0 -2
- package/dist/chunks/chunk-77PNP27P.js +0 -92
- package/dist/chunks/chunk-7QBWHCIZ.js +0 -2
- package/dist/chunks/chunk-BHE66SP3.js +0 -123
- package/dist/chunks/chunk-BR2OSB2I.js +0 -722
- package/dist/chunks/chunk-DSMONSVB.js +0 -407
- package/dist/chunks/chunk-Q5VRWSKG.js +0 -418
- package/dist/chunks/chunk-XWRPOGJN.js +0 -4
- package/dist/chunks/chunk-Y5VIQBT6.js +0 -383
- package/dist/chunks/compaction-config-EGS4577X.js +0 -2
- package/dist/chunks/dist-ITTXQHRJ.js +0 -2
- package/dist/chunks/dist-KFYN3OKD.js +0 -2
- package/dist/chunks/host-VAYADIPW.js +0 -2
- package/dist/chunks/run-manager-52IJZMZJ.js +0 -2
- package/dist/chunks/utils-P7PBSL3R.js +0 -2
- package/dist/sandbox-workspace-session.js +0 -1705
|
@@ -0,0 +1,1715 @@
|
|
|
1
|
+
// @kodax-ai/kodax — bundled distribution. See docs/ADR.md ADR-022 + ADR-024.
|
|
2
|
+
var Zr=Object.defineProperty;var o=(e,t)=>Zr(e,"name",{value:t,configurable:!0});import{spawn as Zl,spawnSync as h$}from"node:child_process";import{createHash as qr,randomUUID as eu}from"node:crypto";import{closeSync as w$,constants as v$,existsSync as b$,fsyncSync as S$,lstatSync as k$,mkdirSync as x$,openSync as E$,readFileSync as R$,readSync as I$,readdirSync as A$,realpathSync as C$,renameSync as T$,rmSync as _$,statSync as P$,writeSync as tu}from"node:fs";import{copyFile as $$,lstat as N$,mkdir as D$,readFile as Rt,realpath as L$,rm as Hr,rmdir as j$,stat as F$,writeFile as K$}from"node:fs/promises";import{createRequire as nu}from"node:module";import b from"node:path";import{fileURLToPath as X$,pathToFileURL as ru}from"node:url";import{AsyncLocalStorage as eo}from"node:async_hooks";var to=new eo;function me(e){let t=to.getStore()?.credential;return t?te(e,t,new WeakMap):e}o(me,"redactScopedProviderCredential");function te(e,t,n){if(typeof e=="string")return e.split(t).join("[REDACTED_CREDENTIAL]");if(e===null||typeof e!="object")return e;let r=n.get(e);if(r!==void 0)return r;if(e instanceof Error){let s=new Error(te(e.message,t,n));return n.set(e,s),s.name=e.name,e.stack!==void 0&&(s.stack=te(e.stack,t,n)),s}if(Array.isArray(e)){let s=[];n.set(e,s);for(let a of e)s.push(te(a,t,n));return s}let i={};n.set(e,i);for(let[s,a]of Object.entries(Object.getOwnPropertyDescriptors(e))){if(!a.enumerable||!("value"in a))continue;let c=s.split(t).join("[REDACTED_CREDENTIAL]");i[c]=te(a.value,t,n)}return i}o(te,"redactCredentialValue");import{AsyncLocalStorage as no}from"node:async_hooks";var Bu=new no;var X={transport:"native-api",conversationSemantics:"full-history",mcpSupport:"none",contextFidelity:"full",toolCallingFidelity:"full",sessionSupport:"full",longRunningSupport:"full",multimodalSupport:"none",evidenceSupport:"full"},At={...X,multimodalSupport:"image-input"},he={transport:"cli-bridge",conversationSemantics:"last-user-message",mcpSupport:"none",contextFidelity:"lossy",toolCallingFidelity:"limited",sessionSupport:"stateless",longRunningSupport:"limited",multimodalSupport:"none",evidenceSupport:"limited"},Ct={...he,multimodalSupport:"image-input"};import{parse as sf}from"partial-json";var Xf=Object.freeze({status:"terminated"}),qf=Object.freeze({status:"already-exited"}),Hf=Object.freeze({status:"unknown"}),zf=String.raw`
|
|
3
|
+
using System;
|
|
4
|
+
using System.Runtime.InteropServices;
|
|
5
|
+
using System.Text;
|
|
6
|
+
public static class KodaXNativeProcessSnapshot {
|
|
7
|
+
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
|
8
|
+
private struct ProcessEntry32 {
|
|
9
|
+
public uint dwSize;
|
|
10
|
+
public uint cntUsage;
|
|
11
|
+
public uint th32ProcessID;
|
|
12
|
+
public IntPtr th32DefaultHeapID;
|
|
13
|
+
public uint th32ModuleID;
|
|
14
|
+
public uint cntThreads;
|
|
15
|
+
public uint th32ParentProcessID;
|
|
16
|
+
public int pcPriClassBase;
|
|
17
|
+
public uint dwFlags;
|
|
18
|
+
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
|
|
19
|
+
public string szExeFile;
|
|
20
|
+
}
|
|
21
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
22
|
+
private static extern IntPtr CreateToolhelp32Snapshot(uint flags, uint processId);
|
|
23
|
+
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
|
24
|
+
private static extern bool Process32First(IntPtr snapshot, ref ProcessEntry32 entry);
|
|
25
|
+
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
|
26
|
+
private static extern bool Process32Next(IntPtr snapshot, ref ProcessEntry32 entry);
|
|
27
|
+
[StructLayout(LayoutKind.Sequential)]
|
|
28
|
+
private struct FileTime {
|
|
29
|
+
public uint Low;
|
|
30
|
+
public uint High;
|
|
31
|
+
}
|
|
32
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
33
|
+
private static extern IntPtr OpenProcess(uint access, bool inheritHandle, uint processId);
|
|
34
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
35
|
+
private static extern bool GetProcessTimes(IntPtr process, out FileTime creation, out FileTime exit, out FileTime kernel, out FileTime user);
|
|
36
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
37
|
+
private static extern bool TerminateProcess(IntPtr process, uint exitCode);
|
|
38
|
+
[DllImport("kernel32.dll")]
|
|
39
|
+
private static extern void GetSystemTimeAsFileTime(out FileTime systemTime);
|
|
40
|
+
[DllImport("kernel32.dll")]
|
|
41
|
+
private static extern bool CloseHandle(IntPtr handle);
|
|
42
|
+
private static ulong ReadCreationTime(uint processId) {
|
|
43
|
+
var process = OpenProcess(0x1000, false, processId);
|
|
44
|
+
if (process == IntPtr.Zero) return 0;
|
|
45
|
+
try {
|
|
46
|
+
FileTime creation, exit, kernel, user;
|
|
47
|
+
if (!GetProcessTimes(process, out creation, out exit, out kernel, out user)) return 0;
|
|
48
|
+
return ((ulong)creation.High << 32) | creation.Low;
|
|
49
|
+
} finally {
|
|
50
|
+
CloseHandle(process);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
public static int TerminateExact(uint processId, ulong expectedCreationTime) {
|
|
54
|
+
var process = OpenProcess(0x1001, false, processId);
|
|
55
|
+
if (process == IntPtr.Zero) return 0;
|
|
56
|
+
try {
|
|
57
|
+
FileTime creation, exit, kernel, user;
|
|
58
|
+
if (!GetProcessTimes(process, out creation, out exit, out kernel, out user)) return 0;
|
|
59
|
+
var actual = (((ulong)creation.High << 32) | creation.Low) / 10000;
|
|
60
|
+
if (actual != expectedCreationTime) return 2;
|
|
61
|
+
return TerminateProcess(process, 1) ? 1 : 0;
|
|
62
|
+
} finally {
|
|
63
|
+
CloseHandle(process);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
public static string ReadRows() {
|
|
67
|
+
FileTime cutoffTime;
|
|
68
|
+
GetSystemTimeAsFileTime(out cutoffTime);
|
|
69
|
+
var cutoff = (((ulong)cutoffTime.High << 32) | cutoffTime.Low) / 10000;
|
|
70
|
+
var snapshot = CreateToolhelp32Snapshot(2, 0);
|
|
71
|
+
if (snapshot == new IntPtr(-1)) return string.Empty;
|
|
72
|
+
var rows = new StringBuilder();
|
|
73
|
+
var entry = new ProcessEntry32();
|
|
74
|
+
entry.dwSize = (uint)Marshal.SizeOf(entry);
|
|
75
|
+
try {
|
|
76
|
+
if (!Process32First(snapshot, ref entry)) return string.Empty;
|
|
77
|
+
do {
|
|
78
|
+
var creationTime = ReadCreationTime(entry.th32ProcessID) / 10000;
|
|
79
|
+
if (creationTime == 0 || creationTime <= cutoff) {
|
|
80
|
+
rows.Append(entry.th32ProcessID).Append(',').Append(entry.th32ParentProcessID).Append(',').Append(creationTime).Append('\n');
|
|
81
|
+
}
|
|
82
|
+
entry.dwSize = (uint)Marshal.SizeOf(entry);
|
|
83
|
+
} while (Process32Next(snapshot, ref entry));
|
|
84
|
+
return rows.ToString();
|
|
85
|
+
} finally {
|
|
86
|
+
CloseHandle(snapshot);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}`;import Nt from"node:fs";import Dt from"node:os";import Lt from"node:path";var Ao="gpt-5.4",Co="auto-gemini-3",To=["gpt-5.4","gpt-5.3-codex","gpt-5.3-codex-spark"],_o=["auto-gemini-3","gemini-3.1-pro-preview","gemini-3-flash-preview","gemini-2.5-pro","gemini-2.5-flash"];function jt(e){let t=new Set,n=[];for(let r of e){let i=r.trim();if(!i)continue;let s=i.toLowerCase();t.has(s)||(t.add(s),n.push(i))}return n}o(jt,"dedupePreserveOrder");function Po(){let e=Lt.join(Dt.homedir(),".codex","config.toml");try{return Nt.readFileSync(e,"utf8").match(/^\s*model\s*=\s*"([^"]+)"/m)?.[1]?.trim()||null}catch{return null}}o(Po,"readCodexConfiguredModel");function Mo(){let e=Lt.join(Dt.homedir(),".gemini","settings.json");try{let t=JSON.parse(Nt.readFileSync(e,"utf8")),n=typeof t.model=="string"?t.model.trim():"";return n||(typeof t.general?.model=="string"?t.general.model.trim():"")||null}catch{return null}}o(Mo,"readGeminiConfiguredModel");function q(){return Po()||Ao}o(q,"getCodexCliDefaultModel");function H(){return Mo()||Co}o(H,"getGeminiCliDefaultModel");function re(){return jt([q(),...To])}o(re,"getCodexCliKnownModels");function oe(){return jt([H(),..._o])}o(oe,"getGeminiCliKnownModels");var Tp=H(),_p=oe();var Bp=q(),Up=re();import{existsSync as Uo,readFileSync as Xo}from"node:fs";import G from"node:path";import{fileURLToPath as qo}from"node:url";var Ft=["none","prompt-only","native-effort","native-budget","native-toggle","native-adaptive","unknown"],Kt=["openai-responses-effort","openai-chat-effort","codex-cli-config","anthropic-output-effort","anthropic-reasoning-effort","provider-budget","provider-toggle","prompt-only","none"],Wt=["anthropic-adaptive","anthropic-budget","provider-budget","provider-toggle","none"],Bt=["zai-glm-5.3","zai-glm-5.2","zai-glm-toggle","deepseek-v4-flash-openai","deepseek-v4-pro-openai","deepseek-v4-openai","deepseek-v4-anthropic","deepseek-toggle","kimi-k3","kimi-k2.7-code","kimi-hybrid-toggle","minimax-m3","minimax-m2-always","mimo-v2.5-toggle","qwen-hybrid-thinking","openai-chat-reasoning","openai-responses-reasoning","codex-cli-effort","claude-adaptive-xhigh","claude-adaptive-max","anthropic-budget","generic-thinking-toggle","none"],Ut=["max_tokens","max_completion_tokens"],Xt=["native","image-input-native","cli-bridge","image-input-cli-bridge"],qt=["count-tokens","models-list","minimal-message","unsupported"];function O(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}o(O,"isPlainObject");function K(e,t){if(typeof e!="string"||e.length===0)throw new Error(`provider-capabilities.json: ${t} must be a non-empty string`);return e}o(K,"requireString");function z(e,t){if(e!==void 0)return K(e,t)}o(z,"optionalString");function Gt(e,t){if(e!==void 0){if(typeof e!="string"||!Ut.includes(e))throw new Error(`provider-capabilities.json: ${t} must be one of ${Ut.join(", ")}, got ${JSON.stringify(e)}`);return e}}o(Gt,"optionalMaxOutputTokensField");function L(e,t){if(e!==void 0){if(typeof e!="number"||!Number.isFinite(e)||e<0)throw new Error(`provider-capabilities.json: ${t} must be a non-negative finite number`);return e}}o(L,"optionalNumber");function R(e,t){if(e!==void 0){if(typeof e!="boolean")throw new Error(`provider-capabilities.json: ${t} must be a boolean`);return e}}o(R,"optionalBoolean");function Ht(e,t){if(e!==void 0){if(!Array.isArray(e))throw new Error(`provider-capabilities.json: ${t} must be an array`);return e.map((n,r)=>K(n,`${t}[${r}]`))}}o(Ht,"optionalStringArray");function $o(e,t){if(e===void 0)return;if(!O(e))throw new Error(`provider-capabilities.json: ${t} must be an object`);let n={};for(let[r,i]of Object.entries(e))n[r]=K(i,`${t}.${r}`);return n}o($o,"optionalStringMap");function No(e,t){if(e!==void 0){if(typeof e!="string"||!Bt.includes(e))throw new Error(`provider-capabilities.json: ${t} must be one of ${Bt.join(", ")}, got ${JSON.stringify(e)}`);return e}}o(No,"optionalReasoningPreset");function je(e,t){if(typeof e!="string"||!Ft.includes(e))throw new Error(`provider-capabilities.json: ${t} must be one of ${Ft.join(", ")}, got ${JSON.stringify(e)}`);return e}o(je,"requireReasoningCapability");function Do(e,t){if(typeof e!="string"||!Kt.includes(e))throw new Error(`provider-capabilities.json: ${t} must be one of ${Kt.join(", ")}, got ${JSON.stringify(e)}`);return e}o(Do,"requireEffortStrategy");function Lo(e,t){if(e!==void 0){if(typeof e!="string"||!Wt.includes(e))throw new Error(`provider-capabilities.json: ${t} must be one of ${Wt.join(", ")}, got ${JSON.stringify(e)}`);return e}}o(Lo,"optionalThinkingStrategy");function zt(e,t){if(e===void 0)return;if(!O(e))throw new Error(`provider-capabilities.json: ${t} must be an object`);let n=Do(e.effortStrategy,`${t}.effortStrategy`),r=No(e.reasoningPreset,`${t}.reasoningPreset`),i=Lo(e.thinkingStrategy,`${t}.thinkingStrategy`),s=z(e.defaultEffort,`${t}.defaultEffort`),a=$o(e.effortAliases,`${t}.effortAliases`),c=Ht(e.disabledEfforts,`${t}.disabledEfforts`),d=Ht(e.localRejectEfforts,`${t}.localRejectEfforts`),l=R(e.allowCustomEffort,`${t}.allowCustomEffort`),u=R(e.supportsReasoningEffort,`${t}.supportsReasoningEffort`),f=R(e.supportsReasoningSummary,`${t}.supportsReasoningSummary`),m=R(e.supportsEncryptedReasoningReplay,`${t}.supportsEncryptedReasoningReplay`),p=R(e.supportsAdaptiveThinking,`${t}.supportsAdaptiveThinking`),h=R(e.supportsManualThinkingBudget,`${t}.supportsManualThinkingBudget`),x=R(e.supportsDisabledThinking,`${t}.supportsDisabledThinking`),y=R(e.requiresEffortBetaHeader,`${t}.requiresEffortBetaHeader`),g={effortStrategy:n};if(r!==void 0&&(g.reasoningPreset=r),i!==void 0&&(g.thinkingStrategy=i),s!==void 0&&(g.defaultEffort=s),a!==void 0&&(g.effortAliases=a),c!==void 0&&(g.disabledEfforts=c),d!==void 0&&(g.localRejectEfforts=d),e.supportedEfforts!==void 0){if(!Array.isArray(e.supportedEfforts))throw new Error(`provider-capabilities.json: ${t}.supportedEfforts must be an array`);g.supportedEfforts=e.supportedEfforts.map((w,v)=>{if(!O(w))throw new Error(`provider-capabilities.json: ${t}.supportedEfforts[${v}] must be an object`);return{value:K(w.value,`${t}.supportedEfforts[${v}].value`),...z(w.description,`${t}.supportedEfforts[${v}].description`)!==void 0?{description:z(w.description,`${t}.supportedEfforts[${v}].description`)}:{},...R(w.isDefault,`${t}.supportedEfforts[${v}].isDefault`)!==void 0?{isDefault:R(w.isDefault,`${t}.supportedEfforts[${v}].isDefault`)}:{},...R(w.isUserVisible,`${t}.supportedEfforts[${v}].isUserVisible`)!==void 0?{isUserVisible:R(w.isUserVisible,`${t}.supportedEfforts[${v}].isUserVisible`)}:{}}})}if(e.budgetByEffort!==void 0){if(!O(e.budgetByEffort))throw new Error(`provider-capabilities.json: ${t}.budgetByEffort must be an object`);let w={};for(let[v,ee]of Object.entries(e.budgetByEffort))w[v]=L(ee,`${t}.budgetByEffort.${v}`)??0;g.budgetByEffort=w}return l!==void 0&&(g.allowCustomEffort=l),u!==void 0&&(g.supportsReasoningEffort=u),f!==void 0&&(g.supportsReasoningSummary=f),m!==void 0&&(g.supportsEncryptedReasoningReplay=m),p!==void 0&&(g.supportsAdaptiveThinking=p),h!==void 0&&(g.supportsManualThinkingBudget=h),x!==void 0&&(g.supportsDisabledThinking=x),y!==void 0&&(g.requiresEffortBetaHeader=y),g}o(zt,"validateReasoningProfile");function Vt(e,t){let n=e.reasoningProfile,r=e.reasoningCapabilityV2;if(n!==void 0&&r!==void 0)throw new Error(`provider-capabilities.json: ${t} must not define both reasoningProfile and deprecated reasoningCapabilityV2`);return n!==void 0?zt(n,`${t}.reasoningProfile`):zt(r,`${t}.reasoningCapabilityV2`)}o(Vt,"validateReasoningProfileField");function jo(e,t){if(typeof e!="string"||!Xt.includes(e))throw new Error(`provider-capabilities.json: ${t} must be one of ${Xt.join(", ")}, got ${JSON.stringify(e)}`);return e}o(jo,"requireProfileName");function Fo(e,t){if(typeof e!="string"||!qt.includes(e))throw new Error(`provider-capabilities.json: ${t} must be one of ${qt.join(", ")}, got ${JSON.stringify(e)}`);return e}o(Fo,"requireVerifyStrategy");function Ko(e,t){if(!O(e))throw new Error(`provider-capabilities.json: ${t} must be an object`);let n=K(e.id,`${t}.id`),r=z(e.wireModel,`${t}.wireModel`),i=z(e.displayName,`${t}.displayName`),s=L(e.contextWindow,`${t}.contextWindow`),a=L(e.maxOutputTokens,`${t}.maxOutputTokens`),c=Gt(e.maxOutputTokensField,`${t}.maxOutputTokensField`),d=L(e.thinkingBudgetCap,`${t}.thinkingBudgetCap`),l=R(e.replayReasoningContent,`${t}.replayReasoningContent`),u=R(e.strictThinkingSignature,`${t}.strictThinkingSignature`),f=L(e.streamMaxDurationMs,`${t}.streamMaxDurationMs`),m=e.reasoningCapability===void 0?void 0:je(e.reasoningCapability,`${t}.reasoningCapability`),p=Vt(e,t),h={id:n};return r!==void 0&&(h.wireModel=r),i!==void 0&&(h.displayName=i),s!==void 0&&(h.contextWindow=s),a!==void 0&&(h.maxOutputTokens=a),c!==void 0&&(h.maxOutputTokensField=c),d!==void 0&&(h.thinkingBudgetCap=d),m!==void 0&&(h.reasoningCapability=m),p!==void 0&&(h.reasoningProfile=p),l!==void 0&&(h.replayReasoningContent=l),u!==void 0&&(h.strictThinkingSignature=u),f!==void 0&&(h.streamMaxDurationMs=f),h}o(Ko,"validateModelDescriptor");function Wo(e,t){if(e===void 0)return;if(!O(e))throw new Error(`provider-capabilities.json: ${t} must be an object`);let n={};for(let[r,i]of Object.entries(e))n[r]=je(i,`${t}.${r}`);return n}o(Wo,"validateModelReasoningCapabilities");function Bo(e,t){if(!O(e))throw new Error(`provider-capabilities.json: providers.${t} must be an object`);let n=R(e.cliBridge,`providers.${t}.cliBridge`),r=K(e.apiKeyEnv,`providers.${t}.apiKeyEnv`),i=je(e.reasoningCapability,`providers.${t}.reasoningCapability`),s=Vt(e,`providers.${t}`),a=jo(e.capabilityProfile,`providers.${t}.capabilityProfile`),c=Fo(e.verifyStrategy,`providers.${t}.verifyStrategy`);if(n&&c!=="unsupported")throw new Error(`provider-capabilities.json: providers.${t} is a cliBridge entry but verifyStrategy="${c}" \u2014 must be "unsupported" (CLI binary owns credentials)`);let d=L(e.contextWindow,`providers.${t}.contextWindow`),l=L(e.maxOutputTokens,`providers.${t}.maxOutputTokens`),u=Gt(e.maxOutputTokensField,`providers.${t}.maxOutputTokensField`),f=L(e.thinkingBudgetCap,`providers.${t}.thinkingBudgetCap`),m=R(e.supportsThinking,`providers.${t}.supportsThinking`),p=Wo(e.modelReasoningCapabilities,`providers.${t}.modelReasoningCapabilities`),h=z(e.model,`providers.${t}.model`);if(n&&(h!==void 0||e.models!==void 0))throw new Error(`provider-capabilities.json: providers.${t} is a cliBridge entry but defines model/models \u2014 must be omitted (filled at load time)`);if(!n&&h===void 0)throw new Error(`provider-capabilities.json: providers.${t}.model is required (only cliBridge entries may omit)`);let x;if(e.models!==void 0){if(!Array.isArray(e.models))throw new Error(`provider-capabilities.json: providers.${t}.models must be an array`);x=e.models.map((w,v)=>Ko(w,`providers.${t}.models[${v}]`));let g=new Set([...h===void 0?[]:[h],...x.map(w=>w.id)]);for(let[w,v]of x.entries())if(v.wireModel!==void 0&&!g.has(v.wireModel))throw new Error(`provider-capabilities.json: providers.${t}.models[${w}].wireModel must reference a declared model, got ${JSON.stringify(v.wireModel)}`)}let y={apiKeyEnv:r,reasoningCapability:i,capabilityProfile:a,verifyStrategy:c};return s!==void 0&&(y.reasoningProfile=s),h!==void 0&&(y.model=h),x!==void 0&&(y.models=x),d!==void 0&&(y.contextWindow=d),l!==void 0&&(y.maxOutputTokens=l),u!==void 0&&(y.maxOutputTokensField=u),f!==void 0&&(y.thinkingBudgetCap=f),m!==void 0&&(y.supportsThinking=m),p!==void 0&&(y.modelReasoningCapabilities=p),n&&(y.cliBridge=!0),y}o(Bo,"validateProviderEntry");function Jt(e){if(!O(e))throw new Error("provider-capabilities.json: root must be an object");if(e.version!==1)throw new Error(`provider-capabilities.json: version must be 1, got ${JSON.stringify(e.version)}`);let t=K(e.updatedAt,"updatedAt");if(!O(e.providers))throw new Error("provider-capabilities.json: providers must be an object");let n={};for(let[r,i]of Object.entries(e.providers))n[r]=Bo(i,r);return{version:1,updatedAt:t,providers:n}}o(Jt,"validateProviderCapabilitiesJson");var Ho=Object.freeze({native:X,"image-input-native":At,"cli-bridge":he,"image-input-cli-bridge":Ct}),we=null;function zo(){if(process.env.KODAX_BUNDLED==="true")return G.join(G.dirname(process.execPath),"provider-capabilities.json");let e=G.dirname(qo(import.meta.url)),t=[G.join(e,"provider-capabilities.json"),G.join(G.dirname(e),"provider-capabilities.json")];for(let n of t)if(Uo(n))return n;return t[0]}o(zo,"resolveJsonPath");function Go(e){if(e.models){for(let t of e.models)t.reasoningProfile&&Yt(t.reasoningProfile);for(let t of e.models)Object.freeze(t);Object.freeze(e.models)}return e.reasoningProfile&&Yt(e.reasoningProfile),e.modelReasoningCapabilities&&Object.freeze(e.modelReasoningCapabilities),Object.freeze(e)}o(Go,"deepFreezeSnapshot");function Yt(e){if(e.supportedEfforts){for(let t of e.supportedEfforts)Object.freeze(t);Object.freeze(e.supportedEfforts)}e.budgetByEffort&&Object.freeze(e.budgetByEffort),e.effortAliases&&Object.freeze(e.effortAliases),e.disabledEfforts&&Object.freeze(e.disabledEfforts),e.localRejectEfforts&&Object.freeze(e.localRejectEfforts),Object.freeze(e)}o(Yt,"freezeReasoningProfile");function Vo(e){if(e==="gemini-cli"){let t=H();return{model:t,models:oe().filter(n=>n!==t).map(n=>({id:n}))}}if(e==="codex-cli"){let t=q();return{model:t,models:re().filter(n=>n!==t).map(n=>({id:n}))}}throw new Error(`provider-capabilities loader: unknown cliBridge provider '${e}'`)}o(Vo,"resolveCliBridgeModels");function Jo(e,t){let n=Ho[t.capabilityProfile];if(!n)throw new Error(`provider-capabilities loader: unknown capabilityProfile '${t.capabilityProfile}' for provider '${e}'`);if(t.cliBridge){let i=Vo(e),s={model:i.model,models:i.models,apiKeyEnv:t.apiKeyEnv,reasoningCapability:t.reasoningCapability,capabilityProfile:n,verifyStrategy:t.verifyStrategy};return t.reasoningProfile!==void 0&&(s.reasoningProfile=t.reasoningProfile),t.supportsThinking!==void 0&&(s.supportsThinking=t.supportsThinking),s}let r={model:t.model,apiKeyEnv:t.apiKeyEnv,reasoningCapability:t.reasoningCapability,capabilityProfile:n,verifyStrategy:t.verifyStrategy};return t.reasoningProfile!==void 0&&(r.reasoningProfile=t.reasoningProfile),t.models!==void 0&&(r.models=t.models),t.modelReasoningCapabilities!==void 0&&(r.modelReasoningCapabilities=t.modelReasoningCapabilities),t.contextWindow!==void 0&&(r.contextWindow=t.contextWindow),t.maxOutputTokens!==void 0&&(r.maxOutputTokens=t.maxOutputTokens),t.maxOutputTokensField!==void 0&&(r.maxOutputTokensField=t.maxOutputTokensField),t.thinkingBudgetCap!==void 0&&(r.thinkingBudgetCap=t.thinkingBudgetCap),t.supportsThinking!==void 0&&(r.supportsThinking=t.supportsThinking),r}o(Jo,"buildSnapshot");function Qt(){if(we)return we;let e=zo(),t;try{let i=Xo(e,"utf8");t=JSON.parse(i)}catch(i){let s=i instanceof Error?i.message:String(i);throw new Error(`provider-capabilities loader: failed to read ${e}: ${s}`)}let n=Jt(t),r={};for(let[i,s]of Object.entries(n.providers))r[i]=Go(Jo(i,s));return we=Object.freeze(r),we}o(Qt,"getProviderSnapshots");var ve=Qt();var Zt=process.env.KODAX_PROVIDER??"zhipu-coding";var Ci=[];function _(e){let t=me(e),n=Ci.at(-1)?.sink;if(n){try{n(t)}catch{}return}if(process.env.KODAX_DIAGNOSTICS_STDERR==="1")try{process.stderr.write(`${wn(t)}
|
|
90
|
+
`)}catch{}}o(_,"emitKodaXDiagnostic");function wn(e){let t=me(e),n=Ti(t.detail);return`[${t.source}] ${t.level}: ${t.message}${n?` ${n}`:""}`}o(wn,"formatKodaXDiagnostic");function Ti(e){if(e===void 0)return"";if(e instanceof Error)return e.stack??e.message;if(typeof e=="string")return e;try{return JSON.stringify(e)}catch{return String(e)}}o(Ti,"formatDiagnosticDetail");var ie=class e{static{o(this,"SpanImpl")}id;traceId;parentId;name;data;startedAt;_endedAt;_error;_children=[];now;nextSpanId;onChildCreated;onSpanEnd;_ended=!1;constructor(t){this.id=t.id,this.traceId=t.traceId,this.parentId=t.parentId,this.name=t.name,this.data=t.data,this.now=t.now??(()=>Date.now()),this.startedAt=t.startedAt??this.now(),this.nextSpanId=t.nextSpanId??_i,this.onChildCreated=t.onChildCreated,this.onSpanEnd=t.onSpanEnd}get endedAt(){return this._endedAt}get error(){return this._error}get children(){return this._children}addChild(t,n){let r=new e({id:this.nextSpanId(),traceId:this.traceId,parentId:this.id,name:t,data:n,now:this.now,nextSpanId:this.nextSpanId,onChildCreated:this.onChildCreated,onSpanEnd:this.onSpanEnd});return this._children.push(r),this.onChildCreated&&this.onChildCreated(r),r}setError(t){t instanceof Error?this._error={message:t.message,stack:t.stack}:this._error=t}end(){this._ended||(this._ended=!0,this._endedAt=this.now(),this.onSpanEnd&&this.onSpanEnd(this))}},vn=0;function _i(){vn+=1;let e=Math.random().toString(36).slice(2,8);return`span-${Date.now()}-${vn}-${e}`}o(_i,"defaultNextSpanId");var bn=0;function Pi(){bn+=1;let e=Math.random().toString(36).slice(2,8);return`trace-${Date.now()}-${bn}-${e}`}o(Pi,"defaultNextTraceId");function qe(e={}){let t=e.now??(()=>Date.now()),n=e.id??(e.nextTraceId??Pi)(),r=t(),i=e.name??"trace",s=e.metadata??new Map,a=e.rootSpanData??{kind:"agent",agentName:i},c=!1,d,l,u=new ie({id:`${n}-root`,traceId:n,name:i,data:a,startedAt:r,now:t,nextSpanId:e.nextSpanId,onChildCreated:e.onSpanStart,onSpanEnd:e.onSpanEnd});e.onSpanStart&&e.onSpanStart(u);let f={id:n,startedAt:r,rootSpan:u,metadata:s,get endedAt(){return d},get error(){return l??u.error},end(){c||(c=!0,d=t(),u.end(),e.onTraceEnd&&e.onTraceEnd(f))}};return f}o(qe,"createTrace");var He=[];function ze(e){for(let t of He)try{t.onSpanStart(e)}catch{}}o(ze,"_emitSpanStart");function Ge(e){for(let t of He)try{t.onSpanEnd(e)}catch{}}o(Ge,"_emitSpanEnd");function Ve(e){for(let t of He)try{t.onTraceEnd(e)}catch{}}o(Ve,"_emitTraceEnd");var be=class{static{o(this,"Tracer")}options;constructor(t={}){this.options=t}startTrace(t={}){return qe({id:t.id,name:t.name,rootSpanData:t.rootSpanData,metadata:t.metadata,now:this.options.now,nextSpanId:this.options.nextSpanId,nextTraceId:this.options.nextTraceId,onSpanStart:ze,onSpanEnd:Ge,onTraceEnd:Ve})}},Sn=new be;var Li=["read","edit","bash:test","bash:read-only","bash:mutating","bash:network","subagent"];var ny=new Set(Li);var Je="ELECTRON_RUN_AS_NODE";var Ye="data:text/javascript,delete%20process.env.ELECTRON_RUN_AS_NODE";var zy=String.raw`
|
|
91
|
+
using System;
|
|
92
|
+
using System.Runtime.InteropServices;
|
|
93
|
+
public static class KodaXWindowsJobMembership {
|
|
94
|
+
[StructLayout(LayoutKind.Sequential)]
|
|
95
|
+
private struct BasicLimitInformation {
|
|
96
|
+
public long PerProcessUserTimeLimit;
|
|
97
|
+
public long PerJobUserTimeLimit;
|
|
98
|
+
public uint LimitFlags;
|
|
99
|
+
public UIntPtr MinimumWorkingSetSize;
|
|
100
|
+
public UIntPtr MaximumWorkingSetSize;
|
|
101
|
+
public uint ActiveProcessLimit;
|
|
102
|
+
public UIntPtr Affinity;
|
|
103
|
+
public uint PriorityClass;
|
|
104
|
+
public uint SchedulingClass;
|
|
105
|
+
}
|
|
106
|
+
[StructLayout(LayoutKind.Sequential)]
|
|
107
|
+
private struct IoCounters {
|
|
108
|
+
public ulong ReadOperationCount;
|
|
109
|
+
public ulong WriteOperationCount;
|
|
110
|
+
public ulong OtherOperationCount;
|
|
111
|
+
public ulong ReadTransferCount;
|
|
112
|
+
public ulong WriteTransferCount;
|
|
113
|
+
public ulong OtherTransferCount;
|
|
114
|
+
}
|
|
115
|
+
[StructLayout(LayoutKind.Sequential)]
|
|
116
|
+
private struct ExtendedLimitInformation {
|
|
117
|
+
public BasicLimitInformation BasicLimitInformation;
|
|
118
|
+
public IoCounters IoInfo;
|
|
119
|
+
public UIntPtr ProcessMemoryLimit;
|
|
120
|
+
public UIntPtr JobMemoryLimit;
|
|
121
|
+
public UIntPtr PeakProcessMemoryUsed;
|
|
122
|
+
public UIntPtr PeakJobMemoryUsed;
|
|
123
|
+
}
|
|
124
|
+
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
|
125
|
+
private static extern IntPtr OpenJobObjectW(uint desiredAccess, bool inheritHandle, string name);
|
|
126
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
127
|
+
private static extern bool IsProcessInJob(IntPtr process, IntPtr job, out bool result);
|
|
128
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
129
|
+
private static extern bool QueryInformationJobObject(
|
|
130
|
+
IntPtr job,
|
|
131
|
+
int informationClass,
|
|
132
|
+
out ExtendedLimitInformation information,
|
|
133
|
+
uint informationLength,
|
|
134
|
+
IntPtr returnLength);
|
|
135
|
+
[DllImport("kernel32.dll")]
|
|
136
|
+
private static extern IntPtr GetCurrentProcess();
|
|
137
|
+
[DllImport("kernel32.dll")]
|
|
138
|
+
private static extern bool CloseHandle(IntPtr handle);
|
|
139
|
+
public static bool IsCurrentProcessContained(string name) {
|
|
140
|
+
var job = OpenJobObjectW(4, false, name);
|
|
141
|
+
if (job == IntPtr.Zero) return false;
|
|
142
|
+
try {
|
|
143
|
+
bool inJob;
|
|
144
|
+
if (!IsProcessInJob(GetCurrentProcess(), job, out inJob) || !inJob) return false;
|
|
145
|
+
ExtendedLimitInformation limits;
|
|
146
|
+
if (!QueryInformationJobObject(
|
|
147
|
+
job,
|
|
148
|
+
9,
|
|
149
|
+
out limits,
|
|
150
|
+
(uint)Marshal.SizeOf(typeof(ExtendedLimitInformation)),
|
|
151
|
+
IntPtr.Zero)) return false;
|
|
152
|
+
return (limits.BasicLimitInformation.LimitFlags & 0x00002000) != 0;
|
|
153
|
+
} finally {
|
|
154
|
+
CloseHandle(job);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}`,Gy=String.raw`
|
|
158
|
+
$ErrorActionPreference = 'Stop'
|
|
159
|
+
$source = [Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($env:KODAX_INTERNAL_JOB_QUERY_SOURCE))
|
|
160
|
+
Add-Type -TypeDefinition $source
|
|
161
|
+
if ([KodaXWindowsJobMembership]::IsCurrentProcessContained($env:KODAX_DAEMON_JOB_NAME)) {
|
|
162
|
+
[Console]::Out.Write('1')
|
|
163
|
+
} else {
|
|
164
|
+
[Console]::Out.Write('0')
|
|
165
|
+
}`,Vy=String.raw`
|
|
166
|
+
using System;
|
|
167
|
+
using System.Runtime.InteropServices;
|
|
168
|
+
using System.Text;
|
|
169
|
+
public static class KodaXNativeProcessSnapshot {
|
|
170
|
+
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
|
|
171
|
+
private struct ProcessEntry32 {
|
|
172
|
+
public uint dwSize;
|
|
173
|
+
public uint cntUsage;
|
|
174
|
+
public uint th32ProcessID;
|
|
175
|
+
public IntPtr th32DefaultHeapID;
|
|
176
|
+
public uint th32ModuleID;
|
|
177
|
+
public uint cntThreads;
|
|
178
|
+
public uint th32ParentProcessID;
|
|
179
|
+
public int pcPriClassBase;
|
|
180
|
+
public uint dwFlags;
|
|
181
|
+
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
|
|
182
|
+
public string szExeFile;
|
|
183
|
+
}
|
|
184
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
185
|
+
private static extern IntPtr CreateToolhelp32Snapshot(uint flags, uint processId);
|
|
186
|
+
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
|
187
|
+
private static extern bool Process32First(IntPtr snapshot, ref ProcessEntry32 entry);
|
|
188
|
+
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
|
|
189
|
+
private static extern bool Process32Next(IntPtr snapshot, ref ProcessEntry32 entry);
|
|
190
|
+
[StructLayout(LayoutKind.Sequential)]
|
|
191
|
+
private struct FileTime {
|
|
192
|
+
public uint Low;
|
|
193
|
+
public uint High;
|
|
194
|
+
}
|
|
195
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
196
|
+
private static extern IntPtr OpenProcess(uint access, bool inheritHandle, uint processId);
|
|
197
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
198
|
+
private static extern bool GetProcessTimes(IntPtr process, out FileTime creation, out FileTime exit, out FileTime kernel, out FileTime user);
|
|
199
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
200
|
+
private static extern bool TerminateProcess(IntPtr process, uint exitCode);
|
|
201
|
+
[DllImport("kernel32.dll")]
|
|
202
|
+
private static extern void GetSystemTimeAsFileTime(out FileTime systemTime);
|
|
203
|
+
[DllImport("kernel32.dll")]
|
|
204
|
+
private static extern bool CloseHandle(IntPtr handle);
|
|
205
|
+
private static ulong ReadCreationTime(uint processId) {
|
|
206
|
+
var process = OpenProcess(0x1000, false, processId);
|
|
207
|
+
if (process == IntPtr.Zero) return 0;
|
|
208
|
+
try {
|
|
209
|
+
FileTime creation, exit, kernel, user;
|
|
210
|
+
if (!GetProcessTimes(process, out creation, out exit, out kernel, out user)) return 0;
|
|
211
|
+
return ((ulong)creation.High << 32) | creation.Low;
|
|
212
|
+
} finally {
|
|
213
|
+
CloseHandle(process);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
public static int TerminateExact(uint processId, ulong expectedCreationTime) {
|
|
217
|
+
var process = OpenProcess(0x1001, false, processId);
|
|
218
|
+
if (process == IntPtr.Zero) return 0;
|
|
219
|
+
try {
|
|
220
|
+
FileTime creation, exit, kernel, user;
|
|
221
|
+
if (!GetProcessTimes(process, out creation, out exit, out kernel, out user)) return 0;
|
|
222
|
+
var actual = (((ulong)creation.High << 32) | creation.Low) / 10000;
|
|
223
|
+
if (actual != expectedCreationTime) return 2;
|
|
224
|
+
return TerminateProcess(process, 1) ? 1 : 0;
|
|
225
|
+
} finally {
|
|
226
|
+
CloseHandle(process);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
public static string ReadRows() {
|
|
230
|
+
FileTime cutoffTime;
|
|
231
|
+
GetSystemTimeAsFileTime(out cutoffTime);
|
|
232
|
+
var cutoff = (((ulong)cutoffTime.High << 32) | cutoffTime.Low) / 10000;
|
|
233
|
+
var snapshot = CreateToolhelp32Snapshot(2, 0);
|
|
234
|
+
if (snapshot == new IntPtr(-1)) return string.Empty;
|
|
235
|
+
var rows = new StringBuilder();
|
|
236
|
+
var entry = new ProcessEntry32();
|
|
237
|
+
entry.dwSize = (uint)Marshal.SizeOf(entry);
|
|
238
|
+
try {
|
|
239
|
+
if (!Process32First(snapshot, ref entry)) return string.Empty;
|
|
240
|
+
do {
|
|
241
|
+
var creationTime = ReadCreationTime(entry.th32ProcessID) / 10000;
|
|
242
|
+
if (creationTime == 0 || creationTime <= cutoff) {
|
|
243
|
+
rows.Append(entry.th32ProcessID).Append(',').Append(entry.th32ParentProcessID).Append(',').Append(creationTime).Append('\n');
|
|
244
|
+
}
|
|
245
|
+
entry.dwSize = (uint)Marshal.SizeOf(entry);
|
|
246
|
+
} while (Process32Next(snapshot, ref entry));
|
|
247
|
+
return rows.ToString();
|
|
248
|
+
} finally {
|
|
249
|
+
CloseHandle(snapshot);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}`,Jy=Object.freeze({status:"terminated"}),Yy=Object.freeze({status:"already-exited"}),Qy=Object.freeze({status:"unknown"});var ke="KODAX_EFFECT_JOB_PAYLOAD";var is=String.raw`
|
|
253
|
+
using System;
|
|
254
|
+
using System.IO;
|
|
255
|
+
using System.Runtime.InteropServices;
|
|
256
|
+
using System.Threading;
|
|
257
|
+
|
|
258
|
+
public static class KodaXEffectJob {
|
|
259
|
+
[StructLayout(LayoutKind.Sequential)]
|
|
260
|
+
private struct IoCounters {
|
|
261
|
+
public ulong ReadOperationCount;
|
|
262
|
+
public ulong WriteOperationCount;
|
|
263
|
+
public ulong OtherOperationCount;
|
|
264
|
+
public ulong ReadTransferCount;
|
|
265
|
+
public ulong WriteTransferCount;
|
|
266
|
+
public ulong OtherTransferCount;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
[StructLayout(LayoutKind.Sequential)]
|
|
270
|
+
private struct BasicLimitInformation {
|
|
271
|
+
public long PerProcessUserTimeLimit;
|
|
272
|
+
public long PerJobUserTimeLimit;
|
|
273
|
+
public uint LimitFlags;
|
|
274
|
+
public UIntPtr MinimumWorkingSetSize;
|
|
275
|
+
public UIntPtr MaximumWorkingSetSize;
|
|
276
|
+
public uint ActiveProcessLimit;
|
|
277
|
+
public UIntPtr Affinity;
|
|
278
|
+
public uint PriorityClass;
|
|
279
|
+
public uint SchedulingClass;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
[StructLayout(LayoutKind.Sequential)]
|
|
283
|
+
private struct ExtendedLimitInformation {
|
|
284
|
+
public BasicLimitInformation BasicLimitInformation;
|
|
285
|
+
public IoCounters IoInfo;
|
|
286
|
+
public UIntPtr ProcessMemoryLimit;
|
|
287
|
+
public UIntPtr JobMemoryLimit;
|
|
288
|
+
public UIntPtr PeakProcessMemoryUsed;
|
|
289
|
+
public UIntPtr PeakJobMemoryUsed;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
[StructLayout(LayoutKind.Sequential)]
|
|
293
|
+
private struct BasicAccountingInformation {
|
|
294
|
+
public long TotalUserTime;
|
|
295
|
+
public long TotalKernelTime;
|
|
296
|
+
public long ThisPeriodTotalUserTime;
|
|
297
|
+
public long ThisPeriodTotalKernelTime;
|
|
298
|
+
public uint TotalPageFaultCount;
|
|
299
|
+
public uint TotalProcesses;
|
|
300
|
+
public uint ActiveProcesses;
|
|
301
|
+
public uint TotalTerminatedProcesses;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
|
305
|
+
private static extern IntPtr CreateJobObjectW(IntPtr attributes, string name);
|
|
306
|
+
|
|
307
|
+
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
|
308
|
+
private static extern IntPtr OpenJobObjectW(uint desiredAccess, bool inheritHandle, string name);
|
|
309
|
+
|
|
310
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
311
|
+
private static extern bool SetInformationJobObject(
|
|
312
|
+
IntPtr job,
|
|
313
|
+
int infoClass,
|
|
314
|
+
ref ExtendedLimitInformation info,
|
|
315
|
+
uint length);
|
|
316
|
+
|
|
317
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
318
|
+
private static extern bool QueryInformationJobObject(
|
|
319
|
+
IntPtr job,
|
|
320
|
+
int infoClass,
|
|
321
|
+
out BasicAccountingInformation info,
|
|
322
|
+
uint length,
|
|
323
|
+
IntPtr returnLength);
|
|
324
|
+
|
|
325
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
326
|
+
private static extern IntPtr OpenProcess(uint access, bool inheritHandle, uint processId);
|
|
327
|
+
|
|
328
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
329
|
+
private static extern bool AssignProcessToJobObject(IntPtr job, IntPtr process);
|
|
330
|
+
|
|
331
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
332
|
+
private static extern uint WaitForSingleObject(IntPtr handle, uint milliseconds);
|
|
333
|
+
|
|
334
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
335
|
+
private static extern bool GetExitCodeProcess(IntPtr process, out uint exitCode);
|
|
336
|
+
|
|
337
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
338
|
+
private static extern bool TerminateJobObject(IntPtr job, uint exitCode);
|
|
339
|
+
|
|
340
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
341
|
+
private static extern bool CloseHandle(IntPtr handle);
|
|
342
|
+
|
|
343
|
+
private const uint Synchronize = 0x00100000;
|
|
344
|
+
private const uint ProcessTerminate = 0x0001;
|
|
345
|
+
private const uint ProcessSetQuota = 0x0100;
|
|
346
|
+
private const uint ProcessQueryLimitedInformation = 0x1000;
|
|
347
|
+
private const uint JobObjectTerminate = 0x0008;
|
|
348
|
+
private const uint JobObjectQuery = 0x0004;
|
|
349
|
+
private const uint JobObjectLimitKillOnJobClose = 0x00002000;
|
|
350
|
+
private const uint WaitObject0 = 0;
|
|
351
|
+
|
|
352
|
+
private static void Require(bool result, string operation) {
|
|
353
|
+
if (!result) throw new InvalidOperationException(
|
|
354
|
+
operation + " failed with Win32 error " + Marshal.GetLastWin32Error());
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
private static void PublishReady() {
|
|
358
|
+
Console.Out.WriteLine("READY");
|
|
359
|
+
Console.Out.Flush();
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
public static void Run(uint targetPid, uint ownerPid, string jobName) {
|
|
363
|
+
var job = CreateJobObjectW(IntPtr.Zero, jobName);
|
|
364
|
+
if (job == IntPtr.Zero) throw new InvalidOperationException(
|
|
365
|
+
"CreateJobObject failed with Win32 error " + Marshal.GetLastWin32Error());
|
|
366
|
+
var processAccess = Synchronize | ProcessTerminate | ProcessSetQuota | ProcessQueryLimitedInformation;
|
|
367
|
+
var target = OpenProcess(processAccess, false, targetPid);
|
|
368
|
+
var owner = OpenProcess(Synchronize, false, ownerPid);
|
|
369
|
+
if (target == IntPtr.Zero || owner == IntPtr.Zero) {
|
|
370
|
+
if (target != IntPtr.Zero) CloseHandle(target);
|
|
371
|
+
if (owner != IntPtr.Zero) CloseHandle(owner);
|
|
372
|
+
CloseHandle(job);
|
|
373
|
+
throw new InvalidOperationException(
|
|
374
|
+
"OpenProcess failed with Win32 error " + Marshal.GetLastWin32Error());
|
|
375
|
+
}
|
|
376
|
+
try {
|
|
377
|
+
var limits = new ExtendedLimitInformation();
|
|
378
|
+
limits.BasicLimitInformation.LimitFlags = JobObjectLimitKillOnJobClose;
|
|
379
|
+
Require(SetInformationJobObject(
|
|
380
|
+
job,
|
|
381
|
+
9,
|
|
382
|
+
ref limits,
|
|
383
|
+
(uint)Marshal.SizeOf(typeof(ExtendedLimitInformation))),
|
|
384
|
+
"SetInformationJobObject");
|
|
385
|
+
Require(AssignProcessToJobObject(job, target), "AssignProcessToJobObject");
|
|
386
|
+
PublishReady();
|
|
387
|
+
|
|
388
|
+
uint targetExitCode = 1;
|
|
389
|
+
while (true) {
|
|
390
|
+
if (WaitForSingleObject(owner, 0) == WaitObject0) break;
|
|
391
|
+
if (WaitForSingleObject(target, 0) == WaitObject0) {
|
|
392
|
+
GetExitCodeProcess(target, out targetExitCode);
|
|
393
|
+
break;
|
|
394
|
+
}
|
|
395
|
+
Thread.Sleep(20);
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
Require(TerminateJobObject(job, targetExitCode), "TerminateJobObject");
|
|
399
|
+
while (true) {
|
|
400
|
+
BasicAccountingInformation accounting;
|
|
401
|
+
Require(QueryInformationJobObject(
|
|
402
|
+
job,
|
|
403
|
+
1,
|
|
404
|
+
out accounting,
|
|
405
|
+
(uint)Marshal.SizeOf(typeof(BasicAccountingInformation)),
|
|
406
|
+
IntPtr.Zero),
|
|
407
|
+
"QueryInformationJobObject");
|
|
408
|
+
if (accounting.ActiveProcesses == 0) return;
|
|
409
|
+
Thread.Sleep(10);
|
|
410
|
+
}
|
|
411
|
+
} finally {
|
|
412
|
+
CloseHandle(owner);
|
|
413
|
+
CloseHandle(target);
|
|
414
|
+
CloseHandle(job);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
public static bool TerminateAndDrain(string jobName) {
|
|
419
|
+
var job = OpenJobObjectW(JobObjectTerminate | JobObjectQuery, false, jobName);
|
|
420
|
+
if (job == IntPtr.Zero) {
|
|
421
|
+
var error = Marshal.GetLastWin32Error();
|
|
422
|
+
if (error == 2) return false;
|
|
423
|
+
throw new InvalidOperationException(
|
|
424
|
+
"OpenJobObject failed with Win32 error " + error);
|
|
425
|
+
}
|
|
426
|
+
try {
|
|
427
|
+
Require(TerminateJobObject(job, 1), "TerminateJobObject");
|
|
428
|
+
while (true) {
|
|
429
|
+
BasicAccountingInformation accounting;
|
|
430
|
+
Require(QueryInformationJobObject(
|
|
431
|
+
job,
|
|
432
|
+
1,
|
|
433
|
+
out accounting,
|
|
434
|
+
(uint)Marshal.SizeOf(typeof(BasicAccountingInformation)),
|
|
435
|
+
IntPtr.Zero),
|
|
436
|
+
"QueryInformationJobObject");
|
|
437
|
+
if (accounting.ActiveProcesses == 0) return true;
|
|
438
|
+
Thread.Sleep(10);
|
|
439
|
+
}
|
|
440
|
+
} finally {
|
|
441
|
+
CloseHandle(job);
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
}`,ss=String.raw`
|
|
446
|
+
using System;
|
|
447
|
+
using System.Collections.Generic;
|
|
448
|
+
using System.Diagnostics;
|
|
449
|
+
using System.Runtime.InteropServices;
|
|
450
|
+
using System.Security.Principal;
|
|
451
|
+
|
|
452
|
+
public static class KodaXSidProbe {
|
|
453
|
+
[StructLayout(LayoutKind.Sequential)]
|
|
454
|
+
private struct WtsProcessInformation {
|
|
455
|
+
public uint SessionId;
|
|
456
|
+
public uint ProcessId;
|
|
457
|
+
public IntPtr ProcessName;
|
|
458
|
+
public IntPtr UserSid;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
|
462
|
+
private struct ProcessEntry32 {
|
|
463
|
+
public uint Size;
|
|
464
|
+
public uint Usage;
|
|
465
|
+
public uint ProcessId;
|
|
466
|
+
public UIntPtr DefaultHeapId;
|
|
467
|
+
public uint ModuleId;
|
|
468
|
+
public uint Threads;
|
|
469
|
+
public uint ParentProcessId;
|
|
470
|
+
public int PriorityClassBase;
|
|
471
|
+
public uint Flags;
|
|
472
|
+
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
|
|
473
|
+
public string ExecutableFile;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
[DllImport("wtsapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
|
477
|
+
private static extern bool WTSEnumerateProcessesW(
|
|
478
|
+
IntPtr server,
|
|
479
|
+
uint reserved,
|
|
480
|
+
uint version,
|
|
481
|
+
out IntPtr processInformation,
|
|
482
|
+
out uint count);
|
|
483
|
+
|
|
484
|
+
[DllImport("wtsapi32.dll")]
|
|
485
|
+
private static extern void WTSFreeMemory(IntPtr memory);
|
|
486
|
+
|
|
487
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
488
|
+
private static extern IntPtr CreateToolhelp32Snapshot(uint flags, uint processId);
|
|
489
|
+
|
|
490
|
+
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
|
491
|
+
private static extern bool Process32FirstW(IntPtr snapshot, ref ProcessEntry32 entry);
|
|
492
|
+
|
|
493
|
+
[DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
|
|
494
|
+
private static extern bool Process32NextW(IntPtr snapshot, ref ProcessEntry32 entry);
|
|
495
|
+
|
|
496
|
+
[DllImport("kernel32.dll", SetLastError = true)]
|
|
497
|
+
private static extern bool CloseHandle(IntPtr handle);
|
|
498
|
+
|
|
499
|
+
private static Dictionary<uint, uint> ProcessParents() {
|
|
500
|
+
var parents = new Dictionary<uint, uint>();
|
|
501
|
+
var snapshot = CreateToolhelp32Snapshot(0x00000002, 0);
|
|
502
|
+
if (snapshot == new IntPtr(-1)) throw new InvalidOperationException(
|
|
503
|
+
"CreateToolhelp32Snapshot failed with Win32 error " + Marshal.GetLastWin32Error());
|
|
504
|
+
try {
|
|
505
|
+
var entry = new ProcessEntry32();
|
|
506
|
+
entry.Size = (uint)Marshal.SizeOf(typeof(ProcessEntry32));
|
|
507
|
+
if (!Process32FirstW(snapshot, ref entry)) throw new InvalidOperationException(
|
|
508
|
+
"Process32First failed with Win32 error " + Marshal.GetLastWin32Error());
|
|
509
|
+
do {
|
|
510
|
+
parents[entry.ProcessId] = entry.ParentProcessId;
|
|
511
|
+
entry.Size = (uint)Marshal.SizeOf(typeof(ProcessEntry32));
|
|
512
|
+
} while (Process32NextW(snapshot, ref entry));
|
|
513
|
+
} finally {
|
|
514
|
+
CloseHandle(snapshot);
|
|
515
|
+
}
|
|
516
|
+
return parents;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
private static HashSet<uint> MatchingProcesses(SecurityIdentifier expected) {
|
|
520
|
+
var matches = new HashSet<uint>();
|
|
521
|
+
IntPtr processes;
|
|
522
|
+
uint count;
|
|
523
|
+
if (!WTSEnumerateProcessesW(IntPtr.Zero, 0, 1, out processes, out count)) {
|
|
524
|
+
throw new InvalidOperationException(
|
|
525
|
+
"WTSEnumerateProcesses failed with Win32 error " + Marshal.GetLastWin32Error());
|
|
526
|
+
}
|
|
527
|
+
try {
|
|
528
|
+
var entrySize = Marshal.SizeOf(typeof(WtsProcessInformation));
|
|
529
|
+
for (uint index = 0; index < count; index++) {
|
|
530
|
+
var address = new IntPtr(processes.ToInt64() + ((long)index * entrySize));
|
|
531
|
+
var entry = (WtsProcessInformation)Marshal.PtrToStructure(
|
|
532
|
+
address,
|
|
533
|
+
typeof(WtsProcessInformation));
|
|
534
|
+
if (entry.UserSid == IntPtr.Zero) continue;
|
|
535
|
+
if (new SecurityIdentifier(entry.UserSid).Equals(expected)) matches.Add(entry.ProcessId);
|
|
536
|
+
}
|
|
537
|
+
} finally {
|
|
538
|
+
WTSFreeMemory(processes);
|
|
539
|
+
}
|
|
540
|
+
return matches;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
private static bool DescendsFrom(
|
|
544
|
+
uint process,
|
|
545
|
+
uint root,
|
|
546
|
+
Dictionary<uint, uint> parents
|
|
547
|
+
) {
|
|
548
|
+
var visited = new HashSet<uint>();
|
|
549
|
+
while (process != 0 && visited.Add(process)) {
|
|
550
|
+
if (process == root) return true;
|
|
551
|
+
if (!parents.ContainsKey(process)) return false;
|
|
552
|
+
process = parents[process];
|
|
553
|
+
}
|
|
554
|
+
return false;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
public static bool HasOtherProcessWithSid(string expectedSid, bool ignoreProbeTree) {
|
|
558
|
+
var expected = new SecurityIdentifier(expectedSid);
|
|
559
|
+
using (var identity = WindowsIdentity.GetCurrent()) {
|
|
560
|
+
var sameUser = identity.User != null && identity.User.Equals(expected);
|
|
561
|
+
var administrator = new WindowsPrincipal(identity)
|
|
562
|
+
.IsInRole(WindowsBuiltInRole.Administrator);
|
|
563
|
+
if (ignoreProbeTree && !sameUser) {
|
|
564
|
+
throw new InvalidOperationException("Process-tree SID probe must run as the expected sandbox user");
|
|
565
|
+
}
|
|
566
|
+
if (!ignoreProbeTree && !sameUser && !administrator) {
|
|
567
|
+
throw new InvalidOperationException(
|
|
568
|
+
"Machine-wide inspection of a foreign Windows SID requires an elevated administrator token");
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
var matches = MatchingProcesses(expected);
|
|
572
|
+
if (!ignoreProbeTree) return matches.Count > 0;
|
|
573
|
+
var current = (uint)Process.GetCurrentProcess().Id;
|
|
574
|
+
if (!matches.Contains(current)) throw new InvalidOperationException(
|
|
575
|
+
"SID probe could not observe its own process");
|
|
576
|
+
var parents = ProcessParents();
|
|
577
|
+
var root = parents.ContainsKey(current) ? parents[current] : current;
|
|
578
|
+
foreach (var process in matches) {
|
|
579
|
+
if (!DescendsFrom(process, root, parents)) return true;
|
|
580
|
+
}
|
|
581
|
+
return false;
|
|
582
|
+
}
|
|
583
|
+
}`,as=String.raw`
|
|
584
|
+
$ErrorActionPreference = 'Stop'
|
|
585
|
+
try {
|
|
586
|
+
$payload = [Text.Encoding]::UTF8.GetString(
|
|
587
|
+
[Convert]::FromBase64String($env:${ke})) | ConvertFrom-Json
|
|
588
|
+
Remove-Item Env:${ke} -ErrorAction SilentlyContinue
|
|
589
|
+
$source = @'
|
|
590
|
+
${is}
|
|
591
|
+
'@
|
|
592
|
+
Add-Type -TypeDefinition $source
|
|
593
|
+
if ($payload.action -eq 'recover') {
|
|
594
|
+
$drained = [KodaXEffectJob]::TerminateAndDrain([string]$payload.jobName)
|
|
595
|
+
[Console]::Out.WriteLine($(if ($drained) { 'DRAINED' } else { 'NOT_FOUND' }))
|
|
596
|
+
[Console]::Out.Flush()
|
|
597
|
+
} else {
|
|
598
|
+
[KodaXEffectJob]::Run(
|
|
599
|
+
[uint32]$payload.targetPid,
|
|
600
|
+
[uint32]$payload.ownerPid,
|
|
601
|
+
[string]$payload.jobName)
|
|
602
|
+
}
|
|
603
|
+
exit 0
|
|
604
|
+
} catch {
|
|
605
|
+
[Console]::Out.WriteLine('ERROR:' + $_.Exception.Message)
|
|
606
|
+
[Console]::Out.Flush()
|
|
607
|
+
exit 1
|
|
608
|
+
}`,dw=Buffer.from(as,"utf16le").toString("base64"),cs=String.raw`
|
|
609
|
+
$ErrorActionPreference = 'Stop'
|
|
610
|
+
try {
|
|
611
|
+
$payload = [Text.Encoding]::UTF8.GetString(
|
|
612
|
+
[Convert]::FromBase64String($env:${ke})) | ConvertFrom-Json
|
|
613
|
+
Remove-Item Env:${ke} -ErrorAction SilentlyContinue
|
|
614
|
+
$source = @'
|
|
615
|
+
${ss}
|
|
616
|
+
'@
|
|
617
|
+
Add-Type -TypeDefinition $source
|
|
618
|
+
$active = [KodaXSidProbe]::HasOtherProcessWithSid(
|
|
619
|
+
[string]$payload.sid,
|
|
620
|
+
[bool]$payload.ignoreCurrentProcessTree)
|
|
621
|
+
[Console]::Out.WriteLine($(if ($active) { 'ACTIVE' } else { 'CLEAR' }))
|
|
622
|
+
[Console]::Out.Flush()
|
|
623
|
+
exit 0
|
|
624
|
+
} catch {
|
|
625
|
+
[Console]::Out.WriteLine('ERROR:' + $_.Exception.Message)
|
|
626
|
+
[Console]::Out.Flush()
|
|
627
|
+
exit 1
|
|
628
|
+
}`,lw=Buffer.from(cs,"utf16le").toString("base64");var ys=Math.floor(3.75*1024*1024);var vs=1440*60*1e3;import{fileURLToPath as Hs}from"url";import{dirname as zs}from"path";var Gs=Hs(import.meta.url),Lb=zs(Gs);import{readFile as Zs,readdir as ea}from"fs/promises";import{join as W,relative as ta}from"path";import $n from"yaml";var Vs=["SessionStart","UserPromptSubmit","PreToolUse","PostToolUse","Stop","SubagentStop","Notification"];function Js(e){let t=e.split(`
|
|
629
|
+
`),n=[];for(let r of t){let i=r.indexOf(":");if(i>0){let s=r.slice(0,i).trim(),a=r.slice(i+1).trim();if(a.includes(":")&&!a.startsWith('"')&&!a.startsWith("'")&&!a.startsWith("[")&&!a.startsWith("|")&&!a.startsWith(">")){n.push(`${s}: |-`),n.push(` ${a}`);continue}}n.push(r)}return n.join(`
|
|
630
|
+
`)}o(Js,"sanitizeYaml");function Nn(e,t={}){let n=e.replace(/^/,"").replace(/\r\n/g,`
|
|
631
|
+
`).replace(/\r/g,`
|
|
632
|
+
`).trimStart();if(!n.startsWith(`---
|
|
633
|
+
`)){if(t.throwOnMissing)throw new Error("Invalid markdown: missing YAML frontmatter");return[null,e]}let r=n.indexOf(`
|
|
634
|
+
---
|
|
635
|
+
`,4);if(r===-1){let c=n.indexOf(`
|
|
636
|
+
---`,4);c!==-1&&c===n.length-4&&(r=c)}if(r===-1){if(t.throwOnMissing)throw new Error("Invalid markdown: unclosed YAML frontmatter");return[null,e]}let i=n.slice(4,r),s=n.slice(r+5).trim(),a;try{a=$n.parse(i)??{}}catch{a=$n.parse(Js(i))??{}}if(a==null||typeof a!="object"||Array.isArray(a)){if(t.throwOnMissing)throw new Error("Invalid markdown: YAML frontmatter must be an object");return[null,s]}return[a,s]}o(Nn,"parseYamlFrontmatter");function Dn(e){if(typeof e=="string"){let t=e.trim();return t.length>0?t:void 0}if(Array.isArray(e)){let t=e.map(n=>String(n).trim()).filter(n=>n.length>0);return t.length>0?t.join(", "):void 0}}o(Dn,"normalizeAllowedToolsString");function Ys(e){if(typeof e=="string"){let t=e.trim();return t?{command:t}:void 0}if(e&&typeof e=="object"&&!Array.isArray(e)){let t=e,n=typeof t.command=="string"?t.command.trim():"";if(!n)return;let r=typeof t.matcher=="string"&&t.matcher.trim()?t.matcher.trim():void 0;return{command:n,matcher:r}}}o(Ys,"normalizeYamlHookEntry");function Qs(e){if(e==null)return;let n=(Array.isArray(e)?e:[e]).map(r=>Ys(r)).filter(r=>r!==void 0);return n.length>0?n:void 0}o(Qs,"normalizeYamlHookEntryList");function Ln(e){if(!e||typeof e!="object"||Array.isArray(e))return;let t=e,n={};for(let r of Vs){let i=Qs(t[r]);i&&(n[r]=i)}return Object.keys(n).length>0?n:void 0}o(Ln,"normalizeYamlHookMap");function jn(e){let[t,n]=Nn(e,{throwOnMissing:!0});if(!t)throw new Error("Invalid SKILL.md: YAML frontmatter must be an object");if(!t.name||typeof t.name!="string")throw new Error('Invalid SKILL.md: missing required "name" field');if(!t.description||typeof t.description!="string")throw new Error('Invalid SKILL.md: missing required "description" field');return{frontmatter:{name:t.name,description:t.description,disableModelInvocation:t["disable-model-invocation"]===!0,userInvocable:t["user-invocable"]!==!1,allowedTools:Dn(t["allowed-tools"]),context:t.context==="fork"?"fork":void 0,agent:typeof t.agent=="string"?t.agent:void 0,argumentHint:typeof t["argument-hint"]=="string"?t["argument-hint"]:void 0,model:typeof t.model=="string"?t.model:void 0,hooks:Ln(t.hooks),license:typeof t.license=="string"?t.license:void 0,compatibility:typeof t.compatibility=="string"?t.compatibility:void 0,metadata:t.metadata&&typeof t.metadata=="object"&&!Array.isArray(t.metadata)?t.metadata:void 0},body:n}}o(jn,"parseSkillMarkdown");async function xe(e,t){let n=W(e,"SKILL.md");try{let r=await Zs(n,"utf-8"),{frontmatter:i,body:s}=jn(r),[a,c,d,l,u]=await Promise.all([V(W(e,"scripts")),V(W(e,"references")),V(W(e,"assets")),V(W(e,"templates")),V(W(e,"resources"))]);return{...i,userInvocable:!0,path:e,skillFilePath:n,content:s,rawContent:s,loaded:!0,source:t,...a.length>0&&{scripts:a},...c.length>0&&{references:c},...d.length>0&&{assets:d},...l.length>0&&{templates:l},...u.length>0&&{resources:u}}}catch(r){return _({source:"agent:skills",level:"error",message:`Failed to load skill from ${e}.`,detail:r}),null}}o(xe,"loadFullSkill");async function V(e,t=e){let n=[];try{let r=await ea(e,{withFileTypes:!0});r.sort((i,s)=>i.name.localeCompare(s.name));for(let i of r){let s=W(e,i.name);if(i.isDirectory()){n.push(...await V(s,t));continue}i.isFile()&&n.push({name:i.name,path:s,relativePath:ta(t,s).replace(/\\/g,"/")})}}catch{}return n}o(V,"loadSkillFiles");var Fn=64*1024,Kn=256*1024;var AS=1024*1024;var ok=16*1024;var pk=16*1024;import{execSync as La}from"child_process";import ja from"path";var Fa=new Set(["ls","cat","pwd","echo","whoami","date","which","whereis","tree","dir","type","get-childitem","get-content","select-string","get-location","grep","find","awk","sed","head","tail","less","more","wc","git status","git diff","git log","git show","git branch","git remote","git ls-files","git rev-parse","git grep","node","npm","yarn","pnpm","tsc","python","pip","go","cargo","rustc"]);function nr(e){if(!e||!e.trim())return!1;let t=e.trim().replace(/\s+/g," ").toLowerCase();for(let n of Fa)if(t===n||t.startsWith(`${n} `)){if(n==="sed"&&t.split(/\s+/).some(s=>s.startsWith("-i")||s==="--in-place"))return!1;if(n==="awk"){let i=t.split(/\s+/);if(i.includes("-f")||i.includes("--file"))return!1}if(["node","npm","yarn","pnpm","tsc","python","pip","go","cargo","rustc"].includes(n)){let i=t.split(/\s+/).slice(1);if(i.length>0&&!i.every(s=>/^(-v|--version|-h|--help)$/.test(s)))return!1}return!0}return!1}o(nr,"isSingleSafeDynamicContextCommand");function Ka(e){if(!e||!e.trim())return!1;let t=e.trim().replace(/\\\r?\n/g," ");if(/[<>|;`]|\$\(|(?<!&)&(?!&)/.test(t)||t.includes("\\")&&ja.sep!=="\\"&&t.replace(/\\ /g,"").includes("\\"))return!1;let r=t.split(/\s*&&\s*/);if(r.length===1)return nr(r[0]);for(let i of r){let s=i?.trim();if(s&&!/^cd\s+/.test(s.toLowerCase())&&!nr(s))return!1}return!0}o(Ka,"isSafeDynamicContextCommand");function rr(e){let t=[],n="",r=!1,i="";for(let s=0;s<e.length;s++){let a=e[s];r?a===i?r=!1:n+=a:a==='"'||a==="'"?(r=!0,i=a):a===" "?n&&(t.push(n),n=""):n+=a}return n&&t.push(n),t}o(rr,"parseArguments");var Ae=class{static{o(this,"VariableResolver")}context;constructor(t){this.context=t}async resolve(t,n){let r=t,i=rr(n);return r=this.resolvePositionalArgs(r,i),r=this.resolveArguments(r,n),r=this.resolveEnvVars(r),r=await this.resolveDynamicContext(r),r}resolvePositionalArgs(t,n){return t.replace(/\$(\d+)(?![a-zA-Z0-9_])/g,(r,i)=>{let s=parseInt(i,10);return n[s]??""})}resolveArguments(t,n){return t.replace(/\$ARGUMENTS/g,n)}resolveEnvVars(t){let n={...this.context.environment,CLAUDE_SESSION_ID:this.context.sessionId??"",KODAX_SESSION_ID:this.context.sessionId??"",KODAX_WORKING_DIR:this.context.workingDirectory};return t.replace(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/g,(r,i)=>n[i]??r)}async resolveDynamicContext(t){let n=/!`([^`]+)`/g,r=[],i;for(;(i=n.exec(t))!==null;)r.push({match:i[0],command:i[1]});if(r.length===0)return t;let s=t;for(let{match:a,command:c}of r)try{let d=await this.executeDynamicCommand(c);s=s.replace(a,d)}catch(d){let l=d instanceof Error?d.message:String(d);s=s.replace(a,`[Error: ${l}]`)}return s}async executeDynamicCommand(t){if(this.context.disableDynamicContext)throw new Error("Dynamic context disabled by host. Skill `!`cmd`` blocks are not allowed in this environment.");if(this.context.executeDynamicContext){let n=await this.context.executeDynamicContext(t,this.context.workingDirectory);return typeof n=="string"?n.trim():""}if(!Ka(t))throw new Error("Unsafe dynamic context command blocked. Only simple read-only commands are allowed in !`...` blocks.");try{return La(t,{cwd:this.context.workingDirectory,encoding:"utf-8",timeout:5e3,maxBuffer:1048576,windowsHide:!0}).trim()}catch(n){throw n instanceof Error?new Error(`Command failed: ${n.message}`):n}}};async function ce(e,t,n){return new Ae(n).resolve(e,t)}o(ce,"resolveSkillContent");function or(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'")}o(or,"escapeXml");var st=120;function Ce(e){return e.replace(/\\/g,"/")}o(Ce,"formatDisplayPath");function Ua(e){return[...(e.references??[]).map(t=>({folder:"references",file:t})),...(e.scripts??[]).map(t=>({folder:"scripts",file:t})),...(e.assets??[]).map(t=>({folder:"assets",file:t})),...(e.templates??[]).map(t=>({folder:"templates",file:t})),...(e.resources??[]).map(t=>({folder:"resources",file:t}))]}o(Ua,"collectSupportFiles");function Xa(e){let t=Ua(e);if(t.length===0)return[];let n=[["references",e.references],["scripts",e.scripts],["assets",e.assets],["templates",e.templates],["resources",e.resources]],r=["Skill support files are rooted at the skill root above. When the skill references `references/...`, `assets/...`, `scripts/...`, `templates/...`, or `resources/...`, read it from this skill root.","","Support roots:"];for(let[i,s]of n)s?.length&&r.push(`- ${i}/: ${Ce(`${e.path}/${i}`)} (${s.length} files)`);r.push("","Support file inventory:");for(let{folder:i,file:s}of t.slice(0,st))r.push(`- ${i}/${s.relativePath}: ${Ce(s.path)}`);return t.length>st&&r.push(`- ... ${t.length-st} more files under ${Ce(e.path)}`),r}o(Xa,"buildSupportFileContext");function qa(e,t,n){let r=[];r.push(`<skill name="${or(e.name)}" location="${or(e.path)}">`),r.push(""),r.push(`Skill root: ${Ce(e.path)}`),e.source==="builtin"?r.push("This is a built-in KodaX skill."):e.source==="project"?r.push("This is a project-defined skill. Project work paths are relative to the project root; skill support files are relative to the skill root above."):e.source==="user"&&r.push("This is a user-defined skill."),r.push("");let i=Xa(e);return i.length>0&&(r.push(...i),r.push("")),r.push(t),n.trim()&&(r.push(""),r.push(`User provided arguments: ${n}`)),r.push(""),r.push("</skill>"),r.join(`
|
|
637
|
+
`)}o(qa,"buildSkillBlock");async function at(e,t,n){let r=await ce(e.content,t,n);return{content:qa(e,r,t),disableModelInvocation:e.disableModelInvocation??!1,skill:e}}o(at,"expandSkillForLLM");import{writeFile as dr}from"node:fs/promises";import F from"node:path";import{existsSync as Ha}from"node:fs";import{mkdir as za,readFile as ct,readdir as Ga,stat as sr,writeFile as ux}from"node:fs/promises";import Va from"node:os";import $ from"node:path";import{fileURLToPath as ar,pathToFileURL as Ja}from"node:url";import Ya from"yaml";var Y=null;async function j(){if(Y)return Y;let e=$.dirname(ar(import.meta.url)),t=[],n=$.resolve(e,"../../../index.js");if(Ha(n))return Y=await import(Ja(n).href),Y;t.push(`relative SDK path not found: ${n}`);try{return Y=await import(["@kodax-ai","kodax"].join("/")),Y}catch(r){t.push(`bare-name @kodax-ai/kodax failed: ${r?.code??r?.message}`)}throw new Error(`Cannot locate KodaX SDK from helper script ${import.meta.url}.
|
|
638
|
+
Attempted:
|
|
639
|
+
- ${t.join(`
|
|
640
|
+
- `)}`)}o(j,"loadKodaXSDK");function Qa(e){let t=e.replace(/^\uFEFF/,"").replace(/\r\n/g,`
|
|
641
|
+
`).replace(/\r/g,`
|
|
642
|
+
`).trimStart();if(!t.startsWith(`---
|
|
643
|
+
`))throw new Error("SKILL.md missing YAML frontmatter");let n=t.indexOf(`
|
|
644
|
+
---
|
|
645
|
+
`,4);if(n===-1)throw new Error("SKILL.md has unclosed YAML frontmatter");return{yamlText:t.slice(4,n),body:t.slice(n+5).trim()}}o(Qa,"extractFrontmatter");function Te(e){let{yamlText:t,body:n}=Qa(e),r=Ya.parse(t);if(!r||typeof r!="object"||Array.isArray(r))throw new Error("Frontmatter must be a YAML object");return{frontmatter:r,body:n}}o(Te,"parseSkillMarkdown");async function le(e){let t=$.join(e,"SKILL.md");if(!(await sr(t).catch(()=>null))?.isFile())throw new Error(`SKILL.md not found in ${e}`);let r=await ct(t,"utf8"),{frontmatter:i,body:s}=Te(r);return{skillDir:$.resolve(e),skillMdPath:t,rawContent:r,body:s,frontmatter:i}}o(le,"loadSkill");async function ue(e){try{return await sr(e),!0}catch{return!1}}o(ue,"pathExists");function _e(e){if(!e.length)return{mean:0,stddev:0,min:0,max:0};let t=e.reduce((r,i)=>r+i,0)/e.length,n=e.length>1?e.reduce((r,i)=>r+(i-t)**2,0)/(e.length-1):0;return{mean:de(t),stddev:de(Math.sqrt(n)),min:de(Math.min(...e)),max:de(Math.max(...e))}}o(_e,"calculateStats");function de(e,t=4){return Number(e.toFixed(t))}o(de,"roundNumber");function Pe(e){return e>=0?`+${e.toFixed(4)}`:e.toFixed(4)}o(Pe,"formatDelta");function ir(e){try{return JSON.parse(e)}catch{return null}}o(ir,"safeJsonParse");function Q(e){let t=ir(e.trim());if(t&&typeof t=="object")return t;let n=e.indexOf("{"),r=e.lastIndexOf("}");return n===-1||r===-1||r<=n?null:ir(e.slice(n,r+1))}o(Q,"extractJsonObject");async function P(e,t=null){try{return JSON.parse(await ct(e,"utf8"))}catch{return t}}o(P,"readJsonFile");async function Z(e,t){let n=$.dirname(ar(e));return ct($.resolve(n,t),"utf8")}o(Z,"loadRelativeText");function I(e,t=12e3){let n=typeof e=="string"?e:String(e??"");if(n.length<=t)return n;let r=n.length-t;return`${n.slice(0,t)}
|
|
646
|
+
|
|
647
|
+
[truncated ${r} chars]`}o(I,"truncateText");function cr(e){let t=Array.isArray(e)?e.length:0,n=Array.isArray(e)?e.filter(i=>i?.passed===!0).length:0,r=Math.max(t-n,0);return{passed:n,failed:r,total:t,pass_rate:t>0?de(n/t):0}}o(cr,"computePassSummary");async function dt(e,t=e,n=[]){let r=await Ga(t,{withFileTypes:!0}).catch(()=>[]);for(let i of r.sort((s,a)=>s.name.localeCompare(a.name))){let s=$.join(t,i.name);if(i.isDirectory()){await dt(e,s,n);continue}i.isFile()&&n.push({absolutePath:s,relativePath:$.relative(e,s).replace(/\\/g,"/")})}return n}o(dt,"collectFiles");function fe(){return $.join(Va.homedir(),".kodax","skills")}o(fe,"getDefaultSkillsDir");async function A(e){return await za(e,{recursive:!0}),e}o(A,"ensureDirectory");function Za(e){return e.split("-").filter(Boolean).map(t=>t[0]?.toUpperCase()+t.slice(1)).join(" ")}o(Za,"titleFromSlug");function ec(e,t){let n=Za(e);return`---
|
|
648
|
+
name: ${e}
|
|
649
|
+
description: ${t}
|
|
650
|
+
user-invocable: true
|
|
651
|
+
disable-model-invocation: false
|
|
652
|
+
allowed-tools: "Read, Grep, Glob"
|
|
653
|
+
compatibility: "Optimized for KodaX and Agent Skills style directories."
|
|
654
|
+
---
|
|
655
|
+
|
|
656
|
+
# ${n}
|
|
657
|
+
|
|
658
|
+
Describe the task this skill handles, the trigger boundary, and the expected outcome.
|
|
659
|
+
|
|
660
|
+
## When to use
|
|
661
|
+
|
|
662
|
+
- Use this skill when the user asks for ${n.toLowerCase()}.
|
|
663
|
+
- Do not use this skill when the request only needs a short explanation or is out of scope.
|
|
664
|
+
|
|
665
|
+
## Workflow
|
|
666
|
+
|
|
667
|
+
1. Restate the task boundary in one sentence.
|
|
668
|
+
2. Gather the minimum context needed to do the work well.
|
|
669
|
+
3. Execute the task, preferring small, verifiable steps.
|
|
670
|
+
4. Summarize what changed, what was validated, and any remaining risks.
|
|
671
|
+
|
|
672
|
+
## References
|
|
673
|
+
|
|
674
|
+
- Put deeper guidance in \`references/\`.
|
|
675
|
+
- Put reusable templates or static files in \`assets/\`.
|
|
676
|
+
- Put repeatable helper scripts in \`scripts/\`.
|
|
677
|
+
`}o(ec,"renderSkillTemplate");function tc(e){return JSON.stringify({skill_name:e,evals:[{id:1,prompt:"TODO: Add a realistic user request to evaluate this skill.",expected_output:"Describe what a successful result should accomplish.",files:[],assertions:[]}]},null,2)}o(tc,"renderEvalTemplate");async function nc(e){let t=F.resolve(e.baseDir??fe()),n=F.join(t,e.name),r=e.description??`Describe what ${e.name} does and when it should be used.`;if(await ue(n)&&!e.force)throw new Error(`Skill directory already exists: ${n}`);return await A(n),await A(F.join(n,"references")),await A(F.join(n,"assets")),await A(F.join(n,"scripts")),await dr(F.join(n,"SKILL.md"),ec(e.name,r),"utf8"),e.includeEvals!==!1&&(await A(F.join(n,"evals")),await dr(F.join(n,"evals","evals.json"),`${tc(e.name)}
|
|
678
|
+
`,"utf8")),{skillDir:n,created:["SKILL.md",...e.includeEvals!==!1?["evals/evals.json"]:[],"references/","assets/","scripts/"]}}o(nc,"initSkill");function rc(e){let t={name:e[2],baseDir:void 0,description:void 0,force:!1,includeEvals:!0};for(let n=3;n<e.length;n+=1){let r=e[n];(r==="--path"||r==="--dest")&&e[n+1]?t.baseDir=e[++n]:r==="--description"&&e[n+1]?t.description=e[++n]:r==="--force"?t.force=!0:r==="--no-evals"&&(t.includeEvals=!1)}return t}o(rc,"parseArgs");async function lr(e=process.argv){let t=rc(e);t.name||(console.error("Usage: node scripts/init-skill.js <skill-name> [--path <skills-dir>] [--description <text>] [--force] [--no-evals]"),process.exit(1));let n=await nc(t);console.log(`Initialized ${n.skillDir}`)}o(lr,"main");var oc=!1;oc&&lr().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exit(1)});import ur from"node:path";var ic=new Set(["name","description","license","compatibility","metadata","allowed-tools","disable-model-invocation","user-invocable","argument-hint","context","agent","model","hooks"]);async function pe(e){let t={valid:!1,errors:[],warnings:[],frontmatter:null},n;try{n=await le(e)}catch(d){return t.errors.push(d instanceof Error?d.message:String(d)),t}let{frontmatter:r,body:i}=n;t.frontmatter=r;let s=Object.keys(r).filter(d=>!ic.has(d));s.length>0&&t.errors.push(`Unexpected frontmatter keys: ${s.sort().join(", ")}`);let a=typeof r.name=="string"?r.name.trim():"",c=typeof r.description=="string"?r.description.trim():"";if(!a)t.errors.push("Missing required frontmatter field: name");else{/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(a)||t.errors.push(`Invalid skill name "${a}". Use lowercase kebab-case and avoid consecutive hyphens.`),a.length>64&&t.errors.push(`Skill name is too long (${a.length}/64).`);let d=ur.basename(ur.resolve(e));d!==a&&t.warnings.push(`Skill directory name "${d}" does not match frontmatter name "${a}".`)}if(c?(c.length>1024&&t.errors.push(`Description is too long (${c.length}/1024).`),/[<>]/.test(c)&&t.errors.push("Description cannot contain angle brackets."),/[。.!?]/.test(c)||t.warnings.push("Description may be too terse; consider making the trigger conditions clearer.")):t.errors.push("Missing required frontmatter field: description"),i.trim()||t.errors.push("SKILL.md body is empty."),r.compatibility!=null&&(typeof r.compatibility!="string"?t.errors.push("compatibility must be a string if provided."):r.compatibility.length>500&&t.errors.push(`compatibility is too long (${r.compatibility.length}/500).`)),r["allowed-tools"]!=null){let d=r["allowed-tools"];typeof d=="string"||Array.isArray(d)&&d.every(u=>typeof u=="string")||t.errors.push("allowed-tools must be a string or string array.")}return r["disable-model-invocation"]!=null&&typeof r["disable-model-invocation"]!="boolean"&&t.errors.push("disable-model-invocation must be a boolean."),r["user-invocable"]!=null&&typeof r["user-invocable"]!="boolean"&&t.errors.push("user-invocable must be a boolean."),r.context!=null&&r.context!=="fork"&&t.errors.push('context must be "fork" when provided.'),r.hooks!=null&&(typeof r.hooks!="object"||Array.isArray(r.hooks))&&t.errors.push("hooks must be an object when provided."),t.valid=t.errors.length===0,t}o(pe,"validateSkillDirectory");async function fr(e=process.argv){let t=e[2];t||(console.error("Usage: node scripts/quick-validate.js <skill-directory>"),process.exit(1));let n=await pe(t);if(n.errors.length===0)console.log("Skill is valid.");else{console.error("Skill validation failed:");for(let r of n.errors)console.error(`- ${r}`)}if(n.warnings.length>0){console.log("Warnings:");for(let r of n.warnings)console.log(`- ${r}`)}process.exit(n.valid?0:1)}o(fr,"main");var sc=!1;sc&&fr().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exit(1)});import{readFile as lt,writeFile as N}from"node:fs/promises";import S from"node:path";function ac(e){return typeof e=="string"?{text:e}:e&&typeof e=="object"&&typeof e.text=="string"?{text:e.text}:null}o(ac,"normalizeAssertion");function cc(e){return e.reduce((t,n)=>Array.isArray(n.content)?t+n.content.filter(r=>r?.type==="tool_use").length:t,0)}o(cc,"countToolCalls");function dc(e){return e.reduce((t,n)=>Array.isArray(n.content)?t+n.content.filter(r=>r?.type==="tool_result"&&r.is_error===!0).length:t,0)}o(dc,"countToolErrors");function lc(e,t){return`${["# Skill Eval Transcript","","## Eval Prompt","",e,"","## Final Response","",t.lastText||"(No final text)","","## Result Flags","",`- success: ${t.success}`,`- signal: ${t.signal??"none"}`,`- interrupted: ${t.interrupted===!0}`,`- limit_reached: ${t.limitReached===!0}`].join(`
|
|
679
|
+
`)}
|
|
680
|
+
`}o(lc,"renderTranscript");async function uc(e,t){let n=S.dirname(S.resolve(t.evalsPath)),r=S.resolve(t.cwd??process.cwd()),i=[];for(let s of e??[]){let a=S.isAbsolute(s)?s:S.resolve(n,s),c=S.resolve(r,s),d=null,l=a;try{d=await lt(a,"utf8")}catch{d=await lt(c,"utf8").catch(()=>null),l=c}if(d==null)throw new Error(`Input file not found for eval: ${s}`);i.push(`### ${s}
|
|
681
|
+
\`\`\`
|
|
682
|
+
${d}
|
|
683
|
+
\`\`\`
|
|
684
|
+
(Resolved from ${l})`)}return i.length===0?"":`## Input Files
|
|
685
|
+
|
|
686
|
+
${i.join(`
|
|
687
|
+
|
|
688
|
+
`)}
|
|
689
|
+
|
|
690
|
+
`}o(uc,"readInputFiles");async function fc(e,t){let n=String(e.prompt??e.query??"").trim();return`${await uc(e.files,t)}${n}`.trim()}o(fc,"buildEvalPrompt");async function pc(e,t){let{runKodaX:n,estimateTokens:r}=await j(),i=Date.now(),s=await n({provider:t.provider??"anthropic",model:t.model,maxIter:t.maxIter??30,reasoningMode:t.reasoningMode??"off",thinking:t.reasoningMode?t.reasoningMode!=="off":!1,context:{gitRoot:S.resolve(t.cwd??process.cwd())}},e);return{result:s,totalTokens:r(s.messages),durationMs:Date.now()-i}}o(pc,"defaultRunAgent");async function mc(e,t,n,r){return e==="with_skill"?(await at(t,n,{workingDirectory:S.resolve(r.cwd??process.cwd()),projectRoot:S.resolve(r.cwd??process.cwd()),sessionId:"skill-eval",environment:{}})).content:n}o(mc,"prepareConfigPrompt");async function hc(e,t,n,r,i){let s=S.join(e,"outputs");await A(s);let a={total_tool_calls:cc(i.result.messages),errors_encountered:dc(i.result.messages),output_chars:i.result.lastText.length};await N(S.join(s,"result.md"),`${i.result.lastText}
|
|
691
|
+
`,"utf8"),await N(S.join(s,"prompt.txt"),`${r}
|
|
692
|
+
`,"utf8"),await N(S.join(e,"transcript.md"),lc(r,i.result),"utf8"),await N(S.join(s,"metrics.json"),`${JSON.stringify({config:t,eval_id:n.id??null,session_id:i.result.sessionId,...a},null,2)}
|
|
693
|
+
`,"utf8"),await N(S.join(s,"messages.json"),`${JSON.stringify(i.result.messages,null,2)}
|
|
694
|
+
`,"utf8"),await N(S.join(e,"timing.json"),`${JSON.stringify({total_tokens:i.totalTokens,duration_ms:i.durationMs,total_duration_seconds:Number((i.durationMs/1e3).toFixed(4))},null,2)}
|
|
695
|
+
`,"utf8"),await N(S.join(e,"result.json"),`${JSON.stringify({success:i.result.success,signal:i.result.signal??null,signal_reason:i.result.signalReason??null,interrupted:i.result.interrupted===!0,limit_reached:i.result.limitReached===!0,session_id:i.result.sessionId,execution_metrics:a},null,2)}
|
|
696
|
+
`,"utf8")}o(hc,"writeRunArtifacts");async function gc(e,t=pc){let n=await xe(S.resolve(e.skillPath),"user");if(!n)throw new Error(`Failed to load skill from ${e.skillPath}`);let r=S.resolve(e.workspaceDir);await A(r);let i=JSON.parse(await lt(e.evalsPath,"utf8")),s=Array.isArray(i.evals)?i.evals:[],a=e.configs?.length?e.configs:["with_skill","without_skill"],c=Number.isFinite(e.runsPerConfig)&&e.runsPerConfig>0?Math.floor(e.runsPerConfig):1,d=[];for(let l=0;l<s.length;l+=1){let u=s[l],f=S.join(r,`eval-${l}`);await A(f),await N(S.join(f,"eval_metadata.json"),`${JSON.stringify({eval_id:u.id??l,eval_name:u.name??`eval-${l}`,prompt:u.prompt??u.query??"",expected_output:u.expected_output??"",assertions:(Array.isArray(u.assertions)?u.assertions:[]).map(ac).filter(Boolean)},null,2)}
|
|
697
|
+
`,"utf8");let m=await fc(u,e),p={};for(let h of a){let x=S.join(f,h);await A(x),p[h]=[];for(let y=1;y<=c;y+=1){let g=S.join(x,`run-${y}`);await A(g);let w=await mc(h,n,m,e),v=await t(w,{...e,configName:h,evalItem:u,runIndex:y});await hc(g,h,u,w,v),p[h].push({run_id:`run-${y}`,session_id:v.result.sessionId,success:v.result.success,total_tokens:v.totalTokens,duration_ms:v.durationMs,output_chars:v.result.lastText.length})}}d.push({eval_id:u.id??l,prompt:u.prompt??u.query??"",configs:p})}return{workspace:r,skill_name:n.name,eval_count:s.length,configs:a,runs_per_config:c,reports:d}}o(gc,"runEvalWorkspace");function yc(e){let t={skillPath:"",evalsPath:"",workspaceDir:"",provider:"anthropic",model:void 0,runsPerConfig:1,maxIter:30,reasoningMode:"off",cwd:process.cwd(),configs:["with_skill","without_skill"],output:void 0};for(let n=2;n<e.length;n+=1){let r=e[n];r==="--skill-path"&&e[n+1]?t.skillPath=e[++n]:r==="--evals"&&e[n+1]?t.evalsPath=e[++n]:r==="--workspace"&&e[n+1]?t.workspaceDir=e[++n]:r==="--provider"&&e[n+1]?t.provider=e[++n]:r==="--model"&&e[n+1]?t.model=e[++n]:r==="--runs"&&e[n+1]?t.runsPerConfig=Number(e[++n]):r==="--max-iter"&&e[n+1]?t.maxIter=Number(e[++n]):r==="--reasoning"&&e[n+1]?t.reasoningMode=e[++n]:r==="--cwd"&&e[n+1]?t.cwd=e[++n]:r==="--configs"&&e[n+1]?t.configs=e[++n].split(",").map(i=>i.trim()).filter(Boolean):r==="--output"&&e[n+1]&&(t.output=e[++n])}return t}o(yc,"parseArgs");async function pr(e=process.argv){let t=yc(e);(!t.skillPath||!t.evalsPath||!t.workspaceDir)&&(console.error("Usage: node scripts/run-eval.js --skill-path <dir> --evals <evals.json> --workspace <dir> [--provider anthropic] [--runs 1]"),process.exit(1));let n=await gc(t),r=`${JSON.stringify(n,null,2)}
|
|
698
|
+
`;t.output?(await N(t.output,r,"utf8"),console.log(`Wrote ${S.resolve(t.output)}`)):process.stdout.write(r)}o(pr,"main");var wc=!1;wc&&pr().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exit(1)});import{readdir as vc,readFile as ut,writeFile as hr}from"node:fs/promises";import k from"node:path";function U(e){return String(e??"").trim()}o(U,"normalizeExpectationText");function gr(e){let n=(Array.isArray(e?.assertions)?e.assertions:[]).map(i=>typeof i=="string"?U(i):i&&typeof i=="object"&&typeof i.text=="string"?U(i.text):"").filter(Boolean);if(n.length>0)return n;let r=U(e?.expected_output);return r?[r]:[]}o(gr,"normalizeExpectedRubric");function ft(e){return Array.isArray(e)?e.map(t=>String(t??"").trim()).filter(Boolean):[]}o(ft,"normalizeStringArray");function mr(e,t){return{text:U(e?.text??t),passed:e?.passed===!0,evidence:U(e?.evidence)}}o(mr,"normalizeExpectationEntry");function bc(e,t){let n=Q(e)??{},r=Array.isArray(n.expectations)?n.expectations:[],i=[],s=new Set;for(let a of t){let c=r.findIndex((d,l)=>s.has(l)?!1:U(d?.text).toLowerCase()===a.toLowerCase());if(c===-1){i.push({text:a,passed:!1,evidence:""});continue}s.add(c),i.push(mr(r[c],a))}if(t.length===0)for(let a of r){let c=mr(a,"");c.text&&i.push(c)}return{overall_summary:U(n.overall_summary),expectations:i,user_notes_summary:{uncertainties:ft(n.user_notes_summary?.uncertainties),needs_review:ft(n.user_notes_summary?.needs_review),workarounds:ft(n.user_notes_summary?.workarounds)}}}o(bc,"normalizeParsedGrading");async function pt(e){return(await vc(e,{withFileTypes:!0}).catch(()=>[])).filter(n=>n.isDirectory()).map(n=>k.join(e,n.name)).sort((n,r)=>n.localeCompare(r))}o(pt,"listDirectories");async function Sc(e){let t=k.dirname(e),n=k.dirname(t),r=k.basename(t),i=k.basename(e),s=k.join(e,"outputs"),a=await P(k.join(n,"eval_metadata.json"),{}),c=await ut(k.join(s,"result.md"),"utf8").catch(()=>""),d=await ut(k.join(s,"prompt.txt"),"utf8").catch(()=>""),l=await ut(k.join(e,"transcript.md"),"utf8").catch(()=>""),u=await P(k.join(s,"metrics.json"),{}),f=await P(k.join(e,"result.json"),{}),m=await P(k.join(e,"timing.json"),{});return{evalDir:n,runDir:e,runId:i,configName:r,evalMetadata:a,outputsDir:s,resultText:c,promptText:d,transcript:l,metrics:u,result:f,timing:m}}o(Sc,"loadRunContext");function kc(e){let t=gr(e.evalMetadata),n=t.length>0?t.map((r,i)=>`${i+1}. ${r}`).join(`
|
|
699
|
+
`):"(No explicit assertions; infer one expectation from expected_output if present.)";return`${e.agentInstructions.trim()}
|
|
700
|
+
|
|
701
|
+
Return JSON with this shape:
|
|
702
|
+
{
|
|
703
|
+
"overall_summary": "short summary",
|
|
704
|
+
"expectations": [
|
|
705
|
+
{
|
|
706
|
+
"text": "expectation text",
|
|
707
|
+
"passed": true,
|
|
708
|
+
"evidence": "short evidence grounded in the output"
|
|
709
|
+
}
|
|
710
|
+
],
|
|
711
|
+
"user_notes_summary": {
|
|
712
|
+
"uncertainties": [],
|
|
713
|
+
"needs_review": [],
|
|
714
|
+
"workarounds": []
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
## Run Metadata
|
|
719
|
+
- eval_id: ${e.evalMetadata.eval_id??"unknown"}
|
|
720
|
+
- eval_name: ${e.evalMetadata.eval_name??"unknown"}
|
|
721
|
+
- config: ${e.configName}
|
|
722
|
+
- run_id: ${e.runId}
|
|
723
|
+
|
|
724
|
+
## Eval Prompt
|
|
725
|
+
${I(e.evalMetadata.prompt??e.promptText,4e3)}
|
|
726
|
+
|
|
727
|
+
## Expected Outcome
|
|
728
|
+
${I(e.evalMetadata.expected_output??"",2e3)}
|
|
729
|
+
|
|
730
|
+
## Assertions
|
|
731
|
+
${n}
|
|
732
|
+
|
|
733
|
+
## Final Output
|
|
734
|
+
${I(e.resultText,12e3)}
|
|
735
|
+
|
|
736
|
+
## Result Flags
|
|
737
|
+
${JSON.stringify({success:e.result.success??null,signal:e.result.signal??null,interrupted:e.result.interrupted??!1,limit_reached:e.result.limit_reached??e.result.limitReached??!1},null,2)}
|
|
738
|
+
|
|
739
|
+
## Execution Metrics
|
|
740
|
+
${JSON.stringify({total_tool_calls:e.metrics.total_tool_calls??e.result.execution_metrics?.total_tool_calls??0,errors_encountered:e.metrics.errors_encountered??e.result.execution_metrics?.errors_encountered??0,output_chars:e.metrics.output_chars??e.result.execution_metrics?.output_chars??e.resultText.length,total_tokens:e.timing.total_tokens??0,total_duration_seconds:e.timing.total_duration_seconds??0},null,2)}
|
|
741
|
+
|
|
742
|
+
## Transcript Excerpt
|
|
743
|
+
${I(e.transcript,5e3)}
|
|
744
|
+
`}o(kc,"buildGradingPrompt");async function yr(e,t){let{runKodaX:n}=await j();return(await n({provider:t.provider??"anthropic",model:t.model,maxIter:t.maxIter??20,reasoningMode:t.reasoningMode??"balanced",thinking:t.reasoningMode?t.reasoningMode!=="off":!0,context:{gitRoot:k.resolve(t.cwd??t.workspaceDir??process.cwd())}},e)).lastText}o(yr,"defaultRunJudge");async function xc(e,t,n=yr){let r=await Sc(k.resolve(e)),i=gr(r.evalMetadata),s=await Z(import.meta.url,"../agents/grader.md"),a=kc({...r,agentInstructions:s}),c=await n(a,{...t,runDir:r.runDir,configName:r.configName,evalMetadata:r.evalMetadata,runId:r.runId}),d=bc(c,i),l={total_tool_calls:r.metrics.total_tool_calls??r.result.execution_metrics?.total_tool_calls??0,errors_encountered:r.metrics.errors_encountered??r.result.execution_metrics?.errors_encountered??0,output_chars:r.metrics.output_chars??r.result.execution_metrics?.output_chars??r.resultText.length},u={summary:cr(d.expectations),expectations:d.expectations,execution_metrics:l,user_notes_summary:d.user_notes_summary,overall_summary:d.overall_summary,timing:{total_tokens:r.timing.total_tokens??0,total_duration_seconds:r.timing.total_duration_seconds??0},meta:{generated_at:new Date().toISOString(),eval_id:r.evalMetadata.eval_id??null,eval_name:r.evalMetadata.eval_name??null,config:r.configName,run_id:r.runId}};return await hr(k.join(r.runDir,"grading.json"),`${JSON.stringify(u,null,2)}
|
|
745
|
+
`,"utf8"),{runDir:r.runDir,grading:u,prompt:a,rawResponse:c}}o(xc,"gradeRun");async function Ec(e,t=yr){let n=k.resolve(e.workspaceDir);await A(n);let r=new Set((e.configs??[]).map(c=>String(c).trim()).filter(Boolean)),i=[],s=[];for(let c of await pt(n))if(k.basename(c).startsWith("eval-"))for(let d of await pt(c)){let l=k.basename(d);if(!(r.size>0&&!r.has(l)))for(let u of await pt(d)){if(!k.basename(u).startsWith("run-"))continue;let f=k.join(u,"grading.json");if(await P(f,null)&&e.overwrite!==!0){s.push(k.relative(n,u).replace(/\\/g,"/"));continue}let p=await xc(u,e,t);i.push({run:k.relative(n,u).replace(/\\/g,"/"),summary:p.grading.summary,config:p.grading.meta.config,eval_id:p.grading.meta.eval_id})}}let a={workspace:n,generated_at:new Date().toISOString(),processed:i.length,skipped:s.length,processed_runs:i,skipped_runs:s};return await hr(k.join(n,"grading-summary.json"),`${JSON.stringify(a,null,2)}
|
|
746
|
+
`,"utf8"),a}o(Ec,"gradeWorkspace");function Rc(e){let t={workspaceDir:e[2]??"",provider:"anthropic",model:void 0,reasoningMode:"balanced",maxIter:20,cwd:process.cwd(),overwrite:!1,configs:[]};for(let n=3;n<e.length;n+=1){let r=e[n];r==="--provider"&&e[n+1]?t.provider=e[++n]:r==="--model"&&e[n+1]?t.model=e[++n]:r==="--reasoning"&&e[n+1]?t.reasoningMode=e[++n]:r==="--max-iter"&&e[n+1]?t.maxIter=Number(e[++n]):r==="--cwd"&&e[n+1]?t.cwd=e[++n]:r==="--overwrite"?t.overwrite=!0:r==="--configs"&&e[n+1]&&(t.configs=e[++n].split(",").map(i=>i.trim()).filter(Boolean))}return t}o(Rc,"parseArgs");async function wr(e=process.argv){let t=Rc(e);t.workspaceDir||(console.error("Usage: node scripts/grade-evals.js <workspace> [--provider anthropic] [--configs with_skill,without_skill] [--overwrite]"),process.exit(1));let n=await Ec(t);process.stdout.write(`${JSON.stringify(n,null,2)}
|
|
747
|
+
`)}o(wr,"main");var Ic=!1;Ic&&wr().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exit(1)});import{writeFile as yt}from"node:fs/promises";import D from"node:path";import{readFile as Ac,readdir as Cc,stat as Tc,writeFile as vr}from"node:fs/promises";import C from"node:path";async function mt(e){return JSON.parse(await Ac(e,"utf8"))}o(mt,"readJson");async function _c(e){try{return await Tc(e),!0}catch{return!1}}o(_c,"pathExists");async function ht(e){return(await Cc(e,{withFileTypes:!0}).catch(()=>[])).filter(n=>n.isDirectory()).map(n=>C.join(e,n.name)).sort((n,r)=>n.localeCompare(r))}o(ht,"listDirectories");async function Me(e){let t=await _c(C.join(e,"runs"))?C.join(e,"runs"):e,n=(await ht(t)).filter(i=>C.basename(i).startsWith("eval-")),r={};for(let i of n){let s=C.join(i,"eval_metadata.json"),c=(await mt(s).catch(()=>({}))).eval_id??C.basename(i);for(let d of await ht(i)){let l=C.basename(d),u=(await ht(d)).filter(f=>C.basename(f).startsWith("run-"));if(u.length!==0){r[l]??=[];for(let f of u){let m=await mt(C.join(f,"grading.json")).catch(()=>null);if(!m)continue;let p=await mt(C.join(f,"timing.json")).catch(()=>({}));r[l].push({eval_id:c,run_id:C.basename(f),pass_rate:m.summary?.pass_rate??0,passed:m.summary?.passed??0,failed:m.summary?.failed??0,total:m.summary?.total??0,time_seconds:p.total_duration_seconds??m.timing?.total_duration_seconds??0,tokens:p.total_tokens??m.execution_metrics?.output_chars??0,tool_calls:m.execution_metrics?.total_tool_calls??0,errors:m.execution_metrics?.errors_encountered??0,expectations:Array.isArray(m.expectations)?m.expectations:[],notes:[...m.user_notes_summary?.uncertainties??[],...m.user_notes_summary?.needs_review??[],...m.user_notes_summary?.workarounds??[]]})}}}}return r}o(Me,"loadRunResults");function Pc(e){let t={};for(let[s,a]of Object.entries(e))t[s]={pass_rate:_e(a.map(c=>Number(c.pass_rate??0))),time_seconds:_e(a.map(c=>Number(c.time_seconds??0))),tokens:_e(a.map(c=>Number(c.tokens??0)))};let n=Object.keys(t),r=t[n[0]]??{pass_rate:{mean:0},time_seconds:{mean:0},tokens:{mean:0}},i=t[n[1]]??{pass_rate:{mean:0},time_seconds:{mean:0},tokens:{mean:0}};return{configs:t,delta:{pass_rate:Pe(r.pass_rate.mean-i.pass_rate.mean),time_seconds:Pe(r.time_seconds.mean-i.time_seconds.mean),tokens:Pe(r.tokens.mean-i.tokens.mean)}}}o(Pc,"summarizeConfigs");function gt(e,t,n){let r=Pc(n);return{skill_name:t,generated_at:new Date().toISOString(),workspace:C.resolve(e),configs:r.configs,delta:r.delta,runs:n}}o(gt,"buildBenchmarkDocument");function Mc(e){let t=[`# Benchmark: ${e.skill_name}`,"",`Generated: ${e.generated_at}`,"","| Config | Pass Rate | Time (s) | Tokens |","| --- | --- | --- | --- |"];for(let[n,r]of Object.entries(e.configs))t.push(`| ${n} | ${r.pass_rate.mean} \xB1 ${r.pass_rate.stddev} | ${r.time_seconds.mean} \xB1 ${r.time_seconds.stddev} | ${r.tokens.mean} \xB1 ${r.tokens.stddev} |`);return t.push(""),t.push("## Delta"),t.push(""),t.push(`- Pass rate: ${e.delta.pass_rate}`),t.push(`- Time (s): ${e.delta.time_seconds}`),t.push(`- Tokens: ${e.delta.tokens}`),t.join(`
|
|
748
|
+
`)}o(Mc,"renderBenchmarkMarkdown");function Oc(e){let t={iterationDir:e[2],skillName:"unknown-skill"};for(let n=3;n<e.length;n+=1)e[n]==="--skill-name"&&e[n+1]&&(t.skillName=e[n+1],n+=1);return t}o(Oc,"parseArgs");async function $c(){let{iterationDir:e,skillName:t}=Oc(process.argv);e||(console.error("Usage: node scripts/aggregate-benchmark.js <iteration-dir> --skill-name <name>"),process.exit(1));let n=await Me(e);Object.keys(n).length===0&&(console.error(`No benchmark runs found in ${e}`),process.exit(1));let r=gt(e,t,n),i=C.join(e,"benchmark.json"),s=C.join(e,"benchmark.md");await vr(i,JSON.stringify(r,null,2)),await vr(s,`${Mc(r)}
|
|
749
|
+
`),console.log(`Wrote ${i}`),console.log(`Wrote ${s}`)}o($c,"main");var Nc=!1;Nc&&$c().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exit(1)});function Oe(e){return Array.isArray(e)?e.map(t=>String(t??"").trim()).filter(Boolean):[]}o(Oe,"normalizeStringArray");function Dc(e){let t={};for(let[n,r]of Object.entries(e)){let i=new Map,s=[];for(let a of r){for(let c of a.expectations??[]){if(c?.passed===!0)continue;let d=String(c?.text??"").trim();d&&i.set(d,(i.get(d)??0)+1)}for(let c of a.notes??[]){let d=String(c??"").trim();d&&s.push(d)}}t[n]={repeated_failures:Array.from(i.entries()).sort((a,c)=>c[1]-a[1]).slice(0,10).map(([a,c])=>({text:a,count:c})),notes:s.slice(0,10)}}return t}o(Dc,"summarizeFailureClusters");function Lc(e,t,n){let r=Q(e)??{};return{skill_name:t.skill_name,generated_at:new Date().toISOString(),workspace:t.workspace,verdict:["improves","regresses","mixed","inconclusive"].includes(r.verdict)?r.verdict:"inconclusive",release_readiness:["ready","needs_iteration","needs_manual_review"].includes(r.release_readiness)?r.release_readiness:"needs_manual_review",recommendation:String(r.recommendation??"").trim(),key_findings:Oe(r.key_findings),variance_hotspots:Oe(r.variance_hotspots),suggested_actions:Oe(r.suggested_actions),watchouts:Oe(r.watchouts),supporting_metrics:{pass_rate_delta:t.delta?.pass_rate??"n/a",time_seconds_delta:t.delta?.time_seconds??"n/a",tokens_delta:t.delta?.tokens??"n/a"},failure_clusters:n}}o(Lc,"normalizeAnalysisResult");function jc(e){return`${e.agentInstructions.trim()}
|
|
750
|
+
|
|
751
|
+
Return JSON with this shape:
|
|
752
|
+
{
|
|
753
|
+
"verdict": "improves | regresses | mixed | inconclusive",
|
|
754
|
+
"release_readiness": "ready | needs_iteration | needs_manual_review",
|
|
755
|
+
"recommendation": "short recommendation",
|
|
756
|
+
"key_findings": [],
|
|
757
|
+
"variance_hotspots": [],
|
|
758
|
+
"suggested_actions": [],
|
|
759
|
+
"watchouts": []
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
## Benchmark Summary
|
|
763
|
+
${I(JSON.stringify({skill_name:e.benchmark.skill_name,configs:e.benchmark.configs,delta:e.benchmark.delta},null,2),12e3)}
|
|
764
|
+
|
|
765
|
+
## Failure Clusters
|
|
766
|
+
${I(JSON.stringify(e.failureClusters,null,2),8e3)}
|
|
767
|
+
`}o(jc,"buildAnalysisPrompt");async function Fc(e,t){let{runKodaX:n}=await j();return(await n({provider:t.provider??"anthropic",model:t.model,maxIter:t.maxIter??20,reasoningMode:t.reasoningMode??"balanced",thinking:t.reasoningMode?t.reasoningMode!=="off":!0,context:{gitRoot:D.resolve(t.cwd??t.workspaceDir??process.cwd())}},e)).lastText}o(Fc,"defaultRunAnalyst");function Kc(e){let t=[`# Benchmark Analysis: ${e.skill_name}`,"",`Generated: ${e.generated_at}`,"",`- Verdict: ${e.verdict}`,`- Release readiness: ${e.release_readiness}`,`- Recommendation: ${e.recommendation||"n/a"}`,""],n=[["key_findings","Key Findings"],["variance_hotspots","Variance Hotspots"],["suggested_actions","Suggested Actions"],["watchouts","Watchouts"]];for(let[r,i]of n){t.push(`## ${i}`),t.push("");let s=Array.isArray(e[r])?e[r]:[];if(s.length===0)t.push("- None");else for(let a of s)t.push(`- ${a}`);t.push("")}return t.push("## Supporting Metrics"),t.push(""),t.push(`- Pass rate delta: ${e.supporting_metrics.pass_rate_delta}`),t.push(`- Time delta: ${e.supporting_metrics.time_seconds_delta}`),t.push(`- Tokens delta: ${e.supporting_metrics.tokens_delta}`),`${t.join(`
|
|
768
|
+
`)}
|
|
769
|
+
`}o(Kc,"renderAnalysisMarkdown");async function Wc(e,t=Fc){let n=D.resolve(e.workspaceDir),r=D.resolve(e.benchmarkPath??D.join(n,"benchmark.json")),i=await P(r,null);if(!i){let p=await Me(n);if(Object.keys(p).length===0)throw new Error(`No benchmark data found in ${n}`);i=gt(n,e.skillName??D.basename(n),p),await yt(r,`${JSON.stringify(i,null,2)}
|
|
770
|
+
`,"utf8")}let s=await Me(n),a=Dc(s),c=await Z(import.meta.url,"../agents/analyzer.md"),d=jc({agentInstructions:c,benchmark:i,failureClusters:a}),l=await t(d,{...e,workspaceDir:n,benchmarkPath:r,benchmark:i}),u=Lc(l,i,a),f=D.resolve(e.outputPath??D.join(n,"analysis.json")),m=D.resolve(e.markdownPath??D.join(n,"analysis.md"));return await yt(f,`${JSON.stringify(u,null,2)}
|
|
771
|
+
`,"utf8"),await yt(m,Kc(u),"utf8"),{analysis:u,prompt:d,rawResponse:l,analysisJsonPath:f,analysisMdPath:m}}o(Wc,"analyzeBenchmark");function Bc(e){let t={workspaceDir:e[2]??"",benchmarkPath:void 0,outputPath:void 0,markdownPath:void 0,skillName:void 0,provider:"anthropic",model:void 0,reasoningMode:"balanced",maxIter:20,cwd:process.cwd()};for(let n=3;n<e.length;n+=1){let r=e[n];r==="--benchmark"&&e[n+1]?t.benchmarkPath=e[++n]:r==="--output"&&e[n+1]?t.outputPath=e[++n]:r==="--markdown"&&e[n+1]?t.markdownPath=e[++n]:r==="--skill-name"&&e[n+1]?t.skillName=e[++n]:r==="--provider"&&e[n+1]?t.provider=e[++n]:r==="--model"&&e[n+1]?t.model=e[++n]:r==="--reasoning"&&e[n+1]?t.reasoningMode=e[++n]:r==="--max-iter"&&e[n+1]?t.maxIter=Number(e[++n]):r==="--cwd"&&e[n+1]&&(t.cwd=e[++n])}return t}o(Bc,"parseArgs");async function br(e=process.argv){let t=Bc(e);t.workspaceDir||(console.error("Usage: node scripts/analyze-benchmark.js <workspace> [--benchmark benchmark.json] [--output analysis.json] [--markdown analysis.md]"),process.exit(1));let n=await Wc(t);process.stdout.write(`${JSON.stringify({analysis:n.analysis,analysis_json:n.analysisJsonPath,analysis_md:n.analysisMdPath},null,2)}
|
|
772
|
+
`)}o(br,"main");var Uc=!1;Uc&&br().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exit(1)});import{readdir as Xc,readFile as Sr,writeFile as kr}from"node:fs/promises";import E from"node:path";async function vt(e){return(await Xc(e,{withFileTypes:!0}).catch(()=>[])).filter(n=>n.isDirectory()).map(n=>E.join(e,n.name)).sort((n,r)=>n.localeCompare(r))}o(vt,"listDirectories");function wt(e){return Array.isArray(e)?e.map(t=>String(t??"").trim()).filter(Boolean):[]}o(wt,"normalizeStringArray");function qc(e){let t=Q(e)??{},n=["A","B","tie","inconclusive"].includes(t.winner)?t.winner:"inconclusive",r=Number(t.confidence);return{winner:n,confidence:Number.isFinite(r)?Math.max(0,Math.min(1,Number(r.toFixed(4)))):0,rationale:String(t.rationale??"").trim(),strengths_a:wt(t.strengths_a),strengths_b:wt(t.strengths_b),risks:wt(t.risks)}}o(qc,"normalizeComparisonResult");async function Hc(e,t,n,r){let i=(await vt(E.join(e,t))).filter(f=>E.basename(f).startsWith("run-")),s=(await vt(E.join(e,n))).filter(f=>E.basename(f).startsWith("run-")),a=i[r],c=s[r];if(!a||!c)return null;let d=await P(E.join(e,"eval_metadata.json"),{}),l=await Sr(E.join(a,"outputs","result.md"),"utf8").catch(()=>""),u=await Sr(E.join(c,"outputs","result.md"),"utf8").catch(()=>"");return{evalDir:e,evalMetadata:d,runA:{runDir:a,runId:E.basename(a),configName:t,output:l},runB:{runDir:c,runId:E.basename(c),configName:n,output:u}}}o(Hc,"loadComparisonPair");function zc(e){let t=e.presentPrimaryFirst?{A:e.runA,B:e.runB}:{A:e.runB,B:e.runA};return`${e.agentInstructions.trim()}
|
|
773
|
+
|
|
774
|
+
Return JSON with this shape:
|
|
775
|
+
{
|
|
776
|
+
"winner": "A | B | tie | inconclusive",
|
|
777
|
+
"confidence": 0.0,
|
|
778
|
+
"rationale": "short explanation",
|
|
779
|
+
"strengths_a": [],
|
|
780
|
+
"strengths_b": [],
|
|
781
|
+
"risks": []
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
Judge only the visible outputs. Do not mention hidden config names in the rationale.
|
|
785
|
+
|
|
786
|
+
## Eval Prompt
|
|
787
|
+
${I(e.evalMetadata.prompt??"",4e3)}
|
|
788
|
+
|
|
789
|
+
## Expected Outcome
|
|
790
|
+
${I(e.evalMetadata.expected_output??"",2e3)}
|
|
791
|
+
|
|
792
|
+
## Assertions
|
|
793
|
+
${I(JSON.stringify(e.evalMetadata.assertions??[],null,2),4e3)}
|
|
794
|
+
|
|
795
|
+
## Candidate A
|
|
796
|
+
${I(t.A.output,12e3)}
|
|
797
|
+
|
|
798
|
+
## Candidate B
|
|
799
|
+
${I(t.B.output,12e3)}
|
|
800
|
+
`}o(zc,"buildComparisonPrompt");async function Gc(e,t){let{runKodaX:n}=await j();return(await n({provider:t.provider??"anthropic",model:t.model,maxIter:t.maxIter??20,reasoningMode:t.reasoningMode??"balanced",thinking:t.reasoningMode?t.reasoningMode!=="off":!0,context:{gitRoot:E.resolve(t.cwd??t.workspaceDir??process.cwd())}},e)).lastText}o(Gc,"defaultRunComparator");function Vc(e,t,n,r){return e==="A"?t?n:r:e==="B"?t?r:n:e}o(Vc,"mapWinnerToConfig");function Jc(e){let t=[`# Blind Comparison: ${e.config_a} vs ${e.config_b}`,"",`Generated: ${e.generated_at}`,"",`- ${e.config_a} wins: ${e.summary.config_a_wins}`,`- ${e.config_b} wins: ${e.summary.config_b_wins}`,`- ties: ${e.summary.ties}`,`- inconclusive: ${e.summary.inconclusive}`,""];for(let n of e.comparisons)t.push(`## Eval ${n.eval_id??n.eval_name??n.index}`),t.push(""),t.push(`- Winner: ${n.winner_config}`),t.push(`- Confidence: ${n.confidence}`),t.push(`- Rationale: ${n.rationale||"n/a"}`),t.push("");return`${t.join(`
|
|
801
|
+
`)}
|
|
802
|
+
`}o(Jc,"renderComparisonMarkdown");async function Yc(e,t=Gc){let n=E.resolve(e.workspaceDir),r=e.configA??"with_skill",i=e.configB??"without_skill",s=Number.isFinite(e.maxPairs)&&e.maxPairs>0?Math.floor(e.maxPairs):Number.POSITIVE_INFINITY,a=await Z(import.meta.url,"../agents/comparator.md"),c=[];for(let f of await vt(n))if(E.basename(f).startsWith("eval-"))for(let m=0;m<s;m+=1){let p=await Hc(f,r,i,m);if(!p)break;let h=c.length%2===0,x=zc({agentInstructions:a,evalMetadata:p.evalMetadata,runA:p.runA,runB:p.runB,presentPrimaryFirst:h}),y=await t(x,{...e,workspaceDir:n,evalDir:f,pairIndex:m,configA:r,configB:i}),g=qc(y),w=Vc(g.winner,h,r,i);c.push({index:c.length+1,eval_id:p.evalMetadata.eval_id??null,eval_name:p.evalMetadata.eval_name??null,run_a:E.relative(n,p.runA.runDir).replace(/\\/g,"/"),run_b:E.relative(n,p.runB.runDir).replace(/\\/g,"/"),presented_as:h?{A:r,B:i}:{A:i,B:r},winner_label:g.winner,winner_config:w,confidence:g.confidence,rationale:g.rationale,strengths_a:g.strengths_a,strengths_b:g.strengths_b,risks:g.risks})}if(c.length===0)throw new Error(`No comparable run pairs found for ${r} vs ${i} in ${n}`);let d={workspace:n,generated_at:new Date().toISOString(),config_a:r,config_b:i,summary:{total_pairs:c.length,config_a_wins:c.filter(f=>f.winner_config===r).length,config_b_wins:c.filter(f=>f.winner_config===i).length,ties:c.filter(f=>f.winner_config==="tie").length,inconclusive:c.filter(f=>f.winner_config==="inconclusive").length},comparisons:c},l=E.resolve(e.outputPath??E.join(n,"comparison.json")),u=E.resolve(e.markdownPath??E.join(n,"comparison.md"));return await kr(l,`${JSON.stringify(d,null,2)}
|
|
803
|
+
`,"utf8"),await kr(u,Jc(d),"utf8"),{document:d,outputPath:l,markdownPath:u}}o(Yc,"compareWorkspace");function Qc(e){let t={workspaceDir:e[2]??"",configA:"with_skill",configB:"without_skill",outputPath:void 0,markdownPath:void 0,provider:"anthropic",model:void 0,reasoningMode:"balanced",maxIter:20,maxPairs:void 0,cwd:process.cwd()};for(let n=3;n<e.length;n+=1){let r=e[n];r==="--config-a"&&e[n+1]?t.configA=e[++n]:r==="--config-b"&&e[n+1]?t.configB=e[++n]:r==="--output"&&e[n+1]?t.outputPath=e[++n]:r==="--markdown"&&e[n+1]?t.markdownPath=e[++n]:r==="--provider"&&e[n+1]?t.provider=e[++n]:r==="--model"&&e[n+1]?t.model=e[++n]:r==="--reasoning"&&e[n+1]?t.reasoningMode=e[++n]:r==="--max-iter"&&e[n+1]?t.maxIter=Number(e[++n]):r==="--max-pairs"&&e[n+1]?t.maxPairs=Number(e[++n]):r==="--cwd"&&e[n+1]&&(t.cwd=e[++n])}return t}o(Qc,"parseArgs");async function xr(e=process.argv){let t=Qc(e);t.workspaceDir||(console.error("Usage: node scripts/compare-runs.js <workspace> [--config-a with_skill] [--config-b without_skill] [--output comparison.json]"),process.exit(1));let n=await Yc(t);process.stdout.write(`${JSON.stringify({comparison:n.document.summary,output:n.outputPath,markdown:n.markdownPath},null,2)}
|
|
804
|
+
`)}o(xr,"main");var Zc=!1;Zc&&xr().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exit(1)});import{readFile as ed,writeFile as td}from"node:fs/promises";import{createHash as nd}from"node:crypto";import bt from"node:path";import{zipSync as rd,strToU8 as od}from"fflate";var id=".kodax-package.json";function sd(e){return e instanceof Uint8Array?e:new Uint8Array(e)}o(sd,"toUint8Array");function ad(e){return nd("sha256").update(e).digest("hex")}o(ad,"sha256");function cd(e,t,n={}){return{format:"kodax-skill-package",version:1,created_at:n.createdAt??new Date().toISOString(),entrypoint:"SKILL.md",skill:{name:e.frontmatter.name,description:e.frontmatter.description,compatibility:e.frontmatter.compatibility??null,user_invocable:e.frontmatter["user-invocable"]??!0,disable_model_invocation:e.frontmatter["disable-model-invocation"]??!1},files:t.map(r=>({path:r.relativePath,size:r.bytes.length,sha256:r.sha256})),note:"This archive is a zip file with a .skill extension. Compatible agents can extract and install the included skill directory."}}o(cd,"createPackageManifest");async function dd(e,t={}){let n=await pe(e);if(!n.valid)throw new Error(`Cannot package invalid skill:
|
|
805
|
+
- ${n.errors.join(`
|
|
806
|
+
- `)}`);let r=await le(e),i=await dt(e),s=[];for(let d of i){if(d.relativePath.endsWith(".skill"))continue;let l=sd(await ed(d.absolutePath));s.push({...d,bytes:l,sha256:ad(l)})}let a=cd(r,s,t),c={[id]:od(JSON.stringify(a,null,2))};for(let d of s)c[d.relativePath]=d.bytes;return{manifest:a,bytes:rd(c,{level:6})}}o(dd,"buildSkillPackage");async function ld(e,t,n={}){let r=await dd(e,n);return await td(t,r.bytes),{...r,outputPath:bt.resolve(t)}}o(ld,"writeSkillPackage");function ud(e){let t={skillDir:e[2],output:void 0};for(let n=3;n<e.length;n+=1)e[n]==="--output"&&e[n+1]&&(t.output=e[++n]);return t}o(ud,"parseArgs");async function Er(e=process.argv){let t=ud(e);t.skillDir||(console.error("Usage: node scripts/package-skill.js <skill-dir> [--output <file.skill>]"),process.exit(1));let n=await le(t.skillDir),r=t.output??bt.join(bt.dirname(t.skillDir),`${n.frontmatter.name}.skill`),i=await ld(t.skillDir,r);console.log(`Wrote ${i.outputPath}`)}o(Er,"main");var fd=!1;fd&&Er().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exit(1)});import{cp as pd,mkdir as St,readFile as Ar,rm as Cr,stat as md,writeFile as hd}from"node:fs/promises";import M from"node:path";import{strFromU8 as Rr,unzipSync as gd}from"fflate";var Ir=".kodax-package.json";function yd(e){return e.replace(/\\/g,"/").replace(/^\.?\//,"")}o(yd,"normalizeArchivePath");function wd(e){let t=yd(e);if(!t||t.startsWith("/")||t.includes("../"))throw new Error(`Unsafe archive entry path: ${e}`);return t}o(wd,"assertSafeArchivePath");function vd(e){return/\.(skill|zip)$/i.test(e)}o(vd,"isZipLike");function bd(e){let t=gd(e),n=Object.entries(t).map(([l,u])=>({relativePath:wd(l),bytes:u})),r=n.find(l=>l.relativePath==="SKILL.md");if(!r)throw new Error("Archive is missing SKILL.md");let i=Te(Rr(r.bytes)),s=typeof i.frontmatter.name=="string"?i.frontmatter.name.trim():"",a=typeof i.frontmatter.description=="string"?i.frontmatter.description.trim():"";if(!s||!a)throw new Error("Archive SKILL.md is missing required frontmatter fields.");let c=n.find(l=>l.relativePath===Ir),d=c?JSON.parse(Rr(c.bytes)):null;return{skillName:s,manifest:d,entries:n.filter(l=>l.relativePath!==Ir)}}o(bd,"readSkillPackageBuffer");async function Sd(e,t){if(await ue(e)){if(!t)throw new Error(`Target skill already exists: ${e}`);await Cr(e,{recursive:!0,force:!0})}await St(e,{recursive:!0})}o(Sd,"ensureInstallTarget");async function kd(e,t={}){let n=M.resolve(t.skillsDir??fe()),r=bd(await Ar(e)),i=M.join(n,r.skillName);await Sd(i,t.force===!0);for(let s of r.entries){let a=M.join(i,s.relativePath);await St(M.dirname(a),{recursive:!0}),await hd(a,s.bytes)}return{skillName:r.skillName,installedTo:i,source:M.resolve(e),manifest:r.manifest}}o(kd,"installSkillArchive");async function xd(e,t={}){let n=await pe(e);if(!n.valid)throw new Error(`Cannot install invalid skill:
|
|
807
|
+
- ${n.errors.join(`
|
|
808
|
+
- `)}`);let r=M.join(e,"SKILL.md"),i=Te(await Ar(r,"utf8")),s=M.resolve(t.skillsDir??fe()),a=M.join(s,i.frontmatter.name);if(await ue(a)){if(!t.force)throw new Error(`Target skill already exists: ${a}`);await Cr(a,{recursive:!0,force:!0})}return await St(s,{recursive:!0}),await pd(e,a,{recursive:!0}),{skillName:i.frontmatter.name,installedTo:a,source:M.resolve(e),manifest:null}}o(xd,"installSkillDirectory");async function Ed(e,t={}){let n=M.resolve(e),r=await md(n).catch(()=>null);if(!r)throw new Error(`Input not found: ${n}`);if(r.isDirectory())return xd(n,t);if(r.isFile()&&vd(n))return kd(n,t);throw new Error("Input must be a skill directory or a .skill/.zip archive.")}o(Ed,"installSkill");function Rd(e){let t={input:e[2],skillsDir:void 0,force:!1};for(let n=3;n<e.length;n+=1){let r=e[n];r==="--dest"&&e[n+1]?t.skillsDir=e[++n]:r==="--force"&&(t.force=!0)}return t}o(Rd,"parseArgs");async function Tr(e=process.argv){let t=Rd(e);t.input||(console.error("Usage: node scripts/install-skill.js <skill-dir-or-archive> [--dest <skills-dir>] [--force]"),process.exit(1));let n=await Ed(t.input,t);console.log(`Installed ${n.skillName} to ${n.installedTo}`)}o(Tr,"main");var Id=!1;Id&&Tr().catch(e=>{console.error(e instanceof Error?e.message:String(e)),process.exit(1)});var kR=1440*60*1e3;var TR=5*6e4;var bI=new Intl.Segmenter("zh-CN",{granularity:"word"});var xA=String.raw`const TOOL_NAME = 'echo_tool';
|
|
809
|
+
const RESOURCE_URI = 'memory://guide';
|
|
810
|
+
const PROMPT_NAME = 'draft_prompt';
|
|
811
|
+
let buffer = '';
|
|
812
|
+
|
|
813
|
+
function writeMessage(payload) {
|
|
814
|
+
process.stdout.write(JSON.stringify(payload) + '\n');
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
function handleRequest(message) {
|
|
818
|
+
const id = message.id;
|
|
819
|
+
const method = message.method;
|
|
820
|
+
const params = message.params || {};
|
|
821
|
+
if (method === 'initialize') {
|
|
822
|
+
writeMessage({
|
|
823
|
+
jsonrpc: '2.0',
|
|
824
|
+
id,
|
|
825
|
+
result: {
|
|
826
|
+
protocolVersion: '2025-11-25',
|
|
827
|
+
capabilities: {
|
|
828
|
+
tools: {},
|
|
829
|
+
resources: {},
|
|
830
|
+
prompts: {},
|
|
831
|
+
},
|
|
832
|
+
serverInfo: {
|
|
833
|
+
name: 'kodax-mcp-test-server',
|
|
834
|
+
version: '1.0.0',
|
|
835
|
+
},
|
|
836
|
+
},
|
|
837
|
+
});
|
|
838
|
+
return;
|
|
839
|
+
}
|
|
840
|
+
if (method === 'tools/list') {
|
|
841
|
+
writeMessage({
|
|
842
|
+
jsonrpc: '2.0',
|
|
843
|
+
id,
|
|
844
|
+
result: {
|
|
845
|
+
tools: [{
|
|
846
|
+
name: TOOL_NAME,
|
|
847
|
+
title: 'Echo Tool',
|
|
848
|
+
description: 'Echo text back from the MCP test server.',
|
|
849
|
+
inputSchema: {
|
|
850
|
+
type: 'object',
|
|
851
|
+
properties: {
|
|
852
|
+
text: { type: 'string' },
|
|
853
|
+
mode: { type: 'string' },
|
|
854
|
+
},
|
|
855
|
+
required: ['text'],
|
|
856
|
+
},
|
|
857
|
+
annotations: {
|
|
858
|
+
destructive: false,
|
|
859
|
+
},
|
|
860
|
+
}],
|
|
861
|
+
},
|
|
862
|
+
});
|
|
863
|
+
return;
|
|
864
|
+
}
|
|
865
|
+
if (method === 'resources/list') {
|
|
866
|
+
writeMessage({
|
|
867
|
+
jsonrpc: '2.0',
|
|
868
|
+
id,
|
|
869
|
+
result: {
|
|
870
|
+
resources: [{
|
|
871
|
+
uri: RESOURCE_URI,
|
|
872
|
+
title: 'Guide Resource',
|
|
873
|
+
description: 'Provides guide text.',
|
|
874
|
+
mimeType: 'text/plain',
|
|
875
|
+
}],
|
|
876
|
+
},
|
|
877
|
+
});
|
|
878
|
+
return;
|
|
879
|
+
}
|
|
880
|
+
if (method === 'prompts/list') {
|
|
881
|
+
writeMessage({
|
|
882
|
+
jsonrpc: '2.0',
|
|
883
|
+
id,
|
|
884
|
+
result: {
|
|
885
|
+
prompts: [{
|
|
886
|
+
name: PROMPT_NAME,
|
|
887
|
+
title: 'Draft Prompt',
|
|
888
|
+
description: 'A simple prompt from the MCP test server.',
|
|
889
|
+
}],
|
|
890
|
+
},
|
|
891
|
+
});
|
|
892
|
+
return;
|
|
893
|
+
}
|
|
894
|
+
if (method === 'tools/call') {
|
|
895
|
+
const args = params.arguments || params.args || {};
|
|
896
|
+
writeMessage({
|
|
897
|
+
jsonrpc: '2.0',
|
|
898
|
+
id,
|
|
899
|
+
result: {
|
|
900
|
+
content: [{
|
|
901
|
+
type: 'text',
|
|
902
|
+
text: 'echo:' + String(args.text || ''),
|
|
903
|
+
}],
|
|
904
|
+
structuredContent: {
|
|
905
|
+
echo: args.text || '',
|
|
906
|
+
mode: args.mode || null,
|
|
907
|
+
},
|
|
908
|
+
},
|
|
909
|
+
});
|
|
910
|
+
return;
|
|
911
|
+
}
|
|
912
|
+
if (method === 'resources/read') {
|
|
913
|
+
const uri = params.uri || params.name || RESOURCE_URI;
|
|
914
|
+
writeMessage({
|
|
915
|
+
jsonrpc: '2.0',
|
|
916
|
+
id,
|
|
917
|
+
result: {
|
|
918
|
+
contents: [{
|
|
919
|
+
uri,
|
|
920
|
+
mimeType: 'text/plain',
|
|
921
|
+
text: 'resource:' + String(uri),
|
|
922
|
+
}],
|
|
923
|
+
},
|
|
924
|
+
});
|
|
925
|
+
return;
|
|
926
|
+
}
|
|
927
|
+
if (method === 'prompts/get') {
|
|
928
|
+
const args = params.arguments || params.args || {};
|
|
929
|
+
const topic = args.topic || 'none';
|
|
930
|
+
writeMessage({
|
|
931
|
+
jsonrpc: '2.0',
|
|
932
|
+
id,
|
|
933
|
+
result: {
|
|
934
|
+
description: 'Prompt result for ' + String(params.name || PROMPT_NAME),
|
|
935
|
+
messages: [{
|
|
936
|
+
role: 'user',
|
|
937
|
+
content: {
|
|
938
|
+
type: 'text',
|
|
939
|
+
text: 'prompt:' + String(params.name || PROMPT_NAME) + ':' + String(topic),
|
|
940
|
+
},
|
|
941
|
+
}],
|
|
942
|
+
},
|
|
943
|
+
});
|
|
944
|
+
return;
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
writeMessage({
|
|
948
|
+
jsonrpc: '2.0',
|
|
949
|
+
id,
|
|
950
|
+
error: {
|
|
951
|
+
code: -32601,
|
|
952
|
+
message: 'Method not found: ' + String(method),
|
|
953
|
+
},
|
|
954
|
+
});
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
function handleFrame(raw) {
|
|
958
|
+
let message;
|
|
959
|
+
try {
|
|
960
|
+
message = JSON.parse(raw);
|
|
961
|
+
} catch (error) {
|
|
962
|
+
process.stderr.write('bad json: ' + String(error) + '\n');
|
|
963
|
+
return;
|
|
964
|
+
}
|
|
965
|
+
if (message.id !== undefined) {
|
|
966
|
+
handleRequest(message);
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
process.stdin.setEncoding('utf8');
|
|
971
|
+
process.stdin.on('data', (chunk) => {
|
|
972
|
+
buffer += chunk;
|
|
973
|
+
while (true) {
|
|
974
|
+
const lineEnd = buffer.indexOf('\n');
|
|
975
|
+
if (lineEnd < 0) {
|
|
976
|
+
return;
|
|
977
|
+
}
|
|
978
|
+
const line = buffer.slice(0, lineEnd).replace(/\r$/, '').trim();
|
|
979
|
+
buffer = buffer.slice(lineEnd + 1);
|
|
980
|
+
if (line) {
|
|
981
|
+
handleFrame(line);
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
});
|
|
985
|
+
|
|
986
|
+
process.on('SIGTERM', () => process.exit(0));
|
|
987
|
+
process.on('SIGINT', () => process.exit(0));
|
|
988
|
+
`;var Or=Object.freeze(["message","label","compaction","branch_summary","archive_marker","rewind_marker","artifact_ledger","memory_outcome_digest","memory_review_receipt"]),Gd=0,Vd=0,$r=o(e=>{let t=e==="label"?++Gd:++Vd,n=Math.random().toString(36).slice(2,8);return`${e}-${Date.now()}-${t}-${n}`},"nextId");async function Jd(e,t,n){let r=$r("label");return await e.append({id:r,ts:Date.now(),type:"label",payload:{targetId:t,label:n}}),r}o(Jd,"appendLabel");async function Yd(e,t,n){let r=$r("artifact");return await e.append({id:r,ts:Date.now(),type:"artifact_ledger",payload:{ref:t,summary:n}}),r}o(Yd,"appendArtifact");function Qd(e){let t=[],n=new Map,r=[],i=null;for(let s of e){if(s.type==="label"){let c=s.payload;c?.targetId&&r.push({targetId:c.targetId,label:c.label});continue}let a={entry:s,children:[]};if(s.type==="message"){t.push(a),n.set(s.id,a),i=a;continue}i?i.children.push(a):t.push(a)}for(let{targetId:s,label:a}of r){let c=n.get(s);c&&a!==void 0&&(c.label=a)}return t}o(Qd,"buildLineageTree");var Zd=Object.freeze({name:"lineage",entryTypes:Or,operators:Object.freeze({label:o((async(e,...t)=>{let[n,r]=t;return Jd(e,n,r)}),"label"),attachArtifact:o((async(e,...t)=>{let[n,r]=t;return Yd(e,n,r)}),"attachArtifact")}),reducers:Object.freeze({buildLineageTree:o(e=>Qd(e),"buildLineageTree")})});var cl=new Set(["skill","ask_user_question","exit_plan_mode","spawn_agent","send_message","followup_task","wait_agent","interrupt_agent","list_agents","agent_output","tool_search","get_goal","create_goal","update_goal","todo_create","todo_update","todo_list","todo_get","worktree_create","worktree_remove","undo","mcp_search","mcp_describe","mcp_call","mcp_read_resource","mcp_get_prompt","repo_overview","changed_scope","changed_diff","changed_diff_bundle","module_context","symbol_context","process_context","impact_estimate","relationship_scan","cyclic_dependencies","semantic_lookup"]),xt=cl,$e=`[\u5BF9\u8BDD\u5386\u53F2\u6458\u8981]
|
|
989
|
+
|
|
990
|
+
`;var WC=$e.trimEnd();var BC=16*1024;var pl={enabled:!1,maxAge:20,protectedTools:Array.from(xt)};import{createRequire as vl}from"node:module";var bl=vl(import.meta.url),Kr,J_=new Proxy({},{get(e,t){return Kr??=bl("typescript"),Reflect.get(Kr,t)}});var f0=new Intl.Segmenter("en",{granularity:"grapheme"});function Bl(e){let t=e.code;return t==="ENOENT"||t==="ENOTDIR"}o(Bl,"isMissingGitTrustPath");function Ul(e,t,n){try{let r=t(e).replaceAll("\\","/").replace(/\/+$/,"");return r===""?void 0:/^[A-Za-z]:$/.test(r)?`${r}/`:r}catch(r){if(n(r))return;throw r}}o(Ul,"normalizeGitSafeDirectoryRootImplementation");function Xl(e,t,n,r){try{let s=t(n.join(e,".git"));if(s.isDirectory()||s.isFile())return!0}catch(s){if(!r(s))throw s}if(!(n.basename(e).toLowerCase()===".git"||/[/\\]\.git[/\\]modules[/\\]/i.test(e)))return!1;try{return t(n.join(e,"HEAD")).isFile()}catch(s){if(r(s))return!1;throw s}}o(Xl,"isRepoBearingGitReadRootImplementation");function ql(e,t,n,r,i){let s=[];typeof e=="string"&&e!==""&&s.push(e);for(let d of n??[])i(d)&&s.push(d);s.push(...t??[]);let a=[],c=new Set;for(let d of s){if(a.length>=8)break;let l=r(d);if(l===void 0)continue;let u=l.toLowerCase();c.has(u)||(c.add(u),a.push(l))}return a}o(ql,"windowsGitTrustRootsImplementation");function Hl(e){if(e==="git_config_count")return"count";if(/^git_config_key_\d+$/.test(e))return"key";if(/^git_config_value_\d+$/.test(e))return"value"}o(Hl,"gitConfigEnvKind");function zl(e,t,n,r,i){let s=new Map,a=[],c,d=!1;for(let l=0;l<t;l+=1){if(e[l]!=="--env"||l+1>=t)continue;let u=e[l+1],f=u.indexOf("="),m=(f<0?u:u.slice(0,f)).toLowerCase(),p=n(m);if(p===void 0)continue;d=!0,a.push(l);let h=f<0?"":u.slice(f+1);if(p==="count"){let g=Number.parseInt(h,10);(c!==void 0||!Number.isSafeInteger(g)||g<0||String(g)!==h)&&r(),c=g;continue}let x=Number.parseInt(m.slice(`git_config_${p}_`.length),10),y=s.get(x)??{};(!Number.isSafeInteger(x)||x<0||y[p]!==void 0)&&r(),y[p]=h,s.set(x,y)}return i(s,a,c,d,r)}o(zl,"parseGitConfigEnvironmentImplementation");function Gl(){throw new Error("ASRT GIT_CONFIG environment has an unexpected shape.")}o(Gl,"throwUnexpectedGitConfigShape");function Vl(e,t,n,r,i){!r||n!==void 0&&e.size===n&&[...e].every(([c,d])=>c<n&&d.key!==void 0&&d.value!==void 0)||i();let a=[...e].map(([c,d])=>({slot:c,key:d.key,value:d.value}));return{argumentIndices:t,pairs:a,sawAny:r}}o(Vl,"finishParsedGitConfigEnvironment");function Jl(e,t){let n=[];for(let i of e)n.push({key:"safe.directory",value:i},{key:"safe.directory",value:`${i}/*`});n.push(...t);let r=n.flatMap((i,s)=>[`GIT_CONFIG_KEY_${s}=${i.key}`,`GIT_CONFIG_VALUE_${s}=${i.value}`]);return r.push(`GIT_CONFIG_COUNT=${n.length}`),r}o(Jl,"gitSafeDirectoryAssignments");function Yl(e,t,n,r){let i=new Set(n.argumentIndices),s=[],a=!1;for(let c=0;c<e.length;c+=1)if(i.has(c)){if(!a){for(let d of r)s.push("--env",d);a=!0}c+=1}else s.push(e[c]);return n.sawAny||s.splice(t,0,...r.flatMap(c=>["--env",c])),s}o(Yl,"replaceGitConfigEnvironment");function Ql(e,t,n,r,i){let s=e.lastIndexOf("--");if(s<0)throw new Error("ASRT Windows wrapper omitted its child separator.");let a=n(e,s),c=a.pairs.filter(l=>l.key.toLowerCase()!=="safe.directory").sort((l,u)=>l.slot-u.slot),d=r(t,c);return i(e,s,a,d)}o(Ql,"rewriteWindowsGitSafeDirectoryArgvImplementation");function Br(){return String.raw`
|
|
991
|
+
const isMissingGitTrustPath = ${Bl.toString()};
|
|
992
|
+
const normalizeGitSafeDirectoryRootImplementation = ${Ul.toString()};
|
|
993
|
+
const normalizeGitSafeDirectoryRoot = (root) => (
|
|
994
|
+
normalizeGitSafeDirectoryRootImplementation(root, realpathSync, isMissingGitTrustPath)
|
|
995
|
+
);
|
|
996
|
+
const isRepoBearingGitReadRootImplementation = ${Xl.toString()};
|
|
997
|
+
const isRepoBearingGitReadRoot = (root) => (
|
|
998
|
+
isRepoBearingGitReadRootImplementation(root, statSync, path, isMissingGitTrustPath)
|
|
999
|
+
);
|
|
1000
|
+
const windowsGitTrustRootsImplementation = ${ql.toString()};
|
|
1001
|
+
const windowsGitTrustRoots = (input) => {
|
|
1002
|
+
const filesystem = (input.config && input.config.filesystem) || {};
|
|
1003
|
+
return windowsGitTrustRootsImplementation(
|
|
1004
|
+
input.cwd,
|
|
1005
|
+
filesystem.allowWrite,
|
|
1006
|
+
filesystem.allowRead,
|
|
1007
|
+
normalizeGitSafeDirectoryRoot,
|
|
1008
|
+
isRepoBearingGitReadRoot,
|
|
1009
|
+
);
|
|
1010
|
+
};
|
|
1011
|
+
const gitConfigEnvKind = ${Hl.toString()};
|
|
1012
|
+
const throwUnexpectedGitConfigShape = ${Gl.toString()};
|
|
1013
|
+
const finishParsedGitConfigEnvironment = ${Vl.toString()};
|
|
1014
|
+
const parseGitConfigEnvironmentImplementation = ${zl.toString()};
|
|
1015
|
+
const parseGitConfigEnvironment = (argv, separator) => (
|
|
1016
|
+
parseGitConfigEnvironmentImplementation(
|
|
1017
|
+
argv,
|
|
1018
|
+
separator,
|
|
1019
|
+
gitConfigEnvKind,
|
|
1020
|
+
throwUnexpectedGitConfigShape,
|
|
1021
|
+
finishParsedGitConfigEnvironment,
|
|
1022
|
+
)
|
|
1023
|
+
);
|
|
1024
|
+
const gitSafeDirectoryAssignments = ${Jl.toString()};
|
|
1025
|
+
const replaceGitConfigEnvironment = ${Yl.toString()};
|
|
1026
|
+
const rewriteWindowsGitSafeDirectoryArgvImplementation = ${Ql.toString()};
|
|
1027
|
+
const rewriteWindowsGitSafeDirectoryArgv = (argv, trustRoots) => (
|
|
1028
|
+
rewriteWindowsGitSafeDirectoryArgvImplementation(
|
|
1029
|
+
argv,
|
|
1030
|
+
trustRoots,
|
|
1031
|
+
parseGitConfigEnvironment,
|
|
1032
|
+
gitSafeDirectoryAssignments,
|
|
1033
|
+
replaceGitConfigEnvironment,
|
|
1034
|
+
)
|
|
1035
|
+
);
|
|
1036
|
+
`}o(Br,"windowsGitBrokerHelpersSource");var jO=64*1024*1024;var FO=String.raw`
|
|
1037
|
+
$ErrorActionPreference = 'Stop'
|
|
1038
|
+
$payloadText = [Console]::In.ReadToEnd()
|
|
1039
|
+
if ([Text.Encoding]::UTF8.GetByteCount($payloadText) -gt 90000000) { throw 'payload exceeds bound' }
|
|
1040
|
+
$payload = $payloadText | ConvertFrom-Json
|
|
1041
|
+
$hostSid = [Security.Principal.WindowsIdentity]::GetCurrent().User
|
|
1042
|
+
$systemSid = [Security.Principal.SecurityIdentifier]::new('S-1-5-18')
|
|
1043
|
+
$usersSid = [Security.Principal.SecurityIdentifier]::new('S-1-5-32-545')
|
|
1044
|
+
$sandboxSid = if ([string]::IsNullOrEmpty([string]$payload.sandboxReadSid)) { $null } else { [Security.Principal.SecurityIdentifier]::new([string]$payload.sandboxReadSid) }
|
|
1045
|
+
$localUsersReadExecute = [bool]$payload.localUsersReadExecute
|
|
1046
|
+
$inherit = [Security.AccessControl.InheritanceFlags]::ContainerInherit -bor [Security.AccessControl.InheritanceFlags]::ObjectInherit
|
|
1047
|
+
$none = [Security.AccessControl.PropagationFlags]::None
|
|
1048
|
+
$allow = [Security.AccessControl.AccessControlType]::Allow
|
|
1049
|
+
function New-DirectorySecurity {
|
|
1050
|
+
$security = [Security.AccessControl.DirectorySecurity]::new()
|
|
1051
|
+
$security.SetAccessRuleProtection($true, $false)
|
|
1052
|
+
$security.SetOwner($hostSid)
|
|
1053
|
+
[void]$security.AddAccessRule([Security.AccessControl.FileSystemAccessRule]::new($hostSid, [Security.AccessControl.FileSystemRights]::FullControl, $inherit, $none, $allow))
|
|
1054
|
+
[void]$security.AddAccessRule([Security.AccessControl.FileSystemAccessRule]::new($systemSid, [Security.AccessControl.FileSystemRights]::FullControl, $inherit, $none, $allow))
|
|
1055
|
+
[void]$security.AddAccessRule([Security.AccessControl.FileSystemAccessRule]::new($usersSid, [Security.AccessControl.FileSystemRights]::ReadAndExecute, $inherit, $none, $allow))
|
|
1056
|
+
return $security
|
|
1057
|
+
}
|
|
1058
|
+
function New-FileSecurity {
|
|
1059
|
+
$security = [Security.AccessControl.FileSecurity]::new()
|
|
1060
|
+
$security.SetAccessRuleProtection($true, $false)
|
|
1061
|
+
$security.SetOwner($hostSid)
|
|
1062
|
+
[void]$security.AddAccessRule([Security.AccessControl.FileSystemAccessRule]::new($hostSid, [Security.AccessControl.FileSystemRights]::FullControl, $allow))
|
|
1063
|
+
[void]$security.AddAccessRule([Security.AccessControl.FileSystemAccessRule]::new($systemSid, [Security.AccessControl.FileSystemRights]::FullControl, $allow))
|
|
1064
|
+
if ($localUsersReadExecute) { [void]$security.AddAccessRule([Security.AccessControl.FileSystemAccessRule]::new($usersSid, [Security.AccessControl.FileSystemRights]::ReadAndExecute, $allow)) }
|
|
1065
|
+
elseif ($null -ne $sandboxSid) { [void]$security.AddAccessRule([Security.AccessControl.FileSystemAccessRule]::new($sandboxSid, [Security.AccessControl.FileSystemRights]::ReadAndExecute, $allow)) }
|
|
1066
|
+
return $security
|
|
1067
|
+
}
|
|
1068
|
+
function Assert-NoReparse([string]$candidate) {
|
|
1069
|
+
$item = Get-Item -LiteralPath $candidate -Force
|
|
1070
|
+
if (($item.Attributes -band [IO.FileAttributes]::ReparsePoint) -ne 0) { throw "reparse artifact path: $candidate" }
|
|
1071
|
+
}
|
|
1072
|
+
function Assert-AclShape($acl, [bool]$directory, [string]$candidate) {
|
|
1073
|
+
if (-not $acl.AreAccessRulesProtected -or $acl.GetOwner([Security.Principal.SecurityIdentifier]).Value -ne $hostSid.Value) { throw 'artifact ACL is not protected and host-owned' }
|
|
1074
|
+
$expected = @{}
|
|
1075
|
+
$expected[$hostSid.Value] = [int][Security.AccessControl.FileSystemRights]::FullControl
|
|
1076
|
+
$expected[$systemSid.Value] = [int][Security.AccessControl.FileSystemRights]::FullControl
|
|
1077
|
+
$readExecuteMask = [int]([Security.AccessControl.FileSystemRights]::ReadAndExecute -bor [Security.AccessControl.FileSystemRights]::Synchronize)
|
|
1078
|
+
if ($directory) { $expected[$usersSid.Value] = $readExecuteMask }
|
|
1079
|
+
if (-not $directory -and $localUsersReadExecute) { $expected[$usersSid.Value] = $readExecuteMask }
|
|
1080
|
+
elseif (-not $directory -and $null -ne $sandboxSid) { $expected[$sandboxSid.Value] = $readExecuteMask }
|
|
1081
|
+
$observed = @{}
|
|
1082
|
+
foreach ($rule in $acl.GetAccessRules($true, $true, [Security.Principal.SecurityIdentifier])) {
|
|
1083
|
+
if ($rule.IsInherited) { throw 'artifact ACL contains an inherited rule' }
|
|
1084
|
+
# Native v2 appends execution-specific DENY ACEs to deny-write roots. A
|
|
1085
|
+
# DENY cannot widen access, so it is safe to retain while the exact ALLOW
|
|
1086
|
+
# surface below remains closed and fully verified.
|
|
1087
|
+
if ($rule.AccessControlType -eq [Security.AccessControl.AccessControlType]::Deny) { continue }
|
|
1088
|
+
$sid = $rule.IdentityReference.Value
|
|
1089
|
+
if (-not $expected.ContainsKey($sid) -or $observed.ContainsKey($sid)) { throw "artifact ACL contains an unexpected allow rule for $sid at $candidate" }
|
|
1090
|
+
if ([int]$rule.FileSystemRights -ne $expected[$sid]) { throw "artifact ACL allow mask is invalid for $sid at $candidate" }
|
|
1091
|
+
if ($directory) {
|
|
1092
|
+
if ($rule.InheritanceFlags -ne $inherit -or $rule.PropagationFlags -ne $none) { throw 'artifact directory ACL inheritance is invalid' }
|
|
1093
|
+
} elseif ($rule.InheritanceFlags -ne [Security.AccessControl.InheritanceFlags]::None) {
|
|
1094
|
+
throw 'artifact file ACL inheritance is invalid'
|
|
1095
|
+
}
|
|
1096
|
+
$observed[$sid] = $true
|
|
1097
|
+
}
|
|
1098
|
+
foreach ($sid in $expected.Keys) { if (-not $observed.ContainsKey($sid)) { throw 'artifact ACL is missing a required allow rule' } }
|
|
1099
|
+
}
|
|
1100
|
+
function Ensure-ProtectedDirectory([string]$candidate) {
|
|
1101
|
+
if (Test-Path -LiteralPath $candidate) {
|
|
1102
|
+
Assert-NoReparse $candidate
|
|
1103
|
+
Assert-AclShape ([IO.Directory]::GetAccessControl($candidate)) $true $candidate
|
|
1104
|
+
return
|
|
1105
|
+
}
|
|
1106
|
+
[void][IO.Directory]::CreateDirectory($candidate, (New-DirectorySecurity))
|
|
1107
|
+
Assert-NoReparse $candidate
|
|
1108
|
+
Assert-AclShape ([IO.Directory]::GetAccessControl($candidate)) $true $candidate
|
|
1109
|
+
}
|
|
1110
|
+
$cacheRoot = [IO.Path]::GetFullPath([string]$payload.cacheRoot)
|
|
1111
|
+
$anchor = [IO.Path]::GetFullPath([string]$payload.anchor)
|
|
1112
|
+
$destinationDirectory = [IO.Path]::GetFullPath([string]$payload.destinationDirectory)
|
|
1113
|
+
if (-not $cacheRoot.StartsWith($anchor + [IO.Path]::DirectorySeparatorChar, [StringComparison]::OrdinalIgnoreCase)) { throw 'cache root escaped host LocalAppData' }
|
|
1114
|
+
if (-not $destinationDirectory.StartsWith($cacheRoot + [IO.Path]::DirectorySeparatorChar, [StringComparison]::OrdinalIgnoreCase)) { throw 'destination escaped cache root' }
|
|
1115
|
+
Assert-NoReparse $anchor
|
|
1116
|
+
$current = $anchor
|
|
1117
|
+
$relative = $destinationDirectory.Substring($anchor.Length).TrimStart([IO.Path]::DirectorySeparatorChar)
|
|
1118
|
+
foreach ($part in ($relative -split '[\\/]')) {
|
|
1119
|
+
if ([string]::IsNullOrEmpty($part)) { continue }
|
|
1120
|
+
$current = [IO.Path]::Combine($current, $part)
|
|
1121
|
+
Ensure-ProtectedDirectory $current
|
|
1122
|
+
}
|
|
1123
|
+
$bytes = [Convert]::FromBase64String([string]$payload.bytes)
|
|
1124
|
+
$hash = [Security.Cryptography.SHA256]::Create()
|
|
1125
|
+
try { $actual = ([BitConverter]::ToString($hash.ComputeHash($bytes))).Replace('-', '').ToLowerInvariant() } finally { $hash.Dispose() }
|
|
1126
|
+
if ($actual -ne ([string]$payload.sha256).ToLowerInvariant()) { throw 'provisioning payload hash mismatch' }
|
|
1127
|
+
$destination = [IO.Path]::Combine($destinationDirectory, [string]$payload.file)
|
|
1128
|
+
# Keep the CreateNew staging name short. PowerShell 5.1 FileStream still hits
|
|
1129
|
+
# MAX_PATH on otherwise valid LocalAppData roots before long-path policy is
|
|
1130
|
+
# enabled, while GetRandomFileName retains cross-process collision resistance.
|
|
1131
|
+
$temporary = [IO.Path]::Combine($destinationDirectory, '.' + [IO.Path]::GetRandomFileName() + '.tmp')
|
|
1132
|
+
try {
|
|
1133
|
+
if (-not (Test-Path -LiteralPath $destination)) {
|
|
1134
|
+
$stream = [IO.FileStream]::new($temporary, [IO.FileMode]::CreateNew, [Security.AccessControl.FileSystemRights]::FullControl, [IO.FileShare]::None, 65536, [IO.FileOptions]::WriteThrough, (New-FileSecurity))
|
|
1135
|
+
try { $stream.Write($bytes, 0, $bytes.Length); $stream.Flush($true) } finally { $stream.Dispose() }
|
|
1136
|
+
try { [IO.File]::Move($temporary, $destination) } catch { if (-not (Test-Path -LiteralPath $destination)) { throw } }
|
|
1137
|
+
}
|
|
1138
|
+
Assert-NoReparse $destination
|
|
1139
|
+
Assert-AclShape ([IO.File]::GetAccessControl($destination)) $false $destination
|
|
1140
|
+
# A sibling Runtime may already be executing this content-addressed image.
|
|
1141
|
+
# Verification must share an immutable published file for read/delete or
|
|
1142
|
+
# artifact provisioning itself becomes a cross-Runtime admission lock.
|
|
1143
|
+
$share = [IO.FileShare]::Read -bor [IO.FileShare]::Delete
|
|
1144
|
+
$stream = [IO.FileStream]::new($destination, [IO.FileMode]::Open, [IO.FileAccess]::Read, $share)
|
|
1145
|
+
try {
|
|
1146
|
+
$publishedHasher = [Security.Cryptography.SHA256]::Create()
|
|
1147
|
+
try { $publishedHash = ([BitConverter]::ToString($publishedHasher.ComputeHash($stream))).Replace('-', '').ToLowerInvariant() } finally { $publishedHasher.Dispose() }
|
|
1148
|
+
} finally { $stream.Dispose() }
|
|
1149
|
+
if ($publishedHash -ne $actual) { throw 'published artifact hash mismatch' }
|
|
1150
|
+
[Console]::Out.Write($destination)
|
|
1151
|
+
} finally {
|
|
1152
|
+
if (Test-Path -LiteralPath $temporary) { Remove-Item -LiteralPath $temporary -Force }
|
|
1153
|
+
}
|
|
1154
|
+
`,KO=String.raw`
|
|
1155
|
+
$ErrorActionPreference = 'Stop'
|
|
1156
|
+
$payload = ([Console]::In.ReadToEnd() | ConvertFrom-Json)
|
|
1157
|
+
$hostSid = [Security.Principal.WindowsIdentity]::GetCurrent().User
|
|
1158
|
+
$systemSid = [Security.Principal.SecurityIdentifier]::new('S-1-5-18')
|
|
1159
|
+
$inherit = [Security.AccessControl.InheritanceFlags]::ContainerInherit -bor [Security.AccessControl.InheritanceFlags]::ObjectInherit
|
|
1160
|
+
$none = [Security.AccessControl.PropagationFlags]::None
|
|
1161
|
+
$allow = [Security.AccessControl.AccessControlType]::Allow
|
|
1162
|
+
function Assert-NoReparse([string]$candidate) {
|
|
1163
|
+
$item = Get-Item -LiteralPath $candidate -Force
|
|
1164
|
+
if (($item.Attributes -band [IO.FileAttributes]::ReparsePoint) -ne 0) { throw "reparse control path: $candidate" }
|
|
1165
|
+
}
|
|
1166
|
+
function New-ControlSecurity {
|
|
1167
|
+
$security = [Security.AccessControl.DirectorySecurity]::new()
|
|
1168
|
+
$security.SetAccessRuleProtection($true, $false)
|
|
1169
|
+
$security.SetOwner($hostSid)
|
|
1170
|
+
[void]$security.AddAccessRule([Security.AccessControl.FileSystemAccessRule]::new($hostSid, [Security.AccessControl.FileSystemRights]::FullControl, $inherit, $none, $allow))
|
|
1171
|
+
[void]$security.AddAccessRule([Security.AccessControl.FileSystemAccessRule]::new($systemSid, [Security.AccessControl.FileSystemRights]::FullControl, $inherit, $none, $allow))
|
|
1172
|
+
return $security
|
|
1173
|
+
}
|
|
1174
|
+
function Assert-ControlSecurity([string]$candidate) {
|
|
1175
|
+
$acl = [IO.Directory]::GetAccessControl($candidate)
|
|
1176
|
+
if (-not $acl.AreAccessRulesProtected -or $acl.GetOwner([Security.Principal.SecurityIdentifier]).Value -ne $hostSid.Value) {
|
|
1177
|
+
throw 'control directory ACL is not protected and host-owned'
|
|
1178
|
+
}
|
|
1179
|
+
$expected = @{}
|
|
1180
|
+
$expected[$hostSid.Value] = $true
|
|
1181
|
+
$expected[$systemSid.Value] = $true
|
|
1182
|
+
$observed = @{}
|
|
1183
|
+
foreach ($rule in $acl.GetAccessRules($true, $true, [Security.Principal.SecurityIdentifier])) {
|
|
1184
|
+
if ($rule.IsInherited -or $rule.AccessControlType -ne $allow) { throw 'control directory ACL contains an unexpected rule' }
|
|
1185
|
+
$sid = $rule.IdentityReference.Value
|
|
1186
|
+
if (-not $expected.ContainsKey($sid) -or $observed.ContainsKey($sid)) { throw 'control directory ACL contains an unexpected principal' }
|
|
1187
|
+
if ($rule.FileSystemRights -ne [Security.AccessControl.FileSystemRights]::FullControl -or $rule.InheritanceFlags -ne $inherit -or $rule.PropagationFlags -ne $none) {
|
|
1188
|
+
throw 'control directory ACL rule shape is invalid'
|
|
1189
|
+
}
|
|
1190
|
+
$observed[$sid] = $true
|
|
1191
|
+
}
|
|
1192
|
+
foreach ($sid in $expected.Keys) { if (-not $observed.ContainsKey($sid)) { throw 'control directory ACL is missing a required principal' } }
|
|
1193
|
+
}
|
|
1194
|
+
function Test-ControlOwnerProcessAlive([uint32]$processId) {
|
|
1195
|
+
if ($processId -gt [int]::MaxValue) { return $false }
|
|
1196
|
+
try {
|
|
1197
|
+
return $null -ne [Diagnostics.Process]::GetProcessById([int]$processId)
|
|
1198
|
+
} catch [ArgumentException] {
|
|
1199
|
+
return $false
|
|
1200
|
+
} catch {
|
|
1201
|
+
return $true
|
|
1202
|
+
}
|
|
1203
|
+
}
|
|
1204
|
+
function Remove-ProvenStaleControlEntries([string]$candidate) {
|
|
1205
|
+
$now = [DateTimeOffset]::UtcNow
|
|
1206
|
+
foreach ($entry in [IO.Directory]::EnumerateFiles($candidate)) {
|
|
1207
|
+
$item = Get-Item -LiteralPath $entry -Force
|
|
1208
|
+
if (($item.Attributes -band [IO.FileAttributes]::ReparsePoint) -ne 0 -or $item.Length -gt 1048576) { continue }
|
|
1209
|
+
$match = [regex]::Match($item.Name, '^windows-(shell|network|terminal)-([0-9]+)-[0-9a-fA-F-]{36}\.json$')
|
|
1210
|
+
if (-not $match.Success) { continue }
|
|
1211
|
+
$ownerPid = 0L
|
|
1212
|
+
if (-not [long]::TryParse($match.Groups[2].Value, [ref]$ownerPid) -or $ownerPid -le 0 -or $ownerPid -gt [uint32]::MaxValue) { continue }
|
|
1213
|
+
if (Test-ControlOwnerProcessAlive ([uint32]$ownerPid)) { continue }
|
|
1214
|
+
$kind = $match.Groups[1].Value
|
|
1215
|
+
$retire = $false
|
|
1216
|
+
if ($kind -eq 'network') {
|
|
1217
|
+
# A network request is deleted as soon as its broker reads it. A dead
|
|
1218
|
+
# creator plus two launch budgets proves this file was never admitted.
|
|
1219
|
+
$retire = $item.LastWriteTimeUtc -lt $now.UtcDateTime.AddMinutes(-1)
|
|
1220
|
+
} else {
|
|
1221
|
+
try { $record = ([IO.File]::ReadAllText($entry) | ConvertFrom-Json) } catch { continue }
|
|
1222
|
+
if ($kind -eq 'shell') {
|
|
1223
|
+
$deadline = 0L
|
|
1224
|
+
$retire = [long]::TryParse([string]$record.operationDeadlineUnixMs, [ref]$deadline) -and $deadline -lt $now.ToUnixTimeMilliseconds()
|
|
1225
|
+
} else {
|
|
1226
|
+
# A terminal record is disposable only after native Job drainage was
|
|
1227
|
+
# durably observed. Unknown or partial records remain fail-closed.
|
|
1228
|
+
$retire = $record.jobDrained -eq $true
|
|
1229
|
+
}
|
|
1230
|
+
}
|
|
1231
|
+
if ($retire) { [IO.File]::Delete($entry) }
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
1234
|
+
$cacheRoot = [IO.Path]::GetFullPath([string]$payload.cacheRoot)
|
|
1235
|
+
$controlRoot = [IO.Path]::GetFullPath([string]$payload.controlRoot)
|
|
1236
|
+
$action = [string]$payload.action
|
|
1237
|
+
if ([IO.Path]::GetDirectoryName($controlRoot) -ne $cacheRoot) { throw 'control directory escaped native cache root' }
|
|
1238
|
+
if (-not (Test-Path -LiteralPath $cacheRoot -PathType Container)) { throw 'protected native cache root is unavailable' }
|
|
1239
|
+
Assert-NoReparse $cacheRoot
|
|
1240
|
+
if ($action -eq 'verify') {
|
|
1241
|
+
if (-not (Test-Path -LiteralPath $controlRoot -PathType Container)) { throw 'protected native shell control state is not initialized; run kodax sandbox setup' }
|
|
1242
|
+
Assert-NoReparse $controlRoot
|
|
1243
|
+
} elseif ($action -eq 'ensure') {
|
|
1244
|
+
if (Test-Path -LiteralPath $controlRoot) {
|
|
1245
|
+
Assert-NoReparse $controlRoot
|
|
1246
|
+
} else {
|
|
1247
|
+
[void][IO.Directory]::CreateDirectory($controlRoot, (New-ControlSecurity))
|
|
1248
|
+
Assert-NoReparse $controlRoot
|
|
1249
|
+
}
|
|
1250
|
+
} elseif ($action -eq 'repair') {
|
|
1251
|
+
if (Test-Path -LiteralPath $controlRoot) {
|
|
1252
|
+
Assert-NoReparse $controlRoot
|
|
1253
|
+
$existing = [IO.Directory]::GetAccessControl($controlRoot)
|
|
1254
|
+
if ($existing.GetOwner([Security.Principal.SecurityIdentifier]).Value -ne $hostSid.Value) { throw 'refusing to repair native shell control state not owned by the host' }
|
|
1255
|
+
Remove-ProvenStaleControlEntries $controlRoot
|
|
1256
|
+
$entries = [IO.Directory]::EnumerateFileSystemEntries($controlRoot).GetEnumerator()
|
|
1257
|
+
try { $notEmpty = $entries.MoveNext() } finally { $entries.Dispose() }
|
|
1258
|
+
if ($notEmpty) { throw 'refusing to repair non-empty native shell control state; close KodaX and remove the directory manually' }
|
|
1259
|
+
[IO.Directory]::SetAccessControl($controlRoot, (New-ControlSecurity))
|
|
1260
|
+
} else {
|
|
1261
|
+
[void][IO.Directory]::CreateDirectory($controlRoot, (New-ControlSecurity))
|
|
1262
|
+
}
|
|
1263
|
+
Assert-NoReparse $controlRoot
|
|
1264
|
+
} else {
|
|
1265
|
+
throw 'invalid native shell control state action'
|
|
1266
|
+
}
|
|
1267
|
+
Assert-ControlSecurity $controlRoot
|
|
1268
|
+
[Console]::Out.Write($controlRoot)
|
|
1269
|
+
`;var Ur=7;function Xr(e){let t=e.args.flatMap((a,c)=>a==="--"?[c]:[]);if(t.length===0)throw new Error("ASRT Windows invocation omitted its target separator.");if(t.length!==1)throw new Error("ASRT Windows invocation must contain exactly one target separator.");let n=t[0],r=e.args.slice(n+1);if(r.length===0||r[0]==="")throw new Error("ASRT Windows invocation omitted its target executable.");let i=new Map,s=[];for(let a=0;a<=n;a+=1){let c=e.args[a],d=c.toLowerCase();if(d.startsWith("--env="))throw new Error("ASRT Windows invocation used an unsupported inline environment entry.");if(d!=="--env"){s.push(c);continue}if(a+1>=n)throw new Error("ASRT Windows invocation contained an incomplete environment entry.");let l=e.args[a+1],u=l.indexOf("="),f=u<1?"":l.slice(0,u),m=u<0?"":l.slice(u+1),p=f.toLowerCase();if(f===""||f.includes("\0")||m.includes("\0"))throw new Error("ASRT Windows invocation contained an invalid environment entry.");i.set(p,[f,m]),a+=1}return{executable:e.executable,prefixArgs:s,targetArgv:r,childEnvironment:Object.fromEntries(i.values())}}o(Xr,"splitAsrtWindowsInvocation");var{DEFAULT_WINDOWS_PROXY_PORT_RANGE:J$,SandboxManager:Ne,getSrtWinPath:Y$,getWindowsSandboxUserStatus:ou,installWindowsSandbox:Q$,resolveSrtWin:iu,uninstallWindowsSandbox:Z$}=await import("@anthropic-ai/sandbox-runtime"),su=1024*1024,au=16*1024;var cu=nu(import.meta.url),eN=process.env.KODAX_BUNDLED==="true"?void 0:ru(cu.resolve("@anthropic-ai/sandbox-runtime")).href;var tN=[".ssh",".aws",".azure",".gnupg",".kube",".docker",".kodax",".agents",".codex",".claude",".gemini",".direnv",".terraform.d",b.join(".cargo","credentials.toml"),b.join(".config","gcloud"),b.join(".config","gh"),b.join(".config","openai"),b.join(".config","anthropic"),".gitconfig",b.join(".config","git","config"),".terraformrc",b.join(".config","pypoetry","auth.toml"),".condarc",".bashrc",".bash_profile",".zshrc",".zprofile",".profile",b.join(".config","fish","config.fish"),b.join(".config","fish","fish_variables"),".bash_history",".zsh_history",b.join(".m2","settings.xml"),b.join(".m2","settings-security.xml"),b.join(".gradle","gradle.properties"),b.join(".nuget","NuGet","NuGet.Config"),b.join(".pip","pip.conf"),b.join(".config","pip","pip.conf"),b.join(".cache","huggingface","token"),b.join(".huggingface","token"),b.join(".config","rclone","rclone.conf"),b.join(".local","share","keyrings"),b.join("Library","Keychains"),b.join("AppData","Roaming","Microsoft","Protect"),b.join("AppData","Roaming","Microsoft","Credentials"),b.join("AppData","Roaming","Microsoft","Vault"),b.join("AppData","Local","Microsoft","Credentials"),b.join("AppData","Local","Microsoft","Protect"),b.join("AppData","Local","Microsoft","Vault"),".password-store",".env",".envrc",".pgpass",".env.local",".env.development",".env.production",".env.test",".env.staging",".npmrc",".pypirc",".netrc",".git-credentials","credentials","credentials.json","application_default_credentials.json","id_rsa","id_dsa","id_ecdsa","id_ed25519"];var zr=JSON.stringify(Ye),It=JSON.stringify(Je),du=String.raw`
|
|
1270
|
+
const { spawn } = require('node:child_process');
|
|
1271
|
+
const { writeSync } = require('node:fs');
|
|
1272
|
+
const input = JSON.parse(Buffer.from(process.argv[2], 'base64').toString('utf8'));
|
|
1273
|
+
const childEnv = { ...process.env };
|
|
1274
|
+
for (const name of Object.keys(childEnv)) {
|
|
1275
|
+
if (name.toLowerCase() === 'electron_run_as_node') delete childEnv[name];
|
|
1276
|
+
}
|
|
1277
|
+
if (input.electronRunAsNode === true) childEnv.ELECTRON_RUN_AS_NODE = '1';
|
|
1278
|
+
const child = spawn(input.command, input.args, {
|
|
1279
|
+
cwd: input.cwd,
|
|
1280
|
+
env: childEnv,
|
|
1281
|
+
shell: false,
|
|
1282
|
+
stdio: ['inherit', 'inherit', 'pipe'],
|
|
1283
|
+
windowsHide: true,
|
|
1284
|
+
windowsVerbatimArguments: input.windowsVerbatimArguments === true,
|
|
1285
|
+
});
|
|
1286
|
+
const stop = (signal) => child.kill(signal);
|
|
1287
|
+
process.once('SIGINT', () => stop('SIGINT'));
|
|
1288
|
+
process.once('SIGTERM', () => stop('SIGTERM'));
|
|
1289
|
+
child.once('spawn', () => {
|
|
1290
|
+
writeSync(2, input.targetStartedMarker);
|
|
1291
|
+
child.stderr.pipe(process.stderr);
|
|
1292
|
+
});
|
|
1293
|
+
child.once('error', (error) => {
|
|
1294
|
+
process.stderr.write((error instanceof Error ? error.message : String(error)) + '\n');
|
|
1295
|
+
process.exitCode = 1;
|
|
1296
|
+
});
|
|
1297
|
+
child.once('exit', (code, signal) => {
|
|
1298
|
+
process.exitCode = signal ? 1 : code ?? 1;
|
|
1299
|
+
});
|
|
1300
|
+
`,lu="eval(Buffer.from(process.argv[1],'base64').toString('utf8'))",uu=JSON.stringify(lu),fu=Buffer.from(du,"utf8").toString("base64"),pu=JSON.stringify(fu),mu=Br(),nN=String.raw`
|
|
1301
|
+
const { spawn } = require('node:child_process');
|
|
1302
|
+
const { createWriteStream } = require('node:fs');
|
|
1303
|
+
const { readFile, rm } = require('node:fs/promises');
|
|
1304
|
+
const readline = require('node:readline');
|
|
1305
|
+
const input = readline.createInterface({ input: process.stdin, terminal: false });
|
|
1306
|
+
input.once('line', async (gate) => {
|
|
1307
|
+
input.close();
|
|
1308
|
+
if (gate !== 'go') { process.exitCode = 125; return; }
|
|
1309
|
+
const launchFile = process.argv[1];
|
|
1310
|
+
const launch = JSON.parse(await readFile(launchFile, 'utf8'));
|
|
1311
|
+
await rm(launchFile, { force: true });
|
|
1312
|
+
const child = spawn(launch.command, launch.args, {
|
|
1313
|
+
cwd: launch.cwd,
|
|
1314
|
+
env: launch.env,
|
|
1315
|
+
shell: false,
|
|
1316
|
+
stdio: launch.controlPipe === true
|
|
1317
|
+
? ['pipe', 'pipe', 'pipe', 'pipe']
|
|
1318
|
+
: ['pipe', 'pipe', 'pipe'],
|
|
1319
|
+
windowsHide: true,
|
|
1320
|
+
});
|
|
1321
|
+
process.stdin.pipe(child.stdin);
|
|
1322
|
+
child.stdout.pipe(process.stdout);
|
|
1323
|
+
child.stderr.pipe(process.stderr);
|
|
1324
|
+
if (launch.controlPipe === true && child.stdio[3]) {
|
|
1325
|
+
child.stdio[3].pipe(createWriteStream(null, { fd: 3, autoClose: false }));
|
|
1326
|
+
}
|
|
1327
|
+
child.once('error', (error) => {
|
|
1328
|
+
process.stderr.write(String(error?.message ?? error));
|
|
1329
|
+
process.exitCode = 1;
|
|
1330
|
+
});
|
|
1331
|
+
child.once('close', (code) => { process.exitCode = Number.isInteger(code) ? code : 1; });
|
|
1332
|
+
});
|
|
1333
|
+
`,rN=String.raw`
|
|
1334
|
+
import { spawn } from 'node:child_process';
|
|
1335
|
+
import { randomUUID } from 'node:crypto';
|
|
1336
|
+
import { realpathSync, statSync, writeSync } from 'node:fs';
|
|
1337
|
+
import path from 'node:path';
|
|
1338
|
+
let SandboxManager;
|
|
1339
|
+
const request = await new Promise((resolve, reject) => {
|
|
1340
|
+
const chunks = [];
|
|
1341
|
+
let bytes = 0;
|
|
1342
|
+
process.stdin.on('data', (chunk) => {
|
|
1343
|
+
bytes += chunk.byteLength;
|
|
1344
|
+
if (bytes > ${su}) {
|
|
1345
|
+
reject(new Error('Sandbox broker request exceeded its byte limit.'));
|
|
1346
|
+
process.stdin.destroy();
|
|
1347
|
+
return;
|
|
1348
|
+
}
|
|
1349
|
+
chunks.push(Buffer.from(chunk));
|
|
1350
|
+
});
|
|
1351
|
+
process.stdin.once('error', reject);
|
|
1352
|
+
process.stdin.once('end', () => {
|
|
1353
|
+
try { resolve(JSON.parse(Buffer.concat(chunks).toString('utf8'))); }
|
|
1354
|
+
catch (error) { reject(error); }
|
|
1355
|
+
});
|
|
1356
|
+
});
|
|
1357
|
+
if (typeof request.controlInvocationId !== 'string' || request.controlInvocationId === '') {
|
|
1358
|
+
throw new Error('Sandbox broker request omitted its control invocation identity.');
|
|
1359
|
+
}
|
|
1360
|
+
const targetStartedMarker = request.targetStartedMarker
|
|
1361
|
+
?? '\u0000KODAX_ASRT_TARGET_STARTED:' + randomUUID() + '\u0000\n';
|
|
1362
|
+
const endpoints = new Set(request.endpoints.map((item) => item.host.toLowerCase() + ':' + item.port));
|
|
1363
|
+
const callback = request.allowAllNetwork === true
|
|
1364
|
+
? async () => true
|
|
1365
|
+
: request.endpoints.length === 0
|
|
1366
|
+
? undefined
|
|
1367
|
+
: async ({ host, port }) => endpoints.has(host.toLowerCase() + ':' + port);
|
|
1368
|
+
${mu}
|
|
1369
|
+
const withWindowsChildEnvironment = (argv, environment, gitTrustRoots) => {
|
|
1370
|
+
const separator = argv.lastIndexOf('--');
|
|
1371
|
+
if (separator < 0) throw new Error('ASRT Windows wrapper omitted its child separator.');
|
|
1372
|
+
const requested = [];
|
|
1373
|
+
const requestedNames = new Set();
|
|
1374
|
+
for (const [name, value] of Object.entries(environment ?? {})) {
|
|
1375
|
+
if (value === undefined) continue;
|
|
1376
|
+
if (!name || name.includes('=') || name.includes('\0') || value.includes('\0')) {
|
|
1377
|
+
throw new Error('Invalid environment entry for ASRT Windows child.');
|
|
1378
|
+
}
|
|
1379
|
+
const normalized = name.toLowerCase();
|
|
1380
|
+
if (requestedNames.has(normalized)) {
|
|
1381
|
+
throw new Error('Ambiguous Windows child environment variable: ' + name + '.');
|
|
1382
|
+
}
|
|
1383
|
+
requestedNames.add(normalized);
|
|
1384
|
+
requested.push([name, value]);
|
|
1385
|
+
}
|
|
1386
|
+
const requestedOverrides = new Set(requested.flatMap(([name]) => (
|
|
1387
|
+
['path', 'pathext'].includes(name.toLowerCase()) ? [name.toLowerCase()] : []
|
|
1388
|
+
)));
|
|
1389
|
+
const controlled = new Set();
|
|
1390
|
+
const prefix = [];
|
|
1391
|
+
for (let index = 0; index < separator; index += 1) {
|
|
1392
|
+
if (argv[index] !== '--env' || index + 1 >= separator) {
|
|
1393
|
+
prefix.push(argv[index]);
|
|
1394
|
+
continue;
|
|
1395
|
+
}
|
|
1396
|
+
const assignment = argv[index + 1];
|
|
1397
|
+
const name = assignment.split('=', 1)[0]?.toLowerCase();
|
|
1398
|
+
if (name) controlled.add(name);
|
|
1399
|
+
if (!name || !requestedOverrides.has(name)) prefix.push(argv[index], assignment);
|
|
1400
|
+
index += 1;
|
|
1401
|
+
}
|
|
1402
|
+
const injected = [];
|
|
1403
|
+
for (const [name, value] of requested) {
|
|
1404
|
+
const normalized = name.toLowerCase();
|
|
1405
|
+
if (controlled.has(normalized) && normalized !== 'path' && normalized !== 'pathext') continue;
|
|
1406
|
+
injected.push('--env', name + '=' + value);
|
|
1407
|
+
}
|
|
1408
|
+
const result = [...prefix, ...injected, ...argv.slice(separator)];
|
|
1409
|
+
const withGitTrust = rewriteWindowsGitSafeDirectoryArgv(result, gitTrustRoots);
|
|
1410
|
+
const estimate = withGitTrust.reduce((size, value) => size + value.length + 3, 0);
|
|
1411
|
+
if (estimate > 30000) throw new Error('ASRT Windows child environment exceeds the CreateProcess command-line limit.');
|
|
1412
|
+
return withGitTrust;
|
|
1413
|
+
};
|
|
1414
|
+
const writeObservation = (observation) => {
|
|
1415
|
+
const payload = Buffer.from(JSON.stringify({
|
|
1416
|
+
version: 1,
|
|
1417
|
+
invocationId: request.controlInvocationId,
|
|
1418
|
+
observation,
|
|
1419
|
+
}) + '\n', 'utf8');
|
|
1420
|
+
if (payload.byteLength > ${au}) {
|
|
1421
|
+
throw new Error('Sandbox broker control frame exceeded its byte limit.');
|
|
1422
|
+
}
|
|
1423
|
+
if (writeSync(3, payload) !== payload.byteLength) {
|
|
1424
|
+
throw new Error('Sandbox broker control frame was only partially written.');
|
|
1425
|
+
}
|
|
1426
|
+
};
|
|
1427
|
+
const waitForTarget = (target, observation, onTargetStarted) => {
|
|
1428
|
+
const marker = Buffer.from(targetStartedMarker, 'utf8');
|
|
1429
|
+
let pending = Buffer.alloc(0);
|
|
1430
|
+
let diagnostic = Buffer.alloc(0);
|
|
1431
|
+
let processError;
|
|
1432
|
+
let wrapperSpawned = false;
|
|
1433
|
+
let targetStarted = false;
|
|
1434
|
+
return new Promise((resolve, reject) => {
|
|
1435
|
+
let settled = false;
|
|
1436
|
+
target.once('spawn', () => {
|
|
1437
|
+
wrapperSpawned = true;
|
|
1438
|
+
});
|
|
1439
|
+
const finish = (result) => {
|
|
1440
|
+
if (settled) return;
|
|
1441
|
+
settled = true;
|
|
1442
|
+
resolve(result);
|
|
1443
|
+
};
|
|
1444
|
+
target.stderr.on('data', (chunk) => {
|
|
1445
|
+
if (targetStarted) {
|
|
1446
|
+
process.stderr.write(chunk);
|
|
1447
|
+
return;
|
|
1448
|
+
}
|
|
1449
|
+
pending = Buffer.concat([pending, Buffer.from(chunk)]);
|
|
1450
|
+
const markerOffset = pending.indexOf(marker);
|
|
1451
|
+
if (markerOffset >= 0) {
|
|
1452
|
+
targetStarted = true;
|
|
1453
|
+
onTargetStarted();
|
|
1454
|
+
const suffix = pending.subarray(markerOffset + marker.length);
|
|
1455
|
+
pending = Buffer.alloc(0);
|
|
1456
|
+
diagnostic = Buffer.alloc(0);
|
|
1457
|
+
try {
|
|
1458
|
+
writeObservation(observation);
|
|
1459
|
+
} catch (error) {
|
|
1460
|
+
processError = error instanceof Error ? error.message : String(error);
|
|
1461
|
+
target.kill('SIGTERM');
|
|
1462
|
+
}
|
|
1463
|
+
if (suffix.length > 0) process.stderr.write(suffix);
|
|
1464
|
+
return;
|
|
1465
|
+
}
|
|
1466
|
+
const retained = Math.max(0, marker.length - 1);
|
|
1467
|
+
if (pending.length > retained) {
|
|
1468
|
+
diagnostic = Buffer.concat([
|
|
1469
|
+
diagnostic,
|
|
1470
|
+
pending.subarray(0, pending.length - retained),
|
|
1471
|
+
]).subarray(-65536);
|
|
1472
|
+
pending = pending.subarray(pending.length - retained);
|
|
1473
|
+
}
|
|
1474
|
+
});
|
|
1475
|
+
target.once('error', (error) => {
|
|
1476
|
+
processError = error instanceof Error ? error.message : String(error);
|
|
1477
|
+
});
|
|
1478
|
+
target.once('close', (exitCode, signal) => {
|
|
1479
|
+
const preTarget = Buffer.concat([diagnostic, pending]).toString('utf8').trim();
|
|
1480
|
+
finish({
|
|
1481
|
+
exitCode: signal ? 1 : exitCode ?? 1,
|
|
1482
|
+
targetStarted,
|
|
1483
|
+
spawnFailedBeforeSpawn: processError !== undefined && !wrapperSpawned,
|
|
1484
|
+
controlFailure: targetStarted ? processError : undefined,
|
|
1485
|
+
diagnostic: preTarget || processError || undefined,
|
|
1486
|
+
});
|
|
1487
|
+
});
|
|
1488
|
+
});
|
|
1489
|
+
};
|
|
1490
|
+
let child;
|
|
1491
|
+
let targetStarted = false;
|
|
1492
|
+
let normalFallbackAttempted = false;
|
|
1493
|
+
let normalFallbackSpawned = false;
|
|
1494
|
+
const runDirect = async () => {
|
|
1495
|
+
const internalElectronNode = request.command === process.execPath && process.versions.electron !== undefined;
|
|
1496
|
+
const directArgs = internalElectronNode
|
|
1497
|
+
? ['--import', ${zr}, ...request.args]
|
|
1498
|
+
: request.args;
|
|
1499
|
+
const directEnv = internalElectronNode
|
|
1500
|
+
? { ...request.env, [${It}]: '1' }
|
|
1501
|
+
: request.env;
|
|
1502
|
+
child = spawn(request.command, directArgs, {
|
|
1503
|
+
cwd: request.cwd,
|
|
1504
|
+
env: directEnv,
|
|
1505
|
+
shell: false,
|
|
1506
|
+
stdio: 'inherit',
|
|
1507
|
+
windowsHide: true,
|
|
1508
|
+
windowsVerbatimArguments: request.windowsVerbatimArguments === true,
|
|
1509
|
+
});
|
|
1510
|
+
return await new Promise((resolve, reject) => {
|
|
1511
|
+
child.once('spawn', () => { normalFallbackSpawned = true; });
|
|
1512
|
+
child.once('error', reject);
|
|
1513
|
+
child.once('exit', (exitCode, signal) => resolve(signal ? 1 : exitCode ?? 1));
|
|
1514
|
+
});
|
|
1515
|
+
};
|
|
1516
|
+
const runNormalFallback = async () => {
|
|
1517
|
+
if (
|
|
1518
|
+
request.fallbackToNormalExecution !== true
|
|
1519
|
+
|| targetStarted
|
|
1520
|
+
|| normalFallbackAttempted
|
|
1521
|
+
) return false;
|
|
1522
|
+
normalFallbackAttempted = true;
|
|
1523
|
+
try {
|
|
1524
|
+
process.exitCode = await runDirect();
|
|
1525
|
+
writeObservation({
|
|
1526
|
+
version: 1,
|
|
1527
|
+
state: 'fallback',
|
|
1528
|
+
reason: 'backend_failed',
|
|
1529
|
+
execution: 'normal_permission_policy',
|
|
1530
|
+
});
|
|
1531
|
+
} catch (error) {
|
|
1532
|
+
if (!normalFallbackSpawned) {
|
|
1533
|
+
writeObservation({
|
|
1534
|
+
version: 1,
|
|
1535
|
+
state: 'not_started',
|
|
1536
|
+
diagnostic: error instanceof Error ? error.message : String(error),
|
|
1537
|
+
});
|
|
1538
|
+
}
|
|
1539
|
+
throw error;
|
|
1540
|
+
}
|
|
1541
|
+
return true;
|
|
1542
|
+
};
|
|
1543
|
+
try {
|
|
1544
|
+
if (request.wrappedInvocation) {
|
|
1545
|
+
const wrapped = request.wrappedInvocation;
|
|
1546
|
+
child = spawn(wrapped.executable, wrapped.args, {
|
|
1547
|
+
cwd: request.cwd,
|
|
1548
|
+
env: wrapped.env,
|
|
1549
|
+
shell: wrapped.shell,
|
|
1550
|
+
stdio: ['inherit', 'inherit', 'pipe'],
|
|
1551
|
+
windowsHide: true,
|
|
1552
|
+
});
|
|
1553
|
+
const result = await waitForTarget(child, {
|
|
1554
|
+
version: 1,
|
|
1555
|
+
state: 'applied',
|
|
1556
|
+
backend: request.observationBackend ?? 'unsupported',
|
|
1557
|
+
policyId: 'kodax-workspace-shell-v1',
|
|
1558
|
+
}, () => { targetStarted = true; });
|
|
1559
|
+
targetStarted = result.targetStarted;
|
|
1560
|
+
if (result.controlFailure) {
|
|
1561
|
+
process.stderr.write(result.controlFailure + '\n');
|
|
1562
|
+
process.exitCode = 125;
|
|
1563
|
+
} else {
|
|
1564
|
+
const fellBack = result.spawnFailedBeforeSpawn
|
|
1565
|
+
? await runNormalFallback()
|
|
1566
|
+
: false;
|
|
1567
|
+
if (!targetStarted && !fellBack) {
|
|
1568
|
+
if (result.spawnFailedBeforeSpawn) {
|
|
1569
|
+
writeObservation({
|
|
1570
|
+
version: 1,
|
|
1571
|
+
state: 'not_started',
|
|
1572
|
+
diagnostic: result.diagnostic,
|
|
1573
|
+
});
|
|
1574
|
+
}
|
|
1575
|
+
process.stderr.write((result.diagnostic || 'Sandbox target launch could not be attested.') + '\n');
|
|
1576
|
+
}
|
|
1577
|
+
if (!fellBack) {
|
|
1578
|
+
process.exitCode = targetStarted ? result.exitCode : result.spawnFailedBeforeSpawn ? 1 : 125;
|
|
1579
|
+
}
|
|
1580
|
+
}
|
|
1581
|
+
} else {
|
|
1582
|
+
({ SandboxManager } = await import(process.argv[1]));
|
|
1583
|
+
const bootstrap = request.bootstrapCommand ?? 'node';
|
|
1584
|
+
const bootstrapIsAbsolute = /^(?:[A-Za-z]:[\\/]|\\\\)/.test(bootstrap);
|
|
1585
|
+
const bootstrapIsElectronNode = bootstrap === process.execPath
|
|
1586
|
+
&& process.versions.electron !== undefined;
|
|
1587
|
+
const config = process.platform === 'win32' && bootstrapIsAbsolute
|
|
1588
|
+
? {
|
|
1589
|
+
...request.config,
|
|
1590
|
+
filesystem: {
|
|
1591
|
+
...request.config.filesystem,
|
|
1592
|
+
allowRead: [...new Set([
|
|
1593
|
+
...request.config.filesystem.allowRead,
|
|
1594
|
+
bootstrap,
|
|
1595
|
+
path.dirname(bootstrap),
|
|
1596
|
+
])],
|
|
1597
|
+
},
|
|
1598
|
+
}
|
|
1599
|
+
: request.config;
|
|
1600
|
+
await SandboxManager.initialize(config, callback);
|
|
1601
|
+
const quote = (value) => process.platform === 'win32'
|
|
1602
|
+
? '"' + value.replaceAll('"', '""') + '"'
|
|
1603
|
+
: "'" + value.replaceAll("'", "'\"'\"'") + "'";
|
|
1604
|
+
const internalElectronNode = request.command === process.execPath && process.versions.electron !== undefined;
|
|
1605
|
+
const childArgs = internalElectronNode
|
|
1606
|
+
? ['--import', ${zr}, ...request.args]
|
|
1607
|
+
: request.args;
|
|
1608
|
+
const command = [
|
|
1609
|
+
quote(bootstrap),
|
|
1610
|
+
'-e',
|
|
1611
|
+
quote(${uu}),
|
|
1612
|
+
${pu},
|
|
1613
|
+
Buffer.from(JSON.stringify({
|
|
1614
|
+
command: request.command,
|
|
1615
|
+
args: childArgs,
|
|
1616
|
+
windowsVerbatimArguments: request.windowsVerbatimArguments === true,
|
|
1617
|
+
cwd: request.cwd,
|
|
1618
|
+
targetStartedMarker,
|
|
1619
|
+
electronRunAsNode: internalElectronNode,
|
|
1620
|
+
}), 'utf8').toString('base64'),
|
|
1621
|
+
].join(' ');
|
|
1622
|
+
if (process.platform === 'win32') {
|
|
1623
|
+
const wrapped = await SandboxManager.wrapWithSandboxArgv(command, 'cmd', undefined, undefined, request.cwd);
|
|
1624
|
+
const requestedEnv = internalElectronNode || bootstrapIsElectronNode
|
|
1625
|
+
? { ...request.env, [${It}]: '1' }
|
|
1626
|
+
: request.env;
|
|
1627
|
+
const childArgv = withWindowsChildEnvironment(wrapped.argv, requestedEnv, windowsGitTrustRoots(request));
|
|
1628
|
+
child = spawn(childArgv[0], childArgv.slice(1), {
|
|
1629
|
+
cwd: request.cwd,
|
|
1630
|
+
env: wrapped.env,
|
|
1631
|
+
shell: false,
|
|
1632
|
+
stdio: ['inherit', 'inherit', 'pipe'],
|
|
1633
|
+
windowsHide: true,
|
|
1634
|
+
});
|
|
1635
|
+
} else {
|
|
1636
|
+
const wrapped = await SandboxManager.wrapWithSandbox(command);
|
|
1637
|
+
const childEnv = internalElectronNode || bootstrapIsElectronNode
|
|
1638
|
+
? { ...request.env, [${It}]: '1' }
|
|
1639
|
+
: request.env;
|
|
1640
|
+
child = spawn(wrapped, {
|
|
1641
|
+
cwd: request.cwd,
|
|
1642
|
+
env: childEnv,
|
|
1643
|
+
shell: true,
|
|
1644
|
+
stdio: ['inherit', 'inherit', 'pipe'],
|
|
1645
|
+
});
|
|
1646
|
+
}
|
|
1647
|
+
const stop = () => child?.kill('SIGTERM');
|
|
1648
|
+
process.once('SIGINT', stop);
|
|
1649
|
+
process.once('SIGTERM', stop);
|
|
1650
|
+
const result = await waitForTarget(child, {
|
|
1651
|
+
version: 1,
|
|
1652
|
+
state: 'applied',
|
|
1653
|
+
backend: request.observationBackend ?? 'unsupported',
|
|
1654
|
+
policyId: 'kodax-workspace-shell-v1',
|
|
1655
|
+
}, () => { targetStarted = true; });
|
|
1656
|
+
targetStarted = result.targetStarted;
|
|
1657
|
+
try { SandboxManager.cleanupAfterCommand(); } catch {}
|
|
1658
|
+
await SandboxManager.reset().catch(() => undefined);
|
|
1659
|
+
if (result.controlFailure) {
|
|
1660
|
+
process.stderr.write(result.controlFailure + '\n');
|
|
1661
|
+
process.exitCode = 125;
|
|
1662
|
+
} else {
|
|
1663
|
+
const fellBack = result.spawnFailedBeforeSpawn
|
|
1664
|
+
? await runNormalFallback()
|
|
1665
|
+
: false;
|
|
1666
|
+
if (!targetStarted && !fellBack) {
|
|
1667
|
+
if (result.spawnFailedBeforeSpawn) {
|
|
1668
|
+
writeObservation({
|
|
1669
|
+
version: 1,
|
|
1670
|
+
state: 'not_started',
|
|
1671
|
+
diagnostic: result.diagnostic,
|
|
1672
|
+
});
|
|
1673
|
+
}
|
|
1674
|
+
process.stderr.write((result.diagnostic || 'Sandbox target launch could not be attested.') + '\n');
|
|
1675
|
+
}
|
|
1676
|
+
if (!fellBack) {
|
|
1677
|
+
process.exitCode = targetStarted ? result.exitCode : result.spawnFailedBeforeSpawn ? 1 : 125;
|
|
1678
|
+
}
|
|
1679
|
+
}
|
|
1680
|
+
}
|
|
1681
|
+
} catch (error) {
|
|
1682
|
+
await SandboxManager?.reset().catch(() => undefined);
|
|
1683
|
+
if (
|
|
1684
|
+
request.fallbackToNormalExecution === true
|
|
1685
|
+
&& !targetStarted
|
|
1686
|
+
&& !normalFallbackAttempted
|
|
1687
|
+
&& child === undefined
|
|
1688
|
+
) {
|
|
1689
|
+
try {
|
|
1690
|
+
await runNormalFallback();
|
|
1691
|
+
} catch (fallbackError) {
|
|
1692
|
+
process.stderr.write((fallbackError instanceof Error ? fallbackError.message : String(fallbackError)) + '\n');
|
|
1693
|
+
process.exitCode = 1;
|
|
1694
|
+
}
|
|
1695
|
+
} else {
|
|
1696
|
+
if (!targetStarted && child === undefined) {
|
|
1697
|
+
try {
|
|
1698
|
+
writeObservation({
|
|
1699
|
+
version: 1,
|
|
1700
|
+
state: 'not_started',
|
|
1701
|
+
diagnostic: error instanceof Error ? error.message : String(error),
|
|
1702
|
+
});
|
|
1703
|
+
} catch {}
|
|
1704
|
+
}
|
|
1705
|
+
process.stderr.write((error instanceof Error ? error.message : String(error)) + '\n');
|
|
1706
|
+
process.exitCode = targetStarted ? 125 : 1;
|
|
1707
|
+
}
|
|
1708
|
+
}
|
|
1709
|
+
`;function Gr(e){return e instanceof Error?e.message:String(e)}o(Gr,"errorText");function hu(e){let t=[];return e.provisioned||t.push("Windows sandbox account does not exist."),e.sid||t.push("Windows sandbox account SID is unavailable."),(!e.groupExists||!e.groupSid)&&t.push("Windows sandbox local group is unavailable."),e.inBuiltinUsers||t.push("Windows sandbox account is not in the built-in Users group."),e.inSandboxGroup||t.push("Windows sandbox account is not in the sandbox-runtime-users group."),e.hiddenFromLogon||t.push("Windows sandbox account is not hidden from interactive logon."),e.credPresent||t.push("Windows sandbox account credential is unavailable."),t}o(hu,"windowsSandboxAccountDiagnostics");var oN=String.raw`
|
|
1710
|
+
$ErrorActionPreference = 'Stop'
|
|
1711
|
+
$process = Start-Process -FilePath $env:KODAX_NATIVE_SETUP_EXE -ArgumentList @('__setup-null-device', $env:KODAX_NATIVE_SETUP_SID) -Verb RunAs -Wait -PassThru -WindowStyle Hidden
|
|
1712
|
+
exit $process.ExitCode
|
|
1713
|
+
`;function gu(){let e=["PATH","Path","PATHEXT","SystemRoot","COMSPEC","TEMP","TMP","HOME","USERPROFILE","LOCALAPPDATA","LANG"],t={NO_COLOR:"1"};for(let n of e)process.env[n]!==void 0&&(t[n]=process.env[n]);for(let[n,r]of Object.entries(process.env))n.startsWith("LC_")&&r!==void 0&&(t[n]=r);return yu(t)}o(gu,"sanitizedEnvironment");function yu(e){if(process.platform!=="win32")return{...e};let t=new Map;for(let[n,r]of Object.entries(e))r!==void 0&&t.set(n.toLowerCase(),[n,r]);return Object.fromEntries(t.values())}o(yu,"normalizedSandboxEnvironment");function Vr(e){tu(3,`${JSON.stringify(e)}
|
|
1714
|
+
`)}o(Vr,"writeWindowsNetworkBrokerReady");async function wu(e){let t=Zl(e,["__controller",String(process.pid)],{env:gu(),shell:!1,stdio:["pipe","pipe","pipe"],windowsHide:!0}),n=Buffer.alloc(0);t.stderr?.on("data",d=>{n=Buffer.concat([n,d]).subarray(-16*1024)});let r,i="",s,a=new Promise(d=>{s=d}),c={child:t,get pipe(){return i},exit:a,stderrTail:o(()=>n.toString("utf8"),"stderrTail"),stopping:!1};t.once("error",d=>{r=d}),t.once("close",(d,l)=>{let u={code:d,signal:l,...r===void 0?{}:{error:r}};c.outcome=u,s(u)});try{let d=t.stdout;if(d===null)throw new Error("Windows native controller stdout pipe was not created.");i=await new Promise((u,f)=>{let m=!1,p=Buffer.alloc(0),h=o(v=>{m||(m=!0,clearTimeout(w),d.off("data",g),t.off("error",x),t.off("exit",y),v())},"finish"),x=o(v=>h(()=>f(v)),"onError"),y=o(v=>h(()=>f(new Error(`Windows native controller exited ${String(v)} before readiness: ${c.stderrTail()}`))),"onExit"),g=o(v=>{if(p=Buffer.concat([p,v]),p.length>4096){h(()=>f(new Error("Windows native controller readiness exceeded 4 KiB.")));return}let ee=p.indexOf(10);ee>=0&&h(()=>u(p.subarray(0,ee).toString("utf8").trim()))},"onData"),w=setTimeout(()=>h(()=>f(new Error("Windows native controller readiness timed out."))),1e4);w.unref(),d.on("data",g),t.once("error",x),t.once("exit",y)});let l=/^\\\\\.\\pipe\\kodax-v2-(\d+)-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.exec(i);if(l===null||t.pid===void 0||Number(l[1])!==t.pid)throw new Error("Windows native controller returned an unauthenticated pipe name.");return c}catch(d){try{await Jr(c)}catch(l){throw new AggregateError([d,l],"Windows native controller startup and cleanup both failed.")}throw d}}o(wu,"startWindowsNativeController");async function Jr(e){e.stopping=!0;let t=e.child.stdin;t!==null&&!t.destroyed&&await new Promise(r=>{let i=o(()=>r(),"finish");t.once("error",i),t.end(i)});let n=await Promise.race([e.exit.then(r=>({graceful:!0,outcome:r})),new Promise(r=>{setTimeout(()=>r(!1),5e3).unref()})]);if(n===!1)throw e.child.kill("SIGKILL"),await e.exit,new Error("Windows native controller did not exit within its cleanup budget.");if(n.outcome.error!==void 0||n.outcome.code!==0||n.outcome.signal!==null)throw new Error(`Windows native controller cleanup failed (code ${String(n.outcome.code)}, signal ${String(n.outcome.signal)}): ${e.stderrTail().trim()}`,n.outcome.error===void 0?void 0:{cause:n.outcome.error})}o(Jr,"stopWindowsNativeController");async function Yr(e){let t,n,r=!1,i=[];try{let s=JSON.parse(await Rt(e,"utf8"));if(await Hr(e,{force:!0}),s.version!==1||s.config.filesystem.disabled!==!0||!b.isAbsolute(s.cwd)||!b.isAbsolute(s.srtWinPath)||!/^[0-9a-f]{64}$/i.test(s.srtWinSha256)||!b.isAbsolute(s.controllerExecutable)||!/^[0-9a-f]{64}$/i.test(s.controllerSha256)||s.controllerProtocol!==Ur||!/^S-\d+(?:-\d+)+$/i.test(s.expectedSandboxUserSid)||!/^S-\d+(?:-\d+)+$/i.test(s.expectedSandboxGroupSid))throw new Error("Windows network broker request is invalid or enables filesystem authority.");let a=await Rt(s.srtWinPath);if(qr("sha256").update(a).digest("hex")!==s.srtWinSha256.toLowerCase())throw new Error("ASRT Windows runner artifact changed before broker startup.");let c=await Rt(s.controllerExecutable);if(qr("sha256").update(c).digest("hex")!==s.controllerSha256.toLowerCase())throw new Error("Windows native controller artifact changed before broker startup.");let d=new Set(s.endpoints.map(y=>`${y.host.toLowerCase()}:${y.port}`)),l=s.allowAllNetwork?async()=>!0:d.size===0?void 0:async({host:y,port:g})=>g!==void 0&&d.has(`${y.toLowerCase()}:${g}`);await Ne.initialize(s.config,l);let u=`KODAX_WINDOWS_V2_${eu()}`,f=await Ne.wrapWithSandboxArgv(`echo ${u}`,"cmd",void 0,void 0,s.cwd);if(f.argv.length<2||!f.argv.some(y=>y.includes(u)))throw new Error("ASRT Windows wrapper did not preserve the controlled target sentinel.");let m=Xr({executable:f.argv[0],args:f.argv.slice(1)}),p=ou({srtWin:iu({path:s.srtWinPath})});if(!p.sid||!p.groupSid||hu(p).length>0)throw new Error("Windows sandbox account is not ready for native shell execution.");if(p.sid.toUpperCase()!==s.expectedSandboxUserSid.toUpperCase()||p.groupSid.toUpperCase()!==s.expectedSandboxGroupSid.toUpperCase())throw new Error("Windows sandbox account changed while the network broker was starting.");t=await wu(s.controllerExecutable),Vr({version:1,ok:!0,asrtExecutable:m.executable,asrtPrefixArgs:m.prefixArgs,asrtChildEnvironment:m.childEnvironment,sandboxUserSid:p.sid,sandboxGroupSid:p.groupSid,controllerPipe:t.pipe}),r=!0;let h=new Promise(y=>{let g=!1,w=o(()=>{g||(g=!0,process.stdin.off("end",w),process.stdin.off("close",w),process.off("SIGINT",w),process.off("SIGTERM",w),process.stdin.pause(),y())},"finish");n=w,process.stdin.once("end",w),process.stdin.once("close",w),process.once("SIGINT",w),process.once("SIGTERM",w),process.stdin.readableEnded||process.stdin.destroyed?w():process.stdin.resume()}),x=t.exit.then(y=>{if(!t?.stopping)throw new Error(`Windows native controller exited while its broker was active (code ${String(y.code)}, signal ${String(y.signal)}): `+t.stderrTail().trim(),y.error===void 0?void 0:{cause:y.error})});if(await Promise.race([h,x]),t.outcome!==void 0&&!t.stopping)throw new Error("Windows native controller exited before broker shutdown completed.")}catch(s){if(!r)try{Vr({version:1,ok:!1,error:Gr(s)}),r=!0}catch(a){i.push(a)}i.push(s)}finally{if(n?.(),t!==void 0)try{await Jr(t)}catch(s){i.push(s)}try{Ne.cleanupAfterCommand()}catch(s){i.push(s)}try{await Ne.reset()}catch(s){i.push(s)}try{await Hr(e,{force:!0})}catch(s){i.push(s)}}return i.length>0?(process.stderr.write(`Windows network broker failed: ${i.map(Gr).join(" | ")}
|
|
1715
|
+
`),1):0}o(Yr,"runAsrtWindowsNetworkBrokerProcess");var Qr=process.argv[2];if(!Qr)throw new Error("Missing Windows ASRT network broker request file.");process.exitCode=await Yr(Qr);
|