@makerstufferupper/flypi 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
@@ -26,6 +26,26 @@ flypi stop
26
26
  The first start downloads two local models (~900 MB) for the memory store — an embedder and a
27
27
  contradiction judge. Skip them with `flypi start --embeddings none --judge none`.
28
28
 
29
+ ## Docker
30
+
31
+ ```bash
32
+ docker build -t flypi .
33
+ docker run -d --name flypi -p 127.0.0.1:8791:8791 -v flypi-data:/data flypi
34
+ open http://localhost:8791/
35
+ ```
36
+
37
+ No start command: the container starts the daemon and prints its URL in `docker logs`. `-v flypi-data:/data`
38
+ is where `.flypi/` lives — conversations, the memory wiki, your config and the ~900 MB of models — so it
39
+ survives the container being removed; without it the download and everything you wrote go with it. Bind
40
+ `127.0.0.1:` unless you want the whole LAN to reach it: the page and `/healthz` are served without the token.
41
+
42
+ `docker stop` shuts the daemon down properly (an in-flight turn is recorded as interrupted, never re-run).
43
+ `docker exec flypi flypi status` and `... flypi logs -n 100` read the running daemon. `flypi update` does not
44
+ work in a container — the package is read-only there; rebuild the image instead.
45
+
46
+ The image installs the published package, so it is the same code `npm install -g` gives you;
47
+ `docker build --build-arg FLYPI_VERSION=0.1.2` pins the version.
48
+
29
49
  ## Configure
30
50
 
31
51
  `.flypi/agent/models.json` names your providers and models, and `.flypi/agent/settings.json` picks
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@makerstufferupper/flypi",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "type": "module",
5
5
  "description": "Local multi-model agent tool with a browser UI and a personal knowledge wiki, built on the pi SDK.",
6
6
  "license": "MIT",
package/scripts/flypi.mjs CHANGED
@@ -7,6 +7,7 @@
7
7
  * detached, wait until `/healthz` answers, and report the URL you would otherwise have to dig out of a log.
8
8
  *
9
9
  * node scripts/flypi.mjs start [--foreground] # or: npm run flypi -- start
10
+ * node scripts/flypi.mjs start --foreground --port 8791 --host 0.0.0.0 # the container entry point
10
11
  * node scripts/flypi.mjs status | stop | restart | logs [-n 50] [-f]
11
12
  * node scripts/flypi.mjs update [--check] # the newest published flypi (docs/architecture.md Phase 7)
12
13
  *
@@ -187,6 +188,12 @@ async function start({ foreground = false, previous } = {}) {
187
188
  if (Object.keys(namedFlags).length > 0) writeFileSync(flagsPath, `${JSON.stringify({ ...readJson(flagsPath), ...namedFlags })}\n`);
188
189
  if (foreground) {
189
190
  const child = spawn(process.execPath, ["--import", "tsx", serveDaemon, "--root", root, ...flags], { cwd: checkout, stdio: "inherit" });
191
+ // Ctrl-C and `docker stop` reach this process, not the daemon. PID 1 in a pid namespace drops a signal it
192
+ // has no handler for, so without this the SIGTERM never arrives: docker waits out its grace period and
193
+ // SIGKILLs a daemon that never got to remove its pid file, close its sockets or record an interrupted
194
+ // turn. Installing the handler is what makes the signal be delivered; forwarding is what makes the
195
+ // daemon run its own shutdown, and the exit code comes from the daemon rather than from this wrapper.
196
+ for (const signal of ["SIGINT", "SIGTERM"]) process.on(signal, () => child.kill(signal));
190
197
  return new Promise((done) => child.on("exit", (code) => done(code ?? 0)));
191
198
  }
192
199
  // The log's directory is created above, not assumed.
@@ -14,7 +14,10 @@ import { spawnSync } from "node:child_process";
14
14
  import { readFileSync } from "node:fs";
15
15
 
16
16
  const argv = process.argv.slice(2);
17
- const dryRun = argv.includes("--dry-run");
17
+ // `npm run release patch --dry-run` hands `--dry-run` to npm, not to this script, but npm does export it as
18
+ // config — so a "dry run" of the release really bumped the version, committed, tagged and pushed, and only the
19
+ // publish was dry. Read both, so the flag means what it says whichever way it arrives.
20
+ const dryRun = argv.includes("--dry-run") || process.env.npm_config_dry_run === "true";
18
21
  const kind = argv.find((a) => ["patch", "minor", "major", "preminor", "premajor"].includes(a)) ?? "patch";
19
22
 
20
23
  /** `remote: true` marks the two steps that leave this machine, so the dry-run output says which is which. */