workos 0.15.2 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -14
- package/dist/bin.js +1449 -1261
- package/dist/bin.js.map +1 -1
- package/dist/cli.config.d.ts +1 -0
- package/dist/cli.config.js +1 -0
- package/dist/cli.config.js.map +1 -1
- package/dist/commands/api/index.js +7 -2
- package/dist/commands/api/index.js.map +1 -1
- package/dist/commands/api/interactive.js +9 -3
- package/dist/commands/api/interactive.js.map +1 -1
- package/dist/commands/debug.d.ts +2 -1
- package/dist/commands/debug.js +43 -3
- package/dist/commands/debug.js.map +1 -1
- package/dist/commands/dev.js +5 -4
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/doctor.js +13 -4
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/emulate.js +2 -2
- package/dist/commands/emulate.js.map +1 -1
- package/dist/commands/env.js +5 -4
- package/dist/commands/env.js.map +1 -1
- package/dist/commands/install-skill.js +4 -3
- package/dist/commands/install-skill.js.map +1 -1
- package/dist/commands/install.js +2 -2
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/login.js +3 -3
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/migrations.d.ts +1 -1
- package/dist/commands/migrations.js +4 -1
- package/dist/commands/migrations.js.map +1 -1
- package/dist/commands/telemetry.d.ts +3 -0
- package/dist/commands/telemetry.js +88 -0
- package/dist/commands/telemetry.js.map +1 -0
- package/dist/commands/uninstall-skill.js +3 -2
- package/dist/commands/uninstall-skill.js.map +1 -1
- package/dist/commands/vault-run.d.ts +13 -0
- package/dist/commands/vault-run.js +194 -0
- package/dist/commands/vault-run.js.map +1 -0
- package/dist/commands/vault.d.ts +3 -2
- package/dist/commands/vault.js +41 -8
- package/dist/commands/vault.js.map +1 -1
- package/dist/lib/adapters/cli-adapter.d.ts +7 -0
- package/dist/lib/adapters/cli-adapter.js +49 -0
- package/dist/lib/adapters/cli-adapter.js.map +1 -1
- package/dist/lib/adapters/dashboard-adapter.d.ts +4 -0
- package/dist/lib/adapters/dashboard-adapter.js +24 -0
- package/dist/lib/adapters/dashboard-adapter.js.map +1 -1
- package/dist/lib/adapters/headless-adapter.d.ts +6 -0
- package/dist/lib/adapters/headless-adapter.js +26 -1
- package/dist/lib/adapters/headless-adapter.js.map +1 -1
- package/dist/lib/api-error-handler.d.ts +15 -3
- package/dist/lib/api-error-handler.js +52 -34
- package/dist/lib/api-error-handler.js.map +1 -1
- package/dist/lib/command-aliases.d.ts +8 -0
- package/dist/lib/command-aliases.js +12 -0
- package/dist/lib/command-aliases.js.map +1 -0
- package/dist/lib/constants.d.ts +0 -1
- package/dist/lib/constants.js +0 -1
- package/dist/lib/constants.js.map +1 -1
- package/dist/lib/device-id.d.ts +25 -0
- package/dist/lib/device-id.js +102 -0
- package/dist/lib/device-id.js.map +1 -0
- package/dist/lib/events.d.ts +15 -0
- package/dist/lib/events.js.map +1 -1
- package/dist/lib/installer-core.d.ts +61 -1
- package/dist/lib/installer-core.js +132 -6
- package/dist/lib/installer-core.js.map +1 -1
- package/dist/lib/installer-core.types.d.ts +24 -0
- package/dist/lib/installer-core.types.js.map +1 -1
- package/dist/lib/preferences.d.ts +101 -0
- package/dist/lib/preferences.js +198 -0
- package/dist/lib/preferences.js.map +1 -0
- package/dist/lib/run-with-core.js +40 -15
- package/dist/lib/run-with-core.js.map +1 -1
- package/dist/lib/scaffold/index.d.ts +1 -0
- package/dist/lib/scaffold/index.js +2 -0
- package/dist/lib/scaffold/index.js.map +1 -0
- package/dist/lib/scaffold/scaffold.d.ts +66 -0
- package/dist/lib/scaffold/scaffold.js +156 -0
- package/dist/lib/scaffold/scaffold.js.map +1 -0
- package/dist/lib/settings.d.ts +6 -0
- package/dist/lib/settings.js +7 -0
- package/dist/lib/settings.js.map +1 -1
- package/dist/lib/telemetry-notice.d.ts +25 -0
- package/dist/lib/telemetry-notice.js +56 -0
- package/dist/lib/telemetry-notice.js.map +1 -0
- package/dist/run.d.ts +2 -2
- package/dist/run.js +2 -1
- package/dist/run.js.map +1 -1
- package/dist/test/force-insecure-storage.d.ts +1 -0
- package/dist/test/force-insecure-storage.js +9 -0
- package/dist/test/force-insecure-storage.js.map +1 -0
- package/dist/test/setup.d.ts +1 -0
- package/dist/test/setup.js +38 -0
- package/dist/test/setup.js.map +1 -0
- package/dist/utils/analytics.d.ts +41 -0
- package/dist/utils/analytics.js +199 -12
- package/dist/utils/analytics.js.map +1 -1
- package/dist/utils/box.d.ts +29 -1
- package/dist/utils/box.js +92 -4
- package/dist/utils/box.js.map +1 -1
- package/dist/utils/cli-exit.d.ts +15 -0
- package/dist/utils/cli-exit.js +11 -0
- package/dist/utils/cli-exit.js.map +1 -0
- package/dist/utils/cli-symbols.d.ts +1 -1
- package/dist/utils/command-telemetry.d.ts +17 -0
- package/dist/utils/command-telemetry.js +67 -0
- package/dist/utils/command-telemetry.js.map +1 -0
- package/dist/utils/crash-reporter.d.ts +13 -0
- package/dist/utils/crash-reporter.js +91 -0
- package/dist/utils/crash-reporter.js.map +1 -0
- package/dist/utils/debug.d.ts +1 -0
- package/dist/utils/debug.js +4 -1
- package/dist/utils/debug.js.map +1 -1
- package/dist/utils/exit-codes.d.ts +5 -0
- package/dist/utils/exit-codes.js +30 -1
- package/dist/utils/exit-codes.js.map +1 -1
- package/dist/utils/help-json.d.ts +6 -0
- package/dist/utils/help-json.js +87 -10
- package/dist/utils/help-json.js.map +1 -1
- package/dist/utils/output.d.ts +7 -2
- package/dist/utils/output.js +9 -2
- package/dist/utils/output.js.map +1 -1
- package/dist/utils/telemetry-client.d.ts +30 -2
- package/dist/utils/telemetry-client.js +122 -12
- package/dist/utils/telemetry-client.js.map +1 -1
- package/dist/utils/telemetry-store-forward.d.ts +11 -0
- package/dist/utils/telemetry-store-forward.js +94 -0
- package/dist/utils/telemetry-store-forward.js.map +1 -0
- package/dist/utils/telemetry-types.d.ts +58 -9
- package/dist/utils/telemetry-types.js.map +1 -1
- package/dist/utils/types.d.ts +10 -4
- package/dist/utils/types.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,57 +1,75 @@
|
|
|
1
1
|
import { WorkOSApiError } from './workos-api.js';
|
|
2
2
|
import { exitWithError } from '../utils/output.js';
|
|
3
|
-
|
|
4
|
-
* Duck-type check for @workos-inc/node SDK exceptions.
|
|
5
|
-
*
|
|
6
|
-
* The SDK throws typed errors (UnauthorizedException, NotFoundException, etc.)
|
|
7
|
-
* that implement the RequestException interface: { status, message, requestID }.
|
|
8
|
-
* We duck-type rather than instanceof to avoid coupling to the SDK's class hierarchy.
|
|
9
|
-
*/
|
|
10
|
-
function isSdkException(error) {
|
|
3
|
+
export function isSdkException(error) {
|
|
11
4
|
if (!(error instanceof Error))
|
|
12
5
|
return false;
|
|
13
6
|
const e = error;
|
|
14
7
|
return typeof e.status === 'number' && typeof e.requestID === 'string';
|
|
15
8
|
}
|
|
9
|
+
function normalizeApiError(error) {
|
|
10
|
+
if (error instanceof WorkOSApiError) {
|
|
11
|
+
return {
|
|
12
|
+
status: error.statusCode,
|
|
13
|
+
code: error.code,
|
|
14
|
+
errors: error.errors,
|
|
15
|
+
message: error.message,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
if (isSdkException(error)) {
|
|
19
|
+
return {
|
|
20
|
+
status: error.status,
|
|
21
|
+
code: error.code,
|
|
22
|
+
errors: error.errors,
|
|
23
|
+
message: error.message,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
function getApiErrorMessage(error, label) {
|
|
29
|
+
if (error.status === 401)
|
|
30
|
+
return 'Invalid API key. Check your environment configuration.';
|
|
31
|
+
if (error.status === 404)
|
|
32
|
+
return `${label} not found.`;
|
|
33
|
+
if (error.status === 422 && error.errors?.length)
|
|
34
|
+
return error.errors.map((e) => e.message).join(', ');
|
|
35
|
+
return error.message;
|
|
36
|
+
}
|
|
16
37
|
/**
|
|
17
38
|
* Create a resource-specific API error handler.
|
|
18
|
-
* Handles
|
|
19
|
-
*
|
|
39
|
+
* Handles raw fetch errors (WorkOSApiError), SDK exceptions, and the SDK's
|
|
40
|
+
* "errors is not iterable" TypeError from malformed 422 responses.
|
|
41
|
+
*
|
|
42
|
+
* `context` optionally names the specific resource instance (e.g. a vault
|
|
43
|
+
* object name) so 404 messages can be more specific.
|
|
20
44
|
*/
|
|
21
45
|
export function createApiErrorHandler(resourceName) {
|
|
22
|
-
return (error) => {
|
|
23
|
-
|
|
24
|
-
if (error instanceof WorkOSApiError) {
|
|
46
|
+
return (error, context) => {
|
|
47
|
+
if (error instanceof TypeError && error.message.includes('errors is not iterable')) {
|
|
25
48
|
exitWithError({
|
|
26
|
-
code:
|
|
27
|
-
message:
|
|
28
|
-
|
|
29
|
-
: error.statusCode === 404
|
|
30
|
-
? `${resourceName} not found.`
|
|
31
|
-
: error.statusCode === 422 && error.errors?.length
|
|
32
|
-
? error.errors.map((e) => e.message).join(', ')
|
|
33
|
-
: error.message,
|
|
34
|
-
details: error.errors,
|
|
49
|
+
code: 'unprocessable_entity',
|
|
50
|
+
message: `${resourceName} API rejected the request. Check that all required fields are provided.`,
|
|
51
|
+
apiContext: { resource: resourceName },
|
|
35
52
|
});
|
|
36
53
|
}
|
|
37
|
-
|
|
38
|
-
|
|
54
|
+
const label = context ? `${resourceName} '${context}'` : resourceName;
|
|
55
|
+
const apiError = normalizeApiError(error);
|
|
56
|
+
if (apiError) {
|
|
57
|
+
const code = apiError.code ?? `http_${apiError.status}`;
|
|
39
58
|
exitWithError({
|
|
40
|
-
code
|
|
41
|
-
message:
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
details: error.errors,
|
|
59
|
+
code,
|
|
60
|
+
message: getApiErrorMessage(apiError, label),
|
|
61
|
+
details: apiError.errors,
|
|
62
|
+
apiContext: {
|
|
63
|
+
status: apiError.status,
|
|
64
|
+
code,
|
|
65
|
+
resource: resourceName,
|
|
66
|
+
},
|
|
49
67
|
});
|
|
50
68
|
}
|
|
51
|
-
// 3. Fallback
|
|
52
69
|
exitWithError({
|
|
53
70
|
code: 'unknown_error',
|
|
54
71
|
message: error instanceof Error ? error.message : 'Unknown error',
|
|
72
|
+
apiContext: { resource: resourceName },
|
|
55
73
|
});
|
|
56
74
|
};
|
|
57
75
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-error-handler.js","sourceRoot":"","sources":["../../src/lib/api-error-handler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD
|
|
1
|
+
{"version":3,"file":"api-error-handler.js","sourceRoot":"","sources":["../../src/lib/api-error-handler.ts"],"names":[],"mappings":"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","sourcesContent":["import { WorkOSApiError } from './workos-api.js';\nimport { exitWithError } from '../utils/output.js';\n\nexport function isSdkException(\n error: unknown,\n): error is { status: number; message: string; requestID: string; code?: string; errors?: Array<{ message: string }> } {\n if (!(error instanceof Error)) return false;\n const e = error as Error & { status?: unknown; requestID?: unknown };\n return typeof e.status === 'number' && typeof e.requestID === 'string';\n}\n\ninterface NormalizedApiError {\n status: number;\n code?: string;\n errors?: Array<{ message: string }>;\n message: string;\n}\n\nfunction normalizeApiError(error: unknown): NormalizedApiError | null {\n if (error instanceof WorkOSApiError) {\n return {\n status: error.statusCode,\n code: error.code,\n errors: error.errors,\n message: error.message,\n };\n }\n\n if (isSdkException(error)) {\n return {\n status: error.status,\n code: error.code,\n errors: error.errors,\n message: error.message,\n };\n }\n\n return null;\n}\n\nfunction getApiErrorMessage(error: NormalizedApiError, label: string): string {\n if (error.status === 401) return 'Invalid API key. Check your environment configuration.';\n if (error.status === 404) return `${label} not found.`;\n if (error.status === 422 && error.errors?.length) return error.errors.map((e) => e.message).join(', ');\n return error.message;\n}\n\n/**\n * Create a resource-specific API error handler.\n * Handles raw fetch errors (WorkOSApiError), SDK exceptions, and the SDK's\n * \"errors is not iterable\" TypeError from malformed 422 responses.\n *\n * `context` optionally names the specific resource instance (e.g. a vault\n * object name) so 404 messages can be more specific.\n */\nexport function createApiErrorHandler(resourceName: string) {\n return (error: unknown, context?: string): never => {\n if (error instanceof TypeError && error.message.includes('errors is not iterable')) {\n exitWithError({\n code: 'unprocessable_entity',\n message: `${resourceName} API rejected the request. Check that all required fields are provided.`,\n apiContext: { resource: resourceName },\n });\n }\n\n const label = context ? `${resourceName} '${context}'` : resourceName;\n const apiError = normalizeApiError(error);\n if (apiError) {\n const code = apiError.code ?? `http_${apiError.status}`;\n exitWithError({\n code,\n message: getApiErrorMessage(apiError, label),\n details: apiError.errors,\n apiContext: {\n status: apiError.status,\n code,\n resource: resourceName,\n },\n });\n }\n\n exitWithError({\n code: 'unknown_error',\n message: error instanceof Error ? error.message : 'Unknown error',\n apiContext: { resource: resourceName },\n });\n };\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared canonical command alias map.
|
|
3
|
+
* Single source of truth for both telemetry and help-json.
|
|
4
|
+
*
|
|
5
|
+
* Keys are user-facing aliases, values are canonical command names.
|
|
6
|
+
* Adding an alias here updates both metrics aggregation and --help --json output.
|
|
7
|
+
*/
|
|
8
|
+
export declare const COMMAND_ALIASES: Record<string, string>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared canonical command alias map.
|
|
3
|
+
* Single source of truth for both telemetry and help-json.
|
|
4
|
+
*
|
|
5
|
+
* Keys are user-facing aliases, values are canonical command names.
|
|
6
|
+
* Adding an alias here updates both metrics aggregation and --help --json output.
|
|
7
|
+
*/
|
|
8
|
+
export const COMMAND_ALIASES = {
|
|
9
|
+
org: 'organization',
|
|
10
|
+
claim: 'env.claim',
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=command-aliases.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-aliases.js","sourceRoot":"","sources":["../../src/lib/command-aliases.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAA2B;IACrD,GAAG,EAAE,cAAc;IACnB,KAAK,EAAE,WAAW;CACnB,CAAC","sourcesContent":["/**\n * Shared canonical command alias map.\n * Single source of truth for both telemetry and help-json.\n *\n * Keys are user-facing aliases, values are canonical command names.\n * Adding an alias here updates both metrics aggregation and --help --json output.\n */\nexport const COMMAND_ALIASES: Record<string, string> = {\n org: 'organization',\n claim: 'env.claim',\n};\n"]}
|
package/dist/lib/constants.d.ts
CHANGED
|
@@ -26,7 +26,6 @@ export declare const WORKOS_DASHBOARD_URL: string;
|
|
|
26
26
|
export declare const ISSUES_URL: string;
|
|
27
27
|
export declare const ANALYTICS_ENABLED: boolean;
|
|
28
28
|
export declare const INSTALLER_INTERACTION_EVENT_NAME: string;
|
|
29
|
-
export declare const WORKOS_TELEMETRY_ENABLED: boolean;
|
|
30
29
|
export declare const OAUTH_PORT: number;
|
|
31
30
|
/**
|
|
32
31
|
* Common glob patterns to ignore when searching for files.
|
package/dist/lib/constants.js
CHANGED
|
@@ -18,7 +18,6 @@ export const WORKOS_DASHBOARD_URL = settings.documentation.dashboardUrl;
|
|
|
18
18
|
export const ISSUES_URL = settings.documentation.issuesUrl;
|
|
19
19
|
export const ANALYTICS_ENABLED = settings.telemetry.enabled;
|
|
20
20
|
export const INSTALLER_INTERACTION_EVENT_NAME = settings.telemetry.eventName;
|
|
21
|
-
export const WORKOS_TELEMETRY_ENABLED = process.env.WORKOS_TELEMETRY !== 'false';
|
|
22
21
|
export const OAUTH_PORT = settings.legacy.oauthPort;
|
|
23
22
|
/**
|
|
24
23
|
* Common glob patterns to ignore when searching for files.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/lib/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAS1C;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE,OAAO;IACd,aAAa,EAAE,gBAAgB;IAC/B,WAAW,EAAE,cAAc;IAC3B,SAAS,EAAE,YAAY;CACf,CAAC;AAOX,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;AAEnF,MAAM,QAAQ,GAAG,SAAS,EAAE,CAAC;AAE7B,MAAM,CAAC,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC;AAChD,MAAM,CAAC,MAAM,eAAe,GAAG,QAAQ,CAAC,aAAa,CAAC,aAAa,CAAC;AACpE,MAAM,CAAC,MAAM,oBAAoB,GAAG,QAAQ,CAAC,aAAa,CAAC,YAAY,CAAC;AACxE,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC,aAAa,CAAC,SAAS,CAAC;AAC3D,MAAM,CAAC,MAAM,iBAAiB,GAAG,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC;AAC5D,MAAM,CAAC,MAAM,gCAAgC,GAAG,QAAQ,CAAC,SAAS,CAAC,SAAS,CAAC;AAC7E,MAAM,CAAC,MAAM,
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/lib/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAS1C;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE,OAAO;IACd,aAAa,EAAE,gBAAgB;IAC/B,WAAW,EAAE,cAAc;IAC3B,SAAS,EAAE,YAAY;CACf,CAAC;AAOX,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;AAEnF,MAAM,QAAQ,GAAG,SAAS,EAAE,CAAC;AAE7B,MAAM,CAAC,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC;AAChD,MAAM,CAAC,MAAM,eAAe,GAAG,QAAQ,CAAC,aAAa,CAAC,aAAa,CAAC;AACpE,MAAM,CAAC,MAAM,oBAAoB,GAAG,QAAQ,CAAC,aAAa,CAAC,YAAY,CAAC;AACxE,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC,aAAa,CAAC,SAAS,CAAC;AAC3D,MAAM,CAAC,MAAM,iBAAiB,GAAG,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC;AAC5D,MAAM,CAAC,MAAM,gCAAgC,GAAG,QAAQ,CAAC,SAAS,CAAC,SAAS,CAAC;AAC7E,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC;AAEpD;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAa;IACvC,oBAAoB;IACpB,YAAY;IACZ,aAAa;IACb,cAAc;IACd,aAAa;CACd,CAAC","sourcesContent":["import { getConfig } from './settings.js';\n\n/**\n * Integration identifier type.\n * No longer an enum — each integration self-registers via the auto-discovery registry.\n * The string value matches the integration directory name (e.g., 'nextjs', 'react-router').\n */\nexport type Integration = string;\n\n/**\n * Well-known integration names for backwards compatibility.\n * New integrations do NOT need to be added here — they're auto-discovered.\n */\nexport const KNOWN_INTEGRATIONS = {\n nextjs: 'nextjs',\n react: 'react',\n tanstackStart: 'tanstack-start',\n reactRouter: 'react-router',\n vanillaJs: 'vanilla-js',\n} as const;\n\nexport interface Args {\n debug: boolean;\n integration: Integration;\n}\n\nexport const IS_DEV = ['test', 'development'].includes(process.env.NODE_ENV ?? '');\n\nconst settings = getConfig();\n\nexport const DEBUG = settings.logging.debugMode;\nexport const WORKOS_DOCS_URL = settings.documentation.workosDocsUrl;\nexport const WORKOS_DASHBOARD_URL = settings.documentation.dashboardUrl;\nexport const ISSUES_URL = settings.documentation.issuesUrl;\nexport const ANALYTICS_ENABLED = settings.telemetry.enabled;\nexport const INSTALLER_INTERACTION_EVENT_NAME = settings.telemetry.eventName;\nexport const OAUTH_PORT = settings.legacy.oauthPort;\n\n/**\n * Common glob patterns to ignore when searching for files.\n * Used by multiple integrations.\n */\nexport const IGNORE_PATTERNS: string[] = [\n '**/node_modules/**',\n '**/dist/**',\n '**/build/**',\n '**/public/**',\n '**/.next/**',\n];\n"]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persistent device identifier for telemetry correlation.
|
|
3
|
+
*
|
|
4
|
+
* Stored at ~/.workos/device-id as a plain UTF-8 UUID string. Not a secret
|
|
5
|
+
* — this is a convenience identifier that survives keyring unavailability.
|
|
6
|
+
* Any IO failure falls through to a one-shot UUID for the current session.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Asynchronously resolve (and lazily create) the device id without blocking
|
|
10
|
+
* the event loop. Memoized: the first call performs the IO, concurrent and
|
|
11
|
+
* later callers await the same promise. Populates the shared cache that the
|
|
12
|
+
* synchronous getDeviceId() reads, so prewarming this at startup keeps the
|
|
13
|
+
* synchronous telemetry path off blocking fs IO. Never rejects.
|
|
14
|
+
*/
|
|
15
|
+
export declare function loadDeviceId(): Promise<string>;
|
|
16
|
+
/**
|
|
17
|
+
* Synchronous accessor for the telemetry event path. Returns the prewarmed
|
|
18
|
+
* value when loadDeviceId() has run; otherwise falls back to a one-time
|
|
19
|
+
* synchronous read of the same file (returning the persisted id, so the value
|
|
20
|
+
* never diverges from the async path). On any IO failure, returns a one-shot
|
|
21
|
+
* UUID scoped to the current process — never throws.
|
|
22
|
+
*/
|
|
23
|
+
export declare function getDeviceId(): string;
|
|
24
|
+
/** Test seam — resets the in-memory cache between test cases. */
|
|
25
|
+
export declare function __resetDeviceIdCache(): void;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Persistent device identifier for telemetry correlation.
|
|
3
|
+
*
|
|
4
|
+
* Stored at ~/.workos/device-id as a plain UTF-8 UUID string. Not a secret
|
|
5
|
+
* — this is a convenience identifier that survives keyring unavailability.
|
|
6
|
+
* Any IO failure falls through to a one-shot UUID for the current session.
|
|
7
|
+
*/
|
|
8
|
+
import fs from 'node:fs';
|
|
9
|
+
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
10
|
+
import path from 'node:path';
|
|
11
|
+
import os from 'node:os';
|
|
12
|
+
import crypto from 'node:crypto';
|
|
13
|
+
// RFC 4122 v4 format — matches what `crypto.randomUUID()` produces.
|
|
14
|
+
// Rejects non-UUID strings like "------------------------------------".
|
|
15
|
+
const UUID_V4_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
16
|
+
let cached;
|
|
17
|
+
let pending;
|
|
18
|
+
function getDeviceIdPath() {
|
|
19
|
+
return path.join(os.homedir(), '.workos', 'device-id');
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Asynchronously resolve (and lazily create) the device id without blocking
|
|
23
|
+
* the event loop. Memoized: the first call performs the IO, concurrent and
|
|
24
|
+
* later callers await the same promise. Populates the shared cache that the
|
|
25
|
+
* synchronous getDeviceId() reads, so prewarming this at startup keeps the
|
|
26
|
+
* synchronous telemetry path off blocking fs IO. Never rejects.
|
|
27
|
+
*/
|
|
28
|
+
export function loadDeviceId() {
|
|
29
|
+
if (cached)
|
|
30
|
+
return Promise.resolve(cached);
|
|
31
|
+
if (pending)
|
|
32
|
+
return pending;
|
|
33
|
+
pending = (async () => {
|
|
34
|
+
const filePath = getDeviceIdPath();
|
|
35
|
+
try {
|
|
36
|
+
try {
|
|
37
|
+
const raw = (await readFile(filePath, 'utf8')).trim();
|
|
38
|
+
if (UUID_V4_REGEX.test(raw)) {
|
|
39
|
+
cached = raw;
|
|
40
|
+
return raw;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
// Missing/unreadable file — fall through and create it.
|
|
45
|
+
}
|
|
46
|
+
const id = crypto.randomUUID();
|
|
47
|
+
await mkdir(path.dirname(filePath), { recursive: true, mode: 0o700 });
|
|
48
|
+
await writeFile(filePath, id, { encoding: 'utf8', mode: 0o600 });
|
|
49
|
+
cached = id;
|
|
50
|
+
return id;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// IO failure (readonly FS, permission denied, etc.) — fall through to
|
|
54
|
+
// a session-scoped UUID, cached for the rest of this process.
|
|
55
|
+
cached = crypto.randomUUID();
|
|
56
|
+
return cached;
|
|
57
|
+
}
|
|
58
|
+
finally {
|
|
59
|
+
pending = undefined;
|
|
60
|
+
}
|
|
61
|
+
})();
|
|
62
|
+
return pending;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Synchronous accessor for the telemetry event path. Returns the prewarmed
|
|
66
|
+
* value when loadDeviceId() has run; otherwise falls back to a one-time
|
|
67
|
+
* synchronous read of the same file (returning the persisted id, so the value
|
|
68
|
+
* never diverges from the async path). On any IO failure, returns a one-shot
|
|
69
|
+
* UUID scoped to the current process — never throws.
|
|
70
|
+
*/
|
|
71
|
+
export function getDeviceId() {
|
|
72
|
+
if (cached)
|
|
73
|
+
return cached;
|
|
74
|
+
const filePath = getDeviceIdPath();
|
|
75
|
+
try {
|
|
76
|
+
if (fs.existsSync(filePath)) {
|
|
77
|
+
const raw = fs.readFileSync(filePath, 'utf8').trim();
|
|
78
|
+
if (UUID_V4_REGEX.test(raw)) {
|
|
79
|
+
cached = raw;
|
|
80
|
+
return raw;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
const id = crypto.randomUUID();
|
|
84
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true, mode: 0o700 });
|
|
85
|
+
fs.writeFileSync(filePath, id, { encoding: 'utf8', mode: 0o600 });
|
|
86
|
+
cached = id;
|
|
87
|
+
return id;
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
// IO failure (readonly FS, permission denied, etc.) — fall through to
|
|
91
|
+
// a session-scoped UUID. Cache it so subsequent calls in this process
|
|
92
|
+
// return the same value; the next process run will retry IO.
|
|
93
|
+
cached = crypto.randomUUID();
|
|
94
|
+
return cached;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/** Test seam — resets the in-memory cache between test cases. */
|
|
98
|
+
export function __resetDeviceIdCache() {
|
|
99
|
+
cached = undefined;
|
|
100
|
+
pending = undefined;
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=device-id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-id.js","sourceRoot":"","sources":["../../src/lib/device-id.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Persistent device identifier for telemetry correlation.\n *\n * Stored at ~/.workos/device-id as a plain UTF-8 UUID string. Not a secret\n * — this is a convenience identifier that survives keyring unavailability.\n * Any IO failure falls through to a one-shot UUID for the current session.\n */\n\nimport fs from 'node:fs';\nimport { mkdir, readFile, writeFile } from 'node:fs/promises';\nimport path from 'node:path';\nimport os from 'node:os';\nimport crypto from 'node:crypto';\n\n// RFC 4122 v4 format — matches what `crypto.randomUUID()` produces.\n// Rejects non-UUID strings like \"------------------------------------\".\nconst UUID_V4_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\nlet cached: string | undefined;\nlet pending: Promise<string> | undefined;\n\nfunction getDeviceIdPath(): string {\n return path.join(os.homedir(), '.workos', 'device-id');\n}\n\n/**\n * Asynchronously resolve (and lazily create) the device id without blocking\n * the event loop. Memoized: the first call performs the IO, concurrent and\n * later callers await the same promise. Populates the shared cache that the\n * synchronous getDeviceId() reads, so prewarming this at startup keeps the\n * synchronous telemetry path off blocking fs IO. Never rejects.\n */\nexport function loadDeviceId(): Promise<string> {\n if (cached) return Promise.resolve(cached);\n if (pending) return pending;\n\n pending = (async () => {\n const filePath = getDeviceIdPath();\n try {\n try {\n const raw = (await readFile(filePath, 'utf8')).trim();\n if (UUID_V4_REGEX.test(raw)) {\n cached = raw;\n return raw;\n }\n } catch {\n // Missing/unreadable file — fall through and create it.\n }\n\n const id = crypto.randomUUID();\n await mkdir(path.dirname(filePath), { recursive: true, mode: 0o700 });\n await writeFile(filePath, id, { encoding: 'utf8', mode: 0o600 });\n cached = id;\n return id;\n } catch {\n // IO failure (readonly FS, permission denied, etc.) — fall through to\n // a session-scoped UUID, cached for the rest of this process.\n cached = crypto.randomUUID();\n return cached;\n } finally {\n pending = undefined;\n }\n })();\n\n return pending;\n}\n\n/**\n * Synchronous accessor for the telemetry event path. Returns the prewarmed\n * value when loadDeviceId() has run; otherwise falls back to a one-time\n * synchronous read of the same file (returning the persisted id, so the value\n * never diverges from the async path). On any IO failure, returns a one-shot\n * UUID scoped to the current process — never throws.\n */\nexport function getDeviceId(): string {\n if (cached) return cached;\n\n const filePath = getDeviceIdPath();\n try {\n if (fs.existsSync(filePath)) {\n const raw = fs.readFileSync(filePath, 'utf8').trim();\n if (UUID_V4_REGEX.test(raw)) {\n cached = raw;\n return raw;\n }\n }\n\n const id = crypto.randomUUID();\n fs.mkdirSync(path.dirname(filePath), { recursive: true, mode: 0o700 });\n fs.writeFileSync(filePath, id, { encoding: 'utf8', mode: 0o600 });\n cached = id;\n return id;\n } catch {\n // IO failure (readonly FS, permission denied, etc.) — fall through to\n // a session-scoped UUID. Cache it so subsequent calls in this process\n // return the same value; the next process run will retry IO.\n cached = crypto.randomUUID();\n return cached;\n }\n}\n\n/** Test seam — resets the in-memory cache between test cases. */\nexport function __resetDeviceIdCache(): void {\n cached = undefined;\n pending = undefined;\n}\n"]}
|
package/dist/lib/events.d.ts
CHANGED
|
@@ -144,6 +144,21 @@ export interface InstallerEvents {
|
|
|
144
144
|
issueCount: number;
|
|
145
145
|
durationMs: number;
|
|
146
146
|
};
|
|
147
|
+
'scaffold:checking': Record<string, never>;
|
|
148
|
+
'scaffold:prompt': {
|
|
149
|
+
packageManager: string;
|
|
150
|
+
};
|
|
151
|
+
'scaffold:start': {
|
|
152
|
+
packageManager: string;
|
|
153
|
+
};
|
|
154
|
+
'scaffold:progress': {
|
|
155
|
+
text: string;
|
|
156
|
+
};
|
|
157
|
+
'scaffold:complete': Record<string, never>;
|
|
158
|
+
'scaffold:failed': {
|
|
159
|
+
error: string;
|
|
160
|
+
};
|
|
161
|
+
'scaffold:skipped': Record<string, never>;
|
|
147
162
|
'branch:checking': Record<string, never>;
|
|
148
163
|
'branch:protected': {
|
|
149
164
|
branch: string;
|
package/dist/lib/events.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/lib/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/lib/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAoGtC,MAAM,OAAO,qBAAsB,SAAQ,YAAY;IACrD,IAAI,CAA+B,KAAQ,EAAE,OAA2B;QACtE,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACpC,CAAC;IAED,EAAE,CAA+B,KAAQ,EAAE,QAA+C;QACxF,OAAO,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACnC,CAAC;IAED,GAAG,CAA+B,KAAQ,EAAE,QAA+C;QACzF,OAAO,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACpC,CAAC;IAED,IAAI,CAA+B,KAAQ,EAAE,QAA+C;QAC1F,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACrC,CAAC;CACF;AAED,MAAM,UAAU,2BAA2B;IACzC,OAAO,IAAI,qBAAqB,EAAE,CAAC;AACrC,CAAC","sourcesContent":["import { EventEmitter } from 'events';\n\nexport interface InstallerEvents {\n status: { message: string };\n output: { text: string; isError?: boolean };\n 'file:write': { path: string; content: string };\n 'file:edit': { path: string; oldContent: string; newContent: string };\n 'prompt:request': { id: string; message: string; options?: string[] };\n 'prompt:response': { id: string; value: string };\n 'confirm:request': { id: string; message: string; warning?: string; files?: string[] };\n 'confirm:response': { id: string; confirmed: boolean };\n 'credentials:request': { requiresApiKey: boolean };\n 'credentials:response': { apiKey: string; clientId: string };\n complete: { success: boolean; summary?: string };\n error: { message: string; stack?: string };\n\n 'state:enter': { state: string };\n 'state:exit': { state: string };\n 'auth:checking': Record<string, never>;\n 'auth:required': Record<string, never>;\n 'auth:success': Record<string, never>;\n 'auth:failure': { message: string };\n 'detection:start': Record<string, never>;\n 'detection:complete': { integration: string };\n 'detection:none': Record<string, never>;\n 'git:checking': Record<string, never>;\n 'git:clean': Record<string, never>;\n 'git:dirty': { files: string[] };\n 'git:dirty:confirmed': Record<string, never>;\n 'git:dirty:cancelled': Record<string, never>;\n 'credentials:gathering': { requiresApiKey: boolean };\n 'credentials:found': Record<string, never>;\n // Credential discovery events\n 'credentials:env:detected': { files: string[] };\n 'credentials:env:prompt': { files: string[] };\n 'credentials:env:scanning': Record<string, never>;\n 'credentials:env:found': { sourcePath: string };\n 'credentials:env:notfound': Record<string, never>;\n // Device auth events\n 'device:started': { verificationUri: string; verificationUriComplete: string; userCode: string };\n 'device:polling': Record<string, never>;\n 'device:success': { email?: string };\n 'device:timeout': Record<string, never>;\n 'device:error': { message: string };\n // Staging API events\n 'staging:fetching': Record<string, never>;\n 'staging:success': Record<string, never>;\n 'staging:error': { message: string; statusCode?: number };\n 'config:start': Record<string, never>;\n 'config:complete': Record<string, never>;\n 'agent:start': Record<string, never>;\n 'agent:progress': { step: string; detail?: string };\n 'agent:success': { summary?: string };\n 'agent:failure': { message: string; stack?: string };\n 'agent:retry': { attempt: number; maxRetries: number };\n\n 'validation:retry:start': { attempt: number };\n 'validation:retry:complete': { attempt: number; passed: boolean };\n\n 'validation:start': { framework: string };\n 'validation:issues': { issues: import('./validation/types.js').ValidationIssue[] };\n 'validation:complete': { passed: boolean; issueCount: number; durationMs: number };\n\n // Scaffold events (empty-directory app scaffolding)\n 'scaffold:checking': Record<string, never>;\n 'scaffold:prompt': { packageManager: string };\n 'scaffold:start': { packageManager: string };\n 'scaffold:progress': { text: string };\n 'scaffold:complete': Record<string, never>;\n 'scaffold:failed': { error: string };\n 'scaffold:skipped': Record<string, never>;\n\n // Branch check events\n 'branch:checking': Record<string, never>;\n 'branch:protected': { branch: string };\n 'branch:prompt': { branch: string };\n 'branch:created': { branch: string };\n 'branch:create:failed': { error: string };\n 'branch:skipped': Record<string, never>;\n\n // Post-install events\n 'postinstall:changes': { files: string[] };\n 'postinstall:nochanges': Record<string, never>;\n 'postinstall:commit:prompt': Record<string, never>;\n 'postinstall:commit:generating': Record<string, never>;\n 'postinstall:commit:committing': { message: string };\n 'postinstall:commit:success': { message: string };\n 'postinstall:commit:failed': { error: string };\n 'postinstall:pr:prompt': Record<string, never>;\n 'postinstall:pr:generating': Record<string, never>;\n 'postinstall:pr:pushing': Record<string, never>;\n 'postinstall:pr:creating': Record<string, never>;\n 'postinstall:pr:success': { url: string };\n 'postinstall:pr:failed': { error: string };\n 'postinstall:push:failed': { error: string };\n 'postinstall:manual': { instructions: string };\n}\n\nexport type InstallerEventName = keyof InstallerEvents;\n\nexport class InstallerEventEmitter extends EventEmitter {\n emit<K extends InstallerEventName>(event: K, payload: InstallerEvents[K]): boolean {\n return super.emit(event, payload);\n }\n\n on<K extends InstallerEventName>(event: K, listener: (payload: InstallerEvents[K]) => void): this {\n return super.on(event, listener);\n }\n\n off<K extends InstallerEventName>(event: K, listener: (payload: InstallerEvents[K]) => void): this {\n return super.off(event, listener);\n }\n\n once<K extends InstallerEventName>(event: K, listener: (payload: InstallerEvents[K]) => void): this {\n return super.once(event, listener);\n }\n}\n\nexport function createInstallerEventEmitter(): InstallerEventEmitter {\n return new InstallerEventEmitter();\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type ActorRefFrom } from 'xstate';
|
|
2
|
-
import type { InstallerMachineContext, InstallerMachineInput, DetectionOutput, GitCheckOutput, AgentOutput, EnvFileInfo, DiscoveryResult, BranchCheckOutput } from './installer-core.types.js';
|
|
2
|
+
import type { InstallerMachineContext, InstallerMachineInput, DetectionOutput, GitCheckOutput, AgentOutput, EnvFileInfo, DiscoveryResult, BranchCheckOutput, WorkspaceCheckOutput } from './installer-core.types.js';
|
|
3
3
|
import type { InstallerOptions } from '../utils/types.js';
|
|
4
4
|
import type { DeviceAuthResult, DeviceAuthResponse } from './device-auth.js';
|
|
5
5
|
import type { StagingCredentials } from './staging-api.js';
|
|
@@ -11,6 +11,10 @@ export declare const installerMachine: import("xstate").StateMachine<InstallerMa
|
|
|
11
11
|
type: "GIT_CONFIRMED";
|
|
12
12
|
} | {
|
|
13
13
|
type: "GIT_CANCELLED";
|
|
14
|
+
} | {
|
|
15
|
+
type: "SCAFFOLD_CONFIRMED";
|
|
16
|
+
} | {
|
|
17
|
+
type: "SCAFFOLD_CANCELLED";
|
|
14
18
|
} | {
|
|
15
19
|
type: "CREDENTIALS_SUBMITTED";
|
|
16
20
|
apiKey: string;
|
|
@@ -44,6 +48,10 @@ export declare const installerMachine: import("xstate").StateMachine<InstallerMa
|
|
|
44
48
|
cwd: string;
|
|
45
49
|
}, import("xstate").EventObject>> | import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<boolean, {
|
|
46
50
|
options: InstallerOptions;
|
|
51
|
+
}, import("xstate").EventObject>> | import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<WorkspaceCheckOutput, {
|
|
52
|
+
options: InstallerOptions;
|
|
53
|
+
}, import("xstate").EventObject>> | import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<void, {
|
|
54
|
+
context: InstallerMachineContext;
|
|
47
55
|
}, import("xstate").EventObject>> | import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<DetectionOutput, {
|
|
48
56
|
options: InstallerOptions;
|
|
49
57
|
}, import("xstate").EventObject>> | import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<GitCheckOutput, {
|
|
@@ -98,6 +106,18 @@ export declare const installerMachine: import("xstate").StateMachine<InstallerMa
|
|
|
98
106
|
options: InstallerOptions;
|
|
99
107
|
}, import("xstate").EventObject>;
|
|
100
108
|
id: string | undefined;
|
|
109
|
+
} | {
|
|
110
|
+
src: "checkWorkspace";
|
|
111
|
+
logic: import("xstate").PromiseActorLogic<WorkspaceCheckOutput, {
|
|
112
|
+
options: InstallerOptions;
|
|
113
|
+
}, import("xstate").EventObject>;
|
|
114
|
+
id: string | undefined;
|
|
115
|
+
} | {
|
|
116
|
+
src: "runScaffold";
|
|
117
|
+
logic: import("xstate").PromiseActorLogic<void, {
|
|
118
|
+
context: InstallerMachineContext;
|
|
119
|
+
}, import("xstate").EventObject>;
|
|
120
|
+
id: string | undefined;
|
|
101
121
|
} | {
|
|
102
122
|
src: "detectIntegration";
|
|
103
123
|
logic: import("xstate").PromiseActorLogic<DetectionOutput, {
|
|
@@ -244,6 +264,30 @@ export declare const installerMachine: import("xstate").StateMachine<InstallerMa
|
|
|
244
264
|
} | {
|
|
245
265
|
type: "emitGitCancelled";
|
|
246
266
|
params: unknown;
|
|
267
|
+
} | {
|
|
268
|
+
type: "emitScaffoldChecking";
|
|
269
|
+
params: unknown;
|
|
270
|
+
} | {
|
|
271
|
+
type: "emitScaffoldPrompt";
|
|
272
|
+
params: unknown;
|
|
273
|
+
} | {
|
|
274
|
+
type: "emitScaffoldStart";
|
|
275
|
+
params: unknown;
|
|
276
|
+
} | {
|
|
277
|
+
type: "emitScaffoldComplete";
|
|
278
|
+
params: unknown;
|
|
279
|
+
} | {
|
|
280
|
+
type: "emitScaffoldFailed";
|
|
281
|
+
params: unknown;
|
|
282
|
+
} | {
|
|
283
|
+
type: "emitScaffoldSkipped";
|
|
284
|
+
params: unknown;
|
|
285
|
+
} | {
|
|
286
|
+
type: "assignWorkspaceResult";
|
|
287
|
+
params: unknown;
|
|
288
|
+
} | {
|
|
289
|
+
type: "assignScaffolded";
|
|
290
|
+
params: unknown;
|
|
247
291
|
} | {
|
|
248
292
|
type: "emitBranchChecking";
|
|
249
293
|
params: unknown;
|
|
@@ -416,7 +460,15 @@ export declare const installerMachine: import("xstate").StateMachine<InstallerMa
|
|
|
416
460
|
} | {
|
|
417
461
|
type: "hasGhCli";
|
|
418
462
|
params: unknown;
|
|
463
|
+
} | {
|
|
464
|
+
type: "notScaffoldable";
|
|
465
|
+
params: unknown;
|
|
466
|
+
} | {
|
|
467
|
+
type: "shouldAutoScaffold";
|
|
468
|
+
params: unknown;
|
|
419
469
|
}, never, "error" | "cancelled" | "complete" | "idle" | "authenticating" | "configuring" | "runningAgent" | {
|
|
470
|
+
scaffold: "done" | "checking" | "running" | "prompting";
|
|
471
|
+
} | {
|
|
420
472
|
preparing: {
|
|
421
473
|
detection: "done" | "running";
|
|
422
474
|
gitCheck: "done" | "running" | "evaluating" | "awaitingConfirmation";
|
|
@@ -431,6 +483,14 @@ export declare const installerMachine: import("xstate").StateMachine<InstallerMa
|
|
|
431
483
|
states: {
|
|
432
484
|
readonly idle: {};
|
|
433
485
|
readonly authenticating: {};
|
|
486
|
+
readonly scaffold: {
|
|
487
|
+
states: {
|
|
488
|
+
readonly checking: {};
|
|
489
|
+
readonly prompting: {};
|
|
490
|
+
readonly running: {};
|
|
491
|
+
readonly done: {};
|
|
492
|
+
};
|
|
493
|
+
};
|
|
434
494
|
readonly preparing: {
|
|
435
495
|
states: {
|
|
436
496
|
readonly detection: {
|