graphitect 0.2.0__py3-none-any.whl
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.
- graphify/__init__.py +30 -0
- graphify/__main__.py +757 -0
- graphify/_minhash.py +107 -0
- graphify/affected.py +318 -0
- graphify/always_on/agents-md.md +12 -0
- graphify/always_on/antigravity-rules.md +14 -0
- graphify/always_on/claude-md.md +9 -0
- graphify/always_on/gemini-md.md +9 -0
- graphify/always_on/kiro-steering.md +5 -0
- graphify/always_on/vscode-instructions.md +17 -0
- graphify/analyze.py +769 -0
- graphify/benchmark.py +152 -0
- graphify/build.py +2300 -0
- graphify/cache.py +1746 -0
- graphify/callflow_html.py +2051 -0
- graphify/cargo_introspect.py +109 -0
- graphify/cli.py +4745 -0
- graphify/cluster.py +409 -0
- graphify/command-kilo.md +15 -0
- graphify/cross_repo_calls.py +216 -0
- graphify/cross_repo_types.py +75 -0
- graphify/csharp_dispatch.py +154 -0
- graphify/dedup.py +1213 -0
- graphify/detect.py +2566 -0
- graphify/diagnostics.py +406 -0
- graphify/export.py +1349 -0
- graphify/exporters/__init__.py +1 -0
- graphify/exporters/base.py +14 -0
- graphify/exporters/graphdb.py +173 -0
- graphify/exporters/html.py +637 -0
- graphify/extract.py +7856 -0
- graphify/extractors/MIGRATION.md +107 -0
- graphify/extractors/__init__.py +66 -0
- graphify/extractors/apex.py +215 -0
- graphify/extractors/base.py +85 -0
- graphify/extractors/bash.py +579 -0
- graphify/extractors/blade.py +53 -0
- graphify/extractors/commonlisp.py +540 -0
- graphify/extractors/csharp.py +448 -0
- graphify/extractors/dart.py +564 -0
- graphify/extractors/dm.py +494 -0
- graphify/extractors/elixir.py +241 -0
- graphify/extractors/engine.py +6509 -0
- graphify/extractors/fortran.py +311 -0
- graphify/extractors/go.py +527 -0
- graphify/extractors/json_config.py +240 -0
- graphify/extractors/julia.py +289 -0
- graphify/extractors/markdown.py +408 -0
- graphify/extractors/models.py +131 -0
- graphify/extractors/objc.py +566 -0
- graphify/extractors/ocaml.py +289 -0
- graphify/extractors/pascal.py +688 -0
- graphify/extractors/pascal_forms.py +196 -0
- graphify/extractors/powershell.py +522 -0
- graphify/extractors/razor.py +192 -0
- graphify/extractors/resolution.py +3584 -0
- graphify/extractors/robot.py +296 -0
- graphify/extractors/rust.py +470 -0
- graphify/extractors/sln.py +92 -0
- graphify/extractors/sql.py +720 -0
- graphify/extractors/terraform.py +181 -0
- graphify/extractors/verilog.py +329 -0
- graphify/extractors/zig.py +181 -0
- graphify/file_slice.py +246 -0
- graphify/global_graph.py +194 -0
- graphify/google_workspace.py +237 -0
- graphify/hooks.py +933 -0
- graphify/ids.py +93 -0
- graphify/ingest.py +358 -0
- graphify/install.py +2366 -0
- graphify/llm.py +3544 -0
- graphify/manifest.py +4 -0
- graphify/manifest_ingest.py +311 -0
- graphify/mcp_ingest.py +386 -0
- graphify/multigraph_compat.py +212 -0
- graphify/pascal_resolution.py +129 -0
- graphify/paths.py +436 -0
- graphify/pg_introspect.py +165 -0
- graphify/prs.py +770 -0
- graphify/querylog.py +80 -0
- graphify/reflect.py +882 -0
- graphify/report.py +346 -0
- graphify/resolver_registry.py +85 -0
- graphify/ruby_resolution.py +242 -0
- graphify/scip_ingest.py +363 -0
- graphify/security.py +460 -0
- graphify/semantic_cleanup.py +336 -0
- graphify/serve.py +2608 -0
- graphify/skill-agents.md +710 -0
- graphify/skill-aider.md +1283 -0
- graphify/skill-amp.md +710 -0
- graphify/skill-claw.md +713 -0
- graphify/skill-codex.md +710 -0
- graphify/skill-copilot.md +713 -0
- graphify/skill-devin.md +1410 -0
- graphify/skill-droid.md +710 -0
- graphify/skill-kilo.md +722 -0
- graphify/skill-kiro.md +713 -0
- graphify/skill-opencode.md +705 -0
- graphify/skill-pi.md +713 -0
- graphify/skill-trae.md +711 -0
- graphify/skill-vscode.md +709 -0
- graphify/skill-windows.md +755 -0
- graphify/skill.md +713 -0
- graphify/skills/agents/references/add-watch.md +56 -0
- graphify/skills/agents/references/exports.md +87 -0
- graphify/skills/agents/references/extraction-spec.md +70 -0
- graphify/skills/agents/references/github-and-merge.md +46 -0
- graphify/skills/agents/references/hooks.md +33 -0
- graphify/skills/agents/references/query.md +311 -0
- graphify/skills/agents/references/transcribe.md +52 -0
- graphify/skills/agents/references/update.md +210 -0
- graphify/skills/amp/references/add-watch.md +56 -0
- graphify/skills/amp/references/exports.md +87 -0
- graphify/skills/amp/references/extraction-spec.md +70 -0
- graphify/skills/amp/references/github-and-merge.md +46 -0
- graphify/skills/amp/references/hooks.md +33 -0
- graphify/skills/amp/references/query.md +311 -0
- graphify/skills/amp/references/transcribe.md +52 -0
- graphify/skills/amp/references/update.md +210 -0
- graphify/skills/claude/references/add-watch.md +56 -0
- graphify/skills/claude/references/exports.md +87 -0
- graphify/skills/claude/references/extraction-spec.md +70 -0
- graphify/skills/claude/references/github-and-merge.md +46 -0
- graphify/skills/claude/references/hooks.md +33 -0
- graphify/skills/claude/references/query.md +311 -0
- graphify/skills/claude/references/transcribe.md +52 -0
- graphify/skills/claude/references/update.md +210 -0
- graphify/skills/claw/references/add-watch.md +56 -0
- graphify/skills/claw/references/exports.md +87 -0
- graphify/skills/claw/references/extraction-spec.md +31 -0
- graphify/skills/claw/references/github-and-merge.md +46 -0
- graphify/skills/claw/references/hooks.md +33 -0
- graphify/skills/claw/references/query.md +311 -0
- graphify/skills/claw/references/transcribe.md +52 -0
- graphify/skills/claw/references/update.md +210 -0
- graphify/skills/codex/references/add-watch.md +56 -0
- graphify/skills/codex/references/exports.md +87 -0
- graphify/skills/codex/references/extraction-spec.md +31 -0
- graphify/skills/codex/references/github-and-merge.md +46 -0
- graphify/skills/codex/references/hooks.md +33 -0
- graphify/skills/codex/references/query.md +311 -0
- graphify/skills/codex/references/transcribe.md +52 -0
- graphify/skills/codex/references/update.md +210 -0
- graphify/skills/copilot/references/add-watch.md +56 -0
- graphify/skills/copilot/references/exports.md +87 -0
- graphify/skills/copilot/references/extraction-spec.md +70 -0
- graphify/skills/copilot/references/github-and-merge.md +46 -0
- graphify/skills/copilot/references/hooks.md +33 -0
- graphify/skills/copilot/references/query.md +311 -0
- graphify/skills/copilot/references/transcribe.md +52 -0
- graphify/skills/copilot/references/update.md +210 -0
- graphify/skills/droid/references/add-watch.md +56 -0
- graphify/skills/droid/references/exports.md +87 -0
- graphify/skills/droid/references/extraction-spec.md +70 -0
- graphify/skills/droid/references/github-and-merge.md +46 -0
- graphify/skills/droid/references/hooks.md +33 -0
- graphify/skills/droid/references/query.md +311 -0
- graphify/skills/droid/references/transcribe.md +52 -0
- graphify/skills/droid/references/update.md +210 -0
- graphify/skills/kilo/references/add-watch.md +56 -0
- graphify/skills/kilo/references/exports.md +87 -0
- graphify/skills/kilo/references/extraction-spec.md +70 -0
- graphify/skills/kilo/references/github-and-merge.md +46 -0
- graphify/skills/kilo/references/hooks.md +33 -0
- graphify/skills/kilo/references/query.md +311 -0
- graphify/skills/kilo/references/transcribe.md +52 -0
- graphify/skills/kilo/references/update.md +210 -0
- graphify/skills/kiro/references/add-watch.md +56 -0
- graphify/skills/kiro/references/exports.md +87 -0
- graphify/skills/kiro/references/extraction-spec.md +31 -0
- graphify/skills/kiro/references/github-and-merge.md +46 -0
- graphify/skills/kiro/references/hooks.md +33 -0
- graphify/skills/kiro/references/query.md +311 -0
- graphify/skills/kiro/references/transcribe.md +52 -0
- graphify/skills/kiro/references/update.md +210 -0
- graphify/skills/opencode/references/add-watch.md +56 -0
- graphify/skills/opencode/references/exports.md +87 -0
- graphify/skills/opencode/references/extraction-spec.md +70 -0
- graphify/skills/opencode/references/github-and-merge.md +46 -0
- graphify/skills/opencode/references/hooks.md +33 -0
- graphify/skills/opencode/references/query.md +311 -0
- graphify/skills/opencode/references/transcribe.md +52 -0
- graphify/skills/opencode/references/update.md +210 -0
- graphify/skills/pi/references/add-watch.md +56 -0
- graphify/skills/pi/references/exports.md +87 -0
- graphify/skills/pi/references/extraction-spec.md +31 -0
- graphify/skills/pi/references/github-and-merge.md +46 -0
- graphify/skills/pi/references/hooks.md +33 -0
- graphify/skills/pi/references/query.md +311 -0
- graphify/skills/pi/references/transcribe.md +52 -0
- graphify/skills/pi/references/update.md +210 -0
- graphify/skills/trae/references/add-watch.md +56 -0
- graphify/skills/trae/references/exports.md +87 -0
- graphify/skills/trae/references/extraction-spec.md +70 -0
- graphify/skills/trae/references/github-and-merge.md +46 -0
- graphify/skills/trae/references/hooks.md +35 -0
- graphify/skills/trae/references/query.md +311 -0
- graphify/skills/trae/references/transcribe.md +52 -0
- graphify/skills/trae/references/update.md +210 -0
- graphify/skills/vscode/references/add-watch.md +56 -0
- graphify/skills/vscode/references/exports.md +87 -0
- graphify/skills/vscode/references/extraction-spec.md +70 -0
- graphify/skills/vscode/references/github-and-merge.md +46 -0
- graphify/skills/vscode/references/hooks.md +33 -0
- graphify/skills/vscode/references/query.md +311 -0
- graphify/skills/vscode/references/transcribe.md +52 -0
- graphify/skills/vscode/references/update.md +210 -0
- graphify/skills/windows/references/add-watch.md +56 -0
- graphify/skills/windows/references/exports.md +87 -0
- graphify/skills/windows/references/extraction-spec.md +70 -0
- graphify/skills/windows/references/github-and-merge.md +46 -0
- graphify/skills/windows/references/hooks.md +33 -0
- graphify/skills/windows/references/query.md +311 -0
- graphify/skills/windows/references/transcribe.md +52 -0
- graphify/skills/windows/references/update.md +210 -0
- graphify/symbol_resolution.py +556 -0
- graphify/transcribe.py +186 -0
- graphify/tree_html.py +603 -0
- graphify/validate.py +95 -0
- graphify/watch.py +2280 -0
- graphify/wiki.py +405 -0
- graphitect/__init__.py +28 -0
- graphitect/__main__.py +4 -0
- graphitect/_vendor/__init__.py +2 -0
- graphitect/_vendor/archify/LICENSE +22 -0
- graphitect/_vendor/archify/SKILL.md +137 -0
- graphitect/_vendor/archify/THIRD_PARTY_NOTICES.md +69 -0
- graphitect/_vendor/archify/assets/JetBrainsMono-OFL.txt +93 -0
- graphitect/_vendor/archify/assets/template.html +14935 -0
- graphitect/_vendor/archify/bin/archify.mjs +2091 -0
- graphitect/_vendor/archify/bin/open-artifact.mjs +86 -0
- graphitect/_vendor/archify/bin/preview.mjs +653 -0
- graphitect/_vendor/archify/bin/visual-check.mjs +829 -0
- graphitect/_vendor/archify/brand-marks/README.md +31 -0
- graphitect/_vendor/archify/brand-marks/catalog.json +131 -0
- graphitect/_vendor/archify/delta/architecture-delta.mjs +1221 -0
- graphitect/_vendor/archify/examples/agent-run.lifecycle.json +60 -0
- graphitect/_vendor/archify/examples/agent-tool-call.workflow.json +94 -0
- graphitect/_vendor/archify/examples/async-job-roundtrip.sequence.json +61 -0
- graphitect/_vendor/archify/examples/brand-aware-delivery.architecture.json +47 -0
- graphitect/_vendor/archify/examples/cache-miss-request.sequence.json +82 -0
- graphitect/_vendor/archify/examples/checkout-platform.base.architecture.json +31 -0
- graphitect/_vendor/archify/examples/checkout-platform.head.architecture.json +31 -0
- graphitect/_vendor/archify/examples/dataflow-product-analytics.html +15045 -0
- graphitect/_vendor/archify/examples/deployment-release.lifecycle.json +49 -0
- graphitect/_vendor/archify/examples/event-stream.dataflow.json +57 -0
- graphitect/_vendor/archify/examples/incident-response.workflow.json +64 -0
- graphitect/_vendor/archify/examples/lifecycle-agent-run.html +14980 -0
- graphitect/_vendor/archify/examples/product-analytics.dataflow.json +76 -0
- graphitect/_vendor/archify/examples/production-deployment.architecture.json +71 -0
- graphitect/_vendor/archify/examples/release-delivery.workflow.json +62 -0
- graphitect/_vendor/archify/examples/sequence-cache-miss-request.html +15060 -0
- graphitect/_vendor/archify/examples/web-app-rendered.html +15009 -0
- graphitect/_vendor/archify/examples/web-app.architecture.json +46 -0
- graphitect/_vendor/archify/examples/workflow-agent-tool-call-rendered.html +15051 -0
- graphitect/_vendor/archify/migrations/workflow-v2.mjs +279 -0
- graphitect/_vendor/archify/package-lock.json +149 -0
- graphitect/_vendor/archify/package.json +39 -0
- graphitect/_vendor/archify/recipes/scenarios.mjs +391 -0
- graphitect/_vendor/archify/references/authoring-contract.md +243 -0
- graphitect/_vendor/archify/references/brand-marks.md +65 -0
- graphitect/_vendor/archify/references/delivery-contract.md +120 -0
- graphitect/_vendor/archify/references/viewer-runtime.md +45 -0
- graphitect/_vendor/archify/renderers/architecture/grid.mjs +62 -0
- graphitect/_vendor/archify/renderers/architecture/render-architecture.mjs +1078 -0
- graphitect/_vendor/archify/renderers/dataflow/README.md +104 -0
- graphitect/_vendor/archify/renderers/dataflow/render-dataflow.mjs +483 -0
- graphitect/_vendor/archify/renderers/lifecycle/README.md +115 -0
- graphitect/_vendor/archify/renderers/lifecycle/render-lifecycle.mjs +561 -0
- graphitect/_vendor/archify/renderers/sequence/README.md +114 -0
- graphitect/_vendor/archify/renderers/sequence/render-sequence.mjs +464 -0
- graphitect/_vendor/archify/renderers/shared/brand-marks.mjs +563 -0
- graphitect/_vendor/archify/renderers/shared/cli.mjs +218 -0
- graphitect/_vendor/archify/renderers/shared/desktop-readability.mjs +26 -0
- graphitect/_vendor/archify/renderers/shared/diagnostics.mjs +127 -0
- graphitect/_vendor/archify/renderers/shared/engineering-profiles.mjs +157 -0
- graphitect/_vendor/archify/renderers/shared/generated-brand-marks.mjs +2003 -0
- graphitect/_vendor/archify/renderers/shared/generated-validators.mjs +13 -0
- graphitect/_vendor/archify/renderers/shared/geometry.mjs +1423 -0
- graphitect/_vendor/archify/renderers/shared/i18n.mjs +595 -0
- graphitect/_vendor/archify/renderers/shared/layout-report.mjs +40 -0
- graphitect/_vendor/archify/renderers/shared/legend.mjs +217 -0
- graphitect/_vendor/archify/renderers/shared/output-path.mjs +340 -0
- graphitect/_vendor/archify/renderers/shared/repository-evidence.mjs +238 -0
- graphitect/_vendor/archify/renderers/shared/repository-location.mjs +58 -0
- graphitect/_vendor/archify/renderers/shared/text-fit.mjs +49 -0
- graphitect/_vendor/archify/renderers/shared/utils.mjs +232 -0
- graphitect/_vendor/archify/renderers/shared/validator.mjs +86 -0
- graphitect/_vendor/archify/renderers/workflow/README.md +223 -0
- graphitect/_vendor/archify/renderers/workflow/render-workflow.mjs +35 -0
- graphitect/_vendor/archify/renderers/workflow/workflow-compiler.mjs +4400 -0
- graphitect/_vendor/archify/renderers/workflow/workflow-migration-geometry.mjs +144 -0
- graphitect/_vendor/archify/schemas/README.md +211 -0
- graphitect/_vendor/archify/schemas/architecture.schema.json +178 -0
- graphitect/_vendor/archify/schemas/common.schema.json +115 -0
- graphitect/_vendor/archify/schemas/dataflow.schema.json +243 -0
- graphitect/_vendor/archify/schemas/lifecycle.schema.json +266 -0
- graphitect/_vendor/archify/schemas/sequence.schema.json +223 -0
- graphitect/_vendor/archify/schemas/workflow.schema.json +428 -0
- graphitect/_vendor/archify/scripts/check-render-output.mjs +836 -0
- graphitect/_vendor/archify/scripts/check-update.mjs +1667 -0
- graphitect/_vendor/archify/scripts/generate-brand-marks.mjs +141 -0
- graphitect/_vendor/archify/scripts/generate-validators.mjs +66 -0
- graphitect/_vendor/archify/scripts/render-examples.mjs +26 -0
- graphitect/_vendor/archify/scripts/update-contract.mjs +182 -0
- graphitect/_vendor/archify/skill-release.json +10 -0
- graphitect/cli.py +981 -0
- graphitect/deliver/__init__.py +5 -0
- graphitect/deliver/archify_adapter.py +1877 -0
- graphitect/deliver/archify_ir.py +160 -0
- graphitect/deliver/archify_repair.py +135 -0
- graphitect/deliver/doc_compiler.py +916 -0
- graphitect/ground/__init__.py +5 -0
- graphitect/ground/describe_source.py +27 -0
- graphitect/ground/fullread_source.py +56 -0
- graphitect/ground/graphify_source.py +107 -0
- graphitect/models.py +118 -0
- graphitect/skill/SKILL.md +80 -0
- graphitect/skill/agents/openai.yaml +4 -0
- graphitect/synthesize/__init__.py +5 -0
- graphitect/synthesize/engine.py +281 -0
- graphitect/synthesize/llm_backend.py +331 -0
- graphitect/synthesize/questions.py +139 -0
- graphitect/synthesize/rubric.py +104 -0
- graphitect-0.2.0.dist-info/METADATA +284 -0
- graphitect-0.2.0.dist-info/RECORD +336 -0
- graphitect-0.2.0.dist-info/WHEEL +5 -0
- graphitect-0.2.0.dist-info/entry_points.txt +2 -0
- graphitect-0.2.0.dist-info/licenses/LICENSE +21 -0
- graphitect-0.2.0.dist-info/licenses/LICENSE-ARCHIFY-MIT +22 -0
- graphitect-0.2.0.dist-info/licenses/LICENSE-GRAPHIFY-APACHE-2.0 +202 -0
- graphitect-0.2.0.dist-info/licenses/LICENSE-GRAPHIFY-MIT +21 -0
- graphitect-0.2.0.dist-info/licenses/NOTICE-ARCHIFY-THIRD-PARTY.md +69 -0
- graphitect-0.2.0.dist-info/licenses/NOTICE-GRAPHIFY +8 -0
- graphitect-0.2.0.dist-info/top_level.txt +2 -0
|
@@ -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,66 @@
|
|
|
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'];
|
|
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
|
+
const generated = `${banner}${validatorCode}\n`;
|
|
52
|
+
|
|
53
|
+
if (process.argv.includes('--check')) {
|
|
54
|
+
const current = fs.existsSync(output)
|
|
55
|
+
? fs.readFileSync(output, 'utf8').replace(/\r\n?/g, '\n')
|
|
56
|
+
: '';
|
|
57
|
+
if (current !== generated) {
|
|
58
|
+
console.error('generated validators are stale — run npm run generate:validators');
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
} else {
|
|
62
|
+
const temporary = `${output}.${process.pid}.tmp`;
|
|
63
|
+
fs.writeFileSync(temporary, generated);
|
|
64
|
+
fs.renameSync(temporary, output);
|
|
65
|
+
console.log(`generated ${path.relative(root, output)}`);
|
|
66
|
+
}
|
|
@@ -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
|
+
}
|