@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
|
@@ -141,6 +141,55 @@
|
|
|
141
141
|
"when": "After creating or modifying aspects, or when paradigm doctor reports stale anchors.",
|
|
142
142
|
"example": "paradigm_aspect_check({ aspect: '~audit-required' })"
|
|
143
143
|
},
|
|
144
|
+
{
|
|
145
|
+
"id": "paradigm-aspect-search",
|
|
146
|
+
"name": "paradigm_aspect_search",
|
|
147
|
+
"description": "Search aspects using three-tier learning search (learned mappings → FTS5 → fuzzy). Returns ranked results with scores and tiers. Call paradigm_aspect_confirm after selecting a result to improve future searches.",
|
|
148
|
+
"when": "When looking for aspects by keyword, description, or related concept. The search improves over time as you confirm results.",
|
|
149
|
+
"example": "paradigm_aspect_search({ query: 'jwt expiry' })"
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
"id": "paradigm-aspect-get",
|
|
153
|
+
"name": "paradigm_aspect_get",
|
|
154
|
+
"description": "Get full aspect details — description, category, severity, code anchor snippets, graph edges, and linked lore entries.",
|
|
155
|
+
"when": "After finding an aspect via search, to see its full context including the actual code at anchor locations.",
|
|
156
|
+
"example": "paradigm_aspect_get({ aspectId: 'token-expiry-24h' })"
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
"id": "paradigm-aspect-graph",
|
|
160
|
+
"name": "paradigm_aspect_graph",
|
|
161
|
+
"description": "Get the subgraph neighborhood of a symbol — all aspects and edges within N hops.",
|
|
162
|
+
"when": "When exploring how aspects relate to each other and to symbols in the codebase.",
|
|
163
|
+
"example": "paradigm_aspect_graph({ symbol: '~token-expiry-24h', hops: 2 })"
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
"id": "paradigm-aspect-heatmap",
|
|
167
|
+
"name": "paradigm_aspect_heatmap",
|
|
168
|
+
"description": "Get most-accessed aspects ranked by usage frequency, broken down by access type (search, ripple, navigate, direct).",
|
|
169
|
+
"when": "To understand which aspects are most frequently referenced and which might be under-utilized.",
|
|
170
|
+
"example": "paradigm_aspect_heatmap({ limit: 10 })"
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"id": "paradigm-aspect-suggest-scan",
|
|
174
|
+
"name": "paradigm_aspect_suggest_scan",
|
|
175
|
+
"description": "Scan a source file for undocumented aspects — magic numbers, hardcoded strings, rate limits, time values, env checks, feature flags, and regex patterns.",
|
|
176
|
+
"when": "When auditing a file for rules and constraints that should be documented as aspects.",
|
|
177
|
+
"example": "paradigm_aspect_suggest_scan({ filePath: 'src/auth/jwt.ts' })"
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"id": "paradigm-aspect-drift",
|
|
181
|
+
"name": "paradigm_aspect_drift",
|
|
182
|
+
"description": "Check aspect anchors for content drift — detects when code at anchored line ranges has changed since the last scan.",
|
|
183
|
+
"when": "During maintenance to find stale anchors, or after significant refactoring to verify aspect integrity.",
|
|
184
|
+
"example": "paradigm_aspect_drift({ aspectId: 'token-expiry-24h' })"
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
"id": "paradigm-aspect-confirm",
|
|
188
|
+
"name": "paradigm_aspect_confirm",
|
|
189
|
+
"description": "Confirm a search result to improve future search quality. Reinforces the query-to-aspect mapping in the learning system.",
|
|
190
|
+
"when": "After selecting a result from paradigm_aspect_search. This is how the search gets smarter over time.",
|
|
191
|
+
"example": "paradigm_aspect_confirm({ query: 'jwt expiry', aspectId: 'token-expiry-24h' })"
|
|
192
|
+
},
|
|
144
193
|
{
|
|
145
194
|
"id": "paradigm-purpose-validate",
|
|
146
195
|
"name": "paradigm_purpose_validate",
|
|
@@ -196,6 +245,67 @@
|
|
|
196
245
|
"description": "Save a session checkpoint for crash recovery. Captures phase, context, modified files, symbols, and decisions. Stored in .paradigm/session-checkpoint.json with 7-day expiry.",
|
|
197
246
|
"when": "At every phase transition — after planning, during implementation, before validation, and on completion.",
|
|
198
247
|
"example": "paradigm_session_checkpoint({ phase: 'implementing', context: 'Adding JWT auth middleware', modifiedFiles: ['src/middleware/auth.ts'], symbolsTouched: ['#auth-middleware'] })"
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
"id": "paradigm-sentinel-record",
|
|
251
|
+
"name": "paradigm_sentinel_record",
|
|
252
|
+
"description": "Record a symbolic incident mapping a runtime error to Paradigm symbols. Captures error details, symbolic context, environment, and optional flow position.",
|
|
253
|
+
"when": "When an error occurs and you want to track it in Sentinel with full symbolic context for pattern matching and triage.",
|
|
254
|
+
"example": "paradigm_sentinel_record({ error: { message: 'Stripe 429', type: 'RateLimitError' }, symbols: { component: '#payment-service' }, environment: 'production' })"
|
|
255
|
+
}
|
|
256
|
+
]
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
"id": "habit-check-types",
|
|
260
|
+
"title": "Habit Check Types",
|
|
261
|
+
"cards": [
|
|
262
|
+
{
|
|
263
|
+
"id": "tool-called",
|
|
264
|
+
"name": "tool-called",
|
|
265
|
+
"description": "Verifies that specified MCP tools were invoked during the session. Any one tool from the list suffices.",
|
|
266
|
+
"when": "For discovery habits (ripple, navigate), collaboration habits (wisdom), and verification habits (postflight)."
|
|
267
|
+
},
|
|
268
|
+
{
|
|
269
|
+
"id": "file-exists",
|
|
270
|
+
"name": "file-exists",
|
|
271
|
+
"description": "Verifies that files matching glob patterns exist. Used for .purpose file coverage and test existence.",
|
|
272
|
+
"when": "For documentation habits (.purpose coverage) and testing habits (test file existence)."
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
"id": "lore-recorded",
|
|
276
|
+
"name": "lore-recorded",
|
|
277
|
+
"description": "Verifies a lore entry was created during sessions that modify 3+ source files.",
|
|
278
|
+
"when": "For documentation habits that enforce lore recording for significant sessions."
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
"id": "gates-declared",
|
|
282
|
+
"name": "gates-declared",
|
|
283
|
+
"description": "Verifies routes added during the session have corresponding gate declarations in portal.yaml.",
|
|
284
|
+
"when": "For security habits that ensure every API endpoint has authorization gates."
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
"id": "commit-message-format",
|
|
288
|
+
"name": "commit-message-format",
|
|
289
|
+
"description": "Verifies commit messages match required regex patterns — default: conventional commit type(#symbol): prefix and Symbols: trailer.",
|
|
290
|
+
"when": "On-commit trigger to enforce consistent, symbol-aware commit messages."
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
"id": "flow-coverage",
|
|
294
|
+
"name": "flow-coverage",
|
|
295
|
+
"description": "Verifies that changes spanning 3+ components have a documented $flow or that flow tools were invoked.",
|
|
296
|
+
"when": "Postflight trigger to ensure multi-component changes are documented as flows."
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
"id": "context-checked",
|
|
300
|
+
"name": "context-checked",
|
|
301
|
+
"description": "Verifies that session context/recovery tools (paradigm_context_check, paradigm_session_recover, paradigm_session_checkpoint) were called.",
|
|
302
|
+
"when": "Preflight trigger to encourage session continuity and context awareness."
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
"id": "aspect-anchored",
|
|
306
|
+
"name": "aspect-anchored",
|
|
307
|
+
"description": "Verifies that aspects (~) touched during the session have valid code anchors via paradigm_aspect_check.",
|
|
308
|
+
"when": "Postflight trigger to ensure aspect anchors remain valid after code changes."
|
|
199
309
|
}
|
|
200
310
|
]
|
|
201
311
|
},
|
|
@@ -268,6 +378,36 @@
|
|
|
268
378
|
"command": "paradigm lore <subcommand>",
|
|
269
379
|
"description": "Manage project lore — the timeline of sessions, decisions, milestones, and incidents. Subcommands: list (show recent entries), show (display a specific entry), record (create a new entry interactively), review (add review scores to an entry).",
|
|
270
380
|
"flags": ["list [--limit 10] [--type agent-session]: List recent entries", "show <id>: Display a specific lore entry", "record [--type agent-session]: Record a new entry", "review <id>: Add completeness and quality scores to an entry"]
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
"id": "portal-export",
|
|
384
|
+
"command": "paradigm portal export",
|
|
385
|
+
"description": "Export portal configuration in machine-readable formats. Outputs gates and routes for CI audits, documentation, or spreadsheet analysis.",
|
|
386
|
+
"flags": ["-f, --format <format>: Output format — json (default), csv, markdown", "-o, --output <file>: Write to file instead of stdout", "-c, --config <path>: Path to portal.yaml (default: ./portal.yaml)"]
|
|
387
|
+
},
|
|
388
|
+
{
|
|
389
|
+
"id": "lint",
|
|
390
|
+
"command": "paradigm lint",
|
|
391
|
+
"description": "Check .purpose files for completeness — validates required fields, symbol formatting, tag references. With --auto-populate, scans source directories for undocumented components and suggests draft .purpose files.",
|
|
392
|
+
"flags": ["--fix: Auto-fix lint issues (or write draft .purpose files with --auto-populate)", "--strict: Treat warnings as errors", "--auto-populate: Scan source dirs for undocumented components and suggest .purpose drafts"]
|
|
393
|
+
},
|
|
394
|
+
{
|
|
395
|
+
"id": "sync-llms",
|
|
396
|
+
"command": "paradigm sync-llms",
|
|
397
|
+
"description": "Generate llms.txt at the project root — a plain-text project summary optimized for LLM consumption. Includes symbols, key files, flows, gates, and conventions.",
|
|
398
|
+
"flags": ["-o, --output <path>: Output path (default: ./llms.txt)"]
|
|
399
|
+
},
|
|
400
|
+
{
|
|
401
|
+
"id": "flow-diagram",
|
|
402
|
+
"command": "paradigm flow diagram <flowId>",
|
|
403
|
+
"description": "Generate a Mermaid flowchart diagram for a flow. Gates appear as diamonds, actions as rectangles, signals as rounded boxes. Color-coded by step type.",
|
|
404
|
+
"flags": ["-o, --output <path>: Write diagram to file instead of stdout"]
|
|
405
|
+
},
|
|
406
|
+
{
|
|
407
|
+
"id": "global-clean",
|
|
408
|
+
"command": "paradigm global clean",
|
|
409
|
+
"description": "Remove old files from ~/.paradigm/ (Global Brain rotation). Scans wisdom, lore, history, and cache subdirectories for files older than the specified duration.",
|
|
410
|
+
"flags": ["--older-than <duration>: Duration threshold (default: 90d). Supports d (days), h (hours), m (minutes)", "-n, --dry-run: Show what would be deleted without deleting"]
|
|
271
411
|
}
|
|
272
412
|
]
|
|
273
413
|
},
|
|
@@ -392,6 +532,136 @@
|
|
|
392
532
|
]
|
|
393
533
|
}
|
|
394
534
|
]
|
|
535
|
+
},
|
|
536
|
+
{
|
|
537
|
+
"id": "aspect-categories",
|
|
538
|
+
"title": "Aspect Categories",
|
|
539
|
+
"cards": [
|
|
540
|
+
{
|
|
541
|
+
"id": "category-rule",
|
|
542
|
+
"name": "rule",
|
|
543
|
+
"description": "A mandatory pattern that must be followed across the codebase. Rules are non-negotiable constraints enforced by code. Inferred from descriptions containing 'must', 'always', 'never', 'required'.",
|
|
544
|
+
"examples": ["~no-console-log", "~audit-required", "~idempotent-payments"],
|
|
545
|
+
"when": "When a pattern must be followed without exception — if violating it would be a bug or compliance issue."
|
|
546
|
+
},
|
|
547
|
+
{
|
|
548
|
+
"id": "category-decision",
|
|
549
|
+
"name": "decision",
|
|
550
|
+
"description": "An architectural or design choice with documented rationale. Decisions capture the 'why' behind implementation choices. Inferred from descriptions containing 'decided', 'chosen', 'selected', 'opted'.",
|
|
551
|
+
"examples": ["~use-redis-for-sessions", "~jwt-signing-rs256", "~monorepo-structure"],
|
|
552
|
+
"when": "When a deliberate choice was made between alternatives and the rationale should be preserved for future reference."
|
|
553
|
+
},
|
|
554
|
+
{
|
|
555
|
+
"id": "category-constraint",
|
|
556
|
+
"name": "constraint",
|
|
557
|
+
"description": "A quantitative limit or boundary on system behavior. Constraints define the numeric or measurable boundaries of operations. Inferred from descriptions containing 'limit', 'maximum', 'minimum', 'cannot exceed'.",
|
|
558
|
+
"examples": ["~max-upload-10mb", "~rate-limit-100-per-minute", "~session-timeout-30m"],
|
|
559
|
+
"when": "When a measurable boundary exists — file size limits, rate limits, timeouts, quotas, or thresholds."
|
|
560
|
+
},
|
|
561
|
+
{
|
|
562
|
+
"id": "category-configuration",
|
|
563
|
+
"name": "configuration",
|
|
564
|
+
"description": "A configurable value or setting that controls system behavior. Configuration aspects document values that may change per environment. Inferred from descriptions containing 'configured', 'set to', 'defaults to', 'environment'.",
|
|
565
|
+
"examples": ["~default-page-size-25", "~cache-ttl-5m", "~feature-flag-new-checkout"],
|
|
566
|
+
"when": "When a value is environment-specific or tunable — defaults, feature flags, environment variables, or deployment settings."
|
|
567
|
+
},
|
|
568
|
+
{
|
|
569
|
+
"id": "category-invariant",
|
|
570
|
+
"name": "invariant",
|
|
571
|
+
"description": "A condition that must always hold true in the system. Invariants are guarantees about system state that should never be violated. Inferred from descriptions containing 'always true', 'never negative', 'invariant', 'guarantee'.",
|
|
572
|
+
"examples": ["~balance-never-negative", "~user-always-has-email", "~order-total-matches-items"],
|
|
573
|
+
"when": "When a system property must hold at all times — data integrity rules, mathematical invariants, or state consistency guarantees."
|
|
574
|
+
}
|
|
575
|
+
]
|
|
576
|
+
},
|
|
577
|
+
{
|
|
578
|
+
"id": "aspect-edge-relations",
|
|
579
|
+
"title": "Aspect Edge Relations",
|
|
580
|
+
"cards": [
|
|
581
|
+
{
|
|
582
|
+
"id": "edge-enforced-by",
|
|
583
|
+
"name": "enforced-by",
|
|
584
|
+
"description": "Indicates that an aspect is enforced by another symbol — typically a component, middleware, or gate that implements the rule in code. The target symbol contains the enforcement logic.",
|
|
585
|
+
"examples": ["~audit-required --enforced-by--> #audit-middleware", "~rate-limited --enforced-by--> ^rate-limiter"],
|
|
586
|
+
"when": "When an aspect has a concrete enforcement mechanism in code. This is the most common edge type for rules and constraints."
|
|
587
|
+
},
|
|
588
|
+
{
|
|
589
|
+
"id": "edge-depends-on",
|
|
590
|
+
"name": "depends-on",
|
|
591
|
+
"description": "Indicates that an aspect depends on another aspect or symbol for its correct functioning. If the dependency changes, the dependent aspect may need updating.",
|
|
592
|
+
"examples": ["~token-expiry-24h --depends-on--> ~jwt-signing-rs256", "~cache-invalidation --depends-on--> #event-bus"],
|
|
593
|
+
"when": "When changing one aspect could break or invalidate another. The ripple analysis follows these edges to discover indirect impacts."
|
|
594
|
+
},
|
|
595
|
+
{
|
|
596
|
+
"id": "edge-contradicts",
|
|
597
|
+
"name": "contradicts",
|
|
598
|
+
"description": "Indicates that two aspects are in tension or direct conflict. Contradictions signal architectural tensions that need resolution or documented trade-offs.",
|
|
599
|
+
"examples": ["~cache-aggressively --contradicts--> ~always-fresh-data", "~minimal-logging --contradicts--> ~full-audit-trail"],
|
|
600
|
+
"when": "When two aspects cannot both be fully satisfied simultaneously. Documenting contradictions makes trade-offs visible rather than hidden."
|
|
601
|
+
},
|
|
602
|
+
{
|
|
603
|
+
"id": "edge-supersedes",
|
|
604
|
+
"name": "supersedes",
|
|
605
|
+
"description": "Indicates that an aspect replaces or overrides a previous version. The superseded aspect is still referenced for history but the superseding one is authoritative.",
|
|
606
|
+
"examples": ["~rate-limit-v2 --supersedes--> ~rate-limit-v1", "~auth-jwt --supersedes--> ~auth-session-cookie"],
|
|
607
|
+
"when": "When an aspect evolves and a newer version replaces the old one. Keeps the historical chain visible while directing users to the current version."
|
|
608
|
+
},
|
|
609
|
+
{
|
|
610
|
+
"id": "edge-related-to",
|
|
611
|
+
"name": "related-to",
|
|
612
|
+
"description": "The weakest relation — indicates a loose association between two symbols. Useful for discovery but not for impact analysis. Does not imply dependency or enforcement.",
|
|
613
|
+
"examples": ["~password-policy --related-to--> ~account-lockout", "~api-versioning --related-to--> ~deprecation-strategy"],
|
|
614
|
+
"when": "When two aspects are conceptually related but do not have a stronger structural relationship like enforcement or dependency."
|
|
615
|
+
}
|
|
616
|
+
]
|
|
617
|
+
},
|
|
618
|
+
{
|
|
619
|
+
"id": "configurable-limits",
|
|
620
|
+
"title": "Configurable Limits",
|
|
621
|
+
"cards": [
|
|
622
|
+
{
|
|
623
|
+
"id": "limits-overview",
|
|
624
|
+
"name": "limits in config.yaml",
|
|
625
|
+
"description": "Paradigm supports configurable limits in .paradigm/config.yaml under a `limits` key. These tune cache TTLs, breadcrumb retention, and checkpoint lifetimes.",
|
|
626
|
+
"when": "When default values don't fit your workflow — e.g., longer cache TTL for stable projects, shorter checkpoint expiry for fast-moving teams."
|
|
627
|
+
},
|
|
628
|
+
{
|
|
629
|
+
"id": "habits-cache-ttl",
|
|
630
|
+
"name": "habitsCacheTtlMs",
|
|
631
|
+
"description": "Habits cache TTL in milliseconds. Controls how long loaded habit definitions are cached before being re-read from YAML files. Default: 30000 (30 seconds).",
|
|
632
|
+
"when": "Set higher for stable habit configs; set to 0 to always re-read."
|
|
633
|
+
},
|
|
634
|
+
{
|
|
635
|
+
"id": "tool-cache-ttl",
|
|
636
|
+
"name": "toolCacheTtlMs",
|
|
637
|
+
"description": "MCP tool cache TTL in milliseconds. Controls how long paradigm_search, paradigm_status, and paradigm_navigate results are cached. Default: 30000 (30 seconds).",
|
|
638
|
+
"when": "Set higher for large, stable projects; set to 0 to disable caching."
|
|
639
|
+
},
|
|
640
|
+
{
|
|
641
|
+
"id": "thread-trail-max",
|
|
642
|
+
"name": "threadTrailMax",
|
|
643
|
+
"description": "Maximum thread trail/breadcrumb entries retained in thread output. Default: 10.",
|
|
644
|
+
"when": "Increase for complex sessions that need more trail context."
|
|
645
|
+
},
|
|
646
|
+
{
|
|
647
|
+
"id": "breadcrumbs-max",
|
|
648
|
+
"name": "breadcrumbsMax",
|
|
649
|
+
"description": "Maximum session breadcrumbs retained by the session tracker. Default: 50.",
|
|
650
|
+
"when": "Increase for very long sessions; decrease to reduce checkpoint file size."
|
|
651
|
+
},
|
|
652
|
+
{
|
|
653
|
+
"id": "checkpoint-max-age",
|
|
654
|
+
"name": "checkpointMaxAgeMs",
|
|
655
|
+
"description": "Maximum age of session checkpoints before they expire. Default: 604800000 (7 days).",
|
|
656
|
+
"when": "Shorten for teams that don't want stale recovery data; lengthen for projects with infrequent sessions."
|
|
657
|
+
},
|
|
658
|
+
{
|
|
659
|
+
"id": "aspect-search-decay",
|
|
660
|
+
"name": "Search Weight Decay",
|
|
661
|
+
"description": "When a search result is confirmed, the selected aspect gets +1.0 weight while all other results for the same query decay by *0.95. This self-correcting mechanism prevents stale mappings.",
|
|
662
|
+
"when": "Automatic — happens on every paradigm_aspect_confirm call."
|
|
663
|
+
}
|
|
664
|
+
]
|
|
395
665
|
}
|
|
396
666
|
]
|
|
397
667
|
}
|
|
@@ -117,7 +117,83 @@ async function portalReportCommand(sessionPath, options = {}) {
|
|
|
117
117
|
process.exit(1);
|
|
118
118
|
}
|
|
119
119
|
}
|
|
120
|
+
async function portalExportCommand(targetPath, options = {}) {
|
|
121
|
+
const rootDir = targetPath ? path.resolve(targetPath) : process.cwd();
|
|
122
|
+
const configPath = options.config || path.join(rootDir, "portal.yaml");
|
|
123
|
+
const format = options.format || "json";
|
|
124
|
+
if (!fs.existsSync(configPath)) {
|
|
125
|
+
console.error(chalk.red(`portal.yaml not found at ${configPath}`));
|
|
126
|
+
process.exit(1);
|
|
127
|
+
}
|
|
128
|
+
const { parse } = await import("./dist-JOHRYQUA.js");
|
|
129
|
+
const raw = fs.readFileSync(configPath, "utf8");
|
|
130
|
+
const config = parse(raw);
|
|
131
|
+
const gates = config.gates || {};
|
|
132
|
+
const routes = config.routes || {};
|
|
133
|
+
let output;
|
|
134
|
+
switch (format) {
|
|
135
|
+
case "csv": {
|
|
136
|
+
const lines = ["route,method,gates"];
|
|
137
|
+
for (const [routeKey, routeGates] of Object.entries(routes)) {
|
|
138
|
+
const parts = routeKey.split(" ");
|
|
139
|
+
const method = parts.length > 1 ? parts[0] : "ANY";
|
|
140
|
+
const routePath = parts.length > 1 ? parts.slice(1).join(" ") : routeKey;
|
|
141
|
+
const gateList = Array.isArray(routeGates) ? routeGates.join(";") : String(routeGates);
|
|
142
|
+
lines.push(`${routePath},${method},"${gateList}"`);
|
|
143
|
+
}
|
|
144
|
+
output = lines.join("\n");
|
|
145
|
+
break;
|
|
146
|
+
}
|
|
147
|
+
case "markdown": {
|
|
148
|
+
const lines = [
|
|
149
|
+
`# Portal Configuration`,
|
|
150
|
+
"",
|
|
151
|
+
`**Version:** ${config.version || "unknown"}`,
|
|
152
|
+
"",
|
|
153
|
+
"## Gates",
|
|
154
|
+
"",
|
|
155
|
+
"| Gate | Description | Check |",
|
|
156
|
+
"|------|-------------|-------|"
|
|
157
|
+
];
|
|
158
|
+
for (const [gateId, gate] of Object.entries(gates)) {
|
|
159
|
+
const g = gate;
|
|
160
|
+
lines.push(`| ^${gateId} | ${g.description || ""} | \`${g.check || ""}\` |`);
|
|
161
|
+
}
|
|
162
|
+
lines.push("", "## Routes", "", "| Route | Gates |", "|-------|-------|");
|
|
163
|
+
for (const [routeKey, routeGates] of Object.entries(routes)) {
|
|
164
|
+
const gateList = Array.isArray(routeGates) ? routeGates.join(", ") : String(routeGates);
|
|
165
|
+
lines.push(`| ${routeKey} | ${gateList} |`);
|
|
166
|
+
}
|
|
167
|
+
output = lines.join("\n");
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
case "json":
|
|
171
|
+
default: {
|
|
172
|
+
const exported = {
|
|
173
|
+
version: config.version,
|
|
174
|
+
exportedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
175
|
+
gates: Object.entries(gates).map(([id, g]) => ({
|
|
176
|
+
id,
|
|
177
|
+
...g
|
|
178
|
+
})),
|
|
179
|
+
routes: Object.entries(routes).map(([route, routeGates]) => ({
|
|
180
|
+
route,
|
|
181
|
+
gates: routeGates
|
|
182
|
+
}))
|
|
183
|
+
};
|
|
184
|
+
output = JSON.stringify(exported, null, 2);
|
|
185
|
+
break;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (options.output) {
|
|
189
|
+
fs.writeFileSync(options.output, output, "utf8");
|
|
190
|
+
console.log(chalk.green(`Exported portal config to ${chalk.cyan(options.output)} (${format})`));
|
|
191
|
+
} else {
|
|
192
|
+
console.log(output);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
120
195
|
export {
|
|
196
|
+
portalExportCommand,
|
|
121
197
|
portalReportCommand,
|
|
122
198
|
portalWatchCommand
|
|
123
199
|
};
|