@a-company/paradigm 3.24.1 → 3.25.2
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-AAYFKS74.js → accept-orchestration-6EM5EHXA.js} +4 -4
- package/dist/{auto-B22FVSQI.js → auto-24ICVUH4.js} +1 -1
- package/dist/{chunk-EZ6XW6FB.js → chunk-7IJ5JVKT.js} +1 -1
- package/dist/{chunk-6EQRU7WC.js → chunk-J26YQVAK.js} +1 -1
- package/dist/{chunk-VHSTF72C.js → chunk-N6RNYCZD.js} +1 -1
- package/dist/{chunk-XKI55IFI.js → chunk-SCC77UUP.js} +82 -62
- package/dist/chunk-UPLDI7CN.js +1334 -0
- package/dist/{chunk-GC6X3YM7.js → chunk-ZOH24ZPF.js} +5 -5
- package/dist/{diff-QC7PWIPF.js → diff-AH7L4PRQ.js} +4 -4
- package/dist/discipline-5F5OVTXB.js +24 -0
- package/dist/{doctor-RVODPMHJ.js → doctor-INBOLZC7.js} +1 -1
- package/dist/index.js +53 -25
- package/dist/{list-CAL7KS7B.js → list-QTFWN35D.js} +3 -2
- package/dist/mcp.js +4 -3
- package/dist/{orchestrate-NNNWNELP.js → orchestrate-HMSQ2CED.js} +4 -4
- package/dist/{providers-NKGY36QF.js → providers-YW3FG6DA.js} +1 -1
- package/dist/{reindex-CMZARW5K.js → reindex-YG3KIXAK.js} +1 -1
- package/dist/{shift-R6TQ6MBP.js → shift-DRF5M3G6.js} +23 -17
- package/dist/{spawn-52PASJJL.js → spawn-DIY7T4QW.js} +2 -2
- package/dist/{team-JZHIH7H5.js → team-YOGT2Q2X.js} +5 -5
- package/dist/{timeline-B6TMGWRU.js → timeline-RKXNRMKF.js} +4 -3
- package/dist/university-content/courses/.purpose +4 -4
- package/dist/university-content/courses/para-101.json +1 -1
- package/dist/university-content/courses/para-201.json +18 -2
- package/dist/university-content/plsat/.purpose +18 -0
- package/dist/university-content/plsat/v3.0.json +105 -0
- package/package.json +1 -1
- package/templates/paradigm/config.yaml +1 -0
- package/dist/chunk-CHSHON3O.js +0 -669
- package/dist/{chunk-7WTOOH23.js → chunk-5SXMV4SP.js} +0 -0
- package/dist/{chunk-4UC6AQOC.js → chunk-C5ZE6WEX.js} +0 -0
- package/dist/{flow-KZKMMXJC.js → flow-UFMPVOEM.js} +1 -1
|
@@ -5,13 +5,17 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
AgentSpawner,
|
|
7
7
|
extractSymbols
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-J26YQVAK.js";
|
|
9
9
|
import {
|
|
10
10
|
AuditLogger
|
|
11
11
|
} from "./chunk-PBHIFAL4.js";
|
|
12
12
|
import {
|
|
13
13
|
loadAgentsManifest
|
|
14
14
|
} from "./chunk-PMXRGPRQ.js";
|
|
15
|
+
import {
|
|
16
|
+
extractDeclaredGates,
|
|
17
|
+
loadPortalConfig
|
|
18
|
+
} from "./chunk-MW5DMGBB.js";
|
|
15
19
|
import {
|
|
16
20
|
calculateCost
|
|
17
21
|
} from "./chunk-5JGJACDU.js";
|
|
@@ -20,10 +24,6 @@ import {
|
|
|
20
24
|
getReferencesTo,
|
|
21
25
|
searchSymbols
|
|
22
26
|
} from "./chunk-6P4IFIK2.js";
|
|
23
|
-
import {
|
|
24
|
-
extractDeclaredGates,
|
|
25
|
-
loadPortalConfig
|
|
26
|
-
} from "./chunk-MW5DMGBB.js";
|
|
27
27
|
|
|
28
28
|
// src/core/orchestrator.ts
|
|
29
29
|
import { minimatch } from "minimatch";
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
BackgroundOrchestrator
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-ZOH24ZPF.js";
|
|
5
5
|
import "./chunk-6QC3YGB6.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-J26YQVAK.js";
|
|
7
7
|
import "./chunk-PBHIFAL4.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-5SXMV4SP.js";
|
|
9
9
|
import "./chunk-PMXRGPRQ.js";
|
|
10
|
+
import "./chunk-MW5DMGBB.js";
|
|
10
11
|
import "./chunk-5JGJACDU.js";
|
|
11
12
|
import "./chunk-6P4IFIK2.js";
|
|
12
13
|
import "./chunk-MRENOFTR.js";
|
|
13
14
|
import "./chunk-IRKUEJVW.js";
|
|
14
|
-
import "./chunk-MW5DMGBB.js";
|
|
15
15
|
import "./chunk-ZXMDA7VB.js";
|
|
16
16
|
|
|
17
17
|
// src/commands/team/diff.ts
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
DISCIPLINE_MAPPINGS,
|
|
4
|
+
GENERIC_SYMBOL_MAPPING,
|
|
5
|
+
STACK_PRESETS,
|
|
6
|
+
detectDiscipline,
|
|
7
|
+
detectStack,
|
|
8
|
+
getDisciplineConfig,
|
|
9
|
+
getDisciplineScanPatterns,
|
|
10
|
+
getStackConfig,
|
|
11
|
+
listStackPresets
|
|
12
|
+
} from "./chunk-UPLDI7CN.js";
|
|
13
|
+
import "./chunk-ZXMDA7VB.js";
|
|
14
|
+
export {
|
|
15
|
+
DISCIPLINE_MAPPINGS,
|
|
16
|
+
GENERIC_SYMBOL_MAPPING,
|
|
17
|
+
STACK_PRESETS,
|
|
18
|
+
detectDiscipline,
|
|
19
|
+
detectStack,
|
|
20
|
+
getDisciplineConfig,
|
|
21
|
+
getDisciplineScanPatterns,
|
|
22
|
+
getStackConfig,
|
|
23
|
+
listStackPresets
|
|
24
|
+
};
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
initCommand
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-CHSHON3O.js";
|
|
4
|
+
} from "./chunk-SCC77UUP.js";
|
|
6
5
|
import "./chunk-W4VFKZVF.js";
|
|
7
6
|
import "./chunk-AK5M6KJB.js";
|
|
8
7
|
import {
|
|
@@ -17,6 +16,7 @@ import {
|
|
|
17
16
|
findGateFiles
|
|
18
17
|
} from "./chunk-IRKUEJVW.js";
|
|
19
18
|
import "./chunk-Z7W7HNRG.js";
|
|
19
|
+
import "./chunk-UPLDI7CN.js";
|
|
20
20
|
import "./chunk-KB4XJWE3.js";
|
|
21
21
|
import "./chunk-YO6DVTL7.js";
|
|
22
22
|
import {
|
|
@@ -109,11 +109,39 @@ ${chalk2.magenta("\u2560\u2550\u255D")}${chalk2.cyan("\u251C\u2500\u2524\u251C\u
|
|
|
109
109
|
${chalk2.magenta("\u2569 ")}${chalk2.cyan("\u2534 \u2534\u2534\u2514\u2500\u2534 \u2534\u2500\u2534\u2518\u2534 \u2514\u2500\u2518\u2534 \u2534")} ${chalk2.gray(`v${VERSION}`)}
|
|
110
110
|
`;
|
|
111
111
|
program.name("paradigm").description("Unified developer tools ecosystem").version(VERSION).addHelpText("before", banner);
|
|
112
|
-
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);
|
|
113
|
-
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").option("--workspace <name>", "Create or join a multi-project workspace with this name (creates ../.paradigm-workspace)").option("--workspace-path <path>", "Custom workspace file location (default: ../.paradigm-workspace)").action(async (options) => {
|
|
114
|
-
const { shiftCommand } = await import("./shift-
|
|
112
|
+
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("--stack <stack>", "Stack preset (e.g., nextjs, fastapi, swift-ios). Auto-detected if omitted.").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);
|
|
113
|
+
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").option("--stack <stack>", "Stack preset (e.g., nextjs, fastapi, swift-ios). Auto-detected if omitted.").option("--workspace <name>", "Create or join a multi-project workspace with this name (creates ../.paradigm-workspace)").option("--workspace-path <path>", "Custom workspace file location (default: ../.paradigm-workspace)").action(async (options) => {
|
|
114
|
+
const { shiftCommand } = await import("./shift-DRF5M3G6.js");
|
|
115
115
|
await shiftCommand(options);
|
|
116
116
|
});
|
|
117
|
+
program.command("presets").description("List available stack presets for paradigm init/shift").option("-d, --discipline <discipline>", "Filter by discipline (e.g., fullstack, api, mobile)").action(async (options) => {
|
|
118
|
+
const { listStackPresets } = await import("./discipline-5F5OVTXB.js");
|
|
119
|
+
const chalk3 = (await import("chalk")).default;
|
|
120
|
+
const presets = listStackPresets(options.discipline);
|
|
121
|
+
if (presets.length === 0) {
|
|
122
|
+
console.log(chalk3.yellow(`
|
|
123
|
+
No presets found${options.discipline ? ` for discipline: ${options.discipline}` : ""}
|
|
124
|
+
`));
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
console.log(chalk3.blue("\n Available Stack Presets\n"));
|
|
128
|
+
console.log(chalk3.gray(" Use with: paradigm init --stack <id> or paradigm shift --stack <id>\n"));
|
|
129
|
+
const byDiscipline = /* @__PURE__ */ new Map();
|
|
130
|
+
for (const preset of presets) {
|
|
131
|
+
const group = byDiscipline.get(preset.discipline) || [];
|
|
132
|
+
group.push(preset);
|
|
133
|
+
byDiscipline.set(preset.discipline, group);
|
|
134
|
+
}
|
|
135
|
+
for (const [discipline, group] of byDiscipline) {
|
|
136
|
+
console.log(chalk3.white(` ${discipline}`));
|
|
137
|
+
for (const preset of group) {
|
|
138
|
+
console.log(chalk3.cyan(` ${preset.id.padEnd(20)}`) + chalk3.gray(preset.name));
|
|
139
|
+
}
|
|
140
|
+
console.log("");
|
|
141
|
+
}
|
|
142
|
+
console.log(chalk3.gray(` ${presets.length} presets available. Auto-detected when --stack is omitted.
|
|
143
|
+
`));
|
|
144
|
+
});
|
|
117
145
|
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) => {
|
|
118
146
|
const { setupCommand } = await import("./setup-HOI52TN3.js");
|
|
119
147
|
await setupCommand(path2, options);
|
|
@@ -198,7 +226,7 @@ program.command("cost [path]").description("Analyze token costs for AI context")
|
|
|
198
226
|
});
|
|
199
227
|
var scanCmd = program.command("scan").description("Visual discovery and auto-generation commands");
|
|
200
228
|
scanCmd.command("auto [path]").description("Auto-generate .purpose files from code analysis").option("-n, --dry-run", "Show what would be generated without writing").option("-f, --force", "Overwrite existing .purpose files").option("--json", "Output as JSON").option("--init", "Full project initialization: generate .purpose files + portal.yaml").action(async (path2, options) => {
|
|
201
|
-
const { autoScanCommand } = await import("./auto-
|
|
229
|
+
const { autoScanCommand } = await import("./auto-24ICVUH4.js");
|
|
202
230
|
await autoScanCommand(path2, options);
|
|
203
231
|
});
|
|
204
232
|
scanCmd.action(() => {
|
|
@@ -209,7 +237,7 @@ scanCmd.action(() => {
|
|
|
209
237
|
});
|
|
210
238
|
var flowCmd = program.command("flow").description("Flow management commands");
|
|
211
239
|
flowCmd.command("diagram <flowId>").description("Generate Mermaid diagram for a flow").option("-o, --output <path>", "Output file path").action(async (flowId, options) => {
|
|
212
|
-
const { flowDiagramCommand } = await import("./flow-
|
|
240
|
+
const { flowDiagramCommand } = await import("./flow-UFMPVOEM.js");
|
|
213
241
|
await flowDiagramCommand(flowId, options);
|
|
214
242
|
});
|
|
215
243
|
flowCmd.action(() => {
|
|
@@ -217,7 +245,7 @@ flowCmd.action(() => {
|
|
|
217
245
|
});
|
|
218
246
|
var teamCmd = program.command("team").description("Multi-agent orchestration commands");
|
|
219
247
|
teamCmd.command("init [path]").description("Initialize team configuration with default agents").option("-f, --force", "Overwrite existing configuration").option("--configure-models", "Force model configuration prompts").option("--no-configure-models", "Skip model configuration").option("--json", "Output as JSON").action(async (path2, options) => {
|
|
220
|
-
const { teamInitCommand } = await import("./team-
|
|
248
|
+
const { teamInitCommand } = await import("./team-YOGT2Q2X.js");
|
|
221
249
|
await teamInitCommand(path2, {
|
|
222
250
|
...options,
|
|
223
251
|
configureModels: options.configureModels,
|
|
@@ -225,47 +253,47 @@ teamCmd.command("init [path]").description("Initialize team configuration with d
|
|
|
225
253
|
});
|
|
226
254
|
});
|
|
227
255
|
teamCmd.command("status [path]").description("Show current team status").option("--running", "Show only running orchestrations").option("--id <id>", "Show specific orchestration").option("--json", "Output as JSON").action(async (path2, options) => {
|
|
228
|
-
const { teamStatusCommand } = await import("./team-
|
|
256
|
+
const { teamStatusCommand } = await import("./team-YOGT2Q2X.js");
|
|
229
257
|
await teamStatusCommand(path2, options);
|
|
230
258
|
});
|
|
231
259
|
teamCmd.command("handoff [path]").description("Hand off current task to another agent").requiredOption("-t, --to <agent>", "Target agent name").option("-s, --summary <text>", "Summary of what was done").option("--json", "Output as JSON").action(async (path2, options) => {
|
|
232
|
-
const { teamHandoffCommand } = await import("./team-
|
|
260
|
+
const { teamHandoffCommand } = await import("./team-YOGT2Q2X.js");
|
|
233
261
|
await teamHandoffCommand(path2, options);
|
|
234
262
|
});
|
|
235
263
|
teamCmd.command("accept [handoff-id] [path]").description("Accept a pending handoff").option("-n, --note <text>", "Acceptance note").option("--json", "Output as JSON").action(async (handoffId, path2, options) => {
|
|
236
|
-
const { teamAcceptCommand } = await import("./team-
|
|
264
|
+
const { teamAcceptCommand } = await import("./team-YOGT2Q2X.js");
|
|
237
265
|
await teamAcceptCommand(handoffId, path2, options);
|
|
238
266
|
});
|
|
239
267
|
teamCmd.command("check [path]").description("Check for conflicts and team health issues").option("--json", "Output as JSON").action(async (path2, options) => {
|
|
240
|
-
const { teamCheckCommand } = await import("./team-
|
|
268
|
+
const { teamCheckCommand } = await import("./team-YOGT2Q2X.js");
|
|
241
269
|
await teamCheckCommand(path2, options);
|
|
242
270
|
});
|
|
243
271
|
teamCmd.command("history [path]").description("Show full activity log").option("-l, --limit <number>", "Number of entries to show", "50").option("--json", "Output as JSON").action(async (path2, options) => {
|
|
244
|
-
const { teamHistoryCommand } = await import("./team-
|
|
272
|
+
const { teamHistoryCommand } = await import("./team-YOGT2Q2X.js");
|
|
245
273
|
await teamHistoryCommand(path2, { ...options, limit: parseInt(options.limit) });
|
|
246
274
|
});
|
|
247
275
|
teamCmd.command("reset [path]").description("Reset team state for fresh start").option("-f, --force", "Force reset even with pending work").option("--json", "Output as JSON").action(async (path2, options) => {
|
|
248
|
-
const { teamResetCommand } = await import("./team-
|
|
276
|
+
const { teamResetCommand } = await import("./team-YOGT2Q2X.js");
|
|
249
277
|
await teamResetCommand(path2, options);
|
|
250
278
|
});
|
|
251
279
|
teamCmd.command("spawn <agent> [path]").description("Spawn an AI agent to work on a task").requiredOption("-t, --task <task>", "Task for the agent to perform").option("-m, --model <model>", "Model to use: opus, sonnet, haiku").option("-p, --provider <provider>", "Provider: auto, claude, claude-code, claude-cli, manual").option("--budget <budget>", 'Budget limits (e.g., "tokens=100000,cost=2")').option("--timeout <ms>", "Timeout in milliseconds").option("--checkpoint", "Pause for approval before writes/deletes").option("-q, --quiet", "Suppress output").option("--json", "Output as JSON").action(async (agent, path2, options) => {
|
|
252
|
-
const { teamSpawnCommand } = await import("./spawn-
|
|
280
|
+
const { teamSpawnCommand } = await import("./spawn-DIY7T4QW.js");
|
|
253
281
|
await teamSpawnCommand(agent, path2, options);
|
|
254
282
|
});
|
|
255
283
|
teamCmd.command("orchestrate <task> [path]").description("Orchestrate a multi-agent task").option("--solo", "Run in solo mode (single Claude)").option("--faceted", "Run in faceted mode (multi-agent, default)").option("--compare", "Run both modes and compare results").option("--background", "Run in background mode (returns immediately)").option("--notify <methods>", "Notification methods: bell,desktop,file,webhook (default: bell)").option("-m, --model <model>", "Orchestrator model: opus, sonnet, haiku").option("-p, --provider <provider>", "Provider: auto, claude, claude-code, claude-cli, manual").option("--budget <budget>", 'Budget limits (e.g., "tokens=500000,cost=5")').option("--checkpoint", "Pause for approval between agents").option("--live", "Stream agent output live").option("--pm", "Enable PM governance (compliance checks before/after)").option("-q, --quiet", "Suppress output").option("--json", "Output as JSON").action(async (task, path2, options) => {
|
|
256
|
-
const { teamOrchestrateCommand } = await import("./orchestrate-
|
|
284
|
+
const { teamOrchestrateCommand } = await import("./orchestrate-HMSQ2CED.js");
|
|
257
285
|
await teamOrchestrateCommand(task, path2, options);
|
|
258
286
|
});
|
|
259
287
|
teamCmd.command("diff <orchestration-id> [path]").description("Show diff of changes from a completed orchestration").option("--full", "Show full file contents").option("--json", "Output as JSON").action(async (orchestrationId, path2, options) => {
|
|
260
|
-
const { teamDiffCommand } = await import("./diff-
|
|
288
|
+
const { teamDiffCommand } = await import("./diff-AH7L4PRQ.js");
|
|
261
289
|
await teamDiffCommand(orchestrationId, path2, options);
|
|
262
290
|
});
|
|
263
291
|
teamCmd.command("accept-orch <orchestration-id> [path]").description("Accept orchestration changes").option("-n, --note <text>", "Acceptance note").option("--json", "Output as JSON").action(async (orchestrationId, path2, options) => {
|
|
264
|
-
const { teamAcceptOrchestrationCommand } = await import("./accept-orchestration-
|
|
292
|
+
const { teamAcceptOrchestrationCommand } = await import("./accept-orchestration-6EM5EHXA.js");
|
|
265
293
|
await teamAcceptOrchestrationCommand(orchestrationId, path2, options);
|
|
266
294
|
});
|
|
267
295
|
teamCmd.command("reject-orch <orchestration-id> [path]").description("Reject orchestration changes").option("-r, --reason <text>", "Rejection reason").option("--cleanup", "Delete created files").option("--json", "Output as JSON").action(async (orchestrationId, path2, options) => {
|
|
268
|
-
const { teamRejectOrchestrationCommand } = await import("./accept-orchestration-
|
|
296
|
+
const { teamRejectOrchestrationCommand } = await import("./accept-orchestration-6EM5EHXA.js");
|
|
269
297
|
await teamRejectOrchestrationCommand(orchestrationId, path2, options);
|
|
270
298
|
});
|
|
271
299
|
teamCmd.command("cost [path]").description("Show cost summary for orchestrations").option("--from <date>", "From date (ISO format)").option("--to <date>", "To date (ISO format)").option("--days <n>", "Last N days").option("-d, --detailed", "Show detailed breakdown").option("--json", "Output as JSON").action(async (path2, options) => {
|
|
@@ -277,11 +305,11 @@ teamCmd.command("export [path]").description("Export orchestration data").option
|
|
|
277
305
|
await teamExportCommand(path2, options);
|
|
278
306
|
});
|
|
279
307
|
teamCmd.command("providers [path]").description("Show available agent providers and their status").option("--set <provider>", "Set preferred provider: auto, claude, claude-code, claude-cli, manual").option("--json", "Output as JSON").action(async (path2, options) => {
|
|
280
|
-
const { teamProvidersCommand } = await import("./providers-
|
|
308
|
+
const { teamProvidersCommand } = await import("./providers-YW3FG6DA.js");
|
|
281
309
|
await teamProvidersCommand(path2, options);
|
|
282
310
|
});
|
|
283
311
|
teamCmd.command("models [path]").description("Configure or view agent model assignments").option("--refresh", "Refresh model cache from environment").option("--json", "Output as JSON").action(async (path2, options) => {
|
|
284
|
-
const { teamModelsCommand } = await import("./team-
|
|
312
|
+
const { teamModelsCommand } = await import("./team-YOGT2Q2X.js");
|
|
285
313
|
await teamModelsCommand(path2, options);
|
|
286
314
|
});
|
|
287
315
|
var agentsCmd = teamCmd.command("agents").description("Agent management commands");
|
|
@@ -296,7 +324,7 @@ agentsCmd.action(() => {
|
|
|
296
324
|
console.log("\nRun `paradigm team agents suggest --help` for options.\n");
|
|
297
325
|
});
|
|
298
326
|
teamCmd.action(async () => {
|
|
299
|
-
const { teamStatusCommand } = await import("./team-
|
|
327
|
+
const { teamStatusCommand } = await import("./team-YOGT2Q2X.js");
|
|
300
328
|
await teamStatusCommand(void 0, {});
|
|
301
329
|
});
|
|
302
330
|
var pluginCmd = program.command("plugin").description("Plugin management commands");
|
|
@@ -326,7 +354,7 @@ workspaceCmd.action(async () => {
|
|
|
326
354
|
await workspaceStatusCommand({});
|
|
327
355
|
});
|
|
328
356
|
program.command("doctor").description("Health check - validate Paradigm setup").option("--context", "Run only context audit checks (CLAUDE.md quality)").action(async (options) => {
|
|
329
|
-
const { doctorCommand } = await import("./doctor-
|
|
357
|
+
const { doctorCommand } = await import("./doctor-INBOLZC7.js");
|
|
330
358
|
await doctorCommand(options);
|
|
331
359
|
});
|
|
332
360
|
program.command("sweep").description("Entropy detection and cleanup \u2014 find orphaned symbols, stale purpose files, phantom gates").option("--dry", "Report only, no fixes applied").option("--skip-fix", "Same as --dry").option("-q, --quiet", "Minimal output").action(async (options) => {
|
|
@@ -626,7 +654,7 @@ triageCmd.option("-l, --limit <number>", "Maximum incidents to show", "10").opti
|
|
|
626
654
|
});
|
|
627
655
|
var loreCmd = program.command("lore").description("Project lore - timeline of everything that happened to this project");
|
|
628
656
|
loreCmd.command("list").alias("ls").description("List recent lore entries").option("--author <author>", "Filter by author").option("--type <type>", "Filter by type: agent-session, human-note, decision, review, incident, milestone, retro, insight").option("--symbol <symbol>", "Filter by symbol").option("--tags <tags>", "Filter by tags (comma-separated)").option("--from <date>", "Filter from date (ISO format, e.g., 2026-02-20)").option("--to <date>", "Filter to date (ISO format)").option("-l, --limit <number>", "Number of entries", "20").option("--json", "Output as JSON").action(async (options) => {
|
|
629
|
-
const { loreListCommand } = await import("./list-
|
|
657
|
+
const { loreListCommand } = await import("./list-QTFWN35D.js");
|
|
630
658
|
await loreListCommand(options);
|
|
631
659
|
});
|
|
632
660
|
loreCmd.command("show <id>").description("Show full detail for a lore entry").option("--json", "Output as JSON").action(async (id, options) => {
|
|
@@ -658,7 +686,7 @@ loreCmd.command("retag").description("Add or remove tags from matching lore entr
|
|
|
658
686
|
await loreRetagCommand(options);
|
|
659
687
|
});
|
|
660
688
|
loreCmd.command("timeline").description("Show lore timeline grouped by date with hot symbols and authors").option("-l, --limit <number>", "Number of entries", "20").option("--json", "Output as JSON").action(async (options) => {
|
|
661
|
-
const { loreTimelineCommand } = await import("./timeline-
|
|
689
|
+
const { loreTimelineCommand } = await import("./timeline-RKXNRMKF.js");
|
|
662
690
|
await loreTimelineCommand(options);
|
|
663
691
|
});
|
|
664
692
|
loreCmd.option("-p, --port <port>", "Port to run on", "3840").option("--no-open", "Don't open browser automatically").action(async (options) => {
|
|
@@ -38,14 +38,15 @@ async function loreListCommand(options) {
|
|
|
38
38
|
"milestone": chalk.hex("#60a5fa")
|
|
39
39
|
};
|
|
40
40
|
for (const entry of entries) {
|
|
41
|
-
const
|
|
41
|
+
const entryType = entry.type || "note";
|
|
42
|
+
const colorFn = typeColor[entryType] || chalk.white;
|
|
42
43
|
const date = new Date(entry.timestamp);
|
|
43
44
|
const dateStr = date.toLocaleDateString("en-US", { month: "short", day: "numeric" });
|
|
44
45
|
const timeStr = date.toLocaleTimeString("en-US", { hour: "2-digit", minute: "2-digit" });
|
|
45
46
|
const authorIcon = entry.agent ? "\u{1F916}" : "\u{1F464}";
|
|
46
47
|
const verifyIcon = entry.verification?.status === "pass" ? chalk.green("\u2713") : entry.verification?.status === "fail" ? chalk.red("\u2717") : entry.verification?.status === "partial" ? chalk.yellow("\u26A0") : chalk.gray("\xB7");
|
|
47
48
|
const reviewStr = entry.review ? chalk.yellow("\u2605".repeat(entry.review.quality) + "\u2606".repeat(5 - entry.review.quality)) : "";
|
|
48
|
-
console.log(` ${chalk.gray(entry.id)} ${colorFn(
|
|
49
|
+
console.log(` ${chalk.gray(entry.id)} ${colorFn(entryType.padEnd(14))} ${verifyIcon} ${chalk.white(entry.title)}`);
|
|
49
50
|
console.log(` ${chalk.gray(dateStr + " " + timeStr)} ${authorIcon} ${chalk.gray(entry.author)} ${(entry.symbols_touched || []).map((s) => chalk.cyan(s)).join(" ")} ${reviewStr}`);
|
|
50
51
|
console.log();
|
|
51
52
|
}
|
package/dist/mcp.js
CHANGED
|
@@ -76,7 +76,7 @@ import {
|
|
|
76
76
|
validatePersona,
|
|
77
77
|
validateProtocol,
|
|
78
78
|
validatePurposeFile
|
|
79
|
-
} from "./chunk-
|
|
79
|
+
} from "./chunk-7IJ5JVKT.js";
|
|
80
80
|
import {
|
|
81
81
|
deleteLoreEntry,
|
|
82
82
|
loadLoreEntries,
|
|
@@ -757,7 +757,8 @@ async function loadProjectContext(rootDir) {
|
|
|
757
757
|
if (config && typeof config.workspace === "string") {
|
|
758
758
|
workspace = loadWorkspaceContext(absoluteRoot, config.workspace);
|
|
759
759
|
}
|
|
760
|
-
} catch {
|
|
760
|
+
} catch (e) {
|
|
761
|
+
console.error(`[paradigm] Warning: Failed to load workspace config: ${e.message}`);
|
|
761
762
|
}
|
|
762
763
|
}
|
|
763
764
|
return {
|
|
@@ -14671,7 +14672,7 @@ Update command:
|
|
|
14671
14672
|
trackToolCall(noWsText.length, name);
|
|
14672
14673
|
return { content: [{ type: "text", text: noWsText }] };
|
|
14673
14674
|
}
|
|
14674
|
-
const { rebuildStaticFiles: rebuildStaticFiles2 } = await import("./reindex-
|
|
14675
|
+
const { rebuildStaticFiles: rebuildStaticFiles2 } = await import("./reindex-YG3KIXAK.js");
|
|
14675
14676
|
const memberResults = [];
|
|
14676
14677
|
for (const member of ctx.workspace.config.members) {
|
|
14677
14678
|
const memberAbsPath = path28.resolve(path28.dirname(ctx.workspace.workspacePath), member.path);
|
|
@@ -2,14 +2,15 @@
|
|
|
2
2
|
import {
|
|
3
3
|
BackgroundOrchestrator,
|
|
4
4
|
Orchestrator
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-ZOH24ZPF.js";
|
|
6
6
|
import "./chunk-6QC3YGB6.js";
|
|
7
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-J26YQVAK.js";
|
|
8
8
|
import "./chunk-PBHIFAL4.js";
|
|
9
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-5SXMV4SP.js";
|
|
10
10
|
import {
|
|
11
11
|
loadAgentsManifest
|
|
12
12
|
} from "./chunk-PMXRGPRQ.js";
|
|
13
|
+
import "./chunk-MW5DMGBB.js";
|
|
13
14
|
import {
|
|
14
15
|
formatCost,
|
|
15
16
|
formatTokens
|
|
@@ -17,7 +18,6 @@ import {
|
|
|
17
18
|
import "./chunk-6P4IFIK2.js";
|
|
18
19
|
import "./chunk-MRENOFTR.js";
|
|
19
20
|
import "./chunk-IRKUEJVW.js";
|
|
20
|
-
import "./chunk-MW5DMGBB.js";
|
|
21
21
|
import "./chunk-ZXMDA7VB.js";
|
|
22
22
|
|
|
23
23
|
// src/commands/team/orchestrate.ts
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
teamInitCommand
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-N6RNYCZD.js";
|
|
5
|
+
import "./chunk-ZOH24ZPF.js";
|
|
6
6
|
import "./chunk-6QC3YGB6.js";
|
|
7
|
-
import "./chunk-
|
|
7
|
+
import "./chunk-J26YQVAK.js";
|
|
8
8
|
import "./chunk-PBHIFAL4.js";
|
|
9
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-5SXMV4SP.js";
|
|
10
10
|
import {
|
|
11
11
|
agentsConfigured
|
|
12
12
|
} from "./chunk-PMXRGPRQ.js";
|
|
@@ -16,16 +16,14 @@ import {
|
|
|
16
16
|
import {
|
|
17
17
|
detectProjectRole
|
|
18
18
|
} from "./chunk-OXG5GVDJ.js";
|
|
19
|
+
import "./chunk-MW5DMGBB.js";
|
|
19
20
|
import {
|
|
20
21
|
doctorCommand
|
|
21
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-C5ZE6WEX.js";
|
|
22
23
|
import "./chunk-5JGJACDU.js";
|
|
23
24
|
import {
|
|
24
25
|
initCommand
|
|
25
|
-
} from "./chunk-
|
|
26
|
-
import {
|
|
27
|
-
detectDiscipline
|
|
28
|
-
} from "./chunk-CHSHON3O.js";
|
|
26
|
+
} from "./chunk-SCC77UUP.js";
|
|
29
27
|
import {
|
|
30
28
|
indexCommand
|
|
31
29
|
} from "./chunk-W4VFKZVF.js";
|
|
@@ -34,6 +32,9 @@ import "./chunk-6P4IFIK2.js";
|
|
|
34
32
|
import "./chunk-MRENOFTR.js";
|
|
35
33
|
import "./chunk-IRKUEJVW.js";
|
|
36
34
|
import "./chunk-Z7W7HNRG.js";
|
|
35
|
+
import {
|
|
36
|
+
detectDiscipline
|
|
37
|
+
} from "./chunk-UPLDI7CN.js";
|
|
37
38
|
import {
|
|
38
39
|
syncCommand
|
|
39
40
|
} from "./chunk-RP6TZYGE.js";
|
|
@@ -42,7 +43,6 @@ import "./chunk-YO6DVTL7.js";
|
|
|
42
43
|
import {
|
|
43
44
|
log
|
|
44
45
|
} from "./chunk-4NCFWYGG.js";
|
|
45
|
-
import "./chunk-MW5DMGBB.js";
|
|
46
46
|
import "./chunk-ZXMDA7VB.js";
|
|
47
47
|
|
|
48
48
|
// src/commands/shift.ts
|
|
@@ -72,7 +72,8 @@ async function shiftCommand(options = {}) {
|
|
|
72
72
|
force: options.force,
|
|
73
73
|
quick: true,
|
|
74
74
|
// We'll scan separately for better UX
|
|
75
|
-
name: projectName
|
|
75
|
+
name: projectName,
|
|
76
|
+
stack: options.stack
|
|
76
77
|
});
|
|
77
78
|
spinner.succeed(chalk.green("Paradigm initialized"));
|
|
78
79
|
} catch (error) {
|
|
@@ -110,7 +111,8 @@ discipline: ${detected}`
|
|
|
110
111
|
}
|
|
111
112
|
}
|
|
112
113
|
}
|
|
113
|
-
} catch {
|
|
114
|
+
} catch (e) {
|
|
115
|
+
log.operation("shift").debug("Discipline detection failed", { error: e.message });
|
|
114
116
|
}
|
|
115
117
|
}
|
|
116
118
|
}
|
|
@@ -187,7 +189,8 @@ workspace: "${relWsPath}"
|
|
|
187
189
|
}
|
|
188
190
|
console.log(chalk.green(` \u2713 Linked workspace in config.yaml`));
|
|
189
191
|
}
|
|
190
|
-
} catch {
|
|
192
|
+
} catch (e) {
|
|
193
|
+
log.operation("shift").debug("Workspace config link failed", { error: e.message });
|
|
191
194
|
}
|
|
192
195
|
} else if (fs.existsSync(configPath)) {
|
|
193
196
|
try {
|
|
@@ -211,7 +214,8 @@ workspace: "${relPath}"
|
|
|
211
214
|
searchDir = parent;
|
|
212
215
|
}
|
|
213
216
|
}
|
|
214
|
-
} catch {
|
|
217
|
+
} catch (e) {
|
|
218
|
+
log.operation("shift").debug("Workspace auto-detect failed", { error: e.message });
|
|
215
219
|
}
|
|
216
220
|
}
|
|
217
221
|
}
|
|
@@ -259,7 +263,8 @@ workspace: "${relPath}"
|
|
|
259
263
|
spinner.warn(chalk.yellow(`Workspace reindex: ${e.message}`));
|
|
260
264
|
}
|
|
261
265
|
}
|
|
262
|
-
} catch {
|
|
266
|
+
} catch (e) {
|
|
267
|
+
log.operation("shift").debug("Workspace config read failed", { error: e.message });
|
|
263
268
|
}
|
|
264
269
|
}
|
|
265
270
|
}
|
|
@@ -275,7 +280,7 @@ workspace: "${relPath}"
|
|
|
275
280
|
try {
|
|
276
281
|
await syncCommand(ide, { quiet: true, force: true });
|
|
277
282
|
syncResults.push(ide);
|
|
278
|
-
} catch {
|
|
283
|
+
} catch (e) {
|
|
279
284
|
}
|
|
280
285
|
}
|
|
281
286
|
if (syncResults.length > 0) {
|
|
@@ -337,7 +342,8 @@ workspace: "${relPath}"
|
|
|
337
342
|
const wsRelPath = path.relative(cwd, wsAbsPath);
|
|
338
343
|
files.push({ path: wsRelPath, desc: "Multi-project workspace", optional: true });
|
|
339
344
|
}
|
|
340
|
-
} catch {
|
|
345
|
+
} catch (e) {
|
|
346
|
+
log.operation("shift").debug("Summary config read failed", { error: e.message });
|
|
341
347
|
}
|
|
342
348
|
}
|
|
343
349
|
for (const file of files) {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
AgentSpawner
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-J26YQVAK.js";
|
|
5
5
|
import "./chunk-PBHIFAL4.js";
|
|
6
6
|
import {
|
|
7
7
|
getBestProvider
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-5SXMV4SP.js";
|
|
9
9
|
import {
|
|
10
10
|
loadAgentsManifest
|
|
11
11
|
} from "./chunk-PMXRGPRQ.js";
|
|
@@ -8,18 +8,18 @@ import {
|
|
|
8
8
|
teamModelsCommand,
|
|
9
9
|
teamResetCommand,
|
|
10
10
|
teamStatusCommand
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import "./chunk-
|
|
11
|
+
} from "./chunk-N6RNYCZD.js";
|
|
12
|
+
import "./chunk-ZOH24ZPF.js";
|
|
13
13
|
import "./chunk-6QC3YGB6.js";
|
|
14
|
-
import "./chunk-
|
|
14
|
+
import "./chunk-J26YQVAK.js";
|
|
15
15
|
import "./chunk-PBHIFAL4.js";
|
|
16
|
-
import "./chunk-
|
|
16
|
+
import "./chunk-5SXMV4SP.js";
|
|
17
17
|
import "./chunk-PMXRGPRQ.js";
|
|
18
|
+
import "./chunk-MW5DMGBB.js";
|
|
18
19
|
import "./chunk-5JGJACDU.js";
|
|
19
20
|
import "./chunk-6P4IFIK2.js";
|
|
20
21
|
import "./chunk-MRENOFTR.js";
|
|
21
22
|
import "./chunk-IRKUEJVW.js";
|
|
22
|
-
import "./chunk-MW5DMGBB.js";
|
|
23
23
|
import "./chunk-ZXMDA7VB.js";
|
|
24
24
|
export {
|
|
25
25
|
teamAcceptCommand,
|
|
@@ -48,7 +48,7 @@ async function loreTimelineCommand(options) {
|
|
|
48
48
|
for (const [date, dayEntries] of byDate) {
|
|
49
49
|
grouped[date] = dayEntries.map((e) => ({
|
|
50
50
|
id: e.id,
|
|
51
|
-
type: e.type,
|
|
51
|
+
type: e.type || "note",
|
|
52
52
|
title: e.title,
|
|
53
53
|
author: e.author,
|
|
54
54
|
symbols: e.symbols_touched || []
|
|
@@ -81,10 +81,11 @@ async function loreTimelineCommand(options) {
|
|
|
81
81
|
for (const [date, dayEntries] of byDate) {
|
|
82
82
|
console.log(chalk.white.bold(` ${date}`) + chalk.gray(` (${dayEntries.length} entries)`));
|
|
83
83
|
for (const entry of dayEntries) {
|
|
84
|
-
const
|
|
84
|
+
const entryType = entry.type || "note";
|
|
85
|
+
const colorFn = typeColor[entryType] || chalk.white;
|
|
85
86
|
const time = entry.timestamp.slice(11, 16);
|
|
86
87
|
const authorIcon = entry.agent ? "\u{1F916}" : "\u{1F464}";
|
|
87
|
-
console.log(` ${chalk.gray(time)} ${colorFn(
|
|
88
|
+
console.log(` ${chalk.gray(time)} ${colorFn(entryType.padEnd(14))} ${chalk.white(entry.title)}`);
|
|
88
89
|
console.log(` ${authorIcon} ${chalk.gray(entry.author)} ${(entry.symbols_touched || []).slice(0, 4).map((s) => chalk.cyan(s)).join(" ")}`);
|
|
89
90
|
}
|
|
90
91
|
console.log();
|
|
@@ -47,10 +47,10 @@ components:
|
|
|
47
47
|
references: ["#portal-protocol"]
|
|
48
48
|
|
|
49
49
|
para-101-first-steps:
|
|
50
|
-
description: "First Steps — paradigm init, paradigm shift,
|
|
50
|
+
description: "First Steps — paradigm init, paradigm shift, stack auto-detection, cold start for existing projects"
|
|
51
51
|
file: para-101.json
|
|
52
52
|
tags: [course-content, para-101]
|
|
53
|
-
references: ["#symbol-system", "#purpose-files", "#scan-index"]
|
|
53
|
+
references: ["#symbol-system", "#purpose-files", "#scan-index", "#stack-presets", "#cold-start"]
|
|
54
54
|
|
|
55
55
|
# PARA 201: Architecture (11 lessons)
|
|
56
56
|
|
|
@@ -85,10 +85,10 @@ components:
|
|
|
85
85
|
references: ["#portal-protocol"]
|
|
86
86
|
|
|
87
87
|
para-201-disciplines:
|
|
88
|
-
description: "Disciplines —
|
|
88
|
+
description: "Disciplines and Stack Presets — 14 disciplines, 16 stack presets, auto-detection, framework-specific config"
|
|
89
89
|
file: para-201.json
|
|
90
90
|
tags: [course-content, para-201]
|
|
91
|
-
references: ["#symbol-system"]
|
|
91
|
+
references: ["#symbol-system", "#stack-presets", "#disciplines"]
|
|
92
92
|
|
|
93
93
|
para-201-symbol-naming:
|
|
94
94
|
description: "Symbol Naming — kebab-case, PascalCase, conventions"
|
|
@@ -495,7 +495,7 @@
|
|
|
495
495
|
{
|
|
496
496
|
"id": "first-steps",
|
|
497
497
|
"title": "Your First Steps",
|
|
498
|
-
"content": "## Getting Started with Paradigm\n\nYou have learned the concepts — now it is time to put them into practice. This lesson walks through the concrete steps to initialize Paradigm in a new project and set up the foundational files.\n\n## Step 1: Initialize the Project\n\nRun `paradigm shift` in your project root. This creates the `.paradigm/` directory with a starter `config.yaml`:\n\n```bash\nparadigm shift\n```\n\nThe init command will prompt you for:\n- **Project name** — Used in config.yaml and as a display name\n- **Discipline** — `web`, `backend`, `fullstack`, `mobile`, `cli`, etc
|
|
498
|
+
"content": "## Getting Started with Paradigm\n\nYou have learned the concepts — now it is time to put them into practice. This lesson walks through the concrete steps to initialize Paradigm in a new project and set up the foundational files.\n\n## Step 1: Initialize the Project\n\nRun `paradigm shift` in your project root. This creates the `.paradigm/` directory with a starter `config.yaml`:\n\n```bash\nparadigm shift\n```\n\nThe init command will prompt you for:\n- **Project name** — Used in config.yaml and as a display name\n- **Discipline** — `web`, `backend`, `fullstack`, `mobile`, `cli`, etc. (auto-detected from your project)\n- **Agent provider** — Which AI tool you use (`claude-code`, `cursor-cli`, etc.)\n\nParadigm automatically detects your discipline from project markers (`package.json`, `Cargo.toml`, `go.mod`, etc.) and your **stack preset** from framework dependencies. For example, a project with Next.js in its dependencies will be detected as `discipline: fullstack` with `stack: nextjs`. The stack preset provides framework-specific scan patterns, purpose-required paths, and refined symbol mappings.\n\nYou can also specify a stack explicitly: `paradigm init --stack fastapi`.\n\nAfter init, you will have:\n```\n.paradigm/\n config.yaml # Includes detected discipline and stack\n tags.yaml\n agents.yaml\n```\n\n## Step 2: Create Your First Purpose File\n\nPick a source directory that contains meaningful code — perhaps your main feature module or your API routes. Create a `.purpose` file:\n\n```yaml\nname: User Authentication\ndescription: Handles user login, registration, and session management\ncontext:\n - Uses bcrypt for password hashing\n - Sessions stored in Redis with 24h TTL\n - Rate limited to 5 login attempts per minute\n\ncomponents:\n #auth-handler:\n description: POST /auth/login and POST /auth/register endpoints\n file: auth.ts\n tags: [feature, auth]\n signals: [\"!login-success\", \"!login-failed\"]\n gates: [\"^authenticated\"]\n\n #session-manager:\n description: Creates and validates user sessions in Redis\n file: session.ts\n tags: [state, auth]\n```\n\nStart small. You do not need to document every file on day one. Begin with the most important module and expand over time.\n\n## Step 3: Set Up portal.yaml (If Needed)\n\nIf your application has any protected endpoints, create `portal.yaml` at the project root:\n\n```yaml\nversion: \"1.0\"\n\ngates:\n ^authenticated:\n description: User must have a valid session\n check: req.session.userId != null\n type: auth\n effects: []\n\nroutes:\n \"POST /auth/login\": []\n \"POST /auth/register\": []\n \"GET /api/profile\": [^authenticated]\n \"PUT /api/profile\": [^authenticated]\n```\n\nNote that public routes like login and register have empty gate arrays `[]` — they are listed to document that they are intentionally unprotected.\n\n## Step 4: Run Your First Scan\n\nGenerate the navigator map so AI agents can find symbols quickly:\n\n```bash\nparadigm scan\n```\n\nThis reads all `.purpose` files and `portal.yaml`, builds a symbol index, and writes `navigator.yaml`.\n\n## Step 5: The Orientation Protocol\n\nWhen starting a new AI session (or when an AI agent first encounters your project), the agent should follow this protocol:\n\n1. **Call `paradigm_status`** — Gets a project overview: symbol counts, health, available features.\n2. **Read `config.yaml`** — Understands the discipline, conventions, and preferences.\n3. **Check `portal.yaml`** — Knows about security gates if they exist.\n4. **Use `paradigm_navigate`** — Finds the relevant code area for the current task.\n\nThis four-step orientation takes ~500 tokens total and gives the agent everything it needs to work effectively.\n\n## Step 6: Iterate\n\nParadigm grows with your project. As you add features:\n- Create `.purpose` files for new directories\n- Add gates to `portal.yaml` for new protected routes\n- Record team decisions in `.paradigm/wisdom/decisions.yaml`\n- Log antipatterns in `.paradigm/wisdom/antipatterns.yaml`\n- Run `paradigm scan` periodically to rebuild the navigator\n\n## Common Pitfalls\n\n- **Do not document everything on day one.** Start with the most critical module and expand.\n- **Do not skip portal.yaml.** If you have any gates or preconditions, you need it.\n- **Do not forget to re-scan.** After adding new `.purpose` files, run `paradigm scan` to update the navigator.\n- **Do not put .purpose files in .paradigm/.** They live alongside source code.\n- **Do not use raw console.log.** Use the Paradigm logger from the start to build good habits.",
|
|
499
499
|
"keyConcepts": [
|
|
500
500
|
"paradigm shift creates the .paradigm/ directory",
|
|
501
501
|
"Start with one .purpose file in your most important module",
|