workos 0.3.3 → 0.5.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/dist/bin.js +57 -9
- 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/commands/login.js +21 -1
- package/dist/commands/login.js.map +1 -1
- 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/credential-store.d.ts +28 -0
- package/dist/lib/credential-store.js +150 -0
- package/dist/lib/credential-store.js.map +1 -0
- package/dist/lib/credentials.d.ts +3 -37
- package/dist/lib/credentials.js +2 -85
- package/dist/lib/credentials.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/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 +9 -6
- 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
package/dist/lib/constants.d.ts
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Integration identifier type.
|
|
3
|
+
* No longer an enum — each integration self-registers via the auto-discovery registry.
|
|
4
|
+
* The string value matches the integration directory name (e.g., 'nextjs', 'react-router').
|
|
5
|
+
*/
|
|
6
|
+
export type Integration = string;
|
|
7
|
+
/**
|
|
8
|
+
* Well-known integration names for backwards compatibility.
|
|
9
|
+
* New integrations do NOT need to be added here — they're auto-discovered.
|
|
10
|
+
*/
|
|
11
|
+
export declare const KNOWN_INTEGRATIONS: {
|
|
12
|
+
readonly nextjs: "nextjs";
|
|
13
|
+
readonly react: "react";
|
|
14
|
+
readonly tanstackStart: "tanstack-start";
|
|
15
|
+
readonly reactRouter: "react-router";
|
|
16
|
+
readonly vanillaJs: "vanilla-js";
|
|
12
17
|
};
|
|
13
|
-
export declare function getIntegrationChoices(): IntegrationChoice[];
|
|
14
18
|
export interface Args {
|
|
15
19
|
debug: boolean;
|
|
16
20
|
integration: Integration;
|
|
@@ -26,7 +30,6 @@ export declare const WORKOS_TELEMETRY_ENABLED: boolean;
|
|
|
26
30
|
export declare const OAUTH_PORT: number;
|
|
27
31
|
/**
|
|
28
32
|
* Common glob patterns to ignore when searching for files.
|
|
29
|
-
* Used by
|
|
33
|
+
* Used by multiple integrations.
|
|
30
34
|
*/
|
|
31
35
|
export declare const IGNORE_PATTERNS: string[];
|
|
32
|
-
export {};
|
package/dist/lib/constants.js
CHANGED
|
@@ -1,34 +1,15 @@
|
|
|
1
1
|
import { getConfig } from './settings.js';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
return 'Next.js';
|
|
14
|
-
case Integration.react:
|
|
15
|
-
return 'React (SPA)';
|
|
16
|
-
case Integration.tanstackStart:
|
|
17
|
-
return 'TanStack Start';
|
|
18
|
-
case Integration.reactRouter:
|
|
19
|
-
return 'React Router';
|
|
20
|
-
case Integration.vanillaJs:
|
|
21
|
-
return 'Vanilla JavaScript';
|
|
22
|
-
default:
|
|
23
|
-
throw new Error(`Unknown integration ${type}`);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
export function getIntegrationChoices() {
|
|
27
|
-
return Object.keys(Integration).map((type) => ({
|
|
28
|
-
name: getIntegrationDescription(type),
|
|
29
|
-
value: type,
|
|
30
|
-
}));
|
|
31
|
-
}
|
|
2
|
+
/**
|
|
3
|
+
* Well-known integration names for backwards compatibility.
|
|
4
|
+
* New integrations do NOT need to be added here — they're auto-discovered.
|
|
5
|
+
*/
|
|
6
|
+
export const KNOWN_INTEGRATIONS = {
|
|
7
|
+
nextjs: 'nextjs',
|
|
8
|
+
react: 'react',
|
|
9
|
+
tanstackStart: 'tanstack-start',
|
|
10
|
+
reactRouter: 'react-router',
|
|
11
|
+
vanillaJs: 'vanilla-js',
|
|
12
|
+
};
|
|
32
13
|
export const IS_DEV = ['test', 'development'].includes(process.env.NODE_ENV ?? '');
|
|
33
14
|
const settings = getConfig();
|
|
34
15
|
export const DEBUG = settings.logging.debugMode;
|
|
@@ -41,7 +22,7 @@ export const WORKOS_TELEMETRY_ENABLED = process.env.WORKOS_TELEMETRY !== 'false'
|
|
|
41
22
|
export const OAUTH_PORT = settings.legacy.oauthPort;
|
|
42
23
|
/**
|
|
43
24
|
* Common glob patterns to ignore when searching for files.
|
|
44
|
-
* Used by
|
|
25
|
+
* Used by multiple integrations.
|
|
45
26
|
*/
|
|
46
27
|
export const IGNORE_PATTERNS = [
|
|
47
28
|
'**/node_modules/**',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/lib/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;
|
|
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,wBAAwB,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,KAAK,OAAO,CAAC;AACjF,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 WORKOS_TELEMETRY_ENABLED = process.env.WORKOS_TELEMETRY !== 'false';\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,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Credential storage abstraction with keyring support and file fallback.
|
|
3
|
+
*
|
|
4
|
+
* Storage priority:
|
|
5
|
+
* 1. If --insecure-storage: use file only
|
|
6
|
+
* 2. Try keyring, fall back to file with warning if unavailable
|
|
7
|
+
*/
|
|
8
|
+
export interface StagingCache {
|
|
9
|
+
clientId: string;
|
|
10
|
+
apiKey: string;
|
|
11
|
+
fetchedAt: number;
|
|
12
|
+
}
|
|
13
|
+
export interface Credentials {
|
|
14
|
+
accessToken: string;
|
|
15
|
+
expiresAt: number;
|
|
16
|
+
userId: string;
|
|
17
|
+
email?: string;
|
|
18
|
+
staging?: StagingCache;
|
|
19
|
+
refreshToken?: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function setInsecureStorage(value: boolean): void;
|
|
22
|
+
declare function getCredentialsPath(): string;
|
|
23
|
+
export declare function hasCredentials(): boolean;
|
|
24
|
+
export declare function getCredentials(): Credentials | null;
|
|
25
|
+
export declare function saveCredentials(creds: Credentials): void;
|
|
26
|
+
export declare function clearCredentials(): void;
|
|
27
|
+
export declare function updateTokens(accessToken: string, expiresAt: number, refreshToken?: string): void;
|
|
28
|
+
export { getCredentialsPath };
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Credential storage abstraction with keyring support and file fallback.
|
|
3
|
+
*
|
|
4
|
+
* Storage priority:
|
|
5
|
+
* 1. If --insecure-storage: use file only
|
|
6
|
+
* 2. Try keyring, fall back to file with warning if unavailable
|
|
7
|
+
*/
|
|
8
|
+
import { Entry } from '@napi-rs/keyring';
|
|
9
|
+
import fs from 'node:fs';
|
|
10
|
+
import path from 'node:path';
|
|
11
|
+
import os from 'node:os';
|
|
12
|
+
import { logWarn } from '../utils/debug.js';
|
|
13
|
+
const SERVICE_NAME = 'workos-cli';
|
|
14
|
+
const ACCOUNT_NAME = 'credentials';
|
|
15
|
+
let fallbackWarningShown = false;
|
|
16
|
+
let forceInsecureStorage = false;
|
|
17
|
+
export function setInsecureStorage(value) {
|
|
18
|
+
forceInsecureStorage = value;
|
|
19
|
+
}
|
|
20
|
+
function getCredentialsDir() {
|
|
21
|
+
return path.join(os.homedir(), '.workos');
|
|
22
|
+
}
|
|
23
|
+
function getCredentialsPath() {
|
|
24
|
+
return path.join(getCredentialsDir(), 'credentials.json');
|
|
25
|
+
}
|
|
26
|
+
function fileExists() {
|
|
27
|
+
return fs.existsSync(getCredentialsPath());
|
|
28
|
+
}
|
|
29
|
+
function readFromFile() {
|
|
30
|
+
if (!fileExists())
|
|
31
|
+
return null;
|
|
32
|
+
try {
|
|
33
|
+
const content = fs.readFileSync(getCredentialsPath(), 'utf-8');
|
|
34
|
+
return JSON.parse(content);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
logWarn('Failed to read credentials file:', error);
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function writeToFile(creds) {
|
|
42
|
+
const dir = getCredentialsDir();
|
|
43
|
+
if (!fs.existsSync(dir)) {
|
|
44
|
+
fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
45
|
+
}
|
|
46
|
+
fs.writeFileSync(getCredentialsPath(), JSON.stringify(creds, null, 2), {
|
|
47
|
+
mode: 0o600,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
function deleteFile() {
|
|
51
|
+
if (fileExists()) {
|
|
52
|
+
fs.unlinkSync(getCredentialsPath());
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function getKeyringEntry() {
|
|
56
|
+
return new Entry(SERVICE_NAME, ACCOUNT_NAME);
|
|
57
|
+
}
|
|
58
|
+
function readFromKeyring() {
|
|
59
|
+
try {
|
|
60
|
+
const entry = getKeyringEntry();
|
|
61
|
+
const data = entry.getPassword();
|
|
62
|
+
if (!data)
|
|
63
|
+
return null;
|
|
64
|
+
return JSON.parse(data);
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
logWarn('Failed to read from keyring:', error);
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function writeToKeyring(creds) {
|
|
72
|
+
try {
|
|
73
|
+
const entry = getKeyringEntry();
|
|
74
|
+
entry.setPassword(JSON.stringify(creds));
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
logWarn('Failed to write to keyring:', error);
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
function deleteFromKeyring() {
|
|
83
|
+
try {
|
|
84
|
+
const entry = getKeyringEntry();
|
|
85
|
+
entry.deletePassword();
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
89
|
+
if (!msg.includes('not found') && !msg.includes('No such')) {
|
|
90
|
+
logWarn('Failed to delete from keyring:', error);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
function showFallbackWarning() {
|
|
95
|
+
if (fallbackWarningShown || forceInsecureStorage)
|
|
96
|
+
return;
|
|
97
|
+
fallbackWarningShown = true;
|
|
98
|
+
logWarn('Unable to store credentials in system keyring. Using file storage.', 'Credentials saved to ~/.workos/credentials.json', 'Use --insecure-storage to suppress this warning.');
|
|
99
|
+
}
|
|
100
|
+
export function hasCredentials() {
|
|
101
|
+
if (forceInsecureStorage) {
|
|
102
|
+
return fileExists();
|
|
103
|
+
}
|
|
104
|
+
return readFromKeyring() !== null || fileExists();
|
|
105
|
+
}
|
|
106
|
+
export function getCredentials() {
|
|
107
|
+
if (forceInsecureStorage)
|
|
108
|
+
return readFromFile();
|
|
109
|
+
const keyringCreds = readFromKeyring();
|
|
110
|
+
if (keyringCreds)
|
|
111
|
+
return keyringCreds;
|
|
112
|
+
const fileCreds = readFromFile();
|
|
113
|
+
if (fileCreds) {
|
|
114
|
+
// Migrate file creds to keyring if possible
|
|
115
|
+
if (writeToKeyring(fileCreds))
|
|
116
|
+
deleteFile();
|
|
117
|
+
return fileCreds;
|
|
118
|
+
}
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
export function saveCredentials(creds) {
|
|
122
|
+
if (forceInsecureStorage)
|
|
123
|
+
return writeToFile(creds);
|
|
124
|
+
if (writeToKeyring(creds)) {
|
|
125
|
+
deleteFile();
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
showFallbackWarning();
|
|
129
|
+
writeToFile(creds);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
export function clearCredentials() {
|
|
133
|
+
deleteFromKeyring();
|
|
134
|
+
deleteFile();
|
|
135
|
+
}
|
|
136
|
+
export function updateTokens(accessToken, expiresAt, refreshToken) {
|
|
137
|
+
const creds = getCredentials();
|
|
138
|
+
if (!creds) {
|
|
139
|
+
throw new Error('No existing credentials to update');
|
|
140
|
+
}
|
|
141
|
+
const updated = {
|
|
142
|
+
...creds,
|
|
143
|
+
accessToken,
|
|
144
|
+
expiresAt,
|
|
145
|
+
...(refreshToken && { refreshToken }),
|
|
146
|
+
};
|
|
147
|
+
saveCredentials(updated);
|
|
148
|
+
}
|
|
149
|
+
export { getCredentialsPath };
|
|
150
|
+
//# sourceMappingURL=credential-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential-store.js","sourceRoot":"","sources":["../../src/lib/credential-store.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Credential storage abstraction with keyring support and file fallback.\n *\n * Storage priority:\n * 1. If --insecure-storage: use file only\n * 2. Try keyring, fall back to file with warning if unavailable\n */\n\nimport { Entry } from '@napi-rs/keyring';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport os from 'node:os';\nimport { logWarn } from '../utils/debug.js';\n\nexport interface StagingCache {\n clientId: string;\n apiKey: string;\n fetchedAt: number;\n}\n\nexport interface Credentials {\n accessToken: string;\n expiresAt: number;\n userId: string;\n email?: string;\n staging?: StagingCache;\n refreshToken?: string;\n}\n\nconst SERVICE_NAME = 'workos-cli';\nconst ACCOUNT_NAME = 'credentials';\n\nlet fallbackWarningShown = false;\nlet forceInsecureStorage = false;\n\nexport function setInsecureStorage(value: boolean): void {\n forceInsecureStorage = value;\n}\n\nfunction getCredentialsDir(): string {\n return path.join(os.homedir(), '.workos');\n}\n\nfunction getCredentialsPath(): string {\n return path.join(getCredentialsDir(), 'credentials.json');\n}\n\nfunction fileExists(): boolean {\n return fs.existsSync(getCredentialsPath());\n}\n\nfunction readFromFile(): Credentials | null {\n if (!fileExists()) return null;\n try {\n const content = fs.readFileSync(getCredentialsPath(), 'utf-8');\n return JSON.parse(content);\n } catch (error) {\n logWarn('Failed to read credentials file:', error);\n return null;\n }\n}\n\nfunction writeToFile(creds: Credentials): void {\n const dir = getCredentialsDir();\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true, mode: 0o700 });\n }\n fs.writeFileSync(getCredentialsPath(), JSON.stringify(creds, null, 2), {\n mode: 0o600,\n });\n}\n\nfunction deleteFile(): void {\n if (fileExists()) {\n fs.unlinkSync(getCredentialsPath());\n }\n}\n\nfunction getKeyringEntry(): Entry {\n return new Entry(SERVICE_NAME, ACCOUNT_NAME);\n}\n\nfunction readFromKeyring(): Credentials | null {\n try {\n const entry = getKeyringEntry();\n const data = entry.getPassword();\n if (!data) return null;\n return JSON.parse(data);\n } catch (error) {\n logWarn('Failed to read from keyring:', error);\n return null;\n }\n}\n\nfunction writeToKeyring(creds: Credentials): boolean {\n try {\n const entry = getKeyringEntry();\n entry.setPassword(JSON.stringify(creds));\n return true;\n } catch (error) {\n logWarn('Failed to write to keyring:', error);\n return false;\n }\n}\n\nfunction deleteFromKeyring(): void {\n try {\n const entry = getKeyringEntry();\n entry.deletePassword();\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n if (!msg.includes('not found') && !msg.includes('No such')) {\n logWarn('Failed to delete from keyring:', error);\n }\n }\n}\n\nfunction showFallbackWarning(): void {\n if (fallbackWarningShown || forceInsecureStorage) return;\n fallbackWarningShown = true;\n logWarn(\n 'Unable to store credentials in system keyring. Using file storage.',\n 'Credentials saved to ~/.workos/credentials.json',\n 'Use --insecure-storage to suppress this warning.',\n );\n}\n\nexport function hasCredentials(): boolean {\n if (forceInsecureStorage) {\n return fileExists();\n }\n return readFromKeyring() !== null || fileExists();\n}\n\nexport function getCredentials(): Credentials | null {\n if (forceInsecureStorage) return readFromFile();\n\n const keyringCreds = readFromKeyring();\n if (keyringCreds) return keyringCreds;\n\n const fileCreds = readFromFile();\n if (fileCreds) {\n // Migrate file creds to keyring if possible\n if (writeToKeyring(fileCreds)) deleteFile();\n return fileCreds;\n }\n\n return null;\n}\n\nexport function saveCredentials(creds: Credentials): void {\n if (forceInsecureStorage) return writeToFile(creds);\n\n if (writeToKeyring(creds)) {\n deleteFile();\n } else {\n showFallbackWarning();\n writeToFile(creds);\n }\n}\n\nexport function clearCredentials(): void {\n deleteFromKeyring();\n deleteFile();\n}\n\nexport function updateTokens(accessToken: string, expiresAt: number, refreshToken?: string): void {\n const creds = getCredentials();\n if (!creds) {\n throw new Error('No existing credentials to update');\n }\n\n const updated: Credentials = {\n ...creds,\n accessToken,\n expiresAt,\n ...(refreshToken && { refreshToken }),\n };\n\n saveCredentials(updated);\n}\n\nexport { getCredentialsPath };\n"]}
|
|
@@ -1,47 +1,13 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
fetchedAt: number;
|
|
5
|
-
}
|
|
6
|
-
export interface Credentials {
|
|
7
|
-
accessToken: string;
|
|
8
|
-
expiresAt: number;
|
|
9
|
-
userId: string;
|
|
10
|
-
email?: string;
|
|
11
|
-
staging?: StagingCache;
|
|
12
|
-
refreshToken?: string;
|
|
13
|
-
}
|
|
14
|
-
export declare function getCredentialsPath(): string;
|
|
15
|
-
export declare function hasCredentials(): boolean;
|
|
16
|
-
export declare function getCredentials(): Credentials | null;
|
|
17
|
-
export declare function saveCredentials(creds: Credentials): void;
|
|
18
|
-
export declare function clearCredentials(): void;
|
|
19
|
-
/**
|
|
20
|
-
* Check if token is actually expired (hard expiry check).
|
|
21
|
-
*/
|
|
1
|
+
export type { StagingCache, Credentials } from './credential-store.js';
|
|
2
|
+
export { hasCredentials, getCredentials, saveCredentials, clearCredentials, updateTokens, getCredentialsPath, setInsecureStorage, } from './credential-store.js';
|
|
3
|
+
import type { Credentials } from './credential-store.js';
|
|
22
4
|
export declare function isTokenExpired(creds: Credentials): boolean;
|
|
23
|
-
/**
|
|
24
|
-
* Get access token if available and not expired.
|
|
25
|
-
*/
|
|
26
5
|
export declare function getAccessToken(): string | null;
|
|
27
|
-
/**
|
|
28
|
-
* Save staging credentials to the credential cache.
|
|
29
|
-
* Staging credentials are tied to the access token lifecycle.
|
|
30
|
-
*/
|
|
31
6
|
export declare function saveStagingCredentials(staging: {
|
|
32
7
|
clientId: string;
|
|
33
8
|
apiKey: string;
|
|
34
9
|
}): void;
|
|
35
|
-
/**
|
|
36
|
-
* Get cached staging credentials if available and access token is still valid.
|
|
37
|
-
* Returns null if no cached credentials or if access token has expired.
|
|
38
|
-
*/
|
|
39
10
|
export declare function getStagingCredentials(): {
|
|
40
11
|
clientId: string;
|
|
41
12
|
apiKey: string;
|
|
42
13
|
} | null;
|
|
43
|
-
/**
|
|
44
|
-
* Atomically update tokens in credentials file.
|
|
45
|
-
* Uses write-to-temp + rename pattern for atomic updates.
|
|
46
|
-
*/
|
|
47
|
-
export declare function updateTokens(accessToken: string, expiresAt: number, refreshToken?: string): void;
|
package/dist/lib/credentials.js
CHANGED
|
@@ -1,49 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import os from 'node:os';
|
|
4
|
-
function getCredentialsDir() {
|
|
5
|
-
return path.join(os.homedir(), '.workos');
|
|
6
|
-
}
|
|
7
|
-
export function getCredentialsPath() {
|
|
8
|
-
return path.join(getCredentialsDir(), 'credentials.json');
|
|
9
|
-
}
|
|
10
|
-
export function hasCredentials() {
|
|
11
|
-
return fs.existsSync(getCredentialsPath());
|
|
12
|
-
}
|
|
13
|
-
export function getCredentials() {
|
|
14
|
-
if (!hasCredentials())
|
|
15
|
-
return null;
|
|
16
|
-
try {
|
|
17
|
-
const content = fs.readFileSync(getCredentialsPath(), 'utf-8');
|
|
18
|
-
return JSON.parse(content);
|
|
19
|
-
}
|
|
20
|
-
catch {
|
|
21
|
-
return null;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
export function saveCredentials(creds) {
|
|
25
|
-
const dir = getCredentialsDir();
|
|
26
|
-
if (!fs.existsSync(dir)) {
|
|
27
|
-
fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
28
|
-
}
|
|
29
|
-
fs.writeFileSync(getCredentialsPath(), JSON.stringify(creds, null, 2), {
|
|
30
|
-
mode: 0o600,
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
export function clearCredentials() {
|
|
34
|
-
if (hasCredentials()) {
|
|
35
|
-
fs.unlinkSync(getCredentialsPath());
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Check if token is actually expired (hard expiry check).
|
|
40
|
-
*/
|
|
1
|
+
export { hasCredentials, getCredentials, saveCredentials, clearCredentials, updateTokens, getCredentialsPath, setInsecureStorage, } from './credential-store.js';
|
|
2
|
+
import { getCredentials, saveCredentials } from './credential-store.js';
|
|
41
3
|
export function isTokenExpired(creds) {
|
|
42
4
|
return Date.now() >= creds.expiresAt;
|
|
43
5
|
}
|
|
44
|
-
/**
|
|
45
|
-
* Get access token if available and not expired.
|
|
46
|
-
*/
|
|
47
6
|
export function getAccessToken() {
|
|
48
7
|
const creds = getCredentials();
|
|
49
8
|
if (!creds)
|
|
@@ -52,10 +11,6 @@ export function getAccessToken() {
|
|
|
52
11
|
return null;
|
|
53
12
|
return creds.accessToken;
|
|
54
13
|
}
|
|
55
|
-
/**
|
|
56
|
-
* Save staging credentials to the credential cache.
|
|
57
|
-
* Staging credentials are tied to the access token lifecycle.
|
|
58
|
-
*/
|
|
59
14
|
export function saveStagingCredentials(staging) {
|
|
60
15
|
const creds = getCredentials();
|
|
61
16
|
if (!creds)
|
|
@@ -68,50 +23,12 @@ export function saveStagingCredentials(staging) {
|
|
|
68
23
|
},
|
|
69
24
|
});
|
|
70
25
|
}
|
|
71
|
-
/**
|
|
72
|
-
* Get cached staging credentials if available and access token is still valid.
|
|
73
|
-
* Returns null if no cached credentials or if access token has expired.
|
|
74
|
-
*/
|
|
75
26
|
export function getStagingCredentials() {
|
|
76
27
|
const creds = getCredentials();
|
|
77
28
|
if (!creds?.staging)
|
|
78
29
|
return null;
|
|
79
|
-
// Invalidate staging credentials when access token expires
|
|
80
30
|
if (isTokenExpired(creds))
|
|
81
31
|
return null;
|
|
82
32
|
return { clientId: creds.staging.clientId, apiKey: creds.staging.apiKey };
|
|
83
33
|
}
|
|
84
|
-
/**
|
|
85
|
-
* Atomically update tokens in credentials file.
|
|
86
|
-
* Uses write-to-temp + rename pattern for atomic updates.
|
|
87
|
-
*/
|
|
88
|
-
export function updateTokens(accessToken, expiresAt, refreshToken) {
|
|
89
|
-
const creds = getCredentials();
|
|
90
|
-
if (!creds) {
|
|
91
|
-
throw new Error('No existing credentials to update');
|
|
92
|
-
}
|
|
93
|
-
const updated = {
|
|
94
|
-
...creds,
|
|
95
|
-
accessToken,
|
|
96
|
-
expiresAt,
|
|
97
|
-
...(refreshToken && { refreshToken }),
|
|
98
|
-
};
|
|
99
|
-
// Atomic write: temp file + rename
|
|
100
|
-
const credPath = getCredentialsPath();
|
|
101
|
-
const tempPath = `${credPath}.${crypto.randomUUID()}.tmp`;
|
|
102
|
-
try {
|
|
103
|
-
fs.writeFileSync(tempPath, JSON.stringify(updated, null, 2), { mode: 0o600 });
|
|
104
|
-
fs.renameSync(tempPath, credPath);
|
|
105
|
-
}
|
|
106
|
-
catch (error) {
|
|
107
|
-
// Clean up temp file if rename failed
|
|
108
|
-
try {
|
|
109
|
-
fs.unlinkSync(tempPath);
|
|
110
|
-
}
|
|
111
|
-
catch {
|
|
112
|
-
// Ignore cleanup errors
|
|
113
|
-
}
|
|
114
|
-
throw error;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
34
|
//# sourceMappingURL=credentials.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/lib/credentials.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/lib/credentials.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,cAAc,EACd,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExE,MAAM,UAAU,cAAc,CAAC,KAAkB;IAC/C,OAAO,IAAI,CAAC,GAAG,EAAE,IAAI,KAAK,CAAC,SAAS,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,MAAM,KAAK,GAAG,cAAc,EAAE,CAAC;IAC/B,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,IAAI,cAAc,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACvC,OAAO,KAAK,CAAC,WAAW,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,OAA6C;IAClF,MAAM,KAAK,GAAG,cAAc,EAAE,CAAC;IAC/B,IAAI,CAAC,KAAK;QAAE,OAAO;IAEnB,eAAe,CAAC;QACd,GAAG,KAAK;QACR,OAAO,EAAE;YACP,GAAG,OAAO;YACV,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB;KACF,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,MAAM,KAAK,GAAG,cAAc,EAAE,CAAC;IAC/B,IAAI,CAAC,KAAK,EAAE,OAAO;QAAE,OAAO,IAAI,CAAC;IACjC,IAAI,cAAc,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACvC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;AAC5E,CAAC","sourcesContent":["export type { StagingCache, Credentials } from './credential-store.js';\n\nexport {\n hasCredentials,\n getCredentials,\n saveCredentials,\n clearCredentials,\n updateTokens,\n getCredentialsPath,\n setInsecureStorage,\n} from './credential-store.js';\n\nimport type { Credentials } from './credential-store.js';\nimport { getCredentials, saveCredentials } from './credential-store.js';\n\nexport function isTokenExpired(creds: Credentials): boolean {\n return Date.now() >= creds.expiresAt;\n}\n\nexport function getAccessToken(): string | null {\n const creds = getCredentials();\n if (!creds) return null;\n if (isTokenExpired(creds)) return null;\n return creds.accessToken;\n}\n\nexport function saveStagingCredentials(staging: { clientId: string; apiKey: string }): void {\n const creds = getCredentials();\n if (!creds) return;\n\n saveCredentials({\n ...creds,\n staging: {\n ...staging,\n fetchedAt: Date.now(),\n },\n });\n}\n\nexport function getStagingCredentials(): { clientId: string; apiKey: string } | null {\n const creds = getCredentials();\n if (!creds?.staging) return null;\n if (isTokenExpired(creds)) return null;\n return { clientId: creds.staging.clientId, apiKey: creds.staging.apiKey };\n}\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { Integration } from './constants.js';
|
|
2
1
|
import type { InstallerOptions } from '../utils/types.js';
|
|
2
|
+
import type { Language } from './language-detection.js';
|
|
3
3
|
/**
|
|
4
4
|
* Configuration interface for framework-specific agent integrations.
|
|
5
5
|
* Each framework exports a FrameworkConfig that the universal runner uses.
|
|
@@ -18,8 +18,8 @@ export interface FrameworkConfig {
|
|
|
18
18
|
export interface FrameworkMetadata {
|
|
19
19
|
/** Display name (e.g., "Next.js", "React") */
|
|
20
20
|
name: string;
|
|
21
|
-
/** Integration
|
|
22
|
-
integration:
|
|
21
|
+
/** Integration identifier (e.g., 'nextjs', 'python'). String, not enum — auto-discovered from registry. */
|
|
22
|
+
integration: string;
|
|
23
23
|
/** URL to framework-specific WorkOS AuthKit docs */
|
|
24
24
|
docsUrl: string;
|
|
25
25
|
/**
|
|
@@ -36,9 +36,18 @@ export interface FrameworkMetadata {
|
|
|
36
36
|
/**
|
|
37
37
|
* Name of the framework-specific skill for agent integration.
|
|
38
38
|
* Skills are located in .claude/skills/{skillName}/SKILL.md
|
|
39
|
-
* Will be populated per-framework in Phase 3.
|
|
40
39
|
*/
|
|
41
40
|
skillName?: string;
|
|
41
|
+
/** Language ecosystem this integration belongs to */
|
|
42
|
+
language: Language;
|
|
43
|
+
/** Stability tier: 'stable' for tested integrations, 'experimental' for new ones */
|
|
44
|
+
stability: 'stable' | 'experimental';
|
|
45
|
+
/** Detection priority — higher numbers are checked first */
|
|
46
|
+
priority: number;
|
|
47
|
+
/** Default package manager command (e.g., 'pip', 'gem', 'go'). Optional for JS integrations. */
|
|
48
|
+
packageManager?: string;
|
|
49
|
+
/** Primary manifest file (e.g., 'pyproject.toml', 'Gemfile'). Optional for JS integrations. */
|
|
50
|
+
manifestFile?: string;
|
|
42
51
|
}
|
|
43
52
|
/**
|
|
44
53
|
* Framework detection and version handling
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"framework-config.js","sourceRoot":"","sources":["../../src/lib/framework-config.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"framework-config.js","sourceRoot":"","sources":["../../src/lib/framework-config.ts"],"names":[],"mappings":"AAuIA;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,aAAqB;IACrD,OAAO,kBAAkB,aAAa,4BAA4B,CAAC;AACrE,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,iFAAiF,CAAC","sourcesContent":["import type { InstallerOptions } from '../utils/types.js';\nimport type { Language } from './language-detection.js';\n\n/**\n * Configuration interface for framework-specific agent integrations.\n * Each framework exports a FrameworkConfig that the universal runner uses.\n */\nexport interface FrameworkConfig {\n metadata: FrameworkMetadata;\n detection: FrameworkDetection;\n environment: EnvironmentConfig;\n analytics: AnalyticsConfig;\n prompts: PromptConfig;\n ui: UIConfig;\n}\n\n/**\n * Basic framework information and documentation\n */\nexport interface FrameworkMetadata {\n /** Display name (e.g., \"Next.js\", \"React\") */\n name: string;\n\n /** Integration identifier (e.g., 'nextjs', 'python'). String, not enum — auto-discovered from registry. */\n integration: string;\n\n /** URL to framework-specific WorkOS AuthKit docs */\n docsUrl: string;\n\n /**\n * Optional URL to docs for users with unsupported framework versions.\n * If not provided, defaults to docsUrl.\n */\n unsupportedVersionDocsUrl?: string;\n\n /**\n * Optional function to gather framework-specific context before agent runs.\n * For Next.js: detects router type\n * For React Native: detects Expo vs bare\n */\n gatherContext?: (options: InstallerOptions) => Promise<Record<string, any>>;\n\n /**\n * Name of the framework-specific skill for agent integration.\n * Skills are located in .claude/skills/{skillName}/SKILL.md\n */\n skillName?: string;\n\n /** Language ecosystem this integration belongs to */\n language: Language;\n\n /** Stability tier: 'stable' for tested integrations, 'experimental' for new ones */\n stability: 'stable' | 'experimental';\n\n /** Detection priority — higher numbers are checked first */\n priority: number;\n\n /** Default package manager command (e.g., 'pip', 'gem', 'go'). Optional for JS integrations. */\n packageManager?: string;\n\n /** Primary manifest file (e.g., 'pyproject.toml', 'Gemfile'). Optional for JS integrations. */\n manifestFile?: string;\n}\n\n/**\n * Framework detection and version handling\n */\nexport interface FrameworkDetection {\n /** Package name to check in package.json (e.g., \"next\", \"react\") */\n packageName: string;\n\n /** Human-readable name for error messages (e.g., \"Next.js\") */\n packageDisplayName: string;\n\n /** Extract version from package.json */\n getVersion: (packageJson: any) => string | undefined;\n\n /** Optional: Convert version to analytics bucket (e.g., \"15.x\") */\n getVersionBucket?: (version: string) => string;\n}\n\n/**\n * Environment variable configuration\n */\nexport interface EnvironmentConfig {\n /** Whether to upload env vars to hosting providers post-agent */\n uploadToHosting: boolean;\n\n /** Whether this framework requires API key (false for client-only SDKs) */\n requiresApiKey: boolean;\n\n /**\n * Build the environment variables object for this framework.\n * Returns the exact variable names and values to upload to hosting providers.\n */\n getEnvVars: (apiKey: string, clientId: string) => Record<string, string>;\n}\n\n/**\n * Analytics configuration\n */\nexport interface AnalyticsConfig {\n /** Generate tags from context (e.g., { 'nextjs-version': '15.x', 'router': 'app' }) */\n getTags: (context: any) => Record<string, any>;\n\n /** Optional: Additional event properties */\n getEventProperties?: (context: any) => Record<string, any>;\n}\n\n/**\n * Prompt configuration\n */\nexport interface PromptConfig {\n /**\n * Optional: Additional context lines to append to base prompt\n * For Next.js: \"- Router: app\"\n * For React Native: \"- Platform: Expo\"\n */\n getAdditionalContextLines?: (context: any) => string[];\n}\n\n/**\n * UI messaging configuration\n */\nexport interface UIConfig {\n /** Success message when agent completes */\n successMessage: string;\n\n /** Generate \"What the agent did\" bullets from context */\n getOutroChanges: (context: any) => string[];\n\n /** Generate \"Next steps\" bullets from context */\n getOutroNextSteps: (context: any) => string[];\n}\n\n/**\n * Generate welcome message from framework name\n */\nexport function getWelcomeMessage(frameworkName: string): string {\n return `WorkOS AuthKit ${frameworkName} installer (agent-powered)`;\n}\n\n/**\n * Shared spinner message for all frameworks\n */\nexport const SPINNER_MESSAGE = 'Setting up WorkOS AuthKit with login, authentication, and session management...';\n"]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Supported programming languages for framework detection.
|
|
3
|
+
*/
|
|
4
|
+
export type Language = 'javascript' | 'python' | 'ruby' | 'php' | 'go' | 'kotlin' | 'dotnet' | 'elixir';
|
|
5
|
+
export interface LanguageSignal {
|
|
6
|
+
language: Language;
|
|
7
|
+
confidence: number;
|
|
8
|
+
manifestFile: string;
|
|
9
|
+
}
|
|
10
|
+
export interface LanguageDetectionResult {
|
|
11
|
+
primary: Language;
|
|
12
|
+
signals: LanguageSignal[];
|
|
13
|
+
ambiguous: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Detect the primary programming language of a project.
|
|
17
|
+
* Runs all detectors and returns the highest-priority match.
|
|
18
|
+
* Sets `ambiguous: true` if multiple non-JS languages are detected.
|
|
19
|
+
*/
|
|
20
|
+
export declare function detectLanguage(cwd: string): LanguageDetectionResult | undefined;
|