@a-company/paradigm 2.0.13 → 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.
- package/dist/{auto-IU7VN55K.js → auto-6MOGYQ4G.js} +34 -0
- package/dist/chunk-27OSFWHG.js +199 -0
- package/dist/{chunk-2M6OSOIG.js → chunk-4WR7X3FE.js} +46 -0
- package/dist/{chunk-5GOA7WYD.js → chunk-GWM2WRXL.js} +1 -1
- package/dist/{chunk-THFVK5AE.js → chunk-QS36NGWV.js} +1 -1
- package/dist/{chunk-ELLR7WP6.js → chunk-S65LENNL.js} +4 -4
- package/dist/{chunk-YDNKXH4Z.js → chunk-YCLN7WXV.js} +37 -0
- package/dist/{chunk-753RICFF.js → chunk-ZPN7MXRA.js} +1 -1
- package/dist/{dist-7MPIRMTZ-IOQOREMZ.js → dist-2F7NO4H4-KSL6SJIO.js} +156 -4182
- package/dist/{doctor-6Y6L6HEB.js → doctor-JBIV5PMN.js} +2 -2
- package/dist/{hooks-MBWE4ILT.js → hooks-7TQIRXXS.js} +1 -1
- package/dist/index.js +56 -35
- package/dist/list-QMUE7DPK.js +53 -0
- package/dist/lore-server-3TAIUZ3Y.js +292 -0
- package/dist/mcp.js +856 -114
- package/dist/{promote-Z52ZJTJU.js → promote-E6NBZ3BK.js} +1 -0
- package/dist/record-5CTCDFUO.js +32 -0
- package/dist/review-QEDNQAIO.js +33 -0
- package/dist/{sentinel-LCFD56OJ.js → sentinel-RSEXIRXM.js} +1 -1
- package/dist/serve-WCIRW244.js +36 -0
- package/dist/server-E2CNZC4K.js +288 -0
- package/dist/server-NXG5N7JE.js +6135 -0
- package/dist/{shift-HKIAP4ZN.js → shift-NABNKPGL.js} +11 -5
- package/dist/show-S653P3TO.js +127 -0
- package/dist/{summary-H6J6N6PJ.js → summary-5SBFO7QK.js} +1 -1
- package/dist/{sync-BEOCW7TZ.js → sync-5KSTPJ4B.js} +2 -2
- package/dist/{triage-ETVXXFMV.js → triage-RM5KNG5V.js} +30 -31
- package/dist/{university-R2WDQLSI.js → university-65YJZ2LW.js} +10 -2
- package/dist/university-content/courses/para-101.json +561 -0
- package/dist/university-content/courses/para-201.json +707 -0
- package/dist/university-content/courses/para-301.json +654 -0
- package/dist/university-content/courses/para-401.json +640 -0
- package/dist/university-content/plsat/v2.0.json +760 -0
- package/dist/university-content/plsat/v3.0.json +1162 -0
- package/dist/university-content/reference.json +336 -0
- package/dist/university-ui/assets/index-CoBFthx2.js +87 -0
- package/dist/university-ui/assets/index-CoBFthx2.js.map +1 -0
- package/dist/university-ui/assets/index-DW2N5NTk.css +1 -0
- package/dist/university-ui/index.html +17 -0
- package/dist/{upgrade-5B3YGGC6.js → upgrade-TIYFQYPO.js} +1 -1
- package/dist/{watch-6IIWPWDN.js → watch-2XEYUH43.js} +1 -1
- package/lore-ui/dist/assets/index-DcT8TINz.js +56 -0
- package/lore-ui/dist/assets/index-DyJhpQ5w.css +1 -0
- package/lore-ui/dist/index.html +13 -0
- package/package.json +7 -3
- package/dist/chunk-ILOWBJRC.js +0 -12
- package/dist/chunk-MQWH7PFI.js +0 -13366
- package/dist/server-F5ITNK6T.js +0 -9846
- package/dist/server-T6WIFYRQ.js +0 -16076
|
@@ -450,6 +450,40 @@ Skipped ${skipped.length} existing file(s). Use --force to overwrite.`));
|
|
|
450
450
|
fs.writeFileSync(g.path, g.content);
|
|
451
451
|
}
|
|
452
452
|
spinner.succeed(chalk.green(`Generated ${generated.length} .purpose file(s)`));
|
|
453
|
+
if (options.init) {
|
|
454
|
+
const portalPath = path.join(rootDir, "portal.yaml");
|
|
455
|
+
const portalExists = fs.existsSync(portalPath);
|
|
456
|
+
if (portalExists && !options.force) {
|
|
457
|
+
console.log(chalk.gray("\nportal.yaml already exists. Use --force to overwrite."));
|
|
458
|
+
} else {
|
|
459
|
+
const portalGates = {};
|
|
460
|
+
const portalRoutes = {};
|
|
461
|
+
for (const gate of gates) {
|
|
462
|
+
portalGates[`^${gate.id}`] = {
|
|
463
|
+
description: gate.description,
|
|
464
|
+
check: `// TODO: implement ${gate.id} check`,
|
|
465
|
+
prizes: []
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
for (const route of routes) {
|
|
469
|
+
if (route.description.startsWith("GET ") || route.description.startsWith("POST ") || route.description.startsWith("PUT ") || route.description.startsWith("PATCH ") || route.description.startsWith("DELETE ")) {
|
|
470
|
+
const routeKey = route.description;
|
|
471
|
+
const gateRefs = gates.length > 0 ? gates.map((g) => `^${g.id}`) : ["# TODO: add gates"];
|
|
472
|
+
portalRoutes[routeKey] = gateRefs;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
if (Object.keys(portalGates).length > 0 || Object.keys(portalRoutes).length > 0) {
|
|
476
|
+
const portalData = { version: "1.0" };
|
|
477
|
+
if (Object.keys(portalGates).length > 0) portalData.gates = portalGates;
|
|
478
|
+
if (Object.keys(portalRoutes).length > 0) portalData.routes = portalRoutes;
|
|
479
|
+
const portalContent = yaml.dump(portalData, { lineWidth: -1, noRefs: true });
|
|
480
|
+
fs.writeFileSync(portalPath, portalContent);
|
|
481
|
+
spinner.succeed(chalk.green(`Generated portal.yaml with ${Object.keys(portalGates).length} gates and ${Object.keys(portalRoutes).length} routes`));
|
|
482
|
+
} else {
|
|
483
|
+
console.log(chalk.gray("\nNo gates or routes detected for portal.yaml."));
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
}
|
|
453
487
|
console.log(chalk.gray("\nNext steps:"));
|
|
454
488
|
console.log(chalk.gray(" 1. Review generated files and adjust descriptions"));
|
|
455
489
|
console.log(chalk.gray(" 2. Run `paradigm lint` to validate"));
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/core/lore/storage.ts
|
|
4
|
+
import * as fs from "fs";
|
|
5
|
+
import * as path from "path";
|
|
6
|
+
import * as yaml from "js-yaml";
|
|
7
|
+
|
|
8
|
+
// src/core/lore/filter.ts
|
|
9
|
+
function applyLoreFilter(entries, filter) {
|
|
10
|
+
let result = entries;
|
|
11
|
+
if (filter.author) {
|
|
12
|
+
result = result.filter((e) => e.author.id === filter.author);
|
|
13
|
+
}
|
|
14
|
+
if (filter.authorType) {
|
|
15
|
+
result = result.filter((e) => e.author.type === filter.authorType);
|
|
16
|
+
}
|
|
17
|
+
if (filter.symbol) {
|
|
18
|
+
result = result.filter(
|
|
19
|
+
(e) => e.symbols_touched.includes(filter.symbol) || e.symbols_created?.includes(filter.symbol)
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
if (filter.dateFrom) {
|
|
23
|
+
const from = new Date(filter.dateFrom).getTime();
|
|
24
|
+
result = result.filter((e) => new Date(e.timestamp).getTime() >= from);
|
|
25
|
+
}
|
|
26
|
+
if (filter.dateTo) {
|
|
27
|
+
const to = new Date(filter.dateTo).getTime();
|
|
28
|
+
result = result.filter((e) => new Date(e.timestamp).getTime() <= to);
|
|
29
|
+
}
|
|
30
|
+
if (filter.type) {
|
|
31
|
+
result = result.filter((e) => e.type === filter.type);
|
|
32
|
+
}
|
|
33
|
+
if (filter.tags && filter.tags.length > 0) {
|
|
34
|
+
result = result.filter(
|
|
35
|
+
(e) => filter.tags.some((tag) => e.tags?.includes(tag))
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
if (filter.hasReview !== void 0) {
|
|
39
|
+
result = result.filter(
|
|
40
|
+
(e) => filter.hasReview ? e.review != null : e.review == null
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
if (filter.minCompleteness !== void 0) {
|
|
44
|
+
result = result.filter(
|
|
45
|
+
(e) => e.review != null && e.review.completeness >= filter.minCompleteness
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
result.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
|
|
49
|
+
if (filter.offset) {
|
|
50
|
+
result = result.slice(filter.offset);
|
|
51
|
+
}
|
|
52
|
+
if (filter.limit) {
|
|
53
|
+
result = result.slice(0, filter.limit);
|
|
54
|
+
}
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// src/core/lore/storage.ts
|
|
59
|
+
var LORE_DIR = ".paradigm/lore";
|
|
60
|
+
var ENTRIES_DIR = "entries";
|
|
61
|
+
var TIMELINE_FILE = "timeline.yaml";
|
|
62
|
+
async function recordLore(rootDir, entry) {
|
|
63
|
+
const lorePath = path.join(rootDir, LORE_DIR);
|
|
64
|
+
const dateStr = entry.timestamp.slice(0, 10);
|
|
65
|
+
const datePath = path.join(lorePath, ENTRIES_DIR, dateStr);
|
|
66
|
+
if (!fs.existsSync(datePath)) {
|
|
67
|
+
fs.mkdirSync(datePath, { recursive: true });
|
|
68
|
+
}
|
|
69
|
+
if (!entry.id) {
|
|
70
|
+
entry.id = generateLoreId(rootDir, dateStr);
|
|
71
|
+
}
|
|
72
|
+
const entryPath = path.join(datePath, `${entry.id}.yaml`);
|
|
73
|
+
fs.writeFileSync(entryPath, yaml.dump(entry, { lineWidth: -1, noRefs: true }));
|
|
74
|
+
await rebuildTimeline(rootDir);
|
|
75
|
+
}
|
|
76
|
+
async function loadLoreEntries(rootDir, filter) {
|
|
77
|
+
const entriesPath = path.join(rootDir, LORE_DIR, ENTRIES_DIR);
|
|
78
|
+
if (!fs.existsSync(entriesPath)) {
|
|
79
|
+
return [];
|
|
80
|
+
}
|
|
81
|
+
const entries = [];
|
|
82
|
+
const dateDirs = fs.readdirSync(entriesPath).filter((d) => /^\d{4}-\d{2}-\d{2}$/.test(d)).sort().reverse();
|
|
83
|
+
for (const dateDir of dateDirs) {
|
|
84
|
+
if (filter?.dateFrom && dateDir < filter.dateFrom.slice(0, 10)) continue;
|
|
85
|
+
if (filter?.dateTo && dateDir > filter.dateTo.slice(0, 10)) continue;
|
|
86
|
+
const dirPath = path.join(entriesPath, dateDir);
|
|
87
|
+
const files = fs.readdirSync(dirPath).filter((f) => f.endsWith(".yaml")).sort();
|
|
88
|
+
for (const file of files) {
|
|
89
|
+
try {
|
|
90
|
+
const content = fs.readFileSync(path.join(dirPath, file), "utf8");
|
|
91
|
+
const entry = yaml.load(content);
|
|
92
|
+
entries.push(entry);
|
|
93
|
+
} catch {
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return filter ? applyLoreFilter(entries, filter) : entries;
|
|
98
|
+
}
|
|
99
|
+
async function rebuildTimeline(rootDir) {
|
|
100
|
+
const lorePath = path.join(rootDir, LORE_DIR);
|
|
101
|
+
const entriesPath = path.join(lorePath, ENTRIES_DIR);
|
|
102
|
+
if (!fs.existsSync(entriesPath)) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const authors = /* @__PURE__ */ new Set();
|
|
106
|
+
let entryCount = 0;
|
|
107
|
+
let lastUpdated = "";
|
|
108
|
+
const dateDirs = fs.readdirSync(entriesPath).filter((d) => /^\d{4}-\d{2}-\d{2}$/.test(d));
|
|
109
|
+
for (const dateDir of dateDirs) {
|
|
110
|
+
const dirPath = path.join(entriesPath, dateDir);
|
|
111
|
+
const files = fs.readdirSync(dirPath).filter((f) => f.endsWith(".yaml"));
|
|
112
|
+
for (const file of files) {
|
|
113
|
+
try {
|
|
114
|
+
const content = fs.readFileSync(path.join(dirPath, file), "utf8");
|
|
115
|
+
const entry = yaml.load(content);
|
|
116
|
+
authors.add(entry.author.id);
|
|
117
|
+
entryCount++;
|
|
118
|
+
if (!lastUpdated || entry.timestamp > lastUpdated) {
|
|
119
|
+
lastUpdated = entry.timestamp;
|
|
120
|
+
}
|
|
121
|
+
} catch {
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
let project = "unknown";
|
|
126
|
+
const configPath = path.join(rootDir, ".paradigm", "config.yaml");
|
|
127
|
+
if (fs.existsSync(configPath)) {
|
|
128
|
+
try {
|
|
129
|
+
const config = yaml.load(fs.readFileSync(configPath, "utf8"));
|
|
130
|
+
project = config.project || config.name || "unknown";
|
|
131
|
+
} catch {
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
const timeline = {
|
|
135
|
+
version: "1.0",
|
|
136
|
+
project,
|
|
137
|
+
entries: entryCount,
|
|
138
|
+
last_updated: lastUpdated || (/* @__PURE__ */ new Date()).toISOString(),
|
|
139
|
+
authors: Array.from(authors)
|
|
140
|
+
};
|
|
141
|
+
if (!fs.existsSync(lorePath)) {
|
|
142
|
+
fs.mkdirSync(lorePath, { recursive: true });
|
|
143
|
+
}
|
|
144
|
+
fs.writeFileSync(
|
|
145
|
+
path.join(lorePath, TIMELINE_FILE),
|
|
146
|
+
yaml.dump(timeline, { lineWidth: -1, noRefs: true })
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
async function addReview(rootDir, entryId, review) {
|
|
150
|
+
const entries = await loadLoreEntries(rootDir);
|
|
151
|
+
const entry = entries.find((e) => e.id === entryId);
|
|
152
|
+
if (!entry) {
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
const dateStr = entry.timestamp.slice(0, 10);
|
|
156
|
+
const entryPath = path.join(rootDir, LORE_DIR, ENTRIES_DIR, dateStr, `${entryId}.yaml`);
|
|
157
|
+
if (!fs.existsSync(entryPath)) {
|
|
158
|
+
return false;
|
|
159
|
+
}
|
|
160
|
+
entry.review = review;
|
|
161
|
+
fs.writeFileSync(entryPath, yaml.dump(entry, { lineWidth: -1, noRefs: true }));
|
|
162
|
+
return true;
|
|
163
|
+
}
|
|
164
|
+
async function loadLoreEntry(rootDir, entryId) {
|
|
165
|
+
const dateMatch = entryId.match(/^L-(\d{4}-\d{2}-\d{2})-/);
|
|
166
|
+
if (dateMatch) {
|
|
167
|
+
const dateStr = dateMatch[1];
|
|
168
|
+
const entryPath = path.join(rootDir, LORE_DIR, ENTRIES_DIR, dateStr, `${entryId}.yaml`);
|
|
169
|
+
if (fs.existsSync(entryPath)) {
|
|
170
|
+
try {
|
|
171
|
+
const content = fs.readFileSync(entryPath, "utf8");
|
|
172
|
+
return yaml.load(content);
|
|
173
|
+
} catch {
|
|
174
|
+
return null;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const entries = await loadLoreEntries(rootDir);
|
|
179
|
+
return entries.find((e) => e.id === entryId) || null;
|
|
180
|
+
}
|
|
181
|
+
function generateLoreId(rootDir, dateStr) {
|
|
182
|
+
const datePath = path.join(rootDir, LORE_DIR, ENTRIES_DIR, dateStr);
|
|
183
|
+
if (!fs.existsSync(datePath)) {
|
|
184
|
+
return `L-${dateStr}-001`;
|
|
185
|
+
}
|
|
186
|
+
const existing = fs.readdirSync(datePath).filter((f) => f.startsWith("L-") && f.endsWith(".yaml")).map((f) => {
|
|
187
|
+
const match = f.match(/L-\d{4}-\d{2}-\d{2}-(\d+)\.yaml/);
|
|
188
|
+
return match ? parseInt(match[1], 10) : 0;
|
|
189
|
+
});
|
|
190
|
+
const next = existing.length > 0 ? Math.max(...existing) + 1 : 1;
|
|
191
|
+
return `L-${dateStr}-${String(next).padStart(3, "0")}`;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
export {
|
|
195
|
+
recordLore,
|
|
196
|
+
loadLoreEntries,
|
|
197
|
+
addReview,
|
|
198
|
+
loadLoreEntry
|
|
199
|
+
};
|
|
@@ -113,6 +113,7 @@ var CLAUDE_CODE_STOP_HOOK = `#!/bin/sh
|
|
|
113
113
|
# 4. Aspect anchor files that no longer exist
|
|
114
114
|
# 5. Per-directory .purpose freshness (tracked via .pending-review)
|
|
115
115
|
# 6. Aspect coverage advisory
|
|
116
|
+
# 7. Lore entry expected for significant sessions (3+ source files)
|
|
116
117
|
|
|
117
118
|
# Read JSON from stdin (hook input)
|
|
118
119
|
INPUT=$(cat)
|
|
@@ -334,6 +335,27 @@ if [ "$HAS_ASPECTS" = true ] && [ "$SOURCE_COUNT" -gt 0 ]; then
|
|
|
334
335
|
fi
|
|
335
336
|
fi
|
|
336
337
|
|
|
338
|
+
# --- Check 7: Lore entry expected for significant sessions ---
|
|
339
|
+
if [ "$SOURCE_COUNT" -ge 3 ] && [ -d ".paradigm/lore" ]; then
|
|
340
|
+
LORE_RECORDED=false
|
|
341
|
+
for file in $MODIFIED; do
|
|
342
|
+
case "$file" in
|
|
343
|
+
.paradigm/lore/entries/*.yaml|.paradigm/lore/entries/*/*.yaml)
|
|
344
|
+
LORE_RECORDED=true
|
|
345
|
+
break
|
|
346
|
+
;;
|
|
347
|
+
esac
|
|
348
|
+
done
|
|
349
|
+
|
|
350
|
+
if [ "$LORE_RECORDED" = false ]; then
|
|
351
|
+
VIOLATIONS="$VIOLATIONS
|
|
352
|
+
- You modified $SOURCE_COUNT source files but recorded no lore entry.
|
|
353
|
+
Record your session: paradigm_lore_record (MCP) or paradigm lore record (CLI).
|
|
354
|
+
Include: type, title, summary, and symbols_touched."
|
|
355
|
+
VIOLATION_COUNT=$((VIOLATION_COUNT + 1))
|
|
356
|
+
fi
|
|
357
|
+
fi
|
|
358
|
+
|
|
337
359
|
# --- Final verdict ---
|
|
338
360
|
if [ "$VIOLATION_COUNT" -gt 0 ]; then
|
|
339
361
|
echo "" >&2
|
|
@@ -350,6 +372,7 @@ if [ "$VIOLATION_COUNT" -gt 0 ]; then
|
|
|
350
372
|
echo " 2. paradigm_purpose_add_aspect \u2014 register cross-cutting concerns (with anchors)" >&2
|
|
351
373
|
echo " 3. paradigm_portal_add_route \u2014 register new endpoints with gates" >&2
|
|
352
374
|
echo " 4. paradigm_reindex \u2014 rebuild indexes after updates" >&2
|
|
375
|
+
echo " 5. paradigm_lore_record \u2014 record session lore entry" >&2
|
|
353
376
|
exit 2
|
|
354
377
|
fi
|
|
355
378
|
|
|
@@ -525,6 +548,7 @@ var CURSOR_STOP_HOOK = `#!/bin/sh
|
|
|
525
548
|
# 4. Aspect anchor files that no longer exist
|
|
526
549
|
# 5. Per-directory .purpose freshness (tracked via .pending-review)
|
|
527
550
|
# 6. Aspect coverage advisory
|
|
551
|
+
# 7. Lore entry expected for significant sessions (3+ source files)
|
|
528
552
|
|
|
529
553
|
# Read JSON from stdin (hook input)
|
|
530
554
|
INPUT=$(cat)
|
|
@@ -746,6 +770,27 @@ if [ "$HAS_ASPECTS" = true ] && [ "$SOURCE_COUNT" -gt 0 ]; then
|
|
|
746
770
|
fi
|
|
747
771
|
fi
|
|
748
772
|
|
|
773
|
+
# --- Check 7: Lore entry expected for significant sessions ---
|
|
774
|
+
if [ "$SOURCE_COUNT" -ge 3 ] && [ -d ".paradigm/lore" ]; then
|
|
775
|
+
LORE_RECORDED=false
|
|
776
|
+
for file in $MODIFIED; do
|
|
777
|
+
case "$file" in
|
|
778
|
+
.paradigm/lore/entries/*.yaml|.paradigm/lore/entries/*/*.yaml)
|
|
779
|
+
LORE_RECORDED=true
|
|
780
|
+
break
|
|
781
|
+
;;
|
|
782
|
+
esac
|
|
783
|
+
done
|
|
784
|
+
|
|
785
|
+
if [ "$LORE_RECORDED" = false ]; then
|
|
786
|
+
VIOLATIONS="$VIOLATIONS
|
|
787
|
+
- You modified $SOURCE_COUNT source files but recorded no lore entry.
|
|
788
|
+
Record your session: paradigm_lore_record (MCP) or paradigm lore record (CLI).
|
|
789
|
+
Include: type, title, summary, and symbols_touched."
|
|
790
|
+
VIOLATION_COUNT=$((VIOLATION_COUNT + 1))
|
|
791
|
+
fi
|
|
792
|
+
fi
|
|
793
|
+
|
|
749
794
|
# --- Final verdict ---
|
|
750
795
|
if [ "$VIOLATION_COUNT" -gt 0 ]; then
|
|
751
796
|
echo "" >&2
|
|
@@ -762,6 +807,7 @@ if [ "$VIOLATION_COUNT" -gt 0 ]; then
|
|
|
762
807
|
echo " 2. paradigm_purpose_add_aspect \u2014 register cross-cutting concerns (with anchors)" >&2
|
|
763
808
|
echo " 3. paradigm_portal_add_route \u2014 register new endpoints with gates" >&2
|
|
764
809
|
echo " 4. paradigm_reindex \u2014 rebuild indexes after updates" >&2
|
|
810
|
+
echo " 5. paradigm_lore_record \u2014 record session lore entry" >&2
|
|
765
811
|
exit 2
|
|
766
812
|
fi
|
|
767
813
|
|
|
@@ -2121,7 +2121,7 @@ var require_sql_wasm = __commonJS({
|
|
|
2121
2121
|
}
|
|
2122
2122
|
});
|
|
2123
2123
|
|
|
2124
|
-
// ../sentinel/dist/chunk-
|
|
2124
|
+
// ../sentinel/dist/chunk-WNZBSJR7.js
|
|
2125
2125
|
var import_sql = __toESM(require_sql_wasm(), 1);
|
|
2126
2126
|
|
|
2127
2127
|
// ../sentinel/node_modules/uuid/dist/esm-node/rng.js
|
|
@@ -2171,7 +2171,7 @@ function v4(options, buf, offset) {
|
|
|
2171
2171
|
}
|
|
2172
2172
|
var v4_default = v4;
|
|
2173
2173
|
|
|
2174
|
-
// ../sentinel/dist/chunk-
|
|
2174
|
+
// ../sentinel/dist/chunk-WNZBSJR7.js
|
|
2175
2175
|
import * as path from "path";
|
|
2176
2176
|
import * as fs from "fs";
|
|
2177
2177
|
var SCHEMA_VERSION = 1;
|
|
@@ -2191,8 +2191,8 @@ var SentinelStorage = class {
|
|
|
2191
2191
|
this.dbPath = dbPath || this.getDefaultDbPath();
|
|
2192
2192
|
}
|
|
2193
2193
|
getDefaultDbPath() {
|
|
2194
|
-
const
|
|
2195
|
-
return path.join(
|
|
2194
|
+
const dataDir = process.env.SENTINEL_DATA_DIR || process.env.PARADIGM_DATA_DIR || path.join(process.cwd(), ".paradigm", "sentinel");
|
|
2195
|
+
return path.join(dataDir, "sentinel.db");
|
|
2196
2196
|
}
|
|
2197
2197
|
createSchema() {
|
|
2198
2198
|
if (!this.db) return;
|
|
@@ -532,6 +532,8 @@ ${f.content}`).join("\n\n---\n\n");
|
|
|
532
532
|
const overview = generateOverview(config);
|
|
533
533
|
return frontmatter("Paradigm core rules - project overview and fundamentals", { alwaysApply: true }) + `# Paradigm - ${projectName}
|
|
534
534
|
|
|
535
|
+
> **Author:** Matt Canoy ([@ascend42](https://github.com/ascend42)) | **Repo:** [github.com/ascend42/a-paradigm](https://github.com/ascend42/a-paradigm) | **npm:** [@a-company/paradigm](https://www.npmjs.com/package/@a-company/paradigm)
|
|
536
|
+
|
|
535
537
|
` + overview + "\n\n" + generateUpdateRules(config);
|
|
536
538
|
}
|
|
537
539
|
/**
|
|
@@ -1499,6 +1501,8 @@ var ClaudeAdapter = class {
|
|
|
1499
1501
|
sections.push(`# ${projectName} - Claude Context`);
|
|
1500
1502
|
sections.push("");
|
|
1501
1503
|
sections.push("> **Paradigm v2.0** | For Claude Code, Claude API, and Claude-native interfaces");
|
|
1504
|
+
sections.push(">");
|
|
1505
|
+
sections.push("> **Author:** Matt Canoy ([@ascend42](https://github.com/ascend42)) | **Repo:** [github.com/ascend42/a-paradigm](https://github.com/ascend42/a-paradigm) | **npm:** [@a-company/paradigm](https://www.npmjs.com/package/@a-company/paradigm) | **Plugin:** `paradigm` via Claude Code marketplace");
|
|
1502
1506
|
sections.push("");
|
|
1503
1507
|
sections.push("## Project Overview");
|
|
1504
1508
|
sections.push("");
|
|
@@ -1514,6 +1518,7 @@ var ClaudeAdapter = class {
|
|
|
1514
1518
|
sections.push(".paradigm/docs/ \u2192 Commands, patterns, troubleshooting");
|
|
1515
1519
|
sections.push(".cursorrules \u2192 IDE instructions (if using Cursor)");
|
|
1516
1520
|
sections.push("portal.yaml \u2192 Security/auth definitions");
|
|
1521
|
+
sections.push(".paradigm/lore/ \u2192 Project timeline and history");
|
|
1517
1522
|
sections.push("```");
|
|
1518
1523
|
sections.push("");
|
|
1519
1524
|
sections.push(generateTerminalGuidance());
|
|
@@ -1620,6 +1625,35 @@ var ClaudeAdapter = class {
|
|
|
1620
1625
|
sections.push("3. Check `portal.yaml` for existing auth gates");
|
|
1621
1626
|
sections.push("4. Check `.paradigm/docs/patterns.md` for coding patterns");
|
|
1622
1627
|
sections.push("");
|
|
1628
|
+
sections.push("## Lore (Project Timeline)");
|
|
1629
|
+
sections.push("");
|
|
1630
|
+
sections.push("Lore records what happened, why, and what was learned \u2014 forming a queryable project history.");
|
|
1631
|
+
sections.push("");
|
|
1632
|
+
sections.push("### MCP Tools");
|
|
1633
|
+
sections.push("");
|
|
1634
|
+
sections.push("| Tool | Purpose |");
|
|
1635
|
+
sections.push("|------|---------|");
|
|
1636
|
+
sections.push("| `paradigm_lore_search` | Search and filter lore entries by author, symbol, date, type |");
|
|
1637
|
+
sections.push("| `paradigm_lore_record` | Record a new lore entry (session, decision, milestone, etc.) |");
|
|
1638
|
+
sections.push("| `paradigm_lore_timeline` | Get project timeline summary with entry count and authors |");
|
|
1639
|
+
sections.push("");
|
|
1640
|
+
sections.push("### CLI Commands");
|
|
1641
|
+
sections.push("");
|
|
1642
|
+
sections.push("| Command | Description |");
|
|
1643
|
+
sections.push("|---------|-------------|");
|
|
1644
|
+
sections.push("| `paradigm lore` | List recent lore entries |");
|
|
1645
|
+
sections.push("| `paradigm lore record` | Interactively record a new entry |");
|
|
1646
|
+
sections.push("| `paradigm lore show <id>` | Show full details of an entry |");
|
|
1647
|
+
sections.push("| `paradigm lore review <id>` | Add human review to an entry |");
|
|
1648
|
+
sections.push("| `paradigm lore timeline` | Show project timeline summary |");
|
|
1649
|
+
sections.push("");
|
|
1650
|
+
sections.push("### When to Record Lore");
|
|
1651
|
+
sections.push("");
|
|
1652
|
+
sections.push("- After completing a feature or significant session");
|
|
1653
|
+
sections.push("- When making architectural decisions");
|
|
1654
|
+
sections.push("- After resolving incidents or bugs");
|
|
1655
|
+
sections.push("- At project milestones");
|
|
1656
|
+
sections.push("");
|
|
1623
1657
|
sections.push(generateNavigationSection(config));
|
|
1624
1658
|
sections.push("## Context Monitoring Protocol");
|
|
1625
1659
|
sections.push("");
|
|
@@ -1651,6 +1685,8 @@ var ClaudeAdapter = class {
|
|
|
1651
1685
|
sections.push("| **Getting test data** | `paradigm_test_fixtures` for fixtures |");
|
|
1652
1686
|
sections.push('| **Building a feature (3+ files)** | `paradigm_orchestrate_inline` mode="plan" |');
|
|
1653
1687
|
sections.push('| **Task involves security + code** | `paradigm_orchestrate_inline` mode="plan" |');
|
|
1688
|
+
sections.push("| **Recording work done** | `paradigm_lore_record` to capture session history |");
|
|
1689
|
+
sections.push("| **Checking project history** | `paradigm_lore_timeline` for timeline overview |");
|
|
1654
1690
|
sections.push("| **Finishing work session** | `paradigm_reindex` to rebuild static index |");
|
|
1655
1691
|
sections.push("");
|
|
1656
1692
|
sections.push("**Benefits**: ~100 tokens per query vs ~2000 for reading files. Always fresh data from live index.");
|
|
@@ -1861,6 +1897,7 @@ var ClaudeAdapter = class {
|
|
|
1861
1897
|
sections.push("| Add multi-step flow | Document as `$flow` in `.purpose` |");
|
|
1862
1898
|
sections.push("| Rename/delete symbol | Update all `.purpose` references |");
|
|
1863
1899
|
sections.push("| Learn antipattern | Add to `.paradigm/wisdom/antipatterns.yaml` |");
|
|
1900
|
+
sections.push("| Complete feature/session | Record lore entry via `paradigm_lore_record` |");
|
|
1864
1901
|
sections.push("");
|
|
1865
1902
|
sections.push("**CRITICAL: Authorization requires portal.yaml**");
|
|
1866
1903
|
sections.push("");
|