@datarails-ai/dr-cli 1.6.186 → 1.6.188
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/README.md +4 -3
- package/dist/cli.js +264 -27
- package/dist/scopes-map.json +39 -7
- package/dist/skills/dr-cli/reference/safety.md +3 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -332,9 +332,9 @@ are covered); a missing `--server`, or a missing `--account` in customer mode;
|
|
|
332
332
|
`--user-id`); a host override (`--app-space-host`, `DR_APP_SPACE_HOST`,
|
|
333
333
|
`--connectors-url`); in org mode, any command the scopes map does not prove
|
|
334
334
|
read-only, plus the few read-scoped commands with side effects
|
|
335
|
-
(`devices request-logs`, `desk smtp test`, `dashboards prepare
|
|
336
|
-
|
|
337
|
-
|
|
335
|
+
(`devices request-logs`, `desk smtp test`, `dashboards prepare`). A pin that is
|
|
336
|
+
set but malformed refuses every command (`--help` and `--version` still print).
|
|
337
|
+
A refusal exits 3, like a scope denial.
|
|
338
338
|
|
|
339
339
|
### API keys (headless and CI)
|
|
340
340
|
|
|
@@ -465,6 +465,7 @@ dr skill print <name> # print an embedded skill's SKILL.md
|
|
|
465
465
|
| Connectors | `connectors publish <dataqueryFile>`, `connectors query repoint <queryId>`, `connectors binding get <fileboxUuid>` (drives the connectors control-plane over VPN) |
|
|
466
466
|
| Agent Studio | `agents list/get/versions/test-link/refresh/pull/update/create/mcp-servers/cli-scopes/scope-registry`, `agents set-listed/set-global/set-visibility/archive` (two-step confirm), `agents models/catalog/system-entities`, `agents skills list/get/versions/bundle/pull/create/publish/delete` (`delete` two-step confirm). A CLI-exposed agent's `dr` sessions are capped by its CLI scopes (`resource:action`, default `*:read`): set with `update --cli-scopes <list>` / `--reset-cli-scopes [--cli-scopes-reason <text>]` or `create --expose-cli --cli-scopes <list>`, read with `cli-scopes`; the scope history and restore stay in the Backoffice (service-token only) |
|
|
467
467
|
| Agent release pins | `agents served`, `agents pin/unpin` (two-step confirm): the version each deployment serves; `--server`, `--servers <keys>` or `--production` |
|
|
468
|
+
| Agent schedules | `agents schedules list/create/update/delete` (`delete` two-step confirm): ai-service cron runs of a managed agent, as the session user. `--agent-id` defaults to the token's `agent_id` claim. Like every `agents` command, an agent needs `managed-agents:write` in its CLI scopes (`managed-agents:destructive` for `delete`): `agents update --id <agentId> --cli-scopes '*:read,managed-agents:write,managed-agents:destructive'` |
|
|
468
469
|
| Skill | `skill` — prints embedded `SKILL.md` |
|
|
469
470
|
|
|
470
471
|
### Connectors: TLS over VPN
|
package/dist/cli.js
CHANGED
|
@@ -8,7 +8,7 @@ import { fileURLToPath as fileURLToPath3 } from "url";
|
|
|
8
8
|
// package.json
|
|
9
9
|
var package_default = {
|
|
10
10
|
name: "@datarails-ai/dr-cli",
|
|
11
|
-
version: "1.6.
|
|
11
|
+
version: "1.6.188",
|
|
12
12
|
description: "Datarails CLI",
|
|
13
13
|
type: "module",
|
|
14
14
|
engines: {
|
|
@@ -40,7 +40,7 @@ var package_default = {
|
|
|
40
40
|
postinstall: "node scripts/postinstall.mjs"
|
|
41
41
|
},
|
|
42
42
|
dependencies: {
|
|
43
|
-
"@datarails-ai/dr-appspace-cli": "0.12.
|
|
43
|
+
"@datarails-ai/dr-appspace-cli": "0.12.62",
|
|
44
44
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
45
45
|
"@napi-rs/keyring": "^1.3.0",
|
|
46
46
|
commander: "^12.1.0",
|
|
@@ -69,7 +69,7 @@ var package_default = {
|
|
|
69
69
|
};
|
|
70
70
|
|
|
71
71
|
// src/buildInfo.ts
|
|
72
|
-
var BUILD_TIME = "2026-11-
|
|
72
|
+
var BUILD_TIME = "2026-11-02T15:33:34.634Z";
|
|
73
73
|
function formatBuildTime(iso) {
|
|
74
74
|
if (iso === "") return "";
|
|
75
75
|
const d = new Date(iso);
|
|
@@ -4390,7 +4390,11 @@ var PROD_GATE_TIER_B = /* @__PURE__ */ new Set([
|
|
|
4390
4390
|
"template-library|update",
|
|
4391
4391
|
"template-library|unpublish",
|
|
4392
4392
|
"template-library|archive",
|
|
4393
|
-
"template-library|restore"
|
|
4393
|
+
"template-library|restore",
|
|
4394
|
+
// agent schedules (dr agents schedules delete). One org row; the plan prints its cron,
|
|
4395
|
+
// timezone, agent, prompt and run-as user, and `dr agents schedules create` with them
|
|
4396
|
+
// restores it (running as the re-creator: create cannot set the run-as user).
|
|
4397
|
+
"managed-agent-schedule|delete"
|
|
4394
4398
|
]);
|
|
4395
4399
|
var PROD_GATE_TIER_A = /* @__PURE__ */ new Set([
|
|
4396
4400
|
// workflow / mec — soft-delete + cascade deletes. `archive` also covers the
|
|
@@ -5211,8 +5215,7 @@ var ORG_MODE_UNSCOPED_ALLOWED = /* @__PURE__ */ new Set([
|
|
|
5211
5215
|
var ORG_MODE_READ_SCOPED_REFUSED = /* @__PURE__ */ new Set([
|
|
5212
5216
|
"devices request-logs",
|
|
5213
5217
|
"desk smtp test",
|
|
5214
|
-
"dashboards prepare"
|
|
5215
|
-
"storyboards prepare"
|
|
5218
|
+
"dashboards prepare"
|
|
5216
5219
|
]);
|
|
5217
5220
|
var LOCAL_COMMANDS_WITH_TARGET_FLAGS = /* @__PURE__ */ new Set([
|
|
5218
5221
|
"app-space scaffold"
|
|
@@ -55679,9 +55682,9 @@ async function listTemplates(client, params, options) {
|
|
|
55679
55682
|
);
|
|
55680
55683
|
return out ?? [];
|
|
55681
55684
|
}
|
|
55682
|
-
async function getTemplate(client, id, options) {
|
|
55685
|
+
async function getTemplate(client, id, options, params) {
|
|
55683
55686
|
const out = await client.getJSON(
|
|
55684
|
-
`/api/processes/v2/process_templates/${id}`,
|
|
55687
|
+
`/api/processes/v2/process_templates/${id}${buildQueryString(params)}`,
|
|
55685
55688
|
options
|
|
55686
55689
|
);
|
|
55687
55690
|
if (out === null) {
|
|
@@ -55700,9 +55703,9 @@ async function createTemplate(client, payload, options) {
|
|
|
55700
55703
|
}
|
|
55701
55704
|
return out;
|
|
55702
55705
|
}
|
|
55703
|
-
async function updateTemplate(client, id, payload, options) {
|
|
55706
|
+
async function updateTemplate(client, id, payload, options, params) {
|
|
55704
55707
|
const out = await client.putJSON(
|
|
55705
|
-
`/api/processes/v2/process_templates/${id}`,
|
|
55708
|
+
`/api/processes/v2/process_templates/${id}${buildQueryString(params)}`,
|
|
55706
55709
|
payload,
|
|
55707
55710
|
options
|
|
55708
55711
|
);
|
|
@@ -57168,6 +57171,10 @@ function validateTagsArray2(raw2) {
|
|
|
57168
57171
|
}
|
|
57169
57172
|
|
|
57170
57173
|
// src/commands/mecWorkflow.ts
|
|
57174
|
+
var MEC_DETAIL = { only_mec: true };
|
|
57175
|
+
function getMecTemplate(client, id, signal, params = {}) {
|
|
57176
|
+
return getTemplate(client, id, { signal }, { ...params, ...MEC_DETAIL });
|
|
57177
|
+
}
|
|
57171
57178
|
function dash6(s) {
|
|
57172
57179
|
if (s === null || s === void 0) return "-";
|
|
57173
57180
|
if (typeof s === "number") return String(s);
|
|
@@ -57303,7 +57310,7 @@ function renderMecWorkflowList(out, rows) {
|
|
|
57303
57310
|
}
|
|
57304
57311
|
async function runMecWorkflowGet(cfg) {
|
|
57305
57312
|
await requireMec(cfg.client, { signal: cfg.signal });
|
|
57306
|
-
const tmpl = await withMec(() =>
|
|
57313
|
+
const tmpl = await withMec(() => getMecTemplate(cfg.client, cfg.id, cfg.signal));
|
|
57307
57314
|
if (cfg.asJson) {
|
|
57308
57315
|
writeJSONIndented(cfg.out, tmpl);
|
|
57309
57316
|
return;
|
|
@@ -57788,9 +57795,7 @@ async function runMecWorkflowUpdate(cfg) {
|
|
|
57788
57795
|
server: cfg.serverFlag,
|
|
57789
57796
|
confirmCmd: `dr mec workflow update ${cfg.id} --file ${cfg.payloadFile} --server ${cfg.serverFlag}`,
|
|
57790
57797
|
describe: async () => {
|
|
57791
|
-
const current = await withMec(
|
|
57792
|
-
() => getTemplate(cfg.client, cfg.id, { signal: cfg.signal })
|
|
57793
|
-
);
|
|
57798
|
+
const current = await withMec(() => getMecTemplate(cfg.client, cfg.id, cfg.signal));
|
|
57794
57799
|
const lines = [`current name: ${current.name}`];
|
|
57795
57800
|
if (cfg.payload.config?.name !== void 0 && cfg.payload.config.name !== current.name) {
|
|
57796
57801
|
lines.push(`new name: ${cfg.payload.config.name}`);
|
|
@@ -57805,9 +57810,7 @@ async function runMecWorkflowUpdate(cfg) {
|
|
|
57805
57810
|
},
|
|
57806
57811
|
execute: async () => {
|
|
57807
57812
|
const updated = await withMec(
|
|
57808
|
-
() => updateTemplate(cfg.client, cfg.id, cfg.payload, {
|
|
57809
|
-
signal: cfg.signal
|
|
57810
|
-
})
|
|
57813
|
+
() => updateTemplate(cfg.client, cfg.id, cfg.payload, { signal: cfg.signal }, MEC_DETAIL)
|
|
57811
57814
|
);
|
|
57812
57815
|
if (cfg.asJson) {
|
|
57813
57816
|
writeJSONIndented(cfg.out, updated);
|
|
@@ -57828,9 +57831,7 @@ async function runMecWorkflowState(cfg) {
|
|
|
57828
57831
|
};
|
|
57829
57832
|
await preflightConfirmToken(action, cfg.token);
|
|
57830
57833
|
await requireMec(cfg.client, { signal: cfg.signal });
|
|
57831
|
-
const current = await withMec(
|
|
57832
|
-
() => getTemplate(cfg.client, cfg.id, { signal: cfg.signal })
|
|
57833
|
-
);
|
|
57834
|
+
const current = await withMec(() => getMecTemplate(cfg.client, cfg.id, cfg.signal));
|
|
57834
57835
|
let cascadeWarning = [];
|
|
57835
57836
|
if (cfg.active) {
|
|
57836
57837
|
cascadeWarning = await collectMecActivationCascade(cfg.client, current, cfg.signal);
|
|
@@ -57880,8 +57881,8 @@ async function collectMecActivationCascade(client, template, signal) {
|
|
|
57880
57881
|
const lines = [];
|
|
57881
57882
|
const instancesAll = template.process_instances ?? [];
|
|
57882
57883
|
if (instancesAll.length === 0) return lines;
|
|
57883
|
-
const
|
|
57884
|
-
|
|
57884
|
+
const created = (p) => Date.parse(p.create_time ?? "") || 0;
|
|
57885
|
+
const latest = instancesAll.reduce((a, b) => created(b) > created(a) ? b : a);
|
|
57885
57886
|
let process2;
|
|
57886
57887
|
try {
|
|
57887
57888
|
process2 = await withMec(() => getProcess(client, latest.id, { signal }));
|
|
@@ -57910,7 +57911,9 @@ async function runMecWorkflowArchive(cfg) {
|
|
|
57910
57911
|
await requireMec(cfg.client, { signal: cfg.signal });
|
|
57911
57912
|
let current = null;
|
|
57912
57913
|
try {
|
|
57913
|
-
current = await withMec(
|
|
57914
|
+
current = await withMec(
|
|
57915
|
+
() => getMecTemplate(cfg.client, cfg.id, cfg.signal, cfg.archive ? {} : { is_archive: true })
|
|
57916
|
+
);
|
|
57914
57917
|
} catch {
|
|
57915
57918
|
current = null;
|
|
57916
57919
|
}
|
|
@@ -57925,7 +57928,7 @@ async function runMecWorkflowArchive(cfg) {
|
|
|
57925
57928
|
return [
|
|
57926
57929
|
`id: ${cfg.id}`,
|
|
57927
57930
|
`target archived: ${cfg.archive ? "yes" : "no"}`,
|
|
57928
|
-
|
|
57931
|
+
`(template not visible via the ${cfg.archive ? "active" : "archived"}-template detail GET \u2014 likely already in the opposite state)`
|
|
57929
57932
|
];
|
|
57930
57933
|
}
|
|
57931
57934
|
return [
|
|
@@ -57961,9 +57964,7 @@ async function runMecWorkflowClone(cfg) {
|
|
|
57961
57964
|
`cloning MEC workflow template ${cfg.templateId} (carries existing members forward)`
|
|
57962
57965
|
);
|
|
57963
57966
|
await requireMec(cfg.client, { signal: cfg.signal });
|
|
57964
|
-
const current = await withMec(
|
|
57965
|
-
() => getTemplate(cfg.client, cfg.templateId, { signal: cfg.signal })
|
|
57966
|
-
);
|
|
57967
|
+
const current = await withMec(() => getMecTemplate(cfg.client, cfg.templateId, cfg.signal));
|
|
57967
57968
|
const dateConfig = resolveDateTagConfig(current);
|
|
57968
57969
|
const source = resolveCopyFrom(current, cfg.copyFrom, dateConfig.id);
|
|
57969
57970
|
const extraTags = resolveExtraTags(current, parseExtraTagFlags(cfg.tagFlags), dateConfig.id);
|
|
@@ -76572,6 +76573,9 @@ async function aiServicePost(client, path13, body, attribute, options) {
|
|
|
76572
76573
|
const fresh = await tokenFor(client, signal, true);
|
|
76573
76574
|
res = await sendOnce(url, fresh.token, payload, extra, signal);
|
|
76574
76575
|
}
|
|
76576
|
+
return parseResponse(rel, res);
|
|
76577
|
+
}
|
|
76578
|
+
async function parseResponse(rel, res) {
|
|
76575
76579
|
const text2 = await res.text();
|
|
76576
76580
|
if (!res.ok) {
|
|
76577
76581
|
const envelope = parseErrorEnvelope(text2);
|
|
@@ -76678,6 +76682,26 @@ function listModels(client, options) {
|
|
|
76678
76682
|
function getSystemEntities(client, options) {
|
|
76679
76683
|
return read(client, "v1/ManagedAgents/getSystemEntities", {}, options);
|
|
76680
76684
|
}
|
|
76685
|
+
async function writeSchedule(client, path13, body, options) {
|
|
76686
|
+
const res = await write(client, path13, body, options);
|
|
76687
|
+
const schedule = res !== null && typeof res === "object" ? res.schedule : void 0;
|
|
76688
|
+
if (schedule === null || typeof schedule !== "object" || Array.isArray(schedule)) {
|
|
76689
|
+
throw new Error(`POST /ai-service/external/${path13}: response has no schedule object`);
|
|
76690
|
+
}
|
|
76691
|
+
return res;
|
|
76692
|
+
}
|
|
76693
|
+
function listSchedules(client, body, options) {
|
|
76694
|
+
return read(client, "v1/ManagedAgentSchedules/listSchedules", body, options);
|
|
76695
|
+
}
|
|
76696
|
+
function createSchedule(client, body, options) {
|
|
76697
|
+
return writeSchedule(client, "v1/ManagedAgentSchedules/createSchedule", body, options);
|
|
76698
|
+
}
|
|
76699
|
+
function updateSchedule(client, body, options) {
|
|
76700
|
+
return writeSchedule(client, "v1/ManagedAgentSchedules/updateSchedule", body, options);
|
|
76701
|
+
}
|
|
76702
|
+
function deleteSchedule(client, body, options) {
|
|
76703
|
+
return write(client, "v1/ManagedAgentSchedules/deleteSchedule", body, options);
|
|
76704
|
+
}
|
|
76681
76705
|
|
|
76682
76706
|
// src/commands/_agentCliScopes.ts
|
|
76683
76707
|
var DEFAULT_CLI_SCOPES = ["*:read"];
|
|
@@ -77689,6 +77713,218 @@ function registerAgentPinCommands(agents) {
|
|
|
77689
77713
|
withPinTargets(unpin);
|
|
77690
77714
|
}
|
|
77691
77715
|
|
|
77716
|
+
// src/commands/agents_schedules.ts
|
|
77717
|
+
var SCHEDULE_ID = "<scheduleId>";
|
|
77718
|
+
function requirePrompt(prompt) {
|
|
77719
|
+
if (prompt.trim() === "") {
|
|
77720
|
+
throw new Error("--prompt must not be empty (omit it, or use update --clear-prompt)");
|
|
77721
|
+
}
|
|
77722
|
+
return prompt;
|
|
77723
|
+
}
|
|
77724
|
+
function tokenAgentId(client) {
|
|
77725
|
+
try {
|
|
77726
|
+
return firstString(decodeJwtClaims(client.session.jwtAccess ?? ""), "agent_id");
|
|
77727
|
+
} catch {
|
|
77728
|
+
return "";
|
|
77729
|
+
}
|
|
77730
|
+
}
|
|
77731
|
+
function agentIdFor(flag, client) {
|
|
77732
|
+
const id = (flag ?? "").trim();
|
|
77733
|
+
return id !== "" ? id : tokenAgentId(client);
|
|
77734
|
+
}
|
|
77735
|
+
function scheduleLine(s) {
|
|
77736
|
+
const state = s.enabled === void 0 ? "?" : s.enabled ? "enabled" : "disabled";
|
|
77737
|
+
return [
|
|
77738
|
+
s.id ?? "?",
|
|
77739
|
+
state,
|
|
77740
|
+
`cron "${s.crontab ?? "?"}" ${s.timezone ?? "UTC"}`,
|
|
77741
|
+
`agent ${s.agentId ?? "?"}`,
|
|
77742
|
+
`last ${s.lastRunStatus ?? "-"}`
|
|
77743
|
+
].join(" ");
|
|
77744
|
+
}
|
|
77745
|
+
function writeResult(cfg, verb, res) {
|
|
77746
|
+
if (cfg.asJson) {
|
|
77747
|
+
writeJSONIndented(cfg.out, res);
|
|
77748
|
+
return;
|
|
77749
|
+
}
|
|
77750
|
+
cfg.out.write(`${verb} ${scheduleLine(res.schedule)}
|
|
77751
|
+
`);
|
|
77752
|
+
}
|
|
77753
|
+
async function runSchedulesList(cfg) {
|
|
77754
|
+
const agentId = agentIdFor(cfg.agentId, cfg.client);
|
|
77755
|
+
const res = await listSchedules(cfg.client, agentId !== "" ? { agentId } : {}, {
|
|
77756
|
+
signal: cfg.signal
|
|
77757
|
+
});
|
|
77758
|
+
if (cfg.asJson) {
|
|
77759
|
+
writeJSONIndented(cfg.out, res);
|
|
77760
|
+
return;
|
|
77761
|
+
}
|
|
77762
|
+
const list29 = res.schedules ?? [];
|
|
77763
|
+
if (list29.length === 0) {
|
|
77764
|
+
cfg.out.write("(no schedules)\n");
|
|
77765
|
+
return;
|
|
77766
|
+
}
|
|
77767
|
+
for (const s of list29) cfg.out.write(`${scheduleLine(s)}
|
|
77768
|
+
`);
|
|
77769
|
+
}
|
|
77770
|
+
async function runSchedulesCreate(cfg) {
|
|
77771
|
+
const agentId = agentIdFor(cfg.agentId, cfg.client);
|
|
77772
|
+
if (agentId === "") {
|
|
77773
|
+
throw new Error(
|
|
77774
|
+
"missing required option: --agent-id <agentId> (the session token names no agent)"
|
|
77775
|
+
);
|
|
77776
|
+
}
|
|
77777
|
+
if (cfg.cron === void 0) throw new Error("missing required option: --cron <expr>");
|
|
77778
|
+
const body = { agentId, crontab: parseCron(cfg.cron) };
|
|
77779
|
+
if (cfg.tz !== void 0) body.timezone = cfg.tz;
|
|
77780
|
+
if (cfg.prompt !== void 0) body.prompt = requirePrompt(cfg.prompt);
|
|
77781
|
+
if (cfg.environmentId !== void 0) body.environmentId = cfg.environmentId;
|
|
77782
|
+
if (cfg.enabled !== void 0) body.enabled = requireBool(cfg.enabled, "--enabled");
|
|
77783
|
+
writeResult(cfg, "Created", await createSchedule(cfg.client, body, { signal: cfg.signal }));
|
|
77784
|
+
}
|
|
77785
|
+
async function runSchedulesUpdate(cfg) {
|
|
77786
|
+
const id = requireId(cfg.id, SCHEDULE_ID);
|
|
77787
|
+
if (cfg.prompt !== void 0 && cfg.clearPrompt === true) {
|
|
77788
|
+
throw new Error("give --prompt or --clear-prompt, not both");
|
|
77789
|
+
}
|
|
77790
|
+
const body = { id };
|
|
77791
|
+
if (cfg.cron !== void 0) body.crontab = parseCron(cfg.cron);
|
|
77792
|
+
if (cfg.tz !== void 0) body.timezone = cfg.tz;
|
|
77793
|
+
if (cfg.prompt !== void 0) body.prompt = requirePrompt(cfg.prompt);
|
|
77794
|
+
if (cfg.clearPrompt === true) body.prompt = null;
|
|
77795
|
+
if (cfg.environmentId !== void 0) body.environmentId = cfg.environmentId;
|
|
77796
|
+
if (cfg.enabled !== void 0) body.enabled = requireBool(cfg.enabled, "--enabled");
|
|
77797
|
+
if (Object.keys(body).length === 1) throw new Error("nothing to change: give at least one flag");
|
|
77798
|
+
writeResult(cfg, "Updated", await updateSchedule(cfg.client, body, { signal: cfg.signal }));
|
|
77799
|
+
}
|
|
77800
|
+
async function runSchedulesDelete(cfg) {
|
|
77801
|
+
const id = requireId(cfg.id, SCHEDULE_ID);
|
|
77802
|
+
const serverKey = cfg.client.serverKey;
|
|
77803
|
+
const action = {
|
|
77804
|
+
resource: "managed-agent-schedule",
|
|
77805
|
+
id: `${serverKey}:${id}`,
|
|
77806
|
+
verb: "delete"
|
|
77807
|
+
};
|
|
77808
|
+
await preflightConfirmToken(action, cfg.token);
|
|
77809
|
+
await twoStepConfirm({
|
|
77810
|
+
out: proseStream(cfg),
|
|
77811
|
+
action,
|
|
77812
|
+
token: cfg.token,
|
|
77813
|
+
server: serverKey,
|
|
77814
|
+
confirmCmd: `dr agents schedules delete --id ${shellArg(id)} --server ${shellArg(serverKey)}`,
|
|
77815
|
+
describe: async () => {
|
|
77816
|
+
const agentId = tokenAgentId(cfg.client);
|
|
77817
|
+
const res = await listSchedules(cfg.client, agentId !== "" ? { agentId } : {}, {
|
|
77818
|
+
signal: cfg.signal
|
|
77819
|
+
});
|
|
77820
|
+
const s = (res.schedules ?? []).find((row) => row.id === id);
|
|
77821
|
+
if (s === void 0) {
|
|
77822
|
+
throw new Error(`no schedule ${id} in this org (see: dr agents schedules list)`);
|
|
77823
|
+
}
|
|
77824
|
+
return [
|
|
77825
|
+
scheduleLine(s),
|
|
77826
|
+
`prompt: ${JSON.stringify(s.prompt ?? null)}`,
|
|
77827
|
+
`environment: ${s.environmentId ?? "(resolved per run)"}`,
|
|
77828
|
+
// `create` cannot set this: a restored schedule runs as whoever re-creates it.
|
|
77829
|
+
`runs as: user ${s.runAsUserId ?? "?"}`
|
|
77830
|
+
];
|
|
77831
|
+
},
|
|
77832
|
+
execute: async () => {
|
|
77833
|
+
const res = await deleteSchedule(cfg.client, { id }, { signal: cfg.signal });
|
|
77834
|
+
proseStream(cfg).write(`Deleted schedule ${id}.
|
|
77835
|
+
`);
|
|
77836
|
+
if (cfg.asJson) writeJSONIndented(cfg.out, res);
|
|
77837
|
+
}
|
|
77838
|
+
});
|
|
77839
|
+
}
|
|
77840
|
+
var AGENT_ID_HELP = "Agent id (default: the session token's agent_id claim, which a managed agent's token carries).";
|
|
77841
|
+
function registerAgentSchedulesCommands(agents) {
|
|
77842
|
+
const schedules = agents.command("schedules").description(
|
|
77843
|
+
"Cron schedules that open a conversation with a managed agent, as the session user."
|
|
77844
|
+
);
|
|
77845
|
+
const list29 = schedules.command("list").description("List the org's schedules.").option(
|
|
77846
|
+
"--agent-id <agentId>",
|
|
77847
|
+
"Only this agent's (default: the session token's agent_id claim; without one, every agent's)."
|
|
77848
|
+
).option("--json", JSON_HELP).action(async (opts) => {
|
|
77849
|
+
const setup = await setupCall(opts.server, opts.account);
|
|
77850
|
+
try {
|
|
77851
|
+
await runSchedulesList({
|
|
77852
|
+
client: setup.client,
|
|
77853
|
+
signal: setup.signal,
|
|
77854
|
+
...std(),
|
|
77855
|
+
agentId: opts.agentId,
|
|
77856
|
+
asJson: opts.json === true
|
|
77857
|
+
});
|
|
77858
|
+
} finally {
|
|
77859
|
+
setup.cleanup();
|
|
77860
|
+
}
|
|
77861
|
+
});
|
|
77862
|
+
withTarget(list29);
|
|
77863
|
+
const create20 = schedules.command("create").description("Schedule an agent; its runs act as you.").option("--agent-id <agentId>", AGENT_ID_HELP).option(
|
|
77864
|
+
"--cron <expr>",
|
|
77865
|
+
'Five-field cron line, runs at least 5 minutes apart, e.g. "0 8 * * 1".'
|
|
77866
|
+
).option("--tz <iana>", "Timezone the cron line is read in (default UTC).").option("--prompt <text>", "What each run is asked (default: a bare trigger turn).").option(
|
|
77867
|
+
"--environment-id <id>",
|
|
77868
|
+
"Anthropic environment for the runs (default: resolved per run)."
|
|
77869
|
+
).option("--enabled <true|false>", "Create it enabled (default true).").option("--json", JSON_HELP).action(async (opts) => {
|
|
77870
|
+
const setup = await setupCall(opts.server, opts.account);
|
|
77871
|
+
try {
|
|
77872
|
+
await runSchedulesCreate({
|
|
77873
|
+
client: setup.client,
|
|
77874
|
+
signal: setup.signal,
|
|
77875
|
+
...std(),
|
|
77876
|
+
agentId: opts.agentId,
|
|
77877
|
+
cron: opts.cron,
|
|
77878
|
+
tz: opts.tz,
|
|
77879
|
+
prompt: opts.prompt,
|
|
77880
|
+
environmentId: opts.environmentId,
|
|
77881
|
+
enabled: opts.enabled,
|
|
77882
|
+
asJson: opts.json === true
|
|
77883
|
+
});
|
|
77884
|
+
} finally {
|
|
77885
|
+
setup.cleanup();
|
|
77886
|
+
}
|
|
77887
|
+
});
|
|
77888
|
+
withTarget(create20);
|
|
77889
|
+
const update13 = schedules.command("update").description("Change a schedule (only the flags given change); its runs then act as you.").option("--id <scheduleId>", "Schedule id.").option("--cron <expr>", "New five-field cron line.").option("--tz <iana>", "New timezone.").option("--prompt <text>", "New prompt.").option("--clear-prompt", "Remove the prompt (runs get a bare trigger turn).").option("--environment-id <id>", "New Anthropic environment.").option("--enabled <true|false>", "Enable or disable it.").option("--json", JSON_HELP).action(async (opts) => {
|
|
77890
|
+
const setup = await setupCall(opts.server, opts.account);
|
|
77891
|
+
try {
|
|
77892
|
+
await runSchedulesUpdate({
|
|
77893
|
+
client: setup.client,
|
|
77894
|
+
signal: setup.signal,
|
|
77895
|
+
...std(),
|
|
77896
|
+
id: opts.id,
|
|
77897
|
+
cron: opts.cron,
|
|
77898
|
+
tz: opts.tz,
|
|
77899
|
+
prompt: opts.prompt,
|
|
77900
|
+
clearPrompt: opts.clearPrompt,
|
|
77901
|
+
environmentId: opts.environmentId,
|
|
77902
|
+
enabled: opts.enabled,
|
|
77903
|
+
asJson: opts.json === true
|
|
77904
|
+
});
|
|
77905
|
+
} finally {
|
|
77906
|
+
setup.cleanup();
|
|
77907
|
+
}
|
|
77908
|
+
});
|
|
77909
|
+
withTarget(update13);
|
|
77910
|
+
const del = schedules.command("delete").description("Delete a schedule. (two-step confirm)").option("--id <scheduleId>", "Schedule id.").option("--confirm-token <token>", CONFIRM_HELP).option("--json", JSON_HELP).action(async (opts) => {
|
|
77911
|
+
const setup = await setupCall(opts.server, opts.account);
|
|
77912
|
+
try {
|
|
77913
|
+
await runSchedulesDelete({
|
|
77914
|
+
client: setup.client,
|
|
77915
|
+
signal: setup.signal,
|
|
77916
|
+
...std(),
|
|
77917
|
+
id: opts.id,
|
|
77918
|
+
token: opts.confirmToken,
|
|
77919
|
+
asJson: opts.json === true
|
|
77920
|
+
});
|
|
77921
|
+
} finally {
|
|
77922
|
+
setup.cleanup();
|
|
77923
|
+
}
|
|
77924
|
+
});
|
|
77925
|
+
withTarget(del);
|
|
77926
|
+
}
|
|
77927
|
+
|
|
77692
77928
|
// src/commands/agents_skills.ts
|
|
77693
77929
|
import { mkdir as mkdir4, writeFile as writeFile7 } from "fs/promises";
|
|
77694
77930
|
import { dirname as dirname9, join as join17 } from "path";
|
|
@@ -79257,6 +79493,7 @@ function registerAgentsCommand(root) {
|
|
|
79257
79493
|
registerAgentPinCommands(agents);
|
|
79258
79494
|
registerAgentStudioCommands(agents);
|
|
79259
79495
|
registerAgentSkillsCommand(agents);
|
|
79496
|
+
registerAgentSchedulesCommands(agents);
|
|
79260
79497
|
}
|
|
79261
79498
|
|
|
79262
79499
|
// src/auth/versionCheck.ts
|
package/dist/scopes-map.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 1,
|
|
3
|
-
"cliVersion": "1.6.
|
|
3
|
+
"cliVersion": "1.6.188",
|
|
4
4
|
"_contract": "Resolve a command path through `aliases` (canonical prefix + alias segment -> canonical path) before any lookup. A path listed in `pendingCommands`, or whose first segment is a key of `pending`, is UNDECIDED, not unrestricted: fail closed or skip it, and never read a path's absence from `commands` as 'no requirement'. An entry carrying `denied` is UNAVAILABLE to any AGENT-SCOPED credential — one whose `scopes` claim carries at least one `resource:action` entry; a claim that is absent, empty, capability-only or wholly unparseable is UNRESTRICTED, and this mark does not apply to it — whatever else that entry says: it is not a ceiling and it is not always-available, its `denied.reason` says why and `denied.until` names the ticket that lifts it, and the absence of `requires` on it must NEVER be read as 'no requirement'. Only an entry in `commands` with an empty `requires` means always-available.",
|
|
5
5
|
"commands": {
|
|
6
6
|
"login": {
|
|
@@ -695,7 +695,7 @@
|
|
|
695
695
|
"requires": [
|
|
696
696
|
{
|
|
697
697
|
"resource": "tables",
|
|
698
|
-
"action": "
|
|
698
|
+
"action": "write"
|
|
699
699
|
}
|
|
700
700
|
]
|
|
701
701
|
},
|
|
@@ -851,7 +851,7 @@
|
|
|
851
851
|
"requires": [
|
|
852
852
|
{
|
|
853
853
|
"resource": "dashboards",
|
|
854
|
-
"action": "
|
|
854
|
+
"action": "write"
|
|
855
855
|
}
|
|
856
856
|
]
|
|
857
857
|
},
|
|
@@ -1067,7 +1067,7 @@
|
|
|
1067
1067
|
"requires": [
|
|
1068
1068
|
{
|
|
1069
1069
|
"resource": "tables",
|
|
1070
|
-
"action": "
|
|
1070
|
+
"action": "write"
|
|
1071
1071
|
}
|
|
1072
1072
|
]
|
|
1073
1073
|
},
|
|
@@ -1075,7 +1075,7 @@
|
|
|
1075
1075
|
"requires": [
|
|
1076
1076
|
{
|
|
1077
1077
|
"resource": "tables",
|
|
1078
|
-
"action": "
|
|
1078
|
+
"action": "write"
|
|
1079
1079
|
}
|
|
1080
1080
|
]
|
|
1081
1081
|
},
|
|
@@ -1083,7 +1083,7 @@
|
|
|
1083
1083
|
"requires": [
|
|
1084
1084
|
{
|
|
1085
1085
|
"resource": "tables",
|
|
1086
|
-
"action": "
|
|
1086
|
+
"action": "write"
|
|
1087
1087
|
}
|
|
1088
1088
|
]
|
|
1089
1089
|
},
|
|
@@ -1863,7 +1863,7 @@
|
|
|
1863
1863
|
"requires": [
|
|
1864
1864
|
{
|
|
1865
1865
|
"resource": "integrations",
|
|
1866
|
-
"action": "
|
|
1866
|
+
"action": "write"
|
|
1867
1867
|
}
|
|
1868
1868
|
]
|
|
1869
1869
|
},
|
|
@@ -5220,6 +5220,38 @@
|
|
|
5220
5220
|
"action": "destructive"
|
|
5221
5221
|
}
|
|
5222
5222
|
]
|
|
5223
|
+
},
|
|
5224
|
+
"agents schedules list": {
|
|
5225
|
+
"requires": [
|
|
5226
|
+
{
|
|
5227
|
+
"resource": "managed-agents",
|
|
5228
|
+
"action": "read"
|
|
5229
|
+
}
|
|
5230
|
+
]
|
|
5231
|
+
},
|
|
5232
|
+
"agents schedules create": {
|
|
5233
|
+
"requires": [
|
|
5234
|
+
{
|
|
5235
|
+
"resource": "managed-agents",
|
|
5236
|
+
"action": "write"
|
|
5237
|
+
}
|
|
5238
|
+
]
|
|
5239
|
+
},
|
|
5240
|
+
"agents schedules update": {
|
|
5241
|
+
"requires": [
|
|
5242
|
+
{
|
|
5243
|
+
"resource": "managed-agents",
|
|
5244
|
+
"action": "write"
|
|
5245
|
+
}
|
|
5246
|
+
]
|
|
5247
|
+
},
|
|
5248
|
+
"agents schedules delete": {
|
|
5249
|
+
"requires": [
|
|
5250
|
+
{
|
|
5251
|
+
"resource": "managed-agents",
|
|
5252
|
+
"action": "destructive"
|
|
5253
|
+
}
|
|
5254
|
+
]
|
|
5223
5255
|
}
|
|
5224
5256
|
},
|
|
5225
5257
|
"aliases": {
|
|
@@ -57,7 +57,9 @@ Reads never need confirmation. Gated **writes** fall into two tiers (full table:
|
|
|
57
57
|
every server, because the agent and skill registry is shared by every
|
|
58
58
|
environment (a write on DEV-1 changes production agents too).
|
|
59
59
|
|
|
60
|
-
**Tier A is the smaller set:** every `delete` (across all resources
|
|
60
|
+
**Tier A is the smaller set:** every `delete` (across all resources, except
|
|
61
|
+
`agents schedules delete`: one schedule row, which `create` restores, though
|
|
62
|
+
the restored row runs as whoever re-creates it), plus
|
|
61
63
|
`workflow`/`mec workflow` `archive` (and its `delete` alias), `process delete`,
|
|
62
64
|
`step delete`, `task delete`; `forecast scenarios bulk-edit`; `cash rules
|
|
63
65
|
delete-all`; `filebox archive` and `filebox data-query clear`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@datarails-ai/dr-cli",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.188",
|
|
4
4
|
"description": "Datarails CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"access": "public"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@datarails-ai/dr-appspace-cli": "0.12.
|
|
20
|
+
"@datarails-ai/dr-appspace-cli": "0.12.62",
|
|
21
21
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
22
22
|
"@napi-rs/keyring": "^1.3.0",
|
|
23
23
|
"commander": "^12.1.0",
|