@bd7pil/ocrc 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +34 -0
- package/README.md +330 -0
- package/dist/cli/host-backends.js +216 -0
- package/dist/cli/host-backends.js.map +1 -0
- package/dist/cli/host.js +185 -0
- package/dist/cli/host.js.map +1 -0
- package/dist/cli/index.js +67 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.js +68 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/install.js +220 -0
- package/dist/cli/install.js.map +1 -0
- package/dist/cli/pair.js +11 -0
- package/dist/cli/pair.js.map +1 -0
- package/dist/cli/uninstall.js +75 -0
- package/dist/cli/uninstall.js.map +1 -0
- package/dist/connectivity/auth/cf-access.js +20 -0
- package/dist/connectivity/auth/cf-access.js.map +1 -0
- package/dist/connectivity/auth/index.js +2 -0
- package/dist/connectivity/auth/index.js.map +1 -0
- package/dist/connectivity/auth/select.js +19 -0
- package/dist/connectivity/auth/select.js.map +1 -0
- package/dist/connectivity/auth/token.js +157 -0
- package/dist/connectivity/auth/token.js.map +1 -0
- package/dist/connectivity/exposure/cloudflared.js +77 -0
- package/dist/connectivity/exposure/cloudflared.js.map +1 -0
- package/dist/connectivity/exposure/index.js +2 -0
- package/dist/connectivity/exposure/index.js.map +1 -0
- package/dist/connectivity/exposure/providers.js +49 -0
- package/dist/connectivity/exposure/providers.js.map +1 -0
- package/dist/connectivity/pairing.js +29 -0
- package/dist/connectivity/pairing.js.map +1 -0
- package/dist/core/agent/acp-backend.js +539 -0
- package/dist/core/agent/acp-backend.js.map +1 -0
- package/dist/core/agent/acp-connect.js +92 -0
- package/dist/core/agent/acp-connect.js.map +1 -0
- package/dist/core/agent/acp-normalizer.js +81 -0
- package/dist/core/agent/acp-normalizer.js.map +1 -0
- package/dist/core/agent/acp-replay.js +89 -0
- package/dist/core/agent/acp-replay.js.map +1 -0
- package/dist/core/agent/acp-store.js +129 -0
- package/dist/core/agent/acp-store.js.map +1 -0
- package/dist/core/agent/backend.js +2 -0
- package/dist/core/agent/backend.js.map +1 -0
- package/dist/core/agent/diff-util.js +70 -0
- package/dist/core/agent/diff-util.js.map +1 -0
- package/dist/core/agent/event.js +12 -0
- package/dist/core/agent/event.js.map +1 -0
- package/dist/core/agent/opencode-backend.js +598 -0
- package/dist/core/agent/opencode-backend.js.map +1 -0
- package/dist/core/agent/opencode-normalizer.js +69 -0
- package/dist/core/agent/opencode-normalizer.js.map +1 -0
- package/dist/core/agent/registry.js +55 -0
- package/dist/core/agent/registry.js.map +1 -0
- package/dist/core/agent/v2-backend.js +176 -0
- package/dist/core/agent/v2-backend.js.map +1 -0
- package/dist/core/card-bus.js +74 -0
- package/dist/core/card-bus.js.map +1 -0
- package/dist/core/channels.js +95 -0
- package/dist/core/channels.js.map +1 -0
- package/dist/core/history.js +91 -0
- package/dist/core/history.js.map +1 -0
- package/dist/core/list-files.js +50 -0
- package/dist/core/list-files.js.map +1 -0
- package/dist/core/opencode-events.js +29 -0
- package/dist/core/opencode-events.js.map +1 -0
- package/dist/core/primary-election.js +91 -0
- package/dist/core/primary-election.js.map +1 -0
- package/dist/core/push.js +152 -0
- package/dist/core/push.js.map +1 -0
- package/dist/core/relay.js +400 -0
- package/dist/core/relay.js.map +1 -0
- package/dist/core/scheduler.js +150 -0
- package/dist/core/scheduler.js.map +1 -0
- package/dist/core/state.js +222 -0
- package/dist/core/state.js.map +1 -0
- package/dist/core/stream-accumulator.js +76 -0
- package/dist/core/stream-accumulator.js.map +1 -0
- package/dist/core/structured-card.js +2 -0
- package/dist/core/structured-card.js.map +1 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/opencode/global-events.js +57 -0
- package/dist/opencode/global-events.js.map +1 -0
- package/dist/opencode/list-sessions.js +122 -0
- package/dist/opencode/list-sessions.js.map +1 -0
- package/dist/opencode/submit.js +39 -0
- package/dist/opencode/submit.js.map +1 -0
- package/dist/opencode/workspaces.js +51 -0
- package/dist/opencode/workspaces.js.map +1 -0
- package/dist/plugin/config.js +128 -0
- package/dist/plugin/config.js.map +1 -0
- package/dist/plugin/control-plane.js +133 -0
- package/dist/plugin/control-plane.js.map +1 -0
- package/dist/plugin/entry.js +409 -0
- package/dist/plugin/entry.js.map +1 -0
- package/dist/plugin/v2/event-map.js +193 -0
- package/dist/plugin/v2/event-map.js.map +1 -0
- package/dist/plugin/v2/types.js +15 -0
- package/dist/plugin/v2/types.js.map +1 -0
- package/dist/transport/interface.js +2 -0
- package/dist/transport/interface.js.map +1 -0
- package/dist/transport/telegram/esc.js +9 -0
- package/dist/transport/telegram/esc.js.map +1 -0
- package/dist/transport/telegram/handlers/info-commands.js +101 -0
- package/dist/transport/telegram/handlers/info-commands.js.map +1 -0
- package/dist/transport/telegram/handlers.js +1348 -0
- package/dist/transport/telegram/handlers.js.map +1 -0
- package/dist/transport/telegram/i18n/en.js +538 -0
- package/dist/transport/telegram/i18n/en.js.map +1 -0
- package/dist/transport/telegram/i18n/index.js +83 -0
- package/dist/transport/telegram/i18n/index.js.map +1 -0
- package/dist/transport/telegram/i18n/zh.js +538 -0
- package/dist/transport/telegram/i18n/zh.js.map +1 -0
- package/dist/transport/telegram/index.js +792 -0
- package/dist/transport/telegram/index.js.map +1 -0
- package/dist/transport/telegram/main-keyboard.js +36 -0
- package/dist/transport/telegram/main-keyboard.js.map +1 -0
- package/dist/transport/telegram/managers/abort-suppression-manager.js +33 -0
- package/dist/transport/telegram/managers/abort-suppression-manager.js.map +1 -0
- package/dist/transport/telegram/managers/external-input-suppression-manager.js +51 -0
- package/dist/transport/telegram/managers/external-input-suppression-manager.js.map +1 -0
- package/dist/transport/telegram/managers/interaction-manager.js +254 -0
- package/dist/transport/telegram/managers/interaction-manager.js.map +1 -0
- package/dist/transport/telegram/managers/permission-manager.js +242 -0
- package/dist/transport/telegram/managers/permission-manager.js.map +1 -0
- package/dist/transport/telegram/managers/question-manager.js +191 -0
- package/dist/transport/telegram/managers/question-manager.js.map +1 -0
- package/dist/transport/telegram/managers/rename-manager.js +56 -0
- package/dist/transport/telegram/managers/rename-manager.js.map +1 -0
- package/dist/transport/telegram/menus.js +77 -0
- package/dist/transport/telegram/menus.js.map +1 -0
- package/dist/transport/telegram/permission-flow.js +156 -0
- package/dist/transport/telegram/permission-flow.js.map +1 -0
- package/dist/transport/telegram/question-flow.js +224 -0
- package/dist/transport/telegram/question-flow.js.map +1 -0
- package/dist/transport/telegram/render/block-parser.js +365 -0
- package/dist/transport/telegram/render/block-parser.js.map +1 -0
- package/dist/transport/telegram/render/block-plain-text.js +87 -0
- package/dist/transport/telegram/render/block-plain-text.js.map +1 -0
- package/dist/transport/telegram/render/block-splitter.js +152 -0
- package/dist/transport/telegram/render/block-splitter.js.map +1 -0
- package/dist/transport/telegram/render/chunker.js +71 -0
- package/dist/transport/telegram/render/chunker.js.map +1 -0
- package/dist/transport/telegram/render/limits.js +13 -0
- package/dist/transport/telegram/render/limits.js.map +1 -0
- package/dist/transport/telegram/render/markdown-normalizer.js +102 -0
- package/dist/transport/telegram/render/markdown-normalizer.js.map +1 -0
- package/dist/transport/telegram/render/markdown-to-telegram-v2.js +116 -0
- package/dist/transport/telegram/render/markdown-to-telegram-v2.js.map +1 -0
- package/dist/transport/telegram/render/part-signature.js +14 -0
- package/dist/transport/telegram/render/part-signature.js.map +1 -0
- package/dist/transport/telegram/render/pipeline.js +23 -0
- package/dist/transport/telegram/render/pipeline.js.map +1 -0
- package/dist/transport/telegram/render/rich-blocks.js +311 -0
- package/dist/transport/telegram/render/rich-blocks.js.map +1 -0
- package/dist/transport/telegram/render/text-splitter.js +64 -0
- package/dist/transport/telegram/render/text-splitter.js.map +1 -0
- package/dist/transport/telegram/render/types.js +2 -0
- package/dist/transport/telegram/render/types.js.map +1 -0
- package/dist/transport/telegram/renderer.js +305 -0
- package/dist/transport/telegram/renderer.js.map +1 -0
- package/dist/transport/telegram/streaming/duration-formatter.js +68 -0
- package/dist/transport/telegram/streaming/duration-formatter.js.map +1 -0
- package/dist/transport/telegram/streaming/finalize-assistant-response.js +37 -0
- package/dist/transport/telegram/streaming/finalize-assistant-response.js.map +1 -0
- package/dist/transport/telegram/streaming/response-streamer.js +400 -0
- package/dist/transport/telegram/streaming/response-streamer.js.map +1 -0
- package/dist/transport/telegram/streaming/running-tool-tracker.js +150 -0
- package/dist/transport/telegram/streaming/running-tool-tracker.js.map +1 -0
- package/dist/transport/telegram/streaming/stream-throttle.js +57 -0
- package/dist/transport/telegram/streaming/stream-throttle.js.map +1 -0
- package/dist/transport/telegram/streaming/tool-call-streamer.js +390 -0
- package/dist/transport/telegram/streaming/tool-call-streamer.js.map +1 -0
- package/dist/transport/telegram/streaming-render.js +182 -0
- package/dist/transport/telegram/streaming-render.js.map +1 -0
- package/dist/transport/telegram/types/interaction.js +2 -0
- package/dist/transport/telegram/types/interaction.js.map +1 -0
- package/dist/transport/telegram/types/model.js +25 -0
- package/dist/transport/telegram/types/model.js.map +1 -0
- package/dist/transport/telegram/types/permission.js +2 -0
- package/dist/transport/telegram/types/permission.js.map +1 -0
- package/dist/transport/telegram/types/question.js +2 -0
- package/dist/transport/telegram/types/question.js.map +1 -0
- package/dist/transport/telegram/types/rename.js +2 -0
- package/dist/transport/telegram/types/rename.js.map +1 -0
- package/dist/transport/telegram/types/scheduled-task.js +23 -0
- package/dist/transport/telegram/types/scheduled-task.js.map +1 -0
- package/dist/transport/telegram/types/session.js +2 -0
- package/dist/transport/telegram/types/session.js.map +1 -0
- package/dist/transport/telegram/ui.js +28 -0
- package/dist/transport/telegram/ui.js.map +1 -0
- package/dist/transport/web/index.js +148 -0
- package/dist/transport/web/index.js.map +1 -0
- package/dist/transport/web/middleware/cf-access.js +104 -0
- package/dist/transport/web/middleware/cf-access.js.map +1 -0
- package/dist/transport/web/opencode-config.js +15 -0
- package/dist/transport/web/opencode-config.js.map +1 -0
- package/dist/transport/web/routes/abort.js +12 -0
- package/dist/transport/web/routes/abort.js.map +1 -0
- package/dist/transport/web/routes/approval.js +16 -0
- package/dist/transport/web/routes/approval.js.map +1 -0
- package/dist/transport/web/routes/catalog.js +11 -0
- package/dist/transport/web/routes/catalog.js.map +1 -0
- package/dist/transport/web/routes/channels.js +53 -0
- package/dist/transport/web/routes/channels.js.map +1 -0
- package/dist/transport/web/routes/commands.js +15 -0
- package/dist/transport/web/routes/commands.js.map +1 -0
- package/dist/transport/web/routes/context.js +17 -0
- package/dist/transport/web/routes/context.js.map +1 -0
- package/dist/transport/web/routes/controls.js +34 -0
- package/dist/transport/web/routes/controls.js.map +1 -0
- package/dist/transport/web/routes/create-session.js +21 -0
- package/dist/transport/web/routes/create-session.js.map +1 -0
- package/dist/transport/web/routes/diff.js +7 -0
- package/dist/transport/web/routes/diff.js.map +1 -0
- package/dist/transport/web/routes/files.js +22 -0
- package/dist/transport/web/routes/files.js.map +1 -0
- package/dist/transport/web/routes/logs.js +9 -0
- package/dist/transport/web/routes/logs.js.map +1 -0
- package/dist/transport/web/routes/m8.js +69 -0
- package/dist/transport/web/routes/m8.js.map +1 -0
- package/dist/transport/web/routes/mcp.js +7 -0
- package/dist/transport/web/routes/mcp.js.map +1 -0
- package/dist/transport/web/routes/message.js +32 -0
- package/dist/transport/web/routes/message.js.map +1 -0
- package/dist/transport/web/routes/overrides.js +20 -0
- package/dist/transport/web/routes/overrides.js.map +1 -0
- package/dist/transport/web/routes/question.js +32 -0
- package/dist/transport/web/routes/question.js.map +1 -0
- package/dist/transport/web/routes/rename.js +12 -0
- package/dist/transport/web/routes/rename.js.map +1 -0
- package/dist/transport/web/routes/schedules.js +28 -0
- package/dist/transport/web/routes/schedules.js.map +1 -0
- package/dist/transport/web/routes/session.js +20 -0
- package/dist/transport/web/routes/session.js.map +1 -0
- package/dist/transport/web/routes/sessions.js +25 -0
- package/dist/transport/web/routes/sessions.js.map +1 -0
- package/dist/transport/web/routes/subagents.js +11 -0
- package/dist/transport/web/routes/subagents.js.map +1 -0
- package/dist/transport/web/routes/suggestions.js +7 -0
- package/dist/transport/web/routes/suggestions.js.map +1 -0
- package/dist/transport/web/routes/todo.js +7 -0
- package/dist/transport/web/routes/todo.js.map +1 -0
- package/dist/transport/web/routes/version.js +5 -0
- package/dist/transport/web/routes/version.js.map +1 -0
- package/dist/transport/web/routes/workspaces.js +7 -0
- package/dist/transport/web/routes/workspaces.js.map +1 -0
- package/dist/transport/web/server.js +111 -0
- package/dist/transport/web/server.js.map +1 -0
- package/dist/transport/web/session-summary.js +46 -0
- package/dist/transport/web/session-summary.js.map +1 -0
- package/dist/transport/web/ws-hub.js +83 -0
- package/dist/transport/web/ws-hub.js.map +1 -0
- package/dist/utils/logger.js +105 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/markdown.js +129 -0
- package/dist/utils/markdown.js.map +1 -0
- package/dist/utils/paths.js +18 -0
- package/dist/utils/paths.js.map +1 -0
- package/dist/utils/version.js +44 -0
- package/dist/utils/version.js.map +1 -0
- package/package.json +91 -0
- package/web/dist/_app/env.js +1 -0
- package/web/dist/_app/immutable/assets/0.DxN3RsuG.css +1 -0
- package/web/dist/_app/immutable/assets/2.BNuGfmZP.css +1 -0
- package/web/dist/_app/immutable/assets/3.CTDprntu.css +1 -0
- package/web/dist/_app/immutable/chunks/BUpwHpMJ.js +1 -0
- package/web/dist/_app/immutable/chunks/BjY4dxcB.js +2 -0
- package/web/dist/_app/immutable/chunks/C2FuqD3s.js +1 -0
- package/web/dist/_app/immutable/chunks/CUHGq08X.js +2 -0
- package/web/dist/_app/immutable/chunks/CWj6FrbW.js +1 -0
- package/web/dist/_app/immutable/chunks/ClvoqtGj.js +1 -0
- package/web/dist/_app/immutable/chunks/DIEDQ_hk.js +1 -0
- package/web/dist/_app/immutable/entry/app.BoRpcVMj.js +2 -0
- package/web/dist/_app/immutable/entry/start.Cj-PQNTq.js +1 -0
- package/web/dist/_app/immutable/nodes/0.y9YEms5p.js +3 -0
- package/web/dist/_app/immutable/nodes/1.CPhhiRM2.js +1 -0
- package/web/dist/_app/immutable/nodes/2.B_c84Mc9.js +1 -0
- package/web/dist/_app/immutable/nodes/3.ClTd0J3D.js +64 -0
- package/web/dist/_app/version.json +1 -0
- package/web/dist/apple-touch-icon.png +0 -0
- package/web/dist/favicon.png +0 -0
- package/web/dist/favicon.svg +17 -0
- package/web/dist/icon-192.png +0 -0
- package/web/dist/icon-512-maskable.png +0 -0
- package/web/dist/icon-512.png +0 -0
- package/web/dist/index.html +73 -0
- package/web/dist/manifest.webmanifest +28 -0
- package/web/dist/service-worker.js +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"question.js","sourceRoot":"","sources":["../../../../src/transport/telegram/types/question.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rename.js","sourceRoot":"","sources":["../../../../src/transport/telegram/types/rename.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export const DEFAULT_TASK_AGENT = "build";
|
|
2
|
+
export function createScheduledTaskModel(model) {
|
|
3
|
+
return {
|
|
4
|
+
providerID: model.providerID,
|
|
5
|
+
modelID: model.modelID,
|
|
6
|
+
variant: model.variant ?? null,
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
export function cloneParsedTaskSchedule(schedule) {
|
|
10
|
+
return { ...schedule };
|
|
11
|
+
}
|
|
12
|
+
export function cloneScheduledTaskModel(model) {
|
|
13
|
+
return { ...model };
|
|
14
|
+
}
|
|
15
|
+
export function cloneScheduledTask(task) {
|
|
16
|
+
return {
|
|
17
|
+
...task,
|
|
18
|
+
// Backfill for tasks persisted before the agent field existed (they ran with "build").
|
|
19
|
+
agent: task.agent ?? DEFAULT_TASK_AGENT,
|
|
20
|
+
model: cloneScheduledTaskModel(task.model),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=scheduled-task.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduled-task.js","sourceRoot":"","sources":["../../../../src/transport/telegram/types/scheduled-task.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,kBAAkB,GAAG,OAAO,CAAC;AAuE1C,MAAM,UAAU,wBAAwB,CAAC,KAAgB;IACvD,OAAO;QACL,UAAU,EAAE,KAAK,CAAC,UAAU;QAC5B,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,IAAI;KAC/B,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,QAA4B;IAClE,OAAO,EAAE,GAAG,QAAQ,EAAE,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,KAAyB;IAC/D,OAAO,EAAE,GAAG,KAAK,EAAE,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAmB;IACpD,OAAO;QACL,GAAG,IAAI;QACP,uFAAuF;QACvF,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,kBAAkB;QACvC,KAAK,EAAE,uBAAuB,CAAC,IAAI,CAAC,KAAK,CAAC;KAC3C,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../../../src/transport/telegram/types/session.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// Minimal Telegram-UI and error helpers shared by the grammY transport.
|
|
2
|
+
// These preserve the old Markup call-shapes (spread-friendly {reply_markup})
|
|
3
|
+
// so call sites stay a mechanical find/replace, and read both grammY's
|
|
4
|
+
// top-level error fields and the legacy response-envelope shape.
|
|
5
|
+
import { InlineKeyboard } from 'grammy';
|
|
6
|
+
export const btn = (text, callback_data) => ({ text, callback_data });
|
|
7
|
+
/** Build an InlineKeyboard from row arrays; returns {reply_markup} for spreading into reply opts. */
|
|
8
|
+
export function inlineKeyboard(rows) {
|
|
9
|
+
let kb = new InlineKeyboard();
|
|
10
|
+
rows.forEach((row, i) => {
|
|
11
|
+
for (const b of row)
|
|
12
|
+
kb = kb.text(b.text, b.callback_data);
|
|
13
|
+
if (i < rows.length - 1)
|
|
14
|
+
kb = kb.row();
|
|
15
|
+
});
|
|
16
|
+
return { reply_markup: kb };
|
|
17
|
+
}
|
|
18
|
+
/** Telegram API error code — grammY raises GrammyError with a top-level code. */
|
|
19
|
+
export function errorCodeOf(e) {
|
|
20
|
+
const anyE = e;
|
|
21
|
+
return anyE?.error_code ?? anyE?.response?.error_code;
|
|
22
|
+
}
|
|
23
|
+
/** retry_after from a 429 — grammY exposes it on the error's parameters. */
|
|
24
|
+
export function retryAfterOf(e) {
|
|
25
|
+
const anyE = e;
|
|
26
|
+
return anyE?.parameters?.retry_after ?? anyE?.response?.parameters?.retry_after;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=ui.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui.js","sourceRoot":"","sources":["../../../src/transport/telegram/ui.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,6EAA6E;AAC7E,uEAAuE;AACvE,iEAAiE;AAEjE,OAAO,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAA;AAOvC,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,IAAY,EAAE,aAAqB,EAAS,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAA;AAE5F,qGAAqG;AACrG,MAAM,UAAU,cAAc,CAAC,IAAe;IAC5C,IAAI,EAAE,GAAG,IAAI,cAAc,EAAE,CAAA;IAC7B,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;QACtB,KAAK,MAAM,CAAC,IAAI,GAAG;YAAE,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,aAAa,CAAC,CAAA;QAC1D,IAAI,CAAC,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC;YAAE,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,CAAA;IACxC,CAAC,CAAC,CAAA;IACF,OAAO,EAAE,YAAY,EAAE,EAAE,EAAE,CAAA;AAC7B,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,WAAW,CAAC,CAAU;IACpC,MAAM,IAAI,GAAG,CAAQ,CAAA;IACrB,OAAO,IAAI,EAAE,UAAU,IAAI,IAAI,EAAE,QAAQ,EAAE,UAAU,CAAA;AACvD,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,YAAY,CAAC,CAAU;IACrC,MAAM,IAAI,GAAG,CAAQ,CAAA;IACrB,OAAO,IAAI,EAAE,UAAU,EAAE,WAAW,IAAI,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,CAAA;AACjF,CAAC"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { serve } from '@hono/node-server';
|
|
4
|
+
import { WebSocketServer } from 'ws';
|
|
5
|
+
import { serveStatic } from '@hono/node-server/serve-static';
|
|
6
|
+
import { buildServer } from './server.js';
|
|
7
|
+
import { createWsHub } from './ws-hub.js';
|
|
8
|
+
import { createLogger } from '../../utils/logger.js';
|
|
9
|
+
const log = createLogger('web');
|
|
10
|
+
const CAPS = {
|
|
11
|
+
edit: true, maxMessageLength: Number.POSITIVE_INFINITY,
|
|
12
|
+
buttons: true, richText: true, streaming: true,
|
|
13
|
+
};
|
|
14
|
+
export function createWebTransport(cfg) {
|
|
15
|
+
let messageHandler;
|
|
16
|
+
let server;
|
|
17
|
+
let wss;
|
|
18
|
+
return {
|
|
19
|
+
name: 'web',
|
|
20
|
+
capabilities: CAPS,
|
|
21
|
+
async start(deps) {
|
|
22
|
+
if (!existsSync(cfg.staticRoot)) {
|
|
23
|
+
throw new Error(`Web static root not found: ${cfg.staticRoot}. Run 'cd web && npm run build' first.`);
|
|
24
|
+
}
|
|
25
|
+
const wsHub = createWsHub({ cardBus: deps.cardBus, registry: cfg.registry, state: deps.state });
|
|
26
|
+
const app = buildServer({
|
|
27
|
+
auth: cfg.auth,
|
|
28
|
+
registry: cfg.registry,
|
|
29
|
+
state: deps.state,
|
|
30
|
+
cardBus: deps.cardBus,
|
|
31
|
+
onMessage: (msg) => messageHandler ? messageHandler(msg) : Promise.resolve(),
|
|
32
|
+
scheduler: cfg.scheduler,
|
|
33
|
+
channels: cfg.channels,
|
|
34
|
+
telegramStatus: cfg.telegramStatus,
|
|
35
|
+
});
|
|
36
|
+
// Immutable hashed assets cache forever; everything else (above all
|
|
37
|
+
// index.html, which references those hashes) must revalidate on every
|
|
38
|
+
// load — a cached stale index points at deleted hashes and the app
|
|
39
|
+
// half-loads after any redeploy ("every refresh looks different").
|
|
40
|
+
app.use('/_app/immutable/*', async (c, next) => {
|
|
41
|
+
await next();
|
|
42
|
+
c.header('Cache-Control', 'public, max-age=31536000, immutable');
|
|
43
|
+
});
|
|
44
|
+
// index.html — served BOTH as the static file ('/') and by the SPA
|
|
45
|
+
// fallback below — must always revalidate.
|
|
46
|
+
app.use(async (c, next) => {
|
|
47
|
+
await next();
|
|
48
|
+
if (c.req.path === '/' || c.req.path === '/index.html') {
|
|
49
|
+
c.header('Cache-Control', 'no-cache');
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
app.use('/*', serveStatic({ root: cfg.staticRoot }));
|
|
53
|
+
// SPA fallback — SvelteKit static adapter only prerenders index.html;
|
|
54
|
+
// dynamic routes like /[sessionId]/ resolve client-side, so any non-API
|
|
55
|
+
// path that doesn't match a real file must serve index.html.
|
|
56
|
+
// Critical: ONLY fall back navigation-style paths. If a missing asset
|
|
57
|
+
// (e.g. stale /_app/old-hash.js a cached browser still asks for) gets
|
|
58
|
+
// index.html, the browser sees text/html where it expects JS and the
|
|
59
|
+
// whole module graph silently stalls.
|
|
60
|
+
const indexHtmlPath = join(cfg.staticRoot, 'index.html');
|
|
61
|
+
// Read once at startup — the previous per-request readFileSync put a
|
|
62
|
+
// synchronous disk hit on every unmatched GET.
|
|
63
|
+
const indexHtml = readFileSync(indexHtmlPath, 'utf-8');
|
|
64
|
+
app.get('*', (c) => {
|
|
65
|
+
const path = c.req.path;
|
|
66
|
+
if (path.startsWith('/api/') || path === '/ws')
|
|
67
|
+
return c.notFound();
|
|
68
|
+
return c.html(indexHtml);
|
|
69
|
+
});
|
|
70
|
+
// serve() returns immediately and bind errors (EADDRINUSE, EACCES) only
|
|
71
|
+
// surface as an async 'error' event. Await the listening callback so a
|
|
72
|
+
// failed bind REJECTS start() — the entrypoint's transport retry loop
|
|
73
|
+
// (1s→30s backoff) then actually recovers, e.g. when the port is held by
|
|
74
|
+
// a still-shutting-down predecessor. Without this, the error used to end
|
|
75
|
+
// up an uncaughtException that installProcessGuards() swallows, leaving
|
|
76
|
+
// the transport "started" but silently unbound.
|
|
77
|
+
server = await new Promise((resolveBind, rejectBind) => {
|
|
78
|
+
const s = serve({ fetch: app.fetch, hostname: cfg.host, port: cfg.port }, (info) => {
|
|
79
|
+
log.info(`web transport listening on http://${info.address}:${info.port}`);
|
|
80
|
+
resolveBind(s);
|
|
81
|
+
});
|
|
82
|
+
s.once('error', rejectBind);
|
|
83
|
+
});
|
|
84
|
+
server.on('error', (err) => {
|
|
85
|
+
log.error(`web transport error after bind: ${err.message}`);
|
|
86
|
+
setImmediate(() => { throw err; });
|
|
87
|
+
});
|
|
88
|
+
// Clients only ever send ping/subscribe — cap frames well below the 100MiB
|
|
89
|
+
// default so a rogue client can't exhaust memory.
|
|
90
|
+
wss = new WebSocketServer({ noServer: true, maxPayload: 64 * 1024 });
|
|
91
|
+
server.on('upgrade', async (req, socket, head) => {
|
|
92
|
+
const hasCookie = !!req.headers?.cookie;
|
|
93
|
+
const hasAccessHdr = !!req.headers?.['cf-access-jwt-assertion'];
|
|
94
|
+
const reqUrl = new URL(req.url, 'http://localhost');
|
|
95
|
+
log.info(`ws upgrade attempt path=${reqUrl.pathname} cookie=${hasCookie} cf-access-hdr=${hasAccessHdr}`);
|
|
96
|
+
if (reqUrl.pathname !== '/ws') {
|
|
97
|
+
log.info(`ws upgrade rejected: wrong path=${reqUrl.pathname}`);
|
|
98
|
+
socket.destroy();
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
// Auth: delegate to the configured strategy (token or CF Access). A throw
|
|
102
|
+
// here would otherwise hang the TCP socket and raise unhandledRejection.
|
|
103
|
+
let user;
|
|
104
|
+
try {
|
|
105
|
+
user = await cfg.auth.verifyUpgrade({ headers: req.headers, url: req.url, socket: req.socket });
|
|
106
|
+
}
|
|
107
|
+
catch (e) {
|
|
108
|
+
log.warn(`ws upgrade rejected: verifyUpgrade threw: ${e.message}`);
|
|
109
|
+
socket.destroy();
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (!user) {
|
|
113
|
+
log.warn(`ws upgrade rejected: JWT verify failed (cookie=${hasCookie} cf-access-hdr=${hasAccessHdr})`);
|
|
114
|
+
socket.destroy();
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const wsUser = { email: user.email ?? user.sub ?? 'user' };
|
|
118
|
+
log.info(`ws upgrade accepted: ${wsUser.email}`);
|
|
119
|
+
wss.handleUpgrade(req, socket, head, (ws) => {
|
|
120
|
+
log.info(`ws handleUpgrade callback fired, attaching`);
|
|
121
|
+
wsHub.attach(ws, wsUser);
|
|
122
|
+
ws.on('message', (data) => {
|
|
123
|
+
try {
|
|
124
|
+
wsHub.handleClientMessage(ws, JSON.parse(data.toString()));
|
|
125
|
+
}
|
|
126
|
+
catch { }
|
|
127
|
+
});
|
|
128
|
+
ws.on('close', (code, reason) => {
|
|
129
|
+
log.info(`ws closed code=${code} reason="${reason.toString()}"`);
|
|
130
|
+
wsHub.detach(ws);
|
|
131
|
+
});
|
|
132
|
+
ws.on('error', (err) => log.warn(`ws error: ${err.message}`));
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
},
|
|
136
|
+
async stop() {
|
|
137
|
+
wss?.close();
|
|
138
|
+
server?.close();
|
|
139
|
+
},
|
|
140
|
+
async send(_chatId, _card) {
|
|
141
|
+
throw new Error('Transport.send not implemented for Web in v0.5.0 (use cardBus.publish)');
|
|
142
|
+
},
|
|
143
|
+
onMessage(h) { messageHandler = h; },
|
|
144
|
+
onCommand() { },
|
|
145
|
+
onButtonClick() { },
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/transport/web/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { createRemoteJWKSet, jwtVerify } from 'jose';
|
|
2
|
+
function isLoopbackAddr(addr) {
|
|
3
|
+
if (!addr)
|
|
4
|
+
return false;
|
|
5
|
+
// Strip IPv6 prefix
|
|
6
|
+
const clean = addr.replace(/^::ffff:/, '').split('%')[0];
|
|
7
|
+
return clean === '127.0.0.1' || clean === '::1';
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Whether dev bypass should grant access for this request.
|
|
11
|
+
*
|
|
12
|
+
* When the real peer address is known, ONLY a loopback peer qualifies — a
|
|
13
|
+
* remote peer must never be bypassed just because the server binds to loopback,
|
|
14
|
+
* otherwise host-header spoofing behind a tunnel (peer is 127.0.0.1 but the
|
|
15
|
+
* real client is remote) would defeat CF Access. Only when the peer address is
|
|
16
|
+
* unavailable (Bun/Nitropack, where raw socket info isn't exposed) do we fall
|
|
17
|
+
* back to opts.host.
|
|
18
|
+
*
|
|
19
|
+
* WARNING: with devBypass on, a same-host cloudflared/quick-tunnel makes ALL
|
|
20
|
+
* remote traffic arrive from 127.0.0.1 — every request looks loopback and auth
|
|
21
|
+
* is silently wide open. Never combine devBypass with a tunnel; a startup
|
|
22
|
+
* warning is logged when devBypass is enabled (see createCfAccessAuth).
|
|
23
|
+
*/
|
|
24
|
+
function devBypassAllowed(peer, opts) {
|
|
25
|
+
if (!opts.devBypass)
|
|
26
|
+
return false;
|
|
27
|
+
const peerKnown = peer !== undefined && peer !== '';
|
|
28
|
+
return peerKnown ? isLoopbackAddr(peer) : isLoopbackAddr(opts.host);
|
|
29
|
+
}
|
|
30
|
+
function remoteAddr(c) {
|
|
31
|
+
try {
|
|
32
|
+
// Hono on Node.js / Bun: use raw request socket
|
|
33
|
+
const raw = c.env?.incoming ?? c.req?.raw;
|
|
34
|
+
return raw?.socket?.remoteAddress;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function extractJwt(headers, query) {
|
|
41
|
+
const header = headers['cf-access-jwt-assertion'];
|
|
42
|
+
if (typeof header === 'string')
|
|
43
|
+
return header;
|
|
44
|
+
if (query) {
|
|
45
|
+
const q = new URLSearchParams(query);
|
|
46
|
+
const j = q.get('cf_access_jwt');
|
|
47
|
+
if (j)
|
|
48
|
+
return j;
|
|
49
|
+
}
|
|
50
|
+
const cookie = headers['cookie'];
|
|
51
|
+
if (typeof cookie === 'string') {
|
|
52
|
+
const m = cookie.match(/CF_Authorization=([^;]+)/);
|
|
53
|
+
if (m)
|
|
54
|
+
return m[1];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
export async function verifyUpgradeJwt(req, opts, jwks) {
|
|
58
|
+
if (devBypassAllowed(req.socket?.remoteAddress, opts)) {
|
|
59
|
+
return { email: opts.devEmail ?? 'dev@localhost', sub: 'dev' };
|
|
60
|
+
}
|
|
61
|
+
const query = req.url?.startsWith('/ws') ? req.url.split('?')[1] : undefined;
|
|
62
|
+
const jwt = extractJwt(req.headers, query);
|
|
63
|
+
if (!jwt)
|
|
64
|
+
return null;
|
|
65
|
+
try {
|
|
66
|
+
const keys = jwks ?? createRemoteJWKSet(new URL(`https://${opts.team}.cloudflareaccess.com/cdn-cgi/access/certs`));
|
|
67
|
+
const { payload } = await jwtVerify(jwt, keys, {
|
|
68
|
+
issuer: `https://${opts.team}.cloudflareaccess.com`,
|
|
69
|
+
audience: opts.aud,
|
|
70
|
+
});
|
|
71
|
+
return { email: payload.email, sub: payload.sub };
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
export function cfAccessMiddleware(opts) {
|
|
78
|
+
const jwksUri = `https://${opts.team}.cloudflareaccess.com/cdn-cgi/access/certs`;
|
|
79
|
+
const issuer = `https://${opts.team}.cloudflareaccess.com`;
|
|
80
|
+
const jwks = createRemoteJWKSet(new URL(jwksUri));
|
|
81
|
+
return async (c, next) => {
|
|
82
|
+
if (devBypassAllowed(remoteAddr(c), opts)) {
|
|
83
|
+
c.set('user', { email: opts.devEmail ?? 'dev@localhost', sub: 'dev' });
|
|
84
|
+
return next();
|
|
85
|
+
}
|
|
86
|
+
// No query-string JWT here: ?cf_access_jwt= on a normal HTTP URL would leak
|
|
87
|
+
// into browser history/referer. It is accepted only on the WS upgrade path
|
|
88
|
+
// (/ws) — see verifyUpgradeJwt — because browsers can't set WS headers.
|
|
89
|
+
const jwt = c.req.header('cf-access-jwt-assertion') ||
|
|
90
|
+
c.req.header('cookie')?.match(/CF_Authorization=([^;]+)/)?.[1];
|
|
91
|
+
if (!jwt) {
|
|
92
|
+
return c.json({ error: 'Unauthorized' }, 401);
|
|
93
|
+
}
|
|
94
|
+
try {
|
|
95
|
+
const { payload } = await jwtVerify(jwt, jwks, { issuer, audience: opts.aud });
|
|
96
|
+
c.set('user', { email: payload.email, sub: payload.sub });
|
|
97
|
+
return next();
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
return c.json({ error: 'Unauthorized' }, 401);
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=cf-access.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cf-access.js","sourceRoot":"","sources":["../../../../src/transport/web/middleware/cf-access.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,MAAM,CAAA;AAYpD,SAAS,cAAc,CAAC,IAAa;IACnC,IAAI,CAAC,IAAI;QAAE,OAAO,KAAK,CAAA;IACvB,oBAAoB;IACpB,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;IACxD,OAAO,KAAK,KAAK,WAAW,IAAI,KAAK,KAAK,KAAK,CAAA;AACjD,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,SAAS,gBAAgB,CAAC,IAAwB,EAAE,IAAkB;IACpE,IAAI,CAAC,IAAI,CAAC,SAAS;QAAE,OAAO,KAAK,CAAA;IACjC,MAAM,SAAS,GAAG,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,EAAE,CAAA;IACnD,OAAO,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACrE,CAAC;AAED,SAAS,UAAU,CAAC,CAAM;IACxB,IAAI,CAAC;QACH,gDAAgD;QAChD,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,EAAE,QAAQ,IAAI,CAAC,CAAC,GAAG,EAAE,GAAG,CAAA;QACzC,OAAO,GAAG,EAAE,MAAM,EAAE,aAAmC,CAAA;IACzD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAA;IAClB,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,OAAsD,EAAE,KAAc;IACxF,MAAM,MAAM,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAA;IACjD,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,MAAM,CAAA;IAC7C,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,CAAC,GAAG,IAAI,eAAe,CAAC,KAAK,CAAC,CAAA;QACpC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,eAAe,CAAC,CAAA;QAChC,IAAI,CAAC;YAAE,OAAO,CAAC,CAAA;IACjB,CAAC;IACD,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAA;IAChC,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAA;QAClD,IAAI,CAAC;YAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAA;IACpB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,GAAkH,EAClH,IAAkB,EAClB,IAA4C;IAE5C,IAAI,gBAAgB,CAAC,GAAG,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,CAAC,EAAE,CAAC;QACtD,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,IAAI,eAAe,EAAE,GAAG,EAAE,KAAK,EAAE,CAAA;IAChE,CAAC;IACD,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IAC5E,MAAM,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;IAC1C,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAA;IACrB,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,IAAI,kBAAkB,CAAC,IAAI,GAAG,CAAC,WAAW,IAAI,CAAC,IAAI,4CAA4C,CAAC,CAAC,CAAA;QAClH,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE;YAC7C,MAAM,EAAE,WAAW,IAAI,CAAC,IAAI,uBAAuB;YACnD,QAAQ,EAAE,IAAI,CAAC,GAAG;SACnB,CAAC,CAAA;QACF,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,KAAe,EAAE,GAAG,EAAE,OAAO,CAAC,GAAa,EAAE,CAAA;IACvE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAkB;IACnD,MAAM,OAAO,GAAG,WAAW,IAAI,CAAC,IAAI,4CAA4C,CAAA;IAChF,MAAM,MAAM,GAAG,WAAW,IAAI,CAAC,IAAI,uBAAuB,CAAA;IAC1D,MAAM,IAAI,GAAG,kBAAkB,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAA;IAEjD,OAAO,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;QACvB,IAAI,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC;YAC1C,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,IAAI,eAAe,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAA;YACtE,OAAO,IAAI,EAAE,CAAA;QACf,CAAC;QAED,4EAA4E;QAC5E,2EAA2E;QAC3E,wEAAwE;QACxE,MAAM,GAAG,GACP,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,yBAAyB,CAAC;YACvC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,0BAA0B,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QAEhE,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,GAAG,CAAC,CAAA;QAC/C,CAAC;QAED,IAAI,CAAC;YACH,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;YAC9E,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,KAAe,EAAE,GAAG,EAAE,OAAO,CAAC,GAAa,EAAE,CAAC,CAAA;YAC7E,OAAO,IAAI,EAAE,CAAA;QACf,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,GAAG,CAAC,CAAA;QAC/C,CAAC;IACH,CAAC,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** Best-effort GET of an opencode raw-config endpoint. Returns {} on any failure. */
|
|
2
|
+
export async function fetchOpencodeConfig(baseUrl, path) {
|
|
3
|
+
if (!baseUrl)
|
|
4
|
+
return {};
|
|
5
|
+
try {
|
|
6
|
+
const res = await fetch(`${baseUrl.replace(/\/+$/, '')}${path}`, { signal: AbortSignal.timeout(5000) });
|
|
7
|
+
if (!res.ok)
|
|
8
|
+
return {};
|
|
9
|
+
return await res.json();
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
return {};
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=opencode-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencode-config.js","sourceRoot":"","sources":["../../../src/transport/web/opencode-config.ts"],"names":[],"mappings":"AAAA,qFAAqF;AACrF,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAAe,EAAE,IAAY;IACrE,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,CAAA;IACvB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACvG,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,EAAE,CAAA;QACtB,OAAO,MAAM,GAAG,CAAC,IAAI,EAAE,CAAA;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAA;IACX,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function registerAbort(app, reg, state) {
|
|
2
|
+
app.post('/api/abort', async (c) => {
|
|
3
|
+
const body = await c.req.json().catch(() => ({}));
|
|
4
|
+
if (typeof body.sessionId !== 'string' || !body.sessionId)
|
|
5
|
+
return c.json({ error: 'sessionId required' }, 400);
|
|
6
|
+
const id = state.normalizeSessionId(body.sessionId);
|
|
7
|
+
state.getActiveAbort(id)?.abort();
|
|
8
|
+
await reg.forSession(id).abort(id);
|
|
9
|
+
return c.json({ ok: true });
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=abort.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"abort.js","sourceRoot":"","sources":["../../../../src/transport/web/routes/abort.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,aAAa,CAAC,GAAS,EAAE,GAAoB,EAAE,KAAmB;IAChF,GAAG,CAAC,IAAI,CAAC,YAAY,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACjC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAA2B,CAAA;QAC3E,IAAI,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,EAAE,GAAG,CAAC,CAAA;QAC9G,MAAM,EAAE,GAAG,KAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QACnD,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAA;QACjC,MAAM,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QAClC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;IAC7B,CAAC,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const DECISIONS = ['once', 'always', 'reject'];
|
|
2
|
+
export function registerApproval(app, reg, state) {
|
|
3
|
+
app.post('/api/approval', async (c) => {
|
|
4
|
+
const body = await c.req.json().catch(() => ({}));
|
|
5
|
+
if (typeof body.sessionId !== 'string' || !body.sessionId)
|
|
6
|
+
return c.json({ error: 'sessionId required' }, 400);
|
|
7
|
+
if (typeof body.requestId !== 'string' || !body.requestId)
|
|
8
|
+
return c.json({ error: 'requestId required' }, 400);
|
|
9
|
+
if (!DECISIONS.includes(body.decision))
|
|
10
|
+
return c.json({ error: 'decision must be once|always|reject' }, 400);
|
|
11
|
+
const id = state.normalizeSessionId(body.sessionId);
|
|
12
|
+
await reg.forSession(id).resolvePermission(id, body.requestId, body.decision);
|
|
13
|
+
return c.json({ ok: true });
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=approval.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approval.js","sourceRoot":"","sources":["../../../../src/transport/web/routes/approval.ts"],"names":[],"mappings":"AAKA,MAAM,SAAS,GAAyB,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAA;AAEpE,MAAM,UAAU,gBAAgB,CAAC,GAAS,EAAE,GAAoB,EAAE,KAAmB;IACnF,GAAG,CAAC,IAAI,CAAC,eAAe,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACpC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAA8E,CAAA;QAC9H,IAAI,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,EAAE,GAAG,CAAC,CAAA;QAC9G,IAAI,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,EAAE,GAAG,CAAC,CAAA;QAC9G,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,QAA8B,CAAC;YAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,qCAAqC,EAAE,EAAE,GAAG,CAAC,CAAA;QAClI,MAAM,EAAE,GAAG,KAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QACnD,MAAM,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,iBAAiB,CAAC,EAAE,EAAE,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,QAA8B,CAAC,CAAA;QACnG,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;IAC7B,CAAC,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export function registerCatalog(app, reg) {
|
|
2
|
+
app.get('/api/agents', async (c) => {
|
|
3
|
+
const b = reg.get(c.req.query('backend') ?? '') ?? reg.active();
|
|
4
|
+
return c.json(await b.getAgents());
|
|
5
|
+
});
|
|
6
|
+
app.get('/api/models', async (c) => {
|
|
7
|
+
const b = reg.get(c.req.query('backend') ?? '') ?? reg.active();
|
|
8
|
+
return c.json(await b.getModels());
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=catalog.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../../../src/transport/web/routes/catalog.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,eAAe,CAAC,GAAS,EAAE,GAAoB;IAC7D,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACjC,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,IAAI,GAAG,CAAC,MAAM,EAAE,CAAA;QAC/D,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,CAAC,CAAA;IACpC,CAAC,CAAC,CAAA;IACF,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACjC,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,IAAI,GAAG,CAAC,MAAM,EAAE,CAAA;QAC/D,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,SAAS,EAAE,CAAC,CAAA;IACpC,CAAC,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* M9: bot-channel settings — list + update. `tgStatus` (injected by entry)
|
|
3
|
+
* reports the live Telegram polling state so the web panel can show
|
|
4
|
+
* connected/未绑定 like the ZCode reference.
|
|
5
|
+
*/
|
|
6
|
+
export function registerChannels(app, channels, tgStatus) {
|
|
7
|
+
if (!channels)
|
|
8
|
+
return;
|
|
9
|
+
app.get('/api/channels', (c) => {
|
|
10
|
+
const status = tgStatus?.() ?? null;
|
|
11
|
+
return c.json({
|
|
12
|
+
channels: channels.list().map((b) => ({
|
|
13
|
+
...b,
|
|
14
|
+
live: b.channel === 'telegram' && status ? { connected: status.connected, username: status.username } : null,
|
|
15
|
+
})),
|
|
16
|
+
});
|
|
17
|
+
});
|
|
18
|
+
app.patch('/api/channels/:id', async (c) => {
|
|
19
|
+
const body = (await c.req.json().catch(() => ({})));
|
|
20
|
+
if (body.replyGranularity && body.replyGranularity !== 'standard' && body.replyGranularity !== 'detailed') {
|
|
21
|
+
return c.json({ error: 'replyGranularity must be standard|detailed' }, 400);
|
|
22
|
+
}
|
|
23
|
+
if (body.workspaces && body.workspaces.mode !== 'all' && body.workspaces.mode !== 'custom') {
|
|
24
|
+
return c.json({ error: 'invalid workspaces' }, 400);
|
|
25
|
+
}
|
|
26
|
+
const updated = channels.update(c.req.param('id'), body);
|
|
27
|
+
if (!updated)
|
|
28
|
+
return c.json({ error: 'not found' }, 404);
|
|
29
|
+
return c.json({ channel: updated });
|
|
30
|
+
});
|
|
31
|
+
app.post('/api/channels/:id/reset', (c) => {
|
|
32
|
+
const updated = channels.reset(c.req.param('id'));
|
|
33
|
+
if (!updated)
|
|
34
|
+
return c.json({ error: 'not found' }, 404);
|
|
35
|
+
return c.json({ channel: updated });
|
|
36
|
+
});
|
|
37
|
+
// Pairing QR — the pair URL carries the token in its fragment, so this is
|
|
38
|
+
// only ever rendered inside an already-paired session (same trust model as
|
|
39
|
+
// TG's /pair command).
|
|
40
|
+
app.get('/api/pair/qr', async (c) => {
|
|
41
|
+
try {
|
|
42
|
+
const { buildPairContext } = await import('../../../connectivity/pairing.js');
|
|
43
|
+
const QRCode = (await import('qrcode')).default;
|
|
44
|
+
const { token, url } = await buildPairContext();
|
|
45
|
+
const svg = await QRCode.toString(url, { type: 'svg', margin: 1 });
|
|
46
|
+
return c.json({ url, svg });
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
return c.json({ error: err.message }, 500);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=channels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"channels.js","sourceRoot":"","sources":["../../../../src/transport/web/routes/channels.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export function registerCommands(app, reg, state) {
|
|
2
|
+
app.get('/api/commands', async (c) => {
|
|
3
|
+
const b = reg.get(c.req.query('backend') ?? '') ?? reg.active();
|
|
4
|
+
return c.json(await b.listCommands());
|
|
5
|
+
});
|
|
6
|
+
app.post('/api/command', async (c) => {
|
|
7
|
+
const body = await c.req.json().catch(() => ({}));
|
|
8
|
+
if (!body.sessionId || !body.command)
|
|
9
|
+
return c.json({ error: 'sessionId and command required' }, 400);
|
|
10
|
+
const id = state.normalizeSessionId(body.sessionId);
|
|
11
|
+
await reg.forSession(id).runCommand(id, body.command, body.arguments);
|
|
12
|
+
return c.json({ ok: true });
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../../../../src/transport/web/routes/commands.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,gBAAgB,CAAC,GAAS,EAAE,GAAoB,EAAE,KAAmB;IACnF,GAAG,CAAC,GAAG,CAAC,eAAe,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACnC,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,IAAI,GAAG,CAAC,MAAM,EAAE,CAAA;QAC/D,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,YAAY,EAAE,CAAC,CAAA;IACvC,CAAC,CAAC,CAAA;IACF,GAAG,CAAC,IAAI,CAAC,cAAc,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACnC,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAiE,CAAA;QACjH,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,gCAAgC,EAAE,EAAE,GAAG,CAAC,CAAA;QACrG,MAAM,EAAE,GAAG,KAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QACnD,MAAM,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,EAAE,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;QACrE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;IAC7B,CAAC,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export function registerContext(app, reg, state) {
|
|
2
|
+
app.get('/api/session/:id/context', async (c) => {
|
|
3
|
+
const id = state.normalizeSessionId(c.req.param('id'));
|
|
4
|
+
const ctx = await reg.forSession(id).getContext(id);
|
|
5
|
+
return c.json({
|
|
6
|
+
sessionId: id,
|
|
7
|
+
agent: ctx.agent,
|
|
8
|
+
model: ctx.model,
|
|
9
|
+
tokens: ctx.tokens,
|
|
10
|
+
cost: ctx.cost ?? state.getSessionCost(id),
|
|
11
|
+
directory: ctx.directory,
|
|
12
|
+
nextAgent: state.getNextAgent(),
|
|
13
|
+
nextModel: state.getNextModel(),
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../../../src/transport/web/routes/context.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,eAAe,CAAC,GAAS,EAAE,GAAoB,EAAE,KAAmB;IAClF,GAAG,CAAC,GAAG,CAAC,0BAA0B,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC9C,MAAM,EAAE,GAAG,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA;QACtD,MAAM,GAAG,GAAG,MAAM,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA;QACnD,OAAO,CAAC,CAAC,IAAI,CAAC;YACZ,SAAS,EAAE,EAAE;YACb,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC;YAC1C,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,SAAS,EAAE,KAAK,CAAC,YAAY,EAAE;YAC/B,SAAS,EAAE,KAAK,CAAC,YAAY,EAAE;SAChC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session controls — read the switchable mode + model for a session, and switch
|
|
3
|
+
* them. Backed by the optional getControls/setMode/setModel (present only when the
|
|
4
|
+
* backend's `sessionControls` capability is true; ACP/kimi). Missing → 404/empty.
|
|
5
|
+
*/
|
|
6
|
+
export function registerControls(app, reg, state) {
|
|
7
|
+
app.get('/api/session/:id/controls', async (c) => {
|
|
8
|
+
const id = state.normalizeSessionId(c.req.param('id'));
|
|
9
|
+
return c.json((await reg.forSession(id).getControls?.(id)) ?? {});
|
|
10
|
+
});
|
|
11
|
+
app.post('/api/session/:id/mode', async (c) => {
|
|
12
|
+
const id = state.normalizeSessionId(c.req.param('id'));
|
|
13
|
+
const { modeId } = await c.req.json().catch(() => ({ modeId: undefined }));
|
|
14
|
+
if (!modeId)
|
|
15
|
+
return c.json({ error: 'modeId required' }, 400);
|
|
16
|
+
const b = reg.forSession(id);
|
|
17
|
+
if (!b.setMode)
|
|
18
|
+
return c.json({ error: 'mode switching not supported' }, 404);
|
|
19
|
+
await b.setMode(id, modeId);
|
|
20
|
+
return c.json({ ok: true });
|
|
21
|
+
});
|
|
22
|
+
app.post('/api/session/:id/model', async (c) => {
|
|
23
|
+
const id = state.normalizeSessionId(c.req.param('id'));
|
|
24
|
+
const { modelId } = await c.req.json().catch(() => ({ modelId: undefined }));
|
|
25
|
+
if (!modelId)
|
|
26
|
+
return c.json({ error: 'modelId required' }, 400);
|
|
27
|
+
const b = reg.forSession(id);
|
|
28
|
+
if (!b.setModel)
|
|
29
|
+
return c.json({ error: 'model switching not supported' }, 404);
|
|
30
|
+
await b.setModel(id, modelId);
|
|
31
|
+
return c.json({ ok: true });
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=controls.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"controls.js","sourceRoot":"","sources":["../../../../src/transport/web/routes/controls.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAS,EAAE,GAAoB,EAAE,KAAmB;IACnF,GAAG,CAAC,GAAG,CAAC,2BAA2B,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC/C,MAAM,EAAE,GAAG,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA;QACtD,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;IACnE,CAAC,CAAC,CAAA;IAEF,GAAG,CAAC,IAAI,CAAC,uBAAuB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC5C,MAAM,EAAE,GAAG,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA;QACtD,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAuB,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC,CAAA;QAC/F,IAAI,CAAC,MAAM;YAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,EAAE,GAAG,CAAC,CAAA;QAC7D,MAAM,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA;QAC5B,IAAI,CAAC,CAAC,CAAC,OAAO;YAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,8BAA8B,EAAE,EAAE,GAAG,CAAC,CAAA;QAC7E,MAAM,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;QAC3B,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;IAC7B,CAAC,CAAC,CAAA;IAEF,GAAG,CAAC,IAAI,CAAC,wBAAwB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC7C,MAAM,EAAE,GAAG,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA;QACtD,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAwB,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC,CAAA;QAClG,IAAI,CAAC,OAAO;YAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,EAAE,GAAG,CAAC,CAAA;QAC/D,MAAM,CAAC,GAAG,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAA;QAC5B,IAAI,CAAC,CAAC,CAAC,QAAQ;YAAE,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,+BAA+B,EAAE,EAAE,GAAG,CAAC,CAAA;QAC/E,MAAM,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;QAC7B,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;IAC7B,CAAC,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export function registerCreateSession(app, reg) {
|
|
2
|
+
app.post('/api/session', async (c) => {
|
|
3
|
+
const body = (await c.req.json().catch(() => ({})));
|
|
4
|
+
const backend = (body.backendId && reg.get(body.backendId)) || reg.active();
|
|
5
|
+
const directory = typeof body.directory === 'string' ? body.directory.trim() : '';
|
|
6
|
+
// Backends that don't enumerate workspaces (e.g. ACP) create in their own
|
|
7
|
+
// default working directory — the directory is optional there.
|
|
8
|
+
if (!directory && backend.capabilities.workspaces) {
|
|
9
|
+
return c.json({ error: 'directory required' }, 400);
|
|
10
|
+
}
|
|
11
|
+
try {
|
|
12
|
+
const { id } = await backend.createSession({ directory, title: body.title });
|
|
13
|
+
reg.tag(id, backend.id);
|
|
14
|
+
return c.json({ id, backendId: backend.id });
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return c.json({ error: 'create failed' }, 500);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=create-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-session.js","sourceRoot":"","sources":["../../../../src/transport/web/routes/create-session.ts"],"names":[],"mappings":"AAGA,MAAM,UAAU,qBAAqB,CAAC,GAAS,EAAE,GAAoB;IACnE,GAAG,CAAC,IAAI,CAAC,cAAc,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACnC,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAA+D,CAAA;QACjH,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,SAAS,IAAI,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,GAAG,CAAC,MAAM,EAAE,CAAA;QAC3E,MAAM,SAAS,GAAG,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;QACjF,0EAA0E;QAC1E,+DAA+D;QAC/D,IAAI,CAAC,SAAS,IAAI,OAAO,CAAC,YAAY,CAAC,UAAU,EAAE,CAAC;YAClD,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,EAAE,GAAG,CAAC,CAAA;QACrD,CAAC;QACD,IAAI,CAAC;YACH,MAAM,EAAE,EAAE,EAAE,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAA;YAC5E,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,CAAC,EAAE,CAAC,CAAA;YACvB,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAA;QAC9C,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,eAAe,EAAE,EAAE,GAAG,CAAC,CAAA;QAChD,CAAC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../../../src/transport/web/routes/diff.ts"],"names":[],"mappings":"AAIA,MAAM,UAAU,YAAY,CAAC,GAAS,EAAE,GAAoB,EAAE,KAAmB;IAC/E,GAAG,CAAC,GAAG,CAAC,uBAAuB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC3C,MAAM,EAAE,GAAG,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAA;QACtD,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAA;IACrD,CAAC,CAAC,CAAA;AACJ,CAAC"}
|