@skrr-ai/cli 0.1.23 → 0.1.25
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/bin/run.js +54 -1
- package/dist/base-command.d.ts +4 -4
- package/dist/base-command.js +81 -6
- package/dist/commands/harnesses/leases/list.js +1 -1
- package/dist/commands/harnesses/products.js +1 -0
- package/dist/commands/machines/dedicated/create.d.ts +18 -0
- package/dist/commands/machines/dedicated/create.js +90 -0
- package/dist/commands/machines/dedicated/destroy.d.ts +14 -0
- package/dist/commands/machines/dedicated/destroy.js +56 -0
- package/dist/commands/machines/dedicated/grow.d.ts +13 -0
- package/dist/commands/machines/dedicated/grow.js +46 -0
- package/dist/commands/machines/dedicated/health-check.d.ts +12 -0
- package/dist/commands/machines/dedicated/health-check.js +42 -0
- package/dist/commands/machines/dedicated/incident-close.d.ts +12 -0
- package/dist/commands/machines/dedicated/incident-close.js +42 -0
- package/dist/commands/machines/dedicated/index.d.ts +6 -0
- package/dist/commands/machines/dedicated/index.js +39 -0
- package/dist/commands/machines/dedicated/list.d.ts +11 -0
- package/dist/commands/machines/dedicated/list.js +58 -0
- package/dist/commands/machines/dedicated/restart.d.ts +12 -0
- package/dist/commands/machines/dedicated/restart.js +42 -0
- package/dist/commands/machines/dedicated/show.d.ts +12 -0
- package/dist/commands/machines/dedicated/show.js +58 -0
- package/dist/commands/machines/dedicated/snapshot.d.ts +12 -0
- package/dist/commands/machines/dedicated/snapshot.js +42 -0
- package/dist/commands/machines/dedicated/start.d.ts +12 -0
- package/dist/commands/machines/dedicated/start.js +42 -0
- package/dist/commands/machines/dedicated/stop.d.ts +12 -0
- package/dist/commands/machines/dedicated/stop.js +42 -0
- package/dist/commands/machines/hosted/index.js +4 -1
- package/dist/commands/spaces/auto-executor/preview.d.ts +8 -0
- package/dist/commands/spaces/auto-executor/preview.js +41 -0
- package/dist/commands/spaces/task-rollups.d.ts +14 -0
- package/dist/commands/spaces/task-rollups.js +66 -0
- package/dist/commands/spaces/update.js +16 -12
- package/dist/commands/spaces/work-sync/reconcile.d.ts +38 -0
- package/dist/commands/spaces/work-sync/reconcile.js +90 -0
- package/dist/commands/spaces/work-sync/telemetry.d.ts +29 -0
- package/dist/commands/spaces/work-sync/telemetry.js +118 -0
- package/dist/commands/tasks/activity.js +5 -1
- package/dist/commands/tasks/assign.js +1 -1
- package/dist/commands/tasks/complete.d.ts +5 -1
- package/dist/commands/tasks/complete.js +17 -3
- package/dist/commands/tasks/create.d.ts +1 -0
- package/dist/commands/tasks/create.js +17 -4
- package/dist/commands/tasks/deliverable/add.js +22 -4
- package/dist/commands/tasks/deliverable/list.js +23 -2
- package/dist/commands/tasks/events/append.js +31 -3
- package/dist/commands/tasks/expectations/assess.d.ts +1 -1
- package/dist/commands/tasks/expectations/assess.js +33 -7
- package/dist/commands/tasks/expectations.js +110 -10
- package/dist/commands/tasks/output.d.ts +0 -1
- package/dist/commands/tasks/output.js +21 -1
- package/dist/commands/tasks/report.js +3 -1
- package/dist/commands/tasks/result/show.js +20 -2
- package/dist/commands/tasks/resume/save.js +11 -1
- package/dist/commands/tasks/self-schedule.js +7 -4
- package/dist/commands/tasks/show.js +19 -0
- package/dist/commands/tasks/timeline.js +9 -1
- package/dist/commands/tasks/updates/add.js +23 -2
- package/dist/lib/api-fetch.js +9 -1
- package/dist/lib/assignee-resolver.d.ts +7 -6
- package/dist/lib/daemonBroker.d.ts +20 -0
- package/dist/lib/daemonBroker.js +58 -17
- package/dist/lib/dedicated-machines.d.ts +66 -0
- package/dist/lib/dedicated-machines.js +161 -0
- package/dist/lib/harnesses.d.ts +5 -0
- package/dist/lib/harnesses.js +5 -2
- package/dist/lib/idempotency-scope.d.ts +10 -0
- package/dist/lib/idempotency-scope.js +16 -0
- package/dist/lib/node-adapter.d.ts +1 -1
- package/dist/lib/node-adapter.js +12 -10
- package/dist/lib/task-legacy.d.ts +24 -0
- package/dist/lib/task-legacy.js +48 -0
- package/dist/lib/tasks.d.ts +32 -0
- package/dist/lib/tasks.js +47 -1
- package/dist/lib/triggers.js +7 -0
- package/dist/lib/work-sync.d.ts +105 -0
- package/dist/lib/work-sync.js +29 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/kek/linux.js +71 -21
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/kek/linux.js +71 -21
- package/dist/node_modules/@skrr-ai/auth-core/package.json +1 -1
- package/dist/node_modules/@skrr-ai/data-provider/index.js +2141 -2061
- package/oclif.manifest.json +15661 -14585
- package/package.json +1 -1
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_command_1 = require("../../../base-command");
|
|
5
|
+
const format_1 = require("../../../lib/format");
|
|
6
|
+
const dedicated_machines_1 = require("../../../lib/dedicated-machines");
|
|
7
|
+
class DedicatedMachinesList extends base_command_1.BaseCommand {
|
|
8
|
+
static description = 'List Dedicated Runtime leases';
|
|
9
|
+
static examples = [
|
|
10
|
+
'<%= config.bin %> machines dedicated list',
|
|
11
|
+
'<%= config.bin %> machines dedicated list --json',
|
|
12
|
+
];
|
|
13
|
+
static flags = {
|
|
14
|
+
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
15
|
+
state: core_1.Flags.string({ description: 'Filter by lease state' }),
|
|
16
|
+
limit: core_1.Flags.integer({ description: 'Max leases to return', default: 50 }),
|
|
17
|
+
};
|
|
18
|
+
async run() {
|
|
19
|
+
this.requireAuth();
|
|
20
|
+
const { flags } = await this.parse(DedicatedMachinesList);
|
|
21
|
+
let response;
|
|
22
|
+
try {
|
|
23
|
+
response = await (0, dedicated_machines_1.listDedicatedRuntimes)({
|
|
24
|
+
limit: flags.limit,
|
|
25
|
+
state: flags.state,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
const message = (0, dedicated_machines_1.formatDedicatedRuntimeApiError)(err);
|
|
30
|
+
if (message)
|
|
31
|
+
this.error(message, { exit: 1 });
|
|
32
|
+
this.handleApiError(err);
|
|
33
|
+
}
|
|
34
|
+
if (flags.json) {
|
|
35
|
+
this.log(JSON.stringify(response, null, 2));
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const leases = response?.leases ?? [];
|
|
39
|
+
if (leases.length === 0) {
|
|
40
|
+
this.log('No Dedicated Runtime leases.');
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
(0, format_1.renderTable)(leases.map((lease) => ({
|
|
44
|
+
id: (0, format_1.formatCell)((0, dedicated_machines_1.dedicatedLeaseId)(lease)),
|
|
45
|
+
status: (0, format_1.formatCell)((0, dedicated_machines_1.dedicatedLeaseState)(lease)),
|
|
46
|
+
name: (0, format_1.formatCell)((0, dedicated_machines_1.dedicatedLeaseDisplayName)(lease)),
|
|
47
|
+
retention: (0, format_1.formatCell)(lease.storage?.retentionClass || '-'),
|
|
48
|
+
backup: (0, format_1.formatCell)(lease.storage?.lastBackupAt || '-'),
|
|
49
|
+
})), [
|
|
50
|
+
{ key: 'id', header: 'ID' },
|
|
51
|
+
{ key: 'status', header: 'STATUS' },
|
|
52
|
+
{ key: 'name', header: 'NAME', maxWidth: 28 },
|
|
53
|
+
{ key: 'retention', header: 'RETENTION', maxWidth: 14 },
|
|
54
|
+
{ key: 'backup', header: 'LAST BACKUP', maxWidth: 24 },
|
|
55
|
+
], (line) => this.log(line));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
exports.default = DedicatedMachinesList;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base-command';
|
|
2
|
+
export default class DedicatedMachinesRestart extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
lease: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
};
|
|
11
|
+
run(): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_command_1 = require("../../../base-command");
|
|
5
|
+
const dedicated_machines_1 = require("../../../lib/dedicated-machines");
|
|
6
|
+
class DedicatedMachinesRestart extends base_command_1.BaseCommand {
|
|
7
|
+
static description = 'Restart a Dedicated Runtime lease';
|
|
8
|
+
static examples = [
|
|
9
|
+
'<%= config.bin %> machines dedicated restart <lease-id>',
|
|
10
|
+
'<%= config.bin %> machines dedicated restart <lease-id> --json',
|
|
11
|
+
];
|
|
12
|
+
static args = {
|
|
13
|
+
lease: core_1.Args.string({
|
|
14
|
+
description: 'Dedicated Runtime lease id',
|
|
15
|
+
required: true,
|
|
16
|
+
ignoreStdin: true,
|
|
17
|
+
}),
|
|
18
|
+
};
|
|
19
|
+
static flags = {
|
|
20
|
+
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
21
|
+
};
|
|
22
|
+
async run() {
|
|
23
|
+
this.requireAuth();
|
|
24
|
+
const { args, flags } = await this.parse(DedicatedMachinesRestart);
|
|
25
|
+
let response;
|
|
26
|
+
try {
|
|
27
|
+
response = await (0, dedicated_machines_1.performDedicatedLeaseAction)(args.lease, 'restart');
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
const message = (0, dedicated_machines_1.formatDedicatedRuntimeApiError)(err);
|
|
31
|
+
if (message)
|
|
32
|
+
this.error(message, { exit: 1 });
|
|
33
|
+
this.handleApiError(err);
|
|
34
|
+
}
|
|
35
|
+
if (flags.json) {
|
|
36
|
+
this.log(JSON.stringify(response, null, 2));
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
this.log(`Dedicated Runtime ${(0, dedicated_machines_1.dedicatedLeaseId)(response?.lease)} ${(0, dedicated_machines_1.dedicatedLeaseState)(response?.lease)}.`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.default = DedicatedMachinesRestart;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base-command';
|
|
2
|
+
export default class DedicatedMachinesShow extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
lease: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
};
|
|
11
|
+
run(): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_command_1 = require("../../../base-command");
|
|
5
|
+
const dedicated_machines_1 = require("../../../lib/dedicated-machines");
|
|
6
|
+
class DedicatedMachinesShow extends base_command_1.BaseCommand {
|
|
7
|
+
static description = 'Show one Dedicated Runtime lease';
|
|
8
|
+
static examples = [
|
|
9
|
+
'<%= config.bin %> machines dedicated show <lease-id>',
|
|
10
|
+
'<%= config.bin %> machines dedicated show <lease-id> --json',
|
|
11
|
+
];
|
|
12
|
+
static args = {
|
|
13
|
+
lease: core_1.Args.string({
|
|
14
|
+
ignoreStdin: true,
|
|
15
|
+
description: 'Dedicated Runtime lease id',
|
|
16
|
+
required: true,
|
|
17
|
+
}),
|
|
18
|
+
};
|
|
19
|
+
static flags = { json: core_1.Flags.boolean({ description: 'Output as JSON' }) };
|
|
20
|
+
async run() {
|
|
21
|
+
this.requireAuth();
|
|
22
|
+
const { args, flags } = await this.parse(DedicatedMachinesShow);
|
|
23
|
+
let response;
|
|
24
|
+
try {
|
|
25
|
+
response = await (0, dedicated_machines_1.getDedicatedRuntime)(args.lease);
|
|
26
|
+
}
|
|
27
|
+
catch (err) {
|
|
28
|
+
const message = (0, dedicated_machines_1.formatDedicatedRuntimeApiError)(err);
|
|
29
|
+
if (message)
|
|
30
|
+
this.error(message, { exit: 1 });
|
|
31
|
+
this.handleApiError(err);
|
|
32
|
+
}
|
|
33
|
+
const lease = response?.lease;
|
|
34
|
+
if (!lease) {
|
|
35
|
+
this.error('Dedicated Runtime lease not found.', { exit: 1 });
|
|
36
|
+
}
|
|
37
|
+
if (flags.json) {
|
|
38
|
+
this.log(JSON.stringify(response, null, 2));
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
this.log((0, dedicated_machines_1.dedicatedLeaseDisplayName)(lease));
|
|
42
|
+
this.log(` id ${(0, dedicated_machines_1.dedicatedLeaseId)(lease)}`);
|
|
43
|
+
this.log(` status ${(0, dedicated_machines_1.dedicatedLeaseState)(lease)}`);
|
|
44
|
+
if (lease.storage?.retentionClass) {
|
|
45
|
+
this.log(` retention ${lease.storage.retentionClass}`);
|
|
46
|
+
}
|
|
47
|
+
if (lease.storage?.backupProfile) {
|
|
48
|
+
this.log(` backup ${lease.storage.backupProfile}`);
|
|
49
|
+
}
|
|
50
|
+
if (lease.storage?.lastBackupAt) {
|
|
51
|
+
this.log(` last backup ${lease.storage.lastBackupAt}`);
|
|
52
|
+
}
|
|
53
|
+
if (lease.billing?.monthlySpendLimitCents != null) {
|
|
54
|
+
this.log(` monthly cap ${lease.billing.monthlySpendLimitCents} cents`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
exports.default = DedicatedMachinesShow;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base-command';
|
|
2
|
+
export default class DedicatedMachinesSnapshot extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
lease: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
};
|
|
11
|
+
run(): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_command_1 = require("../../../base-command");
|
|
5
|
+
const dedicated_machines_1 = require("../../../lib/dedicated-machines");
|
|
6
|
+
class DedicatedMachinesSnapshot extends base_command_1.BaseCommand {
|
|
7
|
+
static description = 'Snapshot a Dedicated Runtime lease workspace';
|
|
8
|
+
static examples = [
|
|
9
|
+
'<%= config.bin %> machines dedicated snapshot <lease-id>',
|
|
10
|
+
'<%= config.bin %> machines dedicated snapshot <lease-id> --json',
|
|
11
|
+
];
|
|
12
|
+
static args = {
|
|
13
|
+
lease: core_1.Args.string({
|
|
14
|
+
description: 'Dedicated Runtime lease id',
|
|
15
|
+
required: true,
|
|
16
|
+
ignoreStdin: true,
|
|
17
|
+
}),
|
|
18
|
+
};
|
|
19
|
+
static flags = {
|
|
20
|
+
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
21
|
+
};
|
|
22
|
+
async run() {
|
|
23
|
+
this.requireAuth();
|
|
24
|
+
const { args, flags } = await this.parse(DedicatedMachinesSnapshot);
|
|
25
|
+
let response;
|
|
26
|
+
try {
|
|
27
|
+
response = await (0, dedicated_machines_1.performDedicatedLeaseAction)(args.lease, 'snapshot');
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
const message = (0, dedicated_machines_1.formatDedicatedRuntimeApiError)(err);
|
|
31
|
+
if (message)
|
|
32
|
+
this.error(message, { exit: 1 });
|
|
33
|
+
this.handleApiError(err);
|
|
34
|
+
}
|
|
35
|
+
if (flags.json) {
|
|
36
|
+
this.log(JSON.stringify(response, null, 2));
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
this.log(`Dedicated Runtime ${(0, dedicated_machines_1.dedicatedLeaseId)(response?.lease)} ${(0, dedicated_machines_1.dedicatedLeaseState)(response?.lease)}.`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.default = DedicatedMachinesSnapshot;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base-command';
|
|
2
|
+
export default class DedicatedMachinesStart extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
lease: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
};
|
|
11
|
+
run(): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_command_1 = require("../../../base-command");
|
|
5
|
+
const dedicated_machines_1 = require("../../../lib/dedicated-machines");
|
|
6
|
+
class DedicatedMachinesStart extends base_command_1.BaseCommand {
|
|
7
|
+
static description = 'Start a Dedicated Runtime lease';
|
|
8
|
+
static examples = [
|
|
9
|
+
'<%= config.bin %> machines dedicated start <lease-id>',
|
|
10
|
+
'<%= config.bin %> machines dedicated start <lease-id> --json',
|
|
11
|
+
];
|
|
12
|
+
static args = {
|
|
13
|
+
lease: core_1.Args.string({
|
|
14
|
+
description: 'Dedicated Runtime lease id',
|
|
15
|
+
required: true,
|
|
16
|
+
ignoreStdin: true,
|
|
17
|
+
}),
|
|
18
|
+
};
|
|
19
|
+
static flags = {
|
|
20
|
+
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
21
|
+
};
|
|
22
|
+
async run() {
|
|
23
|
+
this.requireAuth();
|
|
24
|
+
const { args, flags } = await this.parse(DedicatedMachinesStart);
|
|
25
|
+
let response;
|
|
26
|
+
try {
|
|
27
|
+
response = await (0, dedicated_machines_1.performDedicatedLeaseAction)(args.lease, 'start');
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
const message = (0, dedicated_machines_1.formatDedicatedRuntimeApiError)(err);
|
|
31
|
+
if (message)
|
|
32
|
+
this.error(message, { exit: 1 });
|
|
33
|
+
this.handleApiError(err);
|
|
34
|
+
}
|
|
35
|
+
if (flags.json) {
|
|
36
|
+
this.log(JSON.stringify(response, null, 2));
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
this.log(`Dedicated Runtime ${(0, dedicated_machines_1.dedicatedLeaseId)(response?.lease)} ${(0, dedicated_machines_1.dedicatedLeaseState)(response?.lease)}.`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.default = DedicatedMachinesStart;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base-command';
|
|
2
|
+
export default class DedicatedMachinesStop extends BaseCommand {
|
|
3
|
+
static description: string;
|
|
4
|
+
static examples: string[];
|
|
5
|
+
static args: {
|
|
6
|
+
lease: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
|
+
};
|
|
8
|
+
static flags: {
|
|
9
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
};
|
|
11
|
+
run(): Promise<void>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_command_1 = require("../../../base-command");
|
|
5
|
+
const dedicated_machines_1 = require("../../../lib/dedicated-machines");
|
|
6
|
+
class DedicatedMachinesStop extends base_command_1.BaseCommand {
|
|
7
|
+
static description = 'Stop a Dedicated Runtime lease';
|
|
8
|
+
static examples = [
|
|
9
|
+
'<%= config.bin %> machines dedicated stop <lease-id>',
|
|
10
|
+
'<%= config.bin %> machines dedicated stop <lease-id> --json',
|
|
11
|
+
];
|
|
12
|
+
static args = {
|
|
13
|
+
lease: core_1.Args.string({
|
|
14
|
+
description: 'Dedicated Runtime lease id',
|
|
15
|
+
required: true,
|
|
16
|
+
ignoreStdin: true,
|
|
17
|
+
}),
|
|
18
|
+
};
|
|
19
|
+
static flags = {
|
|
20
|
+
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
21
|
+
};
|
|
22
|
+
async run() {
|
|
23
|
+
this.requireAuth();
|
|
24
|
+
const { args, flags } = await this.parse(DedicatedMachinesStop);
|
|
25
|
+
let response;
|
|
26
|
+
try {
|
|
27
|
+
response = await (0, dedicated_machines_1.performDedicatedLeaseAction)(args.lease, 'stop');
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
const message = (0, dedicated_machines_1.formatDedicatedRuntimeApiError)(err);
|
|
31
|
+
if (message)
|
|
32
|
+
this.error(message, { exit: 1 });
|
|
33
|
+
this.handleApiError(err);
|
|
34
|
+
}
|
|
35
|
+
if (flags.json) {
|
|
36
|
+
this.log(JSON.stringify(response, null, 2));
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
this.log(`Dedicated Runtime ${(0, dedicated_machines_1.dedicatedLeaseId)(response?.lease)} ${(0, dedicated_machines_1.dedicatedLeaseState)(response?.lease)}.`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.default = DedicatedMachinesStop;
|
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const core_1 = require("@oclif/core");
|
|
4
4
|
class Machines extends core_1.Command {
|
|
5
|
-
|
|
5
|
+
// Paired with `machines dedicated`, and the pairing is the point: this one
|
|
6
|
+
// resumes, that one restarts. Stated here so the choice can be made without
|
|
7
|
+
// opening either topic.
|
|
8
|
+
static description = 'A managed workspace that resumes — files, memory and running processes survive pause';
|
|
6
9
|
static examples = [
|
|
7
10
|
'<%= config.bin %> machines hosted start --name scratch --wait',
|
|
8
11
|
'<%= config.bin %> machines hosted list',
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type SpaceAutoExecutorRefillState } from '@skrr-ai/data-provider';
|
|
1
2
|
import { BaseCommand } from '../../../base-command';
|
|
2
3
|
export default class SpacesAutoExecutorPreview extends BaseCommand {
|
|
3
4
|
static description: string;
|
|
@@ -10,3 +11,10 @@ export default class SpacesAutoExecutorPreview extends BaseCommand {
|
|
|
10
11
|
};
|
|
11
12
|
run(): Promise<void>;
|
|
12
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* The refill latch in words: whether start work is owed, why it last woke, and
|
|
16
|
+
* what each recent task-pool change did. This is how "the board is not picking
|
|
17
|
+
* up work" becomes a question with an answer. `undefined` is a server that does
|
|
18
|
+
* not report it; `null` is one that could not read it, and says so.
|
|
19
|
+
*/
|
|
20
|
+
export declare function refillLines(refill: SpaceAutoExecutorRefillState | null | undefined): string[];
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.refillLines = refillLines;
|
|
3
4
|
const core_1 = require("@oclif/core");
|
|
4
5
|
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
5
6
|
const base_command_1 = require("../../../base-command");
|
|
@@ -49,6 +50,8 @@ class SpacesAutoExecutorPreview extends base_command_1.BaseCommand {
|
|
|
49
50
|
if (capacity.budget && !capacity.budget.unlimited) {
|
|
50
51
|
this.log(`Budget: ${capacity.budget.consumedStarts}/${capacity.budget.maxStarts} starts used this round`);
|
|
51
52
|
}
|
|
53
|
+
for (const line of refillLines(result.refill))
|
|
54
|
+
this.log(line);
|
|
52
55
|
const { actions, summary } = plan;
|
|
53
56
|
this.log('');
|
|
54
57
|
this.log(`Board: ${summary.readyCount} ready · ${summary.unassignedCount} unassigned · ` +
|
|
@@ -70,6 +73,44 @@ class SpacesAutoExecutorPreview extends base_command_1.BaseCommand {
|
|
|
70
73
|
}
|
|
71
74
|
}
|
|
72
75
|
exports.default = SpacesAutoExecutorPreview;
|
|
76
|
+
/**
|
|
77
|
+
* The refill latch in words: whether start work is owed, why it last woke, and
|
|
78
|
+
* what each recent task-pool change did. This is how "the board is not picking
|
|
79
|
+
* up work" becomes a question with an answer. `undefined` is a server that does
|
|
80
|
+
* not report it; `null` is one that could not read it, and says so.
|
|
81
|
+
*/
|
|
82
|
+
function refillLines(refill) {
|
|
83
|
+
if (refill === undefined)
|
|
84
|
+
return [];
|
|
85
|
+
if (refill === null)
|
|
86
|
+
return ['Refill: state unavailable (the server could not read it)'];
|
|
87
|
+
const owed = refill.requestedGeneration - refill.processedGeneration;
|
|
88
|
+
const lines = [
|
|
89
|
+
`Refill: ${refill.pending
|
|
90
|
+
? `${owed} wake${owed === 1 ? '' : 's'} owed (generation ${refill.processedGeneration} → ${refill.requestedGeneration})`
|
|
91
|
+
: `caught up (generation ${refill.processedGeneration})`}${refill.lastReason ? ` · last: ${refill.lastReason}` : ''}`,
|
|
92
|
+
];
|
|
93
|
+
if (refill.notBefore)
|
|
94
|
+
lines.push(` deferred until ${refill.notBefore}`);
|
|
95
|
+
if (refill.waitingOnAgentIds.length) {
|
|
96
|
+
lines.push(` waiting on agent capacity: ${refill.waitingOnAgentIds.join(', ')}`);
|
|
97
|
+
}
|
|
98
|
+
const wakes = refill.taskPool.recentWakes;
|
|
99
|
+
if (wakes.length) {
|
|
100
|
+
lines.push('');
|
|
101
|
+
lines.push(`Recent task-pool changes (${wakes.length}):`);
|
|
102
|
+
for (const wake of wakes) {
|
|
103
|
+
const effect = wake.refillRelevant === true
|
|
104
|
+
? 'can start work'
|
|
105
|
+
: wake.refillRelevant === false
|
|
106
|
+
? 'nothing to start'
|
|
107
|
+
: 'unclassified';
|
|
108
|
+
const outcome = wake.status === 'processed' ? (wake.decision ?? 'processed') : wake.status;
|
|
109
|
+
lines.push(` - #${wake.generation} ${wake.mutation} · ${effect} · ${outcome}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return lines;
|
|
113
|
+
}
|
|
73
114
|
function taskLine(task) {
|
|
74
115
|
return `${task.identifier ? `${task.identifier} ` : ''}${task.title}`;
|
|
75
116
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { BaseCommand } from '../../base-command';
|
|
2
|
+
/**
|
|
3
|
+
* `skrr spaces task-rollups` — task-status counts for every Space you can view,
|
|
4
|
+
* in one request: the same rollup the Spaces sidebar row reads, counted by the
|
|
5
|
+
* project-rollup rules (`done` is done only; `open` excludes cancelled).
|
|
6
|
+
*/
|
|
7
|
+
export default class SpacesTaskRollups extends BaseCommand {
|
|
8
|
+
static description: string;
|
|
9
|
+
static examples: string[];
|
|
10
|
+
static flags: {
|
|
11
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
12
|
+
};
|
|
13
|
+
run(): Promise<void>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const data_provider_1 = require("@skrr-ai/data-provider");
|
|
5
|
+
const base_command_1 = require("../../base-command");
|
|
6
|
+
/**
|
|
7
|
+
* `skrr spaces task-rollups` — task-status counts for every Space you can view,
|
|
8
|
+
* in one request: the same rollup the Spaces sidebar row reads, counted by the
|
|
9
|
+
* project-rollup rules (`done` is done only; `open` excludes cancelled).
|
|
10
|
+
*/
|
|
11
|
+
class SpacesTaskRollups extends base_command_1.BaseCommand {
|
|
12
|
+
static description = 'Show task-status counts for every space you can view';
|
|
13
|
+
static examples = [
|
|
14
|
+
'<%= config.bin %> spaces task-rollups',
|
|
15
|
+
'<%= config.bin %> spaces task-rollups --json',
|
|
16
|
+
];
|
|
17
|
+
static flags = {
|
|
18
|
+
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
19
|
+
};
|
|
20
|
+
async run() {
|
|
21
|
+
this.requireAuth();
|
|
22
|
+
const { flags } = await this.parse(SpacesTaskRollups);
|
|
23
|
+
let response;
|
|
24
|
+
// Titles are best-effort: the rollup carries only ids, and a failed title
|
|
25
|
+
// lookup must not hide counts the rollup did return.
|
|
26
|
+
let titles = new Map();
|
|
27
|
+
try {
|
|
28
|
+
const [rollups, spaces] = await Promise.all([
|
|
29
|
+
data_provider_1.dataService.listSpaceTaskRollups(),
|
|
30
|
+
data_provider_1.dataService.listSpaces({ includeArchived: true, limit: 500 }).catch(() => null),
|
|
31
|
+
]);
|
|
32
|
+
response = rollups;
|
|
33
|
+
const rows = (spaces?.data ||
|
|
34
|
+
[]);
|
|
35
|
+
titles = new Map(rows.map((space) => [String(space.id), space.title || '']));
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
this.handleApiError(err);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (flags.json) {
|
|
42
|
+
this.log(JSON.stringify(response, null, 2));
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (response.degraded) {
|
|
46
|
+
// A partial walk is not the whole picture; say so before the numbers.
|
|
47
|
+
this.log(`Degraded: ${(response.warnings || []).join('; ') || 'some spaces were not counted'}`);
|
|
48
|
+
}
|
|
49
|
+
const rows = [...(response.rollups || [])].sort((a, b) => b.tasks.open - a.tasks.open);
|
|
50
|
+
if (rows.length === 0) {
|
|
51
|
+
this.log('No spaces with tasks.');
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
const label = (spaceId) => {
|
|
55
|
+
const title = titles.get(spaceId);
|
|
56
|
+
const text = title ? `${title} (${spaceId.slice(0, 8)})` : spaceId;
|
|
57
|
+
return text.length > 48 ? `${text.slice(0, 45)}...` : text;
|
|
58
|
+
};
|
|
59
|
+
this.log(`${'SPACE'.padEnd(48)} ${'OPEN'.padStart(5)} ${'DONE'.padStart(5)} ${'BLOCKED'.padStart(7)} ${'TOTAL'.padStart(5)}`);
|
|
60
|
+
for (const { spaceId, tasks } of rows) {
|
|
61
|
+
this.log(`${label(spaceId).padEnd(48)} ${String(tasks.open).padStart(5)} ${String(tasks.done).padStart(5)} ` +
|
|
62
|
+
`${String(tasks.blocked).padStart(7)} ${String(tasks.total).padStart(5)}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
exports.default = SpacesTaskRollups;
|
|
@@ -76,7 +76,9 @@ class SpacesUpdate extends base_command_1.BaseCommand {
|
|
|
76
76
|
description: tasks_1.EXPECT_FLAG_HELP +
|
|
77
77
|
' This is the space DEFAULT, and it is where the contract actually gets set: nobody ' +
|
|
78
78
|
'declares one per task, but a space default is configured once and then holds. A ' +
|
|
79
|
-
'per-task --expect wins. Merged into deliveryPolicy without clobbering its other
|
|
79
|
+
'per-task --expect wins. Merged into deliveryPolicy without clobbering its other ' +
|
|
80
|
+
'fields. Replaces the whole list; pass "clear" to remove the default so new tasks ' +
|
|
81
|
+
'inherit nothing.',
|
|
80
82
|
}),
|
|
81
83
|
'delivery-mode': core_1.Flags.string({
|
|
82
84
|
options: ['none', 'branch', 'pr', 'pr_automerge', 'direct'],
|
|
@@ -132,21 +134,23 @@ class SpacesUpdate extends base_command_1.BaseCommand {
|
|
|
132
134
|
// Parse before any write: a bad spec must fail here, not reach the server
|
|
133
135
|
// as a silently-dropped field. A space default nobody is enforcing is worse
|
|
134
136
|
// than none, because every task under it then shows a contract that isn't real.
|
|
135
|
-
|
|
136
|
-
if (
|
|
137
|
-
|
|
138
|
-
if (!parsed.ok) {
|
|
139
|
-
this.error(parsed.error, { exit: 1 });
|
|
140
|
-
}
|
|
141
|
-
else {
|
|
142
|
-
defaultExpectations = parsed.value;
|
|
143
|
-
}
|
|
137
|
+
const resolvedDefaults = (0, tasks_1.resolveDefaultExpectations)(flags['default-expect']);
|
|
138
|
+
if (!resolvedDefaults.ok) {
|
|
139
|
+
this.error(resolvedDefaults.error, { exit: 1 });
|
|
144
140
|
}
|
|
141
|
+
const defaultExpectations = resolvedDefaults.ok ? resolvedDefaults.value : undefined;
|
|
145
142
|
const isolation = flags['worktree-isolation'];
|
|
146
143
|
const deliveryMode = flags['delivery-mode'];
|
|
147
144
|
const integrationBranch = flags['integration-branch'];
|
|
148
145
|
const autoMergeTier = flags['auto-merge-tier'];
|
|
149
|
-
|
|
146
|
+
// `defaultExpectations === null` is a real instruction (remove the default), so
|
|
147
|
+
// it must reach the policy merge — a truthiness test dropped it silently and
|
|
148
|
+
// made `clear` a no-op that printed success.
|
|
149
|
+
if (isolation ||
|
|
150
|
+
defaultExpectations !== undefined ||
|
|
151
|
+
deliveryMode ||
|
|
152
|
+
integrationBranch ||
|
|
153
|
+
autoMergeTier) {
|
|
150
154
|
let basePolicy = {};
|
|
151
155
|
if (payload.deliveryPolicy && typeof payload.deliveryPolicy === 'object') {
|
|
152
156
|
basePolicy = { ...payload.deliveryPolicy };
|
|
@@ -169,7 +173,7 @@ class SpacesUpdate extends base_command_1.BaseCommand {
|
|
|
169
173
|
...(deliveryMode ? { mode: deliveryMode } : {}),
|
|
170
174
|
...(integrationBranch ? { integrationBranch } : {}),
|
|
171
175
|
...(autoMergeTier ? { autoMergeTrustTier: autoMergeTier } : {}),
|
|
172
|
-
...(defaultExpectations ? { defaultExpectations } : {}),
|
|
176
|
+
...(defaultExpectations !== undefined ? { defaultExpectations } : {}),
|
|
173
177
|
};
|
|
174
178
|
}
|
|
175
179
|
// Goal links are NOT part of the PATCH body — the server rejects a PATCH
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base-command';
|
|
2
|
+
/**
|
|
3
|
+
* `skrr spaces work-sync reconcile <space>` — answer the divergence question
|
|
4
|
+
* without a browser, and repair what it finds.
|
|
5
|
+
*
|
|
6
|
+
* Root `CLAUDE.md` records that two Work Sync exit criteria were knowingly
|
|
7
|
+
* overridden, and that "an unexplained board divergence is a live hypothesis, not
|
|
8
|
+
* an impossibility, and is the first thing to suspect." `work-sync telemetry`
|
|
9
|
+
* reports whether the browser's convergence detector has ever RUN. This answers
|
|
10
|
+
* the underlying question directly: it compares every published projection entry
|
|
11
|
+
* against authoritative task truth server-side, and `upserts` is the count that
|
|
12
|
+
* disagreed.
|
|
13
|
+
*
|
|
14
|
+
* That matters because the detector only runs where a board is open. A Space
|
|
15
|
+
* nobody has visited since the detector shipped reports zero comparisons forever,
|
|
16
|
+
* which is indistinguishable from health in the telemetry and is not health. This
|
|
17
|
+
* command needs no board, no browser, and no visitor.
|
|
18
|
+
*
|
|
19
|
+
* IT WRITES, and the help says so plainly rather than burying it. The endpoint is
|
|
20
|
+
* editor-gated because it republishes projection rows that clients will see. It
|
|
21
|
+
* never mutates task truth — the projection is derived, and a republished card is
|
|
22
|
+
* a corrected copy of a Task nobody touched — and on a healthy scope it finds
|
|
23
|
+
* nothing and changes nothing, so the verification and the repair are the same
|
|
24
|
+
* call. There is deliberately no dry-run flag to add: a read-only variant would be
|
|
25
|
+
* a second implementation of the comparison, which is how the two answers start
|
|
26
|
+
* disagreeing.
|
|
27
|
+
*/
|
|
28
|
+
export default class SpacesWorkSyncReconcile extends BaseCommand {
|
|
29
|
+
static description: string;
|
|
30
|
+
static examples: string[];
|
|
31
|
+
static args: {
|
|
32
|
+
space: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
33
|
+
};
|
|
34
|
+
static flags: {
|
|
35
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
36
|
+
};
|
|
37
|
+
run(): Promise<void>;
|
|
38
|
+
}
|