work-ally 0.2.0-alpha.1 → 0.2.0-alpha.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
@@ -31,7 +31,7 @@
31
31
  - `docs/completed/`:已完成专题与已落地 spec,回答“哪些专题已经收口”。
32
32
  - `docs/planning/`:feature spec、专项设计稿、下一阶段规划,回答“后面准备做什么”或“哪些点仍待确认”。
33
33
  - `docs/product-onboarding.md`:产品同事入场指引,回答“先看什么、按什么顺序看”。
34
- - `docs/user-quickstart.md`:CLI 用户从零到启动的主路径。
34
+ - `docs/user-quickstart.md`:CLI 用户从零到启动的主路径(含日志包导出)。
35
35
  - `docs/developer-workflow.md`:研发联调、验证入口、日常改动路径。
36
36
  - `docs/ops-runbook.md` 与 `docs/troubleshooting.md`:运行、恢复、值班和排障口径。
37
37
  - `docs/manual-acceptance.md`:人工验收清单。
@@ -60,6 +60,7 @@
60
60
  - bridge 主干在 `bridge/src/`
61
61
  - 产品级 Skill 包在 `skills/`
62
62
  - 默认安装与升级走 npm(install-first)
63
+ - 安装后可先执行 `ally prepare` 做 Codex CLI 预检查
63
64
  - 官方 Codex runtime 包装在 `runtime/`
64
65
  - assistant 长期资产在 `~/.work-ally/assistants/<name>/`
65
66
  - 运行期状态、日志、会话都在 assistant desk 的 `.system/`
@@ -92,12 +93,26 @@
92
93
 
93
94
  ## CLI 用户主路径
94
95
 
96
+ 先安装(NPM):
97
+
98
+ ```bash
99
+ npm i -g work-ally@alpha
100
+ ```
101
+
102
+ 再启动:
103
+
95
104
  ```bash
96
105
  ally setup <assistant-name> --workspace /path/to/project
97
106
  ally start --assistant <assistant-name>
98
107
  ally status --assistant <assistant-name>
99
108
  ```
100
109
 
110
+ 升级同样走 NPM:
111
+
112
+ ```bash
113
+ npm i -g work-ally@alpha
114
+ ```
115
+
101
116
  这里的 `<assistant-name>` 是你给这位 assistant 起的本机名字,例如 `pm`、`reviewer`、`ally`;它不是固定值。
102
117
 
103
118
  `ally setup <assistant-name> --workspace /path/to/project` 会自动完成:
@@ -180,6 +195,7 @@ ally status --assistant <assistant-name>
180
195
  ## 核心边界
181
196
 
182
197
  - `ally.sh` 是唯一用户入口
198
+ - 日志导出统一走 `ally logs export`,产物是本地 zip 路径(不上报)
183
199
  - `skills/` 承接机制性 workflow,不承接主身份;不要把它们继续写回 bridge core
184
200
  - 发布入口为 npm alpha:`npm publish --tag alpha`(由 `npm run release:alpha` 统一执行)
185
201
  - 当前项目目录只承载项目代码与项目级 `AGENTS.md`
package/ally.sh CHANGED
@@ -85,14 +85,16 @@ usage() {
85
85
  Usage: $CMD_NAME <command> [args]
86
86
 
87
87
  Commands:
88
+ prepare [machine scope] Preflight Codex CLI prerequisites
88
89
  setup [assistant scope] Create or bind an assistant to a project path
89
90
  assistant <subcmd> [global scope] Manage named assistant profiles
90
91
  start [assistant scope] Start a named assistant from anywhere
91
92
  stop [assistant scope] Stop a named assistant from anywhere
92
93
  restart [assistant scope] Restart a named assistant from anywhere
93
94
  status [assistant scope] Show status for a named assistant
94
- logs [timeline|bridge|runtime|routine] [follow|print|--tail N]
95
+ logs [timeline|bridge|runtime|routine|supervisor] [follow|print|--tail N]
95
96
  [assistant scope] View logs for a named assistant
97
+ logs export [machine scope] Export assistant log bundle (.zip)
96
98
  update [assistant scope] Show npm-based update guidance
97
99
  codex [assistant scope] Launch official Codex CLI with assistant-bound profile
98
100
  new [assistant scope] Start a new managed Codex thread in the assistant desk
@@ -23,6 +23,12 @@ npm test
23
23
  npm run release:alpha
24
24
  ```
25
25
 
26
+ 发布前仅自检(不真正发布):
27
+
28
+ ```bash
29
+ npm run release:alpha:check
30
+ ```
31
+
26
32
  4. 在目标机器验证安装形态:
27
33
 
28
34
  ```bash
@@ -6,7 +6,7 @@
6
6
  - 首发正式支持平台:`macOS arm64`
7
7
  - 已有可用的模型 provider 环境变量
8
8
 
9
- ## 安装
9
+ ## 安装(NPM)
10
10
 
11
11
  ```bash
12
12
  npm i -g work-ally@alpha
@@ -18,6 +18,12 @@ npm i -g work-ally@alpha
18
18
  ally help
19
19
  ```
20
20
 
21
+ 安装后先做一次预检查:
22
+
23
+ ```bash
24
+ ally prepare
25
+ ```
26
+
21
27
  ## 三步启动
22
28
 
23
29
  ```bash
@@ -26,14 +32,24 @@ ally start --assistant <assistant-name>
26
32
  ally status --assistant <assistant-name>
27
33
  ```
28
34
 
29
- ## 升级
35
+ ## 升级(NPM)
30
36
 
31
37
  ```bash
32
- npm update -g work-ally
33
- # 或固定 alpha 通道
34
38
  npm i -g work-ally@alpha
35
39
  ```
36
40
 
41
+ ## 降级 / 固定版本
42
+
43
+ ```bash
44
+ npm i -g work-ally@0.2.0-alpha.1
45
+ ```
46
+
47
+ ## 卸载
48
+
49
+ ```bash
50
+ npm rm -g work-ally
51
+ ```
52
+
37
53
  ## 关键说明
38
54
 
39
55
  - 默认是 install-first:`ally` 行为来自当前 npm 安装版本
@@ -44,3 +60,30 @@ WORK_ALLY_SOURCE_DIR=/path/to/work-ally ally status --assistant <assistant-name>
44
60
  ```
45
61
 
46
62
  - 当前不支持用户侧定时任务能力;默认不会在无触发时自行执行任务
63
+ - Codex CLI 是必需依赖;未安装时请先按官方指南安装:<https://openrouter.ai/docs/guides/guides/codex-cli>
64
+
65
+ ## 导出日志包(给支持同学)
66
+
67
+ 导出某一位助理:
68
+
69
+ ```bash
70
+ ally logs export --assistant <assistant-name>
71
+ ```
72
+
73
+ 导出全部助理:
74
+
75
+ ```bash
76
+ ally logs export --all
77
+ ```
78
+
79
+ 可指定输出路径:
80
+
81
+ ```bash
82
+ ally logs export --all --output /tmp/work-ally-logs.zip
83
+ ```
84
+
85
+ 说明:
86
+
87
+ - 命令会生成 zip 文件并打印最终路径
88
+ - 每个助理对应 zip 内一个独立目录
89
+ - 默认只打包日志与运行健康信息,不包含 `config.toml` 或 `.system/config.env`
@@ -12,6 +12,7 @@ usage() {
12
12
  Usage: $cmd_name <command> [args]
13
13
 
14
14
  Commands:
15
+ prepare # machine scope; preflight checks for Codex CLI prerequisites
15
16
  setup # assistant scope; requires --workspace <path>
16
17
  assistant <add|ensure|bind|remove|rename|list|show> [args] # global profile management
17
18
  start # assistant scope; use --assistant <name> when needed
@@ -19,6 +20,7 @@ Commands:
19
20
  restart # assistant scope; use --assistant <name> when needed
20
21
  status # assistant scope; use --assistant <name> when needed
21
22
  logs [bridge|runtime|supervisor|routine] [follow|print|--tail N] # assistant scope
23
+ logs export [--assistant <name>|--all] [--output <zip-path>] # machine scope
22
24
  update # assistant scope
23
25
  codex # assistant scope; launch official Codex CLI with assistant profile
24
26
  new|continue|attach|threads [args] # assistant scope; managed Codex thread actions
@@ -50,6 +52,9 @@ work_ally_init_context
50
52
  work_ally_ensure_state_dirs
51
53
 
52
54
  case "$CMD" in
55
+ prepare)
56
+ exec "$SCRIPT_DIR/modules/runtime/prepare.sh" "$@"
57
+ ;;
53
58
  setup)
54
59
  exec "$SCRIPT_DIR/modules/bootstrap/setup.sh" "$@"
55
60
  ;;
@@ -1448,3 +1448,17 @@ work_ally_install_bridge_dependencies() {
1448
1448
  )
1449
1449
  work_ally_ok "Bridge dependencies installed"
1450
1450
  }
1451
+
1452
+ work_ally_registry_list_assistants() {
1453
+ [ -f "$WORK_ALLY_ASSISTANT_REGISTRY_FILE" ] || return 0
1454
+ awk '
1455
+ /^ [^[:space:]]+:$/ {
1456
+ name = $0
1457
+ sub(/^ /, "", name)
1458
+ sub(/:$/, "", name)
1459
+ if (name != "") {
1460
+ print name
1461
+ }
1462
+ }
1463
+ ' "$WORK_ALLY_ASSISTANT_REGISTRY_FILE"
1464
+ }
@@ -0,0 +1,147 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
5
+ # shellcheck disable=SC1091
6
+ . "$SCRIPT_DIR/../../lib/common.sh"
7
+
8
+ work_ally_init_context
9
+ work_ally_ensure_state_dirs
10
+
11
+ usage() {
12
+ local cmd_name
13
+ cmd_name=$(work_ally_cmd_name)
14
+ cat <<USAGE
15
+ Usage: $cmd_name logs export [--assistant <name>] [--all] [--output <zip-path>]
16
+
17
+ Options:
18
+ --assistant <name> Export logs for one assistant
19
+ --all Export logs for all registered assistants
20
+ --output <zip-path> Target zip path (default: <workspace>/work-ally-logs-<timestamp>.zip)
21
+ USAGE
22
+ }
23
+
24
+ assistant_name=""
25
+ export_all=0
26
+ output_zip=""
27
+
28
+ while [ "$#" -gt 0 ]; do
29
+ case "$1" in
30
+ --assistant)
31
+ [ "$#" -ge 2 ] || work_ally_die "--assistant requires a value"
32
+ assistant_name="$2"
33
+ shift 2
34
+ ;;
35
+ --assistant=*)
36
+ assistant_name="${1#--assistant=}"
37
+ shift
38
+ ;;
39
+ --all)
40
+ export_all=1
41
+ shift
42
+ ;;
43
+ --output)
44
+ [ "$#" -ge 2 ] || work_ally_die "--output requires a value"
45
+ output_zip="$2"
46
+ shift 2
47
+ ;;
48
+ --output=*)
49
+ output_zip="${1#--output=}"
50
+ shift
51
+ ;;
52
+ help|-h|--help)
53
+ usage
54
+ exit 0
55
+ ;;
56
+ *)
57
+ work_ally_die "Unknown argument: $1"
58
+ ;;
59
+ esac
60
+ done
61
+
62
+ if [ "$export_all" -eq 1 ] && [ -n "$assistant_name" ]; then
63
+ work_ally_die "Use either --assistant <name> or --all, not both"
64
+ fi
65
+
66
+ if [ "$export_all" -eq 0 ] && [ -z "$assistant_name" ]; then
67
+ assistant_name=$(work_ally_resolve_assistant_name_from_args || true)
68
+ [ -n "$assistant_name" ] || work_ally_die "Missing target assistant. Use --assistant <name> or --all"
69
+ fi
70
+
71
+ if ! command -v zip >/dev/null 2>&1; then
72
+ work_ally_die "zip is required"
73
+ fi
74
+
75
+ assistants=()
76
+ if [ "$export_all" -eq 1 ]; then
77
+ while IFS= read -r name; do
78
+ [ -n "$name" ] || continue
79
+ assistants+=("$name")
80
+ done <<EOF2
81
+ $(work_ally_registry_list_assistants)
82
+ EOF2
83
+ [ "${#assistants[@]}" -gt 0 ] || work_ally_die "No assistants registered yet."
84
+ else
85
+ work_ally_require_registered_assistant "$assistant_name"
86
+ assistants+=("$assistant_name")
87
+ fi
88
+
89
+ stamp=$(date +%Y%m%d-%H%M%S)
90
+ if [ -z "$output_zip" ]; then
91
+ output_zip="$WORK_ALLY_WORKSPACE_ROOT/work-ally-logs-$stamp.zip"
92
+ fi
93
+
94
+ case "$output_zip" in
95
+ /*) ;;
96
+ *) output_zip="$WORK_ALLY_WORKSPACE_ROOT/$output_zip" ;;
97
+ esac
98
+
99
+ tmp_root=$(mktemp -d "${TMPDIR:-/tmp}/work-ally-log-export.XXXXXX")
100
+ cleanup() {
101
+ rm -rf "$tmp_root"
102
+ }
103
+ trap cleanup EXIT
104
+
105
+ bundle_root="$tmp_root/work-ally-logs-$stamp"
106
+ mkdir -p "$bundle_root"
107
+
108
+ copied_assistants=0
109
+ for name in "${assistants[@]}"; do
110
+ assistant_home=$(work_ally_assistant_registered_home "$name")
111
+ [ -n "$assistant_home" ] || continue
112
+ logs_dir="$assistant_home/.system/logs"
113
+ runtime_dir="$assistant_home/.system/runtime"
114
+
115
+ if [ ! -d "$logs_dir" ] && [ ! -d "$runtime_dir" ]; then
116
+ continue
117
+ fi
118
+
119
+ assistant_bundle_dir="$bundle_root/$name"
120
+ mkdir -p "$assistant_bundle_dir"
121
+
122
+ if [ -d "$logs_dir" ]; then
123
+ mkdir -p "$assistant_bundle_dir/logs"
124
+ cp -R "$logs_dir/." "$assistant_bundle_dir/logs/"
125
+ fi
126
+
127
+ if [ -d "$runtime_dir" ]; then
128
+ mkdir -p "$assistant_bundle_dir/runtime"
129
+ find "$runtime_dir" -maxdepth 1 -type f -name '*.health.json' -exec cp {} "$assistant_bundle_dir/runtime/" \;
130
+ find "$runtime_dir" -maxdepth 1 -type f -name '*.pid' -exec cp {} "$assistant_bundle_dir/runtime/" \;
131
+ fi
132
+
133
+ copied_assistants=$((copied_assistants + 1))
134
+ done
135
+
136
+ [ "$copied_assistants" -gt 0 ] || work_ally_die "No log files found for selected assistant(s)."
137
+
138
+ mkdir -p "$(dirname "$output_zip")"
139
+ rm -f "$output_zip"
140
+ (
141
+ cd "$tmp_root"
142
+ zip -qr "$output_zip" "$(basename "$bundle_root")"
143
+ )
144
+
145
+ work_ally_ok "Log bundle exported"
146
+ printf 'path: %s\n' "$output_zip"
147
+ printf 'assistants: %s\n' "$copied_assistants"
@@ -5,6 +5,14 @@ SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
5
5
  # shellcheck disable=SC1091
6
6
  . "$SCRIPT_DIR/../../lib/common.sh"
7
7
  work_ally_init_context
8
+ work_ally_ensure_state_dirs
9
+ work_ally_load_env
10
+
11
+ if [ "${1:-}" = "export" ]; then
12
+ shift || true
13
+ exec "$SCRIPT_DIR/log-export.sh" "$@"
14
+ fi
15
+
8
16
  if [ -z "${WORK_ALLY_ASSISTANT_NAME:-}" ]; then
9
17
  WORK_ALLY_ASSISTANT_NAME=$(work_ally_resolve_assistant_name_from_args "$@" || true)
10
18
  fi
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
5
+ # shellcheck disable=SC1091
6
+ . "$SCRIPT_DIR/../../lib/common.sh"
7
+
8
+ work_ally_init_context
9
+ work_ally_ensure_state_dirs
10
+
11
+ check_ok=1
12
+
13
+ work_ally_note "Running preflight checks for official Codex CLI integration"
14
+
15
+ if command -v codex >/dev/null 2>&1; then
16
+ codex_bin=$(command -v codex)
17
+ codex_version=$(codex --version 2>/dev/null | head -n 1 || true)
18
+ work_ally_ok "codex found: ${codex_bin}${codex_version:+ ($codex_version)}"
19
+ else
20
+ work_ally_warn "codex command not found"
21
+ check_ok=0
22
+ fi
23
+
24
+ global_codex_config="$HOME/.codex/config.toml"
25
+ if [ -f "$global_codex_config" ]; then
26
+ work_ally_ok "global Codex config found: $global_codex_config"
27
+ else
28
+ work_ally_warn "global Codex config missing: $global_codex_config"
29
+ check_ok=0
30
+ fi
31
+
32
+ if [ -n "${WORK_ALLY_ASSISTANT_NAME:-}" ] && work_ally_registry_has_assistant "$WORK_ALLY_ASSISTANT_NAME"; then
33
+ assistant_codex_home=$(work_ally_assistant_registered_codex_home "$WORK_ALLY_ASSISTANT_NAME")
34
+ if [ -n "$assistant_codex_home" ] && [ -d "$assistant_codex_home" ]; then
35
+ work_ally_ok "assistant codex home ready: $assistant_codex_home"
36
+ else
37
+ work_ally_warn "assistant codex home not ready for ${WORK_ALLY_ASSISTANT_NAME:-unknown}"
38
+ fi
39
+ fi
40
+
41
+ if [ "$check_ok" -eq 0 ]; then
42
+ cat <<'EOF2'
43
+
44
+ Codex CLI is required before using work-ally runtime features.
45
+ Install and configure Codex CLI first:
46
+ https://openrouter.ai/docs/guides/guides/codex-cli
47
+ EOF2
48
+ work_ally_die "Preflight failed"
49
+ fi
50
+
51
+ cat <<'EOF2'
52
+
53
+ Preflight passed.
54
+ You can continue with:
55
+ ally setup <assistant-name> --workspace <path>
56
+ ally start --assistant <assistant-name>
57
+ EOF2
58
+
59
+ work_ally_ok "Prepare checks passed"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "work-ally",
3
- "version": "0.2.0-alpha.1",
3
+ "version": "0.2.0-alpha.3",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "bin": {
@@ -25,13 +25,14 @@
25
25
  "test:full": "npm test",
26
26
  "test:fast": "node --test \"tests/unit/**/*.test.mjs\" \"tests/integration/**/*.test.mjs\"",
27
27
  "test:maintainer": "bash dev/run-regression-suite.sh",
28
- "test:shell": "bash tests/shell/smoke.sh && bash tests/shell/assistant.sh && bash tests/shell/assistant-remove.sh && bash tests/shell/assistant-rename.sh && bash tests/shell/assistant-lock.sh && bash tests/shell/global-entrypoint.sh && bash tests/shell/global-manage.sh && bash tests/shell/security.sh && bash tests/shell/ops.sh && bash tests/shell/lifecycle.sh && bash tests/shell/channel-lock.sh && bash tests/shell/mcp.sh && bash tests/shell/routines.sh && bash tests/shell/recovery.sh && bash tests/shell/service-mode.sh && bash tests/shell/bridge-health-fallback.sh && bash tests/shell/startup-delivery-gate.sh && bash tests/shell/status-health.sh && bash tests/shell/codex-runtime.sh && bash tests/shell/codex-handoff.sh && bash tests/shell/supervised-start-boundary.sh",
28
+ "test:shell": "bash tests/shell/smoke.sh && bash tests/shell/assistant.sh && bash tests/shell/assistant-remove.sh && bash tests/shell/assistant-rename.sh && bash tests/shell/assistant-lock.sh && bash tests/shell/global-entrypoint.sh && bash tests/shell/global-manage.sh && bash tests/shell/security.sh && bash tests/shell/ops.sh && bash tests/shell/lifecycle.sh && bash tests/shell/channel-lock.sh && bash tests/shell/mcp.sh && bash tests/shell/routines.sh && bash tests/shell/recovery.sh && bash tests/shell/service-mode.sh && bash tests/shell/bridge-health-fallback.sh && bash tests/shell/startup-delivery-gate.sh && bash tests/shell/status-health.sh && bash tests/shell/codex-runtime.sh && bash tests/shell/codex-handoff.sh && bash tests/shell/supervised-start-boundary.sh && bash tests/shell/log-export.sh && bash tests/shell/prepare.sh",
29
29
  "test:bridge": "node --test \"tests/unit/**/*.test.mjs\" \"tests/integration/**/*.test.mjs\"",
30
30
  "dev:debug-workspace": "bash dev/prepare-debug-workspace.sh",
31
31
  "bridge:start": "node bridge/src/server.ts",
32
32
  "runtime:health": "node runtime/host/healthcheck-codex-app-server.ts",
33
33
  "runtime:probe": "node runtime/host/probe-codex-app-server.ts",
34
- "release:alpha": "bash script/release-npm-alpha.sh"
34
+ "release:alpha": "bash script/release-npm-alpha.sh",
35
+ "release:alpha:check": "WORK_ALLY_RELEASE_PUBLISH=0 bash script/release-npm-alpha.sh"
35
36
  },
36
37
  "dependencies": {
37
38
  "@larksuiteoapi/node-sdk": "^1.50.0",