oh-my-codex 0.18.12 → 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 +7 -0
- package/dist/autopilot/__tests__/ralplan-gate.test.js +621 -0
- package/dist/autopilot/__tests__/ralplan-gate.test.js.map +1 -1
- package/dist/autopilot/ralplan-gate.d.ts.map +1 -1
- package/dist/autopilot/ralplan-gate.js +32 -18
- package/dist/autopilot/ralplan-gate.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__/index.test.js +54 -1
- package/dist/cli/__tests__/index.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-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-install-mode.test.js +6 -5
- 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__/update.test.js +5 -2
- package/dist/cli/__tests__/update.test.js.map +1 -1
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +9 -1
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/index.d.ts +9 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +209 -7
- 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 +1 -0
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +168 -4
- package/dist/cli/setup.js.map +1 -1
- package/dist/cli/update.d.ts.map +1 -1
- package/dist/cli/update.js +2 -0
- package/dist/cli/update.js.map +1 -1
- package/dist/config/__tests__/codex-hooks.test.js +38 -24
- package/dist/config/__tests__/codex-hooks.test.js.map +1 -1
- package/dist/config/codex-hooks.d.ts +6 -0
- package/dist/config/codex-hooks.d.ts.map +1 -1
- package/dist/config/codex-hooks.js +34 -49
- package/dist/config/codex-hooks.js.map +1 -1
- package/dist/pipeline/__tests__/orchestrator.test.js +125 -0
- 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 +7 -0
- package/dist/pipeline/orchestrator.js.map +1 -1
- package/dist/ralplan/__tests__/consensus-gate.test.js +440 -1
- package/dist/ralplan/__tests__/consensus-gate.test.js.map +1 -1
- package/dist/ralplan/consensus-gate.d.ts +2 -0
- package/dist/ralplan/consensus-gate.d.ts.map +1 -1
- package/dist/ralplan/consensus-gate.js +173 -71
- package/dist/ralplan/consensus-gate.js.map +1 -1
- package/dist/scripts/__tests__/codex-native-hook.test.js +273 -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 +56 -12
- 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/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/src/scripts/__tests__/codex-native-hook.test.ts +363 -0
- package/src/scripts/codex-native-hook.ts +68 -18
- package/src/scripts/codex-native-pre-post.ts +137 -0
|
@@ -325,6 +325,11 @@ function tokenizeShellCommandWithBoundaries(commandText: string): ShellToken[] |
|
|
|
325
325
|
let quote: "'" | "\"" | null = null;
|
|
326
326
|
let escaping = false;
|
|
327
327
|
let nextTokenStartsCommand = false;
|
|
328
|
+
// Command substitution executes even inside double quotes, so we track an
|
|
329
|
+
// active `"$(…)"` (paren depth) or `` "`…`" `` (backtick) substitution to
|
|
330
|
+
// restore double-quote mode once it closes.
|
|
331
|
+
let dquoteSubstParenDepth = 0;
|
|
332
|
+
let backtickFromDquote = false;
|
|
328
333
|
|
|
329
334
|
const pushCurrent = () => {
|
|
330
335
|
if (!current) return;
|
|
@@ -357,6 +362,25 @@ function tokenizeShellCommandWithBoundaries(commandText: string): ShellToken[] |
|
|
|
357
362
|
if (isDoubleQuotedShellEscapeTarget(trimmed[index + 1])) escaping = true;
|
|
358
363
|
else current += char;
|
|
359
364
|
}
|
|
365
|
+
// Command substitution runs inside double quotes, so `"$(cmd …)"` and
|
|
366
|
+
// `` "`cmd …`" `` are real invocations, not literal mentions. Treat the
|
|
367
|
+
// opener as a command-position boundary and parse the substitution body
|
|
368
|
+
// unquoted so the command-head walk resumes, then restore double-quote
|
|
369
|
+
// mode when it closes. Parameter expansion (`${VAR}`), `$HOME`, and an
|
|
370
|
+
// escaped `\$(` stay literal text (no false positive on `grep "(x"`).
|
|
371
|
+
else if (char === "$" && trimmed[index + 1] === "(") {
|
|
372
|
+
pushCurrent();
|
|
373
|
+
nextTokenStartsCommand = true;
|
|
374
|
+
index += 1;
|
|
375
|
+
dquoteSubstParenDepth = 1;
|
|
376
|
+
quote = null;
|
|
377
|
+
}
|
|
378
|
+
else if (char === "`") {
|
|
379
|
+
pushCurrent();
|
|
380
|
+
nextTokenStartsCommand = true;
|
|
381
|
+
backtickFromDquote = true;
|
|
382
|
+
quote = null;
|
|
383
|
+
}
|
|
360
384
|
else current += char;
|
|
361
385
|
continue;
|
|
362
386
|
}
|
|
@@ -368,6 +392,48 @@ function tokenizeShellCommandWithBoundaries(commandText: string): ShellToken[] |
|
|
|
368
392
|
continue;
|
|
369
393
|
}
|
|
370
394
|
|
|
395
|
+
// Grouping / command-substitution openers act as command-position
|
|
396
|
+
// boundaries so the command-head walk resumes after them, mirroring the
|
|
397
|
+
// legacy `[\n;&|(]` boundary set. This catches a real command immediately
|
|
398
|
+
// after `(`, `((`, `$(` (command substitution), or a backtick — e.g.
|
|
399
|
+
// `(apply_patch …)`, `true | (apply_patch …)`, `x=$(apply_patch …)`. We
|
|
400
|
+
// are outside quotes here, so a literal like `grep "(apply_patch"` is left
|
|
401
|
+
// intact and not split.
|
|
402
|
+
// Closing backtick of a command substitution opened inside double quotes
|
|
403
|
+
// ends the substitution and restores the surrounding double-quoted literal.
|
|
404
|
+
if (char === "`" && backtickFromDquote) {
|
|
405
|
+
pushCurrent();
|
|
406
|
+
backtickFromDquote = false;
|
|
407
|
+
quote = "\"";
|
|
408
|
+
continue;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
if (char === "(" || char === ")" || char === "`") {
|
|
412
|
+
pushCurrent();
|
|
413
|
+
nextTokenStartsCommand = true;
|
|
414
|
+
// Track paren depth of a `"$(…)"` substitution opened inside double
|
|
415
|
+
// quotes so the matching `)` restores double-quote mode (nested `$(`
|
|
416
|
+
// and `(` inside it are balanced before we return to the literal).
|
|
417
|
+
if (dquoteSubstParenDepth > 0) {
|
|
418
|
+
if (char === "(") {
|
|
419
|
+
dquoteSubstParenDepth += 1;
|
|
420
|
+
} else if (char === ")") {
|
|
421
|
+
dquoteSubstParenDepth -= 1;
|
|
422
|
+
if (dquoteSubstParenDepth === 0) quote = "\"";
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
continue;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// `{` is a group opener only as its own word (`{ apply_patch …; }`):
|
|
429
|
+
// require an empty pending token (preceded by start/whitespace/boundary)
|
|
430
|
+
// and a following whitespace/newline so brace expansion (`{a,b}`) and
|
|
431
|
+
// parameter expansion (`${VAR}`) are left intact.
|
|
432
|
+
if (char === "{" && current === "" && /\s/.test(trimmed[index + 1] ?? " ")) {
|
|
433
|
+
nextTokenStartsCommand = true;
|
|
434
|
+
continue;
|
|
435
|
+
}
|
|
436
|
+
|
|
371
437
|
if (/\s/.test(char)) {
|
|
372
438
|
pushCurrent();
|
|
373
439
|
continue;
|
|
@@ -488,6 +554,77 @@ function findGitCommandTokenIndex(tokens: ShellToken[]): number {
|
|
|
488
554
|
return -1;
|
|
489
555
|
}
|
|
490
556
|
|
|
557
|
+
const APPLY_PATCH_COMMAND_WRAPPER_TOKENS = new Set(["sudo", "command", "exec"]);
|
|
558
|
+
|
|
559
|
+
// Detects a real `apply_patch` invocation at a shell command position using the
|
|
560
|
+
// same tokenized command-head walk the git commit guard uses
|
|
561
|
+
// (`findGitCommandTokenIndex`): after every statement boundary skip leading
|
|
562
|
+
// inline `NAME=VALUE` assignments, the `env` executable with its full option
|
|
563
|
+
// grammar (`-i`/`--ignore-environment`, `-u`/`--unset`/`--unset=`, `-C`/`-S`,
|
|
564
|
+
// `--`, interleaved assignments), and `sudo`/`command`/`exec` wrappers — in any
|
|
565
|
+
// order — then match when the resolved command token's basename is
|
|
566
|
+
// `apply_patch`. This blocks path-qualified (`/usr/bin/apply_patch`,
|
|
567
|
+
// `./apply_patch`), env-flag (`env -i apply_patch`, `env -u FOO apply_patch`),
|
|
568
|
+
// and reordered (`FOO=bar env apply_patch`, `exec env FOO=bar apply_patch`)
|
|
569
|
+
// forms, while read-only diagnostics that merely mention the literal token
|
|
570
|
+
// (e.g. `grep -n "apply_patch" file`) are not misread as write intent. Heredoc
|
|
571
|
+
// bodies are stripped first so patch payloads cannot break tokenization.
|
|
572
|
+
export function commandInvokesApplyPatch(command: string): boolean {
|
|
573
|
+
const tokens = tokenizeShellCommandWithBoundaries(removeHereDocBodies(command));
|
|
574
|
+
if (!tokens) return false;
|
|
575
|
+
|
|
576
|
+
for (let commandStart = 0; commandStart < tokens.length; commandStart = nextCommandStart(tokens, commandStart)) {
|
|
577
|
+
let index = commandStart;
|
|
578
|
+
const commandEnd = nextCommandStart(tokens, commandStart);
|
|
579
|
+
|
|
580
|
+
let advanced = true;
|
|
581
|
+
while (advanced && index < commandEnd) {
|
|
582
|
+
advanced = false;
|
|
583
|
+
|
|
584
|
+
while (index < commandEnd && isInlineShellEnvAssignment(tokens[index]?.value ?? "")) {
|
|
585
|
+
index += 1;
|
|
586
|
+
advanced = true;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
while (index < commandEnd && isEnvExecutableToken(tokens[index]?.value ?? "")) {
|
|
590
|
+
index += 1;
|
|
591
|
+
advanced = true;
|
|
592
|
+
while (index < commandEnd) {
|
|
593
|
+
const token = tokens[index]?.value ?? "";
|
|
594
|
+
if (token === "--") {
|
|
595
|
+
index += 1;
|
|
596
|
+
break;
|
|
597
|
+
}
|
|
598
|
+
if (isInlineShellEnvAssignment(token)) {
|
|
599
|
+
index += 1;
|
|
600
|
+
continue;
|
|
601
|
+
}
|
|
602
|
+
if (token === "-i" || token === "--ignore-environment" || token.startsWith("--unset=")) {
|
|
603
|
+
index += 1;
|
|
604
|
+
continue;
|
|
605
|
+
}
|
|
606
|
+
if (token.startsWith("-")) {
|
|
607
|
+
index += envOptionConsumesNextValue(token) ? 2 : 1;
|
|
608
|
+
continue;
|
|
609
|
+
}
|
|
610
|
+
break;
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
while (index < commandEnd && APPLY_PATCH_COMMAND_WRAPPER_TOKENS.has((tokens[index]?.value ?? "").toLowerCase())) {
|
|
615
|
+
index += 1;
|
|
616
|
+
advanced = true;
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
if (index < commandEnd && shellCommandBasename(tokens[index]?.value ?? "") === "apply_patch") return true;
|
|
621
|
+
if (commandEnd <= commandStart) break;
|
|
622
|
+
commandStart = commandEnd - 1;
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
return false;
|
|
626
|
+
}
|
|
627
|
+
|
|
491
628
|
function tokenValues(tokens: ShellToken[]): string[] {
|
|
492
629
|
return tokens.map((token) => token.value);
|
|
493
630
|
}
|