@robbeverhelst/do 1.151.0 → 1.152.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/dist/do.js +283 -2
- package/package.json +1 -1
package/dist/do.js
CHANGED
|
@@ -18050,6 +18050,60 @@ var linkGoogleInputSchema = exports_external.object({
|
|
|
18050
18050
|
state: exports_external.string().min(1)
|
|
18051
18051
|
});
|
|
18052
18052
|
|
|
18053
|
+
// ../../packages/schema/src/contracts/changes.ts
|
|
18054
|
+
var changeOpSchema = exports_external.enum(["created", "updated", "deleted"]);
|
|
18055
|
+
var CHANGE_ENTITY_SCOPES = {
|
|
18056
|
+
task: "tasks:read",
|
|
18057
|
+
project: "projects:read",
|
|
18058
|
+
area: "areas:read",
|
|
18059
|
+
routine: "routines:read",
|
|
18060
|
+
habit: "habits:read",
|
|
18061
|
+
occurrence: "occurrences:read",
|
|
18062
|
+
note: "notes:read",
|
|
18063
|
+
contact: "contacts:read",
|
|
18064
|
+
collection_item: "collections:read",
|
|
18065
|
+
inventory_item: "inventory:read",
|
|
18066
|
+
shopping_list: "shopping:read",
|
|
18067
|
+
recipe: "meals:read",
|
|
18068
|
+
meal_plan: "meals:read",
|
|
18069
|
+
event: "calendar:read",
|
|
18070
|
+
time_block: "calendar:read",
|
|
18071
|
+
place: "places:read"
|
|
18072
|
+
};
|
|
18073
|
+
var CHANGE_ENTITIES = Object.keys(CHANGE_ENTITY_SCOPES);
|
|
18074
|
+
var changeEntitySchema = exports_external.enum(CHANGE_ENTITIES);
|
|
18075
|
+
var changeSchema = exports_external.object({
|
|
18076
|
+
entity: changeEntitySchema,
|
|
18077
|
+
id: exports_external.string(),
|
|
18078
|
+
op: changeOpSchema,
|
|
18079
|
+
changedAt: exports_external.coerce.date()
|
|
18080
|
+
});
|
|
18081
|
+
var MAX_CHANGES_LIMIT = 500;
|
|
18082
|
+
var CHANGES_SINCE_NOW = "now";
|
|
18083
|
+
var CURSOR_RE = /^(\d+)-(\d+)$/;
|
|
18084
|
+
function parseChangeCursor(raw) {
|
|
18085
|
+
const m = CURSOR_RE.exec(raw);
|
|
18086
|
+
if (!m)
|
|
18087
|
+
return null;
|
|
18088
|
+
const txid = Number(m[1]);
|
|
18089
|
+
const seq = Number(m[2]);
|
|
18090
|
+
if (!Number.isSafeInteger(txid) || !Number.isSafeInteger(seq))
|
|
18091
|
+
return null;
|
|
18092
|
+
return { txid, seq };
|
|
18093
|
+
}
|
|
18094
|
+
var changesQuerySchema = exports_external.object({
|
|
18095
|
+
since: exports_external.string().refine((s) => s === CHANGES_SINCE_NOW || parseChangeCursor(s) !== null, {
|
|
18096
|
+
message: "since must be a cursor from a prior page's nextCursor, or 'now'"
|
|
18097
|
+
}).optional(),
|
|
18098
|
+
limit: exports_external.coerce.number().int().positive().transform((n) => Math.min(n, MAX_CHANGES_LIMIT)).optional(),
|
|
18099
|
+
entity: exports_external.string().transform((s) => s.split(",").map((e) => e.trim()).filter((e) => e.length > 0)).pipe(exports_external.array(changeEntitySchema).min(1)).optional()
|
|
18100
|
+
});
|
|
18101
|
+
var changesPageSchema = exports_external.object({
|
|
18102
|
+
data: exports_external.array(changeSchema),
|
|
18103
|
+
nextCursor: exports_external.string(),
|
|
18104
|
+
hasMore: exports_external.boolean()
|
|
18105
|
+
});
|
|
18106
|
+
|
|
18053
18107
|
// ../../packages/schema/src/contracts/value-sets.ts
|
|
18054
18108
|
var areaColorSchema = exports_external.enum(areaColor.enumValues);
|
|
18055
18109
|
var reviewCadenceSchema = exports_external.enum(reviewCadence.enumValues);
|
|
@@ -19532,6 +19586,110 @@ var timeBlockRangeQuerySchema = exports_external.object({
|
|
|
19532
19586
|
path: ["to"]
|
|
19533
19587
|
});
|
|
19534
19588
|
|
|
19589
|
+
// ../../packages/schema/src/contracts/agent-chat.ts
|
|
19590
|
+
var agentConnectionSourceSchema = exports_external.enum(["space", "env"]);
|
|
19591
|
+
var agentConnectionSchema = exports_external.object({
|
|
19592
|
+
connected: exports_external.boolean(),
|
|
19593
|
+
source: agentConnectionSourceSchema.nullable(),
|
|
19594
|
+
endpoint: exports_external.string().nullable(),
|
|
19595
|
+
model: exports_external.string().nullable(),
|
|
19596
|
+
hasKey: exports_external.boolean(),
|
|
19597
|
+
agentId: exports_external.string().nullable(),
|
|
19598
|
+
autoFile: exports_external.boolean(),
|
|
19599
|
+
updatedAt: exports_external.coerce.date().nullable()
|
|
19600
|
+
});
|
|
19601
|
+
var agentEndpointSchema = exports_external.string().trim().max(2000).url().refine((value) => /^https?:\/\//i.test(value), "endpoint must be an http(s) URL");
|
|
19602
|
+
var saveAgentConnectionInputSchema = exports_external.object({
|
|
19603
|
+
endpoint: agentEndpointSchema,
|
|
19604
|
+
apiKey: exports_external.string().trim().min(1).max(4000).nullable().optional(),
|
|
19605
|
+
model: exports_external.string().trim().min(1).max(200).nullable().optional(),
|
|
19606
|
+
agentId: exports_external.string().trim().min(1).max(64).nullable().optional(),
|
|
19607
|
+
autoFile: exports_external.boolean().optional()
|
|
19608
|
+
}).strict();
|
|
19609
|
+
var agentPageContextSchema = exports_external.object({
|
|
19610
|
+
route: exports_external.string().trim().min(1).max(500).startsWith("/"),
|
|
19611
|
+
nodeId: exports_external.string().trim().min(1).max(64).nullable()
|
|
19612
|
+
}).strict();
|
|
19613
|
+
var agentChatInputSchema = exports_external.object({
|
|
19614
|
+
message: exports_external.string().trim().min(1).max(8000),
|
|
19615
|
+
context: agentPageContextSchema
|
|
19616
|
+
}).strict();
|
|
19617
|
+
var agentChatEventSchema = exports_external.discriminatedUnion("type", [
|
|
19618
|
+
exports_external.object({ type: exports_external.literal("delta"), text: exports_external.string() }),
|
|
19619
|
+
exports_external.object({ type: exports_external.literal("done") }),
|
|
19620
|
+
exports_external.object({ type: exports_external.literal("error"), message: exports_external.string() })
|
|
19621
|
+
]);
|
|
19622
|
+
var agentChangeValueSchema = exports_external.union([
|
|
19623
|
+
exports_external.string(),
|
|
19624
|
+
exports_external.number(),
|
|
19625
|
+
exports_external.boolean(),
|
|
19626
|
+
exports_external.null(),
|
|
19627
|
+
exports_external.array(exports_external.string())
|
|
19628
|
+
]);
|
|
19629
|
+
var agentChangeFieldSchema = exports_external.object({
|
|
19630
|
+
field: exports_external.string(),
|
|
19631
|
+
before: agentChangeValueSchema,
|
|
19632
|
+
after: agentChangeValueSchema,
|
|
19633
|
+
beforeLabel: exports_external.string().nullable().optional(),
|
|
19634
|
+
afterLabel: exports_external.string().nullable().optional()
|
|
19635
|
+
});
|
|
19636
|
+
var agentChangeSchema = exports_external.object({
|
|
19637
|
+
entity: changeEntitySchema,
|
|
19638
|
+
id: exports_external.string(),
|
|
19639
|
+
op: changeOpSchema,
|
|
19640
|
+
changedAt: exports_external.coerce.date(),
|
|
19641
|
+
title: exports_external.string().nullable(),
|
|
19642
|
+
actor: actorRefSchema,
|
|
19643
|
+
fields: exports_external.array(agentChangeFieldSchema).optional()
|
|
19644
|
+
});
|
|
19645
|
+
var agentChangesPageSchema = exports_external.object({
|
|
19646
|
+
data: exports_external.array(agentChangeSchema),
|
|
19647
|
+
nextCursor: exports_external.string()
|
|
19648
|
+
});
|
|
19649
|
+
var agentChangesQuerySchema = exports_external.object({
|
|
19650
|
+
since: exports_external.string().refine((s) => s === "now" || /^\d+-\d+$/.test(s), {
|
|
19651
|
+
message: "since must be a cursor from a prior page's nextCursor, or 'now'"
|
|
19652
|
+
})
|
|
19653
|
+
});
|
|
19654
|
+
var agentConfirmationKindSchema = exports_external.enum(["delete", "cancel", "google", "orca", "bulk"]);
|
|
19655
|
+
var agentConfirmationStatusSchema = exports_external.enum([
|
|
19656
|
+
"pending",
|
|
19657
|
+
"confirmed",
|
|
19658
|
+
"done",
|
|
19659
|
+
"failed",
|
|
19660
|
+
"declined"
|
|
19661
|
+
]);
|
|
19662
|
+
var agentConfirmationSchema = exports_external.object({
|
|
19663
|
+
id: exports_external.string(),
|
|
19664
|
+
kind: agentConfirmationKindSchema,
|
|
19665
|
+
summary: exports_external.string(),
|
|
19666
|
+
items: exports_external.array(exports_external.object({ id: exports_external.string(), title: exports_external.string().nullable() })),
|
|
19667
|
+
method: exports_external.string(),
|
|
19668
|
+
path: exports_external.string(),
|
|
19669
|
+
status: agentConfirmationStatusSchema,
|
|
19670
|
+
agent: exports_external.object({ id: exports_external.string(), name: exports_external.string().nullable() }),
|
|
19671
|
+
createdAt: exports_external.coerce.date(),
|
|
19672
|
+
decidedAt: exports_external.coerce.date().nullable()
|
|
19673
|
+
});
|
|
19674
|
+
var agentUndoInputSchema = exports_external.object({
|
|
19675
|
+
id: exports_external.string().trim().min(1).max(64),
|
|
19676
|
+
since: exports_external.string().regex(/^\d+-\d+$/, "since must be a change-feed cursor")
|
|
19677
|
+
}).strict();
|
|
19678
|
+
var agentUndoResultSchema = exports_external.object({
|
|
19679
|
+
id: exports_external.string(),
|
|
19680
|
+
undone: exports_external.enum(["removed", "restored"])
|
|
19681
|
+
});
|
|
19682
|
+
var agentRedoResultSchema = exports_external.object({
|
|
19683
|
+
id: exports_external.string(),
|
|
19684
|
+
redone: exports_external.literal(true)
|
|
19685
|
+
});
|
|
19686
|
+
var agentFilingSchema = exports_external.object({
|
|
19687
|
+
confident: exports_external.boolean().default(false),
|
|
19688
|
+
areaId: exports_external.string().nullable().optional(),
|
|
19689
|
+
owner: exports_external.string().nullable().optional(),
|
|
19690
|
+
date: exports_external.string().regex(/^\d{4}-\d{2}-\d{2}$/).nullable().optional()
|
|
19691
|
+
});
|
|
19692
|
+
|
|
19535
19693
|
// ../../packages/schema/src/contracts/roles.ts
|
|
19536
19694
|
var permissionSetSchema = createSelectSchema(permissionSets, {
|
|
19537
19695
|
createdAt: exports_external.coerce.date(),
|
|
@@ -20631,7 +20789,7 @@ function parseCapture2(input, now) {
|
|
|
20631
20789
|
|
|
20632
20790
|
// src/meta.ts
|
|
20633
20791
|
var CLI_NAME = "do";
|
|
20634
|
-
var VERSION = "1.
|
|
20792
|
+
var VERSION = "1.152.0";
|
|
20635
20793
|
var API_PREFIX = "/api/v1";
|
|
20636
20794
|
var DEFAULT_API_URL = "http://localhost:3001";
|
|
20637
20795
|
|
|
@@ -21530,6 +21688,68 @@ var COMMAND_SPECS = [
|
|
|
21530
21688
|
returns: "None",
|
|
21531
21689
|
notes: "Gated behind --allow-destructive + an orca:write key. Idempotent."
|
|
21532
21690
|
},
|
|
21691
|
+
{
|
|
21692
|
+
path: ["agents", "list"],
|
|
21693
|
+
summary: "List the Space's Agents (id + name).",
|
|
21694
|
+
args: [],
|
|
21695
|
+
flags: [],
|
|
21696
|
+
scopes: ["agents:read"],
|
|
21697
|
+
returns: "AgentSummary",
|
|
21698
|
+
notes: "Creating an Agent and minting its keys stays a member's job in the app."
|
|
21699
|
+
},
|
|
21700
|
+
{
|
|
21701
|
+
path: ["agent", "connection", "get"],
|
|
21702
|
+
summary: "Show the agent runtime the Echo panel's chat goes to (never its key).",
|
|
21703
|
+
args: [],
|
|
21704
|
+
flags: [],
|
|
21705
|
+
scopes: ["agents:read"],
|
|
21706
|
+
returns: "AgentConnection",
|
|
21707
|
+
notes: "hasKey says whether a key is set; the key itself is write-only."
|
|
21708
|
+
},
|
|
21709
|
+
{
|
|
21710
|
+
path: ["agent", "connection", "set"],
|
|
21711
|
+
summary: "Point the Echo panel at an agent runtime (replaces the connection).",
|
|
21712
|
+
args: [],
|
|
21713
|
+
flags: [
|
|
21714
|
+
{ name: "endpoint", type: "string", description: "The runtime's base URL (required)." },
|
|
21715
|
+
{
|
|
21716
|
+
name: "model",
|
|
21717
|
+
type: "string",
|
|
21718
|
+
description: "The model to ask for, if the runtime needs one."
|
|
21719
|
+
},
|
|
21720
|
+
{
|
|
21721
|
+
name: "agent",
|
|
21722
|
+
type: "string",
|
|
21723
|
+
description: "The Agent the runtime acts as: its id or name (see `agents list`)."
|
|
21724
|
+
},
|
|
21725
|
+
{
|
|
21726
|
+
name: "auto-file",
|
|
21727
|
+
type: "boolean",
|
|
21728
|
+
description: "Let Echo file new captures (needs --agent)."
|
|
21729
|
+
},
|
|
21730
|
+
{ name: "no-auto-file", type: "boolean", description: "Stop Echo filing new captures." },
|
|
21731
|
+
{
|
|
21732
|
+
name: "key-stdin",
|
|
21733
|
+
type: "boolean",
|
|
21734
|
+
description: "Read the runtime's API key from stdin's first line instead of DO_AGENT_API_KEY."
|
|
21735
|
+
},
|
|
21736
|
+
{ name: "clear-key", type: "boolean", description: "Remove the stored key." }
|
|
21737
|
+
],
|
|
21738
|
+
scopes: ["agents:write"],
|
|
21739
|
+
returns: "AgentConnection",
|
|
21740
|
+
notes: "The runtime's key is read from DO_AGENT_API_KEY or, with --key-stdin, from stdin \u2014 never a flag. With neither, the stored key is kept. --model and --agent are replaced as sent (left out clears them). Owner/admin only (canManageSpace)."
|
|
21741
|
+
},
|
|
21742
|
+
{
|
|
21743
|
+
path: ["agent", "connection", "remove"],
|
|
21744
|
+
summary: "Forget the Space's agent connection (destructive).",
|
|
21745
|
+
args: [],
|
|
21746
|
+
flags: [
|
|
21747
|
+
{ name: "allow-destructive", type: "boolean", description: "Required to actually remove." }
|
|
21748
|
+
],
|
|
21749
|
+
scopes: ["agents:write"],
|
|
21750
|
+
returns: "None",
|
|
21751
|
+
notes: "Owner/admin only. An Agent's key gets a 428 confirmation_required until the member confirms in the Echo panel."
|
|
21752
|
+
},
|
|
21533
21753
|
{
|
|
21534
21754
|
path: ["settings", "get"],
|
|
21535
21755
|
summary: "Show the caller's settings for the Space.",
|
|
@@ -22051,7 +22271,7 @@ var COMMAND_SPECS = [
|
|
|
22051
22271
|
}
|
|
22052
22272
|
];
|
|
22053
22273
|
function matchCommandSpec(positionals) {
|
|
22054
|
-
for (const len of [2, 1]) {
|
|
22274
|
+
for (const len of [3, 2, 1]) {
|
|
22055
22275
|
const candidate = positionals.slice(0, len);
|
|
22056
22276
|
if (candidate.length < len)
|
|
22057
22277
|
continue;
|
|
@@ -23217,6 +23437,35 @@ var HANDLERS = {
|
|
|
23217
23437
|
const input = parseInput(logMetricInputSchema, { value, ...at ? { occurredAt: at } : {} });
|
|
23218
23438
|
return { data: await requireClient().post(`/metrics/${key}`, input), render: renderRecord };
|
|
23219
23439
|
},
|
|
23440
|
+
"agents list": async ({ requireClient }) => ({
|
|
23441
|
+
data: await requireClient().getPage("/agents"),
|
|
23442
|
+
render: renderList
|
|
23443
|
+
}),
|
|
23444
|
+
"agent connection get": async ({ requireClient }) => ({
|
|
23445
|
+
data: await requireClient().get("/agent/connection"),
|
|
23446
|
+
render: renderRecord
|
|
23447
|
+
}),
|
|
23448
|
+
"agent connection set": async ({ io, flags, requireClient }) => {
|
|
23449
|
+
const endpoint = flagString(flags, "endpoint");
|
|
23450
|
+
if (endpoint === undefined)
|
|
23451
|
+
throw usageError("agent connection set needs --endpoint <url>");
|
|
23452
|
+
const client = requireClient();
|
|
23453
|
+
const agent = flagString(flags, "agent");
|
|
23454
|
+
const autoFile = flagBool(flags, "auto-file") ? true : flagBool(flags, "no-auto-file") ? false : undefined;
|
|
23455
|
+
const body = parseInput(saveAgentConnectionInputSchema, {
|
|
23456
|
+
endpoint,
|
|
23457
|
+
model: flagString(flags, "model"),
|
|
23458
|
+
agentId: agent === undefined ? undefined : await resolveAgentId(client, agent),
|
|
23459
|
+
autoFile,
|
|
23460
|
+
apiKey: await readAgentKey(io, flags)
|
|
23461
|
+
});
|
|
23462
|
+
return { data: await client.put("/agent/connection", body), render: renderRecord };
|
|
23463
|
+
},
|
|
23464
|
+
"agent connection remove": async ({ flags, requireClient }) => {
|
|
23465
|
+
assertDestructiveAllowed(flags, "remove the agent connection");
|
|
23466
|
+
await requireClient().delete("/agent/connection");
|
|
23467
|
+
return { data: { ok: true, removed: "agent connection" }, render: renderRecord };
|
|
23468
|
+
},
|
|
23220
23469
|
"settings get": async ({ requireClient }) => ({
|
|
23221
23470
|
data: await requireClient().get("/settings"),
|
|
23222
23471
|
render: renderRecord
|
|
@@ -23635,6 +23884,38 @@ function redact(secret) {
|
|
|
23635
23884
|
return "********";
|
|
23636
23885
|
return `${secret.slice(0, 6)}\u2026${secret.slice(-2)}`;
|
|
23637
23886
|
}
|
|
23887
|
+
var AGENT_KEY_ENV = "DO_AGENT_API_KEY";
|
|
23888
|
+
async function readAgentKey(io, flags) {
|
|
23889
|
+
if (flagBool(flags, "clear-key"))
|
|
23890
|
+
return null;
|
|
23891
|
+
if (flagBool(flags, "key-stdin")) {
|
|
23892
|
+
let first;
|
|
23893
|
+
if (io.stdin) {
|
|
23894
|
+
for await (const line2 of io.stdin) {
|
|
23895
|
+
first = line2;
|
|
23896
|
+
break;
|
|
23897
|
+
}
|
|
23898
|
+
}
|
|
23899
|
+
const key = first?.trim();
|
|
23900
|
+
if (!key)
|
|
23901
|
+
throw usageError("--key-stdin read no key: pipe the key in on stdin");
|
|
23902
|
+
return key;
|
|
23903
|
+
}
|
|
23904
|
+
const fromEnv = io.env[AGENT_KEY_ENV]?.trim();
|
|
23905
|
+
return fromEnv ? fromEnv : undefined;
|
|
23906
|
+
}
|
|
23907
|
+
var ULID = /^[0-9A-HJKMNP-TV-Z]{26}$/i;
|
|
23908
|
+
async function resolveAgentId(client, agent) {
|
|
23909
|
+
if (ULID.test(agent))
|
|
23910
|
+
return agent;
|
|
23911
|
+
const { data } = await client.getPage("/agents");
|
|
23912
|
+
const wanted = agent.trim().toLowerCase();
|
|
23913
|
+
const match = data.find((a) => a.name.toLowerCase() === wanted);
|
|
23914
|
+
if (!match) {
|
|
23915
|
+
throw new CliError("not_found", `no Agent named ${agent} \u2014 see \`do agents list\``, EXIT.NOT_FOUND);
|
|
23916
|
+
}
|
|
23917
|
+
return match.id;
|
|
23918
|
+
}
|
|
23638
23919
|
function requireWrite(entity, op) {
|
|
23639
23920
|
if (!entity.write) {
|
|
23640
23921
|
throw usageError(`\`${entity.name}\` is read-only \u2014 \`${op}\` is not available`);
|