@walwal-harness/cli 7.1.51 → 7.1.52
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/CHANGELOG.md +6 -0
- package/README.md +3 -3
- package/bin/init.js +5 -1
- package/package.json +1 -1
- package/scripts/harness-dashboard-up.sh +87 -72
package/CHANGELOG.md
CHANGED
|
@@ -31,6 +31,12 @@ docmeta:
|
|
|
31
31
|
|
|
32
32
|
## Unreleased
|
|
33
33
|
|
|
34
|
+
## 7.1.52 — Single shared dashboard install (drop per-project `node_modules`) (2026-06-23)
|
|
35
|
+
- `scripts/harness-dashboard-up.sh` now installs the Brick Office dashboard **once per version** under `~/.walwal-harness/dashboard/<version>/` (override base with `WALWAL_HARNESS_HOME`) and serves every project from that one copy. Previously each project got its own copy plus a full `npm install`, duplicating identical `node_modules` (~597MB) + `.next` (~75MB) per project — 100 projects cost ~64GB of identical bytes. Now total cost is ~640MB regardless of project count.
|
|
36
|
+
- `npm install` + `next build` run only on the first launch of a given version (guarded by a `.walwal-dashboard-ready` marker and an atomic `mkdir` build lock so concurrent launches don't race). Each project is then served with its own `HARNESS_ROOT` + `--port` via `next start`; since `next start` reads `.next` read-only, many dashboards run concurrently from the same install safely.
|
|
37
|
+
- This is correct because the dashboard code is byte-identical across projects and `HARNESS_ROOT` is resolved at request time (`lib/harness-root.ts`; all routes are `force-dynamic`), so build output never bakes in a project. Supersedes both the pre-7.1.37 per-project-hashed home cache and the 7.1.37 project-local `.harness/dashboard/` copy.
|
|
38
|
+
- `bin/init.js` now writes hook/statusLine commands in `settings.json` as project-root-relative paths (`bash scripts/...`) instead of absolute `PROJECT_ROOT` paths, so moving or renaming a project no longer breaks the harness Stop hook with `No such file` errors.
|
|
39
|
+
|
|
34
40
|
## 7.1.48 — Auto-managed `.harness` `.gitignore` + runtime untrack on init (2026-06-05)
|
|
35
41
|
- `walwal-harness init` now writes/refreshes a marked managed block in the project-root `.gitignore` so machine-specific harness runtime/local state is never committed and never pollutes teammates' diffs. Ignored: live conductor `progress.json`/`progress.log`/`handoff.json`/`events.jsonl`, the `todos/` live queue (`state.json` + `events.jsonl`), `actions/`, `ops/`, `activity/`, `logs/`, `archive/` migration backups, and the `dashboard/` visualization tooling. Durable team knowledge stays tracked: `conventions/`, `gotchas/`, `documents/`, `memories/`, `memory.md`, `shared/`, `config.json`, `HARNESS.md`, `.bundle-version`.
|
|
36
42
|
- Init also best-effort `git rm --cached`s any of those runtime paths committed before the ignore block existed (files stay on disk), fixing the "`.gitignore` added but already-tracked files keep showing as changes" case.
|
package/README.md
CHANGED
|
@@ -164,7 +164,7 @@ Run on a different port:
|
|
|
164
164
|
bash scripts/harness-dashboard-up.sh --port 3002
|
|
165
165
|
```
|
|
166
166
|
|
|
167
|
-
Force-
|
|
167
|
+
Force-rebuild the shared dashboard install when an older dashboard is still shown:
|
|
168
168
|
|
|
169
169
|
```bash
|
|
170
170
|
bash scripts/harness-dashboard-up.sh --port 3002 --reinstall
|
|
@@ -175,9 +175,9 @@ Dashboard options:
|
|
|
175
175
|
| Option | Role |
|
|
176
176
|
|---|---|
|
|
177
177
|
| `--port <port>` | Run Brick Office on a custom port, e.g. `3002` |
|
|
178
|
-
| `--reinstall` |
|
|
178
|
+
| `--reinstall` | Discard and rebuild the shared dashboard install for this version |
|
|
179
179
|
|
|
180
|
-
The dashboard
|
|
180
|
+
The dashboard code is identical across all projects, so it is installed **once per version** under `~/.walwal-harness/dashboard/<version>/` and shared by every project — a single `node_modules` plus one production build (`npm install` + `next build`) the first time, then reused. Each project is served with its own `HARNESS_ROOT` and port via `next start`, so you can run many dashboards at once without duplicating dependencies (100 projects still cost ~640MB, not 100×). Override the base directory with `WALWAL_HARNESS_HOME`.
|
|
181
181
|
|
|
182
182
|
### Company Auto-Chain State
|
|
183
183
|
|
package/bin/init.js
CHANGED
|
@@ -190,7 +190,11 @@ function shellQuote(value) {
|
|
|
190
190
|
}
|
|
191
191
|
|
|
192
192
|
function harnessScriptCommand(scriptName) {
|
|
193
|
-
|
|
193
|
+
// Relative path (resolved from the project root — where Claude Code runs hooks
|
|
194
|
+
// and the statusLine). A relative path survives the project being moved or
|
|
195
|
+
// renamed; an absolute PROJECT_ROOT path bakes in the install-time location
|
|
196
|
+
// and breaks the moment the directory is relocated.
|
|
197
|
+
return `bash ${shellQuote(path.join('scripts', scriptName))}`;
|
|
194
198
|
}
|
|
195
199
|
|
|
196
200
|
function replaceHarnessHookCommand(entries, marker, command) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@walwal-harness/cli",
|
|
3
|
-
"version": "7.1.
|
|
3
|
+
"version": "7.1.52",
|
|
4
4
|
"description": "Company-style AI agent harness for Claude and Codex. Installs commands, CXX agents, skills, HR-Resource hiring pool, and project-local .harness runtime state.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"walwal-harness": "bin/init.js"
|
|
@@ -1,14 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# walwal-harness — Brick Office dashboard launcher
|
|
2
|
+
# walwal-harness — Brick Office dashboard launcher (shared single-install)
|
|
3
3
|
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
#
|
|
4
|
+
# 대시보드 코드는 모든 프로젝트에서 byte 단위로 동일하다 (패키지가 버전 고정으로
|
|
5
|
+
# 배포). 프로젝트마다 다른 것은 HARNESS_ROOT(어느 .harness/ 를 볼지)와 PORT 뿐이고,
|
|
6
|
+
# HARNESS_ROOT 는 lib/harness-root.ts 가 *런타임*에 읽는다. 따라서 설치본은 하나면
|
|
7
|
+
# 충분하다.
|
|
8
|
+
#
|
|
9
|
+
# 이 런처는 버전별 단일 설치본을 ~/.walwal-harness/dashboard/<version>/ 에 두고
|
|
10
|
+
# (npm install + next build 를 버전당 딱 한 번), 각 프로젝트는 HARNESS_ROOT+PORT 만
|
|
11
|
+
# 바꿔 `next start` 로 띄운다. next start 는 .next 를 읽기전용으로 쓰므로 같은 폴더에서
|
|
12
|
+
# 여러 프로젝트를 동시에 서빙해도 안전하다. 프로젝트가 100개여도 node_modules/.next 는
|
|
13
|
+
# 단 1벌(~640MB).
|
|
14
|
+
#
|
|
15
|
+
# 구버전 호환: 패키지에 dashboard 가 없으면 git sparse-checkout 으로 fallback 한다.
|
|
8
16
|
#
|
|
9
17
|
# Usage:
|
|
10
|
-
# bash scripts/harness-dashboard-up.sh #
|
|
18
|
+
# bash scripts/harness-dashboard-up.sh # build(최초 1회) + serve (port 3001)
|
|
11
19
|
# bash scripts/harness-dashboard-up.sh --port 3050 # override port
|
|
20
|
+
# bash scripts/harness-dashboard-up.sh --reinstall # 공유 설치본 폐기 후 재빌드
|
|
12
21
|
# HARNESS_ROOT=/path/to/project bash ... # explicit harness root
|
|
13
22
|
set -euo pipefail
|
|
14
23
|
|
|
@@ -23,12 +32,13 @@ while [[ $# -gt 0 ]]; do
|
|
|
23
32
|
--port) PORT="$2"; shift 2 ;;
|
|
24
33
|
--reinstall) REINSTALL=true; shift ;;
|
|
25
34
|
--help|-h)
|
|
26
|
-
sed -n '2,
|
|
35
|
+
sed -n '2,28p' "$0"
|
|
27
36
|
exit 0 ;;
|
|
28
37
|
*) echo "[brick-office] unknown arg: $1" >&2; exit 2 ;;
|
|
29
38
|
esac
|
|
30
39
|
done
|
|
31
40
|
|
|
41
|
+
# --- target project (the one whose .harness/ we visualize) ---
|
|
32
42
|
if [[ -z "${HARNESS_ROOT:-}" ]]; then
|
|
33
43
|
HARNESS_ROOT="$(pwd)"
|
|
34
44
|
fi
|
|
@@ -38,87 +48,91 @@ if [[ ! -d "${HARNESS_ROOT}/.harness" ]]; then
|
|
|
38
48
|
exit 3
|
|
39
49
|
fi
|
|
40
50
|
|
|
41
|
-
|
|
42
|
-
VERSION_FILE="${LOCAL_DIR}/.walwal-dashboard-version"
|
|
43
|
-
|
|
51
|
+
# --- locate the packaged dashboard source + its version ---
|
|
44
52
|
PACKAGE_ROOT="${HARNESS_ROOT}/node_modules/@walwal-harness/cli"
|
|
45
53
|
PACKAGED_DASHBOARD="${PACKAGE_ROOT}/${DASHBOARD_PATH}"
|
|
46
54
|
if [[ -f "${PACKAGE_ROOT}/package.json" ]]; then
|
|
47
55
|
PACKAGE_VERSION="$(node -p "require('${PACKAGE_ROOT}/package.json').version" 2>/dev/null || echo unknown)"
|
|
48
56
|
fi
|
|
49
57
|
|
|
58
|
+
# --- shared, version-keyed install (the whole point: one copy for ALL projects) ---
|
|
59
|
+
SHARED_BASE="${WALWAL_HARNESS_HOME:-$HOME/.walwal-harness}/dashboard"
|
|
60
|
+
VERSION_KEY="${PACKAGE_VERSION}"
|
|
61
|
+
[[ "$VERSION_KEY" == "unknown" || -z "$VERSION_KEY" ]] && VERSION_KEY="edge"
|
|
62
|
+
SHARED_DIR="${SHARED_BASE}/${VERSION_KEY}" # node_modules + .next + source live here
|
|
63
|
+
READY_MARKER="${SHARED_DIR}/.walwal-dashboard-ready" # written only after a successful build
|
|
64
|
+
LOCK_DIR="${SHARED_BASE}/.build-lock-${VERSION_KEY}" # mkdir-based build mutex (atomic)
|
|
65
|
+
|
|
50
66
|
if [[ "$REINSTALL" == "true" ]]; then
|
|
51
|
-
rm -rf "$
|
|
67
|
+
rm -rf "$SHARED_DIR"
|
|
52
68
|
fi
|
|
53
69
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
local tpl="${PACKAGE_ROOT}/assets/templates/gitignore-append.txt"
|
|
65
|
-
local block
|
|
66
|
-
if [[ -f "$tpl" ]]; then
|
|
67
|
-
block="$(cat "$tpl")"
|
|
70
|
+
echo "[brick-office] HARNESS_ROOT = ${HARNESS_ROOT}"
|
|
71
|
+
echo "[brick-office] shared install = ${SHARED_DIR} (version ${VERSION_KEY})"
|
|
72
|
+
|
|
73
|
+
# Copy the dashboard source into the shared dir. Leaves any existing node_modules
|
|
74
|
+
# in place (the package tarball ships no node_modules), so a re-entry after a failed
|
|
75
|
+
# build keeps the installed deps.
|
|
76
|
+
populate_source() {
|
|
77
|
+
mkdir -p "$SHARED_DIR"
|
|
78
|
+
if [[ -d "${PACKAGED_DASHBOARD}" ]]; then
|
|
79
|
+
cp -R "${PACKAGED_DASHBOARD}/." "${SHARED_DIR}/"
|
|
68
80
|
else
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
81
|
+
echo "[brick-office] 패키지에 dashboard 없음 — git sparse-checkout fallback (~5MB)."
|
|
82
|
+
local dl="${SHARED_BASE}/.download-${VERSION_KEY}"
|
|
83
|
+
rm -rf "$dl"; mkdir -p "$dl"
|
|
84
|
+
(
|
|
85
|
+
cd "$dl"
|
|
86
|
+
git init -q
|
|
87
|
+
git remote add origin "${REPO_URL}" 2>/dev/null || true
|
|
88
|
+
git config core.sparseCheckout true
|
|
89
|
+
echo "${DASHBOARD_PATH}/" > .git/info/sparse-checkout
|
|
90
|
+
git fetch --depth=1 origin main -q
|
|
91
|
+
git checkout main -q
|
|
92
|
+
)
|
|
93
|
+
cp -R "${dl}/${DASHBOARD_PATH}/." "${SHARED_DIR}/"
|
|
94
|
+
rm -rf "$dl"
|
|
78
95
|
fi
|
|
79
|
-
printf '%s\n' "$block" >> "$gitignore"
|
|
80
96
|
}
|
|
81
97
|
|
|
82
|
-
|
|
98
|
+
# build = install deps + production build, guarded by a single-writer lock so two
|
|
99
|
+
# projects launching at once don't race on the same shared dir. The EXIT trap is a
|
|
100
|
+
# safety net: under `set -e` a failed npm install / next build aborts the script, and
|
|
101
|
+
# the trap then frees the lock (and leaves no READY_MARKER → next launch rebuilds).
|
|
102
|
+
build_shared() {
|
|
103
|
+
local waited=0
|
|
104
|
+
mkdir -p "$SHARED_BASE" # lock dir is created with plain mkdir, so its parent must exist
|
|
105
|
+
while ! mkdir "$LOCK_DIR" 2>/dev/null; do
|
|
106
|
+
# someone else finished the build while we were waiting → done, nothing to own.
|
|
107
|
+
[[ -f "$READY_MARKER" ]] && return 0
|
|
108
|
+
sleep 1; waited=$((waited + 1))
|
|
109
|
+
if (( waited > 600 )); then
|
|
110
|
+
echo "[brick-office] stale build lock (>10m) — 강제 해제." >&2
|
|
111
|
+
rm -rf "$LOCK_DIR"
|
|
112
|
+
fi
|
|
113
|
+
done
|
|
114
|
+
trap 'rm -rf "$LOCK_DIR"' EXIT
|
|
83
115
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
if [[ -d "${PACKAGED_DASHBOARD}" ]]; then
|
|
88
|
-
INSTALLED_VERSION=""
|
|
89
|
-
if [[ -f "${VERSION_FILE}" ]]; then
|
|
90
|
-
INSTALLED_VERSION="$(cat "${VERSION_FILE}" 2>/dev/null || true)"
|
|
91
|
-
fi
|
|
92
|
-
if [[ ! -d "${LOCAL_DIR}/${DASHBOARD_PATH}" || "${INSTALLED_VERSION}" != "${PACKAGE_VERSION}" ]]; then
|
|
93
|
-
echo "[brick-office] dashboard sync from npm package @walwal-harness/cli@${PACKAGE_VERSION}"
|
|
94
|
-
rm -rf "${LOCAL_DIR:?}/${DASHBOARD_PATH}"
|
|
95
|
-
mkdir -p "${LOCAL_DIR}/apps"
|
|
96
|
-
cp -R "${PACKAGED_DASHBOARD}" "${LOCAL_DIR}/apps/"
|
|
97
|
-
printf '%s\n' "${PACKAGE_VERSION}" > "${VERSION_FILE}"
|
|
116
|
+
# double-checked: another waiter may have built it just before we got the lock.
|
|
117
|
+
if [[ -f "$READY_MARKER" && "$(cat "$READY_MARKER" 2>/dev/null || true)" == "$VERSION_KEY" ]]; then
|
|
118
|
+
rm -rf "$LOCK_DIR"; trap - EXIT; return 0
|
|
98
119
|
fi
|
|
99
|
-
elif [[ ! -d "${LOCAL_DIR}/${DASHBOARD_PATH}" ]]; then
|
|
100
|
-
echo "[brick-office] 첫 실행 — git sparse-checkout 으로 dashboard 만 가져옵니다 (~5MB)."
|
|
101
|
-
rm -rf "${LOCAL_DIR}/.download"
|
|
102
|
-
mkdir -p "${LOCAL_DIR}/.download"
|
|
103
|
-
cd "${LOCAL_DIR}/.download"
|
|
104
|
-
git init -q
|
|
105
|
-
git remote add origin "${REPO_URL}" 2>/dev/null || true
|
|
106
|
-
git config core.sparseCheckout true
|
|
107
|
-
echo "${DASHBOARD_PATH}/" > .git/info/sparse-checkout
|
|
108
|
-
git fetch --depth=1 origin main -q
|
|
109
|
-
git checkout main -q
|
|
110
|
-
mkdir -p "${LOCAL_DIR}/apps"
|
|
111
|
-
rm -rf "${LOCAL_DIR:?}/${DASHBOARD_PATH}"
|
|
112
|
-
cp -R "${DASHBOARD_PATH}" "${LOCAL_DIR}/apps/"
|
|
113
|
-
rm -rf "${LOCAL_DIR}/.download"
|
|
114
|
-
echo "[brick-office] 다운로드 완료."
|
|
115
|
-
fi
|
|
116
120
|
|
|
117
|
-
|
|
121
|
+
[[ -f "${SHARED_DIR}/package.json" ]] || populate_source
|
|
122
|
+
|
|
123
|
+
echo "[brick-office] npm install (버전당 1회, ~30s)..."
|
|
124
|
+
( cd "$SHARED_DIR" && npm install --no-audit --no-fund --loglevel=error )
|
|
125
|
+
|
|
126
|
+
echo "[brick-office] next build (버전당 1회)..."
|
|
127
|
+
( cd "$SHARED_DIR" && ./node_modules/.bin/next build )
|
|
128
|
+
|
|
129
|
+
printf '%s\n' "$VERSION_KEY" > "$READY_MARKER"
|
|
130
|
+
echo "[brick-office] 빌드 완료 — 이후 모든 프로젝트가 이 설치본을 공유합니다."
|
|
131
|
+
rm -rf "$LOCK_DIR"; trap - EXIT
|
|
132
|
+
}
|
|
118
133
|
|
|
119
|
-
if [[ ! -
|
|
120
|
-
|
|
121
|
-
npm install --no-audit --no-fund --loglevel=error
|
|
134
|
+
if [[ ! -f "$READY_MARKER" || "$(cat "$READY_MARKER" 2>/dev/null || true)" != "$VERSION_KEY" ]]; then
|
|
135
|
+
build_shared
|
|
122
136
|
fi
|
|
123
137
|
|
|
124
138
|
echo ""
|
|
@@ -130,4 +144,5 @@ echo "║ 실시간 (SSE) 시각화합니다. Ctrl+C 로 종료.
|
|
|
130
144
|
echo "╚══════════════════════════════════════════════════════════╝"
|
|
131
145
|
echo ""
|
|
132
146
|
|
|
133
|
-
|
|
147
|
+
cd "$SHARED_DIR"
|
|
148
|
+
HARNESS_ROOT="${HARNESS_ROOT}" exec ./node_modules/.bin/next start -H 127.0.0.1 -p "${PORT}"
|