tide-commander 0.77.0 → 0.78.1

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.
@@ -1 +1 @@
1
- import{W as s}from"./main-VR06Nfll.js";import"./modulepreload-polyfill-B5Qt9EMX.js";import"./vendor-react-uS-d4TUT.js";import"./vendor-three-DJ4p3FLF.js";class f extends s{constructor(){super(...arguments),this.pending=[],this.deliveredNotifications=[],this.hasNotificationSupport=()=>{if(!("Notification"in window)||!Notification.requestPermission)return!1;if(Notification.permission!=="granted")try{new Notification("")}catch(i){if(i instanceof Error&&i.name==="TypeError")return!1}return!0}}async getDeliveredNotifications(){const i=[];for(const t of this.deliveredNotifications){const e={title:t.title,id:parseInt(t.tag),body:t.body};i.push(e)}return{notifications:i}}async removeDeliveredNotifications(i){for(const t of i.notifications){const e=this.deliveredNotifications.find(n=>n.tag===String(t.id));e==null||e.close(),this.deliveredNotifications=this.deliveredNotifications.filter(()=>!e)}}async removeAllDeliveredNotifications(){for(const i of this.deliveredNotifications)i.close();this.deliveredNotifications=[]}async createChannel(){throw this.unimplemented("Not implemented on web.")}async deleteChannel(){throw this.unimplemented("Not implemented on web.")}async listChannels(){throw this.unimplemented("Not implemented on web.")}async schedule(i){if(!this.hasNotificationSupport())throw this.unavailable("Notifications not supported in this browser.");for(const t of i.notifications)this.sendNotification(t);return{notifications:i.notifications.map(t=>({id:t.id}))}}async getPending(){return{notifications:this.pending}}async registerActionTypes(){throw this.unimplemented("Not implemented on web.")}async cancel(i){this.pending=this.pending.filter(t=>!i.notifications.find(e=>e.id===t.id))}async areEnabled(){const{display:i}=await this.checkPermissions();return{value:i==="granted"}}async changeExactNotificationSetting(){throw this.unimplemented("Not implemented on web.")}async checkExactNotificationSetting(){throw this.unimplemented("Not implemented on web.")}async requestPermissions(){if(!this.hasNotificationSupport())throw this.unavailable("Notifications not supported in this browser.");return{display:this.transformNotificationPermission(await Notification.requestPermission())}}async checkPermissions(){if(!this.hasNotificationSupport())throw this.unavailable("Notifications not supported in this browser.");return{display:this.transformNotificationPermission(Notification.permission)}}transformNotificationPermission(i){switch(i){case"granted":return"granted";case"denied":return"denied";default:return"prompt"}}sendPending(){var i;const t=[],e=new Date().getTime();for(const n of this.pending)!((i=n.schedule)===null||i===void 0)&&i.at&&n.schedule.at.getTime()<=e&&(this.buildNotification(n),t.push(n));this.pending=this.pending.filter(n=>!t.find(o=>o===n))}sendNotification(i){var t;if(!((t=i.schedule)===null||t===void 0)&&t.at){const e=i.schedule.at.getTime()-new Date().getTime();this.pending.push(i),setTimeout(()=>{this.sendPending()},e);return}this.buildNotification(i)}buildNotification(i){const t=new Notification(i.title,{body:i.body,tag:String(i.id)});return t.addEventListener("click",this.onClick.bind(this,i),!1),t.addEventListener("show",this.onShow.bind(this,i),!1),t.addEventListener("close",()=>{this.deliveredNotifications=this.deliveredNotifications.filter(()=>!this)},!1),this.deliveredNotifications.push(t),t}onClick(i){const t={actionId:"tap",notification:i};this.notifyListeners("localNotificationActionPerformed",t)}onShow(i){this.notifyListeners("localNotificationReceived",i)}}export{f as LocalNotificationsWeb};
1
+ import{W as s}from"./main-B3ggaJoY.js";import"./modulepreload-polyfill-B5Qt9EMX.js";import"./vendor-react-uS-d4TUT.js";import"./vendor-three-DJ4p3FLF.js";class f extends s{constructor(){super(...arguments),this.pending=[],this.deliveredNotifications=[],this.hasNotificationSupport=()=>{if(!("Notification"in window)||!Notification.requestPermission)return!1;if(Notification.permission!=="granted")try{new Notification("")}catch(i){if(i instanceof Error&&i.name==="TypeError")return!1}return!0}}async getDeliveredNotifications(){const i=[];for(const t of this.deliveredNotifications){const e={title:t.title,id:parseInt(t.tag),body:t.body};i.push(e)}return{notifications:i}}async removeDeliveredNotifications(i){for(const t of i.notifications){const e=this.deliveredNotifications.find(n=>n.tag===String(t.id));e==null||e.close(),this.deliveredNotifications=this.deliveredNotifications.filter(()=>!e)}}async removeAllDeliveredNotifications(){for(const i of this.deliveredNotifications)i.close();this.deliveredNotifications=[]}async createChannel(){throw this.unimplemented("Not implemented on web.")}async deleteChannel(){throw this.unimplemented("Not implemented on web.")}async listChannels(){throw this.unimplemented("Not implemented on web.")}async schedule(i){if(!this.hasNotificationSupport())throw this.unavailable("Notifications not supported in this browser.");for(const t of i.notifications)this.sendNotification(t);return{notifications:i.notifications.map(t=>({id:t.id}))}}async getPending(){return{notifications:this.pending}}async registerActionTypes(){throw this.unimplemented("Not implemented on web.")}async cancel(i){this.pending=this.pending.filter(t=>!i.notifications.find(e=>e.id===t.id))}async areEnabled(){const{display:i}=await this.checkPermissions();return{value:i==="granted"}}async changeExactNotificationSetting(){throw this.unimplemented("Not implemented on web.")}async checkExactNotificationSetting(){throw this.unimplemented("Not implemented on web.")}async requestPermissions(){if(!this.hasNotificationSupport())throw this.unavailable("Notifications not supported in this browser.");return{display:this.transformNotificationPermission(await Notification.requestPermission())}}async checkPermissions(){if(!this.hasNotificationSupport())throw this.unavailable("Notifications not supported in this browser.");return{display:this.transformNotificationPermission(Notification.permission)}}transformNotificationPermission(i){switch(i){case"granted":return"granted";case"denied":return"denied";default:return"prompt"}}sendPending(){var i;const t=[],e=new Date().getTime();for(const n of this.pending)!((i=n.schedule)===null||i===void 0)&&i.at&&n.schedule.at.getTime()<=e&&(this.buildNotification(n),t.push(n));this.pending=this.pending.filter(n=>!t.find(o=>o===n))}sendNotification(i){var t;if(!((t=i.schedule)===null||t===void 0)&&t.at){const e=i.schedule.at.getTime()-new Date().getTime();this.pending.push(i),setTimeout(()=>{this.sendPending()},e);return}this.buildNotification(i)}buildNotification(i){const t=new Notification(i.title,{body:i.body,tag:String(i.id)});return t.addEventListener("click",this.onClick.bind(this,i),!1),t.addEventListener("show",this.onShow.bind(this,i),!1),t.addEventListener("close",()=>{this.deliveredNotifications=this.deliveredNotifications.filter(()=>!this)},!1),this.deliveredNotifications.push(t),t}onClick(i){const t={actionId:"tap",notification:i};this.notifyListeners("localNotificationActionPerformed",t)}onShow(i){this.notifyListeners("localNotificationReceived",i)}}export{f as LocalNotificationsWeb};
package/dist/index.html CHANGED
@@ -22,11 +22,11 @@
22
22
  <link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16x16.png" />
23
23
  <link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png" />
24
24
  <title>Tide Commander</title>
25
- <script type="module" crossorigin src="/assets/main-VR06Nfll.js"></script>
25
+ <script type="module" crossorigin src="/assets/main-B3ggaJoY.js"></script>
26
26
  <link rel="modulepreload" crossorigin href="/assets/modulepreload-polyfill-B5Qt9EMX.js">
27
27
  <link rel="modulepreload" crossorigin href="/assets/vendor-react-uS-d4TUT.js">
28
28
  <link rel="modulepreload" crossorigin href="/assets/vendor-three-DJ4p3FLF.js">
29
- <link rel="stylesheet" crossorigin href="/assets/main-DrUT6gJW.css">
29
+ <link rel="stylesheet" crossorigin href="/assets/main-D893RHwB.css">
30
30
  </head>
31
31
  <body>
32
32
  <div id="app"></div>
@@ -13,6 +13,7 @@ import { streamingExec } from './streaming-exec.js';
13
13
  import { bitbucketPR } from './bitbucket-pr.js';
14
14
  import { pm2Logs } from './pm2-logs.js';
15
15
  import { createBuilding } from './create-building.js';
16
+ import { releasePipeline } from './release-pipeline.js';
16
17
  /**
17
18
  * All built-in skills that ship with Tide Commander
18
19
  */
@@ -25,6 +26,7 @@ export const BUILTIN_SKILLS = [
25
26
  bitbucketPR,
26
27
  pm2Logs,
27
28
  createBuilding,
29
+ releasePipeline,
28
30
  ];
29
31
  /**
30
32
  * Get the ID for a built-in skill based on its slug
@@ -0,0 +1,319 @@
1
+ export const releasePipeline = {
2
+ slug: 'release-pipeline',
3
+ name: 'TC Release Pipeline',
4
+ description: 'Full release workflow: lint, type-check, test, build, APK, version bump, changelog, git tag, GitHub release. Use when asked to release, publish, ship, or do a full build pipeline.',
5
+ allowedTools: [
6
+ 'Bash(git:*)',
7
+ 'Bash(npm:*)',
8
+ 'Bash(make:*)',
9
+ 'Bash(gh:*)',
10
+ 'Bash(curl:*)',
11
+ 'Bash(npx:*)',
12
+ 'Read',
13
+ 'Edit',
14
+ 'Grep',
15
+ 'Glob',
16
+ ],
17
+ content: `# Release Pipeline
18
+
19
+ Full release workflow for Tide Commander. Runs quality checks, builds web app + debug APK, bumps the version, updates the changelog, tags, pushes, creates a GitHub release with the APK attached.
20
+
21
+ ## Core Principles
22
+
23
+ 1. **Fail fast** - If any quality gate fails, STOP and report to the user. Do NOT attempt to fix issues automatically.
24
+ 2. **Never force push** to shared branches (main, master, develop)
25
+ 3. **Never auto-resolve conflicts** - report them to the user
26
+ 4. **Always verify** the current branch before any operation
27
+ 5. **NEVER add Co-Authored-By trailers** to commits
28
+
29
+ ---
30
+
31
+ ## Full Release Workflow
32
+
33
+ When asked to "release", "ship", "publish", "do a full release", or similar:
34
+
35
+ ### Phase 1: Pre-Flight Checks
36
+
37
+ \`\`\`bash
38
+ # Verify branch and clean state
39
+ git status
40
+ git branch --show-current
41
+ \`\`\`
42
+
43
+ - If there are uncommitted changes, list them and ask the user if they should be included.
44
+ - If not on the expected branch (usually \`master\`), warn the user.
45
+
46
+ \`\`\`bash
47
+ # Pull latest to avoid conflicts
48
+ git pull --rebase origin $(git branch --show-current)
49
+ \`\`\`
50
+
51
+ **If conflicts occur:** STOP immediately and report to user. Do NOT auto-resolve.
52
+
53
+ ---
54
+
55
+ ### Phase 2: Quality Gates (ALL must pass)
56
+
57
+ Run each gate sequentially. If ANY gate fails, STOP and report the failure to the user. Do NOT try to fix issues.
58
+
59
+ Use the Streaming Exec API for all long-running commands so the user can see live output:
60
+
61
+ \`\`\`bash
62
+ curl -s -X POST http://localhost:5174/api/exec \\
63
+ -H "Content-Type: application/json" \\
64
+ -d '{"agentId":"YOUR_AGENT_ID","command":"COMMAND"}'
65
+ \`\`\`
66
+
67
+ #### Gate 1: ESLint (zero warnings)
68
+
69
+ \`\`\`bash
70
+ curl -s -X POST http://localhost:5174/api/exec \\
71
+ -H "Content-Type: application/json" \\
72
+ -d '{"agentId":"YOUR_AGENT_ID","command":"npm run lint"}'
73
+ \`\`\`
74
+
75
+ Check the output. If there are **any warnings or errors**, STOP and report them to the user.
76
+
77
+ #### Gate 2: TypeScript Type Check (zero errors)
78
+
79
+ \`\`\`bash
80
+ curl -s -X POST http://localhost:5174/api/exec \\
81
+ -H "Content-Type: application/json" \\
82
+ -d '{"agentId":"YOUR_AGENT_ID","command":"npm run lint:types"}'
83
+ \`\`\`
84
+
85
+ If there are type errors, STOP and report them.
86
+
87
+ #### Gate 3: Tests (all passing)
88
+
89
+ \`\`\`bash
90
+ curl -s -X POST http://localhost:5174/api/exec \\
91
+ -H "Content-Type: application/json" \\
92
+ -d '{"agentId":"YOUR_AGENT_ID","command":"npm test"}'
93
+ \`\`\`
94
+
95
+ If any tests fail, STOP and report them.
96
+
97
+ ---
98
+
99
+ ### Phase 3: Build
100
+
101
+ #### Build Web App
102
+
103
+ \`\`\`bash
104
+ curl -s -X POST http://localhost:5174/api/exec \\
105
+ -H "Content-Type: application/json" \\
106
+ -d '{"agentId":"YOUR_AGENT_ID","command":"npm run build"}'
107
+ \`\`\`
108
+
109
+ If the build fails, STOP and report the error.
110
+
111
+ #### Build Android Debug APK
112
+
113
+ After the web build succeeds, always build the debug APK. This runs \`npx cap sync android\` + \`gradlew assembleDebug\`:
114
+
115
+ \`\`\`bash
116
+ curl -s -X POST http://localhost:5174/api/exec \\
117
+ -H "Content-Type: application/json" \\
118
+ -d '{"agentId":"YOUR_AGENT_ID","command":"make apk"}'
119
+ \`\`\`
120
+
121
+ Output APK location: \`android/app/build/outputs/apk/debug/app-debug.apk\`
122
+
123
+ If the APK build fails, STOP and report the error.
124
+
125
+ ---
126
+
127
+ ### Phase 4: Version Bump
128
+
129
+ #### Determine Version Type
130
+
131
+ Read the current version:
132
+ \`\`\`bash
133
+ npm pkg get version
134
+ \`\`\`
135
+
136
+ Analyze the commits since the last tag and **decide the version bump yourself** based on conventional commit prefixes. Do NOT ask the user which type to use.
137
+
138
+ Rules for automatic selection:
139
+ - **patch** (0.0.X): Only \`fix:\`, \`perf:\`, \`refactor:\`, \`chore:\`, \`docs:\`, \`style:\`, \`test:\` commits - no new user-facing features
140
+ - **minor** (0.X.0): At least one \`feat:\` or \`add:\` commit, or new files/modules/skills added - no breaking changes
141
+ - **major** (X.0.0): Commits containing \`BREAKING CHANGE\` in the body, or \`feat!:\` / \`fix!:\` prefix indicating breaking API/behavior changes
142
+
143
+ #### Bump the Version
144
+
145
+ \`\`\`bash
146
+ npm version <patch|minor|major> --no-git-tag-version
147
+ \`\`\`
148
+
149
+ ---
150
+
151
+ ### Phase 5: Update Changelog
152
+
153
+ Read recent commits since the last tag:
154
+
155
+ \`\`\`bash
156
+ git log --oneline $(git describe --tags --abbrev=0 2>/dev/null || echo "HEAD~20")..HEAD
157
+ \`\`\`
158
+
159
+ Update \`CHANGELOG.md\` with the new version entry at the top (below the header). Use the Keep a Changelog format:
160
+
161
+ \`\`\`markdown
162
+ ## [X.Y.Z] - YYYY-MM-DD
163
+
164
+ ### Added
165
+ - New features (from \`feat:\` or \`add:\` commits)
166
+
167
+ ### Changed
168
+ - Changes to existing functionality (from \`change:\`, \`update:\`, \`refactor:\`, \`perf:\` commits)
169
+
170
+ ### Fixed
171
+ - Bug fixes (from \`fix:\` or \`bugfix:\` commits)
172
+
173
+ ### Removed
174
+ - Removed features (from \`remove:\` or \`delete:\` commits)
175
+ \`\`\`
176
+
177
+ Only include sections that have entries. Write concise, user-facing descriptions.
178
+
179
+ ---
180
+
181
+ ### Phase 6: Commit, Tag, Push
182
+
183
+ #### Stage and Commit
184
+
185
+ \`\`\`bash
186
+ git add package.json package-lock.json CHANGELOG.md
187
+ git add -A # include any other changed files
188
+
189
+ git diff --cached --stat # show what will be committed
190
+ \`\`\`
191
+
192
+ Show the staged changes summary to the user before committing.
193
+
194
+ \`\`\`bash
195
+ git commit -m "chore(release): v<VERSION>
196
+
197
+ - Summary of main changes
198
+ - Another change"
199
+ \`\`\`
200
+
201
+ #### Create Annotated Tag
202
+
203
+ \`\`\`bash
204
+ git tag -a v<VERSION> -m "Release v<VERSION>
205
+
206
+ Highlights:
207
+ - Main feature or fix
208
+ - Another highlight"
209
+ \`\`\`
210
+
211
+ #### Push to Remote
212
+
213
+ \`\`\`bash
214
+ git push origin $(git branch --show-current)
215
+ git push origin v<VERSION>
216
+ \`\`\`
217
+
218
+ ---
219
+
220
+ ### Phase 7: GitHub Release
221
+
222
+ Create the GitHub release using the \`gh\` CLI:
223
+
224
+ \`\`\`bash
225
+ gh release create v<VERSION> --title "v<VERSION>" --notes "<RELEASE_NOTES>"
226
+ \`\`\`
227
+
228
+ **Release notes format:**
229
+ \`\`\`markdown
230
+ ## What's New
231
+
232
+ ### Added
233
+ - Feature descriptions
234
+
235
+ ### Changed
236
+ - Changes and improvements
237
+
238
+ ### Fixed
239
+ - Bug fixes
240
+
241
+ ## Technical Details
242
+ - Implementation notes
243
+ - Architecture changes
244
+ \`\`\`
245
+
246
+ #### Attach Debug APK to Release
247
+
248
+ Attach the debug APK to the GitHub release:
249
+
250
+ \`\`\`bash
251
+ gh release upload v<VERSION> android/app/build/outputs/apk/debug/app-debug.apk --clobber
252
+ \`\`\`
253
+
254
+ ---
255
+
256
+ ## Partial Workflows
257
+
258
+ The skill also supports running individual phases:
259
+
260
+ ### Quality Check Only
261
+
262
+ When asked to "check quality", "run checks", "lint and test", or "pre-release check":
263
+
264
+ Run Phase 2 only (lint, type-check, tests). Report results without proceeding further.
265
+
266
+ ### Build Only
267
+
268
+ When asked to "build", "build everything", or "build apk":
269
+
270
+ Run Phase 3 only. Skip version bump and release.
271
+
272
+ ### Tag and Release Only
273
+
274
+ When asked to "tag", "create release", or "push release" (when version is already bumped):
275
+
276
+ Skip Phases 2-4, run Phases 5-7 only.
277
+
278
+ ---
279
+
280
+ ## Failure Handling
281
+
282
+ - **Lint warnings/errors**: STOP, report the lint output, do NOT auto-fix
283
+ - **Type errors**: STOP, report the errors, do NOT auto-fix
284
+ - **Test failures**: STOP, report failing tests, do NOT auto-fix
285
+ - **Build failure**: STOP, report the build error
286
+ - **APK build failure**: STOP, report the error (often SDK/Gradle issues)
287
+ - **Git conflicts**: STOP, list conflicting files, ask user to resolve manually
288
+ - **Push rejected**: STOP, report the rejection reason (likely needs pull first)
289
+
290
+ **Critical rule**: When any step fails, do NOT proceed to subsequent steps. Report the failure clearly and wait for user instructions.
291
+
292
+ ---
293
+
294
+ ## Quick Reference
295
+
296
+ | Phase | Command | Gate |
297
+ |-------|---------|------|
298
+ | Lint | \`npm run lint\` | Zero warnings |
299
+ | Types | \`npm run lint:types\` | Zero errors |
300
+ | Tests | \`npm test\` | All passing |
301
+ | Build | \`npm run build\` | Exit code 0 |
302
+ | APK Debug | \`make apk\` | Exit code 0 |
303
+ | Version | \`npm version <type> --no-git-tag-version\` | - |
304
+ | Tag | \`git tag -a v<VER> -m "..."\` | - |
305
+ | Push | \`git push origin <branch> && git push origin v<VER>\` | - |
306
+ | GH Release | \`gh release create v<VER> --notes "..."\` | - |
307
+ | Attach APK | \`gh release upload v<VER> <apk-path> --clobber\` | - |
308
+
309
+ ---
310
+
311
+ ## Version Guidelines
312
+
313
+ - **0.x.x** - Pre-release, API may change
314
+ - **1.0.0** - First stable release
315
+ - **x.Y.0** - New features (backwards compatible)
316
+ - **x.x.Z** - Bug fixes only
317
+
318
+ Always decide the version type automatically based on the commit history. Only ask the user if the commits are genuinely ambiguous (e.g., a mix of features and potential breaking changes).`,
319
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tide-commander",
3
- "version": "0.77.0",
3
+ "version": "0.78.1",
4
4
  "description": "Visual multi-agent orchestrator and manager for Claude Code with 3D/2D interface",
5
5
  "repository": {
6
6
  "type": "git",