guardian-framework 0.1.24 → 0.1.26
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/cli.js +333 -29
- package/dist/exports.js +333 -29
- package/package.json +1 -1
- package/templates/pi/architecture/modules/module-template.md +90 -57
- package/templates/pi/extensions/domain-explorer.ts +402 -108
- package/templates/pi/preflight_report.json +1 -1
- package/templates/pi/skills/agents/design-system-codegen.md +41 -0
- package/templates/pi/skills/design-system-enterprise-codegen.md +241 -237
- package/templates/pi/skills/nextjs-enterprise-codegen.md +302 -292
package/dist/cli.js
CHANGED
|
@@ -1335,7 +1335,7 @@ __export(exports_package, {
|
|
|
1335
1335
|
bin: () => bin,
|
|
1336
1336
|
author: () => author
|
|
1337
1337
|
});
|
|
1338
|
-
var name = "guardian-framework", version = "0.1.
|
|
1338
|
+
var name = "guardian-framework", version = "0.1.26", description = "Token-optimized agentic framework scaffolder with pi-first architecture", type = "module", main = "dist/exports.js", exports, types = "dist/exports.d.ts", bin, files, engines, scripts, publishConfig, pi, repository, homepage = "https://github.com/arman-jalili/guardian-framework#readme", bugs, dependencies, devDependencies, keywords, author = "Arman Wolkensteiner-Jalili", license = "MIT", package_default;
|
|
1339
1339
|
var init_package = __esm(() => {
|
|
1340
1340
|
exports = {
|
|
1341
1341
|
".": {
|
|
@@ -9821,6 +9821,115 @@ Respond with ONLY valid JSON matching this exact structure. Do not include markd
|
|
|
9821
9821
|
"aggregateRoots": "Which entities are aggregate roots and why"
|
|
9822
9822
|
}`;
|
|
9823
9823
|
}
|
|
9824
|
+
function buildFrontendExplorationPrompt(context) {
|
|
9825
|
+
const sanitized = sanitizeBusinessContext(context);
|
|
9826
|
+
return `You are a frontend architecture expert. Analyze the following web application description and extract a structured model focused on user experience, UI concepts, and design principles.
|
|
9827
|
+
|
|
9828
|
+
Business Context:
|
|
9829
|
+
${sanitized}
|
|
9830
|
+
|
|
9831
|
+
Respond with ONLY valid JSON matching this exact structure. Do not include markdown formatting, code fences, or explanatory text:
|
|
9832
|
+
|
|
9833
|
+
{
|
|
9834
|
+
"sessionId": "auto-generated-uuid",
|
|
9835
|
+
"businessContext": "original description",
|
|
9836
|
+
"status": "draft",
|
|
9837
|
+
"actors": [
|
|
9838
|
+
{
|
|
9839
|
+
"name": "UserRole",
|
|
9840
|
+
"description": "Who this user is",
|
|
9841
|
+
"interactions": "What they do in the application"
|
|
9842
|
+
}
|
|
9843
|
+
],
|
|
9844
|
+
"functionalRequirements": [
|
|
9845
|
+
{
|
|
9846
|
+
"id": "FR-001",
|
|
9847
|
+
"requirement": "The user shall be able to...",
|
|
9848
|
+
"priority": "critical|high|medium|low",
|
|
9849
|
+
"boundedContext": "FeatureName"
|
|
9850
|
+
}
|
|
9851
|
+
],
|
|
9852
|
+
"nonFunctionalRequirements": [
|
|
9853
|
+
{
|
|
9854
|
+
"id": "NFR-001",
|
|
9855
|
+
"requirement": "The application shall...",
|
|
9856
|
+
"category": "performance|accessibility|usability|security|maintainability",
|
|
9857
|
+
"target": "Specific measurable target"
|
|
9858
|
+
}
|
|
9859
|
+
],
|
|
9860
|
+
"assumptions": [
|
|
9861
|
+
{
|
|
9862
|
+
"assumption": "We assume that...",
|
|
9863
|
+
"impactIfWrong": "What breaks if this is false",
|
|
9864
|
+
"mitigation": "How we handle it being wrong"
|
|
9865
|
+
}
|
|
9866
|
+
],
|
|
9867
|
+
"boundedContexts": [
|
|
9868
|
+
{
|
|
9869
|
+
"name": "FeatureName",
|
|
9870
|
+
"description": "Brief description of this app feature/section",
|
|
9871
|
+
"entities": ["UIConcept1", "UIConcept2"]
|
|
9872
|
+
}
|
|
9873
|
+
],
|
|
9874
|
+
"entities": [
|
|
9875
|
+
{
|
|
9876
|
+
"name": "UIConceptName",
|
|
9877
|
+
"context": "FeatureName",
|
|
9878
|
+
"type": "ui-concept | user-intent | design-token | app-shell | value-object",
|
|
9879
|
+
"description": "What this UI concept represents"
|
|
9880
|
+
}
|
|
9881
|
+
],
|
|
9882
|
+
"userIntents": [
|
|
9883
|
+
{
|
|
9884
|
+
"name": "UserIntentName",
|
|
9885
|
+
"context": "FeatureName",
|
|
9886
|
+
"description": "What the user is trying to do",
|
|
9887
|
+
"triggeredBy": "What UI action triggers this intent"
|
|
9888
|
+
}
|
|
9889
|
+
],
|
|
9890
|
+
"designPrinciples": [
|
|
9891
|
+
{
|
|
9892
|
+
"principle": "The application is...",
|
|
9893
|
+
"description": "What this principle means in practice",
|
|
9894
|
+
"rationale": "Why this principle exists"
|
|
9895
|
+
}
|
|
9896
|
+
],
|
|
9897
|
+
"navigationPhilosophy": {
|
|
9898
|
+
"contextPreservation": "How the user never loses context",
|
|
9899
|
+
"deepLinking": "How every page is deep-linkable",
|
|
9900
|
+
"multiTab": "How multiple tabs are supported"
|
|
9901
|
+
},
|
|
9902
|
+
"appShell": {
|
|
9903
|
+
"navigation": "Navigation structure",
|
|
9904
|
+
"header": "Header content",
|
|
9905
|
+
"sidebar": "Sidebar content",
|
|
9906
|
+
"commandPalette": "Command palette actions",
|
|
9907
|
+
"globalSearch": "Global search behavior"
|
|
9908
|
+
},
|
|
9909
|
+
"degradationStrategy": [
|
|
9910
|
+
{
|
|
9911
|
+
"feature": "FeatureName",
|
|
9912
|
+
"whenUnavailable": "What happens when this feature's API is down",
|
|
9913
|
+
"degradesTo": "What still works"
|
|
9914
|
+
}
|
|
9915
|
+
],
|
|
9916
|
+
"ubiquitousLanguage": [
|
|
9917
|
+
{
|
|
9918
|
+
"term": "CanonicalTerm",
|
|
9919
|
+
"definition": "Clear definition",
|
|
9920
|
+
"boundedContext": "FeatureName",
|
|
9921
|
+
"aliases": ["AlternativeName1"],
|
|
9922
|
+
"examples": "Usage example"
|
|
9923
|
+
}
|
|
9924
|
+
],
|
|
9925
|
+
"openQuestions": "Any open questions about the application",
|
|
9926
|
+
"designSystem": {
|
|
9927
|
+
"componentLibrary": "Which component library or approach (Tailwind, MUI, custom)",
|
|
9928
|
+
"theming": "How theming works (dark mode, branding)",
|
|
9929
|
+
"accessibility": "Accessibility requirements"
|
|
9930
|
+
}
|
|
9931
|
+
}`;
|
|
9932
|
+
}
|
|
9824
9933
|
function parseExplorationResponse(rawResponse, sessionId) {
|
|
9825
9934
|
try {
|
|
9826
9935
|
let cleaned = rawResponse.trim();
|
|
@@ -9902,6 +10011,14 @@ function coerceEntityType(val) {
|
|
|
9902
10011
|
return "value-object";
|
|
9903
10012
|
if (val === "aggregate-root")
|
|
9904
10013
|
return "aggregate-root";
|
|
10014
|
+
if (val === "ui-concept")
|
|
10015
|
+
return "ui-concept";
|
|
10016
|
+
if (val === "user-intent")
|
|
10017
|
+
return "user-intent";
|
|
10018
|
+
if (val === "design-token")
|
|
10019
|
+
return "design-token";
|
|
10020
|
+
if (val === "app-shell")
|
|
10021
|
+
return "app-shell";
|
|
9905
10022
|
return "entity";
|
|
9906
10023
|
}
|
|
9907
10024
|
function coerceFrPriority(val) {
|
|
@@ -9986,8 +10103,20 @@ async function exploreDomain(context, options) {
|
|
|
9986
10103
|
if (!fs.existsSync(explorationDir)) {
|
|
9987
10104
|
fs.mkdirSync(explorationDir, { recursive: true });
|
|
9988
10105
|
}
|
|
10106
|
+
let lang = options?.language;
|
|
10107
|
+
if (!lang) {
|
|
10108
|
+
try {
|
|
10109
|
+
const manifestPath = path.join(projectDir, "guardian-manifest.json");
|
|
10110
|
+
if (fs.existsSync(manifestPath)) {
|
|
10111
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
|
|
10112
|
+
if (manifest.language)
|
|
10113
|
+
lang = manifest.language;
|
|
10114
|
+
}
|
|
10115
|
+
} catch {}
|
|
10116
|
+
}
|
|
9989
10117
|
const sanitized = sanitizeBusinessContext(context);
|
|
9990
|
-
const
|
|
10118
|
+
const isFrontend = lang === "nextjs" || lang === "angular";
|
|
10119
|
+
const prompt = isFrontend ? buildFrontendExplorationPrompt(sanitized) : buildExplorationPrompt(sanitized);
|
|
9991
10120
|
const promptContent = [
|
|
9992
10121
|
"# Domain Exploration Prompt",
|
|
9993
10122
|
"",
|
|
@@ -10140,6 +10269,18 @@ function extractTable(body, sectionName) {
|
|
|
10140
10269
|
function scaffoldFromExploration(sessionId, options) {
|
|
10141
10270
|
const projectDir = options?.projectDir ?? process.cwd();
|
|
10142
10271
|
const dryRun = options?.dryRun ?? false;
|
|
10272
|
+
let lang = options?.language;
|
|
10273
|
+
if (!lang) {
|
|
10274
|
+
try {
|
|
10275
|
+
const manifestPath = path.join(projectDir, "guardian-manifest.json");
|
|
10276
|
+
if (fs.existsSync(manifestPath)) {
|
|
10277
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
|
|
10278
|
+
if (manifest.language)
|
|
10279
|
+
lang = manifest.language;
|
|
10280
|
+
}
|
|
10281
|
+
} catch {}
|
|
10282
|
+
}
|
|
10283
|
+
const isFrontend = lang === "nextjs" || lang === "angular";
|
|
10143
10284
|
const sessionResult = readExplorationSession(sessionId, projectDir);
|
|
10144
10285
|
if (!sessionResult) {
|
|
10145
10286
|
throw new Error(`Exploration session not found: ${sessionId}`);
|
|
@@ -10261,76 +10402,239 @@ function scaffoldFromExploration(sessionId, options) {
|
|
|
10261
10402
|
`;
|
|
10262
10403
|
}
|
|
10263
10404
|
}
|
|
10264
|
-
let content =
|
|
10405
|
+
let content = "";
|
|
10406
|
+
if (isFrontend) {
|
|
10407
|
+
const uiConcepts = contextEntities.filter((e2) => e2.type === "ui-concept");
|
|
10408
|
+
const userIntents = contextEntities.filter((e2) => e2.type === "user-intent");
|
|
10409
|
+
const designTokens = contextEntities.filter((e2) => e2.type === "design-token");
|
|
10410
|
+
const appShells = contextEntities.filter((e2) => e2.type === "app-shell");
|
|
10411
|
+
content = `# ${bc.name}
|
|
10265
10412
|
|
|
10266
10413
|
`;
|
|
10267
|
-
|
|
10414
|
+
content += `## Module Status
|
|
10268
10415
|
|
|
10269
10416
|
`;
|
|
10270
|
-
|
|
10417
|
+
content += `**Status:** Planned
|
|
10271
10418
|
`;
|
|
10272
|
-
|
|
10419
|
+
content += `**Last reviewed:** ${timestamp}
|
|
10273
10420
|
`;
|
|
10274
|
-
|
|
10421
|
+
content += `**Source session:** ${sessionId}
|
|
10275
10422
|
|
|
10276
10423
|
`;
|
|
10277
|
-
|
|
10424
|
+
content += `## Description
|
|
10278
10425
|
|
|
10279
10426
|
${bc.description}
|
|
10280
10427
|
|
|
10281
10428
|
`;
|
|
10282
|
-
|
|
10429
|
+
content += `## UI Concepts
|
|
10283
10430
|
|
|
10284
|
-
${componentsSection}
|
|
10285
10431
|
`;
|
|
10286
|
-
|
|
10432
|
+
if (uiConcepts.length === 0) {
|
|
10433
|
+
content += `None defined yet.
|
|
10287
10434
|
|
|
10288
10435
|
`;
|
|
10289
|
-
|
|
10290
|
-
|
|
10436
|
+
} else {
|
|
10437
|
+
for (const uc of uiConcepts) {
|
|
10438
|
+
content += `### ${uc.name}
|
|
10439
|
+
`;
|
|
10440
|
+
content += `**Description:** ${uc.description}
|
|
10291
10441
|
|
|
10292
10442
|
`;
|
|
10293
|
-
|
|
10294
|
-
|
|
10295
|
-
|
|
10443
|
+
}
|
|
10444
|
+
}
|
|
10445
|
+
content += `## User Intents
|
|
10446
|
+
|
|
10296
10447
|
`;
|
|
10448
|
+
if (userIntents.length === 0) {
|
|
10449
|
+
content += `None defined yet.
|
|
10450
|
+
|
|
10451
|
+
`;
|
|
10452
|
+
} else {
|
|
10453
|
+
for (const ui of userIntents) {
|
|
10454
|
+
content += `### ${ui.name}
|
|
10455
|
+
`;
|
|
10456
|
+
content += `**Description:** ${ui.description}
|
|
10457
|
+
|
|
10458
|
+
`;
|
|
10459
|
+
}
|
|
10297
10460
|
}
|
|
10461
|
+
if (designTokens.length > 0) {
|
|
10462
|
+
content += `## Design Tokens
|
|
10463
|
+
|
|
10464
|
+
`;
|
|
10465
|
+
for (const dt of designTokens) {
|
|
10466
|
+
content += `- **${dt.name}** - ${dt.description}
|
|
10467
|
+
`;
|
|
10468
|
+
}
|
|
10469
|
+
content += `
|
|
10470
|
+
`;
|
|
10471
|
+
}
|
|
10472
|
+
if (appShells.length > 0) {
|
|
10473
|
+
content += `## App Shell Integration
|
|
10474
|
+
|
|
10475
|
+
`;
|
|
10476
|
+
for (const as of appShells) {
|
|
10477
|
+
content += `- **${as.name}** - ${as.description}
|
|
10478
|
+
`;
|
|
10479
|
+
}
|
|
10480
|
+
content += `
|
|
10481
|
+
`;
|
|
10482
|
+
}
|
|
10483
|
+
content += `## Design Principles
|
|
10484
|
+
|
|
10485
|
+
`;
|
|
10486
|
+
content += `- The Web application is not responsible for enforcing business rules.
|
|
10487
|
+
`;
|
|
10488
|
+
content += `- The Web application is optimistic.
|
|
10489
|
+
`;
|
|
10490
|
+
content += `- The Web application is resilient.
|
|
10491
|
+
`;
|
|
10492
|
+
content += `- The Web application is accessible.
|
|
10493
|
+
`;
|
|
10494
|
+
content += `- The Web application is stateless whenever possible.
|
|
10495
|
+
`;
|
|
10496
|
+
content += `- The Web application delegates authority to Enterprise.
|
|
10497
|
+
`;
|
|
10498
|
+
content += `- The Web application enhances productivity rather than exposing implementation details.
|
|
10499
|
+
`;
|
|
10298
10500
|
content += `
|
|
10299
10501
|
`;
|
|
10300
|
-
|
|
10301
|
-
|
|
10502
|
+
content += `## Navigation Philosophy
|
|
10503
|
+
|
|
10504
|
+
`;
|
|
10505
|
+
content += `- The user shall never lose context.
|
|
10506
|
+
`;
|
|
10507
|
+
content += `- Every screen belongs to a Brain. Every Brain belongs to a Workspace.
|
|
10508
|
+
`;
|
|
10509
|
+
content += `- Every action should expose the current path.
|
|
10510
|
+
`;
|
|
10511
|
+
content += `- Deep linking shall exist for every page.
|
|
10512
|
+
`;
|
|
10513
|
+
content += `- Browser navigation shall always work.
|
|
10514
|
+
`;
|
|
10515
|
+
content += `- Multiple tabs shall be supported.
|
|
10516
|
+
`;
|
|
10517
|
+
content += `
|
|
10518
|
+
`;
|
|
10519
|
+
content += `## Degradation Strategy
|
|
10520
|
+
|
|
10521
|
+
`;
|
|
10522
|
+
content += `- If a feature API is unavailable, navigation still works.
|
|
10523
|
+
`;
|
|
10524
|
+
content += `- Editing still works.
|
|
10525
|
+
`;
|
|
10526
|
+
content += `- AI features are disabled gracefully, not causing errors.
|
|
10527
|
+
`;
|
|
10528
|
+
content += `- The application renders a degraded UI instead of crashing.
|
|
10529
|
+
`;
|
|
10530
|
+
content += `
|
|
10531
|
+
`;
|
|
10532
|
+
content += `## Ubiquitous Language
|
|
10302
10533
|
|
|
10303
10534
|
`;
|
|
10304
|
-
|
|
10305
|
-
|
|
10535
|
+
if (contextTerms.length === 0) {
|
|
10536
|
+
content += `None defined yet.
|
|
10537
|
+
|
|
10538
|
+
`;
|
|
10539
|
+
} else {
|
|
10540
|
+
content += `| Term | Definition | Aliases |
|
|
10541
|
+
`;
|
|
10542
|
+
content += `|------|-----------|---------|
|
|
10543
|
+
`;
|
|
10544
|
+
for (const t of contextTerms) {
|
|
10545
|
+
content += `| ${t.term} | ${t.definition} | ${t.aliases.join(", ")} |
|
|
10546
|
+
`;
|
|
10547
|
+
}
|
|
10548
|
+
content += `
|
|
10549
|
+
`;
|
|
10550
|
+
}
|
|
10551
|
+
content += `## Dependencies
|
|
10552
|
+
|
|
10553
|
+
`;
|
|
10554
|
+
content += `${depsSection}
|
|
10555
|
+
`;
|
|
10556
|
+
content += `## Key Files
|
|
10557
|
+
|
|
10558
|
+
None yet
|
|
10559
|
+
|
|
10560
|
+
`;
|
|
10561
|
+
content += `## ADRs
|
|
10562
|
+
|
|
10563
|
+
None yet
|
|
10306
10564
|
|
|
10307
10565
|
`;
|
|
10308
10566
|
} else {
|
|
10309
|
-
content
|
|
10567
|
+
content = `# ${bc.name}
|
|
10568
|
+
|
|
10310
10569
|
`;
|
|
10311
|
-
content +=
|
|
10570
|
+
content += `## Module Status
|
|
10571
|
+
|
|
10572
|
+
`;
|
|
10573
|
+
content += `**Status:** Planned
|
|
10574
|
+
`;
|
|
10575
|
+
content += `**Last reviewed:** ${timestamp}
|
|
10312
10576
|
`;
|
|
10313
|
-
|
|
10314
|
-
|
|
10577
|
+
content += `**Source session:** ${sessionId}
|
|
10578
|
+
|
|
10579
|
+
`;
|
|
10580
|
+
content += `## Description
|
|
10581
|
+
|
|
10582
|
+
${bc.description}
|
|
10583
|
+
|
|
10584
|
+
`;
|
|
10585
|
+
content += `## Components
|
|
10586
|
+
|
|
10587
|
+
${componentsSection}
|
|
10588
|
+
`;
|
|
10589
|
+
content += `## Domain Events
|
|
10590
|
+
|
|
10591
|
+
`;
|
|
10592
|
+
if (contextEvents.length === 0) {
|
|
10593
|
+
content += `None defined yet.
|
|
10594
|
+
|
|
10595
|
+
`;
|
|
10596
|
+
} else {
|
|
10597
|
+
for (const ev of contextEvents) {
|
|
10598
|
+
content += `- **${ev.name}** - ${ev.description} (triggered by: ${ev.triggeredBy})
|
|
10599
|
+
`;
|
|
10600
|
+
}
|
|
10601
|
+
content += `
|
|
10315
10602
|
`;
|
|
10316
10603
|
}
|
|
10317
|
-
content +=
|
|
10604
|
+
content += `## Ubiquitous Language
|
|
10605
|
+
|
|
10318
10606
|
`;
|
|
10319
|
-
|
|
10320
|
-
|
|
10607
|
+
if (contextTerms.length === 0) {
|
|
10608
|
+
content += `None defined yet.
|
|
10609
|
+
|
|
10610
|
+
`;
|
|
10611
|
+
} else {
|
|
10612
|
+
content += `| Term | Definition | Aliases |
|
|
10613
|
+
`;
|
|
10614
|
+
content += `|------|-----------|---------|
|
|
10615
|
+
`;
|
|
10616
|
+
for (const t of contextTerms) {
|
|
10617
|
+
content += `| ${t.term} | ${t.definition} | ${t.aliases.join(", ")} |
|
|
10618
|
+
`;
|
|
10619
|
+
}
|
|
10620
|
+
content += `
|
|
10621
|
+
`;
|
|
10622
|
+
}
|
|
10623
|
+
content += `## Dependencies
|
|
10321
10624
|
|
|
10322
10625
|
${depsSection}
|
|
10323
10626
|
`;
|
|
10324
|
-
|
|
10627
|
+
content += `## Key Files
|
|
10325
10628
|
|
|
10326
10629
|
None yet
|
|
10327
10630
|
|
|
10328
10631
|
`;
|
|
10329
|
-
|
|
10632
|
+
content += `## ADRs
|
|
10330
10633
|
|
|
10331
10634
|
None yet
|
|
10332
10635
|
|
|
10333
10636
|
`;
|
|
10637
|
+
}
|
|
10334
10638
|
if (!dryRun) {
|
|
10335
10639
|
fs.mkdirSync(modulesDir, { recursive: true });
|
|
10336
10640
|
const tempPath = `${filePath}.tmp`;
|