@ankhorage/devtools 2.0.11 → 2.0.12
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/README.md +1 -1
- package/dist/tools/skills/assets/zora-designer/SKILL.md +3 -2
- package/dist/tools/skills/assets/zora-designer/references/screen-analysis.md +4 -4
- package/dist/tools/skills/assets/zora-designer/references/workflow.md +2 -2
- package/dist/tools/skills/assets/zora-designer/scripts/owner-api.ts +4 -102
- package/dist/tools/skills/zoraDesignerOwnerFixtures.d.ts +1 -1
- package/dist/tools/skills/zoraDesignerOwnerFixtures.js +21 -25
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
# @ankhorage/devtools
|
|
5
5
|
|
|
6
|
-
         
|
|
7
7
|
|
|
8
8
|
Shared tooling, repository automation, and agent standards for Ankhorage TypeScript projects
|
|
9
9
|
|
|
@@ -46,8 +46,9 @@ types, ZORA elements, events, recipes, and version provenance. Never copy owner
|
|
|
46
46
|
schemas, token inventories, color algorithms, action types, or manifest implementations into this
|
|
47
47
|
skill.
|
|
48
48
|
|
|
49
|
-
The inspection
|
|
50
|
-
|
|
49
|
+
The inspection reads the canonical component and authoring metadata directly from released
|
|
50
|
+
`@ankhorage/zora`. Chess, Game, and Tabletop are core ZORA capabilities; do not discover or load
|
|
51
|
+
standalone `@ankhorage/zora-*` packages.
|
|
51
52
|
|
|
52
53
|
For supplied-screen reconstruction, continue through `recognize` and treat the local analyzer's
|
|
53
54
|
`ScreenSpec`, visual graph, confidence, alternatives, and unresolved diagnostics as the structural
|
|
@@ -16,9 +16,9 @@ bun .agents/skills/zora-designer/scripts/owner-api.ts inspect
|
|
|
16
16
|
bun .agents/skills/zora-designer/scripts/analyze-screen.ts screen-analysis-input.json
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
The analyzer uses the current
|
|
20
|
-
`@ankhorage/
|
|
21
|
-
|
|
19
|
+
The analyzer uses the current canonical core ZORA metadata from released `@ankhorage/zora` and
|
|
20
|
+
delegates image processing to released `@ankhorage/utility/image`. It does not discover or compose
|
|
21
|
+
standalone ZORA plugin packages:
|
|
22
22
|
|
|
23
23
|
```text
|
|
24
24
|
supplied image
|
|
@@ -88,7 +88,7 @@ The analyzer returns:
|
|
|
88
88
|
- aggregate confidence;
|
|
89
89
|
- ranked component candidates by region;
|
|
90
90
|
- unresolved diagnostics;
|
|
91
|
-
- the exact
|
|
91
|
+
- the exact core component names and owner version provenance used for the pass.
|
|
92
92
|
|
|
93
93
|
Use the generated `ScreenSpec` as the structural baseline. Do not discard a high-confidence exact
|
|
94
94
|
metadata match merely because another component looks visually similar.
|
|
@@ -18,8 +18,8 @@ navigator types, ZORA elements, or events. Resolve explicit user input before pr
|
|
|
18
18
|
existing brief values, category recommendations, and global defaults. Record the origin of every
|
|
19
19
|
resolved decision.
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
Use the component catalog reported directly by released core `@ankhorage/zora`. Do not discover,
|
|
22
|
+
compose, or maintain a second catalog from standalone `@ankhorage/zora-*` packages.
|
|
23
23
|
|
|
24
24
|
## 2. Ask in dependency order
|
|
25
25
|
|
|
@@ -84,10 +84,6 @@ interface RecipeMetadata extends Record<string, unknown> {
|
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
interface ZoraMetadataApi extends Record<string, unknown> {
|
|
87
|
-
composeZoraPluginMetadata: (plugins: readonly Record<string, unknown>[]) => {
|
|
88
|
-
componentMeta: Record<string, ComponentMetadata | undefined>;
|
|
89
|
-
};
|
|
90
|
-
ZORA_CORE_PLUGIN_METADATA: Record<string, unknown>;
|
|
91
87
|
ZORA_COMPONENT_META: Record<string, ComponentMetadata | undefined>;
|
|
92
88
|
ZORA_THEME_RECIPE_META: Record<string, RecipeMetadata | undefined>;
|
|
93
89
|
}
|
|
@@ -122,8 +118,8 @@ interface LoadedOwnerModule {
|
|
|
122
118
|
const OWNER_RELEASES = {
|
|
123
119
|
colorTheory: { packageName: '@ankhorage/color-theory', minimumVersion: '0.3.1' },
|
|
124
120
|
contracts: { packageName: '@ankhorage/contracts', minimumVersion: '22.0.2' },
|
|
125
|
-
templates: { packageName: '@ankhorage/templates', minimumVersion: '12.0.
|
|
126
|
-
zora: { packageName: '@ankhorage/zora', minimumVersion: '
|
|
121
|
+
templates: { packageName: '@ankhorage/templates', minimumVersion: '12.0.3' },
|
|
122
|
+
zora: { packageName: '@ankhorage/zora', minimumVersion: '21.1.0' },
|
|
127
123
|
};
|
|
128
124
|
|
|
129
125
|
const OWNER_REQUIREMENTS = {
|
|
@@ -159,12 +155,7 @@ const OWNER_REQUIREMENTS = {
|
|
|
159
155
|
zoraMetadata: {
|
|
160
156
|
...OWNER_RELEASES.zora,
|
|
161
157
|
specifier: '@ankhorage/zora/metadata',
|
|
162
|
-
exports: [
|
|
163
|
-
'composeZoraPluginMetadata',
|
|
164
|
-
'ZORA_COMPONENT_META',
|
|
165
|
-
'ZORA_CORE_PLUGIN_METADATA',
|
|
166
|
-
'ZORA_THEME_RECIPE_META',
|
|
167
|
-
],
|
|
158
|
+
exports: ['ZORA_COMPONENT_META', 'ZORA_THEME_RECIPE_META'],
|
|
168
159
|
},
|
|
169
160
|
};
|
|
170
161
|
|
|
@@ -180,112 +171,27 @@ export async function loadOwnerApis(targetDirectory = process.cwd()) {
|
|
|
180
171
|
const templates = await loadOwnerModule(targetDirectory, OWNER_REQUIREMENTS.templates);
|
|
181
172
|
const zoraTheme = await loadOwnerModule(targetDirectory, OWNER_REQUIREMENTS.zoraTheme);
|
|
182
173
|
const zoraMetadata = await loadOwnerModule(targetDirectory, OWNER_REQUIREMENTS.zoraMetadata);
|
|
183
|
-
const installedPluginMetadata = await loadInstalledZoraPluginMetadata(targetDirectory);
|
|
184
174
|
assertColorTheoryApi(colorTheory.module);
|
|
185
175
|
assertContractsApi(contracts.module);
|
|
186
176
|
assertTemplatesApi(templates.module);
|
|
187
177
|
assertZoraThemeApi(zoraTheme.module);
|
|
188
178
|
assertZoraMetadataApi(zoraMetadata.module);
|
|
189
|
-
const composedZoraMetadata = zoraMetadata.module.composeZoraPluginMetadata([
|
|
190
|
-
zoraMetadata.module.ZORA_CORE_PLUGIN_METADATA,
|
|
191
|
-
...installedPluginMetadata.map((entry) => entry.metadata),
|
|
192
|
-
]);
|
|
193
|
-
assertRecord(composedZoraMetadata, 'composed ZORA plugin metadata');
|
|
194
|
-
assertRecord(composedZoraMetadata.componentMeta, 'composed ZORA component metadata');
|
|
195
179
|
|
|
196
180
|
return {
|
|
197
181
|
colorTheory: colorTheory.module,
|
|
198
182
|
contracts: contracts.module,
|
|
199
183
|
templates: templates.module,
|
|
200
184
|
zoraTheme: zoraTheme.module,
|
|
201
|
-
zoraMetadata:
|
|
202
|
-
...zoraMetadata.module,
|
|
203
|
-
ZORA_COMPONENT_META: composedZoraMetadata.componentMeta,
|
|
204
|
-
},
|
|
185
|
+
zoraMetadata: zoraMetadata.module,
|
|
205
186
|
versions: {
|
|
206
187
|
colorTheory: colorTheory.version,
|
|
207
188
|
contracts: contracts.version,
|
|
208
189
|
templates: templates.version,
|
|
209
190
|
zora: zoraTheme.version,
|
|
210
|
-
plugins: Object.fromEntries(
|
|
211
|
-
installedPluginMetadata.map((entry) => [entry.packageName, entry.version]),
|
|
212
|
-
),
|
|
213
191
|
},
|
|
214
192
|
};
|
|
215
193
|
}
|
|
216
194
|
|
|
217
|
-
/*** Load metadata-only descriptors for every installed ZORA plugin declared by the target package. */
|
|
218
|
-
async function loadInstalledZoraPluginMetadata(
|
|
219
|
-
targetDirectory: string,
|
|
220
|
-
): Promise<{ metadata: Record<string, unknown>; packageName: string; version: string }[]> {
|
|
221
|
-
const targetManifestPath = join(resolve(targetDirectory), 'package.json');
|
|
222
|
-
const targetManifest: unknown = JSON.parse(await readFile(targetManifestPath, 'utf8'));
|
|
223
|
-
assertRecord(targetManifest, 'Target package manifest');
|
|
224
|
-
const packageNames = new Set<string>();
|
|
225
|
-
if (typeof targetManifest.name === 'string') packageNames.add(targetManifest.name);
|
|
226
|
-
for (const field of ['dependencies', 'devDependencies', 'peerDependencies']) {
|
|
227
|
-
const dependencies = targetManifest[field];
|
|
228
|
-
if (!isRecord(dependencies)) continue;
|
|
229
|
-
for (const packageName of Object.keys(dependencies)) packageNames.add(packageName);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
const loaded: { metadata: Record<string, unknown>; packageName: string; version: string }[] = [];
|
|
233
|
-
for (const packageName of [...packageNames].filter(isZoraPluginPackage).sort()) {
|
|
234
|
-
const minimumVersion = resolvePluginMinimumVersion(targetManifest, packageName);
|
|
235
|
-
const requirement: OwnerRequirement = {
|
|
236
|
-
packageName,
|
|
237
|
-
minimumVersion,
|
|
238
|
-
specifier: `${packageName}/metadata`,
|
|
239
|
-
exports: ['ZORA_PLUGIN_METADATA'],
|
|
240
|
-
};
|
|
241
|
-
const plugin = await loadOwnerModule(targetDirectory, requirement);
|
|
242
|
-
const metadata = plugin.module.ZORA_PLUGIN_METADATA;
|
|
243
|
-
assertRecord(metadata, `${packageName} ZORA plugin metadata`);
|
|
244
|
-
loaded.push({ metadata, packageName, version: plugin.version });
|
|
245
|
-
}
|
|
246
|
-
return loaded;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
function isZoraPluginPackage(packageName: string): boolean {
|
|
250
|
-
return packageName.startsWith('@ankhorage/zora-') && packageName !== '@ankhorage/zora';
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
/*** Resolve one ZORA plugin minimum version from the target package declaration or owner package itself. */
|
|
254
|
-
function resolvePluginMinimumVersion(
|
|
255
|
-
targetManifest: Record<string, unknown>,
|
|
256
|
-
packageName: string,
|
|
257
|
-
): string {
|
|
258
|
-
if (targetManifest.name === packageName) {
|
|
259
|
-
const { version } = targetManifest;
|
|
260
|
-
if (typeof version === 'string' && parseVersion(version)[0] >= 0) return version;
|
|
261
|
-
throw new Error(`ZORA plugin owner package ${packageName} must declare a semantic version.`);
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
for (const field of ['dependencies', 'devDependencies', 'peerDependencies']) {
|
|
265
|
-
const dependencies = targetManifest[field];
|
|
266
|
-
if (!isRecord(dependencies)) continue;
|
|
267
|
-
const specifier = dependencies[packageName];
|
|
268
|
-
if (typeof specifier === 'string') {
|
|
269
|
-
return readPluginMinimumVersion(packageName, specifier);
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
throw new Error(`ZORA plugin ${packageName} must be declared by the target package.`);
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
/*** Read the semantic lower bound from one supported published dependency specifier. */
|
|
277
|
-
function readPluginMinimumVersion(packageName: string, specifier: string): string {
|
|
278
|
-
const normalized = specifier.trim().replace(/^workspace:/u, '');
|
|
279
|
-
const match = /^(?:\^|~|>=)?(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?)$/u.exec(normalized);
|
|
280
|
-
const minimumVersion = match?.[1];
|
|
281
|
-
if (minimumVersion === undefined) {
|
|
282
|
-
throw new Error(
|
|
283
|
-
`ZORA plugin ${packageName} must use an exact, caret, tilde, or >= semantic dependency range; found ${specifier}.`,
|
|
284
|
-
);
|
|
285
|
-
}
|
|
286
|
-
return minimumVersion;
|
|
287
|
-
}
|
|
288
|
-
|
|
289
195
|
/*** Load only Contracts for tooling that runs before another owner package has been built. */
|
|
290
196
|
export async function loadContractsApi(targetDirectory = process.cwd()): Promise<ContractsApi> {
|
|
291
197
|
const loaded = await loadOwnerModule(targetDirectory, OWNER_REQUIREMENTS.contracts);
|
|
@@ -754,10 +660,6 @@ function assertZoraThemeApi(value: Record<string, unknown>): asserts value is Zo
|
|
|
754
660
|
|
|
755
661
|
/*** Narrow released ZORA metadata into only the fields the orchestration needs. */
|
|
756
662
|
function assertZoraMetadataApi(value: Record<string, unknown>): asserts value is ZoraMetadataApi {
|
|
757
|
-
if (typeof value.composeZoraPluginMetadata !== 'function') {
|
|
758
|
-
throw new Error('composeZoraPluginMetadata must be a function.');
|
|
759
|
-
}
|
|
760
|
-
assertRecord(value.ZORA_CORE_PLUGIN_METADATA, 'ZORA_CORE_PLUGIN_METADATA');
|
|
761
663
|
assertRecord(value.ZORA_COMPONENT_META, 'ZORA_COMPONENT_META');
|
|
762
664
|
for (const [name, metadata] of Object.entries(value.ZORA_COMPONENT_META)) {
|
|
763
665
|
assertComponentMetadata(metadata, name);
|
|
@@ -3,4 +3,4 @@ export declare const TEMPLATES_FIXTURE_SOURCE: string;
|
|
|
3
3
|
export declare const COLOR_THEORY_FIXTURE_SOURCE = "\nexport const COLOR_HARMONIES = ['monochromatic', 'complementary'];\nexport const COLOR_HARMONY_CATALOG = [\n { id: 'monochromatic', label: 'Monochromatic', description: 'One hue.' },\n { id: 'complementary', label: 'Complementary', description: 'Opposing hues.' },\n];\n";
|
|
4
4
|
export declare const CONTRACTS_FIXTURE_SOURCE = "\nexport const APP_CATEGORIES = ['business_productivity'];\nexport const NAVIGATOR_TYPES = ['stack', 'tabs', 'drawer'];\n";
|
|
5
5
|
export declare const ZORA_THEME_FIXTURE_SOURCE = "\nexport const compileZoraTheme = (themeConfig) => ({\n themeConfig,\n light: { surfaceTheme: { mode: 'light' }, diagnostics: [] },\n dark: { surfaceTheme: { mode: 'dark' }, diagnostics: [] },\n diagnostics: [],\n});\n";
|
|
6
|
-
export declare const ZORA_METADATA_FIXTURE_SOURCE = "\nexport const ZORA_COMPONENT_META = {\n Screen: {\n name: 'Screen',\n category: 'layout',\n description: 'Screen layout root',\n directManifestNode: true,\n allowedChildren: ['View', 'Box', 'Text', 'MissingElement'],\n props: {},\n },\n View: {\n name: 'View',\n category: 'layout',\n directManifestNode: true,\n allowedChildren: ['Text', 'Box'],\n props: {},\n },\n Box: {\n name: 'Box',\n category: 'foundation',\n directManifestNode: true,\n allowedChildren: [],\n props: {},\n },\n Text: {\n name: 'Text',\n category: 'component',\n directManifestNode: true,\n allowedChildren: [],\n props: { text: { type: 'string' } },\n events: {\n press: {\n eventType: 'text.press',\n label: 'Press',\n description: 'Text was pressed.',\n },\n },\n },\n MissingElement: {\n name: 'MissingElement',\n category: 'pattern',\n directManifestNode: true,\n allowedChildren: [],\n manifestPolicy: { kind: 'unresolved-element', availability: 'draft-only', releaseGate: 'blocked' },\n blueprint: { defaultProps: { requestedCapability: 'Unresolved', reason: 'No exact element.' } },\n props: {\n requestedCapability: { type: 'string' },\n reason: { type: 'string' },\n evidenceId: { type: 'string' },\n },\n },\n
|
|
6
|
+
export declare const ZORA_METADATA_FIXTURE_SOURCE = "\nexport const ZORA_COMPONENT_META = {\n Screen: {\n name: 'Screen',\n category: 'layout',\n description: 'Screen layout root',\n directManifestNode: true,\n allowedChildren: ['View', 'Box', 'Text', 'MissingElement'],\n props: {},\n },\n View: {\n name: 'View',\n category: 'layout',\n directManifestNode: true,\n allowedChildren: ['Text', 'Box'],\n props: {},\n },\n Box: {\n name: 'Box',\n category: 'foundation',\n directManifestNode: true,\n allowedChildren: [],\n props: {},\n },\n Text: {\n name: 'Text',\n category: 'component',\n directManifestNode: true,\n allowedChildren: [],\n props: { text: { type: 'string' } },\n events: {\n press: {\n eventType: 'text.press',\n label: 'Press',\n description: 'Text was pressed.',\n },\n },\n },\n MissingElement: {\n name: 'MissingElement',\n category: 'pattern',\n directManifestNode: true,\n allowedChildren: [],\n manifestPolicy: { kind: 'unresolved-element', availability: 'draft-only', releaseGate: 'blocked' },\n blueprint: { defaultProps: { requestedCapability: 'Unresolved', reason: 'No exact element.' } },\n props: {\n requestedCapability: { type: 'string' },\n reason: { type: 'string' },\n evidenceId: { type: 'string' },\n },\n },\n ChessBoard: {\n name: 'ChessBoard',\n category: 'component',\n directManifestNode: true,\n allowedChildren: [],\n props: {},\n },\n GameField: {\n name: 'GameField',\n category: 'component',\n directManifestNode: true,\n allowedChildren: [],\n props: {},\n },\n TabletopTable: {\n name: 'TabletopTable',\n category: 'component',\n directManifestNode: true,\n allowedChildren: [],\n props: {},\n },\n};\nexport const ZORA_THEME_RECIPE_META = {\n Card: {\n name: 'Card',\n kind: 'component',\n fields: { variant: { type: 'choice', options: ['filled', 'outlined'] } },\n },\n};\n";
|
|
@@ -130,31 +130,27 @@ export const ZORA_COMPONENT_META = {
|
|
|
130
130
|
evidenceId: { type: 'string' },
|
|
131
131
|
},
|
|
132
132
|
},
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
return { componentMeta };
|
|
133
|
+
ChessBoard: {
|
|
134
|
+
name: 'ChessBoard',
|
|
135
|
+
category: 'component',
|
|
136
|
+
directManifestNode: true,
|
|
137
|
+
allowedChildren: [],
|
|
138
|
+
props: {},
|
|
139
|
+
},
|
|
140
|
+
GameField: {
|
|
141
|
+
name: 'GameField',
|
|
142
|
+
category: 'component',
|
|
143
|
+
directManifestNode: true,
|
|
144
|
+
allowedChildren: [],
|
|
145
|
+
props: {},
|
|
146
|
+
},
|
|
147
|
+
TabletopTable: {
|
|
148
|
+
name: 'TabletopTable',
|
|
149
|
+
category: 'component',
|
|
150
|
+
directManifestNode: true,
|
|
151
|
+
allowedChildren: [],
|
|
152
|
+
props: {},
|
|
153
|
+
},
|
|
158
154
|
};
|
|
159
155
|
export const ZORA_THEME_RECIPE_META = {
|
|
160
156
|
Card: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ankhorage/devtools",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.12",
|
|
4
4
|
"description": "Shared tooling, repository automation, and agent standards for Ankhorage TypeScript projects",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/ankhorage/devtools#readme",
|