@arbiterforge/ca-pi 0.6.2 → 0.8.1
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 +21 -17
- package/package.json +1 -1
- package/plugins/ca-pi/CHANGELOG.md +74 -0
- package/plugins/ca-pi/COMMANDS.md +0 -7
- package/plugins/ca-pi/SKILLS.md +0 -2
- package/plugins/ca-pi/agents/design-quality-reviewer.md +1 -1
- package/plugins/ca-pi/{ORCHESTRATOR.md → arbiter.md} +28 -36
- package/plugins/ca-pi/extensions/codearbiter-child.js +2 -2
- package/plugins/ca-pi/extensions/codearbiter.js +766 -26
- package/plugins/ca-pi/generated/command-catalog.json +0 -10
- package/plugins/ca-pi/hooks/_arbiterstatelib.py +59 -11
- package/plugins/ca-pi/hooks/_bashguardlib.py +12 -1
- package/plugins/ca-pi/hooks/_hooklib.py +58 -17
- package/plugins/ca-pi/hooks/_metricslib.py +20 -0
- package/plugins/ca-pi/hooks/_modelib.py +644 -0
- package/plugins/ca-pi/hooks/_prunelib.py +51 -12
- package/plugins/ca-pi/hooks/_prunepolicy.py +33 -7
- package/plugins/ca-pi/hooks/_readinjectlib.py +10 -4
- package/plugins/ca-pi/hooks/doctor.py +2 -1
- package/plugins/ca-pi/hooks/pi-bridge.py +10 -4
- package/plugins/ca-pi/hooks/prompt-submit.py +486 -0
- package/plugins/ca-pi/hooks/prune-transcript.py +23 -3
- package/plugins/ca-pi/hooks/session-start.py +526 -434
- package/plugins/ca-pi/hooks/statusline.py +27 -9
- package/plugins/ca-pi/includes/anti-slop-design/INDEX.md +1 -1
- package/plugins/ca-pi/includes/dangerous-mode.md +57 -0
- package/plugins/ca-pi/includes/ops-mode.md +96 -0
- package/plugins/ca-pi/includes/pi-host-notes.md +14 -3
- package/plugins/ca-pi/includes/redirect.md +12 -1
- package/plugins/ca-pi/includes/routing-table.md +1 -0
- package/plugins/ca-pi/includes/safety-core.md +86 -0
- package/plugins/ca-pi/includes/smarts/core.md +1 -1
- package/plugins/ca-pi/routines/decision-lifecycle/SKILL.md +1 -1
- package/plugins/ca-pi/routines/decompose/SKILL.md +1 -1
- package/plugins/ca-pi/skills/ca-doctor/SKILL.md +1 -1
- package/plugins/ca-pi/skills/ca-spike/SKILL.md +15 -8
- package/plugins/ca-pi/includes/dev-mode.md +0 -30
- package/plugins/ca-pi/skills/ca-arbiter/SKILL.md +0 -36
- package/plugins/ca-pi/skills/ca-dev/SKILL.md +0 -42
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
var define_CODEARBITER_PI_PERMISSION_POLICY_SURFACES_default = { "ca-plan": "planning-write", codearbiter_background_bash: "background-launch" };
|
|
3
3
|
|
|
4
4
|
// <define:__CODEARBITER_PI_SKILL_EXPANSION_FINGERPRINTS__>
|
|
5
|
-
var define_CODEARBITER_PI_SKILL_EXPANSION_FINGERPRINTS_default = { "0.80.5": "12632f365440b07d5183cff871d889b796a3c711b6b49df20f95d9bc198d6c51", "0.
|
|
5
|
+
var define_CODEARBITER_PI_SKILL_EXPANSION_FINGERPRINTS_default = { "0.80.5": "12632f365440b07d5183cff871d889b796a3c711b6b49df20f95d9bc198d6c51", "0.84.1": "12632f365440b07d5183cff871d889b796a3c711b6b49df20f95d9bc198d6c51" };
|
|
6
6
|
|
|
7
7
|
// <define:__CODEARBITER_PI_TOOL_CLASSES__>
|
|
8
8
|
var define_CODEARBITER_PI_TOOL_CLASSES_default = { bash: "EXEC", codearbiter_background_bash: "EXEC", codearbiter_dispatch: "EXEC", codearbiter_farm_preview: "EXEC", write: "WRITE", edit: "EDIT", read: "READ" };
|
|
@@ -16,7 +16,7 @@ import { fileURLToPath as fileURLToPath5, pathToFileURL as pathToFileURL2 } from
|
|
|
16
16
|
import { types as utilTypes9 } from "node:util";
|
|
17
17
|
|
|
18
18
|
// src/compatibility.ts
|
|
19
|
-
var SUPPORTED_PI_VERSIONS = /* @__PURE__ */ new Set(["0.80.5", "0.
|
|
19
|
+
var SUPPORTED_PI_VERSIONS = /* @__PURE__ */ new Set(["0.80.5", "0.84.1"]);
|
|
20
20
|
var MINIMUM_NODE = [22, 19, 0];
|
|
21
21
|
var SEMVER_PREFIX = /^(\d+)\.(\d+)\.(\d+)(?:$|[-+])/u;
|
|
22
22
|
function atLeast(version, minimum) {
|
|
@@ -31,7 +31,7 @@ function atLeast(version, minimum) {
|
|
|
31
31
|
}
|
|
32
32
|
function compatibilityDirection(input) {
|
|
33
33
|
if (!SUPPORTED_PI_VERSIONS.has(input.piVersion)) {
|
|
34
|
-
return "codeArbiter requires Pi 0.80.5 or 0.
|
|
34
|
+
return "codeArbiter requires Pi 0.80.5 or 0.84.1; install a supported Pi version and run /ca-doctor.";
|
|
35
35
|
}
|
|
36
36
|
if (!atLeast(input.nodeVersion, MINIMUM_NODE)) {
|
|
37
37
|
return "codeArbiter requires Node >=22.19.0 for Pi; upgrade Node and run /ca-doctor.";
|
|
@@ -291,7 +291,7 @@ var PI_STATUS_RESULT_KEYS = /* @__PURE__ */ new Set([
|
|
|
291
291
|
"questions",
|
|
292
292
|
"overrides",
|
|
293
293
|
"sprint",
|
|
294
|
-
"
|
|
294
|
+
"mode",
|
|
295
295
|
"prune"
|
|
296
296
|
]);
|
|
297
297
|
function minimalEnvironment(identities, userHome) {
|
|
@@ -577,14 +577,14 @@ function statusResult(response) {
|
|
|
577
577
|
const patch = record(response.resultPatch);
|
|
578
578
|
if (patch === void 0 || !exactKeys(patch, /* @__PURE__ */ new Set(["footerStatus"]))) return void 0;
|
|
579
579
|
const value = record(patch.footerStatus);
|
|
580
|
-
if (value === void 0 || !exactKeys(value, PI_STATUS_RESULT_KEYS) || value.status !== "ok" || typeof value.stage !== "string" || value.stage.length < 1 || value.stage.length > 128 || CONTROL_RE.test(value.stage) || boundedStatusCount(value.tasks) === void 0 || boundedStatusCount(value.questions) === void 0 || boundedStatusCount(value.overrides) === void 0 || typeof value.sprint !== "boolean" ||
|
|
580
|
+
if (value === void 0 || !exactKeys(value, PI_STATUS_RESULT_KEYS) || value.status !== "ok" || typeof value.stage !== "string" || value.stage.length < 1 || value.stage.length > 128 || CONTROL_RE.test(value.stage) || boundedStatusCount(value.tasks) === void 0 || boundedStatusCount(value.questions) === void 0 || boundedStatusCount(value.overrides) === void 0 || typeof value.sprint !== "boolean" || value.mode !== "arbiter" && value.mode !== "dangerous" && value.mode !== "ops" || value.prune !== null && (typeof value.prune !== "string" || value.prune.length > 256 || CONTROL_RE.test(value.prune))) return void 0;
|
|
581
581
|
return {
|
|
582
582
|
stage: value.stage,
|
|
583
583
|
tasks: value.tasks,
|
|
584
584
|
questions: value.questions,
|
|
585
585
|
overrides: value.overrides,
|
|
586
586
|
sprint: value.sprint,
|
|
587
|
-
|
|
587
|
+
mode: value.mode,
|
|
588
588
|
prune: value.prune === null ? void 0 : value.prune
|
|
589
589
|
};
|
|
590
590
|
}
|
|
@@ -1224,7 +1224,9 @@ import { posix as posix3, win32 as win324 } from "node:path";
|
|
|
1224
1224
|
// src/activity.ts
|
|
1225
1225
|
import { types as utilTypes } from "node:util";
|
|
1226
1226
|
var ACTIVITY_POLICY = Object.freeze({
|
|
1227
|
-
|
|
1227
|
+
// 16 active rows feed the sidebar subagents panel (spec pi-sidebar-panel);
|
|
1228
|
+
// the footer keeps its own tighter display bound.
|
|
1229
|
+
maxActive: 16,
|
|
1228
1230
|
maxRecent: 8,
|
|
1229
1231
|
activeTtlMs: 2 * 60 * 60 * 1e3,
|
|
1230
1232
|
recentTtlMs: 5 * 60 * 1e3,
|
|
@@ -3556,10 +3558,10 @@ function parsePlanLedger(markdown) {
|
|
|
3556
3558
|
if (lines.length > MAX_LEDGER_LINES) return void 0;
|
|
3557
3559
|
let found;
|
|
3558
3560
|
for (let lineIndex = 0; lineIndex < lines.length - 1; lineIndex += 1) {
|
|
3559
|
-
const
|
|
3561
|
+
const header2 = splitTableRow(lines[lineIndex]);
|
|
3560
3562
|
const separator = splitTableRow(lines[lineIndex + 1]);
|
|
3561
|
-
if (
|
|
3562
|
-
const normalizedHeaders =
|
|
3563
|
+
if (header2 === void 0 || separator === void 0 || !isSeparator(separator, header2.length)) continue;
|
|
3564
|
+
const normalizedHeaders = header2.map((cell) => cell.toLowerCase().replace(/\s+/gu, " "));
|
|
3563
3565
|
const taskColumns = normalizedHeaders.flatMap((cell, index) => TASK_HEADERS.has(cell) ? [index] : []);
|
|
3564
3566
|
const statusColumns = normalizedHeaders.flatMap((cell, index) => cell === "status" ? [index] : []);
|
|
3565
3567
|
if (taskColumns.length !== 1 || statusColumns.length !== 1) {
|
|
@@ -3572,7 +3574,7 @@ function parsePlanLedger(markdown) {
|
|
|
3572
3574
|
for (let rowIndex = lineIndex + 2; rowIndex < lines.length; rowIndex += 1) {
|
|
3573
3575
|
const cells = splitTableRow(lines[rowIndex]);
|
|
3574
3576
|
if (cells === void 0) break;
|
|
3575
|
-
if (cells.length !==
|
|
3577
|
+
if (cells.length !== header2.length) return void 0;
|
|
3576
3578
|
const id = cells[taskColumns[0]];
|
|
3577
3579
|
const status = taskStatus(cells[statusColumns[0]]);
|
|
3578
3580
|
if (!TASK_ID.test(id) || CONTROL.test(id) || status === void 0 || ids.has(id)) return void 0;
|
|
@@ -4479,7 +4481,7 @@ function adaptPiFooterState(source) {
|
|
|
4479
4481
|
const entriesValue = callMember2(manager, "getEntries");
|
|
4480
4482
|
const snapshotSession = normalizeSnapshotSession(source.usageSnapshot?.session);
|
|
4481
4483
|
const usage = snapshotSession ?? aggregateSessionUsage(entriesValue);
|
|
4482
|
-
const
|
|
4484
|
+
const sparkline2 = sparklineSeries(entriesValue);
|
|
4483
4485
|
const ageSeconds = sessionAge(callMember2(manager, "getHeader"), now);
|
|
4484
4486
|
const session = usage ? { ...usage, ...ageSeconds === void 0 ? {} : { ageSeconds } } : void 0;
|
|
4485
4487
|
const rawContext = object(callMember2(source.context, "getContextUsage"));
|
|
@@ -4507,7 +4509,7 @@ function adaptPiFooterState(source) {
|
|
|
4507
4509
|
...daily ? { daily } : {},
|
|
4508
4510
|
...updateVersion ? { update: { version: updateVersion } } : {},
|
|
4509
4511
|
...activity ? { activity } : {},
|
|
4510
|
-
...
|
|
4512
|
+
...sparkline2 ? { sparkline: sparkline2 } : {}
|
|
4511
4513
|
};
|
|
4512
4514
|
}
|
|
4513
4515
|
|
|
@@ -4650,9 +4652,10 @@ function gitSegment(git, compact) {
|
|
|
4650
4652
|
return `${colored(COLORS.normal, lead)}${divider}${colored(branchColor, `${branch}${git.dirty ? "*" : ""}`)}`;
|
|
4651
4653
|
}
|
|
4652
4654
|
function governanceSegment(governance) {
|
|
4653
|
-
const
|
|
4655
|
+
const modeBadge = governance.mode === "dangerous" ? " [DANGEROUS]" : governance.mode === "ops" ? " [OPS]" : "";
|
|
4656
|
+
const badge = modeBadge || (governance.sprint ? " [SPRINT]" : "");
|
|
4654
4657
|
const prune = governance.prune ? sanitize2(governance.prune, "") : "";
|
|
4655
|
-
return `${colored(COLORS.ok, "\u25CF")} ${colored(COLORS.normal, `stage:${sanitize2(governance.stage)}`)} ${colored(COLORS.deep, "\xB7")} ${colored(COLORS.normal, `tasks:${boundedCount(governance.tasks)}`)} ${colored(COLORS.deep, "\xB7")} ${colored(governance.questions > 0 ? COLORS.danger : COLORS.muted, `q:${boundedCount(governance.questions)}`)} ${colored(COLORS.deep, "\xB7")} ${colored(governance.overrides > 0 ? COLORS.danger : COLORS.muted, `over:${boundedCount(governance.overrides)}`)}` + (prune ? ` ${colored(COLORS.deep, "\xB7")} ${colored(COLORS.muted, `prune:${prune}`)}` : "") + (badge ? colored(governance.
|
|
4658
|
+
return `${colored(COLORS.ok, "\u25CF")} ${colored(COLORS.normal, `stage:${sanitize2(governance.stage)}`)} ${colored(COLORS.deep, "\xB7")} ${colored(COLORS.normal, `tasks:${boundedCount(governance.tasks)}`)} ${colored(COLORS.deep, "\xB7")} ${colored(governance.questions > 0 ? COLORS.danger : COLORS.muted, `q:${boundedCount(governance.questions)}`)} ${colored(COLORS.deep, "\xB7")} ${colored(governance.overrides > 0 ? COLORS.danger : COLORS.muted, `over:${boundedCount(governance.overrides)}`)}` + (prune ? ` ${colored(COLORS.deep, "\xB7")} ${colored(COLORS.muted, `prune:${prune}`)}` : "") + (badge ? colored(governance.mode === "dangerous" ? COLORS.danger : COLORS.bright, badge) : "");
|
|
4656
4659
|
}
|
|
4657
4660
|
function usageRow(label, usage) {
|
|
4658
4661
|
return `${colored(COLORS.muted, label.padEnd(7))} ${colored(COLORS.deep, "\u2502")} ${colored(COLORS.primary, "\u2193")} ${colored(COLORS.normal, formatTokens(usage.inputTokens).padStart(6))} ${colored(COLORS.primary, "\u2191")} ${colored(COLORS.normal, formatTokens(usage.outputTokens).padStart(6))} ${colored(COLORS.deep, "\u2502")} ${colored(COLORS.ok, formatUsd(usage.costUsd))}`;
|
|
@@ -4693,8 +4696,8 @@ var SPARK_GLYPHS = ["\u2581", "\u2582", "\u2583", "\u2584", "\u2585", "\u2586",
|
|
|
4693
4696
|
function activityRows(activity) {
|
|
4694
4697
|
const rows = activity.slice(0, ACTIVITY_MAX_ROWS).map((item) => {
|
|
4695
4698
|
const glyph = item.state === "active" ? colored(COLORS.ok, "\u25CF") : colored(COLORS.muted, "\u2713");
|
|
4696
|
-
const
|
|
4697
|
-
return `${glyph} ${sanitize2(item.kind, "job")}:${sanitize2(item.label)}${
|
|
4699
|
+
const age2 = item.ageSeconds === void 0 ? "" : ` ${formatDuration(item.ageSeconds)}`;
|
|
4700
|
+
return `${glyph} ${sanitize2(item.kind, "job")}:${sanitize2(item.label)}${age2}`;
|
|
4698
4701
|
});
|
|
4699
4702
|
if (rows.length === 0) return rows;
|
|
4700
4703
|
rows[0] = `${colored(COLORS.bright, "activity")} ${rows[0]}`;
|
|
@@ -4767,8 +4770,8 @@ function renderCompact(input, box) {
|
|
|
4767
4770
|
if (readValue !== void 0 || writeValue !== void 0) {
|
|
4768
4771
|
bits.push(`cache ${read + write > 0 ? Math.round(read / (read + write) * 100) : 0}%`);
|
|
4769
4772
|
}
|
|
4770
|
-
const
|
|
4771
|
-
if (
|
|
4773
|
+
const age2 = usage.ageSeconds;
|
|
4774
|
+
if (age2 !== void 0) bits.push(`age ${formatDuration(age2)}`);
|
|
4772
4775
|
return bits.join(" \xB7 ");
|
|
4773
4776
|
}, "");
|
|
4774
4777
|
const daily = guard(() => {
|
|
@@ -4893,6 +4896,7 @@ var PiFooterLifecycle = class {
|
|
|
4893
4896
|
governance;
|
|
4894
4897
|
updateVersion;
|
|
4895
4898
|
gitFacts;
|
|
4899
|
+
lastInput;
|
|
4896
4900
|
activationEnabled = false;
|
|
4897
4901
|
expected = false;
|
|
4898
4902
|
installed = false;
|
|
@@ -4900,6 +4904,16 @@ var PiFooterLifecycle = class {
|
|
|
4900
4904
|
requestActivityRender() {
|
|
4901
4905
|
requestRender(this.tui);
|
|
4902
4906
|
}
|
|
4907
|
+
/** The live tui handle captured by the footer factory; the sidebar
|
|
4908
|
+
* compositor probes it for the undocumented doRender hook. */
|
|
4909
|
+
currentTui() {
|
|
4910
|
+
return this.tui;
|
|
4911
|
+
}
|
|
4912
|
+
/** The most recently rendered footer input — the sidebar's session,
|
|
4913
|
+
* subagents and workspace panels reuse these already-gathered facts. */
|
|
4914
|
+
lastRenderedInput() {
|
|
4915
|
+
return this.lastInput;
|
|
4916
|
+
}
|
|
4903
4917
|
health() {
|
|
4904
4918
|
return Object.freeze({
|
|
4905
4919
|
expected: this.expected,
|
|
@@ -4982,10 +4996,11 @@ var PiFooterLifecycle = class {
|
|
|
4982
4996
|
questions: this.governance.questions,
|
|
4983
4997
|
overrides: this.governance.overrides,
|
|
4984
4998
|
sprint: this.governance.sprint,
|
|
4985
|
-
|
|
4999
|
+
mode: this.governance.mode,
|
|
4986
5000
|
...this.governance.prune === void 0 ? {} : { prune: this.governance.prune }
|
|
4987
5001
|
}
|
|
4988
5002
|
};
|
|
5003
|
+
this.lastInput = enriched;
|
|
4989
5004
|
const rendered = renderFooter(enriched, {
|
|
4990
5005
|
width,
|
|
4991
5006
|
noColor: Object.prototype.hasOwnProperty.call(process.env, "NO_COLOR")
|
|
@@ -5063,6 +5078,7 @@ var PiFooterLifecycle = class {
|
|
|
5063
5078
|
this.governance = void 0;
|
|
5064
5079
|
this.updateVersion = void 0;
|
|
5065
5080
|
this.gitFacts = void 0;
|
|
5081
|
+
this.lastInput = void 0;
|
|
5066
5082
|
this.activationEnabled = false;
|
|
5067
5083
|
this.expected = false;
|
|
5068
5084
|
this.refreshQueue = Promise.resolve();
|
|
@@ -5079,6 +5095,675 @@ var PiFooterLifecycle = class {
|
|
|
5079
5095
|
}
|
|
5080
5096
|
};
|
|
5081
5097
|
|
|
5098
|
+
// src/sidebar.ts
|
|
5099
|
+
var SIDEBAR_MAX_AGENT_ROWS = 16;
|
|
5100
|
+
var MAX_TODO_ROWS = 12;
|
|
5101
|
+
var MAX_MCP_ROWS = 8;
|
|
5102
|
+
var MAX_LIST_ITEMS = 256;
|
|
5103
|
+
var MAX_TEXT_POINTS3 = 512;
|
|
5104
|
+
var SPARK_GLYPHS2 = ["\u2581", "\u2582", "\u2583", "\u2584", "\u2585", "\u2586", "\u2587", "\u2588"];
|
|
5105
|
+
var ESC2 = "\x1B";
|
|
5106
|
+
var RESET2 = `${ESC2}[0m`;
|
|
5107
|
+
var HEADER_COLOR = `${ESC2}[38;2;178;102;255m`;
|
|
5108
|
+
var MUTED = `${ESC2}[38;2;150;150;162m`;
|
|
5109
|
+
var OK = `${ESC2}[38;2;120;220;150m`;
|
|
5110
|
+
var WARN = `${ESC2}[38;2;255;184;76m`;
|
|
5111
|
+
var OSC_RE2 = /\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)?/gu;
|
|
5112
|
+
var CSI_RE2 = /\x1b\[[0-?]*[ -/]*[@-~]?/gu;
|
|
5113
|
+
var ESCAPE_RE2 = /\x1b[@-_]/gu;
|
|
5114
|
+
var CONTROL_RE3 = /[\u0000-\u001f\u007f-\u009f\u061c\u200b-\u200f\u2028\u2029\u202a-\u202e\u2060-\u206f\ufeff]/gu;
|
|
5115
|
+
function sanitize3(value) {
|
|
5116
|
+
if (typeof value !== "string") return "";
|
|
5117
|
+
return value.replace(OSC_RE2, "").replace(CSI_RE2, "").replace(ESCAPE_RE2, "").replace(CONTROL_RE3, "").slice(0, MAX_TEXT_POINTS3);
|
|
5118
|
+
}
|
|
5119
|
+
function boundedNumber2(value, maximum) {
|
|
5120
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) return 0;
|
|
5121
|
+
return Math.min(value, maximum);
|
|
5122
|
+
}
|
|
5123
|
+
var COLOR_PALETTE = { header: HEADER_COLOR, muted: MUTED, ok: OK, warn: WARN, reset: RESET2 };
|
|
5124
|
+
var PLAIN_PALETTE = { header: "", muted: "", ok: "", warn: "", reset: "" };
|
|
5125
|
+
function fit(text2, context) {
|
|
5126
|
+
const { width, metrics, palette } = context;
|
|
5127
|
+
let value = text2;
|
|
5128
|
+
let visible;
|
|
5129
|
+
try {
|
|
5130
|
+
visible = metrics.visibleWidth(value);
|
|
5131
|
+
} catch {
|
|
5132
|
+
value = "";
|
|
5133
|
+
visible = 0;
|
|
5134
|
+
}
|
|
5135
|
+
if (visible > width) {
|
|
5136
|
+
try {
|
|
5137
|
+
value = metrics.truncateToWidth(value, width, "\u2026");
|
|
5138
|
+
visible = metrics.visibleWidth(value);
|
|
5139
|
+
} catch {
|
|
5140
|
+
value = "";
|
|
5141
|
+
visible = 0;
|
|
5142
|
+
}
|
|
5143
|
+
}
|
|
5144
|
+
if (visible > width) {
|
|
5145
|
+
value = "";
|
|
5146
|
+
visible = 0;
|
|
5147
|
+
}
|
|
5148
|
+
const padded = value + " ".repeat(width - visible);
|
|
5149
|
+
return palette.reset === "" ? padded : padded + palette.reset;
|
|
5150
|
+
}
|
|
5151
|
+
function header(title, context) {
|
|
5152
|
+
const { width, palette } = context;
|
|
5153
|
+
const label = ` ${title} `;
|
|
5154
|
+
const room = Math.max(0, width - label.length - 2);
|
|
5155
|
+
const bar = "\u2500";
|
|
5156
|
+
const text2 = `${bar}${label}${bar.repeat(room)}`.slice(0, width);
|
|
5157
|
+
return fit(`${palette.header}${text2}`, context);
|
|
5158
|
+
}
|
|
5159
|
+
function tokensLabel(input, output) {
|
|
5160
|
+
const compact = (value) => value >= 1e3 ? `${(value / 1e3).toFixed(1)}k` : String(value);
|
|
5161
|
+
return `${compact(input)}\u2191 ${compact(output)}\u2193`;
|
|
5162
|
+
}
|
|
5163
|
+
function sparkline(series) {
|
|
5164
|
+
const bounded = series.slice(-16).map((value) => boundedNumber2(value, Number.MAX_SAFE_INTEGER));
|
|
5165
|
+
if (bounded.length === 0) return "";
|
|
5166
|
+
const maximum = Math.max(...bounded);
|
|
5167
|
+
return bounded.map((value) => {
|
|
5168
|
+
const level = maximum > 0 ? Math.min(8, Math.max(1, Math.ceil(value / maximum * 8))) : 1;
|
|
5169
|
+
return SPARK_GLYPHS2[level - 1];
|
|
5170
|
+
}).join("");
|
|
5171
|
+
}
|
|
5172
|
+
function sessionPanel(session, context) {
|
|
5173
|
+
const { palette } = context;
|
|
5174
|
+
const lines = [header("session", context)];
|
|
5175
|
+
const model = sanitize3(session.model);
|
|
5176
|
+
const thinking = sanitize3(session.thinkingLevel);
|
|
5177
|
+
if (model !== "") lines.push(fit(` ${model}${thinking === "" ? "" : `${palette.muted} \xB7 ${thinking}`}`, context));
|
|
5178
|
+
const percent = boundedNumber2(session.contextPercent, 999);
|
|
5179
|
+
if (session.contextPercent !== void 0) {
|
|
5180
|
+
const cells = 10;
|
|
5181
|
+
const filled = Math.min(cells, Math.round(Math.min(percent, 100) / 100 * cells));
|
|
5182
|
+
const bar = "\u2588".repeat(filled) + "\u2591".repeat(cells - filled);
|
|
5183
|
+
const tone = percent >= 80 ? palette.warn : palette.ok;
|
|
5184
|
+
lines.push(fit(` ctx ${tone}${bar}${palette.reset === "" ? "" : palette.reset} ${Math.round(percent)}%`, context));
|
|
5185
|
+
}
|
|
5186
|
+
const input = boundedNumber2(session.inputTokens, Number.MAX_SAFE_INTEGER);
|
|
5187
|
+
const output = boundedNumber2(session.outputTokens, Number.MAX_SAFE_INTEGER);
|
|
5188
|
+
const cost = boundedNumber2(session.costUsd, 1e9);
|
|
5189
|
+
if (session.inputTokens !== void 0 || session.outputTokens !== void 0 || session.costUsd !== void 0) {
|
|
5190
|
+
lines.push(fit(` ${tokensLabel(input, output)}${palette.muted} \xB7 $${cost.toFixed(cost >= 100 ? 0 : 2)}`, context));
|
|
5191
|
+
}
|
|
5192
|
+
if (session.burn !== void 0 && session.burn.length > 0) {
|
|
5193
|
+
lines.push(fit(` burn ${sparkline(session.burn)}`, context));
|
|
5194
|
+
}
|
|
5195
|
+
return lines;
|
|
5196
|
+
}
|
|
5197
|
+
function agentGlyph(row, palette) {
|
|
5198
|
+
if (row.state === "active") return `${palette.ok}\u25CF${palette.reset === "" ? "" : palette.reset}`;
|
|
5199
|
+
return `${palette.muted}\u25CB${palette.reset === "" ? "" : palette.reset}`;
|
|
5200
|
+
}
|
|
5201
|
+
function age(seconds) {
|
|
5202
|
+
const bounded = boundedNumber2(seconds, 3650 * 86400);
|
|
5203
|
+
if (bounded >= 3600) return `${Math.floor(bounded / 3600)}h`;
|
|
5204
|
+
if (bounded >= 60) return `${Math.floor(bounded / 60)}m`;
|
|
5205
|
+
return `${Math.floor(bounded)}s`;
|
|
5206
|
+
}
|
|
5207
|
+
function agentsPanel(rows, context) {
|
|
5208
|
+
const { palette } = context;
|
|
5209
|
+
const lines = [header("agents", context)];
|
|
5210
|
+
const bounded = rows.slice(0, MAX_LIST_ITEMS);
|
|
5211
|
+
for (const row of bounded.slice(0, SIDEBAR_MAX_AGENT_ROWS)) {
|
|
5212
|
+
const label = sanitize3(row.label);
|
|
5213
|
+
const kind = row.kind === "job" ? "job" : "child";
|
|
5214
|
+
const suffix = row.ageSeconds === void 0 ? "" : ` ${age(row.ageSeconds)}`;
|
|
5215
|
+
lines.push(fit(` ${agentGlyph(row, palette)} ${label}${palette.muted} \xB7 ${kind}${suffix}`, context));
|
|
5216
|
+
}
|
|
5217
|
+
if (bounded.length > SIDEBAR_MAX_AGENT_ROWS) {
|
|
5218
|
+
lines.push(fit(` ${palette.muted}+${bounded.length - SIDEBAR_MAX_AGENT_ROWS} more`, context));
|
|
5219
|
+
}
|
|
5220
|
+
return lines;
|
|
5221
|
+
}
|
|
5222
|
+
function workspacePanel(workspace, context) {
|
|
5223
|
+
const { palette } = context;
|
|
5224
|
+
const lines = [header("workspace", context)];
|
|
5225
|
+
const repository = sanitize3(workspace.repository);
|
|
5226
|
+
if (repository !== "") {
|
|
5227
|
+
const dirty = workspace.dirty === true ? `${palette.warn} \u25CF` : "";
|
|
5228
|
+
lines.push(fit(` ${repository}${dirty}`, context));
|
|
5229
|
+
}
|
|
5230
|
+
const cwd = sanitize3(workspace.cwd);
|
|
5231
|
+
if (cwd !== "") lines.push(fit(` ${palette.muted}${cwd}`, context));
|
|
5232
|
+
return lines;
|
|
5233
|
+
}
|
|
5234
|
+
var TODO_GLYPHS = {
|
|
5235
|
+
done: "\u2713",
|
|
5236
|
+
active: "\u25B8",
|
|
5237
|
+
open: "\xB7"
|
|
5238
|
+
};
|
|
5239
|
+
function todosPanel(rows, context) {
|
|
5240
|
+
const { palette } = context;
|
|
5241
|
+
const lines = [header("todos", context)];
|
|
5242
|
+
const bounded = rows.slice(0, MAX_LIST_ITEMS);
|
|
5243
|
+
for (const row of bounded.slice(0, MAX_TODO_ROWS)) {
|
|
5244
|
+
const glyph = TODO_GLYPHS[row.state] ?? TODO_GLYPHS.open;
|
|
5245
|
+
const tone = row.state === "done" ? palette.muted : row.state === "active" ? palette.ok : "";
|
|
5246
|
+
lines.push(fit(` ${tone}${glyph} ${sanitize3(row.text)}`, context));
|
|
5247
|
+
}
|
|
5248
|
+
if (bounded.length > MAX_TODO_ROWS) {
|
|
5249
|
+
lines.push(fit(` ${palette.muted}+${bounded.length - MAX_TODO_ROWS} more`, context));
|
|
5250
|
+
}
|
|
5251
|
+
return lines;
|
|
5252
|
+
}
|
|
5253
|
+
function mcpPanel(rows, context) {
|
|
5254
|
+
const { palette } = context;
|
|
5255
|
+
const lines = [header("mcp", context)];
|
|
5256
|
+
const bounded = rows.slice(0, MAX_LIST_ITEMS);
|
|
5257
|
+
for (const row of bounded.slice(0, MAX_MCP_ROWS)) {
|
|
5258
|
+
const state = sanitize3(row.state);
|
|
5259
|
+
const tone = state === "connected" ? palette.ok : palette.muted;
|
|
5260
|
+
lines.push(fit(` ${tone}\u25CF${palette.reset === "" ? "" : palette.reset} ${sanitize3(row.name)}${palette.muted} \xB7 ${state}`, context));
|
|
5261
|
+
}
|
|
5262
|
+
return lines;
|
|
5263
|
+
}
|
|
5264
|
+
function renderSidebar(input, width, metrics, options) {
|
|
5265
|
+
const safeWidth = Number.isSafeInteger(width) && width > 0 ? Math.min(width, 160) : 40;
|
|
5266
|
+
const palette = options?.noColor === true ? PLAIN_PALETTE : COLOR_PALETTE;
|
|
5267
|
+
const context = { width: safeWidth, metrics, palette };
|
|
5268
|
+
const lines = [];
|
|
5269
|
+
const panels = [
|
|
5270
|
+
["session", () => {
|
|
5271
|
+
const session = input.session;
|
|
5272
|
+
return session === void 0 ? void 0 : sessionPanel(session, context);
|
|
5273
|
+
}],
|
|
5274
|
+
["agents", () => {
|
|
5275
|
+
const rows = input.subagents;
|
|
5276
|
+
return rows === void 0 || rows.length === 0 ? void 0 : agentsPanel(rows, context);
|
|
5277
|
+
}],
|
|
5278
|
+
["workspace", () => {
|
|
5279
|
+
const workspace = input.workspace;
|
|
5280
|
+
return workspace === void 0 ? void 0 : workspacePanel(workspace, context);
|
|
5281
|
+
}],
|
|
5282
|
+
["todos", () => {
|
|
5283
|
+
const rows = input.todos;
|
|
5284
|
+
return rows === void 0 || rows.length === 0 ? void 0 : todosPanel(rows, context);
|
|
5285
|
+
}],
|
|
5286
|
+
["mcp", () => {
|
|
5287
|
+
const rows = input.mcp;
|
|
5288
|
+
return rows === void 0 || rows.length === 0 ? void 0 : mcpPanel(rows, context);
|
|
5289
|
+
}]
|
|
5290
|
+
];
|
|
5291
|
+
for (const [title, render] of panels) {
|
|
5292
|
+
let rendered;
|
|
5293
|
+
try {
|
|
5294
|
+
rendered = render();
|
|
5295
|
+
} catch {
|
|
5296
|
+
rendered = [header(title, context), fit(` ${palette.muted}(unavailable)`, context)];
|
|
5297
|
+
}
|
|
5298
|
+
if (rendered === void 0 || rendered.length === 0) continue;
|
|
5299
|
+
if (lines.length > 0) lines.push(fit("", context));
|
|
5300
|
+
lines.push(...rendered);
|
|
5301
|
+
}
|
|
5302
|
+
return Object.freeze(lines);
|
|
5303
|
+
}
|
|
5304
|
+
|
|
5305
|
+
// src/sidebar-compositor.ts
|
|
5306
|
+
var SIDEBAR_DEFAULT_WIDTH = 40;
|
|
5307
|
+
var SIDEBAR_MIN_WIDTH = 24;
|
|
5308
|
+
var SIDEBAR_MAX_WIDTH = 60;
|
|
5309
|
+
var SIDEBAR_MAIN_COLUMN_FLOOR = 60;
|
|
5310
|
+
var GEOMETRY_FAILURE_LIMIT = 3;
|
|
5311
|
+
var ESC3 = "\x1B";
|
|
5312
|
+
var SYNC_START = `${ESC3}[?2026h`;
|
|
5313
|
+
var SYNC_END = `${ESC3}[?2026l`;
|
|
5314
|
+
var CURSOR_SAVE = `${ESC3}7`;
|
|
5315
|
+
var CURSOR_RESTORE = `${ESC3}8`;
|
|
5316
|
+
var WRAP_OFF = `${ESC3}[?7l`;
|
|
5317
|
+
var WRAP_ON = `${ESC3}[?7h`;
|
|
5318
|
+
var RESET3 = `${ESC3}[0m`;
|
|
5319
|
+
function unavailable(reason) {
|
|
5320
|
+
return Object.freeze({
|
|
5321
|
+
installed: false,
|
|
5322
|
+
reason,
|
|
5323
|
+
setWidth: () => void 0,
|
|
5324
|
+
dispose: () => void 0
|
|
5325
|
+
});
|
|
5326
|
+
}
|
|
5327
|
+
function columnsDescriptor(terminal) {
|
|
5328
|
+
let target = terminal;
|
|
5329
|
+
while (target !== null) {
|
|
5330
|
+
const descriptor = Object.getOwnPropertyDescriptor(target, "columns");
|
|
5331
|
+
if (descriptor !== void 0) return descriptor;
|
|
5332
|
+
target = Object.getPrototypeOf(target);
|
|
5333
|
+
}
|
|
5334
|
+
return void 0;
|
|
5335
|
+
}
|
|
5336
|
+
function probeSidebarSupport(tui, terminal, metrics) {
|
|
5337
|
+
if (typeof metrics?.visibleWidth !== "function" || typeof metrics?.truncateToWidth !== "function") {
|
|
5338
|
+
return { ok: false, reason: "no-metrics" };
|
|
5339
|
+
}
|
|
5340
|
+
if (typeof tui?.doRender !== "function") return { ok: false, reason: "no-dorender" };
|
|
5341
|
+
const descriptor = columnsDescriptor(terminal);
|
|
5342
|
+
if (descriptor === void 0 || descriptor.configurable !== true) {
|
|
5343
|
+
return { ok: false, reason: "columns-not-configurable" };
|
|
5344
|
+
}
|
|
5345
|
+
return { ok: true };
|
|
5346
|
+
}
|
|
5347
|
+
function clampWidth(width) {
|
|
5348
|
+
if (typeof width !== "number" || !Number.isFinite(width)) return SIDEBAR_DEFAULT_WIDTH;
|
|
5349
|
+
return Math.min(SIDEBAR_MAX_WIDTH, Math.max(SIDEBAR_MIN_WIDTH, Math.floor(width)));
|
|
5350
|
+
}
|
|
5351
|
+
var Compositor = class {
|
|
5352
|
+
constructor(ports, width) {
|
|
5353
|
+
this.ports = ports;
|
|
5354
|
+
this.width = width;
|
|
5355
|
+
this.hadOwnColumns = Object.getOwnPropertyDescriptor(ports.terminal, "columns") !== void 0;
|
|
5356
|
+
this.hadOwnDoRender = Object.getOwnPropertyDescriptor(ports.tui, "doRender") !== void 0;
|
|
5357
|
+
this.originalDescriptor = columnsDescriptor(ports.terminal);
|
|
5358
|
+
this.liveRawColumns = this.originalDescriptor.value;
|
|
5359
|
+
this.originalDoRender = ports.tui.doRender;
|
|
5360
|
+
this.defineNarrowedColumns();
|
|
5361
|
+
this.paintAfterRender = (...args) => {
|
|
5362
|
+
const result3 = this.originalDoRender.apply(ports.tui, args);
|
|
5363
|
+
this.paint();
|
|
5364
|
+
return result3;
|
|
5365
|
+
};
|
|
5366
|
+
ports.tui.doRender = this.paintAfterRender;
|
|
5367
|
+
}
|
|
5368
|
+
ports;
|
|
5369
|
+
active = true;
|
|
5370
|
+
width;
|
|
5371
|
+
geometryFailures = 0;
|
|
5372
|
+
warned = false;
|
|
5373
|
+
narrowedGetter;
|
|
5374
|
+
/** Live raw width for data-descriptor terminals: the host's resize handler
|
|
5375
|
+
* assigns `terminal.columns = N`, which our accessor's setter records here so
|
|
5376
|
+
* neither the host nor the paint path ever sees a stale install-time width. */
|
|
5377
|
+
liveRawColumns;
|
|
5378
|
+
hadOwnColumns;
|
|
5379
|
+
hadOwnDoRender;
|
|
5380
|
+
originalDescriptor;
|
|
5381
|
+
originalDoRender;
|
|
5382
|
+
paintAfterRender;
|
|
5383
|
+
get installed() {
|
|
5384
|
+
return this.active;
|
|
5385
|
+
}
|
|
5386
|
+
setWidth(width) {
|
|
5387
|
+
if (!this.active) return;
|
|
5388
|
+
this.width = clampWidth(width);
|
|
5389
|
+
this.defineNarrowedColumns();
|
|
5390
|
+
try {
|
|
5391
|
+
this.ports.tui.requestRender();
|
|
5392
|
+
} catch {
|
|
5393
|
+
}
|
|
5394
|
+
}
|
|
5395
|
+
dispose() {
|
|
5396
|
+
if (!this.active) return;
|
|
5397
|
+
this.active = false;
|
|
5398
|
+
try {
|
|
5399
|
+
const own = Object.getOwnPropertyDescriptor(this.ports.terminal, "columns");
|
|
5400
|
+
if (own?.get === this.narrowedGetter) {
|
|
5401
|
+
if (!this.hadOwnColumns) {
|
|
5402
|
+
delete this.ports.terminal.columns;
|
|
5403
|
+
} else if (this.originalDescriptor.get !== void 0) {
|
|
5404
|
+
Object.defineProperty(this.ports.terminal, "columns", this.originalDescriptor);
|
|
5405
|
+
} else {
|
|
5406
|
+
Object.defineProperty(this.ports.terminal, "columns", {
|
|
5407
|
+
...this.originalDescriptor,
|
|
5408
|
+
value: this.liveRawColumns
|
|
5409
|
+
});
|
|
5410
|
+
}
|
|
5411
|
+
}
|
|
5412
|
+
} catch {
|
|
5413
|
+
}
|
|
5414
|
+
try {
|
|
5415
|
+
if (this.ports.tui.doRender === this.paintAfterRender) {
|
|
5416
|
+
if (this.hadOwnDoRender) this.ports.tui.doRender = this.originalDoRender;
|
|
5417
|
+
else delete this.ports.tui.doRender;
|
|
5418
|
+
}
|
|
5419
|
+
} catch {
|
|
5420
|
+
}
|
|
5421
|
+
try {
|
|
5422
|
+
this.ports.tui.requestRender();
|
|
5423
|
+
} catch {
|
|
5424
|
+
}
|
|
5425
|
+
}
|
|
5426
|
+
readRawColumns() {
|
|
5427
|
+
return this.originalDescriptor.get !== void 0 ? this.originalDescriptor.get.call(this.ports.terminal) : this.liveRawColumns;
|
|
5428
|
+
}
|
|
5429
|
+
/** "too-narrow" is a recoverable skip — the hooks stay installed and the
|
|
5430
|
+
* next paint re-checks; `undefined` means the surface is no longer
|
|
5431
|
+
* understood and counts toward disposal. */
|
|
5432
|
+
rawGeometry() {
|
|
5433
|
+
const own = Object.getOwnPropertyDescriptor(this.ports.terminal, "columns");
|
|
5434
|
+
if (own?.get !== this.narrowedGetter) return void 0;
|
|
5435
|
+
let rawColumns2;
|
|
5436
|
+
try {
|
|
5437
|
+
rawColumns2 = this.readRawColumns();
|
|
5438
|
+
} catch {
|
|
5439
|
+
return void 0;
|
|
5440
|
+
}
|
|
5441
|
+
const rows = this.ports.terminal.rows;
|
|
5442
|
+
if (typeof rawColumns2 !== "number" || !Number.isFinite(rawColumns2)) return void 0;
|
|
5443
|
+
if (typeof rows !== "number" || !Number.isFinite(rows) || rows <= 0) return void 0;
|
|
5444
|
+
if (rawColumns2 < this.width + SIDEBAR_MAIN_COLUMN_FLOOR) return "too-narrow";
|
|
5445
|
+
return { rawColumns: Math.floor(rawColumns2), rows: Math.floor(rows) };
|
|
5446
|
+
}
|
|
5447
|
+
defineNarrowedColumns() {
|
|
5448
|
+
const narrowed = () => {
|
|
5449
|
+
const geometry = this.rawGeometry();
|
|
5450
|
+
if (geometry === void 0 || geometry === "too-narrow") {
|
|
5451
|
+
try {
|
|
5452
|
+
return this.readRawColumns();
|
|
5453
|
+
} catch {
|
|
5454
|
+
return this.width + SIDEBAR_MAIN_COLUMN_FLOOR;
|
|
5455
|
+
}
|
|
5456
|
+
}
|
|
5457
|
+
return geometry.rawColumns - (this.width + 1);
|
|
5458
|
+
};
|
|
5459
|
+
this.narrowedGetter = narrowed;
|
|
5460
|
+
Object.defineProperty(this.ports.terminal, "columns", {
|
|
5461
|
+
configurable: true,
|
|
5462
|
+
enumerable: true,
|
|
5463
|
+
get: narrowed,
|
|
5464
|
+
// The host's resize handler assigns `columns`; route the assignment to
|
|
5465
|
+
// the original setter, or record it as the live raw width.
|
|
5466
|
+
set: (value) => {
|
|
5467
|
+
if (this.originalDescriptor.set !== void 0) {
|
|
5468
|
+
try {
|
|
5469
|
+
this.originalDescriptor.set.call(this.ports.terminal, value);
|
|
5470
|
+
} catch {
|
|
5471
|
+
}
|
|
5472
|
+
} else {
|
|
5473
|
+
this.liveRawColumns = value;
|
|
5474
|
+
}
|
|
5475
|
+
}
|
|
5476
|
+
});
|
|
5477
|
+
}
|
|
5478
|
+
/** AC-3: paint inside a synchronized-output envelope; every cycle
|
|
5479
|
+
* re-validates raw geometry first and a persistent failure disposes. */
|
|
5480
|
+
paint() {
|
|
5481
|
+
if (!this.active) return;
|
|
5482
|
+
try {
|
|
5483
|
+
const geometry = this.rawGeometry();
|
|
5484
|
+
if (geometry === "too-narrow") return;
|
|
5485
|
+
if (geometry === void 0) {
|
|
5486
|
+
this.geometryFailures += 1;
|
|
5487
|
+
if (this.geometryFailures >= GEOMETRY_FAILURE_LIMIT) this.dispose();
|
|
5488
|
+
return;
|
|
5489
|
+
}
|
|
5490
|
+
this.geometryFailures = 0;
|
|
5491
|
+
const lines = renderSidebar(this.ports.dataSource(), this.width, this.ports.metrics, {
|
|
5492
|
+
noColor: this.ports.noColor
|
|
5493
|
+
});
|
|
5494
|
+
const separatorColumn = geometry.rawColumns - this.width;
|
|
5495
|
+
const parts = [SYNC_START, CURSOR_SAVE, WRAP_OFF];
|
|
5496
|
+
for (let row = 1; row <= geometry.rows; row += 1) {
|
|
5497
|
+
const content = row - 1 < lines.length ? lines[row - 1] : " ".repeat(this.width);
|
|
5498
|
+
parts.push(`${ESC3}[${row};${separatorColumn}H${RESET3}\u2502${content}`);
|
|
5499
|
+
}
|
|
5500
|
+
parts.push(WRAP_ON, CURSOR_RESTORE, SYNC_END);
|
|
5501
|
+
this.ports.writeOut(parts.join(""));
|
|
5502
|
+
} catch {
|
|
5503
|
+
this.dispose();
|
|
5504
|
+
if (!this.warned) {
|
|
5505
|
+
this.warned = true;
|
|
5506
|
+
try {
|
|
5507
|
+
this.ports.notify("codeArbiter sidebar disabled after a paint failure; run /ca-doctor.");
|
|
5508
|
+
} catch {
|
|
5509
|
+
}
|
|
5510
|
+
}
|
|
5511
|
+
}
|
|
5512
|
+
}
|
|
5513
|
+
};
|
|
5514
|
+
function installSidebar(ports, options) {
|
|
5515
|
+
const probe = probeSidebarSupport(ports.tui, ports.terminal, ports.metrics);
|
|
5516
|
+
if (!probe.ok) return unavailable(probe.reason);
|
|
5517
|
+
const width = clampWidth(options.width);
|
|
5518
|
+
const descriptor = columnsDescriptor(ports.terminal);
|
|
5519
|
+
let rawColumns2;
|
|
5520
|
+
try {
|
|
5521
|
+
rawColumns2 = descriptor.get !== void 0 ? descriptor.get.call(ports.terminal) : descriptor.value;
|
|
5522
|
+
} catch {
|
|
5523
|
+
return unavailable("geometry-unreadable");
|
|
5524
|
+
}
|
|
5525
|
+
if (typeof rawColumns2 !== "number" || !Number.isFinite(rawColumns2) || rawColumns2 < width + SIDEBAR_MAIN_COLUMN_FLOOR) {
|
|
5526
|
+
return unavailable("terminal-too-narrow");
|
|
5527
|
+
}
|
|
5528
|
+
const hadOwnColumns = Object.getOwnPropertyDescriptor(ports.terminal, "columns") !== void 0;
|
|
5529
|
+
try {
|
|
5530
|
+
return new Compositor(ports, width);
|
|
5531
|
+
} catch {
|
|
5532
|
+
try {
|
|
5533
|
+
if (hadOwnColumns) Object.defineProperty(ports.terminal, "columns", descriptor);
|
|
5534
|
+
else delete ports.terminal.columns;
|
|
5535
|
+
} catch {
|
|
5536
|
+
}
|
|
5537
|
+
return unavailable("install-failed");
|
|
5538
|
+
}
|
|
5539
|
+
}
|
|
5540
|
+
|
|
5541
|
+
// src/sidebar-manager.ts
|
|
5542
|
+
var SIDEBAR_AUTO_ON_MIN_COLUMNS = 120;
|
|
5543
|
+
var SIDEBAR_SYNTAX = "Usage: /ca-sidebar on|off|toggle|width N (N clamped 24..60)";
|
|
5544
|
+
var DEGRADED_REASONS = Object.freeze(/* @__PURE__ */ new Set([
|
|
5545
|
+
"no-dorender",
|
|
5546
|
+
"columns-not-configurable",
|
|
5547
|
+
"no-metrics",
|
|
5548
|
+
"geometry-unreadable",
|
|
5549
|
+
"install-failed"
|
|
5550
|
+
]));
|
|
5551
|
+
function clampWidth2(width) {
|
|
5552
|
+
return Math.min(SIDEBAR_MAX_WIDTH, Math.max(SIDEBAR_MIN_WIDTH, Math.floor(width)));
|
|
5553
|
+
}
|
|
5554
|
+
function rawColumns(terminal) {
|
|
5555
|
+
try {
|
|
5556
|
+
const value = terminal?.columns;
|
|
5557
|
+
return typeof value === "number" && Number.isFinite(value) ? Math.floor(value) : void 0;
|
|
5558
|
+
} catch {
|
|
5559
|
+
return void 0;
|
|
5560
|
+
}
|
|
5561
|
+
}
|
|
5562
|
+
var Manager = class {
|
|
5563
|
+
constructor(ports) {
|
|
5564
|
+
this.ports = ports;
|
|
5565
|
+
}
|
|
5566
|
+
ports;
|
|
5567
|
+
registered = false;
|
|
5568
|
+
expected = false;
|
|
5569
|
+
compositor;
|
|
5570
|
+
width = SIDEBAR_DEFAULT_WIDTH;
|
|
5571
|
+
userDisabled = false;
|
|
5572
|
+
autoDecided = false;
|
|
5573
|
+
lastReason;
|
|
5574
|
+
metrics;
|
|
5575
|
+
register(context) {
|
|
5576
|
+
if (!interactiveParent(context)) return false;
|
|
5577
|
+
this.expected = true;
|
|
5578
|
+
if (!this.registered) {
|
|
5579
|
+
this.ports.pi.registerCommand("ca-sidebar", {
|
|
5580
|
+
description: "Toggle or resize the codeArbiter sidebar (on|off|toggle|width N).",
|
|
5581
|
+
handler: async (args, commandContext) => {
|
|
5582
|
+
await this.handle(args, commandContext);
|
|
5583
|
+
}
|
|
5584
|
+
});
|
|
5585
|
+
this.registered = true;
|
|
5586
|
+
}
|
|
5587
|
+
return true;
|
|
5588
|
+
}
|
|
5589
|
+
async autoInstall(context) {
|
|
5590
|
+
if (!interactiveParent(context)) return;
|
|
5591
|
+
if (this.autoDecided || this.userDisabled || this.compositor?.installed === true) return;
|
|
5592
|
+
if (this.ports.currentTui() === void 0) return;
|
|
5593
|
+
const columns = rawColumns(this.ports.terminal());
|
|
5594
|
+
if (columns === void 0) return;
|
|
5595
|
+
this.autoDecided = true;
|
|
5596
|
+
if (columns < SIDEBAR_AUTO_ON_MIN_COLUMNS) {
|
|
5597
|
+
this.lastReason = "auto-off-narrow";
|
|
5598
|
+
return;
|
|
5599
|
+
}
|
|
5600
|
+
await this.install(context);
|
|
5601
|
+
}
|
|
5602
|
+
dispose() {
|
|
5603
|
+
try {
|
|
5604
|
+
this.compositor?.dispose();
|
|
5605
|
+
} catch {
|
|
5606
|
+
}
|
|
5607
|
+
this.compositor = void 0;
|
|
5608
|
+
this.expected = false;
|
|
5609
|
+
this.userDisabled = false;
|
|
5610
|
+
this.autoDecided = false;
|
|
5611
|
+
this.lastReason = void 0;
|
|
5612
|
+
this.width = SIDEBAR_DEFAULT_WIDTH;
|
|
5613
|
+
}
|
|
5614
|
+
health() {
|
|
5615
|
+
const installed = this.compositor?.installed === true;
|
|
5616
|
+
const reason = installed ? void 0 : this.compositor?.reason ?? this.lastReason;
|
|
5617
|
+
return Object.freeze({
|
|
5618
|
+
expected: this.expected,
|
|
5619
|
+
installed,
|
|
5620
|
+
degraded: !installed && reason !== void 0 && DEGRADED_REASONS.has(reason),
|
|
5621
|
+
...reason === void 0 ? {} : { reason }
|
|
5622
|
+
});
|
|
5623
|
+
}
|
|
5624
|
+
async install(context) {
|
|
5625
|
+
const tui = this.ports.currentTui();
|
|
5626
|
+
const terminal = this.ports.terminal();
|
|
5627
|
+
if (tui === void 0 || terminal === void 0) {
|
|
5628
|
+
this.lastReason = tui === void 0 ? "no-tui" : "no-terminal";
|
|
5629
|
+
return false;
|
|
5630
|
+
}
|
|
5631
|
+
if (this.metrics === void 0) {
|
|
5632
|
+
try {
|
|
5633
|
+
this.metrics = await this.ports.loadMetrics?.();
|
|
5634
|
+
} catch {
|
|
5635
|
+
this.metrics = void 0;
|
|
5636
|
+
}
|
|
5637
|
+
if (this.metrics === void 0) {
|
|
5638
|
+
this.lastReason = "no-metrics";
|
|
5639
|
+
return false;
|
|
5640
|
+
}
|
|
5641
|
+
}
|
|
5642
|
+
const notify = (message) => {
|
|
5643
|
+
try {
|
|
5644
|
+
context.ui.notify(message, "warning");
|
|
5645
|
+
} catch {
|
|
5646
|
+
}
|
|
5647
|
+
};
|
|
5648
|
+
const compositor = installSidebar({
|
|
5649
|
+
tui,
|
|
5650
|
+
terminal,
|
|
5651
|
+
metrics: this.metrics,
|
|
5652
|
+
writeOut: this.ports.writeOut,
|
|
5653
|
+
notify,
|
|
5654
|
+
dataSource: this.ports.dataSource,
|
|
5655
|
+
noColor: this.ports.noColor()
|
|
5656
|
+
}, { width: this.width });
|
|
5657
|
+
this.compositor = compositor;
|
|
5658
|
+
this.lastReason = compositor.installed ? void 0 : compositor.reason;
|
|
5659
|
+
return compositor.installed;
|
|
5660
|
+
}
|
|
5661
|
+
notifyInfo(context, message, level = "info") {
|
|
5662
|
+
try {
|
|
5663
|
+
context.ui.notify(message, level);
|
|
5664
|
+
} catch {
|
|
5665
|
+
}
|
|
5666
|
+
}
|
|
5667
|
+
async turnOn(context) {
|
|
5668
|
+
this.userDisabled = false;
|
|
5669
|
+
this.autoDecided = true;
|
|
5670
|
+
if (this.compositor?.installed === true) {
|
|
5671
|
+
this.notifyInfo(context, "codeArbiter sidebar is already on.");
|
|
5672
|
+
return;
|
|
5673
|
+
}
|
|
5674
|
+
const installed = await this.install(context);
|
|
5675
|
+
if (!installed) {
|
|
5676
|
+
this.notifyInfo(context, `codeArbiter sidebar unavailable (${this.lastReason ?? "unknown"}); native rendering is untouched.`, "warning");
|
|
5677
|
+
}
|
|
5678
|
+
}
|
|
5679
|
+
turnOff(context) {
|
|
5680
|
+
this.userDisabled = true;
|
|
5681
|
+
this.autoDecided = true;
|
|
5682
|
+
try {
|
|
5683
|
+
this.compositor?.dispose();
|
|
5684
|
+
} catch {
|
|
5685
|
+
}
|
|
5686
|
+
this.compositor = void 0;
|
|
5687
|
+
this.lastReason = "off";
|
|
5688
|
+
this.notifyInfo(context, "codeArbiter sidebar off.");
|
|
5689
|
+
}
|
|
5690
|
+
async handle(rawArgs, context) {
|
|
5691
|
+
if (!interactiveParent(context)) return;
|
|
5692
|
+
const args = typeof rawArgs === "string" ? rawArgs.trim().split(/\s+/u).filter(Boolean) : [];
|
|
5693
|
+
if (args.length === 0 || args.length === 1 && args[0] === "toggle") {
|
|
5694
|
+
if (this.compositor?.installed === true) this.turnOff(context);
|
|
5695
|
+
else await this.turnOn(context);
|
|
5696
|
+
return;
|
|
5697
|
+
}
|
|
5698
|
+
if (args.length === 1 && args[0] === "on") {
|
|
5699
|
+
await this.turnOn(context);
|
|
5700
|
+
return;
|
|
5701
|
+
}
|
|
5702
|
+
if (args.length === 1 && args[0] === "off") {
|
|
5703
|
+
this.turnOff(context);
|
|
5704
|
+
return;
|
|
5705
|
+
}
|
|
5706
|
+
if (args.length === 2 && args[0] === "width" && /^\d{1,4}$/u.test(args[1])) {
|
|
5707
|
+
this.width = clampWidth2(Number(args[1]));
|
|
5708
|
+
if (this.compositor?.installed === true) this.compositor.setWidth(this.width);
|
|
5709
|
+
else this.notifyInfo(context, `codeArbiter sidebar width set to ${this.width}; the sidebar is off.`);
|
|
5710
|
+
return;
|
|
5711
|
+
}
|
|
5712
|
+
this.notifyInfo(context, SIDEBAR_SYNTAX, "warning");
|
|
5713
|
+
}
|
|
5714
|
+
};
|
|
5715
|
+
function createSidebarManager(ports) {
|
|
5716
|
+
return new Manager(ports);
|
|
5717
|
+
}
|
|
5718
|
+
|
|
5719
|
+
// src/sidebar-data.ts
|
|
5720
|
+
function sessionFromFooter(footer) {
|
|
5721
|
+
const context = footer.context;
|
|
5722
|
+
const contextPercent = context !== void 0 && typeof context.windowTokens === "number" && Number.isFinite(context.windowTokens) && context.windowTokens > 0 && typeof context.usedTokens === "number" && Number.isFinite(context.usedTokens) ? context.usedTokens / context.windowTokens * 100 : void 0;
|
|
5723
|
+
const session = {
|
|
5724
|
+
...footer.model?.name === void 0 ? {} : { model: footer.model.name },
|
|
5725
|
+
...footer.model?.thinking === void 0 ? {} : { thinkingLevel: footer.model.thinking },
|
|
5726
|
+
...contextPercent === void 0 ? {} : { contextPercent },
|
|
5727
|
+
...footer.session === void 0 ? {} : {
|
|
5728
|
+
inputTokens: footer.session.inputTokens,
|
|
5729
|
+
outputTokens: footer.session.outputTokens,
|
|
5730
|
+
costUsd: footer.session.costUsd
|
|
5731
|
+
},
|
|
5732
|
+
...footer.sparkline === void 0 || footer.sparkline.length === 0 ? {} : { burn: footer.sparkline }
|
|
5733
|
+
};
|
|
5734
|
+
return Object.keys(session).length === 0 ? void 0 : session;
|
|
5735
|
+
}
|
|
5736
|
+
function sidebarInputFromFooter(footer) {
|
|
5737
|
+
if (footer === void 0) return {};
|
|
5738
|
+
const session = sessionFromFooter(footer);
|
|
5739
|
+
const subagents = footer.activity !== void 0 && footer.activity.length > 0 ? footer.activity.map((item) => ({
|
|
5740
|
+
kind: item.kind,
|
|
5741
|
+
label: item.label,
|
|
5742
|
+
state: item.state,
|
|
5743
|
+
...item.ageSeconds === void 0 ? {} : { ageSeconds: item.ageSeconds }
|
|
5744
|
+
})) : void 0;
|
|
5745
|
+
const workspace = footer.git === void 0 ? void 0 : {
|
|
5746
|
+
cwd: footer.folder,
|
|
5747
|
+
...footer.git.repository === void 0 ? {} : { repository: footer.git.repository },
|
|
5748
|
+
...footer.git.dirty === void 0 ? {} : { dirty: footer.git.dirty }
|
|
5749
|
+
};
|
|
5750
|
+
return {
|
|
5751
|
+
...session === void 0 ? {} : { session },
|
|
5752
|
+
...subagents === void 0 ? {} : { subagents },
|
|
5753
|
+
...workspace === void 0 ? {} : { workspace }
|
|
5754
|
+
};
|
|
5755
|
+
}
|
|
5756
|
+
var TODO_STATE = Object.freeze({
|
|
5757
|
+
PENDING: "open",
|
|
5758
|
+
IN_PROGRESS: "active",
|
|
5759
|
+
ACCEPTED: "done"
|
|
5760
|
+
});
|
|
5761
|
+
function sidebarTodosFromPlan(state) {
|
|
5762
|
+
const tasks = state?.activePlan.tasks;
|
|
5763
|
+
if (tasks === void 0 || tasks.length === 0) return void 0;
|
|
5764
|
+
return tasks.map((task) => ({ text: task.id, state: TODO_STATE[task.status] }));
|
|
5765
|
+
}
|
|
5766
|
+
|
|
5082
5767
|
// src/tool-guard.ts
|
|
5083
5768
|
import { createHash as createHash5, randomUUID as randomUUID3 } from "node:crypto";
|
|
5084
5769
|
import { realpathSync as realpathSync6 } from "node:fs";
|
|
@@ -6127,6 +6812,12 @@ async function collectPiDoctorInput(dependencies) {
|
|
|
6127
6812
|
expected: dependencies.footerExpected === true,
|
|
6128
6813
|
initialized: dependencies.footerInitialized === true
|
|
6129
6814
|
},
|
|
6815
|
+
sidebar: {
|
|
6816
|
+
expected: dependencies.sidebarExpected === true,
|
|
6817
|
+
installed: dependencies.sidebarInstalled === true,
|
|
6818
|
+
degraded: dependencies.sidebarDegraded === true,
|
|
6819
|
+
...dependencies.sidebarReason === void 0 ? {} : { reason: dependencies.sidebarReason }
|
|
6820
|
+
},
|
|
6130
6821
|
background: {
|
|
6131
6822
|
expected: dependencies.backgroundExpected === true,
|
|
6132
6823
|
initialized: dependencies.backgroundInitialized === true,
|
|
@@ -6153,16 +6844,17 @@ async function collectPiDoctorInput(dependencies) {
|
|
|
6153
6844
|
var REMEDIATION = {
|
|
6154
6845
|
package: "Reinstall ca-pi from the approved pinned Git tag, then restart Pi.",
|
|
6155
6846
|
trust: "Run /trust in Pi, inspect the project, grant trust only if you accept it, then start a new session.",
|
|
6156
|
-
version: "Upgrade Pi to 0.80.5 or 0.
|
|
6847
|
+
version: "Upgrade Pi to 0.80.5 or 0.84.1 and Node to >=22.19.0, then restart Pi.",
|
|
6157
6848
|
python: "Upgrade or install Python 3, then run /ca-doctor again.",
|
|
6158
6849
|
core: "Reinstall ca-pi to restore the generated shared core, then run /ca-doctor again.",
|
|
6159
|
-
commands: "Remove conflicting command owners or run Pi 0.80.5/0.
|
|
6850
|
+
commands: "Remove conflicting command owners or run Pi 0.80.5/0.84.1, then restart Pi and run /ca-doctor.",
|
|
6160
6851
|
bridge: "Reinstall ca-pi and Python 3, then run /ca-doctor again.",
|
|
6161
6852
|
child: "Reinstall ca-pi if the hardened child artifact is missing or tampered, then run /ca-doctor again.",
|
|
6162
6853
|
"ambient-marker": "Remove CODEARBITER_SUBAGENT from the parent environment and restart Pi.",
|
|
6163
6854
|
"module-identity": "Reinstall the active Pi CLI and ca-pi from their approved origins, then restart Pi.",
|
|
6164
6855
|
"final-arguments": "Reinstall ca-pi, remove competing mutating tool definitions, and run /ca-doctor again.",
|
|
6165
6856
|
footer: "Restart Pi in an interactive parent session; if the rich footer still fails, reinstall ca-pi and run /ca-doctor again.",
|
|
6857
|
+
sidebar: "Run /ca-sidebar on in a wide terminal; if the probe still reports unavailable, this Pi build changed its render surface \u2014 keep the footer and file an issue.",
|
|
6166
6858
|
background: "Stop active work, restart Pi, and run /ca-doctor before launching another background job.",
|
|
6167
6859
|
"active-dispatch": "Require passing supported-version real-host promotion/CI evidence before closing PI-AC-28."
|
|
6168
6860
|
};
|
|
@@ -6184,7 +6876,7 @@ function diagnosePi(input) {
|
|
|
6184
6876
|
const packageHealthy = input.package.declared && input.package.name === "@arbiterforge/ca-pi" && existsSync(input.package.root) && existsSync(input.package.extensionPath) && samePath2(input.package.extensionPath, expectedExtension) && canonicallyInside(input.package.extensionPath, input.package.root);
|
|
6185
6877
|
const trustHealthy = input.trust.inspected && (!input.trust.required || input.trust.projectTrusted);
|
|
6186
6878
|
const waitingForTrust = input.trust.required && !input.trust.projectTrusted;
|
|
6187
|
-
const versionHealthy = ["0.80.5", "0.
|
|
6879
|
+
const versionHealthy = ["0.80.5", "0.84.1"].includes(input.runtime.piVersion) && atLeast(input.runtime.nodeVersion, [22, 19, 0]);
|
|
6188
6880
|
const piBelowMinimum = !atLeast(input.runtime.piVersion, [0, 80, 5]);
|
|
6189
6881
|
const supportedExpansion = input.commands.expansionVerifiedVersions.includes(input.runtime.piVersion);
|
|
6190
6882
|
const expectedDoctorSkill = resolve9(input.package.root, "skills", "ca-doctor", "SKILL.md");
|
|
@@ -6261,6 +6953,12 @@ function diagnosePi(input) {
|
|
|
6261
6953
|
input.footer.expected ? "The rich footer initialized in the current interactive parent session." : "The rich footer is intentionally absent outside an active interactive parent session.",
|
|
6262
6954
|
input.footer.expected ? "The rich footer did not initialize in the current interactive parent session." : "The rich footer initialized outside an active interactive parent session; isolation is breached."
|
|
6263
6955
|
),
|
|
6956
|
+
diagnosis(
|
|
6957
|
+
"sidebar",
|
|
6958
|
+
input.sidebar.expected ? !input.sidebar.degraded : !input.sidebar.installed && !input.sidebar.degraded,
|
|
6959
|
+
input.sidebar.expected ? input.sidebar.installed ? "The probe-gated sidebar compositor is installed." : `The sidebar is not installed (${input.sidebar.reason ?? "off"}); native rendering is untouched.` : "The sidebar is intentionally absent outside an interactive parent session.",
|
|
6960
|
+
!input.sidebar.expected && input.sidebar.installed ? "The sidebar compositor installed outside an interactive parent session; isolation is breached." : `The sidebar hook probe failed (${input.sidebar.reason ?? "unknown"}); this Pi build changed its render surface and native rendering is untouched.`
|
|
6961
|
+
),
|
|
6264
6962
|
diagnosis(
|
|
6265
6963
|
"background",
|
|
6266
6964
|
input.background.expected ? input.background.initialized && input.background.healthy : !input.background.initialized,
|
|
@@ -6299,7 +6997,7 @@ function diagnosePi(input) {
|
|
|
6299
6997
|
{
|
|
6300
6998
|
id: "active-dispatch",
|
|
6301
6999
|
state: "degraded",
|
|
6302
|
-
message: "Supported Pi 0.80.5/0.
|
|
7000
|
+
message: "Supported Pi 0.80.5/0.84.1 public extension APIs cannot submit this deterministic self-test through the active dispatcher; the wrapper self-test does not exercise active dispatch.",
|
|
6303
7001
|
remediation: REMEDIATION["active-dispatch"]
|
|
6304
7002
|
}
|
|
6305
7003
|
];
|
|
@@ -9167,6 +9865,19 @@ function ownershipStatus(pi, dependencies, nativePlanRegistered = false, nativeJ
|
|
|
9167
9865
|
}
|
|
9168
9866
|
return `codeArbiter host: pi degraded - ${native.length + jobs.length} native command ownership conflict(s); operations blocked`;
|
|
9169
9867
|
}
|
|
9868
|
+
var PERSONA_SENTINEL = "<!-- codearbiter:persona-sentinel -->";
|
|
9869
|
+
async function loadPersonaFrom(packageRoot) {
|
|
9870
|
+
const [safetyCore, body] = await Promise.all([
|
|
9871
|
+
readFile6(resolve15(packageRoot, "includes", "safety-core.md"), "utf8"),
|
|
9872
|
+
readFile6(resolve15(packageRoot, "arbiter.md"), "utf8")
|
|
9873
|
+
]);
|
|
9874
|
+
return `${safetyCore.replace(/\n+$/, "")}
|
|
9875
|
+
|
|
9876
|
+
${body.replace(/\n+$/, "")}
|
|
9877
|
+
|
|
9878
|
+
${PERSONA_SENTINEL}
|
|
9879
|
+
`;
|
|
9880
|
+
}
|
|
9170
9881
|
function installParent(pi, dependencies) {
|
|
9171
9882
|
let enabled = false;
|
|
9172
9883
|
let persona = "";
|
|
@@ -9199,6 +9910,21 @@ function installParent(pi, dependencies) {
|
|
|
9199
9910
|
currentActivity2,
|
|
9200
9911
|
dependencies.collectGitFacts ?? collectGitFacts
|
|
9201
9912
|
);
|
|
9913
|
+
const sidebar = createSidebarManager({
|
|
9914
|
+
pi,
|
|
9915
|
+
currentTui: () => footer.currentTui(),
|
|
9916
|
+
terminal: () => process.stdout,
|
|
9917
|
+
...loadFooterMetrics === void 0 ? {} : { loadMetrics: loadFooterMetrics },
|
|
9918
|
+
dataSource: () => {
|
|
9919
|
+
const input = sidebarInputFromFooter(footer.lastRenderedInput());
|
|
9920
|
+
const todos = sidebarTodosFromPlan(plan?.status());
|
|
9921
|
+
return todos === void 0 ? input : { ...input, todos };
|
|
9922
|
+
},
|
|
9923
|
+
writeOut: (text2) => {
|
|
9924
|
+
process.stdout.write(text2);
|
|
9925
|
+
},
|
|
9926
|
+
noColor: () => Object.prototype.hasOwnProperty.call(process.env, "NO_COLOR")
|
|
9927
|
+
});
|
|
9202
9928
|
const readActivation = dependencies.readActivation ?? isEnabled;
|
|
9203
9929
|
dependencies.installDispatch?.(() => readyLifecycle, currentActivity2);
|
|
9204
9930
|
dependencies.installCompaction?.(() => readyLifecycle);
|
|
@@ -9233,6 +9959,7 @@ function installParent(pi, dependencies) {
|
|
|
9233
9959
|
}
|
|
9234
9960
|
return Object.freeze({
|
|
9235
9961
|
footer: footerHealth,
|
|
9962
|
+
sidebar: sidebar.health(),
|
|
9236
9963
|
background: Object.freeze({
|
|
9237
9964
|
expected: backgroundExpected,
|
|
9238
9965
|
initialized: backgroundInitialized,
|
|
@@ -9253,6 +9980,7 @@ function installParent(pi, dependencies) {
|
|
|
9253
9980
|
activeLifecycle = void 0;
|
|
9254
9981
|
readyLifecycle = void 0;
|
|
9255
9982
|
if (background !== void 0) await background.stop("session-switch");
|
|
9983
|
+
sidebar.dispose();
|
|
9256
9984
|
activity?.dispose();
|
|
9257
9985
|
activity = void 0;
|
|
9258
9986
|
dependencies.enforcementReadiness?.deactivate();
|
|
@@ -9275,6 +10003,9 @@ function installParent(pi, dependencies) {
|
|
|
9275
10003
|
readUpdateVersion: dependencies.readFooterUpdateVersion
|
|
9276
10004
|
});
|
|
9277
10005
|
if (!isCurrent()) return;
|
|
10006
|
+
sidebar.register(context);
|
|
10007
|
+
await sidebar.autoInstall(context);
|
|
10008
|
+
if (!isCurrent()) return;
|
|
9278
10009
|
if (!markerEnabled) {
|
|
9279
10010
|
activeLifecycle = void 0;
|
|
9280
10011
|
dependencies.enforcementReadiness?.deactivate();
|
|
@@ -9370,13 +10101,16 @@ function installParent(pi, dependencies) {
|
|
|
9370
10101
|
if (enabled) publishStatus(context, degradedStatus() ?? "codeArbiter host: pi governed");
|
|
9371
10102
|
});
|
|
9372
10103
|
pi.on("agent_settled", async (_event, context) => {
|
|
10104
|
+
const sequence = lifecycleSequence;
|
|
9373
10105
|
await footer.refresh(context, { activation: { enabled: footerActivationEnabled } });
|
|
10106
|
+
if (sequence === lifecycleSequence) await sidebar.autoInstall(context);
|
|
9374
10107
|
if (enabled) publishStatus(context, degradedStatus());
|
|
9375
10108
|
});
|
|
9376
10109
|
const stopSession = async (reason, context) => {
|
|
9377
10110
|
readyLifecycle = void 0;
|
|
9378
10111
|
activeLifecycle = void 0;
|
|
9379
10112
|
await background?.stop(reason);
|
|
10113
|
+
sidebar.dispose();
|
|
9380
10114
|
activity?.dispose();
|
|
9381
10115
|
activity = void 0;
|
|
9382
10116
|
footer.dispose();
|
|
@@ -9601,7 +10335,7 @@ async function codeArbiterPi(pi) {
|
|
|
9601
10335
|
pi.appendEntry(customType, data);
|
|
9602
10336
|
},
|
|
9603
10337
|
enforcementReadiness: enforcement,
|
|
9604
|
-
loadPersona: async () => await
|
|
10338
|
+
loadPersona: async () => await loadPersonaFrom(packageRoot),
|
|
9605
10339
|
resetBridge,
|
|
9606
10340
|
prepareFooterBridge: (cwd) => {
|
|
9607
10341
|
prepareBridgeIdentity(cwd);
|
|
@@ -9720,6 +10454,10 @@ async function codeArbiterPi(pi) {
|
|
|
9720
10454
|
bridgePrepared: enabledForDoctor && trustedForDoctor && pythonResolutionAttempted,
|
|
9721
10455
|
footerExpected: health.footer.expected,
|
|
9722
10456
|
footerInitialized: health.footer.initialized,
|
|
10457
|
+
sidebarExpected: health.sidebar.expected,
|
|
10458
|
+
sidebarInstalled: health.sidebar.installed,
|
|
10459
|
+
sidebarDegraded: health.sidebar.degraded,
|
|
10460
|
+
...health.sidebar.reason === void 0 ? {} : { sidebarReason: health.sidebar.reason },
|
|
9723
10461
|
backgroundExpected: health.background.expected,
|
|
9724
10462
|
backgroundInitialized: health.background.initialized,
|
|
9725
10463
|
backgroundHealthy: health.background.healthy,
|
|
@@ -9729,7 +10467,7 @@ async function codeArbiterPi(pi) {
|
|
|
9729
10467
|
activeTools: pi.getActiveTools(),
|
|
9730
10468
|
allTools: pi.getAllTools(),
|
|
9731
10469
|
expansionFingerprints,
|
|
9732
|
-
childFingerprint: "
|
|
10470
|
+
childFingerprint: "c9573777b4c59abfb4adbe6879fc03de7f7962327d97c378c2fb71d300a4e22f"
|
|
9733
10471
|
});
|
|
9734
10472
|
const wrapperSelfTest = await runPiWrapperSelfTest({
|
|
9735
10473
|
enabled: enabledForDoctor,
|
|
@@ -9791,6 +10529,7 @@ async function codeArbiterPi(pi) {
|
|
|
9791
10529
|
});
|
|
9792
10530
|
}
|
|
9793
10531
|
export {
|
|
10532
|
+
PERSONA_SENTINEL,
|
|
9794
10533
|
PI_RUNTIME_DIAGNOSIS,
|
|
9795
10534
|
boundedPiEnvironment,
|
|
9796
10535
|
compatibilityDirection,
|
|
@@ -9802,6 +10541,7 @@ export {
|
|
|
9802
10541
|
installParent,
|
|
9803
10542
|
installPiDispatch,
|
|
9804
10543
|
installPiFarmPreview,
|
|
10544
|
+
loadPersonaFrom,
|
|
9805
10545
|
renderPiDoctorReportBlock,
|
|
9806
10546
|
resolvePiBackgroundShell,
|
|
9807
10547
|
resolvePiRuntime,
|