@aiaiai-pt/martha-cli 0.66.1 → 0.68.1

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/CHANGELOG.md CHANGED
@@ -2,6 +2,29 @@
2
2
 
3
3
  All notable changes to `@aiaiai-pt/martha-cli`. Format: [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). This project adheres to semver — `0.x` releases may include breaking changes between minor versions.
4
4
 
5
+ ## [0.68.1] — 2026-11-03
6
+
7
+ ### Fixed
8
+
9
+ - `martha prompts create -f <file>` accepts `content` again. 0.68.0 refused `content` on every prompt write so that `prompts update` would stop dropping it silently, but the create route requires `content`, so no prompt could be created from a file. The refusal now applies to `update` only.
10
+
11
+ ## [0.68.0] — 2026-11-02
12
+
13
+ ### Added
14
+
15
+ - `martha prompts version <name> -f <file> [-m <summary>] [--promote [environment]]` creates a new version of a prompt from the file's `content` (the server's `POST /prompts/{name}/versions`) and can promote it in the same step. Until now the CLI had no way to change a prompt's text.
16
+
17
+ ### Fixed
18
+
19
+ - `martha prompts promote <name>` sends the version and environment the server requires (`--version`, default the newest; `--environment`, default `production`). It used to send `{}`, which the server rejects.
20
+ - `martha prompts update -f <file>` refuses a file with `content` and points at `prompts version`. The update route only changes metadata, so the content was silently dropped while the CLI printed "Updated (v1)".
21
+
22
+ ## [0.67.0] — 2026-11-02
23
+
24
+ ### Added
25
+
26
+ - `martha tasks note <id> <text>` posts a human-lane note to a task's activity log through the existing `POST /api/admin/tasks/{id}/activity` (entry type comment, author set by the server). Empty or whitespace-only text is refused before any request. `--json` prints the created entry (#2377).
27
+
5
28
  ## [0.66.1] — 2026-11-01
6
29
 
7
30
  ### Fixed
package/dist/index.js CHANGED
@@ -11149,7 +11149,7 @@ ${items.length} ${config.typeNamePlural}`));
11149
11149
  throw new CLIError("Missing required field: name", 4 /* Validation */);
11150
11150
  }
11151
11151
  if (config.normalizeBody)
11152
- body = config.normalizeBody(body);
11152
+ body = config.normalizeBody(body, "create");
11153
11153
  const result = await ctx.api.post(config.apiPath, body);
11154
11154
  if (isJson()) {
11155
11155
  console.log(JSON.stringify(result, null, 2));
@@ -11164,7 +11164,7 @@ ${items.length} ${config.typeNamePlural}`));
11164
11164
  throw new CLIError(`File name '${body.name}' does not match argument '${name}'`, 4 /* Validation */);
11165
11165
  }
11166
11166
  if (config.normalizeBody)
11167
- body = config.normalizeBody(body);
11167
+ body = config.normalizeBody(body, "update");
11168
11168
  const result = await ctx.api.put(`${config.apiPath}/${encodeURIComponent(name)}`, body);
11169
11169
  config.verifyUpdateResult?.(body, result);
11170
11170
  if (isJson()) {
@@ -11244,7 +11244,7 @@ init_config();
11244
11244
  init_errors();
11245
11245
 
11246
11246
  // src/version.ts
11247
- var CLI_VERSION = "0.66.1";
11247
+ var CLI_VERSION = "0.68.1";
11248
11248
 
11249
11249
  // src/commands/sessions.ts
11250
11250
  function relativeTime(iso) {
@@ -17710,7 +17710,32 @@ var workflowsConfig = {
17710
17710
  };
17711
17711
 
17712
17712
  // src/commands/prompts.ts
17713
+ init_errors();
17713
17714
  var API_PATH2 = "/api/admin/definitions/prompts";
17715
+ var ENVIRONMENTS = ["production", "staging"];
17716
+ function promptVersionBody(file, changeSummary) {
17717
+ const content = typeof file.content === "string" ? file.content : "";
17718
+ if (!content.trim()) {
17719
+ throw new CLIError("The file has no `content` to version", 4 /* Validation */, "A prompt version is the whole prompt text: put it under `content:`.");
17720
+ }
17721
+ return changeSummary ? { content, change_summary: changeSummary } : { content };
17722
+ }
17723
+ function promptPromoteBody(version, environment = "production") {
17724
+ if (!Number.isInteger(version) || version < 1) {
17725
+ throw new CLIError(`Invalid version '${version}'`, 4 /* Validation */);
17726
+ }
17727
+ if (!ENVIRONMENTS.includes(environment)) {
17728
+ throw new CLIError(`Invalid environment '${environment}'`, 4 /* Validation */, `Use one of: ${ENVIRONMENTS.join(", ")}`);
17729
+ }
17730
+ return { version, environment };
17731
+ }
17732
+ function latestVersionNumber(data) {
17733
+ const rows = (Array.isArray(data) ? data : data?.items) ?? [];
17734
+ const nums = rows.map((r) => Number(r.version)).filter((n) => Number.isInteger(n) && n > 0);
17735
+ if (!nums.length)
17736
+ throw new CLIError("The prompt has no versions", 1 /* Error */);
17737
+ return Math.max(...nums);
17738
+ }
17714
17739
  var promptsConfig = {
17715
17740
  typeName: "prompt",
17716
17741
  typeNamePlural: "prompts",
@@ -17792,16 +17817,43 @@ var promptsConfig = {
17792
17817
  params.is_protected = "true";
17793
17818
  return params;
17794
17819
  },
17820
+ normalizeBody: (body, action) => {
17821
+ if (action === "update" && "content" in body) {
17822
+ throw new CLIError("`prompts update` changes metadata only and the server ignores `content`; change the text with " + "`martha prompts version <name> -f <file> --promote`", 4 /* Validation */);
17823
+ }
17824
+ return body;
17825
+ },
17795
17826
  extraCommands: (parentCmd, getCtx, isJson) => {
17796
- parentCmd.command("promote <name>").description("Promote staging version to production").action(async (name) => {
17827
+ const promote = async (ctx, name, version, environment) => ctx.api.post(`${API_PATH2}/${encodeURIComponent(name)}/promote`, promptPromoteBody(version, environment));
17828
+ parentCmd.command("version <name>").description("Create a new version of a prompt from a file's `content` (optionally promote it)").requiredOption("-f, --file <path>", "YAML or JSON file with a `content` field").option("-m, --summary <text>", "What changed in this version").option("--promote [environment]", "Promote the new version (default: production)").action(async (name, opts) => {
17829
+ const ctx = getCtx();
17830
+ const body = promptVersionBody(loadDefinitionFile(opts.file), opts.summary);
17831
+ const created = await ctx.api.post(`${API_PATH2}/${encodeURIComponent(name)}/versions`, body);
17832
+ const version = Number(created.version);
17833
+ let promoted;
17834
+ if (opts.promote) {
17835
+ const env = typeof opts.promote === "string" ? opts.promote : "production";
17836
+ promoted = await promote(ctx, name, version, env);
17837
+ }
17838
+ if (isJson()) {
17839
+ console.log(JSON.stringify({ version: created, promoted }, null, 2));
17840
+ return;
17841
+ }
17842
+ console.log(`Created '${name}' version ${version}`);
17843
+ if (opts.promote) {
17844
+ const env = typeof opts.promote === "string" ? opts.promote : "production";
17845
+ console.log(`Promoted '${name}' version ${version} → ${env}`);
17846
+ }
17847
+ });
17848
+ parentCmd.command("promote <name>").description("Promote a version (default: the newest) to an environment (default: production)").option("--version <n>", "Version number to promote", (v) => Number(v)).option("--environment <env>", "production | staging", "production").action(async (name, opts) => {
17797
17849
  const ctx = getCtx();
17798
- const result = await ctx.api.post(`${API_PATH2}/${encodeURIComponent(name)}/promote`, {});
17850
+ const version = opts.version ?? latestVersionNumber(await ctx.api.get(`${API_PATH2}/${encodeURIComponent(name)}/versions`));
17851
+ const result = await promote(ctx, name, version, opts.environment);
17799
17852
  if (isJson()) {
17800
17853
  console.log(JSON.stringify(result, null, 2));
17801
17854
  return;
17802
17855
  }
17803
- const prodVer = result.production_version_number ?? result.version;
17804
- console.log(`Promoted '${name}' staging → production (version ${prodVer})`);
17856
+ console.log(`Promoted '${name}' version ${version} → ${opts.environment}`);
17805
17857
  });
17806
17858
  parentCmd.command("linked-collections <name>").description("List collections using this prompt as an extra prompt").action(async (name) => {
17807
17859
  const ctx = getCtx();
@@ -19269,6 +19321,13 @@ var priorityColor = (priority) => {
19269
19321
  return priority;
19270
19322
  }
19271
19323
  };
19324
+ function buildNoteBody(text) {
19325
+ const content = text.trim();
19326
+ if (!content) {
19327
+ throw new CLIError("Note text must not be empty", 4 /* Validation */);
19328
+ }
19329
+ return { content };
19330
+ }
19272
19331
  function registerTaskCommands(program) {
19273
19332
  const cmd = program.command("tasks").description("Manage agent tasks");
19274
19333
  function getCtx() {
@@ -19425,6 +19484,15 @@ ${source_default.red("Error:")}`);
19425
19484
  }
19426
19485
  console.log(`Cancelled task ${id}`);
19427
19486
  });
19487
+ cmd.command("note <id> <text>").description("Add a note to a task's activity log (human lane)").action(async (id, text) => {
19488
+ const ctx = getCtx();
19489
+ const entry = await ctx.api.post(`/api/admin/tasks/${encodeURIComponent(id)}/activity`, buildNoteBody(text));
19490
+ if (isJson()) {
19491
+ console.log(JSON.stringify(entry, null, 2));
19492
+ return;
19493
+ }
19494
+ console.log(`Noted task ${id} (entry ${entry.id ?? "?"})`);
19495
+ });
19428
19496
  cmd.command("poll").description("Poll for open tasks available for claiming").option("--agent <id>", "Filter by agent definition ID (human tokens only; ignored under agent auth)").option("--team <name>", "Poll a team's queue (name or UUID)").option("--limit <n>", "Max results", "10").action(async (opts) => {
19429
19497
  const ctx = getCtx();
19430
19498
  const limitN = parseInt(opts.limit, 10);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiaiai-pt/martha-cli",
3
- "version": "0.66.1",
3
+ "version": "0.68.1",
4
4
  "description": "Terminal-first client for the Martha AI platform",
5
5
  "homepage": "https://docs.martha.nomadriver.co",
6
6
  "repository": {