@saluzi/saluzi-edu 0.4.7 → 0.4.8
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/cli.js +51 -60
- package/dist/guide/guide-data.json +1 -1
- package/dist/vendor/archify/LICENSE +22 -0
- package/dist/vendor/archify/SKILL.md +137 -0
- package/dist/vendor/archify/THIRD_PARTY_NOTICES.md +69 -0
- package/dist/vendor/archify/assets/JetBrainsMono-OFL.txt +93 -0
- package/dist/vendor/archify/assets/template.html +14934 -0
- package/dist/vendor/archify/bin/archify.mjs +2687 -0
- package/dist/vendor/archify/bin/open-artifact.mjs +95 -0
- package/dist/vendor/archify/bin/preview.mjs +764 -0
- package/dist/vendor/archify/bin/visual-check.mjs +1012 -0
- package/dist/vendor/archify/brand-marks/README.md +31 -0
- package/dist/vendor/archify/brand-marks/catalog.json +131 -0
- package/dist/vendor/archify/delta/architecture-delta.mjs +1221 -0
- package/dist/vendor/archify/examples/agent-run.lifecycle.json +60 -0
- package/dist/vendor/archify/examples/agent-tool-call.workflow.json +94 -0
- package/dist/vendor/archify/examples/async-job-roundtrip.sequence.json +61 -0
- package/dist/vendor/archify/examples/brand-aware-delivery.architecture.json +47 -0
- package/dist/vendor/archify/examples/cache-miss-request.sequence.json +82 -0
- package/dist/vendor/archify/examples/checkout-platform.base.architecture.json +31 -0
- package/dist/vendor/archify/examples/checkout-platform.head.architecture.json +31 -0
- package/dist/vendor/archify/examples/dataflow-product-analytics.html +15045 -0
- package/dist/vendor/archify/examples/deployment-release.lifecycle.json +49 -0
- package/dist/vendor/archify/examples/event-stream.dataflow.json +57 -0
- package/dist/vendor/archify/examples/incident-response.workflow.json +64 -0
- package/dist/vendor/archify/examples/lifecycle-agent-run.html +14980 -0
- package/dist/vendor/archify/examples/product-analytics.dataflow.json +76 -0
- package/dist/vendor/archify/examples/production-deployment.architecture.json +71 -0
- package/dist/vendor/archify/examples/release-delivery.workflow.json +62 -0
- package/dist/vendor/archify/examples/sequence-cache-miss-request.html +15060 -0
- package/dist/vendor/archify/examples/web-app-rendered.html +15009 -0
- package/dist/vendor/archify/examples/web-app.architecture.json +46 -0
- package/dist/vendor/archify/examples/workflow-agent-tool-call-rendered.html +15051 -0
- package/dist/vendor/archify/migrations/workflow-v2.mjs +279 -0
- package/dist/vendor/archify/package.json +17 -0
- package/dist/vendor/archify/recipes/scenarios.mjs +391 -0
- package/dist/vendor/archify/references/authoring-contract.md +243 -0
- package/dist/vendor/archify/references/brand-marks.md +65 -0
- package/dist/vendor/archify/references/delivery-contract.md +120 -0
- package/dist/vendor/archify/references/viewer-runtime.md +45 -0
- package/dist/vendor/archify/renderers/architecture/grid.mjs +62 -0
- package/dist/vendor/archify/renderers/architecture/render-architecture.mjs +1078 -0
- package/dist/vendor/archify/renderers/dataflow/README.md +104 -0
- package/dist/vendor/archify/renderers/dataflow/render-dataflow.mjs +483 -0
- package/dist/vendor/archify/renderers/lifecycle/README.md +115 -0
- package/dist/vendor/archify/renderers/lifecycle/render-lifecycle.mjs +561 -0
- package/dist/vendor/archify/renderers/sequence/README.md +114 -0
- package/dist/vendor/archify/renderers/sequence/render-sequence.mjs +464 -0
- package/dist/vendor/archify/renderers/shared/brand-marks.mjs +563 -0
- package/dist/vendor/archify/renderers/shared/cli.mjs +218 -0
- package/dist/vendor/archify/renderers/shared/desktop-readability.mjs +26 -0
- package/dist/vendor/archify/renderers/shared/diagnostics.mjs +127 -0
- package/dist/vendor/archify/renderers/shared/engineering-profiles.mjs +157 -0
- package/dist/vendor/archify/renderers/shared/generated-brand-marks.mjs +2003 -0
- package/dist/vendor/archify/renderers/shared/generated-validators.mjs +13 -0
- package/dist/vendor/archify/renderers/shared/geometry.mjs +1423 -0
- package/dist/vendor/archify/renderers/shared/i18n.mjs +595 -0
- package/dist/vendor/archify/renderers/shared/layout-report.mjs +40 -0
- package/dist/vendor/archify/renderers/shared/legend.mjs +217 -0
- package/dist/vendor/archify/renderers/shared/output-path.mjs +340 -0
- package/dist/vendor/archify/renderers/shared/repository-evidence.mjs +238 -0
- package/dist/vendor/archify/renderers/shared/repository-location.mjs +58 -0
- package/dist/vendor/archify/renderers/shared/text-fit.mjs +49 -0
- package/dist/vendor/archify/renderers/shared/utils.mjs +232 -0
- package/dist/vendor/archify/renderers/shared/validator.mjs +86 -0
- package/dist/vendor/archify/renderers/workflow/README.md +223 -0
- package/dist/vendor/archify/renderers/workflow/render-workflow.mjs +35 -0
- package/dist/vendor/archify/renderers/workflow/workflow-compiler.mjs +4400 -0
- package/dist/vendor/archify/renderers/workflow/workflow-migration-geometry.mjs +144 -0
- package/dist/vendor/archify/schemas/README.md +211 -0
- package/dist/vendor/archify/schemas/architecture.schema.json +178 -0
- package/dist/vendor/archify/schemas/common.schema.json +115 -0
- package/dist/vendor/archify/schemas/dataflow.schema.json +243 -0
- package/dist/vendor/archify/schemas/lifecycle.schema.json +266 -0
- package/dist/vendor/archify/schemas/sequence.schema.json +223 -0
- package/dist/vendor/archify/schemas/workflow.schema.json +428 -0
- package/dist/vendor/archify/scripts/check-render-output.mjs +836 -0
- package/dist/vendor/archify/scripts/check-update.mjs +1667 -0
- package/dist/vendor/archify/scripts/render-examples.mjs +26 -0
- package/dist/vendor/archify/scripts/update-contract.mjs +182 -0
- package/dist/vendor/archify/skill-release.json +10 -0
- package/package.json +1 -1
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Re-render every bundled example from its JSON IR. Installed skills keep HTML
|
|
2
|
+
// beside the JSON examples; the development script passes the golden directory.
|
|
3
|
+
|
|
4
|
+
import { execFileSync } from 'node:child_process';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
|
|
8
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const skillRoot = path.resolve(__dirname, '..');
|
|
10
|
+
const outputRoot = path.resolve(process.argv[2] || path.join(skillRoot, 'examples'));
|
|
11
|
+
|
|
12
|
+
const TARGETS = [
|
|
13
|
+
['workflow', 'agent-tool-call.workflow.json', 'workflow-agent-tool-call-rendered.html'],
|
|
14
|
+
['sequence', 'cache-miss-request.sequence.json', 'sequence-cache-miss-request.html'],
|
|
15
|
+
['dataflow', 'product-analytics.dataflow.json', 'dataflow-product-analytics.html'],
|
|
16
|
+
['lifecycle', 'agent-run.lifecycle.json', 'lifecycle-agent-run.html'],
|
|
17
|
+
['architecture', 'web-app.architecture.json', 'web-app-rendered.html'],
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
for (const [mode, input, output] of TARGETS) {
|
|
21
|
+
execFileSync(process.execPath, [
|
|
22
|
+
path.join(skillRoot, `renderers/${mode}/render-${mode}.mjs`),
|
|
23
|
+
path.join(skillRoot, 'examples', input),
|
|
24
|
+
path.join(outputRoot, output),
|
|
25
|
+
], { stdio: 'inherit' });
|
|
26
|
+
}
|
|
@@ -0,0 +1,182 @@
|
|
|
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 validateStableUpdateManifest(value) {
|
|
141
|
+
if (!hasExactKeys(value, [
|
|
142
|
+
'schemaVersion', 'skillId', 'channel', 'version', 'publishedAt', 'source',
|
|
143
|
+
'artifact', 'summary', 'releaseNotes', 'severity',
|
|
144
|
+
])
|
|
145
|
+
|| value.schemaVersion !== 1
|
|
146
|
+
|| value.skillId !== SKILL_ID
|
|
147
|
+
|| value.channel !== 'stable'
|
|
148
|
+
|| !isStableCoreVersion(value.version)
|
|
149
|
+
|| !hasExactKeys(value.source, ['repository', 'ref', 'treeSha'])
|
|
150
|
+
|| value.source.repository !== EXPECTED_REPOSITORY
|
|
151
|
+
|| value.source.ref !== `v${value.version}`
|
|
152
|
+
|| !HEX_40.test(value.source.treeSha)
|
|
153
|
+
|| !hasExactKeys(value.artifact, ['sha256'])
|
|
154
|
+
|| !HEX_64.test(value.artifact.sha256)) {
|
|
155
|
+
throw new UpdateContractError('invalid immutable stable release identity');
|
|
156
|
+
}
|
|
157
|
+
validateCanonicalUtcTimestamp(value.publishedAt);
|
|
158
|
+
if (typeof value.summary !== 'string' || value.summary.length < 1 || value.summary.length > 160
|
|
159
|
+
|| CONTROL_OR_BIDI.test(value.summary)) {
|
|
160
|
+
throw new UpdateContractError('invalid release summary');
|
|
161
|
+
}
|
|
162
|
+
validateReleaseNotesUrl(value.releaseNotes, value.version);
|
|
163
|
+
if (!['normal', 'security'].includes(value.severity)) {
|
|
164
|
+
throw new UpdateContractError('invalid update severity');
|
|
165
|
+
}
|
|
166
|
+
return {
|
|
167
|
+
schemaVersion: value.schemaVersion,
|
|
168
|
+
skillId: value.skillId,
|
|
169
|
+
channel: value.channel,
|
|
170
|
+
version: value.version,
|
|
171
|
+
publishedAt: value.publishedAt,
|
|
172
|
+
source: {
|
|
173
|
+
repository: value.source.repository,
|
|
174
|
+
ref: value.source.ref,
|
|
175
|
+
treeSha: value.source.treeSha,
|
|
176
|
+
},
|
|
177
|
+
artifact: { sha256: value.artifact.sha256 },
|
|
178
|
+
summary: value.summary,
|
|
179
|
+
releaseNotes: value.releaseNotes,
|
|
180
|
+
severity: value.severity,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"skillId": "archify",
|
|
4
|
+
"channel": "development",
|
|
5
|
+
"version": "2.17.0-dev.1",
|
|
6
|
+
"source": {
|
|
7
|
+
"repository": "https://github.com/tt-a1i/archify"
|
|
8
|
+
},
|
|
9
|
+
"updateManifestUrl": "https://tt-a1i.github.io/archify/skill-updates/archify/stable.json"
|
|
10
|
+
}
|