sneakoscope 4.7.1 → 4.7.4
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 +11 -11
- 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/bin/sks.js +1 -1
- package/dist/cli/command-registry.js +1 -1
- package/dist/cli/install-helpers.js +215 -57
- package/dist/commands/codex-lb.js +143 -7
- package/dist/commands/doctor.js +59 -2
- package/dist/core/codex-app/codex-app-fast-ui-repair.js +11 -1
- package/dist/core/codex-app/codex-app-restart.js +65 -0
- package/dist/core/codex-app/sks-menubar.js +445 -0
- package/dist/core/codex-app.js +239 -3
- package/dist/core/codex-control/codex-sdk-config-policy.js +2 -2
- package/dist/core/codex-control/codex-task-runner.js +2 -2
- package/dist/core/codex-lb/codex-lb-setup.js +1 -1
- package/dist/core/commands/basic-cli.js +14 -7
- package/dist/core/doctor/doctor-dirty-planner.js +2 -0
- package/dist/core/doctor/doctor-readiness-matrix.js +4 -0
- package/dist/core/fsx.js +1 -1
- package/dist/core/imagegen/imagegen-capability.js +2 -2
- package/dist/core/init.js +1 -1
- package/dist/core/managed-assets/managed-assets-manifest.js +1 -1
- package/dist/core/provider/provider-context.js +1 -1
- package/dist/core/routes.js +2 -2
- package/dist/core/update-check.js +67 -18
- package/dist/core/version.js +1 -1
- package/dist/scripts/codex-app-provider-model-ui-check.js +114 -0
- package/dist/scripts/codex-lb-fast-mode-truth-check.js +90 -0
- package/dist/scripts/codex-lb-setup-truthfulness-check.js +6 -1
- package/dist/scripts/doctor-fixes-codex-app-fast-ui-check.js +5 -1
- package/dist/scripts/gpt-image-2-real-file-smoke.js +2 -2
- package/dist/scripts/provider-context-config-toml-check.js +2 -2
- package/dist/scripts/sks-menubar-install-check.js +59 -0
- package/dist/scripts/update-default-command-check.js +28 -0
- package/package.json +5 -1
|
@@ -4,6 +4,7 @@ import { PACKAGE_VERSION, packageRoot, readJson, runProcess, which } from './fsx
|
|
|
4
4
|
import { createRequestedScopeContract } from './safety/requested-scope-contract.js';
|
|
5
5
|
import { guardedPackageInstall, guardContextForRoute } from './safety/mutation-guard.js';
|
|
6
6
|
import { isUpdateMigrationReceiptCurrent, resolveInstalledSksEntrypoint, runPackageLocalDoctor, writeProjectUpdateMigrationReceipt } from './update/update-migration-state.js';
|
|
7
|
+
import { installSksMenuBar } from './codex-app/sks-menubar.js';
|
|
7
8
|
const DEFAULT_REGISTRY = 'https://registry.npmjs.org/';
|
|
8
9
|
export async function runSksUpdateCheck(options = {}) {
|
|
9
10
|
const packageName = options.packageName || 'sneakoscope';
|
|
@@ -164,6 +165,9 @@ export async function runSksUpdateNow(options = {}) {
|
|
|
164
165
|
}).catch(() => null);
|
|
165
166
|
const migrationCurrent = isUpdateMigrationReceiptCurrent(receipt);
|
|
166
167
|
stage('project_receipt', migrationCurrent, migrationCurrent ? 'current' : 'failed', { root: projectReceiptRoot });
|
|
168
|
+
const sksMenuBar = migrationCurrent
|
|
169
|
+
? await installUpdateSksMenuBar({ root: projectReceiptRoot, env, stage })
|
|
170
|
+
: null;
|
|
167
171
|
return buildUpdateNowResult({
|
|
168
172
|
packageName,
|
|
169
173
|
from: check.current,
|
|
@@ -185,19 +189,14 @@ export async function runSksUpdateNow(options = {}) {
|
|
|
185
189
|
newVersionDoctor: null,
|
|
186
190
|
projectReceipt: receipt,
|
|
187
191
|
migrationCurrent,
|
|
192
|
+
sksMenuBar,
|
|
188
193
|
stages,
|
|
189
194
|
error: null
|
|
190
195
|
});
|
|
191
196
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
env,
|
|
196
|
-
timeoutMs: 15_000,
|
|
197
|
-
maxOutputBytes: 32 * 1024
|
|
198
|
-
});
|
|
199
|
-
stage('old_version_doctor_preflight', oldVersionDoctor.ok, oldVersionDoctor.status, { entrypoint: oldVersionDoctor.entrypoint, exit_code: oldVersionDoctor.exit_code });
|
|
200
|
-
if (!oldVersionDoctor.ok && env.SKS_UPDATE_SKIP_OLD_DOCTOR_PREFLIGHT !== '1') {
|
|
197
|
+
if (options.dryRun) {
|
|
198
|
+
stage('old_version_doctor_preflight', true, 'skipped_dry_run', { reason: 'dry_run_does_not_run_doctor_fix' });
|
|
199
|
+
stage('npm_install', true, 'dry_run', { command });
|
|
201
200
|
return buildUpdateNowResult({
|
|
202
201
|
packageName,
|
|
203
202
|
from: check.current,
|
|
@@ -210,21 +209,32 @@ export async function runSksUpdateNow(options = {}) {
|
|
|
210
209
|
cwd,
|
|
211
210
|
registry,
|
|
212
211
|
globalRoot,
|
|
213
|
-
status: '
|
|
214
|
-
ok:
|
|
212
|
+
status: 'dry_run',
|
|
213
|
+
ok: true,
|
|
215
214
|
installCode: null,
|
|
216
|
-
oldVersionDoctor,
|
|
215
|
+
oldVersionDoctor: null,
|
|
217
216
|
newBinary: null,
|
|
218
217
|
newVersion: null,
|
|
219
218
|
newVersionDoctor: null,
|
|
220
219
|
projectReceipt: null,
|
|
221
220
|
migrationCurrent: false,
|
|
222
221
|
stages,
|
|
223
|
-
error:
|
|
222
|
+
error: null
|
|
224
223
|
});
|
|
225
224
|
}
|
|
226
|
-
|
|
227
|
-
|
|
225
|
+
const oldDoctorTimeoutOverride = Number.parseInt(env.SKS_UPDATE_OLD_DOCTOR_TIMEOUT_MS || '', 10);
|
|
226
|
+
const oldDoctorTimeoutMs = Number.isFinite(oldDoctorTimeoutOverride) && oldDoctorTimeoutOverride > 0
|
|
227
|
+
? oldDoctorTimeoutOverride
|
|
228
|
+
: 60_000;
|
|
229
|
+
const oldVersionDoctor = await runPackageLocalDoctor({
|
|
230
|
+
root: projectReceiptRoot,
|
|
231
|
+
args: ['doctor', '--fix', '--yes', '--profile', 'migration', '--machine-only', '--report-file', path.join(projectReceiptRoot, '.sneakoscope', 'update', `old-version-doctor-${Date.now()}.json`)],
|
|
232
|
+
env,
|
|
233
|
+
timeoutMs: oldDoctorTimeoutMs,
|
|
234
|
+
maxOutputBytes: 32 * 1024
|
|
235
|
+
});
|
|
236
|
+
stage('old_version_doctor_preflight', oldVersionDoctor.ok, oldVersionDoctor.status, { entrypoint: oldVersionDoctor.entrypoint, exit_code: oldVersionDoctor.exit_code, timeout_ms: oldDoctorTimeoutMs });
|
|
237
|
+
if (!oldVersionDoctor.ok && env.SKS_UPDATE_SKIP_OLD_DOCTOR_PREFLIGHT !== '1') {
|
|
228
238
|
return buildUpdateNowResult({
|
|
229
239
|
packageName,
|
|
230
240
|
from: check.current,
|
|
@@ -237,8 +247,8 @@ export async function runSksUpdateNow(options = {}) {
|
|
|
237
247
|
cwd,
|
|
238
248
|
registry,
|
|
239
249
|
globalRoot,
|
|
240
|
-
status: '
|
|
241
|
-
ok:
|
|
250
|
+
status: 'failed',
|
|
251
|
+
ok: false,
|
|
242
252
|
installCode: null,
|
|
243
253
|
oldVersionDoctor,
|
|
244
254
|
newBinary: null,
|
|
@@ -247,7 +257,7 @@ export async function runSksUpdateNow(options = {}) {
|
|
|
247
257
|
projectReceipt: null,
|
|
248
258
|
migrationCurrent: false,
|
|
249
259
|
stages,
|
|
250
|
-
error:
|
|
260
|
+
error: oldVersionDoctor.error || 'old-version Doctor preflight failed'
|
|
251
261
|
});
|
|
252
262
|
}
|
|
253
263
|
const mutationLedgerRoot = env.SKS_MUTATION_LEDGER_ROOT || packageRoot();
|
|
@@ -277,6 +287,7 @@ export async function runSksUpdateNow(options = {}) {
|
|
|
277
287
|
let newVersionDoctor = null;
|
|
278
288
|
let projectReceipt = null;
|
|
279
289
|
let migrationCurrent = false;
|
|
290
|
+
let sksMenuBar = null;
|
|
280
291
|
if (installOk) {
|
|
281
292
|
newBinary = await resolveInstalledSksEntrypoint({ packageName, globalRoot, env });
|
|
282
293
|
stage('resolve_new_package_local_binary', Boolean(newBinary), newBinary ? 'resolved' : 'missing', { new_binary: newBinary });
|
|
@@ -310,6 +321,8 @@ export async function runSksUpdateNow(options = {}) {
|
|
|
310
321
|
}).catch(() => null);
|
|
311
322
|
migrationCurrent = isUpdateMigrationReceiptCurrent(projectReceipt);
|
|
312
323
|
stage('project_receipt', migrationCurrent, migrationCurrent ? 'current' : 'failed', { root: projectReceiptRoot });
|
|
324
|
+
if (migrationCurrent)
|
|
325
|
+
sksMenuBar = await installUpdateSksMenuBar({ root: projectReceiptRoot, env, stage });
|
|
313
326
|
}
|
|
314
327
|
}
|
|
315
328
|
const ok = installOk && Boolean(newBinary) && newVersionDoctor?.ok === true && migrationCurrent;
|
|
@@ -334,6 +347,7 @@ export async function runSksUpdateNow(options = {}) {
|
|
|
334
347
|
newVersionDoctor,
|
|
335
348
|
projectReceipt,
|
|
336
349
|
migrationCurrent,
|
|
350
|
+
sksMenuBar,
|
|
337
351
|
stages,
|
|
338
352
|
error: ok ? null : updateNowError(install, newBinary, newVersionDoctor, migrationCurrent)
|
|
339
353
|
});
|
|
@@ -500,10 +514,45 @@ function buildUpdateNowResult(input) {
|
|
|
500
514
|
new_version_doctor: input.newVersionDoctor,
|
|
501
515
|
project_receipt: input.projectReceipt,
|
|
502
516
|
migration_current: input.migrationCurrent,
|
|
517
|
+
sks_menubar: input.sksMenuBar || null,
|
|
503
518
|
stages: input.stages,
|
|
504
519
|
error: input.error
|
|
505
520
|
};
|
|
506
521
|
}
|
|
522
|
+
async function installUpdateSksMenuBar(input) {
|
|
523
|
+
if (input.env.SKS_UPDATE_SKIP_SKS_MENUBAR === '1') {
|
|
524
|
+
input.stage('sks_menubar', true, 'skipped', { reason: 'SKS_UPDATE_SKIP_SKS_MENUBAR=1' });
|
|
525
|
+
return null;
|
|
526
|
+
}
|
|
527
|
+
const result = await installSksMenuBar({
|
|
528
|
+
root: input.root,
|
|
529
|
+
apply: true,
|
|
530
|
+
launch: true,
|
|
531
|
+
env: input.env
|
|
532
|
+
}).catch((err) => ({
|
|
533
|
+
schema: 'sks.codex-app-sks-menubar.v1',
|
|
534
|
+
ok: false,
|
|
535
|
+
apply: true,
|
|
536
|
+
status: 'blocked',
|
|
537
|
+
platform: process.platform,
|
|
538
|
+
app_path: null,
|
|
539
|
+
executable_path: null,
|
|
540
|
+
launch_agent_path: null,
|
|
541
|
+
action_script_path: null,
|
|
542
|
+
report_path: path.join(input.root, '.sneakoscope', 'reports', 'sks-menubar.json'),
|
|
543
|
+
menu_items: [],
|
|
544
|
+
actions: [],
|
|
545
|
+
launch: { requested: true, method: 'none', ok: false, error: err?.message || String(err) },
|
|
546
|
+
blockers: [err?.message || String(err)],
|
|
547
|
+
warnings: []
|
|
548
|
+
}));
|
|
549
|
+
input.stage('sks_menubar', result.ok !== false, result.status, {
|
|
550
|
+
app_path: result.app_path,
|
|
551
|
+
launch_agent_path: result.launch_agent_path,
|
|
552
|
+
launch: result.launch
|
|
553
|
+
});
|
|
554
|
+
return result;
|
|
555
|
+
}
|
|
507
556
|
async function detectNpmGlobalRoot(npmBin, env, opts = {}) {
|
|
508
557
|
const result = await runProcess(npmBin, ['root', '--global', '--silent'], {
|
|
509
558
|
env,
|
package/dist/core/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const PACKAGE_VERSION = '4.7.
|
|
1
|
+
export const PACKAGE_VERSION = '4.7.4';
|
|
2
2
|
//# sourceMappingURL=version.js.map
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { codexProviderModelUiStatus, formatCodexAppStatus } from '../core/codex-app.js';
|
|
6
|
+
import { GLM_CODEX_CONFIG_PROVIDER_ID, GLM_CODEX_CONFIG_REASONING_PROFILES } from '../core/codex-app/glm-model-profile.js';
|
|
7
|
+
import { GLM_52_OPENROUTER_MODEL } from '../core/providers/glm/glm-52-settings.js';
|
|
8
|
+
const tmp = await fs.mkdtemp(path.join(os.tmpdir(), 'sks-codex-app-provider-ui-'));
|
|
9
|
+
const home = path.join(tmp, 'home');
|
|
10
|
+
const cwd = path.join(tmp, 'project');
|
|
11
|
+
await fs.mkdir(path.join(home, '.codex'), { recursive: true });
|
|
12
|
+
await fs.mkdir(path.join(cwd, '.codex'), { recursive: true });
|
|
13
|
+
const missing = await codexProviderModelUiStatus({ home, cwd, env: { HOME: home } });
|
|
14
|
+
const missingText = formatCodexAppStatus(statusFixture(missing));
|
|
15
|
+
await fs.writeFile(path.join(home, '.codex', 'config.toml'), readyConfig(), 'utf8');
|
|
16
|
+
await fs.writeFile(path.join(home, '.codex', 'sks-codex-lb.env'), "export CODEX_LB_BASE_URL='https://lb.example.test/backend-api/codex'\nexport CODEX_LB_API_KEY='sk-codex-lb-fixture'\n", 'utf8');
|
|
17
|
+
const ready = await codexProviderModelUiStatus({
|
|
18
|
+
home,
|
|
19
|
+
cwd,
|
|
20
|
+
env: { HOME: home, OPENROUTER_API_KEY: 'sk-or-fixture' }
|
|
21
|
+
});
|
|
22
|
+
const readyText = formatCodexAppStatus(statusFixture(ready));
|
|
23
|
+
const ok = missing.ok === false
|
|
24
|
+
&& missing.glm.exposed === false
|
|
25
|
+
&& missing.codex_lb.key_entry_visible === true
|
|
26
|
+
&& missing.ui_actions.includes('sks codex-app set-openrouter-key --api-key-stdin')
|
|
27
|
+
&& missing.ui_actions.includes('sks codex-lb setup --host <domain> --api-key-stdin --yes')
|
|
28
|
+
&& /Provider UI:\s*setup/.test(missingText)
|
|
29
|
+
&& /GLM Model:\s*setup/.test(missingText)
|
|
30
|
+
&& /codex-lb Key:\s*missing \(input: sks codex-lb setup/.test(missingText)
|
|
31
|
+
&& ready.ok === true
|
|
32
|
+
&& ready.glm.exposed === true
|
|
33
|
+
&& ready.glm.model === GLM_52_OPENROUTER_MODEL
|
|
34
|
+
&& ready.glm.profiles_present.length === GLM_CODEX_CONFIG_REASONING_PROFILES.length
|
|
35
|
+
&& ready.codex_lb.provider_present === true
|
|
36
|
+
&& ready.codex_lb.key_present === true
|
|
37
|
+
&& /Provider UI:\s*ok/.test(readyText)
|
|
38
|
+
&& readyText.includes(`GLM Model: ok ${GLM_52_OPENROUTER_MODEL}`)
|
|
39
|
+
&& /codex-lb Key:\s*configured/.test(readyText)
|
|
40
|
+
&& !JSON.stringify({ missing, ready, missingText, readyText }).includes('sk-codex-lb-fixture');
|
|
41
|
+
emit({
|
|
42
|
+
schema: 'sks.codex-app-provider-model-ui-check.v1',
|
|
43
|
+
ok,
|
|
44
|
+
missing,
|
|
45
|
+
ready,
|
|
46
|
+
secret_safe: !JSON.stringify({ missing, ready, missingText, readyText }).includes('sk-codex-lb-fixture'),
|
|
47
|
+
blockers: ok ? [] : ['codex_app_provider_model_ui_check_failed']
|
|
48
|
+
});
|
|
49
|
+
function readyConfig() {
|
|
50
|
+
return [
|
|
51
|
+
`[model_providers.${GLM_CODEX_CONFIG_PROVIDER_ID}]`,
|
|
52
|
+
'name = "OpenRouter"',
|
|
53
|
+
'base_url = "https://openrouter.ai/api/v1"',
|
|
54
|
+
'wire_api = "responses"',
|
|
55
|
+
'env_key = "OPENROUTER_API_KEY"',
|
|
56
|
+
'requires_openai_auth = false',
|
|
57
|
+
'',
|
|
58
|
+
...GLM_CODEX_CONFIG_REASONING_PROFILES.flatMap((profile) => [
|
|
59
|
+
`[profiles.${profile.id}]`,
|
|
60
|
+
`model_provider = "${GLM_CODEX_CONFIG_PROVIDER_ID}"`,
|
|
61
|
+
`model = "${GLM_52_OPENROUTER_MODEL}"`,
|
|
62
|
+
`model_reasoning_effort = "${profile.reasoning_effort}"`,
|
|
63
|
+
'service_tier = "default"',
|
|
64
|
+
'approval_policy = "on-request"',
|
|
65
|
+
''
|
|
66
|
+
]),
|
|
67
|
+
'[model_providers.codex-lb]',
|
|
68
|
+
'name = "openai"',
|
|
69
|
+
'base_url = "https://lb.example.test/backend-api/codex"',
|
|
70
|
+
'wire_api = "responses"',
|
|
71
|
+
'env_key = "CODEX_LB_API_KEY"',
|
|
72
|
+
'supports_websockets = true',
|
|
73
|
+
'requires_openai_auth = true',
|
|
74
|
+
''
|
|
75
|
+
].join('\n');
|
|
76
|
+
}
|
|
77
|
+
function statusFixture(providerModelUi) {
|
|
78
|
+
return {
|
|
79
|
+
ok: providerModelUi.ok,
|
|
80
|
+
app: { installed: true, path: '/Applications/Codex.app' },
|
|
81
|
+
codex_cli: { ok: true, version: '0.142.0' },
|
|
82
|
+
remote_control: { ok: true, min_version: '0.130.0', codex_cli: { version_number: '0.142.0' } },
|
|
83
|
+
features: {
|
|
84
|
+
checked: true,
|
|
85
|
+
required_flags_ok: true,
|
|
86
|
+
required_flags: {},
|
|
87
|
+
fast_mode_config: { ok: true, blockers: [] },
|
|
88
|
+
provider_model_ui: providerModelUi,
|
|
89
|
+
git_actions: { ok: true, blockers: [] },
|
|
90
|
+
browser_tool_ready: true,
|
|
91
|
+
browser_tool_source: 'fixture',
|
|
92
|
+
image_generation: true
|
|
93
|
+
},
|
|
94
|
+
plugins: {
|
|
95
|
+
default_plugins: { ok: true },
|
|
96
|
+
design_product: { ok: true, id: 'product-design' },
|
|
97
|
+
picker: { ok: true }
|
|
98
|
+
},
|
|
99
|
+
chrome_extension: { ok: true, blockers: [] },
|
|
100
|
+
mcp: {
|
|
101
|
+
has_computer_use: true,
|
|
102
|
+
computer_use_source: 'mcp_list',
|
|
103
|
+
has_browser_use: true,
|
|
104
|
+
browser_use_source: 'mcp_list'
|
|
105
|
+
},
|
|
106
|
+
guidance: []
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function emit(report) {
|
|
110
|
+
console.log(JSON.stringify(report, null, 2));
|
|
111
|
+
if (!report.ok)
|
|
112
|
+
process.exitCode = 1;
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=codex-app-provider-model-ui-check.js.map
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { run } from '../commands/codex-lb.js';
|
|
6
|
+
const calls = [];
|
|
7
|
+
const home = await fs.mkdtemp(path.join(os.tmpdir(), 'sks-codex-lb-fast-truth-'));
|
|
8
|
+
await fs.mkdir(path.join(home, '.codex'), { recursive: true });
|
|
9
|
+
await fs.writeFile(path.join(home, '.codex', 'config.toml'), [
|
|
10
|
+
'model_provider = "codex-lb"',
|
|
11
|
+
'service_tier = "fast"',
|
|
12
|
+
'',
|
|
13
|
+
'[model_providers.codex-lb]',
|
|
14
|
+
'name = "openai"',
|
|
15
|
+
'base_url = "https://lb.example.test/backend-api/codex"',
|
|
16
|
+
'wire_api = "responses"',
|
|
17
|
+
'env_key = "CODEX_LB_API_KEY"',
|
|
18
|
+
'supports_websockets = true',
|
|
19
|
+
'requires_openai_auth = true',
|
|
20
|
+
''
|
|
21
|
+
].join('\n'));
|
|
22
|
+
await fs.writeFile(path.join(home, '.codex', 'auth.json'), `${JSON.stringify({ auth_mode: 'apikey', OPENAI_API_KEY: 'sk-fixture' })}\n`);
|
|
23
|
+
await fs.writeFile(path.join(home, '.codex', 'sks-codex-lb.env'), "export CODEX_LB_BASE_URL='https://lb.example.test/backend-api/codex'\nexport CODEX_LB_API_KEY='sk-fixture'\n");
|
|
24
|
+
const chain = await runFastCheck({
|
|
25
|
+
HOME: home,
|
|
26
|
+
CODEX_LB_API_KEY: 'sk-fixture',
|
|
27
|
+
CODEX_LB_BASE_URL: 'https://lb.example.test/backend-api/codex'
|
|
28
|
+
});
|
|
29
|
+
const requestedOnly = await runFastCheck({
|
|
30
|
+
HOME: home,
|
|
31
|
+
CODEX_LB_API_KEY: 'sk-fixture',
|
|
32
|
+
CODEX_LB_BASE_URL: 'https://lb.example.test/backend-api/codex',
|
|
33
|
+
SKS_TEST_FAST_ACTUAL_DEFAULT: '1'
|
|
34
|
+
});
|
|
35
|
+
const ok = chain.ok === true
|
|
36
|
+
&& chain.status === 'fast_verified'
|
|
37
|
+
&& calls[0]?.body?.service_tier === 'priority'
|
|
38
|
+
&& requestedOnly.ok === false
|
|
39
|
+
&& requestedOnly.status === 'fast_requested_but_actual_unverified'
|
|
40
|
+
&& requestedOnly.blockers.includes('codex_lb_actual_fast_service_tier_unverified');
|
|
41
|
+
console.log(JSON.stringify({
|
|
42
|
+
schema: 'sks.codex-lb-fast-mode-truth-check.v1',
|
|
43
|
+
ok,
|
|
44
|
+
priority_request_sent: calls[0]?.body?.service_tier === 'priority',
|
|
45
|
+
verified_case: chain,
|
|
46
|
+
requested_only_case: requestedOnly,
|
|
47
|
+
blockers: ok ? [] : ['codex_lb_fast_mode_truth_check_failed']
|
|
48
|
+
}, null, 2));
|
|
49
|
+
if (!ok)
|
|
50
|
+
process.exitCode = 1;
|
|
51
|
+
async function runFastCheck(env) {
|
|
52
|
+
const originalFetch = globalThis.fetch;
|
|
53
|
+
const originalEnv = { ...process.env };
|
|
54
|
+
const outputs = [];
|
|
55
|
+
const originalWrite = process.stdout.write.bind(process.stdout);
|
|
56
|
+
const originalExitCode = process.exitCode;
|
|
57
|
+
try {
|
|
58
|
+
Object.assign(process.env, env);
|
|
59
|
+
process.exitCode = 0;
|
|
60
|
+
globalThis.fetch = async (_url, init) => {
|
|
61
|
+
const body = JSON.parse(String(init.body || '{}'));
|
|
62
|
+
calls.push({ body });
|
|
63
|
+
const id = calls.length % 2 === 1 ? 'resp_fast_1' : 'resp_fast_2';
|
|
64
|
+
const actual = env.SKS_TEST_FAST_ACTUAL_DEFAULT === '1' ? 'default' : 'priority';
|
|
65
|
+
return new Response(JSON.stringify({
|
|
66
|
+
id,
|
|
67
|
+
requestedServiceTier: 'priority',
|
|
68
|
+
actualServiceTier: actual,
|
|
69
|
+
serviceTier: actual
|
|
70
|
+
}), { status: 200, headers: { 'content-type': 'application/json' } });
|
|
71
|
+
};
|
|
72
|
+
process.stdout.write = (chunk) => {
|
|
73
|
+
outputs.push(String(chunk));
|
|
74
|
+
return true;
|
|
75
|
+
};
|
|
76
|
+
await run(null, ['fast-check', '--json']);
|
|
77
|
+
return JSON.parse(outputs.join('') || '{}');
|
|
78
|
+
}
|
|
79
|
+
finally {
|
|
80
|
+
globalThis.fetch = originalFetch;
|
|
81
|
+
process.stdout.write = originalWrite;
|
|
82
|
+
process.exitCode = originalExitCode;
|
|
83
|
+
for (const key of Object.keys(process.env)) {
|
|
84
|
+
if (!(key in originalEnv))
|
|
85
|
+
delete process.env[key];
|
|
86
|
+
}
|
|
87
|
+
Object.assign(process.env, originalEnv);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=codex-lb-fast-mode-truth-check.js.map
|
|
@@ -46,9 +46,14 @@ async function runSetup(name, args, input = 'sk-clb-test\n') {
|
|
|
46
46
|
}
|
|
47
47
|
{
|
|
48
48
|
const row = await runSetup('no-env', ['--no-env-file']);
|
|
49
|
+
const actions = row.json.applied_actions?.map((action) => action.type) || [];
|
|
49
50
|
results.push({
|
|
50
51
|
name: 'no_env_file',
|
|
51
|
-
ok: row.code === 0
|
|
52
|
+
ok: row.code === 0
|
|
53
|
+
&& row.json.status === 'process_env'
|
|
54
|
+
&& row.json.persistence?.applied_modes?.includes('process_only_ephemeral')
|
|
55
|
+
&& !actions.includes('write_env_file')
|
|
56
|
+
&& !(await exists(row.envPath))
|
|
52
57
|
});
|
|
53
58
|
}
|
|
54
59
|
{
|
|
@@ -8,7 +8,7 @@ const codexHome = path.join(root, 'home', '.codex');
|
|
|
8
8
|
await fs.mkdir(path.join(root, '.codex'), { recursive: true });
|
|
9
9
|
await fs.mkdir(codexHome, { recursive: true });
|
|
10
10
|
await fs.writeFile(path.join(root, '.codex', 'config.toml'), 'model = "gpt-5.5"\nmodel_reasoning_effort = "medium"\nmodel_provider = "codex-lb"\n');
|
|
11
|
-
await fs.writeFile(path.join(codexHome, 'config.toml'), '# SKS forced fast UI during legacy install\nmodel = "z-ai/glm-5.2"\nmodel_reasoning_effort = "xhigh"\nmodel_provider = "codex-lb"\nservice_tier = "fast"\n[features]\nfast_mode = false # user disabled, must remain untouched\n\n[profiles.sks-fast-high]\nmodel = "gpt-5.5"\nservice_tier = "fast"\n\n[model_providers.codex-lb]\nname = "
|
|
11
|
+
await fs.writeFile(path.join(codexHome, 'config.toml'), '# SKS forced fast UI during legacy install\nmodel = "z-ai/glm-5.2"\nmodel_reasoning_effort = "xhigh"\nmodel_provider = "codex-lb"\nservice_tier = "fast"\n[features]\nfast_mode = false # user disabled, must remain untouched\n\n[profiles.sks-fast-high]\nmodel = "gpt-5.5"\nservice_tier = "fast"\n\n[model_providers.codex-lb]\nname = "openai"\nbase_url = "https://lb.example.test/backend-api/codex"\nwire_api = "responses"\nenv_key = "CODEX_LB_API_KEY"\nsupports_websockets = true\nrequires_openai_auth = true\n');
|
|
12
12
|
const plan = await repairCodexAppFastUi(root, { codexHome, apply: false });
|
|
13
13
|
const repaired = await repairCodexAppFastUi(root, { codexHome, apply: true });
|
|
14
14
|
const projectAfter = await fs.readFile(path.join(root, '.codex', 'config.toml'), 'utf8');
|
|
@@ -22,8 +22,12 @@ await fs.mkdir(unsafeCodexHome, { recursive: true });
|
|
|
22
22
|
await fs.writeFile(path.join(unsafeCodexHome, 'config.toml'), 'service_tier = "standard"\n');
|
|
23
23
|
const unsafePlan = await repairCodexAppFastUi(unsafeRoot, { codexHome: unsafeCodexHome, apply: false });
|
|
24
24
|
const ok = plan.fast_selector === 'manual_action_required'
|
|
25
|
+
&& plan.provider_selector === 'manual_action_required'
|
|
26
|
+
&& plan.provider_actions.includes('sks codex-app set-openrouter-key --api-key-stdin')
|
|
27
|
+
&& plan.provider_actions.includes('sks codex-lb setup --host <domain> --api-key-stdin --yes')
|
|
25
28
|
&& plan.safe_auto_apply === true
|
|
26
29
|
&& repaired.fast_selector === 'repaired'
|
|
30
|
+
&& repaired.provider_selector === 'manual_action_required'
|
|
27
31
|
&& repaired.safe_auto_apply === true
|
|
28
32
|
&& backups.length >= 2
|
|
29
33
|
&& !/^model\s*=/m.test(projectAfter.split(/\n\s*\[/)[0] || '')
|
|
@@ -92,7 +92,7 @@ function authState() {
|
|
|
92
92
|
};
|
|
93
93
|
}
|
|
94
94
|
const codexLb = readCodexLbAuth();
|
|
95
|
-
if (codexLb.selected && codexLb.provider_configured && codexLb.requires_openai_auth ===
|
|
95
|
+
if (codexLb.selected && codexLb.provider_configured && codexLb.requires_openai_auth === true && codexLb.key && codexLb.base_url) {
|
|
96
96
|
return {
|
|
97
97
|
ok: true,
|
|
98
98
|
provider: 'openai_responses_image_generation',
|
|
@@ -102,7 +102,7 @@ function authState() {
|
|
|
102
102
|
codex_lb: {
|
|
103
103
|
selected: true,
|
|
104
104
|
provider_configured: true,
|
|
105
|
-
requires_openai_auth:
|
|
105
|
+
requires_openai_auth: true,
|
|
106
106
|
base_url: codexLb.base_url,
|
|
107
107
|
env_key: codexLb.env_key,
|
|
108
108
|
env_path: codexLb.env_path,
|
|
@@ -10,11 +10,11 @@ const codexLbConfig = [
|
|
|
10
10
|
'model_provider = "codex-lb"',
|
|
11
11
|
'',
|
|
12
12
|
'[model_providers.codex-lb]',
|
|
13
|
-
'name = "
|
|
13
|
+
'name = "openai"',
|
|
14
14
|
'base_url = "https://lb.example.test"',
|
|
15
15
|
'wire_api = "responses"',
|
|
16
16
|
'env_key = "CODEX_LB_API_KEY"',
|
|
17
|
-
'requires_openai_auth =
|
|
17
|
+
'requires_openai_auth = true',
|
|
18
18
|
''
|
|
19
19
|
].join('\n');
|
|
20
20
|
await fs.writeFile(path.join(codexHome, 'config.toml'), codexLbConfig);
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import fs from 'node:fs/promises';
|
|
2
|
+
import os from 'node:os';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { installSksMenuBar } from '../core/codex-app/sks-menubar.js';
|
|
5
|
+
const temp = await fs.mkdtemp(path.join(os.tmpdir(), 'sks-menubar-check-'));
|
|
6
|
+
const result = await installSksMenuBar({
|
|
7
|
+
apply: true,
|
|
8
|
+
launch: false,
|
|
9
|
+
home: temp,
|
|
10
|
+
root: temp,
|
|
11
|
+
sksEntry: path.join(process.cwd(), 'dist', 'bin', 'sks.js')
|
|
12
|
+
});
|
|
13
|
+
const executableExists = result.executable_path ? await exists(result.executable_path) : false;
|
|
14
|
+
const launchAgentExists = result.launch_agent_path ? await exists(result.launch_agent_path) : false;
|
|
15
|
+
const actionScriptExists = result.action_script_path ? await exists(result.action_script_path) : false;
|
|
16
|
+
const expectedMenuItems = [
|
|
17
|
+
'Use codex-lb',
|
|
18
|
+
'Use ChatGPT OAuth',
|
|
19
|
+
'Set OpenRouter Key and GLM Profiles',
|
|
20
|
+
'Fast Check',
|
|
21
|
+
'SKS Version Check',
|
|
22
|
+
'Update SKS Now'
|
|
23
|
+
];
|
|
24
|
+
const missingExpectedItems = expectedMenuItems.filter((item) => !result.menu_items.includes(item));
|
|
25
|
+
const hasExpectedItems = missingExpectedItems.length === 0;
|
|
26
|
+
const ok = process.platform === 'darwin'
|
|
27
|
+
? result.ok === true
|
|
28
|
+
&& result.status === 'installed_launch_skipped'
|
|
29
|
+
&& executableExists
|
|
30
|
+
&& launchAgentExists
|
|
31
|
+
&& actionScriptExists
|
|
32
|
+
&& hasExpectedItems
|
|
33
|
+
: result.ok === true && result.status === 'unsupported_platform';
|
|
34
|
+
const report = {
|
|
35
|
+
schema: 'sks.sks-menubar-install-check.v1',
|
|
36
|
+
ok,
|
|
37
|
+
temp,
|
|
38
|
+
result,
|
|
39
|
+
executable_exists: executableExists,
|
|
40
|
+
launch_agent_exists: launchAgentExists,
|
|
41
|
+
action_script_exists: actionScriptExists,
|
|
42
|
+
expected_menu_items: expectedMenuItems,
|
|
43
|
+
missing_expected_items: missingExpectedItems,
|
|
44
|
+
has_expected_items: hasExpectedItems,
|
|
45
|
+
blockers: ok ? [] : ['sks_menubar_install_check_failed']
|
|
46
|
+
};
|
|
47
|
+
console.log(JSON.stringify(report, null, 2));
|
|
48
|
+
if (!ok)
|
|
49
|
+
process.exit(1);
|
|
50
|
+
async function exists(file) {
|
|
51
|
+
try {
|
|
52
|
+
await fs.access(file);
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=sks-menubar-install-check.js.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
function assertGate(ok, message, detail) {
|
|
3
|
+
if (!ok) {
|
|
4
|
+
console.error(JSON.stringify({ schema: 'sks.update-default-command-check.v1', ok: false, message, detail }, null, 2));
|
|
5
|
+
process.exit(1);
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
const registry = fs.readFileSync('src/cli/command-registry.ts', 'utf8');
|
|
9
|
+
const basicCli = fs.readFileSync('src/core/commands/basic-cli.ts', 'utf8');
|
|
10
|
+
const update = fs.readFileSync('src/core/update-check.ts', 'utf8');
|
|
11
|
+
const routes = fs.readFileSync('src/core/routes.ts', 'utf8');
|
|
12
|
+
assertGate(registry.includes("subcommand(() => import(basicModule), 'updateCommand', 'dist/core/commands/basic-cli.js', 'now')"), 'bare sks update must default to update now');
|
|
13
|
+
assertGate(basicCli.includes("export async function updateCommand(sub: any = 'now'"), 'updateCommand default must be now');
|
|
14
|
+
assertGate(basicCli.includes("action.startsWith('-')") && basicCli.includes('effectiveArgs = [String(sub), ...args]'), 'sks update --json/--dry-run must be treated as update now with flags');
|
|
15
|
+
assertGate(update.includes('installSksMenuBar') && update.includes('sks_menubar'), 'update now must refresh the SKS menu bar companion stage');
|
|
16
|
+
assertGate(routes.includes('sks update [check|now]'), 'command catalog must document bare sks update as the default update path');
|
|
17
|
+
console.log(JSON.stringify({
|
|
18
|
+
schema: 'sks.update-default-command-check.v1',
|
|
19
|
+
ok: true,
|
|
20
|
+
checks: [
|
|
21
|
+
'registry_default_now',
|
|
22
|
+
'basic_cli_default_now',
|
|
23
|
+
'flag_first_default_now',
|
|
24
|
+
'update_menubar_stage',
|
|
25
|
+
'command_catalog_usage'
|
|
26
|
+
]
|
|
27
|
+
}, null, 2));
|
|
28
|
+
//# sourceMappingURL=update-default-command-check.js.map
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sneakoscope",
|
|
3
3
|
"displayName": "ㅅㅋㅅ",
|
|
4
|
-
"version": "4.7.
|
|
4
|
+
"version": "4.7.4",
|
|
5
5
|
"description": "Sneakoscope Codex: fast proof-first Codex trust layer with image-based Voxel TriWiki.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"homepage": "https://github.com/mandarange/Sneakoscope-Codex#readme",
|
|
@@ -114,6 +114,7 @@
|
|
|
114
114
|
"codex-app:fast-ui-preservation": "node ./dist/scripts/codex-app-fast-ui-preservation-check.js",
|
|
115
115
|
"codex-app:ui-clobber-guard": "node ./dist/scripts/codex-app-ui-clobber-guard-check.js",
|
|
116
116
|
"doctor:fixes-codex-app-fast-ui": "node ./dist/scripts/doctor-fixes-codex-app-fast-ui-check.js",
|
|
117
|
+
"codex-app:provider-model-ui": "node ./dist/scripts/codex-app-provider-model-ui-check.js",
|
|
117
118
|
"mad-sks:app-ui-no-mutation": "node ./dist/scripts/mad-sks-app-ui-no-mutation-check.js",
|
|
118
119
|
"provider:badge-context": "node ./dist/scripts/provider-badge-context-check.js",
|
|
119
120
|
"provider:context-config-toml": "node ./dist/scripts/provider-context-config-toml-check.js",
|
|
@@ -167,6 +168,8 @@
|
|
|
167
168
|
"codex:0.135-compat:require-real": "node ./dist/scripts/codex-0-135-compat-check.js --require-real",
|
|
168
169
|
"doctor:codex-doctor-parity": "node ./dist/scripts/doctor-codex-doctor-parity-check.js",
|
|
169
170
|
"doctor:codex-doctor-parity:actual": "node ./dist/scripts/doctor-codex-doctor-parity-check.js --actual-codex",
|
|
171
|
+
"doctor:sks-menubar": "node ./dist/scripts/sks-menubar-install-check.js",
|
|
172
|
+
"update:default-command": "node ./dist/scripts/update-default-command-check.js",
|
|
170
173
|
"codex:permission-profiles": "node ./dist/scripts/codex-permission-profiles-check.js",
|
|
171
174
|
"codex:legacy-profile-consumers-removed": "node ./dist/scripts/codex-legacy-profile-consumers-removed-check.js",
|
|
172
175
|
"terminal:keyboard-enhancement-safety": "node ./dist/scripts/terminal-keyboard-enhancement-safety-check.js",
|
|
@@ -303,6 +306,7 @@
|
|
|
303
306
|
"codex-lb:setup-truthfulness": "node ./dist/scripts/codex-lb-setup-truthfulness-check.js",
|
|
304
307
|
"codex-lb:persistence-truth": "node ./dist/scripts/codex-lb-persistence-truth-check.js",
|
|
305
308
|
"codex-lb:missing-env-regression": "node ./dist/scripts/codex-lb-missing-env-regression.js",
|
|
309
|
+
"codex-lb:fast-mode-truth": "node ./dist/scripts/codex-lb-fast-mode-truth-check.js",
|
|
306
310
|
"computer-use:policy-check": "node ./dist/scripts/computer-use-policy-check.js",
|
|
307
311
|
"computer-use:visual-route-fixture": "node ./dist/scripts/computer-use-visual-route-fixture-check.js",
|
|
308
312
|
"computer-use:live-optional": "node ./dist/scripts/computer-use-live-optional-check.js",
|