@a-company/paradigm 3.1.2 → 3.1.5
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/check-UZY647TB.js +168 -0
- package/dist/chunk-4G54C4VM.js +241 -0
- package/dist/{chunk-AQZSUGL3.js → chunk-DRUDZKIT.js} +244 -121
- package/dist/{hooks-YXPQV4SP.js → hooks-JKWO44WH.js} +1 -1
- package/dist/index.js +14 -5
- package/dist/mcp.js +195 -152
- package/dist/plugin-update-checker-EWT7YMDF.js +11 -0
- package/dist/{shift-JDBRTHWO.js → shift-2LQFQP4P.js} +1 -1
- package/package.json +3 -2
package/dist/mcp.js
CHANGED
|
@@ -1,35 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
10
|
-
}) : x)(function(x) {
|
|
11
|
-
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
12
|
-
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
13
|
-
});
|
|
14
|
-
var __commonJS = (cb, mod) => function __require2() {
|
|
15
|
-
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
16
|
-
};
|
|
17
|
-
var __copyProps = (to, from, except, desc) => {
|
|
18
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
19
|
-
for (let key of __getOwnPropNames(from))
|
|
20
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
21
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
22
|
-
}
|
|
23
|
-
return to;
|
|
24
|
-
};
|
|
25
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
26
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
27
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
28
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
29
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
30
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
31
|
-
mod
|
|
32
|
-
));
|
|
2
|
+
import {
|
|
3
|
+
__commonJS,
|
|
4
|
+
__require,
|
|
5
|
+
__toESM,
|
|
6
|
+
getPluginUpdateNotice,
|
|
7
|
+
schedulePluginUpdateCheck
|
|
8
|
+
} from "./chunk-4G54C4VM.js";
|
|
33
9
|
|
|
34
10
|
// ../../node_modules/sql.js/dist/sql-wasm.js
|
|
35
11
|
var require_sql_wasm = __commonJS({
|
|
@@ -525,15 +501,15 @@ var require_sql_wasm = __commonJS({
|
|
|
525
501
|
"undefined" != typeof __filename ? ya = __filename : ba && (ya = self.location.href);
|
|
526
502
|
var za = "", Aa, Ba;
|
|
527
503
|
if (ca) {
|
|
528
|
-
var
|
|
504
|
+
var fs27 = __require("fs");
|
|
529
505
|
za = __dirname + "/";
|
|
530
506
|
Ba = (a) => {
|
|
531
507
|
a = Ca(a) ? new URL(a) : a;
|
|
532
|
-
return
|
|
508
|
+
return fs27.readFileSync(a);
|
|
533
509
|
};
|
|
534
510
|
Aa = async (a) => {
|
|
535
511
|
a = Ca(a) ? new URL(a) : a;
|
|
536
|
-
return
|
|
512
|
+
return fs27.readFileSync(a, void 0);
|
|
537
513
|
};
|
|
538
514
|
1 < process.argv.length && (wa = process.argv[1].replace(/\\/g, "/"));
|
|
539
515
|
process.argv.slice(2);
|
|
@@ -815,7 +791,7 @@ var require_sql_wasm = __commonJS({
|
|
|
815
791
|
if (ca) {
|
|
816
792
|
var b = Buffer.alloc(256), c = 0, d = process.stdin.fd;
|
|
817
793
|
try {
|
|
818
|
-
c =
|
|
794
|
+
c = fs27.readSync(d, b, 0, 256);
|
|
819
795
|
} catch (e) {
|
|
820
796
|
if (e.toString().includes("EOF")) c = 0;
|
|
821
797
|
else throw e;
|
|
@@ -4291,8 +4267,8 @@ var SessionTracker = class {
|
|
|
4291
4267
|
* Extract resource type from URI
|
|
4292
4268
|
*/
|
|
4293
4269
|
extractResourceType(uri) {
|
|
4294
|
-
const
|
|
4295
|
-
const firstPart =
|
|
4270
|
+
const path31 = uri.replace("paradigm://", "");
|
|
4271
|
+
const firstPart = path31.split("/")[0];
|
|
4296
4272
|
return firstPart || "unknown";
|
|
4297
4273
|
}
|
|
4298
4274
|
/**
|
|
@@ -7003,7 +6979,7 @@ function navigateExplore(config, target, rootDir) {
|
|
|
7003
6979
|
}
|
|
7004
6980
|
if (result.paths.length === 0) {
|
|
7005
6981
|
const areaSymbols = Object.entries(config.symbols).filter(
|
|
7006
|
-
([sym,
|
|
6982
|
+
([sym, path31]) => sym.toLowerCase().includes(targetLower) || path31.toLowerCase().includes(targetLower)
|
|
7007
6983
|
).slice(0, 10);
|
|
7008
6984
|
result.paths = [...new Set(areaSymbols.map(([, p]) => p))];
|
|
7009
6985
|
result.symbols = areaSymbols.map(([s]) => s);
|
|
@@ -12095,6 +12071,10 @@ async function handleTagsTool(name, args, ctx) {
|
|
|
12095
12071
|
}
|
|
12096
12072
|
}
|
|
12097
12073
|
|
|
12074
|
+
// ../paradigm-mcp/src/tools/purpose-portal.ts
|
|
12075
|
+
import * as fs21 from "fs";
|
|
12076
|
+
import * as path23 from "path";
|
|
12077
|
+
|
|
12098
12078
|
// ../paradigm-mcp/src/utils/purpose-writer.ts
|
|
12099
12079
|
import * as fs19 from "fs";
|
|
12100
12080
|
import * as path21 from "path";
|
|
@@ -13067,6 +13047,21 @@ async function handleAddAspect(args, ctx, reloadContext2) {
|
|
|
13067
13047
|
}
|
|
13068
13048
|
}
|
|
13069
13049
|
const filePath = resolvePurposeFilePath(purposeFile, ctx.rootDir);
|
|
13050
|
+
const purposeDir = path23.dirname(filePath);
|
|
13051
|
+
for (const anchor of anchors) {
|
|
13052
|
+
const anchorFile = anchor.replace(/:.*$/, "");
|
|
13053
|
+
const resolved = path23.resolve(purposeDir, anchorFile);
|
|
13054
|
+
if (!fs21.existsSync(resolved)) {
|
|
13055
|
+
const rootResolved = path23.resolve(ctx.rootDir, anchorFile);
|
|
13056
|
+
if (fs21.existsSync(rootResolved)) {
|
|
13057
|
+
const corrected = path23.relative(purposeDir, rootResolved);
|
|
13058
|
+
const idx = anchors.indexOf(anchor);
|
|
13059
|
+
anchors[idx] = anchor.replace(anchorFile, corrected);
|
|
13060
|
+
} else {
|
|
13061
|
+
return err(`Anchor file not found: "${anchorFile}". Anchors must be relative to the .purpose file directory (${purposeDir}).`);
|
|
13062
|
+
}
|
|
13063
|
+
}
|
|
13064
|
+
}
|
|
13070
13065
|
const data = readPurposeFile(filePath);
|
|
13071
13066
|
if (!data.aspects) data.aspects = {};
|
|
13072
13067
|
const bareId = stripSymbolPrefix(id);
|
|
@@ -13466,12 +13461,12 @@ async function handleValidate(args, ctx) {
|
|
|
13466
13461
|
}
|
|
13467
13462
|
|
|
13468
13463
|
// ../paradigm-mcp/src/tools/pm.ts
|
|
13469
|
-
import * as
|
|
13470
|
-
import * as
|
|
13464
|
+
import * as fs23 from "fs";
|
|
13465
|
+
import * as path26 from "path";
|
|
13471
13466
|
|
|
13472
13467
|
// ../paradigm-mcp/src/utils/habits-loader.ts
|
|
13473
|
-
import * as
|
|
13474
|
-
import * as
|
|
13468
|
+
import * as fs22 from "fs";
|
|
13469
|
+
import * as path24 from "path";
|
|
13475
13470
|
import * as yaml13 from "js-yaml";
|
|
13476
13471
|
var SEED_HABITS = [
|
|
13477
13472
|
{
|
|
@@ -13578,7 +13573,7 @@ var SEED_HABITS = [
|
|
|
13578
13573
|
var HABITS_CACHE_TTL_MS = 30 * 1e3;
|
|
13579
13574
|
var habitsCache = /* @__PURE__ */ new Map();
|
|
13580
13575
|
function loadHabits(rootDir) {
|
|
13581
|
-
const absoluteRoot =
|
|
13576
|
+
const absoluteRoot = path24.resolve(rootDir);
|
|
13582
13577
|
const cached = habitsCache.get(absoluteRoot);
|
|
13583
13578
|
if (cached && Date.now() - cached.loadedAt < HABITS_CACHE_TTL_MS) {
|
|
13584
13579
|
return cached.habits;
|
|
@@ -13593,16 +13588,16 @@ function loadHabitsFresh(rootDir) {
|
|
|
13593
13588
|
habitsById.set(seed.id, { ...seed });
|
|
13594
13589
|
}
|
|
13595
13590
|
const home = process.env.HOME || process.env.USERPROFILE || "~";
|
|
13596
|
-
const globalConfig = loadHabitsYaml(
|
|
13591
|
+
const globalConfig = loadHabitsYaml(path24.join(home, ".paradigm", "habits.yaml"));
|
|
13597
13592
|
if (globalConfig) mergeHabits(habitsById, globalConfig);
|
|
13598
|
-
const projectConfig = loadHabitsYaml(
|
|
13593
|
+
const projectConfig = loadHabitsYaml(path24.join(rootDir, ".paradigm", "habits.yaml"));
|
|
13599
13594
|
if (projectConfig) mergeHabits(habitsById, projectConfig);
|
|
13600
13595
|
return Array.from(habitsById.values());
|
|
13601
13596
|
}
|
|
13602
13597
|
function loadHabitsYaml(filePath) {
|
|
13603
|
-
if (!
|
|
13598
|
+
if (!fs22.existsSync(filePath)) return null;
|
|
13604
13599
|
try {
|
|
13605
|
-
const content =
|
|
13600
|
+
const content = fs22.readFileSync(filePath, "utf8");
|
|
13606
13601
|
return yaml13.load(content);
|
|
13607
13602
|
} catch {
|
|
13608
13603
|
return null;
|
|
@@ -13749,7 +13744,7 @@ function evalFileModified(habit, ctx) {
|
|
|
13749
13744
|
const patterns = habit.check.params.patterns || [];
|
|
13750
13745
|
if (patterns.length === 0) return { habit, result: "followed", reason: "No patterns specified" };
|
|
13751
13746
|
const matched = ctx.filesModified.filter(
|
|
13752
|
-
(f) => patterns.some((p) => f.includes(p) ||
|
|
13747
|
+
(f) => patterns.some((p) => f.includes(p) || path24.basename(f) === p)
|
|
13753
13748
|
);
|
|
13754
13749
|
if (matched.length > 0) {
|
|
13755
13750
|
return { habit, result: "followed", reason: `Matching files: ${matched.join(", ")}`, evidence: matched };
|
|
@@ -13768,12 +13763,12 @@ function evalGitClean(habit, ctx) {
|
|
|
13768
13763
|
}
|
|
13769
13764
|
|
|
13770
13765
|
// ../paradigm-mcp/src/utils/practice-store.ts
|
|
13771
|
-
import * as
|
|
13766
|
+
import * as path25 from "path";
|
|
13772
13767
|
var storageInstance = null;
|
|
13773
13768
|
var storageInitialized2 = false;
|
|
13774
13769
|
async function getStorage2(rootDir) {
|
|
13775
13770
|
if (!storageInstance) {
|
|
13776
|
-
const dbPath =
|
|
13771
|
+
const dbPath = path25.join(rootDir, ".paradigm", "sentinel", "sentinel.db");
|
|
13777
13772
|
storageInstance = new SentinelStorage(dbPath);
|
|
13778
13773
|
await storageInstance.ensureReady();
|
|
13779
13774
|
storageInitialized2 = true;
|
|
@@ -14064,11 +14059,11 @@ function runPostflightCheck(filesModified, symbolsTouched, ctx) {
|
|
|
14064
14059
|
const violations = [];
|
|
14065
14060
|
const declaredRoutes = ctx.gateConfig?.routes ? Object.keys(ctx.gateConfig.routes) : [];
|
|
14066
14061
|
for (const file of filesModified) {
|
|
14067
|
-
const absPath =
|
|
14068
|
-
if (!
|
|
14062
|
+
const absPath = path26.isAbsolute(file) ? file : path26.join(ctx.rootDir, file);
|
|
14063
|
+
if (!fs23.existsSync(absPath)) continue;
|
|
14069
14064
|
let content;
|
|
14070
14065
|
try {
|
|
14071
|
-
content =
|
|
14066
|
+
content = fs23.readFileSync(absPath, "utf-8");
|
|
14072
14067
|
} catch {
|
|
14073
14068
|
continue;
|
|
14074
14069
|
}
|
|
@@ -14086,8 +14081,8 @@ function runPostflightCheck(filesModified, symbolsTouched, ctx) {
|
|
|
14086
14081
|
violations.push({
|
|
14087
14082
|
type: "missing-portal-gate",
|
|
14088
14083
|
severity: "warning",
|
|
14089
|
-
message: `Route "${routePath}" in ${
|
|
14090
|
-
file:
|
|
14084
|
+
message: `Route "${routePath}" in ${path26.relative(ctx.rootDir, absPath)} not in portal.yaml`,
|
|
14085
|
+
file: path26.relative(ctx.rootDir, absPath),
|
|
14091
14086
|
suggestion: "Add route to portal.yaml with ^gates. Use paradigm_gates_for_route for suggestions."
|
|
14092
14087
|
});
|
|
14093
14088
|
} else if (!ctx.gateConfig && routePath.startsWith("/api/")) {
|
|
@@ -14095,7 +14090,7 @@ function runPostflightCheck(filesModified, symbolsTouched, ctx) {
|
|
|
14095
14090
|
type: "missing-portal-gate",
|
|
14096
14091
|
severity: "warning",
|
|
14097
14092
|
message: `API route "${routePath}" found but no portal.yaml exists`,
|
|
14098
|
-
file:
|
|
14093
|
+
file: path26.relative(ctx.rootDir, absPath),
|
|
14099
14094
|
suggestion: "Create portal.yaml to declare gates for API routes."
|
|
14100
14095
|
});
|
|
14101
14096
|
}
|
|
@@ -14153,8 +14148,8 @@ function runPostflightCheck(filesModified, symbolsTouched, ctx) {
|
|
|
14153
14148
|
});
|
|
14154
14149
|
} else {
|
|
14155
14150
|
for (const anchor of anchors) {
|
|
14156
|
-
const filePath =
|
|
14157
|
-
if (!
|
|
14151
|
+
const filePath = path26.isAbsolute(anchor.path) ? anchor.path : path26.join(ctx.rootDir, anchor.path);
|
|
14152
|
+
if (!fs23.existsSync(filePath)) {
|
|
14158
14153
|
violations.push({
|
|
14159
14154
|
type: "stale-aspect",
|
|
14160
14155
|
severity: "warning",
|
|
@@ -14235,12 +14230,12 @@ function runPostflightCheck(filesModified, symbolsTouched, ctx) {
|
|
|
14235
14230
|
reason: e.reason
|
|
14236
14231
|
}))
|
|
14237
14232
|
};
|
|
14238
|
-
const markerPath =
|
|
14233
|
+
const markerPath = path26.join(ctx.rootDir, ".paradigm", ".habits-blocking");
|
|
14239
14234
|
if (evalResult.blocksCompletion) {
|
|
14240
14235
|
const blocking = evalResult.evaluations.filter((e) => e.result === "skipped" && e.habit.severity === "block").map((e) => `${e.habit.name}: ${e.reason}`);
|
|
14241
|
-
|
|
14242
|
-
} else if (
|
|
14243
|
-
|
|
14236
|
+
fs23.writeFileSync(markerPath, blocking.join("\n"), "utf8");
|
|
14237
|
+
} else if (fs23.existsSync(markerPath)) {
|
|
14238
|
+
fs23.unlinkSync(markerPath);
|
|
14244
14239
|
}
|
|
14245
14240
|
} catch {
|
|
14246
14241
|
}
|
|
@@ -14259,8 +14254,8 @@ function runPostflightCheck(filesModified, symbolsTouched, ctx) {
|
|
|
14259
14254
|
}
|
|
14260
14255
|
|
|
14261
14256
|
// ../paradigm-mcp/src/tools/reindex.ts
|
|
14262
|
-
import * as
|
|
14263
|
-
import * as
|
|
14257
|
+
import * as fs24 from "fs";
|
|
14258
|
+
import * as path27 from "path";
|
|
14264
14259
|
import * as yaml14 from "js-yaml";
|
|
14265
14260
|
|
|
14266
14261
|
// ../probe/core/dist/generator.js
|
|
@@ -14599,10 +14594,10 @@ async function rebuildStaticFiles(rootDir, ctx) {
|
|
|
14599
14594
|
} else {
|
|
14600
14595
|
aggregation = await aggregateFromDirectory(rootDir);
|
|
14601
14596
|
}
|
|
14602
|
-
const projectName = ctx?.projectName ||
|
|
14603
|
-
const paradigmDir =
|
|
14604
|
-
if (!
|
|
14605
|
-
|
|
14597
|
+
const projectName = ctx?.projectName || path27.basename(rootDir);
|
|
14598
|
+
const paradigmDir = path27.join(rootDir, ".paradigm");
|
|
14599
|
+
if (!fs24.existsSync(paradigmDir)) {
|
|
14600
|
+
fs24.mkdirSync(paradigmDir, { recursive: true });
|
|
14606
14601
|
}
|
|
14607
14602
|
const scanIndex = generateScanIndex(
|
|
14608
14603
|
{
|
|
@@ -14612,12 +14607,12 @@ async function rebuildStaticFiles(rootDir, ctx) {
|
|
|
14612
14607
|
},
|
|
14613
14608
|
{ projectName }
|
|
14614
14609
|
);
|
|
14615
|
-
const scanIndexPath =
|
|
14616
|
-
|
|
14610
|
+
const scanIndexPath = path27.join(paradigmDir, "scan-index.json");
|
|
14611
|
+
fs24.writeFileSync(scanIndexPath, serializeScanIndex(scanIndex), "utf8");
|
|
14617
14612
|
filesWritten.push(".paradigm/scan-index.json");
|
|
14618
14613
|
const navigatorData = buildNavigatorData(rootDir, aggregation);
|
|
14619
|
-
const navigatorPath =
|
|
14620
|
-
|
|
14614
|
+
const navigatorPath = path27.join(paradigmDir, "navigator.yaml");
|
|
14615
|
+
fs24.writeFileSync(
|
|
14621
14616
|
navigatorPath,
|
|
14622
14617
|
yaml14.dump(navigatorData, { indent: 2, lineWidth: 120, noRefs: true, sortKeys: false }),
|
|
14623
14618
|
"utf8"
|
|
@@ -14626,8 +14621,8 @@ async function rebuildStaticFiles(rootDir, ctx) {
|
|
|
14626
14621
|
const flowIndex = generateFlowIndex(rootDir, aggregation.purposeFiles);
|
|
14627
14622
|
let flowCount = 0;
|
|
14628
14623
|
if (flowIndex && Object.keys(flowIndex.flows).length > 0) {
|
|
14629
|
-
const flowIndexPath =
|
|
14630
|
-
|
|
14624
|
+
const flowIndexPath = path27.join(paradigmDir, "flow-index.json");
|
|
14625
|
+
fs24.writeFileSync(flowIndexPath, JSON.stringify(flowIndex, null, 2), "utf8");
|
|
14631
14626
|
filesWritten.push(".paradigm/flow-index.json");
|
|
14632
14627
|
flowCount = Object.keys(flowIndex.flows).length;
|
|
14633
14628
|
}
|
|
@@ -14656,7 +14651,7 @@ function buildNavigatorData(rootDir, aggregation) {
|
|
|
14656
14651
|
function buildStructure(rootDir) {
|
|
14657
14652
|
const structure = {};
|
|
14658
14653
|
for (const [category, patterns] of Object.entries(DIRECTORY_PATTERNS)) {
|
|
14659
|
-
const existingPaths = patterns.filter((p) =>
|
|
14654
|
+
const existingPaths = patterns.filter((p) => fs24.existsSync(path27.join(rootDir, p)));
|
|
14660
14655
|
if (existingPaths.length > 0) {
|
|
14661
14656
|
const symbolInfo = Object.values(SYMBOL_CATEGORIES).find((s) => s.category === category);
|
|
14662
14657
|
structure[category] = { paths: existingPaths, symbol: symbolInfo?.prefix || "@" };
|
|
@@ -14667,7 +14662,7 @@ function buildStructure(rootDir) {
|
|
|
14667
14662
|
function buildKeyFiles(rootDir) {
|
|
14668
14663
|
const keyFiles = {};
|
|
14669
14664
|
for (const [category, patterns] of Object.entries(KEY_FILE_PATTERNS)) {
|
|
14670
|
-
const existingPaths = patterns.filter((p) =>
|
|
14665
|
+
const existingPaths = patterns.filter((p) => fs24.existsSync(path27.join(rootDir, p)));
|
|
14671
14666
|
if (existingPaths.length > 0) {
|
|
14672
14667
|
keyFiles[category] = existingPaths;
|
|
14673
14668
|
}
|
|
@@ -14683,10 +14678,10 @@ function buildSkipPatterns(rootDir) {
|
|
|
14683
14678
|
unless_testing: [...DEFAULT_SKIP_PATTERNS.unless_testing],
|
|
14684
14679
|
unless_docs: [...DEFAULT_SKIP_PATTERNS.unless_docs]
|
|
14685
14680
|
};
|
|
14686
|
-
const gitignorePath =
|
|
14687
|
-
if (
|
|
14681
|
+
const gitignorePath = path27.join(rootDir, ".gitignore");
|
|
14682
|
+
if (fs24.existsSync(gitignorePath)) {
|
|
14688
14683
|
try {
|
|
14689
|
-
const content =
|
|
14684
|
+
const content = fs24.readFileSync(gitignorePath, "utf8");
|
|
14690
14685
|
const gitignorePatterns = content.split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#")).filter(
|
|
14691
14686
|
(line) => line.endsWith("/") || line.includes("*") || ["node_modules", "dist", "build", ".cache"].some((p) => line.includes(p))
|
|
14692
14687
|
).slice(0, 20);
|
|
@@ -14735,11 +14730,11 @@ function buildSymbolMap(symbols, purposeFiles, _rootDir) {
|
|
|
14735
14730
|
symbolMap[symbolId] = symbol.filePath;
|
|
14736
14731
|
} else {
|
|
14737
14732
|
const matchingPurpose = purposeFiles.find((pf) => {
|
|
14738
|
-
const dir =
|
|
14733
|
+
const dir = path27.dirname(pf);
|
|
14739
14734
|
return dir.toLowerCase().includes(symbol.id.toLowerCase());
|
|
14740
14735
|
});
|
|
14741
14736
|
if (matchingPurpose) {
|
|
14742
|
-
symbolMap[symbolId] =
|
|
14737
|
+
symbolMap[symbolId] = path27.dirname(matchingPurpose) + "/";
|
|
14743
14738
|
}
|
|
14744
14739
|
}
|
|
14745
14740
|
}
|
|
@@ -14750,7 +14745,7 @@ function generateFlowIndex(rootDir, purposeFiles) {
|
|
|
14750
14745
|
const symbolToFlows = {};
|
|
14751
14746
|
for (const filePath of purposeFiles) {
|
|
14752
14747
|
try {
|
|
14753
|
-
const content =
|
|
14748
|
+
const content = fs24.readFileSync(filePath, "utf8");
|
|
14754
14749
|
const data = yaml14.load(content);
|
|
14755
14750
|
if (!data?.flows) continue;
|
|
14756
14751
|
if (Array.isArray(data.flows)) {
|
|
@@ -14764,7 +14759,7 @@ function generateFlowIndex(rootDir, purposeFiles) {
|
|
|
14764
14759
|
id: flowId,
|
|
14765
14760
|
description: flow.description || "",
|
|
14766
14761
|
steps,
|
|
14767
|
-
definedIn:
|
|
14762
|
+
definedIn: path27.relative(rootDir, filePath)
|
|
14768
14763
|
};
|
|
14769
14764
|
indexFlowSymbols(flowId, steps, symbolToFlows);
|
|
14770
14765
|
}
|
|
@@ -14780,7 +14775,7 @@ function generateFlowIndex(rootDir, purposeFiles) {
|
|
|
14780
14775
|
trigger: flowDef.trigger,
|
|
14781
14776
|
steps,
|
|
14782
14777
|
validation: flowDef.validation,
|
|
14783
|
-
definedIn:
|
|
14778
|
+
definedIn: path27.relative(rootDir, filePath)
|
|
14784
14779
|
};
|
|
14785
14780
|
indexFlowSymbols(flowId, steps, symbolToFlows);
|
|
14786
14781
|
}
|
|
@@ -14833,28 +14828,28 @@ function indexFlowSymbols(flowId, steps, symbolToFlows) {
|
|
|
14833
14828
|
}
|
|
14834
14829
|
|
|
14835
14830
|
// ../paradigm-mcp/src/utils/lore-loader.ts
|
|
14836
|
-
import * as
|
|
14837
|
-
import * as
|
|
14831
|
+
import * as fs25 from "fs";
|
|
14832
|
+
import * as path28 from "path";
|
|
14838
14833
|
import * as yaml15 from "js-yaml";
|
|
14839
14834
|
var LORE_DIR = ".paradigm/lore";
|
|
14840
14835
|
var ENTRIES_DIR = "entries";
|
|
14841
14836
|
var TIMELINE_FILE = "timeline.yaml";
|
|
14842
14837
|
async function loadLoreEntries(rootDir, filter) {
|
|
14843
|
-
const entriesPath =
|
|
14844
|
-
if (!
|
|
14838
|
+
const entriesPath = path28.join(rootDir, LORE_DIR, ENTRIES_DIR);
|
|
14839
|
+
if (!fs25.existsSync(entriesPath)) {
|
|
14845
14840
|
return [];
|
|
14846
14841
|
}
|
|
14847
14842
|
migrateLegacyEntries(rootDir);
|
|
14848
14843
|
const entries = [];
|
|
14849
|
-
const dateDirs =
|
|
14844
|
+
const dateDirs = fs25.readdirSync(entriesPath).filter((d) => /^\d{4}-\d{2}-\d{2}$/.test(d)).sort().reverse();
|
|
14850
14845
|
for (const dateDir of dateDirs) {
|
|
14851
14846
|
if (filter?.dateFrom && dateDir < filter.dateFrom.slice(0, 10)) continue;
|
|
14852
14847
|
if (filter?.dateTo && dateDir > filter.dateTo.slice(0, 10)) continue;
|
|
14853
|
-
const dirPath =
|
|
14854
|
-
const files =
|
|
14848
|
+
const dirPath = path28.join(entriesPath, dateDir);
|
|
14849
|
+
const files = fs25.readdirSync(dirPath).filter((f) => f.endsWith(".yaml")).sort();
|
|
14855
14850
|
for (const file of files) {
|
|
14856
14851
|
try {
|
|
14857
|
-
const content =
|
|
14852
|
+
const content = fs25.readFileSync(path28.join(dirPath, file), "utf8");
|
|
14858
14853
|
const entry = yaml15.load(content);
|
|
14859
14854
|
entries.push(entry);
|
|
14860
14855
|
} catch {
|
|
@@ -14867,10 +14862,10 @@ async function loadLoreEntry(rootDir, entryId) {
|
|
|
14867
14862
|
const dateMatch = entryId.match(/^L-(\d{4}-\d{2}-\d{2})-/);
|
|
14868
14863
|
if (dateMatch) {
|
|
14869
14864
|
const dateStr = dateMatch[1];
|
|
14870
|
-
const entryPath =
|
|
14871
|
-
if (
|
|
14865
|
+
const entryPath = path28.join(rootDir, LORE_DIR, ENTRIES_DIR, dateStr, `${entryId}.yaml`);
|
|
14866
|
+
if (fs25.existsSync(entryPath)) {
|
|
14872
14867
|
try {
|
|
14873
|
-
const content =
|
|
14868
|
+
const content = fs25.readFileSync(entryPath, "utf8");
|
|
14874
14869
|
return yaml15.load(content);
|
|
14875
14870
|
} catch {
|
|
14876
14871
|
return null;
|
|
@@ -14881,47 +14876,47 @@ async function loadLoreEntry(rootDir, entryId) {
|
|
|
14881
14876
|
return entries.find((e) => e.id === entryId) || null;
|
|
14882
14877
|
}
|
|
14883
14878
|
async function loadLoreTimeline(rootDir) {
|
|
14884
|
-
const timelinePath =
|
|
14885
|
-
if (!
|
|
14879
|
+
const timelinePath = path28.join(rootDir, LORE_DIR, TIMELINE_FILE);
|
|
14880
|
+
if (!fs25.existsSync(timelinePath)) {
|
|
14886
14881
|
return null;
|
|
14887
14882
|
}
|
|
14888
14883
|
try {
|
|
14889
|
-
const content =
|
|
14884
|
+
const content = fs25.readFileSync(timelinePath, "utf8");
|
|
14890
14885
|
return yaml15.load(content);
|
|
14891
14886
|
} catch {
|
|
14892
14887
|
return null;
|
|
14893
14888
|
}
|
|
14894
14889
|
}
|
|
14895
14890
|
async function recordLoreEntry(rootDir, entry) {
|
|
14896
|
-
const lorePath =
|
|
14891
|
+
const lorePath = path28.join(rootDir, LORE_DIR);
|
|
14897
14892
|
const dateStr = entry.timestamp.slice(0, 10);
|
|
14898
|
-
const datePath =
|
|
14899
|
-
if (!
|
|
14900
|
-
|
|
14893
|
+
const datePath = path28.join(lorePath, ENTRIES_DIR, dateStr);
|
|
14894
|
+
if (!fs25.existsSync(datePath)) {
|
|
14895
|
+
fs25.mkdirSync(datePath, { recursive: true });
|
|
14901
14896
|
}
|
|
14902
14897
|
if (!entry.id) {
|
|
14903
14898
|
entry.id = generateLoreId(rootDir, dateStr);
|
|
14904
14899
|
}
|
|
14905
|
-
const entryPath =
|
|
14906
|
-
|
|
14900
|
+
const entryPath = path28.join(datePath, `${entry.id}.yaml`);
|
|
14901
|
+
fs25.writeFileSync(entryPath, yaml15.dump(entry, { lineWidth: -1, noRefs: true }));
|
|
14907
14902
|
await rebuildTimeline(rootDir);
|
|
14908
14903
|
return entry.id;
|
|
14909
14904
|
}
|
|
14910
14905
|
async function rebuildTimeline(rootDir) {
|
|
14911
|
-
const lorePath =
|
|
14912
|
-
const entriesPath =
|
|
14913
|
-
if (!
|
|
14906
|
+
const lorePath = path28.join(rootDir, LORE_DIR);
|
|
14907
|
+
const entriesPath = path28.join(lorePath, ENTRIES_DIR);
|
|
14908
|
+
if (!fs25.existsSync(entriesPath)) return;
|
|
14914
14909
|
migrateLegacyEntries(rootDir);
|
|
14915
14910
|
const authors = /* @__PURE__ */ new Set();
|
|
14916
14911
|
let entryCount = 0;
|
|
14917
14912
|
let lastUpdated = "";
|
|
14918
|
-
const dateDirs =
|
|
14913
|
+
const dateDirs = fs25.readdirSync(entriesPath).filter((d) => /^\d{4}-\d{2}-\d{2}$/.test(d));
|
|
14919
14914
|
for (const dateDir of dateDirs) {
|
|
14920
|
-
const dirPath =
|
|
14921
|
-
const files =
|
|
14915
|
+
const dirPath = path28.join(entriesPath, dateDir);
|
|
14916
|
+
const files = fs25.readdirSync(dirPath).filter((f) => f.endsWith(".yaml"));
|
|
14922
14917
|
for (const file of files) {
|
|
14923
14918
|
try {
|
|
14924
|
-
const content =
|
|
14919
|
+
const content = fs25.readFileSync(path28.join(dirPath, file), "utf8");
|
|
14925
14920
|
const entry = yaml15.load(content);
|
|
14926
14921
|
authors.add(entry.author.id);
|
|
14927
14922
|
entryCount++;
|
|
@@ -14933,10 +14928,10 @@ async function rebuildTimeline(rootDir) {
|
|
|
14933
14928
|
}
|
|
14934
14929
|
}
|
|
14935
14930
|
let project = "unknown";
|
|
14936
|
-
const configPath =
|
|
14937
|
-
if (
|
|
14931
|
+
const configPath = path28.join(rootDir, ".paradigm", "config.yaml");
|
|
14932
|
+
if (fs25.existsSync(configPath)) {
|
|
14938
14933
|
try {
|
|
14939
|
-
const config = yaml15.load(
|
|
14934
|
+
const config = yaml15.load(fs25.readFileSync(configPath, "utf8"));
|
|
14940
14935
|
project = config.project || config.name || "unknown";
|
|
14941
14936
|
} catch {
|
|
14942
14937
|
}
|
|
@@ -14948,31 +14943,31 @@ async function rebuildTimeline(rootDir) {
|
|
|
14948
14943
|
last_updated: lastUpdated || (/* @__PURE__ */ new Date()).toISOString(),
|
|
14949
14944
|
authors: Array.from(authors)
|
|
14950
14945
|
};
|
|
14951
|
-
if (!
|
|
14952
|
-
|
|
14946
|
+
if (!fs25.existsSync(lorePath)) {
|
|
14947
|
+
fs25.mkdirSync(lorePath, { recursive: true });
|
|
14953
14948
|
}
|
|
14954
|
-
|
|
14955
|
-
|
|
14949
|
+
fs25.writeFileSync(
|
|
14950
|
+
path28.join(lorePath, TIMELINE_FILE),
|
|
14956
14951
|
yaml15.dump(timeline, { lineWidth: -1, noRefs: true })
|
|
14957
14952
|
);
|
|
14958
14953
|
}
|
|
14959
14954
|
function migrateLegacyEntries(rootDir) {
|
|
14960
|
-
const entriesPath =
|
|
14961
|
-
if (!
|
|
14962
|
-
const rootFiles =
|
|
14955
|
+
const entriesPath = path28.join(rootDir, LORE_DIR, ENTRIES_DIR);
|
|
14956
|
+
if (!fs25.existsSync(entriesPath)) return 0;
|
|
14957
|
+
const rootFiles = fs25.readdirSync(entriesPath).filter((f) => f.endsWith(".yaml") && !f.startsWith("."));
|
|
14963
14958
|
let migrated = 0;
|
|
14964
14959
|
for (const file of rootFiles) {
|
|
14965
|
-
const filePath =
|
|
14966
|
-
const stat =
|
|
14960
|
+
const filePath = path28.join(entriesPath, file);
|
|
14961
|
+
const stat = fs25.statSync(filePath);
|
|
14967
14962
|
if (!stat.isFile()) continue;
|
|
14968
14963
|
try {
|
|
14969
|
-
const content =
|
|
14964
|
+
const content = fs25.readFileSync(filePath, "utf8");
|
|
14970
14965
|
const raw = yaml15.load(content);
|
|
14971
14966
|
if (raw.author && typeof raw.author === "object") continue;
|
|
14972
14967
|
const dateStr = typeof raw.date === "string" ? raw.date.slice(0, 10) : (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
14973
|
-
const datePath =
|
|
14974
|
-
if (!
|
|
14975
|
-
|
|
14968
|
+
const datePath = path28.join(entriesPath, dateStr);
|
|
14969
|
+
if (!fs25.existsSync(datePath)) {
|
|
14970
|
+
fs25.mkdirSync(datePath, { recursive: true });
|
|
14976
14971
|
}
|
|
14977
14972
|
const id = generateLoreId(rootDir, dateStr);
|
|
14978
14973
|
const oldType = String(raw.type || "agent-session");
|
|
@@ -14997,11 +14992,11 @@ function migrateLegacyEntries(rootDir) {
|
|
|
14997
14992
|
...verification ? { verification } : {},
|
|
14998
14993
|
tags: ["migrated", oldType]
|
|
14999
14994
|
};
|
|
15000
|
-
|
|
15001
|
-
|
|
14995
|
+
fs25.writeFileSync(
|
|
14996
|
+
path28.join(datePath, `${id}.yaml`),
|
|
15002
14997
|
yaml15.dump(v2Entry, { lineWidth: -1, noRefs: true })
|
|
15003
14998
|
);
|
|
15004
|
-
|
|
14999
|
+
fs25.unlinkSync(filePath);
|
|
15005
15000
|
migrated++;
|
|
15006
15001
|
} catch {
|
|
15007
15002
|
}
|
|
@@ -15012,8 +15007,8 @@ async function updateLoreEntry(rootDir, entryId, partial) {
|
|
|
15012
15007
|
const entry = await loadLoreEntry(rootDir, entryId);
|
|
15013
15008
|
if (!entry) return false;
|
|
15014
15009
|
const dateStr = entry.timestamp.slice(0, 10);
|
|
15015
|
-
const entryPath =
|
|
15016
|
-
if (!
|
|
15010
|
+
const entryPath = path28.join(rootDir, LORE_DIR, ENTRIES_DIR, dateStr, `${entryId}.yaml`);
|
|
15011
|
+
if (!fs25.existsSync(entryPath)) return false;
|
|
15017
15012
|
if (partial.title !== void 0) entry.title = partial.title;
|
|
15018
15013
|
if (partial.summary !== void 0) entry.summary = partial.summary;
|
|
15019
15014
|
if (partial.type !== void 0) entry.type = partial.type;
|
|
@@ -15030,7 +15025,7 @@ async function updateLoreEntry(rootDir, entryId, partial) {
|
|
|
15030
15025
|
if (partial.learnings !== void 0) entry.learnings = partial.learnings;
|
|
15031
15026
|
if (partial.verification !== void 0) entry.verification = partial.verification;
|
|
15032
15027
|
if (partial.tags !== void 0) entry.tags = partial.tags;
|
|
15033
|
-
|
|
15028
|
+
fs25.writeFileSync(entryPath, yaml15.dump(entry, { lineWidth: -1, noRefs: true }));
|
|
15034
15029
|
await rebuildTimeline(rootDir);
|
|
15035
15030
|
return true;
|
|
15036
15031
|
}
|
|
@@ -15038,13 +15033,13 @@ async function deleteLoreEntry(rootDir, entryId) {
|
|
|
15038
15033
|
const entry = await loadLoreEntry(rootDir, entryId);
|
|
15039
15034
|
if (!entry) return false;
|
|
15040
15035
|
const dateStr = entry.timestamp.slice(0, 10);
|
|
15041
|
-
const entryPath =
|
|
15042
|
-
if (!
|
|
15043
|
-
|
|
15044
|
-
const dateDir =
|
|
15045
|
-
const remaining =
|
|
15036
|
+
const entryPath = path28.join(rootDir, LORE_DIR, ENTRIES_DIR, dateStr, `${entryId}.yaml`);
|
|
15037
|
+
if (!fs25.existsSync(entryPath)) return false;
|
|
15038
|
+
fs25.unlinkSync(entryPath);
|
|
15039
|
+
const dateDir = path28.dirname(entryPath);
|
|
15040
|
+
const remaining = fs25.readdirSync(dateDir).filter((f) => f.endsWith(".yaml"));
|
|
15046
15041
|
if (remaining.length === 0) {
|
|
15047
|
-
|
|
15042
|
+
fs25.rmdirSync(dateDir);
|
|
15048
15043
|
}
|
|
15049
15044
|
await rebuildTimeline(rootDir);
|
|
15050
15045
|
return true;
|
|
@@ -15085,11 +15080,11 @@ function applyFilter(entries, filter) {
|
|
|
15085
15080
|
return result;
|
|
15086
15081
|
}
|
|
15087
15082
|
function generateLoreId(rootDir, dateStr) {
|
|
15088
|
-
const datePath =
|
|
15089
|
-
if (!
|
|
15083
|
+
const datePath = path28.join(rootDir, LORE_DIR, ENTRIES_DIR, dateStr);
|
|
15084
|
+
if (!fs25.existsSync(datePath)) {
|
|
15090
15085
|
return `L-${dateStr}-001`;
|
|
15091
15086
|
}
|
|
15092
|
-
const existing =
|
|
15087
|
+
const existing = fs25.readdirSync(datePath).filter((f) => f.startsWith("L-") && f.endsWith(".yaml")).map((f) => {
|
|
15093
15088
|
const match = f.match(/L-\d{4}-\d{2}-\d{2}-(\d+)\.yaml/);
|
|
15094
15089
|
return match ? parseInt(match[1], 10) : 0;
|
|
15095
15090
|
});
|
|
@@ -15592,8 +15587,8 @@ function summarizeEntry(entry) {
|
|
|
15592
15587
|
}
|
|
15593
15588
|
|
|
15594
15589
|
// ../paradigm-mcp/src/tools/habits.ts
|
|
15595
|
-
import * as
|
|
15596
|
-
import * as
|
|
15590
|
+
import * as fs26 from "fs";
|
|
15591
|
+
import * as path29 from "path";
|
|
15597
15592
|
import { execSync as execSync2 } from "child_process";
|
|
15598
15593
|
function getHabitsToolsList() {
|
|
15599
15594
|
return [
|
|
@@ -15842,13 +15837,13 @@ async function handleHabitsCheck(args, ctx) {
|
|
|
15842
15837
|
} catch {
|
|
15843
15838
|
}
|
|
15844
15839
|
}
|
|
15845
|
-
const markerPath =
|
|
15840
|
+
const markerPath = path29.join(ctx.rootDir, ".paradigm", ".habits-blocking");
|
|
15846
15841
|
try {
|
|
15847
15842
|
if (trigger === "on-stop" && evaluation.blocksCompletion) {
|
|
15848
15843
|
const blocking = evaluation.evaluations.filter((e) => e.result === "skipped" && e.habit.severity === "block").map((e) => `${e.habit.name}: ${e.reason}`);
|
|
15849
|
-
|
|
15844
|
+
fs26.writeFileSync(markerPath, blocking.join("\n"), "utf8");
|
|
15850
15845
|
} else if (trigger === "on-stop") {
|
|
15851
|
-
if (
|
|
15846
|
+
if (fs26.existsSync(markerPath)) fs26.unlinkSync(markerPath);
|
|
15852
15847
|
}
|
|
15853
15848
|
} catch {
|
|
15854
15849
|
}
|
|
@@ -16061,7 +16056,7 @@ async function handlePracticeContext(args, ctx) {
|
|
|
16061
16056
|
}
|
|
16062
16057
|
|
|
16063
16058
|
// ../paradigm-mcp/src/tools/fallback-grep.ts
|
|
16064
|
-
import * as
|
|
16059
|
+
import * as path30 from "path";
|
|
16065
16060
|
import { execSync as execSync3 } from "child_process";
|
|
16066
16061
|
function grepForReferences(rootDir, symbol, options = {}) {
|
|
16067
16062
|
const { maxResults = 20 } = options;
|
|
@@ -16090,7 +16085,7 @@ function grepForReferences(rootDir, symbol, options = {}) {
|
|
|
16090
16085
|
const match = line.match(/^(.+?):(\d+):(.*)$/);
|
|
16091
16086
|
if (match) {
|
|
16092
16087
|
const [, filePath, lineNum, content] = match;
|
|
16093
|
-
const relativePath =
|
|
16088
|
+
const relativePath = path30.relative(rootDir, filePath);
|
|
16094
16089
|
let context2 = "unknown";
|
|
16095
16090
|
if (relativePath.includes(".purpose") || relativePath.includes("portal.yaml")) {
|
|
16096
16091
|
context2 = "purpose";
|
|
@@ -16335,7 +16330,20 @@ function registerTools(server, getContext2, reloadContext2) {
|
|
|
16335
16330
|
// Lore tools
|
|
16336
16331
|
...getLoreToolsList(),
|
|
16337
16332
|
// Habits tools
|
|
16338
|
-
...getHabitsToolsList()
|
|
16333
|
+
...getHabitsToolsList(),
|
|
16334
|
+
// Plugin update check
|
|
16335
|
+
{
|
|
16336
|
+
name: "paradigm_plugin_check",
|
|
16337
|
+
description: "Check for updates to installed Claude Code plugins. Reports which marketplace clones have newer remote commits and which cached versions are stale.",
|
|
16338
|
+
inputSchema: {
|
|
16339
|
+
type: "object",
|
|
16340
|
+
properties: {}
|
|
16341
|
+
},
|
|
16342
|
+
annotations: {
|
|
16343
|
+
readOnlyHint: true,
|
|
16344
|
+
destructiveHint: false
|
|
16345
|
+
}
|
|
16346
|
+
}
|
|
16339
16347
|
]
|
|
16340
16348
|
};
|
|
16341
16349
|
}
|
|
@@ -16349,8 +16357,11 @@ function registerTools(server, getContext2, reloadContext2) {
|
|
|
16349
16357
|
const tracker2 = getSessionTracker();
|
|
16350
16358
|
tracker2.setRootDir(ctx.rootDir);
|
|
16351
16359
|
let recoveryPreamble = null;
|
|
16360
|
+
let updateNotice = null;
|
|
16352
16361
|
if (!tracker2.hasRecoveredThisSession()) {
|
|
16353
16362
|
recoveryPreamble = buildRecoveryPreamble(ctx.rootDir);
|
|
16363
|
+
updateNotice = getPluginUpdateNotice();
|
|
16364
|
+
schedulePluginUpdateCheck();
|
|
16354
16365
|
tracker2.markRecovered();
|
|
16355
16366
|
}
|
|
16356
16367
|
const toolResult = await (async () => {
|
|
@@ -16783,6 +16794,37 @@ function registerTools(server, getContext2, reloadContext2) {
|
|
|
16783
16794
|
}]
|
|
16784
16795
|
};
|
|
16785
16796
|
}
|
|
16797
|
+
case "paradigm_plugin_check": {
|
|
16798
|
+
const { runPluginUpdateCheck } = await import("./plugin-update-checker-EWT7YMDF.js");
|
|
16799
|
+
const results = await runPluginUpdateCheck();
|
|
16800
|
+
const updatable = results.filter((r) => r.hasRemoteUpdate || r.hasCacheStale);
|
|
16801
|
+
if (updatable.length === 0) {
|
|
16802
|
+
const msg = results.length === 0 ? "No Claude Code plugins found in ~/.claude/plugins/marketplaces/." : "All installed plugins are up to date.";
|
|
16803
|
+
trackToolCall(msg.length, name);
|
|
16804
|
+
return { content: [{ type: "text", text: msg }] };
|
|
16805
|
+
}
|
|
16806
|
+
const lines = ["Plugin updates available:\n"];
|
|
16807
|
+
const pullCmds = [];
|
|
16808
|
+
for (const r of updatable) {
|
|
16809
|
+
if (r.hasRemoteUpdate) {
|
|
16810
|
+
lines.push(` ${r.plugin} (${r.repo}): remote has newer commits`);
|
|
16811
|
+
pullCmds.push(`git -C ${r.marketplacePath} pull origin main`);
|
|
16812
|
+
} else if (r.hasCacheStale) {
|
|
16813
|
+
lines.push(` ${r.plugin} (${r.repo}): ${r.installedVersion} \u2192 ${r.localVersion} (restart needed)`);
|
|
16814
|
+
}
|
|
16815
|
+
}
|
|
16816
|
+
if (pullCmds.length > 0) {
|
|
16817
|
+
lines.push(`
|
|
16818
|
+
Update command:
|
|
16819
|
+
${pullCmds.join(" && \\\n ")}`);
|
|
16820
|
+
lines.push("\nAfter running, restart the session to apply updates.");
|
|
16821
|
+
} else {
|
|
16822
|
+
lines.push("\nRestart the session to apply cached updates.");
|
|
16823
|
+
}
|
|
16824
|
+
const pluginText = lines.join("\n");
|
|
16825
|
+
trackToolCall(pluginText.length, name);
|
|
16826
|
+
return { content: [{ type: "text", text: pluginText }] };
|
|
16827
|
+
}
|
|
16786
16828
|
default: {
|
|
16787
16829
|
if (name === "paradigm_navigate") {
|
|
16788
16830
|
const result = await handleNavigateTool(name, args, ctx);
|
|
@@ -16915,10 +16957,11 @@ function registerTools(server, getContext2, reloadContext2) {
|
|
|
16915
16957
|
}
|
|
16916
16958
|
}
|
|
16917
16959
|
})();
|
|
16918
|
-
if (recoveryPreamble) {
|
|
16960
|
+
if (recoveryPreamble || updateNotice) {
|
|
16919
16961
|
const first = toolResult.content?.[0];
|
|
16920
16962
|
if (first && typeof first === "object" && "text" in first && typeof first.text === "string") {
|
|
16921
|
-
|
|
16963
|
+
const preamble = [updateNotice, recoveryPreamble].filter(Boolean).join("\n\n");
|
|
16964
|
+
first.text = preamble + "\n\n" + first.text;
|
|
16922
16965
|
}
|
|
16923
16966
|
}
|
|
16924
16967
|
return toolResult;
|