@doist/twist-cli 2.21.1 → 2.21.2

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 (202) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/__mocks__/chalk.d.ts +3 -0
  3. package/dist/__mocks__/chalk.d.ts.map +1 -0
  4. package/dist/__mocks__/chalk.js +8 -0
  5. package/dist/__mocks__/chalk.js.map +1 -0
  6. package/dist/commands/auth.d.ts +3 -0
  7. package/dist/commands/auth.d.ts.map +1 -0
  8. package/dist/commands/auth.js +155 -0
  9. package/dist/commands/auth.js.map +1 -0
  10. package/dist/commands/away.d.ts +3 -0
  11. package/dist/commands/away.d.ts.map +1 -0
  12. package/dist/commands/away.js +120 -0
  13. package/dist/commands/away.js.map +1 -0
  14. package/dist/commands/changelog.d.ts +8 -0
  15. package/dist/commands/changelog.d.ts.map +1 -0
  16. package/dist/commands/changelog.js +113 -0
  17. package/dist/commands/changelog.js.map +1 -0
  18. package/dist/commands/channel.d.ts +3 -0
  19. package/dist/commands/channel.d.ts.map +1 -0
  20. package/dist/commands/channel.js +53 -0
  21. package/dist/commands/channel.js.map +1 -0
  22. package/dist/commands/comment.d.ts +3 -0
  23. package/dist/commands/comment.d.ts.map +1 -0
  24. package/dist/commands/comment.js +99 -0
  25. package/dist/commands/comment.js.map +1 -0
  26. package/dist/commands/completion.d.ts +3 -0
  27. package/dist/commands/completion.d.ts.map +1 -0
  28. package/dist/commands/completion.js +121 -0
  29. package/dist/commands/completion.js.map +1 -0
  30. package/dist/commands/conversation.d.ts +3 -0
  31. package/dist/commands/conversation.d.ts.map +1 -0
  32. package/dist/commands/conversation.js +458 -0
  33. package/dist/commands/conversation.js.map +1 -0
  34. package/dist/commands/inbox.d.ts +3 -0
  35. package/dist/commands/inbox.d.ts.map +1 -0
  36. package/dist/commands/inbox.js +127 -0
  37. package/dist/commands/inbox.js.map +1 -0
  38. package/dist/commands/msg.d.ts +3 -0
  39. package/dist/commands/msg.d.ts.map +1 -0
  40. package/dist/commands/msg.js +103 -0
  41. package/dist/commands/msg.js.map +1 -0
  42. package/dist/commands/react.d.ts +3 -0
  43. package/dist/commands/react.d.ts.map +1 -0
  44. package/dist/commands/react.js +102 -0
  45. package/dist/commands/react.js.map +1 -0
  46. package/dist/commands/search.d.ts +3 -0
  47. package/dist/commands/search.d.ts.map +1 -0
  48. package/dist/commands/search.js +160 -0
  49. package/dist/commands/search.js.map +1 -0
  50. package/dist/commands/skill.d.ts +3 -0
  51. package/dist/commands/skill.d.ts.map +1 -0
  52. package/dist/commands/skill.js +119 -0
  53. package/dist/commands/skill.js.map +1 -0
  54. package/dist/commands/thread/create.d.ts +7 -0
  55. package/dist/commands/thread/create.d.ts.map +1 -0
  56. package/dist/commands/thread/create.js +45 -0
  57. package/dist/commands/thread/create.js.map +1 -0
  58. package/dist/commands/thread/helpers.d.ts +10 -0
  59. package/dist/commands/thread/helpers.d.ts.map +1 -0
  60. package/dist/commands/thread/helpers.js +27 -0
  61. package/dist/commands/thread/helpers.js.map +1 -0
  62. package/dist/commands/thread/mutate.d.ts +5 -0
  63. package/dist/commands/thread/mutate.d.ts.map +1 -0
  64. package/dist/commands/thread/mutate.js +21 -0
  65. package/dist/commands/thread/mutate.js.map +1 -0
  66. package/dist/commands/thread/mute.d.ts +8 -0
  67. package/dist/commands/thread/mute.d.ts.map +1 -0
  68. package/dist/commands/thread/mute.js +58 -0
  69. package/dist/commands/thread/mute.js.map +1 -0
  70. package/dist/commands/thread/reply.d.ts +9 -0
  71. package/dist/commands/thread/reply.d.ts.map +1 -0
  72. package/dist/commands/thread/reply.js +68 -0
  73. package/dist/commands/thread/reply.js.map +1 -0
  74. package/dist/commands/thread/view.d.ts +9 -0
  75. package/dist/commands/thread/view.d.ts.map +1 -0
  76. package/dist/commands/thread/view.js +175 -0
  77. package/dist/commands/thread/view.js.map +1 -0
  78. package/dist/commands/thread.d.ts +3 -0
  79. package/dist/commands/thread.d.ts.map +1 -0
  80. package/dist/commands/thread.js +70 -0
  81. package/dist/commands/thread.js.map +1 -0
  82. package/dist/commands/update.d.ts +14 -0
  83. package/dist/commands/update.d.ts.map +1 -0
  84. package/dist/commands/update.js +91 -0
  85. package/dist/commands/update.js.map +1 -0
  86. package/dist/commands/user.d.ts +3 -0
  87. package/dist/commands/user.d.ts.map +1 -0
  88. package/dist/commands/user.js +67 -0
  89. package/dist/commands/user.js.map +1 -0
  90. package/dist/commands/view.d.ts +3 -0
  91. package/dist/commands/view.d.ts.map +1 -0
  92. package/dist/commands/view.js +63 -0
  93. package/dist/commands/view.js.map +1 -0
  94. package/dist/commands/workspace.d.ts +3 -0
  95. package/dist/commands/workspace.d.ts.map +1 -0
  96. package/dist/commands/workspace.js +48 -0
  97. package/dist/commands/workspace.js.map +1 -0
  98. package/dist/index.d.ts +3 -0
  99. package/dist/index.d.ts.map +1 -0
  100. package/dist/index.js +133 -0
  101. package/dist/index.js.map +1 -0
  102. package/dist/lib/api.d.ts +20 -0
  103. package/dist/lib/api.d.ts.map +1 -0
  104. package/dist/lib/api.js +229 -0
  105. package/dist/lib/api.js.map +1 -0
  106. package/dist/lib/auth.d.ts +21 -0
  107. package/dist/lib/auth.d.ts.map +1 -0
  108. package/dist/lib/auth.js +189 -0
  109. package/dist/lib/auth.js.map +1 -0
  110. package/dist/lib/completion.d.ts +31 -0
  111. package/dist/lib/completion.d.ts.map +1 -0
  112. package/dist/lib/completion.js +173 -0
  113. package/dist/lib/completion.js.map +1 -0
  114. package/dist/lib/config.d.ts +13 -0
  115. package/dist/lib/config.d.ts.map +1 -0
  116. package/dist/lib/config.js +26 -0
  117. package/dist/lib/config.js.map +1 -0
  118. package/dist/lib/dates.d.ts +3 -0
  119. package/dist/lib/dates.d.ts.map +1 -0
  120. package/dist/lib/dates.js +44 -0
  121. package/dist/lib/dates.js.map +1 -0
  122. package/dist/lib/input.d.ts +3 -0
  123. package/dist/lib/input.d.ts.map +1 -0
  124. package/dist/lib/input.js +52 -0
  125. package/dist/lib/input.js.map +1 -0
  126. package/dist/lib/markdown.d.ts +2 -0
  127. package/dist/lib/markdown.d.ts.map +1 -0
  128. package/dist/lib/markdown.js +16 -0
  129. package/dist/lib/markdown.js.map +1 -0
  130. package/dist/lib/oauth-server.d.ts +13 -0
  131. package/dist/lib/oauth-server.d.ts.map +1 -0
  132. package/dist/lib/oauth-server.js +824 -0
  133. package/dist/lib/oauth-server.js.map +1 -0
  134. package/dist/lib/oauth.d.ts +31 -0
  135. package/dist/lib/oauth.d.ts.map +1 -0
  136. package/dist/lib/oauth.js +140 -0
  137. package/dist/lib/oauth.js.map +1 -0
  138. package/dist/lib/options.d.ts +17 -0
  139. package/dist/lib/options.d.ts.map +1 -0
  140. package/dist/lib/options.js +2 -0
  141. package/dist/lib/options.js.map +1 -0
  142. package/dist/lib/output.d.ts +25 -0
  143. package/dist/lib/output.d.ts.map +1 -0
  144. package/dist/lib/output.js +128 -0
  145. package/dist/lib/output.js.map +1 -0
  146. package/dist/lib/permissions.d.ts +4 -0
  147. package/dist/lib/permissions.d.ts.map +1 -0
  148. package/dist/lib/permissions.js +35 -0
  149. package/dist/lib/permissions.js.map +1 -0
  150. package/dist/lib/pkce.d.ts +16 -0
  151. package/dist/lib/pkce.d.ts.map +1 -0
  152. package/dist/lib/pkce.js +35 -0
  153. package/dist/lib/pkce.js.map +1 -0
  154. package/dist/lib/progress.d.ts +29 -0
  155. package/dist/lib/progress.d.ts.map +1 -0
  156. package/dist/lib/progress.js +101 -0
  157. package/dist/lib/progress.js.map +1 -0
  158. package/dist/lib/public-channels.d.ts +5 -0
  159. package/dist/lib/public-channels.d.ts.map +1 -0
  160. package/dist/lib/public-channels.js +35 -0
  161. package/dist/lib/public-channels.js.map +1 -0
  162. package/dist/lib/refs.d.ts +37 -0
  163. package/dist/lib/refs.d.ts.map +1 -0
  164. package/dist/lib/refs.js +219 -0
  165. package/dist/lib/refs.js.map +1 -0
  166. package/dist/lib/search-api.d.ts +25 -0
  167. package/dist/lib/search-api.d.ts.map +1 -0
  168. package/dist/lib/search-api.js +85 -0
  169. package/dist/lib/search-api.js.map +1 -0
  170. package/dist/lib/secure-store.d.ts +11 -0
  171. package/dist/lib/secure-store.d.ts.map +1 -0
  172. package/dist/lib/secure-store.js +57 -0
  173. package/dist/lib/secure-store.js.map +1 -0
  174. package/dist/lib/skills/content.d.ts +5 -0
  175. package/dist/lib/skills/content.d.ts.map +1 -0
  176. package/dist/lib/skills/content.js +286 -0
  177. package/dist/lib/skills/content.js.map +1 -0
  178. package/dist/lib/skills/create-installer.d.ts +9 -0
  179. package/dist/lib/skills/create-installer.d.ts.map +1 -0
  180. package/dist/lib/skills/create-installer.js +60 -0
  181. package/dist/lib/skills/create-installer.js.map +1 -0
  182. package/dist/lib/skills/index.d.ts +7 -0
  183. package/dist/lib/skills/index.d.ts.map +1 -0
  184. package/dist/lib/skills/index.js +54 -0
  185. package/dist/lib/skills/index.js.map +1 -0
  186. package/dist/lib/skills/types.d.ts +30 -0
  187. package/dist/lib/skills/types.d.ts.map +1 -0
  188. package/dist/lib/skills/types.js +2 -0
  189. package/dist/lib/skills/types.js.map +1 -0
  190. package/dist/lib/skills/update-installed.d.ts +9 -0
  191. package/dist/lib/skills/update-installed.d.ts.map +1 -0
  192. package/dist/lib/skills/update-installed.js +20 -0
  193. package/dist/lib/skills/update-installed.js.map +1 -0
  194. package/dist/lib/spinner.d.ts +24 -0
  195. package/dist/lib/spinner.d.ts.map +1 -0
  196. package/dist/lib/spinner.js +126 -0
  197. package/dist/lib/spinner.js.map +1 -0
  198. package/dist/postinstall.d.ts +2 -0
  199. package/dist/postinstall.d.ts.map +1 -0
  200. package/dist/postinstall.js +3 -0
  201. package/dist/postinstall.js.map +1 -0
  202. package/package.json +3 -2
@@ -0,0 +1,286 @@
1
+ export const SKILL_NAME = 'twist-cli';
2
+ export const SKILL_DESCRIPTION = 'Twist messaging CLI for team communication';
3
+ export const SKILL_CONTENT = `# Twist CLI (tw)
4
+
5
+ Access Twist messaging via the \`tw\` CLI. Use when the user asks about their Twist workspaces, threads, messages, or wants to interact with Twist in any way.
6
+
7
+ ## Setup
8
+
9
+ \`\`\`bash
10
+ tw auth login # OAuth login (opens browser, read-write)
11
+ tw auth login --read-only # OAuth login with read-only scope
12
+ tw auth token # Save API token manually (prompts securely; scope unknown, assumed write-capable)
13
+ tw auth status # Verify authentication + show mode
14
+ tw auth status --json # JSON output: { id, email, name }
15
+ tw auth logout # Remove saved token and auth metadata
16
+ tw workspaces # List available workspaces
17
+ tw workspace use <ref> # Set current workspace
18
+ tw completion install # Install shell completions
19
+ tw update # Update CLI to latest version
20
+ tw changelog # Show recent changelog entries
21
+ \`\`\`
22
+
23
+ Stored auth uses the system credential manager when available. If secure storage is unavailable, \`tw\` warns and falls back to \`~/.config/twist-cli/config.json\`. \`TWIST_API_TOKEN\` always takes priority over the stored token, and legacy plaintext config tokens are migrated automatically when secure storage is available.
24
+
25
+ In read-only mode (\`tw auth login --read-only\`), commands that modify Twist data (reply, archive, react, delete, etc.) are blocked by the CLI. Externally provided tokens (\`TWIST_API_TOKEN\` or \`tw auth token\`) are treated as unknown scope and assumed write-capable.
26
+
27
+ ## View by URL
28
+
29
+ \`\`\`bash
30
+ tw view <url> # View any Twist entity by URL
31
+ \`\`\`
32
+
33
+ Routes automatically based on URL structure:
34
+ - Message URL → \`tw msg view\`
35
+ - Conversation URL → \`tw conversation view\`
36
+ - Thread+comment URL → \`tw thread view\` (comment ID extracted from URL)
37
+ - Thread URL → \`tw thread view\`
38
+
39
+ All target command flags pass through (e.g. \`--json\`, \`--raw\`, \`--full\`).
40
+
41
+ ## Inbox
42
+
43
+ \`\`\`bash
44
+ tw inbox # Show inbox threads
45
+ tw inbox --unread # Only unread threads
46
+ tw inbox --channel <filter> # Filter by channel name (fuzzy)
47
+ tw inbox --since <date> # Filter by date (ISO format)
48
+ tw inbox --limit <n> # Max items (default: 50)
49
+ \`\`\`
50
+
51
+ ## Threads
52
+
53
+ \`\`\`bash
54
+ tw thread <thread-ref> # View thread (shorthand for view)
55
+ tw thread view <thread-ref> # View thread with comments
56
+ tw thread view <ref> --comment <id> # View a specific comment
57
+ tw thread view <url-with-/c/id> # Comment ID extracted from URL
58
+ tw thread view <ref> --unread # Show only unread comments
59
+ tw thread view <ref> --context 3 # Include 3 read comments before unread
60
+ tw thread view <ref> --limit 20 # Limit number of comments
61
+ tw thread view <ref> --since <date> # Comments newer than date
62
+ tw thread view <ref> --raw # Show raw markdown
63
+ tw thread create <channel-ref> "Title" "content" # Create a new thread
64
+ tw thread create <channel-ref> "Title" "content" --json # Create and return as JSON
65
+ tw thread create <channel-ref> "Title" "content" --json --full # Include all thread fields
66
+ tw thread create <channel-ref> "Title" "content" --notify 123,456 # Notify specific users
67
+ tw thread create <channel-ref> "Title" "content" --dry-run # Preview without posting
68
+ tw thread reply <ref> "content" # Post a comment (notifies EVERYONE_IN_THREAD by default)
69
+ tw thread reply <ref> "content" --notify EVERYONE # Notify all workspace members
70
+ tw thread reply <ref> "content" --notify 123,id:456 # Notify specific user IDs
71
+ tw thread reply <ref> "content" --json # Post and return comment as JSON
72
+ tw thread reply <ref> "content" --json --full # Include all comment fields
73
+ tw thread reply <ref> "content" --close # Reply and close the thread
74
+ tw thread reply <ref> "content" --reopen # Reply and reopen a closed thread
75
+ tw thread done <ref> # Archive thread (mark done)
76
+ tw thread done <ref> --json # Archive and return status as JSON
77
+ tw thread mute <ref> # Mute thread for 60 minutes (default)
78
+ tw thread mute <ref> --minutes 480 # Mute for custom duration
79
+ tw thread mute <ref> --json # Mute and return { id, mutedUntil } as JSON
80
+ tw thread mute <ref> --json --full # Mute and return full thread as JSON
81
+ tw thread unmute <ref> # Unmute a muted thread
82
+ tw thread unmute <ref> --json # Unmute and return { id, mutedUntil } as JSON
83
+ \`\`\`
84
+
85
+ Default \`--notify\` for reply is EVERYONE_IN_THREAD, which may notify more people than intended. Before posting, confirm with the user whether specific people should be notified instead (via \`--notify <user-ids>\`). Options: EVERYONE, EVERYONE_IN_THREAD, or comma-separated user ID refs.
86
+
87
+ ## Thread Comments
88
+
89
+ \`\`\`bash
90
+ tw comment <comment-ref> # View a comment (shorthand for view)
91
+ tw comment view <comment-ref> # View a single thread comment
92
+ tw comment view <comment-ref> --raw # Show raw markdown
93
+ tw comment view <comment-ref> --json # Output as JSON
94
+ tw comment view <comment-ref> --json --full # Include all fields in JSON output
95
+ tw comment update <comment-ref> "new content" # Update a thread comment
96
+ tw comment update <comment-ref> "content" --json # Update and return updated comment as JSON
97
+ tw comment update <comment-ref> "content" --json --full # Include all comment fields
98
+ tw comment delete <comment-ref> # Delete a thread comment
99
+ tw comment delete <comment-ref> --json # Delete and return status as JSON
100
+ \`\`\`
101
+
102
+ ## Conversations (DMs/Groups)
103
+
104
+ \`\`\`bash
105
+ tw conversation unread # List unread conversations
106
+ tw conversation <conversation-ref> # View conversation (shorthand for view)
107
+ tw conversation view <conversation-ref> # View conversation messages
108
+ tw conversation with <user-ref> # Find your 1:1 DM with a user
109
+ tw conversation with <user-ref> --snippet # Include the latest message preview
110
+ tw conversation with <user-ref> --include-groups # List any conversations with that user
111
+ tw conversation reply <ref> "content" # Send a message
112
+ tw conversation reply <ref> "content" --json # Send and return message as JSON
113
+ tw conversation reply <ref> "content" --json --full # Include all message fields
114
+ tw conversation done <ref> # Archive conversation
115
+ tw conversation done <ref> --json # Archive and return status as JSON
116
+ tw conversation mute <ref> # Mute conversation for 60 minutes (default)
117
+ tw conversation mute <ref> --minutes 480 # Mute for custom duration
118
+ tw conversation mute <ref> --json # Mute and return { id, mutedUntil } as JSON
119
+ tw conversation mute <ref> --json --full # Mute and return full conversation as JSON
120
+ tw conversation unmute <ref> # Unmute a muted conversation
121
+ tw conversation unmute <ref> --json # Unmute and return { id, mutedUntil } as JSON
122
+ \`\`\`
123
+
124
+ Alias: \`tw convo\` works the same as \`tw conversation\`.
125
+
126
+ ## Conversation Messages
127
+
128
+ \`\`\`bash
129
+ tw msg <message-ref> # View a message (shorthand for view)
130
+ tw msg view <message-ref> # View a single conversation message
131
+ tw msg update <ref> "content" # Edit a conversation message
132
+ tw msg update <ref> "content" --json # Edit and return updated message as JSON
133
+ tw msg update <ref> "content" --json --full # Include all message fields
134
+ tw msg delete <ref> # Delete a conversation message
135
+ tw msg delete <ref> --json # Delete and return status as JSON
136
+ \`\`\`
137
+
138
+ Alias: \`tw message\` works the same as \`tw msg\`.
139
+
140
+ ## Search
141
+
142
+ \`\`\`bash
143
+ tw search "query" # Search content
144
+ tw search "query" --type threads # Filter: threads, messages, or all
145
+ tw search "query" --author <ref> # Filter by author
146
+ tw search "query" --to <ref> # Messages sent to user
147
+ tw search "query" --title-only # Search thread titles only
148
+ tw search "query" --mention-me # Results mentioning current user
149
+ tw search "query" --conversation <refs> # Limit to conversations (comma-separated refs)
150
+ tw search "query" --since <date> # Content from date
151
+ tw search "query" --until <date> # Content until date
152
+ tw search "query" --channel <refs> # Filter by channel refs (comma-separated)
153
+ tw search "query" --limit <n> # Max results (default: 50)
154
+ tw search "query" --cursor <cur> # Pagination cursor
155
+ \`\`\`
156
+
157
+ ## Users & Channels
158
+
159
+ \`\`\`bash
160
+ tw user # Show current user info
161
+ tw users # List workspace users
162
+ tw users --search <text> # Filter by name/email
163
+ tw channels # List workspace channels
164
+ \`\`\`
165
+
166
+ ## Away Status
167
+
168
+ \`\`\`bash
169
+ tw away # Show current away status
170
+ tw away set <type> [until] # Set away (type: vacation, parental, sickleave, other)
171
+ tw away set vacation 2026-03-20 # Away until March 20
172
+ tw away set vacation 2026-03-20 --from 2026-03-15 # Custom start date
173
+ tw away clear # Clear away status
174
+ \`\`\`
175
+
176
+ ## Reactions
177
+
178
+ \`\`\`bash
179
+ tw react thread <ref> 👍 # Add reaction to thread
180
+ tw react comment <ref> +1 # Add reaction (shortcode)
181
+ tw react message <ref> heart # Add reaction to DM message
182
+ tw unreact thread <ref> 👍 # Remove reaction
183
+ \`\`\`
184
+
185
+ Supported shortcodes: +1, -1, heart, tada, smile, laughing, thinking, fire, check, x, eyes, pray, clap, rocket, wave
186
+
187
+ ## Shell Completions
188
+
189
+ \`\`\`bash
190
+ tw completion install # Install tab completions (prompts for shell)
191
+ tw completion install bash # Install for specific shell
192
+ tw completion install zsh
193
+ tw completion install fish
194
+ tw completion uninstall # Remove completions
195
+ \`\`\`
196
+
197
+ ### Update
198
+
199
+ \`\`\`bash
200
+ tw update # Update CLI to latest version
201
+ tw update --check # Check for updates without installing
202
+ \`\`\`
203
+
204
+ ### Changelog
205
+ \`\`\`bash
206
+ tw changelog # Show last 5 versions
207
+ tw changelog -n 3 # Show last 3 versions
208
+ tw changelog --count 10 # Show last 10 versions
209
+ \`\`\`
210
+
211
+ ## Global Options
212
+
213
+ \`\`\`bash
214
+ --no-spinner # Disable loading animations
215
+ --progress-jsonl # Machine-readable progress events (JSONL to stderr)
216
+ --accessible # Add text labels to color-coded output (also: TW_ACCESSIBLE=1)
217
+ \`\`\`
218
+
219
+ ## Output Formats
220
+
221
+ All list/view commands support:
222
+
223
+ \`\`\`bash
224
+ --json # Output as JSON
225
+ --ndjson # Output as newline-delimited JSON (for streaming)
226
+ --full # Include all fields (default shows essential fields only)
227
+ \`\`\`
228
+
229
+ ## Reference System
230
+
231
+ Commands accept flexible references:
232
+ - **Numeric IDs**: \`123\` or \`id:123\`
233
+ - **Twist URLs**: Full \`https://twist.com/...\` URLs (parsed automatically)
234
+ - **Fuzzy names**: For workspaces/users - \`"My Workspace"\` or partial matches
235
+
236
+ ## Piping Content
237
+
238
+ Commands that accept content (\`thread create\`, \`thread reply\`, \`comment update\`, \`conversation reply\`, \`msg update\`) auto-detect piped stdin:
239
+
240
+ \`\`\`bash
241
+ cat notes.md | tw thread reply <ref>
242
+ tw thread create <channel-ref> "Title" < body.md
243
+ echo "Quick reply" | tw conversation reply <ref>
244
+ \`\`\`
245
+
246
+ If no content argument is provided and no stdin is piped, the CLI opens \`$EDITOR\` for interactive input.
247
+
248
+ ## Common Workflows
249
+
250
+ **View by URL (auto-routes to the right command):**
251
+ \`\`\`bash
252
+ tw view https://twist.com/a/1585/ch/100/t/200 # View thread
253
+ tw view https://twist.com/a/1585/ch/100/t/200/c/300 # View comment
254
+ tw view https://twist.com/a/1585/msg/400 # View conversation
255
+ tw view https://twist.com/a/1585/msg/400/m/500 --json # View message as JSON
256
+ \`\`\`
257
+
258
+ **Check inbox and respond:**
259
+ \`\`\`bash
260
+ tw inbox --unread --json
261
+ tw thread view <id> --unread
262
+ tw thread reply <id> "Thanks, I'll look into this."
263
+ tw thread done <id>
264
+ \`\`\`
265
+
266
+ **Search and review:**
267
+ \`\`\`bash
268
+ tw search "deployment" --type threads --json
269
+ tw thread view <thread-id>
270
+ \`\`\`
271
+
272
+ **Check DMs:**
273
+ \`\`\`bash
274
+ tw conversation unread --json
275
+ tw conversation view <conversation-id>
276
+ tw conversation with "Alice Example"
277
+ tw conversation reply <id> "Got it, thanks!"
278
+ \`\`\`
279
+ `;
280
+ export const SKILL_FILE_CONTENT = `---
281
+ name: ${SKILL_NAME}
282
+ description: ${JSON.stringify(SKILL_DESCRIPTION)}
283
+ ---
284
+
285
+ ${SKILL_CONTENT}`;
286
+ //# sourceMappingURL=content.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content.js","sourceRoot":"","sources":["../../../src/lib/skills/content.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,UAAU,GAAG,WAAW,CAAA;AAErC,MAAM,CAAC,MAAM,iBAAiB,GAAG,4CAA4C,CAAA;AAE7E,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoR5B,CAAA;AAED,MAAM,CAAC,MAAM,kBAAkB,GAAG;QAC1B,UAAU;eACH,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC;;;EAG9C,aAAa,EAAE,CAAA"}
@@ -0,0 +1,9 @@
1
+ import type { SkillInstaller } from './types.js';
2
+ interface InstallerConfig {
3
+ name: string;
4
+ description: string;
5
+ dirName: string;
6
+ }
7
+ export declare function createInstaller(config: InstallerConfig): SkillInstaller;
8
+ export {};
9
+ //# sourceMappingURL=create-installer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-installer.d.ts","sourceRoot":"","sources":["../../../src/lib/skills/create-installer.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAkB,cAAc,EAAmC,MAAM,YAAY,CAAA;AAEjG,UAAU,eAAe;IACrB,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;CAClB;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,GAAG,cAAc,CAqEvE"}
@@ -0,0 +1,60 @@
1
+ import { mkdir, rm, stat, writeFile } from 'node:fs/promises';
2
+ import { homedir } from 'node:os';
3
+ import { dirname, join } from 'node:path';
4
+ import { SKILL_FILE_CONTENT, SKILL_NAME } from './content.js';
5
+ export function createInstaller(config) {
6
+ function getInstallPath(options) {
7
+ const base = options.local ? process.cwd() : homedir();
8
+ return join(base, config.dirName, 'skills', SKILL_NAME, 'SKILL.md');
9
+ }
10
+ return {
11
+ name: config.name,
12
+ description: config.description,
13
+ getInstallPath,
14
+ async isInstalled(options) {
15
+ try {
16
+ await stat(getInstallPath(options));
17
+ return true;
18
+ }
19
+ catch {
20
+ return false;
21
+ }
22
+ },
23
+ async install(options) {
24
+ if (!options.local && config.dirName !== '.agents') {
25
+ const agentDir = join(homedir(), config.dirName);
26
+ try {
27
+ await stat(agentDir);
28
+ }
29
+ catch {
30
+ throw new Error(`${config.name} does not appear to be installed (${agentDir} not found)`);
31
+ }
32
+ }
33
+ const skillPath = getInstallPath(options);
34
+ const exists = await this.isInstalled(options);
35
+ if (exists && !options.force) {
36
+ throw new Error(`Skill already installed at ${skillPath}. Use --force to overwrite.`);
37
+ }
38
+ await mkdir(dirname(skillPath), { recursive: true });
39
+ await writeFile(skillPath, SKILL_FILE_CONTENT);
40
+ },
41
+ async update(options) {
42
+ const skillPath = getInstallPath(options);
43
+ const exists = await this.isInstalled(options);
44
+ if (!exists) {
45
+ throw new Error(`Skill not installed at ${skillPath}`);
46
+ }
47
+ await writeFile(skillPath, SKILL_FILE_CONTENT);
48
+ },
49
+ async uninstall(options) {
50
+ const skillPath = getInstallPath(options);
51
+ const exists = await this.isInstalled(options);
52
+ if (!exists) {
53
+ throw new Error(`Skill not installed at ${skillPath}`);
54
+ }
55
+ const skillDir = dirname(skillPath);
56
+ await rm(skillDir, { recursive: true });
57
+ },
58
+ };
59
+ }
60
+ //# sourceMappingURL=create-installer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create-installer.js","sourceRoot":"","sources":["../../../src/lib/skills/create-installer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;AAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAS7D,MAAM,UAAU,eAAe,CAAC,MAAuB;IACnD,SAAS,cAAc,CAAC,OAA4B;QAChD,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAA;QACtD,OAAO,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,CAAC,CAAA;IACvE,CAAC;IAED,OAAO;QACH,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,WAAW,EAAE,MAAM,CAAC,WAAW;QAE/B,cAAc;QAEd,KAAK,CAAC,WAAW,CAAC,OAA4B;YAC1C,IAAI,CAAC;gBACD,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAA;gBACnC,OAAO,IAAI,CAAA;YACf,CAAC;YAAC,MAAM,CAAC;gBACL,OAAO,KAAK,CAAA;YAChB,CAAC;QACL,CAAC;QAED,KAAK,CAAC,OAAO,CAAC,OAAuB;YACjC,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;gBACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,CAAA;gBAChD,IAAI,CAAC;oBACD,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAA;gBACxB,CAAC;gBAAC,MAAM,CAAC;oBACL,MAAM,IAAI,KAAK,CACX,GAAG,MAAM,CAAC,IAAI,qCAAqC,QAAQ,aAAa,CAC3E,CAAA;gBACL,CAAC;YACL,CAAC;YAED,MAAM,SAAS,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;YACzC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;YAE9C,IAAI,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;gBAC3B,MAAM,IAAI,KAAK,CACX,8BAA8B,SAAS,6BAA6B,CACvE,CAAA;YACL,CAAC;YAED,MAAM,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;YACpD,MAAM,SAAS,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAA;QAClD,CAAC;QAED,KAAK,CAAC,MAAM,CAAC,OAAsB;YAC/B,MAAM,SAAS,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;YACzC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;YAE9C,IAAI,CAAC,MAAM,EAAE,CAAC;gBACV,MAAM,IAAI,KAAK,CAAC,0BAA0B,SAAS,EAAE,CAAC,CAAA;YAC1D,CAAC;YAED,MAAM,SAAS,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAA;QAClD,CAAC;QAED,KAAK,CAAC,SAAS,CAAC,OAAyB;YACrC,MAAM,SAAS,GAAG,cAAc,CAAC,OAAO,CAAC,CAAA;YACzC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;YAE9C,IAAI,CAAC,MAAM,EAAE,CAAC;gBACV,MAAM,IAAI,KAAK,CAAC,0BAA0B,SAAS,EAAE,CAAC,CAAA;YAC1D,CAAC;YAED,MAAM,QAAQ,GAAG,OAAO,CAAC,SAAS,CAAC,CAAA;YACnC,MAAM,EAAE,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;QAC3C,CAAC;KACJ,CAAA;AACL,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { AgentInfo, SkillInstaller } from './types.js';
2
+ export declare const skillInstallers: Record<string, SkillInstaller>;
3
+ export declare function getInstaller(name: string): SkillInstaller | null;
4
+ export declare function listAgentNames(): string[];
5
+ export declare function listAgents(local: boolean): Promise<AgentInfo[]>;
6
+ export type { AgentInfo, InstallOptions, SkillInstaller, UninstallOptions, UpdateOptions, } from './types.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/skills/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAE3D,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CA+B1D,CAAA;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI,CAEhE;AAED,wBAAgB,cAAc,IAAI,MAAM,EAAE,CAEzC;AAED,wBAAsB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAerE;AAED,YAAY,EACR,SAAS,EACT,cAAc,EACd,cAAc,EACd,gBAAgB,EAChB,aAAa,GAChB,MAAM,YAAY,CAAA"}
@@ -0,0 +1,54 @@
1
+ import { createInstaller } from './create-installer.js';
2
+ export const skillInstallers = {
3
+ 'claude-code': createInstaller({
4
+ name: 'claude-code',
5
+ description: 'Claude Code skill for Twist CLI',
6
+ dirName: '.claude',
7
+ }),
8
+ codex: createInstaller({
9
+ name: 'codex',
10
+ description: 'Codex skill for Twist CLI',
11
+ dirName: '.codex',
12
+ }),
13
+ cursor: createInstaller({
14
+ name: 'cursor',
15
+ description: 'Cursor skill for Twist CLI',
16
+ dirName: '.cursor',
17
+ }),
18
+ gemini: createInstaller({
19
+ name: 'gemini',
20
+ description: 'Gemini CLI skill for Twist CLI',
21
+ dirName: '.gemini',
22
+ }),
23
+ pi: createInstaller({
24
+ name: 'pi',
25
+ description: 'Pi skill for Twist CLI',
26
+ dirName: '.pi',
27
+ }),
28
+ universal: createInstaller({
29
+ name: 'universal',
30
+ description: 'Universal agent skill for Twist CLI',
31
+ dirName: '.agents',
32
+ }),
33
+ };
34
+ export function getInstaller(name) {
35
+ return skillInstallers[name] ?? null;
36
+ }
37
+ export function listAgentNames() {
38
+ return Object.keys(skillInstallers);
39
+ }
40
+ export async function listAgents(local) {
41
+ const agents = [];
42
+ for (const name of listAgentNames()) {
43
+ const installer = skillInstallers[name];
44
+ const installed = await installer.isInstalled({ local });
45
+ agents.push({
46
+ name,
47
+ description: installer.description,
48
+ installed,
49
+ path: installed ? installer.getInstallPath({ local }) : null,
50
+ });
51
+ }
52
+ return agents;
53
+ }
54
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/lib/skills/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AAGvD,MAAM,CAAC,MAAM,eAAe,GAAmC;IAC3D,aAAa,EAAE,eAAe,CAAC;QAC3B,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE,iCAAiC;QAC9C,OAAO,EAAE,SAAS;KACrB,CAAC;IACF,KAAK,EAAE,eAAe,CAAC;QACnB,IAAI,EAAE,OAAO;QACb,WAAW,EAAE,2BAA2B;QACxC,OAAO,EAAE,QAAQ;KACpB,CAAC;IACF,MAAM,EAAE,eAAe,CAAC;QACpB,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,4BAA4B;QACzC,OAAO,EAAE,SAAS;KACrB,CAAC;IACF,MAAM,EAAE,eAAe,CAAC;QACpB,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,gCAAgC;QAC7C,OAAO,EAAE,SAAS;KACrB,CAAC;IACF,EAAE,EAAE,eAAe,CAAC;QAChB,IAAI,EAAE,IAAI;QACV,WAAW,EAAE,wBAAwB;QACrC,OAAO,EAAE,KAAK;KACjB,CAAC;IACF,SAAS,EAAE,eAAe,CAAC;QACvB,IAAI,EAAE,WAAW;QACjB,WAAW,EAAE,qCAAqC;QAClD,OAAO,EAAE,SAAS;KACrB,CAAC;CACL,CAAA;AAED,MAAM,UAAU,YAAY,CAAC,IAAY;IACrC,OAAO,eAAe,CAAC,IAAI,CAAC,IAAI,IAAI,CAAA;AACxC,CAAC;AAED,MAAM,UAAU,cAAc;IAC1B,OAAO,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAA;AACvC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,KAAc;IAC3C,MAAM,MAAM,GAAgB,EAAE,CAAA;IAE9B,KAAK,MAAM,IAAI,IAAI,cAAc,EAAE,EAAE,CAAC;QAClC,MAAM,SAAS,GAAG,eAAe,CAAC,IAAI,CAAC,CAAA;QACvC,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,CAAC,CAAA;QACxD,MAAM,CAAC,IAAI,CAAC;YACR,IAAI;YACJ,WAAW,EAAE,SAAS,CAAC,WAAW;YAClC,SAAS;YACT,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI;SAC/D,CAAC,CAAA;IACN,CAAC;IAED,OAAO,MAAM,CAAA;AACjB,CAAC"}
@@ -0,0 +1,30 @@
1
+ export interface InstallOptions {
2
+ local?: boolean;
3
+ force?: boolean;
4
+ }
5
+ export interface UninstallOptions {
6
+ local?: boolean;
7
+ }
8
+ export interface UpdateOptions {
9
+ local?: boolean;
10
+ }
11
+ export interface SkillInstaller {
12
+ name: string;
13
+ description: string;
14
+ install(options: InstallOptions): Promise<void>;
15
+ update(options: UpdateOptions): Promise<void>;
16
+ uninstall(options: UninstallOptions): Promise<void>;
17
+ isInstalled(options: {
18
+ local?: boolean;
19
+ }): Promise<boolean>;
20
+ getInstallPath(options: {
21
+ local?: boolean;
22
+ }): string;
23
+ }
24
+ export interface AgentInfo {
25
+ name: string;
26
+ description: string;
27
+ installed: boolean;
28
+ path: string | null;
29
+ }
30
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/skills/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,cAAc;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,KAAK,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC7B,KAAK,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,aAAa;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/C,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC7C,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACnD,WAAW,CAAC,OAAO,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAC3D,cAAc,CAAC,OAAO,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,MAAM,CAAA;CACvD;AAED,MAAM,WAAW,SAAS;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,OAAO,CAAA;IAClB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CACtB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/lib/skills/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,9 @@
1
+ export interface UpdateAllResult {
2
+ updated: string[];
3
+ skipped: string[];
4
+ errors: string[];
5
+ }
6
+ export declare function updateAllInstalledSkills(options: {
7
+ local?: boolean;
8
+ }): Promise<UpdateAllResult>;
9
+ //# sourceMappingURL=update-installed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-installed.d.ts","sourceRoot":"","sources":["../../../src/lib/skills/update-installed.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,eAAe;IAC5B,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,MAAM,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,wBAAsB,wBAAwB,CAAC,OAAO,EAAE;IACpD,KAAK,CAAC,EAAE,OAAO,CAAA;CAClB,GAAG,OAAO,CAAC,eAAe,CAAC,CAkB3B"}
@@ -0,0 +1,20 @@
1
+ import { skillInstallers } from './index.js';
2
+ export async function updateAllInstalledSkills(options) {
3
+ const result = { updated: [], skipped: [], errors: [] };
4
+ for (const [name, installer] of Object.entries(skillInstallers)) {
5
+ try {
6
+ const installed = await installer.isInstalled(options);
7
+ if (!installed) {
8
+ result.skipped.push(name);
9
+ continue;
10
+ }
11
+ await installer.update(options);
12
+ result.updated.push(name);
13
+ }
14
+ catch (err) {
15
+ result.errors.push(`${name}: ${err.message}`);
16
+ }
17
+ }
18
+ return result;
19
+ }
20
+ //# sourceMappingURL=update-installed.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update-installed.js","sourceRoot":"","sources":["../../../src/lib/skills/update-installed.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAQ5C,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,OAE9C;IACG,MAAM,MAAM,GAAoB,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAA;IAExE,KAAK,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC;QAC9D,IAAI,CAAC;YACD,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,WAAW,CAAC,OAAO,CAAC,CAAA;YACtD,IAAI,CAAC,SAAS,EAAE,CAAC;gBACb,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;gBACzB,SAAQ;YACZ,CAAC;YACD,MAAM,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;YAC/B,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC7B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,KAAM,GAAa,CAAC,OAAO,EAAE,CAAC,CAAA;QAC5D,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAA;AACjB,CAAC"}
@@ -0,0 +1,24 @@
1
+ interface SpinnerOptions {
2
+ text: string;
3
+ color?: 'green' | 'yellow' | 'blue' | 'red' | 'gray' | 'cyan' | 'magenta';
4
+ noSpinner?: boolean;
5
+ }
6
+ export declare function startEarlySpinner(): void;
7
+ export declare function stopEarlySpinner(): void;
8
+ /** For tests only — reset singleton state without stopping */
9
+ export declare function resetEarlySpinner(): void;
10
+ declare class LoadingSpinner {
11
+ private spinnerInstance;
12
+ private adopted;
13
+ start(options: SpinnerOptions): this;
14
+ succeed(text?: string): void;
15
+ fail(text?: string): void;
16
+ stop(): void;
17
+ }
18
+ /**
19
+ * High-level wrapper function for running async operations with a loading spinner.
20
+ * Automatically handles success/failure states and cleanup.
21
+ */
22
+ export declare function withSpinner<T>(options: SpinnerOptions, asyncOperation: () => Promise<T>): Promise<T>;
23
+ export { LoadingSpinner, type SpinnerOptions };
24
+ //# sourceMappingURL=spinner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spinner.d.ts","sourceRoot":"","sources":["../../src/lib/spinner.ts"],"names":[],"mappings":"AAGA,UAAU,cAAc;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;IACzE,SAAS,CAAC,EAAE,OAAO,CAAA;CACtB;AA8BD,wBAAgB,iBAAiB,IAAI,IAAI,CAcxC;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CASvC;AAED,8DAA8D;AAC9D,wBAAgB,iBAAiB,IAAI,IAAI,CAGxC;AAID,cAAM,cAAc;IAChB,OAAO,CAAC,eAAe,CAA+C;IACtE,OAAO,CAAC,OAAO,CAAQ;IAEvB,KAAK,CAAC,OAAO,EAAE,cAAc;IAuB7B,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM;IAcrB,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM;IASlB,IAAI;CAaP;AAED;;;GAGG;AACH,wBAAsB,WAAW,CAAC,CAAC,EAC/B,OAAO,EAAE,cAAc,EACvB,cAAc,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACjC,OAAO,CAAC,CAAC,CAAC,CAWZ;AAED,OAAO,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,CAAA"}