@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 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
- `storyboards prepare`). A pin that is set but malformed refuses every command
337
- (`--help` and `--version` still print). A refusal exits 3, like a scope denial.
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.186",
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.61",
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-02T07:19:02.800Z";
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(() => getTemplate(cfg.client, cfg.id, { signal: cfg.signal }));
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 latest = instancesAll[instancesAll.length - 1];
57884
- if (latest === void 0) return lines;
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(() => getTemplate(cfg.client, cfg.id, { signal: cfg.signal }));
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
- "(template not visible via active-list GET \u2014 likely already in the opposite state)"
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 1,
3
- "cliVersion": "1.6.186",
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": "read"
698
+ "action": "write"
699
699
  }
700
700
  ]
701
701
  },
@@ -851,7 +851,7 @@
851
851
  "requires": [
852
852
  {
853
853
  "resource": "dashboards",
854
- "action": "read"
854
+ "action": "write"
855
855
  }
856
856
  ]
857
857
  },
@@ -1067,7 +1067,7 @@
1067
1067
  "requires": [
1068
1068
  {
1069
1069
  "resource": "tables",
1070
- "action": "read"
1070
+ "action": "write"
1071
1071
  }
1072
1072
  ]
1073
1073
  },
@@ -1075,7 +1075,7 @@
1075
1075
  "requires": [
1076
1076
  {
1077
1077
  "resource": "tables",
1078
- "action": "read"
1078
+ "action": "write"
1079
1079
  }
1080
1080
  ]
1081
1081
  },
@@ -1083,7 +1083,7 @@
1083
1083
  "requires": [
1084
1084
  {
1085
1085
  "resource": "tables",
1086
- "action": "read"
1086
+ "action": "write"
1087
1087
  }
1088
1088
  ]
1089
1089
  },
@@ -1863,7 +1863,7 @@
1863
1863
  "requires": [
1864
1864
  {
1865
1865
  "resource": "integrations",
1866
- "action": "read"
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), plus
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.186",
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.61",
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",