@inneranimalmedia/agentsam-sdk 2.4.0 → 2.5.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/README.md +7 -6
- package/docs/AGENTSAM_WORKBENCH.md +30 -0
- package/docs/AUTH_IDENTITY_CONTRACT.md +52 -0
- package/docs/CAPABILITIES.md +5 -3
- package/docs/CLI_SHELL.md +57 -80
- package/docs/CMS_STUDIO.md +101 -0
- package/docs/CONTEXT.md +170 -0
- package/docs/LOCAL_OLLAMA.md +58 -0
- package/docs/MERKLE.md +19 -19
- package/docs/PORTABLE_CONTEXT.md +4 -3
- package/docs/PROJECT_CONFIG.md +72 -0
- package/docs/RELEASES.md +26 -2
- package/docs/REPOSITORY_INTELLIGENCE.md +1 -1
- package/docs/REPOSITORY_KNOWLEDGE.md +114 -0
- package/docs/SDK_WORKER.md +86 -0
- package/docs/SECURITY.md +59 -22
- package/docs/client-cms-editor.md +15 -0
- package/docs/local-studio/WORKMODE_DONOR_NOTES.md +485 -0
- package/package.json +17 -5
- package/packages/identity/package.json +11 -2
- package/packages/identity/src/contracts/auth-config.js +98 -0
- package/packages/identity/src/index.js +1 -0
- package/packages/identity/src/oauth/README.md +2 -2
- package/packages/identity/src/oauth/credentials.js +11 -4
- package/packages/identity/src/oauth/iam-platform.js +3 -3
- package/packages/identity/src/providers/iam/index.js +7 -7
- package/packages/identity/src/providers/iam/oauth.js +6 -4
- package/packages/identity/src/providers/iam/profile.js +5 -5
- package/packages/identity/tests/auth-config.test.mjs +57 -0
- package/packages/identity/tests/oauth-credentials.test.mjs +13 -2
- package/protocol/FILEMETA_V1.md +95 -0
- package/protocol/INSPECT_VIEWS_V1.md +40 -0
- package/protocol/MERKLE_PERSISTENCE_V1.md +50 -0
- package/protocol/MERKLE_V1.md +3 -1
- package/protocol/capabilities/manifest.json +32 -3
- package/protocol/capabilities/repository-snapshot.schema.json +1 -0
- package/protocol/context/context-budget.schema.json +41 -0
- package/protocol/context/context-item.schema.json +20 -0
- package/protocol/context/resolved-context-pack.schema.json +42 -0
- package/protocol/context/result-policy.schema.json +17 -0
- package/protocol/knowledge/context-pack.schema.json +33 -0
- package/protocol/knowledge/retrieval-query.schema.json +68 -13
- package/python/README.md +15 -7
- package/python/agentsam_sdk/cli.py +0 -21
- package/python/agentsam_sdk/tui/README.md +17 -12
- package/python/agentsam_sdk/tui/bootstrap.py +2 -2
- package/python/agentsam_sdk/tui/demo.py +25 -10
- package/python/agentsam_sdk/tui/onboarding.py +208 -0
- package/python/tests/test_tui_cli.py +7 -6
- package/skills/README.md +21 -0
- package/skills/agentsam-app-fundamentals/SKILL.md +165 -0
- package/skills/agentsam-app-fundamentals/references/graphs-contracts-ast-merkle.md +89 -0
- package/skills/agentsam-app-fundamentals/references/trust-credentials-and-destinations.md +99 -0
- package/skills/agentsam-jr-dev/SKILL.md +232 -0
- package/skills/agentsam-jr-dev/references/real-application-logic.md +156 -0
- package/skills/agentsam-jr-dev/references/web-application-fundamentals.md +240 -0
- package/skills/agentsam-progression-guard/SKILL.md +197 -0
- package/skills/agentsam-progression-guard/references/checkpoint-chain.md +111 -0
- package/skills/agentsam-progression-guard/references/hooks-operational-io.md +96 -0
- package/skills/catalog.json +53 -0
- package/src/capabilities/index.js +7 -0
- package/src/capabilities/repository-snapshot-view.js +238 -0
- package/src/capabilities/repository-snapshot.js +28 -14
- package/src/cli.js +108 -56
- package/src/commands/cad.js +56 -6
- package/src/commands/context.js +14 -2
- package/src/commands/db.js +4 -7
- package/src/commands/deploy.js +17 -31
- package/src/commands/interactive.js +21 -0
- package/src/commands/knowledge.js +27 -4
- package/src/commands/merkle-persist.js +118 -0
- package/src/commands/merkle.js +32 -17
- package/src/commands/models.js +107 -0
- package/src/commands/ollama.js +259 -0
- package/src/commands/preferences.js +102 -0
- package/src/commands/product.js +86 -16
- package/src/commands/security.js +3 -3
- package/src/commands/shell.js +71 -27
- package/src/commands/skills.js +66 -0
- package/src/commands/start-local.js +1 -1
- package/src/commands/tunnel.js +5 -4
- package/src/context/budget.js +58 -0
- package/src/context/compact.js +28 -0
- package/src/context/index.js +5 -0
- package/src/context/resolve.js +84 -0
- package/src/context/result-policy.js +66 -0
- package/src/index.js +16 -0
- package/src/indexing/execution-boundary.js +144 -0
- package/src/indexing/index.js +8 -0
- package/src/indexing/provider.js +41 -0
- package/src/knowledge/config.js +2 -2
- package/src/knowledge/context-pack.js +12 -1
- package/src/knowledge/contracts.js +9 -4
- package/src/knowledge/engine.js +7 -3
- package/src/knowledge/service/server.js +1 -1
- package/src/lib/auth.js +10 -19
- package/src/lib/bridge-client.js +7 -5
- package/src/lib/cli-preferences.js +74 -0
- package/src/lib/core-client.js +8 -8
- package/src/lib/deploy-receipt/index.js +5 -2
- package/src/lib/detect-context.js +6 -5
- package/src/lib/identity-scaffold.js +1 -1
- package/src/lib/local-scaffold.js +35 -33
- package/src/lib/local-status.js +9 -17
- package/src/lib/merkle/cloudflare-persistence.js +321 -0
- package/src/lib/merkle/filemeta.js +43 -0
- package/src/lib/merkle/git-ignore.js +24 -0
- package/src/lib/merkle/hash.js +1 -0
- package/src/lib/merkle/index.js +22 -0
- package/src/lib/merkle/persistence.js +72 -0
- package/src/lib/merkle/semantic.js +359 -0
- package/src/lib/merkle/snapshot.js +9 -3
- package/src/lib/merkle/tree.js +11 -6
- package/src/lib/open-url.js +66 -0
- package/src/lib/project-config.js +227 -0
- package/src/lib/project-rules.js +68 -0
- package/src/lib/save-sdk-token.js +1 -1
- package/src/lib/slash-commands.js +2 -1
- package/src/lib/tools.js +11 -5
- package/src/security/index.js +1 -0
- package/src/security/inventory.js +4 -1
- package/src/security/render.js +27 -5
- package/src/security/scan.js +24 -9
- package/src/security/trust-boundary.js +24 -0
- package/src/skills/index.js +64 -0
- package/src/tools/index.js +1 -0
- package/src/tools/search.js +70 -0
- package/src/ui/ansi.js +1 -1
- package/src/ui/boot.js +56 -0
- package/src/ui/merkle/render.js +1 -0
- package/src/ui/runtime-activity.js +192 -0
- package/src/ui/theme.js +19 -18
- package/test/app-building-skills.test.mjs +61 -0
- package/test/apps-scaffold-contract.test.mjs +56 -0
- package/test/capabilities.test.mjs +53 -4
- package/test/cli-preferences.test.mjs +25 -0
- package/test/context.test.mjs +95 -0
- package/test/indexing-provider.test.mjs +29 -0
- package/test/jr-dev-skill.test.mjs +26 -0
- package/test/knowledge-context-pack.test.mjs +19 -0
- package/test/knowledge.test.mjs +1 -1
- package/test/merkle-persistence.test.mjs +91 -0
- package/test/merkle.test.mjs +77 -3
- package/test/models.test.mjs +37 -0
- package/test/ollama.test.mjs +94 -0
- package/test/open-url.test.mjs +64 -0
- package/test/project-config.test.mjs +81 -0
- package/test/project-rules.test.mjs +44 -0
- package/test/release-hygiene.test.mjs +34 -0
- package/test/repository-snapshot-view.test.mjs +112 -0
- package/test/runtime-activity.test.mjs +98 -0
- package/test/sdk-worker-contract.test.mjs +68 -0
- package/test/security.test.mjs +46 -0
- package/test/shell.test.mjs +8 -1
- package/test/skills.test.mjs +22 -0
- package/test/smoke.mjs +2 -2
- package/test/theme-portability.test.mjs +14 -0
- package/test/tools-search.test.mjs +27 -0
- package/examples/agentsam-tui-ansi.mjs +0 -149
- package/src/commands/tui.js +0 -120
- package/src/ui/splash-xterm.js +0 -290
- package/src/ui/splash.js +0 -426
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
/**
|
|
3
|
-
* Zero-dependency ANSI companion to the Agent Sam SDK TUI.
|
|
4
|
-
* Use this from Agent Sam PTY / Node scripts when you do not want Python+Rich.
|
|
5
|
-
*
|
|
6
|
-
* node scripts/demo_agentsam_ansi.mjs
|
|
7
|
-
* node scripts/demo_agentsam_ansi.mjs --scene sprite
|
|
8
|
-
* node scripts/demo_agentsam_ansi.mjs --check
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
const HIDE = "\x1b[?25l";
|
|
12
|
-
const SHOW = "\x1b[?25h";
|
|
13
|
-
const CLEAR_LINE = "\x1b[2K";
|
|
14
|
-
const MAGENTA = "\x1b[38;2;211;54;130m";
|
|
15
|
-
const CYAN = "\x1b[38;2;45;212;191m";
|
|
16
|
-
const MUTED = "\x1b[38;2;122;154;170m";
|
|
17
|
-
const GREEN = "\x1b[38;2;163;184;0m";
|
|
18
|
-
const RESET = "\x1b[0m";
|
|
19
|
-
const BOLD = "\x1b[1m";
|
|
20
|
-
const DIM = "\x1b[2m";
|
|
21
|
-
|
|
22
|
-
const WALKER = [
|
|
23
|
-
[" · ", " ○ ", " │╲ ", " │ ○ ", " ○ ░ ", " ░ "],
|
|
24
|
-
[" · ", " ○ ", " │╲ ", " ○ ○ ", " ░ ", " ░ "],
|
|
25
|
-
[" · ", " ○ ", " │╲ ", " ○ │ ", " ○ ", " ░ "],
|
|
26
|
-
[" · ", " ○ ", " ╱│ ", " ○ │ ", " ○ ", " ░ "],
|
|
27
|
-
[" · ", " ○ ", " ╱│ ", " ○ │ ", " ○ ░ ", " ░ "],
|
|
28
|
-
[" · ", " ○ ", " ╱│ ", " ○ │ ", " ○ ░ ", " ░ "],
|
|
29
|
-
[" · ", " ○ ", " │╲ ", " ○ ○ ", " ○ ░ ", " ░ "],
|
|
30
|
-
[" · ", " ○ ", " │╲ ", " │ ○ ", " ○ ░ ", " ░ "],
|
|
31
|
-
];
|
|
32
|
-
|
|
33
|
-
const BRAILLE = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
|
|
34
|
-
|
|
35
|
-
function sleep(ms) {
|
|
36
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function paint(lines) {
|
|
40
|
-
const payload = lines.map((line) => `${CLEAR_LINE}${line}`).join("\n");
|
|
41
|
-
process.stdout.write(`${payload}\n`);
|
|
42
|
-
return lines.length;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function moveUp(n) {
|
|
46
|
-
if (n > 0) process.stdout.write(`\x1b[${n}A`);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function box(title, bodyLines, width = 42) {
|
|
50
|
-
const inner = width - 2;
|
|
51
|
-
const top = `${MAGENTA}╭${"─".repeat(inner)}╮${RESET}`;
|
|
52
|
-
const label = ` ${title} `;
|
|
53
|
-
const titled = `${MAGENTA}╭${RESET}${BOLD}${CYAN}${label}${RESET}${MAGENTA}${"─".repeat(Math.max(0, inner - label.length))}╮${RESET}`;
|
|
54
|
-
const mid = bodyLines.map((line) => {
|
|
55
|
-
const visible = line.replace(/\x1b\[[0-9;]*m/g, "");
|
|
56
|
-
const pad = Math.max(0, inner - 2 - visible.length);
|
|
57
|
-
return `${MAGENTA}│${RESET} ${line}${" ".repeat(pad)} ${MAGENTA}│${RESET}`;
|
|
58
|
-
});
|
|
59
|
-
const bot = `${MAGENTA}╰${"─".repeat(inner)}╯${RESET}`;
|
|
60
|
-
return [titled.length ? titled : top, ...mid, bot];
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
async function sceneSprite({ ticks, delay }) {
|
|
64
|
-
let used = 0;
|
|
65
|
-
for (let i = 0; i < ticks; i += 1) {
|
|
66
|
-
const frame = WALKER[i % WALKER.length];
|
|
67
|
-
const caption = `${MUTED}Agent Sam is walking · frame ${String(i + 1).padStart(2, "0")}${RESET}`;
|
|
68
|
-
const lines = box("agent activity", [...frame.map((row) => `${CYAN}${BOLD}${row}${RESET}`), "", caption], 34);
|
|
69
|
-
if (used) moveUp(used);
|
|
70
|
-
used = paint(lines);
|
|
71
|
-
await sleep(delay);
|
|
72
|
-
}
|
|
73
|
-
return used;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
async function sceneDashboard({ ticks, delay }) {
|
|
77
|
-
const total = 2320;
|
|
78
|
-
let used = 0;
|
|
79
|
-
const started = Date.now();
|
|
80
|
-
for (let i = 0; i < ticks; i += 1) {
|
|
81
|
-
const done = Math.min(total, Math.round(((i + 1) / ticks) * total));
|
|
82
|
-
const symbols = Math.round(done * 2.76);
|
|
83
|
-
const elapsed = Math.round((Date.now() - started) / 1000);
|
|
84
|
-
const spin = BRAILLE[i % BRAILLE.length];
|
|
85
|
-
const walker = WALKER[i % WALKER.length];
|
|
86
|
-
const pct = Math.round((done / total) * 100);
|
|
87
|
-
const barFilled = Math.round(pct / 5);
|
|
88
|
-
const bar = `${CYAN}${"█".repeat(barFilled)}${MUTED}${"░".repeat(20 - barFilled)}${RESET}`;
|
|
89
|
-
const body = [
|
|
90
|
-
`${MUTED}stage${RESET} ${CYAN}${BOLD}parse_chunks${RESET} ${spin}`,
|
|
91
|
-
`${MUTED}files${RESET} ${done.toLocaleString()} / ${total.toLocaleString()}`,
|
|
92
|
-
`${MUTED}symbols${RESET} ${symbols.toLocaleString()}`,
|
|
93
|
-
`${MUTED}errors${RESET} ${GREEN}0${RESET}`,
|
|
94
|
-
`${MUTED}elapsed${RESET} ${elapsed}s`,
|
|
95
|
-
`${bar} ${pct}%`,
|
|
96
|
-
"",
|
|
97
|
-
...walker.map((row) => `${CYAN}${row}${RESET}`),
|
|
98
|
-
];
|
|
99
|
-
const lines = box("◉ Code Index", body, 46);
|
|
100
|
-
if (used) moveUp(used);
|
|
101
|
-
used = paint(lines);
|
|
102
|
-
await sleep(delay);
|
|
103
|
-
}
|
|
104
|
-
return used;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
async function sceneLogs({ delay }) {
|
|
108
|
-
const rows = [
|
|
109
|
-
["INFO", "Connected to Hyperdrive", "471 ms"],
|
|
110
|
-
["WORK", "Parsing batch", "24 files"],
|
|
111
|
-
["OK", "Checkpoint committed", "durable"],
|
|
112
|
-
];
|
|
113
|
-
const styles = { INFO: "\x1b[38;2;58;159;232m", WORK: "\x1b[38;2;230;172;0m", OK: GREEN };
|
|
114
|
-
for (const [level, message, detail] of rows) {
|
|
115
|
-
const now = new Date().toISOString().slice(11, 19);
|
|
116
|
-
process.stdout.write(
|
|
117
|
-
`${DIM}${now}${RESET} ${styles[level]}${level.padStart(4)}${RESET} ${message} ${DIM}· ${detail}${RESET}\n`,
|
|
118
|
-
);
|
|
119
|
-
await sleep(delay);
|
|
120
|
-
}
|
|
121
|
-
return 0;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
async function main() {
|
|
125
|
-
const args = new Set(process.argv.slice(2));
|
|
126
|
-
const check = args.has("--check");
|
|
127
|
-
const scene = [...args].find((a) => !a.startsWith("--")) || (args.has("--scene") ? null : "all");
|
|
128
|
-
const sceneFlagIdx = process.argv.indexOf("--scene");
|
|
129
|
-
const named = sceneFlagIdx >= 0 ? process.argv[sceneFlagIdx + 1] : scene;
|
|
130
|
-
const which = named && named !== "all" && !named.startsWith("--") ? named : "all";
|
|
131
|
-
const delay = check ? 0 : 90;
|
|
132
|
-
const ticks = check ? 4 : 32;
|
|
133
|
-
|
|
134
|
-
process.stdout.write(HIDE);
|
|
135
|
-
try {
|
|
136
|
-
if (which === "sprite" || which === "all") await sceneSprite({ ticks, delay });
|
|
137
|
-
if (which === "dashboard" || which === "all") await sceneDashboard({ ticks, delay });
|
|
138
|
-
if (which === "logs" || which === "all") await sceneLogs({ delay: check ? 0 : 120 });
|
|
139
|
-
process.stdout.write(`\n${GREEN}${BOLD}Done.${RESET} Use the Python agentsam tui command for Rich layouts.\n`);
|
|
140
|
-
} finally {
|
|
141
|
-
process.stdout.write(SHOW);
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
main().catch((err) => {
|
|
146
|
-
process.stdout.write(SHOW);
|
|
147
|
-
console.error(err);
|
|
148
|
-
process.exit(1);
|
|
149
|
-
});
|
package/src/commands/tui.js
DELETED
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
import fs from 'node:fs';
|
|
2
|
-
import path from 'node:path';
|
|
3
|
-
import { spawn } from 'node:child_process';
|
|
4
|
-
import { fileURLToPath } from 'node:url';
|
|
5
|
-
import { collectLocalStatus } from '../lib/local-status.js';
|
|
6
|
-
import { renderLocalStatus } from '../ui/ansi.js';
|
|
7
|
-
import { runMerkle } from './merkle.js';
|
|
8
|
-
|
|
9
|
-
const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', '..');
|
|
10
|
-
const ANSI_DEMO = path.join(ROOT, 'examples', 'agentsam-tui-ansi.mjs');
|
|
11
|
-
const PYTHON_ROOT = path.join(ROOT, 'python');
|
|
12
|
-
|
|
13
|
-
function run(command, args, options = {}) {
|
|
14
|
-
return new Promise((resolve, reject) => {
|
|
15
|
-
const child = spawn(command, args, {
|
|
16
|
-
stdio: options.stdio || 'inherit',
|
|
17
|
-
cwd: options.cwd || process.cwd(),
|
|
18
|
-
env: options.env || process.env,
|
|
19
|
-
});
|
|
20
|
-
child.once('error', reject);
|
|
21
|
-
child.once('exit', (code, signal) => {
|
|
22
|
-
if (signal) reject(new Error(`${command} stopped by ${signal}`));
|
|
23
|
-
else if (code === 0) resolve(0);
|
|
24
|
-
else reject(new Error(`${command} exited ${code ?? 1}`));
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function hasScene(args) {
|
|
30
|
-
return args.includes('--scene') || args.some((arg) => arg.startsWith('--scene='));
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function venvPython(venvRoot) {
|
|
34
|
-
return process.platform === 'win32'
|
|
35
|
-
? path.join(venvRoot, 'Scripts', 'python.exe')
|
|
36
|
-
: path.join(venvRoot, 'bin', 'python');
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
async function findSystemPython() {
|
|
40
|
-
for (const candidate of process.platform === 'win32' ? ['python', 'py'] : ['python3', 'python']) {
|
|
41
|
-
try {
|
|
42
|
-
await run(candidate, ['--version'], { stdio: 'ignore' });
|
|
43
|
-
return candidate;
|
|
44
|
-
} catch {
|
|
45
|
-
// try next candidate
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
return null;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
async function pythonHasRich(python) {
|
|
52
|
-
try {
|
|
53
|
-
await run(python, ['-c', 'import rich'], { stdio: 'ignore' });
|
|
54
|
-
return true;
|
|
55
|
-
} catch {
|
|
56
|
-
return false;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
async function runRich(args) {
|
|
61
|
-
const install = args.includes('--install');
|
|
62
|
-
const forwarded = args.filter((arg) => arg !== '--install');
|
|
63
|
-
const projectVenv = path.resolve(process.cwd(), '.agentsam', 'tui-venv');
|
|
64
|
-
let python = fs.existsSync(venvPython(projectVenv)) ? venvPython(projectVenv) : null;
|
|
65
|
-
|
|
66
|
-
if (!python && install) {
|
|
67
|
-
const systemPython = await findSystemPython();
|
|
68
|
-
if (!systemPython) throw new Error('Python 3 is required for the optional Rich TUI.');
|
|
69
|
-
fs.mkdirSync(path.dirname(projectVenv), { recursive: true });
|
|
70
|
-
console.log(`\n Agent Sam Rich TUI setup\n · creating ${projectVenv}`);
|
|
71
|
-
await run(systemPython, ['-m', 'venv', projectVenv]);
|
|
72
|
-
python = venvPython(projectVenv);
|
|
73
|
-
console.log(' · installing rich into isolated Agent Sam venv');
|
|
74
|
-
await run(python, ['-m', 'pip', 'install', 'rich>=13.7.0']);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
if (!python) {
|
|
78
|
-
const systemPython = await findSystemPython();
|
|
79
|
-
if (systemPython && (await pythonHasRich(systemPython))) python = systemPython;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
if (!python) {
|
|
83
|
-
throw new Error(
|
|
84
|
-
'Rich TUI is optional and not installed. Run `agentsam tui rich --install` to create an isolated .agentsam/tui-venv.',
|
|
85
|
-
);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
const env = {
|
|
89
|
-
...process.env,
|
|
90
|
-
PYTHONPATH: [PYTHON_ROOT, process.env.PYTHONPATH].filter(Boolean).join(path.delimiter),
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
if (!hasScene(forwarded)) {
|
|
94
|
-
const status = await collectLocalStatus();
|
|
95
|
-
env.AGENTSAM_STATUS_JSON = JSON.stringify(status);
|
|
96
|
-
await run(python, ['-m', 'agentsam_sdk.tui.status'], { env });
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
await run(python, ['-m', 'agentsam_sdk.tui', ...forwarded], { env });
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
export async function runTui(argv = []) {
|
|
104
|
-
if (argv[0] === 'merkle') return runMerkle(['tui', ...argv.slice(1)]);
|
|
105
|
-
const args = [...argv];
|
|
106
|
-
const mode = args[0] === 'rich' || args[0] === 'ansi' ? args.shift() : 'ansi';
|
|
107
|
-
|
|
108
|
-
if (mode === 'rich') {
|
|
109
|
-
await runRich(args);
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
if (!hasScene(args)) {
|
|
114
|
-
const status = await collectLocalStatus();
|
|
115
|
-
process.stdout.write(`\n${renderLocalStatus(status)}\n\n`);
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
await run(process.execPath, [ANSI_DEMO, ...args]);
|
|
120
|
-
}
|
package/src/ui/splash-xterm.js
DELETED
|
@@ -1,290 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file src/ui/splash-xterm.js
|
|
3
|
-
* @description In-app splash renderer for xterm.js panels.
|
|
4
|
-
*
|
|
5
|
-
* Same choreography as splash.js (CLI) but writes to an xterm Terminal
|
|
6
|
-
* instance instead of process.stdout. Used by XTermShell.tsx.
|
|
7
|
-
*
|
|
8
|
-
* Usage in XTermShell.tsx:
|
|
9
|
-
* import { runXtermSplash } from '@inneranimalmedia/agentsam-sdk/ui/splash-xterm';
|
|
10
|
-
* import { getXtermOptions } from '@inneranimalmedia/agentsam-sdk/ui/theme';
|
|
11
|
-
*
|
|
12
|
-
* const targetType = connection?.target_type ?? 'platform_vm';
|
|
13
|
-
* const term = new Terminal({
|
|
14
|
-
* ...getXtermOptions(targetType),
|
|
15
|
-
* cols: dimensions.cols,
|
|
16
|
-
* rows: dimensions.rows,
|
|
17
|
-
* });
|
|
18
|
-
*
|
|
19
|
-
* // After term.open(containerRef.current):
|
|
20
|
-
* const stopFlicker = await runXtermSplash(term, {
|
|
21
|
-
* apiBase: 'https://inneranimalmedia.com',
|
|
22
|
-
* workspaceId: activeWorkspace?.id,
|
|
23
|
-
* authToken: session?.token,
|
|
24
|
-
* targetType,
|
|
25
|
-
* skipArt: !isFirstSession,
|
|
26
|
-
* });
|
|
27
|
-
*
|
|
28
|
-
* // On cleanup:
|
|
29
|
-
* return () => { stopFlicker(); term.dispose(); };
|
|
30
|
-
*/
|
|
31
|
-
|
|
32
|
-
import { PALETTE, getLaneTheme } from './theme.js';
|
|
33
|
-
import { probeAll } from './splash.js';
|
|
34
|
-
|
|
35
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
36
|
-
// xterm write helpers
|
|
37
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
38
|
-
|
|
39
|
-
const ESC = '\x1b';
|
|
40
|
-
const CSI = `${ESC}[`;
|
|
41
|
-
|
|
42
|
-
const X = {
|
|
43
|
-
reset: `${CSI}0m`,
|
|
44
|
-
bold: `${CSI}1m`,
|
|
45
|
-
hide: `${CSI}?25l`,
|
|
46
|
-
show: `${CSI}?25h`,
|
|
47
|
-
clearLine: `${CSI}2K\r`,
|
|
48
|
-
up: (n = 1) => `${CSI}${n}A`,
|
|
49
|
-
fg: (hex) => {
|
|
50
|
-
const h = hex.replace('#', '');
|
|
51
|
-
const r = parseInt(h.slice(0, 2), 16);
|
|
52
|
-
const g = parseInt(h.slice(2, 4), 16);
|
|
53
|
-
const b = parseInt(h.slice(4, 6), 16);
|
|
54
|
-
return `${CSI}38;2;${r};${g};${b}m`;
|
|
55
|
-
},
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
const sleep = (ms) => new Promise(r => setTimeout(r, ms));
|
|
59
|
-
|
|
60
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
61
|
-
// COLOR BUILDER (per-lane)
|
|
62
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
63
|
-
|
|
64
|
-
function buildColors() {
|
|
65
|
-
const R = X.reset;
|
|
66
|
-
const B = X.bold;
|
|
67
|
-
return {
|
|
68
|
-
R, B,
|
|
69
|
-
TEAL: X.fg(PALETTE.teal300),
|
|
70
|
-
AMBER: X.fg(PALETTE.amber300),
|
|
71
|
-
STONE: X.fg('#3a3530'),
|
|
72
|
-
STONE2: X.fg('#2a2520'),
|
|
73
|
-
VINE: X.fg('#1a4a2a'),
|
|
74
|
-
VINE2: X.fg('#0f6b3a'),
|
|
75
|
-
FIRE1: X.fg('#f97316'),
|
|
76
|
-
FIRE2: X.fg('#ef4444'),
|
|
77
|
-
FIREY: X.fg('#fef08a'),
|
|
78
|
-
GRILL: X.fg('#1e2830'),
|
|
79
|
-
GRILL2: X.fg('#2d3d4a'),
|
|
80
|
-
PELT: X.fg('#8b6f5a'),
|
|
81
|
-
DIM: X.fg('#444444'),
|
|
82
|
-
GHOST: X.fg('#888888'),
|
|
83
|
-
WHT: X.fg('#e2e8f0'),
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
88
|
-
// SCENE DATA
|
|
89
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
90
|
-
|
|
91
|
-
function gorillaRows(C) {
|
|
92
|
-
const { R, GRILL, GRILL2, PELT, DIM } = C;
|
|
93
|
-
return [
|
|
94
|
-
` ${DIM}░░▒${R}${GRILL2}▓▓▓▓▓▓▓▓${R}${DIM}▒░░${R}`,
|
|
95
|
-
` ${DIM}░${R}${GRILL2}▒▓▓${R}${GRILL}█████████████${R}${GRILL2}▓▓▒${R}${DIM}░${R}`,
|
|
96
|
-
` ${GRILL2}▒▓${R}${GRILL}███${R}${GRILL2}▒▒${R}${GRILL}████████${R}${GRILL2}▒▒${R}${GRILL}███${R}${GRILL2}▓▒${R}`,
|
|
97
|
-
` ${GRILL2}▓${R}${GRILL}████${R} ${DIM}▒▒▒▒▒▒▒▒${R} ${GRILL}████${R}${GRILL2}▓${R}`,
|
|
98
|
-
` ${GRILL}▓███${R}${GRILL2}▒${R} ${PELT}██${R}${DIM}▒${R}${PELT}████${R}${DIM}▒${R}${PELT}██${R} ${GRILL2}▒${R}${GRILL}███▓${R}`,
|
|
99
|
-
` ${GRILL}████${R} ${PELT}███${R}${DIM}▒▒▒▒${R}${PELT}███${R} ${GRILL}████${R}`,
|
|
100
|
-
` ${GRILL}████${R}${GRILL2}▒${R} ${PELT}██████████${R} ${GRILL2}▒${R}${GRILL}████${R}`,
|
|
101
|
-
` ${GRILL}████${R} ${DIM}▒▒▒▒▒▒▒▒▒▒${R} ${GRILL}████${R}`,
|
|
102
|
-
` ${GRILL2}▒${R}${GRILL}████${R}${GRILL2}▓▓▓${R}${GRILL}████████████${R}${GRILL2}▓▓▓${R}${GRILL}████${R}${GRILL2}▒${R}`,
|
|
103
|
-
` ${GRILL}██████████████████████████${R}`,
|
|
104
|
-
` ${DIM}▒▒${R}${GRILL}████████${R}${GRILL2}▒▒▒▒▒▒▒▒▒▒▒▒${R}${GRILL}████████${R}${DIM}▒▒${R}`,
|
|
105
|
-
` ${PELT}▓${R}${GRILL}██████████${R}${DIM}░░░░░░░░░░░░░░${R}${GRILL}██████████${R}${PELT}▓${R}`,
|
|
106
|
-
];
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
function titleBoxLines(C) {
|
|
110
|
-
const { R, B, TEAL, AMBER } = C;
|
|
111
|
-
const wide = 26;
|
|
112
|
-
const h = `${TEAL}═${R}`;
|
|
113
|
-
return [
|
|
114
|
-
`${TEAL}╔${R}${h.repeat(wide)}${TEAL}╗${R}`,
|
|
115
|
-
`${TEAL}║${R} ${B}${AMBER}INNERANIMAL MEDIA${R} ${TEAL}║${R}`,
|
|
116
|
-
`${TEAL}║${R} ${TEAL}inneranimalmedia.com${R} ${TEAL}║${R}`,
|
|
117
|
-
`${TEAL}╚${R}${h.repeat(wide)}${TEAL}╝${R}`,
|
|
118
|
-
];
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function ladderRows(C) {
|
|
122
|
-
const { R, TEAL } = C;
|
|
123
|
-
return [
|
|
124
|
-
` ${TEAL}║${R} ${TEAL}║${R}`,
|
|
125
|
-
` ${TEAL}╠═══╣${R}`,
|
|
126
|
-
` ${TEAL}║${R} ${TEAL}║${R}`,
|
|
127
|
-
` ${TEAL}╠═══╣${R}`,
|
|
128
|
-
` ${TEAL}║${R} ${TEAL}║${R}`,
|
|
129
|
-
` ${TEAL}╠═══╣${R}`,
|
|
130
|
-
` ${TEAL}║${R} ${TEAL}║${R}`,
|
|
131
|
-
];
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
135
|
-
// HUD RENDER
|
|
136
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
137
|
-
|
|
138
|
-
const HUD_ITEMS = [
|
|
139
|
-
{ key: 'workspace', icon: '⊞', label: 'Workspace' },
|
|
140
|
-
{ key: 'runtime', icon: '▣', label: 'Runtime' },
|
|
141
|
-
{ key: 'tunnel', icon: '⟁', label: 'Tunnel' },
|
|
142
|
-
{ key: 'agent', icon: '⬡', label: 'Agent' },
|
|
143
|
-
];
|
|
144
|
-
|
|
145
|
-
const READY_LABELS = {
|
|
146
|
-
workspace: 'active',
|
|
147
|
-
runtime: 'ready',
|
|
148
|
-
tunnel: 'connected',
|
|
149
|
-
agent: 'online',
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
function renderHUDLine(states, C) {
|
|
153
|
-
const { R, B, TEAL, GHOST, WHT, DIM } = C;
|
|
154
|
-
return HUD_ITEMS.map((item, i) => {
|
|
155
|
-
const state = states[item.key] || 'checking';
|
|
156
|
-
let stateStr;
|
|
157
|
-
if (state === 'ready') {
|
|
158
|
-
stateStr = `${TEAL}● ${READY_LABELS[item.key]}${R}`;
|
|
159
|
-
} else if (state === 'checking') {
|
|
160
|
-
stateStr = `${GHOST}◌ checking...${R}`;
|
|
161
|
-
} else if (state === 'error') {
|
|
162
|
-
stateStr = `${X.fg('#ef4444')}✗ error${R}`;
|
|
163
|
-
} else {
|
|
164
|
-
stateStr = `${X.fg('#666666')}○ offline${R}`;
|
|
165
|
-
}
|
|
166
|
-
const div = i < HUD_ITEMS.length - 1 ? ` ${DIM}│${R} ` : '';
|
|
167
|
-
return `${GHOST}${item.icon}${R} ${B}${WHT}${item.label}${R} ${stateStr}${div}`;
|
|
168
|
-
}).join('');
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
172
|
-
// MAIN XTERM SPLASH
|
|
173
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* @param {import('@xterm/xterm').Terminal} term
|
|
177
|
-
* @param {object} opts
|
|
178
|
-
* @param {string} opts.apiBase
|
|
179
|
-
* @param {string} opts.workspaceId
|
|
180
|
-
* @param {string} opts.authToken
|
|
181
|
-
* @param {'user_hosted_tunnel'|'platform_vm'|'sandbox'} opts.targetType
|
|
182
|
-
* @param {boolean} opts.skipArt
|
|
183
|
-
* @returns {Promise<() => void>} stopFlicker — call on unmount
|
|
184
|
-
*/
|
|
185
|
-
export async function runXtermSplash(term, {
|
|
186
|
-
apiBase = '',
|
|
187
|
-
workspaceId = '',
|
|
188
|
-
authToken = '',
|
|
189
|
-
targetType = 'platform_vm',
|
|
190
|
-
skipArt = false,
|
|
191
|
-
} = {}) {
|
|
192
|
-
|
|
193
|
-
const lane = getLaneTheme(targetType);
|
|
194
|
-
const C = buildColors();
|
|
195
|
-
const { R, B, TEAL, AMBER, GHOST, WHT, DIM, STONE, STONE2, FIRE1, FIRE2 } = C;
|
|
196
|
-
const PRIMARY = X.fg(lane.colors.primary);
|
|
197
|
-
const W = term.cols || 80;
|
|
198
|
-
|
|
199
|
-
const w = (s) => term.write(s);
|
|
200
|
-
const wl = (s = '') => term.write(s + '\r\n');
|
|
201
|
-
|
|
202
|
-
w(X.hide);
|
|
203
|
-
w(`${ESC}c`); // full reset
|
|
204
|
-
await sleep(60);
|
|
205
|
-
|
|
206
|
-
// cd verb flash
|
|
207
|
-
w(` ${GHOST}$ ${R}${AMBER}cd ~/inneranimalmedia${R}`);
|
|
208
|
-
await sleep(340);
|
|
209
|
-
w(`\r${X.clearLine}`);
|
|
210
|
-
await sleep(60);
|
|
211
|
-
|
|
212
|
-
if (!skipArt) {
|
|
213
|
-
wl();
|
|
214
|
-
|
|
215
|
-
const rows = gorillaRows(C);
|
|
216
|
-
const title = titleBoxLines(C);
|
|
217
|
-
const TITLE_START = 3;
|
|
218
|
-
|
|
219
|
-
for (let i = 0; i < rows.length; i++) {
|
|
220
|
-
const titleIdx = i - TITLE_START;
|
|
221
|
-
const titlePart = (titleIdx >= 0 && titleIdx < title.length)
|
|
222
|
-
? ' ' + title[titleIdx]
|
|
223
|
-
: '';
|
|
224
|
-
wl(` ${rows[i]}${titlePart}`);
|
|
225
|
-
await sleep(24);
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
wl();
|
|
229
|
-
|
|
230
|
-
// Torches
|
|
231
|
-
w(` ${FIRE1} ▓▓▓${R}`);
|
|
232
|
-
await sleep(90);
|
|
233
|
-
wl(`${' '.repeat(Math.max(0, W - 14))}${FIRE2}▓▓▓${R}`);
|
|
234
|
-
await sleep(30);
|
|
235
|
-
|
|
236
|
-
// Ledge
|
|
237
|
-
w(' ');
|
|
238
|
-
for (let i = 0; i < W - 4; i++) {
|
|
239
|
-
w((i % 2 === 0) ? `${STONE}█${R}` : `${STONE2}▓${R}`);
|
|
240
|
-
await sleep(4);
|
|
241
|
-
}
|
|
242
|
-
wl();
|
|
243
|
-
wl(` ${DIM}${'╌'.repeat(W - 4)}${R}`);
|
|
244
|
-
await sleep(50);
|
|
245
|
-
|
|
246
|
-
// Ladder
|
|
247
|
-
for (const rung of ladderRows(C)) {
|
|
248
|
-
wl(rung);
|
|
249
|
-
await sleep(30);
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
wl();
|
|
254
|
-
|
|
255
|
-
// Start prompt
|
|
256
|
-
await sleep(skipArt ? 0 : 70);
|
|
257
|
-
wl(` ${B}${AMBER}Start ${PRIMARY}▸${R}`);
|
|
258
|
-
await sleep(40);
|
|
259
|
-
wl(` ${GHOST}Type a command to begin.${R}`);
|
|
260
|
-
await sleep(skipArt ? 0 : 70);
|
|
261
|
-
wl();
|
|
262
|
-
|
|
263
|
-
// HUD — fire probes in parallel
|
|
264
|
-
const probePromise = probeAll({ apiBase, workspaceId, authToken });
|
|
265
|
-
const initStates = { workspace: 'checking', runtime: 'checking', tunnel: 'checking', agent: 'checking' };
|
|
266
|
-
|
|
267
|
-
wl(` ${DIM}${'─'.repeat(W - 4)}${R}`);
|
|
268
|
-
wl();
|
|
269
|
-
w(` ${renderHUDLine(initStates, C)}`);
|
|
270
|
-
wl(); wl();
|
|
271
|
-
wl(` ${DIM}${'─'.repeat(W - 4)}${R}`);
|
|
272
|
-
wl();
|
|
273
|
-
|
|
274
|
-
// Update HUD in-place when probes resolve
|
|
275
|
-
const LINES_BELOW = 4;
|
|
276
|
-
probePromise.then(resolved => {
|
|
277
|
-
w(X.up(LINES_BELOW));
|
|
278
|
-
w(`\r${X.clearLine}`);
|
|
279
|
-
w(` ${renderHUDLine(resolved, C)}`);
|
|
280
|
-
w('\r\n'.repeat(LINES_BELOW));
|
|
281
|
-
w(X.show);
|
|
282
|
-
w(` ${PRIMARY}>${R} `);
|
|
283
|
-
});
|
|
284
|
-
|
|
285
|
-
// Torch flicker is handled via CSS animation on the panel wrapper
|
|
286
|
-
// (terminal-lanes.css) — xterm.js decoration API in Phase 2.
|
|
287
|
-
return () => {};
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
export default { runXtermSplash };
|