@interactive-inc/claude-funnel 0.4.1 → 0.8.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/README.md +233 -111
- package/dist/bin.js +1417 -0
- package/dist/gateway/daemon.js +513 -0
- package/dist/highlights-eq9cgrbb.scm +604 -0
- package/dist/highlights-ghv9g403.scm +205 -0
- package/dist/highlights-hk7bwhj4.scm +284 -0
- package/dist/highlights-r812a2qc.scm +150 -0
- package/dist/highlights-x6tmsnaa.scm +115 -0
- package/dist/injections-73j83es3.scm +27 -0
- package/dist/tree-sitter-javascript-nd0q4pe9.wasm +0 -0
- package/dist/tree-sitter-markdown-411r6y9b.wasm +0 -0
- package/dist/tree-sitter-markdown_inline-j5349f42.wasm +0 -0
- package/dist/tree-sitter-typescript-zxjzwt75.wasm +0 -0
- package/dist/tree-sitter-zig-e78zbjpm.wasm +0 -0
- package/lib/bin.ts +78 -0
- package/lib/{modules → cli}/router/to-request.ts +13 -20
- package/lib/cli/routes/channels.$channel.connectors.$connector.rename.$newName.ts +27 -0
- package/lib/cli/routes/channels.$channel.connectors.$connector.request.ts +40 -0
- package/lib/cli/routes/channels.$channel.connectors.$connector.schedules.add.$id.ts +41 -0
- package/lib/cli/routes/channels.$channel.connectors.$connector.schedules.remove.$id.ts +22 -0
- package/lib/cli/routes/channels.$channel.connectors.$connector.schedules.ts +23 -0
- package/lib/cli/routes/channels.$channel.connectors.$connector.ts +26 -0
- package/lib/cli/routes/channels.$channel.connectors.add.$connector.ts +92 -0
- package/lib/cli/routes/channels.$channel.connectors.remove.$connector.ts +22 -0
- package/lib/cli/routes/channels.$channel.connectors.set.$connector.ts +63 -0
- package/lib/cli/routes/channels.$channel.connectors.ts +26 -0
- package/lib/cli/routes/channels.$channel.rename.$newName.ts +22 -0
- package/lib/cli/routes/channels.$channel.set.delivery.$mode.ts +34 -0
- package/lib/cli/routes/channels.$channel.ts +34 -0
- package/lib/cli/routes/channels.add.$channel.ts +33 -0
- package/lib/cli/routes/channels.remove.$channel.ts +20 -0
- package/lib/cli/routes/channels.ts +39 -0
- package/lib/cli/routes/claude.ts +69 -0
- package/lib/cli/routes/gateway.listeners.ts +41 -0
- package/lib/cli/routes/gateway.logs.ts +123 -0
- package/lib/{routes/gateway/restart.ts → cli/routes/gateway.restart.ts} +20 -5
- package/lib/cli/routes/gateway.run.ts +41 -0
- package/lib/cli/routes/gateway.start.ts +50 -0
- package/lib/cli/routes/gateway.status.ts +19 -0
- package/lib/cli/routes/gateway.stop.ts +32 -0
- package/lib/cli/routes/gateway.ts +55 -0
- package/lib/cli/routes/index.ts +202 -0
- package/lib/cli/routes/profiles.$profile.as-default.ts +22 -0
- package/lib/cli/routes/profiles.$profile.rename.$newName.ts +22 -0
- package/lib/cli/routes/profiles.$profile.run.ts +36 -0
- package/lib/cli/routes/profiles.add.$profile.ts +46 -0
- package/lib/cli/routes/profiles.remove.$profile.ts +20 -0
- package/lib/cli/routes/profiles.set.$profile.ts +46 -0
- package/lib/cli/routes/profiles.ts +40 -0
- package/lib/cli/routes/status.ts +93 -0
- package/lib/cli/routes/update.ts +27 -0
- package/lib/connectors/connector-config-schema.ts +16 -0
- package/lib/connectors/connector-factory.ts +94 -0
- package/lib/connectors/connector-listener.ts +20 -0
- package/lib/{modules/connectors/funnel-discord-adapter.ts → connectors/discord-adapter.ts} +6 -11
- package/lib/{modules/connectors → connectors}/discord-connector-schema.ts +4 -1
- package/lib/connectors/discord-listener.ts +111 -0
- package/lib/{modules/connectors/funnel-gh-adapter.ts → connectors/gh-adapter.ts} +3 -6
- package/lib/{modules/connectors → connectors}/gh-connector-schema.ts +4 -1
- package/lib/{modules/connectors/funnel-gh-listener.ts → connectors/gh-listener.ts} +57 -22
- package/lib/{modules/connectors → connectors}/match-cron.ts +10 -4
- package/lib/connectors/schedule-connector-schema.ts +33 -0
- package/lib/connectors/schedule-listener.ts +207 -0
- package/lib/connectors/schedule-state-store.ts +54 -0
- package/lib/connectors/slack-adapter.ts +36 -0
- package/lib/{modules/connectors → connectors}/slack-connector-schema.ts +4 -1
- package/lib/{modules/connectors/funnel-slack-event-processor.ts → connectors/slack-event-processor.ts} +15 -9
- package/lib/{modules/connectors/funnel-slack-listener.ts → connectors/slack-listener.ts} +39 -14
- package/lib/engine/channels/channels.ts +520 -0
- package/lib/{modules/claude/funnel-claude.ts → engine/claude/claude.ts} +47 -62
- package/lib/engine/claude/gateway-controller.ts +4 -0
- package/lib/{modules/fs/funnel-file-system.ts → engine/fs/file-system.ts} +9 -0
- package/lib/{modules/fs/memory-funnel-file-system.ts → engine/fs/memory-file-system.ts} +20 -3
- package/lib/{modules/fs/node-funnel-file-system.ts → engine/fs/node-file-system.ts} +14 -2
- package/lib/{modules/http/memory-funnel-http-client.ts → engine/http/memory-http-client.ts} +1 -5
- package/lib/{modules/http/node-funnel-http-client.ts → engine/http/node-http-client.ts} +1 -5
- package/lib/engine/id/id-generator.ts +7 -0
- package/lib/engine/id/memory-id-generator.ts +20 -0
- package/lib/engine/id/node-id-generator.ts +7 -0
- package/lib/engine/logger/logger.ts +11 -0
- package/lib/engine/logger/memory-logger.ts +28 -0
- package/lib/engine/logger/node-logger.ts +49 -0
- package/lib/engine/logger/noop-logger.ts +9 -0
- package/lib/engine/mcp/channel-server.ts +204 -0
- package/lib/{modules/mcp/funnel-mcp.ts → engine/mcp/mcp.ts} +29 -10
- package/lib/{modules/process/memory-funnel-process-runner.ts → engine/process/memory-process-runner.ts} +1 -1
- package/lib/{modules/process/node-funnel-process-runner.ts → engine/process/node-process-runner.ts} +12 -21
- package/lib/{modules/process/funnel-process-runner.ts → engine/process/process-runner.ts} +5 -0
- package/lib/engine/profiles/profile-channel-checker.ts +7 -0
- package/lib/engine/profiles/profiles.ts +126 -0
- package/lib/{modules/settings/mock-funnel-settings-reader.ts → engine/settings/mock-settings-reader.ts} +4 -3
- package/lib/{modules/settings/funnel-settings-reader.ts → engine/settings/settings-reader.ts} +1 -1
- package/lib/engine/settings/settings-schema.ts +46 -0
- package/lib/engine/settings/settings-store.ts +110 -0
- package/lib/engine/time/clock.ts +15 -0
- package/lib/engine/time/memory-clock.ts +26 -0
- package/lib/engine/time/node-clock.ts +7 -0
- package/lib/funnel.ts +148 -56
- package/lib/gateway/auth-middleware.ts +44 -0
- package/lib/gateway/broadcaster.ts +319 -0
- package/lib/gateway/daemon.ts +47 -0
- package/lib/gateway/factory.ts +10 -0
- package/lib/gateway/funnel-event-store.ts +155 -0
- package/lib/gateway/gateway-server.ts +414 -0
- package/lib/gateway/gateway-token.ts +79 -0
- package/lib/{modules/gateway/funnel-gateway.ts → gateway/gateway.ts} +70 -27
- package/lib/{modules/gateway → gateway}/kill-competing-slack-gateways.ts +7 -3
- package/lib/gateway/listener-supervisor.ts +339 -0
- package/lib/gateway/listeners-client.ts +128 -0
- package/lib/gateway/resolve-daemon-script.ts +26 -0
- package/lib/gateway/routes/channels.connectors.call.ts +39 -0
- package/lib/gateway/routes/health.ts +13 -0
- package/lib/gateway/routes/index.ts +24 -0
- package/lib/gateway/routes/listeners.list.ts +6 -0
- package/lib/gateway/routes/listeners.restart.ts +15 -0
- package/lib/gateway/routes/listeners.start.ts +15 -0
- package/lib/gateway/routes/listeners.stop.ts +15 -0
- package/lib/gateway/routes/route-deps.ts +11 -0
- package/lib/gateway/routes/status.ts +15 -0
- package/lib/gateway/routes/validator.ts +17 -0
- package/lib/index.ts +50 -92
- package/lib/logger/leuco-human-file-writer.ts +65 -0
- package/lib/logger/leuco-human-logger.ts +98 -0
- package/lib/logger/leuco-human-record.ts +16 -0
- package/lib/logger/leuco-human-stdout-writer.ts +26 -0
- package/lib/logger/leuco-human-writer.ts +14 -0
- package/lib/logger/leuco-logger-memory-sink.ts +67 -0
- package/lib/logger/leuco-logger-record.ts +13 -0
- package/lib/logger/leuco-logger-sink.ts +33 -0
- package/lib/logger/leuco-logger-sqlite-sink.ts +355 -0
- package/lib/logger/leuco-logger.ts +135 -0
- package/lib/tui/app.tsx +357 -0
- package/lib/tui/components/add-row.tsx +18 -0
- package/lib/tui/components/brand.tsx +27 -0
- package/lib/tui/components/card.tsx +44 -0
- package/lib/tui/components/detail-bar.tsx +46 -0
- package/lib/tui/components/editable-field.tsx +33 -0
- package/lib/tui/components/empty-state.tsx +11 -0
- package/lib/tui/components/gateway-status.tsx +66 -0
- package/lib/tui/components/keymap.tsx +29 -0
- package/lib/tui/components/menu-item.tsx +73 -0
- package/lib/tui/components/menu.tsx +26 -0
- package/lib/tui/components/panel-header.tsx +22 -0
- package/lib/tui/components/readonly-field.tsx +18 -0
- package/lib/tui/components/section-header.tsx +25 -0
- package/lib/tui/components/selection-accent.tsx +32 -0
- package/lib/tui/components/session-item.tsx +33 -0
- package/lib/tui/components/session-list.tsx +33 -0
- package/lib/tui/components/ui/hascii/accordion-item.tsx +88 -0
- package/lib/tui/components/ui/hascii/accordion.tsx +96 -0
- package/lib/tui/components/ui/hascii/alert-dialog.tsx +43 -0
- package/lib/tui/components/ui/hascii/badge.tsx +51 -0
- package/lib/tui/components/ui/hascii/breadcrumb.tsx +58 -0
- package/lib/tui/components/ui/hascii/button.tsx +194 -0
- package/lib/tui/components/ui/hascii/card-content.tsx +14 -0
- package/lib/tui/components/ui/hascii/card-description.tsx +13 -0
- package/lib/tui/components/ui/hascii/card-footer.tsx +14 -0
- package/lib/tui/components/ui/hascii/card-header.tsx +14 -0
- package/lib/tui/components/ui/hascii/card-title.tsx +13 -0
- package/lib/tui/components/ui/hascii/card.tsx +27 -0
- package/lib/tui/components/ui/hascii/checkbox.tsx +65 -0
- package/lib/tui/components/ui/hascii/command.tsx +159 -0
- package/lib/tui/components/ui/hascii/dialog-content.tsx +14 -0
- package/lib/tui/components/ui/hascii/dialog-description.tsx +13 -0
- package/lib/tui/components/ui/hascii/dialog-footer.tsx +14 -0
- package/lib/tui/components/ui/hascii/dialog-header.tsx +14 -0
- package/lib/tui/components/ui/hascii/dialog-title.tsx +13 -0
- package/lib/tui/components/ui/hascii/dialog.tsx +27 -0
- package/lib/tui/components/ui/hascii/file-tree.tsx +142 -0
- package/lib/tui/components/ui/hascii/focus-group.tsx +62 -0
- package/lib/tui/components/ui/hascii/form-item.tsx +43 -0
- package/lib/tui/components/ui/hascii/input-otp.tsx +86 -0
- package/lib/tui/components/ui/hascii/input.tsx +130 -0
- package/lib/tui/components/ui/hascii/pagination.tsx +105 -0
- package/lib/tui/components/ui/hascii/progress.tsx +28 -0
- package/lib/tui/components/ui/hascii/select.tsx +131 -0
- package/lib/tui/components/ui/hascii/separator.tsx +35 -0
- package/lib/tui/components/ui/hascii/sidebar-content.tsx +23 -0
- package/lib/tui/components/ui/hascii/sidebar-header.tsx +14 -0
- package/lib/tui/components/ui/hascii/sidebar-menu-item.tsx +67 -0
- package/lib/tui/components/ui/hascii/sidebar.tsx +24 -0
- package/lib/tui/components/ui/hascii/skeleton.tsx +60 -0
- package/lib/tui/components/ui/hascii/slider.tsx +91 -0
- package/lib/tui/components/ui/hascii/snackbar.tsx +75 -0
- package/lib/tui/components/ui/hascii/sparkline.tsx +53 -0
- package/lib/tui/components/ui/hascii/spinner.tsx +47 -0
- package/lib/tui/components/ui/hascii/stepper.tsx +54 -0
- package/lib/tui/components/ui/hascii/switch.tsx +66 -0
- package/lib/tui/components/ui/hascii/table.tsx +95 -0
- package/lib/tui/components/ui/hascii/tabs.tsx +59 -0
- package/lib/tui/components/ui/hascii/toggle-group-item.tsx +45 -0
- package/lib/tui/components/ui/hascii/toggle-group.tsx +99 -0
- package/lib/tui/components/ui/hascii/tree.tsx +104 -0
- package/lib/tui/components/view-shell.tsx +44 -0
- package/lib/tui/filter-input.tsx +33 -0
- package/lib/tui/hooks/hascii/use-pressable.ts +54 -0
- package/lib/tui/parse-comma-list.ts +14 -0
- package/lib/tui/profile-launcher.tsx +61 -0
- package/lib/tui/scrollbar-options.ts +19 -0
- package/lib/tui/sidebar.tsx +50 -0
- package/lib/tui/theme.ts +40 -0
- package/lib/tui/tui.tsx +20 -0
- package/lib/tui/types.ts +38 -0
- package/lib/tui/unique-name.ts +18 -0
- package/lib/tui/use-event-stream.ts +133 -0
- package/lib/tui/use-snapshot.ts +99 -0
- package/lib/tui/utils/hascii/form-item-context.tsx +23 -0
- package/lib/tui/utils/hascii/input-focus-context.tsx +31 -0
- package/lib/tui/utils/hascii/theme-context.tsx +26 -0
- package/lib/tui/utils/hascii/theme.ts +176 -0
- package/lib/tui/views/channels-view.tsx +108 -0
- package/lib/tui/views/connectors-view.tsx +164 -0
- package/lib/tui/views/events-view.tsx +160 -0
- package/lib/tui/views/listeners-view.tsx +80 -0
- package/lib/tui/views/profiles-view.tsx +152 -0
- package/package.json +51 -34
- package/lib/modules/channels/channel-connector-ref-updater.ts +0 -4
- package/lib/modules/channels/funnel-channels.ts +0 -155
- package/lib/modules/connectors/connector-config-schema.ts +0 -16
- package/lib/modules/connectors/connector-existence-checker.ts +0 -3
- package/lib/modules/connectors/funnel-callable-connector-store.ts +0 -9
- package/lib/modules/connectors/funnel-connector-listener.ts +0 -5
- package/lib/modules/connectors/funnel-connector-stores.ts +0 -24
- package/lib/modules/connectors/funnel-connector-type-store.ts +0 -24
- package/lib/modules/connectors/funnel-connectors.ts +0 -145
- package/lib/modules/connectors/funnel-discord-listener.ts +0 -65
- package/lib/modules/connectors/funnel-discord-store.ts +0 -84
- package/lib/modules/connectors/funnel-gh-store.ts +0 -84
- package/lib/modules/connectors/funnel-json-connector-store.ts +0 -100
- package/lib/modules/connectors/funnel-schedule-listener.ts +0 -124
- package/lib/modules/connectors/funnel-schedule-store.ts +0 -178
- package/lib/modules/connectors/funnel-slack-adapter.ts +0 -31
- package/lib/modules/connectors/funnel-slack-store.ts +0 -86
- package/lib/modules/connectors/migrate-legacy-connectors.ts +0 -77
- package/lib/modules/connectors/schedule-connector-schema.ts +0 -18
- package/lib/modules/connectors/schedule-last-fired-store.ts +0 -48
- package/lib/modules/gateway/daemon.ts +0 -207
- package/lib/modules/gateway/funnel-broadcaster.ts +0 -37
- package/lib/modules/gateway/funnel-event-logger.ts +0 -59
- package/lib/modules/logger.ts +0 -26
- package/lib/modules/mcp/channel-server.ts +0 -76
- package/lib/modules/profiles/funnel-profiles.ts +0 -123
- package/lib/modules/profiles/profile-channel-checker.ts +0 -3
- package/lib/modules/profiles/profile-channel-ref-updater.ts +0 -3
- package/lib/modules/repos/funnel-repositories.ts +0 -107
- package/lib/modules/schedule/funnel-schedule.ts +0 -34
- package/lib/modules/settings/funnel-settings-store.ts +0 -56
- package/lib/modules/settings/settings-schema.ts +0 -33
- package/lib/modules/tui/app.tsx +0 -44
- package/lib/modules/tui/tui.tsx +0 -13
- package/lib/routes/channels/add.help.ts +0 -3
- package/lib/routes/channels/add.ts +0 -21
- package/lib/routes/channels/connectors-attach.help.ts +0 -3
- package/lib/routes/channels/connectors-attach.ts +0 -17
- package/lib/routes/channels/connectors-detach.help.ts +0 -3
- package/lib/routes/channels/connectors-detach.ts +0 -17
- package/lib/routes/channels/group.help.ts +0 -16
- package/lib/routes/channels/group.ts +0 -22
- package/lib/routes/channels/remove.help.ts +0 -3
- package/lib/routes/channels/remove.ts +0 -17
- package/lib/routes/channels/rename.help.ts +0 -5
- package/lib/routes/channels/rename.ts +0 -17
- package/lib/routes/channels/routes.ts +0 -19
- package/lib/routes/channels/show.help.ts +0 -1
- package/lib/routes/channels/show.ts +0 -26
- package/lib/routes/claude/claude.help.ts +0 -16
- package/lib/routes/claude/claude.ts +0 -76
- package/lib/routes/claude/routes.ts +0 -4
- package/lib/routes/connectors/add.help.ts +0 -28
- package/lib/routes/connectors/add.ts +0 -64
- package/lib/routes/connectors/group.help.ts +0 -14
- package/lib/routes/connectors/group.ts +0 -18
- package/lib/routes/connectors/remove.help.ts +0 -3
- package/lib/routes/connectors/remove.ts +0 -17
- package/lib/routes/connectors/rename.help.ts +0 -5
- package/lib/routes/connectors/rename.ts +0 -17
- package/lib/routes/connectors/routes.ts +0 -23
- package/lib/routes/connectors/schedules-add.help.ts +0 -11
- package/lib/routes/connectors/schedules-add.ts +0 -33
- package/lib/routes/connectors/schedules-group.help.ts +0 -1
- package/lib/routes/connectors/schedules-group.ts +0 -38
- package/lib/routes/connectors/schedules-remove.help.ts +0 -3
- package/lib/routes/connectors/schedules-remove.ts +0 -17
- package/lib/routes/connectors/set.help.ts +0 -8
- package/lib/routes/connectors/set.ts +0 -72
- package/lib/routes/connectors/show.help.ts +0 -1
- package/lib/routes/connectors/show.ts +0 -41
- package/lib/routes/gateway/group.help.ts +0 -15
- package/lib/routes/gateway/group.ts +0 -28
- package/lib/routes/gateway/logs.help.ts +0 -13
- package/lib/routes/gateway/logs.ts +0 -100
- package/lib/routes/gateway/restart.help.ts +0 -10
- package/lib/routes/gateway/routes.ts +0 -18
- package/lib/routes/gateway/run.help.ts +0 -12
- package/lib/routes/gateway/run.ts +0 -35
- package/lib/routes/gateway/start.help.ts +0 -15
- package/lib/routes/gateway/start.ts +0 -32
- package/lib/routes/gateway/status.help.ts +0 -9
- package/lib/routes/gateway/status.ts +0 -28
- package/lib/routes/gateway/stop.help.ts +0 -8
- package/lib/routes/gateway/stop.ts +0 -21
- package/lib/routes/profiles/add.help.ts +0 -3
- package/lib/routes/profiles/add.ts +0 -33
- package/lib/routes/profiles/group.help.ts +0 -16
- package/lib/routes/profiles/group.ts +0 -25
- package/lib/routes/profiles/launch.help.ts +0 -4
- package/lib/routes/profiles/launch.ts +0 -36
- package/lib/routes/profiles/remove.help.ts +0 -3
- package/lib/routes/profiles/remove.ts +0 -17
- package/lib/routes/profiles/rename.help.ts +0 -5
- package/lib/routes/profiles/rename.ts +0 -17
- package/lib/routes/profiles/routes.ts +0 -18
- package/lib/routes/profiles/set.help.ts +0 -5
- package/lib/routes/profiles/set.ts +0 -32
- package/lib/routes/repos/add.help.ts +0 -6
- package/lib/routes/repos/add.ts +0 -20
- package/lib/routes/repos/group.help.ts +0 -11
- package/lib/routes/repos/group.ts +0 -18
- package/lib/routes/repos/remove.help.ts +0 -3
- package/lib/routes/repos/remove.ts +0 -17
- package/lib/routes/repos/rename.help.ts +0 -5
- package/lib/routes/repos/rename.ts +0 -17
- package/lib/routes/repos/routes.ts +0 -17
- package/lib/routes/repos/set.help.ts +0 -5
- package/lib/routes/repos/set.ts +0 -21
- package/lib/routes/repos/show.help.ts +0 -1
- package/lib/routes/repos/show.ts +0 -19
- package/lib/routes/request/discord-help.ts +0 -9
- package/lib/routes/request/discord.help.ts +0 -19
- package/lib/routes/request/discord.ts +0 -65
- package/lib/routes/request/group.help.ts +0 -15
- package/lib/routes/request/group.ts +0 -9
- package/lib/routes/request/routes.ts +0 -14
- package/lib/routes/request/slack-help.ts +0 -9
- package/lib/routes/request/slack.help.ts +0 -19
- package/lib/routes/request/slack.ts +0 -61
- package/lib/routes/status/routes.ts +0 -4
- package/lib/routes/status/status.help.ts +0 -6
- package/lib/routes/status/status.ts +0 -77
- package/lib/routes/update/routes.ts +0 -4
- package/lib/routes/update/update.help.ts +0 -5
- package/lib/routes/update/update.ts +0 -21
- package/lib/routes.ts +0 -40
- /package/lib/{factory.ts → cli/factory.ts} +0 -0
- /package/lib/{modules → cli}/router/query-to-cli-args.ts +0 -0
- /package/lib/{modules → cli}/router/validator.ts +0 -0
- /package/lib/{modules/connectors/funnel-connector-adapter.ts → connectors/connector-adapter.ts} +0 -0
- /package/lib/{modules/connectors/funnel-discord-event-processor.ts → connectors/discord-event-processor.ts} +0 -0
- /package/lib/{modules/http/funnel-http-client.ts → engine/http/http-client.ts} +0 -0
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { z } from "zod"
|
|
2
|
-
import { factory } from "@/factory"
|
|
3
|
-
import { zValidator } from "@/modules/router/validator"
|
|
4
|
-
import { help } from "@/routes/connectors/rename.help"
|
|
5
|
-
|
|
6
|
-
export const connectorsRenameHandler = factory.createHandlers(
|
|
7
|
-
zValidator("param", z.object({ name: z.string(), newName: z.string() })),
|
|
8
|
-
zValidator("query", z.object({}), help),
|
|
9
|
-
(c) => {
|
|
10
|
-
const param = c.req.valid("param")
|
|
11
|
-
const funnel = c.var.funnel
|
|
12
|
-
|
|
13
|
-
funnel.connectors.rename(param.name, param["newName"])
|
|
14
|
-
|
|
15
|
-
return c.text(`renamed connector "${param.name}" to "${param["newName"]}"`)
|
|
16
|
-
},
|
|
17
|
-
)
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { factory } from "@/factory"
|
|
2
|
-
import { connectorsAddHandler } from "@/routes/connectors/add"
|
|
3
|
-
import { connectorsGroupHandler } from "@/routes/connectors/group"
|
|
4
|
-
import { connectorsRemoveHandler } from "@/routes/connectors/remove"
|
|
5
|
-
import { connectorsRenameHandler } from "@/routes/connectors/rename"
|
|
6
|
-
import { connectorsSchedulesAddHandler } from "@/routes/connectors/schedules-add"
|
|
7
|
-
import { connectorsSchedulesGroupHandler } from "@/routes/connectors/schedules-group"
|
|
8
|
-
import { connectorsSchedulesRemoveHandler } from "@/routes/connectors/schedules-remove"
|
|
9
|
-
import { connectorsSetHandler } from "@/routes/connectors/set"
|
|
10
|
-
import { connectorsShowHandler } from "@/routes/connectors/show"
|
|
11
|
-
|
|
12
|
-
export const connectorsRoutes = factory
|
|
13
|
-
.createApp()
|
|
14
|
-
.get("/", ...connectorsGroupHandler)
|
|
15
|
-
.put("/:name/rename/:newName", ...connectorsRenameHandler)
|
|
16
|
-
.put("/rename/:name/:newName", ...connectorsRenameHandler)
|
|
17
|
-
.post("/:name/schedules", ...connectorsSchedulesAddHandler)
|
|
18
|
-
.get("/:name/schedules", ...connectorsSchedulesGroupHandler)
|
|
19
|
-
.delete("/:name/schedules/:id", ...connectorsSchedulesRemoveHandler)
|
|
20
|
-
.post("/:name", ...connectorsAddHandler)
|
|
21
|
-
.put("/:name", ...connectorsSetHandler)
|
|
22
|
-
.delete("/:name", ...connectorsRemoveHandler)
|
|
23
|
-
.get("/:name", ...connectorsShowHandler)
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
export const help = `funnel connectors <name> schedules add — add a schedule entry
|
|
2
|
-
|
|
3
|
-
usage: funnel connectors <name> schedules add --cron "<expr>" --prompt "<text>" [--disabled]
|
|
4
|
-
|
|
5
|
-
options:
|
|
6
|
-
--cron 5-field cron expression (min hour dom month dow)
|
|
7
|
-
--prompt prompt text delivered to subscribing channels when the cron fires
|
|
8
|
-
--disabled create the entry in disabled state
|
|
9
|
-
|
|
10
|
-
example:
|
|
11
|
-
funnel connectors my-cron schedules add --cron "*/5 * * * *" --prompt "status check"`
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { z } from "zod"
|
|
2
|
-
import { factory } from "@/factory"
|
|
3
|
-
import { matchCron } from "@/modules/connectors/match-cron"
|
|
4
|
-
import { zValidator } from "@/modules/router/validator"
|
|
5
|
-
import { help } from "@/routes/connectors/schedules-add.help"
|
|
6
|
-
|
|
7
|
-
export const connectorsSchedulesAddHandler = factory.createHandlers(
|
|
8
|
-
zValidator("param", z.object({ name: z.string() })),
|
|
9
|
-
zValidator(
|
|
10
|
-
"query",
|
|
11
|
-
z.object({
|
|
12
|
-
cron: z.string(),
|
|
13
|
-
prompt: z.string(),
|
|
14
|
-
disabled: z.string().optional(),
|
|
15
|
-
}),
|
|
16
|
-
help,
|
|
17
|
-
),
|
|
18
|
-
(c) => {
|
|
19
|
-
const param = c.req.valid("param")
|
|
20
|
-
const query = c.req.valid("query")
|
|
21
|
-
const funnel = c.var.funnel
|
|
22
|
-
|
|
23
|
-
matchCron(query.cron, new Date())
|
|
24
|
-
|
|
25
|
-
const entry = funnel.schedule.addEntry(param.name, {
|
|
26
|
-
cron: query.cron,
|
|
27
|
-
prompt: query.prompt,
|
|
28
|
-
enabled: query.disabled !== "true",
|
|
29
|
-
})
|
|
30
|
-
|
|
31
|
-
return c.text(`added schedule entry "${entry.id}" to connector "${param.name}"`)
|
|
32
|
-
},
|
|
33
|
-
)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const help = `funnel connectors <name> schedules — list schedule entries`
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { HTTPException } from "hono/http-exception"
|
|
2
|
-
import { z } from "zod"
|
|
3
|
-
import { factory } from "@/factory"
|
|
4
|
-
import { zValidator } from "@/modules/router/validator"
|
|
5
|
-
import { help } from "@/routes/connectors/schedules-group.help"
|
|
6
|
-
|
|
7
|
-
export const connectorsSchedulesGroupHandler = factory.createHandlers(
|
|
8
|
-
zValidator("param", z.object({ name: z.string() })),
|
|
9
|
-
zValidator("query", z.object({}), help),
|
|
10
|
-
(c) => {
|
|
11
|
-
const param = c.req.valid("param")
|
|
12
|
-
const funnel = c.var.funnel
|
|
13
|
-
const connector = funnel.connectors.get(param.name)
|
|
14
|
-
|
|
15
|
-
if (!connector) {
|
|
16
|
-
throw new HTTPException(404, { message: `connector "${param.name}" not found` })
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
if (connector.type !== "schedule") {
|
|
20
|
-
throw new HTTPException(400, {
|
|
21
|
-
message: `connector "${param.name}" is type "${connector.type}", not "schedule"`,
|
|
22
|
-
})
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const entries = funnel.schedule.listEntries(param.name)
|
|
26
|
-
|
|
27
|
-
if (entries.length === 0) return c.text("no schedule entries")
|
|
28
|
-
|
|
29
|
-
const lines: string[] = []
|
|
30
|
-
|
|
31
|
-
for (const entry of entries) {
|
|
32
|
-
const status = entry.enabled ? "" : " (disabled)"
|
|
33
|
-
lines.push(`${entry.id}${status} ${entry.cron} ${entry.prompt}`)
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return c.text(lines.join("\n"))
|
|
37
|
-
},
|
|
38
|
-
)
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { z } from "zod"
|
|
2
|
-
import { factory } from "@/factory"
|
|
3
|
-
import { zValidator } from "@/modules/router/validator"
|
|
4
|
-
import { help } from "@/routes/connectors/schedules-remove.help"
|
|
5
|
-
|
|
6
|
-
export const connectorsSchedulesRemoveHandler = factory.createHandlers(
|
|
7
|
-
zValidator("param", z.object({ name: z.string(), id: z.string() })),
|
|
8
|
-
zValidator("query", z.object({}), help),
|
|
9
|
-
(c) => {
|
|
10
|
-
const param = c.req.valid("param")
|
|
11
|
-
const funnel = c.var.funnel
|
|
12
|
-
|
|
13
|
-
funnel.schedule.removeEntry(param.name, param.id)
|
|
14
|
-
|
|
15
|
-
return c.text(`removed schedule entry "${param.id}" from connector "${param.name}"`)
|
|
16
|
-
},
|
|
17
|
-
)
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export const help = `funnel connectors <name> set — update a connector
|
|
2
|
-
|
|
3
|
-
usage: funnel connectors <name> set [--bot-token ...] [--app-token ...] [--poll-interval ...]
|
|
4
|
-
|
|
5
|
-
fields available per type:
|
|
6
|
-
slack : --bot-token / --app-token
|
|
7
|
-
gh : --poll-interval
|
|
8
|
-
discord : --bot-token`
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { HTTPException } from "hono/http-exception"
|
|
2
|
-
import { z } from "zod"
|
|
3
|
-
import { factory } from "@/factory"
|
|
4
|
-
import { zValidator } from "@/modules/router/validator"
|
|
5
|
-
import { help } from "@/routes/connectors/set.help"
|
|
6
|
-
|
|
7
|
-
const SLACK_FIELDS = ["bot-token", "app-token"] as const
|
|
8
|
-
const GH_FIELDS = ["poll-interval"] as const
|
|
9
|
-
const DISCORD_FIELDS = ["bot-token"] as const
|
|
10
|
-
|
|
11
|
-
const rejectExtraneous = (
|
|
12
|
-
query: Record<string, string | undefined>,
|
|
13
|
-
allowed: ReadonlyArray<string>,
|
|
14
|
-
type: string,
|
|
15
|
-
): void => {
|
|
16
|
-
for (const key of ["bot-token", "app-token", "poll-interval"]) {
|
|
17
|
-
if (query[key] === undefined) continue
|
|
18
|
-
if (allowed.includes(key)) continue
|
|
19
|
-
|
|
20
|
-
throw new HTTPException(400, {
|
|
21
|
-
message: `connector type "${type}" does not accept --${key}`,
|
|
22
|
-
})
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export const connectorsSetHandler = factory.createHandlers(
|
|
27
|
-
zValidator("param", z.object({ name: z.string() })),
|
|
28
|
-
zValidator(
|
|
29
|
-
"query",
|
|
30
|
-
z.object({
|
|
31
|
-
"bot-token": z.string().optional(),
|
|
32
|
-
"app-token": z.string().optional(),
|
|
33
|
-
"poll-interval": z.string().optional(),
|
|
34
|
-
}),
|
|
35
|
-
help,
|
|
36
|
-
),
|
|
37
|
-
(c) => {
|
|
38
|
-
const param = c.req.valid("param")
|
|
39
|
-
const query = c.req.valid("query")
|
|
40
|
-
const funnel = c.var.funnel
|
|
41
|
-
|
|
42
|
-
const current = funnel.connectors.get(param.name)
|
|
43
|
-
|
|
44
|
-
if (!current) {
|
|
45
|
-
throw new HTTPException(404, { message: `connector "${param.name}" not found` })
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (current.type === "slack") {
|
|
49
|
-
rejectExtraneous(query, SLACK_FIELDS, "slack")
|
|
50
|
-
funnel.connectors.updateSlack(param.name, {
|
|
51
|
-
botToken: query["bot-token"],
|
|
52
|
-
appToken: query["app-token"],
|
|
53
|
-
})
|
|
54
|
-
} else if (current.type === "gh") {
|
|
55
|
-
rejectExtraneous(query, GH_FIELDS, "gh")
|
|
56
|
-
funnel.connectors.updateGh(param.name, {
|
|
57
|
-
pollInterval: query["poll-interval"] ? Number(query["poll-interval"]) : undefined,
|
|
58
|
-
})
|
|
59
|
-
} else if (current.type === "discord") {
|
|
60
|
-
rejectExtraneous(query, DISCORD_FIELDS, "discord")
|
|
61
|
-
funnel.connectors.updateDiscord(param.name, {
|
|
62
|
-
botToken: query["bot-token"],
|
|
63
|
-
})
|
|
64
|
-
} else {
|
|
65
|
-
throw new HTTPException(400, {
|
|
66
|
-
message: `schedule connectors have no top-level fields — use schedules add/remove`,
|
|
67
|
-
})
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return c.text(`updated connector "${param.name}"`)
|
|
71
|
-
},
|
|
72
|
-
)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export const help = `funnel connectors <name> — show connector details`
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { HTTPException } from "hono/http-exception"
|
|
2
|
-
import { z } from "zod"
|
|
3
|
-
import { factory } from "@/factory"
|
|
4
|
-
import { zValidator } from "@/modules/router/validator"
|
|
5
|
-
import { help } from "@/routes/connectors/show.help"
|
|
6
|
-
|
|
7
|
-
export const connectorsShowHandler = factory.createHandlers(
|
|
8
|
-
zValidator("param", z.object({ name: z.string() })),
|
|
9
|
-
zValidator("query", z.object({}), help),
|
|
10
|
-
(c) => {
|
|
11
|
-
const param = c.req.valid("param")
|
|
12
|
-
const funnel = c.var.funnel
|
|
13
|
-
const connector = funnel.connectors.get(param.name)
|
|
14
|
-
|
|
15
|
-
if (!connector) {
|
|
16
|
-
throw new HTTPException(404, { message: `connector "${param.name}" not found` })
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const lines: string[] = [`name: ${connector.name}`, `type: ${connector.type}`]
|
|
20
|
-
|
|
21
|
-
if (connector.type === "slack") {
|
|
22
|
-
lines.push(`botToken: ${connector.botToken.slice(0, 8)}...`)
|
|
23
|
-
lines.push(`appToken: ${connector.appToken.slice(0, 8)}...`)
|
|
24
|
-
} else if (connector.type === "gh") {
|
|
25
|
-
lines.push(`pollInterval: ${connector.pollInterval ?? 60}s`)
|
|
26
|
-
} else if (connector.type === "discord") {
|
|
27
|
-
lines.push(`botToken: ${connector.botToken.slice(0, 8)}...`)
|
|
28
|
-
} else if (connector.type === "schedule") {
|
|
29
|
-
lines.push(`entries: ${connector.entries.length}`)
|
|
30
|
-
|
|
31
|
-
for (const entry of connector.entries) {
|
|
32
|
-
const status = entry.enabled ? "" : " (disabled)"
|
|
33
|
-
lines.push(` - ${entry.id}${status}`)
|
|
34
|
-
lines.push(` cron: ${entry.cron}`)
|
|
35
|
-
lines.push(` prompt: ${entry.prompt}`)
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
return c.text(lines.join("\n"))
|
|
40
|
-
},
|
|
41
|
-
)
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export const help = `funnel gateway — manage the gateway
|
|
2
|
-
|
|
3
|
-
usage: funnel gateway [subcommand]
|
|
4
|
-
|
|
5
|
-
subcommands:
|
|
6
|
-
status show running status (default)
|
|
7
|
-
start start in background
|
|
8
|
-
stop stop
|
|
9
|
-
restart stop then start
|
|
10
|
-
run start in foreground (for developers)
|
|
11
|
-
logs [-n <N>] show event logs
|
|
12
|
-
|
|
13
|
-
examples:
|
|
14
|
-
funnel gateway check status
|
|
15
|
-
funnel gateway restart restart`
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { z } from "zod"
|
|
2
|
-
import { factory } from "@/factory"
|
|
3
|
-
import { zValidator } from "@/modules/router/validator"
|
|
4
|
-
import { help } from "@/routes/gateway/group.help"
|
|
5
|
-
|
|
6
|
-
export const gatewayGroupHandler = factory.createHandlers(
|
|
7
|
-
zValidator("query", z.object({}), help),
|
|
8
|
-
async (c) => {
|
|
9
|
-
const funnel = c.var.funnel
|
|
10
|
-
const status = funnel.gateway.getStatus()
|
|
11
|
-
|
|
12
|
-
if (!status.running) {
|
|
13
|
-
return c.text("funnel gateway: not running", 503)
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const res = await fetch(`http://localhost:${status.port}/health`).catch(() => null)
|
|
17
|
-
|
|
18
|
-
if (!res) {
|
|
19
|
-
return c.text(`funnel gateway: running (pid ${status.pid}) — health check failed`)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const health = (await res.json()) as Record<string, unknown>
|
|
23
|
-
|
|
24
|
-
return c.text(
|
|
25
|
-
`funnel gateway: running (pid ${status.pid})\n port: ${status.port}\n clients: ${health.clients ?? 0}`,
|
|
26
|
-
)
|
|
27
|
-
},
|
|
28
|
-
)
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export const help = `funnel gateway logs — tail event logs
|
|
2
|
-
|
|
3
|
-
usage: funnel gateway logs [-n <N>]
|
|
4
|
-
|
|
5
|
-
options:
|
|
6
|
-
-n <N> number of trailing lines to show (default: 20)
|
|
7
|
-
|
|
8
|
-
Tails the latest /tmp/funnel/events/*.jsonl file. Exit with SIGINT.
|
|
9
|
-
Output is formatted as YAML.
|
|
10
|
-
|
|
11
|
-
examples:
|
|
12
|
-
funnel gateway logs
|
|
13
|
-
funnel gateway logs -n 100`
|
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
import { readdirSync } from "node:fs"
|
|
2
|
-
import { join } from "node:path"
|
|
3
|
-
import { stringify } from "yaml"
|
|
4
|
-
import { z } from "zod"
|
|
5
|
-
import { factory } from "@/factory"
|
|
6
|
-
import { logger } from "@/modules/logger"
|
|
7
|
-
import { zValidator } from "@/modules/router/validator"
|
|
8
|
-
import { help } from "@/routes/gateway/logs.help"
|
|
9
|
-
|
|
10
|
-
const tryParseJson = (s: string): unknown => {
|
|
11
|
-
try {
|
|
12
|
-
return JSON.parse(s)
|
|
13
|
-
} catch {
|
|
14
|
-
return null
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export const gatewayLogsHandler = factory.createHandlers(
|
|
19
|
-
zValidator(
|
|
20
|
-
"query",
|
|
21
|
-
z.object({
|
|
22
|
-
n: z.string().optional(),
|
|
23
|
-
}),
|
|
24
|
-
help,
|
|
25
|
-
),
|
|
26
|
-
async (c) => {
|
|
27
|
-
const query = c.req.valid("query")
|
|
28
|
-
const funnel = c.var.funnel
|
|
29
|
-
const logDir = funnel.gateway.getLogDir()
|
|
30
|
-
|
|
31
|
-
const files = readdirSync(logDir)
|
|
32
|
-
.filter((name) => name.endsWith(".jsonl"))
|
|
33
|
-
.sort()
|
|
34
|
-
|
|
35
|
-
if (files.length === 0) {
|
|
36
|
-
return c.text("no logs")
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const latestFile = join(logDir, files[files.length - 1]!)
|
|
40
|
-
const lineCount = query.n ? Number(query.n) : 20
|
|
41
|
-
|
|
42
|
-
const tail = Bun.spawn(["tail", "-f", "-n", String(lineCount), latestFile], {
|
|
43
|
-
stdout: "pipe",
|
|
44
|
-
stderr: "inherit",
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
const forward = (signal: "SIGINT" | "SIGTERM") => {
|
|
48
|
-
tail.kill(signal)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
process.on("SIGINT", () => forward("SIGINT"))
|
|
52
|
-
process.on("SIGTERM", () => forward("SIGTERM"))
|
|
53
|
-
|
|
54
|
-
const reader = tail.stdout.getReader()
|
|
55
|
-
const decoder = new TextDecoder()
|
|
56
|
-
let buffer = ""
|
|
57
|
-
|
|
58
|
-
logger.info("gateway.logs tail start", { file: latestFile })
|
|
59
|
-
|
|
60
|
-
while (true) {
|
|
61
|
-
const result = await reader.read()
|
|
62
|
-
|
|
63
|
-
if (result.done) break
|
|
64
|
-
|
|
65
|
-
buffer += decoder.decode(result.value, { stream: true })
|
|
66
|
-
|
|
67
|
-
const lines = buffer.split("\n")
|
|
68
|
-
buffer = lines.pop() ?? ""
|
|
69
|
-
|
|
70
|
-
for (const line of lines) {
|
|
71
|
-
if (!line.trim()) continue
|
|
72
|
-
|
|
73
|
-
const entry = tryParseJson(line) as {
|
|
74
|
-
timestamp: string
|
|
75
|
-
eventType: string
|
|
76
|
-
meta?: unknown
|
|
77
|
-
content: string
|
|
78
|
-
} | null
|
|
79
|
-
|
|
80
|
-
if (!entry) {
|
|
81
|
-
process.stdout.write(`${line}\n`)
|
|
82
|
-
continue
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const parsedContent = tryParseJson(entry.content) ?? entry.content
|
|
86
|
-
const output = {
|
|
87
|
-
time: entry.timestamp,
|
|
88
|
-
type: entry.eventType,
|
|
89
|
-
...(entry.meta ? { meta: entry.meta } : {}),
|
|
90
|
-
content: parsedContent,
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
process.stdout.write(`---\n${stringify(output)}`)
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
await tail.exited
|
|
98
|
-
process.exit(0)
|
|
99
|
-
},
|
|
100
|
-
)
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
export const help = `funnel gateway restart — restart the gateway
|
|
2
|
-
|
|
3
|
-
usage: funnel gateway restart [--no-caffeine]
|
|
4
|
-
|
|
5
|
-
Stops the running process then starts it again in background.
|
|
6
|
-
On macOS wraps with caffeinate -i by default. Use --no-caffeine to disable.
|
|
7
|
-
|
|
8
|
-
examples:
|
|
9
|
-
funnel gateway restart
|
|
10
|
-
funnel gateway restart --no-caffeine`
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { factory } from "@/factory"
|
|
2
|
-
import { gatewayGroupHandler } from "@/routes/gateway/group"
|
|
3
|
-
import { gatewayLogsHandler } from "@/routes/gateway/logs"
|
|
4
|
-
import { gatewayRestartHandler } from "@/routes/gateway/restart"
|
|
5
|
-
import { gatewayRunHandler } from "@/routes/gateway/run"
|
|
6
|
-
import { gatewayStartHandler } from "@/routes/gateway/start"
|
|
7
|
-
import { gatewayStatusHandler } from "@/routes/gateway/status"
|
|
8
|
-
import { gatewayStopHandler } from "@/routes/gateway/stop"
|
|
9
|
-
|
|
10
|
-
export const gatewayRoutes = factory
|
|
11
|
-
.createApp()
|
|
12
|
-
.get("/", ...gatewayGroupHandler)
|
|
13
|
-
.get("/status", ...gatewayStatusHandler)
|
|
14
|
-
.get("/start", ...gatewayStartHandler)
|
|
15
|
-
.get("/stop", ...gatewayStopHandler)
|
|
16
|
-
.get("/restart", ...gatewayRestartHandler)
|
|
17
|
-
.get("/run", ...gatewayRunHandler)
|
|
18
|
-
.get("/logs", ...gatewayLogsHandler)
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export const help = `funnel gateway run — run the gateway in foreground
|
|
2
|
-
|
|
3
|
-
usage: funnel gateway run [--no-caffeine]
|
|
4
|
-
|
|
5
|
-
For developers. The process is tied to the current terminal and exits on SIGINT / SIGTERM.
|
|
6
|
-
On macOS wraps with caffeinate -i by default. Use --no-caffeine to disable.
|
|
7
|
-
|
|
8
|
-
For normal usage prefer funnel gateway start.
|
|
9
|
-
|
|
10
|
-
examples:
|
|
11
|
-
funnel gateway run
|
|
12
|
-
funnel gateway run --no-caffeine`
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { resolve } from "node:path"
|
|
2
|
-
import { z } from "zod"
|
|
3
|
-
import { factory } from "@/factory"
|
|
4
|
-
import { zValidator } from "@/modules/router/validator"
|
|
5
|
-
import { help } from "@/routes/gateway/run.help"
|
|
6
|
-
|
|
7
|
-
export const gatewayRunHandler = factory.createHandlers(
|
|
8
|
-
zValidator(
|
|
9
|
-
"query",
|
|
10
|
-
z.object({
|
|
11
|
-
"no-caffeine": z.string().optional(),
|
|
12
|
-
}),
|
|
13
|
-
help,
|
|
14
|
-
),
|
|
15
|
-
async (c) => {
|
|
16
|
-
const query = c.req.valid("query")
|
|
17
|
-
const gatewayScript = resolve(import.meta.dir, "../../modules/gateway/daemon.ts")
|
|
18
|
-
|
|
19
|
-
const useCaffeinate = query["no-caffeine"] !== "true" && process.platform === "darwin"
|
|
20
|
-
const command = useCaffeinate
|
|
21
|
-
? ["caffeinate", "-i", "bun", gatewayScript]
|
|
22
|
-
: ["bun", gatewayScript]
|
|
23
|
-
|
|
24
|
-
const proc = Bun.spawn(command, {
|
|
25
|
-
stdio: ["inherit", "inherit", "inherit"],
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
process.on("SIGINT", () => proc.kill("SIGINT"))
|
|
29
|
-
process.on("SIGTERM", () => proc.kill("SIGTERM"))
|
|
30
|
-
|
|
31
|
-
const exitCode = await proc.exited
|
|
32
|
-
|
|
33
|
-
process.exit(exitCode)
|
|
34
|
-
},
|
|
35
|
-
)
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export const help = `funnel gateway start — start the gateway in background
|
|
2
|
-
|
|
3
|
-
usage: funnel gateway start [--no-caffeine]
|
|
4
|
-
|
|
5
|
-
Daemonized with nohup, so it keeps running after the terminal is closed.
|
|
6
|
-
On macOS wraps the process with caffeinate -i by default to prevent idle sleep.
|
|
7
|
-
Use --no-caffeine to disable caffeinate.
|
|
8
|
-
|
|
9
|
-
port: 9742 (override via FUNNEL_PORT)
|
|
10
|
-
pid: ~/.funnel/gateway.pid
|
|
11
|
-
log: /tmp/funnel/gateway.log
|
|
12
|
-
|
|
13
|
-
examples:
|
|
14
|
-
funnel gateway start
|
|
15
|
-
funnel gateway start --no-caffeine`
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { z } from "zod"
|
|
2
|
-
import { factory } from "@/factory"
|
|
3
|
-
import { zValidator } from "@/modules/router/validator"
|
|
4
|
-
import { help } from "@/routes/gateway/start.help"
|
|
5
|
-
|
|
6
|
-
export const gatewayStartHandler = factory.createHandlers(
|
|
7
|
-
zValidator(
|
|
8
|
-
"query",
|
|
9
|
-
z.object({
|
|
10
|
-
"no-caffeine": z.string().optional(),
|
|
11
|
-
}),
|
|
12
|
-
help,
|
|
13
|
-
),
|
|
14
|
-
async (c) => {
|
|
15
|
-
const query = c.req.valid("query")
|
|
16
|
-
const funnel = c.var.funnel
|
|
17
|
-
|
|
18
|
-
if (funnel.gateway.isRunning()) {
|
|
19
|
-
const status = funnel.gateway.getStatus()
|
|
20
|
-
|
|
21
|
-
return c.text(`funnel gateway: already running (pid ${status.pid})`)
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
const started = await funnel.gateway.start({
|
|
25
|
-
caffeinate: query["no-caffeine"] !== "true",
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
return started
|
|
29
|
-
? c.text("funnel gateway: started")
|
|
30
|
-
: c.text("funnel gateway: failed to start", 500)
|
|
31
|
-
},
|
|
32
|
-
)
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { z } from "zod"
|
|
2
|
-
import { factory } from "@/factory"
|
|
3
|
-
import { zValidator } from "@/modules/router/validator"
|
|
4
|
-
import { help } from "@/routes/gateway/status.help"
|
|
5
|
-
|
|
6
|
-
export const gatewayStatusHandler = factory.createHandlers(
|
|
7
|
-
zValidator("query", z.object({}), help),
|
|
8
|
-
async (c) => {
|
|
9
|
-
const funnel = c.var.funnel
|
|
10
|
-
const status = funnel.gateway.getStatus()
|
|
11
|
-
|
|
12
|
-
if (!status.running) {
|
|
13
|
-
return c.text("funnel gateway: not running", 503)
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const res = await fetch(`http://localhost:${status.port}/health`).catch(() => null)
|
|
17
|
-
|
|
18
|
-
if (!res) {
|
|
19
|
-
return c.text(`funnel gateway: running (pid ${status.pid}) — health check failed`)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const health = (await res.json()) as Record<string, unknown>
|
|
23
|
-
|
|
24
|
-
return c.text(
|
|
25
|
-
`funnel gateway: running (pid ${status.pid})\n port: ${status.port}\n clients: ${health.clients ?? 0}`,
|
|
26
|
-
)
|
|
27
|
-
},
|
|
28
|
-
)
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { z } from "zod"
|
|
2
|
-
import { factory } from "@/factory"
|
|
3
|
-
import { zValidator } from "@/modules/router/validator"
|
|
4
|
-
import { help } from "@/routes/gateway/stop.help"
|
|
5
|
-
|
|
6
|
-
export const gatewayStopHandler = factory.createHandlers(
|
|
7
|
-
zValidator("query", z.object({}), help),
|
|
8
|
-
async (c) => {
|
|
9
|
-
const funnel = c.var.funnel
|
|
10
|
-
|
|
11
|
-
if (!funnel.gateway.isRunning()) {
|
|
12
|
-
return c.text("funnel gateway: no running process")
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const stopped = await funnel.gateway.stop()
|
|
16
|
-
|
|
17
|
-
return stopped
|
|
18
|
-
? c.text("funnel gateway: stopped")
|
|
19
|
-
: c.text("funnel gateway: failed to stop", 500)
|
|
20
|
-
},
|
|
21
|
-
)
|