oh-my-codex 0.12.6 → 0.13.0
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 +5 -5
- package/Cargo.toml +1 -1
- package/README.md +1 -0
- package/crates/omx-explore/src/main.rs +300 -3
- package/dist/adapt/__tests__/foundation.test.d.ts +2 -0
- package/dist/adapt/__tests__/foundation.test.d.ts.map +1 -0
- package/dist/adapt/__tests__/foundation.test.js +171 -0
- package/dist/adapt/__tests__/foundation.test.js.map +1 -0
- package/dist/adapt/__tests__/hermes.test.d.ts +2 -0
- package/dist/adapt/__tests__/hermes.test.d.ts.map +1 -0
- package/dist/adapt/__tests__/hermes.test.js +137 -0
- package/dist/adapt/__tests__/hermes.test.js.map +1 -0
- package/dist/adapt/contracts.d.ts +157 -0
- package/dist/adapt/contracts.d.ts.map +1 -0
- package/dist/adapt/contracts.js +10 -0
- package/dist/adapt/contracts.js.map +1 -0
- package/dist/adapt/hermes.d.ts +83 -0
- package/dist/adapt/hermes.d.ts.map +1 -0
- package/dist/adapt/hermes.js +371 -0
- package/dist/adapt/hermes.js.map +1 -0
- package/dist/adapt/index.d.ts +14 -0
- package/dist/adapt/index.d.ts.map +1 -0
- package/dist/adapt/index.js +293 -0
- package/dist/adapt/index.js.map +1 -0
- package/dist/adapt/openclaw.d.ts +7 -0
- package/dist/adapt/openclaw.d.ts.map +1 -0
- package/dist/adapt/openclaw.js +299 -0
- package/dist/adapt/openclaw.js.map +1 -0
- package/dist/adapt/paths.d.ts +3 -0
- package/dist/adapt/paths.d.ts.map +1 -0
- package/dist/adapt/paths.js +15 -0
- package/dist/adapt/paths.js.map +1 -0
- package/dist/adapt/registry.d.ts +4 -0
- package/dist/adapt/registry.d.ts.map +1 -0
- package/dist/adapt/registry.js +48 -0
- package/dist/adapt/registry.js.map +1 -0
- package/dist/cli/__tests__/adapt-help.test.d.ts +2 -0
- package/dist/cli/__tests__/adapt-help.test.d.ts.map +1 -0
- package/dist/cli/__tests__/adapt-help.test.js +39 -0
- package/dist/cli/__tests__/adapt-help.test.js.map +1 -0
- package/dist/cli/__tests__/adapt.test.d.ts +2 -0
- package/dist/cli/__tests__/adapt.test.d.ts.map +1 -0
- package/dist/cli/__tests__/adapt.test.js +62 -0
- package/dist/cli/__tests__/adapt.test.js.map +1 -0
- package/dist/cli/__tests__/cleanup.test.js +61 -2
- package/dist/cli/__tests__/cleanup.test.js.map +1 -1
- package/dist/cli/__tests__/doctor-warning-copy.test.js +85 -0
- package/dist/cli/__tests__/doctor-warning-copy.test.js.map +1 -1
- package/dist/cli/__tests__/explore-windows-diagnostics.test.d.ts +2 -0
- package/dist/cli/__tests__/explore-windows-diagnostics.test.d.ts.map +1 -0
- package/dist/cli/__tests__/explore-windows-diagnostics.test.js +17 -0
- package/dist/cli/__tests__/explore-windows-diagnostics.test.js.map +1 -0
- package/dist/cli/__tests__/explore.test.js +69 -0
- package/dist/cli/__tests__/explore.test.js.map +1 -1
- package/dist/cli/__tests__/index.test.js +170 -8
- package/dist/cli/__tests__/index.test.js.map +1 -1
- package/dist/cli/__tests__/nested-help-routing.test.js +1 -0
- package/dist/cli/__tests__/nested-help-routing.test.js.map +1 -1
- package/dist/cli/__tests__/ralph-prd-deep-interview.test.js +5 -0
- package/dist/cli/__tests__/ralph-prd-deep-interview.test.js.map +1 -1
- package/dist/cli/__tests__/ralph-prd-smoke.test.d.ts +2 -0
- package/dist/cli/__tests__/ralph-prd-smoke.test.d.ts.map +1 -0
- package/dist/cli/__tests__/ralph-prd-smoke.test.js +167 -0
- package/dist/cli/__tests__/ralph-prd-smoke.test.js.map +1 -0
- package/dist/cli/__tests__/ralph.test.js +103 -1
- package/dist/cli/__tests__/ralph.test.js.map +1 -1
- package/dist/cli/__tests__/setup-skills-overwrite.test.js +60 -0
- package/dist/cli/__tests__/setup-skills-overwrite.test.js.map +1 -1
- package/dist/cli/adapt.d.ts +6 -0
- package/dist/cli/adapt.d.ts.map +1 -0
- package/dist/cli/adapt.js +135 -0
- package/dist/cli/adapt.js.map +1 -0
- package/dist/cli/cleanup.d.ts +3 -1
- package/dist/cli/cleanup.d.ts.map +1 -1
- package/dist/cli/cleanup.js +57 -6
- package/dist/cli/cleanup.js.map +1 -1
- package/dist/cli/doctor.d.ts +6 -0
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +72 -3
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/explore.d.ts +2 -0
- package/dist/cli/explore.d.ts.map +1 -1
- package/dist/cli/explore.js +14 -0
- package/dist/cli/explore.js.map +1 -1
- package/dist/cli/index.d.ts +4 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +50 -18
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/ralph.d.ts +3 -1
- package/dist/cli/ralph.d.ts.map +1 -1
- package/dist/cli/ralph.js +83 -0
- package/dist/cli/ralph.js.map +1 -1
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +4 -2
- package/dist/cli/setup.js.map +1 -1
- package/dist/cli/tmux-hook.d.ts.map +1 -1
- package/dist/cli/tmux-hook.js +2 -1
- package/dist/cli/tmux-hook.js.map +1 -1
- package/dist/config/__tests__/codex-hooks.test.js +26 -2
- package/dist/config/__tests__/codex-hooks.test.js.map +1 -1
- package/dist/config/codex-hooks.d.ts +2 -1
- package/dist/config/codex-hooks.d.ts.map +1 -1
- package/dist/config/codex-hooks.js +23 -2
- package/dist/config/codex-hooks.js.map +1 -1
- package/dist/hooks/__tests__/keyword-detector.test.js +32 -0
- package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js +2 -1
- package/dist/hooks/__tests__/notify-hook-all-workers-idle.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-modules.test.js +6 -0
- package/dist/hooks/__tests__/notify-hook-modules.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js +124 -0
- package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.js +2 -1
- package/dist/hooks/__tests__/notify-hook-worker-idle.test.js.map +1 -1
- package/dist/hooks/__tests__/prompt-guidance-contract.test.js +10 -1
- package/dist/hooks/__tests__/prompt-guidance-contract.test.js.map +1 -1
- package/dist/hooks/extensibility/sdk/tmux.d.ts.map +1 -1
- package/dist/hooks/extensibility/sdk/tmux.js +2 -1
- package/dist/hooks/extensibility/sdk/tmux.js.map +1 -1
- package/dist/hooks/keyword-detector.d.ts.map +1 -1
- package/dist/hooks/keyword-detector.js +12 -3
- package/dist/hooks/keyword-detector.js.map +1 -1
- package/dist/hooks/prompt-guidance-contract.d.ts.map +1 -1
- package/dist/hooks/prompt-guidance-contract.js +2 -0
- package/dist/hooks/prompt-guidance-contract.js.map +1 -1
- package/dist/hud/__tests__/hud-tmux-injection.test.js +5 -0
- package/dist/hud/__tests__/hud-tmux-injection.test.js.map +1 -1
- package/dist/hud/__tests__/state.test.js +116 -0
- package/dist/hud/__tests__/state.test.js.map +1 -1
- package/dist/hud/index.d.ts +1 -1
- package/dist/hud/index.d.ts.map +1 -1
- package/dist/hud/index.js +5 -3
- package/dist/hud/index.js.map +1 -1
- package/dist/hud/reconcile.js +1 -1
- package/dist/hud/reconcile.js.map +1 -1
- package/dist/hud/state.d.ts.map +1 -1
- package/dist/hud/state.js +6 -5
- package/dist/hud/state.js.map +1 -1
- package/dist/hud/tmux.d.ts +1 -1
- package/dist/hud/tmux.d.ts.map +1 -1
- package/dist/hud/tmux.js +9 -3
- package/dist/hud/tmux.js.map +1 -1
- package/dist/mcp/__tests__/bootstrap.test.js +1 -1
- package/dist/mcp/__tests__/bootstrap.test.js.map +1 -1
- package/dist/mcp/__tests__/state-paths.test.js +23 -1
- package/dist/mcp/__tests__/state-paths.test.js.map +1 -1
- package/dist/mcp/bootstrap.d.ts +1 -1
- package/dist/mcp/bootstrap.d.ts.map +1 -1
- package/dist/mcp/bootstrap.js +3 -11
- package/dist/mcp/bootstrap.js.map +1 -1
- package/dist/mcp/state-paths.d.ts.map +1 -1
- package/dist/mcp/state-paths.js +18 -0
- package/dist/mcp/state-paths.js.map +1 -1
- package/dist/modes/__tests__/base-tmux-pane.test.js +1 -1
- package/dist/modes/__tests__/base-tmux-pane.test.js.map +1 -1
- package/dist/notifications/__tests__/config.test.js +38 -1
- package/dist/notifications/__tests__/config.test.js.map +1 -1
- package/dist/notifications/__tests__/tmux-detector.test.js +1 -1
- package/dist/notifications/__tests__/tmux-detector.test.js.map +1 -1
- package/dist/notifications/tmux-detector.d.ts +1 -0
- package/dist/notifications/tmux-detector.d.ts.map +1 -1
- package/dist/notifications/tmux-detector.js +6 -3
- package/dist/notifications/tmux-detector.js.map +1 -1
- package/dist/notifications/tmux.d.ts.map +1 -1
- package/dist/notifications/tmux.js +20 -38
- package/dist/notifications/tmux.js.map +1 -1
- package/dist/openclaw/__tests__/config.test.js +97 -10
- package/dist/openclaw/__tests__/config.test.js.map +1 -1
- package/dist/openclaw/config.d.ts +19 -1
- package/dist/openclaw/config.d.ts.map +1 -1
- package/dist/openclaw/config.js +220 -20
- package/dist/openclaw/config.js.map +1 -1
- package/dist/planning/artifacts.d.ts +7 -0
- package/dist/planning/artifacts.d.ts.map +1 -1
- package/dist/planning/artifacts.js +18 -4
- package/dist/planning/artifacts.js.map +1 -1
- package/dist/scripts/__tests__/codex-native-hook.test.js +748 -11
- 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 +71 -31
- package/dist/scripts/codex-native-hook.js.map +1 -1
- package/dist/scripts/codex-native-pre-post.d.ts.map +1 -1
- package/dist/scripts/codex-native-pre-post.js +336 -0
- package/dist/scripts/codex-native-pre-post.js.map +1 -1
- package/dist/scripts/notify-hook/auto-nudge.d.ts +1 -0
- package/dist/scripts/notify-hook/auto-nudge.d.ts.map +1 -1
- package/dist/scripts/notify-hook/auto-nudge.js +10 -2
- package/dist/scripts/notify-hook/auto-nudge.js.map +1 -1
- package/dist/scripts/notify-hook/team-worker.js +1 -1
- package/dist/scripts/notify-hook/team-worker.js.map +1 -1
- package/dist/scripts/notify-hook/tmux-injection.d.ts.map +1 -1
- package/dist/scripts/notify-hook/tmux-injection.js +78 -4
- package/dist/scripts/notify-hook/tmux-injection.js.map +1 -1
- package/dist/scripts/tmux-hook-engine.d.ts.map +1 -1
- package/dist/scripts/tmux-hook-engine.js +9 -7
- package/dist/scripts/tmux-hook-engine.js.map +1 -1
- package/dist/state/__tests__/operations.test.js +38 -0
- package/dist/state/__tests__/operations.test.js.map +1 -1
- package/dist/state/__tests__/workflow-transition.test.js +2 -0
- package/dist/state/__tests__/workflow-transition.test.js.map +1 -1
- package/dist/state/skill-active.d.ts +1 -1
- package/dist/state/skill-active.d.ts.map +1 -1
- package/dist/state/skill-active.js +8 -4
- package/dist/state/skill-active.js.map +1 -1
- package/dist/state/workflow-transition-reconcile.js +1 -1
- package/dist/state/workflow-transition-reconcile.js.map +1 -1
- package/dist/state/workflow-transition.js +3 -3
- package/dist/state/workflow-transition.js.map +1 -1
- package/dist/team/__tests__/leader-activity.test.js +28 -0
- package/dist/team/__tests__/leader-activity.test.js.map +1 -1
- package/dist/team/__tests__/tmux-session.test.js +42 -0
- package/dist/team/__tests__/tmux-session.test.js.map +1 -1
- package/dist/team/__tests__/worktree.test.js +29 -0
- package/dist/team/__tests__/worktree.test.js.map +1 -1
- package/dist/team/leader-activity.d.ts.map +1 -1
- package/dist/team/leader-activity.js +23 -1
- package/dist/team/leader-activity.js.map +1 -1
- package/dist/team/worktree.d.ts.map +1 -1
- package/dist/team/worktree.js +17 -1
- package/dist/team/worktree.js.map +1 -1
- package/dist/utils/__tests__/paths.test.js +6 -1
- package/dist/utils/__tests__/paths.test.js.map +1 -1
- package/dist/utils/__tests__/platform-command.test.js +19 -1
- package/dist/utils/__tests__/platform-command.test.js.map +1 -1
- package/dist/utils/paths.d.ts +2 -0
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +4 -0
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/platform-command.d.ts +1 -0
- package/dist/utils/platform-command.d.ts.map +1 -1
- package/dist/utils/platform-command.js +40 -23
- package/dist/utils/platform-command.js.map +1 -1
- package/dist/verification/__tests__/explore-harness-release-workflow.test.js +1 -1
- package/dist/verification/__tests__/pr-check-workflow.test.d.ts +2 -0
- package/dist/verification/__tests__/pr-check-workflow.test.d.ts.map +1 -0
- package/dist/verification/__tests__/pr-check-workflow.test.js +27 -0
- package/dist/verification/__tests__/pr-check-workflow.test.js.map +1 -0
- package/package.json +1 -1
- package/skills/ralph/SKILL.md +7 -0
- package/skills/ralph-init/SKILL.md +2 -1
- package/src/scripts/__tests__/codex-native-hook.test.ts +970 -94
- package/src/scripts/codex-native-hook.ts +109 -26
- package/src/scripts/codex-native-pre-post.ts +376 -0
- package/src/scripts/notify-hook/auto-nudge.ts +12 -2
- package/src/scripts/notify-hook/team-worker.ts +1 -1
- package/src/scripts/notify-hook/tmux-injection.ts +93 -3
- package/src/scripts/tmux-hook-engine.ts +9 -7
- package/templates/AGENTS.md +3 -1
package/Cargo.lock
CHANGED
|
@@ -32,11 +32,11 @@ checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
|
|
|
32
32
|
|
|
33
33
|
[[package]]
|
|
34
34
|
name = "omx-explore-harness"
|
|
35
|
-
version = "0.
|
|
35
|
+
version = "0.13.0"
|
|
36
36
|
|
|
37
37
|
[[package]]
|
|
38
38
|
name = "omx-mux"
|
|
39
|
-
version = "0.
|
|
39
|
+
version = "0.13.0"
|
|
40
40
|
dependencies = [
|
|
41
41
|
"serde",
|
|
42
42
|
"serde_json",
|
|
@@ -44,7 +44,7 @@ dependencies = [
|
|
|
44
44
|
|
|
45
45
|
[[package]]
|
|
46
46
|
name = "omx-runtime"
|
|
47
|
-
version = "0.
|
|
47
|
+
version = "0.13.0"
|
|
48
48
|
dependencies = [
|
|
49
49
|
"omx-mux",
|
|
50
50
|
"omx-runtime-core",
|
|
@@ -53,7 +53,7 @@ dependencies = [
|
|
|
53
53
|
|
|
54
54
|
[[package]]
|
|
55
55
|
name = "omx-runtime-core"
|
|
56
|
-
version = "0.
|
|
56
|
+
version = "0.13.0"
|
|
57
57
|
dependencies = [
|
|
58
58
|
"fs2",
|
|
59
59
|
"serde",
|
|
@@ -62,7 +62,7 @@ dependencies = [
|
|
|
62
62
|
|
|
63
63
|
[[package]]
|
|
64
64
|
name = "omx-sparkshell"
|
|
65
|
-
version = "0.
|
|
65
|
+
version = "0.13.0"
|
|
66
66
|
dependencies = [
|
|
67
67
|
"omx-mux",
|
|
68
68
|
]
|
package/Cargo.toml
CHANGED
package/README.md
CHANGED
|
@@ -220,6 +220,7 @@ omx wiki refresh --json
|
|
|
220
220
|
|
|
221
221
|
`omx team` works best on macOS/Linux with `tmux`.
|
|
222
222
|
Native Windows remains a secondary path, and WSL2 is generally the better choice if you want a Windows-hosted setup.
|
|
223
|
+
On native Windows, OMX accepts `psmux` as the tmux-compatible binary for the existing tmux-backed paths it already uses.
|
|
223
224
|
|
|
224
225
|
| Platform | Install |
|
|
225
226
|
| --- | --- |
|
|
@@ -12,6 +12,8 @@ const CODEX_BIN_ENV: &str = "OMX_EXPLORE_CODEX_BIN";
|
|
|
12
12
|
const HARNESS_ROOT_ENV: &str = "OMX_EXPLORE_ROOT";
|
|
13
13
|
const INTERNAL_DIRECT_WRAPPER_FLAG: &str = "--internal-allowlist-direct";
|
|
14
14
|
const INTERNAL_SHELL_WRAPPER_FLAG: &str = "--internal-allowlist-shell";
|
|
15
|
+
const WINDOWS_UNSUPPORTED_ALLOWLIST_MESSAGE: &str =
|
|
16
|
+
"omx explore built-in harness is not ready on Windows because its allowlist runtime relies on POSIX sh/bash wrappers. Set OMX_EXPLORE_BIN to a compatible custom harness, prefer `omx sparkshell` for shell-native read-only lookups, or run `omx doctor` for readiness details.";
|
|
15
17
|
|
|
16
18
|
const ALLOWED_DIRECT_COMMANDS: &[&str] = &[
|
|
17
19
|
"rg", "grep", "ls", "find", "wc", "cat", "head", "tail", "pwd", "printf",
|
|
@@ -270,7 +272,12 @@ fn resolve_codex_binary() -> String {
|
|
|
270
272
|
}
|
|
271
273
|
|
|
272
274
|
fn codex_launch_for_binary(codex_binary: &str) -> Option<CodexLaunch> {
|
|
273
|
-
let
|
|
275
|
+
let codex_path = Path::new(codex_binary);
|
|
276
|
+
if let Some(launch) = codex_launch_for_posix_node_shim(codex_path) {
|
|
277
|
+
return Some(launch);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
let interpreter = read_shebang_interpreter(codex_path)?;
|
|
274
281
|
let (program, mut leading_args) = resolve_shebang_launch(&interpreter)?;
|
|
275
282
|
leading_args.push(codex_binary.to_string());
|
|
276
283
|
Some(CodexLaunch {
|
|
@@ -279,6 +286,21 @@ fn codex_launch_for_binary(codex_binary: &str) -> Option<CodexLaunch> {
|
|
|
279
286
|
})
|
|
280
287
|
}
|
|
281
288
|
|
|
289
|
+
fn codex_launch_for_posix_node_shim(codex_path: &Path) -> Option<CodexLaunch> {
|
|
290
|
+
let shebang = read_shebang_interpreter(codex_path)?;
|
|
291
|
+
if !is_posix_shell_shebang(&shebang) {
|
|
292
|
+
return None;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
let script = read_to_string(codex_path).ok()?;
|
|
296
|
+
let entrypoint = resolve_posix_node_shim_entrypoint(codex_path, &script)?;
|
|
297
|
+
let program = resolve_posix_node_shim_program(codex_path, &script)?;
|
|
298
|
+
Some(CodexLaunch {
|
|
299
|
+
program: program.display().to_string(),
|
|
300
|
+
leading_args: vec![entrypoint.display().to_string()],
|
|
301
|
+
})
|
|
302
|
+
}
|
|
303
|
+
|
|
282
304
|
fn read_shebang_interpreter(path: &Path) -> Option<String> {
|
|
283
305
|
let file = File::open(path).ok()?;
|
|
284
306
|
let mut reader = BufReader::new(file);
|
|
@@ -293,6 +315,85 @@ fn read_shebang_interpreter(path: &Path) -> Option<String> {
|
|
|
293
315
|
.map(ToOwned::to_owned)
|
|
294
316
|
}
|
|
295
317
|
|
|
318
|
+
fn is_posix_shell_shebang(shebang: &str) -> bool {
|
|
319
|
+
let parts: Vec<&str> = shebang.split_whitespace().collect();
|
|
320
|
+
let interpreter = *parts.first().unwrap_or(&"");
|
|
321
|
+
if interpreter.ends_with("/env") {
|
|
322
|
+
return parts
|
|
323
|
+
.get(1)
|
|
324
|
+
.is_some_and(|target| is_posix_shell_name(target));
|
|
325
|
+
}
|
|
326
|
+
is_posix_shell_name(interpreter)
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
fn is_posix_shell_name(value: &str) -> bool {
|
|
330
|
+
matches!(
|
|
331
|
+
Path::new(value).file_name().and_then(|name| name.to_str()),
|
|
332
|
+
Some("sh" | "bash" | "dash" | "ash" | "ksh" | "zsh")
|
|
333
|
+
)
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
fn resolve_posix_node_shim_entrypoint(codex_path: &Path, script: &str) -> Option<PathBuf> {
|
|
337
|
+
let basedir = codex_path.parent()?;
|
|
338
|
+
quoted_shell_segments(script)
|
|
339
|
+
.into_iter()
|
|
340
|
+
.filter_map(|segment| strip_basedir_prefix(&segment).map(ToOwned::to_owned))
|
|
341
|
+
.map(|relative| normalize_path(basedir.join(relative)))
|
|
342
|
+
.find(|candidate| is_node_entrypoint(candidate))
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
fn resolve_posix_node_shim_program(codex_path: &Path, script: &str) -> Option<PathBuf> {
|
|
346
|
+
let basedir = codex_path.parent()?;
|
|
347
|
+
if quoted_shell_segments(script)
|
|
348
|
+
.into_iter()
|
|
349
|
+
.any(|segment| matches!(strip_basedir_prefix(&segment), Some("node")))
|
|
350
|
+
{
|
|
351
|
+
let sibling_node = basedir.join("node");
|
|
352
|
+
if is_usable_host_command(&sibling_node) {
|
|
353
|
+
return Some(sibling_node);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
resolve_host_command("node")
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
fn quoted_shell_segments(script: &str) -> Vec<String> {
|
|
360
|
+
let mut segments = Vec::new();
|
|
361
|
+
let mut active_quote: Option<char> = None;
|
|
362
|
+
let mut current = String::new();
|
|
363
|
+
|
|
364
|
+
for ch in script.chars() {
|
|
365
|
+
if let Some(quote) = active_quote {
|
|
366
|
+
if ch == quote {
|
|
367
|
+
segments.push(std::mem::take(&mut current));
|
|
368
|
+
active_quote = None;
|
|
369
|
+
} else {
|
|
370
|
+
current.push(ch);
|
|
371
|
+
}
|
|
372
|
+
continue;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
if ch == '\'' || ch == '"' {
|
|
376
|
+
active_quote = Some(ch);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
segments
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
fn strip_basedir_prefix(segment: &str) -> Option<&str> {
|
|
384
|
+
segment
|
|
385
|
+
.strip_prefix("$basedir/")
|
|
386
|
+
.or_else(|| segment.strip_prefix("${basedir}/"))
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
fn is_node_entrypoint(path: &Path) -> bool {
|
|
390
|
+
path.is_file()
|
|
391
|
+
&& matches!(
|
|
392
|
+
path.extension().and_then(|value| value.to_str()),
|
|
393
|
+
Some("js" | "cjs" | "mjs")
|
|
394
|
+
)
|
|
395
|
+
}
|
|
396
|
+
|
|
296
397
|
fn resolve_shebang_launch(shebang: &str) -> Option<(String, Vec<String>)> {
|
|
297
398
|
let parts: Vec<&str> = shebang.split_whitespace().collect();
|
|
298
399
|
let interpreter = *parts.first()?;
|
|
@@ -366,6 +467,9 @@ fn compose_exec_prompt(user_prompt: &str, prompt_contract: &str) -> String {
|
|
|
366
467
|
}
|
|
367
468
|
|
|
368
469
|
fn prepare_allowlist_environment() -> Result<AllowlistEnvironment, String> {
|
|
470
|
+
if let Some(message) = allowlist_platform_diagnostic(env::consts::OS) {
|
|
471
|
+
return Err(message.to_string());
|
|
472
|
+
}
|
|
369
473
|
let root = temp_allowlist_dir()?;
|
|
370
474
|
let bin_dir = root.path.join("bin");
|
|
371
475
|
create_dir_all(&bin_dir).map_err(|err| {
|
|
@@ -412,6 +516,13 @@ fn prepare_allowlist_environment() -> Result<AllowlistEnvironment, String> {
|
|
|
412
516
|
})
|
|
413
517
|
}
|
|
414
518
|
|
|
519
|
+
fn allowlist_platform_diagnostic(os: &str) -> Option<&'static str> {
|
|
520
|
+
if os.eq_ignore_ascii_case("windows") {
|
|
521
|
+
return Some(WINDOWS_UNSUPPORTED_ALLOWLIST_MESSAGE);
|
|
522
|
+
}
|
|
523
|
+
None
|
|
524
|
+
}
|
|
525
|
+
|
|
415
526
|
fn temp_allowlist_dir() -> Result<TempDirGuard, String> {
|
|
416
527
|
let dir = env::temp_dir().join(format!(
|
|
417
528
|
"omx-explore-allowlist-{}-{}",
|
|
@@ -469,20 +580,39 @@ fn build_direct_wrapper(self_exe: &Path, command: &str) -> Result<String, String
|
|
|
469
580
|
|
|
470
581
|
fn resolve_host_command(command: &str) -> Option<PathBuf> {
|
|
471
582
|
let candidate = Path::new(command);
|
|
472
|
-
if candidate.is_absolute() && candidate
|
|
583
|
+
if candidate.is_absolute() && is_usable_host_command(candidate) {
|
|
473
584
|
return Some(candidate.to_path_buf());
|
|
474
585
|
}
|
|
475
586
|
|
|
476
587
|
let path = env::var_os("PATH")?;
|
|
477
588
|
for entry in env::split_paths(&path) {
|
|
478
589
|
let resolved = entry.join(command);
|
|
479
|
-
if resolved
|
|
590
|
+
if is_usable_host_command(&resolved) {
|
|
480
591
|
return Some(resolved);
|
|
481
592
|
}
|
|
482
593
|
}
|
|
483
594
|
None
|
|
484
595
|
}
|
|
485
596
|
|
|
597
|
+
fn is_usable_host_command(path: &Path) -> bool {
|
|
598
|
+
let metadata = match path.metadata() {
|
|
599
|
+
Ok(metadata) => metadata,
|
|
600
|
+
Err(_) => return false,
|
|
601
|
+
};
|
|
602
|
+
if !metadata.is_file() {
|
|
603
|
+
return false;
|
|
604
|
+
}
|
|
605
|
+
#[cfg(unix)]
|
|
606
|
+
{
|
|
607
|
+
use std::os::unix::fs::PermissionsExt;
|
|
608
|
+
metadata.permissions().mode() & 0o111 != 0
|
|
609
|
+
}
|
|
610
|
+
#[cfg(not(unix))]
|
|
611
|
+
{
|
|
612
|
+
true
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
|
|
486
616
|
fn shell_quote(value: &str) -> String {
|
|
487
617
|
format!("'{}'", value.replace('\'', "'\"'\"'"))
|
|
488
618
|
}
|
|
@@ -885,6 +1015,7 @@ mod tests {
|
|
|
885
1015
|
|
|
886
1016
|
#[test]
|
|
887
1017
|
fn codex_launch_for_env_node_shebang_uses_host_node_absolute_path() {
|
|
1018
|
+
let _guard = env_lock();
|
|
888
1019
|
let root = temp_allowlist_dir().expect("temp root");
|
|
889
1020
|
let script_path = root.path.join("codex-script");
|
|
890
1021
|
write(&script_path, b"#!/usr/bin/env node\nconsole.log(\"ok\");\n").expect("write script");
|
|
@@ -896,6 +1027,162 @@ mod tests {
|
|
|
896
1027
|
assert_eq!(launch.leading_args, vec![script_path.display().to_string()]);
|
|
897
1028
|
}
|
|
898
1029
|
|
|
1030
|
+
#[cfg(unix)]
|
|
1031
|
+
#[test]
|
|
1032
|
+
fn codex_launch_for_posix_package_manager_shim_uses_host_node_and_entrypoint() {
|
|
1033
|
+
let _guard = env_lock();
|
|
1034
|
+
let root = temp_allowlist_dir().expect("temp root");
|
|
1035
|
+
let host_bin = root.path.join("host-bin");
|
|
1036
|
+
let shim_dir = root.path.join("node_modules").join(".bin");
|
|
1037
|
+
let entrypoint = root
|
|
1038
|
+
.path
|
|
1039
|
+
.join("node_modules")
|
|
1040
|
+
.join("@openai")
|
|
1041
|
+
.join("codex")
|
|
1042
|
+
.join("bin")
|
|
1043
|
+
.join("codex.js");
|
|
1044
|
+
create_dir_all(&host_bin).expect("create host bin");
|
|
1045
|
+
create_dir_all(&shim_dir).expect("create shim dir");
|
|
1046
|
+
create_dir_all(entrypoint.parent().expect("entrypoint parent"))
|
|
1047
|
+
.expect("create entrypoint dir");
|
|
1048
|
+
|
|
1049
|
+
let fake_node = host_bin.join("node");
|
|
1050
|
+
write_executable(&fake_node, "#!/bin/sh\nexit 0\n").expect("write fake node");
|
|
1051
|
+
write(&entrypoint, "console.log('ok');\n").expect("write entrypoint");
|
|
1052
|
+
|
|
1053
|
+
let shim_path = shim_dir.join("codex");
|
|
1054
|
+
write_executable(
|
|
1055
|
+
&shim_path,
|
|
1056
|
+
r#"#!/bin/sh
|
|
1057
|
+
basedir=$(dirname "$0")
|
|
1058
|
+
if [ -x "$basedir/node" ]; then
|
|
1059
|
+
exec "$basedir/node" "$basedir/../@openai/codex/bin/codex.js" "$@"
|
|
1060
|
+
fi
|
|
1061
|
+
exec node "$basedir/../@openai/codex/bin/codex.js" "$@"
|
|
1062
|
+
"#,
|
|
1063
|
+
)
|
|
1064
|
+
.expect("write shim");
|
|
1065
|
+
|
|
1066
|
+
let original_path = env::var_os("PATH");
|
|
1067
|
+
unsafe {
|
|
1068
|
+
env::set_var("PATH", &host_bin);
|
|
1069
|
+
}
|
|
1070
|
+
|
|
1071
|
+
let launch =
|
|
1072
|
+
codex_launch_for_binary(shim_path.to_str().expect("shim path")).expect("launch config");
|
|
1073
|
+
|
|
1074
|
+
match original_path {
|
|
1075
|
+
Some(value) => unsafe { env::set_var("PATH", value) },
|
|
1076
|
+
None => unsafe { env::remove_var("PATH") },
|
|
1077
|
+
}
|
|
1078
|
+
|
|
1079
|
+
assert_eq!(launch.program, fake_node.display().to_string());
|
|
1080
|
+
assert_eq!(launch.leading_args, vec![entrypoint.display().to_string()]);
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
#[cfg(unix)]
|
|
1084
|
+
#[test]
|
|
1085
|
+
fn resolve_host_command_skips_directory_and_non_executable_path_entries() {
|
|
1086
|
+
let _guard = env_lock();
|
|
1087
|
+
let root = temp_allowlist_dir().expect("temp root");
|
|
1088
|
+
let bad_bin = root.path.join("bad-bin");
|
|
1089
|
+
let blocked_file_bin = root.path.join("blocked-file-bin");
|
|
1090
|
+
let good_bin = root.path.join("good-bin");
|
|
1091
|
+
create_dir_all(&bad_bin).expect("create bad bin");
|
|
1092
|
+
create_dir_all(&blocked_file_bin).expect("create blocked file bin");
|
|
1093
|
+
create_dir_all(&good_bin).expect("create good bin");
|
|
1094
|
+
|
|
1095
|
+
let blocked_directory = bad_bin.join("node");
|
|
1096
|
+
create_dir_all(&blocked_directory).expect("create blocked directory");
|
|
1097
|
+
|
|
1098
|
+
let blocked_node = blocked_file_bin.join("node");
|
|
1099
|
+
write(&blocked_node, "#!/bin/sh\nexit 0\n").expect("write blocked file node");
|
|
1100
|
+
let executable_node = good_bin.join("node");
|
|
1101
|
+
write_executable(&executable_node, "#!/bin/sh\nexit 0\n").expect("write executable node");
|
|
1102
|
+
|
|
1103
|
+
#[cfg(unix)]
|
|
1104
|
+
{
|
|
1105
|
+
use std::fs;
|
|
1106
|
+
use std::os::unix::fs::PermissionsExt;
|
|
1107
|
+
let mut perms = fs::metadata(&blocked_node)
|
|
1108
|
+
.expect("stat blocked node")
|
|
1109
|
+
.permissions();
|
|
1110
|
+
perms.set_mode(0o644);
|
|
1111
|
+
fs::set_permissions(&blocked_node, perms).expect("chmod blocked node");
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
let original_path = env::var_os("PATH");
|
|
1115
|
+
unsafe {
|
|
1116
|
+
env::set_var(
|
|
1117
|
+
"PATH",
|
|
1118
|
+
env::join_paths([
|
|
1119
|
+
bad_bin.as_path(),
|
|
1120
|
+
blocked_file_bin.as_path(),
|
|
1121
|
+
good_bin.as_path(),
|
|
1122
|
+
])
|
|
1123
|
+
.expect("join path"),
|
|
1124
|
+
);
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
let resolved = resolve_host_command("node");
|
|
1128
|
+
|
|
1129
|
+
match original_path {
|
|
1130
|
+
Some(value) => unsafe { env::set_var("PATH", value) },
|
|
1131
|
+
None => unsafe { env::remove_var("PATH") },
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
assert_eq!(resolved, Some(executable_node));
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
#[cfg(unix)]
|
|
1138
|
+
#[test]
|
|
1139
|
+
fn codex_launch_for_env_node_shebang_skips_non_executable_earlier_node_entry() {
|
|
1140
|
+
let _guard = env_lock();
|
|
1141
|
+
let root = temp_allowlist_dir().expect("temp root");
|
|
1142
|
+
let bad_bin = root.path.join("bad-bin");
|
|
1143
|
+
let good_bin = root.path.join("good-bin");
|
|
1144
|
+
create_dir_all(&bad_bin).expect("create bad bin");
|
|
1145
|
+
create_dir_all(&good_bin).expect("create good bin");
|
|
1146
|
+
|
|
1147
|
+
let blocked_node = bad_bin.join("node");
|
|
1148
|
+
write(&blocked_node, "#!/bin/sh\nexit 0\n").expect("write blocked node");
|
|
1149
|
+
let executable_node = good_bin.join("node");
|
|
1150
|
+
write_executable(&executable_node, "#!/bin/sh\nexit 0\n").expect("write executable node");
|
|
1151
|
+
|
|
1152
|
+
#[cfg(unix)]
|
|
1153
|
+
{
|
|
1154
|
+
use std::fs;
|
|
1155
|
+
use std::os::unix::fs::PermissionsExt;
|
|
1156
|
+
let mut perms = fs::metadata(&blocked_node)
|
|
1157
|
+
.expect("stat blocked node")
|
|
1158
|
+
.permissions();
|
|
1159
|
+
perms.set_mode(0o644);
|
|
1160
|
+
fs::set_permissions(&blocked_node, perms).expect("chmod blocked node");
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
let script_path = root.path.join("codex-script");
|
|
1164
|
+
write(&script_path, b"#!/usr/bin/env node\nconsole.log(\"ok\");\n").expect("write script");
|
|
1165
|
+
|
|
1166
|
+
let original_path = env::var_os("PATH");
|
|
1167
|
+
unsafe {
|
|
1168
|
+
env::set_var(
|
|
1169
|
+
"PATH",
|
|
1170
|
+
env::join_paths([bad_bin.as_path(), good_bin.as_path()]).expect("join path"),
|
|
1171
|
+
);
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
let launch = codex_launch_for_binary(script_path.to_str().expect("script path"))
|
|
1175
|
+
.expect("launch config");
|
|
1176
|
+
|
|
1177
|
+
match original_path {
|
|
1178
|
+
Some(value) => unsafe { env::set_var("PATH", value) },
|
|
1179
|
+
None => unsafe { env::remove_var("PATH") },
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
assert_eq!(launch.program, executable_node.display().to_string());
|
|
1183
|
+
assert_eq!(launch.leading_args, vec![script_path.display().to_string()]);
|
|
1184
|
+
}
|
|
1185
|
+
|
|
899
1186
|
#[cfg(unix)]
|
|
900
1187
|
fn create_host_bin_with_commands(commands: &[&str]) -> (TempDirGuard, PathBuf) {
|
|
901
1188
|
let root = temp_allowlist_dir().expect("temp root");
|
|
@@ -972,6 +1259,7 @@ mod tests {
|
|
|
972
1259
|
#[cfg(unix)]
|
|
973
1260
|
#[test]
|
|
974
1261
|
fn prepare_allowlist_environment_preserves_present_command_wrapper_execution() {
|
|
1262
|
+
let _guard = env_lock();
|
|
975
1263
|
let self_exe = env::current_exe().expect("current exe");
|
|
976
1264
|
let pwd = resolve_host_command("pwd").expect("host pwd path");
|
|
977
1265
|
|
|
@@ -1047,6 +1335,15 @@ mod tests {
|
|
|
1047
1335
|
);
|
|
1048
1336
|
}
|
|
1049
1337
|
|
|
1338
|
+
#[test]
|
|
1339
|
+
fn allowlist_platform_diagnostic_blocks_windows_with_actionable_guidance() {
|
|
1340
|
+
let diagnostic = allowlist_platform_diagnostic("windows").expect("windows diagnostic");
|
|
1341
|
+
|
|
1342
|
+
assert!(diagnostic.contains("not ready on Windows"));
|
|
1343
|
+
assert!(diagnostic.contains("OMX_EXPLORE_BIN"));
|
|
1344
|
+
assert!(allowlist_platform_diagnostic("linux").is_none());
|
|
1345
|
+
}
|
|
1346
|
+
|
|
1050
1347
|
#[test]
|
|
1051
1348
|
fn validate_direct_command_covers_additional_head_wc_and_tail_rejections() {
|
|
1052
1349
|
assert!(validate_direct_command("head", &["-".into()]).is_err());
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"foundation.test.d.ts","sourceRoot":"","sources":["../../../src/adapt/__tests__/foundation.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
3
|
+
import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import { afterEach, beforeEach, describe, it } from "node:test";
|
|
7
|
+
import { buildAdaptDoctorReport, buildAdaptEnvelope, buildAdaptProbeReport, buildAdaptStatusReport, initAdaptFoundation, } from "../index.js";
|
|
8
|
+
import { resolveAdaptPaths } from "../paths.js";
|
|
9
|
+
import { getAdaptTargetDescriptor } from "../registry.js";
|
|
10
|
+
let tempDir;
|
|
11
|
+
let originalEnv;
|
|
12
|
+
beforeEach(async () => {
|
|
13
|
+
originalEnv = { ...process.env };
|
|
14
|
+
tempDir = await mkdtemp(join(tmpdir(), "omx-adapt-foundation-"));
|
|
15
|
+
process.env.HOME = tempDir;
|
|
16
|
+
process.env.CODEX_HOME = join(tempDir, ".codex");
|
|
17
|
+
delete process.env.OMX_OPENCLAW;
|
|
18
|
+
delete process.env.OMX_OPENCLAW_CONFIG;
|
|
19
|
+
delete process.env.OMX_OPENCLAW_COMMAND;
|
|
20
|
+
});
|
|
21
|
+
afterEach(async () => {
|
|
22
|
+
for (const key of Object.keys(process.env)) {
|
|
23
|
+
if (!(key in originalEnv))
|
|
24
|
+
delete process.env[key];
|
|
25
|
+
}
|
|
26
|
+
for (const [key, val] of Object.entries(originalEnv)) {
|
|
27
|
+
process.env[key] = val;
|
|
28
|
+
}
|
|
29
|
+
if (tempDir && existsSync(tempDir)) {
|
|
30
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
async function writeOpenClawOmxConfig(config) {
|
|
34
|
+
const configDir = join(tempDir, ".codex");
|
|
35
|
+
await mkdir(configDir, { recursive: true });
|
|
36
|
+
await writeFile(join(configDir, ".omx-config.json"), `${JSON.stringify(config, null, 2)}\n`);
|
|
37
|
+
}
|
|
38
|
+
describe("adapt foundation", () => {
|
|
39
|
+
it("resolves OMX-owned adapter paths under .omx/adapters/<target>", () => {
|
|
40
|
+
const paths = resolveAdaptPaths(tempDir, "openclaw");
|
|
41
|
+
assert.equal(paths.adapterRoot, join(tempDir, ".omx", "adapters", "openclaw"));
|
|
42
|
+
assert.equal(paths.configPath, join(tempDir, ".omx", "adapters", "openclaw", "adapter.json"));
|
|
43
|
+
assert.equal(paths.envelopePath, join(tempDir, ".omx", "adapters", "openclaw", "envelope.json"));
|
|
44
|
+
assert.equal(paths.probeReportPath, join(tempDir, ".omx", "adapters", "openclaw", "reports", "probe.json"));
|
|
45
|
+
assert.equal(paths.statusReportPath, join(tempDir, ".omx", "adapters", "openclaw", "reports", "status.json"));
|
|
46
|
+
});
|
|
47
|
+
it("links the latest canonical PRD/test-spec artifacts into the envelope", async () => {
|
|
48
|
+
const plansDir = join(tempDir, ".omx", "plans");
|
|
49
|
+
await mkdir(plansDir, { recursive: true });
|
|
50
|
+
await writeFile(join(plansDir, "prd-alpha.md"), "# Alpha\n");
|
|
51
|
+
await writeFile(join(plansDir, "test-spec-alpha.md"), "# Alpha Test Spec\n");
|
|
52
|
+
await writeFile(join(plansDir, "prd-zeta.md"), "# Zeta\n");
|
|
53
|
+
await writeFile(join(plansDir, "test-spec-zeta.md"), "# Zeta Test Spec\n");
|
|
54
|
+
const envelope = buildAdaptEnvelope(tempDir, "openclaw", new Date("2026-04-14T00:00:00.000Z"));
|
|
55
|
+
assert.equal(envelope.planning.prdPath, join(plansDir, "prd-zeta.md"));
|
|
56
|
+
assert.deepEqual(envelope.planning.testSpecPaths, [
|
|
57
|
+
join(plansDir, "test-spec-zeta.md"),
|
|
58
|
+
]);
|
|
59
|
+
assert.match(envelope.planning.summary, /matching test spec/i);
|
|
60
|
+
});
|
|
61
|
+
it("reports asymmetric capability ownership in the shared envelope", () => {
|
|
62
|
+
const envelope = buildAdaptEnvelope(tempDir, "hermes", new Date("2026-04-14T00:00:00.000Z"));
|
|
63
|
+
const ownerships = new Set(envelope.capabilities.map((capability) => capability.ownership));
|
|
64
|
+
assert.deepEqual([...ownerships].sort(), [
|
|
65
|
+
"omx-owned",
|
|
66
|
+
"shared-contract",
|
|
67
|
+
"target-observed",
|
|
68
|
+
]);
|
|
69
|
+
});
|
|
70
|
+
it("keeps OpenClaw init preview read-only until --write is used", () => {
|
|
71
|
+
const result = initAdaptFoundation(tempDir, "openclaw", false, new Date("2026-04-14T00:00:00.000Z"));
|
|
72
|
+
const paths = resolveAdaptPaths(tempDir, "openclaw");
|
|
73
|
+
assert.equal(result.write, false);
|
|
74
|
+
assert.deepEqual(result.wrotePaths, []);
|
|
75
|
+
assert.equal(existsSync(paths.configPath), false);
|
|
76
|
+
assert.equal(existsSync(join(tempDir, ".omx", "state")), false);
|
|
77
|
+
});
|
|
78
|
+
it("writes OpenClaw adapter artifacts only under adapter-owned paths", async () => {
|
|
79
|
+
process.env.OMX_OPENCLAW = "1";
|
|
80
|
+
await writeOpenClawOmxConfig({
|
|
81
|
+
notifications: {
|
|
82
|
+
openclaw: {
|
|
83
|
+
enabled: true,
|
|
84
|
+
gateways: {
|
|
85
|
+
local: {
|
|
86
|
+
type: "http",
|
|
87
|
+
url: "https://example.com/hook",
|
|
88
|
+
timeout: 9000,
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
hooks: {
|
|
92
|
+
"session-start": {
|
|
93
|
+
enabled: true,
|
|
94
|
+
gateway: "local",
|
|
95
|
+
instruction: "start",
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
const result = initAdaptFoundation(tempDir, "openclaw", true, new Date("2026-04-14T00:00:00.000Z"));
|
|
102
|
+
const paths = resolveAdaptPaths(tempDir, "openclaw");
|
|
103
|
+
assert.equal(result.write, true);
|
|
104
|
+
assert.deepEqual(result.wrotePaths, [paths.configPath, paths.envelopePath]);
|
|
105
|
+
assert.equal(existsSync(paths.configPath), true);
|
|
106
|
+
assert.equal(existsSync(paths.envelopePath), true);
|
|
107
|
+
assert.equal(existsSync(join(tempDir, ".omx", "state")), false);
|
|
108
|
+
const envelope = JSON.parse(readFileSync(paths.envelopePath, "utf-8"));
|
|
109
|
+
assert.equal(envelope.target, "openclaw");
|
|
110
|
+
assert.equal(envelope.openclaw?.observedState, "configured");
|
|
111
|
+
assert.equal(envelope.openclaw?.hooks[0]?.event, "session-start");
|
|
112
|
+
});
|
|
113
|
+
it("OpenClaw probe degrades gracefully when env/config evidence is absent", () => {
|
|
114
|
+
const probe = buildAdaptProbeReport(tempDir, "openclaw", new Date("2026-04-14T00:00:00.000Z"));
|
|
115
|
+
assert.equal(probe.openclaw?.observedState, "disabled");
|
|
116
|
+
assert.match(probe.summary, /disabled locally/i);
|
|
117
|
+
});
|
|
118
|
+
it("OpenClaw status degrades gracefully when config is absent", () => {
|
|
119
|
+
process.env.OMX_OPENCLAW = "1";
|
|
120
|
+
const status = buildAdaptStatusReport(tempDir, "openclaw", new Date("2026-04-14T00:00:00.000Z"));
|
|
121
|
+
assert.equal(status.adapter.state, "not-initialized");
|
|
122
|
+
assert.equal(status.openclaw?.observedState, "missing-config");
|
|
123
|
+
assert.match(status.targetRuntime.detail, /local config\/env\/gateway wiring evidence only/i);
|
|
124
|
+
});
|
|
125
|
+
it("OpenClaw status reports local command-gateway blocking without over-claiming health", async () => {
|
|
126
|
+
process.env.OMX_OPENCLAW = "1";
|
|
127
|
+
await writeOpenClawOmxConfig({
|
|
128
|
+
notifications: {
|
|
129
|
+
openclaw: {
|
|
130
|
+
enabled: true,
|
|
131
|
+
gateways: {
|
|
132
|
+
local: { type: "command", command: "echo hi" },
|
|
133
|
+
},
|
|
134
|
+
hooks: {
|
|
135
|
+
stop: {
|
|
136
|
+
enabled: true,
|
|
137
|
+
gateway: "local",
|
|
138
|
+
instruction: "stop",
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
const status = buildAdaptStatusReport(tempDir, "openclaw", new Date("2026-04-14T00:00:00.000Z"));
|
|
145
|
+
assert.equal(status.openclaw?.observedState, "degraded");
|
|
146
|
+
assert.equal(status.openclaw?.hooks.find((hook) => hook.event === "stop")?.status, "blocked");
|
|
147
|
+
assert.match(status.targetRuntime.detail, /not authoritative remote OpenClaw runtime health/i);
|
|
148
|
+
});
|
|
149
|
+
it("doctor surfaces actionable OpenClaw remediation", () => {
|
|
150
|
+
const doctor = buildAdaptDoctorReport(tempDir, "openclaw", new Date("2026-04-14T00:00:00.000Z"));
|
|
151
|
+
assert.equal(doctor.issues[0]?.code, "adapter_not_initialized");
|
|
152
|
+
assert.match(doctor.nextSteps.join("\n"), /OMX_OPENCLAW=1/i);
|
|
153
|
+
assert.match(doctor.nextSteps.join("\n"), /init --write/i);
|
|
154
|
+
});
|
|
155
|
+
it("keeps Hermes foundation behavior unchanged", () => {
|
|
156
|
+
const status = buildAdaptStatusReport(tempDir, "hermes", new Date("2026-04-14T00:00:00.000Z"));
|
|
157
|
+
assert.equal(status.adapter.state, "not-initialized");
|
|
158
|
+
assert.equal(status.targetRuntime.state, "unknown");
|
|
159
|
+
});
|
|
160
|
+
it("doctor surfaces actionable foundation-only remediation", () => {
|
|
161
|
+
const doctor = buildAdaptDoctorReport(tempDir, "hermes", new Date("2026-04-14T00:00:00.000Z"));
|
|
162
|
+
assert.equal(doctor.issues[0]?.code, "adapter_not_initialized");
|
|
163
|
+
assert.match(doctor.nextSteps.join("\n"), /init --write/i);
|
|
164
|
+
assert.match(doctor.nextSteps.join("\n"), /Hermes adapter reads external ACP, gateway, and session-store evidence/i);
|
|
165
|
+
});
|
|
166
|
+
it("rejects inherited prototype-like targets during validation", () => {
|
|
167
|
+
assert.equal(getAdaptTargetDescriptor("__proto__"), null);
|
|
168
|
+
assert.equal(getAdaptTargetDescriptor("constructor"), null);
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
//# sourceMappingURL=foundation.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"foundation.test.js","sourceRoot":"","sources":["../../../src/adapt/__tests__/foundation.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hermes.test.d.ts","sourceRoot":"","sources":["../../../src/adapt/__tests__/hermes.test.ts"],"names":[],"mappings":""}
|