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 +1 -31
- package/README.md +1 -12
- package/package.json +2 -2
- package/src/index.ts +0 -32
- package/src/state.ts +0 -10
- package/src/tui.ts +0 -27
- package/src/types.ts +1 -13
- package/src/update.ts +0 -109
package/AGENT.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# AGENT.md — brl-subagent capability reference
|
|
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.
|
|
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.
|
|
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": "^
|
|
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", "
|
|
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
|
-
}
|