@brainpilot/app 0.0.5 → 0.0.7

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/README.md ADDED
@@ -0,0 +1,85 @@
1
+ # @brainpilot/app
2
+
3
+ **BrainPilot** is an open-source, single-user multi-agent collaboration platform
4
+ built with TypeScript + the [Pi SDK](https://pi.dev) — a Principal agent
5
+ coordinating specialist agents over a file-based mailbox, served as a Hono
6
+ backend + React SPA. It runs as a local process; **no Docker required**.
7
+
8
+ This package (`@brainpilot/app`) is the CLI. It installs the `brainpilot`
9
+ command (`bnpt` is a built-in short alias).
10
+
11
+ ## Prerequisites
12
+
13
+ - Node.js ≥ 22
14
+ - An Anthropic API key (or `BP_MOCK=1` for a no-key test run)
15
+
16
+ ## Install
17
+
18
+ ```bash
19
+ npm install -g @brainpilot/app
20
+ ```
21
+
22
+ ## Quick Start
23
+
24
+ ```bash
25
+ # 1. Scaffold config under ./brainpilot
26
+ brainpilot init --api-key <your-anthropic-key>
27
+
28
+ # 2. Launch (foreground; Ctrl-C to stop)
29
+ brainpilot up
30
+ ```
31
+
32
+ Then open the printed URL (default http://127.0.0.1:9001).
33
+
34
+ A missing key does **not** block launch — `brainpilot up` starts anyway, and you
35
+ can configure the provider URL / key / model in the web **Settings → Providers**
36
+ panel after it opens (the recommended path; it writes `providers.json` for you).
37
+
38
+ ### No-key smoke run
39
+
40
+ ```bash
41
+ BP_MOCK=1 brainpilot up
42
+ ```
43
+
44
+ `BP_MOCK=1` runs a deterministic mock agent that makes no real LLM calls — handy
45
+ for verifying the install end-to-end without an API key.
46
+
47
+ ### Configure a gateway / third-party endpoint
48
+
49
+ ```bash
50
+ brainpilot init --api-key <key> \
51
+ --base-url https://your-gateway.example.com/api \
52
+ --model kimi-k2.6
53
+ ```
54
+
55
+ You can also omit `--api-key` and supply credentials via the `ANTHROPIC_API_KEY`
56
+ environment variable instead.
57
+
58
+ ## Detached mode
59
+
60
+ ```bash
61
+ brainpilot up --detach # run in the background, managed by the CLI
62
+ brainpilot status # health + child pid
63
+ brainpilot logs # tail backend log (add --runtime for the runtime log)
64
+ brainpilot down # stop the detached backend
65
+ ```
66
+
67
+ ## Common flags
68
+
69
+ | Flag | Meaning |
70
+ |------|---------|
71
+ | `--port <n>` | Backend port (default 9001) |
72
+ | `--dir <path>` | Data directory (default `./brainpilot`) |
73
+ | `--detach` | Run in the background |
74
+ | `--no-open` | Don't open the browser on launch |
75
+
76
+ ## Documentation
77
+
78
+ Full documentation, architecture notes, and advanced configuration live in the
79
+ GitHub README:
80
+
81
+ ➡️ **https://github.com/NeuroAIHub/BrainPilot**
82
+
83
+ ## License
84
+
85
+ AGPL-3.0-only
package/dist/bin.js CHANGED
@@ -4,6 +4,8 @@
4
4
  * commander program and maps thrown errors to a non-zero exit (§11A.4).
5
5
  */
6
6
  import { run } from "./program.js";
7
+ import { assertRepoCwd } from "./repo-mode.js";
8
+ assertRepoCwd({ argv: process.argv.slice(2) });
7
9
  run(process.argv.slice(2)).catch(() => {
8
10
  process.exitCode = 1;
9
11
  });
package/dist/bin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA;;;GAGG;AACH,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAEnC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;IACpC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA;;;GAGG;AACH,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,aAAa,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AAE/C,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;IACpC,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"down.d.ts","sourceRoot":"","sources":["../../src/commands/down.ts"],"names":[],"mappings":"AAQA,OAAO,EAAmB,KAAK,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAEjF,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,QAAS,SAAQ,kBAAkB;IAClD,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,wBAAsB,IAAI,CACxB,OAAO,GAAE,WAAgB,EACzB,IAAI,GAAE,QAAa,GAClB,OAAO,CAAC,UAAU,CAAC,CAuBrB"}
1
+ {"version":3,"file":"down.d.ts","sourceRoot":"","sources":["../../src/commands/down.ts"],"names":[],"mappings":"AAUA,OAAO,EAA2B,KAAK,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAEzF,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,QAAS,SAAQ,kBAAkB;IAClD,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,wBAAsB,IAAI,CACxB,OAAO,GAAE,WAAgB,EACzB,IAAI,GAAE,QAAa,GAClB,OAAO,CAAC,UAAU,CAAC,CAmCrB"}
@@ -1,12 +1,14 @@
1
1
  /**
2
2
  * commands/down.ts — stop the detached backend (TS_PI_REFACTOR_DESIGN §11A.4).
3
3
  * Reads `.runtime/backend.pid`, gracefully stops it (SIGTERM→SIGKILL). The
4
- * backend's own LocalProcessOrchestrator stops the runtime child on shutdown,
5
- * but we also clean up a stale runtime.pid if present.
4
+ * backend's own LocalProcessOrchestrator normally stops the runtime child on
5
+ * shutdown, but if the orchestrator lost track of it (issue #58 — the spawn
6
+ * storm could orphan the surviving runtime on port+1), we also stop whatever
7
+ * `.runtime/runtime.pid` points at as a backstop.
6
8
  */
7
9
  import pc from "picocolors";
8
10
  import { resolveDataDir, dataPaths } from "../paths.js";
9
- import { stop, removePid } from "../process-control.js";
11
+ import { stop, removeServerState } from "../process-control.js";
10
12
  export async function down(options = {}, deps = {}) {
11
13
  const log = deps.log ?? ((m) => console.log(m));
12
14
  const dataDir = resolveDataDir({ dir: options.dir, env: deps.env, cwd: deps.cwd });
@@ -17,8 +19,20 @@ export async function down(options = {}, deps = {}) {
17
19
  signal: deps.signal,
18
20
  sleep: deps.sleep,
19
21
  });
20
- // Backend owns the runtime; clean any leftover runtime pid file regardless.
21
- await removePid(p.runtimePid);
22
+ // Backstop the runtime (issue #58): the backend normally kills its runtime
23
+ // child and removes runtime.pid on shutdown, in which case this stop() reads
24
+ // no pid and is a no-op. But if the orchestrator lost track during a failed
25
+ // spawn storm, the real runtime can survive as an orphan on port+1 — stop()
26
+ // reads runtime.pid and actually SIGTERM/SIGKILLs it. Idempotent either way.
27
+ await stop(p.runtimePid, {
28
+ timeoutMs: options.timeoutMs,
29
+ isAlive: deps.isAlive,
30
+ signal: deps.signal,
31
+ sleep: deps.sleep,
32
+ });
33
+ // Drop the persisted server state so a later `status` doesn't report a dead
34
+ // server's ports (issue #41).
35
+ await removeServerState(p.serverState);
22
36
  if (result.pid === null) {
23
37
  log(pc.yellow("No running backend found (no pid file)."));
24
38
  }
@@ -1 +1 @@
1
- {"version":3,"file":"down.js","sourceRoot":"","sources":["../../src/commands/down.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,SAAS,EAA2B,MAAM,uBAAuB,CAAC;AAmBjF,MAAM,CAAC,KAAK,UAAU,IAAI,CACxB,UAAuB,EAAE,EACzB,OAAiB,EAAE;IAEnB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACxD,MAAM,OAAO,GAAG,cAAc,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IACnF,MAAM,CAAC,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IAE7B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,CAAC,CAAC,UAAU,EAAE;QACtC,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,KAAK,EAAE,IAAI,CAAC,KAAK;KAClB,CAAC,CAAC;IAEH,4EAA4E;IAC5E,MAAM,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IAE9B,IAAI,MAAM,CAAC,GAAG,KAAK,IAAI,EAAE,CAAC;QACxB,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,yCAAyC,CAAC,CAAC,CAAC;IAC5D,CAAC;SAAM,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QACzB,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,gBAAgB,MAAM,CAAC,GAAG,+BAA+B,CAAC,CAAC,CAAC;IAC5E,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,MAAM,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
1
+ {"version":3,"file":"down.js","sourceRoot":"","sources":["../../src/commands/down.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,IAAI,EAAE,iBAAiB,EAA2B,MAAM,uBAAuB,CAAC;AAmBzF,MAAM,CAAC,KAAK,UAAU,IAAI,CACxB,UAAuB,EAAE,EACzB,OAAiB,EAAE;IAEnB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACxD,MAAM,OAAO,GAAG,cAAc,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IACnF,MAAM,CAAC,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IAE7B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,CAAC,CAAC,UAAU,EAAE;QACtC,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,KAAK,EAAE,IAAI,CAAC,KAAK;KAClB,CAAC,CAAC;IAEH,2EAA2E;IAC3E,6EAA6E;IAC7E,4EAA4E;IAC5E,4EAA4E;IAC5E,6EAA6E;IAC7E,MAAM,IAAI,CAAC,CAAC,CAAC,UAAU,EAAE;QACvB,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,KAAK,EAAE,IAAI,CAAC,KAAK;KAClB,CAAC,CAAC;IACH,4EAA4E;IAC5E,8BAA8B;IAC9B,MAAM,iBAAiB,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;IAEvC,IAAI,MAAM,CAAC,GAAG,KAAK,IAAI,EAAE,CAAC;QACxB,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,yCAAyC,CAAC,CAAC,CAAC;IAC5D,CAAC;SAAM,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QACzB,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,gBAAgB,MAAM,CAAC,GAAG,+BAA+B,CAAC,CAAC,CAAC;IAC5E,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,gBAAgB,MAAM,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAOA,OAAO,EAAsB,KAAK,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAGpF,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAW,SAAQ,kBAAkB;IACpD,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,qEAAqE;IACrE,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/D;AAED,wBAAsB,MAAM,CAC1B,OAAO,GAAE,aAAkB,EAC3B,IAAI,GAAE,UAAe,GACpB,OAAO,CAAC,YAAY,CAAC,CA4DvB"}
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAOA,OAAO,EAAuC,KAAK,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAGrG,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAW,SAAQ,kBAAkB;IACpD,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,qEAAqE;IACrE,OAAO,CAAC,EAAE,OAAO,KAAK,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/D;AAED,wBAAsB,MAAM,CAC1B,OAAO,GAAE,aAAkB,EAC3B,IAAI,GAAE,UAAe,GACpB,OAAO,CAAC,YAAY,CAAC,CAkEvB"}
@@ -5,7 +5,7 @@
5
5
  */
6
6
  import pc from "picocolors";
7
7
  import { resolveDataDir, dataPaths } from "../paths.js";
8
- import { readPid, isRunning } from "../process-control.js";
8
+ import { readPid, isRunning, readServerState } from "../process-control.js";
9
9
  import { DEFAULT_PORT } from "../scaffold.js";
10
10
  export async function status(options = {}, deps = {}) {
11
11
  const log = deps.log ?? ((m) => console.log(m));
@@ -13,7 +13,11 @@ export async function status(options = {}, deps = {}) {
13
13
  const fetchFn = deps.fetchFn ?? fetch;
14
14
  const dataDir = resolveDataDir({ dir: options.dir, env, cwd: deps.cwd });
15
15
  const p = dataPaths(dataDir);
16
- const port = options.port ?? (Number(env.BP_PORT) || DEFAULT_PORT);
16
+ // Port precedence (issue #41): explicit --port > persisted server.json
17
+ // (written by detached `up`) > BP_PORT > DEFAULT_PORT.
18
+ const state = await readServerState(p.serverState);
19
+ const port = options.port ?? state?.port ?? (Number(env.BP_PORT) || DEFAULT_PORT);
20
+ const runtimePort = options.port === undefined && state ? state.runtimePort : port + 1;
17
21
  const host = "127.0.0.1";
18
22
  const url = `http://${host}:${port}`;
19
23
  const pid = await readPid(p.backendPid);
@@ -46,7 +50,7 @@ export async function status(options = {}, deps = {}) {
46
50
  running,
47
51
  pid,
48
52
  backendPort: port,
49
- runtimePort: port + 1,
53
+ runtimePort,
50
54
  url,
51
55
  healthy,
52
56
  ...(metrics ? { metrics } : {}),
@@ -1 +1 @@
1
- {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,43 @@
1
+ export type DriftState = "no-local" | "in-sync" | "drift";
2
+ export interface AgentStatus {
3
+ name: string;
4
+ state: DriftState;
5
+ /** Absolute path to the on-disk override (always populated, even if absent). */
6
+ path: string;
7
+ }
8
+ export interface CommonOptions {
9
+ dir?: string;
10
+ env?: Record<string, string | undefined>;
11
+ cwd?: string;
12
+ log?: (msg: string) => void;
13
+ /** Test hook so we don't actually read stdin. */
14
+ confirm?: (prompt: string) => Promise<boolean>;
15
+ }
16
+ /** Path to an agent's on-disk persona override (the runtime's load contract). */
17
+ export declare function agentPromptPath(dataDir: string, name: string): string;
18
+ /** Compute drift status for every built-in agent (or just one). */
19
+ export declare function templateList(options?: CommonOptions & {
20
+ agent?: string;
21
+ }): Promise<AgentStatus[]>;
22
+ /** Subset of `templateList` used by `up`'s banner — only agents in drift. */
23
+ export declare function detectPromptDrift(dataDir: string): Promise<AgentStatus[]>;
24
+ export declare function runList(options?: CommonOptions): Promise<void>;
25
+ export declare function runDiff(options?: CommonOptions & {
26
+ agent?: string;
27
+ }): Promise<void>;
28
+ export interface ResetResult {
29
+ /** Agents whose prompt.md was (over)written from the built-in. */
30
+ written: string[];
31
+ /** Backup directory created (only when at least one existing file was replaced). */
32
+ backupDir?: string;
33
+ /** Agents skipped (e.g. already in-sync, or user declined). */
34
+ skipped: {
35
+ name: string;
36
+ reason: string;
37
+ }[];
38
+ }
39
+ export declare function runReset(options?: CommonOptions & {
40
+ agent?: string;
41
+ yes?: boolean;
42
+ }): Promise<ResetResult>;
43
+ //# sourceMappingURL=template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../../src/commands/template.ts"],"names":[],"mappings":"AAyBA,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,SAAS,GAAG,OAAO,CAAC;AAE1D,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,UAAU,CAAC;IAClB,gFAAgF;IAChF,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,iDAAiD;IACjD,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CAChD;AAED,iFAAiF;AACjF,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAErE;AAyBD,mEAAmE;AACnE,wBAAsB,YAAY,CAChC,OAAO,GAAE,aAAa,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAC/C,OAAO,CAAC,WAAW,EAAE,CAAC,CA4BxB;AAED,6EAA6E;AAC7E,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,WAAW,EAAE,CAAC,CAGxB;AAeD,wBAAsB,OAAO,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBxE;AAmDD,wBAAsB,OAAO,CAC3B,OAAO,GAAE,aAAa,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAC/C,OAAO,CAAC,IAAI,CAAC,CAwBf;AAID,MAAM,WAAW,WAAW;IAC1B,kEAAkE;IAClE,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,oFAAoF;IACpF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+DAA+D;IAC/D,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC7C;AA6BD,wBAAsB,QAAQ,CAC5B,OAAO,GAAE,aAAa,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,OAAO,CAAA;CAAO,GAC9D,OAAO,CAAC,WAAW,CAAC,CA0FtB"}
@@ -0,0 +1,300 @@
1
+ /**
2
+ * commands/template.ts — `bp template list|diff|reset` for managing per-agent
3
+ * prompt overrides under `bp_template/agents/<name>/prompt.md`.
4
+ *
5
+ * The runtime's `loadPersona` prefers the on-disk override and falls back to
6
+ * the in-code PERSONAS registry. After #102 the scaffold no longer writes
7
+ * prompt.md by default, so users only end up with overrides if they explicitly
8
+ * materialise one — and these subcommands are the supported way to do that
9
+ * and to keep an existing override in sync with upstream prompt updates.
10
+ *
11
+ * list — show each built-in agent's drift state (no-local / in-sync / drift)
12
+ * diff — print a unified diff between the on-disk override and the built-in
13
+ * reset — write the built-in prompt to disk, backing up any existing override
14
+ *
15
+ * `detectPromptDrift(dataDir)` is also exported so `commands/up.ts` can flash
16
+ * a non-blocking banner at launch when stale overrides are detected.
17
+ */
18
+ import { mkdir, readFile, writeFile, access } from "node:fs/promises";
19
+ import { constants as FS } from "node:fs";
20
+ import { createInterface } from "node:readline/promises";
21
+ import { join, dirname } from "node:path";
22
+ import pc from "picocolors";
23
+ import { BUILTIN_PERSONA_NAMES, PERSONAS } from "@brainpilot/runtime";
24
+ import { resolveDataDir, dataPaths } from "../paths.js";
25
+ /** Path to an agent's on-disk persona override (the runtime's load contract). */
26
+ export function agentPromptPath(dataDir, name) {
27
+ return join(dataDir, "bp_template", "agents", name, "prompt.md");
28
+ }
29
+ async function pathExists(p) {
30
+ try {
31
+ await access(p, FS.F_OK);
32
+ return true;
33
+ }
34
+ catch {
35
+ return false;
36
+ }
37
+ }
38
+ async function readOrNull(p) {
39
+ try {
40
+ return await readFile(p, "utf8");
41
+ }
42
+ catch {
43
+ return null;
44
+ }
45
+ }
46
+ /** Normalize for byte-level comparison: strip a single trailing newline so
47
+ * hand-edited files don't show as `drift` over a meaningless EOL. */
48
+ function normalize(s) {
49
+ return s.endsWith("\n") ? s.slice(0, -1) : s;
50
+ }
51
+ /** Compute drift status for every built-in agent (or just one). */
52
+ export async function templateList(options = {}) {
53
+ const dataDir = resolveDataDir({
54
+ dir: options.dir,
55
+ env: options.env,
56
+ cwd: options.cwd,
57
+ });
58
+ const names = options.agent ? [options.agent] : BUILTIN_PERSONA_NAMES;
59
+ const out = [];
60
+ for (const name of names) {
61
+ const path = agentPromptPath(dataDir, name);
62
+ const disk = await readOrNull(path);
63
+ const builtin = PERSONAS[name];
64
+ if (!builtin) {
65
+ // Unknown agent name (e.g. user passed `template list someExpert` for a
66
+ // runtime-created expert). Report it as `no-local` so the user sees the
67
+ // tool didn't crash, and the path so they can dump one if they want.
68
+ out.push({ name, state: "no-local", path });
69
+ continue;
70
+ }
71
+ if (disk === null) {
72
+ out.push({ name, state: "no-local", path });
73
+ }
74
+ else if (normalize(disk) === normalize(builtin)) {
75
+ out.push({ name, state: "in-sync", path });
76
+ }
77
+ else {
78
+ out.push({ name, state: "drift", path });
79
+ }
80
+ }
81
+ return out;
82
+ }
83
+ /** Subset of `templateList` used by `up`'s banner — only agents in drift. */
84
+ export async function detectPromptDrift(dataDir) {
85
+ const all = await templateList({ dir: dataDir, env: {}, cwd: "/" });
86
+ return all.filter((s) => s.state === "drift");
87
+ }
88
+ /* ------------------------------ list command ------------------------------ */
89
+ const STATE_LABEL = {
90
+ "no-local": pc.dim("no-local"),
91
+ "in-sync": pc.green("in-sync"),
92
+ drift: pc.yellow("drift"),
93
+ };
94
+ const STATE_NOTE = {
95
+ "no-local": "no override (using built-in)",
96
+ "in-sync": "matches built-in",
97
+ drift: "local prompt differs from built-in",
98
+ };
99
+ export async function runList(options = {}) {
100
+ const log = options.log ?? ((m) => console.log(m));
101
+ const rows = await templateList(options);
102
+ log(pc.bold("AGENT STATUS NOTE"));
103
+ for (const r of rows) {
104
+ const name = r.name.padEnd(17, " ");
105
+ const state = STATE_LABEL[r.state].padEnd(20, " "); // colour codes add width
106
+ log(`${name} ${state} ${STATE_NOTE[r.state]}`);
107
+ }
108
+ const drifted = rows.filter((r) => r.state === "drift");
109
+ if (drifted.length > 0) {
110
+ log("");
111
+ log(pc.yellow(`${drifted.length} agent(s) in drift — \`bp template diff [<agent>]\` to inspect, \`bp template reset [<agent>]\` to overwrite.`));
112
+ }
113
+ }
114
+ /* ------------------------------ diff command ------------------------------ */
115
+ /**
116
+ * Tiny line-level unified diff. Not designed to match `diff -u` byte-for-byte;
117
+ * it just needs to make divergences scannable. We deliberately avoid pulling
118
+ * in a `diff` dependency for what is effectively a debug helper.
119
+ */
120
+ function unifiedDiff(a, b, label) {
121
+ const aLines = a.split("\n");
122
+ const bLines = b.split("\n");
123
+ const lines = [];
124
+ lines.push(pc.bold(`--- ${label} (built-in)`));
125
+ lines.push(pc.bold(`+++ ${label} (on-disk)`));
126
+ // Longest common subsequence is overkill for prompt diffs that usually
127
+ // touch a handful of lines. Use a per-line sweep: identical lines pass,
128
+ // divergent runs are emitted as `-old` then `+new` blocks.
129
+ let i = 0;
130
+ let j = 0;
131
+ while (i < aLines.length || j < bLines.length) {
132
+ if (i < aLines.length && j < bLines.length && aLines[i] === bLines[j]) {
133
+ lines.push(" " + aLines[i]);
134
+ i++;
135
+ j++;
136
+ continue;
137
+ }
138
+ // Find next sync point: matching pair within a small window so we don't
139
+ // emit the entire rest of both files when one line diverges.
140
+ let synced = false;
141
+ const window = 32;
142
+ outer: for (let di = 0; di < window && i + di < aLines.length; di++) {
143
+ for (let dj = 0; dj < window && j + dj < bLines.length; dj++) {
144
+ if (aLines[i + di] === bLines[j + dj] && aLines[i + di] !== "") {
145
+ for (let k = 0; k < di; k++)
146
+ lines.push(pc.red("- " + aLines[i + k]));
147
+ for (let k = 0; k < dj; k++)
148
+ lines.push(pc.green("+ " + bLines[j + k]));
149
+ i += di;
150
+ j += dj;
151
+ synced = true;
152
+ break outer;
153
+ }
154
+ }
155
+ }
156
+ if (!synced) {
157
+ if (i < aLines.length)
158
+ lines.push(pc.red("- " + aLines[i++]));
159
+ if (j < bLines.length)
160
+ lines.push(pc.green("+ " + bLines[j++]));
161
+ }
162
+ }
163
+ return lines.join("\n");
164
+ }
165
+ export async function runDiff(options = {}) {
166
+ const log = options.log ?? ((m) => console.log(m));
167
+ const rows = await templateList({ ...options, agent: options.agent });
168
+ let printed = 0;
169
+ for (const r of rows) {
170
+ if (r.state !== "drift")
171
+ continue;
172
+ const disk = (await readOrNull(r.path)) ?? "";
173
+ const builtin = PERSONAS[r.name] ?? "";
174
+ log("");
175
+ log(pc.bold(pc.cyan(`■ ${r.name}`)));
176
+ log(unifiedDiff(builtin, disk, r.name));
177
+ printed++;
178
+ }
179
+ if (printed === 0) {
180
+ if (options.agent) {
181
+ log(`${options.agent}: no drift (state: ${rows.find((r) => r.name === options.agent)?.state ?? "unknown"}).`);
182
+ }
183
+ else {
184
+ log("No agents in drift.");
185
+ }
186
+ }
187
+ }
188
+ /** ISO-ish timestamp safe for use in a directory name. */
189
+ function timestampDir() {
190
+ // Mock-friendly time source so tests don't have to freeze Date.
191
+ const d = new Date();
192
+ const pad = (n) => String(n).padStart(2, "0");
193
+ return (d.getUTCFullYear() +
194
+ pad(d.getUTCMonth() + 1) +
195
+ pad(d.getUTCDate()) +
196
+ "T" +
197
+ pad(d.getUTCHours()) +
198
+ pad(d.getUTCMinutes()) +
199
+ pad(d.getUTCSeconds()) +
200
+ "Z");
201
+ }
202
+ async function defaultConfirm(prompt) {
203
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
204
+ try {
205
+ const ans = (await rl.question(prompt)).trim().toLowerCase();
206
+ return ans === "y" || ans === "yes";
207
+ }
208
+ finally {
209
+ rl.close();
210
+ }
211
+ }
212
+ export async function runReset(options = {}) {
213
+ const log = options.log ?? ((m) => console.log(m));
214
+ const dataDir = resolveDataDir({
215
+ dir: options.dir,
216
+ env: options.env,
217
+ cwd: options.cwd,
218
+ });
219
+ const paths = dataPaths(dataDir);
220
+ const rows = await templateList({ ...options, agent: options.agent });
221
+ // Semantics:
222
+ // - `reset <agent>` (single): materialise or overwrite — includes `no-local`
223
+ // so the user can `dump` a built-in to disk as a starting point.
224
+ // - `reset` (bulk): only touch drifted files. `no-local` agents already use
225
+ // the built-in via fallback, so materialising them would only manufacture
226
+ // new overrides for the user to maintain.
227
+ const isSingle = Boolean(options.agent);
228
+ const targets = rows.filter((r) => {
229
+ if (!(r.name in PERSONAS))
230
+ return false; // unknown agent — nothing to reset to
231
+ if (r.state === "in-sync")
232
+ return false;
233
+ if (!isSingle && r.state === "no-local")
234
+ return false;
235
+ return true;
236
+ });
237
+ const skipped = [];
238
+ for (const r of rows) {
239
+ if (!(r.name in PERSONAS)) {
240
+ skipped.push({ name: r.name, reason: "unknown agent (no built-in persona)" });
241
+ }
242
+ else if (r.state === "in-sync") {
243
+ skipped.push({ name: r.name, reason: "already in sync" });
244
+ }
245
+ else if (!isSingle && r.state === "no-local") {
246
+ skipped.push({ name: r.name, reason: "no override (already using built-in)" });
247
+ }
248
+ }
249
+ if (targets.length === 0) {
250
+ log("Nothing to reset.");
251
+ return { written: [], skipped };
252
+ }
253
+ if (!options.yes) {
254
+ log(`About to (over)write ${targets.length} prompt file(s):`);
255
+ for (const t of targets)
256
+ log(` - ${t.name} (${t.state})`);
257
+ log(pc.dim(" Existing local prompts will be backed up to `.bp/backups/<timestamp>/`."));
258
+ const confirm = options.confirm ?? defaultConfirm;
259
+ const ok = await confirm("Proceed? [y/N] ");
260
+ if (!ok) {
261
+ log("Aborted.");
262
+ return {
263
+ written: [],
264
+ skipped: targets.map((t) => ({ name: t.name, reason: "user declined" })),
265
+ };
266
+ }
267
+ }
268
+ const ts = timestampDir();
269
+ const backupDir = join(paths.bp, "backups", ts);
270
+ let backupCreated = false;
271
+ const written = [];
272
+ for (const t of targets) {
273
+ // Back up existing on-disk file (only if it exists — drift implies it
274
+ // does, but be defensive: a `no-local` reset has nothing to back up).
275
+ if (await pathExists(t.path)) {
276
+ const existing = await readOrNull(t.path);
277
+ if (existing !== null) {
278
+ const backupPath = join(backupDir, "agents", t.name, "prompt.md");
279
+ await mkdir(dirname(backupPath), { recursive: true });
280
+ await writeFile(backupPath, existing, "utf8");
281
+ backupCreated = true;
282
+ }
283
+ }
284
+ await mkdir(dirname(t.path), { recursive: true });
285
+ await writeFile(t.path, PERSONAS[t.name], "utf8");
286
+ written.push(t.name);
287
+ }
288
+ log(pc.green(`✓ Wrote ${written.length} prompt file(s): ${written.join(", ")}`));
289
+ if (backupCreated)
290
+ log(pc.dim(` Backup: ${backupDir}`));
291
+ if (skipped.length > 0) {
292
+ log(pc.dim(` Skipped: ${skipped.map((s) => `${s.name}(${s.reason})`).join(", ")}`));
293
+ }
294
+ return {
295
+ written,
296
+ skipped,
297
+ ...(backupCreated ? { backupDir } : {}),
298
+ };
299
+ }
300
+ //# sourceMappingURL=template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"template.js","sourceRoot":"","sources":["../../src/commands/template.ts"],"names":[],"mappings":"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"}
@@ -37,9 +37,18 @@ export interface ResolvedUpConfig {
37
37
  }
38
38
  /** Build the StartServerOptions from resolved config — exposed for tests. */
39
39
  export declare function buildStartServerOptions(cfg: ResolvedUpConfig): StartServerOptions;
40
+ /** Pick the right CLI invocation hint based on how the process was launched.
41
+ *
42
+ * Direct binary call → `brainpilot up --port <n>`.
43
+ *
44
+ * npm script call → `npm run <script> -- up --port <n>`. The `--` is required
45
+ * to stop npm from swallowing flags (otherwise it warns "Unknown cli config
46
+ * '--port'" and never passes them through), and the `up` subcommand has to
47
+ * follow it because the script itself only invokes `node bin.js`. */
48
+ export declare function portFlagHint(env?: NodeJS.ProcessEnv): string;
40
49
  export declare class PortInUseError extends Error {
41
50
  readonly port: number;
42
- constructor(port: number);
51
+ constructor(port: number, hint?: string);
43
52
  }
44
53
  export interface UpResult {
45
54
  config: ResolvedUpConfig;
@@ -1 +1 @@
1
- {"version":3,"file":"up.d.ts","sourceRoot":"","sources":["../../src/commands/up.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAQlF,MAAM,WAAW,SAAS;IACxB,gCAAgC;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iFAAiF;IACjF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,2CAA2C;IAC3C,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wEAAwE;AACxE,MAAM,WAAW,MAAM;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,kBAAkB,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;IACnE,2EAA2E;IAC3E,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,gBAAgB,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5D,sEAAsE;IACtE,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9D,oFAAoF;IACpF,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAC9B,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAED,wEAAwE;AACxE,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,EAAE,OAAO,CAAC;CACf;AAED,6EAA6E;AAC7E,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,gBAAgB,GACpB,kBAAkB,CAUpB;AAED,qBAAa,cAAe,SAAQ,KAAK;aACX,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM;CAQzC;AAYD,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,gBAAgB,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,sEAAsE;IACtE,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,6DAA6D;IAC7D,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,wBAAsB,EAAE,CACtB,OAAO,GAAE,SAAc,EACvB,IAAI,GAAE,MAAW,GAChB,OAAO,CAAC,QAAQ,CAAC,CAmEnB"}
1
+ {"version":3,"file":"up.d.ts","sourceRoot":"","sources":["../../src/commands/up.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AASlF,MAAM,WAAW,SAAS;IACxB,gCAAgC;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,iFAAiF;IACjF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,2CAA2C;IAC3C,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wEAAwE;AACxE,MAAM,WAAW,MAAM;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,WAAW,CAAC,EAAE,CAAC,IAAI,EAAE,kBAAkB,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC;IACnE,2EAA2E;IAC3E,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,gBAAgB,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5D,sEAAsE;IACtE,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9D,oFAAoF;IACpF,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,gEAAgE;IAChE,OAAO,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;IAC9B,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7B;AAED,wEAAwE;AACxE,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,EAAE,OAAO,CAAC;CACf;AAED,6EAA6E;AAC7E,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,gBAAgB,GACpB,kBAAkB,CAUpB;AAED;;;;;;;sEAOsE;AACtE,wBAAgB,YAAY,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAMzE;AAED,qBAAa,cAAe,SAAQ,KAAK;aAErB,IAAI,EAAE,MAAM;gBAAZ,IAAI,EAAE,MAAM,EAC5B,IAAI,GAAE,MAAuB;CAShC;AAYD,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,gBAAgB,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,sEAAsE;IACtE,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,6DAA6D;IAC7D,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;GAGG;AACH,wBAAsB,EAAE,CACtB,OAAO,GAAE,SAAc,EACvB,IAAI,GAAE,MAAW,GAChB,OAAO,CAAC,QAAQ,CAAC,CAiGnB"}