@kylecheng3146/agent-ops 0.8.4 → 0.8.5

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.
@@ -9,7 +9,7 @@ import { resolveContainedPath } from "../../../runtime/src/fs/paths.js";
9
9
  import { redactSecrets } from "../../../runtime/src/security/redact.js";
10
10
  import { claudeStopRecursionMarker } from "../../../runtime/src/adapters/claude/input.js";
11
11
  import { HARNESS_IDS, harnessDescriptor } from "../../../runtime/src/install/harness.js";
12
- import { officePhaseHint } from "./office-entry.js";
12
+ import { officePhaseHint, officeLoopPhaseHint } from "./office-entry.js";
13
13
  import { evaluateWorktreeEnter } from "../../../runtime/src/parallel/enter.js";
14
14
  import { evaluateWorktreeWrite, resolveMainRoot } from "../../../runtime/src/parallel/guard.js";
15
15
  import { ensureSessionWorktree, recordSessionOrigin } from "../../../runtime/src/parallel/service.js";
@@ -461,7 +461,7 @@ export async function runHookProcess(argv, io, cliVersion, dependencies = {}) {
461
461
  await startDebugSession(root, normalized.sessionId, harnessId).catch(() => undefined);
462
462
  if (dependencies.office !== undefined && config.features.office?.enabled === true) {
463
463
  if (normalized !== null) {
464
- const phase = officePhaseHint(normalized);
464
+ const phase = officePhaseHint(normalized) ?? (harnessId === "codex" ? officeLoopPhaseHint(parsedInput, root) : undefined);
465
465
  void dependencies.office({
466
466
  root,
467
467
  harness: harnessId,
@@ -472,6 +472,9 @@ export async function runHookProcess(argv, io, cliVersion, dependencies = {}) {
472
472
  ...(normalized.agentId === undefined ? {} : { agentId: normalized.agentId }),
473
473
  ...(phase === undefined ? {} : { phase })
474
474
  }).catch(() => undefined);
475
+ // Native patch hooks added for Office must not emit unsupported-policy messages.
476
+ if (harnessId === "codex" && normalized.event === "unsupported" && phase === "implementing")
477
+ return 0;
475
478
  }
476
479
  }
477
480
  const gitRunner = dependencies.gitRunner ?? defaultGitRunner(root);
@@ -1,5 +1,5 @@
1
1
  import { fileURLToPath } from "node:url";
2
- import { basename, join } from "node:path";
2
+ import { basename, join, resolve } from "node:path";
3
3
  import { homedir } from "node:os";
4
4
  import { rm } from "node:fs/promises";
5
5
  import { createHash } from "node:crypto";
@@ -64,17 +64,46 @@ export function officePhaseHint(event) {
64
64
  : [];
65
65
  let phase;
66
66
  for (const command of commands) {
67
- if (basename(command.command) !== "agent-ops")
67
+ let argv = [command.command, ...command.args];
68
+ // Unwrap display hints here; command-policy normalization stays unchanged.
69
+ while (basename(argv[0] ?? "") === "env") {
70
+ argv = argv.slice(1);
71
+ while (argv.length > 0) {
72
+ if (argv[0] === "-u" || argv[0] === "--unset") {
73
+ if (argv[1] === undefined || !/^[A-Za-z_][A-Za-z0-9_]*$/u.test(argv[1]))
74
+ break;
75
+ argv = argv.slice(2);
76
+ }
77
+ else if (/^--unset=[A-Za-z_][A-Za-z0-9_]*$/u.test(argv[0] ?? ""))
78
+ argv = argv.slice(1);
79
+ else
80
+ break;
81
+ }
82
+ if (argv[0] === "--")
83
+ argv = argv.slice(1);
84
+ while (/^[A-Za-z_][A-Za-z0-9_]*=/u.test(argv[0] ?? ""))
85
+ argv = argv.slice(1);
86
+ }
87
+ if (basename(argv[0] ?? "") === "node" || basename(argv[0] ?? "") === "node.exe") {
88
+ const script = argv[1];
89
+ if (script === undefined || ![
90
+ fileURLToPath(new URL("./bin.js", import.meta.url)),
91
+ resolve(event.projectRoot, "dist/packages/cli/src/bin.js")
92
+ ].includes(resolve(event.projectRoot, script)))
93
+ continue;
94
+ argv = ["agent-ops", ...argv.slice(2)];
95
+ }
96
+ if (basename(argv[0] ?? "") !== "agent-ops")
68
97
  continue;
69
- const action = command.args[0];
98
+ const action = argv[1];
70
99
  // batch and advance report their later steps themselves; this is their first.
71
100
  const next = action === "verify" || action === "batch"
72
101
  ? "verifying"
73
102
  : action === "review"
74
103
  ? "reviewing"
75
- : action === "worktree" && command.args[1] === "finish"
104
+ : action === "worktree" && argv[2] === "finish"
76
105
  ? "integrating"
77
- : action === "task" && (command.args[1] === "complete" || command.args[1] === "advance")
106
+ : action === "task" && (argv[2] === "complete" || argv[2] === "advance")
78
107
  ? "integrating"
79
108
  : action === "task"
80
109
  ? "planning"
@@ -93,10 +122,12 @@ export function officeLoopPhaseHint(input, root) {
93
122
  const tool = input.tool_name;
94
123
  if (tool === "Edit" || tool === "Write" || tool === "NotebookEdit" || tool === "FileWrite")
95
124
  return "implementing";
125
+ const toolInput = recordValue(input, "tool_input");
126
+ const command = recordValue(toolInput, "command") ?? recordValue(toolInput, "cmd");
127
+ if (tool === "apply_patch")
128
+ return typeof command === "string" && command.length > 0 ? "implementing" : undefined;
96
129
  if (tool !== "Bash")
97
130
  return undefined;
98
- const toolInput = recordValue(input, "tool_input");
99
- const command = recordValue(toolInput, "command");
100
131
  return typeof command === "string" ? officePhaseHint(normalizeShellHookEvent(command, root)) : undefined;
101
132
  }
102
133
  /** Records hook presence and starts Office at the production process boundary. */
@@ -96,6 +96,9 @@ export function buildCodexHookConfig(capabilities, runtimePath) {
96
96
  if (capabilities.includes("task-debug")) {
97
97
  hooks.Interrupt = [{ hooks: [{ ...commandHook("Interrupt", runtimePath), timeout: 3 }] }];
98
98
  }
99
+ if (capabilities.includes("office-presence") && hooks.PreToolUse !== undefined) {
100
+ hooks.PreToolUse = hooks.PreToolUse.map(group => ({ ...group, matcher: "^(Bash|apply_patch)$" }));
101
+ }
99
102
  return {
100
103
  description: "agent-ops lifecycle hooks.",
101
104
  hooks
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kylecheng3146/agent-ops",
3
- "version": "0.8.4",
3
+ "version": "0.8.5",
4
4
  "description": "Evidence-driven development loops for agy, Codex, Claude Code, and opencode",
5
5
  "type": "module",
6
6
  "license": "SEE LICENSE IN LICENSE",