@galda/cli 0.10.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.
Files changed (34) hide show
  1. package/CLAUDE.md +44 -0
  2. package/README.md +83 -0
  3. package/app/fonts.css +8 -0
  4. package/app/index.html +7638 -0
  5. package/app/theme.css +126 -0
  6. package/app/wp/w1.jpg +0 -0
  7. package/app/wp/w2.jpg +0 -0
  8. package/bin/manager-for-ai.mjs +76 -0
  9. package/engine/lib.mjs +2378 -0
  10. package/engine/manager.mjs +115 -0
  11. package/engine/mcp.mjs +123 -0
  12. package/engine/pr.mjs +144 -0
  13. package/engine/relay-client.mjs +82 -0
  14. package/engine/server.mjs +3315 -0
  15. package/engine/verify.mjs +158 -0
  16. package/examples/task-001/runs/2026-07-03T06-23-57-441Z/attempt-1-proof.png +0 -0
  17. package/examples/task-001/runs/2026-07-03T06-23-57-441Z/report.json +20 -0
  18. package/examples/task-001/runs/2026-07-03T06-29-54-517Z/attempt-1-proof.png +0 -0
  19. package/examples/task-001/runs/2026-07-03T06-29-54-517Z/report.json +20 -0
  20. package/examples/task-001/runs/2026-07-03T06-40-23-231Z/attempt-1-proof.png +0 -0
  21. package/examples/task-001/runs/2026-07-03T06-40-23-231Z/report.json +20 -0
  22. package/examples/task-001/runs/2026-07-03T07-34-58-109Z/attempt-1-proof.png +0 -0
  23. package/examples/task-001/runs/2026-07-03T07-34-58-109Z/report.json +21 -0
  24. package/examples/task-001/runs/2026-07-03T07-53-44-639Z/attempt-1-proof.png +0 -0
  25. package/examples/task-001/runs/2026-07-03T07-53-44-639Z/report.json +21 -0
  26. package/examples/task-001/runs/2026-07-03T08-02-12-117Z/attempt-1-proof.png +0 -0
  27. package/examples/task-001/runs/2026-07-03T08-02-12-117Z/report.json +21 -0
  28. package/examples/task-001/task.json +11 -0
  29. package/examples/task-001/verify.mjs +16 -0
  30. package/examples/toast-app/app.js +23 -0
  31. package/examples/toast-app/index.html +28 -0
  32. package/examples/toast-app/test/guard.test.mjs +83 -0
  33. package/examples/toast-app/test/style.test.mjs +19 -0
  34. package/package.json +52 -0
package/app/theme.css ADDED
@@ -0,0 +1,126 @@
1
+ /* ============================================================================
2
+ Agent Manager — DESIGN TOKENS & THEME (owned by the design/CDO role)
3
+ ----------------------------------------------------------------------------
4
+ This is the ONLY file the design role edits. Colors, fonts, shadows, spacing
5
+ scale, and the light/dark palette live here as CSS variables. Every color in
6
+ the app resolves through these tokens (no hard-coded colors in index.html), so
7
+ :root = W4 "white" default and body[data-theme="dark"] swaps the whole palette
8
+ (and the two fonts) with no per-rule overrides. --iri (the iridescent gradient)
9
+ is identical in both themes: it is the AI signature (logo + send), never a
10
+ general accent. Layout/structure CSS + HTML + JS live in index.html (impl role).
11
+ Source of truth: docs/design/DESIGN-RULES.md · layout: docs/ux-rework-handoff.md
12
+ ========================================================================== */
13
+ :root{
14
+ /* brand fonts FINAL (HANDOFF-v45 §1, Masa確定 2026-07-07): UI = Mona Sans,
15
+ mono = IBM Plex Mono — one stack for ALL themes (per-theme font overrides
16
+ removed: they shadowed the brand tokens and reverted the UI to Inter/SF). */
17
+ --ui:'Mona Sans',-apple-system,system-ui,sans-serif;
18
+ --mono:'IBM Plex Mono',ui-monospace,Menlo,monospace;
19
+ --canvas:#e9ebee; --paper:#ffffff; --panel:#ffffff; --surface:#ffffff; --surface2:#f0f2f5; --chip:#d7dbe1;
20
+ --ink:#1d1d1f; --ink2:#6e6e73; --ink3:#86868b;
21
+ --tint:20,23,31;
22
+ --hair:rgba(var(--tint),.10); --hair2:rgba(var(--tint),.16);
23
+ --glass:rgb(255 255 255 / .72);
24
+ --green-rgb:10,154,106; --blue-rgb:56,116,214; --amber-rgb:176,120,20; --danger-rgb:200,44,44;
25
+ --purple-rgb:150,90,220; --glow-rgb:120,150,230;
26
+ --green:rgb(var(--green-rgb)); --amber:rgb(var(--amber-rgb)); --blue:rgb(var(--blue-rgb)); --danger:rgb(var(--danger-rgb));
27
+ --iri:linear-gradient(112deg,#b794f6 0%,#7cc4ff 38%,#5ce0c0 72%,#ffd27a 100%);
28
+ --on-accent:#0a0a0b; --invink:#ffffff;
29
+ --send-bg:#1d1d1f; --send-ink:#ffffff;
30
+ --thumbbg:#dfe3e8; --dropline:#1d1d1f;
31
+ --media-btn:#222; --media-ink:#fff; --media-scrim:rgba(0,0,0,.55);
32
+ --errbg:rgb(253 237 237 / .96);
33
+ /* flagship surface tokens (DESIGN-RULES §1.5 layout port): row/control hover fill,
34
+ softer row hover, queue-tray inner surface. Values = flagship :root (W4). */
35
+ --hover:rgba(20,23,31,.05); --hover-s:rgba(20,23,31,.045); --surf:rgba(20,23,31,.025);
36
+ }
37
+ /* Theme 3 — Banff (DESIGN-RULES v3 §6.5): scene backdrop behind BLACK glass
38
+ panels, light ink. Faithful port of flagship internal body[data-theme=4]
39
+ (panel rgba(12,13,17,.72) / ink #ecebe5 / white hairlines / soft status hues).
40
+ The backdrop (__bg3 photos/dark scenes) + glass are structural (index.html). */
41
+ body[data-theme="banff"]{
42
+ --canvas:transparent; --paper:rgba(12,13,17,.78); --panel:rgba(12,13,17,.72); --surface:rgba(255,255,255,.06); --surface2:rgba(12,13,17,.5); --chip:rgba(255,255,255,.10);
43
+ --ink:#ecebe5; --ink2:#a9a59c; --ink3:#8b887f;
44
+ --tint:255,255,255;
45
+ --hair:rgba(var(--tint),.09); --hair2:rgba(var(--tint),.16);
46
+ --glass:rgba(12,13,17,.6);
47
+ --green-rgb:79,215,156; --blue-rgb:124,196,255; --amber-rgb:224,180,92; --danger-rgb:240,115,111;
48
+ --purple-rgb:183,148,246; --glow-rgb:146,180,255;
49
+ --green:rgb(var(--green-rgb)); --amber:rgb(var(--amber-rgb)); --blue:rgb(var(--blue-rgb)); --danger:rgb(var(--danger-rgb));
50
+ --on-accent:#0a0a0b; --invink:#0a0a0b;
51
+ --send-bg:#101014; --send-ink:#ffffff;
52
+ --thumbbg:#000; --dropline:#fff;
53
+ --media-btn:#222; --media-ink:#fff; --media-scrim:rgba(0,0,0,.55);
54
+ --errbg:rgba(60,30,30,.8);
55
+ /* flagship surface tokens — flagship internal T4 (black glass) values */
56
+ --hover:rgba(255,255,255,.06); --hover-s:rgba(255,255,255,.05); --surf:rgba(255,255,255,.04);
57
+ }
58
+ /* "dark" is the legacy palette (kept for old layouts only — NOT selectable, v3 §6.5) */
59
+ body[data-theme="dark"],body[data-theme="midnight"],body[data-theme="cinema"]{
60
+ --canvas:#0a0a0b; --paper:#0d0d0f; --panel:#09090a; --surface:#161619; --surface2:#08080a; --chip:#26262b;
61
+ --ink:#e9e7e2; --ink2:#a3a097; --ink3:#6b6862;
62
+ --tint:255,255,255;
63
+ --hair:rgba(var(--tint),.07); --hair2:rgba(var(--tint),.12);
64
+ --glass:rgba(22,22,27,.55);
65
+ --green-rgb:52,211,153; --blue-rgb:124,196,255; --amber-rgb:224,180,92; --danger-rgb:255,120,120;
66
+ --purple-rgb:183,148,246; --glow-rgb:146,180,255;
67
+ --on-accent:#0a0a0b; --invink:#0a0a0b;
68
+ --send-bg:var(--iri); --send-ink:#0a0a0b;
69
+ --thumbbg:#000; --dropline:#fff;
70
+ --errbg:rgba(60,30,30,.8);
71
+ /* flagship surface tokens — flagship internal T5/T6 (dark) values */
72
+ --hover:rgba(255,255,255,.06); --hover-s:rgba(255,255,255,.05); --surf:rgba(255,255,255,.04);
73
+ }
74
+ /* Theme 4 — Glass: ARCHIVED (v3 §6.5 row 4 / §7 decision log 2026-07-07).
75
+ Not selectable from any UI; the token block + WebGL pipeline stay dormant/intact
76
+ so the archive can be revived from the e574 loop without re-porting.
77
+ Original: 本物ガラス (DESIGN-RULES §6.5 theme 4): WebGL refraction glass.
78
+ Tokens = flagship internal body[data-theme="3"] with the gs1 クリア白 (clear
79
+ white, DEFAULT) text values — faithful port, no new colours. The glass slabs
80
+ themselves are drawn by the #glassgl WebGL pipeline (index.html); DOM panels
81
+ go transparent there. These tokens carry the white-family ink, hairlines,
82
+ status hues, the R2 "well" material (--well-*: local re-blur + tint behind
83
+ dense text) and the shared text-shadow (--tsh). gs2-4 text-style variants
84
+ override the well/tsh/surface values via body[data-gs] (index.html). */
85
+ body[data-theme="glass"]{
86
+ --canvas:rgba(8,11,18,.42); --paper:rgba(12,13,17,.78); --panel:rgba(12,13,17,.72); --surface:rgba(255,255,255,.06); --surface2:rgba(12,13,17,.5); --chip:rgba(255,255,255,.10);
87
+ --ink:#ffffff; --ink2:rgba(255,255,255,.80); --ink3:rgba(255,255,255,.56);
88
+ --tint:255,255,255;
89
+ --hair:rgba(255,255,255,.16); --hair2:rgba(255,255,255,.24);
90
+ --glass:rgba(12,13,17,.6);
91
+ --green-rgb:102,230,198; --blue-rgb:143,208,255; --amber-rgb:230,192,106; --danger-rgb:255,138,134;
92
+ --purple-rgb:183,148,246; --glow-rgb:146,180,255;
93
+ --green:rgb(var(--green-rgb)); --amber:rgb(var(--amber-rgb)); --blue:rgb(var(--blue-rgb)); --danger:rgb(var(--danger-rgb));
94
+ --on-accent:#0a0a0b; --invink:#0a0a0b;
95
+ --send-bg:#101014; --send-ink:#ffffff;
96
+ --thumbbg:#000; --dropline:#fff;
97
+ --media-btn:#222; --media-ink:#fff; --media-scrim:rgba(0,0,0,.55);
98
+ --errbg:rgba(60,30,30,.8);
99
+ /* gs1 クリア白: dark-smoke local wells + clear glass; selection/hover = dark smoke */
100
+ --hover:rgba(6,9,15,.34); --hover-s:rgba(6,9,15,.26); --surf:rgba(6,9,15,.20);
101
+ --well-bg:rgba(6,9,15,.36); --well-br:.9; --well-b:9px;
102
+ --tsh:0 1px 3px rgba(0,0,0,.55),0 0 2px rgba(0,0,0,.5);
103
+ }
104
+ /* Gradient — 初期リリースの既定テーマ (DESIGN-RULES v3 §6.5 · Masa 2026-07-07). 背景=端まで
105
+ 全周テーマ色・パネルは白・文字は黒(黒系グラデ選択時は data-arcdark=1 で白反転)。
106
+ パレット=flagship ARC17[1] Lavender(既定) の実値。忠実な移植(新規創作ではない)。逸脱なし。
107
+ 背景グラデの適用(structural)は index.html 側で --edgeG / --edgeA/B を使って行う。
108
+ 緑/赤は Cinema の Vivid 値 #4fd79c / #f0736f(§6.5: W4の深緑/暗赤は濃すぎる)。 */
109
+ body[data-theme="gradient"]{
110
+ --edgeA:#C7B5FF; --edgeB:#7C9EFF; /* Lavender — 背景グラデの両端色 */
111
+ --canvas:#ece9f6; --paper:#ffffff; --panel:#ffffff; --surface:#ffffff; --surface2:#f4f2fb; --chip:#e4e0f5;
112
+ --ink:#17181c; --ink2:#4c4d57; --ink3:#6b6c78;
113
+ --tint:20,23,31;
114
+ --hair:rgba(var(--tint),.10); --hair2:rgba(var(--tint),.16);
115
+ --glass:rgb(255 255 255 / .72);
116
+ --green-rgb:79,215,156; --blue-rgb:37,99,235; --amber-rgb:184,134,11; --danger-rgb:240,115,111;
117
+ --purple-rgb:150,90,220; --glow-rgb:120,150,230;
118
+ --green:rgb(var(--green-rgb)); --amber:rgb(var(--amber-rgb)); --blue:rgb(var(--blue-rgb)); --danger:rgb(var(--danger-rgb));
119
+ --on-accent:#0a0a0b; --invink:#ffffff;
120
+ --send-bg:#1d1d1f; --send-ink:#ffffff;
121
+ --thumbbg:#e6e2f2; --dropline:#1d1d1f;
122
+ --media-btn:#222; --media-ink:#fff; --media-scrim:rgba(0,0,0,.55);
123
+ --errbg:rgb(253 237 237 / .96);
124
+ /* flagship surface tokens — same ink-based values as W4 (panels stay white on Arc) */
125
+ --hover:rgba(20,23,31,.05); --hover-s:rgba(20,23,31,.045); --surf:rgba(20,23,31,.025);
126
+ }
package/app/wp/w1.jpg ADDED
Binary file
package/app/wp/w2.jpg ADDED
Binary file
@@ -0,0 +1,76 @@
1
+ #!/usr/bin/env node
2
+ // Galda — one-line launcher
3
+ //
4
+ // npx galda
5
+ //
6
+ // Checks the environment, starts the local server, prints (and opens) the
7
+ // keyed URL. State lives in ~/.manager-for-ai (never in the npx cache).
8
+
9
+ import { spawnSync } from 'node:child_process';
10
+ import { existsSync } from 'node:fs';
11
+ import { join, resolve, dirname } from 'node:path';
12
+ import { fileURLToPath, pathToFileURL } from 'node:url';
13
+
14
+ const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..');
15
+ const say = (m) => console.log(`[galda] ${m}`);
16
+ // On Windows the `claude`/`ffmpeg` executables are .cmd/.ps1 shims that a bare
17
+ // spawnSync can't resolve (ENOENT) — run through the shell there so PATHEXT
18
+ // resolution kicks in. On macOS/Linux keep shell off (no injection surface).
19
+ const WIN = process.platform === 'win32';
20
+ const probe = (cmd, args) => spawnSync(cmd, args, { encoding: 'utf8', shell: WIN });
21
+
22
+ // 1) claude CLI (the engine — required)
23
+ const claude = probe('claude', ['--version']);
24
+ if (claude.error || claude.status !== 0) {
25
+ say('ERROR: the `claude` CLI was not found.');
26
+ say('Galda runs on your Claude Code subscription (no extra API cost).');
27
+ say('Install it first: https://claude.com/claude-code — then log in with `claude`.');
28
+ process.exit(1);
29
+ }
30
+ say(`claude CLI: ${claude.stdout.trim()}`);
31
+
32
+ // 2) Chrome (for verification proof) — recommended; warn if missing
33
+ const chromeCandidates = [
34
+ process.env.CHROME_PATH,
35
+ '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
36
+ '/Applications/Chromium.app/Contents/MacOS/Chromium',
37
+ '/usr/bin/google-chrome', '/usr/bin/google-chrome-stable', '/usr/bin/chromium-browser', '/usr/bin/chromium',
38
+ 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
39
+ 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe',
40
+ ].filter(Boolean);
41
+ const chrome = chromeCandidates.find((c) => existsSync(c));
42
+ if (chrome) say(`Chrome: ${chrome}`);
43
+ else say('WARNING: Chrome not found — proof videos are disabled. Set CHROME_PATH to enable.');
44
+
45
+ // 3) ffmpeg (mp4/gif proof) — optional
46
+ const ffmpeg = probe('ffmpeg', ['-version']);
47
+ if (ffmpeg.error || ffmpeg.status !== 0) {
48
+ say('WARNING: ffmpeg not found — proof videos stay .webm (no mp4/gif). Install ffmpeg to enable.');
49
+ }
50
+
51
+ // 4) start the server (state in ~/.manager-for-ai unless MANAGER_HOME is set)
52
+ process.env.MANAGER_OPEN_BROWSER = process.env.MANAGER_OPEN_BROWSER ?? '1';
53
+ // Public-build defaults (this CLI is the shipped entry point): point at the
54
+ // deployed billing worker + the fixed-URL relay unless the operator overrides.
55
+ // Set on env BEFORE importing the server so it reads them like any other config.
56
+ // Kept here, not in engine/server.mjs, so tests (which import the server directly)
57
+ // and `npm start` from the repo stay env-driven and don't hit the live worker.
58
+ // The license public key is already baked in engine/lib.mjs (offline verify).
59
+ // Opt out with an empty value: `MANAGER_BILLING_API_URL= RELAY_URL= npx galda`.
60
+ process.env.MANAGER_BILLING_API_URL = process.env.MANAGER_BILLING_API_URL ?? 'https://agent-manager-billing-api.a2c-tech.workers.dev';
61
+ process.env.RELAY_URL = process.env.RELAY_URL ?? 'wss://app.galda.app/agent';
62
+ await import(pathToFileURL(join(ROOT, 'engine', 'server.mjs')).href);
63
+
64
+ // 5) fixed-URL relay (optional): if a relay is configured, connect this local
65
+ // engine to it over an outbound WebSocket so the user reaches their Galda at a
66
+ // stable `<id>.<domain>` from any device. Local-first is preserved — the agent
67
+ // still runs here; the relay is only a door. Opt-in via RELAY_URL for now; the
68
+ // public build will default it to the deployed relay. See relay/DEPLOY.md.
69
+ if (process.env.RELAY_URL) {
70
+ const { spawn } = await import('node:child_process');
71
+ const relay = spawn(process.execPath, [join(ROOT, 'engine', 'relay-client.mjs')], { stdio: 'inherit', env: process.env });
72
+ const stop = () => { try { relay.kill(); } catch { /* already gone */ } };
73
+ process.on('exit', stop);
74
+ for (const sig of ['SIGINT', 'SIGTERM']) process.on(sig, () => { stop(); process.exit(0); });
75
+ say(`relay: connecting to ${process.env.RELAY_URL} — your fixed URL goes live once you sign in`);
76
+ }