@skrr-ai/cli 0.1.47 → 0.1.49
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 +1 -1
- package/dist/base-command.d.ts +18 -0
- package/dist/base-command.js +61 -1
- package/dist/commands/agent-worker.d.ts +12 -0
- package/dist/commands/agent-worker.js +140 -0
- package/dist/commands/agents/chat.d.ts +21 -0
- package/dist/commands/agents/chat.js +26 -9
- package/dist/commands/balance/usage/breakdown.d.ts +14 -0
- package/dist/commands/balance/usage/breakdown.js +68 -0
- package/dist/commands/balance/usage.js +24 -0
- package/dist/commands/commerce/entitlements/explain.d.ts +22 -0
- package/dist/commands/commerce/entitlements/explain.js +40 -0
- package/dist/commands/commerce/incidents/audit.d.ts +20 -0
- package/dist/commands/commerce/incidents/audit.js +37 -0
- package/dist/commands/commerce/incidents/list.d.ts +22 -0
- package/dist/commands/commerce/incidents/list.js +49 -0
- package/dist/commands/commerce/incidents/resolve.d.ts +23 -0
- package/dist/commands/commerce/incidents/resolve.js +45 -0
- package/dist/commands/commerce/incidents/retry.d.ts +22 -0
- package/dist/commands/commerce/incidents/retry.js +45 -0
- package/dist/commands/commerce/incidents/show.d.ts +13 -0
- package/dist/commands/commerce/incidents/show.js +30 -0
- package/dist/commands/commerce/offers/approve.d.ts +17 -0
- package/dist/commands/commerce/offers/approve.js +33 -0
- package/dist/commands/commerce/offers/create.d.ts +18 -0
- package/dist/commands/commerce/offers/create.js +34 -0
- package/dist/commands/commerce/offers/publish.d.ts +13 -0
- package/dist/commands/commerce/offers/publish.js +28 -0
- package/dist/commands/commerce/offers/retire.d.ts +17 -0
- package/dist/commands/commerce/offers/retire.js +32 -0
- package/dist/commands/commerce/offers/validate.d.ts +18 -0
- package/dist/commands/commerce/offers/validate.js +33 -0
- package/dist/commands/commerce/products/create.d.ts +10 -0
- package/dist/commands/commerce/products/create.js +25 -0
- package/dist/commands/commerce/promotions/redeem.d.ts +13 -0
- package/dist/commands/commerce/promotions/redeem.js +32 -0
- package/dist/commands/commerce/terms/accept.d.ts +18 -0
- package/dist/commands/commerce/terms/accept.js +39 -0
- package/dist/commands/commerce/terms/show.d.ts +10 -0
- package/dist/commands/commerce/terms/show.js +34 -0
- package/dist/commands/commerce/trials/conversion-preview.d.ts +18 -0
- package/dist/commands/commerce/trials/conversion-preview.js +39 -0
- package/dist/commands/commerce/trials/start.d.ts +23 -0
- package/dist/commands/commerce/trials/start.js +58 -0
- package/dist/commands/commitments/accounting.d.ts +39 -0
- package/dist/commands/commitments/accounting.js +116 -0
- package/dist/commands/commitments/action-history.d.ts +1 -0
- package/dist/commands/commitments/action-history.js +8 -1
- package/dist/commands/commitments/case.d.ts +1 -0
- package/dist/commands/commitments/case.js +19 -3
- package/dist/commands/commitments/cases.d.ts +1 -0
- package/dist/commands/commitments/cases.js +11 -1
- package/dist/commands/commitments/checks.d.ts +1 -0
- package/dist/commands/commitments/checks.js +5 -1
- package/dist/commands/commitments/cost.d.ts +62 -0
- package/dist/commands/commitments/cost.js +130 -0
- package/dist/commands/commitments/create.js +1 -1
- package/dist/commands/commitments/delete.d.ts +1 -0
- package/dist/commands/commitments/delete.js +56 -6
- package/dist/commands/commitments/feedback.js +9 -1
- package/dist/commands/commitments/handover.js +16 -0
- package/dist/commands/commitments/hypotheses.d.ts +1 -0
- package/dist/commands/commitments/hypotheses.js +17 -2
- package/dist/commands/commitments/links/list.js +4 -1
- package/dist/commands/commitments/liveness.d.ts +18 -0
- package/dist/commands/commitments/liveness.js +80 -0
- package/dist/commands/commitments/metrics.d.ts +1 -0
- package/dist/commands/commitments/metrics.js +8 -1
- package/dist/commands/commitments/next-tick.d.ts +39 -0
- package/dist/commands/commitments/next-tick.js +122 -0
- package/dist/commands/commitments/observations.d.ts +1 -0
- package/dist/commands/commitments/observations.js +19 -2
- package/dist/commands/commitments/pause.js +12 -0
- package/dist/commands/commitments/receipt.d.ts +2 -0
- package/dist/commands/commitments/receipt.js +16 -2
- package/dist/commands/commitments/remediation-proposal.js +6 -2
- package/dist/commands/commitments/remediation-proposals.js +5 -1
- package/dist/commands/commitments/restore.d.ts +25 -0
- package/dist/commands/commitments/restore.js +46 -0
- package/dist/commands/commitments/show.js +32 -0
- package/dist/commands/commitments/trigger-status.js +33 -0
- package/dist/commands/commitments/update.d.ts +1 -0
- package/dist/commands/commitments/update.js +31 -5
- package/dist/commands/commitments/wake-capabilities.d.ts +0 -1
- package/dist/commands/commitments/wake-capabilities.js +8 -4
- package/dist/commands/enterprise/budgets/create.d.ts +11 -0
- package/dist/commands/enterprise/budgets/create.js +27 -0
- package/dist/commands/enterprise/budgets/evaluate.d.ts +17 -0
- package/dist/commands/enterprise/budgets/evaluate.js +32 -0
- package/dist/commands/enterprise/budgets/publish.d.ts +14 -0
- package/dist/commands/enterprise/budgets/publish.js +30 -0
- package/dist/commands/enterprise/contracts/activate.d.ts +14 -0
- package/dist/commands/enterprise/contracts/activate.js +30 -0
- package/dist/commands/enterprise/contracts/create.d.ts +14 -0
- package/dist/commands/enterprise/contracts/create.js +32 -0
- package/dist/commands/enterprise/contracts/issue.d.ts +18 -0
- package/dist/commands/enterprise/contracts/issue.js +34 -0
- package/dist/commands/enterprise/domains/begin.d.ts +20 -0
- package/dist/commands/enterprise/domains/begin.js +39 -0
- package/dist/commands/enterprise/domains/verify.d.ts +14 -0
- package/dist/commands/enterprise/domains/verify.js +32 -0
- package/dist/commands/enterprise/external-config/activate.d.ts +22 -0
- package/dist/commands/enterprise/external-config/activate.js +49 -0
- package/dist/commands/enterprise/external-config/set.d.ts +25 -0
- package/dist/commands/enterprise/external-config/set.js +123 -0
- package/dist/commands/enterprise/external-config/show.d.ts +12 -0
- package/dist/commands/enterprise/external-config/show.js +39 -0
- package/dist/commands/enterprise/external-config/suspend.d.ts +13 -0
- package/dist/commands/enterprise/external-config/suspend.js +41 -0
- package/dist/commands/enterprise/finance/close-snapshot.d.ts +11 -0
- package/dist/commands/enterprise/finance/close-snapshot.js +28 -0
- package/dist/commands/enterprise/finance/record-document.d.ts +18 -0
- package/dist/commands/enterprise/finance/record-document.js +35 -0
- package/dist/commands/enterprise/profile.d.ts +20 -0
- package/dist/commands/enterprise/profile.js +38 -0
- package/dist/commands/login.d.ts +13 -0
- package/dist/commands/login.js +77 -0
- package/dist/commands/machines/dedicated/index.js +3 -0
- package/dist/commands/machines/dedicated/service/apply.d.ts +23 -0
- package/dist/commands/machines/dedicated/service/apply.js +99 -0
- package/dist/commands/machines/dedicated/service/approve.d.ts +23 -0
- package/dist/commands/machines/dedicated/service/approve.js +52 -0
- package/dist/commands/machines/dedicated/service/create.d.ts +55 -0
- package/dist/commands/machines/dedicated/service/create.js +222 -0
- package/dist/commands/machines/dedicated/service/edit.d.ts +30 -0
- package/dist/commands/machines/dedicated/service/edit.js +146 -0
- package/dist/commands/machines/dedicated/service/exec.d.ts +26 -0
- package/dist/commands/machines/dedicated/service/exec.js +92 -0
- package/dist/commands/machines/dedicated/service/export.d.ts +29 -0
- package/dist/commands/machines/dedicated/service/export.js +106 -0
- package/dist/commands/machines/dedicated/service/index.d.ts +14 -0
- package/dist/commands/machines/dedicated/service/index.js +49 -0
- package/dist/commands/machines/dedicated/service/logs.d.ts +33 -0
- package/dist/commands/machines/dedicated/service/logs.js +148 -0
- package/dist/commands/machines/dedicated/service/ls.d.ts +20 -0
- package/dist/commands/machines/dedicated/service/ls.js +80 -0
- package/dist/commands/machines/dedicated/service/restart.d.ts +14 -0
- package/dist/commands/machines/dedicated/service/restart.js +29 -0
- package/dist/commands/machines/dedicated/service/rm.d.ts +20 -0
- package/dist/commands/machines/dedicated/service/rm.js +33 -0
- package/dist/commands/machines/dedicated/service/secret/index.d.ts +14 -0
- package/dist/commands/machines/dedicated/service/secret/index.js +25 -0
- package/dist/commands/machines/dedicated/service/secret/rm.d.ts +22 -0
- package/dist/commands/machines/dedicated/service/secret/rm.js +54 -0
- package/dist/commands/machines/dedicated/service/secret/set.d.ts +22 -0
- package/dist/commands/machines/dedicated/service/secret/set.js +93 -0
- package/dist/commands/machines/dedicated/service/start.d.ts +14 -0
- package/dist/commands/machines/dedicated/service/start.js +29 -0
- package/dist/commands/machines/dedicated/service/status.d.ts +21 -0
- package/dist/commands/machines/dedicated/service/status.js +85 -0
- package/dist/commands/machines/dedicated/service/stop.d.ts +20 -0
- package/dist/commands/machines/dedicated/service/stop.js +35 -0
- package/dist/commands/machines/dedicated/service/top.d.ts +22 -0
- package/dist/commands/machines/dedicated/service/top.js +120 -0
- package/dist/commands/machines/dedicated/sign-in-status.d.ts +22 -0
- package/dist/commands/machines/dedicated/sign-in-status.js +79 -0
- package/dist/commands/machines/dedicated/ssh-config.d.ts +28 -0
- package/dist/commands/machines/dedicated/ssh-config.js +66 -0
- package/dist/commands/machines/dedicated/ssh-proxy.d.ts +22 -0
- package/dist/commands/machines/dedicated/ssh-proxy.js +62 -0
- package/dist/commands/machines/dedicated/ssh.d.ts +29 -0
- package/dist/commands/machines/dedicated/ssh.js +121 -0
- package/dist/commands/native/allow-all.d.ts +14 -0
- package/dist/commands/native/allow-all.js +25 -0
- package/dist/commands/native/allow.d.ts +24 -0
- package/dist/commands/native/allow.js +45 -0
- package/dist/commands/native/deny.d.ts +24 -0
- package/dist/commands/native/deny.js +43 -0
- package/dist/commands/native/disable.d.ts +17 -0
- package/dist/commands/native/disable.js +28 -0
- package/dist/commands/native/enable.d.ts +12 -0
- package/dist/commands/native/enable.js +29 -0
- package/dist/commands/native/list-apps.d.ts +19 -0
- package/dist/commands/native/list-apps.js +30 -0
- package/dist/commands/native/restrict-to.d.ts +22 -0
- package/dist/commands/native/restrict-to.js +41 -0
- package/dist/commands/native/status.d.ts +19 -0
- package/dist/commands/native/status.js +33 -0
- package/dist/commands/native.d.ts +39 -0
- package/dist/commands/native.js +76 -0
- package/dist/commands/service/index.d.ts +14 -0
- package/dist/commands/service/index.js +31 -0
- package/dist/commands/service/logs.d.ts +18 -0
- package/dist/commands/service/logs.js +53 -0
- package/dist/commands/service/ls.d.ts +13 -0
- package/dist/commands/service/ls.js +48 -0
- package/dist/commands/service/propose.d.ts +34 -0
- package/dist/commands/service/propose.js +113 -0
- package/dist/commands/service/status.d.ts +17 -0
- package/dist/commands/service/status.js +56 -0
- package/dist/commands/spaces/auto-executor/runs.d.ts +13 -0
- package/dist/commands/spaces/auto-executor/runs.js +56 -0
- package/dist/commands/store/governance/artifacts.d.ts +25 -0
- package/dist/commands/store/governance/artifacts.js +55 -0
- package/dist/commands/store/governance/assign.d.ts +16 -0
- package/dist/commands/store/governance/assign.js +54 -0
- package/dist/commands/store/governance/create-license.d.ts +18 -0
- package/dist/commands/store/governance/create-license.js +35 -0
- package/dist/commands/store/governance/install-plan.d.ts +25 -0
- package/dist/commands/store/governance/install-plan.js +56 -0
- package/dist/commands/store/governance/license-policy.d.ts +30 -0
- package/dist/commands/store/governance/license-policy.js +69 -0
- package/dist/commands/store/governance/policy.d.ts +25 -0
- package/dist/commands/store/governance/policy.js +65 -0
- package/dist/commands/store/governance/publish-release.d.ts +17 -0
- package/dist/commands/store/governance/publish-release.js +34 -0
- package/dist/commands/tasks/deliverable/add.d.ts +15 -0
- package/dist/commands/tasks/deliverable/add.js +174 -0
- package/dist/commands/tasks/deliverable/archive.d.ts +35 -0
- package/dist/commands/tasks/deliverable/archive.js +205 -0
- package/dist/commands/tasks/labels/detach.js +3 -0
- package/dist/commands/tasks/labels/suggest.d.ts +24 -0
- package/dist/commands/tasks/labels/suggest.js +69 -0
- package/dist/commands/tasks/list.d.ts +16 -2
- package/dist/commands/tasks/list.js +100 -24
- package/dist/commands/tasks/show.d.ts +23 -0
- package/dist/commands/tasks/show.js +51 -1
- package/dist/commands/wiki/rm.d.ts +22 -1
- package/dist/commands/wiki/rm.js +52 -3
- package/dist/lib/agentic-stream.js +10 -2
- package/dist/lib/balance.d.ts +6 -1
- package/dist/lib/balance.js +15 -0
- package/dist/lib/commerce-command.d.ts +48 -0
- package/dist/lib/commerce-command.js +70 -0
- package/dist/lib/commerce.d.ts +93 -0
- package/dist/lib/commerce.js +129 -0
- package/dist/lib/commitment-product.js +1 -1
- package/dist/lib/commitments.d.ts +202 -29
- package/dist/lib/commitments.js +300 -33
- package/dist/lib/daemon-installer.d.ts +6 -5
- package/dist/lib/daemon-installer.js +4 -17
- package/dist/lib/dedicated-lease-command.js +10 -0
- package/dist/lib/dedicated-machines.d.ts +37 -0
- package/dist/lib/dedicated-machines.js +47 -0
- package/dist/lib/dedicated-service-command.d.ts +60 -0
- package/dist/lib/dedicated-service-command.js +182 -0
- package/dist/lib/dedicated-service.d.ts +342 -0
- package/dist/lib/dedicated-service.js +741 -0
- package/dist/lib/dedicated-ssh.d.ts +136 -0
- package/dist/lib/dedicated-ssh.js +387 -0
- package/dist/lib/delegated-cli.js +51 -13
- package/dist/lib/enterprise-commerce.d.ts +67 -0
- package/dist/lib/enterprise-commerce.js +112 -0
- package/dist/lib/enterprise-external-configuration.d.ts +60 -0
- package/dist/lib/enterprise-external-configuration.js +58 -0
- package/dist/lib/first-party-harness.js +17 -3
- package/dist/lib/governed-store.d.ts +110 -0
- package/dist/lib/governed-store.js +79 -0
- package/dist/lib/guest-service-command.d.ts +16 -0
- package/dist/lib/guest-service-command.js +32 -0
- package/dist/lib/guest-service.d.ts +67 -0
- package/dist/lib/guest-service.js +112 -0
- package/dist/lib/prompt.d.ts +1 -0
- package/dist/lib/prompt.js +1 -0
- package/dist/lib/task-asset-upload.d.ts +20 -0
- package/dist/lib/task-asset-upload.js +30 -8
- package/dist/lib/task-extras.d.ts +23 -0
- package/dist/lib/task-extras.js +6 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonScopes.d.ts +9 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonScopes.js +10 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarness.d.ts +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/firstPartyHarness.js +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.d.ts +2 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.js +8 -5
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/messages.d.ts +16 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/messages.js +21 -4
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/releaseManifest.d.ts +38 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/releaseManifest.js +66 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/spawnEnv.d.ts +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/spawnEnv.js +24 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonScopes.d.ts +9 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonScopes.js +10 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarness.d.ts +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/firstPartyHarness.js +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.d.ts +2 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.js +2 -2
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/messages.d.ts +16 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/messages.js +20 -4
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/releaseManifest.d.ts +38 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/releaseManifest.js +64 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/spawnEnv.d.ts +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/spawnEnv.js +24 -2
- package/dist/node_modules/@skrr-ai/auth-core/package.json +1 -1
- package/dist/node_modules/@skrr-ai/data-provider/index.js +5060 -4827
- package/oclif.manifest.json +35194 -29157
- package/package.json +43 -1
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { DedicatedServiceCommand } from '../../../../lib/dedicated-service-command';
|
|
2
|
+
/**
|
|
3
|
+
* `skrr machines dedicated service edit` — change a running declaration in
|
|
4
|
+
* $EDITOR, applied as a compare-and-swap update.
|
|
5
|
+
*
|
|
6
|
+
* The round-trip is honest about the race it cannot hide: the daemon owns the
|
|
7
|
+
* spec and increments `revision` on every write, so an edit made against a
|
|
8
|
+
* stale read is refused `conflict`, never merged. When that happens your edit
|
|
9
|
+
* is saved to a named file, the editor re-opens on the CURRENT spec, and you
|
|
10
|
+
* re-apply — three rounds, then the command gives up with the file named.
|
|
11
|
+
*/
|
|
12
|
+
export default class DedicatedServiceEdit extends DedicatedServiceCommand {
|
|
13
|
+
static summary: string;
|
|
14
|
+
static examples: string[];
|
|
15
|
+
static args: {
|
|
16
|
+
lease: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
17
|
+
name: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
18
|
+
};
|
|
19
|
+
static flags: {
|
|
20
|
+
editor: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
21
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
22
|
+
};
|
|
23
|
+
run(): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Run the editor over the temp file. Returns the new contents, or null when
|
|
26
|
+
* the file is byte-identical — an unopened or untouched edit applies
|
|
27
|
+
* nothing, which is the honest answer to "I looked and left".
|
|
28
|
+
*/
|
|
29
|
+
private editFile;
|
|
30
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const node_fs_1 = require("node:fs");
|
|
7
|
+
const node_os_1 = require("node:os");
|
|
8
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
+
const node_child_process_1 = require("node:child_process");
|
|
10
|
+
const core_1 = require("@oclif/core");
|
|
11
|
+
const dedicated_service_command_1 = require("../../../../lib/dedicated-service-command");
|
|
12
|
+
const dedicated_service_1 = require("../../../../lib/dedicated-service");
|
|
13
|
+
/** How many times a CAS conflict re-seeds the editor before giving up. */
|
|
14
|
+
const EDIT_CONFLICT_ROUNDS = 3;
|
|
15
|
+
/**
|
|
16
|
+
* `skrr machines dedicated service edit` — change a running declaration in
|
|
17
|
+
* $EDITOR, applied as a compare-and-swap update.
|
|
18
|
+
*
|
|
19
|
+
* The round-trip is honest about the race it cannot hide: the daemon owns the
|
|
20
|
+
* spec and increments `revision` on every write, so an edit made against a
|
|
21
|
+
* stale read is refused `conflict`, never merged. When that happens your edit
|
|
22
|
+
* is saved to a named file, the editor re-opens on the CURRENT spec, and you
|
|
23
|
+
* re-apply — three rounds, then the command gives up with the file named.
|
|
24
|
+
*/
|
|
25
|
+
class DedicatedServiceEdit extends dedicated_service_command_1.DedicatedServiceCommand {
|
|
26
|
+
static summary = 'Edit a service spec in $EDITOR and apply it (CAS update)';
|
|
27
|
+
static examples = [
|
|
28
|
+
'<%= config.bin %> machines dedicated service edit <lease-id> <name>',
|
|
29
|
+
];
|
|
30
|
+
static args = {
|
|
31
|
+
lease: core_1.Args.string({
|
|
32
|
+
description: dedicated_service_command_1.SERVICE_LEASE_ARG_DESCRIPTION,
|
|
33
|
+
required: true,
|
|
34
|
+
ignoreStdin: true,
|
|
35
|
+
}),
|
|
36
|
+
name: core_1.Args.string({ description: 'Service name', required: true, ignoreStdin: true }),
|
|
37
|
+
};
|
|
38
|
+
static flags = {
|
|
39
|
+
editor: core_1.Flags.string({ description: 'Editor to use (default $VISUAL, $EDITOR, then vi)' }),
|
|
40
|
+
json: core_1.Flags.boolean({ description: 'Output the updated spec as JSON' }),
|
|
41
|
+
};
|
|
42
|
+
async run() {
|
|
43
|
+
this.requireAuth();
|
|
44
|
+
const { args, flags } = await this.parse(DedicatedServiceEdit);
|
|
45
|
+
const leaseId = await this.resolveLeaseArg(args.lease);
|
|
46
|
+
const editor = flags.editor ?? process.env.VISUAL ?? process.env.EDITOR ?? 'vi';
|
|
47
|
+
const channel = await this.serviceChannel();
|
|
48
|
+
const dir = (0, node_fs_1.mkdtempSync)(node_path_1.default.join((0, node_os_1.tmpdir)(), 'skrr-svc-edit-'));
|
|
49
|
+
const file = node_path_1.default.join(dir, `${args.name}.json`);
|
|
50
|
+
// Set on every path that NAMES the temp file for the user — an error that
|
|
51
|
+
// says "your edit is at <file>" must leave the file standing.
|
|
52
|
+
let keepDir = false;
|
|
53
|
+
try {
|
|
54
|
+
for (let round = 1; round <= EDIT_CONFLICT_ROUNDS; round += 1) {
|
|
55
|
+
const { result } = await channel.call('get', {
|
|
56
|
+
leaseId,
|
|
57
|
+
name: args.name,
|
|
58
|
+
...this.scopeFrom(flags),
|
|
59
|
+
});
|
|
60
|
+
const spec = result?.spec;
|
|
61
|
+
if (!spec) {
|
|
62
|
+
this.error(`No service named ${args.name} on ${leaseId}.`, { exit: 1 });
|
|
63
|
+
}
|
|
64
|
+
const baseRevision = typeof spec.revision === 'number' ? spec.revision : undefined;
|
|
65
|
+
(0, node_fs_1.writeFileSync)(file, `${JSON.stringify(spec, null, 2)}\n`);
|
|
66
|
+
const edited = await this.editFile(file, editor);
|
|
67
|
+
if (edited === null) {
|
|
68
|
+
this.log('Unchanged — nothing applied.');
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
let next;
|
|
72
|
+
try {
|
|
73
|
+
next = (0, dedicated_service_1.parseServiceSpecDocument)(edited, file);
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
keepDir = true;
|
|
77
|
+
// Keep the file so the person can fix it by hand and apply it.
|
|
78
|
+
this.error(`${err instanceof Error ? err.message : err}\nYour edit is still at ${file} — fix it and run \`${this.config.bin} machines dedicated service apply ${leaseId} --file ${file}\`, or re-run edit.`, { exit: 2 });
|
|
79
|
+
}
|
|
80
|
+
try {
|
|
81
|
+
const { result: updated } = await channel.call('update', {
|
|
82
|
+
leaseId,
|
|
83
|
+
name: args.name,
|
|
84
|
+
patch: (0, dedicated_service_1.specPayload)(next),
|
|
85
|
+
baseRevision,
|
|
86
|
+
...this.scopeFrom(flags),
|
|
87
|
+
});
|
|
88
|
+
this.closeServiceChannel();
|
|
89
|
+
if (flags.json) {
|
|
90
|
+
this.log(JSON.stringify(updated ?? (0, dedicated_service_1.specPayload)(next), null, 2));
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
this.log(`Service ${args.name} updated on ${leaseId}.`);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
if (!(err instanceof dedicated_service_1.DedicatedServiceError && err.code === 'conflict')) {
|
|
98
|
+
this.reportServiceError(err);
|
|
99
|
+
}
|
|
100
|
+
// CAS lost: preserve the edit, say where, and re-seed the editor
|
|
101
|
+
// with the spec as it actually is now.
|
|
102
|
+
const rejected = `${file}.rejected-${round}.json`;
|
|
103
|
+
(0, node_fs_1.writeFileSync)(rejected, edited);
|
|
104
|
+
if (round === EDIT_CONFLICT_ROUNDS) {
|
|
105
|
+
keepDir = true;
|
|
106
|
+
this.error(`The spec changed underneath the edit ${EDIT_CONFLICT_ROUNDS} times in a row. ` +
|
|
107
|
+
`Your last edit is at ${rejected} — apply it by hand with \`${this.config.bin} machines dedicated service apply ${leaseId} --file ${rejected}\` once the machine settles.`, { exit: 1 });
|
|
108
|
+
}
|
|
109
|
+
keepDir = true;
|
|
110
|
+
process.stderr.write(`[edit] the spec changed since you opened it; your edit is saved at ${rejected} and the editor re-opens on the current spec.\n`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
finally {
|
|
115
|
+
if (!keepDir) {
|
|
116
|
+
try {
|
|
117
|
+
(0, node_fs_1.rmSync)(dir, { recursive: true, force: true });
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
/* a file the user still needs is worth more than a clean tmpdir */
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Run the editor over the temp file. Returns the new contents, or null when
|
|
127
|
+
* the file is byte-identical — an unopened or untouched edit applies
|
|
128
|
+
* nothing, which is the honest answer to "I looked and left".
|
|
129
|
+
*/
|
|
130
|
+
async editFile(file, editor) {
|
|
131
|
+
const before = (0, node_fs_1.readFileSync)(file, 'utf8');
|
|
132
|
+
// sh -c so "code --wait" and friends work as one flag value.
|
|
133
|
+
const spawned = (0, node_child_process_1.spawnSync)('sh', ['-c', `${editor} "$1"`, 'sh', file], {
|
|
134
|
+
stdio: 'inherit',
|
|
135
|
+
});
|
|
136
|
+
if (spawned.error) {
|
|
137
|
+
this.error(`Could not run ${editor}: ${spawned.error.message}`, { exit: 1 });
|
|
138
|
+
}
|
|
139
|
+
if (spawned.status !== 0) {
|
|
140
|
+
this.error(`${editor} exited ${spawned.status}; nothing was applied.`, { exit: 1 });
|
|
141
|
+
}
|
|
142
|
+
const after = (0, node_fs_1.readFileSync)(file, 'utf8');
|
|
143
|
+
return after === before ? null : after;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
exports.default = DedicatedServiceEdit;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { DedicatedServiceCommand } from '../../../../lib/dedicated-service-command';
|
|
2
|
+
/**
|
|
3
|
+
* `skrr machines dedicated service exec` — a one-off command inside a
|
|
4
|
+
* service's context (phase 2).
|
|
5
|
+
*
|
|
6
|
+
* The spawn carries the service's cwd, env and cgroup scope, so it lands in
|
|
7
|
+
* the service's process tree and shares its fate — the honest way to debug a
|
|
8
|
+
* service whose environment the daemon holds. A daemon that predates the
|
|
9
|
+
* extension refuses cleanly; `machines dedicated exec` is the always-there
|
|
10
|
+
* fallback for ad-hoc commands.
|
|
11
|
+
*/
|
|
12
|
+
export default class DedicatedServiceExec extends DedicatedServiceCommand {
|
|
13
|
+
static summary: string;
|
|
14
|
+
static examples: string[];
|
|
15
|
+
static usage: string;
|
|
16
|
+
static args: {
|
|
17
|
+
lease: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
18
|
+
name: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
19
|
+
command: import("@oclif/core/lib/interfaces").Arg<string[] | undefined, Record<string, unknown>>;
|
|
20
|
+
};
|
|
21
|
+
static flags: {
|
|
22
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
23
|
+
timeout: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
24
|
+
};
|
|
25
|
+
run(): Promise<void>;
|
|
26
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const dedicated_service_command_1 = require("../../../../lib/dedicated-service-command");
|
|
5
|
+
const exec_1 = require("../../hosted/exec");
|
|
6
|
+
/**
|
|
7
|
+
* `skrr machines dedicated service exec` — a one-off command inside a
|
|
8
|
+
* service's context (phase 2).
|
|
9
|
+
*
|
|
10
|
+
* The spawn carries the service's cwd, env and cgroup scope, so it lands in
|
|
11
|
+
* the service's process tree and shares its fate — the honest way to debug a
|
|
12
|
+
* service whose environment the daemon holds. A daemon that predates the
|
|
13
|
+
* extension refuses cleanly; `machines dedicated exec` is the always-there
|
|
14
|
+
* fallback for ad-hoc commands.
|
|
15
|
+
*/
|
|
16
|
+
class DedicatedServiceExec extends dedicated_service_command_1.DedicatedServiceCommand {
|
|
17
|
+
static summary = 'Run a one-off command in a service’s context (phase 2)';
|
|
18
|
+
static examples = [
|
|
19
|
+
'<%= config.bin %> machines dedicated service exec <lease-id> <name> -- printenv',
|
|
20
|
+
'<%= config.bin %> machines dedicated service exec <lease-id> <name> -- cat /workspace/services/name/state.json',
|
|
21
|
+
];
|
|
22
|
+
static usage = 'machines dedicated service exec <lease-id> <name> -- <command...>';
|
|
23
|
+
static args = {
|
|
24
|
+
lease: core_1.Args.string({
|
|
25
|
+
description: dedicated_service_command_1.SERVICE_LEASE_ARG_DESCRIPTION,
|
|
26
|
+
required: true,
|
|
27
|
+
ignoreStdin: true,
|
|
28
|
+
}),
|
|
29
|
+
name: core_1.Args.string({ description: 'Service name', required: true, ignoreStdin: true }),
|
|
30
|
+
command: core_1.Args.string({
|
|
31
|
+
description: 'The command and its arguments, after --',
|
|
32
|
+
multiple: true,
|
|
33
|
+
required: false,
|
|
34
|
+
ignoreStdin: true,
|
|
35
|
+
}),
|
|
36
|
+
};
|
|
37
|
+
static flags = {
|
|
38
|
+
json: core_1.Flags.boolean({ description: 'Output the result as JSON' }),
|
|
39
|
+
timeout: core_1.Flags.integer({
|
|
40
|
+
description: 'Seconds the command may run on the machine (1-600, default 300)',
|
|
41
|
+
min: 1,
|
|
42
|
+
max: 600,
|
|
43
|
+
}),
|
|
44
|
+
};
|
|
45
|
+
async run() {
|
|
46
|
+
this.requireAuth();
|
|
47
|
+
const { head, tail } = (0, exec_1.splitExecArgv)(this.argv);
|
|
48
|
+
const { args, flags } = await this.parse(DedicatedServiceExec, head);
|
|
49
|
+
const argv = tail ?? args.command ?? [];
|
|
50
|
+
if (argv.length === 0) {
|
|
51
|
+
this.error('Command is required — pass it after --.', { exit: 2 });
|
|
52
|
+
}
|
|
53
|
+
const leaseId = await this.resolveLeaseArg(args.lease);
|
|
54
|
+
// Phase-2 verb: `dedicated:service:exec {leaseId, name, argv}`. A daemon
|
|
55
|
+
// without the extension answers with the unsupported path — the command
|
|
56
|
+
// degrades, it does not improvise.
|
|
57
|
+
const timeoutSeconds = flags.timeout ?? 300;
|
|
58
|
+
const result = await this.callService('exec', {
|
|
59
|
+
leaseId,
|
|
60
|
+
name: args.name,
|
|
61
|
+
argv,
|
|
62
|
+
timeoutSeconds,
|
|
63
|
+
...this.scopeFrom(flags),
|
|
64
|
+
},
|
|
65
|
+
// The relay waits timeoutSeconds+30s; the caller must outlive that or a
|
|
66
|
+
// legitimately long exec reports a false connectivity failure.
|
|
67
|
+
(timeoutSeconds + 45) * 1000);
|
|
68
|
+
this.closeServiceChannel();
|
|
69
|
+
if (flags.json) {
|
|
70
|
+
this.log(JSON.stringify(result ?? {}, null, 2));
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
// Binary-safe: the wire contract is base64 — write the decoded bytes
|
|
74
|
+
// verbatim; a debug verb that utf8-mangles or appends newlines lies
|
|
75
|
+
// about what the service emitted.
|
|
76
|
+
const stdout = result?.stdoutBase64
|
|
77
|
+
? Buffer.from(result.stdoutBase64, 'base64')
|
|
78
|
+
: Buffer.from(result?.stdout ?? '', 'utf8');
|
|
79
|
+
const stderr = result?.stderrBase64
|
|
80
|
+
? Buffer.from(result.stderrBase64, 'base64')
|
|
81
|
+
: Buffer.from(result?.stderr ?? '', 'utf8');
|
|
82
|
+
if (stdout.length > 0)
|
|
83
|
+
process.stdout.write(stdout);
|
|
84
|
+
if (stderr.length > 0)
|
|
85
|
+
process.stderr.write(stderr);
|
|
86
|
+
}
|
|
87
|
+
const exitCode = typeof result?.exitCode === 'number' ? result.exitCode : 0;
|
|
88
|
+
if (exitCode !== 0)
|
|
89
|
+
this.exit(exitCode);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
exports.default = DedicatedServiceExec;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { DedicatedServiceCommand } from '../../../../lib/dedicated-service-command';
|
|
2
|
+
/** Shape written by `service export` and accepted by `service apply --file`. */
|
|
3
|
+
export declare const SERVICE_SPEC_EXPORT_VERSION = 1;
|
|
4
|
+
/**
|
|
5
|
+
* `skrr machines dedicated service export` — the stored spec as a repo
|
|
6
|
+
* `service.json` (phase 2).
|
|
7
|
+
*
|
|
8
|
+
* The artifact is the apply-able document: the daemon's bookkeeping
|
|
9
|
+
* (`revision`, `createdBy`, timestamps) is stripped, forward fields are kept
|
|
10
|
+
* verbatim, so `--output service.json` is exactly what
|
|
11
|
+
* `service apply --file service.json` takes on this machine or another one.
|
|
12
|
+
* Like every export verb it asks for a destination — `--summary`,
|
|
13
|
+
* `--output <path>` or `--output -` for deliberate stdout — rather than
|
|
14
|
+
* spilling a spec onto the terminal because a flag was forgotten.
|
|
15
|
+
*/
|
|
16
|
+
export default class DedicatedServiceExport extends DedicatedServiceCommand {
|
|
17
|
+
static summary: string;
|
|
18
|
+
static examples: string[];
|
|
19
|
+
static args: {
|
|
20
|
+
lease: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
21
|
+
name: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
22
|
+
};
|
|
23
|
+
static flags: {
|
|
24
|
+
summary: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
25
|
+
output: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
26
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
27
|
+
};
|
|
28
|
+
run(): Promise<void>;
|
|
29
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SERVICE_SPEC_EXPORT_VERSION = void 0;
|
|
4
|
+
const core_1 = require("@oclif/core");
|
|
5
|
+
const dedicated_service_command_1 = require("../../../../lib/dedicated-service-command");
|
|
6
|
+
const dedicated_service_1 = require("../../../../lib/dedicated-service");
|
|
7
|
+
const artifact_export_1 = require("../../../../lib/artifact-export");
|
|
8
|
+
/** Shape written by `service export` and accepted by `service apply --file`. */
|
|
9
|
+
exports.SERVICE_SPEC_EXPORT_VERSION = 1;
|
|
10
|
+
/**
|
|
11
|
+
* `skrr machines dedicated service export` — the stored spec as a repo
|
|
12
|
+
* `service.json` (phase 2).
|
|
13
|
+
*
|
|
14
|
+
* The artifact is the apply-able document: the daemon's bookkeeping
|
|
15
|
+
* (`revision`, `createdBy`, timestamps) is stripped, forward fields are kept
|
|
16
|
+
* verbatim, so `--output service.json` is exactly what
|
|
17
|
+
* `service apply --file service.json` takes on this machine or another one.
|
|
18
|
+
* Like every export verb it asks for a destination — `--summary`,
|
|
19
|
+
* `--output <path>` or `--output -` for deliberate stdout — rather than
|
|
20
|
+
* spilling a spec onto the terminal because a flag was forgotten.
|
|
21
|
+
*/
|
|
22
|
+
class DedicatedServiceExport extends dedicated_service_command_1.DedicatedServiceCommand {
|
|
23
|
+
static summary = 'Export a stored spec in the repo service.json form';
|
|
24
|
+
static examples = [
|
|
25
|
+
'<%= config.bin %> machines dedicated service export <lease-id> <name> --output service.json',
|
|
26
|
+
'<%= config.bin %> machines dedicated service export <lease-id> <name> --output - | jq .',
|
|
27
|
+
'<%= config.bin %> machines dedicated service export <lease-id> <name> --summary',
|
|
28
|
+
];
|
|
29
|
+
static args = {
|
|
30
|
+
lease: core_1.Args.string({
|
|
31
|
+
description: dedicated_service_command_1.SERVICE_LEASE_ARG_DESCRIPTION,
|
|
32
|
+
required: true,
|
|
33
|
+
ignoreStdin: true,
|
|
34
|
+
}),
|
|
35
|
+
name: core_1.Args.string({ description: 'Service name', required: true, ignoreStdin: true }),
|
|
36
|
+
};
|
|
37
|
+
static flags = {
|
|
38
|
+
...(0, artifact_export_1.standardExportFlags)(),
|
|
39
|
+
};
|
|
40
|
+
async run() {
|
|
41
|
+
this.requireAuth();
|
|
42
|
+
const { args, flags } = await this.parse(DedicatedServiceExport);
|
|
43
|
+
let selection;
|
|
44
|
+
try {
|
|
45
|
+
selection = (0, artifact_export_1.resolveExportSelection)(flags);
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
if (err instanceof artifact_export_1.ExportContractError) {
|
|
49
|
+
this.failWithCliError({
|
|
50
|
+
message: err.message,
|
|
51
|
+
code: err.code,
|
|
52
|
+
exit: 2,
|
|
53
|
+
retryable: false,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
throw err;
|
|
57
|
+
}
|
|
58
|
+
const leaseId = await this.resolveLeaseArg(args.lease);
|
|
59
|
+
const result = await this.callService('get', {
|
|
60
|
+
leaseId,
|
|
61
|
+
name: args.name,
|
|
62
|
+
...this.scopeFrom(flags),
|
|
63
|
+
});
|
|
64
|
+
this.closeServiceChannel();
|
|
65
|
+
if (!result?.spec) {
|
|
66
|
+
this.error(`No service named ${args.name} on ${leaseId}.`, { exit: 1 });
|
|
67
|
+
}
|
|
68
|
+
if (selection.summary) {
|
|
69
|
+
const summary = (0, artifact_export_1.contentFreeSummary)({
|
|
70
|
+
command: 'machines dedicated service export',
|
|
71
|
+
artifactSchemaVersion: exports.SERVICE_SPEC_EXPORT_VERSION,
|
|
72
|
+
itemCount: 1,
|
|
73
|
+
counts: { services: 1 },
|
|
74
|
+
});
|
|
75
|
+
this.log(selection.json ? JSON.stringify(summary, null, 2) : (0, artifact_export_1.humanExportSummary)(summary));
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const serialized = (0, artifact_export_1.serializedArtifact)((0, dedicated_service_1.specExportDocument)(result.spec));
|
|
79
|
+
if (selection.output === '-') {
|
|
80
|
+
this.log(serialized.trimEnd());
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
let receipt;
|
|
84
|
+
try {
|
|
85
|
+
receipt = await (0, artifact_export_1.writeExportArtifact)({
|
|
86
|
+
command: 'machines dedicated service export',
|
|
87
|
+
artifactSchemaVersion: exports.SERVICE_SPEC_EXPORT_VERSION,
|
|
88
|
+
format: 'json',
|
|
89
|
+
output: selection.output,
|
|
90
|
+
content: serialized,
|
|
91
|
+
itemCount: 1,
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
this.failWithCliError({
|
|
96
|
+
message: `Could not write ${selection.output}: ${err.message}`,
|
|
97
|
+
code: 'SERVICE_SPEC_EXPORT_WRITE_FAILED',
|
|
98
|
+
exit: 1,
|
|
99
|
+
retryable: false,
|
|
100
|
+
details: { path: selection.output },
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
this.log(selection.json ? JSON.stringify(receipt, null, 2) : (0, artifact_export_1.humanExportReceipt)(receipt));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
exports.default = DedicatedServiceExport;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Command } from '@oclif/core';
|
|
2
|
+
/**
|
|
3
|
+
* `skrr machines dedicated service` — declared, always-on workloads.
|
|
4
|
+
*
|
|
5
|
+
* A detached process dies at every machine boundary; a declared service is
|
|
6
|
+
* restarted by the machine's daemon across crashes, daemon restarts,
|
|
7
|
+
* checkpoints, stop→start and instance replacement. This topic is how the
|
|
8
|
+
* owner declares them.
|
|
9
|
+
*/
|
|
10
|
+
export default class DedicatedMachinesService extends Command {
|
|
11
|
+
static description: string;
|
|
12
|
+
static examples: string[];
|
|
13
|
+
run(): Promise<void>;
|
|
14
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
/**
|
|
5
|
+
* `skrr machines dedicated service` — declared, always-on workloads.
|
|
6
|
+
*
|
|
7
|
+
* A detached process dies at every machine boundary; a declared service is
|
|
8
|
+
* restarted by the machine's daemon across crashes, daemon restarts,
|
|
9
|
+
* checkpoints, stop→start and instance replacement. This topic is how the
|
|
10
|
+
* owner declares them.
|
|
11
|
+
*/
|
|
12
|
+
class DedicatedMachinesService extends core_1.Command {
|
|
13
|
+
static description = 'Declared services on a Dedicated Runtime — workloads the machine keeps running across restarts, checkpoints and replacements';
|
|
14
|
+
static examples = [
|
|
15
|
+
'<%= config.bin %> machines dedicated service create <lease-id> --name worker --cwd /workspace/repos/app -- node dist/worker.js',
|
|
16
|
+
'<%= config.bin %> machines dedicated service apply <lease-id> --file service.json',
|
|
17
|
+
'<%= config.bin %> machines dedicated service ls <lease-id>',
|
|
18
|
+
'<%= config.bin %> machines dedicated service status <lease-id> <name>',
|
|
19
|
+
'<%= config.bin %> machines dedicated service logs <lease-id> <name> -f',
|
|
20
|
+
'<%= config.bin %> machines dedicated service approve <lease-id> <name>',
|
|
21
|
+
];
|
|
22
|
+
async run() {
|
|
23
|
+
const rows = [
|
|
24
|
+
['create', 'declare a service (argv after --, or --file service.json)'],
|
|
25
|
+
['apply', 'create or update a service from a spec file, idempotently'],
|
|
26
|
+
['ls', 'list services and pending agent proposals'],
|
|
27
|
+
['status', 'one service: spec, computed status and recent exits'],
|
|
28
|
+
['edit', 'edit the spec in $EDITOR and apply it (CAS update)'],
|
|
29
|
+
['logs', 'print a service log; -f follows'],
|
|
30
|
+
['start', 'set desired state to running'],
|
|
31
|
+
['stop', 'set desired state to stopped; survives machine restarts'],
|
|
32
|
+
['restart', 'restart the service now'],
|
|
33
|
+
['rm', 'remove the declaration'],
|
|
34
|
+
['approve', 'approve (--reject to refuse) an agent-proposed service'],
|
|
35
|
+
['exec', 'run a one-off command inside a service’s context (phase 2)'],
|
|
36
|
+
['top', 'per-service cpu/mem/pids (phase 2)'],
|
|
37
|
+
['export', 'print the repo service.json form of a stored spec'],
|
|
38
|
+
['secret', 'set or remove a secret a spec can reference (phase 2)'],
|
|
39
|
+
];
|
|
40
|
+
this.log('skrr machines dedicated service commands:');
|
|
41
|
+
for (const [name, summary] of rows) {
|
|
42
|
+
this.log(` skrr machines dedicated service ${name.padEnd(8)} ${summary}`);
|
|
43
|
+
}
|
|
44
|
+
this.log('');
|
|
45
|
+
this.log('Every command takes a lease id (or `self` on the machine) and --json. ' +
|
|
46
|
+
'Agents on the machine propose services instead: `skrr service propose`.');
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
exports.default = DedicatedMachinesService;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { DedicatedServiceCommand } from '../../../../lib/dedicated-service-command';
|
|
2
|
+
/**
|
|
3
|
+
* `skrr machines dedicated service logs` — tail the service's log, or follow it.
|
|
4
|
+
*
|
|
5
|
+
* The daemon rotates a bounded `current` log per service; `logs` replays a
|
|
6
|
+
* byte tail of it and `-f` keeps the stream open on live
|
|
7
|
+
* `dedicated:service:log` frames. Ctrl-C ends the follow cleanly — the
|
|
8
|
+
* stream is closed with `logs:stop`, the service keeps running.
|
|
9
|
+
*
|
|
10
|
+
* While a follow is open, an agent proposal arriving on the same channel is
|
|
11
|
+
* surfaced on stderr: the owner watching logs is exactly the owner who can
|
|
12
|
+
* approve it.
|
|
13
|
+
*/
|
|
14
|
+
export default class DedicatedServiceLogs extends DedicatedServiceCommand {
|
|
15
|
+
static summary: string;
|
|
16
|
+
static examples: string[];
|
|
17
|
+
static args: {
|
|
18
|
+
lease: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
19
|
+
name: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
20
|
+
};
|
|
21
|
+
static flags: {
|
|
22
|
+
follow: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
23
|
+
tail: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
24
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
25
|
+
};
|
|
26
|
+
run(): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* The machine-readable follow: each log frame is one JSON line. An ack's
|
|
29
|
+
* refusal surfaces through the same channel.call error path as every other
|
|
30
|
+
* verb (a `--json` caller reads the CLI error envelope).
|
|
31
|
+
*/
|
|
32
|
+
private followJson;
|
|
33
|
+
}
|