@a-company/paradigm 3.1.0 → 3.1.2
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/{chunk-LRSJNX7K.js → chunk-AQZSUGL3.js} +16 -6
- package/dist/{chunk-X3ROB27T.js → chunk-MVXJVRFI.js} +44 -1
- package/dist/delete-W67IVTLJ.js +45 -0
- package/dist/edit-Y7XPYSMK.js +63 -0
- package/dist/habits-FA65W77Y.js +1153 -0
- package/dist/{hooks-ZVGXLK6Z.js → hooks-YXPQV4SP.js} +1 -1
- package/dist/index.js +51 -19
- package/dist/{list-SDYF6T7M.js → list-R3QWW4SC.js} +3 -1
- package/dist/{lore-server-3TAIUZ3Y.js → lore-server-RQH5REZV.js} +166 -41
- package/dist/mcp.js +439 -26
- package/dist/{record-5IY5RWTI.js → record-OHQNWOUP.js} +7 -2
- package/dist/{review-CSA223ZJ.js → review-RUHX25A5.js} +1 -1
- package/dist/{serve-WCIRW244.js → serve-H7ZBMODT.js} +1 -1
- package/dist/{shift-DLV5YLFJ.js → shift-JDBRTHWO.js} +1 -1
- package/dist/{show-QRV7CWKT.js → show-WTOJXUTN.js} +1 -1
- package/dist/timeline-P7BARFLI.js +110 -0
- package/dist/university-content/courses/para-401.json +1 -1
- package/dist/university-content/courses/para-501.json +4 -4
- package/lore-ui/dist/assets/index-BB3P4Cok.js +56 -0
- package/lore-ui/dist/assets/index-DI0Q6NmX.css +1 -0
- package/lore-ui/dist/index.html +2 -2
- package/package.json +1 -1
- package/dist/habits-YVCOZ2LC.js +0 -485
- package/lore-ui/dist/assets/index-DcT8TINz.js +0 -56
- package/lore-ui/dist/assets/index-DyJhpQ5w.css +0 -1
|
@@ -242,7 +242,6 @@ fi
|
|
|
242
242
|
# --- Check 4: Aspect anchor files that no longer exist ---
|
|
243
243
|
for purpose_file in $(find . -name ".purpose" -not -path "*/node_modules/*" -not -path "*/.git/*" 2>/dev/null); do
|
|
244
244
|
if grep -q "anchors:" "$purpose_file" 2>/dev/null; then
|
|
245
|
-
purpose_dir=$(dirname "$purpose_file")
|
|
246
245
|
in_anchors=false
|
|
247
246
|
while IFS= read -r line; do
|
|
248
247
|
case "$line" in
|
|
@@ -251,8 +250,7 @@ for purpose_file in $(find . -name ".purpose" -not -path "*/node_modules/*" -not
|
|
|
251
250
|
if [ "$in_anchors" = true ]; then
|
|
252
251
|
anchor_path=$(echo "$line" | sed 's/.*- //' | sed 's/:.*//' | tr -d ' ')
|
|
253
252
|
if [ -n "$anchor_path" ]; then
|
|
254
|
-
|
|
255
|
-
if [ ! -f "$resolved_path" ]; then
|
|
253
|
+
if [ ! -f "$anchor_path" ]; then
|
|
256
254
|
VIOLATIONS="$VIOLATIONS
|
|
257
255
|
- Aspect anchor '$anchor_path' in $purpose_file does not exist.
|
|
258
256
|
Update the anchor or remove the stale aspect."
|
|
@@ -357,6 +355,13 @@ if [ "$SOURCE_COUNT" -ge 3 ] && [ -d ".paradigm/lore" ]; then
|
|
|
357
355
|
fi
|
|
358
356
|
fi
|
|
359
357
|
|
|
358
|
+
# --- Auto-evaluate on-stop habits via CLI ---
|
|
359
|
+
if command -v paradigm >/dev/null 2>&1; then
|
|
360
|
+
paradigm habits check --trigger on-stop --record --json 2>/dev/null || true
|
|
361
|
+
elif command -v npx >/dev/null 2>&1; then
|
|
362
|
+
npx paradigm habits check --trigger on-stop --record --json 2>/dev/null || true
|
|
363
|
+
fi
|
|
364
|
+
|
|
360
365
|
# --- Check 8: Blocking habits ---
|
|
361
366
|
if [ -f ".paradigm/.habits-blocking" ]; then
|
|
362
367
|
HABITS_BLOCKING=$(cat ".paradigm/.habits-blocking")
|
|
@@ -690,7 +695,6 @@ fi
|
|
|
690
695
|
# --- Check 4: Aspect anchor files that no longer exist ---
|
|
691
696
|
for purpose_file in $(find . -name ".purpose" -not -path "*/node_modules/*" -not -path "*/.git/*" 2>/dev/null); do
|
|
692
697
|
if grep -q "anchors:" "$purpose_file" 2>/dev/null; then
|
|
693
|
-
purpose_dir=$(dirname "$purpose_file")
|
|
694
698
|
in_anchors=false
|
|
695
699
|
while IFS= read -r line; do
|
|
696
700
|
case "$line" in
|
|
@@ -699,8 +703,7 @@ for purpose_file in $(find . -name ".purpose" -not -path "*/node_modules/*" -not
|
|
|
699
703
|
if [ "$in_anchors" = true ]; then
|
|
700
704
|
anchor_path=$(echo "$line" | sed 's/.*- //' | sed 's/:.*//' | tr -d ' ')
|
|
701
705
|
if [ -n "$anchor_path" ]; then
|
|
702
|
-
|
|
703
|
-
if [ ! -f "$resolved_path" ]; then
|
|
706
|
+
if [ ! -f "$anchor_path" ]; then
|
|
704
707
|
VIOLATIONS="$VIOLATIONS
|
|
705
708
|
- Aspect anchor '$anchor_path' in $purpose_file does not exist.
|
|
706
709
|
Update the anchor or remove the stale aspect."
|
|
@@ -805,6 +808,13 @@ if [ "$SOURCE_COUNT" -ge 3 ] && [ -d ".paradigm/lore" ]; then
|
|
|
805
808
|
fi
|
|
806
809
|
fi
|
|
807
810
|
|
|
811
|
+
# --- Auto-evaluate on-stop habits via CLI ---
|
|
812
|
+
if command -v paradigm >/dev/null 2>&1; then
|
|
813
|
+
paradigm habits check --trigger on-stop --record --json 2>/dev/null || true
|
|
814
|
+
elif command -v npx >/dev/null 2>&1; then
|
|
815
|
+
npx paradigm habits check --trigger on-stop --record --json 2>/dev/null || true
|
|
816
|
+
fi
|
|
817
|
+
|
|
808
818
|
# --- Check 8: Blocking habits ---
|
|
809
819
|
if [ -f ".paradigm/.habits-blocking" ]; then
|
|
810
820
|
HABITS_BLOCKING=$(cat ".paradigm/.habits-blocking")
|
|
@@ -180,6 +180,47 @@ async function loadLoreEntry(rootDir, entryId) {
|
|
|
180
180
|
const entries = await loadLoreEntries(rootDir);
|
|
181
181
|
return entries.find((e) => e.id === entryId) || null;
|
|
182
182
|
}
|
|
183
|
+
async function updateLoreEntry(rootDir, entryId, partial) {
|
|
184
|
+
const entry = await loadLoreEntry(rootDir, entryId);
|
|
185
|
+
if (!entry) return false;
|
|
186
|
+
const dateStr = entry.timestamp.slice(0, 10);
|
|
187
|
+
const entryPath = path.join(rootDir, LORE_DIR, ENTRIES_DIR, dateStr, `${entryId}.yaml`);
|
|
188
|
+
if (!fs.existsSync(entryPath)) return false;
|
|
189
|
+
if (partial.title !== void 0) entry.title = partial.title;
|
|
190
|
+
if (partial.summary !== void 0) entry.summary = partial.summary;
|
|
191
|
+
if (partial.type !== void 0) entry.type = partial.type;
|
|
192
|
+
if (partial.duration_minutes !== void 0) entry.duration_minutes = partial.duration_minutes;
|
|
193
|
+
if (partial.symbols_touched !== void 0) entry.symbols_touched = partial.symbols_touched;
|
|
194
|
+
if (partial.symbols_created !== void 0) entry.symbols_created = partial.symbols_created;
|
|
195
|
+
if (partial.files_created !== void 0) entry.files_created = partial.files_created;
|
|
196
|
+
if (partial.files_modified !== void 0) entry.files_modified = partial.files_modified;
|
|
197
|
+
if (partial.lines_added !== void 0) entry.lines_added = partial.lines_added;
|
|
198
|
+
if (partial.lines_removed !== void 0) entry.lines_removed = partial.lines_removed;
|
|
199
|
+
if (partial.commit !== void 0) entry.commit = partial.commit;
|
|
200
|
+
if (partial.decisions !== void 0) entry.decisions = partial.decisions;
|
|
201
|
+
if (partial.errors_encountered !== void 0) entry.errors_encountered = partial.errors_encountered;
|
|
202
|
+
if (partial.learnings !== void 0) entry.learnings = partial.learnings;
|
|
203
|
+
if (partial.verification !== void 0) entry.verification = partial.verification;
|
|
204
|
+
if (partial.tags !== void 0) entry.tags = partial.tags;
|
|
205
|
+
fs.writeFileSync(entryPath, yaml.dump(entry, { lineWidth: -1, noRefs: true }));
|
|
206
|
+
await rebuildTimeline(rootDir);
|
|
207
|
+
return true;
|
|
208
|
+
}
|
|
209
|
+
async function deleteLoreEntry(rootDir, entryId) {
|
|
210
|
+
const entry = await loadLoreEntry(rootDir, entryId);
|
|
211
|
+
if (!entry) return false;
|
|
212
|
+
const dateStr = entry.timestamp.slice(0, 10);
|
|
213
|
+
const entryPath = path.join(rootDir, LORE_DIR, ENTRIES_DIR, dateStr, `${entryId}.yaml`);
|
|
214
|
+
if (!fs.existsSync(entryPath)) return false;
|
|
215
|
+
fs.unlinkSync(entryPath);
|
|
216
|
+
const dateDir = path.dirname(entryPath);
|
|
217
|
+
const remaining = fs.readdirSync(dateDir).filter((f) => f.endsWith(".yaml"));
|
|
218
|
+
if (remaining.length === 0) {
|
|
219
|
+
fs.rmdirSync(dateDir);
|
|
220
|
+
}
|
|
221
|
+
await rebuildTimeline(rootDir);
|
|
222
|
+
return true;
|
|
223
|
+
}
|
|
183
224
|
function migrateLegacyEntries(rootDir) {
|
|
184
225
|
const entriesPath = path.join(rootDir, LORE_DIR, ENTRIES_DIR);
|
|
185
226
|
if (!fs.existsSync(entriesPath)) return 0;
|
|
@@ -249,5 +290,7 @@ export {
|
|
|
249
290
|
recordLore,
|
|
250
291
|
loadLoreEntries,
|
|
251
292
|
addReview,
|
|
252
|
-
loadLoreEntry
|
|
293
|
+
loadLoreEntry,
|
|
294
|
+
updateLoreEntry,
|
|
295
|
+
deleteLoreEntry
|
|
253
296
|
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
deleteLoreEntry,
|
|
4
|
+
loadLoreEntry
|
|
5
|
+
} from "./chunk-MVXJVRFI.js";
|
|
6
|
+
import "./chunk-MO4EEYFW.js";
|
|
7
|
+
|
|
8
|
+
// src/commands/lore/delete.ts
|
|
9
|
+
import chalk from "chalk";
|
|
10
|
+
async function loreDeleteCommand(id, options) {
|
|
11
|
+
const rootDir = process.cwd();
|
|
12
|
+
const entry = await loadLoreEntry(rootDir, id);
|
|
13
|
+
if (!entry) {
|
|
14
|
+
console.error(chalk.red(`
|
|
15
|
+
Entry not found: ${id}
|
|
16
|
+
`));
|
|
17
|
+
process.exitCode = 1;
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (!options.yes) {
|
|
21
|
+
console.log(chalk.yellow(`
|
|
22
|
+
Will delete lore entry:`));
|
|
23
|
+
console.log(chalk.white(` ${entry.id} - ${entry.title}`));
|
|
24
|
+
console.log(chalk.gray(` Type: ${entry.type} | Author: ${entry.author.id} | ${entry.timestamp}`));
|
|
25
|
+
console.log(chalk.gray(` Symbols: ${entry.symbols_touched.join(", ")}`));
|
|
26
|
+
console.log(chalk.gray(`
|
|
27
|
+
Use --yes to confirm deletion.
|
|
28
|
+
`));
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const success = await deleteLoreEntry(rootDir, id);
|
|
32
|
+
if (success) {
|
|
33
|
+
console.log(chalk.green(`
|
|
34
|
+
Deleted lore entry: ${id}
|
|
35
|
+
`));
|
|
36
|
+
} else {
|
|
37
|
+
console.error(chalk.red(`
|
|
38
|
+
Failed to delete: ${id}
|
|
39
|
+
`));
|
|
40
|
+
process.exitCode = 1;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export {
|
|
44
|
+
loreDeleteCommand
|
|
45
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
loadLoreEntry,
|
|
4
|
+
updateLoreEntry
|
|
5
|
+
} from "./chunk-MVXJVRFI.js";
|
|
6
|
+
import "./chunk-MO4EEYFW.js";
|
|
7
|
+
|
|
8
|
+
// src/commands/lore/edit.ts
|
|
9
|
+
import chalk from "chalk";
|
|
10
|
+
async function loreEditCommand(id, options) {
|
|
11
|
+
const rootDir = process.cwd();
|
|
12
|
+
const entry = await loadLoreEntry(rootDir, id);
|
|
13
|
+
if (!entry) {
|
|
14
|
+
console.error(chalk.red(`
|
|
15
|
+
Entry not found: ${id}
|
|
16
|
+
`));
|
|
17
|
+
process.exitCode = 1;
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const partial = {};
|
|
21
|
+
if (options.title) partial.title = options.title;
|
|
22
|
+
if (options.summary) partial.summary = options.summary;
|
|
23
|
+
if (options.type) {
|
|
24
|
+
const validTypes = ["agent-session", "human-note", "decision", "review", "incident", "milestone"];
|
|
25
|
+
if (!validTypes.includes(options.type)) {
|
|
26
|
+
console.error(chalk.red(`Invalid type: ${options.type}. Valid: ${validTypes.join(", ")}`));
|
|
27
|
+
process.exitCode = 1;
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
partial.type = options.type;
|
|
31
|
+
}
|
|
32
|
+
if (options.symbols) {
|
|
33
|
+
partial.symbols_touched = options.symbols.split(",").map((s) => s.trim());
|
|
34
|
+
}
|
|
35
|
+
if (options.tags) {
|
|
36
|
+
partial.tags = options.tags.split(",").map((t) => t.trim());
|
|
37
|
+
}
|
|
38
|
+
if (options.learnings) {
|
|
39
|
+
partial.learnings = options.learnings.split(",").map((l) => l.trim());
|
|
40
|
+
}
|
|
41
|
+
if (Object.keys(partial).length === 0) {
|
|
42
|
+
console.log(chalk.yellow("\n No changes specified. Use --title, --summary, --type, --symbols, --tags, or --learnings.\n"));
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const success = await updateLoreEntry(rootDir, id, partial);
|
|
46
|
+
if (success) {
|
|
47
|
+
console.log(chalk.green(`
|
|
48
|
+
Updated lore entry: ${id}`));
|
|
49
|
+
for (const [key, value] of Object.entries(partial)) {
|
|
50
|
+
const display = Array.isArray(value) ? value.join(", ") : String(value);
|
|
51
|
+
console.log(chalk.gray(` ${key}: ${display}`));
|
|
52
|
+
}
|
|
53
|
+
console.log();
|
|
54
|
+
} else {
|
|
55
|
+
console.error(chalk.red(`
|
|
56
|
+
Failed to update: ${id}
|
|
57
|
+
`));
|
|
58
|
+
process.exitCode = 1;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
export {
|
|
62
|
+
loreEditCommand
|
|
63
|
+
};
|