@a-company/paradigm 5.4.0 → 5.6.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/{agent-loader-SJPJJS33.js → agent-loader-DBF4OARL.js} +1 -1
- package/dist/{chunk-MP73YDXF.js → chunk-5EWAQHFY.js} +47 -2
- package/dist/{chunk-ICSLIPUS.js → chunk-B2RC3HEB.js} +17 -9
- package/dist/{chunk-A2L4TSLZ.js → chunk-ITPJJIHG.js} +6 -3
- package/dist/chunk-SDDCVUCV.js +106 -0
- package/dist/{chunk-7HRBT23N.js → chunk-SU3WDCRR.js} +10 -1
- package/dist/mcp.js +194 -44
- package/dist/{nomination-engine-HDWMN4IO.js → nomination-engine-LPLCCDW2.js} +2 -2
- package/dist/{plugin-update-checker-ELOEEQYS.js → plugin-update-checker-KRRSGXMV.js} +1 -1
- package/dist/{reindex-65H4WULU.js → reindex-J5SEDVTT.js} +2 -1
- package/dist/session-work-log-KDOH4GER.js +20 -0
- package/dist/university-content/courses/para-601.json +170 -141
- package/dist/university-ui/assets/{index-C6bH_6xu.js → index-DxZooszP.js} +2 -2
- package/dist/university-ui/assets/{index-C6bH_6xu.js.map → index-DxZooszP.js.map} +1 -1
- package/dist/university-ui/index.html +1 -1
- package/package.json +1 -1
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import * as fs from "fs";
|
|
5
5
|
import * as path from "path";
|
|
6
6
|
import * as os from "os";
|
|
7
|
+
import * as crypto from "crypto";
|
|
7
8
|
import { exec } from "child_process";
|
|
8
9
|
var CLAUDE_PLUGINS_DIR = path.join(os.homedir(), ".claude", "plugins");
|
|
9
10
|
var CHECK_STATE_PATH = path.join(os.homedir(), ".paradigm", "plugin-update-check.json");
|
|
@@ -40,6 +41,39 @@ function isThrottled() {
|
|
|
40
41
|
const elapsed = Date.now() - new Date(state.lastCheck).getTime();
|
|
41
42
|
return elapsed < THROTTLE_HOURS * 3600 * 1e3;
|
|
42
43
|
}
|
|
44
|
+
function computePluginContentHash(pluginDir) {
|
|
45
|
+
const hash = crypto.createHash("sha256");
|
|
46
|
+
const relevantExts = /* @__PURE__ */ new Set([".md", ".json", ".sh", ".yaml", ".yml", ".ts", ".js"]);
|
|
47
|
+
const skipDirs = /* @__PURE__ */ new Set([".git", "node_modules", ".cache"]);
|
|
48
|
+
function walkDir(dir) {
|
|
49
|
+
let entries;
|
|
50
|
+
try {
|
|
51
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
52
|
+
} catch {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
entries.sort((a, b) => a.name.localeCompare(b.name));
|
|
56
|
+
for (const entry of entries) {
|
|
57
|
+
if (skipDirs.has(entry.name)) continue;
|
|
58
|
+
const fullPath = path.join(dir, entry.name);
|
|
59
|
+
if (entry.isDirectory()) {
|
|
60
|
+
walkDir(fullPath);
|
|
61
|
+
} else if (entry.isFile()) {
|
|
62
|
+
const ext = path.extname(entry.name).toLowerCase();
|
|
63
|
+
if (relevantExts.has(ext)) {
|
|
64
|
+
try {
|
|
65
|
+
const content = fs.readFileSync(fullPath, "utf8");
|
|
66
|
+
const relPath = path.relative(pluginDir, fullPath);
|
|
67
|
+
hash.update(relPath + "\0" + content);
|
|
68
|
+
} catch {
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
walkDir(pluginDir);
|
|
75
|
+
return hash.digest("hex").slice(0, 12);
|
|
76
|
+
}
|
|
43
77
|
function discoverPlugins() {
|
|
44
78
|
const plugins = [];
|
|
45
79
|
const marketplacesDir = path.join(CLAUDE_PLUGINS_DIR, "marketplaces");
|
|
@@ -114,7 +148,9 @@ function discoverPlugins() {
|
|
|
114
148
|
installedVersion,
|
|
115
149
|
installedSha,
|
|
116
150
|
marketplacePath,
|
|
117
|
-
localVersion
|
|
151
|
+
localVersion,
|
|
152
|
+
pluginSourceDir: path.join(pluginsSubdir, pluginName),
|
|
153
|
+
pluginCacheDir: fs.existsSync(pluginCacheDir) && installedVersion !== "unknown" ? path.join(pluginCacheDir, installedVersion) : ""
|
|
118
154
|
});
|
|
119
155
|
}
|
|
120
156
|
}
|
|
@@ -140,6 +176,9 @@ async function checkPlugin(plugin) {
|
|
|
140
176
|
}
|
|
141
177
|
const hasRemoteUpdate = remoteSha !== null && remoteSha !== localSha;
|
|
142
178
|
const hasCacheStale = plugin.localVersion !== plugin.installedVersion && plugin.installedVersion !== "unknown";
|
|
179
|
+
const marketplaceContentHash = computePluginContentHash(plugin.pluginSourceDir);
|
|
180
|
+
const cachedContentHash = plugin.pluginCacheDir ? computePluginContentHash(plugin.pluginCacheDir) : "";
|
|
181
|
+
const hasContentDrift = cachedContentHash !== "" && marketplaceContentHash !== cachedContentHash;
|
|
143
182
|
return {
|
|
144
183
|
repo: plugin.repo,
|
|
145
184
|
plugin: plugin.plugin,
|
|
@@ -149,7 +188,10 @@ async function checkPlugin(plugin) {
|
|
|
149
188
|
remoteSha,
|
|
150
189
|
marketplacePath: plugin.marketplacePath,
|
|
151
190
|
hasRemoteUpdate,
|
|
152
|
-
hasCacheStale
|
|
191
|
+
hasCacheStale: hasCacheStale || hasContentDrift,
|
|
192
|
+
marketplaceContentHash,
|
|
193
|
+
cachedContentHash,
|
|
194
|
+
hasContentDrift
|
|
153
195
|
};
|
|
154
196
|
}
|
|
155
197
|
function getPluginUpdateNotice() {
|
|
@@ -168,6 +210,9 @@ function getPluginUpdateNotice() {
|
|
|
168
210
|
lines.push(` - ${r.plugin} (${r.repo}): ${versionInfo}`);
|
|
169
211
|
pullCmds.push(`git -C ${r.marketplacePath} pull origin main`);
|
|
170
212
|
reinstallCmds.push(`/plugin marketplace add ${r.repo}`);
|
|
213
|
+
} else if (r.hasContentDrift) {
|
|
214
|
+
lines.push(` - ${r.plugin} (${r.repo}): content changed (hash ${r.cachedContentHash} \u2192 ${r.marketplaceContentHash}, reinstall needed)`);
|
|
215
|
+
reinstallCmds.push(`/plugin marketplace add ${r.repo}`);
|
|
171
216
|
} else if (r.hasCacheStale) {
|
|
172
217
|
lines.push(` - ${r.plugin} (${r.repo}): ${r.installedVersion} \u2192 ${r.localVersion} (reinstall needed)`);
|
|
173
218
|
reinstallCmds.push(`/plugin marketplace add ${r.repo}`);
|
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
loadAgentProfile,
|
|
5
5
|
loadAllAgentProfiles,
|
|
6
6
|
saveAgentProfile
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-ITPJJIHG.js";
|
|
8
8
|
import {
|
|
9
9
|
init_journal_loader,
|
|
10
10
|
journal_loader_exports
|
|
@@ -686,7 +686,7 @@ function loadDebates(rootDir) {
|
|
|
686
686
|
return [];
|
|
687
687
|
}
|
|
688
688
|
}
|
|
689
|
-
function engageNomination(rootDir, nominationId, response) {
|
|
689
|
+
function engageNomination(rootDir, nominationId, response, reason) {
|
|
690
690
|
const filePath = getNominationsPath(rootDir);
|
|
691
691
|
if (!fs4.existsSync(filePath)) return false;
|
|
692
692
|
try {
|
|
@@ -699,6 +699,7 @@ function engageNomination(rootDir, nominationId, response) {
|
|
|
699
699
|
if (nom.id === nominationId) {
|
|
700
700
|
nom.engaged = true;
|
|
701
701
|
nom.response = response;
|
|
702
|
+
if (reason) nom.reason = reason;
|
|
702
703
|
found = true;
|
|
703
704
|
return JSON.stringify(nom);
|
|
704
705
|
}
|
|
@@ -847,8 +848,12 @@ function adjustAttentionFromFeedback(rootDir, agentId) {
|
|
|
847
848
|
return { adjusted: false, oldThreshold: 0.6, newThreshold: 0.6, reason: "No attention config" };
|
|
848
849
|
}
|
|
849
850
|
const oldThreshold = profile.attention.threshold ?? 0.6;
|
|
850
|
-
const
|
|
851
|
-
const
|
|
851
|
+
const STALE_THRESHOLD_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
852
|
+
const allNominations = loadNominations(rootDir, { agent: agentId });
|
|
853
|
+
const active = allNominations.filter(
|
|
854
|
+
(n) => n.engaged || Date.now() - new Date(n.timestamp).getTime() < STALE_THRESHOLD_MS
|
|
855
|
+
);
|
|
856
|
+
const engaged = active.filter((n) => n.engaged);
|
|
852
857
|
if (engaged.length < 5) {
|
|
853
858
|
return { adjusted: false, oldThreshold, newThreshold: oldThreshold, reason: `Insufficient data (${engaged.length}/5 engaged nominations)` };
|
|
854
859
|
}
|
|
@@ -882,7 +887,11 @@ function adjustAttentionFromFeedback(rootDir, agentId) {
|
|
|
882
887
|
return { adjusted: true, oldThreshold, newThreshold, reason };
|
|
883
888
|
}
|
|
884
889
|
function getNominationStats(rootDir, agentId) {
|
|
885
|
-
const
|
|
890
|
+
const STALE_THRESHOLD_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
891
|
+
const allNominations = loadNominations(rootDir, { agent: agentId });
|
|
892
|
+
const nominations = allNominations.filter(
|
|
893
|
+
(n) => n.engaged || Date.now() - new Date(n.timestamp).getTime() < STALE_THRESHOLD_MS
|
|
894
|
+
);
|
|
886
895
|
const accepted = nominations.filter((n) => n.response === "accepted").length;
|
|
887
896
|
const dismissed = nominations.filter((n) => n.response === "dismissed").length;
|
|
888
897
|
const deferred = nominations.filter((n) => n.response === "deferred").length;
|
|
@@ -987,10 +996,9 @@ function autoPromoteJournalEntries(rootDir, agentId) {
|
|
|
987
996
|
} catch {
|
|
988
997
|
return { promoted: 0, entries: [] };
|
|
989
998
|
}
|
|
990
|
-
const
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
});
|
|
999
|
+
const patternEntries = loadJournalEntries(agentId, { trigger: "pattern_discovered", limit: 100 });
|
|
1000
|
+
const feedbackEntries = loadJournalEntries(agentId, { trigger: "human_feedback", limit: 100 });
|
|
1001
|
+
const journal = [...patternEntries, ...feedbackEntries];
|
|
994
1002
|
const promoted = [];
|
|
995
1003
|
for (const entry of journal) {
|
|
996
1004
|
if (entry.promoted_to_notebook) continue;
|
|
@@ -13,21 +13,24 @@ var init_agents = __esm({
|
|
|
13
13
|
builder: { style: "rapid", risk: "balanced", verbosity: "concise" },
|
|
14
14
|
tester: { style: "methodical", risk: "conservative", verbosity: "concise" },
|
|
15
15
|
reviewer: { style: "deliberate", risk: "conservative", verbosity: "detailed" },
|
|
16
|
-
security: { style: "methodical", risk: "conservative", verbosity: "detailed" }
|
|
16
|
+
security: { style: "methodical", risk: "conservative", verbosity: "detailed" },
|
|
17
|
+
documentor: { style: "methodical", risk: "conservative", verbosity: "concise" }
|
|
17
18
|
};
|
|
18
19
|
DEFAULT_ATTENTION = {
|
|
19
20
|
architect: { symbols: ["$*", "#*"], concepts: ["architecture", "design", "pattern", "refactor"], signals: [{ type: "flow-modified" }, { type: "compliance-violation" }], threshold: 0.5 },
|
|
20
21
|
builder: { paths: ["src/**", "lib/**", "packages/**"], signals: [{ type: "file-modified" }, { type: "error-encountered" }], threshold: 0.7 },
|
|
21
22
|
reviewer: { concepts: ["code quality", "bug", "smell", "convention"], signals: [{ type: "compliance-violation" }], threshold: 0.6 },
|
|
22
23
|
tester: { paths: ["**/*.test.*", "**/*.spec.*"], concepts: ["test", "coverage", "assertion"], signals: [{ type: "error-encountered" }, { type: "test-result" }], threshold: 0.5 },
|
|
23
|
-
security: { symbols: ["^*", "#*-auth", "#*-middleware"], paths: ["auth/**", "middleware/**", "guards/**"], concepts: ["permission", "JWT", "session", "RBAC", "XSS", "injection"], signals: [{ type: "gate-added" }, { type: "route-created" }, { type: "gate-checked" }, { type: "compliance-violation" }], threshold: 0.4 }
|
|
24
|
+
security: { symbols: ["^*", "#*-auth", "#*-middleware"], paths: ["auth/**", "middleware/**", "guards/**"], concepts: ["permission", "JWT", "session", "RBAC", "XSS", "injection"], signals: [{ type: "gate-added" }, { type: "route-created" }, { type: "gate-checked" }, { type: "compliance-violation" }], threshold: 0.4 },
|
|
25
|
+
documentor: { paths: ["**/.purpose", "**/portal.yaml", ".paradigm/**"], concepts: ["purpose", "portal", "symbol", "documentation", "component", "gate", "flow"], signals: [{ type: "file-modified" }, { type: "compliance-violation" }, { type: "work-completed" }], threshold: 0.3 }
|
|
24
26
|
};
|
|
25
27
|
DEFAULT_COLLABORATION = {
|
|
26
28
|
architect: { stance: "lead", debate: { will_challenge: true, evidence_required: true, escalate_to_human: true } },
|
|
27
29
|
builder: { stance: "supportive", with: { architect: { stance: "supportive", can_contradict: false } } },
|
|
28
30
|
reviewer: { stance: "advisory", debate: { will_challenge: true, evidence_required: true, escalate_to_human: true } },
|
|
29
31
|
tester: { stance: "supportive", debate: { will_challenge: false, evidence_required: true, escalate_to_human: false } },
|
|
30
|
-
security: { stance: "advisory", with: { architect: { stance: "peer", can_contradict: true }, builder: { stance: "advisory", review_output: true } }, debate: { will_challenge: true, evidence_required: true, escalate_to_human: true } }
|
|
32
|
+
security: { stance: "advisory", with: { architect: { stance: "peer", can_contradict: true }, builder: { stance: "advisory", review_output: true } }, debate: { will_challenge: true, evidence_required: true, escalate_to_human: true } },
|
|
33
|
+
documentor: { stance: "supportive", with: { architect: { stance: "supportive" }, builder: { stance: "supportive" }, reviewer: { stance: "supportive" }, security: { stance: "supportive" } }, debate: { will_challenge: false, evidence_required: false, escalate_to_human: false } }
|
|
31
34
|
};
|
|
32
35
|
}
|
|
33
36
|
});
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
__esm,
|
|
4
|
+
__export
|
|
5
|
+
} from "./chunk-7N7GSU6K.js";
|
|
6
|
+
|
|
7
|
+
// ../paradigm-mcp/src/utils/session-work-log.ts
|
|
8
|
+
var session_work_log_exports = {};
|
|
9
|
+
__export(session_work_log_exports, {
|
|
10
|
+
appendSessionWorkEntry: () => appendSessionWorkEntry,
|
|
11
|
+
clearSessionWorkLog: () => clearSessionWorkLog,
|
|
12
|
+
getAgentEntries: () => getAgentEntries,
|
|
13
|
+
getAgentVerdicts: () => getAgentVerdicts,
|
|
14
|
+
getContributingAgents: () => getContributingAgents,
|
|
15
|
+
readSessionWorkLog: () => readSessionWorkLog
|
|
16
|
+
});
|
|
17
|
+
import * as fs from "fs";
|
|
18
|
+
import * as path from "path";
|
|
19
|
+
function appendSessionWorkEntry(rootDir, entry) {
|
|
20
|
+
try {
|
|
21
|
+
const filePath = path.join(rootDir, SESSION_LOG_FILE);
|
|
22
|
+
const dir = path.dirname(filePath);
|
|
23
|
+
if (!fs.existsSync(dir)) {
|
|
24
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
25
|
+
}
|
|
26
|
+
if (fs.existsSync(filePath)) {
|
|
27
|
+
const content = fs.readFileSync(filePath, "utf8");
|
|
28
|
+
const lineCount = content.trim().split("\n").filter((l) => l.trim()).length;
|
|
29
|
+
if (lineCount >= MAX_ENTRIES) return;
|
|
30
|
+
}
|
|
31
|
+
const line = JSON.stringify(entry) + "\n";
|
|
32
|
+
fs.appendFileSync(filePath, line, "utf8");
|
|
33
|
+
} catch {
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function readSessionWorkLog(rootDir) {
|
|
37
|
+
try {
|
|
38
|
+
const filePath = path.join(rootDir, SESSION_LOG_FILE);
|
|
39
|
+
if (!fs.existsSync(filePath)) return [];
|
|
40
|
+
return fs.readFileSync(filePath, "utf8").trim().split("\n").filter((line) => line.trim()).map((line) => {
|
|
41
|
+
try {
|
|
42
|
+
return JSON.parse(line);
|
|
43
|
+
} catch {
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
}).filter((e) => e !== null);
|
|
47
|
+
} catch {
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function clearSessionWorkLog(rootDir) {
|
|
52
|
+
try {
|
|
53
|
+
const filePath = path.join(rootDir, SESSION_LOG_FILE);
|
|
54
|
+
if (fs.existsSync(filePath)) {
|
|
55
|
+
fs.writeFileSync(filePath, "", "utf8");
|
|
56
|
+
}
|
|
57
|
+
} catch {
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
function getContributingAgents(rootDir) {
|
|
61
|
+
const entries = readSessionWorkLog(rootDir);
|
|
62
|
+
const agents = /* @__PURE__ */ new Set();
|
|
63
|
+
for (const entry of entries) {
|
|
64
|
+
if (entry.agent) agents.add(entry.agent);
|
|
65
|
+
}
|
|
66
|
+
return Array.from(agents);
|
|
67
|
+
}
|
|
68
|
+
function getAgentEntries(rootDir, agentId) {
|
|
69
|
+
return readSessionWorkLog(rootDir).filter((e) => e.agent === agentId);
|
|
70
|
+
}
|
|
71
|
+
function getAgentVerdicts(rootDir, agentId) {
|
|
72
|
+
const entries = getAgentEntries(rootDir, agentId);
|
|
73
|
+
const contributions = entries.filter((e) => e.type === "agent-contribution");
|
|
74
|
+
const verdicts = entries.filter((e) => e.type === "user-verdict");
|
|
75
|
+
const pairs = [];
|
|
76
|
+
for (const contrib of contributions) {
|
|
77
|
+
pairs.push({ contribution: contrib });
|
|
78
|
+
}
|
|
79
|
+
for (const verdict of verdicts) {
|
|
80
|
+
const unpaired = pairs.find((p) => !p.verdict && p.contribution);
|
|
81
|
+
if (unpaired) {
|
|
82
|
+
unpaired.verdict = verdict;
|
|
83
|
+
} else {
|
|
84
|
+
pairs.push({ verdict });
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return pairs;
|
|
88
|
+
}
|
|
89
|
+
var SESSION_LOG_FILE, MAX_ENTRIES;
|
|
90
|
+
var init_session_work_log = __esm({
|
|
91
|
+
"../paradigm-mcp/src/utils/session-work-log.ts"() {
|
|
92
|
+
SESSION_LOG_FILE = ".paradigm/events/session-log.jsonl";
|
|
93
|
+
MAX_ENTRIES = 200;
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
export {
|
|
98
|
+
appendSessionWorkEntry,
|
|
99
|
+
readSessionWorkLog,
|
|
100
|
+
clearSessionWorkLog,
|
|
101
|
+
getContributingAgents,
|
|
102
|
+
getAgentEntries,
|
|
103
|
+
getAgentVerdicts,
|
|
104
|
+
session_work_log_exports,
|
|
105
|
+
init_session_work_log
|
|
106
|
+
};
|
|
@@ -4,6 +4,10 @@ import {
|
|
|
4
4
|
checkIntegrity,
|
|
5
5
|
checkPurposeHealth
|
|
6
6
|
} from "./chunk-L27I3CPZ.js";
|
|
7
|
+
import {
|
|
8
|
+
init_session_work_log,
|
|
9
|
+
session_work_log_exports
|
|
10
|
+
} from "./chunk-SDDCVUCV.js";
|
|
7
11
|
import {
|
|
8
12
|
init_lore_loader,
|
|
9
13
|
loadLoreEntries,
|
|
@@ -2113,6 +2117,11 @@ var SessionTracker = class {
|
|
|
2113
2117
|
*/
|
|
2114
2118
|
setRootDir(rootDir) {
|
|
2115
2119
|
this.rootDir = rootDir;
|
|
2120
|
+
try {
|
|
2121
|
+
const { clearSessionWorkLog } = (init_session_work_log(), __toCommonJS(session_work_log_exports));
|
|
2122
|
+
clearSessionWorkLog(rootDir);
|
|
2123
|
+
} catch {
|
|
2124
|
+
}
|
|
2116
2125
|
}
|
|
2117
2126
|
createNewSession() {
|
|
2118
2127
|
return {
|
|
@@ -3223,7 +3232,7 @@ async function buildRecoveryPreamble(rootDir) {
|
|
|
3223
3232
|
} catch {
|
|
3224
3233
|
}
|
|
3225
3234
|
try {
|
|
3226
|
-
const { loadNominations } = await import("./nomination-engine-
|
|
3235
|
+
const { loadNominations } = await import("./nomination-engine-LPLCCDW2.js");
|
|
3227
3236
|
const urgent = loadNominations(rootDir, { pending_only: true }).filter((n) => n.urgency === "critical" || n.urgency === "high");
|
|
3228
3237
|
if (urgent.length > 0) {
|
|
3229
3238
|
lines.push("");
|