@akagilnc/pi-workflow-roles 0.1.3545 → 0.1.3552

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 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`, Grok: `runDirectory/grok-home`), 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.
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`,Grok:`runDirectory/grok-home`),统一账目归入司天台。要不要续跑由调用者决定:不再要求 typed HTTP 429,也不要求 `resumable` 状态。未知 run ID、session 主体不在则拒绝。所有可调用角色均可手动 resume:给事中、左拾遗始于 #599,通进司、太医署、符宝郎、察院始于 #633。
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, rm as rm6, writeFile as writeFile10 } from "node:fs/promises";
1243
- import { join as join26 } from "node:path";
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
  }
@@ -6954,6 +6952,16 @@ var SUPPORT_COMMAND_HELP = {
6954
6952
  "ak-role --host grok-build resume 01abc\u2026",
6955
6953
  "ak-role --engine agy resume 01abc\u2026"
6956
6954
  ]
6955
+ },
6956
+ new: {
6957
+ command: "new",
6958
+ summary: "Explicit fresh summons: same role options as a direct call, but always mint a new run (skip same-ticket auto-resume). Caller chooses new vs resume; no overflow judgment.",
6959
+ usage: ["ak-role new <role> [options] \u2026"],
6960
+ examples: [
6961
+ 'ak-role new countersign --attach ./ticket.md "\u88C1\uFF1A\u672C\u7968 #708 \u662F\u5426\u8DB3\u4EE5\u5F00\u5DE5\u3002"',
6962
+ "ak-role new notary --source-run 01abc\u2026@countersign",
6963
+ "ak-role --host grok-build new inspector --attach ./change.patch"
6964
+ ]
6957
6965
  }
6958
6966
  };
6959
6967
  var PUBLIC_COMMAND_HELP = {
@@ -13558,17 +13566,14 @@ function createRoleRuntimeExtension(dependencies) {
13558
13566
 
13559
13567
  // src/grok/role-envelope.ts
13560
13568
  import { randomUUID as randomUUID2 } from "node:crypto";
13561
- import { mkdir as mkdir5, readFile as readFile13, writeFile as writeFile8 } from "node:fs/promises";
13569
+ import { mkdir as mkdir3, readFile as readFile13, writeFile as writeFile7 } from "node:fs/promises";
13562
13570
  import { createServer } from "node:net";
13563
- import { basename as basename8, dirname as dirname16, join as join24 } from "node:path";
13571
+ import { basename as basename7, dirname as dirname15, join as join22 } from "node:path";
13564
13572
  import { fileURLToPath as fileURLToPath2 } from "node:url";
13565
13573
 
13566
13574
  // src/grok/role-turn-host.ts
13567
- import { execFile as execFile3, spawn as spawn4 } from "node:child_process";
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";
13575
+ import { spawn as spawn4 } from "node:child_process";
13570
13576
  import { createInterface } from "node:readline";
13571
- import { promisify as promisify3 } from "node:util";
13572
13577
 
13573
13578
  // src/agent-start-materials.ts
13574
13579
  function renderAgentStartMaterials(body, materials) {
@@ -13576,60 +13581,6 @@ function renderAgentStartMaterials(body, materials) {
13576
13581
  return [body, ...materials.map((material) => JSON.stringify(material))].join("\n\n");
13577
13582
  }
13578
13583
 
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
13584
  // src/grok/role-turn-host.ts
13634
13585
  function renderGrokSystemPromptOverride(authority) {
13635
13586
  return renderAgentStartMaterials(authority.body, authority.materials);
@@ -13756,12 +13707,6 @@ function createGrokRoleTurnHost(config) {
13756
13707
  return {
13757
13708
  executeTurn(request) {
13758
13709
  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
13710
  const continuation = request.continuation;
13766
13711
  const prepared = await config.prepare(request);
13767
13712
  let connection;
@@ -13777,15 +13722,6 @@ function createGrokRoleTurnHost(config) {
13777
13722
  clientCapabilities: {}
13778
13723
  });
13779
13724
  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
13725
  const modelState = initializeMeta?.modelState;
13790
13726
  const availableModels = Array.isArray(modelState?.availableModels) ? modelState.availableModels : void 0;
13791
13727
  if (request.model !== void 0 && availableModels !== void 0 && !availableModels.some((entry) => typeof entry === "object" && entry !== null && entry.modelId === request.model?.model)) {
@@ -13933,222 +13869,10 @@ ${priorNativePaths.join("\n")}` : prepared.prompt;
13933
13869
  var PRIVATE_COMPAT_ENV = Object.fromEntries(
13934
13870
  ["CLAUDE", "CURSOR", "CODEX"].flatMap((vendor) => ["SKILLS", "RULES", "AGENTS", "MCPS", "HOOKS", "SESSIONS"].map((kind) => [`GROK_${vendor}_${kind}_ENABLED`, "false"]))
13935
13871
  );
13936
- var execFileAsync3 = promisify3(execFile3);
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) {
13872
+ function controlledGrokChildEnv(base) {
14147
13873
  return {
14148
13874
  ...base,
14149
13875
  ...PRIVATE_COMPAT_ENV,
14150
- HOME: grokHome,
14151
- GROK_HOME: grokHome,
14152
13876
  GROK_MEMORY: "0",
14153
13877
  GROK_SUBAGENTS: "0"
14154
13878
  };
@@ -14168,7 +13892,7 @@ function buildGrokSkillExpansion(methodSkills, prompt) {
14168
13892
  return Object.freeze({
14169
13893
  name: parsed.name,
14170
13894
  location: method.path,
14171
- content: `References are relative to ${dirname16(method.path)}.
13895
+ content: `References are relative to ${dirname15(method.path)}.
14172
13896
 
14173
13897
  ${method.body}`,
14174
13898
  userMessage: parsed.userMessage
@@ -14238,18 +13962,18 @@ async function prepareGrokRoleEnvelope(options) {
14238
13962
  let infrastructureRoundFailure;
14239
13963
  const hostAbort = new AbortController();
14240
13964
  const runId = request.runDirectory.split("/").filter(Boolean).at(-1) ?? randomUUID2();
14241
- await mkdir5(request.runDirectory, { recursive: true });
13965
+ await mkdir3(request.runDirectory, { recursive: true });
14242
13966
  for (const method of request.methods) {
14243
13967
  if (method.kind !== "skill") continue;
14244
- const name = basename8(dirname16(method.path));
13968
+ const name = basename7(dirname15(method.path));
14245
13969
  const raw = await readFile13(method.path, "utf8");
14246
13970
  methodSkills.set(name, { path: method.path, body: stripSkillFrontmatter(raw).trim() });
14247
13971
  }
14248
- let sessionFile = options.sessionFile ?? join24(request.runDirectory, "session", "session.jsonl");
14249
- await mkdir5(dirname16(sessionFile), { recursive: true });
13972
+ let sessionFile = options.sessionFile ?? join22(request.runDirectory, "session", "session.jsonl");
13973
+ await mkdir3(dirname15(sessionFile), { recursive: true });
14250
13974
  if (request.continuation.kind !== "resume") {
14251
13975
  try {
14252
- await writeFile8(
13976
+ await writeFile7(
14253
13977
  sessionFile,
14254
13978
  `${JSON.stringify({
14255
13979
  type: "session",
@@ -14273,7 +13997,7 @@ async function prepareGrokRoleEnvelope(options) {
14273
13997
  getLeafEntry: () => sessionEntries.at(-1),
14274
13998
  getLeafId: () => runId,
14275
13999
  getEntries: () => sessionEntries,
14276
- getSessionDir: () => dirname16(sessionFile),
14000
+ getSessionDir: () => dirname15(sessionFile),
14277
14001
  getSessionFile: () => sessionFile,
14278
14002
  getHeader: () => ({ type: "session", id: runId }),
14279
14003
  setSessionFile(path) {
@@ -14711,11 +14435,11 @@ async function prepareGrokRoleEnvelope(options) {
14711
14435
  }
14712
14436
 
14713
14437
  // src/grok/session-identity.ts
14714
- import { mkdir as mkdir6, readFile as readFile14, rename, writeFile as writeFile9 } from "node:fs/promises";
14715
- import { dirname as dirname17, join as join25 } from "node:path";
14438
+ import { mkdir as mkdir4, readFile as readFile14, rename, writeFile as writeFile8 } from "node:fs/promises";
14439
+ import { dirname as dirname16, join as join23 } from "node:path";
14716
14440
  var GROK_ACP_SESSION_BINDING = "grok-acp-session.json";
14717
14441
  function createGrokSessionIdentityAuthority(authority) {
14718
- const bindingPath = (principal) => join25(authority.decode(principal).sessionDirectory, GROK_ACP_SESSION_BINDING);
14442
+ const bindingPath = (principal) => join23(authority.decode(principal).sessionDirectory, GROK_ACP_SESSION_BINDING);
14719
14443
  return {
14720
14444
  resolveSessionFile(principal) {
14721
14445
  return authority.decode(principal).sessionFile;
@@ -14734,9 +14458,9 @@ function createGrokSessionIdentityAuthority(authority) {
14734
14458
  },
14735
14459
  async bind(principal, sessionId) {
14736
14460
  const target = bindingPath(principal);
14737
- await mkdir6(dirname17(target), { recursive: true });
14461
+ await mkdir4(dirname16(target), { recursive: true });
14738
14462
  const temporary = `${target}.${process.pid}.tmp`;
14739
- await writeFile9(temporary, `${JSON.stringify({ sessionId })}
14463
+ await writeFile8(temporary, `${JSON.stringify({ sessionId })}
14740
14464
  `, { encoding: "utf8", mode: 384 });
14741
14465
  await rename(temporary, target);
14742
14466
  }
@@ -14745,79 +14469,14 @@ function createGrokSessionIdentityAuthority(authority) {
14745
14469
 
14746
14470
  // src/grok/production-host.ts
14747
14471
  function resolveGrokBinary(operatorHome) {
14748
- return join26(operatorHome, ".grok", "bin", "grok");
14749
- }
14750
- var NO_PRODUCTION_GROK_PRIMARY_FAILURE = {
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
- }
14472
+ return join24(operatorHome, ".grok", "bin", "grok");
14785
14473
  }
14786
- function childEnv(controlledHome, packageRoot) {
14474
+ function childEnv(packageRoot) {
14787
14475
  return {
14788
- ...controlledGrokChildEnv(process.env, controlledHome),
14476
+ ...controlledGrokChildEnv(process.env),
14789
14477
  AK_PACKAGE_ROOT: packageRoot
14790
14478
  };
14791
14479
  }
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
14480
  var navigatorRoutePlaybookPath = fileURLToPath3(
14822
14481
  new URL("../../resources/navigator-route-playbook.md", import.meta.url)
14823
14482
  );
@@ -14885,76 +14544,23 @@ function createGrokRoleRuntimeDependencies(packageRoot) {
14885
14544
  })
14886
14545
  };
14887
14546
  }
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
14547
  function createProductionGrokRoleTurnHost(options) {
14897
14548
  const { packageRoot, principalAuthority } = options;
14898
- let turn;
14899
- let serial = Promise.resolve();
14900
- const inner = createComposedGrokRoleTurnHost({
14549
+ const env = childEnv(packageRoot);
14550
+ return createComposedGrokRoleTurnHost({
14901
14551
  sessionIdentity: createGrokSessionIdentityAuthority(principalAuthority),
14902
14552
  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
14553
  async connect(request) {
14916
- if (turn === void 0) {
14917
- throw new Error("production grok connect requires an active isolated turn");
14918
- }
14919
14554
  return connectGrokAcpStdio({
14920
- binary: turn.binary,
14555
+ binary: resolveGrokBinary(request.home),
14921
14556
  cwd: request.cwd,
14922
- env: turn.env,
14557
+ env,
14923
14558
  ...request.model === void 0 ? {} : { model: request.model.model }
14924
14559
  });
14925
14560
  }
14926
14561
  });
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
14562
  }
14952
14563
  export {
14953
- NO_PRODUCTION_GROK_PRIMARY_FAILURE,
14954
- bindProductionGrokIsolation,
14955
14564
  createGrokRoleRuntimeDependencies,
14956
- createProductionGrokRoleTurnHost,
14957
- openProductionGrokHome,
14958
- settleProductionGrokHomeCleanup,
14959
- withProductionGrokIsolation
14565
+ createProductionGrokRoleTurnHost
14960
14566
  };