@a-company/paradigm 3.18.0 → 3.19.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,283 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- // ../paradigm-mcp/src/utils/assessment-loader.ts
4
- import * as fs from "fs";
5
- import * as path from "path";
6
- import * as yaml from "js-yaml";
7
- var ASSESSMENTS_DIR = ".paradigm/assessments";
8
- var ARCS_DIR = "arcs";
9
- var INDEX_FILE = "index.yaml";
10
- function generateAssessmentId(rootDir, dateStr) {
11
- const arcsPath = path.join(rootDir, ASSESSMENTS_DIR, ARCS_DIR);
12
- let maxSeq = 0;
13
- if (fs.existsSync(arcsPath)) {
14
- const arcDirs = fs.readdirSync(arcsPath).filter((d) => {
15
- try {
16
- return fs.statSync(path.join(arcsPath, d)).isDirectory();
17
- } catch {
18
- return false;
19
- }
20
- });
21
- for (const arcDir of arcDirs) {
22
- const entriesPath = path.join(arcsPath, arcDir, "entries");
23
- if (!fs.existsSync(entriesPath)) continue;
24
- const files = fs.readdirSync(entriesPath).filter(
25
- (f) => f.startsWith(`A-${dateStr}-`) && f.endsWith(".yaml")
26
- );
27
- for (const file of files) {
28
- const match = file.match(/A-\d{4}-\d{2}-\d{2}-(\d+)\.yaml/);
29
- if (match) {
30
- const seq = parseInt(match[1], 10);
31
- if (seq > maxSeq) maxSeq = seq;
32
- }
33
- }
34
- }
35
- }
36
- return `A-${dateStr}-${String(maxSeq + 1).padStart(3, "0")}`;
37
- }
38
- function computeArcStats(rootDir, arc) {
39
- const entriesPath = path.join(rootDir, ASSESSMENTS_DIR, ARCS_DIR, arc.id, "entries");
40
- const symbolSet = /* @__PURE__ */ new Set();
41
- let entryCount = 0;
42
- let latestDate;
43
- if (fs.existsSync(entriesPath)) {
44
- const files = fs.readdirSync(entriesPath).filter((f) => f.endsWith(".yaml"));
45
- for (const file of files) {
46
- try {
47
- const entry = yaml.load(fs.readFileSync(path.join(entriesPath, file), "utf8"));
48
- entryCount++;
49
- if (entry.symbols) entry.symbols.forEach((s) => symbolSet.add(s));
50
- if (!latestDate || entry.date > latestDate) latestDate = entry.date;
51
- } catch {
52
- }
53
- }
54
- }
55
- return { ...arc, entry_count: entryCount, symbols: Array.from(symbolSet), latest_entry: latestDate };
56
- }
57
- async function loadArcs(rootDir, status) {
58
- const arcsPath = path.join(rootDir, ASSESSMENTS_DIR, ARCS_DIR);
59
- if (!fs.existsSync(arcsPath)) return [];
60
- const arcDirs = fs.readdirSync(arcsPath).filter((d) => {
61
- try {
62
- return fs.statSync(path.join(arcsPath, d)).isDirectory();
63
- } catch {
64
- return false;
65
- }
66
- });
67
- const arcs = [];
68
- for (const arcDir of arcDirs) {
69
- const arcFile = path.join(arcsPath, arcDir, "arc.yaml");
70
- if (!fs.existsSync(arcFile)) continue;
71
- try {
72
- const arc = yaml.load(fs.readFileSync(arcFile, "utf8"));
73
- if (status && status !== "all" && arc.status !== status) continue;
74
- arcs.push(computeArcStats(rootDir, arc));
75
- } catch {
76
- }
77
- }
78
- arcs.sort((a, b) => {
79
- const aDate = a.latest_entry || a.created;
80
- const bDate = b.latest_entry || b.created;
81
- return bDate.localeCompare(aDate);
82
- });
83
- return arcs;
84
- }
85
- async function loadArc(rootDir, arcId) {
86
- const arcFile = path.join(rootDir, ASSESSMENTS_DIR, ARCS_DIR, arcId, "arc.yaml");
87
- if (!fs.existsSync(arcFile)) return null;
88
- try {
89
- const arc = yaml.load(fs.readFileSync(arcFile, "utf8"));
90
- return computeArcStats(rootDir, arc);
91
- } catch {
92
- return null;
93
- }
94
- }
95
- var ARC_ID_PATTERN = /^arc-[a-z0-9-]+$/;
96
- async function createArc(rootDir, arc) {
97
- if (!ARC_ID_PATTERN.test(arc.id)) {
98
- throw new Error(`Invalid arc ID "${arc.id}": must match arc-{kebab-case} (lowercase alphanumeric + hyphens)`);
99
- }
100
- const arcPath = path.join(rootDir, ASSESSMENTS_DIR, ARCS_DIR, arc.id);
101
- const entriesPath = path.join(arcPath, "entries");
102
- fs.mkdirSync(entriesPath, { recursive: true });
103
- const arcData = {
104
- id: arc.id,
105
- name: arc.name,
106
- description: arc.description,
107
- created: (/* @__PURE__ */ new Date()).toISOString(),
108
- status: "active",
109
- tags: arc.tags
110
- };
111
- fs.writeFileSync(path.join(arcPath, "arc.yaml"), yaml.dump(arcData, { lineWidth: -1, noRefs: true }));
112
- await rebuildAssessmentIndex(rootDir);
113
- return arc.id;
114
- }
115
- async function closeArc(rootDir, arcId, status) {
116
- const arcFile = path.join(rootDir, ASSESSMENTS_DIR, ARCS_DIR, arcId, "arc.yaml");
117
- if (!fs.existsSync(arcFile)) return false;
118
- try {
119
- const arc = yaml.load(fs.readFileSync(arcFile, "utf8"));
120
- arc.status = status;
121
- fs.writeFileSync(arcFile, yaml.dump(arc, { lineWidth: -1, noRefs: true }));
122
- await rebuildAssessmentIndex(rootDir);
123
- return true;
124
- } catch {
125
- return false;
126
- }
127
- }
128
- async function loadEntries(rootDir, arcId) {
129
- const entriesPath = path.join(rootDir, ASSESSMENTS_DIR, ARCS_DIR, arcId, "entries");
130
- if (!fs.existsSync(entriesPath)) return [];
131
- const entries = [];
132
- const files = fs.readdirSync(entriesPath).filter((f) => f.endsWith(".yaml")).sort();
133
- for (const file of files) {
134
- try {
135
- const entry = yaml.load(fs.readFileSync(path.join(entriesPath, file), "utf8"));
136
- entries.push(entry);
137
- } catch {
138
- }
139
- }
140
- entries.sort((a, b) => b.date.localeCompare(a.date));
141
- return entries;
142
- }
143
- async function loadEntry(rootDir, entryId) {
144
- const arcsPath = path.join(rootDir, ASSESSMENTS_DIR, ARCS_DIR);
145
- if (!fs.existsSync(arcsPath)) return null;
146
- const arcDirs = fs.readdirSync(arcsPath).filter((d) => {
147
- try {
148
- return fs.statSync(path.join(arcsPath, d)).isDirectory();
149
- } catch {
150
- return false;
151
- }
152
- });
153
- for (const arcDir of arcDirs) {
154
- const entryFile = path.join(arcsPath, arcDir, "entries", `${entryId}.yaml`);
155
- if (fs.existsSync(entryFile)) {
156
- try {
157
- const entry = yaml.load(fs.readFileSync(entryFile, "utf8"));
158
- const arcFile = path.join(arcsPath, arcDir, "arc.yaml");
159
- const arc = yaml.load(fs.readFileSync(arcFile, "utf8"));
160
- return { entry, arc };
161
- } catch {
162
- return null;
163
- }
164
- }
165
- }
166
- return null;
167
- }
168
- async function recordEntry(rootDir, entry, arcName, arcDescription) {
169
- const arcPath = path.join(rootDir, ASSESSMENTS_DIR, ARCS_DIR, entry.arc_id);
170
- if (!fs.existsSync(path.join(arcPath, "arc.yaml"))) {
171
- if (!arcName) {
172
- throw new Error(`Arc "${entry.arc_id}" does not exist. Provide arc_name to create it.`);
173
- }
174
- await createArc(rootDir, { id: entry.arc_id, name: arcName, description: arcDescription, tags: entry.symbols });
175
- }
176
- const now = /* @__PURE__ */ new Date();
177
- const dateStr = now.toISOString().slice(0, 10);
178
- const id = generateAssessmentId(rootDir, dateStr);
179
- const fullEntry = {
180
- id,
181
- arc_id: entry.arc_id,
182
- title: entry.title,
183
- summary: entry.summary,
184
- body: entry.body,
185
- symbols: entry.symbols,
186
- tags: entry.tags,
187
- linked_lore: entry.linked_lore,
188
- linked_tasks: entry.linked_tasks,
189
- linked_commits: entry.linked_commits,
190
- date: now.toISOString(),
191
- author: { type: "agent", id: "claude", model: "claude-opus-4-6" },
192
- type: entry.type || "retro"
193
- };
194
- const entriesPath = path.join(arcPath, "entries");
195
- fs.mkdirSync(entriesPath, { recursive: true });
196
- fs.writeFileSync(path.join(entriesPath, `${id}.yaml`), yaml.dump(fullEntry, { lineWidth: -1, noRefs: true }));
197
- await rebuildAssessmentIndex(rootDir);
198
- return id;
199
- }
200
- async function searchEntries(rootDir, filter) {
201
- const arcsPath = path.join(rootDir, ASSESSMENTS_DIR, ARCS_DIR);
202
- if (!fs.existsSync(arcsPath)) return [];
203
- const limit = filter.limit || 20;
204
- const results = [];
205
- const arcDirs = fs.readdirSync(arcsPath).filter((d) => {
206
- try {
207
- return fs.statSync(path.join(arcsPath, d)).isDirectory();
208
- } catch {
209
- return false;
210
- }
211
- });
212
- for (const arcDir of arcDirs) {
213
- const entriesPath = path.join(arcsPath, arcDir, "entries");
214
- if (!fs.existsSync(entriesPath)) continue;
215
- const files = fs.readdirSync(entriesPath).filter((f) => f.endsWith(".yaml"));
216
- for (const file of files) {
217
- try {
218
- const entry = yaml.load(fs.readFileSync(path.join(entriesPath, file), "utf8"));
219
- if (filter.symbol && !(entry.symbols || []).includes(filter.symbol)) continue;
220
- if (filter.tag && !(entry.tags || []).includes(filter.tag)) continue;
221
- if (filter.type && entry.type !== filter.type) continue;
222
- if (filter.dateFrom && entry.date < filter.dateFrom) continue;
223
- if (filter.dateTo && entry.date > filter.dateTo) continue;
224
- results.push(entry);
225
- } catch {
226
- }
227
- }
228
- }
229
- results.sort((a, b) => b.date.localeCompare(a.date));
230
- return results.slice(0, limit);
231
- }
232
- async function rebuildAssessmentIndex(rootDir) {
233
- const arcsPath = path.join(rootDir, ASSESSMENTS_DIR, ARCS_DIR);
234
- const assessmentsPath = path.join(rootDir, ASSESSMENTS_DIR);
235
- let totalArcs = 0, totalEntries = 0, activeArcs = 0;
236
- const arcSummaries = [];
237
- if (fs.existsSync(arcsPath)) {
238
- const arcDirs = fs.readdirSync(arcsPath).filter((d) => {
239
- try {
240
- return fs.statSync(path.join(arcsPath, d)).isDirectory();
241
- } catch {
242
- return false;
243
- }
244
- });
245
- for (const arcDir of arcDirs) {
246
- const arcFile = path.join(arcsPath, arcDir, "arc.yaml");
247
- if (!fs.existsSync(arcFile)) continue;
248
- try {
249
- const arc = yaml.load(fs.readFileSync(arcFile, "utf8"));
250
- const entriesPath = path.join(arcsPath, arcDir, "entries");
251
- const entryCount = fs.existsSync(entriesPath) ? fs.readdirSync(entriesPath).filter((f) => f.endsWith(".yaml")).length : 0;
252
- totalArcs++;
253
- totalEntries += entryCount;
254
- if (arc.status === "active") activeArcs++;
255
- arcSummaries.push({ id: arc.id, name: arc.name, status: arc.status, entries: entryCount });
256
- } catch {
257
- }
258
- }
259
- }
260
- const index = {
261
- version: "1.0",
262
- total_arcs: totalArcs,
263
- total_entries: totalEntries,
264
- active_arcs: activeArcs,
265
- last_updated: (/* @__PURE__ */ new Date()).toISOString(),
266
- arcs: arcSummaries
267
- };
268
- fs.mkdirSync(assessmentsPath, { recursive: true });
269
- fs.writeFileSync(path.join(assessmentsPath, INDEX_FILE), yaml.dump(index, { lineWidth: -1, noRefs: true }));
270
- return index;
271
- }
272
-
273
- export {
274
- loadArcs,
275
- loadArc,
276
- createArc,
277
- closeArc,
278
- loadEntries,
279
- loadEntry,
280
- recordEntry,
281
- searchEntries,
282
- rebuildAssessmentIndex
283
- };