@trydreamstate/cli 1.3.4 → 1.3.6
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 +2 -0
- 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 +5 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +45 -4
- 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 +128 -34
- 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": "0919f010ebbbf4a46e5c0e68f9f8f3026abc6420aa325716911cd528c59568ea",
|
|
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":";AA8BA,OAAO,EAA0F,KAAK,WAAW,EAAE,KAAK,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAKnK,OAAO,EAA0I,KAAK,iBAAiB,EAA6C,MAAM,UAAU,CAAC;AACrO,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAwC,MAAM,UAAU,CAAC;AACzF,OAAO,EAAE,wBAAwB,EAA8D,MAAM,YAAY,CAAC;AAGlH,OAAO,EAAqK,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE7N,MAAM,MAAM,wBAAwB,GAAG,MAAM,CAAC;AAI9C,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,wBAAwB,EAAE,CAAC;AAkD7D,MAAM,MAAM,UAAU,GAClB;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GACnB;IAAE,OAAO,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7D;IAAE,OAAO,EAAE,SAAS,CAAA;CAAE,GACtB;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GACrH;IAAE,OAAO,EAAE,QAAQ,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAC3C;IAAE,OAAO,EAAE,QAAQ,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAC3C;IAAE,OAAO,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,WAAW,EAAE,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GACnE;IAAE,OAAO,EAAE,eAAe,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAClD;IAAE,OAAO,EAAE,cAAc,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAC/D;IAAE,OAAO,EAAE,kBAAkB,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GACrD;IAAE,OAAO,EAAE,iBAAiB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAClE;IAAE,OAAO,EAAE,cAAc,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAC/D;IAAE,OAAO,EAAE,QAAQ,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAC3C;IAAE,OAAO,EAAE,iBAAiB,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GACpD;IAAE,OAAO,EAAE,gBAAgB,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GACtE;IAAE,OAAO,EAAE,YAAY,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAC/C;IAAE,OAAO,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAC9D;IAAE,OAAO,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAC9D;IAAE,OAAO,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAChF;IAAE,OAAO,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAC/E;IAAE,OAAO,EAAE,eAAe,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAClF;IAAE,OAAO,EAAE,gBAAgB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GACpI;IAAE,OAAO,EAAE,eAAe,CAAC;IAAC,MAAM,EAAE,iBAAiB,EAAE,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAClG;IAAE,OAAO,EAAE,iBAAiB,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAClE;IAAE,OAAO,EAAE,cAAc,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GACjF;IAAE,OAAO,EAAE,WAAW,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GACpE;IAAE,OAAO,EAAE,WAAW,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GACvM;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,WAAW,GAAG,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAC/D,YAAY,EAAE,wBAAwB,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAC,MAAM,CAAC,CAAC;IAAC,IAAI,CAAC,EAAE,SAAS,GAAC,MAAM,GAAC,YAAY,CAAC;IACzE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IACjH,UAAU,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC3H;IAAE,OAAO,EAAE,eAAe,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GACnO;IAAE,OAAO,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAC9E;IAAE,OAAO,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAC5D;IAAE,OAAO,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAClF;IAAE,OAAO,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,GAChG;IAAE,OAAO,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAErK,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC,cAAc,GAAG;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;IACpD,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC/B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACnD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC;AAyXD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,UAAU,CA2EvD;AAiCD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAqBzF;AAED,KAAK,SAAS,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,EAAE;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,KAAK;IAAE,KAAK,IAAI,IAAI,CAAC;IAAC,EAAE,CAAC,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,OAAO,CAAA;CAAE,CAAC;AAEhN,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,SAAiB,GAAG,IAAI,CAyB1E;AA4FD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAqBvD;AAwBD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG;IAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAkB3F;AAwBD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,iBAAiB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAmB7G;AAiHD,wBAAsB,MAAM,CAAC,IAAI,GAAE,MAAM,EAA0B,EAAE,OAAO,GAAE,UAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA6Z5G"}
|
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");
|
|
@@ -44,6 +45,7 @@ Usage:
|
|
|
44
45
|
dreamstate status [--json-output|--json]
|
|
45
46
|
dreamstate profiles <list|use|current|remove|env> [name] [--json-output|--json]
|
|
46
47
|
dreamstate whoami [--json-output|--json]
|
|
48
|
+
dreamstate credits [--json-output|--json]
|
|
47
49
|
dreamstate workspaces list [--json-output|--json]
|
|
48
50
|
dreamstate workspaces use <id|slug>
|
|
49
51
|
dreamstate auth login [--api-key-file <path>] [--no-skills]
|
|
@@ -51,13 +53,13 @@ Usage:
|
|
|
51
53
|
dreamstate packs list [--json-output|--json]
|
|
52
54
|
dreamstate packs get <pack_id> [--json-output|--json]
|
|
53
55
|
dreamstate packs route --goal <text> [--json-output|--json]
|
|
54
|
-
dreamstate skills list [--query <query>] [--limit <n>] [--json-output|--json]
|
|
56
|
+
dreamstate skills list [--query <query>] [--limit <n>] [--cursor <cursor>] [--json-output|--json]
|
|
55
57
|
dreamstate skills get <skill_id> [--file <path>] [--json-output|--json]
|
|
56
58
|
dreamstate skills search <query> [--limit <n>] [--json-output|--json]
|
|
57
59
|
dreamstate skills install [--skill <skill_id|*>] [--agents <codex claude-code cursor>] [--project] [--copy] [--json-output|--json]
|
|
58
60
|
dreamstate skills doctor [--agents <codex claude-code cursor>] [--project] [--json-output|--json]
|
|
59
61
|
dreamstate commands search <term> [--json-output|--json]
|
|
60
|
-
dreamstate tools search --goal <goal> [--terms <csv>] [--limit <n>] [--toolset <pack_id>] [--json-output|--json]
|
|
62
|
+
dreamstate tools search --goal <goal> [--terms <csv>] [--limit <n>] [--cursor <cursor>] [--toolset <pack_id>] [--json-output|--json]
|
|
61
63
|
dreamstate tools get <capability_id> [--json-output|--json]
|
|
62
64
|
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
65
|
dreamstate sequences <verb> [args] [flags]
|
|
@@ -65,14 +67,16 @@ Usage:
|
|
|
65
67
|
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
68
|
dreamstate runs list [--limit <n>] [--cursor <cursor>] [--json <query>] [--json-output|--json]
|
|
67
69
|
dreamstate runs get <run_id> [--json-output|--json]
|
|
68
|
-
dreamstate runs
|
|
70
|
+
dreamstate runs status <run_id> [--json-output|--json]
|
|
71
|
+
dreamstate runs wait <run_id> [--wait-timeout <seconds>] [--json-output|--json]
|
|
72
|
+
dreamstate runs events <run_id> [--limit <n>] [--cursor <cursor>] [--json-output|--json]
|
|
69
73
|
dreamstate runs cancel <run_id> [--state-version <n>] [--reason <text>] [--json <body>] [--idempotency-key <key>] [--json-output|--json]
|
|
70
74
|
|
|
71
|
-
All catalog discovery reads live API records.
|
|
75
|
+
All catalog discovery reads live API records. Run dreamstate login to connect.
|
|
72
76
|
Run responses wait for terminal run status by default, timeout default is 120 seconds, --no-wait returns immediate response. Timeout prints latest run envelope and exits ${runWait_1.RUN_WAIT_TIMEOUT_EXIT_CODE}.
|
|
73
77
|
A write you re-run unchanged presents the same Idempotency-Key (printed as meta.idempotency_key), so the server replays instead of running it twice; --idempotency-key sets one yourself. Exit codes: 0 ok, 2 usage, 3 auth, 4 not found, 5 server failure, 6 rate limited, 7 repair.kind ask_user, 8 CLI update required, 9 refused, 10 transport, 11 timeout.
|
|
74
78
|
login opens browser approval and installs Dreamstate skills for detected agents; --no-skills skips installation. login --token stores a ds_user_ session or ds_live_ key (for SSH or remote machines) after verifying it with whoami.
|
|
75
|
-
Global flag --workspace <id|slug> (any command)
|
|
79
|
+
Global flag --workspace <id|slug> (any command) picks the workspace for one call; workspaces use stores a default. Flag beats connection settings, which beat stored defaults. A ds_live_ key is bound to one workspace and cannot switch.
|
|
76
80
|
logout deletes the stored credentials file. --agents takes space-separated, comma-separated or repeated values.
|
|
77
81
|
`;
|
|
78
82
|
function outputOption(values) {
|
|
@@ -147,8 +151,13 @@ function parsePacks(argv) {
|
|
|
147
151
|
return { command: 'packs_list', ...outputOption(values) };
|
|
148
152
|
if (positionals[0] === 'get')
|
|
149
153
|
return { command: 'packs_get', packId: requireOne(positionals, 'dreamstate packs get <pack_id>'), ...outputOption(values) };
|
|
150
|
-
if (positionals
|
|
151
|
-
|
|
154
|
+
if (positionals[0] === 'route') {
|
|
155
|
+
// `packs route "find work emails"` used to fall through to the generic
|
|
156
|
+
// usage line, which never said the goal belongs in --goal.
|
|
157
|
+
if (positionals.length === 1 && values.goal?.trim())
|
|
158
|
+
return { command: 'packs_route', goal: values.goal.trim(), ...outputOption(values) };
|
|
159
|
+
throw new errors_1.CliUsageError('Usage: dreamstate packs route --goal <text>. Pass the goal as --goal, not as a positional argument.');
|
|
160
|
+
}
|
|
152
161
|
throw new errors_1.CliUsageError('Usage: dreamstate packs <list|get|route>');
|
|
153
162
|
}
|
|
154
163
|
/** Rewrites `--agents a b c` into `--agents=a --agents=b --agents=c` so parseArgs sees every value. */
|
|
@@ -171,7 +180,7 @@ function spaceSeparatedAgents(argv) {
|
|
|
171
180
|
return out;
|
|
172
181
|
}
|
|
173
182
|
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 });
|
|
183
|
+
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
184
|
if (values.help)
|
|
176
185
|
return { command: 'help' };
|
|
177
186
|
const agents = () => {
|
|
@@ -189,8 +198,16 @@ function parseSkills(argv) {
|
|
|
189
198
|
query.query = values.query;
|
|
190
199
|
if (values.limit !== undefined)
|
|
191
200
|
query.limit = nonNegativeInteger(values.limit, '--limit');
|
|
201
|
+
if (values.cursor !== undefined) {
|
|
202
|
+
const cursor = values.cursor.trim();
|
|
203
|
+
if (!cursor)
|
|
204
|
+
throw new errors_1.CliUsageError('--cursor must be a non-empty string');
|
|
205
|
+
query.cursor = cursor;
|
|
206
|
+
}
|
|
192
207
|
return { command: 'skills_list', query, ...outputOption(values) };
|
|
193
208
|
}
|
|
209
|
+
if (values.cursor !== undefined)
|
|
210
|
+
throw new errors_1.CliUsageError('--cursor is only valid on skills list');
|
|
194
211
|
if (positionals[0] === 'get')
|
|
195
212
|
return { command: 'skills_get', skillId: requireOne(positionals, 'dreamstate skills get <skill_id>'), ...(values.file?.trim() ? { file: values.file.trim() } : {}), ...outputOption(values) };
|
|
196
213
|
if (positionals[0] === 'search' && positionals.length > 1) {
|
|
@@ -242,7 +259,7 @@ function toolsRunMode(values) {
|
|
|
242
259
|
function parseTools(argv) {
|
|
243
260
|
const { values, positionals } = (0, node_util_1.parseArgs)({ args: argv, options: {
|
|
244
261
|
json: { type: 'string' }, params: { type: 'string' }, goal: { type: 'string' }, terms: { type: 'string' },
|
|
245
|
-
limit: { type: 'string' }, toolset: { type: 'string' },
|
|
262
|
+
limit: { type: 'string' }, cursor: { type: 'string' }, toolset: { type: 'string' },
|
|
246
263
|
'idempotency-key': { type: 'string' }, 'json-output': { type: 'boolean' }, open: { type: 'boolean' },
|
|
247
264
|
'dry-run': { type: 'boolean' }, live: { type: 'boolean' }, mode: { type: 'string' },
|
|
248
265
|
approved: { type: 'boolean' }, 'approved-effect-unknown': { type: 'boolean' },
|
|
@@ -260,12 +277,20 @@ function parseTools(argv) {
|
|
|
260
277
|
query.query_terms = csv(values.terms);
|
|
261
278
|
if (values.limit !== undefined)
|
|
262
279
|
query.limit = nonNegativeInteger(values.limit, '--limit');
|
|
280
|
+
if (values.cursor !== undefined) {
|
|
281
|
+
const cursor = values.cursor.trim();
|
|
282
|
+
if (!cursor)
|
|
283
|
+
throw new errors_1.CliUsageError('--cursor must be a non-empty string');
|
|
284
|
+
query.cursor = cursor;
|
|
285
|
+
}
|
|
263
286
|
if (values.toolset !== undefined)
|
|
264
287
|
query.toolset = values.toolset;
|
|
265
288
|
if (typeof query.goal !== 'string' && !Array.isArray(query.query_terms))
|
|
266
289
|
throw new errors_1.CliUsageError('tools search requires --goal, --terms, or --json query fields');
|
|
267
290
|
return { command: 'tools_search', query, ...output };
|
|
268
291
|
}
|
|
292
|
+
if (values.cursor !== undefined)
|
|
293
|
+
throw new errors_1.CliUsageError('--cursor is only valid on tools search');
|
|
269
294
|
if (positionals[0] === 'get')
|
|
270
295
|
return { command: 'tools_get', capabilityId: requireOne(positionals, 'dreamstate tools get <capability_id>'), ...output };
|
|
271
296
|
if (positionals[0] === 'run') {
|
|
@@ -390,7 +415,7 @@ function runsListLimit(raw) {
|
|
|
390
415
|
return value;
|
|
391
416
|
}
|
|
392
417
|
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 });
|
|
418
|
+
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
419
|
if (values.help)
|
|
395
420
|
return { command: 'help' };
|
|
396
421
|
const output = outputOption(values);
|
|
@@ -406,19 +431,39 @@ function parseRuns(argv) {
|
|
|
406
431
|
}
|
|
407
432
|
return { command: 'runs_list', query, ...output };
|
|
408
433
|
}
|
|
434
|
+
if (positionals[0] === 'events') {
|
|
435
|
+
const runId = requireOne(positionals, 'dreamstate runs events <run_id>');
|
|
436
|
+
const query = {};
|
|
437
|
+
if (values.limit !== undefined)
|
|
438
|
+
query.limit = runsListLimit(values.limit);
|
|
439
|
+
if (values.cursor !== undefined) {
|
|
440
|
+
const cursor = values.cursor.trim();
|
|
441
|
+
if (!cursor)
|
|
442
|
+
throw new errors_1.CliUsageError('--cursor must be a non-empty string');
|
|
443
|
+
query.cursor = cursor;
|
|
444
|
+
}
|
|
445
|
+
return { command: 'runs_events', runId, ...(Object.keys(query).length ? { query } : {}), ...output };
|
|
446
|
+
}
|
|
409
447
|
if (values.limit !== undefined || values.cursor !== undefined) {
|
|
410
|
-
throw new errors_1.CliUsageError('--limit and --cursor are only valid on runs list');
|
|
448
|
+
throw new errors_1.CliUsageError('--limit and --cursor are only valid on runs list and runs events');
|
|
411
449
|
}
|
|
412
450
|
if (positionals[0] === 'resume') {
|
|
413
451
|
// The server retired generic run resume (verifyExecutionDoorCollapse.ts blocks the
|
|
414
452
|
// route), so there is nothing to call. Say where the replacement is.
|
|
415
453
|
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
454
|
}
|
|
417
|
-
const runId = requireOne(positionals, `dreamstate runs ${positionals[0] ?? '<get|events|cancel>'} <run_id>`);
|
|
418
|
-
if (positionals[0] === 'get')
|
|
455
|
+
const runId = requireOne(positionals, `dreamstate runs ${positionals[0] ?? '<get|status|wait|events|cancel>'} <run_id>`);
|
|
456
|
+
if (positionals[0] === 'get' || positionals[0] === 'status') {
|
|
457
|
+
if (values['wait-timeout'] !== undefined)
|
|
458
|
+
throw new errors_1.CliUsageError('--wait-timeout is only valid on runs wait');
|
|
419
459
|
return { command: 'runs_get', runId, ...output };
|
|
420
|
-
|
|
421
|
-
|
|
460
|
+
}
|
|
461
|
+
if (positionals[0] === 'wait') {
|
|
462
|
+
const waitTimeout = values['wait-timeout'] === undefined ? 120 : nonNegativeNumber(values['wait-timeout'], '--wait-timeout');
|
|
463
|
+
return { command: 'runs_wait', runId, waitTimeout, ...output };
|
|
464
|
+
}
|
|
465
|
+
if (values['wait-timeout'] !== undefined)
|
|
466
|
+
throw new errors_1.CliUsageError('--wait-timeout is only valid on runs wait');
|
|
422
467
|
if (positionals[0] === 'cancel') {
|
|
423
468
|
const idempotency = values['idempotency-key'] ? { idempotencyKey: values['idempotency-key'] } : {};
|
|
424
469
|
if (values.json && (values['state-version'] !== undefined || values.reason)) {
|
|
@@ -435,7 +480,7 @@ function parseRuns(argv) {
|
|
|
435
480
|
...output,
|
|
436
481
|
};
|
|
437
482
|
}
|
|
438
|
-
throw new errors_1.CliUsageError('Usage: dreamstate runs <list|get|events|cancel> <run_id>');
|
|
483
|
+
throw new errors_1.CliUsageError('Usage: dreamstate runs <list|get|status|wait|events|cancel> <run_id>');
|
|
439
484
|
}
|
|
440
485
|
function sequencesCommands() {
|
|
441
486
|
return require('./commands/sequences');
|
|
@@ -512,6 +557,14 @@ function parseCliArgs(argv) {
|
|
|
512
557
|
return { command: 'whoami', ...outputOption(values) };
|
|
513
558
|
throw new errors_1.CliUsageError('Usage: dreamstate whoami [--json-output]');
|
|
514
559
|
}
|
|
560
|
+
if (group === 'credits') {
|
|
561
|
+
const { values, positionals } = (0, node_util_1.parseArgs)({ args: rest, options: { 'json-output': { type: 'boolean' }, help: { type: 'boolean', short: 'h' } }, allowPositionals: true, strict: true });
|
|
562
|
+
if (values.help)
|
|
563
|
+
return { command: 'help' };
|
|
564
|
+
if (positionals.length)
|
|
565
|
+
throw new errors_1.CliUsageError('Usage: dreamstate credits [--json-output]');
|
|
566
|
+
return parseTools(['run', 'workspace.usage.status_get', '--params', '{}', ...rest]);
|
|
567
|
+
}
|
|
515
568
|
if (group === 'workspaces') {
|
|
516
569
|
const { values, positionals } = (0, node_util_1.parseArgs)({ args: rest, options: { 'json-output': { type: 'boolean' }, help: { type: 'boolean', short: 'h' } }, allowPositionals: true, strict: true });
|
|
517
570
|
if (values.help)
|
|
@@ -549,11 +602,9 @@ function parseCliArgs(argv) {
|
|
|
549
602
|
throw new errors_1.CliUsageError(`Unknown command: ${group}`);
|
|
550
603
|
}
|
|
551
604
|
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`);
|
|
605
|
+
// tool_turn_token stays: it is a short-lived fetch fence, not a credential.
|
|
606
|
+
// Provider USD does not. Customer maps (values, cells, params, ...) are left whole.
|
|
607
|
+
stdout.write(`${JSON.stringify((0, money_1.scrubCliOutput)(value), null, compact ? 0 : 2)}\n`);
|
|
557
608
|
}
|
|
558
609
|
function printPackRoute(value, stdout) {
|
|
559
610
|
const data = value && typeof value === 'object' && !Array.isArray(value)
|
|
@@ -579,7 +630,7 @@ function printPackRoute(value, stdout) {
|
|
|
579
630
|
continue;
|
|
580
631
|
const { pack_id: packId, reason } = alternate;
|
|
581
632
|
if (typeof packId === 'string')
|
|
582
|
-
stdout.write(`${packId}${typeof reason === 'string' ? `: ${reason}` : ''}\n`);
|
|
633
|
+
stdout.write(`${(0, money_1.scrubDollarText)(packId)}${typeof reason === 'string' ? `: ${(0, money_1.scrubDollarText)(reason)}` : ''}\n`);
|
|
583
634
|
}
|
|
584
635
|
}
|
|
585
636
|
/**
|
|
@@ -600,6 +651,7 @@ function refusalEnvelope(error, exitCode) {
|
|
|
600
651
|
// The client keeps the server's retry decision and repair; dropping them
|
|
601
652
|
// here left CLI automation without the recovery Architect and MCP get.
|
|
602
653
|
...(cliError?.repair === undefined ? {} : { repair: cliError.repair }),
|
|
654
|
+
...(!cliError ? { repair: { kind: 'fix_input', hint: error instanceof config_1.MissingApiKeyError ? 'Run dreamstate login, then retry.' : 'Run dreamstate --help, correct the input or connection settings, then retry.' } } : {}),
|
|
603
655
|
...(cliError?.details === undefined ? {} : { details: cliError.details }),
|
|
604
656
|
},
|
|
605
657
|
meta: {
|
|
@@ -782,7 +834,7 @@ async function readLoginKey(command, runtime) {
|
|
|
782
834
|
}
|
|
783
835
|
if (runtime.promptHidden)
|
|
784
836
|
return runtime.promptHidden('API key (input hidden): ');
|
|
785
|
-
throw new errors_1.CliUsageError('No API key provided.
|
|
837
|
+
throw new errors_1.CliUsageError('No API key provided. Run dreamstate login, pipe a key on stdin, or pass --api-key-file.');
|
|
786
838
|
}
|
|
787
839
|
function deviceState() {
|
|
788
840
|
return (0, node_crypto_1.randomBytes)(32).toString('base64url');
|
|
@@ -821,6 +873,23 @@ function whoamiData(value) {
|
|
|
821
873
|
const data = value && typeof value === 'object' ? value.data : undefined;
|
|
822
874
|
return data && typeof data === 'object' ? data : {};
|
|
823
875
|
}
|
|
876
|
+
const WORKSPACE_MISMATCH_MESSAGE = 'The server acted in a different workspace than the one you approved.';
|
|
877
|
+
/** Canonical workspace id the whoami request actually acted in, or a refusal. */
|
|
878
|
+
function workspacePinFromWhoami(whoami, requested) {
|
|
879
|
+
const data = whoamiData(whoami);
|
|
880
|
+
const acted = typeof data.workspace_id === 'string' ? data.workspace_id : '';
|
|
881
|
+
const wanted = requested.trim().toLowerCase();
|
|
882
|
+
const rows = data.workspaces ?? [];
|
|
883
|
+
const match = rows.find((row) => row.id.toLowerCase() === wanted || row.slug?.toLowerCase() === wanted);
|
|
884
|
+
if (match) {
|
|
885
|
+
if (acted !== match.id)
|
|
886
|
+
throw new client_1.CliError(WORKSPACE_MISMATCH_MESSAGE, 'workspace_mismatch', 400);
|
|
887
|
+
return match.id;
|
|
888
|
+
}
|
|
889
|
+
if (rows.length === 0 && acted.toLowerCase() === wanted)
|
|
890
|
+
return acted;
|
|
891
|
+
throw new client_1.CliError(WORKSPACE_MISMATCH_MESSAGE, 'workspace_mismatch', 400);
|
|
892
|
+
}
|
|
824
893
|
/**
|
|
825
894
|
* What `dreamstate status` reports. The release identity comes from the server's
|
|
826
895
|
* own answers (envelope meta and X-Dreamstate-* headers on every response), so
|
|
@@ -922,17 +991,21 @@ async function loginWithDeviceAuthorization(runtime, stdout, stderr, profile, no
|
|
|
922
991
|
for (;;) {
|
|
923
992
|
const claim = await (0, client_1.claimDeviceAuthorization)(baseUrl, authorization.device_code);
|
|
924
993
|
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
994
|
const client = new client_1.DreamstateClient({
|
|
930
995
|
baseUrl,
|
|
931
996
|
apiKey: claim.token,
|
|
997
|
+
workspace: claim.workspace.id,
|
|
932
998
|
requestTimeoutMs: runtime.requestTimeoutMs,
|
|
933
999
|
onVersionWarning: (message) => (runtime.stderr ?? process.stderr).write(`${message}\n`),
|
|
934
1000
|
});
|
|
935
1001
|
const whoami = await client.getWhoami();
|
|
1002
|
+
if (whoamiData(whoami).workspace_id !== claim.workspace.id) {
|
|
1003
|
+
throw new client_1.CliError(WORKSPACE_MISMATCH_MESSAGE, 'workspace_mismatch', 400);
|
|
1004
|
+
}
|
|
1005
|
+
if (profile)
|
|
1006
|
+
await (0, config_1.storeCredentialProfile)(profile, claim.token, runtimeCredentialsPath(runtime), claim.workspace.id);
|
|
1007
|
+
else
|
|
1008
|
+
await (0, config_1.storeApiKey)(claim.token, runtimeCredentialsPath(runtime), claim.workspace.id);
|
|
936
1009
|
const skills = await installLoginSkills(client, runtime, noSkills, stderr);
|
|
937
1010
|
print(loginResult(whoami, skills), stdout, jsonOutput);
|
|
938
1011
|
return;
|
|
@@ -1051,10 +1124,11 @@ async function runCli(argv = process.argv.slice(2), runtime = {}) {
|
|
|
1051
1124
|
onVersionWarning: (message) => stderr.write(`${message}\n`),
|
|
1052
1125
|
});
|
|
1053
1126
|
const whoami = await client.getWhoami();
|
|
1127
|
+
const pinned = requested ? workspacePinFromWhoami(whoami, requested) : null;
|
|
1054
1128
|
if (command.profile)
|
|
1055
|
-
await (0, config_1.storeCredentialProfile)(command.profile, token, runtimeCredentialsPath(runtime));
|
|
1129
|
+
await (0, config_1.storeCredentialProfile)(command.profile, token, runtimeCredentialsPath(runtime), pinned);
|
|
1056
1130
|
else
|
|
1057
|
-
await (0, config_1.storeApiKey)(token, runtimeCredentialsPath(runtime));
|
|
1131
|
+
await (0, config_1.storeApiKey)(token, runtimeCredentialsPath(runtime), pinned);
|
|
1058
1132
|
const skills = await installLoginSkills(client, runtime, Boolean(command.noSkills), stderr);
|
|
1059
1133
|
print(loginResult(whoami, skills), stdout, Boolean(command.jsonOutput));
|
|
1060
1134
|
process.exitCode = errors_1.CLI_EXIT.SUCCESS;
|
|
@@ -1096,10 +1170,19 @@ async function runCli(argv = process.argv.slice(2), runtime = {}) {
|
|
|
1096
1170
|
const key = await readLoginKey(command, runtime);
|
|
1097
1171
|
if (!(0, config_1.isDreamstateToken)(key))
|
|
1098
1172
|
throw new errors_1.CliUsageError('Dreamstate API keys must start with ds_user_ or ds_live_.');
|
|
1173
|
+
const environment = runtime.env ?? process.env;
|
|
1174
|
+
const requested = extracted.workspace ?? environment.DREAMSTATE_WORKSPACE?.trim();
|
|
1175
|
+
const client = new client_1.DreamstateClient({
|
|
1176
|
+
baseUrl: (0, config_1.resolveApiBaseUrl)(environment),
|
|
1177
|
+
apiKey: key,
|
|
1178
|
+
...(requested ? { workspace: requested } : {}),
|
|
1179
|
+
requestTimeoutMs: runtime.requestTimeoutMs,
|
|
1180
|
+
onVersionWarning: (message) => stderr.write(`${message}\n`),
|
|
1181
|
+
});
|
|
1182
|
+
const pinned = requested ? workspacePinFromWhoami(await client.getWhoami(), requested) : null;
|
|
1099
1183
|
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`) });
|
|
1184
|
+
? await (0, config_1.storeCredentialProfile)(command.profile, key, runtimeCredentialsPath(runtime), pinned)
|
|
1185
|
+
: await (0, config_1.storeApiKey)(key, runtimeCredentialsPath(runtime), pinned);
|
|
1103
1186
|
const skills = await installLoginSkills(client, runtime, Boolean(command.noSkills), stderr);
|
|
1104
1187
|
print({ ok: true, data: { credentials_path: path, skills }, meta: {} }, stdout, Boolean(command.jsonOutput));
|
|
1105
1188
|
process.exitCode = errors_1.CLI_EXIT.SUCCESS;
|
|
@@ -1362,8 +1445,19 @@ async function runCli(argv = process.argv.slice(2), runtime = {}) {
|
|
|
1362
1445
|
case 'runs_get':
|
|
1363
1446
|
result = await client.getRun(command.runId);
|
|
1364
1447
|
break;
|
|
1448
|
+
case 'runs_wait': {
|
|
1449
|
+
const initial = await client.getRun(command.runId);
|
|
1450
|
+
const waited = await (0, runWait_1.waitForRun)(client, initial, command.waitTimeout, runtime.sleep ?? wait);
|
|
1451
|
+
const blocked = (0, gatedRun_1.refusalFromRunResult)(waited.value);
|
|
1452
|
+
if (blocked)
|
|
1453
|
+
throw blocked;
|
|
1454
|
+
result = waited.value;
|
|
1455
|
+
if (waited.timedOut)
|
|
1456
|
+
process.exitCode = runWait_1.RUN_WAIT_TIMEOUT_EXIT_CODE;
|
|
1457
|
+
break;
|
|
1458
|
+
}
|
|
1365
1459
|
case 'runs_events':
|
|
1366
|
-
result = await client.getRunEvents(command.runId);
|
|
1460
|
+
result = await client.getRunEvents(command.runId, command.query ?? {});
|
|
1367
1461
|
break;
|
|
1368
1462
|
case 'runs_cancel': {
|
|
1369
1463
|
const body = command.body ?? {
|
|
@@ -1407,7 +1501,7 @@ async function runCli(argv = process.argv.slice(2), runtime = {}) {
|
|
|
1407
1501
|
}
|
|
1408
1502
|
catch (error) {
|
|
1409
1503
|
const exitCode = exitCodeForError(error);
|
|
1410
|
-
stdout.write(`${JSON.stringify(refusalEnvelope(error, exitCode))}\n`);
|
|
1504
|
+
stdout.write(`${JSON.stringify((0, money_1.scrubCliOutput)(refusalEnvelope(error, exitCode)))}\n`);
|
|
1411
1505
|
process.exitCode = exitCode;
|
|
1412
1506
|
throw error;
|
|
1413
1507
|
}
|
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"}
|