autowonder 0.2.24 → 0.2.26

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
@@ -6,13 +6,13 @@ AutoWonder 本地 agent runtime。安装后启动 daemon,持续轮询本地 as
6
6
 
7
7
  ```bash
8
8
  # Qoder CLI
9
- npx -y autowonder@0.2.24 connect --ws-url <wss-endpoint> --token <executor-token> --executor-id <executor-id> --provider qoder --model Qwen3.7-Max --reasoning-effort medium --context-window 131072
9
+ npx -y autowonder@0.2.26 connect --ws-url <wss-endpoint> --token <executor-token> --executor-id <executor-id> --provider qoder --model Qwen3.7-Max --reasoning-effort medium --context-window 131072
10
10
 
11
11
  # Claude Code
12
- npx -y autowonder@0.2.24 connect --ws-url <wss-endpoint> --token <executor-token> --executor-id <executor-id> --provider claude
12
+ npx -y autowonder@0.2.26 connect --ws-url <wss-endpoint> --token <executor-token> --executor-id <executor-id> --provider claude
13
13
 
14
14
  # Codex CLI
15
- npx -y autowonder@0.2.24 connect --ws-url <wss-endpoint> --token <executor-token> --executor-id <executor-id> --provider codex --model gpt-5.5 --reasoning-effort medium
15
+ npx -y autowonder@0.2.26 connect --ws-url <wss-endpoint> --token <executor-token> --executor-id <executor-id> --provider codex --model gpt-5.5 --reasoning-effort medium
16
16
  ```
17
17
 
18
18
  `connect` 会安装当前 npm 包内置的 daemon,并使用页面生成的 WebSocket endpoint、Token 和执行器 ID 建立连接。目标机器必须提前安装并登录对应的 Qoder CLI、Claude Code 或 Codex CLI;runtime 会继承当前用户的 HOME、环境变量和 CLI 登录状态。
@@ -29,13 +29,18 @@ AUTOWONDER_AUTO_UPDATE=false npx -y autowonder@latest connect ...
29
29
 
30
30
  # 调整检查周期或使用兼容的 npm registry
31
31
  AUTOWONDER_AUTO_UPDATE_INTERVAL=1h \
32
- AUTOWONDER_UPDATE_DOWNLOAD_TIMEOUT=10m \
33
32
  AUTOWONDER_NPM_REGISTRY=https://registry.npmjs.org \
34
33
  npx -y autowonder@latest connect ...
35
34
  ```
36
35
 
37
36
  候选版本缓存在 `~/.autowonder/updates/`;当前二进制和单个回滚副本位于 `~/.autowonder/bin/`。`GET /health` 会返回 `daemonVersion`、`updateState`、`updateTarget` 和 `updateError`。
38
37
 
38
+ ## 发布构建
39
+
40
+ `npm run build` 和发布脚本只接受没有已跟踪或未跟踪改动的 Git worktree。脚本会把准确的 release commit 克隆到仓库外的 detached checkout,再从该目录构建四个平台的 daemon。
41
+
42
+ 每个产物都必须在 Go BuildInfo 中报告相同的完整 commit、`vcs.modified=false` 和目标平台;本机产物的 `--self-check` 还必须与 npm 包版本、短 commit 和平台一致。任一检查失败都会在替换 `vendor` 或执行 `npm publish` 前终止。
43
+
39
44
  ## 提交 assignment
40
45
 
41
46
  daemon 默认轮询 `~/autowonder_workspaces/assignments/*.json`。队列里放 assignment JSON,不放 package zip;JSON 的 `taskPackageRef.downloadUrl` 应指向可下载的 OSS、HTTP 或本地 package 地址。
@@ -50,14 +55,14 @@ mv "$queue/.assignment.tmp" "$queue/assignment.json"
50
55
  也可以直接提交到本地 API:
51
56
 
52
57
  ```bash
53
- npx -y autowonder@0.2.24 dispatch ./assignment.json
58
+ npx -y autowonder@0.2.26 dispatch ./assignment.json
54
59
  ```
55
60
 
56
61
  ## 管理 daemon
57
62
 
58
63
  ```bash
59
- npx -y autowonder@0.2.24 status
60
- npx -y autowonder@0.2.24 stop
64
+ npx -y autowonder@0.2.26 status
65
+ npx -y autowonder@0.2.26 stop
61
66
  ```
62
67
 
63
68
  默认 API 是 `http://127.0.0.1:34989`,日志位于 `~/.autowonder/daemon.log`。npm 包不包含任何 agent、MCP 或服务端凭证。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "autowonder",
3
- "version": "0.2.24",
3
+ "version": "0.2.26",
4
4
  "description": "AutoWonder local runtime — execute AI agent dispatch packages on your machine",
5
5
  "bin": {
6
6
  "autowonder": "bin/cli.js"
@@ -18,12 +18,22 @@ PKG_DIR="$(dirname "$SCRIPT_DIR")"
18
18
  VENDOR_DIR="$PKG_DIR/vendor"
19
19
  SOURCE_DIR="${AUTOWONDER_SOURCE_DIR:-}"
20
20
  SOURCE_REPO="${AUTOWONDER_SOURCE_REPO:-}"
21
- TEMP_SOURCE_DIR=""
21
+ TEMP_SELECTED_SOURCE_DIR=""
22
+ TEMP_BUILD_PARENT=""
23
+ STAGING_VENDOR_DIR=""
22
24
  NPM_CONFIG_FILE=""
23
25
 
26
+ source "$SCRIPT_DIR/release-build-lib.sh"
27
+
24
28
  cleanup() {
25
- if [[ -n "$TEMP_SOURCE_DIR" ]]; then
26
- rm -rf "$TEMP_SOURCE_DIR"
29
+ if [[ -n "$TEMP_SELECTED_SOURCE_DIR" ]]; then
30
+ rm -rf "$TEMP_SELECTED_SOURCE_DIR"
31
+ fi
32
+ if [[ -n "$TEMP_BUILD_PARENT" ]]; then
33
+ rm -rf "$TEMP_BUILD_PARENT"
34
+ fi
35
+ if [[ -n "$STAGING_VENDOR_DIR" ]]; then
36
+ rm -rf "$STAGING_VENDOR_DIR"
27
37
  fi
28
38
  if [[ -n "$NPM_CONFIG_FILE" ]]; then
29
39
  rm -f "$NPM_CONFIG_FILE"
@@ -50,19 +60,33 @@ else
50
60
  echo "Error: set AUTOWONDER_SOURCE_DIR or AUTOWONDER_SOURCE_REPO"
51
61
  exit 1
52
62
  fi
53
- TEMP_SOURCE_DIR="$(mktemp -d)"
54
- SOURCE_DIR="$TEMP_SOURCE_DIR"
63
+ TEMP_SELECTED_SOURCE_DIR="$(mktemp -d)"
64
+ SOURCE_DIR="$TEMP_SELECTED_SOURCE_DIR"
55
65
  echo "Cloning from $SOURCE_REPO..."
56
66
  git clone --depth 1 "$SOURCE_REPO" "$SOURCE_DIR"
57
67
  fi
58
68
 
59
69
  version="$(node -p "require('$PKG_DIR/package.json').version")"
60
- commit="$(git -C "$SOURCE_DIR" rev-parse --short=12 HEAD 2>/dev/null || printf unknown)"
70
+ require_clean_release_source "$SOURCE_DIR"
71
+ release_commit="$(git -C "$SOURCE_DIR" rev-parse HEAD)"
72
+ commit="${release_commit:0:12}"
73
+
74
+ TEMP_BUILD_PARENT="$(mktemp -d)"
75
+ BUILD_SOURCE_DIR="$TEMP_BUILD_PARENT/source"
76
+ prepare_clean_release_checkout "$SOURCE_DIR" "$release_commit" "$BUILD_SOURCE_DIR"
77
+
78
+ source_version="$(node -p "require('$BUILD_SOURCE_DIR/npm/package.json').version")"
79
+ if [[ "$source_version" != "$version" ]]; then
80
+ release_error "package version mismatch: source=$source_version package=$version"
81
+ exit 1
82
+ fi
83
+
61
84
  ldflags="-s -w -X main.buildPackageName=autowonder -X main.buildVersion=$version -X main.buildCommit=$commit"
85
+ echo "Release commit: $release_commit"
86
+ echo "Go toolchain: $(go env GOVERSION)"
62
87
 
63
88
  # Build for all platforms
64
- rm -rf "$VENDOR_DIR"
65
- mkdir -p "$VENDOR_DIR"
89
+ STAGING_VENDOR_DIR="$(mktemp -d "$PKG_DIR/.vendor-staging.XXXXXX")"
66
90
 
67
91
  platforms=("darwin-arm64" "darwin-amd64" "linux-amd64" "linux-arm64")
68
92
  goarch_map=("arm64" "amd64" "amd64" "arm64")
@@ -72,14 +96,28 @@ for i in "${!platforms[@]}"; do
72
96
  platform="${platforms[$i]}"
73
97
  goos="${goos_map[$i]}"
74
98
  goarch="${goarch_map[$i]}"
75
- output="$VENDOR_DIR/autowonder-daemon-${goos}-${goarch}"
99
+ output="$STAGING_VENDOR_DIR/autowonder-daemon-${goos}-${goarch}"
76
100
 
77
101
  echo "Building $platform..."
78
- (cd "$SOURCE_DIR" && CGO_ENABLED=0 GOOS="$goos" GOARCH="$goarch" go build -o "$output" -ldflags="$ldflags" ./cmd/autowonder-daemon)
102
+ (cd "$BUILD_SOURCE_DIR" && CGO_ENABLED=0 GOOS="$goos" GOARCH="$goarch" go build -trimpath -buildvcs=true -o "$output" -ldflags="$ldflags" ./cmd/autowonder-daemon)
79
103
  chmod +x "$output"
104
+ verify_go_binary_provenance "$output" "$release_commit" "$goos" "$goarch"
80
105
  echo " -> $output ($(du -h "$output" | cut -f1))"
81
106
  done
82
107
 
108
+ native_goos="$(go env GOOS)"
109
+ native_goarch="$(go env GOARCH)"
110
+ native_binary="$STAGING_VENDOR_DIR/autowonder-daemon-${native_goos}-${native_goarch}"
111
+ if [[ ! -x "$native_binary" ]]; then
112
+ release_error "native platform is not included in release targets: ${native_goos}-${native_goarch}"
113
+ exit 1
114
+ fi
115
+ verify_daemon_self_check "$native_binary" "$version" "$commit" "$native_goos" "$native_goarch"
116
+
117
+ rm -rf "$VENDOR_DIR"
118
+ mv "$STAGING_VENDOR_DIR" "$VENDOR_DIR"
119
+ STAGING_VENDOR_DIR=""
120
+
83
121
  echo ""
84
122
  echo "Binaries ready in $VENDOR_DIR:"
85
123
  ls -lh "$VENDOR_DIR/"
@@ -0,0 +1,123 @@
1
+ #!/usr/bin/env bash
2
+
3
+ release_error() {
4
+ printf 'Error: %s\n' "$*" >&2
5
+ return 1
6
+ }
7
+
8
+ require_clean_release_source() {
9
+ local source_dir="$1"
10
+ local status
11
+
12
+ if ! git -C "$source_dir" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
13
+ release_error "release source is not a Git worktree: $source_dir"
14
+ return 1
15
+ fi
16
+ if ! status="$(git -C "$source_dir" status --porcelain --untracked-files=all)"; then
17
+ release_error "cannot inspect release source: $source_dir"
18
+ return 1
19
+ fi
20
+ if [[ -n "$status" ]]; then
21
+ release_error "release source is dirty: $source_dir"
22
+ return 1
23
+ fi
24
+ }
25
+
26
+ prepare_clean_release_checkout() {
27
+ local source_dir="$1"
28
+ local expected_commit="$2"
29
+ local destination="$3"
30
+ local actual_commit
31
+
32
+ if ! git clone --quiet --no-local --no-checkout "$source_dir" "$destination"; then
33
+ release_error "cannot clone release source: $source_dir"
34
+ return 1
35
+ fi
36
+ if ! git -C "$destination" checkout --quiet --detach "$expected_commit"; then
37
+ release_error "cannot check out release commit: $expected_commit"
38
+ return 1
39
+ fi
40
+ actual_commit="$(git -C "$destination" rev-parse HEAD)" || return 1
41
+ if [[ "$actual_commit" != "$expected_commit" ]]; then
42
+ release_error "clean checkout commit mismatch: got $actual_commit, want $expected_commit"
43
+ return 1
44
+ fi
45
+ require_clean_release_source "$destination"
46
+ }
47
+
48
+ go_build_value() {
49
+ local binary="$1"
50
+ local key="$2"
51
+
52
+ go version -m "$binary" |
53
+ awk -v key="$key" '$1 == "build" && index($2, key "=") == 1 { sub("^" key "=", "", $2); print $2; exit }'
54
+ }
55
+
56
+ verify_go_binary_provenance() {
57
+ local binary="$1"
58
+ local expected_commit="$2"
59
+ local expected_goos="$3"
60
+ local expected_goarch="$4"
61
+ local vcs revision modified goos goarch
62
+
63
+ vcs="$(go_build_value "$binary" vcs)"
64
+ revision="$(go_build_value "$binary" vcs.revision)"
65
+ modified="$(go_build_value "$binary" vcs.modified)"
66
+ goos="$(go_build_value "$binary" GOOS)"
67
+ goarch="$(go_build_value "$binary" GOARCH)"
68
+
69
+ if [[ "$vcs" != "git" ]]; then
70
+ release_error "missing Git VCS metadata: $binary"
71
+ return 1
72
+ fi
73
+ if [[ "$revision" != "$expected_commit" ]]; then
74
+ release_error "VCS revision mismatch: got $revision, want $expected_commit: $binary"
75
+ return 1
76
+ fi
77
+ if [[ "$modified" != "false" ]]; then
78
+ release_error "binary reports vcs.modified=$modified: $binary"
79
+ return 1
80
+ fi
81
+ if [[ "$goos" != "$expected_goos" ]]; then
82
+ release_error "GOOS mismatch: got $goos, want $expected_goos: $binary"
83
+ return 1
84
+ fi
85
+ if [[ "$goarch" != "$expected_goarch" ]]; then
86
+ release_error "GOARCH mismatch: got $goarch, want $expected_goarch: $binary"
87
+ return 1
88
+ fi
89
+ }
90
+
91
+ verify_daemon_self_check() {
92
+ local binary="$1"
93
+ local expected_version="$2"
94
+ local expected_commit="$3"
95
+ local expected_goos="$4"
96
+ local expected_goarch="$5"
97
+ local identity
98
+
99
+ if ! identity="$("$binary" --self-check --expected-version "$expected_version")"; then
100
+ release_error "daemon self-check failed: $binary"
101
+ return 1
102
+ fi
103
+
104
+ if ! printf '%s' "$identity" | node -e '
105
+ const fs = require("node:fs");
106
+ const actual = JSON.parse(fs.readFileSync(0, "utf8"));
107
+ const expected = {
108
+ package: "autowonder",
109
+ version: process.argv[1],
110
+ commit: process.argv[2],
111
+ goos: process.argv[3],
112
+ goarch: process.argv[4],
113
+ };
114
+ for (const [key, value] of Object.entries(expected)) {
115
+ if (actual[key] !== value) {
116
+ throw new Error(`${key} mismatch: got ${actual[key]}, want ${value}`);
117
+ }
118
+ }
119
+ ' "$expected_version" "$expected_commit" "$expected_goos" "$expected_goarch"; then
120
+ release_error "daemon self-check identity mismatch: $binary"
121
+ return 1
122
+ fi
123
+ }