tide-commander 0.53.0 → 0.53.3
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/dist/index.html
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
<meta name="apple-mobile-web-app-title" content="Tide CMD" />
|
|
20
20
|
<link rel="apple-touch-icon" href="/assets/icons/icon-192.png" />
|
|
21
21
|
<title>Tide Commander</title>
|
|
22
|
-
<script type="module" crossorigin src="/assets/main-
|
|
22
|
+
<script type="module" crossorigin src="/assets/main-CcEFu9h1.js"></script>
|
|
23
23
|
<link rel="modulepreload" crossorigin href="/assets/vendor-react-uS-d4TUT.js">
|
|
24
24
|
<link rel="modulepreload" crossorigin href="/assets/vendor-three-4iQNXcoo.js">
|
|
25
25
|
<link rel="stylesheet" crossorigin href="/assets/main-BIpLsrUu.css">
|
|
@@ -15,6 +15,7 @@ Usage:
|
|
|
15
15
|
tide-commander stop
|
|
16
16
|
tide-commander status
|
|
17
17
|
tide-commander logs [--lines <n>] [--follow]
|
|
18
|
+
tide-commander version
|
|
18
19
|
|
|
19
20
|
Options:
|
|
20
21
|
-p, --port <port> Set server port (default: 5174)
|
|
@@ -32,7 +33,7 @@ function parseArgs(argv) {
|
|
|
32
33
|
for (let i = 0; i < argv.length; i += 1) {
|
|
33
34
|
const arg = argv[i];
|
|
34
35
|
if (!arg.startsWith('-') && !commandParsed) {
|
|
35
|
-
if (arg === 'start' || arg === 'stop' || arg === 'status' || arg === 'logs') {
|
|
36
|
+
if (arg === 'start' || arg === 'stop' || arg === 'status' || arg === 'logs' || arg === 'version') {
|
|
36
37
|
options.command = arg;
|
|
37
38
|
commandParsed = true;
|
|
38
39
|
continue;
|
|
@@ -93,6 +94,10 @@ function parseArgs(argv) {
|
|
|
93
94
|
case '--help':
|
|
94
95
|
options.help = true;
|
|
95
96
|
break;
|
|
97
|
+
case '-v':
|
|
98
|
+
case '--version':
|
|
99
|
+
options.command = 'version';
|
|
100
|
+
break;
|
|
96
101
|
default:
|
|
97
102
|
throw new Error(`Unknown argument: ${arg}`);
|
|
98
103
|
}
|
|
@@ -155,17 +160,37 @@ function stopCommand() {
|
|
|
155
160
|
return 0;
|
|
156
161
|
}
|
|
157
162
|
function statusCommand() {
|
|
163
|
+
// ANSI color codes
|
|
164
|
+
const cyan = '\x1b[36m';
|
|
165
|
+
const green = '\x1b[32m';
|
|
166
|
+
const red = '\x1b[31m';
|
|
167
|
+
const bright = '\x1b[1m';
|
|
168
|
+
const reset = '\x1b[0m';
|
|
169
|
+
const blue = '\x1b[34m';
|
|
158
170
|
const pid = readPidFile();
|
|
159
171
|
if (!pid) {
|
|
160
|
-
console.log(
|
|
172
|
+
console.log(`\n${red}${bright}⨯ Tide Commander is stopped${reset}\n`);
|
|
161
173
|
return 1;
|
|
162
174
|
}
|
|
163
175
|
if (!isRunning(pid)) {
|
|
164
176
|
clearPidFile();
|
|
165
|
-
console.log(
|
|
177
|
+
console.log(`\n${red}${bright}⨯ Tide Commander is stopped${reset} (stale PID file removed)\n`);
|
|
166
178
|
return 1;
|
|
167
179
|
}
|
|
168
|
-
|
|
180
|
+
const port = process.env.PORT || '5174';
|
|
181
|
+
const host = process.env.HOST || 'localhost';
|
|
182
|
+
const url = `http://${host}:${port}`;
|
|
183
|
+
const uptime = getProcessUptime(pid);
|
|
184
|
+
const version = getPackageVersion();
|
|
185
|
+
console.log(`\n${cyan}${bright}🌊 Tide Commander Status${reset}`);
|
|
186
|
+
console.log(`${cyan}${'═'.repeat(60)}${reset}`);
|
|
187
|
+
console.log(`${green}✓ Running${reset} (PID: ${pid})`);
|
|
188
|
+
console.log(`${blue}${bright}🚀 Access: ${url}${reset}`);
|
|
189
|
+
console.log(` Version: ${version}`);
|
|
190
|
+
if (uptime) {
|
|
191
|
+
console.log(` Uptime: ${uptime}`);
|
|
192
|
+
}
|
|
193
|
+
console.log(`${cyan}${'═'.repeat(60)}${reset}\n`);
|
|
169
194
|
return 0;
|
|
170
195
|
}
|
|
171
196
|
async function logsCommand(options) {
|
|
@@ -190,12 +215,65 @@ async function logsCommand(options) {
|
|
|
190
215
|
});
|
|
191
216
|
});
|
|
192
217
|
}
|
|
218
|
+
function getPackageVersion() {
|
|
219
|
+
try {
|
|
220
|
+
const cliDir = path.dirname(fileURLToPath(import.meta.url));
|
|
221
|
+
const packagePath = path.join(cliDir, '..', '..', '..', '..', 'package.json');
|
|
222
|
+
const packageJson = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
|
|
223
|
+
return packageJson.version;
|
|
224
|
+
}
|
|
225
|
+
catch {
|
|
226
|
+
return 'unknown';
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
function getProcessUptime(pid) {
|
|
230
|
+
try {
|
|
231
|
+
// Try to get process start time from /proc/[pid]/stat (Linux)
|
|
232
|
+
if (fs.existsSync(`/proc/${pid}/stat`)) {
|
|
233
|
+
const stat = fs.readFileSync(`/proc/${pid}/stat`, 'utf8').split(' ');
|
|
234
|
+
const starttime = Number(stat[21]); // starttime in jiffies
|
|
235
|
+
const uptimeFile = fs.readFileSync('/proc/uptime', 'utf8').split(' ')[0];
|
|
236
|
+
const systemUptimeJiffies = Number(uptimeFile) * 100; // convert to jiffies (assuming 100 Hz)
|
|
237
|
+
const processUptimeJiffies = systemUptimeJiffies - starttime;
|
|
238
|
+
const processUptimeSeconds = Math.floor(processUptimeJiffies / 100);
|
|
239
|
+
const hours = Math.floor(processUptimeSeconds / 3600);
|
|
240
|
+
const minutes = Math.floor((processUptimeSeconds % 3600) / 60);
|
|
241
|
+
const seconds = processUptimeSeconds % 60;
|
|
242
|
+
if (hours > 0) {
|
|
243
|
+
return `${hours}h ${minutes}m ${seconds}s`;
|
|
244
|
+
}
|
|
245
|
+
else if (minutes > 0) {
|
|
246
|
+
return `${minutes}m ${seconds}s`;
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
return `${seconds}s`;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
catch {
|
|
254
|
+
// Uptime not available (not on Linux or /proc not available)
|
|
255
|
+
}
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
258
|
+
function versionCommand() {
|
|
259
|
+
try {
|
|
260
|
+
const version = getPackageVersion();
|
|
261
|
+
console.log(`Tide Commander v${version}`);
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
console.error('Failed to read version information');
|
|
265
|
+
}
|
|
266
|
+
}
|
|
193
267
|
async function main() {
|
|
194
268
|
const options = parseArgs(process.argv.slice(2));
|
|
195
269
|
if (options.help) {
|
|
196
270
|
printHelp();
|
|
197
271
|
return;
|
|
198
272
|
}
|
|
273
|
+
if (options.command === 'version') {
|
|
274
|
+
versionCommand();
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
199
277
|
if (options.command === 'stop') {
|
|
200
278
|
process.exit(stopCommand());
|
|
201
279
|
}
|
|
@@ -221,7 +299,11 @@ async function main() {
|
|
|
221
299
|
const runInForeground = options.foreground === true || process.env.TIDE_COMMANDER_FOREGROUND === '1';
|
|
222
300
|
const existingPid = readPidFile();
|
|
223
301
|
if (existingPid && isRunning(existingPid)) {
|
|
224
|
-
|
|
302
|
+
const port = process.env.PORT || '5174';
|
|
303
|
+
const host = process.env.HOST || 'localhost';
|
|
304
|
+
const url = `http://${host}:${port}`;
|
|
305
|
+
console.log(`\n🌊 Tide Commander is already running (PID: ${existingPid})`);
|
|
306
|
+
console.log(`🚀 Open: ${url}\n`);
|
|
225
307
|
return;
|
|
226
308
|
}
|
|
227
309
|
clearPidFile();
|
|
@@ -239,7 +321,22 @@ async function main() {
|
|
|
239
321
|
writePidFile(child.pid);
|
|
240
322
|
}
|
|
241
323
|
child.unref();
|
|
242
|
-
|
|
324
|
+
const port = process.env.PORT || '5174';
|
|
325
|
+
const host = process.env.HOST || 'localhost';
|
|
326
|
+
const url = `http://${host}:${port}`;
|
|
327
|
+
// ANSI color codes for beautiful output
|
|
328
|
+
const cyan = '\x1b[36m';
|
|
329
|
+
const green = '\x1b[32m';
|
|
330
|
+
const bright = '\x1b[1m';
|
|
331
|
+
const reset = '\x1b[0m';
|
|
332
|
+
const blue = '\x1b[34m';
|
|
333
|
+
console.log(`\n${cyan}${bright}🌊 Tide Commander${reset}`);
|
|
334
|
+
console.log(`${cyan}${'═'.repeat(60)}${reset}`);
|
|
335
|
+
console.log(`${green}✓${reset} Started in background (PID: ${child.pid ?? 'unknown'})`);
|
|
336
|
+
console.log(`${blue}${bright}🚀 Open: ${url}${reset}`);
|
|
337
|
+
console.log(` Version: ${getPackageVersion()}`);
|
|
338
|
+
console.log(`${green}📝 Logs${reset}: tail -f logs/server.log`);
|
|
339
|
+
console.log(`${cyan}${'═'.repeat(60)}${reset}\n`);
|
|
243
340
|
return;
|
|
244
341
|
}
|
|
245
342
|
if (child.pid) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tide-commander",
|
|
3
|
-
"version": "0.53.
|
|
3
|
+
"version": "0.53.3",
|
|
4
4
|
"description": "Visual multi-agent orchestrator and manager for Claude Code with 3D/2D interface",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -27,20 +27,10 @@
|
|
|
27
27
|
"test:ci": "vitest run --exclude src/packages/client/hooks/__tests__/useSnapshots.test.ts --exclude src/packages/client/hooks/__tests__/useKeyboardShortcuts.test.ts",
|
|
28
28
|
"test:watch": "vitest",
|
|
29
29
|
"test:coverage": "vitest run --coverage",
|
|
30
|
-
"prepack": "npm run build"
|
|
31
|
-
"cap:sync": "npx cap sync android",
|
|
32
|
-
"cap:open": "npx cap open android",
|
|
33
|
-
"cap:build": "npm run build && npx cap sync android",
|
|
34
|
-
"android": "npm run build && npx cap sync android && npx cap open android"
|
|
30
|
+
"prepack": "npm run build"
|
|
35
31
|
},
|
|
36
32
|
"dependencies": {
|
|
37
33
|
"@anthropic-ai/sdk": "^0.71.2",
|
|
38
|
-
"@capacitor/android": "^8.0.1",
|
|
39
|
-
"@capacitor/cli": "^8.0.1",
|
|
40
|
-
"@capacitor/core": "^8.0.1",
|
|
41
|
-
"@capacitor/haptics": "^8.0.0",
|
|
42
|
-
"@capacitor/local-notifications": "^8.0.0",
|
|
43
|
-
"@capawesome/capacitor-background-task": "^8.0.0",
|
|
44
34
|
"@tanstack/react-virtual": "^3.13.18",
|
|
45
35
|
"@types/oracledb": "^6.10.1",
|
|
46
36
|
"archiver": "^7.0.1",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{W as a,I as i,N as r}from"./main-B8eX8FW7.js";import"./vendor-react-uS-d4TUT.js";import"./vendor-three-4iQNXcoo.js";class l extends a{constructor(){super(...arguments),this.selectionStarted=!1}async impact(t){const e=this.patternForImpact(t==null?void 0:t.style);this.vibrateWithPattern(e)}async notification(t){const e=this.patternForNotification(t==null?void 0:t.type);this.vibrateWithPattern(e)}async vibrate(t){const e=(t==null?void 0:t.duration)||300;this.vibrateWithPattern([e])}async selectionStart(){this.selectionStarted=!0}async selectionChanged(){this.selectionStarted&&this.vibrateWithPattern([70])}async selectionEnd(){this.selectionStarted=!1}patternForImpact(t=i.Heavy){return t===i.Medium?[43]:t===i.Light?[20]:[61]}patternForNotification(t=r.Success){return t===r.Warning?[30,40,30,50,60]:t===r.Error?[27,45,50]:[35,65,21]}vibrateWithPattern(t){if(navigator.vibrate)navigator.vibrate(t);else throw this.unavailable("Browser does not support the vibrate API")}}export{l as HapticsWeb};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{W as s}from"./main-B8eX8FW7.js";import"./vendor-react-uS-d4TUT.js";import"./vendor-three-4iQNXcoo.js";class l 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{l as LocalNotificationsWeb};
|