@frehilm/ordna-web 0.1.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 FreHilm
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,93 @@
1
+ # @frehilm/ordna-web
2
+
3
+ A local Kanban for [Ordna](../../README.md) in your browser. Hono server + prebuilt React SPA. Re-exports the entire [@frehilm/ordna-core](../core/README.md) API — no separate core install needed.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ pnpm add @frehilm/ordna-web
9
+ ```
10
+
11
+ If you also have `@frehilm/ordna-cli` globally, just run `ordna web` — it delegates here.
12
+
13
+ ## Run standalone
14
+
15
+ ```bash
16
+ ordna web
17
+ # → opens http://127.0.0.1:7420 in your browser
18
+ ```
19
+
20
+ Flags: `--port <n>`, `--host <h>`, `--no-open`.
21
+
22
+ ## Run programmatically
23
+
24
+ ```ts
25
+ import { runWeb } from "@frehilm/ordna-web";
26
+
27
+ const handle = await runWeb({
28
+ cwd: "/path/to/repo",
29
+ port: 0, // OS-assigned
30
+ openBrowser: false,
31
+ agentHook: { // optional
32
+ url: "http://127.0.0.1:9999/agent",
33
+ label: "Claude",
34
+ headers: { "X-Token": "..." },
35
+ },
36
+ });
37
+
38
+ console.log(`Listening on http://127.0.0.1:${handle.port}`);
39
+ await handle.close(); // graceful shutdown
40
+ ```
41
+
42
+ ## Web UI
43
+
44
+ - **Topbar**: brand, tasks-dir crumb, search, theme toggle, shortcuts, primary `+ New task`.
45
+ - **Sidebar**: Views (All + per-status + Archived) · Priority · Tags. Counts are live.
46
+ - **Subbar**: current view title and visible/total counts.
47
+ - **Board**: columns per configured status, drag-and-drop with a rotated floating overlay and optimistic updates (rolls back on server rejection).
48
+ - **Cards**: id, priority chip, title, tag chips (hashed colors), bottom meta (assignee + AC progress). Hover reveals Edit / Delete action buttons. Click opens a view-mode modal.
49
+ - **Modal**: read-only by default. Press **Edit** for in-place editing — title, status, priority, assignee, tags (chip input), depends_on (chip input), structured acceptance-criteria checklist, section textareas. Save / Cancel.
50
+ - **Theme**: light / dark toggle, persisted in `localStorage`.
51
+
52
+ ## Keyboard shortcuts
53
+
54
+ | Key | Action |
55
+ |----------------|---------------------------------|
56
+ | `⌘/Ctrl + K` | Command palette |
57
+ | `n` | New task |
58
+ | `/` | Focus search |
59
+ | `t` | Toggle theme |
60
+ | `?` | Toggle shortcut cheatsheet |
61
+ | `Esc` | Close modal / overlay |
62
+
63
+ ## Live updates
64
+
65
+ Everything is over WebSocket. Changes from the TUI, CLI, an editor, an agent script, or another browser tab show up instantly. The web process is local — nothing leaves the machine.
66
+
67
+ ## REST API
68
+
69
+ If your IDE wants to talk to the running server directly:
70
+
71
+ ```
72
+ GET /api/config Returns the resolved OrdnaConfig + agentHook info
73
+ GET /api/tasks All tasks
74
+ GET /api/tasks/:id One task
75
+ POST /api/tasks Create
76
+ PATCH /api/tasks/:id Update
77
+ POST /api/tasks/:id/move Change status (depends_on gate)
78
+ DELETE /api/tasks/:id Delete
79
+ POST /api/tasks/:id/agent Forward to ORDNA_AGENT_HOOK_URL (501 if unset)
80
+ WS /ws Broadcasts {added | changed | removed}
81
+ ```
82
+
83
+ Bodies are JSON; `Task` shape comes from [@frehilm/ordna-core](../core/README.md#api).
84
+
85
+ ## Configuration
86
+
87
+ Inherits from [@frehilm/ordna-core](../core/README.md#configuration). The relevant key for this package is `webPort` (default `7420`).
88
+
89
+ The agent hook is configured via env (`ORDNA_AGENT_HOOK_URL`, `ORDNA_AGENT_HOOK_LABEL`, `ORDNA_AGENT_HOOK_HEADERS`) **or** programmatically via the `agentHook` option on `runWeb`. The programmatic option wins. Pass `null` to disable explicitly.
90
+
91
+ ## License
92
+
93
+ MIT — see [LICENSE](../../LICENSE).
@@ -0,0 +1,6 @@
1
+ export * from "@frehilm/ordna-core";
2
+ export { runWeb } from "./server/start.js";
3
+ export type { RunWebOptions, RunWebHandle } from "./server/start.js";
4
+ export type { AgentHookConfig, AgentContext } from "./server/agent.js";
5
+ export { loadAgentHook, postAgent } from "./server/agent.js";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AAEpC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACrE,YAAY,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export * from "@frehilm/ordna-core";
2
+ export { runWeb } from "./server/start.js";
3
+ export { loadAgentHook, postAgent } from "./server/agent.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AAEpC,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAG3C,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,18 @@
1
+ import type { Task } from "@frehilm/ordna-core";
2
+ export interface AgentHookConfig {
3
+ url: string;
4
+ label: string;
5
+ headers: Record<string, string>;
6
+ }
7
+ export declare function loadAgentHook(): AgentHookConfig | null;
8
+ export interface AgentContext {
9
+ tasksDir: string;
10
+ cwd: string;
11
+ schema: string;
12
+ }
13
+ export declare function postAgent(hook: AgentHookConfig, task: Task, context: AgentContext): Promise<{
14
+ ok: boolean;
15
+ status: number;
16
+ body: string;
17
+ }>;
18
+ //# sourceMappingURL=agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/server/agent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAEhD,MAAM,WAAW,eAAe;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,wBAAgB,aAAa,IAAI,eAAe,GAAG,IAAI,CAmBtD;AAED,MAAM,WAAW,YAAY;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,SAAS,CAC9B,IAAI,EAAE,eAAe,EACrB,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,YAAY,GACnB,OAAO,CAAC;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,CAWxD"}
@@ -0,0 +1,36 @@
1
+ export function loadAgentHook() {
2
+ const url = process.env.ORDNA_AGENT_HOOK_URL;
3
+ if (!url)
4
+ return null;
5
+ const label = process.env.ORDNA_AGENT_HOOK_LABEL ?? "Agent";
6
+ let headers = {};
7
+ const rawHeaders = process.env.ORDNA_AGENT_HOOK_HEADERS;
8
+ if (rawHeaders) {
9
+ try {
10
+ const parsed = JSON.parse(rawHeaders);
11
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
12
+ for (const [k, v] of Object.entries(parsed)) {
13
+ if (typeof v === "string")
14
+ headers[k] = v;
15
+ }
16
+ }
17
+ }
18
+ catch {
19
+ // Malformed headers are ignored so the hook still works.
20
+ }
21
+ }
22
+ return { url, label, headers };
23
+ }
24
+ export async function postAgent(hook, task, context) {
25
+ const res = await fetch(hook.url, {
26
+ method: "POST",
27
+ headers: {
28
+ "Content-Type": "application/json",
29
+ ...hook.headers,
30
+ },
31
+ body: JSON.stringify({ action: "agent", task, context }),
32
+ });
33
+ const body = await res.text();
34
+ return { ok: res.ok, status: res.status, body };
35
+ }
36
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/server/agent.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,aAAa;IAC5B,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;IAC7C,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,OAAO,CAAC;IAC5D,IAAI,OAAO,GAA2B,EAAE,CAAC;IACzC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC;IACxD,IAAI,UAAU,EAAE,CAAC;QAChB,IAAI,CAAC;YACJ,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAY,CAAC;YACjD,IAAI,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBACpE,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAiC,CAAC,EAAE,CAAC;oBACxE,IAAI,OAAO,CAAC,KAAK,QAAQ;wBAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;gBAC3C,CAAC;YACF,CAAC;QACF,CAAC;QAAC,MAAM,CAAC;YACR,yDAAyD;QAC1D,CAAC;IACF,CAAC;IACD,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AAChC,CAAC;AAQD,MAAM,CAAC,KAAK,UAAU,SAAS,CAC9B,IAAqB,EACrB,IAAU,EACV,OAAqB;IAErB,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE;QACjC,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACR,cAAc,EAAE,kBAAkB;YAClC,GAAG,IAAI,CAAC,OAAO;SACf;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;KACxD,CAAC,CAAC;IACH,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;IAC9B,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC;AACjD,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=dev.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../src/server/dev.ts"],"names":[],"mappings":""}
@@ -0,0 +1,11 @@
1
+ import { runWeb } from "./start.js";
2
+ const handle = await runWeb({ openBrowser: false });
3
+ console.log(`Ordna server running on http://127.0.0.1:${handle.port}`);
4
+ console.log("Vite dev server proxies /api and /ws here. Run `pnpm dev:client` in another shell.");
5
+ const shutdown = async () => {
6
+ await handle.close();
7
+ process.exit(0);
8
+ };
9
+ process.on("SIGINT", shutdown);
10
+ process.on("SIGTERM", shutdown);
11
+ //# sourceMappingURL=dev.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev.js","sourceRoot":"","sources":["../../src/server/dev.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEpC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC,CAAC;AACpD,OAAO,CAAC,GAAG,CAAC,4CAA4C,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;AACvE,OAAO,CAAC,GAAG,CAAC,oFAAoF,CAAC,CAAC;AAElG,MAAM,QAAQ,GAAG,KAAK,IAAmB,EAAE;IAC1C,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC,CAAC;AACF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AAC/B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { type StoreContext } from "@frehilm/ordna-core";
2
+ import { Hono } from "hono";
3
+ import { type AgentHookConfig } from "./agent.js";
4
+ export declare function buildApiRoutes(ctx: StoreContext, agentHook: AgentHookConfig | null): Hono;
5
+ //# sourceMappingURL=routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/server/routes.ts"],"names":[],"mappings":"AAAA,OAAO,EAMN,KAAK,YAAY,EAEjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAE5B,OAAO,EAAE,KAAK,eAAe,EAAa,MAAM,YAAY,CAAC;AAE7D,wBAAgB,cAAc,CAC7B,GAAG,EAAE,YAAY,EACjB,SAAS,EAAE,eAAe,GAAG,IAAI,GAC/B,IAAI,CA2FN"}
@@ -0,0 +1,83 @@
1
+ import { createTask, deleteTask, getTask, listTasks, moveTask, updateTask, } from "@frehilm/ordna-core";
2
+ import { Hono } from "hono";
3
+ import { toWireTask } from "../shared/types.js";
4
+ import { postAgent } from "./agent.js";
5
+ export function buildApiRoutes(ctx, agentHook) {
6
+ const api = new Hono();
7
+ api.get("/config", (c) => c.json({
8
+ ...ctx.config,
9
+ agentHook: agentHook ? { enabled: true, label: agentHook.label } : null,
10
+ }));
11
+ api.get("/tasks", async (c) => {
12
+ const tasks = await listTasks(ctx);
13
+ return c.json(tasks.map(toWireTask));
14
+ });
15
+ api.get("/tasks/:id", async (c) => {
16
+ const task = await getTask(c.req.param("id"), ctx);
17
+ if (!task)
18
+ return c.json({ error: "not found" }, 404);
19
+ return c.json(toWireTask(task));
20
+ });
21
+ api.post("/tasks", async (c) => {
22
+ const body = (await c.req.json());
23
+ if (!body.title || body.title.trim().length === 0) {
24
+ return c.json({ error: "title is required" }, 400);
25
+ }
26
+ const task = await createTask(body, ctx);
27
+ return c.json(toWireTask(task), 201);
28
+ });
29
+ api.patch("/tasks/:id", async (c) => {
30
+ const id = c.req.param("id");
31
+ const patch = await c.req.json();
32
+ try {
33
+ const task = await updateTask(id, patch, ctx);
34
+ return c.json(toWireTask(task));
35
+ }
36
+ catch (error) {
37
+ return c.json({ error: error.message }, 400);
38
+ }
39
+ });
40
+ api.post("/tasks/:id/move", async (c) => {
41
+ const id = c.req.param("id");
42
+ const { status } = (await c.req.json());
43
+ try {
44
+ const task = await moveTask(id, status, ctx);
45
+ return c.json(toWireTask(task));
46
+ }
47
+ catch (error) {
48
+ return c.json({ error: error.message }, 400);
49
+ }
50
+ });
51
+ api.post("/tasks/:id/agent", async (c) => {
52
+ if (!agentHook)
53
+ return c.json({ error: "agent hook not configured" }, 501);
54
+ const task = await getTask(c.req.param("id"), ctx);
55
+ if (!task)
56
+ return c.json({ error: "not found" }, 404);
57
+ try {
58
+ const result = await postAgent(agentHook, task, {
59
+ tasksDir: ctx.config.tasksDir,
60
+ cwd: ctx.cwd,
61
+ schema: ctx.config.schema,
62
+ });
63
+ if (!result.ok) {
64
+ return c.json({ error: result.body || `hook returned ${result.status}` }, 502);
65
+ }
66
+ return c.json({ ok: true });
67
+ }
68
+ catch (err) {
69
+ return c.json({ error: err.message }, 502);
70
+ }
71
+ });
72
+ api.delete("/tasks/:id", async (c) => {
73
+ try {
74
+ await deleteTask(c.req.param("id"), ctx);
75
+ return c.body(null, 204);
76
+ }
77
+ catch (error) {
78
+ return c.json({ error: error.message }, 404);
79
+ }
80
+ });
81
+ return api;
82
+ }
83
+ //# sourceMappingURL=routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/server/routes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { type StoreContext } from "@frehilm/ordna-core";
2
+ import { type AgentHookConfig } from "./agent.js";
3
+ export interface RunWebOptions {
4
+ cwd?: string;
5
+ port?: number;
6
+ host?: string;
7
+ openBrowser?: boolean;
8
+ clientDir?: string;
9
+ /**
10
+ * Programmatic agent hook config. Overrides ORDNA_AGENT_HOOK_* env vars.
11
+ * Pass `null` to disable the hook explicitly even if env vars are set.
12
+ */
13
+ agentHook?: AgentHookConfig | null;
14
+ }
15
+ export interface RunWebHandle {
16
+ port: number;
17
+ close: () => Promise<void>;
18
+ context: StoreContext;
19
+ }
20
+ export declare function runWeb(options?: RunWebOptions): Promise<RunWebHandle>;
21
+ //# sourceMappingURL=start.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/server/start.ts"],"names":[],"mappings":"AAGA,OAAO,EAAmD,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAKzG,OAAO,EAAE,KAAK,eAAe,EAAiB,MAAM,YAAY,CAAC;AAIjE,MAAM,WAAW,aAAa;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,SAAS,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,YAAY;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,OAAO,EAAE,YAAY,CAAC;CACtB;AAgBD,wBAAsB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,YAAY,CAAC,CA8G/E"}
@@ -0,0 +1,114 @@
1
+ import { serveStatic } from "@hono/node-server/serve-static";
2
+ import { serve } from "@hono/node-server";
3
+ import { createNodeWebSocket } from "@hono/node-ws";
4
+ import { createContext as createStoreContext, watchTasks } from "@frehilm/ordna-core";
5
+ import { existsSync } from "node:fs";
6
+ import { dirname, join, resolve } from "node:path";
7
+ import { fileURLToPath } from "node:url";
8
+ import { Hono } from "hono";
9
+ import { loadAgentHook } from "./agent.js";
10
+ import { buildApiRoutes } from "./routes.js";
11
+ import { toWireTask } from "../shared/types.js";
12
+ const __dirname = dirname(fileURLToPath(import.meta.url));
13
+ function resolveClientDir(clientDir) {
14
+ const candidates = [
15
+ clientDir,
16
+ resolve(__dirname, "../../dist-client"),
17
+ resolve(__dirname, "../../../dist-client"),
18
+ ].filter((p) => typeof p === "string");
19
+ for (const dir of candidates) {
20
+ if (existsSync(join(dir, "index.html")))
21
+ return dir;
22
+ }
23
+ return null;
24
+ }
25
+ export async function runWeb(options = {}) {
26
+ const ctx = createStoreContext(options.cwd);
27
+ const port = options.port ?? ctx.config.webPort;
28
+ const host = options.host ?? "127.0.0.1";
29
+ const app = new Hono();
30
+ const { injectWebSocket, upgradeWebSocket } = createNodeWebSocket({ app });
31
+ const agentHook = options.agentHook === null
32
+ ? null
33
+ : options.agentHook ?? loadAgentHook();
34
+ app.route("/api", buildApiRoutes(ctx, agentHook));
35
+ const clients = new Set();
36
+ const broadcast = (event) => {
37
+ const data = JSON.stringify(event);
38
+ for (const client of clients) {
39
+ try {
40
+ client.send(data);
41
+ }
42
+ catch {
43
+ // Drop broken clients silently; node-ws handles lifecycle via close events.
44
+ }
45
+ }
46
+ };
47
+ const unsubscribe = watchTasks(ctx, (event) => {
48
+ if (event.type === "removed") {
49
+ const id = event.filePath.split("/").pop()?.replace(/\.md$/, "") ?? event.filePath;
50
+ broadcast({ type: "removed", id });
51
+ }
52
+ else {
53
+ broadcast({ type: event.type, task: toWireTask(event.task) });
54
+ }
55
+ });
56
+ app.get("/ws", upgradeWebSocket(() => ({
57
+ onOpen(_evt, ws) {
58
+ const client = { send: (data) => ws.send(data) };
59
+ clients.add(client);
60
+ ws._ordnaClient = client;
61
+ },
62
+ onClose(_evt, ws) {
63
+ const client = ws._ordnaClient;
64
+ if (client)
65
+ clients.delete(client);
66
+ },
67
+ })));
68
+ const clientDir = resolveClientDir(options.clientDir);
69
+ if (clientDir) {
70
+ app.use("/*", serveStatic({
71
+ root: clientDir,
72
+ rewriteRequestPath: (path) => (path === "/" ? "/index.html" : path),
73
+ }));
74
+ app.get("*", async (c) => {
75
+ const indexPath = join(clientDir, "index.html");
76
+ const fs = await import("node:fs/promises");
77
+ const html = await fs.readFile(indexPath, "utf8");
78
+ return c.html(html);
79
+ });
80
+ }
81
+ else {
82
+ app.get("/", (c) => c.text("Ordna server is running. Client bundle missing — run `pnpm --filter @frehilm/ordna-web build:client`."));
83
+ }
84
+ const server = serve({ fetch: app.fetch, port, hostname: host });
85
+ injectWebSocket(server);
86
+ await new Promise((resolve) => {
87
+ if (server.listening)
88
+ resolve();
89
+ else
90
+ server.once("listening", () => resolve());
91
+ });
92
+ const address = server.address();
93
+ const actualPort = typeof address === "object" && address !== null ? address.port : port;
94
+ if (options.openBrowser) {
95
+ const url = `http://${host}:${actualPort}`;
96
+ const { spawn } = await import("node:child_process");
97
+ const opener = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
98
+ try {
99
+ spawn(opener, [url], { stdio: "ignore", detached: true }).unref();
100
+ }
101
+ catch {
102
+ // Best-effort; ignore.
103
+ }
104
+ }
105
+ const close = async () => {
106
+ await unsubscribe();
107
+ const s = server;
108
+ s.closeIdleConnections?.();
109
+ s.closeAllConnections?.();
110
+ await new Promise((r) => s.close(() => r()));
111
+ };
112
+ return { port: actualPort, close, context: ctx };
113
+ }
114
+ //# sourceMappingURL=start.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/server/start.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { OrdnaConfig, Task, TaskCreateInput, TaskUpdateInput } from "@frehilm/ordna-core";
2
+ export type { OrdnaConfig, Task, TaskCreateInput, TaskUpdateInput };
3
+ export interface AgentHookInfo {
4
+ enabled: boolean;
5
+ label: string;
6
+ }
7
+ export type UiConfig = OrdnaConfig & {
8
+ agentHook: AgentHookInfo | null;
9
+ };
10
+ export type WireTask = Omit<Task, "rawContent">;
11
+ export type WsEvent = {
12
+ type: "added";
13
+ task: WireTask;
14
+ } | {
15
+ type: "changed";
16
+ task: WireTask;
17
+ } | {
18
+ type: "removed";
19
+ id: string;
20
+ };
21
+ export declare function toWireTask(task: Task): WireTask;
22
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/shared/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE/F,YAAY,EAAE,WAAW,EAAE,IAAI,EAAE,eAAe,EAAE,eAAe,EAAE,CAAC;AAEpE,MAAM,WAAW,aAAa;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,QAAQ,GAAG,WAAW,GAAG;IACpC,SAAS,EAAE,aAAa,GAAG,IAAI,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;AAEhD,MAAM,MAAM,OAAO,GAChB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnC,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,QAAQ,CAG/C"}
@@ -0,0 +1,5 @@
1
+ export function toWireTask(task) {
2
+ const { rawContent: _rawContent, ...rest } = task;
3
+ return rest;
4
+ }
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/shared/types.ts"],"names":[],"mappings":"AAoBA,MAAM,UAAU,UAAU,CAAC,IAAU;IACpC,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC;IAClD,OAAO,IAAI,CAAC;AACb,CAAC"}