@awak-app/simy-cli 0.5.18 → 0.5.20
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/package.json +1 -1
- package/src/agent.js +2 -0
- package/src/cli-contract.js +1 -1
- package/src/desktop-host.js +6 -0
- package/src/desktop-status.js +37 -0
package/package.json
CHANGED
package/src/agent.js
CHANGED
|
@@ -53,6 +53,7 @@ import {
|
|
|
53
53
|
createConnectionStatusTracker,
|
|
54
54
|
desktopAuthStatus,
|
|
55
55
|
desktopTaskStatus,
|
|
56
|
+
desktopTaskDetail,
|
|
56
57
|
} from "./desktop-status.js";
|
|
57
58
|
import { recoveryContractForPreflight } from "./orchestrator/recovery.js";
|
|
58
59
|
import {
|
|
@@ -1661,6 +1662,7 @@ export async function startAgent({
|
|
|
1661
1662
|
},
|
|
1662
1663
|
requestDesktopLogin,
|
|
1663
1664
|
getDesktopStatus,
|
|
1665
|
+
getDesktopTask: (key) => desktopTaskDetail([registry, directRegistry, localTaskRegistry], key),
|
|
1664
1666
|
async refreshDesktopStatus() {
|
|
1665
1667
|
if (isSessionValid(session, Date.now(), apiOrigin)) {
|
|
1666
1668
|
await heartbeat().catch((error) => reportHeartbeatError(error, quiet));
|
package/src/cli-contract.js
CHANGED
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
} from "./durable-local-task-steps-contract.js";
|
|
14
14
|
import { buildExecutionCapabilityContract } from "./execution-capability-contract.js";
|
|
15
15
|
|
|
16
|
-
export const CLI_VERSION = "0.5.
|
|
16
|
+
export const CLI_VERSION = "0.5.20";
|
|
17
17
|
export const CLI_API_CONTRACT_VERSION = 10;
|
|
18
18
|
|
|
19
19
|
export function withCliContract(
|
package/src/desktop-host.js
CHANGED
|
@@ -144,6 +144,12 @@ export async function startDesktopHost({ input = process.stdin, output = process
|
|
|
144
144
|
queue = queue.then(async () => {
|
|
145
145
|
try {
|
|
146
146
|
const action = command.action;
|
|
147
|
+
if (action === "task_detail") {
|
|
148
|
+
const task = await agent.getDesktopTask?.(command.taskKey);
|
|
149
|
+
emit({ type: "task_detail", id: command.id, taskKey: command.taskKey, task: task ?? null });
|
|
150
|
+
emit({ type: "result", id: command.id, ok: Boolean(task) });
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
147
153
|
if (action === "refresh" || action === "reconnect") {
|
|
148
154
|
await agent.refreshCodexStatus?.();
|
|
149
155
|
await agent.refreshDesktopStatus();
|
package/src/desktop-status.js
CHANGED
|
@@ -83,6 +83,42 @@ export function desktopTaskStatus(registries, { maxItems = MAX_STATUS_ITEMS } =
|
|
|
83
83
|
};
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
+
// Detail is sent only on selection, never in the periodic metadata broadcast.
|
|
87
|
+
export function desktopTaskDetail(registries, key) {
|
|
88
|
+
if (typeof key !== "string" || key.length > 256) return null;
|
|
89
|
+
const match = /^(\d+):(.+)$/.exec(key);
|
|
90
|
+
if (!match) return null;
|
|
91
|
+
const registryIndex = Number(match[1]);
|
|
92
|
+
const task = registries[registryIndex]?.list?.().find((item) => item.id === match[2]);
|
|
93
|
+
if (!task) return null;
|
|
94
|
+
const attempt = task.snapshot?.attempts?.at(-1);
|
|
95
|
+
const request = task.request?.requirement || task.instruction || task.snapshot?.charter?.requirement;
|
|
96
|
+
const result = typeof task.result === "string" ? task.result : task.result?.summary || attempt?.summary;
|
|
97
|
+
const links = [];
|
|
98
|
+
const pr = safeDesktopLink(attempt?.pr_url);
|
|
99
|
+
if (pr) links.push({ label: "Pull request", url: pr });
|
|
100
|
+
return {
|
|
101
|
+
key,
|
|
102
|
+
instruction: desktopContent(request),
|
|
103
|
+
result: desktopContent(result),
|
|
104
|
+
error: desktopContent(task.error, 1000),
|
|
105
|
+
truncated: [request, result].some((value) => typeof value === "string" && value.length > 16000),
|
|
106
|
+
links,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function desktopContent(value, limit = 16000) {
|
|
111
|
+
// Preserve paragraphs/Markdown, but never serialize runtime objects or logs.
|
|
112
|
+
return typeof value === "string" ? value.replace(/[\x00-\x08\x0b\x0c\x0e-\x1f]/g, "").slice(0, limit) : "";
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function safeDesktopLink(value) {
|
|
116
|
+
try {
|
|
117
|
+
const url = new URL(value);
|
|
118
|
+
return url.protocol === "https:" && !url.username && !url.password ? url.href : null;
|
|
119
|
+
} catch { return null; }
|
|
120
|
+
}
|
|
121
|
+
|
|
86
122
|
export function createCodexStatusInspector({
|
|
87
123
|
cacheMs = CODEX_STATUS_CACHE_MS,
|
|
88
124
|
inspect = inspectCodexStatus,
|
|
@@ -178,6 +214,7 @@ function taskStatusItem(task, registryIndex) {
|
|
|
178
214
|
48,
|
|
179
215
|
);
|
|
180
216
|
return {
|
|
217
|
+
key: `${registryIndex}:${bounded(task?.id || "", 240)}`,
|
|
181
218
|
id: bounded(String(task?.id || `unknown-${registryIndex}`), MAX_LABEL_LENGTH),
|
|
182
219
|
label: bounded(
|
|
183
220
|
String(
|