@steerable/agent-shell 0.6.15

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 (204) hide show
  1. package/LICENSE +91 -0
  2. package/contracts/tool-contract.json +326 -0
  3. package/dist/attachments.d.ts +41 -0
  4. package/dist/attachments.js +147 -0
  5. package/dist/brand.d.ts +24 -0
  6. package/dist/brand.js +92 -0
  7. package/dist/host/http-routes.d.ts +21 -0
  8. package/dist/host/http-routes.js +55 -0
  9. package/dist/host/ipc.d.ts +11 -0
  10. package/dist/host/ipc.js +20 -0
  11. package/dist/host/pack-assembly.d.ts +86 -0
  12. package/dist/host/pack-assembly.js +32 -0
  13. package/dist/host/runtime.d.ts +69 -0
  14. package/dist/host/runtime.js +207 -0
  15. package/dist/host/visible-terminal-exec.d.ts +21 -0
  16. package/dist/host/visible-terminal-exec.js +151 -0
  17. package/dist/hosted-web-search.d.ts +13 -0
  18. package/dist/hosted-web-search.js +82 -0
  19. package/dist/image-attachment.d.ts +39 -0
  20. package/dist/image-attachment.js +133 -0
  21. package/dist/insights/flush.d.ts +10 -0
  22. package/dist/insights/flush.js +139 -0
  23. package/dist/insights/record.d.ts +17 -0
  24. package/dist/insights/record.js +44 -0
  25. package/dist/json-store.d.ts +9 -0
  26. package/dist/json-store.js +22 -0
  27. package/dist/llm/index.d.ts +23 -0
  28. package/dist/llm/index.js +105 -0
  29. package/dist/llm/ollama.d.ts +23 -0
  30. package/dist/llm/ollama.js +242 -0
  31. package/dist/llm/openai-compat.d.ts +20 -0
  32. package/dist/llm/openai-compat.js +199 -0
  33. package/dist/llm/sidecar-provider.d.ts +37 -0
  34. package/dist/llm/sidecar-provider.js +163 -0
  35. package/dist/llm/tool-choice.d.ts +35 -0
  36. package/dist/llm/tool-choice.js +85 -0
  37. package/dist/llm/types.d.ts +122 -0
  38. package/dist/llm/types.js +1 -0
  39. package/dist/local-backend/agent-capability.d.ts +101 -0
  40. package/dist/local-backend/agent-capability.js +174 -0
  41. package/dist/local-backend/ai-title.d.ts +43 -0
  42. package/dist/local-backend/ai-title.js +173 -0
  43. package/dist/local-backend/auto-continue-helper.d.ts +80 -0
  44. package/dist/local-backend/auto-continue-helper.js +83 -0
  45. package/dist/local-backend/branch-helper.d.ts +24 -0
  46. package/dist/local-backend/branch-helper.js +27 -0
  47. package/dist/local-backend/context-compactor.d.ts +81 -0
  48. package/dist/local-backend/context-compactor.js +213 -0
  49. package/dist/local-backend/coreloop-stream.d.ts +245 -0
  50. package/dist/local-backend/coreloop-stream.js +277 -0
  51. package/dist/local-backend/deferred-detector.d.ts +15 -0
  52. package/dist/local-backend/deferred-detector.js +124 -0
  53. package/dist/local-backend/history-helper.d.ts +30 -0
  54. package/dist/local-backend/history-helper.js +34 -0
  55. package/dist/local-backend/interrupted-helper.d.ts +29 -0
  56. package/dist/local-backend/interrupted-helper.js +25 -0
  57. package/dist/local-backend/live-stream.d.ts +36 -0
  58. package/dist/local-backend/live-stream.js +23 -0
  59. package/dist/local-backend/llm-diagnose.d.ts +37 -0
  60. package/dist/local-backend/llm-diagnose.js +284 -0
  61. package/dist/local-backend/message-triggers.d.ts +27 -0
  62. package/dist/local-backend/message-triggers.js +67 -0
  63. package/dist/local-backend/pack-backend-routes.d.ts +31 -0
  64. package/dist/local-backend/pack-backend-routes.js +62 -0
  65. package/dist/local-backend/pack-turn-hooks.d.ts +37 -0
  66. package/dist/local-backend/pack-turn-hooks.js +67 -0
  67. package/dist/local-backend/prompt-builder.d.ts +101 -0
  68. package/dist/local-backend/prompt-builder.js +246 -0
  69. package/dist/local-backend/regenerate-helper.d.ts +62 -0
  70. package/dist/local-backend/regenerate-helper.js +75 -0
  71. package/dist/local-backend/router.d.ts +175 -0
  72. package/dist/local-backend/router.js +3139 -0
  73. package/dist/local-backend/skill-install.d.ts +19 -0
  74. package/dist/local-backend/skill-install.js +71 -0
  75. package/dist/local-backend/skill-loader.d.ts +92 -0
  76. package/dist/local-backend/skill-loader.js +146 -0
  77. package/dist/local-backend/skills/00-identity/SKILL.md +32 -0
  78. package/dist/local-backend/skills/10-goal/SKILL.md +59 -0
  79. package/dist/local-backend/skills/11-loop/SKILL.md +71 -0
  80. package/dist/local-backend/skills/12-create-skill/SKILL.md +88 -0
  81. package/dist/local-backend/skills/70-plan-mode/SKILL.md +58 -0
  82. package/dist/local-backend/skills/80-tool-usage/SKILL.md +70 -0
  83. package/dist/local-backend/skills/81-anti-deferred/SKILL.md +53 -0
  84. package/dist/local-backend/skills/82-data-grounding/SKILL.md +56 -0
  85. package/dist/local-backend/skills/85-local-exec/SKILL.md +86 -0
  86. package/dist/local-backend/skills/86-proactive-coding/SKILL.md +51 -0
  87. package/dist/local-backend/subagent-profiles.d.ts +30 -0
  88. package/dist/local-backend/subagent-profiles.js +74 -0
  89. package/dist/local-backend/task-process.d.ts +12 -0
  90. package/dist/local-backend/task-process.js +176 -0
  91. package/dist/local-backend/task-service.d.ts +135 -0
  92. package/dist/local-backend/task-service.js +565 -0
  93. package/dist/local-backend/turn-duration.d.ts +2 -0
  94. package/dist/local-backend/turn-duration.js +9 -0
  95. package/dist/local-backend/turn-timeline.d.ts +16 -0
  96. package/dist/local-backend/turn-timeline.js +42 -0
  97. package/dist/local-backend/worktree-service.d.ts +84 -0
  98. package/dist/local-backend/worktree-service.js +243 -0
  99. package/dist/local-edit.d.ts +48 -0
  100. package/dist/local-edit.js +44 -0
  101. package/dist/local-executor.d.ts +255 -0
  102. package/dist/local-executor.js +881 -0
  103. package/dist/local-script-registry.d.ts +28 -0
  104. package/dist/local-script-registry.js +63 -0
  105. package/dist/log.d.ts +13 -0
  106. package/dist/log.js +12 -0
  107. package/dist/main.d.ts +1 -0
  108. package/dist/main.js +855 -0
  109. package/dist/mcp-executor.d.ts +45 -0
  110. package/dist/mcp-executor.js +241 -0
  111. package/dist/mcp-server-registry.d.ts +104 -0
  112. package/dist/mcp-server-registry.js +234 -0
  113. package/dist/preload-default.d.ts +1 -0
  114. package/dist/preload-default.js +9 -0
  115. package/dist/preload.cjs +395 -0
  116. package/dist/preload.d.ts +20 -0
  117. package/dist/preload.js +411 -0
  118. package/dist/product-config.d.ts +43 -0
  119. package/dist/product-config.js +26 -0
  120. package/dist/project-registry.d.ts +55 -0
  121. package/dist/project-registry.js +106 -0
  122. package/dist/project-rules.d.ts +15 -0
  123. package/dist/project-rules.js +102 -0
  124. package/dist/runtime.d.ts +62 -0
  125. package/dist/runtime.js +217 -0
  126. package/dist/scenario/pack.d.ts +8 -0
  127. package/dist/scenario/pack.js +1 -0
  128. package/dist/scenario/registry.d.ts +24 -0
  129. package/dist/scenario/registry.js +31 -0
  130. package/dist/server/http-server.d.ts +39 -0
  131. package/dist/server/http-server.js +361 -0
  132. package/dist/server/index.d.ts +1 -0
  133. package/dist/server/index.js +107 -0
  134. package/dist/server/sse-bus.d.ts +14 -0
  135. package/dist/server/sse-bus.js +31 -0
  136. package/dist/shell-adapt.d.ts +21 -0
  137. package/dist/shell-adapt.js +104 -0
  138. package/dist/sidecar/boot.d.ts +36 -0
  139. package/dist/sidecar/boot.js +343 -0
  140. package/dist/sidecar/egress-hint.d.ts +15 -0
  141. package/dist/sidecar/egress-hint.js +46 -0
  142. package/dist/sidecar/egress-proxy.d.ts +183 -0
  143. package/dist/sidecar/egress-proxy.js +419 -0
  144. package/dist/sidecar/errors.d.ts +22 -0
  145. package/dist/sidecar/errors.js +38 -0
  146. package/dist/sidecar/exec-sandbox.d.ts +48 -0
  147. package/dist/sidecar/exec-sandbox.js +94 -0
  148. package/dist/sidecar/handle.d.ts +32 -0
  149. package/dist/sidecar/handle.js +53 -0
  150. package/dist/sidecar/index.d.ts +14 -0
  151. package/dist/sidecar/index.js +13 -0
  152. package/dist/sidecar/proxy-detect.d.ts +50 -0
  153. package/dist/sidecar/proxy-detect.js +182 -0
  154. package/dist/sidecar/reverse-approval.d.ts +55 -0
  155. package/dist/sidecar/reverse-approval.js +86 -0
  156. package/dist/sidecar/reverse-ask-user.d.ts +34 -0
  157. package/dist/sidecar/reverse-ask-user.js +59 -0
  158. package/dist/sidecar/reverse-spawn.d.ts +19 -0
  159. package/dist/sidecar/reverse-spawn.js +161 -0
  160. package/dist/sidecar/reverse-tools.d.ts +29 -0
  161. package/dist/sidecar/reverse-tools.js +106 -0
  162. package/dist/sidecar/safety-patterns.d.ts +41 -0
  163. package/dist/sidecar/safety-patterns.js +157 -0
  164. package/dist/sidecar/storage-path.d.ts +14 -0
  165. package/dist/sidecar/storage-path.js +35 -0
  166. package/dist/sidecar/supervisor.d.ts +218 -0
  167. package/dist/sidecar/supervisor.js +932 -0
  168. package/dist/sidecar/types.d.ts +601 -0
  169. package/dist/sidecar/types.js +1 -0
  170. package/dist/single-instance.d.ts +11 -0
  171. package/dist/single-instance.js +21 -0
  172. package/dist/storage/empty-chats.d.ts +9 -0
  173. package/dist/storage/empty-chats.js +16 -0
  174. package/dist/storage/index.d.ts +373 -0
  175. package/dist/storage/index.js +1158 -0
  176. package/dist/storage/insights-redact.d.ts +2 -0
  177. package/dist/storage/insights-redact.js +30 -0
  178. package/dist/storage/insights-settings.d.ts +53 -0
  179. package/dist/storage/insights-settings.js +92 -0
  180. package/dist/storage/llm-settings.d.ts +120 -0
  181. package/dist/storage/llm-settings.js +233 -0
  182. package/dist/storage/local-store-singleton.d.ts +28 -0
  183. package/dist/storage/local-store-singleton.js +38 -0
  184. package/dist/storage/message-order.d.ts +25 -0
  185. package/dist/storage/message-order.js +27 -0
  186. package/dist/storage/pack-migrations.d.ts +22 -0
  187. package/dist/storage/pack-migrations.js +24 -0
  188. package/dist/storage/pack-seeds.d.ts +36 -0
  189. package/dist/storage/pack-seeds.js +42 -0
  190. package/dist/storage/telemetry-settings.d.ts +38 -0
  191. package/dist/storage/telemetry-settings.js +59 -0
  192. package/dist/storage/usage-summary.d.ts +55 -0
  193. package/dist/storage/usage-summary.js +38 -0
  194. package/dist/storage/web-search-settings.d.ts +38 -0
  195. package/dist/storage/web-search-settings.js +74 -0
  196. package/dist/storage/write-lease.d.ts +26 -0
  197. package/dist/storage/write-lease.js +74 -0
  198. package/dist/terminal-manager.d.ts +83 -0
  199. package/dist/terminal-manager.js +506 -0
  200. package/dist/tool-router.d.ts +228 -0
  201. package/dist/tool-router.js +930 -0
  202. package/dist/tool-search-rank.d.ts +42 -0
  203. package/dist/tool-search-rank.js +96 -0
  204. package/package.json +67 -0
package/LICENSE ADDED
@@ -0,0 +1,91 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity.
18
+
19
+ "You" (or "Your") shall mean an individual or Legal Entity
20
+ exercising permissions granted by this License.
21
+
22
+ "Source" form shall mean the preferred form for making modifications.
23
+
24
+ "Object" form shall mean any form resulting from mechanical
25
+ transformation or translation of a Source form.
26
+
27
+ "Work" shall mean the work of authorship made available under the
28
+ License.
29
+
30
+ "Derivative Works" shall mean any work based on the Work.
31
+
32
+ "Contribution" shall mean any work of authorship intentionally
33
+ submitted to Licensor for inclusion in the Work.
34
+
35
+ "Contributor" shall mean Licensor and any individual or Legal Entity
36
+ on behalf of whom a Contribution has been received by Licensor.
37
+
38
+ 2. Grant of Copyright License.
39
+ Subject to the terms and conditions of this License, each Contributor
40
+ hereby grants to You a perpetual, worldwide, non-exclusive, no-charge,
41
+ royalty-free, irrevocable copyright license to reproduce, prepare
42
+ Derivative Works of, publicly display, publicly perform, sublicense,
43
+ and distribute the Work and such Derivative Works in Source or Object
44
+ form.
45
+
46
+ 3. Grant of Patent License.
47
+ Subject to the terms and conditions of this License, each Contributor
48
+ hereby grants to You a perpetual, worldwide, non-exclusive, no-charge,
49
+ royalty-free, irrevocable patent license to make, have made, use,
50
+ offer to sell, sell, import, and otherwise transfer the Work.
51
+
52
+ 4. Redistribution.
53
+ You may reproduce and distribute copies of the Work or Derivative
54
+ Works thereof in any medium, with or without modifications, and in
55
+ Source or Object form, provided that You meet the following conditions:
56
+
57
+ (a) You must give any other recipients of the Work or Derivative
58
+ Works a copy of this License; and
59
+ (b) You must cause any modified files to carry prominent notices
60
+ stating that You changed the files; and
61
+ (c) You must retain, in the Source form of any Derivative Works that
62
+ You distribute, all copyright, patent, trademark, and attribution
63
+ notices from the Source form of the Work; and
64
+ (d) If the Work includes a "NOTICE" text file as part of its
65
+ distribution, then any Derivative Works that You distribute must
66
+ include a readable copy of the attribution notices contained within
67
+ such NOTICE file.
68
+
69
+ 5. Submission of Contributions.
70
+ Unless You explicitly state otherwise, any Contribution intentionally
71
+ submitted for inclusion in the Work shall be under the terms and
72
+ conditions of this License.
73
+
74
+ 6. Trademarks.
75
+ This License does not grant permission to use the trade names,
76
+ trademarks, service marks, or product names of the Licensor.
77
+
78
+ 7. Disclaimer of Warranty.
79
+ Unless required by applicable law or agreed to in writing, Licensor
80
+ provides the Work on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
81
+ OF ANY KIND.
82
+
83
+ 8. Limitation of Liability.
84
+ In no event and under no legal theory shall any Contributor be liable
85
+ to You for damages arising as a result of this License or out of the
86
+ use or inability to use the Work.
87
+
88
+ 9. Accepting Warranty or Additional Liability.
89
+ While redistributing the Work or Derivative Works thereof, You may
90
+ choose to offer, and charge a fee for, acceptance of support, warranty,
91
+ indemnity, or other liability obligations.
@@ -0,0 +1,326 @@
1
+ {
2
+ "edit": {
3
+ "atomic": true,
4
+ "errorCodes": [
5
+ "empty_old",
6
+ "no_edits",
7
+ "ambiguous",
8
+ "not_found",
9
+ "overlap"
10
+ ],
11
+ "matchLevels": [
12
+ "exact",
13
+ "trim",
14
+ "unicode"
15
+ ],
16
+ "newField": "newText",
17
+ "oldField": "oldText",
18
+ "overlap": "reject"
19
+ },
20
+ "toolSearch": {
21
+ "bm25": {
22
+ "b": 0.75,
23
+ "k1": 1.2,
24
+ "nameWeight": 2
25
+ },
26
+ "defaultMaxResults": 8,
27
+ "inventory": [
28
+ {
29
+ "description": "Create a new issue in a GitHub repository",
30
+ "name": "mcp__github__create_issue"
31
+ },
32
+ {
33
+ "description": "Search issues and pull requests in a repository",
34
+ "name": "mcp__github__search_issues"
35
+ },
36
+ {
37
+ "description": "List repositories for the authenticated user",
38
+ "name": "mcp__github__list_repos"
39
+ },
40
+ {
41
+ "description": "Post a message to a Slack channel",
42
+ "name": "mcp__slack__post_message"
43
+ },
44
+ {
45
+ "description": "Search messages across Slack channels",
46
+ "name": "mcp__slack__search_messages"
47
+ },
48
+ {
49
+ "description": "Create an issue in a Linear workspace",
50
+ "name": "mcp__linear__create_issue"
51
+ },
52
+ {
53
+ "description": "Read a file from the local workspace",
54
+ "name": "local_read_file"
55
+ },
56
+ {
57
+ "description": "A tool whose entire name is one query term",
58
+ "name": "issue"
59
+ }
60
+ ],
61
+ "maxResultsCeiling": 20,
62
+ "scoreTolerance": 1e-12,
63
+ "scoreVectors": [
64
+ {
65
+ "query": "github",
66
+ "ranked": [
67
+ {
68
+ "name": "mcp__github__create_issue",
69
+ "score": 1.443104830718
70
+ },
71
+ {
72
+ "name": "mcp__github__list_repos",
73
+ "score": 1.30187499838
74
+ },
75
+ {
76
+ "name": "mcp__github__search_issues",
77
+ "score": 1.251896326088
78
+ }
79
+ ]
80
+ },
81
+ {
82
+ "query": "create issue",
83
+ "ranked": [
84
+ {
85
+ "name": "mcp__linear__create_issue",
86
+ "score": 3.451237117528
87
+ },
88
+ {
89
+ "name": "mcp__github__create_issue",
90
+ "score": 3.400327657896
91
+ },
92
+ {
93
+ "name": "issue",
94
+ "score": 1.384801863508
95
+ }
96
+ ]
97
+ },
98
+ {
99
+ "query": "message",
100
+ "ranked": [
101
+ {
102
+ "name": "mcp__slack__post_message",
103
+ "score": 2.778736145041
104
+ }
105
+ ]
106
+ },
107
+ {
108
+ "query": "search",
109
+ "ranked": [
110
+ {
111
+ "name": "mcp__slack__search_messages",
112
+ "score": 2.047846649401
113
+ },
114
+ {
115
+ "name": "mcp__github__search_issues",
116
+ "score": 1.957222827178
117
+ }
118
+ ]
119
+ },
120
+ {
121
+ "query": "issue repository",
122
+ "ranked": [
123
+ {
124
+ "name": "mcp__github__create_issue",
125
+ "score": 2.658061541828
126
+ },
127
+ {
128
+ "name": "mcp__linear__create_issue",
129
+ "score": 1.464710891814
130
+ },
131
+ {
132
+ "name": "issue",
133
+ "score": 1.384801863508
134
+ },
135
+ {
136
+ "name": "mcp__github__search_issues",
137
+ "score": 1.21495671111
138
+ }
139
+ ]
140
+ },
141
+ {
142
+ "query": "issue",
143
+ "ranked": [
144
+ {
145
+ "name": "mcp__linear__create_issue",
146
+ "score": 1.464710891814
147
+ },
148
+ {
149
+ "name": "mcp__github__create_issue",
150
+ "score": 1.443104830718
151
+ },
152
+ {
153
+ "name": "issue",
154
+ "score": 1.384801863508
155
+ }
156
+ ]
157
+ },
158
+ {
159
+ "query": "create",
160
+ "ranked": [
161
+ {
162
+ "name": "mcp__linear__create_issue",
163
+ "score": 1.986526225713
164
+ },
165
+ {
166
+ "name": "mcp__github__create_issue",
167
+ "score": 1.957222827178
168
+ }
169
+ ]
170
+ },
171
+ {
172
+ "query": "slack channel",
173
+ "ranked": [
174
+ {
175
+ "name": "mcp__slack__post_message",
176
+ "score": 3.734001329872
177
+ },
178
+ {
179
+ "name": "mcp__slack__search_messages",
180
+ "score": 2.047846649401
181
+ }
182
+ ]
183
+ },
184
+ {
185
+ "query": "linear workspace search",
186
+ "ranked": [
187
+ {
188
+ "name": "mcp__linear__create_issue",
189
+ "score": 4.028010974315
190
+ },
191
+ {
192
+ "name": "mcp__slack__search_messages",
193
+ "score": 2.047846649401
194
+ },
195
+ {
196
+ "name": "mcp__github__search_issues",
197
+ "score": 1.957222827178
198
+ },
199
+ {
200
+ "name": "local_read_file",
201
+ "score": 1.324075484332
202
+ }
203
+ ]
204
+ },
205
+ {
206
+ "query": "mcp",
207
+ "ranked": [
208
+ {
209
+ "name": "mcp__slack__search_messages",
210
+ "score": 0.4577086775
211
+ },
212
+ {
213
+ "name": "mcp__github__list_repos",
214
+ "score": 0.448572269188
215
+ },
216
+ {
217
+ "name": "mcp__linear__create_issue",
218
+ "score": 0.439793469682
219
+ },
220
+ {
221
+ "name": "mcp__slack__post_message",
222
+ "score": 0.439793469682
223
+ },
224
+ {
225
+ "name": "mcp__github__create_issue",
226
+ "score": 0.431351686207
227
+ },
228
+ {
229
+ "name": "mcp__github__search_issues",
230
+ "score": 0.431351686207
231
+ }
232
+ ]
233
+ },
234
+ {
235
+ "query": "kubernetes helm rollout",
236
+ "ranked": []
237
+ },
238
+ {
239
+ "query": "zzz",
240
+ "ranked": []
241
+ }
242
+ ],
243
+ "tieBreak": "score descending, then name ascending"
244
+ },
245
+ "tools": {
246
+ "bash": {
247
+ "desktopName": "local_exec_shell",
248
+ "requiredInput": [
249
+ "command"
250
+ ],
251
+ "requiredResult": [
252
+ "exitCode",
253
+ "stdout",
254
+ "stderr"
255
+ ]
256
+ },
257
+ "edit_file": {
258
+ "desktopName": "local_edit_file",
259
+ "optionalInput": [
260
+ "expectedVersion"
261
+ ],
262
+ "requiredInput": [
263
+ "path",
264
+ "edits"
265
+ ],
266
+ "requiredResult": [
267
+ "version",
268
+ "diff",
269
+ "applied",
270
+ "matches"
271
+ ]
272
+ },
273
+ "read_file": {
274
+ "desktopName": "local_read_file",
275
+ "requiredInput": [
276
+ "path"
277
+ ],
278
+ "requiredResult": [
279
+ "content",
280
+ "version"
281
+ ]
282
+ },
283
+ "write_file": {
284
+ "desktopName": "local_write_file",
285
+ "optionalInput": [
286
+ "expectedVersion"
287
+ ],
288
+ "requiredInput": [
289
+ "path",
290
+ "content"
291
+ ],
292
+ "requiredResult": [
293
+ "version"
294
+ ]
295
+ }
296
+ },
297
+ "version": 2,
298
+ "versionAlgorithm": "sha256-utf8-hex",
299
+ "versionToken": {
300
+ "inputField": "expectedVersion",
301
+ "onConflict": "reject",
302
+ "resultField": "version"
303
+ },
304
+ "versionVectors": [
305
+ {
306
+ "input": "",
307
+ "sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
308
+ },
309
+ {
310
+ "input": "hello world",
311
+ "sha256": "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"
312
+ },
313
+ {
314
+ "input": "中文测试",
315
+ "sha256": "e350545d18735c5dd2dec50dcb971f3eb4cdda24b95a79bdb6b553f6a01ceb87"
316
+ },
317
+ {
318
+ "input": "line1\nline2\n",
319
+ "sha256": "2751a3a2f303ad21752038085e2b8c5f98ecff61a2e4ebbd43506a941725be80"
320
+ },
321
+ {
322
+ "input": "The quick brown fox jumps over the lazy dog 中文 123",
323
+ "sha256": "58117d7814c853d4309001a610af6de66b4b2e73dadff71ab5514ea674218644"
324
+ }
325
+ ]
326
+ }
@@ -0,0 +1,41 @@
1
+ export declare const ATTACHMENTS_DIR_NAME = "attachments";
2
+ /** 单个附件上限(base64 解码前字节数);多文件总和还受 HTTP body 上限约束。 */
3
+ export declare const ATTACHMENT_MAX_BYTES: number;
4
+ export interface AttachmentInput {
5
+ /** Electron:源文件绝对路径。 */
6
+ path?: string;
7
+ /** 原始文件名(用于落盘命名)。 */
8
+ name?: string;
9
+ /** BS/browser:base64 编码的文件字节。 */
10
+ data?: string;
11
+ }
12
+ export interface StoredAttachment {
13
+ /** 落盘后的文件名(可能与原名不同,同名会加 -N 后缀)。 */
14
+ name: string;
15
+ /** 落盘后的绝对路径。失败时为空串。 */
16
+ path: string;
17
+ /** 文件字节数。失败时为 0。 */
18
+ size: number;
19
+ /** 单个文件失败原因(成功时缺省)。 */
20
+ error?: string;
21
+ }
22
+ export declare function isValidChatAttachmentsKey(chatId: string): boolean;
23
+ /**
24
+ * 当前会话的附件目录(会确保目录存在)。chatId 非法时仍然返回路径但由
25
+ * 调用方在写入前用 {@link isValidChatAttachmentsKey} 校验。
26
+ */
27
+ export declare function getChatAttachmentsDir(chatId: string): string;
28
+ /** 去掉路径分隔符与控制字符,只保留安全的文件名。 */
29
+ export declare function sanitizeName(name: string): string;
30
+ /** 同名文件加 -1 / -2 后缀,避免覆盖已有附件。 */
31
+ export declare function uniqueFileName(dir: string, name: string): string;
32
+ /**
33
+ * 把一批附件落进会话附件目录。按输入顺序返回逐文件结果(成功或失败都
34
+ * 不会中断整批),调用方据此决定哪些文件可用。
35
+ *
36
+ * 每个文件二选一提供来源:`path`(服务端直接拷贝)或 `data`(base64 字节,
37
+ * 服务端解码落盘)。两者都缺时记 error;两者都有时优先 `data`。
38
+ */
39
+ export declare function saveAttachmentFiles(chatId: string, files: AttachmentInput[]): Promise<{
40
+ files: StoredAttachment[];
41
+ }>;
@@ -0,0 +1,147 @@
1
+ /**
2
+ * 会话附件空间:把用户在输入框上传的文件持久化到会话对应的空间内。
3
+ *
4
+ * 每个会话一个独立目录:`<userDataDir>/attachments/<chatId>/`。持久化的
5
+ * 好处与场景包的每会话工作区(<pack>-projects/<chatId>)一致:
6
+ * - 文件不再依赖「原始路径」——用户拖进来的临时下载文件、截图被移动 /
7
+ * 删除后,会话里的引用仍然有效;
8
+ * - 后续轮次 agent 可以通过 `local_read_file`(以及图像附件的多模态
9
+ * `metadata.images`)稳定读回这份文件;
10
+ * - 目录按 chatId 隔离,删除会话时(未来的清理逻辑)可以整体回收。
11
+ *
12
+ * 与 `image-attachment.ts` 的分工:本模块只负责「把文件放进去」;图片怎么
13
+ * 解码成模型可见的 base64 仍由 `image-attachment.ts` 处理。二者路径都在
14
+ * 主进程 / BS 服务端。
15
+ *
16
+ * 写入支持两种来源(Electron 与 BS 模式各用其一):
17
+ * - `path`:Electron 拖拽 / `<input type="file">` 的 File 对象带真实路径,
18
+ * 服务端直接 copyFile;
19
+ * - `data`:浏览器(BS 模式)里 File 没有路径,renderer 读成 base64 传上
20
+ * 来,服务端解码后落盘。
21
+ */
22
+ import { existsSync, mkdirSync } from 'node:fs';
23
+ import { copyFile, stat, writeFile } from 'node:fs/promises';
24
+ import path from 'node:path';
25
+ import { getUserDataDir } from './runtime.js';
26
+ export const ATTACHMENTS_DIR_NAME = 'attachments';
27
+ /** 单个附件上限(base64 解码前字节数);多文件总和还受 HTTP body 上限约束。 */
28
+ export const ATTACHMENT_MAX_BYTES = 25 * 1024 * 1024;
29
+ /** chatId 由 storage 用 randomUUID 生成;这里只做白名单防御。 */
30
+ const SAFE_CHAT_ID = /^[0-9a-zA-Z_-]{1,64}$/;
31
+ export function isValidChatAttachmentsKey(chatId) {
32
+ return SAFE_CHAT_ID.test(chatId);
33
+ }
34
+ /**
35
+ * 当前会话的附件目录(会确保目录存在)。chatId 非法时仍然返回路径但由
36
+ * 调用方在写入前用 {@link isValidChatAttachmentsKey} 校验。
37
+ */
38
+ export function getChatAttachmentsDir(chatId) {
39
+ const dir = path.join(getUserDataDir(), ATTACHMENTS_DIR_NAME, chatId);
40
+ mkdirSync(dir, { recursive: true });
41
+ return dir;
42
+ }
43
+ /** 去掉路径分隔符与控制字符,只保留安全的文件名。 */
44
+ export function sanitizeName(name) {
45
+ const raw = String(name ?? '').replace(/\\/g, '/');
46
+ const base = raw.split('/').pop() ?? '';
47
+ const cleaned = base
48
+ // 控制字符与 Windows/跨平台保留字符统一替换为下划线。
49
+ // eslint-disable-next-line no-control-regex
50
+ .replace(/[\u0000-\u001f<>:"|?*]/g, '_')
51
+ .trim();
52
+ return cleaned || 'file';
53
+ }
54
+ /** 同名文件加 -1 / -2 后缀,避免覆盖已有附件。 */
55
+ export function uniqueFileName(dir, name) {
56
+ if (!existsSync(path.join(dir, name)))
57
+ return name;
58
+ const ext = path.extname(name);
59
+ const base = path.basename(name, ext);
60
+ for (let i = 1; i < 100_000; i += 1) {
61
+ const candidate = `${base}-${i}${ext}`;
62
+ if (!existsSync(path.join(dir, candidate)))
63
+ return candidate;
64
+ }
65
+ return `${base}-${Date.now()}${ext}`;
66
+ }
67
+ /** base64 → Buffer;空串返回 null(表示「没有数据来源」)。 */
68
+ function decodeData(data) {
69
+ const text = data.trim();
70
+ if (!text)
71
+ return null;
72
+ return Buffer.from(text, 'base64');
73
+ }
74
+ /**
75
+ * 把一批附件落进会话附件目录。按输入顺序返回逐文件结果(成功或失败都
76
+ * 不会中断整批),调用方据此决定哪些文件可用。
77
+ *
78
+ * 每个文件二选一提供来源:`path`(服务端直接拷贝)或 `data`(base64 字节,
79
+ * 服务端解码落盘)。两者都缺时记 error;两者都有时优先 `data`。
80
+ */
81
+ export async function saveAttachmentFiles(chatId, files) {
82
+ const out = [];
83
+ if (!isValidChatAttachmentsKey(chatId)) {
84
+ for (const file of files) {
85
+ const name = sanitizeName(file.name || path.basename(file.path || ''));
86
+ out.push({ name, path: '', size: 0, error: `invalid chatId: ${chatId}` });
87
+ }
88
+ return { files: out };
89
+ }
90
+ const dir = getChatAttachmentsDir(chatId);
91
+ for (const file of files) {
92
+ const sourcePath = typeof file.path === 'string' ? file.path.trim() : '';
93
+ const name = sanitizeName(file.name || path.basename(sourcePath || ''));
94
+ const data = typeof file.data === 'string' ? file.data : '';
95
+ try {
96
+ if (data.trim()) {
97
+ const bytes = decodeData(data);
98
+ const size = bytes.length;
99
+ if (size > ATTACHMENT_MAX_BYTES) {
100
+ out.push({
101
+ name,
102
+ path: '',
103
+ size: 0,
104
+ error: `file too large (${size} bytes), max=${ATTACHMENT_MAX_BYTES}`,
105
+ });
106
+ continue;
107
+ }
108
+ const storedName = uniqueFileName(dir, name);
109
+ const destPath = path.join(dir, storedName);
110
+ await writeFile(destPath, bytes);
111
+ out.push({ name: storedName, path: destPath, size });
112
+ continue;
113
+ }
114
+ if (sourcePath) {
115
+ const sourceStat = await stat(sourcePath);
116
+ if (!sourceStat.isFile()) {
117
+ out.push({ name, path: '', size: 0, error: 'source is not a regular file' });
118
+ continue;
119
+ }
120
+ if (sourceStat.size > ATTACHMENT_MAX_BYTES) {
121
+ out.push({
122
+ name,
123
+ path: '',
124
+ size: 0,
125
+ error: `file too large (${sourceStat.size} bytes), max=${ATTACHMENT_MAX_BYTES}`,
126
+ });
127
+ continue;
128
+ }
129
+ const storedName = uniqueFileName(dir, name);
130
+ const destPath = path.join(dir, storedName);
131
+ await copyFile(sourcePath, destPath);
132
+ out.push({ name: storedName, path: destPath, size: sourceStat.size });
133
+ continue;
134
+ }
135
+ out.push({ name, path: '', size: 0, error: 'no content (missing path and data)' });
136
+ }
137
+ catch (err) {
138
+ out.push({
139
+ name,
140
+ path: '',
141
+ size: 0,
142
+ error: err instanceof Error ? err.message : String(err),
143
+ });
144
+ }
145
+ }
146
+ return { files: out };
147
+ }
@@ -0,0 +1,24 @@
1
+ import type { ScenarioId } from './scenario/pack.js';
2
+ /** 开放字符串(0.3g):'generic' | 各场景产品 flavor | 未来产品 id。 */
3
+ export type AppFlavor = ScenarioId;
4
+ /** shell 默认智能体;场景产品里仍可选,但不一定作为首页默认。 */
5
+ export declare const LOCAL_ASSISTANT_AGENT_ID = "local-assistant";
6
+ /** 内置「智能助手」:种子时 `loadAllSkills` 开启(无视触发条件全量加载技能)。 */
7
+ export declare const ALL_ROUND_ASSISTANT_AGENT_ID = "all-round-assistant";
8
+ export interface Brand {
9
+ flavor: AppFlavor;
10
+ /** UI 显示名:窗口标题、通知标题等 */
11
+ displayName: string;
12
+ /** LLM 身份自称(系统提示词里用) */
13
+ agentName: string;
14
+ /** 一句话定位(fallback prompt 用) */
15
+ tagline: string;
16
+ /** 新对话 / 首页未选手动专家时绑定的内置智能体 id */
17
+ defaultAgentId: string;
18
+ }
19
+ /**
20
+ * 注入产品品牌(产品组装根在第一个 import 时调用)。重复注入抛错
21
+ * (组装期笔误,fail fast)。注入后作废缓存,后续 getBrand() 重算。
22
+ */
23
+ export declare function setProductBrand(brand: Omit<Brand, 'flavor'>): void;
24
+ export declare function getBrand(): Brand;