@akagilnc/pi-workflow-roles 0.1.3545 → 0.1.3549
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/dist/grok/production-host.js +26 -430
- package/dist/public-cli/main.js +24 -41
- package/package.json +1 -1
- package/src/doctor-evidence.ts +1 -8
- package/src/grok/production-host.ts +13 -216
- package/src/grok/role-turn-host.ts +4 -358
- package/src/host-transition-prior-native.ts +23 -32
- package/src/public-cli/post-admission.ts +0 -1
- package/src/grok/bash-seatbelt.ts +0 -69
package/README.md
CHANGED
|
@@ -40,7 +40,7 @@ ak-role judge --attach ./plan.md "Review this plan." > result.txt
|
|
|
40
40
|
|
|
41
41
|
Exit status reports lifecycle honesty, not business success: every lawful typed result (including `audit_escalation`) exits zero; a failure without a lawful result exits nonzero, and its Terminal carries the Error Artifact ref and original cause instead of a fabricated receipt.
|
|
42
42
|
|
|
43
|
-
`ak-role resume <runId> [message]` reopens that run under the **current seat table** for model / host / engine — the same resolution as starting a new leg (`--flag` → persistent seat → package default). Standard chain after a role `escalate`s: take the owner ruling and feed it back with `ak-role resume <runId> "<ruling>"` so the same run continues to a terminal. `[message]` applies only to seats that accept caller instruction: for those seats the optional `message` after `runId` is passed through unchanged as the continuation prompt (opaque: not parsed as flags); omit it to use the package resume envelope. Notary/符宝郎 must omit `message` and derives evidence from the existing source-run/dossier binding. Global `--model` / `--host` / `--engine` override the table for that resume only. On a real host switch (live seat host differs from the previous invocation host), prior native records of the previous host are delivered once as context to the target host; same-host resume does not re-inject. Each host writes only its native volume (Pi: `session/session.jsonl
|
|
43
|
+
`ak-role resume <runId> [message]` reopens that run under the **current seat table** for model / host / engine — the same resolution as starting a new leg (`--flag` → persistent seat → package default). Standard chain after a role `escalate`s: take the owner ruling and feed it back with `ak-role resume <runId> "<ruling>"` so the same run continues to a terminal. `[message]` applies only to seats that accept caller instruction: for those seats the optional `message` after `runId` is passed through unchanged as the continuation prompt (opaque: not parsed as flags); omit it to use the package resume envelope. Notary/符宝郎 must omit `message` and derives evidence from the existing source-run/dossier binding. Global `--model` / `--host` / `--engine` override the table for that resume only. On a real host switch (live seat host differs from the previous invocation host), prior native records of the previous host are delivered once as context to the target host; same-host resume does not re-inject. Each host writes only its native volume (Pi: `session/session.jsonl`; Grok CLI journals stay in the operator grok home, factory dossier is sitian records on the run), with unified ledger entries recorded in 司天台 (Sitian). Whether to resume is the caller's decision: the command does not require a typed HTTP 429 or a `resumable` state. Unknown run IDs and missing session principals are rejected. Every callable role accepts manual resume; Countersign and Gleaner-Left gained it in #599, Collector, Doctor, Notary, and Inspector in #633.
|
|
44
44
|
|
|
45
45
|
Judge, coder, fixer, reviewer, and merger also retry a non-lawful LLM call in place (same `runId` and session) up to `autoResumeLimit` times. Unset defaults to 2; `ak-role config set-auto-resume-limit <N>` writes the ceiling (`0` disables). Lawful typed terminals (`accepted`, `audit_escalation`, `no_receipt`) stop immediately. Manual `ak-role resume` stays available.
|
|
46
46
|
|
package/README.zh-CN.md
CHANGED
|
@@ -38,7 +38,7 @@ ak-role judge --attach ./plan.md "Review this plan." > result.txt
|
|
|
38
38
|
|
|
39
39
|
退出码报的是生命周期诚实,不是业务成败:一切合法 typed 终态(含 `audit_escalation`)退出零;无合法终态的失败退出非零,其 Terminal 携带 Error Artifact 引用与原始原因,不伪造回执。
|
|
40
40
|
|
|
41
|
-
`ak-role resume <runId> [message]` 按**现行席位表**的 model / host / engine 续跑该次运行——与新起角色腿同一解析(调用旗 → 席位持久 → 包默认)。角色 `escalate`(直通御前)后拿到 owner 裁定,标准续跑是 `ak-role resume <runId> "<裁定>"`——把裁定喂回同一 run,角色继续走到终局。`[message]` 只适用于接收 caller instruction 的席位:对这些席位,`runId` 后可选的 `message` 原样作为续跑 prompt(opaque:不进全局旗标语法);省略则用包自带 resume envelope。Notary/符宝郎必须省略 `message`,仅从既有 source-run/案卷绑定自取证。全局 `--model` / `--host` / `--engine` 仅覆盖本次 resume。真实换宿主时(现行席位 host 与上一次 invocation host 不同),将前序宿主原生卷宗一次性作为 context 交付目标宿主;同宿主续跑不重复注入。各宿主仅直写自身原生卷宗(Pi:`session/session.jsonl
|
|
41
|
+
`ak-role resume <runId> [message]` 按**现行席位表**的 model / host / engine 续跑该次运行——与新起角色腿同一解析(调用旗 → 席位持久 → 包默认)。角色 `escalate`(直通御前)后拿到 owner 裁定,标准续跑是 `ak-role resume <runId> "<裁定>"`——把裁定喂回同一 run,角色继续走到终局。`[message]` 只适用于接收 caller instruction 的席位:对这些席位,`runId` 后可选的 `message` 原样作为续跑 prompt(opaque:不进全局旗标语法);省略则用包自带 resume envelope。Notary/符宝郎必须省略 `message`,仅从既有 source-run/案卷绑定自取证。全局 `--model` / `--host` / `--engine` 仅覆盖本次 resume。真实换宿主时(现行席位 host 与上一次 invocation host 不同),将前序宿主原生卷宗一次性作为 context 交付目标宿主;同宿主续跑不重复注入。各宿主仅直写自身原生卷宗(Pi:`session/session.jsonl`;Grok CLI 原始会话留在操作员 grok 家,工厂卷宗为该 run 的司天台记录),统一账目归入司天台。要不要续跑由调用者决定:不再要求 typed HTTP 429,也不要求 `resumable` 状态。未知 run ID、session 主体不在则拒绝。所有可调用角色均可手动 resume:给事中、左拾遗始于 #599,通进司、太医署、符宝郎、察院始于 #633。
|
|
42
42
|
|
|
43
43
|
大理寺、将作监、修内司、御史台、校书郎在单次调用内对非 lawful LLM 终态原地续跑(同一 `runId` 与 session),次数上限为 `autoResumeLimit`。缺键默认 2;`ak-role config set-auto-resume-limit <N>` 写入(`0` 关闭自动续)。lawful typed 终态(`accepted` / `audit_escalation` / `no_receipt`)立即停止。手动 `ak-role resume` 仍可用。
|
|
44
44
|
|
|
@@ -1239,8 +1239,8 @@ var init_in_process_session = __esm({
|
|
|
1239
1239
|
});
|
|
1240
1240
|
|
|
1241
1241
|
// src/grok/production-host.ts
|
|
1242
|
-
import { readFile as readFile15
|
|
1243
|
-
import { join as
|
|
1242
|
+
import { readFile as readFile15 } from "node:fs/promises";
|
|
1243
|
+
import { join as join24 } from "node:path";
|
|
1244
1244
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
1245
1245
|
|
|
1246
1246
|
// src/canonical-skill-binding.ts
|
|
@@ -5284,14 +5284,12 @@ function acceptedFacts(toolName, details) {
|
|
|
5284
5284
|
function record2(value) {
|
|
5285
5285
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5286
5286
|
}
|
|
5287
|
-
var GROK_HOME_DIR_NAME = "grok-home";
|
|
5288
5287
|
async function discoverCaseFiles(root) {
|
|
5289
5288
|
const found = [];
|
|
5290
5289
|
async function walk(dir, depth) {
|
|
5291
5290
|
for (const item of await readdir(dir, { withFileTypes: true })) {
|
|
5292
5291
|
const path = resolve8(dir, item.name);
|
|
5293
5292
|
if (item.isDirectory()) {
|
|
5294
|
-
if (item.name === GROK_HOME_DIR_NAME) continue;
|
|
5295
5293
|
await walk(path, depth + 1);
|
|
5296
5294
|
} else if (item.isFile() && (item.name.endsWith(".jsonl") || item.name === "stderr.log" && depth === 1)) found.push(path);
|
|
5297
5295
|
}
|
|
@@ -13558,17 +13556,14 @@ function createRoleRuntimeExtension(dependencies) {
|
|
|
13558
13556
|
|
|
13559
13557
|
// src/grok/role-envelope.ts
|
|
13560
13558
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
13561
|
-
import { mkdir as
|
|
13559
|
+
import { mkdir as mkdir3, readFile as readFile13, writeFile as writeFile7 } from "node:fs/promises";
|
|
13562
13560
|
import { createServer } from "node:net";
|
|
13563
|
-
import { basename as
|
|
13561
|
+
import { basename as basename7, dirname as dirname15, join as join22 } from "node:path";
|
|
13564
13562
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
13565
13563
|
|
|
13566
13564
|
// src/grok/role-turn-host.ts
|
|
13567
|
-
import {
|
|
13568
|
-
import { copyFile, lstat as lstat3, mkdir as mkdir4, open as open2, realpath as realpath7, rm as rm5 } from "node:fs/promises";
|
|
13569
|
-
import { basename as basename7, dirname as dirname15, isAbsolute as isAbsolute7, join as join23, relative as pathRelative } from "node:path";
|
|
13565
|
+
import { spawn as spawn4 } from "node:child_process";
|
|
13570
13566
|
import { createInterface } from "node:readline";
|
|
13571
|
-
import { promisify as promisify3 } from "node:util";
|
|
13572
13567
|
|
|
13573
13568
|
// src/agent-start-materials.ts
|
|
13574
13569
|
function renderAgentStartMaterials(body, materials) {
|
|
@@ -13576,60 +13571,6 @@ function renderAgentStartMaterials(body, materials) {
|
|
|
13576
13571
|
return [body, ...materials.map((material) => JSON.stringify(material))].join("\n\n");
|
|
13577
13572
|
}
|
|
13578
13573
|
|
|
13579
|
-
// src/grok/bash-seatbelt.ts
|
|
13580
|
-
import { mkdir as mkdir3, writeFile as writeFile7 } from "node:fs/promises";
|
|
13581
|
-
import { join as join22 } from "node:path";
|
|
13582
|
-
function renderGrokBashSeatbeltHookScript() {
|
|
13583
|
-
const reasons = Object.fromEntries(
|
|
13584
|
-
FIXER_BASH_FORBIDDEN_LITERALS.map((literal) => [literal, fixerBashSeatbeltDenyReason(literal)])
|
|
13585
|
-
);
|
|
13586
|
-
return `#!/usr/bin/env node
|
|
13587
|
-
const LITERALS = ${JSON.stringify([...FIXER_BASH_FORBIDDEN_LITERALS])};
|
|
13588
|
-
const REASONS = ${JSON.stringify(reasons)};
|
|
13589
|
-
let raw = "";
|
|
13590
|
-
process.stdin.setEncoding("utf8");
|
|
13591
|
-
process.stdin.on("data", (chunk) => { raw += chunk; });
|
|
13592
|
-
process.stdin.on("end", () => {
|
|
13593
|
-
let event = {};
|
|
13594
|
-
try { event = JSON.parse(raw); } catch { /* fail-open on malformed host payload */ }
|
|
13595
|
-
const input = event && typeof event === "object" ? event.toolInput : undefined;
|
|
13596
|
-
const command = input && typeof input === "object" && typeof input.command === "string"
|
|
13597
|
-
? input.command : undefined;
|
|
13598
|
-
const matched = typeof command === "string"
|
|
13599
|
-
? LITERALS.find((literal) => command.includes(literal))
|
|
13600
|
-
: undefined;
|
|
13601
|
-
const decision = matched === undefined
|
|
13602
|
-
? { decision: "allow" }
|
|
13603
|
-
: { decision: "deny", reason: REASONS[matched] };
|
|
13604
|
-
process.stdout.write(JSON.stringify(decision));
|
|
13605
|
-
});
|
|
13606
|
-
`;
|
|
13607
|
-
}
|
|
13608
|
-
async function installGrokPreToolUseDeny(controlledHome) {
|
|
13609
|
-
const hooksDir = join22(controlledHome, "hooks");
|
|
13610
|
-
await mkdir3(hooksDir, { recursive: true });
|
|
13611
|
-
const scriptName = "ak-bash-seatbelt.mjs";
|
|
13612
|
-
const scriptPath = join22(hooksDir, scriptName);
|
|
13613
|
-
await writeFile7(scriptPath, renderGrokBashSeatbeltHookScript(), { mode: 493 });
|
|
13614
|
-
await writeFile7(join22(hooksDir, "ak-bash-seatbelt.json"), `${JSON.stringify({
|
|
13615
|
-
hooks: {
|
|
13616
|
-
PreToolUse: [
|
|
13617
|
-
{
|
|
13618
|
-
matcher: "Bash|run_terminal_command",
|
|
13619
|
-
hooks: [
|
|
13620
|
-
{
|
|
13621
|
-
type: "command",
|
|
13622
|
-
command: process.execPath + " " + JSON.stringify(scriptPath),
|
|
13623
|
-
timeout: 5
|
|
13624
|
-
}
|
|
13625
|
-
]
|
|
13626
|
-
}
|
|
13627
|
-
]
|
|
13628
|
-
}
|
|
13629
|
-
}, null, 2)}
|
|
13630
|
-
`);
|
|
13631
|
-
}
|
|
13632
|
-
|
|
13633
13574
|
// src/grok/role-turn-host.ts
|
|
13634
13575
|
function renderGrokSystemPromptOverride(authority) {
|
|
13635
13576
|
return renderAgentStartMaterials(authority.body, authority.materials);
|
|
@@ -13756,12 +13697,6 @@ function createGrokRoleTurnHost(config) {
|
|
|
13756
13697
|
return {
|
|
13757
13698
|
executeTurn(request) {
|
|
13758
13699
|
const execution = serial.then(async () => {
|
|
13759
|
-
const inspected = await config.inspect(request);
|
|
13760
|
-
if (inspected.privateActive.length !== 0) {
|
|
13761
|
-
return failure("activation", "UncontrolledGrokSession", "private-config-active", {
|
|
13762
|
-
privateActive: [...inspected.privateActive]
|
|
13763
|
-
});
|
|
13764
|
-
}
|
|
13765
13700
|
const continuation = request.continuation;
|
|
13766
13701
|
const prepared = await config.prepare(request);
|
|
13767
13702
|
let connection;
|
|
@@ -13777,15 +13712,6 @@ function createGrokRoleTurnHost(config) {
|
|
|
13777
13712
|
clientCapabilities: {}
|
|
13778
13713
|
});
|
|
13779
13714
|
const initializeMeta = initialized._meta;
|
|
13780
|
-
const hookMeta = initialized._meta;
|
|
13781
|
-
const hookCapability = hookMeta?.["x.ai/hooks"];
|
|
13782
|
-
const canDeny = Array.isArray(hookCapability?.blockingEvents) && hookCapability.blockingEvents.includes("pre_tool_use") && Array.isArray(hookCapability.decisions) && hookCapability.decisions.includes("deny");
|
|
13783
|
-
let preToolUseDeny = false;
|
|
13784
|
-
if (canDeny && request.activation.role === "fixer") {
|
|
13785
|
-
await installGrokPreToolUseDeny(request.home);
|
|
13786
|
-
preToolUseDeny = true;
|
|
13787
|
-
}
|
|
13788
|
-
await config.recordCapabilities(request, { nativeToolNarrowing: false, preToolUseDeny });
|
|
13789
13715
|
const modelState = initializeMeta?.modelState;
|
|
13790
13716
|
const availableModels = Array.isArray(modelState?.availableModels) ? modelState.availableModels : void 0;
|
|
13791
13717
|
if (request.model !== void 0 && availableModels !== void 0 && !availableModels.some((entry) => typeof entry === "object" && entry !== null && entry.modelId === request.model?.model)) {
|
|
@@ -13933,222 +13859,10 @@ ${priorNativePaths.join("\n")}` : prepared.prompt;
|
|
|
13933
13859
|
var PRIVATE_COMPAT_ENV = Object.fromEntries(
|
|
13934
13860
|
["CLAUDE", "CURSOR", "CODEX"].flatMap((vendor) => ["SKILLS", "RULES", "AGENTS", "MCPS", "HOOKS", "SESSIONS"].map((kind) => [`GROK_${vendor}_${kind}_ENABLED`, "false"]))
|
|
13935
13861
|
);
|
|
13936
|
-
|
|
13937
|
-
function errnoCode2(error) {
|
|
13938
|
-
if (typeof error !== "object" || error === null || !("code" in error)) return void 0;
|
|
13939
|
-
const code = error.code;
|
|
13940
|
-
return typeof code === "string" ? code : void 0;
|
|
13941
|
-
}
|
|
13942
|
-
async function realpathIfPresent(path) {
|
|
13943
|
-
try {
|
|
13944
|
-
return await realpath7(path);
|
|
13945
|
-
} catch (error) {
|
|
13946
|
-
if (errnoCode2(error) === "ENOENT") return void 0;
|
|
13947
|
-
throw error;
|
|
13948
|
-
}
|
|
13949
|
-
}
|
|
13950
|
-
async function worktreeFilePresence(path) {
|
|
13951
|
-
try {
|
|
13952
|
-
const handle = await open2(path, "r");
|
|
13953
|
-
await handle.close();
|
|
13954
|
-
return "present";
|
|
13955
|
-
} catch (error) {
|
|
13956
|
-
if (errnoCode2(error) === "ENOENT") return "absent";
|
|
13957
|
-
throw error;
|
|
13958
|
-
}
|
|
13959
|
-
}
|
|
13960
|
-
async function resolveHeadTreePath(topLevel, relativePath) {
|
|
13961
|
-
const { stdout: exactOut } = await execFileAsync3(
|
|
13962
|
-
"git",
|
|
13963
|
-
["ls-tree", "--name-only", "HEAD", "--", relativePath],
|
|
13964
|
-
{ cwd: topLevel, encoding: "utf8" }
|
|
13965
|
-
);
|
|
13966
|
-
const exactHits = exactOut.split("\n").map((name) => name.trim()).filter((name) => name !== "");
|
|
13967
|
-
if (exactHits.includes(relativePath)) return relativePath;
|
|
13968
|
-
const parent = dirname15(relativePath);
|
|
13969
|
-
const leaf = basename7(relativePath);
|
|
13970
|
-
if (parent !== ".") {
|
|
13971
|
-
const { stdout: parentOut } = await execFileAsync3(
|
|
13972
|
-
"git",
|
|
13973
|
-
["ls-tree", "--name-only", "HEAD", "--", parent],
|
|
13974
|
-
{ cwd: topLevel, encoding: "utf8" }
|
|
13975
|
-
);
|
|
13976
|
-
const parentHits = parentOut.split("\n").map((name) => name.trim()).filter((name) => name !== "");
|
|
13977
|
-
if (!parentHits.includes(parent)) return void 0;
|
|
13978
|
-
}
|
|
13979
|
-
const { stdout: listing } = parent === "." ? await execFileAsync3("git", ["ls-tree", "--name-only", "HEAD"], {
|
|
13980
|
-
cwd: topLevel,
|
|
13981
|
-
encoding: "utf8"
|
|
13982
|
-
}) : await execFileAsync3("git", ["ls-tree", "--name-only", `HEAD:${parent}`], {
|
|
13983
|
-
cwd: topLevel,
|
|
13984
|
-
encoding: "utf8"
|
|
13985
|
-
});
|
|
13986
|
-
const needle = leaf.toLowerCase();
|
|
13987
|
-
const hits = listing.split("\n").map((name) => name.trim()).filter((name) => name !== "" && basename7(name).toLowerCase() === needle).map((name) => parent === "." ? basename7(name) : join23(parent, basename7(name)));
|
|
13988
|
-
return hits.length === 1 ? hits[0] : void 0;
|
|
13989
|
-
}
|
|
13990
|
-
async function isHeadMatchedProjectInstruction(repositoryCwd, absolutePath) {
|
|
13991
|
-
if (absolutePath === "" || absolutePath.includes("\0")) return false;
|
|
13992
|
-
const { stdout: topLevelOut } = await execFileAsync3("git", ["rev-parse", "--show-toplevel"], {
|
|
13993
|
-
cwd: repositoryCwd,
|
|
13994
|
-
encoding: "utf8"
|
|
13995
|
-
});
|
|
13996
|
-
await execFileAsync3("git", ["rev-parse", "--verify", "HEAD"], {
|
|
13997
|
-
cwd: repositoryCwd,
|
|
13998
|
-
encoding: "utf8"
|
|
13999
|
-
});
|
|
14000
|
-
const topLevel = await realpath7(topLevelOut.trim());
|
|
14001
|
-
const parent = await realpathIfPresent(dirname15(absolutePath));
|
|
14002
|
-
if (parent === void 0) return false;
|
|
14003
|
-
const leaf = basename7(absolutePath);
|
|
14004
|
-
if (leaf === "" || leaf === "." || leaf === "..") return false;
|
|
14005
|
-
const candidate = join23(parent, leaf);
|
|
14006
|
-
const relative3 = pathRelative(topLevel, candidate);
|
|
14007
|
-
if (relative3 === "" || relative3.startsWith("..") || isAbsolute7(relative3) || relative3.includes("\0")) {
|
|
14008
|
-
return false;
|
|
14009
|
-
}
|
|
14010
|
-
const headRel = await resolveHeadTreePath(topLevel, relative3);
|
|
14011
|
-
if (headRel === void 0) return false;
|
|
14012
|
-
const headFile = join23(topLevel, headRel);
|
|
14013
|
-
const { stdout: headBlobOut } = await execFileAsync3(
|
|
14014
|
-
"git",
|
|
14015
|
-
["rev-parse", "--verify", `HEAD:${headRel}`],
|
|
14016
|
-
{ cwd: topLevel, encoding: "utf8" }
|
|
14017
|
-
);
|
|
14018
|
-
const headBlob = headBlobOut.trim();
|
|
14019
|
-
let hashTarget = candidate;
|
|
14020
|
-
const candidatePresence = await worktreeFilePresence(candidate);
|
|
14021
|
-
if (candidatePresence === "absent") {
|
|
14022
|
-
if (candidate === headFile) return false;
|
|
14023
|
-
const headPresence = await worktreeFilePresence(headFile);
|
|
14024
|
-
if (headPresence === "absent") return false;
|
|
14025
|
-
hashTarget = headFile;
|
|
14026
|
-
}
|
|
14027
|
-
const { stdout } = await execFileAsync3("git", ["hash-object", "--", hashTarget], {
|
|
14028
|
-
cwd: topLevel,
|
|
14029
|
-
encoding: "utf8"
|
|
14030
|
-
});
|
|
14031
|
-
return headBlob === stdout.trim();
|
|
14032
|
-
}
|
|
14033
|
-
function inspectItemPath(value) {
|
|
14034
|
-
if (typeof value.source?.path === "string") return value.source.path;
|
|
14035
|
-
if (typeof value.path === "string") return value.path;
|
|
14036
|
-
return "";
|
|
14037
|
-
}
|
|
14038
|
-
function isInspectItemActive(value) {
|
|
14039
|
-
return value.disabled !== true && value.enabled !== false && value.compatibilityStatus !== "disabled";
|
|
14040
|
-
}
|
|
14041
|
-
function listActiveProjectInstructionPaths(document) {
|
|
14042
|
-
const items = document.projectInstructions;
|
|
14043
|
-
if (!Array.isArray(items)) return [];
|
|
14044
|
-
const paths = [];
|
|
14045
|
-
for (const value of items) {
|
|
14046
|
-
if (!isInspectItemActive(value)) continue;
|
|
14047
|
-
const path = inspectItemPath(value);
|
|
14048
|
-
if (path !== "") paths.push(path);
|
|
14049
|
-
}
|
|
14050
|
-
return paths;
|
|
14051
|
-
}
|
|
14052
|
-
function classifyGrokInspection(document, packageRoot, options = {}) {
|
|
14053
|
-
const privateActive = /* @__PURE__ */ new Set();
|
|
14054
|
-
const akActive = /* @__PURE__ */ new Set();
|
|
14055
|
-
const headMatched = options.headMatchedProjectInstructionPaths ?? /* @__PURE__ */ new Set();
|
|
14056
|
-
const externalCompat = document.externalCompat;
|
|
14057
|
-
if (Array.isArray(externalCompat?.cells)) {
|
|
14058
|
-
for (const cell of externalCompat.cells) {
|
|
14059
|
-
if (cell.enabled !== true) continue;
|
|
14060
|
-
privateActive.add(`externalCompat:${String(cell.vendor)}:${String(cell.surface)}`);
|
|
14061
|
-
}
|
|
14062
|
-
}
|
|
14063
|
-
for (const section of ["skills", "agents", "plugins", "mcpServers", "hooks", "projectInstructions"]) {
|
|
14064
|
-
const items = document[section];
|
|
14065
|
-
if (!Array.isArray(items)) continue;
|
|
14066
|
-
for (const value of items) {
|
|
14067
|
-
if (!isInspectItemActive(value)) continue;
|
|
14068
|
-
const sourceType = value.source?.type;
|
|
14069
|
-
const path = inspectItemPath(value);
|
|
14070
|
-
const identity = `${section}:${typeof value.name === "string" ? value.name : path}`;
|
|
14071
|
-
if (sourceType === "builtin" || sourceType === "bundled") continue;
|
|
14072
|
-
if (path === packageRoot || path.startsWith(`${packageRoot}/`)) akActive.add(identity);
|
|
14073
|
-
else if (section === "projectInstructions" && headMatched.has(path)) continue;
|
|
14074
|
-
else privateActive.add(identity);
|
|
14075
|
-
}
|
|
14076
|
-
}
|
|
14077
|
-
return { privateActive: [...privateActive].sort(), akActive: [...akActive].sort() };
|
|
14078
|
-
}
|
|
14079
|
-
var AK_BASH_SEATBELT_HOOK_FILES = ["ak-bash-seatbelt.json", "ak-bash-seatbelt.mjs"];
|
|
14080
|
-
function isMissingPathError2(error) {
|
|
14081
|
-
return error instanceof Error && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR");
|
|
14082
|
-
}
|
|
14083
|
-
async function assertControlledGrokHomeIsRealDirectory(controlledHome) {
|
|
14084
|
-
let st;
|
|
14085
|
-
try {
|
|
14086
|
-
st = await lstat3(controlledHome);
|
|
14087
|
-
} catch (error) {
|
|
14088
|
-
if (isMissingPathError2(error)) return;
|
|
14089
|
-
throw error;
|
|
14090
|
-
}
|
|
14091
|
-
if (st.isSymbolicLink()) {
|
|
14092
|
-
throw new Error(`controlled grok home must not be a symlink: ${controlledHome}`);
|
|
14093
|
-
}
|
|
14094
|
-
if (!st.isDirectory()) {
|
|
14095
|
-
throw new Error(`controlled grok home must be a real directory: ${controlledHome}`);
|
|
14096
|
-
}
|
|
14097
|
-
}
|
|
14098
|
-
async function assertControlledGrokAuthIsNotSymlink(authPath) {
|
|
14099
|
-
let st;
|
|
14100
|
-
try {
|
|
14101
|
-
st = await lstat3(authPath);
|
|
14102
|
-
} catch (error) {
|
|
14103
|
-
if (isMissingPathError2(error)) return;
|
|
14104
|
-
throw error;
|
|
14105
|
-
}
|
|
14106
|
-
if (st.isSymbolicLink()) {
|
|
14107
|
-
throw new Error(`controlled grok auth must not be a symlink: ${authPath}`);
|
|
14108
|
-
}
|
|
14109
|
-
}
|
|
14110
|
-
async function scrubAkBashSeatbeltHooks(controlledHome) {
|
|
14111
|
-
const hooksDir = join23(controlledHome, "hooks");
|
|
14112
|
-
for (const name of AK_BASH_SEATBELT_HOOK_FILES) {
|
|
14113
|
-
await rm5(join23(hooksDir, name), { force: true });
|
|
14114
|
-
}
|
|
14115
|
-
}
|
|
14116
|
-
async function prepareControlledGrokHome(sourceHome, controlledHome) {
|
|
14117
|
-
await assertControlledGrokHomeIsRealDirectory(controlledHome);
|
|
14118
|
-
await mkdir4(controlledHome, { recursive: true, mode: 448 });
|
|
14119
|
-
await assertControlledGrokHomeIsRealDirectory(controlledHome);
|
|
14120
|
-
const authPath = join23(controlledHome, "auth.json");
|
|
14121
|
-
await assertControlledGrokAuthIsNotSymlink(authPath);
|
|
14122
|
-
await rm5(authPath, { force: true });
|
|
14123
|
-
await scrubAkBashSeatbeltHooks(controlledHome);
|
|
14124
|
-
await copyFile(join23(sourceHome, ".grok", "auth.json"), authPath);
|
|
14125
|
-
}
|
|
14126
|
-
async function inspectControlledGrok(options) {
|
|
14127
|
-
const { stdout } = await execFileAsync3(options.binary, ["inspect", "--json"], {
|
|
14128
|
-
cwd: options.cwd,
|
|
14129
|
-
env: options.env,
|
|
14130
|
-
encoding: "utf8"
|
|
14131
|
-
});
|
|
14132
|
-
const document = JSON.parse(stdout);
|
|
14133
|
-
if (typeof document !== "object" || document === null || Array.isArray(document)) {
|
|
14134
|
-
throw new Error("Grok structured inspection did not return an object");
|
|
14135
|
-
}
|
|
14136
|
-
const record4 = document;
|
|
14137
|
-
const headMatchedProjectInstructionPaths = /* @__PURE__ */ new Set();
|
|
14138
|
-
for (const path of listActiveProjectInstructionPaths(record4)) {
|
|
14139
|
-
if (path === options.packageRoot || path.startsWith(`${options.packageRoot}/`)) continue;
|
|
14140
|
-
if (await isHeadMatchedProjectInstruction(options.cwd, path)) {
|
|
14141
|
-
headMatchedProjectInstructionPaths.add(path);
|
|
14142
|
-
}
|
|
14143
|
-
}
|
|
14144
|
-
return classifyGrokInspection(record4, options.packageRoot, { headMatchedProjectInstructionPaths });
|
|
14145
|
-
}
|
|
14146
|
-
function controlledGrokChildEnv(base, grokHome) {
|
|
13862
|
+
function controlledGrokChildEnv(base) {
|
|
14147
13863
|
return {
|
|
14148
13864
|
...base,
|
|
14149
13865
|
...PRIVATE_COMPAT_ENV,
|
|
14150
|
-
HOME: grokHome,
|
|
14151
|
-
GROK_HOME: grokHome,
|
|
14152
13866
|
GROK_MEMORY: "0",
|
|
14153
13867
|
GROK_SUBAGENTS: "0"
|
|
14154
13868
|
};
|
|
@@ -14168,7 +13882,7 @@ function buildGrokSkillExpansion(methodSkills, prompt) {
|
|
|
14168
13882
|
return Object.freeze({
|
|
14169
13883
|
name: parsed.name,
|
|
14170
13884
|
location: method.path,
|
|
14171
|
-
content: `References are relative to ${
|
|
13885
|
+
content: `References are relative to ${dirname15(method.path)}.
|
|
14172
13886
|
|
|
14173
13887
|
${method.body}`,
|
|
14174
13888
|
userMessage: parsed.userMessage
|
|
@@ -14238,18 +13952,18 @@ async function prepareGrokRoleEnvelope(options) {
|
|
|
14238
13952
|
let infrastructureRoundFailure;
|
|
14239
13953
|
const hostAbort = new AbortController();
|
|
14240
13954
|
const runId = request.runDirectory.split("/").filter(Boolean).at(-1) ?? randomUUID2();
|
|
14241
|
-
await
|
|
13955
|
+
await mkdir3(request.runDirectory, { recursive: true });
|
|
14242
13956
|
for (const method of request.methods) {
|
|
14243
13957
|
if (method.kind !== "skill") continue;
|
|
14244
|
-
const name =
|
|
13958
|
+
const name = basename7(dirname15(method.path));
|
|
14245
13959
|
const raw = await readFile13(method.path, "utf8");
|
|
14246
13960
|
methodSkills.set(name, { path: method.path, body: stripSkillFrontmatter(raw).trim() });
|
|
14247
13961
|
}
|
|
14248
|
-
let sessionFile = options.sessionFile ??
|
|
14249
|
-
await
|
|
13962
|
+
let sessionFile = options.sessionFile ?? join22(request.runDirectory, "session", "session.jsonl");
|
|
13963
|
+
await mkdir3(dirname15(sessionFile), { recursive: true });
|
|
14250
13964
|
if (request.continuation.kind !== "resume") {
|
|
14251
13965
|
try {
|
|
14252
|
-
await
|
|
13966
|
+
await writeFile7(
|
|
14253
13967
|
sessionFile,
|
|
14254
13968
|
`${JSON.stringify({
|
|
14255
13969
|
type: "session",
|
|
@@ -14273,7 +13987,7 @@ async function prepareGrokRoleEnvelope(options) {
|
|
|
14273
13987
|
getLeafEntry: () => sessionEntries.at(-1),
|
|
14274
13988
|
getLeafId: () => runId,
|
|
14275
13989
|
getEntries: () => sessionEntries,
|
|
14276
|
-
getSessionDir: () =>
|
|
13990
|
+
getSessionDir: () => dirname15(sessionFile),
|
|
14277
13991
|
getSessionFile: () => sessionFile,
|
|
14278
13992
|
getHeader: () => ({ type: "session", id: runId }),
|
|
14279
13993
|
setSessionFile(path) {
|
|
@@ -14711,11 +14425,11 @@ async function prepareGrokRoleEnvelope(options) {
|
|
|
14711
14425
|
}
|
|
14712
14426
|
|
|
14713
14427
|
// src/grok/session-identity.ts
|
|
14714
|
-
import { mkdir as
|
|
14715
|
-
import { dirname as
|
|
14428
|
+
import { mkdir as mkdir4, readFile as readFile14, rename, writeFile as writeFile8 } from "node:fs/promises";
|
|
14429
|
+
import { dirname as dirname16, join as join23 } from "node:path";
|
|
14716
14430
|
var GROK_ACP_SESSION_BINDING = "grok-acp-session.json";
|
|
14717
14431
|
function createGrokSessionIdentityAuthority(authority) {
|
|
14718
|
-
const bindingPath = (principal) =>
|
|
14432
|
+
const bindingPath = (principal) => join23(authority.decode(principal).sessionDirectory, GROK_ACP_SESSION_BINDING);
|
|
14719
14433
|
return {
|
|
14720
14434
|
resolveSessionFile(principal) {
|
|
14721
14435
|
return authority.decode(principal).sessionFile;
|
|
@@ -14734,9 +14448,9 @@ function createGrokSessionIdentityAuthority(authority) {
|
|
|
14734
14448
|
},
|
|
14735
14449
|
async bind(principal, sessionId) {
|
|
14736
14450
|
const target = bindingPath(principal);
|
|
14737
|
-
await
|
|
14451
|
+
await mkdir4(dirname16(target), { recursive: true });
|
|
14738
14452
|
const temporary = `${target}.${process.pid}.tmp`;
|
|
14739
|
-
await
|
|
14453
|
+
await writeFile8(temporary, `${JSON.stringify({ sessionId })}
|
|
14740
14454
|
`, { encoding: "utf8", mode: 384 });
|
|
14741
14455
|
await rename(temporary, target);
|
|
14742
14456
|
}
|
|
@@ -14745,79 +14459,14 @@ function createGrokSessionIdentityAuthority(authority) {
|
|
|
14745
14459
|
|
|
14746
14460
|
// src/grok/production-host.ts
|
|
14747
14461
|
function resolveGrokBinary(operatorHome) {
|
|
14748
|
-
return
|
|
14462
|
+
return join24(operatorHome, ".grok", "bin", "grok");
|
|
14749
14463
|
}
|
|
14750
|
-
|
|
14751
|
-
present: false
|
|
14752
|
-
};
|
|
14753
|
-
async function settleProductionGrokHomeCleanup(controlledHome, primaryFailure, concurrentMessage) {
|
|
14754
|
-
try {
|
|
14755
|
-
await assertControlledGrokHomeIsRealDirectory(controlledHome);
|
|
14756
|
-
const authPath = join26(controlledHome, "auth.json");
|
|
14757
|
-
await assertControlledGrokAuthIsNotSymlink(authPath);
|
|
14758
|
-
await rm6(authPath, { force: true });
|
|
14759
|
-
await scrubAkBashSeatbeltHooks(controlledHome);
|
|
14760
|
-
} catch (cleanupFailure) {
|
|
14761
|
-
if (primaryFailure.present) {
|
|
14762
|
-
throw new AggregateError([primaryFailure.value, cleanupFailure], concurrentMessage, {
|
|
14763
|
-
cause: primaryFailure.value
|
|
14764
|
-
});
|
|
14765
|
-
}
|
|
14766
|
-
throw cleanupFailure;
|
|
14767
|
-
}
|
|
14768
|
-
if (primaryFailure.present) {
|
|
14769
|
-
throw primaryFailure.value;
|
|
14770
|
-
}
|
|
14771
|
-
}
|
|
14772
|
-
async function openProductionGrokHome(runDirectory, operatorHome) {
|
|
14773
|
-
const controlledHome = join26(runDirectory, "grok-home");
|
|
14774
|
-
try {
|
|
14775
|
-
await prepareControlledGrokHome(operatorHome, controlledHome);
|
|
14776
|
-
return controlledHome;
|
|
14777
|
-
} catch (error) {
|
|
14778
|
-
await settleProductionGrokHomeCleanup(
|
|
14779
|
-
controlledHome,
|
|
14780
|
-
{ present: true, value: error },
|
|
14781
|
-
"production grok home open failed and its cleanup also failed"
|
|
14782
|
-
);
|
|
14783
|
-
throw error;
|
|
14784
|
-
}
|
|
14785
|
-
}
|
|
14786
|
-
function childEnv(controlledHome, packageRoot) {
|
|
14464
|
+
function childEnv(packageRoot) {
|
|
14787
14465
|
return {
|
|
14788
|
-
...controlledGrokChildEnv(process.env
|
|
14466
|
+
...controlledGrokChildEnv(process.env),
|
|
14789
14467
|
AK_PACKAGE_ROOT: packageRoot
|
|
14790
14468
|
};
|
|
14791
14469
|
}
|
|
14792
|
-
async function bindProductionGrokIsolation(runDirectory, operatorHome, packageRoot) {
|
|
14793
|
-
const controlledHome = await openProductionGrokHome(runDirectory, operatorHome);
|
|
14794
|
-
return {
|
|
14795
|
-
operatorHome,
|
|
14796
|
-
controlledHome,
|
|
14797
|
-
binary: resolveGrokBinary(operatorHome),
|
|
14798
|
-
env: childEnv(controlledHome, packageRoot)
|
|
14799
|
-
};
|
|
14800
|
-
}
|
|
14801
|
-
async function withProductionGrokIsolation(runDirectory, operatorHome, packageRoot, run) {
|
|
14802
|
-
let binding;
|
|
14803
|
-
let primaryFailure = NO_PRODUCTION_GROK_PRIMARY_FAILURE;
|
|
14804
|
-
let value;
|
|
14805
|
-
try {
|
|
14806
|
-
binding = await bindProductionGrokIsolation(runDirectory, operatorHome, packageRoot);
|
|
14807
|
-
value = await run(binding);
|
|
14808
|
-
} catch (error) {
|
|
14809
|
-
primaryFailure = { present: true, value: error };
|
|
14810
|
-
}
|
|
14811
|
-
if (binding !== void 0) {
|
|
14812
|
-
await settleProductionGrokHomeCleanup(
|
|
14813
|
-
binding.controlledHome,
|
|
14814
|
-
primaryFailure,
|
|
14815
|
-
"production grok isolation turn and cleanup failed"
|
|
14816
|
-
);
|
|
14817
|
-
}
|
|
14818
|
-
if (primaryFailure.present) throw primaryFailure.value;
|
|
14819
|
-
return value;
|
|
14820
|
-
}
|
|
14821
14470
|
var navigatorRoutePlaybookPath = fileURLToPath3(
|
|
14822
14471
|
new URL("../../resources/navigator-route-playbook.md", import.meta.url)
|
|
14823
14472
|
);
|
|
@@ -14885,76 +14534,23 @@ function createGrokRoleRuntimeDependencies(packageRoot) {
|
|
|
14885
14534
|
})
|
|
14886
14535
|
};
|
|
14887
14536
|
}
|
|
14888
|
-
async function recordGrokCapabilities(request, declaration) {
|
|
14889
|
-
await writeFile10(
|
|
14890
|
-
join26(request.runDirectory, "grok-capabilities.json"),
|
|
14891
|
-
`${JSON.stringify(declaration)}
|
|
14892
|
-
`,
|
|
14893
|
-
"utf8"
|
|
14894
|
-
);
|
|
14895
|
-
}
|
|
14896
14537
|
function createProductionGrokRoleTurnHost(options) {
|
|
14897
14538
|
const { packageRoot, principalAuthority } = options;
|
|
14898
|
-
|
|
14899
|
-
|
|
14900
|
-
const inner = createComposedGrokRoleTurnHost({
|
|
14539
|
+
const env = childEnv(packageRoot);
|
|
14540
|
+
return createComposedGrokRoleTurnHost({
|
|
14901
14541
|
sessionIdentity: createGrokSessionIdentityAuthority(principalAuthority),
|
|
14902
14542
|
roleRuntimeDependencies: createGrokRoleRuntimeDependencies(packageRoot),
|
|
14903
|
-
recordCapabilities: recordGrokCapabilities,
|
|
14904
|
-
async inspect(request) {
|
|
14905
|
-
if (turn === void 0) {
|
|
14906
|
-
throw new Error("production grok inspect requires an active isolated turn");
|
|
14907
|
-
}
|
|
14908
|
-
return inspectControlledGrok({
|
|
14909
|
-
binary: turn.binary,
|
|
14910
|
-
cwd: request.cwd,
|
|
14911
|
-
env: turn.env,
|
|
14912
|
-
packageRoot
|
|
14913
|
-
});
|
|
14914
|
-
},
|
|
14915
14543
|
async connect(request) {
|
|
14916
|
-
if (turn === void 0) {
|
|
14917
|
-
throw new Error("production grok connect requires an active isolated turn");
|
|
14918
|
-
}
|
|
14919
14544
|
return connectGrokAcpStdio({
|
|
14920
|
-
binary:
|
|
14545
|
+
binary: resolveGrokBinary(request.home),
|
|
14921
14546
|
cwd: request.cwd,
|
|
14922
|
-
env
|
|
14547
|
+
env,
|
|
14923
14548
|
...request.model === void 0 ? {} : { model: request.model.model }
|
|
14924
14549
|
});
|
|
14925
14550
|
}
|
|
14926
14551
|
});
|
|
14927
|
-
return {
|
|
14928
|
-
executeTurn(request) {
|
|
14929
|
-
const execution = serial.then(
|
|
14930
|
-
() => withProductionGrokIsolation(
|
|
14931
|
-
request.runDirectory,
|
|
14932
|
-
request.home,
|
|
14933
|
-
packageRoot,
|
|
14934
|
-
async (binding) => {
|
|
14935
|
-
turn = binding;
|
|
14936
|
-
try {
|
|
14937
|
-
return await inner.executeTurn({ ...request, home: binding.controlledHome });
|
|
14938
|
-
} finally {
|
|
14939
|
-
turn = void 0;
|
|
14940
|
-
}
|
|
14941
|
-
}
|
|
14942
|
-
)
|
|
14943
|
-
);
|
|
14944
|
-
serial = execution.then(
|
|
14945
|
-
() => void 0,
|
|
14946
|
-
() => void 0
|
|
14947
|
-
);
|
|
14948
|
-
return execution;
|
|
14949
|
-
}
|
|
14950
|
-
};
|
|
14951
14552
|
}
|
|
14952
14553
|
export {
|
|
14953
|
-
NO_PRODUCTION_GROK_PRIMARY_FAILURE,
|
|
14954
|
-
bindProductionGrokIsolation,
|
|
14955
14554
|
createGrokRoleRuntimeDependencies,
|
|
14956
|
-
createProductionGrokRoleTurnHost
|
|
14957
|
-
openProductionGrokHome,
|
|
14958
|
-
settleProductionGrokHomeCleanup,
|
|
14959
|
-
withProductionGrokIsolation
|
|
14555
|
+
createProductionGrokRoleTurnHost
|
|
14960
14556
|
};
|