@monoes/monodesign 1.0.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 (159) hide show
  1. package/LICENSE +191 -0
  2. package/cli/bin/cli.js +83 -0
  3. package/cli/bin/commands/ignores.mjs +331 -0
  4. package/cli/engine/browser/injected/index.mjs +1938 -0
  5. package/cli/engine/cli/main.mjs +322 -0
  6. package/cli/engine/design-system.mjs +815 -0
  7. package/cli/engine/detect-antipatterns-browser.js +5246 -0
  8. package/cli/engine/detect-antipatterns.mjs +51 -0
  9. package/cli/engine/engines/browser/detect-url.mjs +278 -0
  10. package/cli/engine/engines/regex/detect-text.mjs +574 -0
  11. package/cli/engine/engines/static-html/css-cascade.mjs +1016 -0
  12. package/cli/engine/engines/static-html/detect-html.mjs +235 -0
  13. package/cli/engine/engines/visual/screenshot-contrast.mjs +190 -0
  14. package/cli/engine/findings.mjs +13 -0
  15. package/cli/engine/node/file-system.mjs +199 -0
  16. package/cli/engine/profile/profiler.mjs +167 -0
  17. package/cli/engine/registry/antipatterns.mjs +515 -0
  18. package/cli/engine/rules/checks.mjs +2704 -0
  19. package/cli/engine/shared/color.mjs +125 -0
  20. package/cli/engine/shared/constants.mjs +102 -0
  21. package/cli/engine/shared/fonts.mjs +31 -0
  22. package/cli/engine/shared/inline-ignores.mjs +149 -0
  23. package/cli/engine/shared/page.mjs +8 -0
  24. package/cli/lib/monodesign-config.mjs +641 -0
  25. package/package.json +49 -0
  26. package/skill/SKILL.src.md +277 -0
  27. package/skill/agents/monodesign-asset-producer.md +100 -0
  28. package/skill/agents/monodesign-manual-edit-applier.md +103 -0
  29. package/skill/commands/adapt.md +53 -0
  30. package/skill/commands/animate.md +65 -0
  31. package/skill/commands/audit.md +89 -0
  32. package/skill/commands/bolder.md +50 -0
  33. package/skill/commands/clarify.md +64 -0
  34. package/skill/commands/colorize.md +68 -0
  35. package/skill/commands/craft.md +51 -0
  36. package/skill/commands/critique.md +66 -0
  37. package/skill/commands/delight.md +47 -0
  38. package/skill/commands/distill.md +56 -0
  39. package/skill/commands/document.md +83 -0
  40. package/skill/commands/extract.md +74 -0
  41. package/skill/commands/harden.md +65 -0
  42. package/skill/commands/init.md +30 -0
  43. package/skill/commands/layout.md +36 -0
  44. package/skill/commands/live.md +34 -0
  45. package/skill/commands/onboard.md +50 -0
  46. package/skill/commands/optimize.md +64 -0
  47. package/skill/commands/overdrive.md +56 -0
  48. package/skill/commands/polish.md +68 -0
  49. package/skill/commands/quieter.md +57 -0
  50. package/skill/commands/shape.md +71 -0
  51. package/skill/commands/teach.md +18 -0
  52. package/skill/commands/typeset.md +59 -0
  53. package/skill/reference/adapt.md +312 -0
  54. package/skill/reference/adapt.native.md +58 -0
  55. package/skill/reference/android.md +40 -0
  56. package/skill/reference/animate.md +203 -0
  57. package/skill/reference/antipatterns-catalog.md +365 -0
  58. package/skill/reference/audit.md +135 -0
  59. package/skill/reference/audit.native.md +139 -0
  60. package/skill/reference/bolder.md +120 -0
  61. package/skill/reference/brand-workflow.md +180 -0
  62. package/skill/reference/brand.md +108 -0
  63. package/skill/reference/clarify.md +288 -0
  64. package/skill/reference/codex.md +105 -0
  65. package/skill/reference/cognitive-load.md +106 -0
  66. package/skill/reference/color-and-contrast.md +105 -0
  67. package/skill/reference/colorize.md +257 -0
  68. package/skill/reference/component-specs.md +260 -0
  69. package/skill/reference/component-states.md +274 -0
  70. package/skill/reference/component-system.md +358 -0
  71. package/skill/reference/copy-formulas.md +160 -0
  72. package/skill/reference/craft.md +123 -0
  73. package/skill/reference/critique.md +819 -0
  74. package/skill/reference/delight.md +302 -0
  75. package/skill/reference/design-principles.md +246 -0
  76. package/skill/reference/distill.md +111 -0
  77. package/skill/reference/document.md +429 -0
  78. package/skill/reference/extract.md +69 -0
  79. package/skill/reference/harden.md +347 -0
  80. package/skill/reference/heuristics-scoring.md +234 -0
  81. package/skill/reference/hooks.md +92 -0
  82. package/skill/reference/image-prompts.md +130 -0
  83. package/skill/reference/init.md +221 -0
  84. package/skill/reference/interaction-design.md +189 -0
  85. package/skill/reference/ios.md +45 -0
  86. package/skill/reference/layout.md +185 -0
  87. package/skill/reference/live.md +722 -0
  88. package/skill/reference/motion-design.md +109 -0
  89. package/skill/reference/onboard.md +234 -0
  90. package/skill/reference/optimize.md +258 -0
  91. package/skill/reference/overdrive.md +130 -0
  92. package/skill/reference/personas.md +179 -0
  93. package/skill/reference/polish.md +241 -0
  94. package/skill/reference/pre-delivery-checklist.md +108 -0
  95. package/skill/reference/product.md +60 -0
  96. package/skill/reference/quieter.md +99 -0
  97. package/skill/reference/responsive-design.md +114 -0
  98. package/skill/reference/shape.md +165 -0
  99. package/skill/reference/spatial-design.md +100 -0
  100. package/skill/reference/teach.md +10 -0
  101. package/skill/reference/token-architecture.md +222 -0
  102. package/skill/reference/typeset.md +301 -0
  103. package/skill/reference/typography.md +159 -0
  104. package/skill/reference/ux-research.md +143 -0
  105. package/skill/reference/ux-rules.md +211 -0
  106. package/skill/reference/ux-writing.md +107 -0
  107. package/skill/scripts/command-metadata.json +94 -0
  108. package/skill/scripts/context-signals.mjs +227 -0
  109. package/skill/scripts/context.mjs +1062 -0
  110. package/skill/scripts/critique-storage.mjs +243 -0
  111. package/skill/scripts/detect-csp.mjs +199 -0
  112. package/skill/scripts/detect.mjs +34 -0
  113. package/skill/scripts/hook-admin.mjs +662 -0
  114. package/skill/scripts/hook-before-edit.mjs +517 -0
  115. package/skill/scripts/hook-lib.mjs +1777 -0
  116. package/skill/scripts/hook.mjs +62 -0
  117. package/skill/scripts/lib/design-parser.mjs +843 -0
  118. package/skill/scripts/lib/is-generated.mjs +70 -0
  119. package/skill/scripts/lib/monodesign-paths.mjs +130 -0
  120. package/skill/scripts/lib/provider.mjs +5 -0
  121. package/skill/scripts/lib/target-args.mjs +43 -0
  122. package/skill/scripts/live/browser-script-parts.mjs +51 -0
  123. package/skill/scripts/live/completion.mjs +20 -0
  124. package/skill/scripts/live/event-validation.mjs +138 -0
  125. package/skill/scripts/live/insert-ui.mjs +459 -0
  126. package/skill/scripts/live/manual-apply.mjs +940 -0
  127. package/skill/scripts/live/manual-edit-routes.mjs +358 -0
  128. package/skill/scripts/live/manual-edits-buffer.mjs +153 -0
  129. package/skill/scripts/live/session-store.mjs +290 -0
  130. package/skill/scripts/live/svelte-component.mjs +827 -0
  131. package/skill/scripts/live/sveltekit-adapter.mjs +275 -0
  132. package/skill/scripts/live/ui-core.mjs +181 -0
  133. package/skill/scripts/live/vocabulary.mjs +37 -0
  134. package/skill/scripts/live-accept.mjs +813 -0
  135. package/skill/scripts/live-browser-dom.js +147 -0
  136. package/skill/scripts/live-browser-session.js +124 -0
  137. package/skill/scripts/live-browser.js +11241 -0
  138. package/skill/scripts/live-commit-manual-edits.mjs +1242 -0
  139. package/skill/scripts/live-complete.mjs +76 -0
  140. package/skill/scripts/live-copy-edit-agent.mjs +684 -0
  141. package/skill/scripts/live-discard-manual-edits.mjs +52 -0
  142. package/skill/scripts/live-inject.mjs +584 -0
  143. package/skill/scripts/live-insert.mjs +273 -0
  144. package/skill/scripts/live-manual-edit-evidence.mjs +364 -0
  145. package/skill/scripts/live-poll.mjs +385 -0
  146. package/skill/scripts/live-resume.mjs +95 -0
  147. package/skill/scripts/live-server.mjs +1138 -0
  148. package/skill/scripts/live-status.mjs +62 -0
  149. package/skill/scripts/live-target.mjs +31 -0
  150. package/skill/scripts/live-wrap.mjs +895 -0
  151. package/skill/scripts/live.mjs +298 -0
  152. package/skill/scripts/modern-screenshot.umd.js +15 -0
  153. package/skill/scripts/palette.mjs +634 -0
  154. package/skill/scripts/pin.mjs +222 -0
  155. package/src/antipatterns.ts +164 -0
  156. package/src/index.ts +13 -0
  157. package/src/rules.ts +72 -0
  158. package/src/tokens.css +116 -0
  159. package/src/tokens.ts +99 -0
@@ -0,0 +1,290 @@
1
+ // Pattern adapted from impeccable (Apache-2.0) — rebranded for monomind
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ import { getLegacyLiveSessionsDir, getLiveSessionsDir } from '../lib/monodesign-paths.mjs';
5
+
6
+ const COMPLETED_PHASES = new Set(['completed', 'discarded']);
7
+
8
+ export function createLiveSessionStore({ cwd = process.cwd(), sessionId } = {}) {
9
+ const rootDir = getLiveSessionsDir(cwd);
10
+ const legacyRootDir = getLegacyLiveSessionsDir(cwd);
11
+ fs.mkdirSync(rootDir, { recursive: true });
12
+ const snapshotCache = new Map();
13
+
14
+ function loadCachedOrRebuild(id) {
15
+ const cached = snapshotCache.get(id);
16
+ if (cached) return cached;
17
+ const journalPath = getReadableJournalPath(id);
18
+ const rebuilt = rebuildSnapshotFromJournal(journalPath, id);
19
+ snapshotCache.set(id, rebuilt);
20
+ return rebuilt;
21
+ }
22
+
23
+ function getReadableJournalPath(id) {
24
+ const primary = getJournalPath(rootDir, id);
25
+ if (fs.existsSync(primary)) return primary;
26
+ const legacy = getJournalPath(legacyRootDir, id);
27
+ if (fs.existsSync(legacy)) return legacy;
28
+ return primary;
29
+ }
30
+
31
+ return {
32
+ rootDir,
33
+ legacyRootDir,
34
+ appendEvent(event) {
35
+ const normalized = normalizeEvent(event, sessionId);
36
+ const journalPath = getJournalPath(rootDir, normalized.id);
37
+ const snapshotPath = getSnapshotPath(rootDir, normalized.id);
38
+ const legacyJournalPath = getJournalPath(legacyRootDir, normalized.id);
39
+ if (!fs.existsSync(journalPath) && fs.existsSync(legacyJournalPath)) {
40
+ fs.copyFileSync(legacyJournalPath, journalPath);
41
+ }
42
+ const prior = loadCachedOrRebuild(normalized.id);
43
+ const seq = prior.nextSeq;
44
+ const entry = {
45
+ seq,
46
+ id: normalized.id,
47
+ type: normalized.type,
48
+ ts: new Date().toISOString(),
49
+ event: normalized,
50
+ };
51
+ fs.appendFileSync(journalPath, JSON.stringify(entry) + '\n');
52
+ const next = applyEvent(prior.snapshot, entry, prior.diagnostics);
53
+ snapshotCache.set(normalized.id, { snapshot: next, diagnostics: next.diagnostics || [], nextSeq: seq + 1 });
54
+ writeSnapshot(snapshotPath, next);
55
+ return next;
56
+ },
57
+ getSnapshot(id = sessionId, opts = {}) {
58
+ if (!id) throw new Error('session id required');
59
+ const journalPath = getReadableJournalPath(id);
60
+ const snapshotPath = getSnapshotPath(rootDir, id);
61
+ const rebuilt = rebuildSnapshotFromJournal(journalPath, id);
62
+ snapshotCache.set(id, rebuilt);
63
+ writeSnapshot(snapshotPath, rebuilt.snapshot);
64
+ if (!opts.includeCompleted && COMPLETED_PHASES.has(rebuilt.snapshot.phase)) return null;
65
+ return rebuilt.snapshot;
66
+ },
67
+ listActiveSessions() {
68
+ const ids = new Set();
69
+ for (const dir of [legacyRootDir, rootDir]) {
70
+ if (!fs.existsSync(dir)) continue;
71
+ for (const name of fs.readdirSync(dir)) {
72
+ if (name.endsWith('.jsonl')) ids.add(name.slice(0, -'.jsonl'.length));
73
+ }
74
+ }
75
+ return [...ids]
76
+ .sort()
77
+ .map((id) => this.getSnapshot(id))
78
+ .filter(Boolean);
79
+ },
80
+ };
81
+ }
82
+
83
+ function normalizeEvent(event, fallbackId) {
84
+ if (!event || typeof event !== 'object') throw new Error('event object required');
85
+ const id = event.id || fallbackId;
86
+ if (!id || typeof id !== 'string') throw new Error('event id required');
87
+ if (!event.type || typeof event.type !== 'string') throw new Error('event type required');
88
+ return { ...event, id };
89
+ }
90
+
91
+ function getJournalPath(rootDir, id) {
92
+ return path.join(rootDir, safeSessionId(id) + '.jsonl');
93
+ }
94
+
95
+ function getSnapshotPath(rootDir, id) {
96
+ return path.join(rootDir, safeSessionId(id) + '.snapshot.json');
97
+ }
98
+
99
+ function safeSessionId(id) {
100
+ if (!/^[A-Za-z0-9_-]{1,128}$/.test(id)) throw new Error('invalid session id: ' + id);
101
+ return id;
102
+ }
103
+
104
+ function baseSnapshot(id) {
105
+ return {
106
+ id,
107
+ phase: 'new',
108
+ pageUrl: null,
109
+ sourceFile: null,
110
+ previewFile: null,
111
+ previewMode: null,
112
+ expectedVariants: 0,
113
+ arrivedVariants: 0,
114
+ visibleVariant: null,
115
+ paramValues: {},
116
+ pendingEventSeq: null,
117
+ pendingEvent: null,
118
+ deliveryLease: null,
119
+ checkpointRevision: 0,
120
+ activeOwner: null,
121
+ sourceMarkers: {},
122
+ fallbackMode: null,
123
+ annotationArtifacts: [],
124
+ diagnostics: [],
125
+ updatedAt: null,
126
+ };
127
+ }
128
+
129
+ function rebuildSnapshotFromJournal(journalPath, id) {
130
+ let snapshot = baseSnapshot(id);
131
+ const diagnostics = [];
132
+ let nextSeq = 1;
133
+ if (!fs.existsSync(journalPath)) return { snapshot, diagnostics, nextSeq };
134
+
135
+ const lines = fs.readFileSync(journalPath, 'utf-8').split('\n');
136
+ for (let i = 0; i < lines.length; i++) {
137
+ const line = lines[i];
138
+ if (!line.trim()) continue;
139
+ try {
140
+ const entry = JSON.parse(line);
141
+ if (!entry || typeof entry !== 'object') throw new Error('entry is not object');
142
+ if (Number.isInteger(entry.seq)) nextSeq = Math.max(nextSeq, entry.seq + 1);
143
+ snapshot = applyEvent(snapshot, entry);
144
+ } catch (err) {
145
+ diagnostics.push({
146
+ error: 'journal_parse_failed',
147
+ line: i + 1,
148
+ message: err.message,
149
+ });
150
+ }
151
+ }
152
+ snapshot.diagnostics = [...snapshot.diagnostics, ...diagnostics];
153
+ return { snapshot, diagnostics, nextSeq };
154
+ }
155
+
156
+ function applyEvent(snapshot, entry, inheritedDiagnostics = []) {
157
+ const event = entry.event || entry;
158
+ const next = {
159
+ ...snapshot,
160
+ paramValues: { ...(snapshot.paramValues || {}) },
161
+ sourceMarkers: { ...(snapshot.sourceMarkers || {}) },
162
+ annotationArtifacts: [...(snapshot.annotationArtifacts || [])],
163
+ diagnostics: [...(snapshot.diagnostics || [])],
164
+ updatedAt: entry.ts || new Date().toISOString(),
165
+ };
166
+
167
+ if (inheritedDiagnostics.length && next.diagnostics.length === 0) {
168
+ next.diagnostics = [...inheritedDiagnostics];
169
+ }
170
+
171
+ switch (event.type) {
172
+ case 'generate':
173
+ next.phase = 'generate_requested';
174
+ next.pageUrl = event.pageUrl ?? next.pageUrl;
175
+ next.expectedVariants = event.count ?? next.expectedVariants;
176
+ next.pendingEventSeq = entry.seq ?? next.pendingEventSeq;
177
+ next.pendingEvent = toPendingEvent(event);
178
+ if (event.screenshotPath) upsertArtifact(next.annotationArtifacts, { type: 'screenshot', path: event.screenshotPath });
179
+ break;
180
+ case 'variants_ready':
181
+ case 'agent_done':
182
+ next.phase = event.carbonize === true ? 'carbonize_required' : 'variants_ready';
183
+ next.sourceFile = event.sourceFile ?? event.file ?? next.sourceFile;
184
+ next.previewFile = event.previewFile ?? next.previewFile;
185
+ next.previewMode = event.previewMode ?? next.previewMode;
186
+ next.arrivedVariants = event.arrivedVariants ?? (next.expectedVariants || next.arrivedVariants || 0);
187
+ next.pendingEventSeq = null;
188
+ next.pendingEvent = null;
189
+ if (event.carbonize === true) {
190
+ next.diagnostics.push({
191
+ error: 'carbonize_cleanup_required',
192
+ file: event.file || null,
193
+ message: 'Accepted variant still has carbonize markers that must be folded into source CSS.',
194
+ });
195
+ }
196
+ break;
197
+ case 'checkpoint':
198
+ if (COMPLETED_PHASES.has(next.phase)) {
199
+ next.diagnostics.push({ error: 'checkpoint_after_terminal_ignored', phase: event.phase ?? null, revision: event.revision ?? null });
200
+ break;
201
+ }
202
+ if ((event.revision ?? 0) >= (next.checkpointRevision ?? 0)) {
203
+ next.phase = event.phase ?? next.phase;
204
+ next.checkpointRevision = event.revision ?? next.checkpointRevision;
205
+ next.activeOwner = event.owner ?? next.activeOwner;
206
+ next.arrivedVariants = event.arrivedVariants ?? next.arrivedVariants;
207
+ next.visibleVariant = event.visibleVariant ?? next.visibleVariant;
208
+ next.sourceFile = event.sourceFile ?? next.sourceFile;
209
+ next.previewFile = event.previewFile ?? next.previewFile;
210
+ next.previewMode = event.previewMode ?? next.previewMode;
211
+ if (event.paramValues) next.paramValues = { ...event.paramValues };
212
+ } else {
213
+ next.diagnostics.push({ error: 'stale_checkpoint_ignored', revision: event.revision });
214
+ }
215
+ break;
216
+ case 'accept':
217
+ case 'accept_intent':
218
+ next.phase = 'accept_requested';
219
+ next.visibleVariant = Number(event.variantId ?? next.visibleVariant);
220
+ if (event.paramValues) next.paramValues = { ...event.paramValues };
221
+ next.pendingEventSeq = entry.seq ?? next.pendingEventSeq;
222
+ next.pendingEvent = toPendingEvent(event);
223
+ break;
224
+ case 'manual_edit_apply':
225
+ next.phase = 'manual_edit_apply_requested';
226
+ next.pageUrl = event.pageUrl ?? next.pageUrl;
227
+ next.pendingEventSeq = entry.seq ?? next.pendingEventSeq;
228
+ next.pendingEvent = toPendingEvent(event);
229
+ break;
230
+ case 'steer':
231
+ next.phase = 'steer_requested';
232
+ next.pageUrl = event.pageUrl ?? next.pageUrl;
233
+ next.pendingEventSeq = entry.seq ?? next.pendingEventSeq;
234
+ next.pendingEvent = toPendingEvent(event);
235
+ break;
236
+ case 'steer_done':
237
+ next.phase = 'steer_done';
238
+ next.sourceFile = event.sourceFile ?? event.file ?? next.sourceFile;
239
+ next.previewFile = event.previewFile ?? next.previewFile;
240
+ next.previewMode = event.previewMode ?? next.previewMode;
241
+ next.message = event.message ?? next.message;
242
+ next.pendingEventSeq = null;
243
+ next.pendingEvent = null;
244
+ break;
245
+ case 'discard':
246
+ next.phase = 'discard_requested';
247
+ next.pendingEventSeq = entry.seq ?? next.pendingEventSeq;
248
+ next.pendingEvent = toPendingEvent(event);
249
+ break;
250
+ case 'discarded':
251
+ next.phase = 'discarded';
252
+ next.pendingEventSeq = null;
253
+ next.pendingEvent = null;
254
+ break;
255
+ case 'complete':
256
+ next.phase = 'completed';
257
+ next.sourceFile = event.sourceFile ?? event.file ?? next.sourceFile;
258
+ next.previewFile = event.previewFile ?? next.previewFile;
259
+ next.previewMode = event.previewMode ?? next.previewMode;
260
+ next.pendingEventSeq = null;
261
+ next.pendingEvent = null;
262
+ break;
263
+ case 'agent_error':
264
+ next.phase = 'agent_error';
265
+ next.pendingEventSeq = null;
266
+ next.pendingEvent = null;
267
+ next.diagnostics.push({ error: 'agent_error', message: event.message || 'unknown agent error' });
268
+ break;
269
+ default:
270
+ next.diagnostics.push({ error: 'unknown_event_type', type: event.type });
271
+ break;
272
+ }
273
+ return next;
274
+ }
275
+
276
+ function toPendingEvent(event) {
277
+ const pending = { ...event };
278
+ delete pending.token;
279
+ return pending;
280
+ }
281
+
282
+ function upsertArtifact(artifacts, artifact) {
283
+ if (!artifacts.some((existing) => existing.path === artifact.path && existing.type === artifact.type)) {
284
+ artifacts.push(artifact);
285
+ }
286
+ }
287
+
288
+ function writeSnapshot(snapshotPath, snapshot) {
289
+ fs.writeFileSync(snapshotPath, JSON.stringify(snapshot, null, 2) + '\n');
290
+ }