@symerian/symi 3.0.17 → 3.0.18

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 (146) 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/skills/1password/SKILL.md +0 -71
  85. package/skills/1password/references/cli-examples.md +0 -29
  86. package/skills/1password/references/get-started.md +0 -17
  87. package/skills/apple-notes/SKILL.md +0 -78
  88. package/skills/apple-reminders/SKILL.md +0 -119
  89. package/skills/bear-notes/SKILL.md +0 -108
  90. package/skills/blogwatcher/SKILL.md +0 -70
  91. package/skills/blucli/SKILL.md +0 -48
  92. package/skills/bluebubbles/SKILL.md +0 -132
  93. package/skills/camsnap/SKILL.md +0 -46
  94. package/skills/canvas/SKILL.md +0 -204
  95. package/skills/connect-email/SKILL.md +0 -142
  96. package/skills/document-generation/SKILL.md +0 -83
  97. package/skills/eightctl/SKILL.md +0 -51
  98. package/skills/food-order/SKILL.md +0 -49
  99. package/skills/gemini/SKILL.md +0 -44
  100. package/skills/gh-issues/SKILL.md +0 -865
  101. package/skills/gifgrep/SKILL.md +0 -80
  102. package/skills/github/SKILL.md +0 -164
  103. package/skills/gog/SKILL.md +0 -117
  104. package/skills/goplaces/SKILL.md +0 -53
  105. package/skills/healthcheck/SKILL.md +0 -246
  106. package/skills/himalaya/SKILL.md +0 -258
  107. package/skills/himalaya/references/configuration.md +0 -184
  108. package/skills/himalaya/references/message-composition.md +0 -199
  109. package/skills/imsg/SKILL.md +0 -122
  110. package/skills/long-task/SKILL.md +0 -58
  111. package/skills/long-task/scripts/detach-task.sh +0 -187
  112. package/skills/nano-banana-pro/SKILL.md +0 -59
  113. package/skills/nano-banana-pro/scripts/generate_image.py +0 -184
  114. package/skills/nano-pdf/SKILL.md +0 -39
  115. package/skills/notion/SKILL.md +0 -173
  116. package/skills/obsidian/SKILL.md +0 -82
  117. package/skills/openai-image-gen/SKILL.md +0 -90
  118. package/skills/openai-image-gen/scripts/gen.py +0 -240
  119. package/skills/openai-whisper/SKILL.md +0 -39
  120. package/skills/openai-whisper-api/SKILL.md +0 -53
  121. package/skills/openai-whisper-api/scripts/transcribe.sh +0 -85
  122. package/skills/openhue/SKILL.md +0 -113
  123. package/skills/oracle/SKILL.md +0 -126
  124. package/skills/ordercli/SKILL.md +0 -79
  125. package/skills/peekaboo/SKILL.md +0 -191
  126. package/skills/reactions-extensive/SKILL.md +0 -30
  127. package/skills/reactions-minimal/SKILL.md +0 -31
  128. package/skills/safe-edit/SKILL.md +0 -51
  129. package/skills/sag/SKILL.md +0 -88
  130. package/skills/sherpa-onnx-tts/SKILL.md +0 -104
  131. package/skills/sherpa-onnx-tts/bin/sherpa-onnx-tts +0 -178
  132. package/skills/songsee/SKILL.md +0 -50
  133. package/skills/sonoscli/SKILL.md +0 -66
  134. package/skills/spotify-player/SKILL.md +0 -65
  135. package/skills/symihub/SKILL.md +0 -78
  136. package/skills/things-mac/SKILL.md +0 -87
  137. package/skills/tmux/SKILL.md +0 -153
  138. package/skills/tmux/scripts/find-sessions.sh +0 -112
  139. package/skills/tmux/scripts/wait-for-text.sh +0 -83
  140. package/skills/trello/SKILL.md +0 -96
  141. package/skills/video-frames/SKILL.md +0 -47
  142. package/skills/video-frames/scripts/frame.sh +0 -81
  143. package/skills/voice-call/SKILL.md +0 -46
  144. package/skills/wacli/SKILL.md +0 -73
  145. package/skills/weather/SKILL.md +0 -113
  146. package/skills/xurl/SKILL.md +0 -462
@@ -1,142 +0,0 @@
1
- ---
2
- name: connect-email
3
- description: Connect a user's email account (Outlook 365 or Gmail) to Symi. Use when the user asks to connect, link, set up, configure, or troubleshoot email — including any mention of "my email", "work email", "outlook", "gmail", "microsoft 365", "m365", "google workspace", or "inbox". Precheck for an existing connection, ask Gmail or Outlook, then walk through the matching setup. Covers the `/outlook login` device-code flow and the full Gmail `hooks.gmail` Pub/Sub setup.
4
- triggers: [connect-email, connect, email]
5
- ---
6
-
7
- # Connect Email
8
-
9
- Symi has two email integrations. **Do not invent steps. Do not claim email is unsupported.** Follow this skill end-to-end.
10
-
11
- | Integration | Use when | How to connect |
12
- | --------------- | ---------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
13
- | **Outlook 365** | Microsoft 365 work/school account, personal `outlook.com` / `hotmail.com` / `live.com` | User sends `/outlook login` in chat → Microsoft device-code flow → tools become available immediately |
14
- | **Gmail** | Google Workspace, personal Gmail — **and** the user wants incoming mail to auto-create Symi sessions | Google Cloud Pub/Sub + `hooks.gmail` config (multi-step setup) |
15
-
16
- ## Step 0 — Precheck the connection state
17
-
18
- Before asking "Gmail or Outlook?", check what's already connected so you don't ask a user who's already set up.
19
-
20
- 1. **Outlook.** Your current system prompt already contains a line starting with `[Outlook 365]`, injected by the `outlook` plugin's `before_prompt_build` hook. If it reads _"Connected as <email>"_, Outlook is active — acknowledge it ("I can see you're already connected as X") and ask whether the user wants to add a second account or do something else.
21
- 2. **Gmail.** Read `~/.symi/symi.json`. If it has a `hooks.gmail` block with at least `account` and `topic` set, Gmail is configured — again, acknowledge before offering to re-setup.
22
-
23
- If neither is connected — or the user explicitly wants a _different_ account than what's shown — continue.
24
-
25
- ## Step 1 — Ask the user: Gmail or Outlook?
26
-
27
- One plain question. Do not assume. The correct branch depends on which mail provider the user actually has.
28
-
29
- ## Step 2a — Outlook branch
30
-
31
- 1. Ask the user to **type `/outlook login` in chat themselves**. Chat commands are intercepted by the command dispatcher only when the user sends them — if you emit `/outlook login` as assistant text it is just text, not a command.
32
- 2. They will receive a reply with a Microsoft device-code URL (typically `https://login.microsoft.com/device`) and an 8-character code. The code expires in 15 minutes.
33
- 3. The user opens the URL in any browser, signs in with their Microsoft account, pastes the code, and approves access.
34
- 4. Tokens are persisted to `~/.symi/credentials/outlook.json` (mode 0600). From the next turn, the `before_prompt_build` hook will inject `[Outlook 365] Connected as <email>` into your system context automatically.
35
- 5. Ask the user to send `/outlook status` to confirm. On success these seven tools are live for your use:
36
- - `outlook_list` — list messages in a folder (`inbox`, `sentitems`, `drafts`, `archive`, `junkemail`), optional unread filter
37
- - `outlook_read` — fetch the full body of a message by id (auto-marks read)
38
- - `outlook_send` — new message with To/CC, subject, body
39
- - `outlook_reply` — reply or reply-all to an existing message id
40
- - `outlook_search` — keyword search across subject / body / sender
41
- - `outlook_folders` — list folders with unread / total counts
42
- - `outlook_move` — move a message to another folder
43
-
44
- ### Outlook limitations to tell the user up front
45
-
46
- - **Plain-text body only.** No HTML formatting, no attachments (send or receive).
47
- - **Pull-only.** Symi does not receive incoming Outlook mail as Symi conversations. The user has to ask ("any new mail?") and you call `outlook_list` / `outlook_search`. There is no push, webhook, or background poll for Outlook today — if the user wants inbound-triggered sessions, they need Gmail.
48
- - **No Graph API retry/backoff yet.** A transient Graph 5xx surfaces as an error on the first try; re-running the tool usually succeeds.
49
-
50
- ## Step 2b — Gmail branch (full walkthrough)
51
-
52
- Gmail is heavier because Google requires Pub/Sub for push notifications. End result: when new mail lands in the watched label, Google publishes to a Pub/Sub topic; a push subscription POSTs to Symi's webhook; Symi creates a `hook:gmail:<id>` session that you then reply into as the agent.
53
-
54
- ### Prerequisites — verify with the user before starting
55
-
56
- - [ ] Access to a **Google Cloud project** (they can create one free at [console.cloud.google.com](https://console.cloud.google.com)).
57
- - [ ] `gcloud` CLI installed. On macOS: `brew install --cask google-cloud-sdk`. On Linux: follow the [gcloud install guide](https://cloud.google.com/sdk/docs/install).
58
- - [ ] OAuth credentials for the Gmail API, managed via `gogcli`. See `skills/gog/SKILL.md` for gogcli setup (`gog auth credentials /path/to/client_secret.json` then `gog auth add <email> --services gmail`).
59
- - [ ] Symi's webhook endpoint reachable by Google's push service. Either the Symi host is publicly reachable, **or** Tailscale is configured (`tailscale.mode: "serve"` for private, `"funnel"` for public-over-Tailscale).
60
-
61
- If any prerequisite is missing, stop and help the user install/configure it before continuing.
62
-
63
- ### Step-by-step setup
64
-
65
- 1. **Authenticate gcloud** — `gcloud auth login` and `gcloud config set project <project-id>`.
66
- 2. **Set up gogcli OAuth** — follow the `gog` skill: `gog auth credentials /path/to/client_secret.json`, then `gog auth add <email> --services gmail`.
67
- 3. **Create the Pub/Sub topic**
68
- ```bash
69
- gcloud pubsub topics create symi-gmail
70
- ```
71
- 4. **Grant Gmail permission to publish to the topic**
72
- ```bash
73
- gcloud pubsub topics add-iam-policy-binding symi-gmail \
74
- --member=serviceAccount:gmail-api-push@system.gserviceaccount.com \
75
- --role=roles/pubsub.publisher
76
- ```
77
- 5. **Create the push subscription** (pointing at Symi's webhook URL)
78
- ```bash
79
- gcloud pubsub subscriptions create symi-gmail-sub \
80
- --topic=symi-gmail \
81
- --push-endpoint=<SYMI_WEBHOOK_URL>/gmail-pubsub
82
- ```
83
- 6. **Register the Gmail watch** — call `users.watch` on the Gmail API with the topic and the label to watch (normally `INBOX`). The helpers in `src/hooks/gmail-setup-utils.ts` can do this from the gateway; ask the user whether they want you to run the setup via the gateway CLI or execute the `curl` against the Gmail API manually.
84
- 7. **Add `hooks.gmail` to `~/.symi/symi.json`**:
85
-
86
- ```json
87
- {
88
- "hooks": {
89
- "gmail": {
90
- "account": "user@example.com",
91
- "label": "INBOX",
92
- "topic": "projects/<project-id>/topics/symi-gmail",
93
- "subscription": "projects/<project-id>/subscriptions/symi-gmail-sub",
94
- "pushToken": "<random-shared-secret>",
95
- "hookUrl": "http://127.0.0.1:8788/gmail-pubsub",
96
- "includeBody": true,
97
- "maxBytes": 20480,
98
- "renewEveryMinutes": 720,
99
- "serve": { "bind": "127.0.0.1", "port": 8788, "path": "/gmail-pubsub" },
100
- "tailscale": { "mode": "off" }
101
- }
102
- }
103
- }
104
- ```
105
-
106
- Key fields:
107
- - `account` — the Gmail address being watched.
108
- - `label` — Gmail label/folder to watch (default `INBOX`).
109
- - `topic` / `subscription` — fully-qualified Pub/Sub resource names (`projects/<id>/topics/<name>`).
110
- - `pushToken` — shared secret Symi checks on incoming push requests so spoofed pushes are rejected.
111
- - `hookUrl` — URL the push subscription POSTs to; must match `serve.bind` + `serve.port` + `serve.path`, or be a Tailscale serve/funnel exposing them.
112
- - `includeBody` — include the email body in the prompt. `maxBytes` truncates oversized emails.
113
- - `renewEveryMinutes` — Gmail `watch` expires after ~7 days; default 720 (12h) re-registers well ahead.
114
- - `tailscale.mode` — `"off"` if Symi is publicly reachable; `"serve"` for a private tailnet webhook; `"funnel"` for Tailscale-exposed public endpoint.
115
- - `allowUnsafeExternalContent` — leave unset. Setting `true` disables Symi's external-content safety wrapper on email content — only use after explicit user acknowledgement.
116
-
117
- 8. **Restart the gateway** so it picks up the new hook config:
118
- ```bash
119
- systemctl --user restart symi-gateway # Linux
120
- ```
121
- On macOS with the headless tmux wrapper, kill and relaunch the tmux session running `gateway-headless.sh`. Changes under `hooks.gmail` are not hot-reloaded today.
122
- 9. **Verify** — have the user send a test email to `account`. Expected chain: Google publishes to the topic → Pub/Sub pushes to Symi's `/gmail-pubsub` endpoint → a `hook:gmail:<id>` session is created → you reply to it in the normal Symi conversation flow. Confirm the user sees the test email arrive as a Symi session.
123
-
124
- ### Gmail limitations to tell the user
125
-
126
- - Inbound only works while the watch is live. If `renewEveryMinutes` lapses, the Pub/Sub subscription fails, or the IAM binding gets removed, mail stops arriving — the gateway doctor (`symi doctor`) has checks for this.
127
- - Outgoing mail uses the reply path of whichever session/agent handles the inbound — it is not a native SMTP sender tool like `outlook_send`. For "compose a new email from scratch" workflows, Outlook is simpler.
128
- - `maxBytes` truncates very large emails so the prompt stays usable — set higher if the user routinely needs full message bodies.
129
-
130
- ## Which should I recommend?
131
-
132
- - **Microsoft 365 / outlook.com / hotmail.com / live.com** → Outlook. Two-minute setup.
133
- - **Gmail or Google Workspace**, user wants to **send mail on demand only** → Gmail via the `gog` CLI tools (no Pub/Sub needed) is simpler than the full `hooks.gmail` flow — mention this option.
134
- - **Gmail or Google Workspace**, user wants **incoming mail to auto-create Symi sessions** → Full Gmail Pub/Sub setup (Step 2b).
135
- - User wants _both send and auto-receive in Outlook_ → not available today; push/poll for Outlook is not implemented.
136
-
137
- ## References
138
-
139
- - Gmail Pub/Sub concept doc: `docs/automation/gmail-pubsub.md`
140
- - gog (Google Workspace CLI): `skills/gog/SKILL.md`
141
- - Outlook plugin source: `extensions/outlook/` (tools in `src/tools.ts`, OAuth in `src/auth.ts`)
142
- - Config types: `src/config/types.hooks.ts` (`HooksGmailConfig`)
@@ -1,83 +0,0 @@
1
- ---
2
- name: document-generation
3
- description: Generate Word (.docx), Excel (.xlsx), PowerPoint (.pptx), and PDF documents via npm packages bundled with Symi. Write a short Node.js script (.cjs for CommonJS), execute via exec with host=gateway. Use when the user asks to create, generate, or export documents.
4
- triggers: [document, docx, xlsx, pptx, pdf, word, excel, powerpoint, generate, export, file]
5
- ---
6
-
7
- # Document Generation
8
-
9
- Symi ships with these npm packages bundled for document generation via the `exec` tool:
10
-
11
- - **`docx`** — create `.docx` (Word) files with headings, paragraphs, tables, images, styles.
12
- - **`exceljs`** — create `.xlsx` (Excel) files with sheets, formulas, formatting, charts.
13
- - **`pptxgenjs`** — create `.pptx` (PowerPoint) files with slides, layouts, text, images, charts.
14
- - **`pdfkit`** — create `.pdf` files with text, images, tables, vector graphics.
15
-
16
- These are real `dependencies` in Symi's `package.json` — they install with Symi automatically. No separate setup step.
17
-
18
- ## How to invoke
19
-
20
- When the user asks to **create, generate, or export** a document:
21
-
22
- 1. Write a short Node.js script. Save it with the `.cjs` extension so CommonJS `require()` resolves correctly even though Symi's own package is `"type": "module"`.
23
- 2. Execute via the `exec` tool with `host: "gateway"` — the packages are installed in Symi's own `node_modules`, which the gateway host can resolve from.
24
- 3. Write the output to a path the user can pick up — typically the workspace dir, `~/Downloads/`, or wherever the user named.
25
-
26
- ## Minimal example — Word doc
27
-
28
- ```js
29
- // gen.cjs
30
- const { Document, Packer, Paragraph, TextRun, HeadingLevel } = require("docx");
31
- const fs = require("fs");
32
-
33
- const doc = new Document({
34
- sections: [
35
- {
36
- children: [
37
- new Paragraph({ heading: HeadingLevel.TITLE, children: [new TextRun("Report")] }),
38
- new Paragraph({ children: [new TextRun("Body content here.")] }),
39
- ],
40
- },
41
- ],
42
- });
43
-
44
- Packer.toBuffer(doc).then((buf) => {
45
- fs.writeFileSync("/tmp/report.docx", buf);
46
- });
47
- ```
48
-
49
- Then `exec({ host: "gateway", command: "node gen.cjs" })`.
50
-
51
- The script must run on the gateway host because that's where Symi's `node_modules` live — the sandbox and remote nodes do NOT have these packages.
52
-
53
- ## Other formats
54
-
55
- ```js
56
- // xlsx
57
- const ExcelJS = require("exceljs");
58
- const wb = new ExcelJS.Workbook();
59
- const sheet = wb.addWorksheet("Sheet1");
60
- sheet.getCell("A1").value = "Hello";
61
- await wb.xlsx.writeFile("/tmp/out.xlsx");
62
-
63
- // pptx
64
- const PptxGenJS = require("pptxgenjs");
65
- const pptx = new PptxGenJS();
66
- const slide = pptx.addSlide();
67
- slide.addText("Hello", { x: 1, y: 1, w: 4, h: 1 });
68
- await pptx.writeFile({ fileName: "/tmp/out.pptx" });
69
-
70
- // pdf
71
- const PDFDocument = require("pdfkit");
72
- const fs = require("fs");
73
- const pdf = new PDFDocument();
74
- pdf.pipe(fs.createWriteStream("/tmp/out.pdf"));
75
- pdf.text("Hello");
76
- pdf.end();
77
- ```
78
-
79
- ## What NOT to do
80
-
81
- - **Don't use Pandoc, LibreOffice, or other CLI converters** unless the user specifically asks. The bundled npm packages are faster, more reliable, and don't require external binaries.
82
- - **Don't try to generate documents from the sandbox host** — the packages live in Symi's own `node_modules` on the gateway host.
83
- - **Don't dump 10KB of HTML and call it a "document"**. Use the structured generators above.
@@ -1,51 +0,0 @@
1
- ---
2
- name: eightctl
3
- description: Control Eight Sleep pods (status, temperature, alarms, schedules).
4
- homepage: https://eightctl.sh
5
- metadata:
6
- {
7
- "symi":
8
- {
9
- "emoji": "🎛️",
10
- "requires": { "bins": ["eightctl"] },
11
- "install":
12
- [
13
- {
14
- "id": "go",
15
- "kind": "go",
16
- "module": "github.com/steipete/eightctl/cmd/eightctl@latest",
17
- "bins": ["eightctl"],
18
- "label": "Install eightctl (go)",
19
- },
20
- ],
21
- },
22
- }
23
- triggers: [eightctl]
24
- ---
25
-
26
- # eightctl
27
-
28
- Use `eightctl` for Eight Sleep pod control. Requires auth.
29
-
30
- Auth
31
-
32
- - Config: `~/.config/eightctl/config.yaml`
33
- - Env: `EIGHTCTL_EMAIL`, `EIGHTCTL_PASSWORD`
34
-
35
- Quick start
36
-
37
- - `eightctl status`
38
- - `eightctl on|off`
39
- - `eightctl temp 20`
40
-
41
- Common tasks
42
-
43
- - Alarms: `eightctl alarm list|create|dismiss`
44
- - Schedules: `eightctl schedule list|create|update`
45
- - Audio: `eightctl audio state|play|pause`
46
- - Base: `eightctl base info|angle`
47
-
48
- Notes
49
-
50
- - API is unofficial and rate-limited; avoid repeated logins.
51
- - Confirm before changing temperature or alarms.
@@ -1,49 +0,0 @@
1
- ---
2
- name: food-order
3
- description: Reorder Foodora orders + track ETA/status with ordercli. Never confirm without explicit user approval. Triggers: order food, reorder, track ETA.
4
- homepage: https://ordercli.sh
5
- metadata: {"symi":{"emoji":"🥡","requires":{"bins":["ordercli"]},"install":[{"id":"go","kind":"go","module":"github.com/steipete/ordercli/cmd/ordercli@latest","bins":["ordercli"],"label":"Install ordercli (go)"}]}}
6
- triggers: [food-order, food, order]
7
- ---
8
-
9
- # Food order (Foodora via ordercli)
10
-
11
- Goal: reorder a previous Foodora order safely (preview first; confirm only on explicit user “yes/confirm/place the order”).
12
-
13
- Hard safety rules
14
-
15
- - Never run `ordercli foodora reorder ... --confirm` unless user explicitly confirms placing the order.
16
- - Prefer preview-only steps first; show what will happen; ask for confirmation.
17
- - If user is unsure: stop at preview and ask questions.
18
-
19
- Setup (once)
20
-
21
- - Country: `ordercli foodora countries` → `ordercli foodora config set --country AT`
22
- - Login (password): `ordercli foodora login --email you@example.com --password-stdin`
23
- - Login (no password, preferred): `ordercli foodora session chrome --url https://www.foodora.at/ --profile "Default"`
24
-
25
- Find what to reorder
26
-
27
- - Recent list: `ordercli foodora history --limit 10`
28
- - Details: `ordercli foodora history show <orderCode>`
29
- - If needed (machine-readable): `ordercli foodora history show <orderCode> --json`
30
-
31
- Preview reorder (no cart changes)
32
-
33
- - `ordercli foodora reorder <orderCode>`
34
-
35
- Place reorder (cart change; explicit confirmation required)
36
-
37
- - Confirm first, then run: `ordercli foodora reorder <orderCode> --confirm`
38
- - Multiple addresses? Ask user for the right `--address-id` (take from their Foodora account / prior order data) and run:
39
- - `ordercli foodora reorder <orderCode> --confirm --address-id <id>`
40
-
41
- Track the order
42
-
43
- - ETA/status (active list): `ordercli foodora orders`
44
- - Live updates: `ordercli foodora orders --watch`
45
- - Single order detail: `ordercli foodora order <orderCode>`
46
-
47
- Debug / safe testing
48
-
49
- - Use a throwaway config: `ordercli --config /tmp/ordercli.json ...`
@@ -1,44 +0,0 @@
1
- ---
2
- name: gemini
3
- description: Gemini CLI for one-shot Q&A, summaries, and generation.
4
- homepage: https://ai.google.dev/
5
- metadata:
6
- {
7
- "symi":
8
- {
9
- "emoji": "♊️",
10
- "requires": { "bins": ["gemini"] },
11
- "install":
12
- [
13
- {
14
- "id": "brew",
15
- "kind": "brew",
16
- "formula": "gemini-cli",
17
- "bins": ["gemini"],
18
- "label": "Install Gemini CLI (brew)",
19
- },
20
- ],
21
- },
22
- }
23
- triggers: [gemini]
24
- ---
25
-
26
- # Gemini CLI
27
-
28
- Use Gemini in one-shot mode with a positional prompt (avoid interactive mode).
29
-
30
- Quick start
31
-
32
- - `gemini "Answer this question..."`
33
- - `gemini --model <name> "Prompt..."`
34
- - `gemini --output-format json "Return JSON"`
35
-
36
- Extensions
37
-
38
- - List: `gemini --list-extensions`
39
- - Manage: `gemini extensions <command>`
40
-
41
- Notes
42
-
43
- - If auth is required, run `gemini` once interactively and follow the login flow.
44
- - Avoid `--yolo` for safety.