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.
Files changed (32) hide show
  1. package/README.md +8 -7
  2. package/crates/sks-core/Cargo.lock +1 -1
  3. package/crates/sks-core/Cargo.toml +1 -1
  4. package/crates/sks-core/src/main.rs +1 -1
  5. package/dist/bin/sks.js +1 -1
  6. package/dist/cli/command-registry.js +1 -0
  7. package/dist/cli/global-mode-router.js +25 -0
  8. package/dist/cli/router.js +12 -0
  9. package/dist/commands/codex-app.js +10 -1
  10. package/dist/commands/codex.js +15 -1
  11. package/dist/core/codex-app/glm-model-profile.js +2 -0
  12. package/dist/core/codex-app/glm-profile-installer.js +61 -0
  13. package/dist/core/codex-app/glm-profile-schema.js +24 -0
  14. package/dist/core/codex-control/codex-0141-capability.js +95 -0
  15. package/dist/core/commands/glm-command.js +10 -0
  16. package/dist/core/commands/mad-sks-command.js +112 -14
  17. package/dist/core/fsx.js +1 -1
  18. package/dist/core/providers/glm/glm-52-profile.js +30 -0
  19. package/dist/core/providers/glm/glm-52-request.js +34 -0
  20. package/dist/core/providers/glm/glm-52-response-guard.js +34 -0
  21. package/dist/core/providers/glm/glm-52-settings.js +26 -0
  22. package/dist/core/providers/glm/glm-mad-launch.js +113 -0
  23. package/dist/core/providers/glm/glm-mad-mode.js +242 -0
  24. package/dist/core/providers/openrouter/openrouter-client.js +44 -0
  25. package/dist/core/providers/openrouter/openrouter-error.js +37 -0
  26. package/dist/core/providers/openrouter/openrouter-secret-store.js +113 -0
  27. package/dist/core/providers/openrouter/openrouter-types.js +2 -0
  28. package/dist/core/results.js +2 -0
  29. package/dist/core/secret-redaction.js +4 -0
  30. package/dist/core/security/redact-secrets.js +15 -0
  31. package/dist/core/version.js +1 -1
  32. package/package.json +4 -1
@@ -24,16 +24,19 @@ import { writeCodex0138CapabilityArtifacts } from '../codex-control/codex-0138-c
24
24
  import { writeCodex0139CapabilityArtifacts } from '../codex-control/codex-0139-capability.js';
25
25
  import { resolveCodexNativeInvocationPlan } from '../codex-native/codex-native-invocation-router.js';
26
26
  import { repairZellijForSks } from '../zellij/zellij-self-heal.js';
27
+ import { buildMadGlmLaunchArtifact, buildMadGlmLaunchProfileNoWrite, resolveMadGlmLaunchKey, writeMadGlmCodexWrapper } from '../providers/glm/glm-mad-launch.js';
28
+ import { GLM_MAD_MODE } from '../providers/glm/glm-52-settings.js';
27
29
  export async function madHighCommand(args = [], deps = {}) {
28
30
  const subcommand = firstSubcommand(args);
29
31
  if (subcommand)
30
32
  return madSksSubcommand(subcommand, args.filter((arg) => String(arg) !== subcommand));
31
33
  const cleanArgs = stripMadLaunchOnlyArgs(args);
32
34
  const rawArgs = (args || []).map((arg) => String(arg));
35
+ const glmMadLaunch = isMadGlmLaunch(rawArgs, deps);
33
36
  const madDbGrant = resolveMadLaunchMadDbGrant(rawArgs);
34
37
  const dryRun = rawArgs.includes('--dry-run');
35
- if (args.includes('--json') && !dryRun) {
36
- const profile = buildMadHighLaunchProfileNoWrite();
38
+ if (rawArgs.includes('--json') && !dryRun) {
39
+ const profile = glmMadLaunch ? buildMadGlmLaunchProfileNoWrite() : buildMadHighLaunchProfileNoWrite();
37
40
  return console.log(JSON.stringify(profile, null, 2));
38
41
  }
39
42
  const update = { status: 'notice_only', non_blocking: true };
@@ -76,7 +79,7 @@ export async function madHighCommand(args = [], deps = {}) {
76
79
  }
77
80
  return report;
78
81
  }
79
- const codexUpdate = deps.maybePromptCodexUpdateForLaunch ? await deps.maybePromptCodexUpdateForLaunch(args, { label: 'MAD launch' }) : { status: 'skipped' };
82
+ const codexUpdate = deps.maybePromptCodexUpdateForLaunch ? await deps.maybePromptCodexUpdateForLaunch(args, { label: glmMadLaunch ? 'GLM MAD launch' : 'MAD launch' }) : { status: 'skipped' };
80
83
  if (codexUpdate.status === 'failed' || codexUpdate.status === 'updated_not_reflected') {
81
84
  console.error(`Codex CLI update failed: ${codexUpdate.error || 'updated version was not visible on PATH'}`);
82
85
  process.exitCode = 1;
@@ -86,7 +89,7 @@ export async function madHighCommand(args = [], deps = {}) {
86
89
  ? { status: 'skipped', command: 'sks doctor --fix --yes' }
87
90
  : deps.maybePromptZellijUpdateForLaunch
88
91
  ? await deps.maybePromptZellijUpdateForLaunch(args, {
89
- label: 'MAD launch',
92
+ label: glmMadLaunch ? 'GLM MAD launch' : 'MAD launch',
90
93
  root: launchRoot,
91
94
  selfHealOnMissing: true,
92
95
  autoApprove: rawArgs.includes('--yes') || rawArgs.includes('-y'),
@@ -121,8 +124,10 @@ export async function madHighCommand(args = [], deps = {}) {
121
124
  process.exitCode = 1;
122
125
  return;
123
126
  }
124
- const lb = deps.maybePromptCodexLbSetupForLaunch ? await deps.maybePromptCodexLbSetupForLaunch(args) : { status: 'skipped' };
125
- if (lb.status === 'missing_api_key') {
127
+ const lb = glmMadLaunch
128
+ ? { status: 'skipped_glm_openrouter', ok: false, reason: 'glm_mad_uses_openrouter_directly' }
129
+ : deps.maybePromptCodexLbSetupForLaunch ? await deps.maybePromptCodexLbSetupForLaunch(args) : { status: 'skipped' };
130
+ if (!glmMadLaunch && lb.status === 'missing_api_key') {
126
131
  process.exitCode = 1;
127
132
  return;
128
133
  }
@@ -171,6 +176,11 @@ export async function madHighCommand(args = [], deps = {}) {
171
176
  return launchPreflight;
172
177
  }
173
178
  const madLaunch = await activateMadZellijPermissionState(process.cwd(), args);
179
+ const glmRuntime = glmMadLaunch ? await prepareMadGlmLaunchRuntime(madLaunch, deps) : null;
180
+ if (glmMadLaunch && !glmRuntime?.ok) {
181
+ process.exitCode = 1;
182
+ return glmRuntime;
183
+ }
174
184
  const madDbCapability = madDbGrant.enabled
175
185
  ? await createMadDbCapability(madLaunch.root, { missionId: madLaunch.mission_id, ack: madDbGrant.ack, cwd: process.cwd() })
176
186
  : null;
@@ -221,7 +231,9 @@ export async function madHighCommand(args = [], deps = {}) {
221
231
  error: err?.message || String(err)
222
232
  }));
223
233
  await appendJsonlBounded(path.join(madLaunch.dir, 'events.jsonl'), { ts: nowIso(), type: 'mad_sks.update_notice_checked', non_blocking: true, update_available: updateNotice.update_available === true, source: updateNotice.source });
224
- console.log(`SKS MAD ready: ${madHighProfileName()} | gate ${madLaunch.mission_id}`);
234
+ console.log(`SKS MAD ready: ${glmRuntime?.profile?.profile_name || madHighProfileName()} | gate ${madLaunch.mission_id}`);
235
+ if (glmRuntime?.profile)
236
+ console.log(`GLM MAD launch active: ${glmRuntime.profile.model} via OpenRouter; GPT fallback blocked.`);
225
237
  if (madDbCapability)
226
238
  console.log(`MAD-DB one-cycle capability active (${madDbGrant.source}); expires ${madDbCapability.expires_at}.`);
227
239
  if (updateNotice.update_available === true)
@@ -233,8 +245,18 @@ export async function madHighCommand(args = [], deps = {}) {
233
245
  SKS_MAD_SKS_TARGET_ROOT: madLaunch.gate.cwd,
234
246
  SKS_MAD_SKS_PROTECTED_CORE_DIGEST: madLaunch.gate.protected_core_digest
235
247
  };
236
- const launchOpts = codexLbImmediateLaunchOpts(cleanArgs, launchLb, { codexArgs: profile.launch_args, conciseBlockers: true, madSksEnv, launchEnv: madSksEnv });
237
248
  const explicitWorkspace = readOption(cleanArgs, '--workspace', readOption(cleanArgs, '--session', null));
249
+ const launchProfile = glmRuntime?.profile || profile;
250
+ const launchOpts = glmRuntime
251
+ ? buildGlmMadLaunchOpts(cleanArgs, {
252
+ codexArgs: launchProfile.launch_args,
253
+ conciseBlockers: true,
254
+ madSksEnv,
255
+ launchEnv: madSksEnv,
256
+ codexBin: glmRuntime.wrapper.wrapper_path,
257
+ explicitWorkspace
258
+ })
259
+ : codexLbImmediateLaunchOpts(cleanArgs, launchLb, { codexArgs: launchProfile.launch_args, conciseBlockers: true, madSksEnv, launchEnv: madSksEnv });
238
260
  // Only the auto-derived stable `sks-mad-<cwd>` name accumulates panes across
239
261
  // runs; when the user names a session explicitly (or codex-lb already minted a
240
262
  // fresh unique session) respect it and skip the reset.
@@ -268,11 +290,12 @@ export async function madHighCommand(args = [], deps = {}) {
268
290
  worker_panes_created: 0,
269
291
  right_column_mode: 'spawn-on-first-worker'
270
292
  });
271
- const madNativeSwarm = await startMadNativeSwarm(madLaunch.root, madLaunch, args, profile, {
293
+ const madNativeSwarm = await startMadNativeSwarm(madLaunch.root, madLaunch, args, launchProfile, {
272
294
  env: {
273
295
  ...madSksEnv,
274
296
  ...(launch.session_name ? { SKS_ZELLIJ_SESSION_NAME: launch.session_name } : {})
275
297
  },
298
+ glmLaunch: glmRuntime ? { provider: glmRuntime.profile.provider, model: glmRuntime.profile.model } : null,
276
299
  zellijSessionName: launch.session_name || null,
277
300
  workerPlacement: headlessZellij ? 'process' : shouldAutoAttachZellij(args) ? 'zellij-pane' : 'process',
278
301
  zellijVisiblePaneCap: Number(process.env.SKS_ZELLIJ_VISIBLE_PANE_CAP || 8)
@@ -296,6 +319,67 @@ export async function madHighCommand(args = [], deps = {}) {
296
319
  console.log('MAD launch running headless: live_panes=false.');
297
320
  return launch;
298
321
  }
322
+ function isMadGlmLaunch(args = [], deps = {}) {
323
+ const list = (args || []).map((arg) => String(arg));
324
+ return list.includes('--glm') || deps?.glmReadiness?.mode === GLM_MAD_MODE;
325
+ }
326
+ async function prepareMadGlmLaunchRuntime(madLaunch, deps = {}) {
327
+ const keyResolution = await resolveMadGlmLaunchKey(process.env);
328
+ const profile = buildMadGlmLaunchProfileNoWrite();
329
+ if (!keyResolution.key) {
330
+ const blocked = {
331
+ schema: 'sks.glm-mad-launch.v1',
332
+ ok: false,
333
+ status: 'blocked',
334
+ mission_id: madLaunch.mission_id,
335
+ provider: profile.provider,
336
+ model: profile.model,
337
+ gpt_fallback_allowed: false,
338
+ blockers: keyResolution.blockers,
339
+ warnings: keyResolution.warnings
340
+ };
341
+ await writeJsonAtomic(path.join(madLaunch.dir, 'mad-glm-launch.json'), blocked);
342
+ await appendJsonlBounded(path.join(madLaunch.dir, 'events.jsonl'), {
343
+ ts: nowIso(),
344
+ type: 'mad_sks.glm_launch_blocked',
345
+ blockers: keyResolution.blockers
346
+ });
347
+ console.error('SKS GLM MAD launch blocked: OpenRouter API key is missing.');
348
+ console.error('Run: sks --mad --glm --repair');
349
+ return blocked;
350
+ }
351
+ const wrapper = await writeMadGlmCodexWrapper({
352
+ missionDir: madLaunch.dir,
353
+ realCodexBin: process.env.SKS_CODEX_BIN || null
354
+ });
355
+ const report = {
356
+ ...buildMadGlmLaunchArtifact({
357
+ missionId: madLaunch.mission_id,
358
+ keyResolution,
359
+ wrapper,
360
+ profile
361
+ }),
362
+ readiness_status: deps?.glmReadiness?.status || null
363
+ };
364
+ await writeJsonAtomic(path.join(madLaunch.dir, 'mad-glm-launch.json'), report);
365
+ await appendJsonlBounded(path.join(madLaunch.dir, 'events.jsonl'), {
366
+ ts: nowIso(),
367
+ type: 'mad_sks.glm_launch_profile_ready',
368
+ provider: profile.provider,
369
+ model: profile.model,
370
+ key_source: keyResolution.source || null,
371
+ gpt_fallback_allowed: false
372
+ });
373
+ return { ok: true, profile, wrapper, report };
374
+ }
375
+ function buildGlmMadLaunchOpts(cleanArgs = [], opts = {}) {
376
+ if (opts.explicitWorkspace)
377
+ return opts;
378
+ const root = readOption(cleanArgs, '--root', process.cwd());
379
+ const session = sanitizeZellijSessionName(`sks-glm-${Date.now().toString(36)}-${path.basename(root) || 'project'}`);
380
+ console.log(`Using fresh GLM Zellij session: ${session}`);
381
+ return { ...opts, session, glmMadLaunch: true };
382
+ }
299
383
  export function resolveMadLaunchMadDbGrant(args = []) {
300
384
  const list = (args || []).map((arg) => String(arg));
301
385
  return {
@@ -319,6 +403,9 @@ export async function startMadNativeSwarm(root, madLaunch, args = [], profile =
319
403
  status: 'disabled',
320
404
  reason: swarm.disabled_reason,
321
405
  mission_id: madLaunch.mission_id,
406
+ model_provider: opts.glmLaunch?.provider || null,
407
+ model: opts.glmLaunch?.model || null,
408
+ gpt_fallback_allowed: opts.glmLaunch ? false : null,
322
409
  lane_count: 1,
323
410
  ledger_root: path.relative(root, ledgerRoot)
324
411
  };
@@ -381,6 +468,9 @@ export async function startMadNativeSwarm(root, madLaunch, args = [], profile =
381
468
  zellij_session_name: opts.zellijSessionName || null,
382
469
  worker_placement: opts.workerPlacement || (swarm.backend === 'zellij' ? 'zellij-pane' : 'process'),
383
470
  zellij_visible_pane_cap: opts.zellijVisiblePaneCap || null,
471
+ model_provider: opts.glmLaunch?.provider || null,
472
+ model: opts.glmLaunch?.model || null,
473
+ gpt_fallback_allowed: opts.glmLaunch ? false : null,
384
474
  readonly: true,
385
475
  command,
386
476
  stdout_log: path.relative(root, stdoutLog),
@@ -430,13 +520,18 @@ export async function startMadNativeSwarm(root, madLaunch, args = [], profile =
430
520
  }
431
521
  export function resolveMadNativeSwarmOptions(args = [], profile = {}, opts = {}) {
432
522
  const list = (args || []).map((arg) => String(arg));
433
- const disabled = list.includes('--no-swarm') || list.includes('--no-mad-swarm') || process.env.SKS_MAD_NATIVE_SWARM === '0';
523
+ const operatorDisabled = list.includes('--no-swarm') || list.includes('--no-mad-swarm') || process.env.SKS_MAD_NATIVE_SWARM === '0';
524
+ const glmRequested = list.includes('--glm') || opts.glmLaunch?.provider === 'openrouter';
525
+ const glmNativeSwarmDisabled = glmRequested && process.env.SKS_GLM_MAD_ALLOW_GPT_SWARM !== '1';
526
+ const disabled = operatorDisabled || glmNativeSwarmDisabled;
434
527
  const agents = clampInt(readOption(list, '--mad-agents', readOption(list, '--mad-swarm-agents', process.env.SKS_MAD_SWARM_AGENTS || opts.agents || 5)), 1, 20);
435
528
  const workItems = clampInt(readOption(list, '--mad-swarm-work-items', process.env.SKS_MAD_SWARM_WORK_ITEMS || opts.workItems || agents), agents, 100);
436
529
  const backend = defaultMadSwarmBackend(list, opts);
437
530
  return {
438
531
  enabled: !disabled,
439
- disabled_reason: disabled ? 'operator_disabled_mad_native_swarm' : null,
532
+ disabled_reason: operatorDisabled
533
+ ? 'operator_disabled_mad_native_swarm'
534
+ : glmNativeSwarmDisabled ? 'glm_mad_native_swarm_disabled_to_block_gpt_fallback' : null,
440
535
  agents,
441
536
  workItems,
442
537
  backend,
@@ -516,12 +611,14 @@ async function activateMadZellijPermissionState(cwd = process.cwd(), args = [])
516
611
  const root = await sksRoot();
517
612
  if (!(await exists(path.join(root, '.sneakoscope'))))
518
613
  await initProject(root, {});
614
+ const rawArgs = (args || []).map((arg) => String(arg));
615
+ const activatedBy = rawArgs.includes('--glm') ? 'sks --mad --glm' : 'sks --mad';
519
616
  const flags = parseMadSksFlags(['--mad-sks', ...args].filter(Boolean));
520
- const permission = buildMadSksPermissionModel({ targetRoot: cwd, userIntent: 'sks --mad Zellij scoped high-power maintenance session', flags });
617
+ const permission = buildMadSksPermissionModel({ targetRoot: cwd, userIntent: `${activatedBy} Zellij scoped high-power maintenance session`, flags });
521
618
  const allowedScopes = new Set(permission.allowed_scopes || []);
522
619
  const has = (scope) => allowedScopes.has(scope);
523
620
  const dbWriteAllowed = has('db_write');
524
- const { id, dir } = await createMission(root, { mode: 'mad-sks', prompt: 'sks --mad Zellij scoped high-power maintenance session' });
621
+ const { id, dir } = await createMission(root, { mode: 'mad-sks', prompt: `${activatedBy} Zellij scoped high-power maintenance session` });
525
622
  await writeCodex0138CapabilityArtifacts(root, { missionId: id }).catch(() => null);
526
623
  await writeCodex0139CapabilityArtifacts(root, { missionId: id }).catch(() => null);
527
624
  const codexNativeInvocation = await resolveCodexNativeInvocationPlan({
@@ -582,7 +679,7 @@ async function activateMadZellijPermissionState(cwd = process.cwd(), args = [])
582
679
  warnings: codexNativeInvocation.warnings,
583
680
  artifact_path: 'mad-codex-native-invocation.json'
584
681
  } : null,
585
- activated_by: 'sks --mad',
682
+ activated_by: activatedBy,
586
683
  cwd: path.resolve(cwd || process.cwd())
587
684
  };
588
685
  await writeJsonAtomic(path.join(dir, 'mad-sks-gate.json'), gate);
@@ -621,6 +718,7 @@ function madLaunchOnlyFlags() {
621
718
  '--mad',
622
719
  '--MAD',
623
720
  '--mad-sks',
721
+ '--glm',
624
722
  '--high',
625
723
  '--attach',
626
724
  '--no-attach',
package/dist/core/fsx.js CHANGED
@@ -5,7 +5,7 @@ import os from 'node:os';
5
5
  import crypto from 'node:crypto';
6
6
  import { spawn } from 'node:child_process';
7
7
  import { fileURLToPath } from 'node:url';
8
- export const PACKAGE_VERSION = '4.0.2';
8
+ export const PACKAGE_VERSION = '4.0.4';
9
9
  export const DEFAULT_PROCESS_TAIL_BYTES = 256 * 1024;
10
10
  export const DEFAULT_PROCESS_TIMEOUT_MS = 30 * 60 * 1000;
11
11
  export function nowIso() {
@@ -0,0 +1,30 @@
1
+ import { GLM_52_DEFAULT_REQUEST_SETTINGS, GLM_52_OPENROUTER_MODEL, GLM_MAD_MODE } from './glm-52-settings.js';
2
+ export const GLM_CODEX_APP_PROFILE_ID = 'sks/glm-5.2-mad';
3
+ export const GLM_CODEX_APP_PROFILE_LABEL = 'GLM 5.2 (MAD / OpenRouter)';
4
+ export function buildGlmCodexAppModelProfile() {
5
+ return {
6
+ schema: 'sks.codex-app-model-profile.v1',
7
+ id: GLM_CODEX_APP_PROFILE_ID,
8
+ label: GLM_CODEX_APP_PROFILE_LABEL,
9
+ provider: 'openrouter',
10
+ model: GLM_52_OPENROUTER_MODEL,
11
+ mode: GLM_MAD_MODE,
12
+ strictModelLock: true,
13
+ gptFallbackAllowed: false,
14
+ requiresSecret: 'openrouter-api-key',
15
+ defaultSettings: {
16
+ temperature: GLM_52_DEFAULT_REQUEST_SETTINGS.temperature,
17
+ top_p: GLM_52_DEFAULT_REQUEST_SETTINGS.top_p,
18
+ reasoning_effort: 'high',
19
+ tool_choice: 'auto',
20
+ parallel_tool_calls: false
21
+ },
22
+ codexCompatibility: {
23
+ target: 'rust-v0.141.0',
24
+ selectedExecutorPluginMcp: 'defer-to-codex-native',
25
+ duplicateAppMcpDeclarations: 'dedupe-by-codex',
26
+ cwdShellPathSemantics: 'preserve-codex-native'
27
+ }
28
+ };
29
+ }
30
+ //# sourceMappingURL=glm-52-profile.js.map
@@ -0,0 +1,34 @@
1
+ import { GLM_52_DEFAULT_REQUEST_SETTINGS, GLM_52_OPENROUTER_MODEL, clampGlm52MaxTokens } from './glm-52-settings.js';
2
+ export function buildGlm52Request(input) {
3
+ const request = {
4
+ model: GLM_52_OPENROUTER_MODEL,
5
+ messages: input.messages,
6
+ stream: input.stream ?? GLM_52_DEFAULT_REQUEST_SETTINGS.stream,
7
+ temperature: GLM_52_DEFAULT_REQUEST_SETTINGS.temperature,
8
+ top_p: GLM_52_DEFAULT_REQUEST_SETTINGS.top_p,
9
+ reasoning: { effort: input.reasoningEffort ?? 'high' },
10
+ max_tokens: clampGlm52MaxTokens(input.maxTokens),
11
+ tool_choice: input.toolChoice ?? 'auto',
12
+ parallel_tool_calls: input.parallelToolCalls ?? false,
13
+ provider: {
14
+ allow_fallbacks: false,
15
+ require_parameters: true,
16
+ sort: input.providerSort ?? 'throughput'
17
+ }
18
+ };
19
+ return {
20
+ ...request,
21
+ ...(input.tools ? { tools: input.tools } : {}),
22
+ ...(input.responseFormat ? { response_format: input.responseFormat } : {})
23
+ };
24
+ }
25
+ export function buildGlm52KeyValidationRequest() {
26
+ return buildGlm52Request({
27
+ messages: [{ role: 'user', content: 'Reply with OK.' }],
28
+ stream: false,
29
+ maxTokens: 1,
30
+ toolChoice: 'none',
31
+ parallelToolCalls: false
32
+ });
33
+ }
34
+ //# sourceMappingURL=glm-52-request.js.map
@@ -0,0 +1,34 @@
1
+ import { GLM_52_OPENROUTER_MODEL } from './glm-52-settings.js';
2
+ export function assertGlm52ActualModel(responseModel) {
3
+ if (!responseModel) {
4
+ return {
5
+ ok: false,
6
+ code: 'glm_model_missing',
7
+ requestedModel: GLM_52_OPENROUTER_MODEL,
8
+ strictModelLock: true,
9
+ gptFallbackAllowed: false
10
+ };
11
+ }
12
+ const normalized = responseModel.toLowerCase();
13
+ if (normalized === GLM_52_OPENROUTER_MODEL ||
14
+ normalized.startsWith(`${GLM_52_OPENROUTER_MODEL}-`) ||
15
+ normalized.includes('glm-5.2')) {
16
+ return {
17
+ ok: true,
18
+ code: 'ok',
19
+ actualModel: responseModel,
20
+ requestedModel: GLM_52_OPENROUTER_MODEL,
21
+ strictModelLock: true,
22
+ gptFallbackAllowed: false
23
+ };
24
+ }
25
+ return {
26
+ ok: false,
27
+ code: 'glm_model_mismatch',
28
+ actualModel: responseModel,
29
+ requestedModel: GLM_52_OPENROUTER_MODEL,
30
+ strictModelLock: true,
31
+ gptFallbackAllowed: false
32
+ };
33
+ }
34
+ //# sourceMappingURL=glm-52-response-guard.js.map
@@ -0,0 +1,26 @@
1
+ export { OPENROUTER_CHAT_COMPLETIONS_URL } from '../openrouter/openrouter-types.js';
2
+ export const GLM_52_OPENROUTER_MODEL = 'z-ai/glm-5.2';
3
+ export const GLM_MAD_MODE = 'mad-glm';
4
+ export const GLM_52_MAX_TOKENS_DEFAULT = 32768;
5
+ export const GLM_52_MAX_TOKENS_LONG = 65536;
6
+ export const GLM_52_MAX_TOKENS_XLONG = 131072;
7
+ export const GLM_52_TOP_PROVIDER_MAX_COMPLETION_TOKENS = 262144;
8
+ export const GLM_52_DEFAULT_REQUEST_SETTINGS = {
9
+ model: GLM_52_OPENROUTER_MODEL,
10
+ temperature: 1,
11
+ top_p: 0.95,
12
+ reasoning_effort: 'high',
13
+ stream: true,
14
+ provider: {
15
+ allow_fallbacks: false,
16
+ require_parameters: true
17
+ },
18
+ tool_choice: 'auto',
19
+ parallel_tool_calls: false,
20
+ max_tokens: GLM_52_MAX_TOKENS_DEFAULT
21
+ };
22
+ export function clampGlm52MaxTokens(value) {
23
+ const numeric = Number.isFinite(value) ? Math.floor(Number(value)) : GLM_52_MAX_TOKENS_DEFAULT;
24
+ return Math.max(1, Math.min(numeric, GLM_52_TOP_PROVIDER_MAX_COMPLETION_TOKENS));
25
+ }
26
+ //# sourceMappingURL=glm-52-settings.js.map
@@ -0,0 +1,113 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { nowIso, writeTextAtomic } from '../../fsx.js';
4
+ import { resolveOpenRouterApiKey, openRouterSecretPaths } from '../openrouter/openrouter-secret-store.js';
5
+ import { GLM_52_OPENROUTER_MODEL } from './glm-52-settings.js';
6
+ export const GLM_MAD_PROFILE_ID = 'sks/glm-5.2-mad';
7
+ export const OPENROUTER_CODEX_PROVIDER = 'openrouter';
8
+ export function buildMadGlmLaunchProfileNoWrite() {
9
+ return {
10
+ schema: 'sks.glm-mad-launch-profile.v1',
11
+ profile_name: GLM_MAD_PROFILE_ID,
12
+ provider: OPENROUTER_CODEX_PROVIDER,
13
+ model: GLM_52_OPENROUTER_MODEL,
14
+ launch_args: [
15
+ '--sandbox',
16
+ 'danger-full-access',
17
+ '--ask-for-approval',
18
+ 'never',
19
+ '-c',
20
+ 'service_tier=fast',
21
+ '-c',
22
+ 'model_reasoning_effort=high',
23
+ '-c',
24
+ 'model_provider="openrouter"',
25
+ '-c',
26
+ `model="${GLM_52_OPENROUTER_MODEL}"`,
27
+ '-c',
28
+ 'model_providers.openrouter.name="OpenRouter"',
29
+ '-c',
30
+ 'model_providers.openrouter.base_url="https://openrouter.ai/api/v1"',
31
+ '-c',
32
+ 'model_providers.openrouter.env_key="OPENROUTER_API_KEY"',
33
+ '-c',
34
+ 'model_providers.openrouter.wire_api="responses"',
35
+ '-c',
36
+ 'model_providers.openrouter.requires_openai_auth=false'
37
+ ],
38
+ sandbox_mode: 'danger-full-access',
39
+ approval_policy: 'never',
40
+ model_reasoning_effort: 'high',
41
+ service_tier: 'fast',
42
+ gpt_fallback_allowed: false,
43
+ writes_user_codex_config: false
44
+ };
45
+ }
46
+ export async function resolveMadGlmLaunchKey(env = process.env) {
47
+ return resolveOpenRouterApiKey({ env });
48
+ }
49
+ export async function writeMadGlmCodexWrapper(input) {
50
+ const env = input.env || process.env;
51
+ const paths = openRouterSecretPaths(env);
52
+ const realCodexBin = String(input.realCodexBin || env.SKS_CODEX_BIN || 'codex');
53
+ const wrapperPath = path.join(input.missionDir, 'sks-glm-codex-wrapper.sh');
54
+ await writeTextAtomic(wrapperPath, buildMadGlmCodexWrapperScript({
55
+ realCodexBin,
56
+ secretKeyPath: paths.keyPath
57
+ }));
58
+ await fs.chmod(wrapperPath, 0o700).catch(() => undefined);
59
+ return {
60
+ wrapper_path: wrapperPath,
61
+ real_codex_bin: realCodexBin,
62
+ secret_key_path: paths.keyPath,
63
+ raw_key_written_to_wrapper: false
64
+ };
65
+ }
66
+ export function buildMadGlmCodexWrapperScript(input) {
67
+ return [
68
+ '#!/bin/sh',
69
+ 'set -eu',
70
+ '# Generated by SKS GLM MAD launch. This wrapper reads the key at runtime',
71
+ '# so Zellij layout artifacts never contain the raw OpenRouter secret.',
72
+ 'if [ -z "${OPENROUTER_API_KEY:-}" ] && [ -n "${SKS_OPENROUTER_API_KEY:-}" ]; then',
73
+ ' OPENROUTER_API_KEY="$SKS_OPENROUTER_API_KEY"',
74
+ ' export OPENROUTER_API_KEY',
75
+ 'fi',
76
+ `if [ -z "\${OPENROUTER_API_KEY:-}" ] && [ -r ${shellQuote(input.secretKeyPath)} ]; then`,
77
+ ` OPENROUTER_API_KEY="$(cat ${shellQuote(input.secretKeyPath)})"`,
78
+ ' export OPENROUTER_API_KEY',
79
+ 'fi',
80
+ 'if [ -z "${OPENROUTER_API_KEY:-}" ]; then',
81
+ ' echo "SKS GLM MAD blocked: OPENROUTER_API_KEY is missing. Run sks --mad --glm --repair or export OPENROUTER_API_KEY." >&2',
82
+ ' exit 66',
83
+ 'fi',
84
+ `exec ${shellQuote(input.realCodexBin)} "$@"`,
85
+ ''
86
+ ].join('\n');
87
+ }
88
+ export function buildMadGlmLaunchArtifact(input) {
89
+ const profile = input.profile || buildMadGlmLaunchProfileNoWrite();
90
+ return {
91
+ schema: 'sks.glm-mad-launch.v1',
92
+ generated_at: nowIso(),
93
+ ok: Boolean(input.keyResolution.key),
94
+ mission_id: input.missionId,
95
+ provider: profile.provider,
96
+ model: profile.model,
97
+ profile_name: profile.profile_name,
98
+ strict_model_lock: true,
99
+ gpt_fallback_allowed: false,
100
+ openrouter_key_source: input.keyResolution.source || null,
101
+ key_preview: input.keyResolution.key_preview || null,
102
+ wrapper_path: input.wrapper.wrapper_path,
103
+ real_codex_bin: input.wrapper.real_codex_bin,
104
+ raw_key_written_to_wrapper: false,
105
+ codex_args: profile.launch_args,
106
+ blockers: input.keyResolution.key ? [] : input.keyResolution.blockers,
107
+ warnings: input.keyResolution.warnings || []
108
+ };
109
+ }
110
+ function shellQuote(value) {
111
+ return `'${String(value).replace(/'/g, `'\\''`)}'`;
112
+ }
113
+ //# sourceMappingURL=glm-mad-launch.js.map