ac-framework 1.3.0 → 1.4.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.
@@ -1,44 +1,3 @@
1
- # 🤖 AGENTS.md - AI Work Framework
2
-
3
- ```
4
- ╔══════════════════════════════════════════════════════════════════════════════════════════╗
5
- ║ ║
6
- ║ █████╗ ██████╗ ███████╗███╗ ██╗████████╗███████╗ ║
7
- ║ ██╔══██╗██╔════╝ ██╔════╝████╗ ██║╚══██╔══╝██╔════╝ ║
8
- ║ ███████║██║ ███╗█████╗ ██╔██╗ ██║ ██║ ███████╗ ║
9
- ║ ██╔══██║██║ ██║██╔══╝ ██║╚██╗██║ ██║ ╚════██║ ║
10
- ║ ██║ ██║╚██████╔╝███████╗██║ ╚████║ ██║ ███████║ ║
11
- ║ ╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚══════╝ ║
12
- ║ ║
13
- ║ Intelligent Software Development Framework ║
14
- ║ ║
15
- ╚══════════════════════════════════════════════════════════════════════════════════════════╝
16
- ```
17
-
18
- ---
19
-
20
- ## 📋 Index
21
-
22
- 1. [Framework Philosophy](#-framework-philosophy)
23
- 2. [Available Skills](#-available-skills)
24
- 3. [Workflow: New Project](#-workflow-new-project)
25
- 4. [Workflow: Existing Project](#-workflow-existing-project)
26
- 5. [Workflow: Changes/Iterations](#-workflow-changesiterations)
27
- 6. [Validation Checklist](#-validation-checklist)
28
- 7. [Directory Structure](#-directory-structure)
29
-
30
- ---
31
-
32
- ## 🎯 Framework Philosophy
33
-
34
- This framework is designed to ensure all AI-developed projects follow:
35
-
36
- - ✅ **Best coding practices** from the start
37
- - ✅ **Maintainable** and scalable architecture
38
- - ✅ **Complete and up-to-date** documentation
39
- - ✅ **Clear specifications** through OpenSpec
40
- - ✅ **Systematic debugging** of problems
41
- - ✅ **Automated change history**
42
1
 
43
2
  > **Fundamental Principle**: *"Quality over speed. Documentation before code. Planning before execution."*
44
3
 
@@ -338,127 +297,4 @@ Before considering any task as **completed**, verify:
338
297
  ║ └─ □ Change archived with openspec-archive-change ║
339
298
  ║ └─ □ Delta specs synchronized (if applicable) ║
340
299
  ║ ║
341
- ╚═══════════════════════════════════════════════════════════════════════════════════╝
342
- ```
343
-
344
- ---
345
-
346
- ## 📁 Directory Structure
347
-
348
- ```
349
- project/
350
-
351
- ├── 📂 .agents/ # AI-generated documentation
352
- │ ├── security-guidelines.md # Security practices
353
- │ ├── maintainability-rules.md # Maintainability rules
354
- │ ├── architecture-decisions.md # Architecture decisions
355
- │ ├── project-index.md # Complete project index
356
- │ ├── exploration-report.md # Exploration reports
357
- │ ├── brainstorming-session.md # Brainstorming sessions
358
- │ ├── debug-report.md # Debugging reports
359
- │ └── agent-<domain>.md # Per-domain guides (e.g., agent-ui.md)
360
-
361
- ├── 📂 .claude/ # Project-specific skills
362
- │ └── skills/
363
- │ └── project-index-<domain>/
364
- │ └── SKILL.md # Domain-specific skills
365
-
366
- ├── 📂 .openspec/ # Formal specifications (OpenSpec)
367
- │ ├── specs/ # Main specifications
368
- │ │ └── <capability>/
369
- │ │ └── spec.md
370
- │ └── changes/ # Active changes
371
- │ ├── <change-name>/
372
- │ │ ├── proposal.md # Why and what changes
373
- │ │ ├── design.md # How to build it
374
- │ │ ├── tasks.md # Implementation checklist
375
- │ │ └── specs/ # Delta specs
376
- │ │ └── <capability>/
377
- │ │ └── spec.md
378
- │ └── archive/ # Completed changes
379
- │ └── YYYY-MM-DD-<name>/
380
-
381
- ├── 📂 changelogs/ # Change history
382
- │ └── by-ai/ # AI-generated changelogs
383
- │ └── YYYY-MM-DD-feature.md
384
-
385
- └── [project source code]
386
- ```
387
-
388
- ---
389
-
390
- ## 🎓 Quick Usage
391
-
392
- ### To start a new project:
393
- ```
394
- 1. Execute: secure-coding-cybersecurity
395
- 2. Execute: code-maintainability
396
- 3. Execute: brainstorming
397
- 4. Execute: openspec-new-change (or openspec-ff-change for quick mode)
398
- 5. Execute: openspec-continue-change (create specs, design, tasks)
399
- 6. Execute: openspec-apply-change
400
- 7. Execute: systematic-debugging
401
- 8. Execute: openspec-verify-change
402
- 9. Execute: changelog-generator
403
- 10. Execute: openspec-archive-change
404
- ```
405
-
406
- ### To modify an existing project:
407
- ```
408
- 1. Check if documentation exists (.agents/, openspec/)
409
- └─ If NOT exists → Execute: project-index
410
-
411
- 2. Execute: openspec-explore
412
- 3. Execute: brainstorming
413
- 4. Execute: openspec-new-change (create change)
414
- 5. Execute: openspec-continue-change (complete artifacts)
415
- 6. Execute: openspec-apply-change (implement)
416
- 7. Execute: systematic-debugging (validate)
417
- 8. Execute: openspec-verify-change (verify against specs)
418
- 9. Execute: changelog-generator
419
- 10. Execute: openspec-archive-change
420
- ```
421
-
422
- ### Quick OpenSpec commands:
423
- ```
424
- /opsx:explore - Explore before implementing
425
- /opsx:new <name> - Create new change step by step
426
- /opsx:ff <name> - Fast-forward (create all quickly)
427
- /opsx:continue - Continue existing change
428
- /opsx:apply - Implement tasks
429
- /opsx:verify - Verify implementation
430
- /opsx:archive - Archive completed change
431
- /opsx:onboard - OpenSpec tutorial
432
- ```
433
-
434
- ---
435
-
436
- ## 📌 Important Notes
437
-
438
- > **⚠️ NEVER skip workflow steps.** Each skill exists to ensure quality.
439
-
440
- > **📝 Documentation = Code.** If not documented in OpenSpec, it's not done.
441
-
442
- > **🔒 Security first.** Always execute secure-coding-cybersecurity before any implementation.
443
-
444
- > **🧠 Brainstorming is mandatory.** Never implement without questioning the approach first.
445
-
446
- > **✅ Validation before commit.** Always execute systematic-debugging and openspec-verify before finishing.
447
-
448
- > **📦 One change = One feature.** Don't mix multiple features in a single change.
449
-
450
- > **🔄 Sync specs.** After archiving, synchronize delta specs to main specs.
451
-
452
- ---
453
-
454
- ```
455
- ╔═══════════════════════════════════════════════════════════════════════════════════╗
456
- ║ ║
457
- ║ "Well-specified code is well-implemented code" ║
458
- ║ ║
459
- ║ Framework AGENTS.md v2.0 ║
460
- ║ ║
461
- ║ 22 Skills Available | OpenSpec Workflow Integrated ║
462
- ║ ║
463
- ╚═══════════════════════════════════════════════════════════════════════════════════╝
464
- ```
300
+ ╚═══════════════════════════════════════════════════════════════════════════════════╝
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ac-framework",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "Agentic Coding Framework - Multi-assistant configuration system with OpenSpec workflows",
5
5
  "main": "src/index.js",
6
6
  "exports": {
package/src/ui/banner.js CHANGED
@@ -2,68 +2,171 @@ import gradient from 'gradient-string';
2
2
  import chalk from 'chalk';
3
3
  import { sleep } from '../utils/helpers.js';
4
4
 
5
- const acGradient = gradient(['#6C5CE7', '#A29BFE', '#00CEC9', '#0984E3', '#6C5CE7']);
6
- const dimGradient = gradient(['#2D3436', '#636E72', '#2D3436']);
7
- const glowGradient = gradient(['#0984E3', '#00CEC9', '#55EFC4', '#00CEC9', '#0984E3']);
8
-
9
- const LOGO = [
10
- ' ██████╗ ██████╗ ███████╗██████╗ █████╗ ███╗ ███╗███████╗',
11
- ' ██╔══██╗██╔════╝ ██╔════╝██╔══██╗██╔══██╗████╗ ████║██╔════╝',
12
- ' ███████║██║ █████╗ ██████╔╝███████║██╔████╔██║█████╗ ',
13
- ' ██╔══██║██║ ██╔══╝ ██╔══██╗██╔══██║██║╚██╔╝██║██╔══╝ ',
14
- ' ██║ ██║╚██████╗ ██║ ██║ ██║██║ ██║██║ ╚═╝ ██║███████╗',
15
- ' ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝',
5
+ // ── Emerald Color Palette ─────────────────────────────────────────
6
+ const emeraldGradient = gradient(['#1B5E20', '#2ECC71', '#50C878', '#00FF7F', '#50C878', '#2ECC71', '#1B5E20']);
7
+ const dimEmerald = gradient(['#0D2B0D', '#1B3A1B', '#2D4A2D', '#1B3A1B', '#0D2B0D']);
8
+ const brightEmerald = gradient(['#00FF7F', '#55FFB2', '#AAFFDD', '#55FFB2', '#00FF7F']);
9
+ const glowGradient = gradient(['#1B5E20', '#2ECC71', '#50C878', '#2ECC71', '#1B5E20']);
10
+
11
+ // ── Emerald Gem ASCII Art ─────────────────────────────────────────
12
+ // Faceted gem with "AC" in crown and code/symbols in body
13
+ const EMERALD_GEM = [
14
+ ' ╱╲',
15
+ ' ',
16
+ ' ╱ ╲',
17
+ ' ╱ AC ╲',
18
+ ' ╱════════╲',
19
+ ' ╱ {=>} ◈ ╲',
20
+ ' ╱ async AI ╲',
21
+ ' ╱ ◇ /**/ ⊹ ╲',
22
+ ' ╱ import {} ◈ ╲',
23
+ ' ╱══════════════════╲',
24
+ ' ╲ ⊹ () => {} ╱',
25
+ ' ╲ ◈ const ╱',
26
+ ' ╲ ✦ AI ╱',
27
+ ' ╲ ◇ {} ╱',
28
+ ' ╲ ╱',
29
+ ' ╲ ╱',
30
+ ' ╲╱',
16
31
  ];
17
32
 
33
+ // Sparkle row indices where sparkles can appear (around the gem perimeter)
34
+ const SPARKLE_ROWS = [0, 1, 2, 4, 9, 14, 15, 16];
35
+
36
+ const SPARKLE_CHARS = ['✦', '✧', '⊹', '✶', '⋆'];
37
+
18
38
  export async function showBanner() {
19
39
  console.clear();
20
40
  console.log();
21
41
 
22
- // Phase 1: Glitch-in effect — show random noise then resolve to the logo
23
- const maxWidth = Math.max(...LOGO.map((l) => l.length));
24
- const glitchChars = '█▓▒░╗╔╝╚═║╬╣╠╩╦';
25
- const glitchSteps = 6;
42
+ const gemHeight = EMERALD_GEM.length;
43
+ const particleChars = '░▒▓█◈◇⊹';
26
44
 
27
- for (let step = 0; step < glitchSteps; step++) {
28
- const ratio = step / (glitchSteps - 1); // 0 → 1
45
+ // ── Phase 1: Particle Build-up ──────────────────────────────────
46
+ // Green particles progressively form the emerald silhouette
47
+ const buildSteps = 6;
48
+
49
+ for (let step = 0; step < buildSteps; step++) {
50
+ const ratio = step / (buildSteps - 1); // 0 → 1
29
51
  const output = [];
30
- for (const line of LOGO) {
52
+
53
+ for (const line of EMERALD_GEM) {
31
54
  let result = '';
32
55
  for (let i = 0; i < line.length; i++) {
33
56
  if (line[i] === ' ') {
34
- result += ' ';
57
+ // In early frames, occasionally show a stray particle near non-space chars
58
+ if (ratio < 0.6 && Math.random() < 0.03 && i > 0 && line[i - 1] !== ' ') {
59
+ result += particleChars[Math.floor(Math.random() * 3)]; // ░▒▓ only
60
+ } else {
61
+ result += ' ';
62
+ }
35
63
  } else if (Math.random() < ratio) {
36
- result += line[i];
64
+ result += line[i]; // Reveal actual character
37
65
  } else {
38
- result += glitchChars[Math.floor(Math.random() * glitchChars.length)];
66
+ result += particleChars[Math.floor(Math.random() * particleChars.length)];
39
67
  }
40
68
  }
41
69
  output.push(result);
42
70
  }
43
71
 
44
72
  if (step > 0) {
45
- process.stdout.write(`\x1B[${LOGO.length}A`);
73
+ process.stdout.write(`\x1B[${gemHeight}A`);
46
74
  }
47
75
  for (const line of output) {
48
- const colored = step < glitchSteps - 1
49
- ? dimGradient(line)
50
- : acGradient(line);
76
+ const colored = step < buildSteps - 1
77
+ ? dimEmerald(line)
78
+ : emeraldGradient(line);
51
79
  console.log(colored);
52
80
  }
53
- await sleep(step < glitchSteps - 1 ? 80 : 0);
81
+ await sleep(step < buildSteps - 1 ? 100 : 0);
82
+ }
83
+
84
+ // ── Phase 2: Full Reveal with AC highlight ──────────────────────
85
+ // Brief pause then re-render with "AC" in bright white/green
86
+ await sleep(150);
87
+ process.stdout.write(`\x1B[${gemHeight}A`);
88
+
89
+ for (let i = 0; i < EMERALD_GEM.length; i++) {
90
+ const line = EMERALD_GEM[i];
91
+ // Highlight "AC" in the crown (line index 3)
92
+ if (i === 3) {
93
+ const acIdx = line.indexOf('AC');
94
+ const before = line.slice(0, acIdx);
95
+ const ac = line.slice(acIdx, acIdx + 2);
96
+ const after = line.slice(acIdx + 2);
97
+ process.stdout.write(
98
+ `\x1B[2K${emeraldGradient(before)}${chalk.hex('#FFFFFF').bold(ac)}${emeraldGradient(after)}\n`
99
+ );
100
+ } else {
101
+ process.stdout.write(`\x1B[2K${emeraldGradient(line)}\n`);
102
+ }
103
+ }
104
+ await sleep(200);
105
+
106
+ // ── Phase 3: Pulsing Glow Loop ──────────────────────────────────
107
+ // Alternate bright/dim with sparkles around perimeter
108
+ const pulseCycles = 3;
109
+
110
+ for (let cycle = 0; cycle < pulseCycles; cycle++) {
111
+ // Bright phase with sparkles
112
+ process.stdout.write(`\x1B[${gemHeight}A`);
113
+
114
+ for (let i = 0; i < EMERALD_GEM.length; i++) {
115
+ const line = EMERALD_GEM[i];
116
+ let rendered;
117
+
118
+ if (i === 3) {
119
+ const acIdx = line.indexOf('AC');
120
+ const before = line.slice(0, acIdx);
121
+ const ac = line.slice(acIdx, acIdx + 2);
122
+ const after = line.slice(acIdx + 2);
123
+ rendered = brightEmerald(before) + chalk.hex('#FFFFFF').bold(ac) + brightEmerald(after);
124
+ } else {
125
+ rendered = brightEmerald(line);
126
+ }
127
+
128
+ // Add sparkle after the line on perimeter rows
129
+ let sparkle = '';
130
+ if (SPARKLE_ROWS.includes(i) && Math.random() < 0.6) {
131
+ const sp = SPARKLE_CHARS[Math.floor(Math.random() * SPARKLE_CHARS.length)];
132
+ const pad = Math.floor(Math.random() * 3) + 1;
133
+ sparkle = ' '.repeat(pad) + chalk.hex('#AAFFDD')(sp);
134
+ }
135
+
136
+ process.stdout.write(`\x1B[2K${rendered}${sparkle}\n`);
137
+ }
138
+ await sleep(250);
139
+
140
+ // Dim phase
141
+ process.stdout.write(`\x1B[${gemHeight}A`);
142
+ for (let i = 0; i < EMERALD_GEM.length; i++) {
143
+ const line = EMERALD_GEM[i];
144
+ let rendered;
145
+ if (i === 3) {
146
+ const acIdx = line.indexOf('AC');
147
+ const before = line.slice(0, acIdx);
148
+ const ac = line.slice(acIdx, acIdx + 2);
149
+ const after = line.slice(acIdx + 2);
150
+ rendered = emeraldGradient(before) + chalk.hex('#A8E6CF').bold(ac) + emeraldGradient(after);
151
+ } else {
152
+ rendered = emeraldGradient(line);
153
+ }
154
+ process.stdout.write(`\x1B[2K${rendered}\n`);
155
+ }
156
+ await sleep(250);
54
157
  }
55
158
 
56
159
  console.log();
57
160
 
58
- // Phase 2: Animated separator with scanning effect
161
+ // ── Phase 4: Animated separator (preserved) ─────────────────────
59
162
  const sepWidth = 68;
60
163
  const sepChars = '─';
61
164
  for (let i = 0; i <= sepWidth; i++) {
62
165
  const line =
63
- chalk.hex('#2D3436')(' ') +
166
+ chalk.hex('#1B5E20')(' ') +
64
167
  glowGradient(sepChars.repeat(i)) +
65
- chalk.hex('#00CEC9')('●') +
66
- chalk.hex('#2D3436')(sepChars.repeat(Math.max(0, sepWidth - i)));
168
+ chalk.hex('#2ECC71')('●') +
169
+ chalk.hex('#1B5E20')(sepChars.repeat(Math.max(0, sepWidth - i)));
67
170
  process.stdout.write(`\x1B[2K\r${line}`);
68
171
  await sleep(6);
69
172
  }
@@ -71,28 +174,28 @@ export async function showBanner() {
71
174
 
72
175
  console.log();
73
176
 
74
- // Phase 3: Typewriter tagline with cursor blink
177
+ // ── Phase 5: Typewriter tagline (preserved) ─────────────────────
75
178
  const tagline = ' Agentic Coding Framework — Multi-assistant configuration system';
76
179
  const cursor = '▌';
77
180
  for (let i = 0; i <= tagline.length; i++) {
78
181
  const text = tagline.slice(0, i);
79
- process.stdout.write(`\x1B[2K\r${chalk.hex('#DFE6E9')(text)}${chalk.hex('#00CEC9')(cursor)}`);
182
+ process.stdout.write(`\x1B[2K\r${chalk.hex('#DFE6E9')(text)}${chalk.hex('#2ECC71')(cursor)}`);
80
183
  await sleep(i % 4 === 0 ? 18 : 10);
81
184
  }
82
185
  // Blink cursor 3 times then remove
83
186
  for (let b = 0; b < 3; b++) {
84
- process.stdout.write(`\x1B[2K\r${chalk.hex('#DFE6E9')(tagline)}${chalk.hex('#00CEC9')(cursor)}`);
187
+ process.stdout.write(`\x1B[2K\r${chalk.hex('#DFE6E9')(tagline)}${chalk.hex('#2ECC71')(cursor)}`);
85
188
  await sleep(120);
86
189
  process.stdout.write(`\x1B[2K\r${chalk.hex('#DFE6E9')(tagline)} `);
87
190
  await sleep(120);
88
191
  }
89
192
  process.stdout.write(`\x1B[2K\r${chalk.hex('#DFE6E9')(tagline)} \n`);
90
193
 
91
- // Phase 4: Info badges
194
+ // ── Phase 6: Info badges (preserved) ────────────────────────────
92
195
  console.log();
93
- const version = chalk.hex('#2D3436').bgHex('#00CEC9').bold(' v1.x ');
94
- const badge = chalk.hex('#2D3436').bgHex('#6C5CE7').bold(' CLI ');
95
- const badge2 = chalk.hex('#2D3436').bgHex('#FDCB6E').bold(' 23 Assistants ');
196
+ const version = chalk.hex('#1B5E20').bgHex('#00FF7F').bold(' v1.x ');
197
+ const badge = chalk.hex('#FFFFFF').bgHex('#2ECC71').bold(' CLI ');
198
+ const badge2 = chalk.hex('#1B5E20').bgHex('#A8E6CF').bold(' 23 Assistants ');
96
199
  console.log(` ${version} ${badge} ${badge2}`);
97
200
 
98
201
  console.log();