codify-plugin-lib 1.0.181 → 1.0.182-beta10

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 (46) hide show
  1. package/dist/index.d.ts +4 -1
  2. package/dist/index.js +4 -1
  3. package/dist/plugin/plugin.js +5 -2
  4. package/dist/pty/background-pty.d.ts +1 -0
  5. package/dist/pty/background-pty.js +17 -6
  6. package/dist/pty/index.d.ts +19 -1
  7. package/dist/pty/seqeuntial-pty.d.ts +17 -0
  8. package/dist/pty/seqeuntial-pty.js +117 -0
  9. package/dist/resource/parsed-resource-settings.d.ts +3 -1
  10. package/dist/resource/parsed-resource-settings.js +4 -6
  11. package/dist/resource/resource-settings.d.ts +5 -1
  12. package/dist/resource/resource-settings.js +1 -1
  13. package/dist/test.d.ts +1 -0
  14. package/dist/test.js +5 -0
  15. package/dist/utils/file-utils.d.ts +16 -0
  16. package/dist/utils/file-utils.js +172 -0
  17. package/dist/utils/functions.d.ts +12 -0
  18. package/dist/utils/functions.js +74 -0
  19. package/dist/utils/index.d.ts +26 -0
  20. package/dist/utils/index.js +111 -0
  21. package/dist/utils/internal-utils.d.ts +12 -0
  22. package/dist/utils/internal-utils.js +74 -0
  23. package/dist/utils/verbosity-level.d.ts +5 -0
  24. package/dist/utils/verbosity-level.js +9 -0
  25. package/package.json +2 -2
  26. package/src/index.ts +4 -1
  27. package/src/plan/plan.test.ts +6 -1
  28. package/src/plugin/plugin.test.ts +11 -2
  29. package/src/plugin/plugin.ts +5 -2
  30. package/src/pty/background-pty.ts +18 -6
  31. package/src/pty/index.test.ts +7 -4
  32. package/src/pty/index.ts +20 -2
  33. package/src/pty/seqeuntial-pty.ts +148 -0
  34. package/src/pty/sequential-pty.test.ts +179 -0
  35. package/src/resource/parsed-resource-settings.ts +8 -7
  36. package/src/resource/resource-controller-stateful-mode.test.ts +2 -1
  37. package/src/resource/resource-controller.test.ts +22 -4
  38. package/src/resource/resource-settings.test.ts +29 -2
  39. package/src/resource/resource-settings.ts +13 -2
  40. package/src/utils/file-utils.test.ts +7 -0
  41. package/src/utils/file-utils.ts +216 -0
  42. package/src/utils/{utils.ts → functions.ts} +0 -16
  43. package/src/utils/index.ts +144 -0
  44. package/src/utils/{utils.test.ts → internal-utils.test.ts} +1 -1
  45. package/src/utils/test-utils.test.ts +5 -2
  46. package/src/utils/verbosity-level.ts +11 -0
@@ -0,0 +1,111 @@
1
+ import os from 'node:os';
2
+ import path from 'node:path';
3
+ export function isDebug() {
4
+ return process.env.DEBUG != null && process.env.DEBUG.includes('codify'); // TODO: replace with debug library
5
+ }
6
+ export var Shell;
7
+ (function (Shell) {
8
+ Shell["ZSH"] = "zsh";
9
+ Shell["BASH"] = "bash";
10
+ Shell["SH"] = "sh";
11
+ Shell["KSH"] = "ksh";
12
+ Shell["CSH"] = "csh";
13
+ Shell["FISH"] = "fish";
14
+ })(Shell || (Shell = {}));
15
+ export const Utils = {
16
+ getUser() {
17
+ return os.userInfo().username;
18
+ },
19
+ getSystemInfo() {
20
+ return {
21
+ os: os.type(),
22
+ shell: this.getShell(),
23
+ };
24
+ },
25
+ isMacOS() {
26
+ return os.platform() === 'darwin';
27
+ },
28
+ isLinux() {
29
+ return os.platform() === 'linux';
30
+ },
31
+ getShell() {
32
+ const shell = process.env.SHELL || '';
33
+ if (shell.endsWith('bash')) {
34
+ return Shell.BASH;
35
+ }
36
+ if (shell.endsWith('zsh')) {
37
+ return Shell.ZSH;
38
+ }
39
+ if (shell.endsWith('sh')) {
40
+ return Shell.SH;
41
+ }
42
+ if (shell.endsWith('csh')) {
43
+ return Shell.CSH;
44
+ }
45
+ if (shell.endsWith('ksh')) {
46
+ return Shell.KSH;
47
+ }
48
+ if (shell.endsWith('fish')) {
49
+ return Shell.FISH;
50
+ }
51
+ return undefined;
52
+ },
53
+ getPrimaryShellRc() {
54
+ return this.getShellRcFiles()[0];
55
+ },
56
+ getShellRcFiles() {
57
+ const shell = process.env.SHELL || '';
58
+ const homeDir = os.homedir();
59
+ if (shell.endsWith('bash')) {
60
+ // Linux typically uses .bashrc, macOS uses .bash_profile
61
+ if (Utils.isLinux()) {
62
+ return [
63
+ path.join(homeDir, '.bashrc'),
64
+ path.join(homeDir, '.bash_profile'),
65
+ path.join(homeDir, '.profile'),
66
+ ];
67
+ }
68
+ return [
69
+ path.join(homeDir, '.bash_profile'),
70
+ path.join(homeDir, '.bashrc'),
71
+ path.join(homeDir, '.profile'),
72
+ ];
73
+ }
74
+ if (shell.endsWith('zsh')) {
75
+ return [
76
+ path.join(homeDir, '.zshrc'),
77
+ path.join(homeDir, '.zprofile'),
78
+ path.join(homeDir, '.zshenv'),
79
+ ];
80
+ }
81
+ if (shell.endsWith('sh')) {
82
+ return [
83
+ path.join(homeDir, '.profile'),
84
+ ];
85
+ }
86
+ if (shell.endsWith('ksh')) {
87
+ return [
88
+ path.join(homeDir, '.profile'),
89
+ path.join(homeDir, '.kshrc'),
90
+ ];
91
+ }
92
+ if (shell.endsWith('csh')) {
93
+ return [
94
+ path.join(homeDir, '.cshrc'),
95
+ path.join(homeDir, '.login'),
96
+ path.join(homeDir, '.logout'),
97
+ ];
98
+ }
99
+ if (shell.endsWith('fish')) {
100
+ return [
101
+ path.join(homeDir, '.config/fish/config.fish'),
102
+ ];
103
+ }
104
+ // Default to bash-style files
105
+ return [
106
+ path.join(homeDir, '.bashrc'),
107
+ path.join(homeDir, '.bash_profile'),
108
+ path.join(homeDir, '.profile'),
109
+ ];
110
+ },
111
+ };
@@ -0,0 +1,12 @@
1
+ import { ResourceConfig, StringIndexedObject } from 'codify-schemas';
2
+ export declare function splitUserConfig<T extends StringIndexedObject>(config: ResourceConfig & T): {
3
+ parameters: T;
4
+ coreParameters: ResourceConfig;
5
+ };
6
+ export declare function setsEqual(set1: Set<unknown>, set2: Set<unknown>): boolean;
7
+ export declare function untildify(pathWithTilde: string): string;
8
+ export declare function tildify(pathWithTilde: string): string;
9
+ export declare function resolvePathWithVariables(pathWithVariables: string): string;
10
+ export declare function addVariablesToPath(pathWithoutVariables: string): string;
11
+ export declare function unhome(pathWithHome: string): string;
12
+ export declare function areArraysEqual(isElementEqual: ((desired: unknown, current: unknown) => boolean) | undefined, desired: unknown, current: unknown): boolean;
@@ -0,0 +1,74 @@
1
+ import os from 'node:os';
2
+ import path from 'node:path';
3
+ export function splitUserConfig(config) {
4
+ const coreParameters = {
5
+ type: config.type,
6
+ ...(config.name ? { name: config.name } : {}),
7
+ ...(config.dependsOn ? { dependsOn: config.dependsOn } : {}),
8
+ };
9
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
10
+ const { type, name, dependsOn, ...parameters } = config;
11
+ return {
12
+ parameters: parameters,
13
+ coreParameters,
14
+ };
15
+ }
16
+ export function setsEqual(set1, set2) {
17
+ return set1.size === set2.size && [...set1].every((v) => set2.has(v));
18
+ }
19
+ const homeDirectory = os.homedir();
20
+ export function untildify(pathWithTilde) {
21
+ return homeDirectory ? pathWithTilde.replace(/^~(?=$|\/|\\)/, homeDirectory) : pathWithTilde;
22
+ }
23
+ export function tildify(pathWithTilde) {
24
+ return homeDirectory ? pathWithTilde.replace(homeDirectory, '~') : pathWithTilde;
25
+ }
26
+ export function resolvePathWithVariables(pathWithVariables) {
27
+ // @ts-expect-error Ignore this for now
28
+ return pathWithVariables.replace(/\$([A-Z_]+[A-Z0-9_]*)|\${([A-Z0-9_]*)}/ig, (_, a, b) => process.env[a || b]);
29
+ }
30
+ export function addVariablesToPath(pathWithoutVariables) {
31
+ let result = pathWithoutVariables;
32
+ for (const [key, value] of Object.entries(process.env)) {
33
+ if (!value || !path.isAbsolute(value) || value === '/' || key === 'HOME' || key === 'PATH' || key === 'SHELL' || key === 'PWD') {
34
+ continue;
35
+ }
36
+ result = result.replaceAll(value, `$${key}`);
37
+ }
38
+ return result;
39
+ }
40
+ export function unhome(pathWithHome) {
41
+ return pathWithHome.includes('$HOME') ? pathWithHome.replaceAll('$HOME', os.homedir()) : pathWithHome;
42
+ }
43
+ export function areArraysEqual(isElementEqual, desired, current) {
44
+ if (!desired || !current) {
45
+ return false;
46
+ }
47
+ if (!Array.isArray(desired) || !Array.isArray(current)) {
48
+ throw new Error(`A non-array value:
49
+
50
+ Desired: ${JSON.stringify(desired, null, 2)}
51
+
52
+ Current: ${JSON.stringify(desired, null, 2)}
53
+
54
+ Was provided even though type array was specified.
55
+ `);
56
+ }
57
+ if (desired.length !== current.length) {
58
+ return false;
59
+ }
60
+ const desiredCopy = [...desired];
61
+ const currentCopy = [...current];
62
+ // Algorithm for to check equality between two un-ordered; un-hashable arrays using
63
+ // an isElementEqual method. Time: O(n^2)
64
+ for (let counter = desiredCopy.length - 1; counter >= 0; counter--) {
65
+ const idx = currentCopy.findIndex((e2) => (isElementEqual
66
+ ?? ((a, b) => a === b))(desiredCopy[counter], e2));
67
+ if (idx === -1) {
68
+ return false;
69
+ }
70
+ desiredCopy.splice(counter, 1);
71
+ currentCopy.splice(idx, 1);
72
+ }
73
+ return currentCopy.length === 0;
74
+ }
@@ -0,0 +1,5 @@
1
+ export declare const VerbosityLevel: {
2
+ level: number;
3
+ get(): number;
4
+ set(level: number): void;
5
+ };
@@ -0,0 +1,9 @@
1
+ export const VerbosityLevel = new class {
2
+ level = 0;
3
+ get() {
4
+ return this.level;
5
+ }
6
+ set(level) {
7
+ this.level = level;
8
+ }
9
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codify-plugin-lib",
3
- "version": "1.0.181",
3
+ "version": "1.0.182-beta10",
4
4
  "description": "Library plugin library",
5
5
  "main": "dist/index.js",
6
6
  "typings": "dist/index.d.ts",
@@ -22,7 +22,7 @@
22
22
  "ajv": "^8.12.0",
23
23
  "ajv-formats": "^2.1.1",
24
24
  "clean-deep": "^3.4.0",
25
- "codify-schemas": "1.0.83",
25
+ "codify-schemas": "1.0.86-beta5",
26
26
  "lodash.isequal": "^4.5.0",
27
27
  "nanoid": "^5.0.9",
28
28
  "strip-ansi": "^7.1.0",
package/src/index.ts CHANGED
@@ -12,7 +12,10 @@ export * from './resource/parsed-resource-settings.js';
12
12
  export * from './resource/resource.js'
13
13
  export * from './resource/resource-settings.js'
14
14
  export * from './stateful-parameter/stateful-parameter.js'
15
- export * from './utils/utils.js'
15
+ export * from './utils/file-utils.js'
16
+ export * from './utils/functions.js'
17
+ export * from './utils/index.js'
18
+ export * from './utils/verbosity-level.js'
16
19
 
17
20
  export async function runPlugin(plugin: Plugin) {
18
21
  const messageHandler = new MessageHandler(plugin);
@@ -1,6 +1,6 @@
1
1
  import { describe, expect, it } from 'vitest';
2
2
  import { Plan } from './plan.js';
3
- import { ParameterOperation, ResourceOperation } from 'codify-schemas';
3
+ import { OS, ParameterOperation, ResourceOperation } from 'codify-schemas';
4
4
  import { TestConfig, TestResource } from '../utils/test-utils.test.js';
5
5
  import { ResourceController } from '../resource/resource-controller.js';
6
6
  import { ParsedResourceSettings } from '../resource/parsed-resource-settings.js';
@@ -152,6 +152,7 @@ describe('Plan entity tests', () => {
152
152
  getSettings(): ResourceSettings<any> {
153
153
  return {
154
154
  id: 'type',
155
+ operatingSystems: [OS.Darwin],
155
156
  parameterSettings: {
156
157
  propZ: { type: 'array', isElementEqual: (a, b) => b.includes(a) }
157
158
  }
@@ -184,6 +185,7 @@ describe('Plan entity tests', () => {
184
185
  getSettings(): ResourceSettings<any> {
185
186
  return {
186
187
  id: 'type',
188
+ operatingSystems: [OS.Darwin],
187
189
  parameterSettings: {
188
190
  propZ: {
189
191
  type: 'array',
@@ -236,6 +238,7 @@ describe('Plan entity tests', () => {
236
238
  getSettings(): ResourceSettings<TestConfig> {
237
239
  return {
238
240
  id: 'type',
241
+ operatingSystems: [OS.Darwin],
239
242
  parameterSettings: {
240
243
  propA: { type: 'string' },
241
244
  propB: { type: 'string', canModify: true },
@@ -289,6 +292,7 @@ describe('Plan entity tests', () => {
289
292
  getSettings(): ResourceSettings<TestConfig> {
290
293
  return {
291
294
  id: 'type',
295
+ operatingSystems: [OS.Darwin],
292
296
  parameterSettings: {
293
297
  propA: { type: 'string' },
294
298
  propB: { type: 'string', canModify: true },
@@ -351,6 +355,7 @@ function createTestResource() {
351
355
  getSettings(): ResourceSettings<TestConfig> {
352
356
  return {
353
357
  id: 'type',
358
+ operatingSystems: [OS.Darwin],
354
359
  parameterSettings: {
355
360
  propA: {
356
361
  default: 'defaultA'
@@ -1,6 +1,6 @@
1
1
  import { describe, expect, it } from 'vitest';
2
2
  import { Plugin } from './plugin.js';
3
- import { ApplyRequestData, ParameterOperation, ResourceOperation, StringIndexedObject } from 'codify-schemas';
3
+ import { ApplyRequestData, OS, ParameterOperation, ResourceOperation, StringIndexedObject } from 'codify-schemas';
4
4
  import { Resource } from '../resource/resource.js';
5
5
  import { Plan } from '../plan/plan.js';
6
6
  import { spy } from 'sinon';
@@ -17,7 +17,8 @@ interface TestConfig extends StringIndexedObject {
17
17
  class TestResource extends Resource<TestConfig> {
18
18
  getSettings(): ResourceSettings<TestConfig> {
19
19
  return {
20
- id: 'testResource'
20
+ id: 'testResource',
21
+ operatingSystems: [OS.Darwin],
21
22
  };
22
23
  }
23
24
 
@@ -154,6 +155,7 @@ describe('Plugin tests', () => {
154
155
  getSettings(): ResourceSettings<TestConfig> {
155
156
  return {
156
157
  id: 'typeId',
158
+ operatingSystems: [OS.Darwin],
157
159
  schema,
158
160
  }
159
161
  }
@@ -192,6 +194,7 @@ describe('Plugin tests', () => {
192
194
  getSettings(): ResourceSettings<TestConfig> {
193
195
  return {
194
196
  id: 'typeId',
197
+ operatingSystems: [OS.Darwin],
195
198
  schema,
196
199
  importAndDestroy: {
197
200
  requiredParameters: []
@@ -285,6 +288,7 @@ describe('Plugin tests', () => {
285
288
  getSettings(): ResourceSettings<TestConfig> {
286
289
  return {
287
290
  id: 'type',
291
+ operatingSystems: [OS.Darwin],
288
292
  schema: {
289
293
  '$schema': 'http://json-schema.org/draft-07/schema',
290
294
  '$id': 'https://www.codifycli.com/ssh-config.json',
@@ -330,6 +334,7 @@ describe('Plugin tests', () => {
330
334
  getSettings(): ResourceSettings<TestConfig> {
331
335
  return {
332
336
  ...super.getSettings(),
337
+ operatingSystems: [OS.Darwin],
333
338
  allowMultiple: {
334
339
  identifyingParameters: ['path', 'paths']
335
340
  }
@@ -351,6 +356,7 @@ describe('Plugin tests', () => {
351
356
  getSettings(): ResourceSettings<TestConfig> {
352
357
  return {
353
358
  ...super.getSettings(),
359
+ operatingSystems: [OS.Darwin],
354
360
  parameterSettings: {
355
361
  path: { type: 'directory' },
356
362
  paths: { type: 'array', itemType: 'directory' }
@@ -407,6 +413,7 @@ describe('Plugin tests', () => {
407
413
  getSettings(): ResourceSettings<TestConfig> {
408
414
  return {
409
415
  id: 'ssh-config',
416
+ operatingSystems: [OS.Darwin],
410
417
  parameterSettings: {
411
418
  hosts: { type: 'stateful', definition: new TestStatefulParameter() }
412
419
  },
@@ -454,6 +461,7 @@ describe('Plugin tests', () => {
454
461
  getSettings(): ResourceSettings<TestConfig> {
455
462
  return {
456
463
  id: 'ssh-config',
464
+ operatingSystems: [OS.Darwin],
457
465
  allowMultiple: true
458
466
  }
459
467
  }
@@ -476,6 +484,7 @@ describe('Plugin tests', () => {
476
484
  getSettings(): ResourceSettings<TestConfig> {
477
485
  return {
478
486
  id: 'ssh-config',
487
+ operatingSystems: [OS.Darwin],
479
488
  }
480
489
  }
481
490
  })
@@ -21,10 +21,11 @@ import { ApplyValidationError } from '../common/errors.js';
21
21
  import { Plan } from '../plan/plan.js';
22
22
  import { BackgroundPty } from '../pty/background-pty.js';
23
23
  import { getPty } from '../pty/index.js';
24
+ import { SequentialPty } from '../pty/seqeuntial-pty.js';
24
25
  import { Resource } from '../resource/resource.js';
25
26
  import { ResourceController } from '../resource/resource-controller.js';
26
27
  import { ptyLocalStorage } from '../utils/pty-local-storage.js';
27
- import { VerbosityLevel } from '../utils/utils.js';
28
+ import { VerbosityLevel } from '../utils/verbosity-level.js';
28
29
 
29
30
  export class Plugin {
30
31
  planStorage: Map<string, Plan<any>>;
@@ -75,6 +76,7 @@ export class Plugin {
75
76
  dependencies: r.dependencies,
76
77
  type: r.typeId,
77
78
  sensitiveParameters,
79
+ operatingSystems: r.settings.operatingSystems,
78
80
  }
79
81
  })
80
82
  }
@@ -121,6 +123,7 @@ export class Plugin {
121
123
  import: {
122
124
  requiredParameters: requiredPropertyNames,
123
125
  },
126
+ operatingSystems: resource.settings.operatingSystems,
124
127
  sensitiveParameters,
125
128
  allowMultiple
126
129
  }
@@ -232,7 +235,7 @@ export class Plugin {
232
235
  throw new Error('Malformed plan with resource that cannot be found');
233
236
  }
234
237
 
235
- await resource.apply(plan);
238
+ await ptyLocalStorage.run(new SequentialPty(), async () => resource.apply(plan))
236
239
 
237
240
  // Validate using desired/desired. If the apply was successful, no changes should be reported back.
238
241
  // Default back desired back to current if it is not defined (for destroys only)
@@ -6,7 +6,8 @@ import * as fs from 'node:fs/promises';
6
6
  import stripAnsi from 'strip-ansi';
7
7
 
8
8
  import { debugLog } from '../utils/debug.js';
9
- import { VerbosityLevel } from '../utils/utils.js';
9
+ import { Shell, Utils } from '../utils/index.js';
10
+ import { VerbosityLevel } from '../utils/verbosity-level.js';
10
11
  import { IPty, SpawnError, SpawnOptions, SpawnResult } from './index.js';
11
12
  import { PromiseQueue } from './promise-queue.js';
12
13
 
@@ -19,8 +20,10 @@ EventEmitter.defaultMaxListeners = 1000;
19
20
  * without a tty (or even a stdin) attached so interactive commands will not work.
20
21
  */
21
22
  export class BackgroundPty implements IPty {
23
+ private historyIgnore = Utils.getShell() === Shell.ZSH ? { HISTORY_IGNORE: '*' } : { HISTIGNORE: '*' };
22
24
  private basePty = pty.spawn(this.getDefaultShell(), ['-i'], {
23
- env: process.env, name: nanoid(6),
25
+ env: { ...process.env, ...this.historyIgnore },
26
+ name: nanoid(6),
24
27
  handleFlowControl: true
25
28
  });
26
29
 
@@ -128,9 +131,18 @@ export class BackgroundPty implements IPty {
128
131
 
129
132
  return new Promise(resolve => {
130
133
  // zsh-specific commands
131
- if (this.getDefaultShell() === 'zsh') {
132
- this.basePty.write('setopt hist_ignore_space;\n');
133
- }
134
+ // switch (Utils.getShell()) {
135
+ // case Shell.ZSH: {
136
+ // this.basePty.write('setopt HIST_NO_STORE;\n');
137
+ // break;
138
+ // }
139
+ //
140
+ // default: {
141
+ // this.basePty.write('export HISTIGNORE=\'history*\';\n');
142
+ // break;
143
+ // }
144
+ // }
145
+
134
146
  this.basePty.write(' unset PS1;\n');
135
147
  this.basePty.write(' unset PS0;\n')
136
148
  this.basePty.write(' echo setup complete\\"\n')
@@ -147,6 +159,6 @@ export class BackgroundPty implements IPty {
147
159
  }
148
160
 
149
161
  private getDefaultShell(): string {
150
- return process.platform === 'darwin' ? 'zsh' : 'bash';
162
+ return process.env.SHELL!;
151
163
  }
152
164
  }
@@ -3,8 +3,9 @@ import { TestConfig, TestResource } from '../utils/test-utils.test.js';
3
3
  import { getPty, IPty } from './index.js';
4
4
  import { Plugin } from '../plugin/plugin.js'
5
5
  import { CreatePlan } from '../plan/plan-types.js';
6
- import { ResourceOperation } from 'codify-schemas';
6
+ import { OS, ResourceOperation } from 'codify-schemas';
7
7
  import { ResourceSettings } from '../resource/resource-settings.js';
8
+ import { SequentialPty } from './seqeuntial-pty.js';
8
9
 
9
10
  describe('General tests for PTYs', () => {
10
11
  it('Can get pty within refresh', async () => {
@@ -45,7 +46,8 @@ describe('General tests for PTYs', () => {
45
46
  const testResource1 = new class extends TestResource {
46
47
  getSettings(): ResourceSettings<TestConfig> {
47
48
  return {
48
- id: 'type1'
49
+ id: 'type1',
50
+ operatingSystems: [OS.Darwin],
49
51
  }
50
52
  }
51
53
 
@@ -64,6 +66,7 @@ describe('General tests for PTYs', () => {
64
66
  getSettings(): ResourceSettings<TestConfig> {
65
67
  return {
66
68
  id: 'type2',
69
+ operatingSystems: [OS.Darwin],
67
70
  }
68
71
  }
69
72
 
@@ -103,11 +106,11 @@ describe('General tests for PTYs', () => {
103
106
  expect(pty1).to.eq(pty2);
104
107
  })
105
108
 
106
- it('Currently pty not available for apply', async () => {
109
+ it('Sequential pty should be available for applies', async () => {
107
110
  const testResource = new class extends TestResource {
108
111
  create(plan: CreatePlan<TestConfig>): Promise<void> {
109
112
  const $ = getPty();
110
- expect($).to.be.undefined;
113
+ expect($).to.instanceof(SequentialPty)
111
114
  }
112
115
  }
113
116
 
package/src/pty/index.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { ptyLocalStorage } from '../utils/pty-local-storage.js';
2
2
 
3
3
  export interface SpawnResult {
4
- status: 'success' | 'error';
4
+ status: 'error' | 'success';
5
5
  exitCode: number;
6
6
  data: string;
7
7
  }
@@ -11,9 +11,27 @@ export enum SpawnStatus {
11
11
  ERROR = 'error',
12
12
  }
13
13
 
14
+ /**
15
+ * Represents the configuration options for spawning a child process.
16
+ *
17
+ * @interface SpawnOptions
18
+ *
19
+ * @property {string} [cwd] - Specifies the working directory of the child process.
20
+ * If not provided, the current working directory of the parent process is used.
21
+ *
22
+ * @property {Record<string, unknown>} [env] - Defines environment key-value pairs
23
+ * that will be available to the child process. If not specified, the child process
24
+ * will inherit the environment variables of the parent process.
25
+ *
26
+ * @property {boolean} [interactive] - Indicates whether the spawned process needs
27
+ * to be interactive. Only works within apply (not plan). Defaults to true.
28
+ */
14
29
  export interface SpawnOptions {
15
30
  cwd?: string;
16
- env?: Record<string, unknown>,
31
+ env?: Record<string, unknown>;
32
+ interactive?: boolean;
33
+ requiresRoot?: boolean;
34
+ stdin?: boolean;
17
35
  }
18
36
 
19
37
  export class SpawnError extends Error {