@assethub/cli 0.1.33 → 0.1.36
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 +67 -24
- package/dist/agentSetup.d.ts +35 -40
- package/dist/agentSetup.d.ts.map +1 -1
- package/dist/agentSetup.js +72 -113
- package/dist/hooks/command.d.ts +1 -0
- package/dist/hooks/command.d.ts.map +1 -1
- package/dist/hooks/command.js +2 -1
- package/dist/hooks/save.d.ts +14 -0
- package/dist/hooks/save.d.ts.map +1 -1
- package/dist/hooks/save.js +20 -0
- package/dist/hooks/types.d.ts +2 -0
- package/dist/hooks/types.d.ts.map +1 -1
- package/dist/hooks/upload.d.ts +6 -0
- package/dist/hooks/upload.d.ts.map +1 -1
- package/dist/hooks/upload.js +16 -2
- package/dist/index.d.ts +5 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +156 -30
- package/dist/setupCommand.d.ts +53 -2
- package/dist/setupCommand.d.ts.map +1 -1
- package/dist/setupCommand.js +344 -131
- package/dist/updateNotice.d.ts +71 -0
- package/dist/updateNotice.d.ts.map +1 -0
- package/dist/updateNotice.js +189 -0
- package/package.json +1 -1
- package/skills/assethub/SKILL.md +20 -3
package/dist/hooks/save.js
CHANGED
|
@@ -30,6 +30,8 @@ const spawnCli = (args, profile) => {
|
|
|
30
30
|
};
|
|
31
31
|
/** SessionEnd: upload this session, then retry up to SWEEP_LIMIT older pending ones. */
|
|
32
32
|
export const spawnDetachedUpload = (sessionDir, profile) => spawnCli(['hooks', 'upload', '--session', sessionDir, '--auto', '--sweep', String(SWEEP_LIMIT)], profile);
|
|
33
|
+
/** Stop / PreCompact: upload this running session only; no sweep. */
|
|
34
|
+
export const spawnDetachedSessionUpload = (sessionDir, profile) => spawnCli(['hooks', 'upload', '--session', sessionDir, '--auto'], profile);
|
|
33
35
|
/** SessionStart: retry up to SWEEP_LIMIT pending sessions. */
|
|
34
36
|
export const spawnDetachedSweep = (profile) => spawnCli(['hooks', 'upload', '--pending', '--limit', String(SWEEP_LIMIT)], profile);
|
|
35
37
|
export const retentionDays = (env) => {
|
|
@@ -155,6 +157,13 @@ const collectImages = async (sessionDir, transcript, cwd) => {
|
|
|
155
157
|
export const ABANDONED_AFTER_MS = 2 * 60 * 60 * 1000;
|
|
156
158
|
/** Sessions retried in the background per SessionStart / SessionEnd. */
|
|
157
159
|
export const SWEEP_LIMIT = 3;
|
|
160
|
+
/**
|
|
161
|
+
* A running session is uploaded at most this often. Claude Code app sessions
|
|
162
|
+
* stay open for days and rarely reach SessionEnd, so without this they would
|
|
163
|
+
* only be uploaded once abandoned (ABANDONED_AFTER_MS quiet, then a new session).
|
|
164
|
+
*/
|
|
165
|
+
export const WORKING_UPLOAD_INTERVAL_MS = 20 * 60 * 1000;
|
|
166
|
+
const WORKING_UPLOAD_EVENTS = new Set(['Stop', 'PreCompact']);
|
|
158
167
|
/** Events that copy and redact the transcript now; the rest only mark it changed. */
|
|
159
168
|
const FULL_SAVE_EVENTS = new Set(['SessionEnd', 'Manual']);
|
|
160
169
|
/**
|
|
@@ -312,6 +321,17 @@ export const saveSession = async (options = {}) => {
|
|
|
312
321
|
if (full)
|
|
313
322
|
await materializeSession(sessionDir, { env, transcriptPath });
|
|
314
323
|
const result = { sessionDir, event };
|
|
324
|
+
if (uploadOn && options.startWorkingUpload && WORKING_UPLOAD_EVENTS.has(event)) {
|
|
325
|
+
const latest = await readMeta(sessionDir);
|
|
326
|
+
// Counts uploads any path started (an earlier Stop, SessionEnd, a sweep).
|
|
327
|
+
const lastStart = Math.max(Date.parse(latest?.lastWorkingUploadAt ?? '') || 0, Date.parse(latest?.lastUploadAttemptAt ?? '') || 0);
|
|
328
|
+
if (latest && now.getTime() - lastStart >= WORKING_UPLOAD_INTERVAL_MS) {
|
|
329
|
+
// Stamped before spawning, so the next few turns do not start more.
|
|
330
|
+
await updateMeta(sessionDir, latest, current => ({ ...current, lastWorkingUploadAt: now.toISOString() }));
|
|
331
|
+
options.startWorkingUpload(sessionDir, options.upload?.profile);
|
|
332
|
+
result.uploadStarted = true;
|
|
333
|
+
}
|
|
334
|
+
}
|
|
315
335
|
if (event === 'SessionEnd') {
|
|
316
336
|
const days = retentionDays(env);
|
|
317
337
|
if (days != null)
|
package/dist/hooks/types.d.ts
CHANGED
|
@@ -39,6 +39,8 @@ export type SessionMeta = {
|
|
|
39
39
|
abandoned?: boolean;
|
|
40
40
|
/** How far the graph is compacted after uploads failed for size or time (0 = none). */
|
|
41
41
|
compactLevel?: number;
|
|
42
|
+
/** When Stop or PreCompact last started a background upload of this running session. */
|
|
43
|
+
lastWorkingUploadAt?: string;
|
|
42
44
|
/** Failed uploads in a row; spaces out the automatic retries. */
|
|
43
45
|
failedAttempts?: number;
|
|
44
46
|
/** Size of the live transcript the local copy was made from (before masking). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/hooks/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,OAAO,CAAA;AAE3C,MAAM,MAAM,SAAS,GAAG;IACtB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,gBAAgB,GAAG,UAAU,CAAA;AAEnE,MAAM,MAAM,YAAY,GAAG;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAC,CAAA;AAEvF,MAAM,MAAM,WAAW,GAAG;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,UAAU,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,aAAa,CAAA;IACrB,MAAM,EAAE,YAAY,EAAE,CAAA;IACtB,+EAA+E;IAC/E,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,gGAAgG;IAChG,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,kEAAkE;IAClE,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,mEAAmE;IACnE,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,uFAAuF;IACvF,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,iEAAiE;IACjE,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,iFAAiF;IACjF,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,8FAA8F;IAC9F,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,OAAO,CAAA;IACX,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,sFAAsF;IACtF,SAAS,CAAC,EAAE,IAAI,CAAA;CACjB,CAAA"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/hooks/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,OAAO,CAAA;AAE3C,MAAM,MAAM,SAAS,GAAG;IACtB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,gBAAgB,GAAG,UAAU,CAAA;AAEnE,MAAM,MAAM,YAAY,GAAG;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAC,CAAA;AAEvF,MAAM,MAAM,WAAW,GAAG;IACxB,SAAS,EAAE,MAAM,CAAA;IACjB,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,UAAU,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,aAAa,CAAA;IACrB,MAAM,EAAE,YAAY,EAAE,CAAA;IACtB,+EAA+E;IAC/E,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,gGAAgG;IAChG,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,kEAAkE;IAClE,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,mEAAmE;IACnE,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,uFAAuF;IACvF,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,wFAAwF;IACxF,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,iEAAiE;IACjE,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,iFAAiF;IACjF,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,8FAA8F;IAC9F,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,EAAE,EAAE,OAAO,CAAA;IACX,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,sFAAsF;IACtF,SAAS,CAAC,EAAE,IAAI,CAAA;CACjB,CAAA"}
|
package/dist/hooks/upload.d.ts
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import type { UploadOutcome } from './types.js';
|
|
2
2
|
export declare const CODING_AGENT_SESSION_API_PREFIX = "/api/v2/coding-agent-sessions";
|
|
3
3
|
export declare const UPLOAD_TIMEOUT_MS = 20000;
|
|
4
|
+
/** A session's upload lock older than this belongs to a crashed upload. */
|
|
5
|
+
export declare const UPLOAD_LOCK_STALE_MS: number;
|
|
6
|
+
/** How often a running upload refreshes its lock, well inside UPLOAD_LOCK_STALE_MS. */
|
|
7
|
+
export declare const UPLOAD_LOCK_HEARTBEAT_MS = 60000;
|
|
4
8
|
export type UploadAuth = {
|
|
5
9
|
apiKey: string;
|
|
6
10
|
baseUrl: string;
|
|
7
11
|
workspaceId?: string;
|
|
8
12
|
};
|
|
9
13
|
export type UploadOptions = {
|
|
14
|
+
/** How often a running upload refreshes its lock (tests shorten it). */
|
|
15
|
+
lockHeartbeatMs?: number;
|
|
10
16
|
profile?: string;
|
|
11
17
|
home?: string;
|
|
12
18
|
env?: NodeJS.ProcessEnv;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/hooks/upload.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAc,aAAa,EAAC,MAAM,YAAY,CAAA;AAG1D,eAAO,MAAM,+BAA+B,kCAAkC,CAAA;AAQ9E,eAAO,MAAM,iBAAiB,QAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/hooks/upload.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAc,aAAa,EAAC,MAAM,YAAY,CAAA;AAG1D,eAAO,MAAM,+BAA+B,kCAAkC,CAAA;AAQ9E,eAAO,MAAM,iBAAiB,QAAS,CAAA;AACvC,2EAA2E;AAC3E,eAAO,MAAM,oBAAoB,QAAc,CAAA;AAC/C,uFAAuF;AACvF,eAAO,MAAM,wBAAwB,QAAS,CAAA;AAE9C,MAAM,MAAM,UAAU,GAAG;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAC,CAAA;AAEhF,MAAM,MAAM,aAAa,GAAG;IAC1B,wEAAwE;IACxE,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAA;IACvB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAA;IACxB,IAAI,CAAC,EAAE,UAAU,CAAA;IACjB,GAAG,CAAC,EAAE,MAAM,IAAI,CAAA;IAChB,wEAAwE;IACxE,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAC5B,SAAS,IAAI,CAAC,aAAa,EAAE,SAAS,GAAG,MAAM,GAAG,KAAK,CAAC,KACvD,OAAO,CAAC,UAAU,GAAG,IAAI,CA2B3B,CAAA;AAED,iFAAiF;AACjF,eAAO,MAAM,YAAY,GAAI,gBAAgB,MAAM,KAAG,MACmB,CAAA;AAmBzE;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,GAC5B,MAAM,UAAU,EAChB,YAAW,OAAO,KAAyC,KAC1D,OAAO,CAAC,OAAO,CAgBjB,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa,GACxB,YAAY,MAAM,EAClB,UAAS,aAAkB,KAC1B,OAAO,CAAC,aAAa,CAmBvB,CAAA;AAoHD;;;;GAIG;AACH,eAAO,MAAM,aAAa,GACxB,UAAS,aAAa,GAAG;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAM,KAC/D,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,aAAa,CAAA;CAAC,EAAE,CAkBrD,CAAA"}
|
package/dist/hooks/upload.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// contract as `runs upload`, so the plan and transport are shared; only the
|
|
4
4
|
// URL prefix and the extra `session` registration fields differ. Sessions are
|
|
5
5
|
// owned by, and readable only by, the key's user.
|
|
6
|
-
import { readFile } from 'node:fs/promises';
|
|
6
|
+
import { readFile, utimes } from 'node:fs/promises';
|
|
7
7
|
import { basename, join } from 'node:path';
|
|
8
8
|
import { buildRunUploadPlan } from '../runsUpload/buildRunUpload.js';
|
|
9
9
|
import { controlRunUploadUrls } from '../runsUpload/controlEndpoints.js';
|
|
@@ -24,6 +24,10 @@ const canvasIdOf = (value) => {
|
|
|
24
24
|
};
|
|
25
25
|
const DAY_MS = 24 * 60 * 60 * 1000;
|
|
26
26
|
export const UPLOAD_TIMEOUT_MS = 20_000;
|
|
27
|
+
/** A session's upload lock older than this belongs to a crashed upload. */
|
|
28
|
+
export const UPLOAD_LOCK_STALE_MS = 15 * 60_000;
|
|
29
|
+
/** How often a running upload refreshes its lock, well inside UPLOAD_LOCK_STALE_MS. */
|
|
30
|
+
export const UPLOAD_LOCK_HEARTBEAT_MS = 60_000;
|
|
27
31
|
/**
|
|
28
32
|
* Resolve the CLI profile's key + base URL from ~/.assethub/config.json.
|
|
29
33
|
* src/index.ts's resolveAuth is module-private, so this mirrors its precedence
|
|
@@ -105,13 +109,23 @@ export const canUploadSessions = async (auth, fetchImpl = globalThis.fetch.bind(
|
|
|
105
109
|
export const uploadSession = async (sessionDir, options = {}) => {
|
|
106
110
|
if (!(await readMeta(sessionDir)))
|
|
107
111
|
return { ok: false, reason: 'no-session' };
|
|
108
|
-
const
|
|
112
|
+
const lockPath = join(sessionDir, '.upload.lock');
|
|
113
|
+
const release = await acquireLock(lockPath, { waitMs: 0, staleMs: UPLOAD_LOCK_STALE_MS });
|
|
109
114
|
if (!release)
|
|
110
115
|
return { ok: false, reason: 'upload-in-progress', throttled: true };
|
|
116
|
+
// A lock older than UPLOAD_LOCK_STALE_MS is taken over as a crashed upload's.
|
|
117
|
+
// Touching it while this upload runs keeps a long upload from looking crashed,
|
|
118
|
+
// so a later Stop, sweep or SessionEnd cannot start a second one beside it.
|
|
119
|
+
const heartbeat = setInterval(() => {
|
|
120
|
+
const now = new Date();
|
|
121
|
+
void utimes(lockPath, now, now).catch(() => { });
|
|
122
|
+
}, options.lockHeartbeatMs ?? UPLOAD_LOCK_HEARTBEAT_MS);
|
|
123
|
+
heartbeat.unref?.();
|
|
111
124
|
try {
|
|
112
125
|
return await uploadSessionUnlocked(sessionDir, options);
|
|
113
126
|
}
|
|
114
127
|
finally {
|
|
128
|
+
clearInterval(heartbeat);
|
|
115
129
|
await release();
|
|
116
130
|
}
|
|
117
131
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { type SetupStepName } from './setupCommand.js';
|
|
2
3
|
import { type InstallHooks } from './setupHooksBridge.js';
|
|
3
4
|
import { type AnimationRetargetRequest, type Intervention, type RigRequest, createAssetHubClient } from '@assethub/api-client';
|
|
4
5
|
import { buildRunUploadPlan } from './runsUpload/buildRunUpload.js';
|
|
@@ -23,8 +24,10 @@ type CommandContext = {
|
|
|
23
24
|
*/
|
|
24
25
|
args: string[];
|
|
25
26
|
};
|
|
26
|
-
export declare const usage = "AssetHub CLI\n\nCLI and MCP are available to all AssetHub users. Workspace permissions and feature availability apply.\n\nUsage:\n assethub --version\n assethub setup [--client claude|codex|both] [--profile <name>] [--workspace <id>] [--api-key-stdin] [--base-url <url>] [--no-app-env] [--dry-run] [--yes] [--print-env] [--json]\n assethub env load [--profile <name>]\n assethub update [--check] [--dry-run] [--yes]\n assethub doctor [--mcp] [--profile <name>] [--timeout-ms <n>]\n assethub init [--agent claude-code|codex|cursor...] [--project] [--dry-run] [--base-url <url>] [--workspace <id>] [--profile <name>]\n assethub mcp tools [tool-name] [--account] [--profile <name>] [--timeout-ms <n>]\n assethub mcp config --client cursor|codex [--account] [--base-url <url>]\n assethub auth login --api-key <key> [--base-url <url>] [--profile <name>]\n assethub auth login --api-key-stdin [--base-url <url>] [--profile <name>]\n assethub auth login --access-token-stdin [--base-url <url>] [--profile <name>]\n assethub auth status [--profile <name>]\n assethub auth logout [--profile <name>]\n assethub workspace list [--query <text>] [--limit <1-100>] [--cursor <cursor>]\n assethub workspace get\n assethub workspace create --name <name> [--operation-id <uuid>]\n assethub workspace use <workspace-id>\n assethub workspace members [--workspace <id>]\n assethub workspace invite --email <email> [--role user|admin] [--resend] [--workspace <id>]\n assethub workspace set-role <user-id> --role user|admin [--workspace <id>]\n assethub workspace remove-member <user-id> [--workspace <id>]\n assethub workspace prepare|sync|analyze|verify --internal --manifest <json> --state <json>\n assethub workspace self-check --internal\n assethub workspace context put --internal --org <uuid> --actor <uuid> --canvas <id> --file <json> [--if-version <n>] [--order <uuid>]\n assethub workspace context get --internal --org <uuid> --actor <uuid> --canvas <id> [--out <json>] [--order <uuid>]\n assethub project ingest <source-dir> --out-dir <directory> [--exclude-dir <relative-path>...]\n assethub language text|vision --input-json @<json> --operation-id <uuid> [--out <json>]\n assethub canvas download --canvas <id> --out-dir <directory> [--mesh <mesh_asset_id>]\n assethub canvas nodes --canvas <id>\n assethub canvas import --canvas <id> --file <image> [--name <name>]\n assethub canvas context get --canvas <id> [--out <json>]\n assethub canvas context put --canvas <id> --file <json> [--if-version <n>]\n assethub canvas layout --canvas <id> --input-json @<json>\n assethub canvas compare --canvas <id> --source-id <asset-id> --asset-id <asset-id> --out <html>\n assethub moodboard create --input-json @<json> [--operation-id <uuid>]\n assethub moodboard list|get|update|archive [<board-id>] [--input-json @<json>]\n assethub moodboard analyze <board-id> [--revision <uuid>] [--wait]\n assethub image generate --canvas <id> --context <id> [--context-version <n>] [--context-source <key>] [--moodboard-revision <uuid>] --prompt <text> --wait\n assethub models list [--domain <domain>] [--ids-only] [--limit <n>]\n assethub models get <model-id>\n assethub files import <url> --media-type image|mesh\n assethub files upload <file> --media-type image|mesh\n assethub source create (--file <path> | --source-url <url> | --source-id <id> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri> | --clipboard) --media-type image|mesh [--file-name <name>] [--content-type <type>]\n assethub capabilities\n assethub api search [query]\n assethub api describe \"<METHOD /path>\"\n assethub api call \"<METHOD /path>\" [--path-json <json|@file>] [--query-json <json|@file>] [--input-json <json|@file|@->] [--operation-id <uuid>]\n assethub composer models\n assethub composer refine --list-modes\n assethub composer refine --from-run <run-id> --instruction <text> [--mode standard|thorough|placement|workshop|blender|codex] [--effort light|standard|thorough] [--max-rounds <n>] [--agent-model <provider:id|unambiguous-id>] [--transforms-json <json|@file>] [--wait] [--download --out-dir <dir>]\n assethub composer refine --input-json <json|@file> [--canvas <id>] [--operation-id <uuid>] [--wait] [--download --out-dir <dir>]\n assethub composer refine --from-run <run-id> --skill-assembly [--reasoning low|medium|high] [--agent-model <agents-api model>] [--wait]\n assethub composer run --part <mesh-asset-id>[=<part-image-id>] [--part <mesh-asset-id>[=<part-image-id>]...] --reference <image-asset-id> [--model <id>] [--agent-model <provider:id|unambiguous-id>] [--mode quick|quality] [--optimize off|light|medium|heavy] [--transforms-json <json|@file>] [--canvas <id>] [--wait]\n assethub composer run --part <mesh-asset-id>=<part-image-id>... --reference <image-asset-id> --model V6 [--optimize off|light|medium|heavy] [--canvas <id>] [--wait]\n assethub composer run --part <mesh-asset-id>... --reference <image-asset-id> --model V5.1 [--reasoning low|medium|high] [--agent-model <agents-api model>] [--transforms-json <json|@file>] [--canvas <id>] [--wait]\n assethub composer run --input-json <json|@file> [--canvas <id>] [--operation-id <uuid>] [--wait] [--download --out-dir <dir>]\n assethub composer run --from-run <run-id> [--transforms-json <json|@file>] [--mode quick|quality] [--wait]\n assethub composer run --node <shape:id> --canvas <id> [--model <id>] [--mode quick|quality] [--operation-id <uuid>] [--wait]\n assethub canvas create [--name <name>] [--operation-id <uuid>]\n assethub canvas list [--cursor <cursor>] [--limit <n>]\n assethub canvas get|use|open [<id>]\n assethub canvas graph-id <canvas-id>\n assethub runs list [--canvas <id>] [--cursor <cursor>] [--limit <n>]\n assethub runs get|watch|wait <run-id> [--interval-ms <ms>] [--timeout-ms <n>] [--summary] [--download --out-dir <dir>]\n assethub runs resume <operation-id> [--wait]\n assethub graph list [--cursor <cursor>] [--limit <n>]\n assethub graph show|export [--canvas <id> | --graph <id>] [--source generated|upload] [--artifact <node-id>] [--out <path>] [--allow-truncated]\n assethub graph lineage --artifact <node-id> [--canvas <id> | --graph <id>] [--source generated|upload] [--direction ancestors|descendants|both] [--depth <n>] [--out <path>]\n assethub graph snapshot <graph-id> [--offset <n>] [--limit <n>]\n assethub graph node <graph-id> <node-id>\n assethub graph image <graph-id> <node-id> [--out <path>]\n assethub evaluate list\n assethub evaluations submit --artifact <asset-id> --report <json|file|@file|@-> [--agent <name>] [--canvas <id>] [--reference <asset-id>...] [--run <run-id>] [--operation-id <uuid>] [--require-pass]\n assethub evaluations list [--canvas <id>] [--artifact <asset-id>]\n assethub evaluations get <evaluation-id>\n assethub image generate --input-json <json|@file|@-> [--canvas <id>] [--operation-id <uuid>] [--agent <name>] [--derived-from-run <run-id>] [--from-node <graphId/nodeId> --graph-revision <rev>] [--wait]\n assethub mesh generate --input-json <json|@file|@-> [--canvas <id>] [--operation-id <uuid>] [--agent <name>] [--derived-from-run <run-id>] [--from-node <graphId/nodeId> --graph-revision <rev>] [--wait]\n assethub mesh generate --node <shape:id> --canvas <id> [--model-id <id>] [--params-json <json|@file>] [--operation-id <uuid>] [--wait]\n assethub mesh list [--query <text>] [--cursor <cursor>] [--limit <n>]\n assethub mesh get <mesh-asset-id>\n assethub mesh download <mesh-asset-id> --out-dir <directory>\n assethub image generate --prompt <text> [--file <path> | --source-url <url> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri> | --clipboard] [--file-name <name>] [--content-type <type>] [--model-id <id>] [--batch-size <n>] [--wait] [--download --out-dir <dir>] [--canvas <id>] [--operation-id <uuid>] [--api-version v2]\n assethub image generate --prompt <text> --source-resource-id <id> --api-version v2 [--model-id <id>] [--batch-size <n>] [--wait]\n assethub mesh generate (--file <path> | --source-url <url> | --source-resource-id <id> | --file-ref-json <json> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri>) [--file-name <name>] [--content-type <type>] [--model-id <id>] [--name <name>] [--wait] [--download --out-dir <dir>]\n assethub mesh retopo (--source-resource-id <id> | --source-url <url> | --file-ref-json <json> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri>) --model-id <id> [--file-name <name>] [--content-type <type>] [--wait] [--download --out-dir <dir>]\n assethub rig check (--file <path> | --source-url <url> | --source-resource-id <id> | --file-ref-json <json> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri>) [--name <name>] [--wait] [--download --out-dir <dir>]\n assethub rig create (--file <path> | --source-url <url> | --source-resource-id <id> | --file-ref-json <json> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri>) [--model v1.0-20240301|v2.5-20260210] [--rig-type biped|quadruped|hexapod|octopod|avian|serpentine|aquatic] [--spec tripo|mixamo] [--out-format glb|fbx] [--name <name>] [--wait] [--download --out-dir <dir>]\n assethub animate presets [--model v1.0-20240301|v2.5-20260210] [--rig-type <type>]\n assethub animate retarget --resource-id <id> --animation <preset-id> [--animation <preset-id>... up to 5 total] [--out-format glb|fbx] [--bake-animation true|false] [--export-with-geometry true|false] [--animate-in-place true|false] [--name <name>] [--wait] [--download --out-dir <dir>]\n assethub jobs get <job-id> [--download --out-dir <dir>]\n assethub jobs watch <job-id> [--interval-ms <ms>] [--timeout-ms <ms>] [--download --out-dir <dir>]\n assethub production analyze (--file <path> | --source-url <url> | --source-id <id> | --image-url <url> | --file-ref-json <json> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri> | --clipboard) [--file-name <name>] [--content-type <type>] [--part-extractor <name>] [--name <name>] [--base-body <mesh-asset-id>] [--skill-planner-model <model>] [--auto-repair true|false] [--skill-mode auto|manual|off] [--skill-id <id>...] [--context <canvas-id> --context-version <n>] [--wait] [--download --out-dir <dir>]\n Production graph options: --pipeline-depth parts|mesh|composition [--assembly-policy concept-to-character-v1] [--mesh-generation-json <json|@file>]\n assethub production batch (--file <path>... | --files-dir <dir> | --source-id <id>... | --source-url <url>...) --part-extractor <name> [--repeat <n>] [--yes] [--canvas <id>] [--operation-id <uuid>] [--wait [--concurrency <n>]] [--download --out-dir <dir>]\n One production analyze per image \u00D7 --repeat, on one canvas. Takes the production analyze options. Rerun with the printed --operation-id to resume; nothing is started twice.\n assethub production agents\n assethub production automation --input-json <json|@file|@-> [--canvas <id>] [--operation-id <uuid>] [--wait]\n assethub production status <order-id> [--wait] [--download --out-dir <dir>]\n assethub production execute --order-id <id> --mission-id <id> --task-id <id> [--task-id <id>...] [--part-extractor <name>] [--part-extraction-mode fast|high_quality] [--wait] [--download --out-dir <dir>]\n assethub production run --order-id <id> --mission-id <id> [--run-mode full_auto|approval] [--task-id <id>...] [--part-extractor <name>] [--part-extraction-mode fast|high_quality] [--allowed-model-id <id>...] [--max-iterations <n>] [--max-cost-credits <n>] [--wait] [--download --out-dir <dir>]\n assethub production run --image <file|asset-id> [--canvas <id>] [--part-extractor <name>] [--compose v6|none] [--mesh-model <id>] [--max-parts <n>] [--max-cost <credits>] [--estimate] [--wait] [--download --out-dir <dir>] [--json]\n assethub production watch <order-id> [--interval-ms <ms>] [--timeout-ms <ms>] [--download --out-dir <dir>]\n assethub production intervene <order-id> (--exclude <target-id> | --include <target-id> | --add-part <name> | --rename <target-id>=<name> | --reject <target-id>[=<reason>] | --regenerate <target-id>=<mode> | --set-param <key>=<value> | --ops-json <json|@file|@->)... [--idempotency-key <key>]\n assethub production interventions <order-id>\n assethub production resume <run-id|order-id> [--expected-resume-count <n>] [--wait] [--timeout-ms <ms>] [--download --out-dir <dir>] (after a fix, pick a stopped or stalled graph run back up; no new charge)\n assethub runs upload <path> [--graph-id <id>] [--stream-id <id>] [--rev <n>] [--description <text>] [--tag <tag>...] [--skip-register] [--dry-run]\n assethub parts split (--file <path> | --source-url <url> | --source-id <id> | --image-url <url> | --file-ref-json <json> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri> | --clipboard | --order-id <id>) [--file-name <name>] [--content-type <type>] [--part-extractor <name>] [--base-body <mesh-asset-id>] [--skill-planner-model <model>] [--auto-repair true|false] [--skill-mode auto|manual|off] [--skill-id <id>...] [--wait] [--task-id <id>...] [--mission-id <id>] [--all-ready] [--download --out-dir <dir>]\n assethub parts compare (--file <path> | --source-url <url> | --source-id <id> | --image-url <url> | --file-ref-json <json> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri> | --clipboard) [--file-name <name>] [--content-type <type>] [--preprocess-prompt <text>] [--preprocess-model-id <id>] [--fail-on-preprocess-error] [--part-extractor <name>] [--wait] [--task-id <id>...] [--mission-id <id>] [--all-ready] [--download --out-dir <dir>]\n assethub autopilot [<image>] --demo [--yolo] [--json] [--max-regen <n>] [--stall-rounds <n>] [--tie-epsilon <x>] [--multiview 2-view|4-view|6-view] [--ab-mode serial|cross] [--credit-budget <n>]\n assethub memory memorize --canvas <id> [--nodes <shape-id>,<shape-id>,...] [--wait] [--timeout <s>]\n assethub memory replay <memory-id> --source <asset-id> [--wait] [--timeout <s>]\n assethub skills list [--cursor <cursor>]\n assethub skills get <skill-id> [--revision <n>]\n assethub skills memory <skill-id> [--revision <n>] [--images <dir>]\n assethub skills learn --input-json <json|@file|@-> --operation-id <uuid>\n assethub skills update <skill-id> --input-json <json|@file|@->\n assethub skills controls <skill-id> --revision <n> --grant-revision <n> --mode automatic|manual|off [--share]\n assethub skills prepare --input-json <json|@file|@->\n assethub skills proposal <proposal-id>\n assethub skills accept <proposal-id> --input-json <json|@file|@->\n assethub skills validate --input-json <json|@file|@-> [--build <build-id>]\n assethub skills schema\n assethub skills build --goal <text> (--canvas <id>... | --memory <id>...) [--instructions <text>] [--operation-id <uuid>] [--wait] [--dry-run]\n assethub skills official list\n assethub skills official install <skill-id> --revision <n> --content-sha256 <sha256> [--expected-revision <n>] [--expected-grant-revision <n>]\n assethub skills official prepare <skill-id> --input-json <json|@file|@->\n assethub skills official customize <skill-id> --input-json <json|@file|@->\n assethub org search <query>\n assethub org canvases --org <orgId>\n assethub graph export-canvas --org <orgId> --canvas <id>[,<id>...] [--wait] [--timeout <s>] [--out-dir <dir>]\n\nGlobal options:\n --api-key <key> Overrides saved auth and ASSETHUB_API_KEY.\n --base-url <url> Override the selected API origin. Default: https://app.assethub.io.\n --profile <name> Select this saved profile ahead of environment credentials and origin.\n --workspace <id> Select workspace scope for this command without changing saved selection.\n --config <path> Auth config path. Defaults to ~/.assethub/config.json.\n --version Show installed package version.\n --help Show help.\n\nExamples:\n ASSETHUB_API_KEY=ah_live_xxx assethub models list\n assethub auth login --api-key-stdin\n assethub init --dry-run\n assethub models list --ids-only\n assethub files upload ./input.png --media-type image\n assethub source create --file ./input.png --media-type image\n pbpaste | assethub source create --stdin-data-uri --media-type image\n assethub source create --clipboard --media-type image --file-name clipboard.png\n printf '{\"image_url\":{\"url\":\"data:image/png;base64,...\"}}' | assethub parts split --stdin-json --part-extractor \"V1.5\" --wait\n base64 -i ./input.png | assethub parts split --stdin-base64 --file-name input.png --content-type image/png --part-extractor \"V1.5\" --wait\n cat ./input.png | assethub parts split --stdin --file-name input.png --part-extractor \"V1.5\" --wait\n assethub image generate --prompt \"stylized prop concept\" --wait\n assethub mesh generate --file ./input.png --wait\n assethub animate presets --rig-type biped\n assethub rig create --source-resource-id mesh_x --rig-type biped --wait\n assethub animate retarget --resource-id rig_x --animation preset:idle --wait\n assethub production analyze --file ./input.png --part-extractor \"V1.5\" --wait\n assethub production analyze --file ./concept.png --part-extractor v4 --wait --download --out-dir ./character\n assethub production batch --file ./harpy.png --file ./satyr.png --repeat 2 --part-extractor v4 --yes --wait --download --out-dir ./batch\n assethub production run --order-id ord_x --mission-id ms_x --run-mode full_auto --max-cost-credits 200 --wait\n assethub production run --image ./character.png --estimate\n assethub production run --image ./character.png --compose v6 --max-cost 500 --wait --download --out-dir ./out/asset\n assethub production watch ord_x\n assethub runs get run_x --summary\n assethub runs wait run_x --timeout-ms 3600000\n assethub production intervene ord_x --exclude 7 --rename 3=\"left wing\" --idempotency-key review-2026-07-29\n assethub production interventions ord_x\n assethub production resume ord_x\n assethub production resume <run-id> --wait --download --out-dir ./character\n assethub runs upload ./out/pluffy-run-2026-07-30 --dry-run\n assethub runs upload ./out/pluffy-run-2026-07-30 --tag pluffy --description \"V3 humanoid, 18 parts\"\n assethub parts split --file ./input.png --part-extractor \"V1.5\" --wait --all-ready\n assethub parts compare --file ./input.png --preprocess-prompt \"clean white background, centered product photo\" --part-extractor \"V1.5\" --wait --all-ready\n";
|
|
27
|
-
export declare const commandSetup: (flags: Flags, installHooks?: InstallHooks
|
|
27
|
+
export declare const usage = "AssetHub CLI\n\nCLI and MCP are available to all AssetHub users. Workspace permissions and feature availability apply.\n\nUsage:\n assethub --version\n assethub setup [--agent claude-code|codex|cursor...] [--project] [--only <step,...>] [--skip <step,...>] [--no-skills] [--no-auto-update | --auto-update] [--profile <name>] [--workspace <id>] [--api-key-stdin] [--base-url <url>] [--no-app-env] [--dry-run] [--yes] [--print-env] [--json]\n assethub env load [--profile <name>]\n assethub update [--check] [--dry-run] [--yes] (once a day a newer version installs itself in the background; turn off: setup --no-auto-update or ASSETHUB_NO_AUTO_UPDATE=1)\n assethub doctor [--mcp] [--setup [--agent <name>...] [--project]] [--profile <name>] [--timeout-ms <n>]\n assethub mcp tools [tool-name] [--account] [--profile <name>] [--timeout-ms <n>]\n assethub mcp config --client cursor|codex [--account] [--base-url <url>]\n assethub auth login --api-key <key> [--base-url <url>] [--profile <name>]\n assethub auth login --api-key-stdin [--base-url <url>] [--profile <name>]\n assethub auth login --access-token-stdin [--base-url <url>] [--profile <name>]\n assethub auth status [--profile <name>]\n assethub auth logout [--profile <name>]\n assethub workspace list [--query <text>] [--limit <1-100>] [--cursor <cursor>]\n assethub workspace get\n assethub workspace create --name <name> [--operation-id <uuid>]\n assethub workspace use <workspace-id>\n assethub workspace members [--workspace <id>]\n assethub workspace invite --email <email> [--role user|admin] [--resend] [--workspace <id>]\n assethub workspace set-role <user-id> --role user|admin [--workspace <id>]\n assethub workspace remove-member <user-id> [--workspace <id>]\n assethub workspace prepare|sync|analyze|verify --internal --manifest <json> --state <json>\n assethub workspace self-check --internal\n assethub workspace context put --internal --org <uuid> --actor <uuid> --canvas <id> --file <json> [--if-version <n>] [--order <uuid>]\n assethub workspace context get --internal --org <uuid> --actor <uuid> --canvas <id> [--out <json>] [--order <uuid>]\n assethub project ingest <source-dir> --out-dir <directory> [--exclude-dir <relative-path>...]\n assethub language text|vision --input-json @<json> --operation-id <uuid> [--out <json>]\n assethub canvas download --canvas <id> --out-dir <directory> [--mesh <mesh_asset_id>]\n assethub canvas nodes --canvas <id>\n assethub canvas import --canvas <id> --file <image> [--name <name>]\n assethub canvas context get --canvas <id> [--out <json>]\n assethub canvas context put --canvas <id> --file <json> [--if-version <n>]\n assethub canvas layout --canvas <id> --input-json @<json>\n assethub canvas compare --canvas <id> --source-id <asset-id> --asset-id <asset-id> --out <html>\n assethub moodboard create --input-json @<json> [--operation-id <uuid>]\n assethub moodboard list|get|update|archive [<board-id>] [--input-json @<json>]\n assethub moodboard analyze <board-id> [--revision <uuid>] [--wait]\n assethub image generate --canvas <id> --context <id> [--context-version <n>] [--context-source <key>] [--moodboard-revision <uuid>] --prompt <text> --wait\n assethub models list [--domain <domain>] [--ids-only] [--limit <n>]\n assethub models get <model-id>\n assethub files import <url> --media-type image|mesh\n assethub files upload <file> --media-type image|mesh\n assethub source create (--file <path> | --source-url <url> | --source-id <id> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri> | --clipboard) --media-type image|mesh [--file-name <name>] [--content-type <type>]\n assethub capabilities\n assethub api search [query]\n assethub api describe \"<METHOD /path>\"\n assethub api call \"<METHOD /path>\" [--path-json <json|@file>] [--query-json <json|@file>] [--input-json <json|@file|@->] [--operation-id <uuid>]\n assethub composer models\n assethub composer refine --list-modes\n assethub composer refine --from-run <run-id> --instruction <text> [--mode standard|thorough|placement|workshop|blender|codex] [--effort light|standard|thorough] [--max-rounds <n>] [--agent-model <provider:id|unambiguous-id>] [--transforms-json <json|@file>] [--wait] [--download --out-dir <dir>]\n assethub composer refine --input-json <json|@file> [--canvas <id>] [--operation-id <uuid>] [--wait] [--download --out-dir <dir>]\n assethub composer refine --from-run <run-id> --skill-assembly [--reasoning low|medium|high] [--agent-model <agents-api model>] [--wait]\n assethub composer run --part <mesh-asset-id>[=<part-image-id>] [--part <mesh-asset-id>[=<part-image-id>]...] --reference <image-asset-id> [--model <id>] [--agent-model <provider:id|unambiguous-id>] [--mode quick|quality] [--optimize off|light|medium|heavy] [--transforms-json <json|@file>] [--canvas <id>] [--wait]\n assethub composer run --part <mesh-asset-id>=<part-image-id>... --reference <image-asset-id> --model V6 [--optimize off|light|medium|heavy] [--canvas <id>] [--wait]\n assethub composer run --part <mesh-asset-id>... --reference <image-asset-id> --model V5.1 [--reasoning low|medium|high] [--agent-model <agents-api model>] [--transforms-json <json|@file>] [--canvas <id>] [--wait]\n assethub composer run --input-json <json|@file> [--canvas <id>] [--operation-id <uuid>] [--wait] [--download --out-dir <dir>]\n assethub composer run --from-run <run-id> [--transforms-json <json|@file>] [--mode quick|quality] [--wait]\n assethub composer run --node <shape:id> --canvas <id> [--model <id>] [--mode quick|quality] [--operation-id <uuid>] [--wait]\n assethub canvas create [--name <name>] [--operation-id <uuid>]\n assethub canvas list [--cursor <cursor>] [--limit <n>]\n assethub canvas get|use|open [<id>]\n assethub canvas graph-id <canvas-id>\n assethub runs list [--canvas <id>] [--cursor <cursor>] [--limit <n>]\n assethub runs get|watch|wait <run-id> [--interval-ms <ms>] [--timeout-ms <n>] [--summary] [--download --out-dir <dir>]\n assethub runs resume <operation-id> [--wait]\n assethub graph list [--cursor <cursor>] [--limit <n>]\n assethub graph show|export [--canvas <id> | --graph <id>] [--source generated|upload] [--artifact <node-id>] [--out <path>] [--allow-truncated]\n assethub graph lineage --artifact <node-id> [--canvas <id> | --graph <id>] [--source generated|upload] [--direction ancestors|descendants|both] [--depth <n>] [--out <path>]\n assethub graph snapshot <graph-id> [--offset <n>] [--limit <n>]\n assethub graph node <graph-id> <node-id>\n assethub graph image <graph-id> <node-id> [--out <path>]\n assethub evaluate list\n assethub evaluations submit --artifact <asset-id> --report <json|file|@file|@-> [--agent <name>] [--canvas <id>] [--reference <asset-id>...] [--run <run-id>] [--operation-id <uuid>] [--require-pass]\n assethub evaluations list [--canvas <id>] [--artifact <asset-id>]\n assethub evaluations get <evaluation-id>\n assethub image generate --input-json <json|@file|@-> [--canvas <id>] [--operation-id <uuid>] [--agent <name>] [--derived-from-run <run-id>] [--from-node <graphId/nodeId> --graph-revision <rev>] [--wait]\n assethub mesh generate --input-json <json|@file|@-> [--canvas <id>] [--operation-id <uuid>] [--agent <name>] [--derived-from-run <run-id>] [--from-node <graphId/nodeId> --graph-revision <rev>] [--wait]\n assethub mesh generate --node <shape:id> --canvas <id> [--model-id <id>] [--params-json <json|@file>] [--operation-id <uuid>] [--wait]\n assethub mesh list [--query <text>] [--cursor <cursor>] [--limit <n>]\n assethub mesh get <mesh-asset-id>\n assethub mesh download <mesh-asset-id> --out-dir <directory>\n assethub image generate --prompt <text> [--file <path> | --source-url <url> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri> | --clipboard] [--file-name <name>] [--content-type <type>] [--model-id <id>] [--batch-size <n>] [--wait] [--download --out-dir <dir>] [--canvas <id>] [--operation-id <uuid>] [--api-version v2]\n assethub image generate --prompt <text> --source-resource-id <id> --api-version v2 [--model-id <id>] [--batch-size <n>] [--wait]\n assethub mesh generate (--file <path> | --source-url <url> | --source-resource-id <id> | --file-ref-json <json> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri>) [--file-name <name>] [--content-type <type>] [--model-id <id>] [--name <name>] [--wait] [--download --out-dir <dir>]\n assethub mesh retopo (--source-resource-id <id> | --source-url <url> | --file-ref-json <json> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri>) --model-id <id> [--file-name <name>] [--content-type <type>] [--wait] [--download --out-dir <dir>]\n assethub rig check (--file <path> | --source-url <url> | --source-resource-id <id> | --file-ref-json <json> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri>) [--name <name>] [--wait] [--download --out-dir <dir>]\n assethub rig create (--file <path> | --source-url <url> | --source-resource-id <id> | --file-ref-json <json> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri>) [--model v1.0-20240301|v2.5-20260210] [--rig-type biped|quadruped|hexapod|octopod|avian|serpentine|aquatic] [--spec tripo|mixamo] [--out-format glb|fbx] [--name <name>] [--wait] [--download --out-dir <dir>]\n assethub animate presets [--model v1.0-20240301|v2.5-20260210] [--rig-type <type>]\n assethub animate retarget --resource-id <id> --animation <preset-id> [--animation <preset-id>... up to 5 total] [--out-format glb|fbx] [--bake-animation true|false] [--export-with-geometry true|false] [--animate-in-place true|false] [--name <name>] [--wait] [--download --out-dir <dir>]\n assethub jobs get <job-id> [--download --out-dir <dir>]\n assethub jobs watch <job-id> [--interval-ms <ms>] [--timeout-ms <ms>] [--download --out-dir <dir>]\n assethub production analyze (--file <path> | --source-url <url> | --source-id <id> | --image-url <url> | --file-ref-json <json> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri> | --clipboard) [--file-name <name>] [--content-type <type>] [--part-extractor <name>] [--name <name>] [--base-body <mesh-asset-id>] [--skill-planner-model <model>] [--auto-repair true|false] [--skill-mode auto|manual|off] [--skill-id <id>...] [--context <canvas-id> --context-version <n>] [--wait] [--download --out-dir <dir>]\n Production graph options: --pipeline-depth parts|mesh|composition [--assembly-policy concept-to-character-v1] [--mesh-generation-json <json|@file>]\n assethub production batch (--file <path>... | --files-dir <dir> | --source-id <id>... | --source-url <url>...) --part-extractor <name> [--repeat <n>] [--yes] [--canvas <id>] [--operation-id <uuid>] [--wait [--concurrency <n>]] [--download --out-dir <dir>]\n One production analyze per image \u00D7 --repeat, on one canvas. Takes the production analyze options. Rerun with the printed --operation-id to resume; nothing is started twice.\n assethub production agents\n assethub production automation --input-json <json|@file|@-> [--canvas <id>] [--operation-id <uuid>] [--wait]\n assethub production status <order-id> [--wait] [--download --out-dir <dir>]\n assethub production execute --order-id <id> --mission-id <id> --task-id <id> [--task-id <id>...] [--part-extractor <name>] [--part-extraction-mode fast|high_quality] [--wait] [--download --out-dir <dir>]\n assethub production run --order-id <id> --mission-id <id> [--run-mode full_auto|approval] [--task-id <id>...] [--part-extractor <name>] [--part-extraction-mode fast|high_quality] [--allowed-model-id <id>...] [--max-iterations <n>] [--max-cost-credits <n>] [--wait] [--download --out-dir <dir>]\n assethub production run --image <file|asset-id> [--canvas <id>] [--part-extractor <name>] [--compose v6|none] [--mesh-model <id>] [--max-parts <n>] [--max-cost <credits>] [--estimate] [--wait] [--download --out-dir <dir>] [--json]\n assethub production watch <order-id> [--interval-ms <ms>] [--timeout-ms <ms>] [--download --out-dir <dir>]\n assethub production intervene <order-id> (--exclude <target-id> | --include <target-id> | --add-part <name> | --rename <target-id>=<name> | --reject <target-id>[=<reason>] | --regenerate <target-id>=<mode> | --set-param <key>=<value> | --ops-json <json|@file|@->)... [--idempotency-key <key>]\n assethub production interventions <order-id>\n assethub production resume <run-id|order-id> [--expected-resume-count <n>] [--wait] [--timeout-ms <ms>] [--download --out-dir <dir>] (after a fix, pick a stopped or stalled graph run back up; no new charge)\n assethub runs upload <path> [--graph-id <id>] [--stream-id <id>] [--rev <n>] [--description <text>] [--tag <tag>...] [--skip-register] [--dry-run]\n assethub parts split (--file <path> | --source-url <url> | --source-id <id> | --image-url <url> | --file-ref-json <json> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri> | --clipboard | --order-id <id>) [--file-name <name>] [--content-type <type>] [--part-extractor <name>] [--base-body <mesh-asset-id>] [--skill-planner-model <model>] [--auto-repair true|false] [--skill-mode auto|manual|off] [--skill-id <id>...] [--wait] [--task-id <id>...] [--mission-id <id>] [--all-ready] [--download --out-dir <dir>]\n assethub parts compare (--file <path> | --source-url <url> | --source-id <id> | --image-url <url> | --file-ref-json <json> | --stdin | --stdin-base64 | --stdin-data-uri | --stdin-json | --source-json <json|@file|@-> | --data-uri <uri> | --clipboard) [--file-name <name>] [--content-type <type>] [--preprocess-prompt <text>] [--preprocess-model-id <id>] [--fail-on-preprocess-error] [--part-extractor <name>] [--wait] [--task-id <id>...] [--mission-id <id>] [--all-ready] [--download --out-dir <dir>]\n assethub autopilot [<image>] --demo [--yolo] [--json] [--max-regen <n>] [--stall-rounds <n>] [--tie-epsilon <x>] [--multiview 2-view|4-view|6-view] [--ab-mode serial|cross] [--credit-budget <n>]\n assethub memory memorize --canvas <id> [--nodes <shape-id>,<shape-id>,...] [--wait] [--timeout <s>]\n assethub memory replay <memory-id> --source <asset-id> [--wait] [--timeout <s>]\n assethub skills list [--cursor <cursor>]\n assethub skills get <skill-id> [--revision <n>]\n assethub skills memory <skill-id> [--revision <n>] [--images <dir>]\n assethub skills learn --input-json <json|@file|@-> --operation-id <uuid>\n assethub skills update <skill-id> --input-json <json|@file|@->\n assethub skills controls <skill-id> --revision <n> --grant-revision <n> --mode automatic|manual|off [--share]\n assethub skills prepare --input-json <json|@file|@->\n assethub skills proposal <proposal-id>\n assethub skills accept <proposal-id> --input-json <json|@file|@->\n assethub skills validate --input-json <json|@file|@-> [--build <build-id>]\n assethub skills schema\n assethub skills build --goal <text> (--canvas <id>... | --memory <id>...) [--instructions <text>] [--operation-id <uuid>] [--wait] [--dry-run]\n assethub skills official list\n assethub skills official install <skill-id> --revision <n> --content-sha256 <sha256> [--expected-revision <n>] [--expected-grant-revision <n>]\n assethub skills official prepare <skill-id> --input-json <json|@file|@->\n assethub skills official customize <skill-id> --input-json <json|@file|@->\n assethub org search <query>\n assethub org canvases --org <orgId>\n assethub graph export-canvas --org <orgId> --canvas <id>[,<id>...] [--wait] [--timeout <s>] [--out-dir <dir>]\n\nGlobal options:\n --api-key <key> Overrides saved auth and ASSETHUB_API_KEY.\n --base-url <url> Override the selected API origin. Default: https://app.assethub.io.\n --profile <name> Select this saved profile ahead of environment credentials and origin.\n --workspace <id> Select workspace scope for this command without changing saved selection.\n --config <path> Auth config path. Defaults to ~/.assethub/config.json.\n --version Show installed package version.\n --help Show help.\n\nExamples:\n ASSETHUB_API_KEY=ah_live_xxx assethub models list\n assethub auth login --api-key-stdin\n assethub setup --dry-run\n assethub setup --only skills --project\n assethub models list --ids-only\n assethub files upload ./input.png --media-type image\n assethub source create --file ./input.png --media-type image\n pbpaste | assethub source create --stdin-data-uri --media-type image\n assethub source create --clipboard --media-type image --file-name clipboard.png\n printf '{\"image_url\":{\"url\":\"data:image/png;base64,...\"}}' | assethub parts split --stdin-json --part-extractor \"V1.5\" --wait\n base64 -i ./input.png | assethub parts split --stdin-base64 --file-name input.png --content-type image/png --part-extractor \"V1.5\" --wait\n cat ./input.png | assethub parts split --stdin --file-name input.png --part-extractor \"V1.5\" --wait\n assethub image generate --prompt \"stylized prop concept\" --wait\n assethub mesh generate --file ./input.png --wait\n assethub animate presets --rig-type biped\n assethub rig create --source-resource-id mesh_x --rig-type biped --wait\n assethub animate retarget --resource-id rig_x --animation preset:idle --wait\n assethub production analyze --file ./input.png --part-extractor \"V1.5\" --wait\n assethub production analyze --file ./concept.png --part-extractor v4 --wait --download --out-dir ./character\n assethub production batch --file ./harpy.png --file ./satyr.png --repeat 2 --part-extractor v4 --yes --wait --download --out-dir ./batch\n assethub production run --order-id ord_x --mission-id ms_x --run-mode full_auto --max-cost-credits 200 --wait\n assethub production run --image ./character.png --estimate\n assethub production run --image ./character.png --compose v6 --max-cost 500 --wait --download --out-dir ./out/asset\n assethub production watch ord_x\n assethub runs get run_x --summary\n assethub runs wait run_x --timeout-ms 3600000\n assethub production intervene ord_x --exclude 7 --rename 3=\"left wing\" --idempotency-key review-2026-07-29\n assethub production interventions ord_x\n assethub production resume ord_x\n assethub production resume <run-id> --wait --download --out-dir ./character\n assethub runs upload ./out/pluffy-run-2026-07-30 --dry-run\n assethub runs upload ./out/pluffy-run-2026-07-30 --tag pluffy --description \"V3 humanoid, 18 parts\"\n assethub parts split --file ./input.png --part-extractor \"V1.5\" --wait --all-ready\n assethub parts compare --file ./input.png --preprocess-prompt \"clean white background, centered product photo\" --part-extractor \"V1.5\" --wait --all-ready\n";
|
|
28
|
+
export declare const commandSetup: (flags: Flags, installHooks?: InstallHooks, overrides?: {
|
|
29
|
+
skip?: SetupStepName[];
|
|
30
|
+
}) => Promise<void>;
|
|
28
31
|
/**
|
|
29
32
|
* The `animate retarget` request, built from flags alone.
|
|
30
33
|
*
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAgBA,OAAO,EAYL,KAAK,aAAa,EACnB,MAAM,mBAAmB,CAAA;AAE1B,OAAO,EAAsB,KAAK,YAAY,EAAC,MAAM,uBAAuB,CAAA;AA0D5E,OAAO,EAIL,KAAK,wBAAwB,EAS7B,KAAK,YAAY,EAEjB,KAAK,UAAU,EAkBf,oBAAoB,EACrB,MAAM,sBAAsB,CAAA;AAc7B,OAAO,EAAC,kBAAkB,EAAc,MAAM,gCAAgC,CAAA;AAqB9E,KAAK,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,CAAC,CAAA;AAuBxD,KAAK,YAAY,GAAG;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,cAAc,CAAC,EAAE,UAAU,CAAA;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAAA;CACnC,CAAA;AAED,KAAK,cAAc,GAAG;IACpB,MAAM,EAAE,UAAU,CAAC,OAAO,oBAAoB,CAAC,CAAA;IAC/C,KAAK,EAAE,KAAK,CAAA;IACZ,IAAI,EAAE,YAAY,CAAA;IAClB;;;;;OAKG;IACH,IAAI,EAAE,MAAM,EAAE,CAAA;CACf,CAAA;AAsOD,eAAO,MAAM,KAAK,qolBAmLjB,CAAA;AAmjED,eAAO,MAAM,YAAY,GACvB,OAAO,KAAK,EACZ,eAAc,YAAkC,EAChD,YAAW;IAAC,IAAI,CAAC,EAAE,aAAa,EAAE,CAAA;CAAM,KACvC,OAAO,CAAC,IAAI,CAWd,CAAA;AA+qCD;;;;;;GAMG;AACH,eAAO,MAAM,6BAA6B,GACxC,OAAO,KAAK,KACX,wBA0BF,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,GAChC,OAAO,KAAK,KACX,IAAI,CAAC,UAAU,EAAE,QAAQ,CAM1B,CAAA;AA6fF;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,uBAAuB,GAClC,MAAM,SAAS,MAAM,EAAE,KACtB,YAAY,EAuGd,CAAA;AAigDD,eAAO,MAAM,YAAY,GACvB,YAAY,MAAM,GAAG,SAAS,EAC9B,aAAa,MAAM,EAAE,EACrB,KAAK,cAAc,kBAiGpB,CAAA;AAgLD,MAAM,MAAM,cAAc,GAAG;IAC3B,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAA;IAC5B,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;IACvB,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,MAAM,EAAE,OAAO,CAAA;IACf,YAAY,EAAE,OAAO,CAAA;CACtB,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAC9B,YAAY,MAAM,GAAG,SAAS,EAC9B,aAAa,MAAM,EAAE,EACrB,OAAO,KAAK,KACX,cAoBF,CAAA;AAED,KAAK,iBAAiB,GAAG,IAAI,CAC3B,OAAO,CAAC,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAC,EAC5C,SAAS,GACT,UAAU,GACV,KAAK,GACL,WAAW,GACX,QAAQ,GACR,OAAO,GACP,OAAO,GACP,UAAU,CACb,CAAA;AAED,eAAO,MAAM,iBAAiB,GAC5B,WAAW,MAAM,EACjB,MAAM,iBAAiB;;;;;;;;;;;;;;CAUvB,CAAA;AAEF,eAAO,MAAM,sBAAsB,GACjC,SAAS,UAAU,CAAC,OAAO,iBAAiB,CAAC,EAC7C,MAAM,iBAAiB,EACvB,SAAS,MAAM;;;;;;;;;;;;;;;;;;;;;;;CAYf,CAAA;AAyaF,eAAO,MAAM,aAAa,GACxB,YAAY,MAAM,GAAG,SAAS,EAC9B,aAAa,MAAM,EAAE,EACrB,KAAK,cAAc,KAClB,OAAO,CAAC,IAAI,CAwCd,CAAA;AA4SD,eAAO,MAAM,aAAa,GACxB,YAAY,MAAM,GAAG,SAAS,EAC9B,aAAa,MAAM,EAAE,EACrB,KAAK,cAAc,KAClB,OAAO,CAAC,IAAI,CA2Xd,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,UAAU,GACrB,YAAY,MAAM,GAAG,SAAS,EAC9B,aAAa,MAAM,EAAE,EACrB,KAAK,cAAc,KAClB,OAAO,CAAC,IAAI,CA4Bd,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
import { childOperationId, expandProductionBatch, planProductionNodeMeshes, callApiOperation, describeApiOperation, discoverApiOperations, searchApiOperations, TERMINAL_WORKSPACE_SKILL_BUILD_STATUSES, WORKSPACE_SKILL_ENHANCE_SECTIONS, } from '@assethub/api-client';
|
|
3
3
|
import { setTimeout as delay } from 'node:timers/promises';
|
|
4
4
|
import { cliVersion, diagnose, mcpConfig } from './setup.js';
|
|
5
|
-
import { AGENT_IDS,
|
|
6
|
-
import { confirmNo, confirmYes, defaultFileDeps, formatSetupSummary, pickFromList, promptHidden, runProcess, runSetup, } from './setupCommand.js';
|
|
5
|
+
import { AGENT_IDS, parseAgentIds, syncInstalledSkill } from './agentSetup.js';
|
|
6
|
+
import { confirmNo, confirmYes, defaultFileDeps, formatSetupSummary, pickFromList, promptHidden, runProcess, runSetup, SETUP_STEPS, } from './setupCommand.js';
|
|
7
7
|
import { launchAgentProgram, loadKeyIntoLaunchd } from './appEnv.js';
|
|
8
8
|
import { defaultInstallHooks } from './setupHooksBridge.js';
|
|
9
9
|
import { canUploadSessions, installHooks as installSessionHooks, runHooksCommand } from './hooks/index.js';
|
|
10
10
|
import { createNodeUpdateDeps, runUpdate } from './update.js';
|
|
11
|
+
import { autoUpdateEnabled, claimRefreshAttempt, decideUpdateNotice, isInstalledPackage, patchUpdateCheck, readAutoUpdateSetting, readUpdateCheck, REFRESH_CHILD_ENV, refreshInBackground, refreshUpdateCheck, settingsPath, takeLock, updateCheckDisabled, updateCheckPath, writeAutoUpdateSetting, writeUpdateCheck, } from './updateNotice.js';
|
|
11
12
|
import { ingestProjectSources } from './projectSources.js';
|
|
12
13
|
import { downloadCanvas } from './canvasDownload.js';
|
|
13
14
|
import { downloadCanvasGraphZip } from './canvasGraphDownload.js';
|
|
@@ -18,7 +19,7 @@ import { importCanvasAssetWithState } from './canvasAssetImport.js';
|
|
|
18
19
|
import { execFile, spawn } from 'node:child_process';
|
|
19
20
|
import { createHash, randomUUID } from 'node:crypto';
|
|
20
21
|
import { realpathSync } from 'node:fs';
|
|
21
|
-
import { chmod, mkdir, readdir, readFile, rename, unlink, writeFile, } from 'node:fs/promises';
|
|
22
|
+
import { chmod, mkdir, readdir, readFile, rename, rm, unlink, writeFile, } from 'node:fs/promises';
|
|
22
23
|
import { homedir, tmpdir } from 'node:os';
|
|
23
24
|
import { basename, dirname, extname, join, resolve } from 'node:path';
|
|
24
25
|
import { argv, env, exit, stdin, stderr, stdout } from 'node:process';
|
|
@@ -222,11 +223,10 @@ CLI and MCP are available to all AssetHub users. Workspace permissions and featu
|
|
|
222
223
|
|
|
223
224
|
Usage:
|
|
224
225
|
assethub --version
|
|
225
|
-
assethub setup [--
|
|
226
|
+
assethub setup [--agent claude-code|codex|cursor...] [--project] [--only <step,...>] [--skip <step,...>] [--no-skills] [--no-auto-update | --auto-update] [--profile <name>] [--workspace <id>] [--api-key-stdin] [--base-url <url>] [--no-app-env] [--dry-run] [--yes] [--print-env] [--json]
|
|
226
227
|
assethub env load [--profile <name>]
|
|
227
|
-
assethub update [--check] [--dry-run] [--yes]
|
|
228
|
-
assethub doctor [--mcp] [--profile <name>] [--timeout-ms <n>]
|
|
229
|
-
assethub init [--agent claude-code|codex|cursor...] [--project] [--dry-run] [--base-url <url>] [--workspace <id>] [--profile <name>]
|
|
228
|
+
assethub update [--check] [--dry-run] [--yes] (once a day a newer version installs itself in the background; turn off: setup --no-auto-update or ASSETHUB_NO_AUTO_UPDATE=1)
|
|
229
|
+
assethub doctor [--mcp] [--setup [--agent <name>...] [--project]] [--profile <name>] [--timeout-ms <n>]
|
|
230
230
|
assethub mcp tools [tool-name] [--account] [--profile <name>] [--timeout-ms <n>]
|
|
231
231
|
assethub mcp config --client cursor|codex [--account] [--base-url <url>]
|
|
232
232
|
assethub auth login --api-key <key> [--base-url <url>] [--profile <name>]
|
|
@@ -364,7 +364,8 @@ Global options:
|
|
|
364
364
|
Examples:
|
|
365
365
|
ASSETHUB_API_KEY=ah_live_xxx assethub models list
|
|
366
366
|
assethub auth login --api-key-stdin
|
|
367
|
-
assethub
|
|
367
|
+
assethub setup --dry-run
|
|
368
|
+
assethub setup --only skills --project
|
|
368
369
|
assethub models list --ids-only
|
|
369
370
|
assethub files upload ./input.png --media-type image
|
|
370
371
|
assethub source create --file ./input.png --media-type image
|
|
@@ -1906,11 +1907,41 @@ const commandAuth = async (subcommand, flags) => {
|
|
|
1906
1907
|
};
|
|
1907
1908
|
// One-command onboarding. Login and workspace selection reuse commandAuth and
|
|
1908
1909
|
// commandWorkspace (their JSON output is suppressed); setupCommand.ts owns the
|
|
1909
|
-
//
|
|
1910
|
-
|
|
1911
|
-
const
|
|
1912
|
-
|
|
1913
|
-
|
|
1910
|
+
// steps, the agent configuration and the summary.
|
|
1911
|
+
const parseSetupSelection = (flags) => {
|
|
1912
|
+
const agentValues = getFlagValues(flags, 'agent').map(value => assertFlagHasValue(value, '--agent <name>'));
|
|
1913
|
+
let agents = agentValues.length > 0 ? parseAgentIds(agentValues) : undefined;
|
|
1914
|
+
if (!agents && hasFlag(flags, 'client')) {
|
|
1915
|
+
// Older spelling: --client claude|codex|both.
|
|
1916
|
+
const client = getFlag(flags, 'client');
|
|
1917
|
+
if (client !== 'claude' && client !== 'codex' && client !== 'both')
|
|
1918
|
+
throw new Error('--client must be claude, codex or both (use --agent claude-code|codex|cursor)');
|
|
1919
|
+
agents = client === 'both' ? ['claude-code', 'codex'] : parseAgentIds([client]);
|
|
1920
|
+
}
|
|
1921
|
+
const stepValues = (name) => getFlagValues(flags, name)
|
|
1922
|
+
.map(value => assertFlagHasValue(value, `--${name} <step>`))
|
|
1923
|
+
.flatMap(value => value.split(','))
|
|
1924
|
+
.map(value => value.trim())
|
|
1925
|
+
.filter(Boolean);
|
|
1926
|
+
const known = (name, values) => {
|
|
1927
|
+
const unknown = values.filter(value => !SETUP_STEPS.includes(value));
|
|
1928
|
+
if (unknown.length > 0)
|
|
1929
|
+
throw new Error(`Unknown setup step for --${name}: ${unknown.join(', ')}. Steps: login, workspace, mcp, skills, auto-update, app-env, doctor.`);
|
|
1930
|
+
return values;
|
|
1931
|
+
};
|
|
1932
|
+
const only = known('only', stepValues('only'));
|
|
1933
|
+
const skip = new Set(known('skip', stepValues('skip')));
|
|
1934
|
+
if (only.length > 0)
|
|
1935
|
+
for (const step of SETUP_STEPS)
|
|
1936
|
+
if (!only.includes(step))
|
|
1937
|
+
skip.add(step);
|
|
1938
|
+
if (hasFlag(flags, 'no-skills'))
|
|
1939
|
+
skip.add('skills');
|
|
1940
|
+
return { agents, skip: SETUP_STEPS.filter(step => skip.has(step)) };
|
|
1941
|
+
};
|
|
1942
|
+
/** The `runSetup` options and real dependencies for these flags; `setup`, `init` and `doctor --setup` share them. */
|
|
1943
|
+
const setupRun = async (flags, installHooks, overrides = {}) => {
|
|
1944
|
+
const selection = parseSetupSelection(flags);
|
|
1914
1945
|
const config = await readAuthConfig(getConfigPath(flags));
|
|
1915
1946
|
// Only name a profile the user chose or one that is saved: a synthetic profile
|
|
1916
1947
|
// would make resolveAuth reject a fresh machine before its ASSETHUB_API_KEY fallback.
|
|
@@ -1933,26 +1964,32 @@ export const commandSetup = async (flags, installHooks = defaultInstallHooks) =>
|
|
|
1933
1964
|
printSuppressed = false;
|
|
1934
1965
|
}
|
|
1935
1966
|
};
|
|
1936
|
-
const
|
|
1937
|
-
|
|
1967
|
+
const options = {
|
|
1968
|
+
agents: selection.agents,
|
|
1969
|
+
project: hasFlag(flags, 'project'),
|
|
1970
|
+
skip: [...new Set([...selection.skip, ...(overrides.skip ?? [])])],
|
|
1938
1971
|
workspace: getFlag(flags, 'workspace'),
|
|
1939
1972
|
apiKeyStdin,
|
|
1940
1973
|
apiKey: flagKey ?? envKey,
|
|
1941
1974
|
apiKeySource: flagKey ? 'flag' : envKey ? 'env' : undefined,
|
|
1942
1975
|
noHook: hasFlag(flags, 'no-hook'),
|
|
1943
1976
|
noAppEnv: hasFlag(flags, 'no-app-env'),
|
|
1977
|
+
...(hasFlag(flags, 'no-auto-update') ? { autoUpdate: false } : hasFlag(flags, 'auto-update') ? { autoUpdate: true } : {}),
|
|
1944
1978
|
saveSessions: hasFlag(flags, 'save-sessions'),
|
|
1945
|
-
dryRun: hasFlag(flags, 'dry-run'),
|
|
1979
|
+
dryRun: overrides.dryRun ?? hasFlag(flags, 'dry-run'),
|
|
1946
1980
|
yes: hasFlag(flags, 'yes'),
|
|
1947
1981
|
printEnv: hasFlag(flags, 'print-env'),
|
|
1948
|
-
}
|
|
1982
|
+
};
|
|
1983
|
+
const deps = {
|
|
1949
1984
|
...defaultFileDeps(),
|
|
1950
1985
|
launchAgentProgram: launchAgentProgram(process.execPath, realpathSync(argv[1] ?? fileURLToPath(import.meta.url)), ['env', 'load', ...(hasFlag(flags, 'profile') ? ['--profile', requireFlag(flags, 'profile')] : [])]),
|
|
1951
1986
|
interactive: Boolean(stdin.isTTY && stderr.isTTY) && !apiKeyStdin,
|
|
1952
1987
|
installHooks,
|
|
1953
|
-
log:
|
|
1954
|
-
|
|
1955
|
-
|
|
1988
|
+
log: overrides.quietLog
|
|
1989
|
+
? () => { }
|
|
1990
|
+
: line => {
|
|
1991
|
+
stderr.write(`${line}\n`);
|
|
1992
|
+
},
|
|
1956
1993
|
hasWorkingKey: async () => {
|
|
1957
1994
|
try {
|
|
1958
1995
|
const auth = await resolveAuth(base);
|
|
@@ -1976,6 +2013,11 @@ export const commandSetup = async (flags, installHooks = defaultInstallHooks) =>
|
|
|
1976
2013
|
}
|
|
1977
2014
|
return commandAuth('login', loginFlags);
|
|
1978
2015
|
}),
|
|
2016
|
+
resolveTarget: () => resolveMcpTarget(flags),
|
|
2017
|
+
readAutoUpdate: () => readAutoUpdateSetting(settingsPath(getConfigPath(flags))),
|
|
2018
|
+
writeAutoUpdate: on => writeAutoUpdateSetting(settingsPath(getConfigPath(flags)), on),
|
|
2019
|
+
canSelfUpdate: async () => isInstalledPackage(realpathSync(argv[1] ?? fileURLToPath(import.meta.url))),
|
|
2020
|
+
autoUpdateBlockedByEnv: !autoUpdateEnabled(undefined, env),
|
|
1979
2021
|
resolveAuth: async () => {
|
|
1980
2022
|
const auth = await resolveAuth(base);
|
|
1981
2023
|
return { apiKey: auth.apiKey, baseUrl: auth.baseUrl, profile: auth.profile, workspaceId: auth.workspaceId };
|
|
@@ -2006,7 +2048,14 @@ export const commandSetup = async (flags, installHooks = defaultInstallHooks) =>
|
|
|
2006
2048
|
includeMcp: true,
|
|
2007
2049
|
timeoutMs: parsePositiveIntegerFlag(flags, 'timeout-ms', 15000),
|
|
2008
2050
|
}),
|
|
2009
|
-
}
|
|
2051
|
+
};
|
|
2052
|
+
return { options, deps };
|
|
2053
|
+
};
|
|
2054
|
+
export const commandSetup = async (flags, installHooks = defaultInstallHooks, overrides = {}) => {
|
|
2055
|
+
const { options, deps } = await setupRun(flags, installHooks, overrides);
|
|
2056
|
+
if (hasFlag(flags, 'client') && !hasFlag(flags, 'agent'))
|
|
2057
|
+
stderr.write('--client is deprecated; use --agent claude-code|codex|cursor.\n');
|
|
2058
|
+
const result = await runSetup(options, deps);
|
|
2010
2059
|
if (hasFlag(flags, 'json'))
|
|
2011
2060
|
print(result);
|
|
2012
2061
|
else {
|
|
@@ -2017,6 +2066,29 @@ export const commandSetup = async (flags, installHooks = defaultInstallHooks) =>
|
|
|
2017
2066
|
if (!result.ok)
|
|
2018
2067
|
process.exitCode = 2;
|
|
2019
2068
|
};
|
|
2069
|
+
/**
|
|
2070
|
+
* `doctor --setup`: the setup steps as a dry run that changes nothing, needs no
|
|
2071
|
+
* network, and fails when MCP config or the skill is missing or out of date.
|
|
2072
|
+
*/
|
|
2073
|
+
const setupCheck = async (flags) => {
|
|
2074
|
+
const { options, deps } = await setupRun(flags, installSessionHooks, {
|
|
2075
|
+
skip: ['login', 'workspace', 'auto-update', 'app-env', 'hook', 'doctor'],
|
|
2076
|
+
dryRun: true,
|
|
2077
|
+
quietLog: true,
|
|
2078
|
+
});
|
|
2079
|
+
const result = await runSetup(options, deps);
|
|
2080
|
+
const outdated = result.steps.filter(step => step.status === 'fail' || step.change === 'would-update');
|
|
2081
|
+
return {
|
|
2082
|
+
name: 'setup',
|
|
2083
|
+
status: outdated.length === 0 ? 'pass' : 'fail',
|
|
2084
|
+
...(outdated.length > 0
|
|
2085
|
+
? {
|
|
2086
|
+
message: outdated.map(step => `${step.name}: ${step.detail.replace(/ \(dry run\)$/, '')}`).join('; '),
|
|
2087
|
+
hint: `Run \`assethub setup${options.project ? ' --project' : ''}\` to fix it.`,
|
|
2088
|
+
}
|
|
2089
|
+
: { message: `${result.agents.join(', ')}: MCP config and skill are up to date` }),
|
|
2090
|
+
};
|
|
2091
|
+
};
|
|
2020
2092
|
// `env load` is what the macOS login agent installed by `setup` runs: it copies
|
|
2021
2093
|
// the saved key into launchd's user environment so Claude and Codex, started
|
|
2022
2094
|
// from the Dock, can expand ${ASSETHUB_API_KEY} in their MCP config.
|
|
@@ -5583,6 +5655,33 @@ const resolveMcpTarget = async (flags) => {
|
|
|
5583
5655
|
(stored && new URL(baseUrl).origin === new URL(stored.baseUrl).origin ? stored.workspaceId : undefined);
|
|
5584
5656
|
return { baseUrl, workspaceId };
|
|
5585
5657
|
};
|
|
5658
|
+
// A stderr line when a newer CLI is known or was just installed, from a cache
|
|
5659
|
+
// refreshed (and, with auto-update on, acted on) at most once a day in the background.
|
|
5660
|
+
const noticeUpdate = async (flags) => {
|
|
5661
|
+
if (updateCheckDisabled(env) || env[REFRESH_CHILD_ENV])
|
|
5662
|
+
return;
|
|
5663
|
+
try {
|
|
5664
|
+
const cli = realpathSync(argv[1] ?? fileURLToPath(import.meta.url));
|
|
5665
|
+
if (!isInstalledPackage(cli))
|
|
5666
|
+
return;
|
|
5667
|
+
const cachePath = updateCheckPath(getConfigPath(flags));
|
|
5668
|
+
const cache = await readUpdateCheck(cachePath);
|
|
5669
|
+
const now = new Date();
|
|
5670
|
+
const decision = decideUpdateNotice(await cliVersion(), cache, now);
|
|
5671
|
+
for (const notice of decision.notices)
|
|
5672
|
+
stderr.write(`${notice}\n`);
|
|
5673
|
+
if (cache && (decision.markAnnounced || decision.markNoticed))
|
|
5674
|
+
await patchUpdateCheck(cachePath, cache, {
|
|
5675
|
+
...(decision.markAnnounced && cache.autoUpdate ? { autoUpdate: { ...cache.autoUpdate, announced: true } } : {}),
|
|
5676
|
+
...(decision.markNoticed ? { noticedAt: now.toISOString() } : {}),
|
|
5677
|
+
});
|
|
5678
|
+
if (decision.refresh && (await claimRefreshAttempt(cachePath, now)))
|
|
5679
|
+
refreshInBackground(process.execPath, cli, getConfigPath(flags));
|
|
5680
|
+
}
|
|
5681
|
+
catch {
|
|
5682
|
+
// best effort
|
|
5683
|
+
}
|
|
5684
|
+
};
|
|
5586
5685
|
const run = async () => {
|
|
5587
5686
|
const parsed = parseArgs(argv.slice(2));
|
|
5588
5687
|
if (hasFlag(parsed.flags, 'version')) {
|
|
@@ -5596,16 +5695,16 @@ const run = async () => {
|
|
|
5596
5695
|
const [command, subcommand] = parsed.positionals;
|
|
5597
5696
|
if (command !== 'init')
|
|
5598
5697
|
await syncInstalledSkill();
|
|
5698
|
+
if (!['update', 'hooks', 'env'].includes(command ?? ''))
|
|
5699
|
+
await noticeUpdate(parsed.flags);
|
|
5599
5700
|
if (command === 'init') {
|
|
5600
5701
|
if (subcommand)
|
|
5601
5702
|
throw new Error(`Use init [--agent ${AGENT_IDS.join('|')}] [--project] [--dry-run]`);
|
|
5602
|
-
|
|
5603
|
-
|
|
5604
|
-
|
|
5605
|
-
|
|
5606
|
-
|
|
5607
|
-
dryRun: hasFlag(parsed.flags, 'dry-run'),
|
|
5608
|
-
}));
|
|
5703
|
+
// Kept for existing scripts: agent wiring only, as before, through setup's steps.
|
|
5704
|
+
stderr.write('`assethub init` is deprecated and will be removed in a later version; use `assethub setup` (or `assethub setup --only mcp,skills` for agent wiring only).\n');
|
|
5705
|
+
await commandSetup({ ...parsed.flags, json: true, yes: true }, installSessionHooks, {
|
|
5706
|
+
skip: ['login', 'workspace', 'auto-update', 'app-env', 'hook', 'doctor'],
|
|
5707
|
+
});
|
|
5609
5708
|
return;
|
|
5610
5709
|
}
|
|
5611
5710
|
if (command === 'mcp' && subcommand === 'tools') {
|
|
@@ -5671,22 +5770,49 @@ const run = async () => {
|
|
|
5671
5770
|
return;
|
|
5672
5771
|
}
|
|
5673
5772
|
if (command === 'update') {
|
|
5773
|
+
const cachePath = updateCheckPath(getConfigPath(parsed.flags));
|
|
5774
|
+
if (hasFlag(parsed.flags, 'refresh-check')) {
|
|
5775
|
+
// The detached daily check started by noticeUpdate: record the latest
|
|
5776
|
+
// version and, with auto-update on, install it. Prints nothing.
|
|
5777
|
+
const configPath = getConfigPath(parsed.flags);
|
|
5778
|
+
await refreshUpdateCheck({
|
|
5779
|
+
cachePath,
|
|
5780
|
+
lockPath: `${cachePath}.lock`,
|
|
5781
|
+
autoUpdate: autoUpdateEnabled(await readAutoUpdateSetting(settingsPath(configPath)), env),
|
|
5782
|
+
deps: createNodeUpdateDeps(['--config', configPath]),
|
|
5783
|
+
});
|
|
5784
|
+
return;
|
|
5785
|
+
}
|
|
5674
5786
|
// The verifying doctor checks the same login this command was given.
|
|
5675
5787
|
const forwardFlags = ['profile', 'config', 'base-url', 'workspace'].flatMap(name => {
|
|
5676
5788
|
const value = getFlag(parsed.flags, name);
|
|
5677
5789
|
return value ? [`--${name}`, value] : [];
|
|
5678
5790
|
});
|
|
5679
5791
|
const apiKey = getFlag(parsed.flags, 'api-key');
|
|
5680
|
-
|
|
5792
|
+
const installs = !hasFlag(parsed.flags, 'check') && !hasFlag(parsed.flags, 'dry-run');
|
|
5793
|
+
// Never install alongside a background auto-update.
|
|
5794
|
+
if (installs && !(await takeLock(`${cachePath}.lock`)))
|
|
5795
|
+
throw new Error('A background update of the CLI is running; try again in a minute.');
|
|
5796
|
+
const report = await runUpdate({ check: hasFlag(parsed.flags, 'check'), dryRun: hasFlag(parsed.flags, 'dry-run'), yes: hasFlag(parsed.flags, 'yes') }, createNodeUpdateDeps(forwardFlags, apiKey ? { ASSETHUB_API_KEY: apiKey } : {})).finally(async () => {
|
|
5797
|
+
if (installs)
|
|
5798
|
+
await rm(`${cachePath}.lock`, { force: true });
|
|
5799
|
+
});
|
|
5800
|
+
// Every answer from the registry refreshes the daily hint, so it never nags about an installed version.
|
|
5801
|
+
await writeUpdateCheck(cachePath, report.status === 'updated' ? report.to : report.latest).catch(() => undefined);
|
|
5802
|
+
print(report);
|
|
5681
5803
|
return;
|
|
5682
5804
|
}
|
|
5683
5805
|
if (command === 'doctor') {
|
|
5684
5806
|
stderr.write('Checking AssetHub connection…\n');
|
|
5685
|
-
const
|
|
5807
|
+
const diagnosed = await diagnose({
|
|
5686
5808
|
resolveAuth: () => resolveAuth(parsed.flags),
|
|
5687
5809
|
includeMcp: hasFlag(parsed.flags, 'mcp'),
|
|
5688
5810
|
timeoutMs: parsePositiveIntegerFlag(parsed.flags, 'timeout-ms', 15000),
|
|
5689
5811
|
});
|
|
5812
|
+
const setup = hasFlag(parsed.flags, 'setup') ? await setupCheck(parsed.flags) : undefined;
|
|
5813
|
+
const report = setup
|
|
5814
|
+
? { ...diagnosed, ok: diagnosed.ok && setup.status === 'pass', checks: [...diagnosed.checks, setup] }
|
|
5815
|
+
: diagnosed;
|
|
5690
5816
|
print(report);
|
|
5691
5817
|
if (!report.ok)
|
|
5692
5818
|
process.exitCode = 2;
|