@tianshu-ai/tianshu 0.3.4 → 0.3.5

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.
Files changed (2) hide show
  1. package/bin/serve.mjs +54 -0
  2. package/package.json +2 -2
package/bin/serve.mjs ADDED
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env node
2
+ // Production startup entrypoint.
3
+ //
4
+ // Invoked from `npm run serve` (and the wizard-installed launchd
5
+ // plist, on global installs). Three responsibilities:
6
+ //
7
+ // 1. Resolve the package root from this file's own location so
8
+ // we work regardless of cwd (launchd's WorkingDirectory may
9
+ // or may not match the install dir; npm's $PWD may or may
10
+ // not expand depending on the shell wrapping behaviour).
11
+ //
12
+ // 2. Set TIANSHU_WEB_DIST to the bundled web dist so the server
13
+ // hosts the SPA on the API port — one process, one port.
14
+ //
15
+ // 3. Hand off to the server entry by importing it. Same Node
16
+ // process, so signal handlers + the server's own
17
+ // graceful-shutdown still fire correctly.
18
+ //
19
+ // We deliberately don't use `npm run dev`-style child processes
20
+ // here — that would re-enter the build chain (tsc / vite),
21
+ // which fails on global installs without devDependencies.
22
+ // See packages/server/src/setup/repo-root.ts (isDevelopmentCheckout)
23
+ // for the heuristic the wizard uses to pick `dev` vs `serve`.
24
+
25
+ import { dirname, join, resolve } from "node:path";
26
+ import { existsSync } from "node:fs";
27
+ import { fileURLToPath } from "node:url";
28
+
29
+ const here = dirname(fileURLToPath(import.meta.url));
30
+ const packageRoot = resolve(here, "..");
31
+ const webDist = join(packageRoot, "packages", "web", "dist");
32
+ const serverDist = join(packageRoot, "packages", "server", "dist", "index.js");
33
+
34
+ if (existsSync(webDist) && existsSync(join(webDist, "index.html"))) {
35
+ // The server reads this once at boot to decide whether to
36
+ // mount express.static + SPA fallback. Leaving it unset is
37
+ // the legitimate dev-mode signal — the server doesn't try to
38
+ // serve static files when running alongside vite.
39
+ process.env.TIANSHU_WEB_DIST = webDist;
40
+ }
41
+
42
+ if (!existsSync(serverDist)) {
43
+ // eslint-disable-next-line no-console
44
+ console.error(
45
+ `[tianshu] serve: server dist not found at ${serverDist}.\n` +
46
+ "This shouldn't happen on a global install. Try:\n" +
47
+ " npm install -g @tianshu-ai/tianshu@latest --force",
48
+ );
49
+ process.exit(1);
50
+ }
51
+
52
+ // Dynamic import so the resolution above is visible to the
53
+ // server (which reads process.env at module top-level).
54
+ await import(serverDist);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tianshu-ai/tianshu",
3
- "version": "0.3.4",
3
+ "version": "0.3.5",
4
4
  "description": "An open AI agent platform with a sidecar browser. Built in public.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://github.com/tianshu-ai/tianshu",
@@ -52,7 +52,7 @@
52
52
  "doctor": "node bin/tianshu.mjs doctor",
53
53
  "setup": "node bin/tianshu.mjs setup",
54
54
  "prepublishOnly": "npm run build",
55
- "serve": "TIANSHU_WEB_DIST=\"$PWD/packages/web/dist\" node packages/server/dist/index.js"
55
+ "serve": "node bin/serve.mjs"
56
56
  },
57
57
  "publishConfig": {
58
58
  "access": "public",