@aiaiai-pt/martha-cli 0.48.0 → 0.51.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
@@ -4,6 +4,34 @@ All notable changes to `@aiaiai-pt/martha-cli`. Format: [Keep a Changelog](https
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [0.51.1] — 2026-07-17
8
+
9
+ ### Fixed — hosted embed cache migration (#955)
10
+
11
+ - Hosted bundle URLs and generated HTML snippets now use the one-time `0.3.0`
12
+ cache key needed to escape the former immutable stable-file policy.
13
+ - HTML snippets apply the same key to `stylesheet-url`, because the loader
14
+ query is not inherited by the sibling CSS request.
15
+
16
+ ## [0.51.0] — 2026-07-17
17
+
18
+ ### Added — customer-configurable agent display names (#951)
19
+
20
+ - `martha agents create --display-name <name>` sets the customer-facing chat
21
+ identity without changing the stable technical agent key.
22
+ - Agent YAML/JSON create and update files round-trip `display_name`; list and
23
+ detail output now show both the display name and technical key.
24
+
25
+ ## [0.49.0] — 2026-07-15
26
+
27
+ ### Added — UMS-gated second-party approval governance (#583 G1+G2)
28
+
29
+ - `martha approvals` now surfaces the server-computed requester, required-group
30
+ snapshot, and whether the current viewer can resolve the case. Resolution
31
+ remains server-authoritative and reports typed group/self-approval failures.
32
+ - `martha policy` and `martha approvals` consistently honor `--api-url`, including
33
+ machine-readable `--json` workflows against non-default Martha deployments.
34
+
7
35
  ## [0.48.0] — 2026-07-13
8
36
 
9
37
  ### Changed — BREAKING: `martha runner` means ONE thing (#714 runner-journey unification)
package/dist/index.js CHANGED
@@ -11119,7 +11119,7 @@ init_config();
11119
11119
  init_errors();
11120
11120
 
11121
11121
  // src/version.ts
11122
- var CLI_VERSION = "0.48.0";
11122
+ var CLI_VERSION = "0.51.1";
11123
11123
 
11124
11124
  // src/commands/sessions.ts
11125
11125
  function relativeTime(iso) {
@@ -11549,12 +11549,19 @@ var agentsConfig = {
11549
11549
  },
11550
11550
  normalizeBody: normalizeAgentBody,
11551
11551
  extraCreateOptions: (cmd) => {
11552
- cmd.option("--name <name>", "Agent name").option("--reasoning <mode>", "Where the agent reasons: 'martha' (Martha-hosted, default) or " + "'self-hosted' (your service; reached via webhook)").option("--enable-host-runner", "Enable a host runner + mint a runner key: attach `martha runner` as this " + "agent's host executor (channel tool.* only). Alias: --runner-key").option("--runner-key", "Alias for --enable-host-runner").option("--model <model>", "LLM model (e.g. anthropic/claude-sonnet-4-6)").option("--provider <provider>", "LLM provider (anthropic, openai)").option("--prompt <text>", "System prompt").option("--description <text>", "Agent description").option("--temperature <n>", "Temperature (0-1)").option("--max-tokens <n>", "Max output tokens").option("--tags <tags>", "Capability domains (comma-separated)").option("--local-tools <tools>", "Local tools (comma-separated)").option("--type <type>", "Deprecated: use --reasoning. cloud=Martha-hosted, external=self-hosted").option("--auth <method>", "Deprecated: use --enable-host-runner. service-account (self-hosted only) or api-key");
11552
+ cmd.option("--name <name>", "Stable technical agent key").option("--display-name <name>", "Customer-facing name shown in chat").option("--reasoning <mode>", "Where the agent reasons: 'martha' (Martha-hosted, default) or " + "'self-hosted' (your service; reached via webhook)").option("--enable-host-runner", "Enable a host runner + mint a runner key: attach `martha runner` as this " + "agent's host executor (channel tool.* only). Alias: --runner-key").option("--runner-key", "Alias for --enable-host-runner").option("--model <model>", "LLM model (e.g. anthropic/claude-sonnet-4-6)").option("--provider <provider>", "LLM provider (anthropic, openai)").option("--prompt <text>", "System prompt").option("--description <text>", "Agent description").option("--temperature <n>", "Temperature (0-1)").option("--max-tokens <n>", "Max output tokens").option("--tags <tags>", "Capability domains (comma-separated)").option("--local-tools <tools>", "Local tools (comma-separated)").option("--type <type>", "Deprecated: use --reasoning. cloud=Martha-hosted, external=self-hosted").option("--auth <method>", "Deprecated: use --enable-host-runner. service-account (self-hosted only) or api-key");
11553
11553
  },
11554
11554
  buildInlineBody: (opts) => {
11555
11555
  if (!opts.name)
11556
11556
  return null;
11557
11557
  const body = { name: opts.name };
11558
+ if (opts.displayName !== undefined) {
11559
+ const displayName = String(opts.displayName).trim();
11560
+ if (!displayName) {
11561
+ throw new CLIError("--display-name must contain visible text", 4 /* Validation */);
11562
+ }
11563
+ body.display_name = displayName;
11564
+ }
11558
11565
  if (opts.description)
11559
11566
  body.description = opts.description;
11560
11567
  if (opts.prompt)
@@ -11607,6 +11614,10 @@ var agentsConfig = {
11607
11614
  },
11608
11615
  listColumns: [
11609
11616
  { header: "NAME", accessor: (item) => String(item.name ?? "") },
11617
+ {
11618
+ header: "DISPLAY NAME",
11619
+ accessor: (item) => String(item.display_name ?? "-")
11620
+ },
11610
11621
  {
11611
11622
  header: "MODEL",
11612
11623
  accessor: (item) => {
@@ -11621,8 +11632,11 @@ var agentsConfig = {
11621
11632
  { header: "VER", accessor: (item) => String(item.version ?? 1) }
11622
11633
  ],
11623
11634
  renderDetail: (agent) => {
11624
- console.log(source_default.bold(`Agent: ${agent.name}
11635
+ console.log(source_default.bold(`Agent: ${agent.display_name ?? agent.name}
11625
11636
  `));
11637
+ console.log(` Technical key: ${agent.name}`);
11638
+ if (agent.display_name)
11639
+ console.log(` Display name: ${agent.display_name}`);
11626
11640
  if (agent.description)
11627
11641
  console.log(` ${agent.description}
11628
11642
  `);
@@ -16983,13 +16997,11 @@ init_errors();
16983
16997
  function registerApprovalCommands(program2) {
16984
16998
  const cmd = program2.command("approvals").description("Manage approval cases");
16985
16999
  function getCtx() {
16986
- const ctx = createContext({
17000
+ return createContext({
16987
17001
  profileOverride: program2.opts().profile,
17002
+ apiUrlOverride: program2.opts().apiUrl,
16988
17003
  verbose: program2.opts().verbose
16989
17004
  });
16990
- if (program2.opts().apiUrl)
16991
- ctx.profile.api_url = program2.opts().apiUrl;
16992
- return ctx;
16993
17005
  }
16994
17006
  function isJson() {
16995
17007
  return !!program2.opts().json;
@@ -18879,6 +18891,7 @@ init_errors();
18879
18891
 
18880
18892
  // src/lib/embed.ts
18881
18893
  init_errors();
18894
+ var HOSTED_EMBED_CACHE_KEY = "0.3.0";
18882
18895
  var EMBED_FEATURE_KEYS = [
18883
18896
  "uploads",
18884
18897
  "history",
@@ -18945,12 +18958,13 @@ function getEmbedAssetBaseUrl(apiUrl, override) {
18945
18958
  }
18946
18959
  function bundleUrls(assetBaseUrl) {
18947
18960
  const base = normalizeAssetBaseUrl(assetBaseUrl);
18961
+ const asset = (filename) => `${base}${filename}?v=${HOSTED_EMBED_CACHE_KEY}`;
18948
18962
  return {
18949
- webComponent: `${base}martha-chat.ce.js`,
18950
- esm: `${base}martha-chat.es.js`,
18951
- react: `${base}martha-chat.react.js`,
18952
- svelte: `${base}martha-chat.svelte.js`,
18953
- css: `${base}martha-chat.css`
18963
+ webComponent: asset("martha-chat.ce.js"),
18964
+ esm: asset("martha-chat.es.js"),
18965
+ react: asset("martha-chat.react.js"),
18966
+ svelte: asset("martha-chat.svelte.js"),
18967
+ css: asset("martha-chat.css")
18954
18968
  };
18955
18969
  }
18956
18970
  function normalizeOrigin(input) {
@@ -19132,7 +19146,8 @@ function renderHtmlSnippet(options) {
19132
19146
  const urls = bundleUrls(options.assetBaseUrl);
19133
19147
  const attrs = [
19134
19148
  `api-url=${jsString(options.apiUrl)}`,
19135
- `client-key=${jsString(options.clientKey)}`
19149
+ `client-key=${jsString(options.clientKey)}`,
19150
+ `stylesheet-url=${jsString(urls.css)}`
19136
19151
  ];
19137
19152
  if (options.mode === "launcher")
19138
19153
  attrs.push("launcher");
@@ -20916,13 +20931,11 @@ function assertOneOf(value, allowed, flag) {
20916
20931
  function registerPolicyCommands(program2) {
20917
20932
  const cmd = program2.command("policy").description("Manage the tenant's invoke-time capability policy");
20918
20933
  function getCtx() {
20919
- const ctx = createContext({
20934
+ return createContext({
20920
20935
  profileOverride: program2.opts().profile,
20936
+ apiUrlOverride: program2.opts().apiUrl,
20921
20937
  verbose: program2.opts().verbose
20922
20938
  });
20923
- if (program2.opts().apiUrl)
20924
- ctx.profile.api_url = program2.opts().apiUrl;
20925
- return ctx;
20926
20939
  }
20927
20940
  const isJson = () => !!program2.opts().json;
20928
20941
  cmd.command("show").description("Show the current policy: settings + rules").action(async () => {
@@ -21208,6 +21221,8 @@ ${typed.hint}
21208
21221
  // src/commands/authz.ts
21209
21222
  var DEFAULT_ENTITY = "document_collection";
21210
21223
  var DEFAULT_ACTION = "read";
21224
+ var APPROVAL_ENTITY = "approval";
21225
+ var RESOLVE_ACTION = "resolve";
21211
21226
  function registerAuthzCommands(program2) {
21212
21227
  function getCtx() {
21213
21228
  const ctx = createContext({
@@ -21222,6 +21237,7 @@ function registerAuthzCommands(program2) {
21222
21237
  registerCollections(program2, getCtx, isJson);
21223
21238
  registerAccess(program2, getCtx, isJson);
21224
21239
  registerGroups(program2, getCtx, isJson);
21240
+ registerApprovers(program2, getCtx, isJson);
21225
21241
  }
21226
21242
  function renderGrantsTable(resp) {
21227
21243
  if (resp.grants.length === 0) {
@@ -21479,6 +21495,71 @@ function registerGroups(program2, getCtx, isJson) {
21479
21495
  }
21480
21496
  });
21481
21497
  }
21498
+ function registerApprovers(program2, getCtx, isJson) {
21499
+ const cmd = program2.command("approvers").description("Manage who may resolve approval cases in the tenant (UMS approval/resolve). " + "Noun-first sugar over `access` on the approval entity.");
21500
+ cmd.command("add <group>").description("Make a group a tenant approver (its members can resolve approvals)").option("--tenant <tenant>", "Target tenant (super-admin only)").action(async (group, opts) => {
21501
+ const ctx = getCtx();
21502
+ const json = isJson();
21503
+ try {
21504
+ await grant(ctx, {
21505
+ granteeType: "group",
21506
+ granteeId: group,
21507
+ entityType: APPROVAL_ENTITY,
21508
+ action: RESOLVE_ACTION,
21509
+ objectId: null,
21510
+ tenant: opts.tenant
21511
+ });
21512
+ emitOk(json, {
21513
+ status: "approver_added",
21514
+ entity_type: APPROVAL_ENTITY,
21515
+ action: RESOLVE_ACTION,
21516
+ grantee: `group:${group}`,
21517
+ text: `Group ${group} can now resolve approvals in this tenant.`
21518
+ });
21519
+ } catch (err) {
21520
+ emitAuthzError(err, json);
21521
+ }
21522
+ });
21523
+ cmd.command("remove <group>").description("Remove a group's tenant approver binding").option("--tenant <tenant>", "Target tenant (super-admin only)").action(async (group, opts) => {
21524
+ const ctx = getCtx();
21525
+ const json = isJson();
21526
+ try {
21527
+ await revoke(ctx, {
21528
+ granteeType: "group",
21529
+ granteeId: group,
21530
+ entityType: APPROVAL_ENTITY,
21531
+ action: RESOLVE_ACTION,
21532
+ objectId: null,
21533
+ tenant: opts.tenant
21534
+ });
21535
+ emitOk(json, {
21536
+ status: "approver_removed",
21537
+ grantee: `group:${group}`,
21538
+ text: `Group ${group} can no longer resolve approvals in this tenant.`
21539
+ });
21540
+ } catch (err) {
21541
+ emitAuthzError(err, json);
21542
+ }
21543
+ });
21544
+ cmd.command("list").description("Show which groups may resolve approvals in the tenant").option("--tenant <tenant>", "Target tenant (super-admin only)").action(async (opts) => {
21545
+ const ctx = getCtx();
21546
+ const json = isJson();
21547
+ try {
21548
+ const resp = await listGrants(ctx, {
21549
+ entityType: APPROVAL_ENTITY,
21550
+ action: RESOLVE_ACTION,
21551
+ tenant: opts.tenant
21552
+ });
21553
+ if (json) {
21554
+ console.log(JSON.stringify(resp, null, 2));
21555
+ } else {
21556
+ console.log(renderGrantsTable(resp));
21557
+ }
21558
+ } catch (err) {
21559
+ emitAuthzError(err, json);
21560
+ }
21561
+ });
21562
+ }
21482
21563
  function emitOk(json, payload) {
21483
21564
  if (json) {
21484
21565
  const rest = { ...payload };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiaiai-pt/martha-cli",
3
- "version": "0.48.0",
3
+ "version": "0.51.1",
4
4
  "description": "Terminal-first client for the Martha AI platform",
5
5
  "homepage": "https://docs.martha.nomadriver.co",
6
6
  "repository": {