sneakoscope 3.1.4 → 3.1.6
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/README.md +8 -36
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/crates/sks-core/src/main.rs +1 -1
- package/dist/.sks-build-stamp.json +4 -4
- package/dist/bin/sks.js +1 -1
- package/dist/cli/command-registry.js +1 -2
- package/dist/cli/install-helpers.js +56 -4
- package/dist/commands/codex-app.js +1 -11
- package/dist/commands/codex-lb.js +12 -9
- package/dist/commands/codex-native.js +68 -0
- package/dist/commands/doctor.js +64 -0
- package/dist/core/codex-app/codex-agent-role-sync.js +69 -11
- package/dist/core/codex-app/codex-agent-type-probe.js +202 -0
- package/dist/core/codex-app/codex-app-execution-profile.js +43 -14
- package/dist/core/codex-app/codex-app-fast-ui-repair.js +7 -4
- package/dist/core/codex-app/codex-app-harness-matrix.js +4 -65
- package/dist/core/codex-app/codex-app-types.js +21 -0
- package/dist/core/codex-app/codex-hook-approval-probe.js +188 -0
- package/dist/core/codex-app/codex-hook-lifecycle.js +34 -10
- package/dist/core/codex-app/codex-init-deep.js +154 -3
- package/dist/core/codex-app/codex-skill-sync.js +84 -9
- package/dist/core/codex-native/codex-native-capability-cache.js +21 -0
- package/dist/core/codex-native/codex-native-feature-broker.js +182 -0
- package/dist/core/codex-native/codex-native-feature-matrix.js +31 -0
- package/dist/core/codex-native/codex-native-harness-compat.js +54 -0
- package/dist/core/codex-native/codex-native-interop-policy.js +58 -0
- package/dist/core/codex-native/codex-native-invocation-router.js +112 -0
- package/dist/core/codex-native/codex-native-pattern-analysis.js +56 -0
- package/dist/core/codex-native/codex-native-reference-evidence.js +2 -0
- package/dist/core/codex-native/codex-native-reference-source.js +110 -0
- package/dist/core/codex-native/codex-native-rename-map.js +25 -0
- package/dist/core/commands/mad-sks-command.js +37 -2
- package/dist/core/commands/qa-loop-command.js +3 -2
- package/dist/core/commands/research-command.js +2 -2
- package/dist/core/doctor/doctor-zellij-repair.js +5 -1
- package/dist/core/feature-fixtures.js +3 -4
- package/dist/core/feature-registry.js +5 -2
- package/dist/core/fsx.js +1 -1
- package/dist/core/image/image-artifact-path-contract.js +18 -1
- package/dist/core/init.js +4 -1
- package/dist/core/loops/loop-continuation-enforcer.js +11 -3
- package/dist/core/loops/loop-owner-inference.js +3 -0
- package/dist/core/loops/loop-planner.js +28 -5
- package/dist/core/loops/loop-worker-runtime.js +52 -8
- package/dist/core/naruto/naruto-loop-worker-router.js +11 -2
- package/dist/core/qa-loop.js +62 -4
- package/dist/core/research/research-cycle-runner.js +1 -0
- package/dist/core/research/research-stage-runner.js +9 -2
- package/dist/core/research.js +68 -1
- package/dist/core/routes.js +2 -3
- package/dist/core/version.js +1 -1
- package/dist/core/zellij/homebrew-policy.js +0 -1
- package/dist/core/zellij/zellij-self-heal-types.js +45 -0
- package/dist/core/zellij/zellij-self-heal.js +69 -8
- package/dist/core/zellij/zellij-update.js +9 -1
- package/dist/scripts/sks-3-1-4-directive-check-lib.js +1 -30
- package/dist/scripts/sks-3-1-5-directive-check-lib.js +318 -0
- package/dist/scripts/sks-3-1-6-directive-check-lib.js +522 -0
- package/package.json +53 -9
- package/dist/cli/hermes-command.js +0 -99
- package/dist/cli/openclaw-command.js +0 -83
- package/dist/commands/hermes.js +0 -5
- package/dist/commands/openclaw.js +0 -3
- package/dist/core/codex-app/lazycodex-analysis.js +0 -51
- package/dist/core/codex-app/lazycodex-interop-policy.js +0 -49
- package/dist/core/hermes.js +0 -192
- package/dist/core/openclaw.js +0 -171
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@ Sneakoscope Codex (`sks`) is a Codex CLI/App harness that makes repeatable Codex
|
|
|
27
27
|
|
|
28
28
|

|
|
29
29
|
|
|
30
|
-
## LLM Init Prompt for
|
|
30
|
+
## LLM Init Prompt for Codex Native Agent Builders
|
|
31
31
|
|
|
32
32
|
```text
|
|
33
33
|
Set up this agent project with Sneakoscope Codex. Use [[mandarange/Sneakoscope-Codex](https://github.com/mandarange/Sneakoscope-Codex)] as the repo reference and [npm i -g sneakoscope] as the recommended global install command, then run the appropriate `sks` setup, doctor, Codex App, and proof checks for this repo. Keep generated SKS state out of source control unless documented, and record every version-facing change in CHANGELOG.md.
|
|
@@ -35,7 +35,7 @@ Set up this agent project with Sneakoscope Codex. Use [[mandarange/Sneakoscope-C
|
|
|
35
35
|
|
|
36
36
|
## 🚀 Current Release
|
|
37
37
|
|
|
38
|
-
SKS **3.1.
|
|
38
|
+
SKS **3.1.6** removes external reference branding from user-visible release surfaces and routes Codex-native feature decisions through one broker for Loop, QA, Research, Image, MAD, and Doctor.
|
|
39
39
|
|
|
40
40
|
SKS 3.0.0 was the parallel-runtime stabilization release. The whole live-swarm experience — what you actually *see* while 5, 20, or 100 workers run — was rebuilt and proven end-to-end.
|
|
41
41
|
|
|
@@ -292,7 +292,7 @@ sks selftest --mock
|
|
|
292
292
|
|
|
293
293
|
## 🎁 What Sneakoscope Adds
|
|
294
294
|
|
|
295
|
-
`sks` adds a Zellij-backed Codex CLI runtime, Codex App `$` commands, Team/QA/PPT/Research/DB/GX/Wiki routes,
|
|
295
|
+
`sks` adds a Zellij-backed Codex CLI runtime, Codex App `$` commands, Codex Native broker routing, Team/QA/PPT/Research/DB/GX/Wiki routes, Context7-gated current docs, TriWiki context packs, DB safety, design SSOT policy, skill dreaming, release checks, and Honest Mode.
|
|
296
296
|
|
|
297
297
|
## Report-Only Planning Surfaces
|
|
298
298
|
|
|
@@ -618,43 +618,15 @@ SKS does not install Git pre-commit hooks. Release metadata is changed only by e
|
|
|
618
618
|
|
|
619
619
|
TriWiki is intentionally sparse: `sks wiki sweep` records demote, soft-forget, archive, delete, promote-to-skill, and promote-to-rule candidates instead of injecting every old claim into future prompts. `sks harness fixture` validates the broader Harness Growth Factory contract: deliberate forgetting fixtures, skill card metadata, experiment schema, tool-error taxonomy, permission profiles, MultiAgentV2 defaults, and tmux cockpit view coverage. `sks code-structure scan` flags handwritten files above 1000/2000/3000-line thresholds so new logic can be extracted before command files become harder to maintain.
|
|
620
620
|
|
|
621
|
-
##
|
|
622
|
-
|
|
623
|
-
Sneakoscope can generate an OpenClaw skill package for agents that need to operate SKS-enabled repositories.
|
|
621
|
+
## Codex Native Broker
|
|
624
622
|
|
|
625
623
|
```sh
|
|
626
|
-
sks
|
|
627
|
-
sks
|
|
624
|
+
sks codex-native status --json
|
|
625
|
+
sks codex-native invocation-plan --route '$Loop' --capability agent-role --json
|
|
626
|
+
sks codex-native init-deep --apply --directory-local --json
|
|
628
627
|
```
|
|
629
628
|
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
```sh
|
|
633
|
-
SKS_OPENCLAW=1 sks root
|
|
634
|
-
SKS_OPENCLAW=1 sks commands
|
|
635
|
-
SKS_OPENCLAW=1 sks dollar-commands
|
|
636
|
-
SKS_OPENCLAW=1 sks deps check
|
|
637
|
-
SKS_OPENCLAW=1 sks proof-field scan --intent "small CLI change" --changed src/cli/main.ts
|
|
638
|
-
```
|
|
639
|
-
|
|
640
|
-
If OpenClaw runs in a sandbox, grant shell execution only for trusted workspaces. Database, migration, and destructive work still follows SKS safety routes.
|
|
641
|
-
|
|
642
|
-
Sneakoscope can also generate a Hermes Agent skill package for the Hermes `/skills` surface.
|
|
643
|
-
|
|
644
|
-
```sh
|
|
645
|
-
sks hermes install
|
|
646
|
-
sks hermes status --json
|
|
647
|
-
sks hermes path
|
|
648
|
-
```
|
|
649
|
-
|
|
650
|
-
By default this writes `~/.hermes/skills/sneakoscope-codex/` with `SKILL.md`, a README, `hermes-config.example.yaml`, and `skill-bundle.example.yaml`. Set `HERMES_HOME` or pass `--dir` for a custom location. Hermes agents should invoke `/sneakoscope-codex` with the terminal toolset enabled and run shell commands with `SKS_HERMES=1`; this enables non-interactive dependency/update prompts while leaving SKS DB, migration, and destructive-operation safety routes intact. If you use Hermes `skills.external_dirs`, remember writable external directories can be updated by Hermes, so protect shared skill folders with filesystem permissions when needed.
|
|
651
|
-
|
|
652
|
-
```sh
|
|
653
|
-
SKS_HERMES=1 sks root --json
|
|
654
|
-
SKS_HERMES=1 sks commands --json
|
|
655
|
-
SKS_HERMES=1 sks dollar-commands --json
|
|
656
|
-
SKS_HERMES=1 sks status --json
|
|
657
|
-
```
|
|
629
|
+
The broker records Codex-native feature availability, invocation defaults, neutral pattern evidence, and managed memory setup without exposing reference implementation branding in user-facing artifacts.
|
|
658
630
|
|
|
659
631
|
## 💬 Prompt `$` Commands
|
|
660
632
|
|
|
@@ -4,7 +4,7 @@ use std::io::{self, Read, Seek, SeekFrom};
|
|
|
4
4
|
fn main() {
|
|
5
5
|
let mut args = std::env::args().skip(1);
|
|
6
6
|
match args.next().as_deref() {
|
|
7
|
-
Some("--version") => println!("sks-rs 3.1.
|
|
7
|
+
Some("--version") => println!("sks-rs 3.1.6"),
|
|
8
8
|
Some("compact-info") => {
|
|
9
9
|
let mut input = String::new();
|
|
10
10
|
let _ = io::stdin().read_to_string(&mut input);
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "sks.dist-build-stamp.v1",
|
|
3
3
|
"package_name": "sneakoscope",
|
|
4
|
-
"package_version": "3.1.
|
|
5
|
-
"source_digest": "
|
|
6
|
-
"source_file_count":
|
|
7
|
-
"built_at_source_time":
|
|
4
|
+
"package_version": "3.1.6",
|
|
5
|
+
"source_digest": "98f9f4c6a64ddd6b1d43f757e16358768f24b27cd9c3285eab0bdacce7cbf5d6",
|
|
6
|
+
"source_file_count": 2543,
|
|
7
|
+
"built_at_source_time": 1781450666248
|
|
8
8
|
}
|
package/dist/bin/sks.js
CHANGED
|
@@ -97,11 +97,10 @@ export const COMMANDS = {
|
|
|
97
97
|
postinstall: entry('stable', 'Run postinstall bootstrap', 'dist/core/commands/basic-cli.js', basicArgs('postinstallCommand')),
|
|
98
98
|
codex: entry('beta', 'Check Codex CLI compatibility and vendored hook schemas', 'dist/commands/codex.js', directCommand(() => import('../commands/codex.js'), 'dist/commands/codex.js')),
|
|
99
99
|
'codex-app': entry('beta', 'Check Codex App readiness', 'dist/commands/codex-app.js', directCommand(() => import('../commands/codex-app.js'), 'dist/commands/codex-app.js')),
|
|
100
|
+
'codex-native': entry('beta', 'Inspect Codex Native broker and routing readiness', 'dist/commands/codex-native.js', directCommand(() => import('../commands/codex-native.js'), 'dist/commands/codex-native.js')),
|
|
100
101
|
'codex-lb': entry('beta', 'Inspect codex-lb status and circuit health', 'dist/commands/codex-lb.js', directCommand(() => import('../commands/codex-lb.js'), 'dist/commands/codex-lb.js')),
|
|
101
102
|
auth: entry('beta', 'Alias for codex-lb auth commands', 'dist/commands/codex-lb.js', directCommand(() => import('../commands/codex-lb.js'), 'dist/commands/codex-lb.js')),
|
|
102
103
|
hooks: entry('beta', 'Explain and inspect Codex hooks', 'dist/commands/hooks.js', directCommand(() => import('../commands/hooks.js'), 'dist/commands/hooks.js')),
|
|
103
|
-
openclaw: entry('labs', 'Create OpenClaw skill package', 'dist/commands/openclaw.js', directCommand(() => import('../commands/openclaw.js'), 'dist/commands/openclaw.js')),
|
|
104
|
-
hermes: entry('labs', 'Create Hermes Agent skill package', 'dist/commands/hermes.js', directCommand(() => import('../commands/hermes.js'), 'dist/commands/hermes.js')),
|
|
105
104
|
tmux: entry('beta', 'Show removed-runtime migration notice', 'dist/commands/tmux.js', directCommand(() => import('../commands/tmux.js'), 'dist/commands/tmux.js')),
|
|
106
105
|
'zellij-lane': entry('beta', 'Render a Zellij lane frame for SKS sessions', 'dist/commands/zellij-lane.js', directCommand(() => import('../commands/zellij-lane.js'), 'dist/commands/zellij-lane.js')),
|
|
107
106
|
'zellij-slot-pane': entry('beta', 'Render a compact Zellij worker slot pane', 'dist/commands/zellij-slot-pane.js', directCommand(() => import('../commands/zellij-slot-pane.js'), 'dist/commands/zellij-slot-pane.js')),
|
|
@@ -144,6 +144,8 @@ async function reportPostinstallCodexLbAuth() {
|
|
|
144
144
|
console.log(`codex-lb auth: restored from existing Codex login cache into ${codexLbAuth.env_path}.`);
|
|
145
145
|
else if (codexLbAuth.status === 'synced' || codexLbAuth.status === 'present' || codexLbAuth.status === 'repaired')
|
|
146
146
|
console.log(`codex-lb auth: preserved from ${codexLbAuth.env_path}.`);
|
|
147
|
+
else if (codexLbAuth.status === 'present_unselected')
|
|
148
|
+
console.log('codex-lb auth: preserved but not selected; ChatGPT OAuth remains active.');
|
|
147
149
|
else if (codexLbAuth.status === 'skipped')
|
|
148
150
|
console.log(`codex-lb auth: skipped (${codexLbAuth.reason}).`);
|
|
149
151
|
else if (codexLbAuth.status === 'missing_env_key')
|
|
@@ -284,6 +286,7 @@ async function capturePostinstallCodexLbConfigSnapshot(home = process.env.HOME |
|
|
|
284
286
|
env_path: envPath,
|
|
285
287
|
auth_path: authPath,
|
|
286
288
|
base_url: baseUrl ? normalizeCodexLbBaseUrl(baseUrl) : null,
|
|
289
|
+
selected: hasTopLevelCodexLbSelected(config),
|
|
287
290
|
auth_existed: authExisted,
|
|
288
291
|
auth_text: authText
|
|
289
292
|
};
|
|
@@ -294,7 +297,7 @@ async function restorePostinstallCodexLbConfigSnapshot(snapshot) {
|
|
|
294
297
|
let configRestored = false;
|
|
295
298
|
if (snapshot.base_url) {
|
|
296
299
|
const current = await readText(snapshot.config_path, '');
|
|
297
|
-
const next = normalizeCodexFastModeUiConfig(upsertCodexLbConfig(current, snapshot.base_url));
|
|
300
|
+
const next = normalizeCodexFastModeUiConfig(upsertCodexLbConfig(current, snapshot.base_url, snapshot.selected === true));
|
|
298
301
|
const alreadyOk = next === ensureTrailingNewline(current) && codexLbProviderBaseUrl(current);
|
|
299
302
|
if (!alreadyOk) {
|
|
300
303
|
const safeWrite = await safeWriteCodexConfigToml(snapshot.config_path, current, next, 'codex-lb-restore');
|
|
@@ -488,6 +491,12 @@ export async function codexLbStatus(opts = {}) {
|
|
|
488
491
|
const providerEnvKey = codexLbProviderEnvKey(config);
|
|
489
492
|
const providerUsesCodexLbEnvAuth = providerConfigured && providerEnvKey === 'CODEX_LB_API_KEY' && providerOpenAiAuthDisabled;
|
|
490
493
|
const codexAppUsableWithCodexLb = providerUsesCodexLbEnvAuth && envKeyConfigured && Boolean(baseUrl);
|
|
494
|
+
const launchEnvironment = await inspectCodexLbMacLaunchEnvironment(baseUrl, opts).catch((err) => ({
|
|
495
|
+
checked: true,
|
|
496
|
+
available: false,
|
|
497
|
+
status: 'inspect_failed',
|
|
498
|
+
error: err.message
|
|
499
|
+
}));
|
|
491
500
|
return {
|
|
492
501
|
ok: providerConfigured && envKeyConfigured && Boolean(baseUrl) && providerUsesCodexLbEnvAuth,
|
|
493
502
|
config_path: configPath,
|
|
@@ -514,7 +523,8 @@ export async function codexLbStatus(opts = {}) {
|
|
|
514
523
|
auth_path: authPath,
|
|
515
524
|
auth_mode: authMode.mode,
|
|
516
525
|
auth_usable_for_codex_app: authMode.codex_app_usable || codexAppUsableWithCodexLb,
|
|
517
|
-
auth_summary: codexAppUsableWithCodexLb ? 'codex-lb provider uses CODEX_LB_API_KEY env_key; OpenAI OAuth not required' : authMode.summary
|
|
526
|
+
auth_summary: codexAppUsableWithCodexLb ? 'codex-lb provider uses CODEX_LB_API_KEY env_key; OpenAI OAuth not required' : authMode.summary,
|
|
527
|
+
launch_environment: launchEnvironment
|
|
518
528
|
};
|
|
519
529
|
}
|
|
520
530
|
export function formatCodexLbStatusText(status = {}, opts = {}) {
|
|
@@ -541,12 +551,12 @@ export function formatCodexLbStatusText(status = {}, opts = {}) {
|
|
|
541
551
|
lines.push('', 'Sign in to Codex App/CLI again, then run: sks codex-lb repair');
|
|
542
552
|
else if (status.ok && !status.selected)
|
|
543
553
|
lines.push('', 'Run: sks codex-lb repair to activate codex-lb for Codex App.');
|
|
554
|
+
else if (status.ok)
|
|
555
|
+
lines.push('', 'Status: codex-lb active; no repair needed.');
|
|
544
556
|
else if (!status.ok && status.base_url && status.env_key_configured)
|
|
545
557
|
lines.push('', 'Run: sks codex-lb repair to restore the upstream codex-lb provider block.');
|
|
546
558
|
else if (!status.ok)
|
|
547
559
|
lines.push('', 'Run: sks codex-lb setup --host <domain> --api-key <key>');
|
|
548
|
-
else
|
|
549
|
-
lines.push('', 'Repair provider auth: sks codex-lb repair');
|
|
550
560
|
if (backupPresent)
|
|
551
561
|
lines.push('Switch fully away from codex-lb: sks codex-lb release');
|
|
552
562
|
return `${lines.join('\n')}\n`;
|
|
@@ -862,6 +872,17 @@ export async function ensureCodexLbAuthDuringInstall(opts = {}) {
|
|
|
862
872
|
const status = await codexLbStatus(opts);
|
|
863
873
|
if (!status.selected && !status.provider_configured && !status.env_file)
|
|
864
874
|
return { status: 'not_configured', codex_lb: status };
|
|
875
|
+
if (status.ok && !status.selected && status.auth_mode === 'chatgpt_oauth') {
|
|
876
|
+
return {
|
|
877
|
+
ok: true,
|
|
878
|
+
status: 'present_unselected',
|
|
879
|
+
reason: 'chatgpt_oauth_active_codex_lb_unselected',
|
|
880
|
+
config_path: status.config_path,
|
|
881
|
+
env_path: status.env_path,
|
|
882
|
+
base_url: status.base_url,
|
|
883
|
+
codex_lb: status
|
|
884
|
+
};
|
|
885
|
+
}
|
|
865
886
|
await migrateCodexAuthKeyFormat({ home: opts.home });
|
|
866
887
|
if (status.ok && (!status.selected || !status.provider_uses_codex_lb_env_auth))
|
|
867
888
|
return repairCodexLbAuth(opts);
|
|
@@ -1236,6 +1257,9 @@ export async function maybePromptCodexLbSetupForLaunch(args = [], opts = {}) {
|
|
|
1236
1257
|
if (args.includes('--json') || args.includes('--skip-codex-lb') || process.env.SKS_SKIP_CODEX_LB_PROMPT === '1')
|
|
1237
1258
|
return { status: 'skipped' };
|
|
1238
1259
|
let status = await codexLbStatus(opts);
|
|
1260
|
+
if (status.env_key_configured && status.base_url && !status.selected && status.auth_mode === 'chatgpt_oauth') {
|
|
1261
|
+
return { status: 'continued_to_codex', ok: false, chain_health: null, codex_lb: status, reason: 'chatgpt_oauth_active_codex_lb_unselected' };
|
|
1262
|
+
}
|
|
1239
1263
|
if (status.env_key_configured && status.base_url && (!status.provider_configured || !status.selected || !status.provider_uses_codex_lb_env_auth)) {
|
|
1240
1264
|
let promptedRestore = false;
|
|
1241
1265
|
if (!status.provider_configured && canAskYesNo()) {
|
|
@@ -1355,6 +1379,34 @@ async function syncCodexLbMacLaunchEnvironment(values = {}, opts = {}) {
|
|
|
1355
1379
|
return { ok: false, status: 'launch_env_failed', variables: results.map((result) => result.key), failed, error: failed.map((result) => `${result.key}: ${result.error}`).join('; ') };
|
|
1356
1380
|
return { ok: true, status: 'synced', variables: results.map((result) => result.key) };
|
|
1357
1381
|
}
|
|
1382
|
+
async function inspectCodexLbMacLaunchEnvironment(baseUrl = '', opts = {}) {
|
|
1383
|
+
if (process.platform !== 'darwin' && !opts.forceLaunchEnv)
|
|
1384
|
+
return { checked: false, status: 'not_macos', skipped: true };
|
|
1385
|
+
const launchctl = opts.launchctlBin || await which('launchctl').catch(() => null) || await exists('/bin/launchctl').then((ok) => ok ? '/bin/launchctl' : null).catch(() => null);
|
|
1386
|
+
if (!launchctl)
|
|
1387
|
+
return { checked: true, available: false, status: 'launchctl_missing' };
|
|
1388
|
+
const readVar = async (key) => {
|
|
1389
|
+
const result = await runProcess(launchctl, ['getenv', key], { timeoutMs: 3000, maxOutputBytes: 8192 });
|
|
1390
|
+
return result.code === 0 ? String(result.stdout || '').trim() : '';
|
|
1391
|
+
};
|
|
1392
|
+
const currentBaseUrl = await readVar('CODEX_LB_BASE_URL');
|
|
1393
|
+
const currentApiKey = await readVar('CODEX_LB_API_KEY');
|
|
1394
|
+
const baseMatches = !baseUrl || currentBaseUrl === String(baseUrl || '').trim();
|
|
1395
|
+
const basePresent = Boolean(currentBaseUrl);
|
|
1396
|
+
const keyPresent = Boolean(currentApiKey);
|
|
1397
|
+
return {
|
|
1398
|
+
checked: true,
|
|
1399
|
+
available: true,
|
|
1400
|
+
status: basePresent && keyPresent && baseMatches ? 'synced' : basePresent || keyPresent ? 'partial' : 'missing',
|
|
1401
|
+
variables: [
|
|
1402
|
+
...(keyPresent ? ['CODEX_LB_API_KEY'] : []),
|
|
1403
|
+
...(basePresent ? ['CODEX_LB_BASE_URL'] : [])
|
|
1404
|
+
],
|
|
1405
|
+
base_url_present: basePresent,
|
|
1406
|
+
base_url_matches: baseMatches,
|
|
1407
|
+
api_key_present: keyPresent
|
|
1408
|
+
};
|
|
1409
|
+
}
|
|
1358
1410
|
async function maybeSyncCodexLbSharedLogin(apiKey, opts = {}) {
|
|
1359
1411
|
if (!apiKey)
|
|
1360
1412
|
return { ok: false, status: 'missing_env_key' };
|
|
@@ -9,7 +9,6 @@ import { syncCodexAgentRoles } from '../core/codex-app/codex-agent-role-sync.js'
|
|
|
9
9
|
import { runCodexInitDeep } from '../core/codex-app/codex-init-deep.js';
|
|
10
10
|
import { buildCodexHookLifecycle } from '../core/codex-app/codex-hook-lifecycle.js';
|
|
11
11
|
import { resolveCodexAppExecutionProfile } from '../core/codex-app/codex-app-execution-profile.js';
|
|
12
|
-
import { buildLazyCodexInteropPolicy } from '../core/codex-app/lazycodex-interop-policy.js';
|
|
13
12
|
export async function run(_command, args = []) {
|
|
14
13
|
const action = args[0] || 'check';
|
|
15
14
|
if (action === 'remote-control' || action === 'remote')
|
|
@@ -26,11 +25,6 @@ export async function run(_command, args = []) {
|
|
|
26
25
|
return printCodexAppResult(args, await buildCodexHookLifecycle({ root: await sksRoot(), apply: flag(args, '--apply') || flag(args, '--fix') }));
|
|
27
26
|
if (action === 'execution-profile')
|
|
28
27
|
return printCodexAppResult(args, await resolveCodexAppExecutionProfile({ root: await sksRoot() }));
|
|
29
|
-
if (action === 'interop' && args[1] === 'lazycodex') {
|
|
30
|
-
const modeArg = readOption(args, '--mode', 'coexist');
|
|
31
|
-
const mode = modeArg === 'sks-primary' || modeArg === 'handoff-to-omo' ? modeArg : 'coexist';
|
|
32
|
-
return printCodexAppResult(args, await buildLazyCodexInteropPolicy({ root: await sksRoot(), mode }));
|
|
33
|
-
}
|
|
34
28
|
if (action === 'product-design' || action === 'design-product' || action === 'ensure-product-design') {
|
|
35
29
|
const checkOnly = flag(args, '--check-only') || flag(args, '--no-install');
|
|
36
30
|
const status = await codexProductDesignPluginStatus({
|
|
@@ -91,7 +85,7 @@ export async function run(_command, args = []) {
|
|
|
91
85
|
process.exitCode = 1;
|
|
92
86
|
return;
|
|
93
87
|
}
|
|
94
|
-
console.error('Usage: sks codex-app check|status|harness-matrix|skill-sync|agent-role-sync|init-deep|hook-lifecycle|execution-profile|
|
|
88
|
+
console.error('Usage: sks codex-app check|status|harness-matrix|skill-sync|agent-role-sync|init-deep|hook-lifecycle|execution-profile|product-design [--check-only]|ensure-product-design|chrome-extension|pat status|remote-control [--json]');
|
|
95
89
|
process.exitCode = 1;
|
|
96
90
|
}
|
|
97
91
|
function printCodexAppResult(args = [], result) {
|
|
@@ -109,8 +103,4 @@ function printCodexAppResult(args = [], result) {
|
|
|
109
103
|
if (result?.ok === false)
|
|
110
104
|
process.exitCode = 1;
|
|
111
105
|
}
|
|
112
|
-
function readOption(args = [], name, fallback) {
|
|
113
|
-
const index = args.indexOf(name);
|
|
114
|
-
return index >= 0 && args[index + 1] ? String(args[index + 1]) : fallback;
|
|
115
|
-
}
|
|
116
106
|
//# sourceMappingURL=codex-app.js.map
|
|
@@ -302,16 +302,19 @@ async function resolveNewApiKey(args = []) {
|
|
|
302
302
|
return '';
|
|
303
303
|
}
|
|
304
304
|
function shapeCodexLbStatus(status = {}) {
|
|
305
|
-
const
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
305
|
+
const modes = [];
|
|
306
|
+
if (status.env_file && status.env_key_configured)
|
|
307
|
+
modes.push('durable_env_file');
|
|
308
|
+
if (status.env_loader?.api_key?.source === 'keychain' || status.env_loader?.keychain?.status === 'present')
|
|
309
|
+
modes.push('durable_keychain');
|
|
310
|
+
if (status.launch_environment?.status === 'synced')
|
|
311
|
+
modes.push('durable_launchctl');
|
|
312
|
+
if (!modes.length && status.env_loader?.api_key?.source === 'process.env')
|
|
313
|
+
modes.push('process_only_ephemeral');
|
|
314
|
+
const mode = modes[0] || 'none';
|
|
312
315
|
const persistence = codexLbPersistenceSummary({
|
|
313
|
-
selectedModes:
|
|
314
|
-
appliedModes: mode === 'none' ? ['none'] : [mode],
|
|
316
|
+
selectedModes: modes.length ? modes : [],
|
|
317
|
+
appliedModes: modes.length ? modes : mode === 'none' ? ['none'] : [mode],
|
|
315
318
|
processOnly: mode === 'process_only_ephemeral'
|
|
316
319
|
});
|
|
317
320
|
return {
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { flag } from '../cli/args.js';
|
|
2
|
+
import { printJson } from '../cli/output.js';
|
|
3
|
+
import { sksRoot } from '../core/fsx.js';
|
|
4
|
+
import { syncCodexAgentRoles } from '../core/codex-app/codex-agent-role-sync.js';
|
|
5
|
+
import { resolveCodexAppExecutionProfile } from '../core/codex-app/codex-app-execution-profile.js';
|
|
6
|
+
import { buildCodexAppHarnessMatrix } from '../core/codex-app/codex-app-harness-matrix.js';
|
|
7
|
+
import { buildCodexHookLifecycle } from '../core/codex-app/codex-hook-lifecycle.js';
|
|
8
|
+
import { runCodexInitDeep } from '../core/codex-app/codex-init-deep.js';
|
|
9
|
+
import { syncCodexSksSkills } from '../core/codex-app/codex-skill-sync.js';
|
|
10
|
+
import { buildCodexNativeFeatureMatrix } from '../core/codex-native/codex-native-feature-broker.js';
|
|
11
|
+
import { resolveCodexNativeInvocationPlan } from '../core/codex-native/codex-native-invocation-router.js';
|
|
12
|
+
import { buildCodexNativeInteropPolicy } from '../core/codex-native/codex-native-interop-policy.js';
|
|
13
|
+
import { analyzeCodexNativeReferenceSource } from '../core/codex-native/codex-native-reference-evidence.js';
|
|
14
|
+
import { writeCodexNativePatternAnalysis } from '../core/codex-native/codex-native-pattern-analysis.js';
|
|
15
|
+
export async function run(_command, args = []) {
|
|
16
|
+
const root = await sksRoot();
|
|
17
|
+
const action = String(args[0] || 'status');
|
|
18
|
+
if (action === 'status' || action === 'check' || action === 'feature-broker' || action === 'feature-matrix') {
|
|
19
|
+
return printCodexNativeResult(args, await buildCodexNativeFeatureMatrix({ root, applyRepairs: flag(args, '--fix') || flag(args, '--apply') }));
|
|
20
|
+
}
|
|
21
|
+
if (action === 'harness-matrix' || action === 'harness-compat') {
|
|
22
|
+
return printCodexNativeResult(args, await buildCodexAppHarnessMatrix({ root, applyRepairs: flag(args, '--fix') || flag(args, '--apply') }));
|
|
23
|
+
}
|
|
24
|
+
if (action === 'skill-sync')
|
|
25
|
+
return printCodexNativeResult(args, await syncCodexSksSkills({ root, apply: flag(args, '--apply') || flag(args, '--fix') }));
|
|
26
|
+
if (action === 'agent-role-sync')
|
|
27
|
+
return printCodexNativeResult(args, await syncCodexAgentRoles({ root, apply: flag(args, '--apply') || flag(args, '--fix') }));
|
|
28
|
+
if (action === 'init-deep')
|
|
29
|
+
return printCodexNativeResult(args, await runCodexInitDeep({ root, apply: flag(args, '--apply') || flag(args, '--fix'), directoryLocal: flag(args, '--directory-local') }));
|
|
30
|
+
if (action === 'hook-lifecycle')
|
|
31
|
+
return printCodexNativeResult(args, await buildCodexHookLifecycle({ root, apply: flag(args, '--apply') || flag(args, '--fix') }));
|
|
32
|
+
if (action === 'execution-profile')
|
|
33
|
+
return printCodexNativeResult(args, await resolveCodexAppExecutionProfile({ root }));
|
|
34
|
+
if (action === 'interop-policy')
|
|
35
|
+
return printCodexNativeResult(args, await buildCodexNativeInteropPolicy({ root }));
|
|
36
|
+
if (action === 'reference-evidence')
|
|
37
|
+
return printCodexNativeResult(args, await analyzeCodexNativeReferenceSource({ root, writeReport: true }));
|
|
38
|
+
if (action === 'pattern-analysis')
|
|
39
|
+
return printCodexNativeResult(args, await writeCodexNativePatternAnalysis(root));
|
|
40
|
+
if (action === 'route' || action === 'invocation-plan') {
|
|
41
|
+
const route = readOption(args, '--route', '$Loop');
|
|
42
|
+
const desiredCapability = readOption(args, '--capability', 'agent-role');
|
|
43
|
+
const missionId = readOption(args, '--mission', null);
|
|
44
|
+
return printCodexNativeResult(args, await resolveCodexNativeInvocationPlan({ root, missionId, route, desiredCapability }));
|
|
45
|
+
}
|
|
46
|
+
console.error('Usage: sks codex-native status|feature-broker|harness-compat|skill-sync|agent-role-sync|init-deep|hook-lifecycle|execution-profile|interop-policy|reference-evidence|pattern-analysis|invocation-plan [--json]');
|
|
47
|
+
process.exitCode = 1;
|
|
48
|
+
}
|
|
49
|
+
function printCodexNativeResult(args = [], result) {
|
|
50
|
+
if (flag(args, '--json')) {
|
|
51
|
+
printJson(result);
|
|
52
|
+
if (result?.ok === false)
|
|
53
|
+
process.exitCode = 1;
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
console.log(`${result?.schema || 'sks.codex-native-result'}: ${result?.ok === false ? 'blocked' : 'ok'}`);
|
|
57
|
+
for (const blocker of result?.blockers || [])
|
|
58
|
+
console.log(`- blocker: ${blocker}`);
|
|
59
|
+
for (const warning of result?.warnings || [])
|
|
60
|
+
console.log(`- warning: ${warning}`);
|
|
61
|
+
if (result?.ok === false)
|
|
62
|
+
process.exitCode = 1;
|
|
63
|
+
}
|
|
64
|
+
function readOption(args = [], name, fallback) {
|
|
65
|
+
const index = args.indexOf(name);
|
|
66
|
+
return index >= 0 && args[index + 1] ? String(args[index + 1]) : fallback;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=codex-native.js.map
|
package/dist/commands/doctor.js
CHANGED
|
@@ -25,6 +25,7 @@ import { writeCodexPluginInventoryArtifacts, pluginAppTemplatePolicy } from '../
|
|
|
25
25
|
import { writeMcpPluginInventoryArtifacts } from '../core/mcp/mcp-plugin-inventory.js';
|
|
26
26
|
import { runDoctorZellijRepair, doctorZellijRepairConsoleLine } from '../core/doctor/doctor-zellij-repair.js';
|
|
27
27
|
import { buildCodexAppHarnessMatrix } from '../core/codex-app/codex-app-harness-matrix.js';
|
|
28
|
+
import { buildCodexNativeFeatureMatrix } from '../core/codex-native/codex-native-feature-broker.js';
|
|
28
29
|
export async function run(_command, args = []) {
|
|
29
30
|
const doctorFix = flag(args, '--fix');
|
|
30
31
|
let setupRepair = null;
|
|
@@ -206,6 +207,22 @@ export async function run(_command, args = []) {
|
|
|
206
207
|
blockers: [err?.message || String(err)],
|
|
207
208
|
warnings: []
|
|
208
209
|
}));
|
|
210
|
+
const codexNativeFeatureMatrix = await buildCodexNativeFeatureMatrix({ root, applyRepairs: doctorFix }).catch((err) => ({
|
|
211
|
+
schema: 'sks.codex-native-feature-matrix.v1',
|
|
212
|
+
ok: false,
|
|
213
|
+
codex_cli: { available: Boolean(codex.bin), version: codex.version || null, bin: codex.bin || null },
|
|
214
|
+
features: {},
|
|
215
|
+
invocation_defaults: {
|
|
216
|
+
loop_worker_role_strategy: 'message-role',
|
|
217
|
+
qa_visual_review_strategy: 'blocked',
|
|
218
|
+
research_source_strategy: 'local-files',
|
|
219
|
+
image_followup_strategy: 'blocked',
|
|
220
|
+
hook_evidence_policy: 'unknown-do-not-count',
|
|
221
|
+
skill_bridge_strategy: 'cli-only'
|
|
222
|
+
},
|
|
223
|
+
blockers: [err?.message || String(err)],
|
|
224
|
+
warnings: []
|
|
225
|
+
}));
|
|
209
226
|
const pkgBytes = await dirSize(root).catch(() => 0);
|
|
210
227
|
const ready = await writeDoctorReadinessMatrix(root, {
|
|
211
228
|
codex,
|
|
@@ -232,6 +249,7 @@ export async function run(_command, args = []) {
|
|
|
232
249
|
]
|
|
233
250
|
});
|
|
234
251
|
const zellijReadiness = buildZellijReadiness(root, zellij, ready);
|
|
252
|
+
const runtimeReadiness = buildRuntimeReadiness(zellijReadiness, codexNativeFeatureMatrix);
|
|
235
253
|
const result = {
|
|
236
254
|
schema: 'sks.doctor-status.v1',
|
|
237
255
|
ok: ready.ready && (!sksUpdate || sksUpdate.ok !== false),
|
|
@@ -265,6 +283,8 @@ export async function run(_command, args = []) {
|
|
|
265
283
|
mcp_plugin_inventory: mcpPluginInventory?.candidates || null
|
|
266
284
|
},
|
|
267
285
|
codex_app_harness_matrix: codexAppHarnessMatrix,
|
|
286
|
+
codex_native_feature_matrix: codexNativeFeatureMatrix,
|
|
287
|
+
runtime_readiness: runtimeReadiness,
|
|
268
288
|
ready,
|
|
269
289
|
sneakoscope: { ok: await exists(`${root}/.sneakoscope`) },
|
|
270
290
|
package: { bytes: pkgBytes, human: formatBytes(pkgBytes) },
|
|
@@ -298,6 +318,14 @@ export async function run(_command, args = []) {
|
|
|
298
318
|
console.log(` codex doctor: ${codexDoctor.available ? (codexDoctor.exit_code === 0 ? 'ok' : 'warning') : 'unavailable'}`);
|
|
299
319
|
console.log(`Rust acc.: ${rust.mode || (rust.available ? 'rust_accelerated' : 'js_fallback')} ${rust.version || rust.status || ''}`);
|
|
300
320
|
console.log(`Codex App: ${ready.codex_app_ready ? 'ok' : 'optional_missing'}`);
|
|
321
|
+
console.log('SKS Runtime Readiness:');
|
|
322
|
+
console.log(` Zellij: ${runtimeReadiness.zellij}`);
|
|
323
|
+
console.log(` Codex Native: ${runtimeReadiness.codex_native}`);
|
|
324
|
+
console.log(` Loop Mesh: ${runtimeReadiness.loop_mesh}`);
|
|
325
|
+
console.log(` QA Visual: ${runtimeReadiness.qa_visual}`);
|
|
326
|
+
console.log(` Research Sources: ${runtimeReadiness.research_sources}`);
|
|
327
|
+
for (const action of runtimeReadiness.repair_actions)
|
|
328
|
+
console.log(` Repair: ${action}`);
|
|
301
329
|
console.log('Codex App Harness:');
|
|
302
330
|
console.log(` plugins: ${codexAppHarnessMatrix.app_features?.plugin_json ? 'ok' : 'degraded'}`);
|
|
303
331
|
console.log(` hook approval: ${codexAppHarnessMatrix.app_features?.hook_approval_state_detectable ? 'ok' : 'unknown'}`);
|
|
@@ -385,6 +413,42 @@ export async function run(_command, args = []) {
|
|
|
385
413
|
if (!result.ok)
|
|
386
414
|
process.exitCode = 1;
|
|
387
415
|
}
|
|
416
|
+
function buildRuntimeReadiness(zellijReadiness, matrix) {
|
|
417
|
+
const defaults = matrix?.invocation_defaults || {};
|
|
418
|
+
const hookPolicy = defaults.hook_evidence_policy || 'unknown-do-not-count';
|
|
419
|
+
const agentStrategy = defaults.loop_worker_role_strategy || 'message-role';
|
|
420
|
+
const zellijStatus = zellijReadiness?.status === 'ok'
|
|
421
|
+
? 'ok'
|
|
422
|
+
: zellijReadiness?.cli_ready ? 'headless_available' : 'repair_required';
|
|
423
|
+
const codexNative = matrix?.ok === true
|
|
424
|
+
? 'ok'
|
|
425
|
+
: matrix?.codex_cli?.available ? 'degraded' : 'blocked';
|
|
426
|
+
const repairActions = [];
|
|
427
|
+
if (zellijStatus === 'repair_required')
|
|
428
|
+
repairActions.push('sks doctor --fix --yes');
|
|
429
|
+
if (codexNative !== 'ok')
|
|
430
|
+
repairActions.push('sks doctor --fix --repair-codex-native --yes');
|
|
431
|
+
if (matrix?.features?.project_memory?.ok !== true)
|
|
432
|
+
repairActions.push('sks codex-native init-deep --apply --directory-local');
|
|
433
|
+
if (hookPolicy !== 'approved-only')
|
|
434
|
+
repairActions.push('hook-derived evidence will not count until Codex hook approval is approved');
|
|
435
|
+
return {
|
|
436
|
+
schema: 'sks.runtime-readiness-story.v1',
|
|
437
|
+
zellij: zellijStatus,
|
|
438
|
+
codex_native: codexNative,
|
|
439
|
+
loop_mesh: agentStrategy === 'agent_type' ? 'ok' : 'fallback',
|
|
440
|
+
qa_visual: defaults.qa_visual_review_strategy || 'blocked',
|
|
441
|
+
research_sources: defaults.research_source_strategy || 'local-files',
|
|
442
|
+
hook_evidence_policy: hookPolicy,
|
|
443
|
+
agent_role_strategy: agentStrategy,
|
|
444
|
+
notes: [
|
|
445
|
+
...(zellijStatus === 'headless_available' ? ['MAD can run with --headless; live panes require repair'] : []),
|
|
446
|
+
...(hookPolicy !== 'approved-only' ? ['hook-derived evidence will not count'] : []),
|
|
447
|
+
...(agentStrategy !== 'agent_type' ? ['message-role fallback active'] : [])
|
|
448
|
+
],
|
|
449
|
+
repair_actions: repairActions
|
|
450
|
+
};
|
|
451
|
+
}
|
|
388
452
|
// Assemble the explicit Zellij readiness block for `doctor --json` from the
|
|
389
453
|
// capability probe + readiness matrix. Proof statuses are availability-derived:
|
|
390
454
|
// `verified` is reserved for a real environment run (SKS_REQUIRE_ZELLIJ=1 gates);
|