@a-company/paradigm 3.28.0 → 3.34.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.
Files changed (41) hide show
  1. package/dist/{accept-orchestration-6EM5EHXA.js → accept-orchestration-XXANWJVZ.js} +3 -3
  2. package/dist/{aggregate-M5WMUI6B.js → aggregate-XHQ6GI3Z.js} +2 -2
  3. package/dist/{beacon-XL2ALH5O.js → beacon-BTLQMYQL.js} +2 -2
  4. package/dist/{chunk-AK5M6KJB.js → chunk-36TKPM5Z.js} +20 -2
  5. package/dist/{chunk-ZOH24ZPF.js → chunk-3BGSDKWD.js} +3 -3
  6. package/dist/{chunk-6P4IFIK2.js → chunk-CTF6RHKG.js} +37 -3
  7. package/dist/{chunk-SCC77UUP.js → chunk-H4TVBJD4.js} +3 -3
  8. package/dist/{chunk-KWDTBXP2.js → chunk-LHLIAYQ3.js} +1 -1
  9. package/dist/{chunk-7IJ5JVKT.js → chunk-PFLWLC6J.js} +59 -7
  10. package/dist/{chunk-W4VFKZVF.js → chunk-S5TDFT5Q.js} +2 -2
  11. package/dist/{chunk-N6RNYCZD.js → chunk-UQNTJ5VB.js} +1 -1
  12. package/dist/{chunk-MRENOFTR.js → chunk-VUSCJJ4A.js} +6 -1
  13. package/dist/{chunk-OXG5GVDJ.js → chunk-WOONGZ3C.js} +1 -1
  14. package/dist/{commands-6ZVTD74M.js → commands-KPT2T2OZ.js} +1 -1
  15. package/dist/{constellation-NXU6Q2HM.js → constellation-LZ6XIKDT.js} +2 -2
  16. package/dist/{cost-CTGSLSOC.js → cost-4SZM7OUS.js} +1 -1
  17. package/dist/{cursorrules-XBWFX66V.js → cursorrules-3TKZ4E4R.js} +2 -2
  18. package/dist/{diff-AH7L4PRQ.js → diff-T6YJSAAC.js} +3 -3
  19. package/dist/{dist-KY5HGDDL.js → dist-OH4DBV2O.js} +42 -3
  20. package/dist/{dist-7U64HDSC.js → dist-QSBAGCZT.js} +8 -2
  21. package/dist/index.js +43 -39
  22. package/dist/{lint-53GPXKKI.js → lint-MTRZB5EC.js} +1 -1
  23. package/dist/mcp.js +42 -7
  24. package/dist/migrate-HRN5TUBQ.js +871 -0
  25. package/dist/{orchestrate-HMSQ2CED.js → orchestrate-3SI6ON33.js} +3 -3
  26. package/dist/{probe-SN4BNXOC.js → probe-ABMGCXQG.js} +4 -4
  27. package/dist/{reindex-YG3KIXAK.js → reindex-YC7LD4MN.js} +1 -1
  28. package/dist/{remember-IEBQHXHZ.js → remember-WR6ZVXLT.js} +1 -1
  29. package/dist/{ripple-DFMXLFWI.js → ripple-QTXKJCEI.js} +2 -2
  30. package/dist/sentinel.js +6 -6
  31. package/dist/{setup-HOI52TN3.js → setup-ASR6OMKV.js} +4 -4
  32. package/dist/{shift-DRF5M3G6.js → shift-7XLSBLDW.js} +19 -9
  33. package/dist/{snapshot-XHINQBZS.js → snapshot-QZFD7YBI.js} +2 -2
  34. package/dist/{summary-NV7SBV5O.js → summary-R4CSYNNP.js} +2 -2
  35. package/dist/{team-YOGT2Q2X.js → team-VH3HYABB.js} +4 -4
  36. package/dist/university-content/courses/para-101.json +53 -0
  37. package/dist/university-content/plsat/v3.0.json +78 -1
  38. package/dist/{upgrade-65QOQXRC.js → upgrade-ANX3LVSA.js} +1 -0
  39. package/dist/{validate-TKKRGJKC.js → validate-OUHUBZPO.js} +1 -1
  40. package/dist/{workspace-L27RR5MF.js → workspace-5RBSALXC.js} +5 -5
  41. package/package.json +1 -1
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  BackgroundOrchestrator,
4
4
  Orchestrator
5
- } from "./chunk-ZOH24ZPF.js";
5
+ } from "./chunk-3BGSDKWD.js";
6
6
  import "./chunk-6QC3YGB6.js";
7
7
  import "./chunk-J26YQVAK.js";
8
8
  import "./chunk-PBHIFAL4.js";
@@ -15,8 +15,8 @@ import {
15
15
  formatCost,
16
16
  formatTokens
17
17
  } from "./chunk-5JGJACDU.js";
18
- import "./chunk-6P4IFIK2.js";
19
- import "./chunk-MRENOFTR.js";
18
+ import "./chunk-CTF6RHKG.js";
19
+ import "./chunk-VUSCJJ4A.js";
20
20
  import "./chunk-IRKUEJVW.js";
21
21
  import "./chunk-ZXMDA7VB.js";
22
22
 
@@ -2,15 +2,15 @@
2
2
  import {
3
3
  generateFlowIndex,
4
4
  generateNavigator
5
- } from "./chunk-W4VFKZVF.js";
5
+ } from "./chunk-S5TDFT5Q.js";
6
6
  import {
7
7
  generateScanIndex,
8
8
  serializeScanIndex
9
- } from "./chunk-AK5M6KJB.js";
9
+ } from "./chunk-36TKPM5Z.js";
10
10
  import {
11
11
  aggregateFromDirectory
12
- } from "./chunk-6P4IFIK2.js";
13
- import "./chunk-MRENOFTR.js";
12
+ } from "./chunk-CTF6RHKG.js";
13
+ import "./chunk-VUSCJJ4A.js";
14
14
  import "./chunk-IRKUEJVW.js";
15
15
  import "./chunk-Z7W7HNRG.js";
16
16
  import {
@@ -3,7 +3,7 @@ import {
3
3
  getReindexToolsList,
4
4
  handleReindexTool,
5
5
  rebuildStaticFiles
6
- } from "./chunk-7IJ5JVKT.js";
6
+ } from "./chunk-PFLWLC6J.js";
7
7
  import "./chunk-3DYYXGDC.js";
8
8
  export {
9
9
  getReindexToolsList,
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  aggregatePurposes,
4
4
  getAllPurposeFiles
5
- } from "./chunk-MRENOFTR.js";
5
+ } from "./chunk-VUSCJJ4A.js";
6
6
  import "./chunk-ZXMDA7VB.js";
7
7
 
8
8
  // src/commands/purpose/remember.ts
@@ -7,8 +7,8 @@ import {
7
7
  getSymbol,
8
8
  getSymbolsByType,
9
9
  parseSymbol
10
- } from "./chunk-6P4IFIK2.js";
11
- import "./chunk-MRENOFTR.js";
10
+ } from "./chunk-CTF6RHKG.js";
11
+ import "./chunk-VUSCJJ4A.js";
12
12
  import "./chunk-IRKUEJVW.js";
13
13
  import {
14
14
  log
package/dist/sentinel.js CHANGED
@@ -8,28 +8,28 @@ var { version: VERSION } = require2("../package.json");
8
8
  var program = new Command();
9
9
  program.name("sentinel").description("Semantic error monitoring \u2014 errors that speak your language").version(VERSION);
10
10
  program.command("defend", { isDefault: true }).description("Launch the Sentinel dashboard").option("-p, --port <port>", "Port number", "3838").option("--no-open", "Don't open browser").action(async (opts) => {
11
- const { launchDashboard } = await import("./commands-6ZVTD74M.js");
11
+ const { launchDashboard } = await import("./commands-KPT2T2OZ.js");
12
12
  await launchDashboard(opts);
13
13
  });
14
14
  program.command("init").description("Initialize Sentinel in current project").option("--detect", "Auto-detect symbols from codebase").action(async (opts) => {
15
- const { initProject } = await import("./commands-6ZVTD74M.js");
15
+ const { initProject } = await import("./commands-KPT2T2OZ.js");
16
16
  await initProject(opts);
17
17
  });
18
18
  var triage = program.command("triage").description("Incident triage");
19
19
  triage.command("list").description("List incidents").option("-s, --status <status>", "Filter by status (open, investigating, resolved, wont-fix)").option("-e, --env <env>", "Filter by environment").option("--symbol <symbol>", "Filter by symbol").option("-n, --limit <n>", "Max results", "10").action(async (opts) => {
20
- const { triageList } = await import("./commands-6ZVTD74M.js");
20
+ const { triageList } = await import("./commands-KPT2T2OZ.js");
21
21
  await triageList(opts);
22
22
  });
23
23
  triage.command("show <id>").description("Show incident details").option("--timeline", "Include flow timeline").action(async (id, opts) => {
24
- const { triageShow } = await import("./commands-6ZVTD74M.js");
24
+ const { triageShow } = await import("./commands-KPT2T2OZ.js");
25
25
  await triageShow(id, opts);
26
26
  });
27
27
  triage.command("resolve <id>").description("Resolve an incident").option("--pattern <id>", "Pattern that resolved it").option("--commit <hash>", "Fix commit").option("--notes <text>", "Resolution notes").action(async (id, opts) => {
28
- const { triageResolve } = await import("./commands-6ZVTD74M.js");
28
+ const { triageResolve } = await import("./commands-KPT2T2OZ.js");
29
29
  await triageResolve(id, opts);
30
30
  });
31
31
  triage.command("stats").description("Show incident statistics").option("-p, --period <period>", "Period (7d, 30d, 90d)", "7d").action(async (opts) => {
32
- const { triageStats } = await import("./commands-6ZVTD74M.js");
32
+ const { triageStats } = await import("./commands-KPT2T2OZ.js");
33
33
  await triageStats(opts);
34
34
  });
35
35
  program.parse();
@@ -2,14 +2,14 @@
2
2
  import {
3
3
  cursorrrulesExists,
4
4
  writeCursorrules
5
- } from "./chunk-KWDTBXP2.js";
6
- import "./chunk-AK5M6KJB.js";
5
+ } from "./chunk-LHLIAYQ3.js";
6
+ import "./chunk-36TKPM5Z.js";
7
7
  import {
8
8
  getDefaultPremiseContent
9
- } from "./chunk-6P4IFIK2.js";
9
+ } from "./chunk-CTF6RHKG.js";
10
10
  import {
11
11
  getDefaultPurposeContent
12
- } from "./chunk-MRENOFTR.js";
12
+ } from "./chunk-VUSCJJ4A.js";
13
13
  import "./chunk-IRKUEJVW.js";
14
14
  import {
15
15
  DEFAULT_CONVENTIONS,
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  teamInitCommand
4
- } from "./chunk-N6RNYCZD.js";
5
- import "./chunk-ZOH24ZPF.js";
4
+ } from "./chunk-UQNTJ5VB.js";
5
+ import "./chunk-3BGSDKWD.js";
6
6
  import "./chunk-6QC3YGB6.js";
7
7
  import "./chunk-J26YQVAK.js";
8
8
  import "./chunk-PBHIFAL4.js";
@@ -15,7 +15,7 @@ import {
15
15
  } from "./chunk-DS5QY37M.js";
16
16
  import {
17
17
  detectProjectRole
18
- } from "./chunk-OXG5GVDJ.js";
18
+ } from "./chunk-WOONGZ3C.js";
19
19
  import "./chunk-MW5DMGBB.js";
20
20
  import {
21
21
  doctorCommand
@@ -23,13 +23,13 @@ import {
23
23
  import "./chunk-5JGJACDU.js";
24
24
  import {
25
25
  initCommand
26
- } from "./chunk-SCC77UUP.js";
26
+ } from "./chunk-H4TVBJD4.js";
27
27
  import {
28
28
  indexCommand
29
- } from "./chunk-W4VFKZVF.js";
30
- import "./chunk-AK5M6KJB.js";
31
- import "./chunk-6P4IFIK2.js";
32
- import "./chunk-MRENOFTR.js";
29
+ } from "./chunk-S5TDFT5Q.js";
30
+ import "./chunk-36TKPM5Z.js";
31
+ import "./chunk-CTF6RHKG.js";
32
+ import "./chunk-VUSCJJ4A.js";
33
33
  import "./chunk-IRKUEJVW.js";
34
34
  import "./chunk-Z7W7HNRG.js";
35
35
  import {
@@ -116,6 +116,16 @@ discipline: ${detected}`
116
116
  }
117
117
  }
118
118
  }
119
+ if (isInitialized) {
120
+ spinner.start("Step 1b/6: Checking for migrations...");
121
+ try {
122
+ const { migrateCommand } = await import("./migrate-HRN5TUBQ.js");
123
+ await migrateCommand({ apply: true, quiet: true, noSync: true });
124
+ spinner.succeed(chalk.green("Migrations applied"));
125
+ } catch (error) {
126
+ spinner.warn(chalk.yellow(`Migration warning: ${error.message}`));
127
+ }
128
+ }
119
129
  {
120
130
  const configPath = path.join(paradigmDir, "config.yaml");
121
131
  if (options.workspace && fs.existsSync(configPath)) {
@@ -256,7 +266,7 @@ workspace: "${relPath}"
256
266
  if (configForWs.workspace) {
257
267
  spinner.start("Step 3b/6: Reindexing workspace members...");
258
268
  try {
259
- const { workspaceReindexCommand } = await import("./workspace-L27RR5MF.js");
269
+ const { workspaceReindexCommand } = await import("./workspace-5RBSALXC.js");
260
270
  await workspaceReindexCommand({ quiet: true });
261
271
  spinner.succeed(chalk.green("Workspace members reindexed"));
262
272
  } catch (e) {
@@ -3,8 +3,8 @@ import {
3
3
  createSnapshot,
4
4
  parsePremiseFile,
5
5
  serializePremiseFile
6
- } from "./chunk-6P4IFIK2.js";
7
- import "./chunk-MRENOFTR.js";
6
+ } from "./chunk-CTF6RHKG.js";
7
+ import "./chunk-VUSCJJ4A.js";
8
8
  import "./chunk-IRKUEJVW.js";
9
9
  import "./chunk-ZXMDA7VB.js";
10
10
 
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  aggregateFromDirectory
4
- } from "./chunk-6P4IFIK2.js";
5
- import "./chunk-MRENOFTR.js";
4
+ } from "./chunk-CTF6RHKG.js";
5
+ import "./chunk-VUSCJJ4A.js";
6
6
  import "./chunk-IRKUEJVW.js";
7
7
  import {
8
8
  detectIDE,
@@ -8,8 +8,8 @@ import {
8
8
  teamModelsCommand,
9
9
  teamResetCommand,
10
10
  teamStatusCommand
11
- } from "./chunk-N6RNYCZD.js";
12
- import "./chunk-ZOH24ZPF.js";
11
+ } from "./chunk-UQNTJ5VB.js";
12
+ import "./chunk-3BGSDKWD.js";
13
13
  import "./chunk-6QC3YGB6.js";
14
14
  import "./chunk-J26YQVAK.js";
15
15
  import "./chunk-PBHIFAL4.js";
@@ -17,8 +17,8 @@ import "./chunk-5SXMV4SP.js";
17
17
  import "./chunk-PMXRGPRQ.js";
18
18
  import "./chunk-MW5DMGBB.js";
19
19
  import "./chunk-5JGJACDU.js";
20
- import "./chunk-6P4IFIK2.js";
21
- import "./chunk-MRENOFTR.js";
20
+ import "./chunk-CTF6RHKG.js";
21
+ import "./chunk-VUSCJJ4A.js";
22
22
  import "./chunk-IRKUEJVW.js";
23
23
  import "./chunk-ZXMDA7VB.js";
24
24
  export {
@@ -557,6 +557,59 @@
557
557
  "explanation": "A common pitfall is trying to document everything on day one. The recommended approach is to start with the most critical module, create one .purpose file, and expand incrementally as the project grows."
558
558
  }
559
559
  ]
560
+ },
561
+ {
562
+ "id": "component-types",
563
+ "title": "Component Types & Hierarchy",
564
+ "content": "## Why Component Types?\n\nComponents (`#`) are the most common symbol in any Paradigm project. A large project might have hundreds of components — services, views, utilities, routers, filters, models, and more. Without further classification, an AI agent triaging 'where is access control handled?' has to read every component to understand what kind of thing it is.\n\nComponent types solve this by adding an optional `type` field that describes a component's **structural role** — what the code IS, not what domain it belongs to.\n\n## The `type` Field\n\nAdd `type` to any component in a `.purpose` file:\n\n```yaml\ncomponents:\n PaymentService:\n description: Coordinates payment processing\n type: service\n PaymentForm:\n description: Credit card input form\n type: view\n format-currency:\n description: Formats numbers as currency strings\n type: utility\n```\n\nTypes are **open strings** — each project defines its own vocabulary in the `component_types` glossary in `.paradigm/config.yaml`. There is no fixed enum. Common types include: `view`, `service`, `model`, `tool`, `utility`, `engine`, `loader`, `provider`, `manager`, `router`, `filter`, `handler`, `config`.\n\n## The `parent` Field\n\nComponents can declare a parent to establish hierarchy:\n\n```yaml\ncomponents:\n InputOrchestrator:\n description: Coordinates all input sources\n type: manager\n GazeRouter:\n description: Maps gaze coordinates to dispatch targets\n type: router\n parent: \"#InputOrchestrator\"\n KalmanFilter2D:\n description: Smooths noisy gaze signal\n type: filter\n parent: \"#GazeRouter\"\n```\n\nParent is declared on the **child**, not maintained as a roster on the parent. This keeps `.purpose` files decentralized.\n\n## Type vs Tag\n\nThis is a common source of confusion:\n\n- **`type`** = structural role (what the code IS). One per component. Examples: `service`, `view`, `router`\n- **`tags`** = behavioral or domain classification. Many per component. Examples: `[feature]`, `[security]`, `[integration]`\n\nA component can be `type: service` with `tags: [feature, security]`. Type tells you the architecture; tags tell you the domain.\n\n## Config Glossary\n\nProjects define their vocabulary in `.paradigm/config.yaml`:\n\n```yaml\ncomponent_types:\n service: \"Business logic coordinator — orchestrates tools, loaders, writers\"\n view: \"UI rendering unit — SwiftUI view, React component\"\n utility: \"Shared helper function or module — no side effects, pure logic\"\n router: \"Maps input signals to targets based on rules\"\n```\n\nThe glossary is **descriptive only** — it helps agents understand types but does not enforce them.\n\n## MCP Integration\n\nComponent types integrate with MCP tools:\n\n- `paradigm_search` with `componentType: \"service\"` finds all services\n- `paradigm_status` shows a component type breakdown\n- `paradigm_purpose_add_component` accepts `type` and `parent` parameters\n- `paradigm_reindex` aggregates type counts into `$meta.componentTypes`",
565
+ "keyConcepts": [
566
+ "Component type describes structural role (what the code IS)",
567
+ "Types are open strings defined per project vocabulary",
568
+ "Parent field establishes hierarchy (declared on child)",
569
+ "Type vs tag: type = architecture, tags = domain/behavior",
570
+ "Config glossary describes types but does not enforce them"
571
+ ],
572
+ "quiz": [
573
+ {
574
+ "id": "q1",
575
+ "question": "What does the `type` field on a component describe?",
576
+ "choices": {
577
+ "A": "The programming language the component is written in",
578
+ "B": "The structural role of the component (e.g., service, view, router)",
579
+ "C": "The business domain the component belongs to",
580
+ "D": "The test coverage level of the component",
581
+ "E": "The deployment environment for the component"
582
+ },
583
+ "correct": "B",
584
+ "explanation": "The `type` field describes a component's structural role — what the code IS architecturally (service, view, router, filter, etc.). Business domain classification uses tags instead."
585
+ },
586
+ {
587
+ "id": "q2",
588
+ "question": "Where should the `parent` relationship be declared?",
589
+ "choices": {
590
+ "A": "On the parent component, listing all children",
591
+ "B": "In a separate relationships.yaml file",
592
+ "C": "On the child component, referencing the parent with a # symbol",
593
+ "D": "In portal.yaml alongside gate definitions",
594
+ "E": "In the config.yaml component_types glossary"
595
+ },
596
+ "correct": "C",
597
+ "explanation": "Parent is declared on the child component using a `parent: \"#parent-name\"` field. This keeps .purpose files decentralized — you don't need to maintain rosters on parent components."
598
+ },
599
+ {
600
+ "id": "q3",
601
+ "question": "A `PaymentService` handles payment processing and integrates with Stripe. How should it be documented?",
602
+ "choices": {
603
+ "A": "`type: integration` with no tags",
604
+ "B": "`type: service` with `tags: [integration, feature]`",
605
+ "C": "`tags: [service, integration]` with no type",
606
+ "D": "`type: feature` with `tags: [service]`",
607
+ "E": "`type: service-integration` combining both concepts"
608
+ },
609
+ "correct": "B",
610
+ "explanation": "Type describes what the code IS (a service), while tags describe behavior and domain (it's an integration and a feature). The correct approach is `type: service` with `tags: [integration, feature]`."
611
+ }
612
+ ]
560
613
  }
561
614
  ]
562
615
  }
@@ -2,7 +2,7 @@
2
2
  "version": "3.0",
3
3
  "frameworkVersion": "2.0",
4
4
  "timeLimit": 5400,
5
- "totalSlots": 99,
5
+ "totalSlots": 102,
6
6
  "passThreshold": 0.8,
7
7
  "title": "The PLSAT \u2014 Paradigm Licensure Standardized Assessment Test",
8
8
  "description": "99 questions. 90 minutes. 80% to pass. Good luck, scholar.",
@@ -2489,6 +2489,83 @@
2489
2489
  "explanation": "Stack presets include scan hints — framework-specific patterns that tell the auto-scanner where to look and what patterns to match. The django preset knows that views.py files contain route handlers, models.py files contain data models, and urls.py files define URL routing. This is why stack presets solve the cold-start problem: they bring framework knowledge that makes auto-scanning productive for existing projects."
2490
2490
  }
2491
2491
  ]
2492
+ },
2493
+ {
2494
+ "type": "standalone",
2495
+ "slot": "slot-100",
2496
+ "course": "para-101",
2497
+ "variants": [
2498
+ {
2499
+ "id": "plsat-100",
2500
+ "scenario": "Your project has a `#PaymentService` that coordinates payment processing and integrates with Stripe. A new developer asks whether they should use `type: integration` or `tags: [integration]` to capture the Stripe relationship.",
2501
+ "question": "What is the correct approach?",
2502
+ "choices": {
2503
+ "A": "`type: integration` — because the Stripe integration is the most important thing about this component",
2504
+ "B": "`type: service` with `tags: [integration]` — type describes structural role, tags describe domain/behavior",
2505
+ "C": "Both `type: integration` and `tags: [integration]` — redundancy is good for search",
2506
+ "D": "Neither — integration is a v1 concept replaced by `&` prefix in v2",
2507
+ "E": "`type: stripe` — use the specific integration name as the type"
2508
+ },
2509
+ "correct": "B",
2510
+ "explanation": "The `type` field describes a component's structural role — what the code IS architecturally. PaymentService is a service, so `type: service`. The Stripe integration is a behavioral/domain concern, captured with `tags: [integration]`. Type and tags serve different classification axes: type = architecture, tags = domain."
2511
+ },
2512
+ {
2513
+ "id": "plsat-100b",
2514
+ "scenario": "A developer adds a new `#EmailValidator` utility and sets `type: validator` in the .purpose file. Another developer points out that `validator` is not in the project's `component_types` glossary in config.yaml.",
2515
+ "question": "Is `type: validator` valid?",
2516
+ "choices": {
2517
+ "A": "No — types must exactly match the glossary entries or they are rejected",
2518
+ "B": "Yes — types are open strings and the glossary is descriptive only, not enforced",
2519
+ "C": "No — you must add it to the glossary first before using it",
2520
+ "D": "Yes — but only if the developer also adds a `~validator` aspect",
2521
+ "E": "It depends on the `strict-types` setting in config.yaml"
2522
+ },
2523
+ "correct": "B",
2524
+ "explanation": "Component types are open strings — any project can invent its own vocabulary. The glossary in config.yaml is descriptive only (it helps agents understand types) but does not enforce or block unknown types. The developer can use `type: validator` freely."
2525
+ }
2526
+ ]
2527
+ },
2528
+ {
2529
+ "type": "standalone",
2530
+ "slot": "slot-101",
2531
+ "course": "para-101",
2532
+ "variants": [
2533
+ {
2534
+ "id": "plsat-101",
2535
+ "scenario": "You have a `#GazeRouter` component that maps gaze coordinates to dispatch targets. It is managed by `#InputOrchestrator`. You want to express this hierarchy in the .purpose file.",
2536
+ "question": "How should the parent relationship be declared?",
2537
+ "choices": {
2538
+ "A": "On `#InputOrchestrator` with `children: [\"#GazeRouter\"]`",
2539
+ "B": "On `#GazeRouter` with `parent: \"#InputOrchestrator\"`",
2540
+ "C": "In a separate `relationships` section at the top of the .purpose file",
2541
+ "D": "In portal.yaml alongside route gates",
2542
+ "E": "Using `tags: [child-of-InputOrchestrator]` on GazeRouter"
2543
+ },
2544
+ "correct": "B",
2545
+ "explanation": "Parent relationships are declared on the child component using the `parent` field with a `#` symbol reference. This keeps .purpose files decentralized — you don't need to maintain a children roster on the parent. The parent field is computed upward, not maintained downward."
2546
+ }
2547
+ ]
2548
+ },
2549
+ {
2550
+ "type": "standalone",
2551
+ "slot": "slot-102",
2552
+ "course": "para-101",
2553
+ "variants": [
2554
+ {
2555
+ "id": "plsat-102",
2556
+ "scenario": "An AI agent needs to find all router components in a project to understand the dispatch architecture. The project uses component types consistently.",
2557
+ "question": "What is the most efficient MCP tool call?",
2558
+ "choices": {
2559
+ "A": "`paradigm_search` with `query: \"router\"` — search by name",
2560
+ "B": "`paradigm_search` with `query: \"*\"` and `componentType: \"router\"` — filter by type",
2561
+ "C": "`paradigm_navigate` with `intent: \"find\"` and `target: \"router\"` — navigate to routers",
2562
+ "D": "`paradigm_ripple` with `symbol: \"#router\"` — check router dependencies",
2563
+ "E": "Read every .purpose file and grep for `type: router`"
2564
+ },
2565
+ "correct": "B",
2566
+ "explanation": "The `paradigm_search` tool accepts a `componentType` filter that directly queries the symbol index for components of a specific type. This is the most efficient approach — it uses the index instead of reading files, and returns exactly the components with `type: router`."
2567
+ }
2568
+ ]
2492
2569
  }
2493
2570
  ]
2494
2571
  }
@@ -35,6 +35,7 @@ async function upgradeCommand(targetPath, options) {
35
35
  const rootDir = targetPath ? path.resolve(targetPath) : process.cwd();
36
36
  const projectName = path.basename(rootDir);
37
37
  const spinner = ora();
38
+ console.log(chalk.yellow("\n `paradigm upgrade` is deprecated. Use `paradigm migrate` instead.\n"));
38
39
  console.log(chalk.blue("\n\u{1F504} Paradigm Upgrade\n"));
39
40
  if (options.fromHorizon) {
40
41
  const result = await migrateFromHorizon(rootDir, projectName, options, spinner);
@@ -3,7 +3,7 @@ import {
3
3
  formatValidationResult,
4
4
  getAllPurposeFiles,
5
5
  validatePurposeFile
6
- } from "./chunk-MRENOFTR.js";
6
+ } from "./chunk-VUSCJJ4A.js";
7
7
  import "./chunk-ZXMDA7VB.js";
8
8
 
9
9
  // src/commands/purpose/validate.ts
@@ -4,11 +4,11 @@ import {
4
4
  workspaceInitCommand,
5
5
  workspaceReindexCommand,
6
6
  workspaceStatusCommand
7
- } from "./chunk-OXG5GVDJ.js";
8
- import "./chunk-W4VFKZVF.js";
9
- import "./chunk-AK5M6KJB.js";
10
- import "./chunk-6P4IFIK2.js";
11
- import "./chunk-MRENOFTR.js";
7
+ } from "./chunk-WOONGZ3C.js";
8
+ import "./chunk-S5TDFT5Q.js";
9
+ import "./chunk-36TKPM5Z.js";
10
+ import "./chunk-CTF6RHKG.js";
11
+ import "./chunk-VUSCJJ4A.js";
12
12
  import "./chunk-IRKUEJVW.js";
13
13
  import "./chunk-Z7W7HNRG.js";
14
14
  import "./chunk-4NCFWYGG.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@a-company/paradigm",
3
- "version": "3.28.0",
3
+ "version": "3.34.0",
4
4
  "description": "Unified CLI for Paradigm developer tools",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",