oh-my-codex 0.18.11 → 0.18.13
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/Cargo.lock +6 -6
- package/Cargo.toml +1 -1
- package/README.md +9 -1
- package/dist/autopilot/__tests__/ralplan-gate.test.js +668 -0
- package/dist/autopilot/__tests__/ralplan-gate.test.js.map +1 -1
- package/dist/autopilot/completion-gate.d.ts +10 -0
- package/dist/autopilot/completion-gate.d.ts.map +1 -0
- package/dist/autopilot/completion-gate.js +154 -0
- package/dist/autopilot/completion-gate.js.map +1 -0
- package/dist/autopilot/ralplan-gate.d.ts.map +1 -1
- package/dist/autopilot/ralplan-gate.js +42 -21
- package/dist/autopilot/ralplan-gate.js.map +1 -1
- package/dist/cli/__tests__/codex-plugin-layout.test.js +46 -3
- package/dist/cli/__tests__/codex-plugin-layout.test.js.map +1 -1
- package/dist/cli/__tests__/doctor-invalid-config.test.js +35 -0
- package/dist/cli/__tests__/doctor-invalid-config.test.js.map +1 -1
- package/dist/cli/__tests__/doctor-warning-copy.test.js +317 -0
- package/dist/cli/__tests__/doctor-warning-copy.test.js.map +1 -1
- package/dist/cli/__tests__/index.test.js +120 -2
- package/dist/cli/__tests__/index.test.js.map +1 -1
- package/dist/cli/__tests__/launch-fallback.test.js +1 -1
- package/dist/cli/__tests__/launch-fallback.test.js.map +1 -1
- package/dist/cli/__tests__/resume.test.js +217 -1
- package/dist/cli/__tests__/resume.test.js.map +1 -1
- package/dist/cli/__tests__/session-scoped-runtime.test.js +101 -0
- package/dist/cli/__tests__/session-scoped-runtime.test.js.map +1 -1
- package/dist/cli/__tests__/session-search-help.test.js +3 -2
- package/dist/cli/__tests__/session-search-help.test.js.map +1 -1
- package/dist/cli/__tests__/session-search.test.js +64 -2
- package/dist/cli/__tests__/session-search.test.js.map +1 -1
- package/dist/cli/__tests__/setup-agents-overwrite.test.js +289 -1
- package/dist/cli/__tests__/setup-agents-overwrite.test.js.map +1 -1
- package/dist/cli/__tests__/setup-install-mode.test.js +290 -17
- package/dist/cli/__tests__/setup-install-mode.test.js.map +1 -1
- package/dist/cli/__tests__/setup-prompts-overwrite.test.js +74 -0
- package/dist/cli/__tests__/setup-prompts-overwrite.test.js.map +1 -1
- package/dist/cli/__tests__/setup-scope.test.js +45 -0
- package/dist/cli/__tests__/setup-scope.test.js.map +1 -1
- package/dist/cli/__tests__/state.test.js +93 -0
- package/dist/cli/__tests__/state.test.js.map +1 -1
- package/dist/cli/__tests__/update.test.js +157 -3
- package/dist/cli/__tests__/update.test.js.map +1 -1
- package/dist/cli/__tests__/version-sync-contract.test.js +2 -0
- package/dist/cli/__tests__/version-sync-contract.test.js.map +1 -1
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +90 -12
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/index.d.ts +13 -4
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +439 -46
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/project-runtime-codex-homes.d.ts +6 -0
- package/dist/cli/project-runtime-codex-homes.d.ts.map +1 -0
- package/dist/cli/project-runtime-codex-homes.js +27 -0
- package/dist/cli/project-runtime-codex-homes.js.map +1 -0
- package/dist/cli/session-search.d.ts.map +1 -1
- package/dist/cli/session-search.js +8 -1
- package/dist/cli/session-search.js.map +1 -1
- package/dist/cli/setup.d.ts +2 -2
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +482 -126
- package/dist/cli/setup.js.map +1 -1
- package/dist/cli/state.d.ts.map +1 -1
- package/dist/cli/state.js +79 -8
- package/dist/cli/state.js.map +1 -1
- package/dist/cli/update.d.ts +1 -0
- package/dist/cli/update.d.ts.map +1 -1
- package/dist/cli/update.js +42 -10
- package/dist/cli/update.js.map +1 -1
- package/dist/config/__tests__/codex-hooks.test.js +73 -29
- package/dist/config/__tests__/codex-hooks.test.js.map +1 -1
- package/dist/config/codex-hooks.d.ts +14 -0
- package/dist/config/codex-hooks.d.ts.map +1 -1
- package/dist/config/codex-hooks.js +54 -51
- package/dist/config/codex-hooks.js.map +1 -1
- package/dist/config/generator.d.ts +1 -1
- package/dist/config/generator.d.ts.map +1 -1
- package/dist/config/generator.js +1 -1
- package/dist/config/generator.js.map +1 -1
- package/dist/hooks/__tests__/best-practice-research-skill.test.js +12 -0
- package/dist/hooks/__tests__/best-practice-research-skill.test.js.map +1 -1
- package/dist/hud/__tests__/authority.test.js +45 -12
- package/dist/hud/__tests__/authority.test.js.map +1 -1
- package/dist/hud/__tests__/reconcile.test.js +95 -0
- package/dist/hud/__tests__/reconcile.test.js.map +1 -1
- package/dist/hud/__tests__/render.test.js +6 -6
- package/dist/hud/__tests__/render.test.js.map +1 -1
- package/dist/hud/__tests__/tmux.test.js +2 -2
- package/dist/hud/__tests__/tmux.test.js.map +1 -1
- package/dist/hud/authority.d.ts.map +1 -1
- package/dist/hud/authority.js +17 -2
- package/dist/hud/authority.js.map +1 -1
- package/dist/hud/index.js +1 -4
- package/dist/hud/index.js.map +1 -1
- package/dist/hud/reconcile.d.ts.map +1 -1
- package/dist/hud/reconcile.js +42 -0
- package/dist/hud/reconcile.js.map +1 -1
- package/dist/hud/render.d.ts.map +1 -1
- package/dist/hud/render.js +6 -0
- package/dist/hud/render.js.map +1 -1
- package/dist/hud/tmux.d.ts.map +1 -1
- package/dist/hud/tmux.js +5 -4
- package/dist/hud/tmux.js.map +1 -1
- package/dist/mcp/__tests__/bootstrap.test.js +31 -1
- package/dist/mcp/__tests__/bootstrap.test.js.map +1 -1
- package/dist/mcp/bootstrap.d.ts +1 -0
- package/dist/mcp/bootstrap.d.ts.map +1 -1
- package/dist/mcp/bootstrap.js +32 -0
- package/dist/mcp/bootstrap.js.map +1 -1
- package/dist/modes/__tests__/base-autopilot-gates.test.d.ts +2 -0
- package/dist/modes/__tests__/base-autopilot-gates.test.d.ts.map +1 -0
- package/dist/modes/__tests__/base-autopilot-gates.test.js +154 -0
- package/dist/modes/__tests__/base-autopilot-gates.test.js.map +1 -0
- package/dist/modes/base.d.ts +4 -1
- package/dist/modes/base.d.ts.map +1 -1
- package/dist/modes/base.js +71 -1
- package/dist/modes/base.js.map +1 -1
- package/dist/pipeline/__tests__/orchestrator.test.js +144 -3
- package/dist/pipeline/__tests__/orchestrator.test.js.map +1 -1
- package/dist/pipeline/__tests__/stages.test.js +109 -0
- package/dist/pipeline/__tests__/stages.test.js.map +1 -1
- package/dist/pipeline/orchestrator.d.ts.map +1 -1
- package/dist/pipeline/orchestrator.js +11 -4
- package/dist/pipeline/orchestrator.js.map +1 -1
- package/dist/pipeline/stages/code-review.d.ts +2 -0
- package/dist/pipeline/stages/code-review.d.ts.map +1 -1
- package/dist/pipeline/stages/code-review.js +2 -0
- package/dist/pipeline/stages/code-review.js.map +1 -1
- package/dist/pipeline/stages/ultraqa.d.ts +3 -0
- package/dist/pipeline/stages/ultraqa.d.ts.map +1 -1
- package/dist/pipeline/stages/ultraqa.js +3 -0
- package/dist/pipeline/stages/ultraqa.js.map +1 -1
- package/dist/ralplan/__tests__/consensus-gate.test.d.ts +2 -0
- package/dist/ralplan/__tests__/consensus-gate.test.d.ts.map +1 -0
- package/dist/ralplan/__tests__/consensus-gate.test.js +631 -0
- package/dist/ralplan/__tests__/consensus-gate.test.js.map +1 -0
- package/dist/ralplan/consensus-gate.d.ts +9 -1
- package/dist/ralplan/consensus-gate.d.ts.map +1 -1
- package/dist/ralplan/consensus-gate.js +287 -65
- package/dist/ralplan/consensus-gate.js.map +1 -1
- package/dist/scripts/__tests__/codex-native-hook.test.js +481 -0
- package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -1
- package/dist/scripts/codex-native-hook.d.ts.map +1 -1
- package/dist/scripts/codex-native-hook.js +145 -25
- package/dist/scripts/codex-native-hook.js.map +1 -1
- package/dist/scripts/codex-native-pre-post.d.ts +1 -0
- package/dist/scripts/codex-native-pre-post.d.ts.map +1 -1
- package/dist/scripts/codex-native-pre-post.js +130 -0
- package/dist/scripts/codex-native-pre-post.js.map +1 -1
- package/dist/session-history/__tests__/search.test.js +166 -0
- package/dist/session-history/__tests__/search.test.js.map +1 -1
- package/dist/session-history/search.d.ts +7 -0
- package/dist/session-history/search.d.ts.map +1 -1
- package/dist/session-history/search.js +83 -24
- package/dist/session-history/search.js.map +1 -1
- package/dist/sidecar/__tests__/collector.test.js +60 -0
- package/dist/sidecar/__tests__/collector.test.js.map +1 -1
- package/dist/sidecar/collector.d.ts.map +1 -1
- package/dist/sidecar/collector.js +3 -6
- package/dist/sidecar/collector.js.map +1 -1
- package/dist/state/__tests__/operations.test.js +622 -0
- package/dist/state/__tests__/operations.test.js.map +1 -1
- package/dist/state/__tests__/skill-active.test.js +82 -0
- package/dist/state/__tests__/skill-active.test.js.map +1 -1
- package/dist/state/operations.d.ts.map +1 -1
- package/dist/state/operations.js +31 -9
- package/dist/state/operations.js.map +1 -1
- package/dist/state/skill-active.d.ts.map +1 -1
- package/dist/state/skill-active.js +41 -1
- package/dist/state/skill-active.js.map +1 -1
- package/dist/team/__tests__/runtime.test.js +81 -57
- package/dist/team/__tests__/runtime.test.js.map +1 -1
- package/dist/team/runtime.js +4 -4
- package/dist/team/runtime.js.map +1 -1
- package/dist/utils/__tests__/paths.test.js +23 -0
- package/dist/utils/__tests__/paths.test.js.map +1 -1
- package/dist/utils/__tests__/version.test.js +27 -0
- package/dist/utils/__tests__/version.test.js.map +1 -1
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +4 -2
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/version.d.ts.map +1 -1
- package/dist/utils/version.js +7 -2
- package/dist/utils/version.js.map +1 -1
- package/dist/verification/__tests__/ci-rust-gates.test.js +4 -2
- package/dist/verification/__tests__/ci-rust-gates.test.js.map +1 -1
- package/dist/verification/__tests__/dev-merge-issue-close-workflow.test.js +71 -3
- package/dist/verification/__tests__/dev-merge-issue-close-workflow.test.js.map +1 -1
- package/package.json +1 -1
- package/plugins/oh-my-codex/.codex-plugin/plugin.json +1 -1
- package/plugins/oh-my-codex/hooks/codex-native-hook.mjs +53 -2
- package/plugins/oh-my-codex/skills/best-practice-research/SKILL.md +6 -1
- package/skills/best-practice-research/SKILL.md +6 -1
- package/src/scripts/__tests__/codex-native-hook.test.ts +615 -0
- package/src/scripts/codex-native-hook.ts +162 -32
- package/src/scripts/codex-native-pre-post.ts +137 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codex-native-hook.d.ts","sourceRoot":"","sources":["../../src/scripts/codex-native-hook.ts"],"names":[],"mappings":"AA2CA,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"codex-native-hook.d.ts","sourceRoot":"","sources":["../../src/scripts/codex-native-hook.ts"],"names":[],"mappings":"AA2CA,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,8BAA8B,CAAC;AAgCtC,OAAO,EAAE,2BAA2B,EAAE,MAAM,qBAAqB,CAAC;AAwClE,KAAK,kBAAkB,GACnB,cAAc,GACd,YAAY,GACZ,aAAa,GACb,kBAAkB,GAClB,YAAY,GACZ,aAAa,GACb,MAAM,CAAC;AAEX,KAAK,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEhD,UAAU,yBAAyB;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,6BAA6B,CAAC,EAAE,OAAO,2BAA2B,CAAC;CACpE;AAED,MAAM,WAAW,wBAAwB;IACvC,aAAa,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACzC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,UAAU,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACpC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC5C;AAyZD,wBAAgB,2BAA2B,CACzC,aAAa,EAAE,kBAAkB,GAAG,IAAI,GACvC,MAAM,GAAG,IAAI,CAmBf;AAwoBD,wBAAgB,kCAAkC,CAChD,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE;IACP,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IAC/C,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;CACzC,GACL,MAAM,GAAG,IAAI,CAuBf;AA6+BD,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAMnE;AAg6DD,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,gBAAgB,EACzB,OAAO,GAAE,yBAA8B,GACtC,OAAO,CAAC,wBAAwB,CAAC,CAoVnC;AA6BD,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,OAAO,CAGT;AAyMD,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC,CAyC3D"}
|
|
@@ -17,7 +17,7 @@ import { detectKeywords, detectPrimaryKeyword, recordSkillActivation, } from "..
|
|
|
17
17
|
import { buildDeepInterviewConfigInstruction } from "../hooks/deep-interview-config-instruction.js";
|
|
18
18
|
import { readTeamModeConfig } from "../config/team-mode.js";
|
|
19
19
|
import { detectNativeStopStallPattern, loadAutoNudgeConfig, normalizeAutoNudgeSignatureText, resolveEffectiveAutoNudgeResponse, } from "./notify-hook/auto-nudge.js";
|
|
20
|
-
import { SLOPPY_FALLBACK_GROUNDING_PATTERNS, SLOPPY_FALLBACK_IMPLEMENTATION_CONTEXT_PATTERNS, SLOPPY_FALLBACK_PHRASE_PATTERNS, buildNativePostToolUseOutput, buildNativePreToolUseOutput, detectMcpTransportFailure, hasAnyPattern, } from "./codex-native-pre-post.js";
|
|
20
|
+
import { SLOPPY_FALLBACK_GROUNDING_PATTERNS, SLOPPY_FALLBACK_IMPLEMENTATION_CONTEXT_PATTERNS, SLOPPY_FALLBACK_PHRASE_PATTERNS, buildNativePostToolUseOutput, buildNativePreToolUseOutput, commandInvokesApplyPatch, detectMcpTransportFailure, hasAnyPattern, } from "./codex-native-pre-post.js";
|
|
21
21
|
import { handleTeamWorkerPostToolUseSuccess } from "./notify-hook/team-worker-posttooluse.js";
|
|
22
22
|
import { maybeNudgeLeaderForAllowedWorkerStop } from "./notify-hook/team-worker-stop.js";
|
|
23
23
|
import { resolveCodexExecutionSurface, } from "./codex-execution-surface.js";
|
|
@@ -2223,10 +2223,69 @@ function readPreToolUsePathCandidates(payload) {
|
|
|
2223
2223
|
];
|
|
2224
2224
|
return candidates.map((candidate) => safeString(candidate).trim()).filter(Boolean);
|
|
2225
2225
|
}
|
|
2226
|
+
const APPLY_PATCH_TOOL_NAMES = new Set(["apply_patch", "ApplyPatch"]);
|
|
2227
|
+
function isApplyPatchToolName(toolName) {
|
|
2228
|
+
return APPLY_PATCH_TOOL_NAMES.has(toolName);
|
|
2229
|
+
}
|
|
2230
|
+
function readApplyPatchText(payload) {
|
|
2231
|
+
const input = safeObject(payload.tool_input);
|
|
2232
|
+
for (const key of ["input", "patch", "content", "text", "command"]) {
|
|
2233
|
+
const value = safeString(input[key]).trim();
|
|
2234
|
+
if (value)
|
|
2235
|
+
return value;
|
|
2236
|
+
}
|
|
2237
|
+
return "";
|
|
2238
|
+
}
|
|
2239
|
+
function extractApplyPatchTargetPaths(patchText) {
|
|
2240
|
+
if (!patchText)
|
|
2241
|
+
return [];
|
|
2242
|
+
const paths = [];
|
|
2243
|
+
for (const match of patchText.matchAll(/^\s*\*\*\*\s+(?:Add|Update|Delete)\s+File:\s*(.+?)\s*$/gm)) {
|
|
2244
|
+
const candidate = safeString(match[1]).trim();
|
|
2245
|
+
if (candidate)
|
|
2246
|
+
paths.push(candidate);
|
|
2247
|
+
}
|
|
2248
|
+
for (const match of patchText.matchAll(/^\s*\*\*\*\s+Move\s+to:\s*(.+?)\s*$/gm)) {
|
|
2249
|
+
const candidate = safeString(match[1]).trim();
|
|
2250
|
+
if (candidate)
|
|
2251
|
+
paths.push(candidate);
|
|
2252
|
+
}
|
|
2253
|
+
return paths;
|
|
2254
|
+
}
|
|
2255
|
+
function collectImplementationToolPathCandidates(payload, toolName, structuredCandidates) {
|
|
2256
|
+
if (!isApplyPatchToolName(toolName))
|
|
2257
|
+
return structuredCandidates;
|
|
2258
|
+
return [...structuredCandidates, ...extractApplyPatchTargetPaths(readApplyPatchText(payload))];
|
|
2259
|
+
}
|
|
2226
2260
|
function isNullDeviceRedirectTarget(target) {
|
|
2227
2261
|
const normalized = target.trim().replace(/^['"]|['"]$/g, "").toLowerCase();
|
|
2228
2262
|
return normalized === "/dev/null" || normalized === "nul";
|
|
2229
2263
|
}
|
|
2264
|
+
// Collects same-command literal variable assignments (`NAME="value"`), skipping
|
|
2265
|
+
// any value that involves expansion (`$`, backticks) so unresolved/dynamic
|
|
2266
|
+
// targets stay conservatively blocked.
|
|
2267
|
+
function extractCommandLiteralAssignments(command) {
|
|
2268
|
+
const assignments = new Map();
|
|
2269
|
+
const pattern = /(?:^|[\n;&|(]|&&|\|\|)\s*([A-Za-z_][A-Za-z0-9_]*)=(?:"([^"$`]*)"|'([^']*)'|([^\s"'$`;&|<>]+))/g;
|
|
2270
|
+
for (const match of command.matchAll(pattern)) {
|
|
2271
|
+
const name = safeString(match[1]).trim();
|
|
2272
|
+
if (!name)
|
|
2273
|
+
continue;
|
|
2274
|
+
const value = match[2] ?? match[3] ?? match[4] ?? "";
|
|
2275
|
+
assignments.set(name, value);
|
|
2276
|
+
}
|
|
2277
|
+
return assignments;
|
|
2278
|
+
}
|
|
2279
|
+
// Resolves a redirect/tee target of the form `$NAME`/`${NAME}` against
|
|
2280
|
+
// same-command literal assignments; non-variable or unresolved targets are
|
|
2281
|
+
// returned unchanged so they remain subject to the allowed-path check.
|
|
2282
|
+
function resolveCommandRedirectTarget(target, assignments) {
|
|
2283
|
+
const variableMatch = target.match(/^\$\{?([A-Za-z_][A-Za-z0-9_]*)\}?$/);
|
|
2284
|
+
if (!variableMatch)
|
|
2285
|
+
return target;
|
|
2286
|
+
const resolved = assignments.get(safeString(variableMatch[1]));
|
|
2287
|
+
return resolved !== undefined ? resolved : target;
|
|
2288
|
+
}
|
|
2230
2289
|
function extractDeepInterviewCommandRedirectTargets(command) {
|
|
2231
2290
|
const targets = [];
|
|
2232
2291
|
for (const match of command.matchAll(/(?:^|[^>])>{1,2}\s*(["']?)([^\s&|;<>]+)\1/g)) {
|
|
@@ -2237,7 +2296,7 @@ function extractDeepInterviewCommandRedirectTargets(command) {
|
|
|
2237
2296
|
return targets;
|
|
2238
2297
|
}
|
|
2239
2298
|
function commandHasDeepInterviewWriteIntent(command) {
|
|
2240
|
-
return
|
|
2299
|
+
return commandInvokesApplyPatch(command)
|
|
2241
2300
|
|| extractDeepInterviewCommandRedirectTargets(command).length > 0
|
|
2242
2301
|
|| /\btee\s+(?:-a\s+)?[^\s&|;]+/.test(command)
|
|
2243
2302
|
|| /\bsed\s+(?:[^\n;&|]*\s)?-i(?:\b|['"])/.test(command)
|
|
@@ -2245,11 +2304,13 @@ function commandHasDeepInterviewWriteIntent(command) {
|
|
|
2245
2304
|
|| /\b(?:git\s+(?:checkout|switch|restore|reset|apply|am|merge|rebase)|npm\s+(?:install|i|ci)|pnpm\s+(?:install|i)|yarn\s+(?:install|add))\b/.test(command);
|
|
2246
2305
|
}
|
|
2247
2306
|
function extractDeepInterviewCommandWriteTargets(command) {
|
|
2248
|
-
const
|
|
2307
|
+
const assignments = extractCommandLiteralAssignments(command);
|
|
2308
|
+
const targets = extractDeepInterviewCommandRedirectTargets(command)
|
|
2309
|
+
.map((target) => resolveCommandRedirectTarget(target, assignments));
|
|
2249
2310
|
for (const match of command.matchAll(/\btee\s+(?:-a\s+)?(["']?)([^\s&|;<>]+)\1/g)) {
|
|
2250
2311
|
const candidate = safeString(match[2]).trim();
|
|
2251
2312
|
if (candidate)
|
|
2252
|
-
targets.push(candidate);
|
|
2313
|
+
targets.push(resolveCommandRedirectTarget(candidate, assignments));
|
|
2253
2314
|
}
|
|
2254
2315
|
return targets;
|
|
2255
2316
|
}
|
|
@@ -2262,21 +2323,45 @@ function isAllowedDeepInterviewBashWrite(cwd, command) {
|
|
|
2262
2323
|
return targets.length > 0 && targets.every((target) => isAllowedDeepInterviewArtifactPath(cwd, target));
|
|
2263
2324
|
}
|
|
2264
2325
|
async function readActiveDeepInterviewStateForPreToolUse(cwd, stateDir, sessionId, threadId) {
|
|
2326
|
+
const canonicalState = sessionId
|
|
2327
|
+
? await readVisibleSkillActiveStateForStateDir(stateDir, sessionId)
|
|
2328
|
+
: await readSkillActiveState(join(stateDir, SKILL_ACTIVE_STATE_FILE));
|
|
2329
|
+
if (!canonicalState)
|
|
2330
|
+
return null;
|
|
2265
2331
|
const modeState = sessionId
|
|
2266
2332
|
? await readStopSessionPinnedState("deep-interview-state.json", cwd, sessionId, stateDir)
|
|
2267
2333
|
: await readJsonIfExists(join(stateDir, "deep-interview-state.json"));
|
|
2268
|
-
if (
|
|
2334
|
+
if (isActiveDeepInterviewPhase(modeState) && modeState && modeStateMatchesSkillStopContext(modeState, cwd, sessionId)) {
|
|
2335
|
+
const hasActiveDeepInterviewSkill = listActiveSkills(canonicalState).some((entry) => (entry.skill === "deep-interview"
|
|
2336
|
+
&& matchesSkillStopContext(entry, canonicalState, sessionId, threadId)));
|
|
2337
|
+
if (hasActiveDeepInterviewSkill)
|
|
2338
|
+
return modeState;
|
|
2339
|
+
}
|
|
2340
|
+
const autopilotState = sessionId
|
|
2341
|
+
? await readStopSessionPinnedState("autopilot-state.json", cwd, sessionId, stateDir)
|
|
2342
|
+
: await readJsonIfExists(join(stateDir, "autopilot-state.json"));
|
|
2343
|
+
if (!autopilotState || autopilotState.active !== true)
|
|
2269
2344
|
return null;
|
|
2270
|
-
|
|
2345
|
+
const autopilotMode = safeString(autopilotState.mode).trim();
|
|
2346
|
+
if (autopilotMode && autopilotMode !== "autopilot")
|
|
2271
2347
|
return null;
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
if (
|
|
2348
|
+
if (!modeStateMatchesSkillStopContext(autopilotState, cwd, sessionId))
|
|
2349
|
+
return null;
|
|
2350
|
+
const terminalAutopilotRunState = await readCanonicalTerminalRunStateForStop(cwd, sessionId, "autopilot");
|
|
2351
|
+
if (terminalAutopilotRunState)
|
|
2276
2352
|
return null;
|
|
2277
|
-
const
|
|
2353
|
+
const autopilotStatePhase = safeString(autopilotState.current_phase ?? autopilotState.currentPhase).trim().toLowerCase();
|
|
2354
|
+
const autopilotIsDeepInterview = normalizeAutopilotPhase(autopilotStatePhase) === "deep-interview";
|
|
2355
|
+
const hasDeepInterviewScopedAutopilotSkill = listActiveSkills(canonicalState).some((entry) => (entry.skill === "autopilot"
|
|
2356
|
+
&& normalizeAutopilotPhase(safeString(entry.phase).trim().toLowerCase()) === "deep-interview"
|
|
2357
|
+
&& matchesSkillStopContext(entry, canonicalState, sessionId, threadId)));
|
|
2358
|
+
const hasActiveAutopilotSkill = listActiveSkills(canonicalState).some((entry) => (entry.skill === "autopilot"
|
|
2278
2359
|
&& matchesSkillStopContext(entry, canonicalState, sessionId, threadId)));
|
|
2279
|
-
|
|
2360
|
+
if (!hasActiveAutopilotSkill)
|
|
2361
|
+
return null;
|
|
2362
|
+
if (!autopilotIsDeepInterview && !hasDeepInterviewScopedAutopilotSkill)
|
|
2363
|
+
return null;
|
|
2364
|
+
return autopilotState;
|
|
2280
2365
|
}
|
|
2281
2366
|
async function readActiveRalplanStateForPreToolUse(cwd, stateDir, sessionId, threadId) {
|
|
2282
2367
|
const modeState = sessionId
|
|
@@ -2342,12 +2427,29 @@ async function buildRalplanPreToolUseBoundaryOutput(payload, cwd, stateDir, reso
|
|
|
2342
2427
|
const command = readPreToolUseCommand(payload);
|
|
2343
2428
|
const pathCandidates = readPreToolUsePathCandidates(payload);
|
|
2344
2429
|
let blocked = false;
|
|
2430
|
+
let blockedDetail = "implementation/write tools are blocked until an explicit execution handoff workflow is activated";
|
|
2345
2431
|
if (toolName === "Bash") {
|
|
2346
2432
|
blocked = !isAllowedRalplanBashWrite(cwd, command);
|
|
2433
|
+
if (blocked) {
|
|
2434
|
+
const targets = extractDeepInterviewCommandWriteTargets(command);
|
|
2435
|
+
const blockedTarget = targets.find((target) => !isAllowedRalplanArtifactPath(cwd, target));
|
|
2436
|
+
blockedDetail = blockedTarget
|
|
2437
|
+
? `write target ${blockedTarget} is not under allowed planning artifact paths (${RALPLAN_ALLOWED_WRITE_PREFIXES.join(", ")})`
|
|
2438
|
+
: "Bash write intent did not identify an allowed planning artifact path";
|
|
2439
|
+
}
|
|
2347
2440
|
}
|
|
2348
2441
|
else if (PLANNING_MODE_IMPLEMENTATION_TOOL_NAMES.has(toolName)) {
|
|
2349
|
-
|
|
2350
|
-
|
|
2442
|
+
if (pathCandidates.length === 0) {
|
|
2443
|
+
blocked = true;
|
|
2444
|
+
blockedDetail = `${toolName} did not include a file path; only planning artifact paths are allowed`;
|
|
2445
|
+
}
|
|
2446
|
+
else {
|
|
2447
|
+
const blockedPath = pathCandidates.find((candidate) => !isAllowedRalplanArtifactPath(cwd, candidate));
|
|
2448
|
+
blocked = blockedPath !== undefined;
|
|
2449
|
+
if (blockedPath !== undefined) {
|
|
2450
|
+
blockedDetail = `path ${blockedPath} is not under allowed planning artifact paths (${RALPLAN_ALLOWED_WRITE_PREFIXES.join(", ")})`;
|
|
2451
|
+
}
|
|
2452
|
+
}
|
|
2351
2453
|
}
|
|
2352
2454
|
if (!blocked)
|
|
2353
2455
|
return null;
|
|
@@ -2359,7 +2461,7 @@ async function buildRalplanPreToolUseBoundaryOutput(payload, cwd, stateDir, reso
|
|
|
2359
2461
|
: "Ralplan is consensus-planning mode";
|
|
2360
2462
|
return {
|
|
2361
2463
|
decision: "block",
|
|
2362
|
-
reason: `${planningModeLabel} is active (phase: ${phase}); implementation/write tools are blocked until an explicit execution handoff workflow is activated.`,
|
|
2464
|
+
reason: `${planningModeLabel} is active (phase: ${phase}); implementation/write tools are blocked until an explicit execution handoff workflow is activated; ${blockedDetail}.`,
|
|
2363
2465
|
hookSpecificOutput: {
|
|
2364
2466
|
hookEventName: "PreToolUse",
|
|
2365
2467
|
additionalContext: `${planningModeDescription}. `
|
|
@@ -2383,8 +2485,9 @@ async function buildDeepInterviewPreToolUseBoundaryOutput(payload, cwd, stateDir
|
|
|
2383
2485
|
blocked = !isAllowedDeepInterviewBashWrite(cwd, command);
|
|
2384
2486
|
}
|
|
2385
2487
|
else if (DEEP_INTERVIEW_IMPLEMENTATION_TOOL_NAMES.has(toolName)) {
|
|
2386
|
-
|
|
2387
|
-
|
|
2488
|
+
const candidates = collectImplementationToolPathCandidates(payload, toolName, pathCandidates);
|
|
2489
|
+
blocked = candidates.length === 0
|
|
2490
|
+
|| !candidates.every((candidate) => isAllowedDeepInterviewArtifactPath(cwd, candidate));
|
|
2388
2491
|
}
|
|
2389
2492
|
if (!blocked)
|
|
2390
2493
|
return null;
|
|
@@ -3217,18 +3320,35 @@ export async function dispatchCodexNativeHook(payload, options = {}) {
|
|
|
3217
3320
|
if (hookEventName === "SessionStart" && nativeSessionId) {
|
|
3218
3321
|
const transcriptPath = safeString(payload.transcript_path ?? payload.transcriptPath).trim();
|
|
3219
3322
|
const subagentSessionStart = readNativeSubagentSessionStartMetadata(transcriptPath);
|
|
3220
|
-
if (subagentSessionStart
|
|
3323
|
+
if (subagentSessionStart) {
|
|
3324
|
+
// A native child/subagent SessionStart carries a parent_thread_id in its
|
|
3325
|
+
// transcript session_meta. Treat it as a child-agent lifecycle event for
|
|
3326
|
+
// notification suppression and subagent tracking even when the canonical
|
|
3327
|
+
// leader session has not been reconciled yet (#2831). A child start must
|
|
3328
|
+
// never promote itself into a root/leader session or emit an independent
|
|
3329
|
+
// session-start notification at session/minimal verbosity.
|
|
3221
3330
|
isSubagentSessionStart = true;
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3331
|
+
if (canonicalSessionId) {
|
|
3332
|
+
const belongsToCanonicalSession = await nativeSubagentSessionStartBelongsToCanonicalSession(cwd, canonicalSessionId, currentSessionState, subagentSessionStart);
|
|
3333
|
+
if (belongsToCanonicalSession) {
|
|
3334
|
+
resolvedNativeSessionId = nativeSessionId;
|
|
3335
|
+
await recordNativeSubagentSessionStart(cwd, canonicalSessionId, nativeSessionId, subagentSessionStart, transcriptPath);
|
|
3336
|
+
}
|
|
3337
|
+
else {
|
|
3338
|
+
skipCanonicalSessionStartContext = true;
|
|
3339
|
+
resolvedNativeSessionId =
|
|
3340
|
+
safeString(currentSessionState?.native_session_id).trim() || nativeSessionId;
|
|
3341
|
+
await recordIgnoredNativeSubagentSessionStart(cwd, canonicalSessionId, nativeSessionId, subagentSessionStart, transcriptPath);
|
|
3342
|
+
}
|
|
3226
3343
|
}
|
|
3227
3344
|
else {
|
|
3345
|
+
// No canonical leader session is resolved in this worktree yet. Still
|
|
3346
|
+
// register the child thread under its parent so its later Stop is
|
|
3347
|
+
// recognized as subagent-scoped, skip leader SessionStart context, and
|
|
3348
|
+
// do not reconcile the child as a new root session.
|
|
3228
3349
|
skipCanonicalSessionStartContext = true;
|
|
3229
|
-
resolvedNativeSessionId =
|
|
3230
|
-
|
|
3231
|
-
await recordIgnoredNativeSubagentSessionStart(cwd, canonicalSessionId, nativeSessionId, subagentSessionStart, transcriptPath);
|
|
3350
|
+
resolvedNativeSessionId = nativeSessionId;
|
|
3351
|
+
await recordNativeSubagentSessionStart(cwd, canonicalSessionId, nativeSessionId, subagentSessionStart, transcriptPath);
|
|
3232
3352
|
}
|
|
3233
3353
|
}
|
|
3234
3354
|
else {
|