@monoes/monodesign 1.2.20 → 1.2.22

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 (85) hide show
  1. package/README.md +2 -2
  2. package/cli/engine/design-system-checks.mjs +381 -0
  3. package/cli/engine/design-system-parse.mjs +433 -0
  4. package/cli/engine/design-system.mjs +20 -736
  5. package/cli/engine/engines/regex/detect-text-matchers.mjs +371 -0
  6. package/cli/engine/engines/regex/detect-text-run.mjs +186 -0
  7. package/cli/engine/engines/regex/detect-text.mjs +11 -523
  8. package/cli/engine/engines/static-html/css-cascade-color.mjs +219 -0
  9. package/cli/engine/engines/static-html/css-cascade-static-data.mjs +138 -0
  10. package/cli/engine/engines/static-html/css-cascade-static-dom.mjs +132 -0
  11. package/cli/engine/engines/static-html/css-cascade-static-parse.mjs +393 -0
  12. package/cli/engine/engines/static-html/css-cascade.mjs +24 -837
  13. package/cli/lib/monodesign-config-consent.mjs +93 -0
  14. package/cli/lib/monodesign-config-core.mjs +37 -0
  15. package/cli/lib/monodesign-config-detection.mjs +133 -0
  16. package/cli/lib/monodesign-config-filter.mjs +198 -0
  17. package/cli/lib/monodesign-config-ignore-value.mjs +212 -0
  18. package/cli/lib/monodesign-config.mjs +21 -623
  19. package/package.json +2 -2
  20. package/skill/scripts/context-fields.mjs +65 -0
  21. package/skill/scripts/context-resolve.mjs +425 -0
  22. package/skill/scripts/context-update.mjs +151 -0
  23. package/skill/scripts/context-utils.mjs +68 -0
  24. package/skill/scripts/context-workspace.mjs +245 -0
  25. package/skill/scripts/context.mjs +17 -891
  26. package/skill/scripts/hook-admin-config.mjs +152 -0
  27. package/skill/scripts/hook-admin-ignore.mjs +131 -0
  28. package/skill/scripts/hook-admin-manifest.mjs +292 -0
  29. package/skill/scripts/hook-admin.mjs +8 -541
  30. package/skill/scripts/hook-lib-cache.mjs +145 -0
  31. package/skill/scripts/hook-lib-config.mjs +292 -0
  32. package/skill/scripts/hook-lib-detector.mjs +72 -0
  33. package/skill/scripts/hook-lib-events.mjs +182 -0
  34. package/skill/scripts/hook-lib-findings.mjs +201 -0
  35. package/skill/scripts/hook-lib-ignore.mjs +205 -0
  36. package/skill/scripts/hook-lib-render.mjs +273 -0
  37. package/skill/scripts/hook-lib-run.mjs +281 -0
  38. package/skill/scripts/hook-lib-scan-targets.mjs +128 -0
  39. package/skill/scripts/hook-lib.mjs +71 -1747
  40. package/skill/scripts/lib/design-parser-colors.mjs +182 -0
  41. package/skill/scripts/lib/design-parser-extract.mjs +333 -0
  42. package/skill/scripts/lib/design-parser-sections.mjs +214 -0
  43. package/skill/scripts/lib/design-parser-yaml.mjs +135 -0
  44. package/skill/scripts/lib/design-parser.mjs +10 -783
  45. package/skill/scripts/live/manual-apply-chunk.mjs +151 -0
  46. package/skill/scripts/live/manual-apply-compact.mjs +122 -0
  47. package/skill/scripts/live/manual-apply-evidence.mjs +115 -0
  48. package/skill/scripts/live/manual-apply-log.mjs +179 -0
  49. package/skill/scripts/live/manual-apply-transaction.mjs +122 -0
  50. package/skill/scripts/live/manual-apply.mjs +65 -640
  51. package/skill/scripts/live/svelte-component-accept.mjs +248 -0
  52. package/skill/scripts/live/svelte-component-css.mjs +230 -0
  53. package/skill/scripts/live/svelte-component-markup.mjs +104 -0
  54. package/skill/scripts/live/svelte-component-scaffold.mjs +118 -0
  55. package/skill/scripts/live/svelte-component-session.mjs +158 -0
  56. package/skill/scripts/live/svelte-component.mjs +32 -792
  57. package/skill/scripts/live-accept-mutate.mjs +152 -0
  58. package/skill/scripts/live-accept-parse.mjs +370 -0
  59. package/skill/scripts/live-accept-scrub.mjs +59 -0
  60. package/skill/scripts/live-accept-search.mjs +58 -0
  61. package/skill/scripts/live-accept.mjs +15 -631
  62. package/skill/scripts/live-commit-manual-edits-paths.mjs +27 -0
  63. package/skill/scripts/live-commit-manual-edits-repair.mjs +166 -0
  64. package/skill/scripts/live-commit-manual-edits-rollback.mjs +231 -0
  65. package/skill/scripts/live-commit-manual-edits-utils.mjs +167 -0
  66. package/skill/scripts/live-commit-manual-edits-verify.mjs +356 -0
  67. package/skill/scripts/live-commit-manual-edits.mjs +24 -881
  68. package/skill/scripts/live-copy-edit-agent.mjs +16 -551
  69. package/skill/scripts/live-copy-edit-compact.mjs +137 -0
  70. package/skill/scripts/live-copy-edit-post-apply.mjs +175 -0
  71. package/skill/scripts/live-copy-edit-runners.mjs +297 -0
  72. package/skill/scripts/live-inject-csp.mjs +132 -0
  73. package/skill/scripts/live-inject-files.mjs +229 -0
  74. package/skill/scripts/live-inject-tag.mjs +114 -0
  75. package/skill/scripts/live-inject.mjs +13 -440
  76. package/skill/scripts/live-server-poll.mjs +232 -0
  77. package/skill/scripts/live-server-routes.mjs +449 -0
  78. package/skill/scripts/live-server-state.mjs +361 -0
  79. package/skill/scripts/live-server.mjs +10 -946
  80. package/skill/scripts/live-wrap-css.mjs +132 -0
  81. package/skill/scripts/live-wrap-manual-edit.mjs +153 -0
  82. package/skill/scripts/live-wrap-search.mjs +247 -0
  83. package/skill/scripts/live-wrap.mjs +21 -484
  84. package/skill/scripts/palette-seeds.mjs +401 -0
  85. package/skill/scripts/palette.mjs +1 -395
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Small generic helpers and shared constants for context.mjs's project/context
3
+ * resolution: canonical file name lists, monorepo marker/ignore sets, and
4
+ * path/JSON primitives used across the context-*.mjs sibling modules.
5
+ *
6
+ * Split out of context.mjs. See that file for context.
7
+ */
8
+ import fs from 'node:fs';
9
+ import path from 'node:path';
10
+
11
+ export const PRODUCT_NAMES = ['PRODUCT.md', 'Product.md', 'product.md'];
12
+ export const DESIGN_NAMES = ['DESIGN.md', 'Design.md', 'design.md'];
13
+ export const FALLBACK_DIRS = ['.agents/context', 'docs'];
14
+ export const MONOREPO_MARKER_FILES = ['pnpm-workspace.yaml', 'turbo.json', 'nx.json', 'lerna.json'];
15
+ export const MONOREPO_FALLBACK_PROJECT_DIRS = ['apps', 'packages'];
16
+ export const WORKSPACE_DISCOVERY_IGNORED_DIRS = new Set([
17
+ 'node_modules',
18
+ '.git',
19
+ 'dist',
20
+ 'build',
21
+ '.next',
22
+ '.nuxt',
23
+ '.svelte-kit',
24
+ '.turbo',
25
+ '.cache',
26
+ 'coverage',
27
+ ]);
28
+
29
+ export function isPathInside(candidate, root) {
30
+ const rel = path.relative(root, candidate).split(path.sep).join('/');
31
+ return !!rel && !rel.startsWith('..') && !path.isAbsolute(rel);
32
+ }
33
+
34
+ export function isPathInsideOrEqual(candidate, root) {
35
+ return path.resolve(candidate) === path.resolve(root) || isPathInside(candidate, root);
36
+ }
37
+
38
+ export function readJson(filePath) {
39
+ try {
40
+ return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
41
+ } catch {
42
+ return null;
43
+ }
44
+ }
45
+
46
+ export function firstExisting(dir, names) {
47
+ for (const name of names) {
48
+ const abs = path.join(dir, name);
49
+ if (fs.existsSync(abs)) return abs;
50
+ }
51
+ return null;
52
+ }
53
+
54
+ export function safeRead(p) {
55
+ try {
56
+ return fs.readFileSync(p, 'utf-8');
57
+ } catch {
58
+ return null;
59
+ }
60
+ }
61
+
62
+ export function escapeRegExp(value) {
63
+ return String(value).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
64
+ }
65
+
66
+ export function hasTargetOption(options) {
67
+ return !!(options && typeof options.targetPath === 'string' && options.targetPath.trim());
68
+ }
@@ -0,0 +1,245 @@
1
+ /**
2
+ * Monorepo workspace pattern discovery for context.mjs: reading workspace
3
+ * globs from package.json/pnpm-workspace.yaml/lerna.json, matching a target
4
+ * path against them, and resolving the nearest project-like root when no
5
+ * pattern matches.
6
+ *
7
+ * Split out of context.mjs. See that file for context.
8
+ */
9
+ import fs from 'node:fs';
10
+ import path from 'node:path';
11
+ import {
12
+ DESIGN_NAMES,
13
+ MONOREPO_FALLBACK_PROJECT_DIRS,
14
+ PRODUCT_NAMES,
15
+ escapeRegExp,
16
+ firstExisting,
17
+ isPathInsideOrEqual,
18
+ readJson,
19
+ } from './context-utils.mjs';
20
+
21
+ export function resolveWorkspaceProjectRoot(repoRoot, targetDir) {
22
+ const rel = path.relative(repoRoot, targetDir).split(path.sep).join('/');
23
+ if (!rel || rel.startsWith('..') || path.isAbsolute(rel)) return repoRoot;
24
+ // rel is POSIX-normalised above, so split on '/' — splitting on path.sep here
25
+ // returned the whole string as a single segment on Windows, no workspace
26
+ // pattern ever matched, and every child project silently resolved to the
27
+ // repo root instead.
28
+ const relSegments = rel.split('/').filter(Boolean);
29
+ const patterns = readWorkspacePatterns(repoRoot);
30
+ const excluded = isExcludedByWorkspacePattern(relSegments, patterns);
31
+ if (!excluded) {
32
+ for (const pattern of patterns) {
33
+ const projectRoot = projectRootFromWorkspacePattern(repoRoot, relSegments, pattern);
34
+ if (projectRoot) return projectRoot;
35
+ }
36
+ }
37
+ if (excluded) return repoRoot;
38
+ if (
39
+ relSegments.length >= 2
40
+ && MONOREPO_FALLBACK_PROJECT_DIRS.includes(relSegments[0])
41
+ ) {
42
+ return path.join(repoRoot, relSegments[0], relSegments[1]);
43
+ }
44
+ const nearest = nearestProjectLikeRoot(repoRoot, targetDir);
45
+ if (nearest) return nearest;
46
+ return repoRoot;
47
+ }
48
+
49
+ export function isExcludedByWorkspacePattern(relSegments, patterns) {
50
+ return patterns.some((rawPattern) => {
51
+ const pattern = normalizeWorkspacePattern(rawPattern);
52
+ if (!pattern.startsWith('!')) return false;
53
+ return workspacePatternMatchesRel(pattern.slice(1), relSegments);
54
+ });
55
+ }
56
+
57
+ function nearestProjectLikeRoot(repoRoot, targetDir) {
58
+ let dir = path.resolve(targetDir);
59
+ const stop = path.resolve(repoRoot);
60
+ while (dir && dir !== stop) {
61
+ if (
62
+ firstExisting(dir, [...PRODUCT_NAMES, ...DESIGN_NAMES])
63
+ || fs.existsSync(path.join(dir, 'package.json'))
64
+ ) {
65
+ return dir;
66
+ }
67
+ const parent = path.dirname(dir);
68
+ if (parent === dir) break;
69
+ dir = parent;
70
+ }
71
+ return null;
72
+ }
73
+
74
+ function nearestPackageRootBetween(repoRoot, targetDir, stopDir) {
75
+ let dir = path.resolve(targetDir);
76
+ const stop = path.resolve(stopDir || repoRoot);
77
+ const root = path.resolve(repoRoot);
78
+ while (dir && dir !== stop && isPathInsideOrEqual(dir, root)) {
79
+ if (fs.existsSync(path.join(dir, 'package.json'))) return dir;
80
+ const parent = path.dirname(dir);
81
+ if (parent === dir) break;
82
+ dir = parent;
83
+ }
84
+ return null;
85
+ }
86
+
87
+ function workspacePatternMatchesRel(pattern, relSegments) {
88
+ const patternSegments = normalizeWorkspacePattern(pattern).split('/').filter(Boolean);
89
+ if (!patternSegments.length) return false;
90
+ if (patternSegments.includes('**')) {
91
+ const firstGlobIndex = patternSegments.findIndex((segment) => segment.includes('*'));
92
+ const literalPrefix = firstGlobIndex === -1
93
+ ? patternSegments
94
+ : patternSegments.slice(0, firstGlobIndex);
95
+ if (relSegments.length < literalPrefix.length + 1) return false;
96
+ for (let i = 0; i < literalPrefix.length; i++) {
97
+ if (!segmentMatches(literalPrefix[i], relSegments[i])) return false;
98
+ }
99
+ return true;
100
+ }
101
+ if (relSegments.length < patternSegments.length) return false;
102
+ for (let i = 0; i < patternSegments.length; i++) {
103
+ if (!segmentMatches(patternSegments[i], relSegments[i])) return false;
104
+ }
105
+ return true;
106
+ }
107
+
108
+ export function readWorkspacePatterns(repoRoot) {
109
+ return [
110
+ ...readPackageWorkspaces(repoRoot),
111
+ ...readPnpmWorkspaces(repoRoot),
112
+ ...readLernaWorkspaces(repoRoot),
113
+ ].filter(Boolean);
114
+ }
115
+
116
+ function readPackageWorkspaces(repoRoot) {
117
+ const pkg = readJson(path.join(repoRoot, 'package.json'));
118
+ const workspaces = pkg?.workspaces;
119
+ if (Array.isArray(workspaces)) return workspaces;
120
+ if (Array.isArray(workspaces?.packages)) return workspaces.packages;
121
+ return [];
122
+ }
123
+
124
+ function readLernaWorkspaces(repoRoot) {
125
+ const lerna = readJson(path.join(repoRoot, 'lerna.json'));
126
+ return Array.isArray(lerna?.packages) ? lerna.packages : [];
127
+ }
128
+
129
+ function readPnpmWorkspaces(repoRoot) {
130
+ try {
131
+ const body = fs.readFileSync(path.join(repoRoot, 'pnpm-workspace.yaml'), 'utf-8');
132
+ const patterns = [];
133
+ let inPackages = false;
134
+ for (const line of body.split(/\r?\n/)) {
135
+ const trimmed = stripYamlInlineComment(line).trim();
136
+ if (!trimmed || trimmed.startsWith('#')) continue;
137
+ const flowMatch = trimmed.match(/^packages:\s*\[(.*)\]\s*$/);
138
+ if (flowMatch) {
139
+ patterns.push(...parseYamlFlowList(flowMatch[1]));
140
+ inPackages = false;
141
+ continue;
142
+ }
143
+ if (/^packages:\s*$/.test(trimmed)) {
144
+ inPackages = true;
145
+ continue;
146
+ }
147
+ if (inPackages && /^[A-Za-z0-9_-]+:\s*/.test(trimmed)) break;
148
+ if (inPackages) {
149
+ const match = trimmed.match(/^-\s*(.+)$/);
150
+ if (match) patterns.push(unquoteYamlValue(match[1]));
151
+ }
152
+ }
153
+ return patterns;
154
+ } catch {
155
+ return [];
156
+ }
157
+ }
158
+
159
+ function stripYamlInlineComment(line) {
160
+ let quote = null;
161
+ for (let i = 0; i < line.length; i++) {
162
+ const ch = line[i];
163
+ if ((ch === '"' || ch === "'") && line[i - 1] !== '\\') {
164
+ quote = quote === ch ? null : quote || ch;
165
+ continue;
166
+ }
167
+ if (ch === '#' && !quote) return line.slice(0, i);
168
+ }
169
+ return line;
170
+ }
171
+
172
+ function parseYamlFlowList(body) {
173
+ const items = [];
174
+ let quote = null;
175
+ let current = '';
176
+ for (let i = 0; i < body.length; i++) {
177
+ const ch = body[i];
178
+ if ((ch === '"' || ch === "'") && body[i - 1] !== '\\') {
179
+ quote = quote === ch ? null : quote || ch;
180
+ current += ch;
181
+ continue;
182
+ }
183
+ if (ch === ',' && !quote) {
184
+ const value = unquoteYamlValue(current);
185
+ if (value) items.push(value);
186
+ current = '';
187
+ continue;
188
+ }
189
+ current += ch;
190
+ }
191
+ const value = unquoteYamlValue(current);
192
+ if (value) items.push(value);
193
+ return items;
194
+ }
195
+
196
+ function unquoteYamlValue(value) {
197
+ return String(value || '')
198
+ .trim()
199
+ .replace(/^['"]|['"]$/g, '');
200
+ }
201
+ function projectRootFromWorkspacePattern(repoRoot, relSegments, rawPattern) {
202
+ const pattern = normalizeWorkspacePattern(rawPattern);
203
+ if (!pattern || pattern.startsWith('!')) return null;
204
+ const patternSegments = pattern.split('/').filter(Boolean);
205
+ if (!patternSegments.length) return null;
206
+ if (patternSegments.includes('**')) {
207
+ return projectRootFromDoubleStarPattern(repoRoot, relSegments, patternSegments);
208
+ }
209
+ if (relSegments.length < patternSegments.length) return null;
210
+ for (let i = 0; i < patternSegments.length; i++) {
211
+ if (!segmentMatches(patternSegments[i], relSegments[i])) return null;
212
+ }
213
+ return path.join(repoRoot, ...relSegments.slice(0, patternSegments.length));
214
+ }
215
+
216
+ function projectRootFromDoubleStarPattern(repoRoot, relSegments, patternSegments) {
217
+ const firstGlobIndex = patternSegments.findIndex((segment) => segment.includes('*'));
218
+ const literalPrefix = firstGlobIndex === -1
219
+ ? patternSegments
220
+ : patternSegments.slice(0, firstGlobIndex);
221
+ if (relSegments.length < literalPrefix.length + 1) return null;
222
+ for (let i = 0; i < literalPrefix.length; i++) {
223
+ if (!segmentMatches(literalPrefix[i], relSegments[i])) return null;
224
+ }
225
+ const prefixDir = path.join(repoRoot, ...literalPrefix);
226
+ const targetDir = path.join(repoRoot, ...relSegments);
227
+ const packageRoot = nearestPackageRootBetween(repoRoot, targetDir, prefixDir);
228
+ if (packageRoot) return packageRoot;
229
+ return path.join(repoRoot, ...relSegments.slice(0, literalPrefix.length + 1));
230
+ }
231
+
232
+ export function normalizeWorkspacePattern(pattern) {
233
+ return String(pattern || '')
234
+ .trim()
235
+ .replace(/^['"]|['"]$/g, '')
236
+ .replace(/^\.\//, '')
237
+ .replace(/\/+$/, '');
238
+ }
239
+
240
+ export function segmentMatches(patternSegment, relSegment) {
241
+ if (patternSegment === '*') return true;
242
+ if (!patternSegment.includes('*')) return patternSegment === relSegment;
243
+ const re = new RegExp(`^${escapeRegExp(patternSegment).replace(/\\\*/g, '[^/]*')}$`);
244
+ return re.test(relSegment);
245
+ }