@symerian/symi 3.0.17 → 3.0.19

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 (259) hide show
  1. package/dist/{audio-preflight-CBDFctZN.js → audio-preflight-BfmZbg4Y.js} +4 -4
  2. package/dist/{audio-preflight-gsZSpG-6.js → audio-preflight-DcuC-liM.js} +4 -4
  3. package/dist/build-info.json +3 -3
  4. package/dist/bundled/boot-md/handler.js +8 -8
  5. package/dist/bundled/session-memory/handler.js +7 -7
  6. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  7. package/dist/{chrome-nPMY1XTJ.js → chrome-Bo7cbvFK.js} +5 -5
  8. package/dist/{chrome-BjVab8gM.js → chrome-DYp18Q0t.js} +5 -5
  9. package/dist/{deliver-D-QFqm31.js → deliver-ChSIbiMM.js} +1 -1
  10. package/dist/{deliver-B4-bcot9.js → deliver-DEgRQM4J.js} +1 -1
  11. package/dist/extensionAPI.js +7 -7
  12. package/dist/{image-CDwtQjmt.js → image-Bx-hvoNJ.js} +1 -1
  13. package/dist/{image-CcS-vzTA.js → image-CQl_mjWk.js} +1 -1
  14. package/dist/llm-slug-generator.js +7 -7
  15. package/dist/{manager-BnEdHzmO.js → manager-D_pn0urG.js} +1 -1
  16. package/dist/{manager-09r0qPze.js → manager-YQxK2t0C.js} +1 -1
  17. package/dist/{pi-embedded-CWsY69-4.js → pi-embedded-CLw_ZzEZ.js} +16 -16
  18. package/dist/{pi-embedded-helpers-BBMy-lqr.js → pi-embedded-helpers-B5I53aw6.js} +4 -4
  19. package/dist/{pi-embedded-helpers-ChEYbgVj.js → pi-embedded-helpers-sUAEIC9X.js} +4 -4
  20. package/dist/plugin-sdk/{accounts-BfyWsC_i.js → accounts-CWFytwbR.js} +3 -3
  21. package/dist/plugin-sdk/{active-listener-DcJW7xAT.js → active-listener-BkZ4jHrL.js} +2 -2
  22. package/dist/plugin-sdk/{agent-scope-ChbGV6of.js → agent-scope-C9gfY_Gk.js} +2 -2
  23. package/dist/plugin-sdk/{audio-preflight-D3GtNLqW.js → audio-preflight-HKbdzXLZ.js} +21 -21
  24. package/dist/plugin-sdk/{bindings-CN2Qmefj.js → bindings-BaKIqPPy.js} +2 -2
  25. package/dist/plugin-sdk/{channel-web-DTyqujjA.js → channel-web-D5nWiTH1.js} +18 -18
  26. package/dist/plugin-sdk/{chrome-BKzAKr3K.js → chrome-klTSnz-9.js} +3 -3
  27. package/dist/plugin-sdk/{chunk-DhDkBujV.js → chunk-BbrYSny_.js} +1 -1
  28. package/dist/plugin-sdk/{command-format-CVrYFyZS.js → command-format-BN6tyZt6.js} +1 -1
  29. package/dist/plugin-sdk/{commands-registry-17yfZkHZ.js → commands-registry-CTzKKtY6.js} +4 -4
  30. package/dist/plugin-sdk/{config-7wk65zKC.js → config-Crv2qEdJ.js} +9 -9
  31. package/dist/plugin-sdk/{consolidate-exbAW0ml.js → consolidate-DT1QH65Q.js} +2 -2
  32. package/dist/plugin-sdk/{deliver-TxAcw7J5.js → deliver-7rOvAlrc.js} +12 -12
  33. package/dist/plugin-sdk/{diagnostic-Debx4frd.js → diagnostic-0nsxhWp7.js} +1 -1
  34. package/dist/plugin-sdk/{fs-safe-wBYbAkJF.js → fs-safe-DfWYBeWF.js} +1 -1
  35. package/dist/plugin-sdk/{gemini-auth-7U2pm2Ky.js → gemini-auth-C0N0_u49.js} +1 -1
  36. package/dist/plugin-sdk/{image-BtDVmYA5.js → image-WOSl2apK.js} +4 -4
  37. package/dist/plugin-sdk/index.js +43 -43
  38. package/dist/plugin-sdk/{ir-CKMvRrGW.js → ir-9J84MTls.js} +4 -4
  39. package/dist/plugin-sdk/{local-roots-c_gaPs01.js → local-roots-OLRDbvyY.js} +3 -3
  40. package/dist/plugin-sdk/{login-DUym1Jy0.js → login-C7x4q0i2.js} +7 -7
  41. package/dist/plugin-sdk/{login-qr-B-WBdvrX.js → login-qr-Dv5_MoAW.js} +9 -9
  42. package/dist/plugin-sdk/{manager-B71SCzos.js → manager-C83tK17x.js} +8 -8
  43. package/dist/plugin-sdk/{manifest-registry-Dnic6Chh.js → manifest-registry-CJMV-PI7.js} +1 -1
  44. package/dist/plugin-sdk/{markdown-tables-Dur7OTlM.js → markdown-tables-DXNKz5y_.js} +1 -1
  45. package/dist/plugin-sdk/{message-channel-BrAhJJV_.js → message-channel-aGy1HbQQ.js} +1 -1
  46. package/dist/plugin-sdk/{model-selection-B9qaVQSJ.js → model-selection-C-3-tpe7.js} +4 -4
  47. package/dist/plugin-sdk/{outbound-DB1wDM8b.js → outbound-DquCeSy5.js} +6 -6
  48. package/dist/plugin-sdk/{pi-auth-json-ZO118hoy.js → pi-auth-json-D9PDCXGn.js} +1 -1
  49. package/dist/plugin-sdk/{pi-embedded-helpers-s_U0Un7j.js → pi-embedded-helpers-D3ygfH7l.js} +16 -16
  50. package/dist/plugin-sdk/{plugins-DF81oSaI.js → plugins-DOwnSg9D.js} +4 -4
  51. package/dist/plugin-sdk/{pw-ai-CTwP02uv.js → pw-ai-rlengLjb.js} +8 -8
  52. package/dist/plugin-sdk/{qmd-manager-CBaSGant.js → qmd-manager-BzxFjRFa.js} +4 -4
  53. package/dist/plugin-sdk/{registry-CZVURNhF.js → registry-5iFfixlB.js} +2 -2
  54. package/dist/plugin-sdk/{replies-hwRbkU3z.js → replies-BXOzO_H5.js} +7 -7
  55. package/dist/plugin-sdk/{reply-prefix-CaXmzZlx.js → reply-prefix-INAKTqCU.js} +1 -1
  56. package/dist/plugin-sdk/{resolve-outbound-target-fxVSOBmk.js → resolve-outbound-target-DvbxHtqp.js} +2 -2
  57. package/dist/plugin-sdk/{resolve-route-ClCyiOeu.js → resolve-route-URXlY3AK.js} +3 -3
  58. package/dist/plugin-sdk/{runner-Cq5jvwQ7.js → runner-Bv0_DWoH.js} +9 -9
  59. package/dist/plugin-sdk/{session-B_TkB65Y.js → session-C3r8l7ou.js} +4 -4
  60. package/dist/plugin-sdk/{skill-commands-0LF9HTGr.js → skill-commands-KjLUGIdZ.js} +5 -5
  61. package/dist/plugin-sdk/{skills-BIT_O7J0.js → skills-BrsD4L5c.js} +7 -7
  62. package/dist/plugin-sdk/{sqlite-Bx5Y5U5X.js → sqlite-CjW7ME1H.js} +1 -1
  63. package/dist/plugin-sdk/{subsystem-CXqYeDy-.js → subsystem-DcOg1xJr.js} +1 -1
  64. package/dist/plugin-sdk/{synthesis-DtsYAj1E.js → synthesis-CY7YAasV.js} +38 -38
  65. package/dist/plugin-sdk/{target-errors-B8mokOeH.js → target-errors-BVWJGWFq.js} +2 -2
  66. package/dist/plugin-sdk/{thinking-Ca0DhqzO.js → thinking-CtsTDPOi.js} +3 -3
  67. package/dist/plugin-sdk/{tokens-CvlONEqh.js → tokens-8lqOTZCB.js} +1 -1
  68. package/dist/plugin-sdk/{tool-images-DpBaWEHT.js → tool-images-Cl_rGIUZ.js} +2 -2
  69. package/dist/plugin-sdk/{tool-loop-detection-BOvUFa0f.js → tool-loop-detection-Da4WUT_P.js} +2 -2
  70. package/dist/plugin-sdk/{unified-runner-CnM7lyNd.js → unified-runner-nwMnsZyj.js} +60 -60
  71. package/dist/plugin-sdk/web-BlweOZDp.js +54 -0
  72. package/dist/plugin-sdk/{whatsapp-actions-CvnfsFJm.js → whatsapp-actions-DpfaGYs7.js} +21 -21
  73. package/dist/{pw-ai-BW8_KeDf.js → pw-ai-BqxJG-Wh.js} +1 -1
  74. package/dist/{pw-ai-j9IE1K0-.js → pw-ai-C-NSGye0.js} +1 -1
  75. package/dist/{runner-8ALr2UII.js → runner-COGFTeDw.js} +1 -1
  76. package/dist/{runner-C4-9kFdR.js → runner-DhCi2lT1.js} +1 -1
  77. package/dist/{synthesis-Cph3LhA1.js → synthesis-CXZu24Vx.js} +7 -7
  78. package/dist/{synthesis-Cus0A2dL.js → synthesis-DrPxcMlQ.js} +7 -7
  79. package/dist/{unified-runner-CX80YMTk.js → unified-runner-iByUazvW.js} +16 -16
  80. package/dist/{web-ChozvJ7I.js → web-EsMQBIYf.js} +7 -7
  81. package/dist/{web-DFlsbXmQ.js → web-PPg5y6xI.js} +7 -7
  82. package/package.json +1 -1
  83. package/dist/plugin-sdk/web-CIPJBHAU.js +0 -54
  84. package/extensions/copilot-proxy/README.md +0 -24
  85. package/extensions/copilot-proxy/index.ts +0 -154
  86. package/extensions/copilot-proxy/node_modules/.bin/symi +0 -21
  87. package/extensions/copilot-proxy/package.json +0 -15
  88. package/extensions/copilot-proxy/symi.plugin.json +0 -9
  89. package/extensions/device-pair/index.ts +0 -642
  90. package/extensions/device-pair/symi.plugin.json +0 -20
  91. package/extensions/diagnostics-otel/index.ts +0 -15
  92. package/extensions/diagnostics-otel/node_modules/.bin/acorn +0 -21
  93. package/extensions/diagnostics-otel/node_modules/.bin/symi +0 -21
  94. package/extensions/diagnostics-otel/package.json +0 -27
  95. package/extensions/diagnostics-otel/src/service.test.ts +0 -290
  96. package/extensions/diagnostics-otel/src/service.ts +0 -666
  97. package/extensions/diagnostics-otel/symi.plugin.json +0 -8
  98. package/extensions/google-antigravity-auth/README.md +0 -24
  99. package/extensions/google-antigravity-auth/index.ts +0 -424
  100. package/extensions/google-antigravity-auth/node_modules/.bin/symi +0 -21
  101. package/extensions/google-antigravity-auth/package.json +0 -15
  102. package/extensions/google-antigravity-auth/symi.plugin.json +0 -9
  103. package/extensions/google-gemini-cli-auth/README.md +0 -35
  104. package/extensions/google-gemini-cli-auth/index.ts +0 -75
  105. package/extensions/google-gemini-cli-auth/node_modules/.bin/symi +0 -21
  106. package/extensions/google-gemini-cli-auth/oauth.test.ts +0 -162
  107. package/extensions/google-gemini-cli-auth/oauth.ts +0 -636
  108. package/extensions/google-gemini-cli-auth/package.json +0 -15
  109. package/extensions/google-gemini-cli-auth/symi.plugin.json +0 -9
  110. package/extensions/learning-loop/index.ts +0 -159
  111. package/extensions/learning-loop/node_modules/.bin/symi +0 -21
  112. package/extensions/learning-loop/package.json +0 -18
  113. package/extensions/learning-loop/src/analytics/gateway-methods.ts +0 -230
  114. package/extensions/learning-loop/src/analytics/metrics-aggregator.ts +0 -153
  115. package/extensions/learning-loop/src/capture/run-tracker.ts +0 -181
  116. package/extensions/learning-loop/src/capture/serializer.ts +0 -74
  117. package/extensions/learning-loop/src/db.ts +0 -583
  118. package/extensions/learning-loop/src/feedback/explicit-feedback.ts +0 -58
  119. package/extensions/learning-loop/src/feedback/implicit-signals.ts +0 -89
  120. package/extensions/learning-loop/src/graph/edge-inference.ts +0 -189
  121. package/extensions/learning-loop/src/graph/graph-retrieval.ts +0 -144
  122. package/extensions/learning-loop/src/graph/graph-store.ts +0 -183
  123. package/extensions/learning-loop/src/hooks.ts +0 -244
  124. package/extensions/learning-loop/src/injection/cache.ts +0 -73
  125. package/extensions/learning-loop/src/injection/context-injector.ts +0 -104
  126. package/extensions/learning-loop/src/injection/prompt-builder.ts +0 -43
  127. package/extensions/learning-loop/src/learning/embedding-bridge.ts +0 -54
  128. package/extensions/learning-loop/src/learning/learning-extractor.ts +0 -217
  129. package/extensions/learning-loop/src/learning/learning-store.ts +0 -158
  130. package/extensions/learning-loop/src/learning/retrieval.ts +0 -87
  131. package/extensions/learning-loop/src/math/confidence-intervals.ts +0 -62
  132. package/extensions/learning-loop/src/math/ewma.ts +0 -51
  133. package/extensions/learning-loop/src/math/weighted-scorer.ts +0 -42
  134. package/extensions/learning-loop/src/schema.ts +0 -176
  135. package/extensions/learning-loop/src/scoring/normalization.ts +0 -32
  136. package/extensions/learning-loop/src/scoring/quality-engine.ts +0 -78
  137. package/extensions/learning-loop/src/scoring/signal-extractors.ts +0 -155
  138. package/extensions/learning-loop/src/test/context-injector.test.ts +0 -142
  139. package/extensions/learning-loop/src/test/fixes.test.ts +0 -1286
  140. package/extensions/learning-loop/src/test/graph.test.ts +0 -711
  141. package/extensions/learning-loop/src/test/integration.test.ts +0 -312
  142. package/extensions/learning-loop/src/test/learning-store.test.ts +0 -191
  143. package/extensions/learning-loop/src/test/math.test.ts +0 -148
  144. package/extensions/learning-loop/src/test/quality-engine.test.ts +0 -231
  145. package/extensions/learning-loop/src/test/run-tracker.test.ts +0 -143
  146. package/extensions/learning-loop/src/types.ts +0 -281
  147. package/extensions/learning-loop/symi.plugin.json +0 -46
  148. package/extensions/llm-task/README.md +0 -97
  149. package/extensions/llm-task/index.ts +0 -6
  150. package/extensions/llm-task/package.json +0 -12
  151. package/extensions/llm-task/src/llm-task-tool.test.ts +0 -138
  152. package/extensions/llm-task/src/llm-task-tool.ts +0 -249
  153. package/extensions/llm-task/symi.plugin.json +0 -21
  154. package/extensions/memory-lancedb/config.ts +0 -161
  155. package/extensions/memory-lancedb/index.test.ts +0 -330
  156. package/extensions/memory-lancedb/index.ts +0 -670
  157. package/extensions/memory-lancedb/node_modules/.bin/arrow2csv +0 -21
  158. package/extensions/memory-lancedb/node_modules/.bin/openai +0 -21
  159. package/extensions/memory-lancedb/node_modules/.bin/symi +0 -21
  160. package/extensions/memory-lancedb/package.json +0 -20
  161. package/extensions/memory-lancedb/symi.plugin.json +0 -71
  162. package/extensions/minimax-portal-auth/README.md +0 -33
  163. package/extensions/minimax-portal-auth/index.ts +0 -161
  164. package/extensions/minimax-portal-auth/node_modules/.bin/symi +0 -21
  165. package/extensions/minimax-portal-auth/oauth.ts +0 -247
  166. package/extensions/minimax-portal-auth/package.json +0 -15
  167. package/extensions/minimax-portal-auth/symi.plugin.json +0 -9
  168. package/extensions/model-equalizer/index.ts +0 -80
  169. package/extensions/model-equalizer/skills/model-equalizer/SKILL.md +0 -58
  170. package/extensions/model-equalizer/src/detection.ts +0 -62
  171. package/extensions/model-equalizer/src/enhancer.ts +0 -63
  172. package/extensions/model-equalizer/src/test/detection.test.ts +0 -218
  173. package/extensions/model-equalizer/src/test/enhancer.test.ts +0 -137
  174. package/extensions/model-equalizer/src/test/integration.test.ts +0 -185
  175. package/extensions/model-equalizer/src/types.ts +0 -24
  176. package/extensions/model-equalizer/symi.plugin.json +0 -12
  177. package/extensions/phone-control/index.ts +0 -421
  178. package/extensions/phone-control/symi.plugin.json +0 -10
  179. package/extensions/pipeline/README.md +0 -75
  180. package/extensions/pipeline/SKILL.md +0 -97
  181. package/extensions/pipeline/index.ts +0 -18
  182. package/extensions/pipeline/package.json +0 -11
  183. package/extensions/pipeline/src/pipeline-tool.test.ts +0 -345
  184. package/extensions/pipeline/src/pipeline-tool.ts +0 -266
  185. package/extensions/pipeline/src/windows-spawn.test.ts +0 -148
  186. package/extensions/pipeline/src/windows-spawn.ts +0 -193
  187. package/extensions/pipeline/symi.plugin.json +0 -10
  188. package/extensions/qwen-portal-auth/README.md +0 -24
  189. package/extensions/qwen-portal-auth/index.ts +0 -134
  190. package/extensions/qwen-portal-auth/oauth.ts +0 -190
  191. package/extensions/qwen-portal-auth/symi.plugin.json +0 -9
  192. package/extensions/talk-voice/index.ts +0 -150
  193. package/extensions/talk-voice/symi.plugin.json +0 -10
  194. package/extensions/thread-ownership/index.test.ts +0 -180
  195. package/extensions/thread-ownership/index.ts +0 -133
  196. package/extensions/thread-ownership/symi.plugin.json +0 -28
  197. package/skills/1password/SKILL.md +0 -71
  198. package/skills/1password/references/cli-examples.md +0 -29
  199. package/skills/1password/references/get-started.md +0 -17
  200. package/skills/apple-notes/SKILL.md +0 -78
  201. package/skills/apple-reminders/SKILL.md +0 -119
  202. package/skills/bear-notes/SKILL.md +0 -108
  203. package/skills/blogwatcher/SKILL.md +0 -70
  204. package/skills/blucli/SKILL.md +0 -48
  205. package/skills/bluebubbles/SKILL.md +0 -132
  206. package/skills/camsnap/SKILL.md +0 -46
  207. package/skills/canvas/SKILL.md +0 -204
  208. package/skills/connect-email/SKILL.md +0 -142
  209. package/skills/document-generation/SKILL.md +0 -83
  210. package/skills/eightctl/SKILL.md +0 -51
  211. package/skills/food-order/SKILL.md +0 -49
  212. package/skills/gemini/SKILL.md +0 -44
  213. package/skills/gh-issues/SKILL.md +0 -865
  214. package/skills/gifgrep/SKILL.md +0 -80
  215. package/skills/github/SKILL.md +0 -164
  216. package/skills/gog/SKILL.md +0 -117
  217. package/skills/goplaces/SKILL.md +0 -53
  218. package/skills/healthcheck/SKILL.md +0 -246
  219. package/skills/himalaya/SKILL.md +0 -258
  220. package/skills/himalaya/references/configuration.md +0 -184
  221. package/skills/himalaya/references/message-composition.md +0 -199
  222. package/skills/imsg/SKILL.md +0 -122
  223. package/skills/long-task/SKILL.md +0 -58
  224. package/skills/long-task/scripts/detach-task.sh +0 -187
  225. package/skills/nano-banana-pro/SKILL.md +0 -59
  226. package/skills/nano-banana-pro/scripts/generate_image.py +0 -184
  227. package/skills/nano-pdf/SKILL.md +0 -39
  228. package/skills/notion/SKILL.md +0 -173
  229. package/skills/obsidian/SKILL.md +0 -82
  230. package/skills/openai-image-gen/SKILL.md +0 -90
  231. package/skills/openai-image-gen/scripts/gen.py +0 -240
  232. package/skills/openai-whisper/SKILL.md +0 -39
  233. package/skills/openai-whisper-api/SKILL.md +0 -53
  234. package/skills/openai-whisper-api/scripts/transcribe.sh +0 -85
  235. package/skills/openhue/SKILL.md +0 -113
  236. package/skills/oracle/SKILL.md +0 -126
  237. package/skills/ordercli/SKILL.md +0 -79
  238. package/skills/peekaboo/SKILL.md +0 -191
  239. package/skills/reactions-extensive/SKILL.md +0 -30
  240. package/skills/reactions-minimal/SKILL.md +0 -31
  241. package/skills/safe-edit/SKILL.md +0 -51
  242. package/skills/sag/SKILL.md +0 -88
  243. package/skills/sherpa-onnx-tts/SKILL.md +0 -104
  244. package/skills/sherpa-onnx-tts/bin/sherpa-onnx-tts +0 -178
  245. package/skills/songsee/SKILL.md +0 -50
  246. package/skills/sonoscli/SKILL.md +0 -66
  247. package/skills/spotify-player/SKILL.md +0 -65
  248. package/skills/symihub/SKILL.md +0 -78
  249. package/skills/things-mac/SKILL.md +0 -87
  250. package/skills/tmux/SKILL.md +0 -153
  251. package/skills/tmux/scripts/find-sessions.sh +0 -112
  252. package/skills/tmux/scripts/wait-for-text.sh +0 -83
  253. package/skills/trello/SKILL.md +0 -96
  254. package/skills/video-frames/SKILL.md +0 -47
  255. package/skills/video-frames/scripts/frame.sh +0 -81
  256. package/skills/voice-call/SKILL.md +0 -46
  257. package/skills/wacli/SKILL.md +0 -73
  258. package/skills/weather/SKILL.md +0 -113
  259. package/skills/xurl/SKILL.md +0 -462
@@ -1,75 +0,0 @@
1
- # Pipeline (plugin)
2
-
3
- Adds the `pipeline` agent tool as an **optional** plugin tool.
4
-
5
- ## What this is
6
-
7
- - Pipeline is a standalone workflow shell (typed JSON-first pipelines + approvals/resume).
8
- - This plugin integrates Pipeline with Symi _without core changes_.
9
-
10
- ## Enable
11
-
12
- Because this tool can trigger side effects (via workflows), it is registered with `optional: true`.
13
-
14
- Enable it in an agent allowlist:
15
-
16
- ```json
17
- {
18
- "agents": {
19
- "list": [
20
- {
21
- "id": "main",
22
- "tools": {
23
- "allow": [
24
- "pipeline" // plugin id (enables all tools from this plugin)
25
- ]
26
- }
27
- }
28
- ]
29
- }
30
- }
31
- ```
32
-
33
- ## Using `symi.invoke` (Pipeline → Symi tools)
34
-
35
- Some pipelines may include a `symi.invoke` step to call back into Symi tools/plugins (for example: `gog` for Google Workspace, `gh` for GitHub, `message.send`, etc.).
36
-
37
- For this to work, the Symi Gateway must expose the tool bridge endpoint and the target tool must be allowed by policy:
38
-
39
- - Symi provides an HTTP endpoint: `POST /tools/invoke`.
40
- - The request is gated by **gateway auth** (e.g. `Authorization: Bearer …` when token auth is enabled).
41
- - The invoked tool is gated by **tool policy** (global + per-agent + provider + group policy). If the tool is not allowed, Symi returns `404 Tool not available`.
42
-
43
- ### Allowlisting recommended
44
-
45
- To avoid letting workflows call arbitrary tools, set a tight allowlist on the agent that will be used by `symi.invoke`.
46
-
47
- Example (allow only a small set of tools):
48
-
49
- ```jsonc
50
- {
51
- "agents": {
52
- "list": [
53
- {
54
- "id": "main",
55
- "tools": {
56
- "allow": ["pipeline", "web_fetch", "web_search", "gog", "gh"],
57
- "deny": ["gateway"],
58
- },
59
- },
60
- ],
61
- },
62
- }
63
- ```
64
-
65
- Notes:
66
-
67
- - If `tools.allow` is omitted or empty, it behaves like "allow everything (except denied)". For a real allowlist, set a **non-empty** `allow`.
68
- - Tool names depend on which plugins you have installed/enabled.
69
-
70
- ## Security
71
-
72
- - Runs the pipeline executable as a local subprocess.
73
- - Does not manage OAuth/tokens.
74
- - Uses timeouts, stdout caps, and strict JSON envelope parsing.
75
- - Ensure the pipeline runtime is available on `PATH` for the gateway process.
@@ -1,97 +0,0 @@
1
- # Pipeline
2
-
3
- Pipeline executes multi-step workflows with approval checkpoints. Use it when:
4
-
5
- - User wants a repeatable automation (triage, monitor, sync)
6
- - Actions need human approval before executing (send, post, delete)
7
- - Multiple tool calls should run as one deterministic operation
8
-
9
- ## When to use Pipeline
10
-
11
- | User intent | Use Pipeline? |
12
- | ------------------------------------------------------ | --------------------------------------------- |
13
- | "Triage my email" | Yes — multi-step, may send replies |
14
- | "Send a message" | No — single action, use message tool directly |
15
- | "Check my email every morning and ask before replying" | Yes — scheduled workflow with approval |
16
- | "What's the weather?" | No — simple query |
17
- | "Monitor this PR and notify me of changes" | Yes — stateful, recurring |
18
-
19
- ## Basic usage
20
-
21
- ### Run a pipeline
22
-
23
- ```json
24
- {
25
- "action": "run",
26
- "pipeline": "gog.gmail.search --query 'newer_than:1d' --max 20 | email.triage"
27
- }
28
- ```
29
-
30
- Returns structured result:
31
-
32
- ```json
33
- {
34
- "protocolVersion": 1,
35
- "ok": true,
36
- "status": "ok",
37
- "output": [{ "summary": {...}, "items": [...] }],
38
- "requiresApproval": null
39
- }
40
- ```
41
-
42
- ### Handle approval
43
-
44
- If the workflow needs approval:
45
-
46
- ```json
47
- {
48
- "status": "needs_approval",
49
- "output": [],
50
- "requiresApproval": {
51
- "prompt": "Send 3 draft replies?",
52
- "items": [...],
53
- "resumeToken": "..."
54
- }
55
- }
56
- ```
57
-
58
- Present the prompt to the user. If they approve:
59
-
60
- ```json
61
- {
62
- "action": "resume",
63
- "token": "<resumeToken>",
64
- "approve": true
65
- }
66
- ```
67
-
68
- ## Example workflows
69
-
70
- ### Email triage
71
-
72
- ```
73
- gog.gmail.search --query 'newer_than:1d' --max 20 | email.triage
74
- ```
75
-
76
- Fetches recent emails, classifies into buckets (needs_reply, needs_action, fyi).
77
-
78
- ### Email triage with approval gate
79
-
80
- ```
81
- gog.gmail.search --query 'newer_than:1d' | email.triage | approve --prompt 'Process these?'
82
- ```
83
-
84
- Same as above, but halts for approval before returning.
85
-
86
- ## Key behaviors
87
-
88
- - **Deterministic**: Same input → same output (no LLM variance in pipeline execution)
89
- - **Approval gates**: `approve` command halts execution, returns token
90
- - **Resumable**: Use `resume` action with token to continue
91
- - **Structured output**: Always returns JSON envelope with `protocolVersion`
92
-
93
- ## Don't use Pipeline for
94
-
95
- - Simple single-action requests (just use the tool directly)
96
- - Queries that need LLM interpretation mid-flow
97
- - One-off tasks that won't be repeated
@@ -1,18 +0,0 @@
1
- import type {
2
- AnyAgentTool,
3
- SymiPluginApi,
4
- SymiPluginToolFactory,
5
- } from "../../src/plugins/types.js";
6
- import { createPipelineTool } from "./src/pipeline-tool.js";
7
-
8
- export default function register(api: SymiPluginApi) {
9
- api.registerTool(
10
- ((ctx) => {
11
- if (ctx.sandboxed) {
12
- return null;
13
- }
14
- return createPipelineTool(api) as AnyAgentTool;
15
- }) as SymiPluginToolFactory,
16
- { optional: true },
17
- );
18
- }
@@ -1,11 +0,0 @@
1
- {
2
- "name": "@symi/pipeline",
3
- "version": "3.0.9",
4
- "description": "Pipeline workflow tool plugin (typed pipelines + resumable approvals)",
5
- "type": "module",
6
- "symi": {
7
- "extensions": [
8
- "./index.ts"
9
- ]
10
- }
11
- }
@@ -1,345 +0,0 @@
1
- import { EventEmitter } from "node:events";
2
- import fs from "node:fs/promises";
3
- import os from "node:os";
4
- import path from "node:path";
5
- import { PassThrough } from "node:stream";
6
- import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
7
- import type { SymiPluginApi, SymiPluginToolContext } from "../../../src/plugins/types.js";
8
-
9
- const spawnState = vi.hoisted(() => ({
10
- queue: [] as Array<{ stdout: string; stderr?: string; exitCode?: number }>,
11
- spawn: vi.fn(),
12
- }));
13
-
14
- vi.mock("node:child_process", () => ({
15
- spawn: (...args: unknown[]) => spawnState.spawn(...args),
16
- }));
17
-
18
- let createPipelineTool: typeof import("./pipeline-tool.js").createPipelineTool;
19
-
20
- function fakeApi(overrides: Partial<SymiPluginApi> = {}): SymiPluginApi {
21
- return {
22
- id: "pipeline",
23
- name: "pipeline",
24
- source: "test",
25
- config: {},
26
- pluginConfig: {},
27
- // oxlint-disable-next-line typescript/no-explicit-any
28
- runtime: { version: "test" } as any,
29
- logger: { info() {}, warn() {}, error() {}, debug() {} },
30
- registerTool() {},
31
- registerHttpHandler() {},
32
- registerChannel() {},
33
- registerGatewayMethod() {},
34
- registerCli() {},
35
- registerService() {},
36
- registerProvider() {},
37
- registerHook() {},
38
- registerHttpRoute() {},
39
- registerCommand() {},
40
- on() {},
41
- resolvePath: (p) => p,
42
- ...overrides,
43
- };
44
- }
45
-
46
- function fakeCtx(overrides: Partial<SymiPluginToolContext> = {}): SymiPluginToolContext {
47
- return {
48
- config: {},
49
- workspaceDir: "/tmp",
50
- agentDir: "/tmp",
51
- agentId: "main",
52
- sessionKey: "main",
53
- messageChannel: undefined,
54
- agentAccountId: undefined,
55
- sandboxed: false,
56
- ...overrides,
57
- };
58
- }
59
-
60
- function setProcessPlatform(platform: NodeJS.Platform) {
61
- Object.defineProperty(process, "platform", {
62
- value: platform,
63
- configurable: true,
64
- });
65
- }
66
-
67
- describe("pipeline plugin tool", () => {
68
- let tempDir = "";
69
- const originalPlatform = Object.getOwnPropertyDescriptor(process, "platform");
70
- const originalPath = process.env.PATH;
71
- const originalPathAlt = process.env.Path;
72
- const originalPathExt = process.env.PATHEXT;
73
- const originalPathExtAlt = process.env.Pathext;
74
-
75
- beforeAll(async () => {
76
- ({ createPipelineTool } = await import("./pipeline-tool.js"));
77
-
78
- tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "symi-pipeline-plugin-"));
79
- });
80
-
81
- afterEach(() => {
82
- if (originalPlatform) {
83
- Object.defineProperty(process, "platform", originalPlatform);
84
- }
85
- if (originalPath === undefined) {
86
- delete process.env.PATH;
87
- } else {
88
- process.env.PATH = originalPath;
89
- }
90
- if (originalPathAlt === undefined) {
91
- delete process.env.Path;
92
- } else {
93
- process.env.Path = originalPathAlt;
94
- }
95
- if (originalPathExt === undefined) {
96
- delete process.env.PATHEXT;
97
- } else {
98
- process.env.PATHEXT = originalPathExt;
99
- }
100
- if (originalPathExtAlt === undefined) {
101
- delete process.env.Pathext;
102
- } else {
103
- process.env.Pathext = originalPathExtAlt;
104
- }
105
- });
106
-
107
- afterAll(async () => {
108
- if (!tempDir) {
109
- return;
110
- }
111
- if (process.platform === "win32") {
112
- await fs.rm(tempDir, { recursive: true, force: true, maxRetries: 10, retryDelay: 50 });
113
- } else {
114
- await fs.rm(tempDir, { recursive: true, force: true });
115
- }
116
- });
117
-
118
- beforeEach(() => {
119
- spawnState.queue.length = 0;
120
- spawnState.spawn.mockReset();
121
- spawnState.spawn.mockImplementation(() => {
122
- const next = spawnState.queue.shift() ?? { stdout: "" };
123
- const stdout = new PassThrough();
124
- const stderr = new PassThrough();
125
- const child = new EventEmitter() as EventEmitter & {
126
- stdout: PassThrough;
127
- stderr: PassThrough;
128
- kill: (signal?: string) => boolean;
129
- };
130
- child.stdout = stdout;
131
- child.stderr = stderr;
132
- child.kill = () => true;
133
-
134
- setImmediate(() => {
135
- if (next.stderr) {
136
- stderr.end(next.stderr);
137
- } else {
138
- stderr.end();
139
- }
140
- stdout.end(next.stdout);
141
- child.emit("exit", next.exitCode ?? 0);
142
- });
143
-
144
- return child;
145
- });
146
- });
147
-
148
- const queueSuccessfulEnvelope = (hello = "world") => {
149
- spawnState.queue.push({
150
- stdout: JSON.stringify({
151
- ok: true,
152
- status: "ok",
153
- output: [{ hello }],
154
- requiresApproval: null,
155
- }),
156
- });
157
- };
158
-
159
- const createWindowsShimFixture = async (params: {
160
- shimPath: string;
161
- scriptPath: string;
162
- scriptToken: string;
163
- }) => {
164
- await fs.mkdir(path.dirname(params.scriptPath), { recursive: true });
165
- await fs.mkdir(path.dirname(params.shimPath), { recursive: true });
166
- await fs.writeFile(params.scriptPath, "module.exports = {};\n", "utf8");
167
- await fs.writeFile(params.shimPath, `@echo off\r\n"${params.scriptToken}" %*\r\n`, "utf8");
168
- };
169
-
170
- it("runs pipeline and returns parsed envelope in details", async () => {
171
- spawnState.queue.push({
172
- stdout: JSON.stringify({
173
- ok: true,
174
- status: "ok",
175
- output: [{ hello: "world" }],
176
- requiresApproval: null,
177
- }),
178
- });
179
-
180
- const tool = createPipelineTool(fakeApi());
181
- const res = await tool.execute("call1", {
182
- action: "run",
183
- pipeline: "noop",
184
- timeoutMs: 1000,
185
- });
186
-
187
- expect(spawnState.spawn).toHaveBeenCalled();
188
- expect(res.details).toMatchObject({ ok: true, status: "ok" });
189
- });
190
-
191
- it("tolerates noisy stdout before the JSON envelope", async () => {
192
- const payload = { ok: true, status: "ok", output: [], requiresApproval: null };
193
- spawnState.queue.push({
194
- stdout: `noise before json\n${JSON.stringify(payload)}`,
195
- });
196
-
197
- const tool = createPipelineTool(fakeApi());
198
- const res = await tool.execute("call-noisy", {
199
- action: "run",
200
- pipeline: "noop",
201
- timeoutMs: 1000,
202
- });
203
-
204
- expect(res.details).toMatchObject({ ok: true, status: "ok" });
205
- });
206
-
207
- it("requires action", async () => {
208
- const tool = createPipelineTool(fakeApi());
209
- await expect(tool.execute("call-action-missing", {})).rejects.toThrow(/action required/);
210
- });
211
-
212
- it("requires pipeline for run action", async () => {
213
- const tool = createPipelineTool(fakeApi());
214
- await expect(
215
- tool.execute("call-pipeline-missing", {
216
- action: "run",
217
- }),
218
- ).rejects.toThrow(/pipeline required/);
219
- });
220
-
221
- it("requires token and approve for resume action", async () => {
222
- const tool = createPipelineTool(fakeApi());
223
- await expect(
224
- tool.execute("call-resume-token-missing", {
225
- action: "resume",
226
- approve: true,
227
- }),
228
- ).rejects.toThrow(/token required/);
229
- await expect(
230
- tool.execute("call-resume-approve-missing", {
231
- action: "resume",
232
- token: "resume-token",
233
- }),
234
- ).rejects.toThrow(/approve required/);
235
- });
236
-
237
- it("rejects unknown action", async () => {
238
- const tool = createPipelineTool(fakeApi());
239
- await expect(
240
- tool.execute("call-action-unknown", {
241
- action: "explode",
242
- }),
243
- ).rejects.toThrow(/Unknown action/);
244
- });
245
-
246
- it("rejects absolute cwd", async () => {
247
- const tool = createPipelineTool(fakeApi());
248
- await expect(
249
- tool.execute("call2c", {
250
- action: "run",
251
- pipeline: "noop",
252
- cwd: "/tmp",
253
- }),
254
- ).rejects.toThrow(/cwd must be a relative path/);
255
- });
256
-
257
- it("rejects cwd that escapes the gateway working directory", async () => {
258
- const tool = createPipelineTool(fakeApi());
259
- await expect(
260
- tool.execute("call2d", {
261
- action: "run",
262
- pipeline: "noop",
263
- cwd: "../../etc",
264
- }),
265
- ).rejects.toThrow(/must stay within/);
266
- });
267
-
268
- it("rejects invalid JSON from pipeline", async () => {
269
- spawnState.queue.push({ stdout: "nope" });
270
-
271
- const tool = createPipelineTool(fakeApi());
272
- await expect(
273
- tool.execute("call3", {
274
- action: "run",
275
- pipeline: "noop",
276
- }),
277
- ).rejects.toThrow(/invalid JSON/);
278
- });
279
-
280
- it("runs Windows cmd shims through Node without enabling shell", async () => {
281
- setProcessPlatform("win32");
282
- const shimScriptPath = path.join(tempDir, "shim-dist", "lobster-cli.cjs");
283
- const shimPath = path.join(tempDir, "shim-bin", "lobster.cmd");
284
- await createWindowsShimFixture({
285
- shimPath,
286
- scriptPath: shimScriptPath,
287
- scriptToken: "%dp0%\\..\\shim-dist\\lobster-cli.cjs",
288
- });
289
- process.env.PATHEXT = ".CMD;.EXE";
290
- process.env.PATH = `${path.dirname(shimPath)};${process.env.PATH ?? ""}`;
291
- queueSuccessfulEnvelope();
292
-
293
- const tool = createPipelineTool(fakeApi());
294
- await tool.execute("call-win-shim", {
295
- action: "run",
296
- pipeline: "noop",
297
- });
298
-
299
- const [command, argv, options] = spawnState.spawn.mock.calls[0] ?? [];
300
- expect(command).toBe(process.execPath);
301
- expect(argv).toEqual([shimScriptPath, "run", "--mode", "tool", "noop"]);
302
- expect(options).toMatchObject({ windowsHide: true });
303
- expect(options).not.toHaveProperty("shell");
304
- });
305
-
306
- it("does not retry a failed Windows spawn with shell fallback", async () => {
307
- setProcessPlatform("win32");
308
- spawnState.spawn.mockReset();
309
- spawnState.spawn.mockImplementationOnce(() => {
310
- const child = new EventEmitter() as EventEmitter & {
311
- stdout: PassThrough;
312
- stderr: PassThrough;
313
- kill: (signal?: string) => boolean;
314
- };
315
- child.stdout = new PassThrough();
316
- child.stderr = new PassThrough();
317
- child.kill = () => true;
318
- const err = Object.assign(new Error("spawn failed"), { code: "ENOENT" });
319
- setImmediate(() => child.emit("error", err));
320
- return child;
321
- });
322
-
323
- const tool = createPipelineTool(fakeApi());
324
- await expect(
325
- tool.execute("call-win-no-retry", {
326
- action: "run",
327
- pipeline: "noop",
328
- }),
329
- ).rejects.toThrow(/spawn failed/);
330
- expect(spawnState.spawn).toHaveBeenCalledTimes(1);
331
- });
332
-
333
- it("can be gated off in sandboxed contexts", async () => {
334
- const api = fakeApi();
335
- const factoryTool = (ctx: SymiPluginToolContext) => {
336
- if (ctx.sandboxed) {
337
- return null;
338
- }
339
- return createPipelineTool(api);
340
- };
341
-
342
- expect(factoryTool(fakeCtx({ sandboxed: true }))).toBeNull();
343
- expect(factoryTool(fakeCtx({ sandboxed: false }))?.name).toBe("pipeline");
344
- });
345
- });