openuispec 0.2.19 → 0.2.20
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/check/audit.js +392 -0
- package/dist/check/index.js +216 -0
- package/dist/cli/configure-target.js +391 -0
- package/dist/cli/index.js +510 -0
- package/dist/cli/init.js +1047 -0
- package/dist/drift/index.js +903 -0
- package/dist/mcp-server/index.js +886 -0
- package/dist/mcp-server/preview-render.js +1761 -0
- package/dist/mcp-server/preview.js +233 -0
- package/dist/mcp-server/screenshot-android.js +458 -0
- package/dist/mcp-server/screenshot-ios.js +639 -0
- package/dist/mcp-server/screenshot-shared.js +180 -0
- package/dist/mcp-server/screenshot.js +459 -0
- package/dist/prepare/index.js +1216 -0
- package/dist/runtime/package-paths.js +33 -0
- package/dist/schema/semantic-lint.js +564 -0
- package/dist/schema/validate.js +689 -0
- package/dist/status/index.js +194 -0
- package/package.json +12 -13
- package/check/audit.ts +0 -426
- package/check/index.ts +0 -320
- package/cli/configure-target.ts +0 -523
- package/cli/index.ts +0 -537
- package/cli/init.ts +0 -1253
- package/drift/index.ts +0 -1165
- package/mcp-server/index.ts +0 -1041
- package/mcp-server/preview-render.ts +0 -1922
- package/mcp-server/preview.ts +0 -292
- package/mcp-server/screenshot-android.ts +0 -621
- package/mcp-server/screenshot-ios.ts +0 -753
- package/mcp-server/screenshot-shared.ts +0 -237
- package/mcp-server/screenshot.ts +0 -563
- package/prepare/index.ts +0 -1530
- package/schema/semantic-lint.ts +0 -692
- package/schema/validate.ts +0 -870
- package/scripts/regenerate-previews.ts +0 -136
- package/scripts/take-all-screenshots.ts +0 -507
- package/status/index.ts +0 -275
package/status/index.ts
DELETED
|
@@ -1,275 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env tsx
|
|
2
|
-
/**
|
|
3
|
-
* Cross-target status summary for OpenUISpec projects.
|
|
4
|
-
*
|
|
5
|
-
* Usage:
|
|
6
|
-
* openuispec status # summarize every target
|
|
7
|
-
* openuispec status --json # machine-readable output
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { existsSync } from "node:fs";
|
|
11
|
-
import {
|
|
12
|
-
computeDrift,
|
|
13
|
-
computeSharedDrift,
|
|
14
|
-
discoverTargets,
|
|
15
|
-
explainDrift,
|
|
16
|
-
findProjectDir,
|
|
17
|
-
formatBaseline,
|
|
18
|
-
hasDriftChanges,
|
|
19
|
-
readOutputDirs,
|
|
20
|
-
readProjectName,
|
|
21
|
-
readSharedLayers,
|
|
22
|
-
readSharedLayerState,
|
|
23
|
-
resolveOutputDir,
|
|
24
|
-
stateFilePath,
|
|
25
|
-
type SharedLayerConfig,
|
|
26
|
-
type StateFile,
|
|
27
|
-
} from "../drift/index.js";
|
|
28
|
-
|
|
29
|
-
import { readFileSync } from "node:fs";
|
|
30
|
-
|
|
31
|
-
interface TargetStatus {
|
|
32
|
-
target: string;
|
|
33
|
-
output_dir: string;
|
|
34
|
-
output_exists: boolean;
|
|
35
|
-
snapshot: boolean;
|
|
36
|
-
snapshot_at: string | null;
|
|
37
|
-
baseline: {
|
|
38
|
-
kind: string | null;
|
|
39
|
-
commit: string | null;
|
|
40
|
-
branch: string | null;
|
|
41
|
-
label: string | null;
|
|
42
|
-
};
|
|
43
|
-
changed: number;
|
|
44
|
-
added: number;
|
|
45
|
-
removed: number;
|
|
46
|
-
behind: boolean;
|
|
47
|
-
explain_available: boolean;
|
|
48
|
-
status: "up to date" | "behind" | "needs baseline" | "needs generation";
|
|
49
|
-
recommended_next_step: string;
|
|
50
|
-
note?: string;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
interface SharedLayerStatus {
|
|
54
|
-
name: string;
|
|
55
|
-
platforms: string[];
|
|
56
|
-
root: string;
|
|
57
|
-
snapshot: boolean;
|
|
58
|
-
snapshot_at: string | null;
|
|
59
|
-
generated_by_target: string | null;
|
|
60
|
-
has_drift: boolean;
|
|
61
|
-
status: "up to date" | "behind" | "needs generation";
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export interface StatusResult {
|
|
65
|
-
project: string;
|
|
66
|
-
targets: TargetStatus[];
|
|
67
|
-
shared_layers?: SharedLayerStatus[];
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function configuredTargets(projectDir: string): string[] {
|
|
71
|
-
try {
|
|
72
|
-
const manifest = readOutputDirs(projectDir);
|
|
73
|
-
const keys = Object.keys(manifest);
|
|
74
|
-
if (keys.length > 0) return keys.sort();
|
|
75
|
-
} catch {
|
|
76
|
-
// ignore
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Fallback to common targets when manifest output_dir is absent.
|
|
80
|
-
return ["android", "ios", "web"];
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function allTargets(projectDir: string, projectName: string): string[] {
|
|
84
|
-
const seen = new Set<string>(configuredTargets(projectDir));
|
|
85
|
-
for (const target of discoverTargets(projectDir, projectName)) {
|
|
86
|
-
seen.add(target);
|
|
87
|
-
}
|
|
88
|
-
return Array.from(seen).sort();
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
function readState(statePath: string): StateFile {
|
|
92
|
-
return JSON.parse(readFileSync(statePath, "utf-8")) as StateFile;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function buildTargetStatus(cwd: string, projectDir: string, projectName: string, target: string): TargetStatus {
|
|
96
|
-
const outputDir = resolveOutputDir(projectDir, projectName, target);
|
|
97
|
-
const outputExists = existsSync(outputDir);
|
|
98
|
-
const path = stateFilePath(projectDir, projectName, target);
|
|
99
|
-
|
|
100
|
-
if (!existsSync(path)) {
|
|
101
|
-
return {
|
|
102
|
-
target,
|
|
103
|
-
output_dir: outputDir,
|
|
104
|
-
output_exists: outputExists,
|
|
105
|
-
snapshot: false,
|
|
106
|
-
snapshot_at: null,
|
|
107
|
-
baseline: {
|
|
108
|
-
kind: null,
|
|
109
|
-
commit: null,
|
|
110
|
-
branch: null,
|
|
111
|
-
label: null,
|
|
112
|
-
},
|
|
113
|
-
changed: 0,
|
|
114
|
-
added: 0,
|
|
115
|
-
removed: 0,
|
|
116
|
-
behind: false,
|
|
117
|
-
explain_available: false,
|
|
118
|
-
status: outputExists ? "needs baseline" : "needs generation",
|
|
119
|
-
recommended_next_step: outputExists
|
|
120
|
-
? `Review the generated output, then run \`openuispec drift --snapshot --target ${target}\` to create the baseline.`
|
|
121
|
-
: `Run code generation for "${target}", then \`openuispec prepare --target ${target}\` to build the target work bundle.`,
|
|
122
|
-
note: outputExists
|
|
123
|
-
? "Baseline pending — generated code exists but user has not yet confirmed it with a snapshot."
|
|
124
|
-
: `Output directory not found. Run code generation for "${target}" first.`,
|
|
125
|
-
};
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
const state = readState(path);
|
|
129
|
-
const result = computeDrift(projectDir, state, false);
|
|
130
|
-
const explanation = explainDrift(projectDir, result);
|
|
131
|
-
const changed = result.drift.changed.length;
|
|
132
|
-
const added = result.drift.added.length;
|
|
133
|
-
const removed = result.drift.removed.length;
|
|
134
|
-
|
|
135
|
-
return {
|
|
136
|
-
target,
|
|
137
|
-
output_dir: outputDir,
|
|
138
|
-
output_exists: outputExists,
|
|
139
|
-
snapshot: true,
|
|
140
|
-
snapshot_at: state.snapshot_at,
|
|
141
|
-
baseline: {
|
|
142
|
-
kind: state.baseline?.kind ?? null,
|
|
143
|
-
commit: state.baseline?.commit ?? null,
|
|
144
|
-
branch: state.baseline?.branch ?? null,
|
|
145
|
-
label: formatBaseline(state.baseline),
|
|
146
|
-
},
|
|
147
|
-
changed,
|
|
148
|
-
added,
|
|
149
|
-
removed,
|
|
150
|
-
behind: changed + added + removed > 0,
|
|
151
|
-
explain_available: explanation.available,
|
|
152
|
-
status: changed + added + removed > 0 ? "behind" : "up to date",
|
|
153
|
-
recommended_next_step:
|
|
154
|
-
changed + added + removed > 0
|
|
155
|
-
? `Run \`openuispec prepare --target ${target}\` to build the target work bundle for the pending spec changes.`
|
|
156
|
-
: `No immediate action required for "${target}". Re-run \`openuispec status\` after spec changes or after re-baselining.`,
|
|
157
|
-
note: explanation.available ? undefined : explanation.note,
|
|
158
|
-
};
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
function buildSharedLayerStatus(projectDir: string, layer: SharedLayerConfig): SharedLayerStatus {
|
|
162
|
-
const state = readSharedLayerState(layer);
|
|
163
|
-
if (!state) {
|
|
164
|
-
return {
|
|
165
|
-
name: layer.name,
|
|
166
|
-
platforms: layer.platforms,
|
|
167
|
-
root: layer.root,
|
|
168
|
-
snapshot: false,
|
|
169
|
-
snapshot_at: null,
|
|
170
|
-
generated_by_target: null,
|
|
171
|
-
has_drift: false,
|
|
172
|
-
status: "needs generation",
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
let hasDrift = false;
|
|
177
|
-
if (layer.tracks.length > 0) {
|
|
178
|
-
hasDrift = hasDriftChanges(computeSharedDrift(projectDir, layer).drift);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
return {
|
|
182
|
-
name: layer.name,
|
|
183
|
-
platforms: layer.platforms,
|
|
184
|
-
root: layer.root,
|
|
185
|
-
snapshot: true,
|
|
186
|
-
snapshot_at: state.snapshot_at,
|
|
187
|
-
generated_by_target: state.generated_by_target,
|
|
188
|
-
has_drift: hasDrift,
|
|
189
|
-
status: hasDrift ? "behind" : "up to date",
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
export function buildStatusResult(cwd: string = process.cwd()): StatusResult {
|
|
194
|
-
const projectDir = findProjectDir(cwd);
|
|
195
|
-
const projectName = readProjectName(projectDir);
|
|
196
|
-
const targets = allTargets(projectDir, projectName).map((target) =>
|
|
197
|
-
buildTargetStatus(cwd, projectDir, projectName, target)
|
|
198
|
-
);
|
|
199
|
-
|
|
200
|
-
const sharedLayers = readSharedLayers(projectDir);
|
|
201
|
-
const sharedLayerStatuses = sharedLayers.length > 0
|
|
202
|
-
? sharedLayers.map((layer) => buildSharedLayerStatus(projectDir, layer))
|
|
203
|
-
: undefined;
|
|
204
|
-
|
|
205
|
-
return {
|
|
206
|
-
project: projectName,
|
|
207
|
-
targets,
|
|
208
|
-
...(sharedLayerStatuses ? { shared_layers: sharedLayerStatuses } : {}),
|
|
209
|
-
};
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
function printReport(result: StatusResult): void {
|
|
213
|
-
console.log("OpenUISpec Status");
|
|
214
|
-
console.log("=================");
|
|
215
|
-
console.log(`Project: ${result.project}`);
|
|
216
|
-
console.log("");
|
|
217
|
-
|
|
218
|
-
for (const target of result.targets) {
|
|
219
|
-
const summary = target.snapshot
|
|
220
|
-
? `${target.changed} changed, ${target.added} added, ${target.removed} removed`
|
|
221
|
-
: target.output_exists
|
|
222
|
-
? "no snapshot"
|
|
223
|
-
: "output missing";
|
|
224
|
-
console.log(`${target.target}`);
|
|
225
|
-
console.log(` output: ${target.output_dir}`);
|
|
226
|
-
console.log(` output exists: ${target.output_exists ? "yes" : "no"}`);
|
|
227
|
-
console.log(` snapshot: ${target.snapshot ? target.snapshot_at : "missing"}`);
|
|
228
|
-
if (target.baseline.label) {
|
|
229
|
-
console.log(` baseline: ${target.baseline.label}`);
|
|
230
|
-
}
|
|
231
|
-
console.log(` drift: ${summary}`);
|
|
232
|
-
console.log(` status: ${target.status}`);
|
|
233
|
-
console.log(` explain: ${target.explain_available ? "available" : "unavailable"}`);
|
|
234
|
-
if (target.note) {
|
|
235
|
-
console.log(` note: ${target.note}`);
|
|
236
|
-
}
|
|
237
|
-
console.log(` next: ${target.recommended_next_step}`);
|
|
238
|
-
console.log("");
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
if (result.shared_layers && result.shared_layers.length > 0) {
|
|
242
|
-
console.log("Shared Layers");
|
|
243
|
-
console.log("─────────────");
|
|
244
|
-
for (const layer of result.shared_layers) {
|
|
245
|
-
console.log(`${layer.name} (${layer.platforms.join(", ")})`);
|
|
246
|
-
console.log(` root: ${layer.root}`);
|
|
247
|
-
console.log(` snapshot: ${layer.snapshot ? layer.snapshot_at : "missing"}`);
|
|
248
|
-
if (layer.generated_by_target) {
|
|
249
|
-
console.log(` generated by: ${layer.generated_by_target}`);
|
|
250
|
-
}
|
|
251
|
-
console.log(` status: ${layer.status}`);
|
|
252
|
-
console.log("");
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
export function runStatus(argv: string[]): void {
|
|
258
|
-
const isJson = argv.includes("--json");
|
|
259
|
-
const result = buildStatusResult(process.cwd());
|
|
260
|
-
|
|
261
|
-
if (isJson) {
|
|
262
|
-
console.log(JSON.stringify(result, null, 2));
|
|
263
|
-
return;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
printReport(result);
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
const isDirectRun =
|
|
270
|
-
process.argv[1]?.endsWith("status/index.ts") ||
|
|
271
|
-
process.argv[1]?.endsWith("status/index.js");
|
|
272
|
-
|
|
273
|
-
if (isDirectRun) {
|
|
274
|
-
runStatus(process.argv.slice(2));
|
|
275
|
-
}
|