@a-company/paradigm 3.23.2 → 3.24.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/{accept-orchestration-ORQRKKGR.js → accept-orchestration-AAYFKS74.js} +5 -5
- package/dist/chunk-4UC6AQOC.js +631 -0
- package/dist/{chunk-YOFP72IB.js → chunk-6EQRU7WC.js} +4 -4
- package/dist/{chunk-K34C7NAN.js → chunk-6UV47VRD.js} +1 -1
- package/dist/{chunk-Z42FOOVT.js → chunk-GC6X3YM7.js} +6 -6
- package/dist/{chunk-C3BK3E23.js → chunk-OXG5GVDJ.js} +1 -1
- package/dist/{chunk-XKAFTZOZ.js → chunk-VHSTF72C.js} +1 -1
- package/dist/{chunk-UI3XXVJ6.js → chunk-W4VFKZVF.js} +58 -1
- package/dist/{graph-5VSRBRKZ.js → chunk-Z7W7HNRG.js} +2 -1
- package/dist/context-audit-RI4R2WRH.js +549 -0
- package/dist/{diff-4XJZN4OB.js → diff-QC7PWIPF.js} +5 -5
- package/dist/{doctor-FINKMI66.js → doctor-RVODPMHJ.js} +1 -1
- package/dist/graph-ERNQQQ7C.js +12 -0
- package/dist/index.js +64 -30
- package/dist/mcp.js +841 -17
- package/dist/{orchestrate-6XGEA655.js → orchestrate-NNNWNELP.js} +8 -8
- package/dist/pipeline-3G2FRAKM.js +263 -0
- package/dist/{probe-T77FFIAG.js → probe-SN4BNXOC.js} +2 -1
- package/dist/{providers-VIBWDN5D.js → providers-NKGY36QF.js} +1 -1
- package/dist/{shift-SW3GSODO.js → shift-G42AEUHE.js} +15 -14
- package/dist/{spawn-JSV2HST3.js → spawn-52PASJJL.js} +3 -3
- package/dist/sweep-5POCF2E4.js +934 -0
- package/dist/{team-YIYA4ZLX.js → team-JZHIH7H5.js} +6 -6
- package/dist/university-content/courses/.purpose +307 -0
- package/dist/university-content/plsat/.purpose +131 -0
- package/dist/{workspace-S5Q5LVA6.js → workspace-L27RR5MF.js} +3 -2
- package/package.json +1 -1
- package/dist/chunk-ZMN3RAIT.js +0 -564
- package/dist/{chunk-XNUWLW73.js → chunk-7WTOOH23.js} +0 -0
- package/dist/{flow-UFMPVOEM.js → flow-KZKMMXJC.js} +1 -1
package/dist/mcp.js
CHANGED
|
@@ -2026,7 +2026,7 @@ function registerResources(server, getContext2) {
|
|
|
2026
2026
|
|
|
2027
2027
|
// ../paradigm-mcp/src/tools/index.ts
|
|
2028
2028
|
import * as os3 from "os";
|
|
2029
|
-
import * as
|
|
2029
|
+
import * as path28 from "path";
|
|
2030
2030
|
import {
|
|
2031
2031
|
ListToolsRequestSchema,
|
|
2032
2032
|
CallToolRequestSchema
|
|
@@ -2790,7 +2790,7 @@ function navigateExplore(config, target, rootDir) {
|
|
|
2790
2790
|
}
|
|
2791
2791
|
if (result.paths.length === 0) {
|
|
2792
2792
|
const areaSymbols = Object.entries(config.symbols).filter(
|
|
2793
|
-
([sym,
|
|
2793
|
+
([sym, path29]) => sym.toLowerCase().includes(targetLower) || path29.toLowerCase().includes(targetLower)
|
|
2794
2794
|
).slice(0, 10);
|
|
2795
2795
|
result.paths = [...new Set(areaSymbols.map(([, p]) => p))];
|
|
2796
2796
|
result.symbols = areaSymbols.map(([s]) => s);
|
|
@@ -11288,8 +11288,8 @@ function generateRunId() {
|
|
|
11288
11288
|
var TEMPLATE_REGEX = /\{\{([^}]+)\}\}/g;
|
|
11289
11289
|
function interpolate(value, scope) {
|
|
11290
11290
|
if (typeof value === "string") {
|
|
11291
|
-
return value.replace(TEMPLATE_REGEX, (_match,
|
|
11292
|
-
const resolved = resolvePath(
|
|
11291
|
+
return value.replace(TEMPLATE_REGEX, (_match, path29) => {
|
|
11292
|
+
const resolved = resolvePath(path29.trim(), scope);
|
|
11293
11293
|
return resolved !== void 0 ? String(resolved) : _match;
|
|
11294
11294
|
});
|
|
11295
11295
|
}
|
|
@@ -11322,8 +11322,8 @@ function resolvePath(dotPath, scope) {
|
|
|
11322
11322
|
return void 0;
|
|
11323
11323
|
}
|
|
11324
11324
|
}
|
|
11325
|
-
function deepGet(obj,
|
|
11326
|
-
const parts =
|
|
11325
|
+
function deepGet(obj, path29) {
|
|
11326
|
+
const parts = path29.split(/[.\[\]]+/).filter(Boolean);
|
|
11327
11327
|
let current = obj;
|
|
11328
11328
|
for (const part of parts) {
|
|
11329
11329
|
if (current == null || typeof current !== "object") return void 0;
|
|
@@ -11559,11 +11559,11 @@ async function runPersonaObject(rootDir, persona, options) {
|
|
|
11559
11559
|
}
|
|
11560
11560
|
async function runChain(rootDir, chainId, options) {
|
|
11561
11561
|
const start = Date.now();
|
|
11562
|
-
const
|
|
11563
|
-
const
|
|
11564
|
-
const
|
|
11565
|
-
const chainPath =
|
|
11566
|
-
if (!
|
|
11562
|
+
const fs25 = await import("fs");
|
|
11563
|
+
const path29 = await import("path");
|
|
11564
|
+
const yaml15 = await import("js-yaml");
|
|
11565
|
+
const chainPath = path29.join(rootDir, ".paradigm", "personas", "chains", `${chainId}.yaml`);
|
|
11566
|
+
if (!fs25.existsSync(chainPath)) {
|
|
11567
11567
|
return {
|
|
11568
11568
|
chain_id: chainId,
|
|
11569
11569
|
status: "error",
|
|
@@ -11572,7 +11572,7 @@ async function runChain(rootDir, chainId, options) {
|
|
|
11572
11572
|
duration_ms: Date.now() - start
|
|
11573
11573
|
};
|
|
11574
11574
|
}
|
|
11575
|
-
const chain =
|
|
11575
|
+
const chain = yaml15.load(fs25.readFileSync(chainPath, "utf8"));
|
|
11576
11576
|
let permutation;
|
|
11577
11577
|
if (options.permutation && chain.permutations) {
|
|
11578
11578
|
permutation = chain.permutations.find((p) => p.id === options.permutation);
|
|
@@ -11676,8 +11676,8 @@ function validateInterpolation(persona) {
|
|
|
11676
11676
|
const serialized = JSON.stringify(step);
|
|
11677
11677
|
const templates = serialized.match(TEMPLATE_REGEX) || [];
|
|
11678
11678
|
for (const template of templates) {
|
|
11679
|
-
const
|
|
11680
|
-
const [namespace, ...rest] =
|
|
11679
|
+
const path29 = template.replace("{{", "").replace("}}", "").trim();
|
|
11680
|
+
const [namespace, ...rest] = path29.split(".");
|
|
11681
11681
|
const key = rest.join(".");
|
|
11682
11682
|
switch (namespace) {
|
|
11683
11683
|
case "fixtures":
|
|
@@ -12939,8 +12939,811 @@ function buildGraphState(rootDir, symbolFilter, groups, links, graphName = "Gene
|
|
|
12939
12939
|
};
|
|
12940
12940
|
}
|
|
12941
12941
|
|
|
12942
|
-
// ../paradigm-mcp/src/tools/
|
|
12942
|
+
// ../paradigm-mcp/src/tools/heatmap.ts
|
|
12943
|
+
import * as fs23 from "fs";
|
|
12943
12944
|
import * as path25 from "path";
|
|
12945
|
+
var HEAT_MAP_FILE = ".paradigm/heat-map.json";
|
|
12946
|
+
var CONFIDENCE_DECAY_RATE = 0.05;
|
|
12947
|
+
function getHeatmapToolsList() {
|
|
12948
|
+
return [
|
|
12949
|
+
{
|
|
12950
|
+
name: "paradigm_heatmap_query",
|
|
12951
|
+
description: "Query the adaptive heat map for historically relevant symbols given keywords. Returns associations sorted by confidence.",
|
|
12952
|
+
inputSchema: {
|
|
12953
|
+
type: "object",
|
|
12954
|
+
properties: {
|
|
12955
|
+
keywords: {
|
|
12956
|
+
type: "array",
|
|
12957
|
+
items: { type: "string" },
|
|
12958
|
+
description: "Keywords to search for in the heat map"
|
|
12959
|
+
}
|
|
12960
|
+
},
|
|
12961
|
+
required: ["keywords"]
|
|
12962
|
+
},
|
|
12963
|
+
annotations: {
|
|
12964
|
+
readOnlyHint: true,
|
|
12965
|
+
destructiveHint: false
|
|
12966
|
+
}
|
|
12967
|
+
},
|
|
12968
|
+
{
|
|
12969
|
+
name: "paradigm_heatmap_record",
|
|
12970
|
+
description: "Record a query-to-symbol association in the adaptive heat map. Use positive signal to reinforce, negative to correct.",
|
|
12971
|
+
inputSchema: {
|
|
12972
|
+
type: "object",
|
|
12973
|
+
properties: {
|
|
12974
|
+
keywords: {
|
|
12975
|
+
type: "array",
|
|
12976
|
+
items: { type: "string" },
|
|
12977
|
+
description: "Keywords that relate to the symbols"
|
|
12978
|
+
},
|
|
12979
|
+
symbols: {
|
|
12980
|
+
type: "array",
|
|
12981
|
+
items: { type: "string" },
|
|
12982
|
+
description: "Symbol IDs (with prefix) that are relevant"
|
|
12983
|
+
},
|
|
12984
|
+
aspects: {
|
|
12985
|
+
type: "array",
|
|
12986
|
+
items: { type: "string" },
|
|
12987
|
+
description: "Aspect IDs that are relevant (optional)"
|
|
12988
|
+
},
|
|
12989
|
+
context: {
|
|
12990
|
+
type: "string",
|
|
12991
|
+
description: "Why this association exists"
|
|
12992
|
+
},
|
|
12993
|
+
signal: {
|
|
12994
|
+
type: "string",
|
|
12995
|
+
enum: ["positive", "negative"],
|
|
12996
|
+
description: "Positive reinforces, negative reduces confidence"
|
|
12997
|
+
},
|
|
12998
|
+
correction: {
|
|
12999
|
+
type: "string",
|
|
13000
|
+
description: "Explanation if correcting a wrong association"
|
|
13001
|
+
}
|
|
13002
|
+
},
|
|
13003
|
+
required: ["keywords", "symbols", "signal"]
|
|
13004
|
+
},
|
|
13005
|
+
annotations: {
|
|
13006
|
+
readOnlyHint: false,
|
|
13007
|
+
destructiveHint: false
|
|
13008
|
+
}
|
|
13009
|
+
},
|
|
13010
|
+
{
|
|
13011
|
+
name: "paradigm_heatmap_stats",
|
|
13012
|
+
description: "Show heat map statistics \u2014 total associations, hot/cold keywords, top symbols, session count.",
|
|
13013
|
+
inputSchema: {
|
|
13014
|
+
type: "object",
|
|
13015
|
+
properties: {}
|
|
13016
|
+
},
|
|
13017
|
+
annotations: {
|
|
13018
|
+
readOnlyHint: true,
|
|
13019
|
+
destructiveHint: false
|
|
13020
|
+
}
|
|
13021
|
+
}
|
|
13022
|
+
];
|
|
13023
|
+
}
|
|
13024
|
+
function loadHeatMap(projectDir2) {
|
|
13025
|
+
const filePath = path25.join(projectDir2, HEAT_MAP_FILE);
|
|
13026
|
+
if (!fs23.existsSync(filePath)) {
|
|
13027
|
+
return {
|
|
13028
|
+
version: "1.0",
|
|
13029
|
+
lastUpdated: (/* @__PURE__ */ new Date()).toISOString(),
|
|
13030
|
+
sessionCount: 0,
|
|
13031
|
+
associations: []
|
|
13032
|
+
};
|
|
13033
|
+
}
|
|
13034
|
+
return JSON.parse(fs23.readFileSync(filePath, "utf8"));
|
|
13035
|
+
}
|
|
13036
|
+
function saveHeatMap(projectDir2, heatMap) {
|
|
13037
|
+
const filePath = path25.join(projectDir2, HEAT_MAP_FILE);
|
|
13038
|
+
const dir = path25.dirname(filePath);
|
|
13039
|
+
if (!fs23.existsSync(dir)) fs23.mkdirSync(dir, { recursive: true });
|
|
13040
|
+
heatMap.lastUpdated = (/* @__PURE__ */ new Date()).toISOString();
|
|
13041
|
+
fs23.writeFileSync(filePath, JSON.stringify(heatMap, null, 2), "utf8");
|
|
13042
|
+
}
|
|
13043
|
+
async function handleHeatmapQuery(args, projectDir2) {
|
|
13044
|
+
const heatMap = loadHeatMap(projectDir2);
|
|
13045
|
+
const now = Date.now();
|
|
13046
|
+
for (const assoc of heatMap.associations) {
|
|
13047
|
+
const daysSinceHit = (now - new Date(assoc.lastHit).getTime()) / (1e3 * 60 * 60 * 24);
|
|
13048
|
+
const decayPeriods = Math.floor(daysSinceHit / 30);
|
|
13049
|
+
if (decayPeriods > 0) {
|
|
13050
|
+
assoc.confidence = Math.max(
|
|
13051
|
+
0.01,
|
|
13052
|
+
assoc.confidence * Math.pow(1 - CONFIDENCE_DECAY_RATE, decayPeriods)
|
|
13053
|
+
);
|
|
13054
|
+
}
|
|
13055
|
+
}
|
|
13056
|
+
const queryKeywords = args.keywords.map((k) => k.toLowerCase());
|
|
13057
|
+
const matches = heatMap.associations.filter(
|
|
13058
|
+
(a) => a.keywords.some(
|
|
13059
|
+
(k) => queryKeywords.some((qk) => k.includes(qk) || qk.includes(k))
|
|
13060
|
+
)
|
|
13061
|
+
).sort((a, b) => b.confidence - a.confidence).slice(0, 10);
|
|
13062
|
+
return JSON.stringify({
|
|
13063
|
+
matches,
|
|
13064
|
+
totalAssociations: heatMap.associations.length
|
|
13065
|
+
});
|
|
13066
|
+
}
|
|
13067
|
+
async function handleHeatmapRecord(args, projectDir2) {
|
|
13068
|
+
const heatMap = loadHeatMap(projectDir2);
|
|
13069
|
+
const queryKeywords = args.keywords.map((k) => k.toLowerCase());
|
|
13070
|
+
const existing = heatMap.associations.find(
|
|
13071
|
+
(a) => a.keywords.some((k) => queryKeywords.includes(k))
|
|
13072
|
+
);
|
|
13073
|
+
if (args.signal === "positive") {
|
|
13074
|
+
if (existing) {
|
|
13075
|
+
existing.confidence = Math.min(1, existing.confidence + 0.05);
|
|
13076
|
+
existing.hitCount += 1;
|
|
13077
|
+
existing.lastHit = (/* @__PURE__ */ new Date()).toISOString();
|
|
13078
|
+
for (const s of args.symbols) {
|
|
13079
|
+
if (!existing.symbols.includes(s)) existing.symbols.push(s);
|
|
13080
|
+
}
|
|
13081
|
+
if (args.aspects) {
|
|
13082
|
+
if (!existing.aspects) existing.aspects = [];
|
|
13083
|
+
for (const a of args.aspects) {
|
|
13084
|
+
if (!existing.aspects.includes(a)) existing.aspects.push(a);
|
|
13085
|
+
}
|
|
13086
|
+
}
|
|
13087
|
+
for (const k of queryKeywords) {
|
|
13088
|
+
if (!existing.keywords.includes(k)) existing.keywords.push(k);
|
|
13089
|
+
}
|
|
13090
|
+
} else {
|
|
13091
|
+
heatMap.associations.push({
|
|
13092
|
+
keywords: queryKeywords,
|
|
13093
|
+
symbols: args.symbols,
|
|
13094
|
+
aspects: args.aspects,
|
|
13095
|
+
confidence: 0.5,
|
|
13096
|
+
hitCount: 1,
|
|
13097
|
+
lastHit: (/* @__PURE__ */ new Date()).toISOString()
|
|
13098
|
+
});
|
|
13099
|
+
}
|
|
13100
|
+
} else {
|
|
13101
|
+
if (existing) {
|
|
13102
|
+
existing.confidence = Math.max(0.01, existing.confidence - 0.15);
|
|
13103
|
+
if (args.correction) {
|
|
13104
|
+
for (const s of args.symbols) {
|
|
13105
|
+
const idx = existing.symbols.indexOf(s);
|
|
13106
|
+
if (idx >= 0) existing.symbols.splice(idx, 1);
|
|
13107
|
+
}
|
|
13108
|
+
}
|
|
13109
|
+
}
|
|
13110
|
+
}
|
|
13111
|
+
saveHeatMap(projectDir2, heatMap);
|
|
13112
|
+
return JSON.stringify({
|
|
13113
|
+
recorded: true,
|
|
13114
|
+
totalAssociations: heatMap.associations.length
|
|
13115
|
+
});
|
|
13116
|
+
}
|
|
13117
|
+
async function handleHeatmapStats(projectDir2) {
|
|
13118
|
+
const heatMap = loadHeatMap(projectDir2);
|
|
13119
|
+
const sorted = [...heatMap.associations].sort(
|
|
13120
|
+
(a, b) => b.confidence - a.confidence
|
|
13121
|
+
);
|
|
13122
|
+
const hot = sorted.filter((a) => a.confidence > 0.7);
|
|
13123
|
+
const cold = sorted.filter((a) => a.confidence < 0.3);
|
|
13124
|
+
return JSON.stringify({
|
|
13125
|
+
totalAssociations: heatMap.associations.length,
|
|
13126
|
+
sessionCount: heatMap.sessionCount,
|
|
13127
|
+
lastUpdated: heatMap.lastUpdated,
|
|
13128
|
+
hotAssociations: hot.slice(0, 5).map((a) => ({
|
|
13129
|
+
keywords: a.keywords,
|
|
13130
|
+
confidence: a.confidence,
|
|
13131
|
+
hitCount: a.hitCount
|
|
13132
|
+
})),
|
|
13133
|
+
coldAssociations: cold.slice(0, 5).map((a) => ({
|
|
13134
|
+
keywords: a.keywords,
|
|
13135
|
+
confidence: a.confidence,
|
|
13136
|
+
hitCount: a.hitCount
|
|
13137
|
+
})),
|
|
13138
|
+
topSymbols: getTopSymbols(heatMap)
|
|
13139
|
+
});
|
|
13140
|
+
}
|
|
13141
|
+
function getTopSymbols(heatMap) {
|
|
13142
|
+
const counts = /* @__PURE__ */ new Map();
|
|
13143
|
+
for (const a of heatMap.associations) {
|
|
13144
|
+
for (const s of a.symbols) {
|
|
13145
|
+
counts.set(s, (counts.get(s) || 0) + a.hitCount);
|
|
13146
|
+
}
|
|
13147
|
+
}
|
|
13148
|
+
return [...counts.entries()].sort((a, b) => b[1] - a[1]).slice(0, 10).map(([symbol, mentions]) => ({ symbol, mentions }));
|
|
13149
|
+
}
|
|
13150
|
+
async function handleHeatmapTool(name, args, ctx) {
|
|
13151
|
+
switch (name) {
|
|
13152
|
+
case "paradigm_heatmap_query": {
|
|
13153
|
+
const text = await handleHeatmapQuery(
|
|
13154
|
+
args,
|
|
13155
|
+
ctx.rootDir
|
|
13156
|
+
);
|
|
13157
|
+
trackToolCall(text.length, name);
|
|
13158
|
+
return { handled: true, text };
|
|
13159
|
+
}
|
|
13160
|
+
case "paradigm_heatmap_record": {
|
|
13161
|
+
const text = await handleHeatmapRecord(
|
|
13162
|
+
args,
|
|
13163
|
+
ctx.rootDir
|
|
13164
|
+
);
|
|
13165
|
+
trackToolCall(text.length, name);
|
|
13166
|
+
return { handled: true, text };
|
|
13167
|
+
}
|
|
13168
|
+
case "paradigm_heatmap_stats": {
|
|
13169
|
+
const text = await handleHeatmapStats(ctx.rootDir);
|
|
13170
|
+
trackToolCall(text.length, name);
|
|
13171
|
+
return { handled: true, text };
|
|
13172
|
+
}
|
|
13173
|
+
default:
|
|
13174
|
+
return { handled: false, text: "" };
|
|
13175
|
+
}
|
|
13176
|
+
}
|
|
13177
|
+
|
|
13178
|
+
// ../paradigm-mcp/src/tools/pipeline.ts
|
|
13179
|
+
import * as fs24 from "fs";
|
|
13180
|
+
import * as path26 from "path";
|
|
13181
|
+
import * as yaml14 from "js-yaml";
|
|
13182
|
+
var STAGE_ORDER = ["specify", "plan", "task", "implement", "validate"];
|
|
13183
|
+
var PIPELINE_DIR = ".paradigm/pipeline";
|
|
13184
|
+
var DEFAULT_TEMPLATES = {
|
|
13185
|
+
"add-feature": {
|
|
13186
|
+
gates: { specify: "manual", plan: "manual", task: "auto", implement: "sentinel", validate: "sentinel" },
|
|
13187
|
+
description: "Standard feature addition with manual spec/plan review"
|
|
13188
|
+
},
|
|
13189
|
+
"bug-fix": {
|
|
13190
|
+
gates: { specify: "auto", plan: "auto", task: "auto", implement: "sentinel", validate: "sentinel" },
|
|
13191
|
+
description: "Quick bug fix with automated gates except validation"
|
|
13192
|
+
},
|
|
13193
|
+
"security-change": {
|
|
13194
|
+
gates: { specify: "manual", plan: "manual", task: "manual", implement: "manual", validate: "manual" },
|
|
13195
|
+
description: "Security-sensitive change with all-manual gates"
|
|
13196
|
+
},
|
|
13197
|
+
"refactor": {
|
|
13198
|
+
gates: { specify: "auto", plan: "manual", task: "auto", implement: "sentinel", validate: "sentinel" },
|
|
13199
|
+
description: "Code refactoring with manual plan review"
|
|
13200
|
+
}
|
|
13201
|
+
};
|
|
13202
|
+
function slugify2(name) {
|
|
13203
|
+
return name.toLowerCase().replace(/[^a-z0-9-]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
|
|
13204
|
+
}
|
|
13205
|
+
function loadPipeline(projectDir2, feature) {
|
|
13206
|
+
const slug = slugify2(feature);
|
|
13207
|
+
const filePath = path26.join(projectDir2, PIPELINE_DIR, `${slug}.yaml`);
|
|
13208
|
+
if (!fs24.existsSync(filePath)) return null;
|
|
13209
|
+
return yaml14.load(fs24.readFileSync(filePath, "utf8"));
|
|
13210
|
+
}
|
|
13211
|
+
function savePipeline(projectDir2, pipeline) {
|
|
13212
|
+
const slug = slugify2(pipeline.feature);
|
|
13213
|
+
const dir = path26.join(projectDir2, PIPELINE_DIR);
|
|
13214
|
+
if (!fs24.existsSync(dir)) fs24.mkdirSync(dir, { recursive: true });
|
|
13215
|
+
const filePath = path26.join(dir, `${slug}.yaml`);
|
|
13216
|
+
fs24.writeFileSync(filePath, yaml14.dump(pipeline, { lineWidth: 120 }), "utf8");
|
|
13217
|
+
return filePath;
|
|
13218
|
+
}
|
|
13219
|
+
function listPipelines(projectDir2) {
|
|
13220
|
+
const dir = path26.join(projectDir2, PIPELINE_DIR);
|
|
13221
|
+
if (!fs24.existsSync(dir)) return [];
|
|
13222
|
+
return fs24.readdirSync(dir).filter((f) => f.endsWith(".yaml") && !f.startsWith("completed")).map((f) => {
|
|
13223
|
+
try {
|
|
13224
|
+
return yaml14.load(fs24.readFileSync(path26.join(dir, f), "utf8"));
|
|
13225
|
+
} catch {
|
|
13226
|
+
return null;
|
|
13227
|
+
}
|
|
13228
|
+
}).filter(Boolean);
|
|
13229
|
+
}
|
|
13230
|
+
function createPipeline(feature, gateConfig, template) {
|
|
13231
|
+
const stages = {
|
|
13232
|
+
specify: { status: "pending" },
|
|
13233
|
+
plan: { status: "pending" },
|
|
13234
|
+
task: { status: "pending" },
|
|
13235
|
+
implement: { status: "pending" },
|
|
13236
|
+
validate: { status: "pending" }
|
|
13237
|
+
};
|
|
13238
|
+
stages.specify.status = "in-progress";
|
|
13239
|
+
return {
|
|
13240
|
+
version: "1.0",
|
|
13241
|
+
feature: slugify2(feature),
|
|
13242
|
+
created: (/* @__PURE__ */ new Date()).toISOString(),
|
|
13243
|
+
current_stage: "specify",
|
|
13244
|
+
gate_config: gateConfig,
|
|
13245
|
+
template,
|
|
13246
|
+
stages
|
|
13247
|
+
};
|
|
13248
|
+
}
|
|
13249
|
+
function getNextStage(current) {
|
|
13250
|
+
const idx = STAGE_ORDER.indexOf(current);
|
|
13251
|
+
return idx < STAGE_ORDER.length - 1 ? STAGE_ORDER[idx + 1] : null;
|
|
13252
|
+
}
|
|
13253
|
+
function archivePipeline(projectDir2, pipeline) {
|
|
13254
|
+
const slug = slugify2(pipeline.feature);
|
|
13255
|
+
const completedDir = path26.join(projectDir2, PIPELINE_DIR, "completed");
|
|
13256
|
+
if (!fs24.existsSync(completedDir)) fs24.mkdirSync(completedDir, { recursive: true });
|
|
13257
|
+
const destPath = path26.join(completedDir, `${slug}.yaml`);
|
|
13258
|
+
fs24.writeFileSync(destPath, yaml14.dump(pipeline, { lineWidth: 120 }), "utf8");
|
|
13259
|
+
const activePath = path26.join(projectDir2, PIPELINE_DIR, `${slug}.yaml`);
|
|
13260
|
+
if (fs24.existsSync(activePath)) fs24.unlinkSync(activePath);
|
|
13261
|
+
}
|
|
13262
|
+
function getPipelineToolsList() {
|
|
13263
|
+
return [
|
|
13264
|
+
{
|
|
13265
|
+
name: "paradigm_pipeline_start",
|
|
13266
|
+
description: "Create a new spec pipeline for a feature. Uses templates (add-feature, bug-fix, security-change, refactor) or custom gate config. Returns pipeline state. ~200 tokens.",
|
|
13267
|
+
inputSchema: {
|
|
13268
|
+
type: "object",
|
|
13269
|
+
properties: {
|
|
13270
|
+
feature: {
|
|
13271
|
+
type: "string",
|
|
13272
|
+
description: "Feature name or description (will be slugified)"
|
|
13273
|
+
},
|
|
13274
|
+
template: {
|
|
13275
|
+
type: "string",
|
|
13276
|
+
enum: ["add-feature", "bug-fix", "security-change", "refactor"],
|
|
13277
|
+
description: "Pipeline template (default: add-feature)"
|
|
13278
|
+
},
|
|
13279
|
+
gates: {
|
|
13280
|
+
type: "object",
|
|
13281
|
+
properties: {
|
|
13282
|
+
specify: { type: "string", enum: ["auto", "manual", "sentinel"] },
|
|
13283
|
+
plan: { type: "string", enum: ["auto", "manual", "sentinel"] },
|
|
13284
|
+
task: { type: "string", enum: ["auto", "manual", "sentinel"] },
|
|
13285
|
+
implement: { type: "string", enum: ["auto", "manual", "sentinel"] },
|
|
13286
|
+
validate: { type: "string", enum: ["auto", "manual", "sentinel"] }
|
|
13287
|
+
},
|
|
13288
|
+
description: "Custom gate config (overrides template)"
|
|
13289
|
+
}
|
|
13290
|
+
},
|
|
13291
|
+
required: ["feature"]
|
|
13292
|
+
},
|
|
13293
|
+
annotations: {
|
|
13294
|
+
readOnlyHint: false,
|
|
13295
|
+
destructiveHint: false
|
|
13296
|
+
}
|
|
13297
|
+
},
|
|
13298
|
+
{
|
|
13299
|
+
name: "paradigm_pipeline_status",
|
|
13300
|
+
description: "Get pipeline status \u2014 current stage, progress, gate config. Pass feature name for specific pipeline, or omit for all active pipelines. ~200 tokens.",
|
|
13301
|
+
inputSchema: {
|
|
13302
|
+
type: "object",
|
|
13303
|
+
properties: {
|
|
13304
|
+
feature: {
|
|
13305
|
+
type: "string",
|
|
13306
|
+
description: "Feature name (omit to list all active pipelines)"
|
|
13307
|
+
}
|
|
13308
|
+
}
|
|
13309
|
+
},
|
|
13310
|
+
annotations: {
|
|
13311
|
+
readOnlyHint: true,
|
|
13312
|
+
destructiveHint: false
|
|
13313
|
+
}
|
|
13314
|
+
},
|
|
13315
|
+
{
|
|
13316
|
+
name: "paradigm_pipeline_advance",
|
|
13317
|
+
description: "Advance pipeline past the current gate. Marks current stage as approved and moves to the next stage. ~150 tokens.",
|
|
13318
|
+
inputSchema: {
|
|
13319
|
+
type: "object",
|
|
13320
|
+
properties: {
|
|
13321
|
+
feature: {
|
|
13322
|
+
type: "string",
|
|
13323
|
+
description: "Feature name"
|
|
13324
|
+
},
|
|
13325
|
+
approved_by: {
|
|
13326
|
+
type: "string",
|
|
13327
|
+
description: "Who approved this gate (default: agent)"
|
|
13328
|
+
}
|
|
13329
|
+
},
|
|
13330
|
+
required: ["feature"]
|
|
13331
|
+
},
|
|
13332
|
+
annotations: {
|
|
13333
|
+
readOnlyHint: false,
|
|
13334
|
+
destructiveHint: false
|
|
13335
|
+
}
|
|
13336
|
+
},
|
|
13337
|
+
{
|
|
13338
|
+
name: "paradigm_pipeline_configure",
|
|
13339
|
+
description: "Change gate modes on an active pipeline. Use to escalate or relax gates during development. ~150 tokens.",
|
|
13340
|
+
inputSchema: {
|
|
13341
|
+
type: "object",
|
|
13342
|
+
properties: {
|
|
13343
|
+
feature: {
|
|
13344
|
+
type: "string",
|
|
13345
|
+
description: "Feature name"
|
|
13346
|
+
},
|
|
13347
|
+
updates: {
|
|
13348
|
+
type: "object",
|
|
13349
|
+
properties: {
|
|
13350
|
+
specify: { type: "string", enum: ["auto", "manual", "sentinel"] },
|
|
13351
|
+
plan: { type: "string", enum: ["auto", "manual", "sentinel"] },
|
|
13352
|
+
task: { type: "string", enum: ["auto", "manual", "sentinel"] },
|
|
13353
|
+
implement: { type: "string", enum: ["auto", "manual", "sentinel"] },
|
|
13354
|
+
validate: { type: "string", enum: ["auto", "manual", "sentinel"] }
|
|
13355
|
+
},
|
|
13356
|
+
description: "Stage-to-gate-mode updates"
|
|
13357
|
+
},
|
|
13358
|
+
reason: {
|
|
13359
|
+
type: "string",
|
|
13360
|
+
description: "Reason for the configuration change"
|
|
13361
|
+
}
|
|
13362
|
+
},
|
|
13363
|
+
required: ["feature", "updates", "reason"]
|
|
13364
|
+
},
|
|
13365
|
+
annotations: {
|
|
13366
|
+
readOnlyHint: false,
|
|
13367
|
+
destructiveHint: false
|
|
13368
|
+
}
|
|
13369
|
+
},
|
|
13370
|
+
{
|
|
13371
|
+
name: "paradigm_pipeline_escalate",
|
|
13372
|
+
description: "Flag a pipeline stage for user input. Use when a gate requires a decision the agent cannot make autonomously. ~200 tokens.",
|
|
13373
|
+
inputSchema: {
|
|
13374
|
+
type: "object",
|
|
13375
|
+
properties: {
|
|
13376
|
+
feature: {
|
|
13377
|
+
type: "string",
|
|
13378
|
+
description: "Feature name"
|
|
13379
|
+
},
|
|
13380
|
+
stage: {
|
|
13381
|
+
type: "string",
|
|
13382
|
+
enum: ["specify", "plan", "task", "implement", "validate"],
|
|
13383
|
+
description: "Stage to escalate"
|
|
13384
|
+
},
|
|
13385
|
+
question: {
|
|
13386
|
+
type: "string",
|
|
13387
|
+
description: "Question for the user"
|
|
13388
|
+
},
|
|
13389
|
+
options: {
|
|
13390
|
+
type: "array",
|
|
13391
|
+
items: { type: "string" },
|
|
13392
|
+
description: "Available options for the user"
|
|
13393
|
+
},
|
|
13394
|
+
context: {
|
|
13395
|
+
type: "object",
|
|
13396
|
+
description: "Additional context for the decision"
|
|
13397
|
+
}
|
|
13398
|
+
},
|
|
13399
|
+
required: ["feature", "stage", "question", "options"]
|
|
13400
|
+
},
|
|
13401
|
+
annotations: {
|
|
13402
|
+
readOnlyHint: false,
|
|
13403
|
+
destructiveHint: false
|
|
13404
|
+
}
|
|
13405
|
+
},
|
|
13406
|
+
{
|
|
13407
|
+
name: "paradigm_pipeline_abort",
|
|
13408
|
+
description: "Cancel and archive an active pipeline. Use when a feature is abandoned or no longer needed. ~100 tokens.",
|
|
13409
|
+
inputSchema: {
|
|
13410
|
+
type: "object",
|
|
13411
|
+
properties: {
|
|
13412
|
+
feature: {
|
|
13413
|
+
type: "string",
|
|
13414
|
+
description: "Feature name"
|
|
13415
|
+
}
|
|
13416
|
+
},
|
|
13417
|
+
required: ["feature"]
|
|
13418
|
+
},
|
|
13419
|
+
annotations: {
|
|
13420
|
+
readOnlyHint: false,
|
|
13421
|
+
destructiveHint: true
|
|
13422
|
+
}
|
|
13423
|
+
},
|
|
13424
|
+
{
|
|
13425
|
+
name: "paradigm_pipeline_list",
|
|
13426
|
+
description: "List all active pipelines with current stages and progress. ~150 tokens.",
|
|
13427
|
+
inputSchema: {
|
|
13428
|
+
type: "object",
|
|
13429
|
+
properties: {}
|
|
13430
|
+
},
|
|
13431
|
+
annotations: {
|
|
13432
|
+
readOnlyHint: true,
|
|
13433
|
+
destructiveHint: false
|
|
13434
|
+
}
|
|
13435
|
+
}
|
|
13436
|
+
];
|
|
13437
|
+
}
|
|
13438
|
+
async function handlePipelineTool(name, args, ctx) {
|
|
13439
|
+
switch (name) {
|
|
13440
|
+
case "paradigm_pipeline_start": {
|
|
13441
|
+
const feature = args.feature;
|
|
13442
|
+
const templateName = args.template || "add-feature";
|
|
13443
|
+
const customGates = args.gates;
|
|
13444
|
+
let gateConfig;
|
|
13445
|
+
if (customGates) {
|
|
13446
|
+
gateConfig = {
|
|
13447
|
+
specify: customGates.specify || "manual",
|
|
13448
|
+
plan: customGates.plan || "manual",
|
|
13449
|
+
task: customGates.task || "auto",
|
|
13450
|
+
implement: customGates.implement || "sentinel",
|
|
13451
|
+
validate: customGates.validate || "sentinel"
|
|
13452
|
+
};
|
|
13453
|
+
} else {
|
|
13454
|
+
const tmpl = DEFAULT_TEMPLATES[templateName];
|
|
13455
|
+
if (!tmpl) {
|
|
13456
|
+
return {
|
|
13457
|
+
handled: true,
|
|
13458
|
+
text: JSON.stringify({
|
|
13459
|
+
error: `Unknown template: ${templateName}`,
|
|
13460
|
+
available: Object.keys(DEFAULT_TEMPLATES)
|
|
13461
|
+
})
|
|
13462
|
+
};
|
|
13463
|
+
}
|
|
13464
|
+
gateConfig = tmpl.gates;
|
|
13465
|
+
}
|
|
13466
|
+
const pipeline = createPipeline(feature, gateConfig, templateName);
|
|
13467
|
+
const filePath = savePipeline(ctx.rootDir, pipeline);
|
|
13468
|
+
return {
|
|
13469
|
+
handled: true,
|
|
13470
|
+
text: JSON.stringify(
|
|
13471
|
+
{
|
|
13472
|
+
created: true,
|
|
13473
|
+
feature: pipeline.feature,
|
|
13474
|
+
template: templateName,
|
|
13475
|
+
file: filePath,
|
|
13476
|
+
current_stage: pipeline.current_stage,
|
|
13477
|
+
gate_config: pipeline.gate_config,
|
|
13478
|
+
stages: pipeline.stages,
|
|
13479
|
+
hint: `Pipeline '${pipeline.feature}' started at 'specify' stage. Create your spec, then call paradigm_pipeline_advance to move to 'plan'.`
|
|
13480
|
+
},
|
|
13481
|
+
null,
|
|
13482
|
+
2
|
|
13483
|
+
)
|
|
13484
|
+
};
|
|
13485
|
+
}
|
|
13486
|
+
case "paradigm_pipeline_status": {
|
|
13487
|
+
const feature = args.feature;
|
|
13488
|
+
if (feature) {
|
|
13489
|
+
const pipeline = loadPipeline(ctx.rootDir, feature);
|
|
13490
|
+
if (!pipeline) {
|
|
13491
|
+
return {
|
|
13492
|
+
handled: true,
|
|
13493
|
+
text: JSON.stringify({ error: `Pipeline not found: ${feature}` })
|
|
13494
|
+
};
|
|
13495
|
+
}
|
|
13496
|
+
const completedStages = STAGE_ORDER.filter(
|
|
13497
|
+
(s) => pipeline.stages[s].status === "approved"
|
|
13498
|
+
).length;
|
|
13499
|
+
return {
|
|
13500
|
+
handled: true,
|
|
13501
|
+
text: JSON.stringify(
|
|
13502
|
+
{
|
|
13503
|
+
feature: pipeline.feature,
|
|
13504
|
+
created: pipeline.created,
|
|
13505
|
+
template: pipeline.template,
|
|
13506
|
+
current_stage: pipeline.current_stage,
|
|
13507
|
+
progress: `${completedStages}/${STAGE_ORDER.length}`,
|
|
13508
|
+
gate_config: pipeline.gate_config,
|
|
13509
|
+
stages: pipeline.stages
|
|
13510
|
+
},
|
|
13511
|
+
null,
|
|
13512
|
+
2
|
|
13513
|
+
)
|
|
13514
|
+
};
|
|
13515
|
+
}
|
|
13516
|
+
const pipelines = listPipelines(ctx.rootDir);
|
|
13517
|
+
if (pipelines.length === 0) {
|
|
13518
|
+
return {
|
|
13519
|
+
handled: true,
|
|
13520
|
+
text: JSON.stringify({
|
|
13521
|
+
count: 0,
|
|
13522
|
+
message: "No active pipelines. Use paradigm_pipeline_start to create one."
|
|
13523
|
+
})
|
|
13524
|
+
};
|
|
13525
|
+
}
|
|
13526
|
+
return {
|
|
13527
|
+
handled: true,
|
|
13528
|
+
text: JSON.stringify(
|
|
13529
|
+
{
|
|
13530
|
+
count: pipelines.length,
|
|
13531
|
+
pipelines: pipelines.map((p) => {
|
|
13532
|
+
const completed = STAGE_ORDER.filter(
|
|
13533
|
+
(s) => p.stages[s].status === "approved"
|
|
13534
|
+
).length;
|
|
13535
|
+
return {
|
|
13536
|
+
feature: p.feature,
|
|
13537
|
+
current_stage: p.current_stage,
|
|
13538
|
+
progress: `${completed}/${STAGE_ORDER.length}`,
|
|
13539
|
+
template: p.template,
|
|
13540
|
+
created: p.created
|
|
13541
|
+
};
|
|
13542
|
+
})
|
|
13543
|
+
},
|
|
13544
|
+
null,
|
|
13545
|
+
2
|
|
13546
|
+
)
|
|
13547
|
+
};
|
|
13548
|
+
}
|
|
13549
|
+
case "paradigm_pipeline_advance": {
|
|
13550
|
+
const feature = args.feature;
|
|
13551
|
+
const approvedBy = args.approved_by || "agent";
|
|
13552
|
+
const pipeline = loadPipeline(ctx.rootDir, feature);
|
|
13553
|
+
if (!pipeline) {
|
|
13554
|
+
return {
|
|
13555
|
+
handled: true,
|
|
13556
|
+
text: JSON.stringify({ error: `Pipeline not found: ${feature}` })
|
|
13557
|
+
};
|
|
13558
|
+
}
|
|
13559
|
+
const current = pipeline.current_stage;
|
|
13560
|
+
const gateMode = pipeline.gate_config[current];
|
|
13561
|
+
const next = getNextStage(current);
|
|
13562
|
+
pipeline.stages[current].status = "approved";
|
|
13563
|
+
pipeline.stages[current].approved_by = approvedBy;
|
|
13564
|
+
pipeline.stages[current].approved_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
13565
|
+
if (gateMode === "auto") {
|
|
13566
|
+
pipeline.stages[current].auto_passed_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
13567
|
+
}
|
|
13568
|
+
if (next) {
|
|
13569
|
+
pipeline.current_stage = next;
|
|
13570
|
+
pipeline.stages[next].status = "in-progress";
|
|
13571
|
+
savePipeline(ctx.rootDir, pipeline);
|
|
13572
|
+
return {
|
|
13573
|
+
handled: true,
|
|
13574
|
+
text: JSON.stringify(
|
|
13575
|
+
{
|
|
13576
|
+
advanced: true,
|
|
13577
|
+
from: current,
|
|
13578
|
+
to: next,
|
|
13579
|
+
gate_mode: gateMode,
|
|
13580
|
+
approved_by: approvedBy,
|
|
13581
|
+
pipeline: {
|
|
13582
|
+
feature: pipeline.feature,
|
|
13583
|
+
current_stage: pipeline.current_stage,
|
|
13584
|
+
stages: pipeline.stages
|
|
13585
|
+
}
|
|
13586
|
+
},
|
|
13587
|
+
null,
|
|
13588
|
+
2
|
|
13589
|
+
)
|
|
13590
|
+
};
|
|
13591
|
+
}
|
|
13592
|
+
savePipeline(ctx.rootDir, pipeline);
|
|
13593
|
+
archivePipeline(ctx.rootDir, pipeline);
|
|
13594
|
+
return {
|
|
13595
|
+
handled: true,
|
|
13596
|
+
text: JSON.stringify(
|
|
13597
|
+
{
|
|
13598
|
+
completed: true,
|
|
13599
|
+
feature: pipeline.feature,
|
|
13600
|
+
message: `Pipeline '${pipeline.feature}' completed and archived.`,
|
|
13601
|
+
stages: pipeline.stages
|
|
13602
|
+
},
|
|
13603
|
+
null,
|
|
13604
|
+
2
|
|
13605
|
+
)
|
|
13606
|
+
};
|
|
13607
|
+
}
|
|
13608
|
+
case "paradigm_pipeline_configure": {
|
|
13609
|
+
const feature = args.feature;
|
|
13610
|
+
const updates = args.updates;
|
|
13611
|
+
const reason = args.reason;
|
|
13612
|
+
const pipeline = loadPipeline(ctx.rootDir, feature);
|
|
13613
|
+
if (!pipeline) {
|
|
13614
|
+
return {
|
|
13615
|
+
handled: true,
|
|
13616
|
+
text: JSON.stringify({ error: `Pipeline not found: ${feature}` })
|
|
13617
|
+
};
|
|
13618
|
+
}
|
|
13619
|
+
const changes = [];
|
|
13620
|
+
for (const [stage, mode] of Object.entries(updates)) {
|
|
13621
|
+
if (STAGE_ORDER.includes(stage) && ["auto", "manual", "sentinel"].includes(mode)) {
|
|
13622
|
+
const old = pipeline.gate_config[stage];
|
|
13623
|
+
pipeline.gate_config[stage] = mode;
|
|
13624
|
+
changes.push({ stage, from: old, to: mode });
|
|
13625
|
+
}
|
|
13626
|
+
}
|
|
13627
|
+
if (changes.length === 0) {
|
|
13628
|
+
return {
|
|
13629
|
+
handled: true,
|
|
13630
|
+
text: JSON.stringify({
|
|
13631
|
+
error: "No valid gate updates provided",
|
|
13632
|
+
valid_stages: STAGE_ORDER,
|
|
13633
|
+
valid_modes: ["auto", "manual", "sentinel"]
|
|
13634
|
+
})
|
|
13635
|
+
};
|
|
13636
|
+
}
|
|
13637
|
+
savePipeline(ctx.rootDir, pipeline);
|
|
13638
|
+
return {
|
|
13639
|
+
handled: true,
|
|
13640
|
+
text: JSON.stringify(
|
|
13641
|
+
{
|
|
13642
|
+
configured: true,
|
|
13643
|
+
feature: pipeline.feature,
|
|
13644
|
+
changes,
|
|
13645
|
+
reason,
|
|
13646
|
+
gate_config: pipeline.gate_config
|
|
13647
|
+
},
|
|
13648
|
+
null,
|
|
13649
|
+
2
|
|
13650
|
+
)
|
|
13651
|
+
};
|
|
13652
|
+
}
|
|
13653
|
+
case "paradigm_pipeline_escalate": {
|
|
13654
|
+
const feature = args.feature;
|
|
13655
|
+
const stage = args.stage;
|
|
13656
|
+
const question = args.question;
|
|
13657
|
+
const options = args.options;
|
|
13658
|
+
const context2 = args.context;
|
|
13659
|
+
const pipeline = loadPipeline(ctx.rootDir, feature);
|
|
13660
|
+
if (!pipeline) {
|
|
13661
|
+
return {
|
|
13662
|
+
handled: true,
|
|
13663
|
+
text: JSON.stringify({ error: `Pipeline not found: ${feature}` })
|
|
13664
|
+
};
|
|
13665
|
+
}
|
|
13666
|
+
pipeline.stages[stage].status = "blocked";
|
|
13667
|
+
pipeline.stages[stage].block_reason = question;
|
|
13668
|
+
savePipeline(ctx.rootDir, pipeline);
|
|
13669
|
+
return {
|
|
13670
|
+
handled: true,
|
|
13671
|
+
text: JSON.stringify(
|
|
13672
|
+
{
|
|
13673
|
+
escalated: true,
|
|
13674
|
+
feature: pipeline.feature,
|
|
13675
|
+
stage,
|
|
13676
|
+
question,
|
|
13677
|
+
options,
|
|
13678
|
+
context: context2 || {},
|
|
13679
|
+
current_gate: pipeline.gate_config[stage],
|
|
13680
|
+
instruction: "This pipeline stage requires user input. Present the question and options to the user, then use paradigm_pipeline_advance or paradigm_pipeline_configure based on their response."
|
|
13681
|
+
},
|
|
13682
|
+
null,
|
|
13683
|
+
2
|
|
13684
|
+
)
|
|
13685
|
+
};
|
|
13686
|
+
}
|
|
13687
|
+
case "paradigm_pipeline_abort": {
|
|
13688
|
+
const feature = args.feature;
|
|
13689
|
+
const pipeline = loadPipeline(ctx.rootDir, feature);
|
|
13690
|
+
if (!pipeline) {
|
|
13691
|
+
return {
|
|
13692
|
+
handled: true,
|
|
13693
|
+
text: JSON.stringify({ error: `Pipeline not found: ${feature}` })
|
|
13694
|
+
};
|
|
13695
|
+
}
|
|
13696
|
+
archivePipeline(ctx.rootDir, pipeline);
|
|
13697
|
+
return {
|
|
13698
|
+
handled: true,
|
|
13699
|
+
text: JSON.stringify({
|
|
13700
|
+
aborted: true,
|
|
13701
|
+
feature: pipeline.feature,
|
|
13702
|
+
message: `Pipeline '${pipeline.feature}' aborted and archived.`
|
|
13703
|
+
})
|
|
13704
|
+
};
|
|
13705
|
+
}
|
|
13706
|
+
case "paradigm_pipeline_list": {
|
|
13707
|
+
const pipelines = listPipelines(ctx.rootDir);
|
|
13708
|
+
if (pipelines.length === 0) {
|
|
13709
|
+
return {
|
|
13710
|
+
handled: true,
|
|
13711
|
+
text: JSON.stringify({
|
|
13712
|
+
count: 0,
|
|
13713
|
+
message: "No active pipelines."
|
|
13714
|
+
})
|
|
13715
|
+
};
|
|
13716
|
+
}
|
|
13717
|
+
return {
|
|
13718
|
+
handled: true,
|
|
13719
|
+
text: JSON.stringify(
|
|
13720
|
+
{
|
|
13721
|
+
count: pipelines.length,
|
|
13722
|
+
pipelines: pipelines.map((p) => {
|
|
13723
|
+
const completed = STAGE_ORDER.filter(
|
|
13724
|
+
(s) => p.stages[s].status === "approved"
|
|
13725
|
+
).length;
|
|
13726
|
+
return {
|
|
13727
|
+
feature: p.feature,
|
|
13728
|
+
current_stage: p.current_stage,
|
|
13729
|
+
progress: `${completed}/${STAGE_ORDER.length}`,
|
|
13730
|
+
template: p.template,
|
|
13731
|
+
created: p.created
|
|
13732
|
+
};
|
|
13733
|
+
})
|
|
13734
|
+
},
|
|
13735
|
+
null,
|
|
13736
|
+
2
|
|
13737
|
+
)
|
|
13738
|
+
};
|
|
13739
|
+
}
|
|
13740
|
+
default:
|
|
13741
|
+
return { handled: false, text: "" };
|
|
13742
|
+
}
|
|
13743
|
+
}
|
|
13744
|
+
|
|
13745
|
+
// ../paradigm-mcp/src/tools/fallback-grep.ts
|
|
13746
|
+
import * as path27 from "path";
|
|
12944
13747
|
import { execSync as execSync5 } from "child_process";
|
|
12945
13748
|
function grepForReferences(rootDir, symbol, options = {}) {
|
|
12946
13749
|
const { maxResults = 20 } = options;
|
|
@@ -12969,7 +13772,7 @@ function grepForReferences(rootDir, symbol, options = {}) {
|
|
|
12969
13772
|
const match = line.match(/^(.+?):(\d+):(.*)$/);
|
|
12970
13773
|
if (match) {
|
|
12971
13774
|
const [, filePath, lineNum, content] = match;
|
|
12972
|
-
const relativePath =
|
|
13775
|
+
const relativePath = path27.relative(rootDir, filePath);
|
|
12973
13776
|
let context2 = "unknown";
|
|
12974
13777
|
if (relativePath.includes(".purpose") || relativePath.includes("portal.yaml")) {
|
|
12975
13778
|
context2 = "purpose";
|
|
@@ -13234,6 +14037,10 @@ function registerTools(server, getContext2, reloadContext2) {
|
|
|
13234
14037
|
...getProtocolsToolsList(),
|
|
13235
14038
|
// Graph generation tool
|
|
13236
14039
|
...getGraphToolsList(),
|
|
14040
|
+
// Heat map tools
|
|
14041
|
+
...getHeatmapToolsList(),
|
|
14042
|
+
// Pipeline tools
|
|
14043
|
+
...getPipelineToolsList(),
|
|
13237
14044
|
// Plugin update check
|
|
13238
14045
|
{
|
|
13239
14046
|
name: "paradigm_plugin_check",
|
|
@@ -13867,7 +14674,7 @@ Update command:
|
|
|
13867
14674
|
const { rebuildStaticFiles: rebuildStaticFiles2 } = await import("./reindex-CMZARW5K.js");
|
|
13868
14675
|
const memberResults = [];
|
|
13869
14676
|
for (const member of ctx.workspace.config.members) {
|
|
13870
|
-
const memberAbsPath =
|
|
14677
|
+
const memberAbsPath = path28.resolve(path28.dirname(ctx.workspace.workspacePath), member.path);
|
|
13871
14678
|
try {
|
|
13872
14679
|
const result = await rebuildStaticFiles2(memberAbsPath);
|
|
13873
14680
|
memberResults.push({
|
|
@@ -14065,6 +14872,23 @@ Update command:
|
|
|
14065
14872
|
};
|
|
14066
14873
|
}
|
|
14067
14874
|
}
|
|
14875
|
+
if (name.startsWith("paradigm_heatmap_")) {
|
|
14876
|
+
const result = await handleHeatmapTool(name, args, ctx);
|
|
14877
|
+
if (result.handled) {
|
|
14878
|
+
return {
|
|
14879
|
+
content: [{ type: "text", text: result.text }]
|
|
14880
|
+
};
|
|
14881
|
+
}
|
|
14882
|
+
}
|
|
14883
|
+
if (name.startsWith("paradigm_pipeline_")) {
|
|
14884
|
+
const result = await handlePipelineTool(name, args, ctx);
|
|
14885
|
+
if (result.handled) {
|
|
14886
|
+
trackToolCall(result.text.length, name);
|
|
14887
|
+
return {
|
|
14888
|
+
content: [{ type: "text", text: result.text }]
|
|
14889
|
+
};
|
|
14890
|
+
}
|
|
14891
|
+
}
|
|
14068
14892
|
if (name === "paradigm_reindex") {
|
|
14069
14893
|
const reload = reloadContext2 || (async () => {
|
|
14070
14894
|
});
|