@agimon-ai/po-task 0.0.0-alpha.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/LICENSE +21 -0
- package/README.md +131 -0
- package/dist/apiContracts.cjs +54 -0
- package/dist/apiContracts.cjs.map +1 -0
- package/dist/apiContracts.d.mts +53 -0
- package/dist/apiContracts.d.mts.map +1 -0
- package/dist/apiContracts.mjs +49 -0
- package/dist/apiContracts.mjs.map +1 -0
- package/dist/config-CFSs3iku.mjs +72 -0
- package/dist/config-CFSs3iku.mjs.map +1 -0
- package/dist/config-CdX-Bv8q.cjs +173 -0
- package/dist/config-CdX-Bv8q.cjs.map +1 -0
- package/dist/config.cjs +19 -0
- package/dist/config.d.mts +2 -0
- package/dist/config.mjs +2 -0
- package/dist/delegation-BiOy3_7g.mjs +7 -0
- package/dist/delegation-BiOy3_7g.mjs.map +1 -0
- package/dist/delegation-CdMqOZB4.mjs +626 -0
- package/dist/delegation-CdMqOZB4.mjs.map +1 -0
- package/dist/delegation-DsnKjMbJ.cjs +661 -0
- package/dist/delegation-DsnKjMbJ.cjs.map +1 -0
- package/dist/delegation-LDpHP2CC.cjs +12 -0
- package/dist/delegation-LDpHP2CC.cjs.map +1 -0
- package/dist/delegationManager.cjs +10 -0
- package/dist/delegationManager.d.mts +2 -0
- package/dist/delegationManager.mjs +3 -0
- package/dist/extensions/mcp-ui.mjs +23 -0
- package/dist/extensions/mcp-ui.mjs.map +1 -0
- package/dist/extensions/mcp.cjs +1144 -0
- package/dist/extensions/mcp.cjs.map +1 -0
- package/dist/extensions/mcp.d.mts +5 -0
- package/dist/extensions/mcp.d.mts.map +1 -0
- package/dist/extensions/mcp.mjs +1115 -0
- package/dist/extensions/mcp.mjs.map +1 -0
- package/dist/extensions/native.mjs +1175 -0
- package/dist/extensions/native.mjs.map +1 -0
- package/dist/extensions/server.cjs +569 -0
- package/dist/extensions/server.cjs.map +1 -0
- package/dist/extensions/server.d.mts +5 -0
- package/dist/extensions/server.d.mts.map +1 -0
- package/dist/extensions/server.mjs +563 -0
- package/dist/extensions/server.mjs.map +1 -0
- package/dist/extensions/web.mjs +1018 -0
- package/dist/extensions/web.mjs.map +1 -0
- package/dist/index-B-3sCF2S.d.mts +43 -0
- package/dist/index-B-3sCF2S.d.mts.map +1 -0
- package/dist/index-B1JPJdpZ.d.mts +51 -0
- package/dist/index-B1JPJdpZ.d.mts.map +1 -0
- package/dist/index-CUWCvh-E.d.mts +72 -0
- package/dist/index-CUWCvh-E.d.mts.map +1 -0
- package/dist/index-DlmXKyhQ.d.mts +34 -0
- package/dist/index-DlmXKyhQ.d.mts.map +1 -0
- package/dist/index-Dvb8X_qB.d.mts +67 -0
- package/dist/index-Dvb8X_qB.d.mts.map +1 -0
- package/dist/index-XY9VPmfm.d.mts +26 -0
- package/dist/index-XY9VPmfm.d.mts.map +1 -0
- package/dist/index-teIf67qQ.d.mts +196 -0
- package/dist/index-teIf67qQ.d.mts.map +1 -0
- package/dist/index.cjs +93 -0
- package/dist/index.d.mts +11 -0
- package/dist/index.mjs +12 -0
- package/dist/invariants-DhjEjBPU.cjs +79 -0
- package/dist/invariants-DhjEjBPU.cjs.map +1 -0
- package/dist/invariants-q_UamF7D.mjs +62 -0
- package/dist/invariants-q_UamF7D.mjs.map +1 -0
- package/dist/logSinkTelemetry-B23qGiP-.cjs +52 -0
- package/dist/logSinkTelemetry-B23qGiP-.cjs.map +1 -0
- package/dist/logSinkTelemetry-BMBsC54p.mjs +41 -0
- package/dist/logSinkTelemetry-BMBsC54p.mjs.map +1 -0
- package/dist/logSinkTelemetry.cjs +6 -0
- package/dist/logSinkTelemetry.d.mts +23 -0
- package/dist/logSinkTelemetry.d.mts.map +1 -0
- package/dist/logSinkTelemetry.mjs +3 -0
- package/dist/paths-CSya2l9_.cjs +308 -0
- package/dist/paths-CSya2l9_.cjs.map +1 -0
- package/dist/paths-Cah1vFGv.mjs +207 -0
- package/dist/paths-Cah1vFGv.mjs.map +1 -0
- package/dist/processLiveness-Ccd9wenT.mjs +20 -0
- package/dist/processLiveness-Ccd9wenT.mjs.map +1 -0
- package/dist/processLiveness-umpNgsPR.cjs +25 -0
- package/dist/processLiveness-umpNgsPR.cjs.map +1 -0
- package/dist/reconcile-BcD-hTbd.mjs +63 -0
- package/dist/reconcile-BcD-hTbd.mjs.map +1 -0
- package/dist/reconcile-cRL0NjDr.cjs +80 -0
- package/dist/reconcile-cRL0NjDr.cjs.map +1 -0
- package/dist/reducer-BEfJFM5L.mjs +345 -0
- package/dist/reducer-BEfJFM5L.mjs.map +1 -0
- package/dist/reducer-BV0YIZ2o.cjs +380 -0
- package/dist/reducer-BV0YIZ2o.cjs.map +1 -0
- package/dist/storeInvariants.cjs +5 -0
- package/dist/storeInvariants.d.mts +23 -0
- package/dist/storeInvariants.d.mts.map +1 -0
- package/dist/storeInvariants.mjs +2 -0
- package/dist/storePaths.cjs +14 -0
- package/dist/storePaths.d.mts +2 -0
- package/dist/storePaths.mjs +2 -0
- package/dist/storeProcessLiveness.cjs +3 -0
- package/dist/storeProcessLiveness.d.mts +11 -0
- package/dist/storeProcessLiveness.d.mts.map +1 -0
- package/dist/storeProcessLiveness.mjs +2 -0
- package/dist/storeReconcile.cjs +5 -0
- package/dist/storeReconcile.d.mts +2 -0
- package/dist/storeReconcile.mjs +2 -0
- package/dist/storeReducer.cjs +8 -0
- package/dist/storeReducer.d.mts +2 -0
- package/dist/storeReducer.mjs +2 -0
- package/dist/storeTaskGraph.cjs +7 -0
- package/dist/storeTaskGraph.d.mts +2 -0
- package/dist/storeTaskGraph.mjs +2 -0
- package/dist/storeTaskStore.cjs +3 -0
- package/dist/storeTaskStore.d.mts +2 -0
- package/dist/storeTaskStore.mjs +2 -0
- package/dist/storeTypes.cjs +6 -0
- package/dist/storeTypes.d.mts +2 -0
- package/dist/storeTypes.mjs +2 -0
- package/dist/task-CXF9VULl.cjs +49 -0
- package/dist/task-CXF9VULl.cjs.map +1 -0
- package/dist/task-DJpTteeJ.d.mts +187 -0
- package/dist/task-DJpTteeJ.d.mts.map +1 -0
- package/dist/task-DO0TwZ0z.mjs +132 -0
- package/dist/task-DO0TwZ0z.mjs.map +1 -0
- package/dist/task-Dhta7JyA.d.mts +126 -0
- package/dist/task-Dhta7JyA.d.mts.map +1 -0
- package/dist/task-UvW877Ez.cjs +227 -0
- package/dist/task-UvW877Ez.cjs.map +1 -0
- package/dist/task-giCbpKzV.mjs +26 -0
- package/dist/task-giCbpKzV.mjs.map +1 -0
- package/dist/taskGraph-BOQvT0-M.mjs +63 -0
- package/dist/taskGraph-BOQvT0-M.mjs.map +1 -0
- package/dist/taskGraph-BskRslrr.cjs +92 -0
- package/dist/taskGraph-BskRslrr.cjs.map +1 -0
- package/dist/taskGraph-D0zFHF2p.d.mts +25 -0
- package/dist/taskGraph-D0zFHF2p.d.mts.map +1 -0
- package/dist/taskResult-D2G7b4w-.cjs +224 -0
- package/dist/taskResult-D2G7b4w-.cjs.map +1 -0
- package/dist/taskResult-edBAAKSH.mjs +165 -0
- package/dist/taskResult-edBAAKSH.mjs.map +1 -0
- package/dist/taskStore-DjU60rMm.cjs +215 -0
- package/dist/taskStore-DjU60rMm.cjs.map +1 -0
- package/dist/taskStore-pAJ971Ml.mjs +208 -0
- package/dist/taskStore-pAJ971Ml.mjs.map +1 -0
- package/dist/telemetry-Ca0I3Tqo.cjs +30 -0
- package/dist/telemetry-Ca0I3Tqo.cjs.map +1 -0
- package/dist/telemetry-DyS44zAD.mjs +25 -0
- package/dist/telemetry-DyS44zAD.mjs.map +1 -0
- package/dist/telemetry-FMGRovb4.d.mts +35 -0
- package/dist/telemetry-FMGRovb4.d.mts.map +1 -0
- package/dist/toolPromptGuidelines.cjs +27 -0
- package/dist/toolPromptGuidelines.cjs.map +1 -0
- package/dist/toolPromptGuidelines.d.mts +13 -0
- package/dist/toolPromptGuidelines.d.mts.map +1 -0
- package/dist/toolPromptGuidelines.mjs +26 -0
- package/dist/toolPromptGuidelines.mjs.map +1 -0
- package/dist/toolResponseEnvelope.cjs +12 -0
- package/dist/toolResponseEnvelope.d.mts +2 -0
- package/dist/toolResponseEnvelope.mjs +2 -0
- package/dist/toolSchema.cjs +18 -0
- package/dist/toolSchema.d.mts +2 -0
- package/dist/toolSchema.mjs +2 -0
- package/package.json +223 -0
- package/src/types/webTasks.ts +24 -0
|
@@ -0,0 +1,1175 @@
|
|
|
1
|
+
import { defineActivityGroup, defineChannelFile, defineFill, defineNativePlugin, defineSessionStore, defineToolRenderer } from "@agimon-ai/po-core/native";
|
|
2
|
+
import { Badge, Button, ChevronDownIcon, ChevronRightIcon, CodeBlock, Dot, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, EditIcon, Input, KebabIcon, Label, ListRow, MessageIcon, MessageItem, MessageItemBody, MessageItemHeader, MessageItemStatus, SegmentedControl, Sheet, SheetBody, SheetContent, SheetHeader, SheetTitle, StatusBadge, TaskIcon, Textarea, TrashIcon, toolTone } from "@agimon-ai/po-native-components";
|
|
3
|
+
import { createElement, useCallback, useState, useSyncExternalStore } from "react";
|
|
4
|
+
import { View } from "react-native-unistyles/components/native/View";
|
|
5
|
+
import { Text } from "react-native-unistyles/components/native/Text";
|
|
6
|
+
import { StyleSheet } from "react-native-unistyles";
|
|
7
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
8
|
+
//#region src/types/webTasks.ts
|
|
9
|
+
/** Browser-safe task view published by the cockpit hub channel. */
|
|
10
|
+
const TASKS_CHANNEL_TYPE = "task_graph";
|
|
11
|
+
//#endregion
|
|
12
|
+
//#region src/extensions/workspaces/sessions/(frontend)/channel/_lib/tasksModel.ts
|
|
13
|
+
function isRecord$1(value) {
|
|
14
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
15
|
+
}
|
|
16
|
+
function parseTask(value) {
|
|
17
|
+
if (!isRecord$1(value) || typeof value.id !== "number" || typeof value.subject !== "string") return null;
|
|
18
|
+
if (![
|
|
19
|
+
"pending",
|
|
20
|
+
"in_progress",
|
|
21
|
+
"completed",
|
|
22
|
+
"failed"
|
|
23
|
+
].includes(String(value.status))) return null;
|
|
24
|
+
const task = {
|
|
25
|
+
id: value.id,
|
|
26
|
+
subject: value.subject,
|
|
27
|
+
status: value.status,
|
|
28
|
+
blockedBy: Array.isArray(value.blockedBy) ? value.blockedBy.filter((id) => typeof id === "number") : []
|
|
29
|
+
};
|
|
30
|
+
if (typeof value.description === "string") task.description = value.description;
|
|
31
|
+
if (typeof value.activeForm === "string") task.activeForm = value.activeForm;
|
|
32
|
+
if (typeof value.owner === "string") task.owner = value.owner;
|
|
33
|
+
if (typeof value.updatedAt === "string") task.updatedAt = value.updatedAt;
|
|
34
|
+
if (isRecord$1(value.delegation)) {
|
|
35
|
+
task.delegation = {};
|
|
36
|
+
if (typeof value.delegation.agent === "string") task.delegation.agent = value.delegation.agent;
|
|
37
|
+
if (typeof value.delegation.state === "string") task.delegation.state = value.delegation.state;
|
|
38
|
+
}
|
|
39
|
+
return task;
|
|
40
|
+
}
|
|
41
|
+
/** Narrows a hub frame to a task graph payload; null when it is not one. */
|
|
42
|
+
function parseTasksPayload(input) {
|
|
43
|
+
if (!isRecord$1(input) || !Array.isArray(input.tasks) || typeof input.rev !== "number") return null;
|
|
44
|
+
return {
|
|
45
|
+
tasks: input.tasks.map(parseTask).filter((task) => task !== null),
|
|
46
|
+
rev: input.rev
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function taskEditDraft(task) {
|
|
50
|
+
return {
|
|
51
|
+
subject: task.subject,
|
|
52
|
+
description: task.description ?? "",
|
|
53
|
+
status: task.status
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function changedFields(task, draft) {
|
|
57
|
+
const changes = [];
|
|
58
|
+
const subject = draft.subject.trim();
|
|
59
|
+
const description = draft.description.trim();
|
|
60
|
+
if (subject && subject !== task.subject) changes.push(`set subject to "${subject}"`);
|
|
61
|
+
if (description !== (task.description ?? "").trim()) changes.push(description ? `set description to "${description}"` : "clear the description");
|
|
62
|
+
if (draft.status !== task.status) changes.push(`set status to ${draft.status}`);
|
|
63
|
+
return changes;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* The agent stays the only writer of task state, so an edit leaves the cockpit
|
|
67
|
+
* as one prompt naming exactly the fields the human changed. Nothing changed
|
|
68
|
+
* means nothing to send.
|
|
69
|
+
*/
|
|
70
|
+
function taskEditInstruction(task, draft) {
|
|
71
|
+
const changes = changedFields(task, draft);
|
|
72
|
+
if (changes.length === 0) return null;
|
|
73
|
+
return `Update task #${task.id}: ${changes.join("; ")}. Change nothing else and keep the dependency graph valid.`;
|
|
74
|
+
}
|
|
75
|
+
function requestTaskEdit(send, sessionId, task, draft) {
|
|
76
|
+
const message = taskEditInstruction(task, draft);
|
|
77
|
+
if (message === null) return false;
|
|
78
|
+
send(sessionId, {
|
|
79
|
+
type: "prompt",
|
|
80
|
+
message
|
|
81
|
+
});
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
/** Steering for the subagent that owns a delegated task. */
|
|
85
|
+
function taskMessageInstruction(taskId, agent, message) {
|
|
86
|
+
return `Steer the ${agent} run working on task #${taskId} with this message, then update the task if its plan changed: ${message.trim()}`;
|
|
87
|
+
}
|
|
88
|
+
function requestTaskMessage(send, sessionId, taskId, agent, message) {
|
|
89
|
+
send(sessionId, {
|
|
90
|
+
type: "prompt",
|
|
91
|
+
message: taskMessageInstruction(taskId, agent, message)
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
function requestTaskRemoval(send, sessionId, taskId) {
|
|
95
|
+
send(sessionId, {
|
|
96
|
+
type: "prompt",
|
|
97
|
+
message: `Remove task #${taskId}. Also remove or repair every dependency that references it so the remaining task graph is valid.`
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
//#endregion
|
|
101
|
+
//#region src/extensions/workspaces/sessions/(frontend)/channel/_lib/tasksStore.native.ts
|
|
102
|
+
/**
|
|
103
|
+
* The native copy of the task graph store. It mirrors tasksStore.ts with the
|
|
104
|
+
* native SDK, since the app provides `@agimon-ai/po-core/native` and never the
|
|
105
|
+
* web contract; the parsing and the edit prompts come from the same model.
|
|
106
|
+
*/
|
|
107
|
+
const tasks = defineSessionStore({
|
|
108
|
+
tasks: [],
|
|
109
|
+
rev: 0
|
|
110
|
+
});
|
|
111
|
+
const tasksChannel = tasks.channel({
|
|
112
|
+
channel: TASKS_CHANNEL_TYPE,
|
|
113
|
+
parse: parseTasksPayload,
|
|
114
|
+
reduce: (_current, payload) => payload
|
|
115
|
+
});
|
|
116
|
+
//#endregion
|
|
117
|
+
//#region src/extensions/workspaces/sessions/(frontend)/activity-group/tasks.native.ts
|
|
118
|
+
/**
|
|
119
|
+
* The live task board in the app's Activity list, matching tasks.web.ts.
|
|
120
|
+
*
|
|
121
|
+
* Active means a delegated run is still out, not that the list has entries: a
|
|
122
|
+
* pending task waits for this agent's next turn and reports to nobody.
|
|
123
|
+
*/
|
|
124
|
+
var tasks_native_default = defineActivityGroup({
|
|
125
|
+
keys: "t l",
|
|
126
|
+
icon: (_props) => createElement(TaskIcon),
|
|
127
|
+
statusKey: "@agimon-ai/po-task",
|
|
128
|
+
marksBackgroundWork: false,
|
|
129
|
+
activeSource: {
|
|
130
|
+
subscribe(listener) {
|
|
131
|
+
const subscription = tasks.store.subscribe(listener);
|
|
132
|
+
return () => subscription.unsubscribe();
|
|
133
|
+
},
|
|
134
|
+
isActive(sessionId) {
|
|
135
|
+
return tasks.select(tasks.store.state, sessionId).tasks.some((task) => task.delegation?.state === "requested" || task.delegation?.state === "running");
|
|
136
|
+
}
|
|
137
|
+
},
|
|
138
|
+
order: 65
|
|
139
|
+
});
|
|
140
|
+
//#endregion
|
|
141
|
+
//#region src/extensions/workspaces/sessions/(frontend)/channel/task-graph.native.ts
|
|
142
|
+
var task_graph_native_default = defineChannelFile(tasksChannel);
|
|
143
|
+
//#endregion
|
|
144
|
+
//#region src/extensions/workspaces/sessions/(frontend)/fill/_lib/TaskDetailSheet.native.tsx
|
|
145
|
+
const STATUS_CHOICES = [
|
|
146
|
+
"pending",
|
|
147
|
+
"in_progress",
|
|
148
|
+
"completed",
|
|
149
|
+
"failed"
|
|
150
|
+
];
|
|
151
|
+
const DESCRIPTION_LINES = 5;
|
|
152
|
+
const MESSAGE_LINES = 4;
|
|
153
|
+
function Field({ label, children }) {
|
|
154
|
+
return /* @__PURE__ */ jsxs(View, {
|
|
155
|
+
style: styles$2.field,
|
|
156
|
+
children: [/* @__PURE__ */ jsx(Label, { children: label }), children]
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
function ReadOnlyValue({ value, testID }) {
|
|
160
|
+
return /* @__PURE__ */ jsx(Text, {
|
|
161
|
+
testID,
|
|
162
|
+
style: styles$2.value,
|
|
163
|
+
children: value
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
function SheetAction({ label, variant, testID, onPress }) {
|
|
167
|
+
return /* @__PURE__ */ jsx(Button, {
|
|
168
|
+
testID,
|
|
169
|
+
variant,
|
|
170
|
+
onPress,
|
|
171
|
+
children: label
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
function TaskFacts({ task }) {
|
|
175
|
+
return /* @__PURE__ */ jsxs(View, {
|
|
176
|
+
style: styles$2.facts,
|
|
177
|
+
children: [
|
|
178
|
+
/* @__PURE__ */ jsx(Field, {
|
|
179
|
+
label: "Status",
|
|
180
|
+
children: /* @__PURE__ */ jsx(ReadOnlyValue, {
|
|
181
|
+
testID: "task-detail-status",
|
|
182
|
+
value: task.status.replace("_", " ")
|
|
183
|
+
})
|
|
184
|
+
}),
|
|
185
|
+
task.activeForm ? /* @__PURE__ */ jsx(Field, {
|
|
186
|
+
label: "Active form",
|
|
187
|
+
children: /* @__PURE__ */ jsx(ReadOnlyValue, {
|
|
188
|
+
testID: "task-detail-active-form",
|
|
189
|
+
value: task.activeForm
|
|
190
|
+
})
|
|
191
|
+
}) : null,
|
|
192
|
+
task.owner ? /* @__PURE__ */ jsx(Field, {
|
|
193
|
+
label: "Owner",
|
|
194
|
+
children: /* @__PURE__ */ jsx(ReadOnlyValue, {
|
|
195
|
+
testID: "task-detail-owner",
|
|
196
|
+
value: task.owner
|
|
197
|
+
})
|
|
198
|
+
}) : null,
|
|
199
|
+
task.delegation?.agent ? /* @__PURE__ */ jsx(Field, {
|
|
200
|
+
label: "Delegated to",
|
|
201
|
+
children: /* @__PURE__ */ jsx(ReadOnlyValue, {
|
|
202
|
+
testID: "task-detail-agent",
|
|
203
|
+
value: task.delegation.state ? `${task.delegation.agent} · ${task.delegation.state}` : task.delegation.agent
|
|
204
|
+
})
|
|
205
|
+
}) : null,
|
|
206
|
+
task.blockedBy.length > 0 ? /* @__PURE__ */ jsx(Field, {
|
|
207
|
+
label: "Blocked by",
|
|
208
|
+
children: /* @__PURE__ */ jsx(ReadOnlyValue, {
|
|
209
|
+
testID: "task-detail-blocked-by",
|
|
210
|
+
value: task.blockedBy.map((id) => `#${id}`).join(", ")
|
|
211
|
+
})
|
|
212
|
+
}) : null,
|
|
213
|
+
task.updatedAt ? /* @__PURE__ */ jsx(Field, {
|
|
214
|
+
label: "Updated",
|
|
215
|
+
children: /* @__PURE__ */ jsx(ReadOnlyValue, {
|
|
216
|
+
testID: "task-detail-updated",
|
|
217
|
+
value: task.updatedAt
|
|
218
|
+
})
|
|
219
|
+
}) : null
|
|
220
|
+
]
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* One task in a bottom sheet, read first and changed second, as the web
|
|
225
|
+
* dialog does. Every change leaves as a prompt the session can see, so the
|
|
226
|
+
* agent remains the only writer of task state.
|
|
227
|
+
*/
|
|
228
|
+
function TaskDetailSheet({ task, sessionId, mode: initialMode, send, onClose }) {
|
|
229
|
+
const [mode, setMode] = useState(initialMode);
|
|
230
|
+
const [draft, setDraft] = useState(() => taskEditDraft(task));
|
|
231
|
+
const [message, setMessage] = useState("");
|
|
232
|
+
const agent = task.delegation?.agent;
|
|
233
|
+
const submitEdit = () => {
|
|
234
|
+
if (requestTaskEdit(send, sessionId, task, draft)) onClose();
|
|
235
|
+
};
|
|
236
|
+
const submitMessage = () => {
|
|
237
|
+
if (!message.trim() || !agent) return;
|
|
238
|
+
requestTaskMessage(send, sessionId, task.id, agent, message);
|
|
239
|
+
onClose();
|
|
240
|
+
};
|
|
241
|
+
return /* @__PURE__ */ jsx(Sheet, {
|
|
242
|
+
open: true,
|
|
243
|
+
onOpenChange: (open) => {
|
|
244
|
+
if (!open) onClose();
|
|
245
|
+
},
|
|
246
|
+
children: /* @__PURE__ */ jsxs(SheetContent, { children: [/* @__PURE__ */ jsx(SheetHeader, {
|
|
247
|
+
closeLabel: "close task",
|
|
248
|
+
children: /* @__PURE__ */ jsx(SheetTitle, {
|
|
249
|
+
testID: "task-detail-title",
|
|
250
|
+
accessibilityLabel: `task #${task.id}: ${task.subject}`,
|
|
251
|
+
children: task.subject
|
|
252
|
+
})
|
|
253
|
+
}), /* @__PURE__ */ jsxs(SheetBody, {
|
|
254
|
+
testID: "task-detail-dialog",
|
|
255
|
+
children: [
|
|
256
|
+
mode === "view" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
257
|
+
/* @__PURE__ */ jsx(Field, {
|
|
258
|
+
label: "Description",
|
|
259
|
+
children: /* @__PURE__ */ jsx(ReadOnlyValue, {
|
|
260
|
+
testID: "task-detail-description",
|
|
261
|
+
value: task.description ?? "no description on this task"
|
|
262
|
+
})
|
|
263
|
+
}),
|
|
264
|
+
/* @__PURE__ */ jsx(TaskFacts, { task }),
|
|
265
|
+
/* @__PURE__ */ jsxs(View, {
|
|
266
|
+
style: styles$2.footer,
|
|
267
|
+
children: [agent ? /* @__PURE__ */ jsx(SheetAction, {
|
|
268
|
+
label: "message agent",
|
|
269
|
+
variant: "ghost",
|
|
270
|
+
testID: "task-detail-open-message",
|
|
271
|
+
onPress: () => setMode("message")
|
|
272
|
+
}) : null, /* @__PURE__ */ jsx(SheetAction, {
|
|
273
|
+
label: "edit",
|
|
274
|
+
variant: "primary",
|
|
275
|
+
testID: "task-detail-open-edit",
|
|
276
|
+
onPress: () => setMode("edit")
|
|
277
|
+
})]
|
|
278
|
+
})
|
|
279
|
+
] }) : null,
|
|
280
|
+
mode === "edit" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
281
|
+
/* @__PURE__ */ jsx(Field, {
|
|
282
|
+
label: "Subject",
|
|
283
|
+
children: /* @__PURE__ */ jsx(Input, {
|
|
284
|
+
testID: "task-detail-subject-input",
|
|
285
|
+
accessibilityLabel: "Subject",
|
|
286
|
+
autoFocus: true,
|
|
287
|
+
value: draft.subject,
|
|
288
|
+
onChangeText: (subject) => setDraft({
|
|
289
|
+
...draft,
|
|
290
|
+
subject
|
|
291
|
+
})
|
|
292
|
+
})
|
|
293
|
+
}),
|
|
294
|
+
/* @__PURE__ */ jsx(Field, {
|
|
295
|
+
label: "Description",
|
|
296
|
+
children: /* @__PURE__ */ jsx(Textarea, {
|
|
297
|
+
testID: "task-detail-description-input",
|
|
298
|
+
accessibilityLabel: "Description",
|
|
299
|
+
numberOfLines: DESCRIPTION_LINES,
|
|
300
|
+
value: draft.description,
|
|
301
|
+
placeholder: "what this task covers",
|
|
302
|
+
onChangeText: (description) => setDraft({
|
|
303
|
+
...draft,
|
|
304
|
+
description
|
|
305
|
+
})
|
|
306
|
+
})
|
|
307
|
+
}),
|
|
308
|
+
/* @__PURE__ */ jsx(Field, {
|
|
309
|
+
label: "Status",
|
|
310
|
+
children: /* @__PURE__ */ jsx(SegmentedControl, {
|
|
311
|
+
accessibilityLabel: "Status",
|
|
312
|
+
options: STATUS_CHOICES.map((status) => ({
|
|
313
|
+
value: status,
|
|
314
|
+
label: status.replace("_", " ")
|
|
315
|
+
})),
|
|
316
|
+
value: draft.status,
|
|
317
|
+
onValueChange: (status) => {
|
|
318
|
+
if (STATUS_CHOICES.includes(status)) setDraft({
|
|
319
|
+
...draft,
|
|
320
|
+
status
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
})
|
|
324
|
+
}),
|
|
325
|
+
/* @__PURE__ */ jsx(Text, {
|
|
326
|
+
style: styles$2.hint,
|
|
327
|
+
children: "saved as one prompt naming only the fields you changed"
|
|
328
|
+
}),
|
|
329
|
+
/* @__PURE__ */ jsxs(View, {
|
|
330
|
+
style: styles$2.footer,
|
|
331
|
+
children: [/* @__PURE__ */ jsx(SheetAction, {
|
|
332
|
+
label: "cancel",
|
|
333
|
+
variant: "ghost",
|
|
334
|
+
testID: "task-detail-cancel",
|
|
335
|
+
onPress: onClose
|
|
336
|
+
}), /* @__PURE__ */ jsx(SheetAction, {
|
|
337
|
+
label: "save",
|
|
338
|
+
variant: "primary",
|
|
339
|
+
testID: "task-detail-save",
|
|
340
|
+
onPress: submitEdit
|
|
341
|
+
})]
|
|
342
|
+
})
|
|
343
|
+
] }) : null,
|
|
344
|
+
mode === "message" && agent ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
345
|
+
/* @__PURE__ */ jsx(Field, {
|
|
346
|
+
label: `Message to ${agent}`,
|
|
347
|
+
children: /* @__PURE__ */ jsx(Textarea, {
|
|
348
|
+
testID: "task-detail-message-input",
|
|
349
|
+
accessibilityLabel: "Message to agent",
|
|
350
|
+
autoFocus: true,
|
|
351
|
+
numberOfLines: MESSAGE_LINES,
|
|
352
|
+
value: message,
|
|
353
|
+
placeholder: "guidance for the run working on this task",
|
|
354
|
+
onChangeText: setMessage
|
|
355
|
+
})
|
|
356
|
+
}),
|
|
357
|
+
/* @__PURE__ */ jsx(Text, {
|
|
358
|
+
style: styles$2.hint,
|
|
359
|
+
children: "steers the run, it does not edit the task"
|
|
360
|
+
}),
|
|
361
|
+
/* @__PURE__ */ jsxs(View, {
|
|
362
|
+
style: styles$2.footer,
|
|
363
|
+
children: [/* @__PURE__ */ jsx(SheetAction, {
|
|
364
|
+
label: "cancel",
|
|
365
|
+
variant: "ghost",
|
|
366
|
+
testID: "task-detail-cancel",
|
|
367
|
+
onPress: onClose
|
|
368
|
+
}), /* @__PURE__ */ jsx(SheetAction, {
|
|
369
|
+
label: "send",
|
|
370
|
+
variant: "primary",
|
|
371
|
+
testID: "task-detail-send",
|
|
372
|
+
onPress: submitMessage
|
|
373
|
+
})]
|
|
374
|
+
})
|
|
375
|
+
] }) : null
|
|
376
|
+
]
|
|
377
|
+
})] })
|
|
378
|
+
});
|
|
379
|
+
}
|
|
380
|
+
const styles$2 = StyleSheet.create((theme) => ({
|
|
381
|
+
field: {
|
|
382
|
+
gap: theme.spacing(1.5),
|
|
383
|
+
uni__dependencies: [0]
|
|
384
|
+
},
|
|
385
|
+
facts: {
|
|
386
|
+
flexDirection: "row",
|
|
387
|
+
flexWrap: "wrap",
|
|
388
|
+
gap: theme.spacing(5),
|
|
389
|
+
uni__dependencies: [0]
|
|
390
|
+
},
|
|
391
|
+
value: {
|
|
392
|
+
fontSize: theme.fontSize.base,
|
|
393
|
+
lineHeight: theme.lineHeight.lg,
|
|
394
|
+
color: theme.colors.dim,
|
|
395
|
+
uni__dependencies: [0]
|
|
396
|
+
},
|
|
397
|
+
hint: {
|
|
398
|
+
fontSize: theme.fontSize.sm,
|
|
399
|
+
lineHeight: theme.lineHeight.sm,
|
|
400
|
+
color: theme.colors.dim,
|
|
401
|
+
uni__dependencies: [0]
|
|
402
|
+
},
|
|
403
|
+
footer: {
|
|
404
|
+
flexDirection: "row",
|
|
405
|
+
justifyContent: "flex-end",
|
|
406
|
+
gap: theme.spacing(2),
|
|
407
|
+
uni__dependencies: [0]
|
|
408
|
+
}
|
|
409
|
+
}));
|
|
410
|
+
//#endregion
|
|
411
|
+
//#region src/extensions/workspaces/sessions/(frontend)/fill/_lib/taskStatusTone.ts
|
|
412
|
+
const TASK_STATUS_TONE = {
|
|
413
|
+
pending: "muted",
|
|
414
|
+
in_progress: "yellow",
|
|
415
|
+
completed: "green",
|
|
416
|
+
failed: "red",
|
|
417
|
+
deleted: "muted"
|
|
418
|
+
};
|
|
419
|
+
//#endregion
|
|
420
|
+
//#region src/extensions/workspaces/sessions/(frontend)/fill/_lib/TasksActivitySection.native.tsx
|
|
421
|
+
function titleInk(status) {
|
|
422
|
+
if (status === "failed") return "red";
|
|
423
|
+
return status === "completed" ? "dim" : "hi";
|
|
424
|
+
}
|
|
425
|
+
/** The session's tasks, read from the native store without @tanstack/react-store, which the app does not provide. */
|
|
426
|
+
function useSessionTasks(sessionId) {
|
|
427
|
+
const subscribe = useCallback((listener) => {
|
|
428
|
+
const subscription = tasks.store.subscribe(listener);
|
|
429
|
+
return () => subscription.unsubscribe();
|
|
430
|
+
}, []);
|
|
431
|
+
return useSyncExternalStore(subscribe, () => tasks.select(tasks.store.state, sessionId).tasks);
|
|
432
|
+
}
|
|
433
|
+
function TaskRow({ task, sessionId, sendSessionFrame, openSheet }) {
|
|
434
|
+
const detail = task.status === "in_progress" ? task.activeForm : task.description;
|
|
435
|
+
const agent = task.delegation?.agent;
|
|
436
|
+
return /* @__PURE__ */ jsx(View, {
|
|
437
|
+
testID: `activity-task-${task.id}`,
|
|
438
|
+
children: /* @__PURE__ */ jsx(ListRow, {
|
|
439
|
+
leading: /* @__PURE__ */ jsx(Dot, {
|
|
440
|
+
tone: TASK_STATUS_TONE[task.status],
|
|
441
|
+
pulse: task.status === "in_progress"
|
|
442
|
+
}),
|
|
443
|
+
title: /* @__PURE__ */ jsx(Button, {
|
|
444
|
+
variant: "ghost",
|
|
445
|
+
testID: `activity-task-title-${task.id}`,
|
|
446
|
+
accessibilityLabel: task.subject,
|
|
447
|
+
onPress: () => openSheet("view"),
|
|
448
|
+
children: /* @__PURE__ */ jsxs(Text, {
|
|
449
|
+
numberOfLines: 1,
|
|
450
|
+
style: styles$1.title(titleInk(task.status)),
|
|
451
|
+
children: [
|
|
452
|
+
"#",
|
|
453
|
+
task.id,
|
|
454
|
+
" ",
|
|
455
|
+
task.subject
|
|
456
|
+
]
|
|
457
|
+
})
|
|
458
|
+
}),
|
|
459
|
+
description: detail || agent || task.blockedBy.length > 0 ? /* @__PURE__ */ jsxs(Text, {
|
|
460
|
+
numberOfLines: 1,
|
|
461
|
+
style: styles$1.meta,
|
|
462
|
+
children: [
|
|
463
|
+
agent ? `[${agent}] ` : "",
|
|
464
|
+
detail ?? "",
|
|
465
|
+
task.blockedBy.length > 0 ? ` · blocked by ${task.blockedBy.map((id) => `#${id}`).join(", ")}` : ""
|
|
466
|
+
]
|
|
467
|
+
}) : void 0,
|
|
468
|
+
trailing: /* @__PURE__ */ jsxs(View, {
|
|
469
|
+
style: styles$1.line,
|
|
470
|
+
children: [/* @__PURE__ */ jsx(Text, {
|
|
471
|
+
style: styles$1.meta,
|
|
472
|
+
children: task.status.replace("_", " ")
|
|
473
|
+
}), task.status !== "completed" && task.status !== "deleted" ? /* @__PURE__ */ jsxs(DropdownMenu, { children: [/* @__PURE__ */ jsx(DropdownMenuTrigger, {
|
|
474
|
+
variant: "ghost",
|
|
475
|
+
size: "icon",
|
|
476
|
+
testID: `activity-task-menu-${task.id}`,
|
|
477
|
+
accessibilityLabel: `task #${task.id} actions`,
|
|
478
|
+
children: /* @__PURE__ */ jsx(KebabIcon, {})
|
|
479
|
+
}), /* @__PURE__ */ jsxs(DropdownMenuContent, { children: [
|
|
480
|
+
/* @__PURE__ */ jsxs(DropdownMenuItem, {
|
|
481
|
+
onSelect: () => openSheet("edit"),
|
|
482
|
+
children: [/* @__PURE__ */ jsx(EditIcon, {}), "Edit"]
|
|
483
|
+
}),
|
|
484
|
+
agent ? /* @__PURE__ */ jsxs(DropdownMenuItem, {
|
|
485
|
+
onSelect: () => openSheet("message"),
|
|
486
|
+
children: [/* @__PURE__ */ jsx(MessageIcon, {}), "Message agent"]
|
|
487
|
+
}) : null,
|
|
488
|
+
/* @__PURE__ */ jsxs(DropdownMenuItem, {
|
|
489
|
+
variant: "destructive",
|
|
490
|
+
onSelect: () => requestTaskRemoval(sendSessionFrame, sessionId, task.id),
|
|
491
|
+
children: [/* @__PURE__ */ jsx(TrashIcon, { color: "red" }), "Remove"]
|
|
492
|
+
})
|
|
493
|
+
] })] }) : null]
|
|
494
|
+
})
|
|
495
|
+
})
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* The session task graph in the app's Activity list, mirroring the web
|
|
500
|
+
* section: active rows first, finished ones behind a collapsed history, and a
|
|
501
|
+
* sheet for reading or changing one task. Empty graphs render nothing.
|
|
502
|
+
*/
|
|
503
|
+
function TasksActivitySection({ sessionId, sendSessionFrame }) {
|
|
504
|
+
const sessionTasks = useSessionTasks(sessionId);
|
|
505
|
+
const [historyOpen, setHistoryOpen] = useState(false);
|
|
506
|
+
const [sheet, setSheet] = useState();
|
|
507
|
+
if (sessionId === null || sessionTasks.length === 0) return null;
|
|
508
|
+
const active = sessionTasks.filter((task) => task.status === "pending" || task.status === "in_progress");
|
|
509
|
+
const history = sessionTasks.filter((task) => task.status === "completed" || task.status === "failed");
|
|
510
|
+
const sheetTask = sheet ? sessionTasks.find((task) => task.id === sheet.taskId) : void 0;
|
|
511
|
+
const row = (task) => /* @__PURE__ */ jsx(TaskRow, {
|
|
512
|
+
task,
|
|
513
|
+
sessionId,
|
|
514
|
+
sendSessionFrame,
|
|
515
|
+
openSheet: (mode) => setSheet({
|
|
516
|
+
taskId: task.id,
|
|
517
|
+
mode
|
|
518
|
+
})
|
|
519
|
+
}, task.id);
|
|
520
|
+
return /* @__PURE__ */ jsxs(View, {
|
|
521
|
+
style: styles$1.section,
|
|
522
|
+
children: [
|
|
523
|
+
active.length > 0 ? /* @__PURE__ */ jsx(View, {
|
|
524
|
+
style: styles$1.group,
|
|
525
|
+
children: active.map(row)
|
|
526
|
+
}) : null,
|
|
527
|
+
history.length > 0 ? /* @__PURE__ */ jsxs(View, {
|
|
528
|
+
style: styles$1.group,
|
|
529
|
+
children: [/* @__PURE__ */ jsxs(Button, {
|
|
530
|
+
variant: "ghost",
|
|
531
|
+
accessibilityState: { expanded: historyOpen },
|
|
532
|
+
onPress: () => setHistoryOpen((open) => !open),
|
|
533
|
+
style: styles$1.historyToggle,
|
|
534
|
+
children: [
|
|
535
|
+
/* @__PURE__ */ jsx(Fragment, { children: historyOpen ? /* @__PURE__ */ jsx(ChevronDownIcon, {}) : /* @__PURE__ */ jsx(ChevronRightIcon, {}) }),
|
|
536
|
+
/* @__PURE__ */ jsx(Text, {
|
|
537
|
+
style: styles$1.historyLabel,
|
|
538
|
+
children: "Session"
|
|
539
|
+
}),
|
|
540
|
+
/* @__PURE__ */ jsx(Badge, { children: history.length })
|
|
541
|
+
]
|
|
542
|
+
}), historyOpen ? /* @__PURE__ */ jsx(View, {
|
|
543
|
+
style: [styles$1.group, styles$1.history],
|
|
544
|
+
children: history.map(row)
|
|
545
|
+
}) : null]
|
|
546
|
+
}) : null,
|
|
547
|
+
sheet && sheetTask ? /* @__PURE__ */ jsx(TaskDetailSheet, {
|
|
548
|
+
task: sheetTask,
|
|
549
|
+
sessionId,
|
|
550
|
+
mode: sheet.mode,
|
|
551
|
+
send: sendSessionFrame,
|
|
552
|
+
onClose: () => setSheet(void 0)
|
|
553
|
+
}, `${sheetTask.id}-${sheet.mode}`) : null
|
|
554
|
+
]
|
|
555
|
+
});
|
|
556
|
+
}
|
|
557
|
+
const styles$1 = StyleSheet.create((theme) => ({
|
|
558
|
+
section: {
|
|
559
|
+
gap: theme.spacing(2),
|
|
560
|
+
uni__dependencies: [0]
|
|
561
|
+
},
|
|
562
|
+
group: {
|
|
563
|
+
gap: theme.spacing(.5),
|
|
564
|
+
uni__dependencies: [0]
|
|
565
|
+
},
|
|
566
|
+
history: {
|
|
567
|
+
paddingLeft: theme.spacing(2),
|
|
568
|
+
uni__dependencies: [0]
|
|
569
|
+
},
|
|
570
|
+
row: {
|
|
571
|
+
gap: theme.spacing(1),
|
|
572
|
+
paddingHorizontal: theme.spacing(1),
|
|
573
|
+
paddingVertical: theme.spacing(1),
|
|
574
|
+
borderRadius: theme.borderRadius.md,
|
|
575
|
+
uni__dependencies: [0]
|
|
576
|
+
},
|
|
577
|
+
line: {
|
|
578
|
+
flexDirection: "row",
|
|
579
|
+
alignItems: "center",
|
|
580
|
+
gap: theme.spacing(1.5),
|
|
581
|
+
uni__dependencies: [0]
|
|
582
|
+
},
|
|
583
|
+
title: (ink) => ({
|
|
584
|
+
fontSize: theme.fontSize.base,
|
|
585
|
+
lineHeight: theme.lineHeight.base,
|
|
586
|
+
fontWeight: "600",
|
|
587
|
+
color: theme.colors[ink],
|
|
588
|
+
uni__dependencies: [0]
|
|
589
|
+
}),
|
|
590
|
+
id: {
|
|
591
|
+
color: theme.colors.dim,
|
|
592
|
+
uni__dependencies: [0]
|
|
593
|
+
},
|
|
594
|
+
meta: {
|
|
595
|
+
fontSize: theme.fontSize.sm,
|
|
596
|
+
lineHeight: theme.lineHeight.sm,
|
|
597
|
+
color: theme.colors.dim,
|
|
598
|
+
uni__dependencies: [0]
|
|
599
|
+
},
|
|
600
|
+
detail: {
|
|
601
|
+
paddingLeft: theme.spacing(3),
|
|
602
|
+
uni__dependencies: [0]
|
|
603
|
+
},
|
|
604
|
+
historyToggle: {
|
|
605
|
+
flexDirection: "row",
|
|
606
|
+
alignItems: "center",
|
|
607
|
+
gap: theme.spacing(1.5),
|
|
608
|
+
minHeight: theme.spacing(11),
|
|
609
|
+
paddingHorizontal: theme.spacing(1),
|
|
610
|
+
borderRadius: theme.borderRadius.md,
|
|
611
|
+
uni__dependencies: [0]
|
|
612
|
+
},
|
|
613
|
+
chevron: {
|
|
614
|
+
fontSize: theme.fontSize.sm,
|
|
615
|
+
lineHeight: theme.lineHeight.sm,
|
|
616
|
+
color: theme.colors.faint,
|
|
617
|
+
uni__dependencies: [0]
|
|
618
|
+
},
|
|
619
|
+
historyLabel: {
|
|
620
|
+
fontSize: theme.fontSize.base,
|
|
621
|
+
lineHeight: theme.lineHeight.base,
|
|
622
|
+
fontWeight: "500",
|
|
623
|
+
color: theme.colors.dim,
|
|
624
|
+
uni__dependencies: [0]
|
|
625
|
+
},
|
|
626
|
+
count: {
|
|
627
|
+
fontSize: theme.fontSize["2xs"],
|
|
628
|
+
lineHeight: theme.lineHeight["2xs"],
|
|
629
|
+
color: theme.colors.faint,
|
|
630
|
+
uni__dependencies: [0]
|
|
631
|
+
}
|
|
632
|
+
}));
|
|
633
|
+
//#endregion
|
|
634
|
+
//#region src/extensions/workspaces/sessions/(frontend)/fill/Tasks.activity.tasks.native.tsx
|
|
635
|
+
var Tasks_activity_tasks_native_default = defineFill({ component: TasksActivitySection });
|
|
636
|
+
//#endregion
|
|
637
|
+
//#region src/extensions/workspaces/sessions/(frontend)/tool/_lib/taskToolFormat.ts
|
|
638
|
+
const STATUS_GLYPH = {
|
|
639
|
+
pending: "○",
|
|
640
|
+
in_progress: "◐",
|
|
641
|
+
completed: "●",
|
|
642
|
+
failed: "✗",
|
|
643
|
+
deleted: "⊘"
|
|
644
|
+
};
|
|
645
|
+
const STATUS_LABEL = {
|
|
646
|
+
pending: "pending",
|
|
647
|
+
in_progress: "in progress",
|
|
648
|
+
completed: "completed",
|
|
649
|
+
failed: "failed",
|
|
650
|
+
deleted: "deleted"
|
|
651
|
+
};
|
|
652
|
+
const ACTION_GLYPH = {
|
|
653
|
+
upsert: "✎",
|
|
654
|
+
delete: "×",
|
|
655
|
+
get: "›",
|
|
656
|
+
list: "☰",
|
|
657
|
+
clear: "∅",
|
|
658
|
+
assign: "⇒",
|
|
659
|
+
cancel: "⊗"
|
|
660
|
+
};
|
|
661
|
+
/**
|
|
662
|
+
* `upsert` is two operations behind one name, so a homogeneous batch narrows to
|
|
663
|
+
* the glyph the operator already reads: `+` means new work appeared, `→` means
|
|
664
|
+
* work moved. A mixed batch keeps the neutral write glyph.
|
|
665
|
+
*/
|
|
666
|
+
const UPSERT_CREATE_GLYPH = "+";
|
|
667
|
+
const UPSERT_UPDATE_GLYPH = "→";
|
|
668
|
+
/** Task rows kept in a collapsed result, before the card is expanded. */
|
|
669
|
+
const TRANSCRIPT_TASK_ROWS = 8;
|
|
670
|
+
const TASK_STATUSES = [
|
|
671
|
+
"pending",
|
|
672
|
+
"in_progress",
|
|
673
|
+
"completed",
|
|
674
|
+
"failed",
|
|
675
|
+
"deleted"
|
|
676
|
+
];
|
|
677
|
+
const TASK_ACTIONS = [
|
|
678
|
+
"upsert",
|
|
679
|
+
"list",
|
|
680
|
+
"get",
|
|
681
|
+
"delete",
|
|
682
|
+
"clear",
|
|
683
|
+
"assign",
|
|
684
|
+
"cancel"
|
|
685
|
+
];
|
|
686
|
+
const INLINE_WHITESPACE = /\s+/gu;
|
|
687
|
+
function isRecord(value) {
|
|
688
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
689
|
+
}
|
|
690
|
+
function isStatus(value) {
|
|
691
|
+
return typeof value === "string" && TASK_STATUSES.includes(value);
|
|
692
|
+
}
|
|
693
|
+
function isAction(value) {
|
|
694
|
+
return typeof value === "string" && TASK_ACTIONS.includes(value);
|
|
695
|
+
}
|
|
696
|
+
function taskView(value) {
|
|
697
|
+
if (!isRecord(value) || typeof value.id !== "number" || typeof value.subject !== "string") return null;
|
|
698
|
+
if (!isStatus(value.status)) return null;
|
|
699
|
+
const task = {
|
|
700
|
+
id: value.id,
|
|
701
|
+
subject: value.subject,
|
|
702
|
+
status: value.status
|
|
703
|
+
};
|
|
704
|
+
if (typeof value.activeForm === "string") task.activeForm = value.activeForm;
|
|
705
|
+
if (Array.isArray(value.blockedBy)) task.blockedBy = value.blockedBy.filter((id) => typeof id === "number");
|
|
706
|
+
if (isRecord(value.delegation)) {
|
|
707
|
+
task.delegation = {};
|
|
708
|
+
if (typeof value.delegation.agent === "string") task.delegation.agent = value.delegation.agent;
|
|
709
|
+
if (typeof value.delegation.state === "string") task.delegation.state = value.delegation.state;
|
|
710
|
+
}
|
|
711
|
+
return task;
|
|
712
|
+
}
|
|
713
|
+
function idList(value) {
|
|
714
|
+
return Array.isArray(value) ? value.filter((id) => typeof id === "number") : [];
|
|
715
|
+
}
|
|
716
|
+
/** Narrows the wire details; null when they are not a task result at all. */
|
|
717
|
+
function taskDetailsView(details) {
|
|
718
|
+
if (!isRecord(details) || !isAction(details.action) || !Array.isArray(details.tasks)) return null;
|
|
719
|
+
const view = {
|
|
720
|
+
action: details.action,
|
|
721
|
+
params: isRecord(details.params) ? details.params : {},
|
|
722
|
+
tasks: details.tasks.map(taskView).filter((task) => task !== null)
|
|
723
|
+
};
|
|
724
|
+
if (typeof details.error === "string") view.error = details.error;
|
|
725
|
+
if (isRecord(details.upsert)) view.upsert = {
|
|
726
|
+
applied: idList(details.upsert.applied),
|
|
727
|
+
failed: typeof details.upsert.failed === "number" ? details.upsert.failed : 0
|
|
728
|
+
};
|
|
729
|
+
if (isRecord(details.assignment)) view.assignment = {
|
|
730
|
+
assigned: idList(details.assignment.assigned),
|
|
731
|
+
failed: typeof details.assignment.failed === "number" ? details.assignment.failed : 0
|
|
732
|
+
};
|
|
733
|
+
return view;
|
|
734
|
+
}
|
|
735
|
+
/** `#id` for the wire's id, which the TUI would resolve to a subject through the store. */
|
|
736
|
+
function idLabel(value) {
|
|
737
|
+
return typeof value === "number" || typeof value === "string" ? `#${value}` : "#?";
|
|
738
|
+
}
|
|
739
|
+
/** Keep dynamic content on one line. */
|
|
740
|
+
function inlineText(text) {
|
|
741
|
+
return text.replace(INLINE_WHITESPACE, " ").trim();
|
|
742
|
+
}
|
|
743
|
+
function upsertGlyph(items) {
|
|
744
|
+
if (items.length === 0) return ACTION_GLYPH.upsert;
|
|
745
|
+
if (items.every((item) => item.id === void 0)) return UPSERT_CREATE_GLYPH;
|
|
746
|
+
if (items.every((item) => item.id !== void 0)) return UPSERT_UPDATE_GLYPH;
|
|
747
|
+
return ACTION_GLYPH.upsert;
|
|
748
|
+
}
|
|
749
|
+
/**
|
|
750
|
+
* The TUI resolves an id to its subject through the task store; the card has
|
|
751
|
+
* no store and shows `#id` until the result names the task.
|
|
752
|
+
*/
|
|
753
|
+
function taskCallView(args) {
|
|
754
|
+
const action = typeof args.action === "string" ? args.action : "task";
|
|
755
|
+
if (!isAction(action)) return {
|
|
756
|
+
glyph: "?",
|
|
757
|
+
action,
|
|
758
|
+
subjectTone: "dim"
|
|
759
|
+
};
|
|
760
|
+
const items = action === "upsert" && Array.isArray(args.tasks) ? args.tasks.filter(isRecord) : [];
|
|
761
|
+
const view = {
|
|
762
|
+
glyph: action === "upsert" ? upsertGlyph(items) : ACTION_GLYPH[action],
|
|
763
|
+
action,
|
|
764
|
+
subjectTone: "dim"
|
|
765
|
+
};
|
|
766
|
+
if (action === "upsert") {
|
|
767
|
+
if (items.length === 1) {
|
|
768
|
+
const only = items[0] ?? {};
|
|
769
|
+
if (only.id === void 0) {
|
|
770
|
+
if (typeof only.subject === "string") view.subject = inlineText(only.subject);
|
|
771
|
+
} else {
|
|
772
|
+
view.subject = typeof only.subject === "string" ? inlineText(only.subject) : idLabel(only.id);
|
|
773
|
+
view.subjectTone = "accent";
|
|
774
|
+
}
|
|
775
|
+
} else if (items.length > 1) view.subject = `${items.length} tasks`;
|
|
776
|
+
} else if (action === "assign") {
|
|
777
|
+
const assignments = Array.isArray(args.assignments) ? args.assignments.filter(isRecord) : [];
|
|
778
|
+
if (assignments.length === 1) {
|
|
779
|
+
const only = assignments[0] ?? {};
|
|
780
|
+
view.subject = idLabel(only.id);
|
|
781
|
+
view.subjectTone = "accent";
|
|
782
|
+
if (typeof only.agent === "string") view.detail = `→ ${only.agent}`;
|
|
783
|
+
} else if (assignments.length > 1) view.subject = `${assignments.length} tasks`;
|
|
784
|
+
} else if ((action === "get" || action === "delete" || action === "cancel") && args.id !== void 0) {
|
|
785
|
+
view.subject = idLabel(args.id);
|
|
786
|
+
view.subjectTone = "accent";
|
|
787
|
+
} else if (action === "list" && isStatus(args.status)) view.detail = STATUS_LABEL[args.status];
|
|
788
|
+
return view;
|
|
789
|
+
}
|
|
790
|
+
function taskRow(task) {
|
|
791
|
+
const row = {
|
|
792
|
+
id: task.id,
|
|
793
|
+
glyph: STATUS_GLYPH[task.status],
|
|
794
|
+
subject: inlineText(task.subject),
|
|
795
|
+
status: task.status,
|
|
796
|
+
closed: task.status === "completed" || task.status === "deleted",
|
|
797
|
+
blockedBy: task.blockedBy ?? []
|
|
798
|
+
};
|
|
799
|
+
if (task.delegation?.agent) row.agent = inlineText(task.delegation.agent);
|
|
800
|
+
if (task.status === "in_progress" && task.activeForm) row.activeForm = inlineText(task.activeForm);
|
|
801
|
+
return row;
|
|
802
|
+
}
|
|
803
|
+
function nonEmptyLines(text) {
|
|
804
|
+
return text.split("\n").filter((line) => line.trim().length > 0);
|
|
805
|
+
}
|
|
806
|
+
/**
|
|
807
|
+
* The rows `list` reported to the model: `details.tasks` is the whole
|
|
808
|
+
* document, so the call's filters apply again here or the card would disagree
|
|
809
|
+
* with the text the model was given.
|
|
810
|
+
*/
|
|
811
|
+
function listedTasks(details) {
|
|
812
|
+
let view = details.tasks;
|
|
813
|
+
if (details.params.includeDeleted !== true) view = view.filter((task) => task.status !== "deleted");
|
|
814
|
+
if (isStatus(details.params.status)) view = view.filter((task) => task.status === details.params.status);
|
|
815
|
+
return view;
|
|
816
|
+
}
|
|
817
|
+
function byIds(details, ids) {
|
|
818
|
+
return ids.flatMap((id) => details.tasks.find((task) => task.id === id) ?? []);
|
|
819
|
+
}
|
|
820
|
+
function batch(tasks, failed, verb, expanded) {
|
|
821
|
+
if (tasks.length === 1 && failed === 0) return {
|
|
822
|
+
rows: [taskRow(tasks[0])],
|
|
823
|
+
status: null
|
|
824
|
+
};
|
|
825
|
+
const shown = expanded ? tasks : tasks.slice(0, TRANSCRIPT_TASK_ROWS);
|
|
826
|
+
let summary = `${tasks.length} ${verb}`;
|
|
827
|
+
if (failed > 0) summary += ` · ${failed} failed`;
|
|
828
|
+
if (tasks.length > shown.length) summary += ` · ${tasks.length - shown.length} more`;
|
|
829
|
+
return {
|
|
830
|
+
rows: shown.map(taskRow),
|
|
831
|
+
status: {
|
|
832
|
+
glyph: failed > 0 ? "!" : "✓",
|
|
833
|
+
tone: failed > 0 ? "warning" : "ok",
|
|
834
|
+
text: summary
|
|
835
|
+
}
|
|
836
|
+
};
|
|
837
|
+
}
|
|
838
|
+
function taskResultView(input) {
|
|
839
|
+
const details = taskDetailsView(input.details);
|
|
840
|
+
if (input.isPartial) return {
|
|
841
|
+
rows: [],
|
|
842
|
+
errorLines: [],
|
|
843
|
+
status: {
|
|
844
|
+
glyph: "◐",
|
|
845
|
+
tone: "running",
|
|
846
|
+
text: nonEmptyLines(input.output).at(-1) ?? "working"
|
|
847
|
+
}
|
|
848
|
+
};
|
|
849
|
+
if (input.isError || details?.error !== void 0) {
|
|
850
|
+
const all = nonEmptyLines(details?.error ?? input.output);
|
|
851
|
+
if (all.length <= 1) return {
|
|
852
|
+
rows: [],
|
|
853
|
+
errorLines: [],
|
|
854
|
+
status: {
|
|
855
|
+
glyph: "✗",
|
|
856
|
+
tone: "error",
|
|
857
|
+
text: all[0] ?? ""
|
|
858
|
+
}
|
|
859
|
+
};
|
|
860
|
+
return {
|
|
861
|
+
rows: [],
|
|
862
|
+
errorLines: input.expanded ? all : all.slice(0, TRANSCRIPT_TASK_ROWS),
|
|
863
|
+
status: {
|
|
864
|
+
glyph: "✗",
|
|
865
|
+
tone: "error",
|
|
866
|
+
text: ""
|
|
867
|
+
}
|
|
868
|
+
};
|
|
869
|
+
}
|
|
870
|
+
if (details === null) return {
|
|
871
|
+
rows: [],
|
|
872
|
+
errorLines: [],
|
|
873
|
+
status: {
|
|
874
|
+
glyph: "✓",
|
|
875
|
+
tone: "ok",
|
|
876
|
+
text: ""
|
|
877
|
+
}
|
|
878
|
+
};
|
|
879
|
+
if (details.action === "list") {
|
|
880
|
+
const tasks = listedTasks(details);
|
|
881
|
+
const shown = input.expanded ? tasks : tasks.slice(0, TRANSCRIPT_TASK_ROWS);
|
|
882
|
+
let summary = tasks.length === 0 ? "no tasks" : `${tasks.length} task${tasks.length === 1 ? "" : "s"}`;
|
|
883
|
+
if (tasks.length > shown.length) summary += ` · ${tasks.length - shown.length} more`;
|
|
884
|
+
return {
|
|
885
|
+
rows: shown.map(taskRow),
|
|
886
|
+
errorLines: [],
|
|
887
|
+
status: {
|
|
888
|
+
glyph: "✓",
|
|
889
|
+
tone: "ok",
|
|
890
|
+
text: summary
|
|
891
|
+
}
|
|
892
|
+
};
|
|
893
|
+
}
|
|
894
|
+
if (details.action === "clear") return {
|
|
895
|
+
rows: [],
|
|
896
|
+
errorLines: [],
|
|
897
|
+
status: {
|
|
898
|
+
glyph: "✓",
|
|
899
|
+
tone: "ok",
|
|
900
|
+
text: "cleared"
|
|
901
|
+
}
|
|
902
|
+
};
|
|
903
|
+
if (details.action === "assign" && details.assignment) return {
|
|
904
|
+
errorLines: [],
|
|
905
|
+
...batch(byIds(details, details.assignment.assigned), details.assignment.failed, "assigned", input.expanded)
|
|
906
|
+
};
|
|
907
|
+
if (details.action === "upsert") return {
|
|
908
|
+
errorLines: [],
|
|
909
|
+
...batch(byIds(details, details.upsert?.applied ?? []), details.upsert?.failed ?? 0, "applied", input.expanded)
|
|
910
|
+
};
|
|
911
|
+
const id = details.params.id;
|
|
912
|
+
const task = typeof id === "number" ? details.tasks.find((candidate) => candidate.id === id) : void 0;
|
|
913
|
+
if (!task) return {
|
|
914
|
+
rows: [],
|
|
915
|
+
errorLines: [],
|
|
916
|
+
status: {
|
|
917
|
+
glyph: "✓",
|
|
918
|
+
tone: "ok",
|
|
919
|
+
text: ""
|
|
920
|
+
}
|
|
921
|
+
};
|
|
922
|
+
return {
|
|
923
|
+
rows: [taskRow(task)],
|
|
924
|
+
errorLines: [],
|
|
925
|
+
status: null
|
|
926
|
+
};
|
|
927
|
+
}
|
|
928
|
+
//#endregion
|
|
929
|
+
//#region src/extensions/workspaces/sessions/(frontend)/tool/_lib/TaskToolMessage.native.tsx
|
|
930
|
+
const STATUS_DOT = {
|
|
931
|
+
pending: "muted",
|
|
932
|
+
in_progress: "yellow",
|
|
933
|
+
completed: "green",
|
|
934
|
+
failed: "red",
|
|
935
|
+
deleted: "muted"
|
|
936
|
+
};
|
|
937
|
+
const CALL_INK = {
|
|
938
|
+
dim: "hi",
|
|
939
|
+
accent: "blue"
|
|
940
|
+
};
|
|
941
|
+
const STATUS_TONE = {
|
|
942
|
+
pending: "neutral",
|
|
943
|
+
in_progress: "running",
|
|
944
|
+
completed: "ok",
|
|
945
|
+
failed: "error",
|
|
946
|
+
deleted: "neutral"
|
|
947
|
+
};
|
|
948
|
+
const RESULT_TONE = {
|
|
949
|
+
running: "running",
|
|
950
|
+
ok: "ok",
|
|
951
|
+
error: "error",
|
|
952
|
+
warning: "running"
|
|
953
|
+
};
|
|
954
|
+
function subjectInk(row) {
|
|
955
|
+
if (row.closed) return "dim";
|
|
956
|
+
return row.status === "in_progress" ? "blue" : "hi";
|
|
957
|
+
}
|
|
958
|
+
/** One task row: status glyph, id, subject and chips on the left, the status label flushed right. */
|
|
959
|
+
function TaskRowLine({ row }) {
|
|
960
|
+
return /* @__PURE__ */ jsxs(View, {
|
|
961
|
+
testID: "tool-result-task-row",
|
|
962
|
+
style: styles.row,
|
|
963
|
+
children: [
|
|
964
|
+
/* @__PURE__ */ jsx(Dot, {
|
|
965
|
+
tone: STATUS_DOT[row.status],
|
|
966
|
+
pulse: row.status === "in_progress"
|
|
967
|
+
}),
|
|
968
|
+
/* @__PURE__ */ jsxs(Text, {
|
|
969
|
+
style: styles.meta,
|
|
970
|
+
children: ["#", row.id]
|
|
971
|
+
}),
|
|
972
|
+
/* @__PURE__ */ jsxs(Text, {
|
|
973
|
+
numberOfLines: 1,
|
|
974
|
+
style: [
|
|
975
|
+
styles.rowSubject,
|
|
976
|
+
styles.ink(subjectInk(row)),
|
|
977
|
+
row.closed ? styles.struck : null
|
|
978
|
+
],
|
|
979
|
+
children: [
|
|
980
|
+
row.subject,
|
|
981
|
+
row.agent ? /* @__PURE__ */ jsxs(Text, {
|
|
982
|
+
style: styles.meta,
|
|
983
|
+
children: [
|
|
984
|
+
" [",
|
|
985
|
+
row.agent,
|
|
986
|
+
"]"
|
|
987
|
+
]
|
|
988
|
+
}) : null,
|
|
989
|
+
row.activeForm ? /* @__PURE__ */ jsxs(Text, {
|
|
990
|
+
style: styles.meta,
|
|
991
|
+
children: [
|
|
992
|
+
" (",
|
|
993
|
+
row.activeForm,
|
|
994
|
+
")"
|
|
995
|
+
]
|
|
996
|
+
}) : null,
|
|
997
|
+
row.blockedBy.length > 0 ? /* @__PURE__ */ jsxs(Text, {
|
|
998
|
+
style: styles.meta,
|
|
999
|
+
children: [" ⛓ ", row.blockedBy.map((id) => `#${id}`).join(",")]
|
|
1000
|
+
}) : null
|
|
1001
|
+
]
|
|
1002
|
+
}),
|
|
1003
|
+
/* @__PURE__ */ jsx(StatusBadge, {
|
|
1004
|
+
tone: STATUS_TONE[row.status],
|
|
1005
|
+
children: STATUS_LABEL[row.status]
|
|
1006
|
+
})
|
|
1007
|
+
]
|
|
1008
|
+
});
|
|
1009
|
+
}
|
|
1010
|
+
/**
|
|
1011
|
+
* The task tool's timeline item on the phone, laid out as the web card is:
|
|
1012
|
+
* `glyph action subject` with the assignee or list filter in the header, then
|
|
1013
|
+
* the rows the action touched and the batch or list summary.
|
|
1014
|
+
*/
|
|
1015
|
+
function TaskToolMessage({ args, result, output, running, isError }) {
|
|
1016
|
+
const call = taskCallView(args);
|
|
1017
|
+
const collapsed = taskResultView({
|
|
1018
|
+
details: result?.details,
|
|
1019
|
+
output,
|
|
1020
|
+
expanded: false,
|
|
1021
|
+
isPartial: running,
|
|
1022
|
+
isError
|
|
1023
|
+
});
|
|
1024
|
+
const full = taskResultView({
|
|
1025
|
+
details: result?.details,
|
|
1026
|
+
output,
|
|
1027
|
+
expanded: true,
|
|
1028
|
+
isPartial: running,
|
|
1029
|
+
isError
|
|
1030
|
+
});
|
|
1031
|
+
const hidden = full.rows.length - collapsed.rows.length + (full.errorLines.length - collapsed.errorLines.length);
|
|
1032
|
+
return /* @__PURE__ */ jsx(MessageItem, {
|
|
1033
|
+
testID: "tool-task",
|
|
1034
|
+
tone: toolTone({
|
|
1035
|
+
running,
|
|
1036
|
+
isError
|
|
1037
|
+
}),
|
|
1038
|
+
expandable: hidden > 0,
|
|
1039
|
+
children: ({ expanded }) => {
|
|
1040
|
+
const view = expanded ? full : collapsed;
|
|
1041
|
+
const empty = view.rows.length === 0 && view.errorLines.length === 0 && view.status === null;
|
|
1042
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs(MessageItemHeader, {
|
|
1043
|
+
title: "task",
|
|
1044
|
+
testID: "tool-call-task",
|
|
1045
|
+
accessibilityLabel: `task ${call.action}`,
|
|
1046
|
+
children: [
|
|
1047
|
+
/* @__PURE__ */ jsxs(Text, {
|
|
1048
|
+
style: styles.action,
|
|
1049
|
+
children: [
|
|
1050
|
+
call.glyph,
|
|
1051
|
+
" ",
|
|
1052
|
+
call.action
|
|
1053
|
+
]
|
|
1054
|
+
}),
|
|
1055
|
+
call.subject ? /* @__PURE__ */ jsx(Text, {
|
|
1056
|
+
numberOfLines: 1,
|
|
1057
|
+
style: [styles.subject, styles.ink(CALL_INK[call.subjectTone])],
|
|
1058
|
+
children: call.subject
|
|
1059
|
+
}) : null,
|
|
1060
|
+
call.detail ? /* @__PURE__ */ jsx(Text, {
|
|
1061
|
+
style: styles.meta,
|
|
1062
|
+
children: call.detail
|
|
1063
|
+
}) : null
|
|
1064
|
+
]
|
|
1065
|
+
}), empty ? null : /* @__PURE__ */ jsxs(MessageItemBody, {
|
|
1066
|
+
testID: "tool-result-task",
|
|
1067
|
+
children: [
|
|
1068
|
+
view.rows.length > 0 ? /* @__PURE__ */ jsx(View, {
|
|
1069
|
+
style: styles.rows,
|
|
1070
|
+
children: view.rows.map((row) => /* @__PURE__ */ jsx(TaskRowLine, { row }, row.id))
|
|
1071
|
+
}) : null,
|
|
1072
|
+
view.errorLines.length > 0 ? /* @__PURE__ */ jsx(CodeBlock, { text: view.errorLines.join("\n") }) : null,
|
|
1073
|
+
!expanded && hidden > 0 ? /* @__PURE__ */ jsxs(MessageItemStatus, {
|
|
1074
|
+
expands: true,
|
|
1075
|
+
accessibilityLabel: `Show ${hidden} more`,
|
|
1076
|
+
children: [hidden, " more"]
|
|
1077
|
+
}) : null,
|
|
1078
|
+
view.status ? /* @__PURE__ */ jsx(MessageItemStatus, {
|
|
1079
|
+
testID: "tool-result-task-status",
|
|
1080
|
+
tone: RESULT_TONE[view.status.tone],
|
|
1081
|
+
glyph: view.status.glyph,
|
|
1082
|
+
children: view.status.text
|
|
1083
|
+
}) : null
|
|
1084
|
+
]
|
|
1085
|
+
})] });
|
|
1086
|
+
}
|
|
1087
|
+
});
|
|
1088
|
+
}
|
|
1089
|
+
const styles = StyleSheet.create((theme) => ({
|
|
1090
|
+
action: {
|
|
1091
|
+
fontSize: theme.fontSize.base,
|
|
1092
|
+
lineHeight: theme.lineHeight.base,
|
|
1093
|
+
fontWeight: "600",
|
|
1094
|
+
color: theme.colors.text,
|
|
1095
|
+
uni__dependencies: [0]
|
|
1096
|
+
},
|
|
1097
|
+
subject: {
|
|
1098
|
+
flexShrink: 1,
|
|
1099
|
+
fontSize: theme.fontSize.base,
|
|
1100
|
+
lineHeight: theme.lineHeight.base,
|
|
1101
|
+
fontWeight: "600",
|
|
1102
|
+
uni__dependencies: [0]
|
|
1103
|
+
},
|
|
1104
|
+
body: {
|
|
1105
|
+
gap: theme.spacing(1),
|
|
1106
|
+
uni__dependencies: [0]
|
|
1107
|
+
},
|
|
1108
|
+
rows: {
|
|
1109
|
+
gap: theme.spacing(.5),
|
|
1110
|
+
uni__dependencies: [0]
|
|
1111
|
+
},
|
|
1112
|
+
row: {
|
|
1113
|
+
flexDirection: "row",
|
|
1114
|
+
alignItems: "baseline",
|
|
1115
|
+
gap: theme.spacing(2),
|
|
1116
|
+
uni__dependencies: [0]
|
|
1117
|
+
},
|
|
1118
|
+
rowSubject: {
|
|
1119
|
+
flex: 1,
|
|
1120
|
+
fontSize: theme.fontSize.base,
|
|
1121
|
+
lineHeight: theme.lineHeight.base,
|
|
1122
|
+
fontWeight: "600",
|
|
1123
|
+
uni__dependencies: [0]
|
|
1124
|
+
},
|
|
1125
|
+
struck: { textDecorationLine: "line-through" },
|
|
1126
|
+
meta: {
|
|
1127
|
+
fontSize: theme.fontSize.sm,
|
|
1128
|
+
lineHeight: theme.lineHeight.sm,
|
|
1129
|
+
color: theme.colors.dim,
|
|
1130
|
+
uni__dependencies: [0]
|
|
1131
|
+
},
|
|
1132
|
+
statusGlyph: {
|
|
1133
|
+
fontSize: theme.fontSize.sm,
|
|
1134
|
+
lineHeight: theme.lineHeight.sm,
|
|
1135
|
+
fontWeight: "600",
|
|
1136
|
+
uni__dependencies: [0]
|
|
1137
|
+
},
|
|
1138
|
+
ink: (token) => ({
|
|
1139
|
+
color: theme.colors[token],
|
|
1140
|
+
uni__dependencies: [0]
|
|
1141
|
+
})
|
|
1142
|
+
}));
|
|
1143
|
+
//#endregion
|
|
1144
|
+
//#region src/extensions/workspaces/sessions/(frontend)/tool/task.native.tsx
|
|
1145
|
+
var task_native_default = defineToolRenderer({ message: TaskToolMessage });
|
|
1146
|
+
//#endregion
|
|
1147
|
+
//#region generated/native.ts
|
|
1148
|
+
const via = (identity, value) => value === void 0 ? void 0 : {
|
|
1149
|
+
...identity,
|
|
1150
|
+
...value
|
|
1151
|
+
};
|
|
1152
|
+
const nativePlugin = defineNativePlugin({
|
|
1153
|
+
id: "task",
|
|
1154
|
+
session: {
|
|
1155
|
+
get activityGroups() {
|
|
1156
|
+
return [via({ name: "tasks" }, tasks_native_default)];
|
|
1157
|
+
},
|
|
1158
|
+
get channels() {
|
|
1159
|
+
return [via({ channel: "task_graph" }, task_graph_native_default)];
|
|
1160
|
+
},
|
|
1161
|
+
get fills() {
|
|
1162
|
+
return [via({
|
|
1163
|
+
slot: "activity.tasks",
|
|
1164
|
+
id: "tasks"
|
|
1165
|
+
}, Tasks_activity_tasks_native_default)];
|
|
1166
|
+
},
|
|
1167
|
+
get toolRenderers() {
|
|
1168
|
+
return [via({ tools: ["task"] }, task_native_default)];
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
});
|
|
1172
|
+
//#endregion
|
|
1173
|
+
export { nativePlugin };
|
|
1174
|
+
|
|
1175
|
+
//# sourceMappingURL=native.mjs.map
|