@workser/cli 0.6.15 → 0.6.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -3743,6 +3743,27 @@ workser agent-cloud machines # video, data analysis, design, ...
3743
3743
  A model marked "needs your own key" will make \`publish\` FAIL unless a matching
3744
3744
  secret is stored first. Add the key with \`add <id> secret\` before setting it.
3745
3745
 
3746
+ ## Agents need a paid plan \u2014 the trial does not include them
3747
+
3748
+ \`create\` and \`run\` both refuse with **402** on a free or trialling
3749
+ organisation. That is a rule, not a fault: every run buys model tokens and
3750
+ holds a machine, so it costs real money the moment it happens.
3751
+
3752
+ **When you hit it, hand the plan over \u2014 do not just describe it.** Workser
3753
+ files the refusal on the conversation as a step and an artifact the user can
3754
+ click, so the person you are helping gets something actionable rather than a
3755
+ paragraph. Say plainly what you were doing, that agents need a plan, and stop.
3756
+
3757
+ Do NOT:
3758
+
3759
+ - retry the call, or try a different agent \u2014 the answer is the same
3760
+ - try to work around it by running the job yourself as a coding agent; that is
3761
+ a different product and it will not be there when the user closes the window
3762
+ - guess at prices, discounts or trial extensions
3763
+
3764
+ If the user asks how much: it is per minute of run time plus the model, and the
3765
+ plan page has the current figures. You do not have them.
3766
+
3746
3767
  ## When to reach for this
3747
3768
 
3748
3769
  When the user describes a job that **keeps happening** and needs judgement:
@@ -8336,7 +8357,7 @@ function registerMemory(program3) {
8336
8357
  const results = res?.results ?? res ?? [];
8337
8358
  if (!results?.length) return line(import_picocolors24.default.dim("No matching memories."));
8338
8359
  for (const r of results) {
8339
- line(`${import_picocolors24.default.dim(r.id ?? "?")} ${r.memory ?? r.content ?? ""}`);
8360
+ line(`${import_picocolors24.default.dim(r.id ?? "?")} ${memoryText(r)}`);
8340
8361
  }
8341
8362
  });
8342
8363
  })
@@ -8351,6 +8372,13 @@ function registerMemory(program3) {
8351
8372
  })
8352
8373
  );
8353
8374
  }
8375
+ function memoryText(r) {
8376
+ const text = r?.memory ?? r?.chunk ?? r?.content ?? r?.text;
8377
+ if (typeof text === "string" && text.trim()) return text;
8378
+ const title = r?.documents?.[0]?.title;
8379
+ if (typeof title === "string" && title.trim()) return title;
8380
+ return import_picocolors24.default.dim("(no readable text on this row)");
8381
+ }
8354
8382
 
8355
8383
  // src/commands/note.ts
8356
8384
  var import_picocolors25 = __toESM(require_picocolors(), 1);
@@ -8741,7 +8769,7 @@ function registerImage(program3) {
8741
8769
  );
8742
8770
  const res = await api(
8743
8771
  ctx,
8744
- `/projects/${projectId}/images/generate`,
8772
+ `/v1/projects/${projectId}/images/generate`,
8745
8773
  {
8746
8774
  method: "POST",
8747
8775
  body: {
@@ -8781,7 +8809,7 @@ function registerImage(program3) {
8781
8809
  action(async ({ ctx, opts, args }) => {
8782
8810
  const projectId = requireProject(ctx);
8783
8811
  const source = await resolveMediaSource({ url: opts.url, file: opts.file });
8784
- const res = await api(ctx, `/projects/${projectId}/images/understand`, {
8812
+ const res = await api(ctx, `/v1/projects/${projectId}/images/understand`, {
8785
8813
  method: "POST",
8786
8814
  body: { source, query: args[0], task: opts.task }
8787
8815
  });
@@ -8814,7 +8842,7 @@ function registerVideo(program3) {
8814
8842
  action(async ({ ctx, opts, args }) => {
8815
8843
  const projectId = requireProject(ctx);
8816
8844
  const source = await resolveMediaSource({ url: opts.url, file: opts.file });
8817
- const res = await api(ctx, `/projects/${projectId}/video/understand`, {
8845
+ const res = await api(ctx, `/v1/projects/${projectId}/video/understand`, {
8818
8846
  method: "POST",
8819
8847
  body: { source, query: args[0], task: opts.task }
8820
8848
  });
@@ -8834,7 +8862,7 @@ function registerAudio(program3) {
8834
8862
  action(async ({ ctx, opts, args }) => {
8835
8863
  const projectId = requireProject(ctx);
8836
8864
  const source = await resolveMediaSource({ url: opts.url, file: opts.file });
8837
- const res = await api(ctx, `/projects/${projectId}/audio/understand`, {
8865
+ const res = await api(ctx, `/v1/projects/${projectId}/audio/understand`, {
8838
8866
  method: "POST",
8839
8867
  body: { source, query: args[0], task: opts.task }
8840
8868
  });
@@ -9255,6 +9283,7 @@ var STATUSES2 = [
9255
9283
  ];
9256
9284
  var PRIORITIES2 = ["urgent", "high", "normal", "low"];
9257
9285
  var SIZES = ["small", "standard"];
9286
+ var ESTIMATES = ["10m", "30m", "45m", "1h", "1h+"];
9258
9287
  var ROLES = [
9259
9288
  "pm",
9260
9289
  "architect",
@@ -9337,6 +9366,9 @@ function registerTask(program3) {
9337
9366
  ).option("--priority <value>", `how urgent (${PRIORITIES2.join(" | ")})`).option(
9338
9367
  "--size <value>",
9339
9368
  `small lets the channel start it without asking; standard asks (${SIZES.join(" | ")})`
9369
+ ).option(
9370
+ "--estimate <value>",
9371
+ `roughly how long this should take, shown on the plan (${ESTIMATES.join(" | ")})`
9340
9372
  ).option(
9341
9373
  "--status <value>",
9342
9374
  `start it somewhere other than 'todo' \u2014 use 'backlog' for a later phase's work (${STATUSES2.join(" | ")})`
@@ -9347,6 +9379,8 @@ function registerTask(program3) {
9347
9379
  if (opts.priority !== void 0)
9348
9380
  assertOneOf("--priority", opts.priority, PRIORITIES2);
9349
9381
  if (opts.size !== void 0) assertOneOf("--size", opts.size, SIZES);
9382
+ if (opts.estimate !== void 0)
9383
+ assertOneOf("--estimate", opts.estimate, ESTIMATES);
9350
9384
  if (opts.status !== void 0)
9351
9385
  assertOneOf("--status", opts.status, STATUSES2);
9352
9386
  const hasChannelOrigin = Boolean(
@@ -9364,6 +9398,7 @@ function registerTask(program3) {
9364
9398
  phase: opts.phase,
9365
9399
  priority: opts.priority,
9366
9400
  size: opts.size,
9401
+ estimate: opts.estimate,
9367
9402
  // `backlog` for a later phase's work: written down so the owner can
9368
9403
  // read the whole plan, with nothing for the runner to pick up.
9369
9404
  status: opts.status,
@@ -10679,7 +10714,7 @@ function readMirror(cwd, filePath) {
10679
10714
  // src/commands/design.ts
10680
10715
  var import_picocolors35 = __toESM(require_picocolors(), 1);
10681
10716
  function registerDesign(program3) {
10682
- const design = program3.command("design").description("Read the project's brand (colours, fonts, logo)");
10717
+ const design = program3.command("design").description("The project's brand, and pictures of the screens you draw");
10683
10718
  design.command("show").description("Show this project's brand \u2014 read it before writing any UI").option("--raw", "print the generated token files verbatim instead of a summary").action(
10684
10719
  action(async ({ ctx, opts }) => {
10685
10720
  const projectId = requireProject(ctx);
@@ -10733,6 +10768,41 @@ function registerDesign(program3) {
10733
10768
  });
10734
10769
  })
10735
10770
  );
10771
+ design.command("shot").argument("<files...>", "the HTML screens to photograph, relative to the project folder").description("Render a design screen to a PNG beside it, for surfaces that can't run a page").option("--width <px>", "artboard width (default 1440)", (v) => Number(v)).option("--height <px>", "artboard height (default 900)", (v) => Number(v)).action(
10772
+ action(async ({ ctx, args, opts }) => {
10773
+ const projectId = requireProject(ctx);
10774
+ const res = await api(ctx, "/v1/design-shot", {
10775
+ method: "POST",
10776
+ body: {
10777
+ projectId,
10778
+ files: args,
10779
+ width: opts.width,
10780
+ height: opts.height
10781
+ }
10782
+ });
10783
+ ok(res, () => {
10784
+ for (const shot of res.shots ?? []) {
10785
+ if (shot.out) {
10786
+ line(`${import_picocolors35.default.green("\u2713")} ${shot.file} ${import_picocolors35.default.dim("\u2192")} ${shot.out}`);
10787
+ } else {
10788
+ line(`${import_picocolors35.default.red("\u2717")} ${shot.file} ${import_picocolors35.default.dim(shot.error ?? "no image")}`);
10789
+ }
10790
+ }
10791
+ for (const path of res.refused ?? []) {
10792
+ line(import_picocolors35.default.dim(`skipped ${path} \u2014 not a page inside this project`));
10793
+ }
10794
+ const made = (res.shots ?? []).filter((s) => s.out).length;
10795
+ if (made) {
10796
+ line("");
10797
+ line(
10798
+ import_picocolors35.default.dim(
10799
+ `Record each one so it shows up: workser artifact add <file>.png --kind design -d "<what this screen is>"`
10800
+ )
10801
+ );
10802
+ }
10803
+ });
10804
+ })
10805
+ );
10736
10806
  }
10737
10807
  function parseTokens(files) {
10738
10808
  const doc = files.find((f) => f.path.endsWith("tokens.json"));
@@ -11754,7 +11824,7 @@ function colour(d) {
11754
11824
 
11755
11825
  // src/index.ts
11756
11826
  var pkg = {
11757
- version: true ? "0.6.15" : "0.0.0-dev"
11827
+ version: true ? "0.6.17" : "0.0.0-dev"
11758
11828
  };
11759
11829
  var program2 = new Command();
11760
11830
  program2.name("workser").description(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@workser/cli",
3
- "version": "0.6.15",
3
+ "version": "0.6.17",
4
4
  "description": "Workser CLI — give your local AI agent native DevOps & infrastructure on Workser. The agent runs `workser …` to provision, deploy, and manage real apps.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -79,6 +79,27 @@ workser agent-cloud machines # video, data analysis, design, ...
79
79
  A model marked "needs your own key" will make `publish` FAIL unless a matching
80
80
  secret is stored first. Add the key with `add <id> secret` before setting it.
81
81
 
82
+ ## Agents need a paid plan — the trial does not include them
83
+
84
+ `create` and `run` both refuse with **402** on a free or trialling
85
+ organisation. That is a rule, not a fault: every run buys model tokens and
86
+ holds a machine, so it costs real money the moment it happens.
87
+
88
+ **When you hit it, hand the plan over — do not just describe it.** Workser
89
+ files the refusal on the conversation as a step and an artifact the user can
90
+ click, so the person you are helping gets something actionable rather than a
91
+ paragraph. Say plainly what you were doing, that agents need a plan, and stop.
92
+
93
+ Do NOT:
94
+
95
+ - retry the call, or try a different agent — the answer is the same
96
+ - try to work around it by running the job yourself as a coding agent; that is
97
+ a different product and it will not be there when the user closes the window
98
+ - guess at prices, discounts or trial extensions
99
+
100
+ If the user asks how much: it is per minute of run time plus the model, and the
101
+ plan page has the current figures. You do not have them.
102
+
82
103
  ## When to reach for this
83
104
 
84
105
  When the user describes a job that **keeps happening** and needs judgement: