@aiaiai-pt/martha-cli 0.48.0 → 0.50.0
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 +10 -0
- package/dist/index.js +73 -9
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,16 @@ All notable changes to `@aiaiai-pt/martha-cli`. Format: [Keep a Changelog](https
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.49.0] — 2026-07-15
|
|
8
|
+
|
|
9
|
+
### Added — UMS-gated second-party approval governance (#583 G1+G2)
|
|
10
|
+
|
|
11
|
+
- `martha approvals` now surfaces the server-computed requester, required-group
|
|
12
|
+
snapshot, and whether the current viewer can resolve the case. Resolution
|
|
13
|
+
remains server-authoritative and reports typed group/self-approval failures.
|
|
14
|
+
- `martha policy` and `martha approvals` consistently honor `--api-url`, including
|
|
15
|
+
machine-readable `--json` workflows against non-default Martha deployments.
|
|
16
|
+
|
|
7
17
|
## [0.48.0] — 2026-07-13
|
|
8
18
|
|
|
9
19
|
### 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.50.0";
|
|
11123
11123
|
|
|
11124
11124
|
// src/commands/sessions.ts
|
|
11125
11125
|
function relativeTime(iso) {
|
|
@@ -16983,13 +16983,11 @@ init_errors();
|
|
|
16983
16983
|
function registerApprovalCommands(program2) {
|
|
16984
16984
|
const cmd = program2.command("approvals").description("Manage approval cases");
|
|
16985
16985
|
function getCtx() {
|
|
16986
|
-
|
|
16986
|
+
return createContext({
|
|
16987
16987
|
profileOverride: program2.opts().profile,
|
|
16988
|
+
apiUrlOverride: program2.opts().apiUrl,
|
|
16988
16989
|
verbose: program2.opts().verbose
|
|
16989
16990
|
});
|
|
16990
|
-
if (program2.opts().apiUrl)
|
|
16991
|
-
ctx.profile.api_url = program2.opts().apiUrl;
|
|
16992
|
-
return ctx;
|
|
16993
16991
|
}
|
|
16994
16992
|
function isJson() {
|
|
16995
16993
|
return !!program2.opts().json;
|
|
@@ -20916,13 +20914,11 @@ function assertOneOf(value, allowed, flag) {
|
|
|
20916
20914
|
function registerPolicyCommands(program2) {
|
|
20917
20915
|
const cmd = program2.command("policy").description("Manage the tenant's invoke-time capability policy");
|
|
20918
20916
|
function getCtx() {
|
|
20919
|
-
|
|
20917
|
+
return createContext({
|
|
20920
20918
|
profileOverride: program2.opts().profile,
|
|
20919
|
+
apiUrlOverride: program2.opts().apiUrl,
|
|
20921
20920
|
verbose: program2.opts().verbose
|
|
20922
20921
|
});
|
|
20923
|
-
if (program2.opts().apiUrl)
|
|
20924
|
-
ctx.profile.api_url = program2.opts().apiUrl;
|
|
20925
|
-
return ctx;
|
|
20926
20922
|
}
|
|
20927
20923
|
const isJson = () => !!program2.opts().json;
|
|
20928
20924
|
cmd.command("show").description("Show the current policy: settings + rules").action(async () => {
|
|
@@ -21208,6 +21204,8 @@ ${typed.hint}
|
|
|
21208
21204
|
// src/commands/authz.ts
|
|
21209
21205
|
var DEFAULT_ENTITY = "document_collection";
|
|
21210
21206
|
var DEFAULT_ACTION = "read";
|
|
21207
|
+
var APPROVAL_ENTITY = "approval";
|
|
21208
|
+
var RESOLVE_ACTION = "resolve";
|
|
21211
21209
|
function registerAuthzCommands(program2) {
|
|
21212
21210
|
function getCtx() {
|
|
21213
21211
|
const ctx = createContext({
|
|
@@ -21222,6 +21220,7 @@ function registerAuthzCommands(program2) {
|
|
|
21222
21220
|
registerCollections(program2, getCtx, isJson);
|
|
21223
21221
|
registerAccess(program2, getCtx, isJson);
|
|
21224
21222
|
registerGroups(program2, getCtx, isJson);
|
|
21223
|
+
registerApprovers(program2, getCtx, isJson);
|
|
21225
21224
|
}
|
|
21226
21225
|
function renderGrantsTable(resp) {
|
|
21227
21226
|
if (resp.grants.length === 0) {
|
|
@@ -21479,6 +21478,71 @@ function registerGroups(program2, getCtx, isJson) {
|
|
|
21479
21478
|
}
|
|
21480
21479
|
});
|
|
21481
21480
|
}
|
|
21481
|
+
function registerApprovers(program2, getCtx, isJson) {
|
|
21482
|
+
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.");
|
|
21483
|
+
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) => {
|
|
21484
|
+
const ctx = getCtx();
|
|
21485
|
+
const json = isJson();
|
|
21486
|
+
try {
|
|
21487
|
+
await grant(ctx, {
|
|
21488
|
+
granteeType: "group",
|
|
21489
|
+
granteeId: group,
|
|
21490
|
+
entityType: APPROVAL_ENTITY,
|
|
21491
|
+
action: RESOLVE_ACTION,
|
|
21492
|
+
objectId: null,
|
|
21493
|
+
tenant: opts.tenant
|
|
21494
|
+
});
|
|
21495
|
+
emitOk(json, {
|
|
21496
|
+
status: "approver_added",
|
|
21497
|
+
entity_type: APPROVAL_ENTITY,
|
|
21498
|
+
action: RESOLVE_ACTION,
|
|
21499
|
+
grantee: `group:${group}`,
|
|
21500
|
+
text: `Group ${group} can now resolve approvals in this tenant.`
|
|
21501
|
+
});
|
|
21502
|
+
} catch (err) {
|
|
21503
|
+
emitAuthzError(err, json);
|
|
21504
|
+
}
|
|
21505
|
+
});
|
|
21506
|
+
cmd.command("remove <group>").description("Remove a group's tenant approver binding").option("--tenant <tenant>", "Target tenant (super-admin only)").action(async (group, opts) => {
|
|
21507
|
+
const ctx = getCtx();
|
|
21508
|
+
const json = isJson();
|
|
21509
|
+
try {
|
|
21510
|
+
await revoke(ctx, {
|
|
21511
|
+
granteeType: "group",
|
|
21512
|
+
granteeId: group,
|
|
21513
|
+
entityType: APPROVAL_ENTITY,
|
|
21514
|
+
action: RESOLVE_ACTION,
|
|
21515
|
+
objectId: null,
|
|
21516
|
+
tenant: opts.tenant
|
|
21517
|
+
});
|
|
21518
|
+
emitOk(json, {
|
|
21519
|
+
status: "approver_removed",
|
|
21520
|
+
grantee: `group:${group}`,
|
|
21521
|
+
text: `Group ${group} can no longer resolve approvals in this tenant.`
|
|
21522
|
+
});
|
|
21523
|
+
} catch (err) {
|
|
21524
|
+
emitAuthzError(err, json);
|
|
21525
|
+
}
|
|
21526
|
+
});
|
|
21527
|
+
cmd.command("list").description("Show which groups may resolve approvals in the tenant").option("--tenant <tenant>", "Target tenant (super-admin only)").action(async (opts) => {
|
|
21528
|
+
const ctx = getCtx();
|
|
21529
|
+
const json = isJson();
|
|
21530
|
+
try {
|
|
21531
|
+
const resp = await listGrants(ctx, {
|
|
21532
|
+
entityType: APPROVAL_ENTITY,
|
|
21533
|
+
action: RESOLVE_ACTION,
|
|
21534
|
+
tenant: opts.tenant
|
|
21535
|
+
});
|
|
21536
|
+
if (json) {
|
|
21537
|
+
console.log(JSON.stringify(resp, null, 2));
|
|
21538
|
+
} else {
|
|
21539
|
+
console.log(renderGrantsTable(resp));
|
|
21540
|
+
}
|
|
21541
|
+
} catch (err) {
|
|
21542
|
+
emitAuthzError(err, json);
|
|
21543
|
+
}
|
|
21544
|
+
});
|
|
21545
|
+
}
|
|
21482
21546
|
function emitOk(json, payload) {
|
|
21483
21547
|
if (json) {
|
|
21484
21548
|
const rest = { ...payload };
|