@mquan/portal 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/README.md +168 -0
  2. package/dist/src/api.d.ts +5 -0
  3. package/dist/src/api.js +357 -0
  4. package/dist/src/api.js.map +1 -0
  5. package/dist/src/cli.d.ts +17 -0
  6. package/dist/src/cli.js +618 -0
  7. package/dist/src/cli.js.map +1 -0
  8. package/dist/src/daemon-lifecycle.d.ts +24 -0
  9. package/dist/src/daemon-lifecycle.js +107 -0
  10. package/dist/src/daemon-lifecycle.js.map +1 -0
  11. package/dist/src/daemon.d.ts +17 -0
  12. package/dist/src/daemon.js +90 -0
  13. package/dist/src/daemon.js.map +1 -0
  14. package/dist/src/doctor.d.ts +14 -0
  15. package/dist/src/doctor.js +51 -0
  16. package/dist/src/doctor.js.map +1 -0
  17. package/dist/src/entrypoint.d.ts +2 -0
  18. package/dist/src/entrypoint.js +14 -0
  19. package/dist/src/entrypoint.js.map +1 -0
  20. package/dist/src/index.d.ts +5 -0
  21. package/dist/src/index.js +5 -0
  22. package/dist/src/index.js.map +1 -0
  23. package/dist/src/launch.d.ts +41 -0
  24. package/dist/src/launch.js +186 -0
  25. package/dist/src/launch.js.map +1 -0
  26. package/dist/src/mcp.d.ts +9 -0
  27. package/dist/src/mcp.js +132 -0
  28. package/dist/src/mcp.js.map +1 -0
  29. package/dist/src/network/client.d.ts +67 -0
  30. package/dist/src/network/client.js +540 -0
  31. package/dist/src/network/client.js.map +1 -0
  32. package/dist/src/network/coordinator.d.ts +83 -0
  33. package/dist/src/network/coordinator.js +225 -0
  34. package/dist/src/network/coordinator.js.map +1 -0
  35. package/dist/src/network/protocol.d.ts +1352 -0
  36. package/dist/src/network/protocol.js +360 -0
  37. package/dist/src/network/protocol.js.map +1 -0
  38. package/dist/src/network/server.d.ts +28 -0
  39. package/dist/src/network/server.js +474 -0
  40. package/dist/src/network/server.js.map +1 -0
  41. package/dist/src/network/tasks.d.ts +65 -0
  42. package/dist/src/network/tasks.js +276 -0
  43. package/dist/src/network/tasks.js.map +1 -0
  44. package/dist/src/portal-index.d.ts +21 -0
  45. package/dist/src/portal-index.js +140 -0
  46. package/dist/src/portal-index.js.map +1 -0
  47. package/dist/src/provider/claude-managed.d.ts +34 -0
  48. package/dist/src/provider/claude-managed.js +125 -0
  49. package/dist/src/provider/claude-managed.js.map +1 -0
  50. package/dist/src/provider/claude.d.ts +24 -0
  51. package/dist/src/provider/claude.js +114 -0
  52. package/dist/src/provider/claude.js.map +1 -0
  53. package/dist/src/provider/codex/app-server-client.d.ts +43 -0
  54. package/dist/src/provider/codex/app-server-client.js +143 -0
  55. package/dist/src/provider/codex/app-server-client.js.map +1 -0
  56. package/dist/src/provider/codex/index.d.ts +3 -0
  57. package/dist/src/provider/codex/index.js +4 -0
  58. package/dist/src/provider/codex/index.js.map +1 -0
  59. package/dist/src/provider/codex/managed-runner.d.ts +12 -0
  60. package/dist/src/provider/codex/managed-runner.js +162 -0
  61. package/dist/src/provider/codex/managed-runner.js.map +1 -0
  62. package/dist/src/provider/codex/probe.d.ts +2 -0
  63. package/dist/src/provider/codex/probe.js +33 -0
  64. package/dist/src/provider/codex/probe.js.map +1 -0
  65. package/dist/src/provider/codex/protocol.d.ts +193 -0
  66. package/dist/src/provider/codex/protocol.js +10 -0
  67. package/dist/src/provider/codex/protocol.js.map +1 -0
  68. package/dist/src/provider/codex/provider.d.ts +35 -0
  69. package/dist/src/provider/codex/provider.js +289 -0
  70. package/dist/src/provider/codex/provider.js.map +1 -0
  71. package/dist/src/provider/codex/remote-app-server.d.ts +16 -0
  72. package/dist/src/provider/codex/remote-app-server.js +80 -0
  73. package/dist/src/provider/codex/remote-app-server.js.map +1 -0
  74. package/dist/src/provider/codex/websocket-client.d.ts +40 -0
  75. package/dist/src/provider/codex/websocket-client.js +174 -0
  76. package/dist/src/provider/codex/websocket-client.js.map +1 -0
  77. package/dist/src/provider/types.d.ts +35 -0
  78. package/dist/src/provider/types.js +2 -0
  79. package/dist/src/provider/types.js.map +1 -0
  80. package/dist/src/recall/embedding.d.ts +28 -0
  81. package/dist/src/recall/embedding.js +142 -0
  82. package/dist/src/recall/embedding.js.map +1 -0
  83. package/dist/src/recall/types.d.ts +35 -0
  84. package/dist/src/recall/types.js +2 -0
  85. package/dist/src/recall/types.js.map +1 -0
  86. package/dist/src/rpc/client.d.ts +6 -0
  87. package/dist/src/rpc/client.js +58 -0
  88. package/dist/src/rpc/client.js.map +1 -0
  89. package/dist/src/rpc/protocol.d.ts +21 -0
  90. package/dist/src/rpc/protocol.js +11 -0
  91. package/dist/src/rpc/protocol.js.map +1 -0
  92. package/dist/src/rpc/server.d.ts +12 -0
  93. package/dist/src/rpc/server.js +154 -0
  94. package/dist/src/rpc/server.js.map +1 -0
  95. package/dist/src/runtime/paths.d.ts +8 -0
  96. package/dist/src/runtime/paths.js +18 -0
  97. package/dist/src/runtime/paths.js.map +1 -0
  98. package/dist/src/service.d.ts +127 -0
  99. package/dist/src/service.js +637 -0
  100. package/dist/src/service.js.map +1 -0
  101. package/dist/src/session-profile.d.ts +39 -0
  102. package/dist/src/session-profile.js +186 -0
  103. package/dist/src/session-profile.js.map +1 -0
  104. package/dist/src/storage/database.d.ts +9 -0
  105. package/dist/src/storage/database.js +354 -0
  106. package/dist/src/storage/database.js.map +1 -0
  107. package/dist/src/storage/repository.d.ts +275 -0
  108. package/dist/src/storage/repository.js +1291 -0
  109. package/dist/src/storage/repository.js.map +1 -0
  110. package/dist/src/version.d.ts +1 -0
  111. package/dist/src/version.js +2 -0
  112. package/dist/src/version.js.map +1 -0
  113. package/docs/architecture-plan.md +191 -0
  114. package/docs/mvp-plan.md +111 -0
  115. package/docs/remote-demo.md +346 -0
  116. package/package.json +47 -0
@@ -0,0 +1,154 @@
1
+ import { mkdir, chmod, lstat, unlink } from "node:fs/promises";
2
+ import net from "node:net";
3
+ import path from "node:path";
4
+ import { isRpcRequest, MAX_RPC_LINE_BYTES } from "./protocol.js";
5
+ function failure(id, code, message, data) {
6
+ return data === undefined ? { id, error: { code, message } } : { id, error: { code, message, data } };
7
+ }
8
+ async function removeStaleSocket(socketPath) {
9
+ try {
10
+ const stat = await lstat(socketPath);
11
+ if (!stat.isSocket())
12
+ throw new Error(`Refusing to replace non-socket path: ${socketPath}`);
13
+ if (await socketAcceptsConnections(socketPath)) {
14
+ throw new Error(`Portal daemon is already listening at ${socketPath}`);
15
+ }
16
+ await unlink(socketPath);
17
+ }
18
+ catch (error) {
19
+ if (error.code !== "ENOENT")
20
+ throw error;
21
+ }
22
+ }
23
+ async function socketAcceptsConnections(socketPath) {
24
+ return new Promise((resolve, reject) => {
25
+ const socket = net.createConnection(socketPath);
26
+ let settled = false;
27
+ const finish = (value) => {
28
+ if (settled)
29
+ return;
30
+ settled = true;
31
+ clearTimeout(timer);
32
+ socket.destroy();
33
+ resolve(value);
34
+ };
35
+ const timer = setTimeout(() => finish(true), 500);
36
+ timer.unref();
37
+ socket.once("connect", () => finish(true));
38
+ socket.once("error", (error) => {
39
+ if (settled)
40
+ return;
41
+ if (error.code === "ECONNREFUSED" || error.code === "ENOENT")
42
+ finish(false);
43
+ else {
44
+ settled = true;
45
+ clearTimeout(timer);
46
+ reject(error);
47
+ }
48
+ });
49
+ });
50
+ }
51
+ export class RpcServer {
52
+ #options;
53
+ #server = null;
54
+ #sockets = new Set();
55
+ constructor(options) {
56
+ this.#options = options;
57
+ }
58
+ async start() {
59
+ if (this.#server !== null)
60
+ return;
61
+ const directory = path.dirname(this.#options.socketPath);
62
+ await mkdir(directory, { recursive: true, mode: 0o700 });
63
+ await chmod(directory, 0o700);
64
+ await removeStaleSocket(this.#options.socketPath);
65
+ const server = net.createServer((socket) => {
66
+ this.#sockets.add(socket);
67
+ socket.once("close", () => this.#sockets.delete(socket));
68
+ this.#serve(socket);
69
+ });
70
+ this.#server = server;
71
+ try {
72
+ await new Promise((resolve, reject) => {
73
+ server.once("error", reject);
74
+ server.listen(this.#options.socketPath, () => {
75
+ server.off("error", reject);
76
+ resolve();
77
+ });
78
+ });
79
+ }
80
+ catch (error) {
81
+ this.#server = null;
82
+ throw error;
83
+ }
84
+ await chmod(this.#options.socketPath, 0o600);
85
+ }
86
+ async close() {
87
+ const server = this.#server;
88
+ this.#server = null;
89
+ if (server !== null) {
90
+ await new Promise((resolve) => {
91
+ let settled = false;
92
+ const finish = () => {
93
+ if (settled)
94
+ return;
95
+ settled = true;
96
+ clearTimeout(deadline);
97
+ resolve();
98
+ };
99
+ const deadline = setTimeout(() => {
100
+ for (const socket of this.#sockets)
101
+ socket.destroy();
102
+ finish();
103
+ }, 1_000);
104
+ deadline.unref();
105
+ server.close(() => finish());
106
+ });
107
+ }
108
+ await removeStaleSocket(this.#options.socketPath);
109
+ }
110
+ #serve(socket) {
111
+ socket.setEncoding("utf8");
112
+ let buffered = "";
113
+ socket.on("data", (chunk) => {
114
+ buffered += chunk;
115
+ if (Buffer.byteLength(buffered) > MAX_RPC_LINE_BYTES) {
116
+ socket.end(`${JSON.stringify(failure("unknown", "request_too_large", "RPC request exceeded size limit"))}\n`);
117
+ return;
118
+ }
119
+ let newline = buffered.indexOf("\n");
120
+ while (newline >= 0) {
121
+ const line = buffered.slice(0, newline);
122
+ buffered = buffered.slice(newline + 1);
123
+ if (line.trim())
124
+ void this.#handleLine(socket, line);
125
+ newline = buffered.indexOf("\n");
126
+ }
127
+ });
128
+ }
129
+ async #handleLine(socket, line) {
130
+ let response;
131
+ let value;
132
+ try {
133
+ value = JSON.parse(line);
134
+ }
135
+ catch {
136
+ response = failure("unknown", "invalid_json", "Request is not valid JSON");
137
+ socket.write(`${JSON.stringify(response)}\n`);
138
+ return;
139
+ }
140
+ if (!isRpcRequest(value)) {
141
+ response = failure("unknown", "invalid_request", "Request requires string id and method");
142
+ }
143
+ else {
144
+ try {
145
+ response = { id: value.id, result: await this.#options.handler(value) };
146
+ }
147
+ catch (error) {
148
+ response = failure(value.id, "handler_error", error instanceof Error ? error.message : "Unknown handler error");
149
+ }
150
+ }
151
+ socket.write(`${JSON.stringify(response)}\n`);
152
+ }
153
+ }
154
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../../src/rpc/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export interface PortalPaths {
2
+ stateDir: string;
3
+ databasePath: string;
4
+ runtimeDir: string;
5
+ socketPath: string;
6
+ controlTokenPath: string;
7
+ }
8
+ export declare function resolvePortalPaths(environment?: NodeJS.ProcessEnv): PortalPaths;
@@ -0,0 +1,18 @@
1
+ import os from "node:os";
2
+ import path from "node:path";
3
+ export function resolvePortalPaths(environment = process.env) {
4
+ const stateDir = environment.PORTAL_STATE_DIR ??
5
+ (process.platform === "darwin"
6
+ ? path.join(os.homedir(), "Library", "Application Support", "Portal")
7
+ : path.join(environment.XDG_STATE_HOME ?? path.join(os.homedir(), ".local", "state"), "portal"));
8
+ const runtimeDir = environment.PORTAL_RUNTIME_DIR ??
9
+ path.join(environment.XDG_RUNTIME_DIR ?? os.tmpdir(), `portal-${process.getuid?.() ?? "user"}`);
10
+ return {
11
+ stateDir,
12
+ databasePath: path.join(stateDir, "portal.db"),
13
+ runtimeDir,
14
+ socketPath: path.join(runtimeDir, "portald.sock"),
15
+ controlTokenPath: path.join(runtimeDir, "control.token"),
16
+ };
17
+ }
18
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../src/runtime/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAU7B,MAAM,UAAU,kBAAkB,CAAC,WAAW,GAAsB,OAAO,CAAC,GAAG;IAC7E,MAAM,QAAQ,GACZ,WAAW,CAAC,gBAAgB;QAC5B,CAAC,OAAO,CAAC,QAAQ,KAAK,QAAQ;YAC5B,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,qBAAqB,EAAE,QAAQ,CAAC;YACrE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,cAAc,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC;IAErG,MAAM,UAAU,GACd,WAAW,CAAC,kBAAkB;QAC9B,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,eAAe,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,UAAU,OAAO,CAAC,MAAM,EAAE,EAAE,IAAI,MAAM,EAAE,CAAC,CAAC;IAElG,OAAO;QACL,QAAQ;QACR,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC;QAC9C,UAAU;QACV,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC;QACjD,gBAAgB,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC;KACzD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,127 @@
1
+ import type { ProviderAdapter, ProviderName } from "./provider/types.js";
2
+ import type { RecallBundle, RecallOptions } from "./recall/types.js";
3
+ import { type SessionReachability } from "./session-profile.js";
4
+ import { PortalIndex } from "./portal-index.js";
5
+ import type { MessageReceipt, StoredMessage, StoredRemoteTaskEvent, StoredSession, StoredSessionProfile } from "./storage/repository.js";
6
+ export interface RefreshError {
7
+ provider: ProviderName;
8
+ vendorSessionId: string | null;
9
+ message: string;
10
+ }
11
+ export interface RefreshResult {
12
+ observed: number;
13
+ indexed: number;
14
+ unchanged: number;
15
+ errors: RefreshError[];
16
+ sessions: StoredSession[];
17
+ }
18
+ export interface PortalServiceOptions {
19
+ databasePath: string;
20
+ providers?: readonly ProviderAdapter[];
21
+ }
22
+ export interface SendMessageInput {
23
+ senderSessionId: string;
24
+ targetSessionId?: string;
25
+ targetReference?: string;
26
+ body: string;
27
+ idempotencyKey?: string;
28
+ replyTo?: string | null;
29
+ }
30
+ export interface ResolutionCandidate {
31
+ portalSessionId: string;
32
+ displayName: string;
33
+ description: string;
34
+ reachability: SessionReachability;
35
+ score: number;
36
+ reasons: string[];
37
+ }
38
+ export interface MessageResolution {
39
+ status: "resolved" | "ambiguous" | "unresolved";
40
+ query: string;
41
+ strategy?: "id" | "exact" | "normalized" | "profile" | "intent" | "idempotent";
42
+ targetSessionId?: string;
43
+ candidates: ResolutionCandidate[];
44
+ }
45
+ export interface SentMessageResult {
46
+ message: StoredMessage;
47
+ delivery: "completed" | "failed" | "delivered" | "queued_inbox" | "queued_unavailable";
48
+ receipt?: MessageReceipt;
49
+ resolution: MessageResolution;
50
+ }
51
+ export interface UnresolvedMessageResult {
52
+ message: null;
53
+ delivery: "not_sent";
54
+ resolution: MessageResolution;
55
+ }
56
+ export type SendMessageResult = SentMessageResult | UnresolvedMessageResult;
57
+ export interface SessionView extends StoredSession {
58
+ profile: StoredSessionProfile | null;
59
+ reachability: SessionReachability;
60
+ }
61
+ export interface RunnerDelivery {
62
+ source: "local" | "remote";
63
+ message: StoredMessage;
64
+ senderLabel: string;
65
+ senderReference: string;
66
+ authenticated: boolean;
67
+ remoteEvent?: StoredRemoteTaskEvent;
68
+ }
69
+ export type RunnerCompletion = MessageReceipt | StoredRemoteTaskEvent;
70
+ export interface PreparedManagedSession {
71
+ session: StoredSession;
72
+ token: string;
73
+ }
74
+ /** Coordinates adapters, the durable index, recall, and the message queue. */
75
+ export declare class PortalService {
76
+ #private;
77
+ readonly index: PortalIndex;
78
+ readonly providers: readonly ProviderAdapter[];
79
+ constructor(options: PortalServiceOptions);
80
+ close(): Promise<void>;
81
+ refresh(options?: {
82
+ workspace?: string;
83
+ providers?: readonly ProviderName[];
84
+ }): Promise<RefreshResult>;
85
+ listSessions(workspace?: string): SessionView[];
86
+ resolveSession(reference: string, workspace?: string): StoredSession;
87
+ issueSessionCredential(reference: string, workspace?: string): {
88
+ sessionId: string;
89
+ token: string;
90
+ };
91
+ prepareManagedSession(input: {
92
+ provider: ProviderName;
93
+ vendorSessionId: string;
94
+ workspace: string;
95
+ title?: string | null;
96
+ managedName?: string | null;
97
+ initialPrompt?: string | null;
98
+ }): PreparedManagedSession;
99
+ authenticateSession(sessionId: string, token: string): StoredSession;
100
+ disconnectSession(sessionId: string, token: string): void;
101
+ finishManagedSession(sessionId: string, token: string): void;
102
+ bindManagedSession(sessionId: string, token: string, vendorSessionId: string): StoredSession;
103
+ recall(query: string, options: RecallOptions & {
104
+ refresh?: boolean;
105
+ }): Promise<RecallBundle>;
106
+ send(input: SendMessageInput): Promise<SendMessageResult>;
107
+ private resolveMessageTarget;
108
+ private rankedRoutingCandidates;
109
+ private saveDerivedProfile;
110
+ private sessionReachability;
111
+ nextRunnerMessage(sessionId: string, token: string, waitMs?: number): Promise<RunnerDelivery | null>;
112
+ runnerMessageReceived(sessionId: string, token: string, messageId: string, turnId: string): RunnerCompletion;
113
+ runnerMessageStarting(sessionId: string, token: string, messageId: string): RunnerCompletion;
114
+ heartbeatRunner(sessionId: string, token: string): {
115
+ active: true;
116
+ };
117
+ runnerMessageCompleted(sessionId: string, token: string, messageId: string, input: {
118
+ turnId: string;
119
+ answer: string | null;
120
+ toolResults: readonly unknown[];
121
+ }): RunnerCompletion;
122
+ runnerMessageFailed(sessionId: string, token: string, messageId: string, error: string): RunnerCompletion;
123
+ disconnectRunner(sessionId: string, token: string): void;
124
+ private waitForRunnerCompletion;
125
+ inbox(targetSessionId: string): StoredMessage[];
126
+ receiveInbox(targetSessionId: string, acknowledgements?: readonly string[]): StoredMessage[];
127
+ }