@laitszkin/apollo-toolkit 3.10.0 → 3.11.0
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/CHANGELOG.md +20 -0
- package/analyse-app-logs/scripts/__pycache__/filter_logs_by_time.cpython-312.pyc +0 -0
- package/analyse-app-logs/scripts/__pycache__/log_cli_utils.cpython-312.pyc +0 -0
- package/analyse-app-logs/scripts/__pycache__/search_logs.cpython-312.pyc +0 -0
- package/docs-to-voice/scripts/__pycache__/docs_to_voice.cpython-312.pyc +0 -0
- package/generate-spec/SKILL.md +17 -15
- package/generate-spec/agents/openai.yaml +1 -1
- package/generate-spec/references/TEMPLATE_SPEC.md +103 -84
- package/generate-spec/scripts/__pycache__/create-specscpython-312.pyc +0 -0
- package/init-project-html/SKILL.md +82 -126
- package/init-project-html/agents/openai.yaml +17 -8
- package/init-project-html/lib/atlas/assets/architecture.css +140 -0
- package/init-project-html/lib/atlas/assets/viewer.client.js +93 -0
- package/init-project-html/lib/atlas/cli.js +995 -0
- package/init-project-html/lib/atlas/layout.js +229 -0
- package/init-project-html/lib/atlas/render.js +485 -0
- package/init-project-html/lib/atlas/schema.js +310 -0
- package/init-project-html/lib/atlas/state.js +402 -0
- package/init-project-html/references/TEMPLATE_SPEC.md +123 -84
- package/init-project-html/sample-demo/resources/project-architecture/assets/architecture.css +139 -1058
- package/init-project-html/sample-demo/resources/project-architecture/assets/viewer.client.js +93 -0
- package/init-project-html/sample-demo/resources/project-architecture/atlas/atlas.index.yaml +34 -0
- package/init-project-html/sample-demo/resources/project-architecture/atlas/features/get-invite-codes.yaml +159 -0
- package/init-project-html/sample-demo/resources/project-architecture/atlas/features/invite-code-registration.yaml +160 -0
- package/init-project-html/sample-demo/resources/project-architecture/features/get-invite-codes/index.html +67 -52
- package/init-project-html/sample-demo/resources/project-architecture/features/get-invite-codes/invite-code-generator.html +48 -163
- package/init-project-html/sample-demo/resources/project-architecture/features/get-invite-codes/invite-issuance-service.html +70 -196
- package/init-project-html/sample-demo/resources/project-architecture/features/get-invite-codes/postgresql.html +64 -163
- package/init-project-html/sample-demo/resources/project-architecture/features/get-invite-codes/public-api.html +68 -150
- package/init-project-html/sample-demo/resources/project-architecture/features/get-invite-codes/web-get-invite-ui.html +65 -138
- package/init-project-html/sample-demo/resources/project-architecture/features/invite-code-registration/index.html +61 -51
- package/init-project-html/sample-demo/resources/project-architecture/features/invite-code-registration/postgresql.html +66 -159
- package/init-project-html/sample-demo/resources/project-architecture/features/invite-code-registration/public-api.html +63 -143
- package/init-project-html/sample-demo/resources/project-architecture/features/invite-code-registration/registration-service.html +77 -188
- package/init-project-html/sample-demo/resources/project-architecture/features/invite-code-registration/web-register-ui.html +65 -138
- package/init-project-html/sample-demo/resources/project-architecture/index.html +232 -335
- package/init-project-html/scripts/architecture.js +65 -247
- package/katex/scripts/__pycache__/render_katex.cpython-312.pyc +0 -0
- package/open-github-issue/scripts/__pycache__/open_github_issue.cpython-312.pyc +0 -0
- package/package.json +6 -2
- package/read-github-issue/scripts/__pycache__/find_issues.cpython-312.pyc +0 -0
- package/read-github-issue/scripts/__pycache__/read_issue.cpython-312.pyc +0 -0
- package/resolve-review-comments/scripts/__pycache__/review_threads.cpython-312.pyc +0 -0
- package/spec-to-project-html/SKILL.md +61 -63
- package/spec-to-project-html/agents/openai.yaml +14 -8
- package/spec-to-project-html/references/TEMPLATE_SPEC.md +96 -83
- package/text-to-short-video/scripts/__pycache__/enforce_video_aspect_ratio.cpython-312.pyc +0 -0
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// architecture.js —
|
|
3
|
-
// a paginated before/after diff viewer from every active spec's
|
|
4
|
-
// architecture_diff/ directory under docs/plans/.
|
|
2
|
+
// architecture.js — thin shim over lib/atlas/cli.js.
|
|
5
3
|
//
|
|
6
|
-
//
|
|
7
|
-
// architecture.js
|
|
4
|
+
// Backward-compatible legacy entrypoint:
|
|
5
|
+
// architecture.js # same as `open`
|
|
8
6
|
// architecture.js open [--project <root>] [--no-open]
|
|
9
7
|
// architecture.js diff [--project <root>] [--out <dir>] [--no-open]
|
|
10
|
-
//
|
|
8
|
+
//
|
|
9
|
+
// All new declarative verbs (feature add, submodule add, function add,
|
|
10
|
+
// variable add, dataflow add|remove|reorder, error add, edge add, meta
|
|
11
|
+
// set, actor add, render, validate, undo) are routed through
|
|
12
|
+
// lib/atlas/cli.js, which owns layout, no-overlap, DOM, CSS, and pan/zoom.
|
|
11
13
|
|
|
12
14
|
'use strict';
|
|
13
15
|
|
|
@@ -15,25 +17,41 @@ const fs = require('node:fs');
|
|
|
15
17
|
const path = require('node:path');
|
|
16
18
|
const { spawn } = require('node:child_process');
|
|
17
19
|
|
|
20
|
+
const newCli = require('../lib/atlas/cli');
|
|
21
|
+
|
|
18
22
|
const ATLAS_REL = path.join('resources', 'project-architecture', 'index.html');
|
|
19
23
|
const RESOURCES_REL = path.join('resources', 'project-architecture');
|
|
20
24
|
const PLANS_REL = path.join('docs', 'plans');
|
|
21
25
|
const DIFF_DIRNAME = 'architecture_diff';
|
|
22
26
|
const REMOVED_FILE = '_removed.txt';
|
|
27
|
+
const ATLAS_DIRNAME = 'atlas';
|
|
23
28
|
const DEFAULT_OUT_REL = path.join('.apollo-toolkit', 'architecture-diff');
|
|
24
29
|
|
|
25
|
-
const
|
|
30
|
+
const LEGACY_VERBS = new Set(['open', 'diff']);
|
|
26
31
|
|
|
27
|
-
|
|
28
|
-
apltk architecture Open resources/project-architecture/index.html
|
|
29
|
-
apltk architecture open Same as above
|
|
30
|
-
apltk architecture diff Render every architecture_diff/ as one paginated viewer
|
|
31
|
-
apltk architecture --help Show this help
|
|
32
|
+
const USAGE = `apltk architecture — declarative atlas CLI.
|
|
32
33
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
Usage:
|
|
35
|
+
apltk architecture Open resources/project-architecture/index.html
|
|
36
|
+
apltk architecture open Same as above
|
|
37
|
+
apltk architecture diff Render every architecture_diff/ as one paginated viewer
|
|
38
|
+
apltk architecture render Regenerate atlas HTML from current YAML state
|
|
39
|
+
apltk architecture validate Run schema + referential checks
|
|
40
|
+
apltk architecture feature add|set|remove Manage feature modules
|
|
41
|
+
apltk architecture submodule add|set|remove Manage sub-modules
|
|
42
|
+
apltk architecture function|variable|dataflow|error|edge add|remove
|
|
43
|
+
Manage component rows and edges
|
|
44
|
+
apltk architecture meta set Update meta.title / meta.summary
|
|
45
|
+
apltk architecture actor add|remove Manage top-level actors
|
|
46
|
+
apltk architecture undo Revert the most recent mutation
|
|
47
|
+
apltk architecture --help Show this help
|
|
48
|
+
|
|
49
|
+
Global flags:
|
|
50
|
+
--project <root> Project root (default: nearest ancestor with resources/project-architecture/)
|
|
51
|
+
--spec <spec_dir> Mutations write to <spec_dir>/architecture_diff/atlas/
|
|
52
|
+
--no-render Skip auto-render after a mutation
|
|
53
|
+
--no-open For open/diff: skip launching the browser
|
|
54
|
+
--out <dir> For diff: override viewer output directory
|
|
37
55
|
-h, --help Show this help`;
|
|
38
56
|
|
|
39
57
|
function parseArgs(argv) {
|
|
@@ -80,6 +98,7 @@ function findProjectRoot(startDir) {
|
|
|
80
98
|
let dir = path.resolve(startDir);
|
|
81
99
|
while (true) {
|
|
82
100
|
if (fs.existsSync(path.join(dir, ATLAS_REL))) return dir;
|
|
101
|
+
if (fs.existsSync(path.join(dir, RESOURCES_REL, ATLAS_DIRNAME, 'atlas.index.yaml'))) return dir;
|
|
83
102
|
const parent = path.dirname(dir);
|
|
84
103
|
if (parent === dir) return null;
|
|
85
104
|
dir = parent;
|
|
@@ -90,44 +109,27 @@ function openInBrowser(filePath) {
|
|
|
90
109
|
const platform = process.platform;
|
|
91
110
|
let command;
|
|
92
111
|
let args;
|
|
93
|
-
if (platform === 'darwin') {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
} else if (platform === 'win32') {
|
|
97
|
-
command = 'cmd';
|
|
98
|
-
args = ['/c', 'start', '""', filePath];
|
|
99
|
-
} else {
|
|
100
|
-
command = 'xdg-open';
|
|
101
|
-
args = [filePath];
|
|
102
|
-
}
|
|
112
|
+
if (platform === 'darwin') { command = 'open'; args = [filePath]; }
|
|
113
|
+
else if (platform === 'win32') { command = 'cmd'; args = ['/c', 'start', '""', filePath]; }
|
|
114
|
+
else { command = 'xdg-open'; args = [filePath]; }
|
|
103
115
|
try {
|
|
104
116
|
const child = spawn(command, args, { stdio: 'ignore', detached: true });
|
|
105
|
-
child.on('error', () => {
|
|
117
|
+
child.on('error', () => {});
|
|
106
118
|
child.unref();
|
|
107
|
-
} catch (
|
|
108
|
-
/* best effort */
|
|
109
|
-
}
|
|
119
|
+
} catch (_e) { /* best effort */ }
|
|
110
120
|
}
|
|
111
121
|
|
|
112
122
|
function walkArchitectureDiffDirs(plansRoot) {
|
|
113
123
|
const result = [];
|
|
114
124
|
if (!fs.existsSync(plansRoot)) return result;
|
|
115
|
-
|
|
116
125
|
function recurse(dir) {
|
|
117
126
|
let entries;
|
|
118
|
-
try {
|
|
119
|
-
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
120
|
-
} catch (_err) {
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
127
|
+
try { entries = fs.readdirSync(dir, { withFileTypes: true }); } catch (_e) { return; }
|
|
123
128
|
for (const entry of entries) {
|
|
124
129
|
if (!entry.isDirectory()) continue;
|
|
125
130
|
if (entry.name === 'node_modules' || entry.name.startsWith('.')) continue;
|
|
126
131
|
const full = path.join(dir, entry.name);
|
|
127
|
-
if (entry.name === DIFF_DIRNAME) {
|
|
128
|
-
result.push(full);
|
|
129
|
-
continue;
|
|
130
|
-
}
|
|
132
|
+
if (entry.name === DIFF_DIRNAME) { result.push(full); continue; }
|
|
131
133
|
recurse(full);
|
|
132
134
|
}
|
|
133
135
|
}
|
|
@@ -139,20 +141,16 @@ function walkAfterStateHtml(diffDir) {
|
|
|
139
141
|
const out = [];
|
|
140
142
|
function recurse(dir, relParts) {
|
|
141
143
|
let entries;
|
|
142
|
-
try {
|
|
143
|
-
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
144
|
-
} catch (_err) {
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
144
|
+
try { entries = fs.readdirSync(dir, { withFileTypes: true }); } catch (_e) { return; }
|
|
147
145
|
for (const entry of entries) {
|
|
148
146
|
if (entry.name === 'assets') continue;
|
|
147
|
+
if (entry.name === ATLAS_DIRNAME) continue;
|
|
149
148
|
if (entry.name === REMOVED_FILE) continue;
|
|
150
149
|
if (entry.name.startsWith('.')) continue;
|
|
151
150
|
const full = path.join(dir, entry.name);
|
|
152
151
|
const nextRel = [...relParts, entry.name];
|
|
153
|
-
if (entry.isDirectory())
|
|
154
|
-
|
|
155
|
-
} else if (entry.isFile() && entry.name.toLowerCase().endsWith('.html')) {
|
|
152
|
+
if (entry.isDirectory()) recurse(full, nextRel);
|
|
153
|
+
else if (entry.isFile() && entry.name.toLowerCase().endsWith('.html')) {
|
|
156
154
|
out.push({ abs: full, rel: nextRel.join('/') });
|
|
157
155
|
}
|
|
158
156
|
}
|
|
@@ -179,7 +177,6 @@ function collectChanges(projectRoot) {
|
|
|
179
177
|
for (const diffDir of diffDirs) {
|
|
180
178
|
const specDir = path.dirname(diffDir);
|
|
181
179
|
const specLabel = path.relative(projectRoot, specDir);
|
|
182
|
-
|
|
183
180
|
for (const after of walkAfterStateHtml(diffDir)) {
|
|
184
181
|
const beforeAbs = path.join(resourcesRoot, after.rel);
|
|
185
182
|
const beforeExists = fs.existsSync(beforeAbs);
|
|
@@ -191,7 +188,6 @@ function collectChanges(projectRoot) {
|
|
|
191
188
|
afterPath: path.relative(projectRoot, after.abs),
|
|
192
189
|
});
|
|
193
190
|
}
|
|
194
|
-
|
|
195
191
|
for (const removedRel of readRemovedManifest(diffDir)) {
|
|
196
192
|
const beforeAbs = path.join(resourcesRoot, removedRel);
|
|
197
193
|
if (!fs.existsSync(beforeAbs)) continue;
|
|
@@ -210,19 +206,9 @@ function collectChanges(projectRoot) {
|
|
|
210
206
|
if (a.kind !== b.kind) return a.kind.localeCompare(b.kind);
|
|
211
207
|
return a.rel.localeCompare(b.rel);
|
|
212
208
|
});
|
|
213
|
-
|
|
214
209
|
return changes;
|
|
215
210
|
}
|
|
216
211
|
|
|
217
|
-
function htmlEscape(value) {
|
|
218
|
-
return String(value)
|
|
219
|
-
.replace(/&/g, '&')
|
|
220
|
-
.replace(/</g, '<')
|
|
221
|
-
.replace(/>/g, '>')
|
|
222
|
-
.replace(/"/g, '"')
|
|
223
|
-
.replace(/'/g, ''');
|
|
224
|
-
}
|
|
225
|
-
|
|
226
212
|
function toViewerRel(outDir, projectRoot, projectRelPath) {
|
|
227
213
|
if (!projectRelPath) return null;
|
|
228
214
|
const absolute = path.resolve(projectRoot, projectRelPath);
|
|
@@ -231,190 +217,7 @@ function toViewerRel(outDir, projectRoot, projectRelPath) {
|
|
|
231
217
|
}
|
|
232
218
|
|
|
233
219
|
function renderViewer({ changes, projectRoot, outDir }) {
|
|
234
|
-
|
|
235
|
-
kind: change.kind,
|
|
236
|
-
rel: change.rel,
|
|
237
|
-
spec: change.spec,
|
|
238
|
-
beforeSrc: toViewerRel(outDir, projectRoot, change.beforePath),
|
|
239
|
-
afterSrc: toViewerRel(outDir, projectRoot, change.afterPath),
|
|
240
|
-
}));
|
|
241
|
-
|
|
242
|
-
const summary = {
|
|
243
|
-
total: pages.length,
|
|
244
|
-
modified: pages.filter((p) => p.kind === 'modified').length,
|
|
245
|
-
added: pages.filter((p) => p.kind === 'added').length,
|
|
246
|
-
removed: pages.filter((p) => p.kind === 'removed').length,
|
|
247
|
-
projectRoot,
|
|
248
|
-
};
|
|
249
|
-
|
|
250
|
-
const payload = JSON.stringify({ pages, summary });
|
|
251
|
-
|
|
252
|
-
return `<!DOCTYPE html>
|
|
253
|
-
<html lang="en" data-atlas="diff-viewer">
|
|
254
|
-
<head>
|
|
255
|
-
<meta charset="utf-8">
|
|
256
|
-
<title>Architecture diff — ${htmlEscape(path.basename(projectRoot))}</title>
|
|
257
|
-
<style>
|
|
258
|
-
:root {
|
|
259
|
-
color-scheme: light dark;
|
|
260
|
-
--bg: #0f172a;
|
|
261
|
-
--panel: #1e293b;
|
|
262
|
-
--text: #e2e8f0;
|
|
263
|
-
--muted: #94a3b8;
|
|
264
|
-
--accent: #38bdf8;
|
|
265
|
-
--added: #4ade80;
|
|
266
|
-
--removed: #f87171;
|
|
267
|
-
--modified: #facc15;
|
|
268
|
-
}
|
|
269
|
-
* { box-sizing: border-box; }
|
|
270
|
-
html, body { height: 100%; margin: 0; font-family: ui-sans-serif, system-ui, sans-serif; background: var(--bg); color: var(--text); }
|
|
271
|
-
body { display: flex; flex-direction: column; min-height: 100vh; }
|
|
272
|
-
header { padding: 12px 20px; background: var(--panel); border-bottom: 1px solid #334155; display: flex; flex-wrap: wrap; gap: 12px; align-items: center; justify-content: space-between; }
|
|
273
|
-
header .title { font-size: 14px; color: var(--muted); }
|
|
274
|
-
header .title strong { color: var(--text); }
|
|
275
|
-
header .summary { display: flex; gap: 12px; font-size: 12px; color: var(--muted); }
|
|
276
|
-
header .summary span.count { font-weight: 600; }
|
|
277
|
-
header .summary .modified { color: var(--modified); }
|
|
278
|
-
header .summary .added { color: var(--added); }
|
|
279
|
-
header .summary .removed { color: var(--removed); }
|
|
280
|
-
main { flex: 1; display: flex; flex-direction: column; }
|
|
281
|
-
.meta { padding: 10px 20px; background: var(--bg); border-bottom: 1px solid #334155; display: flex; flex-wrap: wrap; gap: 16px; align-items: center; justify-content: space-between; font-size: 13px; }
|
|
282
|
-
.meta .left { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
|
|
283
|
-
.badge { display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; border: 1px solid currentColor; }
|
|
284
|
-
.badge.modified { color: var(--modified); }
|
|
285
|
-
.badge.added { color: var(--added); }
|
|
286
|
-
.badge.removed { color: var(--removed); }
|
|
287
|
-
.path { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; color: var(--text); }
|
|
288
|
-
.spec { color: var(--muted); font-size: 12px; }
|
|
289
|
-
.nav { display: flex; align-items: center; gap: 8px; }
|
|
290
|
-
.nav button { background: transparent; color: var(--text); border: 1px solid #475569; padding: 6px 12px; border-radius: 6px; cursor: pointer; font-size: 13px; }
|
|
291
|
-
.nav button:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
|
|
292
|
-
.nav button:disabled { opacity: 0.4; cursor: not-allowed; }
|
|
293
|
-
.nav .counter { font-variant-numeric: tabular-nums; color: var(--muted); min-width: 72px; text-align: center; }
|
|
294
|
-
.frames { flex: 1; display: grid; gap: 1px; background: #334155; padding: 1px; min-height: 0; }
|
|
295
|
-
.frames.split { grid-template-columns: 1fr 1fr; }
|
|
296
|
-
.frames.single { grid-template-columns: 1fr; }
|
|
297
|
-
.pane { background: #ffffff; display: flex; flex-direction: column; min-height: 0; }
|
|
298
|
-
.pane h2 { margin: 0; padding: 8px 14px; font-size: 12px; text-transform: uppercase; letter-spacing: 0.08em; background: #f1f5f9; color: #1e293b; border-bottom: 1px solid #cbd5f5; display: flex; align-items: center; gap: 8px; }
|
|
299
|
-
.pane h2 .side-badge { font-size: 10px; padding: 1px 6px; border-radius: 4px; background: #cbd5f5; color: #1e293b; }
|
|
300
|
-
.pane h2.before .side-badge { background: #fee2e2; color: #991b1b; }
|
|
301
|
-
.pane h2.after .side-badge { background: #dcfce7; color: #166534; }
|
|
302
|
-
.pane iframe { flex: 1; width: 100%; border: 0; background: #ffffff; }
|
|
303
|
-
.empty { display: flex; align-items: center; justify-content: center; padding: 32px; font-size: 14px; color: var(--muted); }
|
|
304
|
-
footer { padding: 8px 20px; background: var(--panel); border-top: 1px solid #334155; font-size: 12px; color: var(--muted); }
|
|
305
|
-
footer kbd { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; background: #0f172a; padding: 1px 6px; border-radius: 4px; border: 1px solid #475569; }
|
|
306
|
-
</style>
|
|
307
|
-
</head>
|
|
308
|
-
<body>
|
|
309
|
-
<header>
|
|
310
|
-
<div class="title">Apollo Toolkit · <strong>architecture diff</strong> · ${htmlEscape(path.basename(projectRoot))}</div>
|
|
311
|
-
<div class="summary">
|
|
312
|
-
<span><span class="count">${summary.total}</span> change<span>${summary.total === 1 ? '' : 's'}</span></span>
|
|
313
|
-
<span class="modified"><span class="count">${summary.modified}</span> modified</span>
|
|
314
|
-
<span class="added"><span class="count">${summary.added}</span> added</span>
|
|
315
|
-
<span class="removed"><span class="count">${summary.removed}</span> removed</span>
|
|
316
|
-
</div>
|
|
317
|
-
</header>
|
|
318
|
-
<main>
|
|
319
|
-
<div class="meta">
|
|
320
|
-
<div class="left">
|
|
321
|
-
<span id="badge" class="badge modified">modified</span>
|
|
322
|
-
<span class="path" id="path">—</span>
|
|
323
|
-
<span class="spec" id="spec">—</span>
|
|
324
|
-
</div>
|
|
325
|
-
<div class="nav">
|
|
326
|
-
<button id="prev" type="button" aria-label="Previous change">← Prev</button>
|
|
327
|
-
<span class="counter" id="counter">0 / 0</span>
|
|
328
|
-
<button id="next" type="button" aria-label="Next change">Next →</button>
|
|
329
|
-
</div>
|
|
330
|
-
</div>
|
|
331
|
-
<div class="frames" id="frames">
|
|
332
|
-
<div class="empty" id="empty">No architecture diffs found under docs/plans/**/architecture_diff/.</div>
|
|
333
|
-
</div>
|
|
334
|
-
</main>
|
|
335
|
-
<footer>
|
|
336
|
-
Navigate with <kbd>←</kbd> / <kbd>→</kbd> or the buttons above. Each page pairs the current atlas (left) with the proposed-after HTML (right) for one affected page.
|
|
337
|
-
</footer>
|
|
338
|
-
<script id="__diff_payload" type="application/json">${payload.replace(/</g, '\\u003c')}</script>
|
|
339
|
-
<script>
|
|
340
|
-
(function () {
|
|
341
|
-
const data = JSON.parse(document.getElementById('__diff_payload').textContent);
|
|
342
|
-
const pages = data.pages || [];
|
|
343
|
-
const framesEl = document.getElementById('frames');
|
|
344
|
-
const emptyEl = document.getElementById('empty');
|
|
345
|
-
const badgeEl = document.getElementById('badge');
|
|
346
|
-
const pathEl = document.getElementById('path');
|
|
347
|
-
const specEl = document.getElementById('spec');
|
|
348
|
-
const counterEl = document.getElementById('counter');
|
|
349
|
-
const prevBtn = document.getElementById('prev');
|
|
350
|
-
const nextBtn = document.getElementById('next');
|
|
351
|
-
|
|
352
|
-
if (pages.length === 0) {
|
|
353
|
-
counterEl.textContent = '0 / 0';
|
|
354
|
-
prevBtn.disabled = true;
|
|
355
|
-
nextBtn.disabled = true;
|
|
356
|
-
return;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
let index = 0;
|
|
360
|
-
|
|
361
|
-
function render() {
|
|
362
|
-
const page = pages[index];
|
|
363
|
-
badgeEl.className = 'badge ' + page.kind;
|
|
364
|
-
badgeEl.textContent = page.kind;
|
|
365
|
-
pathEl.textContent = page.rel;
|
|
366
|
-
specEl.textContent = page.spec;
|
|
367
|
-
counterEl.textContent = (index + 1) + ' / ' + pages.length;
|
|
368
|
-
prevBtn.disabled = index === 0;
|
|
369
|
-
nextBtn.disabled = index === pages.length - 1;
|
|
370
|
-
|
|
371
|
-
framesEl.innerHTML = '';
|
|
372
|
-
if (page.kind === 'modified') {
|
|
373
|
-
framesEl.className = 'frames split';
|
|
374
|
-
framesEl.appendChild(buildPane('Before', page.beforeSrc, 'before'));
|
|
375
|
-
framesEl.appendChild(buildPane('After', page.afterSrc, 'after'));
|
|
376
|
-
} else if (page.kind === 'added') {
|
|
377
|
-
framesEl.className = 'frames single';
|
|
378
|
-
framesEl.appendChild(buildPane('After (new)', page.afterSrc, 'after'));
|
|
379
|
-
} else if (page.kind === 'removed') {
|
|
380
|
-
framesEl.className = 'frames single';
|
|
381
|
-
framesEl.appendChild(buildPane('Before (removed)', page.beforeSrc, 'before'));
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
function buildPane(label, src, side) {
|
|
386
|
-
const pane = document.createElement('div');
|
|
387
|
-
pane.className = 'pane';
|
|
388
|
-
const heading = document.createElement('h2');
|
|
389
|
-
heading.className = side;
|
|
390
|
-
const sideBadge = document.createElement('span');
|
|
391
|
-
sideBadge.className = 'side-badge';
|
|
392
|
-
sideBadge.textContent = side;
|
|
393
|
-
heading.appendChild(sideBadge);
|
|
394
|
-
heading.appendChild(document.createTextNode(' ' + label));
|
|
395
|
-
pane.appendChild(heading);
|
|
396
|
-
const frame = document.createElement('iframe');
|
|
397
|
-
frame.src = src;
|
|
398
|
-
frame.loading = 'lazy';
|
|
399
|
-
frame.title = label;
|
|
400
|
-
pane.appendChild(frame);
|
|
401
|
-
return pane;
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
prevBtn.addEventListener('click', () => { if (index > 0) { index--; render(); } });
|
|
405
|
-
nextBtn.addEventListener('click', () => { if (index < pages.length - 1) { index++; render(); } });
|
|
406
|
-
document.addEventListener('keydown', (event) => {
|
|
407
|
-
if (event.key === 'ArrowLeft') { prevBtn.click(); }
|
|
408
|
-
else if (event.key === 'ArrowRight') { nextBtn.click(); }
|
|
409
|
-
});
|
|
410
|
-
|
|
411
|
-
emptyEl.remove();
|
|
412
|
-
render();
|
|
413
|
-
})();
|
|
414
|
-
</script>
|
|
415
|
-
</body>
|
|
416
|
-
</html>
|
|
417
|
-
`;
|
|
220
|
+
return newCli.renderDiffViewer({ changes, projectRoot, outDir });
|
|
418
221
|
}
|
|
419
222
|
|
|
420
223
|
function runOpen(opts, io) {
|
|
@@ -443,7 +246,6 @@ function runDiff(opts, io) {
|
|
|
443
246
|
);
|
|
444
247
|
return 1;
|
|
445
248
|
}
|
|
446
|
-
|
|
447
249
|
const outDir = opts.out || path.join(projectRoot, DEFAULT_OUT_REL);
|
|
448
250
|
fs.mkdirSync(outDir, { recursive: true });
|
|
449
251
|
|
|
@@ -460,6 +262,9 @@ function runDiff(opts, io) {
|
|
|
460
262
|
return 0;
|
|
461
263
|
}
|
|
462
264
|
|
|
265
|
+
// main(argv, io) is sync and supports the legacy verbs `open` and
|
|
266
|
+
// `diff` only. Tests rely on the sync return-code contract. All other
|
|
267
|
+
// verbs go through dispatchAsync().
|
|
463
268
|
function main(argv, io = { stdout: process.stdout, stderr: process.stderr }) {
|
|
464
269
|
let opts;
|
|
465
270
|
try {
|
|
@@ -478,9 +283,21 @@ function main(argv, io = { stdout: process.stdout, stderr: process.stderr }) {
|
|
|
478
283
|
return 1;
|
|
479
284
|
}
|
|
480
285
|
|
|
286
|
+
async function dispatchAsync(argv, io = { stdout: process.stdout, stderr: process.stderr }) {
|
|
287
|
+
return newCli.dispatch(argv, io);
|
|
288
|
+
}
|
|
289
|
+
|
|
481
290
|
if (require.main === module) {
|
|
482
|
-
const
|
|
483
|
-
|
|
291
|
+
const argv = process.argv.slice(2);
|
|
292
|
+
const verb = argv[0];
|
|
293
|
+
if (!verb || verb.startsWith('-') || LEGACY_VERBS.has(verb)) {
|
|
294
|
+
process.exit(main(argv));
|
|
295
|
+
} else {
|
|
296
|
+
dispatchAsync(argv).then((code) => process.exit(code)).catch((err) => {
|
|
297
|
+
process.stderr.write(`${err && err.stack ? err.stack : err}\n`);
|
|
298
|
+
process.exit(1);
|
|
299
|
+
});
|
|
300
|
+
}
|
|
484
301
|
}
|
|
485
302
|
|
|
486
303
|
module.exports = {
|
|
@@ -493,4 +310,5 @@ module.exports = {
|
|
|
493
310
|
walkAfterStateHtml,
|
|
494
311
|
readRemovedManifest,
|
|
495
312
|
main,
|
|
313
|
+
dispatchAsync,
|
|
496
314
|
};
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@laitszkin/apollo-toolkit",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.11.0",
|
|
4
4
|
"description": "Apollo Toolkit npm installer for managed skill copying across Codex, OpenClaw, and Trae.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "LaiTszKin",
|
|
@@ -33,5 +33,9 @@
|
|
|
33
33
|
"skills",
|
|
34
34
|
"openclaw",
|
|
35
35
|
"trae"
|
|
36
|
-
]
|
|
36
|
+
],
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"elkjs": "^0.11.1",
|
|
39
|
+
"js-yaml": "^4.1.1"
|
|
40
|
+
}
|
|
37
41
|
}
|
|
Binary file
|
|
Binary file
|