tide-commander 0.77.0 → 0.78.0
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.
- package/README.md +8 -0
- package/dist/assets/{main-VR06Nfll.js → main-CNF5ilVy.js} +54 -54
- package/dist/assets/main-D893RHwB.css +1 -0
- package/dist/assets/{web-G5mRoUDp.js → web-OIx7WerG.js} +1 -1
- package/dist/index.html +2 -2
- package/dist/src/packages/server/data/builtin-skills/index.js +2 -0
- package/dist/src/packages/server/data/builtin-skills/release-pipeline.js +341 -0
- package/package.json +1 -1
- package/dist/assets/main-DrUT6gJW.css +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{W as s}from"./main-
|
|
1
|
+
import{W as s}from"./main-CNF5ilVy.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-
|
|
25
|
+
<script type="module" crossorigin src="/assets/main-CNF5ilVy.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-
|
|
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,341 @@
|
|
|
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 everything, bumps the version, updates the changelog, tags, pushes, creates a GitHub release, and optionally attaches the APK.
|
|
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 APK (optional - ask user)
|
|
112
|
+
|
|
113
|
+
Ask the user: "Do you want to build the Android APK as part of this release?"
|
|
114
|
+
|
|
115
|
+
If yes, build the **release** APK:
|
|
116
|
+
|
|
117
|
+
\`\`\`bash
|
|
118
|
+
curl -s -X POST http://localhost:5174/api/exec \\
|
|
119
|
+
-H "Content-Type: application/json" \\
|
|
120
|
+
-d '{"agentId":"YOUR_AGENT_ID","command":"make apk-release"}'
|
|
121
|
+
\`\`\`
|
|
122
|
+
|
|
123
|
+
This runs: \`npm run build\` + \`npx cap sync\` + \`gradlew assembleRelease\`
|
|
124
|
+
|
|
125
|
+
Output APK location: \`android/app/build/outputs/apk/release/app-release-unsigned.apk\`
|
|
126
|
+
|
|
127
|
+
For a **debug** APK instead:
|
|
128
|
+
|
|
129
|
+
\`\`\`bash
|
|
130
|
+
curl -s -X POST http://localhost:5174/api/exec \\
|
|
131
|
+
-H "Content-Type: application/json" \\
|
|
132
|
+
-d '{"agentId":"YOUR_AGENT_ID","command":"make apk"}'
|
|
133
|
+
\`\`\`
|
|
134
|
+
|
|
135
|
+
Output: \`android/app/build/outputs/apk/debug/app-debug.apk\`
|
|
136
|
+
|
|
137
|
+
If the APK build fails, STOP and report the error.
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
### Phase 4: Version Bump
|
|
142
|
+
|
|
143
|
+
#### Determine Version Type
|
|
144
|
+
|
|
145
|
+
Read the current version:
|
|
146
|
+
\`\`\`bash
|
|
147
|
+
npm pkg get version
|
|
148
|
+
\`\`\`
|
|
149
|
+
|
|
150
|
+
Ask the user or infer from changes:
|
|
151
|
+
- **patch** (0.0.X): Bug fixes, small changes, performance tweaks
|
|
152
|
+
- **minor** (0.X.0): New features, non-breaking changes
|
|
153
|
+
- **major** (X.0.0): Breaking changes, major rewrites
|
|
154
|
+
|
|
155
|
+
#### Bump the Version
|
|
156
|
+
|
|
157
|
+
\`\`\`bash
|
|
158
|
+
npm version <patch|minor|major> --no-git-tag-version
|
|
159
|
+
\`\`\`
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
### Phase 5: Update Changelog
|
|
164
|
+
|
|
165
|
+
Read recent commits since the last tag:
|
|
166
|
+
|
|
167
|
+
\`\`\`bash
|
|
168
|
+
git log --oneline $(git describe --tags --abbrev=0 2>/dev/null || echo "HEAD~20")..HEAD
|
|
169
|
+
\`\`\`
|
|
170
|
+
|
|
171
|
+
Update \`CHANGELOG.md\` with the new version entry at the top (below the header). Use the Keep a Changelog format:
|
|
172
|
+
|
|
173
|
+
\`\`\`markdown
|
|
174
|
+
## [X.Y.Z] - YYYY-MM-DD
|
|
175
|
+
|
|
176
|
+
### Added
|
|
177
|
+
- New features (from \`feat:\` or \`add:\` commits)
|
|
178
|
+
|
|
179
|
+
### Changed
|
|
180
|
+
- Changes to existing functionality (from \`change:\`, \`update:\`, \`refactor:\`, \`perf:\` commits)
|
|
181
|
+
|
|
182
|
+
### Fixed
|
|
183
|
+
- Bug fixes (from \`fix:\` or \`bugfix:\` commits)
|
|
184
|
+
|
|
185
|
+
### Removed
|
|
186
|
+
- Removed features (from \`remove:\` or \`delete:\` commits)
|
|
187
|
+
\`\`\`
|
|
188
|
+
|
|
189
|
+
Only include sections that have entries. Write concise, user-facing descriptions.
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
### Phase 6: Commit, Tag, Push
|
|
194
|
+
|
|
195
|
+
#### Stage and Commit
|
|
196
|
+
|
|
197
|
+
\`\`\`bash
|
|
198
|
+
git add package.json package-lock.json CHANGELOG.md
|
|
199
|
+
git add -A # include any other changed files
|
|
200
|
+
|
|
201
|
+
git diff --cached --stat # show what will be committed
|
|
202
|
+
\`\`\`
|
|
203
|
+
|
|
204
|
+
Show the staged changes summary to the user before committing.
|
|
205
|
+
|
|
206
|
+
\`\`\`bash
|
|
207
|
+
git commit -m "chore(release): v<VERSION>
|
|
208
|
+
|
|
209
|
+
- Summary of main changes
|
|
210
|
+
- Another change"
|
|
211
|
+
\`\`\`
|
|
212
|
+
|
|
213
|
+
#### Create Annotated Tag
|
|
214
|
+
|
|
215
|
+
\`\`\`bash
|
|
216
|
+
git tag -a v<VERSION> -m "Release v<VERSION>
|
|
217
|
+
|
|
218
|
+
Highlights:
|
|
219
|
+
- Main feature or fix
|
|
220
|
+
- Another highlight"
|
|
221
|
+
\`\`\`
|
|
222
|
+
|
|
223
|
+
#### Push to Remote
|
|
224
|
+
|
|
225
|
+
\`\`\`bash
|
|
226
|
+
git push origin $(git branch --show-current)
|
|
227
|
+
git push origin v<VERSION>
|
|
228
|
+
\`\`\`
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
### Phase 7: GitHub Release
|
|
233
|
+
|
|
234
|
+
Create the GitHub release using the \`gh\` CLI:
|
|
235
|
+
|
|
236
|
+
\`\`\`bash
|
|
237
|
+
gh release create v<VERSION> --title "v<VERSION>" --notes "<RELEASE_NOTES>"
|
|
238
|
+
\`\`\`
|
|
239
|
+
|
|
240
|
+
**Release notes format:**
|
|
241
|
+
\`\`\`markdown
|
|
242
|
+
## What's New
|
|
243
|
+
|
|
244
|
+
### Added
|
|
245
|
+
- Feature descriptions
|
|
246
|
+
|
|
247
|
+
### Changed
|
|
248
|
+
- Changes and improvements
|
|
249
|
+
|
|
250
|
+
### Fixed
|
|
251
|
+
- Bug fixes
|
|
252
|
+
|
|
253
|
+
## Technical Details
|
|
254
|
+
- Implementation notes
|
|
255
|
+
- Architecture changes
|
|
256
|
+
\`\`\`
|
|
257
|
+
|
|
258
|
+
#### Attach APK to Release (if built)
|
|
259
|
+
|
|
260
|
+
If an APK was built, attach it to the GitHub release:
|
|
261
|
+
|
|
262
|
+
\`\`\`bash
|
|
263
|
+
gh release upload v<VERSION> android/app/build/outputs/apk/release/app-release-unsigned.apk --clobber
|
|
264
|
+
\`\`\`
|
|
265
|
+
|
|
266
|
+
Or for debug APK:
|
|
267
|
+
\`\`\`bash
|
|
268
|
+
gh release upload v<VERSION> android/app/build/outputs/apk/debug/app-debug.apk --clobber
|
|
269
|
+
\`\`\`
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## Partial Workflows
|
|
274
|
+
|
|
275
|
+
The skill also supports running individual phases:
|
|
276
|
+
|
|
277
|
+
### Quality Check Only
|
|
278
|
+
|
|
279
|
+
When asked to "check quality", "run checks", "lint and test", or "pre-release check":
|
|
280
|
+
|
|
281
|
+
Run Phase 2 only (lint, type-check, tests). Report results without proceeding further.
|
|
282
|
+
|
|
283
|
+
### Build Only
|
|
284
|
+
|
|
285
|
+
When asked to "build", "build everything", or "build apk":
|
|
286
|
+
|
|
287
|
+
Run Phase 3 only. Skip version bump and release.
|
|
288
|
+
|
|
289
|
+
### Tag and Release Only
|
|
290
|
+
|
|
291
|
+
When asked to "tag", "create release", or "push release" (when version is already bumped):
|
|
292
|
+
|
|
293
|
+
Skip Phases 2-4, run Phases 5-7 only.
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
297
|
+
## Failure Handling
|
|
298
|
+
|
|
299
|
+
- **Lint warnings/errors**: STOP, report the lint output, do NOT auto-fix
|
|
300
|
+
- **Type errors**: STOP, report the errors, do NOT auto-fix
|
|
301
|
+
- **Test failures**: STOP, report failing tests, do NOT auto-fix
|
|
302
|
+
- **Build failure**: STOP, report the build error
|
|
303
|
+
- **APK build failure**: STOP, report the error (often SDK/Gradle issues)
|
|
304
|
+
- **Git conflicts**: STOP, list conflicting files, ask user to resolve manually
|
|
305
|
+
- **Push rejected**: STOP, report the rejection reason (likely needs pull first)
|
|
306
|
+
|
|
307
|
+
**Critical rule**: When any step fails, do NOT proceed to subsequent steps. Report the failure clearly and wait for user instructions.
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
## Quick Reference
|
|
312
|
+
|
|
313
|
+
| Phase | Command | Gate |
|
|
314
|
+
|-------|---------|------|
|
|
315
|
+
| Lint | \`npm run lint\` | Zero warnings |
|
|
316
|
+
| Types | \`npm run lint:types\` | Zero errors |
|
|
317
|
+
| Tests | \`npm test\` | All passing |
|
|
318
|
+
| Build | \`npm run build\` | Exit code 0 |
|
|
319
|
+
| APK Debug | \`make apk\` | Exit code 0 |
|
|
320
|
+
| APK Release | \`make apk-release\` | Exit code 0 |
|
|
321
|
+
| Version | \`npm version <type> --no-git-tag-version\` | - |
|
|
322
|
+
| Tag | \`git tag -a v<VER> -m "..."\` | - |
|
|
323
|
+
| Push | \`git push origin <branch> && git push origin v<VER>\` | - |
|
|
324
|
+
| GH Release | \`gh release create v<VER> --notes "..."\` | - |
|
|
325
|
+
| Attach APK | \`gh release upload v<VER> <apk-path> --clobber\` | - |
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
## Version Guidelines
|
|
330
|
+
|
|
331
|
+
- **0.x.x** - Pre-release, API may change
|
|
332
|
+
- **1.0.0** - First stable release
|
|
333
|
+
- **x.Y.0** - New features (backwards compatible)
|
|
334
|
+
- **x.x.Z** - Bug fixes only
|
|
335
|
+
|
|
336
|
+
When unsure about version type, ask the user:
|
|
337
|
+
> "What type of release is this?
|
|
338
|
+
> - **patch** (bug fixes only)
|
|
339
|
+
> - **minor** (new features, no breaking changes)
|
|
340
|
+
> - **major** (breaking changes)"`,
|
|
341
|
+
};
|