codedeck 0.3.0 → 0.4.0
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/dist/cli/charts/bar-chart.js +104 -0
- package/dist/cli/charts/bar-chart.js.map +1 -0
- package/dist/cli/charts/sparkline.js +18 -0
- package/dist/cli/charts/sparkline.js.map +1 -0
- package/dist/cli/charts/stacked-bar.js +59 -0
- package/dist/cli/charts/stacked-bar.js.map +1 -0
- package/dist/cli/commands/models.js +4 -4
- package/dist/cli/commands/models.js.map +1 -1
- package/dist/cli/commands/open.js +218 -57
- package/dist/cli/commands/open.js.map +1 -1
- package/dist/cli/commands/ps.js +1 -35
- package/dist/cli/commands/ps.js.map +1 -1
- package/dist/cli/commands/run.js +4 -3
- package/dist/cli/commands/run.js.map +1 -1
- package/dist/cli/commands/setup.js +604 -13
- package/dist/cli/commands/setup.js.map +1 -1
- package/dist/cli/commands/usage.js +171 -16
- package/dist/cli/commands/usage.js.map +1 -1
- package/dist/cli/commands/web.js +224 -0
- package/dist/cli/commands/web.js.map +1 -0
- package/dist/cli/index.js +3 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/ui.js +34 -0
- package/dist/cli/ui.js.map +1 -1
- package/dist/cli/usage/dashboard.js +330 -0
- package/dist/cli/usage/dashboard.js.map +1 -0
- package/dist/cli/usage/snapshot.js +112 -0
- package/dist/cli/usage/snapshot.js.map +1 -0
- package/dist/config/config.js +287 -5
- package/dist/config/config.js.map +1 -1
- package/dist/config/paths.js +20 -9
- package/dist/config/paths.js.map +1 -1
- package/dist/core/autocompact.js +77 -0
- package/dist/core/autocompact.js.map +1 -0
- package/dist/core/driver.js.map +1 -1
- package/dist/core/models.js +166 -3
- package/dist/core/models.js.map +1 -1
- package/dist/core/pricing.js +18 -0
- package/dist/core/pricing.js.map +1 -1
- package/dist/core/session.js +14 -1
- package/dist/core/session.js.map +1 -1
- package/dist/daemon/daemon.js +196 -5
- package/dist/daemon/daemon.js.map +1 -1
- package/dist/drivers/antigravity/driver.js +158 -0
- package/dist/drivers/antigravity/driver.js.map +1 -0
- package/dist/drivers/antigravity/parser.js +168 -0
- package/dist/drivers/antigravity/parser.js.map +1 -0
- package/dist/drivers/claude/driver.js +13 -3
- package/dist/drivers/claude/driver.js.map +1 -1
- package/dist/drivers/registry.js +2 -0
- package/dist/drivers/registry.js.map +1 -1
- package/dist/drivers/session-driver.js +6 -4
- package/dist/drivers/session-driver.js.map +1 -1
- package/dist/drivers/session-runtime.js +1 -1
- package/dist/drivers/session-runtime.js.map +1 -1
- package/dist/open/contract.js +16 -4
- package/dist/open/contract.js.map +1 -1
- package/dist/open/injection.js +1 -0
- package/dist/open/injection.js.map +1 -1
- package/dist/open/launchers/claude.js +4 -1
- package/dist/open/launchers/claude.js.map +1 -1
- package/dist/open/launchers/opencode.js +37 -2
- package/dist/open/launchers/opencode.js.map +1 -1
- package/dist/open/runtime.js +43 -8
- package/dist/open/runtime.js.map +1 -1
- package/dist/plugin/agents/orchestrator-edit.md +1 -3
- package/dist/plugin/agents/orchestrator-read.md +1 -3
- package/dist/plugin/agents/orchestrator.md +2 -4
- package/dist/store/database.js +36 -15
- package/dist/store/database.js.map +1 -1
- package/dist/store/sessions.js +220 -3
- package/dist/store/sessions.js.map +1 -1
- package/dist/web/canvas-page.js +921 -0
- package/dist/web/canvas-page.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { visibleWidth } from "../ui.js";
|
|
2
|
+
const BLOCK_GLYPHS = [" ", " ", "▂", "▃", "▄", "▅", "▆", "▇", "█"];
|
|
3
|
+
function centerText(text, width) {
|
|
4
|
+
const v = visibleWidth(text);
|
|
5
|
+
if (v >= width)
|
|
6
|
+
return text.slice(0, width);
|
|
7
|
+
const left = Math.floor((width - v) / 2);
|
|
8
|
+
const right = width - v - left;
|
|
9
|
+
return " ".repeat(left) + text + " ".repeat(right);
|
|
10
|
+
}
|
|
11
|
+
export function renderBarChart(data, options = {}) {
|
|
12
|
+
if (data.length === 0)
|
|
13
|
+
return [" (no data for this period)"];
|
|
14
|
+
const height = Math.max(3, options.height ?? 6);
|
|
15
|
+
const maxWidth = options.maxWidth ?? 80;
|
|
16
|
+
const useColor = options.color ?? true;
|
|
17
|
+
const formatY = options.formatY ?? ((v) => `$${v >= 1000 ? `${(v / 1000).toFixed(1)}k` : v.toFixed(v < 10 ? 2 : 0)}`);
|
|
18
|
+
const values = data.map((d) => (Number.isFinite(d.value) && d.value > 0 ? d.value : 0));
|
|
19
|
+
const maxValue = Math.max(...values, 0.01);
|
|
20
|
+
const totalSublevels = height * 8;
|
|
21
|
+
// Y-axis labels (4 steps: max, 2/3, 1/3, 0)
|
|
22
|
+
const yLabels = [
|
|
23
|
+
formatY(maxValue),
|
|
24
|
+
formatY((maxValue * 2) / 3),
|
|
25
|
+
formatY(maxValue / 3),
|
|
26
|
+
formatY(0),
|
|
27
|
+
];
|
|
28
|
+
const yLabelWidth = Math.max(...yLabels.map((l) => visibleWidth(l)));
|
|
29
|
+
const paddedYLabels = yLabels.map((l) => l.padStart(yLabelWidth, " "));
|
|
30
|
+
// Calculate dynamic wide bars based on available space and number of columns
|
|
31
|
+
const availableWidth = Math.max(30, maxWidth - yLabelWidth - 8);
|
|
32
|
+
const count = data.length;
|
|
33
|
+
const targetBarWidth = options.barWidth ?? Math.max(4, Math.min(14, Math.floor(availableWidth / (count * 1.5))));
|
|
34
|
+
const gapWidth = Math.max(2, Math.min(6, Math.floor(targetBarWidth * 0.5)));
|
|
35
|
+
const lines = [];
|
|
36
|
+
// Render each vertical line of the chart (top down)
|
|
37
|
+
for (let row = height - 1; row >= 0; row--) {
|
|
38
|
+
let yPrefix = " ".repeat(yLabelWidth);
|
|
39
|
+
if (row === height - 1) {
|
|
40
|
+
yPrefix = paddedYLabels[0];
|
|
41
|
+
}
|
|
42
|
+
else if (row === Math.floor(height * 0.66)) {
|
|
43
|
+
yPrefix = paddedYLabels[1];
|
|
44
|
+
}
|
|
45
|
+
else if (row === Math.floor(height * 0.33)) {
|
|
46
|
+
yPrefix = paddedYLabels[2];
|
|
47
|
+
}
|
|
48
|
+
else if (row === 0) {
|
|
49
|
+
yPrefix = paddedYLabels[3];
|
|
50
|
+
}
|
|
51
|
+
let rowBars = "";
|
|
52
|
+
for (let i = 0; i < data.length; i++) {
|
|
53
|
+
const val = values[i];
|
|
54
|
+
const sub = Math.min(totalSublevels, Math.round((val / maxValue) * totalSublevels));
|
|
55
|
+
const gap = " ".repeat(gapWidth);
|
|
56
|
+
if (sub >= (row + 1) * 8) {
|
|
57
|
+
const barBlock = "█".repeat(targetBarWidth);
|
|
58
|
+
rowBars += `${gap}${useColor ? `\x1b[36m${barBlock}\x1b[0m` : barBlock}`;
|
|
59
|
+
}
|
|
60
|
+
else if (sub <= row * 8) {
|
|
61
|
+
rowBars += `${gap}${" ".repeat(targetBarWidth)}`;
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
const glyphIdx = Math.min(8, Math.max(0, sub - row * 8));
|
|
65
|
+
const glyph = BLOCK_GLYPHS[glyphIdx];
|
|
66
|
+
const barBlock = glyph.repeat(targetBarWidth);
|
|
67
|
+
rowBars += `${gap}${useColor ? `\x1b[36m${barBlock}\x1b[0m` : barBlock}`;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
lines.push(` ${yPrefix} │${rowBars}`);
|
|
71
|
+
}
|
|
72
|
+
// X-axis baseline and ticks
|
|
73
|
+
let axisLine = "";
|
|
74
|
+
for (let i = 0; i < data.length; i++) {
|
|
75
|
+
const gap = "─".repeat(gapWidth);
|
|
76
|
+
const tickBar = "─".repeat(targetBarWidth);
|
|
77
|
+
axisLine += `${gap}${tickBar}`;
|
|
78
|
+
}
|
|
79
|
+
lines.push(` ${" ".repeat(yLabelWidth)} └───${axisLine}──`);
|
|
80
|
+
// X-axis date labels (centered under each bar)
|
|
81
|
+
let dateLine = "";
|
|
82
|
+
for (let i = 0; i < data.length; i++) {
|
|
83
|
+
const gap = " ".repeat(gapWidth);
|
|
84
|
+
const rawLabel = data[i].label.length > 5 ? data[i].label.slice(5) : data[i].label; // e.g. "2026-09-07" -> "09-07"
|
|
85
|
+
const centered = centerText(rawLabel, targetBarWidth);
|
|
86
|
+
dateLine += `${gap}${centered}`;
|
|
87
|
+
}
|
|
88
|
+
lines.push(` ${" ".repeat(yLabelWidth)} ${dateLine}`);
|
|
89
|
+
// X-axis value labels (centered under each date)
|
|
90
|
+
if (options.showValues ?? true) {
|
|
91
|
+
let valueLine = "";
|
|
92
|
+
for (let i = 0; i < data.length; i++) {
|
|
93
|
+
const gap = " ".repeat(gapWidth);
|
|
94
|
+
const val = values[i];
|
|
95
|
+
const valText = `$${val.toFixed(val < 10 ? 2 : 0)}`;
|
|
96
|
+
const centered = centerText(valText, targetBarWidth);
|
|
97
|
+
const colored = useColor ? `\x1b[1m${centered}\x1b[0m` : centered;
|
|
98
|
+
valueLine += `${gap}${colored}`;
|
|
99
|
+
}
|
|
100
|
+
lines.push(` ${" ".repeat(yLabelWidth)} ${valueLine}`);
|
|
101
|
+
}
|
|
102
|
+
return lines;
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=bar-chart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bar-chart.js","sourceRoot":"","sources":["../../../src/cli/charts/bar-chart.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const SPARKS = [" ", "▂", "▃", "▄", "▅", "▆", "▇", "█"];
|
|
2
|
+
export function renderSparkline(values) {
|
|
3
|
+
if (values.length === 0)
|
|
4
|
+
return "";
|
|
5
|
+
const valid = values.map((v) => (Number.isFinite(v) && v >= 0 ? v : 0));
|
|
6
|
+
const min = Math.min(...valid);
|
|
7
|
+
const max = Math.max(...valid);
|
|
8
|
+
const range = max - min;
|
|
9
|
+
return valid
|
|
10
|
+
.map((v) => {
|
|
11
|
+
if (range === 0)
|
|
12
|
+
return v > 0 ? SPARKS[4] : SPARKS[0];
|
|
13
|
+
const idx = Math.min(7, Math.max(0, Math.round(((v - min) / range) * 7)));
|
|
14
|
+
return SPARKS[idx];
|
|
15
|
+
})
|
|
16
|
+
.join("");
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=sparkline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sparkline.js","sourceRoot":"","sources":["../../../src/cli/charts/sparkline.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAExD,MAAM,UAAU,eAAe,CAAC,MAAgB;IAC9C,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACnC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACxE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;IAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC;IAC/B,MAAM,KAAK,GAAG,GAAG,GAAG,GAAG,CAAC;IAExB,OAAO,KAAK;SACT,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,IAAI,KAAK,KAAK,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACtD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1E,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC,CAAC;SACD,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
const PALETTE = [
|
|
2
|
+
"\x1b[36m", // Cyan
|
|
3
|
+
"\x1b[32m", // Green
|
|
4
|
+
"\x1b[33m", // Yellow
|
|
5
|
+
"\x1b[35m", // Magenta
|
|
6
|
+
"\x1b[34m", // Blue
|
|
7
|
+
"\x1b[91m", // Bright Red
|
|
8
|
+
"\x1b[96m", // Bright Cyan
|
|
9
|
+
"\x1b[92m", // Bright Green
|
|
10
|
+
];
|
|
11
|
+
const RESET = "\x1b[0m";
|
|
12
|
+
export function renderStackedBar(segments, width, options = {}) {
|
|
13
|
+
const useColor = options.color ?? true;
|
|
14
|
+
const validSegments = segments.filter((s) => Number.isFinite(s.value) && s.value > 0);
|
|
15
|
+
const total = validSegments.reduce((sum, s) => sum + s.value, 0);
|
|
16
|
+
if (total <= 0 || width <= 2) {
|
|
17
|
+
const emptyRoom = Math.max(0, width - 2);
|
|
18
|
+
return {
|
|
19
|
+
bar: `[${" ".repeat(emptyRoom)}]`,
|
|
20
|
+
legend: "",
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
const innerWidth = width - 2; // Discount brackets '[' and ']'
|
|
24
|
+
// Largest Remainder Method (Hamilton)
|
|
25
|
+
const exactAllocations = validSegments.map((s) => ({
|
|
26
|
+
segment: s,
|
|
27
|
+
exact: (s.value / total) * innerWidth,
|
|
28
|
+
}));
|
|
29
|
+
const integers = exactAllocations.map((a) => Math.floor(a.exact));
|
|
30
|
+
const remainders = exactAllocations.map((a, idx) => ({
|
|
31
|
+
idx,
|
|
32
|
+
rem: a.exact - integers[idx],
|
|
33
|
+
}));
|
|
34
|
+
let allocated = integers.reduce((sum, v) => sum + v, 0);
|
|
35
|
+
remainders.sort((a, b) => b.rem - a.rem);
|
|
36
|
+
for (let i = 0; i < innerWidth - allocated; i++) {
|
|
37
|
+
integers[remainders[i % remainders.length].idx] += 1;
|
|
38
|
+
}
|
|
39
|
+
let barChars = "";
|
|
40
|
+
const legendParts = [];
|
|
41
|
+
for (let i = 0; i < validSegments.length; i++) {
|
|
42
|
+
const count = integers[i];
|
|
43
|
+
const color = useColor ? PALETTE[i % PALETTE.length] : "";
|
|
44
|
+
const reset = useColor ? RESET : "";
|
|
45
|
+
const pct = Math.round((validSegments[i].value / total) * 100);
|
|
46
|
+
if (count > 0) {
|
|
47
|
+
barChars += `${color}${"█".repeat(count)}${reset}`;
|
|
48
|
+
}
|
|
49
|
+
// Only show items that have at least 1% share
|
|
50
|
+
if (pct >= 1) {
|
|
51
|
+
legendParts.push(`${color}■${reset} ${validSegments[i].label} (${pct}%)`);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
bar: `[${barChars}]`,
|
|
56
|
+
legend: legendParts.join(" "),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=stacked-bar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stacked-bar.js","sourceRoot":"","sources":["../../../src/cli/charts/stacked-bar.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { IpcClient, isDaemonRunning } from "../../daemon/ipc.js";
|
|
2
2
|
import { getRegistry } from "../../drivers/registry.js";
|
|
3
3
|
import { getCachedOrDiscoverModels, } from "../../core/models.js";
|
|
4
|
-
import { AGENT_IDS } from "../../core/session.js";
|
|
4
|
+
import { AGENT_IDS, normalizeAgentId } from "../../core/session.js";
|
|
5
5
|
export function filterHarnessModels(harnesses, options) {
|
|
6
6
|
const search = options.search?.toLowerCase().trim();
|
|
7
7
|
const providerFilter = options.provider?.toLowerCase().trim();
|
|
@@ -109,12 +109,12 @@ export function registerModelsCommand(program) {
|
|
|
109
109
|
.action(async (agentArg, opts = {}) => {
|
|
110
110
|
let agent;
|
|
111
111
|
if (agentArg) {
|
|
112
|
-
const
|
|
113
|
-
if (!
|
|
112
|
+
const resolved = normalizeAgentId(agentArg);
|
|
113
|
+
if (!resolved) {
|
|
114
114
|
console.error(`Invalid agent "${agentArg}". Available agents: ${AGENT_IDS.join(", ")}`);
|
|
115
115
|
process.exit(1);
|
|
116
116
|
}
|
|
117
|
-
agent =
|
|
117
|
+
agent = resolved;
|
|
118
118
|
}
|
|
119
119
|
let harnesses = [];
|
|
120
120
|
try {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../../src/cli/commands/models.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxD,OAAO,EACL,yBAAyB,GAI1B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,SAAS,EAAgB,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"models.js","sourceRoot":"","sources":["../../../src/cli/commands/models.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
import { spawn } from "node:child_process";
|
|
2
|
-
import
|
|
1
|
+
import { execFileSync, spawn } from "node:child_process";
|
|
2
|
+
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import * as readline from "node:readline";
|
|
5
5
|
import { IpcClient } from "../../daemon/ipc.js";
|
|
6
6
|
import { loadConfig, resolveRoleBinding, resolveOrchestratorMode, } from "../../config/config.js";
|
|
7
|
+
import { parseAutocompact } from "../../core/autocompact.js";
|
|
7
8
|
import { harnessInjection } from "../../open/injection.js";
|
|
9
|
+
import { getGitInfo } from "../../git/repository.js";
|
|
10
|
+
import { createWorktree } from "../../git/worktree.js";
|
|
8
11
|
import { ptyShimPath } from "../../open/pty.js";
|
|
9
12
|
import { isInteractiveTerminal } from "./setup.js";
|
|
10
13
|
import { sessionsDir } from "../../open/pty.js";
|
|
@@ -13,13 +16,13 @@ import { getCliName } from "../cli-name.js";
|
|
|
13
16
|
import { effectiveModel, resolveOpenModel } from "../../open/contract.js";
|
|
14
17
|
import { buildArgs as buildOpencodeArgs, buildInlineConfig, createEphemeralTuiDir, ensureOpencodeTheme, OPENCODE_NOT_FOUND, preflight as preflightOpencode, removeEphemeralTuiDir, resolveBinary as resolveOpencodeBinary, } from "../../open/launchers/opencode.js";
|
|
15
18
|
import { assertSupport, buildOpenArgs, CLAUDE_NOT_FOUND, DEFAULT_EFFORT, DEFAULT_MODEL, entitlementError, preflightModel, resolveBinary, } from "../../open/launchers/claude.js";
|
|
16
|
-
import { assertPluginDirectory, currentWorkingDirectory, finishOpenSession, playBoot, renderBanner, spawnHarness, } from "../../open/runtime.js";
|
|
19
|
+
import { SESSION_ID_PATTERN, assertPluginDirectory, currentWorkingDirectory, finishOpenSession, playBoot, renderBanner, spawnHarness, } from "../../open/runtime.js";
|
|
17
20
|
export { ROLES, parseRole, resolvePluginDir };
|
|
18
21
|
export { effectiveModel };
|
|
19
22
|
export { buildOpenArgs, buildSettings, entitlementError, judgeModel, sessionName } from "../../open/launchers/claude.js";
|
|
20
|
-
export { bootFrame, ensureCodedeckShim, exitCodeFor, finishOpenSession, installSigintGuard, renderBanner, renderExit, resumeHint, sanitizeEnv, spinnerTips, withCodedeckOnPath, writeStdoutSync, } from "../../open/runtime.js";
|
|
23
|
+
export { CLAUDE_RESUME_ERASE, SESSION_ID_PATTERN, bootFrame, ensureCodedeckShim, exitCodeFor, finishOpenSession, installSigintGuard, renderBanner, renderExit, resumeHint, sanitizeEnv, spinnerTips, withCodedeckOnPath, writeStdoutSync, } from "../../open/runtime.js";
|
|
21
24
|
const DEFAULT_ROLE = "orchestrator";
|
|
22
|
-
export function launchClaude(claudeBin, model, args, cwd, sessionFile, onClose, spawnChild = spawn, signalHost = process, envExtra, pty) {
|
|
25
|
+
export function launchClaude(claudeBin, model, args, cwd, sessionFile, onClose, spawnChild = spawn, signalHost = process, envExtra, pty, onSpawn) {
|
|
23
26
|
return spawnHarness(claudeBin, args, {
|
|
24
27
|
cwd,
|
|
25
28
|
sessionFile,
|
|
@@ -31,6 +34,7 @@ export function launchClaude(claudeBin, model, args, cwd, sessionFile, onClose,
|
|
|
31
34
|
spawnChild,
|
|
32
35
|
signalHost,
|
|
33
36
|
pty,
|
|
37
|
+
onSpawn,
|
|
34
38
|
});
|
|
35
39
|
}
|
|
36
40
|
/**
|
|
@@ -69,6 +73,59 @@ export function harnessMismatch(role, binding) {
|
|
|
69
73
|
return (`Agent "${role}" runs on ${binding.harness}, and ${getCliName()} open only launches claude and opencode sessions. ` +
|
|
70
74
|
`Use \`${getCliName()} run --role ${role} "<prompt>"\`, or move it with \`${getCliName()} setup\`.`);
|
|
71
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Best-effort snapshot of `opencode session list`, or undefined. Capture
|
|
78
|
+
* is allowed to fail: no snapshot means no resume hint (OP-09), never a
|
|
79
|
+
* failed launch. No daemon, no config writes (OP-10, OP-19).
|
|
80
|
+
*/
|
|
81
|
+
export function readOpencodeSessions(bin, cwd) {
|
|
82
|
+
try {
|
|
83
|
+
const parsed = JSON.parse(execFileSync(bin, ["session", "list", "--format", "json", "-n", "50"], {
|
|
84
|
+
encoding: "utf8",
|
|
85
|
+
timeout: 10000,
|
|
86
|
+
maxBuffer: 1024 * 1024,
|
|
87
|
+
...(cwd !== undefined ? { cwd } : {}),
|
|
88
|
+
}));
|
|
89
|
+
return Array.isArray(parsed) ? parsed : undefined;
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* The id of the session created or continued between snapshots, or
|
|
97
|
+
* undefined. A newly created session takes precedence; if no session was
|
|
98
|
+
* created, a single session whose updated timestamp moved forward is
|
|
99
|
+
* identified. Zero or ambiguous sessions mean "cannot tell", and a
|
|
100
|
+
* missing hint beats a wrong one.
|
|
101
|
+
*/
|
|
102
|
+
export function diffOpencodeSession(before, after) {
|
|
103
|
+
const known = new Set(before.map((row) => (typeof row.id === "string" ? row.id : "")));
|
|
104
|
+
const fresh = after.filter((row) => typeof row.id === "string" && !known.has(row.id));
|
|
105
|
+
if (fresh.length === 1)
|
|
106
|
+
return fresh[0].id;
|
|
107
|
+
if (fresh.length > 1)
|
|
108
|
+
return undefined;
|
|
109
|
+
const beforeUpdated = new Map();
|
|
110
|
+
for (const row of before) {
|
|
111
|
+
if (typeof row.id === "string" && typeof row.updated === "number") {
|
|
112
|
+
beforeUpdated.set(row.id, row.updated);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
const touched = after.filter((row) => typeof row.id === "string" &&
|
|
116
|
+
typeof row.updated === "number" &&
|
|
117
|
+
beforeUpdated.has(row.id) &&
|
|
118
|
+
row.updated > (beforeUpdated.get(row.id) ?? 0));
|
|
119
|
+
if (touched.length === 1)
|
|
120
|
+
return touched[0].id;
|
|
121
|
+
if (touched.length > 1) {
|
|
122
|
+
touched.sort((a, b) => b.updated - a.updated);
|
|
123
|
+
if (touched[0].updated > touched[1].updated) {
|
|
124
|
+
return touched[0].id;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return undefined;
|
|
128
|
+
}
|
|
72
129
|
/**
|
|
73
130
|
* The one dispatch decision: the binding owns the harness, and an unbound
|
|
74
131
|
* role opens claude like it always did. Anything else throws instead of
|
|
@@ -235,7 +292,9 @@ export function registerOpenCommand(program) {
|
|
|
235
292
|
.description(`Open a configured Claude Code session (roles: ${ROLES.join(" | ")}, default: ${DEFAULT_ROLE}, 3-letter prefixes accepted)`)
|
|
236
293
|
.option("--model <model>", `model to use (default: ${DEFAULT_MODEL})`)
|
|
237
294
|
.option("--effort <level>", `reasoning effort (default: ${DEFAULT_EFFORT})`)
|
|
238
|
-
.option("--
|
|
295
|
+
.option("--autocompact [value]", "native auto-compact: Claude window size is auto or 100000-1000000 tokens; OpenCode toggles its native setting")
|
|
296
|
+
.option("--no-autocompact", "disable native auto-compaction in Claude and OpenCode")
|
|
297
|
+
.option("--resume <session>", "resume an interactive session")
|
|
239
298
|
.option("--worktree", "ask Claude Code to create an isolated worktree")
|
|
240
299
|
.option("--no-bypass", "do not skip Claude Code permission prompts")
|
|
241
300
|
.option("--no-theme", "keep only the CodeDeck status line, without the theme or the renderer")
|
|
@@ -243,6 +302,7 @@ export function registerOpenCommand(program) {
|
|
|
243
302
|
.allowUnknownOption()
|
|
244
303
|
.action(async (roleArg, opts, command) => {
|
|
245
304
|
const invocation = getInvocation(command, roleArg);
|
|
305
|
+
const autocompact = parseAutocompact(opts.autocompact);
|
|
246
306
|
const interactive = !isNonInteractiveLaunch(invocation.passthrough);
|
|
247
307
|
const role = await resolveRole(invocation.roleInput, interactive);
|
|
248
308
|
const pluginDir = resolvePluginDir();
|
|
@@ -263,22 +323,122 @@ export function registerOpenCommand(program) {
|
|
|
263
323
|
// this file into a live session, and on Linux anyone on the box can put
|
|
264
324
|
// a file in /tmp under a name that is only a pid.
|
|
265
325
|
const sessionFile = path.join(sessionsDir(), `codedeck-session-${process.pid}`);
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
326
|
+
if (launcher === "opencode" && boundModel === undefined) {
|
|
327
|
+
throw new Error(`Agent "${role}" has no model bound. Run \`${getCliName()} setup\` to bind one.`);
|
|
328
|
+
}
|
|
329
|
+
const initialModel = passthroughModel ?? boundModel ?? (launcher === "opencode" ? undefined : DEFAULT_MODEL);
|
|
330
|
+
const adoptRes = await client.request("session.adopt", {
|
|
331
|
+
agent: launcher,
|
|
332
|
+
model: initialModel,
|
|
333
|
+
cwd,
|
|
334
|
+
name: role,
|
|
335
|
+
});
|
|
336
|
+
const runId = adoptRes.session.id;
|
|
337
|
+
let patchPromise;
|
|
338
|
+
try {
|
|
339
|
+
if (launcher === "opencode") {
|
|
340
|
+
let openCwd = cwd;
|
|
341
|
+
let wtInfo;
|
|
342
|
+
if (opts.worktree) {
|
|
343
|
+
const gitInfo = await getGitInfo(cwd);
|
|
344
|
+
if (!gitInfo) {
|
|
345
|
+
throw new Error(`--worktree needs a git repository, and the current directory is outside one.`);
|
|
346
|
+
}
|
|
347
|
+
// A creation failure propagates before the spawn: OP-14 would
|
|
348
|
+
// rather fail than open in the wrong cwd.
|
|
349
|
+
const wt = await createWorktree({
|
|
350
|
+
repoRoot: gitInfo.root,
|
|
351
|
+
sessionId: runId,
|
|
352
|
+
prompt: role,
|
|
353
|
+
name: role,
|
|
354
|
+
});
|
|
355
|
+
wtInfo = wt;
|
|
356
|
+
openCwd = wt.path;
|
|
357
|
+
}
|
|
358
|
+
const model = passthroughModel ?? boundModel;
|
|
359
|
+
await preflightOpencode(model, fromConfig);
|
|
360
|
+
const opencodeBin = await resolveOpencodeBinary();
|
|
361
|
+
// No opencode effort reader (probe-effort-2026-09-07): an explicit
|
|
362
|
+
// flag warns instead of dying silently, and the banner keeps
|
|
363
|
+
// naming "default" (OP-16, OP-23).
|
|
364
|
+
const effort = "default";
|
|
365
|
+
if (opts.effort !== undefined) {
|
|
366
|
+
console.error('Warning: --effort has no effect on opencode (no mapped reader); continuing with "default".');
|
|
367
|
+
}
|
|
368
|
+
// --no-theme asks for no CodeDeck styling, and an animation is styling.
|
|
369
|
+
if (opts.theme === false) {
|
|
370
|
+
process.stdout.write(renderBanner(role, model, effort));
|
|
371
|
+
}
|
|
372
|
+
else {
|
|
373
|
+
await playBoot(role, model, effort);
|
|
374
|
+
}
|
|
375
|
+
// --no-theme leaves the user's own opencode theme alone. Otherwise the
|
|
376
|
+
// managed rage theme is ensured once and selected through an ephemeral
|
|
377
|
+
// config dir, so the user's tui.json is never rewritten.
|
|
378
|
+
const tuiDir = opts.theme === false || !ensureOpencodeTheme(pluginDir)
|
|
379
|
+
? undefined
|
|
380
|
+
: createEphemeralTuiDir();
|
|
381
|
+
// Snapshot before the spawn so the close path can tell which
|
|
382
|
+
// session this launch created or continued (probe-session-id-2026-09-07).
|
|
383
|
+
const sessionsBefore = readOpencodeSessions(opencodeBin, openCwd);
|
|
384
|
+
const closeOpencode = async () => {
|
|
385
|
+
if (tuiDir !== undefined)
|
|
386
|
+
removeEphemeralTuiDir(tuiDir);
|
|
387
|
+
const after = readOpencodeSessions(opencodeBin, openCwd);
|
|
388
|
+
const diffedId = after === undefined || sessionsBefore === undefined
|
|
389
|
+
? undefined
|
|
390
|
+
: diffOpencodeSession(sessionsBefore, after);
|
|
391
|
+
const id = diffedId ?? (opts.resume && SESSION_ID_PATTERN.test(opts.resume) ? opts.resume : undefined);
|
|
392
|
+
if (id !== undefined) {
|
|
393
|
+
try {
|
|
394
|
+
fs.writeFileSync(sessionFile, id);
|
|
395
|
+
}
|
|
396
|
+
catch { }
|
|
397
|
+
}
|
|
398
|
+
const nativeSessionId = finishOpenSession(role, sessionFile);
|
|
399
|
+
try {
|
|
400
|
+
if (patchPromise)
|
|
401
|
+
await patchPromise;
|
|
402
|
+
}
|
|
403
|
+
catch { }
|
|
404
|
+
try {
|
|
405
|
+
await client.request("session.release", {
|
|
406
|
+
id: runId,
|
|
407
|
+
nativeSessionId,
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
catch { }
|
|
411
|
+
};
|
|
412
|
+
await spawnHarness(opencodeBin, buildOpencodeArgs(role, { ...opts, model: boundModel }, invocation.passthrough), {
|
|
413
|
+
cwd: openCwd,
|
|
414
|
+
envExtra: {
|
|
415
|
+
CODEDECK_RUN_ID: runId,
|
|
416
|
+
OPENCODE_CONFIG_CONTENT: buildInlineConfig(pluginDir, role, orchestratorMode, { config, explicit: autocompact }),
|
|
417
|
+
...(tuiDir !== undefined ? { OPENCODE_CONFIG_DIR: tuiDir } : {}),
|
|
418
|
+
},
|
|
419
|
+
sessionFile,
|
|
420
|
+
model,
|
|
421
|
+
notFoundMessage: OPENCODE_NOT_FOUND,
|
|
422
|
+
onClose: closeOpencode,
|
|
423
|
+
onSpawn: (child) => {
|
|
424
|
+
if (child.pid) {
|
|
425
|
+
patchPromise = client.request("session.patch", {
|
|
426
|
+
id: runId,
|
|
427
|
+
pid: child.pid,
|
|
428
|
+
...(wtInfo ? { worktree: wtInfo.path, branch: wtInfo.branch, baseCommit: wtInfo.baseCommit ?? undefined, cwd: wtInfo.path } : {}),
|
|
429
|
+
});
|
|
430
|
+
}
|
|
431
|
+
},
|
|
432
|
+
});
|
|
433
|
+
return;
|
|
276
434
|
}
|
|
277
|
-
const
|
|
278
|
-
|
|
279
|
-
const
|
|
280
|
-
|
|
281
|
-
const
|
|
435
|
+
const resolved = boundModel ?? DEFAULT_MODEL;
|
|
436
|
+
const args = buildOpenArgs(role, { ...opts, model: resolved, remoteControl: config.remoteControl, autocompact }, pluginDir, invocation.passthrough, cwd, orchestratorMode, config);
|
|
437
|
+
const model = passthroughModel ?? resolved;
|
|
438
|
+
await preflightModel(model, fromConfig);
|
|
439
|
+
const claudeBin = await resolveBinary();
|
|
440
|
+
await assertSupport(claudeBin, cwd);
|
|
441
|
+
const effort = opts.effort ?? DEFAULT_EFFORT;
|
|
282
442
|
// --no-theme asks for no CodeDeck styling, and an animation is styling.
|
|
283
443
|
if (opts.theme === false) {
|
|
284
444
|
process.stdout.write(renderBanner(role, model, effort));
|
|
@@ -286,46 +446,47 @@ export function registerOpenCommand(program) {
|
|
|
286
446
|
else {
|
|
287
447
|
await playBoot(role, model, effort);
|
|
288
448
|
}
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
449
|
+
const closeClaude = async () => {
|
|
450
|
+
if (!fs.existsSync(sessionFile) && opts.resume && SESSION_ID_PATTERN.test(opts.resume)) {
|
|
451
|
+
try {
|
|
452
|
+
fs.writeFileSync(sessionFile, opts.resume);
|
|
453
|
+
}
|
|
454
|
+
catch { }
|
|
455
|
+
}
|
|
456
|
+
const nativeSessionId = finishOpenSession(role, sessionFile);
|
|
457
|
+
try {
|
|
458
|
+
if (patchPromise)
|
|
459
|
+
await patchPromise;
|
|
460
|
+
}
|
|
461
|
+
catch { }
|
|
462
|
+
try {
|
|
463
|
+
await client.request("session.release", {
|
|
464
|
+
id: runId,
|
|
465
|
+
nativeSessionId,
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
catch { }
|
|
299
469
|
};
|
|
300
|
-
await
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
}
|
|
307
|
-
sessionFile,
|
|
308
|
-
model,
|
|
309
|
-
notFoundMessage: OPENCODE_NOT_FOUND,
|
|
310
|
-
onClose: closeOpencode,
|
|
470
|
+
await launchClaude(claudeBin, model, args, cwd, sessionFile, closeClaude, undefined, undefined, { CODEDECK_RUN_ID: runId }, ptyLaunchForHarness("claude", pluginDir, sessionFile, opts, config, interactive), (child) => {
|
|
471
|
+
if (child.pid) {
|
|
472
|
+
patchPromise = client.request("session.patch", {
|
|
473
|
+
id: runId,
|
|
474
|
+
pid: child.pid,
|
|
475
|
+
});
|
|
476
|
+
}
|
|
311
477
|
});
|
|
312
|
-
return;
|
|
313
|
-
}
|
|
314
|
-
const resolved = boundModel ?? DEFAULT_MODEL;
|
|
315
|
-
const args = buildOpenArgs(role, { ...opts, model: resolved, remoteControl: config.remoteControl }, pluginDir, invocation.passthrough, cwd, orchestratorMode);
|
|
316
|
-
const model = passthroughModel ?? resolved;
|
|
317
|
-
await preflightModel(model, fromConfig);
|
|
318
|
-
const claudeBin = await resolveBinary();
|
|
319
|
-
await assertSupport(claudeBin, cwd);
|
|
320
|
-
const effort = opts.effort ?? DEFAULT_EFFORT;
|
|
321
|
-
// --no-theme asks for no CodeDeck styling, and an animation is styling.
|
|
322
|
-
if (opts.theme === false) {
|
|
323
|
-
process.stdout.write(renderBanner(role, model, effort));
|
|
324
478
|
}
|
|
325
|
-
|
|
326
|
-
|
|
479
|
+
catch (err) {
|
|
480
|
+
try {
|
|
481
|
+
await client.request("session.release", {
|
|
482
|
+
id: runId,
|
|
483
|
+
status: "failed",
|
|
484
|
+
error: err instanceof Error ? err.message : String(err),
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
catch { }
|
|
488
|
+
throw err;
|
|
327
489
|
}
|
|
328
|
-
await launchClaude(claudeBin, model, args, cwd, sessionFile, () => finishOpenSession(role, sessionFile), undefined, undefined, { CODEDECK_RUN_ID: runId }, ptyLaunchForHarness("claude", pluginDir, sessionFile, opts, config, interactive));
|
|
329
490
|
});
|
|
330
491
|
}
|
|
331
492
|
//# sourceMappingURL=open.js.map
|