napbox 0.1.0 → 0.1.1

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
@@ -8,7 +8,7 @@ napbox reads a project's compose file and gives every git worktree its own isola
8
8
 
9
9
  It is built on Apple's open-source [Containerization](https://github.com/apple/containerization) framework: one lightweight Linux VM per environment, with all its services in it.
10
10
 
11
- **Status: 0.1.0, early.** Used daily on one machine for several projects (PostgreSQL with PostGIS, Redis, MinIO, Go and Node backends, nginx front ends). Expect rough edges.
11
+ **Status: 0.1.1, early.** Used daily on one machine for several projects (PostgreSQL with PostGIS, Redis, MinIO, Go and Node backends, nginx front ends). Expect rough edges.
12
12
 
13
13
  ## Requirements
14
14
 
@@ -36,7 +36,7 @@ Without Claude Code: `npx napbox setup`.
36
36
  ## How it works
37
37
 
38
38
  - **One environment per worktree.** Environments are named `<project>/<worktree>` (the main checkout is `<project>/main`). Two worktrees of the same project run side by side without port clashes.
39
- - **Ports.** In compose, write only the container port (`- "5432"`). napbox assigns a host port on `127.0.0.1` and keeps it for the environment across sleep, wake, `up` again, napboxd restarts and profile changes. It is released only on `down`. Other worktrees and temporary environments get other ports, so read them from `napbox env` instead of hard-coding them.
39
+ - **Ports.** In compose, write only the container port (`- "5432"`). napbox assigns a host port on `127.0.0.1` and keeps it for the environment across sleep, wake, `up` again, napboxd restarts and profile changes. It is released only on `down`. Other worktrees and temporary environments get other ports, so read them from `napbox env` instead of hard-coding them. When a service needs its own address on the host (for example to build links a browser opens), write `${NAPBOX_API_3100}` in `environment` or `env_file`; napbox replaces it with the address this environment was given (`127.0.0.1:41217`) when the service starts.
40
40
  - **Sleep.** After 30 minutes without connections an environment sleeps and its memory goes back to macOS. The next connection to one of its ports wakes it; the first connection waits about a second.
41
41
  - **Temporary environments.** `napbox up --temp <name>` starts a throwaway environment next to the dev one (an empty test database, for example), and `napbox down --temp <name>` deletes it. `napbox run <service>` starts a one-off environment, runs one service in the foreground and returns its exit code.
42
42
  - **Builds.** `build:` is built inside a dedicated VM with BuildKit; the build cache is shared by all environments.
package/README.zh-CN.md CHANGED
@@ -8,7 +8,7 @@ napbox 按项目的 compose 文件,给每个 git worktree 起一套隔离的
8
8
 
9
9
  底层是苹果开源的 [Containerization](https://github.com/apple/containerization):一个环境一台轻量的 Linux 虚拟机,环境里的服务都在这台虚拟机里。
10
10
 
11
- **状态:0.1.0,早期版本。** 已经在一台电脑上给好几个项目日常使用(带 PostGIS 的 PostgreSQL、Redis、MinIO、Go 和 Node 后端、nginx 前端),但还会有不顺手的地方。
11
+ **状态:0.1.1,早期版本。** 已经在一台电脑上给好几个项目日常使用(带 PostGIS 的 PostgreSQL、Redis、MinIO、Go 和 Node 后端、nginx 前端),但还会有不顺手的地方。
12
12
 
13
13
  ## 要求
14
14
 
@@ -36,7 +36,7 @@ agent 第一次要起服务时,napbox 会报还没准备好,agent 就去调
36
36
  ## 怎么工作
37
37
 
38
38
  - **一个 worktree 一个环境。** 环境叫 `<项目>/<worktree>`,主工作区是 `<项目>/main`。同一个项目的两个 worktree 可以同时运行,端口不冲突。
39
- - **端口。** compose 里只写容器端口(`- "5432"`)。napbox 在 `127.0.0.1` 上分一个宿主机端口,这个环境一直用它:休眠、唤醒、再次 `up`、napboxd 重启、换 profile 都不变,`down` 了才释放。别的 worktree 和临时环境是别的端口,所以要从 `napbox env` 读,不要写死。
39
+ - **端口。** compose 里只写容器端口(`- "5432"`)。napbox 在 `127.0.0.1` 上分一个宿主机端口,这个环境一直用它:休眠、唤醒、再次 `up`、napboxd 重启、换 profile 都不变,`down` 了才释放。别的 worktree 和临时环境是别的端口,所以要从 `napbox env` 读,不要写死。环境里的服务要知道自己在宿主机上的地址时(比如服务端生成给浏览器打开的链接),在 `environment` 或 `env_file` 里写 `${NAPBOX_API_3100}`,起服务时换成这个环境分到的地址(`127.0.0.1:41217`)。
40
40
  - **休眠。** 30 分钟没有连接就休眠,内存还给 macOS。下次连它的端口就自动唤醒,第一条连接要等约 1 秒。
41
41
  - **临时环境。** `napbox up --temp <名字>` 在开发环境旁边另起一个用完就扔的环境(比如测试用的空库),`napbox down --temp <名字>` 删掉它。`napbox run <服务>` 临时起一个环境,在前台跑一个服务,返回它的退出码。
42
42
  - **构建。** 写了 `build:` 的服务在单独的虚拟机里用 BuildKit 构建,所有环境共用一份构建缓存。
@@ -1,4 +1,4 @@
1
- // Claude Code 插件的钩子(DESIGN.md 第 4 节、第 12 节第 3 条):
1
+ // Claude Code 插件的钩子:
2
2
  // - 会话开始和每次压缩上下文之后,当前 worktree 有环境就把端口告诉 agent;
3
3
  // - 已接入的项目里运行 docker compose up/start/run 时拦下;自己起数据库这类服务、或者 docker run 时提醒。
4
4
  import { execFile } from "node:child_process";
@@ -98,7 +98,7 @@ function ownServiceReminder(argv) {
98
98
  function resolveCds(cwd, cds) {
99
99
  return cds.reduce((directory, target) => path.resolve(directory, target), cwd);
100
100
  }
101
- /** 已接入:worktree 根目录有 .napbox.yaml,或者这个仓库的某个 worktree 有环境记录(DESIGN.md 第 12 节第 3 条) */
101
+ /** 已接入:worktree 根目录有 .napbox.yaml,或者这个仓库的某个 worktree 有环境记录 */
102
102
  async function isOnboarded(directory) {
103
103
  const root = await git(directory, ["rev-parse", "--show-toplevel"]);
104
104
  if (!root)
@@ -2,5 +2,5 @@ export declare const packageRoot: string;
2
2
  export declare const packageVersion: string;
3
3
  /** 编译好的 napbox、napboxd、napbox-guard。发布的包在 native/ 下;仓库里没有,要用 NAPBOX_BIN 指向编译产物 */
4
4
  export declare const nativeDirectory: () => string;
5
- /** 插件把固定版本的包装在这里。可以随时删,下次用到时重新安装;napboxd 不放这里(DESIGN.md 第 4 节) */
5
+ /** 插件把固定版本的包装在这里。可以随时删,下次用到时重新安装;napboxd 不放这里 */
6
6
  export declare const cacheDirectory: () => string;
@@ -7,5 +7,5 @@ export const packageRoot = fileURLToPath(new URL("../../", import.meta.url));
7
7
  export const packageVersion = JSON.parse(readFileSync(path.join(packageRoot, "package.json"), "utf8")).version;
8
8
  /** 编译好的 napbox、napboxd、napbox-guard。发布的包在 native/ 下;仓库里没有,要用 NAPBOX_BIN 指向编译产物 */
9
9
  export const nativeDirectory = () => process.env.NAPBOX_BIN || path.join(packageRoot, "native");
10
- /** 插件把固定版本的包装在这里。可以随时删,下次用到时重新安装;napboxd 不放这里(DESIGN.md 第 4 节) */
10
+ /** 插件把固定版本的包装在这里。可以随时删,下次用到时重新安装;napboxd 不放这里 */
11
11
  export const cacheDirectory = () => path.join(homedir(), "Library/Caches/napbox");
@@ -1,4 +1,4 @@
1
- // napbox setup(DESIGN.md 第 4 节):把后台程序放到固定位置,准备内核和 vminit,注册成登录项并启动。
1
+ // napbox setup:把后台程序放到固定位置,准备内核和 vminit,注册成登录项并启动。
2
2
  // 不放在 npm 或 npx 的目录里运行:那些目录会变、会被清理,登录项要一直找得到程序。
3
3
  import { execFile as execFileCallback } from "node:child_process";
4
4
  import { createHash } from "node:crypto";
@@ -148,7 +148,7 @@ function launchAgent(daemon) {
148
148
  </dict>
149
149
  `
150
150
  : "";
151
- // ProcessType:不写时 launchd 会限速,虚拟机跟着慢(DESIGN.md 第 2 节)。Interactive 和普通 app 一样不限。
151
+ // ProcessType:不写时 launchd 会限速,虚拟机跟着慢。Interactive 和普通 app 一样不限。
152
152
  // KeepAlive:崩溃了拉起来;正常退出(退出码 0)不拉,比如 launchctl bootout。
153
153
  return `<?xml version="1.0" encoding="UTF-8"?>
154
154
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
@@ -1,4 +1,4 @@
1
- // MCP 工具,和命令行一一对应(DESIGN.md 第 4 节)。出错时的内容和命令行一样是 {"error": {"code", "message"}}。
1
+ // MCP 工具,和命令行一一对应。出错时的内容和命令行一样是 {"error": {"code", "message"}}。
2
2
  import path from "node:path";
3
3
  import { z } from "zod";
4
4
  import { NapboxError } from "../client.js";
package/dist/cli.js CHANGED
@@ -52,7 +52,7 @@ try {
52
52
  }
53
53
  }
54
54
  catch (error) {
55
- // 和命令行一样的错误格式(DESIGN.md 第 9 节)
55
+ // 和命令行一样的错误格式
56
56
  const { code, message } = error instanceof NapboxError ? error : { code: "internal_error", message: String(error) };
57
57
  process.stdout.write(`${JSON.stringify({ error: { code, message } })}\n`);
58
58
  process.exit(1);
package/dist/client.d.ts CHANGED
@@ -46,7 +46,7 @@ export interface ExecOptions {
46
46
  signal?: AbortSignal;
47
47
  }
48
48
  export interface SubscribeOptions extends SubscribeParams {
49
- /** 订阅生效了,从这以后的事件都会送到。在这里查 status、runs,中间不会漏(DESIGN.md 第 9 节) */
49
+ /** 订阅生效了,从这以后的事件都会送到。在这里查 status、runs,中间不会漏 */
50
50
  onSubscribed?: () => void | Promise<void>;
51
51
  onEvent: (event: EnvironmentEvent) => void | Promise<void>;
52
52
  /** 不再订阅时用它取消 */
package/dist/client.js CHANGED
@@ -1,4 +1,4 @@
1
- // 调用 napboxd 本地 socket 的客户端,协议见 DESIGN.md 第 4、9 节。
1
+ // 调用 napboxd 本地 socket 的客户端。协议类型和 native/Sources/NapboxProtocol/Protocol.swift 一一对应。
2
2
  //
3
3
  // 约定(测试在 test/client.test.ts、test/vm.test.ts):
4
4
  // - 每次调用一个连接。一个连接上的请求是排队处理的,up 可能要很久,不能共用。
@@ -7,7 +7,7 @@ import { homedir } from "node:os";
7
7
  import path from "node:path";
8
8
  import { pathToFileURL } from "node:url";
9
9
 
10
- const VERSION = "0.1.0";
10
+ const VERSION = "0.1.1";
11
11
 
12
12
  // 和 src/agent/locations.ts 的 cacheDirectory 同一个目录
13
13
  const versions = path.join(homedir(), "Library/Caches/napbox/versions");
package/native/napbox CHANGED
Binary file
Binary file
package/native/napboxd CHANGED
@@ -1,4 +1,4 @@
1
1
  [diffend] Oversized file quarantined before diffing.
2
2
  name: package/native/napboxd
3
- size: 48767280 bytes
4
- sha256: 4302f4e9ae9cfcd26763cc66ca909fb80f66b9a8a3b00c8bf7f13eeaa18e596d
3
+ size: 48788320 bytes
4
+ sha256: 082a181fd142838ec8e0f60b475ccf5eeb569d56fb3ce09f55b90944f980e1ad
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "napbox",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Local dev environments for coding agents on Apple silicon Macs, without Docker: an isolated set of compose services for every git worktree.",
5
5
  "type": "module",
6
6
  "bin": {