@maintainer-pro/ai-server 0.1.2 → 0.1.3

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 CHANGED
@@ -11,12 +11,12 @@ It is **not** what you ship as the production website. Without this process, `lo
11
11
  ## Quick start
12
12
 
13
13
  ```bash
14
- npx --yes @maintainer-pro/ai-server
14
+ npx --yes @maintainer-pro/ai-server@latest
15
15
  ```
16
16
 
17
17
  Put a `.env` in the current directory (from the admin setup guide or by hand). CLI flags override env.
18
18
 
19
- Requires **Node.js 22+**, [`@maintainer-pro/ai-ui`](https://www.npmjs.com/package/@maintainer-pro/ai-ui) next to this package (for `/ai-ui.iife.js`), and one authenticated coding-agent CLI.
19
+ Requires **Node.js 22+** and one authenticated coding-agent CLI. `npx` also installs [`@maintainer-pro/ai-ui`](https://www.npmjs.com/package/@maintainer-pro/ai-ui) so `GET /ai-ui.iife.js` is available.
20
20
 
21
21
  ## Routes
22
22
 
@@ -25,7 +25,7 @@ Requires **Node.js 22+**, [`@maintainer-pro/ai-ui`](https://www.npmjs.com/packag
25
25
  | `GET` / `POST /api/chat` | Chat (agent + Maintainer Pro store) |
26
26
  | `WS /api/ws` (also `/ws`) | Live AI events (`subscribe`, `chat.run`, `message.created`) |
27
27
  | `GET /embed-config.js` | `window.__MAINTAINER_PRO__` — `aiServerUrl`, `apiUrl`, `aiServerWsUrl`, client keys |
28
- | `GET /ai-ui.iife.js` | Embed widget from `node_modules/@maintainer-pro/ai-ui` (unless a file exists in `AI_SERVER_UI`) |
28
+ | `GET /ai-ui.iife.js` | Embed widget from `@maintainer-pro/ai-ui` (unless a file exists in `AI_SERVER_UI`) |
29
29
  | other paths | Static files from `AI_SERVER_UI` |
30
30
 
31
31
  A copied `ai-ui.iife.js` in the UI folder is served first and will not update when you `npm update @maintainer-pro/ai-ui`. Prefer the `node_modules` copy, then restart this process.
@@ -47,7 +47,7 @@ A copied `ai-ui.iife.js` in the UI folder is served first and will not update wh
47
47
  | `AI_SERVER_PRODUCT_DESCRIPTION` | Optional product text for the agent prompt |
48
48
 
49
49
  ```bash
50
- npx --yes @maintainer-pro/ai-server --port 3100 --ui . --workspace .
50
+ npx --yes @maintainer-pro/ai-server@latest --port 3100 --ui . --workspace .
51
51
  ```
52
52
 
53
53
  ## Related packages
package/bin/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * npx --yes @maintainer-pro/ai-server
3
+ * npx --yes @maintainer-pro/ai-server@latest
4
4
  */
5
5
  import "../src/server.mjs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maintainer-pro/ai-server",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Node HTTP server for Maintainer Pro chat. Uses @maintainer-pro/ai-cli to talk to coding agents.",
5
5
  "keywords": [
6
6
  "maintainer-pro",
@@ -27,6 +27,7 @@
27
27
  },
28
28
  "dependencies": {
29
29
  "@maintainer-pro/ai-cli": "^0.1.5",
30
+ "@maintainer-pro/ai-ui": "^0.2.3",
30
31
  "ws": "^8.21.3"
31
32
  },
32
33
  "engines": {
package/src/server.mjs CHANGED
@@ -8,6 +8,7 @@
8
8
  import { randomUUID } from "node:crypto";
9
9
  import fs from "node:fs";
10
10
  import http from "node:http";
11
+ import { createRequire } from "node:module";
11
12
  import path from "node:path";
12
13
  import { fileURLToPath } from "node:url";
13
14
  import {
@@ -63,8 +64,8 @@ if (args.help) {
63
64
  console.log(`Maintainer Pro AI server
64
65
 
65
66
  Usage:
66
- npx @maintainer-pro/ai-server
67
- npx @maintainer-pro/ai-server --port 3000 --ui . --workspace .
67
+ npx @maintainer-pro/ai-server@latest
68
+ npx @maintainer-pro/ai-server@latest --port 3000 --ui . --workspace .
68
69
 
69
70
  Flags override .env. Preferred config is env (from the admin setup guide).
70
71
 
@@ -122,14 +123,25 @@ function resolveUiFile(uiDir, pathname) {
122
123
  return null;
123
124
  }
124
125
 
126
+ function tryResolveIife(from) {
127
+ try {
128
+ return createRequire(from).resolve("@maintainer-pro/ai-ui");
129
+ } catch {
130
+ return null;
131
+ }
132
+ }
133
+
125
134
  function findIife() {
126
135
  const here = path.dirname(fileURLToPath(import.meta.url));
136
+ const cwdPkg = path.join(process.cwd(), "package.json");
127
137
  const candidates = [
138
+ tryResolveIife(import.meta.url),
139
+ fs.existsSync(cwdPkg) ? tryResolveIife(cwdPkg) : null,
128
140
  path.resolve(process.cwd(), "node_modules/@maintainer-pro/ai-ui/dist/ai-ui.iife.js"),
129
141
  path.resolve(here, "../../ai-ui/dist/ai-ui.iife.js"),
130
142
  path.resolve(here, "../../../node_modules/@maintainer-pro/ai-ui/dist/ai-ui.iife.js"),
131
143
  ];
132
- return candidates.find((file) => fs.existsSync(file)) ?? null;
144
+ return candidates.find((file) => file && fs.existsSync(file)) ?? null;
133
145
  }
134
146
 
135
147
  async function toFetchRequest(req) {
@@ -526,6 +538,11 @@ const server = http.createServer((req, res) => {
526
538
  }
527
539
  const file = resolveUiFile(uiDir, pathname);
528
540
  if (!file) {
541
+ if (pathname === "/ai-ui.iife.js") {
542
+ logger.warn(
543
+ "GET /ai-ui.iife.js 404 — @maintainer-pro/ai-ui is not installed next to ai-server"
544
+ );
545
+ }
529
546
  res.statusCode = 404;
530
547
  res.end("Not found");
531
548
  return;
@@ -766,6 +783,15 @@ async function start() {
766
783
  logger.info(`ws → ${toHttpWsUrl(base)}/api/ws`);
767
784
  logger.info(`ui → ${base}/`);
768
785
  logger.info(`embed-config → ${base}/embed-config.js`);
786
+ const widget = findIife();
787
+ if (widget) {
788
+ logger.info(`widget → ${base}/ai-ui.iife.js`);
789
+ logger.debug({ widget }, "widget file");
790
+ } else {
791
+ logger.warn(
792
+ "GET /ai-ui.iife.js will 404 — @maintainer-pro/ai-ui is not installed next to ai-server"
793
+ );
794
+ }
769
795
  logger.info(`workspace ${workspaceDir}`);
770
796
  logger.info(
771
797
  {