@zerwiz/sessrumnir 0.1.8-alpha

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.
Files changed (113) hide show
  1. package/LICENSE +200 -0
  2. package/README.md +329 -0
  3. package/bin/sessrumnir-web.sh +117 -0
  4. package/bin/sessrumnir.js +169 -0
  5. package/out/main/index.js +10850 -0
  6. package/out/preload/index.js +719 -0
  7. package/out/renderer/assets/cormorant-cyrillic-400-normal-C8QS47vb.woff2 +0 -0
  8. package/out/renderer/assets/cormorant-cyrillic-400-normal-D3EsxgFc.woff +0 -0
  9. package/out/renderer/assets/cormorant-cyrillic-500-normal-B7dJQtg-.woff +0 -0
  10. package/out/renderer/assets/cormorant-cyrillic-500-normal-BLlg2W5x.woff2 +0 -0
  11. package/out/renderer/assets/cormorant-cyrillic-600-normal-BcIsDXzC.woff2 +0 -0
  12. package/out/renderer/assets/cormorant-cyrillic-600-normal-CBymlcNF.woff +0 -0
  13. package/out/renderer/assets/cormorant-cyrillic-ext-400-normal-Bgrpe4p1.woff +0 -0
  14. package/out/renderer/assets/cormorant-cyrillic-ext-400-normal-BlcaxZtM.woff2 +0 -0
  15. package/out/renderer/assets/cormorant-cyrillic-ext-500-normal-CdQuyvtc.woff +0 -0
  16. package/out/renderer/assets/cormorant-cyrillic-ext-500-normal-pZw22qtS.woff2 +0 -0
  17. package/out/renderer/assets/cormorant-cyrillic-ext-600-normal-Dr-wLyOm.woff +0 -0
  18. package/out/renderer/assets/cormorant-cyrillic-ext-600-normal-dLR2-a_v.woff2 +0 -0
  19. package/out/renderer/assets/cormorant-latin-400-normal-BGH8Vunh.woff2 +0 -0
  20. package/out/renderer/assets/cormorant-latin-400-normal-C3_-2Ua-.woff +0 -0
  21. package/out/renderer/assets/cormorant-latin-500-normal-Dj3SQ6fR.woff +0 -0
  22. package/out/renderer/assets/cormorant-latin-500-normal-EBdSCOD3.woff2 +0 -0
  23. package/out/renderer/assets/cormorant-latin-600-normal-B254Xisw.woff2 +0 -0
  24. package/out/renderer/assets/cormorant-latin-600-normal-DUW-TI76.woff +0 -0
  25. package/out/renderer/assets/cormorant-latin-ext-400-normal-DuQ88yz3.woff2 +0 -0
  26. package/out/renderer/assets/cormorant-latin-ext-400-normal-DuXFa1Dr.woff +0 -0
  27. package/out/renderer/assets/cormorant-latin-ext-500-normal-AH9qog1s.woff2 +0 -0
  28. package/out/renderer/assets/cormorant-latin-ext-500-normal-DAuUCO41.woff +0 -0
  29. package/out/renderer/assets/cormorant-latin-ext-600-normal-CD-dlDpD.woff +0 -0
  30. package/out/renderer/assets/cormorant-latin-ext-600-normal-D3T6BBXG.woff2 +0 -0
  31. package/out/renderer/assets/cormorant-vietnamese-400-normal-C-RiYxEf.woff2 +0 -0
  32. package/out/renderer/assets/cormorant-vietnamese-400-normal-DmUuA7Y2.woff +0 -0
  33. package/out/renderer/assets/cormorant-vietnamese-500-normal-DsPuwQHi.woff2 +0 -0
  34. package/out/renderer/assets/cormorant-vietnamese-500-normal-tGBW_mI7.woff +0 -0
  35. package/out/renderer/assets/cormorant-vietnamese-600-normal-Dar_cCT6.woff2 +0 -0
  36. package/out/renderer/assets/cormorant-vietnamese-600-normal-GIs8CF2x.woff +0 -0
  37. package/out/renderer/assets/ibm-plex-mono-cyrillic-300-normal-Ba-HN6uq.woff +0 -0
  38. package/out/renderer/assets/ibm-plex-mono-cyrillic-300-normal-ByB2hQUF.woff2 +0 -0
  39. package/out/renderer/assets/ibm-plex-mono-cyrillic-400-normal-BSMlKf0J.woff2 +0 -0
  40. package/out/renderer/assets/ibm-plex-mono-cyrillic-400-normal-CEL4l2ZJ.woff +0 -0
  41. package/out/renderer/assets/ibm-plex-mono-cyrillic-500-normal-Ael50iVv.woff +0 -0
  42. package/out/renderer/assets/ibm-plex-mono-cyrillic-500-normal-Bq9vWWag.woff2 +0 -0
  43. package/out/renderer/assets/ibm-plex-mono-cyrillic-ext-300-normal-B8O3uHbr.woff +0 -0
  44. package/out/renderer/assets/ibm-plex-mono-cyrillic-ext-300-normal-BbtBtHoB.woff2 +0 -0
  45. package/out/renderer/assets/ibm-plex-mono-cyrillic-ext-400-normal-DMdlQ8Kv.woff +0 -0
  46. package/out/renderer/assets/ibm-plex-mono-cyrillic-ext-400-normal-xuaO2J-f.woff2 +0 -0
  47. package/out/renderer/assets/ibm-plex-mono-cyrillic-ext-500-normal-BIfNGwUT.woff +0 -0
  48. package/out/renderer/assets/ibm-plex-mono-cyrillic-ext-500-normal-BqneJy0T.woff2 +0 -0
  49. package/out/renderer/assets/ibm-plex-mono-latin-300-normal-BPU54Tw3.woff +0 -0
  50. package/out/renderer/assets/ibm-plex-mono-latin-300-normal-BRS-C4KA.woff2 +0 -0
  51. package/out/renderer/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
  52. package/out/renderer/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
  53. package/out/renderer/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
  54. package/out/renderer/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
  55. package/out/renderer/assets/ibm-plex-mono-latin-ext-300-normal-BEtQ2wm2.woff2 +0 -0
  56. package/out/renderer/assets/ibm-plex-mono-latin-ext-300-normal-CQbCaAQ4.woff +0 -0
  57. package/out/renderer/assets/ibm-plex-mono-latin-ext-400-normal-BmRBH3aV.woff2 +0 -0
  58. package/out/renderer/assets/ibm-plex-mono-latin-ext-400-normal-D3D2R8hC.woff +0 -0
  59. package/out/renderer/assets/ibm-plex-mono-latin-ext-500-normal-CAhNIIs5.woff2 +0 -0
  60. package/out/renderer/assets/ibm-plex-mono-latin-ext-500-normal-CZ70TYgx.woff +0 -0
  61. package/out/renderer/assets/ibm-plex-mono-vietnamese-300-normal-B6fSpYYV.woff +0 -0
  62. package/out/renderer/assets/ibm-plex-mono-vietnamese-300-normal-CpdbWO_2.woff2 +0 -0
  63. package/out/renderer/assets/ibm-plex-mono-vietnamese-400-normal-BulugwFq.woff2 +0 -0
  64. package/out/renderer/assets/ibm-plex-mono-vietnamese-400-normal-DDuiU_S-.woff +0 -0
  65. package/out/renderer/assets/ibm-plex-mono-vietnamese-500-normal-C8zxqsMH.woff +0 -0
  66. package/out/renderer/assets/ibm-plex-mono-vietnamese-500-normal-DZ4AoWbu.woff2 +0 -0
  67. package/out/renderer/assets/index-CgJYtdL8.js +97387 -0
  68. package/out/renderer/assets/index-CyRDW9WV.css +4824 -0
  69. package/out/renderer/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
  70. package/out/renderer/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
  71. package/out/renderer/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
  72. package/out/renderer/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
  73. package/out/renderer/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  74. package/out/renderer/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  75. package/out/renderer/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
  76. package/out/renderer/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
  77. package/out/renderer/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
  78. package/out/renderer/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
  79. package/out/renderer/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
  80. package/out/renderer/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
  81. package/out/renderer/assets/newsreader-latin-ext-wght-italic-DFS986qL.woff2 +0 -0
  82. package/out/renderer/assets/newsreader-latin-ext-wght-normal-C-3rgBeH.woff2 +0 -0
  83. package/out/renderer/assets/newsreader-latin-wght-italic-Bxi8ein9.woff2 +0 -0
  84. package/out/renderer/assets/newsreader-latin-wght-normal-CCVVNp6i.woff2 +0 -0
  85. package/out/renderer/assets/newsreader-vietnamese-wght-italic-xAqemagA.woff2 +0 -0
  86. package/out/renderer/assets/newsreader-vietnamese-wght-normal-Czsa-EzN.woff2 +0 -0
  87. package/out/renderer/assets/openmoji-color-9qo_2DLG.woff2 +0 -0
  88. package/out/renderer/assets/pi-logo-8LswgQgB.svg +17 -0
  89. package/out/renderer/index.html +19 -0
  90. package/out/renderer/theme-boot.js +30 -0
  91. package/out/shared/src/shared/tsconfig.tsbuildinfo +1 -0
  92. package/package.json +183 -0
  93. package/resources/icons/generate_icons.py +38 -0
  94. package/resources/icons/icon-128.png +0 -0
  95. package/resources/icons/icon-16.png +0 -0
  96. package/resources/icons/icon-256.png +0 -0
  97. package/resources/icons/icon-32.png +0 -0
  98. package/resources/icons/icon-48.png +0 -0
  99. package/resources/icons/icon-512.png +0 -0
  100. package/resources/icons/icon-64.png +0 -0
  101. package/resources/icons/icon.icns +0 -0
  102. package/resources/icons/icon.ico +0 -0
  103. package/resources/icons/icon.png +0 -0
  104. package/resources/icons/icon.svg +55 -0
  105. package/resources/linux/after-install.sh +23 -0
  106. package/resources/linux/after-remove.sh +18 -0
  107. package/resources/locales/en/translation.json +1735 -0
  108. package/resources/permission-prompt-text.test.ts +111 -0
  109. package/resources/permission-prompt-text.ts +84 -0
  110. package/resources/permission-rules.test.ts +351 -0
  111. package/resources/permission-rules.ts +293 -0
  112. package/resources/pi-desktop-permissions.ts +62 -0
  113. package/resources/ymir-sessrumnir.desktop.in +12 -0
@@ -0,0 +1,719 @@
1
+ "use strict";
2
+ const electron = require("electron");
3
+ const BASE = "";
4
+ const WS_BASE = "";
5
+ function createHttpBridge() {
6
+ const subscriptions = /* @__PURE__ */ new Map();
7
+ async function invoke(channel, ...args) {
8
+ const body = args.length === 1 ? args[0] : args;
9
+ const res = await fetch(`${BASE}/api/${channel}`, {
10
+ method: "POST",
11
+ headers: { "Content-Type": "application/json" },
12
+ body: JSON.stringify(body)
13
+ });
14
+ if (!res.ok) {
15
+ const text = await res.text().catch(() => "");
16
+ throw new Error(`HTTP ${res.status}: ${text}`);
17
+ }
18
+ return res.json();
19
+ }
20
+ function subscribe(channel, callback) {
21
+ const ws = new WebSocket(`${WS_BASE}/ws/${channel}`);
22
+ const handler = (event) => {
23
+ const data = typeof event.data === "string" ? JSON.parse(event.data) : event.data;
24
+ callback(data);
25
+ };
26
+ ws.addEventListener("message", handler);
27
+ const entry = { ws, handler };
28
+ const existing = subscriptions.get(channel) || [];
29
+ existing.push(entry);
30
+ subscriptions.set(channel, existing);
31
+ return () => {
32
+ const subs = subscriptions.get(channel);
33
+ if (subs) {
34
+ const idx = subs.indexOf(entry);
35
+ if (idx >= 0) subs.splice(idx, 1);
36
+ ws.close();
37
+ }
38
+ };
39
+ }
40
+ const pi = {
41
+ start: (options) => invoke("pi:start", options),
42
+ stop: () => invoke("pi:stop"),
43
+ restart: (options) => invoke("pi:restart", options),
44
+ getStatus: () => invoke("pi:status"),
45
+ detectInstallations: (options) => invoke("pi:detect-installations", options)
46
+ };
47
+ const commands = {
48
+ prompt: (message, options) => invoke("pi:prompt", message, options),
49
+ steer: (message, images) => invoke("pi:steer", message, images),
50
+ followUp: (message) => invoke("pi:follow-up", message),
51
+ abort: () => invoke("pi:abort"),
52
+ bash: (command) => invoke("pi:bash", command),
53
+ abortBash: () => invoke("pi:abort-bash")
54
+ };
55
+ const session = {
56
+ createNew: () => invoke("session:new"),
57
+ launchTask: (options) => invoke("session:launch-task", options),
58
+ closeRuntime: (runtimeId) => invoke("session:close-runtime", runtimeId),
59
+ switch: (sessionPath, cwd) => invoke("session:switch", sessionPath, cwd),
60
+ listRuntimes: () => invoke("session:list-runtimes"),
61
+ fork: (entryId) => invoke("session:fork", entryId),
62
+ clone: () => invoke("session:clone"),
63
+ list: (cwd) => invoke("session:list", cwd),
64
+ listAll: (cwd) => invoke("session:list-all", cwd),
65
+ getState: () => invoke("session:get-state"),
66
+ getMessages: () => invoke("session:get-messages"),
67
+ getStats: () => invoke("session:get-stats"),
68
+ setName: (name) => invoke("session:set-name", name),
69
+ exportHtml: (outputPath) => invoke("session:export-html", outputPath),
70
+ getForkMessages: () => invoke("session:get-fork-messages"),
71
+ delete: (sessionPath) => invoke("session:delete", sessionPath),
72
+ archive: (sessionId) => invoke("session:archive", sessionId),
73
+ unarchive: (sessionId) => invoke("session:unarchive", sessionId),
74
+ listArchived: () => invoke("session:list-archived"),
75
+ getLineage: () => invoke("session:get-lineage"),
76
+ compact: (customInstructions) => invoke("session:compact", customInstructions)
77
+ };
78
+ const model = {
79
+ set: (provider, modelId) => invoke("model:set", provider, modelId),
80
+ cycle: () => invoke("model:cycle"),
81
+ listAvailable: () => invoke("model:list-available")
82
+ };
83
+ const thinking = {
84
+ setLevel: (level) => invoke("thinking:set-level", level),
85
+ cycleLevel: () => invoke("thinking:cycle-level")
86
+ };
87
+ const settings = {
88
+ getAll: () => invoke("settings:get-all"),
89
+ save: (s) => invoke("settings:save", s)
90
+ };
91
+ const permissionRules = {
92
+ get: (scope) => invoke("permission-rules:get", scope),
93
+ set: (scope, rules) => invoke("permission-rules:set", scope, rules),
94
+ importFromFile: () => invoke("permission-rules:import"),
95
+ exportToFile: (rules) => invoke("permission-rules:export", rules),
96
+ workspaceStatus: () => invoke("permission-rules:workspace-status"),
97
+ removeWorkspace: () => invoke("permission-rules:remove-workspace"),
98
+ setWorkspaceTrust: (trusted) => invoke("permission-rules:set-workspace-trust", trusted)
99
+ };
100
+ const themes = {
101
+ list: () => invoke("themes:list"),
102
+ save: (file, existingId) => invoke("themes:save", file, existingId),
103
+ delete: (id) => invoke("themes:delete", id),
104
+ installFromUrl: (url) => invoke("themes:install-from-url", url),
105
+ export: (file) => invoke("themes:export", file),
106
+ import: () => invoke("themes:import"),
107
+ gallery: () => invoke("themes:gallery-list"),
108
+ galleryImage: (url) => invoke("themes:gallery-image", url)
109
+ };
110
+ const workspace = {
111
+ list: () => invoke("workspace:list"),
112
+ create: (name, path) => invoke("workspace:create", name, path),
113
+ createTab: (options) => invoke("workspace:create-tab", options),
114
+ remove: (workspaceId) => invoke("workspace:remove", workspaceId),
115
+ rename: (workspaceId, name) => invoke("workspace:rename", workspaceId, name),
116
+ changePath: (workspaceId, newPath) => invoke("workspace:change-path", workspaceId, newPath),
117
+ pathExists: () => invoke("workspace:path-exists"),
118
+ setActive: (workspaceId) => invoke("workspace:set-active", workspaceId),
119
+ getActive: () => invoke("workspace:get-active"),
120
+ startPi: (workspaceId, options) => invoke("workspace:start-pi", workspaceId, options),
121
+ stopPi: (workspaceId) => invoke("workspace:stop-pi", workspaceId),
122
+ getActivity: () => invoke("workspace:activity"),
123
+ takePendingActivation: () => invoke("workspace:take-pending-activation")
124
+ };
125
+ const packages = {
126
+ listInstalled: () => invoke("package:list-installed"),
127
+ install: (spec) => invoke("package:install", spec),
128
+ remove: (spec) => invoke("package:remove", spec),
129
+ update: (spec) => invoke("package:update", spec),
130
+ updateAll: () => invoke("package:update-all"),
131
+ checkUpdates: () => invoke("package:check-updates"),
132
+ fetchCatalog: (query) => invoke("package:catalog-fetch", query)
133
+ };
134
+ const models = {
135
+ read: () => invoke("models:read"),
136
+ write: (config) => invoke("models:write", config)
137
+ };
138
+ const council = {
139
+ detect: () => invoke("council:detect"),
140
+ runConsultants: (payload) => invoke("council:run-consultants", payload),
141
+ arbiter: (payload) => invoke("council:arbiter", payload),
142
+ onProgress: (callback) => subscribe("event:council-progress", callback)
143
+ };
144
+ const skills = { list: () => invoke("skills:list") };
145
+ const piCommands = { list: () => invoke("commands:list") };
146
+ const mcpServers = { list: () => invoke("mcp:servers-list") };
147
+ const tags = {
148
+ get: (sessionId) => invoke("tag:get", sessionId),
149
+ set: (sessionId, tags2) => invoke("tag:set", sessionId, tags2),
150
+ add: (sessionId, tag) => invoke("tag:add", sessionId, tag),
151
+ remove: (sessionId, tag) => invoke("tag:remove", sessionId, tag),
152
+ getAll: () => invoke("tag:get-all"),
153
+ getAllUsed: () => invoke("tag:get-all-used"),
154
+ autoGetAll: () => invoke("tag:auto-get-all"),
155
+ autoEnsure: (sessions) => invoke("tag:auto-ensure", sessions),
156
+ autoRemove: (sessionId) => invoke("tag:auto-remove", sessionId)
157
+ };
158
+ const git = {
159
+ status: () => invoke("git:conveyor-status"),
160
+ commit: (options) => invoke("git:conveyor-commit", options),
161
+ push: () => invoke("git:conveyor-push"),
162
+ createPullRequest: (options) => invoke("git:conveyor-create-pr", options)
163
+ };
164
+ const notes = {
165
+ list: () => invoke("notes:list"),
166
+ create: (input) => invoke("notes:create", input),
167
+ update: (id, patch) => invoke("notes:update", id, patch),
168
+ remove: (id) => invoke("notes:remove", id)
169
+ };
170
+ const files = {
171
+ getTree: (maxDepth) => invoke("file:tree", maxDepth),
172
+ search: (query) => invoke("file:search", query),
173
+ searchContent: (query) => invoke("file:search-content", query),
174
+ read: (path) => invoke("file:read", path),
175
+ readAttachment: (path) => invoke("file:read-attachment", path),
176
+ write: (path, content) => invoke("file:write", path, content),
177
+ getDiff: (filePath) => invoke("file:diff", filePath),
178
+ getStagedDiff: (filePath) => invoke("file:staged-diff", filePath),
179
+ getGitStatus: () => invoke("git:status"),
180
+ getGitBranch: () => invoke("git:branch")
181
+ };
182
+ const system = {
183
+ openDialog: (options) => invoke("system:open-dialog", options),
184
+ getPath: (name) => invoke("system:get-path", name),
185
+ getPathForFile: (_file) => "",
186
+ // NOT PORTABLE: requires webUtils.getPathForFile
187
+ pathKind: (path) => invoke("system:path-kind", path),
188
+ openExternal: (url) => invoke("system:open-external", url),
189
+ hallUrl: () => invoke("system:hall-url"),
190
+ getVersion: () => invoke("system:get-version"),
191
+ get platform() {
192
+ return "linux";
193
+ }
194
+ // stub: web has no process.platform
195
+ };
196
+ const activity = {
197
+ getStats: () => invoke("activity:get-stats")
198
+ };
199
+ const workflows = {
200
+ list: () => invoke("workflow:list"),
201
+ getRun: (workspaceId, runId) => invoke("workflow:get-run", workspaceId, runId),
202
+ control: (workspaceId, runId, action) => invoke("workflow:control", workspaceId, runId, action),
203
+ setPersistAgentSessions: (enabled) => invoke("workflow:set-persistence", enabled)
204
+ };
205
+ const diagnostics = {
206
+ get: () => invoke("diagnostics:get")
207
+ };
208
+ const updates = {
209
+ check: () => invoke("update:check")
210
+ };
211
+ const i18n = {
212
+ getEnvironment: () => invoke("i18n:get-environment")
213
+ };
214
+ const terminal = {
215
+ start: (options) => invoke("terminal:start", options),
216
+ input: (data) => invoke("terminal:input", data),
217
+ resize: (cols, rows) => invoke("terminal:resize", { cols, rows }),
218
+ stop: () => invoke("terminal:stop"),
219
+ onData: (callback) => subscribe("event:terminal-data", callback),
220
+ onExit: (callback) => subscribe("event:terminal-exit", callback)
221
+ };
222
+ const ui = {
223
+ respondSelect: (id, value) => invoke("ui:select-response", id, value),
224
+ respondConfirm: (id, confirmed) => invoke("ui:confirm-response", id, confirmed),
225
+ respondInput: (id, value) => invoke("ui:input-response", id, value),
226
+ respondEditor: (id, value) => invoke("ui:editor-response", id, value),
227
+ flushPendingPrompts: (workspaceId) => invoke("ui:pending-flush", workspaceId),
228
+ getPendingPrompts: () => invoke("ui:pending-get"),
229
+ setEditorDirty: (_dirty, _fileName) => {
230
+ }
231
+ };
232
+ const onEvent = (callback) => subscribe("event:pi", callback);
233
+ const onPendingPrompts = (callback) => subscribe("event:pending-prompts", callback);
234
+ const onWorkspaceActivity = (callback) => subscribe("event:workspace-activity", callback);
235
+ const onSessionRuntime = (callback) => subscribe("event:session-runtime", callback);
236
+ const onActivateWorkspace = (callback) => subscribe("event:activate-workspace", callback);
237
+ const onFileChange = (callback) => subscribe("event:file-change", callback);
238
+ const onMenuAction = (_callback) => {
239
+ return () => {
240
+ };
241
+ };
242
+ return {
243
+ pi,
244
+ commands,
245
+ session,
246
+ model,
247
+ thinking,
248
+ settings,
249
+ permissionRules,
250
+ themes,
251
+ workspace,
252
+ packages,
253
+ models,
254
+ council,
255
+ skills,
256
+ piCommands,
257
+ mcpServers,
258
+ tags,
259
+ git,
260
+ notes,
261
+ files,
262
+ system,
263
+ activity,
264
+ workflows,
265
+ diagnostics,
266
+ updates,
267
+ i18n,
268
+ terminal,
269
+ ui,
270
+ onEvent,
271
+ onPendingPrompts,
272
+ onWorkspaceActivity,
273
+ onSessionRuntime,
274
+ onActivateWorkspace,
275
+ onFileChange,
276
+ onMenuAction
277
+ };
278
+ }
279
+ const IPC_CHANNELS = {
280
+ // Pi process lifecycle
281
+ PI_START: "pi:start",
282
+ PI_STOP: "pi:stop",
283
+ PI_RESTART: "pi:restart",
284
+ PI_STATUS: "pi:status",
285
+ PI_DETECT_INSTALLATIONS: "pi:detect-installations",
286
+ // Pi commands
287
+ PI_PROMPT: "pi:prompt",
288
+ PI_STEER: "pi:steer",
289
+ PI_FOLLOW_UP: "pi:follow-up",
290
+ PI_ABORT: "pi:abort",
291
+ PI_BASH: "pi:bash",
292
+ PI_ABORT_BASH: "pi:abort-bash",
293
+ // Session management
294
+ SESSION_NEW: "session:new",
295
+ SESSION_LAUNCH_TASK: "session:launch-task",
296
+ SESSION_CLOSE_RUNTIME: "session:close-runtime",
297
+ SESSION_SWITCH: "session:switch",
298
+ SESSION_LIST_RUNTIMES: "session:list-runtimes",
299
+ SESSION_FORK: "session:fork",
300
+ SESSION_CLONE: "session:clone",
301
+ SESSION_LIST: "session:list",
302
+ SESSION_LIST_ALL: "session:list-all",
303
+ SESSION_GET_STATE: "session:get-state",
304
+ SESSION_GET_MESSAGES: "session:get-messages",
305
+ SESSION_GET_STATS: "session:get-stats",
306
+ SESSION_SET_NAME: "session:set-name",
307
+ SESSION_EXPORT_HTML: "session:export-html",
308
+ SESSION_GET_FORK_MESSAGES: "session:get-fork-messages",
309
+ SESSION_DELETE: "session:delete",
310
+ SESSION_ARCHIVE: "session:archive",
311
+ SESSION_UNARCHIVE: "session:unarchive",
312
+ SESSION_LIST_ARCHIVED: "session:list-archived",
313
+ SESSION_GET_LINEAGE: "session:get-lineage",
314
+ SESSION_COMPACT: "session:compact",
315
+ // Model management
316
+ MODEL_SET: "model:set",
317
+ MODEL_CYCLE: "model:cycle",
318
+ MODEL_LIST_AVAILABLE: "model:list-available",
319
+ THINKING_SET_LEVEL: "thinking:set-level",
320
+ THINKING_CYCLE_LEVEL: "thinking:cycle-level",
321
+ // Settings
322
+ SETTINGS_GET_ALL: "settings:get-all",
323
+ SETTINGS_SAVE: "settings:save",
324
+ I18N_GET_ENVIRONMENT: "i18n:get-environment",
325
+ // Permission rules
326
+ PERMISSION_RULES_GET: "permission-rules:get",
327
+ PERMISSION_RULES_SET: "permission-rules:set",
328
+ PERMISSION_RULES_IMPORT: "permission-rules:import",
329
+ PERMISSION_RULES_EXPORT: "permission-rules:export",
330
+ PERMISSION_RULES_WORKSPACE_STATUS: "permission-rules:workspace-status",
331
+ PERMISSION_RULES_REMOVE_WORKSPACE: "permission-rules:remove-workspace",
332
+ PERMISSION_RULES_SET_WORKSPACE_TRUST: "permission-rules:set-workspace-trust",
333
+ // UI
334
+ UI_SELECT_RESPONSE: "ui:select-response",
335
+ UI_CONFIRM_RESPONSE: "ui:confirm-response",
336
+ UI_INPUT_RESPONSE: "ui:input-response",
337
+ UI_EDITOR_RESPONSE: "ui:editor-response",
338
+ UI_PENDING_FLUSH: "ui:pending-flush",
339
+ UI_PENDING_GET: "ui:pending-get",
340
+ UI_EDITOR_DIRTY_SET: "ui:editor-dirty-set",
341
+ // System
342
+ SYSTEM_OPEN_DIALOG: "system:open-dialog",
343
+ SYSTEM_GET_PATH: "system:get-path",
344
+ SYSTEM_PATH_KIND: "system:path-kind",
345
+ SYSTEM_OPEN_EXTERNAL: "system:open-external",
346
+ SYSTEM_HALL_URL: "system:hall-url",
347
+ SYSTEM_GET_VERSION: "system:get-version",
348
+ UPDATE_CHECK: "update:check",
349
+ // Activity
350
+ ACTIVITY_GET_STATS: "activity:get-stats",
351
+ // Workflow run monitoring
352
+ WORKFLOW_LIST: "workflow:list",
353
+ WORKFLOW_GET_RUN: "workflow:get-run",
354
+ WORKFLOW_CONTROL: "workflow:control",
355
+ WORKFLOW_SET_PERSISTENCE: "workflow:set-persistence",
356
+ // Diagnostics
357
+ DIAGNOSTICS_GET: "diagnostics:get",
358
+ // Workspaces
359
+ WORKSPACE_LIST: "workspace:list",
360
+ WORKSPACE_CREATE: "workspace:create",
361
+ WORKSPACE_REMOVE: "workspace:remove",
362
+ WORKSPACE_RENAME: "workspace:rename",
363
+ WORKSPACE_SET_ACTIVE: "workspace:set-active",
364
+ WORKSPACE_GET_ACTIVE: "workspace:get-active",
365
+ WORKSPACE_CHANGE_PATH: "workspace:change-path",
366
+ WORKSPACE_PATH_EXISTS: "workspace:path-exists",
367
+ WORKSPACE_START_PI: "workspace:start-pi",
368
+ WORKSPACE_STOP_PI: "workspace:stop-pi",
369
+ WORKSPACE_CREATE_TAB: "workspace:create-tab",
370
+ WORKSPACE_ACTIVITY_GET: "workspace:activity",
371
+ WORKSPACE_TAKE_PENDING_ACTIVATION: "workspace:take-pending-activation",
372
+ // Packages
373
+ PACKAGE_LIST_INSTALLED: "package:list-installed",
374
+ PACKAGE_INSTALL: "package:install",
375
+ PACKAGE_REMOVE: "package:remove",
376
+ PACKAGE_UPDATE: "package:update",
377
+ PACKAGE_UPDATE_ALL: "package:update-all",
378
+ PACKAGE_CHECK_UPDATES: "package:check-updates",
379
+ PACKAGE_CATALOG_FETCH: "package:catalog-fetch",
380
+ // Skills
381
+ SKILLS_LIST: "skills:list",
382
+ COMMANDS_LIST: "commands:list",
383
+ MCP_SERVERS_LIST: "mcp:servers-list",
384
+ // Models config
385
+ MODELS_READ: "models:read",
386
+ MODELS_WRITE: "models:write",
387
+ // Council planning
388
+ COUNCIL_DETECT: "council:detect",
389
+ COUNCIL_RUN_CONSULTANTS: "council:run-consultants",
390
+ COUNCIL_ARBITER: "council:arbiter",
391
+ // File operations
392
+ FILE_TREE: "file:tree",
393
+ FILE_SEARCH: "file:search",
394
+ FILE_SEARCH_CONTENT: "file:search-content",
395
+ FILE_READ: "file:read",
396
+ FILE_READ_ATTACHMENT: "file:read-attachment",
397
+ FILE_WRITE: "file:write",
398
+ FILE_DIFF: "file:diff",
399
+ FILE_STAGED_DIFF: "file:staged-diff",
400
+ GIT_STATUS: "git:status",
401
+ GIT_BRANCH: "git:branch",
402
+ GIT_CONVEYOR_STATUS: "git:conveyor-status",
403
+ GIT_CONVEYOR_COMMIT: "git:conveyor-commit",
404
+ GIT_CONVEYOR_PUSH: "git:conveyor-push",
405
+ GIT_CONVEYOR_CREATE_PR: "git:conveyor-create-pr",
406
+ // Terminal
407
+ TERMINAL_START: "terminal:start",
408
+ TERMINAL_INPUT: "terminal:input",
409
+ TERMINAL_RESIZE: "terminal:resize",
410
+ TERMINAL_STOP: "terminal:stop",
411
+ // Session tags
412
+ TAG_GET: "tag:get",
413
+ TAG_SET: "tag:set",
414
+ TAG_ADD: "tag:add",
415
+ TAG_REMOVE: "tag:remove",
416
+ TAG_GET_ALL: "tag:get-all",
417
+ TAG_GET_ALL_USED: "tag:get-all-used",
418
+ TAG_AUTO_GET_ALL: "tag:auto-get-all",
419
+ TAG_AUTO_ENSURE: "tag:auto-ensure",
420
+ TAG_AUTO_REMOVE: "tag:auto-remove",
421
+ // Notes (reusable prompts / commands)
422
+ NOTES_LIST: "notes:list",
423
+ NOTES_CREATE: "notes:create",
424
+ NOTES_UPDATE: "notes:update",
425
+ NOTES_REMOVE: "notes:remove",
426
+ // Themes (user-created theme storage)
427
+ THEMES_LIST: "themes:list",
428
+ THEMES_SAVE: "themes:save",
429
+ THEMES_DELETE: "themes:delete",
430
+ THEMES_INSTALL_URL: "themes:install-from-url",
431
+ THEMES_EXPORT: "themes:export",
432
+ THEMES_IMPORT: "themes:import",
433
+ THEMES_GALLERY_LIST: "themes:gallery-list",
434
+ THEMES_GALLERY_IMAGE: "themes:gallery-image",
435
+ // Events (main → renderer)
436
+ EVENT_PI: "event:pi",
437
+ EVENT_PENDING_PROMPTS: "event:pending-prompts",
438
+ EVENT_WORKSPACE_ACTIVITY: "event:workspace-activity",
439
+ EVENT_SESSION_RUNTIME: "event:session-runtime",
440
+ EVENT_ACTIVATE_WORKSPACE: "event:activate-workspace",
441
+ EVENT_FILE_CHANGE: "event:file-change",
442
+ EVENT_TERMINAL_DATA: "event:terminal-data",
443
+ EVENT_TERMINAL_EXIT: "event:terminal-exit",
444
+ EVENT_COUNCIL_PROGRESS: "event:council-progress"
445
+ };
446
+ const IS_ELECTRON = typeof electron.contextBridge !== "undefined" && typeof electron.ipcRenderer !== "undefined";
447
+ function createBridge() {
448
+ if (IS_ELECTRON) {
449
+ const api = {
450
+ pi: {
451
+ start: (options) => electron.ipcRenderer.invoke(IPC_CHANNELS.PI_START, options),
452
+ stop: () => electron.ipcRenderer.invoke(IPC_CHANNELS.PI_STOP),
453
+ restart: (options) => electron.ipcRenderer.invoke(IPC_CHANNELS.PI_RESTART, options),
454
+ getStatus: () => electron.ipcRenderer.invoke(IPC_CHANNELS.PI_STATUS),
455
+ detectInstallations: (options) => electron.ipcRenderer.invoke(IPC_CHANNELS.PI_DETECT_INSTALLATIONS, options)
456
+ },
457
+ commands: {
458
+ prompt: (message, options) => electron.ipcRenderer.invoke(IPC_CHANNELS.PI_PROMPT, message, options),
459
+ steer: (message, images) => electron.ipcRenderer.invoke(IPC_CHANNELS.PI_STEER, message, images),
460
+ followUp: (message) => electron.ipcRenderer.invoke(IPC_CHANNELS.PI_FOLLOW_UP, message),
461
+ abort: () => electron.ipcRenderer.invoke(IPC_CHANNELS.PI_ABORT),
462
+ bash: (command) => electron.ipcRenderer.invoke(IPC_CHANNELS.PI_BASH, command),
463
+ abortBash: () => electron.ipcRenderer.invoke(IPC_CHANNELS.PI_ABORT_BASH)
464
+ },
465
+ session: {
466
+ createNew: () => electron.ipcRenderer.invoke(IPC_CHANNELS.SESSION_NEW),
467
+ launchTask: (options) => electron.ipcRenderer.invoke(IPC_CHANNELS.SESSION_LAUNCH_TASK, options),
468
+ closeRuntime: (runtimeId) => electron.ipcRenderer.invoke(IPC_CHANNELS.SESSION_CLOSE_RUNTIME, runtimeId),
469
+ switch: (sessionPath, cwd) => electron.ipcRenderer.invoke(IPC_CHANNELS.SESSION_SWITCH, sessionPath, cwd),
470
+ listRuntimes: () => electron.ipcRenderer.invoke(IPC_CHANNELS.SESSION_LIST_RUNTIMES),
471
+ fork: (entryId) => electron.ipcRenderer.invoke(IPC_CHANNELS.SESSION_FORK, entryId),
472
+ clone: () => electron.ipcRenderer.invoke(IPC_CHANNELS.SESSION_CLONE),
473
+ list: (cwd) => electron.ipcRenderer.invoke(IPC_CHANNELS.SESSION_LIST, cwd),
474
+ listAll: (cwd) => electron.ipcRenderer.invoke(IPC_CHANNELS.SESSION_LIST_ALL, cwd),
475
+ getState: () => electron.ipcRenderer.invoke(IPC_CHANNELS.SESSION_GET_STATE),
476
+ getMessages: () => electron.ipcRenderer.invoke(IPC_CHANNELS.SESSION_GET_MESSAGES),
477
+ getStats: () => electron.ipcRenderer.invoke(IPC_CHANNELS.SESSION_GET_STATS),
478
+ setName: (name) => electron.ipcRenderer.invoke(IPC_CHANNELS.SESSION_SET_NAME, name),
479
+ exportHtml: (outputPath) => electron.ipcRenderer.invoke(IPC_CHANNELS.SESSION_EXPORT_HTML, outputPath),
480
+ getForkMessages: () => electron.ipcRenderer.invoke(IPC_CHANNELS.SESSION_GET_FORK_MESSAGES),
481
+ getLineage: () => electron.ipcRenderer.invoke(IPC_CHANNELS.SESSION_GET_LINEAGE),
482
+ compact: (customInstructions) => electron.ipcRenderer.invoke(IPC_CHANNELS.SESSION_COMPACT, customInstructions),
483
+ delete: (sessionPath) => electron.ipcRenderer.invoke(IPC_CHANNELS.SESSION_DELETE, sessionPath),
484
+ archive: (sessionId) => electron.ipcRenderer.invoke(IPC_CHANNELS.SESSION_ARCHIVE, sessionId),
485
+ unarchive: (sessionId) => electron.ipcRenderer.invoke(IPC_CHANNELS.SESSION_UNARCHIVE, sessionId),
486
+ listArchived: () => electron.ipcRenderer.invoke(IPC_CHANNELS.SESSION_LIST_ARCHIVED)
487
+ },
488
+ model: {
489
+ set: (provider, modelId) => electron.ipcRenderer.invoke(IPC_CHANNELS.MODEL_SET, provider, modelId),
490
+ cycle: () => electron.ipcRenderer.invoke(IPC_CHANNELS.MODEL_CYCLE),
491
+ listAvailable: () => electron.ipcRenderer.invoke(IPC_CHANNELS.MODEL_LIST_AVAILABLE)
492
+ },
493
+ thinking: {
494
+ setLevel: (level) => electron.ipcRenderer.invoke(IPC_CHANNELS.THINKING_SET_LEVEL, level),
495
+ cycleLevel: () => electron.ipcRenderer.invoke(IPC_CHANNELS.THINKING_CYCLE_LEVEL)
496
+ },
497
+ settings: {
498
+ getAll: () => electron.ipcRenderer.invoke(IPC_CHANNELS.SETTINGS_GET_ALL),
499
+ save: (settings) => electron.ipcRenderer.invoke(IPC_CHANNELS.SETTINGS_SAVE, settings)
500
+ },
501
+ permissionRules: {
502
+ get: (scope) => electron.ipcRenderer.invoke(IPC_CHANNELS.PERMISSION_RULES_GET, scope),
503
+ set: (scope, rules) => electron.ipcRenderer.invoke(IPC_CHANNELS.PERMISSION_RULES_SET, scope, rules),
504
+ importFromFile: () => electron.ipcRenderer.invoke(IPC_CHANNELS.PERMISSION_RULES_IMPORT),
505
+ exportToFile: (rules) => electron.ipcRenderer.invoke(IPC_CHANNELS.PERMISSION_RULES_EXPORT, rules),
506
+ workspaceStatus: () => electron.ipcRenderer.invoke(IPC_CHANNELS.PERMISSION_RULES_WORKSPACE_STATUS),
507
+ removeWorkspace: () => electron.ipcRenderer.invoke(IPC_CHANNELS.PERMISSION_RULES_REMOVE_WORKSPACE),
508
+ setWorkspaceTrust: (trusted) => electron.ipcRenderer.invoke(IPC_CHANNELS.PERMISSION_RULES_SET_WORKSPACE_TRUST, trusted)
509
+ },
510
+ themes: {
511
+ list: () => electron.ipcRenderer.invoke(IPC_CHANNELS.THEMES_LIST),
512
+ save: (file, existingId) => electron.ipcRenderer.invoke(IPC_CHANNELS.THEMES_SAVE, file, existingId),
513
+ delete: (id) => electron.ipcRenderer.invoke(IPC_CHANNELS.THEMES_DELETE, id),
514
+ installFromUrl: (url) => electron.ipcRenderer.invoke(IPC_CHANNELS.THEMES_INSTALL_URL, url),
515
+ export: (file) => electron.ipcRenderer.invoke(IPC_CHANNELS.THEMES_EXPORT, file),
516
+ import: () => electron.ipcRenderer.invoke(IPC_CHANNELS.THEMES_IMPORT),
517
+ gallery: () => electron.ipcRenderer.invoke(IPC_CHANNELS.THEMES_GALLERY_LIST),
518
+ galleryImage: (url) => electron.ipcRenderer.invoke(IPC_CHANNELS.THEMES_GALLERY_IMAGE, url)
519
+ },
520
+ workspace: {
521
+ list: () => electron.ipcRenderer.invoke(IPC_CHANNELS.WORKSPACE_LIST),
522
+ create: (name, path) => electron.ipcRenderer.invoke(IPC_CHANNELS.WORKSPACE_CREATE, name, path),
523
+ remove: (workspaceId) => electron.ipcRenderer.invoke(IPC_CHANNELS.WORKSPACE_REMOVE, workspaceId),
524
+ rename: (workspaceId, name) => electron.ipcRenderer.invoke(IPC_CHANNELS.WORKSPACE_RENAME, workspaceId, name),
525
+ changePath: (workspaceId, newPath) => electron.ipcRenderer.invoke(IPC_CHANNELS.WORKSPACE_CHANGE_PATH, workspaceId, newPath),
526
+ pathExists: () => electron.ipcRenderer.invoke(IPC_CHANNELS.WORKSPACE_PATH_EXISTS),
527
+ setActive: (workspaceId) => electron.ipcRenderer.invoke(IPC_CHANNELS.WORKSPACE_SET_ACTIVE, workspaceId),
528
+ getActive: () => electron.ipcRenderer.invoke(IPC_CHANNELS.WORKSPACE_GET_ACTIVE),
529
+ startPi: (workspaceId, options) => electron.ipcRenderer.invoke(IPC_CHANNELS.WORKSPACE_START_PI, workspaceId, options),
530
+ stopPi: (workspaceId) => electron.ipcRenderer.invoke(IPC_CHANNELS.WORKSPACE_STOP_PI, workspaceId),
531
+ createTab: (options) => electron.ipcRenderer.invoke(IPC_CHANNELS.WORKSPACE_CREATE_TAB, options),
532
+ getActivity: () => electron.ipcRenderer.invoke(IPC_CHANNELS.WORKSPACE_ACTIVITY_GET),
533
+ takePendingActivation: () => electron.ipcRenderer.invoke(IPC_CHANNELS.WORKSPACE_TAKE_PENDING_ACTIVATION)
534
+ },
535
+ packages: {
536
+ listInstalled: () => electron.ipcRenderer.invoke(IPC_CHANNELS.PACKAGE_LIST_INSTALLED),
537
+ install: (spec) => electron.ipcRenderer.invoke(IPC_CHANNELS.PACKAGE_INSTALL, spec),
538
+ remove: (spec) => electron.ipcRenderer.invoke(IPC_CHANNELS.PACKAGE_REMOVE, spec),
539
+ update: (spec) => electron.ipcRenderer.invoke(IPC_CHANNELS.PACKAGE_UPDATE, spec),
540
+ updateAll: () => electron.ipcRenderer.invoke(IPC_CHANNELS.PACKAGE_UPDATE_ALL),
541
+ checkUpdates: () => electron.ipcRenderer.invoke(IPC_CHANNELS.PACKAGE_CHECK_UPDATES),
542
+ fetchCatalog: (query) => electron.ipcRenderer.invoke(IPC_CHANNELS.PACKAGE_CATALOG_FETCH, query)
543
+ },
544
+ models: {
545
+ read: () => electron.ipcRenderer.invoke(IPC_CHANNELS.MODELS_READ),
546
+ write: (config) => electron.ipcRenderer.invoke(IPC_CHANNELS.MODELS_WRITE, config)
547
+ },
548
+ council: {
549
+ detect: () => electron.ipcRenderer.invoke(IPC_CHANNELS.COUNCIL_DETECT),
550
+ runConsultants: (payload) => electron.ipcRenderer.invoke(IPC_CHANNELS.COUNCIL_RUN_CONSULTANTS, payload),
551
+ arbiter: (payload) => electron.ipcRenderer.invoke(IPC_CHANNELS.COUNCIL_ARBITER, payload),
552
+ onProgress: (callback) => {
553
+ const handler = (_event, data) => callback(data);
554
+ electron.ipcRenderer.on(IPC_CHANNELS.EVENT_COUNCIL_PROGRESS, handler);
555
+ return () => electron.ipcRenderer.removeListener(IPC_CHANNELS.EVENT_COUNCIL_PROGRESS, handler);
556
+ }
557
+ },
558
+ skills: {
559
+ list: () => electron.ipcRenderer.invoke(IPC_CHANNELS.SKILLS_LIST)
560
+ },
561
+ piCommands: {
562
+ list: () => electron.ipcRenderer.invoke(IPC_CHANNELS.COMMANDS_LIST)
563
+ },
564
+ mcpServers: {
565
+ list: () => electron.ipcRenderer.invoke(IPC_CHANNELS.MCP_SERVERS_LIST)
566
+ },
567
+ tags: {
568
+ get: (sessionId) => electron.ipcRenderer.invoke(IPC_CHANNELS.TAG_GET, sessionId),
569
+ set: (sessionId, tags) => electron.ipcRenderer.invoke(IPC_CHANNELS.TAG_SET, sessionId, tags),
570
+ add: (sessionId, tag) => electron.ipcRenderer.invoke(IPC_CHANNELS.TAG_ADD, sessionId, tag),
571
+ remove: (sessionId, tag) => electron.ipcRenderer.invoke(IPC_CHANNELS.TAG_REMOVE, sessionId, tag),
572
+ getAll: () => electron.ipcRenderer.invoke(IPC_CHANNELS.TAG_GET_ALL),
573
+ getAllUsed: () => electron.ipcRenderer.invoke(IPC_CHANNELS.TAG_GET_ALL_USED),
574
+ autoGetAll: () => electron.ipcRenderer.invoke(IPC_CHANNELS.TAG_AUTO_GET_ALL),
575
+ autoEnsure: (sessions) => electron.ipcRenderer.invoke(IPC_CHANNELS.TAG_AUTO_ENSURE, sessions),
576
+ autoRemove: (sessionId) => electron.ipcRenderer.invoke(IPC_CHANNELS.TAG_AUTO_REMOVE, sessionId)
577
+ },
578
+ git: {
579
+ status: () => electron.ipcRenderer.invoke(IPC_CHANNELS.GIT_CONVEYOR_STATUS),
580
+ commit: (options) => electron.ipcRenderer.invoke(IPC_CHANNELS.GIT_CONVEYOR_COMMIT, options),
581
+ push: () => electron.ipcRenderer.invoke(IPC_CHANNELS.GIT_CONVEYOR_PUSH),
582
+ createPullRequest: (options) => electron.ipcRenderer.invoke(IPC_CHANNELS.GIT_CONVEYOR_CREATE_PR, options)
583
+ },
584
+ notes: {
585
+ list: () => electron.ipcRenderer.invoke(IPC_CHANNELS.NOTES_LIST),
586
+ create: (input) => electron.ipcRenderer.invoke(IPC_CHANNELS.NOTES_CREATE, input),
587
+ update: (id, patch) => electron.ipcRenderer.invoke(IPC_CHANNELS.NOTES_UPDATE, id, patch),
588
+ remove: (id) => electron.ipcRenderer.invoke(IPC_CHANNELS.NOTES_REMOVE, id)
589
+ },
590
+ files: {
591
+ getTree: (maxDepth) => electron.ipcRenderer.invoke(IPC_CHANNELS.FILE_TREE, maxDepth),
592
+ search: (query) => electron.ipcRenderer.invoke(IPC_CHANNELS.FILE_SEARCH, query),
593
+ searchContent: (query) => electron.ipcRenderer.invoke(IPC_CHANNELS.FILE_SEARCH_CONTENT, query),
594
+ read: (path) => electron.ipcRenderer.invoke(IPC_CHANNELS.FILE_READ, path),
595
+ readAttachment: (path) => electron.ipcRenderer.invoke(IPC_CHANNELS.FILE_READ_ATTACHMENT, path),
596
+ write: (path, content) => electron.ipcRenderer.invoke(IPC_CHANNELS.FILE_WRITE, path, content),
597
+ getDiff: (filePath) => electron.ipcRenderer.invoke(IPC_CHANNELS.FILE_DIFF, filePath),
598
+ getStagedDiff: (filePath) => electron.ipcRenderer.invoke(IPC_CHANNELS.FILE_STAGED_DIFF, filePath),
599
+ getGitStatus: () => electron.ipcRenderer.invoke(IPC_CHANNELS.GIT_STATUS),
600
+ getGitBranch: () => electron.ipcRenderer.invoke(IPC_CHANNELS.GIT_BRANCH)
601
+ },
602
+ system: {
603
+ openDialog: (options) => electron.ipcRenderer.invoke(IPC_CHANNELS.SYSTEM_OPEN_DIALOG, options),
604
+ getPath: (name) => electron.ipcRenderer.invoke(IPC_CHANNELS.SYSTEM_GET_PATH, name),
605
+ getPathForFile: (file) => electron.webUtils.getPathForFile(file),
606
+ pathKind: (path) => electron.ipcRenderer.invoke(IPC_CHANNELS.SYSTEM_PATH_KIND, path),
607
+ platform: process.platform,
608
+ openExternal: (url) => electron.ipcRenderer.invoke(IPC_CHANNELS.SYSTEM_OPEN_EXTERNAL, url),
609
+ hallUrl: () => electron.ipcRenderer.invoke(IPC_CHANNELS.SYSTEM_HALL_URL),
610
+ getVersion: () => electron.ipcRenderer.invoke(IPC_CHANNELS.SYSTEM_GET_VERSION)
611
+ },
612
+ activity: {
613
+ getStats: () => electron.ipcRenderer.invoke(IPC_CHANNELS.ACTIVITY_GET_STATS)
614
+ },
615
+ workflows: {
616
+ list: () => electron.ipcRenderer.invoke(IPC_CHANNELS.WORKFLOW_LIST),
617
+ getRun: (workspaceId, runId) => electron.ipcRenderer.invoke(IPC_CHANNELS.WORKFLOW_GET_RUN, workspaceId, runId),
618
+ control: (workspaceId, runId, action) => electron.ipcRenderer.invoke(IPC_CHANNELS.WORKFLOW_CONTROL, workspaceId, runId, action),
619
+ setPersistAgentSessions: (enabled) => electron.ipcRenderer.invoke(IPC_CHANNELS.WORKFLOW_SET_PERSISTENCE, enabled)
620
+ },
621
+ diagnostics: {
622
+ get: () => electron.ipcRenderer.invoke(IPC_CHANNELS.DIAGNOSTICS_GET)
623
+ },
624
+ updates: {
625
+ check: () => electron.ipcRenderer.invoke(IPC_CHANNELS.UPDATE_CHECK)
626
+ },
627
+ i18n: {
628
+ getEnvironment: () => electron.ipcRenderer.invoke(IPC_CHANNELS.I18N_GET_ENVIRONMENT)
629
+ },
630
+ terminal: {
631
+ start: (options) => electron.ipcRenderer.invoke(IPC_CHANNELS.TERMINAL_START, options),
632
+ input: (data) => electron.ipcRenderer.invoke(IPC_CHANNELS.TERMINAL_INPUT, data),
633
+ resize: (cols, rows) => electron.ipcRenderer.invoke(IPC_CHANNELS.TERMINAL_RESIZE, { cols, rows }),
634
+ stop: () => electron.ipcRenderer.invoke(IPC_CHANNELS.TERMINAL_STOP),
635
+ onData: (callback) => {
636
+ const handler = (_event, data) => callback(data);
637
+ electron.ipcRenderer.on(IPC_CHANNELS.EVENT_TERMINAL_DATA, handler);
638
+ return () => electron.ipcRenderer.removeListener(IPC_CHANNELS.EVENT_TERMINAL_DATA, handler);
639
+ },
640
+ onExit: (callback) => {
641
+ const handler = (_event, data) => callback(data);
642
+ electron.ipcRenderer.on(IPC_CHANNELS.EVENT_TERMINAL_EXIT, handler);
643
+ return () => electron.ipcRenderer.removeListener(IPC_CHANNELS.EVENT_TERMINAL_EXIT, handler);
644
+ }
645
+ },
646
+ ui: {
647
+ respondSelect: (id, value) => electron.ipcRenderer.invoke(IPC_CHANNELS.UI_SELECT_RESPONSE, id, value),
648
+ respondConfirm: (id, confirmed) => electron.ipcRenderer.invoke(IPC_CHANNELS.UI_CONFIRM_RESPONSE, id, confirmed),
649
+ respondInput: (id, value) => electron.ipcRenderer.invoke(IPC_CHANNELS.UI_INPUT_RESPONSE, id, value),
650
+ respondEditor: (id, value) => electron.ipcRenderer.invoke(IPC_CHANNELS.UI_EDITOR_RESPONSE, id, value),
651
+ flushPendingPrompts: (workspaceId) => electron.ipcRenderer.invoke(IPC_CHANNELS.UI_PENDING_FLUSH, workspaceId),
652
+ getPendingPrompts: () => electron.ipcRenderer.invoke(IPC_CHANNELS.UI_PENDING_GET),
653
+ setEditorDirty: (dirty, fileName) => electron.ipcRenderer.send(
654
+ IPC_CHANNELS.UI_EDITOR_DIRTY_SET,
655
+ dirty === true,
656
+ typeof fileName === "string" ? fileName : null
657
+ )
658
+ },
659
+ onEvent: (callback) => {
660
+ const handler = (_event, data) => callback(data);
661
+ electron.ipcRenderer.on(IPC_CHANNELS.EVENT_PI, handler);
662
+ return () => {
663
+ electron.ipcRenderer.removeListener(IPC_CHANNELS.EVENT_PI, handler);
664
+ };
665
+ },
666
+ onPendingPrompts: (callback) => {
667
+ const handler = (_event, data) => callback(data);
668
+ electron.ipcRenderer.on(IPC_CHANNELS.EVENT_PENDING_PROMPTS, handler);
669
+ return () => {
670
+ electron.ipcRenderer.removeListener(IPC_CHANNELS.EVENT_PENDING_PROMPTS, handler);
671
+ };
672
+ },
673
+ onWorkspaceActivity: (callback) => {
674
+ const handler = (_event, data) => callback(data);
675
+ electron.ipcRenderer.on(IPC_CHANNELS.EVENT_WORKSPACE_ACTIVITY, handler);
676
+ return () => {
677
+ electron.ipcRenderer.removeListener(IPC_CHANNELS.EVENT_WORKSPACE_ACTIVITY, handler);
678
+ };
679
+ },
680
+ onSessionRuntime: (callback) => {
681
+ const handler = (_event, data) => callback(data);
682
+ electron.ipcRenderer.on(IPC_CHANNELS.EVENT_SESSION_RUNTIME, handler);
683
+ return () => {
684
+ electron.ipcRenderer.removeListener(IPC_CHANNELS.EVENT_SESSION_RUNTIME, handler);
685
+ };
686
+ },
687
+ onActivateWorkspace: (callback) => {
688
+ const handler = (_event, data) => callback(data);
689
+ electron.ipcRenderer.on(IPC_CHANNELS.EVENT_ACTIVATE_WORKSPACE, handler);
690
+ return () => {
691
+ electron.ipcRenderer.removeListener(IPC_CHANNELS.EVENT_ACTIVATE_WORKSPACE, handler);
692
+ };
693
+ },
694
+ onFileChange: (callback) => {
695
+ const handler = (_event, data) => callback(data);
696
+ electron.ipcRenderer.on(IPC_CHANNELS.EVENT_FILE_CHANGE, handler);
697
+ return () => {
698
+ electron.ipcRenderer.removeListener(IPC_CHANNELS.EVENT_FILE_CHANGE, handler);
699
+ };
700
+ },
701
+ onMenuAction: (callback) => {
702
+ const handlers = [];
703
+ const actions = ["menu:new-session", "menu:new-workspace", "menu:open-project"];
704
+ for (const action of actions) {
705
+ const handler = () => callback(action);
706
+ electron.ipcRenderer.on(action, handler);
707
+ handlers.push(() => electron.ipcRenderer.removeListener(action, handler));
708
+ }
709
+ return () => {
710
+ for (const cleanup of handlers) cleanup();
711
+ };
712
+ }
713
+ };
714
+ return api;
715
+ }
716
+ return createHttpBridge();
717
+ }
718
+ const bridge = createBridge();
719
+ electron.contextBridge.exposeInMainWorld("piDesktop", bridge);