gipity 1.0.356 → 1.0.374
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/banner.js +3 -1
- package/dist/capture/sources/claude-code.js +76 -11
- package/dist/commands/add.js +45 -28
- package/dist/commands/agent.js +3 -5
- package/dist/commands/approval.js +3 -3
- package/dist/commands/audit.js +2 -2
- package/dist/commands/chat.js +4 -4
- package/dist/commands/claude.js +8 -9
- package/dist/commands/credits.js +1 -1
- package/dist/commands/db.js +7 -6
- package/dist/commands/deploy.js +5 -8
- package/dist/commands/doctor.js +11 -13
- package/dist/commands/domain.js +18 -15
- package/dist/commands/email.js +0 -4
- package/dist/commands/fn.js +2 -2
- package/dist/commands/generate.js +73 -18
- package/dist/commands/job.js +6 -6
- package/dist/commands/location.js +7 -7
- package/dist/commands/login.js +2 -16
- package/dist/commands/logout.js +2 -3
- package/dist/commands/logs.js +1 -1
- package/dist/commands/page-eval.js +48 -7
- package/dist/commands/page-fetch.js +136 -0
- package/dist/commands/page-inspect.js +59 -29
- package/dist/commands/page-screenshot.js +51 -41
- package/dist/commands/page-test.js +86 -0
- package/dist/commands/page.js +8 -3
- package/dist/commands/plan.js +4 -4
- package/dist/commands/push.js +2 -6
- package/dist/commands/realtime.js +7 -9
- package/dist/commands/relay-install.js +18 -21
- package/dist/commands/relay.js +29 -31
- package/dist/commands/sandbox.js +16 -3
- package/dist/commands/service.js +54 -0
- package/dist/commands/skill.js +2 -1
- package/dist/commands/status.js +2 -2
- package/dist/commands/sync.js +4 -1
- package/dist/commands/test.js +7 -13
- package/dist/commands/text.js +148 -0
- package/dist/commands/uninstall.js +20 -42
- package/dist/commands/update.js +0 -2
- package/dist/commands/upload.js +4 -4
- package/dist/commands/workflow.js +11 -16
- package/dist/config.js +8 -1
- package/dist/help-skills.js +1 -0
- package/dist/helpers/output.js +52 -8
- package/dist/helpers/text-analysis.js +200 -0
- package/dist/hooks/capture-runner.js +32 -8
- package/dist/index.js +35 -2
- package/dist/knowledge.js +32 -7
- package/dist/progress.js +60 -0
- package/dist/project-setup.js +5 -1
- package/dist/provider-docs.js +7 -7
- package/dist/relay/daemon.js +11 -1
- package/dist/relay/stream-json.js +45 -8
- package/dist/setup.js +38 -11
- package/dist/sync.js +30 -8
- package/dist/updater/shim.js +18 -4
- package/dist/upload.js +6 -0
- package/package.json +5 -4
|
@@ -32,7 +32,7 @@ const roomCommand = new Command('room')
|
|
|
32
32
|
switch (sub) {
|
|
33
33
|
case 'list': {
|
|
34
34
|
const res = await get(base);
|
|
35
|
-
printList(res.data, opts, 'No realtime rooms. Create one: gipity realtime room create <name>', r =>
|
|
35
|
+
printList(res.data, opts, 'No realtime rooms. Create one: gipity realtime room create <name>', r => `${bold(r.name)} ${muted(`${r.room_type} · ${r.auth_level} · max ${r.max_clients}`)}`);
|
|
36
36
|
break;
|
|
37
37
|
}
|
|
38
38
|
case 'create': {
|
|
@@ -74,7 +74,7 @@ const roomCommand = new Command('room')
|
|
|
74
74
|
console.log(JSON.stringify({ success: true }));
|
|
75
75
|
}
|
|
76
76
|
else {
|
|
77
|
-
console.log(`Deleted room '${name}'
|
|
77
|
+
console.log(success(`Deleted room '${name}'.`) + ' Active instances drain as clients disconnect.');
|
|
78
78
|
}
|
|
79
79
|
break;
|
|
80
80
|
}
|
|
@@ -89,13 +89,11 @@ const roomCommand = new Command('room')
|
|
|
89
89
|
}
|
|
90
90
|
else {
|
|
91
91
|
const { room, live } = res.data;
|
|
92
|
-
console.log(
|
|
93
|
-
console.log(`
|
|
94
|
-
console.log(`
|
|
95
|
-
console.log(`
|
|
96
|
-
console.log(`
|
|
97
|
-
console.log(` Live: ${live ? `${live.instances} instance(s), ${live.clients} client(s)` : muted('Colyseus server unreachable')}`);
|
|
98
|
-
console.log('');
|
|
92
|
+
console.log(`${bold(room.name)}`);
|
|
93
|
+
console.log(`Type: ${room.room_type}`);
|
|
94
|
+
console.log(`Auth: ${room.auth_level}`);
|
|
95
|
+
console.log(`Max clients: ${room.max_clients}`);
|
|
96
|
+
console.log(`Live: ${live ? `${live.instances} instance(s), ${live.clients} client(s)` : muted('Colyseus server unreachable')}`);
|
|
99
97
|
}
|
|
100
98
|
break;
|
|
101
99
|
}
|
|
@@ -8,7 +8,7 @@ import { planFor, UnsupportedPlatformError } from '../relay/installers.js';
|
|
|
8
8
|
function requirePaired() {
|
|
9
9
|
const device = state.getDevice();
|
|
10
10
|
if (!device) {
|
|
11
|
-
console.error(
|
|
11
|
+
console.error(`${clrError('No paired device.')} Run ${bold('gipity claude')} to pair this machine.`);
|
|
12
12
|
process.exit(1);
|
|
13
13
|
}
|
|
14
14
|
return device;
|
|
@@ -48,40 +48,37 @@ export function registerInstallCommands(relayCommand) {
|
|
|
48
48
|
}
|
|
49
49
|
catch (err) {
|
|
50
50
|
if (err instanceof UnsupportedPlatformError) {
|
|
51
|
-
console.error(
|
|
52
|
-
console.error(
|
|
51
|
+
console.error(clrError(err.message));
|
|
52
|
+
console.error(muted('Supported on macOS, Linux, and Windows.'));
|
|
53
53
|
}
|
|
54
54
|
else
|
|
55
55
|
throw err;
|
|
56
56
|
process.exit(1);
|
|
57
57
|
}
|
|
58
|
-
console.log('');
|
|
59
|
-
console.log(
|
|
60
|
-
console.log(` ${bold('File:')} ${plan.path}`);
|
|
61
|
-
console.log('');
|
|
58
|
+
console.log(`${bold('Install plan:')} ${plan.summary}`);
|
|
59
|
+
console.log(`${bold('File:')} ${plan.path}`);
|
|
62
60
|
if (opts.print) {
|
|
61
|
+
console.log('');
|
|
63
62
|
console.log(`${dim('--- file content ---')}`);
|
|
64
63
|
console.log(plan.content);
|
|
65
64
|
console.log(`${dim('--- enable: ---')}`);
|
|
66
65
|
console.log(plan.enableDisplay);
|
|
67
|
-
console.log('');
|
|
68
66
|
return;
|
|
69
67
|
}
|
|
70
|
-
if (!(await confirm('
|
|
71
|
-
console.log(
|
|
68
|
+
if (!(await confirm('Write the file and enable the service now?'))) {
|
|
69
|
+
console.log(muted('Cancelled. (Use --print to preview without installing.)'));
|
|
72
70
|
return;
|
|
73
71
|
}
|
|
74
72
|
mkdirSync(dirname(plan.path), { recursive: true });
|
|
75
73
|
writeFileSync(plan.path, plan.content);
|
|
76
|
-
console.log(
|
|
74
|
+
console.log(success(`Wrote ${plan.path}`));
|
|
77
75
|
if (!runArgvSequence(plan.enableCmds, { failFast: true })) {
|
|
78
|
-
console.error(
|
|
76
|
+
console.error(clrError(`Couldn't enable autostart. Try manually: ${plan.enableDisplay}`));
|
|
79
77
|
process.exit(1);
|
|
80
78
|
}
|
|
81
|
-
console.log('');
|
|
82
|
-
console.log(`
|
|
83
|
-
console.log(
|
|
84
|
-
console.log(` ${dim(`Tail logs: gipity relay log`)}`);
|
|
79
|
+
console.log(success('Background service installed and started.'));
|
|
80
|
+
console.log(muted(`Check status: ${plan.statusDisplay}`));
|
|
81
|
+
console.log(muted(`Tail logs: gipity relay log`));
|
|
85
82
|
});
|
|
86
83
|
relayCommand
|
|
87
84
|
.command('autostart <on|off>')
|
|
@@ -89,7 +86,7 @@ export function registerInstallCommands(relayCommand) {
|
|
|
89
86
|
.action(async (mode) => {
|
|
90
87
|
const want = mode.toLowerCase();
|
|
91
88
|
if (want !== 'on' && want !== 'off') {
|
|
92
|
-
console.error(
|
|
89
|
+
console.error(clrError('Usage: gipity relay autostart <on|off>'));
|
|
93
90
|
process.exit(1);
|
|
94
91
|
}
|
|
95
92
|
let plan;
|
|
@@ -98,7 +95,7 @@ export function registerInstallCommands(relayCommand) {
|
|
|
98
95
|
}
|
|
99
96
|
catch (err) {
|
|
100
97
|
if (err instanceof UnsupportedPlatformError) {
|
|
101
|
-
console.error(
|
|
98
|
+
console.error(clrError(err.message));
|
|
102
99
|
process.exit(1);
|
|
103
100
|
}
|
|
104
101
|
else
|
|
@@ -106,14 +103,14 @@ export function registerInstallCommands(relayCommand) {
|
|
|
106
103
|
}
|
|
107
104
|
const cmds = want === 'on' ? plan.enableCmds : plan.disableCmds;
|
|
108
105
|
const display = want === 'on' ? plan.enableDisplay : plan.disableDisplay;
|
|
109
|
-
console.log(
|
|
106
|
+
console.log(`${info('Running:')} ${dim(display)}`);
|
|
110
107
|
// Disable is best-effort (the task may already be stopped); enable is fail-fast.
|
|
111
108
|
const ok = runArgvSequence(cmds, { failFast: want === 'on' });
|
|
112
109
|
if (!ok && want === 'on') {
|
|
113
|
-
console.error(
|
|
110
|
+
console.error(clrError('Command failed.'));
|
|
114
111
|
process.exit(1);
|
|
115
112
|
}
|
|
116
|
-
console.log(
|
|
113
|
+
console.log(success(`Autostart ${want}.`));
|
|
117
114
|
});
|
|
118
115
|
}
|
|
119
116
|
//# sourceMappingURL=relay-install.js.map
|
package/dist/commands/relay.js
CHANGED
|
@@ -10,7 +10,7 @@ import { existsSync, readFileSync, unlinkSync } from 'fs';
|
|
|
10
10
|
import { spawn } from 'child_process';
|
|
11
11
|
import { post } from '../api.js';
|
|
12
12
|
import { confirm } from '../utils.js';
|
|
13
|
-
import { bold, brand,
|
|
13
|
+
import { bold, brand, success, error as clrError, muted, } from '../colors.js';
|
|
14
14
|
import * as state from '../relay/state.js';
|
|
15
15
|
import * as daemon from '../relay/daemon.js';
|
|
16
16
|
import { registerInstallCommands } from './relay-install.js';
|
|
@@ -32,16 +32,14 @@ relayCommand
|
|
|
32
32
|
console.log(JSON.stringify(safe, null, 2));
|
|
33
33
|
return;
|
|
34
34
|
}
|
|
35
|
-
console.log('');
|
|
36
35
|
if (!s.device) {
|
|
37
|
-
console.log(
|
|
36
|
+
console.log(`${muted('No paired device.')} Run ${brand('gipity claude')} to pair this machine.`);
|
|
38
37
|
return;
|
|
39
38
|
}
|
|
40
|
-
console.log(
|
|
41
|
-
console.log(
|
|
42
|
-
console.log(
|
|
43
|
-
console.log(
|
|
44
|
-
console.log('');
|
|
39
|
+
console.log(`${bold('Device:')} ${brand(s.device.name)} ${muted(`(${s.device.guid})`)}`);
|
|
40
|
+
console.log(`${bold('Platform:')} ${s.device.platform}`);
|
|
41
|
+
console.log(`${bold('Paired:')} ${s.device.paired_at}`);
|
|
42
|
+
console.log(`${bold('Paused:')} ${s.paused ? 'yes' : 'no'}`);
|
|
45
43
|
});
|
|
46
44
|
// ─── gipity relay run ──────────────────────────────────────────────────
|
|
47
45
|
relayCommand
|
|
@@ -64,12 +62,12 @@ relayCommand
|
|
|
64
62
|
.action(async (opts) => {
|
|
65
63
|
const pidPath = state.getDaemonPidPath();
|
|
66
64
|
if (!existsSync(pidPath)) {
|
|
67
|
-
console.log(
|
|
65
|
+
console.log(muted('Background service isn\'t running.'));
|
|
68
66
|
return;
|
|
69
67
|
}
|
|
70
68
|
const pid = parseInt(readFileSync(pidPath, 'utf-8').trim(), 10);
|
|
71
69
|
if (!pid || isNaN(pid)) {
|
|
72
|
-
console.error(
|
|
70
|
+
console.error(clrError('PID file is empty or malformed.'));
|
|
73
71
|
process.exit(1);
|
|
74
72
|
}
|
|
75
73
|
try {
|
|
@@ -77,14 +75,14 @@ relayCommand
|
|
|
77
75
|
}
|
|
78
76
|
catch (err) {
|
|
79
77
|
if (err?.code === 'ESRCH') {
|
|
80
|
-
console.log(
|
|
78
|
+
console.log(muted(`PID ${pid} not running - cleaning up stale PID file.`));
|
|
81
79
|
try {
|
|
82
80
|
unlinkSync(pidPath);
|
|
83
81
|
}
|
|
84
82
|
catch { /* ignore */ }
|
|
85
83
|
return;
|
|
86
84
|
}
|
|
87
|
-
console.error(
|
|
85
|
+
console.error(clrError(`Could not signal PID ${pid}: ${err?.message || err}`));
|
|
88
86
|
process.exit(1);
|
|
89
87
|
}
|
|
90
88
|
// Wait up to 5s for clean shutdown.
|
|
@@ -110,15 +108,15 @@ relayCommand
|
|
|
110
108
|
process.kill(pid, 'SIGKILL');
|
|
111
109
|
}
|
|
112
110
|
catch { /* ignore */ }
|
|
113
|
-
console.log(
|
|
111
|
+
console.log(success('Background service force-stopped.'));
|
|
114
112
|
}
|
|
115
113
|
else {
|
|
116
|
-
console.error(
|
|
114
|
+
console.error(clrError(`Didn't shut down cleanly after 5s. Retry with --force to stop it.`));
|
|
117
115
|
process.exit(1);
|
|
118
116
|
}
|
|
119
117
|
}
|
|
120
118
|
else {
|
|
121
|
-
console.log(
|
|
119
|
+
console.log(success('Background service stopped.'));
|
|
122
120
|
}
|
|
123
121
|
});
|
|
124
122
|
// ─── gipity relay pause / resume ───────────────────────────────────────
|
|
@@ -128,7 +126,7 @@ relayCommand
|
|
|
128
126
|
.action(() => {
|
|
129
127
|
requirePaired();
|
|
130
128
|
state.setPaused(true);
|
|
131
|
-
console.log(
|
|
129
|
+
console.log(`${success('Paused.')} ${muted('Run `gipity relay resume` to accept commands again.')}`);
|
|
132
130
|
});
|
|
133
131
|
relayCommand
|
|
134
132
|
.command('resume')
|
|
@@ -136,7 +134,7 @@ relayCommand
|
|
|
136
134
|
.action(() => {
|
|
137
135
|
requirePaired();
|
|
138
136
|
state.setPaused(false);
|
|
139
|
-
console.log(
|
|
137
|
+
console.log(success('Resumed.'));
|
|
140
138
|
});
|
|
141
139
|
// ─── gipity relay rename <name> ────────────────────────────────────────
|
|
142
140
|
relayCommand
|
|
@@ -146,7 +144,7 @@ relayCommand
|
|
|
146
144
|
const device = requirePaired();
|
|
147
145
|
const name = newName.trim();
|
|
148
146
|
if (!name || name.length > 100) {
|
|
149
|
-
console.error(
|
|
147
|
+
console.error(clrError('Device name must be 1–100 non-whitespace characters.'));
|
|
150
148
|
process.exit(1);
|
|
151
149
|
}
|
|
152
150
|
try {
|
|
@@ -154,14 +152,14 @@ relayCommand
|
|
|
154
152
|
await post(`/remote-devices/${encodeURIComponent(device.guid)}/rename`, { name });
|
|
155
153
|
}
|
|
156
154
|
catch (err) {
|
|
157
|
-
console.error(
|
|
155
|
+
console.error(clrError(`Rename failed: ${err?.message || err}`));
|
|
158
156
|
if (err?.statusCode === 401) {
|
|
159
|
-
console.error(
|
|
157
|
+
console.error(muted('Run `gipity login` first - rename requires your user auth.'));
|
|
160
158
|
}
|
|
161
159
|
process.exit(1);
|
|
162
160
|
}
|
|
163
161
|
state.setDevice({ ...device, name });
|
|
164
|
-
console.log(
|
|
162
|
+
console.log(success(`Renamed to ${bold(name)}.`));
|
|
165
163
|
});
|
|
166
164
|
// ─── gipity relay revoke ───────────────────────────────────────────────
|
|
167
165
|
relayCommand
|
|
@@ -169,8 +167,8 @@ relayCommand
|
|
|
169
167
|
.description('Revoke and forget this device')
|
|
170
168
|
.action(async () => {
|
|
171
169
|
const device = requirePaired();
|
|
172
|
-
if (!(await confirm(`
|
|
173
|
-
console.log(
|
|
170
|
+
if (!(await confirm(`Revoke ${bold(device.name)} (${device.guid})?`))) {
|
|
171
|
+
console.log(muted('Cancelled.'));
|
|
174
172
|
return;
|
|
175
173
|
}
|
|
176
174
|
try {
|
|
@@ -179,12 +177,12 @@ relayCommand
|
|
|
179
177
|
catch (err) {
|
|
180
178
|
// Even if the server call fails, drop local state - a stale token is
|
|
181
179
|
// worse than double-revoking. Warn loudly though.
|
|
182
|
-
console.error(
|
|
183
|
-
console.error(
|
|
180
|
+
console.error(clrError(`Server revoke failed: ${err?.message || err}`));
|
|
181
|
+
console.error(muted('Local token cleared anyway. Visit the web CLI to confirm the server-side revoke.'));
|
|
184
182
|
}
|
|
185
183
|
state.clearDevice();
|
|
186
|
-
console.log(
|
|
187
|
-
console.log(
|
|
184
|
+
console.log(success('Device revoked + local state cleared.'));
|
|
185
|
+
console.log(muted('Any running background service will notice and exit within ~30s.'));
|
|
188
186
|
});
|
|
189
187
|
// ─── gipity relay log ──────────────────────────────────────────────────
|
|
190
188
|
relayCommand
|
|
@@ -195,7 +193,7 @@ relayCommand
|
|
|
195
193
|
.action((opts) => {
|
|
196
194
|
const path = daemon.RELAY_LOG_PATH;
|
|
197
195
|
if (!existsSync(path)) {
|
|
198
|
-
console.log(
|
|
196
|
+
console.log(muted('No log file yet. Start the service with `gipity relay run` (or install it).'));
|
|
199
197
|
return;
|
|
200
198
|
}
|
|
201
199
|
const lines = parseInt(opts.lines, 10) || 100;
|
|
@@ -205,14 +203,14 @@ relayCommand
|
|
|
205
203
|
process.stdout.write(tail);
|
|
206
204
|
}
|
|
207
205
|
catch (err) {
|
|
208
|
-
console.error(
|
|
206
|
+
console.error(clrError(`Could not read log: ${err?.message || err}`));
|
|
209
207
|
process.exit(1);
|
|
210
208
|
}
|
|
211
209
|
if (opts.follow) {
|
|
212
210
|
// Defer real follow to `tail -f` - cross-platform fallback below.
|
|
213
211
|
const tailCmd = process.platform === 'win32' ? null : 'tail';
|
|
214
212
|
if (!tailCmd) {
|
|
215
|
-
console.error(
|
|
213
|
+
console.error(clrError('--follow is not supported on this platform yet.'));
|
|
216
214
|
process.exit(1);
|
|
217
215
|
}
|
|
218
216
|
const child = spawn(tailCmd, ['-f', '-n', '0', path], { stdio: 'inherit' });
|
|
@@ -226,7 +224,7 @@ registerInstallCommands(relayCommand);
|
|
|
226
224
|
function requirePaired() {
|
|
227
225
|
const device = state.getDevice();
|
|
228
226
|
if (!device) {
|
|
229
|
-
console.error(
|
|
227
|
+
console.error(`${clrError('No paired device.')} Run ${brand('gipity claude')} to pair this machine.`);
|
|
230
228
|
process.exit(1);
|
|
231
229
|
}
|
|
232
230
|
return device;
|
package/dist/commands/sandbox.js
CHANGED
|
@@ -2,6 +2,7 @@ import { Command } from 'commander';
|
|
|
2
2
|
import { dirname, relative } from 'path';
|
|
3
3
|
import { post } from '../api.js';
|
|
4
4
|
import { resolveProjectContext, getConfigPath } from '../config.js';
|
|
5
|
+
import { sync } from '../sync.js';
|
|
5
6
|
import { error as clrError, dim } from '../colors.js';
|
|
6
7
|
import { run } from '../helpers/index.js';
|
|
7
8
|
const LANG_MAP = {
|
|
@@ -41,6 +42,9 @@ file you write lands back in the project. No manual copy needed.
|
|
|
41
42
|
Use --input only for projects over the auto-mirror cap, or when you want
|
|
42
43
|
to restrict what the sandbox sees.
|
|
43
44
|
|
|
45
|
+
No network, and the toolset is fixed - pip/npm/apt installs won't work.
|
|
46
|
+
Use only preinstalled tools, or pull external inputs into the project first.
|
|
47
|
+
|
|
44
48
|
Examples:
|
|
45
49
|
|
|
46
50
|
# Auto-mirror: code sees the whole project at /work/
|
|
@@ -80,8 +84,17 @@ GCC/Rust).
|
|
|
80
84
|
input_files: opts.input,
|
|
81
85
|
cwd,
|
|
82
86
|
});
|
|
87
|
+
// Pull sandbox-written outputs down to the local cwd automatically. The
|
|
88
|
+
// server has already mirrored them into the project (VFS) and handed back
|
|
89
|
+
// the exact list, so honoring it here means files land locally without a
|
|
90
|
+
// manual `gipity sync` - same auto-pull contract `gipity chat` uses on its
|
|
91
|
+
// `filesChanged` flag. Skip in one-off mode (no local project to sync into).
|
|
92
|
+
const pulledLocal = !!(res.data.outputFiles?.length && getConfigPath());
|
|
93
|
+
if (pulledLocal) {
|
|
94
|
+
await sync({ interactive: false });
|
|
95
|
+
}
|
|
83
96
|
if (opts.json) {
|
|
84
|
-
console.log(JSON.stringify(res.data));
|
|
97
|
+
console.log(JSON.stringify({ ...res.data, filesSynced: pulledLocal }));
|
|
85
98
|
}
|
|
86
99
|
else {
|
|
87
100
|
if (res.data.autoMirrorSkipped) {
|
|
@@ -94,9 +107,9 @@ GCC/Rust).
|
|
|
94
107
|
if (res.data.timedOut)
|
|
95
108
|
console.error(`[Timed out after ${res.data.durationMs}ms]`);
|
|
96
109
|
if (res.data.outputFiles && res.data.outputFiles.length > 0) {
|
|
97
|
-
console.log(`\nOutput files saved to project:`);
|
|
110
|
+
console.log(`\nOutput files ${pulledLocal ? 'synced to this directory' : 'saved to project'}:`);
|
|
98
111
|
for (const f of res.data.outputFiles)
|
|
99
|
-
console.log(
|
|
112
|
+
console.log(`${f}`);
|
|
100
113
|
}
|
|
101
114
|
if (res.data.exitCode !== 0)
|
|
102
115
|
process.exit(res.data.exitCode);
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { get, post } from '../api.js';
|
|
3
|
+
import { requireConfig } from '../config.js';
|
|
4
|
+
import { bold, muted } from '../colors.js';
|
|
5
|
+
import { run } from '../helpers/index.js';
|
|
6
|
+
/** Known app-service endpoints, shown by `gipity service list` and used to
|
|
7
|
+
* give a helpful hint on typos. POST endpoints take a JSON body; GET
|
|
8
|
+
* endpoints (model/voice listings) are reached with `--get`. */
|
|
9
|
+
const SERVICES = [
|
|
10
|
+
{ name: 'llm', method: 'POST', desc: 'Chat completion ({ prompt | messages, model?, ... })' },
|
|
11
|
+
{ name: 'llm/models', method: 'GET', desc: 'List available LLM models' },
|
|
12
|
+
{ name: 'image', method: 'POST', desc: 'Generate an image ({ prompt, provider?, size? })' },
|
|
13
|
+
{ name: 'image/models', method: 'GET', desc: 'List image providers/models' },
|
|
14
|
+
{ name: 'tts', method: 'POST', desc: 'Text-to-speech ({ text, voice?, ... })' },
|
|
15
|
+
{ name: 'tts/voices', method: 'GET', desc: 'List TTS voices' },
|
|
16
|
+
{ name: 'sound', method: 'POST', desc: 'Sound effect ({ prompt, duration_seconds? })' },
|
|
17
|
+
{ name: 'music', method: 'POST', desc: 'Music generation ({ prompt, duration_seconds? })' },
|
|
18
|
+
{ name: 'video', method: 'POST', desc: 'Video generation ({ prompt, ... })' },
|
|
19
|
+
{ name: 'location/ip', method: 'POST', desc: 'IP geolocation ({ ip? })' },
|
|
20
|
+
{ name: 'location/geocode', method: 'POST', desc: 'Reverse geocode ({ lat, lon })' },
|
|
21
|
+
];
|
|
22
|
+
export const serviceCommand = new Command('service')
|
|
23
|
+
.description('Call a Gipity app service (LLM, image, music, TTS, ...)');
|
|
24
|
+
serviceCommand
|
|
25
|
+
.command('list')
|
|
26
|
+
.description('List callable app services')
|
|
27
|
+
.action(() => run('Services', async () => {
|
|
28
|
+
requireConfig();
|
|
29
|
+
const width = SERVICES.reduce((m, s) => Math.max(m, s.name.length), 0);
|
|
30
|
+
console.log('Call one with `gipity service call <name> \'{"json":"body"}\'`');
|
|
31
|
+
console.log(muted('(GET endpoints like llm/models, tts/voices take --get and no body)'));
|
|
32
|
+
console.log('');
|
|
33
|
+
for (const s of SERVICES) {
|
|
34
|
+
console.log(`${bold(s.name.padEnd(width))} ${muted(`[${s.method}] ${s.desc}`)}`);
|
|
35
|
+
}
|
|
36
|
+
}));
|
|
37
|
+
serviceCommand
|
|
38
|
+
.command('call <name> [body]')
|
|
39
|
+
.description('Call an app service by name (e.g. llm, image, music). Uses your logged-in session - no token wrangling.')
|
|
40
|
+
.option('--data <json>', 'JSON request body (alternative to the positional [body])')
|
|
41
|
+
.option('--get', 'Issue a GET (for listing endpoints like llm/models, tts/voices)')
|
|
42
|
+
.option('--json', 'Output compact JSON')
|
|
43
|
+
.action((name, bodyArg, opts) => run('Call', async () => {
|
|
44
|
+
const config = requireConfig();
|
|
45
|
+
// Encode each path segment but preserve the `/` separators so subpaths
|
|
46
|
+
// like `location/geocode` and `llm/models` resolve correctly.
|
|
47
|
+
const path = name.split('/').map(encodeURIComponent).join('/');
|
|
48
|
+
const url = `/api/${config.projectGuid}/services/${path}`;
|
|
49
|
+
const res = opts.get
|
|
50
|
+
? await get(url)
|
|
51
|
+
: await post(url, JSON.parse(bodyArg || opts.data || '{}'));
|
|
52
|
+
console.log(opts.json ? JSON.stringify(res) : JSON.stringify(res, null, 2));
|
|
53
|
+
}));
|
|
54
|
+
//# sourceMappingURL=service.js.map
|
package/dist/commands/skill.js
CHANGED
|
@@ -16,7 +16,8 @@ skillCommand
|
|
|
16
16
|
process.exit(1);
|
|
17
17
|
}
|
|
18
18
|
const res = await get(`/skills?agent=${config.agentGuid}`);
|
|
19
|
-
|
|
19
|
+
const width = res.data.reduce((m, s) => Math.max(m, s.name.length), 0);
|
|
20
|
+
printList(res.data, opts, 'No skills available.', s => ` ${bold(s.name.padEnd(width))} ${muted(s.description)}`, 'Read one with `gipity skill read <name>`:');
|
|
20
21
|
}));
|
|
21
22
|
skillCommand
|
|
22
23
|
.command('read <name>')
|
package/dist/commands/status.js
CHANGED
|
@@ -86,8 +86,8 @@ export const statusCommand = new Command('status')
|
|
|
86
86
|
}
|
|
87
87
|
else {
|
|
88
88
|
console.log(`${muted('Hooks:')} ${warning(`missing/modified: ${hookCheck.missing.join(', ')}`)}`);
|
|
89
|
-
console.log(
|
|
90
|
-
console.log(
|
|
89
|
+
console.log(muted('Run `gipity status --repair-hooks` to re-install.'));
|
|
90
|
+
console.log(muted('Without these, web CLI dispatches can\'t show Claude Code output.'));
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
});
|
package/dist/commands/sync.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { sync } from '../sync.js';
|
|
3
|
+
import { createProgressReporter } from '../progress.js';
|
|
3
4
|
import { error as clrError } from '../colors.js';
|
|
4
5
|
export const syncCommand = new Command('sync')
|
|
5
6
|
.description('Sync files')
|
|
@@ -8,7 +9,9 @@ export const syncCommand = new Command('sync')
|
|
|
8
9
|
.option('--json', 'Output as JSON')
|
|
9
10
|
.action(async (opts) => {
|
|
10
11
|
try {
|
|
11
|
-
|
|
12
|
+
// JSON mode stays machine-clean; otherwise show live progress on a TTY.
|
|
13
|
+
const progress = opts.json ? undefined : createProgressReporter();
|
|
14
|
+
const result = await sync({ plan: opts.plan, force: opts.force, progress });
|
|
12
15
|
if (opts.json) {
|
|
13
16
|
console.log(JSON.stringify(result));
|
|
14
17
|
}
|
package/dist/commands/test.js
CHANGED
|
@@ -86,7 +86,6 @@ export const testCommand = new Command('test')
|
|
|
86
86
|
const config = requireConfig();
|
|
87
87
|
await syncBeforeAction(opts);
|
|
88
88
|
if (!opts.json) {
|
|
89
|
-
console.log('');
|
|
90
89
|
console.log(bold(`Running tests: ${filterPath || 'all'}`));
|
|
91
90
|
console.log('');
|
|
92
91
|
}
|
|
@@ -98,7 +97,7 @@ export const testCommand = new Command('test')
|
|
|
98
97
|
});
|
|
99
98
|
const runGuid = kickoff.data.runGuid;
|
|
100
99
|
if (!opts.json) {
|
|
101
|
-
console.log(
|
|
100
|
+
console.log(muted(`Run: ${runGuid}`));
|
|
102
101
|
console.log('');
|
|
103
102
|
}
|
|
104
103
|
// Poll for results (streams results as they complete)
|
|
@@ -123,7 +122,6 @@ export const testCommand = new Command('test')
|
|
|
123
122
|
if (data.skipped > 0)
|
|
124
123
|
parts.push(muted(`${data.skipped} skipped`));
|
|
125
124
|
console.log(`${parts.join(', ')} ${muted(`(${data.durationMs}ms)`)}`);
|
|
126
|
-
console.log('');
|
|
127
125
|
if (data.failed > 0)
|
|
128
126
|
process.exit(1);
|
|
129
127
|
}));
|
|
@@ -150,24 +148,22 @@ testCommand
|
|
|
150
148
|
return;
|
|
151
149
|
}
|
|
152
150
|
const icon = data.status === 'running' ? muted('⧗') : data.status === 'passed' ? success('✓') : clrError('✗');
|
|
153
|
-
console.log(
|
|
154
|
-
console.log(` ${icon} ${bold(data.status)} - ${data.passed}/${data.total} passed`);
|
|
151
|
+
console.log(`${icon} ${bold(data.status)} - ${data.passed}/${data.total} passed`);
|
|
155
152
|
if (data.totalFiles > 0) {
|
|
156
|
-
console.log(
|
|
153
|
+
console.log(muted(`Files: ${data.completedFiles}/${data.totalFiles}`));
|
|
157
154
|
}
|
|
158
155
|
if (data.durationMs) {
|
|
159
|
-
console.log(
|
|
156
|
+
console.log(muted(`Duration: ${data.durationMs}ms`));
|
|
160
157
|
}
|
|
161
158
|
if (data.failed > 0) {
|
|
162
159
|
console.log('');
|
|
163
160
|
const failures = data.results.filter(r => r.status === 'failed');
|
|
164
161
|
for (const f of failures) {
|
|
165
|
-
console.log(
|
|
162
|
+
console.log(`${clrError('✗')} ${f.path}/${f.name}`);
|
|
166
163
|
if (f.error)
|
|
167
|
-
console.log(`
|
|
164
|
+
console.log(` ${clrError(f.error)}`);
|
|
168
165
|
}
|
|
169
166
|
}
|
|
170
|
-
console.log('');
|
|
171
167
|
}));
|
|
172
168
|
// ── History subcommand ─────────────────────────────────────────────────
|
|
173
169
|
testCommand
|
|
@@ -186,13 +182,11 @@ testCommand
|
|
|
186
182
|
console.log(muted('No test runs yet.'));
|
|
187
183
|
return;
|
|
188
184
|
}
|
|
189
|
-
console.log('');
|
|
190
185
|
console.log(bold('Test History'));
|
|
191
186
|
for (const entry of res.data) {
|
|
192
187
|
const icon = entry.status === 'passed' ? success('✓') : entry.status === 'running' ? muted('⧗') : clrError('✗');
|
|
193
188
|
const date = new Date(entry.started_at).toLocaleDateString('en-US', { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' });
|
|
194
|
-
console.log(
|
|
189
|
+
console.log(`${icon} ${muted(date)} ${entry.passed}/${entry.total} passed ${muted(entry.run_guid)}`);
|
|
195
190
|
}
|
|
196
|
-
console.log('');
|
|
197
191
|
}));
|
|
198
192
|
//# sourceMappingURL=test.js.map
|