@agenit/cli 2.1.0 → 2.1.2
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 +149 -0
- package/cli.js +63177 -40802
- package/config/flow.toml +64 -3
- package/config/recipes.toml +60 -0
- package/control/api.mjs +32 -3
- package/control/app.mjs +5 -0
- package/control/panels/Debug.mjs +681 -0
- package/control/shell/LeftNav.mjs +1 -0
- package/control/style.css +138 -0
- package/package.json +1 -1
package/config/flow.toml
CHANGED
|
@@ -4,8 +4,17 @@
|
|
|
4
4
|
# /opt/homebrew/bin on macOS, /usr/local/bin on Linux, %APPDATA%\npm on
|
|
5
5
|
# Windows). Set an absolute path only if you need to pin a specific install.
|
|
6
6
|
binary = "gemini"
|
|
7
|
-
# Model override —
|
|
8
|
-
|
|
7
|
+
# Model override — pinned to 2.5-pro to avoid 2.5-flash's RESOURCE_EXHAUSTED on the free OAuth pool.
|
|
8
|
+
model = "gemini-2.5-pro"
|
|
9
|
+
# Fallback model — used for one transparent retry when the primary model
|
|
10
|
+
# returns HTTP 429 / "No capacity available". A one-line warning is
|
|
11
|
+
# printed to stderr when this fires. Unset or equal-to-`model` disables.
|
|
12
|
+
fallback_model = "gemini-2.5-flash"
|
|
13
|
+
# Per-request wall-clock timeout in seconds. Caps gemini-cli's internal
|
|
14
|
+
# retry-on-429 hangs (which can otherwise run 3+ minutes silently). On
|
|
15
|
+
# timeout the spawned process is killed and the fallback retry path
|
|
16
|
+
# triggers. Default 90s. Set to 0 to disable.
|
|
17
|
+
request_timeout_secs = 90
|
|
9
18
|
# Working dir handed to the spawned Gemini-CLI as cwd. Resolved against the
|
|
10
19
|
# directory the user invoked `agenit` from (NOT the directory holding this
|
|
11
20
|
# file). Leave unset (or "." ) to follow the user's project — every
|
|
@@ -266,7 +275,7 @@ cooldown_ms = 30000
|
|
|
266
275
|
# requirements}.md`. Markdown stays the source of truth; mempalace is the
|
|
267
276
|
# optional accelerator. When `enabled = false` (default), `/req` and `/arch`
|
|
268
277
|
# stages run identically to today and `/mempalace` prints a one-liner pointing
|
|
269
|
-
# at
|
|
278
|
+
# at docs/integrations/mempalace.md. Install with `pip install mempalace`.
|
|
270
279
|
#
|
|
271
280
|
# Override the master switch at runtime with the AGENIT_MEMPALACE env var
|
|
272
281
|
# ("1"/"true" → on; "0"/"false" → off; anything else falls through to this
|
|
@@ -394,3 +403,55 @@ tier = "smart"
|
|
|
394
403
|
# Don't summarize sessions shorter than this — trivial sessions
|
|
395
404
|
# (lookup, /exit) don't yield durable signal.
|
|
396
405
|
min_turns = 3
|
|
406
|
+
|
|
407
|
+
# ─── Session resume strategy (#95/#114) ─────────────────────────────────────
|
|
408
|
+
# When resuming a session with >= this many turns, show the Resume
|
|
409
|
+
# Strategy Modal (F = full history, S = summary, Esc = cancel).
|
|
410
|
+
# Set to -1 to always load full history. Set to 0 to always show modal.
|
|
411
|
+
# resume_summary_threshold = 20
|
|
412
|
+
|
|
413
|
+
# ─── Agile persona layer (#99-#111) ─────────────────────────────────────────
|
|
414
|
+
# Set enabled = true to activate the Agile management crew.
|
|
415
|
+
# When false (default), the entire Agile layer is dormant — zero
|
|
416
|
+
# impact on V-Model commands (/swe1–/swe5, /goal, /qa, /audit).
|
|
417
|
+
[agile]
|
|
418
|
+
enabled = false
|
|
419
|
+
mode = "scrum" # "scrum" | "kanban" | "hybrid"
|
|
420
|
+
|
|
421
|
+
[agile.cadence]
|
|
422
|
+
sprint_length_days = 14
|
|
423
|
+
standup_every_turns = 10
|
|
424
|
+
blocker_threshold = 5
|
|
425
|
+
escalation_threshold = 15
|
|
426
|
+
auto_next_sprint = true
|
|
427
|
+
|
|
428
|
+
[agile.relay]
|
|
429
|
+
channels = ["repl", "telegram", "file"]
|
|
430
|
+
human_gate_timeout_hours = 24
|
|
431
|
+
|
|
432
|
+
# Each persona: "agent" (autonomous) | "human" (relay gate) | "off"
|
|
433
|
+
[personas]
|
|
434
|
+
product_owner = "agent"
|
|
435
|
+
customer = "agent"
|
|
436
|
+
scrum_master = "agent"
|
|
437
|
+
project_manager = "human"
|
|
438
|
+
pmo = "human"
|
|
439
|
+
|
|
440
|
+
# ─── OPA Engine (#100-#103) ─────────────────────────────────────────────────
|
|
441
|
+
# Organizational Process Assets — policies, templates, historical lessons.
|
|
442
|
+
# When false (default), no OPA files are read and no context injection occurs.
|
|
443
|
+
[opa]
|
|
444
|
+
enabled = false
|
|
445
|
+
processes = true
|
|
446
|
+
templates = true
|
|
447
|
+
lessons = true
|
|
448
|
+
max_injection_tokens = 2000
|
|
449
|
+
mode = "agile" # "agile" = advisory gates; "traditional" = blocking
|
|
450
|
+
|
|
451
|
+
# ─── /qa command (#97) ──────────────────────────────────────────────────────
|
|
452
|
+
# Static checks run in Phase 2 deliverable verification.
|
|
453
|
+
[qa]
|
|
454
|
+
# checks = ["tsc --noEmit", "eslint src/", "pytest"]
|
|
455
|
+
checks = []
|
|
456
|
+
tier = "smart"
|
|
457
|
+
save_report = true
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Cross-widget orchestration recipes.
|
|
2
|
+
#
|
|
3
|
+
# Each `[[recipe]]` block declares a trigger (`when`) and an ordered
|
|
4
|
+
# list of actions to run. The Recipes widget in the TUI shows live
|
|
5
|
+
# fires; press `t` on a selected recipe to test-fire with synthetic
|
|
6
|
+
# payload, `p` to enable/disable.
|
|
7
|
+
#
|
|
8
|
+
# Available triggers:
|
|
9
|
+
# - "hw.probe.failed" (a hardware probe returned non-zero)
|
|
10
|
+
# - "hw.probe.ok" (probe succeeded after a prior failure)
|
|
11
|
+
# - "goal.tick.failed" (a /goal tick was blocked)
|
|
12
|
+
# - "goal.tick.complete" (a /goal tick succeeded)
|
|
13
|
+
# - "agent.failed" (squad helper / goal tick failed or was killed)
|
|
14
|
+
# - "agent.idle" (agent finished and went ready)
|
|
15
|
+
# - "tasks.changed" (tasks.md modified on disk)
|
|
16
|
+
# - "widget.action" (any widget action button pressed)
|
|
17
|
+
#
|
|
18
|
+
# Available actions:
|
|
19
|
+
# - submit-slash { value = "/foo bar" }
|
|
20
|
+
# - system-message { text = "..." }
|
|
21
|
+
# - wait { seconds = N }
|
|
22
|
+
# - tasks.assign { task = "T-04", worker = "implementer" }
|
|
23
|
+
# - tasks.comment { task = "T-04", text = "..." }
|
|
24
|
+
# - tasks.priority { task = "T-04", priority = "P1" } # or P2/P3/null
|
|
25
|
+
# - tasks.add { description = "...", priority = "P1" }
|
|
26
|
+
# - log { level = "info|warn|error", text = "..." }
|
|
27
|
+
#
|
|
28
|
+
# Templates: `{{taskId}}`, `{{agentLabel}}`, etc. are substituted
|
|
29
|
+
# from the triggering event's payload.
|
|
30
|
+
#
|
|
31
|
+
# Guards (per recipe):
|
|
32
|
+
# guard.max_per_hour hard cap on firings; default 6
|
|
33
|
+
# guard.cooldown_seconds minimum gap between firings; default 1
|
|
34
|
+
|
|
35
|
+
[[recipe]]
|
|
36
|
+
name = "log goal failures"
|
|
37
|
+
description = "Whenever a /goal tick gets blocked, emit a system message with the goal id."
|
|
38
|
+
when = "goal.tick.failed"
|
|
39
|
+
do = [
|
|
40
|
+
{ action = "system-message", text = "⚠ goal {{goalId}} blocked at turn {{turn}} — review tasks.md" },
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
[[recipe]]
|
|
44
|
+
name = "escalate to hw-debugger on probe failure"
|
|
45
|
+
description = "Stub recipe — wire when hw.probe.failed event is emitted (Phase: events extension)."
|
|
46
|
+
when = "hw.probe.failed"
|
|
47
|
+
enabled = false
|
|
48
|
+
do = [
|
|
49
|
+
{ action = "log", level = "warn", text = "hardware probe failed — flagging triage tasks" },
|
|
50
|
+
{ action = "tasks.add", description = "Triage probe failure", priority = "P1" },
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
[[recipe]]
|
|
54
|
+
name = "notify when agent fails"
|
|
55
|
+
description = "Surface a system message whenever any agent fails so the dashboard isn't the only signal."
|
|
56
|
+
when = "agent.failed"
|
|
57
|
+
do = [
|
|
58
|
+
{ action = "system-message", text = "✗ agent {{agentLabel}} failed" },
|
|
59
|
+
]
|
|
60
|
+
guard = { max_per_hour = 10, cooldown_seconds = 2 }
|
package/control/api.mjs
CHANGED
|
@@ -4,14 +4,35 @@
|
|
|
4
4
|
//
|
|
5
5
|
// The token (if any) is sourced once from the page URL (?token=…) at
|
|
6
6
|
// load and reused for every subsequent fetch + WS upgrade.
|
|
7
|
+
//
|
|
8
|
+
// VS Code extension host: when the SPA is embedded in a webview the
|
|
9
|
+
// page origin is `vscode-webview://…` (not the daemon). The extension
|
|
10
|
+
// injects `window.__AGENIT_ORIGIN__` and `window.__AGENIT_TOKEN__`
|
|
11
|
+
// before this module loads so requests are routed to the daemon's
|
|
12
|
+
// loopback address regardless of the document's host. Browser usage
|
|
13
|
+
// is unaffected — both globals fall back to `undefined`.
|
|
7
14
|
|
|
8
15
|
const url = new URL(window.location.href);
|
|
9
|
-
|
|
16
|
+
const INJECTED_ORIGIN =
|
|
17
|
+
typeof window !== "undefined" && typeof window.__AGENIT_ORIGIN__ === "string"
|
|
18
|
+
? window.__AGENIT_ORIGIN__.replace(/\/+$/, "")
|
|
19
|
+
: "";
|
|
20
|
+
const INJECTED_TOKEN =
|
|
21
|
+
typeof window !== "undefined" && typeof window.__AGENIT_TOKEN__ === "string"
|
|
22
|
+
? window.__AGENIT_TOKEN__
|
|
23
|
+
: "";
|
|
24
|
+
export const TOKEN = INJECTED_TOKEN || url.searchParams.get("token") || "";
|
|
25
|
+
|
|
26
|
+
function absolute(path) {
|
|
27
|
+
if (!INJECTED_ORIGIN) return path;
|
|
28
|
+
if (/^https?:\/\//i.test(path)) return path;
|
|
29
|
+
return INJECTED_ORIGIN + (path.startsWith("/") ? path : "/" + path);
|
|
30
|
+
}
|
|
10
31
|
|
|
11
32
|
function withToken(path) {
|
|
12
|
-
if (!TOKEN) return path;
|
|
33
|
+
if (!TOKEN) return absolute(path);
|
|
13
34
|
const sep = path.indexOf("?") >= 0 ? "&" : "?";
|
|
14
|
-
return path + sep + "token=" + encodeURIComponent(TOKEN);
|
|
35
|
+
return absolute(path + sep + "token=" + encodeURIComponent(TOKEN));
|
|
15
36
|
}
|
|
16
37
|
|
|
17
38
|
function authHeaders() {
|
|
@@ -46,6 +67,14 @@ export async function apiJson(path, opts) {
|
|
|
46
67
|
}
|
|
47
68
|
|
|
48
69
|
export function wsUrl(path) {
|
|
70
|
+
if (INJECTED_ORIGIN) {
|
|
71
|
+
const wsBase = INJECTED_ORIGIN.replace(/^http/, "ws");
|
|
72
|
+
const sep = path.indexOf("?") >= 0 ? "&" : "?";
|
|
73
|
+
const tokenSuffix = TOKEN
|
|
74
|
+
? sep + "token=" + encodeURIComponent(TOKEN)
|
|
75
|
+
: "";
|
|
76
|
+
return wsBase + (path.startsWith("/") ? path : "/" + path) + tokenSuffix;
|
|
77
|
+
}
|
|
49
78
|
const proto = location.protocol === "https:" ? "wss:" : "ws:";
|
|
50
79
|
return withToken(proto + "//" + location.host + path);
|
|
51
80
|
}
|
package/control/app.mjs
CHANGED
|
@@ -22,6 +22,7 @@ import { Goal } from "./panels/Goal.mjs";
|
|
|
22
22
|
import { Memory } from "./panels/Memory.mjs";
|
|
23
23
|
import { Jobs } from "./panels/Jobs.mjs";
|
|
24
24
|
import { Design } from "./panels/Design.mjs";
|
|
25
|
+
import { Debug } from "./panels/Debug.mjs";
|
|
25
26
|
|
|
26
27
|
import { getSnapshot, startStore, subscribe } from "./store.mjs";
|
|
27
28
|
|
|
@@ -115,6 +116,10 @@ function Stage({ active, state, events, tuiEvents }) {
|
|
|
115
116
|
case "jobs":
|
|
116
117
|
main = html`<${Jobs} state=${state} />`;
|
|
117
118
|
break;
|
|
119
|
+
case "debug":
|
|
120
|
+
main = html`<${Debug} />`;
|
|
121
|
+
withRail = false;
|
|
122
|
+
break;
|
|
118
123
|
default: {
|
|
119
124
|
const panel = PANELS.find((p) => p.id === active) || PANELS[0];
|
|
120
125
|
main = html`<${PanelPlaceholder} panel=${panel} />`;
|