@xano/cli 0.0.26 → 0.0.27

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 (110) hide show
  1. package/dist/base-command.d.ts +3 -1
  2. package/dist/base-command.js +12 -5
  3. package/dist/commands/auth/index.d.ts +21 -0
  4. package/dist/commands/auth/index.js +533 -0
  5. package/dist/commands/branch/create/index.d.ts +17 -0
  6. package/dist/commands/branch/create/index.js +164 -0
  7. package/dist/commands/branch/delete/index.d.ts +18 -0
  8. package/dist/commands/branch/delete/index.js +156 -0
  9. package/dist/commands/branch/edit/index.d.ts +19 -0
  10. package/dist/commands/branch/edit/index.js +166 -0
  11. package/dist/commands/branch/get/index.d.ts +16 -0
  12. package/dist/commands/branch/get/index.js +135 -0
  13. package/dist/commands/branch/list/index.d.ts +18 -0
  14. package/dist/commands/branch/list/index.js +138 -0
  15. package/dist/commands/branch/set-live/index.d.ts +18 -0
  16. package/dist/commands/branch/set-live/index.js +155 -0
  17. package/dist/commands/function/create/index.d.ts +7 -6
  18. package/dist/commands/function/create/index.js +55 -55
  19. package/dist/commands/function/edit/index.d.ts +11 -10
  20. package/dist/commands/function/edit/index.js +155 -162
  21. package/dist/commands/function/get/index.d.ts +6 -5
  22. package/dist/commands/function/get/index.js +55 -60
  23. package/dist/commands/function/list/index.d.ts +6 -5
  24. package/dist/commands/function/list/index.js +52 -52
  25. package/dist/commands/profile/create/index.d.ts +6 -6
  26. package/dist/commands/profile/create/index.js +37 -37
  27. package/dist/commands/profile/delete/index.d.ts +2 -2
  28. package/dist/commands/profile/delete/index.js +9 -9
  29. package/dist/commands/profile/edit/index.d.ts +8 -7
  30. package/dist/commands/profile/edit/index.js +48 -48
  31. package/dist/commands/profile/get-default/index.js +1 -1
  32. package/dist/commands/profile/list/index.d.ts +2 -2
  33. package/dist/commands/profile/list/index.js +9 -9
  34. package/dist/commands/profile/me/index.d.ts +4 -3
  35. package/dist/commands/profile/me/index.js +21 -21
  36. package/dist/commands/profile/project/index.js +1 -1
  37. package/dist/commands/profile/set-default/index.js +1 -1
  38. package/dist/commands/profile/token/index.js +1 -1
  39. package/dist/commands/profile/wizard/index.d.ts +5 -4
  40. package/dist/commands/profile/wizard/index.js +142 -108
  41. package/dist/commands/run/env/delete/index.d.ts +3 -2
  42. package/dist/commands/run/env/delete/index.js +10 -10
  43. package/dist/commands/run/env/get/index.d.ts +3 -2
  44. package/dist/commands/run/env/get/index.js +11 -11
  45. package/dist/commands/run/env/list/index.d.ts +3 -2
  46. package/dist/commands/run/env/list/index.js +17 -19
  47. package/dist/commands/run/env/set/index.d.ts +3 -2
  48. package/dist/commands/run/env/set/index.js +5 -5
  49. package/dist/commands/run/exec/index.d.ts +19 -8
  50. package/dist/commands/run/exec/index.js +186 -108
  51. package/dist/commands/run/info/index.d.ts +5 -4
  52. package/dist/commands/run/info/index.js +27 -27
  53. package/dist/commands/run/projects/create/index.d.ts +4 -3
  54. package/dist/commands/run/projects/create/index.js +23 -23
  55. package/dist/commands/run/projects/delete/index.d.ts +3 -2
  56. package/dist/commands/run/projects/delete/index.js +10 -10
  57. package/dist/commands/run/projects/list/index.d.ts +3 -2
  58. package/dist/commands/run/projects/list/index.js +12 -12
  59. package/dist/commands/run/projects/update/index.d.ts +4 -3
  60. package/dist/commands/run/projects/update/index.js +21 -21
  61. package/dist/commands/run/secrets/delete/index.d.ts +3 -2
  62. package/dist/commands/run/secrets/delete/index.js +10 -10
  63. package/dist/commands/run/secrets/get/index.d.ts +3 -2
  64. package/dist/commands/run/secrets/get/index.js +11 -11
  65. package/dist/commands/run/secrets/list/index.d.ts +3 -2
  66. package/dist/commands/run/secrets/list/index.js +22 -24
  67. package/dist/commands/run/secrets/set/index.d.ts +4 -3
  68. package/dist/commands/run/secrets/set/index.js +16 -16
  69. package/dist/commands/run/sessions/delete/index.d.ts +3 -2
  70. package/dist/commands/run/sessions/delete/index.js +10 -10
  71. package/dist/commands/run/sessions/get/index.d.ts +3 -2
  72. package/dist/commands/run/sessions/get/index.js +11 -11
  73. package/dist/commands/run/sessions/list/index.d.ts +3 -2
  74. package/dist/commands/run/sessions/list/index.js +11 -11
  75. package/dist/commands/run/sessions/start/index.d.ts +3 -2
  76. package/dist/commands/run/sessions/start/index.js +11 -11
  77. package/dist/commands/run/sessions/stop/index.d.ts +3 -2
  78. package/dist/commands/run/sessions/stop/index.js +11 -11
  79. package/dist/commands/run/sink/get/index.d.ts +3 -2
  80. package/dist/commands/run/sink/get/index.js +11 -11
  81. package/dist/commands/static_host/build/create/index.d.ts +5 -4
  82. package/dist/commands/static_host/build/create/index.js +33 -33
  83. package/dist/commands/static_host/build/get/index.d.ts +5 -4
  84. package/dist/commands/static_host/build/get/index.js +20 -20
  85. package/dist/commands/static_host/build/list/index.d.ts +4 -3
  86. package/dist/commands/static_host/build/list/index.js +31 -31
  87. package/dist/commands/static_host/list/index.d.ts +4 -3
  88. package/dist/commands/static_host/list/index.js +31 -31
  89. package/dist/commands/workspace/create/index.d.ts +14 -0
  90. package/dist/commands/workspace/create/index.js +131 -0
  91. package/dist/commands/workspace/delete/index.d.ts +20 -0
  92. package/dist/commands/workspace/delete/index.js +141 -0
  93. package/dist/commands/workspace/edit/index.d.ts +22 -0
  94. package/dist/commands/workspace/edit/index.js +176 -0
  95. package/dist/commands/workspace/get/index.d.ts +18 -0
  96. package/dist/commands/workspace/get/index.js +136 -0
  97. package/dist/commands/workspace/list/index.d.ts +3 -2
  98. package/dist/commands/workspace/list/index.js +15 -15
  99. package/dist/commands/workspace/pull/index.d.ts +5 -4
  100. package/dist/commands/workspace/pull/index.js +113 -64
  101. package/dist/commands/workspace/push/index.d.ts +1 -0
  102. package/dist/commands/workspace/push/index.js +5 -5
  103. package/dist/help.d.ts +1 -1
  104. package/dist/lib/base-run-command.d.ts +6 -6
  105. package/dist/lib/base-run-command.js +8 -6
  106. package/dist/lib/run-http-client.d.ts +24 -18
  107. package/dist/lib/run-http-client.js +96 -61
  108. package/dist/lib/run-types.d.ts +80 -80
  109. package/oclif.manifest.json +1963 -785
  110. package/package.json +1 -1
@@ -7,16 +7,6 @@ export default class RunEnvGet extends BaseRunCommand {
7
7
  required: true,
8
8
  }),
9
9
  };
10
- static flags = {
11
- ...BaseRunCommand.baseFlags,
12
- output: Flags.string({
13
- char: 'o',
14
- description: 'Output format',
15
- required: false,
16
- default: 'value',
17
- options: ['value', 'json'],
18
- }),
19
- };
20
10
  static description = 'Get an environment variable value';
21
11
  static examples = [
22
12
  `$ xano run env get API_KEY
@@ -26,10 +16,20 @@ my-secret-api-key
26
16
  { "name": "API_KEY", "value": "my-secret-api-key" }
27
17
  `,
28
18
  ];
19
+ static flags = {
20
+ ...BaseRunCommand.baseFlags,
21
+ output: Flags.string({
22
+ char: 'o',
23
+ default: 'value',
24
+ description: 'Output format',
25
+ options: ['value', 'json'],
26
+ required: false,
27
+ }),
28
+ };
29
29
  async run() {
30
30
  const { args, flags } = await this.parse(RunEnvGet);
31
31
  // Initialize with project required
32
- await this.initRunCommandWithProject(flags.profile);
32
+ await this.initRunCommandWithProject(flags.profile, flags.verbose);
33
33
  try {
34
34
  const url = this.httpClient.buildProjectUrl('/env', { name: args.name });
35
35
  const result = await this.httpClient.get(url);
@@ -1,11 +1,12 @@
1
1
  import BaseRunCommand from '../../../../lib/base-run-command.js';
2
2
  export default class RunEnvList extends BaseRunCommand {
3
3
  static args: {};
4
+ static description: string;
5
+ static examples: string[];
4
6
  static flags: {
5
7
  output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
6
8
  profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
9
+ verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
10
  };
8
- static description: string;
9
- static examples: string[];
10
11
  run(): Promise<void>;
11
12
  }
@@ -2,16 +2,6 @@ import { Flags } from '@oclif/core';
2
2
  import BaseRunCommand from '../../../../lib/base-run-command.js';
3
3
  export default class RunEnvList extends BaseRunCommand {
4
4
  static args = {};
5
- static flags = {
6
- ...BaseRunCommand.baseFlags,
7
- output: Flags.string({
8
- char: 'o',
9
- description: 'Output format',
10
- required: false,
11
- default: 'list',
12
- options: ['list', 'json'],
13
- }),
14
- };
15
5
  static description = 'List all environment variable keys';
16
6
  static examples = [
17
7
  `$ xano run env list
@@ -24,25 +14,33 @@ Environment variables:
24
14
  { "env": ["API_KEY", "DATABASE_URL", "DEBUG"] }
25
15
  `,
26
16
  ];
17
+ static flags = {
18
+ ...BaseRunCommand.baseFlags,
19
+ output: Flags.string({
20
+ char: 'o',
21
+ default: 'list',
22
+ description: 'Output format',
23
+ options: ['list', 'json'],
24
+ required: false,
25
+ }),
26
+ };
27
27
  async run() {
28
28
  const { flags } = await this.parse(RunEnvList);
29
29
  // Initialize with project required
30
- await this.initRunCommandWithProject(flags.profile);
30
+ await this.initRunCommandWithProject(flags.profile, flags.verbose);
31
31
  try {
32
32
  const url = this.httpClient.buildProjectUrl('/env/key');
33
33
  const result = await this.httpClient.get(url);
34
34
  if (flags.output === 'json') {
35
35
  this.outputJson(result);
36
36
  }
37
+ else if (result.env.length === 0) {
38
+ this.log('No environment variables found.');
39
+ }
37
40
  else {
38
- if (result.env.length === 0) {
39
- this.log('No environment variables found.');
40
- }
41
- else {
42
- this.log('Environment variables:');
43
- for (const key of result.env) {
44
- this.log(` - ${key}`);
45
- }
41
+ this.log('Environment variables:');
42
+ for (const key of result.env) {
43
+ this.log(` - ${key}`);
46
44
  }
47
45
  }
48
46
  }
@@ -4,10 +4,11 @@ export default class RunEnvSet extends BaseRunCommand {
4
4
  name: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
5
5
  value: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
6
6
  };
7
+ static description: string;
8
+ static examples: string[];
7
9
  static flags: {
8
10
  profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
12
  };
10
- static description: string;
11
- static examples: string[];
12
13
  run(): Promise<void>;
13
14
  }
@@ -11,9 +11,6 @@ export default class RunEnvSet extends BaseRunCommand {
11
11
  required: true,
12
12
  }),
13
13
  };
14
- static flags = {
15
- ...BaseRunCommand.baseFlags,
16
- };
17
14
  static description = 'Set an environment variable';
18
15
  static examples = [
19
16
  `$ xano run env set API_KEY my-secret-key
@@ -23,16 +20,19 @@ Environment variable 'API_KEY' set successfully!
23
20
  Environment variable 'DATABASE_URL' set successfully!
24
21
  `,
25
22
  ];
23
+ static flags = {
24
+ ...BaseRunCommand.baseFlags,
25
+ };
26
26
  async run() {
27
27
  const { args, flags } = await this.parse(RunEnvSet);
28
28
  // Initialize with project required
29
- await this.initRunCommandWithProject(flags.profile);
29
+ await this.initRunCommandWithProject(flags.profile, flags.verbose);
30
30
  const input = {
31
- name: args.name,
32
31
  env: {
33
32
  name: args.name,
34
33
  value: args.value,
35
34
  },
35
+ name: args.name,
36
36
  };
37
37
  try {
38
38
  const url = this.httpClient.buildProjectUrl('/env');
@@ -1,20 +1,31 @@
1
1
  import BaseRunCommand from '../../../lib/base-run-command.js';
2
2
  export default class RunExec extends BaseRunCommand {
3
- static args: {};
3
+ static args: {
4
+ path: import("@oclif/core/interfaces").Arg<string | undefined, Record<string, unknown>>;
5
+ };
6
+ static description: string;
7
+ static examples: string[];
4
8
  static flags: {
5
- file: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
6
- stdin: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
- edit: import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
- output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
9
9
  args: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
10
+ edit: import("@oclif/core/interfaces").BooleanFlag<boolean>;
10
11
  env: import("@oclif/core/interfaces").OptionFlag<string[] | undefined, import("@oclif/core/interfaces").CustomOptions>;
12
+ file: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
13
+ output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
14
+ stdin: import("@oclif/core/interfaces").BooleanFlag<boolean>;
11
15
  profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
16
+ verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
12
17
  };
13
- static description: string;
14
- static examples: string[];
15
18
  run(): Promise<void>;
16
- private outputSummary;
19
+ /**
20
+ * Recursively collect all .xs files from a directory, sorted for deterministic ordering.
21
+ */
22
+ private collectFiles;
17
23
  private editFile;
18
24
  private isUrl;
25
+ /**
26
+ * Load all .xs files from a directory and combine them into a multidoc.
27
+ */
28
+ private loadMultidocFromDirectory;
29
+ private outputSummary;
19
30
  private readStdin;
20
31
  }
@@ -1,58 +1,28 @@
1
- import { Flags } from '@oclif/core';
1
+ import { Args, Flags } from '@oclif/core';
2
2
  import { execSync } from 'node:child_process';
3
3
  import * as fs from 'node:fs';
4
4
  import * as os from 'node:os';
5
5
  import * as path from 'node:path';
6
6
  import BaseRunCommand from '../../../lib/base-run-command.js';
7
7
  export default class RunExec extends BaseRunCommand {
8
- static args = {};
9
- static flags = {
10
- ...BaseRunCommand.baseFlags,
11
- file: Flags.string({
12
- char: 'f',
13
- description: 'Path or URL to file containing XanoScript code',
8
+ static args = {
9
+ path: Args.string({
10
+ description: 'Path to file or directory containing XanoScript code (directory creates multidoc from .xs files)',
14
11
  required: false,
15
- exclusive: ['stdin'],
16
- }),
17
- stdin: Flags.boolean({
18
- char: 's',
19
- description: 'Read XanoScript code from stdin',
20
- required: false,
21
- default: false,
22
- exclusive: ['file'],
23
- }),
24
- edit: Flags.boolean({
25
- char: 'e',
26
- description: 'Open file in editor before running (requires --file)',
27
- required: false,
28
- default: false,
29
- dependsOn: ['file'],
30
- }),
31
- output: Flags.string({
32
- char: 'o',
33
- description: 'Output format',
34
- required: false,
35
- default: 'summary',
36
- options: ['summary', 'json'],
37
- }),
38
- args: Flags.string({
39
- char: 'a',
40
- description: 'Path or URL to JSON file containing input arguments',
41
- required: false,
42
- }),
43
- env: Flags.string({
44
- description: 'Environment variable override (key=value)',
45
- required: false,
46
- multiple: true,
47
12
  }),
48
13
  };
49
14
  static description = 'Execute XanoScript code (job or service)';
50
15
  static examples = [
51
- `$ xano run exec -f script.xs
16
+ `$ xano run exec script.xs
17
+ Executed successfully!
18
+ ...
19
+ `,
20
+ `$ xano run exec ./my-workspace
21
+ # Executes all .xs files in directory as multidoc
52
22
  Executed successfully!
53
23
  ...
54
24
  `,
55
- `$ xano run exec -f script.xs --edit
25
+ `$ xano run exec script.xs --edit
56
26
  # Opens script.xs in $EDITOR, then executes
57
27
  Executed successfully!
58
28
  ...
@@ -61,45 +31,102 @@ Executed successfully!
61
31
  Executed successfully!
62
32
  ...
63
33
  `,
64
- `$ xano run exec -f script.xs -o json
34
+ `$ xano run exec script.xs -o json
65
35
  {
66
36
  "run": { ... }
67
37
  }
68
38
  `,
69
- `$ xano run exec -f script.xs -a args.json
39
+ `$ xano run exec script.xs -a args.json
70
40
  # Executes with input arguments from args.json
71
41
  Executed successfully!
72
42
  ...
73
43
  `,
74
- `$ xano run exec -f script.xs --env API_KEY=secret --env DEBUG=true
44
+ `$ xano run exec script.xs --env API_KEY=secret --env DEBUG=true
75
45
  # Executes with environment variable overrides
76
46
  Executed successfully!
77
47
  ...
78
48
  `,
79
49
  ];
50
+ static flags = {
51
+ ...BaseRunCommand.baseFlags,
52
+ args: Flags.string({
53
+ char: 'a',
54
+ description: 'Path or URL to JSON file containing input arguments',
55
+ required: false,
56
+ }),
57
+ edit: Flags.boolean({
58
+ char: 'e',
59
+ default: false,
60
+ description: 'Open file in editor before running (requires path argument or --file)',
61
+ required: false,
62
+ }),
63
+ env: Flags.string({
64
+ description: 'Environment variable override (key=value)',
65
+ multiple: true,
66
+ required: false,
67
+ }),
68
+ file: Flags.string({
69
+ char: 'f',
70
+ description: 'Path or URL to file containing XanoScript code (deprecated: use path argument instead)',
71
+ exclusive: ['stdin'],
72
+ required: false,
73
+ }),
74
+ output: Flags.string({
75
+ char: 'o',
76
+ default: 'summary',
77
+ description: 'Output format',
78
+ options: ['summary', 'json'],
79
+ required: false,
80
+ }),
81
+ stdin: Flags.boolean({
82
+ char: 's',
83
+ default: false,
84
+ description: 'Read XanoScript code from stdin',
85
+ exclusive: ['file'],
86
+ required: false,
87
+ }),
88
+ };
80
89
  async run() {
81
- const { flags } = await this.parse(RunExec);
90
+ const { args, flags } = await this.parse(RunExec);
82
91
  // Initialize with project required
83
- await this.initRunCommandWithProject(flags.profile);
92
+ await this.initRunCommandWithProject(flags.profile, flags.verbose);
93
+ // Determine input source: path argument, --file flag, or --stdin
94
+ const inputPath = args.path || flags.file;
95
+ // Validate --edit flag requirements
96
+ if (flags.edit) {
97
+ if (!inputPath) {
98
+ this.error('--edit requires a file path (either path argument or --file flag)');
99
+ }
100
+ if (this.isUrl(inputPath)) {
101
+ this.error('--edit cannot be used with URLs');
102
+ }
103
+ if (fs.existsSync(inputPath) && fs.statSync(inputPath).isDirectory()) {
104
+ this.error('--edit cannot be used with directories');
105
+ }
106
+ }
84
107
  // Read XanoScript content
85
108
  let xanoscript;
86
- if (flags.file) {
87
- if (this.isUrl(flags.file)) {
109
+ if (inputPath) {
110
+ if (this.isUrl(inputPath)) {
88
111
  // Fetch URL content
89
112
  try {
90
- const response = await fetch(flags.file);
113
+ const response = await fetch(inputPath);
91
114
  if (!response.ok) {
92
115
  this.error(`Failed to fetch URL: ${response.status} ${response.statusText}`);
93
116
  }
94
117
  xanoscript = await response.text();
95
118
  }
96
119
  catch (error) {
97
- this.error(`Failed to fetch URL '${flags.file}': ${error}`);
120
+ this.error(`Failed to fetch URL '${inputPath}': ${error}`);
98
121
  }
99
122
  }
123
+ else if (fs.existsSync(inputPath) && fs.statSync(inputPath).isDirectory()) {
124
+ // Handle directory - collect .xs files and create multidoc
125
+ xanoscript = this.loadMultidocFromDirectory(inputPath);
126
+ }
100
127
  else if (flags.edit) {
101
128
  // If edit flag is set, copy to temp file and open in editor
102
- const fileToRead = await this.editFile(flags.file);
129
+ const fileToRead = await this.editFile(inputPath);
103
130
  xanoscript = fs.readFileSync(fileToRead, 'utf8');
104
131
  // Clean up temp file
105
132
  try {
@@ -111,10 +138,10 @@ Executed successfully!
111
138
  }
112
139
  else {
113
140
  try {
114
- xanoscript = fs.readFileSync(flags.file, 'utf8');
141
+ xanoscript = fs.readFileSync(inputPath, 'utf8');
115
142
  }
116
143
  catch (error) {
117
- this.error(`Failed to read file '${flags.file}': ${error}`);
144
+ this.error(`Failed to read file '${inputPath}': ${error}`);
118
145
  }
119
146
  }
120
147
  }
@@ -127,7 +154,7 @@ Executed successfully!
127
154
  }
128
155
  }
129
156
  else {
130
- this.error('Either --file or --stdin must be specified to provide XanoScript code');
157
+ this.error('Either a path argument, --file, or --stdin must be specified to provide XanoScript code');
131
158
  }
132
159
  // Validate xanoscript is not empty
133
160
  if (!xanoscript || xanoscript.trim().length === 0) {
@@ -195,13 +222,115 @@ Executed successfully!
195
222
  }
196
223
  catch (error) {
197
224
  if (error instanceof Error) {
198
- this.error(`Failed to execute: ${error.message}`);
225
+ const xanoError = error;
226
+ if (xanoError.response) {
227
+ const responseStr = typeof xanoError.response === 'string'
228
+ ? xanoError.response
229
+ : JSON.stringify(xanoError.response, null, 2);
230
+ this.error(`Failed to execute: ${error.message}\n\n${responseStr}`);
231
+ }
232
+ else {
233
+ this.error(`Failed to execute: ${error.message}`);
234
+ }
199
235
  }
200
236
  else {
201
237
  this.error(`Failed to execute: ${String(error)}`);
202
238
  }
203
239
  }
204
240
  }
241
+ /**
242
+ * Recursively collect all .xs files from a directory, sorted for deterministic ordering.
243
+ */
244
+ collectFiles(dir) {
245
+ const files = [];
246
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
247
+ for (const entry of entries) {
248
+ const fullPath = path.join(dir, entry.name);
249
+ if (entry.isDirectory()) {
250
+ files.push(...this.collectFiles(fullPath));
251
+ }
252
+ else if (entry.isFile() && entry.name.endsWith('.xs')) {
253
+ files.push(fullPath);
254
+ }
255
+ }
256
+ return files.sort();
257
+ }
258
+ // Editor value comes from EDITOR/VISUAL environment variables, not user input
259
+ async editFile(filePath) {
260
+ const editor = process.env.EDITOR || process.env.VISUAL;
261
+ if (!editor) {
262
+ this.error('No editor configured. Please set the EDITOR or VISUAL environment variable.\n' +
263
+ 'Example: export EDITOR=vim');
264
+ }
265
+ // Validate editor executable exists
266
+ try {
267
+ execSync(`which ${editor.split(' ')[0]}`, { stdio: 'ignore' });
268
+ }
269
+ catch {
270
+ this.error(`Editor '${editor}' not found. Please set EDITOR to a valid editor.\n` +
271
+ 'Example: export EDITOR=vim');
272
+ }
273
+ // Read the original file
274
+ let originalContent;
275
+ try {
276
+ originalContent = fs.readFileSync(filePath, 'utf8');
277
+ }
278
+ catch (error) {
279
+ this.error(`Failed to read file '${filePath}': ${error}`);
280
+ }
281
+ // Create a temporary file with the same extension
282
+ const ext = path.extname(filePath);
283
+ const tmpFile = path.join(os.tmpdir(), `xano-edit-${Date.now()}${ext}`);
284
+ // Copy content to temp file
285
+ try {
286
+ fs.writeFileSync(tmpFile, originalContent, 'utf8');
287
+ }
288
+ catch (error) {
289
+ this.error(`Failed to create temporary file: ${error}`);
290
+ }
291
+ // Open the editor
292
+ try {
293
+ execSync(`${editor} ${tmpFile}`, { stdio: 'inherit' });
294
+ }
295
+ catch (error) {
296
+ try {
297
+ fs.unlinkSync(tmpFile);
298
+ }
299
+ catch {
300
+ // Ignore cleanup errors
301
+ }
302
+ this.error(`Editor exited with an error: ${error}`);
303
+ }
304
+ return tmpFile;
305
+ }
306
+ isUrl(str) {
307
+ return str.startsWith('http://') || str.startsWith('https://');
308
+ }
309
+ /**
310
+ * Load all .xs files from a directory and combine them into a multidoc.
311
+ */
312
+ loadMultidocFromDirectory(dir) {
313
+ const resolvedDir = path.resolve(dir);
314
+ if (!fs.existsSync(resolvedDir)) {
315
+ this.error(`Directory not found: ${resolvedDir}`);
316
+ }
317
+ const files = this.collectFiles(resolvedDir);
318
+ if (files.length === 0) {
319
+ this.error(`No .xs files found in ${dir}`);
320
+ }
321
+ // Read each file and join with --- separator
322
+ const documents = [];
323
+ for (const filePath of files) {
324
+ const content = fs.readFileSync(filePath, 'utf8').trim();
325
+ if (content) {
326
+ documents.push(content);
327
+ }
328
+ }
329
+ if (documents.length === 0) {
330
+ this.error(`All .xs files in ${dir} are empty`);
331
+ }
332
+ return documents.join('\n---\n');
333
+ }
205
334
  outputSummary(result) {
206
335
  this.log('Executed successfully!');
207
336
  this.log('');
@@ -216,7 +345,7 @@ Executed successfully!
216
345
  this.log(` Run ID: ${result.run.id}`);
217
346
  }
218
347
  if (result.run?.session) {
219
- const session = result.run.session;
348
+ const { session } = result.run;
220
349
  this.log(` Session ID: ${session.id}`);
221
350
  this.log(` State: ${session.state}`);
222
351
  this.log('');
@@ -224,7 +353,7 @@ Executed successfully!
224
353
  // Handle timing info
225
354
  const timing = result.run?.result || result.run?.session || result.result;
226
355
  if (timing) {
227
- const formatTime = (time) => time !== undefined ? `${(time * 1000).toFixed(2)}ms` : undefined;
356
+ const formatTime = (time) => time === undefined ? undefined : `${(time * 1000).toFixed(2)}ms`;
228
357
  const times = [
229
358
  { label: 'Total', value: formatTime(timing.total_time) },
230
359
  { label: 'Boot', value: formatTime(timing.boot_time) },
@@ -284,57 +413,6 @@ Executed successfully!
284
413
  this.log(` Error: ${result.run.session.error_msg}`);
285
414
  }
286
415
  }
287
- // Editor value comes from EDITOR/VISUAL environment variables, not user input
288
- async editFile(filePath) {
289
- const editor = process.env.EDITOR || process.env.VISUAL;
290
- if (!editor) {
291
- this.error('No editor configured. Please set the EDITOR or VISUAL environment variable.\n' +
292
- 'Example: export EDITOR=vim');
293
- }
294
- // Validate editor executable exists
295
- try {
296
- execSync(`which ${editor.split(' ')[0]}`, { stdio: 'ignore' });
297
- }
298
- catch {
299
- this.error(`Editor '${editor}' not found. Please set EDITOR to a valid editor.\n` +
300
- 'Example: export EDITOR=vim');
301
- }
302
- // Read the original file
303
- let originalContent;
304
- try {
305
- originalContent = fs.readFileSync(filePath, 'utf8');
306
- }
307
- catch (error) {
308
- this.error(`Failed to read file '${filePath}': ${error}`);
309
- }
310
- // Create a temporary file with the same extension
311
- const ext = path.extname(filePath);
312
- const tmpFile = path.join(os.tmpdir(), `xano-edit-${Date.now()}${ext}`);
313
- // Copy content to temp file
314
- try {
315
- fs.writeFileSync(tmpFile, originalContent, 'utf8');
316
- }
317
- catch (error) {
318
- this.error(`Failed to create temporary file: ${error}`);
319
- }
320
- // Open the editor
321
- try {
322
- execSync(`${editor} ${tmpFile}`, { stdio: 'inherit' });
323
- }
324
- catch (error) {
325
- try {
326
- fs.unlinkSync(tmpFile);
327
- }
328
- catch {
329
- // Ignore cleanup errors
330
- }
331
- this.error(`Editor exited with an error: ${error}`);
332
- }
333
- return tmpFile;
334
- }
335
- isUrl(str) {
336
- return str.startsWith('http://') || str.startsWith('https://');
337
- }
338
416
  async readStdin() {
339
417
  return new Promise((resolve, reject) => {
340
418
  const chunks = [];
@@ -1,16 +1,17 @@
1
1
  import BaseRunCommand from '../../../lib/base-run-command.js';
2
2
  export default class RunInfo extends BaseRunCommand {
3
3
  static args: {};
4
+ static description: string;
5
+ static examples: string[];
4
6
  static flags: {
5
7
  file: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
6
- stdin: import("@oclif/core/interfaces").BooleanFlag<boolean>;
7
8
  output: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
9
+ stdin: import("@oclif/core/interfaces").BooleanFlag<boolean>;
8
10
  profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
11
+ verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
9
12
  };
10
- static description: string;
11
- static examples: string[];
12
13
  run(): Promise<void>;
13
- private outputSummary;
14
14
  private isUrl;
15
+ private outputSummary;
15
16
  private readStdin;
16
17
  }