workos 0.4.5 → 0.5.1
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/dist/bin.js +32 -3
- package/dist/bin.js.map +1 -1
- package/dist/commands/doctor.d.ts +10 -0
- package/dist/commands/doctor.js +30 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/doctor/checks/connectivity.d.ts +2 -0
- package/dist/doctor/checks/connectivity.js +35 -0
- package/dist/doctor/checks/connectivity.js.map +1 -0
- package/dist/doctor/checks/dashboard.d.ts +3 -0
- package/dist/doctor/checks/dashboard.js +123 -0
- package/dist/doctor/checks/dashboard.js.map +1 -0
- package/dist/doctor/checks/environment.d.ts +2 -0
- package/dist/doctor/checks/environment.js +68 -0
- package/dist/doctor/checks/environment.js.map +1 -0
- package/dist/doctor/checks/framework.d.ts +2 -0
- package/dist/doctor/checks/framework.js +75 -0
- package/dist/doctor/checks/framework.js.map +1 -0
- package/dist/doctor/checks/runtime.d.ts +2 -0
- package/dist/doctor/checks/runtime.js +20 -0
- package/dist/doctor/checks/runtime.js.map +1 -0
- package/dist/doctor/checks/sdk.d.ts +2 -0
- package/dist/doctor/checks/sdk.js +111 -0
- package/dist/doctor/checks/sdk.js.map +1 -0
- package/dist/doctor/clipboard.d.ts +1 -0
- package/dist/doctor/clipboard.js +43 -0
- package/dist/doctor/clipboard.js.map +1 -0
- package/dist/doctor/index.d.ts +6 -0
- package/dist/doctor/index.js +94 -0
- package/dist/doctor/index.js.map +1 -0
- package/dist/doctor/issues.d.ts +58 -0
- package/dist/doctor/issues.js +134 -0
- package/dist/doctor/issues.js.map +1 -0
- package/dist/doctor/json-output.d.ts +2 -0
- package/dist/doctor/json-output.js +4 -0
- package/dist/doctor/json-output.js.map +1 -0
- package/dist/doctor/output.d.ts +5 -0
- package/dist/doctor/output.js +149 -0
- package/dist/doctor/output.js.map +1 -0
- package/dist/doctor/types.d.ts +105 -0
- package/dist/doctor/types.js +2 -0
- package/dist/doctor/types.js.map +1 -0
- package/dist/integrations/dotnet/index.d.ts +8 -0
- package/dist/integrations/dotnet/index.js +163 -0
- package/dist/integrations/dotnet/index.js.map +1 -0
- package/dist/integrations/elixir/index.d.ts +8 -0
- package/dist/integrations/elixir/index.js +152 -0
- package/dist/integrations/elixir/index.js.map +1 -0
- package/dist/integrations/go/index.d.ts +11 -0
- package/dist/integrations/go/index.js +220 -0
- package/dist/integrations/go/index.js.map +1 -0
- package/dist/integrations/kotlin/index.d.ts +4 -0
- package/dist/integrations/kotlin/index.js +53 -0
- package/dist/integrations/kotlin/index.js.map +1 -0
- package/dist/integrations/nextjs/index.d.ts +4 -0
- package/dist/integrations/nextjs/index.js +90 -0
- package/dist/integrations/nextjs/index.js.map +1 -0
- package/dist/integrations/nextjs/utils.d.ts +8 -0
- package/dist/integrations/nextjs/utils.js +53 -0
- package/dist/integrations/nextjs/utils.js.map +1 -0
- package/dist/integrations/node/index.d.ts +4 -0
- package/dist/integrations/node/index.js +52 -0
- package/dist/integrations/node/index.js.map +1 -0
- package/dist/integrations/php/index.d.ts +4 -0
- package/dist/integrations/php/index.js +51 -0
- package/dist/integrations/php/index.js.map +1 -0
- package/dist/integrations/php-laravel/index.d.ts +4 -0
- package/dist/integrations/php-laravel/index.js +51 -0
- package/dist/integrations/php-laravel/index.js.map +1 -0
- package/dist/integrations/python/index.d.ts +9 -0
- package/dist/integrations/python/index.js +254 -0
- package/dist/integrations/python/index.js.map +1 -0
- package/dist/integrations/react/index.d.ts +4 -0
- package/dist/integrations/react/index.js +49 -0
- package/dist/integrations/react/index.js.map +1 -0
- package/dist/integrations/react-router/index.d.ts +4 -0
- package/dist/integrations/react-router/index.js +94 -0
- package/dist/integrations/react-router/index.js.map +1 -0
- package/dist/integrations/react-router/utils.d.ts +10 -0
- package/dist/integrations/react-router/utils.js +146 -0
- package/dist/integrations/react-router/utils.js.map +1 -0
- package/dist/integrations/ruby/index.d.ts +8 -0
- package/dist/integrations/ruby/index.js +142 -0
- package/dist/integrations/ruby/index.js.map +1 -0
- package/dist/integrations/sveltekit/index.d.ts +4 -0
- package/dist/integrations/sveltekit/index.js +50 -0
- package/dist/integrations/sveltekit/index.js.map +1 -0
- package/dist/integrations/tanstack-start/index.d.ts +4 -0
- package/dist/integrations/tanstack-start/index.js +51 -0
- package/dist/integrations/tanstack-start/index.js.map +1 -0
- package/dist/integrations/vanilla-js/index.d.ts +4 -0
- package/dist/integrations/vanilla-js/index.js +49 -0
- package/dist/integrations/vanilla-js/index.js.map +1 -0
- package/dist/lib/agent-interface.js +66 -1
- package/dist/lib/agent-interface.js.map +1 -1
- package/dist/lib/config.d.ts +32 -58
- package/dist/lib/config.js +19 -70
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/constants.d.ts +17 -14
- package/dist/lib/constants.js +12 -31
- package/dist/lib/constants.js.map +1 -1
- package/dist/lib/framework-config.d.ts +13 -4
- package/dist/lib/framework-config.js.map +1 -1
- package/dist/lib/language-detection.d.ts +20 -0
- package/dist/lib/language-detection.js +96 -0
- package/dist/lib/language-detection.js.map +1 -0
- package/dist/lib/port-detection.js +4 -2
- package/dist/lib/port-detection.js.map +1 -1
- package/dist/lib/registry.d.ts +43 -0
- package/dist/lib/registry.js +96 -0
- package/dist/lib/registry.js.map +1 -0
- package/dist/lib/run-with-core.js +70 -26
- package/dist/lib/run-with-core.js.map +1 -1
- package/dist/lib/validation/validator.js +43 -13
- package/dist/lib/validation/validator.js.map +1 -1
- package/dist/nextjs/nextjs-installer-agent.d.ts +3 -4
- package/dist/nextjs/nextjs-installer-agent.js +3 -94
- package/dist/nextjs/nextjs-installer-agent.js.map +1 -1
- package/dist/nextjs/utils.d.ts +4 -8
- package/dist/nextjs/utils.js +4 -52
- package/dist/nextjs/utils.js.map +1 -1
- package/dist/react/react-installer-agent.d.ts +4 -2
- package/dist/react/react-installer-agent.js +4 -46
- package/dist/react/react-installer-agent.js.map +1 -1
- package/dist/react-router/react-router-installer-agent.d.ts +2 -4
- package/dist/react-router/react-router-installer-agent.js +2 -100
- package/dist/react-router/react-router-installer-agent.js.map +1 -1
- package/dist/react-router/utils.d.ts +2 -17
- package/dist/react-router/utils.js +2 -207
- package/dist/react-router/utils.js.map +1 -1
- package/dist/tanstack-start/tanstack-start-installer-agent.d.ts +4 -2
- package/dist/tanstack-start/tanstack-start-installer-agent.js +4 -48
- package/dist/tanstack-start/tanstack-start-installer-agent.js.map +1 -1
- package/dist/vanilla-js/vanilla-js-installer-agent.d.ts +4 -2
- package/dist/vanilla-js/vanilla-js-installer-agent.js +4 -46
- package/dist/vanilla-js/vanilla-js-installer-agent.js.map +1 -1
- package/package.json +6 -5
- package/skills/workos-authkit-nextjs/SKILL.md +41 -11
- package/skills/workos-authkit-sveltekit/SKILL.md +160 -0
- package/skills/workos-dotnet/SKILL.md +163 -0
- package/skills/workos-elixir/SKILL.md +194 -0
- package/skills/workos-go/SKILL.md +191 -0
- package/skills/workos-kotlin/SKILL.md +161 -0
- package/skills/workos-node/SKILL.md +164 -0
- package/skills/workos-php/SKILL.md +127 -0
- package/skills/workos-php-laravel/SKILL.md +147 -0
- package/skills/workos-python/SKILL.md +159 -0
- package/skills/workos-ruby/SKILL.md +163 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import Chalk from 'chalk';
|
|
2
|
+
export function formatReport(report, options) {
|
|
3
|
+
console.log('');
|
|
4
|
+
console.log(Chalk.cyan('WorkOS Doctor'));
|
|
5
|
+
console.log(Chalk.dim('━'.repeat(70)));
|
|
6
|
+
// SDK & Project
|
|
7
|
+
console.log('');
|
|
8
|
+
console.log('SDK & Project Information');
|
|
9
|
+
if (report.sdk.name) {
|
|
10
|
+
console.log(` SDK: ${report.sdk.name} v${report.sdk.version}`);
|
|
11
|
+
}
|
|
12
|
+
else {
|
|
13
|
+
console.log(` SDK: ${Chalk.red('Not found')}`);
|
|
14
|
+
}
|
|
15
|
+
console.log(` Runtime: Node.js ${report.runtime.nodeVersion}`);
|
|
16
|
+
if (report.framework.name) {
|
|
17
|
+
const variant = report.framework.variant ? ` (${report.framework.variant})` : '';
|
|
18
|
+
console.log(` Framework: ${report.framework.name} ${report.framework.version}${variant}`);
|
|
19
|
+
}
|
|
20
|
+
if (report.runtime.packageManager) {
|
|
21
|
+
console.log(` Package Manager: ${report.runtime.packageManager} ${report.runtime.packageManagerVersion ?? ''}`);
|
|
22
|
+
}
|
|
23
|
+
// Environment
|
|
24
|
+
console.log('');
|
|
25
|
+
console.log('Environment Configuration');
|
|
26
|
+
const envType = report.environment.apiKeyType
|
|
27
|
+
? report.environment.apiKeyType.charAt(0).toUpperCase() + report.environment.apiKeyType.slice(1)
|
|
28
|
+
: 'Unable to determine';
|
|
29
|
+
console.log(` Environment: ${envType}`);
|
|
30
|
+
console.log(` Client ID: ${report.environment.clientId ?? Chalk.red('Not set')}`);
|
|
31
|
+
console.log(` API Key: ${report.environment.apiKeyConfigured ? Chalk.green('configured') : Chalk.red('not set')}`);
|
|
32
|
+
console.log(` Base URL: ${report.environment.baseUrl} ${Chalk.green('✓')}`);
|
|
33
|
+
// Connectivity & Credential Validation
|
|
34
|
+
console.log('');
|
|
35
|
+
console.log('Connectivity');
|
|
36
|
+
if (report.connectivity.apiReachable) {
|
|
37
|
+
console.log(` API: ${Chalk.green('✓')} Reachable (${report.connectivity.latencyMs}ms)`);
|
|
38
|
+
}
|
|
39
|
+
else if (report.connectivity.error?.includes('Skipped')) {
|
|
40
|
+
console.log(` API: ${Chalk.dim('Skipped (--skip-api)')}`);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
console.log(` API: ${Chalk.red('✗')} ${report.connectivity.error}`);
|
|
44
|
+
}
|
|
45
|
+
// Credential validation
|
|
46
|
+
if (report.credentialValidation) {
|
|
47
|
+
if (report.credentialValidation.valid && report.credentialValidation.clientIdMatch) {
|
|
48
|
+
console.log(` Credentials: ${Chalk.green('✓')} Valid and matching`);
|
|
49
|
+
}
|
|
50
|
+
else if (!report.credentialValidation.valid) {
|
|
51
|
+
console.log(` Credentials: ${Chalk.red('✗')} ${report.credentialValidation.error ?? 'Invalid'}`);
|
|
52
|
+
}
|
|
53
|
+
else if (!report.credentialValidation.clientIdMatch) {
|
|
54
|
+
console.log(` Credentials: ${Chalk.red('✗')} Client ID mismatch`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Dashboard Settings (if available)
|
|
58
|
+
if (report.dashboardSettings) {
|
|
59
|
+
console.log('');
|
|
60
|
+
console.log('Dashboard Settings (Staging)');
|
|
61
|
+
console.log(` Auth Methods: ${report.dashboardSettings.authMethods.length > 0 ? report.dashboardSettings.authMethods.join(', ') : 'None configured'}`);
|
|
62
|
+
console.log(` Session Timeout: ${report.dashboardSettings.sessionTimeout ?? 'Default'}`);
|
|
63
|
+
console.log(` MFA: ${formatMfa(report.dashboardSettings.mfa)}`);
|
|
64
|
+
console.log(` Organizations: ${report.dashboardSettings.organizationCount} configured`);
|
|
65
|
+
}
|
|
66
|
+
else if (report.dashboardError) {
|
|
67
|
+
console.log('');
|
|
68
|
+
console.log('Dashboard Settings');
|
|
69
|
+
console.log(` Status: ${Chalk.dim(report.dashboardError)}`);
|
|
70
|
+
}
|
|
71
|
+
// Redirect URI (can't verify against dashboard - no list API)
|
|
72
|
+
if (report.redirectUris?.codeUri) {
|
|
73
|
+
console.log('');
|
|
74
|
+
const source = report.redirectUris.source === 'inferred' ? 'Inferred' : 'Configured';
|
|
75
|
+
console.log(`Redirect URI (${source})`);
|
|
76
|
+
console.log(` ${report.redirectUris.codeUri}`);
|
|
77
|
+
}
|
|
78
|
+
// Verbose mode additions
|
|
79
|
+
if (options?.verbose) {
|
|
80
|
+
console.log('');
|
|
81
|
+
console.log(Chalk.dim('Verbose Details'));
|
|
82
|
+
console.log(` ${Chalk.dim('Project path:')} ${report.project.path}`);
|
|
83
|
+
console.log(` ${Chalk.dim('Timestamp:')} ${report.timestamp}`);
|
|
84
|
+
console.log(` ${Chalk.dim('Doctor version:')} ${report.version}`);
|
|
85
|
+
}
|
|
86
|
+
console.log('');
|
|
87
|
+
console.log(Chalk.dim('━'.repeat(70)));
|
|
88
|
+
// Issues
|
|
89
|
+
if (report.issues.length > 0) {
|
|
90
|
+
const errors = report.issues.filter((i) => i.severity === 'error');
|
|
91
|
+
const warnings = report.issues.filter((i) => i.severity === 'warning');
|
|
92
|
+
console.log('');
|
|
93
|
+
if (errors.length > 0) {
|
|
94
|
+
console.log(Chalk.red(`Critical Issues Found (${errors.length} errors)`));
|
|
95
|
+
console.log('');
|
|
96
|
+
for (const issue of errors) {
|
|
97
|
+
formatIssue(issue);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (warnings.length > 0) {
|
|
101
|
+
console.log(Chalk.yellow(`Warnings (${warnings.length})`));
|
|
102
|
+
console.log('');
|
|
103
|
+
for (const issue of warnings) {
|
|
104
|
+
formatIssue(issue);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
console.log(Chalk.dim('━'.repeat(70)));
|
|
109
|
+
console.log('');
|
|
110
|
+
// Summary
|
|
111
|
+
if (report.summary.healthy) {
|
|
112
|
+
console.log(Chalk.green('Your WorkOS integration looks healthy!'));
|
|
113
|
+
}
|
|
114
|
+
else if (report.summary.errors > 0) {
|
|
115
|
+
console.log(Chalk.red(`${report.summary.errors} issue(s) must be resolved before authentication will work.`));
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
console.log(Chalk.yellow(`${report.summary.warnings} warning(s) to review.`));
|
|
119
|
+
}
|
|
120
|
+
console.log('');
|
|
121
|
+
console.log(Chalk.dim('Copy this report: workos doctor --copy'));
|
|
122
|
+
console.log(Chalk.dim('Troubleshooting: https://workos.com/docs/troubleshooting'));
|
|
123
|
+
console.log('');
|
|
124
|
+
}
|
|
125
|
+
function formatIssue(issue) {
|
|
126
|
+
const icon = issue.severity === 'error' ? Chalk.red('✗') : Chalk.yellow('!');
|
|
127
|
+
const color = issue.severity === 'error' ? Chalk.red : Chalk.yellow;
|
|
128
|
+
console.log(`${icon} ${color(issue.code)}: ${issue.message}`);
|
|
129
|
+
if (issue.remediation) {
|
|
130
|
+
console.log(` ${Chalk.dim('→')} ${issue.remediation}`);
|
|
131
|
+
}
|
|
132
|
+
if (issue.docsUrl) {
|
|
133
|
+
console.log(` ${Chalk.dim('Docs:')} ${issue.docsUrl}`);
|
|
134
|
+
}
|
|
135
|
+
console.log('');
|
|
136
|
+
}
|
|
137
|
+
function formatMfa(mfa) {
|
|
138
|
+
switch (mfa) {
|
|
139
|
+
case 'required':
|
|
140
|
+
return 'Required';
|
|
141
|
+
case 'optional':
|
|
142
|
+
return 'Optional';
|
|
143
|
+
case 'disabled':
|
|
144
|
+
return 'Disabled';
|
|
145
|
+
default:
|
|
146
|
+
return 'Not configured';
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/doctor/output.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,MAAM,UAAU,YAAY,CAAC,MAAoB,EAAE,OAAuB;IACxE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;IACzC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAEvC,gBAAgB;IAChB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;IACzC,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;QACpB,OAAO,CAAC,GAAG,CAAC,wBAAwB,MAAM,CAAC,GAAG,CAAC,IAAI,KAAK,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IAChF,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,wBAAwB,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,gCAAgC,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAC1E,IAAI,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;QAC1B,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,SAAS,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACjF,OAAO,CAAC,GAAG,CAAC,wBAAwB,MAAM,CAAC,SAAS,CAAC,IAAI,IAAI,MAAM,CAAC,SAAS,CAAC,OAAO,GAAG,OAAO,EAAE,CAAC,CAAC;IACrG,CAAC;IACD,IAAI,MAAM,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,wBAAwB,MAAM,CAAC,OAAO,CAAC,cAAc,IAAI,MAAM,CAAC,OAAO,CAAC,qBAAqB,IAAI,EAAE,EAAE,CAAC,CAAC;IACrH,CAAC;IAED,cAAc;IACd,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,MAAM,CAAC,WAAW,CAAC,UAAU;QAC3C,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;QAChG,CAAC,CAAC,qBAAqB,CAAC;IAC1B,OAAO,CAAC,GAAG,CAAC,wBAAwB,OAAO,EAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,wBAAwB,MAAM,CAAC,WAAW,CAAC,QAAQ,IAAI,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAC3F,OAAO,CAAC,GAAG,CACT,wBAAwB,MAAM,CAAC,WAAW,CAAC,gBAAgB,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CACjH,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,wBAAwB,MAAM,CAAC,WAAW,CAAC,OAAO,IAAI,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEtF,uCAAuC;IACvC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAC5B,IAAI,MAAM,CAAC,YAAY,CAAC,YAAY,EAAE,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,wBAAwB,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,eAAe,MAAM,CAAC,YAAY,CAAC,SAAS,KAAK,CAAC,CAAC;IACzG,CAAC;SAAM,IAAI,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1D,OAAO,CAAC,GAAG,CAAC,wBAAwB,KAAK,CAAC,GAAG,CAAC,sBAAsB,CAAC,EAAE,CAAC,CAAC;IAC3E,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,wBAAwB,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC,CAAC;IACrF,CAAC;IAED,wBAAwB;IACxB,IAAI,MAAM,CAAC,oBAAoB,EAAE,CAAC;QAChC,IAAI,MAAM,CAAC,oBAAoB,CAAC,KAAK,IAAI,MAAM,CAAC,oBAAoB,CAAC,aAAa,EAAE,CAAC;YACnF,OAAO,CAAC,GAAG,CAAC,wBAAwB,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;QAC7E,CAAC;aAAM,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,KAAK,EAAE,CAAC;YAC9C,OAAO,CAAC,GAAG,CAAC,wBAAwB,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,oBAAoB,CAAC,KAAK,IAAI,SAAS,EAAE,CAAC,CAAC;QAC1G,CAAC;aAAM,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,aAAa,EAAE,CAAC;YACtD,OAAO,CAAC,GAAG,CAAC,wBAAwB,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC;IAED,oCAAoC;IACpC,IAAI,MAAM,CAAC,iBAAiB,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;QAC5C,OAAO,CAAC,GAAG,CACT,wBAAwB,MAAM,CAAC,iBAAiB,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAChJ,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,wBAAwB,MAAM,CAAC,iBAAiB,CAAC,cAAc,IAAI,SAAS,EAAE,CAAC,CAAC;QAC5F,OAAO,CAAC,GAAG,CAAC,wBAAwB,SAAS,CAAC,MAAM,CAAC,iBAAiB,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC/E,OAAO,CAAC,GAAG,CAAC,wBAAwB,MAAM,CAAC,iBAAiB,CAAC,iBAAiB,aAAa,CAAC,CAAC;IAC/F,CAAC;SAAM,IAAI,MAAM,CAAC,cAAc,EAAE,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,wBAAwB,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,8DAA8D;IAC9D,IAAI,MAAM,CAAC,YAAY,EAAE,OAAO,EAAE,CAAC;QACjC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,MAAM,MAAM,GAAG,MAAM,CAAC,YAAY,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,CAAC;QACrF,OAAO,CAAC,GAAG,CAAC,iBAAiB,MAAM,GAAG,CAAC,CAAC;QACxC,OAAO,CAAC,GAAG,CAAC,MAAM,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,yBAAyB;IACzB,IAAI,OAAO,EAAE,OAAO,EAAE,CAAC;QACrB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC;QAC1C,OAAO,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,eAAe,CAAC,KAAK,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;QACxE,OAAO,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,QAAQ,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;QACrE,OAAO,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAEvC,SAAS;IACT,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;QACnE,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC;QAEvE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,0BAA0B,MAAM,CAAC,MAAM,UAAU,CAAC,CAAC,CAAC;YAC1E,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,WAAW,CAAC,KAAK,CAAC,CAAC;YACrB,CAAC;QACH,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,aAAa,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YAC3D,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAChB,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;gBAC7B,WAAW,CAAC,KAAK,CAAC,CAAC;YACrB,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACvC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,UAAU;IACV,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC,CAAC;IACrE,CAAC;SAAM,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,6DAA6D,CAAC,CAAC,CAAC;IAChH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,wBAAwB,CAAC,CAAC,CAAC;IAChF,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,wCAAwC,CAAC,CAAC,CAAC;IACjE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC,CAAC;IACpF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC;AAED,SAAS,WAAW,CAAC,KAAY;IAC/B,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC7E,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;IAEpE,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,IAAI,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAC9D,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;IAC3D,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;QAClB,OAAO,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC;AAED,SAAS,SAAS,CAAC,GAAkB;IACnC,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,UAAU;YACb,OAAO,UAAU,CAAC;QACpB,KAAK,UAAU;YACb,OAAO,UAAU,CAAC;QACpB,KAAK,UAAU;YACb,OAAO,UAAU,CAAC;QACpB;YACE,OAAO,gBAAgB,CAAC;IAC5B,CAAC;AACH,CAAC","sourcesContent":["import Chalk from 'chalk';\nimport type { DoctorReport, Issue } from './types.js';\n\nexport interface FormatOptions {\n verbose?: boolean;\n}\n\nexport function formatReport(report: DoctorReport, options?: FormatOptions): void {\n console.log('');\n console.log(Chalk.cyan('WorkOS Doctor'));\n console.log(Chalk.dim('━'.repeat(70)));\n\n // SDK & Project\n console.log('');\n console.log('SDK & Project Information');\n if (report.sdk.name) {\n console.log(` SDK: ${report.sdk.name} v${report.sdk.version}`);\n } else {\n console.log(` SDK: ${Chalk.red('Not found')}`);\n }\n console.log(` Runtime: Node.js ${report.runtime.nodeVersion}`);\n if (report.framework.name) {\n const variant = report.framework.variant ? ` (${report.framework.variant})` : '';\n console.log(` Framework: ${report.framework.name} ${report.framework.version}${variant}`);\n }\n if (report.runtime.packageManager) {\n console.log(` Package Manager: ${report.runtime.packageManager} ${report.runtime.packageManagerVersion ?? ''}`);\n }\n\n // Environment\n console.log('');\n console.log('Environment Configuration');\n const envType = report.environment.apiKeyType\n ? report.environment.apiKeyType.charAt(0).toUpperCase() + report.environment.apiKeyType.slice(1)\n : 'Unable to determine';\n console.log(` Environment: ${envType}`);\n console.log(` Client ID: ${report.environment.clientId ?? Chalk.red('Not set')}`);\n console.log(\n ` API Key: ${report.environment.apiKeyConfigured ? Chalk.green('configured') : Chalk.red('not set')}`,\n );\n console.log(` Base URL: ${report.environment.baseUrl} ${Chalk.green('✓')}`);\n\n // Connectivity & Credential Validation\n console.log('');\n console.log('Connectivity');\n if (report.connectivity.apiReachable) {\n console.log(` API: ${Chalk.green('✓')} Reachable (${report.connectivity.latencyMs}ms)`);\n } else if (report.connectivity.error?.includes('Skipped')) {\n console.log(` API: ${Chalk.dim('Skipped (--skip-api)')}`);\n } else {\n console.log(` API: ${Chalk.red('✗')} ${report.connectivity.error}`);\n }\n\n // Credential validation\n if (report.credentialValidation) {\n if (report.credentialValidation.valid && report.credentialValidation.clientIdMatch) {\n console.log(` Credentials: ${Chalk.green('✓')} Valid and matching`);\n } else if (!report.credentialValidation.valid) {\n console.log(` Credentials: ${Chalk.red('✗')} ${report.credentialValidation.error ?? 'Invalid'}`);\n } else if (!report.credentialValidation.clientIdMatch) {\n console.log(` Credentials: ${Chalk.red('✗')} Client ID mismatch`);\n }\n }\n\n // Dashboard Settings (if available)\n if (report.dashboardSettings) {\n console.log('');\n console.log('Dashboard Settings (Staging)');\n console.log(\n ` Auth Methods: ${report.dashboardSettings.authMethods.length > 0 ? report.dashboardSettings.authMethods.join(', ') : 'None configured'}`,\n );\n console.log(` Session Timeout: ${report.dashboardSettings.sessionTimeout ?? 'Default'}`);\n console.log(` MFA: ${formatMfa(report.dashboardSettings.mfa)}`);\n console.log(` Organizations: ${report.dashboardSettings.organizationCount} configured`);\n } else if (report.dashboardError) {\n console.log('');\n console.log('Dashboard Settings');\n console.log(` Status: ${Chalk.dim(report.dashboardError)}`);\n }\n\n // Redirect URI (can't verify against dashboard - no list API)\n if (report.redirectUris?.codeUri) {\n console.log('');\n const source = report.redirectUris.source === 'inferred' ? 'Inferred' : 'Configured';\n console.log(`Redirect URI (${source})`);\n console.log(` ${report.redirectUris.codeUri}`);\n }\n\n // Verbose mode additions\n if (options?.verbose) {\n console.log('');\n console.log(Chalk.dim('Verbose Details'));\n console.log(` ${Chalk.dim('Project path:')} ${report.project.path}`);\n console.log(` ${Chalk.dim('Timestamp:')} ${report.timestamp}`);\n console.log(` ${Chalk.dim('Doctor version:')} ${report.version}`);\n }\n\n console.log('');\n console.log(Chalk.dim('━'.repeat(70)));\n\n // Issues\n if (report.issues.length > 0) {\n const errors = report.issues.filter((i) => i.severity === 'error');\n const warnings = report.issues.filter((i) => i.severity === 'warning');\n\n console.log('');\n if (errors.length > 0) {\n console.log(Chalk.red(`Critical Issues Found (${errors.length} errors)`));\n console.log('');\n for (const issue of errors) {\n formatIssue(issue);\n }\n }\n\n if (warnings.length > 0) {\n console.log(Chalk.yellow(`Warnings (${warnings.length})`));\n console.log('');\n for (const issue of warnings) {\n formatIssue(issue);\n }\n }\n }\n\n console.log(Chalk.dim('━'.repeat(70)));\n console.log('');\n\n // Summary\n if (report.summary.healthy) {\n console.log(Chalk.green('Your WorkOS integration looks healthy!'));\n } else if (report.summary.errors > 0) {\n console.log(Chalk.red(`${report.summary.errors} issue(s) must be resolved before authentication will work.`));\n } else {\n console.log(Chalk.yellow(`${report.summary.warnings} warning(s) to review.`));\n }\n\n console.log('');\n console.log(Chalk.dim('Copy this report: workos doctor --copy'));\n console.log(Chalk.dim('Troubleshooting: https://workos.com/docs/troubleshooting'));\n console.log('');\n}\n\nfunction formatIssue(issue: Issue): void {\n const icon = issue.severity === 'error' ? Chalk.red('✗') : Chalk.yellow('!');\n const color = issue.severity === 'error' ? Chalk.red : Chalk.yellow;\n\n console.log(`${icon} ${color(issue.code)}: ${issue.message}`);\n if (issue.remediation) {\n console.log(` ${Chalk.dim('→')} ${issue.remediation}`);\n }\n if (issue.docsUrl) {\n console.log(` ${Chalk.dim('Docs:')} ${issue.docsUrl}`);\n }\n console.log('');\n}\n\nfunction formatMfa(mfa: string | null): string {\n switch (mfa) {\n case 'required':\n return 'Required';\n case 'optional':\n return 'Optional';\n case 'disabled':\n return 'Disabled';\n default:\n return 'Not configured';\n }\n}\n"]}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
export type IssueSeverity = 'error' | 'warning';
|
|
2
|
+
export interface Issue {
|
|
3
|
+
code: string;
|
|
4
|
+
severity: IssueSeverity;
|
|
5
|
+
message: string;
|
|
6
|
+
details?: Record<string, unknown>;
|
|
7
|
+
remediation?: string;
|
|
8
|
+
docsUrl?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface SdkInfo {
|
|
11
|
+
name: string | null;
|
|
12
|
+
version: string | null;
|
|
13
|
+
latest: string | null;
|
|
14
|
+
outdated: boolean;
|
|
15
|
+
isAuthKit: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface FrameworkInfo {
|
|
18
|
+
name: string | null;
|
|
19
|
+
version: string | null;
|
|
20
|
+
variant?: string;
|
|
21
|
+
expectedCallbackPath?: string;
|
|
22
|
+
detectedPort?: number;
|
|
23
|
+
}
|
|
24
|
+
export interface RuntimeInfo {
|
|
25
|
+
nodeVersion: string;
|
|
26
|
+
packageManager: string | null;
|
|
27
|
+
packageManagerVersion: string | null;
|
|
28
|
+
}
|
|
29
|
+
export interface EnvironmentInfo {
|
|
30
|
+
apiKeyConfigured: boolean;
|
|
31
|
+
apiKeyType: 'staging' | 'production' | null;
|
|
32
|
+
clientId: string | null;
|
|
33
|
+
redirectUri: string | null;
|
|
34
|
+
cookieDomain: string | null;
|
|
35
|
+
baseUrl: string | null;
|
|
36
|
+
}
|
|
37
|
+
/** Internal environment data - not included in report output */
|
|
38
|
+
export interface EnvironmentRaw {
|
|
39
|
+
apiKey: string | null;
|
|
40
|
+
clientId: string | null;
|
|
41
|
+
baseUrl: string | null;
|
|
42
|
+
}
|
|
43
|
+
export interface EnvironmentCheckResult {
|
|
44
|
+
info: EnvironmentInfo;
|
|
45
|
+
raw: EnvironmentRaw;
|
|
46
|
+
}
|
|
47
|
+
export interface ConnectivityInfo {
|
|
48
|
+
apiReachable: boolean;
|
|
49
|
+
latencyMs: number | null;
|
|
50
|
+
tlsValid: boolean;
|
|
51
|
+
error?: string;
|
|
52
|
+
}
|
|
53
|
+
export interface DashboardSettings {
|
|
54
|
+
redirectUris: string[];
|
|
55
|
+
authMethods: string[];
|
|
56
|
+
sessionTimeout: string | null;
|
|
57
|
+
mfa: 'optional' | 'required' | 'disabled' | null;
|
|
58
|
+
organizationCount: number;
|
|
59
|
+
}
|
|
60
|
+
export interface RedirectUriComparison {
|
|
61
|
+
codeUri: string | null;
|
|
62
|
+
dashboardUris: string[];
|
|
63
|
+
match: boolean;
|
|
64
|
+
source?: 'env' | 'inferred';
|
|
65
|
+
}
|
|
66
|
+
export interface CredentialValidation {
|
|
67
|
+
valid: boolean;
|
|
68
|
+
clientIdMatch: boolean;
|
|
69
|
+
error?: string;
|
|
70
|
+
}
|
|
71
|
+
export interface DashboardFetchResult {
|
|
72
|
+
settings: DashboardSettings | null;
|
|
73
|
+
credentialValidation?: CredentialValidation;
|
|
74
|
+
error?: string;
|
|
75
|
+
}
|
|
76
|
+
export interface DoctorReport {
|
|
77
|
+
version: string;
|
|
78
|
+
timestamp: string;
|
|
79
|
+
project: {
|
|
80
|
+
path: string;
|
|
81
|
+
packageManager: string | null;
|
|
82
|
+
};
|
|
83
|
+
sdk: SdkInfo;
|
|
84
|
+
runtime: RuntimeInfo;
|
|
85
|
+
framework: FrameworkInfo;
|
|
86
|
+
environment: EnvironmentInfo;
|
|
87
|
+
connectivity: ConnectivityInfo;
|
|
88
|
+
dashboardSettings?: DashboardSettings;
|
|
89
|
+
dashboardError?: string;
|
|
90
|
+
redirectUris?: RedirectUriComparison;
|
|
91
|
+
credentialValidation?: CredentialValidation;
|
|
92
|
+
issues: Issue[];
|
|
93
|
+
summary: {
|
|
94
|
+
errors: number;
|
|
95
|
+
warnings: number;
|
|
96
|
+
healthy: boolean;
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
export interface DoctorOptions {
|
|
100
|
+
installDir: string;
|
|
101
|
+
verbose?: boolean;
|
|
102
|
+
skipApi?: boolean;
|
|
103
|
+
json?: boolean;
|
|
104
|
+
copy?: boolean;
|
|
105
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/doctor/types.ts"],"names":[],"mappings":"","sourcesContent":["export type IssueSeverity = 'error' | 'warning';\n\nexport interface Issue {\n code: string;\n severity: IssueSeverity;\n message: string;\n details?: Record<string, unknown>;\n remediation?: string;\n docsUrl?: string;\n}\n\nexport interface SdkInfo {\n name: string | null;\n version: string | null;\n latest: string | null;\n outdated: boolean;\n isAuthKit: boolean;\n}\n\nexport interface FrameworkInfo {\n name: string | null;\n version: string | null;\n variant?: string; // e.g., 'app-router' | 'pages-router'\n expectedCallbackPath?: string; // e.g., '/auth/callback' for Next.js\n detectedPort?: number;\n}\n\nexport interface RuntimeInfo {\n nodeVersion: string;\n packageManager: string | null;\n packageManagerVersion: string | null;\n}\n\nexport interface EnvironmentInfo {\n apiKeyConfigured: boolean;\n apiKeyType: 'staging' | 'production' | null;\n clientId: string | null; // truncated for display\n redirectUri: string | null;\n cookieDomain: string | null;\n baseUrl: string | null;\n}\n\n/** Internal environment data - not included in report output */\nexport interface EnvironmentRaw {\n apiKey: string | null;\n clientId: string | null;\n baseUrl: string | null;\n}\n\nexport interface EnvironmentCheckResult {\n info: EnvironmentInfo;\n raw: EnvironmentRaw;\n}\n\nexport interface ConnectivityInfo {\n apiReachable: boolean;\n latencyMs: number | null;\n tlsValid: boolean;\n error?: string;\n}\n\nexport interface DashboardSettings {\n redirectUris: string[];\n authMethods: string[];\n sessionTimeout: string | null;\n mfa: 'optional' | 'required' | 'disabled' | null;\n organizationCount: number;\n}\n\nexport interface RedirectUriComparison {\n codeUri: string | null;\n dashboardUris: string[];\n match: boolean;\n source?: 'env' | 'inferred'; // Where the codeUri came from\n}\n\nexport interface CredentialValidation {\n valid: boolean;\n clientIdMatch: boolean;\n error?: string;\n}\n\nexport interface DashboardFetchResult {\n settings: DashboardSettings | null;\n credentialValidation?: CredentialValidation;\n error?: string;\n}\n\nexport interface DoctorReport {\n version: string;\n timestamp: string;\n project: {\n path: string;\n packageManager: string | null;\n };\n sdk: SdkInfo;\n runtime: RuntimeInfo;\n framework: FrameworkInfo;\n environment: EnvironmentInfo;\n connectivity: ConnectivityInfo;\n dashboardSettings?: DashboardSettings;\n dashboardError?: string;\n redirectUris?: RedirectUriComparison;\n credentialValidation?: CredentialValidation;\n issues: Issue[];\n summary: {\n errors: number;\n warnings: number;\n healthy: boolean;\n };\n}\n\nexport interface DoctorOptions {\n installDir: string;\n verbose?: boolean;\n skipApi?: boolean;\n json?: boolean;\n copy?: boolean;\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { FrameworkConfig } from '../../lib/framework-config.js';
|
|
2
|
+
import type { InstallerOptions } from '../../utils/types.js';
|
|
3
|
+
export declare const config: FrameworkConfig;
|
|
4
|
+
/**
|
|
5
|
+
* Custom run function for .NET — bypasses runAgentInstaller's JS-centric assumptions
|
|
6
|
+
* (no package.json, no .env.local, no TypeScript detection, no JS port detection).
|
|
7
|
+
*/
|
|
8
|
+
export declare function run(options: InstallerOptions): Promise<string>;
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { enableDebugLogs } from '../../utils/debug.js';
|
|
2
|
+
import { SPINNER_MESSAGE } from '../../lib/framework-config.js';
|
|
3
|
+
import { getOrAskForWorkOSCredentials } from '../../utils/clack-utils.js';
|
|
4
|
+
import { analytics } from '../../utils/analytics.js';
|
|
5
|
+
import { INSTALLER_INTERACTION_EVENT_NAME } from '../../lib/constants.js';
|
|
6
|
+
import { initializeAgent, runAgent } from '../../lib/agent-interface.js';
|
|
7
|
+
import { autoConfigureWorkOSEnvironment } from '../../lib/workos-management.js';
|
|
8
|
+
import { validateInstallation } from '../../lib/validation/index.js';
|
|
9
|
+
export const config = {
|
|
10
|
+
metadata: {
|
|
11
|
+
name: '.NET (ASP.NET Core)',
|
|
12
|
+
integration: 'dotnet',
|
|
13
|
+
docsUrl: 'https://github.com/workos/workos-dotnet',
|
|
14
|
+
skillName: 'workos-dotnet',
|
|
15
|
+
language: 'dotnet',
|
|
16
|
+
stability: 'experimental',
|
|
17
|
+
priority: 35,
|
|
18
|
+
packageManager: 'dotnet',
|
|
19
|
+
manifestFile: '*.csproj',
|
|
20
|
+
},
|
|
21
|
+
detection: {
|
|
22
|
+
// Detection handled by language-detection.ts globExists('*.csproj').
|
|
23
|
+
// These fields satisfy the FrameworkDetection interface but aren't used for non-JS SDKs.
|
|
24
|
+
packageName: 'WorkOS.net',
|
|
25
|
+
packageDisplayName: '.NET (ASP.NET Core)',
|
|
26
|
+
getVersion: () => undefined,
|
|
27
|
+
},
|
|
28
|
+
environment: {
|
|
29
|
+
uploadToHosting: false,
|
|
30
|
+
requiresApiKey: true,
|
|
31
|
+
getEnvVars: (apiKey, clientId) => ({
|
|
32
|
+
WORKOS_API_KEY: apiKey,
|
|
33
|
+
WORKOS_CLIENT_ID: clientId,
|
|
34
|
+
}),
|
|
35
|
+
},
|
|
36
|
+
analytics: {
|
|
37
|
+
getTags: () => ({}),
|
|
38
|
+
},
|
|
39
|
+
prompts: {},
|
|
40
|
+
ui: {
|
|
41
|
+
successMessage: 'WorkOS AuthKit integration complete',
|
|
42
|
+
getOutroChanges: () => [
|
|
43
|
+
'Analyzed your ASP.NET Core project structure',
|
|
44
|
+
'Installed WorkOS.net NuGet package',
|
|
45
|
+
'Created authentication endpoints (login, callback, logout)',
|
|
46
|
+
'Configured WorkOS in appsettings',
|
|
47
|
+
],
|
|
48
|
+
getOutroNextSteps: () => [
|
|
49
|
+
'Run `dotnet run` to start your development server',
|
|
50
|
+
'Visit the WorkOS Dashboard to manage users and settings',
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Custom run function for .NET — bypasses runAgentInstaller's JS-centric assumptions
|
|
56
|
+
* (no package.json, no .env.local, no TypeScript detection, no JS port detection).
|
|
57
|
+
*/
|
|
58
|
+
export async function run(options) {
|
|
59
|
+
if (options.debug) {
|
|
60
|
+
enableDebugLogs();
|
|
61
|
+
}
|
|
62
|
+
options.emitter?.emit('status', {
|
|
63
|
+
message: `Setting up WorkOS AuthKit for ${config.metadata.name}`,
|
|
64
|
+
});
|
|
65
|
+
analytics.capture(INSTALLER_INTERACTION_EVENT_NAME, {
|
|
66
|
+
action: 'started agent integration',
|
|
67
|
+
integration: config.metadata.integration,
|
|
68
|
+
});
|
|
69
|
+
const { apiKey, clientId } = await getOrAskForWorkOSCredentials(options, config.environment.requiresApiKey);
|
|
70
|
+
// Auto-configure WorkOS environment (redirect URI, CORS, homepage)
|
|
71
|
+
const callerHandledConfig = Boolean(options.apiKey || options.clientId);
|
|
72
|
+
if (!callerHandledConfig && apiKey) {
|
|
73
|
+
const port = 5000; // ASP.NET Core default HTTP port
|
|
74
|
+
await autoConfigureWorkOSEnvironment(apiKey, config.metadata.integration, port, {
|
|
75
|
+
homepageUrl: options.homepageUrl,
|
|
76
|
+
redirectUri: options.redirectUri,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
// Build prompt — credentials are passed via prompt context since .NET doesn't use .env.local
|
|
80
|
+
const skillName = config.metadata.skillName;
|
|
81
|
+
const redirectUri = options.redirectUri || 'http://localhost:5000/auth/callback';
|
|
82
|
+
const prompt = `You are integrating WorkOS AuthKit into this ASP.NET Core application.
|
|
83
|
+
|
|
84
|
+
## Project Context
|
|
85
|
+
|
|
86
|
+
- Framework: ASP.NET Core
|
|
87
|
+
- Language: C#
|
|
88
|
+
- Package manager: dotnet (NuGet)
|
|
89
|
+
|
|
90
|
+
## Environment
|
|
91
|
+
|
|
92
|
+
The following WorkOS credentials should be configured in appsettings.Development.json:
|
|
93
|
+
- WORKOS_API_KEY: ${apiKey || '(not provided)'}
|
|
94
|
+
- WORKOS_CLIENT_ID: ${clientId}
|
|
95
|
+
- WORKOS_REDIRECT_URI: ${redirectUri}
|
|
96
|
+
|
|
97
|
+
## Your Task
|
|
98
|
+
|
|
99
|
+
Use the \`${skillName}\` skill to integrate WorkOS AuthKit into this application.
|
|
100
|
+
|
|
101
|
+
The skill contains step-by-step instructions including:
|
|
102
|
+
1. Fetching the SDK documentation
|
|
103
|
+
2. Installing the WorkOS.net NuGet package
|
|
104
|
+
3. Configuring DI registration
|
|
105
|
+
4. Creating authentication endpoints
|
|
106
|
+
5. Setting up appsettings configuration
|
|
107
|
+
|
|
108
|
+
Report your progress using [STATUS] prefixes.
|
|
109
|
+
|
|
110
|
+
Begin by invoking the ${skillName} skill.`;
|
|
111
|
+
const agent = await initializeAgent({
|
|
112
|
+
workingDirectory: options.installDir,
|
|
113
|
+
workOSApiKey: apiKey,
|
|
114
|
+
workOSApiHost: 'https://api.workos.com',
|
|
115
|
+
}, options);
|
|
116
|
+
const agentResult = await runAgent(agent, prompt, options, {
|
|
117
|
+
spinnerMessage: SPINNER_MESSAGE,
|
|
118
|
+
successMessage: config.ui.successMessage,
|
|
119
|
+
errorMessage: 'Integration failed',
|
|
120
|
+
}, options.emitter);
|
|
121
|
+
if (agentResult.error) {
|
|
122
|
+
await analytics.shutdown('error');
|
|
123
|
+
const message = agentResult.errorMessage || agentResult.error;
|
|
124
|
+
throw new Error(`Agent SDK error: ${message}`);
|
|
125
|
+
}
|
|
126
|
+
// Post-installation validation
|
|
127
|
+
if (!options.noValidate) {
|
|
128
|
+
options.emitter?.emit('validation:start', { framework: config.metadata.integration });
|
|
129
|
+
const validationResult = await validateInstallation(config.metadata.integration, options.installDir, {
|
|
130
|
+
runBuild: true,
|
|
131
|
+
});
|
|
132
|
+
if (validationResult.issues.length > 0) {
|
|
133
|
+
options.emitter?.emit('validation:issues', { issues: validationResult.issues });
|
|
134
|
+
}
|
|
135
|
+
options.emitter?.emit('validation:complete', {
|
|
136
|
+
passed: validationResult.passed,
|
|
137
|
+
issueCount: validationResult.issues.length,
|
|
138
|
+
durationMs: validationResult.durationMs,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
const envVars = config.environment.getEnvVars(apiKey, clientId);
|
|
142
|
+
const changes = [
|
|
143
|
+
...config.ui.getOutroChanges({}),
|
|
144
|
+
Object.keys(envVars).length > 0 ? 'Configured WorkOS credentials in appsettings' : '',
|
|
145
|
+
].filter(Boolean);
|
|
146
|
+
const nextSteps = config.ui.getOutroNextSteps({});
|
|
147
|
+
const lines = [
|
|
148
|
+
'Successfully installed WorkOS AuthKit!',
|
|
149
|
+
'',
|
|
150
|
+
'What the agent did:',
|
|
151
|
+
...changes.map((c) => `• ${c}`),
|
|
152
|
+
'',
|
|
153
|
+
'Next steps:',
|
|
154
|
+
...nextSteps.map((s) => `• ${s}`),
|
|
155
|
+
'',
|
|
156
|
+
`Learn more: ${config.metadata.docsUrl}`,
|
|
157
|
+
'',
|
|
158
|
+
'Note: This installer uses an LLM agent to analyze and modify your project. Please review the changes made.',
|
|
159
|
+
];
|
|
160
|
+
await analytics.shutdown('success');
|
|
161
|
+
return lines.join('\n');
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/integrations/dotnet/index.ts"],"names":[],"mappings":"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","sourcesContent":["/* .NET (ASP.NET Core) integration — auto-discovered by registry */\nimport type { FrameworkConfig } from '../../lib/framework-config.js';\nimport type { InstallerOptions } from '../../utils/types.js';\nimport { enableDebugLogs } from '../../utils/debug.js';\nimport { SPINNER_MESSAGE } from '../../lib/framework-config.js';\nimport { getOrAskForWorkOSCredentials } from '../../utils/clack-utils.js';\nimport { analytics } from '../../utils/analytics.js';\nimport { INSTALLER_INTERACTION_EVENT_NAME } from '../../lib/constants.js';\nimport { initializeAgent, runAgent } from '../../lib/agent-interface.js';\nimport { autoConfigureWorkOSEnvironment } from '../../lib/workos-management.js';\nimport { validateInstallation } from '../../lib/validation/index.js';\n\nexport const config: FrameworkConfig = {\n metadata: {\n name: '.NET (ASP.NET Core)',\n integration: 'dotnet',\n docsUrl: 'https://github.com/workos/workos-dotnet',\n skillName: 'workos-dotnet',\n language: 'dotnet',\n stability: 'experimental',\n priority: 35,\n packageManager: 'dotnet',\n manifestFile: '*.csproj',\n },\n\n detection: {\n // Detection handled by language-detection.ts globExists('*.csproj').\n // These fields satisfy the FrameworkDetection interface but aren't used for non-JS SDKs.\n packageName: 'WorkOS.net',\n packageDisplayName: '.NET (ASP.NET Core)',\n getVersion: () => undefined,\n },\n\n environment: {\n uploadToHosting: false,\n requiresApiKey: true,\n getEnvVars: (apiKey: string, clientId: string) => ({\n WORKOS_API_KEY: apiKey,\n WORKOS_CLIENT_ID: clientId,\n }),\n },\n\n analytics: {\n getTags: () => ({}),\n },\n\n prompts: {},\n\n ui: {\n successMessage: 'WorkOS AuthKit integration complete',\n getOutroChanges: () => [\n 'Analyzed your ASP.NET Core project structure',\n 'Installed WorkOS.net NuGet package',\n 'Created authentication endpoints (login, callback, logout)',\n 'Configured WorkOS in appsettings',\n ],\n getOutroNextSteps: () => [\n 'Run `dotnet run` to start your development server',\n 'Visit the WorkOS Dashboard to manage users and settings',\n ],\n },\n};\n\n/**\n * Custom run function for .NET — bypasses runAgentInstaller's JS-centric assumptions\n * (no package.json, no .env.local, no TypeScript detection, no JS port detection).\n */\nexport async function run(options: InstallerOptions): Promise<string> {\n if (options.debug) {\n enableDebugLogs();\n }\n\n options.emitter?.emit('status', {\n message: `Setting up WorkOS AuthKit for ${config.metadata.name}`,\n });\n\n analytics.capture(INSTALLER_INTERACTION_EVENT_NAME, {\n action: 'started agent integration',\n integration: config.metadata.integration,\n });\n\n const { apiKey, clientId } = await getOrAskForWorkOSCredentials(options, config.environment.requiresApiKey);\n\n // Auto-configure WorkOS environment (redirect URI, CORS, homepage)\n const callerHandledConfig = Boolean(options.apiKey || options.clientId);\n if (!callerHandledConfig && apiKey) {\n const port = 5000; // ASP.NET Core default HTTP port\n await autoConfigureWorkOSEnvironment(apiKey, config.metadata.integration, port, {\n homepageUrl: options.homepageUrl,\n redirectUri: options.redirectUri,\n });\n }\n\n // Build prompt — credentials are passed via prompt context since .NET doesn't use .env.local\n const skillName = config.metadata.skillName!;\n const redirectUri = options.redirectUri || 'http://localhost:5000/auth/callback';\n\n const prompt = `You are integrating WorkOS AuthKit into this ASP.NET Core application.\n\n## Project Context\n\n- Framework: ASP.NET Core\n- Language: C#\n- Package manager: dotnet (NuGet)\n\n## Environment\n\nThe following WorkOS credentials should be configured in appsettings.Development.json:\n- WORKOS_API_KEY: ${apiKey || '(not provided)'}\n- WORKOS_CLIENT_ID: ${clientId}\n- WORKOS_REDIRECT_URI: ${redirectUri}\n\n## Your Task\n\nUse the \\`${skillName}\\` skill to integrate WorkOS AuthKit into this application.\n\nThe skill contains step-by-step instructions including:\n1. Fetching the SDK documentation\n2. Installing the WorkOS.net NuGet package\n3. Configuring DI registration\n4. Creating authentication endpoints\n5. Setting up appsettings configuration\n\nReport your progress using [STATUS] prefixes.\n\nBegin by invoking the ${skillName} skill.`;\n\n const agent = await initializeAgent(\n {\n workingDirectory: options.installDir,\n workOSApiKey: apiKey,\n workOSApiHost: 'https://api.workos.com',\n },\n options,\n );\n\n const agentResult = await runAgent(\n agent,\n prompt,\n options,\n {\n spinnerMessage: SPINNER_MESSAGE,\n successMessage: config.ui.successMessage,\n errorMessage: 'Integration failed',\n },\n options.emitter,\n );\n\n if (agentResult.error) {\n await analytics.shutdown('error');\n const message = agentResult.errorMessage || agentResult.error;\n throw new Error(`Agent SDK error: ${message}`);\n }\n\n // Post-installation validation\n if (!options.noValidate) {\n options.emitter?.emit('validation:start', { framework: config.metadata.integration });\n\n const validationResult = await validateInstallation(config.metadata.integration, options.installDir, {\n runBuild: true,\n });\n\n if (validationResult.issues.length > 0) {\n options.emitter?.emit('validation:issues', { issues: validationResult.issues });\n }\n\n options.emitter?.emit('validation:complete', {\n passed: validationResult.passed,\n issueCount: validationResult.issues.length,\n durationMs: validationResult.durationMs,\n });\n }\n\n const envVars = config.environment.getEnvVars(apiKey, clientId);\n\n const changes = [\n ...config.ui.getOutroChanges({}),\n Object.keys(envVars).length > 0 ? 'Configured WorkOS credentials in appsettings' : '',\n ].filter(Boolean);\n\n const nextSteps = config.ui.getOutroNextSteps({});\n\n const lines: string[] = [\n 'Successfully installed WorkOS AuthKit!',\n '',\n 'What the agent did:',\n ...changes.map((c) => `• ${c}`),\n '',\n 'Next steps:',\n ...nextSteps.map((s) => `• ${s}`),\n '',\n `Learn more: ${config.metadata.docsUrl}`,\n '',\n 'Note: This installer uses an LLM agent to analyze and modify your project. Please review the changes made.',\n ];\n\n await analytics.shutdown('success');\n\n return lines.join('\\n');\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { FrameworkConfig } from '../../lib/framework-config.js';
|
|
2
|
+
import type { InstallerOptions } from '../../utils/types.js';
|
|
3
|
+
export declare const config: FrameworkConfig;
|
|
4
|
+
/**
|
|
5
|
+
* Custom run function for Elixir — bypasses runAgentInstaller() which assumes
|
|
6
|
+
* package.json exists. Directly calls initializeAgent/runAgent instead.
|
|
7
|
+
*/
|
|
8
|
+
export declare function run(options: InstallerOptions): Promise<string>;
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { enableDebugLogs } from '../../utils/debug.js';
|
|
2
|
+
import { SPINNER_MESSAGE } from '../../lib/framework-config.js';
|
|
3
|
+
import { analytics } from '../../utils/analytics.js';
|
|
4
|
+
import { INSTALLER_INTERACTION_EVENT_NAME } from '../../lib/constants.js';
|
|
5
|
+
import { getOrAskForWorkOSCredentials } from '../../utils/clack-utils.js';
|
|
6
|
+
import { initializeAgent, runAgent } from '../../lib/agent-interface.js';
|
|
7
|
+
import { writeEnvLocal } from '../../lib/env-writer.js';
|
|
8
|
+
export const config = {
|
|
9
|
+
metadata: {
|
|
10
|
+
name: 'Elixir (Phoenix)',
|
|
11
|
+
integration: 'elixir',
|
|
12
|
+
docsUrl: 'https://github.com/workos/workos-elixir',
|
|
13
|
+
skillName: 'workos-elixir',
|
|
14
|
+
language: 'elixir',
|
|
15
|
+
stability: 'experimental',
|
|
16
|
+
priority: 30,
|
|
17
|
+
packageManager: 'mix',
|
|
18
|
+
manifestFile: 'mix.exs',
|
|
19
|
+
},
|
|
20
|
+
detection: {
|
|
21
|
+
// Required by FrameworkDetection interface — stubs for non-JS integration.
|
|
22
|
+
// Actual detection uses language-detection.ts (mix.exs) + registry manifestFile check.
|
|
23
|
+
packageName: 'workos',
|
|
24
|
+
packageDisplayName: 'WorkOS Elixir',
|
|
25
|
+
getVersion: () => undefined,
|
|
26
|
+
},
|
|
27
|
+
environment: {
|
|
28
|
+
uploadToHosting: false,
|
|
29
|
+
requiresApiKey: true,
|
|
30
|
+
getEnvVars: (apiKey, clientId) => ({
|
|
31
|
+
WORKOS_API_KEY: apiKey,
|
|
32
|
+
WORKOS_CLIENT_ID: clientId,
|
|
33
|
+
}),
|
|
34
|
+
},
|
|
35
|
+
analytics: {
|
|
36
|
+
getTags: () => ({}),
|
|
37
|
+
},
|
|
38
|
+
prompts: {},
|
|
39
|
+
ui: {
|
|
40
|
+
successMessage: 'WorkOS AuthKit integration complete',
|
|
41
|
+
getOutroChanges: () => [
|
|
42
|
+
'Analyzed your Phoenix project structure',
|
|
43
|
+
'Installed workos Hex package',
|
|
44
|
+
'Configured WorkOS in config/runtime.exs',
|
|
45
|
+
'Created auth controller and routes',
|
|
46
|
+
],
|
|
47
|
+
getOutroNextSteps: () => [
|
|
48
|
+
'Run `mix phx.server` to test authentication',
|
|
49
|
+
'Visit the WorkOS Dashboard to manage users and settings',
|
|
50
|
+
],
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
/**
|
|
54
|
+
* Custom run function for Elixir — bypasses runAgentInstaller() which assumes
|
|
55
|
+
* package.json exists. Directly calls initializeAgent/runAgent instead.
|
|
56
|
+
*/
|
|
57
|
+
export async function run(options) {
|
|
58
|
+
if (options.debug) {
|
|
59
|
+
enableDebugLogs();
|
|
60
|
+
}
|
|
61
|
+
options.emitter?.emit('status', {
|
|
62
|
+
message: `Setting up WorkOS AuthKit for ${config.metadata.name}`,
|
|
63
|
+
});
|
|
64
|
+
analytics.capture(INSTALLER_INTERACTION_EVENT_NAME, {
|
|
65
|
+
action: 'started agent integration',
|
|
66
|
+
integration: config.metadata.integration,
|
|
67
|
+
});
|
|
68
|
+
// Get WorkOS credentials
|
|
69
|
+
const { apiKey, clientId } = await getOrAskForWorkOSCredentials(options, config.environment.requiresApiKey);
|
|
70
|
+
// Write env vars to .env.local for the agent to reference
|
|
71
|
+
const callerHandledConfig = Boolean(options.apiKey || options.clientId);
|
|
72
|
+
if (!callerHandledConfig) {
|
|
73
|
+
const port = 4000; // Phoenix default
|
|
74
|
+
const callbackPath = '/auth/callback';
|
|
75
|
+
const redirectUri = options.redirectUri || `http://localhost:${port}${callbackPath}`;
|
|
76
|
+
writeEnvLocal(options.installDir, {
|
|
77
|
+
...(apiKey ? { WORKOS_API_KEY: apiKey } : {}),
|
|
78
|
+
WORKOS_CLIENT_ID: clientId,
|
|
79
|
+
WORKOS_REDIRECT_URI: redirectUri,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
// Build Elixir-specific prompt
|
|
83
|
+
const integrationPrompt = buildElixirPrompt();
|
|
84
|
+
// Initialize and run agent
|
|
85
|
+
const agent = await initializeAgent({
|
|
86
|
+
workingDirectory: options.installDir,
|
|
87
|
+
workOSApiKey: apiKey,
|
|
88
|
+
workOSApiHost: 'https://api.workos.com',
|
|
89
|
+
}, options);
|
|
90
|
+
const agentResult = await runAgent(agent, integrationPrompt, options, {
|
|
91
|
+
spinnerMessage: SPINNER_MESSAGE,
|
|
92
|
+
successMessage: config.ui.successMessage,
|
|
93
|
+
errorMessage: 'Integration failed',
|
|
94
|
+
}, options.emitter);
|
|
95
|
+
if (agentResult.error) {
|
|
96
|
+
await analytics.shutdown('error');
|
|
97
|
+
const message = agentResult.errorMessage || agentResult.error;
|
|
98
|
+
throw new Error(`Agent SDK error: ${message}`);
|
|
99
|
+
}
|
|
100
|
+
// Build summary
|
|
101
|
+
const changes = config.ui.getOutroChanges({});
|
|
102
|
+
const nextSteps = config.ui.getOutroNextSteps({});
|
|
103
|
+
const lines = [
|
|
104
|
+
'Successfully installed WorkOS AuthKit!',
|
|
105
|
+
'',
|
|
106
|
+
'What the agent did:',
|
|
107
|
+
...changes.map((c) => `• ${c}`),
|
|
108
|
+
'',
|
|
109
|
+
'Next steps:',
|
|
110
|
+
...nextSteps.map((s) => `• ${s}`),
|
|
111
|
+
'',
|
|
112
|
+
`Learn more: ${config.metadata.docsUrl}`,
|
|
113
|
+
'',
|
|
114
|
+
'Note: This installer uses an LLM agent to analyze and modify your project. Please review the changes made.',
|
|
115
|
+
];
|
|
116
|
+
await analytics.shutdown('success');
|
|
117
|
+
return lines.join('\n');
|
|
118
|
+
}
|
|
119
|
+
function buildElixirPrompt() {
|
|
120
|
+
return `You are integrating WorkOS AuthKit into this Elixir/Phoenix application.
|
|
121
|
+
|
|
122
|
+
## Project Context
|
|
123
|
+
|
|
124
|
+
- Framework: Phoenix (Elixir)
|
|
125
|
+
- Package manager: mix (Hex)
|
|
126
|
+
|
|
127
|
+
## Environment
|
|
128
|
+
|
|
129
|
+
The following environment variables have been configured in .env.local:
|
|
130
|
+
- WORKOS_API_KEY
|
|
131
|
+
- WORKOS_CLIENT_ID
|
|
132
|
+
- WORKOS_REDIRECT_URI
|
|
133
|
+
|
|
134
|
+
Note: For Elixir/Phoenix, these should be read via System.get_env() in config/runtime.exs rather than from .env.local directly.
|
|
135
|
+
|
|
136
|
+
## Your Task
|
|
137
|
+
|
|
138
|
+
Use the \`workos-elixir\` skill to integrate WorkOS AuthKit into this application.
|
|
139
|
+
|
|
140
|
+
The skill contains step-by-step instructions including:
|
|
141
|
+
1. Fetching the SDK documentation
|
|
142
|
+
2. Validating the Phoenix project structure
|
|
143
|
+
3. Installing the workos Hex package
|
|
144
|
+
4. Configuring WorkOS in runtime.exs
|
|
145
|
+
5. Creating auth controller and routes
|
|
146
|
+
6. Verification with mix compile
|
|
147
|
+
|
|
148
|
+
Report your progress using [STATUS] prefixes.
|
|
149
|
+
|
|
150
|
+
Begin by invoking the workos-elixir skill.`;
|
|
151
|
+
}
|
|
152
|
+
//# sourceMappingURL=index.js.map
|