shortcutxl 0.3.73 → 0.3.74
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/CHANGELOG.md +1 -1
- package/dist/app/subagents/clone/agent.d.ts +1 -0
- package/dist/app/subagents/clone/agent.js +12 -3
- package/dist/app/subagents/index.d.ts +1 -1
- package/dist/app/subagents/index.js +1 -1
- package/dist/cli.js +12 -3
- package/dist/embedded-agent/host-tools/task/agents/clone.d.ts +1 -0
- package/dist/embedded-agent/host-tools/task/agents/clone.js +11 -3
- package/native-app/package.json +1 -1
- package/native-app/renderer/assets/{index-upOaS1d7.js → index-Fluj0X8h.js} +87 -36
- package/native-app/renderer/assets/{index-m6aeCx-5.css → index-OhGE0UY4.css} +42 -32
- package/native-app/renderer/index.html +2 -2
- package/package.json +1 -1
- package/user-docs/dist/shortcutxl-docs.pdf +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,5 +3,6 @@
|
|
|
3
3
|
* but cannot spawn other clones.
|
|
4
4
|
*/
|
|
5
5
|
import type { AgentDefinition } from '../../agent-definition.js';
|
|
6
|
+
export declare const CLONE_AGENT_TOOL_NAMES: readonly ["bash", "write", "execute_code", "task", "take_screenshot", "get_tool_info", "execute_tool", "mcp"];
|
|
6
7
|
export declare const cloneAgent: AgentDefinition;
|
|
7
8
|
//# sourceMappingURL=agent.d.ts.map
|
|
@@ -2,13 +2,22 @@
|
|
|
2
2
|
* Clone subagent — a full copy of the action agent that can spawn leaf subagents
|
|
3
3
|
* but cannot spawn other clones.
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
6
|
-
import { ACTION_AGENT_TOOL_NAMES } from '../../modes/action/agent.js';
|
|
5
|
+
import { BASH, EXECUTE_CODE, EXECUTE_TOOL, GET_TOOL_INFO, MCP_TOOL_NAMES, TAKE_SCREENSHOT, TASK, WRITE } from '../../../tool-names.js';
|
|
7
6
|
import { buildActionPrompt } from '../../modes/action/prompt.js';
|
|
8
7
|
import { DEFAULT_SUBAGENT_MODEL, DEFAULT_SUBAGENT_TIMEOUT_SECONDS } from '../defaults.js';
|
|
9
8
|
const NAME = 'clone';
|
|
10
9
|
const DESCRIPTION = `\
|
|
11
10
|
A write-capable clone of the main agent with the same tools, including the ability to spawn subagents. Useful for parallelization and delegation of tasks.`;
|
|
11
|
+
export const CLONE_AGENT_TOOL_NAMES = [
|
|
12
|
+
BASH,
|
|
13
|
+
WRITE,
|
|
14
|
+
EXECUTE_CODE,
|
|
15
|
+
TASK,
|
|
16
|
+
TAKE_SCREENSHOT,
|
|
17
|
+
GET_TOOL_INFO,
|
|
18
|
+
EXECUTE_TOOL,
|
|
19
|
+
...MCP_TOOL_NAMES
|
|
20
|
+
];
|
|
12
21
|
const SUBAGENT_OUTPUT_DISCIPLINE = `\
|
|
13
22
|
======================
|
|
14
23
|
SUBAGENT OUTPUT
|
|
@@ -20,7 +29,7 @@ export const cloneAgent = {
|
|
|
20
29
|
get systemPrompt() {
|
|
21
30
|
return `${buildActionPrompt()}\n\n${SUBAGENT_OUTPUT_DISCIPLINE}`;
|
|
22
31
|
},
|
|
23
|
-
tools:
|
|
32
|
+
tools: [...CLONE_AGENT_TOOL_NAMES],
|
|
24
33
|
excludeSubagents: ['clone'],
|
|
25
34
|
model: DEFAULT_SUBAGENT_MODEL,
|
|
26
35
|
thinkingLevel: 'medium',
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* catalog, even after test resets.
|
|
6
6
|
*/
|
|
7
7
|
export type { AgentDefinition } from '../agent-definition.js';
|
|
8
|
-
export { cloneAgent } from './clone/agent.js';
|
|
8
|
+
export { CLONE_AGENT_TOOL_NAMES, cloneAgent } from './clone/agent.js';
|
|
9
9
|
export { DEFAULT_SUBAGENT_MODEL, DEFAULT_SUBAGENT_TIMEOUT_SECONDS, TASK_MODEL_CHOICES } from './defaults.js';
|
|
10
10
|
export { documentReaderAgent } from './document-reader/agent.js';
|
|
11
11
|
export { verificationAgent } from './verification/agent.js';
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Built-in agents are registered eagerly so callers always see a stable
|
|
5
5
|
* catalog, even after test resets.
|
|
6
6
|
*/
|
|
7
|
-
export { cloneAgent } from './clone/agent.js';
|
|
7
|
+
export { CLONE_AGENT_TOOL_NAMES, cloneAgent } from './clone/agent.js';
|
|
8
8
|
export { DEFAULT_SUBAGENT_MODEL, DEFAULT_SUBAGENT_TIMEOUT_SECONDS, TASK_MODEL_CHOICES } from './defaults.js';
|
|
9
9
|
export { documentReaderAgent } from './document-reader/agent.js';
|
|
10
10
|
export { verificationAgent } from './verification/agent.js';
|
package/dist/cli.js
CHANGED
|
@@ -372010,16 +372010,25 @@ var init_defaults = __esm({
|
|
|
372010
372010
|
});
|
|
372011
372011
|
|
|
372012
372012
|
// src/app/subagents/clone/agent.ts
|
|
372013
|
-
var NAME, DESCRIPTION6, SUBAGENT_OUTPUT_DISCIPLINE, cloneAgent;
|
|
372013
|
+
var NAME, DESCRIPTION6, CLONE_AGENT_TOOL_NAMES, SUBAGENT_OUTPUT_DISCIPLINE, cloneAgent;
|
|
372014
372014
|
var init_agent6 = __esm({
|
|
372015
372015
|
"src/app/subagents/clone/agent.ts"() {
|
|
372016
372016
|
"use strict";
|
|
372017
372017
|
init_tool_names();
|
|
372018
|
-
init_agent();
|
|
372019
372018
|
init_prompt();
|
|
372020
372019
|
init_defaults();
|
|
372021
372020
|
NAME = "clone";
|
|
372022
372021
|
DESCRIPTION6 = `A write-capable clone of the main agent with the same tools, including the ability to spawn subagents. Useful for parallelization and delegation of tasks.`;
|
|
372022
|
+
CLONE_AGENT_TOOL_NAMES = [
|
|
372023
|
+
BASH,
|
|
372024
|
+
WRITE,
|
|
372025
|
+
EXECUTE_CODE,
|
|
372026
|
+
TASK,
|
|
372027
|
+
TAKE_SCREENSHOT,
|
|
372028
|
+
GET_TOOL_INFO,
|
|
372029
|
+
EXECUTE_TOOL,
|
|
372030
|
+
...MCP_TOOL_NAMES
|
|
372031
|
+
];
|
|
372023
372032
|
SUBAGENT_OUTPUT_DISCIPLINE = `======================
|
|
372024
372033
|
SUBAGENT OUTPUT
|
|
372025
372034
|
======================
|
|
@@ -372032,7 +372041,7 @@ Be concise and clear. Keep reports clear, succinct, and structured when possible
|
|
|
372032
372041
|
|
|
372033
372042
|
${SUBAGENT_OUTPUT_DISCIPLINE}`;
|
|
372034
372043
|
},
|
|
372035
|
-
tools:
|
|
372044
|
+
tools: [...CLONE_AGENT_TOOL_NAMES],
|
|
372036
372045
|
excludeSubagents: ["clone"],
|
|
372037
372046
|
model: DEFAULT_SUBAGENT_MODEL,
|
|
372038
372047
|
thinkingLevel: "medium",
|
|
@@ -5,5 +5,6 @@
|
|
|
5
5
|
* can spawn leaf subagents, but cannot recursively spawn another clone.
|
|
6
6
|
*/
|
|
7
7
|
import { type AgentDefinition } from '../agent-definition.js';
|
|
8
|
+
export declare const CLONE_TOOL_NAMES: readonly ["get_tool_info", "execute_tool", "execute_code", "bash_command", "take_screenshot", "mcp", "task"];
|
|
8
9
|
export declare const cloneSubagent: AgentDefinition;
|
|
9
10
|
//# sourceMappingURL=clone.d.ts.map
|
|
@@ -9,11 +9,19 @@ import { AGENT_PHILOSOPHY, COMMUNICATION, DATA_FORMATTING, TASK_EXECUTION, WRITI
|
|
|
9
9
|
import { buildSubagentApiReferenceSection } from '../../../../utils/api-reference.js';
|
|
10
10
|
import { buildActionModeMainSection } from '../../../prompt/modes/action.js';
|
|
11
11
|
import { API_HIERARCHY_SECTION, SANDBOX_FILESYSTEM, getPlatformIdentity } from '../../../prompt/sections.js';
|
|
12
|
-
import {
|
|
13
|
-
import { REFRESH_CONTEXT } from '../../tool-names.js';
|
|
12
|
+
import { BASH_COMMAND, EXECUTE_CODE, EXECUTE_TOOL, GET_TOOL_INFO, MCP, TAKE_SCREENSHOT, TASK } from '../../tool-names.js';
|
|
14
13
|
import { DEFAULT_TASK_SUBAGENT_MODEL_ID, DEFAULT_TASK_SUBAGENT_TIMEOUT_SECONDS } from '../agent-definition.js';
|
|
15
14
|
const DESCRIPTION = `\
|
|
16
15
|
A write-capable clone of the main agent with the same tools, including the ability to spawn subagents. Useful for parallelization and delegation of tasks.`;
|
|
16
|
+
export const CLONE_TOOL_NAMES = [
|
|
17
|
+
GET_TOOL_INFO,
|
|
18
|
+
EXECUTE_TOOL,
|
|
19
|
+
EXECUTE_CODE,
|
|
20
|
+
BASH_COMMAND,
|
|
21
|
+
TAKE_SCREENSHOT,
|
|
22
|
+
MCP,
|
|
23
|
+
TASK
|
|
24
|
+
];
|
|
17
25
|
const SUBAGENT_OUTPUT_SECTION = `\
|
|
18
26
|
======================
|
|
19
27
|
SUBAGENT OUTPUT
|
|
@@ -40,7 +48,7 @@ export const cloneSubagent = {
|
|
|
40
48
|
name: 'clone',
|
|
41
49
|
description: DESCRIPTION,
|
|
42
50
|
systemPrompt: buildSystemPrompt,
|
|
43
|
-
tools:
|
|
51
|
+
tools: [...CLONE_TOOL_NAMES],
|
|
44
52
|
model: DEFAULT_TASK_SUBAGENT_MODEL_ID,
|
|
45
53
|
thinkingLevel: RUNTIME_THINKING_LEVEL.Medium,
|
|
46
54
|
timeoutSeconds: DEFAULT_TASK_SUBAGENT_TIMEOUT_SECONDS,
|
package/native-app/package.json
CHANGED
|
@@ -25602,6 +25602,7 @@ function indexToolResults(messages) {
|
|
|
25602
25602
|
}
|
|
25603
25603
|
return results;
|
|
25604
25604
|
}
|
|
25605
|
+
const MAX_COLLAPSED_LINES = 2;
|
|
25605
25606
|
function record(value) {
|
|
25606
25607
|
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
25607
25608
|
}
|
|
@@ -25655,6 +25656,13 @@ function line(text2, tone = "output") {
|
|
|
25655
25656
|
function splitLines(text2, tone = "output") {
|
|
25656
25657
|
return text2.replace(/\t/g, " ").split("\n").map((value) => line(value, tone));
|
|
25657
25658
|
}
|
|
25659
|
+
function compactOutputLine(text2) {
|
|
25660
|
+
return compact(text2, 180);
|
|
25661
|
+
}
|
|
25662
|
+
function capCollapsedLines(lines) {
|
|
25663
|
+
if (lines.length <= MAX_COLLAPSED_LINES) return lines;
|
|
25664
|
+
return [lines[0], lines.at(-1)];
|
|
25665
|
+
}
|
|
25658
25666
|
function titleText(parts) {
|
|
25659
25667
|
return parts.map((value) => value.text).join("");
|
|
25660
25668
|
}
|
|
@@ -25694,9 +25702,13 @@ function bashPresentation(args, output, details, isError) {
|
|
|
25694
25702
|
if (suffix) expandedHeader.push(part(suffix, "dim"));
|
|
25695
25703
|
const rawLines = output.trim() ? output.trim().split("\n") : [];
|
|
25696
25704
|
const outputTone = isError ? "error" : "output";
|
|
25697
|
-
const
|
|
25698
|
-
const
|
|
25699
|
-
|
|
25705
|
+
const lastOutput = rawLines.at(-1);
|
|
25706
|
+
const preview = lastOutput ? [
|
|
25707
|
+
line(
|
|
25708
|
+
`⎿ ${compactOutputLine(lastOutput)}${rawLines.length > 1 ? ` · ${rawLines.length} lines` : ""}`,
|
|
25709
|
+
outputTone
|
|
25710
|
+
)
|
|
25711
|
+
] : [];
|
|
25700
25712
|
preview.push(...warningLines(details));
|
|
25701
25713
|
const expanded = rawLines.map(
|
|
25702
25714
|
(value, index2) => line(`${index2 === 0 ? "⎿ " : " "}${value}`, outputTone)
|
|
@@ -25719,37 +25731,36 @@ function fileHeader(name2, args) {
|
|
|
25719
25731
|
}
|
|
25720
25732
|
return [part(name2, "title", true), part(" "), part(path2, "accent")];
|
|
25721
25733
|
}
|
|
25722
|
-
function filePresentation(name2, args, output, details, isError) {
|
|
25734
|
+
function filePresentation(name2, args, output, details, isError, running) {
|
|
25723
25735
|
const header = fileHeader(name2, args);
|
|
25724
25736
|
if (name2 === "read") {
|
|
25725
25737
|
if (!output) return { header, collapsedLines: [], expandedLines: [] };
|
|
25726
25738
|
const lines = output.replace(/\t/g, " ").split("\n");
|
|
25727
|
-
const preview = lines.slice(-2).map((value) => line(value));
|
|
25728
|
-
const skipped = Math.max(0, lines.length - 2);
|
|
25729
|
-
if (skipped > 0) preview.push(line(`... +${skipped} lines`, "dim"));
|
|
25730
25739
|
return {
|
|
25731
25740
|
header,
|
|
25732
|
-
collapsedLines:
|
|
25741
|
+
collapsedLines: [
|
|
25742
|
+
line(`Read ${lines.length} ${lines.length === 1 ? "line" : "lines"}`, "dim")
|
|
25743
|
+
],
|
|
25733
25744
|
expandedLines: lines.map((value) => line(value))
|
|
25734
25745
|
};
|
|
25735
25746
|
}
|
|
25736
25747
|
if (name2 === "write") {
|
|
25737
25748
|
const content2 = stringArg(args, "content");
|
|
25749
|
+
const hasContent = typeof args.content === "string";
|
|
25738
25750
|
const contentLines = content2 ? content2.replace(/\t/g, " ").split("\n") : [];
|
|
25739
|
-
const collapsedLines = contentLines.slice(0, 10).map((value) => line(value));
|
|
25740
|
-
if (contentLines.length > 10) {
|
|
25741
|
-
collapsedLines.push(
|
|
25742
|
-
line(`... (${contentLines.length - 10} more lines, ${contentLines.length} total)`, "dim")
|
|
25743
|
-
);
|
|
25744
|
-
}
|
|
25745
25751
|
const expandedLines2 = contentLines.map((value) => line(value));
|
|
25746
25752
|
if (isError && output) {
|
|
25747
|
-
collapsedLines.push(...splitLines(output, "error"));
|
|
25748
25753
|
expandedLines2.push(...splitLines(output, "error"));
|
|
25749
25754
|
}
|
|
25755
|
+
const collapsedLines = isError ? [line(`Write failed: ${compactOutputLine(output || "Unknown error")}`, "error")] : hasContent ? [
|
|
25756
|
+
line(
|
|
25757
|
+
contentLines.length === 0 ? `${running ? "Writing" : "Wrote"} empty file` : `${running ? "Writing" : "Wrote"} ${contentLines.length} ${contentLines.length === 1 ? "line" : "lines"}`,
|
|
25758
|
+
"dim"
|
|
25759
|
+
)
|
|
25760
|
+
] : [];
|
|
25750
25761
|
return {
|
|
25751
25762
|
header,
|
|
25752
|
-
collapsedLines
|
|
25763
|
+
collapsedLines,
|
|
25753
25764
|
expandedLines: contentLines.length ? [line(""), ...expandedLines2] : expandedLines2
|
|
25754
25765
|
};
|
|
25755
25766
|
}
|
|
@@ -25803,10 +25814,8 @@ function searchWarnings(name2, details) {
|
|
|
25803
25814
|
function searchPresentation(name2, args, output, details) {
|
|
25804
25815
|
const header = searchHeader(name2, args);
|
|
25805
25816
|
const lines = output.trim() ? output.trim().split("\n").map((value) => line(value)) : [];
|
|
25806
|
-
const
|
|
25807
|
-
const preview = lines.
|
|
25808
|
-
if (lines.length > max && max > 0)
|
|
25809
|
-
preview.push(line(`... (${lines.length - max} more lines)`, "dim"));
|
|
25817
|
+
const noun = name2 === "ls" ? lines.length === 1 ? "entry" : "entries" : name2 === "find" ? lines.length === 1 ? "result" : "results" : lines.length === 1 ? "match" : "matches";
|
|
25818
|
+
const preview = lines.length ? [line(`${lines.length} ${noun}`, "dim")] : [];
|
|
25810
25819
|
preview.push(...searchWarnings(name2, details));
|
|
25811
25820
|
return {
|
|
25812
25821
|
header,
|
|
@@ -25923,11 +25932,18 @@ function goalPresentation(args, output, details, isError) {
|
|
|
25923
25932
|
function genericPresentation(name2, args, output) {
|
|
25924
25933
|
const header = [part(name2, "title", true)];
|
|
25925
25934
|
const argsText = Object.keys(args).length ? safeJson(args, true) : "";
|
|
25926
|
-
const
|
|
25935
|
+
const expandedLines = [
|
|
25927
25936
|
...argsText ? [line(""), ...splitLines(argsText)] : [],
|
|
25928
25937
|
...output ? splitLines(output) : []
|
|
25929
25938
|
];
|
|
25930
|
-
|
|
25939
|
+
const outputPreview = output.split("\n").map((value) => value.trim()).find(Boolean);
|
|
25940
|
+
const argumentPreview = primaryToolArgument(args, name2);
|
|
25941
|
+
const preview = outputPreview || argumentPreview;
|
|
25942
|
+
return {
|
|
25943
|
+
header,
|
|
25944
|
+
collapsedLines: preview ? [line(` ${compactOutputLine(preview)}`, "dim")] : [],
|
|
25945
|
+
expandedLines
|
|
25946
|
+
};
|
|
25931
25947
|
}
|
|
25932
25948
|
function humanizeToolName(value) {
|
|
25933
25949
|
return value.replace(/[_-]+/g, " ").replace(/\b\w/g, (letter) => letter.toUpperCase()).trim();
|
|
@@ -25972,7 +25988,7 @@ function buildToolDisplay({
|
|
|
25972
25988
|
case "read":
|
|
25973
25989
|
case "write":
|
|
25974
25990
|
case "edit":
|
|
25975
|
-
presentation = filePresentation(name2, args, output, details, isError);
|
|
25991
|
+
presentation = filePresentation(name2, args, output, details, isError, running);
|
|
25976
25992
|
break;
|
|
25977
25993
|
case "ls":
|
|
25978
25994
|
case "find":
|
|
@@ -26124,6 +26140,7 @@ function buildToolDisplay({
|
|
|
26124
26140
|
isError,
|
|
26125
26141
|
title: titleText(presentation.header),
|
|
26126
26142
|
...presentation,
|
|
26143
|
+
collapsedLines: capCollapsedLines(presentation.collapsedLines),
|
|
26127
26144
|
images: messageImages(result)
|
|
26128
26145
|
};
|
|
26129
26146
|
}
|
|
@@ -26406,13 +26423,27 @@ function EmptyConversation({
|
|
|
26406
26423
|
] })
|
|
26407
26424
|
] });
|
|
26408
26425
|
}
|
|
26409
|
-
function
|
|
26410
|
-
return payload && typeof payload === "object"
|
|
26426
|
+
function payloadRecord(payload) {
|
|
26427
|
+
return payload !== null && typeof payload === "object" && !Array.isArray(payload) ? payload : {};
|
|
26428
|
+
}
|
|
26429
|
+
function payloadText(payload, key) {
|
|
26430
|
+
const value = payload[key];
|
|
26431
|
+
return typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
26411
26432
|
}
|
|
26412
|
-
function
|
|
26413
|
-
|
|
26414
|
-
const
|
|
26415
|
-
|
|
26433
|
+
function approvalDetails(rawPayload) {
|
|
26434
|
+
const payload = payloadRecord(rawPayload);
|
|
26435
|
+
const details = ["description", "reason", "summary", "path", "command", "query", "documentPath"].map((key) => payloadText(payload, key)).filter((detail) => Boolean(detail));
|
|
26436
|
+
for (const key of ["highRiskOperations", "operations"]) {
|
|
26437
|
+
const operations = payload[key];
|
|
26438
|
+
if (!Array.isArray(operations)) continue;
|
|
26439
|
+
for (const operation of operations) {
|
|
26440
|
+
const values = payloadRecord(operation);
|
|
26441
|
+
const label2 = payloadText(values, "label");
|
|
26442
|
+
const reason = payloadText(values, "reason");
|
|
26443
|
+
if (reason) details.push(`${label2 ? `${label2}: ` : ""}${reason}`);
|
|
26444
|
+
}
|
|
26445
|
+
}
|
|
26446
|
+
return [...new Set(details)];
|
|
26416
26447
|
}
|
|
26417
26448
|
function InteractionPanel({
|
|
26418
26449
|
interaction,
|
|
@@ -26422,13 +26453,13 @@ function InteractionPanel({
|
|
|
26422
26453
|
const [input, setInput] = reactExports.useState("");
|
|
26423
26454
|
if (interaction.kind === "approval") {
|
|
26424
26455
|
const request = interaction.approval.request;
|
|
26425
|
-
const
|
|
26456
|
+
const details = approvalDetails(request.payload);
|
|
26426
26457
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("section", { className: "interaction-panel approval-panel", children: [
|
|
26427
26458
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "interaction-heading", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
26428
26459
|
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: request.title }),
|
|
26429
26460
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: request.kind })
|
|
26430
26461
|
] }) }),
|
|
26431
|
-
|
|
26462
|
+
details.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "interaction-details", children: details.map((detail) => /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "interaction-detail", children: detail }, detail)) }),
|
|
26432
26463
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "interaction-actions", children: request.choices.map((choice, index2) => /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
26433
26464
|
"button",
|
|
26434
26465
|
{
|
|
@@ -27989,6 +28020,8 @@ function useAgentHost() {
|
|
|
27989
28020
|
const [restartKey, setRestartKey] = reactExports.useState(0);
|
|
27990
28021
|
const hostIdRef = reactExports.useRef(void 0);
|
|
27991
28022
|
const hostsRef = reactExports.useRef(state.hosts);
|
|
28023
|
+
const hostRuntimeArgsRef = reactExports.useRef(/* @__PURE__ */ new Map());
|
|
28024
|
+
const startHostRef = reactExports.useRef(void 0);
|
|
27992
28025
|
hostsRef.current = state.hosts;
|
|
27993
28026
|
const activeView = state.activeHostId ? state.hosts[state.activeHostId] : void 0;
|
|
27994
28027
|
const connection = state.status === "ready" && state.activeHostId && activeView ? { status: "ready", hostId: state.activeHostId, view: activeView } : state.status === "failed" ? { status: "failed", message: state.message ?? "Agent runtime stopped" } : { status: "starting" };
|
|
@@ -28001,6 +28034,7 @@ function useAgentHost() {
|
|
|
28001
28034
|
if (!active) return;
|
|
28002
28035
|
if ("termination" in payload) {
|
|
28003
28036
|
hostIds.delete(payload.hostId);
|
|
28037
|
+
hostRuntimeArgsRef.current.delete(payload.hostId);
|
|
28004
28038
|
if (hostIdRef.current === payload.hostId) {
|
|
28005
28039
|
hostIdRef.current = [...hostIds].at(-1);
|
|
28006
28040
|
}
|
|
@@ -28022,25 +28056,34 @@ function useAgentHost() {
|
|
|
28022
28056
|
return;
|
|
28023
28057
|
}
|
|
28024
28058
|
hostIds.add(result.hostId);
|
|
28059
|
+
hostRuntimeArgsRef.current.set(result.hostId, [...runtimeArgs ?? []]);
|
|
28025
28060
|
hostIdRef.current = result.hostId;
|
|
28026
28061
|
dispatch({ type: "ready", ...result });
|
|
28027
28062
|
} catch (error) {
|
|
28028
28063
|
if (active && requestGeneration === generation) {
|
|
28029
28064
|
dispatch({ type: "failed", message: String(error) });
|
|
28030
28065
|
}
|
|
28066
|
+
throw error;
|
|
28031
28067
|
}
|
|
28032
28068
|
};
|
|
28069
|
+
startHostRef.current = start;
|
|
28033
28070
|
const unsubscribeWorkspace = window.shortcut.agent.onOpenWorkspace(({ cwd: cwd2, runtimeArgs }) => {
|
|
28034
|
-
void start(cwd2, runtimeArgs)
|
|
28071
|
+
void start(cwd2, runtimeArgs).catch(() => {
|
|
28072
|
+
});
|
|
28073
|
+
});
|
|
28074
|
+
void start().catch(() => {
|
|
28035
28075
|
});
|
|
28036
|
-
void start();
|
|
28037
28076
|
return () => {
|
|
28038
28077
|
active = false;
|
|
28039
28078
|
generation += 1;
|
|
28040
28079
|
unsubscribe();
|
|
28041
28080
|
unsubscribeWorkspace();
|
|
28081
|
+
if (startHostRef.current === start) startHostRef.current = void 0;
|
|
28042
28082
|
hostIdRef.current = void 0;
|
|
28043
|
-
for (const hostId of hostIds)
|
|
28083
|
+
for (const hostId of hostIds) {
|
|
28084
|
+
hostRuntimeArgsRef.current.delete(hostId);
|
|
28085
|
+
void window.shortcut.agent.stop({ hostId });
|
|
28086
|
+
}
|
|
28044
28087
|
hostIds.clear();
|
|
28045
28088
|
};
|
|
28046
28089
|
}, [restartKey]);
|
|
@@ -28072,6 +28115,13 @@ function useAgentHost() {
|
|
|
28072
28115
|
[request]
|
|
28073
28116
|
);
|
|
28074
28117
|
const newSession = reactExports.useCallback(async () => {
|
|
28118
|
+
const hostId = hostIdRef.current;
|
|
28119
|
+
const startHost = startHostRef.current;
|
|
28120
|
+
const currentView = hostId ? hostsRef.current[hostId] : void 0;
|
|
28121
|
+
if (!hostId || !startHost || !currentView) throw new Error("Agent runtime is not ready");
|
|
28122
|
+
await startHost(currentView.snapshot.session.cwd, hostRuntimeArgsRef.current.get(hostId) ?? []);
|
|
28123
|
+
}, []);
|
|
28124
|
+
const replaceSession = reactExports.useCallback(async () => {
|
|
28075
28125
|
const result = await request({ type: "new_session" });
|
|
28076
28126
|
if (!result.cancelled) await refreshSnapshot();
|
|
28077
28127
|
}, [refreshSnapshot, request]);
|
|
@@ -28242,6 +28292,7 @@ function useAgentHost() {
|
|
|
28242
28292
|
abort,
|
|
28243
28293
|
respondToInteraction,
|
|
28244
28294
|
newSession,
|
|
28295
|
+
replaceSession,
|
|
28245
28296
|
listSessions,
|
|
28246
28297
|
deleteSession,
|
|
28247
28298
|
switchSession,
|
|
@@ -28350,7 +28401,7 @@ function App({ initialThemeId: initialThemeId2 }) {
|
|
|
28350
28401
|
const newestNotice = view?.notices.at(-1);
|
|
28351
28402
|
const latestNotice = newestNotice?.id === dismissedNoticeId ? void 0 : newestNotice;
|
|
28352
28403
|
const activeInteraction = view?.pendingInteractions[0];
|
|
28353
|
-
const canStartNewChat = Boolean(ready
|
|
28404
|
+
const canStartNewChat = Boolean(ready);
|
|
28354
28405
|
const liveSessions = agent.hosts.map(({ hostId, view: hostView }) => ({
|
|
28355
28406
|
hostId,
|
|
28356
28407
|
sessionId: hostView.snapshot.session.id,
|
|
@@ -28374,7 +28425,7 @@ function App({ initialThemeId: initialThemeId2 }) {
|
|
|
28374
28425
|
return run(async () => {
|
|
28375
28426
|
const activePath = view.snapshot.session.path;
|
|
28376
28427
|
if (activePath && paths.includes(activePath)) {
|
|
28377
|
-
await agent.
|
|
28428
|
+
await agent.replaceSession();
|
|
28378
28429
|
await agent.deleteSession(activePath);
|
|
28379
28430
|
}
|
|
28380
28431
|
for (const path2 of paths) {
|
|
@@ -772,13 +772,13 @@ button:not(:disabled):active {
|
|
|
772
772
|
gap: 16px;
|
|
773
773
|
}
|
|
774
774
|
|
|
775
|
-
.runtime-dashboard > section > header h2,
|
|
776
|
-
.command-reference > header h2 {
|
|
777
|
-
font-family: var(--font-terminal);
|
|
778
|
-
font-size: var(--terminal-text-size);
|
|
779
|
-
font-weight: 700;
|
|
780
|
-
letter-spacing: 0.06em;
|
|
781
|
-
text-transform: uppercase;
|
|
775
|
+
.runtime-dashboard > section > header h2,
|
|
776
|
+
.command-reference > header h2 {
|
|
777
|
+
font-family: var(--font-terminal);
|
|
778
|
+
font-size: var(--terminal-text-size);
|
|
779
|
+
font-weight: 700;
|
|
780
|
+
letter-spacing: 0.06em;
|
|
781
|
+
text-transform: uppercase;
|
|
782
782
|
}
|
|
783
783
|
|
|
784
784
|
.runtime-dashboard h2 {
|
|
@@ -807,12 +807,12 @@ button:not(:disabled):active {
|
|
|
807
807
|
padding: 0 8px;
|
|
808
808
|
border: 0;
|
|
809
809
|
border-bottom: 1px solid var(--line);
|
|
810
|
-
border-radius: 0;
|
|
811
|
-
color: var(--quiet);
|
|
812
|
-
background: transparent;
|
|
813
|
-
font-size: var(--terminal-text-size);
|
|
814
|
-
text-align: left;
|
|
815
|
-
}
|
|
810
|
+
border-radius: 0;
|
|
811
|
+
color: var(--quiet);
|
|
812
|
+
background: transparent;
|
|
813
|
+
font-size: var(--terminal-text-size);
|
|
814
|
+
text-align: left;
|
|
815
|
+
}
|
|
816
816
|
|
|
817
817
|
.environment-list > button,
|
|
818
818
|
.command-reference button {
|
|
@@ -821,12 +821,12 @@ button:not(:disabled):active {
|
|
|
821
821
|
|
|
822
822
|
.environment-list code,
|
|
823
823
|
.command-reference code {
|
|
824
|
-
width: 88px;
|
|
825
|
-
flex: 0 0 88px;
|
|
826
|
-
color: var(--ink-soft);
|
|
827
|
-
font-size: inherit;
|
|
828
|
-
font-weight: 620;
|
|
829
|
-
}
|
|
824
|
+
width: 88px;
|
|
825
|
+
flex: 0 0 88px;
|
|
826
|
+
color: var(--ink-soft);
|
|
827
|
+
font-size: inherit;
|
|
828
|
+
font-weight: 620;
|
|
829
|
+
}
|
|
830
830
|
|
|
831
831
|
.environment-list span,
|
|
832
832
|
.command-reference button span {
|
|
@@ -1817,6 +1817,7 @@ button:not(:disabled):active {
|
|
|
1817
1817
|
}
|
|
1818
1818
|
|
|
1819
1819
|
.interaction-panel {
|
|
1820
|
+
min-width: 0;
|
|
1820
1821
|
padding: 14px;
|
|
1821
1822
|
border: 1px solid var(--line-strong);
|
|
1822
1823
|
border-bottom: 0;
|
|
@@ -1832,9 +1833,15 @@ button:not(:disabled):active {
|
|
|
1832
1833
|
|
|
1833
1834
|
.interaction-heading > div {
|
|
1834
1835
|
display: grid;
|
|
1836
|
+
min-width: 0;
|
|
1835
1837
|
gap: 2px;
|
|
1836
1838
|
}
|
|
1837
1839
|
|
|
1840
|
+
.interaction-heading strong,
|
|
1841
|
+
.interaction-panel > p {
|
|
1842
|
+
overflow-wrap: anywhere;
|
|
1843
|
+
}
|
|
1844
|
+
|
|
1838
1845
|
.interaction-heading strong {
|
|
1839
1846
|
color: var(--ink-soft);
|
|
1840
1847
|
font-size: 0.75rem;
|
|
@@ -1846,19 +1853,22 @@ button:not(:disabled):active {
|
|
|
1846
1853
|
font-size: 0.625rem;
|
|
1847
1854
|
}
|
|
1848
1855
|
|
|
1849
|
-
.interaction-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
}
|
|
1855
|
-
|
|
1856
|
-
.interaction-panel .interaction-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1856
|
+
.interaction-details {
|
|
1857
|
+
display: grid;
|
|
1858
|
+
min-width: 0;
|
|
1859
|
+
margin: 12px 0;
|
|
1860
|
+
gap: 6px;
|
|
1861
|
+
}
|
|
1862
|
+
|
|
1863
|
+
.interaction-panel .interaction-detail {
|
|
1864
|
+
min-width: 0;
|
|
1865
|
+
margin: 0;
|
|
1866
|
+
color: var(--ink-soft);
|
|
1867
|
+
font-size: var(--terminal-footer-size);
|
|
1868
|
+
line-height: 1.5;
|
|
1869
|
+
overflow-wrap: anywhere;
|
|
1870
|
+
white-space: pre-wrap;
|
|
1871
|
+
}
|
|
1862
1872
|
|
|
1863
1873
|
.interaction-actions {
|
|
1864
1874
|
justify-content: flex-end;
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>Shortcut CLI</title>
|
|
7
|
-
<script type="module" crossorigin src="./assets/index-
|
|
8
|
-
<link rel="stylesheet" crossorigin href="./assets/index-
|
|
7
|
+
<script type="module" crossorigin src="./assets/index-Fluj0X8h.js"></script>
|
|
8
|
+
<link rel="stylesheet" crossorigin href="./assets/index-OhGE0UY4.css">
|
|
9
9
|
</head>
|
|
10
10
|
<body>
|
|
11
11
|
<div id="root"></div>
|
package/package.json
CHANGED
|
Binary file
|