gipity 1.0.365 → 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/commands/add.js +2 -2
- 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 +57 -5
- 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 +6 -4
- package/dist/commands/page-fetch.js +136 -0
- package/dist/commands/page-inspect.js +29 -27
- package/dist/commands/page-screenshot.js +17 -18
- package/dist/commands/page-test.js +8 -8
- package/dist/commands/page.js +6 -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 +1 -3
- 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 +10 -10
- 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 +1 -2
- package/dist/helpers/output.js +45 -7
- package/dist/index.js +4 -0
- package/dist/knowledge.js +19 -4
- package/dist/progress.js +60 -0
- package/dist/project-setup.js +5 -1
- package/dist/provider-docs.js +7 -7
- package/dist/setup.js +20 -7
- package/dist/sync.js +16 -6
- package/dist/updater/shim.js +18 -4
- package/dist/upload.js +6 -0
- package/package.json +5 -4
package/dist/banner.js
CHANGED
|
@@ -191,7 +191,9 @@ function renderBox(opts, outerW, bodyLines) {
|
|
|
191
191
|
for (const row of bodyLines)
|
|
192
192
|
lines.push(row);
|
|
193
193
|
lines.push(border('╰') + border('─'.repeat(innerW)) + border('╯'));
|
|
194
|
-
|
|
194
|
+
// Leading blank comes from the central output frame; keep the trailing one
|
|
195
|
+
// (it separates the banner from the picker/output that follows).
|
|
196
|
+
console.log(lines.join('\n') + '\n');
|
|
195
197
|
}
|
|
196
198
|
// ── Narrow layout (single panel, egg only) ────────────────────────────
|
|
197
199
|
function printNarrow(opts, outerW) {
|
package/dist/commands/add.js
CHANGED
|
@@ -154,7 +154,7 @@ export const addCommand = new Command('add')
|
|
|
154
154
|
console.log(JSON.stringify({ templates: { starters: STARTERS, blank: BLANK }, kits: KITS }));
|
|
155
155
|
}
|
|
156
156
|
else {
|
|
157
|
-
console.log(
|
|
157
|
+
console.log(catalogText());
|
|
158
158
|
}
|
|
159
159
|
return;
|
|
160
160
|
}
|
|
@@ -207,7 +207,7 @@ export const addCommand = new Command('add')
|
|
|
207
207
|
console.log(success(`Scaffolded "${data.title}" (${data.type}) - ${data.files.length} files:`));
|
|
208
208
|
}
|
|
209
209
|
for (const f of data.files)
|
|
210
|
-
console.log(
|
|
210
|
+
console.log(`${f}`);
|
|
211
211
|
if (data.notes?.length) {
|
|
212
212
|
console.log('');
|
|
213
213
|
for (const n of data.notes)
|
package/dist/commands/agent.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { get, post, put, del } from '../api.js';
|
|
3
3
|
import { requireConfig, saveConfig } from '../config.js';
|
|
4
|
-
import { error as clrError } from '../colors.js';
|
|
4
|
+
import { error as clrError, success } from '../colors.js';
|
|
5
5
|
import { run, printList, printResult } from '../helpers/index.js';
|
|
6
6
|
import { confirm } from '../utils.js';
|
|
7
7
|
export const agentCommand = new Command('agent')
|
|
@@ -51,11 +51,9 @@ agentCommand
|
|
|
51
51
|
console.log(JSON.stringify(res.data));
|
|
52
52
|
}
|
|
53
53
|
else {
|
|
54
|
-
console.log(
|
|
55
|
-
console.log(`Created "${res.data.name}" (${res.data.short_guid})`);
|
|
54
|
+
console.log(success(`Created "${res.data.name}" (${res.data.short_guid})`));
|
|
56
55
|
if (opts.switch)
|
|
57
56
|
console.log('Switched.');
|
|
58
|
-
console.log('');
|
|
59
57
|
}
|
|
60
58
|
}));
|
|
61
59
|
agentCommand
|
|
@@ -114,7 +112,7 @@ agentCommand
|
|
|
114
112
|
const res = await get('/agents');
|
|
115
113
|
const match = res.data.find(a => a.name === name || a.short_guid === name);
|
|
116
114
|
if (!match) {
|
|
117
|
-
console.error(`Agent "${name}" not found.`);
|
|
115
|
+
console.error(clrError(`Agent "${name}" not found.`));
|
|
118
116
|
process.exit(1);
|
|
119
117
|
}
|
|
120
118
|
if (!await confirm(`Delete agent "${match.name}"?`)) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { get, post } from '../api.js';
|
|
3
|
-
import { muted } from '../colors.js';
|
|
3
|
+
import { muted, success } from '../colors.js';
|
|
4
4
|
import { run, printList, printResult } from '../helpers/index.js';
|
|
5
5
|
function timeAgo(dateStr) {
|
|
6
6
|
const diffMs = Date.now() - new Date(dateStr).getTime();
|
|
@@ -53,7 +53,7 @@ approvalCommand
|
|
|
53
53
|
if (opts.expiresIn)
|
|
54
54
|
body.expires_in_minutes = Number(opts.expiresIn);
|
|
55
55
|
const res = await post('/approvals', body);
|
|
56
|
-
printResult(`Created ${res.data.guid}
|
|
56
|
+
printResult(success(`Created ${res.data.guid}.`), opts, res.data);
|
|
57
57
|
}));
|
|
58
58
|
approvalCommand
|
|
59
59
|
.command('answer <guid> [selection...]')
|
|
@@ -112,6 +112,6 @@ approvalCommand
|
|
|
112
112
|
throw new Error('Expected approval guid like ap_xxxxxxxx');
|
|
113
113
|
}
|
|
114
114
|
await post(`/approvals/${guid}/cancel`, {});
|
|
115
|
-
printResult(`Cancelled ${guid}
|
|
115
|
+
printResult(success(`Cancelled ${guid}.`), opts, { guid, cancelled: true });
|
|
116
116
|
}));
|
|
117
117
|
//# sourceMappingURL=approval.js.map
|
package/dist/commands/audit.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { get } from '../api.js';
|
|
3
3
|
import { requireConfig } from '../config.js';
|
|
4
|
-
import { muted } from '../colors.js';
|
|
4
|
+
import { muted, brand } from '../colors.js';
|
|
5
5
|
import { run, printList } from '../helpers/index.js';
|
|
6
6
|
export const auditCommand = new Command('audit')
|
|
7
7
|
.description('Query audit logs');
|
|
@@ -47,6 +47,6 @@ auditCommand
|
|
|
47
47
|
if (opts.entity)
|
|
48
48
|
params.set('entity_type', opts.entity);
|
|
49
49
|
const res = await get(`/projects/${config.projectGuid}/audit/count?${params}`);
|
|
50
|
-
console.log(opts.json ? JSON.stringify(res.data) : `${res.data.count} events`);
|
|
50
|
+
console.log(opts.json ? JSON.stringify(res.data) : `${brand(String(res.data.count))} events`);
|
|
51
51
|
}));
|
|
52
52
|
//# sourceMappingURL=audit.js.map
|
package/dist/commands/chat.js
CHANGED
|
@@ -2,7 +2,7 @@ import { Command } from 'commander';
|
|
|
2
2
|
import { get, post, put, del } from '../api.js';
|
|
3
3
|
import { resolveProjectContext, saveConfig } from '../config.js';
|
|
4
4
|
import { sync } from '../sync.js';
|
|
5
|
-
import { error as clrError, muted } from '../colors.js';
|
|
5
|
+
import { error as clrError, muted, success } from '../colors.js';
|
|
6
6
|
import { run, printList, printResult } from '../helpers/index.js';
|
|
7
7
|
export const chatCommand = new Command('chat')
|
|
8
8
|
.description('Send a message to your agent')
|
|
@@ -95,7 +95,7 @@ chatCommand
|
|
|
95
95
|
.action((guid, titleParts, opts) => run('Rename', async () => {
|
|
96
96
|
const title = titleParts.join(' ');
|
|
97
97
|
await put(`/conversations/${guid}`, { title });
|
|
98
|
-
printResult(`Renamed ${guid} → "${title}"
|
|
98
|
+
printResult(success(`Renamed ${guid} → "${title}".`), opts, { guid, title });
|
|
99
99
|
}));
|
|
100
100
|
chatCommand
|
|
101
101
|
.command('archive <guid>')
|
|
@@ -103,7 +103,7 @@ chatCommand
|
|
|
103
103
|
.option('--json', 'Output as JSON')
|
|
104
104
|
.action((guid, opts) => run('Archive', async () => {
|
|
105
105
|
await put(`/conversations/${guid}`, { archive: true });
|
|
106
|
-
printResult(`Archived ${guid}
|
|
106
|
+
printResult(success(`Archived ${guid}.`), opts, { guid, archived: true });
|
|
107
107
|
}));
|
|
108
108
|
chatCommand
|
|
109
109
|
.command('delete <guid>')
|
|
@@ -111,6 +111,6 @@ chatCommand
|
|
|
111
111
|
.option('--json', 'Output as JSON')
|
|
112
112
|
.action((guid, opts) => run('Delete', async () => {
|
|
113
113
|
await del(`/conversations/${guid}`);
|
|
114
|
-
printResult(`Deleted ${guid}
|
|
114
|
+
printResult(success(`Deleted ${guid}.`), opts, { guid, deleted: true });
|
|
115
115
|
}));
|
|
116
116
|
//# sourceMappingURL=chat.js.map
|
package/dist/commands/claude.js
CHANGED
|
@@ -27,6 +27,7 @@ import * as relayState from '../relay/state.js';
|
|
|
27
27
|
import { maybeOfferRelayOn, ensureDaemonRunning } from '../relay/onboarding.js';
|
|
28
28
|
import { prompt, promptBoxed, pickOne, decodeJwtExp, confirm } from '../utils.js';
|
|
29
29
|
import { brand, bold, info, success, error as clrError, muted } from '../colors.js';
|
|
30
|
+
import { createProgressReporter } from '../progress.js';
|
|
30
31
|
import { printBanner } from '../banner.js';
|
|
31
32
|
import { scanForAdoption, isLikelyEmpty, canAdoptCwd, formatCwdLabel, formatBytes, adoptCurrentDir, ADOPT_THRESHOLDS, } from '../adopt-cwd.js';
|
|
32
33
|
const __clDir = dirname(fileURLToPath(import.meta.url));
|
|
@@ -297,12 +298,10 @@ export const claudeCommand = new Command('claude')
|
|
|
297
298
|
// ── Step 2: Project ───────────────────────────────────────────────
|
|
298
299
|
let initialPrompt = '';
|
|
299
300
|
let headlessNewProject = false;
|
|
300
|
-
//
|
|
301
|
-
// sync of a large tree no longer reads as a hang.
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
console.log(` ${muted(msg)}`);
|
|
305
|
-
};
|
|
301
|
+
// One reporter for the (otherwise silent) sync phases + upload bar, so a
|
|
302
|
+
// long sync of a large tree no longer reads as a hang. Stays silent in
|
|
303
|
+
// headless (-p) runs to keep machine-readable output clean.
|
|
304
|
+
const syncProgress = nonInteractive ? undefined : createProgressReporter();
|
|
306
305
|
let existing = getConfig();
|
|
307
306
|
let forceAdoptCwd = false;
|
|
308
307
|
// Ambiguity guard: a `.gipity.json` inherited from an ANCESTOR directory
|
|
@@ -394,7 +393,7 @@ export const claudeCommand = new Command('claude')
|
|
|
394
393
|
});
|
|
395
394
|
console.log(`\n Using ${projectDir}`);
|
|
396
395
|
try {
|
|
397
|
-
const result = await sync({ interactive: !nonInteractive,
|
|
396
|
+
const result = await sync({ interactive: !nonInteractive, progress: syncProgress });
|
|
398
397
|
if (result.applied > 0) {
|
|
399
398
|
console.log(` Synced ${result.applied} change${result.applied > 1 ? 's' : ''} with Gipity.`);
|
|
400
399
|
}
|
|
@@ -462,7 +461,7 @@ export const claudeCommand = new Command('claude')
|
|
|
462
461
|
}
|
|
463
462
|
if (doSync) {
|
|
464
463
|
try {
|
|
465
|
-
const result = await sync({ interactive: !nonInteractive,
|
|
464
|
+
const result = await sync({ interactive: !nonInteractive, progress: syncProgress });
|
|
466
465
|
if (result.applied > 0) {
|
|
467
466
|
console.log(` Synced ${result.applied} change${result.applied > 1 ? 's' : ''} with Gipity.`);
|
|
468
467
|
}
|
|
@@ -588,7 +587,7 @@ export const claudeCommand = new Command('claude')
|
|
|
588
587
|
console.log(`\n Using ${projectDir}`);
|
|
589
588
|
// Unified sync - push and pull resolved via three-way merge (non-fatal)
|
|
590
589
|
try {
|
|
591
|
-
const result = await sync({ interactive: !nonInteractive,
|
|
590
|
+
const result = await sync({ interactive: !nonInteractive, progress: syncProgress });
|
|
592
591
|
if (result.applied > 0) {
|
|
593
592
|
console.log(` Synced ${result.applied} change${result.applied > 1 ? 's' : ''} with Gipity.`);
|
|
594
593
|
}
|
package/dist/commands/credits.js
CHANGED
|
@@ -28,7 +28,7 @@ export const creditsCommand = new Command('credits')
|
|
|
28
28
|
if (res.data.balances.length > 0) {
|
|
29
29
|
for (const b of res.data.balances) {
|
|
30
30
|
const exp = new Date(b.expiresAt).toLocaleDateString();
|
|
31
|
-
console.log(
|
|
31
|
+
console.log(`${b.source}: ${b.creditsRemaining.toLocaleString()} ${muted(`expires ${exp}`)}`);
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
}
|
package/dist/commands/db.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { get, post, sendMessage } from '../api.js';
|
|
3
3
|
import { requireConfig } from '../config.js';
|
|
4
|
-
import { error as clrError } from '../colors.js';
|
|
4
|
+
import { error as clrError, success } from '../colors.js';
|
|
5
5
|
import { run, printList } from '../helpers/index.js';
|
|
6
6
|
import { confirm } from '../utils.js';
|
|
7
7
|
export const dbCommand = new Command('db')
|
|
@@ -62,12 +62,10 @@ dbCommand
|
|
|
62
62
|
console.log(JSON.stringify(res.data));
|
|
63
63
|
return;
|
|
64
64
|
}
|
|
65
|
-
console.log('');
|
|
66
65
|
console.log(`Databases: ${count}/${limit}`);
|
|
67
66
|
console.log('');
|
|
68
67
|
if (databases.length === 0) {
|
|
69
68
|
console.log('No databases.');
|
|
70
|
-
console.log('');
|
|
71
69
|
return;
|
|
72
70
|
}
|
|
73
71
|
// Group by project
|
|
@@ -78,13 +76,16 @@ dbCommand
|
|
|
78
76
|
grouped.set(key, []);
|
|
79
77
|
grouped.get(key).push(db);
|
|
80
78
|
}
|
|
79
|
+
let first = true;
|
|
81
80
|
for (const [projectGuid, dbs] of grouped) {
|
|
81
|
+
if (!first)
|
|
82
|
+
console.log('');
|
|
83
|
+
first = false;
|
|
82
84
|
const label = dbs[0].projectSlug || dbs[0].projectName || projectGuid;
|
|
83
85
|
console.log(label);
|
|
84
86
|
for (const db of dbs) {
|
|
85
|
-
console.log(
|
|
87
|
+
console.log(`${db.friendlyName}`);
|
|
86
88
|
}
|
|
87
|
-
console.log();
|
|
88
89
|
}
|
|
89
90
|
}
|
|
90
91
|
else {
|
|
@@ -143,7 +144,7 @@ dbCommand
|
|
|
143
144
|
console.log(JSON.stringify({ success: true }));
|
|
144
145
|
}
|
|
145
146
|
else {
|
|
146
|
-
console.log(`Dropped database '${name}'.`);
|
|
147
|
+
console.log(success(`Dropped database '${name}'.`));
|
|
147
148
|
}
|
|
148
149
|
}));
|
|
149
150
|
//# sourceMappingURL=db.js.map
|
package/dist/commands/deploy.js
CHANGED
|
@@ -31,8 +31,6 @@ export const deployCommand = new Command('deploy')
|
|
|
31
31
|
}
|
|
32
32
|
const config = requireConfig();
|
|
33
33
|
await syncBeforeAction(opts);
|
|
34
|
-
if (!opts.json)
|
|
35
|
-
console.log('');
|
|
36
34
|
// Call server - pipeline runs entirely server-side
|
|
37
35
|
const res = await post(`/projects/${config.projectGuid}/deploy`, {
|
|
38
36
|
target,
|
|
@@ -52,26 +50,26 @@ export const deployCommand = new Command('deploy')
|
|
|
52
50
|
console.log(muted('─'.repeat(40)));
|
|
53
51
|
if (d.phases && d.phases.length > 0) {
|
|
54
52
|
for (const phase of d.phases) {
|
|
55
|
-
console.log(
|
|
53
|
+
console.log(`${statusIcon(phase.status)} ${bold(phase.name)}: ${phase.summary}`);
|
|
56
54
|
}
|
|
57
55
|
}
|
|
58
56
|
else {
|
|
59
57
|
// Fallback for simple deploys without phases
|
|
60
58
|
const size = formatSize(d.totalBytes);
|
|
61
|
-
console.log(
|
|
59
|
+
console.log(`${success('✓')} ${d.fileCount} files (${size}) → ${success(d.url)}`);
|
|
62
60
|
}
|
|
63
61
|
if (d.customDomains?.length) {
|
|
64
|
-
console.log(
|
|
62
|
+
console.log(`${muted('Also:')} ${d.customDomains.join(', ')}`);
|
|
65
63
|
}
|
|
66
64
|
if (d.warning) {
|
|
67
|
-
console.log(
|
|
65
|
+
console.log(`${warning(d.warning)}`);
|
|
68
66
|
}
|
|
69
67
|
// Show example curl commands for public endpoints
|
|
70
68
|
if (d.examples && d.examples.length > 0) {
|
|
71
69
|
console.log('');
|
|
72
70
|
console.log(bold('Test your endpoints:'));
|
|
73
71
|
for (const ex of d.examples) {
|
|
74
|
-
console.log(
|
|
72
|
+
console.log(`${muted(ex)}`);
|
|
75
73
|
}
|
|
76
74
|
}
|
|
77
75
|
console.log(muted('─'.repeat(40)));
|
|
@@ -83,6 +81,5 @@ export const deployCommand = new Command('deploy')
|
|
|
83
81
|
else {
|
|
84
82
|
console.log(success(`✓ Deployed to ${target}`) + muted(` (${d.elapsedMs}ms)`));
|
|
85
83
|
}
|
|
86
|
-
console.log('');
|
|
87
84
|
}));
|
|
88
85
|
//# sourceMappingURL=deploy.js.map
|
package/dist/commands/doctor.js
CHANGED
|
@@ -46,22 +46,20 @@ export const doctorCommand = new Command('doctor')
|
|
|
46
46
|
const dis = updatesDisabled();
|
|
47
47
|
const local = localVersion();
|
|
48
48
|
const localOk = existsSync(LOCAL_ENTRY);
|
|
49
|
-
console.log('');
|
|
50
49
|
console.log(bold('Gipity CLI - doctor'));
|
|
51
50
|
console.log('');
|
|
52
|
-
console.log(
|
|
53
|
-
console.log(
|
|
54
|
-
console.log(
|
|
55
|
-
console.log('');
|
|
56
|
-
console.log(` ${muted('auto-updates ')} ${dis.disabled ? warning(`disabled (${dis.reason})`) : success('enabled')}`);
|
|
57
|
-
console.log(` ${muted('settings file ')} ${existsSync(SETTINGS_FILE) ? SETTINGS_FILE : dim('(default)')} autoUpdates=${settings.autoUpdates}`);
|
|
58
|
-
console.log(` ${muted('last check ')} ${rel(state.lastCheckAt)}`);
|
|
59
|
-
console.log(` ${muted('last error ')} ${state.lastError ? clrError(state.lastError) : dim('none')}`);
|
|
60
|
-
console.log(` ${muted('state file ')} ${existsSync(STATE_FILE) ? STATE_FILE : dim('(none yet)')}`);
|
|
61
|
-
console.log(` ${muted('update log ')} ${existsSync(UPDATE_LOG) ? `${UPDATE_LOG} (${statSync(UPDATE_LOG).size} bytes)` : dim('(none yet)')}`);
|
|
51
|
+
console.log(`${muted('shim version ')} ${shimVersion()}`);
|
|
52
|
+
console.log(`${muted('local version ')} ${local ?? dim('not installed')} ${localOk ? success('✓') : warning('(running from shim fallback)')}`);
|
|
53
|
+
console.log(`${muted('local install ')} ${LOCAL_PKG_DIR}`);
|
|
62
54
|
console.log('');
|
|
63
|
-
console.log(
|
|
64
|
-
console.log(
|
|
55
|
+
console.log(`${muted('auto-updates ')} ${dis.disabled ? warning(`disabled (${dis.reason})`) : success('enabled')}`);
|
|
56
|
+
console.log(`${muted('settings file ')} ${existsSync(SETTINGS_FILE) ? SETTINGS_FILE : dim('(default)')} autoUpdates=${settings.autoUpdates}`);
|
|
57
|
+
console.log(`${muted('last check ')} ${rel(state.lastCheckAt)}`);
|
|
58
|
+
console.log(`${muted('last error ')} ${state.lastError ? clrError(state.lastError) : dim('none')}`);
|
|
59
|
+
console.log(`${muted('state file ')} ${existsSync(STATE_FILE) ? STATE_FILE : dim('(none yet)')}`);
|
|
60
|
+
console.log(`${muted('update log ')} ${existsSync(UPDATE_LOG) ? `${UPDATE_LOG} (${statSync(UPDATE_LOG).size} bytes)` : dim('(none yet)')}`);
|
|
65
61
|
console.log('');
|
|
62
|
+
console.log(dim('Force an update with: gipity update'));
|
|
63
|
+
console.log(dim('Disable auto-update: export DISABLE_AUTOUPDATER=1 (or set autoUpdates: false in settings.json)'));
|
|
66
64
|
});
|
|
67
65
|
//# sourceMappingURL=doctor.js.map
|
package/dist/commands/domain.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import { get, post, del } from '../api.js';
|
|
3
3
|
import { getConfig, requireConfig } from '../config.js';
|
|
4
|
-
import { error as clrError, success, muted } from '../colors.js';
|
|
4
|
+
import { error as clrError, success, muted, brand } from '../colors.js';
|
|
5
5
|
import { run, printList } from '../helpers/index.js';
|
|
6
6
|
export const domainCommand = new Command('domain')
|
|
7
7
|
.description('Manage custom domains')
|
|
@@ -21,7 +21,7 @@ export const domainCommand = new Command('domain')
|
|
|
21
21
|
console.log(JSON.stringify(res.data));
|
|
22
22
|
return;
|
|
23
23
|
}
|
|
24
|
-
console.log(
|
|
24
|
+
console.log(`${muted('Domains:')} ${brand(`${count}/${limit}`)}\n`);
|
|
25
25
|
if (domains.length === 0) {
|
|
26
26
|
console.log('No custom domains.');
|
|
27
27
|
return;
|
|
@@ -34,18 +34,21 @@ export const domainCommand = new Command('domain')
|
|
|
34
34
|
grouped.set(key, []);
|
|
35
35
|
grouped.get(key).push(d);
|
|
36
36
|
}
|
|
37
|
+
let first = true;
|
|
37
38
|
for (const [label, doms] of grouped) {
|
|
38
|
-
|
|
39
|
+
if (!first)
|
|
40
|
+
console.log('');
|
|
41
|
+
first = false;
|
|
42
|
+
console.log(brand(label));
|
|
39
43
|
for (const d of doms) {
|
|
40
|
-
console.log(
|
|
44
|
+
console.log(`${d.domain} ${muted(d.status)} ${muted(`[${d.shortGuid}]`)}`);
|
|
41
45
|
}
|
|
42
|
-
console.log();
|
|
43
46
|
}
|
|
44
47
|
}
|
|
45
48
|
else {
|
|
46
49
|
const config = requireConfig();
|
|
47
50
|
const res = await get(`/projects/${config.projectGuid}/domains`);
|
|
48
|
-
printList(res.data, opts, 'No custom domains configured.', d =>
|
|
51
|
+
printList(res.data, opts, 'No custom domains configured.', d => `${d.domain} ${muted(d.status)} ${muted(`[${d.short_guid}]`)}`);
|
|
49
52
|
}
|
|
50
53
|
break;
|
|
51
54
|
}
|
|
@@ -64,15 +67,15 @@ export const domainCommand = new Command('domain')
|
|
|
64
67
|
console.log(success(`Domain "${data.domain.domain}" added.`));
|
|
65
68
|
console.log('');
|
|
66
69
|
console.log('Add this DNS record:');
|
|
67
|
-
console.log(
|
|
68
|
-
console.log(
|
|
69
|
-
console.log(
|
|
70
|
+
console.log(`${muted('Type:'.padEnd(8))}${data.instructions.type}`);
|
|
71
|
+
console.log(`${muted('Name:'.padEnd(8))}${data.instructions.name}`);
|
|
72
|
+
console.log(`${muted('Target:'.padEnd(8))}${data.instructions.target}`);
|
|
70
73
|
if (data.instructions.note) {
|
|
71
74
|
console.log('');
|
|
72
75
|
console.log(data.instructions.note);
|
|
73
76
|
}
|
|
74
77
|
console.log('');
|
|
75
|
-
console.log(`Then run: gipity domain verify ${data.domain.short_guid}`);
|
|
78
|
+
console.log(muted(`Then run: gipity domain verify ${data.domain.short_guid}`));
|
|
76
79
|
}
|
|
77
80
|
break;
|
|
78
81
|
}
|
|
@@ -121,11 +124,11 @@ export const domainCommand = new Command('domain')
|
|
|
121
124
|
default:
|
|
122
125
|
console.log('Usage: gipity domain [list|add|verify|remove]');
|
|
123
126
|
console.log('');
|
|
124
|
-
console.log('
|
|
125
|
-
console.log('
|
|
126
|
-
console.log('
|
|
127
|
-
console.log('
|
|
128
|
-
console.log('
|
|
127
|
+
console.log(`${brand('gipity domain list')} ${muted('List project domains')}`);
|
|
128
|
+
console.log(`${brand('gipity domain list --all')} ${muted('List all domains across projects')}`);
|
|
129
|
+
console.log(`${brand('gipity domain add <domain.com>')} ${muted('Add a custom domain (requires project)')}`);
|
|
130
|
+
console.log(`${brand('gipity domain verify <guid>')} ${muted('Verify DNS and activate (requires project)')}`);
|
|
131
|
+
console.log(`${brand('gipity domain remove <guid>')} ${muted('Remove a custom domain')}`);
|
|
129
132
|
}
|
|
130
133
|
}));
|
|
131
134
|
//# sourceMappingURL=domain.js.map
|
package/dist/commands/email.js
CHANGED
|
@@ -41,15 +41,11 @@ export const emailCommand = new Command('email')
|
|
|
41
41
|
const recap = res.data.to.join(', ')
|
|
42
42
|
+ (res.data.cc.length ? `, cc: ${res.data.cc.join(', ')}` : '')
|
|
43
43
|
+ (res.data.bcc.length ? `, bcc: ${res.data.bcc.length}` : '');
|
|
44
|
-
console.log('');
|
|
45
44
|
console.log(success(`Email sent to ${recap}: ${res.data.subject}`));
|
|
46
|
-
console.log('');
|
|
47
45
|
}
|
|
48
46
|
}
|
|
49
47
|
catch (err) {
|
|
50
|
-
console.log('');
|
|
51
48
|
console.error(clrError(`Email failed: ${err.message}`));
|
|
52
|
-
console.log('');
|
|
53
49
|
process.exit(1);
|
|
54
50
|
}
|
|
55
51
|
});
|
package/dist/commands/fn.js
CHANGED
|
@@ -14,7 +14,7 @@ fnCommand
|
|
|
14
14
|
const res = await get(`/projects/${config.projectGuid}/functions`);
|
|
15
15
|
printList(res.data, opts, 'No functions defined.', f => {
|
|
16
16
|
const line = `${bold(f.name)} ${muted(`v${f.version}`)} ${muted(f.auth_level)} ${muted(`timeout=${f.timeout_ms}ms`)}`;
|
|
17
|
-
return f.description ? `${line}\n
|
|
17
|
+
return f.description ? `${line}\n${muted(f.description)}` : line;
|
|
18
18
|
});
|
|
19
19
|
}));
|
|
20
20
|
fnCommand
|
|
@@ -30,7 +30,7 @@ fnCommand
|
|
|
30
30
|
const ts = new Date(log.created_at).toLocaleString();
|
|
31
31
|
const statusColor = log.status === 'success' ? success : log.status === 'error' ? clrError : muted;
|
|
32
32
|
const line = `${statusColor(log.status)} ${dur} ${muted(log.trigger_type || 'http')} ${muted(ts)}`;
|
|
33
|
-
return log.error_message ? `${line}\n
|
|
33
|
+
return log.error_message ? `${line}\n${clrError(`error: ${log.error_message}`)}` : line;
|
|
34
34
|
});
|
|
35
35
|
}));
|
|
36
36
|
fnCommand
|
|
@@ -28,13 +28,13 @@ Gemini-specific options:
|
|
|
28
28
|
Examples:
|
|
29
29
|
gipity generate image "a cat wearing a top hat"
|
|
30
30
|
gipity generate image "landscape sunset" --provider gemini --aspect-ratio 16:9 --image-size 2K
|
|
31
|
-
gipity generate image "product photo" --provider openai --model gpt-image-
|
|
31
|
+
gipity generate image "product photo" --provider openai --model gpt-image-2 --size 1536x1024 --quality high
|
|
32
32
|
gipity generate image "abstract art" --provider bfl --model flux-2-pro -o art.png`)
|
|
33
33
|
.argument('<prompt>', 'Text description of the image to generate')
|
|
34
34
|
.option('--provider <provider>', 'Image provider: openai, bfl, or gemini (default: bfl)')
|
|
35
35
|
.option('--model <model>', 'Model ID (see provider list above)')
|
|
36
36
|
.option('--size <size>', 'Dimensions as WxH, e.g. "1024x1024" (OpenAI/BFL)')
|
|
37
|
-
.option('--quality <quality>', 'Quality: low|medium|high|auto (gpt-image-
|
|
37
|
+
.option('--quality <quality>', 'Quality: low|medium|high|auto (gpt-image-2)')
|
|
38
38
|
.option('--aspect-ratio <ratio>', 'Aspect ratio (Gemini only): 1:1, 16:9, 9:16, 4:3, 3:4, 3:2, 2:3, 4:5, 5:4, 21:9')
|
|
39
39
|
.option('--image-size <size>', 'Output resolution (Gemini only): 512, 1K, 2K, 4K')
|
|
40
40
|
.option('-o, --output <file>', 'Output path (default ./generated.png). For an image your app ships, write it into the source tree so it deploys, e.g. -o src/assets/images/hero.png; the cwd default is fine for one-off generation.')
|
|
@@ -96,7 +96,8 @@ Examples:
|
|
|
96
96
|
.action(async (prompt, opts) => {
|
|
97
97
|
try {
|
|
98
98
|
const { config } = await resolveProjectContext();
|
|
99
|
-
|
|
99
|
+
if (!opts.json)
|
|
100
|
+
console.log(info('Generating video (this may take 30-120 seconds)...')); // keep --json stdout pure JSON
|
|
100
101
|
const result = await post(`/projects/${config.projectGuid}/generate/video`, {
|
|
101
102
|
prompt,
|
|
102
103
|
model: opts.model,
|
|
@@ -178,10 +179,61 @@ Examples:
|
|
|
178
179
|
process.exit(1);
|
|
179
180
|
}
|
|
180
181
|
});
|
|
182
|
+
// ── MUSIC ──────────────────────────────────────────────────────────────
|
|
183
|
+
const musicCommand = new Command('music')
|
|
184
|
+
.description(`Generate music from a text prompt using AI.
|
|
185
|
+
|
|
186
|
+
The model is chosen from the platform's music catalog. Omit --model to use the
|
|
187
|
+
default; pass --model <id> only if you want a specific one (see the catalog with
|
|
188
|
+
\`gipity service call music/models --get\`).
|
|
189
|
+
|
|
190
|
+
Tips:
|
|
191
|
+
- Describe genre, mood, instruments, and tempo (e.g. "upbeat lo-fi hip hop with mellow piano")
|
|
192
|
+
- Music is instrumental by default; pass --vocals to allow singing
|
|
193
|
+
- Longer clips cost more; the max length depends on the model
|
|
194
|
+
|
|
195
|
+
Examples:
|
|
196
|
+
gipity generate music "chill lo-fi beat for studying"
|
|
197
|
+
gipity generate music "epic orchestral battle theme" --duration 60 -o src/assets/audio/theme.mp3
|
|
198
|
+
gipity generate music "indie pop chorus" --vocals --duration 20`)
|
|
199
|
+
.argument('<prompt>', 'Text description of the music to generate')
|
|
200
|
+
.option('--duration <seconds>', 'Clip length in seconds (default 30; max depends on the model)', (v) => parseInt(v, 10))
|
|
201
|
+
.option('--model <model>', 'Music model id (default: platform default)')
|
|
202
|
+
.option('--vocals', 'Allow vocals (default: instrumental only)')
|
|
203
|
+
.option('-o, --output <file>', 'Output path (default ./music.mp3). For audio your app ships, write it into the source tree so it deploys, e.g. -o src/assets/audio/theme.mp3; the cwd default is fine for one-off generation.')
|
|
204
|
+
.option('--json', 'Output as JSON')
|
|
205
|
+
.action(async (prompt, opts) => {
|
|
206
|
+
try {
|
|
207
|
+
const { config } = await resolveProjectContext();
|
|
208
|
+
if (!opts.json)
|
|
209
|
+
console.log(info('Generating music...')); // keep --json stdout pure JSON
|
|
210
|
+
const result = await post(`/projects/${config.projectGuid}/generate/music`, {
|
|
211
|
+
prompt,
|
|
212
|
+
duration_seconds: opts.duration,
|
|
213
|
+
model: opts.model,
|
|
214
|
+
instrumental: !opts.vocals,
|
|
215
|
+
});
|
|
216
|
+
const filename = opts.output || 'music.mp3';
|
|
217
|
+
const savedPath = await downloadFile(result.url, filename);
|
|
218
|
+
if (opts.json) {
|
|
219
|
+
console.log(JSON.stringify({ ...result, saved: savedPath }));
|
|
220
|
+
}
|
|
221
|
+
else {
|
|
222
|
+
const sizeKb = Math.round(result.size_bytes / 1024);
|
|
223
|
+
console.log(`${muted(`Generated with ${result.model} (${sizeKb}KB)`)}`);
|
|
224
|
+
console.log(success(`Saved to ${savedPath}`));
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
catch (err) {
|
|
228
|
+
console.error(clrError(`Music generation failed: ${err.message}`));
|
|
229
|
+
process.exit(1);
|
|
230
|
+
}
|
|
231
|
+
});
|
|
181
232
|
// ── PARENT COMMAND ─────────────────────────────────────────────────────
|
|
182
233
|
export const generateCommand = new Command('generate')
|
|
183
|
-
.description('Generate images, video, or
|
|
234
|
+
.description('Generate images, video, speech, or music')
|
|
184
235
|
.addCommand(imageCommand)
|
|
185
236
|
.addCommand(videoCommand)
|
|
186
|
-
.addCommand(speechCommand)
|
|
237
|
+
.addCommand(speechCommand)
|
|
238
|
+
.addCommand(musicCommand);
|
|
187
239
|
//# sourceMappingURL=generate.js.map
|
package/dist/commands/job.js
CHANGED
|
@@ -17,7 +17,7 @@ jobCommand
|
|
|
17
17
|
if (j.on_complete)
|
|
18
18
|
tags.push(muted(`→ ${j.on_complete}`));
|
|
19
19
|
const line = `${bold(j.name)} ${tags.join(' ')}`;
|
|
20
|
-
return j.description ? `${line}\n
|
|
20
|
+
return j.description ? `${line}\n${muted(j.description)}` : line;
|
|
21
21
|
});
|
|
22
22
|
}));
|
|
23
23
|
jobCommand
|
|
@@ -57,13 +57,13 @@ jobCommand
|
|
|
57
57
|
const statusColor = r.status === 'success' ? success : r.status === 'failed' ? clrError : muted;
|
|
58
58
|
console.log(`${statusColor(r.status)} ${muted(r.guid)}`);
|
|
59
59
|
if (r.progress_pct != null)
|
|
60
|
-
console.log(`
|
|
60
|
+
console.log(`progress: ${Math.round(r.progress_pct * 100)}%${r.progress_message ? ` (${r.progress_message})` : ''}`);
|
|
61
61
|
if (r.duration_ms != null)
|
|
62
|
-
console.log(`
|
|
62
|
+
console.log(`duration: ${r.duration_ms}ms`);
|
|
63
63
|
if (r.error)
|
|
64
|
-
console.log(
|
|
64
|
+
console.log(`${clrError('error:')} ${r.error}`);
|
|
65
65
|
if (r.output)
|
|
66
|
-
console.log(`
|
|
66
|
+
console.log(`output: ${JSON.stringify(r.output)}`);
|
|
67
67
|
}));
|
|
68
68
|
jobCommand
|
|
69
69
|
.command('runs <name>')
|
|
@@ -78,7 +78,7 @@ jobCommand
|
|
|
78
78
|
const dur = r.duration_ms != null ? `${r.duration_ms}ms` : '?';
|
|
79
79
|
const ts = new Date(r.created_at).toLocaleString();
|
|
80
80
|
const line = `${statusColor(r.status)} ${dur} ${muted(r.trigger_type)} ${muted(r.guid)} ${muted(ts)}`;
|
|
81
|
-
return r.error ? `${line}\n
|
|
81
|
+
return r.error ? `${line}\n${clrError(`error: ${r.error}`)}` : line;
|
|
82
82
|
});
|
|
83
83
|
}));
|
|
84
84
|
jobCommand
|
|
@@ -12,16 +12,16 @@ function formatLocation(r) {
|
|
|
12
12
|
const lines = [];
|
|
13
13
|
const place = [r.city, r.region, r.country].filter(Boolean).join(', ');
|
|
14
14
|
if (place)
|
|
15
|
-
lines.push(
|
|
15
|
+
lines.push(place);
|
|
16
16
|
if (r.lat != null && r.lon != null)
|
|
17
|
-
lines.push(`
|
|
17
|
+
lines.push(`Coordinates: ${r.lat}, ${r.lon}`);
|
|
18
18
|
if (r.ip)
|
|
19
|
-
lines.push(`
|
|
19
|
+
lines.push(`IP: ${r.ip}`);
|
|
20
20
|
if (r.timezone)
|
|
21
|
-
lines.push(`
|
|
21
|
+
lines.push(`Timezone: ${r.timezone}`);
|
|
22
22
|
if (r.accuracy != null)
|
|
23
|
-
lines.push(`
|
|
24
|
-
lines.push(`
|
|
23
|
+
lines.push(`Accuracy: ${Math.round(r.accuracy)}m`);
|
|
24
|
+
lines.push(`Source: ${r.source}`);
|
|
25
25
|
return lines.join('\n');
|
|
26
26
|
}
|
|
27
27
|
/**
|
|
@@ -71,7 +71,7 @@ export const locationCommand = new Command('location')
|
|
|
71
71
|
return;
|
|
72
72
|
}
|
|
73
73
|
if (!res.data) {
|
|
74
|
-
console.log('
|
|
74
|
+
console.log('No location data.');
|
|
75
75
|
return;
|
|
76
76
|
}
|
|
77
77
|
console.log(formatLocation(res.data));
|