sneakoscope 0.6.37 → 0.6.38
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/package.json +1 -1
- package/src/cli/main.mjs +75 -9
- package/src/core/fsx.mjs +1 -1
- package/src/core/init.mjs +6 -106
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ Core value: repetition resistance. SKS records release traps, stale command surf
|
|
|
7
7
|
|
|
8
8
|
## AI Answer Snapshot
|
|
9
9
|
|
|
10
|
-
Package: `sneakoscope`. CLI: `sks` or `sneakoscope`. `sks setup` prepares
|
|
10
|
+
Package: `sneakoscope`. CLI: `sks` or `sneakoscope`. Global install seeds `$HOME/.agents/skills` so Codex App can show `$sks`, `$team`, `$qa-loop`, and the other SKS dollar routes before a project is initialized. `sks setup` prepares project hooks/state and installs Codex CLI when missing; open Codex App so first-party MCP/plugin tools reach CLI sessions.
|
|
11
11
|
|
|
12
12
|
```bash
|
|
13
13
|
npm i -g sneakoscope
|
|
@@ -53,7 +53,7 @@ UI/UX reads `design.md` first. If missing, `design-system-builder` creates it fr
|
|
|
53
53
|
|
|
54
54
|
## Codex App
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
Global install creates user-level `$` skills; run `sks setup` once inside each project to add project hooks/skills plus `.sneakoscope/` state. Team status is mirrored to `team-live.md`, `team-transcript.jsonl`, and `sks team watch latest`.
|
|
57
57
|
|
|
58
58
|
Implementation/code-changing prompts default to Team orchestration: parallel analysis scouts, TriWiki refresh/validate, debate/consensus, then fresh parallel executors. Answer-only, DFix, Help, Wiki maintenance, and safety-specific routes stay lightweight.
|
|
59
59
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sneakoscope",
|
|
3
3
|
"displayName": "ㅅㅋㅅ",
|
|
4
|
-
"version": "0.6.
|
|
4
|
+
"version": "0.6.38",
|
|
5
5
|
"description": "Sneakoscope Codex: database-safe Codex CLI/App harness with Team, Ralph, AutoResearch, TriWiki, and Honest Mode.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"homepage": "https://github.com/mandarange/Sneakoscope-Codex#readme",
|
package/src/cli/main.mjs
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
+
import os from 'node:os';
|
|
2
3
|
import fsp from 'node:fs/promises';
|
|
3
4
|
import readline from 'node:readline/promises';
|
|
4
5
|
import { stdin as input, stdout as output } from 'node:process';
|
|
5
6
|
import { projectRoot, readJson, writeJsonAtomic, writeTextAtomic, appendJsonlBounded, nowIso, exists, ensureDir, tmpdir, packageRoot, dirSize, formatBytes, which, runProcess, PACKAGE_VERSION } from '../core/fsx.mjs';
|
|
6
|
-
import { initProject, normalizeInstallScope, sksCommandPrefix } from '../core/init.mjs';
|
|
7
|
+
import { initProject, installSkills, normalizeInstallScope, sksCommandPrefix } from '../core/init.mjs';
|
|
7
8
|
import { getCodexInfo, runCodexExec } from '../core/codex-adapter.mjs';
|
|
8
9
|
import { createMission, loadMission, findLatestMission, missionDir, setCurrent, stateFile } from '../core/mission.mjs';
|
|
9
10
|
import { buildQuestionSchema, writeQuestions } from '../core/questions.mjs';
|
|
@@ -209,6 +210,11 @@ async function postinstall() {
|
|
|
209
210
|
else if (context7Install.status === 'codex_missing') console.log('Context7 MCP: Codex CLI missing. Install @openai/codex or set SKS_CODEX_BIN, then run `sks context7 setup --scope global` or `sks setup` in a project.');
|
|
210
211
|
else if (context7Install.status === 'skipped') console.log(`Context7 MCP: skipped (${context7Install.reason}).`);
|
|
211
212
|
else if (context7Install.status === 'failed') console.log(`Context7 MCP: auto setup failed. Run \`sks context7 setup --scope global\` or \`sks setup\`. ${context7Install.error || ''}`.trim());
|
|
213
|
+
const globalSkills = await ensureGlobalCodexSkillsDuringInstall();
|
|
214
|
+
if (globalSkills.status === 'installed') console.log(`Codex App global $ skills: installed in ${globalSkills.root} (${globalSkills.installed_count} skills).`);
|
|
215
|
+
else if (globalSkills.status === 'partial') console.log(`Codex App global $ skills: partial in ${globalSkills.root}; missing ${globalSkills.missing_skills.join(', ')}. Run \`sks doctor --fix\`.`);
|
|
216
|
+
else if (globalSkills.status === 'skipped') console.log(`Codex App global $ skills: skipped (${globalSkills.reason}).`);
|
|
217
|
+
else if (globalSkills.status === 'failed') console.log(`Codex App global $ skills: auto setup failed. Run \`sks doctor --fix\`. ${globalSkills.error || ''}`.trim());
|
|
212
218
|
const appSetup = await ensureCodexAppProjectDuringInstall(installRoot, { shim });
|
|
213
219
|
if (appSetup.status === 'installed') console.log(`Codex App project setup: installed in ${appSetup.root} (${appSetup.install_scope}; canonical picker skills include ${appSetup.aliases.join(', ')}).`);
|
|
214
220
|
else if (appSetup.status === 'partial') console.log(`Codex App project setup: repaired with missing skill warning (${appSetup.missing_skills.join(', ')}). Run \`sks doctor --fix\`.`);
|
|
@@ -323,6 +329,20 @@ async function ensureGlobalContext7DuringInstall() {
|
|
|
323
329
|
return { status: 'failed', error: `${add.stderr || add.stdout || 'codex mcp add failed'}`.trim() };
|
|
324
330
|
}
|
|
325
331
|
|
|
332
|
+
async function ensureGlobalCodexSkillsDuringInstall(opts = {}) {
|
|
333
|
+
if (process.env.SKS_SKIP_POSTINSTALL_GLOBAL_SKILLS === '1' && !opts.force) return { status: 'skipped', reason: 'SKS_SKIP_POSTINSTALL_GLOBAL_SKILLS=1' };
|
|
334
|
+
const home = opts.home || process.env.HOME || os.homedir();
|
|
335
|
+
if (!home) return { status: 'skipped', reason: 'home directory unavailable' };
|
|
336
|
+
const root = globalCodexSkillsRoot(home);
|
|
337
|
+
try {
|
|
338
|
+
const install = await installSkills(home);
|
|
339
|
+
const skills = await checkRequiredSkills(home, root);
|
|
340
|
+
return { status: skills.ok ? 'installed' : 'partial', root, installed_count: install.installed_skills.length, removed_aliases: install.removed_agent_skill_aliases, missing_skills: skills.missing };
|
|
341
|
+
} catch (err) {
|
|
342
|
+
return { status: 'failed', root, error: err.message };
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
|
|
326
346
|
async function ensureRelatedCliTools(args = []) {
|
|
327
347
|
const skip = flag(args, '--skip-cli-tools') || process.env.SKS_SKIP_CLI_TOOLS === '1';
|
|
328
348
|
const codex = await ensureCodexCliTool({ skip });
|
|
@@ -1046,9 +1066,15 @@ async function codexAppHelp(args = []) {
|
|
|
1046
1066
|
const action = args[0] || 'help';
|
|
1047
1067
|
if (action === 'check' || action === 'status') {
|
|
1048
1068
|
const status = await codexAppIntegrationStatus();
|
|
1049
|
-
|
|
1069
|
+
const skills = await codexAppSkillReadiness();
|
|
1070
|
+
const readiness = { ...status, ok: status.ok && skills.ok, runtime_ok: status.ok, skills };
|
|
1071
|
+
if (flag(args, '--json')) return console.log(JSON.stringify(readiness, null, 2));
|
|
1050
1072
|
console.log(formatCodexAppStatus(status, { includeRaw: flag(args, '--verbose') }));
|
|
1051
|
-
|
|
1073
|
+
console.log('');
|
|
1074
|
+
console.log(`Project $ skills: ${skills.project.ok ? 'ok' : `missing ${skills.project.missing.length}`} ${skills.project.root}`);
|
|
1075
|
+
console.log(`Global $ skills: ${skills.global.ok ? 'ok' : `missing ${skills.global.missing.length}`} ${skills.global.root}`);
|
|
1076
|
+
if (!skills.ok) console.log('Run: sks setup, or reinstall/repair with npm i -g sneakoscope && sks doctor --fix');
|
|
1077
|
+
if (!readiness.ok) process.exitCode = 1;
|
|
1052
1078
|
return;
|
|
1053
1079
|
}
|
|
1054
1080
|
if (action === 'open') {
|
|
@@ -1059,10 +1085,15 @@ async function codexAppHelp(args = []) {
|
|
|
1059
1085
|
return;
|
|
1060
1086
|
}
|
|
1061
1087
|
const status = await codexAppIntegrationStatus();
|
|
1088
|
+
const skills = await codexAppSkillReadiness();
|
|
1062
1089
|
console.log(`ㅅㅋㅅ App Usage
|
|
1063
1090
|
|
|
1064
1091
|
${formatCodexAppStatus(status)}
|
|
1065
1092
|
|
|
1093
|
+
Dollar-command skills:
|
|
1094
|
+
Project: ${skills.project.ok ? 'ok' : `missing ${skills.project.missing.length}`} ${skills.project.root}
|
|
1095
|
+
Global: ${skills.global.ok ? 'ok' : `missing ${skills.global.missing.length}`} ${skills.global.root}
|
|
1096
|
+
|
|
1066
1097
|
Run once in the project:
|
|
1067
1098
|
sks setup
|
|
1068
1099
|
|
|
@@ -1619,6 +1650,9 @@ async function setup(args) {
|
|
|
1619
1650
|
const cliTools = await ensureRelatedCliTools(args);
|
|
1620
1651
|
const globalCommand = await globalSksCommand();
|
|
1621
1652
|
const res = await initProject(root, { force: flag(args, '--force'), installScope, globalCommand, localOnly });
|
|
1653
|
+
const globalSkills = localOnly
|
|
1654
|
+
? { status: 'skipped', reason: '--local-only', root: globalCodexSkillsRoot() }
|
|
1655
|
+
: await ensureGlobalCodexSkillsDuringInstall({ force: flag(args, '--force') });
|
|
1622
1656
|
const install = await installStatus(root, installScope, { globalCommand });
|
|
1623
1657
|
const versioningInfo = await versioningStatus(root);
|
|
1624
1658
|
const appRuntime = await codexAppIntegrationStatus();
|
|
@@ -1632,11 +1666,13 @@ async function setup(args) {
|
|
|
1632
1666
|
config: path.join(root, '.codex', 'config.toml'),
|
|
1633
1667
|
hooks: hooksPath,
|
|
1634
1668
|
skills: path.join(root, '.agents', 'skills'),
|
|
1669
|
+
global_skills: globalSkills.root,
|
|
1635
1670
|
agents: path.join(root, '.codex', 'agents'),
|
|
1636
1671
|
quick_reference: path.join(root, '.codex', 'SNEAKOSCOPE.md'),
|
|
1637
1672
|
agents_rules: path.join(root, 'AGENTS.md')
|
|
1638
1673
|
},
|
|
1639
1674
|
codex_app_runtime: appRuntime,
|
|
1675
|
+
global_skills: globalSkills,
|
|
1640
1676
|
created: res.created,
|
|
1641
1677
|
versioning: versioningInfo,
|
|
1642
1678
|
local_only: localOnly,
|
|
@@ -1651,6 +1687,7 @@ async function setup(args) {
|
|
|
1651
1687
|
console.log(`Version: ${versioningInfo.enabled ? (versioningInfo.hook_installed ? 'auto-bump enabled' : 'auto-bump hook missing') : 'not enabled'}${versioningInfo.package_version ? ` (${versioningInfo.package_version})` : ''}`);
|
|
1652
1688
|
if (localOnly) console.log('Git: local-only (.git/info/exclude; user AGENTS preserved, SKS managed block refreshed)');
|
|
1653
1689
|
console.log(`Codex App: .codex/config.toml, .codex/hooks.json, .agents/skills, .codex/agents, .codex/SNEAKOSCOPE.md`);
|
|
1690
|
+
console.log(`Global $: ${globalSkills.status === 'installed' ? 'ok' : globalSkills.status} ${globalSkills.root || ''}`.trimEnd());
|
|
1654
1691
|
console.log(`App tools: ${appRuntime.ok ? 'ok' : 'needs setup'} Codex App=${appRuntime.app.installed ? 'ok' : 'missing'} Browser Use=${appRuntime.mcp.has_browser_use ? 'ok' : 'missing'} Computer Use=${appRuntime.mcp.has_computer_use ? 'ok' : 'missing'}`);
|
|
1655
1692
|
console.log(`Prompt: intent-first routing, $Answer fact-check route, $DFix ultralight design/content route, Context7 gate`);
|
|
1656
1693
|
console.log(`Skills: .agents/skills`);
|
|
@@ -1706,10 +1743,12 @@ async function doctor(args) {
|
|
|
1706
1743
|
: null;
|
|
1707
1744
|
let conflictScan = await scanHarnessConflicts(root);
|
|
1708
1745
|
let repairApplied = false;
|
|
1746
|
+
let globalSkillsRepair = null;
|
|
1709
1747
|
if (flag(args, '--fix') && !conflictScan.hard_block) {
|
|
1710
1748
|
const fixScope = requestedScope || 'global';
|
|
1711
1749
|
const existingManifest = await readJson(path.join(root, '.sneakoscope', 'manifest.json'), null);
|
|
1712
1750
|
await initProject(root, { installScope: fixScope, globalCommand: await globalSksCommand(), localOnly: flag(args, '--local-only') || Boolean(existingManifest?.git?.local_only), force: true, repair: true });
|
|
1751
|
+
if (!flag(args, '--local-only')) globalSkillsRepair = await ensureGlobalCodexSkillsDuringInstall({ force: true });
|
|
1713
1752
|
repairApplied = true;
|
|
1714
1753
|
conflictScan = await scanHarnessConflicts(root);
|
|
1715
1754
|
}
|
|
@@ -1726,6 +1765,7 @@ async function doctor(args) {
|
|
|
1726
1765
|
const context7Status = await checkContext7(root);
|
|
1727
1766
|
const appRuntime = await codexAppIntegrationStatus({ codex });
|
|
1728
1767
|
const skillStatus = await checkRequiredSkills(root);
|
|
1768
|
+
const globalSkillStatus = await checkRequiredSkills(null, globalCodexSkillsRoot());
|
|
1729
1769
|
const guardStatus = await harnessGuardStatus(root);
|
|
1730
1770
|
const versioningInfo = await versioningStatus(root);
|
|
1731
1771
|
const codexApp = {
|
|
@@ -1733,6 +1773,7 @@ async function doctor(args) {
|
|
|
1733
1773
|
hooks: { ok: await exists(path.join(root, '.codex', 'hooks.json')) },
|
|
1734
1774
|
versioning: versioningInfo,
|
|
1735
1775
|
skills: skillStatus,
|
|
1776
|
+
global_skills: globalSkillStatus,
|
|
1736
1777
|
agents: { ok: await exists(path.join(root, '.codex', 'agents')) },
|
|
1737
1778
|
quick_reference: { ok: await exists(path.join(root, '.codex', 'SNEAKOSCOPE.md')) },
|
|
1738
1779
|
agents_rules: { ok: await exists(path.join(root, 'AGENTS.md')) }
|
|
@@ -1740,7 +1781,7 @@ async function doctor(args) {
|
|
|
1740
1781
|
const result = {
|
|
1741
1782
|
node: { ok: nodeOk, version: process.version }, root, codex, rust,
|
|
1742
1783
|
install,
|
|
1743
|
-
repair: { applied: repairApplied, blocked_by_other_harness: flag(args, '--fix') && conflictScan.hard_block },
|
|
1784
|
+
repair: { applied: repairApplied, global_skills: globalSkillsRepair, blocked_by_other_harness: flag(args, '--fix') && conflictScan.hard_block },
|
|
1744
1785
|
harness_conflicts: {
|
|
1745
1786
|
ok: conflictScan.ok,
|
|
1746
1787
|
hard_block: conflictScan.hard_block,
|
|
@@ -1755,14 +1796,15 @@ async function doctor(args) {
|
|
|
1755
1796
|
versioning: versioningInfo,
|
|
1756
1797
|
db_guard: { ok: dbPolicyExists && dbScan.ok, policy: dbPolicyExists ? await loadDbSafetyPolicy(root) : null, scan: dbScan },
|
|
1757
1798
|
hooks: { ok: await exists(path.join(root, '.codex', 'hooks.json')) },
|
|
1758
|
-
skills:
|
|
1799
|
+
skills: skillStatus,
|
|
1800
|
+
global_skills: globalSkillStatus,
|
|
1759
1801
|
codex_app: {
|
|
1760
1802
|
...codexApp,
|
|
1761
1803
|
ok: codexApp.config.ok && codexApp.hooks.ok && codexApp.skills.ok && codexApp.agents.ok && codexApp.quick_reference.ok && codexApp.agents_rules.ok
|
|
1762
1804
|
},
|
|
1763
1805
|
package: { bytes: pkgBytes, human: formatBytes(pkgBytes) }, storage
|
|
1764
1806
|
};
|
|
1765
|
-
result.ready = !result.harness_conflicts.hard_block && nodeOk && Boolean(codex.bin) && install.ok && result.sneakoscope.ok && result.context7.ok && appRuntime.ok && result.harness_guard.ok && result.versioning.ok && result.db_guard.ok && result.codex_app.ok && result.skills.ok;
|
|
1807
|
+
result.ready = !result.harness_conflicts.hard_block && nodeOk && Boolean(codex.bin) && install.ok && result.sneakoscope.ok && result.context7.ok && appRuntime.ok && result.harness_guard.ok && result.versioning.ok && result.db_guard.ok && result.codex_app.ok && result.skills.ok && result.global_skills.ok;
|
|
1766
1808
|
if (result.harness_conflicts.hard_block) process.exitCode = 1;
|
|
1767
1809
|
if (flag(args, '--json')) return console.log(JSON.stringify(result, null, 2));
|
|
1768
1810
|
console.log('ㅅㅋㅅ Doctor\n');
|
|
@@ -1772,6 +1814,7 @@ async function doctor(args) {
|
|
|
1772
1814
|
console.log(`Install: ${install.ok ? 'ok' : 'missing'} ${install.scope} (${install.command_prefix})`);
|
|
1773
1815
|
console.log(`Conflicts: ${result.harness_conflicts.hard_block ? 'blocked' : 'ok'} ${result.harness_conflicts.conflicts.length} finding(s)`);
|
|
1774
1816
|
if (repairApplied) console.log('Repair: regenerated SKS managed files from the installed package template');
|
|
1817
|
+
if (globalSkillsRepair) console.log(`Global $ repair: ${globalSkillsRepair.status} ${globalSkillsRepair.root || ''}`.trimEnd());
|
|
1775
1818
|
if (flag(args, '--fix') && result.harness_conflicts.hard_block) console.log('Repair: skipped because another Codex harness needs human-approved removal first');
|
|
1776
1819
|
console.log(`Rust acc.: ${rust.available ? rust.version : 'optional-missing'}`);
|
|
1777
1820
|
console.log(`State: ${result.sneakoscope.ok ? 'ok' : 'missing .sneakoscope'}`);
|
|
@@ -1783,6 +1826,7 @@ async function doctor(args) {
|
|
|
1783
1826
|
console.log(`Hooks: ${result.hooks.ok ? 'ok' : 'missing .codex/hooks.json'}`);
|
|
1784
1827
|
console.log(`Codex App: ${result.codex_app.ok ? 'ok' : 'missing app files'} .codex/config.toml .codex/hooks.json .agents/skills .codex/agents .codex/SNEAKOSCOPE.md`);
|
|
1785
1828
|
console.log(`Skills: ${result.skills.ok ? 'ok' : `missing ${result.skills.missing.length} skill(s)`}`);
|
|
1829
|
+
console.log(`Global $: ${result.global_skills.ok ? 'ok' : `missing ${result.global_skills.missing.length} skill(s)`} ${result.global_skills.root}`);
|
|
1786
1830
|
console.log(`Package: ${result.package.human}`);
|
|
1787
1831
|
console.log(`Storage: ${storage.total_human || '0 B'}`);
|
|
1788
1832
|
console.log(`Ready: ${result.ready ? 'yes' : 'no'}`);
|
|
@@ -1795,19 +1839,31 @@ async function doctor(args) {
|
|
|
1795
1839
|
if (!result.harness_guard.ok) console.log('Harness guard failed. Run: sks setup from a real terminal, then sks guard check.');
|
|
1796
1840
|
if (!result.versioning.ok) console.log('Versioning hook missing. Run: sks versioning hook, or sks doctor --fix.');
|
|
1797
1841
|
if (!result.skills.ok) console.log(`Missing skills: ${result.skills.missing.join(', ')}. Run: sks setup`);
|
|
1842
|
+
if (!result.global_skills.ok) console.log(`Missing global $ skills: ${result.global_skills.missing.join(', ')}. Run: npm i -g sneakoscope, or sks setup from a non-local-only run.`);
|
|
1798
1843
|
if (!result.ready && !flag(args, '--fix')) console.log('Run: sks doctor --fix');
|
|
1799
1844
|
}
|
|
1800
1845
|
|
|
1801
|
-
async function checkRequiredSkills(root) {
|
|
1846
|
+
async function checkRequiredSkills(root, skillRoot = path.join(root, '.agents', 'skills')) {
|
|
1802
1847
|
const expected = Array.from(new Set([
|
|
1803
1848
|
...DOLLAR_SKILL_NAMES,
|
|
1804
1849
|
...RECOMMENDED_SKILLS
|
|
1805
1850
|
])).sort();
|
|
1806
1851
|
const missing = [];
|
|
1807
1852
|
for (const name of expected) {
|
|
1808
|
-
if (!(await exists(path.join(
|
|
1853
|
+
if (!(await exists(path.join(skillRoot, name, 'SKILL.md')))) missing.push(name);
|
|
1809
1854
|
}
|
|
1810
|
-
return { ok: missing.length === 0, expected, missing };
|
|
1855
|
+
return { ok: missing.length === 0, root: skillRoot, expected, missing };
|
|
1856
|
+
}
|
|
1857
|
+
|
|
1858
|
+
async function codexAppSkillReadiness(root = null) {
|
|
1859
|
+
root ||= await projectRoot();
|
|
1860
|
+
const project = await checkRequiredSkills(root);
|
|
1861
|
+
const global = await checkRequiredSkills(null, globalCodexSkillsRoot());
|
|
1862
|
+
return { ok: project.ok || global.ok, project, global };
|
|
1863
|
+
}
|
|
1864
|
+
|
|
1865
|
+
function globalCodexSkillsRoot(home = process.env.HOME || os.homedir()) {
|
|
1866
|
+
return path.join(home, '.agents', 'skills');
|
|
1811
1867
|
}
|
|
1812
1868
|
|
|
1813
1869
|
async function init(args) {
|
|
@@ -2339,6 +2395,11 @@ async function selftest() {
|
|
|
2339
2395
|
if (postinstallSetup.code !== 0) throw new Error(`selftest failed: postinstall setup exited ${postinstallSetup.code}: ${postinstallSetup.stderr}`);
|
|
2340
2396
|
if (await exists(path.join(postinstallSetupTmp, '.agents', 'skills', 'agent-team', 'SKILL.md'))) throw new Error('selftest failed: postinstall installed deprecated agent-team fallback skill');
|
|
2341
2397
|
if (!String(postinstallSetup.stdout || '').includes('Codex App project setup: installed')) throw new Error('selftest failed: postinstall did not report automatic Codex App setup');
|
|
2398
|
+
if (!String(postinstallSetup.stdout || '').includes('Codex App global $ skills: installed')) throw new Error('selftest failed: postinstall did not report automatic global Codex App skills');
|
|
2399
|
+
for (const { command } of DOLLAR_COMMANDS) {
|
|
2400
|
+
const skillName = command.slice(1).toLowerCase();
|
|
2401
|
+
if (!(await exists(path.join(postinstallSetupTmp, 'home', '.agents', 'skills', skillName, 'SKILL.md')))) throw new Error(`selftest failed: postinstall global ${command} skill not installed`);
|
|
2402
|
+
}
|
|
2342
2403
|
const guardBlocked = await checkHarnessModification(tmp, { tool_name: 'apply_patch', command: '*** Update File: .agents/skills/team/SKILL.md\n+tamper\n' });
|
|
2343
2404
|
if (guardBlocked.action !== 'block') throw new Error('selftest failed: harness guard allowed skill tampering');
|
|
2344
2405
|
const setupBlocked = await checkHarnessModification(tmp, { command: 'sks setup --force' });
|
|
@@ -2454,6 +2515,11 @@ async function selftest() {
|
|
|
2454
2515
|
const shimDir = path.join(shimTmp, 'bin');
|
|
2455
2516
|
const shimResult = await ensureSksCommandDuringInstall({ force: true, pathEnv: shimDir, home: shimTmp, target: path.join(packageRoot(), 'bin', 'sks.mjs'), nodeBin: process.execPath });
|
|
2456
2517
|
if (shimResult.status !== 'created' || !(await exists(path.join(shimDir, process.platform === 'win32' ? 'sks.cmd' : 'sks')))) throw new Error('selftest failed: sks command shim not created');
|
|
2518
|
+
const globalSkillsTmp = tmpdir();
|
|
2519
|
+
const globalSkillsResult = await ensureGlobalCodexSkillsDuringInstall({ force: true, home: globalSkillsTmp });
|
|
2520
|
+
if (globalSkillsResult.status !== 'installed') throw new Error(`selftest failed: global Codex App skills not installed: ${globalSkillsResult.status}`);
|
|
2521
|
+
const globalSkillStatus = await checkRequiredSkills(globalSkillsTmp, path.join(globalSkillsTmp, '.agents', 'skills'));
|
|
2522
|
+
if (!globalSkillStatus.ok) throw new Error(`selftest failed: global Codex App skills missing: ${globalSkillStatus.missing.join(', ')}`);
|
|
2457
2523
|
const codexSkillMirrorExists = await exists(path.join(tmp, '.codex', 'skills', 'research-discovery', 'SKILL.md'));
|
|
2458
2524
|
if (codexSkillMirrorExists) throw new Error('selftest failed: generated .codex/skills mirror still installed');
|
|
2459
2525
|
const codexAppSkillExists = await exists(path.join(tmp, '.agents', 'skills', 'research-discovery', 'SKILL.md'));
|
package/src/core/fsx.mjs
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
|
|
|
8
|
-
export const PACKAGE_VERSION = '0.6.
|
|
8
|
+
export const PACKAGE_VERSION = '0.6.38';
|
|
9
9
|
export const DEFAULT_PROCESS_TAIL_BYTES = 256 * 1024;
|
|
10
10
|
export const DEFAULT_PROCESS_TIMEOUT_MS = 30 * 60 * 1000;
|
|
11
11
|
|
package/src/core/init.mjs
CHANGED
|
@@ -83,109 +83,7 @@ function isSksManagedHook(hook) {
|
|
|
83
83
|
return hook.type === 'command' && /\bhook\s+(?:user-prompt-submit|pre-tool|post-tool|permission-request|stop)\b/.test(command) && /\b(?:sks|sneakoscope|sks\.mjs)\b/.test(command);
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
const AGENTS_BLOCK = `
|
|
87
|
-
# Sneakoscope Codex Managed Rules
|
|
88
|
-
|
|
89
|
-
This repository uses Sneakoscope Codex.
|
|
90
|
-
|
|
91
|
-
## Ralph No-Question Rule
|
|
92
|
-
|
|
93
|
-
Ralph may ask questions only during prepare. After decision-contract.json is sealed and Ralph run starts, the assistant must not ask the user questions, request confirmation, or present choices. Resolve using the decision ladder.
|
|
94
|
-
|
|
95
|
-
## Performance and Retention
|
|
96
|
-
|
|
97
|
-
Sneakoscope Codex keeps runtime state bounded. Do not write large raw logs into prompts. Store raw outputs in files, keep only tails/summaries in JSON, and allow sks gc to remove old arenas, temp files, and stale mission logs.
|
|
98
|
-
|
|
99
|
-
## Update Check Before Work
|
|
100
|
-
|
|
101
|
-
Before any substantive work, SKS hooks check whether the installed SKS package is behind the latest published package. If an update is available, ask the user to choose between updating now and skipping the update for this conversation only. If the user skips, continue the current conversation without asking again, but check again in the next conversation. If the user accepts, update SKS, rerun setup/doctor, then continue the original task.
|
|
102
|
-
|
|
103
|
-
## Project Versioning
|
|
104
|
-
|
|
105
|
-
SKS manages the worker project's package version through a managed Git pre-commit hook. Every commit in a project with \`package.json\` gets a patch version bump in the same commit, with \`package-lock.json\` and \`npm-shrinkwrap.json\` kept in sync when present. The version guard uses a lock in the Git common directory so parallel workers or multiple worktrees do not reuse the same version. Check with \`sks versioning status\`; bypass only for exceptional maintenance with \`SKS_DISABLE_VERSIONING=1\`.
|
|
106
|
-
|
|
107
|
-
## Harness Self-Protection
|
|
108
|
-
|
|
109
|
-
After setup, installed Sneakoscope harness control files are immutable to LLM tool edits. Do not edit \`.codex/hooks.json\`, \`.codex/config.toml\`, \`.codex/SNEAKOSCOPE.md\`, \`.agents/skills/\`, \`.codex/agents/\`, \`.sneakoscope/manifest.json\`, \`.sneakoscope/policy.json\`, \`.sneakoscope/db-safety.json\`, \`.sneakoscope/harness-guard.json\`, \`AGENTS.md\`, or \`node_modules/sneakoscope\` from the agent. SKS hooks block direct writes and SKS maintenance commands from LLM tool calls. The only automatic exception is the Sneakoscope engine source repository itself, detected by \`package.json\` name \`sneakoscope\` plus \`bin/sks.mjs\` and \`src/core/*\`.
|
|
110
|
-
|
|
111
|
-
## Other Harness Conflict Gate
|
|
112
|
-
|
|
113
|
-
Before installing, setting up, or repairing SKS, check for incompatible Codex harnesses such as OMX or DCodex. OMX is a hard blocker. If another harness is found, SKS setup/doctor must stop and show \`sks conflicts prompt\`. Cleanup requires explicit human approval and should be performed by an LLM operator in Codex App using GPT-5.5 high mode. If the human does not approve cleanup, SKS cannot be installed in that environment.
|
|
114
|
-
|
|
115
|
-
## Honest Mode Completion
|
|
116
|
-
|
|
117
|
-
Do not stop at a plan when implementation was requested. Continue until the stated goal is actually handled or a hard blocker is explicitly reported. Before the final answer, run SKS Honest Mode: re-check the goal, evidence, tests, risk boundaries, and remaining gaps. The final answer must be honest about what passed, what was not verified, and whether the goal is genuinely complete.
|
|
118
|
-
|
|
119
|
-
## Evaluation
|
|
120
|
-
|
|
121
|
-
When a task claims performance, token, accuracy, context-compression, or workflow improvement, produce evidence with sks eval run or sks eval compare. Do not claim live model accuracy unless the run used an explicitly scored task dataset; otherwise call it an evidence-weighted accuracy proxy.
|
|
122
|
-
|
|
123
|
-
## Research Mode
|
|
124
|
-
|
|
125
|
-
When the user asks for research, new discoveries, hypothesis generation, frontier exploration, or deep investigation, use SKS Research Mode. Research must produce candidate insights, falsification attempts, a novelty ledger, and testable next experiments. Do not present a breakthrough claim unless it is explicitly marked with evidence, confidence, falsifiers, and uncertainty.
|
|
126
|
-
|
|
127
|
-
## AutoResearch Loop
|
|
128
|
-
|
|
129
|
-
For open-ended improvement, discovery, prompt, evaluation, ranking, SEO/GEO, or workflow-quality tasks, use the SKS AutoResearch loop inspired by iterative hypothesis search: define a program, choose a metric, run the smallest useful experiment, keep or discard the result, record the ledger, falsify the best candidate, and repeat within budget. Do not claim an improvement without evidence.
|
|
130
|
-
|
|
131
|
-
## Team Orchestration
|
|
132
|
-
|
|
133
|
-
When the user invokes Team mode, \`$Team\`, or a general implementation/code-changing prompt, default to Codex multi-agent orchestration: parallel analysis scouts, TriWiki refresh, read-only debate, then a fresh parallel executor team. Answer, DFix, Help, Wiki maintenance, and safety-specific routes are lightweight exceptions. TriWiki is not one-time setup: before each stage read \`.sneakoscope/wiki/context-pack.json\`; hydrate low-trust claims from source/hash/RGBA anchors; refresh or pack after scout, debate, consensus, implementation, review, or blockers; validate before handoff/final claims. Role counts like \`executor:5 reviewer:2 user:1\` create exactly N \`analysis_scout_N\`, N debate participants, and a separate N-person \`executor_N\` team. Scouts split repo, docs, tests, API, DB-risk, UX-friction, and implementation surfaces. Debate is read-only and includes stubborn users, capable executors, strict reviewers, and planners. Close debate agents once the objective is sealed, refresh/validate TriWiki, then launch disjoint executor slices in parallel. The parent orchestrates, integrates, verifies, and records useful scout/debate/handoff/review lines with \`sks team event <mission-id|latest> --agent <name> --phase <phase> --message "..."\`. Do not let subagents bypass SKS hooks or destructive DB safety.
|
|
134
|
-
|
|
135
|
-
## Code-Changing Execution
|
|
136
|
-
|
|
137
|
-
For code-changing work, first surface SKS route, guard, write scopes, and verification. General implementation prompts route to Team by default, then split independent write scopes across worker subagents. The parent assigns ownership, keeps urgent blockers local, integrates, and verifies. Subagents must not bypass DB safety, harness guard, Ralph, Context7, H-Proof, or Honest Mode.
|
|
138
|
-
|
|
139
|
-
## Design Execution
|
|
140
|
-
|
|
141
|
-
When creating or editing UI/UX, always look for \`design.md\` first. If it does not exist, use the local design-system-builder skill to create it from \`docs/Design-Sys-Prompt.md\`; that flow must use the Codex plan tool to remove ambiguity and recommend a default font choice before implementation. When \`design.md\` exists, use the design-ui-editor skill plus the local design artifact skill, follow the design guidelines exactly, and verify the rendered result. Any image, logo, raster, or bitmap asset generation must use the Codex \`imagegen\` skill.
|
|
142
|
-
|
|
143
|
-
## Prompt Optimization Pipeline
|
|
144
|
-
|
|
145
|
-
Every prompt starts with intent classification. Answer-only uses TriWiki/web/Context7 when useful plus Honest Mode, then direct reply. DFix uses its ultralight task list. General execution/code-changing prompts default to Team unless a more specific safety/research/DB/GX route applies. Extract intent, target surface, constraints, acceptance criteria, risks, and the smallest safe path before acting.
|
|
146
|
-
|
|
147
|
-
## Intent Inference And Clarification
|
|
148
|
-
|
|
149
|
-
The default stance is strong intent inference: when the user speaks roughly, infer the likely goal from local context, repo conventions, current route state, and prior artifacts. Do not ask lazy discovery questions. However, ambiguity removal is mandatory when a missing answer can change the target, scope, safety boundary, data risk, irreversible operation, user-facing behavior, or acceptance criteria. Ask the smallest set of concrete questions, then seal the inferred contract before implementation.
|
|
150
|
-
|
|
151
|
-
## Reasoning Effort Routing
|
|
152
|
-
|
|
153
|
-
Use temporary route-specific reasoning only. Simple fulfillment uses medium, any logical/safety/orchestration work uses high, and research or experiment loops use xhigh. Do not persist profile changes; return to the default or user-selected profile when the route gate passes.
|
|
154
|
-
|
|
155
|
-
## Context7 MCP Requirement
|
|
156
|
-
|
|
157
|
-
When work depends on external libraries, frameworks, APIs, MCPs, package managers, DB SDKs, or generated documentation, use Context7 MCP before completion. The required evidence flow is resolve-library-id followed by query-docs (or legacy get-library-docs). SKS PostToolUse records these calls in context7-evidence.jsonl, and Stop hooks block required routes until evidence exists. Pure command discovery and simple $DFix copy/color/spacing edits do not require Context7.
|
|
158
|
-
|
|
159
|
-
## LLM Wiki Continuity
|
|
160
|
-
|
|
161
|
-
TriWiki is the context-tracking SSOT for long-running missions, Team handoffs, and context-pressure recovery. It is anchor-first, not lossy-summary-first. Use relevant TriWiki context at every work stage, not only at the beginning: read the pack before a stage, hydrate low-trust claims during the stage, refresh after new findings or artifact changes, and validate before handoffs/final claims. Important claims, visual nodes, policy facts, and evidence pointers should receive deterministic RGBA wiki coordinates: R maps to domain angle, G maps to layer radius through sine, B maps to phase angle, and A maps to concentration/confidence. Use those trigonometric coordinates to preserve stable retrieval anchors across turns. Selected claims may be pasted as text, but non-selected claims must remain hydratable through id, hash, source path, and RGBA coordinate anchors instead of disappearing from the workflow. Refresh with \`sks wiki refresh\` or \`sks wiki pack\` and validate with \`sks wiki validate .sneakoscope/wiki/context-pack.json\` whenever route continuity, stage context, source evidence, or handoff context changes.
|
|
162
|
-
|
|
163
|
-
## Dollar Commands
|
|
164
|
-
|
|
165
|
-
Codex App users may invoke local SKS modes with skill-style dollar commands. \`$DFix\` is the fast design/content fix route for small changes such as text color, copy edits, label changes, spacing tweaks, or translating visible text. \`$DFix\` bypasses the general SKS prompt pipeline and runs an ultralight task-list path: list the exact micro-edits, inspect only needed files, apply only those edits, and run only cheap verification when useful.
|
|
166
|
-
|
|
167
|
-
## Codex App Usage
|
|
168
|
-
|
|
169
|
-
When this repository is opened in Codex App, use the local Sneakoscope files as the app control surface. Read \`.codex/SNEAKOSCOPE.md\` for the quick reference, load project skills from \`.agents/skills\` when applicable, and use the generated \`.codex/hooks.json\` hooks for DB safety, no-question Ralph runs, retention, and done-gate enforcement.
|
|
170
|
-
|
|
171
|
-
## Source Priority
|
|
172
|
-
|
|
173
|
-
1. Current code, tests, config
|
|
174
|
-
2. decision-contract.json
|
|
175
|
-
3. vgraph.json
|
|
176
|
-
4. beta.json
|
|
177
|
-
5. GX render/snapshot metadata
|
|
178
|
-
6. LLM Wiki coordinate index
|
|
179
|
-
7. model knowledge only if explicitly allowed
|
|
180
|
-
|
|
181
|
-
## Database Safety
|
|
182
|
-
|
|
183
|
-
Sneakoscope Codex treats database access as high risk. Destructive database operations are never allowed: DROP, TRUNCATE, mass DELETE/UPDATE, reset, push, repair, project deletion, branch reset/merge/delete, RLS disabling, broad grants/revokes, and any operation that could erase or overwrite data. Supabase/Postgres MCP should be read-only and project-scoped by default. Live database writes must not be performed through direct execute_sql; schema changes must be migration-file based and allowed only for local or preview/branch environments by the sealed contract.
|
|
184
|
-
|
|
185
|
-
## Done Means
|
|
186
|
-
|
|
187
|
-
A task is not done until relevant tests are run or justified, unsupported critical claims are zero, database safety violations are zero, visual/wiki drift is low or explicitly accepted, and final output includes evidence.
|
|
188
|
-
`;
|
|
86
|
+
const AGENTS_BLOCK = "\n# Sneakoscope Codex Managed Rules\n\nThis repository uses Sneakoscope Codex.\n\n## Core Rules\n\n- Ralph asks only during prepare. After `decision-contract.json` is sealed, do not ask the user; resolve with the decision ladder.\n- Keep runtime state bounded: raw logs go to files, prompts get tails/summaries, and `sks gc` may prune stale artifacts.\n- Before substantive work, SKS checks npm for a newer package. If newer, ask update-now vs skip-for-this-conversation.\n- Versioning is managed by the SKS pre-commit hook; check `sks versioning status`. Bypass only with `SKS_DISABLE_VERSIONING=1`.\n- Installed harness files are immutable to LLM edits: `.codex/*`, `.agents/skills/`, `.codex/agents/`, `.sneakoscope/*policy*.json`, `AGENTS.md`, and `node_modules/sneakoscope`. The Sneakoscope engine source repo is the only automatic exception.\n- OMX/DCodex conflicts block setup/doctor. Show `sks conflicts prompt`; cleanup requires explicit human approval.\n- Do not stop at a plan when implementation was requested. Finish, verify, or report the hard blocker.\n\n## Routes\n\n- General execution/code-changing prompts default to `$Team`: analysis scouts, TriWiki refresh/validate, read-only debate, consensus, fresh executor team, review, integration, Honest Mode.\n- `$DFix` is only for tiny design/content edits and bypasses the main pipeline. `$Answer`, `$Help`, and `$Wiki` stay lightweight.\n- For code work, surface route/guard/write scopes first, split independent worker scopes when available, and keep parent-owned integration and verification.\n- Design work reads `design.md`; if missing, use `design-system-builder`. Image/logo/raster assets use `imagegen`.\n- Research, AutoResearch, performance, token, accuracy, SEO/GEO, or workflow-improvement claims need experiment/eval evidence. Do not claim live model accuracy without a scored dataset.\n\n## Evidence And Context\n\n- Context7 is required for external libraries, APIs, MCPs, package managers, DB SDKs, and generated docs: resolve-library-id then query-docs.\n- TriWiki is the context-tracking SSOT for long-running missions, Team handoffs, and context-pressure recovery. Read `.sneakoscope/wiki/context-pack.json` before each stage, hydrate low-trust claims from source/hash/RGBA anchors, refresh after findings or artifact changes, and validate before handoffs/final claims.\n- Source priority: current code/tests/config, decision contract, vgraph, beta, GX render/snapshot metadata, LLM Wiki coordinate index, then model knowledge only if allowed.\n- Honest Mode before final: re-check goal, evidence, tests, risk boundaries, and remaining gaps. Say what passed and what was not verified.\n\n## Safety\n\n- Database access is high risk. Use read-only inspection by default; live data mutation is out of scope unless a sealed contract allows local or branch-only migration files.\n- Task completion requires relevant tests or justification, zero unsupported critical claims, accepted visual/wiki drift, and final evidence.\n\n## Codex App\n\nUse `.codex/SNEAKOSCOPE.md`, generated `.agents/skills`, `.codex/hooks.json`, and SKS dollar commands (`$sks`, `$team`, `$dfix`, `$qa-loop`, etc.) as the app control surface.\n";
|
|
189
87
|
|
|
190
88
|
export async function initProject(root, opts = {}) {
|
|
191
89
|
const created = [];
|
|
@@ -666,7 +564,7 @@ Hooks route Codex App events through SKS guards; status messages show checks, wh
|
|
|
666
564
|
`;
|
|
667
565
|
}
|
|
668
566
|
|
|
669
|
-
async function installSkills(root) {
|
|
567
|
+
export async function installSkills(root) {
|
|
670
568
|
const skills = {
|
|
671
569
|
'dfix': `---\nname: dfix\ndescription: Ultralight fast design/content fix mode for $DFix or $dfix requests and inferred simple edits such as text color, copy, labels, spacing, or translation.\n---\n\nYou are running SKS DFix mode.\n\nPurpose:\n- Bypass the general SKS prompt pipeline for small design/content requests.\n- Convert the request into a tiny task list, then execute only those tasks.\n- Use for requests like 글자 색 바꿔줘, 내용을 영어로 바꿔줘, button label 수정, spacing 조정, copy replacement, simple style tweaks.\n\nUltralight loop:\n1. List the exact micro-edits implied by the request.\n2. Inspect only the files needed to locate those targets.\n3. Apply only the listed edits.\n4. Run only cheap verification when useful.\n5. Final response should be short: what changed and any verification.\n\nRules:\n- Do not enter the general prompt pipeline, mission workflow, ambiguity gate, TriWiki refresh, Context7 routing, subagent orchestration, Ralph, Research, eval, or broad redesign.\n- Do not ask for more requirements when the target can be inferred from local context.\n- For UI/UX micro-edits, read \`design.md\` when present and preserve the existing design system and component patterns.\n- If \`design.md\` is missing and the change requires design judgment instead of a tiny mechanical edit, reroute to design-system-builder before editing.\n- Use imagegen for any image/logo/raster asset.\n`,
|
|
672
570
|
'answer': `---\nname: answer\ndescription: Answer-only research route for ordinary questions that should not start implementation.\n---\n\nUse when the user is asking for an explanation, comparison, status, facts, source-backed research, or documentation guidance rather than asking you to change files or run work.\n\nEvidence flow:\n1. Use current repo files and TriWiki first when the answer is project-local.\n2. Hydrate low-trust wiki claims from source paths before relying on them.\n3. Use web search for current, external, or uncertain facts when browsing is available or the user asks for latest/source-backed information.\n4. Use Context7 resolve-library-id plus query-docs when the answer depends on package, API, framework, SDK, MCP, or generated documentation behavior.\n5. End with Honest Mode fact-checking: separate verified facts, source-backed inferences, and uncertainty.\n\nRules:\n- Do not create route mission state, ambiguity-gate questions, subagents, Team handoffs, Ralph, Research loops, eval loops, or file edits.\n- If the prompt turns out to request implementation, state the reroute and use the proper execution pipeline.\n`,
|
|
@@ -710,9 +608,11 @@ async function installSkills(root) {
|
|
|
710
608
|
await writeTextAtomic(path.join(dir, 'SKILL.md'), `${skillContent.trim()}\n`);
|
|
711
609
|
await writeSkillMetadata(dir, name);
|
|
712
610
|
}
|
|
611
|
+
const skillNames = Object.keys(skills);
|
|
713
612
|
return {
|
|
714
|
-
|
|
715
|
-
|
|
613
|
+
installed_skills: skillNames,
|
|
614
|
+
removed_agent_skill_aliases: await removeGeneratedAgentSkillAliases(root, skillNames),
|
|
615
|
+
removed_codex_skill_mirrors: await removeGeneratedCodexSkillMirrors(root, skillNames)
|
|
716
616
|
};
|
|
717
617
|
}
|
|
718
618
|
|