tide-commander 0.78.1 → 0.80.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 +5 -0
- package/dist/assets/{main-B3ggaJoY.js → main-DLhL06nK.js} +94 -93
- package/dist/assets/main-DsPovOaA.css +1 -0
- package/dist/assets/{web-Cjmp1lCs.js → web-GvAkFt2u.js} +1 -1
- package/dist/index.html +2 -2
- package/dist/src/packages/server/claude/runner/stdout-pipeline.js +32 -1
- package/dist/src/packages/server/data/builtin-skills/release-pipeline.js +43 -6
- package/package.json +1 -1
- package/dist/assets/main-D893RHwB.css +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{W as s}from"./main-
|
|
1
|
+
import{W as s}from"./main-DLhL06nK.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-DLhL06nK.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-DsPovOaA.css">
|
|
30
30
|
</head>
|
|
31
31
|
<body>
|
|
32
32
|
<div id="app"></div>
|
|
@@ -129,13 +129,20 @@ export class RunnerStdoutPipeline {
|
|
|
129
129
|
break;
|
|
130
130
|
}
|
|
131
131
|
case 'step_complete': {
|
|
132
|
-
|
|
132
|
+
const hasErrorResultText = this.isLikelyErrorResultText(event.resultText);
|
|
133
|
+
if (event.resultText && (!this.textEmittedInTurn.has(agentId) || hasErrorResultText)) {
|
|
133
134
|
log.log(`[step_complete] Emitting resultText as fallback (no prior text events) for agent ${agentId.slice(0, 4)}`);
|
|
134
135
|
this.callbacks.onOutput(agentId, event.resultText, false, undefined, event.uuid);
|
|
135
136
|
}
|
|
136
137
|
else if (event.resultText) {
|
|
137
138
|
log.log(`[step_complete] Skipping resultText (already emitted via text events) for agent ${agentId.slice(0, 4)}`);
|
|
138
139
|
}
|
|
140
|
+
if (event.permissionDenials && event.permissionDenials.length > 0) {
|
|
141
|
+
for (const denial of event.permissionDenials) {
|
|
142
|
+
const denialSummary = this.formatPermissionDenialSummary(denial.toolName, denial.toolInput);
|
|
143
|
+
this.callbacks.onOutput(agentId, `[System] Permission denied: ${denialSummary}`, false, undefined, event.uuid);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
139
146
|
this.textEmittedInTurn.delete(agentId);
|
|
140
147
|
if (event.tokens) {
|
|
141
148
|
this.callbacks.onOutput(agentId, `Tokens: ${event.tokens.input} in, ${event.tokens.output} out`, false, undefined, event.uuid);
|
|
@@ -160,4 +167,28 @@ export class RunnerStdoutPipeline {
|
|
|
160
167
|
break;
|
|
161
168
|
}
|
|
162
169
|
}
|
|
170
|
+
isLikelyErrorResultText(resultText) {
|
|
171
|
+
if (!resultText)
|
|
172
|
+
return false;
|
|
173
|
+
const lower = resultText.toLowerCase();
|
|
174
|
+
return (lower.includes('api error') ||
|
|
175
|
+
lower.includes('internal server error') ||
|
|
176
|
+
lower.includes('permission denied') ||
|
|
177
|
+
lower.includes('tool denied') ||
|
|
178
|
+
lower.includes('error'));
|
|
179
|
+
}
|
|
180
|
+
formatPermissionDenialSummary(toolName, input) {
|
|
181
|
+
const details = input && typeof input === 'object' ? this.summarizeToolInput(input) : '';
|
|
182
|
+
return details ? `${toolName} (${details})` : toolName;
|
|
183
|
+
}
|
|
184
|
+
summarizeToolInput(input) {
|
|
185
|
+
const summaryKeys = ['command', 'file_path', 'path', 'pattern', 'url', 'query', 'description'];
|
|
186
|
+
for (const key of summaryKeys) {
|
|
187
|
+
const value = input[key];
|
|
188
|
+
if (typeof value === 'string' && value.trim().length > 0) {
|
|
189
|
+
return value.length > 120 ? `${value.slice(0, 117)}...` : value;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return '';
|
|
193
|
+
}
|
|
163
194
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export const releasePipeline = {
|
|
2
2
|
slug: 'release-pipeline',
|
|
3
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.',
|
|
4
|
+
description: 'Full release workflow: lint, type-check, test, build, APK artifacts, version bump, changelog, git tag, GitHub release, npm public publish. Use when asked to release, publish, ship, or do a full build pipeline.',
|
|
5
5
|
allowedTools: [
|
|
6
6
|
'Bash(git:*)',
|
|
7
7
|
'Bash(npm:*)',
|
|
@@ -16,7 +16,7 @@ export const releasePipeline = {
|
|
|
16
16
|
],
|
|
17
17
|
content: `# Release Pipeline
|
|
18
18
|
|
|
19
|
-
Full release workflow for Tide Commander. Runs quality checks, builds web app +
|
|
19
|
+
Full release workflow for Tide Commander. Runs quality checks, builds web app + APK artifacts, bumps the version, updates the changelog, tags, pushes, creates a GitHub release with APKs attached, and publishes publicly to npm.
|
|
20
20
|
|
|
21
21
|
## Core Principles
|
|
22
22
|
|
|
@@ -122,6 +122,20 @@ Output APK location: \`android/app/build/outputs/apk/debug/app-debug.apk\`
|
|
|
122
122
|
|
|
123
123
|
If the APK build fails, STOP and report the error.
|
|
124
124
|
|
|
125
|
+
#### Build Android Non-Dev Debug APK (signing-safe artifact)
|
|
126
|
+
|
|
127
|
+
Build a non-dev debug APK using bundled assets:
|
|
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-release-nondev"}'
|
|
133
|
+
\`\`\`
|
|
134
|
+
|
|
135
|
+
Output APK location: \`android/app/build/outputs/apk/debug/app-debug.apk\`
|
|
136
|
+
|
|
137
|
+
If the non-dev debug APK build fails, STOP and report the error.
|
|
138
|
+
|
|
125
139
|
---
|
|
126
140
|
|
|
127
141
|
### Phase 4: Version Bump
|
|
@@ -217,7 +231,7 @@ git push origin v<VERSION>
|
|
|
217
231
|
|
|
218
232
|
---
|
|
219
233
|
|
|
220
|
-
### Phase 7: GitHub
|
|
234
|
+
### Phase 7: Public Release (GitHub + npm)
|
|
221
235
|
|
|
222
236
|
Create the GitHub release using the \`gh\` CLI:
|
|
223
237
|
|
|
@@ -243,14 +257,33 @@ gh release create v<VERSION> --title "v<VERSION>" --notes "<RELEASE_NOTES>"
|
|
|
243
257
|
- Architecture changes
|
|
244
258
|
\`\`\`
|
|
245
259
|
|
|
246
|
-
#### Attach
|
|
260
|
+
#### Attach APK Artifacts to Release
|
|
247
261
|
|
|
248
|
-
Attach
|
|
262
|
+
Attach APK artifacts to the GitHub release:
|
|
249
263
|
|
|
250
264
|
\`\`\`bash
|
|
251
265
|
gh release upload v<VERSION> android/app/build/outputs/apk/debug/app-debug.apk --clobber
|
|
252
266
|
\`\`\`
|
|
253
267
|
|
|
268
|
+
#### Publish to npm (public)
|
|
269
|
+
|
|
270
|
+
Preferred path: pushing tag \`v<VERSION>\` triggers the trusted publish workflow in \`.github/workflows/publish.yml\`.
|
|
271
|
+
|
|
272
|
+
Verify publish workflow completion:
|
|
273
|
+
|
|
274
|
+
\`\`\`bash
|
|
275
|
+
gh run list --workflow publish.yml --limit 5
|
|
276
|
+
\`\`\`
|
|
277
|
+
|
|
278
|
+
If workflow is unavailable or user asks for manual publish, run:
|
|
279
|
+
|
|
280
|
+
\`\`\`bash
|
|
281
|
+
npm whoami
|
|
282
|
+
npm publish --provenance --access public
|
|
283
|
+
\`\`\`
|
|
284
|
+
|
|
285
|
+
If publish fails, STOP and report exact error (auth, 2FA, version exists, provenance, etc).
|
|
286
|
+
|
|
254
287
|
---
|
|
255
288
|
|
|
256
289
|
## Partial Workflows
|
|
@@ -284,6 +317,8 @@ Skip Phases 2-4, run Phases 5-7 only.
|
|
|
284
317
|
- **Test failures**: STOP, report failing tests, do NOT auto-fix
|
|
285
318
|
- **Build failure**: STOP, report the build error
|
|
286
319
|
- **APK build failure**: STOP, report the error (often SDK/Gradle issues)
|
|
320
|
+
- **GitHub release failure**: STOP, report the \`gh\` error and current release/tag state
|
|
321
|
+
- **npm publish failure**: STOP, report exact publish error (auth, 2FA, version exists, provenance)
|
|
287
322
|
- **Git conflicts**: STOP, list conflicting files, ask user to resolve manually
|
|
288
323
|
- **Push rejected**: STOP, report the rejection reason (likely needs pull first)
|
|
289
324
|
|
|
@@ -300,11 +335,13 @@ Skip Phases 2-4, run Phases 5-7 only.
|
|
|
300
335
|
| Tests | \`npm test\` | All passing |
|
|
301
336
|
| Build | \`npm run build\` | Exit code 0 |
|
|
302
337
|
| APK Debug | \`make apk\` | Exit code 0 |
|
|
338
|
+
| APK Non-Dev Debug | \`make apk-release-nondev\` | Exit code 0 |
|
|
303
339
|
| Version | \`npm version <type> --no-git-tag-version\` | - |
|
|
304
340
|
| Tag | \`git tag -a v<VER> -m "..."\` | - |
|
|
305
341
|
| Push | \`git push origin <branch> && git push origin v<VER>\` | - |
|
|
306
342
|
| GH Release | \`gh release create v<VER> --notes "..."\` | - |
|
|
307
|
-
| Attach
|
|
343
|
+
| Attach APKs | \`gh release upload v<VER> <apk-path> --clobber\` | - |
|
|
344
|
+
| npm Publish | \`npm publish --provenance --access public\` | Exit code 0 |
|
|
308
345
|
|
|
309
346
|
---
|
|
310
347
|
|