@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 +28 -0
- package/dist/index.js +98 -17
- package/package.json +1 -1
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.
|
|
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>", "
|
|
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
|
-
|
|
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:
|
|
18950
|
-
esm:
|
|
18951
|
-
react:
|
|
18952
|
-
svelte:
|
|
18953
|
-
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
|
-
|
|
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 };
|