omnara 0.1.3 → 0.1.5
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/cli-auth-service.d.ts +1 -1
- package/dist/auth/credential-manager.d.ts +1 -1
- package/dist/auth/login-flow.d.ts +2 -2
- package/dist/auth/supabase-client.d.ts +1 -1
- package/dist/cli.js +5940 -44
- package/dist/cli.js.map +7 -1
- package/dist/commands/index.d.ts +2 -2
- package/dist/http/user-sessions.d.ts +13 -0
- package/dist/orchestrator/agent-orchestrator.d.ts +14 -6
- package/dist/orchestrator/ai-client.d.ts +5 -4
- package/dist/orchestrator/orchestrator-prompt.d.ts +3 -2
- package/dist/orchestrator/orchestrator-prompt.md +405 -0
- package/dist/orchestrator/{types.d.ts → orchestrator-types.d.ts} +33 -29
- package/dist/orchestrator/session.d.ts +7 -3
- package/dist/orchestrator/tools/worker-status-tool.d.ts +7 -0
- package/dist/orchestrator/tools/worker-tools.d.ts +2 -1
- package/dist/orchestrator/utils/async-queue.d.ts +26 -0
- package/dist/orchestrator/utils/session-logger.d.ts +1 -1
- package/dist/orchestrator/worker-manager.d.ts +31 -15
- package/dist/relay/relay-bridge.d.ts +24 -3
- package/dist/relay/relay-service.d.ts +4 -7
- package/dist/schemas/index.d.ts +2 -0
- package/dist/voice/voice-service.d.ts +1 -1
- package/package.json +13 -3
- package/scripts/preinstall.js +141 -0
- package/scripts/test-preinstall.js +125 -0
- package/dist/auth/auth-provider.js +0 -58
- package/dist/auth/auth-provider.js.map +0 -1
- package/dist/auth/cli-auth-service.js +0 -47
- package/dist/auth/cli-auth-service.js.map +0 -1
- package/dist/auth/credential-manager.js +0 -73
- package/dist/auth/credential-manager.js.map +0 -1
- package/dist/auth/credentials-store.js +0 -75
- package/dist/auth/credentials-store.js.map +0 -1
- package/dist/auth/login-flow.js +0 -202
- package/dist/auth/login-flow.js.map +0 -1
- package/dist/auth/loopback-listener.js +0 -159
- package/dist/auth/loopback-listener.js.map +0 -1
- package/dist/auth/pkce.js +0 -18
- package/dist/auth/pkce.js.map +0 -1
- package/dist/auth/supabase-client.js +0 -13
- package/dist/auth/supabase-client.js.map +0 -1
- package/dist/auth/supabase-config.js +0 -24
- package/dist/auth/supabase-config.js.map +0 -1
- package/dist/commands/agent.js +0 -174
- package/dist/commands/agent.js.map +0 -1
- package/dist/commands/auth.js +0 -87
- package/dist/commands/auth.js.map +0 -1
- 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/commands/index.js +0 -9
- package/dist/commands/index.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/http/api-client.js +0 -122
- package/dist/http/api-client.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/orchestrator/agent-orchestrator.js +0 -423
- package/dist/orchestrator/agent-orchestrator.js.map +0 -1
- package/dist/orchestrator/ai-client.js +0 -74
- package/dist/orchestrator/ai-client.js.map +0 -1
- package/dist/orchestrator/orchestrator-prompt.js +0 -160
- package/dist/orchestrator/orchestrator-prompt.js.map +0 -1
- package/dist/orchestrator/session.js +0 -273
- package/dist/orchestrator/session.js.map +0 -1
- package/dist/orchestrator/tools/worker-tools.js +0 -165
- package/dist/orchestrator/tools/worker-tools.js.map +0 -1
- package/dist/orchestrator/types.js +0 -33
- package/dist/orchestrator/types.js.map +0 -1
- package/dist/orchestrator/utils/session-logger.js +0 -53
- package/dist/orchestrator/utils/session-logger.js.map +0 -1
- package/dist/orchestrator/worker-manager.js +0 -250
- package/dist/orchestrator/worker-manager.js.map +0 -1
- package/dist/relay/relay-bridge.js +0 -309
- package/dist/relay/relay-bridge.js.map +0 -1
- package/dist/relay/relay-service.js +0 -29
- package/dist/relay/relay-service.js.map +0 -1
- package/dist/repl/terminal-repl.js +0 -258
- package/dist/repl/terminal-repl.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.d.ts +0 -1
- package/dist/test-agent.js +0 -63
- package/dist/test-agent.js.map +0 -1
- package/dist/utils/base64url.d.ts +0 -1
- package/dist/utils/base64url.js +0 -12
- package/dist/utils/base64url.js.map +0 -1
- package/dist/utils/prompt.js +0 -19
- package/dist/utils/prompt.js.map +0 -1
- package/dist/utils/random.d.ts +0 -1
- package/dist/utils/random.js +0 -9
- package/dist/utils/random.js.map +0 -1
- package/dist/voice/voice-service.js +0 -27
- package/dist/voice/voice-service.js.map +0 -1
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface StatusUpdateEvent {
|
|
2
|
+
message: string;
|
|
3
|
+
metadata?: Record<string, unknown>;
|
|
4
|
+
timestamp: number;
|
|
5
|
+
}
|
|
6
|
+
export type StatusUpdateCallback = (event: StatusUpdateEvent) => void;
|
|
7
|
+
export declare function createWorkerStatusMcpServer(onStatusUpdate: StatusUpdateCallback): import("@anthropic-ai/claude-agent-sdk").McpSdkServerConfigWithInstance;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import type { WorkerManager } from '../worker-manager';
|
|
1
|
+
import type { WorkerManager } from '../worker-manager.js';
|
|
2
2
|
interface WorkerMcpContext {
|
|
3
3
|
resolveSessionIdBySdk: (sdkSessionId?: string) => string | undefined;
|
|
4
4
|
resolveSessionIdByToolUse: (toolUseId: string) => string | undefined;
|
|
5
|
+
getMainCodingSessionId: () => string | null;
|
|
5
6
|
}
|
|
6
7
|
export declare function createWorkerMcpServer(workerManager: WorkerManager, context: WorkerMcpContext): import("@anthropic-ai/claude-agent-sdk").McpSdkServerConfigWithInstance;
|
|
7
8
|
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A simple async queue for streaming messages to workers.
|
|
3
|
+
* Allows pushing messages and consuming them via async iteration.
|
|
4
|
+
*/
|
|
5
|
+
export declare class AsyncQueue<T> {
|
|
6
|
+
private queue;
|
|
7
|
+
private resolvers;
|
|
8
|
+
private closed;
|
|
9
|
+
/**
|
|
10
|
+
* Push a new item to the queue.
|
|
11
|
+
* If there are waiting consumers, resolve them immediately.
|
|
12
|
+
*/
|
|
13
|
+
push(item: T): void;
|
|
14
|
+
/**
|
|
15
|
+
* Close the queue, signaling that no more items will be added.
|
|
16
|
+
*/
|
|
17
|
+
close(): void;
|
|
18
|
+
/**
|
|
19
|
+
* Check if the queue is closed.
|
|
20
|
+
*/
|
|
21
|
+
isClosed(): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Async iterator implementation for consuming items from the queue.
|
|
24
|
+
*/
|
|
25
|
+
[Symbol.asyncIterator](): AsyncIterator<T>;
|
|
26
|
+
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { EventEmitter } from 'events';
|
|
2
|
-
import type {
|
|
2
|
+
import type { SDKUserMessage } from '@anthropic-ai/claude-agent-sdk';
|
|
3
|
+
import type { AgentClient } from './ai-client.js';
|
|
4
|
+
import { AsyncQueue } from './utils/async-queue.js';
|
|
3
5
|
export type WorkerStatus = 'running' | 'completed' | 'error' | 'canceled';
|
|
4
6
|
export interface WorkerProgressEntry {
|
|
5
7
|
timestamp: number;
|
|
@@ -18,24 +20,18 @@ export interface WorkerRecord {
|
|
|
18
20
|
result?: string;
|
|
19
21
|
error?: string;
|
|
20
22
|
metadata?: Record<string, unknown>;
|
|
21
|
-
|
|
22
|
-
export interface WorkerUpdatePayload {
|
|
23
|
-
id: string;
|
|
24
|
-
task: string;
|
|
25
|
-
status: WorkerStatus;
|
|
26
|
-
prompt: string;
|
|
27
|
-
lastUpdateAt: number;
|
|
28
|
-
result?: string;
|
|
29
|
-
error?: string;
|
|
30
|
-
latestMessage?: string;
|
|
31
|
-
originSessionId?: string;
|
|
32
|
-
sessionId: string;
|
|
23
|
+
messageQueue: AsyncQueue<SDKUserMessage>;
|
|
33
24
|
}
|
|
34
25
|
export interface WorkerMessageEvent {
|
|
35
26
|
record: WorkerRecord;
|
|
36
|
-
messageType: 'assistant_text' | 'assistant_complete';
|
|
27
|
+
messageType: 'assistant_text' | 'assistant_complete' | 'tool_call' | 'tool_result';
|
|
37
28
|
text?: string;
|
|
38
29
|
success?: boolean;
|
|
30
|
+
toolName?: string;
|
|
31
|
+
toolUseId?: string;
|
|
32
|
+
toolInput?: unknown;
|
|
33
|
+
toolContent?: unknown;
|
|
34
|
+
isError?: boolean;
|
|
39
35
|
}
|
|
40
36
|
interface LaunchWorkerOptions {
|
|
41
37
|
task: string;
|
|
@@ -44,7 +40,7 @@ interface LaunchWorkerOptions {
|
|
|
44
40
|
metadata?: Record<string, unknown>;
|
|
45
41
|
}
|
|
46
42
|
interface WorkerManagerOptions {
|
|
47
|
-
createClient: () => AgentClient;
|
|
43
|
+
createClient: (mcpServers?: Record<string, any>) => AgentClient;
|
|
48
44
|
resolveSessionIdBySdk?: (sdkSessionId?: string) => string | undefined;
|
|
49
45
|
}
|
|
50
46
|
export declare class WorkerManager extends EventEmitter {
|
|
@@ -55,10 +51,30 @@ export declare class WorkerManager extends EventEmitter {
|
|
|
55
51
|
listWorkers(): WorkerRecord[];
|
|
56
52
|
getWorker(id: string): WorkerRecord | undefined;
|
|
57
53
|
getWorkerByTask(task: string): WorkerRecord | undefined;
|
|
54
|
+
/**
|
|
55
|
+
* Get a formatted summary of all current worker statuses for inclusion in system prompts.
|
|
56
|
+
* Returns a string describing all active workers and their current state.
|
|
57
|
+
*/
|
|
58
|
+
getWorkerStatusSummary(): string;
|
|
58
59
|
launchWorker({ task, prompt, originSessionId, metadata }: LaunchWorkerOptions): WorkerRecord;
|
|
59
60
|
cancelWorker(id: string): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* Send a message to a running worker.
|
|
63
|
+
*
|
|
64
|
+
* @param task - The task name of the worker to message
|
|
65
|
+
* @param message - The message content to send
|
|
66
|
+
* @param interrupt - If true, interrupt current generation; if false, queue for next turn
|
|
67
|
+
* @returns true if message was sent, false if worker not found or not running
|
|
68
|
+
*/
|
|
69
|
+
messageWorker(task: string, message: string, interrupt: boolean): Promise<boolean>;
|
|
60
70
|
private emitUpdate;
|
|
61
71
|
private emitCompleted;
|
|
72
|
+
private handleStatusUpdate;
|
|
73
|
+
/**
|
|
74
|
+
* Create an async iterable stream of user messages for the worker.
|
|
75
|
+
* Yields the initial prompt, then streams any additional messages from the queue.
|
|
76
|
+
*/
|
|
77
|
+
private createMessageStream;
|
|
62
78
|
private runWorker;
|
|
63
79
|
private handleMessage;
|
|
64
80
|
private extractAssistantText;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import EventEmitter from 'events';
|
|
2
|
-
import { AgentOrchestrator } from '../orchestrator/agent-orchestrator';
|
|
3
|
-
import { CredentialsStore } from '../auth/credentials-store';
|
|
2
|
+
import { AgentOrchestrator } from '../orchestrator/agent-orchestrator.js';
|
|
3
|
+
import { CredentialsStore } from '../auth/credentials-store.js';
|
|
4
4
|
export interface RelayBridgeOptions {
|
|
5
5
|
store?: CredentialsStore;
|
|
6
6
|
logger?: Console;
|
|
@@ -20,15 +20,36 @@ export declare class RelayBridge extends EventEmitter {
|
|
|
20
20
|
private pingTimer;
|
|
21
21
|
private heartbeatIntervalMs;
|
|
22
22
|
private authProviderPromise;
|
|
23
|
-
private
|
|
23
|
+
private userSessionId;
|
|
24
|
+
private currentAgentSessionId;
|
|
24
25
|
constructor(orchestrator: AgentOrchestrator, options: RelayBridgeOptions);
|
|
25
26
|
start(): Promise<void>;
|
|
26
27
|
stop(): Promise<void>;
|
|
27
28
|
private establishConnection;
|
|
28
29
|
private getAuthProvider;
|
|
30
|
+
private ensureAgentSessionExists;
|
|
31
|
+
private ensureUserSession;
|
|
32
|
+
private sendPrimarySessionInit;
|
|
33
|
+
private sendFrame;
|
|
29
34
|
private handleWebsocketLifecycle;
|
|
30
35
|
private handleOutbound;
|
|
31
36
|
private handleInbound;
|
|
37
|
+
private toRelayFrame;
|
|
38
|
+
private tryHandleControlMessage;
|
|
39
|
+
private tryHandleMessageEnvelope;
|
|
40
|
+
private handleSessionBootstrap;
|
|
41
|
+
private handleSessionInitAck;
|
|
42
|
+
private handleSessionAnnounce;
|
|
43
|
+
private handleMessageEnvelope;
|
|
44
|
+
private isTextContent;
|
|
45
|
+
private buildTextEnvelope;
|
|
46
|
+
private buildToolCallEnvelope;
|
|
47
|
+
private normalizeToolArguments;
|
|
48
|
+
private buildToolResultEnvelope;
|
|
49
|
+
private buildAgentCompleteEnvelope;
|
|
50
|
+
private buildProgressEnvelope;
|
|
51
|
+
private buildEnvelope;
|
|
52
|
+
private isMessageEnvelope;
|
|
32
53
|
private enqueue;
|
|
33
54
|
private flushQueue;
|
|
34
55
|
private startPingTimer;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { ApiClient } from '../http/api-client';
|
|
1
|
+
import { ApiClient } from '../http/api-client.js';
|
|
2
2
|
export type RelayClientKind = 'cli' | 'web' | 'mobile' | 'voice';
|
|
3
3
|
export interface RelayRegistration {
|
|
4
|
-
|
|
4
|
+
userSessionId: string;
|
|
5
5
|
relayToken: string;
|
|
6
6
|
relayTokenExpiresIn: number;
|
|
7
7
|
relayWsPath: string;
|
|
@@ -12,11 +12,8 @@ export interface RelayTokenRefresh {
|
|
|
12
12
|
relayTokenExpiresIn: number;
|
|
13
13
|
}
|
|
14
14
|
export interface RegisterRelayOptions {
|
|
15
|
-
|
|
16
|
-
parentSessionId?: string;
|
|
17
|
-
name?: string;
|
|
18
|
-
metadata?: Record<string, unknown>;
|
|
15
|
+
userSessionId: string;
|
|
19
16
|
clientKind?: RelayClientKind;
|
|
20
17
|
}
|
|
21
|
-
export declare function registerRelaySession(client: ApiClient, accessToken: string, options
|
|
18
|
+
export declare function registerRelaySession(client: ApiClient, accessToken: string, options: RegisterRelayOptions): Promise<RelayRegistration>;
|
|
22
19
|
export declare function refreshRelayToken(client: ApiClient, accessToken: string, relayToken: string): Promise<RelayTokenRefresh>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omnara",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
|
+
"type": "module",
|
|
4
5
|
"description": "Command-line interface for Omnara.",
|
|
5
6
|
"main": "dist/cli.js",
|
|
6
7
|
"types": "dist/cli.d.ts",
|
|
@@ -8,10 +9,13 @@
|
|
|
8
9
|
"omnara": "./bin/omnara.js"
|
|
9
10
|
},
|
|
10
11
|
"scripts": {
|
|
11
|
-
"build": "
|
|
12
|
+
"build": "npm run build:types && node build.mjs && npm run copy-assets",
|
|
13
|
+
"build:types": "tsc --emitDeclarationOnly --project tsconfig.json",
|
|
14
|
+
"copy-assets": "mkdir -p dist/orchestrator && cp -r src/orchestrator/*.md dist/orchestrator/",
|
|
15
|
+
"preinstall": "node scripts/preinstall.js",
|
|
12
16
|
"dev": "tsx watch src/cli.ts",
|
|
13
17
|
"test": "tsx --test \"tests/**/*.ts\" \"tests/*.ts\"",
|
|
14
|
-
"typecheck": "tsc
|
|
18
|
+
"typecheck": "tsc --noEmit",
|
|
15
19
|
"lint": "eslint --format unix \"src/**/*.ts\" \"tests/**/*.ts\"",
|
|
16
20
|
"lint:fix": "eslint --format unix --fix \"src/**/*.ts\" \"tests/**/*.ts\"",
|
|
17
21
|
"format": "prettier --check \"src/**/*.ts\" \"tests/**/*.ts\"",
|
|
@@ -29,6 +33,7 @@
|
|
|
29
33
|
"files": [
|
|
30
34
|
"dist",
|
|
31
35
|
"bin",
|
|
36
|
+
"scripts",
|
|
32
37
|
"README.md"
|
|
33
38
|
],
|
|
34
39
|
"dependencies": {
|
|
@@ -36,17 +41,22 @@
|
|
|
36
41
|
"@anthropic-ai/sdk": "^0.67.0",
|
|
37
42
|
"@modelcontextprotocol/sdk": "^1.20.1",
|
|
38
43
|
"@supabase/supabase-js": "^2.76.1",
|
|
44
|
+
"ajv": "^8.17.1",
|
|
45
|
+
"ajv-formats": "^2.1.1",
|
|
39
46
|
"commander": "^11.1.0",
|
|
40
47
|
"ws": "^8.18.3",
|
|
41
48
|
"zod": "^3.25.76"
|
|
42
49
|
},
|
|
43
50
|
"devDependencies": {
|
|
51
|
+
"@omnara/shared-js": "file:../shared-js",
|
|
44
52
|
"@types/node": "^20.11.30",
|
|
45
53
|
"@types/ws": "^8.18.1",
|
|
46
54
|
"@typescript-eslint/eslint-plugin": "^8.46.2",
|
|
47
55
|
"@typescript-eslint/parser": "^8.46.2",
|
|
56
|
+
"esbuild": "^0.25.12",
|
|
48
57
|
"eslint": "^9.38.0",
|
|
49
58
|
"eslint-formatter-unix": "^8.40.0",
|
|
59
|
+
"json-schema-to-typescript": "^14.0.1",
|
|
50
60
|
"prettier": "^3.6.2",
|
|
51
61
|
"tsx": "^4.7.0",
|
|
52
62
|
"typescript": "^5.4.0",
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { execSync } from 'child_process';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Preinstall script to uninstall old omnara packages (pip and brew).
|
|
7
|
+
* This ensures a clean migration to the npm package.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
function log(message) {
|
|
11
|
+
console.log(`[omnara preinstall] ${message}`);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function checkPipCommand() {
|
|
15
|
+
const pipCommands = ['pip3', 'pip'];
|
|
16
|
+
|
|
17
|
+
for (const cmd of pipCommands) {
|
|
18
|
+
try {
|
|
19
|
+
execSync(`${cmd} --version`, { stdio: 'ignore' });
|
|
20
|
+
return cmd;
|
|
21
|
+
} catch {
|
|
22
|
+
// Command not found, try next
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function isPipPackageInstalled(pipCommand) {
|
|
30
|
+
try {
|
|
31
|
+
execSync(`${pipCommand} show omnara`, { stdio: 'ignore' });
|
|
32
|
+
return true;
|
|
33
|
+
} catch {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function uninstallPipPackage(pipCommand) {
|
|
39
|
+
try {
|
|
40
|
+
log(`Detected old omnara pip package in ${pipCommand}. Uninstalling...`);
|
|
41
|
+
|
|
42
|
+
// Try without sudo first
|
|
43
|
+
try {
|
|
44
|
+
execSync(`${pipCommand} uninstall -y omnara`, { stdio: 'inherit' });
|
|
45
|
+
log(`Successfully uninstalled old omnara pip package from ${pipCommand}.`);
|
|
46
|
+
return true;
|
|
47
|
+
} catch (firstError) {
|
|
48
|
+
// If that fails, try with sudo
|
|
49
|
+
log('Permission denied. Attempting with sudo...');
|
|
50
|
+
try {
|
|
51
|
+
execSync(`sudo ${pipCommand} uninstall -y omnara`, { stdio: 'inherit' });
|
|
52
|
+
log(`Successfully uninstalled old omnara pip package from ${pipCommand} (with sudo).`);
|
|
53
|
+
return true;
|
|
54
|
+
} catch (sudoError) {
|
|
55
|
+
throw sudoError;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
} catch (error) {
|
|
59
|
+
log(`Warning: Failed to uninstall pip package from ${pipCommand}: ${error.message}`);
|
|
60
|
+
log('You may need to manually run: sudo ' + pipCommand + ' uninstall omnara');
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function checkBrewCommand() {
|
|
66
|
+
try {
|
|
67
|
+
execSync('brew --version', { stdio: 'ignore' });
|
|
68
|
+
return true;
|
|
69
|
+
} catch {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function isBrewPackageInstalled() {
|
|
75
|
+
try {
|
|
76
|
+
execSync('brew list omnara', { stdio: 'ignore' });
|
|
77
|
+
return true;
|
|
78
|
+
} catch {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function uninstallBrewPackage() {
|
|
84
|
+
try {
|
|
85
|
+
log('Detected old omnara brew package. Uninstalling...');
|
|
86
|
+
execSync('brew uninstall omnara', { stdio: 'inherit' });
|
|
87
|
+
log('Successfully uninstalled old omnara brew package.');
|
|
88
|
+
return true;
|
|
89
|
+
} catch (error) {
|
|
90
|
+
log(`Warning: Failed to uninstall brew package: ${error.message}`);
|
|
91
|
+
return false;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function main() {
|
|
96
|
+
log('Checking for old omnara installations...');
|
|
97
|
+
|
|
98
|
+
// Check for pip packages - check BOTH pip and pip3
|
|
99
|
+
log('Checking for pip packages...');
|
|
100
|
+
const pipCommands = ['pip3', 'pip'];
|
|
101
|
+
let foundAnyPip = false;
|
|
102
|
+
|
|
103
|
+
for (const pipCmd of pipCommands) {
|
|
104
|
+
try {
|
|
105
|
+
execSync(`${pipCmd} --version`, { stdio: 'ignore' });
|
|
106
|
+
foundAnyPip = true;
|
|
107
|
+
log(`Found ${pipCmd} command`);
|
|
108
|
+
|
|
109
|
+
if (isPipPackageInstalled(pipCmd)) {
|
|
110
|
+
uninstallPipPackage(pipCmd);
|
|
111
|
+
} else {
|
|
112
|
+
log(`No old omnara package found in ${pipCmd}.`);
|
|
113
|
+
}
|
|
114
|
+
} catch {
|
|
115
|
+
// Command not found, skip
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (!foundAnyPip) {
|
|
120
|
+
log('pip/pip3 not found. Skipping pip package check.');
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Check for brew package
|
|
124
|
+
log('Checking for brew package...');
|
|
125
|
+
if (!checkBrewCommand()) {
|
|
126
|
+
log('brew not found. Skipping brew package check.');
|
|
127
|
+
} else {
|
|
128
|
+
log('Found brew command');
|
|
129
|
+
|
|
130
|
+
if (isBrewPackageInstalled()) {
|
|
131
|
+
uninstallBrewPackage();
|
|
132
|
+
} else {
|
|
133
|
+
log('No old brew package found.');
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
log('Package check complete. Continuing with installation.');
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
main();
|
|
141
|
+
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Test script for preinstall.js
|
|
5
|
+
* This simulates various scenarios to ensure the preinstall script works correctly.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { execSync } from 'child_process';
|
|
9
|
+
import { readFileSync } from 'fs';
|
|
10
|
+
|
|
11
|
+
console.log('='.repeat(60));
|
|
12
|
+
console.log('Testing preinstall.js');
|
|
13
|
+
console.log('='.repeat(60));
|
|
14
|
+
|
|
15
|
+
// Test 0: Verify package.json configuration
|
|
16
|
+
console.log('\n[TEST 0] Verifying package.json configuration...');
|
|
17
|
+
try {
|
|
18
|
+
const packageJson = JSON.parse(readFileSync('package.json', 'utf8'));
|
|
19
|
+
|
|
20
|
+
// Check if preinstall script exists
|
|
21
|
+
if (packageJson.scripts?.preinstall) {
|
|
22
|
+
console.log('✅ preinstall script found in package.json');
|
|
23
|
+
console.log(` Command: ${packageJson.scripts.preinstall}`);
|
|
24
|
+
} else {
|
|
25
|
+
console.error('❌ preinstall script NOT found in package.json');
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Check if scripts directory is included in files
|
|
30
|
+
if (packageJson.files?.includes('scripts')) {
|
|
31
|
+
console.log('✅ scripts directory included in package files');
|
|
32
|
+
} else {
|
|
33
|
+
console.error('❌ scripts directory NOT included in package files');
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
} catch (error) {
|
|
37
|
+
console.error('❌ Failed to read package.json:', error.message);
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Test 1: Check if the script runs without errors
|
|
42
|
+
console.log('\n[TEST 1] Running preinstall.js...');
|
|
43
|
+
try {
|
|
44
|
+
execSync('node scripts/preinstall.js', {
|
|
45
|
+
stdio: 'inherit',
|
|
46
|
+
cwd: process.cwd()
|
|
47
|
+
});
|
|
48
|
+
console.log('✅ Script executed successfully');
|
|
49
|
+
} catch (error) {
|
|
50
|
+
console.error('❌ Script failed:', error.message);
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Test 2: Check if pip/pip3 is available and check BOTH
|
|
55
|
+
console.log('\n[TEST 2] Checking pip availability...');
|
|
56
|
+
const pipCommands = ['pip3', 'pip'];
|
|
57
|
+
let pipFound = false;
|
|
58
|
+
for (const cmd of pipCommands) {
|
|
59
|
+
try {
|
|
60
|
+
execSync(`${cmd} --version`, { stdio: 'ignore' });
|
|
61
|
+
console.log(`✅ Found ${cmd}`);
|
|
62
|
+
pipFound = true;
|
|
63
|
+
|
|
64
|
+
// Check if omnara pip package is installed
|
|
65
|
+
try {
|
|
66
|
+
const result = execSync(`${cmd} show omnara`, { encoding: 'utf8', stdio: 'pipe' });
|
|
67
|
+
console.log(`⚠️ Warning: omnara pip package IS installed in ${cmd}`);
|
|
68
|
+
console.log(' Package info:', result.split('\n')[0]);
|
|
69
|
+
} catch {
|
|
70
|
+
console.log(`✅ No omnara pip package found in ${cmd} (good)`);
|
|
71
|
+
}
|
|
72
|
+
} catch {
|
|
73
|
+
// Command not found
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (!pipFound) {
|
|
77
|
+
console.log('ℹ️ No pip/pip3 found on system');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Test 3: Check if brew is available
|
|
81
|
+
console.log('\n[TEST 3] Checking brew availability...');
|
|
82
|
+
try {
|
|
83
|
+
execSync('brew --version', { stdio: 'ignore' });
|
|
84
|
+
console.log('✅ Found brew');
|
|
85
|
+
|
|
86
|
+
// Check if omnara brew package is installed
|
|
87
|
+
try {
|
|
88
|
+
execSync('brew list omnara', { stdio: 'ignore' });
|
|
89
|
+
console.log('⚠️ Warning: omnara brew package IS installed');
|
|
90
|
+
} catch {
|
|
91
|
+
console.log('✅ No omnara brew package found (good)');
|
|
92
|
+
}
|
|
93
|
+
} catch {
|
|
94
|
+
console.log('ℹ️ No brew found on system');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Test 4: Verify script file permissions
|
|
98
|
+
console.log('\n[TEST 4] Checking script permissions...');
|
|
99
|
+
try {
|
|
100
|
+
const fs = await import('fs');
|
|
101
|
+
const stats = fs.statSync('scripts/preinstall.js');
|
|
102
|
+
const mode = (stats.mode & parseInt('777', 8)).toString(8);
|
|
103
|
+
console.log(`✅ Script permissions: ${mode}`);
|
|
104
|
+
} catch (error) {
|
|
105
|
+
console.error('❌ Could not check permissions:', error.message);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
console.log('\n' + '='.repeat(60));
|
|
109
|
+
console.log('Test Summary:');
|
|
110
|
+
console.log('='.repeat(60));
|
|
111
|
+
console.log('✅ All tests passed! The preinstall script is ready to use.');
|
|
112
|
+
console.log('\nThe script will automatically run when users install with:');
|
|
113
|
+
console.log(' npm install -g omnara');
|
|
114
|
+
console.log('\nWhat the preinstall script does:');
|
|
115
|
+
console.log(' 1. Checks both pip3 AND pip for old omnara packages');
|
|
116
|
+
console.log(' 2. Checks brew for old omnara packages');
|
|
117
|
+
console.log(' 3. Uninstalls any found packages (using sudo if needed)');
|
|
118
|
+
console.log(' 4. Continues with npm installation');
|
|
119
|
+
console.log('\nTo test the full installation flow:');
|
|
120
|
+
console.log(' 1. Build: npm run build');
|
|
121
|
+
console.log(' 2. Pack: npm pack');
|
|
122
|
+
console.log(' 3. Install: npm install -g omnara-0.1.4.tgz');
|
|
123
|
+
console.log(' 4. Verify: omnara --version');
|
|
124
|
+
console.log('='.repeat(60));
|
|
125
|
+
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AuthProvider = void 0;
|
|
4
|
-
exports.createAuthProvider = createAuthProvider;
|
|
5
|
-
const credential_manager_1 = require("./credential-manager");
|
|
6
|
-
const login_flow_1 = require("./login-flow");
|
|
7
|
-
const api_client_1 = require("../http/api-client");
|
|
8
|
-
class AuthProvider {
|
|
9
|
-
constructor(options) {
|
|
10
|
-
this.options = options;
|
|
11
|
-
this.cached = null;
|
|
12
|
-
this.backendUrl = (0, api_client_1.normalizeBaseUrl)(options.backendUrl);
|
|
13
|
-
}
|
|
14
|
-
async getAuthContext() {
|
|
15
|
-
const auth = await this.loadAuthContext();
|
|
16
|
-
this.cached = auth;
|
|
17
|
-
return auth;
|
|
18
|
-
}
|
|
19
|
-
async getAccessToken() {
|
|
20
|
-
const auth = await this.getAuthContext();
|
|
21
|
-
return auth.accessToken;
|
|
22
|
-
}
|
|
23
|
-
async loadAuthContext() {
|
|
24
|
-
try {
|
|
25
|
-
return await (0, credential_manager_1.ensureAuthContext)(this.options.store, this.backendUrl);
|
|
26
|
-
}
|
|
27
|
-
catch (error) {
|
|
28
|
-
if (!shouldAttemptLogin(error)) {
|
|
29
|
-
throw error;
|
|
30
|
-
}
|
|
31
|
-
this.options.logger?.log('Opening browser to authenticate…');
|
|
32
|
-
await (0, login_flow_1.performVerificationLogin)({
|
|
33
|
-
backendUrlOption: this.backendUrl,
|
|
34
|
-
frontendUrlOption: this.options.frontendUrl,
|
|
35
|
-
store: this.options.store,
|
|
36
|
-
});
|
|
37
|
-
return await (0, credential_manager_1.ensureAuthContext)(this.options.store, this.backendUrl);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
exports.AuthProvider = AuthProvider;
|
|
42
|
-
function shouldAttemptLogin(error) {
|
|
43
|
-
if (!(error instanceof Error)) {
|
|
44
|
-
return false;
|
|
45
|
-
}
|
|
46
|
-
const message = error.message.toLowerCase();
|
|
47
|
-
return (message.includes('no credentials found') ||
|
|
48
|
-
message.includes('run `omnara auth login` first') ||
|
|
49
|
-
message.includes('refresh token expired') ||
|
|
50
|
-
message.includes('refresh token unavailable') ||
|
|
51
|
-
message.includes('access token expired'));
|
|
52
|
-
}
|
|
53
|
-
async function createAuthProvider(options) {
|
|
54
|
-
const provider = new AuthProvider(options);
|
|
55
|
-
await provider.getAuthContext();
|
|
56
|
-
return provider;
|
|
57
|
-
}
|
|
58
|
-
//# sourceMappingURL=auth-provider.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"auth-provider.js","sourceRoot":"","sources":["../../src/auth/auth-provider.ts"],"names":[],"mappings":";;;AAiEA,gDAIC;AAlED,6DAA2E;AAC3E,6CAAwD;AACxD,mDAAsD;AAStD,MAAa,YAAY;IAIvB,YAA6B,OAA4B;QAA5B,YAAO,GAAP,OAAO,CAAqB;QAHjD,WAAM,GAAuB,IAAI,CAAC;QAIxC,IAAI,CAAC,UAAU,GAAG,IAAA,6BAAgB,EAAC,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,IAAA,sCAAiB,EAAC,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,IAAA,qCAAwB,EAAC;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,IAAA,sCAAiB,EAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;CACF;AAnCD,oCAmCC;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;AAEM,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,47 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createCliAuthSession = createCliAuthSession;
|
|
4
|
-
exports.exchangeCliCode = exchangeCliCode;
|
|
5
|
-
async function createCliAuthSession(client, options = {}) {
|
|
6
|
-
const body = {};
|
|
7
|
-
if (options.frontendUrl) {
|
|
8
|
-
body.frontend_url = options.frontendUrl;
|
|
9
|
-
}
|
|
10
|
-
if (options.loopbackRedirectUri) {
|
|
11
|
-
body.loopback_redirect_uri = options.loopbackRedirectUri;
|
|
12
|
-
}
|
|
13
|
-
if (options.loopbackState) {
|
|
14
|
-
body.loopback_state = options.loopbackState;
|
|
15
|
-
}
|
|
16
|
-
if (options.pkceChallenge) {
|
|
17
|
-
body.pkce_challenge = options.pkceChallenge;
|
|
18
|
-
body.pkce_challenge_method = options.pkceChallengeMethod ?? 'S256';
|
|
19
|
-
}
|
|
20
|
-
const wire = await client.postJson('/api/v1/cli-auth/session', body);
|
|
21
|
-
return {
|
|
22
|
-
sessionId: wire.session_id,
|
|
23
|
-
verificationUri: wire.verification_uri,
|
|
24
|
-
verificationUriComplete: wire.verification_uri_complete,
|
|
25
|
-
expiresIn: wire.expires_in,
|
|
26
|
-
pollInterval: wire.poll_interval,
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
async function exchangeCliCode(client, sessionId, code, options = {}) {
|
|
30
|
-
const requestBody = {
|
|
31
|
-
session_id: sessionId,
|
|
32
|
-
code,
|
|
33
|
-
};
|
|
34
|
-
if (options.codeVerifier) {
|
|
35
|
-
requestBody.code_verifier = options.codeVerifier;
|
|
36
|
-
}
|
|
37
|
-
const wire = await client.postJson('/api/v1/cli-auth/exchange', requestBody);
|
|
38
|
-
return {
|
|
39
|
-
accessToken: wire.access_token,
|
|
40
|
-
accessTokenExpiresIn: wire.access_token_expires_in,
|
|
41
|
-
refreshToken: wire.refresh_token,
|
|
42
|
-
refreshTokenExpiresIn: wire.refresh_token_expires_in,
|
|
43
|
-
relayWsPath: wire.relay_ws_path,
|
|
44
|
-
relayHeartbeatIntervalSec: wire.relay_heartbeat_interval_sec,
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
//# sourceMappingURL=cli-auth-service.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cli-auth-service.js","sourceRoot":"","sources":["../../src/auth/cli-auth-service.ts"],"names":[],"mappings":";;AA0DA,oDA6BC;AAED,0CA0BC;AAzDM,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;AAEM,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"}
|