@seanpropapp/cli 0.1.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +64 -0
- package/dist/commands/autostart.d.ts +42 -0
- package/dist/commands/autostart.js +195 -0
- package/dist/commands/autostart.js.map +1 -0
- package/dist/commands/bridge.d.ts +54 -0
- package/dist/commands/bridge.js +145 -0
- package/dist/commands/bridge.js.map +1 -0
- package/dist/commands/connect.d.ts +56 -0
- package/dist/commands/connect.js +213 -0
- package/dist/commands/connect.js.map +1 -0
- package/dist/commands/doctor.d.ts +24 -0
- package/dist/commands/doctor.js +200 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/install-claude.d.ts +22 -0
- package/dist/commands/install-claude.js +56 -0
- package/dist/commands/install-claude.js.map +1 -0
- package/dist/commands/mcp.d.ts +5 -0
- package/dist/commands/mcp.js +23 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/pair-url.d.ts +12 -0
- package/dist/commands/pair-url.js +23 -0
- package/dist/commands/pair-url.js.map +1 -0
- package/dist/commands/pair.d.ts +12 -0
- package/dist/commands/pair.js +24 -0
- package/dist/commands/pair.js.map +1 -0
- package/dist/commands/prompt.d.ts +5 -0
- package/dist/commands/prompt.js +24 -0
- package/dist/commands/prompt.js.map +1 -0
- package/dist/commands/telemetry-cmd.d.ts +8 -0
- package/dist/commands/telemetry-cmd.js +55 -0
- package/dist/commands/telemetry-cmd.js.map +1 -0
- package/dist/config.d.ts +63 -0
- package/dist/config.js +77 -0
- package/dist/config.js.map +1 -0
- package/dist/http/auth-middleware.d.ts +9 -0
- package/dist/http/auth-middleware.js +29 -0
- package/dist/http/auth-middleware.js.map +1 -0
- package/dist/http/chat-completions.d.ts +48 -0
- package/dist/http/chat-completions.js +117 -0
- package/dist/http/chat-completions.js.map +1 -0
- package/dist/http/cors.d.ts +9 -0
- package/dist/http/cors.js +35 -0
- package/dist/http/cors.js.map +1 -0
- package/dist/http/handshake.d.ts +43 -0
- package/dist/http/handshake.js +28 -0
- package/dist/http/handshake.js.map +1 -0
- package/dist/http/messages-endpoint.d.ts +67 -0
- package/dist/http/messages-endpoint.js +95 -0
- package/dist/http/messages-endpoint.js.map +1 -0
- package/dist/http/server.d.ts +37 -0
- package/dist/http/server.js +83 -0
- package/dist/http/server.js.map +1 -0
- package/dist/http/sse.d.ts +35 -0
- package/dist/http/sse.js +72 -0
- package/dist/http/sse.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +219 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/manifest.d.ts +16 -0
- package/dist/mcp/manifest.js +88 -0
- package/dist/mcp/manifest.js.map +1 -0
- package/dist/mcp/server.d.ts +25 -0
- package/dist/mcp/server.js +166 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/providers/base.d.ts +91 -0
- package/dist/providers/base.js +27 -0
- package/dist/providers/base.js.map +1 -0
- package/dist/providers/claude.d.ts +22 -0
- package/dist/providers/claude.js +157 -0
- package/dist/providers/claude.js.map +1 -0
- package/dist/providers/codex.d.ts +38 -0
- package/dist/providers/codex.js +179 -0
- package/dist/providers/codex.js.map +1 -0
- package/dist/providers/detect-util.d.ts +17 -0
- package/dist/providers/detect-util.js +68 -0
- package/dist/providers/detect-util.js.map +1 -0
- package/dist/providers/index.d.ts +14 -0
- package/dist/providers/index.js +21 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/telemetry.d.ts +68 -0
- package/dist/telemetry.js +118 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/version.d.ts +9 -0
- package/dist/version.js +10 -0
- package/dist/version.js.map +1 -0
- package/package.json +62 -0
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { Context } from "hono";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import type { Provider } from "../providers/base.js";
|
|
4
|
+
declare const MessagesRequestSchema: z.ZodObject<{
|
|
5
|
+
model: z.ZodString;
|
|
6
|
+
max_tokens: z.ZodOptional<z.ZodNumber>;
|
|
7
|
+
system: z.ZodOptional<z.ZodString>;
|
|
8
|
+
messages: z.ZodArray<z.ZodObject<{
|
|
9
|
+
role: z.ZodEnum<["user", "assistant", "system"]>;
|
|
10
|
+
content: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodObject<{
|
|
11
|
+
type: z.ZodString;
|
|
12
|
+
text: z.ZodOptional<z.ZodString>;
|
|
13
|
+
}, "strip", z.ZodTypeAny, {
|
|
14
|
+
type: string;
|
|
15
|
+
text?: string | undefined;
|
|
16
|
+
}, {
|
|
17
|
+
type: string;
|
|
18
|
+
text?: string | undefined;
|
|
19
|
+
}>, "many">]>;
|
|
20
|
+
}, "strip", z.ZodTypeAny, {
|
|
21
|
+
role: "user" | "assistant" | "system";
|
|
22
|
+
content: string | {
|
|
23
|
+
type: string;
|
|
24
|
+
text?: string | undefined;
|
|
25
|
+
}[];
|
|
26
|
+
}, {
|
|
27
|
+
role: "user" | "assistant" | "system";
|
|
28
|
+
content: string | {
|
|
29
|
+
type: string;
|
|
30
|
+
text?: string | undefined;
|
|
31
|
+
}[];
|
|
32
|
+
}>, "many">;
|
|
33
|
+
stream: z.ZodOptional<z.ZodBoolean>;
|
|
34
|
+
temperature: z.ZodOptional<z.ZodNumber>;
|
|
35
|
+
}, "strip", z.ZodTypeAny, {
|
|
36
|
+
model: string;
|
|
37
|
+
messages: {
|
|
38
|
+
role: "user" | "assistant" | "system";
|
|
39
|
+
content: string | {
|
|
40
|
+
type: string;
|
|
41
|
+
text?: string | undefined;
|
|
42
|
+
}[];
|
|
43
|
+
}[];
|
|
44
|
+
system?: string | undefined;
|
|
45
|
+
max_tokens?: number | undefined;
|
|
46
|
+
stream?: boolean | undefined;
|
|
47
|
+
temperature?: number | undefined;
|
|
48
|
+
}, {
|
|
49
|
+
model: string;
|
|
50
|
+
messages: {
|
|
51
|
+
role: "user" | "assistant" | "system";
|
|
52
|
+
content: string | {
|
|
53
|
+
type: string;
|
|
54
|
+
text?: string | undefined;
|
|
55
|
+
}[];
|
|
56
|
+
}[];
|
|
57
|
+
system?: string | undefined;
|
|
58
|
+
max_tokens?: number | undefined;
|
|
59
|
+
stream?: boolean | undefined;
|
|
60
|
+
temperature?: number | undefined;
|
|
61
|
+
}>;
|
|
62
|
+
export type MessagesRequest = z.infer<typeof MessagesRequestSchema>;
|
|
63
|
+
export interface MessagesDeps {
|
|
64
|
+
pickProvider: (model: string) => Provider;
|
|
65
|
+
}
|
|
66
|
+
export declare function makeMessagesHandler(deps: MessagesDeps): (c: Context) => Promise<import("undici-types").Response>;
|
|
67
|
+
export {};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { ClassifiedError } from "../providers/base.js";
|
|
3
|
+
import { encodeAnthropicSSE } from "./sse.js";
|
|
4
|
+
const MessagesRequestSchema = z.object({
|
|
5
|
+
model: z.string().min(1),
|
|
6
|
+
max_tokens: z.number().int().positive().optional(),
|
|
7
|
+
system: z.string().optional(),
|
|
8
|
+
messages: z
|
|
9
|
+
.array(z.object({
|
|
10
|
+
role: z.enum(["user", "assistant", "system"]),
|
|
11
|
+
content: z.union([
|
|
12
|
+
z.string(),
|
|
13
|
+
z.array(z.object({
|
|
14
|
+
type: z.string(),
|
|
15
|
+
text: z.string().optional(),
|
|
16
|
+
})),
|
|
17
|
+
]),
|
|
18
|
+
}))
|
|
19
|
+
.min(1),
|
|
20
|
+
stream: z.boolean().optional(),
|
|
21
|
+
temperature: z.number().optional(),
|
|
22
|
+
});
|
|
23
|
+
function errorEventBytes(err) {
|
|
24
|
+
return encodeAnthropicSSE({
|
|
25
|
+
type: "error",
|
|
26
|
+
error: {
|
|
27
|
+
type: err.category === "subscription_limit"
|
|
28
|
+
? "rate_limit_exceeded"
|
|
29
|
+
: err.category,
|
|
30
|
+
message: err.message,
|
|
31
|
+
retry_after_seconds: err.retryAfterSeconds,
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
export function makeMessagesHandler(deps) {
|
|
36
|
+
return async (c) => {
|
|
37
|
+
let body;
|
|
38
|
+
try {
|
|
39
|
+
body = await c.req.json();
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
return c.json({ error: { type: "invalid_request", message: "Body must be JSON" } }, 400);
|
|
43
|
+
}
|
|
44
|
+
const parsed = MessagesRequestSchema.safeParse(body);
|
|
45
|
+
if (!parsed.success) {
|
|
46
|
+
return c.json({
|
|
47
|
+
error: {
|
|
48
|
+
type: "invalid_request",
|
|
49
|
+
message: parsed.error.issues
|
|
50
|
+
.map((i) => `${i.path.join(".")}: ${i.message}`)
|
|
51
|
+
.join("; "),
|
|
52
|
+
},
|
|
53
|
+
}, 400);
|
|
54
|
+
}
|
|
55
|
+
const request = parsed.data;
|
|
56
|
+
const provider = deps.pickProvider(request.model);
|
|
57
|
+
// Stream Anthropic-format SSE back to the browser. We set the response
|
|
58
|
+
// headers immediately and then push events through a TransformStream so
|
|
59
|
+
// the runtime flushes per chunk.
|
|
60
|
+
const { readable, writable } = new TransformStream();
|
|
61
|
+
const writer = writable.getWriter();
|
|
62
|
+
// Kick off the pipe in the background; never await it before returning.
|
|
63
|
+
(async () => {
|
|
64
|
+
try {
|
|
65
|
+
for await (const event of provider.stream(request)) {
|
|
66
|
+
await writer.write(encodeAnthropicSSE(event));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch (err) {
|
|
70
|
+
if (err instanceof ClassifiedError) {
|
|
71
|
+
await writer.write(errorEventBytes(err));
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
75
|
+
await writer.write(encodeAnthropicSSE({
|
|
76
|
+
type: "error",
|
|
77
|
+
error: { type: "internal_error", message },
|
|
78
|
+
}));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
finally {
|
|
82
|
+
await writer.close().catch(() => undefined);
|
|
83
|
+
}
|
|
84
|
+
})();
|
|
85
|
+
return new Response(readable, {
|
|
86
|
+
status: 200,
|
|
87
|
+
headers: {
|
|
88
|
+
"Content-Type": "text/event-stream",
|
|
89
|
+
"Cache-Control": "no-cache, no-transform",
|
|
90
|
+
Connection: "keep-alive",
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=messages-endpoint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages-endpoint.js","sourceRoot":"","sources":["../../src/http/messages-endpoint.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
import type { Provider } from "../providers/base.js";
|
|
3
|
+
export declare const DEFAULT_BRIDGE_PORT = 17492;
|
|
4
|
+
export declare const MAX_PORT_FALLBACK = 17500;
|
|
5
|
+
export interface StartServerOptions {
|
|
6
|
+
port?: number;
|
|
7
|
+
/**
|
|
8
|
+
* Either a literal token (the simple v0.1.0-alpha shape) or a getter that
|
|
9
|
+
* returns the current token. The getter form lets the bridge process
|
|
10
|
+
* rotate tokens on SIGHUP without restarting the HTTP listener.
|
|
11
|
+
*/
|
|
12
|
+
token: string | (() => string);
|
|
13
|
+
/** Optional provider overrides for testing. */
|
|
14
|
+
providers?: {
|
|
15
|
+
claude?: Provider;
|
|
16
|
+
codex?: Provider;
|
|
17
|
+
};
|
|
18
|
+
/** Optional override for the paired_at value surfaced in /v1/handshake. */
|
|
19
|
+
pairedAt?: () => string | null;
|
|
20
|
+
}
|
|
21
|
+
export interface RunningServer {
|
|
22
|
+
port: number;
|
|
23
|
+
url: string;
|
|
24
|
+
close: () => Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Build the Hono app. Exposed for tests so they can run the app directly
|
|
28
|
+
* via `app.request(...)` without binding to a real socket.
|
|
29
|
+
*/
|
|
30
|
+
export declare function createApp(opts: StartServerOptions): Hono<import("hono/types").BlankEnv, import("hono/types").BlankSchema, "/">;
|
|
31
|
+
/**
|
|
32
|
+
* Bind the server, falling back through ports 17492..17500 if the requested
|
|
33
|
+
* port is taken. When a non-default port is explicitly supplied, fall back
|
|
34
|
+
* up to 8 ports above the requested port (matches the default range width)
|
|
35
|
+
* so explicit ports get the same graceful behavior.
|
|
36
|
+
*/
|
|
37
|
+
export declare function startServer(opts: StartServerOptions): Promise<RunningServer>;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
import { serve } from "@hono/node-server";
|
|
3
|
+
import { corsMiddleware } from "./cors.js";
|
|
4
|
+
import { makeAuthMiddleware } from "./auth-middleware.js";
|
|
5
|
+
import { makeHandshakeHandler } from "./handshake.js";
|
|
6
|
+
import { makeMessagesHandler } from "./messages-endpoint.js";
|
|
7
|
+
import { makeChatCompletionsHandler } from "./chat-completions.js";
|
|
8
|
+
import { ClaudeProvider, CodexProvider } from "../providers/index.js";
|
|
9
|
+
export const DEFAULT_BRIDGE_PORT = 17492;
|
|
10
|
+
export const MAX_PORT_FALLBACK = 17500;
|
|
11
|
+
/**
|
|
12
|
+
* Build the Hono app. Exposed for tests so they can run the app directly
|
|
13
|
+
* via `app.request(...)` without binding to a real socket.
|
|
14
|
+
*/
|
|
15
|
+
export function createApp(opts) {
|
|
16
|
+
const claude = opts.providers?.claude ?? new ClaudeProvider();
|
|
17
|
+
const codex = opts.providers?.codex ?? new CodexProvider();
|
|
18
|
+
function pickProviderForModel(model) {
|
|
19
|
+
const m = model.toLowerCase();
|
|
20
|
+
if (m.startsWith("claude-"))
|
|
21
|
+
return claude;
|
|
22
|
+
if (m.startsWith("gpt-") || m.startsWith("o3") || m.startsWith("o1")) {
|
|
23
|
+
return codex;
|
|
24
|
+
}
|
|
25
|
+
// Generic "subscription" pseudo-model: route by what's installed; default to claude.
|
|
26
|
+
return claude;
|
|
27
|
+
}
|
|
28
|
+
const app = new Hono();
|
|
29
|
+
app.use("*", corsMiddleware);
|
|
30
|
+
app.get("/v1/handshake", makeAuthMiddleware(opts.token), makeHandshakeHandler({
|
|
31
|
+
pairedAt: opts.pairedAt ?? (() => null),
|
|
32
|
+
claude,
|
|
33
|
+
codex,
|
|
34
|
+
}));
|
|
35
|
+
app.post("/v1/messages", makeAuthMiddleware(opts.token), makeMessagesHandler({ pickProvider: pickProviderForModel }));
|
|
36
|
+
app.post("/v1/chat/completions", makeAuthMiddleware(opts.token), makeChatCompletionsHandler({ pickProvider: pickProviderForModel }));
|
|
37
|
+
return app;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Try to bind to `port`. Resolves with the actual port on success or null
|
|
41
|
+
* if the port is in use. Other errors reject.
|
|
42
|
+
*/
|
|
43
|
+
function tryListen(app, port) {
|
|
44
|
+
return new Promise((resolve, reject) => {
|
|
45
|
+
const server = serve({ fetch: app.fetch, port, hostname: "127.0.0.1" }, (info) => {
|
|
46
|
+
resolve({
|
|
47
|
+
port: info.port,
|
|
48
|
+
url: `http://127.0.0.1:${info.port}`,
|
|
49
|
+
close: () => new Promise((res) => {
|
|
50
|
+
server.close(() => res());
|
|
51
|
+
}),
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
server.on("error", (err) => {
|
|
55
|
+
if (err.code === "EADDRINUSE") {
|
|
56
|
+
resolve(null);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
reject(err);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Bind the server, falling back through ports 17492..17500 if the requested
|
|
66
|
+
* port is taken. When a non-default port is explicitly supplied, fall back
|
|
67
|
+
* up to 8 ports above the requested port (matches the default range width)
|
|
68
|
+
* so explicit ports get the same graceful behavior.
|
|
69
|
+
*/
|
|
70
|
+
export async function startServer(opts) {
|
|
71
|
+
const app = createApp(opts);
|
|
72
|
+
const startPort = opts.port ?? DEFAULT_BRIDGE_PORT;
|
|
73
|
+
const endPort = startPort === DEFAULT_BRIDGE_PORT
|
|
74
|
+
? MAX_PORT_FALLBACK
|
|
75
|
+
: startPort + (MAX_PORT_FALLBACK - DEFAULT_BRIDGE_PORT);
|
|
76
|
+
for (let port = startPort; port <= endPort; port++) {
|
|
77
|
+
const running = await tryListen(app, port);
|
|
78
|
+
if (running)
|
|
79
|
+
return running;
|
|
80
|
+
}
|
|
81
|
+
throw new Error(`No available port in range ${startPort}-${endPort}. Stop another process or pass --port.`);
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/http/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { AnthropicSSEEvent } from "../providers/base.js";
|
|
2
|
+
/**
|
|
3
|
+
* Encode an Anthropic-shape SSE event as wire bytes.
|
|
4
|
+
* Anthropic's format: `event: <name>\ndata: <json>\n\n`
|
|
5
|
+
*/
|
|
6
|
+
export declare function encodeAnthropicSSE(event: AnthropicSSEEvent): Uint8Array;
|
|
7
|
+
export interface OpenAIDelta {
|
|
8
|
+
id: string;
|
|
9
|
+
object: "chat.completion.chunk";
|
|
10
|
+
created: number;
|
|
11
|
+
model: string;
|
|
12
|
+
choices: Array<{
|
|
13
|
+
index: number;
|
|
14
|
+
delta: {
|
|
15
|
+
content?: string;
|
|
16
|
+
role?: "assistant";
|
|
17
|
+
};
|
|
18
|
+
finish_reason: string | null;
|
|
19
|
+
}>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Translate an Anthropic SSE event back into OpenAI Chat Completions
|
|
23
|
+
* chunk format, so the bridge can serve both wire shapes uniformly.
|
|
24
|
+
* Returns null when an event doesn't map to a chunk (e.g. message_start).
|
|
25
|
+
*/
|
|
26
|
+
export declare function anthropicEventToOpenAIChunk(event: AnthropicSSEEvent, ctx: {
|
|
27
|
+
id: string;
|
|
28
|
+
model: string;
|
|
29
|
+
created: number;
|
|
30
|
+
}): OpenAIDelta | {
|
|
31
|
+
done: true;
|
|
32
|
+
} | null;
|
|
33
|
+
export declare function encodeOpenAIChunk(chunk: OpenAIDelta | {
|
|
34
|
+
done: true;
|
|
35
|
+
}): Uint8Array;
|
package/dist/http/sse.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encode an Anthropic-shape SSE event as wire bytes.
|
|
3
|
+
* Anthropic's format: `event: <name>\ndata: <json>\n\n`
|
|
4
|
+
*/
|
|
5
|
+
export function encodeAnthropicSSE(event) {
|
|
6
|
+
const payload = `event: ${event.type}\ndata: ${JSON.stringify(event)}\n\n`;
|
|
7
|
+
return new TextEncoder().encode(payload);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Translate an Anthropic SSE event back into OpenAI Chat Completions
|
|
11
|
+
* chunk format, so the bridge can serve both wire shapes uniformly.
|
|
12
|
+
* Returns null when an event doesn't map to a chunk (e.g. message_start).
|
|
13
|
+
*/
|
|
14
|
+
export function anthropicEventToOpenAIChunk(event, ctx) {
|
|
15
|
+
switch (event.type) {
|
|
16
|
+
case "message_start":
|
|
17
|
+
return {
|
|
18
|
+
id: ctx.id,
|
|
19
|
+
object: "chat.completion.chunk",
|
|
20
|
+
created: ctx.created,
|
|
21
|
+
model: ctx.model,
|
|
22
|
+
choices: [
|
|
23
|
+
{
|
|
24
|
+
index: 0,
|
|
25
|
+
delta: { role: "assistant" },
|
|
26
|
+
finish_reason: null,
|
|
27
|
+
},
|
|
28
|
+
],
|
|
29
|
+
};
|
|
30
|
+
case "content_block_delta":
|
|
31
|
+
return {
|
|
32
|
+
id: ctx.id,
|
|
33
|
+
object: "chat.completion.chunk",
|
|
34
|
+
created: ctx.created,
|
|
35
|
+
model: ctx.model,
|
|
36
|
+
choices: [
|
|
37
|
+
{
|
|
38
|
+
index: 0,
|
|
39
|
+
delta: { content: event.delta.text },
|
|
40
|
+
finish_reason: null,
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
};
|
|
44
|
+
case "message_delta":
|
|
45
|
+
return {
|
|
46
|
+
id: ctx.id,
|
|
47
|
+
object: "chat.completion.chunk",
|
|
48
|
+
created: ctx.created,
|
|
49
|
+
model: ctx.model,
|
|
50
|
+
choices: [
|
|
51
|
+
{
|
|
52
|
+
index: 0,
|
|
53
|
+
delta: {},
|
|
54
|
+
finish_reason: event.delta.stop_reason === null ? null : "stop",
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
};
|
|
58
|
+
case "message_stop":
|
|
59
|
+
return { done: true };
|
|
60
|
+
case "error":
|
|
61
|
+
return null;
|
|
62
|
+
default:
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
export function encodeOpenAIChunk(chunk) {
|
|
67
|
+
if ("done" in chunk) {
|
|
68
|
+
return new TextEncoder().encode("data: [DONE]\n\n");
|
|
69
|
+
}
|
|
70
|
+
return new TextEncoder().encode(`data: ${JSON.stringify(chunk)}\n\n`);
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=sse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sse.js","sourceRoot":"","sources":["../../src/http/sse.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAwB;IACzD,MAAM,OAAO,GAAG,UAAU,KAAK,CAAC,IAAI,WAAW,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC;IAC3E,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAC3C,CAAC;AAcD;;;;GAIG;AACH,MAAM,UAAU,2BAA2B,CACzC,KAAwB,EACxB,GAAmD;IAEnD,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,eAAe;YAClB,OAAO;gBACL,EAAE,EAAE,GAAG,CAAC,EAAE;gBACV,MAAM,EAAE,uBAAuB;gBAC/B,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,KAAK,EAAE,GAAG,CAAC,KAAK;gBAChB,OAAO,EAAE;oBACP;wBACE,KAAK,EAAE,CAAC;wBACR,KAAK,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE;wBAC5B,aAAa,EAAE,IAAI;qBACpB;iBACF;aACF,CAAC;QACJ,KAAK,qBAAqB;YACxB,OAAO;gBACL,EAAE,EAAE,GAAG,CAAC,EAAE;gBACV,MAAM,EAAE,uBAAuB;gBAC/B,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,KAAK,EAAE,GAAG,CAAC,KAAK;gBAChB,OAAO,EAAE;oBACP;wBACE,KAAK,EAAE,CAAC;wBACR,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE;wBACpC,aAAa,EAAE,IAAI;qBACpB;iBACF;aACF,CAAC;QACJ,KAAK,eAAe;YAClB,OAAO;gBACL,EAAE,EAAE,GAAG,CAAC,EAAE;gBACV,MAAM,EAAE,uBAAuB;gBAC/B,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,KAAK,EAAE,GAAG,CAAC,KAAK;gBAChB,OAAO,EAAE;oBACP;wBACE,KAAK,EAAE,CAAC;wBACR,KAAK,EAAE,EAAE;wBACT,aAAa,EAAE,KAAK,CAAC,KAAK,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM;qBAChE;iBACF;aACF,CAAC;QACJ,KAAK,cAAc;YACjB,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QACxB,KAAK,OAAO;YACV,OAAO,IAAI,CAAC;QACd;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAmC;IACnE,IAAI,MAAM,IAAI,KAAK,EAAE,CAAC;QACpB,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;IACtD,CAAC;IACD,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AACxE,CAAC"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command, Option } from "commander";
|
|
3
|
+
import { CLI_VERSION } from "./version.js";
|
|
4
|
+
import { runConnect } from "./commands/connect.js";
|
|
5
|
+
import { runPair } from "./commands/pair.js";
|
|
6
|
+
import { runBridgeForeground, spawnBackgroundBridge } from "./commands/bridge.js";
|
|
7
|
+
import { loadConfig, updateConfig } from "./config.js";
|
|
8
|
+
import { runMcpCommand } from "./commands/mcp.js";
|
|
9
|
+
import { runDoctor } from "./commands/doctor.js";
|
|
10
|
+
import { installAutostart, uninstallAutostart } from "./commands/autostart.js";
|
|
11
|
+
import { runTelemetryDisable, runTelemetryEnable, runTelemetryStatus, } from "./commands/telemetry-cmd.js";
|
|
12
|
+
const HELP_AFTER = `
|
|
13
|
+
Usage: seanpropapp <command>
|
|
14
|
+
|
|
15
|
+
Run SeanPropApp on your existing Claude Pro or ChatGPT Plus subscription.
|
|
16
|
+
|
|
17
|
+
Commands:
|
|
18
|
+
connect Start everything and pair with your browser (use this first)
|
|
19
|
+
bridge Run the bridge server explicitly
|
|
20
|
+
pair Generate a new pair URL
|
|
21
|
+
mcp Run as MCP stdio server (Claude Desktop, Cursor)
|
|
22
|
+
doctor Self-diagnostic
|
|
23
|
+
autostart Install OS-native auto-start
|
|
24
|
+
telemetry enable | disable | status (opt-in TTHW events)
|
|
25
|
+
|
|
26
|
+
Global flags:
|
|
27
|
+
--config <path> Use custom config dir (default: ~/.seanpropapp/)
|
|
28
|
+
--quiet Suppress non-error output
|
|
29
|
+
--json Structured output for tooling
|
|
30
|
+
--verbose Debug-level diagnostics
|
|
31
|
+
--no-telemetry Suppress opt-in telemetry for this invocation
|
|
32
|
+
|
|
33
|
+
Quick start: npx @seanpropapp/cli connect
|
|
34
|
+
`;
|
|
35
|
+
function getGlobalOpts(cmd) {
|
|
36
|
+
// Commander stores global opts on the root program. Walk up to find it.
|
|
37
|
+
let cur = cmd;
|
|
38
|
+
while (cur.parent)
|
|
39
|
+
cur = cur.parent;
|
|
40
|
+
return cur.opts();
|
|
41
|
+
}
|
|
42
|
+
const program = new Command();
|
|
43
|
+
program
|
|
44
|
+
.name("seanpropapp")
|
|
45
|
+
.description("Run SeanPropApp on your existing Claude Pro or ChatGPT Plus subscription.")
|
|
46
|
+
.version(CLI_VERSION)
|
|
47
|
+
.addOption(new Option("--config <path>", "Use custom config dir").default(undefined, "~/.seanpropapp/"))
|
|
48
|
+
.addOption(new Option("--quiet", "Suppress non-error output"))
|
|
49
|
+
.addOption(new Option("--json", "Structured output for tooling"))
|
|
50
|
+
.addOption(new Option("--verbose", "Debug-level diagnostics"))
|
|
51
|
+
.addOption(new Option("--no-telemetry", "Suppress opt-in telemetry for this invocation"))
|
|
52
|
+
.addHelpText("after", HELP_AFTER);
|
|
53
|
+
program
|
|
54
|
+
.command("connect")
|
|
55
|
+
.description("Start everything and pair with your browser (use this first)")
|
|
56
|
+
.option("--port <n>", "Override the starting bridge port", (v) => Number(v))
|
|
57
|
+
.option("--no-bridge-fork", "Run the bridge inline instead of detaching it")
|
|
58
|
+
.action(async (opts, cmd) => {
|
|
59
|
+
const g = getGlobalOpts(cmd);
|
|
60
|
+
const connectOpts = {};
|
|
61
|
+
if (g.config !== undefined)
|
|
62
|
+
connectOpts.configDir = g.config;
|
|
63
|
+
if (opts.port !== undefined)
|
|
64
|
+
connectOpts.port = opts.port;
|
|
65
|
+
if (opts.bridgeFork === false)
|
|
66
|
+
connectOpts.noBridgeFork = true;
|
|
67
|
+
if (g.telemetry === false)
|
|
68
|
+
connectOpts.noTelemetry = true;
|
|
69
|
+
const result = await runConnect(connectOpts);
|
|
70
|
+
if (!result.success)
|
|
71
|
+
process.exitCode = 1;
|
|
72
|
+
});
|
|
73
|
+
program
|
|
74
|
+
.command("bridge")
|
|
75
|
+
.description("Run the bridge server explicitly")
|
|
76
|
+
.option("--port <n>", "Bridge port (default 17492)", (v) => Number(v))
|
|
77
|
+
.option("--foreground", "Run inline; default backgrounds it")
|
|
78
|
+
.option("--no-token-rotation", "Use pre-seeded SEANPROPAPP_PRESEED_TOKEN (internal flag)")
|
|
79
|
+
.action(async (opts, cmd) => {
|
|
80
|
+
const g = getGlobalOpts(cmd);
|
|
81
|
+
const preseed = process.env["SEANPROPAPP_PRESEED_TOKEN"];
|
|
82
|
+
if (opts.foreground) {
|
|
83
|
+
const bridgeOpts = {
|
|
84
|
+
reuseToken: opts.tokenRotation === false,
|
|
85
|
+
};
|
|
86
|
+
if (g.config !== undefined)
|
|
87
|
+
bridgeOpts.configDir = g.config;
|
|
88
|
+
if (opts.port !== undefined)
|
|
89
|
+
bridgeOpts.port = opts.port;
|
|
90
|
+
if (preseed)
|
|
91
|
+
bridgeOpts.token = preseed;
|
|
92
|
+
await runBridgeForeground(bridgeOpts);
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
// Background spawn (default).
|
|
96
|
+
const cfg = await loadConfig(g.config);
|
|
97
|
+
const token = preseed ??
|
|
98
|
+
(opts.tokenRotation === false && cfg.pair_token
|
|
99
|
+
? cfg.pair_token
|
|
100
|
+
: await (async () => {
|
|
101
|
+
const { generatePairToken } = await import("./commands/pair-url.js");
|
|
102
|
+
return generatePairToken();
|
|
103
|
+
})());
|
|
104
|
+
const spawnOpts = {
|
|
105
|
+
token,
|
|
106
|
+
};
|
|
107
|
+
if (opts.port !== undefined)
|
|
108
|
+
spawnOpts.port = opts.port;
|
|
109
|
+
if (g.config !== undefined)
|
|
110
|
+
spawnOpts.configDir = g.config;
|
|
111
|
+
await spawnBackgroundBridge(spawnOpts);
|
|
112
|
+
await updateConfig({ pair_token: token }, g.config);
|
|
113
|
+
process.stdout.write(`Bridge spawned in background. Run \`seanpropapp doctor\` to see its status.\n`);
|
|
114
|
+
});
|
|
115
|
+
program
|
|
116
|
+
.command("pair")
|
|
117
|
+
.description("Generate a new pair URL")
|
|
118
|
+
.action(async (_opts, cmd) => {
|
|
119
|
+
const g = getGlobalOpts(cmd);
|
|
120
|
+
const pairOpts = {};
|
|
121
|
+
if (g.config !== undefined)
|
|
122
|
+
pairOpts.configDir = g.config;
|
|
123
|
+
await runPair(pairOpts);
|
|
124
|
+
});
|
|
125
|
+
program
|
|
126
|
+
.command("mcp")
|
|
127
|
+
.description("Run as MCP stdio server (Claude Desktop, Cursor)")
|
|
128
|
+
.action(async (_opts, cmd) => {
|
|
129
|
+
const g = getGlobalOpts(cmd);
|
|
130
|
+
const mcpOpts = {};
|
|
131
|
+
if (g.config !== undefined)
|
|
132
|
+
mcpOpts.configDir = g.config;
|
|
133
|
+
await runMcpCommand(mcpOpts);
|
|
134
|
+
});
|
|
135
|
+
program
|
|
136
|
+
.command("doctor")
|
|
137
|
+
.description("Self-diagnostic")
|
|
138
|
+
.action(async (_opts, cmd) => {
|
|
139
|
+
const g = getGlobalOpts(cmd);
|
|
140
|
+
const dOpts = {};
|
|
141
|
+
if (g.config !== undefined)
|
|
142
|
+
dOpts.configDir = g.config;
|
|
143
|
+
if (g.json)
|
|
144
|
+
dOpts.json = true;
|
|
145
|
+
const res = await runDoctor(dOpts);
|
|
146
|
+
if (!res.ok)
|
|
147
|
+
process.exitCode = 1;
|
|
148
|
+
});
|
|
149
|
+
const autostart = program
|
|
150
|
+
.command("autostart")
|
|
151
|
+
.description("Install OS-native auto-start (macOS LaunchAgent, Linux systemd, Windows Task Scheduler)");
|
|
152
|
+
autostart
|
|
153
|
+
.command("install")
|
|
154
|
+
.description("Install the OS-native supervisor entry")
|
|
155
|
+
.option("--dry-run", "Write the unit/plist but skip launchctl/systemctl", false)
|
|
156
|
+
.action(async (opts) => {
|
|
157
|
+
const installOpts = {};
|
|
158
|
+
if (opts.dryRun)
|
|
159
|
+
installOpts.dryRun = true;
|
|
160
|
+
const res = await installAutostart(installOpts);
|
|
161
|
+
if (!res.ok)
|
|
162
|
+
process.exitCode = 1;
|
|
163
|
+
});
|
|
164
|
+
autostart
|
|
165
|
+
.command("uninstall")
|
|
166
|
+
.description("Remove the OS-native supervisor entry")
|
|
167
|
+
.option("--dry-run", "Delete the unit/plist file but skip launchctl/systemctl", false)
|
|
168
|
+
.action(async (opts) => {
|
|
169
|
+
const unOpts = {};
|
|
170
|
+
if (opts.dryRun)
|
|
171
|
+
unOpts.dryRun = true;
|
|
172
|
+
const res = await uninstallAutostart(unOpts);
|
|
173
|
+
if (!res.ok)
|
|
174
|
+
process.exitCode = 1;
|
|
175
|
+
});
|
|
176
|
+
const telemetry = program
|
|
177
|
+
.command("telemetry")
|
|
178
|
+
.description("Opt-in TTHW telemetry: enable | disable | status");
|
|
179
|
+
telemetry
|
|
180
|
+
.command("enable")
|
|
181
|
+
.description("Opt in. Future connect/pair/first-analysis events will be sent.")
|
|
182
|
+
.action(async (_opts, cmd) => {
|
|
183
|
+
const g = getGlobalOpts(cmd);
|
|
184
|
+
const tOpts = {};
|
|
185
|
+
if (g.config !== undefined)
|
|
186
|
+
tOpts.configDir = g.config;
|
|
187
|
+
if (g.json)
|
|
188
|
+
tOpts.json = true;
|
|
189
|
+
await runTelemetryEnable(tOpts);
|
|
190
|
+
});
|
|
191
|
+
telemetry
|
|
192
|
+
.command("disable")
|
|
193
|
+
.description("Opt out. No events will be sent.")
|
|
194
|
+
.action(async (_opts, cmd) => {
|
|
195
|
+
const g = getGlobalOpts(cmd);
|
|
196
|
+
const tOpts = {};
|
|
197
|
+
if (g.config !== undefined)
|
|
198
|
+
tOpts.configDir = g.config;
|
|
199
|
+
if (g.json)
|
|
200
|
+
tOpts.json = true;
|
|
201
|
+
await runTelemetryDisable(tOpts);
|
|
202
|
+
});
|
|
203
|
+
telemetry
|
|
204
|
+
.command("status")
|
|
205
|
+
.description("Show current opt-in state, correlation id, and target URL.")
|
|
206
|
+
.action(async (_opts, cmd) => {
|
|
207
|
+
const g = getGlobalOpts(cmd);
|
|
208
|
+
const tOpts = {};
|
|
209
|
+
if (g.config !== undefined)
|
|
210
|
+
tOpts.configDir = g.config;
|
|
211
|
+
if (g.json)
|
|
212
|
+
tOpts.json = true;
|
|
213
|
+
await runTelemetryStatus(tOpts);
|
|
214
|
+
});
|
|
215
|
+
program.parseAsync(process.argv).catch((err) => {
|
|
216
|
+
process.stderr.write(`Error: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
217
|
+
process.exit(1);
|
|
218
|
+
});
|
|
219
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SeanPropApp methodology module manifest.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors `packages/mcp-server/src/manifest.ts` in the proposition-app monorepo.
|
|
5
|
+
* Metadata only: zero analytical content lives here. Module prompts are
|
|
6
|
+
* assembled server-side via /api/mcp/assemble-prompt.
|
|
7
|
+
*
|
|
8
|
+
* Keep this list in sync with the upstream registry. Drift between this file
|
|
9
|
+
* and the registry will surface as 400s from /api/mcp/assemble-prompt at runtime.
|
|
10
|
+
*/
|
|
11
|
+
export interface ModuleManifestEntry {
|
|
12
|
+
id: string;
|
|
13
|
+
displayName: string;
|
|
14
|
+
description: string;
|
|
15
|
+
}
|
|
16
|
+
export declare const MODULES: ModuleManifestEntry[];
|