sneakoscope 4.0.2 → 4.0.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 +8 -7
- 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 -0
- package/dist/cli/global-mode-router.js +25 -0
- package/dist/cli/router.js +12 -0
- package/dist/commands/codex-app.js +10 -1
- package/dist/commands/codex.js +15 -1
- package/dist/core/codex-app/glm-model-profile.js +2 -0
- package/dist/core/codex-app/glm-profile-installer.js +61 -0
- package/dist/core/codex-app/glm-profile-schema.js +24 -0
- package/dist/core/codex-control/codex-0141-capability.js +95 -0
- package/dist/core/commands/glm-command.js +10 -0
- package/dist/core/commands/mad-sks-command.js +112 -14
- package/dist/core/fsx.js +1 -1
- package/dist/core/providers/glm/glm-52-profile.js +30 -0
- package/dist/core/providers/glm/glm-52-request.js +34 -0
- package/dist/core/providers/glm/glm-52-response-guard.js +34 -0
- package/dist/core/providers/glm/glm-52-settings.js +26 -0
- package/dist/core/providers/glm/glm-mad-launch.js +113 -0
- package/dist/core/providers/glm/glm-mad-mode.js +242 -0
- package/dist/core/providers/openrouter/openrouter-client.js +44 -0
- package/dist/core/providers/openrouter/openrouter-error.js +37 -0
- package/dist/core/providers/openrouter/openrouter-secret-store.js +113 -0
- package/dist/core/providers/openrouter/openrouter-types.js +2 -0
- package/dist/core/results.js +2 -0
- package/dist/core/secret-redaction.js +4 -0
- package/dist/core/security/redact-secrets.js +15 -0
- package/dist/core/version.js +1 -1
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -35,15 +35,16 @@ Set up this agent project with Sneakoscope Codex. Use [[mandarange/Sneakoscope-C
|
|
|
35
35
|
|
|
36
36
|
## 🚀 Current Release
|
|
37
37
|
|
|
38
|
-
SKS **4.0.
|
|
38
|
+
SKS **4.0.4** makes the GLM 5.2 MAD launch path real: `sks --mad --glm` now resolves the OpenRouter key, opens the MAD Zellij launch flow with Codex configured for `z-ai/glm-5.2`, blocks GPT fallback panes, and records launch proof; `sks --mad --glm --repair` still rotates the OpenRouter API key outside project files.
|
|
39
39
|
|
|
40
|
-
What changed in 4.0.
|
|
40
|
+
What changed in 4.0.4:
|
|
41
41
|
|
|
42
|
-
- **
|
|
43
|
-
- **
|
|
44
|
-
- **
|
|
45
|
-
- **
|
|
46
|
-
- **
|
|
42
|
+
- **GLM MAD actually launches.** `sks --mad --glm` no longer stops after the readiness banner; it continues into the MAD launcher with a GLM/OpenRouter Codex profile.
|
|
43
|
+
- **No leaked OpenRouter key.** The Zellij pane uses a mission-local `sks-glm-codex-wrapper.sh` that reads the key at runtime, so layout artifacts do not contain the raw secret.
|
|
44
|
+
- **No GPT fallback panes.** GLM MAD disables the existing GPT/codex-sdk native swarm by default until a GLM worker backend exists, preserving the no-fallback guarantee.
|
|
45
|
+
- **Launch proof.** Each GLM MAD launch writes `mad-glm-launch.json` with provider/model/profile/wrapper evidence and records disabled fallback status.
|
|
46
|
+
- **OpenRouter key lifecycle.** Keys resolve from `OPENROUTER_API_KEY`, `SKS_OPENROUTER_API_KEY`, or the user SKS secret store; stored keys use private permissions and redacted metadata.
|
|
47
|
+
- **4.0.3 GLM request safeguards remain.** GLM requests still use `provider.allow_fallbacks: false`, omit fallback `models`, and reject non-GLM response model ids before mutation.
|
|
47
48
|
|
|
48
49
|
SKS **3.1.16** was a launch-reliability patch on the 3.1.15 doctor-reliability release. It made `sks --mad` self-bootstrap a fresh project instead of dead-ending on a missing Codex config.
|
|
49
50
|
|
|
@@ -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 4.0.
|
|
7
|
+
Some("--version") => println!("sks-rs 4.0.4"),
|
|
8
8
|
Some("compact-info") => {
|
|
9
9
|
let mut input = String::new();
|
|
10
10
|
let _ = io::stdin().read_to_string(&mut input);
|
package/dist/bin/sks.js
CHANGED
|
@@ -111,6 +111,7 @@ export const COMMANDS = {
|
|
|
111
111
|
'zellij-slot-column-anchor': entry('beta', 'Render the compact SLOTS anchor pane for first-slot-down Zellij stacks', 'dist/commands/zellij-slot-column-anchor.js', directCommand(() => import('../commands/zellij-slot-column-anchor.js'), 'dist/commands/zellij-slot-column-anchor.js')),
|
|
112
112
|
zellij: entry('beta', 'Inspect Zellij runtime status and explain repair (no auto-install)', 'dist/commands/zellij.js', directCommand(() => import('../commands/zellij.js'), 'dist/commands/zellij.js')),
|
|
113
113
|
'mad-sks': entry('beta', 'MAD-SKS scoped permission modifier', 'dist/commands/mad-sks.js', directCommand(() => import('../commands/mad-sks.js'), 'dist/commands/mad-sks.js')),
|
|
114
|
+
glm: entry('beta', 'Run GLM 5.2 MAD mode through OpenRouter', 'dist/core/commands/glm-command.js', argsCommand(() => import('../core/commands/glm-command.js'), 'glmCommand', 'dist/core/commands/glm-command.js')),
|
|
114
115
|
'mad-db': entry('beta', 'Create or inspect one-cycle Mad-DB break-glass capability tokens', 'dist/commands/mad-db.js', directCommand(() => import('../commands/mad-db.js'), 'dist/commands/mad-db.js')),
|
|
115
116
|
'auto-review': entry('beta', 'Manage auto-review profile', 'dist/commands/auto-review.js', directCommand(() => import('../commands/auto-review.js'), 'dist/commands/auto-review.js')),
|
|
116
117
|
'dollar-commands': entry('stable', 'List Codex App dollar commands', 'dist/core/commands/basic-cli.js', basicArgs('dollarCommandsCommand')),
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const RESERVED_COMMANDS = new Set(['help', '--help', '-h', 'version', '--version', '-v']);
|
|
2
|
+
export function detectGlobalMode(args = []) {
|
|
3
|
+
if (!args.length || RESERVED_COMMANDS.has(String(args[0])))
|
|
4
|
+
return null;
|
|
5
|
+
const hasMad = args.includes('--mad');
|
|
6
|
+
const hasGlm = args.includes('--glm');
|
|
7
|
+
if (hasMad && hasGlm)
|
|
8
|
+
return { kind: 'mad-glm', args: stripGlobalModeFlags(args) };
|
|
9
|
+
if (hasGlm && !hasMad)
|
|
10
|
+
return { kind: 'glm-without-mad', args: stripGlobalModeFlags(args) };
|
|
11
|
+
return null;
|
|
12
|
+
}
|
|
13
|
+
export function stripGlobalModeFlags(args) {
|
|
14
|
+
return args.filter((arg) => arg !== '--mad' && arg !== '--glm');
|
|
15
|
+
}
|
|
16
|
+
export function glmWithoutMadResult() {
|
|
17
|
+
return {
|
|
18
|
+
ok: false,
|
|
19
|
+
status: 'blocked',
|
|
20
|
+
mode: 'glm',
|
|
21
|
+
reason: 'glm_requires_mad',
|
|
22
|
+
hint: 'use sks --mad --glm'
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=global-mode-router.js.map
|
package/dist/cli/router.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { COMMAND_ALIASES, COMMANDS, } from './command-registry.js';
|
|
2
|
+
import { detectGlobalMode, glmWithoutMadResult } from './global-mode-router.js';
|
|
2
3
|
export function isCommandName(value) {
|
|
3
4
|
return Object.prototype.hasOwnProperty.call(COMMANDS, value);
|
|
4
5
|
}
|
|
@@ -18,6 +19,17 @@ export function normalizeCommand(args = []) {
|
|
|
18
19
|
}
|
|
19
20
|
export async function dispatch(args) {
|
|
20
21
|
const argv = args ?? process.argv.slice(2);
|
|
22
|
+
const globalMode = detectGlobalMode(argv);
|
|
23
|
+
if (globalMode?.kind === 'mad-glm') {
|
|
24
|
+
const mod = await import('../core/commands/glm-command.js');
|
|
25
|
+
return mod.glmCommand(globalMode.args);
|
|
26
|
+
}
|
|
27
|
+
if (globalMode?.kind === 'glm-without-mad') {
|
|
28
|
+
const result = glmWithoutMadResult();
|
|
29
|
+
console.error(`GLM mode requires MAD: ${result.hint}`);
|
|
30
|
+
process.exitCode = 1;
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
21
33
|
const { command, rawCommand, args: rest } = normalizeCommand(argv);
|
|
22
34
|
if (!command) {
|
|
23
35
|
if (!argv.length) {
|
|
@@ -10,6 +10,7 @@ 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
12
|
import { repairCodexNativeManagedAssets } from '../core/codex-native/codex-native-repair-transaction.js';
|
|
13
|
+
import { doctorCodexAppGlmProfile, installCodexAppGlmProfile } from '../core/codex-app/glm-profile-installer.js';
|
|
13
14
|
export async function run(_command, args = []) {
|
|
14
15
|
const action = args[0] || 'check';
|
|
15
16
|
if (action === 'remote-control' || action === 'remote')
|
|
@@ -28,6 +29,14 @@ export async function run(_command, args = []) {
|
|
|
28
29
|
return printCodexAppResult(args, await buildCodexHookLifecycle({ root: await sksRoot(), apply: flag(args, '--apply') || flag(args, '--fix') }));
|
|
29
30
|
if (action === 'execution-profile')
|
|
30
31
|
return printCodexAppResult(args, await resolveCodexAppExecutionProfile({ root: await sksRoot() }));
|
|
32
|
+
if (action === 'glm-profile') {
|
|
33
|
+
const subcommand = args[1] || 'doctor';
|
|
34
|
+
const root = await sksRoot();
|
|
35
|
+
const result = subcommand === 'install' || subcommand === 'repair'
|
|
36
|
+
? await installCodexAppGlmProfile({ root, apply: true })
|
|
37
|
+
: await doctorCodexAppGlmProfile({ root });
|
|
38
|
+
return printCodexAppResult(args, result);
|
|
39
|
+
}
|
|
31
40
|
if (action === 'product-design' || action === 'design-product' || action === 'ensure-product-design') {
|
|
32
41
|
const checkOnly = flag(args, '--check-only') || flag(args, '--no-install');
|
|
33
42
|
const status = await codexProductDesignPluginStatus({
|
|
@@ -88,7 +97,7 @@ export async function run(_command, args = []) {
|
|
|
88
97
|
process.exitCode = 1;
|
|
89
98
|
return;
|
|
90
99
|
}
|
|
91
|
-
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]');
|
|
100
|
+
console.error('Usage: sks codex-app check|status|harness-matrix|skill-sync|agent-role-sync|init-deep|hook-lifecycle|execution-profile|glm-profile [install|doctor]|product-design [--check-only]|ensure-product-design|chrome-extension|pat status|remote-control [--json]');
|
|
92
101
|
process.exitCode = 1;
|
|
93
102
|
}
|
|
94
103
|
function printCodexAppResult(args = [], result) {
|
package/dist/commands/codex.js
CHANGED
|
@@ -3,6 +3,7 @@ import { printJson } from '../cli/output.js';
|
|
|
3
3
|
import { codexCompatibilityReport, codexDoctorReport } from '../core/codex-compat/codex-compat-report.js';
|
|
4
4
|
import { codexVersionReport } from '../core/codex-compat/codex-version.js';
|
|
5
5
|
import { codexSchemaSnapshotReport } from '../core/codex-compat/codex-schema-snapshot.js';
|
|
6
|
+
import { detectCodex0141Capability } from '../core/codex-control/codex-0141-capability.js';
|
|
6
7
|
export async function run(_command, args = []) {
|
|
7
8
|
const action = args[0] || 'compatibility';
|
|
8
9
|
if (action === 'compatibility' || action === 'compat') {
|
|
@@ -24,6 +25,19 @@ export async function run(_command, args = []) {
|
|
|
24
25
|
console.log(`Codex detected: ${result.detected.version || 'not installed'} (${result.policy.status})`);
|
|
25
26
|
return;
|
|
26
27
|
}
|
|
28
|
+
if (action === '0.141' || action === '0141' || action === 'rust-v0.141.0') {
|
|
29
|
+
const result = await detectCodex0141Capability();
|
|
30
|
+
if (flag(args, '--json'))
|
|
31
|
+
return printJson(result);
|
|
32
|
+
console.log(`Codex 0.141 compatibility: ${result.ok ? 'ok' : 'blocked'}`);
|
|
33
|
+
for (const blocker of result.blockers || [])
|
|
34
|
+
console.log(`- blocker: ${blocker}`);
|
|
35
|
+
for (const warning of result.warnings || [])
|
|
36
|
+
console.log(`- warning: ${warning}`);
|
|
37
|
+
if (!result.ok)
|
|
38
|
+
process.exitCode = 1;
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
27
41
|
if (action === 'doctor') {
|
|
28
42
|
const result = await codexDoctorReport();
|
|
29
43
|
if (flag(args, '--json'))
|
|
@@ -42,7 +56,7 @@ export async function run(_command, args = []) {
|
|
|
42
56
|
process.exitCode = 1;
|
|
43
57
|
return;
|
|
44
58
|
}
|
|
45
|
-
console.error('Usage: sks codex compatibility|version|doctor|schema [--json]');
|
|
59
|
+
console.error('Usage: sks codex compatibility|version|doctor|schema|0.141 [--json]');
|
|
46
60
|
process.exitCode = 1;
|
|
47
61
|
}
|
|
48
62
|
//# sourceMappingURL=codex.js.map
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { readJson, writeJsonAtomic, nowIso } from '../fsx.js';
|
|
3
|
+
import { buildGlmCodexAppModelProfile } from './glm-model-profile.js';
|
|
4
|
+
import { validateGlmCodexAppModelProfile } from './glm-profile-schema.js';
|
|
5
|
+
import { resolveOpenRouterApiKey } from '../providers/openrouter/openrouter-secret-store.js';
|
|
6
|
+
export async function installCodexAppGlmProfile(input) {
|
|
7
|
+
const root = path.resolve(input.root);
|
|
8
|
+
const profile = buildGlmCodexAppModelProfile();
|
|
9
|
+
const profilePath = path.join(root, '.sneakoscope', 'codex-app', 'glm-model-profile.json');
|
|
10
|
+
const reportPath = path.join(root, '.sneakoscope', 'reports', 'codex-app-glm-profile.json');
|
|
11
|
+
const key = await resolveOpenRouterApiKey({ env: input.env || process.env });
|
|
12
|
+
const warnings = [
|
|
13
|
+
...key.warnings,
|
|
14
|
+
...(key.key ? [] : ['openrouter_key_missing_until_sks_--mad_--glm_--repair'])
|
|
15
|
+
];
|
|
16
|
+
if (input.apply !== false)
|
|
17
|
+
await writeJsonAtomic(profilePath, profile);
|
|
18
|
+
const result = {
|
|
19
|
+
schema: 'sks.codex-app-glm-profile-result.v1',
|
|
20
|
+
generated_at: nowIso(),
|
|
21
|
+
ok: true,
|
|
22
|
+
status: input.apply === false ? 'valid' : 'installed',
|
|
23
|
+
profile,
|
|
24
|
+
profile_path: '.sneakoscope/codex-app/glm-model-profile.json',
|
|
25
|
+
report_path: '.sneakoscope/reports/codex-app-glm-profile.json',
|
|
26
|
+
openrouter_key_source: key.source,
|
|
27
|
+
blockers: [],
|
|
28
|
+
warnings
|
|
29
|
+
};
|
|
30
|
+
await writeJsonAtomic(reportPath, result).catch(() => undefined);
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
export async function doctorCodexAppGlmProfile(input) {
|
|
34
|
+
const root = path.resolve(input.root);
|
|
35
|
+
const profilePath = path.join(root, '.sneakoscope', 'codex-app', 'glm-model-profile.json');
|
|
36
|
+
const reportPath = path.join(root, '.sneakoscope', 'reports', 'codex-app-glm-profile.json');
|
|
37
|
+
const existing = await readJson(profilePath, null);
|
|
38
|
+
const validation = validateGlmCodexAppModelProfile(existing);
|
|
39
|
+
const key = await resolveOpenRouterApiKey({ env: input.env || process.env });
|
|
40
|
+
const profile = validation.profile || buildGlmCodexAppModelProfile();
|
|
41
|
+
const blockers = [...validation.blockers];
|
|
42
|
+
const warnings = [
|
|
43
|
+
...key.warnings,
|
|
44
|
+
...(key.key ? [] : ['openrouter_key_missing_until_sks_--mad_--glm_--repair'])
|
|
45
|
+
];
|
|
46
|
+
const result = {
|
|
47
|
+
schema: 'sks.codex-app-glm-profile-result.v1',
|
|
48
|
+
generated_at: nowIso(),
|
|
49
|
+
ok: blockers.length === 0,
|
|
50
|
+
status: blockers.length === 0 ? 'valid' : 'blocked',
|
|
51
|
+
profile,
|
|
52
|
+
profile_path: '.sneakoscope/codex-app/glm-model-profile.json',
|
|
53
|
+
report_path: '.sneakoscope/reports/codex-app-glm-profile.json',
|
|
54
|
+
openrouter_key_source: key.source,
|
|
55
|
+
blockers,
|
|
56
|
+
warnings
|
|
57
|
+
};
|
|
58
|
+
await writeJsonAtomic(reportPath, result).catch(() => undefined);
|
|
59
|
+
return result;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=glm-profile-installer.js.map
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { GLM_CODEX_APP_PROFILE_ID, buildGlmCodexAppModelProfile } from './glm-model-profile.js';
|
|
2
|
+
import { GLM_52_OPENROUTER_MODEL, GLM_MAD_MODE } from '../providers/glm/glm-52-settings.js';
|
|
3
|
+
export function validateGlmCodexAppModelProfile(value) {
|
|
4
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
5
|
+
return { ok: false, blockers: ['glm_codex_app_profile_missing'], profile: null };
|
|
6
|
+
}
|
|
7
|
+
const profile = value;
|
|
8
|
+
const expected = buildGlmCodexAppModelProfile();
|
|
9
|
+
const blockers = [
|
|
10
|
+
profile.schema === expected.schema ? null : 'glm_codex_app_profile_invalid_schema',
|
|
11
|
+
profile.id === GLM_CODEX_APP_PROFILE_ID ? null : 'glm_codex_app_profile_invalid_id',
|
|
12
|
+
profile.provider === 'openrouter' ? null : 'glm_codex_app_profile_invalid_provider',
|
|
13
|
+
profile.model === GLM_52_OPENROUTER_MODEL ? null : 'glm_codex_app_profile_invalid_model',
|
|
14
|
+
profile.mode === GLM_MAD_MODE ? null : 'glm_codex_app_profile_invalid_mode',
|
|
15
|
+
profile.strictModelLock === true ? null : 'glm_codex_app_profile_not_strict',
|
|
16
|
+
profile.gptFallbackAllowed === false ? null : 'glm_codex_app_profile_allows_gpt_fallback'
|
|
17
|
+
].filter((item) => Boolean(item));
|
|
18
|
+
return {
|
|
19
|
+
ok: blockers.length === 0,
|
|
20
|
+
blockers,
|
|
21
|
+
profile: blockers.length === 0 ? profile : null
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=glm-profile-schema.js.map
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { findCodexBinary } from '../codex-adapter.js';
|
|
3
|
+
import { compareSemverLike, parseCodexVersionText } from '../codex-compat/codex-version-policy.js';
|
|
4
|
+
import { nowIso, runProcess, writeJsonAtomic } from '../fsx.js';
|
|
5
|
+
export const CODEX_0141_FEATURE_KEYS = [
|
|
6
|
+
'noise_relay_delegated',
|
|
7
|
+
'native_cwd_shell_path_preserved',
|
|
8
|
+
'permission_paths_preserved',
|
|
9
|
+
'selected_plugin_mcp_per_thread',
|
|
10
|
+
'auth_curated_marketplaces',
|
|
11
|
+
'child_threads_api',
|
|
12
|
+
'external_agent_import_results',
|
|
13
|
+
'rate_limit_reset_credits',
|
|
14
|
+
'realtime_startup_context_control',
|
|
15
|
+
'tui_prompt_auto_resolve',
|
|
16
|
+
'hook_trust_resume_persistence',
|
|
17
|
+
'post_tool_use_blocking_respected',
|
|
18
|
+
'plugin_app_mcp_dedupe',
|
|
19
|
+
'windows_sandbox_repairs_delegated',
|
|
20
|
+
'idle_exec_relay_keepalive',
|
|
21
|
+
'wait_agent_interrupt_native',
|
|
22
|
+
'sqlite_wal_reset_fix_delegated',
|
|
23
|
+
'tls_p521_native',
|
|
24
|
+
'tool_heavy_copy_reduction',
|
|
25
|
+
'prompt_image_cache_bound_64_mib',
|
|
26
|
+
'feedback_upload_bound_8_threads',
|
|
27
|
+
'terminal_resize_reflow_always'
|
|
28
|
+
];
|
|
29
|
+
export async function detectCodex0141Capability(input = {}) {
|
|
30
|
+
const fake = process.env.SKS_CODEX_0141_FAKE === '1';
|
|
31
|
+
const codexBin = fake ? input.codexBin || process.env.CODEX_BIN || 'codex' : input.codexBin || process.env.CODEX_BIN || await findCodexBinary();
|
|
32
|
+
const versionText = fake ? String(process.env.SKS_CODEX_VERSION_FAKE || 'codex-cli 0.141.0') : await readCodexVersionText(codexBin);
|
|
33
|
+
const parsed = parseCodexVersionText(versionText);
|
|
34
|
+
const supports0141 = Boolean(parsed && compareSemverLike(parsed, '0.141.0') >= 0);
|
|
35
|
+
const featureStates = Object.fromEntries(CODEX_0141_FEATURE_KEYS.map((key) => [key, featureStateFor(key, supports0141)]));
|
|
36
|
+
const blockers = [
|
|
37
|
+
...(!codexBin ? ['codex_cli_missing'] : []),
|
|
38
|
+
...(supports0141 ? [] : ['codex_0_141_required_for_0141_features'])
|
|
39
|
+
];
|
|
40
|
+
return {
|
|
41
|
+
schema: 'sks.codex-0141-capability.v1',
|
|
42
|
+
generated_at: nowIso(),
|
|
43
|
+
ok: blockers.length === 0,
|
|
44
|
+
codex_version: parsed,
|
|
45
|
+
supports_0141: supports0141,
|
|
46
|
+
feature_states: featureStates,
|
|
47
|
+
blockers,
|
|
48
|
+
warnings: supports0141
|
|
49
|
+
? CODEX_0141_FEATURE_KEYS.map((key) => `codex_0141_${key}_assumed_by_version`)
|
|
50
|
+
: [],
|
|
51
|
+
codex_bin: codexBin || null,
|
|
52
|
+
release_source: 'https://github.com/openai/codex/releases/tag/rust-v0.141.0'
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
export async function writeCodex0141CapabilityArtifacts(root, input = {}) {
|
|
56
|
+
const report = await detectCodex0141Capability({ codexBin: input.codexBin || null });
|
|
57
|
+
const rootArtifact = path.join(root, '.sneakoscope', 'codex-0141-capability.json');
|
|
58
|
+
await writeJsonAtomic(rootArtifact, report);
|
|
59
|
+
let missionArtifact = null;
|
|
60
|
+
if (input.missionId) {
|
|
61
|
+
missionArtifact = path.join(root, '.sneakoscope', 'missions', input.missionId, 'codex-0141-capability.json');
|
|
62
|
+
await writeJsonAtomic(missionArtifact, report);
|
|
63
|
+
}
|
|
64
|
+
return { report, root_artifact: rootArtifact, mission_artifact: missionArtifact };
|
|
65
|
+
}
|
|
66
|
+
function featureStateFor(key, supports0141) {
|
|
67
|
+
return {
|
|
68
|
+
supported: supports0141,
|
|
69
|
+
certainty: supports0141 ? 'assumed_by_version' : 'failed',
|
|
70
|
+
evidence: supports0141 ? ['codex_version>=0.141.0', `release:rust-v0.141.0:${key}`] : [],
|
|
71
|
+
blockers: supports0141 ? [] : ['codex_0_141_required_for_0141_features'],
|
|
72
|
+
sks_policy: sksPolicyFor(key)
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function sksPolicyFor(key) {
|
|
76
|
+
if (key.includes('dedupe'))
|
|
77
|
+
return 'dedupe';
|
|
78
|
+
if (key.includes('bound') || key.includes('cache') || key.includes('feedback'))
|
|
79
|
+
return 'bound';
|
|
80
|
+
if (key.includes('blocking') || key.includes('trust'))
|
|
81
|
+
return 'respect';
|
|
82
|
+
return 'delegate';
|
|
83
|
+
}
|
|
84
|
+
async function readCodexVersionText(codexBin) {
|
|
85
|
+
if (!codexBin)
|
|
86
|
+
return null;
|
|
87
|
+
const result = await runProcess(codexBin, ['--version'], { timeoutMs: 10_000, maxOutputBytes: 16 * 1024 }).catch((err) => ({
|
|
88
|
+
code: 1,
|
|
89
|
+
stdout: '',
|
|
90
|
+
stderr: err instanceof Error ? err.message : String(err)
|
|
91
|
+
}));
|
|
92
|
+
const text = `${result.stdout || ''}${result.stderr || ''}`.trim();
|
|
93
|
+
return result.code === 0 ? text : text || null;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=codex-0141-capability.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { runMadGlmMode } from '../providers/glm/glm-mad-mode.js';
|
|
2
|
+
import { flag } from '../../cli/args.js';
|
|
3
|
+
import { madHighCommand } from './mad-sks-command.js';
|
|
4
|
+
export async function glmCommand(args = []) {
|
|
5
|
+
const result = await runMadGlmMode(args);
|
|
6
|
+
if (!result.ok || flag(args, '--repair') || flag(args, '--json'))
|
|
7
|
+
return result;
|
|
8
|
+
return madHighCommand(['--glm', ...args], { glmReadiness: result });
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=glm-command.js.map
|