@skrr-ai/cli 0.1.86 → 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 (103) hide show
  1. package/bin/run.js +11 -0
  2. package/dist/base-command.js +1 -0
  3. package/dist/commands/agents/chat.d.ts +58 -1
  4. package/dist/commands/agents/chat.js +206 -4
  5. package/dist/commands/computer/index.d.ts +19 -0
  6. package/dist/commands/computer/index.js +37 -0
  7. package/dist/commands/labels/create.d.ts +1 -0
  8. package/dist/commands/labels/create.js +2 -0
  9. package/dist/commands/labels/restore.d.ts +1 -0
  10. package/dist/commands/labels/restore.js +6 -3
  11. package/dist/commands/labels/update.d.ts +1 -0
  12. package/dist/commands/labels/update.js +2 -0
  13. package/dist/commands/machines/computer-adoption.d.ts +15 -0
  14. package/dist/commands/machines/computer-adoption.js +33 -0
  15. package/dist/commands/machines/dedicated/archive.d.ts +26 -0
  16. package/dist/commands/machines/dedicated/archive.js +113 -0
  17. package/dist/commands/machines/dedicated/audit.d.ts +25 -0
  18. package/dist/commands/machines/dedicated/audit.js +113 -0
  19. package/dist/commands/machines/dedicated/computer.d.ts +23 -0
  20. package/dist/commands/machines/dedicated/computer.js +64 -0
  21. package/dist/commands/machines/dedicated/cp.d.ts +2 -0
  22. package/dist/commands/machines/dedicated/cp.js +74 -2
  23. package/dist/commands/machines/dedicated/git-status.d.ts +15 -0
  24. package/dist/commands/machines/dedicated/git-status.js +56 -0
  25. package/dist/commands/machines/dedicated/index.js +15 -1
  26. package/dist/commands/machines/dedicated/ls.d.ts +27 -0
  27. package/dist/commands/machines/dedicated/ls.js +100 -0
  28. package/dist/commands/machines/dedicated/mkdir.d.ts +18 -0
  29. package/dist/commands/machines/dedicated/mkdir.js +57 -0
  30. package/dist/commands/machines/dedicated/mv.d.ts +24 -0
  31. package/dist/commands/machines/dedicated/mv.js +83 -0
  32. package/dist/commands/machines/dedicated/rm.d.ts +26 -0
  33. package/dist/commands/machines/dedicated/rm.js +100 -0
  34. package/dist/commands/machines/dedicated/search.d.ts +24 -0
  35. package/dist/commands/machines/dedicated/search.js +78 -0
  36. package/dist/commands/machines/dedicated/stat.d.ts +22 -0
  37. package/dist/commands/machines/dedicated/stat.js +92 -0
  38. package/dist/commands/machines/hosted/index.js +1 -1
  39. package/dist/commands/machines/hosted/list.js +1 -1
  40. package/dist/commands/machines/hosted/start.js +1 -1
  41. package/dist/commands/machines/services/declare.d.ts +24 -0
  42. package/dist/commands/machines/services/declare.js +73 -0
  43. package/dist/commands/machines/services/index.d.ts +15 -0
  44. package/dist/commands/machines/services/index.js +31 -0
  45. package/dist/commands/machines/services/ls.d.ts +17 -0
  46. package/dist/commands/machines/services/ls.js +60 -0
  47. package/dist/commands/machines/services/withdraw.d.ts +19 -0
  48. package/dist/commands/machines/services/withdraw.js +47 -0
  49. package/dist/commands/machines/share.d.ts +29 -0
  50. package/dist/commands/machines/share.js +100 -0
  51. package/dist/commands/machines/shared.d.ts +19 -0
  52. package/dist/commands/machines/shared.js +62 -0
  53. package/dist/commands/machines/shares.d.ts +16 -0
  54. package/dist/commands/machines/shares.js +69 -0
  55. package/dist/commands/machines/unshare.d.ts +19 -0
  56. package/dist/commands/machines/unshare.js +61 -0
  57. package/dist/commands/tasks/labels/create.d.ts +1 -0
  58. package/dist/commands/tasks/labels/create.js +3 -0
  59. package/dist/commands/views/create.d.ts +1 -0
  60. package/dist/commands/views/create.js +5 -0
  61. package/dist/lib/agent-home-workspace.d.ts +26 -0
  62. package/dist/lib/agent-home-workspace.js +174 -0
  63. package/dist/lib/agentic-stream.d.ts +135 -0
  64. package/dist/lib/agentic-stream.js +341 -6
  65. package/dist/lib/auth-storage.d.ts +4 -0
  66. package/dist/lib/auth-storage.js +33 -0
  67. package/dist/lib/computer-adoption.d.ts +55 -0
  68. package/dist/lib/computer-adoption.js +67 -0
  69. package/dist/lib/computer-consent.d.ts +13 -0
  70. package/dist/lib/computer-consent.js +33 -0
  71. package/dist/lib/computer-files.d.ts +239 -0
  72. package/dist/lib/computer-files.js +707 -0
  73. package/dist/lib/dedicated-copy.d.ts +45 -9
  74. package/dist/lib/dedicated-copy.js +141 -44
  75. package/dist/lib/dedicated-machines.d.ts +49 -0
  76. package/dist/lib/dedicated-machines.js +97 -6
  77. package/dist/lib/keychain.d.ts +1 -0
  78. package/dist/lib/keychain.js +67 -14
  79. package/dist/lib/label-scope.d.ts +12 -0
  80. package/dist/lib/label-scope.js +15 -1
  81. package/dist/lib/machine-audit.d.ts +34 -0
  82. package/dist/lib/machine-audit.js +50 -0
  83. package/dist/lib/machine-grants.d.ts +70 -0
  84. package/dist/lib/machine-grants.js +47 -0
  85. package/dist/lib/machine-services.d.ts +64 -0
  86. package/dist/lib/machine-services.js +60 -0
  87. package/dist/lib/refresh.d.ts +7 -0
  88. package/dist/lib/refresh.js +2 -1
  89. package/dist/lib/task-view-render.d.ts +2 -0
  90. package/dist/lib/task-view-render.js +1 -1
  91. package/dist/lib/views/vocabulary.d.ts +1 -1
  92. package/dist/lib/views/vocabulary.js +2 -1
  93. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/computerWire.d.ts +955 -0
  94. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/computerWire.js +1070 -0
  95. package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/daemonToolApproval.js +7 -0
  96. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/computerWire.d.ts +955 -0
  97. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/computerWire.js +1051 -0
  98. package/dist/node_modules/@skrr-ai/auth-core/dist/esm/daemonToolApproval.js +7 -0
  99. package/dist/node_modules/@skrr-ai/auth-core/package.json +11 -1
  100. package/dist/node_modules/@skrr-ai/data-provider/index.js +22143 -20728
  101. package/dist/node_modules/@skrr-ai/data-provider/package.json +1 -1
  102. package/oclif.manifest.json +18855 -17260
  103. package/package.json +2 -2
@@ -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
+ }
@@ -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 computer_files_1 = require("../../../lib/computer-files");
6
+ /**
7
+ * `skrr machines dedicated rm` — delete one path on the machine.
8
+ *
9
+ * As `rm` does: a directory needs --recursive and is refused `not_empty`
10
+ * without it. `--tag` is the optimistic-concurrency fence — the tag `stat`
11
+ * prints; a file that changed since that read is refused `file_changed`, so a
12
+ * scripted delete never removes a version it never saw. For `--recursive` the
13
+ * tag must be the folder's CONTENTS tag (`stat --contents`): anything changed
14
+ * inside the folder since is refused. `--recursive` without `--tag` is unfenced.
15
+ */
16
+ class DedicatedMachinesRm extends dedicated_lease_command_1.DedicatedLeaseCommand {
17
+ static summary = 'Delete a file or folder on a Dedicated Runtime machine';
18
+ static description = 'Deletes one path inside repos/ or user-data/, as the workload user. A ' +
19
+ 'folder needs --recursive and is refused without it. --tag takes the tag ' +
20
+ '`stat` prints and refuses the delete when the path changed since. With ' +
21
+ "--recursive, --tag must be the folder's contents tag from `stat --contents` " +
22
+ '(inode:size:mtimeNs:contents), and the delete is refused if anything inside ' +
23
+ 'the folder changed since; --recursive without --tag deletes whatever the ' +
24
+ 'folder holds at that moment (unfenced). There is no trash: a deleted path is gone.';
25
+ static examples = [
26
+ '<%= config.bin %> machines dedicated rm rtl_abc123 user-data/notes/draft.md',
27
+ '<%= config.bin %> machines dedicated rm rtl_abc123 repos/app/dist --recursive',
28
+ '<%= config.bin %> machines dedicated rm rtl_abc123 repos/app/lock --tag 12345:3182:1761234567890000000',
29
+ '<%= config.bin %> machines dedicated rm rtl_abc123 repos/app/dist --recursive --tag <tag from `stat --contents`>',
30
+ ];
31
+ static args = {
32
+ lease: core_1.Args.string({
33
+ description: dedicated_lease_command_1.DEDICATED_LEASE_ARG_DESCRIPTION,
34
+ required: true,
35
+ ignoreStdin: true,
36
+ }),
37
+ path: core_1.Args.string({
38
+ description: 'Path to delete, relative to /workspace (inside repos/ or user-data/)',
39
+ required: true,
40
+ ignoreStdin: true,
41
+ }),
42
+ };
43
+ static flags = {
44
+ recursive: core_1.Flags.boolean({
45
+ char: 'r',
46
+ description: 'Delete a folder and everything in it',
47
+ }),
48
+ tag: core_1.Flags.string({
49
+ description: 'Refuse unless the path still has this tag — the <inode>:<size>:<mtimeNs> `stat` prints; with --recursive, the <inode>:<size>:<mtimeNs>:<contents> tag `stat --contents` prints',
50
+ }),
51
+ json: core_1.Flags.boolean({ description: 'Output the result as JSON' }),
52
+ };
53
+ async run() {
54
+ this.requireAuth();
55
+ const { args, flags } = await this.parse(DedicatedMachinesRm);
56
+ const leaseId = await this.resolveLeaseArg(args.lease);
57
+ let tag;
58
+ if (flags.tag !== undefined) {
59
+ try {
60
+ tag = (0, computer_files_1.parseComputerFileTag)(flags.tag);
61
+ }
62
+ catch (err) {
63
+ this.error(err.message, { exit: 2 });
64
+ }
65
+ // Said here rather than spent on a round trip the server would refuse
66
+ // (`contents_tag_required`): a folder's own tag covers only its direct
67
+ // entries, which is not what a recursive delete erases.
68
+ if (flags.recursive === true && tag?.contents === undefined) {
69
+ this.error(`--recursive --tag needs the folder's contents tag, which covers everything inside it. Read it with \`${this.config.bin} machines dedicated stat ${leaseId} ${args.path} --contents\` and pass that tag.`, { exit: 2 });
70
+ }
71
+ }
72
+ let result;
73
+ try {
74
+ const scope = this.scopeFrom(flags);
75
+ const generation = await (0, computer_files_1.resolveDedicatedFileGeneration)(leaseId, scope);
76
+ result = await (0, computer_files_1.deleteComputerFile)(leaseId, {
77
+ path: args.path,
78
+ generation,
79
+ ...(tag ? { tag } : {}),
80
+ recursive: flags.recursive === true,
81
+ }, scope);
82
+ }
83
+ catch (err) {
84
+ const failure = (0, computer_files_1.describeComputerFileFailure)(err, {
85
+ bin: this.config.bin,
86
+ leaseId,
87
+ takesTag: true,
88
+ });
89
+ if (failure)
90
+ this.failWithCliError({ ...failure, exit: 1 });
91
+ this.handleApiError(err);
92
+ }
93
+ if (flags.json) {
94
+ this.log(JSON.stringify({ ...result, deleted: true }, null, 2));
95
+ return;
96
+ }
97
+ this.log(`Deleted ${result.path}`);
98
+ }
99
+ }
100
+ exports.default = DedicatedMachinesRm;
@@ -0,0 +1,24 @@
1
+ import { DedicatedLeaseCommand } from '../../../lib/dedicated-lease-command';
2
+ /**
3
+ * `skrr machines dedicated search` — find files by name, or text inside them,
4
+ * under one folder. Guest-only today; the answer states whether it is whole.
5
+ */
6
+ export default class DedicatedMachinesSearch 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
+ query: import("@oclif/core/lib/interfaces").OptionFlag<string, import("@oclif/core/lib/interfaces").CustomOptions>;
16
+ content: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
17
+ 'no-ignore': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
18
+ 'case-sensitive': import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
19
+ limit: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
20
+ 'budget-ms': import("@oclif/core/lib/interfaces").OptionFlag<number | 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,78 @@
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 search` — find files by name, or text inside them,
8
+ * under one folder. Guest-only today; the answer states whether it is whole.
9
+ */
10
+ class DedicatedMachinesSearch extends dedicated_lease_command_1.DedicatedLeaseCommand {
11
+ static summary = 'Search a folder on a Dedicated Runtime machine';
12
+ static description = 'Finds files by name, or with --content lines containing the text, under one folder. ' +
13
+ '.gitignore is honoured unless --no-ignore. The search is bounded: it stops at the result ' +
14
+ 'limit or at a time bound, and says which — a truncated or "still searching" answer is ' +
15
+ 'never printed as complete. Available on dedicated machines, not on a personal machine.';
16
+ static examples = [
17
+ '<%= config.bin %> machines dedicated search rtl_abc123 repos/app --query package.json',
18
+ '<%= config.bin %> machines dedicated search rtl_abc123 repos/app --query TODO --content --limit 50',
19
+ '<%= config.bin %> machines dedicated search rtl_abc123 repos/app --query dist --no-ignore --json',
20
+ ];
21
+ static args = {
22
+ lease: core_1.Args.string({
23
+ description: dedicated_lease_command_1.DEDICATED_LEASE_ARG_DESCRIPTION,
24
+ required: true,
25
+ ignoreStdin: true,
26
+ }),
27
+ path: core_1.Args.string({
28
+ description: 'Folder to search under, relative to /workspace (inside repos/ or user-data/)',
29
+ required: true,
30
+ ignoreStdin: true,
31
+ }),
32
+ };
33
+ static flags = {
34
+ query: core_1.Flags.string({
35
+ description: 'Text to look for (one line, at most 200 characters)',
36
+ required: true,
37
+ }),
38
+ content: core_1.Flags.boolean({ description: 'Search inside files instead of file names' }),
39
+ 'no-ignore': core_1.Flags.boolean({ description: 'Also search what .gitignore excludes' }),
40
+ 'case-sensitive': core_1.Flags.boolean({ description: 'Match case exactly' }),
41
+ limit: core_1.Flags.integer({ description: 'Most results to return (at most 1000)' }),
42
+ 'budget-ms': core_1.Flags.integer({ description: 'Time bound in milliseconds (at most 20000)' }),
43
+ json: core_1.Flags.boolean({ description: 'Output the result as JSON' }),
44
+ };
45
+ async run() {
46
+ this.requireAuth();
47
+ const { args, flags } = await this.parse(DedicatedMachinesSearch);
48
+ const leaseId = await this.resolveLeaseArg(args.lease);
49
+ let result;
50
+ try {
51
+ const scope = this.scopeFrom(flags);
52
+ const generation = await (0, computer_files_1.resolveDedicatedFileGeneration)(leaseId, scope);
53
+ result = await (0, computer_files_1.searchComputerFiles)(leaseId, {
54
+ path: args.path,
55
+ generation,
56
+ query: flags.query,
57
+ content: flags.content,
58
+ ...(flags['no-ignore'] ? { respectIgnore: false } : {}),
59
+ caseSensitive: flags['case-sensitive'],
60
+ ...(flags.limit !== undefined ? { limit: flags.limit } : {}),
61
+ ...(flags['budget-ms'] !== undefined ? { budgetMs: flags['budget-ms'] } : {}),
62
+ }, scope);
63
+ }
64
+ catch (err) {
65
+ const failure = (0, computer_files_1.describeComputerFileFailure)(err, { bin: this.config.bin, leaseId });
66
+ if (failure)
67
+ this.failWithCliError({ ...failure, exit: 1 });
68
+ this.handleApiError(err);
69
+ }
70
+ if (flags.json) {
71
+ this.log(JSON.stringify(result, null, 2));
72
+ return;
73
+ }
74
+ for (const line of (0, computer_files_1.computerFileSearchLines)(result))
75
+ this.log(line);
76
+ }
77
+ }
78
+ exports.default = DedicatedMachinesSearch;
@@ -0,0 +1,22 @@
1
+ import type { ComputerFileStatResult } from '@skrr-ai/data-provider';
2
+ import { DedicatedLeaseCommand } from '../../../lib/dedicated-lease-command';
3
+ /** The `stat` read-out, as lines. Pure so a spec can pin it. */
4
+ export declare function computerFileStatLines(result: ComputerFileStatResult): string[];
5
+ /**
6
+ * `skrr machines dedicated stat` — one path's facts, including the entity tag
7
+ * a `mv`/`rm`/`file_changed` retry presents.
8
+ */
9
+ export default class DedicatedMachinesStat extends DedicatedLeaseCommand {
10
+ static summary: string;
11
+ static description: string;
12
+ static examples: string[];
13
+ static args: {
14
+ lease: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
15
+ path: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
16
+ };
17
+ static flags: {
18
+ contents: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
19
+ json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
20
+ };
21
+ run(): Promise<void>;
22
+ }
@@ -0,0 +1,92 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.computerFileStatLines = computerFileStatLines;
4
+ const core_1 = require("@oclif/core");
5
+ const dedicated_lease_command_1 = require("../../../lib/dedicated-lease-command");
6
+ const computer_files_1 = require("../../../lib/computer-files");
7
+ /** The `stat` read-out, as lines. Pure so a spec can pin it. */
8
+ function computerFileStatLines(result) {
9
+ const { entry } = result;
10
+ const lines = [entry.path];
11
+ const row = (label, value) => {
12
+ if (value === undefined || value === null || value === '')
13
+ return;
14
+ lines.push(` ${`${label} `.padEnd(12)}${value}`);
15
+ };
16
+ row('type', entry.type);
17
+ row('size', `${entry.size} bytes`);
18
+ row('modified', Number.isFinite(entry.mtimeMs) ? new Date(entry.mtimeMs).toISOString() : undefined);
19
+ row('mode', `${entry.mode.toString(8).padStart(4, '0')} (${(0, computer_files_1.computerFileModeString)(entry.type, entry.mode)})`);
20
+ row('link target', entry.linkTarget);
21
+ if (entry.withheld) {
22
+ row('withheld', `${entry.withheld.reason}${entry.withheld.rule ? ` (${entry.withheld.rule})` : ''}`);
23
+ }
24
+ // `--contents` on a folder: how much a fenced `rm -r --tag` would erase.
25
+ if (result.entries !== undefined) {
26
+ row('contains', `${result.entries} entr${result.entries === 1 ? 'y' : 'ies'}, at every depth`);
27
+ }
28
+ // The tag is what `--tag` on mv and rm takes back, spelled the same way — for
29
+ // a folder read with --contents, with its contents digest as a fourth part.
30
+ row('tag', result.tag ? (0, computer_files_1.computerFileTagString)(result.tag) : undefined);
31
+ return lines;
32
+ }
33
+ /**
34
+ * `skrr machines dedicated stat` — one path's facts, including the entity tag
35
+ * a `mv`/`rm`/`file_changed` retry presents.
36
+ */
37
+ class DedicatedMachinesStat extends dedicated_lease_command_1.DedicatedLeaseCommand {
38
+ static summary = 'Show one path on a Dedicated Runtime machine, with its tag';
39
+ static description = 'Type, size, mtime, mode and link target of one path on the machine, plus its entity tag, ' +
40
+ 'the optimistic-concurrency token --tag on `mv` and `rm` (and --if-tag on `cp`) accepts. ' +
41
+ 'With --contents, a folder is also walked: its tag gains a fourth part, a digest of everything ' +
42
+ 'inside it, and the entry count is shown — the tag `rm --recursive --tag` needs, so a fenced ' +
43
+ 'recursive delete can only erase what you were shown. A path the machine withholds is answered ' +
44
+ 'as a refusal.';
45
+ static examples = [
46
+ '<%= config.bin %> machines dedicated stat rtl_abc123 repos/app/package.json',
47
+ '<%= config.bin %> machines dedicated stat rtl_abc123 repos/app --json',
48
+ '<%= config.bin %> machines dedicated stat rtl_abc123 repos/app/dist --contents',
49
+ ];
50
+ static args = {
51
+ lease: core_1.Args.string({
52
+ description: dedicated_lease_command_1.DEDICATED_LEASE_ARG_DESCRIPTION,
53
+ required: true,
54
+ ignoreStdin: true,
55
+ }),
56
+ path: core_1.Args.string({
57
+ description: 'Path on the machine, relative to /workspace',
58
+ required: true,
59
+ ignoreStdin: true,
60
+ }),
61
+ };
62
+ static flags = {
63
+ contents: core_1.Flags.boolean({
64
+ description: 'For a folder: walk it and show its contents tag and entry count (for `rm --recursive --tag`)',
65
+ }),
66
+ json: core_1.Flags.boolean({ description: 'Output the result as JSON' }),
67
+ };
68
+ async run() {
69
+ this.requireAuth();
70
+ const { args, flags } = await this.parse(DedicatedMachinesStat);
71
+ const leaseId = await this.resolveLeaseArg(args.lease);
72
+ let result;
73
+ try {
74
+ const scope = this.scopeFrom(flags);
75
+ const generation = await (0, computer_files_1.resolveDedicatedFileGeneration)(leaseId, scope);
76
+ result = await (0, computer_files_1.statComputerFile)(leaseId, { path: args.path, generation, ...(flags.contents ? { contents: true } : {}) }, scope);
77
+ }
78
+ catch (err) {
79
+ const failure = (0, computer_files_1.describeComputerFileFailure)(err, { bin: this.config.bin, leaseId });
80
+ if (failure)
81
+ this.failWithCliError({ ...failure, exit: 1 });
82
+ this.handleApiError(err);
83
+ }
84
+ if (flags.json) {
85
+ this.log(JSON.stringify(result, null, 2));
86
+ return;
87
+ }
88
+ for (const line of computerFileStatLines(result))
89
+ this.log(line);
90
+ }
91
+ }
92
+ exports.default = DedicatedMachinesStat;
@@ -14,7 +14,7 @@ class Machines extends core_1.Command {
14
14
  '<%= config.bin %> machines hosted connect <machine-id>',
15
15
  ];
16
16
  async run() {
17
- this.log('skrr Hosted Machine commands:');
17
+ this.log('Skrr Hosted Machine commands:');
18
18
  this.log(' skrr machines hosted start start a hosted machine');
19
19
  this.log(' skrr machines hosted list list Hosted Machine sessions');
20
20
  this.log(' skrr machines hosted status show machine status');
@@ -6,7 +6,7 @@ const api_fetch_1 = require("../../../lib/api-fetch");
6
6
  const format_1 = require("../../../lib/format");
7
7
  const hosted_machines_1 = require("../../../lib/hosted-machines");
8
8
  class HostedMachinesList extends base_command_1.BaseCommand {
9
- static description = 'List skrr Hosted Machine sessions';
9
+ static description = 'List Skrr Hosted Machine sessions';
10
10
  static examples = [
11
11
  '<%= config.bin %> machines hosted list',
12
12
  '<%= config.bin %> machines hosted list --workspace <workspace-id>',