@a-company/paradigm 3.17.2 → 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.
- package/dist/chunk-3DYYXGDC.js +403 -0
- package/dist/{chunk-ZRPEI35Q.js → chunk-BKMNLROM.js} +533 -5
- package/dist/{chunk-IWDLTLZH.js → chunk-BRILIG7Z.js} +155 -32
- package/dist/{chunk-D4VBBKGV.js → chunk-EZ6XW6FB.js} +150 -409
- package/dist/{delete-KBKPTIMU.js → delete-YTASL4SM.js} +3 -3
- package/dist/{dist-YHDSIZQD.js → dist-IKBGY7FQ.js} +3 -1
- package/dist/{edit-Y6SKWVHI.js → edit-S7NZD7H7.js} +1 -1
- package/dist/index.js +18 -10
- package/dist/{list-SLAH7X7N.js → list-CAL7KS7B.js} +3 -3
- package/dist/lore-loader-S5BXMH27.js +21 -0
- package/dist/{lore-server-WFU4H5DI.js → lore-server-2NYDLGCJ.js} +102 -17
- package/dist/mcp.js +503 -147
- package/dist/migrate-assessments-FPR6C35Z.js +97 -0
- package/dist/{record-PLZ2OQAN.js → record-UGN75GTB.js} +10 -7
- package/dist/{reindex-T4N3NG73.js → reindex-CMZARW5K.js} +2 -1
- package/dist/retag-URLJLMSK.js +62 -0
- package/dist/{review-Z4Z37PD5.js → review-725ZKA7U.js} +1 -1
- package/dist/{serve-BU43NO7D.js → serve-GUJ3L3IG.js} +1 -1
- package/dist/{show-WGDIK56Q.js → show-GEVVQWWG.js} +54 -5
- package/dist/{timeline-X3CZM7MW.js → timeline-B6TMGWRU.js} +9 -8
- package/dist/university-content/courses/para-501.json +30 -30
- package/dist/university-content/plsat/v3.0.json +26 -26
- package/lore-ui/dist/assets/{index-CB4RregB.js → index-CDr7Tr1E.js} +10 -10
- package/lore-ui/dist/index.html +1 -1
- package/package.json +1 -1
- package/dist/assessment-loader-C5EOUM47.js +0 -23
- package/dist/chunk-DSXS42FY.js +0 -283
package/dist/mcp.js
CHANGED
|
@@ -7,16 +7,6 @@ import {
|
|
|
7
7
|
shelveTask,
|
|
8
8
|
updateTask
|
|
9
9
|
} from "./chunk-CSD7IHSN.js";
|
|
10
|
-
import {
|
|
11
|
-
closeArc,
|
|
12
|
-
createArc,
|
|
13
|
-
loadArc,
|
|
14
|
-
loadArcs,
|
|
15
|
-
loadEntries,
|
|
16
|
-
loadEntry,
|
|
17
|
-
recordEntry,
|
|
18
|
-
searchEntries
|
|
19
|
-
} from "./chunk-DSXS42FY.js";
|
|
20
10
|
import {
|
|
21
11
|
PatternMatcher,
|
|
22
12
|
PatternSuggester,
|
|
@@ -24,7 +14,7 @@ import {
|
|
|
24
14
|
StatsCalculator,
|
|
25
15
|
TimelineBuilder,
|
|
26
16
|
loadAllSeedPatterns
|
|
27
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-BKMNLROM.js";
|
|
28
18
|
import {
|
|
29
19
|
addStep,
|
|
30
20
|
addToolBreadcrumb,
|
|
@@ -34,7 +24,6 @@ import {
|
|
|
34
24
|
checkDrift,
|
|
35
25
|
closeAspectGraph,
|
|
36
26
|
createPersona,
|
|
37
|
-
deleteLoreEntry,
|
|
38
27
|
deletePersona,
|
|
39
28
|
detectProtocolSuggestion,
|
|
40
29
|
findPurposeFiles,
|
|
@@ -62,9 +51,6 @@ import {
|
|
|
62
51
|
loadGlobalAntipatterns,
|
|
63
52
|
loadGlobalDecisions,
|
|
64
53
|
loadGlobalPreferences,
|
|
65
|
-
loadLoreEntries,
|
|
66
|
-
loadLoreEntry,
|
|
67
|
-
loadLoreTimeline,
|
|
68
54
|
loadPersona,
|
|
69
55
|
loadPersonas,
|
|
70
56
|
loadProtocol,
|
|
@@ -76,7 +62,6 @@ import {
|
|
|
76
62
|
rebuildStaticFiles,
|
|
77
63
|
recordGlobalAntipattern,
|
|
78
64
|
recordGlobalDecision,
|
|
79
|
-
recordLoreEntry,
|
|
80
65
|
recordProtocol,
|
|
81
66
|
removeStep,
|
|
82
67
|
searchProtocols,
|
|
@@ -85,14 +70,21 @@ import {
|
|
|
85
70
|
toolCache,
|
|
86
71
|
trackResourceRead,
|
|
87
72
|
trackToolCall,
|
|
88
|
-
updateLoreEntry,
|
|
89
73
|
updatePersona,
|
|
90
74
|
updateProtocol,
|
|
91
75
|
validateAgainstSentinel,
|
|
92
76
|
validatePersona,
|
|
93
77
|
validateProtocol,
|
|
94
78
|
validatePurposeFile
|
|
95
|
-
} from "./chunk-
|
|
79
|
+
} from "./chunk-EZ6XW6FB.js";
|
|
80
|
+
import {
|
|
81
|
+
deleteLoreEntry,
|
|
82
|
+
loadLoreEntries,
|
|
83
|
+
loadLoreEntry,
|
|
84
|
+
loadLoreTimeline,
|
|
85
|
+
recordLoreEntry,
|
|
86
|
+
updateLoreEntry
|
|
87
|
+
} from "./chunk-3DYYXGDC.js";
|
|
96
88
|
import {
|
|
97
89
|
getPluginUpdateNotice,
|
|
98
90
|
schedulePluginUpdateCheck
|
|
@@ -2033,8 +2025,8 @@ function registerResources(server, getContext2) {
|
|
|
2033
2025
|
}
|
|
2034
2026
|
|
|
2035
2027
|
// ../paradigm-mcp/src/tools/index.ts
|
|
2036
|
-
import * as
|
|
2037
|
-
import * as
|
|
2028
|
+
import * as os3 from "os";
|
|
2029
|
+
import * as path25 from "path";
|
|
2038
2030
|
import {
|
|
2039
2031
|
ListToolsRequestSchema,
|
|
2040
2032
|
CallToolRequestSchema
|
|
@@ -2798,7 +2790,7 @@ function navigateExplore(config, target, rootDir) {
|
|
|
2798
2790
|
}
|
|
2799
2791
|
if (result.paths.length === 0) {
|
|
2800
2792
|
const areaSymbols = Object.entries(config.symbols).filter(
|
|
2801
|
-
([sym,
|
|
2793
|
+
([sym, path26]) => sym.toLowerCase().includes(targetLower) || path26.toLowerCase().includes(targetLower)
|
|
2802
2794
|
).slice(0, 10);
|
|
2803
2795
|
result.paths = [...new Set(areaSymbols.map(([, p]) => p))];
|
|
2804
2796
|
result.symbols = areaSymbols.map(([s]) => s);
|
|
@@ -8215,6 +8207,26 @@ function runPostflightCheck(filesModified, symbolsTouched, ctx) {
|
|
|
8215
8207
|
}
|
|
8216
8208
|
|
|
8217
8209
|
// ../paradigm-mcp/src/tools/lore.ts
|
|
8210
|
+
import { execSync as execSync2 } from "child_process";
|
|
8211
|
+
import * as os from "os";
|
|
8212
|
+
function resolveAuthorForMcp() {
|
|
8213
|
+
const envAuthor = process.env.PARADIGM_AUTHOR;
|
|
8214
|
+
if (envAuthor) return sanitize(envAuthor);
|
|
8215
|
+
try {
|
|
8216
|
+
const gitName = execSync2("git config user.name", { encoding: "utf-8", timeout: 3e3 }).trim();
|
|
8217
|
+
if (gitName) return sanitize(gitName);
|
|
8218
|
+
} catch {
|
|
8219
|
+
}
|
|
8220
|
+
try {
|
|
8221
|
+
const username = os.userInfo().username;
|
|
8222
|
+
if (username) return sanitize(username);
|
|
8223
|
+
} catch {
|
|
8224
|
+
}
|
|
8225
|
+
return "unknown";
|
|
8226
|
+
}
|
|
8227
|
+
function sanitize(name) {
|
|
8228
|
+
return name.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 20) || "unknown";
|
|
8229
|
+
}
|
|
8218
8230
|
function getLoreToolsList() {
|
|
8219
8231
|
return [
|
|
8220
8232
|
{
|
|
@@ -8229,18 +8241,30 @@ function getLoreToolsList() {
|
|
|
8229
8241
|
},
|
|
8230
8242
|
author: {
|
|
8231
8243
|
type: "string",
|
|
8232
|
-
description: 'Filter by author
|
|
8244
|
+
description: 'Filter by author (human user name, e.g., "ascend")'
|
|
8245
|
+
},
|
|
8246
|
+
hasAgent: {
|
|
8247
|
+
type: "boolean",
|
|
8248
|
+
description: "Filter by AI assistance: true = AI-assisted entries, false = human-only"
|
|
8233
8249
|
},
|
|
8234
8250
|
authorType: {
|
|
8235
8251
|
type: "string",
|
|
8236
8252
|
enum: ["human", "agent"],
|
|
8237
|
-
description: "Filter by author type"
|
|
8253
|
+
description: "(Deprecated, use hasAgent) Filter by old author type"
|
|
8238
8254
|
},
|
|
8239
8255
|
type: {
|
|
8240
8256
|
type: "string",
|
|
8241
|
-
enum: ["agent-session", "human-note", "decision", "review", "incident", "milestone"],
|
|
8257
|
+
enum: ["agent-session", "human-note", "decision", "review", "incident", "milestone", "retro", "insight"],
|
|
8242
8258
|
description: "Filter by entry type"
|
|
8243
8259
|
},
|
|
8260
|
+
tag: {
|
|
8261
|
+
type: "string",
|
|
8262
|
+
description: 'Filter by tag prefix (e.g., "arc:lore-evolution" for arc entries)'
|
|
8263
|
+
},
|
|
8264
|
+
hasBody: {
|
|
8265
|
+
type: "boolean",
|
|
8266
|
+
description: "Filter for entries with/without long-form body content"
|
|
8267
|
+
},
|
|
8244
8268
|
dateFrom: {
|
|
8245
8269
|
type: "string",
|
|
8246
8270
|
description: 'Filter from date (ISO 8601, e.g., "2026-02-20")'
|
|
@@ -8281,7 +8305,7 @@ function getLoreToolsList() {
|
|
|
8281
8305
|
properties: {
|
|
8282
8306
|
type: {
|
|
8283
8307
|
type: "string",
|
|
8284
|
-
enum: ["agent-session", "human-note", "decision", "review", "incident", "milestone"],
|
|
8308
|
+
enum: ["agent-session", "human-note", "decision", "review", "incident", "milestone", "retro", "insight"],
|
|
8285
8309
|
description: "Entry type"
|
|
8286
8310
|
},
|
|
8287
8311
|
title: {
|
|
@@ -8363,9 +8387,32 @@ function getLoreToolsList() {
|
|
|
8363
8387
|
type: "array",
|
|
8364
8388
|
items: { type: "string" },
|
|
8365
8389
|
description: "Tags for categorization"
|
|
8390
|
+
},
|
|
8391
|
+
meta: {
|
|
8392
|
+
type: "object",
|
|
8393
|
+
description: 'Project-defined metadata (open-ended key-value pairs, e.g., { meeting_type: "design-review", sprint: 12 })'
|
|
8394
|
+
},
|
|
8395
|
+
body: {
|
|
8396
|
+
type: "string",
|
|
8397
|
+
description: "Long-form content (detailed retrospective notes, decision rationale, etc.)"
|
|
8398
|
+
},
|
|
8399
|
+
linked_lore: {
|
|
8400
|
+
type: "array",
|
|
8401
|
+
items: { type: "string" },
|
|
8402
|
+
description: "Cross-references to other lore entry IDs"
|
|
8403
|
+
},
|
|
8404
|
+
linked_tasks: {
|
|
8405
|
+
type: "array",
|
|
8406
|
+
items: { type: "string" },
|
|
8407
|
+
description: "References to paradigm task IDs"
|
|
8408
|
+
},
|
|
8409
|
+
linked_commits: {
|
|
8410
|
+
type: "array",
|
|
8411
|
+
items: { type: "string" },
|
|
8412
|
+
description: "Git commit SHAs related to this entry"
|
|
8366
8413
|
}
|
|
8367
8414
|
},
|
|
8368
|
-
required: ["
|
|
8415
|
+
required: ["title", "summary", "symbols_touched"]
|
|
8369
8416
|
},
|
|
8370
8417
|
annotations: {
|
|
8371
8418
|
readOnlyHint: false,
|
|
@@ -8397,7 +8444,7 @@ function getLoreToolsList() {
|
|
|
8397
8444
|
properties: {
|
|
8398
8445
|
id: {
|
|
8399
8446
|
type: "string",
|
|
8400
|
-
description: 'Lore entry ID (e.g., "L-2026-02-23-001")'
|
|
8447
|
+
description: 'Lore entry ID (e.g., "L-2026-02-23-001" or "L-2026-03-02-ascend-143025-001")'
|
|
8401
8448
|
}
|
|
8402
8449
|
},
|
|
8403
8450
|
required: ["id"]
|
|
@@ -8421,7 +8468,7 @@ function getLoreToolsList() {
|
|
|
8421
8468
|
summary: { type: "string", description: "New summary" },
|
|
8422
8469
|
type: {
|
|
8423
8470
|
type: "string",
|
|
8424
|
-
enum: ["agent-session", "human-note", "decision", "review", "incident", "milestone"],
|
|
8471
|
+
enum: ["agent-session", "human-note", "decision", "review", "incident", "milestone", "retro", "insight"],
|
|
8425
8472
|
description: "New entry type"
|
|
8426
8473
|
},
|
|
8427
8474
|
symbols_touched: {
|
|
@@ -8499,11 +8546,14 @@ async function handleLoreTool(name, args, ctx) {
|
|
|
8499
8546
|
case "paradigm_lore_search": {
|
|
8500
8547
|
const filter = {
|
|
8501
8548
|
author: args.author,
|
|
8549
|
+
hasAgent: args.hasAgent,
|
|
8502
8550
|
authorType: args.authorType,
|
|
8503
8551
|
symbol: args.symbol,
|
|
8504
8552
|
dateFrom: args.dateFrom,
|
|
8505
8553
|
dateTo: args.dateTo,
|
|
8506
8554
|
type: args.type,
|
|
8555
|
+
tag: args.tag,
|
|
8556
|
+
hasBody: args.hasBody,
|
|
8507
8557
|
tags: args.tags,
|
|
8508
8558
|
hasReview: args.hasReview,
|
|
8509
8559
|
limit: args.limit || 20,
|
|
@@ -8538,7 +8588,12 @@ async function handleLoreTool(name, args, ctx) {
|
|
|
8538
8588
|
errors_encountered,
|
|
8539
8589
|
learnings,
|
|
8540
8590
|
verification,
|
|
8541
|
-
tags
|
|
8591
|
+
tags,
|
|
8592
|
+
meta,
|
|
8593
|
+
body,
|
|
8594
|
+
linked_lore,
|
|
8595
|
+
linked_tasks,
|
|
8596
|
+
linked_commits
|
|
8542
8597
|
} = args;
|
|
8543
8598
|
let habit_compliance;
|
|
8544
8599
|
try {
|
|
@@ -8560,10 +8615,11 @@ async function handleLoreTool(name, args, ctx) {
|
|
|
8560
8615
|
const entry = {
|
|
8561
8616
|
id: "",
|
|
8562
8617
|
// Will be generated
|
|
8563
|
-
type,
|
|
8618
|
+
type: type || "agent-session",
|
|
8564
8619
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8565
8620
|
duration_minutes,
|
|
8566
|
-
author:
|
|
8621
|
+
author: resolveAuthorForMcp(),
|
|
8622
|
+
agent: { provider: "anthropic", model: "claude-opus-4-6" },
|
|
8567
8623
|
title,
|
|
8568
8624
|
summary,
|
|
8569
8625
|
symbols_touched,
|
|
@@ -8578,7 +8634,12 @@ async function handleLoreTool(name, args, ctx) {
|
|
|
8578
8634
|
learnings,
|
|
8579
8635
|
verification,
|
|
8580
8636
|
tags,
|
|
8581
|
-
|
|
8637
|
+
meta: meta || void 0,
|
|
8638
|
+
habit_compliance,
|
|
8639
|
+
body,
|
|
8640
|
+
linked_lore,
|
|
8641
|
+
linked_tasks,
|
|
8642
|
+
linked_commits
|
|
8582
8643
|
};
|
|
8583
8644
|
const id = await recordLoreEntry(ctx.rootDir, entry);
|
|
8584
8645
|
getSessionTracker().setLastLoreEntryId(id);
|
|
@@ -8618,11 +8679,12 @@ async function handleLoreTool(name, args, ctx) {
|
|
|
8618
8679
|
const hotSymbols = Object.entries(symbolCounts).sort(([, a], [, b]) => b - a).slice(0, 10).map(([symbol, count]) => ({ symbol, count }));
|
|
8619
8680
|
const authorActivity = {};
|
|
8620
8681
|
for (const entry of entries) {
|
|
8621
|
-
const aid = entry.author
|
|
8682
|
+
const aid = entry.author;
|
|
8622
8683
|
if (!authorActivity[aid]) {
|
|
8623
|
-
authorActivity[aid] = { count: 0, lastActive: entry.timestamp,
|
|
8684
|
+
authorActivity[aid] = { count: 0, lastActive: entry.timestamp, hasAgent: entry.agent != null };
|
|
8624
8685
|
}
|
|
8625
8686
|
authorActivity[aid].count++;
|
|
8687
|
+
if (entry.agent) authorActivity[aid].hasAgent = true;
|
|
8626
8688
|
if (entry.timestamp > authorActivity[aid].lastActive) {
|
|
8627
8689
|
authorActivity[aid].lastActive = entry.timestamp;
|
|
8628
8690
|
}
|
|
@@ -8635,7 +8697,7 @@ async function handleLoreTool(name, args, ctx) {
|
|
|
8635
8697
|
hotSymbols,
|
|
8636
8698
|
authors: Object.entries(authorActivity).map(([id, info]) => ({
|
|
8637
8699
|
id,
|
|
8638
|
-
|
|
8700
|
+
hasAgent: info.hasAgent,
|
|
8639
8701
|
entries: info.count,
|
|
8640
8702
|
lastActive: info.lastActive
|
|
8641
8703
|
}))
|
|
@@ -8708,6 +8770,7 @@ function summarizeEntry(entry) {
|
|
|
8708
8770
|
title: entry.title,
|
|
8709
8771
|
summary: entry.summary,
|
|
8710
8772
|
author: entry.author,
|
|
8773
|
+
agent: entry.agent,
|
|
8711
8774
|
timestamp: entry.timestamp,
|
|
8712
8775
|
duration_minutes: entry.duration_minutes,
|
|
8713
8776
|
symbols_touched: entry.symbols_touched,
|
|
@@ -8723,7 +8786,7 @@ function summarizeEntry(entry) {
|
|
|
8723
8786
|
// ../paradigm-mcp/src/tools/habits.ts
|
|
8724
8787
|
import * as fs19 from "fs";
|
|
8725
8788
|
import * as path21 from "path";
|
|
8726
|
-
import { execSync as
|
|
8789
|
+
import { execSync as execSync3 } from "child_process";
|
|
8727
8790
|
function getHabitsToolsList() {
|
|
8728
8791
|
return [
|
|
8729
8792
|
{
|
|
@@ -8927,7 +8990,7 @@ async function handleHabitsCheck(args, ctx) {
|
|
|
8927
8990
|
].some((k) => taskLower.includes(k));
|
|
8928
8991
|
let gitClean;
|
|
8929
8992
|
try {
|
|
8930
|
-
const status =
|
|
8993
|
+
const status = execSync3("git status --porcelain", {
|
|
8931
8994
|
cwd: ctx.rootDir,
|
|
8932
8995
|
encoding: "utf8",
|
|
8933
8996
|
timeout: 5e3
|
|
@@ -10191,8 +10254,8 @@ function getTasksToolsList() {
|
|
|
10191
10254
|
priority: { type: "string", enum: ["high", "medium", "low"] },
|
|
10192
10255
|
status: { type: "string", enum: ["open", "done", "shelved"] },
|
|
10193
10256
|
tags: { type: "array", items: { type: "string" }, description: "Replace tags" },
|
|
10194
|
-
related_lore: { type: "array", items: { type: "string" } },
|
|
10195
|
-
related_assessments: { type: "array", items: { type: "string" } }
|
|
10257
|
+
related_lore: { type: "array", items: { type: "string" }, description: "Related lore entry IDs (includes former assessment entries)" },
|
|
10258
|
+
related_assessments: { type: "array", items: { type: "string" }, description: "(Deprecated \u2014 use related_lore) Alias for related_lore" }
|
|
10196
10259
|
},
|
|
10197
10260
|
required: ["id"]
|
|
10198
10261
|
},
|
|
@@ -10282,7 +10345,7 @@ async function handleTasksTool(name, args, ctx) {
|
|
|
10282
10345
|
text: JSON.stringify({
|
|
10283
10346
|
completed: id,
|
|
10284
10347
|
task,
|
|
10285
|
-
hint: "Consider
|
|
10348
|
+
hint: "Consider recording a lore entry with arc:* tags if this was a significant milestone."
|
|
10286
10349
|
}, null, 2)
|
|
10287
10350
|
};
|
|
10288
10351
|
}
|
|
@@ -10300,18 +10363,228 @@ async function handleTasksTool(name, args, ctx) {
|
|
|
10300
10363
|
}
|
|
10301
10364
|
}
|
|
10302
10365
|
|
|
10366
|
+
// ../paradigm-mcp/src/utils/assessment-loader.ts
|
|
10367
|
+
import * as fs21 from "fs";
|
|
10368
|
+
import * as path23 from "path";
|
|
10369
|
+
import * as yaml12 from "js-yaml";
|
|
10370
|
+
var ASSESSMENTS_DIR = ".paradigm/assessments";
|
|
10371
|
+
var ARCS_DIR = "arcs";
|
|
10372
|
+
var INDEX_FILE = "index.yaml";
|
|
10373
|
+
function computeArcStats(rootDir, arc) {
|
|
10374
|
+
const entriesPath = path23.join(rootDir, ASSESSMENTS_DIR, ARCS_DIR, arc.id, "entries");
|
|
10375
|
+
const symbolSet = /* @__PURE__ */ new Set();
|
|
10376
|
+
let entryCount = 0;
|
|
10377
|
+
let latestDate;
|
|
10378
|
+
if (fs21.existsSync(entriesPath)) {
|
|
10379
|
+
const files = fs21.readdirSync(entriesPath).filter((f) => f.endsWith(".yaml"));
|
|
10380
|
+
for (const file of files) {
|
|
10381
|
+
try {
|
|
10382
|
+
const entry = yaml12.load(fs21.readFileSync(path23.join(entriesPath, file), "utf8"));
|
|
10383
|
+
entryCount++;
|
|
10384
|
+
if (entry.symbols) entry.symbols.forEach((s) => symbolSet.add(s));
|
|
10385
|
+
if (!latestDate || entry.date > latestDate) latestDate = entry.date;
|
|
10386
|
+
} catch {
|
|
10387
|
+
}
|
|
10388
|
+
}
|
|
10389
|
+
}
|
|
10390
|
+
return { ...arc, entry_count: entryCount, symbols: Array.from(symbolSet), latest_entry: latestDate };
|
|
10391
|
+
}
|
|
10392
|
+
async function loadArcs(rootDir, status) {
|
|
10393
|
+
const arcsPath = path23.join(rootDir, ASSESSMENTS_DIR, ARCS_DIR);
|
|
10394
|
+
if (!fs21.existsSync(arcsPath)) return [];
|
|
10395
|
+
const arcDirs = fs21.readdirSync(arcsPath).filter((d) => {
|
|
10396
|
+
try {
|
|
10397
|
+
return fs21.statSync(path23.join(arcsPath, d)).isDirectory();
|
|
10398
|
+
} catch {
|
|
10399
|
+
return false;
|
|
10400
|
+
}
|
|
10401
|
+
});
|
|
10402
|
+
const arcs = [];
|
|
10403
|
+
for (const arcDir of arcDirs) {
|
|
10404
|
+
const arcFile = path23.join(arcsPath, arcDir, "arc.yaml");
|
|
10405
|
+
if (!fs21.existsSync(arcFile)) continue;
|
|
10406
|
+
try {
|
|
10407
|
+
const arc = yaml12.load(fs21.readFileSync(arcFile, "utf8"));
|
|
10408
|
+
if (status && status !== "all" && arc.status !== status) continue;
|
|
10409
|
+
arcs.push(computeArcStats(rootDir, arc));
|
|
10410
|
+
} catch {
|
|
10411
|
+
}
|
|
10412
|
+
}
|
|
10413
|
+
arcs.sort((a, b) => {
|
|
10414
|
+
const aDate = a.latest_entry || a.created;
|
|
10415
|
+
const bDate = b.latest_entry || b.created;
|
|
10416
|
+
return bDate.localeCompare(aDate);
|
|
10417
|
+
});
|
|
10418
|
+
return arcs;
|
|
10419
|
+
}
|
|
10420
|
+
async function loadArc(rootDir, arcId) {
|
|
10421
|
+
const arcFile = path23.join(rootDir, ASSESSMENTS_DIR, ARCS_DIR, arcId, "arc.yaml");
|
|
10422
|
+
if (!fs21.existsSync(arcFile)) return null;
|
|
10423
|
+
try {
|
|
10424
|
+
const arc = yaml12.load(fs21.readFileSync(arcFile, "utf8"));
|
|
10425
|
+
return computeArcStats(rootDir, arc);
|
|
10426
|
+
} catch {
|
|
10427
|
+
return null;
|
|
10428
|
+
}
|
|
10429
|
+
}
|
|
10430
|
+
async function closeArc(rootDir, arcId, status) {
|
|
10431
|
+
const arcFile = path23.join(rootDir, ASSESSMENTS_DIR, ARCS_DIR, arcId, "arc.yaml");
|
|
10432
|
+
if (!fs21.existsSync(arcFile)) return false;
|
|
10433
|
+
try {
|
|
10434
|
+
const arc = yaml12.load(fs21.readFileSync(arcFile, "utf8"));
|
|
10435
|
+
arc.status = status;
|
|
10436
|
+
fs21.writeFileSync(arcFile, yaml12.dump(arc, { lineWidth: -1, noRefs: true }));
|
|
10437
|
+
await rebuildAssessmentIndex(rootDir);
|
|
10438
|
+
return true;
|
|
10439
|
+
} catch {
|
|
10440
|
+
return false;
|
|
10441
|
+
}
|
|
10442
|
+
}
|
|
10443
|
+
async function loadEntries(rootDir, arcId) {
|
|
10444
|
+
const entriesPath = path23.join(rootDir, ASSESSMENTS_DIR, ARCS_DIR, arcId, "entries");
|
|
10445
|
+
if (!fs21.existsSync(entriesPath)) return [];
|
|
10446
|
+
const entries = [];
|
|
10447
|
+
const files = fs21.readdirSync(entriesPath).filter((f) => f.endsWith(".yaml")).sort();
|
|
10448
|
+
for (const file of files) {
|
|
10449
|
+
try {
|
|
10450
|
+
const entry = yaml12.load(fs21.readFileSync(path23.join(entriesPath, file), "utf8"));
|
|
10451
|
+
entries.push(entry);
|
|
10452
|
+
} catch {
|
|
10453
|
+
}
|
|
10454
|
+
}
|
|
10455
|
+
entries.sort((a, b) => b.date.localeCompare(a.date));
|
|
10456
|
+
return entries;
|
|
10457
|
+
}
|
|
10458
|
+
async function loadEntry(rootDir, entryId) {
|
|
10459
|
+
const arcsPath = path23.join(rootDir, ASSESSMENTS_DIR, ARCS_DIR);
|
|
10460
|
+
if (!fs21.existsSync(arcsPath)) return null;
|
|
10461
|
+
const arcDirs = fs21.readdirSync(arcsPath).filter((d) => {
|
|
10462
|
+
try {
|
|
10463
|
+
return fs21.statSync(path23.join(arcsPath, d)).isDirectory();
|
|
10464
|
+
} catch {
|
|
10465
|
+
return false;
|
|
10466
|
+
}
|
|
10467
|
+
});
|
|
10468
|
+
for (const arcDir of arcDirs) {
|
|
10469
|
+
const entryFile = path23.join(arcsPath, arcDir, "entries", `${entryId}.yaml`);
|
|
10470
|
+
if (fs21.existsSync(entryFile)) {
|
|
10471
|
+
try {
|
|
10472
|
+
const entry = yaml12.load(fs21.readFileSync(entryFile, "utf8"));
|
|
10473
|
+
const arcFile = path23.join(arcsPath, arcDir, "arc.yaml");
|
|
10474
|
+
const arc = yaml12.load(fs21.readFileSync(arcFile, "utf8"));
|
|
10475
|
+
return { entry, arc };
|
|
10476
|
+
} catch {
|
|
10477
|
+
return null;
|
|
10478
|
+
}
|
|
10479
|
+
}
|
|
10480
|
+
}
|
|
10481
|
+
return null;
|
|
10482
|
+
}
|
|
10483
|
+
async function searchEntries(rootDir, filter) {
|
|
10484
|
+
const arcsPath = path23.join(rootDir, ASSESSMENTS_DIR, ARCS_DIR);
|
|
10485
|
+
if (!fs21.existsSync(arcsPath)) return [];
|
|
10486
|
+
const limit = filter.limit || 20;
|
|
10487
|
+
const results = [];
|
|
10488
|
+
const arcDirs = fs21.readdirSync(arcsPath).filter((d) => {
|
|
10489
|
+
try {
|
|
10490
|
+
return fs21.statSync(path23.join(arcsPath, d)).isDirectory();
|
|
10491
|
+
} catch {
|
|
10492
|
+
return false;
|
|
10493
|
+
}
|
|
10494
|
+
});
|
|
10495
|
+
for (const arcDir of arcDirs) {
|
|
10496
|
+
const entriesPath = path23.join(arcsPath, arcDir, "entries");
|
|
10497
|
+
if (!fs21.existsSync(entriesPath)) continue;
|
|
10498
|
+
const files = fs21.readdirSync(entriesPath).filter((f) => f.endsWith(".yaml"));
|
|
10499
|
+
for (const file of files) {
|
|
10500
|
+
try {
|
|
10501
|
+
const entry = yaml12.load(fs21.readFileSync(path23.join(entriesPath, file), "utf8"));
|
|
10502
|
+
if (filter.symbol && !(entry.symbols || []).includes(filter.symbol)) continue;
|
|
10503
|
+
if (filter.tag && !(entry.tags || []).includes(filter.tag)) continue;
|
|
10504
|
+
if (filter.type && entry.type !== filter.type) continue;
|
|
10505
|
+
if (filter.dateFrom && entry.date < filter.dateFrom) continue;
|
|
10506
|
+
if (filter.dateTo && entry.date > filter.dateTo) continue;
|
|
10507
|
+
results.push(entry);
|
|
10508
|
+
} catch {
|
|
10509
|
+
}
|
|
10510
|
+
}
|
|
10511
|
+
}
|
|
10512
|
+
results.sort((a, b) => b.date.localeCompare(a.date));
|
|
10513
|
+
return results.slice(0, limit);
|
|
10514
|
+
}
|
|
10515
|
+
async function rebuildAssessmentIndex(rootDir) {
|
|
10516
|
+
const arcsPath = path23.join(rootDir, ASSESSMENTS_DIR, ARCS_DIR);
|
|
10517
|
+
const assessmentsPath = path23.join(rootDir, ASSESSMENTS_DIR);
|
|
10518
|
+
let totalArcs = 0, totalEntries = 0, activeArcs = 0;
|
|
10519
|
+
const arcSummaries = [];
|
|
10520
|
+
if (fs21.existsSync(arcsPath)) {
|
|
10521
|
+
const arcDirs = fs21.readdirSync(arcsPath).filter((d) => {
|
|
10522
|
+
try {
|
|
10523
|
+
return fs21.statSync(path23.join(arcsPath, d)).isDirectory();
|
|
10524
|
+
} catch {
|
|
10525
|
+
return false;
|
|
10526
|
+
}
|
|
10527
|
+
});
|
|
10528
|
+
for (const arcDir of arcDirs) {
|
|
10529
|
+
const arcFile = path23.join(arcsPath, arcDir, "arc.yaml");
|
|
10530
|
+
if (!fs21.existsSync(arcFile)) continue;
|
|
10531
|
+
try {
|
|
10532
|
+
const arc = yaml12.load(fs21.readFileSync(arcFile, "utf8"));
|
|
10533
|
+
const entriesPath = path23.join(arcsPath, arcDir, "entries");
|
|
10534
|
+
const entryCount = fs21.existsSync(entriesPath) ? fs21.readdirSync(entriesPath).filter((f) => f.endsWith(".yaml")).length : 0;
|
|
10535
|
+
totalArcs++;
|
|
10536
|
+
totalEntries += entryCount;
|
|
10537
|
+
if (arc.status === "active") activeArcs++;
|
|
10538
|
+
arcSummaries.push({ id: arc.id, name: arc.name, status: arc.status, entries: entryCount });
|
|
10539
|
+
} catch {
|
|
10540
|
+
}
|
|
10541
|
+
}
|
|
10542
|
+
}
|
|
10543
|
+
const index = {
|
|
10544
|
+
version: "1.0",
|
|
10545
|
+
total_arcs: totalArcs,
|
|
10546
|
+
total_entries: totalEntries,
|
|
10547
|
+
active_arcs: activeArcs,
|
|
10548
|
+
last_updated: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10549
|
+
arcs: arcSummaries
|
|
10550
|
+
};
|
|
10551
|
+
fs21.mkdirSync(assessmentsPath, { recursive: true });
|
|
10552
|
+
fs21.writeFileSync(path23.join(assessmentsPath, INDEX_FILE), yaml12.dump(index, { lineWidth: -1, noRefs: true }));
|
|
10553
|
+
return index;
|
|
10554
|
+
}
|
|
10555
|
+
|
|
10303
10556
|
// ../paradigm-mcp/src/tools/assessment.ts
|
|
10557
|
+
import { execSync as execSync4 } from "child_process";
|
|
10558
|
+
import * as os2 from "os";
|
|
10559
|
+
function resolveAuthor() {
|
|
10560
|
+
const envAuthor = process.env.PARADIGM_AUTHOR;
|
|
10561
|
+
if (envAuthor) return sanitize2(envAuthor);
|
|
10562
|
+
try {
|
|
10563
|
+
const gitName = execSync4("git config user.name", { encoding: "utf-8", timeout: 3e3 }).trim();
|
|
10564
|
+
if (gitName) return sanitize2(gitName);
|
|
10565
|
+
} catch {
|
|
10566
|
+
}
|
|
10567
|
+
try {
|
|
10568
|
+
const username = os2.userInfo().username;
|
|
10569
|
+
if (username) return sanitize2(username);
|
|
10570
|
+
} catch {
|
|
10571
|
+
}
|
|
10572
|
+
return "unknown";
|
|
10573
|
+
}
|
|
10574
|
+
function sanitize2(name) {
|
|
10575
|
+
return name.toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 20) || "unknown";
|
|
10576
|
+
}
|
|
10304
10577
|
function getAssessmentToolsList() {
|
|
10305
10578
|
return [
|
|
10306
10579
|
{
|
|
10307
10580
|
name: "paradigm_assessment_record",
|
|
10308
|
-
description: "
|
|
10581
|
+
description: "[DEPRECATED \u2014 use paradigm_lore_record with arc:* tags] Add a reflection entry. Forwards to lore with arc:{arc_id} and assessment:{type} tags. ~150 tokens.",
|
|
10309
10582
|
inputSchema: {
|
|
10310
10583
|
type: "object",
|
|
10311
10584
|
properties: {
|
|
10312
|
-
arc_id: { type: "string", description:
|
|
10313
|
-
arc_name: { type: "string", description: "Human-readable arc name (
|
|
10314
|
-
arc_description: { type: "string", description: "Arc description (
|
|
10585
|
+
arc_id: { type: "string", description: "Arc ID (becomes arc:{id} tag on the lore entry)" },
|
|
10586
|
+
arc_name: { type: "string", description: "Human-readable arc name (ignored \u2014 arcs are now just tags)" },
|
|
10587
|
+
arc_description: { type: "string", description: "Arc description (ignored \u2014 arcs are now just tags)" },
|
|
10315
10588
|
title: { type: "string", description: "Entry title" },
|
|
10316
10589
|
summary: { type: "string", description: "Short summary (1-2 sentences)" },
|
|
10317
10590
|
body: { type: "string", description: "Full reflection \u2014 what happened, what was learned, what changed" },
|
|
@@ -10319,7 +10592,7 @@ function getAssessmentToolsList() {
|
|
|
10319
10592
|
tags: { type: "array", items: { type: "string" } },
|
|
10320
10593
|
type: { type: "string", enum: ["retro", "insight", "decision", "milestone"], description: "Entry type (default: retro)" },
|
|
10321
10594
|
linked_lore: { type: "array", items: { type: "string" }, description: "Lore entry IDs" },
|
|
10322
|
-
linked_tasks: { type: "array", items: { type: "string" }, description: "Task IDs
|
|
10595
|
+
linked_tasks: { type: "array", items: { type: "string" }, description: "Task IDs" },
|
|
10323
10596
|
linked_commits: { type: "array", items: { type: "string" }, description: "Commit hashes" }
|
|
10324
10597
|
},
|
|
10325
10598
|
required: ["arc_id", "title", "summary"]
|
|
@@ -10328,7 +10601,7 @@ function getAssessmentToolsList() {
|
|
|
10328
10601
|
},
|
|
10329
10602
|
{
|
|
10330
10603
|
name: "paradigm_assessment_list",
|
|
10331
|
-
description: "List assessment arcs
|
|
10604
|
+
description: '[DEPRECATED \u2014 use paradigm_lore_search with tag:"arc:{id}"] List assessment arcs or entries within a specific arc. ~200 tokens.',
|
|
10332
10605
|
inputSchema: {
|
|
10333
10606
|
type: "object",
|
|
10334
10607
|
properties: {
|
|
@@ -10341,7 +10614,7 @@ function getAssessmentToolsList() {
|
|
|
10341
10614
|
},
|
|
10342
10615
|
{
|
|
10343
10616
|
name: "paradigm_assessment_get",
|
|
10344
|
-
description: "Get a specific assessment entry or arc detail.
|
|
10617
|
+
description: "[DEPRECATED \u2014 use paradigm_lore_get] Get a specific assessment entry or arc detail. ~200 tokens.",
|
|
10345
10618
|
inputSchema: {
|
|
10346
10619
|
type: "object",
|
|
10347
10620
|
properties: {
|
|
@@ -10353,7 +10626,7 @@ function getAssessmentToolsList() {
|
|
|
10353
10626
|
},
|
|
10354
10627
|
{
|
|
10355
10628
|
name: "paradigm_assessment_search",
|
|
10356
|
-
description: "Search across
|
|
10629
|
+
description: "[DEPRECATED \u2014 use paradigm_lore_search with tag/type filters] Search across assessment entries by symbol, tag, type, or date. ~200 tokens.",
|
|
10357
10630
|
inputSchema: {
|
|
10358
10631
|
type: "object",
|
|
10359
10632
|
properties: {
|
|
@@ -10369,13 +10642,13 @@ function getAssessmentToolsList() {
|
|
|
10369
10642
|
},
|
|
10370
10643
|
{
|
|
10371
10644
|
name: "paradigm_assessment_arc_create",
|
|
10372
|
-
description: "
|
|
10645
|
+
description: "[DEPRECATED \u2014 arcs are now tag prefixes] No-op. Arcs are just arc:* tags on lore entries. No explicit creation needed. ~100 tokens.",
|
|
10373
10646
|
inputSchema: {
|
|
10374
10647
|
type: "object",
|
|
10375
10648
|
properties: {
|
|
10376
|
-
id: { type: "string", description:
|
|
10377
|
-
name: { type: "string", description: "
|
|
10378
|
-
description: { type: "string", description: "
|
|
10649
|
+
id: { type: "string", description: "Arc ID (no longer needed \u2014 just use arc:{id} tag on lore entries)" },
|
|
10650
|
+
name: { type: "string", description: "Arc name (ignored)" },
|
|
10651
|
+
description: { type: "string", description: "Arc description (ignored)" },
|
|
10379
10652
|
tags: { type: "array", items: { type: "string" } }
|
|
10380
10653
|
},
|
|
10381
10654
|
required: ["id", "name"]
|
|
@@ -10384,7 +10657,7 @@ function getAssessmentToolsList() {
|
|
|
10384
10657
|
},
|
|
10385
10658
|
{
|
|
10386
10659
|
name: "paradigm_assessment_arc_close",
|
|
10387
|
-
description: "
|
|
10660
|
+
description: "[DEPRECATED \u2014 use paradigm_lore_search + paradigm_lore_update] Adds arc-closed tag to all entries in the arc. ~100 tokens.",
|
|
10388
10661
|
inputSchema: {
|
|
10389
10662
|
type: "object",
|
|
10390
10663
|
properties: {
|
|
@@ -10400,27 +10673,38 @@ function getAssessmentToolsList() {
|
|
|
10400
10673
|
async function handleAssessmentTool(name, args, ctx) {
|
|
10401
10674
|
switch (name) {
|
|
10402
10675
|
case "paradigm_assessment_record": {
|
|
10676
|
+
const arcId = args.arc_id;
|
|
10677
|
+
const entryType = args.type || "retro";
|
|
10678
|
+
const userTags = args.tags || [];
|
|
10679
|
+
const tags = [
|
|
10680
|
+
`arc:${arcId}`,
|
|
10681
|
+
`assessment:${entryType}`,
|
|
10682
|
+
...userTags
|
|
10683
|
+
];
|
|
10684
|
+
const entry = {
|
|
10685
|
+
id: "",
|
|
10686
|
+
type: entryType,
|
|
10687
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10688
|
+
author: resolveAuthor(),
|
|
10689
|
+
agent: { provider: "anthropic", model: "claude-opus-4-6" },
|
|
10690
|
+
title: args.title,
|
|
10691
|
+
summary: args.summary,
|
|
10692
|
+
body: args.body,
|
|
10693
|
+
symbols_touched: args.symbols || [],
|
|
10694
|
+
tags,
|
|
10695
|
+
linked_lore: args.linked_lore,
|
|
10696
|
+
linked_tasks: args.linked_tasks,
|
|
10697
|
+
linked_commits: args.linked_commits
|
|
10698
|
+
};
|
|
10403
10699
|
try {
|
|
10404
|
-
const id = await
|
|
10405
|
-
ctx.rootDir,
|
|
10406
|
-
{
|
|
10407
|
-
arc_id: args.arc_id,
|
|
10408
|
-
title: args.title,
|
|
10409
|
-
summary: args.summary,
|
|
10410
|
-
body: args.body,
|
|
10411
|
-
symbols: args.symbols,
|
|
10412
|
-
tags: args.tags,
|
|
10413
|
-
type: args.type,
|
|
10414
|
-
linked_lore: args.linked_lore,
|
|
10415
|
-
linked_tasks: args.linked_tasks,
|
|
10416
|
-
linked_commits: args.linked_commits
|
|
10417
|
-
},
|
|
10418
|
-
args.arc_name,
|
|
10419
|
-
args.arc_description
|
|
10420
|
-
);
|
|
10700
|
+
const id = await recordLoreEntry(ctx.rootDir, entry);
|
|
10421
10701
|
return {
|
|
10422
10702
|
handled: true,
|
|
10423
|
-
text: JSON.stringify({
|
|
10703
|
+
text: JSON.stringify({
|
|
10704
|
+
recorded: id,
|
|
10705
|
+
arc_id: arcId,
|
|
10706
|
+
deprecated: 'Use paradigm_lore_record with tags: ["arc:' + arcId + '"] instead'
|
|
10707
|
+
}, null, 2)
|
|
10424
10708
|
};
|
|
10425
10709
|
} catch (err2) {
|
|
10426
10710
|
return {
|
|
@@ -10432,88 +10716,160 @@ async function handleAssessmentTool(name, args, ctx) {
|
|
|
10432
10716
|
case "paradigm_assessment_list": {
|
|
10433
10717
|
const arcId = args.arc_id;
|
|
10434
10718
|
if (arcId) {
|
|
10435
|
-
const entries = await
|
|
10436
|
-
|
|
10437
|
-
|
|
10438
|
-
|
|
10439
|
-
const
|
|
10440
|
-
for (const e of
|
|
10441
|
-
|
|
10442
|
-
}
|
|
10443
|
-
|
|
10444
|
-
|
|
10445
|
-
|
|
10446
|
-
|
|
10447
|
-
|
|
10448
|
-
|
|
10449
|
-
|
|
10450
|
-
const
|
|
10451
|
-
|
|
10719
|
+
const entries = await loadLoreEntries(ctx.rootDir, {
|
|
10720
|
+
tag: `arc:${arcId}`,
|
|
10721
|
+
limit: args.limit || 20
|
|
10722
|
+
});
|
|
10723
|
+
const lines = [`${entries.length} entries with arc:${arcId} tag:`];
|
|
10724
|
+
for (const e of entries) {
|
|
10725
|
+
lines.push(` [${e.type || "unknown"}] ${e.id}: ${e.title} (${e.timestamp.slice(0, 10)})`);
|
|
10726
|
+
}
|
|
10727
|
+
lines.push("", 'Deprecated: Use paradigm_lore_search with tag: "arc:' + arcId + '"');
|
|
10728
|
+
return { handled: true, text: lines.join("\n") };
|
|
10729
|
+
}
|
|
10730
|
+
try {
|
|
10731
|
+
const status = args.status || "active";
|
|
10732
|
+
const arcs = await loadArcs(ctx.rootDir, status);
|
|
10733
|
+
const limited = arcs.slice(0, args.limit || 20);
|
|
10734
|
+
const lines = [`${limited.length} ${status} arc(s):`];
|
|
10735
|
+
for (const a of limited) {
|
|
10736
|
+
const symbols = a.symbols.length > 0 ? ` [${a.symbols.slice(0, 3).join(", ")}]` : "";
|
|
10737
|
+
lines.push(` ${a.id}: ${a.name} (${a.entry_count} entries)${symbols}`);
|
|
10738
|
+
}
|
|
10739
|
+
lines.push("", 'Deprecated: Run "paradigm lore migrate-assessments" then use paradigm_lore_search');
|
|
10740
|
+
return { handled: true, text: lines.join("\n") };
|
|
10741
|
+
} catch {
|
|
10742
|
+
return { handled: true, text: "No assessment arcs found. Assessments are now unified with lore." };
|
|
10452
10743
|
}
|
|
10453
|
-
return { handled: true, text: lines.join("\n") };
|
|
10454
10744
|
}
|
|
10455
10745
|
case "paradigm_assessment_get": {
|
|
10456
10746
|
const id = args.id;
|
|
10747
|
+
if (id.startsWith("L-")) {
|
|
10748
|
+
const entry = await loadLoreEntry(ctx.rootDir, id);
|
|
10749
|
+
if (entry) {
|
|
10750
|
+
return {
|
|
10751
|
+
handled: true,
|
|
10752
|
+
text: JSON.stringify({
|
|
10753
|
+
entry,
|
|
10754
|
+
deprecated: "Use paradigm_lore_get instead"
|
|
10755
|
+
}, null, 2)
|
|
10756
|
+
};
|
|
10757
|
+
}
|
|
10758
|
+
}
|
|
10457
10759
|
if (id.startsWith("arc-")) {
|
|
10458
|
-
|
|
10459
|
-
|
|
10760
|
+
try {
|
|
10761
|
+
const arc = await loadArc(ctx.rootDir, id);
|
|
10762
|
+
if (!arc) {
|
|
10763
|
+
return { handled: true, text: JSON.stringify({ error: `Arc ${id} not found` }) };
|
|
10764
|
+
}
|
|
10765
|
+
const entries = await loadEntries(ctx.rootDir, id);
|
|
10766
|
+
return {
|
|
10767
|
+
handled: true,
|
|
10768
|
+
text: JSON.stringify({
|
|
10769
|
+
arc,
|
|
10770
|
+
entries: entries.map((e) => ({ id: e.id, type: e.type, title: e.title, date: e.date.slice(0, 10), summary: e.summary })),
|
|
10771
|
+
deprecated: 'Run "paradigm lore migrate-assessments" then use paradigm_lore_search with tag: "arc:' + id + '"'
|
|
10772
|
+
}, null, 2)
|
|
10773
|
+
};
|
|
10774
|
+
} catch {
|
|
10460
10775
|
return { handled: true, text: JSON.stringify({ error: `Arc ${id} not found` }) };
|
|
10461
10776
|
}
|
|
10462
|
-
|
|
10777
|
+
}
|
|
10778
|
+
try {
|
|
10779
|
+
const result = await loadEntry(ctx.rootDir, id);
|
|
10780
|
+
if (!result) {
|
|
10781
|
+
return { handled: true, text: JSON.stringify({ error: `Entry ${id} not found` }) };
|
|
10782
|
+
}
|
|
10463
10783
|
return {
|
|
10464
10784
|
handled: true,
|
|
10465
10785
|
text: JSON.stringify({
|
|
10466
|
-
|
|
10467
|
-
|
|
10786
|
+
entry: result.entry,
|
|
10787
|
+
arc: { id: result.arc.id, name: result.arc.name, status: result.arc.status },
|
|
10788
|
+
deprecated: 'Run "paradigm lore migrate-assessments" then use paradigm_lore_get'
|
|
10468
10789
|
}, null, 2)
|
|
10469
10790
|
};
|
|
10470
|
-
}
|
|
10471
|
-
const result = await loadEntry(ctx.rootDir, id);
|
|
10472
|
-
if (!result) {
|
|
10791
|
+
} catch {
|
|
10473
10792
|
return { handled: true, text: JSON.stringify({ error: `Entry ${id} not found` }) };
|
|
10474
10793
|
}
|
|
10475
|
-
return {
|
|
10476
|
-
handled: true,
|
|
10477
|
-
text: JSON.stringify({ entry: result.entry, arc: { id: result.arc.id, name: result.arc.name, status: result.arc.status } }, null, 2)
|
|
10478
|
-
};
|
|
10479
10794
|
}
|
|
10480
10795
|
case "paradigm_assessment_search": {
|
|
10481
|
-
const
|
|
10482
|
-
symbol: args.symbol,
|
|
10483
|
-
tag: args.tag,
|
|
10484
|
-
type: args.type,
|
|
10485
|
-
dateFrom: args.dateFrom,
|
|
10486
|
-
dateTo: args.dateTo,
|
|
10796
|
+
const filter = {
|
|
10487
10797
|
limit: args.limit || 20
|
|
10488
|
-
}
|
|
10489
|
-
|
|
10490
|
-
|
|
10491
|
-
|
|
10492
|
-
|
|
10798
|
+
};
|
|
10799
|
+
if (args.symbol) filter.symbol = args.symbol;
|
|
10800
|
+
if (args.tag) filter.tag = args.tag;
|
|
10801
|
+
if (args.type) filter.tag = `assessment:${args.type}`;
|
|
10802
|
+
if (args.dateFrom) filter.dateFrom = args.dateFrom;
|
|
10803
|
+
if (args.dateTo) filter.dateTo = args.dateTo;
|
|
10804
|
+
const loreEntries = await loadLoreEntries(ctx.rootDir, filter);
|
|
10805
|
+
const arcEntries = loreEntries.filter((e) => e.tags?.some((t) => t.startsWith("arc:")));
|
|
10806
|
+
if (arcEntries.length > 0) {
|
|
10807
|
+
const lines = [`${arcEntries.length} matching lore entries (with arc tags):`];
|
|
10808
|
+
for (const e of arcEntries) {
|
|
10809
|
+
const arcTag = e.tags?.find((t) => t.startsWith("arc:")) || "";
|
|
10810
|
+
const symbols = (e.symbols_touched || []).slice(0, 3).join(", ");
|
|
10811
|
+
lines.push(` [${e.type || "unknown"}] ${e.id} (${arcTag}): ${e.title} \u2014 ${symbols}`);
|
|
10812
|
+
}
|
|
10813
|
+
lines.push("", "Deprecated: Use paradigm_lore_search with tag filter");
|
|
10814
|
+
return { handled: true, text: lines.join("\n") };
|
|
10493
10815
|
}
|
|
10494
|
-
return { handled: true, text: lines.join("\n") };
|
|
10495
|
-
}
|
|
10496
|
-
case "paradigm_assessment_arc_create": {
|
|
10497
10816
|
try {
|
|
10498
|
-
const
|
|
10499
|
-
|
|
10500
|
-
|
|
10501
|
-
|
|
10502
|
-
|
|
10817
|
+
const entries = await searchEntries(ctx.rootDir, {
|
|
10818
|
+
symbol: args.symbol,
|
|
10819
|
+
tag: args.tag,
|
|
10820
|
+
type: args.type,
|
|
10821
|
+
dateFrom: args.dateFrom,
|
|
10822
|
+
dateTo: args.dateTo,
|
|
10823
|
+
limit: args.limit || 20
|
|
10503
10824
|
});
|
|
10504
|
-
|
|
10505
|
-
|
|
10506
|
-
|
|
10825
|
+
const lines = [`${entries.length} matching entries:`];
|
|
10826
|
+
for (const e of entries) {
|
|
10827
|
+
const symbols = (e.symbols || []).slice(0, 3).join(", ");
|
|
10828
|
+
lines.push(` [${e.type}] ${e.id} (${e.arc_id}): ${e.title} \u2014 ${symbols}`);
|
|
10829
|
+
}
|
|
10830
|
+
lines.push("", 'Deprecated: Run "paradigm lore migrate-assessments" then use paradigm_lore_search');
|
|
10831
|
+
return { handled: true, text: lines.join("\n") };
|
|
10832
|
+
} catch {
|
|
10833
|
+
return { handled: true, text: "0 matching entries." };
|
|
10507
10834
|
}
|
|
10508
10835
|
}
|
|
10836
|
+
case "paradigm_assessment_arc_create": {
|
|
10837
|
+
return {
|
|
10838
|
+
handled: true,
|
|
10839
|
+
text: JSON.stringify({
|
|
10840
|
+
message: "Arcs are now tag prefixes on lore entries. No explicit creation needed.",
|
|
10841
|
+
guidance: `To create entries in this arc, use paradigm_lore_record with tags: ["arc:${args.id}"]`,
|
|
10842
|
+
deprecated: true
|
|
10843
|
+
}, null, 2)
|
|
10844
|
+
};
|
|
10845
|
+
}
|
|
10509
10846
|
case "paradigm_assessment_arc_close": {
|
|
10510
10847
|
const arcId = args.arc_id;
|
|
10511
10848
|
const status = args.status || "complete";
|
|
10512
|
-
const
|
|
10513
|
-
|
|
10514
|
-
|
|
10849
|
+
const entries = await loadLoreEntries(ctx.rootDir, { tag: `arc:${arcId}` });
|
|
10850
|
+
let updated = 0;
|
|
10851
|
+
for (const entry of entries) {
|
|
10852
|
+
const currentTags = entry.tags || [];
|
|
10853
|
+
if (!currentTags.includes("arc-closed")) {
|
|
10854
|
+
await updateLoreEntry(ctx.rootDir, entry.id, {
|
|
10855
|
+
tags: [...currentTags, "arc-closed", `arc-status:${status}`]
|
|
10856
|
+
});
|
|
10857
|
+
updated++;
|
|
10858
|
+
}
|
|
10515
10859
|
}
|
|
10516
|
-
|
|
10860
|
+
try {
|
|
10861
|
+
await closeArc(ctx.rootDir, arcId, status);
|
|
10862
|
+
} catch {
|
|
10863
|
+
}
|
|
10864
|
+
return {
|
|
10865
|
+
handled: true,
|
|
10866
|
+
text: JSON.stringify({
|
|
10867
|
+
closed: arcId,
|
|
10868
|
+
status,
|
|
10869
|
+
lore_entries_tagged: updated,
|
|
10870
|
+
deprecated: "Use paradigm_lore_search + paradigm_lore_update to manage arc lifecycle via tags"
|
|
10871
|
+
}, null, 2)
|
|
10872
|
+
};
|
|
10517
10873
|
}
|
|
10518
10874
|
default:
|
|
10519
10875
|
return { handled: false, text: "" };
|
|
@@ -10530,8 +10886,8 @@ function generateRunId() {
|
|
|
10530
10886
|
var TEMPLATE_REGEX = /\{\{([^}]+)\}\}/g;
|
|
10531
10887
|
function interpolate(value, scope) {
|
|
10532
10888
|
if (typeof value === "string") {
|
|
10533
|
-
return value.replace(TEMPLATE_REGEX, (_match,
|
|
10534
|
-
const resolved = resolvePath(
|
|
10889
|
+
return value.replace(TEMPLATE_REGEX, (_match, path26) => {
|
|
10890
|
+
const resolved = resolvePath(path26.trim(), scope);
|
|
10535
10891
|
return resolved !== void 0 ? String(resolved) : _match;
|
|
10536
10892
|
});
|
|
10537
10893
|
}
|
|
@@ -10564,8 +10920,8 @@ function resolvePath(dotPath, scope) {
|
|
|
10564
10920
|
return void 0;
|
|
10565
10921
|
}
|
|
10566
10922
|
}
|
|
10567
|
-
function deepGet(obj,
|
|
10568
|
-
const parts =
|
|
10923
|
+
function deepGet(obj, path26) {
|
|
10924
|
+
const parts = path26.split(/[.\[\]]+/).filter(Boolean);
|
|
10569
10925
|
let current = obj;
|
|
10570
10926
|
for (const part of parts) {
|
|
10571
10927
|
if (current == null || typeof current !== "object") return void 0;
|
|
@@ -10801,11 +11157,11 @@ async function runPersonaObject(rootDir, persona, options) {
|
|
|
10801
11157
|
}
|
|
10802
11158
|
async function runChain(rootDir, chainId, options) {
|
|
10803
11159
|
const start = Date.now();
|
|
10804
|
-
const
|
|
10805
|
-
const
|
|
10806
|
-
const
|
|
10807
|
-
const chainPath =
|
|
10808
|
-
if (!
|
|
11160
|
+
const fs22 = await import("fs");
|
|
11161
|
+
const path26 = await import("path");
|
|
11162
|
+
const yaml13 = await import("js-yaml");
|
|
11163
|
+
const chainPath = path26.join(rootDir, ".paradigm", "personas", "chains", `${chainId}.yaml`);
|
|
11164
|
+
if (!fs22.existsSync(chainPath)) {
|
|
10809
11165
|
return {
|
|
10810
11166
|
chain_id: chainId,
|
|
10811
11167
|
status: "error",
|
|
@@ -10814,7 +11170,7 @@ async function runChain(rootDir, chainId, options) {
|
|
|
10814
11170
|
duration_ms: Date.now() - start
|
|
10815
11171
|
};
|
|
10816
11172
|
}
|
|
10817
|
-
const chain =
|
|
11173
|
+
const chain = yaml13.load(fs22.readFileSync(chainPath, "utf8"));
|
|
10818
11174
|
let permutation;
|
|
10819
11175
|
if (options.permutation && chain.permutations) {
|
|
10820
11176
|
permutation = chain.permutations.find((p) => p.id === options.permutation);
|
|
@@ -10918,8 +11274,8 @@ function validateInterpolation(persona) {
|
|
|
10918
11274
|
const serialized = JSON.stringify(step);
|
|
10919
11275
|
const templates = serialized.match(TEMPLATE_REGEX) || [];
|
|
10920
11276
|
for (const template of templates) {
|
|
10921
|
-
const
|
|
10922
|
-
const [namespace, ...rest] =
|
|
11277
|
+
const path26 = template.replace("{{", "").replace("}}", "").trim();
|
|
11278
|
+
const [namespace, ...rest] = path26.split(".");
|
|
10923
11279
|
const key = rest.join(".");
|
|
10924
11280
|
switch (namespace) {
|
|
10925
11281
|
case "fixtures":
|
|
@@ -10980,7 +11336,7 @@ var PERSONA_SCHEMA = {
|
|
|
10980
11336
|
var sentinelSchemaRegistered = false;
|
|
10981
11337
|
async function emitPersonaEvents(result) {
|
|
10982
11338
|
try {
|
|
10983
|
-
const { SentinelStorage: SentinelStorage2 } = await import("./dist-
|
|
11339
|
+
const { SentinelStorage: SentinelStorage2 } = await import("./dist-IKBGY7FQ.js");
|
|
10984
11340
|
const storage2 = new SentinelStorage2();
|
|
10985
11341
|
if (!sentinelSchemaRegistered) {
|
|
10986
11342
|
try {
|
|
@@ -11932,8 +12288,8 @@ function summarizeStep(step) {
|
|
|
11932
12288
|
}
|
|
11933
12289
|
|
|
11934
12290
|
// ../paradigm-mcp/src/tools/fallback-grep.ts
|
|
11935
|
-
import * as
|
|
11936
|
-
import { execSync as
|
|
12291
|
+
import * as path24 from "path";
|
|
12292
|
+
import { execSync as execSync5 } from "child_process";
|
|
11937
12293
|
function grepForReferences(rootDir, symbol, options = {}) {
|
|
11938
12294
|
const { maxResults = 20 } = options;
|
|
11939
12295
|
const results = [];
|
|
@@ -11947,7 +12303,7 @@ function grepForReferences(rootDir, symbol, options = {}) {
|
|
|
11947
12303
|
let output = "";
|
|
11948
12304
|
for (const cmd of grepCommands) {
|
|
11949
12305
|
try {
|
|
11950
|
-
output =
|
|
12306
|
+
output = execSync5(cmd, { encoding: "utf8", maxBuffer: 1024 * 1024 });
|
|
11951
12307
|
if (output.trim()) break;
|
|
11952
12308
|
} catch {
|
|
11953
12309
|
continue;
|
|
@@ -11961,7 +12317,7 @@ function grepForReferences(rootDir, symbol, options = {}) {
|
|
|
11961
12317
|
const match = line.match(/^(.+?):(\d+):(.*)$/);
|
|
11962
12318
|
if (match) {
|
|
11963
12319
|
const [, filePath, lineNum, content] = match;
|
|
11964
|
-
const relativePath =
|
|
12320
|
+
const relativePath = path24.relative(rootDir, filePath);
|
|
11965
12321
|
let context2 = "unknown";
|
|
11966
12322
|
if (relativePath.includes(".purpose") || relativePath.includes("portal.yaml")) {
|
|
11967
12323
|
context2 = "purpose";
|
|
@@ -12614,7 +12970,7 @@ function registerTools(server, getContext2, reloadContext2) {
|
|
|
12614
12970
|
const symbols = getSymbolsByType(ctx.index, type);
|
|
12615
12971
|
examples[type] = symbols.slice(0, 3).map((s) => s.symbol);
|
|
12616
12972
|
}
|
|
12617
|
-
const platform2 =
|
|
12973
|
+
const platform2 = os3.platform();
|
|
12618
12974
|
const isWindows = platform2 === "win32";
|
|
12619
12975
|
const shell = isWindows ? "PowerShell/CMD" : platform2 === "darwin" ? "zsh/bash" : "bash";
|
|
12620
12976
|
let protocols;
|
|
@@ -12854,10 +13210,10 @@ Update command:
|
|
|
12854
13210
|
trackToolCall(noWsText.length, name);
|
|
12855
13211
|
return { content: [{ type: "text", text: noWsText }] };
|
|
12856
13212
|
}
|
|
12857
|
-
const { rebuildStaticFiles: rebuildStaticFiles2 } = await import("./reindex-
|
|
13213
|
+
const { rebuildStaticFiles: rebuildStaticFiles2 } = await import("./reindex-CMZARW5K.js");
|
|
12858
13214
|
const memberResults = [];
|
|
12859
13215
|
for (const member of ctx.workspace.config.members) {
|
|
12860
|
-
const memberAbsPath =
|
|
13216
|
+
const memberAbsPath = path25.resolve(path25.dirname(ctx.workspace.workspacePath), member.path);
|
|
12861
13217
|
try {
|
|
12862
13218
|
const result = await rebuildStaticFiles2(memberAbsPath);
|
|
12863
13219
|
memberResults.push({
|