@a-company/paradigm 3.1.5 → 3.5.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-CWZNCGZX.js → accept-orchestration-DIGPJVUR.js} +6 -5
- package/dist/{aggregate-W7Q6VIM2.js → aggregate-V4KPR3RW.js} +2 -2
- package/dist/{beacon-B47XSTL7.js → beacon-XRXL5KZB.js} +2 -2
- package/dist/{chunk-4LGLU2LO.js → chunk-2E2RTBSM.js} +533 -182
- package/dist/{chunk-YCLN7WXV.js → chunk-2QNZ6PVD.js} +219 -35
- package/dist/{chunk-UM54F7G5.js → chunk-4N6AYEEA.js} +1 -1
- package/dist/{chunk-MVXJVRFI.js → chunk-5TUAVVIG.js} +65 -1
- package/dist/{chunk-5C4SGQKH.js → chunk-6P4IFIK2.js} +4 -2
- package/dist/{chunk-WS5KM7OL.js → chunk-6RNYVBSG.js} +1 -1
- package/dist/{chunk-N6PJAPDE.js → chunk-AK5M6KJB.js} +18 -0
- package/dist/{chunk-VZ7CXFRZ.js → chunk-CRICL4FQ.js} +1004 -17
- package/dist/{chunk-MC7XC7XQ.js → chunk-GZDFVP2N.js} +20 -13
- package/dist/chunk-HPC3JAUP.js +42 -0
- package/dist/chunk-IRVA7NKV.js +657 -0
- package/dist/{chunk-ZPN7MXRA.js → chunk-KFHK6EBI.js} +184 -1
- package/dist/{chunk-UUZ2DMG5.js → chunk-KWDTBXP2.js} +1 -1
- package/dist/{chunk-DRUDZKIT.js → chunk-M2XMTJHQ.js} +693 -70
- package/dist/{chunk-PW2EXJQT.js → chunk-MRENOFTR.js} +24 -1
- package/dist/{chunk-QS36NGWV.js → chunk-QHJGB5TV.js} +1 -1
- package/dist/chunk-UI3XXVJ6.js +449 -0
- package/dist/{chunk-AD2LSCHB.js → chunk-Y4XZWCHK.js} +40 -74
- package/dist/{constellation-K3CIQCHI.js → constellation-GNK5DIMH.js} +2 -2
- package/dist/{cost-AEK6R7HK.js → cost-AGO5N7DD.js} +1 -1
- package/dist/{cursorrules-KI5QWHIX.js → cursorrules-LQFA7M62.js} +2 -2
- package/dist/{delete-W67IVTLJ.js → delete-3YXAJ5AA.js} +12 -1
- package/dist/{diff-AJJ5H6HV.js → diff-J6C5IHPV.js} +6 -5
- package/dist/{dist-2F7NO4H4-KSL6SJIO.js → dist-AG5JNIZU-XSEZ2LLK.js} +28 -3
- package/dist/dist-JOHRYQUA.js +7294 -0
- package/dist/{dist-NHJQVVUW.js → dist-Q6SAZI7X.js} +2 -2
- package/dist/{dist-GPQ4LAY3.js → dist-YP2CO4TG.js} +24 -6
- package/dist/{doctor-JBIV5PMN.js → doctor-TQYRF7KK.js} +2 -2
- package/dist/{edit-Y7XPYSMK.js → edit-EOMPXOG5.js} +1 -1
- package/dist/flow-7JUH6D4H.js +185 -0
- package/dist/global-AXILUM5X.js +136 -0
- package/dist/{habits-FA65W77Y.js → habits-CHP4EW5H.js} +234 -5
- package/dist/{hooks-JKWO44WH.js → hooks-DLZEYHI3.js} +1 -1
- package/dist/index.js +125 -100
- package/dist/{lint-HXKTWRNO.js → lint-N4LMMEXH.js} +141 -1
- package/dist/{list-R3QWW4SC.js → list-JKBJ7ESH.js} +1 -1
- package/dist/mcp.js +9273 -6515
- package/dist/{orchestrate-4ZH5GUQH.js → orchestrate-FAV64G2R.js} +6 -5
- package/dist/{probe-OYCP4JYG.js → probe-X3J2JX62.js} +18 -3
- package/dist/{promote-E6NBZ3BK.js → promote-HZH5E5CO.js} +1 -1
- package/dist/{providers-4PGPZEWP.js → providers-NQ67LO2Z.js} +1 -1
- package/dist/{record-OHQNWOUP.js → record-EECZ3E4I.js} +1 -1
- package/dist/{remember-6VZ74B7E.js → remember-3KJZGDUG.js} +1 -1
- package/dist/{review-RUHX25A5.js → review-BF26ILZB.js} +1 -1
- package/dist/{ripple-SBQOSTZD.js → ripple-JIUAMBLA.js} +2 -2
- package/dist/sentinel-ZTL224IG.js +63 -0
- package/dist/{server-MV4HNFVF.js → server-MZBYDXJY.js} +4193 -9
- package/dist/{setup-DF4F3ICN.js → setup-363IB6MO.js} +1 -1
- package/dist/{setup-JHBPZAG7.js → setup-UKJ3VGHI.js} +4 -4
- package/dist/{shift-2LQFQP4P.js → shift-KDVYB6CR.js} +16 -13
- package/dist/{show-WTOJXUTN.js → show-SAMTXEHG.js} +1 -1
- package/dist/{snapshot-GTVPRYZG.js → snapshot-KCMONZAO.js} +2 -2
- package/dist/{spawn-BJRQA2NR.js → spawn-EO7B2UM3.js} +2 -2
- package/dist/{summary-5SBFO7QK.js → summary-E2PU4UN2.js} +3 -3
- package/dist/{switch-6EANJ7O6.js → switch-CC2KACXO.js} +1 -1
- package/dist/{sync-5KSTPJ4B.js → sync-5VJPZQNX.js} +2 -2
- package/dist/sync-llms-7QDA3ZWC.js +166 -0
- package/dist/{team-NWP2KJAB.js → team-6CCNANKE.js} +7 -6
- package/dist/{test-MA5TWJQV.js → test-DK2RWLTK.js} +91 -8
- package/dist/{thread-JCJVRUQR.js → thread-RNSLADXN.js} +18 -2
- package/dist/{timeline-P7BARFLI.js → timeline-TJDVVVA3.js} +1 -1
- package/dist/{triage-TBIWJA6R.js → triage-PXMU3RWV.js} +2 -2
- package/dist/university-content/courses/para-101.json +2 -1
- package/dist/university-content/courses/para-201.json +102 -3
- package/dist/university-content/courses/para-301.json +14 -11
- package/dist/university-content/courses/para-401.json +57 -3
- package/dist/university-content/courses/para-501.json +204 -6
- package/dist/university-content/plsat/v3.0.json +808 -3
- package/dist/university-content/reference.json +270 -0
- package/dist/{upgrade-TIYFQYPO.js → upgrade-RBSE4M6I.js} +1 -1
- package/dist/{validate-QEEY6KFS.js → validate-2LTHHORX.js} +1 -1
- package/dist/{watch-4LT4O6K7.js → watch-NBPOMOEX.js} +76 -0
- package/dist/{watch-2XEYUH43.js → watch-PAEH6MOG.js} +1 -1
- package/package.json +1 -1
- package/dist/chunk-GWM2WRXL.js +0 -1095
- package/dist/sentinel-WB7GIK4V.js +0 -43
- /package/dist/{chunk-TAP5N3HH.js → chunk-CCG6KYBT.js} +0 -0
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
import {
|
|
3
3
|
cursorrrulesExists,
|
|
4
4
|
writeCursorrules
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-KWDTBXP2.js";
|
|
6
|
+
import "./chunk-AK5M6KJB.js";
|
|
7
7
|
import {
|
|
8
8
|
getDefaultPremiseContent
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-6P4IFIK2.js";
|
|
10
10
|
import {
|
|
11
11
|
getDefaultPurposeContent
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-MRENOFTR.js";
|
|
13
13
|
import "./chunk-IRKUEJVW.js";
|
|
14
14
|
import {
|
|
15
15
|
DEFAULT_CONVENTIONS,
|
|
@@ -1,36 +1,39 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
teamInitCommand
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-4N6AYEEA.js";
|
|
5
|
+
import "./chunk-Y4XZWCHK.js";
|
|
6
6
|
import "./chunk-6QC3YGB6.js";
|
|
7
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-HPC3JAUP.js";
|
|
8
|
+
import "./chunk-6RNYVBSG.js";
|
|
8
9
|
import "./chunk-PBHIFAL4.js";
|
|
9
|
-
import "./chunk-
|
|
10
|
+
import "./chunk-CCG6KYBT.js";
|
|
10
11
|
import {
|
|
11
12
|
agentsConfigured
|
|
12
13
|
} from "./chunk-PMXRGPRQ.js";
|
|
13
14
|
import {
|
|
14
15
|
hooksInstallCommand
|
|
15
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-M2XMTJHQ.js";
|
|
16
17
|
import {
|
|
17
|
-
indexCommand,
|
|
18
18
|
initCommand
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-IRVA7NKV.js";
|
|
20
|
+
import {
|
|
21
|
+
indexCommand
|
|
22
|
+
} from "./chunk-UI3XXVJ6.js";
|
|
20
23
|
import {
|
|
21
24
|
detectDiscipline
|
|
22
25
|
} from "./chunk-CHSHON3O.js";
|
|
23
|
-
import "./chunk-
|
|
24
|
-
import "./chunk-
|
|
25
|
-
import "./chunk-
|
|
26
|
+
import "./chunk-AK5M6KJB.js";
|
|
27
|
+
import "./chunk-6P4IFIK2.js";
|
|
28
|
+
import "./chunk-MRENOFTR.js";
|
|
26
29
|
import "./chunk-IRKUEJVW.js";
|
|
27
30
|
import {
|
|
28
31
|
syncCommand
|
|
29
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-QHJGB5TV.js";
|
|
30
33
|
import {
|
|
31
34
|
doctorCommand
|
|
32
|
-
} from "./chunk-
|
|
33
|
-
import "./chunk-
|
|
35
|
+
} from "./chunk-KFHK6EBI.js";
|
|
36
|
+
import "./chunk-2QNZ6PVD.js";
|
|
34
37
|
import {
|
|
35
38
|
log
|
|
36
39
|
} from "./chunk-4NCFWYGG.js";
|
|
@@ -3,8 +3,8 @@ import {
|
|
|
3
3
|
createSnapshot,
|
|
4
4
|
parsePremiseFile,
|
|
5
5
|
serializePremiseFile
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import "./chunk-
|
|
6
|
+
} from "./chunk-6P4IFIK2.js";
|
|
7
|
+
import "./chunk-MRENOFTR.js";
|
|
8
8
|
import "./chunk-IRKUEJVW.js";
|
|
9
9
|
import "./chunk-MO4EEYFW.js";
|
|
10
10
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
AgentSpawner
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-6RNYVBSG.js";
|
|
5
5
|
import "./chunk-PBHIFAL4.js";
|
|
6
6
|
import {
|
|
7
7
|
getBestProvider
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-CCG6KYBT.js";
|
|
9
9
|
import {
|
|
10
10
|
loadAgentsManifest
|
|
11
11
|
} from "./chunk-PMXRGPRQ.js";
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
aggregateFromDirectory
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-6P4IFIK2.js";
|
|
5
|
+
import "./chunk-MRENOFTR.js";
|
|
6
6
|
import "./chunk-IRKUEJVW.js";
|
|
7
7
|
import {
|
|
8
8
|
detectIDE,
|
|
9
9
|
getAdapter
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-2QNZ6PVD.js";
|
|
11
11
|
import "./chunk-YO6DVTL7.js";
|
|
12
12
|
import "./chunk-MO4EEYFW.js";
|
|
13
13
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
syncCommand
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-QHJGB5TV.js";
|
|
5
|
+
import "./chunk-2QNZ6PVD.js";
|
|
6
6
|
import "./chunk-4NCFWYGG.js";
|
|
7
7
|
import "./chunk-YO6DVTL7.js";
|
|
8
8
|
import "./chunk-MO4EEYFW.js";
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
loadParadigmFiles
|
|
4
|
+
} from "./chunk-2QNZ6PVD.js";
|
|
5
|
+
import {
|
|
6
|
+
log
|
|
7
|
+
} from "./chunk-4NCFWYGG.js";
|
|
8
|
+
import "./chunk-YO6DVTL7.js";
|
|
9
|
+
import "./chunk-MO4EEYFW.js";
|
|
10
|
+
|
|
11
|
+
// src/commands/sync-llms.ts
|
|
12
|
+
import * as fs from "fs";
|
|
13
|
+
import * as path from "path";
|
|
14
|
+
import * as yaml from "js-yaml";
|
|
15
|
+
import chalk from "chalk";
|
|
16
|
+
import ora from "ora";
|
|
17
|
+
async function syncLlmsCommand(options) {
|
|
18
|
+
const rootDir = process.cwd();
|
|
19
|
+
const spinner = ora();
|
|
20
|
+
console.log(chalk.blue("\n Paradigm Sync LLMs\n"));
|
|
21
|
+
spinner.start("Loading .paradigm/ configuration...");
|
|
22
|
+
const files = loadParadigmFiles(rootDir);
|
|
23
|
+
if (!files) {
|
|
24
|
+
spinner.fail("No .paradigm/ directory found");
|
|
25
|
+
console.log(chalk.gray("\nRun `paradigm init` to initialize Paradigm in this project.\n"));
|
|
26
|
+
log.command("sync-llms").error("Missing .paradigm/ directory");
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
spinner.succeed(`Loaded configuration for ${chalk.cyan(files.projectName)}`);
|
|
30
|
+
log.command("sync-llms").debug("Configuration loaded", { projectName: files.projectName });
|
|
31
|
+
spinner.start("Reading navigator.yaml...");
|
|
32
|
+
let navigator = null;
|
|
33
|
+
const navigatorPath = path.join(rootDir, ".paradigm", "navigator.yaml");
|
|
34
|
+
if (fs.existsSync(navigatorPath)) {
|
|
35
|
+
try {
|
|
36
|
+
const content2 = fs.readFileSync(navigatorPath, "utf8");
|
|
37
|
+
navigator = yaml.load(content2);
|
|
38
|
+
spinner.succeed("Loaded navigator.yaml");
|
|
39
|
+
} catch {
|
|
40
|
+
spinner.warn("Could not parse navigator.yaml, skipping key files section");
|
|
41
|
+
log.command("sync-llms").warn("Failed to parse navigator.yaml");
|
|
42
|
+
}
|
|
43
|
+
} else {
|
|
44
|
+
spinner.info("No navigator.yaml found, skipping key files section");
|
|
45
|
+
}
|
|
46
|
+
let flows = null;
|
|
47
|
+
const flowsPath = path.join(rootDir, ".paradigm", "flows.yaml");
|
|
48
|
+
if (fs.existsSync(flowsPath)) {
|
|
49
|
+
try {
|
|
50
|
+
const content2 = fs.readFileSync(flowsPath, "utf8");
|
|
51
|
+
flows = yaml.load(content2);
|
|
52
|
+
} catch {
|
|
53
|
+
log.command("sync-llms").warn("Failed to parse flows.yaml");
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
let portal = null;
|
|
57
|
+
const portalPath = path.join(rootDir, "portal.yaml");
|
|
58
|
+
if (fs.existsSync(portalPath)) {
|
|
59
|
+
try {
|
|
60
|
+
const content2 = fs.readFileSync(portalPath, "utf8");
|
|
61
|
+
portal = yaml.load(content2);
|
|
62
|
+
} catch {
|
|
63
|
+
log.command("sync-llms").warn("Failed to parse portal.yaml");
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
spinner.start("Generating llms.txt...");
|
|
67
|
+
const content = generateLlmsTxt(files, navigator, flows, portal);
|
|
68
|
+
const outputPath = options.output ? path.resolve(rootDir, options.output) : path.join(rootDir, "llms.txt");
|
|
69
|
+
try {
|
|
70
|
+
fs.writeFileSync(outputPath, content, "utf8");
|
|
71
|
+
spinner.succeed(chalk.green(`Generated llms.txt`));
|
|
72
|
+
console.log(chalk.gray(`
|
|
73
|
+
Path: ${path.relative(rootDir, outputPath)}`));
|
|
74
|
+
console.log("");
|
|
75
|
+
log.command("sync-llms").success("llms.txt generated", { path: outputPath });
|
|
76
|
+
} catch (error) {
|
|
77
|
+
spinner.fail(chalk.red(`Failed to write llms.txt`));
|
|
78
|
+
log.command("sync-llms").error("Write failed", { error: error.message });
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function generateLlmsTxt(files, navigator, flows, portal) {
|
|
83
|
+
const { config, projectName } = files;
|
|
84
|
+
const sections = [];
|
|
85
|
+
sections.push(`# ${config.project || projectName}`);
|
|
86
|
+
const overview = config["agent-guidelines"]?.overview?.trim();
|
|
87
|
+
if (overview) {
|
|
88
|
+
sections.push(`> ${overview.replace(/\n/g, "\n> ")}`);
|
|
89
|
+
}
|
|
90
|
+
const symbolSystem = config["symbol-system"];
|
|
91
|
+
if (symbolSystem) {
|
|
92
|
+
const symbolLines = ["## Symbols", ""];
|
|
93
|
+
symbolLines.push("| Prefix | Name | Description |");
|
|
94
|
+
symbolLines.push("|--------|------|-------------|");
|
|
95
|
+
for (const [prefix, def] of Object.entries(symbolSystem)) {
|
|
96
|
+
if (["#", "$", "^", "!", "~"].includes(prefix)) {
|
|
97
|
+
symbolLines.push(`| \`${prefix}\` | ${def.name} | ${def.description} |`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
sections.push(symbolLines.join("\n"));
|
|
101
|
+
}
|
|
102
|
+
if (navigator?.key_files) {
|
|
103
|
+
const keyFileLines = ["## Key Files", ""];
|
|
104
|
+
for (const [category, paths] of Object.entries(navigator.key_files)) {
|
|
105
|
+
if (paths && paths.length > 0) {
|
|
106
|
+
keyFileLines.push(`### ${category.charAt(0).toUpperCase() + category.slice(1)}`);
|
|
107
|
+
keyFileLines.push("");
|
|
108
|
+
for (const p of paths) {
|
|
109
|
+
keyFileLines.push(`- \`${p}\``);
|
|
110
|
+
}
|
|
111
|
+
keyFileLines.push("");
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (keyFileLines.length > 2) {
|
|
115
|
+
sections.push(keyFileLines.join("\n").trimEnd());
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (flows?.flows && Object.keys(flows.flows).length > 0) {
|
|
119
|
+
const flowLines = ["## Flows", ""];
|
|
120
|
+
for (const [id, flow] of Object.entries(flows.flows)) {
|
|
121
|
+
const name = flow.name || flow.description || id;
|
|
122
|
+
const trigger = flow.trigger ? ` (trigger: \`${flow.trigger}\`)` : "";
|
|
123
|
+
flowLines.push(`- **$${id}**: ${name}${trigger}`);
|
|
124
|
+
}
|
|
125
|
+
sections.push(flowLines.join("\n"));
|
|
126
|
+
}
|
|
127
|
+
if (portal?.gates && Object.keys(portal.gates).length > 0) {
|
|
128
|
+
const gateLines = ["## Gates", ""];
|
|
129
|
+
gateLines.push("| Gate | Description |");
|
|
130
|
+
gateLines.push("|------|-------------|");
|
|
131
|
+
for (const [id, gate] of Object.entries(portal.gates)) {
|
|
132
|
+
const desc = gate.description || "";
|
|
133
|
+
gateLines.push(`| \`^${id}\` | ${desc} |`);
|
|
134
|
+
}
|
|
135
|
+
if (portal.routes && Object.keys(portal.routes).length > 0) {
|
|
136
|
+
gateLines.push("");
|
|
137
|
+
gateLines.push("### Protected Routes");
|
|
138
|
+
gateLines.push("");
|
|
139
|
+
for (const [route, gates] of Object.entries(portal.routes)) {
|
|
140
|
+
gateLines.push(`- \`${route}\`: ${gates.join(", ")}`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
sections.push(gateLines.join("\n"));
|
|
144
|
+
}
|
|
145
|
+
const conventions = config.conventions;
|
|
146
|
+
if (conventions && conventions.length > 0) {
|
|
147
|
+
const convLines = ["## Conventions", ""];
|
|
148
|
+
for (const conv of conventions) {
|
|
149
|
+
convLines.push(`- ${conv}`);
|
|
150
|
+
}
|
|
151
|
+
sections.push(convLines.join("\n"));
|
|
152
|
+
}
|
|
153
|
+
const furtherReading = [
|
|
154
|
+
"## Further Reading",
|
|
155
|
+
"",
|
|
156
|
+
"- `.paradigm/specs/` - Detailed specifications",
|
|
157
|
+
"- `.paradigm/docs/` - Commands, patterns, troubleshooting",
|
|
158
|
+
"- `CLAUDE.md` - AI agent instructions (Claude Code)",
|
|
159
|
+
"- `AGENTS.md` - Universal agent instructions"
|
|
160
|
+
];
|
|
161
|
+
sections.push(furtherReading.join("\n"));
|
|
162
|
+
return sections.join("\n\n") + "\n";
|
|
163
|
+
}
|
|
164
|
+
export {
|
|
165
|
+
syncLlmsCommand
|
|
166
|
+
};
|
|
@@ -8,15 +8,16 @@ import {
|
|
|
8
8
|
teamModelsCommand,
|
|
9
9
|
teamResetCommand,
|
|
10
10
|
teamStatusCommand
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import "./chunk-
|
|
11
|
+
} from "./chunk-4N6AYEEA.js";
|
|
12
|
+
import "./chunk-Y4XZWCHK.js";
|
|
13
13
|
import "./chunk-6QC3YGB6.js";
|
|
14
|
-
import "./chunk-
|
|
14
|
+
import "./chunk-HPC3JAUP.js";
|
|
15
|
+
import "./chunk-6RNYVBSG.js";
|
|
15
16
|
import "./chunk-PBHIFAL4.js";
|
|
16
|
-
import "./chunk-
|
|
17
|
+
import "./chunk-CCG6KYBT.js";
|
|
17
18
|
import "./chunk-PMXRGPRQ.js";
|
|
18
|
-
import "./chunk-
|
|
19
|
-
import "./chunk-
|
|
19
|
+
import "./chunk-6P4IFIK2.js";
|
|
20
|
+
import "./chunk-MRENOFTR.js";
|
|
20
21
|
import "./chunk-IRKUEJVW.js";
|
|
21
22
|
import "./chunk-5JGJACDU.js";
|
|
22
23
|
import "./chunk-MO4EEYFW.js";
|
|
@@ -831,6 +831,96 @@ var enableValidation = typeof process !== "undefined" ? process.env.PORTAL_VALID
|
|
|
831
831
|
var isTestMode = typeof process !== "undefined" ? process.env.PORTAL_TEST_MODE === "true" : typeof import.meta !== "undefined" && import.meta.env?.VITE_TEST_MODE === "true";
|
|
832
832
|
|
|
833
833
|
// src/commands/portal/test.ts
|
|
834
|
+
function extractPropertiesFromExpression(expr) {
|
|
835
|
+
const propPattern = /\b([a-zA-Z_$][\w$]*(?:\.[a-zA-Z_$][\w$]*)+)/g;
|
|
836
|
+
const matches = /* @__PURE__ */ new Set();
|
|
837
|
+
let match;
|
|
838
|
+
while ((match = propPattern.exec(expr)) !== null) {
|
|
839
|
+
matches.add(match[1]);
|
|
840
|
+
}
|
|
841
|
+
return [...matches];
|
|
842
|
+
}
|
|
843
|
+
function buildEntityFromPath(path4) {
|
|
844
|
+
const parts = path4.split(".");
|
|
845
|
+
const root = {};
|
|
846
|
+
let current = root;
|
|
847
|
+
for (let i = 0; i < parts.length; i++) {
|
|
848
|
+
const part = parts[i];
|
|
849
|
+
if (i === parts.length - 1) {
|
|
850
|
+
current[part] = "test-value";
|
|
851
|
+
} else {
|
|
852
|
+
const next = {};
|
|
853
|
+
current[part] = next;
|
|
854
|
+
current = next;
|
|
855
|
+
}
|
|
856
|
+
}
|
|
857
|
+
return root;
|
|
858
|
+
}
|
|
859
|
+
function deepMerge(target, source) {
|
|
860
|
+
const result = { ...target };
|
|
861
|
+
for (const [key, value] of Object.entries(source)) {
|
|
862
|
+
if (value && typeof value === "object" && !Array.isArray(value) && result[key] && typeof result[key] === "object" && !Array.isArray(result[key])) {
|
|
863
|
+
result[key] = deepMerge(
|
|
864
|
+
result[key],
|
|
865
|
+
value
|
|
866
|
+
);
|
|
867
|
+
} else {
|
|
868
|
+
result[key] = value;
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
return result;
|
|
872
|
+
}
|
|
873
|
+
function generateTestCasesFromLocks(gate) {
|
|
874
|
+
const cases = [];
|
|
875
|
+
if (!gate.locks || gate.locks.length === 0) {
|
|
876
|
+
cases.push({
|
|
877
|
+
name: `${gate.id}: no locks (should pass)`,
|
|
878
|
+
entity: { user: { id: "test-user" } },
|
|
879
|
+
expected: true
|
|
880
|
+
});
|
|
881
|
+
return cases;
|
|
882
|
+
}
|
|
883
|
+
let fullEntity = {};
|
|
884
|
+
for (const lock of gate.locks) {
|
|
885
|
+
for (const key of lock.keys) {
|
|
886
|
+
const paths = extractPropertiesFromExpression(key.expression);
|
|
887
|
+
for (const p of paths) {
|
|
888
|
+
const partial = buildEntityFromPath(p);
|
|
889
|
+
fullEntity = deepMerge(fullEntity, partial);
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
cases.push({
|
|
894
|
+
name: `${gate.id}: entity satisfying all locks (should pass)`,
|
|
895
|
+
entity: fullEntity,
|
|
896
|
+
expected: true
|
|
897
|
+
});
|
|
898
|
+
for (const lock of gate.locks) {
|
|
899
|
+
const lockPaths = [];
|
|
900
|
+
for (const key of lock.keys) {
|
|
901
|
+
lockPaths.push(...extractPropertiesFromExpression(key.expression));
|
|
902
|
+
}
|
|
903
|
+
if (lockPaths.length > 0) {
|
|
904
|
+
const missingEntity = {};
|
|
905
|
+
for (const otherLock of gate.locks) {
|
|
906
|
+
if (otherLock.id === lock.id) continue;
|
|
907
|
+
for (const key of otherLock.keys) {
|
|
908
|
+
const paths = extractPropertiesFromExpression(key.expression);
|
|
909
|
+
for (const p of paths) {
|
|
910
|
+
const partial = buildEntityFromPath(p);
|
|
911
|
+
Object.assign(missingEntity, deepMerge(missingEntity, partial));
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
cases.push({
|
|
916
|
+
name: `${gate.id}: missing lock "${lock.id}" properties (should fail)`,
|
|
917
|
+
entity: gate.locks.length === 1 ? {} : missingEntity,
|
|
918
|
+
expected: false
|
|
919
|
+
});
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
return cases;
|
|
923
|
+
}
|
|
834
924
|
async function gateTestCommand(targetPath, options) {
|
|
835
925
|
const rootDir = targetPath ? path3.resolve(targetPath) : process.cwd();
|
|
836
926
|
const gateConfigPath = path3.join(rootDir, "portal.yaml");
|
|
@@ -896,14 +986,7 @@ async function gateTestCommand(targetPath, options) {
|
|
|
896
986
|
entity: {},
|
|
897
987
|
expected: false
|
|
898
988
|
},
|
|
899
|
-
|
|
900
|
-
name: "Entity with required properties",
|
|
901
|
-
entity: {
|
|
902
|
-
// TODO: Add properties based on gate locks
|
|
903
|
-
user: { id: "test-user" }
|
|
904
|
-
},
|
|
905
|
-
expected: true
|
|
906
|
-
}
|
|
989
|
+
...generateTestCasesFromLocks(gate)
|
|
907
990
|
];
|
|
908
991
|
const result = await validateGateway(options.gate, testCases, client);
|
|
909
992
|
if (result.passed) {
|
|
@@ -5,6 +5,7 @@ import "./chunk-MO4EEYFW.js";
|
|
|
5
5
|
import * as fs from "fs";
|
|
6
6
|
import * as path from "path";
|
|
7
7
|
import chalk from "chalk";
|
|
8
|
+
import * as yaml from "js-yaml";
|
|
8
9
|
var THREAD_TEMPLATE = `# Thread - Session Continuity
|
|
9
10
|
|
|
10
11
|
> Pass context between AI agent sessions. Updated by \`paradigm thread save\`.
|
|
@@ -24,6 +25,21 @@ var THREAD_TEMPLATE = `# Thread - Session Continuity
|
|
|
24
25
|
*Run \`paradigm thread save "message"\` to update*
|
|
25
26
|
*Run \`paradigm thread clear\` to reset*
|
|
26
27
|
`;
|
|
28
|
+
function getThreadTrailMax() {
|
|
29
|
+
try {
|
|
30
|
+
const configPath = path.join(process.cwd(), ".paradigm", "config.yaml");
|
|
31
|
+
if (fs.existsSync(configPath)) {
|
|
32
|
+
const content = fs.readFileSync(configPath, "utf8");
|
|
33
|
+
const config = yaml.load(content);
|
|
34
|
+
const limits = config?.limits;
|
|
35
|
+
if (limits?.threadTrailMax && typeof limits.threadTrailMax === "number") {
|
|
36
|
+
return limits.threadTrailMax;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
} catch {
|
|
40
|
+
}
|
|
41
|
+
return 10;
|
|
42
|
+
}
|
|
27
43
|
function parseThread(content) {
|
|
28
44
|
const data = {
|
|
29
45
|
trail: [],
|
|
@@ -75,7 +91,7 @@ function generateThread(data) {
|
|
|
75
91
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").split(".")[0];
|
|
76
92
|
let trailContent = "_No activity recorded yet_";
|
|
77
93
|
if (data.trail.length > 0) {
|
|
78
|
-
trailContent = data.trail.slice(-
|
|
94
|
+
trailContent = data.trail.slice(-getThreadTrailMax()).map((entry) => `- ${entry.message}`).join("\n");
|
|
79
95
|
}
|
|
80
96
|
let looseEndsContent = "_No pending tasks_";
|
|
81
97
|
if (data.looseEnds.length > 0) {
|
|
@@ -83,7 +99,7 @@ function generateThread(data) {
|
|
|
83
99
|
}
|
|
84
100
|
let breadcrumbsContent = "_No notes yet_";
|
|
85
101
|
if (data.breadcrumbs.length > 0) {
|
|
86
|
-
breadcrumbsContent = data.breadcrumbs.slice(-
|
|
102
|
+
breadcrumbsContent = data.breadcrumbs.slice(-getThreadTrailMax()).map((item) => `- ${item}`).join("\n");
|
|
87
103
|
}
|
|
88
104
|
return THREAD_TEMPLATE.replace("{timestamp}", timestamp).replace("{trail}", trailContent).replace("{looseEnds}", looseEndsContent).replace("{breadcrumbs}", breadcrumbsContent);
|
|
89
105
|
}
|
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
StatsCalculator,
|
|
7
7
|
TimelineBuilder,
|
|
8
8
|
loadAllSeedPatterns
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-2E2RTBSM.js";
|
|
10
10
|
import {
|
|
11
11
|
SentinelStorage
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-CRICL4FQ.js";
|
|
13
13
|
import "./chunk-MO4EEYFW.js";
|
|
14
14
|
|
|
15
15
|
// src/commands/triage/index.ts
|
|
@@ -355,7 +355,8 @@
|
|
|
355
355
|
"config.yaml defines discipline, conventions, and agent preferences",
|
|
356
356
|
"navigator.yaml is generated by 'paradigm scan' for fast symbol lookup",
|
|
357
357
|
"wisdom/ captures team decisions, preferences, and antipatterns",
|
|
358
|
-
"portal.yaml lives at the project root, not inside .paradigm/"
|
|
358
|
+
"portal.yaml lives at the project root, not inside .paradigm/",
|
|
359
|
+
"llms.txt at project root is an LLM-readable project summary — regenerate with 'paradigm sync-llms'"
|
|
359
360
|
],
|
|
360
361
|
"quiz": [
|
|
361
362
|
{
|