@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/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 — leave commented out to use Gemini CLI's own default
8
- # model = "gemini-2.5-pro"
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 doc/integrations/mempalace.md. Install with `pip install mempalace`.
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
- export const TOKEN = url.searchParams.get("token") || "";
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} />`;