sneakoscope 0.7.11 → 0.7.13
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 +27 -27
- package/package.json +2 -2
- package/src/cli/install-helpers.mjs +12 -13
- package/src/cli/main.mjs +87 -100
- package/src/cli/maintenance-commands.mjs +31 -31
- package/src/core/artifact-schemas.mjs +6 -6
- package/src/core/codex-app.mjs +1 -1
- package/src/core/evaluation.mjs +3 -3
- package/src/core/fsx.mjs +1 -1
- package/src/core/init.mjs +6 -6
- package/src/core/pipeline.mjs +2 -2
- package/src/core/ppt.mjs +100 -19
- package/src/core/questions.mjs +1 -1
- package/src/core/routes.mjs +9 -9
- package/src/core/team-live.mjs +8 -8
- package/src/core/tmux-ui.mjs +447 -0
- package/src/core/warp-ui.mjs +0 -557
|
@@ -29,7 +29,7 @@ import { PIPELINE_PLAN_ARTIFACT, validatePipelinePlan, writePipelinePlan } from
|
|
|
29
29
|
import { GOAL_BRIDGE_ARTIFACT, GOAL_WORKFLOW_ARTIFACT, updateGoalWorkflow, writeGoalWorkflow } from '../core/goal-workflow.mjs';
|
|
30
30
|
import { scanCodeStructure, writeCodeStructureReport } from '../core/code-structure.mjs';
|
|
31
31
|
import { writeMemorySweepReport } from '../core/memory-governor.mjs';
|
|
32
|
-
import {
|
|
32
|
+
import { cleanupTmuxTeamView, launchTmuxTeamView } from '../core/tmux-ui.mjs';
|
|
33
33
|
import { loadSkillDreamState, recordSkillDreamEvent, runSkillDream, writeSkillForgeReport } from '../core/skill-forge.mjs';
|
|
34
34
|
import { writeMistakeMemoryReport } from '../core/mistake-memory.mjs';
|
|
35
35
|
import { checkDbOperation, checkSqlFile, classifyCommand, classifySql, loadDbSafetyPolicy, safeSupabaseMcpConfig, scanDbSafety } from '../core/db-safety.mjs';
|
|
@@ -56,8 +56,8 @@ Use outside a project:
|
|
|
56
56
|
sks deps check
|
|
57
57
|
sks team "global mission"
|
|
58
58
|
|
|
59
|
-
If
|
|
60
|
-
sks deps install
|
|
59
|
+
If tmux is missing:
|
|
60
|
+
sks deps install tmux
|
|
61
61
|
|
|
62
62
|
Initialize this project for CLI and Codex App:
|
|
63
63
|
sks setup --bootstrap
|
|
@@ -70,7 +70,7 @@ Open from terminal:
|
|
|
70
70
|
Verify:
|
|
71
71
|
sks deps check
|
|
72
72
|
sks codex-app check
|
|
73
|
-
sks
|
|
73
|
+
sks tmux check
|
|
74
74
|
sks auto-review status
|
|
75
75
|
sks doctor --fix
|
|
76
76
|
sks context7 check
|
|
@@ -640,7 +640,7 @@ export async function harnessCommand(sub, args = []) {
|
|
|
640
640
|
if (flag(args, '--json')) return console.log(JSON.stringify(report, null, 2));
|
|
641
641
|
console.log('SKS Harness Growth');
|
|
642
642
|
console.log(`Forgetting fixture: ${report.forgetting.fixture.passed ? 'pass' : 'fail'}`);
|
|
643
|
-
console.log(`
|
|
643
|
+
console.log(`tmux views: ${report.tmux.views.length}`);
|
|
644
644
|
console.log(`Tool taxonomy: ${report.reliability.tool_error_taxonomy.join(', ')}`);
|
|
645
645
|
console.log(`Unknown errors recorded as bugs: ${report.reliability.unknown_errors_are_bugs ? 'yes' : 'no'}`);
|
|
646
646
|
}
|
|
@@ -1172,7 +1172,7 @@ function userRequestSignal(prompt = '') {
|
|
|
1172
1172
|
const topicRules = [
|
|
1173
1173
|
['ambiguity-questions', /모호|ambiguity|clarification|질문|답변|answers?\.json|decision-contract|추론|예측/],
|
|
1174
1174
|
['triwiki-priority-memory', /triwiki|wiki|메모리|memory|기억|우선|반복|자주|카운팅|count|frequency|weight/],
|
|
1175
|
-
['install-bootstrap', /bootstrap|postinstall|doctor|deps|
|
|
1175
|
+
['install-bootstrap', /bootstrap|postinstall|doctor|deps|tmux|homebrew|최초\s*설치|셋업|setup/],
|
|
1176
1176
|
['version-release', /버전|version|publish:dry|release|npm\s+pack/],
|
|
1177
1177
|
['qa-loop', /qa|e2e|검증|리포트|report/],
|
|
1178
1178
|
['team-pipeline', /team|subagent|세션|cleanup|reflection|회고|반성/],
|
|
@@ -1416,15 +1416,15 @@ export async function gxCommand(sub, args) {
|
|
|
1416
1416
|
}
|
|
1417
1417
|
|
|
1418
1418
|
export async function team(args) {
|
|
1419
|
-
const teamSubcommands = new Set(['log', 'tail', 'watch', 'lane', 'status', 'dashboard', 'event', 'message', 'cleanup-
|
|
1419
|
+
const teamSubcommands = new Set(['log', 'tail', 'watch', 'lane', 'status', 'dashboard', 'event', 'message', 'cleanup-tmux']);
|
|
1420
1420
|
if (teamSubcommands.has(args[0])) return teamCommand(args[0], args.slice(1));
|
|
1421
|
-
const
|
|
1422
|
-
const cleanCreateArgs = args.filter((arg) => !['--open-
|
|
1421
|
+
const openTmux = flag(args, '--open-tmux') || flag(args, '--tmux-open');
|
|
1422
|
+
const cleanCreateArgs = args.filter((arg) => !['--open-tmux', '--tmux-open'].includes(String(arg)));
|
|
1423
1423
|
const opts = parseTeamCreateArgs(cleanCreateArgs);
|
|
1424
1424
|
const { prompt, agentSessions, roleCounts, roster } = opts;
|
|
1425
1425
|
if (!prompt) {
|
|
1426
|
-
console.error('Usage: sks team "task" [executor:5 reviewer:2 user:1] [--agents N] [--open-
|
|
1427
|
-
console.error(' sks team log|tail|watch|lane|status|message|cleanup-
|
|
1426
|
+
console.error('Usage: sks team "task" [executor:5 reviewer:2 user:1] [--agents N] [--open-tmux] [--json]');
|
|
1427
|
+
console.error(' sks team log|tail|watch|lane|status|message|cleanup-tmux [mission-id|latest]');
|
|
1428
1428
|
console.error(' sks team event [mission-id|latest] --agent <name> --phase <phase> --message "..."');
|
|
1429
1429
|
console.error(' sks team message [mission-id|latest] --from <agent> --to <agent|all> --message "..."');
|
|
1430
1430
|
process.exitCode = 1;
|
|
@@ -1490,7 +1490,7 @@ export async function team(args) {
|
|
|
1490
1490
|
questions: path.join(dir, 'questions.md'),
|
|
1491
1491
|
codex_agents: ['analysis_scout', 'team_consensus', 'implementation_worker', 'db_safety_reviewer', 'qa_reviewer']
|
|
1492
1492
|
};
|
|
1493
|
-
result.
|
|
1493
|
+
result.tmux = await launchTmuxTeamView({ root, missionId: id, plan, promptFile: result.workflow, json: flag(args, '--json') || !openTmux });
|
|
1494
1494
|
if (flag(args, '--json')) return console.log(JSON.stringify(result, null, 2));
|
|
1495
1495
|
console.log(`Team mission created: ${id}`);
|
|
1496
1496
|
console.log(`Plan: ${path.relative(root, result.plan)}`);
|
|
@@ -1501,13 +1501,13 @@ export async function team(args) {
|
|
|
1501
1501
|
console.log(`Runtime graph: ${path.relative(root, result.team_graph)}`);
|
|
1502
1502
|
console.log(`Worker inbox: ${path.relative(root, result.worker_inbox_dir)}`);
|
|
1503
1503
|
console.log(`Live: ${path.relative(root, result.live)}`);
|
|
1504
|
-
if (result.
|
|
1505
|
-
const
|
|
1506
|
-
console.log(`
|
|
1504
|
+
if (result.tmux.ready) {
|
|
1505
|
+
const tmuxState = result.tmux.created ? 'opened' : 'not opened; use --open-tmux for a tmux session';
|
|
1506
|
+
console.log(`tmux: ${tmuxState} ${result.tmux.opened_lane_count || result.tmux.agents.length} agent lane(s) in ${result.tmux.session || result.tmux.workspace}`);
|
|
1507
1507
|
}
|
|
1508
|
-
else console.log(`
|
|
1508
|
+
else console.log(`tmux: blocked (${Array.from(new Set(result.tmux.blockers || [])).join('; ')})`);
|
|
1509
1509
|
console.log(`Watch: sks team watch ${id}`);
|
|
1510
|
-
console.log('Use $Team in Codex App or the
|
|
1510
|
+
console.log('Use $Team in Codex App or the tmux launch view from this CLI flow to run scouts, debate/consensus, runtime graph/inbox handoff, then a fresh implementation team with disjoint ownership.');
|
|
1511
1511
|
}
|
|
1512
1512
|
|
|
1513
1513
|
export function parseTeamCreateArgs(args) {
|
|
@@ -1654,7 +1654,7 @@ export function buildTeamPlan(id, prompt, opts = {}) {
|
|
|
1654
1654
|
markdown: 'team-live.md',
|
|
1655
1655
|
transcript: 'team-transcript.jsonl',
|
|
1656
1656
|
dashboard: 'team-dashboard.json',
|
|
1657
|
-
|
|
1657
|
+
tmux: 'sks team opens a tmux workspace with one live multi-line lane per visible Team agent budget when tmux is available.',
|
|
1658
1658
|
commands: [
|
|
1659
1659
|
'sks team status <mission-id>',
|
|
1660
1660
|
'sks team log <mission-id>',
|
|
@@ -1663,7 +1663,7 @@ export function buildTeamPlan(id, prompt, opts = {}) {
|
|
|
1663
1663
|
'sks team lane <mission-id> --agent <name> --follow',
|
|
1664
1664
|
'sks team event <mission-id> --agent <name> --phase <phase> --message "..."',
|
|
1665
1665
|
'sks team message <mission-id> --from <agent> --to <agent|all> --message "..."',
|
|
1666
|
-
'sks team cleanup-
|
|
1666
|
+
'sks team cleanup-tmux <mission-id>'
|
|
1667
1667
|
]
|
|
1668
1668
|
},
|
|
1669
1669
|
required_artifacts: requiredArtifacts,
|
|
@@ -1774,19 +1774,19 @@ async function teamCommand(sub, args) {
|
|
|
1774
1774
|
artifact: readFlagValue(args, '--artifact', ''),
|
|
1775
1775
|
message
|
|
1776
1776
|
});
|
|
1777
|
-
const
|
|
1777
|
+
const tmuxCleanup = /^session_cleanup$|^team_cleanup$|^cleanup$/i.test(String(phase || ''))
|
|
1778
1778
|
? await requestTeamSessionCleanup(dir, {
|
|
1779
1779
|
missionId: id,
|
|
1780
1780
|
agent: readFlagValue(args, '--agent', 'parent_orchestrator'),
|
|
1781
1781
|
reason: message,
|
|
1782
|
-
finalMessage: 'Team cleanup event received. Follow panes may stop;
|
|
1783
|
-
}).then(() =>
|
|
1782
|
+
finalMessage: 'Team cleanup event received. Follow panes may stop; tmux panes remain user-controlled.'
|
|
1783
|
+
}).then(() => cleanupTmuxTeamView({ root, missionId: id, closeSession: flag(args, '--close-session') || flag(args, '--close') })).catch((err) => ({ ok: false, reason: err.message || 'tmux cleanup failed' }))
|
|
1784
1784
|
: null;
|
|
1785
1785
|
if (flag(args, '--json')) return console.log(JSON.stringify(record, null, 2));
|
|
1786
1786
|
console.log(`${record.ts} [${record.phase}] ${record.agent}: ${record.message}`);
|
|
1787
|
-
if (
|
|
1788
|
-
if (
|
|
1789
|
-
else console.log(`
|
|
1787
|
+
if (tmuxCleanup) {
|
|
1788
|
+
if (tmuxCleanup.ok) console.log(`tmux cleanup: marked complete (${tmuxCleanup.reason || 'record updated'})`);
|
|
1789
|
+
else console.log(`tmux cleanup: skipped (${tmuxCleanup.reason || 'not available'})`);
|
|
1790
1790
|
}
|
|
1791
1791
|
return;
|
|
1792
1792
|
}
|
|
@@ -1810,12 +1810,12 @@ async function teamCommand(sub, args) {
|
|
|
1810
1810
|
console.log(`${record.ts} [${record.phase}] ${record.agent} -> ${record.to}: ${record.message}`);
|
|
1811
1811
|
return;
|
|
1812
1812
|
}
|
|
1813
|
-
if (sub === 'cleanup-
|
|
1813
|
+
if (sub === 'cleanup-tmux') {
|
|
1814
1814
|
const control = await requestTeamSessionCleanup(dir, {
|
|
1815
1815
|
missionId: id,
|
|
1816
1816
|
agent: readFlagValue(args, '--agent', 'parent_orchestrator'),
|
|
1817
1817
|
reason: readFlagValue(args, '--reason', 'Team session ended; clean up live follow panes.'),
|
|
1818
|
-
finalMessage: 'Team session ended. Lane/watch follow loops will stop after showing this cleanup summary;
|
|
1818
|
+
finalMessage: 'Team session ended. Lane/watch follow loops will stop after showing this cleanup summary; tmux panes remain user-controlled.'
|
|
1819
1819
|
});
|
|
1820
1820
|
await appendTeamEvent(dir, {
|
|
1821
1821
|
agent: readFlagValue(args, '--agent', 'parent_orchestrator'),
|
|
@@ -1823,16 +1823,16 @@ async function teamCommand(sub, args) {
|
|
|
1823
1823
|
type: 'cleanup',
|
|
1824
1824
|
message: control.cleanup_reason || 'Team session cleanup requested.'
|
|
1825
1825
|
});
|
|
1826
|
-
const cleanup = await
|
|
1826
|
+
const cleanup = await cleanupTmuxTeamView({ root, missionId: id, closeSession: flag(args, '--close-session') || flag(args, '--close') });
|
|
1827
1827
|
cleanup.control = control;
|
|
1828
1828
|
if (flag(args, '--json')) return console.log(JSON.stringify(cleanup, null, 2));
|
|
1829
1829
|
if (!cleanup.ok) {
|
|
1830
|
-
console.error(`
|
|
1830
|
+
console.error(`tmux cleanup skipped: ${cleanup.reason || 'not available'}`);
|
|
1831
1831
|
process.exitCode = cleanup.skipped ? 0 : 2;
|
|
1832
1832
|
return;
|
|
1833
1833
|
}
|
|
1834
|
-
if (cleanup.
|
|
1835
|
-
else console.log(`
|
|
1834
|
+
if (cleanup.killed_session) console.log(`tmux cleanup: killed session ${cleanup.session}`);
|
|
1835
|
+
else console.log(`tmux cleanup: marked complete (${cleanup.reason || 'record updated'})`);
|
|
1836
1836
|
console.log(renderTeamCleanupSummary(control));
|
|
1837
1837
|
return;
|
|
1838
1838
|
}
|
|
@@ -20,7 +20,7 @@ export const ARTIFACT_FILES = {
|
|
|
20
20
|
harness_growth_report: 'harness-growth-report.json',
|
|
21
21
|
code_structure_report: 'code-structure-report.json',
|
|
22
22
|
team_dashboard_state: 'team-dashboard-state.json',
|
|
23
|
-
|
|
23
|
+
tmux_pane_plan: 'tmux-pane-plan.json',
|
|
24
24
|
final_honest_mode_report: 'final-honest-mode-report.json'
|
|
25
25
|
};
|
|
26
26
|
|
|
@@ -170,12 +170,12 @@ export function validateHarnessGrowthReport(data = {}) {
|
|
|
170
170
|
pushMissing(errors, isObj(data.skills), 'skills_missing');
|
|
171
171
|
pushMissing(errors, isObj(data.experiments), 'experiments_missing');
|
|
172
172
|
pushMissing(errors, isObj(data.codex_native), 'codex_native_missing');
|
|
173
|
-
pushMissing(errors, isObj(data.
|
|
173
|
+
pushMissing(errors, isObj(data.tmux), 'tmux_missing');
|
|
174
174
|
pushMissing(errors, isObj(data.reliability), 'reliability_missing');
|
|
175
175
|
if (data.forgetting?.fixture?.passed !== true) errors.push('forgetting_fixture_failed');
|
|
176
176
|
if (!Array.isArray(data.reliability?.tool_error_taxonomy) || !data.reliability.tool_error_taxonomy.includes('Unknown')) errors.push('tool_error_taxonomy_missing_unknown');
|
|
177
177
|
if (data.reliability?.unknown_errors_are_bugs !== true) errors.push('unknown_errors_not_marked_bug');
|
|
178
|
-
if (!Array.isArray(data.
|
|
178
|
+
if (!Array.isArray(data.tmux?.views) || data.tmux.views.length < 10) errors.push('tmux_views_incomplete');
|
|
179
179
|
return validationResult('HarnessGrowthReport', errors);
|
|
180
180
|
}
|
|
181
181
|
|
|
@@ -202,12 +202,12 @@ export function validateTeamDashboardState(data = {}) {
|
|
|
202
202
|
return validationResult('TeamDashboardState', errors);
|
|
203
203
|
}
|
|
204
204
|
|
|
205
|
-
export function
|
|
205
|
+
export function validateTmuxPanePlan(data = {}) {
|
|
206
206
|
const errors = [];
|
|
207
207
|
pushMissing(errors, nonEmpty(data.mission_id), 'mission_id_missing');
|
|
208
208
|
pushMissing(errors, Array.isArray(data.panes), 'panes_not_array');
|
|
209
209
|
if (arr(data.panes).some((pane) => !nonEmpty(pane.name) || !nonEmpty(pane.command))) errors.push('pane_missing_name_or_command');
|
|
210
|
-
return validationResult('
|
|
210
|
+
return validationResult('TmuxPanePlan', errors);
|
|
211
211
|
}
|
|
212
212
|
|
|
213
213
|
export function validateFinalHonestModeReport(data = {}) {
|
|
@@ -233,7 +233,7 @@ export const ARTIFACT_VALIDATORS = {
|
|
|
233
233
|
harness_growth_report: validateHarnessGrowthReport,
|
|
234
234
|
code_structure_report: validateCodeStructureReport,
|
|
235
235
|
team_dashboard_state: validateTeamDashboardState,
|
|
236
|
-
|
|
236
|
+
tmux_pane_plan: validateTmuxPanePlan,
|
|
237
237
|
final_honest_mode_report: validateFinalHonestModeReport
|
|
238
238
|
};
|
|
239
239
|
|
package/src/core/codex-app.mjs
CHANGED
|
@@ -118,7 +118,7 @@ export async function codexAppIntegrationStatus(opts = {}) {
|
|
|
118
118
|
export function codexAppGuidance({ appInstalled, codex, mcpList, computerUseReady, browserUseReady }) {
|
|
119
119
|
const lines = [];
|
|
120
120
|
if (!appInstalled) {
|
|
121
|
-
lines.push('Install and open Codex App for first-party MCP/plugin tools. SKS
|
|
121
|
+
lines.push('Install and open Codex App for first-party MCP/plugin tools. SKS tmux launch can still run with Codex CLI alone, but Codex Computer Use evidence will be unavailable until Codex App is ready.');
|
|
122
122
|
lines.push(`Docs: ${CODEX_APP_DOCS_URL}`);
|
|
123
123
|
}
|
|
124
124
|
if (!codex?.bin) lines.push('Install Codex CLI too: npm i -g @openai/codex, or set SKS_CODEX_BIN.');
|
package/src/core/evaluation.mjs
CHANGED
|
@@ -82,7 +82,7 @@ export const DEFAULT_MULTIAGENT_V2 = Object.freeze({
|
|
|
82
82
|
subagent_output: 'structured_summary_only'
|
|
83
83
|
});
|
|
84
84
|
|
|
85
|
-
export const
|
|
85
|
+
export const TMUX_COCKPIT_VIEWS = Object.freeze([
|
|
86
86
|
'Mission / Goal View',
|
|
87
87
|
'Agent Grid View',
|
|
88
88
|
'MultiAgentV2 Graph View',
|
|
@@ -287,8 +287,8 @@ export function harnessGrowthReport(input = {}) {
|
|
|
287
287
|
goal_checkpoint_required_fields: ['goal_id', 'phase', 'summary', 'completed_checkboxes', 'open_checkboxes', 'blockers', 'evidence'],
|
|
288
288
|
external_session_import: 'structured_summary_only_with_utility_score_and_forgetting_metadata'
|
|
289
289
|
},
|
|
290
|
-
|
|
291
|
-
views:
|
|
290
|
+
tmux: {
|
|
291
|
+
views: TMUX_COCKPIT_VIEWS,
|
|
292
292
|
status_terms: ['idle', 'planning', 'exploring', 'implementing', 'waiting_for_tool', 'waiting_for_approval', 'dogfooding', 'verifying', 'summarizing', 'blocked', 'failed', 'completed', 'paused', 'resuming']
|
|
293
293
|
},
|
|
294
294
|
reliability: {
|
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.7.
|
|
8
|
+
export const PACKAGE_VERSION = '0.7.13';
|
|
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
|
@@ -91,7 +91,7 @@ function isSksManagedHook(hook) {
|
|
|
91
91
|
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);
|
|
92
92
|
}
|
|
93
93
|
|
|
94
|
-
const AGENTS_BLOCK = "\n# Sneakoscope Codex Managed Rules\n\nThis repository uses Sneakoscope Codex.\n\n## Core Rules\n\n- Codex native `/goal` workflows are the persisted continuation surface; Ralph is removed from the user-facing SKS surface.\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- Do not create unrequested fallback implementation code. If the requested path is impossible, block with evidence instead of inventing substitute behavior.\n\n## Routes\n\n- General execution/code-changing prompts default to `$Team`: analysis scouts, TriWiki refresh/validate, read-only debate, consensus, concrete runtime task graph/inboxes, fresh executor team, review, integration, Honest Mode.\n- `$Computer-Use` / `$CU` is the maximum-speed Codex Computer Use lane for UI/browser/visual tasks: skip Team debate and upfront TriWiki loops, use Codex Computer Use directly, then refresh/validate TriWiki and run Honest Mode at final closeout.\n- `$Goal` is a fast bridge/overlay for Codex native `/goal` create/pause/resume/clear persistence controls; implementation continues through the selected SKS execution route.\n- TriWiki recall must stay bounded. Use `sks wiki sweep` to record demote, soft-forget, archive, delete, promote-to-skill, and promote-to-rule candidates instead of injecting every old claim.\n- Team missions must keep schema-backed evidence current: `work-order-ledger.json`, `effort-decision.json`, `team-dashboard-state.json`, and route-specific visual/dogfood artifacts where applicable. Use `sks validate-artifacts latest` before claiming those artifacts pass.\n- `$DFix` is only for tiny design/content edits and bypasses the main pipeline, Team, TriWiki/TriFix/reflection recording, and persistent route state; it still uses a one-line DFix-specific Honest check before final. `$PPT` is the restrained, information-first HTML/PDF presentation route and must seal delivery context, audience profile, STP, decision context, and 3+ pain-point/solution/aha mappings before design/render work. It must avoid over-designed visuals, carry detail through hierarchy, spacing, alignment, thin rules, source clarity, and subtle accents, preserve editable source HTML under `source-html/`, and clean PPT-only temporary build files before completion. `$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`. Design-system and presentation-like HTML/PDF work consults getdesign.md / getdesign-reference first; image/logo/raster assets use `imagegen`, which must prefer official Codex App built-in image generation via `$imagegen` / `gpt-image-2` before API generation.\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- Treat handwritten files above 3000 lines as split-review risks. Run `sks code-structure scan` and prefer extraction before adding substantial logic.\n- Skill dreaming stays lightweight: route use records JSON counters in `.sneakoscope/skills/dream-state.json`, and full skill inventory/recommendation runs only after the configured count/cooldown threshold. Reports are recommendation-only; deleting or merging skills needs explicit user approval.\n\n## Evidence And Context\n\n- Context7 is required for external libraries, APIs, MCPs, package managers, SDKs, and generated docs: resolve-library-id then query-docs.\n- When tech stack, framework, package, runtime, or deployment-platform versions change, use Context7 or official vendor web docs, record current syntax/security/limit guidance as high-priority TriWiki claims, then refresh and validate before coding.\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, use `attention.use_first` for compact high-trust recall, hydrate `attention.hydrate_first` from source before risky or lower-trust decisions, 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- Final response before stop: summarize what was done, what changed for the user/repo, what was verified, and what remains unverified or blocked; then run Honest Mode. Say what passed and what was not verified.\n- `$From-Chat-IMG` uses forensic visual effort, not ordinary Team effort. Completion is blocked until source inventory, visual mapping, work-order coverage, scoped dogfood/QA, and post-fix verification artifacts are present and valid.\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- MAD and MAD-SKS widen only explicit scoped permissions; they still do not authorize unrequested fallback implementation code.\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`, `$computer-use`, `$cu`, `$ppt`, `$goal`, `$dfix`, `$qa-loop`, etc.) as the app control surface.\n";
|
|
94
|
+
const AGENTS_BLOCK = "\n# Sneakoscope Codex Managed Rules\n\nThis repository uses Sneakoscope Codex.\n\n## Core Rules\n\n- Codex native `/goal` workflows are the persisted continuation surface; Ralph is removed from the user-facing SKS surface.\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- Do not create unrequested fallback implementation code. If the requested path is impossible, block with evidence instead of inventing substitute behavior.\n\n## Routes\n\n- General execution/code-changing prompts default to `$Team`: analysis scouts, TriWiki refresh/validate, read-only debate, consensus, concrete runtime task graph/inboxes, fresh executor team, review, integration, Honest Mode.\n- `$Computer-Use` / `$CU` is the maximum-speed Codex Computer Use lane for UI/browser/visual tasks: skip Team debate and upfront TriWiki loops, use Codex Computer Use directly, then refresh/validate TriWiki and run Honest Mode at final closeout.\n- `$Goal` is a fast bridge/overlay for Codex native `/goal` create/pause/resume/clear persistence controls; implementation continues through the selected SKS execution route.\n- TriWiki recall must stay bounded. Use `sks wiki sweep` to record demote, soft-forget, archive, delete, promote-to-skill, and promote-to-rule candidates instead of injecting every old claim.\n- Team missions must keep schema-backed evidence current: `work-order-ledger.json`, `effort-decision.json`, `team-dashboard-state.json`, and route-specific visual/dogfood artifacts where applicable. Use `sks validate-artifacts latest` before claiming those artifacts pass.\n- `$DFix` is only for tiny design/content edits and bypasses the main pipeline, Team, TriWiki/TriFix/reflection recording, and persistent route state; it still uses a one-line DFix-specific Honest check before final. `$PPT` is the restrained, information-first HTML/PDF presentation route and must seal delivery context, audience profile, STP, decision context, and 3+ pain-point/solution/aha mappings before design/render work. It must avoid over-designed visuals, carry detail through hierarchy, spacing, alignment, thin rules, source clarity, and subtle accents, preserve editable source HTML under `source-html/`, record `ppt-parallel-report.json`, and clean PPT-only temporary build files before completion. `$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`. Design-system and presentation-like HTML/PDF work consults getdesign.md / getdesign-reference first; image/logo/raster assets use `imagegen`, which must prefer official Codex App built-in image generation via `$imagegen` / `gpt-image-2` before API generation.\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- Treat handwritten files above 3000 lines as split-review risks. Run `sks code-structure scan` and prefer extraction before adding substantial logic.\n- Skill dreaming stays lightweight: route use records JSON counters in `.sneakoscope/skills/dream-state.json`, and full skill inventory/recommendation runs only after the configured count/cooldown threshold. Reports are recommendation-only; deleting or merging skills needs explicit user approval.\n\n## Evidence And Context\n\n- Context7 is required for external libraries, APIs, MCPs, package managers, SDKs, and generated docs: resolve-library-id then query-docs.\n- When tech stack, framework, package, runtime, or deployment-platform versions change, use Context7 or official vendor web docs, record current syntax/security/limit guidance as high-priority TriWiki claims, then refresh and validate before coding.\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, use `attention.use_first` for compact high-trust recall, hydrate `attention.hydrate_first` from source before risky or lower-trust decisions, 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- Final response before stop: summarize what was done, what changed for the user/repo, what was verified, and what remains unverified or blocked; then run Honest Mode. Say what passed and what was not verified.\n- `$From-Chat-IMG` uses forensic visual effort, not ordinary Team effort. Completion is blocked until source inventory, visual mapping, work-order coverage, scoped dogfood/QA, and post-fix verification artifacts are present and valid.\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- MAD and MAD-SKS widen only explicit scoped permissions; they still do not authorize unrequested fallback implementation code.\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`, `$computer-use`, `$cu`, `$ppt`, `$goal`, `$dfix`, `$qa-loop`, etc.) as the app control surface.\n";
|
|
95
95
|
|
|
96
96
|
export async function initProject(root, opts = {}) {
|
|
97
97
|
const created = [];
|
|
@@ -522,7 +522,7 @@ function codexAppQuickReference(scope, commandPrefix) {
|
|
|
522
522
|
`Install scope: \`${scope}\``,
|
|
523
523
|
`Command: \`${commandPrefix} <command>\``,
|
|
524
524
|
'Files: AGENTS.md, .codex/hooks.json, .codex/config.toml, .codex/SNEAKOSCOPE.md, .agents/skills, .codex/agents, .sneakoscope/missions.',
|
|
525
|
-
`Discover: ${commandPrefix} bootstrap; ${commandPrefix} deps check; ${commandPrefix} commands; ${commandPrefix} codex-app check; ${commandPrefix}
|
|
525
|
+
`Discover: ${commandPrefix} bootstrap; ${commandPrefix} deps check; ${commandPrefix} commands; ${commandPrefix} codex-app check; ${commandPrefix} tmux check; ${commandPrefix} dollar-commands; ${commandPrefix} pipeline status; ${commandPrefix} pipeline plan.`,
|
|
526
526
|
'dollar-commands:',
|
|
527
527
|
...DOLLAR_COMMANDS.map((c) => `- \`${c.command}\`: ${c.route}`),
|
|
528
528
|
`Picker skills: ${DOLLAR_COMMAND_ALIASES.map((x) => x.app_skill).join(', ')}.`,
|
|
@@ -532,8 +532,8 @@ function codexAppQuickReference(scope, commandPrefix) {
|
|
|
532
532
|
`Runtime root: ${commandPrefix} root shows whether SKS is using the nearest project root or the per-user global SKS runtime root; outside any project marker, runtime commands use the global root instead of writing .sneakoscope into the current random directory.`,
|
|
533
533
|
`Context Tracking: TriWiki SSOT. Before each route phase read only the latest coordinate+voxel overlay pack at .sneakoscope/wiki/context-pack.json; coordinate-only legacy packs are invalid. Use attention.use_first for compact high-trust recall and hydrate attention.hydrate_first from source before risky/lower-trust decisions. During every stage hydrate low-trust claims from source/hash/RGBA anchors; after changes run ${commandPrefix} wiki refresh or pack; before handoff/final run ${commandPrefix} wiki validate .sneakoscope/wiki/context-pack.json.`,
|
|
534
534
|
stackCurrentDocsPolicyText(commandPrefix),
|
|
535
|
-
`Team
|
|
536
|
-
`Runtime: open Codex App once, then run ${commandPrefix} bootstrap, ${commandPrefix} deps check, or ${commandPrefix}
|
|
535
|
+
`Team tmux view: ${commandPrefix} team "task" prepares live watch/lane commands without opening tmux by default; add --open-tmux when you explicitly want a named tmux session with an overview watch pane plus color-coded split per-agent lanes; ${commandPrefix} team lane latest --agent analysis_scout_1 --follow shows one agent's status, assigned runtime tasks, recent agent events, direct messages, and fallback global tail; ${commandPrefix} team message latest --from analysis_scout_1 --to executor_1 --message "handoff note" mirrors bounded agent communication into transcript/lane panes; ${commandPrefix} team cleanup-tmux latest marks the SKS session record complete and asks follow panes to show a cleanup summary then stop.`,
|
|
536
|
+
`Runtime: open Codex App once, then run ${commandPrefix} bootstrap, ${commandPrefix} deps check, or ${commandPrefix} tmux open when you explicitly want a tmux/Codex CLI launch.`,
|
|
537
537
|
`Guard: generated harness files are immutable outside the engine source repo; check ${commandPrefix} guard check; conflicts use ${commandPrefix} conflicts prompt with human approval.`
|
|
538
538
|
].join('\n') + '\n';
|
|
539
539
|
}
|
|
@@ -544,10 +544,10 @@ export async function installSkills(root) {
|
|
|
544
544
|
'answer': `---\nname: answer\ndescription: Answer-only research route for ordinary questions that should not start implementation.\n---\n\nUse for explanations, comparisons, status, facts, source-backed research, or docs guidance. Use repo/TriWiki first for project-local facts; hydrate low-trust claims from source. Browse or use Context7 for current external package/API/framework/MCP docs. End with a concise answer summary plus Honest Mode; do not create missions, subagents, or file edits.\n`,
|
|
545
545
|
'sks': `---\nname: sks\ndescription: General Sneakoscope Codex command route for $SKS or $sks usage, setup, status, and workflow help.\n---\n\nUse local SKS commands: bootstrap, deps, commands, quickstart, codex-app, context7, guard, conflicts, reasoning, wiki, pipeline status, pipeline plan, skill-dream. Promote code-changing work to Team unless Answer/DFix/Help/Wiki/safety route fits. Surface route/guard/scope, use TriWiki, do not edit installed harness files outside this engine repo, and require human-approved conflict cleanup. ${skillDreamPolicyText()}\n`,
|
|
546
546
|
'wiki': `---\nname: wiki\ndescription: Dollar-command route for $Wiki TriWiki refresh, pack, validate, and prune commands.\n---\n\nUse for $Wiki or Korean wiki-refresh requests. Refresh/update/갱신: run sks wiki refresh, then validate .sneakoscope/wiki/context-pack.json. Pack: run sks wiki pack, then validate. Prune/clean/정리: use sks wiki refresh --prune, or sks wiki prune --dry-run for inspection. Report claims, anchors, trust, attention.use_first/hydrate_first, validation, and blockers. Do not start ambiguity-gated implementation, subagents, or unrelated work.\n`,
|
|
547
|
-
'team': `---\nname: team\ndescription: SKS Team orchestration for $Team/code work; $From-Chat-IMG is the explicit chat-image alias.\n---\n\nUse for $Team/code work. Ambiguity gate first. Read pipeline-plan.json or run sks pipeline plan to see the runtime lane, kept/skipped stages, and verification before implementation. Write team-roster.json; team-gate.json needs team_roster_confirmed=true. executor:N means N scouts, N debate voices, then fresh N executors. After consensus, compile team-graph.json, team-runtime-tasks.json, team-decomposition-report.json, and team-inbox/ so worker handoff uses concrete runtime task ids with role/path/domain/lane hints. Refresh/validate TriWiki before debate, implementation, review, and final; consume attention.use_first and hydrate attention.hydrate_first before risky decisions. ${outcomeRubricPolicyText()} ${speedLanePolicyText()} ${skillDreamPolicyText()} Log events and use sks team message for bounded inter-agent communication in transcript/lane panes. Color-coded
|
|
547
|
+
'team': `---\nname: team\ndescription: SKS Team orchestration for $Team/code work; $From-Chat-IMG is the explicit chat-image alias.\n---\n\nUse for $Team/code work. Ambiguity gate first. Read pipeline-plan.json or run sks pipeline plan to see the runtime lane, kept/skipped stages, and verification before implementation. Write team-roster.json; team-gate.json needs team_roster_confirmed=true. executor:N means N scouts, N debate voices, then fresh N executors. After consensus, compile team-graph.json, team-runtime-tasks.json, team-decomposition-report.json, and team-inbox/ so worker handoff uses concrete runtime task ids with role/path/domain/lane hints. Refresh/validate TriWiki before debate, implementation, review, and final; consume attention.use_first and hydrate attention.hydrate_first before risky decisions. ${outcomeRubricPolicyText()} ${speedLanePolicyText()} ${skillDreamPolicyText()} Log events and use sks team message for bounded inter-agent communication in transcript/lane panes. Color-coded tmux lanes distinguish overview/scout/planning/execution/review/safety sessions. End with cleanup-tmux or a cleanup event so follow panes show cleanup and stop; pass team-session-cleanup.json, then reflection and Honest Mode. Parent integrates/verifies.\n\n${chatCaptureIntakeText()}\n`,
|
|
548
548
|
'from-chat-img': `---\nname: from-chat-img\ndescription: Explicit $From-Chat-IMG Team alias for chat screenshot plus attachment analysis.\n---\n\nUse only for From-Chat-IMG/$From-Chat-IMG. It enters the normal Team pipeline. Treat uploads as chat screenshot plus originals. Use Codex Computer Use visual inspection when available, list requirements first, match regions to attachments with confidence, write ${FROM_CHAT_IMG_COVERAGE_ARTIFACT}, ${FROM_CHAT_IMG_CHECKLIST_ARTIFACT}, ${FROM_CHAT_IMG_TEMP_TRIWIKI_ARTIFACT}, and ${FROM_CHAT_IMG_QA_LOOP_ARTIFACT}, then continue Team gates, review, reflection, and Honest Mode. ${CODEX_COMPUTER_USE_ONLY_POLICY} The ledger must account for every visible customer request, screenshot image region, and separate attachment; ${FROM_CHAT_IMG_CHECKLIST_ARTIFACT} must have a checked item for each request, image-region/attachment match, work item, scoped QA-LOOP, and verification step; ${FROM_CHAT_IMG_TEMP_TRIWIKI_ARTIFACT} stores temporary TriWiki-backed session context with expires_after_sessions=${FROM_CHAT_IMG_TEMP_TRIWIKI_SESSIONS}. ${FROM_CHAT_IMG_QA_LOOP_ARTIFACT} must prove QA-LOOP ran over the exact customer-request work-order range after implementation, with every work item covered, post-fix verification complete, and zero unresolved findings. team-gate.json cannot pass From-Chat-IMG completion until unresolved_items is empty, every checklist box is checked, and scoped_qa_loop_completed=true.\n`,
|
|
549
549
|
'qa-loop': `---\nname: qa-loop\ndescription: $QA-LOOP dogfoods UI/API as human proxy with safety gates, Codex Computer Use-only UI evidence, safe fixes, rechecks, and a QA report.\n---\n\nUse only $QA-LOOP. Ask scope, target, mutation, login. Credentials are runtime-only; never save secrets. UI-level E2E needs Codex Computer Use evidence or must be marked unverified; Chrome MCP, Browser Use, Playwright, Selenium, Puppeteer, and other browser automation do not satisfy UI/browser verification. Deployed targets are read-only; destructive removal is forbidden. After answer/run, dogfood real flows, apply safe contract-allowed code/test/docs fixes, recheck, and do not pass qa-gate.json with unresolved findings or without post_fix_verification_complete. Finish qa-ledger, date/version report, gate, completion summary, and Honest Mode.\n`,
|
|
550
|
-
'ppt': `---\nname: ppt\ndescription: $PPT information-first HTML/PDF presentation pipeline with STP, audience, pain-point, format, research, design-system, and verification questions.\n---\n\nUse only when the user invokes $PPT or asks to create a presentation, deck, slides, pitch deck, proposal deck, HTML presentation, or PDF presentation artifact. Before artifact work, seal presentation-specific ambiguity answers: delivery context, target audience profile including role/average age/job/industry/topic familiarity/decision power, STP strategy, decision context and objections, and 3+ pain-point to solution mappings with expected aha moments. Presentation design must be simple, restrained, and information-first: avoid over-designed decoration, ornamental gradients, nested cards, and effects that compete with the message. Design detail should be embedded through typography hierarchy, spacing, alignment, thin rules, source clarity, and subtle accents. Use getdesign-reference and design-artifact-expert for design-system grounding. If generated image assets are needed, use imagegen and prefer Codex App built-in image generation (${CODEX_APP_IMAGE_GENERATION_DOC_URL}) before API generation. Use web or Context7 evidence when external facts/libraries are involved, then create the PDF plus editable source HTML under source-html/, verify readability, overlap, format fit, source coverage, export state, and temporary build files cleanup. Finish with reflection and Honest Mode; do not skip STP/audience questions for presentation artifacts.\n`,
|
|
550
|
+
'ppt': `---\nname: ppt\ndescription: $PPT information-first HTML/PDF presentation pipeline with STP, audience, pain-point, format, research, design-system, and verification questions.\n---\n\nUse only when the user invokes $PPT or asks to create a presentation, deck, slides, pitch deck, proposal deck, HTML presentation, or PDF presentation artifact. Before artifact work, seal presentation-specific ambiguity answers: delivery context, target audience profile including role/average age/job/industry/topic familiarity/decision power, STP strategy, decision context and objections, and 3+ pain-point to solution mappings with expected aha moments. Presentation design must be simple, restrained, and information-first: avoid over-designed decoration, ornamental gradients, nested cards, and effects that compete with the message. Design detail should be embedded through typography hierarchy, spacing, alignment, thin rules, source clarity, and subtle accents. Use getdesign-reference and design-artifact-expert for design-system grounding. If generated image assets are needed, use imagegen and prefer Codex App built-in image generation (${CODEX_APP_IMAGE_GENERATION_DOC_URL}) before API generation. Use web or Context7 evidence when external facts/libraries are involved, then create the PDF plus editable source HTML under source-html/, keep independent strategy/render/file-write phases parallel where inputs allow, record ppt-parallel-report.json, and verify readability, overlap, format fit, source coverage, export state, and temporary build files cleanup. Finish with reflection and Honest Mode; do not skip STP/audience questions for presentation artifacts.\n`,
|
|
551
551
|
'computer-use': `---\nname: computer-use\ndescription: Maximum-speed $Computer-Use/$CU lane for Codex Computer Use UI/browser/visual tasks.\n---\n\nUse only when the user invokes $Computer-Use/$CU or asks for a Computer Use-specific fast lane. Skip Team debate, QA-LOOP clarification, upfront TriWiki refresh, Context7, subagents, and reflection unless explicitly requested. Infer the smallest target, use Codex Computer Use directly, and never substitute Playwright, Chrome MCP, Browser Use, Selenium, Puppeteer, or other browser automation for UI/browser evidence. If Computer Use is unavailable, mark UI/browser evidence unverified and stop with the blocker. At the end only, refresh or pack TriWiki, validate it, then provide a concise completion summary plus Honest Mode.\n`,
|
|
552
552
|
'computer-use-fast': `---\nname: computer-use-fast\ndescription: Alias for the maximum-speed $Computer-Use/$CU Codex Computer Use lane.\n---\n\nUse the same rules as computer-use: skip Team debate, QA-LOOP clarification, upfront TriWiki refresh, Context7, subagents, and reflection unless explicitly requested. Use Codex Computer Use directly; never substitute Playwright, Chrome MCP, Browser Use, Selenium, Puppeteer, or other browser automation for UI/browser evidence. At the end only, refresh/pack TriWiki, validate it, then provide a concise completion summary plus Honest Mode.\n`,
|
|
553
553
|
'cu': `---\nname: cu\ndescription: Short alias for the maximum-speed $Computer-Use Codex Computer Use lane.\n---\n\nUse the same rules as computer-use. This is a speed lane for focused UI/browser/visual tasks that require Codex Computer Use evidence, with TriWiki refresh/validate and Honest Mode deferred to final closeout.\n`,
|
package/src/core/pipeline.mjs
CHANGED
|
@@ -245,7 +245,7 @@ export function promptPipelineContext(prompt, route = routePrompt(prompt)) {
|
|
|
245
245
|
if (reflectionRequiredForRoute(route)) lines.push(reflectionInstructionText());
|
|
246
246
|
if (route?.id === 'Team') lines.push(`Team route: scouts, TriWiki refresh, debate, consensus, runtime graph compile with concrete task ids and worker inboxes, close planning agents, fresh executors, review/integration, ${TEAM_SESSION_CLEANUP_ARTIFACT}, reflection, and Honest Mode.`);
|
|
247
247
|
if (route?.id === 'Goal') lines.push('Goal route: write SKS goal bridge artifacts, then use Codex native /goal persistence for create, pause, resume, and clear continuation controls.');
|
|
248
|
-
if (route?.id === 'PPT') lines.push(`PPT route: before design or PDF work, seal delivery context, audience profile including average age/job/industry, STP strategy, decision context, and at least three pain-point to solution mappings. Keep the visual system simple, restrained, and information-first; design detail should come from hierarchy, spacing, alignment, rules, and subtle accents rather than decorative overdesign. If generated image assets are needed, prefer Codex App built-in image generation through the imagegen skill (${CODEX_APP_IMAGE_GENERATION_DOC_URL}). Then build source ledger, storyboard with aha moments, style tokens, editable source HTML under source-html/, PDF artifact, render QA, PPT-only temporary build file cleanup,
|
|
248
|
+
if (route?.id === 'PPT') lines.push(`PPT route: before design or PDF work, seal delivery context, audience profile including average age/job/industry, STP strategy, decision context, and at least three pain-point to solution mappings. Keep the visual system simple, restrained, and information-first; design detail should come from hierarchy, spacing, alignment, rules, and subtle accents rather than decorative overdesign. If generated image assets are needed, prefer Codex App built-in image generation through the imagegen skill (${CODEX_APP_IMAGE_GENERATION_DOC_URL}). Then build source ledger, storyboard with aha moments, style tokens, editable source HTML under source-html/, PDF artifact, render QA, PPT-only temporary build file cleanup, and ppt-parallel-report.json so independent strategy/render/file-write phases stay parallel-friendly, then reflection and Honest Mode.`);
|
|
249
249
|
if (route?.id === 'AutoResearch') lines.push('AutoResearch route: load autoresearch-loop plus seo-geo-optimizer when SEO/GEO, discoverability, README, npm, GitHub stars, ranking, or AI-search visibility is relevant.');
|
|
250
250
|
if (route?.id === 'DB') lines.push('DB route: scan/check database risk first; destructive DB operations remain forbidden.');
|
|
251
251
|
if (route?.id === 'GX') lines.push('GX route: use deterministic vgraph/beta render, validate, drift, and snapshot artifacts.');
|
|
@@ -584,7 +584,7 @@ async function prepareTeam(root, route, task, required) {
|
|
|
584
584
|
markdown: 'team-live.md',
|
|
585
585
|
transcript: 'team-transcript.jsonl',
|
|
586
586
|
dashboard: 'team-dashboard.json',
|
|
587
|
-
|
|
587
|
+
tmux: 'CLI Team entrypoints open tmux live lanes for the visible Team agent budget when tmux is available.',
|
|
588
588
|
commands: ['sks team status latest', 'sks team log latest', 'sks team tail latest', 'sks team watch latest', 'sks team lane latest --agent <name> --follow', 'sks team event latest --agent <name> --phase <phase> --message "..."']
|
|
589
589
|
},
|
|
590
590
|
required_artifacts: ['team-roster.json', 'team-analysis.md', ...(fromChatImgRequired ? [FROM_CHAT_IMG_COVERAGE_ARTIFACT, FROM_CHAT_IMG_CHECKLIST_ARTIFACT, FROM_CHAT_IMG_TEMP_TRIWIKI_ARTIFACT, FROM_CHAT_IMG_QA_LOOP_ARTIFACT] : []), 'team-consensus.md', ...teamRuntimeRequiredArtifacts(), 'team-review.md', 'team-gate.json', TEAM_SESSION_CLEANUP_ARTIFACT, 'reflection.md', 'reflection-gate.json', 'team-live.md', 'team-transcript.jsonl', 'team-dashboard.json', '.sneakoscope/wiki/context-pack.json', 'context7-evidence.jsonl']
|
package/src/core/ppt.mjs
CHANGED
|
@@ -12,6 +12,7 @@ export const PPT_HTML_ARTIFACT = `${PPT_SOURCE_HTML_DIR}/artifact.html`;
|
|
|
12
12
|
export const PPT_PDF_ARTIFACT = 'artifact.pdf';
|
|
13
13
|
export const PPT_RENDER_REPORT_ARTIFACT = 'ppt-render-report.json';
|
|
14
14
|
export const PPT_CLEANUP_REPORT_ARTIFACT = 'ppt-cleanup-report.json';
|
|
15
|
+
export const PPT_PARALLEL_REPORT_ARTIFACT = 'ppt-parallel-report.json';
|
|
15
16
|
export const PPT_TEMP_DIR = 'ppt-tmp';
|
|
16
17
|
|
|
17
18
|
export const PPT_REQUIRED_GATE_FIELDS = Object.freeze([
|
|
@@ -20,6 +21,7 @@ export const PPT_REQUIRED_GATE_FIELDS = Object.freeze([
|
|
|
20
21
|
'source_ledger_created',
|
|
21
22
|
'storyboard_created',
|
|
22
23
|
'style_tokens_created',
|
|
24
|
+
'parallel_build_recorded',
|
|
23
25
|
'html_artifact_created',
|
|
24
26
|
'source_html_preserved',
|
|
25
27
|
'pdf_exported_or_explicitly_deferred',
|
|
@@ -83,6 +85,62 @@ function normalizePainpoints(answers = {}) {
|
|
|
83
85
|
});
|
|
84
86
|
}
|
|
85
87
|
|
|
88
|
+
function msSince(startedAt) {
|
|
89
|
+
return Math.max(0, Date.now() - startedAt);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function createPptParallelReporter(contract = {}) {
|
|
93
|
+
const report = {
|
|
94
|
+
schema_version: 1,
|
|
95
|
+
created_at: nowIso(),
|
|
96
|
+
contract_hash: contract.sealed_hash || null,
|
|
97
|
+
strategy: 'parallelize_independent_ppt_artifact_phases_without_changing_output_semantics',
|
|
98
|
+
parallel_groups: [],
|
|
99
|
+
dependency_graph: [
|
|
100
|
+
{ id: 'strategy_inputs', depends_on: ['sealed_decision_contract'], can_run_parallel: ['audience_strategy', 'source_ledger', 'style_tokens'] },
|
|
101
|
+
{ id: 'storyboard_phase', depends_on: ['audience_strategy'] },
|
|
102
|
+
{ id: 'render_targets', depends_on: ['storyboard', 'style_tokens', 'source_ledger'], can_run_parallel: ['html_source', 'pdf_export'] },
|
|
103
|
+
{ id: 'artifact_writes', depends_on: ['strategy_inputs', 'storyboard_phase', 'render_targets'], can_run_parallel: ['json_artifacts', 'html_source_write', 'pdf_write'] },
|
|
104
|
+
{ id: 'final_reports', depends_on: ['artifact_writes', 'cleanup'], can_run_parallel: ['cleanup_report_write', 'parallel_report_write'] }
|
|
105
|
+
],
|
|
106
|
+
notes: [
|
|
107
|
+
'This report records deterministic Promise.all groups used by the built-in PPT builder.',
|
|
108
|
+
'External web research, image generation, and design critique should use the same split: sources, STP/audience synthesis, style tokens, storyboard, assets, render QA, and cleanup as separable lanes when their inputs are available.'
|
|
109
|
+
]
|
|
110
|
+
};
|
|
111
|
+
return {
|
|
112
|
+
async group(id, tasks = {}) {
|
|
113
|
+
const entries = Object.entries(tasks);
|
|
114
|
+
const started = Date.now();
|
|
115
|
+
const startedAt = nowIso();
|
|
116
|
+
const values = await Promise.all(entries.map(async ([taskId, task]) => {
|
|
117
|
+
const taskStarted = Date.now();
|
|
118
|
+
const value = await task();
|
|
119
|
+
return [taskId, value, { id: taskId, duration_ms: msSince(taskStarted) }];
|
|
120
|
+
}));
|
|
121
|
+
report.parallel_groups.push({
|
|
122
|
+
id,
|
|
123
|
+
started_at: startedAt,
|
|
124
|
+
duration_ms: msSince(started),
|
|
125
|
+
task_count: entries.length,
|
|
126
|
+
tasks: values.map(([, , meta]) => meta),
|
|
127
|
+
executed_in_parallel: entries.length > 1
|
|
128
|
+
});
|
|
129
|
+
return Object.fromEntries(values.map(([taskId, value]) => [taskId, value]));
|
|
130
|
+
},
|
|
131
|
+
report() {
|
|
132
|
+
const groups = report.parallel_groups;
|
|
133
|
+
return {
|
|
134
|
+
...report,
|
|
135
|
+
completed_at: nowIso(),
|
|
136
|
+
total_groups: groups.length,
|
|
137
|
+
parallel_group_count: groups.filter((group) => group.executed_in_parallel).length,
|
|
138
|
+
passed: groups.some((group) => group.executed_in_parallel)
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
86
144
|
export function buildPptAudienceStrategy(contract = {}) {
|
|
87
145
|
const answers = contract.answers || {};
|
|
88
146
|
const painpoints = normalizePainpoints(answers);
|
|
@@ -414,6 +472,7 @@ export function buildPptRenderReport({ contract = {}, audience, sourceLedger, st
|
|
|
414
472
|
unsupported_external_claims: 0
|
|
415
473
|
},
|
|
416
474
|
editable_source_html: PPT_HTML_ARTIFACT,
|
|
475
|
+
parallel_build_report: PPT_PARALLEL_REPORT_ARTIFACT,
|
|
417
476
|
output_files: [PPT_HTML_ARTIFACT, PPT_PDF_ARTIFACT],
|
|
418
477
|
notes: [
|
|
419
478
|
'This build is deterministic and dependency-free. Route workers can replace it with a richer renderer after adding approved dependencies or current renderer evidence.'
|
|
@@ -491,7 +550,8 @@ export async function buildPptCleanupReport(dir) {
|
|
|
491
550
|
PPT_HTML_ARTIFACT,
|
|
492
551
|
PPT_PDF_ARTIFACT,
|
|
493
552
|
PPT_RENDER_REPORT_ARTIFACT,
|
|
494
|
-
PPT_CLEANUP_REPORT_ARTIFACT
|
|
553
|
+
PPT_CLEANUP_REPORT_ARTIFACT,
|
|
554
|
+
PPT_PARALLEL_REPORT_ARTIFACT
|
|
495
555
|
],
|
|
496
556
|
notes: [
|
|
497
557
|
'The editable HTML source is retained under source-html/ so future PDF revisions do not depend on transient build files.'
|
|
@@ -519,6 +579,7 @@ export function defaultPptGate(contract = {}) {
|
|
|
519
579
|
source_ledger_created: false,
|
|
520
580
|
storyboard_created: false,
|
|
521
581
|
style_tokens_created: false,
|
|
582
|
+
parallel_build_recorded: false,
|
|
522
583
|
html_artifact_created: false,
|
|
523
584
|
source_html_preserved: false,
|
|
524
585
|
pdf_exported_or_explicitly_deferred: false,
|
|
@@ -533,12 +594,14 @@ export function defaultPptGate(contract = {}) {
|
|
|
533
594
|
PPT_HTML_ARTIFACT,
|
|
534
595
|
'artifact.pdf or explicit PDF deferral note',
|
|
535
596
|
'ppt-render-report.json',
|
|
536
|
-
'ppt-cleanup-report.json'
|
|
597
|
+
'ppt-cleanup-report.json',
|
|
598
|
+
'ppt-parallel-report.json'
|
|
537
599
|
],
|
|
538
600
|
notes: [
|
|
539
601
|
'Do not pass this gate until the HTML/PDF artifact work is actually complete or the PDF export is explicitly deferred with evidence.',
|
|
540
602
|
'Audience strategy must stay linked to STP, target pain points, proof, and three or more aha moments.',
|
|
541
|
-
'Preserve the editable HTML source under source-html/ and remove PPT-only temporary build files before completion.'
|
|
603
|
+
'Preserve the editable HTML source under source-html/ and remove PPT-only temporary build files before completion.',
|
|
604
|
+
'Record independent PPT build phases in ppt-parallel-report.json so research/design/render work can stay parallel-friendly.'
|
|
542
605
|
]
|
|
543
606
|
};
|
|
544
607
|
}
|
|
@@ -556,30 +619,45 @@ export async function writePptRouteArtifacts(dir, contract = {}) {
|
|
|
556
619
|
|
|
557
620
|
export async function writePptBuildArtifacts(dir, contract = null) {
|
|
558
621
|
const sealed = contract || await readJson(path.join(dir, 'decision-contract.json'));
|
|
559
|
-
const
|
|
560
|
-
const
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
622
|
+
const parallel = createPptParallelReporter(sealed);
|
|
623
|
+
const initial = await parallel.group('strategy_inputs', {
|
|
624
|
+
audience: async () => buildPptAudienceStrategy(sealed),
|
|
625
|
+
sourceLedger: async () => buildPptSourceLedger(sealed),
|
|
626
|
+
styleTokens: async () => buildPptStyleTokens(sealed)
|
|
627
|
+
});
|
|
628
|
+
const { audience, sourceLedger, styleTokens } = initial;
|
|
629
|
+
const { storyboard } = await parallel.group('storyboard_phase', {
|
|
630
|
+
storyboard: async () => buildPptStoryboard(sealed, audience)
|
|
631
|
+
});
|
|
632
|
+
const { html, pdfBytes } = await parallel.group('render_targets', {
|
|
633
|
+
html: async () => buildPptHtml({ contract: sealed, audience, sourceLedger, storyboard, styleTokens }),
|
|
634
|
+
pdfBytes: async () => makePdf(storyboard, styleTokens)
|
|
635
|
+
});
|
|
565
636
|
const report = buildPptRenderReport({ contract: sealed, audience, sourceLedger, storyboard, styleTokens, html, pdfBytes });
|
|
566
|
-
await
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
637
|
+
await parallel.group('artifact_writes', {
|
|
638
|
+
audience_strategy: async () => writeJsonAtomic(path.join(dir, PPT_AUDIENCE_STRATEGY_ARTIFACT), audience),
|
|
639
|
+
source_ledger: async () => writeJsonAtomic(path.join(dir, PPT_SOURCE_LEDGER_ARTIFACT), sourceLedger),
|
|
640
|
+
storyboard: async () => writeJsonAtomic(path.join(dir, PPT_STORYBOARD_ARTIFACT), storyboard),
|
|
641
|
+
style_tokens: async () => writeJsonAtomic(path.join(dir, PPT_STYLE_TOKENS_ARTIFACT), styleTokens),
|
|
642
|
+
html_source: async () => writeTextAtomic(path.join(dir, PPT_HTML_ARTIFACT), html),
|
|
643
|
+
pdf: async () => fsp.writeFile(path.join(dir, PPT_PDF_ARTIFACT), pdfBytes),
|
|
644
|
+
render_report: async () => writeJsonAtomic(path.join(dir, PPT_RENDER_REPORT_ARTIFACT), report)
|
|
645
|
+
});
|
|
573
646
|
const cleanupReport = await buildPptCleanupReport(dir);
|
|
574
|
-
|
|
647
|
+
const parallelReport = parallel.report();
|
|
648
|
+
await parallel.group('final_reports', {
|
|
649
|
+
cleanup_report: async () => writeJsonAtomic(path.join(dir, PPT_CLEANUP_REPORT_ARTIFACT), cleanupReport),
|
|
650
|
+
parallel_report: async () => writeJsonAtomic(path.join(dir, PPT_PARALLEL_REPORT_ARTIFACT), parallelReport)
|
|
651
|
+
});
|
|
575
652
|
const baseGate = defaultPptGate(sealed);
|
|
576
653
|
const gate = {
|
|
577
654
|
...baseGate,
|
|
578
|
-
passed: report.passed && cleanupReport.source_html_preserved && cleanupReport.temp_cleanup_completed,
|
|
655
|
+
passed: report.passed && cleanupReport.source_html_preserved && cleanupReport.temp_cleanup_completed && parallelReport.passed,
|
|
579
656
|
audience_strategy_sealed: baseGate.audience_strategy_sealed,
|
|
580
657
|
source_ledger_created: true,
|
|
581
658
|
storyboard_created: true,
|
|
582
659
|
style_tokens_created: true,
|
|
660
|
+
parallel_build_recorded: parallelReport.passed,
|
|
583
661
|
html_artifact_created: true,
|
|
584
662
|
source_html_preserved: cleanupReport.source_html_preserved,
|
|
585
663
|
pdf_exported_or_explicitly_deferred: true,
|
|
@@ -588,7 +666,8 @@ export async function writePptBuildArtifacts(dir, contract = null) {
|
|
|
588
666
|
honest_mode_complete: true,
|
|
589
667
|
render_report_passed: report.passed,
|
|
590
668
|
cleanup_report_passed: cleanupReport.source_html_preserved && cleanupReport.temp_cleanup_completed,
|
|
591
|
-
|
|
669
|
+
parallel_report_passed: parallelReport.passed,
|
|
670
|
+
output_files: [PPT_HTML_ARTIFACT, PPT_PDF_ARTIFACT, PPT_RENDER_REPORT_ARTIFACT, PPT_CLEANUP_REPORT_ARTIFACT, PPT_PARALLEL_REPORT_ARTIFACT],
|
|
592
671
|
updated_at: nowIso()
|
|
593
672
|
};
|
|
594
673
|
await writeJsonAtomic(path.join(dir, PPT_GATE_ARTIFACT), gate);
|
|
@@ -597,6 +676,7 @@ export async function writePptBuildArtifacts(dir, contract = null) {
|
|
|
597
676
|
gate,
|
|
598
677
|
report,
|
|
599
678
|
cleanup_report: cleanupReport,
|
|
679
|
+
parallel_report: parallelReport,
|
|
600
680
|
files: {
|
|
601
681
|
audience_strategy: path.join(dir, PPT_AUDIENCE_STRATEGY_ARTIFACT),
|
|
602
682
|
source_ledger: path.join(dir, PPT_SOURCE_LEDGER_ARTIFACT),
|
|
@@ -607,6 +687,7 @@ export async function writePptBuildArtifacts(dir, contract = null) {
|
|
|
607
687
|
pdf: path.join(dir, PPT_PDF_ARTIFACT),
|
|
608
688
|
render_report: path.join(dir, PPT_RENDER_REPORT_ARTIFACT),
|
|
609
689
|
cleanup_report: path.join(dir, PPT_CLEANUP_REPORT_ARTIFACT),
|
|
690
|
+
parallel_report: path.join(dir, PPT_PARALLEL_REPORT_ARTIFACT),
|
|
610
691
|
gate: path.join(dir, PPT_GATE_ARTIFACT)
|
|
611
692
|
}
|
|
612
693
|
};
|
package/src/core/questions.mjs
CHANGED
|
@@ -87,7 +87,7 @@ export function inferAnswersForPrompt(prompt, explicitAnswers = {}) {
|
|
|
87
87
|
.trim();
|
|
88
88
|
const version = String(text || '').match(/\bv?(\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)\b/)?.[1] || null;
|
|
89
89
|
const versionWork = /버전|version|bump|release|publish:dry|npm\s+pack/.test(lower);
|
|
90
|
-
const installWork = /bootstrap|postinstall|doctor|deps|
|
|
90
|
+
const installWork = /bootstrap|postinstall|doctor|deps|tmux|homebrew|first install|최초\s*설치|설치\s*ux|셋업|setup/.test(lower);
|
|
91
91
|
const questionGateWork = /모호|ambiguity|clarification|질문|triwiki|추론|infer|predict|예측|answers?\.json|decision-contract/.test(lower);
|
|
92
92
|
const uiuxWork = /\b(ui|modal|screen|button|visual|design|layout|component|prototype|frontend)\b|화면|버튼|모달|디자인|레이아웃|컴포넌트|프론트|시각|발표자료|디자인\s*시스템/.test(lower);
|
|
93
93
|
const presentationWork = looksLikePresentationArtifactPrompt(lower);
|