sneakoscope 6.0.1 → 6.0.2
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 +2 -1
- package/crates/sks-core/Cargo.lock +1 -1
- package/crates/sks-core/Cargo.toml +1 -1
- package/dist/bin/fast-inline.js +0 -60
- package/dist/bin/sks-dispatch.js +0 -24
- package/dist/cli/codex-app-command.js +1 -2
- package/dist/cli/help-fast.js +2 -2
- package/dist/cli/install-helpers.js +25 -31
- package/dist/config/skills-manifest.json +57 -57
- package/dist/core/agents/agent-effort-policy.js +19 -38
- package/dist/core/agents/agent-orchestrator.js +2 -2
- package/dist/core/agents/agent-role-config.js +17 -10
- package/dist/core/agents/agent-roster.js +19 -39
- package/dist/core/agents/agent-scheduler.js +6 -5
- package/dist/core/agents/agent-schema.js +4 -5
- package/dist/core/agents/agent-task-graph.js +1 -1
- package/dist/core/agents/agent-work-partition.js +2 -1
- package/dist/core/agents/native-worker-backend-router.js +1 -1
- package/dist/core/agents/route-collaboration-ledger.js +2 -2
- package/dist/core/auto-review.js +1 -4
- package/dist/core/codex/codex-config-guard.js +9 -13
- package/dist/core/codex-adapter.js +2 -2
- package/dist/core/codex-app/codex-agent-role-sync.js +0 -1
- package/dist/core/codex-app/codex-app-fast-ui-repair.js +6 -40
- package/dist/core/codex-app/codex-app-ui-state-snapshot.js +1 -7
- package/dist/core/codex-control/codex-model-capabilities.js +1 -2
- package/dist/core/codex-control/codex-model-metadata.js +13 -6
- package/dist/core/codex-control/codex-sdk-config-policy.js +3 -3
- package/dist/core/codex-control/codex-task-runner.js +2 -3
- package/dist/core/codex-model-guard.js +24 -87
- package/dist/core/commands/basic-cli.js +6 -0
- package/dist/core/commands/loop-command.js +2 -2
- package/dist/core/commands/naruto-command.js +11 -11
- package/dist/core/commands/profile-command.js +14 -5
- package/dist/core/commands/qa-loop-command.js +2 -2
- package/dist/core/commands/research-command.js +2 -2
- package/dist/core/doctor/doctor-codex-startup-repair.js +0 -3
- package/dist/core/evaluation.js +1 -1
- package/dist/core/feature-fixtures.js +2 -2
- package/dist/core/feature-registry.js +1 -1
- package/dist/core/hooks-runtime.js +7 -45
- package/dist/core/image-ux-review/imagegen-adapter.js +17 -2
- package/dist/core/init/skills.js +6 -7
- package/dist/core/init.js +6 -20
- package/dist/core/loops/loop-concurrency-budget.js +6 -4
- package/dist/core/loops/loop-planner.js +1 -1
- package/dist/core/loops/loop-runtime.js +2 -2
- package/dist/core/loops/loop-scheduler.js +7 -7
- package/dist/core/managed-assets/managed-assets-manifest.js +1 -4
- package/dist/core/naruto/naruto-concurrency-governor.js +20 -17
- package/dist/core/naruto/naruto-loop-mesh.js +3 -3
- package/dist/core/naruto/resource-pressure-monitor.js +5 -2
- package/dist/core/provider/model-router.js +15 -35
- package/dist/core/release/release-gate-batch-runner.js +2 -1
- package/dist/core/release/release-gate-resource-governor.js +12 -12
- package/dist/core/release/resource-class-budget.js +5 -5
- package/dist/core/routes/constants.js +3 -4
- package/dist/core/routes.js +1 -1
- package/dist/core/structured-output-adapter.js +15 -1
- package/dist/core/update/update-migration-state.js +3 -32
- package/dist/core/version.js +1 -1
- package/dist/scripts/agent-backfill-replenishment-check.js +1 -1
- package/dist/scripts/agent-dynamic-pool-check.js +3 -3
- package/dist/scripts/agent-dynamic-pool-fixture.js +1 -1
- package/dist/scripts/agent-goal-mode-propagation-check.js +1 -1
- package/dist/scripts/agent-patch-swarm-gate-lib.js +2 -2
- package/dist/scripts/agent-role-config-repair-check.js +9 -5
- package/dist/scripts/agent-scheduler-proof-check.js +1 -1
- package/dist/scripts/agent-scheduler-proof-hardening-check.js +1 -1
- package/dist/scripts/agent-source-intelligence-propagation-check.js +1 -1
- package/dist/scripts/agent-strategy-to-lease-wiring-check.js +2 -2
- package/dist/scripts/agent-zellij-dynamic-backfill-panes-check.js +1 -1
- package/dist/scripts/codex-app-fast-ui-preservation-check.js +2 -2
- package/dist/scripts/codex-app-ui-preservation-check.js +6 -5
- package/dist/scripts/codex-lb-fast-ui-preservation-check.js +3 -3
- package/dist/scripts/codex-lb-gpt55-fast-profile-check.js +2 -3
- package/dist/scripts/doctor-fixes-codex-app-fast-ui-check.js +7 -7
- package/dist/scripts/install-update-preserves-config-check.js +4 -4
- package/dist/scripts/loop-hardening-check-lib.js +1 -1
- package/dist/scripts/naruto-parallelism-mode-check.js +2 -1
- package/dist/scripts/naruto-shadow-clone-swarm-check.js +25 -34
- package/dist/scripts/npm-publish-performance-check.js +1 -1
- package/dist/scripts/release-aggressive-resource-governor-check.js +2 -2
- package/dist/scripts/release-parallel-check.js +1 -2
- package/dist/scripts/release-real-check.js +1 -1
- package/dist/scripts/sizecheck.js +3 -3
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -25,7 +25,7 @@ sneakoscope is a proof-first Codex trust layer for bounded agent workflows, sear
|
|
|
25
25
|
|
|
26
26
|
Sneakoscope Codex (`sks`) is a Codex CLI and Codex App harness for people who want parallel AI coding without losing proof. It gives Codex a simple front door, a dynamic worker swarm, a local dashboard, TriWiki project memory, and release gates that separate machine evidence from LLM opinion.
|
|
27
27
|
|
|
28
|
-
Current release: SKS **6.0.
|
|
28
|
+
Current release: SKS **6.0.2**. This release lets Codex own the complete model catalog—including current and future GPT-5.6 options—without SKS allowlists or silent model replacement. It also bounds agent, loop, and release concurrency to keep Codex Desktop responsive, preserves explicit user model/provider choices during repair and updates, and adds a clean-build verification path for `npm publish --ignore-scripts`. See [CHANGELOG.md](CHANGELOG.md).
|
|
29
29
|
|
|
30
30
|
## Install
|
|
31
31
|
|
|
@@ -96,6 +96,7 @@ It shows the v5 flow: one-line install, `$Plan`, `$Work`/`$Swarm`, `sks review`,
|
|
|
96
96
|
- Native capability repair: `sks doctor --fix` (imagegen/Computer Use/Browser Use), `.sneakoscope/reports/native-capability-readiness.json`
|
|
97
97
|
- Agent bridge for any agent system: `sks mcp-server`, `sks agent-bridge setup`, `SKS_AGENT_MODE=1` — see [docs/AGENT-BRIDGE.md](docs/AGENT-BRIDGE.md)
|
|
98
98
|
- Release gates: `node ./dist/scripts/release-gate-dag-runner.js --preset release --full`
|
|
99
|
+
- Lifecycle-disabled npm release: run `npm run publish:verify-ignore-scripts` first, then `npm publish --ignore-scripts`; the raw publish command intentionally cannot run build or validation hooks.
|
|
99
100
|
- Release readiness notes: [docs/release-readiness.md](docs/release-readiness.md) and [CHANGELOG.md](CHANGELOG.md)
|
|
100
101
|
- Image generation review routes require Codex App `$imagegen`/`gpt-image-2` evidence with recorded output hashes; direct API fallback and mock fixtures do not satisfy full route gates.
|
|
101
102
|
|
package/dist/bin/fast-inline.js
CHANGED
|
@@ -151,63 +151,3 @@ exports.rootJsonFastInline = rootJsonFastInline;
|
|
|
151
151
|
exports.doctorJsonFastInline = doctorJsonFastInline;
|
|
152
152
|
exports.narutoHelpJsonFastInline = narutoHelpJsonFastInline;
|
|
153
153
|
exports.hookUserPromptSubmitPerfInline = hookUserPromptSubmitPerfInline;
|
|
154
|
-
|
|
155
|
-
exports.rootJsonFastInline = rootJsonFastInline;
|
|
156
|
-
exports.doctorJsonFastInline = doctorJsonFastInline;
|
|
157
|
-
exports.narutoHelpJsonFastInline = narutoHelpJsonFastInline;
|
|
158
|
-
exports.hookUserPromptSubmitPerfInline = hookUserPromptSubmitPerfInline;
|
|
159
|
-
|
|
160
|
-
exports.rootJsonFastInline = rootJsonFastInline;
|
|
161
|
-
exports.doctorJsonFastInline = doctorJsonFastInline;
|
|
162
|
-
exports.narutoHelpJsonFastInline = narutoHelpJsonFastInline;
|
|
163
|
-
exports.hookUserPromptSubmitPerfInline = hookUserPromptSubmitPerfInline;
|
|
164
|
-
|
|
165
|
-
exports.rootJsonFastInline = rootJsonFastInline;
|
|
166
|
-
exports.doctorJsonFastInline = doctorJsonFastInline;
|
|
167
|
-
exports.narutoHelpJsonFastInline = narutoHelpJsonFastInline;
|
|
168
|
-
exports.hookUserPromptSubmitPerfInline = hookUserPromptSubmitPerfInline;
|
|
169
|
-
|
|
170
|
-
exports.rootJsonFastInline = rootJsonFastInline;
|
|
171
|
-
exports.doctorJsonFastInline = doctorJsonFastInline;
|
|
172
|
-
exports.narutoHelpJsonFastInline = narutoHelpJsonFastInline;
|
|
173
|
-
exports.hookUserPromptSubmitPerfInline = hookUserPromptSubmitPerfInline;
|
|
174
|
-
|
|
175
|
-
exports.rootJsonFastInline = rootJsonFastInline;
|
|
176
|
-
exports.doctorJsonFastInline = doctorJsonFastInline;
|
|
177
|
-
exports.narutoHelpJsonFastInline = narutoHelpJsonFastInline;
|
|
178
|
-
exports.hookUserPromptSubmitPerfInline = hookUserPromptSubmitPerfInline;
|
|
179
|
-
|
|
180
|
-
exports.rootJsonFastInline = rootJsonFastInline;
|
|
181
|
-
exports.doctorJsonFastInline = doctorJsonFastInline;
|
|
182
|
-
exports.narutoHelpJsonFastInline = narutoHelpJsonFastInline;
|
|
183
|
-
exports.hookUserPromptSubmitPerfInline = hookUserPromptSubmitPerfInline;
|
|
184
|
-
|
|
185
|
-
exports.rootJsonFastInline = rootJsonFastInline;
|
|
186
|
-
exports.doctorJsonFastInline = doctorJsonFastInline;
|
|
187
|
-
exports.narutoHelpJsonFastInline = narutoHelpJsonFastInline;
|
|
188
|
-
exports.hookUserPromptSubmitPerfInline = hookUserPromptSubmitPerfInline;
|
|
189
|
-
|
|
190
|
-
exports.rootJsonFastInline = rootJsonFastInline;
|
|
191
|
-
exports.doctorJsonFastInline = doctorJsonFastInline;
|
|
192
|
-
exports.narutoHelpJsonFastInline = narutoHelpJsonFastInline;
|
|
193
|
-
exports.hookUserPromptSubmitPerfInline = hookUserPromptSubmitPerfInline;
|
|
194
|
-
|
|
195
|
-
exports.rootJsonFastInline = rootJsonFastInline;
|
|
196
|
-
exports.doctorJsonFastInline = doctorJsonFastInline;
|
|
197
|
-
exports.narutoHelpJsonFastInline = narutoHelpJsonFastInline;
|
|
198
|
-
exports.hookUserPromptSubmitPerfInline = hookUserPromptSubmitPerfInline;
|
|
199
|
-
|
|
200
|
-
exports.rootJsonFastInline = rootJsonFastInline;
|
|
201
|
-
exports.doctorJsonFastInline = doctorJsonFastInline;
|
|
202
|
-
exports.narutoHelpJsonFastInline = narutoHelpJsonFastInline;
|
|
203
|
-
exports.hookUserPromptSubmitPerfInline = hookUserPromptSubmitPerfInline;
|
|
204
|
-
|
|
205
|
-
exports.rootJsonFastInline = rootJsonFastInline;
|
|
206
|
-
exports.doctorJsonFastInline = doctorJsonFastInline;
|
|
207
|
-
exports.narutoHelpJsonFastInline = narutoHelpJsonFastInline;
|
|
208
|
-
exports.hookUserPromptSubmitPerfInline = hookUserPromptSubmitPerfInline;
|
|
209
|
-
|
|
210
|
-
exports.rootJsonFastInline = rootJsonFastInline;
|
|
211
|
-
exports.doctorJsonFastInline = doctorJsonFastInline;
|
|
212
|
-
exports.narutoHelpJsonFastInline = narutoHelpJsonFastInline;
|
|
213
|
-
exports.hookUserPromptSubmitPerfInline = hookUserPromptSubmitPerfInline;
|
package/dist/bin/sks-dispatch.js
CHANGED
|
@@ -60,27 +60,3 @@ async function runSks(args) {
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
exports.runSks = runSks;
|
|
63
|
-
|
|
64
|
-
exports.runSks = runSks;
|
|
65
|
-
|
|
66
|
-
exports.runSks = runSks;
|
|
67
|
-
|
|
68
|
-
exports.runSks = runSks;
|
|
69
|
-
|
|
70
|
-
exports.runSks = runSks;
|
|
71
|
-
|
|
72
|
-
exports.runSks = runSks;
|
|
73
|
-
|
|
74
|
-
exports.runSks = runSks;
|
|
75
|
-
|
|
76
|
-
exports.runSks = runSks;
|
|
77
|
-
|
|
78
|
-
exports.runSks = runSks;
|
|
79
|
-
|
|
80
|
-
exports.runSks = runSks;
|
|
81
|
-
|
|
82
|
-
exports.runSks = runSks;
|
|
83
|
-
|
|
84
|
-
exports.runSks = runSks;
|
|
85
|
-
|
|
86
|
-
exports.runSks = runSks;
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { spawn } from 'node:child_process';
|
|
2
2
|
import { codexRemoteControlStatus, formatCodexRemoteControlStatus } from '../core/codex-app.js';
|
|
3
|
-
import { forceRequiredCodexModelConfigArgs } from '../core/codex-model-guard.js';
|
|
4
3
|
export async function codexAppRemoteControlCommand(args = [], opts = {}) {
|
|
5
4
|
const controlArgs = argsBeforeSeparator(args);
|
|
6
5
|
if (controlArgs.includes('--help') || controlArgs.includes('-h')) {
|
|
@@ -25,7 +24,7 @@ export async function codexAppRemoteControlCommand(args = [], opts = {}) {
|
|
|
25
24
|
process.exitCode = 1;
|
|
26
25
|
return;
|
|
27
26
|
}
|
|
28
|
-
const passthrough =
|
|
27
|
+
const passthrough = stripSeparator(args).map((arg) => String(arg));
|
|
29
28
|
const spawnFn = opts.spawn || spawn;
|
|
30
29
|
const code = await spawnInherited(spawnFn, status.codex_cli.bin, ['remote-control', ...passthrough], {
|
|
31
30
|
cwd: process.cwd(),
|
package/dist/cli/help-fast.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { COMMAND_MANIFEST_LITE } from './command-manifest-lite.js';
|
|
2
|
-
|
|
2
|
+
import { PACKAGE_VERSION } from '../core/version.js';
|
|
3
3
|
export function helpFast() {
|
|
4
4
|
console.log(`SKS
|
|
5
|
-
SNEAKOSCOPE CODEX v${
|
|
5
|
+
SNEAKOSCOPE CODEX v${PACKAGE_VERSION}
|
|
6
6
|
|
|
7
7
|
3-pillar frontdoor
|
|
8
8
|
|
|
@@ -23,7 +23,6 @@ import { extractTomlTable, writeCodexConfigGuarded } from '../core/codex/codex-c
|
|
|
23
23
|
import { cleanupCodexConfigBackups, validateCodexConfigRoundTrip } from '../core/codex/codex-config-toml.js';
|
|
24
24
|
import { runPostinstallGlobalDoctorAndMarkPending } from '../core/update/update-migration-state.js';
|
|
25
25
|
import { repairCodexImagegen } from '../core/doctor/imagegen-repair.js';
|
|
26
|
-
import { GPT55_CODEX_MODEL, GPT56_CODEX_MODELS, REQUIRED_CODEX_MODEL } from '../core/codex-model-guard.js';
|
|
27
26
|
const CODEX_LB_PROVIDER_NAME = 'openai';
|
|
28
27
|
const CODEX_LB_PROVIDER_ENV_KEY = 'CODEX_LB_API_KEY';
|
|
29
28
|
const CODEX_LB_CANONICAL_FAST_SERVICE_TIER = 'priority';
|
|
@@ -276,7 +275,7 @@ async function postinstallHarnessConflictNotice(conflictScan) {
|
|
|
276
275
|
console.log(formatHarnessConflictReport(conflictScan, { includePrompt: false }));
|
|
277
276
|
console.log('\nWhat this means: npm can finish installing the package, but `sks setup` and `sks doctor --fix` will refuse to activate SKS until the conflicting harness is removed with human approval.');
|
|
278
277
|
console.log('No files were removed by postinstall.');
|
|
279
|
-
console.log(
|
|
278
|
+
console.log('Cleanup requires a human-approved Codex App session. Keep the model selected in Codex and use high reasoning effort.');
|
|
280
279
|
if (shouldAskPostinstallQuestion()) {
|
|
281
280
|
const answer = await askPostinstallQuestion('Show the cleanup prompt now? [y/N] ');
|
|
282
281
|
if (/^(y|yes|예|네|응)$/i.test(answer.trim())) {
|
|
@@ -902,7 +901,9 @@ export async function checkCodexLbResponseChain(status = {}, opts = {}) {
|
|
|
902
901
|
const fetchImpl = opts.fetch || globalThis.fetch;
|
|
903
902
|
if (typeof fetchImpl !== 'function')
|
|
904
903
|
return { ok: true, status: 'skipped', skipped: true, reason: 'fetch unavailable' };
|
|
905
|
-
const model = opts.model || env.SKS_CODEX_MODEL ||
|
|
904
|
+
const model = String(opts.model || env.SKS_CODEX_MODEL || env.CODEX_MODEL || '').trim();
|
|
905
|
+
if (!model)
|
|
906
|
+
return { ok: true, status: 'skipped', skipped: true, reason: 'model_unselected_use_explicit_model_or_codex_catalog' };
|
|
906
907
|
const timeoutMs = Number(opts.timeoutMs || env.SKS_CODEX_LB_CHAIN_CHECK_TIMEOUT_MS || 8000);
|
|
907
908
|
const serviceTier = opts.fastMode === true || opts.serviceTier === 'fast' || opts.serviceTier === CODEX_LB_CANONICAL_FAST_SERVICE_TIER
|
|
908
909
|
? CODEX_LB_CANONICAL_FAST_SERVICE_TIER
|
|
@@ -1894,10 +1895,9 @@ function normalizeCodexFastModeUiConfigOnce(text = '', opts = {}) {
|
|
|
1894
1895
|
// `default_profile`, `[profiles.<name>]` tables, `[user.fast_mode]`, and
|
|
1895
1896
|
// `notice.fast_default_opt_out`. The only documented fast-default mechanism is
|
|
1896
1897
|
// the plain top-level `service_tier = "fast"`. This pass strips every legacy
|
|
1897
|
-
//
|
|
1898
|
+
// schema stamps SKS wrote and keeps user-authored top-level choices intact.
|
|
1898
1899
|
let next = String(text || '');
|
|
1899
1900
|
next = removeLegacyTopLevelCodexModeLocks(next);
|
|
1900
|
-
next = normalizeCodexAppDefaultModel(next);
|
|
1901
1901
|
next = removeTopLevelTomlKeyIfValue(next, 'default_profile', 'sks-fast-high');
|
|
1902
1902
|
next = removeTomlTable(next, 'user.fast_mode');
|
|
1903
1903
|
next = removeTomlTable(next, 'profiles.sks-fast-high');
|
|
@@ -1926,6 +1926,10 @@ function normalizeCodexFastModeUiConfigOnce(text = '', opts = {}) {
|
|
|
1926
1926
|
for (const featureLine of ['hooks = true', 'multi_agent = true', 'fast_mode = true', 'apps = true']) {
|
|
1927
1927
|
next = upsertTomlTableKeyIfAbsent(next, 'features', featureLine);
|
|
1928
1928
|
}
|
|
1929
|
+
if (process.env.SKS_ALLOW_HIGH_AGENT_CONCURRENCY !== '1') {
|
|
1930
|
+
next = upsertTomlTableKey(next, 'agents', 'max_threads = 4');
|
|
1931
|
+
}
|
|
1932
|
+
next = removeTomlTable(next, 'features.multi_agent_v2');
|
|
1929
1933
|
// Plugin auto-enable is OPT-IN only. Force-writing `[plugins."name@marketplace"] enabled =
|
|
1930
1934
|
// true` for marketplace plugins the App may not have installed (different build/channel)
|
|
1931
1935
|
// makes the App reference plugins it cannot load -> broken/blocked plugin UI. It also
|
|
@@ -1967,28 +1971,18 @@ function removeLegacyTopLevelCodexModeLocks(text = '') {
|
|
|
1967
1971
|
const lines = String(text || '').split('\n');
|
|
1968
1972
|
const firstTable = lines.findIndex((x) => /^\s*\[.+\]\s*$/.test(x));
|
|
1969
1973
|
const end = firstTable === -1 ? lines.length : firstTable;
|
|
1970
|
-
const topLevelModel = topLevelTomlString(text, 'model');
|
|
1971
|
-
const removeSksOwnedModeLock = isLegacySksCodexModelStamp(topLevelModel);
|
|
1972
1974
|
return lines.filter((line, index) => {
|
|
1973
1975
|
if (index >= end)
|
|
1974
1976
|
return true;
|
|
1975
|
-
if (
|
|
1977
|
+
if (!/^\s*(?:model|model_reasoning_effort)\s*=/.test(line))
|
|
1976
1978
|
return true;
|
|
1977
|
-
return
|
|
1979
|
+
return ![line, lines[index - 1] || ''].some((candidate) => {
|
|
1980
|
+
const trimmed = String(candidate || '').trim();
|
|
1981
|
+
const comment = trimmed.startsWith('#') ? trimmed : trimmed.includes('#') ? trimmed.slice(trimmed.indexOf('#')) : '';
|
|
1982
|
+
return /(?:SKS|Sneakoscope|codex-lb|sks fast)/i.test(comment);
|
|
1983
|
+
});
|
|
1978
1984
|
}).join('\n').replace(/^\n+/, '').replace(/\n{3,}/g, '\n\n');
|
|
1979
1985
|
}
|
|
1980
|
-
function normalizeCodexAppDefaultModel(text = '') {
|
|
1981
|
-
const currentModel = topLevelTomlString(text, 'model');
|
|
1982
|
-
if (!currentModel)
|
|
1983
|
-
return upsertTopLevelTomlString(text, 'model', REQUIRED_CODEX_MODEL);
|
|
1984
|
-
if (isLegacySksCodexModelStamp(currentModel))
|
|
1985
|
-
return upsertTopLevelTomlString(text, 'model', REQUIRED_CODEX_MODEL);
|
|
1986
|
-
return String(text || '');
|
|
1987
|
-
}
|
|
1988
|
-
function isLegacySksCodexModelStamp(value = '') {
|
|
1989
|
-
const model = String(value || '').trim().toLowerCase();
|
|
1990
|
-
return model === REQUIRED_CODEX_MODEL || model === GPT55_CODEX_MODEL || GPT56_CODEX_MODELS.includes(model);
|
|
1991
|
-
}
|
|
1992
1986
|
function removeTopLevelTomlKeyIfValue(text = '', key = '', value = '') {
|
|
1993
1987
|
const lines = String(text || '').split('\n');
|
|
1994
1988
|
const firstTable = lines.findIndex((x) => /^\s*\[.+\]\s*$/.test(x));
|
|
@@ -2877,8 +2871,8 @@ export async function selftestCodexLb(tmp) {
|
|
|
2877
2871
|
// escape that dash emits literally and bash collapses to `"`).
|
|
2878
2872
|
await writeTextAtomic(codexLbFakeCodex, "#!/bin/sh\nif [ \"$1\" = \"--version\" ]; then echo \"codex-cli 99.0.0\"; exit 0; fi\nif [ \"$1\" = \"login\" ] && [ \"$2\" = \"status\" ]; then echo \"logged in with browser auth\"; exit 0; fi\nif [ \"$1\" = \"login\" ] && [ \"$2\" = \"--with-api-key\" ]; then read key; mkdir -p \"$HOME/.codex\"; printf '{\"auth_mode\":\"apikey\",\"OPENAI_API_KEY\":\"%s\"}\\n' \"$key\" > \"$HOME/.codex/auth.json\"; printf '%s\\n' \"$key\" >> \"$HOME/.codex/login-calls.log\"; exit 0; fi\necho \"fake codex unsupported\" >&2\nexit 1\n");
|
|
2879
2873
|
await fsp.chmod(codexLbFakeCodex, 0o755);
|
|
2880
|
-
await writeTextAtomic(path.join(codexLbHome, '.codex', 'config.toml'), `
|
|
2881
|
-
const codexLbEnvForSelftest = { HOME: codexLbHome, SKS_GLOBAL_ROOT: path.join(tmp, 'codex-lb-global'), PATH: `${codexLbFakeBin}${path.delimiter}${process.env.PATH || ''}`, SKS_SKIP_CODEX_LB_LAUNCH_ENV: '1' };
|
|
2874
|
+
await writeTextAtomic(path.join(codexLbHome, '.codex', 'config.toml'), `model_reasoning_effort = "low"\nservice_tier = "fast"\nsuppress_unstable_features_warning = true\n\n[profiles.custom]\nmodel_reasoning_effort = "low"\n\n[notice]\nfast_default_opt_out = true\n\n[features]\nhooks = true\n`);
|
|
2875
|
+
const codexLbEnvForSelftest = { HOME: codexLbHome, SKS_GLOBAL_ROOT: path.join(tmp, 'codex-lb-global'), PATH: `${codexLbFakeBin}${path.delimiter}${process.env.PATH || ''}`, SKS_SKIP_CODEX_LB_LAUNCH_ENV: '1', SKS_CODEX_MODEL: 'selftest-codex-model' };
|
|
2882
2876
|
const codexLbSetup = await runProcess(process.execPath, [packagedSksEntrypoint(), 'codex-lb', 'setup', '--host', 'lb.example.test', '--api-key', 'sk-test', '--json'], {
|
|
2883
2877
|
cwd: tmp,
|
|
2884
2878
|
env: codexLbEnvForSelftest,
|
|
@@ -2982,7 +2976,7 @@ export async function selftestCodexLb(tmp) {
|
|
|
2982
2976
|
await postinstall({
|
|
2983
2977
|
bootstrap: async () => {
|
|
2984
2978
|
await writeTextAtomic(path.join(codexLbHome, '.codex', 'auth.json'), '{"auth_mode":"browser"}\n');
|
|
2985
|
-
await writeTextAtomic(path.join(codexLbHome, '.codex', 'config.toml'), `
|
|
2979
|
+
await writeTextAtomic(path.join(codexLbHome, '.codex', 'config.toml'), `service_tier = "fast"\nsuppress_unstable_features_warning = true\n\n[features]\nhooks = true\n`);
|
|
2986
2980
|
}
|
|
2987
2981
|
});
|
|
2988
2982
|
}
|
|
@@ -3008,7 +3002,7 @@ export async function selftestCodexLb(tmp) {
|
|
|
3008
3002
|
await writeTextAtomic(path.join(doctorProject, 'package.json'), '{"name":"codex-lb-doctor-project","version":"0.0.0"}\n');
|
|
3009
3003
|
await writeTextAtomic(path.join(codexLbHome, '.codex', 'sks-codex-lb.env'), "export CODEX_LB_BASE_URL='https://lb.example.test/backend-api/codex'\nexport CODEX_LB_API_KEY='sk-test'\n");
|
|
3010
3004
|
await writeTextAtomic(path.join(codexLbHome, '.codex', 'auth.json'), '{"auth_mode":"browser"}\n');
|
|
3011
|
-
await writeTextAtomic(path.join(codexLbHome, '.codex', 'config.toml'), `
|
|
3005
|
+
await writeTextAtomic(path.join(codexLbHome, '.codex', 'config.toml'), `service_tier = "fast"\nsuppress_unstable_features_warning = true\n\n[features]\nhooks = true\n`);
|
|
3012
3006
|
const codexLbDoctorRepair = await runProcess(process.execPath, [packagedSksEntrypoint(), 'doctor', '--fix', '--json'], {
|
|
3013
3007
|
cwd: doctorProject,
|
|
3014
3008
|
env: { ...codexLbEnvForSelftest, SKS_GLOBAL_ROOT: path.join(tmp, 'codex-lb-doctor-global') },
|
|
@@ -3201,7 +3195,7 @@ export async function selftestCodexLb(tmp) {
|
|
|
3201
3195
|
if (!codexLbLegacyDoctorJson.repair?.codex_lb?.ok || !codexLbLegacyDoctorJson.repair.codex_lb.legacy_auth_migrated || !codexLbLegacyDoctorEnv.includes("CODEX_LB_API_KEY='sk-legacy-doctor'") || !codexLbLegacyDoctorAuth.includes('"auth_mode":"apikey"') || !codexLbLegacyDoctorAuth.includes('sk-legacy-doctor') || !hasTopLevelCodexLbSelected(codexLbLegacyDoctorConfig) || !codexLbLegacyDoctorConfig.includes('env_key = "CODEX_LB_API_KEY"'))
|
|
3202
3196
|
throw new Error('selftest: legacy doctor codex-lb restore');
|
|
3203
3197
|
await writeTextAtomic(path.join(codexLbHome, '.codex', 'sks-codex-lb.env'), "export CODEX_LB_BASE_URL='https://lb.example.test/backend-api/codex'\n");
|
|
3204
|
-
await writeTextAtomic(path.join(codexLbHome, '.codex', 'config.toml'),
|
|
3198
|
+
await writeTextAtomic(path.join(codexLbHome, '.codex', 'config.toml'), 'service_tier = "fast"\n');
|
|
3205
3199
|
await writeTextAtomic(path.join(codexLbHome, '.codex', 'auth.json'), '{"auth_mode":"apikey","key":"sk-env-only"}\n');
|
|
3206
3200
|
const codexLbLoginCallsBeforeEnvOnlyPostinstall = await codexLbLoginCallCount(codexLbHome);
|
|
3207
3201
|
const codexLbEnvOnlyPostinstall = await runProcess(process.execPath, [packagedSksEntrypoint(), 'postinstall'], {
|
|
@@ -3219,7 +3213,7 @@ export async function selftestCodexLb(tmp) {
|
|
|
3219
3213
|
if (!String(codexLbEnvOnlyPostinstall.stdout || '').includes('codex-lb auth: restored from existing Codex login cache') || !codexLbEnvOnlyPostinstallEnv.includes("CODEX_LB_API_KEY='sk-env-only'") || !codexLbEnvOnlyPostinstallConfig.includes('env_key = "CODEX_LB_API_KEY"') || !hasTopLevelCodexLbSelected(codexLbEnvOnlyPostinstallConfig) || !codexLbEnvOnlyPostinstallAuth.includes('sk-env-only') || codexLbLoginCallsAfterEnvOnlyPostinstall !== codexLbLoginCallsBeforeEnvOnlyPostinstall)
|
|
3220
3214
|
throw new Error('selftest: env-only codex-lb postinstall restore');
|
|
3221
3215
|
await writeTextAtomic(path.join(codexLbHome, '.codex', 'sks-codex-lb.env'), "export CODEX_LB_BASE_URL='https://lb.example.test/backend-api/codex'\n");
|
|
3222
|
-
await writeTextAtomic(path.join(codexLbHome, '.codex', 'config.toml'),
|
|
3216
|
+
await writeTextAtomic(path.join(codexLbHome, '.codex', 'config.toml'), 'service_tier = "fast"\n');
|
|
3223
3217
|
await writeTextAtomic(path.join(codexLbHome, '.codex', 'auth.json'), '{"auth_mode":"apikey","key":"sk-env-only-doctor"}\n');
|
|
3224
3218
|
const codexLbEnvOnlyDoctorProject = tmpdir();
|
|
3225
3219
|
await ensureDir(path.join(codexLbEnvOnlyDoctorProject, '.git'));
|
|
@@ -3349,7 +3343,7 @@ export async function selftestCodexLb(tmp) {
|
|
|
3349
3343
|
}
|
|
3350
3344
|
if (autobypassLaunch.status !== 'chain_unhealthy' || autobypassLaunch.bypass_codex_lb !== true || autobypassLaunch.chain_health?.status !== 'second_request_failed')
|
|
3351
3345
|
throw new Error('selftest: SKS_CODEX_LB_AUTOBYPASS=1 should bypass codex-lb on hard chain failure');
|
|
3352
|
-
await writeTextAtomic(path.join(codexLbHome, '.codex', 'config.toml'),
|
|
3346
|
+
await writeTextAtomic(path.join(codexLbHome, '.codex', 'config.toml'), 'service_tier = "fast"\n');
|
|
3353
3347
|
await writeTextAtomic(path.join(codexLbHome, '.codex', 'sks-codex-lb.env'), "export CODEX_LB_BASE_URL='https://lb.example.test/backend-api/codex'\nexport CODEX_LB_API_KEY='sk-test'\n");
|
|
3354
3348
|
const missingProviderLaunchCalls = [];
|
|
3355
3349
|
const missingProviderLaunch = await maybePromptCodexLbSetupForLaunch([], {
|
|
@@ -3416,11 +3410,11 @@ export async function selftestCodexLb(tmp) {
|
|
|
3416
3410
|
throw new Error(`selftest: codex-lb setup did not enforce the renewed feature-flag contract (documented flags present, legacy stamps stripped, user profile tables preserved)${survivingLegacy.length ? ` — surviving legacy stamps: ${survivingLegacy.join(', ')}` : ''}`);
|
|
3417
3411
|
if (!hasCodexUnstableFeatureWarningSuppression(codexLbConfig))
|
|
3418
3412
|
throw new Error('selftest: codex-lb setup did not suppress Codex unstable feature warning');
|
|
3419
|
-
const codexLbLaunch = `source ${path.join(tmp, '.codex', 'sks-codex-lb.env')} && codex
|
|
3413
|
+
const codexLbLaunch = `source ${path.join(tmp, '.codex', 'sks-codex-lb.env')} && codex`;
|
|
3420
3414
|
if (!codexLbLaunch.includes('sks-codex-lb.env'))
|
|
3421
3415
|
throw new Error('selftest: Zellij launch command does not source codex-lb env file');
|
|
3422
|
-
if (
|
|
3423
|
-
throw new Error(
|
|
3416
|
+
if (codexLbLaunch.includes('--model'))
|
|
3417
|
+
throw new Error('selftest: Zellij launch command without an explicit model must inherit the Codex selection');
|
|
3424
3418
|
const madLaunchSource = await safeReadText(path.join(packageRoot(), 'src', 'core', 'commands', 'mad-sks-command.js'));
|
|
3425
3419
|
if (!madLaunchSource.includes('const lb = await deps.maybePromptCodexLbSetupForLaunch(args)') || !madLaunchSource.includes("const launchLb = lb.status === 'present'") || !madLaunchSource.includes('codexLbImmediateLaunchOpts(cleanArgs, launchLb') || !madLaunchSource.includes('bypass_codex_lb') || !madLaunchSource.includes('model_provider="openai"') || !madLaunchSource.includes('codexLbFreshSession: true'))
|
|
3426
3420
|
throw new Error('selftest: MAD launch does not sync codex-lb auth and fresh-session launch options');
|