image-skill 0.1.5 → 0.1.7

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 CHANGED
@@ -11,12 +11,19 @@ Install the agent skill from the public mirror repo:
11
11
  npx skills add danielgwilson/image-skill-cli --skill image-skill -g -a codex -y
12
12
  ```
13
13
 
14
- Install the executable CLI from npm:
14
+ Run the executable CLI from npm without requiring a writable global npm prefix:
15
+
16
+ ```bash
17
+ npm exec --yes --package image-skill@latest -- image-skill doctor --json
18
+ ```
19
+
20
+ For repeated shell use, global install is optional only after confirming the
21
+ runtime has a writable npm prefix:
15
22
 
16
23
  ```bash
17
24
  npm install -g image-skill
18
25
  image-skill doctor --json
19
- image-skill signup --agent --human-email CONTACT_OR_SPONSOR_EMAIL --agent-name creative-agent --runtime openclaw --save --json
26
+ image-skill signup --agent --agent-contact CONTACT_OR_SPONSOR_INBOX --agent-name creative-agent --runtime openclaw --save --json
20
27
  image-skill credits methods --json
21
28
  image-skill credits packs list --json
22
29
  image-skill credits quote --pack starter-500 --payment-method stripe_checkout --idempotency-key first-topup-001 --json
@@ -37,3 +44,13 @@ The CLI saves hosted agent tokens only when `--save` is explicit. Saved tokens
37
44
  live at `${XDG_CONFIG_HOME:-~/.config}/image-skill/config.json` by default with
38
45
  0600 permissions. Use `IMAGE_SKILL_CONFIG_PATH` to override the config path and
39
46
  `IMAGE_SKILL_TOKEN` or `--token-stdin` for runtime secret injection.
47
+
48
+ Fresh sandboxes should prefer:
49
+
50
+ ```bash
51
+ export IMAGE_SKILL_CONFIG_PATH="$PWD/.image-skill/config.json"
52
+ npm exec --yes --package image-skill@latest -- image-skill signup --agent --agent-contact CONTACT_OR_SPONSOR_INBOX --agent-name creative-agent --runtime openclaw --save --json
53
+ ```
54
+
55
+ If npm prefix/cache paths are read-only, set `npm_config_cache` and
56
+ `npm_config_prefix` to writable directories before using `npm exec`.
@@ -7,7 +7,7 @@ import { Readable } from "node:stream";
7
7
  import { pipeline } from "node:stream/promises";
8
8
  import os from "node:os";
9
9
 
10
- const VERSION = "0.1.5";
10
+ const VERSION = "0.1.7";
11
11
  const DEFAULT_API_BASE_URL = "https://api.image-skill.com";
12
12
  const DEFAULT_CONFIG_PATH = join(
13
13
  process.env.XDG_CONFIG_HOME ?? join(os.homedir(), ".config"),
@@ -15,9 +15,9 @@ const DEFAULT_CONFIG_PATH = join(
15
15
  "config.json",
16
16
  );
17
17
  const SIGNUP_SUGGESTED_COMMAND =
18
- "image-skill signup --agent --human-email CONTACT_OR_SPONSOR_EMAIL --agent-name NAME --runtime RUNTIME --save --json";
18
+ "image-skill signup --agent --agent-contact CONTACT_OR_SPONSOR_INBOX --agent-name NAME --runtime RUNTIME --save --json";
19
19
  const SIGNUP_CONTACT_GUIDANCE =
20
- "Use --human-email for the accountable contact or sponsor inbox for this restricted agent identity. If no individual human is in the loop, use a durable operator/team/agent inbox that can receive future claim, billing, or abuse notices; do not invent a person or use a throwaway inbox.";
20
+ "Use --agent-contact for the accountable contact, sponsor, operator, or agent inbox for this restricted agent identity. If no individual human is in the loop, use a durable operator/team/agent inbox that can receive future claim, billing, or abuse notices; do not invent a person or use a throwaway inbox. --human-email remains a compatibility alias.";
21
21
 
22
22
  const argv = process.argv.slice(2);
23
23
  const result = await main(argv);
@@ -39,7 +39,7 @@ async function main(rawArgv) {
39
39
  docs_url: "https://image-skill.com/cli.md",
40
40
  commands: [
41
41
  "doctor",
42
- "signup --agent --save",
42
+ "signup --agent --agent-contact --save",
43
43
  "auth status",
44
44
  "auth save",
45
45
  "auth logout",
@@ -79,37 +79,37 @@ async function main(rawArgv) {
79
79
  try {
80
80
  switch (command) {
81
81
  case "doctor":
82
- return doctor(rest);
82
+ return await doctor(rest);
83
83
  case "signup":
84
- return signup(rest);
84
+ return await signup(rest);
85
85
  case "auth":
86
- return auth(rest);
86
+ return await auth(rest);
87
87
  case "whoami":
88
- return whoami(rest);
88
+ return await whoami(rest);
89
89
  case "usage":
90
- return usage(rest);
90
+ return await usage(rest);
91
91
  case "quota":
92
- return quota(rest);
92
+ return await quota(rest);
93
93
  case "credits":
94
- return credits(rest);
94
+ return await credits(rest);
95
95
  case "models":
96
- return models(rest);
96
+ return await models(rest);
97
97
  case "capabilities":
98
- return capabilities(rest);
98
+ return await capabilities(rest);
99
99
  case "create":
100
- return create(rest);
100
+ return await create(rest);
101
101
  case "upload":
102
- return upload(rest);
102
+ return await upload(rest);
103
103
  case "edit":
104
- return edit(rest);
104
+ return await edit(rest);
105
105
  case "assets":
106
- return assets(rest);
106
+ return await assets(rest);
107
107
  case "jobs":
108
- return jobs(rest);
108
+ return await jobs(rest);
109
109
  case "activity":
110
- return activity(rest);
110
+ return await activity(rest);
111
111
  case "feedback":
112
- return feedback(rest);
112
+ return await feedback(rest);
113
113
  default:
114
114
  return failure(
115
115
  `image-skill ${command}`,
@@ -173,18 +173,35 @@ async function signup(argv) {
173
173
  if (!flagBool(args, "agent")) {
174
174
  return invalid("image-skill signup", "signup currently requires --agent");
175
175
  }
176
- const humanEmail = flagString(args, "human-email");
176
+ const contact = signupContact(args);
177
177
  const agentName = flagString(args, "agent-name");
178
178
  const runtime = flagString(args, "runtime");
179
- if (humanEmail === null || agentName === null || runtime === null) {
179
+ if (!contact.ok) {
180
+ return failure(
181
+ "image-skill signup",
182
+ 2,
183
+ "INVALID_ARGUMENTS",
184
+ contact.message,
185
+ false,
186
+ {
187
+ required_flags: ["--agent-contact", "--agent-name", "--runtime"],
188
+ suggested_command: SIGNUP_SUGGESTED_COMMAND,
189
+ docs_url: "https://image-skill.com/cli.md#image-skill-signup-agent",
190
+ },
191
+ );
192
+ }
193
+ if (contact.value === null || agentName === null || runtime === null) {
180
194
  return failure(
181
195
  "image-skill signup",
182
196
  2,
183
197
  "INVALID_ARGUMENTS",
184
- `signup requires --human-email, --agent-name, and --runtime. ${SIGNUP_CONTACT_GUIDANCE}`,
198
+ `signup requires --agent-contact, --agent-name, and --runtime. ${SIGNUP_CONTACT_GUIDANCE}`,
185
199
  false,
186
200
  {
187
- required_flags: ["--human-email", "--agent-name", "--runtime"],
201
+ required_flags: ["--agent-contact", "--agent-name", "--runtime"],
202
+ accepted_aliases: {
203
+ "--human-email": "--agent-contact",
204
+ },
188
205
  suggested_command: SIGNUP_SUGGESTED_COMMAND,
189
206
  docs_url: "https://image-skill.com/cli.md#image-skill-signup-agent",
190
207
  },
@@ -192,13 +209,19 @@ async function signup(argv) {
192
209
  }
193
210
  const save = flagBool(args, "save");
194
211
  const showToken = flagBool(args, "show-token");
212
+ if (save) {
213
+ const configReady = await assertConfigWritable("image-skill signup");
214
+ if (!configReady.ok) {
215
+ return configReady.result;
216
+ }
217
+ }
195
218
  const result = await apiRequest({
196
219
  command: "image-skill signup",
197
220
  method: "POST",
198
221
  apiBaseUrl: apiBase(args),
199
222
  path: "/v1/agent-signups",
200
223
  body: {
201
- human_email: humanEmail,
224
+ human_email: contact.value,
202
225
  agent_name: agentName,
203
226
  runtime,
204
227
  return_token: save || showToken,
@@ -221,12 +244,16 @@ async function signup(argv) {
221
244
  },
222
245
  );
223
246
  }
224
- await saveConfig({
225
- api_base_url: apiBase(args),
226
- token,
227
- saved_at: new Date().toISOString(),
228
- actor: result.envelope.actor ?? result.envelope.data?.actor ?? null,
229
- });
247
+ try {
248
+ await saveConfig({
249
+ api_base_url: apiBase(args),
250
+ token,
251
+ saved_at: new Date().toISOString(),
252
+ actor: result.envelope.actor ?? result.envelope.data?.actor ?? null,
253
+ });
254
+ } catch (error) {
255
+ return configWriteFailure("image-skill signup", error);
256
+ }
230
257
  warnings.push(`saved hosted token to ${configPath()}`);
231
258
  }
232
259
 
@@ -285,12 +312,20 @@ async function auth(argv) {
285
312
  if (!token.ok) {
286
313
  return token.result;
287
314
  }
288
- await saveConfig({
289
- api_base_url: apiBase(args),
290
- token: token.token,
291
- saved_at: new Date().toISOString(),
292
- actor: null,
293
- });
315
+ const configReady = await assertConfigWritable("image-skill auth save");
316
+ if (!configReady.ok) {
317
+ return configReady.result;
318
+ }
319
+ try {
320
+ await saveConfig({
321
+ api_base_url: apiBase(args),
322
+ token: token.token,
323
+ saved_at: new Date().toISOString(),
324
+ actor: null,
325
+ });
326
+ } catch (error) {
327
+ return configWriteFailure("image-skill auth save", error);
328
+ }
294
329
  return success("image-skill auth save", {
295
330
  saved: true,
296
331
  config_path: configPath(),
@@ -1239,6 +1274,43 @@ async function saveConfig(value) {
1239
1274
  await chmod(path, 0o600);
1240
1275
  }
1241
1276
 
1277
+ async function assertConfigWritable(command) {
1278
+ const path = configPath();
1279
+ const probePath = `${path}.write-test-${process.pid}-${randomBytes(4).toString("hex")}`;
1280
+ try {
1281
+ await mkdir(dirname(path), { recursive: true });
1282
+ await writeFile(probePath, "", { mode: 0o600 });
1283
+ await chmod(probePath, 0o600);
1284
+ await rm(probePath, { force: true });
1285
+ return { ok: true };
1286
+ } catch (error) {
1287
+ await rm(probePath, { force: true }).catch(() => {});
1288
+ return {
1289
+ ok: false,
1290
+ result: configWriteFailure(command, error),
1291
+ };
1292
+ }
1293
+ }
1294
+
1295
+ function configWriteFailure(command, error) {
1296
+ const message =
1297
+ error instanceof Error
1298
+ ? error.message
1299
+ : "public CLI could not write its local auth config";
1300
+ return failure(
1301
+ command,
1302
+ 9,
1303
+ "PUBLIC_CLI_CONFIG_WRITE_FAILED",
1304
+ `public CLI could not write auth config at ${configPath()}: ${message}`,
1305
+ true,
1306
+ {
1307
+ suggested_command:
1308
+ 'IMAGE_SKILL_CONFIG_PATH="$PWD/.image-skill/config.json" image-skill signup --agent --agent-contact CONTACT_OR_SPONSOR_INBOX --agent-name NAME --runtime RUNTIME --save --json',
1309
+ docs_url: "https://image-skill.com/cli.md#local-config-and-install",
1310
+ },
1311
+ );
1312
+ }
1313
+
1242
1314
  function parseArgs(argv) {
1243
1315
  const flags = new Map();
1244
1316
  const positionals = [];
@@ -1280,6 +1352,49 @@ function flagBool(args, name) {
1280
1352
  return args.flags.has(name) && args.flags.get(name)?.at(-1) !== "false";
1281
1353
  }
1282
1354
 
1355
+ function signupContact(args) {
1356
+ if (
1357
+ args.flags.has("agent-contact") &&
1358
+ flagString(args, "agent-contact") === null
1359
+ ) {
1360
+ return {
1361
+ ok: false,
1362
+ value: null,
1363
+ message: "agent-contact requires a value",
1364
+ };
1365
+ }
1366
+ if (
1367
+ args.flags.has("human-email") &&
1368
+ flagString(args, "human-email") === null
1369
+ ) {
1370
+ return {
1371
+ ok: false,
1372
+ value: null,
1373
+ message: "human-email requires a value",
1374
+ };
1375
+ }
1376
+ const agentContact = flagString(args, "agent-contact");
1377
+ const humanEmail = flagString(args, "human-email");
1378
+ if (agentContact !== null && humanEmail !== null) {
1379
+ const normalizedAgentContact = agentContact.trim().toLowerCase();
1380
+ const normalizedHumanEmail = humanEmail.trim().toLowerCase();
1381
+ if (normalizedAgentContact !== normalizedHumanEmail) {
1382
+ return {
1383
+ ok: false,
1384
+ value: null,
1385
+ message:
1386
+ "signup received both --agent-contact and --human-email with different values; use one durable contact inbox",
1387
+ };
1388
+ }
1389
+ return { ok: true, value: normalizedAgentContact };
1390
+ }
1391
+ const value = agentContact ?? humanEmail;
1392
+ return {
1393
+ ok: true,
1394
+ value: value === null ? null : value.trim().toLowerCase(),
1395
+ };
1396
+ }
1397
+
1283
1398
  function flagNumber(args, name) {
1284
1399
  const value = flagString(args, name);
1285
1400
  if (value === null) {
package/cli.md CHANGED
@@ -54,7 +54,7 @@ Bootstraps restricted agent access.
54
54
 
55
55
  ```bash
56
56
  image-skill signup --agent \
57
- --human-email human@example.com \
57
+ --agent-contact agent-ops@example.com \
58
58
  --agent-name creative-agent \
59
59
  --runtime codex \
60
60
  --save \
@@ -66,13 +66,14 @@ permissions and redacts it from stdout. Use `--show-token` only when the agent
66
66
  runtime has a separate secret store and needs the raw token once. Do not paste
67
67
  tokens into prompts, logs, issue text, or feedback.
68
68
 
69
- In this preview contract, `--human-email` is the accountable contact or sponsor
70
- inbox for the restricted agent identity. If no individual human is in the loop,
71
- use a durable operator/team/agent inbox that can receive future claim, billing,
72
- or abuse notices. Do not invent a person or use a throwaway inbox.
69
+ In this preview contract, `--agent-contact` is the accountable contact,
70
+ sponsor, operator, or agent inbox for the restricted agent identity. If no
71
+ individual human is in the loop, use a durable operator/team/agent inbox that
72
+ can receive future claim, billing, or abuse notices. Do not invent a person or
73
+ use a throwaway inbox.
73
74
  `example.invalid` addresses are only appropriate inside documented harness or
74
- proof runs. Agent-contact-backed signup is planned, but the currently published
75
- CLI uses `--human-email`.
75
+ proof runs. `--human-email` remains accepted as a compatibility alias for
76
+ `--agent-contact`.
76
77
 
77
78
  For shell-based agent runtimes, store the token outside prompts and then expose
78
79
  it as:
@@ -91,6 +92,44 @@ printf '%s\n' "$IMAGE_SKILL_TOKEN" | image-skill usage quota --token-stdin --jso
91
92
  `--api-base-url` is an advanced preview/test override; production public agents
92
93
  should omit it.
93
94
 
95
+ ### Local Config And Install
96
+
97
+ Prefer package execution in fresh agent sandboxes:
98
+
99
+ ```bash
100
+ npm exec --yes --package image-skill@latest -- image-skill doctor --json
101
+ ```
102
+
103
+ Global install is optional, not the primary path. If `npm install -g image-skill`
104
+ or `npx image-skill@latest ...` hits prefix/cache `EACCES`, retry with writable
105
+ package-manager paths instead of cloning private source:
106
+
107
+ ```bash
108
+ export npm_config_cache="${npm_config_cache:-$PWD/.npm-cache}"
109
+ export npm_config_prefix="${npm_config_prefix:-$PWD/.npm-global}"
110
+ export PATH="$npm_config_prefix/bin:$PATH"
111
+ npm exec --yes --package image-skill@latest -- image-skill doctor --json
112
+ ```
113
+
114
+ Saved auth state defaults to
115
+ `${XDG_CONFIG_HOME:-~/.config}/image-skill/config.json`. If that location is
116
+ read-only, set a writable config path before `signup --save`:
117
+
118
+ ```bash
119
+ export IMAGE_SKILL_CONFIG_PATH="$PWD/.image-skill/config.json"
120
+ npm exec --yes --package image-skill@latest -- image-skill signup --agent \
121
+ --agent-contact agent-ops@example.com \
122
+ --agent-name creative-agent \
123
+ --runtime codex \
124
+ --save \
125
+ --json
126
+ ```
127
+
128
+ Config write failures return `PUBLIC_CLI_CONFIG_WRITE_FAILED` with a structured
129
+ `error.recovery.suggested_command`. Agents should follow that recovery field,
130
+ then continue with `whoami`, `usage quota`, `models list`, and the requested
131
+ creative flow.
132
+
94
133
  ### `image-skill whoami`
95
134
 
96
135
  Shows current actor, organization, claim state, token class, and grants.
@@ -235,6 +274,11 @@ image-skill credits quote \
235
274
  --json
236
275
  ```
237
276
 
277
+ Idempotency keys are scoped to the current hosted agent identity and exact
278
+ quote request. Reusing a key with different credits, pack, or payment method
279
+ returns a structured `error.recovery.suggested_command` with a fresh
280
+ idempotency key for the attempted quote terms.
281
+
238
282
  For Stripe Checkout terms, prefer a named pack:
239
283
 
240
284
  ```bash
package/llms.txt CHANGED
@@ -44,7 +44,7 @@ Claim states:
44
44
 
45
45
  First-run flow:
46
46
  1. image-skill doctor --json
47
- 2. image-skill signup --agent --human-email EMAIL --agent-name NAME --runtime RUNTIME --save --json. The preview hosted signup path currently requires human_email as the accountable contact or sponsor inbox for the restricted agent identity. If no individual human is in the loop, use a durable operator/team/agent inbox that can receive future claim, billing, or abuse notices; do not invent a person or use a throwaway inbox. example.invalid addresses are only appropriate inside documented harness or proof runs. Future payment-backed and agent-contact-backed signup paths are planned. Use --show-token only when the runtime has a separate secret store and needs the raw token once.
47
+ 2. image-skill signup --agent --agent-contact EMAIL --agent-name NAME --runtime RUNTIME --save --json. The preview hosted signup path uses --agent-contact as the accountable contact, sponsor, operator, or agent inbox for the restricted agent identity. If no individual human is in the loop, use a durable operator/team/agent inbox that can receive future claim, billing, or abuse notices; do not invent a person or use a throwaway inbox. example.invalid addresses are only appropriate inside documented harness or proof runs. --human-email remains accepted as a compatibility alias. Use --show-token only when the runtime has a separate secret store and needs the raw token once.
48
48
  3. Reuse the saved CLI auth for later commands, or store the returned data.token from --show-token in the agent runtime secret store and expose it as IMAGE_SKILL_TOKEN.
49
49
  4. image-skill whoami --json
50
50
  5. image-skill usage quota --json
@@ -67,7 +67,7 @@ First-run flow:
67
67
 
68
68
  Core commands:
69
69
  - image-skill doctor --json
70
- - image-skill signup --agent --human-email EMAIL --agent-name NAME --runtime RUNTIME --save --json
70
+ - image-skill signup --agent --agent-contact EMAIL --agent-name NAME --runtime RUNTIME --save --json
71
71
  - image-skill whoami --json
72
72
  - image-skill usage quota --json
73
73
  - image-skill quota --json (compatibility alias)
@@ -98,7 +98,7 @@ Core commands:
98
98
  - image-skill feedback create --type TYPE --title TITLE --body BODY --command COMMAND --expected EXPECTED --actual ACTUAL --proof-needed PROOF --surface cli,docs --evidence trace:TRACE_ID --severity medium --confidence high --next-state watch --json
99
99
 
100
100
  Hosted API endpoints:
101
- - POST https://api.image-skill.com/v1/agent-signups creates or rotates a restricted unclaimed agent token. Request human_email is the preview contact/sponsor inbox, not a requirement that an autonomous agent stop until a specific human is present. The response returns the token once as data.token. Store it in the agent runtime secret store; never put it in prompts, logs, issue text, or feedback.
101
+ - POST https://api.image-skill.com/v1/agent-signups creates or rotates a restricted unclaimed agent token. Raw API request human_email is the compatibility contact field; CLI agents should prefer --agent-contact. The contact is not a requirement that an autonomous agent stop until a specific human is present. The response returns the token once as data.token. Store it in the agent runtime secret store; never put it in prompts, logs, issue text, or feedback.
102
102
  - GET https://api.image-skill.com/v1/whoami returns durable hosted identity for Authorization: Bearer TOKEN.
103
103
  - GET https://api.image-skill.com/v1/quota returns durable hosted quota for Authorization: Bearer TOKEN.
104
104
  - GET https://api.image-skill.com/v1/payment-methods returns the no-auth payment rail catalog. It tells agents which rails are available, whether live money can move, buyer modes (agent_only, hybrid, human_only), browser requirements, limits, endpoint paths, and recovery commands.
@@ -181,7 +181,7 @@ Unclaimed agents may not:
181
181
  - send card data, wallet secrets, provider receipts, Stripe secrets, MPP tokens, SPTs, or any payment credential to Image Skill; Stripe payment details must be entered only on Stripe-hosted checkout pages
182
182
 
183
183
  Credits:
184
- One Image Skill credit is $0.01. Use image-skill credits methods --json to inspect payment rail availability and whether a browser/human action is required. Use image-skill credits packs list --json to inspect recommended Stripe Checkout packs. Use image-skill credits quote --pack PACK_ID --payment-method stripe_checkout --json for the default live-money top-up path. Use image-skill credits quote --credits CREDITS --json for exact bounded custom top-ups when the required budget is already known. The default payment_method is fake. Use image-skill credits buy --provider stripe --json to create a hosted Stripe Checkout Session for a stripe_checkout quote; this returns checkout_url and does not grant credits. Use image-skill credits status --payment-attempt-id PAYMENT_ATTEMPT_ID --json after buy and after checkout completion to read state, receipt, credit_event, limits, and retry guidance. Use image-skill credits fake-purchase --json only to exercise the quote, receipt, credit-ledger, and activity-audit contract before live settlement rails are enabled. Create/edit debit model-priced credits after provider success; inspect models show and operation cost.credit_pricing for credits_required and pricing_confidence. Credits buy and fake-purchase require explicit --idempotency-key. Never send payment credentials to Image Skill; Stripe collects payment details on Stripe-hosted pages. Public request fields are credits, pack_id, payment_method, quote_id, status reference IDs, and idempotency_key.
184
+ One Image Skill credit is $0.01. Use image-skill credits methods --json to inspect payment rail availability and whether a browser/human action is required. Use image-skill credits packs list --json to inspect recommended Stripe Checkout packs. Use image-skill credits quote --pack PACK_ID --payment-method stripe_checkout --json for the default live-money top-up path. Use image-skill credits quote --credits CREDITS --json for exact bounded custom top-ups when the required budget is already known. The default payment_method is fake. Use image-skill credits buy --provider stripe --json to create a hosted Stripe Checkout Session for a stripe_checkout quote; this returns checkout_url and does not grant credits. Use image-skill credits status --payment-attempt-id PAYMENT_ATTEMPT_ID --json after buy and after checkout completion to read state, receipt, credit_event, limits, and retry guidance. Use image-skill credits fake-purchase --json only to exercise the quote, receipt, credit-ledger, and activity-audit contract before live settlement rails are enabled. Create/edit debit model-priced credits after provider success; inspect models show and operation cost.credit_pricing for credits_required and pricing_confidence. Credits buy and fake-purchase require explicit --idempotency-key. Quote idempotency keys are scoped to the hosted agent identity and exact quote terms; use per-run/per-step quote keys and inspect error.recovery.suggested_command on CREDIT_QUOTE_CONFLICT. Never send payment credentials to Image Skill; Stripe collects payment details on Stripe-hosted pages. Public request fields are credits, pack_id, payment_method, quote_id, status reference IDs, and idempotency_key.
185
185
 
186
186
  Telemetry:
187
187
  - command or endpoint name
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "image-skill",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "Thin hosted CLI for Image Skill, a creative runtime for agents.",
5
5
  "type": "module",
6
6
  "private": false,
package/skill.md CHANGED
@@ -35,12 +35,18 @@ supports skills.sh-compatible installation:
35
35
  npx skills add danielgwilson/image-skill-cli --skill image-skill -g -a codex -y
36
36
  ```
37
37
 
38
- Install the executable CLI from npm:
38
+ Run the executable CLI from npm without relying on a writable global npm
39
+ prefix:
39
40
 
40
41
  ```bash
41
- npm install -g image-skill
42
+ npm exec --yes --package image-skill@latest -- image-skill doctor --json
42
43
  ```
43
44
 
45
+ For repeated shell use, use global package linking only after confirming the
46
+ runtime has a writable npm prefix. In fresh sandboxes, prefer `npm exec`/`npx` and set
47
+ `IMAGE_SKILL_CONFIG_PATH` to a writable persistent path if the default config
48
+ home is read-only.
49
+
44
50
  Check service and client health:
45
51
 
46
52
  ```bash
@@ -51,7 +57,7 @@ Bootstrap restricted agent access:
51
57
 
52
58
  ```bash
53
59
  image-skill signup --agent \
54
- --human-email HUMAN_EMAIL \
60
+ --agent-contact CONTACT_OR_SPONSOR_INBOX \
55
61
  --agent-name AGENT_NAME \
56
62
  --runtime RUNTIME_NAME \
57
63
  --save \
@@ -62,18 +68,40 @@ image-skill signup --agent \
62
68
  permissions and redacts it from stdout. Use `--show-token` only when the agent
63
69
  runtime has a separate secret store and needs the raw token once.
64
70
 
65
- In the preview contract, `--human-email` means the accountable contact or
66
- sponsor inbox for the restricted agent identity. If no individual human is in
67
- the loop, use a durable operator/team/agent inbox that can receive future claim,
68
- billing, or abuse notices. Do not invent a person or use a throwaway inbox.
71
+ In the preview contract, `--agent-contact` means the accountable contact,
72
+ sponsor, operator, or agent inbox for the restricted agent identity. If no
73
+ individual human is in the loop, use a durable operator/team/agent inbox that
74
+ can receive future claim, billing, or abuse notices. Do not invent a person or
75
+ use a throwaway inbox.
69
76
  `example.invalid` addresses are only appropriate inside documented harness or
70
- proof runs. Agent-contact-backed signup is planned, but the currently published
71
- CLI uses `--human-email`.
77
+ proof runs. `--human-email` remains accepted as a compatibility alias for
78
+ `--agent-contact`.
72
79
 
73
80
  If the runtime supports stdin secret handoff, prefer `--token-stdin` for
74
81
  `whoami`, `usage quota`, `quota`, `create`, and `feedback create` instead of
75
82
  placing the token in command args.
76
83
 
84
+ ## Local Config And Install
85
+
86
+ The CLI stores saved hosted tokens only when `--save` is explicit. By default
87
+ that file lives at `${XDG_CONFIG_HOME:-~/.config}/image-skill/config.json` with
88
+ 0600 permissions. If a sandbox or hosted executor has a read-only home or npm
89
+ prefix, keep using the public package through `npm exec` and point auth state at
90
+ a writable path:
91
+
92
+ ```bash
93
+ export IMAGE_SKILL_CONFIG_PATH="$PWD/.image-skill/config.json"
94
+ npm exec --yes --package image-skill@latest -- image-skill signup --agent \
95
+ --agent-contact CONTACT_OR_SPONSOR_INBOX \
96
+ --agent-name AGENT_NAME \
97
+ --runtime RUNTIME_NAME \
98
+ --save \
99
+ --json
100
+ ```
101
+
102
+ Do not clone private source or fall back to direct provider APIs because global
103
+ package linking or the default config directory is blocked.
104
+
77
105
  Inspect identity and quota:
78
106
 
79
107
  ```bash
@@ -81,10 +109,10 @@ image-skill whoami --json
81
109
  image-skill usage quota --json
82
110
  ```
83
111
 
84
- The preview hosted signup path currently uses the contact/sponsor email field
85
- above. Future payment-backed and agent-contact-backed signup paths are planned
86
- so capable agents can become bounded paying users without making human claim the
87
- only path to meaningful usage.
112
+ The preview hosted signup path currently uses the agent-contact inbox above.
113
+ Future payment-backed signup paths are planned so capable agents can become
114
+ bounded paying users without making human claim the only path to meaningful
115
+ usage.
88
116
 
89
117
  Credit quote and buy flow:
90
118