@really-knows-ai/foundry 2.3.2 → 3.0.1

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 (170) hide show
  1. package/README.md +180 -369
  2. package/dist/.opencode/plugins/foundry-tools/appraiser-tools.js +28 -0
  3. package/dist/.opencode/plugins/foundry-tools/artefact-tools.js +58 -0
  4. package/dist/.opencode/plugins/foundry-tools/assay-tools.js +92 -0
  5. package/dist/.opencode/plugins/foundry-tools/attestation-tools.js +191 -0
  6. package/dist/.opencode/plugins/foundry-tools/config-create-tools.js +128 -0
  7. package/dist/.opencode/plugins/foundry-tools/config-law-tools.js +380 -0
  8. package/dist/.opencode/plugins/foundry-tools/config-tools.js +43 -0
  9. package/dist/.opencode/plugins/foundry-tools/feedback-tools.js +234 -0
  10. package/dist/.opencode/plugins/foundry-tools/git-helpers.js +354 -0
  11. package/dist/.opencode/plugins/foundry-tools/git-tools.js +181 -0
  12. package/dist/.opencode/plugins/foundry-tools/helpers.js +340 -0
  13. package/dist/.opencode/plugins/foundry-tools/history-tools.js +20 -0
  14. package/dist/.opencode/plugins/foundry-tools/memory-admin-tools.js +296 -0
  15. package/dist/.opencode/plugins/foundry-tools/memory-helpers.js +104 -0
  16. package/dist/.opencode/plugins/foundry-tools/memory-tools.js +286 -0
  17. package/dist/.opencode/plugins/foundry-tools/orchestrate-tool.js +159 -0
  18. package/dist/.opencode/plugins/foundry-tools/snapshot-tools.js +104 -0
  19. package/dist/.opencode/plugins/foundry-tools/stage-tools.js +186 -0
  20. package/dist/.opencode/plugins/foundry-tools/validate-tools.js +263 -0
  21. package/dist/.opencode/plugins/foundry-tools/workfile-tools.js +102 -0
  22. package/dist/.opencode/plugins/foundry.js +105 -0
  23. package/dist/CHANGELOG.md +533 -0
  24. package/dist/LICENSE +21 -0
  25. package/dist/README.md +278 -0
  26. package/dist/docs/README.md +59 -0
  27. package/dist/docs/architecture.md +433 -0
  28. package/dist/docs/concepts.md +395 -0
  29. package/dist/docs/getting-started.md +344 -0
  30. package/dist/docs/memory-maintenance.md +176 -0
  31. package/dist/docs/tools.md +1411 -0
  32. package/dist/docs/work-spec.md +283 -0
  33. package/dist/scripts/lib/artefacts.js +151 -0
  34. package/dist/scripts/lib/assay/loader.js +151 -0
  35. package/dist/scripts/lib/assay/parse-jsonl.js +102 -0
  36. package/dist/scripts/lib/assay/permissions.js +52 -0
  37. package/dist/scripts/lib/assay/run.js +219 -0
  38. package/dist/scripts/lib/assay/spawn-with-timeout.js +138 -0
  39. package/dist/scripts/lib/attestation/attest.js +111 -0
  40. package/dist/scripts/lib/attestation/canonical-json.js +109 -0
  41. package/dist/scripts/lib/attestation/hash.js +17 -0
  42. package/dist/scripts/lib/attestation/parse.js +14 -0
  43. package/dist/scripts/lib/attestation/payload.js +106 -0
  44. package/dist/scripts/lib/attestation/render.js +16 -0
  45. package/dist/scripts/lib/attestation/verify.js +15 -0
  46. package/dist/scripts/lib/branch-guard.js +72 -0
  47. package/dist/scripts/lib/config-creators/appraiser.js +9 -0
  48. package/dist/scripts/lib/config-creators/artefact-type.js +9 -0
  49. package/dist/scripts/lib/config-creators/cycle.js +11 -0
  50. package/dist/scripts/lib/config-creators/factory.js +49 -0
  51. package/dist/scripts/lib/config-creators/flow.js +11 -0
  52. package/dist/scripts/lib/config-validators/appraiser.js +49 -0
  53. package/dist/scripts/lib/config-validators/artefact-type.js +38 -0
  54. package/dist/scripts/lib/config-validators/cycle.js +131 -0
  55. package/dist/scripts/lib/config-validators/flow.js +57 -0
  56. package/dist/scripts/lib/config-validators/helpers.js +96 -0
  57. package/dist/scripts/lib/config-validators/law.js +96 -0
  58. package/dist/scripts/lib/config.js +328 -0
  59. package/dist/scripts/lib/failed-flow.js +131 -0
  60. package/dist/scripts/lib/feedback-store.js +249 -0
  61. package/dist/scripts/lib/feedback-transitions.js +105 -0
  62. package/dist/scripts/lib/finalize.js +70 -0
  63. package/dist/scripts/lib/foundational-guards.js +13 -0
  64. package/dist/scripts/lib/git-bridge.js +77 -0
  65. package/dist/scripts/lib/git-finish/work-finish.js +233 -0
  66. package/dist/scripts/lib/git-policy.js +101 -0
  67. package/dist/scripts/lib/guards.js +125 -0
  68. package/dist/scripts/lib/history.js +132 -0
  69. package/dist/scripts/lib/memory/admin/create-edge-type.js +91 -0
  70. package/dist/scripts/lib/memory/admin/create-entity-type.js +43 -0
  71. package/dist/scripts/lib/memory/admin/create-extractor.js +67 -0
  72. package/dist/scripts/lib/memory/admin/drop-edge-type.js +40 -0
  73. package/dist/scripts/lib/memory/admin/drop-entity-type.js +172 -0
  74. package/dist/scripts/lib/memory/admin/dump.js +47 -0
  75. package/dist/scripts/lib/memory/admin/helpers.js +31 -0
  76. package/dist/scripts/lib/memory/admin/init.js +170 -0
  77. package/dist/scripts/lib/memory/admin/live-store.js +76 -0
  78. package/dist/scripts/lib/memory/admin/reembed.js +285 -0
  79. package/dist/scripts/lib/memory/admin/rename-edge-type.js +54 -0
  80. package/dist/scripts/lib/memory/admin/rename-entity-type.js +151 -0
  81. package/dist/scripts/lib/memory/admin/reset.js +24 -0
  82. package/dist/scripts/lib/memory/admin/vacuum.js +9 -0
  83. package/dist/scripts/lib/memory/admin/validate.js +19 -0
  84. package/dist/scripts/lib/memory/config.js +149 -0
  85. package/dist/scripts/lib/memory/cozo.js +136 -0
  86. package/dist/scripts/lib/memory/drift.js +71 -0
  87. package/dist/scripts/lib/memory/embeddings.js +128 -0
  88. package/dist/scripts/lib/memory/frontmatter.js +75 -0
  89. package/dist/scripts/lib/memory/ndjson.js +84 -0
  90. package/dist/scripts/lib/memory/paths.js +25 -0
  91. package/dist/scripts/lib/memory/permissions.js +41 -0
  92. package/dist/scripts/lib/memory/prompt.js +109 -0
  93. package/dist/scripts/lib/memory/query.js +56 -0
  94. package/dist/scripts/lib/memory/reads.js +109 -0
  95. package/dist/scripts/lib/memory/schema.js +64 -0
  96. package/dist/scripts/lib/memory/search.js +73 -0
  97. package/dist/scripts/lib/memory/singleton.js +49 -0
  98. package/dist/scripts/lib/memory/store.js +162 -0
  99. package/dist/scripts/lib/memory/types.js +93 -0
  100. package/dist/scripts/lib/memory/validate.js +58 -0
  101. package/dist/scripts/lib/memory/writes.js +40 -0
  102. package/{scripts → dist/scripts}/lib/pending.js +7 -2
  103. package/dist/scripts/lib/secret.js +59 -0
  104. package/{scripts → dist/scripts}/lib/slug.js +3 -2
  105. package/dist/scripts/lib/snapshot/finish.js +103 -0
  106. package/dist/scripts/lib/snapshot/inspect.js +253 -0
  107. package/dist/scripts/lib/snapshot/render.js +55 -0
  108. package/dist/scripts/lib/sort-fs-check.js +121 -0
  109. package/dist/scripts/lib/sort-routing.js +101 -0
  110. package/{scripts → dist/scripts}/lib/stage-guard.js +12 -6
  111. package/{scripts → dist/scripts}/lib/state.js +4 -0
  112. package/dist/scripts/lib/token.js +57 -0
  113. package/dist/scripts/lib/tracing.js +59 -0
  114. package/dist/scripts/lib/ulid.js +100 -0
  115. package/dist/scripts/lib/validator-jsonl.js +162 -0
  116. package/{scripts → dist/scripts}/lib/workfile.js +38 -20
  117. package/dist/scripts/orchestrate-cycle.js +215 -0
  118. package/dist/scripts/orchestrate-phases.js +314 -0
  119. package/dist/scripts/orchestrate.js +163 -0
  120. package/dist/scripts/sort.js +278 -0
  121. package/{skills → dist/skills}/add-appraiser/SKILL.md +39 -9
  122. package/{skills → dist/skills}/add-artefact-type/SKILL.md +62 -40
  123. package/{skills → dist/skills}/add-cycle/SKILL.md +57 -17
  124. package/dist/skills/add-extractor/SKILL.md +133 -0
  125. package/{skills → dist/skills}/add-flow/SKILL.md +36 -10
  126. package/dist/skills/add-law/SKILL.md +191 -0
  127. package/dist/skills/add-memory-edge-type/SKILL.md +52 -0
  128. package/dist/skills/add-memory-entity-type/SKILL.md +74 -0
  129. package/{skills → dist/skills}/appraise/SKILL.md +62 -13
  130. package/dist/skills/assay/SKILL.md +72 -0
  131. package/dist/skills/change-embedding-model/SKILL.md +58 -0
  132. package/dist/skills/drop-memory-edge-type/SKILL.md +54 -0
  133. package/dist/skills/drop-memory-entity-type/SKILL.md +57 -0
  134. package/dist/skills/dry-run/SKILL.md +116 -0
  135. package/{skills → dist/skills}/flow/SKILL.md +15 -2
  136. package/dist/skills/forge/SKILL.md +121 -0
  137. package/dist/skills/human-appraise/SKILL.md +153 -0
  138. package/{skills → dist/skills}/init-foundry/SKILL.md +23 -4
  139. package/dist/skills/init-memory/SKILL.md +92 -0
  140. package/{skills → dist/skills}/orchestrate/SKILL.md +30 -4
  141. package/dist/skills/quench/SKILL.md +99 -0
  142. package/{skills → dist/skills}/refresh-agents/SKILL.md +1 -1
  143. package/dist/skills/rename-memory-edge-type/SKILL.md +50 -0
  144. package/dist/skills/rename-memory-entity-type/SKILL.md +51 -0
  145. package/dist/skills/reset-memory/SKILL.md +54 -0
  146. package/dist/skills/upgrade-foundry/SKILL.md +191 -0
  147. package/package.json +34 -17
  148. package/.opencode/plugins/foundry.js +0 -761
  149. package/CHANGELOG.md +0 -100
  150. package/docs/concepts.md +0 -122
  151. package/docs/getting-started.md +0 -187
  152. package/docs/work-spec.md +0 -207
  153. package/scripts/lib/artefacts.js +0 -124
  154. package/scripts/lib/config.js +0 -175
  155. package/scripts/lib/feedback-transitions.js +0 -25
  156. package/scripts/lib/feedback.js +0 -440
  157. package/scripts/lib/finalize.js +0 -41
  158. package/scripts/lib/history.js +0 -59
  159. package/scripts/lib/secret.js +0 -23
  160. package/scripts/lib/tags.js +0 -108
  161. package/scripts/lib/token.js +0 -26
  162. package/scripts/orchestrate.js +0 -418
  163. package/scripts/sort.js +0 -370
  164. package/scripts/validate-tags.js +0 -54
  165. package/skills/add-law/SKILL.md +0 -111
  166. package/skills/forge/SKILL.md +0 -88
  167. package/skills/human-appraise/SKILL.md +0 -82
  168. package/skills/quench/SKILL.md +0 -62
  169. package/skills/upgrade-foundry/SKILL.md +0 -216
  170. /package/{skills → dist/skills}/list-agents/SKILL.md +0 -0
@@ -1,124 +0,0 @@
1
- /**
2
- * Artefacts table utilities for WORK.md.
3
- *
4
- * Parses, adds rows to, and updates status in the markdown artefacts table.
5
- */
6
-
7
- /**
8
- * Parse the artefacts markdown table from text.
9
- * @param {string} text
10
- * @returns {Array<{file: string, type: string, cycle: string, status: string}>}
11
- */
12
- export function parseArtefactsTable(text) {
13
- const artefacts = [];
14
- let inTable = false;
15
-
16
- for (const line of text.split('\n')) {
17
- const stripped = line.trim();
18
-
19
- if (stripped.startsWith('| File')) {
20
- inTable = true;
21
- continue;
22
- }
23
- if (inTable && stripped.startsWith('|---')) {
24
- continue;
25
- }
26
- if (inTable && stripped.startsWith('|')) {
27
- const cols = stripped.split('|').slice(1, -1).map(c => c.trim());
28
- if (cols.length >= 4) {
29
- artefacts.push({
30
- file: cols[0],
31
- type: cols[1],
32
- cycle: cols[2],
33
- status: cols[3],
34
- });
35
- }
36
- } else if (inTable) {
37
- inTable = false;
38
- }
39
- }
40
-
41
- return artefacts;
42
- }
43
-
44
- /**
45
- * Add a row to the artefacts table.
46
- * @param {string} text - Full WORK.md text
47
- * @param {{file: string, type: string, cycle: string, status: string}} row
48
- * @returns {string} Updated text
49
- */
50
- export function addArtefactRow(text, { file, type, cycle, status }) {
51
- const lines = text.split('\n');
52
- let lastTableRow = -1;
53
- let inTable = false;
54
-
55
- for (let i = 0; i < lines.length; i++) {
56
- const stripped = lines[i].trim();
57
- if (stripped.startsWith('| File')) {
58
- inTable = true;
59
- continue;
60
- }
61
- if (inTable && stripped.startsWith('|---')) {
62
- if (lastTableRow < 0) lastTableRow = i; // insert after separator if no data rows
63
- continue;
64
- }
65
- if (inTable && stripped.startsWith('|')) {
66
- lastTableRow = i;
67
- } else if (inTable) {
68
- break;
69
- }
70
- }
71
-
72
- if (lastTableRow === -1) {
73
- throw new Error('Artefacts table not found');
74
- }
75
-
76
- const newRow = `| ${file} | ${type} | ${cycle} | ${status} |`;
77
- lines.splice(lastTableRow + 1, 0, newRow);
78
- return lines.join('\n');
79
- }
80
-
81
- /**
82
- * Update the status column for a specific file in the artefacts table.
83
- * @param {string} text - Full WORK.md text
84
- * @param {string} file - File name to match
85
- * @param {string} newStatus - New status value
86
- * @returns {string} Updated text
87
- */
88
- export function setArtefactStatus(text, file, newStatus) {
89
- if (newStatus === 'draft') {
90
- throw new Error('status draft not permitted; use stage_finalize for registration');
91
- }
92
- if (!['done', 'blocked'].includes(newStatus)) {
93
- throw new Error(`invalid status: ${newStatus}`);
94
- }
95
- const lines = text.split('\n');
96
- let inTable = false;
97
- let found = false;
98
-
99
- for (let i = 0; i < lines.length; i++) {
100
- const stripped = lines[i].trim();
101
- if (stripped.startsWith('| File')) {
102
- inTable = true;
103
- continue;
104
- }
105
- if (inTable && stripped.startsWith('|---')) continue;
106
- if (inTable && stripped.startsWith('|')) {
107
- const cols = stripped.split('|').slice(1, -1).map(c => c.trim());
108
- if (cols.length >= 4 && cols[0] === file) {
109
- cols[3] = newStatus;
110
- lines[i] = '| ' + cols.join(' | ') + ' |';
111
- found = true;
112
- break;
113
- }
114
- } else if (inTable) {
115
- break;
116
- }
117
- }
118
-
119
- if (!found) {
120
- throw new Error(`File not found in artefacts table: ${file}`);
121
- }
122
-
123
- return lines.join('\n');
124
- }
@@ -1,175 +0,0 @@
1
- /**
2
- * Structured reads of foundry/ directory contents.
3
- */
4
-
5
- import { join } from 'path';
6
- import { parseFrontmatter } from './workfile.js';
7
-
8
- function parseDoc(text) {
9
- const frontmatter = parseFrontmatter(text);
10
- const body = text.replace(/^---\n.+?\n---\n?/s, '').trim();
11
- return { frontmatter, body };
12
- }
13
-
14
- export async function getCycleDefinition(foundryDir, cycleId, io) {
15
- const path = join(foundryDir, 'cycles', `${cycleId}.md`);
16
- if (!(await io.exists(path))) {
17
- throw new Error(`Cycle not found: ${cycleId}`);
18
- }
19
- const text = await io.readFile(path);
20
- return parseDoc(text);
21
- }
22
-
23
- export async function getArtefactType(foundryDir, typeId, io) {
24
- const path = join(foundryDir, 'artefacts', typeId, 'definition.md');
25
- if (!(await io.exists(path))) {
26
- throw new Error(`Artefact type not found: ${typeId}`);
27
- }
28
- const text = await io.readFile(path);
29
- return parseDoc(text);
30
- }
31
-
32
- export async function getLaws(foundryDir, typeId, io) {
33
- // Handle optional typeId: if typeId is the io object, shift args
34
- if (typeId && typeof typeId === 'object' && typeof typeId.exists === 'function') {
35
- io = typeId;
36
- typeId = null;
37
- }
38
-
39
- const laws = [];
40
-
41
- function parseLaws(text, source) {
42
- const lines = text.split('\n');
43
- let currentId = null;
44
- let currentLines = [];
45
-
46
- for (const line of lines) {
47
- const heading = line.match(/^## (.+)/);
48
- if (heading) {
49
- if (currentId) {
50
- laws.push({ id: currentId, text: currentLines.join('\n').trim(), source });
51
- }
52
- currentId = heading[1];
53
- currentLines = [];
54
- } else if (currentId) {
55
- currentLines.push(line);
56
- }
57
- }
58
- if (currentId) {
59
- laws.push({ id: currentId, text: currentLines.join('\n').trim(), source });
60
- }
61
- }
62
-
63
- // Global laws
64
- const globalDir = join(foundryDir, 'laws');
65
- if (await io.exists(globalDir)) {
66
- const files = await io.readDir(globalDir);
67
- const mdFiles = files.filter(f => f.endsWith('.md')).sort();
68
- for (const file of mdFiles) {
69
- const text = await io.readFile(join(globalDir, file));
70
- parseLaws(text, `laws/${file}`);
71
- }
72
- }
73
-
74
- // Type-specific laws
75
- if (typeId) {
76
- const typeLawsPath = join(foundryDir, 'artefacts', typeId, 'laws.md');
77
- if (await io.exists(typeLawsPath)) {
78
- const text = await io.readFile(typeLawsPath);
79
- parseLaws(text, `artefacts/${typeId}/laws.md`);
80
- }
81
- }
82
-
83
- return laws;
84
- }
85
-
86
- export async function getValidation(foundryDir, typeId, io) {
87
- const path = join(foundryDir, 'artefacts', typeId, 'validation.md');
88
- if (!(await io.exists(path))) {
89
- return null;
90
- }
91
- const text = await io.readFile(path);
92
- const entries = [];
93
- const lines = text.split('\n');
94
- let currentId = null;
95
- let currentCommand = null;
96
- let currentFailure = null;
97
-
98
- function flush() {
99
- if (currentId && currentCommand) {
100
- const entry = { id: currentId, command: currentCommand };
101
- if (currentFailure) entry.failureMeans = currentFailure;
102
- entries.push(entry);
103
- }
104
- currentId = null;
105
- currentCommand = null;
106
- currentFailure = null;
107
- }
108
-
109
- for (const line of lines) {
110
- const heading = line.match(/^## (.+)/);
111
- if (heading) {
112
- flush();
113
- currentId = heading[1].trim();
114
- } else if (currentId) {
115
- const cmdMatch = line.match(/^Command:\s*(.+)/);
116
- const failMatch = line.match(/^Failure means:\s*(.+)/);
117
- if (cmdMatch) currentCommand = cmdMatch[1].trim().replace(/^`|`$/g, '');
118
- if (failMatch) currentFailure = failMatch[1].trim();
119
- }
120
- }
121
- flush();
122
- return entries;
123
- }
124
-
125
- export async function getAppraisers(foundryDir, io) {
126
- const dir = join(foundryDir, 'appraisers');
127
- if (!(await io.exists(dir))) return [];
128
- const files = await io.readDir(dir);
129
- const mdFiles = files.filter(f => f.endsWith('.md')).sort();
130
- const result = [];
131
- for (const file of mdFiles) {
132
- const text = await io.readFile(join(dir, file));
133
- const { frontmatter, body } = parseDoc(text);
134
- const entry = { id: frontmatter.id, personality: body };
135
- if (frontmatter.model) entry.model = frontmatter.model;
136
- result.push(entry);
137
- }
138
- return result;
139
- }
140
-
141
- export async function getFlow(foundryDir, flowId, io) {
142
- const path = join(foundryDir, 'flows', `${flowId}.md`);
143
- if (!(await io.exists(path))) {
144
- throw new Error(`Flow not found: ${flowId}`);
145
- }
146
- const text = await io.readFile(path);
147
- return parseDoc(text);
148
- }
149
-
150
- export async function selectAppraisers(foundryDir, typeId, countOverride, io) {
151
- // Handle optional countOverride
152
- if (countOverride && typeof countOverride === 'object' && typeof countOverride.exists === 'function') {
153
- io = countOverride;
154
- countOverride = null;
155
- }
156
-
157
- const { frontmatter } = await getArtefactType(foundryDir, typeId, io);
158
- const appraiserConfig = frontmatter.appraisers || {};
159
- const count = countOverride || appraiserConfig.count || 3;
160
- const allowed = appraiserConfig.allowed || null;
161
-
162
- const allAppraisers = await getAppraisers(foundryDir, io);
163
- let pool = allowed
164
- ? allAppraisers.filter(a => allowed.includes(a.id))
165
- : allAppraisers;
166
-
167
- if (pool.length === 0) return [];
168
-
169
- // Round-robin distribute
170
- const result = [];
171
- for (let i = 0; i < count; i++) {
172
- result.push(pool[i % pool.length]);
173
- }
174
- return result;
175
- }
@@ -1,25 +0,0 @@
1
- import { createHash } from 'node:crypto';
2
-
3
- // Matrix: [current][target] => set of allowed stageBases
4
- const MATRIX = {
5
- open: { actioned: ['forge'], 'wont-fix': ['forge'] },
6
- actioned: { approved: ['quench', 'appraise', 'human-appraise'], rejected: ['quench', 'appraise', 'human-appraise'] },
7
- 'wont-fix': { approved: ['appraise', 'human-appraise'], rejected: ['appraise', 'human-appraise'] },
8
- rejected: { actioned: ['forge'], 'wont-fix': ['forge'] },
9
- approved: {}, // terminal
10
- };
11
-
12
- export function validateTransition(current, target, stageBase) {
13
- const row = MATRIX[current];
14
- if (!row) return { ok: false, reason: `unknown state: ${current}` };
15
- const allowedStages = row[target];
16
- if (!allowedStages) return { ok: false, reason: `invalid transition ${current} → ${target}` };
17
- if (!allowedStages.includes(stageBase)) {
18
- return { ok: false, reason: `stage ${stageBase} cannot transition ${current} → ${target}` };
19
- }
20
- return { ok: true };
21
- }
22
-
23
- export function hashText(text) {
24
- return createHash('sha256').update(text).digest('hex').slice(0, 16);
25
- }