@aiaiai-pt/martha-cli 0.27.1 → 0.29.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 +7 -0
- package/dist/index.js +218 -33
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,13 @@ All notable changes to `@aiaiai-pt/martha-cli`. Format: [Keep a Changelog](https
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.28.0] — 2026-06-30
|
|
8
|
+
|
|
9
|
+
### Added — #714 Slice 1 external-agent `event.emit` binding surfaces
|
|
10
|
+
- `martha agents grant-trigger <agent> <trigger>` binds an agent's emitted events to a trigger (so an agent-emitted event may fire it); `martha agents revoke-trigger <agent> <trigger>` removes the binding; `martha agents triggers <agent>` lists the triggers an agent may fire.
|
|
11
|
+
- `martha triggers allow-agent <trigger> <agentId>` accepts an agent as a source for a trigger; `martha triggers disallow-agent <trigger> <agentId>` removes it; `martha triggers agents <trigger>` lists the accepted agent sources.
|
|
12
|
+
- Both directions mutate the same `agent_trigger_access` binding (#714) and reflect each other. All support `--json`. The trigger is resolved by name → id; the agent side keys on the agent's stored (server-normalized) name and the agent id, respectively. Cross-tenant agent/trigger → 404 (IDOR guard).
|
|
13
|
+
|
|
7
14
|
## [0.20.0] — 2026-06-21
|
|
8
15
|
|
|
9
16
|
### Added — #649 agent→agent delegation surfaces
|
package/dist/index.js
CHANGED
|
@@ -5,43 +5,25 @@ var __getProtoOf = Object.getPrototypeOf;
|
|
|
5
5
|
var __defProp = Object.defineProperty;
|
|
6
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
function __accessProp(key) {
|
|
9
|
-
return this[key];
|
|
10
|
-
}
|
|
11
|
-
var __toESMCache_node;
|
|
12
|
-
var __toESMCache_esm;
|
|
13
8
|
var __toESM = (mod, isNodeMode, target) => {
|
|
14
|
-
var canCache = mod != null && typeof mod === "object";
|
|
15
|
-
if (canCache) {
|
|
16
|
-
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
17
|
-
var cached = cache.get(mod);
|
|
18
|
-
if (cached)
|
|
19
|
-
return cached;
|
|
20
|
-
}
|
|
21
9
|
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
22
10
|
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
23
11
|
for (let key of __getOwnPropNames(mod))
|
|
24
12
|
if (!__hasOwnProp.call(to, key))
|
|
25
13
|
__defProp(to, key, {
|
|
26
|
-
get:
|
|
14
|
+
get: () => mod[key],
|
|
27
15
|
enumerable: true
|
|
28
16
|
});
|
|
29
|
-
if (canCache)
|
|
30
|
-
cache.set(mod, to);
|
|
31
17
|
return to;
|
|
32
18
|
};
|
|
33
19
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
34
|
-
var __returnValue = (v) => v;
|
|
35
|
-
function __exportSetter(name, newValue) {
|
|
36
|
-
this[name] = __returnValue.bind(null, newValue);
|
|
37
|
-
}
|
|
38
20
|
var __export = (target, all) => {
|
|
39
21
|
for (var name in all)
|
|
40
22
|
__defProp(target, name, {
|
|
41
23
|
get: all[name],
|
|
42
24
|
enumerable: true,
|
|
43
25
|
configurable: true,
|
|
44
|
-
set:
|
|
26
|
+
set: (newValue) => all[name] = () => newValue
|
|
45
27
|
});
|
|
46
28
|
};
|
|
47
29
|
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
@@ -1019,7 +1001,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1019
1001
|
this._exitCallback = (err) => {
|
|
1020
1002
|
if (err.code !== "commander.executeSubCommandAsync") {
|
|
1021
1003
|
throw err;
|
|
1022
|
-
}
|
|
1004
|
+
} else {}
|
|
1023
1005
|
};
|
|
1024
1006
|
}
|
|
1025
1007
|
return this;
|
|
@@ -11081,7 +11063,7 @@ init_config();
|
|
|
11081
11063
|
init_errors();
|
|
11082
11064
|
|
|
11083
11065
|
// src/version.ts
|
|
11084
|
-
var CLI_VERSION = "0.
|
|
11066
|
+
var CLI_VERSION = "0.29.0";
|
|
11085
11067
|
|
|
11086
11068
|
// src/commands/sessions.ts
|
|
11087
11069
|
function relativeTime(iso) {
|
|
@@ -13512,7 +13494,7 @@ function registerConfigCommand(program2) {
|
|
|
13512
13494
|
config.current_profile = name;
|
|
13513
13495
|
}
|
|
13514
13496
|
saveConfig(config);
|
|
13515
|
-
if (
|
|
13497
|
+
if (program2.opts().json) {
|
|
13516
13498
|
console.log(JSON.stringify({
|
|
13517
13499
|
name,
|
|
13518
13500
|
profile,
|
|
@@ -13556,7 +13538,7 @@ function registerConfigCommand(program2) {
|
|
|
13556
13538
|
config.current_profile = remaining[0] ?? "default";
|
|
13557
13539
|
}
|
|
13558
13540
|
saveConfig(config);
|
|
13559
|
-
if (
|
|
13541
|
+
if (program2.opts().json) {
|
|
13560
13542
|
console.log(JSON.stringify({ name, deleted: true }));
|
|
13561
13543
|
return;
|
|
13562
13544
|
}
|
|
@@ -15066,6 +15048,50 @@ var agentsConfig = {
|
|
|
15066
15048
|
}
|
|
15067
15049
|
console.log(`Removed function '${functionName}' from agent '${agent}'`);
|
|
15068
15050
|
});
|
|
15051
|
+
parentCmd.command("grant-trigger <agent> <trigger>").description("Allow an agent's emitted events to fire a trigger").action(async (agent, trigger) => {
|
|
15052
|
+
const ctx = getCtx();
|
|
15053
|
+
const t = await ctx.api.get(`/api/admin/triggers/${encodeURIComponent(trigger)}`);
|
|
15054
|
+
const result = await ctx.api.post(`${API_PATH}/${encodeURIComponent(agent)}/triggers`, { trigger_id: t.id });
|
|
15055
|
+
if (isJson()) {
|
|
15056
|
+
console.log(JSON.stringify(result, null, 2));
|
|
15057
|
+
return;
|
|
15058
|
+
}
|
|
15059
|
+
console.log(`Granted trigger '${trigger}' to agent '${agent}'`);
|
|
15060
|
+
});
|
|
15061
|
+
parentCmd.command("revoke-trigger <agent> <trigger>").description("Revoke an agent's binding to a trigger").action(async (agent, trigger) => {
|
|
15062
|
+
const ctx = getCtx();
|
|
15063
|
+
const t = await ctx.api.get(`/api/admin/triggers/${encodeURIComponent(trigger)}`);
|
|
15064
|
+
await ctx.api.del(`${API_PATH}/${encodeURIComponent(agent)}/triggers/${encodeURIComponent(String(t.id))}`);
|
|
15065
|
+
if (isJson()) {
|
|
15066
|
+
console.log(JSON.stringify({ agent, trigger, removed: true }));
|
|
15067
|
+
return;
|
|
15068
|
+
}
|
|
15069
|
+
console.log(`Revoked trigger '${trigger}' from agent '${agent}'`);
|
|
15070
|
+
});
|
|
15071
|
+
parentCmd.command("triggers <agent>").description("List triggers an agent may fire").action(async (agent) => {
|
|
15072
|
+
const ctx = getCtx();
|
|
15073
|
+
const items = await ctx.api.get(`${API_PATH}/${encodeURIComponent(agent)}/triggers`);
|
|
15074
|
+
if (isJson()) {
|
|
15075
|
+
console.log(JSON.stringify(items, null, 2));
|
|
15076
|
+
return;
|
|
15077
|
+
}
|
|
15078
|
+
if (items.length === 0) {
|
|
15079
|
+
console.log(source_default.dim("No triggers bound to this agent."));
|
|
15080
|
+
return;
|
|
15081
|
+
}
|
|
15082
|
+
const nameW = Math.max(7, ...items.map((b) => String(b.trigger_name ?? "").length));
|
|
15083
|
+
const header = ["TRIGGER", "GRANTED BY", "GRANTED AT"].map((h, i) => h.padEnd([nameW, 16, 20][i])).join(" ");
|
|
15084
|
+
console.log(source_default.bold(header));
|
|
15085
|
+
console.log(source_default.dim("-".repeat(header.length)));
|
|
15086
|
+
for (const b of items) {
|
|
15087
|
+
const date = b.granted_at ? new Date(b.granted_at).toISOString().slice(0, 16).replace("T", " ") : "-";
|
|
15088
|
+
console.log([
|
|
15089
|
+
String(b.trigger_name ?? "").padEnd(nameW),
|
|
15090
|
+
String(b.granted_by ?? "-").padEnd(16),
|
|
15091
|
+
date.padEnd(20)
|
|
15092
|
+
].join(" "));
|
|
15093
|
+
}
|
|
15094
|
+
});
|
|
15069
15095
|
parentCmd.command("provision-auth <agent>").description("Provision, switch, or rotate agent auth credentials").requiredOption("--method <method>", "Auth method: service-account or api-key").action(async (agent, opts) => {
|
|
15070
15096
|
const ctx = getCtx();
|
|
15071
15097
|
const methodMap = {
|
|
@@ -15495,6 +15521,51 @@ var triggersConfig = {
|
|
|
15495
15521
|
}
|
|
15496
15522
|
}
|
|
15497
15523
|
});
|
|
15524
|
+
parentCmd.command("allow-agent <trigger> <agentId>").description("Accept an agent's emitted events as a source for a trigger").action(async (trigger, agentId) => {
|
|
15525
|
+
const ctx = getCtx();
|
|
15526
|
+
const t = await ctx.api.get(`/api/admin/triggers/${encodeURIComponent(trigger)}`);
|
|
15527
|
+
const result = await ctx.api.post(`/api/admin/triggers/${encodeURIComponent(String(t.id))}/agents`, { agent_id: agentId });
|
|
15528
|
+
if (isJson()) {
|
|
15529
|
+
console.log(JSON.stringify(result, null, 2));
|
|
15530
|
+
return;
|
|
15531
|
+
}
|
|
15532
|
+
console.log(`Accepted agent '${agentId}' as a source for '${trigger}'`);
|
|
15533
|
+
});
|
|
15534
|
+
parentCmd.command("disallow-agent <trigger> <agentId>").description("Remove an agent as a source for a trigger").action(async (trigger, agentId) => {
|
|
15535
|
+
const ctx = getCtx();
|
|
15536
|
+
const t = await ctx.api.get(`/api/admin/triggers/${encodeURIComponent(trigger)}`);
|
|
15537
|
+
await ctx.api.del(`/api/admin/triggers/${encodeURIComponent(String(t.id))}/agents/${encodeURIComponent(agentId)}`);
|
|
15538
|
+
if (isJson()) {
|
|
15539
|
+
console.log(JSON.stringify({ trigger, agent_id: agentId, removed: true }));
|
|
15540
|
+
return;
|
|
15541
|
+
}
|
|
15542
|
+
console.log(`Removed agent '${agentId}' as a source for '${trigger}'`);
|
|
15543
|
+
});
|
|
15544
|
+
parentCmd.command("agents <trigger>").description("List the agents accepted as sources for a trigger").action(async (trigger) => {
|
|
15545
|
+
const ctx = getCtx();
|
|
15546
|
+
const t = await ctx.api.get(`/api/admin/triggers/${encodeURIComponent(trigger)}`);
|
|
15547
|
+
const items = await ctx.api.get(`/api/admin/triggers/${encodeURIComponent(String(t.id))}/agents`);
|
|
15548
|
+
if (isJson()) {
|
|
15549
|
+
console.log(JSON.stringify(items, null, 2));
|
|
15550
|
+
return;
|
|
15551
|
+
}
|
|
15552
|
+
if (items.length === 0) {
|
|
15553
|
+
console.log(source_default.dim("No agent sources accepted for this trigger."));
|
|
15554
|
+
return;
|
|
15555
|
+
}
|
|
15556
|
+
const nameW = Math.max(5, ...items.map((b) => String(b.agent_name ?? "").length));
|
|
15557
|
+
const header = ["AGENT", "AGENT ID", "GRANTED AT"].map((h, i) => h.padEnd([nameW, 36, 20][i])).join(" ");
|
|
15558
|
+
console.log(source_default.bold(header));
|
|
15559
|
+
console.log(source_default.dim("-".repeat(header.length)));
|
|
15560
|
+
for (const b of items) {
|
|
15561
|
+
const date = b.granted_at ? new Date(b.granted_at).toISOString().slice(0, 16).replace("T", " ") : "-";
|
|
15562
|
+
console.log([
|
|
15563
|
+
String(b.agent_name ?? "-").padEnd(nameW),
|
|
15564
|
+
String(b.agent_id ?? "-").padEnd(36),
|
|
15565
|
+
date.padEnd(20)
|
|
15566
|
+
].join(" "));
|
|
15567
|
+
}
|
|
15568
|
+
});
|
|
15498
15569
|
}
|
|
15499
15570
|
};
|
|
15500
15571
|
|
|
@@ -16488,6 +16559,119 @@ function registerApprovalCommands(program2) {
|
|
|
16488
16559
|
});
|
|
16489
16560
|
}
|
|
16490
16561
|
|
|
16562
|
+
// src/commands/asks.ts
|
|
16563
|
+
init_errors();
|
|
16564
|
+
var KINDS = ["agent_question", "agent_approval_request"];
|
|
16565
|
+
function statusColor(status) {
|
|
16566
|
+
if (status === "approved")
|
|
16567
|
+
return source_default.green(status);
|
|
16568
|
+
if (status === "rejected")
|
|
16569
|
+
return source_default.red(status);
|
|
16570
|
+
if (status === "expired")
|
|
16571
|
+
return source_default.dim(status);
|
|
16572
|
+
return source_default.yellow(status);
|
|
16573
|
+
}
|
|
16574
|
+
function renderAsk(a) {
|
|
16575
|
+
const lines = [
|
|
16576
|
+
`${source_default.bold(a.case_id ?? "?")} ${statusColor(a.status ?? "?")} ${source_default.dim(a.kind ?? "")}`,
|
|
16577
|
+
` ${a.reason ?? ""}`
|
|
16578
|
+
];
|
|
16579
|
+
if (a.context_summary)
|
|
16580
|
+
lines.push(` ${source_default.dim(a.context_summary)}`);
|
|
16581
|
+
if (a.decision) {
|
|
16582
|
+
lines.push(` ${source_default.bold("decision:")} ${statusColor(a.decision)}`);
|
|
16583
|
+
if (a.comment)
|
|
16584
|
+
lines.push(` ${source_default.bold("answer:")} ${a.comment}`);
|
|
16585
|
+
}
|
|
16586
|
+
if (a.expires_at)
|
|
16587
|
+
lines.push(` ${source_default.dim(`expires ${a.expires_at}`)}`);
|
|
16588
|
+
return lines.join(`
|
|
16589
|
+
`);
|
|
16590
|
+
}
|
|
16591
|
+
function registerAskCommands(program2) {
|
|
16592
|
+
const cmd = program2.command("asks").description("Agent asks — questions/approval requests to the human queue (agent credentials)");
|
|
16593
|
+
function getCtx() {
|
|
16594
|
+
const ctx = createContext({
|
|
16595
|
+
profileOverride: program2.opts().profile,
|
|
16596
|
+
verbose: program2.opts().verbose
|
|
16597
|
+
});
|
|
16598
|
+
if (program2.opts().apiUrl)
|
|
16599
|
+
ctx.profile.api_url = program2.opts().apiUrl;
|
|
16600
|
+
return ctx;
|
|
16601
|
+
}
|
|
16602
|
+
function isJson() {
|
|
16603
|
+
return !!program2.opts().json;
|
|
16604
|
+
}
|
|
16605
|
+
cmd.command("create").description("File an ask (the server attributes it to the token's agent)").requiredOption("--reason <text>", "The question / what approval is requested").option("--kind <kind>", `${KINDS.join(" | ")} (default agent_question)`, "agent_question").option("--context <text>", "Context summary for the reviewer").option("--questions <json>", "Structured questions JSON array (ask_user shape: question/header/options/multiSelect)").option("--expires-in <seconds>", "Auto-expire the ask after N seconds").option("--idempotency-key <key>", "Dedup key — retries with the same key do not double-file").action(async (opts) => {
|
|
16606
|
+
if (!KINDS.includes(opts.kind)) {
|
|
16607
|
+
throw new CLIError(`--kind must be one of: ${KINDS.join(", ")}`, 4 /* Validation */);
|
|
16608
|
+
}
|
|
16609
|
+
let questions;
|
|
16610
|
+
if (opts.questions) {
|
|
16611
|
+
try {
|
|
16612
|
+
questions = JSON.parse(opts.questions);
|
|
16613
|
+
} catch {
|
|
16614
|
+
throw new CLIError("--questions must be valid JSON", 4 /* Validation */);
|
|
16615
|
+
}
|
|
16616
|
+
}
|
|
16617
|
+
let expiresIn;
|
|
16618
|
+
if (opts.expiresIn) {
|
|
16619
|
+
expiresIn = parseInt(opts.expiresIn, 10);
|
|
16620
|
+
if (isNaN(expiresIn) || expiresIn < 60) {
|
|
16621
|
+
throw new CLIError("--expires-in must be an integer >= 60 (seconds)", 4 /* Validation */);
|
|
16622
|
+
}
|
|
16623
|
+
}
|
|
16624
|
+
const ctx = getCtx();
|
|
16625
|
+
const ask = await ctx.api.post("/api/agent/asks", {
|
|
16626
|
+
kind: opts.kind,
|
|
16627
|
+
reason: opts.reason,
|
|
16628
|
+
context_summary: opts.context,
|
|
16629
|
+
questions,
|
|
16630
|
+
expires_in_s: expiresIn,
|
|
16631
|
+
idempotency_key: opts.idempotencyKey
|
|
16632
|
+
});
|
|
16633
|
+
if (isJson()) {
|
|
16634
|
+
console.log(JSON.stringify(ask, null, 2));
|
|
16635
|
+
return;
|
|
16636
|
+
}
|
|
16637
|
+
console.log(`Filed ask ${source_default.bold(ask.case_id)} (${ask.status})`);
|
|
16638
|
+
console.log(source_default.dim(`Poll the answer with: martha asks get ${ask.case_id}`));
|
|
16639
|
+
});
|
|
16640
|
+
cmd.command("list").description("List this agent's own asks (newest first)").option("--status <status>", "Filter by status (pending/approved/rejected/expired)").option("--limit <n>", "Max results", "50").action(async (opts) => {
|
|
16641
|
+
const limitN = parseInt(opts.limit, 10);
|
|
16642
|
+
if (isNaN(limitN) || limitN < 1) {
|
|
16643
|
+
throw new CLIError("--limit must be a positive integer", 4 /* Validation */);
|
|
16644
|
+
}
|
|
16645
|
+
const ctx = getCtx();
|
|
16646
|
+
const params = { limit: String(limitN) };
|
|
16647
|
+
if (opts.status)
|
|
16648
|
+
params.status = opts.status;
|
|
16649
|
+
const items = await ctx.api.get("/api/agent/asks", {
|
|
16650
|
+
params
|
|
16651
|
+
});
|
|
16652
|
+
if (isJson()) {
|
|
16653
|
+
console.log(JSON.stringify(items, null, 2));
|
|
16654
|
+
return;
|
|
16655
|
+
}
|
|
16656
|
+
if (items.length === 0) {
|
|
16657
|
+
console.log(source_default.dim("No asks."));
|
|
16658
|
+
return;
|
|
16659
|
+
}
|
|
16660
|
+
console.log(items.map(renderAsk).join(`
|
|
16661
|
+
|
|
16662
|
+
`));
|
|
16663
|
+
});
|
|
16664
|
+
cmd.command("get <caseId>").description("Show one own ask — status, and decision+answer once resolved").action(async (caseId) => {
|
|
16665
|
+
const ctx = getCtx();
|
|
16666
|
+
const ask = await ctx.api.get(`/api/agent/asks/${caseId}`);
|
|
16667
|
+
if (isJson()) {
|
|
16668
|
+
console.log(JSON.stringify(ask, null, 2));
|
|
16669
|
+
return;
|
|
16670
|
+
}
|
|
16671
|
+
console.log(renderAsk(ask));
|
|
16672
|
+
});
|
|
16673
|
+
}
|
|
16674
|
+
|
|
16491
16675
|
// src/commands/tasks.ts
|
|
16492
16676
|
import { readFileSync as readFileSync2 } from "node:fs";
|
|
16493
16677
|
init_errors();
|
|
@@ -16508,7 +16692,7 @@ var sleep4 = (ms, signal) => new Promise((resolve2) => {
|
|
|
16508
16692
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
16509
16693
|
});
|
|
16510
16694
|
var fmtDate2 = (v) => typeof v === "string" ? new Date(v).toISOString().slice(0, 16).replace("T", " ") : "-";
|
|
16511
|
-
var
|
|
16695
|
+
var statusColor2 = (status) => {
|
|
16512
16696
|
switch (status) {
|
|
16513
16697
|
case "open":
|
|
16514
16698
|
return source_default.yellow(status);
|
|
@@ -16611,7 +16795,7 @@ function registerTaskCommands(program2) {
|
|
|
16611
16795
|
const row = columns.map((col, i) => {
|
|
16612
16796
|
let val = col.accessor(item);
|
|
16613
16797
|
if (col.header === "STATUS")
|
|
16614
|
-
val =
|
|
16798
|
+
val = statusColor2(val);
|
|
16615
16799
|
if (col.header === "PRIORITY")
|
|
16616
16800
|
val = priorityColor(val);
|
|
16617
16801
|
return col.header === "STATUS" || col.header === "PRIORITY" ? val.padEnd(widths[i] + (val.length - col.accessor(item).length)) : val.padEnd(widths[i]);
|
|
@@ -16660,7 +16844,7 @@ ${items.length} task(s)`));
|
|
|
16660
16844
|
return;
|
|
16661
16845
|
}
|
|
16662
16846
|
console.log(`Created task ${source_default.cyan(String(result.id ?? ""))}`);
|
|
16663
|
-
console.log(` Status: ${
|
|
16847
|
+
console.log(` Status: ${statusColor2(String(result.status ?? "-"))}`);
|
|
16664
16848
|
console.log(` Priority: ${priorityColor(String(result.priority ?? "-"))}`);
|
|
16665
16849
|
console.log(` Goal: ${truncate2(String(result.goal ?? "-"), 60)}`);
|
|
16666
16850
|
});
|
|
@@ -16674,7 +16858,7 @@ ${items.length} task(s)`));
|
|
|
16674
16858
|
console.log(source_default.bold("Task Details"));
|
|
16675
16859
|
console.log(source_default.dim("-".repeat(50)));
|
|
16676
16860
|
console.log(`${source_default.cyan("ID:")} ${item.id ?? "-"}`);
|
|
16677
|
-
console.log(`${source_default.cyan("Status:")} ${
|
|
16861
|
+
console.log(`${source_default.cyan("Status:")} ${statusColor2(String(item.status ?? "-"))}`);
|
|
16678
16862
|
console.log(`${source_default.cyan("Priority:")} ${priorityColor(String(item.priority ?? "-"))}`);
|
|
16679
16863
|
console.log(`${source_default.cyan("Title:")} ${item.title ?? "-"}`);
|
|
16680
16864
|
console.log(`${source_default.cyan("Agent:")} ${item.agent_definition_id ?? "-"}`);
|
|
@@ -16785,7 +16969,7 @@ ${items.length} task(s) available`));
|
|
|
16785
16969
|
return;
|
|
16786
16970
|
}
|
|
16787
16971
|
console.log(`Claimed task ${source_default.cyan(String(result.id ?? "").slice(0, 8))}`);
|
|
16788
|
-
console.log(` Status: ${
|
|
16972
|
+
console.log(` Status: ${statusColor2(String(result.status ?? "-"))}`);
|
|
16789
16973
|
console.log(` Executor: ${result.executor_id ?? "-"}`);
|
|
16790
16974
|
console.log(` Lease: expires ${fmtDate2(result.lease_expires_at)}`);
|
|
16791
16975
|
});
|
|
@@ -16958,7 +17142,7 @@ ${items.length} task(s) available`));
|
|
|
16958
17142
|
return;
|
|
16959
17143
|
}
|
|
16960
17144
|
console.log(`Completed task ${source_default.cyan(String(result.id ?? "").slice(0, 8))}`);
|
|
16961
|
-
console.log(` Status: ${
|
|
17145
|
+
console.log(` Status: ${statusColor2(String(result.status ?? "-"))}`);
|
|
16962
17146
|
console.log(` Completed at: ${fmtDate2(result.completed_at)}`);
|
|
16963
17147
|
});
|
|
16964
17148
|
}
|
|
@@ -19970,7 +20154,7 @@ async function resolveCredentialFlag(value) {
|
|
|
19970
20154
|
// src/commands/policy.ts
|
|
19971
20155
|
init_errors();
|
|
19972
20156
|
var ACTIONS = ["allow", "require_approval", "block"];
|
|
19973
|
-
var
|
|
20157
|
+
var KINDS2 = ["risk_tag", "risk_level", "capability"];
|
|
19974
20158
|
var SCOPES = ["any", "agent", "client"];
|
|
19975
20159
|
var truncate4 = (s, n) => s.length > n ? s.slice(0, n - 1) + "…" : s;
|
|
19976
20160
|
function assertOneOf(value, allowed, flag) {
|
|
@@ -20066,8 +20250,8 @@ function registerPolicyCommands(program2) {
|
|
|
20066
20250
|
console.log(`Safe-default bundle ${enabled ? source_default.yellow("enabled") : source_default.dim("disabled")}.`);
|
|
20067
20251
|
});
|
|
20068
20252
|
const rule = cmd.command("rule").description("Manage explicit policy rules");
|
|
20069
|
-
rule.command("add").description("Create or update a rule").requiredOption(`--kind <kind>`, `Match kind (${
|
|
20070
|
-
assertOneOf(opts.kind,
|
|
20253
|
+
rule.command("add").description("Create or update a rule").requiredOption(`--kind <kind>`, `Match kind (${KINDS2.join("|")})`).requiredOption("--value <value>", "Match value (a risk tag, level, or capability ref)").requiredOption(`--action <action>`, `Action (${ACTIONS.join("|")})`).option(`--scope <scope>`, `Principal scope (${SCOPES.join("|")})`, "any").option("--note <text>", "Optional human note").action(async (opts) => {
|
|
20254
|
+
assertOneOf(opts.kind, KINDS2, "--kind");
|
|
20071
20255
|
assertOneOf(opts.action, ACTIONS, "--action");
|
|
20072
20256
|
assertOneOf(opts.scope, SCOPES, "--scope");
|
|
20073
20257
|
const ctx = getCtx();
|
|
@@ -21363,6 +21547,7 @@ registerDocumentCommands(program2);
|
|
|
21363
21547
|
registerDocumentSyncCommands(program2);
|
|
21364
21548
|
registerWikiCommands(program2);
|
|
21365
21549
|
registerApprovalCommands(program2);
|
|
21550
|
+
registerAskCommands(program2);
|
|
21366
21551
|
registerTaskCommands(program2);
|
|
21367
21552
|
registerRunnerCommand(program2);
|
|
21368
21553
|
registerTeamCommands(program2);
|