sneakoscope 0.6.7 → 0.6.8
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 +0 -1
- package/package.json +1 -1
- package/src/cli/main.mjs +6 -6
- package/src/core/evaluation.mjs +1 -1
- package/src/core/fsx.mjs +1 -1
- package/src/core/init.mjs +41 -8
package/README.md
CHANGED
|
@@ -597,7 +597,6 @@ sks hproof check latest
|
|
|
597
597
|
.codex/skills/ Codex App local project skills
|
|
598
598
|
.codex/agents/ Codex App custom agents for Team mode
|
|
599
599
|
.codex/SNEAKOSCOPE.md Codex App quick reference
|
|
600
|
-
.agents/skills/ Sneakoscope Codex helper skills
|
|
601
600
|
AGENTS.md managed repository rules block
|
|
602
601
|
```
|
|
603
602
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sneakoscope",
|
|
3
3
|
"displayName": "Sneakoscope Codex",
|
|
4
|
-
"version": "0.6.
|
|
4
|
+
"version": "0.6.8",
|
|
5
5
|
"description": "Sneakoscope Codex: update-aware, database-safe Codex CLI harness with multi-agent Team orchestration, Ralph no-question execution, autoresearch-style loops, and H-Proof gates.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"homepage": "https://github.com/mandarange/Sneakoscope-Codex#readme",
|
package/src/cli/main.mjs
CHANGED
|
@@ -789,7 +789,7 @@ async function setup(args) {
|
|
|
789
789
|
if (localOnly) console.log('Git: local-only (.git/info/exclude; existing AGENTS.md not modified)');
|
|
790
790
|
console.log(`Codex App: .codex/config.toml, .codex/hooks.json, .codex/skills, .codex/agents, .codex/SNEAKOSCOPE.md`);
|
|
791
791
|
console.log(`Prompt: default optimization pipeline, $DF fast design/content route`);
|
|
792
|
-
console.log(`Skills: .codex/skills
|
|
792
|
+
console.log(`Skills: .codex/skills`);
|
|
793
793
|
console.log(`Next: sks selftest --mock; sks commands; sks dollar-commands`);
|
|
794
794
|
if (!install.ok && install.scope === 'global') console.log('\nGlobal command missing. Run: npm i -g sneakoscope');
|
|
795
795
|
if (!install.ok && install.scope === 'project') console.log('\nProject package missing. Run: npm i -D sneakoscope');
|
|
@@ -854,7 +854,7 @@ async function doctor(args) {
|
|
|
854
854
|
sneakoscope: { ok: await exists(path.join(root, '.sneakoscope')) },
|
|
855
855
|
db_guard: { ok: dbPolicyExists && dbScan.ok, policy: dbPolicyExists ? await loadDbSafetyPolicy(root) : null, scan: dbScan },
|
|
856
856
|
hooks: { ok: await exists(path.join(root, '.codex', 'hooks.json')) },
|
|
857
|
-
skills: { ok:
|
|
857
|
+
skills: { ok: await exists(path.join(root, '.codex', 'skills')) },
|
|
858
858
|
codex_app: {
|
|
859
859
|
...codexApp,
|
|
860
860
|
ok: codexApp.config.ok && codexApp.hooks.ok && codexApp.skills.ok && codexApp.agents.ok && codexApp.quick_reference.ok && codexApp.agents_rules.ok
|
|
@@ -873,7 +873,7 @@ async function doctor(args) {
|
|
|
873
873
|
console.log(`DB Guard: ${result.db_guard.ok ? 'ok' : 'blocked'} ${dbScan.findings?.length || 0} finding(s)`);
|
|
874
874
|
console.log(`Hooks: ${result.hooks.ok ? 'ok' : 'missing .codex/hooks.json'}`);
|
|
875
875
|
console.log(`Codex App: ${result.codex_app.ok ? 'ok' : 'missing app files'} .codex/config.toml .codex/hooks.json .codex/skills .codex/agents .codex/SNEAKOSCOPE.md`);
|
|
876
|
-
console.log(`Skills: ${result.skills.ok ? 'ok' : 'missing .codex/skills
|
|
876
|
+
console.log(`Skills: ${result.skills.ok ? 'ok' : 'missing .codex/skills'}`);
|
|
877
877
|
console.log(`Package: ${result.package.human}`);
|
|
878
878
|
console.log(`Storage: ${storage.total_human || '0 B'}`);
|
|
879
879
|
console.log(`Ready: ${result.ready ? 'yes' : 'no'}`);
|
|
@@ -1252,8 +1252,8 @@ async function selftest() {
|
|
|
1252
1252
|
if (oldSksBin === undefined) delete process.env.SKS_BIN;
|
|
1253
1253
|
else process.env.SKS_BIN = oldSksBin;
|
|
1254
1254
|
}
|
|
1255
|
-
const
|
|
1256
|
-
if (
|
|
1255
|
+
const legacySkillMirrorExists = await exists(path.join(tmp, '.agents', 'skills', 'research-discovery', 'SKILL.md'));
|
|
1256
|
+
if (legacySkillMirrorExists) throw new Error('selftest failed: legacy .agents/skills mirror still installed');
|
|
1257
1257
|
const codexAppSkillExists = await exists(path.join(tmp, '.codex', 'skills', 'research-discovery', 'SKILL.md'));
|
|
1258
1258
|
if (!codexAppSkillExists) throw new Error('selftest failed: Codex App skill not installed');
|
|
1259
1259
|
const dfSkillExists = await exists(path.join(tmp, '.codex', 'skills', 'DF', 'SKILL.md'));
|
|
@@ -1439,7 +1439,7 @@ async function projectWikiClaims(root) {
|
|
|
1439
1439
|
const claims = [
|
|
1440
1440
|
['wiki-hooks', '.codex/hooks.json routes UserPromptSubmit, tool, permission, and Stop events through SKS guards.', '.codex/hooks.json', 'code', 'high'],
|
|
1441
1441
|
['wiki-config', '.codex/config.toml enables Codex App profiles, multi-agent support, and Team agent limits.', '.codex/config.toml', 'code', 'high'],
|
|
1442
|
-
['wiki-skills', '.codex/skills
|
|
1442
|
+
['wiki-skills', '.codex/skills provides local routes for DF, Team, Ralph, Research, AutoResearch, DB, GX, wiki, and evaluation workflows.', '.codex/skills', 'code', 'medium'],
|
|
1443
1443
|
['wiki-agents', '.codex/agents defines Team planning, implementation, DB safety, and QA reviewer roles.', '.codex/agents', 'code', 'medium'],
|
|
1444
1444
|
['wiki-policy', '.sneakoscope/policy.json stores update-check, honest-mode, retention, database, performance, and prompt-pipeline policy.', '.sneakoscope/policy.json', 'contract', 'high'],
|
|
1445
1445
|
['wiki-memory', '.sneakoscope/memory stores Q0 raw, Q1 evidence, Q2 facts, Q3 tags, and Q4 control bits for hydratable context.', '.sneakoscope/memory', 'wiki', 'high'],
|
package/src/core/evaluation.mjs
CHANGED
|
@@ -38,7 +38,7 @@ export function defaultEvaluationScenario() {
|
|
|
38
38
|
['req-wiki-rgba', 'TriWiki stores RGBA-derived trigonometric wiki anchors so compressed context remains hydratable by id, hash, source, and coordinate.', 'code', 'high', 1.2],
|
|
39
39
|
['req-retention', 'runtime logs and mission artifacts are bounded through retention policy and sks gc.', 'code', 'medium', 0.85],
|
|
40
40
|
['req-selftest', 'selftest covers contract sealing, DB guard blocking, done-gate evaluation, GX render/validate/drift, snapshot, and retention report.', 'test', 'high', 1.1],
|
|
41
|
-
['req-skill', 'sks init installs local
|
|
41
|
+
['req-skill', 'sks init installs one canonical local skill set under .codex/skills so project workflows can trigger domain-specific guidance without duplicate commands.', 'code', 'medium', 0.9],
|
|
42
42
|
['req-design', 'design artifact work should gather design context, build an HTML artifact, expose variations when useful, and verify rendered output.', 'code', 'medium', 0.8]
|
|
43
43
|
];
|
|
44
44
|
const noise = [
|
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.8';
|
|
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
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
|
+
import fsp from 'node:fs/promises';
|
|
2
3
|
import { ensureDir, readJson, readText, writeJsonAtomic, writeTextAtomic, mergeManagedBlock, nowIso, PACKAGE_VERSION, exists } from './fsx.mjs';
|
|
3
4
|
import { DEFAULT_RETENTION_POLICY } from './retention.mjs';
|
|
4
5
|
import { DEFAULT_DB_SAFETY_POLICY } from './db-safety.mjs';
|
|
@@ -102,7 +103,7 @@ export async function initProject(root, opts = {}) {
|
|
|
102
103
|
const hookCommandPrefix = opts.hookCommandPrefix || sksCommandPrefix(installScope, { globalCommand: opts.globalCommand });
|
|
103
104
|
const sine = path.join(root, '.sneakoscope');
|
|
104
105
|
const dirs = [
|
|
105
|
-
'.sneakoscope/state', '.sneakoscope/missions', '.sneakoscope/db', '.sneakoscope/bus', '.sneakoscope/hproof', '.sneakoscope/db', '.sneakoscope/wiki', '.sneakoscope/memory/q0_raw', '.sneakoscope/memory/q1_evidence', '.sneakoscope/memory/q2_facts', '.sneakoscope/memory/q3_tags', '.sneakoscope/memory/q4_bits', '.sneakoscope/gx/cartridges', '.sneakoscope/model/fingerprints', '.sneakoscope/genome/candidates', '.sneakoscope/trajectories/raw', '.sneakoscope/locks', '.sneakoscope/tmp', '.sneakoscope/arenas', '.sneakoscope/reports', '.codex', '.codex/skills', '.codex/agents'
|
|
106
|
+
'.sneakoscope/state', '.sneakoscope/missions', '.sneakoscope/db', '.sneakoscope/bus', '.sneakoscope/hproof', '.sneakoscope/db', '.sneakoscope/wiki', '.sneakoscope/memory/q0_raw', '.sneakoscope/memory/q1_evidence', '.sneakoscope/memory/q2_facts', '.sneakoscope/memory/q3_tags', '.sneakoscope/memory/q4_bits', '.sneakoscope/gx/cartridges', '.sneakoscope/model/fingerprints', '.sneakoscope/genome/candidates', '.sneakoscope/trajectories/raw', '.sneakoscope/locks', '.sneakoscope/tmp', '.sneakoscope/arenas', '.sneakoscope/reports', '.codex', '.codex/skills', '.codex/agents'
|
|
106
107
|
];
|
|
107
108
|
for (const d of dirs) await ensureDir(path.join(root, d));
|
|
108
109
|
const localExclude = localOnly ? await ensureLocalOnlyGitExclude(root) : null;
|
|
@@ -288,9 +289,9 @@ export async function initProject(root, opts = {}) {
|
|
|
288
289
|
});
|
|
289
290
|
created.push(`.codex/hooks.json (${installScope})`);
|
|
290
291
|
|
|
291
|
-
await installSkills(root);
|
|
292
|
+
const skillInstall = await installSkills(root);
|
|
292
293
|
created.push('.codex/skills/*');
|
|
293
|
-
created.push(
|
|
294
|
+
if (skillInstall.removed_legacy_agent_skill_dirs.length) created.push(`.agents/skills legacy mirrors removed (${skillInstall.removed_legacy_agent_skill_dirs.length})`);
|
|
294
295
|
await installCodexAgents(root);
|
|
295
296
|
created.push('.codex/agents/*');
|
|
296
297
|
return { created };
|
|
@@ -435,12 +436,44 @@ async function installSkills(root) {
|
|
|
435
436
|
'design-artifact-expert': `---\nname: design-artifact-expert\ndescription: Create or revise high-fidelity HTML, UI, prototype, deck-like, or visual design artifacts using project design context, variations, and rendered verification.\n---\n\nUse when the user asks for design, UI, prototype, HTML artifact, landing page, deck-like visual work, interaction design, or visual refinement.\n\nWorkflow:\n1. Understand the artifact, audience, constraints, fidelity, variants, and existing brand/design system.\n2. Inspect local code, assets, screenshots, or design-system docs before inventing visuals. If context exists, follow its visual vocabulary.\n3. Build the actual usable screen or artifact first; avoid empty landing-page framing unless the task is explicitly marketing.\n4. Use descriptive HTML filenames. Keep large artifacts split into small support files when needed.\n5. For screens/slides, add data-screen-label attributes for comment context. Slide labels are 1-indexed.\n6. Preserve state for decks, videos, or multi-step prototypes with localStorage when refresh continuity matters.\n7. Expose a small Tweaks surface for useful variants such as layout, density, color, copy, or interaction options.\n8. Verify the artifact renders cleanly in a browser or preview. For design tasks, set done-gate.json design_verification_required/present fields and cite evidence.\n\nQuality bar:\n- Root design decisions in available assets and components.\n- Use restrained, domain-appropriate layout and typography.\n- Avoid text overlap, unreadable controls, decorative clutter, one-note palettes, and placeholder-only deliverables.\n- Prefer icons and familiar controls for tool actions, and make repeated UI dimensions stable.\n`
|
|
436
437
|
};
|
|
437
438
|
for (const [name, content] of Object.entries(skills)) {
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
await writeTextAtomic(path.join(dir, 'SKILL.md'), `${content.trim()}\n`);
|
|
442
|
-
}
|
|
439
|
+
const dir = path.join(root, '.codex', 'skills', name);
|
|
440
|
+
await ensureDir(dir);
|
|
441
|
+
await writeTextAtomic(path.join(dir, 'SKILL.md'), `${content.trim()}\n`);
|
|
443
442
|
}
|
|
443
|
+
return { removed_legacy_agent_skill_dirs: await removeLegacyAgentSkillMirrors(root, Object.keys(skills)) };
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
async function removeLegacyAgentSkillMirrors(root, skillNames) {
|
|
447
|
+
const legacyRoot = path.join(root, '.agents', 'skills');
|
|
448
|
+
if (!(await exists(legacyRoot))) return [];
|
|
449
|
+
const removed = [];
|
|
450
|
+
for (const name of skillNames) {
|
|
451
|
+
const dir = path.join(legacyRoot, name);
|
|
452
|
+
const skillPath = path.join(dir, 'SKILL.md');
|
|
453
|
+
const text = await readText(skillPath, null);
|
|
454
|
+
if (!isGeneratedSksLegacySkill(text, name)) continue;
|
|
455
|
+
await fsp.rm(dir, { recursive: true, force: true });
|
|
456
|
+
removed.push(path.relative(root, dir));
|
|
457
|
+
}
|
|
458
|
+
await removeDirIfEmpty(legacyRoot);
|
|
459
|
+
await removeDirIfEmpty(path.join(root, '.agents'));
|
|
460
|
+
return removed;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
function isGeneratedSksLegacySkill(text, name) {
|
|
464
|
+
if (typeof text !== 'string') return false;
|
|
465
|
+
return text.startsWith('---') && new RegExp(`^name:\\s*${escapeRegExp(name)}\\s*$`, 'm').test(text);
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
function escapeRegExp(value) {
|
|
469
|
+
return String(value).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
async function removeDirIfEmpty(dir) {
|
|
473
|
+
try {
|
|
474
|
+
const entries = await fsp.readdir(dir);
|
|
475
|
+
if (!entries.length) await fsp.rmdir(dir);
|
|
476
|
+
} catch {}
|
|
444
477
|
}
|
|
445
478
|
|
|
446
479
|
async function installCodexAgents(root) {
|