omnara 0.1.2 → 0.1.4
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/bin/omnara.js +8 -3
- package/dist/auth/auth-provider.d.ts +2 -2
- package/dist/auth/auth-provider.js +14 -16
- package/dist/auth/auth-provider.js.map +1 -1
- package/dist/auth/cli-auth-service.d.ts +12 -3
- package/dist/auth/cli-auth-service.js +23 -9
- package/dist/auth/cli-auth-service.js.map +1 -1
- package/dist/auth/credential-manager.d.ts +1 -1
- package/dist/auth/credential-manager.js +7 -9
- package/dist/auth/credential-manager.js.map +1 -1
- package/dist/auth/credentials-store.js +14 -20
- package/dist/auth/credentials-store.js.map +1 -1
- package/dist/auth/login-flow.d.ts +2 -2
- package/dist/auth/login-flow.js +128 -39
- package/dist/auth/login-flow.js.map +1 -1
- package/dist/auth/loopback-listener.d.ts +20 -0
- package/dist/auth/loopback-listener.js +155 -0
- package/dist/auth/loopback-listener.js.map +1 -0
- package/dist/auth/pkce.d.ts +6 -0
- package/dist/auth/pkce.js +15 -0
- package/dist/auth/pkce.js.map +1 -0
- package/dist/auth/supabase-client.d.ts +1 -1
- package/dist/auth/supabase-client.js +3 -6
- package/dist/auth/supabase-client.js.map +1 -1
- package/dist/auth/supabase-config.js +3 -6
- package/dist/auth/supabase-config.js.map +1 -1
- package/dist/cli.js +26 -25
- package/dist/cli.js.map +1 -1
- package/dist/commands/agent.js +36 -38
- package/dist/commands/agent.js.map +1 -1
- package/dist/commands/auth.js +13 -16
- package/dist/commands/auth.js.map +1 -1
- package/dist/commands/index.d.ts +2 -2
- package/dist/commands/index.js +2 -8
- package/dist/commands/index.js.map +1 -1
- package/dist/http/api-client.js +7 -11
- package/dist/http/api-client.js.map +1 -1
- package/dist/http/user-sessions.d.ts +13 -0
- package/dist/http/user-sessions.js +9 -0
- package/dist/http/user-sessions.js.map +1 -0
- package/dist/orchestrator/agent-orchestrator.d.ts +11 -6
- package/dist/orchestrator/agent-orchestrator.js +226 -57
- package/dist/orchestrator/agent-orchestrator.js.map +1 -1
- package/dist/orchestrator/ai-client.d.ts +5 -4
- package/dist/orchestrator/ai-client.js +17 -14
- package/dist/orchestrator/ai-client.js.map +1 -1
- package/dist/orchestrator/orchestrator-prompt.d.ts +2 -7
- package/dist/orchestrator/orchestrator-prompt.js +7 -154
- package/dist/orchestrator/orchestrator-prompt.js.map +1 -1
- package/dist/orchestrator/orchestrator-prompt.md +405 -0
- package/dist/orchestrator/session.d.ts +7 -3
- package/dist/orchestrator/session.js +56 -34
- package/dist/orchestrator/session.js.map +1 -1
- package/dist/orchestrator/tools/worker-status-tool.d.ts +7 -0
- package/dist/orchestrator/tools/worker-status-tool.js +41 -0
- package/dist/orchestrator/tools/worker-status-tool.js.map +1 -0
- package/dist/orchestrator/tools/worker-tools.d.ts +1 -1
- package/dist/orchestrator/tools/worker-tools.js +73 -89
- package/dist/orchestrator/tools/worker-tools.js.map +1 -1
- package/dist/orchestrator/types.d.ts +19 -29
- package/dist/orchestrator/types.js +22 -25
- package/dist/orchestrator/types.js.map +1 -1
- package/dist/orchestrator/utils/async-queue.d.ts +26 -0
- package/dist/orchestrator/utils/async-queue.js +70 -0
- package/dist/orchestrator/utils/async-queue.js.map +1 -0
- package/dist/orchestrator/utils/session-logger.d.ts +1 -1
- package/dist/orchestrator/utils/session-logger.js +8 -14
- package/dist/orchestrator/utils/session-logger.js.map +1 -1
- package/dist/orchestrator/worker-manager.d.ts +31 -15
- package/dist/orchestrator/worker-manager.js +186 -18
- package/dist/orchestrator/worker-manager.js.map +1 -1
- package/dist/relay/relay-bridge.d.ts +24 -3
- package/dist/relay/relay-bridge.js +382 -90
- package/dist/relay/relay-bridge.js.map +1 -1
- package/dist/relay/relay-service.d.ts +4 -7
- package/dist/relay/relay-service.js +5 -11
- package/dist/relay/relay-service.js.map +1 -1
- package/dist/repl/terminal-repl.js +34 -30
- package/dist/repl/terminal-repl.js.map +1 -1
- package/dist/schemas/generated.d.ts +244 -0
- package/dist/schemas/generated.js +5 -0
- package/dist/schemas/generated.js.map +1 -0
- package/dist/schemas/index.d.ts +2 -0
- package/dist/schemas/index.js +2 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/scripts/generate-schema-types.js +53 -0
- package/dist/scripts/generate-schema-types.js.map +1 -0
- package/dist/scripts/sync-schemas.d.ts +1 -0
- package/dist/scripts/sync-schemas.js +28 -0
- package/dist/scripts/sync-schemas.js.map +1 -0
- package/dist/utils/prompt.js +4 -10
- package/dist/utils/prompt.js.map +1 -1
- package/dist/voice/voice-service.d.ts +1 -1
- package/dist/voice/voice-service.js +2 -4
- package/dist/voice/voice-service.js.map +1 -1
- package/package.json +6 -2
- package/dist/commands/hello.d.ts +0 -2
- package/dist/commands/hello.js +0 -12
- package/dist/commands/hello.js.map +0 -1
- package/dist/generated/relay.d.ts +0 -240
- package/dist/generated/relay.js +0 -2376
- package/dist/generated/relay.js.map +0 -1
- package/dist/messaging/proto-codec.d.ts +0 -5
- package/dist/messaging/proto-codec.js +0 -387
- package/dist/messaging/proto-codec.js.map +0 -1
- package/dist/server/agent-server.d.ts +0 -46
- package/dist/server/agent-server.js +0 -429
- package/dist/server/agent-server.js.map +0 -1
- package/dist/server/ai-client.d.ts +0 -16
- package/dist/server/ai-client.js +0 -74
- package/dist/server/ai-client.js.map +0 -1
- package/dist/server/session.d.ts +0 -35
- package/dist/server/session.js +0 -272
- package/dist/server/session.js.map +0 -1
- package/dist/server/subagents.d.ts +0 -19
- package/dist/server/subagents.js +0 -42
- package/dist/server/subagents.js.map +0 -1
- package/dist/server/tools/worker-tools.d.ts +0 -2
- package/dist/server/tools/worker-tools.js +0 -37
- package/dist/server/tools/worker-tools.js.map +0 -1
- package/dist/server/types.d.ts +0 -120
- package/dist/server/types.js +0 -29
- package/dist/server/types.js.map +0 -1
- package/dist/server/utils/session-logger.d.ts +0 -7
- package/dist/server/utils/session-logger.js +0 -53
- package/dist/server/utils/session-logger.js.map +0 -1
- package/dist/server/worker-manager.d.ts +0 -67
- package/dist/server/worker-manager.js +0 -207
- package/dist/server/worker-manager.js.map +0 -1
- package/dist/test-agent.js +0 -63
- package/dist/test-agent.js.map +0 -1
- /package/dist/{test-agent.d.ts → scripts/generate-schema-types.d.ts} +0 -0
package/bin/omnara.js
CHANGED
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
|
|
7
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
8
|
+
const __dirname = path.dirname(__filename);
|
|
5
9
|
|
|
6
10
|
const distEntry = path.join(__dirname, '..', 'dist', 'cli.js');
|
|
7
11
|
|
|
@@ -13,4 +17,5 @@ if (!fs.existsSync(distEntry)) {
|
|
|
13
17
|
process.exit(1);
|
|
14
18
|
}
|
|
15
19
|
|
|
16
|
-
|
|
20
|
+
const { run } = await import(distEntry);
|
|
21
|
+
await run(process.argv);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { CredentialsStore } from './credentials-store';
|
|
2
|
-
import { type AuthContext } from './credential-manager';
|
|
1
|
+
import { CredentialsStore } from './credentials-store.js';
|
|
2
|
+
import { type AuthContext } from './credential-manager.js';
|
|
3
3
|
export interface AuthProviderOptions {
|
|
4
4
|
store: CredentialsStore;
|
|
5
5
|
backendUrl: string;
|
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import { CredentialsStore } from './credentials-store.js';
|
|
2
|
+
import { ensureAuthContext } from './credential-manager.js';
|
|
3
|
+
import { performVerificationLogin } from './login-flow.js';
|
|
4
|
+
import { normalizeBaseUrl } from '../http/api-client.js';
|
|
5
|
+
export class AuthProvider {
|
|
6
|
+
options;
|
|
7
|
+
cached = null;
|
|
8
|
+
backendUrl;
|
|
9
9
|
constructor(options) {
|
|
10
10
|
this.options = options;
|
|
11
|
-
this.
|
|
12
|
-
this.backendUrl = (0, api_client_1.normalizeBaseUrl)(options.backendUrl);
|
|
11
|
+
this.backendUrl = normalizeBaseUrl(options.backendUrl);
|
|
13
12
|
}
|
|
14
13
|
async getAuthContext() {
|
|
15
14
|
const auth = await this.loadAuthContext();
|
|
@@ -22,23 +21,22 @@ class AuthProvider {
|
|
|
22
21
|
}
|
|
23
22
|
async loadAuthContext() {
|
|
24
23
|
try {
|
|
25
|
-
return await
|
|
24
|
+
return await ensureAuthContext(this.options.store, this.backendUrl);
|
|
26
25
|
}
|
|
27
26
|
catch (error) {
|
|
28
27
|
if (!shouldAttemptLogin(error)) {
|
|
29
28
|
throw error;
|
|
30
29
|
}
|
|
31
|
-
this.options.logger?.log('
|
|
32
|
-
await
|
|
30
|
+
this.options.logger?.log('Opening browser to authenticate…');
|
|
31
|
+
await performVerificationLogin({
|
|
33
32
|
backendUrlOption: this.backendUrl,
|
|
34
33
|
frontendUrlOption: this.options.frontendUrl,
|
|
35
34
|
store: this.options.store,
|
|
36
35
|
});
|
|
37
|
-
return await
|
|
36
|
+
return await ensureAuthContext(this.options.store, this.backendUrl);
|
|
38
37
|
}
|
|
39
38
|
}
|
|
40
39
|
}
|
|
41
|
-
exports.AuthProvider = AuthProvider;
|
|
42
40
|
function shouldAttemptLogin(error) {
|
|
43
41
|
if (!(error instanceof Error)) {
|
|
44
42
|
return false;
|
|
@@ -50,7 +48,7 @@ function shouldAttemptLogin(error) {
|
|
|
50
48
|
message.includes('refresh token unavailable') ||
|
|
51
49
|
message.includes('access token expired'));
|
|
52
50
|
}
|
|
53
|
-
async function createAuthProvider(options) {
|
|
51
|
+
export async function createAuthProvider(options) {
|
|
54
52
|
const provider = new AuthProvider(options);
|
|
55
53
|
await provider.getAuthContext();
|
|
56
54
|
return provider;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-provider.js","sourceRoot":"","sources":["../../src/auth/auth-provider.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"auth-provider.js","sourceRoot":"","sources":["../../src/auth/auth-provider.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAoB,MAAM,yBAAyB,CAAC;AAC9E,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AASzD,MAAM,OAAO,YAAY;IAIM;IAHrB,MAAM,GAAuB,IAAI,CAAC;IACzB,UAAU,CAAS;IAEpC,YAA6B,OAA4B;QAA5B,YAAO,GAAP,OAAO,CAAqB;QACvD,IAAI,CAAC,UAAU,GAAG,gBAAgB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACzD,CAAC;IAED,KAAK,CAAC,cAAc;QAClB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAC1C,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,cAAc;QAClB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;QACzC,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAEO,KAAK,CAAC,eAAe;QAC3B,IAAI,CAAC;YACH,OAAO,MAAM,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACtE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC/B,MAAM,KAAK,CAAC;YACd,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,kCAAkC,CAAC,CAAC;YAC7D,MAAM,wBAAwB,CAAC;gBAC7B,gBAAgB,EAAE,IAAI,CAAC,UAAU;gBACjC,iBAAiB,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW;gBAC3C,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK;aAC1B,CAAC,CAAC;YACH,OAAO,MAAM,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;CACF;AAED,SAAS,kBAAkB,CAAC,KAAc;IACxC,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;IAC5C,OAAO,CACL,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAC;QACxC,OAAO,CAAC,QAAQ,CAAC,+BAA+B,CAAC;QACjD,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAC;QACzC,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAAC;QAC7C,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAC,CACzC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAA4B;IACnE,MAAM,QAAQ,GAAG,IAAI,YAAY,CAAC,OAAO,CAAC,CAAC;IAC3C,MAAM,QAAQ,CAAC,cAAc,EAAE,CAAC;IAChC,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ApiClient } from '../http/api-client';
|
|
1
|
+
import { ApiClient } from '../http/api-client.js';
|
|
2
2
|
export interface CliAuthSession {
|
|
3
3
|
sessionId: string;
|
|
4
4
|
verificationUri: string;
|
|
@@ -6,6 +6,13 @@ export interface CliAuthSession {
|
|
|
6
6
|
expiresIn: number;
|
|
7
7
|
pollInterval: number;
|
|
8
8
|
}
|
|
9
|
+
export interface CreateCliAuthSessionOptions {
|
|
10
|
+
frontendUrl?: string;
|
|
11
|
+
loopbackRedirectUri?: string;
|
|
12
|
+
loopbackState?: string;
|
|
13
|
+
pkceChallenge?: string;
|
|
14
|
+
pkceChallengeMethod?: string;
|
|
15
|
+
}
|
|
9
16
|
export interface ExchangeCliCodeResult {
|
|
10
17
|
accessToken: string;
|
|
11
18
|
accessTokenExpiresIn: number;
|
|
@@ -14,5 +21,7 @@ export interface ExchangeCliCodeResult {
|
|
|
14
21
|
relayWsPath: string;
|
|
15
22
|
relayHeartbeatIntervalSec: number;
|
|
16
23
|
}
|
|
17
|
-
export declare function createCliAuthSession(client: ApiClient,
|
|
18
|
-
export declare function exchangeCliCode(client: ApiClient, sessionId: string, code: string
|
|
24
|
+
export declare function createCliAuthSession(client: ApiClient, options?: CreateCliAuthSessionOptions): Promise<CliAuthSession>;
|
|
25
|
+
export declare function exchangeCliCode(client: ApiClient, sessionId: string, code: string, options?: {
|
|
26
|
+
codeVerifier?: string;
|
|
27
|
+
}): Promise<ExchangeCliCodeResult>;
|
|
@@ -1,9 +1,19 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
import { ApiClient } from '../http/api-client.js';
|
|
2
|
+
export async function createCliAuthSession(client, options = {}) {
|
|
3
|
+
const body = {};
|
|
4
|
+
if (options.frontendUrl) {
|
|
5
|
+
body.frontend_url = options.frontendUrl;
|
|
6
|
+
}
|
|
7
|
+
if (options.loopbackRedirectUri) {
|
|
8
|
+
body.loopback_redirect_uri = options.loopbackRedirectUri;
|
|
9
|
+
}
|
|
10
|
+
if (options.loopbackState) {
|
|
11
|
+
body.loopback_state = options.loopbackState;
|
|
12
|
+
}
|
|
13
|
+
if (options.pkceChallenge) {
|
|
14
|
+
body.pkce_challenge = options.pkceChallenge;
|
|
15
|
+
body.pkce_challenge_method = options.pkceChallengeMethod ?? 'S256';
|
|
16
|
+
}
|
|
7
17
|
const wire = await client.postJson('/api/v1/cli-auth/session', body);
|
|
8
18
|
return {
|
|
9
19
|
sessionId: wire.session_id,
|
|
@@ -13,11 +23,15 @@ async function createCliAuthSession(client, frontendUrl) {
|
|
|
13
23
|
pollInterval: wire.poll_interval,
|
|
14
24
|
};
|
|
15
25
|
}
|
|
16
|
-
async function exchangeCliCode(client, sessionId, code) {
|
|
17
|
-
const
|
|
26
|
+
export async function exchangeCliCode(client, sessionId, code, options = {}) {
|
|
27
|
+
const requestBody = {
|
|
18
28
|
session_id: sessionId,
|
|
19
29
|
code,
|
|
20
|
-
}
|
|
30
|
+
};
|
|
31
|
+
if (options.codeVerifier) {
|
|
32
|
+
requestBody.code_verifier = options.codeVerifier;
|
|
33
|
+
}
|
|
34
|
+
const wire = await client.postJson('/api/v1/cli-auth/exchange', requestBody);
|
|
21
35
|
return {
|
|
22
36
|
accessToken: wire.access_token,
|
|
23
37
|
accessTokenExpiresIn: wire.access_token_expires_in,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-auth-service.js","sourceRoot":"","sources":["../../src/auth/cli-auth-service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cli-auth-service.js","sourceRoot":"","sources":["../../src/auth/cli-auth-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AA0DlD,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,MAAiB,EACjB,UAAuC,EAAE;IAEzC,MAAM,IAAI,GAA6B,EAAE,CAAC;IAC1C,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;QACxB,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IAC1C,CAAC;IACD,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;QAChC,IAAI,CAAC,qBAAqB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAC3D,CAAC;IACD,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;QAC1B,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;IAC9C,CAAC;IACD,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;QAC1B,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;QAC5C,IAAI,CAAC,qBAAqB,GAAG,OAAO,CAAC,mBAAmB,IAAI,MAAM,CAAC;IACrE,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,QAAQ,CAChC,0BAA0B,EAC1B,IAAI,CACL,CAAC;IACF,OAAO;QACL,SAAS,EAAE,IAAI,CAAC,UAAU;QAC1B,eAAe,EAAE,IAAI,CAAC,gBAAgB;QACtC,uBAAuB,EAAE,IAAI,CAAC,yBAAyB;QACvD,SAAS,EAAE,IAAI,CAAC,UAAU;QAC1B,YAAY,EAAE,IAAI,CAAC,aAAa;KACjC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAAiB,EACjB,SAAiB,EACjB,IAAY,EACZ,UAAqC,EAAE;IAEvC,MAAM,WAAW,GAAwB;QACvC,UAAU,EAAE,SAAS;QACrB,IAAI;KACL,CAAC;IACF,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;QACzB,WAAW,CAAC,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IACnD,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,QAAQ,CAChC,2BAA2B,EAC3B,WAAW,CACZ,CAAC;IACF,OAAO;QACL,WAAW,EAAE,IAAI,CAAC,YAAY;QAC9B,oBAAoB,EAAE,IAAI,CAAC,uBAAuB;QAClD,YAAY,EAAE,IAAI,CAAC,aAAa;QAChC,qBAAqB,EAAE,IAAI,CAAC,wBAAwB;QACpD,WAAW,EAAE,IAAI,CAAC,aAAa;QAC/B,yBAAyB,EAAE,IAAI,CAAC,4BAA4B;KAC7D,CAAC;AACJ,CAAC"}
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
const EXPIRY_BUFFER_MS = 60000; // refresh tokens one minute before expiry
|
|
7
|
-
async function ensureAuthContext(store, backendUrl) {
|
|
1
|
+
import { CredentialsStore } from './credentials-store.js';
|
|
2
|
+
import { buildSupabaseClient } from './supabase-client.js';
|
|
3
|
+
import { getSupabaseAuthConfig } from './supabase-config.js';
|
|
4
|
+
const EXPIRY_BUFFER_MS = 60_000; // refresh tokens one minute before expiry
|
|
5
|
+
export async function ensureAuthContext(store, backendUrl) {
|
|
8
6
|
const credentials = await store.load();
|
|
9
7
|
if (!credentials) {
|
|
10
8
|
throw new Error('No credentials found. Run `omnara auth login` first.');
|
|
@@ -28,8 +26,8 @@ async function refreshWithStoredToken(store, credentials, backendUrl, reason) {
|
|
|
28
26
|
if (credentials.refreshTokenExpiresAt && isExpiring(credentials.refreshTokenExpiresAt, 0)) {
|
|
29
27
|
throw new Error('Refresh token expired. Please run `omnara auth login`.');
|
|
30
28
|
}
|
|
31
|
-
const supabaseConfig = await
|
|
32
|
-
const supabase =
|
|
29
|
+
const supabaseConfig = await getSupabaseAuthConfig(backendUrl);
|
|
30
|
+
const supabase = buildSupabaseClient(supabaseConfig);
|
|
33
31
|
const { data, error } = await supabase.auth.refreshSession({ refresh_token: refreshToken });
|
|
34
32
|
if (error || !data?.session) {
|
|
35
33
|
throw new Error(`${reason} Failed to refresh Supabase session: ${error?.message ?? 'unknown error'}.`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credential-manager.js","sourceRoot":"","sources":["../../src/auth/credential-manager.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"credential-manager.js","sourceRoot":"","sources":["../../src/auth/credential-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,26 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
exports.CredentialsStore = exports.DEFAULT_CREDENTIALS_PATH = void 0;
|
|
7
|
-
const promises_1 = __importDefault(require("fs/promises"));
|
|
8
|
-
const os_1 = __importDefault(require("os"));
|
|
9
|
-
const path_1 = __importDefault(require("path"));
|
|
10
|
-
const DEFAULT_DIR = path_1.default.join(os_1.default.homedir(), '.omnara');
|
|
11
|
-
exports.DEFAULT_CREDENTIALS_PATH = path_1.default.join(DEFAULT_DIR, 'credentials.json');
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import os from 'os';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
const DEFAULT_DIR = path.join(os.homedir(), '.omnara');
|
|
5
|
+
export const DEFAULT_CREDENTIALS_PATH = path.join(DEFAULT_DIR, 'credentials.json');
|
|
12
6
|
const DEFAULT_FILE_MODE = 0o600;
|
|
13
7
|
const DEFAULT_DIR_MODE = 0o700;
|
|
14
8
|
function isStoredCredentials(value) {
|
|
15
9
|
return Boolean(value) && typeof value === 'object';
|
|
16
10
|
}
|
|
17
|
-
class CredentialsStore {
|
|
18
|
-
|
|
11
|
+
export class CredentialsStore {
|
|
12
|
+
filePath;
|
|
13
|
+
constructor(filePath = DEFAULT_CREDENTIALS_PATH) {
|
|
19
14
|
this.filePath = filePath;
|
|
20
15
|
}
|
|
21
16
|
async load() {
|
|
22
17
|
try {
|
|
23
|
-
const raw = await
|
|
18
|
+
const raw = await fs.readFile(this.filePath, 'utf8');
|
|
24
19
|
const parsed = JSON.parse(raw);
|
|
25
20
|
if (!isStoredCredentials(parsed)) {
|
|
26
21
|
throw new Error('File does not contain valid credentials data');
|
|
@@ -41,16 +36,16 @@ class CredentialsStore {
|
|
|
41
36
|
refreshToken: credentials.refreshToken,
|
|
42
37
|
refreshTokenExpiresAt: credentials.refreshTokenExpiresAt,
|
|
43
38
|
};
|
|
44
|
-
await
|
|
39
|
+
await fs.mkdir(path.dirname(this.filePath), { recursive: true, mode: DEFAULT_DIR_MODE });
|
|
45
40
|
const tempPath = `${this.filePath}.tmp`;
|
|
46
41
|
const serialized = JSON.stringify(payload, null, 2);
|
|
47
|
-
await
|
|
48
|
-
await
|
|
49
|
-
await
|
|
42
|
+
await fs.writeFile(tempPath, serialized, { mode: DEFAULT_FILE_MODE });
|
|
43
|
+
await fs.chmod(tempPath, DEFAULT_FILE_MODE);
|
|
44
|
+
await fs.rename(tempPath, this.filePath);
|
|
50
45
|
}
|
|
51
46
|
async clear() {
|
|
52
47
|
try {
|
|
53
|
-
await
|
|
48
|
+
await fs.unlink(this.filePath);
|
|
54
49
|
}
|
|
55
50
|
catch (error) {
|
|
56
51
|
if (!isFileNotFound(error)) {
|
|
@@ -59,7 +54,6 @@ class CredentialsStore {
|
|
|
59
54
|
}
|
|
60
55
|
}
|
|
61
56
|
}
|
|
62
|
-
exports.CredentialsStore = CredentialsStore;
|
|
63
57
|
function isFileNotFound(error) {
|
|
64
58
|
return Boolean(error &&
|
|
65
59
|
typeof error === 'object' &&
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"credentials-store.js","sourceRoot":"","sources":["../../src/auth/credentials-store.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"credentials-store.js","sourceRoot":"","sources":["../../src/auth/credentials-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { CredentialsStore, type StoredCredentials } from './credentials-store';
|
|
2
|
-
import { type ExchangeCliCodeResult } from './cli-auth-service';
|
|
1
|
+
import { CredentialsStore, type StoredCredentials } from './credentials-store.js';
|
|
2
|
+
import { type ExchangeCliCodeResult } from './cli-auth-service.js';
|
|
3
3
|
interface LoginOptions {
|
|
4
4
|
backendUrlOption?: string;
|
|
5
5
|
frontendUrlOption?: string;
|
package/dist/auth/login-flow.js
CHANGED
|
@@ -1,58 +1,114 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
const api_client_1 = require("../http/api-client");
|
|
10
|
-
const prompt_1 = require("../utils/prompt");
|
|
11
|
-
const cli_auth_service_1 = require("./cli-auth-service");
|
|
12
|
-
async function performVerificationLogin({ backendUrlOption, frontendUrlOption, store, }) {
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
import { ApiClient, ApiError, normalizeBaseUrl } from '../http/api-client.js';
|
|
3
|
+
import { CredentialsStore } from './credentials-store.js';
|
|
4
|
+
import { prompt } from '../utils/prompt.js';
|
|
5
|
+
import { createCliAuthSession, exchangeCliCode, } from './cli-auth-service.js';
|
|
6
|
+
import { generatePkcePair } from './pkce.js';
|
|
7
|
+
import { LoopbackListener } from './loopback-listener.js';
|
|
8
|
+
export async function performVerificationLogin({ backendUrlOption, frontendUrlOption, store, }) {
|
|
13
9
|
const backendUrl = resolveBackendUrl(backendUrlOption);
|
|
14
10
|
const frontendUrl = resolveFrontendUrl(frontendUrlOption);
|
|
15
|
-
const client = new
|
|
16
|
-
console.log('\
|
|
17
|
-
const
|
|
11
|
+
const client = new ApiClient({ baseUrl: backendUrl });
|
|
12
|
+
console.log('\nAuthenticating CLI…');
|
|
13
|
+
const loopback = await LoopbackListener.create();
|
|
14
|
+
const pkce = loopback ? generatePkcePair() : null;
|
|
15
|
+
const sessionOptions = {
|
|
16
|
+
frontendUrl,
|
|
17
|
+
};
|
|
18
|
+
if (loopback && pkce) {
|
|
19
|
+
sessionOptions.loopbackRedirectUri = loopback.redirectUri;
|
|
20
|
+
sessionOptions.loopbackState = loopback.state;
|
|
21
|
+
sessionOptions.pkceChallenge = pkce.challenge;
|
|
22
|
+
sessionOptions.pkceChallengeMethod = pkce.method;
|
|
23
|
+
}
|
|
24
|
+
const session = await createCliAuthSession(client, sessionOptions);
|
|
18
25
|
printSessionInstructions(session);
|
|
19
26
|
tryOpenBrowser(session.verificationUriComplete);
|
|
20
|
-
|
|
21
|
-
|
|
27
|
+
let completed = false;
|
|
28
|
+
let successLogged = false;
|
|
29
|
+
let latestCredentials = null;
|
|
30
|
+
const completeLogin = async (code, codeVerifier) => {
|
|
31
|
+
if (completed) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const exchange = await exchangeCliCode(client, session.sessionId, code, codeVerifier ? { codeVerifier } : {});
|
|
35
|
+
const updated = mergeCredentialsAfterExchange({
|
|
36
|
+
exchange,
|
|
37
|
+
});
|
|
38
|
+
await store.save(updated);
|
|
39
|
+
latestCredentials = updated;
|
|
40
|
+
if (!successLogged) {
|
|
41
|
+
console.log('\nLogin successful. Credentials saved.');
|
|
42
|
+
successLogged = true;
|
|
43
|
+
}
|
|
44
|
+
completed = true;
|
|
45
|
+
};
|
|
46
|
+
const loopbackTask = loopback && pkce
|
|
47
|
+
? waitForLoopback(loopback, session.sessionId, async (code) => {
|
|
48
|
+
await completeLogin(code, pkce.verifier);
|
|
49
|
+
if (typeof process.stdin.emit === 'function') {
|
|
50
|
+
process.stdin.emit('data', '\n');
|
|
51
|
+
}
|
|
52
|
+
})
|
|
53
|
+
: null;
|
|
54
|
+
if (!loopbackTask && !completed) {
|
|
55
|
+
console.log('\nWaiting for approval in the browser…');
|
|
56
|
+
}
|
|
57
|
+
while (!completed) {
|
|
58
|
+
const input = await prompt('\nFallback code if automatic login doesn\'t complete: ');
|
|
22
59
|
const cleaned = input.trim();
|
|
60
|
+
if (completed) {
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
if (!cleaned) {
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
23
66
|
if (!/^[0-9]{6}$/.test(cleaned)) {
|
|
24
67
|
console.log('Codes must be exactly six digits.');
|
|
25
68
|
continue;
|
|
26
69
|
}
|
|
27
70
|
try {
|
|
28
|
-
|
|
29
|
-
const updated = mergeCredentialsAfterExchange({
|
|
30
|
-
exchange,
|
|
31
|
-
});
|
|
32
|
-
await store.save(updated);
|
|
33
|
-
console.log('\nLogin successful. Credentials saved.');
|
|
34
|
-
return updated;
|
|
71
|
+
await completeLogin(cleaned);
|
|
35
72
|
}
|
|
36
73
|
catch (error) {
|
|
37
|
-
if (error instanceof
|
|
38
|
-
|
|
39
|
-
|
|
74
|
+
if (error instanceof ApiError) {
|
|
75
|
+
if (error.status === 401) {
|
|
76
|
+
console.log('Code not recognized. Double-check the digits shown in the browser.');
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
if (error.status === 409) {
|
|
80
|
+
console.log('Browser approval already completed. Finishing up…');
|
|
81
|
+
completed = true;
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
40
84
|
}
|
|
85
|
+
await loopback?.stop();
|
|
41
86
|
throw error;
|
|
42
87
|
}
|
|
43
88
|
}
|
|
89
|
+
await loopback?.stop();
|
|
90
|
+
if (!latestCredentials) {
|
|
91
|
+
const stored = await store.load();
|
|
92
|
+
if (stored) {
|
|
93
|
+
latestCredentials = stored;
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
throw new Error('Login completed but credentials were not stored.');
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return latestCredentials;
|
|
44
100
|
}
|
|
45
101
|
const DEFAULT_BACKEND_URL = 'https://omnara-voice.onrender.com/';
|
|
46
102
|
const DEFAULT_FRONTEND_URL = 'https://voice.omnara.com/';
|
|
47
|
-
function resolveBackendUrl(option) {
|
|
103
|
+
export function resolveBackendUrl(option) {
|
|
48
104
|
const candidate = option ?? process.env.OMNARA_BACKEND_URL ?? DEFAULT_BACKEND_URL;
|
|
49
|
-
return
|
|
105
|
+
return normalizeBaseUrl(candidate);
|
|
50
106
|
}
|
|
51
|
-
function resolveFrontendUrl(option) {
|
|
107
|
+
export function resolveFrontendUrl(option) {
|
|
52
108
|
const candidate = option ?? process.env.OMNARA_FRONTEND_URL ?? DEFAULT_FRONTEND_URL;
|
|
53
|
-
return
|
|
109
|
+
return normalizeBaseUrl(candidate);
|
|
54
110
|
}
|
|
55
|
-
function mergeCredentialsAfterExchange(args) {
|
|
111
|
+
export function mergeCredentialsAfterExchange(args) {
|
|
56
112
|
const now = Date.now();
|
|
57
113
|
const accessExpiresAt = new Date(now + args.exchange.accessTokenExpiresIn * 1000).toISOString();
|
|
58
114
|
const refreshExpiresAt = new Date(now + args.exchange.refreshTokenExpiresIn * 1000).toISOString();
|
|
@@ -63,7 +119,7 @@ function mergeCredentialsAfterExchange(args) {
|
|
|
63
119
|
refreshTokenExpiresAt: refreshExpiresAt,
|
|
64
120
|
};
|
|
65
121
|
}
|
|
66
|
-
function formatDuration(ms) {
|
|
122
|
+
export function formatDuration(ms) {
|
|
67
123
|
const totalSeconds = Math.round(ms / 1000);
|
|
68
124
|
if (totalSeconds < 60) {
|
|
69
125
|
return `${totalSeconds}s`;
|
|
@@ -82,12 +138,17 @@ function formatDuration(ms) {
|
|
|
82
138
|
const hours = totalDays % 24;
|
|
83
139
|
return hours > 0 ? `${totalDays}d ${hours}h` : `${totalDays}d`;
|
|
84
140
|
}
|
|
141
|
+
function reportLoopbackError(error) {
|
|
142
|
+
if (error instanceof ApiError) {
|
|
143
|
+
console.log(`Automatic login failed (HTTP ${error.status}). Paste the 6-digit code shown in the browser.`);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
console.log(`Automatic login failed: ${extractErrorMessage(error)}`);
|
|
147
|
+
}
|
|
85
148
|
function printSessionInstructions(session) {
|
|
86
|
-
console.log('\
|
|
87
|
-
console.log(`
|
|
88
|
-
console.log('
|
|
89
|
-
console.log(` This link expires in about ${formatDuration(session.expiresIn * 1000)}.`);
|
|
90
|
-
console.log('\n3. Return here and paste the 6-digit code when prompted.');
|
|
149
|
+
console.log('\nOpen this link in your browser if it did not open automatically:');
|
|
150
|
+
console.log(` ${session.verificationUriComplete}`);
|
|
151
|
+
console.log('Approve the request, then return to the CLI.');
|
|
91
152
|
}
|
|
92
153
|
function tryOpenBrowser(url) {
|
|
93
154
|
const command = process.platform === 'darwin'
|
|
@@ -97,11 +158,39 @@ function tryOpenBrowser(url) {
|
|
|
97
158
|
: 'xdg-open';
|
|
98
159
|
const args = process.platform === 'win32' ? ['/c', 'start', '', url] : [url];
|
|
99
160
|
try {
|
|
100
|
-
const child =
|
|
161
|
+
const child = spawn(command, args, { stdio: 'ignore', detached: true });
|
|
101
162
|
child.unref();
|
|
102
163
|
}
|
|
103
164
|
catch {
|
|
104
165
|
// Ignore failures; user can open manually.
|
|
105
166
|
}
|
|
106
167
|
}
|
|
168
|
+
function extractErrorMessage(error) {
|
|
169
|
+
if (error instanceof Error && error.message) {
|
|
170
|
+
return error.message;
|
|
171
|
+
}
|
|
172
|
+
return String(error);
|
|
173
|
+
}
|
|
174
|
+
async function waitForLoopback(listener, sessionId, onCode) {
|
|
175
|
+
try {
|
|
176
|
+
const callback = await listener.waitForCallback();
|
|
177
|
+
if (callback.sessionId && callback.sessionId !== sessionId) {
|
|
178
|
+
console.log('Received browser callback for a different session.');
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
if (callback.state && callback.state !== listener.state) {
|
|
182
|
+
console.log('Received browser callback with unexpected state.');
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
try {
|
|
186
|
+
await onCode(callback.code);
|
|
187
|
+
}
|
|
188
|
+
catch (error) {
|
|
189
|
+
reportLoopbackError(error);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
console.log(`Loopback listener error: ${extractErrorMessage(error)}`);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
107
196
|
//# sourceMappingURL=login-flow.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login-flow.js","sourceRoot":"","sources":["../../src/auth/login-flow.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"login-flow.js","sourceRoot":"","sources":["../../src/auth/login-flow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface LoopbackCallback {
|
|
2
|
+
code: string;
|
|
3
|
+
sessionId: string | null;
|
|
4
|
+
state: string | null;
|
|
5
|
+
}
|
|
6
|
+
export declare class LoopbackListener {
|
|
7
|
+
static create(): Promise<LoopbackListener | null>;
|
|
8
|
+
readonly state: string;
|
|
9
|
+
redirectUri: string;
|
|
10
|
+
private readonly server;
|
|
11
|
+
private resolveCallback;
|
|
12
|
+
private rejectCallback;
|
|
13
|
+
private pending;
|
|
14
|
+
private constructor();
|
|
15
|
+
waitForCallback(): Promise<LoopbackCallback>;
|
|
16
|
+
stop(): Promise<void>;
|
|
17
|
+
private start;
|
|
18
|
+
private handleRequest;
|
|
19
|
+
private respond;
|
|
20
|
+
}
|