@walwal-harness/cli 7.1.24 → 7.1.25

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/CHANGELOG.md CHANGED
@@ -31,6 +31,16 @@ docmeta:
31
31
 
32
32
  ## Unreleased
33
33
 
34
+ ## 7.1.25 — Absolute Claude hook paths + Codex adapter docs (2026-05-26)
35
+
36
+ ### Fixed
37
+ - Claude hooks and statusline now install with project-root absolute script paths, preventing `UserPromptSubmit hook error: scripts/harness-user-prompt-submit.sh: No such file or directory` when Claude runs hooks outside the project root.
38
+ - Existing relative-path harness hooks are migrated to absolute paths on re-init.
39
+
40
+ ### Changed
41
+ - Codex command and AGENTS templates now explain that `.codex/skills/**/SKILL.md` is the Codex runtime protocol and `.codex/agents/` is not required.
42
+ - `migrate` appends a Codex Runtime Adapter block to existing AGENTS.md files when missing.
43
+
34
44
  ## 7.1.24 — Hourly CEO wake loop + migrate script refresh (2026-05-22)
35
45
 
36
46
  ### Changed
package/README.md CHANGED
@@ -215,6 +215,7 @@ Hourly autonomous wake:
215
215
  - `HARNESS_WAKE_MODEL=<model>` optionally pins the Claude model for wake ticks.
216
216
  - Each wake tick prompts CEO to convene CXX + OPS, collect progress and decisions, dispatch the next action without asking Owner, and require CQO/OPS verification until the active goal works.
217
217
  - `npx @walwal-harness/cli migrate` refreshes package-owned runtime scripts, so existing projects receive wake prompt updates without a full re-init.
218
+ - In Codex, `.codex/skills/**/SKILL.md` files are the runtime protocol. `.codex/agents/` is not required; Codex should manually read the relevant skill if it is not auto-listed.
218
219
 
219
220
  ---
220
221
 
@@ -19,6 +19,18 @@ Internal routing uses agent/skill wiring only.
19
19
 
20
20
  ---
21
21
 
22
+ ## 1.1 Codex Runtime Adapter
23
+
24
+ Codex does not need `.codex/agents/` to run this harness. The installed Codex contract is:
25
+
26
+ - Owner entrypoints are `.codex/commands/goal.md`, `.codex/commands/submission.md`, and `.codex/commands/hot-fix.md`.
27
+ - Harness role protocols live in `.codex/skills/harness-{ceo,coo,cdo,cto,cqo,ops,hiring,resource-manager,brick-office}/SKILL.md`.
28
+ - If Codex does not auto-list these as available skills, manually read the relevant `SKILL.md` file and follow it. Do not report that the harness is unavailable just because `.codex/agents/` is absent.
29
+ - When a command asks for a "fresh session context", Codex must create a role-scoped context by reading only the role skill, the active mission files, and required conventions/gotchas before writing that role's `{cxx}.md`. If Codex sub-agent tooling is explicitly available and requested, it may be used; otherwise execute the role protocol sequentially with clear role boundaries.
30
+ - Codex must not treat `.codex/skills` as passive documentation. These files are the installed runtime protocol for Codex.
31
+
32
+ ---
33
+
22
34
  ## 2. Think Before Acting
23
35
 
24
36
  Don't assume. Don't hide confusion.
package/bin/init.js CHANGED
@@ -168,6 +168,33 @@ function mergeClaudePermissionAllow(settings, entries) {
168
168
  return changed;
169
169
  }
170
170
 
171
+ function shellQuote(value) {
172
+ return `'${String(value).replace(/'/g, `'\\''`)}'`;
173
+ }
174
+
175
+ function harnessScriptCommand(scriptName) {
176
+ return `bash ${shellQuote(path.join(PROJECT_ROOT, 'scripts', scriptName))}`;
177
+ }
178
+
179
+ function replaceHarnessHookCommand(entries, marker, command) {
180
+ let changed = false;
181
+ for (const entry of entries) {
182
+ if (!entry || typeof entry !== 'object') continue;
183
+ if (Array.isArray(entry.hooks)) {
184
+ for (const hook of entry.hooks) {
185
+ if (hook && hook.command && hook.command.includes(marker) && hook.command !== command) {
186
+ hook.command = command;
187
+ changed = true;
188
+ }
189
+ }
190
+ } else if (entry.type === 'command' && entry.command && entry.command.includes(marker) && entry.command !== command) {
191
+ entry.command = command;
192
+ changed = true;
193
+ }
194
+ }
195
+ return changed;
196
+ }
197
+
171
198
  const V7_REMOVED_CONVENTION_FILES = [
172
199
  'conductor.md',
173
200
  'coo-developer.md',
@@ -820,7 +847,7 @@ function installSessionHook() {
820
847
 
821
848
  // Migrate any legacy flat entries (created by older walwal-harness versions)
822
849
  // into the correct matcher + hooks-array shape that Claude Code expects.
823
- const hookCmd = 'bash scripts/harness-session-start.sh';
850
+ const hookCmd = harnessScriptCommand('harness-session-start.sh');
824
851
  let migrated = false;
825
852
  settings.hooks.SessionStart = settings.hooks.SessionStart
826
853
  .map((entry) => {
@@ -845,6 +872,8 @@ function installSessionHook() {
845
872
  )
846
873
  );
847
874
 
875
+ const hookUpdated = replaceHarnessHookCommand(settings.hooks.SessionStart, 'harness-session-start', hookCmd);
876
+
848
877
  if (!alreadyInstalled) {
849
878
  settings.hooks.SessionStart.push({
850
879
  matcher: '',
@@ -852,9 +881,9 @@ function installSessionHook() {
852
881
  });
853
882
  writeClaudeSettings(settings);
854
883
  log('SessionStart hook installed in .claude/settings.json');
855
- } else if (migrated) {
884
+ } else if (migrated || hookUpdated) {
856
885
  writeClaudeSettings(settings);
857
- log('SessionStart hook migrated to matcher + hooks-array format');
886
+ log('SessionStart hook migrated in .claude/settings.json');
858
887
  } else {
859
888
  log('SessionStart hook already installed');
860
889
  }
@@ -872,16 +901,9 @@ function installStatusline() {
872
901
 
873
902
  let settings = readClaudeSettings();
874
903
 
875
- // Check if statusLine is already configured
876
- if (settings.statusLine && settings.statusLine.command &&
877
- settings.statusLine.command.includes('harness-statusline')) {
878
- log('Statusline already installed');
879
- return;
880
- }
881
-
882
904
  settings.statusLine = {
883
905
  type: 'command',
884
- command: 'bash scripts/harness-statusline.sh',
906
+ command: harnessScriptCommand('harness-statusline.sh'),
885
907
  refreshInterval: 3
886
908
  };
887
909
 
@@ -904,7 +926,7 @@ function installUserPromptSubmitHook() {
904
926
  if (!settings.hooks) settings.hooks = {};
905
927
  if (!settings.hooks.UserPromptSubmit) settings.hooks.UserPromptSubmit = [];
906
928
 
907
- const hookCmd = 'bash scripts/harness-user-prompt-submit.sh';
929
+ const hookCmd = harnessScriptCommand('harness-user-prompt-submit.sh');
908
930
 
909
931
  // Detect existing harness UserPromptSubmit hook (any shape)
910
932
  const alreadyInstalled = settings.hooks.UserPromptSubmit.some((entry) => {
@@ -920,6 +942,8 @@ function installUserPromptSubmitHook() {
920
942
  return false;
921
943
  });
922
944
 
945
+ const hookUpdated = replaceHarnessHookCommand(settings.hooks.UserPromptSubmit, 'harness-user-prompt-submit', hookCmd);
946
+
923
947
  if (!alreadyInstalled) {
924
948
  settings.hooks.UserPromptSubmit.push({
925
949
  matcher: '',
@@ -930,6 +954,9 @@ function installUserPromptSubmitHook() {
930
954
  log(' → /goal, /submission, and /hot-fix are guided through harness-ceo and CXX workflow');
931
955
  log(' → Opt-out per message: say "harness skip" or "without harness"');
932
956
  log(' → Disable globally: set .harness/config.json behavior.auto_route_ceo = false');
957
+ } else if (hookUpdated) {
958
+ writeClaudeSettings(settings);
959
+ log('UserPromptSubmit hook migrated in .claude/settings.json');
933
960
  } else {
934
961
  log('UserPromptSubmit hook already installed');
935
962
  }
@@ -950,7 +977,7 @@ function installStopHook() {
950
977
  if (!settings.hooks) settings.hooks = {};
951
978
  if (!settings.hooks.Stop) settings.hooks.Stop = [];
952
979
 
953
- const hookCmd = 'bash scripts/harness-stop.sh';
980
+ const hookCmd = harnessScriptCommand('harness-stop.sh');
954
981
 
955
982
  const alreadyInstalled = settings.hooks.Stop.some((entry) => {
956
983
  if (!entry || typeof entry !== 'object') return false;
@@ -965,6 +992,8 @@ function installStopHook() {
965
992
  return false;
966
993
  });
967
994
 
995
+ const hookUpdated = replaceHarnessHookCommand(settings.hooks.Stop, 'harness-stop', hookCmd);
996
+
968
997
  if (!alreadyInstalled) {
969
998
  settings.hooks.Stop.push({
970
999
  matcher: '',
@@ -975,6 +1004,9 @@ function installStopHook() {
975
1004
  log(' → Conductor 가 running 인 동안 turn 종료 시 자동으로 다음 tick 으로 연쇄');
976
1005
  log(' → 비활성: .harness/config.json behavior.auto_chain_on_stop = false');
977
1006
  log(' → 상한: behavior.auto_chain_max_per_sprint (기본 200)');
1007
+ } else if (hookUpdated) {
1008
+ writeClaudeSettings(settings);
1009
+ log('Stop hook migrated in .claude/settings.json');
978
1010
  } else {
979
1011
  log('Stop hook already installed');
980
1012
  }
@@ -1227,6 +1259,7 @@ function detectMigrationNeeded() {
1227
1259
  hrResourcePoolStale: false,
1228
1260
  harnessMdStale: false,
1229
1261
  agentsMissingOpsVerificationRules: false,
1262
+ agentsMissingCodexAdapterRules: false,
1230
1263
  rosterCodexPathsMissing: false,
1231
1264
  resourceIndexCodexWordingMissing: false,
1232
1265
  memoryMissingSystemEntries: [],
@@ -1347,6 +1380,12 @@ function detectMigrationNeeded() {
1347
1380
  ) {
1348
1381
  flags.agentsMissingOpsVerificationRules = true;
1349
1382
  }
1383
+ if (
1384
+ !agentsBody.includes('Codex Runtime Adapter') &&
1385
+ !agentsBody.includes('.codex/skills/harness-ceo/SKILL.md')
1386
+ ) {
1387
+ flags.agentsMissingCodexAdapterRules = true;
1388
+ }
1350
1389
  } catch {}
1351
1390
  }
1352
1391
  if (fs.existsSync(rosterPath)) {
@@ -1852,6 +1891,32 @@ function runMigrate(opts = {}) {
1852
1891
  }
1853
1892
  }
1854
1893
 
1894
+
1895
+ if (flags.agentsMissingCodexAdapterRules) {
1896
+ const agentsPath = path.join(PROJECT_ROOT, 'AGENTS.md');
1897
+ if (fs.existsSync(agentsPath)) {
1898
+ const original = fs.readFileSync(agentsPath, 'utf8');
1899
+ const block = [
1900
+ '',
1901
+ '---',
1902
+ '',
1903
+ '## walwal-harness Codex Runtime Adapter',
1904
+ '',
1905
+ '- Codex does not require .codex/agents/; repo-local .codex/skills/**/SKILL.md files are the Codex runtime protocol.',
1906
+ '- For /goal, /submission, and /hot-fix, read .codex/commands/{goal,submission,hot-fix}.md and .codex/skills/harness-ceo/SKILL.md if Codex does not auto-load them.',
1907
+ '- Do not report walwal-harness as unavailable just because skills are not listed in the global Available Skills panel.',
1908
+ '- Emulate fresh CXX context by reading the role skill, active mission files, and required conventions/gotchas before writing that role\'s {cxx}.md.',
1909
+ ''
1910
+ ].join('\n');
1911
+ log(' AGENTS.md: Codex runtime adapter rules append');
1912
+ if (!dryRun) {
1913
+ fs.writeFileSync(path.join(backupDir, 'AGENTS.codex-adapter.md'), original);
1914
+ const sep = original.endsWith('\n') ? '' : '\n';
1915
+ fs.writeFileSync(agentsPath, original + sep + block);
1916
+ }
1917
+ }
1918
+ }
1919
+
1855
1920
  // 7. Bundle version stamp — record which package version was last applied.
1856
1921
  if (flags.bundleVersionStale) {
1857
1922
  const { current, installed } = flags.bundleVersionStale;
package/commands/goal.md CHANGED
@@ -7,6 +7,11 @@ argument-hint: "<goal request>"
7
7
 
8
8
  Route the Owner request to the installed `harness-ceo` agent/skill.
9
9
 
10
+ Codex adapter:
11
+ - If Codex does not auto-load `harness-ceo`, manually read `.codex/skills/harness-ceo/SKILL.md` and follow it.
12
+ - Absence of `.codex/agents/` is not a failure. `.codex/skills/**/SKILL.md` is the Codex runtime protocol.
13
+ - For CXX "fresh session context", use role-scoped context: read the CXX skill, active mission files, and required conventions/gotchas before writing that role's `{cxx}.md`.
14
+
10
15
  Required flow:
11
16
  1. Create or update a goal under `.harness/documents/goal-{goal_index}-{goal_name}/`.
12
17
  2. Record CEO decisions in `.harness/documents/goal-{goal_index}-{goal_name}/ceo.md`.
@@ -7,6 +7,11 @@ argument-hint: "<incident or fix request>"
7
7
 
8
8
  Route the Owner request to the installed `harness-ceo` agent/skill as an emergency mission under the active goal.
9
9
 
10
+ Codex adapter:
11
+ - If Codex does not auto-load `harness-ceo`, manually read `.codex/skills/harness-ceo/SKILL.md` and follow it.
12
+ - Absence of `.codex/agents/` is not a failure. `.codex/skills/**/SKILL.md` is the Codex runtime protocol.
13
+ - For CXX "fresh session context", use role-scoped context: read the CXX skill, active mission files, and required conventions/gotchas before writing that role's `{cxx}.md`.
14
+
10
15
  Required flow:
11
16
  1. Locate the active goal document root under `.harness/documents/{goal_name}/`. If no active goal exists, CEO must create/select one before proceeding.
12
17
  2. Create `.harness/documents/{goal_name}/hotfix-{hotfix_index}-{hotfix_name}/ceo.md`.
@@ -7,6 +7,11 @@ argument-hint: "<additional requirement>"
7
7
 
8
8
  Route the Owner request to the installed `harness-ceo` agent/skill as an additional requirement under the active goal.
9
9
 
10
+ Codex adapter:
11
+ - If Codex does not auto-load `harness-ceo`, manually read `.codex/skills/harness-ceo/SKILL.md` and follow it.
12
+ - Absence of `.codex/agents/` is not a failure. `.codex/skills/**/SKILL.md` is the Codex runtime protocol.
13
+ - For CXX "fresh session context", use role-scoped context: read the CXX skill, active mission files, and required conventions/gotchas before writing that role's `{cxx}.md`.
14
+
10
15
  Required flow:
11
16
  1. Locate the active goal document root under `.harness/documents/{goal_name}/`. If no active goal exists, CEO must ask the Owner to create or select one with `/goal` before proceeding.
12
17
  2. Create a submission record under `.harness/documents/{goal_name}/submission-{submission_index}-{submission_name}/`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@walwal-harness/cli",
3
- "version": "7.1.24",
3
+ "version": "7.1.25",
4
4
  "description": "Company-style AI agent harness for Claude and Codex. Installs commands, CXX agents, skills, HR-Resource hiring pool, and project-local .harness runtime state.",
5
5
  "bin": {
6
6
  "walwal-harness": "bin/init.js"