@crewx/cli 0.9.0-rc.94 → 0.9.0-rc.96
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/bootstrap/crewx-cli.js +5 -1
- package/dist/commands/cal.d.ts +15 -0
- package/dist/commands/cal.js +44 -0
- package/dist/commands/db.d.ts +1 -0
- package/dist/commands/db.js +191 -1
- package/dist/commands/detached.d.ts +65 -0
- package/dist/commands/detached.js +507 -0
- package/dist/commands/execute.d.ts +4 -6
- package/dist/commands/execute.js +46 -96
- package/dist/commands/kill.d.ts +2 -8
- package/dist/commands/kill.js +6 -47
- package/dist/commands/ps.d.ts +2 -2
- package/dist/commands/ps.js +18 -9
- package/dist/commands/query.d.ts +2 -0
- package/dist/commands/query.js +39 -7
- package/dist/commands/registry.js +1 -1
- package/dist/commands/result.d.ts +3 -2
- package/dist/commands/result.js +104 -7
- package/dist/commands/stop.d.ts +8 -0
- package/dist/commands/stop.js +119 -0
- package/dist/main.js +17 -9
- package/dist/utils/inherited-trace.d.ts +24 -0
- package/dist/utils/inherited-trace.js +40 -0
- package/package.json +14 -13
|
@@ -9,6 +9,7 @@ const plugins_1 = require("@crewx/sdk/plugins");
|
|
|
9
9
|
const repository_1 = require("@crewx/sdk/repository");
|
|
10
10
|
const register_builtin_tools_1 = require("../register-builtin-tools");
|
|
11
11
|
const version_1 = require("../utils/version");
|
|
12
|
+
const inherited_trace_1 = require("../utils/inherited-trace");
|
|
12
13
|
const codex_writable_roots_1 = require("./codex-writable-roots");
|
|
13
14
|
/**
|
|
14
15
|
* Build a Crewx instance with CLI-standard plugins (FileLogger + SqliteTracing)
|
|
@@ -59,6 +60,9 @@ async function createCliCrewx(configPath = process.env.CREWX_CONFIG ?? 'crewx.ya
|
|
|
59
60
|
(0, register_builtin_tools_1.registerBuiltinToolsIfNeeded)(crewx);
|
|
60
61
|
await crewx.use(new plugins_1.ConversationPlugin());
|
|
61
62
|
await crewx.use(new plugins_1.FileLoggerPlugin({ version: version_1.CLI_VERSION, workspaceRoot }));
|
|
62
|
-
await crewx.use(new plugins_1.SqliteTracingPlugin({
|
|
63
|
+
await crewx.use(new plugins_1.SqliteTracingPlugin({
|
|
64
|
+
version: version_1.CLI_VERSION,
|
|
65
|
+
runnerIdentity: (0, inherited_trace_1.consumeInheritedRunnerIdentity)(),
|
|
66
|
+
}));
|
|
63
67
|
return crewx;
|
|
64
68
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ActionContext } from '@crewx/knowledge-core';
|
|
2
|
+
/** Suggested wait rungs in seconds. 540 is the safe caller-harness cap. */
|
|
3
|
+
export declare const WAIT_LADDER_SECONDS: readonly [60, 300, 540];
|
|
4
|
+
export interface SuggestWaitSecondsOptions {
|
|
5
|
+
startedAt?: string | number | Date | null;
|
|
6
|
+
lastWaitSeconds?: number;
|
|
7
|
+
now?: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Select the next safe result wait based on task runtime without stepping
|
|
11
|
+
* down from the wait value the caller just used.
|
|
12
|
+
*/
|
|
13
|
+
export declare function suggestWaitSeconds(options: SuggestWaitSecondsOptions): number;
|
|
14
|
+
/** Write a human-only CAL footer without contaminating command stdout. */
|
|
15
|
+
export declare function writeCalFooter(context: ActionContext): void;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.WAIT_LADDER_SECONDS = void 0;
|
|
4
|
+
exports.suggestWaitSeconds = suggestWaitSeconds;
|
|
5
|
+
exports.writeCalFooter = writeCalFooter;
|
|
6
|
+
const knowledge_core_1 = require("@crewx/knowledge-core");
|
|
7
|
+
/** Suggested wait rungs in seconds. 540 is the safe caller-harness cap. */
|
|
8
|
+
exports.WAIT_LADDER_SECONDS = [60, 300, 540];
|
|
9
|
+
function toTimestamp(value) {
|
|
10
|
+
if (value instanceof Date) {
|
|
11
|
+
return Number.isFinite(value.getTime()) ? value.getTime() : undefined;
|
|
12
|
+
}
|
|
13
|
+
if (typeof value === 'number') {
|
|
14
|
+
return Number.isFinite(value) ? value : undefined;
|
|
15
|
+
}
|
|
16
|
+
if (typeof value === 'string') {
|
|
17
|
+
const timestamp = Date.parse(value);
|
|
18
|
+
return Number.isFinite(timestamp) ? timestamp : undefined;
|
|
19
|
+
}
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Select the next safe result wait based on task runtime without stepping
|
|
24
|
+
* down from the wait value the caller just used.
|
|
25
|
+
*/
|
|
26
|
+
function suggestWaitSeconds(options) {
|
|
27
|
+
const now = Number.isFinite(options.now) ? options.now : Date.now();
|
|
28
|
+
const startedAt = toTimestamp(options.startedAt);
|
|
29
|
+
const elapsedSeconds = startedAt === undefined
|
|
30
|
+
? 0
|
|
31
|
+
: Math.max(0, (now - startedAt) / 1000);
|
|
32
|
+
const rung = exports.WAIT_LADDER_SECONDS.find(seconds => seconds > elapsedSeconds)
|
|
33
|
+
?? exports.WAIT_LADDER_SECONDS[exports.WAIT_LADDER_SECONDS.length - 1];
|
|
34
|
+
const lastWaitSeconds = Number.isFinite(options.lastWaitSeconds)
|
|
35
|
+
? Math.max(0, options.lastWaitSeconds)
|
|
36
|
+
: 0;
|
|
37
|
+
return Math.min(exports.WAIT_LADDER_SECONDS[exports.WAIT_LADDER_SECONDS.length - 1], Math.max(rung, lastWaitSeconds));
|
|
38
|
+
}
|
|
39
|
+
/** Write a human-only CAL footer without contaminating command stdout. */
|
|
40
|
+
function writeCalFooter(context) {
|
|
41
|
+
const block = (0, knowledge_core_1.formatActions)((0, knowledge_core_1.generateNextActions)(context));
|
|
42
|
+
if (block)
|
|
43
|
+
process.stderr.write(`${block}\n`);
|
|
44
|
+
}
|
package/dist/commands/db.d.ts
CHANGED
|
@@ -7,4 +7,5 @@
|
|
|
7
7
|
* crewx db push --dry-run Show preview only, no changes
|
|
8
8
|
*/
|
|
9
9
|
export declare const TASK_LOG_MIGRATION_HELP = "Usage:\n crewx db migrate-task-logs --dry-run [--db PATH]\n crewx db migrate-task-logs --apply [--db PATH] [--batch-tasks N]\n crewx db migrate-task-logs --verify [--db PATH]\n\nModes:\n --dry-run Read and validate legacy blobs without writing or creating a backup.\n --apply Create a consistent SQLite backup, then migrate one task per transaction.\n --verify Check source invariants, event sequences, counts, and orphan rows.\n\nApply policy:\n Only blob tasks with status success, failed, or completed are migrated.\n pending, running, paused, and unknown statuses are deferred for a later run.\n There is no --force or --include-active option. Apply requires the estimated\n database/event growth plus a 10 GiB free-space reserve.\n\nExit codes:\n 0 Completed with no malformed rows or invariant failures.\n 1 Safe tasks completed but a row/invariant failed, or apply was blocked.\n 2 Invalid command-line arguments.\n\nThe command never runs automatically at server startup and never runs VACUUM.";
|
|
10
|
+
export declare const USAGE_BACKFILL_HELP = "Usage:\n crewx db backfill-usage [--dry-run|--apply|--verify] [--db PATH] [--backup PATH]\n crewx db backfill-usage --restore SNAPSHOT [--db PATH]\n\nModes:\n --dry-run Show provider/reason recovery plans without changing the database (default).\n --apply Create a row-level undo snapshot, then account one task per transaction.\n --verify Recheck remaining targets and usageAccounting markers without changing the database.\n --restore Restore rows from SNAPSHOT when their current values still match the snapshot after-state.\n\nApply policy:\n Only success, failed, and completed tasks with zero recorded usage are considered.\n Workflow/MCP anchors and plugin/mock rows are excluded. Rows completed within 24 hours\n are not marked unavailable when their logs do not contain usage.\n\nExit codes:\n 0 Completed successfully.\n 1 Apply was blocked or one or more task updates failed.\n 2 Invalid command-line arguments.";
|
|
10
11
|
export declare function handleDb(args: string[]): Promise<void>;
|
package/dist/commands/db.js
CHANGED
|
@@ -11,7 +11,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
11
11
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
12
12
|
};
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.TASK_LOG_MIGRATION_HELP = void 0;
|
|
14
|
+
exports.USAGE_BACKFILL_HELP = exports.TASK_LOG_MIGRATION_HELP = void 0;
|
|
15
15
|
exports.handleDb = handleDb;
|
|
16
16
|
const path_1 = __importDefault(require("path"));
|
|
17
17
|
const os_1 = __importDefault(require("os"));
|
|
@@ -19,6 +19,7 @@ const readline_1 = __importDefault(require("readline"));
|
|
|
19
19
|
const repository_1 = require("@crewx/sdk/repository");
|
|
20
20
|
const repository_2 = require("@crewx/sdk/repository");
|
|
21
21
|
const repository_3 = require("@crewx/sdk/repository");
|
|
22
|
+
const repository_4 = require("@crewx/sdk/repository");
|
|
22
23
|
exports.TASK_LOG_MIGRATION_HELP = `Usage:
|
|
23
24
|
crewx db migrate-task-logs --dry-run [--db PATH]
|
|
24
25
|
crewx db migrate-task-logs --apply [--db PATH] [--batch-tasks N]
|
|
@@ -41,6 +42,25 @@ Exit codes:
|
|
|
41
42
|
2 Invalid command-line arguments.
|
|
42
43
|
|
|
43
44
|
The command never runs automatically at server startup and never runs VACUUM.`;
|
|
45
|
+
exports.USAGE_BACKFILL_HELP = `Usage:
|
|
46
|
+
crewx db backfill-usage [--dry-run|--apply|--verify] [--db PATH] [--backup PATH]
|
|
47
|
+
crewx db backfill-usage --restore SNAPSHOT [--db PATH]
|
|
48
|
+
|
|
49
|
+
Modes:
|
|
50
|
+
--dry-run Show provider/reason recovery plans without changing the database (default).
|
|
51
|
+
--apply Create a row-level undo snapshot, then account one task per transaction.
|
|
52
|
+
--verify Recheck remaining targets and usageAccounting markers without changing the database.
|
|
53
|
+
--restore Restore rows from SNAPSHOT when their current values still match the snapshot after-state.
|
|
54
|
+
|
|
55
|
+
Apply policy:
|
|
56
|
+
Only success, failed, and completed tasks with zero recorded usage are considered.
|
|
57
|
+
Workflow/MCP anchors and plugin/mock rows are excluded. Rows completed within 24 hours
|
|
58
|
+
are not marked unavailable when their logs do not contain usage.
|
|
59
|
+
|
|
60
|
+
Exit codes:
|
|
61
|
+
0 Completed successfully.
|
|
62
|
+
1 Apply was blocked or one or more task updates failed.
|
|
63
|
+
2 Invalid command-line arguments.`;
|
|
44
64
|
function defaultDbPath() {
|
|
45
65
|
return path_1.default.join(os_1.default.homedir(), '.crewx', 'crewx.db');
|
|
46
66
|
}
|
|
@@ -102,6 +122,10 @@ async function handleDb(args) {
|
|
|
102
122
|
await handleTaskLogMigration(args.slice(1));
|
|
103
123
|
return;
|
|
104
124
|
}
|
|
125
|
+
if (subcommand === 'backfill-usage') {
|
|
126
|
+
await handleUsageBackfill(args.slice(1));
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
105
129
|
if (subcommand === '--help' || subcommand === '-h') {
|
|
106
130
|
console.log('Usage: crewx db push [--force] [--dry-run]');
|
|
107
131
|
console.log(exports.TASK_LOG_MIGRATION_HELP);
|
|
@@ -118,6 +142,8 @@ async function handleDb(args) {
|
|
|
118
142
|
}
|
|
119
143
|
class TaskLogMigrationUsageError extends Error {
|
|
120
144
|
}
|
|
145
|
+
class UsageBackfillUsageError extends Error {
|
|
146
|
+
}
|
|
121
147
|
function parseTaskLogMigrationArgs(args) {
|
|
122
148
|
let mode;
|
|
123
149
|
let dbPath;
|
|
@@ -266,6 +292,170 @@ async function handleTaskLogMigration(args) {
|
|
|
266
292
|
process.exitCode = 1;
|
|
267
293
|
}
|
|
268
294
|
}
|
|
295
|
+
function parseUsageBackfillArgs(args) {
|
|
296
|
+
let mode;
|
|
297
|
+
let dbPath;
|
|
298
|
+
let backupPath;
|
|
299
|
+
let restorePath;
|
|
300
|
+
const setMode = (next) => {
|
|
301
|
+
if (mode)
|
|
302
|
+
throw new UsageBackfillUsageError('Choose exactly one of --dry-run, --apply, --verify, or --restore.');
|
|
303
|
+
mode = next;
|
|
304
|
+
};
|
|
305
|
+
const requireValue = (index, flag) => {
|
|
306
|
+
const value = args[index + 1];
|
|
307
|
+
if (!value || value.startsWith('--'))
|
|
308
|
+
throw new UsageBackfillUsageError(`${flag} requires a value.`);
|
|
309
|
+
return value;
|
|
310
|
+
};
|
|
311
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
312
|
+
const arg = args[index];
|
|
313
|
+
if (arg === '--help' || arg === '-h')
|
|
314
|
+
throw new UsageBackfillUsageError(exports.USAGE_BACKFILL_HELP);
|
|
315
|
+
if (arg === '--dry-run') {
|
|
316
|
+
setMode('dry-run');
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
319
|
+
if (arg === '--apply') {
|
|
320
|
+
setMode('apply');
|
|
321
|
+
continue;
|
|
322
|
+
}
|
|
323
|
+
if (arg === '--verify') {
|
|
324
|
+
setMode('verify');
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
if (arg === '--restore') {
|
|
328
|
+
setMode('restore');
|
|
329
|
+
restorePath = requireValue(index, '--restore');
|
|
330
|
+
index += 1;
|
|
331
|
+
continue;
|
|
332
|
+
}
|
|
333
|
+
if (arg.startsWith('--restore=')) {
|
|
334
|
+
setMode('restore');
|
|
335
|
+
restorePath = arg.slice('--restore='.length);
|
|
336
|
+
if (!restorePath)
|
|
337
|
+
throw new UsageBackfillUsageError('--restore requires a value.');
|
|
338
|
+
continue;
|
|
339
|
+
}
|
|
340
|
+
if (arg === '--db') {
|
|
341
|
+
dbPath = requireValue(index, '--db');
|
|
342
|
+
index += 1;
|
|
343
|
+
continue;
|
|
344
|
+
}
|
|
345
|
+
if (arg.startsWith('--db=')) {
|
|
346
|
+
dbPath = arg.slice('--db='.length);
|
|
347
|
+
if (!dbPath)
|
|
348
|
+
throw new UsageBackfillUsageError('--db requires a value.');
|
|
349
|
+
continue;
|
|
350
|
+
}
|
|
351
|
+
if (arg === '--backup') {
|
|
352
|
+
backupPath = requireValue(index, '--backup');
|
|
353
|
+
index += 1;
|
|
354
|
+
continue;
|
|
355
|
+
}
|
|
356
|
+
if (arg.startsWith('--backup=')) {
|
|
357
|
+
backupPath = arg.slice('--backup='.length);
|
|
358
|
+
if (!backupPath)
|
|
359
|
+
throw new UsageBackfillUsageError('--backup requires a value.');
|
|
360
|
+
continue;
|
|
361
|
+
}
|
|
362
|
+
throw new UsageBackfillUsageError(`Unknown option: ${arg}`);
|
|
363
|
+
}
|
|
364
|
+
const selectedMode = mode ?? 'dry-run';
|
|
365
|
+
if (backupPath && selectedMode !== 'apply') {
|
|
366
|
+
throw new UsageBackfillUsageError('--backup is only valid with --apply.');
|
|
367
|
+
}
|
|
368
|
+
if (restorePath && selectedMode !== 'restore') {
|
|
369
|
+
throw new UsageBackfillUsageError('--restore is only valid with restore mode.');
|
|
370
|
+
}
|
|
371
|
+
return { mode: selectedMode, dbPath, backupPath, restorePath };
|
|
372
|
+
}
|
|
373
|
+
function formatUsageBackfillReport(report) {
|
|
374
|
+
const modeLabel = report.mode === 'dry-run'
|
|
375
|
+
? 'Dry-run'
|
|
376
|
+
: report.mode === 'apply'
|
|
377
|
+
? 'Apply'
|
|
378
|
+
: report.mode === 'restore'
|
|
379
|
+
? 'Restore'
|
|
380
|
+
: 'Verify';
|
|
381
|
+
const lines = [
|
|
382
|
+
`[crewx] Usage backfill — ${modeLabel}`,
|
|
383
|
+
` Database: ${report.dbPath}`,
|
|
384
|
+
` Tasks scanned: ${report.scannedTasks}`,
|
|
385
|
+
` Terminal tasks: ${report.terminalTasks}`,
|
|
386
|
+
` Raw target tasks: ${report.rawTargetTasks}`,
|
|
387
|
+
` Candidate tasks: ${report.candidateTasks}`,
|
|
388
|
+
` Recovered: ${report.recoveredTasks}`,
|
|
389
|
+
` Unavailable: ${report.unavailableTasks}`,
|
|
390
|
+
` Deferred (within 24h): ${report.deferredTasks}`,
|
|
391
|
+
` Changed: ${report.changedTasks}`,
|
|
392
|
+
` Would change: ${report.wouldChangeTasks}`,
|
|
393
|
+
` Restored: ${report.restored}`,
|
|
394
|
+
` Skipped conflicts: ${report.skippedConflict}`,
|
|
395
|
+
` Remaining target tasks: ${report.remainingTargetTasks}`,
|
|
396
|
+
` Tasks with usageAccounting: ${report.accountingTasks}`,
|
|
397
|
+
' Provider distribution:',
|
|
398
|
+
];
|
|
399
|
+
const providers = Object.entries(report.providerDistribution);
|
|
400
|
+
if (providers.length === 0) {
|
|
401
|
+
lines.push(' (none)');
|
|
402
|
+
}
|
|
403
|
+
else {
|
|
404
|
+
for (const [provider, stats] of providers) {
|
|
405
|
+
lines.push(` ${provider}: candidates=${stats.candidates}, recovered=${stats.recovered}, unavailable=${stats.unavailable}, deferred=${stats.deferred}`);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
lines.push(' Reason counts:');
|
|
409
|
+
for (const [reason, count] of Object.entries(report.reasonCounts))
|
|
410
|
+
lines.push(` ${reason}: ${count}`);
|
|
411
|
+
lines.push(` Estimated free-space need: ${report.estimatedFreeSpaceBytes}`);
|
|
412
|
+
lines.push(` Required free space (with reserve): ${report.requiredFreeSpaceBytes}`);
|
|
413
|
+
lines.push(` Available free space: ${report.availableFreeSpaceBytes}`);
|
|
414
|
+
lines.push(` Free-space gate: ${report.freeSpaceGatePassed ? 'PASS' : 'FAIL'}`);
|
|
415
|
+
const snapshotPath = report.snapshotPath ?? report.backupPath;
|
|
416
|
+
if (snapshotPath) {
|
|
417
|
+
lines.push(` Undo snapshot: ${snapshotPath}`);
|
|
418
|
+
if (report.backupMethod)
|
|
419
|
+
lines.push(` Snapshot method: ${report.backupMethod}`);
|
|
420
|
+
}
|
|
421
|
+
if (report.blockedReason)
|
|
422
|
+
lines.push(` Blocked: ${report.blockedReason}`);
|
|
423
|
+
for (const conflict of report.conflictSamples) {
|
|
424
|
+
lines.push(` Conflict sample: ${conflict.taskId}: ${conflict.fields.join(', ')}`);
|
|
425
|
+
}
|
|
426
|
+
for (const failure of report.failures)
|
|
427
|
+
lines.push(` Failure: ${failure.taskId}: ${failure.reason}`);
|
|
428
|
+
for (const warning of report.warnings)
|
|
429
|
+
lines.push(` Warning: ${warning}`);
|
|
430
|
+
return lines.join('\n');
|
|
431
|
+
}
|
|
432
|
+
async function handleUsageBackfill(args) {
|
|
433
|
+
let parsed;
|
|
434
|
+
try {
|
|
435
|
+
parsed = parseUsageBackfillArgs(args);
|
|
436
|
+
}
|
|
437
|
+
catch (error) {
|
|
438
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
439
|
+
if (message === exports.USAGE_BACKFILL_HELP) {
|
|
440
|
+
console.log(message);
|
|
441
|
+
}
|
|
442
|
+
else {
|
|
443
|
+
console.error(message);
|
|
444
|
+
console.error(exports.USAGE_BACKFILL_HELP);
|
|
445
|
+
process.exitCode = 2;
|
|
446
|
+
}
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
449
|
+
try {
|
|
450
|
+
const report = await (0, repository_4.runUsageBackfill)(parsed);
|
|
451
|
+
console.log(formatUsageBackfillReport(report));
|
|
452
|
+
process.exitCode = report.ok ? 0 : 1;
|
|
453
|
+
}
|
|
454
|
+
catch (error) {
|
|
455
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
456
|
+
process.exitCode = 1;
|
|
457
|
+
}
|
|
458
|
+
}
|
|
269
459
|
async function handleDbPush(args) {
|
|
270
460
|
const force = args.includes('--force');
|
|
271
461
|
const dryRun = args.includes('--dry-run');
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared receipt-mode implementation for the query and execute commands.
|
|
3
|
+
*
|
|
4
|
+
* A receipt is persisted before a detached runner is started. The runner gets
|
|
5
|
+
* its own identity variables, while the trace variables remain the caller's
|
|
6
|
+
* trace context and are never repurposed as the runner assignment.
|
|
7
|
+
*/
|
|
8
|
+
import { TaskRepository } from '@crewx/sdk/repository';
|
|
9
|
+
/**
|
|
10
|
+
* Remove receipt-selection flags, respecting the `--` literal-args sentinel.
|
|
11
|
+
*/
|
|
12
|
+
export declare function extractReceiptFlags(args: string[]): {
|
|
13
|
+
detach: boolean;
|
|
14
|
+
wait: boolean;
|
|
15
|
+
rest: string[];
|
|
16
|
+
};
|
|
17
|
+
export type ReceiptModeReason = 'explicit-detach' | 'agent-context' | 'detached-runner' | 'wait' | 'default';
|
|
18
|
+
export interface ReceiptModeDecision {
|
|
19
|
+
receipt: boolean;
|
|
20
|
+
reason: ReceiptModeReason;
|
|
21
|
+
}
|
|
22
|
+
/** Resolve the receipt/synchronous mode contract shared by q and x. */
|
|
23
|
+
export declare function resolveReceiptMode(options: {
|
|
24
|
+
detach: boolean;
|
|
25
|
+
wait: boolean;
|
|
26
|
+
detachedRunner: boolean;
|
|
27
|
+
agentContext: boolean;
|
|
28
|
+
}): ReceiptModeDecision;
|
|
29
|
+
export type AssignedTaskAdoption = {
|
|
30
|
+
kind: 'adopted';
|
|
31
|
+
taskId: string;
|
|
32
|
+
} | {
|
|
33
|
+
kind: 'stale';
|
|
34
|
+
} | {
|
|
35
|
+
kind: 'failed';
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Claim a pre-issued receipt without overwriting an already-owned row.
|
|
39
|
+
* Assignment-only leakage is recoverable: discard the stale id and let the
|
|
40
|
+
* normal SDK path create a fresh task. A real detached runner must fail loud
|
|
41
|
+
* because its receipt would otherwise point at no execution row.
|
|
42
|
+
*/
|
|
43
|
+
export declare function adoptAssignedTask(taskRepo: Pick<TaskRepository, 'adoptPendingTask'>, taskId: string, detachedRunner: boolean): AssignedTaskAdoption;
|
|
44
|
+
export interface DetachedMiddleHop {
|
|
45
|
+
taskId: string;
|
|
46
|
+
logPath: string;
|
|
47
|
+
runnerArgs: string[];
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Read the private Windows middle-hop contract. Invalid direct invocations
|
|
51
|
+
* are left untouched and therefore fail through the normal unknown-option
|
|
52
|
+
* path instead of becoming an undocumented public command.
|
|
53
|
+
*/
|
|
54
|
+
export declare function readDetachedMiddleHop(args: string[]): DetachedMiddleHop | undefined;
|
|
55
|
+
/**
|
|
56
|
+
* Windows middle hop: transfer a transient log handle to the final runner,
|
|
57
|
+
* close the middle process's copy, and exit immediately. The parent treats a
|
|
58
|
+
* successful middle-hop exit as normal and makes adoption a database decision.
|
|
59
|
+
*/
|
|
60
|
+
export declare function runDetachedMiddle(command: string, hop: DetachedMiddleHop): Promise<void>;
|
|
61
|
+
/**
|
|
62
|
+
* Persist a receipt and launch its detached runner. Unix uses one hop. Windows
|
|
63
|
+
* uses a short-lived middle hop so the final runner has no live parent link.
|
|
64
|
+
*/
|
|
65
|
+
export declare function runDetached(command: string, filteredArgs: string[], reason: ReceiptModeReason): Promise<void>;
|