@plot-pm/board 0.16.1 → 0.16.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/dist/board-server.mjs +167 -139
- package/package.json +2 -3
- package/plot-agent-manifest.sh +111 -15
- package/plot-agent-monitor.sh +43 -5
- package/plot-approve.sh +234 -74
- package/plot-build-monitor.sh +49 -4
- package/plot-config.sh +10 -14
- package/plot-deliver.sh +10 -732
- package/plot-desk-root.sh +127 -0
- package/plot-dispatch.sh +313 -135
- package/plot-fleet-scan.sh +746 -62
- package/plot-host.sh +356 -43
- package/plot-monitor-subject.sh +55 -3
- package/plot-plan-meta.sh +155 -139
- package/plot-pr-merged.sh +16 -0
- package/plot-reap.sh +82 -93
- package/plot-state-receipt.sh +12 -2
- package/plot-tmp.sh +90 -14
- package/plot-transcript-quiet.sh +3 -1
- package/plot-worker-state.sh +633 -24
- package/plot-resolve-artifact.sh +0 -429
- package/plot-worker-monitor.sh +0 -705
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# The ONE answer to "where do desks and action records go?" — sourced, not run.
|
|
3
|
+
#
|
|
4
|
+
# Every script that resolved this privately asks here instead. Nine sites
|
|
5
|
+
# computed the rule on 2026-10-01 and two of them already answered `.worktrees`
|
|
6
|
+
# while seven answered the checkout's parent, so one of the two populations was
|
|
7
|
+
# always writing somewhere the other did not read.
|
|
8
|
+
#
|
|
9
|
+
# The rule itself is `deskRoot` in the domain, asked through
|
|
10
|
+
# `board/plot-desk-root.mjs`, per *A Shell Script Asks The Domain*: every caller
|
|
11
|
+
# runs once per operator command, which is the cost rule's permitted case.
|
|
12
|
+
#
|
|
13
|
+
# NO CALLER KEEPS A FALLBACK DEFAULT. When the bundle cannot answer — no `node`,
|
|
14
|
+
# a missing file — the caller stops with the reason. A silent fallback is a
|
|
15
|
+
# second default, and two defaults are the defect this removes.
|
|
16
|
+
#
|
|
17
|
+
# plot_repo_root → the MAIN checkout, from anywhere
|
|
18
|
+
# plot_desk_root [repo [configured]] → the desk root; exit 3 when unaskable
|
|
19
|
+
# plot_exclude_desk_root [repo] → keep it out of `git status`; never fails
|
|
20
|
+
#
|
|
21
|
+
# shellcheck shell=bash
|
|
22
|
+
|
|
23
|
+
# The MAIN checkout, from a desk as readily as from the checkout itself.
|
|
24
|
+
#
|
|
25
|
+
# `--show-toplevel` answers the DESK inside a linked worktree, so with
|
|
26
|
+
# `.worktrees` as the default it would resolve `<desk>/.worktrees` and place
|
|
27
|
+
# every tree under a root nothing else reads. `plot-reap.sh:440-447` recorded
|
|
28
|
+
# that failure on 2026-09-10, when every tree read as unplaceable.
|
|
29
|
+
#
|
|
30
|
+
# The parent of `--git-common-dir` is the main checkout from anywhere, because
|
|
31
|
+
# every linked worktree shares that one directory. It is asked FIRST and
|
|
32
|
+
# `--show-toplevel` is the fallback, since the common dir is also correct in a
|
|
33
|
+
# non-worktree checkout: there `.git` is a real directory in the root.
|
|
34
|
+
#
|
|
35
|
+
# PHYSICAL, through `pwd -P`: `git worktree list` and `--show-toplevel` print
|
|
36
|
+
# resolved paths, and a desk root composed from a logical one (`/tmp` against
|
|
37
|
+
# `/private/tmp` on macOS) is a prefix no worktree path ever starts with.
|
|
38
|
+
plot_repo_root() {
|
|
39
|
+
local common root=''
|
|
40
|
+
common=$(git rev-parse --git-common-dir 2>/dev/null) && [ -n "$common" ] && {
|
|
41
|
+
common=$(cd -- "$common" 2>/dev/null && pwd -P) || common=''
|
|
42
|
+
[ -n "$common" ] && root=$(dirname -- "$common")
|
|
43
|
+
}
|
|
44
|
+
[ -n "$root" ] || root=$(git rev-parse --show-toplevel 2>/dev/null) || root=$(pwd)
|
|
45
|
+
printf '%s\n' "$root"
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
# Resolved ONCE at source time, the way `plot-pr-merged.sh:105` resolves its
|
|
49
|
+
# own bundle. Computing it inside a function reads `BASH_SOURCE[0]` at call
|
|
50
|
+
# time, which is the caller's file once the function has been exported.
|
|
51
|
+
_plot_desk_root_mjs="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/board/plot-desk-root.mjs"
|
|
52
|
+
_plot_desk_root_config="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)/plot-config.sh"
|
|
53
|
+
|
|
54
|
+
# The desk root for a repository, or exit 3 with the reason on stderr.
|
|
55
|
+
#
|
|
56
|
+
# A second argument is a value the caller was handed in place of the key — a
|
|
57
|
+
# `--worktrees DIR` flag — and goes through the same rule; without one the
|
|
58
|
+
# `Worktree root` key is read.
|
|
59
|
+
#
|
|
60
|
+
# READ THE EXIT CODE. A caller that treats an empty answer as a location would
|
|
61
|
+
# compose paths against the filesystem root.
|
|
62
|
+
plot_desk_root() {
|
|
63
|
+
local repo="${1:-}" bundle="$_plot_desk_root_mjs" configured answer
|
|
64
|
+
[ -n "$repo" ] || repo=$(plot_repo_root)
|
|
65
|
+
if [ ! -f "$bundle" ]; then
|
|
66
|
+
printf 'plot: cannot resolve the desk root: %s is missing\n' "$bundle" >&2
|
|
67
|
+
return 3
|
|
68
|
+
fi
|
|
69
|
+
if [ "$#" -ge 2 ]; then
|
|
70
|
+
configured="$2"
|
|
71
|
+
else
|
|
72
|
+
# Read from the TARGET repository, never the ambient one: `plot-config.sh`
|
|
73
|
+
# walks up from its cwd, so a caller asking about another checkout would
|
|
74
|
+
# otherwise get this one's key.
|
|
75
|
+
# A read that fails is a refusal, never the absent row: reading it as empty
|
|
76
|
+
# would answer the default for a repository that configured another root.
|
|
77
|
+
configured=$(cd -- "$repo" 2>/dev/null && bash "$_plot_desk_root_config" get "Worktree root" "" 2>/dev/null) || {
|
|
78
|
+
printf 'plot: cannot resolve the desk root: the Worktree root key in %s could not be read\n' "$repo" >&2
|
|
79
|
+
return 3
|
|
80
|
+
}
|
|
81
|
+
fi
|
|
82
|
+
answer=$(node "$bundle" "$repo" "$configured" 2>&1) || {
|
|
83
|
+
printf 'plot: cannot resolve the desk root: %s\n' "$answer" >&2
|
|
84
|
+
return 3
|
|
85
|
+
}
|
|
86
|
+
[ -n "$answer" ] || {
|
|
87
|
+
printf 'plot: the desk root rule answered nothing for %s\n' "$repo" >&2
|
|
88
|
+
return 3
|
|
89
|
+
}
|
|
90
|
+
printf '%s\n' "$answer"
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
# Keep the desk root out of `git status`, when it lies inside the repository.
|
|
94
|
+
#
|
|
95
|
+
# The line goes into the COMMON git directory's `info/exclude`: git reads that
|
|
96
|
+
# file from the common directory only, so a linked worktree's private gitdir is
|
|
97
|
+
# the wrong place and a desk writing there would exclude nothing. The write is
|
|
98
|
+
# idempotent, and `info/exclude` is never committed.
|
|
99
|
+
#
|
|
100
|
+
# Called by whoever CREATES the directory. Best-effort and always exit 0: a
|
|
101
|
+
# failure leaves untracked files in a listing, which is untidy, while refusing
|
|
102
|
+
# to create a desk over it would stop the work.
|
|
103
|
+
plot_exclude_desk_root() {
|
|
104
|
+
local repo="${1:-}" bundle="$_plot_desk_root_mjs" line common exclude configured
|
|
105
|
+
[ -n "$repo" ] || repo=$(plot_repo_root)
|
|
106
|
+
[ -f "$bundle" ] || return 0
|
|
107
|
+
configured=$(cd -- "$repo" 2>/dev/null && bash "$_plot_desk_root_config" get "Worktree root" "" 2>/dev/null) || configured=''
|
|
108
|
+
line=$(node "$bundle" --exclude-line "$repo" "$configured" 2>/dev/null) || return 0
|
|
109
|
+
# Empty means the root lies outside the repository, which needs no line.
|
|
110
|
+
[ -n "$line" ] || return 0
|
|
111
|
+
# Already ignored, by a `.gitignore` line /plot-init wrote or by an earlier
|
|
112
|
+
# run. A second rule for a path already ignored is noise in a file people read.
|
|
113
|
+
( cd -- "$repo" 2>/dev/null && git check-ignore -q ".$line" ) && return 0
|
|
114
|
+
common=$(cd -- "$repo" 2>/dev/null && git rev-parse --git-common-dir 2>/dev/null) || return 0
|
|
115
|
+
[ -n "$common" ] || return 0
|
|
116
|
+
case "$common" in /*) ;; *) common="$repo/$common" ;; esac
|
|
117
|
+
exclude="$common/info/exclude"
|
|
118
|
+
if [ -f "$exclude" ] && grep -qxF "$line" "$exclude" 2>/dev/null; then return 0; fi
|
|
119
|
+
mkdir -p "$common/info" 2>/dev/null || return 0
|
|
120
|
+
# A file not ending in a newline would otherwise join this line to its last.
|
|
121
|
+
if [ -s "$exclude" ] && [ "$(tail -c 1 "$exclude" 2>/dev/null)" != "" ]; then
|
|
122
|
+
printf '\n%s\n' "$line" >> "$exclude" 2>/dev/null || true
|
|
123
|
+
else
|
|
124
|
+
printf '%s\n' "$line" >> "$exclude" 2>/dev/null || true
|
|
125
|
+
fi
|
|
126
|
+
return 0
|
|
127
|
+
}
|