synergyspec-selfevolving 1.3.0 → 2.0.0
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 +50 -19
- package/dist/commands/learn.d.ts +12 -1
- package/dist/commands/learn.js +373 -31
- package/dist/commands/self-evolution-episode.d.ts +177 -0
- package/dist/commands/self-evolution-episode.js +423 -0
- package/dist/commands/self-evolution.d.ts +12 -190
- package/dist/commands/self-evolution.js +179 -786
- package/dist/commands/workflow/status.js +3 -1
- package/dist/core/archive.d.ts +0 -1
- package/dist/core/archive.js +0 -58
- package/dist/core/artifact-graph/instruction-loader.d.ts +2 -4
- package/dist/core/artifact-graph/instruction-loader.js +3 -31
- package/dist/core/config-prompts.js +4 -0
- package/dist/core/fitness/health/health-metrics.d.ts +26 -56
- package/dist/core/fitness/health/health-metrics.js +19 -58
- package/dist/core/fitness/health/index.d.ts +15 -2
- package/dist/core/fitness/health/index.js +25 -1
- package/dist/core/fitness/health/local-source.d.ts +43 -4
- package/dist/core/fitness/health/local-source.js +181 -25
- package/dist/core/fitness/health/metric-source.d.ts +48 -19
- package/dist/core/fitness/health/metric-source.js +8 -18
- package/dist/core/fitness/health/resolve-source.js +4 -1
- package/dist/core/fitness/loss.d.ts +7 -7
- package/dist/core/fitness/loss.js +6 -6
- package/dist/core/fitness/sample.d.ts +10 -0
- package/dist/core/fitness/test-failures.d.ts +30 -0
- package/dist/core/fitness/test-failures.js +123 -0
- package/dist/core/learn/credit-path.d.ts +36 -0
- package/dist/core/learn/credit-path.js +198 -0
- package/dist/core/learn/trajectory-discovery.d.ts +39 -0
- package/dist/core/learn/trajectory-discovery.js +140 -0
- package/dist/core/learn.d.ts +39 -5
- package/dist/core/learn.js +131 -14
- package/dist/core/project-config.d.ts +4 -0
- package/dist/core/project-config.js +52 -1
- package/dist/core/self-evolution/candidate-fitness.d.ts +23 -1
- package/dist/core/self-evolution/candidate-fitness.js +31 -5
- package/dist/core/self-evolution/candidates.d.ts +0 -9
- package/dist/core/self-evolution/canonical-targets.d.ts +8 -4
- package/dist/core/self-evolution/canonical-targets.js +8 -4
- package/dist/core/self-evolution/critic-agent.d.ts +150 -0
- package/dist/core/self-evolution/critic-agent.js +487 -0
- package/dist/core/self-evolution/edits-contract.d.ts +53 -0
- package/dist/core/self-evolution/edits-contract.js +89 -0
- package/dist/core/self-evolution/episode-orchestrator.d.ts +197 -0
- package/dist/core/self-evolution/episode-orchestrator.js +534 -0
- package/dist/core/self-evolution/episode-store.d.ts +266 -0
- package/dist/core/self-evolution/episode-store.js +573 -0
- package/dist/core/self-evolution/evolution-switches.d.ts +1 -1
- package/dist/core/self-evolution/evolution-switches.js +5 -10
- package/dist/core/self-evolution/evolving-agent.d.ts +162 -0
- package/dist/core/self-evolution/evolving-agent.js +449 -0
- package/dist/core/self-evolution/health-baseline.d.ts +25 -6
- package/dist/core/self-evolution/health-baseline.js +30 -6
- package/dist/core/self-evolution/host-harness.d.ts +1 -2
- package/dist/core/self-evolution/host-harness.js +1 -2
- package/dist/core/self-evolution/index.d.ts +10 -6
- package/dist/core/self-evolution/index.js +19 -6
- package/dist/core/self-evolution/learn-hints.d.ts +31 -0
- package/dist/core/self-evolution/learn-hints.js +16 -0
- package/dist/core/self-evolution/learn-observation-adapter.d.ts +35 -0
- package/dist/core/self-evolution/learn-observation-adapter.js +285 -10
- package/dist/core/self-evolution/line-diff.d.ts +60 -0
- package/dist/core/self-evolution/line-diff.js +130 -0
- package/dist/core/self-evolution/policy/fs-safe.d.ts +19 -0
- package/dist/core/self-evolution/policy/fs-safe.js +89 -0
- package/dist/core/self-evolution/policy/index.d.ts +13 -0
- package/dist/core/self-evolution/policy/index.js +13 -0
- package/dist/core/self-evolution/policy/policy-store.d.ts +217 -0
- package/dist/core/self-evolution/policy/policy-store.js +774 -0
- package/dist/core/self-evolution/policy/reject-buffer.d.ts +48 -0
- package/dist/core/self-evolution/policy/reject-buffer.js +168 -0
- package/dist/core/self-evolution/promote.d.ts +1 -1
- package/dist/core/self-evolution/promote.js +6 -33
- package/dist/core/self-evolution/promotion.js +1 -2
- package/dist/core/self-evolution/proposer-agent.d.ts +41 -0
- package/dist/core/self-evolution/proposer-agent.js +94 -13
- package/dist/core/self-evolution/proposer-slice.d.ts +26 -0
- package/dist/core/self-evolution/proposer-slice.js +54 -0
- package/dist/core/self-evolution/reward-agent.d.ts +234 -0
- package/dist/core/self-evolution/reward-agent.js +564 -0
- package/dist/core/self-evolution/scope-gate.d.ts +66 -0
- package/dist/core/self-evolution/scope-gate.js +107 -0
- package/dist/core/self-evolution/success-channel.d.ts +79 -0
- package/dist/core/self-evolution/success-channel.js +361 -0
- package/dist/core/self-evolution/target-evolution.d.ts +11 -0
- package/dist/core/self-evolution/target-evolution.js +2 -0
- package/dist/core/self-evolution/tool-evolution.js +2 -13
- package/dist/core/self-evolution/verdict.d.ts +8 -5
- package/dist/core/self-evolution/verdict.js +4 -7
- package/dist/core/templates/skill-templates.d.ts +1 -0
- package/dist/core/templates/skill-templates.js +1 -0
- package/dist/core/templates/workflow-manifest.js +2 -0
- package/dist/core/templates/workflows/learn.d.ts +4 -2
- package/dist/core/templates/workflows/learn.js +25 -166
- package/dist/core/templates/workflows/self-evolving.d.ts +13 -0
- package/dist/core/templates/workflows/self-evolving.js +127 -0
- package/dist/core/trajectory/facts.d.ts +16 -0
- package/dist/core/trajectory/facts.js +12 -4
- package/dist/core/trajectory/skeleton.d.ts +43 -0
- package/dist/core/trajectory/skeleton.js +239 -0
- package/dist/dashboard/data.d.ts +25 -51
- package/dist/dashboard/data.js +68 -180
- package/dist/dashboard/react-client.js +458 -503
- package/dist/dashboard/react-styles.js +3 -3
- package/dist/dashboard/server.js +23 -17
- package/dist/ui/ascii-patterns.d.ts +7 -15
- package/dist/ui/ascii-patterns.js +123 -54
- package/dist/ui/welcome-screen.d.ts +0 -14
- package/dist/ui/welcome-screen.js +16 -35
- package/package.json +3 -1
- package/scripts/code-health.py +1066 -638
- package/scripts/slop_rules.yaml +2151 -0
|
@@ -831,7 +831,7 @@ h1 {
|
|
|
831
831
|
}
|
|
832
832
|
.evolve-main .panel-title,
|
|
833
833
|
.evolve-main .metric-value,
|
|
834
|
-
.evolve-main .
|
|
834
|
+
.evolve-main .episode-name,
|
|
835
835
|
.evolve-main .lineage-node strong { color: #fff; }
|
|
836
836
|
.evolve-main .head-meta,
|
|
837
837
|
.evolve-main .metric-label,
|
|
@@ -1424,7 +1424,7 @@ h1 {
|
|
|
1424
1424
|
}
|
|
1425
1425
|
.run-card:hover { transform: translateY(-2px); box-shadow: var(--shadow-md); border-color: var(--line-strong); }
|
|
1426
1426
|
.run-head { display: flex; justify-content: space-between; gap: 12px; align-items: flex-start; }
|
|
1427
|
-
.
|
|
1427
|
+
.episode-name { color: var(--ink); font-weight: var(--w-semibold); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
1428
1428
|
.run-id { margin-top: 3px; color: var(--muted); font: 11px/1.35 var(--mono); word-break: break-all; }
|
|
1429
1429
|
.donut-wrap { width: 66px; height: 66px; position: relative; flex: 0 0 66px; }
|
|
1430
1430
|
.donut-center { position: absolute; inset: 0; display: grid; place-items: center; color: var(--ink); font-weight: var(--w-semibold); font-size: 13px; }
|
|
@@ -2398,7 +2398,7 @@ h1,
|
|
|
2398
2398
|
.panel-title,
|
|
2399
2399
|
.change-name,
|
|
2400
2400
|
.empty-title,
|
|
2401
|
-
.
|
|
2401
|
+
.episode-name,
|
|
2402
2402
|
.interface-plan h2,
|
|
2403
2403
|
.workflow-step strong,
|
|
2404
2404
|
.agent-phase strong,
|
package/dist/dashboard/server.js
CHANGED
|
@@ -5,7 +5,8 @@ import { createRequire } from 'module';
|
|
|
5
5
|
import { dirname, isAbsolute, relative, resolve } from 'path';
|
|
6
6
|
import { tailFile, readAllJsonLines } from './tail.js';
|
|
7
7
|
import { renderDashboardHtml } from './index-html.js';
|
|
8
|
-
import { readOverview, readProjectInfo, listChanges, readChange, readCliHistory, readAgentInterfacePlan,
|
|
8
|
+
import { readOverview, readProjectInfo, listChanges, readChange, readCliHistory, readAgentInterfacePlan, readSelfEvolution, readArchitecture, } from './data.js';
|
|
9
|
+
import { listEpisodes, readEpisode, readRejectBufferAll, } from '../core/self-evolution/index.js';
|
|
9
10
|
const requireFromHere = createRequire(import.meta.url);
|
|
10
11
|
const vendorPackageRoots = new Map();
|
|
11
12
|
const vendorAssets = new Map([
|
|
@@ -219,12 +220,11 @@ async function handle(req, res, tracePath, projectRoot, clients) {
|
|
|
219
220
|
}
|
|
220
221
|
}
|
|
221
222
|
if (req.method === 'GET' && url.pathname === '/') {
|
|
222
|
-
const [project, changes, cliHistory,
|
|
223
|
+
const [project, changes, cliHistory, se, history, agentInterface, architecture] = await Promise.all([
|
|
223
224
|
readProjectInfo(projectRoot).catch(() => ({})),
|
|
224
225
|
listChanges(projectRoot).catch(() => []),
|
|
225
226
|
readCliHistory(projectRoot, 500).catch(() => []),
|
|
226
|
-
|
|
227
|
-
readEvolveArchive(projectRoot).catch(() => ({ entries: [], generations: [] })),
|
|
227
|
+
readSelfEvolution(projectRoot).catch(() => ({ episodes: [], policyLineages: [], rejectBuffer: [] })),
|
|
228
228
|
readAllJsonLines(tracePath).catch(() => []),
|
|
229
229
|
readAgentInterfacePlan(projectRoot).catch(() => null),
|
|
230
230
|
readArchitecture(projectRoot).catch(() => null),
|
|
@@ -233,8 +233,9 @@ async function handle(req, res, tracePath, projectRoot, clients) {
|
|
|
233
233
|
project,
|
|
234
234
|
changes,
|
|
235
235
|
cliHistory,
|
|
236
|
-
|
|
237
|
-
|
|
236
|
+
episodes: se.episodes,
|
|
237
|
+
policyLineages: se.policyLineages,
|
|
238
|
+
rejectBuffer: se.rejectBuffer,
|
|
238
239
|
history,
|
|
239
240
|
agentInterface,
|
|
240
241
|
architecture,
|
|
@@ -306,24 +307,29 @@ async function handle(req, res, tracePath, projectRoot, clients) {
|
|
|
306
307
|
sendJson(res, await readArchitecture(projectRoot));
|
|
307
308
|
return;
|
|
308
309
|
}
|
|
309
|
-
if (req.method === 'GET' && url.pathname === '/api/
|
|
310
|
-
sendJson(res, await
|
|
310
|
+
if (req.method === 'GET' && url.pathname === '/api/episodes') {
|
|
311
|
+
sendJson(res, await listEpisodes(projectRoot));
|
|
311
312
|
return;
|
|
312
313
|
}
|
|
313
|
-
if (req.method === 'GET' && url.pathname.startsWith('/api/
|
|
314
|
-
const id = decodeURIComponent(url.pathname.slice('/api/
|
|
315
|
-
|
|
316
|
-
|
|
314
|
+
if (req.method === 'GET' && url.pathname.startsWith('/api/episodes/')) {
|
|
315
|
+
const id = decodeURIComponent(url.pathname.slice('/api/episodes/'.length));
|
|
316
|
+
try {
|
|
317
|
+
const episode = await readEpisode(projectRoot, id);
|
|
318
|
+
sendJson(res, episode);
|
|
319
|
+
}
|
|
320
|
+
catch {
|
|
317
321
|
res.statusCode = 404;
|
|
318
322
|
res.setHeader('content-type', 'application/json; charset=utf-8');
|
|
319
|
-
res.end(JSON.stringify({ error: '
|
|
320
|
-
return;
|
|
323
|
+
res.end(JSON.stringify({ error: 'episode not found', id }));
|
|
321
324
|
}
|
|
322
|
-
sendJson(res, run);
|
|
323
325
|
return;
|
|
324
326
|
}
|
|
325
|
-
if (req.method === 'GET' && url.pathname === '/api/
|
|
326
|
-
sendJson(res, (await
|
|
327
|
+
if (req.method === 'GET' && url.pathname === '/api/policy/ledger') {
|
|
328
|
+
sendJson(res, (await readSelfEvolution(projectRoot)).policyLineages);
|
|
329
|
+
return;
|
|
330
|
+
}
|
|
331
|
+
if (req.method === 'GET' && url.pathname === '/api/reject-buffer') {
|
|
332
|
+
sendJson(res, await readRejectBufferAll(projectRoot));
|
|
327
333
|
return;
|
|
328
334
|
}
|
|
329
335
|
if (req.method === 'GET' && url.pathname === '/api/history') {
|
|
@@ -1,21 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ASCII art animation for the
|
|
3
|
-
*
|
|
4
|
-
* A self-evolving DNA double-helix: two strands twist continuously while a
|
|
5
|
-
* generation counter and a fitness bar climb — a nod to the genetic-algorithm /
|
|
6
|
-
* fitness machinery that actually drives self-evolution. Deliberately distinct
|
|
7
|
-
* from the upstream diamond logo so the product reads as its own thing.
|
|
8
|
-
*
|
|
9
|
-
* INVARIANT: every frame has the SAME number of rows. `showWelcomeScreen`
|
|
10
|
-
* (welcome-screen.ts) moves the cursor up by a fixed height derived from
|
|
11
|
-
* `frames[0].length` between redraws, so unequal-height frames corrupt the
|
|
12
|
-
* animation. Enforced by test/ui/welcome-animation.test.ts.
|
|
2
|
+
* ASCII art animation patterns for the welcome screen.
|
|
3
|
+
* SynergySpec-SelfEvolving logo animation - diamond/rhombus shape with hollow center "O".
|
|
13
4
|
*/
|
|
14
5
|
/**
|
|
15
|
-
* Welcome animation frames
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
6
|
+
* Welcome animation frames - SynergySpec-SelfEvolving logo building from center
|
|
7
|
+
* 7 rows × 6 columns diamond with hollow center "O"
|
|
8
|
+
* Center bar is 2 cols × 3 rows (rows 3,4,5 cols 3,4)
|
|
9
|
+
* Each frame is an array of strings (lines of ASCII art)
|
|
10
|
+
* Grid: 6 cols × 2 chars = 12 chars wide
|
|
19
11
|
*/
|
|
20
12
|
export declare const WELCOME_ANIMATION: {
|
|
21
13
|
interval: number;
|
|
@@ -1,64 +1,133 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ASCII art animation for the
|
|
3
|
-
*
|
|
4
|
-
* A self-evolving DNA double-helix: two strands twist continuously while a
|
|
5
|
-
* generation counter and a fitness bar climb — a nod to the genetic-algorithm /
|
|
6
|
-
* fitness machinery that actually drives self-evolution. Deliberately distinct
|
|
7
|
-
* from the upstream diamond logo so the product reads as its own thing.
|
|
8
|
-
*
|
|
9
|
-
* INVARIANT: every frame has the SAME number of rows. `showWelcomeScreen`
|
|
10
|
-
* (welcome-screen.ts) moves the cursor up by a fixed height derived from
|
|
11
|
-
* `frames[0].length` between redraws, so unequal-height frames corrupt the
|
|
12
|
-
* animation. Enforced by test/ui/welcome-animation.test.ts.
|
|
2
|
+
* ASCII art animation patterns for the welcome screen.
|
|
3
|
+
* SynergySpec-SelfEvolving logo animation - diamond/rhombus shape with hollow center "O".
|
|
13
4
|
*/
|
|
14
|
-
// Detect if full Unicode is supported
|
|
5
|
+
// Detect if full Unicode is supported
|
|
15
6
|
const supportsUnicode = process.platform !== 'win32' ||
|
|
16
7
|
!!process.env.WT_SESSION || // Windows Terminal
|
|
17
8
|
!!process.env.TERM_PROGRAM; // Modern terminal
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
const
|
|
21
|
-
? {
|
|
22
|
-
: {
|
|
23
|
-
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
// these downward one phase per frame reads as a continuous twist.
|
|
27
|
-
const PHASES = [
|
|
28
|
-
` ${G.cross} `, // crossover
|
|
29
|
-
` ${G.up} ${G.down} `, // diverging (just below a crossover)
|
|
30
|
-
` ${G.node} ${G.node} `, // strands at max separation
|
|
31
|
-
` ${G.down} ${G.up} `, // converging (just above a crossover)
|
|
32
|
-
];
|
|
33
|
-
const HELIX_ROWS = 9;
|
|
34
|
-
const FRAME_COUNT = 8;
|
|
35
|
-
// Nine rows of helix, phase-shifted by `offset` so the braid scrolls/twists.
|
|
36
|
-
function helixFrame(offset) {
|
|
37
|
-
const rows = [];
|
|
38
|
-
for (let i = 0; i < HELIX_ROWS; i++) {
|
|
39
|
-
rows.push(PHASES[(offset + i) % PHASES.length]);
|
|
40
|
-
}
|
|
41
|
-
return rows;
|
|
42
|
-
}
|
|
43
|
-
function generationRow(generation) {
|
|
44
|
-
return ` gen ${String(generation).padStart(2, '0')}`;
|
|
45
|
-
}
|
|
46
|
-
// Fill `step` (1..FRAME_COUNT) ascending cells of the fitness bar.
|
|
47
|
-
function fitnessRow(step) {
|
|
48
|
-
return ` fit ${FITNESS_RAMP.slice(0, step)}`;
|
|
49
|
-
}
|
|
9
|
+
// Character set based on Unicode support
|
|
10
|
+
// Block characters for pixel-art aesthetic
|
|
11
|
+
const CHARS = supportsUnicode
|
|
12
|
+
? { full: '██', dim: '░░', empty: ' ' }
|
|
13
|
+
: { full: '##', dim: '++', empty: ' ' };
|
|
14
|
+
const _ = CHARS.empty;
|
|
15
|
+
const F = CHARS.full;
|
|
16
|
+
const D = CHARS.dim;
|
|
50
17
|
/**
|
|
51
|
-
* Welcome animation frames
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
18
|
+
* Welcome animation frames - SynergySpec-SelfEvolving logo building from center
|
|
19
|
+
* 7 rows × 6 columns diamond with hollow center "O"
|
|
20
|
+
* Center bar is 2 cols × 3 rows (rows 3,4,5 cols 3,4)
|
|
21
|
+
* Each frame is an array of strings (lines of ASCII art)
|
|
22
|
+
* Grid: 6 cols × 2 chars = 12 chars wide
|
|
55
23
|
*/
|
|
56
24
|
export const WELCOME_ANIMATION = {
|
|
57
|
-
interval:
|
|
58
|
-
frames:
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
25
|
+
interval: 120,
|
|
26
|
+
frames: [
|
|
27
|
+
// Frame 1: Empty
|
|
28
|
+
[
|
|
29
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`, // padding row 1
|
|
30
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`, // padding row 2
|
|
31
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`, // padding row 3
|
|
32
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`,
|
|
33
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`,
|
|
34
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`,
|
|
35
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`,
|
|
36
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`,
|
|
37
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`,
|
|
38
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`,
|
|
39
|
+
],
|
|
40
|
+
// Frame 2: Center blocks appear (dim) - 2x3 center bar
|
|
41
|
+
[
|
|
42
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`, // padding row 1
|
|
43
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`, // padding row 2
|
|
44
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`, // padding row 3
|
|
45
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`,
|
|
46
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`,
|
|
47
|
+
`${_}${_}${_}${_}${D}${D}${_}${_}`,
|
|
48
|
+
`${_}${_}${_}${_}${D}${D}${_}${_}`,
|
|
49
|
+
`${_}${_}${_}${_}${D}${D}${_}${_}`,
|
|
50
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`,
|
|
51
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`,
|
|
52
|
+
],
|
|
53
|
+
// Frame 3: Center blocks solidify
|
|
54
|
+
[
|
|
55
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`, // padding row 1
|
|
56
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`, // padding row 2
|
|
57
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`, // padding row 3
|
|
58
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`,
|
|
59
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`,
|
|
60
|
+
`${_}${_}${_}${_}${F}${F}${_}${_}`,
|
|
61
|
+
`${_}${_}${_}${_}${F}${F}${_}${_}`,
|
|
62
|
+
`${_}${_}${_}${_}${F}${F}${_}${_}`,
|
|
63
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`,
|
|
64
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`,
|
|
65
|
+
],
|
|
66
|
+
// Frame 4: Top and bottom points appear
|
|
67
|
+
[
|
|
68
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`, // padding row 1
|
|
69
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`, // padding row 2
|
|
70
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`, // padding row 3
|
|
71
|
+
`${_}${_}${_}${_}${D}${D}${_}${_}`,
|
|
72
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`,
|
|
73
|
+
`${_}${_}${_}${_}${F}${F}${_}${_}`,
|
|
74
|
+
`${_}${_}${_}${_}${F}${F}${_}${_}`,
|
|
75
|
+
`${_}${_}${_}${_}${F}${F}${_}${_}`,
|
|
76
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`,
|
|
77
|
+
`${_}${_}${_}${_}${D}${D}${_}${_}`,
|
|
78
|
+
],
|
|
79
|
+
// Frame 5: Inner ring forming
|
|
80
|
+
[
|
|
81
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`, // padding row 1
|
|
82
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`, // padding row 2
|
|
83
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`, // padding row 3
|
|
84
|
+
`${_}${_}${_}${_}${F}${F}${_}${_}`,
|
|
85
|
+
`${_}${_}${_}${D}${_}${_}${D}${_}`,
|
|
86
|
+
`${_}${_}${_}${_}${F}${F}${_}${_}`,
|
|
87
|
+
`${_}${_}${_}${_}${F}${F}${_}${_}`,
|
|
88
|
+
`${_}${_}${_}${_}${F}${F}${_}${_}`,
|
|
89
|
+
`${_}${_}${_}${D}${_}${_}${D}${_}`,
|
|
90
|
+
`${_}${_}${_}${_}${F}${F}${_}${_}`,
|
|
91
|
+
],
|
|
92
|
+
// Frame 6: Outer ring appearing
|
|
93
|
+
[
|
|
94
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`, // padding row 1
|
|
95
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`, // padding row 2
|
|
96
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`, // padding row 3
|
|
97
|
+
`${_}${_}${_}${_}${F}${F}${_}${_}`,
|
|
98
|
+
`${_}${_}${_}${F}${_}${_}${F}${_}`,
|
|
99
|
+
`${_}${_}${D}${_}${F}${F}${_}${D}`,
|
|
100
|
+
`${_}${_}${D}${_}${F}${F}${_}${D}`,
|
|
101
|
+
`${_}${_}${D}${_}${F}${F}${_}${D}`,
|
|
102
|
+
`${_}${_}${_}${F}${_}${_}${F}${_}`,
|
|
103
|
+
`${_}${_}${_}${_}${F}${F}${_}${_}`,
|
|
104
|
+
],
|
|
105
|
+
// Frame 7: Full logo
|
|
106
|
+
[
|
|
107
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`, // padding row 1
|
|
108
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`, // padding row 2
|
|
109
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`, // padding row 3
|
|
110
|
+
`${_}${_}${_}${_}${F}${F}${_}${_}`,
|
|
111
|
+
`${_}${_}${_}${F}${_}${_}${F}${_}`,
|
|
112
|
+
`${_}${_}${F}${_}${F}${F}${_}${F}`,
|
|
113
|
+
`${_}${_}${F}${_}${F}${F}${_}${F}`,
|
|
114
|
+
`${_}${_}${F}${_}${F}${F}${_}${F}`,
|
|
115
|
+
`${_}${_}${_}${F}${_}${_}${F}${_}`,
|
|
116
|
+
`${_}${_}${_}${_}${F}${F}${_}${_}`,
|
|
117
|
+
],
|
|
118
|
+
// Frame 8: Hold complete logo
|
|
119
|
+
[
|
|
120
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`, // padding row 1
|
|
121
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`, // padding row 2
|
|
122
|
+
`${_}${_}${_}${_}${_}${_}${_}${_}`, // padding row 3
|
|
123
|
+
`${_}${_}${_}${_}${F}${F}${_}${_}`,
|
|
124
|
+
`${_}${_}${_}${F}${_}${_}${F}${_}`,
|
|
125
|
+
`${_}${_}${F}${_}${F}${F}${_}${F}`,
|
|
126
|
+
`${_}${_}${F}${_}${F}${F}${_}${F}`,
|
|
127
|
+
`${_}${_}${F}${_}${F}${F}${_}${F}`,
|
|
128
|
+
`${_}${_}${_}${F}${_}${_}${F}${_}`,
|
|
129
|
+
`${_}${_}${_}${_}${F}${F}${_}${_}`,
|
|
130
|
+
],
|
|
131
|
+
],
|
|
63
132
|
};
|
|
64
133
|
//# sourceMappingURL=ascii-patterns.js.map
|
|
@@ -2,20 +2,6 @@
|
|
|
2
2
|
* Animated welcome screen for the experimental artifact workflow setup.
|
|
3
3
|
* Shows side-by-side layout with animated ASCII art on left and welcome text on right.
|
|
4
4
|
*/
|
|
5
|
-
/**
|
|
6
|
-
* Welcome text content (right column).
|
|
7
|
-
* Leads with the self-evolving loop — the thing that sets this apart.
|
|
8
|
-
* Keep each line ≤ 35 visible chars so it never wraps at the 60-col MIN_WIDTH
|
|
9
|
-
* after the 24-col art gutter (locked by test/ui/welcome-animation.test.ts).
|
|
10
|
-
*/
|
|
11
|
-
export declare function getWelcomeText(): string[];
|
|
12
|
-
/**
|
|
13
|
-
* Renders a single frame with side-by-side layout.
|
|
14
|
-
* `artColor` lets the caller pulse the helix color per frame; the raw art is
|
|
15
|
-
* padded to the column width BEFORE coloring so ANSI codes never count toward
|
|
16
|
-
* the width and the text column stays aligned.
|
|
17
|
-
*/
|
|
18
|
-
export declare function renderFrame(artLines: string[], textLines: string[], artColor?: (s: string) => string): string;
|
|
19
5
|
/**
|
|
20
6
|
* Shows the animated welcome screen.
|
|
21
7
|
* Returns when user presses Enter.
|
|
@@ -9,61 +9,43 @@ const MIN_WIDTH = 60;
|
|
|
9
9
|
// Width of the ASCII art column (with padding)
|
|
10
10
|
const ART_COLUMN_WIDTH = 24;
|
|
11
11
|
/**
|
|
12
|
-
* Welcome text content (right column)
|
|
13
|
-
* Leads with the self-evolving loop — the thing that sets this apart.
|
|
14
|
-
* Keep each line ≤ 35 visible chars so it never wraps at the 60-col MIN_WIDTH
|
|
15
|
-
* after the 24-col art gutter (locked by test/ui/welcome-animation.test.ts).
|
|
12
|
+
* Welcome text content (right column)
|
|
16
13
|
*/
|
|
17
|
-
|
|
14
|
+
function getWelcomeText() {
|
|
18
15
|
return [
|
|
19
16
|
chalk.white.bold('Welcome to SynergySpec-SelfEvolving'),
|
|
20
|
-
chalk.dim('
|
|
17
|
+
chalk.dim('A lightweight spec-driven framework'),
|
|
21
18
|
'',
|
|
22
19
|
chalk.white('This setup will configure:'),
|
|
23
20
|
chalk.dim(' • Agent Skills for AI tools'),
|
|
24
21
|
chalk.dim(' • /synspec:* slash commands'),
|
|
25
|
-
chalk.green(' • A self-evolution loop'),
|
|
26
|
-
chalk.dim(' that improves its own prompts'),
|
|
27
22
|
'',
|
|
28
23
|
chalk.white('Quick start after setup:'),
|
|
29
|
-
` ${chalk.yellow('/synspec:
|
|
30
|
-
` ${chalk.yellow('/synspec:
|
|
31
|
-
` ${chalk.yellow('/synspec:
|
|
24
|
+
` ${chalk.yellow('/synspec:new')} ${chalk.dim('Create a change')}`,
|
|
25
|
+
` ${chalk.yellow('/synspec:continue')} ${chalk.dim('Next artifact')}`,
|
|
26
|
+
` ${chalk.yellow('/synspec:apply')} ${chalk.dim('Implement tasks')}`,
|
|
32
27
|
'',
|
|
33
28
|
chalk.cyan('Press Enter to select tools...'),
|
|
34
29
|
];
|
|
35
30
|
}
|
|
36
31
|
/**
|
|
37
|
-
* Renders a single frame with side-by-side layout
|
|
38
|
-
* `artColor` lets the caller pulse the helix color per frame; the raw art is
|
|
39
|
-
* padded to the column width BEFORE coloring so ANSI codes never count toward
|
|
40
|
-
* the width and the text column stays aligned.
|
|
32
|
+
* Renders a single frame with side-by-side layout
|
|
41
33
|
*/
|
|
42
|
-
|
|
34
|
+
function renderFrame(artLines, textLines) {
|
|
43
35
|
const maxLines = Math.max(artLines.length, textLines.length);
|
|
44
36
|
const lines = [];
|
|
45
37
|
for (let i = 0; i < maxLines; i++) {
|
|
46
38
|
const artLine = artLines[i] || '';
|
|
47
39
|
const textLine = textLines[i] || '';
|
|
48
|
-
// Pad the art column to fixed width
|
|
40
|
+
// Pad the art column to fixed width
|
|
49
41
|
const paddedArt = artLine.padEnd(ART_COLUMN_WIDTH);
|
|
50
|
-
// Color the
|
|
51
|
-
const coloredArt =
|
|
42
|
+
// Color the ASCII art with cyan for visual appeal
|
|
43
|
+
const coloredArt = chalk.cyan(paddedArt);
|
|
52
44
|
// Clear line before writing to prevent residual characters
|
|
53
45
|
lines.push(`\x1b[2K${coloredArt}${textLine}`);
|
|
54
46
|
}
|
|
55
47
|
return lines.join('\n');
|
|
56
48
|
}
|
|
57
|
-
/**
|
|
58
|
-
* Per-frame color cycle that makes the helix look alive/evolving
|
|
59
|
-
* (cyan → bright cyan → green → bright green → …).
|
|
60
|
-
*/
|
|
61
|
-
const PULSE_COLORS = [
|
|
62
|
-
chalk.cyan,
|
|
63
|
-
chalk.cyanBright,
|
|
64
|
-
chalk.green,
|
|
65
|
-
chalk.greenBright,
|
|
66
|
-
];
|
|
67
49
|
/**
|
|
68
50
|
* Checks if the terminal supports animation
|
|
69
51
|
*/
|
|
@@ -119,9 +101,9 @@ function waitForEnter() {
|
|
|
119
101
|
export async function showWelcomeScreen() {
|
|
120
102
|
const textLines = getWelcomeText();
|
|
121
103
|
if (!canAnimate()) {
|
|
122
|
-
// Fallback: show
|
|
123
|
-
const frame = WELCOME_ANIMATION.frames[
|
|
124
|
-
process.stdout.write('\n' + renderFrame(frame, textLines
|
|
104
|
+
// Fallback: show static welcome
|
|
105
|
+
const frame = WELCOME_ANIMATION.frames[3]; // Peak frame
|
|
106
|
+
process.stdout.write('\n' + renderFrame(frame, textLines) + '\n\n');
|
|
125
107
|
return;
|
|
126
108
|
}
|
|
127
109
|
let frameIndex = 0;
|
|
@@ -144,9 +126,8 @@ export async function showWelcomeScreen() {
|
|
|
144
126
|
process.stdout.write(`\x1b[${frameHeight}A`);
|
|
145
127
|
}
|
|
146
128
|
isFirstRender = false;
|
|
147
|
-
// Render current frame
|
|
148
|
-
|
|
149
|
-
process.stdout.write(renderFrame(frame, textLines, color) + '\n\n');
|
|
129
|
+
// Render current frame
|
|
130
|
+
process.stdout.write(renderFrame(frame, textLines) + '\n\n');
|
|
150
131
|
// Advance to next frame
|
|
151
132
|
frameIndex = (frameIndex + 1) % WELCOME_ANIMATION.frames.length;
|
|
152
133
|
}, WELCOME_ANIMATION.interval);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "synergyspec-selfevolving",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "AI-native system for spec-driven development",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"synergyspec-selfevolving",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"scripts/postinstall.js",
|
|
39
39
|
"scripts/nl2repo_synergyspec-selfevolving_wrapper.py",
|
|
40
40
|
"scripts/code-health.py",
|
|
41
|
+
"scripts/slop_rules.yaml",
|
|
41
42
|
"!dist/**/*.test.js",
|
|
42
43
|
"!dist/**/__tests__",
|
|
43
44
|
"!dist/**/*.map"
|
|
@@ -79,6 +80,7 @@
|
|
|
79
80
|
"vitest": "^3.2.4"
|
|
80
81
|
},
|
|
81
82
|
"dependencies": {
|
|
83
|
+
"@ast-grep/cli": "0.43.0",
|
|
82
84
|
"@inquirer/core": "^10.2.2",
|
|
83
85
|
"@inquirer/prompts": "^7.8.0",
|
|
84
86
|
"ansi-regex": "^5.0.1",
|