@skrr-ai/cli 0.1.87 → 0.1.88

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.
Files changed (92) hide show
  1. package/dist/commands/agents/chat.js +27 -1
  2. package/dist/commands/computer/index.d.ts +19 -0
  3. package/dist/commands/computer/index.js +37 -0
  4. package/dist/commands/labels/create.d.ts +1 -0
  5. package/dist/commands/labels/create.js +2 -0
  6. package/dist/commands/labels/restore.d.ts +1 -0
  7. package/dist/commands/labels/restore.js +6 -3
  8. package/dist/commands/labels/update.d.ts +1 -0
  9. package/dist/commands/labels/update.js +2 -0
  10. package/dist/commands/machines/computer-adoption.d.ts +15 -0
  11. package/dist/commands/machines/computer-adoption.js +33 -0
  12. package/dist/commands/machines/dedicated/archive.d.ts +26 -0
  13. package/dist/commands/machines/dedicated/archive.js +113 -0
  14. package/dist/commands/machines/dedicated/audit.d.ts +25 -0
  15. package/dist/commands/machines/dedicated/audit.js +113 -0
  16. package/dist/commands/machines/dedicated/computer.d.ts +23 -0
  17. package/dist/commands/machines/dedicated/computer.js +64 -0
  18. package/dist/commands/machines/dedicated/cp.d.ts +2 -0
  19. package/dist/commands/machines/dedicated/cp.js +74 -2
  20. package/dist/commands/machines/dedicated/git-status.d.ts +15 -0
  21. package/dist/commands/machines/dedicated/git-status.js +56 -0
  22. package/dist/commands/machines/dedicated/index.js +15 -1
  23. package/dist/commands/machines/dedicated/ls.d.ts +27 -0
  24. package/dist/commands/machines/dedicated/ls.js +100 -0
  25. package/dist/commands/machines/dedicated/mkdir.d.ts +18 -0
  26. package/dist/commands/machines/dedicated/mkdir.js +57 -0
  27. package/dist/commands/machines/dedicated/mv.d.ts +24 -0
  28. package/dist/commands/machines/dedicated/mv.js +83 -0
  29. package/dist/commands/machines/dedicated/rm.d.ts +26 -0
  30. package/dist/commands/machines/dedicated/rm.js +100 -0
  31. package/dist/commands/machines/dedicated/search.d.ts +24 -0
  32. package/dist/commands/machines/dedicated/search.js +78 -0
  33. package/dist/commands/machines/dedicated/stat.d.ts +22 -0
  34. package/dist/commands/machines/dedicated/stat.js +92 -0
  35. package/dist/commands/machines/hosted/index.js +1 -1
  36. package/dist/commands/machines/hosted/list.js +1 -1
  37. package/dist/commands/machines/hosted/start.js +1 -1
  38. package/dist/commands/machines/services/declare.d.ts +24 -0
  39. package/dist/commands/machines/services/declare.js +73 -0
  40. package/dist/commands/machines/services/index.d.ts +15 -0
  41. package/dist/commands/machines/services/index.js +31 -0
  42. package/dist/commands/machines/services/ls.d.ts +17 -0
  43. package/dist/commands/machines/services/ls.js +60 -0
  44. package/dist/commands/machines/services/withdraw.d.ts +19 -0
  45. package/dist/commands/machines/services/withdraw.js +47 -0
  46. package/dist/commands/machines/share.d.ts +29 -0
  47. package/dist/commands/machines/share.js +100 -0
  48. package/dist/commands/machines/shared.d.ts +19 -0
  49. package/dist/commands/machines/shared.js +62 -0
  50. package/dist/commands/machines/shares.d.ts +16 -0
  51. package/dist/commands/machines/shares.js +69 -0
  52. package/dist/commands/machines/unshare.d.ts +19 -0
  53. package/dist/commands/machines/unshare.js +61 -0
  54. package/dist/commands/tasks/labels/create.d.ts +1 -0
  55. package/dist/commands/tasks/labels/create.js +3 -0
  56. package/dist/commands/views/create.d.ts +1 -0
  57. package/dist/commands/views/create.js +5 -0
  58. package/dist/lib/agent-home-workspace.d.ts +7 -0
  59. package/dist/lib/agent-home-workspace.js +147 -0
  60. package/dist/lib/computer-adoption.d.ts +55 -0
  61. package/dist/lib/computer-adoption.js +67 -0
  62. package/dist/lib/computer-consent.d.ts +13 -0
  63. package/dist/lib/computer-consent.js +33 -0
  64. package/dist/lib/computer-files.d.ts +239 -0
  65. package/dist/lib/computer-files.js +707 -0
  66. package/dist/lib/dedicated-copy.d.ts +45 -9
  67. package/dist/lib/dedicated-copy.js +141 -44
  68. package/dist/lib/dedicated-machines.d.ts +49 -0
  69. package/dist/lib/dedicated-machines.js +97 -6
  70. package/dist/lib/label-scope.d.ts +12 -0
  71. package/dist/lib/label-scope.js +15 -1
  72. package/dist/lib/machine-audit.d.ts +34 -0
  73. package/dist/lib/machine-audit.js +50 -0
  74. package/dist/lib/machine-grants.d.ts +70 -0
  75. package/dist/lib/machine-grants.js +47 -0
  76. package/dist/lib/machine-services.d.ts +64 -0
  77. package/dist/lib/machine-services.js +60 -0
  78. package/dist/lib/task-view-render.d.ts +2 -0
  79. package/dist/lib/task-view-render.js +1 -1
  80. package/dist/lib/views/vocabulary.d.ts +1 -1
  81. package/dist/lib/views/vocabulary.js +2 -1
  82. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/computerWire.d.ts +955 -0
  83. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/computerWire.js +1070 -0
  84. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonToolApproval.js +7 -0
  85. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/computerWire.d.ts +955 -0
  86. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/computerWire.js +1051 -0
  87. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonToolApproval.js +7 -0
  88. package/dist/node_modules/@skrr-ai/auth-core/package.json +11 -1
  89. package/dist/node_modules/@skrr-ai/data-provider/index.js +22143 -20728
  90. package/dist/node_modules/@skrr-ai/data-provider/package.json +1 -1
  91. package/oclif.manifest.json +11550 -9963
  92. package/package.json +2 -2
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const core_1 = require("@oclif/core");
4
4
  const base_command_1 = require("../../../base-command");
5
+ const computer_files_1 = require("../../../lib/computer-files");
5
6
  const dedicated_machines_1 = require("../../../lib/dedicated-machines");
6
7
  const dedicated_copy_1 = require("../../../lib/dedicated-copy");
7
8
  const LIMIT_MIB = dedicated_machines_1.DEDICATED_FILE_MAX_BYTES / (1024 * 1024);
@@ -26,6 +27,12 @@ class DedicatedMachinesCp extends base_command_1.BaseCommand {
26
27
  'machine is created.',
27
28
  'As with cp and scp, a destination that ends in / or is an existing directory receives the file ' +
28
29
  'under its source name.',
30
+ 'Copying to the machine never replaces a file unasked. A destination that does not exist is created, ' +
31
+ 'and the copy commits only if the name is still free. A destination that exists is refused before ' +
32
+ 'anything is sent, unless --overwrite is given (it replaces the version found when the copy starts, ' +
33
+ 'and says which) or --if-tag <tag> (it replaces exactly the version `stat` showed you). Either way, a ' +
34
+ 'destination that changes during the copy is not replaced. Every request of one copy is bound to the ' +
35
+ 'machine as it was when the copy started: a machine replaced meanwhile refuses the rest.',
29
36
  'Files marked executable keep owner execute permission on the copy. Other permissions use ' +
30
37
  'destination defaults; source special permission bits are not copied.',
31
38
  'Neither side is left half-written: the file is staged beside its destination and renamed into ' +
@@ -36,6 +43,8 @@ class DedicatedMachinesCp extends base_command_1.BaseCommand {
36
43
  static examples = [
37
44
  '<%= config.bin %> machines dedicated cp ./dist/app.tar.gz rtl_abc123:repos/app/app.tar.gz',
38
45
  '<%= config.bin %> machines dedicated cp ./notes.md rtl_abc123:user-data/',
46
+ '<%= config.bin %> machines dedicated cp ./build.zip rtl_abc123:repos/app/build.zip --overwrite',
47
+ '<%= config.bin %> machines dedicated cp ./build.zip rtl_abc123:repos/app/build.zip --if-tag 12345:3182:1761234567890000000',
39
48
  '<%= config.bin %> machines dedicated cp rtl_abc123:repos/app/coverage/report.html ./report.html',
40
49
  ];
41
50
  // `ignoreStdin: true` on both, per the CLI's own hygiene rule: without it oclif
@@ -55,6 +64,12 @@ class DedicatedMachinesCp extends base_command_1.BaseCommand {
55
64
  };
56
65
  static flags = {
57
66
  workspace: core_1.Flags.string({ description: 'Workspace scope' }),
67
+ overwrite: core_1.Flags.boolean({
68
+ description: 'Copying to the machine: replace an existing destination (the version found when the copy starts)',
69
+ }),
70
+ 'if-tag': core_1.Flags.string({
71
+ description: 'Copying to the machine: replace the destination only if it still has this tag — the <inode>:<size>:<mtimeNs> `stat` prints',
72
+ }),
58
73
  json: core_1.Flags.boolean({ description: 'Output the result as JSON' }),
59
74
  };
60
75
  async run() {
@@ -68,6 +83,23 @@ class DedicatedMachinesCp extends base_command_1.BaseCommand {
68
83
  this.error(err.message, { exit: 2 });
69
84
  }
70
85
  const scope = { workspaceId: flags.workspace };
86
+ if (plan.direction === 'download' && (flags.overwrite || flags['if-tag'] !== undefined)) {
87
+ this.error('--overwrite and --if-tag apply when copying to the machine.', { exit: 2 });
88
+ }
89
+ let ifTag;
90
+ if (flags['if-tag'] !== undefined) {
91
+ try {
92
+ ifTag = (0, computer_files_1.parseComputerFileTag)(flags['if-tag']);
93
+ }
94
+ catch (err) {
95
+ this.error(err.message.replace(/--tag/g, '--if-tag'), { exit: 2 });
96
+ }
97
+ if (ifTag.contents !== undefined) {
98
+ this.error('--if-tag names a file version; a folder contents tag cannot be replaced.', {
99
+ exit: 2,
100
+ });
101
+ }
102
+ }
71
103
  // Progress is drawn on stderr, for a person at a terminal: never into a
72
104
  // --json document, and never into a CI log as a stream of carriage returns.
73
105
  const progress = !flags.json && process.stderr.isTTY && !(0, dedicated_copy_1.isContinuousIntegration)()
@@ -84,13 +116,24 @@ class DedicatedMachinesCp extends base_command_1.BaseCommand {
84
116
  let result;
85
117
  try {
86
118
  const { signal } = interrupt;
119
+ // Once, before the first file call: every request of this copy presents
120
+ // this generation, so a machine replaced mid-copy refuses the rest.
121
+ const generation = await (0, computer_files_1.resolveDedicatedFileGeneration)(plan.leaseId, scope);
87
122
  result =
88
123
  plan.direction === 'upload'
89
124
  ? await (0, dedicated_copy_1.uploadToDedicatedRuntime)(plan.localPath, plan.leaseId, plan.remotePath, scope, {
125
+ generation,
90
126
  signal,
91
127
  onProgress,
128
+ overwrite: flags.overwrite === true,
129
+ ...(ifTag ? { ifTag } : {}),
130
+ // Said before a byte is sent, so the person knows what is being replaced.
131
+ onReplace: (destination, tag) => {
132
+ progress?.clear();
133
+ process.stderr.write(`Replacing ${destination} (tag ${(0, computer_files_1.computerFileTagString)(tag)})\n`);
134
+ },
92
135
  })
93
- : await (0, dedicated_copy_1.downloadFromDedicatedRuntime)(plan.leaseId, plan.remotePath, plan.localPath, scope, { signal, onProgress });
136
+ : await (0, dedicated_copy_1.downloadFromDedicatedRuntime)(plan.leaseId, plan.remotePath, plan.localPath, scope, { generation, signal, onProgress });
94
137
  }
95
138
  catch (thrown) {
96
139
  progress?.clear();
@@ -107,6 +150,28 @@ class DedicatedMachinesCp extends base_command_1.BaseCommand {
107
150
  if (err instanceof dedicated_copy_1.DedicatedCopyError) {
108
151
  this.error(err.message, { exit: 1, code: err.code });
109
152
  }
153
+ if (err instanceof computer_files_1.DedicatedFileGenerationUnavailableError) {
154
+ this.error(err.message, { exit: 1, code: err.code });
155
+ }
156
+ // The machine was replaced mid-copy, or its image cannot fence the copy:
157
+ // the computer vocabulary says what to do about either.
158
+ const computerCode = (0, computer_files_1.computerFileRefusalInfo)(err)?.code;
159
+ if (computerCode === 'stale_generation' || computerCode === 'capability_missing') {
160
+ const failure = (0, computer_files_1.describeComputerFileFailure)(err, {
161
+ bin: this.config.bin,
162
+ leaseId: plan.leaseId,
163
+ });
164
+ if (failure) {
165
+ const notReplaced = plan.direction === 'upload'
166
+ ? ` ${plan.leaseId}:${plan.remotePath} was not changed.`
167
+ : ` Nothing was written to ${plan.localPath}.`;
168
+ this.failWithCliError({
169
+ ...failure,
170
+ message: `${failure.message}${notReplaced}`,
171
+ exit: 1,
172
+ });
173
+ }
174
+ }
110
175
  // Keep the API status, request id and explicit retry decision together.
111
176
  if ((0, base_command_1.apiRefusal)(err).body?.retryable === true)
112
177
  this.handleApiError(err);
@@ -129,7 +194,14 @@ class DedicatedMachinesCp extends base_command_1.BaseCommand {
129
194
  this.log(JSON.stringify({ direction: plan.direction, ...result }, null, 2));
130
195
  return;
131
196
  }
132
- this.log(`${plan.direction === 'upload' ? 'Uploaded' : 'Downloaded'} ${result.bytes} bytes → ${result.destination}`);
197
+ if (plan.direction === 'upload' && result.alreadyCommitted) {
198
+ this.log(`Already copied: ${result.destination} (an earlier attempt committed it)`);
199
+ return;
200
+ }
201
+ const replaced = result.replacedTag
202
+ ? ` (replaced the version tagged ${result.replacedTag})`
203
+ : '';
204
+ this.log(`${plan.direction === 'upload' ? 'Uploaded' : 'Downloaded'} ${result.bytes} bytes → ${result.destination}${replaced}`);
133
205
  }
134
206
  }
135
207
  exports.default = DedicatedMachinesCp;
@@ -0,0 +1,15 @@
1
+ import { DedicatedLeaseCommand } from '../../../lib/dedicated-lease-command';
2
+ /** `skrr machines dedicated git-status` — git marks of one folder's entries. */
3
+ export default class DedicatedMachinesGitStatus extends DedicatedLeaseCommand {
4
+ static summary: string;
5
+ static description: string;
6
+ static examples: string[];
7
+ static args: {
8
+ lease: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
9
+ path: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
10
+ };
11
+ static flags: {
12
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
13
+ };
14
+ run(): Promise<void>;
15
+ }
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const dedicated_lease_command_1 = require("../../../lib/dedicated-lease-command");
5
+ const computer_files_1 = require("../../../lib/computer-files");
6
+ /** `skrr machines dedicated git-status` — git marks of one folder's entries. */
7
+ class DedicatedMachinesGitStatus extends dedicated_lease_command_1.DedicatedLeaseCommand {
8
+ static summary = 'Show git marks for a folder on a Dedicated Runtime machine';
9
+ static description = 'Prints the git mark (modified, added, untracked, ignored, conflicted) of each entry of one ' +
10
+ 'folder, as the computer’s Files window decorates them. A folder outside a repository is ' +
11
+ 'said so; a status that does not finish in time offers no marks rather than a partial set. ' +
12
+ 'Available on dedicated machines, not on a personal machine.';
13
+ static examples = [
14
+ '<%= config.bin %> machines dedicated git-status rtl_abc123 repos/app',
15
+ '<%= config.bin %> machines dedicated git-status rtl_abc123 repos/app --json',
16
+ ];
17
+ static args = {
18
+ lease: core_1.Args.string({
19
+ description: dedicated_lease_command_1.DEDICATED_LEASE_ARG_DESCRIPTION,
20
+ required: true,
21
+ ignoreStdin: true,
22
+ }),
23
+ path: core_1.Args.string({
24
+ description: 'Folder on the machine, relative to /workspace',
25
+ required: true,
26
+ ignoreStdin: true,
27
+ }),
28
+ };
29
+ static flags = {
30
+ json: core_1.Flags.boolean({ description: 'Output the result as JSON' }),
31
+ };
32
+ async run() {
33
+ this.requireAuth();
34
+ const { args, flags } = await this.parse(DedicatedMachinesGitStatus);
35
+ const leaseId = await this.resolveLeaseArg(args.lease);
36
+ let result;
37
+ try {
38
+ const scope = this.scopeFrom(flags);
39
+ const generation = await (0, computer_files_1.resolveDedicatedFileGeneration)(leaseId, scope);
40
+ result = await (0, computer_files_1.gitStatusComputerFiles)(leaseId, { path: args.path, generation }, scope);
41
+ }
42
+ catch (err) {
43
+ const failure = (0, computer_files_1.describeComputerFileFailure)(err, { bin: this.config.bin, leaseId });
44
+ if (failure)
45
+ this.failWithCliError({ ...failure, exit: 1 });
46
+ this.handleApiError(err);
47
+ }
48
+ if (flags.json) {
49
+ this.log(JSON.stringify(result, null, 2));
50
+ return;
51
+ }
52
+ for (const line of (0, computer_files_1.computerFileGitStatusLines)(result))
53
+ this.log(line);
54
+ }
55
+ }
56
+ exports.default = DedicatedMachinesGitStatus;
@@ -19,6 +19,13 @@ class DedicatedMachines extends core_1.Command {
19
19
  '<%= config.bin %> machines dedicated sign-in <lease-id> github',
20
20
  '<%= config.bin %> machines dedicated exec <lease-id> -- git -C repos/app status',
21
21
  '<%= config.bin %> machines dedicated cp ./notes.md <lease-id>:user-data/notes.md',
22
+ '<%= config.bin %> machines dedicated ls <lease-id> repos/app',
23
+ '<%= config.bin %> machines dedicated stat <lease-id> repos/app/package.json',
24
+ '<%= config.bin %> machines dedicated mkdir <lease-id> repos/app/dist',
25
+ '<%= config.bin %> machines dedicated mv <lease-id> repos/a repos/b',
26
+ '<%= config.bin %> machines dedicated rm <lease-id> repos/app/dist --recursive',
27
+ '<%= config.bin %> machines dedicated archive <lease-id> repos/app',
28
+ '<%= config.bin %> machines dedicated computer <lease-id>',
22
29
  '<%= config.bin %> machines dedicated stop <lease-id> --wait',
23
30
  '<%= config.bin %> machines dedicated start <lease-id> --wait',
24
31
  '<%= config.bin %> machines dedicated restart <lease-id>',
@@ -44,6 +51,13 @@ class DedicatedMachines extends core_1.Command {
44
51
  ['sign-in', 'sign in to GitHub CLI, Claude Code or Codex there'],
45
52
  ['exec', 'run one command; output and exit code'],
46
53
  ['cp', 'copy a file to or from the machine'],
54
+ ['ls', 'list a directory on the machine'],
55
+ ['stat', 'one path: type, size, mtime, mode and its tag'],
56
+ ['mkdir', 'create a directory, parents included'],
57
+ ['mv', 'rename or move a path'],
58
+ ['rm', 'delete a file or folder (--recursive)'],
59
+ ['archive', 'download a folder as a tar file'],
60
+ ['computer', 'open the machine’s computer in the browser or skrr Desktop'],
47
61
  ['start', 'start a stopped runtime'],
48
62
  ['stop', 'stop compute and keep the disk'],
49
63
  ['restart', 'restart the instance; files stay'],
@@ -56,7 +70,7 @@ class DedicatedMachines extends core_1.Command {
56
70
  ['service', 'declare workloads the machine keeps running'],
57
71
  ['destroy', 'stop compute; keep or purge the workspace disk'],
58
72
  ];
59
- this.log('skrr Dedicated Runtime commands:');
73
+ this.log('Skrr Dedicated Runtime commands:');
60
74
  for (const [name, summary] of rows) {
61
75
  this.log(` skrr machines dedicated ${name.padEnd(15)} ${summary}`);
62
76
  }
@@ -0,0 +1,27 @@
1
+ import { DedicatedLeaseCommand } from '../../../lib/dedicated-lease-command';
2
+ /**
3
+ * `skrr machines dedicated ls` — list one directory on the machine.
4
+ *
5
+ * Paths are relative to /workspace and, on a guest, confined to `repos/` and
6
+ * `user-data/` — the tenant roots; the workspace root itself is the runtime's
7
+ * and a listing of it is refused `path_withheld`. Entries are sorted by the
8
+ * machine by name bytes; a symlink shows its stored target and is never
9
+ * followed; an entry the machine withholds (deny set, blockedPaths, a
10
+ * sensitive pattern, an OS permission) is shown as withheld, not hidden.
11
+ */
12
+ export default class DedicatedMachinesLs extends DedicatedLeaseCommand {
13
+ static summary: string;
14
+ static description: string;
15
+ static examples: string[];
16
+ static args: {
17
+ lease: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
18
+ path: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
19
+ };
20
+ static flags: {
21
+ limit: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
22
+ cursor: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
23
+ all: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
24
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
25
+ };
26
+ run(): Promise<void>;
27
+ }
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const dedicated_lease_command_1 = require("../../../lib/dedicated-lease-command");
5
+ const format_1 = require("../../../lib/format");
6
+ const computer_files_1 = require("../../../lib/computer-files");
7
+ /**
8
+ * `skrr machines dedicated ls` — list one directory on the machine.
9
+ *
10
+ * Paths are relative to /workspace and, on a guest, confined to `repos/` and
11
+ * `user-data/` — the tenant roots; the workspace root itself is the runtime's
12
+ * and a listing of it is refused `path_withheld`. Entries are sorted by the
13
+ * machine by name bytes; a symlink shows its stored target and is never
14
+ * followed; an entry the machine withholds (deny set, blockedPaths, a
15
+ * sensitive pattern, an OS permission) is shown as withheld, not hidden.
16
+ */
17
+ class DedicatedMachinesLs extends dedicated_lease_command_1.DedicatedLeaseCommand {
18
+ static summary = 'List a directory on a Dedicated Runtime machine';
19
+ static description = 'Lists one directory on the machine, one page of up to 500 entries. ' +
20
+ 'Paths are relative to /workspace and must be inside repos/ or user-data/. ' +
21
+ 'A path the machine withholds is answered as a refusal, and an entry it ' +
22
+ 'withholds is shown marked rather than hidden.';
23
+ static examples = [
24
+ '<%= config.bin %> machines dedicated ls rtl_abc123 repos/app',
25
+ '<%= config.bin %> machines dedicated ls rtl_abc123 repos/app --limit 1000 --all',
26
+ '<%= config.bin %> machines dedicated ls rtl_abc123 repos/app --json',
27
+ ];
28
+ static args = {
29
+ lease: core_1.Args.string({
30
+ description: dedicated_lease_command_1.DEDICATED_LEASE_ARG_DESCRIPTION,
31
+ required: true,
32
+ ignoreStdin: true,
33
+ }),
34
+ path: core_1.Args.string({
35
+ description: 'Directory on the machine, relative to /workspace (inside repos/ or user-data/)',
36
+ required: true,
37
+ ignoreStdin: true,
38
+ }),
39
+ };
40
+ static flags = {
41
+ limit: core_1.Flags.integer({ description: 'Entries per page (at most 2000)' }),
42
+ cursor: core_1.Flags.string({ description: 'Continue the listing from a nextCursor' }),
43
+ all: core_1.Flags.boolean({ description: 'Follow the cursor until the directory is listed whole' }),
44
+ json: core_1.Flags.boolean({ description: 'Output the result as JSON' }),
45
+ };
46
+ async run() {
47
+ this.requireAuth();
48
+ const { args, flags } = await this.parse(DedicatedMachinesLs);
49
+ const leaseId = await this.resolveLeaseArg(args.lease);
50
+ const scope = this.scopeFrom(flags);
51
+ const entries = [];
52
+ let listedPath = args.path;
53
+ let nextCursor;
54
+ try {
55
+ // Once: every page of this listing is read from the same machine.
56
+ const generation = await (0, computer_files_1.resolveDedicatedFileGeneration)(leaseId, scope);
57
+ let cursor = flags.cursor;
58
+ do {
59
+ const page = await (0, computer_files_1.listComputerFiles)(leaseId, {
60
+ path: args.path,
61
+ generation,
62
+ ...(cursor ? { cursor } : {}),
63
+ ...(flags.limit !== undefined ? { limit: flags.limit } : {}),
64
+ }, scope);
65
+ listedPath = page.path;
66
+ entries.push(...page.entries);
67
+ cursor = page.nextCursor;
68
+ nextCursor = page.nextCursor;
69
+ } while (flags.all && cursor);
70
+ }
71
+ catch (err) {
72
+ const failure = (0, computer_files_1.describeComputerFileFailure)(err, { bin: this.config.bin, leaseId });
73
+ if (failure)
74
+ this.failWithCliError({ ...failure, exit: 1 });
75
+ this.handleApiError(err);
76
+ }
77
+ if (flags.json) {
78
+ this.log(JSON.stringify({ path: listedPath, entries, ...(nextCursor ? { nextCursor } : {}) }, null, 2));
79
+ return;
80
+ }
81
+ this.log(`${listedPath} — ${entries.length} entr${entries.length === 1 ? 'y' : 'ies'}`);
82
+ (0, format_1.renderTable)(entries.map((entry) => ({
83
+ type: (0, format_1.formatCell)(entry.withheld ? 'withheld' : entry.type),
84
+ mode: (0, format_1.formatCell)(entry.withheld ? '-' : (0, computer_files_1.computerFileModeString)(entry.type, entry.mode)),
85
+ size: (0, format_1.formatCell)(entry.withheld ? '-' : (0, computer_files_1.formatComputerFileSize)(entry.size)),
86
+ modified: (0, format_1.formatCell)(entry.withheld ? '-' : (0, format_1.localStamp)(entry.mtimeMs)),
87
+ name: (0, format_1.formatCell)((0, computer_files_1.computerFileEntryName)(entry)),
88
+ })), [
89
+ { key: 'type', header: 'TYPE' },
90
+ { key: 'mode', header: 'MODE' },
91
+ { key: 'size', header: 'SIZE' },
92
+ { key: 'modified', header: 'MODIFIED' },
93
+ { key: 'name', header: 'NAME', verbatim: true },
94
+ ], (line) => this.log(line));
95
+ if (nextCursor) {
96
+ this.log(`More entries: --cursor ${nextCursor} (or --all to list the whole directory).`);
97
+ }
98
+ }
99
+ }
100
+ exports.default = DedicatedMachinesLs;
@@ -0,0 +1,18 @@
1
+ import { DedicatedLeaseCommand } from '../../../lib/dedicated-lease-command';
2
+ /**
3
+ * `skrr machines dedicated mkdir` — create a directory on the machine, missing
4
+ * parents included (`mkdir -p` semantics; the machine makes the chain).
5
+ */
6
+ export default class DedicatedMachinesMkdir extends DedicatedLeaseCommand {
7
+ static summary: string;
8
+ static description: string;
9
+ static examples: string[];
10
+ static args: {
11
+ lease: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
12
+ path: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
13
+ };
14
+ static flags: {
15
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
16
+ };
17
+ run(): Promise<void>;
18
+ }
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const dedicated_lease_command_1 = require("../../../lib/dedicated-lease-command");
5
+ const computer_files_1 = require("../../../lib/computer-files");
6
+ /**
7
+ * `skrr machines dedicated mkdir` — create a directory on the machine, missing
8
+ * parents included (`mkdir -p` semantics; the machine makes the chain).
9
+ */
10
+ class DedicatedMachinesMkdir extends dedicated_lease_command_1.DedicatedLeaseCommand {
11
+ static summary = 'Create a directory on a Dedicated Runtime machine';
12
+ static description = 'Creates the directory and any missing parents, as the workload user, inside ' +
13
+ 'repos/ or user-data/. The tenant roots themselves and a path that already ' +
14
+ 'exists are refused.';
15
+ static examples = [
16
+ '<%= config.bin %> machines dedicated mkdir rtl_abc123 repos/app/dist',
17
+ '<%= config.bin %> machines dedicated mkdir rtl_abc123 user-data/notes --json',
18
+ ];
19
+ static args = {
20
+ lease: core_1.Args.string({
21
+ description: dedicated_lease_command_1.DEDICATED_LEASE_ARG_DESCRIPTION,
22
+ required: true,
23
+ ignoreStdin: true,
24
+ }),
25
+ path: core_1.Args.string({
26
+ description: 'Directory to create, relative to /workspace (inside repos/ or user-data/)',
27
+ required: true,
28
+ ignoreStdin: true,
29
+ }),
30
+ };
31
+ static flags = {
32
+ json: core_1.Flags.boolean({ description: 'Output the result as JSON' }),
33
+ };
34
+ async run() {
35
+ this.requireAuth();
36
+ const { args, flags } = await this.parse(DedicatedMachinesMkdir);
37
+ const leaseId = await this.resolveLeaseArg(args.lease);
38
+ let result;
39
+ try {
40
+ const scope = this.scopeFrom(flags);
41
+ const generation = await (0, computer_files_1.resolveDedicatedFileGeneration)(leaseId, scope);
42
+ result = await (0, computer_files_1.mkdirComputerFile)(leaseId, { path: args.path, generation }, scope);
43
+ }
44
+ catch (err) {
45
+ const failure = (0, computer_files_1.describeComputerFileFailure)(err, { bin: this.config.bin, leaseId });
46
+ if (failure)
47
+ this.failWithCliError({ ...failure, exit: 1 });
48
+ this.handleApiError(err);
49
+ }
50
+ if (flags.json) {
51
+ this.log(JSON.stringify(result, null, 2));
52
+ return;
53
+ }
54
+ this.log(`Created ${result.path}`);
55
+ }
56
+ }
57
+ exports.default = DedicatedMachinesMkdir;
@@ -0,0 +1,24 @@
1
+ import { DedicatedLeaseCommand } from '../../../lib/dedicated-lease-command';
2
+ /**
3
+ * `skrr machines dedicated mv` — rename or move one path on the machine.
4
+ *
5
+ * `--tag` is the optimistic-concurrency fence (design §6.3): the tag `stat`
6
+ * prints for the source. When the source changed since that read the move is
7
+ * refused `file_changed` and the refusal carries the current tag — it is never
8
+ * silently applied over the version you did not see.
9
+ */
10
+ export default class DedicatedMachinesMv extends DedicatedLeaseCommand {
11
+ static summary: string;
12
+ static description: string;
13
+ static examples: string[];
14
+ static args: {
15
+ lease: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
16
+ from: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
17
+ to: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
18
+ };
19
+ static flags: {
20
+ tag: 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
+ }
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const core_1 = require("@oclif/core");
4
+ const dedicated_lease_command_1 = require("../../../lib/dedicated-lease-command");
5
+ const computer_files_1 = require("../../../lib/computer-files");
6
+ /**
7
+ * `skrr machines dedicated mv` — rename or move one path on the machine.
8
+ *
9
+ * `--tag` is the optimistic-concurrency fence (design §6.3): the tag `stat`
10
+ * prints for the source. When the source changed since that read the move is
11
+ * refused `file_changed` and the refusal carries the current tag — it is never
12
+ * silently applied over the version you did not see.
13
+ */
14
+ class DedicatedMachinesMv extends dedicated_lease_command_1.DedicatedLeaseCommand {
15
+ static summary = 'Rename or move a path on a Dedicated Runtime machine';
16
+ static description = 'Moves or renames one path inside repos/ or user-data/. --tag takes the tag ' +
17
+ '`stat` prints for the source and refuses the move if the path changed ' +
18
+ 'since; without it the move is unconditional.';
19
+ static examples = [
20
+ '<%= config.bin %> machines dedicated mv rtl_abc123 repos/app/old repos/app/new',
21
+ '<%= config.bin %> machines dedicated mv rtl_abc123 user-data/draft.md user-data/sent/draft.md',
22
+ '<%= config.bin %> machines dedicated mv rtl_abc123 repos/a repos/b --tag 12345:3182:1761234567890000000',
23
+ ];
24
+ static args = {
25
+ lease: core_1.Args.string({
26
+ description: dedicated_lease_command_1.DEDICATED_LEASE_ARG_DESCRIPTION,
27
+ required: true,
28
+ ignoreStdin: true,
29
+ }),
30
+ from: core_1.Args.string({
31
+ description: 'Existing path on the machine, relative to /workspace',
32
+ required: true,
33
+ ignoreStdin: true,
34
+ }),
35
+ to: core_1.Args.string({
36
+ description: 'Where it goes, relative to /workspace',
37
+ required: true,
38
+ ignoreStdin: true,
39
+ }),
40
+ };
41
+ static flags = {
42
+ tag: core_1.Flags.string({
43
+ description: 'Refuse unless the source still has this tag — the <inode>:<size>:<mtimeNs> `stat` prints',
44
+ }),
45
+ json: core_1.Flags.boolean({ description: 'Output the result as JSON' }),
46
+ };
47
+ async run() {
48
+ this.requireAuth();
49
+ const { args, flags } = await this.parse(DedicatedMachinesMv);
50
+ const leaseId = await this.resolveLeaseArg(args.lease);
51
+ let tag;
52
+ if (flags.tag !== undefined) {
53
+ try {
54
+ tag = (0, computer_files_1.parseComputerFileTag)(flags.tag);
55
+ }
56
+ catch (err) {
57
+ this.error(err.message, { exit: 2 });
58
+ }
59
+ }
60
+ let result;
61
+ try {
62
+ const scope = this.scopeFrom(flags);
63
+ const generation = await (0, computer_files_1.resolveDedicatedFileGeneration)(leaseId, scope);
64
+ result = await (0, computer_files_1.moveComputerFile)(leaseId, { from: args.from, to: args.to, generation, ...(tag ? { tag } : {}) }, scope);
65
+ }
66
+ catch (err) {
67
+ const failure = (0, computer_files_1.describeComputerFileFailure)(err, {
68
+ bin: this.config.bin,
69
+ leaseId,
70
+ takesTag: true,
71
+ });
72
+ if (failure)
73
+ this.failWithCliError({ ...failure, exit: 1 });
74
+ this.handleApiError(err);
75
+ }
76
+ if (flags.json) {
77
+ this.log(JSON.stringify(result, null, 2));
78
+ return;
79
+ }
80
+ this.log(`Moved ${args.from} → ${result.path}`);
81
+ }
82
+ }
83
+ exports.default = DedicatedMachinesMv;
@@ -0,0 +1,26 @@
1
+ import { DedicatedLeaseCommand } from '../../../lib/dedicated-lease-command';
2
+ /**
3
+ * `skrr machines dedicated rm` — delete one path on the machine.
4
+ *
5
+ * As `rm` does: a directory needs --recursive and is refused `not_empty`
6
+ * without it. `--tag` is the optimistic-concurrency fence — the tag `stat`
7
+ * prints; a file that changed since that read is refused `file_changed`, so a
8
+ * scripted delete never removes a version it never saw. For `--recursive` the
9
+ * tag must be the folder's CONTENTS tag (`stat --contents`): anything changed
10
+ * inside the folder since is refused. `--recursive` without `--tag` is unfenced.
11
+ */
12
+ export default class DedicatedMachinesRm extends DedicatedLeaseCommand {
13
+ static summary: string;
14
+ static description: string;
15
+ static examples: string[];
16
+ static args: {
17
+ lease: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
18
+ path: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
19
+ };
20
+ static flags: {
21
+ recursive: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
22
+ tag: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
23
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
24
+ };
25
+ run(): Promise<void>;
26
+ }