@stacksjs/defaults 0.75.360 → 0.75.362
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/ai/skills/stacks-ai/SKILL.md +22 -0
- package/ai/skills/stacks-native/CATALOG.md +4 -4
- package/ai/skills/stacks-payments/SKILL.md +28 -0
- package/ai/skills/stacks-technical-diagrams/LICENSE +202 -22
- package/ai/skills/stacks-technical-diagrams/LICENSE-MIT +22 -0
- package/ai/skills/stacks-technical-diagrams/NOTICE +26 -0
- package/ai/skills/stacks-technical-diagrams/SKILL.md +106 -266
- package/ai/skills/stacks-technical-diagrams/THIRD_PARTY_NOTICES.md +11 -2
- package/ai/skills/stacks-technical-diagrams/UPSTREAM.json +12 -0
- package/ai/skills/stacks-technical-diagrams/agents/openai.yaml +2 -2
- package/ai/skills/stacks-technical-diagrams/assets/template.html +3655 -3798
- package/ai/skills/stacks-technical-diagrams/bin/archify.mjs +7290 -0
- package/ai/skills/stacks-technical-diagrams/bin/delivery-update.mjs +7 -0
- package/ai/skills/stacks-technical-diagrams/bin/diagrams +1 -0
- package/ai/skills/stacks-technical-diagrams/bin/finalize.mjs +1056 -0
- package/ai/skills/stacks-technical-diagrams/bin/open-artifact.mjs +72 -12
- package/ai/skills/stacks-technical-diagrams/bin/preview.mjs +348 -31
- package/ai/skills/stacks-technical-diagrams/bin/recover-output.mjs +41 -0
- package/ai/skills/stacks-technical-diagrams/bin/technical-diagrams.mjs +3 -2097
- package/ai/skills/stacks-technical-diagrams/bin/visual-check.mjs +2142 -157
- package/ai/skills/stacks-technical-diagrams/brand-marks/README.md +3 -3
- package/ai/skills/stacks-technical-diagrams/delta/architecture-delta.mjs +130 -33
- package/ai/skills/stacks-technical-diagrams/examples/agent-run.lifecycle.json +25 -30
- package/ai/skills/stacks-technical-diagrams/examples/agent-tool-call.workflow.json +0 -20
- package/ai/skills/stacks-technical-diagrams/examples/archify-dev-activity.timeline.json +176 -0
- package/ai/skills/stacks-technical-diagrams/examples/archify-repository.tree.json +197 -0
- package/ai/skills/stacks-technical-diagrams/examples/async-job-roundtrip.sequence.json +1 -6
- package/ai/skills/stacks-technical-diagrams/examples/brand-aware-delivery.architecture.json +3 -16
- package/ai/skills/stacks-technical-diagrams/examples/cache-miss-request.sequence.json +2 -7
- package/ai/skills/stacks-technical-diagrams/examples/checkout-platform.base.architecture.json +2 -1
- package/ai/skills/stacks-technical-diagrams/examples/checkout-platform.head.architecture.json +2 -1
- package/ai/skills/stacks-technical-diagrams/examples/checkout-request.waterfall.json +20 -0
- package/ai/skills/stacks-technical-diagrams/examples/class-payment-processors-rendered.html +14987 -0
- package/ai/skills/stacks-technical-diagrams/examples/class-payments-rendered.html +14787 -0
- package/ai/skills/stacks-technical-diagrams/examples/dataflow-product-analytics.html +14880 -0
- package/ai/skills/stacks-technical-diagrams/examples/delivery.explainer.json +155 -0
- package/ai/skills/stacks-technical-diagrams/examples/deployment-release.lifecycle.json +57 -34
- package/ai/skills/stacks-technical-diagrams/examples/erd-orders-rendered.html +15112 -0
- package/ai/skills/stacks-technical-diagrams/examples/event-stream.dataflow.json +1 -6
- package/ai/skills/stacks-technical-diagrams/examples/example-rebuild.waterfall.json +212 -0
- package/ai/skills/stacks-technical-diagrams/examples/holiday-planning.workflow.json +143 -0
- package/ai/skills/stacks-technical-diagrams/examples/incident-response.workflow.json +1 -6
- package/ai/skills/stacks-technical-diagrams/examples/lifecycle-agent-run.html +14892 -0
- package/ai/skills/stacks-technical-diagrams/examples/locales/de.json +463 -0
- package/ai/skills/stacks-technical-diagrams/examples/locales/fr.json +463 -0
- package/ai/skills/stacks-technical-diagrams/examples/locales/fr.partial.json +22 -0
- package/ai/skills/stacks-technical-diagrams/examples/locales/it.json +463 -0
- package/ai/skills/stacks-technical-diagrams/examples/locales/ja.json +463 -0
- package/ai/skills/stacks-technical-diagrams/examples/locales/pt.json +463 -0
- package/ai/skills/stacks-technical-diagrams/examples/locales/ru.json +463 -0
- package/ai/skills/stacks-technical-diagrams/examples/orders.erd.json +337 -0
- package/ai/skills/stacks-technical-diagrams/examples/payment-incident.timeline.json +24 -0
- package/ai/skills/stacks-technical-diagrams/examples/payment-platform.tree.json +22 -0
- package/ai/skills/stacks-technical-diagrams/examples/payment-processors.class.json +177 -0
- package/ai/skills/stacks-technical-diagrams/examples/payments.class.json +85 -0
- package/ai/skills/stacks-technical-diagrams/examples/product-analytics.dataflow.json +1 -6
- package/ai/skills/stacks-technical-diagrams/examples/production-deployment.architecture.json +3 -23
- package/ai/skills/stacks-technical-diagrams/examples/release-delivery.workflow.json +1 -6
- package/ai/skills/stacks-technical-diagrams/examples/sequence-cache-miss-request.html +14895 -0
- package/ai/skills/stacks-technical-diagrams/examples/subscription-billing-rendered.html +15369 -0
- package/ai/skills/stacks-technical-diagrams/examples/subscription-billing.erd.json +548 -0
- package/ai/skills/stacks-technical-diagrams/examples/timeline-archify-dev-activity-rendered.html +15002 -0
- package/ai/skills/stacks-technical-diagrams/examples/timeline-payment-incident-rendered.html +14772 -0
- package/ai/skills/stacks-technical-diagrams/examples/tree-archify-repository-rendered.html +15071 -0
- package/ai/skills/stacks-technical-diagrams/examples/tree-payment-platform-rendered.html +14810 -0
- package/ai/skills/stacks-technical-diagrams/examples/waterfall-checkout-request-rendered.html +14754 -0
- package/ai/skills/stacks-technical-diagrams/examples/waterfall-example-rebuild-rendered.html +14940 -0
- package/ai/skills/stacks-technical-diagrams/examples/web-app-rendered.html +14889 -0
- package/ai/skills/stacks-technical-diagrams/examples/web-app.architecture.json +1 -6
- package/ai/skills/stacks-technical-diagrams/examples/workflow-agent-tool-call-rendered.html +14907 -0
- package/ai/skills/stacks-technical-diagrams/explainer/browser-check.mjs +208 -0
- package/ai/skills/stacks-technical-diagrams/explainer/charts.mjs +70 -0
- package/ai/skills/stacks-technical-diagrams/explainer/check.mjs +168 -0
- package/ai/skills/stacks-technical-diagrams/explainer/diagrams.mjs +518 -0
- package/ai/skills/stacks-technical-diagrams/explainer/diff.mjs +124 -0
- package/ai/skills/stacks-technical-diagrams/explainer/inline.mjs +155 -0
- package/ai/skills/stacks-technical-diagrams/explainer/layout.mjs +35 -0
- package/ai/skills/stacks-technical-diagrams/explainer/page-bundle.mjs +16 -0
- package/ai/skills/stacks-technical-diagrams/explainer/parse.mjs +300 -0
- package/ai/skills/stacks-technical-diagrams/explainer/patch.mjs +117 -0
- package/ai/skills/stacks-technical-diagrams/explainer/prepare.mjs +131 -0
- package/ai/skills/stacks-technical-diagrams/explainer/reader.css +472 -0
- package/ai/skills/stacks-technical-diagrams/explainer/reader.js +667 -0
- package/ai/skills/stacks-technical-diagrams/explainer/render.mjs +224 -0
- package/ai/skills/stacks-technical-diagrams/explainer/revision.mjs +20 -0
- package/ai/skills/stacks-technical-diagrams/explainer/sources.mjs +318 -0
- package/ai/skills/stacks-technical-diagrams/explainer/validate.mjs +138 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/LICENSE +40 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/README.md +5 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/3DKXF73K.js +4 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/42UTT654.js +3 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/DKTLEL5E.js +1 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/EEIX5ZYH.js +2 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/EJ5KOXYD.js +25 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/GUJTEFZK.js +1 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/IZOKQ2GT.js +4 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/L4LY553T.js +3 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/MSKIJHB2.js +2 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/RVARI57O.js +1 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/UKSIWDDN.js +2 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/UPTXNAXN.js +2 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/XTDUIGUI.js +9 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/chunks/YAYTP6L5.js +9 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/core.js +1 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/diagrams/pie.js +1 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/diagrams/quadrantChart.js +1 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/diagrams/radar.js +1 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/diagrams/sankey.js +1 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/diagrams/venn.js +1 -0
- package/ai/skills/stacks-technical-diagrams/explainer/vendor/pele/diagrams/xychart.js +1 -0
- package/ai/skills/stacks-technical-diagrams/explainer/writing.mjs +139 -0
- package/ai/skills/stacks-technical-diagrams/locales/README.md +40 -0
- package/ai/skills/stacks-technical-diagrams/locales/ar.json +488 -0
- package/ai/skills/stacks-technical-diagrams/locales/en.json +488 -0
- package/ai/skills/stacks-technical-diagrams/locales/es.json +488 -0
- package/ai/skills/stacks-technical-diagrams/locales/ko.json +488 -0
- package/ai/skills/stacks-technical-diagrams/locales/manifest.json +10 -0
- package/ai/skills/stacks-technical-diagrams/locales/zh-CN.json +488 -0
- package/ai/skills/stacks-technical-diagrams/locales/zh-TW.json +488 -0
- package/ai/skills/stacks-technical-diagrams/migrations/workflow-v2.mjs +1 -0
- package/ai/skills/stacks-technical-diagrams/recipes/scenarios.mjs +115 -51
- package/ai/skills/stacks-technical-diagrams/references/architecture-layout-repair.md +18 -0
- package/ai/skills/stacks-technical-diagrams/references/authoring-contract.md +453 -51
- package/ai/skills/stacks-technical-diagrams/references/authoring-defaults.md +57 -0
- package/ai/skills/stacks-technical-diagrams/references/brand-marks.md +57 -3
- package/ai/skills/stacks-technical-diagrams/references/delivery-contract.md +603 -58
- package/ai/skills/stacks-technical-diagrams/references/explainer-authoring.md +274 -0
- package/ai/skills/stacks-technical-diagrams/references/repository-authoring.md +126 -0
- package/ai/skills/stacks-technical-diagrams/references/update-awareness.md +13 -0
- package/ai/skills/stacks-technical-diagrams/references/viewer-runtime.md +18 -11
- package/ai/skills/stacks-technical-diagrams/renderers/architecture/grid.mjs +1 -1
- package/ai/skills/stacks-technical-diagrams/renderers/architecture/labels.mjs +2 -0
- package/ai/skills/stacks-technical-diagrams/renderers/architecture/render-architecture.mjs +550 -424
- package/ai/skills/stacks-technical-diagrams/renderers/architecture/routing.mjs +1469 -0
- package/ai/skills/stacks-technical-diagrams/renderers/class/README.md +129 -0
- package/ai/skills/stacks-technical-diagrams/renderers/class/render-class.mjs +1095 -0
- package/ai/skills/stacks-technical-diagrams/renderers/dataflow/README.md +89 -17
- package/ai/skills/stacks-technical-diagrams/renderers/dataflow/dataflow-compiler.mjs +1605 -0
- package/ai/skills/stacks-technical-diagrams/renderers/dataflow/joint-label-routing.mjs +165 -0
- package/ai/skills/stacks-technical-diagrams/renderers/dataflow/label-capacity.mjs +81 -0
- package/ai/skills/stacks-technical-diagrams/renderers/dataflow/render-dataflow.mjs +14 -474
- package/ai/skills/stacks-technical-diagrams/renderers/erd/README.md +246 -0
- package/ai/skills/stacks-technical-diagrams/renderers/erd/grid.mjs +150 -0
- package/ai/skills/stacks-technical-diagrams/renderers/erd/render-erd.mjs +1588 -0
- package/ai/skills/stacks-technical-diagrams/renderers/explainer/render-explainer.mjs +42 -0
- package/ai/skills/stacks-technical-diagrams/renderers/lifecycle/README.md +83 -94
- package/ai/skills/stacks-technical-diagrams/renderers/lifecycle/render-lifecycle.mjs +990 -417
- package/ai/skills/stacks-technical-diagrams/renderers/sequence/README.md +49 -17
- package/ai/skills/stacks-technical-diagrams/renderers/sequence/render-sequence.mjs +735 -94
- package/ai/skills/stacks-technical-diagrams/renderers/shared/atomic-output.mjs +1982 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/automatic-labels.mjs +290 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/brand-marks.mjs +169 -26
- package/ai/skills/stacks-technical-diagrams/renderers/shared/cli.mjs +266 -54
- package/ai/skills/stacks-technical-diagrams/renderers/shared/desktop-readability.mjs +106 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/diagnostics.mjs +0 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/generated-validators.mjs +268 -2
- package/ai/skills/stacks-technical-diagrams/renderers/shared/geometry.mjs +774 -124
- package/ai/skills/stacks-technical-diagrams/renderers/shared/i18n.mjs +289 -556
- package/ai/skills/stacks-technical-diagrams/renderers/shared/layout-report.mjs +18 -1
- package/ai/skills/stacks-technical-diagrams/renderers/shared/legend.mjs +16 -6
- package/ai/skills/stacks-technical-diagrams/renderers/shared/node-card-style.mjs +32 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/output-path.mjs +329 -229
- package/ai/skills/stacks-technical-diagrams/renderers/shared/owned-temp-directory.mjs +82 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/path-semantics.mjs +1017 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/portable-path.mjs +408 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/repository-evidence.mjs +235 -79
- package/ai/skills/stacks-technical-diagrams/renderers/shared/repository-location.mjs +17 -4
- package/ai/skills/stacks-technical-diagrams/renderers/shared/route-quality.mjs +670 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/sidecar-path.mjs +38 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/software-notices.mjs +6 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/spatial-grid.mjs +66 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/svg-path-analysis.mjs +135 -0
- package/ai/skills/stacks-technical-diagrams/renderers/shared/text-fit.mjs +59 -3
- package/ai/skills/stacks-technical-diagrams/renderers/shared/utils.mjs +63 -35
- package/ai/skills/stacks-technical-diagrams/renderers/shared/validator.mjs +2 -5
- package/ai/skills/stacks-technical-diagrams/renderers/timeline/README.md +76 -0
- package/ai/skills/stacks-technical-diagrams/renderers/timeline/render-timeline.mjs +576 -0
- package/ai/skills/stacks-technical-diagrams/renderers/tree/README.md +96 -0
- package/ai/skills/stacks-technical-diagrams/renderers/tree/render-tree.mjs +573 -0
- package/ai/skills/stacks-technical-diagrams/renderers/waterfall/README.md +73 -0
- package/ai/skills/stacks-technical-diagrams/renderers/waterfall/render-waterfall.mjs +413 -0
- package/ai/skills/stacks-technical-diagrams/renderers/workflow/README.md +137 -23
- package/ai/skills/stacks-technical-diagrams/renderers/workflow/render-workflow.mjs +18 -6
- package/ai/skills/stacks-technical-diagrams/renderers/workflow/workflow-compiler.mjs +2230 -710
- package/ai/skills/stacks-technical-diagrams/renderers/workflow/workflow-migration-geometry.mjs +17 -0
- package/ai/skills/stacks-technical-diagrams/renderers/workflow/workflow-placement-repair.mjs +94 -0
- package/ai/skills/stacks-technical-diagrams/schemas/README.md +87 -40
- package/ai/skills/stacks-technical-diagrams/schemas/architecture.schema.json +7 -33
- package/ai/skills/stacks-technical-diagrams/schemas/class.schema.json +345 -0
- package/ai/skills/stacks-technical-diagrams/schemas/common.schema.json +68 -2
- package/ai/skills/stacks-technical-diagrams/schemas/dataflow.schema.json +14 -3
- package/ai/skills/stacks-technical-diagrams/schemas/erd.schema.json +381 -0
- package/ai/skills/stacks-technical-diagrams/schemas/explainer.schema.json +927 -0
- package/ai/skills/stacks-technical-diagrams/schemas/lifecycle.schema.json +23 -110
- package/ai/skills/stacks-technical-diagrams/schemas/sequence.schema.json +15 -4
- package/ai/skills/stacks-technical-diagrams/schemas/timeline.schema.json +160 -0
- package/ai/skills/stacks-technical-diagrams/schemas/tree.schema.json +141 -0
- package/ai/skills/stacks-technical-diagrams/schemas/waterfall.schema.json +147 -0
- package/ai/skills/stacks-technical-diagrams/schemas/workflow.schema.json +14 -3
- package/ai/skills/stacks-technical-diagrams/scripts/check-render-output.mjs +876 -243
- package/ai/skills/stacks-technical-diagrams/scripts/check-update.mjs +1717 -0
- package/ai/skills/stacks-technical-diagrams/scripts/delivery-update-child.mjs +26 -0
- package/ai/skills/stacks-technical-diagrams/scripts/generate-brand-marks.mjs +141 -0
- package/ai/skills/stacks-technical-diagrams/scripts/generate-validators.mjs +105 -0
- package/ai/skills/stacks-technical-diagrams/scripts/render-examples.mjs +11 -1
- package/ai/skills/stacks-technical-diagrams/scripts/update-contract.mjs +187 -0
- package/ai/skills/stacks-technical-diagrams/skill-release.json +10 -0
- package/ide/vscode/package.json +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { checkForUpdate } from './check-update.mjs';
|
|
4
|
+
|
|
5
|
+
// The parent can be busy in synchronous renderer work. Enforce its original
|
|
6
|
+
// deadline here, in a separate event loop, so cache work cannot continue late.
|
|
7
|
+
if (!/^\d{1,30}$/.test(process.argv[2] || '')) process.exit(1);
|
|
8
|
+
const deadlineAt = BigInt(process.argv[2]);
|
|
9
|
+
const remainingMs = Number(deadlineAt - process.hrtime.bigint()) / 1_000_000;
|
|
10
|
+
if (remainingMs <= 0) process.exit(1);
|
|
11
|
+
const deadlineTimer = setTimeout(() => process.kill(process.pid, 'SIGKILL'), remainingMs);
|
|
12
|
+
deadlineTimer.unref();
|
|
13
|
+
|
|
14
|
+
const result = await checkForUpdate({
|
|
15
|
+
...(process.env.ARCHIFY_UPDATE_RELEASE_PATH
|
|
16
|
+
? { releasePath: process.env.ARCHIFY_UPDATE_RELEASE_PATH } : {}),
|
|
17
|
+
...(process.env.ARCHIFY_UPDATE_CACHE_DIRECTORY
|
|
18
|
+
? { cacheDirectory: process.env.ARCHIFY_UPDATE_CACHE_DIRECTORY } : {}),
|
|
19
|
+
// Leave time to record a failed fetch, so a slow network backs off instead
|
|
20
|
+
// of being killed before its result reaches the cache.
|
|
21
|
+
timeoutMs: Math.max(1, Math.floor(remainingMs - 150)),
|
|
22
|
+
// Recompute the remaining fetch budget after cache preparation, so that
|
|
23
|
+
// startup work cannot consume the failure-recording reserve unnoticed.
|
|
24
|
+
fetchDeadlineNs: deadlineAt - 150_000_000n,
|
|
25
|
+
});
|
|
26
|
+
process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import * as simpleIcons from 'simple-icons';
|
|
7
|
+
|
|
8
|
+
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const root = path.resolve(here, '..');
|
|
10
|
+
const catalogPath = path.join(root, 'brand-marks', 'catalog.json');
|
|
11
|
+
const outputPath = path.join(root, 'renderers', 'shared', 'generated-brand-marks.mjs');
|
|
12
|
+
const catalog = JSON.parse(fs.readFileSync(catalogPath, 'utf8'));
|
|
13
|
+
const simpleIconsVersion = JSON.parse(fs.readFileSync(
|
|
14
|
+
path.join(root, 'node_modules', 'simple-icons', 'package.json'),
|
|
15
|
+
'utf8',
|
|
16
|
+
)).version;
|
|
17
|
+
const simpleBySlug = new Map(Object.values(simpleIcons)
|
|
18
|
+
.filter((icon) => icon && typeof icon === 'object' && icon.slug && icon.path)
|
|
19
|
+
.map((icon) => [icon.slug, icon]));
|
|
20
|
+
|
|
21
|
+
function normalizedList(value) {
|
|
22
|
+
return [...new Set((Array.isArray(value) ? value : [])
|
|
23
|
+
.map((item) => String(item).trim())
|
|
24
|
+
.filter(Boolean))];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function lookupForms(value) {
|
|
28
|
+
const raw = String(value ?? '').trim().toLocaleLowerCase('en-US');
|
|
29
|
+
if (!raw) return [];
|
|
30
|
+
return [...new Set([
|
|
31
|
+
raw,
|
|
32
|
+
raw.replace(/[\s_]+/g, '-'),
|
|
33
|
+
raw.replace(/[\s_.-]+/g, ''),
|
|
34
|
+
])];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function fail(message) {
|
|
38
|
+
console.error(`brand catalog: ${message}`);
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (catalog.schemaVersion !== 1 || !Array.isArray(catalog.marks) || catalog.marks.length === 0) {
|
|
43
|
+
fail('catalog.json must contain a non-empty schemaVersion 1 marks array');
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const ids = new Set();
|
|
47
|
+
const lookupKeys = new Map();
|
|
48
|
+
const domains = new Map();
|
|
49
|
+
const generated = catalog.marks.map((entry, index) => {
|
|
50
|
+
if (!/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(entry.id || '')) fail(`marks[${index}] has an invalid id`);
|
|
51
|
+
if (ids.has(entry.id)) fail(`duplicate id ${entry.id}`);
|
|
52
|
+
ids.add(entry.id);
|
|
53
|
+
|
|
54
|
+
const aliases = normalizedList(entry.aliases);
|
|
55
|
+
const entryDomains = normalizedList(entry.domains).map((domain) => domain.toLowerCase());
|
|
56
|
+
for (const key of [entry.id, ...aliases]) {
|
|
57
|
+
for (const form of lookupForms(key)) {
|
|
58
|
+
if (lookupKeys.has(form) && lookupKeys.get(form) !== entry.id) {
|
|
59
|
+
fail(`lookup key ${JSON.stringify(key)} is shared by ${lookupKeys.get(form)} and ${entry.id}`);
|
|
60
|
+
}
|
|
61
|
+
lookupKeys.set(form, entry.id);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
for (const domain of entryDomains) {
|
|
65
|
+
if (domains.has(domain) && domains.get(domain) !== entry.id) {
|
|
66
|
+
fail(`domain ${domain} is shared by ${domains.get(domain)} and ${entry.id}`);
|
|
67
|
+
}
|
|
68
|
+
domains.set(domain, entry.id);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
let mark;
|
|
72
|
+
if (entry.simpleIcon) {
|
|
73
|
+
const icon = simpleBySlug.get(entry.simpleIcon);
|
|
74
|
+
if (!icon) fail(`${entry.id} references missing Simple Icons slug ${entry.simpleIcon}`);
|
|
75
|
+
mark = {
|
|
76
|
+
id: entry.id,
|
|
77
|
+
title: entry.title || icon.title,
|
|
78
|
+
category: entry.category,
|
|
79
|
+
aliases,
|
|
80
|
+
domains: entryDomains,
|
|
81
|
+
viewBox: 24,
|
|
82
|
+
hex: icon.hex,
|
|
83
|
+
path: icon.path,
|
|
84
|
+
provenance: {
|
|
85
|
+
provider: 'Simple Icons',
|
|
86
|
+
providerVersion: simpleIconsVersion,
|
|
87
|
+
source: icon.source,
|
|
88
|
+
...(icon.guidelines ? { guidelines: icon.guidelines } : {}),
|
|
89
|
+
...(icon.license ? { license: icon.license } : {}),
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
} else if (entry.custom) {
|
|
93
|
+
const custom = entry.custom;
|
|
94
|
+
if (!entry.title || !custom.path || !custom.source || !/^[0-9A-F]{6}$/i.test(custom.hex || '')) {
|
|
95
|
+
fail(`${entry.id} custom mark requires title, path, source, and six-digit hex`);
|
|
96
|
+
}
|
|
97
|
+
mark = {
|
|
98
|
+
id: entry.id,
|
|
99
|
+
title: entry.title,
|
|
100
|
+
category: entry.category,
|
|
101
|
+
aliases,
|
|
102
|
+
domains: entryDomains,
|
|
103
|
+
viewBox: custom.viewBox || 24,
|
|
104
|
+
hex: custom.hex.toUpperCase(),
|
|
105
|
+
path: custom.path,
|
|
106
|
+
provenance: {
|
|
107
|
+
provider: 'Official brand asset',
|
|
108
|
+
source: custom.source,
|
|
109
|
+
...(custom.guidelines ? { guidelines: custom.guidelines } : {}),
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
} else {
|
|
113
|
+
fail(`${entry.id} must provide simpleIcon or custom`);
|
|
114
|
+
}
|
|
115
|
+
if (!mark.category || !mark.title) fail(`${entry.id} is missing category or title`);
|
|
116
|
+
for (const form of lookupForms(mark.title)) {
|
|
117
|
+
if (lookupKeys.has(form) && lookupKeys.get(form) !== entry.id) {
|
|
118
|
+
fail(`title ${JSON.stringify(mark.title)} is shared by ${lookupKeys.get(form)} and ${entry.id}`);
|
|
119
|
+
}
|
|
120
|
+
lookupKeys.set(form, entry.id);
|
|
121
|
+
}
|
|
122
|
+
return mark;
|
|
123
|
+
}).sort((left, right) => left.id.localeCompare(right.id));
|
|
124
|
+
|
|
125
|
+
const banner = `// Generated by scripts/generate-brand-marks.mjs from brand-marks/catalog.json.\n// Simple Icons ${simpleIconsVersion}. Do not edit by hand.\n`;
|
|
126
|
+
const source = `${banner}export const BRAND_MARKS = Object.freeze(${JSON.stringify(generated, null, 2)});\n`;
|
|
127
|
+
|
|
128
|
+
if (process.argv.includes('--check')) {
|
|
129
|
+
const current = fs.existsSync(outputPath)
|
|
130
|
+
? fs.readFileSync(outputPath, 'utf8').replace(/\r\n?/g, '\n')
|
|
131
|
+
: '';
|
|
132
|
+
if (current !== source) {
|
|
133
|
+
console.error('generated brand marks are stale — run npm run generate:brand-marks');
|
|
134
|
+
process.exit(1);
|
|
135
|
+
}
|
|
136
|
+
} else {
|
|
137
|
+
const temporary = `${outputPath}.${process.pid}.tmp`;
|
|
138
|
+
fs.writeFileSync(temporary, source);
|
|
139
|
+
fs.renameSync(temporary, outputPath);
|
|
140
|
+
console.log(`generated ${path.relative(root, outputPath)} (${generated.length} marks)`);
|
|
141
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import Ajv2020 from 'ajv/dist/2020.js';
|
|
7
|
+
import standaloneCode from 'ajv/dist/standalone/index.js';
|
|
8
|
+
|
|
9
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
const root = path.resolve(__dirname, '..');
|
|
11
|
+
const schemasDir = path.join(root, 'schemas');
|
|
12
|
+
const output = path.join(root, 'renderers/shared/generated-validators.mjs');
|
|
13
|
+
const diagramTypes = ['workflow', 'sequence', 'dataflow', 'lifecycle', 'architecture', 'erd', 'tree', 'class', 'timeline', 'waterfall', 'explainer'];
|
|
14
|
+
|
|
15
|
+
const ajv = new Ajv2020({
|
|
16
|
+
allErrors: true,
|
|
17
|
+
strict: true,
|
|
18
|
+
code: { source: true, esm: true },
|
|
19
|
+
});
|
|
20
|
+
ajv.addSchema(JSON.parse(fs.readFileSync(path.join(schemasDir, 'common.schema.json'), 'utf8')));
|
|
21
|
+
|
|
22
|
+
const schemaIds = {};
|
|
23
|
+
for (const type of diagramTypes) {
|
|
24
|
+
const schema = JSON.parse(fs.readFileSync(path.join(schemasDir, `${type}.schema.json`), 'utf8'));
|
|
25
|
+
ajv.addSchema(schema);
|
|
26
|
+
schemaIds[type] = schema.$id;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const banner = '// Generated by scripts/generate-validators.mjs. Do not edit by hand.\n';
|
|
30
|
+
const ajvUcs2Import = 'require("ajv/dist/runtime/ucs2length").default';
|
|
31
|
+
const inlineUcs2Length = `function ucs2length(str) {
|
|
32
|
+
const len = str.length;
|
|
33
|
+
let length = 0;
|
|
34
|
+
let pos = 0;
|
|
35
|
+
while (pos < len) {
|
|
36
|
+
length += 1;
|
|
37
|
+
const value = str.charCodeAt(pos++);
|
|
38
|
+
if (value >= 0xd800 && value <= 0xdbff && pos < len
|
|
39
|
+
&& (str.charCodeAt(pos) & 0xfc00) === 0xdc00) pos += 1;
|
|
40
|
+
}
|
|
41
|
+
return length;
|
|
42
|
+
}`;
|
|
43
|
+
let validatorCode = standaloneCode(ajv, schemaIds);
|
|
44
|
+
if (!validatorCode.includes(ajvUcs2Import)) {
|
|
45
|
+
throw new Error('AJV standalone output no longer contains the expected ucs2length helper');
|
|
46
|
+
}
|
|
47
|
+
validatorCode = validatorCode.replaceAll(ajvUcs2Import, inlineUcs2Length);
|
|
48
|
+
if (validatorCode.includes('require(')) {
|
|
49
|
+
throw new Error('AJV standalone output contains an unexpected runtime dependency');
|
|
50
|
+
}
|
|
51
|
+
for (const type of diagramTypes) {
|
|
52
|
+
const exportPattern = new RegExp(`export const ${type} = (validate\\d+);`);
|
|
53
|
+
const match = validatorCode.match(exportPattern);
|
|
54
|
+
if (!match) throw new Error(`AJV standalone output no longer exports the ${type} validator as expected`);
|
|
55
|
+
validatorCode = validatorCode.replace(exportPattern, `const ${type}Schema = ${match[1]};`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// A diagram type that is a reserved word (`class`) cannot name a function, so
|
|
59
|
+
// it is defined under a safe local name and exported under the type itself.
|
|
60
|
+
const RESERVED_TYPE_NAMES = new Set(['class']);
|
|
61
|
+
const portableOutputWrappers = diagramTypes.map((type) => {
|
|
62
|
+
const name = RESERVED_TYPE_NAMES.has(type) ? `${type}Diagram` : type;
|
|
63
|
+
const exported = name === type ? '' : `\nexport { ${name} as ${type} };`;
|
|
64
|
+
return `${name === type ? 'export ' : ''}function ${name}(data, context = undefined) {
|
|
65
|
+
if (!${type}Schema(data, context)) {
|
|
66
|
+
${name}.errors = ${type}Schema.errors;
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
const output = data?.meta?.output;
|
|
70
|
+
if (typeof output === 'string') {
|
|
71
|
+
try {
|
|
72
|
+
validatePortablePath(output, { profile: 'output' });
|
|
73
|
+
} catch (error) {
|
|
74
|
+
${name}.errors = [{
|
|
75
|
+
instancePath: \`${'${context?.instancePath || \'\'}'}/meta/output\`,
|
|
76
|
+
schemaPath: 'common.schema.json#/$defs/portableOutputPath',
|
|
77
|
+
keyword: 'portablePath',
|
|
78
|
+
params: { reason: error?.reason || 'invalid' },
|
|
79
|
+
message: 'must satisfy the portable output path contract',
|
|
80
|
+
}];
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
${name}.errors = null;
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
${name}.evaluated = ${type}Schema.evaluated;${exported}`;
|
|
88
|
+
}).join('\n');
|
|
89
|
+
|
|
90
|
+
const generated = `${banner}import { validatePortablePath } from './portable-path.mjs';\n${validatorCode}\n${portableOutputWrappers}\n`;
|
|
91
|
+
|
|
92
|
+
if (process.argv.includes('--check')) {
|
|
93
|
+
const current = fs.existsSync(output)
|
|
94
|
+
? fs.readFileSync(output, 'utf8').replace(/\r\n?/g, '\n')
|
|
95
|
+
: '';
|
|
96
|
+
if (current !== generated) {
|
|
97
|
+
console.error('generated validators are stale — run npm run generate:validators');
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
} else {
|
|
101
|
+
const temporary = `${output}.${process.pid}.tmp`;
|
|
102
|
+
fs.writeFileSync(temporary, generated);
|
|
103
|
+
fs.renameSync(temporary, output);
|
|
104
|
+
console.log(`generated ${path.relative(root, output)}`);
|
|
105
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import { runtimeArgs } from '../renderers/shared/bun-runtime.mjs';
|
|
1
2
|
// Re-render every bundled example from its JSON IR. Installed skills keep HTML
|
|
2
3
|
// beside the JSON examples; the development script passes the golden directory.
|
|
3
4
|
|
|
4
5
|
import { execFileSync } from 'node:child_process';
|
|
5
6
|
import path from 'node:path';
|
|
6
7
|
import { fileURLToPath } from 'node:url';
|
|
7
|
-
import { runtimeArgs } from '../renderers/shared/bun-runtime.mjs';
|
|
8
8
|
|
|
9
9
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
10
10
|
const skillRoot = path.resolve(__dirname, '..');
|
|
@@ -16,6 +16,16 @@ const TARGETS = [
|
|
|
16
16
|
['dataflow', 'product-analytics.dataflow.json', 'dataflow-product-analytics.html'],
|
|
17
17
|
['lifecycle', 'agent-run.lifecycle.json', 'lifecycle-agent-run.html'],
|
|
18
18
|
['architecture', 'web-app.architecture.json', 'web-app-rendered.html'],
|
|
19
|
+
['erd', 'orders.erd.json', 'erd-orders-rendered.html'],
|
|
20
|
+
['erd', 'subscription-billing.erd.json', 'subscription-billing-rendered.html'],
|
|
21
|
+
['tree', 'payment-platform.tree.json', 'tree-payment-platform-rendered.html'],
|
|
22
|
+
['tree', 'archify-repository.tree.json', 'tree-archify-repository-rendered.html'],
|
|
23
|
+
['class', 'payments.class.json', 'class-payments-rendered.html'],
|
|
24
|
+
['class', 'payment-processors.class.json', 'class-payment-processors-rendered.html'],
|
|
25
|
+
['timeline', 'payment-incident.timeline.json', 'timeline-payment-incident-rendered.html'],
|
|
26
|
+
['timeline', 'archify-dev-activity.timeline.json', 'timeline-archify-dev-activity-rendered.html'],
|
|
27
|
+
['waterfall', 'checkout-request.waterfall.json', 'waterfall-checkout-request-rendered.html'],
|
|
28
|
+
['waterfall', 'example-rebuild.waterfall.json', 'waterfall-example-rebuild-rendered.html'],
|
|
19
29
|
];
|
|
20
30
|
|
|
21
31
|
for (const [mode, input, output] of TARGETS) {
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
export const SKILL_ID = 'archify';
|
|
2
|
+
export const EXPECTED_REPOSITORY = 'https://github.com/tt-a1i/archify';
|
|
3
|
+
export const DEFAULT_MANIFEST_URL = 'https://tt-a1i.github.io/archify/skill-updates/archify/stable.json';
|
|
4
|
+
|
|
5
|
+
const CONTROL_OR_BIDI = /[\u0000-\u001f\u007f-\u009f\u202a-\u202e\u2066-\u2069]/u;
|
|
6
|
+
const HEX_40 = /^[a-f0-9]{40}$/;
|
|
7
|
+
const HEX_64 = /^[a-f0-9]{64}$/;
|
|
8
|
+
const SEMVER = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$/;
|
|
9
|
+
const UTC_SECONDS = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/;
|
|
10
|
+
|
|
11
|
+
export class UpdateContractError extends Error {
|
|
12
|
+
constructor(message) {
|
|
13
|
+
super(message);
|
|
14
|
+
this.name = 'UpdateContractError';
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function isPlainObject(value) {
|
|
19
|
+
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function hasExactKeys(value, expected) {
|
|
23
|
+
return isPlainObject(value)
|
|
24
|
+
&& Object.keys(value).sort().join('\0') === [...expected].sort().join('\0');
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function parseSemver(value) {
|
|
28
|
+
if (typeof value !== 'string' || value.length > 128) {
|
|
29
|
+
throw new UpdateContractError(`invalid SemVer: ${JSON.stringify(value)}`);
|
|
30
|
+
}
|
|
31
|
+
const match = SEMVER.exec(value);
|
|
32
|
+
if (!match) throw new UpdateContractError(`invalid SemVer: ${JSON.stringify(value)}`);
|
|
33
|
+
const prerelease = match[4]?.split('.') ?? null;
|
|
34
|
+
if (prerelease?.some((identifier) => /^\d+$/.test(identifier)
|
|
35
|
+
&& identifier.length > 1 && identifier.startsWith('0'))) {
|
|
36
|
+
throw new UpdateContractError(`invalid SemVer: ${JSON.stringify(value)}`);
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
core: match.slice(1, 4),
|
|
40
|
+
prerelease,
|
|
41
|
+
build: match[5]?.split('.') ?? null,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function compareNumericIdentifiers(left, right) {
|
|
46
|
+
if (left.length !== right.length) return left.length < right.length ? -1 : 1;
|
|
47
|
+
if (left === right) return 0;
|
|
48
|
+
return left < right ? -1 : 1;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function comparePrerelease(left, right) {
|
|
52
|
+
if (left === null && right === null) return 0;
|
|
53
|
+
if (left === null) return 1;
|
|
54
|
+
if (right === null) return -1;
|
|
55
|
+
const length = Math.max(left.length, right.length);
|
|
56
|
+
for (let index = 0; index < length; index += 1) {
|
|
57
|
+
if (left[index] === undefined) return -1;
|
|
58
|
+
if (right[index] === undefined) return 1;
|
|
59
|
+
if (left[index] === right[index]) continue;
|
|
60
|
+
const leftNumeric = /^\d+$/.test(left[index]);
|
|
61
|
+
const rightNumeric = /^\d+$/.test(right[index]);
|
|
62
|
+
if (leftNumeric && rightNumeric) return compareNumericIdentifiers(left[index], right[index]);
|
|
63
|
+
if (leftNumeric !== rightNumeric) return leftNumeric ? -1 : 1;
|
|
64
|
+
return left[index] < right[index] ? -1 : 1;
|
|
65
|
+
}
|
|
66
|
+
return 0;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function compareSemver(leftValue, rightValue) {
|
|
70
|
+
const left = parseSemver(leftValue);
|
|
71
|
+
const right = parseSemver(rightValue);
|
|
72
|
+
for (let index = 0; index < left.core.length; index += 1) {
|
|
73
|
+
const comparison = compareNumericIdentifiers(left.core[index], right.core[index]);
|
|
74
|
+
if (comparison !== 0) return comparison;
|
|
75
|
+
}
|
|
76
|
+
return comparePrerelease(left.prerelease, right.prerelease);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function releaseChannelForVersion(value) {
|
|
80
|
+
return parseSemver(value).prerelease ? 'development' : 'stable';
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export function isStableCoreVersion(value) {
|
|
84
|
+
try {
|
|
85
|
+
const parsed = parseSemver(value);
|
|
86
|
+
return parsed.prerelease === null && parsed.build === null;
|
|
87
|
+
} catch {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function validateCanonicalUtcTimestamp(value) {
|
|
93
|
+
if (typeof value !== 'string' || !UTC_SECONDS.test(value)) {
|
|
94
|
+
throw new UpdateContractError('publication time must use YYYY-MM-DDTHH:mm:ssZ');
|
|
95
|
+
}
|
|
96
|
+
const timestamp = Date.parse(value);
|
|
97
|
+
if (!Number.isFinite(timestamp)
|
|
98
|
+
|| new Date(timestamp).toISOString().replace('.000Z', 'Z') !== value) {
|
|
99
|
+
throw new UpdateContractError('publication time is not a real UTC calendar instant');
|
|
100
|
+
}
|
|
101
|
+
return value;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function validateLocalRelease(value) {
|
|
105
|
+
if (!hasExactKeys(value, [
|
|
106
|
+
'schemaVersion', 'skillId', 'channel', 'version', 'source', 'updateManifestUrl',
|
|
107
|
+
])
|
|
108
|
+
|| value.schemaVersion !== 1
|
|
109
|
+
|| value.skillId !== SKILL_ID
|
|
110
|
+
|| !hasExactKeys(value.source, ['repository'])
|
|
111
|
+
|| value.source.repository !== EXPECTED_REPOSITORY
|
|
112
|
+
|| value.updateManifestUrl !== DEFAULT_MANIFEST_URL) {
|
|
113
|
+
throw new UpdateContractError('invalid local release identity');
|
|
114
|
+
}
|
|
115
|
+
const expectedChannel = releaseChannelForVersion(value.version);
|
|
116
|
+
if (value.channel !== expectedChannel) {
|
|
117
|
+
throw new UpdateContractError('local release channel does not match its version');
|
|
118
|
+
}
|
|
119
|
+
return {
|
|
120
|
+
schemaVersion: value.schemaVersion,
|
|
121
|
+
skillId: value.skillId,
|
|
122
|
+
channel: value.channel,
|
|
123
|
+
version: value.version,
|
|
124
|
+
source: { repository: value.source.repository },
|
|
125
|
+
updateManifestUrl: value.updateManifestUrl,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export function validateReleaseNotesUrl(value, version) {
|
|
130
|
+
if (!isStableCoreVersion(version)) {
|
|
131
|
+
throw new UpdateContractError('release notes require a stable core version');
|
|
132
|
+
}
|
|
133
|
+
const expected = `https://github.com/tt-a1i/archify/releases/tag/v${version}`;
|
|
134
|
+
if (value !== expected) {
|
|
135
|
+
throw new UpdateContractError('release notes URL is outside the exact trusted release path');
|
|
136
|
+
}
|
|
137
|
+
return value;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export function validateReleaseSummary(value) {
|
|
141
|
+
if (typeof value !== 'string' || value.length < 1 || value.length > 160
|
|
142
|
+
|| CONTROL_OR_BIDI.test(value)) {
|
|
143
|
+
throw new UpdateContractError('invalid release summary');
|
|
144
|
+
}
|
|
145
|
+
return value;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export function validateStableUpdateManifest(value) {
|
|
149
|
+
if (!hasExactKeys(value, [
|
|
150
|
+
'schemaVersion', 'skillId', 'channel', 'version', 'publishedAt', 'source',
|
|
151
|
+
'artifact', 'summary', 'releaseNotes', 'severity',
|
|
152
|
+
])
|
|
153
|
+
|| value.schemaVersion !== 1
|
|
154
|
+
|| value.skillId !== SKILL_ID
|
|
155
|
+
|| value.channel !== 'stable'
|
|
156
|
+
|| !isStableCoreVersion(value.version)
|
|
157
|
+
|| !hasExactKeys(value.source, ['repository', 'ref', 'treeSha'])
|
|
158
|
+
|| value.source.repository !== EXPECTED_REPOSITORY
|
|
159
|
+
|| value.source.ref !== `v${value.version}`
|
|
160
|
+
|| !HEX_40.test(value.source.treeSha)
|
|
161
|
+
|| !hasExactKeys(value.artifact, ['sha256'])
|
|
162
|
+
|| !HEX_64.test(value.artifact.sha256)) {
|
|
163
|
+
throw new UpdateContractError('invalid immutable stable release identity');
|
|
164
|
+
}
|
|
165
|
+
validateCanonicalUtcTimestamp(value.publishedAt);
|
|
166
|
+
validateReleaseSummary(value.summary);
|
|
167
|
+
validateReleaseNotesUrl(value.releaseNotes, value.version);
|
|
168
|
+
if (!['normal', 'security'].includes(value.severity)) {
|
|
169
|
+
throw new UpdateContractError('invalid update severity');
|
|
170
|
+
}
|
|
171
|
+
return {
|
|
172
|
+
schemaVersion: value.schemaVersion,
|
|
173
|
+
skillId: value.skillId,
|
|
174
|
+
channel: value.channel,
|
|
175
|
+
version: value.version,
|
|
176
|
+
publishedAt: value.publishedAt,
|
|
177
|
+
source: {
|
|
178
|
+
repository: value.source.repository,
|
|
179
|
+
ref: value.source.ref,
|
|
180
|
+
treeSha: value.source.treeSha,
|
|
181
|
+
},
|
|
182
|
+
artifact: { sha256: value.artifact.sha256 },
|
|
183
|
+
summary: value.summary,
|
|
184
|
+
releaseNotes: value.releaseNotes,
|
|
185
|
+
severity: value.severity,
|
|
186
|
+
};
|
|
187
|
+
}
|
package/ide/vscode/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"publisher": "Stacks",
|
|
3
3
|
"name": "vscode-stacks",
|
|
4
4
|
"displayName": "Stacks",
|
|
5
|
-
"version": "0.75.
|
|
5
|
+
"version": "0.75.362",
|
|
6
6
|
"description": "Stacks, built into VS Code: stx templates, pickier linting and formatting, encrypted env files, the dev server preview and every buddy command. No other extensions required.",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"funding": "https://github.com/sponsors/chrisbbreuer",
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@stacksjs/defaults",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"sideEffects": false,
|
|
5
|
-
"version": "0.75.
|
|
5
|
+
"version": "0.75.362",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "git+https://github.com/stacksjs/stacks.git",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"dependencies": {
|
|
46
46
|
"@iconify-json/f7": "^1.2.2",
|
|
47
47
|
"@iconify-json/hugeicons": "^1.2.35",
|
|
48
|
-
"@stacksjs/mobile": "0.75.
|
|
48
|
+
"@stacksjs/mobile": "0.75.362",
|
|
49
49
|
"@stacksjs/sanitizer": "0.2.736",
|
|
50
50
|
"@stacksjs/stx": "0.2.736",
|
|
51
51
|
"@xterm/addon-fit": "^0.11.0",
|