@trydreamstate/cli 1.3.4 → 1.3.5
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/agent-plugin/.claude-plugin/plugin.json +1 -1
- package/agent-plugin/.codex-plugin/plugin.json +1 -1
- package/agent-plugin/skills/crm/SKILL.md +1 -1
- package/agent-plugin/skills/diagnostics/SKILL.md +1 -1
- package/agent-plugin/skills/dreamstate/SKILL.md +1 -1
- package/agent-plugin/skills/first-win/SKILL.md +1 -1
- package/agent-plugin/skills/inbox-replies/SKILL.md +1 -1
- package/agent-plugin/skills/knowledge/SKILL.md +1 -1
- package/agent-plugin/skills/linkedin-posts/SKILL.md +1 -1
- package/agent-plugin/skills/linkedin-warm-signals/SKILL.md +2 -2
- package/agent-plugin/skills/list-building/SKILL.md +2 -2
- package/agent-plugin/skills/list-building/column-authoring.md +2 -1
- package/agent-plugin/skills/outreach/SKILL.md +2 -2
- package/agent-plugin/skills/plays/SKILL.md +1 -1
- package/agent-plugin/skills/reddit-posts/SKILL.md +1 -1
- package/agent-plugin/skills/skill-authoring/SKILL.md +1 -1
- package/agent-plugin/skills/social/SKILL.md +1 -1
- package/agent-plugin/skills/visibility/SKILL.md +1 -1
- package/agent-plugin/skills/workflows/SKILL.md +1 -1
- package/agent-plugin/skills/worksheet-tidy/SKILL.md +1 -1
- package/agent-plugin/skills/writing/SKILL.md +1 -1
- package/agent-plugin/skills/x-posts/SKILL.md +1 -1
- package/dist/client.d.ts +4 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +41 -3
- package/dist/commands/shared.d.ts.map +1 -1
- package/dist/commands/shared.js +2 -1
- package/dist/config.d.ts +5 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +12 -2
- package/dist/gatedRun.d.ts +2 -0
- package/dist/gatedRun.d.ts.map +1 -1
- package/dist/gatedRun.js +130 -9
- package/dist/generated/packVerbs.generated.json +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +115 -31
- package/dist/money.d.ts +10 -0
- package/dist/money.d.ts.map +1 -0
- package/dist/money.js +75 -0
- package/dist/runWait.d.ts.map +1 -1
- package/dist/runWait.js +2 -0
- package/dist/turnCache.d.ts +3 -1
- package/dist/turnCache.d.ts.map +1 -1
- package/dist/turnCache.js +6 -2
- package/package.json +1 -1
package/dist/gatedRun.js
CHANGED
|
@@ -7,6 +7,7 @@ exports.parameterIdempotencyKey = parameterIdempotencyKey;
|
|
|
7
7
|
exports.cliSurfaceRefusal = cliSurfaceRefusal;
|
|
8
8
|
exports.planFingerprint = planFingerprint;
|
|
9
9
|
exports.runGated = runGated;
|
|
10
|
+
exports.refusalFromRunResult = refusalFromRunResult;
|
|
10
11
|
exports.readCapability = readCapability;
|
|
11
12
|
const node_crypto_1 = require("node:crypto");
|
|
12
13
|
const client_1 = require("./client");
|
|
@@ -147,11 +148,103 @@ function quoteFromResult(value, depth = 0) {
|
|
|
147
148
|
}
|
|
148
149
|
return null;
|
|
149
150
|
}
|
|
150
|
-
function
|
|
151
|
+
function quotePriced(capabilityId, body, quote) {
|
|
151
152
|
const params = body.params && typeof body.params === 'object' ? body.params : {};
|
|
152
153
|
const rows = typeof params.max_rows === 'number' ? `${params.max_rows} rows` : 'rows not stated';
|
|
153
154
|
const credits = quote.maximum_credits === null ? 'credits not stated' : `up to ${quote.maximum_credits} credits`;
|
|
154
|
-
return `Dry run of ${capabilityId} priced: ${rows}, ${credits}
|
|
155
|
+
return `Dry run of ${capabilityId} priced: ${rows}, ${credits}.`;
|
|
156
|
+
}
|
|
157
|
+
/** A known price of 0 spends nothing. An unknown price or a positive price is sent only after the caller passes the approval flag. */
|
|
158
|
+
function spendNeedsApproval(maximum, approved) {
|
|
159
|
+
if (approved)
|
|
160
|
+
return false;
|
|
161
|
+
if (maximum === 0)
|
|
162
|
+
return false;
|
|
163
|
+
return true;
|
|
164
|
+
}
|
|
165
|
+
const CREDENTIALS_REQUIRED_SENTENCE = 'A connected credential is required before this run can continue.';
|
|
166
|
+
function readinessRecord(value) {
|
|
167
|
+
return value && typeof value === 'object' && !Array.isArray(value) ? value : null;
|
|
168
|
+
}
|
|
169
|
+
function blockerSentence(blocker) {
|
|
170
|
+
if (typeof blocker === 'string' && blocker.trim())
|
|
171
|
+
return blocker.trim();
|
|
172
|
+
const record = readinessRecord(blocker);
|
|
173
|
+
const message = record?.message;
|
|
174
|
+
return typeof message === 'string' && message.trim() ? message.trim() : null;
|
|
175
|
+
}
|
|
176
|
+
function blockerCodeOf(blocker) {
|
|
177
|
+
const record = readinessRecord(blocker);
|
|
178
|
+
const code = record?.code;
|
|
179
|
+
return typeof code === 'string' && /^[a-z][a-z0-9_]*$/.test(code) ? code : null;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* HTTP 200 can still be a refusal: smoke and dry_run succeed without spending
|
|
183
|
+
* and attach run_blockers or readiness.blockers. Only those top-level buckets
|
|
184
|
+
* count. A row skip_reason is not a refusal of the command.
|
|
185
|
+
*/
|
|
186
|
+
function readinessRefusal(value) {
|
|
187
|
+
const root = readinessRecord(value);
|
|
188
|
+
const data = readinessRecord(root?.data) ?? root;
|
|
189
|
+
if (!data)
|
|
190
|
+
return null;
|
|
191
|
+
const run = readinessRecord(data.run);
|
|
192
|
+
const outputs = readinessRecord(run?.outputs);
|
|
193
|
+
const buckets = [];
|
|
194
|
+
const states = [];
|
|
195
|
+
const take = (readiness) => {
|
|
196
|
+
if (!readiness)
|
|
197
|
+
return;
|
|
198
|
+
if (Array.isArray(readiness.blockers))
|
|
199
|
+
buckets.push(...readiness.blockers);
|
|
200
|
+
if (typeof readiness.state === 'string')
|
|
201
|
+
states.push(readiness.state);
|
|
202
|
+
};
|
|
203
|
+
// Dry runs put readiness on run.outputs. Durable and polled runs put the
|
|
204
|
+
// same object on run.steps[].outputs. A blocked rehearsal is an array of
|
|
205
|
+
// { status:'blocked', blocked_by, next_action }, not { blockers, state }.
|
|
206
|
+
const absorbSurface = (surface) => {
|
|
207
|
+
if (!surface)
|
|
208
|
+
return;
|
|
209
|
+
if (Array.isArray(surface.run_blockers))
|
|
210
|
+
buckets.push(...surface.run_blockers);
|
|
211
|
+
absorbReadiness(surface.readiness);
|
|
212
|
+
};
|
|
213
|
+
const absorbReadiness = (readiness) => {
|
|
214
|
+
if (Array.isArray(readiness)) {
|
|
215
|
+
for (const entry of readiness) {
|
|
216
|
+
const row = readinessRecord(entry);
|
|
217
|
+
if (!row || row.status !== 'blocked')
|
|
218
|
+
continue;
|
|
219
|
+
const blockedBy = Array.isArray(row.blocked_by)
|
|
220
|
+
? row.blocked_by.filter((item) => typeof item === 'string' && /^[a-z][a-z0-9_]*$/.test(item))
|
|
221
|
+
: [];
|
|
222
|
+
const nextAction = typeof row.next_action === 'string' && row.next_action.trim() ? row.next_action.trim() : null;
|
|
223
|
+
const message = typeof row.message === 'string' && row.message.trim() ? row.message.trim() : null;
|
|
224
|
+
buckets.push({
|
|
225
|
+
...(blockedBy[0] ? { code: blockedBy[0] } : {}),
|
|
226
|
+
message: nextAction ?? message ?? 'This run is blocked until the workspace is ready.',
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
take(readinessRecord(readiness));
|
|
232
|
+
};
|
|
233
|
+
absorbSurface(outputs);
|
|
234
|
+
if (Array.isArray(run?.steps)) {
|
|
235
|
+
for (const step of run.steps)
|
|
236
|
+
absorbSurface(readinessRecord(readinessRecord(step)?.outputs));
|
|
237
|
+
}
|
|
238
|
+
absorbReadiness(run?.readiness);
|
|
239
|
+
absorbReadiness(data.readiness);
|
|
240
|
+
const codes = buckets.map(blockerCodeOf).filter((code) => Boolean(code));
|
|
241
|
+
const sentences = buckets.map(blockerSentence).filter((sentence) => Boolean(sentence));
|
|
242
|
+
const credentials = codes.includes('credentials_required') || states.includes('credentials_required');
|
|
243
|
+
if (!credentials && codes.length === 0 && sentences.length === 0)
|
|
244
|
+
return null;
|
|
245
|
+
const sentence = sentences[0] ?? (credentials ? CREDENTIALS_REQUIRED_SENTENCE : 'This run is blocked until the workspace is ready.');
|
|
246
|
+
const code = credentials ? 'credentials_required' : codes[0] ?? 'not_ready';
|
|
247
|
+
return new client_1.CliError(sentence, code, 409, { retryable: false });
|
|
155
248
|
}
|
|
156
249
|
/** Adds the idempotency key to the printed meta, so a user can see which key to re-run with. */
|
|
157
250
|
function withIdempotencyMeta(value, key) {
|
|
@@ -222,11 +315,15 @@ async function runGated(context, input) {
|
|
|
222
315
|
let turnToken = input.turnToken ?? pending ?? (inlineRead ? undefined : optionalToolTurnToken(fetched));
|
|
223
316
|
// Only a quote the caller named or a dry run of this exact input returned.
|
|
224
317
|
// The server's refusal also shows a price, but that one is information, not consent.
|
|
225
|
-
|
|
318
|
+
const explicitQuote = typeof body.quote_hash === 'string';
|
|
319
|
+
let quoteHash = explicitQuote
|
|
226
320
|
? body.quote_hash
|
|
227
321
|
: live ? cached?.quote_hash ?? undefined : undefined;
|
|
322
|
+
// null means the price was not stated (or the flag named a hash with no ceiling).
|
|
323
|
+
let quotedMaximum = !explicitQuote && cached?.quote_hash ? cached.maximum_credits : undefined;
|
|
228
324
|
let ranDryRun = false;
|
|
229
325
|
let sentKey = null;
|
|
326
|
+
const approvalRequired = () => new client_1.CliError('This run spends credits. Rerun the same command with --approved.', 'approval_required', 409, { retryable: false, repair: { kind: 'ask_user', hint: 'Rerun the same command with --approved.' } });
|
|
230
327
|
const requestBody = () => ({
|
|
231
328
|
...body,
|
|
232
329
|
...(turnToken ? { tool_turn_token: turnToken } : {}),
|
|
@@ -259,6 +356,16 @@ async function runGated(context, input) {
|
|
|
259
356
|
let result;
|
|
260
357
|
try {
|
|
261
358
|
try {
|
|
359
|
+
if (live && quoteHash) {
|
|
360
|
+
const maximum = explicitQuote ? null : quotedMaximum ?? null;
|
|
361
|
+
if (spendNeedsApproval(maximum, body.approved === true)) {
|
|
362
|
+
stderr.write(`${quotePriced(capabilityId, body, { quote_hash: quoteHash, maximum_credits: maximum })}\n`);
|
|
363
|
+
throw approvalRequired();
|
|
364
|
+
}
|
|
365
|
+
if (body.approved === true || maximum === 0) {
|
|
366
|
+
stderr.write(`${quotePriced(capabilityId, body, { quote_hash: quoteHash, maximum_credits: maximum })}\nRunning live on that quote.\n`);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
262
369
|
result = await run();
|
|
263
370
|
}
|
|
264
371
|
catch (error) {
|
|
@@ -294,8 +401,12 @@ async function runGated(context, input) {
|
|
|
294
401
|
}
|
|
295
402
|
ranDryRun = true;
|
|
296
403
|
quoteHash = quote.quote_hash;
|
|
297
|
-
|
|
298
|
-
|
|
404
|
+
quotedMaximum = quote.maximum_credits;
|
|
405
|
+
stderr.write(`${quotePriced(capabilityId, body, quote)}\n`);
|
|
406
|
+
await (0, turnCache_1.rememberTurnToken)(context.turnsPath, context.baseUrl, context.turnKey, capabilityId, turnToken, Date.now(), warnTurnCache, { quote_hash: quote.quote_hash, fingerprint, maximum_credits: quote.maximum_credits });
|
|
407
|
+
if (spendNeedsApproval(quote.maximum_credits, body.approved === true))
|
|
408
|
+
throw approvalRequired();
|
|
409
|
+
stderr.write('Running live on that quote.\n');
|
|
299
410
|
result = await run();
|
|
300
411
|
}
|
|
301
412
|
else {
|
|
@@ -310,7 +421,7 @@ async function runGated(context, input) {
|
|
|
310
421
|
if (code(error) === 'approval_required') {
|
|
311
422
|
stderr.write('This run needs a person\'s approval. Show them the rows and cost above; when they agree, rerun the same command with --approved.\n');
|
|
312
423
|
}
|
|
313
|
-
await (0, turnCache_1.rememberTurnToken)(context.turnsPath, context.baseUrl, context.turnKey, capabilityId, turnToken, Date.now(), warnTurnCache, quoteHash ? { quote_hash: quoteHash, fingerprint } : undefined);
|
|
424
|
+
await (0, turnCache_1.rememberTurnToken)(context.turnsPath, context.baseUrl, context.turnKey, capabilityId, turnToken, Date.now(), warnTurnCache, quoteHash ? { quote_hash: quoteHash, fingerprint, ...(quotedMaximum !== undefined ? { maximum_credits: quotedMaximum } : {}) } : undefined);
|
|
314
425
|
}
|
|
315
426
|
// Only an unknown or transient result may resume an attempt. A server
|
|
316
427
|
// refusal with retryable:false is terminal and must receive a new key.
|
|
@@ -322,10 +433,8 @@ async function runGated(context, input) {
|
|
|
322
433
|
if (!input.turnToken) {
|
|
323
434
|
if (body.mode === 'dry_run' && turnToken) {
|
|
324
435
|
const quote = quoteFromResult(result);
|
|
325
|
-
await (0, turnCache_1.rememberTurnToken)(context.turnsPath, context.baseUrl, context.turnKey, capabilityId, turnToken, Date.now(), warnTurnCache, quote ? { quote_hash: quote.quote_hash, fingerprint } : undefined);
|
|
436
|
+
await (0, turnCache_1.rememberTurnToken)(context.turnsPath, context.baseUrl, context.turnKey, capabilityId, turnToken, Date.now(), warnTurnCache, quote ? { quote_hash: quote.quote_hash, fingerprint, maximum_credits: quote.maximum_credits } : undefined);
|
|
326
437
|
}
|
|
327
|
-
else if (pending || ranDryRun)
|
|
328
|
-
await (0, turnCache_1.forgetTurnToken)(context.turnsPath, context.baseUrl, context.turnKey, capabilityId, warnTurnCache);
|
|
329
438
|
}
|
|
330
439
|
let timedOut = false;
|
|
331
440
|
if (!input.noWait && !posture?.returnsRunId) {
|
|
@@ -333,12 +442,24 @@ async function runGated(context, input) {
|
|
|
333
442
|
result = waited.value;
|
|
334
443
|
timedOut = waited.timedOut;
|
|
335
444
|
}
|
|
445
|
+
// A timeout still owns the quote and the idempotency key. Forgetting the
|
|
446
|
+
// turn here made the rerun hash a body with no quote_hash and start a second run.
|
|
447
|
+
if (!input.turnToken && body.mode !== 'dry_run' && (pending || ranDryRun) && !timedOut) {
|
|
448
|
+
await (0, turnCache_1.forgetTurnToken)(context.turnsPath, context.baseUrl, context.turnKey, capabilityId, warnTurnCache);
|
|
449
|
+
}
|
|
336
450
|
// A run still active after waiting has unknown outcome; retain its key for
|
|
337
451
|
// the read-back/retry rule. A terminal response completes this attempt.
|
|
338
452
|
if (attemptIdentity && !timedOut)
|
|
339
453
|
await (0, idempotency_1.finishIdempotencyAttempt)(idempotencyPath, attemptIdentity);
|
|
454
|
+
const blocked = readinessRefusal(result);
|
|
455
|
+
if (blocked)
|
|
456
|
+
throw blocked;
|
|
340
457
|
return { value: withIdempotencyMeta(result, explicitKey ? null : sentKey), timedOut, idempotencyKey: sentKey, turnToken: turnToken ?? null };
|
|
341
458
|
}
|
|
459
|
+
/** Blocker refusal for a run envelope that did not go through runGated (runs wait). */
|
|
460
|
+
function refusalFromRunResult(value) {
|
|
461
|
+
return readinessRefusal(value);
|
|
462
|
+
}
|
|
342
463
|
/** A read the CLI needs before it can form a write, run through the same gate as any other run. */
|
|
343
464
|
async function readCapability(context, capabilityId, params, waitTimeout) {
|
|
344
465
|
const outcome = await runGated(context, { capabilityId, body: { params }, waitTimeout });
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"generated_by": "packages/cli/scripts/generate-pack-verbs.mjs from apps/backend/src/services/v1/capabilityRegistry/catalog.snapshot.json; do not edit by hand",
|
|
3
|
-
"registry_hash": "
|
|
3
|
+
"registry_hash": "95d77c841946a6aaedc94455495a3972caa0b8ba51d708181c2654dd755da418",
|
|
4
4
|
"verbs": [
|
|
5
5
|
{
|
|
6
6
|
"command": "sequences analytics",
|
package/dist/index.d.ts
CHANGED
|
@@ -155,9 +155,15 @@ export type CliCommand = {
|
|
|
155
155
|
command: 'runs_get';
|
|
156
156
|
runId: string;
|
|
157
157
|
jsonOutput?: boolean;
|
|
158
|
+
} | {
|
|
159
|
+
command: 'runs_wait';
|
|
160
|
+
runId: string;
|
|
161
|
+
waitTimeout: number;
|
|
162
|
+
jsonOutput?: boolean;
|
|
158
163
|
} | {
|
|
159
164
|
command: 'runs_events';
|
|
160
165
|
runId: string;
|
|
166
|
+
query?: Record<string, unknown>;
|
|
161
167
|
jsonOutput?: boolean;
|
|
162
168
|
} | {
|
|
163
169
|
command: 'runs_cancel';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AA8BA,OAAO,EAA0F,KAAK,WAAW,EAAE,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -20,6 +20,7 @@ const config_1 = require("./config");
|
|
|
20
20
|
const pluginInstaller_1 = require("./pluginInstaller");
|
|
21
21
|
const turnCache_1 = require("./turnCache");
|
|
22
22
|
const idempotency_1 = require("./idempotency");
|
|
23
|
+
const money_1 = require("./money");
|
|
23
24
|
const runWait_1 = require("./runWait");
|
|
24
25
|
const client_1 = require("./client");
|
|
25
26
|
const errors_1 = require("./errors");
|
|
@@ -51,13 +52,13 @@ Usage:
|
|
|
51
52
|
dreamstate packs list [--json-output|--json]
|
|
52
53
|
dreamstate packs get <pack_id> [--json-output|--json]
|
|
53
54
|
dreamstate packs route --goal <text> [--json-output|--json]
|
|
54
|
-
dreamstate skills list [--query <query>] [--limit <n>] [--json-output|--json]
|
|
55
|
+
dreamstate skills list [--query <query>] [--limit <n>] [--cursor <cursor>] [--json-output|--json]
|
|
55
56
|
dreamstate skills get <skill_id> [--file <path>] [--json-output|--json]
|
|
56
57
|
dreamstate skills search <query> [--limit <n>] [--json-output|--json]
|
|
57
58
|
dreamstate skills install [--skill <skill_id|*>] [--agents <codex claude-code cursor>] [--project] [--copy] [--json-output|--json]
|
|
58
59
|
dreamstate skills doctor [--agents <codex claude-code cursor>] [--project] [--json-output|--json]
|
|
59
60
|
dreamstate commands search <term> [--json-output|--json]
|
|
60
|
-
dreamstate tools search --goal <goal> [--terms <csv>] [--limit <n>] [--toolset <pack_id>] [--json-output|--json]
|
|
61
|
+
dreamstate tools search --goal <goal> [--terms <csv>] [--limit <n>] [--cursor <cursor>] [--toolset <pack_id>] [--json-output|--json]
|
|
61
62
|
dreamstate tools get <capability_id> [--json-output|--json]
|
|
62
63
|
dreamstate tools run <capability_id> [--params <object>|--json <body>] [--turn-token <token>] (--live | --dry-run | --mode <smoke_test|dry_run|live>) [--approved] [--approval-id <uuid>] [--approved-effect-unknown] [--max-credits <n>] [--max-live-sends <n>] [--quote-hash <sha256:...>] [--idempotency-key <key>] [--wait-timeout <seconds>] [--no-wait] [--open] [--json-output]
|
|
63
64
|
dreamstate sequences <verb> [args] [flags]
|
|
@@ -65,7 +66,9 @@ Usage:
|
|
|
65
66
|
dreamstate tables import --table-id <uuid> --file <path> [--format <csv|json|jsonl|xlsx>] [--preview] [--upsert-key <header>] [--row-kind <person|company>] [--keep-unmapped-columns <true|false>] [--json-output|--json]
|
|
66
67
|
dreamstate runs list [--limit <n>] [--cursor <cursor>] [--json <query>] [--json-output|--json]
|
|
67
68
|
dreamstate runs get <run_id> [--json-output|--json]
|
|
68
|
-
dreamstate runs
|
|
69
|
+
dreamstate runs status <run_id> [--json-output|--json]
|
|
70
|
+
dreamstate runs wait <run_id> [--wait-timeout <seconds>] [--json-output|--json]
|
|
71
|
+
dreamstate runs events <run_id> [--limit <n>] [--cursor <cursor>] [--json-output|--json]
|
|
69
72
|
dreamstate runs cancel <run_id> [--state-version <n>] [--reason <text>] [--json <body>] [--idempotency-key <key>] [--json-output|--json]
|
|
70
73
|
|
|
71
74
|
All catalog discovery reads live API records. Set DREAMSTATE_API_URL and DREAMSTATE_API_KEY.
|
|
@@ -147,8 +150,13 @@ function parsePacks(argv) {
|
|
|
147
150
|
return { command: 'packs_list', ...outputOption(values) };
|
|
148
151
|
if (positionals[0] === 'get')
|
|
149
152
|
return { command: 'packs_get', packId: requireOne(positionals, 'dreamstate packs get <pack_id>'), ...outputOption(values) };
|
|
150
|
-
if (positionals
|
|
151
|
-
|
|
153
|
+
if (positionals[0] === 'route') {
|
|
154
|
+
// `packs route "find work emails"` used to fall through to the generic
|
|
155
|
+
// usage line, which never said the goal belongs in --goal.
|
|
156
|
+
if (positionals.length === 1 && values.goal?.trim())
|
|
157
|
+
return { command: 'packs_route', goal: values.goal.trim(), ...outputOption(values) };
|
|
158
|
+
throw new errors_1.CliUsageError('Usage: dreamstate packs route --goal <text>. Pass the goal as --goal, not as a positional argument.');
|
|
159
|
+
}
|
|
152
160
|
throw new errors_1.CliUsageError('Usage: dreamstate packs <list|get|route>');
|
|
153
161
|
}
|
|
154
162
|
/** Rewrites `--agents a b c` into `--agents=a --agents=b --agents=c` so parseArgs sees every value. */
|
|
@@ -171,7 +179,7 @@ function spaceSeparatedAgents(argv) {
|
|
|
171
179
|
return out;
|
|
172
180
|
}
|
|
173
181
|
function parseSkills(argv) {
|
|
174
|
-
const { values, positionals } = (0, node_util_1.parseArgs)({ args: spaceSeparatedAgents(argv), options: { query: { type: 'string' }, limit: { type: 'string' }, skill: { type: 'string' }, file: { type: 'string' }, agents: { type: 'string', multiple: true }, project: { type: 'boolean' }, copy: { type: 'boolean' }, 'json-output': { type: 'boolean' }, help: { type: 'boolean', short: 'h' } }, allowPositionals: true, strict: true });
|
|
182
|
+
const { values, positionals } = (0, node_util_1.parseArgs)({ args: spaceSeparatedAgents(argv), options: { query: { type: 'string' }, limit: { type: 'string' }, cursor: { type: 'string' }, skill: { type: 'string' }, file: { type: 'string' }, agents: { type: 'string', multiple: true }, project: { type: 'boolean' }, copy: { type: 'boolean' }, 'json-output': { type: 'boolean' }, help: { type: 'boolean', short: 'h' } }, allowPositionals: true, strict: true });
|
|
175
183
|
if (values.help)
|
|
176
184
|
return { command: 'help' };
|
|
177
185
|
const agents = () => {
|
|
@@ -189,8 +197,16 @@ function parseSkills(argv) {
|
|
|
189
197
|
query.query = values.query;
|
|
190
198
|
if (values.limit !== undefined)
|
|
191
199
|
query.limit = nonNegativeInteger(values.limit, '--limit');
|
|
200
|
+
if (values.cursor !== undefined) {
|
|
201
|
+
const cursor = values.cursor.trim();
|
|
202
|
+
if (!cursor)
|
|
203
|
+
throw new errors_1.CliUsageError('--cursor must be a non-empty string');
|
|
204
|
+
query.cursor = cursor;
|
|
205
|
+
}
|
|
192
206
|
return { command: 'skills_list', query, ...outputOption(values) };
|
|
193
207
|
}
|
|
208
|
+
if (values.cursor !== undefined)
|
|
209
|
+
throw new errors_1.CliUsageError('--cursor is only valid on skills list');
|
|
194
210
|
if (positionals[0] === 'get')
|
|
195
211
|
return { command: 'skills_get', skillId: requireOne(positionals, 'dreamstate skills get <skill_id>'), ...(values.file?.trim() ? { file: values.file.trim() } : {}), ...outputOption(values) };
|
|
196
212
|
if (positionals[0] === 'search' && positionals.length > 1) {
|
|
@@ -242,7 +258,7 @@ function toolsRunMode(values) {
|
|
|
242
258
|
function parseTools(argv) {
|
|
243
259
|
const { values, positionals } = (0, node_util_1.parseArgs)({ args: argv, options: {
|
|
244
260
|
json: { type: 'string' }, params: { type: 'string' }, goal: { type: 'string' }, terms: { type: 'string' },
|
|
245
|
-
limit: { type: 'string' }, toolset: { type: 'string' },
|
|
261
|
+
limit: { type: 'string' }, cursor: { type: 'string' }, toolset: { type: 'string' },
|
|
246
262
|
'idempotency-key': { type: 'string' }, 'json-output': { type: 'boolean' }, open: { type: 'boolean' },
|
|
247
263
|
'dry-run': { type: 'boolean' }, live: { type: 'boolean' }, mode: { type: 'string' },
|
|
248
264
|
approved: { type: 'boolean' }, 'approved-effect-unknown': { type: 'boolean' },
|
|
@@ -260,12 +276,20 @@ function parseTools(argv) {
|
|
|
260
276
|
query.query_terms = csv(values.terms);
|
|
261
277
|
if (values.limit !== undefined)
|
|
262
278
|
query.limit = nonNegativeInteger(values.limit, '--limit');
|
|
279
|
+
if (values.cursor !== undefined) {
|
|
280
|
+
const cursor = values.cursor.trim();
|
|
281
|
+
if (!cursor)
|
|
282
|
+
throw new errors_1.CliUsageError('--cursor must be a non-empty string');
|
|
283
|
+
query.cursor = cursor;
|
|
284
|
+
}
|
|
263
285
|
if (values.toolset !== undefined)
|
|
264
286
|
query.toolset = values.toolset;
|
|
265
287
|
if (typeof query.goal !== 'string' && !Array.isArray(query.query_terms))
|
|
266
288
|
throw new errors_1.CliUsageError('tools search requires --goal, --terms, or --json query fields');
|
|
267
289
|
return { command: 'tools_search', query, ...output };
|
|
268
290
|
}
|
|
291
|
+
if (values.cursor !== undefined)
|
|
292
|
+
throw new errors_1.CliUsageError('--cursor is only valid on tools search');
|
|
269
293
|
if (positionals[0] === 'get')
|
|
270
294
|
return { command: 'tools_get', capabilityId: requireOne(positionals, 'dreamstate tools get <capability_id>'), ...output };
|
|
271
295
|
if (positionals[0] === 'run') {
|
|
@@ -390,7 +414,7 @@ function runsListLimit(raw) {
|
|
|
390
414
|
return value;
|
|
391
415
|
}
|
|
392
416
|
function parseRuns(argv) {
|
|
393
|
-
const { values, positionals } = (0, node_util_1.parseArgs)({ args: argv, options: { json: { type: 'string' }, limit: { type: 'string' }, cursor: { type: 'string' }, reason: { type: 'string' }, 'state-version': { type: 'string' }, 'idempotency-key': { type: 'string' }, open: { type: 'boolean' }, 'json-output': { type: 'boolean' }, help: { type: 'boolean', short: 'h' } }, allowPositionals: true, strict: true });
|
|
417
|
+
const { values, positionals } = (0, node_util_1.parseArgs)({ args: argv, options: { json: { type: 'string' }, limit: { type: 'string' }, cursor: { type: 'string' }, reason: { type: 'string' }, 'state-version': { type: 'string' }, 'idempotency-key': { type: 'string' }, 'wait-timeout': { type: 'string' }, open: { type: 'boolean' }, 'json-output': { type: 'boolean' }, help: { type: 'boolean', short: 'h' } }, allowPositionals: true, strict: true });
|
|
394
418
|
if (values.help)
|
|
395
419
|
return { command: 'help' };
|
|
396
420
|
const output = outputOption(values);
|
|
@@ -406,19 +430,39 @@ function parseRuns(argv) {
|
|
|
406
430
|
}
|
|
407
431
|
return { command: 'runs_list', query, ...output };
|
|
408
432
|
}
|
|
433
|
+
if (positionals[0] === 'events') {
|
|
434
|
+
const runId = requireOne(positionals, 'dreamstate runs events <run_id>');
|
|
435
|
+
const query = {};
|
|
436
|
+
if (values.limit !== undefined)
|
|
437
|
+
query.limit = runsListLimit(values.limit);
|
|
438
|
+
if (values.cursor !== undefined) {
|
|
439
|
+
const cursor = values.cursor.trim();
|
|
440
|
+
if (!cursor)
|
|
441
|
+
throw new errors_1.CliUsageError('--cursor must be a non-empty string');
|
|
442
|
+
query.cursor = cursor;
|
|
443
|
+
}
|
|
444
|
+
return { command: 'runs_events', runId, ...(Object.keys(query).length ? { query } : {}), ...output };
|
|
445
|
+
}
|
|
409
446
|
if (values.limit !== undefined || values.cursor !== undefined) {
|
|
410
|
-
throw new errors_1.CliUsageError('--limit and --cursor are only valid on runs list');
|
|
447
|
+
throw new errors_1.CliUsageError('--limit and --cursor are only valid on runs list and runs events');
|
|
411
448
|
}
|
|
412
449
|
if (positionals[0] === 'resume') {
|
|
413
450
|
// The server retired generic run resume (verifyExecutionDoorCollapse.ts blocks the
|
|
414
451
|
// route), so there is nothing to call. Say where the replacement is.
|
|
415
452
|
throw new errors_1.CliUsageError('runs resume was retired: the server has no generic run resume. A table run checkpoint resumes with: dreamstate tools run tables.table_runs.resume --params \'{...}\' --live. Start a new run for anything else.');
|
|
416
453
|
}
|
|
417
|
-
const runId = requireOne(positionals, `dreamstate runs ${positionals[0] ?? '<get|events|cancel>'} <run_id>`);
|
|
418
|
-
if (positionals[0] === 'get')
|
|
454
|
+
const runId = requireOne(positionals, `dreamstate runs ${positionals[0] ?? '<get|status|wait|events|cancel>'} <run_id>`);
|
|
455
|
+
if (positionals[0] === 'get' || positionals[0] === 'status') {
|
|
456
|
+
if (values['wait-timeout'] !== undefined)
|
|
457
|
+
throw new errors_1.CliUsageError('--wait-timeout is only valid on runs wait');
|
|
419
458
|
return { command: 'runs_get', runId, ...output };
|
|
420
|
-
|
|
421
|
-
|
|
459
|
+
}
|
|
460
|
+
if (positionals[0] === 'wait') {
|
|
461
|
+
const waitTimeout = values['wait-timeout'] === undefined ? 120 : nonNegativeNumber(values['wait-timeout'], '--wait-timeout');
|
|
462
|
+
return { command: 'runs_wait', runId, waitTimeout, ...output };
|
|
463
|
+
}
|
|
464
|
+
if (values['wait-timeout'] !== undefined)
|
|
465
|
+
throw new errors_1.CliUsageError('--wait-timeout is only valid on runs wait');
|
|
422
466
|
if (positionals[0] === 'cancel') {
|
|
423
467
|
const idempotency = values['idempotency-key'] ? { idempotencyKey: values['idempotency-key'] } : {};
|
|
424
468
|
if (values.json && (values['state-version'] !== undefined || values.reason)) {
|
|
@@ -435,7 +479,7 @@ function parseRuns(argv) {
|
|
|
435
479
|
...output,
|
|
436
480
|
};
|
|
437
481
|
}
|
|
438
|
-
throw new errors_1.CliUsageError('Usage: dreamstate runs <list|get|events|cancel> <run_id>');
|
|
482
|
+
throw new errors_1.CliUsageError('Usage: dreamstate runs <list|get|status|wait|events|cancel> <run_id>');
|
|
439
483
|
}
|
|
440
484
|
function sequencesCommands() {
|
|
441
485
|
return require('./commands/sequences');
|
|
@@ -549,11 +593,9 @@ function parseCliArgs(argv) {
|
|
|
549
593
|
throw new errors_1.CliUsageError(`Unknown command: ${group}`);
|
|
550
594
|
}
|
|
551
595
|
function print(value, stdout, compact) {
|
|
552
|
-
//
|
|
553
|
-
//
|
|
554
|
-
|
|
555
|
-
// to the caller's own session, not a credential, and MCP and REST return it too.
|
|
556
|
-
stdout.write(`${JSON.stringify(value, null, compact ? 0 : 2)}\n`);
|
|
596
|
+
// tool_turn_token stays: it is a short-lived fetch fence, not a credential.
|
|
597
|
+
// Provider USD does not. Customer maps (values, cells, params, ...) are left whole.
|
|
598
|
+
stdout.write(`${JSON.stringify((0, money_1.scrubCliOutput)(value), null, compact ? 0 : 2)}\n`);
|
|
557
599
|
}
|
|
558
600
|
function printPackRoute(value, stdout) {
|
|
559
601
|
const data = value && typeof value === 'object' && !Array.isArray(value)
|
|
@@ -579,7 +621,7 @@ function printPackRoute(value, stdout) {
|
|
|
579
621
|
continue;
|
|
580
622
|
const { pack_id: packId, reason } = alternate;
|
|
581
623
|
if (typeof packId === 'string')
|
|
582
|
-
stdout.write(`${packId}${typeof reason === 'string' ? `: ${reason}` : ''}\n`);
|
|
624
|
+
stdout.write(`${(0, money_1.scrubDollarText)(packId)}${typeof reason === 'string' ? `: ${(0, money_1.scrubDollarText)(reason)}` : ''}\n`);
|
|
583
625
|
}
|
|
584
626
|
}
|
|
585
627
|
/**
|
|
@@ -821,6 +863,23 @@ function whoamiData(value) {
|
|
|
821
863
|
const data = value && typeof value === 'object' ? value.data : undefined;
|
|
822
864
|
return data && typeof data === 'object' ? data : {};
|
|
823
865
|
}
|
|
866
|
+
const WORKSPACE_MISMATCH_MESSAGE = 'The server acted in a different workspace than the one you approved.';
|
|
867
|
+
/** Canonical workspace id the whoami request actually acted in, or a refusal. */
|
|
868
|
+
function workspacePinFromWhoami(whoami, requested) {
|
|
869
|
+
const data = whoamiData(whoami);
|
|
870
|
+
const acted = typeof data.workspace_id === 'string' ? data.workspace_id : '';
|
|
871
|
+
const wanted = requested.trim().toLowerCase();
|
|
872
|
+
const rows = data.workspaces ?? [];
|
|
873
|
+
const match = rows.find((row) => row.id.toLowerCase() === wanted || row.slug?.toLowerCase() === wanted);
|
|
874
|
+
if (match) {
|
|
875
|
+
if (acted !== match.id)
|
|
876
|
+
throw new client_1.CliError(WORKSPACE_MISMATCH_MESSAGE, 'workspace_mismatch', 400);
|
|
877
|
+
return match.id;
|
|
878
|
+
}
|
|
879
|
+
if (rows.length === 0 && acted.toLowerCase() === wanted)
|
|
880
|
+
return acted;
|
|
881
|
+
throw new client_1.CliError(WORKSPACE_MISMATCH_MESSAGE, 'workspace_mismatch', 400);
|
|
882
|
+
}
|
|
824
883
|
/**
|
|
825
884
|
* What `dreamstate status` reports. The release identity comes from the server's
|
|
826
885
|
* own answers (envelope meta and X-Dreamstate-* headers on every response), so
|
|
@@ -922,17 +981,21 @@ async function loginWithDeviceAuthorization(runtime, stdout, stderr, profile, no
|
|
|
922
981
|
for (;;) {
|
|
923
982
|
const claim = await (0, client_1.claimDeviceAuthorization)(baseUrl, authorization.device_code);
|
|
924
983
|
if (claim.status === 'ready') {
|
|
925
|
-
if (profile)
|
|
926
|
-
await (0, config_1.storeCredentialProfile)(profile, claim.token, runtimeCredentialsPath(runtime), claim.workspace.id);
|
|
927
|
-
else
|
|
928
|
-
await (0, config_1.storeApiKey)(claim.token, runtimeCredentialsPath(runtime), claim.workspace.id);
|
|
929
984
|
const client = new client_1.DreamstateClient({
|
|
930
985
|
baseUrl,
|
|
931
986
|
apiKey: claim.token,
|
|
987
|
+
workspace: claim.workspace.id,
|
|
932
988
|
requestTimeoutMs: runtime.requestTimeoutMs,
|
|
933
989
|
onVersionWarning: (message) => (runtime.stderr ?? process.stderr).write(`${message}\n`),
|
|
934
990
|
});
|
|
935
991
|
const whoami = await client.getWhoami();
|
|
992
|
+
if (whoamiData(whoami).workspace_id !== claim.workspace.id) {
|
|
993
|
+
throw new client_1.CliError(WORKSPACE_MISMATCH_MESSAGE, 'workspace_mismatch', 400);
|
|
994
|
+
}
|
|
995
|
+
if (profile)
|
|
996
|
+
await (0, config_1.storeCredentialProfile)(profile, claim.token, runtimeCredentialsPath(runtime), claim.workspace.id);
|
|
997
|
+
else
|
|
998
|
+
await (0, config_1.storeApiKey)(claim.token, runtimeCredentialsPath(runtime), claim.workspace.id);
|
|
936
999
|
const skills = await installLoginSkills(client, runtime, noSkills, stderr);
|
|
937
1000
|
print(loginResult(whoami, skills), stdout, jsonOutput);
|
|
938
1001
|
return;
|
|
@@ -1051,10 +1114,11 @@ async function runCli(argv = process.argv.slice(2), runtime = {}) {
|
|
|
1051
1114
|
onVersionWarning: (message) => stderr.write(`${message}\n`),
|
|
1052
1115
|
});
|
|
1053
1116
|
const whoami = await client.getWhoami();
|
|
1117
|
+
const pinned = requested ? workspacePinFromWhoami(whoami, requested) : null;
|
|
1054
1118
|
if (command.profile)
|
|
1055
|
-
await (0, config_1.storeCredentialProfile)(command.profile, token, runtimeCredentialsPath(runtime));
|
|
1119
|
+
await (0, config_1.storeCredentialProfile)(command.profile, token, runtimeCredentialsPath(runtime), pinned);
|
|
1056
1120
|
else
|
|
1057
|
-
await (0, config_1.storeApiKey)(token, runtimeCredentialsPath(runtime));
|
|
1121
|
+
await (0, config_1.storeApiKey)(token, runtimeCredentialsPath(runtime), pinned);
|
|
1058
1122
|
const skills = await installLoginSkills(client, runtime, Boolean(command.noSkills), stderr);
|
|
1059
1123
|
print(loginResult(whoami, skills), stdout, Boolean(command.jsonOutput));
|
|
1060
1124
|
process.exitCode = errors_1.CLI_EXIT.SUCCESS;
|
|
@@ -1096,10 +1160,19 @@ async function runCli(argv = process.argv.slice(2), runtime = {}) {
|
|
|
1096
1160
|
const key = await readLoginKey(command, runtime);
|
|
1097
1161
|
if (!(0, config_1.isDreamstateToken)(key))
|
|
1098
1162
|
throw new errors_1.CliUsageError('Dreamstate API keys must start with ds_user_ or ds_live_.');
|
|
1163
|
+
const environment = runtime.env ?? process.env;
|
|
1164
|
+
const requested = extracted.workspace ?? environment.DREAMSTATE_WORKSPACE?.trim();
|
|
1165
|
+
const client = new client_1.DreamstateClient({
|
|
1166
|
+
baseUrl: (0, config_1.resolveApiBaseUrl)(environment),
|
|
1167
|
+
apiKey: key,
|
|
1168
|
+
...(requested ? { workspace: requested } : {}),
|
|
1169
|
+
requestTimeoutMs: runtime.requestTimeoutMs,
|
|
1170
|
+
onVersionWarning: (message) => stderr.write(`${message}\n`),
|
|
1171
|
+
});
|
|
1172
|
+
const pinned = requested ? workspacePinFromWhoami(await client.getWhoami(), requested) : null;
|
|
1099
1173
|
const path = command.profile
|
|
1100
|
-
? await (0, config_1.storeCredentialProfile)(command.profile, key, runtimeCredentialsPath(runtime))
|
|
1101
|
-
: await (0, config_1.storeApiKey)(key, runtimeCredentialsPath(runtime));
|
|
1102
|
-
const client = new client_1.DreamstateClient({ baseUrl: (0, config_1.resolveApiBaseUrl)(runtime.env ?? process.env), apiKey: key, requestTimeoutMs: runtime.requestTimeoutMs, onVersionWarning: (message) => stderr.write(`${message}\n`) });
|
|
1174
|
+
? await (0, config_1.storeCredentialProfile)(command.profile, key, runtimeCredentialsPath(runtime), pinned)
|
|
1175
|
+
: await (0, config_1.storeApiKey)(key, runtimeCredentialsPath(runtime), pinned);
|
|
1103
1176
|
const skills = await installLoginSkills(client, runtime, Boolean(command.noSkills), stderr);
|
|
1104
1177
|
print({ ok: true, data: { credentials_path: path, skills }, meta: {} }, stdout, Boolean(command.jsonOutput));
|
|
1105
1178
|
process.exitCode = errors_1.CLI_EXIT.SUCCESS;
|
|
@@ -1362,8 +1435,19 @@ async function runCli(argv = process.argv.slice(2), runtime = {}) {
|
|
|
1362
1435
|
case 'runs_get':
|
|
1363
1436
|
result = await client.getRun(command.runId);
|
|
1364
1437
|
break;
|
|
1438
|
+
case 'runs_wait': {
|
|
1439
|
+
const initial = await client.getRun(command.runId);
|
|
1440
|
+
const waited = await (0, runWait_1.waitForRun)(client, initial, command.waitTimeout, runtime.sleep ?? wait);
|
|
1441
|
+
const blocked = (0, gatedRun_1.refusalFromRunResult)(waited.value);
|
|
1442
|
+
if (blocked)
|
|
1443
|
+
throw blocked;
|
|
1444
|
+
result = waited.value;
|
|
1445
|
+
if (waited.timedOut)
|
|
1446
|
+
process.exitCode = runWait_1.RUN_WAIT_TIMEOUT_EXIT_CODE;
|
|
1447
|
+
break;
|
|
1448
|
+
}
|
|
1365
1449
|
case 'runs_events':
|
|
1366
|
-
result = await client.getRunEvents(command.runId);
|
|
1450
|
+
result = await client.getRunEvents(command.runId, command.query ?? {});
|
|
1367
1451
|
break;
|
|
1368
1452
|
case 'runs_cancel': {
|
|
1369
1453
|
const body = command.body ?? {
|
|
@@ -1407,7 +1491,7 @@ async function runCli(argv = process.argv.slice(2), runtime = {}) {
|
|
|
1407
1491
|
}
|
|
1408
1492
|
catch (error) {
|
|
1409
1493
|
const exitCode = exitCodeForError(error);
|
|
1410
|
-
stdout.write(`${JSON.stringify(refusalEnvelope(error, exitCode))}\n`);
|
|
1494
|
+
stdout.write(`${JSON.stringify((0, money_1.scrubCliOutput)(refusalEnvelope(error, exitCode)))}\n`);
|
|
1411
1495
|
process.exitCode = exitCode;
|
|
1412
1496
|
throw error;
|
|
1413
1497
|
}
|
package/dist/money.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Customers see credits. Provider USD (a key that pairs usd with a cost word,
|
|
3
|
+
* a cogs key other than cogs_credits, or a provider_cost / provider_spend
|
|
4
|
+
* prefix) is dropped. Dollar amounts in our own sentences become "an amount".
|
|
5
|
+
* Customer maps are not entered: annual_revenue_usd and price_usd stay.
|
|
6
|
+
*/
|
|
7
|
+
export declare function isProviderCostKey(key: string): boolean;
|
|
8
|
+
export declare function scrubDollarText(text: string): string;
|
|
9
|
+
export declare function scrubCliOutput(value: unknown, depth?: number): unknown;
|
|
10
|
+
//# sourceMappingURL=money.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"money.d.ts","sourceRoot":"","sources":["../src/money.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAwBH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAQtD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGpD;AAeD,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,SAAI,GAAG,OAAO,CAWjE"}
|