sneakoscope 4.6.5 → 4.7.1
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 +18 -4
- 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/install-helpers.js +80 -15
- package/dist/commands/codex-app.js +34 -3
- package/dist/commands/doctor.js +1 -1
- package/dist/core/agents/agent-effort-policy.js +110 -5
- package/dist/core/agents/agent-orchestrator.js +27 -3
- package/dist/core/agents/agent-plan.js +2 -2
- package/dist/core/agents/agent-roster.js +8 -0
- package/dist/core/agents/agent-worker-slot.js +4 -0
- package/dist/core/codex/agent-config-file-repair.js +4 -4
- package/dist/core/codex-app/codex-app-fast-ui-repair.js +4 -2
- package/dist/core/codex-app/codex-app-ui-state-snapshot.js +14 -3
- package/dist/core/codex-app/glm-model-profile.js +1 -1
- package/dist/core/codex-app/glm-profile-installer.js +111 -7
- package/dist/core/codex-app/glm-profile-schema.js +21 -2
- package/dist/core/codex-app.js +2 -0
- package/dist/core/codex-control/codex-sdk-config-policy.js +2 -1
- package/dist/core/codex-model-guard.js +3 -1
- package/dist/core/commands/fast-mode-command.js +5 -2
- package/dist/core/commands/glm-command.js +2 -1
- package/dist/core/commands/mad-sks-command.js +24 -0
- package/dist/core/doctor/doctor-codex-startup-repair.js +111 -9
- package/dist/core/feature-registry.js +3 -3
- package/dist/core/fsx.js +1 -1
- package/dist/core/harness-guard.js +89 -3
- package/dist/core/init.js +13 -16
- package/dist/core/managed-assets/managed-assets-manifest.js +9 -8
- package/dist/core/pipeline-internals/runtime-core.js +3 -3
- package/dist/core/providers/glm/glm-52-profile.js +46 -0
- package/dist/core/providers/glm/glm-52-request.js +11 -2
- package/dist/core/providers/glm/glm-direct-run.js +1 -0
- package/dist/core/providers/glm/glm-mad-launch.js +3 -2
- package/dist/core/providers/glm/glm-profile-resolver.js +69 -4
- package/dist/core/providers/glm/naruto/glm-naruto-command.js +2 -1
- package/dist/core/team-live.js +2 -2
- package/dist/core/version.js +1 -1
- package/dist/scripts/agent-role-config-repair-check.js +5 -3
- package/dist/scripts/codex-native-reference-cache-check.js +8 -1
- package/dist/scripts/doctor-codex-startup-repair-check.js +21 -0
- package/dist/scripts/doctor-fixes-codex-app-fast-ui-check.js +6 -2
- package/dist/scripts/naruto-shadow-clone-swarm-check.js +11 -3
- package/dist/scripts/release-readiness-report.js +1 -1
- package/dist/scripts/sks-3-1-6-directive-check-lib.js +11 -0
- package/package.json +1 -1
|
@@ -154,7 +154,7 @@ export function buildAllFeaturesSelftest(registry, opts = {}) {
|
|
|
154
154
|
checkRow('native_agent_intake_contract_present', registry.features.some((feature) => feature.id === 'route-native-agent-intake'), ['route-native-agent-intake']),
|
|
155
155
|
checkRow('cli_agent_fixture_pass', registry.features.some((feature) => feature.id === 'cli-agent' && feature.fixture?.status === 'pass' && feature.fixture.expected_artifacts?.some((artifact) => expectedArtifactPath(artifact).includes('agent-proof-evidence'))), ['cli-agent']),
|
|
156
156
|
checkRow('agent_proof_evidence_contract_present', registry.features.some((feature) => feature.id === 'proof-agent-evidence'), ['proof-agent-evidence']),
|
|
157
|
-
checkRow('agent_lease_policy_present', registry.features.some((feature) => feature.id === 'route-native-agent-intake' && /
|
|
157
|
+
checkRow('agent_lease_policy_present', registry.features.some((feature) => feature.id === 'route-native-agent-intake' && /bounded workspace-write/i.test(JSON.stringify(feature.contract || {})) && /lease/i.test(JSON.stringify(feature.contract || {}))), ['route-native-agent-intake']),
|
|
158
158
|
checkRow('fixture_pass_threshold', (fixturesSummary.counts.pass || 0) >= 90, [`pass=${fixturesSummary.counts.pass || 0}`]),
|
|
159
159
|
checkRow('fixture_not_required_ceiling', (fixturesSummary.counts.not_required || 0) <= 16, [`not_required=${fixturesSummary.counts.not_required || 0}`]),
|
|
160
160
|
checkRow('fixture_mock_blocked_zero', (fixturesSummary.counts.blocked || 0) === 0, [`blocked=${fixturesSummary.counts.blocked || 0}`]),
|
|
@@ -628,7 +628,7 @@ function nativeAgentIntakeFeature() {
|
|
|
628
628
|
aliases: ['sks team "task" [executor:5 reviewer:6 user:1]'],
|
|
629
629
|
category: 'proof-route',
|
|
630
630
|
maturity: 'stable',
|
|
631
|
-
intent: 'Default
|
|
631
|
+
intent: 'Default bounded workspace-write native multi-session agent intake before serious route implementation.',
|
|
632
632
|
voxel_triwiki_integration: 'native agent findings are TriWiki-ready and can require image voxel evidence for visual routes',
|
|
633
633
|
completion_proof_integration: 'Completion Proof evidence.agents records agent_count, route, leases, no-overlap proof, cleanup, proof graph, and dynamic effort policy',
|
|
634
634
|
known_gaps: ['real speedup claims require runtime timing/eval evidence; mock/static timing is not enough'],
|
|
@@ -636,7 +636,7 @@ function nativeAgentIntakeFeature() {
|
|
|
636
636
|
input: 'serious route mission, route collaboration fixture, or explicit sks agent run',
|
|
637
637
|
output: 'agents/agent-central-ledger.json, agents/agent-task-board.json, agents/agent-leases.json, agents/agent-no-overlap-proof.json, agents/agent-session-cleanup.json, agents/agent-proof-evidence.json, agents/agent-effort-policy.json',
|
|
638
638
|
state: 'mission-local native agent artifacts',
|
|
639
|
-
safety: '
|
|
639
|
+
safety: 'bounded workspace-write analysis agents; central leases prevent overlapping write scopes; parent owns integration',
|
|
640
640
|
proof: 'evidence.agents required for serious native route proof',
|
|
641
641
|
voxel: 'visual agent records image voxel requirements without satisfying visual evidence by itself',
|
|
642
642
|
tests: 'unit, integration, e2e route fixtures, native release gate scripts',
|
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.
|
|
8
|
+
export const PACKAGE_VERSION = '4.7.0';
|
|
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() {
|
|
@@ -125,8 +125,9 @@ export function classifyHarnessPayload(root, payload = {}, policy = {}) {
|
|
|
125
125
|
const command = extractCommand(payload);
|
|
126
126
|
const writeIntent = hasWriteIntent(toolName, command, hay);
|
|
127
127
|
const maintenance = classifyMaintenanceCommand(command || hay);
|
|
128
|
-
const
|
|
129
|
-
const
|
|
128
|
+
const writeTargets = extractWriteTargets(root, payload, strings, command);
|
|
129
|
+
const protectedMatches = findProtectedMatches(root, writeTargets.length ? writeTargets : strings, policy);
|
|
130
|
+
const packageEdit = writeIntent && packageManifestEditDetected(writeTargets, hay);
|
|
130
131
|
const block = maintenance.block || packageEdit || (writeIntent && protectedMatches.length > 0);
|
|
131
132
|
const reasons = [];
|
|
132
133
|
if (maintenance.block)
|
|
@@ -135,7 +136,7 @@ export function classifyHarnessPayload(root, payload = {}, policy = {}) {
|
|
|
135
136
|
reasons.push('package_manifest_sneakoscope_edit_blocked');
|
|
136
137
|
if (writeIntent && protectedMatches.length)
|
|
137
138
|
reasons.push('protected_harness_path_write_blocked');
|
|
138
|
-
return { block, reasons: [...new Set(reasons)], matches: protectedMatches, writeIntent, toolName, command };
|
|
139
|
+
return { block, reasons: [...new Set(reasons)], matches: protectedMatches, writeIntent, toolName, command, writeTargets };
|
|
139
140
|
}
|
|
140
141
|
export async function collectHarnessFingerprints(root) {
|
|
141
142
|
const out = {};
|
|
@@ -196,6 +197,91 @@ function collectPayloadStrings(obj, out = [], depth = 0) {
|
|
|
196
197
|
}
|
|
197
198
|
return out;
|
|
198
199
|
}
|
|
200
|
+
function extractWriteTargets(root, payload = {}, strings = [], command = '') {
|
|
201
|
+
const targets = new Set();
|
|
202
|
+
for (const value of collectPathFieldStrings(payload))
|
|
203
|
+
addWriteTarget(root, targets, value);
|
|
204
|
+
for (const text of [command, ...strings]) {
|
|
205
|
+
const s = String(text || '');
|
|
206
|
+
for (const match of s.matchAll(/^\*\*\*\s+(?:Update|Add|Delete)\s+File:\s+(.+)$/gmi))
|
|
207
|
+
addWriteTarget(root, targets, match[1]);
|
|
208
|
+
for (const match of s.matchAll(/^\*\*\*\s+Move to:\s+(.+)$/gmi))
|
|
209
|
+
addWriteTarget(root, targets, match[1]);
|
|
210
|
+
for (const match of s.matchAll(/>{1,2}\s*(['"]?)([^\s;&|'"`]+)\1/g))
|
|
211
|
+
addWriteTarget(root, targets, match[2]);
|
|
212
|
+
collectShellCommandTargets(root, targets, s);
|
|
213
|
+
}
|
|
214
|
+
return [...targets].sort();
|
|
215
|
+
}
|
|
216
|
+
function collectPathFieldStrings(obj, out = [], depth = 0) {
|
|
217
|
+
if (depth > 8 || obj == null)
|
|
218
|
+
return out;
|
|
219
|
+
if (Array.isArray(obj)) {
|
|
220
|
+
for (const value of obj)
|
|
221
|
+
collectPathFieldStrings(value, out, depth + 1);
|
|
222
|
+
return out;
|
|
223
|
+
}
|
|
224
|
+
if (typeof obj !== 'object')
|
|
225
|
+
return out;
|
|
226
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
227
|
+
const normalized = String(key || '').toLowerCase();
|
|
228
|
+
if (typeof value === 'string' && /^(?:path|file|filename|target|destination|dest|to|from|cwd|workdir|file_path|target_path|output_path|artifact_path)$/.test(normalized))
|
|
229
|
+
out.push(value);
|
|
230
|
+
collectPathFieldStrings(value, out, depth + 1);
|
|
231
|
+
}
|
|
232
|
+
return out;
|
|
233
|
+
}
|
|
234
|
+
function collectShellCommandTargets(root, targets, text) {
|
|
235
|
+
const words = shellWords(text);
|
|
236
|
+
for (let i = 0; i < words.length; i += 1) {
|
|
237
|
+
const word = words[i] || '';
|
|
238
|
+
if (!/^(?:rm|rmdir|mv|cp|touch|mkdir|chmod|chown)$/.test(word))
|
|
239
|
+
continue;
|
|
240
|
+
for (let j = i + 1; j < words.length; j += 1) {
|
|
241
|
+
const candidate = words[j] || '';
|
|
242
|
+
if (!candidate || candidate.startsWith('-'))
|
|
243
|
+
continue;
|
|
244
|
+
if (/^(?:&&|\|\||;|\|)$/.test(candidate))
|
|
245
|
+
break;
|
|
246
|
+
if (/^(?:rm|rmdir|mv|cp|touch|mkdir|chmod|chown|git|npm|node|python\d?)$/.test(candidate) && j > i + 1)
|
|
247
|
+
break;
|
|
248
|
+
addWriteTarget(root, targets, candidate);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
function shellWords(text) {
|
|
253
|
+
return [...String(text || '').matchAll(/"([^"]*)"|'([^']*)'|([^\s]+)/g)].map((match) => match[1] || match[2] || match[3]).filter(Boolean);
|
|
254
|
+
}
|
|
255
|
+
function addWriteTarget(root, targets, value) {
|
|
256
|
+
const normalized = normalizeTargetPath(root, value);
|
|
257
|
+
if (normalized)
|
|
258
|
+
targets.add(normalized);
|
|
259
|
+
}
|
|
260
|
+
function normalizeTargetPath(root, value) {
|
|
261
|
+
let s = String(value || '').trim();
|
|
262
|
+
if (!s)
|
|
263
|
+
return '';
|
|
264
|
+
s = s.replace(/^['"`<]+|['"`>,]+$/g, '');
|
|
265
|
+
if (!s || /^\$[\w{]/.test(s) || /^[A-Z_][A-Z0-9_]*=/.test(s))
|
|
266
|
+
return '';
|
|
267
|
+
if (/^(?:--?|&&|\|\||;|\|)$/.test(s))
|
|
268
|
+
return '';
|
|
269
|
+
s = s.replace(/\\/g, '/');
|
|
270
|
+
if (s.startsWith('a/') || s.startsWith('b/'))
|
|
271
|
+
s = s.slice(2);
|
|
272
|
+
if (s.startsWith('./'))
|
|
273
|
+
s = s.slice(2);
|
|
274
|
+
const rootNorm = String(root || '').replace(/\\/g, '/').replace(/\/$/, '');
|
|
275
|
+
if (rootNorm && s.startsWith(`${rootNorm}/`))
|
|
276
|
+
s = s.slice(rootNorm.length + 1);
|
|
277
|
+
return s.replace(/\/$/, '');
|
|
278
|
+
}
|
|
279
|
+
function packageManifestEditDetected(writeTargets, hay) {
|
|
280
|
+
const hasPackageTarget = writeTargets.length > 0
|
|
281
|
+
? writeTargets.some((target) => /(^|\/)(?:package\.json|package-lock\.json|pnpm-lock\.yaml|yarn\.lock)$/.test(target))
|
|
282
|
+
: /\b(package\.json|package-lock\.json|pnpm-lock\.yaml|yarn\.lock)\b/i.test(hay);
|
|
283
|
+
return hasPackageTarget && /\bsneakoscope\b/i.test(hay);
|
|
284
|
+
}
|
|
199
285
|
function hasWriteIntent(toolName, command, hay) {
|
|
200
286
|
if (/\b(apply_patch|edit|write|create|delete|remove|rename|str_replace|file_write|fs_write)\b/i.test(toolName))
|
|
201
287
|
return true;
|
package/dist/core/init.js
CHANGED
|
@@ -69,8 +69,7 @@ export function hasTopLevelCodexModeLock(text = '') {
|
|
|
69
69
|
const lines = String(text || '').split('\n');
|
|
70
70
|
const firstTable = lines.findIndex((x) => /^\s*\[.+\]\s*$/.test(x));
|
|
71
71
|
const top = (firstTable === -1 ? lines : lines.slice(0, firstTable)).join('\n');
|
|
72
|
-
|
|
73
|
-
return (Boolean(model) && model !== 'gpt-5.5') || /^model_reasoning_effort\s*=/m.test(top);
|
|
72
|
+
return /^model\s*=/.test(top) || /^model_reasoning_effort\s*=/m.test(top);
|
|
74
73
|
}
|
|
75
74
|
export function hasDeprecatedCodexHooksFeatureFlag(text = '') {
|
|
76
75
|
const lines = String(text || '').split('\n');
|
|
@@ -590,10 +589,8 @@ export async function initProject(root, opts = {}) {
|
|
|
590
589
|
let next = removeLegacyTopLevelCodexModeLocks(String(existingContent || '').trimEnd());
|
|
591
590
|
next = removeTomlTableKey(next, 'notice', 'fast_default_opt_out');
|
|
592
591
|
next = removeTomlTableKey(next, 'features', 'codex_hooks');
|
|
593
|
-
//
|
|
594
|
-
//
|
|
595
|
-
// is intentionally left untouched at the top level.
|
|
596
|
-
next = upsertTopLevelTomlStringIfAbsent(next, 'model', 'gpt-5.5');
|
|
592
|
+
// Model/reasoning defaults live in profiles. Leaving them out of top-level config
|
|
593
|
+
// keeps Codex Desktop's native model and speed selectors available.
|
|
597
594
|
next = upsertTopLevelTomlBooleanIfAbsent(next, 'suppress_unstable_features_warning', true);
|
|
598
595
|
// Codex App feature flags: SET-IF-ABSENT only (see note above).
|
|
599
596
|
for (const flag of MANAGED_CODEX_FEATURE_FLAGS) {
|
|
@@ -704,7 +701,7 @@ export async function initProject(root, opts = {}) {
|
|
|
704
701
|
return lines.filter((line, index) => {
|
|
705
702
|
if (index >= end)
|
|
706
703
|
return true;
|
|
707
|
-
return !/^\s*model_reasoning_effort\s*=/.test(line);
|
|
704
|
+
return !/^\s*(?:model|model_reasoning_effort)\s*=/.test(line);
|
|
708
705
|
}).join('\n').replace(/^\n+/, '').replace(/\n{3,}/g, '\n\n');
|
|
709
706
|
}
|
|
710
707
|
function removeTopLevelTomlKeyIfValue(text = '', key = '', value = '') {
|
|
@@ -814,11 +811,11 @@ export async function initProject(root, opts = {}) {
|
|
|
814
811
|
// with `url is not supported for stdio`. Remote is also the transport the doctor
|
|
815
812
|
// migrates everyone to (local stdio can block interactive Codex launch).
|
|
816
813
|
{ table: 'mcp_servers.context7', text: context7ConfigToml('remote').trim(), preserveExisting: true },
|
|
817
|
-
{ table: 'agents.native_agent', text: agentConfigBlock('native_agent', '
|
|
818
|
-
{ table: 'agents.team_consensus', text: agentConfigBlock('team_consensus', 'SKS planning/debate agent.', './agents/team-consensus.toml', ['Consensus', 'Atlas']) },
|
|
814
|
+
{ table: 'agents.native_agent', text: agentConfigBlock('native_agent', 'SKS native agent with bounded write capability.', './agents/native-agent-intake.toml', ['Analysis', 'Mapper']) },
|
|
815
|
+
{ table: 'agents.team_consensus', text: agentConfigBlock('team_consensus', 'SKS planning/debate agent with bounded write capability.', './agents/team-consensus.toml', ['Consensus', 'Atlas']) },
|
|
819
816
|
{ table: 'agents.implementation_worker', text: agentConfigBlock('implementation_worker', 'SKS bounded implementation worker.', './agents/implementation-worker.toml', ['Builder', 'Mason']) },
|
|
820
|
-
{ table: 'agents.db_safety_reviewer', text: agentConfigBlock('db_safety_reviewer', '
|
|
821
|
-
{ table: 'agents.qa_reviewer', text: agentConfigBlock('qa_reviewer', '
|
|
817
|
+
{ table: 'agents.db_safety_reviewer', text: agentConfigBlock('db_safety_reviewer', 'DB safety reviewer with bounded write capability.', './agents/db-safety-reviewer.toml', ['Sentinel', 'Ledger']) },
|
|
818
|
+
{ table: 'agents.qa_reviewer', text: agentConfigBlock('qa_reviewer', 'QA reviewer with bounded write capability.', './agents/qa-reviewer.toml', ['Verifier', 'Reviewer']) },
|
|
822
819
|
// NOTE: SKS config profiles are NO LONGER emitted as `[profiles.sks-*]` tables.
|
|
823
820
|
// Codex 0.134+ deprecated config-profile tables / the `profile=` selector (warns at
|
|
824
821
|
// startup) in favor of per-file `$CODEX_HOME/<name>.config.toml` overlays loaded by
|
|
@@ -1304,12 +1301,12 @@ async function removeDirIfEmpty(dir) {
|
|
|
1304
1301
|
}
|
|
1305
1302
|
async function installCodexAgents(root) {
|
|
1306
1303
|
const agents = {
|
|
1307
|
-
'analysis-scout.toml': `name = "analysis_scout"\ndescription = "
|
|
1308
|
-
'native-agent-intake.toml': `name = "native_agent"\ndescription = "
|
|
1309
|
-
'team-consensus.toml': `name = "team_consensus"\ndescription = "Planning and debate specialist for SKS Team mode. Maps options, constraints, role-persona risks, and proposes the agreed objective before implementation starts."\nmodel = "gpt-5.5"\nmodel_reasoning_effort = "high"\nsandbox_mode = "
|
|
1304
|
+
'analysis-scout.toml': `name = "analysis_scout"\ndescription = "SKS analysis scout with bounded write capability retained for stale Codex agent-role config repair."\nmodel = "gpt-5.5"\nmodel_reasoning_effort = "low"\nsandbox_mode = "workspace-write"\ndeveloper_instructions = """\nYou are an SKS analysis scout.\nOnly edit bounded files assigned by the parent orchestrator; otherwise inspect only and return concise source-backed findings.\n"""\n`,
|
|
1305
|
+
'native-agent-intake.toml': `name = "native_agent"\ndescription = "Team native agent with bounded write capability. Maps one independent repo/docs/tests/API/risk/user-friction slice and can produce patch-envelope work when assigned."\nmodel = "gpt-5.5"\nmodel_reasoning_effort = "low"\nsandbox_mode = "workspace-write"\ndeveloper_instructions = """\nYou are an SKS Team native agent.\nOnly edit bounded files assigned by the parent orchestrator.\nOwn exactly one investigation or implementation slice assigned by the parent orchestrator.\nUse the mission roster or worker inbox model and model_reasoning_effort when the host exposes it: simple bounded work may use gpt-5.4-mini, ordinary tool work uses gpt-5.5 low, and knowledge/research/safety/release work uses gpt-5.5 high.\nMap relevant source files, docs, tests, APIs, DB or safety risks, UX friction, and likely implementation boundaries.\nReturn concise source-backed claims suitable for team-analysis.md and TriWiki ingestion: claim, source path, evidence hash or quoted anchor, risk, confidence, and recommended implementation slice.\nDo not debate the final plan. Implement only when the assigned slice includes write paths.\nAlso return a concise LIVE_EVENT line that the parent can record with sks team event.\n"""\n`,
|
|
1306
|
+
'team-consensus.toml': `name = "team_consensus"\ndescription = "Planning and debate specialist for SKS Team mode with bounded write capability. Maps options, constraints, role-persona risks, and proposes the agreed objective before implementation starts."\nmodel = "gpt-5.5"\nmodel_reasoning_effort = "high"\nsandbox_mode = "workspace-write"\ndeveloper_instructions = """\nYou are the SKS Team consensus specialist.\nOnly edit bounded files assigned by the parent orchestrator.\nUse the mission roster model and model_reasoning_effort when the host exposes them; planning normally uses gpt-5.5 low or high depending on risk.\nMap the affected code paths, viable approaches, constraints, risks, and acceptance criteria.\nRun the debate as role-persona synthesis: final users are low-context, self-interested, stubborn, and inconvenience-averse; executors are capable developers; reviewers are strict.\nArgue for the smallest coherent objective that can be handed to a fresh executor_N development team.\nPlan for at least ${MIN_TEAM_REVIEWER_LANES} independent reviewer/QA validation lanes before integration or final.\nReturn: recommended objective, rejected alternatives, implementation slices, required reviewers, user-friction risks, and unresolved risks.\nAlso return a concise LIVE_EVENT line that the parent can record with sks team event.\n"""\n`,
|
|
1310
1307
|
'implementation-worker.toml': `name = "implementation_worker"\ndescription = "Implementation specialist for SKS Team mode. Owns one bounded write set and coordinates with other executor_N workers."\nmodel = "gpt-5.5"\nmodel_reasoning_effort = "medium"\nsandbox_mode = "workspace-write"\ndeveloper_instructions = """\nYou are an SKS Team executor/developer in the fresh development bundle.\nYou are not alone in the codebase. Other executor_N workers may be editing disjoint files.\nUse the mission roster or worker inbox reasoning_effort when the host exposes it; simple bounded changes can use low, tool-heavy implementation medium, and safety/release/DB work high.\nOnly edit the files or module slice assigned to you.\nDo not revert or overwrite edits made by others.\nRead local patterns first, make the smallest correct change, avoid adding user friction, run focused verification for your slice, and report changed paths plus evidence.\nDo not create fallback implementation code, substitute behavior, mock behavior, or compatibility shims unless the user or sealed decision contract explicitly requested them.\nRespect all SKS hooks, DB safety rules, no-question run rules, and H-Proof completion gates.\nAlso return concise LIVE_EVENT lines for started, blocked, changed files, verification, and final result so the parent can record them.\n"""\n`,
|
|
1311
|
-
'db-safety-reviewer.toml': `name = "db_safety_reviewer"\ndescription = "
|
|
1312
|
-
'qa-reviewer.toml': `name = "qa_reviewer"\ndescription = "Strict
|
|
1308
|
+
'db-safety-reviewer.toml': `name = "db_safety_reviewer"\ndescription = "Database safety reviewer with bounded write capability for SQL, migrations, Supabase, RLS, destructive-operation risk, and rollback safety."\nmodel = "gpt-5.5"\nmodel_reasoning_effort = "high"\nsandbox_mode = "workspace-write"\ndeveloper_instructions = """\nYou are a database safety reviewer.\nOnly edit bounded files assigned by the parent orchestrator. Never execute destructive commands.\nReview migrations, SQL, Supabase RLS, transaction boundaries, rollback safety, and MCP database tool usage.\nBlock DROP, TRUNCATE, mass DELETE/UPDATE, db reset, db push, project deletion, branch reset/merge/delete, RLS disabling, and live execute_sql writes.\nReturn concrete risks, exact file references, and required fixes.\nAlso return a concise LIVE_EVENT line that the parent can record with sks team event.\n"""\n`,
|
|
1309
|
+
'qa-reviewer.toml': `name = "qa_reviewer"\ndescription = "Strict verification reviewer with bounded write capability for correctness, regressions, missing tests, user friction, and final evidence."\nmodel = "gpt-5.5"\nmodel_reasoning_effort = "high"\nsandbox_mode = "workspace-write"\ndeveloper_instructions = """\nYou are an SKS Team strict reviewer.\nOnly edit bounded files assigned by the parent orchestrator.\nReview correctness, edge cases, regression risk, missing tests, unsupported claims, and whether the final evidence proves the claimed outcome.\nTeam review must cover at least ${MIN_TEAM_REVIEWER_LANES} independent reviewer/QA validation lanes before integration or final; flag missing review lane evidence.\nAlso evaluate practical friction from the viewpoint of a stubborn, low-context final user who dislikes inconvenience.\nPrioritize concrete findings with file references and focused verification suggestions.\nFlag any unrequested fallback implementation code, substitute behavior, mock behavior, or compatibility shim as a blocking finding unless the user or sealed decision contract explicitly requested it.\nReturn no findings if the implementation is sound, and clearly list residual test gaps.\nAlso return a concise LIVE_EVENT line that the parent can record with sks team event.\n"""\n`
|
|
1313
1310
|
};
|
|
1314
1311
|
const dir = path.join(root, '.codex', 'agents');
|
|
1315
1312
|
await ensureDir(dir);
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { REQUIRED_CODEX_MODEL } from '../codex-model-guard.js';
|
|
2
2
|
export const MANAGED_ASSET_SCHEMA_VERSION = 1;
|
|
3
|
-
export const MANAGED_ASSET_VERSION = '4.
|
|
3
|
+
export const MANAGED_ASSET_VERSION = '4.7.0';
|
|
4
4
|
export const MANAGED_ASSET_MARKER = 'SKS-MANAGED-ASSET';
|
|
5
5
|
export const MANAGED_AGENT_ROLES = Object.freeze([
|
|
6
|
-
role('sks-explorer', 'analysis-scout.toml', 'analysis_scout', '
|
|
7
|
-
role('sks-
|
|
6
|
+
role('sks-explorer', 'analysis-scout.toml', 'analysis_scout', 'SKS analysis scout for bounded read/write slices retained for stale Codex agent-role config repair.', 'workspace-write', ['analysis-scout', 'analysis_scout']),
|
|
7
|
+
role('sks-native-agent', 'native-agent-intake.toml', 'native_agent', 'SKS native agent for bounded read/write intake slices.', 'workspace-write', ['native-agent-intake', 'native_agent']),
|
|
8
|
+
role('sks-planner', 'team-consensus.toml', 'team_consensus', 'Planning and debate specialist for bounded SKS Team mode write sets.', 'workspace-write', ['team-consensus', 'team_consensus']),
|
|
8
9
|
role('sks-implementer', 'implementation-worker.toml', 'implementation_worker', 'Implementation specialist for bounded SKS Team write sets.', 'workspace-write', ['implementation-worker', 'implementation_worker']),
|
|
9
|
-
role('sks-checker', 'qa-reviewer.toml', 'qa_reviewer', 'Strict
|
|
10
|
-
role('sks-release-verifier', 'sks-release-verifier.toml', 'sks_release_verifier', '
|
|
11
|
-
role('sks-zellij-ui-verifier', 'sks-zellij-ui-verifier.toml', 'sks_zellij_ui_verifier', '
|
|
12
|
-
role('sks-codex-probe-verifier', 'sks-codex-probe-verifier.toml', 'sks_codex_probe_verifier', '
|
|
13
|
-
role('db-safety-reviewer', 'db-safety-reviewer.toml', 'db_safety_reviewer', '
|
|
10
|
+
role('sks-checker', 'qa-reviewer.toml', 'qa_reviewer', 'Strict verification reviewer for correctness, regressions, and final evidence with bounded write capability.', 'workspace-write', ['qa-reviewer', 'qa_reviewer']),
|
|
11
|
+
role('sks-release-verifier', 'sks-release-verifier.toml', 'sks_release_verifier', 'Release verifier for repository, docs, tests, API, and risk slices with bounded write capability.', 'workspace-write', ['release-verifier']),
|
|
12
|
+
role('sks-zellij-ui-verifier', 'sks-zellij-ui-verifier.toml', 'sks_zellij_ui_verifier', 'Zellij UI verifier for session, pane, layout, and terminal evidence with bounded write capability.', 'workspace-write', ['zellij-ui-verifier']),
|
|
13
|
+
role('sks-codex-probe-verifier', 'sks-codex-probe-verifier.toml', 'sks_codex_probe_verifier', 'Codex probe verifier for CLI, App, SDK, MCP, and native capability evidence with bounded write capability.', 'workspace-write', ['codex-probe-verifier']),
|
|
14
|
+
role('db-safety-reviewer', 'db-safety-reviewer.toml', 'db_safety_reviewer', 'Database safety reviewer for SQL, migrations, Supabase, and rollback safety with bounded write capability.', 'workspace-write', ['db-safety-reviewer', 'db_safety_reviewer'])
|
|
14
15
|
]);
|
|
15
16
|
export const MANAGED_SKILLS = Object.freeze([
|
|
16
17
|
'loop',
|
|
@@ -213,7 +213,7 @@ export function validatePipelinePlan(plan = {}) {
|
|
|
213
213
|
issues.push('ssot_guard_stage');
|
|
214
214
|
if (!plan.next_actions?.length)
|
|
215
215
|
issues.push('next_actions');
|
|
216
|
-
if (plan.agent_intake?.required && !plan.stages?.some((stage) => stage.id === AGENT_INTAKE_STAGE_ID && stage.agent_count === AGENT_COUNT && stage.read_only ===
|
|
216
|
+
if (plan.agent_intake?.required && !plan.stages?.some((stage) => stage.id === AGENT_INTAKE_STAGE_ID && stage.agent_count === AGENT_COUNT && stage.read_only === false && /bounded workspace-write/i.test(String(stage.write_policy || '')) && /lease/i.test(String(stage.write_policy || ''))))
|
|
217
217
|
issues.push('agent_intake_stage');
|
|
218
218
|
return { ok: issues.length === 0, issues };
|
|
219
219
|
}
|
|
@@ -970,7 +970,7 @@ async function materializeAutoSealedTeam(root, id, dir, route, task, contractHas
|
|
|
970
970
|
team_runtime: teamRuntimePlanMetadata(),
|
|
971
971
|
phases: [
|
|
972
972
|
{ id: 'team_roster_confirmation', goal: `Materialize the Team roster from default SKS counts or explicit user counts, write team-roster.json, and surface role counts ${formatRoleCounts(roleCounts)}.`, agents: ['parent_orchestrator'], output: 'team-roster.json' },
|
|
973
|
-
{ id: 'native_agent_intake', goal: `Read TriWiki context, then run exactly ${roster.bundle_size}
|
|
973
|
+
{ id: 'native_agent_intake', goal: `Read TriWiki context, then run exactly ${roster.bundle_size} bounded workspace-write native_agent_N sessions in parallel. ${fromChatImgRequired ? `From-Chat-IMG active: ${CODEX_COMPUTER_USE_ONLY_POLICY}` : 'From-Chat-IMG inactive: do not assume ordinary images are chat captures.'} Native agents may edit only parent-assigned lease paths and parent integration owns final changes.`, agents: roster.analysis_team.map((agent) => agent.id), max_parallel_native_sessions: agentSessions, write_policy: 'bounded workspace-write leases; parent-owned integration' },
|
|
974
974
|
{ id: 'triwiki_refresh', goal: `Refresh or pack TriWiki and run ${triwikiContextTracking().validate_command}.`, agents: ['parent_orchestrator'], output: '.sneakoscope/wiki/context-pack.json' },
|
|
975
975
|
{ id: 'ssot_guard', goal: ssotGuardPolicyText(), agents: ['parent_orchestrator'], output: SSOT_GUARD_ARTIFACT },
|
|
976
976
|
{ id: 'planning_debate', goal: 'Run read-only planning debate, map constraints and implementation slices, then seal one objective.', agents: roster.debate_team.map((agent) => agent.id) },
|
|
@@ -1063,7 +1063,7 @@ async function prepareTeam(root, route, task, required, opts = {}) {
|
|
|
1063
1063
|
team_runtime: teamRuntimePlanMetadata(),
|
|
1064
1064
|
phases: [
|
|
1065
1065
|
{ id: 'team_roster_confirmation', goal: `Before any implementation, materialize the Team roster from default SKS counts or explicit user counts, write team-roster.json, and surface role counts ${formatRoleCounts(roleCounts)}. Implementation cannot be considered complete unless team-gate.json has team_roster_confirmed=true.`, agents: ['parent_orchestrator'], output: 'team-roster.json' },
|
|
1066
|
-
{ id: 'native_agent_intake', goal: `Before native agent intake, read TriWiki context. ${fromChatImgRequired ? `From-Chat-IMG active: for web/browser/webapp targets require Codex Chrome Extension readiness first; for native Mac/non-web surfaces use Codex Computer Use visual inspection when available. List every visible customer request, match every screenshot image region to attachments, write ${FROM_CHAT_IMG_COVERAGE_ARTIFACT}, ${FROM_CHAT_IMG_CHECKLIST_ARTIFACT}, and ${FROM_CHAT_IMG_TEMP_TRIWIKI_ARTIFACT}, then require scoped QA-LOOP evidence in ${FROM_CHAT_IMG_QA_LOOP_ARTIFACT} after the customer-request work is done. ${CODEX_WEB_VERIFICATION_POLICY} ${CODEX_COMPUTER_USE_ONLY_POLICY}` : `From-Chat-IMG inactive: do not assume ordinary images are chat captures. ${CODEX_WEB_VERIFICATION_POLICY} ${CODEX_COMPUTER_USE_ONLY_POLICY}`} Run exactly ${roster.bundle_size}
|
|
1066
|
+
{ id: 'native_agent_intake', goal: `Before native agent intake, read TriWiki context. ${fromChatImgRequired ? `From-Chat-IMG active: for web/browser/webapp targets require Codex Chrome Extension readiness first; for native Mac/non-web surfaces use Codex Computer Use visual inspection when available. List every visible customer request, match every screenshot image region to attachments, write ${FROM_CHAT_IMG_COVERAGE_ARTIFACT}, ${FROM_CHAT_IMG_CHECKLIST_ARTIFACT}, and ${FROM_CHAT_IMG_TEMP_TRIWIKI_ARTIFACT}, then require scoped QA-LOOP evidence in ${FROM_CHAT_IMG_QA_LOOP_ARTIFACT} after the customer-request work is done. ${CODEX_WEB_VERIFICATION_POLICY} ${CODEX_COMPUTER_USE_ONLY_POLICY}` : `From-Chat-IMG inactive: do not assume ordinary images are chat captures. ${CODEX_WEB_VERIFICATION_POLICY} ${CODEX_COMPUTER_USE_ONLY_POLICY}`} Run exactly ${roster.bundle_size} bounded workspace-write native_agent_N sessions in parallel, using the full available session budget without exceeding ${agentSessions}. Split repo/docs/tests/API/user-flow/risk investigation into independent slices, hydrate relevant low-trust claims from source, record source-backed findings, and edit only parent-assigned lease paths.`, agents: roster.analysis_team.map((agent) => agent.id), max_parallel_native_sessions: agentSessions, write_policy: 'bounded workspace-write leases; parent-owned integration' },
|
|
1067
1067
|
{ id: 'triwiki_refresh', goal: `Parent orchestrator updates Team analysis artifacts, then runs ${triwikiContextTracking().refresh_command} or ${triwikiContextTracking().pack_command}, prunes with ${triwikiContextTracking().prune_command} when stale/oversized wiki state would pollute handoffs, and runs ${triwikiContextTracking().validate_command} so the next stage uses current TriWiki context.`, agents: ['parent_orchestrator'], output: '.sneakoscope/wiki/context-pack.json' },
|
|
1068
1068
|
{ id: 'ssot_guard', goal: ssotGuardPolicyText(), agents: ['parent_orchestrator'], output: SSOT_GUARD_ARTIFACT },
|
|
1069
1069
|
{ id: 'planning_debate', goal: `Before debate, read the refreshed TriWiki pack. Debate team of exactly ${roster.bundle_size} participants maps user inconvenience, options, constraints, affected files, DB/test risk, and tradeoffs while applying compact Hyperplan-derived lenses: challenge framing, subtract surface, demand evidence, test integration risk, and consider one simpler alternative. Hydrate low-trust claims from source.`, agents: roster.debate_team.map((agent) => agent.id) },
|
|
@@ -2,6 +2,48 @@ import { GLM_52_OPENROUTER_MODEL, GLM_MAD_MODE } from './glm-52-settings.js';
|
|
|
2
2
|
import { profileFromConst } from './glm-profile-resolver.js';
|
|
3
3
|
export const GLM_CODEX_APP_PROFILE_ID = 'sks/glm-5.2-mad';
|
|
4
4
|
export const GLM_CODEX_APP_PROFILE_LABEL = 'GLM 5.2 (MAD Speed / OpenRouter)';
|
|
5
|
+
export const GLM_CODEX_CONFIG_PROVIDER_ID = 'openrouter';
|
|
6
|
+
export const GLM_CODEX_CONFIG_PROFILE_ID = 'sks-glm-52-mad';
|
|
7
|
+
export const GLM_CODEX_SELECTABLE_REASONING_EFFORTS = [
|
|
8
|
+
'none',
|
|
9
|
+
'minimal',
|
|
10
|
+
'low',
|
|
11
|
+
'medium',
|
|
12
|
+
'high',
|
|
13
|
+
'xhigh',
|
|
14
|
+
];
|
|
15
|
+
export const GLM_CODEX_CONFIG_REASONING_PROFILES = [
|
|
16
|
+
{
|
|
17
|
+
id: GLM_CODEX_CONFIG_PROFILE_ID,
|
|
18
|
+
label: 'GLM 5.2 MAD Speed',
|
|
19
|
+
reasoning_effort: 'none',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
id: 'sks-glm-52-minimal',
|
|
23
|
+
label: 'GLM 5.2 Minimal',
|
|
24
|
+
reasoning_effort: 'minimal',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
id: 'sks-glm-52-low',
|
|
28
|
+
label: 'GLM 5.2 Low',
|
|
29
|
+
reasoning_effort: 'low',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
id: 'sks-glm-52-medium',
|
|
33
|
+
label: 'GLM 5.2 Medium',
|
|
34
|
+
reasoning_effort: 'medium',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
id: 'sks-glm-52-high',
|
|
38
|
+
label: 'GLM 5.2 High',
|
|
39
|
+
reasoning_effort: 'high',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
id: 'sks-glm-52-xhigh',
|
|
43
|
+
label: 'GLM 5.2 XHigh',
|
|
44
|
+
reasoning_effort: 'xhigh',
|
|
45
|
+
},
|
|
46
|
+
];
|
|
5
47
|
export function buildGlmCodexAppModelProfile() {
|
|
6
48
|
const speed = profileFromConst('speed');
|
|
7
49
|
return {
|
|
@@ -10,6 +52,10 @@ export function buildGlmCodexAppModelProfile() {
|
|
|
10
52
|
label: GLM_CODEX_APP_PROFILE_LABEL,
|
|
11
53
|
provider: 'openrouter',
|
|
12
54
|
model: GLM_52_OPENROUTER_MODEL,
|
|
55
|
+
codexConfigProvider: GLM_CODEX_CONFIG_PROVIDER_ID,
|
|
56
|
+
codexConfigProfile: GLM_CODEX_CONFIG_PROFILE_ID,
|
|
57
|
+
supportedReasoningEfforts: GLM_CODEX_SELECTABLE_REASONING_EFFORTS,
|
|
58
|
+
reasoningProfiles: GLM_CODEX_CONFIG_REASONING_PROFILES,
|
|
13
59
|
mode: GLM_MAD_MODE,
|
|
14
60
|
strictModelLock: true,
|
|
15
61
|
gptFallbackAllowed: false,
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { GLM_52_DEFAULT_REQUEST_SETTINGS, GLM_52_OPENROUTER_MODEL, clampGlm52MaxTokens } from './glm-52-settings.js';
|
|
2
2
|
import { buildDeepReasoningConfig, buildFastReasoningConfig } from './glm-reasoning-policy.js';
|
|
3
|
-
import { profileFromConst, resolveGlmProfileFromArgs } from './glm-profile-resolver.js';
|
|
3
|
+
import { profileFromConst, reasoningEffortFromGlmSlashModelArgs, resolveGlmProfileFromArgs } from './glm-profile-resolver.js';
|
|
4
4
|
export function buildGlm52Request(input) {
|
|
5
5
|
const profile = resolveInputProfile(input.profile, input.args, input.reasoningEffort);
|
|
6
6
|
if (profile.blockers.length) {
|
|
7
7
|
throw new Error(`GLM request profile blocked: ${profile.blockers.join(', ')}`);
|
|
8
8
|
}
|
|
9
9
|
const strictOrDeepEffort = profile.reasoning_effort || (input.reasoningEffort === 'high' || input.reasoningEffort === 'xhigh' ? input.reasoningEffort : undefined);
|
|
10
|
+
const selectedReasoningEffort = input.reasoningEffort || (input.args ? reasoningEffortFromGlmSlashModelArgs(input.args) || undefined : undefined);
|
|
10
11
|
const reasoning = profile.name === 'speed'
|
|
11
|
-
?
|
|
12
|
+
? buildSpeedReasoningConfig(selectedReasoningEffort, input.reasoningMeta)
|
|
12
13
|
: buildDeepReasoningConfig(strictOrDeepEffort || 'high');
|
|
13
14
|
if (profile.name === 'speed' && (reasoning.effort === 'high' || reasoning.effort === 'xhigh')) {
|
|
14
15
|
throw new Error(`GLM speed profile invariant violated: forbidden reasoning effort ${reasoning.effort}`);
|
|
@@ -62,4 +63,12 @@ function resolveInputProfile(profile, args, reasoningEffort) {
|
|
|
62
63
|
return profileFromConst('deep');
|
|
63
64
|
return profileFromConst(GLM_52_DEFAULT_REQUEST_SETTINGS.mode === 'mad-glm-speed' ? 'speed' : 'speed');
|
|
64
65
|
}
|
|
66
|
+
function buildSpeedReasoningConfig(reasoningEffort, reasoningMeta) {
|
|
67
|
+
if (reasoningEffort === 'none')
|
|
68
|
+
return { exclude: true };
|
|
69
|
+
if (reasoningEffort === 'minimal' || reasoningEffort === 'low' || reasoningEffort === 'medium') {
|
|
70
|
+
return { effort: reasoningEffort, exclude: true };
|
|
71
|
+
}
|
|
72
|
+
return buildFastReasoningConfig(reasoningMeta);
|
|
73
|
+
}
|
|
65
74
|
//# sourceMappingURL=glm-52-request.js.map
|
|
@@ -39,6 +39,7 @@ export async function runGlmDirectSpeedRun(input) {
|
|
|
39
39
|
controller.transition('request');
|
|
40
40
|
const request = buildGlm52Request({
|
|
41
41
|
profile: 'speed',
|
|
42
|
+
...(input.args ? { args: input.args } : {}),
|
|
42
43
|
messages: [
|
|
43
44
|
{ role: 'system', content: 'Return only <sks_patch>, <sks_need_context>, or <sks_blocked>. Use unified diff for patches.' },
|
|
44
45
|
{ role: 'user', content: JSON.stringify({ task: input.task, context }) }
|
|
@@ -45,7 +45,8 @@ export function buildMadGlmLaunchProfileNoWrite(args = []) {
|
|
|
45
45
|
model_reasoning_effort: effort,
|
|
46
46
|
service_tier: 'fast',
|
|
47
47
|
gpt_fallback_allowed: false,
|
|
48
|
-
writes_user_codex_config: false
|
|
48
|
+
writes_user_codex_config: false,
|
|
49
|
+
blockers: profile.blockers
|
|
49
50
|
};
|
|
50
51
|
}
|
|
51
52
|
export async function resolveMadGlmLaunchKey(env = process.env) {
|
|
@@ -111,7 +112,7 @@ export function buildMadGlmLaunchArtifact(input) {
|
|
|
111
112
|
real_codex_bin: input.wrapper.real_codex_bin,
|
|
112
113
|
raw_key_written_to_wrapper: false,
|
|
113
114
|
codex_args: profile.launch_args,
|
|
114
|
-
blockers: input.keyResolution.key ? [] : input.keyResolution.blockers,
|
|
115
|
+
blockers: [...profile.blockers, ...(input.keyResolution.key ? [] : input.keyResolution.blockers)],
|
|
115
116
|
warnings: input.keyResolution.warnings || []
|
|
116
117
|
};
|
|
117
118
|
}
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { readOption } from '../../../cli/args.js';
|
|
2
|
-
import { GLM_DEEP_MODE, GLM_DEEP_PROFILE, GLM_SPEED_MODE, GLM_SPEED_PROFILE, GLM_STRICT_MODE, GLM_STRICT_PROFILE, GLM_XHIGH_MODE, GLM_XHIGH_PROFILE } from './glm-52-settings.js';
|
|
2
|
+
import { GLM_DEEP_MODE, GLM_DEEP_PROFILE, GLM_52_OPENROUTER_MODEL, GLM_SPEED_MODE, GLM_SPEED_PROFILE, GLM_STRICT_MODE, GLM_STRICT_PROFILE, GLM_XHIGH_MODE, GLM_XHIGH_PROFILE } from './glm-52-settings.js';
|
|
3
3
|
export function resolveGlmProfileFromArgs(args = []) {
|
|
4
4
|
const list = args.map(String);
|
|
5
5
|
const exactProvider = readOption(list, '--exact-provider', null);
|
|
6
|
+
const slashSelection = parseGlmSlashModelSelection(list);
|
|
6
7
|
const providerBlockers = exactProvider && !isValidOpenRouterProviderSlug(exactProvider)
|
|
7
8
|
? [`invalid_openrouter_provider_slug:${exactProvider}`]
|
|
8
9
|
: [];
|
|
9
|
-
const base = list.includes('--xhigh')
|
|
10
|
+
const base = slashSelection.reasoning_effort === 'xhigh' || list.includes('--xhigh')
|
|
10
11
|
? profileFromConst('xhigh')
|
|
11
12
|
: list.includes('--strict')
|
|
12
13
|
? profileFromConst('strict')
|
|
13
|
-
: list.includes('--deep')
|
|
14
|
+
: slashSelection.reasoning_effort === 'high' || list.includes('--deep')
|
|
14
15
|
? profileFromConst('deep')
|
|
15
16
|
: profileFromConst('speed');
|
|
16
17
|
const provider = exactProvider && !providerBlockers.length
|
|
@@ -29,7 +30,64 @@ export function resolveGlmProfileFromArgs(args = []) {
|
|
|
29
30
|
return {
|
|
30
31
|
...base,
|
|
31
32
|
provider,
|
|
32
|
-
blockers: providerBlockers
|
|
33
|
+
blockers: [...providerBlockers, ...slashSelection.blockers]
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export function reasoningEffortFromGlmSlashModelArgs(args = []) {
|
|
37
|
+
return parseGlmSlashModelSelection(args).reasoning_effort;
|
|
38
|
+
}
|
|
39
|
+
export function stripGlmSlashModelArgs(args = []) {
|
|
40
|
+
const consumed = new Set(parseGlmSlashModelSelection(args).consumed_indexes);
|
|
41
|
+
return args.map(String).filter((_arg, index) => !consumed.has(index));
|
|
42
|
+
}
|
|
43
|
+
export function parseGlmSlashModelSelection(args = []) {
|
|
44
|
+
const list = args.map(String);
|
|
45
|
+
const consumed = new Set();
|
|
46
|
+
const values = [];
|
|
47
|
+
for (let i = 0; i < list.length; i += 1) {
|
|
48
|
+
const arg = list[i] || '';
|
|
49
|
+
if (arg === '/model') {
|
|
50
|
+
consumed.add(i);
|
|
51
|
+
for (let j = i + 1; j < list.length && values.length < 2; j += 1) {
|
|
52
|
+
const candidate = list[j] || '';
|
|
53
|
+
if (candidate.startsWith('--') || candidate.startsWith('/'))
|
|
54
|
+
break;
|
|
55
|
+
consumed.add(j);
|
|
56
|
+
values.push(candidate);
|
|
57
|
+
if (values.length === 1 && isSelectableGlmReasoningEffort(candidate.trim().toLowerCase()))
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
const inline = arg.match(/^\/model(?::|=)(.+)$/)?.[1];
|
|
63
|
+
if (inline) {
|
|
64
|
+
consumed.add(i);
|
|
65
|
+
values.push(...inline.split(/[,:]/).map((value) => value.trim()).filter(Boolean).slice(0, 2));
|
|
66
|
+
break;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
let model = null;
|
|
70
|
+
let reasoning = null;
|
|
71
|
+
const blockers = [];
|
|
72
|
+
for (const value of values) {
|
|
73
|
+
const normalized = value.trim().toLowerCase();
|
|
74
|
+
if (isSelectableGlmReasoningEffort(normalized)) {
|
|
75
|
+
reasoning = normalized;
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
if (!model) {
|
|
79
|
+
model = value;
|
|
80
|
+
if (!isAllowedGlmSlashModel(value))
|
|
81
|
+
blockers.push(`glm_slash_model_mismatch:${value}`);
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
blockers.push(`glm_slash_model_unrecognized:${value}`);
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
model,
|
|
88
|
+
reasoning_effort: reasoning,
|
|
89
|
+
consumed_indexes: [...consumed].sort((a, b) => a - b),
|
|
90
|
+
blockers
|
|
33
91
|
};
|
|
34
92
|
}
|
|
35
93
|
export function profileFromConst(name) {
|
|
@@ -101,4 +159,11 @@ export function profileFromConst(name) {
|
|
|
101
159
|
export function isValidOpenRouterProviderSlug(value) {
|
|
102
160
|
return /^(?!.*(?:^|\/)\.\.?(?:\/|$))[a-z0-9][a-z0-9._-]{0,63}(?:\/[a-z0-9][a-z0-9._-]{0,63}){0,3}$/i.test(value);
|
|
103
161
|
}
|
|
162
|
+
function isSelectableGlmReasoningEffort(value) {
|
|
163
|
+
return value === 'none' || value === 'minimal' || value === 'low' || value === 'medium' || value === 'high' || value === 'xhigh';
|
|
164
|
+
}
|
|
165
|
+
function isAllowedGlmSlashModel(value) {
|
|
166
|
+
const normalized = value.trim().toLowerCase();
|
|
167
|
+
return normalized === GLM_52_OPENROUTER_MODEL || normalized === 'glm-5.2' || normalized === 'glm5.2';
|
|
168
|
+
}
|
|
104
169
|
//# sourceMappingURL=glm-profile-resolver.js.map
|
|
@@ -2,6 +2,7 @@ import { flag, readOption, positionalArgs } from '../../../../cli/args.js';
|
|
|
2
2
|
import { printJson } from '../../../../cli/output.js';
|
|
3
3
|
import { runGlmNarutoMission } from './glm-naruto-orchestrator.js';
|
|
4
4
|
import { runGlmNarutoBench } from './glm-naruto-bench.js';
|
|
5
|
+
import { stripGlmSlashModelArgs } from '../glm-profile-resolver.js';
|
|
5
6
|
export async function glmNarutoCommand(args = []) {
|
|
6
7
|
if (flag(args, '--bench')) {
|
|
7
8
|
// --compare is an alias; the benchmark always compares direct vs Naruto.
|
|
@@ -24,7 +25,7 @@ export async function glmNarutoCommand(args = []) {
|
|
|
24
25
|
}
|
|
25
26
|
return result;
|
|
26
27
|
}
|
|
27
|
-
const positional = positionalArgs(args).map(String);
|
|
28
|
+
const positional = positionalArgs(stripGlmSlashModelArgs(args)).map(String);
|
|
28
29
|
const task = positional.join(' ').trim();
|
|
29
30
|
if (!task && !flag(args, '--repair') && !flag(args, '--status')) {
|
|
30
31
|
const result = {
|
package/dist/core/team-live.js
CHANGED
|
@@ -417,14 +417,14 @@ export function buildTeamRoster(roleCounts = DEFAULT_TEAM_ROLE_COUNTS, opts = {}
|
|
|
417
417
|
const debateReviewers = numberedAgents('debate_reviewer', counts.reviewer, 'Strict debate reviewer: applies validator/researcher lenses to correctness, safety, DB risk, tests, regressions, and unsupported assumptions.', 'reviewer', { prompt });
|
|
418
418
|
const debateExecutorPool = numberedAgents('debate_executor', bundleSize, 'Capable developer voice in debate: applies skeptic/architect lenses to implementation shape, ownership boundaries, dependencies, coupling, and risks before coding starts.', 'executor', { prompt });
|
|
419
419
|
const debateTeam = composeDebateTeam({ users: debateUsers, planners: debatePlanners, reviewers: debateReviewers, executors: debateExecutorPool, bundleSize });
|
|
420
|
-
const nativeAgents = numberedAgents('native_agent', bundleSize, '
|
|
420
|
+
const nativeAgents = numberedAgents('native_agent', bundleSize, 'Bounded native agent: quickly maps one independent slice of repo/docs/tests/API risk, records source paths and evidence, returns TriWiki-ready findings, and edits only parent-assigned lease paths.', 'analysis', { prompt });
|
|
421
421
|
const developmentExecutors = numberedAgents('executor', bundleSize, 'Capable developer executor: owns one disjoint implementation slice and coordinates without reverting others.', 'executor', { prompt });
|
|
422
422
|
const validationReviewers = numberedAgents('reviewer', counts.reviewer, 'Strict reviewer: adversarial about correctness, safety, DB risk, tests, regressions, and unsupported claims.', 'reviewer', { prompt });
|
|
423
423
|
const validationUsers = numberedAgents('user', counts.user, 'Impatient final user acceptance persona: low-context, self-interested, stubborn, dislikes inconvenience, rejects clever work that feels annoying.', 'user', { prompt });
|
|
424
424
|
return {
|
|
425
425
|
role_counts: counts,
|
|
426
426
|
bundle_size: bundleSize,
|
|
427
|
-
analysis_team: nativeAgents.map((agent) => ({ ...agent, write_policy: '
|
|
427
|
+
analysis_team: nativeAgents.map((agent) => ({ ...agent, write_policy: 'bounded workspace-write native analysis lease', output: 'team-analysis.md' })),
|
|
428
428
|
debate_team: debateTeam,
|
|
429
429
|
development_team: developmentExecutors.map((agent) => ({ ...agent, write_policy: 'workspace-write with explicit ownership' })),
|
|
430
430
|
validation_team: [
|
package/dist/core/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const PACKAGE_VERSION = '4.
|
|
1
|
+
export const PACKAGE_VERSION = '4.7.0';
|
|
2
2
|
//# sourceMappingURL=version.js.map
|
|
@@ -16,18 +16,20 @@ fs.writeFileSync(path.join(staleRoot, '.codex', 'agents', 'analysis-scout.toml')
|
|
|
16
16
|
const stalePlan = await mod.repairAgentRoleConfigs({ root: staleRoot, apply: false, codexHome: path.join(staleRoot, 'codex-home') });
|
|
17
17
|
const staleRepair = await mod.repairAgentRoleConfigs({ root: staleRoot, apply: true, codexHome: path.join(staleRoot, 'codex-home') });
|
|
18
18
|
const repairedText = fs.readFileSync(path.join(staleRoot, '.codex', 'agents', 'analysis-scout.toml'), 'utf8');
|
|
19
|
+
const createdText = fs.readFileSync(analysisScout, 'utf8');
|
|
19
20
|
const report = {
|
|
20
21
|
schema: 'sks.agent-role-config-repair-check.v1',
|
|
21
22
|
plan_ok: plan.ok === true && plan.missing.includes('analysis-scout.toml'),
|
|
22
23
|
repair_ok: repair.ok === true,
|
|
23
24
|
analysis_scout_created: fs.existsSync(analysisScout),
|
|
24
|
-
created_matches_model:
|
|
25
|
+
created_matches_model: createdText.includes('model = "gpt-5.5"'),
|
|
26
|
+
created_write_capable: createdText.includes('sandbox_mode = "workspace-write"') && !createdText.includes('Do not edit files.'),
|
|
25
27
|
stale_detected: stalePlan.stale.includes('analysis-scout.toml'),
|
|
26
|
-
stale_repaired: staleRepair.repaired.includes('.codex/agents/analysis-scout.toml') && repairedText.includes('name = "analysis_scout"') && repairedText.includes('model = "gpt-5.5"'),
|
|
28
|
+
stale_repaired: staleRepair.repaired.includes('.codex/agents/analysis-scout.toml') && repairedText.includes('name = "analysis_scout"') && repairedText.includes('model = "gpt-5.5"') && repairedText.includes('sandbox_mode = "workspace-write"'),
|
|
27
29
|
warnings_suppressed: repair.warnings_suppressed === true,
|
|
28
30
|
artifact_written: fs.existsSync(path.join(root, '.sneakoscope', 'reports', 'agent-role-config-repair.json'))
|
|
29
31
|
};
|
|
30
|
-
const ok = report.plan_ok && report.repair_ok && report.analysis_scout_created && report.created_matches_model && report.stale_detected && report.stale_repaired && report.warnings_suppressed && report.artifact_written;
|
|
32
|
+
const ok = report.plan_ok && report.repair_ok && report.analysis_scout_created && report.created_matches_model && report.created_write_capable && report.stale_detected && report.stale_repaired && report.warnings_suppressed && report.artifact_written;
|
|
31
33
|
assertGate(ok, 'doctor --fix must repair missing SKS-owned agent role configs', report);
|
|
32
34
|
emitGate('agent:role-config-repair', report);
|
|
33
35
|
//# sourceMappingURL=agent-role-config-repair-check.js.map
|