@tekyzinc/gsd-t 2.50.12 → 2.53.10

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 (99) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/README.md +379 -372
  3. package/bin/component-registry.js +250 -0
  4. package/bin/graph-cgc.js +510 -510
  5. package/bin/graph-indexer.js +147 -147
  6. package/bin/graph-overlay.js +195 -195
  7. package/bin/graph-parsers.js +327 -327
  8. package/bin/graph-query.js +453 -452
  9. package/bin/graph-store.js +154 -154
  10. package/bin/qa-calibrator.js +194 -0
  11. package/bin/scan-data-collector.js +153 -153
  12. package/bin/scan-diagrams-generators.js +187 -187
  13. package/bin/scan-diagrams.js +79 -79
  14. package/bin/scan-renderer.js +92 -92
  15. package/bin/scan-report-sections.js +121 -121
  16. package/bin/scan-report.js +184 -184
  17. package/bin/scan-schema-parsers.js +199 -199
  18. package/bin/scan-schema.js +103 -103
  19. package/bin/token-budget.js +246 -0
  20. package/commands/Claude-md.md +10 -10
  21. package/commands/branch.md +15 -15
  22. package/commands/checkin.md +45 -45
  23. package/commands/global-change.md +209 -209
  24. package/commands/gsd-t-audit.md +199 -0
  25. package/commands/gsd-t-backlog-add.md +94 -94
  26. package/commands/gsd-t-backlog-edit.md +111 -111
  27. package/commands/gsd-t-backlog-list.md +63 -63
  28. package/commands/gsd-t-backlog-move.md +94 -94
  29. package/commands/gsd-t-backlog-promote.md +123 -123
  30. package/commands/gsd-t-backlog-remove.md +86 -86
  31. package/commands/gsd-t-backlog-settings.md +158 -158
  32. package/commands/gsd-t-complete-milestone.md +528 -515
  33. package/commands/gsd-t-debug.md +506 -399
  34. package/commands/gsd-t-discuss.md +174 -174
  35. package/commands/gsd-t-execute.md +758 -634
  36. package/commands/gsd-t-feature.md +276 -276
  37. package/commands/gsd-t-health.md +142 -142
  38. package/commands/gsd-t-help.md +465 -457
  39. package/commands/gsd-t-impact.md +302 -302
  40. package/commands/gsd-t-init.md +320 -280
  41. package/commands/gsd-t-integrate.md +365 -249
  42. package/commands/gsd-t-milestone.md +87 -87
  43. package/commands/gsd-t-partition.md +442 -361
  44. package/commands/gsd-t-pause.md +82 -82
  45. package/commands/gsd-t-plan.md +345 -344
  46. package/commands/gsd-t-populate.md +111 -111
  47. package/commands/gsd-t-prd.md +326 -326
  48. package/commands/gsd-t-project.md +211 -211
  49. package/commands/gsd-t-promote-debt.md +123 -123
  50. package/commands/gsd-t-prompt.md +137 -137
  51. package/commands/gsd-t-qa.md +266 -266
  52. package/commands/gsd-t-quick.md +357 -234
  53. package/commands/gsd-t-reflect.md +134 -134
  54. package/commands/gsd-t-resume.md +72 -72
  55. package/commands/gsd-t-scan.md +615 -615
  56. package/commands/gsd-t-setup.md +76 -0
  57. package/commands/gsd-t-status.md +192 -166
  58. package/commands/gsd-t-test-sync.md +381 -381
  59. package/commands/gsd-t-triage-and-merge.md +171 -171
  60. package/commands/gsd-t-verify.md +382 -382
  61. package/commands/gsd-t-visualize.md +118 -118
  62. package/commands/gsd-t-wave.md +401 -378
  63. package/docs/GSD-T-README.md +425 -422
  64. package/docs/architecture.md +385 -369
  65. package/docs/harness-design-analysis.md +371 -0
  66. package/docs/infrastructure.md +205 -205
  67. package/docs/prd-graph-engine.md +398 -398
  68. package/docs/prd-gsd2-hybrid.md +559 -559
  69. package/docs/prd-harness-evolution.md +583 -0
  70. package/docs/requirements.md +14 -0
  71. package/docs/workflows.md +226 -226
  72. package/examples/.gsd-t/domains/example-domain/scope.md +13 -13
  73. package/package.json +40 -40
  74. package/scripts/gsd-t-auto-route.js +39 -39
  75. package/scripts/gsd-t-dashboard-mockup.html +1143 -1143
  76. package/scripts/gsd-t-dashboard-server.js +171 -171
  77. package/scripts/gsd-t-dashboard.html +262 -262
  78. package/scripts/gsd-t-event-writer.js +128 -128
  79. package/scripts/gsd-t-statusline.js +94 -94
  80. package/scripts/gsd-t-tools.js +175 -175
  81. package/templates/CLAUDE-global.md +639 -614
  82. package/templates/CLAUDE-project.md +24 -0
  83. package/templates/backlog-settings.md +18 -18
  84. package/templates/backlog.md +1 -1
  85. package/templates/progress.md +40 -40
  86. package/templates/shared-services-contract.md +60 -60
  87. package/templates/stacks/desktop.ini +2 -2
  88. package/bin/desktop.ini +0 -2
  89. package/commands/desktop.ini +0 -2
  90. package/docs/ci-examples/desktop.ini +0 -2
  91. package/docs/desktop.ini +0 -2
  92. package/examples/.gsd-t/contracts/desktop.ini +0 -2
  93. package/examples/.gsd-t/desktop.ini +0 -2
  94. package/examples/.gsd-t/domains/desktop.ini +0 -2
  95. package/examples/.gsd-t/domains/example-domain/desktop.ini +0 -2
  96. package/examples/desktop.ini +0 -2
  97. package/examples/rules/desktop.ini +0 -2
  98. package/scripts/desktop.ini +0 -2
  99. package/templates/desktop.ini +0 -2
@@ -1,187 +1,187 @@
1
- 'use strict';
2
-
3
- function genSystemArchitecture(analysisData) {
4
- try {
5
- const services = (analysisData.services || []).slice(0, 4);
6
- if (services.length >= 2) {
7
- const lines = ['graph TB',
8
- ' classDef user fill:#0d2035,stroke:#06b6d4,color:#a5f3fc',
9
- ' classDef svc fill:#1a0f3a,stroke:#7c3aed,color:#ddd6fe',
10
- ' classDef db fill:#0a2318,stroke:#10b981,color:#a7f3d0',
11
- ' User(["👤 User"]):::user'];
12
- services.forEach((s, i) => { lines.push(' S' + i + '["' + s + '"]:::svc'); lines.push(' User --> S' + i); });
13
- return lines.join('\n');
14
- }
15
- return `graph TB
16
- classDef user fill:#0d2035,stroke:#06b6d4,color:#a5f3fc
17
- classDef app fill:#0f1d3a,stroke:#3b82f6,color:#bfdbfe
18
- classDef api fill:#1a0f3a,stroke:#7c3aed,color:#ddd6fe
19
- classDef db fill:#0a2318,stroke:#10b981,color:#a7f3d0
20
- classDef ext fill:#111827,stroke:#374151,color:#9ca3af
21
- USER(["👤 User\\nweb & mobile"]):::user
22
- subgraph PLATFORM[" Application Platform "]
23
- APP["🌐 Frontend\\nUser Interface"]:::app
24
- API["⚡ Backend\\nApplication Logic"]:::api
25
- DB[("🗃 Database\\nPrimary Store")]:::db
26
- end
27
- EXT["🌎 External Services\\nAPIs & Integrations"]:::ext
28
- USER -->|"HTTPS"| APP
29
- APP -->|"REST / JSON"| API
30
- API -->|"reads / writes"| DB
31
- API -->|"calls"| EXT
32
- style PLATFORM fill:#0a0f1e,stroke:#1e3a5f,color:#e2e8f0`;
33
- } catch { return 'graph TB\n App[Application] --> DB[(Database)]'; }
34
- }
35
-
36
- function genAppArchitecture(analysisData) {
37
- try {
38
- const layers = (analysisData.layers || []).slice(0, 5);
39
- if (layers.length >= 3) {
40
- const lines = ['graph TB'];
41
- const colors = ['#0f1d3a,#3b82f6', '#1a0f3a,#7c3aed', '#0a2318,#10b981', '#1f1505,#f59e0b', '#12102a,#6366f1'];
42
- layers.forEach((l, i) => {
43
- const [bg, stroke] = colors[i % colors.length].split(',');
44
- lines.push(` L${i}["${l}"]`);
45
- lines.push(` style L${i} fill:${bg},stroke:${stroke},color:#e2e8f0`);
46
- if (i > 0) lines.push(` L${i - 1} --> L${i}`);
47
- });
48
- return lines.join('\n');
49
- }
50
- return `graph TB
51
- classDef client fill:#0d2035,stroke:#06b6d4,color:#a5f3fc
52
- classDef ctrl fill:#0f1d3a,stroke:#3b82f6,color:#bfdbfe
53
- classDef svc fill:#1a0f3a,stroke:#7c3aed,color:#ddd6fe
54
- classDef repo fill:#1a0f3a,stroke:#8b5cf6,color:#ddd6fe
55
- classDef db fill:#0a2318,stroke:#10b981,color:#a7f3d0
56
- subgraph CL[" Clients "]
57
- WEB["🌐 Web App"]:::client
58
- MOB["📱 Mobile"]:::client
59
- end
60
- subgraph CTR[" Controller Layer "]
61
- AC["AuthController"]:::ctrl
62
- TC["TasksController"]:::ctrl
63
- PC["ProjectsController"]:::ctrl
64
- end
65
- subgraph SVC[" Service Layer "]
66
- AS["AuthService"]:::svc
67
- TS["TasksService"]:::svc
68
- PS["ProjectsService"]:::svc
69
- end
70
- DB[("🗃 Database")]:::db
71
- WEB & MOB --> CTR --> SVC --> DB
72
- style CL fill:#080e1a,stroke:#0e2035
73
- style CTR fill:#080e1a,stroke:#1e3a5f
74
- style SVC fill:#080e1a,stroke:#2d1a5e`;
75
- } catch { return 'graph TB\n subgraph App\n Controllers --> Services --> Repositories\n end'; }
76
- }
77
-
78
- function genWorkflow(analysisData) {
79
- try {
80
- const states = (analysisData.states || []).slice(0, 6);
81
- if (states.length >= 3) {
82
- const lines = ['stateDiagram-v2', ' direction LR', ' [*] --> ' + states[0]];
83
- states.forEach((s, i) => { if (i < states.length - 1) lines.push(` ${s} --> ${states[i + 1]}`); });
84
- lines.push(' ' + states[states.length - 1] + ' --> [*]');
85
- return lines.join('\n');
86
- }
87
- return `stateDiagram-v2
88
- direction LR
89
- [*] --> Draft : create
90
- Draft --> Open : submit
91
- Draft --> [*] : discard
92
- Open --> InProgress : assign
93
- Open --> Cancelled : cancel
94
- InProgress --> Review : mark done
95
- InProgress --> Blocked : flag blocker
96
- InProgress --> Open : unassign
97
- Blocked --> InProgress : resolve
98
- Review --> Done : approve
99
- Review --> InProgress : reject
100
- Done --> [*]
101
- Cancelled --> [*]
102
- note right of Blocked
103
- No SLA timeout —
104
- can stagnate here
105
- end note`;
106
- } catch { return 'stateDiagram-v2\n [*] --> Active\n Active --> Done\n Done --> [*]'; }
107
- }
108
-
109
- function genDataFlow(analysisData) {
110
- try {
111
- const endpoints = (analysisData.endpoints || []).slice(0, 1);
112
- const ep = endpoints[0] || 'POST /api/resource';
113
- return `flowchart TD
114
- classDef user fill:#0d2035,stroke:#06b6d4,color:#a5f3fc
115
- classDef fe fill:#0f1d3a,stroke:#3b82f6,color:#bfdbfe
116
- classDef api fill:#1a0f3a,stroke:#7c3aed,color:#ddd6fe
117
- classDef db fill:#0a2318,stroke:#10b981,color:#a7f3d0
118
- classDef queue fill:#1f1505,stroke:#f59e0b,color:#fde68a
119
- classDef ok fill:#0a2318,stroke:#10b981,color:#a7f3d0
120
- USR(["&#128100; User"]):::user
121
- subgraph FE["Frontend"]
122
- FORM["Form\\n+ Client Validation"]:::fe
123
- end
124
- subgraph API["API Server"]
125
- PIPE["ValidationPipe\\n+ Sanitize"]:::api
126
- CTRL["Controller\\n${ep}"]:::api
127
- SVC["Service\\nbusiness logic"]:::api
128
- REPO["Repository\\nINSERT / UPDATE"]:::api
129
- end
130
- DB[("&#128451; Database")]:::db
131
- RD[("&#9889; Queue")]:::queue
132
- RES(["&#10003; Response"]):::ok
133
- USR --> FORM --> PIPE --> CTRL --> SVC --> REPO --> DB
134
- SVC --> RD
135
- DB --> RES
136
- style FE fill:#080e1a,stroke:#1e3a5f
137
- style API fill:#080e1a,stroke:#2d1a5e`;
138
- } catch { return 'flowchart TD\n Input --> Validate --> Process --> Store --> Respond'; }
139
- }
140
-
141
- function genSequence(analysisData) {
142
- try {
143
- const ep = ((analysisData.endpoints || [])[0]) || 'POST /api/resource';
144
- return `sequenceDiagram
145
- autonumber
146
- actor User
147
- participant Client
148
- participant API as API Server
149
- participant DB as Database
150
- participant Queue
151
- User->>Client: Submit form
152
- Client->>API: ${ep}
153
- API->>API: validate &amp; sanitize
154
- alt invalid input
155
- API-->>Client: 400 Bad Request
156
- else valid
157
- API->>DB: INSERT record
158
- DB-->>API: record id
159
- API->>Queue: enqueue background job
160
- API-->>Client: 201 Created
161
- Client-->>User: Success feedback
162
- end`;
163
- } catch { return 'sequenceDiagram\n Client->>Server: Request\n Server->>DB: Query\n DB-->>Server: Result\n Server-->>Client: Response'; }
164
- }
165
-
166
- function genDatabaseSchema(schemaData) {
167
- try {
168
- if (!schemaData || !schemaData.detected || !schemaData.entities || schemaData.entities.length === 0) return '';
169
- const relMap = { 'one-to-many': '||--o{', 'many-to-one': '}o--||', 'many-to-many': '}o--o{', 'one-to-one': '||--||' };
170
- const lines = ['erDiagram'];
171
- for (const entity of schemaData.entities.slice(0, 8)) {
172
- lines.push(' ' + entity.name + ' {');
173
- for (const f of (entity.fields || []).slice(0, 10)) {
174
- lines.push(' ' + (f.type || 'string') + ' ' + f.name);
175
- }
176
- lines.push(' }');
177
- }
178
- for (const entity of schemaData.entities) {
179
- for (const rel of (entity.relations || [])) {
180
- lines.push(' ' + rel.fromEntity + ' ' + (relMap[rel.type] || '||--o{') + ' ' + rel.toEntity + ' : "has"');
181
- }
182
- }
183
- return lines.join('\n');
184
- } catch { return ''; }
185
- }
186
-
187
- module.exports = { genSystemArchitecture, genAppArchitecture, genWorkflow, genDataFlow, genSequence, genDatabaseSchema };
1
+ 'use strict';
2
+
3
+ function genSystemArchitecture(analysisData) {
4
+ try {
5
+ const services = (analysisData.services || []).slice(0, 4);
6
+ if (services.length >= 2) {
7
+ const lines = ['graph TB',
8
+ ' classDef user fill:#0d2035,stroke:#06b6d4,color:#a5f3fc',
9
+ ' classDef svc fill:#1a0f3a,stroke:#7c3aed,color:#ddd6fe',
10
+ ' classDef db fill:#0a2318,stroke:#10b981,color:#a7f3d0',
11
+ ' User(["&#128100; User"]):::user'];
12
+ services.forEach((s, i) => { lines.push(' S' + i + '["' + s + '"]:::svc'); lines.push(' User --> S' + i); });
13
+ return lines.join('\n');
14
+ }
15
+ return `graph TB
16
+ classDef user fill:#0d2035,stroke:#06b6d4,color:#a5f3fc
17
+ classDef app fill:#0f1d3a,stroke:#3b82f6,color:#bfdbfe
18
+ classDef api fill:#1a0f3a,stroke:#7c3aed,color:#ddd6fe
19
+ classDef db fill:#0a2318,stroke:#10b981,color:#a7f3d0
20
+ classDef ext fill:#111827,stroke:#374151,color:#9ca3af
21
+ USER(["&#128100; User\\nweb &amp; mobile"]):::user
22
+ subgraph PLATFORM[" Application Platform "]
23
+ APP["&#127760; Frontend\\nUser Interface"]:::app
24
+ API["&#9889; Backend\\nApplication Logic"]:::api
25
+ DB[("&#128451; Database\\nPrimary Store")]:::db
26
+ end
27
+ EXT["&#127758; External Services\\nAPIs &amp; Integrations"]:::ext
28
+ USER -->|"HTTPS"| APP
29
+ APP -->|"REST / JSON"| API
30
+ API -->|"reads / writes"| DB
31
+ API -->|"calls"| EXT
32
+ style PLATFORM fill:#0a0f1e,stroke:#1e3a5f,color:#e2e8f0`;
33
+ } catch { return 'graph TB\n App[Application] --> DB[(Database)]'; }
34
+ }
35
+
36
+ function genAppArchitecture(analysisData) {
37
+ try {
38
+ const layers = (analysisData.layers || []).slice(0, 5);
39
+ if (layers.length >= 3) {
40
+ const lines = ['graph TB'];
41
+ const colors = ['#0f1d3a,#3b82f6', '#1a0f3a,#7c3aed', '#0a2318,#10b981', '#1f1505,#f59e0b', '#12102a,#6366f1'];
42
+ layers.forEach((l, i) => {
43
+ const [bg, stroke] = colors[i % colors.length].split(',');
44
+ lines.push(` L${i}["${l}"]`);
45
+ lines.push(` style L${i} fill:${bg},stroke:${stroke},color:#e2e8f0`);
46
+ if (i > 0) lines.push(` L${i - 1} --> L${i}`);
47
+ });
48
+ return lines.join('\n');
49
+ }
50
+ return `graph TB
51
+ classDef client fill:#0d2035,stroke:#06b6d4,color:#a5f3fc
52
+ classDef ctrl fill:#0f1d3a,stroke:#3b82f6,color:#bfdbfe
53
+ classDef svc fill:#1a0f3a,stroke:#7c3aed,color:#ddd6fe
54
+ classDef repo fill:#1a0f3a,stroke:#8b5cf6,color:#ddd6fe
55
+ classDef db fill:#0a2318,stroke:#10b981,color:#a7f3d0
56
+ subgraph CL[" Clients "]
57
+ WEB["&#127760; Web App"]:::client
58
+ MOB["&#128241; Mobile"]:::client
59
+ end
60
+ subgraph CTR[" Controller Layer "]
61
+ AC["AuthController"]:::ctrl
62
+ TC["TasksController"]:::ctrl
63
+ PC["ProjectsController"]:::ctrl
64
+ end
65
+ subgraph SVC[" Service Layer "]
66
+ AS["AuthService"]:::svc
67
+ TS["TasksService"]:::svc
68
+ PS["ProjectsService"]:::svc
69
+ end
70
+ DB[("&#128451; Database")]:::db
71
+ WEB & MOB --> CTR --> SVC --> DB
72
+ style CL fill:#080e1a,stroke:#0e2035
73
+ style CTR fill:#080e1a,stroke:#1e3a5f
74
+ style SVC fill:#080e1a,stroke:#2d1a5e`;
75
+ } catch { return 'graph TB\n subgraph App\n Controllers --> Services --> Repositories\n end'; }
76
+ }
77
+
78
+ function genWorkflow(analysisData) {
79
+ try {
80
+ const states = (analysisData.states || []).slice(0, 6);
81
+ if (states.length >= 3) {
82
+ const lines = ['stateDiagram-v2', ' direction LR', ' [*] --> ' + states[0]];
83
+ states.forEach((s, i) => { if (i < states.length - 1) lines.push(` ${s} --> ${states[i + 1]}`); });
84
+ lines.push(' ' + states[states.length - 1] + ' --> [*]');
85
+ return lines.join('\n');
86
+ }
87
+ return `stateDiagram-v2
88
+ direction LR
89
+ [*] --> Draft : create
90
+ Draft --> Open : submit
91
+ Draft --> [*] : discard
92
+ Open --> InProgress : assign
93
+ Open --> Cancelled : cancel
94
+ InProgress --> Review : mark done
95
+ InProgress --> Blocked : flag blocker
96
+ InProgress --> Open : unassign
97
+ Blocked --> InProgress : resolve
98
+ Review --> Done : approve
99
+ Review --> InProgress : reject
100
+ Done --> [*]
101
+ Cancelled --> [*]
102
+ note right of Blocked
103
+ No SLA timeout —
104
+ can stagnate here
105
+ end note`;
106
+ } catch { return 'stateDiagram-v2\n [*] --> Active\n Active --> Done\n Done --> [*]'; }
107
+ }
108
+
109
+ function genDataFlow(analysisData) {
110
+ try {
111
+ const endpoints = (analysisData.endpoints || []).slice(0, 1);
112
+ const ep = endpoints[0] || 'POST /api/resource';
113
+ return `flowchart TD
114
+ classDef user fill:#0d2035,stroke:#06b6d4,color:#a5f3fc
115
+ classDef fe fill:#0f1d3a,stroke:#3b82f6,color:#bfdbfe
116
+ classDef api fill:#1a0f3a,stroke:#7c3aed,color:#ddd6fe
117
+ classDef db fill:#0a2318,stroke:#10b981,color:#a7f3d0
118
+ classDef queue fill:#1f1505,stroke:#f59e0b,color:#fde68a
119
+ classDef ok fill:#0a2318,stroke:#10b981,color:#a7f3d0
120
+ USR(["&#128100; User"]):::user
121
+ subgraph FE["Frontend"]
122
+ FORM["Form\\n+ Client Validation"]:::fe
123
+ end
124
+ subgraph API["API Server"]
125
+ PIPE["ValidationPipe\\n+ Sanitize"]:::api
126
+ CTRL["Controller\\n${ep}"]:::api
127
+ SVC["Service\\nbusiness logic"]:::api
128
+ REPO["Repository\\nINSERT / UPDATE"]:::api
129
+ end
130
+ DB[("&#128451; Database")]:::db
131
+ RD[("&#9889; Queue")]:::queue
132
+ RES(["&#10003; Response"]):::ok
133
+ USR --> FORM --> PIPE --> CTRL --> SVC --> REPO --> DB
134
+ SVC --> RD
135
+ DB --> RES
136
+ style FE fill:#080e1a,stroke:#1e3a5f
137
+ style API fill:#080e1a,stroke:#2d1a5e`;
138
+ } catch { return 'flowchart TD\n Input --> Validate --> Process --> Store --> Respond'; }
139
+ }
140
+
141
+ function genSequence(analysisData) {
142
+ try {
143
+ const ep = ((analysisData.endpoints || [])[0]) || 'POST /api/resource';
144
+ return `sequenceDiagram
145
+ autonumber
146
+ actor User
147
+ participant Client
148
+ participant API as API Server
149
+ participant DB as Database
150
+ participant Queue
151
+ User->>Client: Submit form
152
+ Client->>API: ${ep}
153
+ API->>API: validate &amp; sanitize
154
+ alt invalid input
155
+ API-->>Client: 400 Bad Request
156
+ else valid
157
+ API->>DB: INSERT record
158
+ DB-->>API: record id
159
+ API->>Queue: enqueue background job
160
+ API-->>Client: 201 Created
161
+ Client-->>User: Success feedback
162
+ end`;
163
+ } catch { return 'sequenceDiagram\n Client->>Server: Request\n Server->>DB: Query\n DB-->>Server: Result\n Server-->>Client: Response'; }
164
+ }
165
+
166
+ function genDatabaseSchema(schemaData) {
167
+ try {
168
+ if (!schemaData || !schemaData.detected || !schemaData.entities || schemaData.entities.length === 0) return '';
169
+ const relMap = { 'one-to-many': '||--o{', 'many-to-one': '}o--||', 'many-to-many': '}o--o{', 'one-to-one': '||--||' };
170
+ const lines = ['erDiagram'];
171
+ for (const entity of schemaData.entities.slice(0, 8)) {
172
+ lines.push(' ' + entity.name + ' {');
173
+ for (const f of (entity.fields || []).slice(0, 10)) {
174
+ lines.push(' ' + (f.type || 'string') + ' ' + f.name);
175
+ }
176
+ lines.push(' }');
177
+ }
178
+ for (const entity of schemaData.entities) {
179
+ for (const rel of (entity.relations || [])) {
180
+ lines.push(' ' + rel.fromEntity + ' ' + (relMap[rel.type] || '||--o{') + ' ' + rel.toEntity + ' : "has"');
181
+ }
182
+ }
183
+ return lines.join('\n');
184
+ } catch { return ''; }
185
+ }
186
+
187
+ module.exports = { genSystemArchitecture, genAppArchitecture, genWorkflow, genDataFlow, genSequence, genDatabaseSchema };
@@ -1,79 +1,79 @@
1
- 'use strict';
2
-
3
- const {
4
- genSystemArchitecture,
5
- genAppArchitecture,
6
- genWorkflow,
7
- genDataFlow,
8
- genSequence,
9
- genDatabaseSchema
10
- } = require('./scan-diagrams-generators');
11
-
12
- const PLACEHOLDER_HTML = '<div class="diagram-placeholder">\n <p>Diagram unavailable — rendering tools not found</p>\n <p>Install: <code>npm install -g @mermaid-js/mermaid-cli</code></p>\n</div>';
13
-
14
- const NOTES = {
15
- 'system-architecture': 'C4-style context diagram showing services, databases, and external integrations',
16
- 'app-architecture': 'Layered diagram showing framework architecture and component boundaries',
17
- 'workflow': 'State machine derived from status enums and state transition logic',
18
- 'data-flow': 'Data flow from user input through validation, persistence, and async processing',
19
- 'sequence': 'Request/response sequence for the primary API endpoint',
20
- 'database-schema': 'Schema diagram generated from ORM, document DB, vector store, or raw SQL definitions'
21
- };
22
-
23
- const DIAGRAM_DEFS = [
24
- { type: 'system-architecture', title: 'System Architecture', typeBadge: 'graph TB', gen: (a) => genSystemArchitecture(a) },
25
- { type: 'app-architecture', title: 'Application Architecture', typeBadge: 'graph TB', gen: (a) => genAppArchitecture(a) },
26
- { type: 'workflow', title: 'Workflow', typeBadge: 'stateDiagram-v2', gen: (a) => genWorkflow(a) },
27
- { type: 'data-flow', title: 'Data Flow', typeBadge: 'flowchart TD', gen: (a) => genDataFlow(a) },
28
- { type: 'sequence', title: 'Sequence', typeBadge: 'sequenceDiagram', gen: (a) => genSequence(a) },
29
- { type: 'database-schema', title: 'Database Schema', typeBadge: 'erDiagram', gen: (_, s) => genDatabaseSchema(s) }
30
- ];
31
-
32
- function buildPlaceholder(def, mmd) {
33
- return {
34
- type: def.type,
35
- title: def.title,
36
- typeBadge: def.typeBadge,
37
- svgContent: PLACEHOLDER_HTML,
38
- mmdSource: mmd || '',
39
- note: NOTES[def.type] || '',
40
- rendered: false,
41
- rendererUsed: 'placeholder'
42
- };
43
- }
44
-
45
- function generateDiagrams(analysisData, schemaData, options) {
46
- try {
47
- const { renderDiagram } = require('./scan-renderer');
48
- const results = [];
49
- for (const def of DIAGRAM_DEFS) {
50
- try {
51
- const mmd = def.gen(analysisData, schemaData);
52
- const isDbSchema = def.type === 'database-schema';
53
- const noSchema = !schemaData || !schemaData.detected || !mmd;
54
- if (isDbSchema && noSchema) {
55
- results.push(buildPlaceholder(def, ''));
56
- } else {
57
- const rendered = renderDiagram(mmd, def.type, options || {});
58
- results.push({
59
- type: def.type,
60
- title: def.title,
61
- typeBadge: def.typeBadge,
62
- svgContent: rendered.svgContent,
63
- mmdSource: mmd,
64
- note: NOTES[def.type] || '',
65
- rendered: rendered.rendered,
66
- rendererUsed: rendered.rendererUsed
67
- });
68
- }
69
- } catch {
70
- results.push(buildPlaceholder(def, ''));
71
- }
72
- }
73
- return results;
74
- } catch {
75
- return DIAGRAM_DEFS.map(def => buildPlaceholder(def));
76
- }
77
- }
78
-
79
- module.exports = { generateDiagrams };
1
+ 'use strict';
2
+
3
+ const {
4
+ genSystemArchitecture,
5
+ genAppArchitecture,
6
+ genWorkflow,
7
+ genDataFlow,
8
+ genSequence,
9
+ genDatabaseSchema
10
+ } = require('./scan-diagrams-generators');
11
+
12
+ const PLACEHOLDER_HTML = '<div class="diagram-placeholder">\n <p>Diagram unavailable — rendering tools not found</p>\n <p>Install: <code>npm install -g @mermaid-js/mermaid-cli</code></p>\n</div>';
13
+
14
+ const NOTES = {
15
+ 'system-architecture': 'C4-style context diagram showing services, databases, and external integrations',
16
+ 'app-architecture': 'Layered diagram showing framework architecture and component boundaries',
17
+ 'workflow': 'State machine derived from status enums and state transition logic',
18
+ 'data-flow': 'Data flow from user input through validation, persistence, and async processing',
19
+ 'sequence': 'Request/response sequence for the primary API endpoint',
20
+ 'database-schema': 'Schema diagram generated from ORM, document DB, vector store, or raw SQL definitions'
21
+ };
22
+
23
+ const DIAGRAM_DEFS = [
24
+ { type: 'system-architecture', title: 'System Architecture', typeBadge: 'graph TB', gen: (a) => genSystemArchitecture(a) },
25
+ { type: 'app-architecture', title: 'Application Architecture', typeBadge: 'graph TB', gen: (a) => genAppArchitecture(a) },
26
+ { type: 'workflow', title: 'Workflow', typeBadge: 'stateDiagram-v2', gen: (a) => genWorkflow(a) },
27
+ { type: 'data-flow', title: 'Data Flow', typeBadge: 'flowchart TD', gen: (a) => genDataFlow(a) },
28
+ { type: 'sequence', title: 'Sequence', typeBadge: 'sequenceDiagram', gen: (a) => genSequence(a) },
29
+ { type: 'database-schema', title: 'Database Schema', typeBadge: 'erDiagram', gen: (_, s) => genDatabaseSchema(s) }
30
+ ];
31
+
32
+ function buildPlaceholder(def, mmd) {
33
+ return {
34
+ type: def.type,
35
+ title: def.title,
36
+ typeBadge: def.typeBadge,
37
+ svgContent: PLACEHOLDER_HTML,
38
+ mmdSource: mmd || '',
39
+ note: NOTES[def.type] || '',
40
+ rendered: false,
41
+ rendererUsed: 'placeholder'
42
+ };
43
+ }
44
+
45
+ function generateDiagrams(analysisData, schemaData, options) {
46
+ try {
47
+ const { renderDiagram } = require('./scan-renderer');
48
+ const results = [];
49
+ for (const def of DIAGRAM_DEFS) {
50
+ try {
51
+ const mmd = def.gen(analysisData, schemaData);
52
+ const isDbSchema = def.type === 'database-schema';
53
+ const noSchema = !schemaData || !schemaData.detected || !mmd;
54
+ if (isDbSchema && noSchema) {
55
+ results.push(buildPlaceholder(def, ''));
56
+ } else {
57
+ const rendered = renderDiagram(mmd, def.type, options || {});
58
+ results.push({
59
+ type: def.type,
60
+ title: def.title,
61
+ typeBadge: def.typeBadge,
62
+ svgContent: rendered.svgContent,
63
+ mmdSource: mmd,
64
+ note: NOTES[def.type] || '',
65
+ rendered: rendered.rendered,
66
+ rendererUsed: rendered.rendererUsed
67
+ });
68
+ }
69
+ } catch {
70
+ results.push(buildPlaceholder(def, ''));
71
+ }
72
+ }
73
+ return results;
74
+ } catch {
75
+ return DIAGRAM_DEFS.map(def => buildPlaceholder(def));
76
+ }
77
+ }
78
+
79
+ module.exports = { generateDiagrams };