flavor-code 1.4.3 → 1.4.4-beta.2
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 +2 -2
- package/README.zh-CN.md +2 -2
- package/dist/{app-TVY2HM5L.js → app-C5I2TH7I.js} +100 -40
- package/dist/{chunk-QACFKPZP.js → chunk-U4XTQ5PU.js} +1 -0
- package/dist/{cli-MAWCV2YR.js → cli-V3BLZ5UW.js} +1 -1
- package/dist/cli-main.js +4 -4
- package/dist/desktop/main.js +9 -0
- package/dist/{production-TQROFEPV.js → production-TD7UWWXW.js} +1 -1
- package/dist/production.d.ts +2 -0
- package/dist/sdk/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -33,7 +33,7 @@ Flavor Code connects to OpenAI, Anthropic, or compatible services and works with
|
|
|
33
33
|
| --- | --- | --- |
|
|
34
34
|
| 🖥️ | **One runtime, three entry points** | CLI, Electron, and VS Code share model configuration, sessions, and tooling |
|
|
35
35
|
| 🧭 | **Controlled progress on complex tasks** | Task plans, sub-agents, steering, follow-ups, `/loop`, `/goal`, and conflict-safe parallel execution (tasks owning overlapping files run serially) |
|
|
36
|
-
| 🏝️ | **Flavor Island local control** | Host apps steer a running session over a token-authenticated local IPC channel (Windows named pipes / Unix sockets): abort, steering, follow-ups, and window focus; model duration, token usage, task summaries, and deliverables are reported via hook events |
|
|
36
|
+
| 🏝️ | **Flavor Island local control** | Host apps steer a running session over a token-authenticated local IPC channel (Windows named pipes / Unix sockets): abort, steering, follow-ups, and window focus; model duration, token usage, session titles, task summaries, and deliverables are reported via hook events |
|
|
37
37
|
| ⏪ | **Traceable, resumable results** | Full timeline, checkpoints, rewind, traces, diffs, and failure audits |
|
|
38
38
|
| 🧱 | **Crash-consistent execution** | Fsync-backed event journal, durable steering queue, savepoints, and no automatic replay of non-idempotent tools |
|
|
39
39
|
| 🧠 | **Local long-term context** | Memory, Skills, plugins, and project guides stored on your machine |
|
|
@@ -325,7 +325,7 @@ A Skill is a `SKILL.md` with YAML frontmatter, placed in `.flavor/skills/<name>/
|
|
|
325
325
|
|
|
326
326
|
Plugins live in `.flavor/plugins/` and can register commands, tools, hooks, Skill roots, and model adapters. Official plugins can be installed with the plugin manager: `npx --yes @flavor-code/plugin-manager`. `additionalContext` returned by `SessionStart` and `UserPromptSubmit` hooks is added to the current task context, enabling reliable project-level engineering policy injection. Plugin loads record a content fingerprint plus declared capabilities. Worker/vm isolation is available through the embedding API's `pluginSandbox: true` option; the compatibility default remains in-process because bundled and existing plugins use Node.js APIs that the isolated runtime does not yet mediate.
|
|
327
327
|
|
|
328
|
-
When the `flavor-island` plugin is loaded, Flavor also starts a Flavor Island local control channel: a loopback-only IPC service (Windows named pipe, or Unix socket on macOS/Linux) secured by a random token. A host app (such as the Flavor Island desktop) can use it to abort, steer, or send follow-ups to a running session, and desktop hosts can also bring their window into focus. The channel's endpoint, token, and capability list are exposed to the host plugin via hook event context (`islandControlEndpoint`/`islandControlToken`/`islandControlCapabilities`); model-call duration and token usage, plus the final task summary and deliverables, are reported through hook events so the host can show live status and a result overview.
|
|
328
|
+
When the `flavor-island` plugin is loaded, Flavor also starts a Flavor Island local control channel: a loopback-only IPC service (Windows named pipe, or Unix socket on macOS/Linux) secured by a random token. A host app (such as the Flavor Island desktop) can use it to abort, steer, or send follow-ups to a running session, and desktop hosts can also bring their window into focus. The channel's endpoint, token, and capability list are exposed to the host plugin via hook event context (`islandControlEndpoint`/`islandControlToken`/`islandControlCapabilities`); model-call duration and token usage, the current session title (desktop custom task name, falling back to the session preview), plus the final task summary and deliverables, are reported through hook events so the host can show live status and a result overview.
|
|
329
329
|
|
|
330
330
|
> [!WARNING]
|
|
331
331
|
> The default in-process plugin runtime grants full Node.js access. Only install and enable plugins you trust. Sandboxing reduces ambient access but does not make untrusted instructions safe, and plugins that import Node.js built-ins will not load with `pluginSandbox: true` yet.
|
package/README.zh-CN.md
CHANGED
|
@@ -33,7 +33,7 @@ Flavor Code 接入 OpenAI、Anthropic 或兼容服务,在受控工作区内使
|
|
|
33
33
|
| --- | --- | --- |
|
|
34
34
|
| 🖥️ | **一个运行时,三个入口** | CLI、Electron 与 VS Code 共享模型配置、会话和工具能力 |
|
|
35
35
|
| 🧭 | **复杂任务可控推进** | 任务计划、子 Agent、steering、follow-up、`/loop`、`/goal`,并行任务自动避免写冲突(拥有重叠文件的任务串行执行) |
|
|
36
|
-
| 🏝️ | **Flavor Island 本地控制** | 宿主应用通过 token 认证的本机 IPC(Windows named pipe / Unix socket)控制运行中的会话:中止、steering、follow-up 与窗口聚焦;模型耗时、token
|
|
36
|
+
| 🏝️ | **Flavor Island 本地控制** | 宿主应用通过 token 认证的本机 IPC(Windows named pipe / Unix socket)控制运行中的会话:中止、steering、follow-up 与窗口聚焦;模型耗时、token 用量、会话标题、任务摘要和交付物随 Hook 事件上报 |
|
|
37
37
|
| ⏪ | **结果可追溯、可恢复** | 完整时间线、checkpoint、rewind、trace、Diff 和失败审计 |
|
|
38
38
|
| 🧱 | **崩溃一致执行** | fsync 事件日志、持久 steering 队列、savepoint,非幂等工具不自动重放 |
|
|
39
39
|
| 🧠 | **本地长期上下文** | 记忆、Skill、插件和项目指南均保存在本机 |
|
|
@@ -325,7 +325,7 @@ Skill 是带有 YAML 头信息的 `SKILL.md`,放在 `.flavor/skills/<name>/`
|
|
|
325
325
|
|
|
326
326
|
插件放在 `.flavor/plugins/`,可以注册命令、工具、Hook、Skill 根目录和模型适配器。官方插件可通过插件管理器安装:`npx --yes @flavor-code/plugin-manager`。`SessionStart` 与 `UserPromptSubmit` Hook 返回的 `additionalContext` 会进入当前任务上下文,可用于注入项目级工程规则。插件加载会记录内容指纹与声明的能力。可通过嵌入 API 的 `pluginSandbox: true` 启用 Worker/vm 隔离;由于内置插件和已有插件依赖沙箱尚未代理的 Node.js API,当前兼容默认值仍为进程内运行。
|
|
327
327
|
|
|
328
|
-
加载 `flavor-island` 插件时,Flavor 会额外启动一个 Flavor Island 本地控制通道:这是一个只监听本机回环的 IPC 服务(Windows 使用 named pipe,macOS/Linux 使用 Unix socket),通过随机 token 认证。宿主应用(如 Flavor Island 桌面端)可以借此对运行中的会话执行中止、steering、follow-up 等操作,桌面端还支持把窗口带到前台(focus)。通道的地址、token 与能力列表会通过 Hook 事件上下文(`islandControlEndpoint`/`islandControlToken`/`islandControlCapabilities`)提供给宿主插件,模型调用的耗时与 token
|
|
328
|
+
加载 `flavor-island` 插件时,Flavor 会额外启动一个 Flavor Island 本地控制通道:这是一个只监听本机回环的 IPC 服务(Windows 使用 named pipe,macOS/Linux 使用 Unix socket),通过随机 token 认证。宿主应用(如 Flavor Island 桌面端)可以借此对运行中的会话执行中止、steering、follow-up 等操作,桌面端还支持把窗口带到前台(focus)。通道的地址、token 与能力列表会通过 Hook 事件上下文(`islandControlEndpoint`/`islandControlToken`/`islandControlCapabilities`)提供给宿主插件,模型调用的耗时与 token 用量、当前会话标题(桌面端自定义任务名,缺省时回退到会话 preview 摘要)、任务结束时的摘要和交付文件也会随 Hook 事件上报,方便宿主展示运行状态与结果概览。
|
|
329
329
|
|
|
330
330
|
> [!WARNING]
|
|
331
331
|
> 默认的进程内插件运行时拥有完整 Node.js 权限,只安装和启用你信任的插件。沙箱会降低环境权限,但不能让不可信指令自动变安全;目前导入 Node.js 内置模块的插件在 `pluginSandbox: true` 下仍无法加载。
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
createGlobTool,
|
|
35
35
|
createProductionRuntime,
|
|
36
36
|
isDestructiveTool
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-U4XTQ5PU.js";
|
|
38
38
|
import {
|
|
39
39
|
getGraphemeSegmenter
|
|
40
40
|
} from "./chunk-TIEOVQW6.js";
|
|
@@ -3427,7 +3427,12 @@ function TerminalLayout({
|
|
|
3427
3427
|
[completed, budget]
|
|
3428
3428
|
);
|
|
3429
3429
|
const memoryReviewRows = memoryReviews.length === 0 ? 0 : 5;
|
|
3430
|
-
const
|
|
3430
|
+
const focusedOpen = approval !== void 0 || questions !== void 0 && questions.length > 0 || queueOpen;
|
|
3431
|
+
const focusedRows = focusedOpen ? Math.min(
|
|
3432
|
+
focusedPanelNaturalRows({ approval, approvalExpanded, questions, questionIndex, queueOpen, pendingPrompts, columns, rows }),
|
|
3433
|
+
Math.min(Math.max(4, rows - 3), Math.max(6, Math.floor(rows / 2)))
|
|
3434
|
+
) : 0;
|
|
3435
|
+
const fixedBottomRows = focusedRows + memoryReviewRows + (pendingPrompts.length === 0 ? 0 : 1) + imageAttachments.length + (clipboardNotice === void 0 ? 0 : 1) + (activeSession ? 1 : 0) + 2;
|
|
3431
3436
|
const taskPanelRows = taskPanelViewportRows(rows, fixedBottomRows, activeTaskBlocks.length > 0);
|
|
3432
3437
|
const availableBottomRows = Math.max(1, rows - taskPanelRows - 1);
|
|
3433
3438
|
const bottomMaxRows = Math.min(availableBottomRows, Math.max(Math.floor(rows / 2), fixedBottomRows + 1));
|
|
@@ -3451,28 +3456,8 @@ function TerminalLayout({
|
|
|
3451
3456
|
} else {
|
|
3452
3457
|
footerHint = `Enter send \xB7 \u2191\u2193/Ctrl/Cmd+R history \xB7 ${outputShortcut} ${expandedOutput ? "collapse all output" : "expand all output"} \xB7 Ctrl+C exit`;
|
|
3453
3458
|
}
|
|
3454
|
-
if (approval !== void 0 || questions !== void 0 && questions.length > 0 || queueOpen) {
|
|
3455
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3456
|
-
FocusedCliPanel,
|
|
3457
|
-
{
|
|
3458
|
-
rows,
|
|
3459
|
-
columns,
|
|
3460
|
-
input,
|
|
3461
|
-
promptCursor,
|
|
3462
|
-
...approval === void 0 ? {} : { approval },
|
|
3463
|
-
approvalExpanded,
|
|
3464
|
-
...questions === void 0 ? {} : { questions },
|
|
3465
|
-
questionIndex,
|
|
3466
|
-
customQuestionActive,
|
|
3467
|
-
pendingPrompts,
|
|
3468
|
-
queueSelection,
|
|
3469
|
-
...onQueueSelectionChange === void 0 ? {} : { onQueueSelectionChange },
|
|
3470
|
-
...focusScrollRef === void 0 ? {} : { focusScrollRef }
|
|
3471
|
-
}
|
|
3472
|
-
);
|
|
3473
|
-
}
|
|
3474
3459
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { height: rows, width: "100%", flexDirection: "column", overflow: "hidden", children: [
|
|
3475
|
-
showWelcome ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Box_default, { flexGrow: 1, flexShrink: 1, flexDirection: "column", overflow: "hidden", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(WelcomeCard, { model, ...serviceName === void 0 ? {} : { serviceName }, workspaceName, ...updateTo === void 0 ? {} : { updateTo }, columns, availableRows: Math.max(0, rows - taskPanelRows - fixedBottomRows - 1) }) }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(ScrollBox_default, { ...scrollRef === void 0 ? {} : { ref: scrollRef }, flexGrow: 1, flexDirection: "column", stickyScroll: true, children: [
|
|
3460
|
+
showWelcome && !focusedOpen ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Box_default, { flexGrow: 1, flexShrink: 1, flexDirection: "column", overflow: "hidden", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(WelcomeCard, { model, ...serviceName === void 0 ? {} : { serviceName }, workspaceName, ...updateTo === void 0 ? {} : { updateTo }, columns, availableRows: Math.max(0, rows - taskPanelRows - fixedBottomRows - 1) }) }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(ScrollBox_default, { ...scrollRef === void 0 ? {} : { ref: scrollRef }, flexGrow: 1, flexDirection: "column", stickyScroll: true, children: [
|
|
3476
3461
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { dimColor: true, children: [
|
|
3477
3462
|
"flavor \xB7 ",
|
|
3478
3463
|
model,
|
|
@@ -3521,6 +3506,23 @@ function TerminalLayout({
|
|
|
3521
3506
|
mentionCompletion === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MentionMenu, { completion: mentionCompletion, ...onMentionSelect === void 0 ? {} : { onSelect: onMentionSelect } })
|
|
3522
3507
|
] }),
|
|
3523
3508
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { flexDirection: "column", flexShrink: 0, maxHeight: bottomMaxRows, width: "100%", overflowY: "hidden", children: [
|
|
3509
|
+
!focusedOpen ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3510
|
+
FocusedCliPanel,
|
|
3511
|
+
{
|
|
3512
|
+
rows,
|
|
3513
|
+
panelRows: focusedRows,
|
|
3514
|
+
columns,
|
|
3515
|
+
...approval === void 0 ? {} : { approval },
|
|
3516
|
+
approvalExpanded,
|
|
3517
|
+
...questions === void 0 ? {} : { questions },
|
|
3518
|
+
questionIndex,
|
|
3519
|
+
customQuestionActive,
|
|
3520
|
+
pendingPrompts,
|
|
3521
|
+
queueSelection,
|
|
3522
|
+
...onQueueSelectionChange === void 0 ? {} : { onQueueSelectionChange },
|
|
3523
|
+
...focusScrollRef === void 0 ? {} : { focusScrollRef }
|
|
3524
|
+
}
|
|
3525
|
+
),
|
|
3524
3526
|
memoryReviews.length === 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MemoryReviewCards, { reviews: memoryReviews, autoDismissSeconds: memoryAutoDismissSeconds }),
|
|
3525
3527
|
!activeSession ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { color: "cyan", wrap: "truncate-end", children: columns < 48 ? "Running \xB7 Enter queues \xB7 /queue list" : "Running \xB7 /queue manage \xB7 Enter queues next \xB7 /steer acts now" }),
|
|
3526
3528
|
pendingPrompts.length === 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: "yellow", wrap: "truncate-end", children: [
|
|
@@ -3584,11 +3586,34 @@ function ideFooterPresentation(context) {
|
|
|
3584
3586
|
const count = Math.max(1, endLine - context.selection.start.line + 1);
|
|
3585
3587
|
return `${count} ${count === 1 ? "line" : "lines"} selected`;
|
|
3586
3588
|
}
|
|
3589
|
+
function focusedPanelNaturalRows({
|
|
3590
|
+
approval,
|
|
3591
|
+
approvalExpanded,
|
|
3592
|
+
questions,
|
|
3593
|
+
questionIndex,
|
|
3594
|
+
queueOpen,
|
|
3595
|
+
pendingPrompts,
|
|
3596
|
+
columns,
|
|
3597
|
+
rows
|
|
3598
|
+
}) {
|
|
3599
|
+
if (approval !== void 0) {
|
|
3600
|
+
const allowAlways = !isDestructiveTool(approval.tool) && approval.allowAlways !== false;
|
|
3601
|
+
const detail = approvalExpanded ? approvalDetailLines(approval) : [];
|
|
3602
|
+
const contentRows = wrappedRows(approval.reason ?? "This action needs permission.", columns) + detail.reduce((total, line) => total + wrappedRows(line, columns), 0);
|
|
3603
|
+
return 1 + Math.max(contentRows, 1) + 2 + (allowAlways && columns < 36 && rows >= 5 ? 1 : 0);
|
|
3604
|
+
}
|
|
3605
|
+
const question = questions?.[Math.min(questionIndex, questions.length - 1)];
|
|
3606
|
+
if (question !== void 0) {
|
|
3607
|
+
const contentRows = wrappedRows(question.question, columns) + question.options.reduce((total, option) => total + wrappedRows(`${option.label}${option.description ? ` ${option.description}` : ""}`, columns), 0) + 1;
|
|
3608
|
+
return 1 + Math.max(contentRows, 1) + 1;
|
|
3609
|
+
}
|
|
3610
|
+
if (queueOpen) return 1 + Math.max(1, pendingPrompts.length) + 2;
|
|
3611
|
+
return 0;
|
|
3612
|
+
}
|
|
3587
3613
|
function FocusedCliPanel({
|
|
3588
3614
|
rows,
|
|
3615
|
+
panelRows,
|
|
3589
3616
|
columns,
|
|
3590
|
-
input,
|
|
3591
|
-
promptCursor,
|
|
3592
3617
|
approval,
|
|
3593
3618
|
approvalExpanded,
|
|
3594
3619
|
questions,
|
|
@@ -3602,27 +3627,45 @@ function FocusedCliPanel({
|
|
|
3602
3627
|
if (approval !== void 0) {
|
|
3603
3628
|
const allowAlways = !isDestructiveTool(approval.tool) && approval.allowAlways !== false;
|
|
3604
3629
|
const narrow = columns < 36;
|
|
3605
|
-
|
|
3630
|
+
const detailLines = approvalExpanded ? approvalDetailLines(approval) : [];
|
|
3631
|
+
const chromeRows = 3 + (allowAlways && narrow && rows >= 5 ? 1 : 0);
|
|
3632
|
+
const thirdHint = allowAlways && narrow && rows >= 5;
|
|
3633
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { width: "100%", height: panelRows, flexDirection: "column", flexShrink: 0, overflow: "hidden", children: [
|
|
3606
3634
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { bold: true, color: "magenta", wrap: "truncate-end", children: [
|
|
3635
|
+
"\u250C\u2500 ",
|
|
3607
3636
|
"Approval \xB7 ",
|
|
3608
3637
|
approval.tool
|
|
3609
3638
|
] }),
|
|
3610
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(ScrollBox_default, { ...focusScrollRef === void 0 ? {} : { ref: focusScrollRef },
|
|
3611
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.
|
|
3612
|
-
|
|
3639
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(ScrollBox_default, { ...focusScrollRef === void 0 ? {} : { ref: focusScrollRef }, height: Math.max(1, panelRows - chromeRows), flexDirection: "column", children: [
|
|
3640
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: "magentaBright", wrap: "wrap", children: [
|
|
3641
|
+
"\u2502 ",
|
|
3642
|
+
approval.reason ?? "This action needs permission."
|
|
3643
|
+
] }),
|
|
3644
|
+
approvalExpanded ? detailLines.map((line, index) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: "magentaBright", wrap: "wrap", children: [
|
|
3645
|
+
"\u2502 ",
|
|
3646
|
+
line
|
|
3647
|
+
] }, `${approval.id}:detail:${index}`)) : null
|
|
3648
|
+
] }),
|
|
3649
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { bold: true, color: "magenta", wrap: "truncate-end", children: [
|
|
3650
|
+
"\u2502 ",
|
|
3651
|
+
narrow ? "y once \xB7 n deny" : "y=once \xB7 n=deny \xB7 Esc=deny"
|
|
3613
3652
|
] }),
|
|
3614
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Text, { bold: true, color: "magenta", wrap: "truncate-end", children: narrow ? "y once \xB7 n deny" : "y=once \xB7 n=deny \xB7 Esc=deny" }),
|
|
3615
3653
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: "magenta", wrap: "truncate-end", children: [
|
|
3654
|
+
thirdHint ? "\u2502 " : "\u2514\u2500 ",
|
|
3616
3655
|
narrow ? "v details \xB7 e edits" : "v=details \xB7 e=accept edits",
|
|
3617
3656
|
allowAlways && !narrow ? " \xB7 a=same-type" : ""
|
|
3618
3657
|
] }),
|
|
3619
|
-
|
|
3658
|
+
thirdHint ? /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: "magenta", wrap: "truncate-end", children: [
|
|
3659
|
+
"\u2514\u2500 ",
|
|
3660
|
+
"a same-type \xB7 Esc deny"
|
|
3661
|
+
] }) : null
|
|
3620
3662
|
] });
|
|
3621
3663
|
}
|
|
3622
3664
|
const question = questions?.[Math.min(questionIndex, questions.length - 1)];
|
|
3623
3665
|
if (question !== void 0) {
|
|
3624
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, {
|
|
3666
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { width: "100%", height: panelRows, flexDirection: "column", flexShrink: 0, overflow: "hidden", children: [
|
|
3625
3667
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { bold: true, color: "cyan", wrap: "truncate-end", children: [
|
|
3668
|
+
"\u250C\u2500 ",
|
|
3626
3669
|
"Question ",
|
|
3627
3670
|
questionIndex + 1,
|
|
3628
3671
|
"/",
|
|
@@ -3630,10 +3673,14 @@ function FocusedCliPanel({
|
|
|
3630
3673
|
" \xB7 ",
|
|
3631
3674
|
question.header
|
|
3632
3675
|
] }),
|
|
3633
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(ScrollBox_default, { ...focusScrollRef === void 0 ? {} : { ref: focusScrollRef },
|
|
3634
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.
|
|
3676
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(ScrollBox_default, { ...focusScrollRef === void 0 ? {} : { ref: focusScrollRef }, height: Math.max(1, panelRows - 2), flexDirection: "column", children: [
|
|
3677
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: "cyanBright", wrap: "wrap", children: [
|
|
3678
|
+
"\u2502 ",
|
|
3679
|
+
question.question
|
|
3680
|
+
] }),
|
|
3635
3681
|
question.options.map((option, index) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: "cyan", wrap: "wrap", children: [
|
|
3636
3682
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { bold: true, color: "green", children: [
|
|
3683
|
+
"\u2502 ",
|
|
3637
3684
|
index + 1,
|
|
3638
3685
|
". ",
|
|
3639
3686
|
option.label
|
|
@@ -3641,21 +3688,25 @@ function FocusedCliPanel({
|
|
|
3641
3688
|
option.description ? ` ${option.description}` : ""
|
|
3642
3689
|
] }, index)),
|
|
3643
3690
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: "cyan", children: [
|
|
3691
|
+
"\u2502 ",
|
|
3644
3692
|
question.options.length + 1,
|
|
3645
3693
|
". Custom input"
|
|
3646
3694
|
] })
|
|
3647
3695
|
] }),
|
|
3648
|
-
|
|
3649
|
-
|
|
3696
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: "cyan", wrap: "truncate-end", children: [
|
|
3697
|
+
"\u2514\u2500 ",
|
|
3698
|
+
customQuestionActive ? columns < 40 ? "Enter answer \xB7 Esc choices" : "Enter=answer \xB7 Esc=choices \xB7 PgUp/PgDn=scroll" : columns < 40 ? `1-${question.options.length + 1} choose \xB7 Esc cancel` : `1-${question.options.length + 1}=choose \xB7 Esc=cancel \xB7 PgUp/PgDn=scroll`
|
|
3699
|
+
] })
|
|
3650
3700
|
] });
|
|
3651
3701
|
}
|
|
3652
|
-
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, {
|
|
3702
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Box_default, { width: "100%", height: panelRows, flexDirection: "column", flexShrink: 0, overflow: "hidden", children: [
|
|
3653
3703
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { bold: true, color: "yellow", wrap: "truncate-end", children: [
|
|
3704
|
+
"\u250C\u2500 ",
|
|
3654
3705
|
"Queued messages (",
|
|
3655
3706
|
pendingPrompts.length,
|
|
3656
3707
|
")"
|
|
3657
3708
|
] }),
|
|
3658
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ScrollBox_default, { ...focusScrollRef === void 0 ? {} : { ref: focusScrollRef },
|
|
3709
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ScrollBox_default, { ...focusScrollRef === void 0 ? {} : { ref: focusScrollRef }, height: Math.max(1, panelRows - 3), flexDirection: "column", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
3659
3710
|
QueueItems,
|
|
3660
3711
|
{
|
|
3661
3712
|
items: pendingPrompts,
|
|
@@ -3664,10 +3715,19 @@ function FocusedCliPanel({
|
|
|
3664
3715
|
...onQueueSelectionChange === void 0 ? {} : { onSelect: onQueueSelectionChange }
|
|
3665
3716
|
}
|
|
3666
3717
|
) }),
|
|
3667
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.
|
|
3668
|
-
|
|
3718
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { bold: true, color: "yellow", wrap: "truncate-end", children: [
|
|
3719
|
+
"\u2502 ",
|
|
3720
|
+
columns < 48 ? "Enter edit \xB7 d cancel" : "Enter=edit selected \xB7 d=cancel selected"
|
|
3721
|
+
] }),
|
|
3722
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(Text, { color: "yellow", wrap: "truncate-end", children: [
|
|
3723
|
+
"\u2514\u2500 ",
|
|
3724
|
+
columns < 48 ? "\u2191\u2193 select \xB7 Esc close" : "\u2191/\u2193=select \xB7 PgUp/PgDn=jump \xB7 Esc=close"
|
|
3725
|
+
] })
|
|
3669
3726
|
] });
|
|
3670
3727
|
}
|
|
3728
|
+
function wrappedRows(text, columns) {
|
|
3729
|
+
return Math.max(1, Math.ceil(stringWidth(text) / Math.max(20, columns)));
|
|
3730
|
+
}
|
|
3671
3731
|
function QueueItems({ items, selection, scrollRef, onSelect }) {
|
|
3672
3732
|
const selectedElement = (0, import_react8.useRef)(null);
|
|
3673
3733
|
(0, import_react8.useEffect)(() => {
|
|
@@ -40914,6 +40914,7 @@ async function createProductionRuntime(options) {
|
|
|
40914
40914
|
protocolVersion: 2,
|
|
40915
40915
|
workspace,
|
|
40916
40916
|
...hookSessionId === void 0 ? {} : { sessionId: hookSessionId },
|
|
40917
|
+
...hookSessionId === void 0 || options.islandSessionTitle === void 0 ? {} : { sessionTitle: options.islandSessionTitle(hookSessionId) },
|
|
40917
40918
|
...islandControlMetadata === void 0 ? {} : {
|
|
40918
40919
|
islandControlEndpoint: islandControlMetadata.endpoint,
|
|
40919
40920
|
islandControlToken: islandControlMetadata.token,
|
|
@@ -3,7 +3,7 @@ import { createRequire as createFlavorRequire } from "node:module"; const requir
|
|
|
3
3
|
import {
|
|
4
4
|
createExecutionEnvironment,
|
|
5
5
|
createProductionRuntime
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-U4XTQ5PU.js";
|
|
7
7
|
import "./chunk-TIEOVQW6.js";
|
|
8
8
|
import "./chunk-OKHV7CTB.js";
|
|
9
9
|
import {
|
package/dist/cli-main.js
CHANGED
|
@@ -4081,7 +4081,7 @@ function createProgram(dependencies = {}) {
|
|
|
4081
4081
|
registerConfigCommands(program2);
|
|
4082
4082
|
registerUsageCommands(program2);
|
|
4083
4083
|
program2.command("eval <spec>").option("--output <path>", "write the JSON report to a file").description("run a repeatable coding-agent evaluation").action(async (spec, command) => {
|
|
4084
|
-
const { runEvaluationFile } = await import("./cli-
|
|
4084
|
+
const { runEvaluationFile } = await import("./cli-V3BLZ5UW.js");
|
|
4085
4085
|
process.exitCode = await runEvaluationFile(spec, command.output);
|
|
4086
4086
|
});
|
|
4087
4087
|
program2.action(async (options) => {
|
|
@@ -4173,7 +4173,7 @@ async function runInteractiveCli(props) {
|
|
|
4173
4173
|
const [{ render, AlternateScreen }, { default: React }, { App }] = await Promise.all([
|
|
4174
4174
|
import("./claude-ink-F554I3GJ.js"),
|
|
4175
4175
|
import("./react-M6JGXSJZ.js"),
|
|
4176
|
-
import("./app-
|
|
4176
|
+
import("./app-C5I2TH7I.js")
|
|
4177
4177
|
]);
|
|
4178
4178
|
const instance = await render(React.createElement(
|
|
4179
4179
|
AlternateScreen,
|
|
@@ -4212,7 +4212,7 @@ async function runRpcMode(options) {
|
|
|
4212
4212
|
import("./server-2KLKPHPL.js"),
|
|
4213
4213
|
import("./write-stream-CGD57URC.js"),
|
|
4214
4214
|
import("./recorder-FAGJJH3N.js"),
|
|
4215
|
-
import("./production-
|
|
4215
|
+
import("./production-TD7UWWXW.js")
|
|
4216
4216
|
]);
|
|
4217
4217
|
let recorder;
|
|
4218
4218
|
try {
|
|
@@ -4346,7 +4346,7 @@ async function runPrint(prompt, dependencies = {}, resumeSession, memoryRestart
|
|
|
4346
4346
|
code = 1;
|
|
4347
4347
|
});
|
|
4348
4348
|
try {
|
|
4349
|
-
const createRuntime = dependencies.createRuntime ?? (await import("./production-
|
|
4349
|
+
const createRuntime = dependencies.createRuntime ?? (await import("./production-TD7UWWXW.js")).createProductionRuntime;
|
|
4350
4350
|
runtime = await createRuntime({
|
|
4351
4351
|
workspace: process.cwd(),
|
|
4352
4352
|
home: homedir3(),
|
package/dist/desktop/main.js
CHANGED
|
@@ -30210,6 +30210,7 @@ async function createProductionRuntime(options) {
|
|
|
30210
30210
|
protocolVersion: 2,
|
|
30211
30211
|
workspace,
|
|
30212
30212
|
...hookSessionId === void 0 ? {} : { sessionId: hookSessionId },
|
|
30213
|
+
...hookSessionId === void 0 || options.islandSessionTitle === void 0 ? {} : { sessionTitle: options.islandSessionTitle(hookSessionId) },
|
|
30213
30214
|
...islandControlMetadata === void 0 ? {} : {
|
|
30214
30215
|
islandControlEndpoint: islandControlMetadata.endpoint,
|
|
30215
30216
|
islandControlToken: islandControlMetadata.token,
|
|
@@ -37174,6 +37175,14 @@ function createDesktopController(workspace, owner2) {
|
|
|
37174
37175
|
},
|
|
37175
37176
|
createRuntime: async (runtimeOptions) => createProductionRuntime({
|
|
37176
37177
|
...runtimeOptions,
|
|
37178
|
+
islandSessionTitle: (sessionId) => {
|
|
37179
|
+
const project = workspace ?? runtimeOptions.workspace;
|
|
37180
|
+
if (project === void 0) return void 0;
|
|
37181
|
+
const custom = workbench.sessionMeta[sessionMetaKey(project, sessionId)]?.title?.trim();
|
|
37182
|
+
if (custom) return custom;
|
|
37183
|
+
const summary2 = owner2?.snapshot.sessions.find((item) => item.sessionId === sessionId) ?? managedProjects.get(project)?.snapshot.sessions.find((item) => item.sessionId === sessionId);
|
|
37184
|
+
return summary2?.preview?.trim();
|
|
37185
|
+
},
|
|
37177
37186
|
islandControl: {
|
|
37178
37187
|
focus: () => {
|
|
37179
37188
|
const target = mainWindow;
|
package/dist/production.d.ts
CHANGED
|
@@ -60,6 +60,8 @@ export interface ProductionRuntimeOptions {
|
|
|
60
60
|
islandControl?: {
|
|
61
61
|
focus?(): void | Promise<void>;
|
|
62
62
|
};
|
|
63
|
+
/** Current desktop task title for the companion island; read on every hook. */
|
|
64
|
+
islandSessionTitle?: (sessionId: string) => string | undefined;
|
|
63
65
|
/** Explicitly opt into CLI-local collaboration. Omit for print/RPC/eval callers. */
|
|
64
66
|
collaboration?: {
|
|
65
67
|
instanceId: string;
|
package/dist/sdk/index.js
CHANGED
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
WorkspaceCheckpointStore,
|
|
16
16
|
buildDockerInvocation,
|
|
17
17
|
createProductionRuntime
|
|
18
|
-
} from "../chunk-
|
|
18
|
+
} from "../chunk-U4XTQ5PU.js";
|
|
19
19
|
import "../chunk-TIEOVQW6.js";
|
|
20
20
|
import "../chunk-OKHV7CTB.js";
|
|
21
21
|
import "../chunk-JQM2L2YM.js";
|