@drawcall/market 0.9.3 → 0.9.4

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.
Files changed (64) hide show
  1. package/README.md +11 -12
  2. package/dist/auth.d.ts.map +1 -1
  3. package/dist/auth.js +2 -1
  4. package/dist/auth.js.map +1 -1
  5. package/dist/cli-client.d.ts +6 -0
  6. package/dist/cli-client.d.ts.map +1 -1
  7. package/dist/cli-client.js +7 -2
  8. package/dist/cli-client.js.map +1 -1
  9. package/dist/commands/agent.js +1 -1
  10. package/dist/commands/agent.js.map +1 -1
  11. package/dist/commands/install.d.ts +2 -2
  12. package/dist/commands/install.d.ts.map +1 -1
  13. package/dist/commands/install.js +24 -6
  14. package/dist/commands/install.js.map +1 -1
  15. package/dist/commands/reference-images.d.ts.map +1 -1
  16. package/dist/commands/reference-images.js +2 -1
  17. package/dist/commands/reference-images.js.map +1 -1
  18. package/dist/commands/upload.js +1 -1
  19. package/dist/commands/upload.js.map +1 -1
  20. package/dist/config.d.ts +1 -0
  21. package/dist/config.d.ts.map +1 -1
  22. package/dist/config.js +3 -3
  23. package/dist/config.js.map +1 -1
  24. package/dist/install-entry.d.ts +1 -1
  25. package/dist/install-entry.d.ts.map +1 -1
  26. package/dist/install.d.ts +1 -1
  27. package/dist/install.d.ts.map +1 -1
  28. package/dist/installation-id.d.ts +4 -0
  29. package/dist/installation-id.d.ts.map +1 -0
  30. package/dist/installation-id.js +39 -0
  31. package/dist/installation-id.js.map +1 -0
  32. package/dist/output.js +1 -1
  33. package/dist/output.js.map +1 -1
  34. package/dist/pack.d.ts +1 -1
  35. package/dist/pack.js +1 -1
  36. package/dist/skill.generated.d.ts +1 -1
  37. package/dist/skill.generated.d.ts.map +1 -1
  38. package/dist/skill.generated.js +1 -1
  39. package/dist/skill.generated.js.map +1 -1
  40. package/dist/v1/client.d.ts +5 -0
  41. package/dist/v1/client.d.ts.map +1 -1
  42. package/dist/v1/client.js +10 -1
  43. package/dist/v1/client.js.map +1 -1
  44. package/dist/v1/contract.d.ts +22 -0
  45. package/dist/v1/contract.d.ts.map +1 -1
  46. package/dist/v1/contract.js +15 -0
  47. package/dist/v1/contract.js.map +1 -1
  48. package/package.json +1 -1
  49. package/skills/market/SKILL.md +9 -9
  50. package/src/auth.ts +2 -1
  51. package/src/cli-client.ts +15 -2
  52. package/src/commands/agent.ts +3 -1
  53. package/src/commands/install.ts +34 -6
  54. package/src/commands/reference-images.ts +2 -1
  55. package/src/commands/upload.ts +1 -1
  56. package/src/config.ts +3 -3
  57. package/src/install-entry.ts +1 -1
  58. package/src/install.ts +1 -1
  59. package/src/installation-id.ts +44 -0
  60. package/src/output.ts +1 -1
  61. package/src/pack.ts +1 -1
  62. package/src/skill.generated.ts +1 -1
  63. package/src/v1/client.ts +12 -1
  64. package/src/v1/contract.ts +17 -0
@@ -1 +1 @@
1
- {"version":3,"file":"skill.generated.d.ts","sourceRoot":"","sources":["../src/skill.generated.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,cAAc,6pHAConH,CAAA;AAC/oH,eAAO,MAAM,cAAc,4mGACglG,CAAA"}
1
+ {"version":3,"file":"skill.generated.d.ts","sourceRoot":"","sources":["../src/skill.generated.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,cAAc,ipHACwmH,CAAA;AACnoH,eAAO,MAAM,cAAc,4mGACglG,CAAA"}
@@ -1,4 +1,4 @@
1
1
  // Generated from skill/SKILL.template.md.
2
- export const cliMarketSkill = '---\nname: market\ndescription: Find, inspect, generate, and use Drawcall Market assets from a coding agent.\n---\n\n# Drawcall Market\n\n## CLI transport\n\nRun commands as `npx @drawcall/market <command>`; do not assume a global `market` binary or switch to MCP after a CLI failure. Use `npx @drawcall/market skill` when these instructions are not already available.\n\nDiscover the current vocabulary and choose an asset:\n\n```sh\nnpx @drawcall/market types\nnpx @drawcall/market search "<query>" --type <type> --limit 3\nnpx @drawcall/market preview <name@version> --out /tmp/<name>.png\nnpx @drawcall/market urls <name@version>\n```\n\n`urls` prints one base URL, file subpaths, and a preview URL without changing the project. Install exact refs together when the project needs local files:\n\n```sh\nnpx @drawcall/market install <name@range...> --cwd "$PWD"\n```\n\nInstall records `assetDependencies` in the nearest `package.json`. `list --cwd "$PWD"` reads that inventory without network access. Run `sync --cwd "$PWD"` after moving installed files so aliases continue to resolve. Use `--force` only with permission to overwrite changed files.\n\nGenerate and install one asset with:\n\n```sh\nnpx @drawcall/market generate --type <type> "<description>"\n```\n\nIf it returns a continuation, run the printed `generate install <jobId>` command. The Market agent can source a coherent set of assets from a broader goal:\n\n```sh\nnpx @drawcall/market agent "<goal>"\n```\n\nPublish only when asked. `pack <source> --out <zip>` creates a Market archive and `upload <name> <source> "<description>" --type <type>` publishes it. Use command help for dependency and visibility options. If authentication is required, ask before running `npx @drawcall/market login`.\n\n## Choose assets\n\nSearch one concrete need at a time. Use one result for an exact lookup and up to three when the user should choose. If nothing fits, try one broader noun phrase before generating a replacement.\n\nThe exact `name@version` returned by Market is authoritative. Copy it verbatim. Generated identifiers can legitimately end mid-word at the catalog limit; never expand, normalize, or reconstruct one from its description.\n\nPreview a finalist when appearance determines whether it fits. File, preview, and zip URLs returned by Market are opaque. Capability-bearing private URLs are secrets; never derive a URL from an asset name or preview metadata.\n\n## Generate\n\nGeneration creates one Market asset from a description. The description is provider input, not the eventual asset name. A fast provider may return the asset immediately; a slow provider returns a continuation ID for the matching status operation. Resume that job instead of starting the same generation again.\n\nReference images must be direct fetchable image URLs or image data, never webpage URLs. The current asset-type metadata says which types support references and how many they accept.\n\nA generated humanoid model is one expressive, animation-ready biped: one head, two arms, two legs, open empty hands, and no companions or scene. Describe identity, theme, silhouette, clothing, colors, and materials. Express topology outside the shared skeleton as costume or body-surface design so the result remains riggable.\n\nRequest public or private access only when visibility matters. Private generation requires the account\'s `market:private` entitlement.\n\n## Failures\n\nAn error means the operation did not happen. Correct invalid inputs, refresh an exact reference after a not-found response, and retry one upstream failure once. Never repeat an unchanged failed generation. Use unapproved assets only when the user explicitly requests and accepts them.\n';
2
+ export const cliMarketSkill = '---\nname: market\ndescription: Find, inspect, generate, and use Drawcall Market assets from a coding agent.\n---\n\n# Drawcall Market\n\n## CLI transport\n\nRun commands as `npx drawcall market <command>`; do not assume a global `market` binary or switch to MCP after a CLI failure. Use `npx drawcall market skill` when these instructions are not already available.\n\nDiscover the current vocabulary and choose an asset:\n\n```sh\nnpx drawcall market types\nnpx drawcall market search "<query>" --type <type> --limit 3\nnpx drawcall market preview <name@version> --out /tmp/<name>.png\nnpx drawcall market urls <name@version>\n```\n\n`urls` prints one base URL, file subpaths, and a preview URL without changing the project. Install exact refs together when the project needs local files:\n\n```sh\nnpx drawcall market install <name@range...> --cwd "$PWD"\n```\n\nInstall records `assetDependencies` in the nearest `package.json`. `list --cwd "$PWD"` reads that inventory without network access. Run `sync --cwd "$PWD"` after moving installed files so aliases continue to resolve. Use `--force` only with permission to overwrite changed files.\n\nGenerate and install one asset with:\n\n```sh\nnpx drawcall market generate --type <type> "<description>"\n```\n\nIf it returns a continuation, run the printed `generate install <jobId>` command. The Market agent can source a coherent set of assets from a broader goal:\n\n```sh\nnpx drawcall market agent "<goal>"\n```\n\nPublish only when asked. `pack <source> --out <zip>` creates a Market archive and `upload <name> <source> "<description>" --type <type>` publishes it. Use command help for dependency and visibility options. If authentication is required, ask before running `npx drawcall auth login`.\n\n## Choose assets\n\nSearch one concrete need at a time. Use one result for an exact lookup and up to three when the user should choose. If nothing fits, try one broader noun phrase before generating a replacement.\n\nThe exact `name@version` returned by Market is authoritative. Copy it verbatim. Generated identifiers can legitimately end mid-word at the catalog limit; never expand, normalize, or reconstruct one from its description.\n\nPreview a finalist when appearance determines whether it fits. File, preview, and zip URLs returned by Market are opaque. Capability-bearing private URLs are secrets; never derive a URL from an asset name or preview metadata.\n\n## Generate\n\nGeneration creates one Market asset from a description. The description is provider input, not the eventual asset name. A fast provider may return the asset immediately; a slow provider returns a continuation ID for the matching status operation. Resume that job instead of starting the same generation again.\n\nReference images must be direct fetchable image URLs or image data, never webpage URLs. The current asset-type metadata says which types support references and how many they accept.\n\nA generated humanoid model is one expressive, animation-ready biped: one head, two arms, two legs, open empty hands, and no companions or scene. Describe identity, theme, silhouette, clothing, colors, and materials. Express topology outside the shared skeleton as costume or body-surface design so the result remains riggable.\n\nRequest public or private access only when visibility matters. Private generation requires the account\'s `market:private` entitlement.\n\n## Failures\n\nAn error means the operation did not happen. Correct invalid inputs, refresh an exact reference after a not-found response, and retry one upstream failure once. Never repeat an unchanged failed generation. Use unapproved assets only when the user explicitly requests and accepts them.\n';
3
3
  export const mcpMarketSkill = "---\nname: market\ndescription: Find, inspect, generate, and use Drawcall Market assets from a coding agent.\n---\n\n# Drawcall Market\n\n## MCP transport\n\nMCP tools are the only Market transport in this environment. Do not invoke the CLI, make direct API requests, or switch transports after a failed call.\n\nUse the same conceptual workflow as the Market CLI:\n\n```text\nlist_market_asset_types\nsearch_market\nget_market_asset\nget_market_asset_preview\n```\n\n`search_market` requires an asset type and returns exact `name@version` references. Inspect the exact manifest with `get_market_asset`; request its preview only when visual evidence matters. Remote MCP tools return immutable references and fetch-ready URLs. They do not install files into the caller's local project.\n\nWhen generation is available, call `generate_market_asset`. If it returns a `jobId`, continue with `get_market_asset_generation`. Do not start the same generation again.\n\nWhen the Market agent is available, call `start_market_agent_run` with the full goal and continue its returned `runId` with `get_market_agent_run`.\n\nUse an exact Market reference with `create_design_frame` when the selected asset belongs in Drawcall Design.\n\n## Choose assets\n\nSearch one concrete need at a time. Use one result for an exact lookup and up to three when the user should choose. If nothing fits, try one broader noun phrase before generating a replacement.\n\nThe exact `name@version` returned by Market is authoritative. Copy it verbatim. Generated identifiers can legitimately end mid-word at the catalog limit; never expand, normalize, or reconstruct one from its description.\n\nPreview a finalist when appearance determines whether it fits. File, preview, and zip URLs returned by Market are opaque. Capability-bearing private URLs are secrets; never derive a URL from an asset name or preview metadata.\n\n## Generate\n\nGeneration creates one Market asset from a description. The description is provider input, not the eventual asset name. A fast provider may return the asset immediately; a slow provider returns a continuation ID for the matching status operation. Resume that job instead of starting the same generation again.\n\nReference images must be direct fetchable image URLs or image data, never webpage URLs. The current asset-type metadata says which types support references and how many they accept.\n\nA generated humanoid model is one expressive, animation-ready biped: one head, two arms, two legs, open empty hands, and no companions or scene. Describe identity, theme, silhouette, clothing, colors, and materials. Express topology outside the shared skeleton as costume or body-surface design so the result remains riggable.\n\nRequest public or private access only when visibility matters. Private generation requires the account's `market:private` entitlement.\n\n## Failures\n\nAn error means the operation did not happen. Correct invalid inputs, refresh an exact reference after a not-found response, and retry one upstream failure once. Never repeat an unchanged failed generation. Use unapproved assets only when the user explicitly requests and accepts them.\n";
4
4
  //# sourceMappingURL=skill.generated.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"skill.generated.js","sourceRoot":"","sources":["../src/skill.generated.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,MAAM,CAAC,MAAM,cAAc,GACzB,6oHAA6oH,CAAA;AAC/oH,MAAM,CAAC,MAAM,cAAc,GACzB,ymGAAymG,CAAA"}
1
+ {"version":3,"file":"skill.generated.js","sourceRoot":"","sources":["../src/skill.generated.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAC1C,MAAM,CAAC,MAAM,cAAc,GACzB,ioHAAioH,CAAA;AACnoH,MAAM,CAAC,MAAM,cAAc,GACzB,ymGAAymG,CAAA"}
@@ -5,6 +5,11 @@ export interface MarketV1ClientOptions {
5
5
  baseUrl?: string;
6
6
  fetch?: typeof globalThis.fetch;
7
7
  authToken?: string;
8
+ source?: {
9
+ surface: 'cli' | 'mcp' | 'sdk' | 'web';
10
+ distinctId?: string;
11
+ analyticsDisabled?: boolean;
12
+ };
8
13
  }
9
14
  /**
10
15
  * A typed client for the v1 REST surface (`/api/v1`). Same call shapes as the legacy RPC client —
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/v1/client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAC1D,OAAO,EAAY,KAAK,UAAU,EAAE,MAAM,eAAe,CAAA;AAEzD,MAAM,MAAM,cAAc,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAA;AAa7D,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAA;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AA4BD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,GAAE,qBAA0B,GAAG,cAAc,CAO7E"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/v1/client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAC1D,OAAO,EAAY,KAAK,UAAU,EAAE,MAAM,eAAe,CAAA;AAEzD,MAAM,MAAM,cAAc,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAA;AAa7D,MAAM,WAAW,qBAAqB;IACpC,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAA;IAC/B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE;QACP,OAAO,EAAE,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,CAAA;QACtC,UAAU,CAAC,EAAE,MAAM,CAAA;QACnB,iBAAiB,CAAC,EAAE,OAAO,CAAA;KAC5B,CAAA;CACF;AA4BD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,GAAE,qBAA0B,GAAG,cAAc,CAa7E"}
package/dist/v1/client.js CHANGED
@@ -43,10 +43,19 @@ function resilientReads(baseFetch) {
43
43
  * they are curl-able, shareable and cacheable.
44
44
  */
45
45
  export function createClient(opts = {}) {
46
+ const headers = {};
47
+ if (opts.authToken)
48
+ headers.authorization = `Bearer ${opts.authToken}`;
49
+ if (opts.source)
50
+ headers['x-market-surface'] = opts.source.surface;
51
+ if (opts.source?.distinctId)
52
+ headers['x-posthog-distinct-id'] = opts.source.distinctId;
53
+ if (opts.source?.analyticsDisabled)
54
+ headers['x-market-analytics-disabled'] = 'true';
46
55
  const link = new OpenAPILink(contract, {
47
56
  url: new URL('/api/v1', opts.baseUrl ?? DEFAULT_BASE_URL).href,
48
57
  fetch: resilientReads(opts.fetch ?? ((input, init) => globalThis.fetch(input, init))),
49
- headers: opts.authToken ? { authorization: `Bearer ${opts.authToken}` } : undefined,
58
+ headers,
50
59
  });
51
60
  return createORPCClient(link);
52
61
  }
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/v1/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AAExD,OAAO,EAAE,QAAQ,EAAmB,MAAM,eAAe,CAAA;AAIzD,MAAM,gBAAgB,GAAG,4BAA4B,CAAA;AAErD;;;;;;GAMG;AACH,MAAM,qBAAqB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;AAQrD;;;;GAIG;AACH,SAAS,cAAc,CAAC,SAAkC;IACxD,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;QAC3B,MAAM,MAAM,GAAG,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC,KAAK,YAAY,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,EAAE,CAAA;QAChG,IAAI,MAAM,KAAK,KAAK,IAAI,MAAM,KAAK,MAAM;YAAE,OAAO,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;QAExE,IAAI,SAAkB,CAAA;QACtB,KAAK,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,IAAI,qBAAqB,CAAC,OAAO,EAAE,EAAE,CAAC;YACnE,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;YAC9C,MAAM,MAAM,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAA;YAC/E,IAAI,CAAC;gBACH,OAAO,MAAM,SAAS,CAAC,KAAK,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,CAAC,CAAA;YACpD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,SAAS,GAAG,KAAK,CAAA;gBACjB,IAAI,IAAI,EAAE,MAAM,EAAE,OAAO,IAAI,OAAO,KAAK,qBAAqB,CAAC,MAAM,GAAG,CAAC;oBAAE,MAAM,KAAK,CAAA;gBACtF,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,CAAA;YAChF,CAAC;QACH,CAAC;QACD,MAAM,SAAS,CAAA;IACjB,CAAC,CAAA;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,OAA8B,EAAE;IAC3D,MAAM,IAAI,GAAG,IAAI,WAAW,CAAC,QAAQ,EAAE;QACrC,GAAG,EAAE,IAAI,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,IAAI,gBAAgB,CAAC,CAAC,IAAI;QAC9D,KAAK,EAAE,cAAc,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;QACrF,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,UAAU,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS;KACpF,CAAC,CAAA;IACF,OAAO,gBAAgB,CAAiB,IAAI,CAAC,CAAA;AAC/C,CAAC"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/v1/client.ts"],"names":[],"mappings":"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"}
@@ -37,6 +37,15 @@ export interface AssetQueryResult {
37
37
  total: number;
38
38
  assets: AssetSearchResult[];
39
39
  }
40
+ export declare const installReceiptSchema: z.ZodObject<{
41
+ assetCount: z.ZodNumber;
42
+ assetTypes: z.ZodArray<z.ZodString>;
43
+ fileCount: z.ZodNumber;
44
+ npmDependencyCount: z.ZodNumber;
45
+ redirectedFileCount: z.ZodNumber;
46
+ skillDependencyCount: z.ZodNumber;
47
+ warningCount: z.ZodNumber;
48
+ }, z.core.$strip>;
40
49
  /**
41
50
  * The v1 contract: the same procedure tree as the legacy RPC surface (so call sites migrate by
42
51
  * swapping only the client), with HTTP routes attached — served as plain REST under `/api/v1`.
@@ -186,6 +195,19 @@ export declare const contract: {
186
195
  }, z.core.$strip>], "status">, Record<never, never>, Record<never, never>>;
187
196
  };
188
197
  };
198
+ installation: {
199
+ complete: import("@orpc/contract").ContractProcedureBuilderWithInputOutput<z.ZodObject<{
200
+ assetCount: z.ZodNumber;
201
+ assetTypes: z.ZodArray<z.ZodString>;
202
+ fileCount: z.ZodNumber;
203
+ npmDependencyCount: z.ZodNumber;
204
+ redirectedFileCount: z.ZodNumber;
205
+ skillDependencyCount: z.ZodNumber;
206
+ warningCount: z.ZodNumber;
207
+ }, z.core.$strip>, z.ZodObject<{
208
+ accepted: z.ZodLiteral<true>;
209
+ }, z.core.$strip>, Record<never, never>, Record<never, never>>;
210
+ };
189
211
  user: {
190
212
  getProfile: import("@orpc/contract").ContractProcedureBuilderWithOutput<import("@orpc/contract").Schema<unknown, unknown>, z.ZodCustom<User | null, User | null>, Record<never, never>, Record<never, never>>;
191
213
  updateProfile: import("@orpc/contract").ContractProcedureBuilderWithInputOutput<z.ZodObject<{
@@ -1 +1 @@
1
- {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../src/v1/contract.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AACtD,OAAO,KAAK,EACV,cAAc,EACd,oBAAoB,EACpB,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,IAAI,EACL,MAAM,gBAAgB,CAAA;AAgBvB;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,QAAQ,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAA;IAC5B,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACvC,iBAAiB,EAAE,iBAAiB,CAAA;IACpC,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACzC,KAAK,EAAE,cAAc,EAAE,CAAA;IACvB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,MAAM,EAAE,MAAM,CAAA;CACf;AAED;0FAC0F;AAC1F,MAAM,WAAW,aAAc,SAAQ,oBAAoB;IACzD,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,CAAC,aAAa,GAAG,IAAI,CAAC,EAAE,CAAA;CACjC;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,iBAAiB,EAAE,CAAA;CAC5B;AAED;;;;GAIG;AACH,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAaa,gBAAgB,EAAE;;qBAAlB,gBAAgB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBAkDnB,MAAM;uBAAa,IAAI;;oBAAvB,MAAM;uBAAa,IAAI;;;;;;;CAMvD,CAAA;AAED,MAAM,MAAM,UAAU,GAAG,OAAO,QAAQ,CAAA"}
1
+ {"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../../src/v1/contract.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AACtD,OAAO,KAAK,EACV,cAAc,EACd,oBAAoB,EACpB,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,IAAI,EACL,MAAM,gBAAgB,CAAA;AAgBvB;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,QAAQ,EAAE,OAAO,CAAA;IACjB,MAAM,EAAE,QAAQ,GAAG,SAAS,CAAA;IAC5B,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACvC,iBAAiB,EAAE,iBAAiB,CAAA;IACpC,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACzC,KAAK,EAAE,cAAc,EAAE,CAAA;IACvB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,MAAM,EAAE,MAAM,CAAA;CACf;AAED;0FAC0F;AAC1F,MAAM,WAAW,aAAc,SAAQ,oBAAoB;IACzD,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,CAAC,aAAa,GAAG,IAAI,CAAC,EAAE,CAAA;CACjC;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,iBAAiB,EAAE,CAAA;CAC5B;AAED,eAAO,MAAM,oBAAoB;;;;;;;;iBAQ/B,CAAA;AAEF;;;;GAIG;AACH,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAaa,gBAAgB,EAAE;;qBAAlB,gBAAgB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBAyDnB,MAAM;uBAAa,IAAI;;oBAAvB,MAAM;uBAAa,IAAI;;;;;;;CAMvD,CAAA;AAED,MAAM,MAAM,UAAU,GAAG,OAAO,QAAQ,CAAA"}
@@ -1,6 +1,15 @@
1
1
  import { oc } from '@orpc/contract';
2
2
  import { z } from 'zod';
3
3
  import { MAX_UPLOAD_ZIP_SIZE_BYTES, agentRunStatusSchema, agentStartSchema, agentStatusSchema, assetCollectionReadSchema, assetQueriesSchema, generateAssetSchema, generateJobStatusSchema, generateResponseSchema, generateStatusInputSchema, updateProfileSchema, uploadZipSchema, } from '../schemas.js';
4
+ export const installReceiptSchema = z.object({
5
+ assetCount: z.number().int().nonnegative(),
6
+ assetTypes: z.array(z.string().min(1).max(64)).max(64),
7
+ fileCount: z.number().int().nonnegative(),
8
+ npmDependencyCount: z.number().int().nonnegative(),
9
+ redirectedFileCount: z.number().int().nonnegative(),
10
+ skillDependencyCount: z.number().int().nonnegative(),
11
+ warningCount: z.number().int().nonnegative(),
12
+ });
4
13
  /**
5
14
  * The v1 contract: the same procedure tree as the legacy RPC surface (so call sites migrate by
6
15
  * swapping only the client), with HTTP routes attached — served as plain REST under `/api/v1`.
@@ -50,6 +59,12 @@ export const contract = {
50
59
  .output(agentRunStatusSchema),
51
60
  },
52
61
  },
62
+ installation: {
63
+ complete: oc
64
+ .route({ method: 'POST', path: '/installs' })
65
+ .input(installReceiptSchema)
66
+ .output(z.object({ accepted: z.literal(true) })),
67
+ },
53
68
  user: {
54
69
  getProfile: oc.route({ method: 'GET', path: '/me' }).output(z.custom()),
55
70
  updateProfile: oc
@@ -1 +1 @@
1
- {"version":3,"file":"contract.js","sourceRoot":"","sources":["../../src/v1/contract.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"contract.js","sourceRoot":"","sources":["../../src/v1/contract.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drawcall/market",
3
- "version": "0.9.3",
3
+ "version": "0.9.4",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/drawcall-ai/market",
@@ -7,21 +7,21 @@ description: Find, inspect, generate, and use Drawcall Market assets from a codi
7
7
 
8
8
  ## CLI transport
9
9
 
10
- Run commands as `npx @drawcall/market <command>`; do not assume a global `market` binary or switch to MCP after a CLI failure. Use `npx @drawcall/market skill` when these instructions are not already available.
10
+ Run commands as `npx drawcall market <command>`; do not assume a global `market` binary or switch to MCP after a CLI failure. Use `npx drawcall market skill` when these instructions are not already available.
11
11
 
12
12
  Discover the current vocabulary and choose an asset:
13
13
 
14
14
  ```sh
15
- npx @drawcall/market types
16
- npx @drawcall/market search "<query>" --type <type> --limit 3
17
- npx @drawcall/market preview <name@version> --out /tmp/<name>.png
18
- npx @drawcall/market urls <name@version>
15
+ npx drawcall market types
16
+ npx drawcall market search "<query>" --type <type> --limit 3
17
+ npx drawcall market preview <name@version> --out /tmp/<name>.png
18
+ npx drawcall market urls <name@version>
19
19
  ```
20
20
 
21
21
  `urls` prints one base URL, file subpaths, and a preview URL without changing the project. Install exact refs together when the project needs local files:
22
22
 
23
23
  ```sh
24
- npx @drawcall/market install <name@range...> --cwd "$PWD"
24
+ npx drawcall market install <name@range...> --cwd "$PWD"
25
25
  ```
26
26
 
27
27
  Install records `assetDependencies` in the nearest `package.json`. `list --cwd "$PWD"` reads that inventory without network access. Run `sync --cwd "$PWD"` after moving installed files so aliases continue to resolve. Use `--force` only with permission to overwrite changed files.
@@ -29,16 +29,16 @@ Install records `assetDependencies` in the nearest `package.json`. `list --cwd "
29
29
  Generate and install one asset with:
30
30
 
31
31
  ```sh
32
- npx @drawcall/market generate --type <type> "<description>"
32
+ npx drawcall market generate --type <type> "<description>"
33
33
  ```
34
34
 
35
35
  If it returns a continuation, run the printed `generate install <jobId>` command. The Market agent can source a coherent set of assets from a broader goal:
36
36
 
37
37
  ```sh
38
- npx @drawcall/market agent "<goal>"
38
+ npx drawcall market agent "<goal>"
39
39
  ```
40
40
 
41
- Publish only when asked. `pack <source> --out <zip>` creates a Market archive and `upload <name> <source> "<description>" --type <type>` publishes it. Use command help for dependency and visibility options. If authentication is required, ask before running `npx @drawcall/market login`.
41
+ Publish only when asked. `pack <source> --out <zip>` creates a Market archive and `upload <name> <source> "<description>" --type <type>` publishes it. Use command help for dependency and visibility options. If authentication is required, ask before running `npx drawcall auth login`.
42
42
 
43
43
  ## Choose assets
44
44
 
package/src/auth.ts CHANGED
@@ -9,6 +9,7 @@ import { logout } from './commands/logout.js'
9
9
  import { clearConfig, saveConfig } from './config.js'
10
10
  import { loginResult } from './output.js'
11
11
  import { createClient } from './v1/client.js'
12
+ import { getCliSource } from './installation-id.js'
12
13
 
13
14
  const DEFAULT_BASE_URL = 'https://market.drawcall.ai'
14
15
 
@@ -24,7 +25,7 @@ export function createLoginCommand(): Command {
24
25
  .action(async (options: { api?: string }) => {
25
26
  const baseUrl = options.api ?? DEFAULT_BASE_URL
26
27
  const token = await runDeviceLogin()
27
- const client = createClient({ baseUrl, authToken: token })
28
+ const client = createClient({ baseUrl, authToken: token, source: await getCliSource() })
28
29
  const profile = await client.user.getProfile()
29
30
  if (!profile) throw new Error('The Market API did not accept the auth token.')
30
31
 
package/src/cli-client.ts CHANGED
@@ -2,12 +2,13 @@ import type { MarketClient } from './client.js'
2
2
  import { getAuthToken } from '@drawcall/auth'
3
3
  import { createClient as createV1Client } from './v1/client.js'
4
4
  import { loadConfig } from './config.js'
5
+ import { getCliSource } from './installation-id.js'
5
6
 
6
7
  const DEFAULT_BASE_URL = 'https://market.drawcall.ai'
7
8
 
8
9
  export class NotLoggedInError extends Error {
9
10
  constructor() {
10
- super('Not logged in. Run `market login` first.')
11
+ super('Not logged in. Run `npx drawcall auth login` first.')
11
12
  this.name = 'NotLoggedInError'
12
13
  }
13
14
  }
@@ -25,6 +26,14 @@ export interface CliClient {
25
26
  authToken: string | undefined
26
27
  }
27
28
 
29
+ export interface AuthenticatedCliClient extends CliClient {
30
+ authToken: string
31
+ }
32
+
33
+ export function getCliClient(
34
+ opts: CliClientOptions & { requireAuth: true },
35
+ ): Promise<AuthenticatedCliClient>
36
+ export function getCliClient(opts?: CliClientOptions): Promise<CliClient>
28
37
  export async function getCliClient(opts: CliClientOptions = {}): Promise<CliClient> {
29
38
  const authToken = await getAuthToken()
30
39
  const config = await loadConfig()
@@ -37,7 +46,11 @@ export async function getCliClient(opts: CliClientOptions = {}): Promise<CliClie
37
46
  return {
38
47
  // The v1 client has the same call shapes as the legacy `MarketClient`, so every CLI command
39
48
  // and library consumer of `getCliClient` speaks /api/v1 without a signature change.
40
- client: createV1Client({ baseUrl, authToken }),
49
+ client: createV1Client({
50
+ baseUrl,
51
+ authToken,
52
+ source: await getCliSource(),
53
+ }),
41
54
  baseUrl,
42
55
  authToken,
43
56
  }
@@ -43,7 +43,9 @@ function printResult(result: AgentResult, asJson: boolean): void {
43
43
  const note = asset.notes ? ` — ${asset.notes}` : ''
44
44
  console.log(`- ${assetVersionRef(asset.name, asset.version)}${note}`)
45
45
  }
46
- console.log(`Install: market install ${assets.map((asset) => asset.name).join(' ')}`)
46
+ console.log(
47
+ `Install: npx drawcall market install ${assets.map((asset) => asset.name).join(' ')}`,
48
+ )
47
49
  }
48
50
  if (notes) {
49
51
  console.log(`Notes: ${notes}`)
@@ -2,7 +2,12 @@ import * as fs from 'fs/promises'
2
2
  import * as path from 'path'
3
3
  import ora from 'ora'
4
4
  import { resolve } from '../resolve.js'
5
- import { findInstallRoot, install as runInstall, type InstallRootRequest } from '../install.js'
5
+ import {
6
+ findInstallRoot,
7
+ install as runInstall,
8
+ type InstallResult,
9
+ type InstallRootRequest,
10
+ } from '../install.js'
6
11
  import { packageJsonAssetDependencies } from '../package-json.js'
7
12
  import { assetDependencyRange, assetNameSchema, type AssetDependencies } from '../schemas.js'
8
13
  import { getCliClient } from '../cli-client.js'
@@ -57,18 +62,41 @@ export async function installCommand(args: string[], opts: InstallCommandOptions
57
62
 
58
63
  spinner.stop()
59
64
  console.log(installResult(result, metadata))
65
+ await reportCompletedInstall(client, result)
60
66
  } catch (err) {
61
67
  spinner.stop()
62
68
  throw err
63
69
  }
64
70
  }
65
71
 
72
+ async function reportCompletedInstall(client: MarketClient, result: InstallResult): Promise<void> {
73
+ try {
74
+ await client.installation.complete({
75
+ assetCount: result.assets.length,
76
+ assetTypes: [...new Set(result.assets.map((asset) => asset.type))],
77
+ fileCount: result.assets.reduce((count, asset) => count + asset.files.length, 0),
78
+ npmDependencyCount: Object.keys(result.npmDependencies).length,
79
+ redirectedFileCount: result.assets.reduce(
80
+ (count, asset) => count + asset.redirectedFiles.length,
81
+ 0,
82
+ ),
83
+ skillDependencyCount: Object.keys(result.skillDependencies).length,
84
+ warningCount: result.warnings.length,
85
+ })
86
+ } catch (error) {
87
+ const message = error instanceof Error ? error.message : String(error)
88
+ console.warn(
89
+ `Assets installed, but the Market could not record the completed install: ${message}`,
90
+ )
91
+ }
92
+ }
93
+
66
94
  /**
67
95
  * Resolve a single `name` or `name@range` argument to an exact asset request.
68
96
  * Asset names are globally unique, so the name fully determines the asset — no
69
97
  * `--type` is needed. install never fuzzy-searches or generates: it points the
70
- * caller at `market search` / `market generate` instead, which keeps behavior
71
- * predictable for agents.
98
+ * caller at `npx drawcall market search` / `npx drawcall market generate`
99
+ * instead, which keeps behavior predictable for agents.
72
100
  */
73
101
  export async function resolveArg(
74
102
  client: MarketClient,
@@ -79,7 +107,7 @@ export async function resolveArg(
79
107
  const parsed = parseNameAndRange(arg)
80
108
  if (!parsed) {
81
109
  throw new Error(
82
- `Invalid asset name "${arg}". Use \`market search --type <type> <query>\` to find assets.`,
110
+ `Invalid asset name "${arg}". Use \`npx drawcall market search --type <type> <query>\` to find assets.`,
83
111
  )
84
112
  }
85
113
 
@@ -108,8 +136,8 @@ export async function resolveArg(
108
136
  }
109
137
 
110
138
  throw new Error(
111
- `Asset "${parsed.name}" not found. Use \`market search\` to find assets or ` +
112
- `\`market generate --type <type>\` to create one.`,
139
+ `Asset "${parsed.name}" not found. Use \`npx drawcall market search\` to find assets or ` +
140
+ `\`npx drawcall market generate --type <type>\` to create one.`,
113
141
  )
114
142
  }
115
143
 
@@ -1,3 +1,4 @@
1
+ import { Buffer } from 'node:buffer'
1
2
  import { readFile } from 'node:fs/promises'
2
3
  import { extname } from 'node:path'
3
4
 
@@ -12,7 +13,7 @@ export function loadReferenceImages(refs: string[]): Promise<string[]> {
12
13
  async function loadReferenceImage(ref: string): Promise<string> {
13
14
  if (ref.startsWith('http://') || ref.startsWith('https://')) return ref
14
15
  const data = await readFile(ref)
15
- return `data:${mimeFor(ref)};base64,${data.toString('base64')}`
16
+ return `data:${mimeFor(ref)};base64,${Buffer.from(data).toString('base64')}`
16
17
  }
17
18
 
18
19
  function mimeFor(path: string): string {
@@ -74,7 +74,7 @@ export async function uploadCommand(
74
74
  for (const line of packWarnings(packed)) console.warn(line)
75
75
  const profile = await client.user.getProfile()
76
76
  if (!profile) {
77
- throw new Error('Not logged in. Run `market login` first.')
77
+ throw new Error('Not logged in. Run `npx drawcall auth login` first.')
78
78
  }
79
79
  const [existing] = await lookupAssets(client.asset, [{ name: parsedName }], {
80
80
  includeUnapproved: true,
package/src/config.ts CHANGED
@@ -13,7 +13,7 @@ export interface Config {
13
13
  baseUrl?: string
14
14
  }
15
15
 
16
- function configDir(): string {
16
+ export function getConfigDir(): string {
17
17
  if (process.platform === 'win32' && process.env.APPDATA) {
18
18
  return path.join(process.env.APPDATA, 'drawcall-market')
19
19
  }
@@ -22,7 +22,7 @@ function configDir(): string {
22
22
  }
23
23
 
24
24
  function configPath(): string {
25
- return path.join(configDir(), 'config.json')
25
+ return path.join(getConfigDir(), 'config.json')
26
26
  }
27
27
 
28
28
  export async function loadConfig(): Promise<Config | null> {
@@ -35,7 +35,7 @@ export async function loadConfig(): Promise<Config | null> {
35
35
  }
36
36
 
37
37
  export async function saveConfig(config: Config): Promise<void> {
38
- const dir = configDir()
38
+ const dir = getConfigDir()
39
39
  await fs.mkdir(dir, { recursive: true })
40
40
  // `mode` on writeFile/mkdir only applies when the path is created, so chmod
41
41
  // explicitly to protect a pre-existing (possibly world-readable) token file
@@ -1,6 +1,6 @@
1
1
  export type { MarketClient, MarketClientOptions } from './client.js'
2
2
  export { getCliClient, NotLoggedInError } from './cli-client.js'
3
- export type { CliClient, CliClientOptions } from './cli-client.js'
3
+ export type { AuthenticatedCliClient, CliClient, CliClientOptions } from './cli-client.js'
4
4
 
5
5
  export { resolve, ResolutionError } from './resolve.js'
6
6
  export type { ResolvedAsset, ResolveResult } from './resolve.js'
package/src/install.ts CHANGED
@@ -40,7 +40,7 @@ export interface InstallOptions {
40
40
  rootRequests?: InstallRootRequest[]
41
41
  /** Asset-type install policy from the Market API. */
42
42
  installMetadata?: Record<string, AssetInstallMetadata>
43
- /** Capability key of a shared private asset (`market install <asset> --key <key>`). */
43
+ /** Capability key of a shared private asset (`npx drawcall market install <asset> --key <key>`). */
44
44
  key?: string
45
45
  /** Log progress */
46
46
  onProgress?: (message: string) => void
@@ -0,0 +1,44 @@
1
+ import * as fs from 'fs/promises'
2
+ import * as path from 'path'
3
+ import { z } from 'zod'
4
+ import { getConfigDir } from './config.js'
5
+ import type { MarketV1ClientOptions } from './v1/client.js'
6
+
7
+ const installationIdSchema = z.string().uuid()
8
+
9
+ function installationIdPath(): string {
10
+ return path.join(getConfigDir(), 'installation-id')
11
+ }
12
+
13
+ export async function getInstallationId(): Promise<string> {
14
+ try {
15
+ return installationIdSchema.parse((await fs.readFile(installationIdPath(), 'utf-8')).trim())
16
+ } catch (error) {
17
+ if (!isMissingFile(error)) throw error
18
+ }
19
+
20
+ const dir = getConfigDir()
21
+ const installationId = crypto.randomUUID()
22
+ await fs.mkdir(dir, { recursive: true })
23
+ await fs.chmod(dir, 0o700)
24
+ await fs.writeFile(installationIdPath(), `${installationId}\n`, {
25
+ encoding: 'utf-8',
26
+ flag: 'wx',
27
+ mode: 0o600,
28
+ })
29
+ return installationId
30
+ }
31
+
32
+ export async function getCliSource(): Promise<NonNullable<MarketV1ClientOptions['source']>> {
33
+ const analyticsDisabled =
34
+ process.env.DO_NOT_TRACK === '1' || process.env.MARKET_TELEMETRY_DISABLED === '1'
35
+ return {
36
+ surface: 'cli',
37
+ distinctId: analyticsDisabled ? undefined : await getInstallationId(),
38
+ analyticsDisabled,
39
+ }
40
+ }
41
+
42
+ function isMissingFile(error: unknown): boolean {
43
+ return error instanceof Error && 'code' in error && error.code === 'ENOENT'
44
+ }
package/src/output.ts CHANGED
@@ -189,7 +189,7 @@ export function generationRunningResult(jobId: string): string {
189
189
  }
190
190
 
191
191
  function generationInstallCommand(jobId: string): string {
192
- return `npx @drawcall/market@latest generate install ${jobId} --cwd "$PWD"`
192
+ return `npx drawcall market generate install ${jobId} --cwd "$PWD"`
193
193
  }
194
194
 
195
195
  export function uploadResult(name: string, version: string): string {
package/src/pack.ts CHANGED
@@ -616,7 +616,7 @@ export interface AssetDependencySync {
616
616
 
617
617
  /**
618
618
  * Update the aliases in package.json `assetDependencies` to match where each dependency's files
619
- * currently live — the standalone form of what pack does before omitting (`market sync`). Renamed
619
+ * currently live — the standalone form of what pack does before omitting (`npx drawcall market sync`). Renamed
620
620
  * files gain an alias, files back at their canonical path lose theirs, and dependencies whose
621
621
  * manifest cannot be fetched are reported as skipped rather than blindly rewritten.
622
622
  */
@@ -1,5 +1,5 @@
1
1
  // Generated from skill/SKILL.template.md.
2
2
  export const cliMarketSkill =
3
- '---\nname: market\ndescription: Find, inspect, generate, and use Drawcall Market assets from a coding agent.\n---\n\n# Drawcall Market\n\n## CLI transport\n\nRun commands as `npx @drawcall/market <command>`; do not assume a global `market` binary or switch to MCP after a CLI failure. Use `npx @drawcall/market skill` when these instructions are not already available.\n\nDiscover the current vocabulary and choose an asset:\n\n```sh\nnpx @drawcall/market types\nnpx @drawcall/market search "<query>" --type <type> --limit 3\nnpx @drawcall/market preview <name@version> --out /tmp/<name>.png\nnpx @drawcall/market urls <name@version>\n```\n\n`urls` prints one base URL, file subpaths, and a preview URL without changing the project. Install exact refs together when the project needs local files:\n\n```sh\nnpx @drawcall/market install <name@range...> --cwd "$PWD"\n```\n\nInstall records `assetDependencies` in the nearest `package.json`. `list --cwd "$PWD"` reads that inventory without network access. Run `sync --cwd "$PWD"` after moving installed files so aliases continue to resolve. Use `--force` only with permission to overwrite changed files.\n\nGenerate and install one asset with:\n\n```sh\nnpx @drawcall/market generate --type <type> "<description>"\n```\n\nIf it returns a continuation, run the printed `generate install <jobId>` command. The Market agent can source a coherent set of assets from a broader goal:\n\n```sh\nnpx @drawcall/market agent "<goal>"\n```\n\nPublish only when asked. `pack <source> --out <zip>` creates a Market archive and `upload <name> <source> "<description>" --type <type>` publishes it. Use command help for dependency and visibility options. If authentication is required, ask before running `npx @drawcall/market login`.\n\n## Choose assets\n\nSearch one concrete need at a time. Use one result for an exact lookup and up to three when the user should choose. If nothing fits, try one broader noun phrase before generating a replacement.\n\nThe exact `name@version` returned by Market is authoritative. Copy it verbatim. Generated identifiers can legitimately end mid-word at the catalog limit; never expand, normalize, or reconstruct one from its description.\n\nPreview a finalist when appearance determines whether it fits. File, preview, and zip URLs returned by Market are opaque. Capability-bearing private URLs are secrets; never derive a URL from an asset name or preview metadata.\n\n## Generate\n\nGeneration creates one Market asset from a description. The description is provider input, not the eventual asset name. A fast provider may return the asset immediately; a slow provider returns a continuation ID for the matching status operation. Resume that job instead of starting the same generation again.\n\nReference images must be direct fetchable image URLs or image data, never webpage URLs. The current asset-type metadata says which types support references and how many they accept.\n\nA generated humanoid model is one expressive, animation-ready biped: one head, two arms, two legs, open empty hands, and no companions or scene. Describe identity, theme, silhouette, clothing, colors, and materials. Express topology outside the shared skeleton as costume or body-surface design so the result remains riggable.\n\nRequest public or private access only when visibility matters. Private generation requires the account\'s `market:private` entitlement.\n\n## Failures\n\nAn error means the operation did not happen. Correct invalid inputs, refresh an exact reference after a not-found response, and retry one upstream failure once. Never repeat an unchanged failed generation. Use unapproved assets only when the user explicitly requests and accepts them.\n'
3
+ '---\nname: market\ndescription: Find, inspect, generate, and use Drawcall Market assets from a coding agent.\n---\n\n# Drawcall Market\n\n## CLI transport\n\nRun commands as `npx drawcall market <command>`; do not assume a global `market` binary or switch to MCP after a CLI failure. Use `npx drawcall market skill` when these instructions are not already available.\n\nDiscover the current vocabulary and choose an asset:\n\n```sh\nnpx drawcall market types\nnpx drawcall market search "<query>" --type <type> --limit 3\nnpx drawcall market preview <name@version> --out /tmp/<name>.png\nnpx drawcall market urls <name@version>\n```\n\n`urls` prints one base URL, file subpaths, and a preview URL without changing the project. Install exact refs together when the project needs local files:\n\n```sh\nnpx drawcall market install <name@range...> --cwd "$PWD"\n```\n\nInstall records `assetDependencies` in the nearest `package.json`. `list --cwd "$PWD"` reads that inventory without network access. Run `sync --cwd "$PWD"` after moving installed files so aliases continue to resolve. Use `--force` only with permission to overwrite changed files.\n\nGenerate and install one asset with:\n\n```sh\nnpx drawcall market generate --type <type> "<description>"\n```\n\nIf it returns a continuation, run the printed `generate install <jobId>` command. The Market agent can source a coherent set of assets from a broader goal:\n\n```sh\nnpx drawcall market agent "<goal>"\n```\n\nPublish only when asked. `pack <source> --out <zip>` creates a Market archive and `upload <name> <source> "<description>" --type <type>` publishes it. Use command help for dependency and visibility options. If authentication is required, ask before running `npx drawcall auth login`.\n\n## Choose assets\n\nSearch one concrete need at a time. Use one result for an exact lookup and up to three when the user should choose. If nothing fits, try one broader noun phrase before generating a replacement.\n\nThe exact `name@version` returned by Market is authoritative. Copy it verbatim. Generated identifiers can legitimately end mid-word at the catalog limit; never expand, normalize, or reconstruct one from its description.\n\nPreview a finalist when appearance determines whether it fits. File, preview, and zip URLs returned by Market are opaque. Capability-bearing private URLs are secrets; never derive a URL from an asset name or preview metadata.\n\n## Generate\n\nGeneration creates one Market asset from a description. The description is provider input, not the eventual asset name. A fast provider may return the asset immediately; a slow provider returns a continuation ID for the matching status operation. Resume that job instead of starting the same generation again.\n\nReference images must be direct fetchable image URLs or image data, never webpage URLs. The current asset-type metadata says which types support references and how many they accept.\n\nA generated humanoid model is one expressive, animation-ready biped: one head, two arms, two legs, open empty hands, and no companions or scene. Describe identity, theme, silhouette, clothing, colors, and materials. Express topology outside the shared skeleton as costume or body-surface design so the result remains riggable.\n\nRequest public or private access only when visibility matters. Private generation requires the account\'s `market:private` entitlement.\n\n## Failures\n\nAn error means the operation did not happen. Correct invalid inputs, refresh an exact reference after a not-found response, and retry one upstream failure once. Never repeat an unchanged failed generation. Use unapproved assets only when the user explicitly requests and accepts them.\n'
4
4
  export const mcpMarketSkill =
5
5
  "---\nname: market\ndescription: Find, inspect, generate, and use Drawcall Market assets from a coding agent.\n---\n\n# Drawcall Market\n\n## MCP transport\n\nMCP tools are the only Market transport in this environment. Do not invoke the CLI, make direct API requests, or switch transports after a failed call.\n\nUse the same conceptual workflow as the Market CLI:\n\n```text\nlist_market_asset_types\nsearch_market\nget_market_asset\nget_market_asset_preview\n```\n\n`search_market` requires an asset type and returns exact `name@version` references. Inspect the exact manifest with `get_market_asset`; request its preview only when visual evidence matters. Remote MCP tools return immutable references and fetch-ready URLs. They do not install files into the caller's local project.\n\nWhen generation is available, call `generate_market_asset`. If it returns a `jobId`, continue with `get_market_asset_generation`. Do not start the same generation again.\n\nWhen the Market agent is available, call `start_market_agent_run` with the full goal and continue its returned `runId` with `get_market_agent_run`.\n\nUse an exact Market reference with `create_design_frame` when the selected asset belongs in Drawcall Design.\n\n## Choose assets\n\nSearch one concrete need at a time. Use one result for an exact lookup and up to three when the user should choose. If nothing fits, try one broader noun phrase before generating a replacement.\n\nThe exact `name@version` returned by Market is authoritative. Copy it verbatim. Generated identifiers can legitimately end mid-word at the catalog limit; never expand, normalize, or reconstruct one from its description.\n\nPreview a finalist when appearance determines whether it fits. File, preview, and zip URLs returned by Market are opaque. Capability-bearing private URLs are secrets; never derive a URL from an asset name or preview metadata.\n\n## Generate\n\nGeneration creates one Market asset from a description. The description is provider input, not the eventual asset name. A fast provider may return the asset immediately; a slow provider returns a continuation ID for the matching status operation. Resume that job instead of starting the same generation again.\n\nReference images must be direct fetchable image URLs or image data, never webpage URLs. The current asset-type metadata says which types support references and how many they accept.\n\nA generated humanoid model is one expressive, animation-ready biped: one head, two arms, two legs, open empty hands, and no companions or scene. Describe identity, theme, silhouette, clothing, colors, and materials. Express topology outside the shared skeleton as costume or body-surface design so the result remains riggable.\n\nRequest public or private access only when visibility matters. Private generation requires the account's `market:private` entitlement.\n\n## Failures\n\nAn error means the operation did not happen. Correct invalid inputs, refresh an exact reference after a not-found response, and retry one upstream failure once. Never repeat an unchanged failed generation. Use unapproved assets only when the user explicitly requests and accepts them.\n"
package/src/v1/client.ts CHANGED
@@ -20,6 +20,11 @@ export interface MarketV1ClientOptions {
20
20
  baseUrl?: string
21
21
  fetch?: typeof globalThis.fetch
22
22
  authToken?: string
23
+ source?: {
24
+ surface: 'cli' | 'mcp' | 'sdk' | 'web'
25
+ distinctId?: string
26
+ analyticsDisabled?: boolean
27
+ }
23
28
  }
24
29
 
25
30
  /**
@@ -54,10 +59,16 @@ function resilientReads(baseFetch: typeof globalThis.fetch): typeof globalThis.f
54
59
  * they are curl-able, shareable and cacheable.
55
60
  */
56
61
  export function createClient(opts: MarketV1ClientOptions = {}): MarketV1Client {
62
+ const headers: Record<string, string> = {}
63
+ if (opts.authToken) headers.authorization = `Bearer ${opts.authToken}`
64
+ if (opts.source) headers['x-market-surface'] = opts.source.surface
65
+ if (opts.source?.distinctId) headers['x-posthog-distinct-id'] = opts.source.distinctId
66
+ if (opts.source?.analyticsDisabled) headers['x-market-analytics-disabled'] = 'true'
67
+
57
68
  const link = new OpenAPILink(contract, {
58
69
  url: new URL('/api/v1', opts.baseUrl ?? DEFAULT_BASE_URL).href,
59
70
  fetch: resilientReads(opts.fetch ?? ((input, init) => globalThis.fetch(input, init))),
60
- headers: opts.authToken ? { authorization: `Bearer ${opts.authToken}` } : undefined,
71
+ headers,
61
72
  })
62
73
  return createORPCClient<MarketV1Client>(link)
63
74
  }
@@ -64,6 +64,16 @@ export interface AssetQueryResult {
64
64
  assets: AssetSearchResult[]
65
65
  }
66
66
 
67
+ export const installReceiptSchema = z.object({
68
+ assetCount: z.number().int().nonnegative(),
69
+ assetTypes: z.array(z.string().min(1).max(64)).max(64),
70
+ fileCount: z.number().int().nonnegative(),
71
+ npmDependencyCount: z.number().int().nonnegative(),
72
+ redirectedFileCount: z.number().int().nonnegative(),
73
+ skillDependencyCount: z.number().int().nonnegative(),
74
+ warningCount: z.number().int().nonnegative(),
75
+ })
76
+
67
77
  /**
68
78
  * The v1 contract: the same procedure tree as the legacy RPC surface (so call sites migrate by
69
79
  * swapping only the client), with HTTP routes attached — served as plain REST under `/api/v1`.
@@ -122,6 +132,13 @@ export const contract = {
122
132
  },
123
133
  },
124
134
 
135
+ installation: {
136
+ complete: oc
137
+ .route({ method: 'POST', path: '/installs' })
138
+ .input(installReceiptSchema)
139
+ .output(z.object({ accepted: z.literal(true) })),
140
+ },
141
+
125
142
  user: {
126
143
  getProfile: oc.route({ method: 'GET', path: '/me' }).output(z.custom<User | null>()),
127
144