agentlas 1.0.46 → 1.0.47
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 +17 -0
- package/README.md +7 -7
- package/engine/agentlas-capabilities.cjs +3 -2
- package/engine/agentlas-core-harness.cjs +18 -0
- package/engine/agentlas-i18n.cjs +8 -8
- package/engine/agentlas-input.cjs +2 -2
- package/engine/agentlas-native-host.cjs +124 -11
- package/engine/agentlas-onboard.cjs +8 -3
- package/engine/agentlas-permissions.cjs +5 -1
- package/engine/agentlas-workforce.cjs +81 -24
- package/engine/agents/router.cjs +4 -2
- package/engine/architecture.data.json +6 -30
- package/engine/automation/daemon.cjs +1 -1
- package/engine/bootstrap-schema.sql +216 -191
- package/engine/browser/cdp.cjs +10 -4
- package/engine/cloud-assets/commands.cjs +1 -1
- package/engine/cloud-assets/package.cjs +161 -45
- package/engine/commands/context.cjs +14 -3
- package/engine/commands/doctor.cjs +7 -4
- package/engine/commands/graph.cjs +46 -54
- package/engine/commands/search.cjs +2 -2
- package/engine/core/desktop-core.cjs +39 -1
- package/engine/graph/interview.cjs +2 -11
- package/engine/graph/vocabulary.generated.cjs +1 -1
- package/engine/hephaestus/runtime.cjs +2 -6
- package/engine/project/memory-context.cjs +20 -7
- package/engine/project/seed.cjs +46 -31
- package/engine/project/state.cjs +8 -1
- package/engine/runtimes/auth-evidence.cjs +6 -0
- package/engine/runtimes/detect.cjs +1 -1
- package/engine/runtimes/resolve.cjs +27 -7
- package/engine/sessions/prompt.cjs +2 -2
- package/engine/ui/palette.cjs +1 -1
- package/engine/ui/repl.cjs +2 -2
- package/engine/ui/shell.cjs +5 -2
- package/engine/workforce/capture.cjs +52 -3
- package/engine/workforce/deps.cjs +2 -2
- package/engine/workforce/local-core-transport.cjs +13 -19
- package/package.json +1 -1
- package/engine/project/super-ontology-seed.json +0 -3288
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.0.47 — 2026-08-14
|
|
4
|
+
|
|
5
|
+
Antigravity and the shared runtime contracts now reach the independent
|
|
6
|
+
Terminal surface.
|
|
7
|
+
|
|
8
|
+
- `agy` is recognized as a first-class runtime in capabilities, detection,
|
|
9
|
+
resolution, permissions, and the interactive shell.
|
|
10
|
+
- Terminal model and runtime choices use the same runtime contract as Desktop,
|
|
11
|
+
including honest no-runtime stops and project-scoped execution.
|
|
12
|
+
- Workforce capture, local Core transport, graph commands, and the native host
|
|
13
|
+
preserve the synchronized Agentlas architecture without copying Desktop-only
|
|
14
|
+
SaaS state into Terminal.
|
|
15
|
+
|
|
16
|
+
Verification: the local smoke suite passed 100 cases with 0 failures. The npm
|
|
17
|
+
publication gate remains the authority for whether this tag is visible in the
|
|
18
|
+
registry.
|
|
19
|
+
|
|
3
20
|
## 1.0.46 — 2026-08-11
|
|
4
21
|
|
|
5
22
|
Pick from a list instead of retyping a slug.
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚══════╝╚═╝ ╚═╝╚══════╝
|
|
10
10
|
```
|
|
11
11
|
|
|
12
|
-
**Agentlas Terminal CLI** — Independent AI agent runtime installed via `npm install -g agentlas` and launched with `agentlas`. Run exact installed agents, teams, and parallel sessions directly from your shell without keeping Desktop open. When Desktop is installed, Terminal reads the same local project, agent, and runtime state. Bring your own model — use
|
|
12
|
+
**Agentlas Terminal CLI** — Independent AI agent runtime installed via `npm install -g agentlas` and launched with `agentlas`. Run exact installed agents, teams, and parallel sessions directly from your shell without keeping Desktop open. When Desktop is installed, Terminal reads the same local project, agent, and runtime state. Bring your own model — use Antigravity (`agy`), Claude Code, Codex, legacy Gemini CLI, or BYOK API keys.
|
|
13
13
|
|
|
14
14
|
Use this existing independent Terminal as the command-line runtime: inspect owner-private packages with `agentlas cloud list`, restore one with `agentlas cloud restore <slug>`, or install an eligible public package with `agentlas install <slug>`.
|
|
15
15
|
|
|
@@ -24,10 +24,10 @@ Agent Trust is our product principle: agent packages are treated as portable, ow
|
|
|
24
24
|
| Category | Requirement |
|
|
25
25
|
| --- | --- |
|
|
26
26
|
| **Node.js** | **Node 22+ recommended.** `package.json` specifies `engines: ">=20"`, but if native optional dependency `better-sqlite3` build fails, the launcher falls back strictly to `node:sqlite` in Node 22+. Node 20 works when `better-sqlite3` native build succeeds. |
|
|
27
|
-
| **Agent CLI** | Requires at least one supported runtime CLI (`claude`, `codex`, or `gemini`
|
|
27
|
+
| **Agent CLI** | Requires at least one supported runtime CLI: `agy` (Antigravity, preferred), `claude`, `codex`, or legacy `gemini` in your `PATH`. Halts honestly with `no_runtime` if none are found (no fake model responses). |
|
|
28
28
|
| **OS** | macOS is verified by the current local release gate. Linux is covered by the public adapter/CI contract. A Windows launcher is provided, but this release does not claim independent end-to-end Windows verification. |
|
|
29
29
|
|
|
30
|
-
*Note: `kimi`, `grok`, and `cursor-agent` are detected by diagnostics (`doctor`) but not yet executable (`has no v2 streaming driver yet`). Supported active runtimes are `claude-code`, `codex`, and `gemini`.*
|
|
30
|
+
*Note: `kimi`, `grok`, and `cursor-agent` are detected by diagnostics (`doctor`) but not yet executable (`has no v2 streaming driver yet`). Supported active runtimes are `claude-code`, `codex`, `agy` (Antigravity), and legacy `gemini`.*
|
|
31
31
|
|
|
32
32
|
## Installation
|
|
33
33
|
|
|
@@ -143,7 +143,7 @@ agentlas netadmin <sub> # Local network administration (init|status|re
|
|
|
143
143
|
agentlas version | help
|
|
144
144
|
```
|
|
145
145
|
|
|
146
|
-
Common flags across subcommands: `-p|--print`, `--runtime claude-code|codex|gemini`, `--permission read|write|full`.
|
|
146
|
+
Common flags across subcommands: `-p|--print`, `--runtime claude-code|codex|agy|gemini`, `--permission read|write|full`.
|
|
147
147
|
|
|
148
148
|
### Typo Guard & Desktop Surface Redirection
|
|
149
149
|
|
|
@@ -183,7 +183,7 @@ Executing `agentlas` with no arguments resolves the current folder to an Agentla
|
|
|
183
183
|
| `/agents` · `/list` | List installed agents |
|
|
184
184
|
| `/mcp` | List active MCP servers |
|
|
185
185
|
| `/doctor` | Run runtime & database diagnostics |
|
|
186
|
-
| `/runtime <kind>` | Set runtime for new sessions (`claude-code` \| `codex` \| `gemini`) |
|
|
186
|
+
| `/runtime <kind>` | Set runtime for new sessions (`claude-code` \| `codex` \| `agy` (Antigravity) \| legacy `gemini`) |
|
|
187
187
|
| `/permission <level>` | Set permission level for new sessions (`read` \| `write` \| `full`) |
|
|
188
188
|
| `/quit` · `/exit` | Exit REPL |
|
|
189
189
|
|
|
@@ -276,8 +276,8 @@ agentlas doctor # Checks database, PATH runtimes, active CLI drivers, and c
|
|
|
276
276
|
agentlas --where # Outputs JSON diagnostic of launcher, engine, DB paths, driver, and Node version
|
|
277
277
|
```
|
|
278
278
|
|
|
279
|
-
- **`no_runtime: no agent CLI found`**:
|
|
280
|
-
- **`runtime '<kind>' has no v2 streaming driver yet`**: Specified `--runtime` is not supported for active execution. Supported values: `claude-code`, `codex`, `gemini
|
|
279
|
+
- **`no_runtime: no agent CLI found`**: Connect Antigravity and put `agy` on `PATH` first, or install `claude`/`codex`; `gemini` remains available as a legacy CLI. Note that `kimi`/`grok`/`cursor-agent` are detected by `doctor` but do not yet have streaming execution drivers.
|
|
280
|
+
- **`runtime '<kind>' has no v2 streaming driver yet`**: Specified `--runtime` is not supported for active execution. Supported values: `claude-code`, `codex`, `agy` (Antigravity), `gemini` (legacy).
|
|
281
281
|
- **`Node vX — Node 22+ (node:sqlite) is required when better-sqlite3 is unavailable`**: `better-sqlite3` native build failed on Node 20/21. Upgrade to Node 22+ or install build tools for native compilation.
|
|
282
282
|
- **`storm`/`context`/`hep` halting due to missing runtime**: Agentlas OS core runtime is missing. Install Agentlas OS or set `HEPHAESTUS_BIN=<path>`.
|
|
283
283
|
- **`'xxx' is not an agentlas command`**: Typo guard intercepted an unrecognized command. Use `agentlas run -p "xxx"` to run it as a prompt.
|
|
@@ -15,6 +15,7 @@ const RUNTIME_CAPS = {
|
|
|
15
15
|
"claude-code": { code: true, image: false, label: "claude" },
|
|
16
16
|
codex: { code: true, image: true, label: "codex" }, // Imagen
|
|
17
17
|
gemini: { code: true, image: true, label: "gemini" }, // nano-banana
|
|
18
|
+
agy: { code: true, image: true, label: "antigravity" },
|
|
18
19
|
grok: { code: true, image: true, label: "grok" }, // Grok Imagine (generate_image/generate_video, 구독 키리스)
|
|
19
20
|
anthropic: { code: true, image: false, label: "anthropic" },
|
|
20
21
|
openai: { code: true, image: true, label: "openai" }, // gpt-image
|
|
@@ -25,7 +26,7 @@ const RUNTIME_CAPS = {
|
|
|
25
26
|
|
|
26
27
|
// NOTE: grok은 CAPS(멀티모달 능력 인지)만 등록 — 터미널 스폰 러너(RUNTIME_BIN)가 아직 없어
|
|
27
28
|
// CLI_KINDS에 넣으면 repl의 which(RUNTIME_BIN[k]) 탐지가 깨진다. 러너 추가 시 함께 확장할 것.
|
|
28
|
-
const CLI_KINDS = ["claude-code", "codex", "gemini"];
|
|
29
|
+
const CLI_KINDS = ["claude-code", "codex", "agy", "gemini"];
|
|
29
30
|
|
|
30
31
|
function capsFor(spec) {
|
|
31
32
|
return RUNTIME_CAPS[spec] || { code: true, image: false, label: spec || "?" };
|
|
@@ -115,7 +116,7 @@ function clearImageJudgments() {
|
|
|
115
116
|
function autoRuntimeFor(agent, { installedKinds, activeSpec }) {
|
|
116
117
|
if (needsImage(agent)) {
|
|
117
118
|
if (capsFor(activeSpec).image) return activeSpec;
|
|
118
|
-
for (const k of ["gemini", "codex"]) if ((installedKinds || []).includes(k)) return k;
|
|
119
|
+
for (const k of ["agy", "gemini", "codex"]) if ((installedKinds || []).includes(k)) return k;
|
|
119
120
|
}
|
|
120
121
|
return activeSpec;
|
|
121
122
|
}
|
|
@@ -17,6 +17,10 @@ const CORE_RUNTIME_MARKERS = [
|
|
|
17
17
|
["schemas", "workforce-work-order.schema.json"],
|
|
18
18
|
["schemas", "workforce-selection.schema.json"],
|
|
19
19
|
];
|
|
20
|
+
const CONTEXT_MAP_V3_RUNTIME_MARKERS = [
|
|
21
|
+
["agentlas_cloud", "project_bootstrap.py"],
|
|
22
|
+
["schemas", "context-index-policy.schema.json"],
|
|
23
|
+
];
|
|
20
24
|
|
|
21
25
|
const PY_BOOTSTRAP =
|
|
22
26
|
"import os, runpy, sys; " +
|
|
@@ -116,6 +120,18 @@ function resolveCoreRuntimeRoot(explicitRoot, requiredMarkers = [], options = {}
|
|
|
116
120
|
return resolveCoreRuntimeRootFromCandidates(runtimeRoots(explicitRoot), requiredMarkers, options);
|
|
117
121
|
}
|
|
118
122
|
|
|
123
|
+
// Context Map is a versioned Core capability. Every Terminal caller that
|
|
124
|
+
// injects a slice must use the same marker and minimum-version gate as the
|
|
125
|
+
// explicit `agentlas context` command; otherwise a stale runtime can silently
|
|
126
|
+
// supply a pre-v3 map to prompts, memory, or Workforce.
|
|
127
|
+
function resolveContextMapCoreRoot(explicitRoot) {
|
|
128
|
+
return resolveCoreRuntimeRoot(
|
|
129
|
+
explicitRoot,
|
|
130
|
+
CONTEXT_MAP_V3_RUNTIME_MARKERS,
|
|
131
|
+
{ minVersion: CONTEXT_MAP_MIN_CORE_VERSION },
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
|
|
119
135
|
function pythonCandidates() {
|
|
120
136
|
return [...new Set([
|
|
121
137
|
process.env.HEPHAESTUS_PYTHON,
|
|
@@ -262,10 +278,12 @@ module.exports = {
|
|
|
262
278
|
HARNESS_ID,
|
|
263
279
|
HARNESS_MODE,
|
|
264
280
|
CONTEXT_MAP_MIN_CORE_VERSION,
|
|
281
|
+
CONTEXT_MAP_V3_RUNTIME_MARKERS,
|
|
265
282
|
PY_BOOTSTRAP,
|
|
266
283
|
readCoreRuntimeVersion,
|
|
267
284
|
resolveCoreRuntimeRootFromCandidates,
|
|
268
285
|
resolveCoreRuntimeRoot,
|
|
286
|
+
resolveContextMapCoreRoot,
|
|
269
287
|
resolvePython,
|
|
270
288
|
spawnCoreModule,
|
|
271
289
|
parseJsonOutput,
|
package/engine/agentlas-i18n.cjs
CHANGED
|
@@ -62,9 +62,9 @@ const STRINGS = {
|
|
|
62
62
|
"noKey": "No %s API key. Add one in the app (Settings → BYOK), or switch with /runtime.",
|
|
63
63
|
"runtimeSet": "runtime → %s",
|
|
64
64
|
"runtimeNotInstalled": "%s CLI is not installed.",
|
|
65
|
-
"runtimeUnknown": "Unknown runtime: %s (claude-code|codex|gemini)",
|
|
66
|
-
"runtimeUnavailable": "No runtime is available. Install a CLI (claude/codex/gemini) or configure an API key/Ollama in the app.",
|
|
67
|
-
"runtimeUsage": "usage: /runtime claude-code|codex|gemini|anthropic|openai|google|ollama|upstage",
|
|
65
|
+
"runtimeUnknown": "Unknown runtime: %s (claude-code|codex|agy|gemini)",
|
|
66
|
+
"runtimeUnavailable": "No runtime is available. Install a CLI (claude/codex/agy; legacy gemini is supported) or configure an API key/Ollama in the app.",
|
|
67
|
+
"runtimeUsage": "usage: /runtime claude-code|codex|agy|gemini|anthropic|openai|google|ollama|upstage",
|
|
68
68
|
"modelOnlyApi": "/model only applies to BYOK/Ollama (api) runtimes.",
|
|
69
69
|
"modelSet": "model → %s",
|
|
70
70
|
"modelCurrent": "current model: %s",
|
|
@@ -166,7 +166,7 @@ const STRINGS = {
|
|
|
166
166
|
"help.team": "view/assign each agent's LLM (auto-routed by capability)",
|
|
167
167
|
"help.agent": "switch to another agent",
|
|
168
168
|
"help.firms": "list companies / switch to one",
|
|
169
|
-
"help.runtime": "switch runtime (claude-code|codex|gemini|anthropic|openai|google|ollama|upstage)",
|
|
169
|
+
"help.runtime": "switch runtime (claude-code|codex|agy|legacy gemini|anthropic|openai|google|ollama|upstage)",
|
|
170
170
|
"help.model": "set the model (claude/codex/gemini alias or BYOK/Ollama id)",
|
|
171
171
|
"help.effort": "set reasoning effort (low|medium|high|max|off|auto)",
|
|
172
172
|
"help.permission": "what it may do (read|write|full)",
|
|
@@ -311,9 +311,9 @@ const STRINGS = {
|
|
|
311
311
|
"noKey": "%s API 키가 없습니다. 앱 설정 → BYOK에서 등록하거나 /runtime으로 전환하세요.",
|
|
312
312
|
"runtimeSet": "런타임 → %s",
|
|
313
313
|
"runtimeNotInstalled": "%s CLI가 설치돼 있지 않습니다.",
|
|
314
|
-
"runtimeUnknown": "알 수 없는 런타임: %s (claude-code|codex|gemini)",
|
|
315
|
-
"runtimeUnavailable": "사용 가능한 런타임이 없습니다. CLI(claude/codex/gemini)를 설치하거나 앱에서 API 키/Ollama를 설정하세요.",
|
|
316
|
-
"runtimeUsage": "사용법: /runtime claude-code|codex|gemini|anthropic|openai|google|ollama|upstage",
|
|
314
|
+
"runtimeUnknown": "알 수 없는 런타임: %s (claude-code|codex|agy|gemini)",
|
|
315
|
+
"runtimeUnavailable": "사용 가능한 런타임이 없습니다. CLI(claude/codex/agy, 레거시 gemini 지원)를 설치하거나 앱에서 API 키/Ollama를 설정하세요.",
|
|
316
|
+
"runtimeUsage": "사용법: /runtime claude-code|codex|agy|gemini|anthropic|openai|google|ollama|upstage",
|
|
317
317
|
"modelOnlyApi": "/model은 BYOK/Ollama(api) 런타임에서만 적용됩니다.",
|
|
318
318
|
"modelSet": "모델 → %s",
|
|
319
319
|
"modelCurrent": "현재 모델: %s",
|
|
@@ -414,7 +414,7 @@ const STRINGS = {
|
|
|
414
414
|
"help.team": "에이전트별 LLM 보기/지정 (능력 기반 자동)",
|
|
415
415
|
"help.agent": "다른 에이전트로 전환",
|
|
416
416
|
"help.firms": "회사 목록 / 전환",
|
|
417
|
-
"help.runtime": "런타임 전환 (claude-code|codex|gemini|anthropic|openai|google|ollama|upstage)",
|
|
417
|
+
"help.runtime": "런타임 전환 (claude-code|codex|agy|레거시 gemini|anthropic|openai|google|ollama|upstage)",
|
|
418
418
|
"help.model": "모델 지정 (claude/codex/gemini 별칭 또는 BYOK/Ollama id)",
|
|
419
419
|
"help.effort": "추론 강도 지정 (low|medium|high|max|off|auto)",
|
|
420
420
|
"help.permission": "허용 범위 (read|write|full)",
|
|
@@ -270,7 +270,7 @@ const SLASH_COMMAND_META = [
|
|
|
270
270
|
{ command: "/agent", description: "Switch to another agent", category: "Routing", usage: "/agent <name>", detail: "Switch the current conversation to an installed agent." },
|
|
271
271
|
{ command: "/firms", description: "List installed companies", category: "Routing", usage: "/firms", detail: "Show company CEOs available in this terminal." },
|
|
272
272
|
{ command: "/firm", description: "Switch to a company CEO", category: "Routing", usage: "/firm <name>", detail: "Switch the current conversation to a company CEO agent." },
|
|
273
|
-
{ command: "/runtime", description: "Switch runtime: claude-code, codex, gemini, BYOK, or Ollama", category: "Settings", usage: "/runtime
|
|
273
|
+
{ command: "/runtime", description: "Switch runtime: claude-code, codex, agy, legacy gemini, BYOK, or Ollama", category: "Settings", usage: "/runtime agy", detail: "Change the engine Agentlas uses for subsequent turns." },
|
|
274
274
|
{ command: "/model", description: "Pin a model or return to auto allocation", category: "Settings", usage: "/model <id|auto>", detail: "An id is an explicit session pin; auto lets the higher-level allocator choose a provider-compatible tier." },
|
|
275
275
|
{ command: "/effort", description: "Pin reasoning effort or return to auto", category: "Settings", usage: "/effort low|medium|high|max|off|auto", detail: "A level is an explicit pin; auto lets the higher-level allocator choose per task; off is an explicit no-effort pin." },
|
|
276
276
|
{ command: "/permission", description: "Set read/write/full permission", category: "Settings", usage: "/permission full", detail: "No argument shows what read, write, and full mean.", aliases: ["/perm"] },
|
|
@@ -306,7 +306,7 @@ const SLASH_COMMAND_META = [
|
|
|
306
306
|
{ command: "/exit", description: "Quit Agentlas", category: "Session", usage: "/exit", detail: "Close the terminal session.", aliases: ["/quit"] },
|
|
307
307
|
];
|
|
308
308
|
const SLASH_COMMANDS = SLASH_COMMAND_META.flatMap((entry) => [entry.command].concat(entry.aliases || []));
|
|
309
|
-
const RUNTIME_SPECS = ["claude-code", "codex", "gemini", "anthropic", "openai", "google", "ollama", "upstage"];
|
|
309
|
+
const RUNTIME_SPECS = ["claude-code", "codex", "agy", "gemini", "anthropic", "openai", "google", "ollama", "upstage"];
|
|
310
310
|
const PERM_LEVELS = ["read", "write", "full"];
|
|
311
311
|
|
|
312
312
|
const HELP_KEY_BY_COMMAND = {
|
|
@@ -700,6 +700,118 @@ function geminiArgs({ prompt, systemPrompt, permission, model, mcpServers, mcpAl
|
|
|
700
700
|
];
|
|
701
701
|
}
|
|
702
702
|
|
|
703
|
+
function agyPermissionArgs(permission) {
|
|
704
|
+
const level = permissions.normalize(permission);
|
|
705
|
+
if (level === "full") return ["--dangerously-skip-permissions"];
|
|
706
|
+
return [
|
|
707
|
+
"--mode", level === "write" ? "accept-edits" : "plan",
|
|
708
|
+
"--sandbox",
|
|
709
|
+
];
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
function agyArgs({ prompt, systemPrompt, permission, model, addDirectories = [] }) {
|
|
713
|
+
const body = systemPrompt ? `${systemPrompt}\n\n---\n\n${prompt}` : prompt;
|
|
714
|
+
return [
|
|
715
|
+
...(model ? ["--model", model] : []),
|
|
716
|
+
...[...new Set(addDirectories.filter(Boolean))].flatMap((dir) => ["--add-dir", dir]),
|
|
717
|
+
...agyPermissionArgs(permission),
|
|
718
|
+
"--output-format", "stream-json",
|
|
719
|
+
"--print-timeout", "30m",
|
|
720
|
+
"--prompt", body,
|
|
721
|
+
];
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
const AGY_WINDOWS_ARGV_PROMPT_LIMIT = 6_000;
|
|
725
|
+
|
|
726
|
+
function agyPromptBootstrap(promptFile) {
|
|
727
|
+
return `Read the complete Agentlas request from ${JSON.stringify(promptFile)}, follow it exactly, and do not reveal the file path.`;
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
/**
|
|
731
|
+
* Windows npm CLI shims pass through cmd.exe's much smaller command-line
|
|
732
|
+
* ceiling. Move only oversized agy prompts into a private one-shot file and
|
|
733
|
+
* keep argv limited to a short bootstrap. The caller owns cleanup and must run
|
|
734
|
+
* it on every process terminal path (close, spawn error, timeout, and abort).
|
|
735
|
+
*/
|
|
736
|
+
function prepareAgyLaunch(request, options = {}) {
|
|
737
|
+
const body = request.systemPrompt
|
|
738
|
+
? `${request.systemPrompt}\n\n---\n\n${request.prompt}`
|
|
739
|
+
: request.prompt;
|
|
740
|
+
const platform = options.platform || process.platform;
|
|
741
|
+
const promptLimit = Number.isFinite(options.promptLimit)
|
|
742
|
+
? Math.max(1, Math.trunc(options.promptLimit))
|
|
743
|
+
: AGY_WINDOWS_ARGV_PROMPT_LIMIT;
|
|
744
|
+
if (platform !== "win32" || body.length <= promptLimit) {
|
|
745
|
+
return { args: agyArgs(request), promptFile: null, cleanup: () => {} };
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
let directory = null;
|
|
749
|
+
try {
|
|
750
|
+
directory = fs.mkdtempSync(path.join(os.tmpdir(), "agentlas-agy-prompt-"));
|
|
751
|
+
try { fs.chmodSync(directory, 0o700); } catch { /* Windows/best-effort */ }
|
|
752
|
+
const promptFile = path.join(directory, "request.txt");
|
|
753
|
+
fs.writeFileSync(promptFile, body, { encoding: "utf8", mode: 0o600, flag: "wx" });
|
|
754
|
+
try { fs.chmodSync(promptFile, 0o600); } catch { /* Windows/best-effort */ }
|
|
755
|
+
let cleaned = false;
|
|
756
|
+
return {
|
|
757
|
+
args: agyArgs({
|
|
758
|
+
...request,
|
|
759
|
+
systemPrompt: "",
|
|
760
|
+
prompt: agyPromptBootstrap(promptFile),
|
|
761
|
+
addDirectories: [directory, ...(request.addDirectories || [])],
|
|
762
|
+
}),
|
|
763
|
+
promptFile,
|
|
764
|
+
cleanup: () => {
|
|
765
|
+
if (cleaned) return;
|
|
766
|
+
cleaned = true;
|
|
767
|
+
try { fs.rmSync(directory, { recursive: true, force: true }); } catch { /* OS temp cleanup fallback */ }
|
|
768
|
+
},
|
|
769
|
+
};
|
|
770
|
+
} catch (error) {
|
|
771
|
+
if (directory) {
|
|
772
|
+
try { fs.rmSync(directory, { recursive: true, force: true }); } catch { /* best-effort */ }
|
|
773
|
+
}
|
|
774
|
+
throw error;
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
function handleAgyLine(line, st, ui) {
|
|
779
|
+
let obj;
|
|
780
|
+
try { obj = JSON.parse(line); } catch { return; }
|
|
781
|
+
if (obj.event === "result") {
|
|
782
|
+
if (st.geminiStreaming) { ui.streamEnd(); st.geminiStreaming = false; }
|
|
783
|
+
if (obj.result && typeof obj.result.response === "string") st.finalText = obj.result.response;
|
|
784
|
+
if (obj.result?.status && !["success", "completed", "done"].includes(String(obj.result.status).toLowerCase())) {
|
|
785
|
+
st.error = `agy ${obj.result.status}`;
|
|
786
|
+
st.errorKind = "exit";
|
|
787
|
+
st.errorSource = "marker";
|
|
788
|
+
}
|
|
789
|
+
return;
|
|
790
|
+
}
|
|
791
|
+
if (obj.event !== "step_update" || !obj.step_update) {
|
|
792
|
+
if (obj.event) ui.status(`agy: ${obj.event}`);
|
|
793
|
+
return;
|
|
794
|
+
}
|
|
795
|
+
const step = obj.step_update;
|
|
796
|
+
if (step.usage) {
|
|
797
|
+
st.usage = {
|
|
798
|
+
input_tokens: step.usage.input_tokens,
|
|
799
|
+
output_tokens: step.usage.output_tokens,
|
|
800
|
+
...(step.usage.duration_ms != null ? { duration_ms: step.usage.duration_ms } : {}),
|
|
801
|
+
};
|
|
802
|
+
}
|
|
803
|
+
if (step.step_type === "agent_response") {
|
|
804
|
+
const delta = typeof step.text_delta === "string" ? step.text_delta : "";
|
|
805
|
+
if (!delta) return;
|
|
806
|
+
if (!st.geminiStreaming) { ui.streamStart(); st.geminiStreaming = true; }
|
|
807
|
+
ui.streamDelta(delta);
|
|
808
|
+
st.text += delta;
|
|
809
|
+
return;
|
|
810
|
+
}
|
|
811
|
+
if (st.geminiStreaming) { ui.streamEnd(); st.geminiStreaming = false; }
|
|
812
|
+
ui.status(`agy: ${step.step_type || "step"}${step.state ? ` (${step.state})` : ""}`);
|
|
813
|
+
}
|
|
814
|
+
|
|
703
815
|
// gemini 툴명 → 친숙한 표시명 (claude/codex 표기와 통일)
|
|
704
816
|
const GEMINI_TOOL_NAMES = {
|
|
705
817
|
run_shell_command: "Bash",
|
|
@@ -829,6 +941,7 @@ function runNativeTurn(req) {
|
|
|
829
941
|
let args;
|
|
830
942
|
let lineHandler;
|
|
831
943
|
let plainStream = false;
|
|
944
|
+
let launchCleanup = () => {};
|
|
832
945
|
try {
|
|
833
946
|
if (kind === "claude-code") {
|
|
834
947
|
args = claudeArgs(launchReq);
|
|
@@ -840,17 +953,10 @@ function runNativeTurn(req) {
|
|
|
840
953
|
args = geminiArgs(launchReq);
|
|
841
954
|
lineHandler = (l) => handleGeminiLine(l, st, ui);
|
|
842
955
|
} else if (kind === "agy") {
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
*/
|
|
848
|
-
const agyPrompt = launchReq.systemPrompt
|
|
849
|
-
? `${launchReq.systemPrompt}\n\n---\n\n${launchReq.prompt}`
|
|
850
|
-
: launchReq.prompt;
|
|
851
|
-
args = ["--print", agyPrompt, ...(launchReq.model ? ["--model", launchReq.model] : [])];
|
|
852
|
-
plainStream = true;
|
|
853
|
-
lineHandler = null;
|
|
956
|
+
const prepared = prepareAgyLaunch(launchReq);
|
|
957
|
+
args = prepared.args;
|
|
958
|
+
launchCleanup = prepared.cleanup;
|
|
959
|
+
lineHandler = (l) => handleAgyLine(l, st, ui);
|
|
854
960
|
} else {
|
|
855
961
|
return Promise.resolve({ text: "", session: st.session, error: `unknown runtime: ${kind}`, errorKind: "unsupported", errorSource: "marker" });
|
|
856
962
|
}
|
|
@@ -885,6 +991,7 @@ function runNativeTurn(req) {
|
|
|
885
991
|
try { req.onSpawn(child); } catch { /* observer 실패가 턴을 죽이면 안 됨 */ }
|
|
886
992
|
}
|
|
887
993
|
} catch (e) {
|
|
994
|
+
launchCleanup();
|
|
888
995
|
ui.error(uiText(ui, "runtime.failed", kind, e.message));
|
|
889
996
|
return resolve({ text: "", session: st.session, error: e.message });
|
|
890
997
|
}
|
|
@@ -911,6 +1018,7 @@ function runNativeTurn(req) {
|
|
|
911
1018
|
removeLineReader();
|
|
912
1019
|
child.stderr?.removeListener("data", onStderr);
|
|
913
1020
|
if (req.signal) req.signal.removeEventListener?.("abort", onAbort);
|
|
1021
|
+
launchCleanup();
|
|
914
1022
|
};
|
|
915
1023
|
const finish = (result) => {
|
|
916
1024
|
if (settled) return;
|
|
@@ -1212,6 +1320,11 @@ module.exports = {
|
|
|
1212
1320
|
codexPermissionArgs,
|
|
1213
1321
|
geminiArgs,
|
|
1214
1322
|
geminiPermissionArgs,
|
|
1323
|
+
agyArgs,
|
|
1324
|
+
agyPermissionArgs,
|
|
1325
|
+
agyPromptBootstrap,
|
|
1326
|
+
prepareAgyLaunch,
|
|
1327
|
+
handleAgyLine,
|
|
1215
1328
|
claudeMcpIsolationArgs,
|
|
1216
1329
|
geminiMcpIsolationArgs,
|
|
1217
1330
|
prepareCodexRuntimeEnv,
|
|
@@ -133,11 +133,12 @@ async function runOnboard({ ui, rl, helpers, persist }) {
|
|
|
133
133
|
// Step 2 — default runtime
|
|
134
134
|
ui.line("");
|
|
135
135
|
printIndented(ui.t("wiz.runtimeQ"), c.bold);
|
|
136
|
-
const cliKinds = ["claude-code", "codex", "gemini"];
|
|
136
|
+
const cliKinds = ["claude-code", "codex", "agy", "gemini"];
|
|
137
137
|
const rtOpts = [{ value: "auto", label: ui.t("wiz.runtimeAuto") }];
|
|
138
138
|
for (const k of cliKinds) {
|
|
139
139
|
const has = !!H.which(H.RUNTIME_BIN[k]);
|
|
140
|
-
|
|
140
|
+
const runtimeLabel = k === "agy" ? "agy · Antigravity" : k === "gemini" ? "gemini · legacy" : k;
|
|
141
|
+
rtOpts.push({ value: k, label: `${runtimeLabel} (${has ? ui.t("wiz.runtimeInstalled") : ui.t("wiz.runtimeMissing")})` });
|
|
141
142
|
}
|
|
142
143
|
rtOpts.forEach((o, i) => optionLine(i + 1, o.label, i === 0));
|
|
143
144
|
const ri = await pickNum(rtOpts.length);
|
|
@@ -149,6 +150,7 @@ async function runOnboard({ ui, rl, helpers, persist }) {
|
|
|
149
150
|
const installHint = {
|
|
150
151
|
"claude-code": "npm i -g @anthropic-ai/claude-code",
|
|
151
152
|
codex: "npm i -g @openai/codex",
|
|
153
|
+
agy: "Install Antigravity from https://antigravity.google/ and put agy on PATH",
|
|
152
154
|
gemini: "npm i -g @google/gemini-cli",
|
|
153
155
|
}[runtime];
|
|
154
156
|
if (!H.which(H.RUNTIME_BIN[runtime])) {
|
|
@@ -156,7 +158,10 @@ async function runOnboard({ ui, rl, helpers, persist }) {
|
|
|
156
158
|
} else {
|
|
157
159
|
try {
|
|
158
160
|
const { runtimeAuthEvidence } = require("./runtimes/auth-evidence.cjs");
|
|
159
|
-
|
|
161
|
+
// Antigravity and legacy Gemini currently share Google's local OAuth
|
|
162
|
+
// evidence root, but remain distinct executable/runtime selections.
|
|
163
|
+
const evidenceKind = runtime === "agy" ? "gemini" : runtime;
|
|
164
|
+
if (runtimeAuthEvidence(evidenceKind).status === "none") {
|
|
160
165
|
printIndented(ui.t("wiz.runtimeLoginHint", H.RUNTIME_BIN[runtime]), c.dim);
|
|
161
166
|
}
|
|
162
167
|
} catch { /* evidence unavailable — say nothing rather than guess */ }
|
|
@@ -9,6 +9,10 @@
|
|
|
9
9
|
|
|
10
10
|
const LEVELS = ["read", "write", "full"];
|
|
11
11
|
|
|
12
|
+
function isLevel(value) {
|
|
13
|
+
return LEVELS.includes(String(value || "").trim().toLowerCase());
|
|
14
|
+
}
|
|
15
|
+
|
|
12
16
|
const COPY = {
|
|
13
17
|
en: {
|
|
14
18
|
read: {
|
|
@@ -94,4 +98,4 @@ function createCycleController(options = {}) {
|
|
|
94
98
|
};
|
|
95
99
|
}
|
|
96
100
|
|
|
97
|
-
module.exports = { LEVELS, normalize, persistent, next, copy, createCycleController };
|
|
101
|
+
module.exports = { LEVELS, isLevel, normalize, persistent, next, copy, createCycleController };
|