@percena/weft 0.4.0-next.3 → 0.4.0-next.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/action-bridge.cjs +172 -6
- package/dist/action-bridge.d.cts +112 -13
- package/dist/action-bridge.d.ts +112 -13
- package/dist/action-bridge.js +166 -4
- package/dist/chat.cjs +982 -3
- package/dist/chat.d.cts +30 -1
- package/dist/chat.d.ts +30 -1
- package/dist/chat.js +981 -2
- package/dist/index.cjs +341 -1616
- package/dist/index.d.cts +4 -274
- package/dist/index.d.ts +4 -274
- package/dist/index.js +174 -1408
- package/dist/styles/fonts/KaTeX_AMS-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_AMS-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_AMS-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Caligraphic-Bold.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Caligraphic-Bold.woff +0 -0
- package/dist/styles/fonts/KaTeX_Caligraphic-Bold.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Caligraphic-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Caligraphic-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Caligraphic-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Fraktur-Bold.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Fraktur-Bold.woff +0 -0
- package/dist/styles/fonts/KaTeX_Fraktur-Bold.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Fraktur-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Fraktur-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Fraktur-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Main-Bold.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Main-Bold.woff +0 -0
- package/dist/styles/fonts/KaTeX_Main-Bold.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Main-BoldItalic.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Main-BoldItalic.woff +0 -0
- package/dist/styles/fonts/KaTeX_Main-BoldItalic.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Main-Italic.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Main-Italic.woff +0 -0
- package/dist/styles/fonts/KaTeX_Main-Italic.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Main-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Main-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Main-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Math-BoldItalic.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Math-BoldItalic.woff +0 -0
- package/dist/styles/fonts/KaTeX_Math-BoldItalic.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Math-Italic.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Math-Italic.woff +0 -0
- package/dist/styles/fonts/KaTeX_Math-Italic.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Bold.ttf +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Bold.woff +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Bold.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Italic.ttf +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Italic.woff +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Italic.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_SansSerif-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Script-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Script-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Script-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Size1-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Size1-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Size1-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Size2-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Size2-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Size2-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Size3-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Size3-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Size3-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Size4-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Size4-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Size4-Regular.woff2 +0 -0
- package/dist/styles/fonts/KaTeX_Typewriter-Regular.ttf +0 -0
- package/dist/styles/fonts/KaTeX_Typewriter-Regular.woff +0 -0
- package/dist/styles/fonts/KaTeX_Typewriter-Regular.woff2 +0 -0
- package/package.json +2 -30
- package/dist/local-runtime.cjs +0 -1387
- package/dist/local-runtime.d.cts +0 -3314
- package/dist/local-runtime.d.ts +0 -3314
- package/dist/local-runtime.js +0 -1345
- package/dist/skills-browser.cjs +0 -118
- package/dist/skills-browser.d.cts +0 -105
- package/dist/skills-browser.d.ts +0 -105
- package/dist/skills-browser.js +0 -88
package/dist/index.js
CHANGED
|
@@ -1,722 +1,5 @@
|
|
|
1
|
-
// ../packages/
|
|
2
|
-
|
|
3
|
-
return `msg-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
4
|
-
}
|
|
5
|
-
function messageToStored(msg) {
|
|
6
|
-
const { role, isStreaming, isPending, ...rest } = msg;
|
|
7
|
-
return { ...rest, type: role };
|
|
8
|
-
}
|
|
9
|
-
function storedToMessage(stored) {
|
|
10
|
-
const { type, ...rest } = stored;
|
|
11
|
-
return { ...rest, role: type, timestamp: stored.timestamp ?? Date.now() };
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
// ../packages/core/dist/chunk-LCDW7EA2.js
|
|
15
|
-
function debug(..._args) {
|
|
16
|
-
}
|
|
17
|
-
function normalizePath(path) {
|
|
18
|
-
return path.replace(/\\/g, "/");
|
|
19
|
-
}
|
|
20
|
-
function pathStartsWith(filePath, dirPath) {
|
|
21
|
-
const normalizedFile = normalizePath(filePath);
|
|
22
|
-
const normalizedDir = normalizePath(dirPath);
|
|
23
|
-
return normalizedFile.startsWith(normalizedDir + "/") || normalizedFile === normalizedDir;
|
|
24
|
-
}
|
|
25
|
-
function stripPathPrefix(filePath, prefix) {
|
|
26
|
-
const normalizedFile = normalizePath(filePath);
|
|
27
|
-
const normalizedPrefix = normalizePath(prefix);
|
|
28
|
-
if (normalizedFile.startsWith(normalizedPrefix + "/")) {
|
|
29
|
-
return normalizedFile.slice(normalizedPrefix.length + 1);
|
|
30
|
-
}
|
|
31
|
-
return filePath;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// ../packages/core/dist/index.js
|
|
35
|
-
var THINKING_LEVEL_IDS = [
|
|
36
|
-
"off",
|
|
37
|
-
"low",
|
|
38
|
-
"medium",
|
|
39
|
-
"high",
|
|
40
|
-
"xhigh",
|
|
41
|
-
"max"
|
|
42
|
-
];
|
|
43
|
-
var THINKING_LEVELS = [
|
|
44
|
-
{ id: "off", nameKey: "thinking.off", descriptionKey: "thinking.offDesc" },
|
|
45
|
-
{ id: "low", nameKey: "thinking.low", descriptionKey: "thinking.lowDesc" },
|
|
46
|
-
{ id: "medium", nameKey: "thinking.medium", descriptionKey: "thinking.mediumDesc" },
|
|
47
|
-
{ id: "high", nameKey: "thinking.high", descriptionKey: "thinking.highDesc" },
|
|
48
|
-
{ id: "xhigh", nameKey: "thinking.xhigh", descriptionKey: "thinking.xhighDesc" },
|
|
49
|
-
{ id: "max", nameKey: "thinking.max", descriptionKey: "thinking.maxDesc" }
|
|
50
|
-
];
|
|
51
|
-
var THINKING_TO_EFFORT = {
|
|
52
|
-
off: null,
|
|
53
|
-
low: "low",
|
|
54
|
-
medium: "medium",
|
|
55
|
-
high: "high",
|
|
56
|
-
xhigh: "xhigh",
|
|
57
|
-
max: "max"
|
|
58
|
-
};
|
|
59
|
-
var TOKEN_BUDGETS = {
|
|
60
|
-
haiku: {
|
|
61
|
-
off: 0,
|
|
62
|
-
low: 2e3,
|
|
63
|
-
medium: 4e3,
|
|
64
|
-
high: 6e3,
|
|
65
|
-
xhigh: 7e3,
|
|
66
|
-
max: 8e3
|
|
67
|
-
},
|
|
68
|
-
default: {
|
|
69
|
-
off: 0,
|
|
70
|
-
low: 4e3,
|
|
71
|
-
medium: 1e4,
|
|
72
|
-
high: 2e4,
|
|
73
|
-
xhigh: 26e3,
|
|
74
|
-
max: 32e3
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
function getThinkingTokens(level, modelId) {
|
|
78
|
-
const isHaiku = modelId.toLowerCase().includes("haiku");
|
|
79
|
-
const budgets = isHaiku ? TOKEN_BUDGETS.haiku : TOKEN_BUDGETS.default;
|
|
80
|
-
return budgets[level];
|
|
81
|
-
}
|
|
82
|
-
function getThinkingLevelNameKey(level) {
|
|
83
|
-
const def = THINKING_LEVELS.find((l) => l.id === level);
|
|
84
|
-
return def?.nameKey ?? `thinking.${level}`;
|
|
85
|
-
}
|
|
86
|
-
function isValidThinkingLevel(value) {
|
|
87
|
-
return typeof value === "string" && THINKING_LEVEL_IDS.includes(value);
|
|
88
|
-
}
|
|
89
|
-
function normalizeThinkingLevel(value) {
|
|
90
|
-
if (value === "think") return "medium";
|
|
91
|
-
if (isValidThinkingLevel(value)) return value;
|
|
92
|
-
return void 0;
|
|
93
|
-
}
|
|
94
|
-
var RPC_CHANNELS = {
|
|
95
|
-
remote: {
|
|
96
|
-
TEST_CONNECTION: "remote:testConnection"
|
|
97
|
-
},
|
|
98
|
-
server: {
|
|
99
|
-
GET_WORKSPACES: "server:getWorkspaces",
|
|
100
|
-
CREATE_WORKSPACE: "server:createWorkspace",
|
|
101
|
-
GET_STATUS: "server:getStatus",
|
|
102
|
-
GET_HEALTH: "server:getHealth",
|
|
103
|
-
GET_ACTIVE_SESSIONS: "server:getActiveSessions",
|
|
104
|
-
SHUTTING_DOWN: "server:shuttingDown",
|
|
105
|
-
STATUS_CHANGED: "server:statusChanged",
|
|
106
|
-
HOME_DIR: "server:homeDir"
|
|
107
|
-
},
|
|
108
|
-
sessions: {
|
|
109
|
-
GET: "sessions:get",
|
|
110
|
-
GET_UNREAD_SUMMARY: "sessions:getUnreadSummary",
|
|
111
|
-
MARK_ALL_READ: "sessions:markAllRead",
|
|
112
|
-
UNREAD_SUMMARY_CHANGED: "sessions:unreadSummaryChanged",
|
|
113
|
-
CREATE: "sessions:create",
|
|
114
|
-
DELETE: "sessions:delete",
|
|
115
|
-
GET_MESSAGES: "sessions:getMessages",
|
|
116
|
-
SEND_MESSAGE: "sessions:sendMessage",
|
|
117
|
-
CANCEL: "sessions:cancel",
|
|
118
|
-
KILL_SHELL: "sessions:killShell",
|
|
119
|
-
RESPOND_TO_PERMISSION: "sessions:respondToPermission",
|
|
120
|
-
RESPOND_TO_CREDENTIAL: "sessions:respondToCredential",
|
|
121
|
-
COMMAND: "sessions:command",
|
|
122
|
-
GET_PENDING_PLAN_EXECUTION: "sessions:getPendingPlanExecution",
|
|
123
|
-
GET_PERMISSION_MODE_STATE: "sessions:getPermissionModeState",
|
|
124
|
-
EVENT: "session:event",
|
|
125
|
-
GET_MODEL: "session:getModel",
|
|
126
|
-
SET_MODEL: "session:setModel",
|
|
127
|
-
GET_FILES: "sessions:getFiles",
|
|
128
|
-
GET_NOTES: "sessions:getNotes",
|
|
129
|
-
SET_NOTES: "sessions:setNotes",
|
|
130
|
-
WATCH_FILES: "sessions:watchFiles",
|
|
131
|
-
UNWATCH_FILES: "sessions:unwatchFiles",
|
|
132
|
-
FILES_CHANGED: "sessions:filesChanged",
|
|
133
|
-
SEARCH_CONTENT: "sessions:searchContent",
|
|
134
|
-
EXPORT: "sessions:export",
|
|
135
|
-
IMPORT: "sessions:import",
|
|
136
|
-
EXPORT_REMOTE_TRANSFER: "sessions:exportRemoteTransfer",
|
|
137
|
-
IMPORT_REMOTE_TRANSFER: "sessions:importRemoteTransfer"
|
|
138
|
-
},
|
|
139
|
-
transfer: {
|
|
140
|
-
START: "transfer:start",
|
|
141
|
-
CHUNK: "transfer:chunk",
|
|
142
|
-
COMMIT: "transfer:commit",
|
|
143
|
-
ABORT: "transfer:abort"
|
|
144
|
-
},
|
|
145
|
-
tasks: {
|
|
146
|
-
GET_OUTPUT: "tasks:getOutput"
|
|
147
|
-
},
|
|
148
|
-
workspaces: {
|
|
149
|
-
GET: "workspaces:get",
|
|
150
|
-
CREATE: "workspaces:create",
|
|
151
|
-
CHECK_SLUG: "workspaces:checkSlug",
|
|
152
|
-
UPDATE_REMOTE: "workspaces:updateRemote"
|
|
153
|
-
},
|
|
154
|
-
window: {
|
|
155
|
-
GET_WORKSPACE: "window:getWorkspace",
|
|
156
|
-
GET_MODE: "window:getMode",
|
|
157
|
-
OPEN_WORKSPACE: "window:openWorkspace",
|
|
158
|
-
OPEN_SESSION_IN_NEW_WINDOW: "window:openSessionInNewWindow",
|
|
159
|
-
SWITCH_WORKSPACE: "window:switchWorkspace",
|
|
160
|
-
CLOSE: "window:close",
|
|
161
|
-
CLOSE_REQUESTED: "window:closeRequested",
|
|
162
|
-
CONFIRM_CLOSE: "window:confirmClose",
|
|
163
|
-
CANCEL_CLOSE: "window:cancelClose",
|
|
164
|
-
SET_TRAFFIC_LIGHTS: "window:setTrafficLights",
|
|
165
|
-
FOCUS_STATE: "window:focusState",
|
|
166
|
-
GET_FOCUS_STATE: "window:getFocusState"
|
|
167
|
-
},
|
|
168
|
-
file: {
|
|
169
|
-
READ: "file:read",
|
|
170
|
-
READ_DATA_URL: "file:readDataUrl",
|
|
171
|
-
READ_PREVIEW_DATA_URL: "file:readPreviewDataUrl",
|
|
172
|
-
READ_BINARY: "file:readBinary",
|
|
173
|
-
OPEN_DIALOG: "file:openDialog",
|
|
174
|
-
READ_ATTACHMENT: "file:readAttachment",
|
|
175
|
-
READ_USER_ATTACHMENT: "file:readUserAttachment",
|
|
176
|
-
STORE_ATTACHMENT: "file:storeAttachment",
|
|
177
|
-
GENERATE_THUMBNAIL: "file:generateThumbnail"
|
|
178
|
-
},
|
|
179
|
-
fs: {
|
|
180
|
-
SEARCH: "fs:search",
|
|
181
|
-
LIST_DIRECTORY: "fs:listDirectory"
|
|
182
|
-
},
|
|
183
|
-
debug: {
|
|
184
|
-
LOG: "debug:log"
|
|
185
|
-
},
|
|
186
|
-
theme: {
|
|
187
|
-
GET_SYSTEM_PREFERENCE: "theme:getSystemPreference",
|
|
188
|
-
SYSTEM_CHANGED: "theme:systemChanged",
|
|
189
|
-
APP_CHANGED: "theme:appChanged",
|
|
190
|
-
GET_APP: "theme:getApp",
|
|
191
|
-
GET_PRESETS: "theme:getPresets",
|
|
192
|
-
LOAD_PRESET: "theme:loadPreset",
|
|
193
|
-
GET_COLOR_THEME: "theme:getColorTheme",
|
|
194
|
-
SET_COLOR_THEME: "theme:setColorTheme",
|
|
195
|
-
BROADCAST_PREFERENCES: "theme:broadcastPreferences",
|
|
196
|
-
PREFERENCES_CHANGED: "theme:preferencesChanged",
|
|
197
|
-
GET_WORKSPACE_COLOR_THEME: "theme:getWorkspaceColorTheme",
|
|
198
|
-
SET_WORKSPACE_COLOR_THEME: "theme:setWorkspaceColorTheme",
|
|
199
|
-
GET_ALL_WORKSPACE_THEMES: "theme:getAllWorkspaceThemes",
|
|
200
|
-
BROADCAST_WORKSPACE_THEME: "theme:broadcastWorkspaceTheme",
|
|
201
|
-
WORKSPACE_THEME_CHANGED: "theme:workspaceThemeChanged"
|
|
202
|
-
},
|
|
203
|
-
system: {
|
|
204
|
-
VERSIONS: "system:versions",
|
|
205
|
-
HOME_DIR: "system:homeDir",
|
|
206
|
-
IS_DEBUG_MODE: "system:isDebugMode"
|
|
207
|
-
},
|
|
208
|
-
update: {
|
|
209
|
-
CHECK: "update:check",
|
|
210
|
-
GET_INFO: "update:getInfo",
|
|
211
|
-
INSTALL: "update:install",
|
|
212
|
-
DISMISS: "update:dismiss",
|
|
213
|
-
GET_DISMISSED: "update:getDismissed",
|
|
214
|
-
AVAILABLE: "update:available",
|
|
215
|
-
DOWNLOAD_PROGRESS: "update:downloadProgress"
|
|
216
|
-
},
|
|
217
|
-
shell: {
|
|
218
|
-
OPEN_URL: "shell:openUrl",
|
|
219
|
-
OPEN_FILE: "shell:openFile",
|
|
220
|
-
SHOW_IN_FOLDER: "shell:showInFolder"
|
|
221
|
-
},
|
|
222
|
-
menu: {
|
|
223
|
-
NEW_CHAT: "menu:newChat",
|
|
224
|
-
NEW_WINDOW: "menu:newWindow",
|
|
225
|
-
OPEN_SETTINGS: "menu:openSettings",
|
|
226
|
-
KEYBOARD_SHORTCUTS: "menu:keyboardShortcuts",
|
|
227
|
-
TOGGLE_FOCUS_MODE: "menu:toggleFocusMode",
|
|
228
|
-
TOGGLE_SIDEBAR: "menu:toggleSidebar",
|
|
229
|
-
QUIT: "menu:quit",
|
|
230
|
-
MINIMIZE: "menu:minimize",
|
|
231
|
-
MAXIMIZE: "menu:maximize",
|
|
232
|
-
ZOOM_IN: "menu:zoomIn",
|
|
233
|
-
ZOOM_OUT: "menu:zoomOut",
|
|
234
|
-
ZOOM_RESET: "menu:zoomReset",
|
|
235
|
-
TOGGLE_DEV_TOOLS: "menu:toggleDevTools",
|
|
236
|
-
UNDO: "menu:undo",
|
|
237
|
-
REDO: "menu:redo",
|
|
238
|
-
CUT: "menu:cut",
|
|
239
|
-
COPY: "menu:copy",
|
|
240
|
-
PASTE: "menu:paste",
|
|
241
|
-
SELECT_ALL: "menu:selectAll"
|
|
242
|
-
},
|
|
243
|
-
deeplink: {
|
|
244
|
-
NAVIGATE: "deeplink:navigate"
|
|
245
|
-
},
|
|
246
|
-
auth: {
|
|
247
|
-
LOGOUT: "auth:logout",
|
|
248
|
-
SHOW_LOGOUT_CONFIRMATION: "auth:showLogoutConfirmation",
|
|
249
|
-
SHOW_DELETE_SESSION_CONFIRMATION: "auth:showDeleteSessionConfirmation"
|
|
250
|
-
},
|
|
251
|
-
credentials: {
|
|
252
|
-
HEALTH_CHECK: "credentials:healthCheck"
|
|
253
|
-
},
|
|
254
|
-
onboarding: {
|
|
255
|
-
GET_AUTH_STATE: "onboarding:getAuthState",
|
|
256
|
-
VALIDATE_MCP: "onboarding:validateMcp",
|
|
257
|
-
START_MCP_OAUTH: "onboarding:startMcpOAuth",
|
|
258
|
-
START_CLAUDE_OAUTH: "onboarding:startClaudeOAuth",
|
|
259
|
-
EXCHANGE_CLAUDE_CODE: "onboarding:exchangeClaudeCode",
|
|
260
|
-
HAS_CLAUDE_OAUTH_STATE: "onboarding:hasClaudeOAuthState",
|
|
261
|
-
CLEAR_CLAUDE_OAUTH_STATE: "onboarding:clearClaudeOAuthState",
|
|
262
|
-
DEFER_SETUP: "onboarding:deferSetup"
|
|
263
|
-
},
|
|
264
|
-
llmConnections: {
|
|
265
|
-
LIST: "LLM_Connection:list",
|
|
266
|
-
LIST_WITH_STATUS: "LLM_Connection:listWithStatus",
|
|
267
|
-
GET: "LLM_Connection:get",
|
|
268
|
-
GET_API_KEY: "LLM_Connection:getApiKey",
|
|
269
|
-
SAVE: "LLM_Connection:save",
|
|
270
|
-
DELETE: "LLM_Connection:delete",
|
|
271
|
-
TEST: "LLM_Connection:test",
|
|
272
|
-
SET_DEFAULT: "LLM_Connection:setDefault",
|
|
273
|
-
SET_WORKSPACE_DEFAULT: "LLM_Connection:setWorkspaceDefault",
|
|
274
|
-
REFRESH_MODELS: "LLM_Connection:refreshModels",
|
|
275
|
-
CHANGED: "LLM_Connection:changed"
|
|
276
|
-
},
|
|
277
|
-
chatgpt: {
|
|
278
|
-
START_OAUTH: "chatgpt:startOAuth",
|
|
279
|
-
COMPLETE_OAUTH: "chatgpt:completeOAuth",
|
|
280
|
-
CANCEL_OAUTH: "chatgpt:cancelOAuth",
|
|
281
|
-
GET_AUTH_STATUS: "chatgpt:getAuthStatus",
|
|
282
|
-
LOGOUT: "chatgpt:logout"
|
|
283
|
-
},
|
|
284
|
-
copilot: {
|
|
285
|
-
START_OAUTH: "copilot:startOAuth",
|
|
286
|
-
CANCEL_OAUTH: "copilot:cancelOAuth",
|
|
287
|
-
GET_AUTH_STATUS: "copilot:getAuthStatus",
|
|
288
|
-
LOGOUT: "copilot:logout",
|
|
289
|
-
DEVICE_CODE: "copilot:deviceCode"
|
|
290
|
-
},
|
|
291
|
-
settings: {
|
|
292
|
-
SETUP_LLM_CONNECTION: "settings:setupLlmConnection",
|
|
293
|
-
TEST_LLM_CONNECTION_SETUP: "settings:testLlmConnectionSetup",
|
|
294
|
-
GET_DEFAULT_THINKING_LEVEL: "settings:getDefaultThinkingLevel",
|
|
295
|
-
SET_DEFAULT_THINKING_LEVEL: "settings:setDefaultThinkingLevel",
|
|
296
|
-
GET_NETWORK_PROXY: "settings:getNetworkProxy",
|
|
297
|
-
SET_NETWORK_PROXY: "settings:setNetworkProxy",
|
|
298
|
-
GET_SERVER_CONFIG: "settings:getServerConfig",
|
|
299
|
-
SET_SERVER_CONFIG: "settings:setServerConfig",
|
|
300
|
-
GET_SERVER_STATUS: "settings:getServerStatus"
|
|
301
|
-
},
|
|
302
|
-
pi: {
|
|
303
|
-
GET_API_KEY_PROVIDERS: "pi:getApiKeyProviders",
|
|
304
|
-
GET_PROVIDER_BASE_URL: "pi:getProviderBaseUrl",
|
|
305
|
-
GET_PROVIDER_MODELS: "pi:getProviderModels"
|
|
306
|
-
},
|
|
307
|
-
dialog: {
|
|
308
|
-
OPEN_FOLDER: "dialog:openFolder"
|
|
309
|
-
},
|
|
310
|
-
preferences: {
|
|
311
|
-
READ: "preferences:read",
|
|
312
|
-
WRITE: "preferences:write"
|
|
313
|
-
},
|
|
314
|
-
drafts: {
|
|
315
|
-
GET: "drafts:get",
|
|
316
|
-
SET: "drafts:set",
|
|
317
|
-
DELETE: "drafts:delete",
|
|
318
|
-
GET_ALL: "drafts:getAll"
|
|
319
|
-
},
|
|
320
|
-
sources: {
|
|
321
|
-
GET: "sources:get",
|
|
322
|
-
CREATE: "sources:create",
|
|
323
|
-
DELETE: "sources:delete",
|
|
324
|
-
START_OAUTH: "sources:startOAuth",
|
|
325
|
-
SAVE_CREDENTIALS: "sources:saveCredentials",
|
|
326
|
-
CHANGED: "sources:changed",
|
|
327
|
-
GET_PERMISSIONS: "sources:getPermissions",
|
|
328
|
-
GET_MCP_TOOLS: "sources:getMcpTools"
|
|
329
|
-
},
|
|
330
|
-
oauth: {
|
|
331
|
-
START: "oauth:start",
|
|
332
|
-
COMPLETE: "oauth:complete",
|
|
333
|
-
CANCEL: "oauth:cancel",
|
|
334
|
-
REVOKE: "oauth:revoke"
|
|
335
|
-
},
|
|
336
|
-
workspace: {
|
|
337
|
-
GET_PERMISSIONS: "workspace:getPermissions",
|
|
338
|
-
READ_IMAGE: "workspace:readImage",
|
|
339
|
-
WRITE_IMAGE: "workspace:writeImage",
|
|
340
|
-
SETTINGS_GET: "workspaceSettings:get",
|
|
341
|
-
SETTINGS_UPDATE: "workspaceSettings:update"
|
|
342
|
-
},
|
|
343
|
-
permissions: {
|
|
344
|
-
GET_DEFAULTS: "permissions:getDefaults",
|
|
345
|
-
DEFAULTS_CHANGED: "permissions:defaultsChanged"
|
|
346
|
-
},
|
|
347
|
-
skills: {
|
|
348
|
-
GET: "skills:get",
|
|
349
|
-
GET_FILES: "skills:getFiles",
|
|
350
|
-
DELETE: "skills:delete",
|
|
351
|
-
OPEN_EDITOR: "skills:openEditor",
|
|
352
|
-
OPEN_FINDER: "skills:openFinder",
|
|
353
|
-
CHANGED: "skills:changed"
|
|
354
|
-
},
|
|
355
|
-
statuses: {
|
|
356
|
-
LIST: "statuses:list",
|
|
357
|
-
REORDER: "statuses:reorder",
|
|
358
|
-
CHANGED: "statuses:changed"
|
|
359
|
-
},
|
|
360
|
-
labels: {
|
|
361
|
-
LIST: "labels:list",
|
|
362
|
-
CREATE: "labels:create",
|
|
363
|
-
DELETE: "labels:delete",
|
|
364
|
-
CHANGED: "labels:changed"
|
|
365
|
-
},
|
|
366
|
-
views: {
|
|
367
|
-
LIST: "views:list",
|
|
368
|
-
SAVE: "views:save"
|
|
369
|
-
},
|
|
370
|
-
toolIcons: {
|
|
371
|
-
GET_MAPPINGS: "toolIcons:getMappings"
|
|
372
|
-
},
|
|
373
|
-
logo: {
|
|
374
|
-
GET_URL: "logo:getUrl"
|
|
375
|
-
},
|
|
376
|
-
notification: {
|
|
377
|
-
SHOW: "notification:show",
|
|
378
|
-
NAVIGATE: "notification:navigate",
|
|
379
|
-
GET_ENABLED: "notification:getEnabled",
|
|
380
|
-
SET_ENABLED: "notification:setEnabled"
|
|
381
|
-
},
|
|
382
|
-
input: {
|
|
383
|
-
GET_AUTO_CAPITALISATION: "input:getAutoCapitalisation",
|
|
384
|
-
SET_AUTO_CAPITALISATION: "input:setAutoCapitalisation",
|
|
385
|
-
GET_SEND_MESSAGE_KEY: "input:getSendMessageKey",
|
|
386
|
-
SET_SEND_MESSAGE_KEY: "input:setSendMessageKey",
|
|
387
|
-
GET_SPELL_CHECK: "input:getSpellCheck",
|
|
388
|
-
SET_SPELL_CHECK: "input:setSpellCheck"
|
|
389
|
-
},
|
|
390
|
-
power: {
|
|
391
|
-
GET_KEEP_AWAKE: "power:getKeepAwake",
|
|
392
|
-
SET_KEEP_AWAKE: "power:setKeepAwake"
|
|
393
|
-
},
|
|
394
|
-
appearance: {
|
|
395
|
-
GET_RICH_TOOL_DESCRIPTIONS: "appearance:getRichToolDescriptions",
|
|
396
|
-
SET_RICH_TOOL_DESCRIPTIONS: "appearance:setRichToolDescriptions"
|
|
397
|
-
},
|
|
398
|
-
tools: {
|
|
399
|
-
GET_BROWSER_TOOL_ENABLED: "tools:getBrowserToolEnabled",
|
|
400
|
-
SET_BROWSER_TOOL_ENABLED: "tools:setBrowserToolEnabled"
|
|
401
|
-
},
|
|
402
|
-
caching: {
|
|
403
|
-
GET_EXTENDED_PROMPT_CACHE: "caching:getExtendedPromptCache",
|
|
404
|
-
SET_EXTENDED_PROMPT_CACHE: "caching:setExtendedPromptCache",
|
|
405
|
-
GET_ENABLE_1M_CONTEXT: "caching:getEnable1MContext",
|
|
406
|
-
SET_ENABLE_1M_CONTEXT: "caching:setEnable1MContext"
|
|
407
|
-
},
|
|
408
|
-
badge: {
|
|
409
|
-
REFRESH: "badge:refresh",
|
|
410
|
-
SET_ICON: "badge:setIcon",
|
|
411
|
-
DRAW: "badge:draw",
|
|
412
|
-
DRAW_WINDOWS: "badge:draw-windows"
|
|
413
|
-
},
|
|
414
|
-
releaseNotes: {
|
|
415
|
-
GET: "releaseNotes:get",
|
|
416
|
-
GET_LATEST_VERSION: "releaseNotes:getLatestVersion"
|
|
417
|
-
},
|
|
418
|
-
git: {
|
|
419
|
-
GET_BRANCH: "git:getBranch"
|
|
420
|
-
},
|
|
421
|
-
gitbash: {
|
|
422
|
-
CHECK: "gitbash:check",
|
|
423
|
-
BROWSE: "gitbash:browse",
|
|
424
|
-
SET_PATH: "gitbash:setPath"
|
|
425
|
-
},
|
|
426
|
-
browserPane: {
|
|
427
|
-
CREATE: "browser-pane:create",
|
|
428
|
-
DESTROY: "browser-pane:destroy",
|
|
429
|
-
LIST: "browser-pane:list",
|
|
430
|
-
NAVIGATE: "browser-pane:navigate",
|
|
431
|
-
GO_BACK: "browser-pane:go-back",
|
|
432
|
-
GO_FORWARD: "browser-pane:go-forward",
|
|
433
|
-
RELOAD: "browser-pane:reload",
|
|
434
|
-
STOP: "browser-pane:stop",
|
|
435
|
-
FOCUS: "browser-pane:focus",
|
|
436
|
-
SNAPSHOT: "browser-pane:snapshot",
|
|
437
|
-
CLICK: "browser-pane:click",
|
|
438
|
-
FILL: "browser-pane:fill",
|
|
439
|
-
SELECT: "browser-pane:select",
|
|
440
|
-
SCREENSHOT: "browser-pane:screenshot",
|
|
441
|
-
EVALUATE: "browser-pane:evaluate",
|
|
442
|
-
SCROLL: "browser-pane:scroll",
|
|
443
|
-
LAUNCH: "browser-empty-state:launch",
|
|
444
|
-
STATE_CHANGED: "browser-pane:state-changed",
|
|
445
|
-
REMOVED: "browser-pane:removed",
|
|
446
|
-
INTERACTED: "browser-pane:interacted"
|
|
447
|
-
},
|
|
448
|
-
automations: {
|
|
449
|
-
GET: "automations:get",
|
|
450
|
-
TEST: "automations:test",
|
|
451
|
-
SET_ENABLED: "automations:setEnabled",
|
|
452
|
-
DUPLICATE: "automations:duplicate",
|
|
453
|
-
DELETE: "automations:delete",
|
|
454
|
-
GET_HISTORY: "automations:getHistory",
|
|
455
|
-
GET_LAST_EXECUTED: "automations:getLastExecuted",
|
|
456
|
-
REPLAY: "automations:replay",
|
|
457
|
-
CHANGED: "automations:changed"
|
|
458
|
-
},
|
|
459
|
-
resources: {
|
|
460
|
-
EXPORT: "resources:export",
|
|
461
|
-
IMPORT: "resources:import"
|
|
462
|
-
},
|
|
463
|
-
messaging: {
|
|
464
|
-
// WhatsApp subprocess → Gateway (subprocess invokes on server)
|
|
465
|
-
WA_REGISTER: "messaging:wa:register",
|
|
466
|
-
WA_INCOMING: "messaging:wa:incoming",
|
|
467
|
-
WA_BUTTON_PRESS: "messaging:wa:buttonPress",
|
|
468
|
-
WA_STATUS: "messaging:wa:status",
|
|
469
|
-
WA_QR: "messaging:wa:qr",
|
|
470
|
-
// Gateway → WhatsApp subprocess (server invokes on client)
|
|
471
|
-
WA_SEND: "messaging:wa:send",
|
|
472
|
-
WA_SEND_BUTTONS: "messaging:wa:sendButtons",
|
|
473
|
-
WA_SEND_TYPING: "messaging:wa:sendTyping",
|
|
474
|
-
WA_SEND_FILE: "messaging:wa:sendFile",
|
|
475
|
-
WA_CONNECT: "messaging:wa:connect",
|
|
476
|
-
WA_DISCONNECT: "messaging:wa:disconnect",
|
|
477
|
-
// Gateway → UI clients (broadcast)
|
|
478
|
-
BINDING_CHANGED: "messaging:bindingChanged",
|
|
479
|
-
PLATFORM_STATUS: "messaging:platformStatus",
|
|
480
|
-
/** Broadcast when the workspace's pending-senders list mutates. */
|
|
481
|
-
PENDING_CHANGED: "messaging:pendingChanged",
|
|
482
|
-
// UI ↔ Server (config/binding CRUD)
|
|
483
|
-
GET_CONFIG: "messaging:getConfig",
|
|
484
|
-
UPDATE_CONFIG: "messaging:updateConfig",
|
|
485
|
-
TEST_TELEGRAM: "messaging:testTelegram",
|
|
486
|
-
SAVE_TELEGRAM: "messaging:saveTelegram",
|
|
487
|
-
TEST_LARK: "messaging:testLark",
|
|
488
|
-
SAVE_LARK: "messaging:saveLark",
|
|
489
|
-
DISCONNECT: "messaging:disconnect",
|
|
490
|
-
FORGET: "messaging:forget",
|
|
491
|
-
GET_BINDINGS: "messaging:getBindings",
|
|
492
|
-
GENERATE_CODE: "messaging:generateCode",
|
|
493
|
-
UNBIND: "messaging:unbind",
|
|
494
|
-
UNBIND_BINDING: "messaging:unbindBinding",
|
|
495
|
-
/** Workspace-supergroup pairing (Telegram forum support). UI ↔ Server. */
|
|
496
|
-
GENERATE_SUPERGROUP_CODE: "messaging:generateSupergroupCode",
|
|
497
|
-
GET_SUPERGROUP: "messaging:getSupergroup",
|
|
498
|
-
UNBIND_SUPERGROUP: "messaging:unbindSupergroup",
|
|
499
|
-
// UI ↔ Server — WhatsApp pairing/connection flow (Baileys subprocess adapter)
|
|
500
|
-
WA_START_CONNECT: "messaging:wa:startConnect",
|
|
501
|
-
WA_SUBMIT_PHONE: "messaging:wa:submitPhone",
|
|
502
|
-
/** Broadcast to UI clients: QR string, pairing code, status, unavailable, error. */
|
|
503
|
-
WA_UI_EVENT: "messaging:wa:uiEvent",
|
|
504
|
-
// UI ↔ Server — Access control (per-platform owners + per-binding allow-list)
|
|
505
|
-
GET_PLATFORM_OWNERS: "messaging:access:getOwners",
|
|
506
|
-
SET_PLATFORM_OWNERS: "messaging:access:setOwners",
|
|
507
|
-
GET_PLATFORM_ACCESS_MODE: "messaging:access:getMode",
|
|
508
|
-
SET_PLATFORM_ACCESS_MODE: "messaging:access:setMode",
|
|
509
|
-
GET_PENDING_SENDERS: "messaging:access:getPending",
|
|
510
|
-
DISMISS_PENDING_SENDER: "messaging:access:dismissPending",
|
|
511
|
-
ALLOW_PENDING_SENDER: "messaging:access:allowPending",
|
|
512
|
-
SET_BINDING_ACCESS: "messaging:access:setBindingAccess"
|
|
513
|
-
}
|
|
514
|
-
};
|
|
515
|
-
var SKILL_PATTERN = /\[skill:([^\]]+)\]/g;
|
|
516
|
-
var SOURCE_PATTERN = /\[source:([^\]]+)\]/g;
|
|
517
|
-
var FILE_PATTERN = /\[file:([^\]]+)\]/g;
|
|
518
|
-
var FOLDER_PATTERN = /\[folder:([^\]]+)\]/g;
|
|
519
|
-
function parseMentions(text, availableSkillSlugs, availableSourceSlugs) {
|
|
520
|
-
const skillSet = new Set(availableSkillSlugs);
|
|
521
|
-
const sourceSet = new Set(availableSourceSlugs);
|
|
522
|
-
const skills = [];
|
|
523
|
-
const invalidSkills = [];
|
|
524
|
-
const sources = [];
|
|
525
|
-
const files = [];
|
|
526
|
-
const folders = [];
|
|
527
|
-
for (const match of text.matchAll(SKILL_PATTERN)) {
|
|
528
|
-
const slug = extractSkillSlug(match[1]);
|
|
529
|
-
if (skillSet.has(slug)) {
|
|
530
|
-
if (!skills.includes(slug)) skills.push(slug);
|
|
531
|
-
} else {
|
|
532
|
-
if (!invalidSkills.includes(slug)) invalidSkills.push(slug);
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
for (const match of text.matchAll(SOURCE_PATTERN)) {
|
|
536
|
-
const slug = match[1].trim();
|
|
537
|
-
if (sourceSet.has(slug) && !sources.includes(slug)) {
|
|
538
|
-
sources.push(slug);
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
for (const match of text.matchAll(FILE_PATTERN)) {
|
|
542
|
-
const path = match[1].trim();
|
|
543
|
-
if (path && !files.includes(path)) files.push(path);
|
|
544
|
-
}
|
|
545
|
-
for (const match of text.matchAll(FOLDER_PATTERN)) {
|
|
546
|
-
const path = match[1].trim();
|
|
547
|
-
if (path && !folders.includes(path)) folders.push(path);
|
|
548
|
-
}
|
|
549
|
-
return { skills, invalidSkills, sources, files, folders };
|
|
550
|
-
}
|
|
551
|
-
function resolveSkillMentions(text, skillNames) {
|
|
552
|
-
return text.replace(SKILL_PATTERN, (full, raw) => {
|
|
553
|
-
const slug = extractSkillSlug(raw);
|
|
554
|
-
const displayName = skillNames.get(slug) ?? slug;
|
|
555
|
-
return `[Mentioned skill: ${displayName} (slug: ${slug})]`;
|
|
556
|
-
});
|
|
557
|
-
}
|
|
558
|
-
function resolveSourceMentions(text) {
|
|
559
|
-
return text.replace(SOURCE_PATTERN, (_, slug) => {
|
|
560
|
-
return `[Mentioned source: ${slug.trim()}]`;
|
|
561
|
-
});
|
|
562
|
-
}
|
|
563
|
-
async function resolvePathMentions(text, workingDirectory) {
|
|
564
|
-
const { basename } = await import("path");
|
|
565
|
-
const cwd = workingDirectory ?? process.cwd();
|
|
566
|
-
const fileMatches = [...text.matchAll(FILE_PATTERN)];
|
|
567
|
-
const folderMatches = [...text.matchAll(FOLDER_PATTERN)];
|
|
568
|
-
const fileReplacements = /* @__PURE__ */ new Map();
|
|
569
|
-
for (const match of fileMatches) {
|
|
570
|
-
const rawPath = match[1].trim();
|
|
571
|
-
const absPath = await resolvePath(rawPath, cwd);
|
|
572
|
-
const name = basename(absPath);
|
|
573
|
-
fileReplacements.set(match[0], `[Mentioned file: ${name} (at ${absPath})]`);
|
|
574
|
-
}
|
|
575
|
-
const folderReplacements = /* @__PURE__ */ new Map();
|
|
576
|
-
for (const match of folderMatches) {
|
|
577
|
-
const rawPath = match[1].trim();
|
|
578
|
-
const absPath = await resolvePath(rawPath, cwd);
|
|
579
|
-
const name = basename(absPath);
|
|
580
|
-
folderReplacements.set(match[0], `[Mentioned folder: ${name} (at ${absPath})]`);
|
|
581
|
-
}
|
|
582
|
-
let result = text;
|
|
583
|
-
for (const [original, replacement] of fileReplacements) {
|
|
584
|
-
result = result.replace(original, replacement);
|
|
585
|
-
}
|
|
586
|
-
for (const [original, replacement] of folderReplacements) {
|
|
587
|
-
result = result.replace(original, replacement);
|
|
588
|
-
}
|
|
589
|
-
return result;
|
|
590
|
-
}
|
|
591
|
-
function resolveFileMentions(text, workingDirectory) {
|
|
592
|
-
return resolvePathMentions(text, workingDirectory);
|
|
593
|
-
}
|
|
594
|
-
function stripAllMentions(text) {
|
|
595
|
-
let result = text;
|
|
596
|
-
result = result.replace(SKILL_PATTERN, (_, raw) => extractSkillSlug(raw));
|
|
597
|
-
result = result.replace(SOURCE_PATTERN, (_, slug) => slug.trim());
|
|
598
|
-
result = result.replace(FILE_PATTERN, (_, p) => p.trim());
|
|
599
|
-
result = result.replace(FOLDER_PATTERN, (_, p) => p.trim());
|
|
600
|
-
return result.replace(/\s{2,}/g, " ").trim();
|
|
601
|
-
}
|
|
602
|
-
function findMentionMatches(text, availableSkillSlugs, availableSourceSlugs) {
|
|
603
|
-
const matches = [];
|
|
604
|
-
for (const match of text.matchAll(SKILL_PATTERN)) {
|
|
605
|
-
matches.push({
|
|
606
|
-
type: "skill",
|
|
607
|
-
id: extractSkillSlug(match[1]),
|
|
608
|
-
fullMatch: match[0],
|
|
609
|
-
startIndex: match.index
|
|
610
|
-
});
|
|
611
|
-
}
|
|
612
|
-
for (const match of text.matchAll(SOURCE_PATTERN)) {
|
|
613
|
-
matches.push({
|
|
614
|
-
type: "source",
|
|
615
|
-
id: match[1].trim(),
|
|
616
|
-
fullMatch: match[0],
|
|
617
|
-
startIndex: match.index
|
|
618
|
-
});
|
|
619
|
-
}
|
|
620
|
-
for (const match of text.matchAll(FILE_PATTERN)) {
|
|
621
|
-
matches.push({
|
|
622
|
-
type: "file",
|
|
623
|
-
id: match[1].trim(),
|
|
624
|
-
fullMatch: match[0],
|
|
625
|
-
startIndex: match.index
|
|
626
|
-
});
|
|
627
|
-
}
|
|
628
|
-
for (const match of text.matchAll(FOLDER_PATTERN)) {
|
|
629
|
-
matches.push({
|
|
630
|
-
type: "folder",
|
|
631
|
-
id: match[1].trim(),
|
|
632
|
-
fullMatch: match[0],
|
|
633
|
-
startIndex: match.index
|
|
634
|
-
});
|
|
635
|
-
}
|
|
636
|
-
return matches.sort((a, b) => a.startIndex - b.startIndex);
|
|
637
|
-
}
|
|
638
|
-
function extractSkillSlug(raw) {
|
|
639
|
-
const parts = raw.trim().split(":");
|
|
640
|
-
return parts[parts.length - 1].trim();
|
|
641
|
-
}
|
|
642
|
-
async function resolvePath(path, cwd) {
|
|
643
|
-
const { resolve } = await import("path");
|
|
644
|
-
if (path.startsWith("~")) {
|
|
645
|
-
const { homedir } = await import("os");
|
|
646
|
-
return resolve(homedir(), path.slice(2));
|
|
647
|
-
}
|
|
648
|
-
if (path.startsWith("/")) return path;
|
|
649
|
-
return resolve(cwd, path);
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
// ../packages/timeline/dist/index.js
|
|
653
|
-
function createTimelineSequencer(options) {
|
|
654
|
-
let seq = options.startSeq ?? 0;
|
|
655
|
-
const now = options.now ?? Date.now;
|
|
656
|
-
return {
|
|
657
|
-
append(item, rawRef) {
|
|
658
|
-
seq += 1;
|
|
659
|
-
return appendTimelineItem({
|
|
660
|
-
sessionId: options.sessionId,
|
|
661
|
-
provider: options.provider,
|
|
662
|
-
epoch: options.epoch,
|
|
663
|
-
seq,
|
|
664
|
-
timestamp: now(),
|
|
665
|
-
item,
|
|
666
|
-
rawRef
|
|
667
|
-
});
|
|
668
|
-
}
|
|
669
|
-
};
|
|
670
|
-
}
|
|
671
|
-
function appendTimelineItem(envelope) {
|
|
672
|
-
return {
|
|
673
|
-
...envelope,
|
|
674
|
-
rawRef: envelope.rawRef ? { ...envelope.rawRef } : void 0
|
|
675
|
-
};
|
|
676
|
-
}
|
|
677
|
-
function createTimelineCursor(cursor) {
|
|
678
|
-
return {
|
|
679
|
-
epoch: cursor.epoch,
|
|
680
|
-
afterSeq: cursor.afterSeq
|
|
681
|
-
};
|
|
682
|
-
}
|
|
683
|
-
function fetchTimeline(timeline, request = {}) {
|
|
684
|
-
const ordered = sortTimeline(timeline);
|
|
685
|
-
const cursor = request.cursor ?? cursorFromTimelineStart(ordered);
|
|
686
|
-
const items = ordered.filter((item) => item.epoch === cursor.epoch && item.seq > cursor.afterSeq).slice(0, request.limit);
|
|
687
|
-
const lastSeq = items.at(-1)?.seq ?? cursor.afterSeq;
|
|
688
|
-
const firstSeq = items[0]?.seq;
|
|
689
|
-
return {
|
|
690
|
-
items,
|
|
691
|
-
nextCursor: {
|
|
692
|
-
epoch: cursor.epoch,
|
|
693
|
-
afterSeq: lastSeq
|
|
694
|
-
},
|
|
695
|
-
hasGap: firstSeq !== void 0 && firstSeq > cursor.afterSeq + 1
|
|
696
|
-
};
|
|
697
|
-
}
|
|
698
|
-
function mergeTimeline(existing, incoming) {
|
|
699
|
-
const byKey = /* @__PURE__ */ new Map();
|
|
700
|
-
for (const item of [...existing, ...incoming]) {
|
|
701
|
-
byKey.set(timelineKey(item), item);
|
|
702
|
-
}
|
|
703
|
-
return sortTimeline([...byKey.values()]);
|
|
704
|
-
}
|
|
705
|
-
function cursorFromTimelineStart(timeline) {
|
|
706
|
-
return {
|
|
707
|
-
epoch: timeline[0]?.epoch ?? "default",
|
|
708
|
-
afterSeq: 0
|
|
709
|
-
};
|
|
710
|
-
}
|
|
711
|
-
function sortTimeline(timeline) {
|
|
712
|
-
return [...timeline].sort((left, right) => {
|
|
713
|
-
if (left.epoch !== right.epoch) return left.epoch.localeCompare(right.epoch);
|
|
714
|
-
return left.seq - right.seq;
|
|
715
|
-
});
|
|
716
|
-
}
|
|
717
|
-
function timelineKey(item) {
|
|
718
|
-
return `${item.epoch}:${item.seq}`;
|
|
719
|
-
}
|
|
1
|
+
// ../packages/react/src/use-agent-session.ts
|
|
2
|
+
import { useEffect, useMemo, useRef } from "react";
|
|
720
3
|
|
|
721
4
|
// ../packages/runtime-core/dist/index.js
|
|
722
5
|
var RUNTIME_KINDS = ["native-sdk", "app-server", "compatible-sdk", "cli-fallback"];
|
|
@@ -819,203 +102,9 @@ function createRuntimeExtensionContext(context = {}) {
|
|
|
819
102
|
hostServices: context.hostServices
|
|
820
103
|
};
|
|
821
104
|
}
|
|
822
|
-
function sanitizeProviderSourceTools(sourceTools) {
|
|
823
|
-
if (!sourceTools || sourceTools.length === 0) return [];
|
|
824
|
-
const sanitized = [];
|
|
825
|
-
for (const sourceTool of sourceTools) {
|
|
826
|
-
if (sourceTool.kind === "api-source") {
|
|
827
|
-
const defaultHeaders = sourceTool.defaultHeaders ? copyNonCredentialStringRecord(sourceTool.defaultHeaders) : void 0;
|
|
828
|
-
sanitized.push({
|
|
829
|
-
kind: "api-source",
|
|
830
|
-
sourceSlug: sourceTool.sourceSlug,
|
|
831
|
-
baseUrl: sourceTool.baseUrl,
|
|
832
|
-
authType: sourceTool.authType,
|
|
833
|
-
...defaultHeaders && Object.keys(defaultHeaders).length > 0 ? { defaultHeaders } : {},
|
|
834
|
-
...sourceTool.credentialRef ? { credentialRef: sanitizeSourceCredentialRef(sourceTool.credentialRef) } : {}
|
|
835
|
-
});
|
|
836
|
-
continue;
|
|
837
|
-
}
|
|
838
|
-
if (sourceTool.kind === "local-source") {
|
|
839
|
-
sanitized.push({
|
|
840
|
-
kind: "local-source",
|
|
841
|
-
sourceSlug: sourceTool.sourceSlug,
|
|
842
|
-
path: sourceTool.path,
|
|
843
|
-
...sourceTool.format ? { format: sourceTool.format } : {}
|
|
844
|
-
});
|
|
845
|
-
continue;
|
|
846
|
-
}
|
|
847
|
-
if (sourceTool.kind === "mcp-server") {
|
|
848
|
-
const env = sourceTool.env ? copyNonCredentialStringRecord(sourceTool.env) : void 0;
|
|
849
|
-
const headers = sourceTool.headers ? copyNonCredentialStringRecord(sourceTool.headers) : void 0;
|
|
850
|
-
sanitized.push({
|
|
851
|
-
kind: "mcp-server",
|
|
852
|
-
sourceSlug: sourceTool.sourceSlug,
|
|
853
|
-
transport: sourceTool.transport,
|
|
854
|
-
...sourceTool.url ? { url: sourceTool.url } : {},
|
|
855
|
-
...sourceTool.command ? { command: sourceTool.command } : {},
|
|
856
|
-
...sourceTool.args ? { args: sourceTool.args.filter((value) => typeof value === "string") } : {},
|
|
857
|
-
...env && Object.keys(env).length > 0 ? { env } : {},
|
|
858
|
-
...headers && Object.keys(headers).length > 0 ? { headers } : {},
|
|
859
|
-
...sourceTool.credentialRef ? { credentialRef: sanitizeSourceCredentialRef(sourceTool.credentialRef) } : {}
|
|
860
|
-
});
|
|
861
|
-
}
|
|
862
|
-
}
|
|
863
|
-
return sanitized;
|
|
864
|
-
}
|
|
865
|
-
var sessionToolRequestCounter = 0;
|
|
866
|
-
async function invokeSessionTool(options) {
|
|
867
|
-
const requestId = `session-tool-${++sessionToolRequestCounter}`;
|
|
868
|
-
const origin = originFromSessionToolRequest(options.request) ?? options.commandOrigin;
|
|
869
|
-
const policyDecision = await evaluateSessionToolPolicy(options, requestId);
|
|
870
|
-
const timelineRefs = [];
|
|
871
|
-
const append = (item) => {
|
|
872
|
-
const envelope = options.appendTimeline?.(item);
|
|
873
|
-
if (envelope) {
|
|
874
|
-
timelineRefs.push({ epoch: envelope.epoch, seq: envelope.seq });
|
|
875
|
-
}
|
|
876
|
-
};
|
|
877
|
-
if (policyDecision.decision !== "allow") {
|
|
878
|
-
const reason = policyDecision.decision === "deny" ? policyDecision.reason : policyDecision.reason;
|
|
879
|
-
append({
|
|
880
|
-
type: "host_state_changed",
|
|
881
|
-
state: {
|
|
882
|
-
kind: "host_tool_denied",
|
|
883
|
-
requestId,
|
|
884
|
-
toolName: options.toolName,
|
|
885
|
-
reason
|
|
886
|
-
}
|
|
887
|
-
});
|
|
888
|
-
return {
|
|
889
|
-
ok: false,
|
|
890
|
-
requestId,
|
|
891
|
-
toolName: options.toolName,
|
|
892
|
-
origin,
|
|
893
|
-
policyDecision,
|
|
894
|
-
reason,
|
|
895
|
-
timelineRefs
|
|
896
|
-
};
|
|
897
|
-
}
|
|
898
|
-
append({
|
|
899
|
-
type: "host_state_changed",
|
|
900
|
-
state: {
|
|
901
|
-
kind: "host_tool_invoked",
|
|
902
|
-
requestId,
|
|
903
|
-
toolName: options.toolName,
|
|
904
|
-
...origin ? { origin } : {}
|
|
905
|
-
}
|
|
906
|
-
});
|
|
907
|
-
const callback = options.bridge[options.toolName];
|
|
908
|
-
if (!callback) {
|
|
909
|
-
const reason = `Session tool bridge callback is not registered: ${String(options.toolName)}`;
|
|
910
|
-
append({
|
|
911
|
-
type: "host_state_changed",
|
|
912
|
-
state: {
|
|
913
|
-
kind: "host_tool_result",
|
|
914
|
-
requestId,
|
|
915
|
-
toolName: options.toolName,
|
|
916
|
-
ok: false,
|
|
917
|
-
reason
|
|
918
|
-
}
|
|
919
|
-
});
|
|
920
|
-
return {
|
|
921
|
-
ok: false,
|
|
922
|
-
requestId,
|
|
923
|
-
toolName: options.toolName,
|
|
924
|
-
origin,
|
|
925
|
-
policyDecision,
|
|
926
|
-
reason,
|
|
927
|
-
timelineRefs
|
|
928
|
-
};
|
|
929
|
-
}
|
|
930
|
-
try {
|
|
931
|
-
const result = await callback(options.request);
|
|
932
|
-
append({
|
|
933
|
-
type: "host_state_changed",
|
|
934
|
-
state: {
|
|
935
|
-
kind: "host_tool_result",
|
|
936
|
-
requestId,
|
|
937
|
-
toolName: options.toolName,
|
|
938
|
-
ok: true
|
|
939
|
-
}
|
|
940
|
-
});
|
|
941
|
-
return {
|
|
942
|
-
ok: true,
|
|
943
|
-
requestId,
|
|
944
|
-
toolName: options.toolName,
|
|
945
|
-
origin,
|
|
946
|
-
policyDecision,
|
|
947
|
-
result,
|
|
948
|
-
timelineRefs
|
|
949
|
-
};
|
|
950
|
-
} catch (error) {
|
|
951
|
-
const reason = error instanceof Error ? error.message : String(error);
|
|
952
|
-
append({
|
|
953
|
-
type: "host_state_changed",
|
|
954
|
-
state: {
|
|
955
|
-
kind: "host_tool_result",
|
|
956
|
-
requestId,
|
|
957
|
-
toolName: options.toolName,
|
|
958
|
-
ok: false,
|
|
959
|
-
reason
|
|
960
|
-
}
|
|
961
|
-
});
|
|
962
|
-
return {
|
|
963
|
-
ok: false,
|
|
964
|
-
requestId,
|
|
965
|
-
toolName: options.toolName,
|
|
966
|
-
origin,
|
|
967
|
-
policyDecision,
|
|
968
|
-
reason,
|
|
969
|
-
timelineRefs
|
|
970
|
-
};
|
|
971
|
-
}
|
|
972
|
-
}
|
|
973
|
-
async function evaluateSessionToolPolicy(options, requestId) {
|
|
974
|
-
if (!options.policy) return { decision: "allow" };
|
|
975
|
-
return options.policy({
|
|
976
|
-
toolName: `host.${String(options.toolName)}`,
|
|
977
|
-
input: recordFromSessionToolRequest(options.request),
|
|
978
|
-
toolIntent: { kind: "unknown", toolName: `host.${String(options.toolName)}` },
|
|
979
|
-
scope: { type: "session", sessionId: options.sessionId }
|
|
980
|
-
});
|
|
981
|
-
}
|
|
982
|
-
function originFromSessionToolRequest(request) {
|
|
983
|
-
const record = recordFromSessionToolRequest(request);
|
|
984
|
-
const origin = record.origin ?? record.commandOrigin;
|
|
985
|
-
return isCommandOrigin(origin) ? origin : void 0;
|
|
986
|
-
}
|
|
987
|
-
function recordFromSessionToolRequest(request) {
|
|
988
|
-
return request && typeof request === "object" ? { ...request } : {};
|
|
989
|
-
}
|
|
990
|
-
function isCommandOrigin(value) {
|
|
991
|
-
if (!value || typeof value !== "object") return false;
|
|
992
|
-
const type = value.type;
|
|
993
|
-
return type === "user" || type === "automation" || type === "scheduler" || type === "host" || type === "replay" || type === "system";
|
|
994
|
-
}
|
|
995
105
|
function unique(values) {
|
|
996
106
|
return [...new Set(values)];
|
|
997
107
|
}
|
|
998
|
-
function sanitizeSourceCredentialRef(credentialRef) {
|
|
999
|
-
return {
|
|
1000
|
-
type: credentialRef.type,
|
|
1001
|
-
sourceSlug: credentialRef.sourceSlug,
|
|
1002
|
-
...credentialRef.workspaceId ? { workspaceId: credentialRef.workspaceId } : {}
|
|
1003
|
-
};
|
|
1004
|
-
}
|
|
1005
|
-
function copyStringRecord(record) {
|
|
1006
|
-
return Object.fromEntries(
|
|
1007
|
-
Object.entries(record).filter((entry) => typeof entry[0] === "string" && typeof entry[1] === "string")
|
|
1008
|
-
);
|
|
1009
|
-
}
|
|
1010
|
-
function copyNonCredentialStringRecord(record) {
|
|
1011
|
-
return Object.fromEntries(
|
|
1012
|
-
Object.entries(copyStringRecord(record)).filter(([key]) => !isCredentialKey(key))
|
|
1013
|
-
);
|
|
1014
|
-
}
|
|
1015
|
-
function isCredentialKey(key) {
|
|
1016
|
-
const normalized = key.toLowerCase();
|
|
1017
|
-
return normalized === "authorization" || normalized === "proxy-authorization" || normalized === "cookie" || normalized === "set-cookie" || normalized.includes("api-key") || normalized.includes("apikey") || normalized.includes("token") || normalized.includes("secret") || normalized.includes("password");
|
|
1018
|
-
}
|
|
1019
108
|
function findCandidate(candidates, kind) {
|
|
1020
109
|
return candidates.find((candidate) => candidate.kind === kind);
|
|
1021
110
|
}
|
|
@@ -1101,463 +190,51 @@ function normalizeExtensionCapabilities(capabilities = {}) {
|
|
|
1101
190
|
};
|
|
1102
191
|
}
|
|
1103
192
|
|
|
1104
|
-
// ../packages/
|
|
1105
|
-
|
|
1106
|
-
var DANGEROUS_BASH_COMMANDS = /* @__PURE__ */ new Set([
|
|
1107
|
-
"rm",
|
|
1108
|
-
"rmdir",
|
|
1109
|
-
"sudo",
|
|
1110
|
-
"su",
|
|
1111
|
-
"chmod",
|
|
1112
|
-
"chown",
|
|
1113
|
-
"chgrp",
|
|
1114
|
-
"mv",
|
|
1115
|
-
"cp",
|
|
1116
|
-
"dd",
|
|
1117
|
-
"mkfs",
|
|
1118
|
-
"fdisk",
|
|
1119
|
-
"parted",
|
|
1120
|
-
"kill",
|
|
1121
|
-
"killall",
|
|
1122
|
-
"pkill",
|
|
1123
|
-
"reboot",
|
|
1124
|
-
"shutdown",
|
|
1125
|
-
"halt",
|
|
1126
|
-
"poweroff",
|
|
1127
|
-
"curl",
|
|
1128
|
-
"wget",
|
|
1129
|
-
"ssh",
|
|
1130
|
-
"scp",
|
|
1131
|
-
"rsync"
|
|
1132
|
-
]);
|
|
1133
|
-
var READ_ONLY_BASH_PATTERNS = [
|
|
1134
|
-
/^git\s+status(\s|$)/,
|
|
1135
|
-
/^git\s+diff(\s|$)/,
|
|
1136
|
-
/^git\s+log(\s|$)/,
|
|
1137
|
-
/^ls(\s|$)/,
|
|
1138
|
-
/^pwd(\s|$)/,
|
|
1139
|
-
/^cat\s+/,
|
|
1140
|
-
/^sed\s+-n\s+/,
|
|
1141
|
-
/^rg(\s|$)/,
|
|
1142
|
-
/^find\s+/
|
|
1143
|
-
];
|
|
1144
|
-
function createPermissionPolicy(options = {}) {
|
|
1145
|
-
return {
|
|
1146
|
-
mode: options.mode ?? "ask",
|
|
1147
|
-
alwaysAllow: [...options.alwaysAllow ?? []],
|
|
1148
|
-
approvals: [...options.approvals ?? []],
|
|
1149
|
-
layers: [...options.layers ?? []]
|
|
1150
|
-
};
|
|
1151
|
-
}
|
|
1152
|
-
function createSourcePolicyLayer(options) {
|
|
1153
|
-
return {
|
|
1154
|
-
id: options.id ?? `source:${options.sourceSlug}`,
|
|
1155
|
-
rules: {
|
|
1156
|
-
...options.rules,
|
|
1157
|
-
allowedMcpPatterns: options.rules.allowedMcpPatterns?.map(
|
|
1158
|
-
(pattern) => scopeMcpPatternToSource(options.sourceSlug, pattern)
|
|
1159
|
-
)
|
|
1160
|
-
}
|
|
1161
|
-
};
|
|
1162
|
-
}
|
|
1163
|
-
function validatePolicyConfig(input) {
|
|
1164
|
-
const errors = [];
|
|
1165
|
-
const warnings = [];
|
|
1166
|
-
const config = asRecord(input);
|
|
1167
|
-
const mode = config.mode;
|
|
1168
|
-
if (mode !== void 0 && !isPermissionMode(mode)) {
|
|
1169
|
-
errors.push({
|
|
1170
|
-
path: "mode",
|
|
1171
|
-
message: `Invalid permission mode: ${String(mode)}`,
|
|
1172
|
-
suggestion: "Use one of: safe, ask, allow-all"
|
|
1173
|
-
});
|
|
1174
|
-
}
|
|
1175
|
-
if (config.layers !== void 0 && !Array.isArray(config.layers)) {
|
|
1176
|
-
errors.push({
|
|
1177
|
-
path: "layers",
|
|
1178
|
-
message: "Expected layers to be an array"
|
|
1179
|
-
});
|
|
1180
|
-
}
|
|
1181
|
-
if (Array.isArray(config.layers)) {
|
|
1182
|
-
config.layers.forEach((layerValue, layerIndex) => {
|
|
1183
|
-
const layer = asRecord(layerValue);
|
|
1184
|
-
const basePath = `layers[${layerIndex}]`;
|
|
1185
|
-
if (typeof layer.id !== "string" || layer.id.length === 0) {
|
|
1186
|
-
errors.push({
|
|
1187
|
-
path: `${basePath}.id`,
|
|
1188
|
-
message: "Layer id is required"
|
|
1189
|
-
});
|
|
1190
|
-
}
|
|
1191
|
-
validateRuleSet(layer.rules, `${basePath}.rules`, errors);
|
|
1192
|
-
});
|
|
1193
|
-
}
|
|
1194
|
-
return {
|
|
1195
|
-
valid: errors.length === 0,
|
|
1196
|
-
errors,
|
|
1197
|
-
warnings
|
|
1198
|
-
};
|
|
1199
|
-
}
|
|
1200
|
-
function createPermissionPolicyFromConfig(input) {
|
|
1201
|
-
const validation = validatePolicyConfig(input);
|
|
1202
|
-
if (!validation.valid) return { validation };
|
|
1203
|
-
const config = asRecord(input);
|
|
1204
|
-
return {
|
|
1205
|
-
validation,
|
|
1206
|
-
policy: createPermissionPolicy({
|
|
1207
|
-
mode: config.mode,
|
|
1208
|
-
alwaysAllow: config.alwaysAllow,
|
|
1209
|
-
approvals: config.approvals,
|
|
1210
|
-
layers: (config.layers ?? []).map(
|
|
1211
|
-
(layer) => layer.sourceSlug ? createSourcePolicyLayer({
|
|
1212
|
-
id: layer.id,
|
|
1213
|
-
sourceSlug: layer.sourceSlug,
|
|
1214
|
-
rules: layer.rules
|
|
1215
|
-
}) : {
|
|
1216
|
-
id: layer.id,
|
|
1217
|
-
rules: layer.rules,
|
|
1218
|
-
scope: layer.scope
|
|
1219
|
-
}
|
|
1220
|
-
)
|
|
1221
|
-
})
|
|
1222
|
-
};
|
|
1223
|
-
}
|
|
1224
|
-
function evaluateToolPolicy(policy, request) {
|
|
1225
|
-
const explanation = explainToolPolicy(policy, request);
|
|
1226
|
-
if (explanation.decision === "allow") return { decision: "allow" };
|
|
193
|
+
// ../packages/timeline/dist/index.js
|
|
194
|
+
function createTimelineCursor(cursor) {
|
|
1227
195
|
return {
|
|
1228
|
-
|
|
1229
|
-
|
|
196
|
+
epoch: cursor.epoch,
|
|
197
|
+
afterSeq: cursor.afterSeq
|
|
1230
198
|
};
|
|
1231
199
|
}
|
|
1232
|
-
function
|
|
1233
|
-
const
|
|
1234
|
-
const
|
|
200
|
+
function fetchTimeline(timeline, request = {}) {
|
|
201
|
+
const ordered = sortTimeline(timeline);
|
|
202
|
+
const cursor = request.cursor ?? cursorFromTimelineStart(ordered);
|
|
203
|
+
const items = ordered.filter((item) => item.epoch === cursor.epoch && item.seq > cursor.afterSeq).slice(0, request.limit);
|
|
204
|
+
const lastSeq = items.at(-1)?.seq ?? cursor.afterSeq;
|
|
205
|
+
const firstSeq = items[0]?.seq;
|
|
1235
206
|
return {
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
...options.origin ? { origin: options.origin } : {},
|
|
1243
|
-
...options.ttl !== void 0 ? { ttl: options.ttl } : {},
|
|
1244
|
-
...explanation.hint ? { hint: explanation.hint } : {},
|
|
1245
|
-
...options.timelineRefs ? { timelineRefs: options.timelineRefs } : {}
|
|
207
|
+
items,
|
|
208
|
+
nextCursor: {
|
|
209
|
+
epoch: cursor.epoch,
|
|
210
|
+
afterSeq: lastSeq
|
|
211
|
+
},
|
|
212
|
+
hasGap: firstSeq !== void 0 && firstSeq > cursor.afterSeq + 1
|
|
1246
213
|
};
|
|
1247
214
|
}
|
|
1248
|
-
function
|
|
1249
|
-
const
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
}
|
|
1253
|
-
if (matchesAlwaysAllow(policy, request)) {
|
|
1254
|
-
return { decision: "allow", intent };
|
|
1255
|
-
}
|
|
1256
|
-
if (policy.mode === "allow-all") {
|
|
1257
|
-
return { decision: "allow", intent };
|
|
1258
|
-
}
|
|
1259
|
-
const layeredAllow = findLayeredAllow(policy, intent, request.scope);
|
|
1260
|
-
if (layeredAllow) {
|
|
1261
|
-
return {
|
|
1262
|
-
decision: "allow",
|
|
1263
|
-
intent,
|
|
1264
|
-
matchedRule: layeredAllow
|
|
1265
|
-
};
|
|
1266
|
-
}
|
|
1267
|
-
if (intent.kind === "file_write") {
|
|
1268
|
-
if (policy.mode === "ask") {
|
|
1269
|
-
return {
|
|
1270
|
-
decision: "ask",
|
|
1271
|
-
reason: `${intent.toolName} requires approval in ask mode`,
|
|
1272
|
-
intent
|
|
1273
|
-
};
|
|
1274
|
-
}
|
|
1275
|
-
return {
|
|
1276
|
-
decision: "deny",
|
|
1277
|
-
reason: `${intent.toolName} is blocked in safe mode`,
|
|
1278
|
-
intent
|
|
1279
|
-
};
|
|
1280
|
-
}
|
|
1281
|
-
if (intent.kind === "bash") {
|
|
1282
|
-
return evaluateBashPolicy(policy, intent);
|
|
1283
|
-
}
|
|
1284
|
-
if (intent.kind === "mcp" && policy.mode === "safe") {
|
|
1285
|
-
return {
|
|
1286
|
-
decision: "deny",
|
|
1287
|
-
reason: `MCP tool is blocked in safe mode: ${intent.name}`,
|
|
1288
|
-
intent
|
|
1289
|
-
};
|
|
1290
|
-
}
|
|
1291
|
-
if (intent.kind === "api" && policy.mode === "safe") {
|
|
1292
|
-
return {
|
|
1293
|
-
decision: "deny",
|
|
1294
|
-
reason: `API endpoint is blocked in safe mode: ${intent.method} ${intent.path}`,
|
|
1295
|
-
intent
|
|
1296
|
-
};
|
|
215
|
+
function mergeTimeline(existing, incoming) {
|
|
216
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
217
|
+
for (const item of [...existing, ...incoming]) {
|
|
218
|
+
byKey.set(timelineKey(item), item);
|
|
1297
219
|
}
|
|
1298
|
-
return
|
|
220
|
+
return sortTimeline([...byKey.values()]);
|
|
1299
221
|
}
|
|
1300
|
-
function
|
|
1301
|
-
const approvals = /* @__PURE__ */ new Map();
|
|
1302
|
-
const now = options.now ?? Date.now;
|
|
222
|
+
function cursorFromTimelineStart(timeline) {
|
|
1303
223
|
return {
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
...approval,
|
|
1307
|
-
createdAt: approval.createdAt ?? now()
|
|
1308
|
-
});
|
|
1309
|
-
},
|
|
1310
|
-
revoke(id) {
|
|
1311
|
-
approvals.delete(id);
|
|
1312
|
-
},
|
|
1313
|
-
snapshot() {
|
|
1314
|
-
const currentTime = now();
|
|
1315
|
-
return [...approvals.values()].filter((approval) => !approval.expiresAt || approval.expiresAt > currentTime);
|
|
1316
|
-
}
|
|
224
|
+
epoch: timeline[0]?.epoch ?? "default",
|
|
225
|
+
afterSeq: 0
|
|
1317
226
|
};
|
|
1318
227
|
}
|
|
1319
|
-
function
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
function matchesAlwaysAllow(policy, request) {
|
|
1324
|
-
const requestScope = scopeKey(request.scope);
|
|
1325
|
-
return policy.alwaysAllow.some((rule) => {
|
|
1326
|
-
if (rule.toolName !== request.toolName) return false;
|
|
1327
|
-
if (!rule.scope) return true;
|
|
1328
|
-
return scopeKey(rule.scope) === requestScope;
|
|
1329
|
-
});
|
|
1330
|
-
}
|
|
1331
|
-
function scopeKey(scope) {
|
|
1332
|
-
if (!scope) return "global";
|
|
1333
|
-
if (typeof scope === "string") return scope;
|
|
1334
|
-
switch (scope.type) {
|
|
1335
|
-
case "session":
|
|
1336
|
-
return `session:${scope.sessionId}`;
|
|
1337
|
-
case "workspace":
|
|
1338
|
-
return `workspace:${scope.workspaceId}`;
|
|
1339
|
-
case "source":
|
|
1340
|
-
return `source:${scope.sourceSlug}`;
|
|
1341
|
-
case "skill":
|
|
1342
|
-
return `skill:${scope.skillSlug}`;
|
|
1343
|
-
case "automation":
|
|
1344
|
-
return `automation:${scope.automationId}`;
|
|
1345
|
-
case "tool-call":
|
|
1346
|
-
return `tool-call:${scope.callId}`;
|
|
1347
|
-
}
|
|
1348
|
-
}
|
|
1349
|
-
function evaluateBashPolicy(policy, intent) {
|
|
1350
|
-
if (intent.kind !== "bash") {
|
|
1351
|
-
return { decision: "allow", intent };
|
|
1352
|
-
}
|
|
1353
|
-
if (policy.mode === "ask" && DANGEROUS_BASH_COMMANDS.has(intent.baseCommand)) {
|
|
1354
|
-
return {
|
|
1355
|
-
decision: "ask",
|
|
1356
|
-
reason: `${intent.baseCommand} requires approval in ask mode`,
|
|
1357
|
-
intent
|
|
1358
|
-
};
|
|
1359
|
-
}
|
|
1360
|
-
if (policy.mode === "safe") {
|
|
1361
|
-
const layeredAllow = findLayeredAllow(policy, intent);
|
|
1362
|
-
const readOnly = READ_ONLY_BASH_PATTERNS.some((pattern) => pattern.test(intent.command.trim()));
|
|
1363
|
-
if (!readOnly) {
|
|
1364
|
-
const hint = findBlockedCommandHint(policy, intent);
|
|
1365
|
-
return {
|
|
1366
|
-
decision: "deny",
|
|
1367
|
-
reason: `Bash command is blocked in safe mode: ${intent.baseCommand || "unknown command"}`,
|
|
1368
|
-
intent,
|
|
1369
|
-
hint: hint?.reason,
|
|
1370
|
-
matchedRule: hint?.match,
|
|
1371
|
-
...hint?.tryInstead?.length ? { tryInstead: hint.tryInstead } : {},
|
|
1372
|
-
...hint?.context ? { hintContext: hint.context } : {}
|
|
1373
|
-
};
|
|
1374
|
-
}
|
|
1375
|
-
if (layeredAllow) {
|
|
1376
|
-
return { decision: "allow", intent, matchedRule: layeredAllow };
|
|
1377
|
-
}
|
|
1378
|
-
}
|
|
1379
|
-
return { decision: "allow", intent };
|
|
1380
|
-
}
|
|
1381
|
-
function normalizeToolIntent(request) {
|
|
1382
|
-
if (request.toolIntent) return request.toolIntent;
|
|
1383
|
-
if (request.toolName === "Bash") {
|
|
1384
|
-
const command = String(request.input?.command ?? "");
|
|
1385
|
-
const baseCommand = command.trim().split(/\s+/)[0] ?? "";
|
|
1386
|
-
return { kind: "bash", command, baseCommand };
|
|
1387
|
-
}
|
|
1388
|
-
if (FILE_WRITE_TOOLS.has(request.toolName)) {
|
|
1389
|
-
return {
|
|
1390
|
-
kind: "file_write",
|
|
1391
|
-
toolName: request.toolName,
|
|
1392
|
-
path: String(request.input?.file_path ?? request.input?.path ?? "")
|
|
1393
|
-
};
|
|
1394
|
-
}
|
|
1395
|
-
if (request.toolName === "MCP") {
|
|
1396
|
-
return {
|
|
1397
|
-
kind: "mcp",
|
|
1398
|
-
name: String(request.input?.name ?? request.input?.toolName ?? request.input?.tool ?? "")
|
|
1399
|
-
};
|
|
1400
|
-
}
|
|
1401
|
-
if (request.toolName === "API") {
|
|
1402
|
-
const url = request.input?.url ? String(request.input.url) : void 0;
|
|
1403
|
-
return {
|
|
1404
|
-
kind: "api",
|
|
1405
|
-
method: String(request.input?.method ?? "GET").toUpperCase(),
|
|
1406
|
-
path: pathFromUrl(url ?? String(request.input?.path ?? "/")),
|
|
1407
|
-
url
|
|
1408
|
-
};
|
|
1409
|
-
}
|
|
1410
|
-
return { kind: "unknown", toolName: request.toolName };
|
|
1411
|
-
}
|
|
1412
|
-
function findLayeredAllow(policy, intent, scope) {
|
|
1413
|
-
for (const layer of policy.layers) {
|
|
1414
|
-
if (layer.scope && scopeKey(layer.scope) !== scopeKey(scope)) continue;
|
|
1415
|
-
const match = matchLayerRules(layer, intent);
|
|
1416
|
-
if (match) return match;
|
|
1417
|
-
}
|
|
1418
|
-
return void 0;
|
|
1419
|
-
}
|
|
1420
|
-
function matchLayerRules(layer, intent) {
|
|
1421
|
-
if (intent.kind === "file_write") {
|
|
1422
|
-
const pattern = layer.rules.allowedWritePaths?.find((rule) => globMatches(rule, intent.path));
|
|
1423
|
-
return pattern ? { layerId: layer.id, ruleType: "write-path", pattern } : void 0;
|
|
1424
|
-
}
|
|
1425
|
-
if (intent.kind === "mcp") {
|
|
1426
|
-
const pattern = layer.rules.allowedMcpPatterns?.find((rule) => regexMatches(rule, intent.name));
|
|
1427
|
-
return pattern ? { layerId: layer.id, ruleType: "mcp-pattern", pattern } : void 0;
|
|
1428
|
-
}
|
|
1429
|
-
if (intent.kind === "api") {
|
|
1430
|
-
const rule = layer.rules.allowedApiEndpoints?.find((candidate) => candidate.method.toUpperCase() === intent.method && globMatches(candidate.pattern, intent.path));
|
|
1431
|
-
return rule ? { layerId: layer.id, ruleType: "api-endpoint", pattern: `${rule.method.toUpperCase()} ${rule.pattern}` } : void 0;
|
|
1432
|
-
}
|
|
1433
|
-
if (intent.kind === "bash") {
|
|
1434
|
-
const pattern = layer.rules.allowedBashPatterns?.find((rule) => regexMatches(rule, intent.command));
|
|
1435
|
-
return pattern ? { layerId: layer.id, ruleType: "bash-pattern", pattern } : void 0;
|
|
1436
|
-
}
|
|
1437
|
-
return void 0;
|
|
1438
|
-
}
|
|
1439
|
-
function findBlockedCommandHint(policy, intent) {
|
|
1440
|
-
for (const layer of policy.layers) {
|
|
1441
|
-
const hint = layer.rules.blockedCommandHints?.find((rule) => {
|
|
1442
|
-
if (rule.command !== intent.baseCommand) return false;
|
|
1443
|
-
if (!rule.whenNotMatching) return true;
|
|
1444
|
-
return !regexMatches(rule.whenNotMatching, intent.command);
|
|
1445
|
-
});
|
|
1446
|
-
if (hint) {
|
|
1447
|
-
return {
|
|
1448
|
-
reason: hint.reason,
|
|
1449
|
-
match: {
|
|
1450
|
-
layerId: layer.id,
|
|
1451
|
-
ruleType: "blocked-command-hint",
|
|
1452
|
-
pattern: hint.command
|
|
1453
|
-
},
|
|
1454
|
-
...hint.tryInstead?.length ? { tryInstead: hint.tryInstead } : {},
|
|
1455
|
-
...hint.context ? { context: hint.context } : {}
|
|
1456
|
-
};
|
|
1457
|
-
}
|
|
1458
|
-
}
|
|
1459
|
-
return void 0;
|
|
1460
|
-
}
|
|
1461
|
-
function pathFromUrl(value) {
|
|
1462
|
-
try {
|
|
1463
|
-
return new URL(value).pathname;
|
|
1464
|
-
} catch {
|
|
1465
|
-
return value.startsWith("/") ? value : `/${value}`;
|
|
1466
|
-
}
|
|
1467
|
-
}
|
|
1468
|
-
function regexMatches(pattern, value) {
|
|
1469
|
-
try {
|
|
1470
|
-
return new RegExp(pattern).test(value);
|
|
1471
|
-
} catch {
|
|
1472
|
-
return pattern === value;
|
|
1473
|
-
}
|
|
1474
|
-
}
|
|
1475
|
-
function globMatches(pattern, value) {
|
|
1476
|
-
const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*\*/g, "__DOUBLE_STAR__").replace(/\*/g, "[^/]*").replace(/__DOUBLE_STAR__/g, ".*");
|
|
1477
|
-
return new RegExp(`^${escaped}$`).test(value);
|
|
1478
|
-
}
|
|
1479
|
-
function scopeMcpPatternToSource(sourceSlug, pattern) {
|
|
1480
|
-
if (pattern.includes("mcp__")) return pattern;
|
|
1481
|
-
return `^mcp__${escapeRegex(sourceSlug)}__.*${pattern}`;
|
|
1482
|
-
}
|
|
1483
|
-
function escapeRegex(value) {
|
|
1484
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1485
|
-
}
|
|
1486
|
-
function validateRuleSet(rulesValue, path, errors) {
|
|
1487
|
-
if (rulesValue === void 0) {
|
|
1488
|
-
errors.push({
|
|
1489
|
-
path,
|
|
1490
|
-
message: "Layer rules are required"
|
|
1491
|
-
});
|
|
1492
|
-
return;
|
|
1493
|
-
}
|
|
1494
|
-
const rules = asRecord(rulesValue);
|
|
1495
|
-
validateRegexList(rules.allowedBashPatterns, `${path}.allowedBashPatterns`, errors);
|
|
1496
|
-
validateRegexList(rules.allowedMcpPatterns, `${path}.allowedMcpPatterns`, errors);
|
|
1497
|
-
validateApiEndpointRules(rules.allowedApiEndpoints, `${path}.allowedApiEndpoints`, errors);
|
|
1498
|
-
}
|
|
1499
|
-
function validateRegexList(value, path, errors) {
|
|
1500
|
-
if (value === void 0) return;
|
|
1501
|
-
if (!Array.isArray(value)) {
|
|
1502
|
-
errors.push({ path, message: "Expected an array of regular expression strings" });
|
|
1503
|
-
return;
|
|
1504
|
-
}
|
|
1505
|
-
value.forEach((pattern, index) => {
|
|
1506
|
-
if (typeof pattern !== "string") {
|
|
1507
|
-
errors.push({ path: `${path}[${index}]`, message: "Expected a regular expression string" });
|
|
1508
|
-
return;
|
|
1509
|
-
}
|
|
1510
|
-
if (!isValidRegex(pattern)) {
|
|
1511
|
-
errors.push({
|
|
1512
|
-
path: `${path}[${index}]`,
|
|
1513
|
-
message: `Invalid regular expression: ${pattern}`
|
|
1514
|
-
});
|
|
1515
|
-
}
|
|
1516
|
-
});
|
|
1517
|
-
}
|
|
1518
|
-
function validateApiEndpointRules(value, path, errors) {
|
|
1519
|
-
if (value === void 0) return;
|
|
1520
|
-
if (!Array.isArray(value)) {
|
|
1521
|
-
errors.push({ path, message: "Expected an array of API endpoint rules" });
|
|
1522
|
-
return;
|
|
1523
|
-
}
|
|
1524
|
-
value.forEach((ruleValue, index) => {
|
|
1525
|
-
const rule = asRecord(ruleValue);
|
|
1526
|
-
const method = rule.method;
|
|
1527
|
-
if (typeof method !== "string" || !HTTP_METHODS.has(method.toUpperCase())) {
|
|
1528
|
-
errors.push({
|
|
1529
|
-
path: `${path}[${index}].method`,
|
|
1530
|
-
message: `Invalid HTTP method: ${String(method)}`,
|
|
1531
|
-
suggestion: "Use one of: GET, POST, PUT, PATCH, DELETE"
|
|
1532
|
-
});
|
|
1533
|
-
}
|
|
1534
|
-
if (typeof rule.pattern !== "string") {
|
|
1535
|
-
errors.push({
|
|
1536
|
-
path: `${path}[${index}].pattern`,
|
|
1537
|
-
message: "API endpoint pattern is required"
|
|
1538
|
-
});
|
|
1539
|
-
}
|
|
228
|
+
function sortTimeline(timeline) {
|
|
229
|
+
return [...timeline].sort((left, right) => {
|
|
230
|
+
if (left.epoch !== right.epoch) return left.epoch.localeCompare(right.epoch);
|
|
231
|
+
return left.seq - right.seq;
|
|
1540
232
|
});
|
|
1541
233
|
}
|
|
1542
|
-
function
|
|
1543
|
-
return
|
|
1544
|
-
}
|
|
1545
|
-
var HTTP_METHODS = /* @__PURE__ */ new Set(["GET", "POST", "PUT", "PATCH", "DELETE"]);
|
|
1546
|
-
function isValidRegex(pattern) {
|
|
1547
|
-
try {
|
|
1548
|
-
new RegExp(pattern);
|
|
1549
|
-
return true;
|
|
1550
|
-
} catch {
|
|
1551
|
-
return false;
|
|
1552
|
-
}
|
|
1553
|
-
}
|
|
1554
|
-
function asRecord(value) {
|
|
1555
|
-
return value && typeof value === "object" ? value : {};
|
|
234
|
+
function timelineKey(item) {
|
|
235
|
+
return `${item.epoch}:${item.seq}`;
|
|
1556
236
|
}
|
|
1557
237
|
|
|
1558
|
-
// src/index.ts
|
|
1559
|
-
import { useAgentSession } from "@percena/weft-react";
|
|
1560
|
-
|
|
1561
238
|
// ../packages/client/dist/index.js
|
|
1562
239
|
var FlitroHttpClient = class {
|
|
1563
240
|
baseUrl;
|
|
@@ -2218,6 +895,109 @@ var PushTimelineStream = class {
|
|
|
2218
895
|
}
|
|
2219
896
|
};
|
|
2220
897
|
|
|
898
|
+
// ../packages/react/src/use-agent-session.ts
|
|
899
|
+
function useAgentSession(options) {
|
|
900
|
+
const onTokenExpiredRef = useRef(options.onTokenExpired);
|
|
901
|
+
onTokenExpiredRef.current = options.onTokenExpired;
|
|
902
|
+
const tokenRef = useRef(options.token);
|
|
903
|
+
tokenRef.current = options.token;
|
|
904
|
+
const runtime = useMemo(() => {
|
|
905
|
+
return createDeferredAgentRuntime({
|
|
906
|
+
provider: "flitro",
|
|
907
|
+
runtimeKind: "app-server",
|
|
908
|
+
sessionId: options.sessionId,
|
|
909
|
+
createRuntime: () => createFlitroEmbedRuntime({
|
|
910
|
+
baseUrl: options.server,
|
|
911
|
+
token: tokenRef.current,
|
|
912
|
+
sessionId: options.sessionId,
|
|
913
|
+
onTokenExpired: () => onTokenExpiredRef.current?.()
|
|
914
|
+
})
|
|
915
|
+
});
|
|
916
|
+
}, [options.server, options.sessionId]);
|
|
917
|
+
useEffect(() => {
|
|
918
|
+
return () => {
|
|
919
|
+
void runtime.disposeIfCreated();
|
|
920
|
+
};
|
|
921
|
+
}, [runtime]);
|
|
922
|
+
return { runtime, sessionId: options.sessionId, server: options.server };
|
|
923
|
+
}
|
|
924
|
+
function createDeferredAgentRuntime(options) {
|
|
925
|
+
let runtime = null;
|
|
926
|
+
let disposed = false;
|
|
927
|
+
const getRuntime = () => {
|
|
928
|
+
if (disposed) {
|
|
929
|
+
throw new Error("Agent runtime has been disposed");
|
|
930
|
+
}
|
|
931
|
+
runtime ??= options.createRuntime();
|
|
932
|
+
return runtime;
|
|
933
|
+
};
|
|
934
|
+
return {
|
|
935
|
+
get sessionId() {
|
|
936
|
+
return runtime?.sessionId ?? options.sessionId;
|
|
937
|
+
},
|
|
938
|
+
get provider() {
|
|
939
|
+
return runtime?.provider ?? options.provider;
|
|
940
|
+
},
|
|
941
|
+
get runtimeKind() {
|
|
942
|
+
return runtime?.runtimeKind ?? options.runtimeKind;
|
|
943
|
+
},
|
|
944
|
+
events: {
|
|
945
|
+
connect(onEvent, onError, onClose) {
|
|
946
|
+
getRuntime().events.connect(onEvent, onError, onClose);
|
|
947
|
+
},
|
|
948
|
+
disconnect() {
|
|
949
|
+
runtime?.events.disconnect();
|
|
950
|
+
},
|
|
951
|
+
isConnected() {
|
|
952
|
+
return runtime?.events.isConnected() ?? false;
|
|
953
|
+
}
|
|
954
|
+
},
|
|
955
|
+
commands: {
|
|
956
|
+
sendMessage(message, sendOptions) {
|
|
957
|
+
return getRuntime().commands.sendMessage(message, sendOptions);
|
|
958
|
+
},
|
|
959
|
+
abort(reason) {
|
|
960
|
+
return getRuntime().commands.abort(reason);
|
|
961
|
+
},
|
|
962
|
+
respondToPermission(requestId, allowed, remember) {
|
|
963
|
+
return getRuntime().commands.respondToPermission(requestId, allowed, remember);
|
|
964
|
+
},
|
|
965
|
+
async resumeTool(runId, resumeData) {
|
|
966
|
+
const commands = getRuntime().commands;
|
|
967
|
+
if (!commands.resumeTool) {
|
|
968
|
+
throw new Error(`resumeTool is not supported by the ${options.provider} runtime`);
|
|
969
|
+
}
|
|
970
|
+
await commands.resumeTool(runId, resumeData);
|
|
971
|
+
},
|
|
972
|
+
dispose() {
|
|
973
|
+
disposed = true;
|
|
974
|
+
const current = runtime;
|
|
975
|
+
runtime = null;
|
|
976
|
+
return current?.commands.dispose() ?? Promise.resolve();
|
|
977
|
+
}
|
|
978
|
+
},
|
|
979
|
+
preflight() {
|
|
980
|
+
return getRuntime().preflight();
|
|
981
|
+
},
|
|
982
|
+
fetchTimeline(request) {
|
|
983
|
+
return getRuntime().fetchTimeline(request);
|
|
984
|
+
},
|
|
985
|
+
getState() {
|
|
986
|
+
return runtime?.getState() ?? {
|
|
987
|
+
status: initialRuntimeState.status,
|
|
988
|
+
acceptedMessages: [],
|
|
989
|
+
queuedMessages: []
|
|
990
|
+
};
|
|
991
|
+
},
|
|
992
|
+
async disposeIfCreated() {
|
|
993
|
+
if (!runtime) return;
|
|
994
|
+
const current = runtime;
|
|
995
|
+
runtime = null;
|
|
996
|
+
await current.commands.dispose();
|
|
997
|
+
}
|
|
998
|
+
};
|
|
999
|
+
}
|
|
1000
|
+
|
|
2221
1001
|
// ../packages/local-chat/dist/index.js
|
|
2222
1002
|
import { useState as useState22 } from "react";
|
|
2223
1003
|
|
|
@@ -2258,6 +1038,33 @@ var EN_FALLBACK = {
|
|
|
2258
1038
|
"plan.acceptAndSendFollowups": "Accept & send follow-ups"
|
|
2259
1039
|
};
|
|
2260
1040
|
|
|
1041
|
+
// ../packages/core/dist/chunk-QEEF5TZY.js
|
|
1042
|
+
function generateMessageId() {
|
|
1043
|
+
return `msg-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
1044
|
+
}
|
|
1045
|
+
function storedToMessage(stored) {
|
|
1046
|
+
const { type, ...rest } = stored;
|
|
1047
|
+
return { ...rest, role: type, timestamp: stored.timestamp ?? Date.now() };
|
|
1048
|
+
}
|
|
1049
|
+
|
|
1050
|
+
// ../packages/core/dist/chunk-LCDW7EA2.js
|
|
1051
|
+
function normalizePath(path) {
|
|
1052
|
+
return path.replace(/\\/g, "/");
|
|
1053
|
+
}
|
|
1054
|
+
function pathStartsWith(filePath, dirPath) {
|
|
1055
|
+
const normalizedFile = normalizePath(filePath);
|
|
1056
|
+
const normalizedDir = normalizePath(dirPath);
|
|
1057
|
+
return normalizedFile.startsWith(normalizedDir + "/") || normalizedFile === normalizedDir;
|
|
1058
|
+
}
|
|
1059
|
+
function stripPathPrefix(filePath, prefix) {
|
|
1060
|
+
const normalizedFile = normalizePath(filePath);
|
|
1061
|
+
const normalizedPrefix = normalizePath(prefix);
|
|
1062
|
+
if (normalizedFile.startsWith(normalizedPrefix + "/")) {
|
|
1063
|
+
return normalizedFile.slice(normalizedPrefix.length + 1);
|
|
1064
|
+
}
|
|
1065
|
+
return filePath;
|
|
1066
|
+
}
|
|
1067
|
+
|
|
2261
1068
|
// ../packages/ui/dist/index.js
|
|
2262
1069
|
import * as React10 from "react";
|
|
2263
1070
|
import { useMemo as useMemo5, useEffect as useEffect4, useRef as useRef5, useCallback as useCallback6, useState as useState7 } from "react";
|
|
@@ -2329,7 +1136,7 @@ import * as React7 from "react";
|
|
|
2329
1136
|
import { jsx as jsx20, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2330
1137
|
import * as React8 from "react";
|
|
2331
1138
|
import * as React9 from "react";
|
|
2332
|
-
import { useCallback as useCallback4, useEffect as
|
|
1139
|
+
import { useCallback as useCallback4, useEffect as useEffect22, useRef as useRef32, useState as useState5 } from "react";
|
|
2333
1140
|
import { useTranslation as useTranslation2 } from "react-i18next";
|
|
2334
1141
|
import * as ReactDOM from "react-dom";
|
|
2335
1142
|
import { ChevronDown } from "lucide-react";
|
|
@@ -2347,7 +1154,7 @@ import { jsx as jsx25, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
|
2347
1154
|
import { useTranslation as useTranslation4 } from "react-i18next";
|
|
2348
1155
|
import { CheckCircle2 as CheckCircle22, XCircle as XCircle2, X } from "lucide-react";
|
|
2349
1156
|
import { Fragment as Fragment9, jsx as jsx26, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
2350
|
-
import { useMemo as
|
|
1157
|
+
import { useMemo as useMemo62, useState as useState9, useCallback as useCallback7 } from "react";
|
|
2351
1158
|
import { useEffect as useEffect5, useRef as useRef6, useState as useState8 } from "react";
|
|
2352
1159
|
import { Clock } from "lucide-react";
|
|
2353
1160
|
import { File, Image as ImageIcon } from "lucide-react";
|
|
@@ -2885,7 +1692,7 @@ function groupActivitiesByParent(activities) {
|
|
|
2885
1692
|
}
|
|
2886
1693
|
return result;
|
|
2887
1694
|
}
|
|
2888
|
-
function
|
|
1695
|
+
function asRecord(value) {
|
|
2889
1696
|
return value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
2890
1697
|
}
|
|
2891
1698
|
function normalizeFollowUpText(text) {
|
|
@@ -2895,7 +1702,7 @@ function getAnnotationNoteText(annotation) {
|
|
|
2895
1702
|
const noteBody = annotation.body.find((body) => body.type === "note");
|
|
2896
1703
|
const bodyText = noteBody?.text?.trim() ?? "";
|
|
2897
1704
|
if (bodyText.length > 0) return bodyText;
|
|
2898
|
-
const followUpMeta =
|
|
1705
|
+
const followUpMeta = asRecord(asRecord(annotation.meta)?.followUp);
|
|
2899
1706
|
const metaText = typeof followUpMeta?.text === "string" ? followUpMeta.text.trim() : "";
|
|
2900
1707
|
return metaText;
|
|
2901
1708
|
}
|
|
@@ -4812,8 +3619,8 @@ function AcceptPlanDropdown({
|
|
|
4812
3619
|
const effectiveAcceptOptionLabel = acceptOptionLabel ?? t2("plan.accept");
|
|
4813
3620
|
const [isOpen, setIsOpen] = useState5(false);
|
|
4814
3621
|
const [position, setPosition] = useState5(null);
|
|
4815
|
-
const triggerRef =
|
|
4816
|
-
const menuRef =
|
|
3622
|
+
const triggerRef = useRef32(null);
|
|
3623
|
+
const menuRef = useRef32(null);
|
|
4817
3624
|
const updatePosition = useCallback4(() => {
|
|
4818
3625
|
if (!triggerRef.current) return;
|
|
4819
3626
|
const rect = triggerRef.current.getBoundingClientRect();
|
|
@@ -4862,12 +3669,12 @@ function AcceptPlanDropdown({
|
|
|
4862
3669
|
handleClose();
|
|
4863
3670
|
onAcceptWithCompact();
|
|
4864
3671
|
}, [handleClose, onAcceptWithCompact]);
|
|
4865
|
-
|
|
3672
|
+
useEffect22(() => {
|
|
4866
3673
|
if (isOpen) {
|
|
4867
3674
|
updatePosition();
|
|
4868
3675
|
}
|
|
4869
3676
|
}, [isOpen, updatePosition]);
|
|
4870
|
-
|
|
3677
|
+
useEffect22(() => {
|
|
4871
3678
|
if (!isOpen) return;
|
|
4872
3679
|
const handleClickOutside = (e) => {
|
|
4873
3680
|
if (menuRef.current && !menuRef.current.contains(e.target) && triggerRef.current && !triggerRef.current.contains(e.target)) {
|
|
@@ -6990,7 +5797,7 @@ function ChatTranscript({
|
|
|
6990
5797
|
sessionFolderPath,
|
|
6991
5798
|
children
|
|
6992
5799
|
}) {
|
|
6993
|
-
const turns =
|
|
5800
|
+
const turns = useMemo62(() => groupMessagesByTurn(messages), [messages]);
|
|
6994
5801
|
const [expandedTurns, setExpandedTurns] = useState9(() => {
|
|
6995
5802
|
if (defaultExpanded) {
|
|
6996
5803
|
return new Set(
|
|
@@ -8986,7 +7793,7 @@ function useEventProcessor(options) {
|
|
|
8986
7793
|
// ../packages/local-chat/dist/index.js
|
|
8987
7794
|
import { useCallback as useCallback9, useEffect as useEffect9, useMemo as useMemo8, useRef as useRef8, useState as useState12 } from "react";
|
|
8988
7795
|
import { jsx as jsx39, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
8989
|
-
import { useCallback as useCallback22, useEffect as
|
|
7796
|
+
import { useCallback as useCallback22, useEffect as useEffect23, useMemo as useMemo22, useRef as useRef22, useState as useState32 } from "react";
|
|
8990
7797
|
import { jsx as jsx210, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
8991
7798
|
function createAgentChatPanelModel(args) {
|
|
8992
7799
|
return {
|
|
@@ -9550,7 +8357,7 @@ function TimelineAgentChatPanel({
|
|
|
9550
8357
|
[chat.timeline]
|
|
9551
8358
|
);
|
|
9552
8359
|
const scrollRef = useRef22(null);
|
|
9553
|
-
|
|
8360
|
+
useEffect23(() => {
|
|
9554
8361
|
if (scrollRef.current) {
|
|
9555
8362
|
scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
|
|
9556
8363
|
}
|
|
@@ -9711,50 +8518,9 @@ function TimelineAgentChatPanel({
|
|
|
9711
8518
|
export {
|
|
9712
8519
|
AgentChatPanel,
|
|
9713
8520
|
EN_FALLBACK,
|
|
9714
|
-
RPC_CHANNELS,
|
|
9715
|
-
THINKING_LEVELS,
|
|
9716
|
-
THINKING_LEVEL_IDS,
|
|
9717
|
-
THINKING_TO_EFFORT,
|
|
9718
8521
|
TimelineAgentChatPanel,
|
|
9719
|
-
appendTimelineItem,
|
|
9720
8522
|
createFlitroEmbedRuntime,
|
|
9721
|
-
createInMemoryApprovalStore,
|
|
9722
|
-
createPermissionPolicy,
|
|
9723
|
-
createPermissionPolicyFromConfig,
|
|
9724
|
-
createPolicyDecisionReceipt,
|
|
9725
|
-
createRuntimeCapabilityReport,
|
|
9726
|
-
createRuntimeExtensionContext,
|
|
9727
|
-
createSourcePolicyLayer,
|
|
9728
|
-
createTimelineCursor,
|
|
9729
|
-
createTimelineSequencer,
|
|
9730
|
-
debug,
|
|
9731
|
-
evaluateToolPolicy,
|
|
9732
|
-
explainToolPolicy,
|
|
9733
|
-
fetchTimeline,
|
|
9734
|
-
findMentionMatches,
|
|
9735
|
-
generateMessageId,
|
|
9736
|
-
getThinkingLevelNameKey,
|
|
9737
|
-
getThinkingTokens,
|
|
9738
|
-
invokeSessionTool,
|
|
9739
|
-
isValidThinkingLevel,
|
|
9740
|
-
mergeTimeline,
|
|
9741
|
-
messageToStored,
|
|
9742
|
-
normalizePath,
|
|
9743
|
-
normalizeThinkingLevel,
|
|
9744
|
-
parseMentions,
|
|
9745
|
-
pathStartsWith,
|
|
9746
|
-
reduceRuntimeState,
|
|
9747
|
-
resolveFileMentions,
|
|
9748
|
-
resolvePathMentions,
|
|
9749
|
-
resolveSkillMentions,
|
|
9750
|
-
resolveSourceMentions,
|
|
9751
|
-
sanitizeProviderSourceTools,
|
|
9752
|
-
selectRuntimeCandidate,
|
|
9753
|
-
storedToMessage,
|
|
9754
|
-
stripAllMentions,
|
|
9755
|
-
stripPathPrefix,
|
|
9756
8523
|
useAgentChatSession,
|
|
9757
8524
|
useAgentSession,
|
|
9758
|
-
useTimelineAgentChatSession
|
|
9759
|
-
validatePolicyConfig
|
|
8525
|
+
useTimelineAgentChatSession
|
|
9760
8526
|
};
|