@a-company/paradigm 3.6.0 → 3.7.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/assessment-loader-T4GPBHLB.js +24 -0
- package/dist/{chunk-IRVA7NKV.js → chunk-BC6XKMUA.js} +2 -0
- package/dist/chunk-CSD7IHSN.js +152 -0
- package/dist/chunk-DSXS42FY.js +283 -0
- package/dist/{chunk-4G54C4VM.js → chunk-YT3QWWKP.js} +15 -39
- package/dist/index.js +2 -2
- package/dist/mcp.js +476 -7
- package/dist/{plugin-update-checker-EWT7YMDF.js → plugin-update-checker-TWBWUSAG.js} +2 -1
- package/dist/{shift-KDVYB6CR.js → shift-KJWSJLWN.js} +1 -1
- package/dist/task-loader-GUX4KS6N.js +20 -0
- package/dist/university-content/courses/para-501.json +110 -0
- package/dist/university-content/plsat/v3.0.json +87 -3
- package/package.json +1 -1
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
closeArc,
|
|
4
|
+
createArc,
|
|
5
|
+
loadArc,
|
|
6
|
+
loadArcs,
|
|
7
|
+
loadEntries,
|
|
8
|
+
loadEntry,
|
|
9
|
+
rebuildAssessmentIndex,
|
|
10
|
+
recordEntry,
|
|
11
|
+
searchEntries
|
|
12
|
+
} from "./chunk-DSXS42FY.js";
|
|
13
|
+
import "./chunk-MO4EEYFW.js";
|
|
14
|
+
export {
|
|
15
|
+
closeArc,
|
|
16
|
+
createArc,
|
|
17
|
+
loadArc,
|
|
18
|
+
loadArcs,
|
|
19
|
+
loadEntries,
|
|
20
|
+
loadEntry,
|
|
21
|
+
rebuildAssessmentIndex,
|
|
22
|
+
recordEntry,
|
|
23
|
+
searchEntries
|
|
24
|
+
};
|
|
@@ -548,6 +548,8 @@ ${purposeLines}
|
|
|
548
548
|
function createMinimalStructure(paradigmDir, projectName) {
|
|
549
549
|
fs.mkdirSync(path.join(paradigmDir, "specs"), { recursive: true });
|
|
550
550
|
fs.mkdirSync(path.join(paradigmDir, "docs"), { recursive: true });
|
|
551
|
+
fs.mkdirSync(path.join(paradigmDir, "tasks"), { recursive: true });
|
|
552
|
+
fs.mkdirSync(path.join(paradigmDir, "assessments"), { recursive: true });
|
|
551
553
|
const minimalConfig = `# Paradigm Configuration
|
|
552
554
|
version: "1.0"
|
|
553
555
|
project: "${projectName}"
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// ../paradigm-mcp/src/utils/task-loader.ts
|
|
4
|
+
import * as fs from "fs";
|
|
5
|
+
import * as path from "path";
|
|
6
|
+
import * as yaml from "js-yaml";
|
|
7
|
+
var TASKS_ROOT = ".paradigm/tasks";
|
|
8
|
+
var ENTRIES_DIR = "entries";
|
|
9
|
+
var INDEX_FILE = "index.yaml";
|
|
10
|
+
function generateTaskId(rootDir, dateStr) {
|
|
11
|
+
const datePath = path.join(rootDir, TASKS_ROOT, ENTRIES_DIR, dateStr);
|
|
12
|
+
if (!fs.existsSync(datePath)) {
|
|
13
|
+
return `T-${dateStr}-001`;
|
|
14
|
+
}
|
|
15
|
+
const existing = fs.readdirSync(datePath).filter((f) => f.startsWith("T-") && f.endsWith(".yaml")).map((f) => {
|
|
16
|
+
const match = f.match(/T-\d{4}-\d{2}-\d{2}-(\d+)\.yaml/);
|
|
17
|
+
return match ? parseInt(match[1], 10) : 0;
|
|
18
|
+
});
|
|
19
|
+
const next = existing.length > 0 ? Math.max(...existing) + 1 : 1;
|
|
20
|
+
return `T-${dateStr}-${String(next).padStart(3, "0")}`;
|
|
21
|
+
}
|
|
22
|
+
var PRIORITY_ORDER = { high: 0, medium: 1, low: 2 };
|
|
23
|
+
function applyFilter(tasks, filter) {
|
|
24
|
+
let result = tasks;
|
|
25
|
+
if (filter.status && filter.status !== "all") {
|
|
26
|
+
result = result.filter((t) => t.status === filter.status);
|
|
27
|
+
}
|
|
28
|
+
if (filter.priority) {
|
|
29
|
+
result = result.filter((t) => t.priority === filter.priority);
|
|
30
|
+
}
|
|
31
|
+
if (filter.tag) {
|
|
32
|
+
result = result.filter((t) => t.tags.includes(filter.tag));
|
|
33
|
+
}
|
|
34
|
+
result.sort((a, b) => {
|
|
35
|
+
const priDiff = (PRIORITY_ORDER[a.priority] ?? 1) - (PRIORITY_ORDER[b.priority] ?? 1);
|
|
36
|
+
if (priDiff !== 0) return priDiff;
|
|
37
|
+
return new Date(b.created).getTime() - new Date(a.created).getTime();
|
|
38
|
+
});
|
|
39
|
+
if (filter.limit) {
|
|
40
|
+
result = result.slice(0, filter.limit);
|
|
41
|
+
}
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
44
|
+
async function loadTasks(rootDir, filter) {
|
|
45
|
+
const entriesPath = path.join(rootDir, TASKS_ROOT, ENTRIES_DIR);
|
|
46
|
+
if (!fs.existsSync(entriesPath)) return [];
|
|
47
|
+
const effectiveFilter = { status: "open", limit: 20, ...filter };
|
|
48
|
+
const tasks = [];
|
|
49
|
+
const dateDirs = fs.readdirSync(entriesPath).filter((d) => /^\d{4}-\d{2}-\d{2}$/.test(d)).sort().reverse();
|
|
50
|
+
for (const dateDir of dateDirs) {
|
|
51
|
+
const dirPath = path.join(entriesPath, dateDir);
|
|
52
|
+
const files = fs.readdirSync(dirPath).filter((f) => f.endsWith(".yaml")).sort();
|
|
53
|
+
for (const file of files) {
|
|
54
|
+
try {
|
|
55
|
+
const content = fs.readFileSync(path.join(dirPath, file), "utf8");
|
|
56
|
+
const task = yaml.load(content);
|
|
57
|
+
tasks.push(task);
|
|
58
|
+
} catch {
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return applyFilter(tasks, effectiveFilter);
|
|
63
|
+
}
|
|
64
|
+
async function loadTask(rootDir, taskId) {
|
|
65
|
+
const dateMatch = taskId.match(/^T-(\d{4}-\d{2}-\d{2})-/);
|
|
66
|
+
if (dateMatch) {
|
|
67
|
+
const filePath = path.join(rootDir, TASKS_ROOT, ENTRIES_DIR, dateMatch[1], `${taskId}.yaml`);
|
|
68
|
+
if (fs.existsSync(filePath)) {
|
|
69
|
+
try {
|
|
70
|
+
return yaml.load(fs.readFileSync(filePath, "utf8"));
|
|
71
|
+
} catch {
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const tasks = await loadTasks(rootDir, { status: "all", limit: 9999 });
|
|
77
|
+
return tasks.find((t) => t.id === taskId) || null;
|
|
78
|
+
}
|
|
79
|
+
async function createTask(rootDir, task) {
|
|
80
|
+
const now = /* @__PURE__ */ new Date();
|
|
81
|
+
const dateStr = now.toISOString().slice(0, 10);
|
|
82
|
+
const datePath = path.join(rootDir, TASKS_ROOT, ENTRIES_DIR, dateStr);
|
|
83
|
+
fs.mkdirSync(datePath, { recursive: true });
|
|
84
|
+
const id = generateTaskId(rootDir, dateStr);
|
|
85
|
+
const entry = {
|
|
86
|
+
id,
|
|
87
|
+
blurb: task.blurb,
|
|
88
|
+
priority: task.priority || "medium",
|
|
89
|
+
status: "open",
|
|
90
|
+
tags: task.tags || [],
|
|
91
|
+
created: now.toISOString(),
|
|
92
|
+
session_link: task.session_link,
|
|
93
|
+
related_lore: task.related_lore
|
|
94
|
+
};
|
|
95
|
+
fs.writeFileSync(path.join(datePath, `${id}.yaml`), yaml.dump(entry, { lineWidth: -1, noRefs: true }));
|
|
96
|
+
await rebuildTaskIndex(rootDir);
|
|
97
|
+
return id;
|
|
98
|
+
}
|
|
99
|
+
async function updateTask(rootDir, taskId, partial) {
|
|
100
|
+
const task = await loadTask(rootDir, taskId);
|
|
101
|
+
if (!task) return false;
|
|
102
|
+
const dateStr = task.created.slice(0, 10);
|
|
103
|
+
const taskPath = path.join(rootDir, TASKS_ROOT, ENTRIES_DIR, dateStr, `${taskId}.yaml`);
|
|
104
|
+
if (!fs.existsSync(taskPath)) return false;
|
|
105
|
+
const { id: _id, created: _created, ...safePartial } = partial;
|
|
106
|
+
const updated = { ...task, ...safePartial };
|
|
107
|
+
fs.writeFileSync(taskPath, yaml.dump(updated, { lineWidth: -1, noRefs: true }));
|
|
108
|
+
await rebuildTaskIndex(rootDir);
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
async function completeTask(rootDir, taskId) {
|
|
112
|
+
return updateTask(rootDir, taskId, { status: "done", completed: (/* @__PURE__ */ new Date()).toISOString() });
|
|
113
|
+
}
|
|
114
|
+
async function shelveTask(rootDir, taskId) {
|
|
115
|
+
return updateTask(rootDir, taskId, { status: "shelved", shelved: (/* @__PURE__ */ new Date()).toISOString() });
|
|
116
|
+
}
|
|
117
|
+
async function rebuildTaskIndex(rootDir) {
|
|
118
|
+
const entriesPath = path.join(rootDir, TASKS_ROOT, ENTRIES_DIR);
|
|
119
|
+
const tasksRootPath = path.join(rootDir, TASKS_ROOT);
|
|
120
|
+
let total = 0, open = 0, done = 0, shelved = 0;
|
|
121
|
+
if (fs.existsSync(entriesPath)) {
|
|
122
|
+
const dateDirs = fs.readdirSync(entriesPath).filter((d) => /^\d{4}-\d{2}-\d{2}$/.test(d));
|
|
123
|
+
for (const dateDir of dateDirs) {
|
|
124
|
+
const dirPath = path.join(entriesPath, dateDir);
|
|
125
|
+
const files = fs.readdirSync(dirPath).filter((f) => f.endsWith(".yaml"));
|
|
126
|
+
for (const file of files) {
|
|
127
|
+
try {
|
|
128
|
+
const task = yaml.load(fs.readFileSync(path.join(dirPath, file), "utf8"));
|
|
129
|
+
total++;
|
|
130
|
+
if (task.status === "open") open++;
|
|
131
|
+
else if (task.status === "done") done++;
|
|
132
|
+
else if (task.status === "shelved") shelved++;
|
|
133
|
+
} catch {
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
const index = { version: "1.0", total, open, done, shelved, last_updated: (/* @__PURE__ */ new Date()).toISOString() };
|
|
139
|
+
fs.mkdirSync(tasksRootPath, { recursive: true });
|
|
140
|
+
fs.writeFileSync(path.join(tasksRootPath, INDEX_FILE), yaml.dump(index, { lineWidth: -1, noRefs: true }));
|
|
141
|
+
return index;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export {
|
|
145
|
+
loadTasks,
|
|
146
|
+
loadTask,
|
|
147
|
+
createTask,
|
|
148
|
+
updateTask,
|
|
149
|
+
completeTask,
|
|
150
|
+
shelveTask,
|
|
151
|
+
rebuildTaskIndex
|
|
152
|
+
};
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// ../paradigm-mcp/src/utils/assessment-loader.ts
|
|
4
|
+
import * as fs from "fs";
|
|
5
|
+
import * as path from "path";
|
|
6
|
+
import * as yaml from "js-yaml";
|
|
7
|
+
var ASSESSMENTS_DIR = ".paradigm/assessments";
|
|
8
|
+
var ARCS_DIR = "arcs";
|
|
9
|
+
var INDEX_FILE = "index.yaml";
|
|
10
|
+
function generateAssessmentId(rootDir, dateStr) {
|
|
11
|
+
const arcsPath = path.join(rootDir, ASSESSMENTS_DIR, ARCS_DIR);
|
|
12
|
+
let maxSeq = 0;
|
|
13
|
+
if (fs.existsSync(arcsPath)) {
|
|
14
|
+
const arcDirs = fs.readdirSync(arcsPath).filter((d) => {
|
|
15
|
+
try {
|
|
16
|
+
return fs.statSync(path.join(arcsPath, d)).isDirectory();
|
|
17
|
+
} catch {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
for (const arcDir of arcDirs) {
|
|
22
|
+
const entriesPath = path.join(arcsPath, arcDir, "entries");
|
|
23
|
+
if (!fs.existsSync(entriesPath)) continue;
|
|
24
|
+
const files = fs.readdirSync(entriesPath).filter(
|
|
25
|
+
(f) => f.startsWith(`A-${dateStr}-`) && f.endsWith(".yaml")
|
|
26
|
+
);
|
|
27
|
+
for (const file of files) {
|
|
28
|
+
const match = file.match(/A-\d{4}-\d{2}-\d{2}-(\d+)\.yaml/);
|
|
29
|
+
if (match) {
|
|
30
|
+
const seq = parseInt(match[1], 10);
|
|
31
|
+
if (seq > maxSeq) maxSeq = seq;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return `A-${dateStr}-${String(maxSeq + 1).padStart(3, "0")}`;
|
|
37
|
+
}
|
|
38
|
+
function computeArcStats(rootDir, arc) {
|
|
39
|
+
const entriesPath = path.join(rootDir, ASSESSMENTS_DIR, ARCS_DIR, arc.id, "entries");
|
|
40
|
+
const symbolSet = /* @__PURE__ */ new Set();
|
|
41
|
+
let entryCount = 0;
|
|
42
|
+
let latestDate;
|
|
43
|
+
if (fs.existsSync(entriesPath)) {
|
|
44
|
+
const files = fs.readdirSync(entriesPath).filter((f) => f.endsWith(".yaml"));
|
|
45
|
+
for (const file of files) {
|
|
46
|
+
try {
|
|
47
|
+
const entry = yaml.load(fs.readFileSync(path.join(entriesPath, file), "utf8"));
|
|
48
|
+
entryCount++;
|
|
49
|
+
if (entry.symbols) entry.symbols.forEach((s) => symbolSet.add(s));
|
|
50
|
+
if (!latestDate || entry.date > latestDate) latestDate = entry.date;
|
|
51
|
+
} catch {
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return { ...arc, entry_count: entryCount, symbols: Array.from(symbolSet), latest_entry: latestDate };
|
|
56
|
+
}
|
|
57
|
+
async function loadArcs(rootDir, status) {
|
|
58
|
+
const arcsPath = path.join(rootDir, ASSESSMENTS_DIR, ARCS_DIR);
|
|
59
|
+
if (!fs.existsSync(arcsPath)) return [];
|
|
60
|
+
const arcDirs = fs.readdirSync(arcsPath).filter((d) => {
|
|
61
|
+
try {
|
|
62
|
+
return fs.statSync(path.join(arcsPath, d)).isDirectory();
|
|
63
|
+
} catch {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
const arcs = [];
|
|
68
|
+
for (const arcDir of arcDirs) {
|
|
69
|
+
const arcFile = path.join(arcsPath, arcDir, "arc.yaml");
|
|
70
|
+
if (!fs.existsSync(arcFile)) continue;
|
|
71
|
+
try {
|
|
72
|
+
const arc = yaml.load(fs.readFileSync(arcFile, "utf8"));
|
|
73
|
+
if (status && status !== "all" && arc.status !== status) continue;
|
|
74
|
+
arcs.push(computeArcStats(rootDir, arc));
|
|
75
|
+
} catch {
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
arcs.sort((a, b) => {
|
|
79
|
+
const aDate = a.latest_entry || a.created;
|
|
80
|
+
const bDate = b.latest_entry || b.created;
|
|
81
|
+
return bDate.localeCompare(aDate);
|
|
82
|
+
});
|
|
83
|
+
return arcs;
|
|
84
|
+
}
|
|
85
|
+
async function loadArc(rootDir, arcId) {
|
|
86
|
+
const arcFile = path.join(rootDir, ASSESSMENTS_DIR, ARCS_DIR, arcId, "arc.yaml");
|
|
87
|
+
if (!fs.existsSync(arcFile)) return null;
|
|
88
|
+
try {
|
|
89
|
+
const arc = yaml.load(fs.readFileSync(arcFile, "utf8"));
|
|
90
|
+
return computeArcStats(rootDir, arc);
|
|
91
|
+
} catch {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
var ARC_ID_PATTERN = /^arc-[a-z0-9-]+$/;
|
|
96
|
+
async function createArc(rootDir, arc) {
|
|
97
|
+
if (!ARC_ID_PATTERN.test(arc.id)) {
|
|
98
|
+
throw new Error(`Invalid arc ID "${arc.id}": must match arc-{kebab-case} (lowercase alphanumeric + hyphens)`);
|
|
99
|
+
}
|
|
100
|
+
const arcPath = path.join(rootDir, ASSESSMENTS_DIR, ARCS_DIR, arc.id);
|
|
101
|
+
const entriesPath = path.join(arcPath, "entries");
|
|
102
|
+
fs.mkdirSync(entriesPath, { recursive: true });
|
|
103
|
+
const arcData = {
|
|
104
|
+
id: arc.id,
|
|
105
|
+
name: arc.name,
|
|
106
|
+
description: arc.description,
|
|
107
|
+
created: (/* @__PURE__ */ new Date()).toISOString(),
|
|
108
|
+
status: "active",
|
|
109
|
+
tags: arc.tags
|
|
110
|
+
};
|
|
111
|
+
fs.writeFileSync(path.join(arcPath, "arc.yaml"), yaml.dump(arcData, { lineWidth: -1, noRefs: true }));
|
|
112
|
+
await rebuildAssessmentIndex(rootDir);
|
|
113
|
+
return arc.id;
|
|
114
|
+
}
|
|
115
|
+
async function closeArc(rootDir, arcId, status) {
|
|
116
|
+
const arcFile = path.join(rootDir, ASSESSMENTS_DIR, ARCS_DIR, arcId, "arc.yaml");
|
|
117
|
+
if (!fs.existsSync(arcFile)) return false;
|
|
118
|
+
try {
|
|
119
|
+
const arc = yaml.load(fs.readFileSync(arcFile, "utf8"));
|
|
120
|
+
arc.status = status;
|
|
121
|
+
fs.writeFileSync(arcFile, yaml.dump(arc, { lineWidth: -1, noRefs: true }));
|
|
122
|
+
await rebuildAssessmentIndex(rootDir);
|
|
123
|
+
return true;
|
|
124
|
+
} catch {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
async function loadEntries(rootDir, arcId) {
|
|
129
|
+
const entriesPath = path.join(rootDir, ASSESSMENTS_DIR, ARCS_DIR, arcId, "entries");
|
|
130
|
+
if (!fs.existsSync(entriesPath)) return [];
|
|
131
|
+
const entries = [];
|
|
132
|
+
const files = fs.readdirSync(entriesPath).filter((f) => f.endsWith(".yaml")).sort();
|
|
133
|
+
for (const file of files) {
|
|
134
|
+
try {
|
|
135
|
+
const entry = yaml.load(fs.readFileSync(path.join(entriesPath, file), "utf8"));
|
|
136
|
+
entries.push(entry);
|
|
137
|
+
} catch {
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
entries.sort((a, b) => b.date.localeCompare(a.date));
|
|
141
|
+
return entries;
|
|
142
|
+
}
|
|
143
|
+
async function loadEntry(rootDir, entryId) {
|
|
144
|
+
const arcsPath = path.join(rootDir, ASSESSMENTS_DIR, ARCS_DIR);
|
|
145
|
+
if (!fs.existsSync(arcsPath)) return null;
|
|
146
|
+
const arcDirs = fs.readdirSync(arcsPath).filter((d) => {
|
|
147
|
+
try {
|
|
148
|
+
return fs.statSync(path.join(arcsPath, d)).isDirectory();
|
|
149
|
+
} catch {
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
for (const arcDir of arcDirs) {
|
|
154
|
+
const entryFile = path.join(arcsPath, arcDir, "entries", `${entryId}.yaml`);
|
|
155
|
+
if (fs.existsSync(entryFile)) {
|
|
156
|
+
try {
|
|
157
|
+
const entry = yaml.load(fs.readFileSync(entryFile, "utf8"));
|
|
158
|
+
const arcFile = path.join(arcsPath, arcDir, "arc.yaml");
|
|
159
|
+
const arc = yaml.load(fs.readFileSync(arcFile, "utf8"));
|
|
160
|
+
return { entry, arc };
|
|
161
|
+
} catch {
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
async function recordEntry(rootDir, entry, arcName, arcDescription) {
|
|
169
|
+
const arcPath = path.join(rootDir, ASSESSMENTS_DIR, ARCS_DIR, entry.arc_id);
|
|
170
|
+
if (!fs.existsSync(path.join(arcPath, "arc.yaml"))) {
|
|
171
|
+
if (!arcName) {
|
|
172
|
+
throw new Error(`Arc "${entry.arc_id}" does not exist. Provide arc_name to create it.`);
|
|
173
|
+
}
|
|
174
|
+
await createArc(rootDir, { id: entry.arc_id, name: arcName, description: arcDescription, tags: entry.symbols });
|
|
175
|
+
}
|
|
176
|
+
const now = /* @__PURE__ */ new Date();
|
|
177
|
+
const dateStr = now.toISOString().slice(0, 10);
|
|
178
|
+
const id = generateAssessmentId(rootDir, dateStr);
|
|
179
|
+
const fullEntry = {
|
|
180
|
+
id,
|
|
181
|
+
arc_id: entry.arc_id,
|
|
182
|
+
title: entry.title,
|
|
183
|
+
summary: entry.summary,
|
|
184
|
+
body: entry.body,
|
|
185
|
+
symbols: entry.symbols,
|
|
186
|
+
tags: entry.tags,
|
|
187
|
+
linked_lore: entry.linked_lore,
|
|
188
|
+
linked_tasks: entry.linked_tasks,
|
|
189
|
+
linked_commits: entry.linked_commits,
|
|
190
|
+
date: now.toISOString(),
|
|
191
|
+
author: { type: "agent", id: "claude", model: "claude-opus-4-6" },
|
|
192
|
+
type: entry.type || "retro"
|
|
193
|
+
};
|
|
194
|
+
const entriesPath = path.join(arcPath, "entries");
|
|
195
|
+
fs.mkdirSync(entriesPath, { recursive: true });
|
|
196
|
+
fs.writeFileSync(path.join(entriesPath, `${id}.yaml`), yaml.dump(fullEntry, { lineWidth: -1, noRefs: true }));
|
|
197
|
+
await rebuildAssessmentIndex(rootDir);
|
|
198
|
+
return id;
|
|
199
|
+
}
|
|
200
|
+
async function searchEntries(rootDir, filter) {
|
|
201
|
+
const arcsPath = path.join(rootDir, ASSESSMENTS_DIR, ARCS_DIR);
|
|
202
|
+
if (!fs.existsSync(arcsPath)) return [];
|
|
203
|
+
const limit = filter.limit || 20;
|
|
204
|
+
const results = [];
|
|
205
|
+
const arcDirs = fs.readdirSync(arcsPath).filter((d) => {
|
|
206
|
+
try {
|
|
207
|
+
return fs.statSync(path.join(arcsPath, d)).isDirectory();
|
|
208
|
+
} catch {
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
for (const arcDir of arcDirs) {
|
|
213
|
+
const entriesPath = path.join(arcsPath, arcDir, "entries");
|
|
214
|
+
if (!fs.existsSync(entriesPath)) continue;
|
|
215
|
+
const files = fs.readdirSync(entriesPath).filter((f) => f.endsWith(".yaml"));
|
|
216
|
+
for (const file of files) {
|
|
217
|
+
try {
|
|
218
|
+
const entry = yaml.load(fs.readFileSync(path.join(entriesPath, file), "utf8"));
|
|
219
|
+
if (filter.symbol && !(entry.symbols || []).includes(filter.symbol)) continue;
|
|
220
|
+
if (filter.tag && !(entry.tags || []).includes(filter.tag)) continue;
|
|
221
|
+
if (filter.type && entry.type !== filter.type) continue;
|
|
222
|
+
if (filter.dateFrom && entry.date < filter.dateFrom) continue;
|
|
223
|
+
if (filter.dateTo && entry.date > filter.dateTo) continue;
|
|
224
|
+
results.push(entry);
|
|
225
|
+
} catch {
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
results.sort((a, b) => b.date.localeCompare(a.date));
|
|
230
|
+
return results.slice(0, limit);
|
|
231
|
+
}
|
|
232
|
+
async function rebuildAssessmentIndex(rootDir) {
|
|
233
|
+
const arcsPath = path.join(rootDir, ASSESSMENTS_DIR, ARCS_DIR);
|
|
234
|
+
const assessmentsPath = path.join(rootDir, ASSESSMENTS_DIR);
|
|
235
|
+
let totalArcs = 0, totalEntries = 0, activeArcs = 0;
|
|
236
|
+
const arcSummaries = [];
|
|
237
|
+
if (fs.existsSync(arcsPath)) {
|
|
238
|
+
const arcDirs = fs.readdirSync(arcsPath).filter((d) => {
|
|
239
|
+
try {
|
|
240
|
+
return fs.statSync(path.join(arcsPath, d)).isDirectory();
|
|
241
|
+
} catch {
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
244
|
+
});
|
|
245
|
+
for (const arcDir of arcDirs) {
|
|
246
|
+
const arcFile = path.join(arcsPath, arcDir, "arc.yaml");
|
|
247
|
+
if (!fs.existsSync(arcFile)) continue;
|
|
248
|
+
try {
|
|
249
|
+
const arc = yaml.load(fs.readFileSync(arcFile, "utf8"));
|
|
250
|
+
const entriesPath = path.join(arcsPath, arcDir, "entries");
|
|
251
|
+
const entryCount = fs.existsSync(entriesPath) ? fs.readdirSync(entriesPath).filter((f) => f.endsWith(".yaml")).length : 0;
|
|
252
|
+
totalArcs++;
|
|
253
|
+
totalEntries += entryCount;
|
|
254
|
+
if (arc.status === "active") activeArcs++;
|
|
255
|
+
arcSummaries.push({ id: arc.id, name: arc.name, status: arc.status, entries: entryCount });
|
|
256
|
+
} catch {
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
const index = {
|
|
261
|
+
version: "1.0",
|
|
262
|
+
total_arcs: totalArcs,
|
|
263
|
+
total_entries: totalEntries,
|
|
264
|
+
active_arcs: activeArcs,
|
|
265
|
+
last_updated: (/* @__PURE__ */ new Date()).toISOString(),
|
|
266
|
+
arcs: arcSummaries
|
|
267
|
+
};
|
|
268
|
+
fs.mkdirSync(assessmentsPath, { recursive: true });
|
|
269
|
+
fs.writeFileSync(path.join(assessmentsPath, INDEX_FILE), yaml.dump(index, { lineWidth: -1, noRefs: true }));
|
|
270
|
+
return index;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
export {
|
|
274
|
+
loadArcs,
|
|
275
|
+
loadArc,
|
|
276
|
+
createArc,
|
|
277
|
+
closeArc,
|
|
278
|
+
loadEntries,
|
|
279
|
+
loadEntry,
|
|
280
|
+
recordEntry,
|
|
281
|
+
searchEntries,
|
|
282
|
+
rebuildAssessmentIndex
|
|
283
|
+
};
|
|
@@ -1,35 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var __create = Object.create;
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
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
|
-
));
|
|
33
2
|
|
|
34
3
|
// ../paradigm-mcp/src/utils/plugin-update-checker.ts
|
|
35
4
|
import * as fs from "fs";
|
|
@@ -185,24 +154,34 @@ function getPluginUpdateNotice() {
|
|
|
185
154
|
lines.push("--- PLUGIN UPDATES AVAILABLE ---");
|
|
186
155
|
lines.push("Updates available for installed Claude Code plugins:");
|
|
187
156
|
const pullCmds = [];
|
|
157
|
+
const reinstallCmds = [];
|
|
188
158
|
for (const r of updatable) {
|
|
189
159
|
if (r.hasRemoteUpdate) {
|
|
190
160
|
const versionInfo = r.installedVersion !== "unknown" ? `${r.installedVersion} \u2192 ${r.localVersion}` : "newer commits available";
|
|
191
161
|
lines.push(` - ${r.plugin} (${r.repo}): ${versionInfo}`);
|
|
192
162
|
pullCmds.push(`git -C ${r.marketplacePath} pull origin main`);
|
|
163
|
+
reinstallCmds.push(`/plugin marketplace add ${r.repo}`);
|
|
193
164
|
} else if (r.hasCacheStale) {
|
|
194
|
-
lines.push(` - ${r.plugin} (${r.repo}): ${r.installedVersion} \u2192 ${r.localVersion} (
|
|
165
|
+
lines.push(` - ${r.plugin} (${r.repo}): ${r.installedVersion} \u2192 ${r.localVersion} (reinstall needed)`);
|
|
166
|
+
reinstallCmds.push(`/plugin marketplace add ${r.repo}`);
|
|
195
167
|
}
|
|
196
168
|
}
|
|
169
|
+
lines.push("");
|
|
170
|
+
lines.push("Tell the user about these updates and suggest the following steps:");
|
|
197
171
|
if (pullCmds.length > 0) {
|
|
198
172
|
lines.push("");
|
|
199
|
-
lines.push("
|
|
173
|
+
lines.push("Step 1 \u2014 Pull latest from remote:");
|
|
200
174
|
lines.push(` ${pullCmds.join(" && \\\n ")}`);
|
|
175
|
+
}
|
|
176
|
+
if (reinstallCmds.length > 0) {
|
|
177
|
+
const stepNum = pullCmds.length > 0 ? 2 : 1;
|
|
201
178
|
lines.push("");
|
|
202
|
-
lines.push(
|
|
203
|
-
|
|
179
|
+
lines.push(`Step ${stepNum} \u2014 Reinstall to update the cached version:`);
|
|
180
|
+
for (const cmd of reinstallCmds) {
|
|
181
|
+
lines.push(` ${cmd}`);
|
|
182
|
+
}
|
|
204
183
|
lines.push("");
|
|
205
|
-
lines.push(
|
|
184
|
+
lines.push(`Step ${stepNum + 1} \u2014 Restart the Claude Code session to load the new version.`);
|
|
206
185
|
}
|
|
207
186
|
lines.push("---");
|
|
208
187
|
return lines.join("\n");
|
|
@@ -232,9 +211,6 @@ async function runPluginUpdateCheck() {
|
|
|
232
211
|
}
|
|
233
212
|
|
|
234
213
|
export {
|
|
235
|
-
__require,
|
|
236
|
-
__commonJS,
|
|
237
|
-
__toESM,
|
|
238
214
|
getPluginUpdateNotice,
|
|
239
215
|
schedulePluginUpdateCheck,
|
|
240
216
|
runPluginUpdateCheck
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
initCommand
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-BC6XKMUA.js";
|
|
5
5
|
import "./chunk-UI3XXVJ6.js";
|
|
6
6
|
import "./chunk-CHSHON3O.js";
|
|
7
7
|
import "./chunk-AK5M6KJB.js";
|
|
@@ -110,7 +110,7 @@ ${chalk2.magenta("\u2569 ")}${chalk2.cyan("\u2534 \u2534\u2534\u2514\u2500\u253
|
|
|
110
110
|
program.name("paradigm").description("Unified developer tools ecosystem").version(VERSION).addHelpText("before", banner);
|
|
111
111
|
program.command("init").description("Initialize Paradigm in the current project").option("-f, --force", "Overwrite existing files").option("--name <name>", "Project name").option("--ide <ide>", "Target IDE: cursor, copilot, windsurf, claude").option("--migrate", "Output migration prompt for existing IDE files").option("--quick", "Non-interactive mode with smart defaults").option("--dry-run", "Show what would be created without creating").action(initCommand);
|
|
112
112
|
program.command("shift").description("Full project setup in one command (init + team init + scan + sync all IDEs + doctor)").option("-f, --force", "Reinitialize even if already setup").option("-q, --quick", "Skip slow operations (scan)").option("--verify", "Run health checks after setup").option("--ide <ide>", "Target specific IDE instead of all").option("--configure-models", "Force model configuration prompts for team agents").action(async (options) => {
|
|
113
|
-
const { shiftCommand } = await import("./shift-
|
|
113
|
+
const { shiftCommand } = await import("./shift-KJWSJLWN.js");
|
|
114
114
|
await shiftCommand(options);
|
|
115
115
|
});
|
|
116
116
|
program.command("setup [path]").description("Interactive setup wizard for Paradigm").option("-y, --yes", "Accept all defaults (non-interactive)").option("-f, --force", "Overwrite existing .paradigm config").action(async (path2, options) => {
|