brl-subagent 2.3.5 → 2.3.6

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/AGENT.md CHANGED
@@ -1,4 +1,4 @@
1
- # AGENT.md — brl-subagent capability reference (v2.3.4+)
1
+ # AGENT.md — brl-subagent capability reference
2
2
 
3
3
  > The `delegate_task` prompt guidelines are a derived summary of this file; if they disagree, this file wins.
4
4
 
@@ -56,33 +56,3 @@ Presets and templates are documented in the schema, not here. Judgment only:
56
56
  - Recurring task shapes → a saved template.
57
57
 
58
58
  The schema's `delegate_task` parameters, the `templateSummary` and `presetRestrictionSummary` lines in the prompt guidelines, and `get_subagent_result`'s description are the mechanics reference.
59
-
60
- ## Local development
61
-
62
- This repo is the package source. Daily use runs the **published npm package**;
63
- development runs the **local checkout**. Both are `pi install` entries and cannot
64
- coexist — two loaded copies register the same tools — so remove one first.
65
-
66
- ```bash
67
- # Daily: the published artifact — the same thing users install
68
- pi remove <local-repo-path>
69
- pi install npm:brl-subagent
70
-
71
- # Develop: load the checkout in place — no copying, no syncing
72
- pi remove npm:brl-subagent
73
- pi install <local-repo-path> # or a worktree: …/brl-subagent-wt-<n>
74
- # then /reload pi after edits
75
-
76
- # Back to the published artifact
77
- pi remove <local-repo-path>
78
- pi install npm:brl-subagent
79
- ```
80
-
81
- A local-path install loads the directory in place and can point at an **unmerged
82
- worktree**, so it doubles as live verification for a PR. `pi update --extensions`
83
- advances the npm install and leaves a local-path install alone.
84
-
85
- (The former `sync-extension.sh` — rsync into `~/.pi/agent/extensions/brl-subagent`
86
- — was retired once the package was published: the local-path install supersedes it
87
- and does not fight `pi update --extensions` by mutating a package-manager-owned
88
- directory.)
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  > Multi-agent orchestration for [pi](https://github.com/earendil-works/pi) — chain, parallel, and dependency-graph delegation to isolated subagents with per-step model routing, preset-driven tool scoping, thinking-level control, and background execution with live monitoring, real abort, and per-agent timeouts.
4
4
 
5
- **Version:** 2.3.4 · **Author:** Azmeen Afandi / [Beeroo Labs](https://beeroolabs.com) · **License:** MIT
5
+ **Version:** 2.3.6 · **Author:** Azmeen Afandi / [Beeroo Labs](https://beeroolabs.com) · **License:** MIT
6
6
 
7
7
  ---
8
8
 
@@ -35,16 +35,6 @@ pi update --extensions # update installed packages
35
35
  pi remove npm:brl-subagent # uninstall
36
36
  ```
37
37
 
38
- <details>
39
- <summary>Alternative: install from git</summary>
40
-
41
- ```bash
42
- pi install git:github.com/azmeenafandi/brl-subagent@v2.3.4
43
- ```
44
-
45
- Git installs are **pinned** to the ref you specify. `pi update --extensions` reconciles to that ref but never advances it — upgrading means re-running `pi install` with a newer `@ref`.
46
- </details>
47
-
48
38
  ---
49
39
 
50
40
  ## Quick reference
@@ -70,7 +60,6 @@ Git installs are **pinned** to the ref you specify. `pi update --extensions` rec
70
60
  | `/brl-subagent monitor` | Live monitor running subagents |
71
61
  | `/brl-subagent dashboard` | Live observability dashboard |
72
62
  | `/brl-subagent retry` | Browse failed runs to retry |
73
- | `/brl-subagent update-check` | Toggle update check on startup |
74
63
  | `/brl-subagent reset` | Reset all configuration |
75
64
 
76
65
  All settings persist across sessions.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brl-subagent",
3
- "version": "2.3.5",
3
+ "version": "2.3.6",
4
4
  "description": "Subagent extension for pi with configurable model and thinking mode via selection UI",
5
5
  "keywords": [
6
6
  "pi-package"
@@ -42,7 +42,7 @@
42
42
  "jiti": "^2.7.0",
43
43
  "typebox": "^1.3.25",
44
44
  "typescript": "^5.9.3",
45
- "vitest": "^4.1.11"
45
+ "vitest": "^5.0.0"
46
46
  },
47
47
  "overrides": {
48
48
  "nanoid": "^3.3.17"
package/src/index.ts CHANGED
@@ -4,7 +4,6 @@
4
4
  * See AGENT.md for the conductor-facing capability reference.
5
5
  */
6
6
 
7
- import * as fs from "node:fs";
8
7
  import * as path from "node:path";
9
8
  import type {
10
9
  AgentToolResult,
@@ -93,7 +92,6 @@ import {
93
92
  showCompletionNotifySelector,
94
93
  showPresetManager,
95
94
  showTemplateManager,
96
- showUpdateCheckToggle,
97
95
  showSLAConfig,
98
96
  showSLAStats,
99
97
  showConfigMenu,
@@ -106,8 +104,6 @@ import {
106
104
  } from "./tui";
107
105
  import { createLogger, type Logger } from "./logging";
108
106
  import { Intercom } from "./messaging";
109
- import { checkForUpdates } from "./update";
110
- import { UPDATE_CHECK_INTERVAL_MS } from "./types";
111
107
  import * as eventBus from "./event-bus";
112
108
  import {
113
109
  buildCompletionMessage,
@@ -198,16 +194,6 @@ export function buildTemplateGuideline(templateSummary: string): string {
198
194
  export default function (pi: ExtensionAPI) {
199
195
  const log = createLogger("brl-subagent");
200
196
 
201
- // Read current version from package.json
202
- const currentVersion = (() => {
203
- try {
204
- const pkg = JSON.parse(fs.readFileSync(pkgPath("package.json"), "utf-8"));
205
- return pkg.version || "0.0.0";
206
- } catch {
207
- return "0.0.0";
208
- }
209
- })();
210
-
211
197
  // F7: Session-bound state — initialized per session
212
198
  let state = createSessionState(log);
213
199
 
@@ -1932,7 +1918,6 @@ export default function (pi: ExtensionAPI) {
1932
1918
  preset: () => showPresetManager(ctx, state),
1933
1919
  templates: () => showTemplateManager(ctx, state),
1934
1920
  retry: () => showRetryMenu(ctx, state),
1935
- "update-check": () => showUpdateCheckToggle(ctx, state, applyConfig),
1936
1921
  sla: () => showSLAConfig(ctx, state, applyConfig),
1937
1922
  "sla-stats": () => showSLAStats(ctx, state),
1938
1923
  };
@@ -3740,23 +3725,6 @@ export default function (pi: ExtensionAPI) {
3740
3725
  // F5/F9: Safe state restoration with type guards
3741
3726
  state.restoreFromSession(ctx);
3742
3727
 
3743
- // Check for updates (non-blocking, once per 24h)
3744
- if (state.config.updateCheckEnabled) {
3745
- const now = Date.now();
3746
- if (now - state.config.lastUpdateCheck > UPDATE_CHECK_INTERVAL_MS) {
3747
- state.config.lastUpdateCheck = now;
3748
- checkForUpdates(currentVersion, log).then((result) => {
3749
- if (result?.available) {
3750
- ctx.ui.notify(
3751
- "brl-subagent " + result.version + " available (current: " + currentVersion + "). Visit " + result.url + " to update. /brl-subagent update-check to disable.",
3752
- "info"
3753
- );
3754
- log.info("Update available", { current: currentVersion, latest: result.version });
3755
- }
3756
- }).catch(() => {}); // silently ignore errors
3757
- }
3758
- }
3759
-
3760
3728
  updateStatus(state, ctx);
3761
3729
  });
3762
3730
 
package/src/state.ts CHANGED
@@ -142,8 +142,6 @@ export class SessionState {
142
142
  circuitBreaker: this.defaultCircuitBreaker(),
143
143
  slaTrackingEnabled: false,
144
144
  slaWindowSize: 50,
145
- updateCheckEnabled: true,
146
- lastUpdateCheck: 0,
147
145
  };
148
146
  }
149
147
 
@@ -168,8 +166,6 @@ export class SessionState {
168
166
  slaTrackingEnabled: this.config.slaTrackingEnabled,
169
167
  slaWindowSize: this.config.slaWindowSize,
170
168
  lastSLAMetrics: this.config.lastSLAMetrics,
171
- updateCheckEnabled: this.config.updateCheckEnabled,
172
- lastUpdateCheck: this.config.lastUpdateCheck,
173
169
  });
174
170
  }
175
171
 
@@ -258,10 +254,6 @@ export class SessionState {
258
254
  this.config.lastSLAMetrics = data.lastSLAMetrics as import("./types").SLAMetrics;
259
255
  }
260
256
 
261
- // Restore update check fields
262
- if (typeof data.updateCheckEnabled === "boolean") this.config.updateCheckEnabled = data.updateCheckEnabled;
263
- if (typeof data.lastUpdateCheck === "number" && data.lastUpdateCheck >= 0) this.config.lastUpdateCheck = data.lastUpdateCheck;
264
-
265
257
  this.log?.info("State restored from session", {
266
258
  model: data.model ? `${data.model.provider}/${data.model.id}` : "none",
267
259
  thinkingLevel: data.maxThinkingLevel,
@@ -508,8 +500,6 @@ export class SessionState {
508
500
  this.config.slaTrackingEnabled = false;
509
501
  this.config.slaWindowSize = 50;
510
502
  this.config.lastSLAMetrics = undefined;
511
- this.config.updateCheckEnabled = true;
512
- this.config.lastUpdateCheck = 0;
513
503
  }
514
504
  }
515
505
 
package/src/tui.ts CHANGED
@@ -337,28 +337,6 @@ export async function showCompletionNotifySelector(
337
337
  onConfigChanged(ctx, `Completion notify mode set to ${result}`);
338
338
  }
339
339
 
340
- // ---------------------------------------------------------------------------
341
- // Update check toggle
342
- // ---------------------------------------------------------------------------
343
-
344
- export async function showUpdateCheckToggle(
345
- ctx: ExtensionContext,
346
- state: SessionState,
347
- onConfigChanged: (ctx: ExtensionContext, msg: string) => void,
348
- ): Promise<void> {
349
- const items: SelectItem[] = [
350
- { value: "enabled", label: "Enabled", description: "Check for updates on session start" },
351
- { value: "disabled", label: "Disabled", description: "Skip update check" },
352
- ];
353
-
354
- const result = await showSelectList(ctx, "Update Check", items, 5);
355
- if (!result) return;
356
-
357
- state.config.updateCheckEnabled = result === "enabled";
358
- onConfigChanged(ctx, `Update check ${result}`);
359
- }
360
-
361
- // ---------------------------------------------------------------------------
362
340
  // ---------------------------------------------------------------------------
363
341
  // E4: SLA tracking configuration
364
342
  // ---------------------------------------------------------------------------
@@ -1199,11 +1177,6 @@ export function getConfigMenuItems(state: SessionState): SelectItem[] {
1199
1177
  ? `Enabled (window: ${state.config.slaWindowSize})`
1200
1178
  : "Disabled",
1201
1179
  },
1202
- {
1203
- value: "update-check",
1204
- label: "Update Check",
1205
- description: state.config.updateCheckEnabled ? "Enabled" : "Disabled",
1206
- },
1207
1180
  ];
1208
1181
  }
1209
1182
 
package/src/types.ts CHANGED
@@ -209,8 +209,6 @@ export interface SubagentState {
209
209
  slaTrackingEnabled: boolean; // E4: SLA tracking toggle
210
210
  slaWindowSize: number; // E4: number of recent runs to analyze (10-500)
211
211
  lastSLAMetrics?: SLAMetrics; // E4: persisted baseline for degradation comparison
212
- updateCheckEnabled: boolean; // Version update notifier toggle
213
- lastUpdateCheck: number; // Epoch ms of last update check
214
212
  }
215
213
 
216
214
  /**
@@ -556,8 +554,6 @@ export const TEMPLATE_PARAM_RE = /\$\{(\w+)\}/g;
556
554
 
557
555
  export const DEFAULT_SESSION_COST_LIMIT = 0;
558
556
 
559
- export const UPDATE_CHECK_INTERVAL_MS = 24 * 60 * 60 * 1000; // 24 hours
560
-
561
557
  export const CUSTOM_ENTRY_TYPES = {
562
558
  run: "brl-subagent-run",
563
559
  state: "brl-subagent-state",
@@ -589,7 +585,7 @@ export const RESERVED_NAME_PATTERN = /^__.*__$/;
589
585
  export const RESERVED_COMMAND_NAMES = new Set([
590
586
  "model", "thinking", "concurrency", "depth", "history", "monitor",
591
587
  "preset", "retry", "reset", "priority", "templates", "dashboard", "approval",
592
- "costlimit", "historyentries", "sla", "update-check", "completionnotify",
588
+ "costlimit", "historyentries", "sla", "completionnotify",
593
589
  "graph", "sla-stats",
594
590
  ]);
595
591
 
@@ -750,14 +746,6 @@ export function isSubagentStateShape(value: unknown): value is SubagentState {
750
746
  if (typeof v.slaWindowSize !== "number" || v.slaWindowSize < 10 || v.slaWindowSize > 500) return false;
751
747
  }
752
748
 
753
- // updateCheckEnabled must be a boolean if present
754
- if (v.updateCheckEnabled !== undefined && typeof v.updateCheckEnabled !== "boolean") return false;
755
-
756
- // lastUpdateCheck must be a non-negative number if present
757
- if (v.lastUpdateCheck !== undefined) {
758
- if (typeof v.lastUpdateCheck !== "number" || v.lastUpdateCheck < 0) return false;
759
- }
760
-
761
749
  return true;
762
750
  }
763
751
 
package/src/update.ts DELETED
@@ -1,109 +0,0 @@
1
- /**
2
- * brl-subagent — Version Update Notifier
3
- *
4
- * Checks GitHub releases for newer versions of brl-subagent.
5
- * Runs non-blocking with a 5-second timeout on session start.
6
- */
7
-
8
- import type { Logger } from "./logging";
9
-
10
- // ---------------------------------------------------------------------------
11
- // Types
12
- // ---------------------------------------------------------------------------
13
-
14
- export interface UpdateCheckResult {
15
- available: boolean;
16
- version?: string;
17
- url?: string;
18
- }
19
-
20
- // ---------------------------------------------------------------------------
21
- // Semver comparison
22
- // ---------------------------------------------------------------------------
23
-
24
- /**
25
- * Compare two semver strings (e.g., "2.1.0" vs "2.0.1").
26
- * Returns 1 if a > b, -1 if a < b, 0 if equal.
27
- */
28
- function compareSemver(a: string, b: string): number {
29
- const aParts = a.split(".").map(Number);
30
- const bParts = b.split(".").map(Number);
31
- const len = Math.max(aParts.length, bParts.length);
32
-
33
- for (let i = 0; i < len; i++) {
34
- const aVal = aParts[i] ?? 0;
35
- const bVal = bParts[i] ?? 0;
36
- if (aVal > bVal) return 1;
37
- if (aVal < bVal) return -1;
38
- }
39
- return 0;
40
- }
41
-
42
- // ---------------------------------------------------------------------------
43
- // Main export
44
- // ---------------------------------------------------------------------------
45
-
46
- /**
47
- * Check GitHub for a newer release of brl-subagent.
48
- *
49
- * @param currentVersion - The current version string (e.g., "2.0.1")
50
- * @param log - Optional logger for debug output
51
- * @returns Update check result, or null on any error (never throws)
52
- */
53
- export async function checkForUpdates(
54
- currentVersion: string,
55
- log?: Logger,
56
- ): Promise<UpdateCheckResult | null> {
57
- try {
58
- const controller = new AbortController();
59
- const timeoutId = setTimeout(() => controller.abort(), 5_000);
60
-
61
- const response = await fetch(
62
- "https://api.github.com/repos/azmeenafandi/brl-subagent/releases/latest",
63
- {
64
- headers: {
65
- Accept: "application/vnd.github+json",
66
- "User-Agent": "brl-subagent",
67
- },
68
- signal: controller.signal,
69
- },
70
- );
71
-
72
- clearTimeout(timeoutId);
73
-
74
- if (!response.ok) {
75
- log?.debug("Update check: non-OK response", { status: response.status });
76
- return null;
77
- }
78
-
79
- const data = (await response.json()) as {
80
- tag_name?: string;
81
- html_url?: string;
82
- };
83
-
84
- if (!data.tag_name || !data.html_url) {
85
- log?.debug("Update check: missing tag_name or html_url in response");
86
- return null;
87
- }
88
-
89
- // Strip "v" prefix from tag_name (e.g., "v2.1.0" → "2.1.0")
90
- const latestVersion = data.tag_name.replace(/^v/, "");
91
-
92
- const cmp = compareSemver(latestVersion, currentVersion);
93
-
94
- if (cmp > 0) {
95
- return {
96
- available: true,
97
- version: latestVersion,
98
- url: data.html_url,
99
- };
100
- }
101
-
102
- return { available: false };
103
- } catch (err) {
104
- log?.debug("Update check failed", {
105
- error: err instanceof Error ? err.message : String(err),
106
- });
107
- return null;
108
- }
109
- }