@hraness/slopcamera 3.2.6 → 3.2.8

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 (78) hide show
  1. package/NOTICE.md +1 -7
  2. package/PRIVACY.md +16 -7
  3. package/README.md +41 -13
  4. package/apps/desktop/README.md +14 -130
  5. package/apps/desktop/application/context.ts +0 -9
  6. package/apps/desktop/application/default-registry.ts +0 -10
  7. package/apps/desktop/application/operation.ts +1 -5
  8. package/apps/desktop/application/operations/index.ts +0 -1
  9. package/apps/desktop/cli/args.ts +22 -86
  10. package/apps/desktop/cli/command-host-resources.ts +5 -1
  11. package/apps/desktop/cli/commands.ts +37 -67
  12. package/apps/desktop/cli/help.ts +24 -20
  13. package/apps/desktop/cli/html-scene.ts +479 -0
  14. package/apps/desktop/cli/io.ts +2 -1
  15. package/apps/desktop/cli/main.ts +28 -47
  16. package/apps/desktop/cli/media-ingest-model.ts +2 -0
  17. package/apps/desktop/cli/media-ingest-program.ts +9 -4
  18. package/apps/desktop/cli/menubar.ts +244 -0
  19. package/apps/desktop/cli/music-analysis-service.ts +61 -0
  20. package/apps/desktop/cli/portable-surface.ts +13 -4
  21. package/apps/desktop/cli/root-help-intro.ts +14 -0
  22. package/apps/desktop/code/application-node-planner.ts +0 -47
  23. package/apps/desktop/code/host-source-layout.ts +46 -0
  24. package/apps/desktop/code/public.ts +0 -1
  25. package/apps/desktop/code/runtime-identity.ts +50 -8
  26. package/apps/desktop/code/semantic-builder.ts +0 -43
  27. package/apps/desktop/code/source-bundle.ts +23 -6
  28. package/apps/desktop/code/source-typecheck.ts +131 -43
  29. package/apps/desktop/code/worker-client.ts +14 -2
  30. package/apps/desktop/core/music-analysis.ts +124 -1
  31. package/apps/desktop/dist/cli/main.js +261 -248
  32. package/apps/desktop/html-overlay/audio-reactivity.ts +127 -0
  33. package/apps/desktop/html-overlay/contracts.ts +3 -0
  34. package/apps/desktop/html-overlay/index.ts +28 -0
  35. package/apps/desktop/html-overlay/music-clock.ts +126 -0
  36. package/apps/desktop/html-overlay/rigged-glb.ts +429 -0
  37. package/apps/desktop/html-overlay/runtime.ts +4 -0
  38. package/apps/desktop/html-overlay/scaffolds.ts +2 -1
  39. package/apps/desktop/html-overlay/scene.ts +76 -0
  40. package/dist/cli.js +83 -81
  41. package/dist/{index-jchqst8w.js → index-7131pg1c.js} +43 -236
  42. package/dist/{index-mcy8z0br.js → index-fava6pge.js} +1 -1
  43. package/dist/{index-z7239b4h.js → index-h1k0fnjq.js} +1 -1
  44. package/dist/{index-p63wavx0.js → index-zfnddgay.js} +1 -1
  45. package/dist/index.js +4 -18
  46. package/dist/operations.js +2 -2
  47. package/dist/vectorize/worker.js +1 -1
  48. package/dist/workflow.js +3 -3
  49. package/docs/README.md +2 -1
  50. package/docs/studio.md +1 -1
  51. package/examples/html/music-video.html +514 -0
  52. package/examples/html/music-video.json +16 -0
  53. package/package.json +8 -21
  54. package/skills/slopcamera/SKILL.md +10 -1
  55. package/skills/slopcamera/references/diagrams.md +5 -14
  56. package/skills/slopcamera/references/install.md +2 -2
  57. package/skills/slopcamera/references/music-video.md +169 -0
  58. package/skills/slopcamera/references/reference-led-3d.md +1 -1
  59. package/skills/slopcamera/references/support.md +25 -0
  60. package/skills/slopcamera/references/video-projects.md +6 -2
  61. package/skills/slopcamera/references/web-media-excerpts.md +120 -0
  62. package/skills/slopcamera/references/workflows-sdk.md +1 -1
  63. package/src/cli.ts +28 -98
  64. package/src/index.ts +0 -23
  65. package/src/support-completion.ts +16 -0
  66. package/src/support.ts +42 -0
  67. package/src/version.ts +1 -1
  68. package/apps/desktop/application/operations/recording/index.ts +0 -5
  69. package/apps/desktop/application/operations/recording/pause.ts +0 -34
  70. package/apps/desktop/application/operations/recording/resume.ts +0 -34
  71. package/apps/desktop/application/operations/recording/shared.ts +0 -199
  72. package/apps/desktop/application/operations/recording/start.ts +0 -169
  73. package/apps/desktop/application/operations/recording/stop.ts +0 -34
  74. package/apps/desktop/capture/protocol.ts +0 -689
  75. package/apps/desktop/cli/capture-bundle.ts +0 -1117
  76. package/apps/desktop/cli/recording-controller.ts +0 -1567
  77. package/apps/desktop/cli/recording-daemon.ts +0 -931
  78. package/src/desktop.ts +0 -253
package/dist/cli.js CHANGED
@@ -4,30 +4,25 @@ import {
4
4
  SLOPCAMERA_VERSION,
5
5
  artifactSummary,
6
6
  checkDiagramFile,
7
- desktopStatus,
8
- getLatestDesktopRelease,
9
- installDesktop,
10
- openInDesktop,
11
7
  renderDiagramFile,
12
- runMcpServer,
13
- selectDesktopAsset
14
- } from "./index-jchqst8w.js";
8
+ runMcpServer
9
+ } from "./index-7131pg1c.js";
15
10
  import {
16
11
  installSkill,
17
12
  pathExists
18
13
  } from "./index-7308egqr.js";
19
14
  import"./index-8txs6fkn.js";
20
- import"./index-mcy8z0br.js";
15
+ import"./index-fava6pge.js";
21
16
  import {
22
17
  executeSlopcameraOperation,
23
18
  isSlopcameraOperationCode,
24
19
  searchSlopcameraOperations,
25
20
  slopcameraOperationCodes,
26
21
  withSlopcameraOperationHostAdmission
27
- } from "./index-z7239b4h.js";
22
+ } from "./index-h1k0fnjq.js";
28
23
  import {
29
24
  vectorizeImage
30
- } from "./index-p63wavx0.js";
25
+ } from "./index-zfnddgay.js";
31
26
  import {
32
27
  generateSlopcameraImageFile,
33
28
  slopcameraGatewayCredentialStatus,
@@ -41,7 +36,58 @@ import {
41
36
  // src/cli.ts
42
37
  import { writeFile } from "fs/promises";
43
38
  import { resolve } from "path";
44
- import { createInterface } from "readline/promises";
39
+
40
+ // src/support-completion.ts
41
+ function reportUsefulResult(observer) {
42
+ try {
43
+ if (observer !== undefined)
44
+ Promise.resolve(observer()).catch(() => {
45
+ return;
46
+ });
47
+ } catch {}
48
+ }
49
+
50
+ // src/support.ts
51
+ import {
52
+ maybeShowSupportInvitation,
53
+ runSupportCommand
54
+ } from "@hraness/support-foundation/node";
55
+ var supportProfile = {
56
+ id: "slopcamera",
57
+ name: "Slopcamera",
58
+ valueProposition: "Support ongoing development of local visual tools for agents.",
59
+ updates: false
60
+ };
61
+ function standaloneSupportEnvironment() {
62
+ const env = { ...process.env };
63
+ process.env.HRANESS_SUPPORT_AUDIENCE = "off";
64
+ process.env.HRANESS_SUPPORT_EMAIL = "off";
65
+ return env;
66
+ }
67
+ async function runProductSupportCommand(args, options = {}) {
68
+ const result = await runSupportCommand(supportProfile, args, {
69
+ command: ["slopcamera"],
70
+ ...options,
71
+ gitEmail: false
72
+ });
73
+ if (result.stdout !== "")
74
+ process.stdout.write(result.stdout);
75
+ if (result.stderr !== "")
76
+ process.stderr.write(result.stderr);
77
+ return result.exitCode;
78
+ }
79
+ async function showProductSupportInvitation(options = {}) {
80
+ try {
81
+ await maybeShowSupportInvitation(supportProfile, {
82
+ usefulResult: true,
83
+ command: ["slopcamera"],
84
+ ...options,
85
+ gitEmail: false
86
+ });
87
+ } catch {}
88
+ }
89
+
90
+ // src/cli.ts
45
91
  var slopcameraCliVersion = SLOPCAMERA_VERSION;
46
92
  var help = `slopcamera ${slopcameraCliVersion}
47
93
 
@@ -56,11 +102,8 @@ Usage:
56
102
  slopcamera code search [query] [--limit <number>]
57
103
  slopcamera code execute <operation> --input <JSON>
58
104
  slopcamera mcp --root <workspace>
59
- slopcamera canvas open <file.tldr|file.tldraw>
60
- slopcamera canvas status
61
- slopcamera canvas url
62
- slopcamera canvas install [--yes] [--download-only]
63
105
  slopcamera doctor
106
+ slopcamera support [--json|protocol --json|offer --json|shown <id>|release <id>|dismiss|snooze|enable|status --json]
64
107
  slopcamera skill path
65
108
  slopcamera skill install [--target codex|claude|agents] [--scope user|project] [--force]
66
109
 
@@ -71,9 +114,8 @@ Render writes the same five replaceable artifacts on every run:
71
114
  <name>.light.png
72
115
  <name>.dark.png
73
116
 
74
- The .tldr file is editable tldraw interchange. It imports into tldraw Offline,
75
- which can save the newer app-owned .tldraw bundle. Rendering does not require
76
- tldraw Offline or the tldraw SDK.
117
+ The .tldr file is editable interchange for browser-based canvas tooling.
118
+ Rendering does not require a desktop application or a bundled UI runtime.
77
119
 
78
120
  Vectorize adaptively traces a raster with a checksum-pinned VTracer binary.
79
121
  It enforces bounded input, decode, time, path, and output budgets and emits a
@@ -85,6 +127,10 @@ Set AI_GATEWAY_API_KEY, or run through \`vercel env run -- \u2026\` so
85
127
  VERCEL_OIDC_TOKEN is available. Slopcamera never stores or prints the token.
86
128
  PNG, JPEG, and WebP responses are signature-checked and published atomically.
87
129
 
130
+ Optional support: after useful work, agents can read slopcamera support protocol --json.
131
+ Discovery uses stderr without claiming an invitation; HRANESS_SUPPORT_AUDIENCE=off disables it.
132
+ No feature requires payment. Imported CLI/SDK calls and probes stay quiet.
133
+
88
134
  Code mode searches and executes a fixed semantic registry. Execute accepts
89
135
  typed JSON for one exact owned operation code; it never evaluates source text.
90
136
 
@@ -187,18 +233,6 @@ var starter = {
187
233
  ],
188
234
  edges: [{ id: "source-result", from: "source", to: "result" }]
189
235
  };
190
- async function confirmInstall() {
191
- if (!process.stdin.isTTY) {
192
- throw new Error("Pass --yes to download the 100\u2013230 MB official tldraw Offline installer");
193
- }
194
- const prompt = createInterface({ input: process.stdin, output: process.stdout });
195
- try {
196
- const answer = await prompt.question("Download, verify, and launch the official tldraw Offline installer? [y/N] ");
197
- return answer.trim().toLowerCase() === "y" || answer.trim().toLowerCase() === "yes";
198
- } finally {
199
- prompt.close();
200
- }
201
- }
202
236
  function hostAdmissionOptions(dependencies) {
203
237
  return dependencies.hostResourceCoordinator === undefined ? {} : { hostResourceCoordinator: dependencies.hostResourceCoordinator };
204
238
  }
@@ -216,15 +250,7 @@ function canonicalArguments(args) {
216
250
  }
217
251
  throw new Error("Use slopcamera image vectorize or generate");
218
252
  }
219
- if (surface === "canvas") {
220
- if (subcommand === "open")
221
- return ["open", ...rest];
222
- if (subcommand === "status" || subcommand === "url" || subcommand === "install") {
223
- return ["desktop", subcommand, ...rest];
224
- }
225
- throw new Error("Use slopcamera canvas open, status, url, or install");
226
- }
227
- if (surface === "init" || surface === "check" || surface === "render" || surface === "vectorize" || surface === "generate" || surface === "open" || surface === "desktop") {
253
+ if (surface === "init" || surface === "check" || surface === "render" || surface === "vectorize" || surface === "generate") {
228
254
  throw new Error(`The flat \`${surface}\` command moved to a namespaced Slopcamera surface.
229
255
 
230
256
  ${help}`);
@@ -232,6 +258,10 @@ ${help}`);
232
258
  return args;
233
259
  }
234
260
  async function main(args, dependencies = {}) {
261
+ if (args[0] === "support") {
262
+ process.exitCode = await runProductSupportCommand(args.slice(1), dependencies.supportEnvironment === undefined ? {} : { env: dependencies.supportEnvironment });
263
+ return;
264
+ }
235
265
  const [command, ...rest] = canonicalArguments(args);
236
266
  if (command === undefined || command === "help" || command === "--help" || command === "-h") {
237
267
  console.log(help);
@@ -249,6 +279,7 @@ async function main(args, dependencies = {}) {
249
279
  await writeFile(filePath, `${JSON.stringify(starter, null, 2)}
250
280
  `);
251
281
  console.log(`Created ${filePath}`);
282
+ reportUsefulResult(dependencies.onUsefulResult);
252
283
  return;
253
284
  }
254
285
  if (command === "check") {
@@ -274,6 +305,7 @@ async function main(args, dependencies = {}) {
274
305
  }), hostAdmissionOptions(dependencies));
275
306
  console.log(artifactSummary(result.artifacts));
276
307
  printFindings(result.findings);
308
+ reportUsefulResult(dependencies.onUsefulResult);
277
309
  return;
278
310
  }
279
311
  if (command === "vectorize") {
@@ -304,6 +336,7 @@ async function main(args, dependencies = {}) {
304
336
  } else {
305
337
  (dependencies.log ?? console.log)(`Vectorized ${result.receipt.width}\xD7${result.receipt.height} with ` + `${result.receipt.profile}/${result.receipt.representation}: ${result.outputPath}`);
306
338
  }
339
+ reportUsefulResult(dependencies.onUsefulResult);
307
340
  return;
308
341
  }
309
342
  if (command === "generate") {
@@ -329,6 +362,7 @@ async function main(args, dependencies = {}) {
329
362
  } else {
330
363
  (dependencies.log ?? console.log)(`Generated ${result.mediaType} with ${result.model}: ${result.outputPath} (${result.bytes} bytes, request ${result.requestId})`);
331
364
  }
365
+ reportUsefulResult(dependencies.onUsefulResult);
332
366
  return;
333
367
  }
334
368
  if (command === "code") {
@@ -367,6 +401,9 @@ async function main(args, dependencies = {}) {
367
401
  ...hostAdmissionOptions(dependencies)
368
402
  });
369
403
  (dependencies.log ?? console.log)(JSON.stringify({ operation, result }, null, 2));
404
+ if (operation === "slopcamera.diagram.render" || operation === "slopcamera.image.vectorize" || operation === "slopcamera.image.generate") {
405
+ reportUsefulResult(dependencies.onUsefulResult);
406
+ }
370
407
  return;
371
408
  }
372
409
  throw new Error("Use slopcamera code search [query] or slopcamera code execute <operation> --input <JSON>");
@@ -382,14 +419,7 @@ async function main(args, dependencies = {}) {
382
419
  });
383
420
  return;
384
421
  }
385
- if (command === "open") {
386
- const parsed = parseArguments(rest, new Set);
387
- await openInDesktop(requiredPositional(parsed, 0, "tldraw file"));
388
- console.log("Opened in tldraw Offline.");
389
- return;
390
- }
391
422
  if (command === "doctor") {
392
- const status = await desktopStatus();
393
423
  console.log(`slopcamera ${slopcameraCliVersion}`);
394
424
  console.log(`Bun ${process.versions.bun ?? "not detected"}`);
395
425
  console.log("Headless diagram SVG/PNG/tldraw renderer ready");
@@ -397,42 +427,8 @@ async function main(args, dependencies = {}) {
397
427
  console.log("Root-relative MCP check/render server ready (trusted local workspace)");
398
428
  const gateway = slopcameraGatewayCredentialStatus();
399
429
  console.log(gateway.available ? `Vercel AI Gateway ready via ${gateway.source}` : "Vercel AI Gateway requires AI_GATEWAY_API_KEY or VERCEL_OIDC_TOKEN");
400
- console.log(status.installedPath === null ? "tldraw Offline not installed (optional)" : `tldraw Offline: ${status.installedPath}`);
401
- console.log(status.server === null ? "tldraw Offline agent server not running (optional)" : `tldraw Offline agent server: localhost:${status.server.port}`);
402
430
  return;
403
431
  }
404
- if (command === "desktop") {
405
- const [subcommand, ...subcommandArgs] = rest;
406
- if (subcommand === "status") {
407
- const status = await desktopStatus();
408
- console.log(JSON.stringify(status, null, 2));
409
- return;
410
- }
411
- if (subcommand === "url") {
412
- const release = await getLatestDesktopRelease();
413
- const asset = selectDesktopAsset(release);
414
- console.log(JSON.stringify({
415
- release: release.tag_name,
416
- releaseUrl: release.html_url,
417
- asset: asset.name,
418
- url: asset.browser_download_url,
419
- bytes: asset.size,
420
- sha256: asset.digest
421
- }, null, 2));
422
- return;
423
- }
424
- if (subcommand === "install") {
425
- const parsed = parseArguments(subcommandArgs, new Set);
426
- if (!parsed.flags.has("yes") && !await confirmInstall()) {
427
- console.log("Cancelled.");
428
- return;
429
- }
430
- const result = await installDesktop({ downloadOnly: parsed.flags.has("download-only") });
431
- console.log(`${parsed.flags.has("download-only") ? "Downloaded" : "Prepared"} tldraw Offline ${result.release}: ${result.filePath}`);
432
- return;
433
- }
434
- throw new Error("Use slopcamera canvas status, url, or install");
435
- }
436
432
  if (command === "skill") {
437
433
  const [subcommand, ...subcommandArgs] = rest;
438
434
  if (subcommand === "path") {
@@ -467,7 +463,13 @@ ${help}`);
467
463
  }
468
464
  if (import.meta.main) {
469
465
  try {
470
- await main(process.argv.slice(2));
466
+ const env = standaloneSupportEnvironment();
467
+ let usefulResult = false;
468
+ await main(process.argv.slice(2), { supportEnvironment: env, onUsefulResult: () => {
469
+ usefulResult = true;
470
+ } });
471
+ if (usefulResult && (process.exitCode ?? 0) === 0)
472
+ await showProductSupportInvitation({ env });
471
473
  } catch (error) {
472
474
  console.error(error instanceof Error ? error.message : String(error));
473
475
  process.exitCode = 1;