vralphy 0.8.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.
Files changed (158) hide show
  1. package/README.md +512 -0
  2. package/bin/vralphy.js +3 -0
  3. package/dist/commands/build.d.ts +9 -0
  4. package/dist/commands/build.d.ts.map +1 -0
  5. package/dist/commands/build.js +176 -0
  6. package/dist/commands/build.js.map +1 -0
  7. package/dist/commands/cleanup.d.ts +19 -0
  8. package/dist/commands/cleanup.d.ts.map +1 -0
  9. package/dist/commands/cleanup.js +159 -0
  10. package/dist/commands/cleanup.js.map +1 -0
  11. package/dist/commands/cleanup.test.d.ts +2 -0
  12. package/dist/commands/cleanup.test.d.ts.map +1 -0
  13. package/dist/commands/cleanup.test.js +389 -0
  14. package/dist/commands/cleanup.test.js.map +1 -0
  15. package/dist/commands/init.d.ts +13 -0
  16. package/dist/commands/init.d.ts.map +1 -0
  17. package/dist/commands/init.js +120 -0
  18. package/dist/commands/init.js.map +1 -0
  19. package/dist/commands/plan.d.ts +9 -0
  20. package/dist/commands/plan.d.ts.map +1 -0
  21. package/dist/commands/plan.js +147 -0
  22. package/dist/commands/plan.js.map +1 -0
  23. package/dist/commands/spec.d.ts +9 -0
  24. package/dist/commands/spec.d.ts.map +1 -0
  25. package/dist/commands/spec.js +111 -0
  26. package/dist/commands/spec.js.map +1 -0
  27. package/dist/index.d.ts +3 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +251 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/lib/agents.d.ts +32 -0
  32. package/dist/lib/agents.d.ts.map +1 -0
  33. package/dist/lib/agents.js +96 -0
  34. package/dist/lib/agents.js.map +1 -0
  35. package/dist/lib/config.d.ts +54 -0
  36. package/dist/lib/config.d.ts.map +1 -0
  37. package/dist/lib/config.js +199 -0
  38. package/dist/lib/config.js.map +1 -0
  39. package/dist/lib/config.test.d.ts +2 -0
  40. package/dist/lib/config.test.d.ts.map +1 -0
  41. package/dist/lib/config.test.js +57 -0
  42. package/dist/lib/config.test.js.map +1 -0
  43. package/dist/lib/context.d.ts +29 -0
  44. package/dist/lib/context.d.ts.map +1 -0
  45. package/dist/lib/context.js +175 -0
  46. package/dist/lib/context.js.map +1 -0
  47. package/dist/lib/engines/base.d.ts +75 -0
  48. package/dist/lib/engines/base.d.ts.map +1 -0
  49. package/dist/lib/engines/base.js +62 -0
  50. package/dist/lib/engines/base.js.map +1 -0
  51. package/dist/lib/engines/base.test.d.ts +2 -0
  52. package/dist/lib/engines/base.test.d.ts.map +1 -0
  53. package/dist/lib/engines/base.test.js +28 -0
  54. package/dist/lib/engines/base.test.js.map +1 -0
  55. package/dist/lib/engines/claude.d.ts +12 -0
  56. package/dist/lib/engines/claude.d.ts.map +1 -0
  57. package/dist/lib/engines/claude.js +156 -0
  58. package/dist/lib/engines/claude.js.map +1 -0
  59. package/dist/lib/engines/codex.d.ts +28 -0
  60. package/dist/lib/engines/codex.d.ts.map +1 -0
  61. package/dist/lib/engines/codex.js +177 -0
  62. package/dist/lib/engines/codex.js.map +1 -0
  63. package/dist/lib/engines/index.d.ts +19 -0
  64. package/dist/lib/engines/index.d.ts.map +1 -0
  65. package/dist/lib/engines/index.js +40 -0
  66. package/dist/lib/engines/index.js.map +1 -0
  67. package/dist/lib/engines/opencode.d.ts +14 -0
  68. package/dist/lib/engines/opencode.d.ts.map +1 -0
  69. package/dist/lib/engines/opencode.js +127 -0
  70. package/dist/lib/engines/opencode.js.map +1 -0
  71. package/dist/lib/events/index.d.ts +6 -0
  72. package/dist/lib/events/index.d.ts.map +1 -0
  73. package/dist/lib/events/index.js +5 -0
  74. package/dist/lib/events/index.js.map +1 -0
  75. package/dist/lib/events/types.d.ts +93 -0
  76. package/dist/lib/events/types.d.ts.map +1 -0
  77. package/dist/lib/events/types.js +7 -0
  78. package/dist/lib/events/types.js.map +1 -0
  79. package/dist/lib/events/writer.d.ts +68 -0
  80. package/dist/lib/events/writer.d.ts.map +1 -0
  81. package/dist/lib/events/writer.js +178 -0
  82. package/dist/lib/events/writer.js.map +1 -0
  83. package/dist/lib/events.d.ts +33 -0
  84. package/dist/lib/events.d.ts.map +1 -0
  85. package/dist/lib/events.js +81 -0
  86. package/dist/lib/events.js.map +1 -0
  87. package/dist/lib/events.test.d.ts +2 -0
  88. package/dist/lib/events.test.d.ts.map +1 -0
  89. package/dist/lib/events.test.js +123 -0
  90. package/dist/lib/events.test.js.map +1 -0
  91. package/dist/lib/file-injection.d.ts +32 -0
  92. package/dist/lib/file-injection.d.ts.map +1 -0
  93. package/dist/lib/file-injection.js +138 -0
  94. package/dist/lib/file-injection.js.map +1 -0
  95. package/dist/lib/file-injection.test.d.ts +2 -0
  96. package/dist/lib/file-injection.test.d.ts.map +1 -0
  97. package/dist/lib/file-injection.test.js +508 -0
  98. package/dist/lib/file-injection.test.js.map +1 -0
  99. package/dist/lib/init.d.ts +27 -0
  100. package/dist/lib/init.d.ts.map +1 -0
  101. package/dist/lib/init.js +363 -0
  102. package/dist/lib/init.js.map +1 -0
  103. package/dist/lib/init.test.d.ts +2 -0
  104. package/dist/lib/init.test.d.ts.map +1 -0
  105. package/dist/lib/init.test.js +315 -0
  106. package/dist/lib/init.test.js.map +1 -0
  107. package/dist/lib/plan.d.ts +11 -0
  108. package/dist/lib/plan.d.ts.map +1 -0
  109. package/dist/lib/plan.js +22 -0
  110. package/dist/lib/plan.js.map +1 -0
  111. package/dist/lib/plan.test.d.ts +2 -0
  112. package/dist/lib/plan.test.d.ts.map +1 -0
  113. package/dist/lib/plan.test.js +70 -0
  114. package/dist/lib/plan.test.js.map +1 -0
  115. package/dist/lib/prompts/codex.d.ts +18 -0
  116. package/dist/lib/prompts/codex.d.ts.map +1 -0
  117. package/dist/lib/prompts/codex.js +82 -0
  118. package/dist/lib/prompts/codex.js.map +1 -0
  119. package/dist/lib/prompts/opencode.d.ts +16 -0
  120. package/dist/lib/prompts/opencode.d.ts.map +1 -0
  121. package/dist/lib/prompts/opencode.js +71 -0
  122. package/dist/lib/prompts/opencode.js.map +1 -0
  123. package/dist/lib/prompts.d.ts +57 -0
  124. package/dist/lib/prompts.d.ts.map +1 -0
  125. package/dist/lib/prompts.js +255 -0
  126. package/dist/lib/prompts.js.map +1 -0
  127. package/dist/lib/prompts.test.d.ts +2 -0
  128. package/dist/lib/prompts.test.d.ts.map +1 -0
  129. package/dist/lib/prompts.test.js +128 -0
  130. package/dist/lib/prompts.test.js.map +1 -0
  131. package/dist/lib/skills.d.ts +36 -0
  132. package/dist/lib/skills.d.ts.map +1 -0
  133. package/dist/lib/skills.js +132 -0
  134. package/dist/lib/skills.js.map +1 -0
  135. package/dist/lib/slack.d.ts +43 -0
  136. package/dist/lib/slack.d.ts.map +1 -0
  137. package/dist/lib/slack.js +130 -0
  138. package/dist/lib/slack.js.map +1 -0
  139. package/dist/lib/slack.test.d.ts +2 -0
  140. package/dist/lib/slack.test.d.ts.map +1 -0
  141. package/dist/lib/slack.test.js +74 -0
  142. package/dist/lib/slack.test.js.map +1 -0
  143. package/dist/lib/templates/injections.d.ts +18 -0
  144. package/dist/lib/templates/injections.d.ts.map +1 -0
  145. package/dist/lib/templates/injections.js +32 -0
  146. package/dist/lib/templates/injections.js.map +1 -0
  147. package/dist/lib/templates/readme.d.ts +6 -0
  148. package/dist/lib/templates/readme.d.ts.map +1 -0
  149. package/dist/lib/templates/readme.js +168 -0
  150. package/dist/lib/templates/readme.js.map +1 -0
  151. package/docs/COMMANDS.md +664 -0
  152. package/docs/DESIGN.md +537 -0
  153. package/docs/EXAMPLES.md +812 -0
  154. package/docs/METHODOLOGY.md +390 -0
  155. package/docs/README.md +110 -0
  156. package/docs/WORKFLOWS.md +808 -0
  157. package/llms.txt +104 -0
  158. package/package.json +58 -0
@@ -0,0 +1,132 @@
1
+ import { readFile, readdir } from 'fs/promises';
2
+ import { existsSync } from 'fs';
3
+ import { join, basename } from 'path';
4
+ /**
5
+ * Parse frontmatter from markdown file
6
+ */
7
+ function parseFrontmatter(content) {
8
+ const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
9
+ if (!frontmatterMatch) {
10
+ return { metadata: {}, content };
11
+ }
12
+ const [, frontmatter, body] = frontmatterMatch;
13
+ const metadata = {};
14
+ for (const line of frontmatter.split('\n')) {
15
+ const match = line.match(/^(\w+):\s*(.*)$/);
16
+ if (match) {
17
+ const [, key, value] = match;
18
+ if (value.startsWith('[') || value.startsWith('"')) {
19
+ try {
20
+ metadata[key] = JSON.parse(value);
21
+ }
22
+ catch (e) {
23
+ if (process.env.VRALPHY_VERBOSE === 'true') {
24
+ console.warn(`Warning: Failed to parse JSON value for '${key}': ${value}`);
25
+ }
26
+ metadata[key] = value;
27
+ }
28
+ }
29
+ else if (value.startsWith('-')) {
30
+ metadata[key] = [value.slice(1).trim()];
31
+ }
32
+ else {
33
+ metadata[key] = value;
34
+ }
35
+ }
36
+ else if (line.startsWith(' -') && Object.keys(metadata).length > 0) {
37
+ const lastKey = Object.keys(metadata).pop();
38
+ const arr = metadata[lastKey];
39
+ if (Array.isArray(arr)) {
40
+ arr.push(line.slice(4).trim());
41
+ }
42
+ }
43
+ }
44
+ return { metadata, content: body };
45
+ }
46
+ /**
47
+ * Load a single skill from file
48
+ */
49
+ async function loadSkill(path) {
50
+ const content = await readFile(path, 'utf-8');
51
+ const { metadata, content: body } = parseFrontmatter(content);
52
+ const name = metadata.name ?? basename(path, '.md');
53
+ return {
54
+ name,
55
+ path,
56
+ metadata: {
57
+ name,
58
+ description: metadata.description,
59
+ triggers: metadata.triggers,
60
+ alwaysInclude: metadata.alwaysInclude,
61
+ },
62
+ content: body,
63
+ };
64
+ }
65
+ /**
66
+ * Load all skills from a directory
67
+ */
68
+ export async function loadSkills(dir) {
69
+ if (!existsSync(dir)) {
70
+ return [];
71
+ }
72
+ const files = await readdir(dir);
73
+ const mdFiles = files.filter((f) => f.endsWith('.md'));
74
+ const skills = [];
75
+ for (const file of mdFiles) {
76
+ try {
77
+ const skill = await loadSkill(join(dir, file));
78
+ skills.push(skill);
79
+ }
80
+ catch (e) {
81
+ console.error(`Failed to load skill ${file}:`, e);
82
+ }
83
+ }
84
+ return skills;
85
+ }
86
+ /**
87
+ * Filter skills by triggers matching text
88
+ */
89
+ export function filterSkillsByTriggers(skills, text) {
90
+ const lowerText = text.toLowerCase();
91
+ return skills.filter((skill) => {
92
+ if (skill.metadata.alwaysInclude)
93
+ return true;
94
+ if (!skill.metadata.triggers)
95
+ return false;
96
+ return skill.metadata.triggers.some((trigger) => lowerText.includes(trigger.toLowerCase()));
97
+ });
98
+ }
99
+ /**
100
+ * Format skills for prompt injection
101
+ */
102
+ export function formatSkillsForPrompt(skills) {
103
+ if (skills.length === 0)
104
+ return '';
105
+ let result = '## Loaded Skills\n\n';
106
+ for (const skill of skills) {
107
+ const name = skill.name ?? 'Unnamed Skill';
108
+ const description = skill.metadata?.description ?? '';
109
+ const content = skill.content ?? '';
110
+ result += `### ${name}\n`;
111
+ if (description) {
112
+ result += `${description}\n\n`;
113
+ }
114
+ result += `${content}\n\n`;
115
+ }
116
+ return result;
117
+ }
118
+ /**
119
+ * List available skills (for CLI command)
120
+ */
121
+ export async function listSkills(dir) {
122
+ const skills = await loadSkills(dir);
123
+ return skills.map((s) => ({ name: s.name, description: s.metadata.description }));
124
+ }
125
+ /**
126
+ * Get skill by name
127
+ */
128
+ export async function getSkill(dir, name) {
129
+ const skills = await loadSkills(dir);
130
+ return skills.find((s) => s.name === name);
131
+ }
132
+ //# sourceMappingURL=skills.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/lib/skills.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAgBtC;;GAEG;AACH,SAAS,gBAAgB,CAAC,OAAe;IACvC,MAAM,gBAAgB,GAAG,OAAO,CAAC,KAAK,CAAC,mCAAmC,CAAC,CAAC;IAE5E,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC;IACnC,CAAC;IAED,MAAM,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,GAAG,gBAAgB,CAAC;IAC/C,MAAM,QAAQ,GAA4B,EAAE,CAAC;IAE7C,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAC5C,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,CAAC,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC;YAC7B,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBACnD,IAAI,CAAC;oBACH,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBACpC,CAAC;gBAAC,OAAO,CAAC,EAAE,CAAC;oBACX,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,KAAK,MAAM,EAAE,CAAC;wBAC3C,OAAO,CAAC,IAAI,CAAC,4CAA4C,GAAG,MAAM,KAAK,EAAE,CAAC,CAAC;oBAC7E,CAAC;oBACD,QAAQ,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;gBACxB,CAAC;YACH,CAAC;iBAAM,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBACjC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YAC1C,CAAC;iBAAM,CAAC;gBACN,QAAQ,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YACxB,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtE,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAG,CAAC;YAC7C,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;YAC9B,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBACvB,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;YACjC,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AACrC,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,SAAS,CAAC,IAAY;IACnC,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC9C,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAE9D,MAAM,IAAI,GAAI,QAAQ,CAAC,IAAe,IAAI,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAEhE,OAAO;QACL,IAAI;QACJ,IAAI;QACJ,QAAQ,EAAE;YACR,IAAI;YACJ,WAAW,EAAE,QAAQ,CAAC,WAAiC;YACvD,QAAQ,EAAE,QAAQ,CAAC,QAAgC;YACnD,aAAa,EAAE,QAAQ,CAAC,aAAoC;SAC7D;QACD,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAW;IAC1C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACrB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;IACjC,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;IAEvD,MAAM,MAAM,GAAY,EAAE,CAAC;IAE3B,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;YAC/C,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,KAAK,CAAC,wBAAwB,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAe,EAAE,IAAY;IAClE,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAErC,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE;QAC7B,IAAI,KAAK,CAAC,QAAQ,CAAC,aAAa;YAAE,OAAO,IAAI,CAAC;QAC9C,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ;YAAE,OAAO,KAAK,CAAC;QAE3C,OAAO,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAC9C,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAC1C,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,MAAe;IACnD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEnC,IAAI,MAAM,GAAG,sBAAsB,CAAC;IAEpC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,IAAI,eAAe,CAAC;QAC3C,MAAM,WAAW,GAAG,KAAK,CAAC,QAAQ,EAAE,WAAW,IAAI,EAAE,CAAC;QACtD,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC;QAEpC,MAAM,IAAI,OAAO,IAAI,IAAI,CAAC;QAC1B,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,IAAI,GAAG,WAAW,MAAM,CAAC;QACjC,CAAC;QACD,MAAM,IAAI,GAAG,OAAO,MAAM,CAAC;IAC7B,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAW;IAC1C,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC;IACrC,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;AACpF,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,GAAW,EAAE,IAAY;IACtD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,CAAC;IACrC,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AAC7C,CAAC"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Slack webhook notifications for vralphy
3
+ * Fire-and-forget - never blocks or fails execution
4
+ */
5
+ export interface SlackMessage {
6
+ text: string;
7
+ blocks?: SlackBlock[];
8
+ }
9
+ interface SlackBlock {
10
+ type: string;
11
+ text?: {
12
+ type: string;
13
+ text: string;
14
+ emoji?: boolean;
15
+ };
16
+ }
17
+ /**
18
+ * Send a message to Slack via webhook
19
+ * Fire-and-forget: never blocks or throws
20
+ */
21
+ export declare function sendSlack(webhookUrl: string, message: SlackMessage): void;
22
+ /**
23
+ * Create session start message
24
+ */
25
+ export declare function sessionStartMessage(project: string, command: string, maxIterations: number, engine: string, model: string): SlackMessage;
26
+ /**
27
+ * Create iteration end message
28
+ */
29
+ export declare function iterationEndMessage(project: string, iteration: number, maxIterations: number, durationMs: number): SlackMessage;
30
+ /**
31
+ * Create session end message
32
+ */
33
+ export declare function sessionEndMessage(project: string, iterations: number, totalDurationMs: number, success: boolean): SlackMessage;
34
+ /**
35
+ * Create error message for iteration failure
36
+ */
37
+ export declare function iterationErrorMessage(project: string, iteration: number, maxIterations: number, error?: string): SlackMessage;
38
+ /**
39
+ * Create plan completion message
40
+ */
41
+ export declare function planCompletedMessage(project: string, totalTasks: number, iteration: number, durationMs: number): SlackMessage;
42
+ export {};
43
+ //# sourceMappingURL=slack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack.d.ts","sourceRoot":"","sources":["../../src/lib/slack.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC;CACvB;AAED,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB,CAAC;CACH;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,GAAG,IAAI,CAQzE;AAeD;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,GACZ,YAAY,CAcd;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,MAAM,GACjB,YAAY,CAMd;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,MAAM,EACvB,OAAO,EAAE,OAAO,GACf,YAAY,CA4Bd;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,EACrB,KAAK,CAAC,EAAE,MAAM,GACb,YAAY,CAed;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GACjB,YAAY,CAiBd"}
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Slack webhook notifications for vralphy
3
+ * Fire-and-forget - never blocks or fails execution
4
+ */
5
+ /**
6
+ * Send a message to Slack via webhook
7
+ * Fire-and-forget: never blocks or throws
8
+ */
9
+ export function sendSlack(webhookUrl, message) {
10
+ fetch(webhookUrl, {
11
+ method: 'POST',
12
+ headers: { 'Content-Type': 'application/json' },
13
+ body: JSON.stringify(message),
14
+ }).catch(() => {
15
+ // Silently ignore errors - notifications should never block execution
16
+ });
17
+ }
18
+ /**
19
+ * Format duration in milliseconds to human-readable string
20
+ */
21
+ function formatDuration(ms) {
22
+ const seconds = Math.floor(ms / 1000);
23
+ if (seconds < 60) {
24
+ return `${seconds}s`;
25
+ }
26
+ const minutes = Math.floor(seconds / 60);
27
+ const remainingSeconds = seconds % 60;
28
+ return `${minutes}m ${remainingSeconds}s`;
29
+ }
30
+ /**
31
+ * Create session start message
32
+ */
33
+ export function sessionStartMessage(project, command, maxIterations, engine, model) {
34
+ const iterationText = maxIterations > 0 ? `${maxIterations} iterations` : 'unlimited iterations';
35
+ return {
36
+ text: `:rocket: vralphy ${command} started on \`${project}\` (${iterationText})`,
37
+ blocks: [
38
+ {
39
+ type: 'section',
40
+ text: {
41
+ type: 'mrkdwn',
42
+ text: `:rocket: *vralphy ${command} started*\nProject: \`${project}\`\nEngine: ${engine} (${model})\nIterations: ${iterationText}`,
43
+ },
44
+ },
45
+ ],
46
+ };
47
+ }
48
+ /**
49
+ * Create iteration end message
50
+ */
51
+ export function iterationEndMessage(project, iteration, maxIterations, durationMs) {
52
+ const iterationText = maxIterations > 0 ? `${iteration}/${maxIterations}` : `${iteration}`;
53
+ const duration = formatDuration(durationMs);
54
+ return {
55
+ text: `:hourglass: Iteration ${iterationText} completed on \`${project}\` (${duration})`,
56
+ };
57
+ }
58
+ /**
59
+ * Create session end message
60
+ */
61
+ export function sessionEndMessage(project, iterations, totalDurationMs, success) {
62
+ const duration = formatDuration(totalDurationMs);
63
+ if (success) {
64
+ return {
65
+ text: `:white_check_mark: vralphy completed on \`${project}\` - ${iterations} iteration(s), ${duration}`,
66
+ blocks: [
67
+ {
68
+ type: 'section',
69
+ text: {
70
+ type: 'mrkdwn',
71
+ text: `:white_check_mark: *vralphy completed*\nProject: \`${project}\`\nIterations: ${iterations}\nDuration: ${duration}`,
72
+ },
73
+ },
74
+ ],
75
+ };
76
+ }
77
+ return {
78
+ text: `:x: vralphy failed on \`${project}\` after ${iterations} iteration(s)`,
79
+ blocks: [
80
+ {
81
+ type: 'section',
82
+ text: {
83
+ type: 'mrkdwn',
84
+ text: `:x: *vralphy failed*\nProject: \`${project}\`\nIterations completed: ${iterations}`,
85
+ },
86
+ },
87
+ ],
88
+ };
89
+ }
90
+ /**
91
+ * Create error message for iteration failure
92
+ */
93
+ export function iterationErrorMessage(project, iteration, maxIterations, error) {
94
+ const iterationText = maxIterations > 0 ? `${iteration}/${maxIterations}` : `${iteration}`;
95
+ const errorText = error ? `\nError: ${error}` : '';
96
+ return {
97
+ text: `:x: vralphy failed on iteration ${iterationText} on \`${project}\`${errorText}`,
98
+ blocks: [
99
+ {
100
+ type: 'section',
101
+ text: {
102
+ type: 'mrkdwn',
103
+ text: `:x: *vralphy failed on iteration ${iterationText}*\nProject: \`${project}\`${errorText}`,
104
+ },
105
+ },
106
+ ],
107
+ };
108
+ }
109
+ /**
110
+ * Create plan completion message
111
+ */
112
+ export function planCompletedMessage(project, totalTasks, iteration, durationMs) {
113
+ const duration = formatDuration(durationMs);
114
+ return {
115
+ text: `[${project}] Plan completed! ${totalTasks} tasks done in ${iteration} iteration(s) (${duration})`,
116
+ blocks: [
117
+ {
118
+ type: 'section',
119
+ text: {
120
+ type: 'mrkdwn',
121
+ text: `:tada: *[${project}] Plan Completed*\n` +
122
+ `All ${totalTasks} tasks are now checked off.\n` +
123
+ `Iterations: ${iteration} | Duration: ${duration}\n` +
124
+ `_Session continues - agent may find new work._`,
125
+ },
126
+ },
127
+ ],
128
+ };
129
+ }
130
+ //# sourceMappingURL=slack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack.js","sourceRoot":"","sources":["../../src/lib/slack.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=slack.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack.test.d.ts","sourceRoot":"","sources":["../../src/lib/slack.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,74 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { sessionStartMessage, iterationEndMessage, sessionEndMessage, iterationErrorMessage, planCompletedMessage, } from './slack.js';
3
+ describe('Slack message formatters', () => {
4
+ describe('sessionStartMessage', () => {
5
+ it('returns message with text and blocks', () => {
6
+ const msg = sessionStartMessage('my-project', 'build', 5, 'claude', 'opus');
7
+ expect(msg.text).toContain('my-project');
8
+ expect(msg.text).toContain('build');
9
+ expect(msg.blocks).toBeDefined();
10
+ expect(msg.blocks.length).toBeGreaterThan(0);
11
+ });
12
+ it('handles unlimited iterations', () => {
13
+ const msg = sessionStartMessage('proj', 'build', 0, 'claude', 'opus');
14
+ expect(msg.text).toContain('unlimited');
15
+ });
16
+ });
17
+ describe('iterationEndMessage', () => {
18
+ it('returns message with iteration count', () => {
19
+ const msg = iterationEndMessage('my-project', 3, 10, 60000);
20
+ expect(msg.text).toContain('3/10');
21
+ expect(msg.text).toContain('my-project');
22
+ });
23
+ it('handles unlimited iterations', () => {
24
+ const msg = iterationEndMessage('proj', 5, 0, 30000);
25
+ expect(msg.text).toContain('5');
26
+ expect(msg.text).not.toContain('5/');
27
+ });
28
+ });
29
+ describe('sessionEndMessage', () => {
30
+ it('returns success message with blocks', () => {
31
+ const msg = sessionEndMessage('my-project', 3, 120000, true);
32
+ expect(msg.text).toContain('completed');
33
+ expect(msg.text).toContain('my-project');
34
+ expect(msg.blocks).toBeDefined();
35
+ });
36
+ it('returns failure message with blocks', () => {
37
+ const msg = sessionEndMessage('my-project', 2, 60000, false);
38
+ expect(msg.text).toContain('failed');
39
+ expect(msg.blocks).toBeDefined();
40
+ });
41
+ });
42
+ describe('iterationErrorMessage', () => {
43
+ it('returns error message with blocks', () => {
44
+ const msg = iterationErrorMessage('my-project', 2, 5, 'Something went wrong');
45
+ expect(msg.text).toContain('failed');
46
+ expect(msg.text).toContain('2/5');
47
+ expect(msg.text).toContain('Something went wrong');
48
+ expect(msg.blocks).toBeDefined();
49
+ });
50
+ it('handles missing error message', () => {
51
+ const msg = iterationErrorMessage('my-project', 1, 3);
52
+ expect(msg.text).toContain('failed');
53
+ expect(msg.blocks).toBeDefined();
54
+ });
55
+ });
56
+ describe('planCompletedMessage', () => {
57
+ it('returns completion message with text and blocks', () => {
58
+ const msg = planCompletedMessage('my-project', 10, 3, 180000);
59
+ expect(msg.text).toContain('my-project');
60
+ expect(msg.text).toContain('10');
61
+ expect(msg.text).toContain('3');
62
+ expect(msg.blocks).toBeDefined();
63
+ expect(msg.blocks.length).toBeGreaterThan(0);
64
+ });
65
+ it('includes celebration and context in blocks', () => {
66
+ const msg = planCompletedMessage('proj', 5, 2, 60000);
67
+ const blockText = msg.blocks[0].text?.text || '';
68
+ expect(blockText).toContain(':tada:');
69
+ expect(blockText).toContain('Plan Completed');
70
+ expect(blockText).toContain('continues');
71
+ });
72
+ });
73
+ });
74
+ //# sourceMappingURL=slack.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"slack.test.js","sourceRoot":"","sources":["../../src/lib/slack.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Injection markers and content for CLAUDE.md and AGENTS.md files
3
+ */
4
+ export declare const INJECTION_MARKERS: {
5
+ readonly start: "<!-- vralphy:start -->";
6
+ readonly end: "<!-- vralphy:end -->";
7
+ };
8
+ /**
9
+ * Content to inject into CLAUDE.md files
10
+ * References the comprehensive README in .vralphy/
11
+ */
12
+ export declare const CLAUDE_MD_INJECTION = "\n## vralphy Integration\n\nThis project uses vralphy for autonomous AI development. Key references:\n\n- **Full documentation**: @.vralphy/README.md\n- **Project context**: @.vralphy/AGENTS.md\n- **Current plan**: @IMPLEMENTATION_PLAN.md\n\nWhen working on vralphy tasks, check IMPLEMENTATION_PLAN.md for current progress.\n";
13
+ /**
14
+ * Content to inject into root AGENTS.md files
15
+ * Minimal section pointing to vralphy documentation
16
+ */
17
+ export declare const AGENTS_MD_INJECTION = "\n## vralphy\n\nThis project uses vralphy. See `.vralphy/README.md` for full documentation.\n";
18
+ //# sourceMappingURL=injections.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injections.d.ts","sourceRoot":"","sources":["../../../src/lib/templates/injections.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,iBAAiB;;;CAGpB,CAAC;AAEX;;;GAGG;AACH,eAAO,MAAM,mBAAmB,0UAU/B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,kGAI/B,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Injection markers and content for CLAUDE.md and AGENTS.md files
3
+ */
4
+ export const INJECTION_MARKERS = {
5
+ start: '<!-- vralphy:start -->',
6
+ end: '<!-- vralphy:end -->',
7
+ };
8
+ /**
9
+ * Content to inject into CLAUDE.md files
10
+ * References the comprehensive README in .vralphy/
11
+ */
12
+ export const CLAUDE_MD_INJECTION = `
13
+ ## vralphy Integration
14
+
15
+ This project uses vralphy for autonomous AI development. Key references:
16
+
17
+ - **Full documentation**: @.vralphy/README.md
18
+ - **Project context**: @.vralphy/AGENTS.md
19
+ - **Current plan**: @IMPLEMENTATION_PLAN.md
20
+
21
+ When working on vralphy tasks, check IMPLEMENTATION_PLAN.md for current progress.
22
+ `;
23
+ /**
24
+ * Content to inject into root AGENTS.md files
25
+ * Minimal section pointing to vralphy documentation
26
+ */
27
+ export const AGENTS_MD_INJECTION = `
28
+ ## vralphy
29
+
30
+ This project uses vralphy. See \`.vralphy/README.md\` for full documentation.
31
+ `;
32
+ //# sourceMappingURL=injections.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injections.js","sourceRoot":"","sources":["../../../src/lib/templates/injections.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,KAAK,EAAE,wBAAwB;IAC/B,GAAG,EAAE,sBAAsB;CACnB,CAAC;AAEX;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;;;;;;;CAUlC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;CAIlC,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * README template for .vralphy/README.md
3
+ * Comprehensive documentation for external AI coding agents
4
+ */
5
+ export declare const README_TEMPLATE = "# vralphy - AI Agent Documentation\n\nThis project uses **vralphy**, a CLI tool implementing the Ralph Playbook methodology for autonomous AI development.\n\n## What is vralphy?\n\nvralphy wraps AI coding CLIs (Claude, OpenCode, Codex) with a loop-based execution model. It enables AI agents to autonomously plan, build, test, and commit code through structured iteration.\n\n## The Workflow Loop\n\n```\nUser specs \u2192 Plan phase \u2192 Build phase \u2192 Tests \u2192 Commit \u2192 Loop\n \u2191 \u2502\n \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n```\n\n1. **Specs** (`specs/*.md`): Define what to build\n2. **Plan** (`vralphy plan`): AI analyzes specs and creates IMPLEMENTATION_PLAN.md\n3. **Build** (`vralphy build`): AI executes tasks from the plan\n4. **Tests**: Validation runs after each iteration\n5. **Commit**: Changes are committed on successful validation\n6. **Loop**: Process repeats until plan is complete\n\n## Writing Specifications\n\nCreate `.md` files in `specs/` directory. Format:\n\n```markdown\n# Feature Name\n\n## Goal\nWhat this feature should accomplish.\n\n## Requirements\n- Requirement 1\n- Requirement 2\n\n## Constraints\n- Any technical limitations or preferences\n\n## Acceptance Criteria\n- [ ] Criterion 1\n- [ ] Criterion 2\n```\n\n### Good Spec Examples\n\n- Clear, atomic features\n- Measurable acceptance criteria\n- Specific constraints (not \"make it fast\")\n- References to existing code when relevant\n\n### Avoid\n\n- Vague requirements (\"improve the code\")\n- Multiple unrelated features in one spec\n- Implementation details (let AI decide how)\n\n## Key Commands\n\n| Command | Description |\n|---------|-------------|\n| `vralphy plan` | Analyze specs and create/update IMPLEMENTATION_PLAN.md |\n| `vralphy build` | Execute tasks from the implementation plan |\n| `vralphy spec <topic>` | Interactive specification creation |\n| `vralphy init` | Initialize vralphy in a project |\n| `vralphy cleanup` | Remove vralphy artifacts |\n| `vralphy engines` | List available AI engines |\n\n### Common Options\n\n```bash\n--engine <name> # claude | opencode | codex\n--planning-model <model> # Model for planning (default: opus)\n--executor-model <model> # Model for execution (default: sonnet)\n--verbose # Detailed output\n--dry-run # Preview without executing\n```\n\n## Loop Mechanics\n\n### Iteration Flow\n\nEach `vralphy build` iteration:\n1. Reads IMPLEMENTATION_PLAN.md\n2. Identifies next unchecked task (`- [ ]`)\n3. Executes task using AI engine\n4. Runs validation (typecheck, tests, lint)\n5. On success: marks task complete (`- [x]`), commits\n6. Continues to next task\n\n### Context Window Management\n\n- Each iteration starts fresh\n- The AI reads relevant files on demand\n- AGENTS.md provides persistent project context\n- IMPLEMENTATION_PLAN.md tracks progress\n\n### Plan Completion\n\nWhen all tasks are `- [x]`:\n- Build mode exits successfully\n- Slack notification sent (if configured)\n- Ready for next spec or manual review\n\n## Key Files\n\n| File | Purpose |\n|------|---------|\n| `specs/*.md` | Feature specifications (input) |\n| `IMPLEMENTATION_PLAN.md` | Task list with checkboxes (state) |\n| `.vralphy/AGENTS.md` | Project context for AI agents |\n| `.vralphy/prompts/*.md` | Customizable prompts |\n| `.vralphy/logs/events.jsonl` | Event log (auto-rotates at 5MB) |\n| `.vralphy/config.json` | Project-specific configuration |\n\n## Event Logging\n\nEvents are logged to `.vralphy/logs/events.jsonl`:\n\n```json\n{\"timestamp\":\"...\",\"event\":\"build:start\",\"data\":{...}}\n{\"timestamp\":\"...\",\"event\":\"task:complete\",\"data\":{...}}\n{\"timestamp\":\"...\",\"event\":\"build:complete\",\"data\":{...}}\n```\n\nLog files auto-rotate at 5MB to prevent unbounded growth.\n\n## Model System\n\nvralphy uses a two-tier model approach:\n\n- **Planning model** (opus): Complex reasoning, orchestration, plan creation\n- **Executor model** (sonnet): Fast parallel task execution\n\n## Configuration\n\nPriority order:\n1. CLI flags (`--engine`, `--planning-model`)\n2. Environment (`VRALPHY_ENGINE`, `VRALPHY_PLANNING_MODEL`)\n3. Project config (`.vralphy/config.json`)\n4. Global config (`~/.config/vralphy/config.json`)\n5. Built-in defaults\n\n### Example Config\n\n```json\n{\n \"engine\": \"claude\",\n \"planningModel\": \"opus\",\n \"executorModel\": \"sonnet\",\n \"slackWebhook\": \"https://hooks.slack.com/...\"\n}\n```\n\n## Tips for AI Agents\n\n1. **Read IMPLEMENTATION_PLAN.md first** - understand current progress\n2. **Check .vralphy/AGENTS.md** - project-specific conventions\n3. **Run validation commands** - typecheck, test, lint before committing\n4. **Atomic commits** - one task = one commit\n5. **Update plan on completion** - mark tasks `- [x]` when done\n";
6
+ //# sourceMappingURL=readme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readme.d.ts","sourceRoot":"","sources":["../../../src/lib/templates/readme.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,eAAe,0gKAkK3B,CAAC"}
@@ -0,0 +1,168 @@
1
+ /**
2
+ * README template for .vralphy/README.md
3
+ * Comprehensive documentation for external AI coding agents
4
+ */
5
+ export const README_TEMPLATE = `# vralphy - AI Agent Documentation
6
+
7
+ This project uses **vralphy**, a CLI tool implementing the Ralph Playbook methodology for autonomous AI development.
8
+
9
+ ## What is vralphy?
10
+
11
+ vralphy wraps AI coding CLIs (Claude, OpenCode, Codex) with a loop-based execution model. It enables AI agents to autonomously plan, build, test, and commit code through structured iteration.
12
+
13
+ ## The Workflow Loop
14
+
15
+ \`\`\`
16
+ User specs → Plan phase → Build phase → Tests → Commit → Loop
17
+ ↑ │
18
+ └──────────────────────────────────────────────┘
19
+ \`\`\`
20
+
21
+ 1. **Specs** (\`specs/*.md\`): Define what to build
22
+ 2. **Plan** (\`vralphy plan\`): AI analyzes specs and creates IMPLEMENTATION_PLAN.md
23
+ 3. **Build** (\`vralphy build\`): AI executes tasks from the plan
24
+ 4. **Tests**: Validation runs after each iteration
25
+ 5. **Commit**: Changes are committed on successful validation
26
+ 6. **Loop**: Process repeats until plan is complete
27
+
28
+ ## Writing Specifications
29
+
30
+ Create \`.md\` files in \`specs/\` directory. Format:
31
+
32
+ \`\`\`markdown
33
+ # Feature Name
34
+
35
+ ## Goal
36
+ What this feature should accomplish.
37
+
38
+ ## Requirements
39
+ - Requirement 1
40
+ - Requirement 2
41
+
42
+ ## Constraints
43
+ - Any technical limitations or preferences
44
+
45
+ ## Acceptance Criteria
46
+ - [ ] Criterion 1
47
+ - [ ] Criterion 2
48
+ \`\`\`
49
+
50
+ ### Good Spec Examples
51
+
52
+ - Clear, atomic features
53
+ - Measurable acceptance criteria
54
+ - Specific constraints (not "make it fast")
55
+ - References to existing code when relevant
56
+
57
+ ### Avoid
58
+
59
+ - Vague requirements ("improve the code")
60
+ - Multiple unrelated features in one spec
61
+ - Implementation details (let AI decide how)
62
+
63
+ ## Key Commands
64
+
65
+ | Command | Description |
66
+ |---------|-------------|
67
+ | \`vralphy plan\` | Analyze specs and create/update IMPLEMENTATION_PLAN.md |
68
+ | \`vralphy build\` | Execute tasks from the implementation plan |
69
+ | \`vralphy spec <topic>\` | Interactive specification creation |
70
+ | \`vralphy init\` | Initialize vralphy in a project |
71
+ | \`vralphy cleanup\` | Remove vralphy artifacts |
72
+ | \`vralphy engines\` | List available AI engines |
73
+
74
+ ### Common Options
75
+
76
+ \`\`\`bash
77
+ --engine <name> # claude | opencode | codex
78
+ --planning-model <model> # Model for planning (default: opus)
79
+ --executor-model <model> # Model for execution (default: sonnet)
80
+ --verbose # Detailed output
81
+ --dry-run # Preview without executing
82
+ \`\`\`
83
+
84
+ ## Loop Mechanics
85
+
86
+ ### Iteration Flow
87
+
88
+ Each \`vralphy build\` iteration:
89
+ 1. Reads IMPLEMENTATION_PLAN.md
90
+ 2. Identifies next unchecked task (\`- [ ]\`)
91
+ 3. Executes task using AI engine
92
+ 4. Runs validation (typecheck, tests, lint)
93
+ 5. On success: marks task complete (\`- [x]\`), commits
94
+ 6. Continues to next task
95
+
96
+ ### Context Window Management
97
+
98
+ - Each iteration starts fresh
99
+ - The AI reads relevant files on demand
100
+ - AGENTS.md provides persistent project context
101
+ - IMPLEMENTATION_PLAN.md tracks progress
102
+
103
+ ### Plan Completion
104
+
105
+ When all tasks are \`- [x]\`:
106
+ - Build mode exits successfully
107
+ - Slack notification sent (if configured)
108
+ - Ready for next spec or manual review
109
+
110
+ ## Key Files
111
+
112
+ | File | Purpose |
113
+ |------|---------|
114
+ | \`specs/*.md\` | Feature specifications (input) |
115
+ | \`IMPLEMENTATION_PLAN.md\` | Task list with checkboxes (state) |
116
+ | \`.vralphy/AGENTS.md\` | Project context for AI agents |
117
+ | \`.vralphy/prompts/*.md\` | Customizable prompts |
118
+ | \`.vralphy/logs/events.jsonl\` | Event log (auto-rotates at 5MB) |
119
+ | \`.vralphy/config.json\` | Project-specific configuration |
120
+
121
+ ## Event Logging
122
+
123
+ Events are logged to \`.vralphy/logs/events.jsonl\`:
124
+
125
+ \`\`\`json
126
+ {"timestamp":"...","event":"build:start","data":{...}}
127
+ {"timestamp":"...","event":"task:complete","data":{...}}
128
+ {"timestamp":"...","event":"build:complete","data":{...}}
129
+ \`\`\`
130
+
131
+ Log files auto-rotate at 5MB to prevent unbounded growth.
132
+
133
+ ## Model System
134
+
135
+ vralphy uses a two-tier model approach:
136
+
137
+ - **Planning model** (opus): Complex reasoning, orchestration, plan creation
138
+ - **Executor model** (sonnet): Fast parallel task execution
139
+
140
+ ## Configuration
141
+
142
+ Priority order:
143
+ 1. CLI flags (\`--engine\`, \`--planning-model\`)
144
+ 2. Environment (\`VRALPHY_ENGINE\`, \`VRALPHY_PLANNING_MODEL\`)
145
+ 3. Project config (\`.vralphy/config.json\`)
146
+ 4. Global config (\`~/.config/vralphy/config.json\`)
147
+ 5. Built-in defaults
148
+
149
+ ### Example Config
150
+
151
+ \`\`\`json
152
+ {
153
+ "engine": "claude",
154
+ "planningModel": "opus",
155
+ "executorModel": "sonnet",
156
+ "slackWebhook": "https://hooks.slack.com/..."
157
+ }
158
+ \`\`\`
159
+
160
+ ## Tips for AI Agents
161
+
162
+ 1. **Read IMPLEMENTATION_PLAN.md first** - understand current progress
163
+ 2. **Check .vralphy/AGENTS.md** - project-specific conventions
164
+ 3. **Run validation commands** - typecheck, test, lint before committing
165
+ 4. **Atomic commits** - one task = one commit
166
+ 5. **Update plan on completion** - mark tasks \`- [x]\` when done
167
+ `;
168
+ //# sourceMappingURL=readme.js.map