@indigoai-us/hq-cli 5.345.123 → 5.345.124
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 +14 -0
- package/assets/scaffold/core/scripts/work-mesh-project-registration-offer.sh +77 -0
- package/assets/scaffold/core/scripts/workflow-gate.sh +247 -0
- package/dist/command-catalog.generated.d.ts +239 -0
- package/dist/command-catalog.generated.js +291 -0
- package/dist/commands/core-bucket-c-work-mesh-offer-native.d.ts +7 -0
- package/dist/commands/core-bucket-c-work-mesh-offer-native.js +147 -0
- package/dist/commands/core-bucket-c-workflow-gate-fast.d.ts +3 -0
- package/dist/commands/core-bucket-c-workflow-gate-fast.js +17 -0
- package/dist/commands/core-bucket-c-workflow-gate-native.d.ts +7 -0
- package/dist/commands/core-bucket-c-workflow-gate-native.js +250 -0
- package/dist/commands/core.js +12 -0
- package/dist/commands/mesh.js +457 -16
- package/dist/fast-scaffold.js +26 -0
- package/dist/lib/lanes/quota-notice.d.ts +24 -0
- package/dist/lib/lanes/quota-notice.js +61 -0
- package/dist/lib/lanes/quota.d.ts +44 -8
- package/dist/lib/lanes/quota.js +187 -45
- package/dist/lib/lanes/reconcile.js +17 -1
- package/dist/lib/lanes/watcher.js +13 -1
- package/dist/lib/mesh/api.d.ts +2 -0
- package/dist/lib/mesh/api.js +3 -0
- package/dist/lib/mesh/client.d.ts +6 -1
- package/dist/lib/mesh/client.js +18 -5
- package/dist/lib/mesh/team-coordination.d.ts +106 -0
- package/dist/lib/mesh/team-coordination.js +297 -0
- package/dist/lib/work-context/auto-bind.d.ts +75 -0
- package/dist/lib/work-context/auto-bind.js +245 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,11 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [5.345.124] — 2026-10-14
|
|
6
|
+
- Lanes no longer stop every lane on an account for days after a single weekly-limit 429. Reset times such as "resets Oct 16 at 1am (America/Denver)" are now read with their time and timezone. A reset more than a day away first gets only a short hold, and the full hold applies only if the next lane after that also gets a 429. When a hold is set, the lane's senior gets a message with the provider's text and `hq lanes accounts clear-quota <provider> <account>`.
|
|
7
|
+
|
|
8
|
+
- `hq mesh claim` assigns a Board story to you and moves it to in_progress in one call.
|
|
9
|
+
`hq mesh story` and `hq mesh claim` accept `--force`; without it, a story held by
|
|
10
|
+
someone else prints who holds it and exits 2.
|
|
11
|
+
- `hq mesh context prd-sync` claims an unassigned story for you when it moves the
|
|
12
|
+
story to in_progress, and warns (without forcing) when someone else holds it.
|
|
13
|
+
- `hq mesh session status` shows display names, falling back to the local directory cache.
|
|
14
|
+
- New: `hq mesh overlap`, `hq mesh project reassign`, `hq mesh suggest`, `hq mesh roster`,
|
|
15
|
+
and `hq mesh context auto-bind`. On a server without these routes they print one
|
|
16
|
+
"not available on this server yet" line and exit 0.
|
|
17
|
+
|
|
5
18
|
## [5.345.123] — 2026-10-14
|
|
6
19
|
- Add native `hq core handoff-sync-prefetch` and `hq core handoff-sync-publish` commands behind the `core-native-bucket-c` family gate, with pinned shell rollback assets.
|
|
7
20
|
- `hq lanes create` without `--provider` or a worker-profile provider now uses the engine of the orchestrator session instead of always picking Codex: the senior lane's provider, then the senior session's `conduct_engine`, then `HQ_HARNESS`, Codex/Grok runtime variables, or `CLAUDECODE=1`. When none of these is known it exits with `provider_required` and asks for `--provider`. `provider_source` stays `default` for these lanes.
|
|
8
21
|
- Add native `hq core knowledge-pulse-lock` and `hq core skill-installed` commands behind the existing `core-native-bucket-c` family gate, with pinned shell rollback assets.
|
|
9
22
|
- Match shell behavior for failed claim markers and mkdir errors, skill frontmatter edge cases, and trailing company-list commas.
|
|
23
|
+
- Add native `hq core workflow-gate` and `hq core work-mesh-project-registration-offer` commands behind the `core-native-bucket-c` family gate, with pinned shell rollback assets.
|
|
10
24
|
|
|
11
25
|
- New `hq deploy list [query]` lists your company's hq-deploy apps with their
|
|
12
26
|
public URL, type and access mode. The query filters by name or subdomain;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
ROOT="${HQ_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)}"
|
|
5
|
+
FLAG_READER="$ROOT/.claude/hooks/work-mesh-project-registration-offer-flag.cjs"
|
|
6
|
+
|
|
7
|
+
die() { echo "$*" >&2; exit 1; }
|
|
8
|
+
|
|
9
|
+
resolve_cloud_uid() {
|
|
10
|
+
local company="$1" manifest="$ROOT/companies/manifest.yaml"
|
|
11
|
+
[ -f "$manifest" ] || return 0
|
|
12
|
+
awk -v company="$company" '
|
|
13
|
+
/^companies:[[:space:]]*$/ { in_companies=1; next }
|
|
14
|
+
in_companies && /^[^[:space:]]/ { in_companies=0 }
|
|
15
|
+
in_companies && /^ [^ #][^:]*:/ {
|
|
16
|
+
slug=$1; sub(/[[:space:]]+$/, "", slug); sub(/:$/, "", slug); in_company=(slug == company); next
|
|
17
|
+
}
|
|
18
|
+
in_company && /^ [^[:space:]#]/ { exit }
|
|
19
|
+
in_company && $1 == "cloud_uid:" { gsub(/["\047]/, "", $2); sub(/[[:space:]]+$/, "", $2); print $2; exit }
|
|
20
|
+
' "$manifest"
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
valid_names() {
|
|
24
|
+
case "$1" in *[!A-Za-z0-9_-]*|"") return 1 ;; esac
|
|
25
|
+
case "$2" in *[!A-Za-z0-9._-]*|"") return 1 ;; esac
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
board_path() { printf '%s\n' "$ROOT/companies/$1/board.json"; }
|
|
29
|
+
|
|
30
|
+
update_prompt_state() {
|
|
31
|
+
local company="$1" project="$2" state="$3" board tmp
|
|
32
|
+
board="$(board_path "$company")"
|
|
33
|
+
[ -f "$board" ] || die "no company board for $company"
|
|
34
|
+
jq -e --arg id "$project" 'any(.projects[]?; .id == $id or .mesh_project_id == $id)' "$board" >/dev/null \
|
|
35
|
+
|| die "no local Board project $project for $company"
|
|
36
|
+
tmp="$(mktemp)"
|
|
37
|
+
jq --arg id "$project" --arg state "$state" '
|
|
38
|
+
.projects |= map(if .id == $id or .mesh_project_id == $id then . + {mesh_registration_prompt_state:$state} else . end)
|
|
39
|
+
' "$board" > "$tmp"
|
|
40
|
+
mv "$tmp" "$board"
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
check_offer() {
|
|
44
|
+
local company="$1" project="$2" uid board row_state enabled
|
|
45
|
+
valid_names "$company" "$project" || die "invalid company or project id"
|
|
46
|
+
uid="$(resolve_cloud_uid "$company")"
|
|
47
|
+
[ -n "$uid" ] || { printf 'local\n'; return 0; }
|
|
48
|
+
[[ "$uid" =~ ^cmp_[A-Za-z0-9]{3,128}$ ]] || { printf 'local\n'; return 0; }
|
|
49
|
+
board="$(board_path "$company")"
|
|
50
|
+
[ -f "$board" ] || { printf 'missing\n'; return 0; }
|
|
51
|
+
row_state="$(jq -r --arg id "$project" '
|
|
52
|
+
[.projects[]? | select(.id == $id or .mesh_project_id == $id)] | first |
|
|
53
|
+
if . == null then "missing"
|
|
54
|
+
elif (.threadId // "") != "" and (.channelId // "") != "" then "registered"
|
|
55
|
+
else (.mesh_registration_prompt_state // "offer") end
|
|
56
|
+
' "$board" 2>/dev/null || printf 'missing')"
|
|
57
|
+
case "$row_state" in
|
|
58
|
+
accepted|deferred|registered|missing) printf '%s\n' "$row_state"; return 0 ;;
|
|
59
|
+
esac
|
|
60
|
+
|
|
61
|
+
[ -f "$FLAG_READER" ] && command -v node >/dev/null 2>&1 || { printf 'off\n'; return 0; }
|
|
62
|
+
enabled="$(HQ_COMPANY_UID="$uid" HQ_COMPANY_SLUG="$company" \
|
|
63
|
+
HQ_CLI_BIN="$(command -v hq 2>/dev/null || true)" node "$FLAG_READER" 2>/dev/null || printf 'false')"
|
|
64
|
+
[ "$enabled" = "true" ] && printf 'offer\n' || printf 'off\n'
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if [ "${1:-}" = "--check" ] && [ "$#" -eq 3 ]; then
|
|
68
|
+
check_offer "$2" "$3"
|
|
69
|
+
elif [ "${1:-}" = "--accept" ] && [ "$#" -eq 3 ]; then
|
|
70
|
+
valid_names "$2" "$3" || die "invalid company or project id"
|
|
71
|
+
update_prompt_state "$2" "$3" accepted
|
|
72
|
+
elif [ "${1:-}" = "--defer" ] && [ "$#" -eq 3 ]; then
|
|
73
|
+
valid_names "$2" "$3" || die "invalid company or project id"
|
|
74
|
+
update_prompt_state "$2" "$3" deferred
|
|
75
|
+
else
|
|
76
|
+
die "usage: work-mesh-project-registration-offer.sh --check <company> <project-id> | --accept <company> <project-id> | --defer <company> <project-id>"
|
|
77
|
+
fi
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# workflow-gate.sh — inspect and answer human gates opened by codex-workflow.mjs gate().
|
|
3
|
+
#
|
|
4
|
+
# A gate is a self-contained pending question file written by a paused workflow
|
|
5
|
+
# run; writing a matching answered/<id>.json resumes that run in place. Answers
|
|
6
|
+
# are durable: a re-launched run returns them instantly instead of re-asking
|
|
7
|
+
# the human, so never delete answered/ files while their project is live.
|
|
8
|
+
#
|
|
9
|
+
# Usage:
|
|
10
|
+
# workflow-gate.sh list
|
|
11
|
+
# workflow-gate.sh show <id>
|
|
12
|
+
# workflow-gate.sh answer <id> <choice|N> [--notes "..."] [--by name] [--force] [--freeform]
|
|
13
|
+
# <choice|N> an option label, or a 1-based option index
|
|
14
|
+
# --notes free-text note stored alongside the choice
|
|
15
|
+
# --by who answered (recorded as answered_by)
|
|
16
|
+
# --force pre-answer a gate that has not opened yet, or overwrite an
|
|
17
|
+
# existing answer
|
|
18
|
+
# --freeform accept a choice that is not one of the gate's options
|
|
19
|
+
# workflow-gate.sh wait-pending [--timeout secs]
|
|
20
|
+
# Blocks until any pending gate exists (exit 0) or the timeout elapses
|
|
21
|
+
# (exit 1). Monitor-friendly wake condition for watching sessions.
|
|
22
|
+
# workflow-gate.sh watch-run <run-dir> [--timeout secs]
|
|
23
|
+
# Run-scoped wake condition for the session that launched a workflow.
|
|
24
|
+
# Blocks until a gate belonging to THAT run opens (prints its id, exit 0),
|
|
25
|
+
# the run finishes (exit 3), or --timeout elapses (exit 1). Match is on
|
|
26
|
+
# the run_dir every gate carries, which is the --run-dir the launching
|
|
27
|
+
# session chose — no id parsing, no env coupling, no startup race.
|
|
28
|
+
# workflow-gate.sh clear <id>
|
|
29
|
+
# Remove both the pending and answered files for a gate id.
|
|
30
|
+
#
|
|
31
|
+
# Env: HQ_WORKFLOW_GATES_DIR overrides the gates root (default
|
|
32
|
+
# <hq-root>/workspace/gates); legacy CODEX_WORKFLOW_GATES_DIR is honored.
|
|
33
|
+
|
|
34
|
+
set -uo pipefail
|
|
35
|
+
|
|
36
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
37
|
+
HQ_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
38
|
+
GATES_DIR="${HQ_WORKFLOW_GATES_DIR:-${CODEX_WORKFLOW_GATES_DIR:-$HQ_ROOT/workspace/gates}}"
|
|
39
|
+
PENDING_DIR="$GATES_DIR/pending"
|
|
40
|
+
ANSWERED_DIR="$GATES_DIR/answered"
|
|
41
|
+
|
|
42
|
+
die() { printf 'workflow-gate: %s\n' "$1" >&2; exit 1; }
|
|
43
|
+
usage() { sed -n '2,33p' "$0" | sed 's/^# \{0,1\}//'; exit "${1:-0}"; }
|
|
44
|
+
|
|
45
|
+
# Gate ids are slugged filenames (see the spec) — reject anything else so an id
|
|
46
|
+
# can never traverse outside the gates dir or smuggle path separators.
|
|
47
|
+
require_gate_id() {
|
|
48
|
+
case "$1" in
|
|
49
|
+
(*[!a-z0-9._-]*|'') die "invalid gate id \"$1\" — ids are lowercase [a-z0-9._-]" ;;
|
|
50
|
+
esac
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
cmd="${1:-}"
|
|
54
|
+
[ -n "$cmd" ] || usage 1
|
|
55
|
+
shift
|
|
56
|
+
|
|
57
|
+
case "$cmd" in
|
|
58
|
+
|
|
59
|
+
list)
|
|
60
|
+
if ! ls "$PENDING_DIR"/*.json >/dev/null 2>&1; then
|
|
61
|
+
echo "no pending gates"
|
|
62
|
+
exit 0
|
|
63
|
+
fi
|
|
64
|
+
node -e '
|
|
65
|
+
const fs = require("fs");
|
|
66
|
+
for (const f of process.argv.slice(1)) {
|
|
67
|
+
try {
|
|
68
|
+
const g = JSON.parse(fs.readFileSync(f, "utf8"));
|
|
69
|
+
const ageMin = Math.max(0, Math.round((Date.now() - Date.parse(g.created_at || 0)) / 60000));
|
|
70
|
+
const opts = (g.options || []).map((o, i) => `${i + 1}=${o.label}`).join(" ");
|
|
71
|
+
console.log(`${g.id} (${ageMin}m) ${g.question}${opts ? ` [${opts}]` : ""}`);
|
|
72
|
+
} catch { console.log(`<unreadable> ${f}`); }
|
|
73
|
+
}
|
|
74
|
+
' "$PENDING_DIR"/*.json
|
|
75
|
+
;;
|
|
76
|
+
|
|
77
|
+
show)
|
|
78
|
+
id="${1:-}"
|
|
79
|
+
[ -n "$id" ] || die "usage: show <id>"
|
|
80
|
+
require_gate_id "$id"
|
|
81
|
+
if [ -f "$PENDING_DIR/$id.json" ]; then
|
|
82
|
+
cat "$PENDING_DIR/$id.json"
|
|
83
|
+
elif [ -f "$ANSWERED_DIR/$id.json" ]; then
|
|
84
|
+
cat "$ANSWERED_DIR/$id.json"
|
|
85
|
+
else
|
|
86
|
+
die "no gate \"$id\" in pending or answered"
|
|
87
|
+
fi
|
|
88
|
+
;;
|
|
89
|
+
|
|
90
|
+
answer)
|
|
91
|
+
id="${1:-}"; choice="${2:-}"
|
|
92
|
+
{ [ -n "$id" ] && [ -n "$choice" ]; } || die "usage: answer <id> <choice|N> [--notes ...] [--by name] [--force] [--freeform]"
|
|
93
|
+
require_gate_id "$id"
|
|
94
|
+
shift 2
|
|
95
|
+
notes=""; by=""; force=0; freeform=0
|
|
96
|
+
while [ $# -gt 0 ]; do
|
|
97
|
+
case "$1" in
|
|
98
|
+
--notes) [ $# -ge 2 ] || die "--notes needs a value"; notes="$2"; shift 2 ;;
|
|
99
|
+
--by) [ $# -ge 2 ] || die "--by needs a value"; by="$2"; shift 2 ;;
|
|
100
|
+
--force) force=1; shift ;;
|
|
101
|
+
--freeform) freeform=1; shift ;;
|
|
102
|
+
*) die "unknown flag: $1" ;;
|
|
103
|
+
esac
|
|
104
|
+
done
|
|
105
|
+
JS="$(cat <<'NODE'
|
|
106
|
+
const fs = require("fs");
|
|
107
|
+
const path = require("path");
|
|
108
|
+
const [, pendingDir, answeredDir, id, rawChoice, notes, by, force, freeform] = process.argv;
|
|
109
|
+
const F = force === "1";
|
|
110
|
+
const FF = freeform === "1";
|
|
111
|
+
const pendingFile = path.join(pendingDir, id + ".json");
|
|
112
|
+
const answeredFile = path.join(answeredDir, id + ".json");
|
|
113
|
+
const fail = (m) => { console.error("workflow-gate: " + m); process.exit(1); };
|
|
114
|
+
|
|
115
|
+
let gate = null;
|
|
116
|
+
try { gate = JSON.parse(fs.readFileSync(pendingFile, "utf8")); } catch { /* not pending */ }
|
|
117
|
+
if (!gate && !F) {
|
|
118
|
+
let ids = [];
|
|
119
|
+
try { ids = fs.readdirSync(pendingDir).filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -5)); } catch { /* no dir */ }
|
|
120
|
+
fail(`no pending gate "${id}"${ids.length ? ` — pending: ${ids.join(", ")}` : " — nothing is pending"} (use --force to pre-answer)`);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
let choice = rawChoice;
|
|
124
|
+
const opts = gate && Array.isArray(gate.options) ? gate.options : [];
|
|
125
|
+
if (opts.length) {
|
|
126
|
+
if (/^[0-9]+$/.test(rawChoice)) {
|
|
127
|
+
const n = Number(rawChoice);
|
|
128
|
+
if (n >= 1 && n <= opts.length) choice = opts[n - 1].label;
|
|
129
|
+
else fail(`index ${n} is out of range 1..${opts.length} for "${id}"`);
|
|
130
|
+
} else {
|
|
131
|
+
const hit = opts.find((o) => String(o.label).toLowerCase() === rawChoice.toLowerCase());
|
|
132
|
+
if (hit) choice = hit.label;
|
|
133
|
+
else if (!FF) fail(`"${rawChoice}" is not an option for "${id}" — options: ${opts.map((o) => o.label).join(", ")} (use --freeform to record it anyway)`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (fs.existsSync(answeredFile) && !F) {
|
|
138
|
+
fail(`gate "${id}" is already answered (${answeredFile}) — use --force to overwrite`);
|
|
139
|
+
}
|
|
140
|
+
fs.mkdirSync(answeredDir, { recursive: true });
|
|
141
|
+
const answer = {
|
|
142
|
+
id,
|
|
143
|
+
choice,
|
|
144
|
+
...(notes ? { notes } : {}),
|
|
145
|
+
...(by ? { answered_by: by } : {}),
|
|
146
|
+
answered_at: new Date().toISOString(),
|
|
147
|
+
};
|
|
148
|
+
const tmp = `${answeredFile}.tmp-${process.pid}`;
|
|
149
|
+
fs.writeFileSync(tmp, JSON.stringify(answer, null, 2) + "\n");
|
|
150
|
+
fs.renameSync(tmp, answeredFile);
|
|
151
|
+
try { fs.rmSync(pendingFile, { force: true }); } catch { /* best-effort */ }
|
|
152
|
+
console.log(`answered ${id} -> ${choice}`);
|
|
153
|
+
NODE
|
|
154
|
+
)"
|
|
155
|
+
node -e "$JS" "$PENDING_DIR" "$ANSWERED_DIR" "$id" "$choice" "$notes" "$by" "$force" "$freeform"
|
|
156
|
+
;;
|
|
157
|
+
|
|
158
|
+
wait-pending)
|
|
159
|
+
timeout=""
|
|
160
|
+
while [ $# -gt 0 ]; do
|
|
161
|
+
case "$1" in
|
|
162
|
+
--timeout) [ $# -ge 2 ] || die "--timeout needs a value"; timeout="$2"; shift 2 ;;
|
|
163
|
+
*) die "unknown flag: $1" ;;
|
|
164
|
+
esac
|
|
165
|
+
done
|
|
166
|
+
if [ -n "$timeout" ]; then
|
|
167
|
+
case "$timeout" in
|
|
168
|
+
(*[!0-9]*|'') die "--timeout must be a whole number of seconds" ;;
|
|
169
|
+
esac
|
|
170
|
+
fi
|
|
171
|
+
elapsed=0
|
|
172
|
+
while :; do
|
|
173
|
+
if ls "$PENDING_DIR"/*.json >/dev/null 2>&1; then exit 0; fi
|
|
174
|
+
if [ -n "$timeout" ] && [ "$elapsed" -ge "$timeout" ]; then exit 1; fi
|
|
175
|
+
sleep 1
|
|
176
|
+
elapsed=$((elapsed + 1))
|
|
177
|
+
done
|
|
178
|
+
;;
|
|
179
|
+
|
|
180
|
+
watch-run)
|
|
181
|
+
# Run-scoped wake condition: block until a gate belonging to THIS run opens,
|
|
182
|
+
# or until the run finishes. Gates carry the run_dir the runner was launched
|
|
183
|
+
# with, and the launching session chooses that --run-dir, so matching on it
|
|
184
|
+
# needs no id parsing, no env coupling, and no race at startup.
|
|
185
|
+
# exit 0 + gate id a pending gate for this run
|
|
186
|
+
# exit 3 the run finished (journal.jsonl has run-done)
|
|
187
|
+
# exit 1 --timeout elapsed
|
|
188
|
+
run_dir="${1:-}"
|
|
189
|
+
[ -n "$run_dir" ] || die "usage: watch-run <run-dir> [--timeout secs]"
|
|
190
|
+
case "$run_dir" in -*) die "usage: watch-run <run-dir> [--timeout secs]" ;; esac
|
|
191
|
+
shift
|
|
192
|
+
timeout=""
|
|
193
|
+
while [ $# -gt 0 ]; do
|
|
194
|
+
case "$1" in
|
|
195
|
+
--timeout) [ $# -ge 2 ] || die "--timeout needs a value"; timeout="$2"; shift 2 ;;
|
|
196
|
+
*) die "unknown flag: $1" ;;
|
|
197
|
+
esac
|
|
198
|
+
done
|
|
199
|
+
if [ -n "$timeout" ]; then
|
|
200
|
+
case "$timeout" in
|
|
201
|
+
(*[!0-9]*|'') die "--timeout must be a whole number of seconds" ;;
|
|
202
|
+
esac
|
|
203
|
+
fi
|
|
204
|
+
elapsed=0
|
|
205
|
+
while :; do
|
|
206
|
+
# Gate check first: a gate that opened just before the run ended must
|
|
207
|
+
# still be surfaced rather than swallowed by the run-done exit.
|
|
208
|
+
hit="$(PENDING_DIR="$PENDING_DIR" RUN_DIR="$run_dir" node -e '
|
|
209
|
+
const fs = require("fs"), path = require("path");
|
|
210
|
+
const pendingDir = process.env.PENDING_DIR;
|
|
211
|
+
const want = path.resolve(process.env.RUN_DIR);
|
|
212
|
+
let files = [];
|
|
213
|
+
try { files = fs.readdirSync(pendingDir).filter((f) => f.endsWith(".json")); } catch { process.exit(0); }
|
|
214
|
+
files.sort();
|
|
215
|
+
for (const f of files) {
|
|
216
|
+
try {
|
|
217
|
+
const g = JSON.parse(fs.readFileSync(path.join(pendingDir, f), "utf8"));
|
|
218
|
+
if (g.run_dir && path.resolve(g.run_dir) === want) { console.log(g.id || f.slice(0, -5)); break; }
|
|
219
|
+
} catch { /* half-written or malformed — try the next one */ }
|
|
220
|
+
}
|
|
221
|
+
' 2>/dev/null)"
|
|
222
|
+
if [ -n "$hit" ]; then printf '%s\n' "$hit"; exit 0; fi
|
|
223
|
+
if [ -f "$run_dir/journal.jsonl" ] && grep -q '"event":"run-done"' "$run_dir/journal.jsonl" 2>/dev/null; then
|
|
224
|
+
exit 3
|
|
225
|
+
fi
|
|
226
|
+
if [ -n "$timeout" ] && [ "$elapsed" -ge "$timeout" ]; then exit 1; fi
|
|
227
|
+
sleep 1
|
|
228
|
+
elapsed=$((elapsed + 1))
|
|
229
|
+
done
|
|
230
|
+
;;
|
|
231
|
+
|
|
232
|
+
clear)
|
|
233
|
+
id="${1:-}"
|
|
234
|
+
[ -n "$id" ] || die "usage: clear <id>"
|
|
235
|
+
require_gate_id "$id"
|
|
236
|
+
rm -f "$PENDING_DIR/$id.json" "$ANSWERED_DIR/$id.json"
|
|
237
|
+
echo "cleared $id"
|
|
238
|
+
;;
|
|
239
|
+
|
|
240
|
+
-h|--help|help)
|
|
241
|
+
usage 0
|
|
242
|
+
;;
|
|
243
|
+
|
|
244
|
+
*)
|
|
245
|
+
die "unknown command: $cmd (list | show | answer | wait-pending | watch-run | clear)"
|
|
246
|
+
;;
|
|
247
|
+
esac
|
|
@@ -9596,6 +9596,40 @@ export declare const COMMAND_CATALOG: readonly [{
|
|
|
9596
9596
|
}];
|
|
9597
9597
|
readonly options: readonly [];
|
|
9598
9598
|
readonly subcommands: readonly [];
|
|
9599
|
+
}, {
|
|
9600
|
+
readonly name: "work-mesh-project-registration-offer";
|
|
9601
|
+
readonly description: "Check and record the work-mesh project registration offer";
|
|
9602
|
+
readonly aliases: readonly [];
|
|
9603
|
+
readonly hidden: false;
|
|
9604
|
+
readonly helpOption: false;
|
|
9605
|
+
readonly helpCommand: false;
|
|
9606
|
+
readonly usage: "[args...]";
|
|
9607
|
+
readonly helpText: readonly [];
|
|
9608
|
+
readonly arguments: readonly [{
|
|
9609
|
+
readonly name: "args";
|
|
9610
|
+
readonly required: false;
|
|
9611
|
+
readonly variadic: true;
|
|
9612
|
+
readonly description: "arguments passed through to the script";
|
|
9613
|
+
}];
|
|
9614
|
+
readonly options: readonly [];
|
|
9615
|
+
readonly subcommands: readonly [];
|
|
9616
|
+
}, {
|
|
9617
|
+
readonly name: "workflow-gate";
|
|
9618
|
+
readonly description: "Inspect, answer, and wait for workflow gates";
|
|
9619
|
+
readonly aliases: readonly [];
|
|
9620
|
+
readonly hidden: false;
|
|
9621
|
+
readonly helpOption: false;
|
|
9622
|
+
readonly helpCommand: false;
|
|
9623
|
+
readonly usage: "[args...]";
|
|
9624
|
+
readonly helpText: readonly [];
|
|
9625
|
+
readonly arguments: readonly [{
|
|
9626
|
+
readonly name: "args";
|
|
9627
|
+
readonly required: false;
|
|
9628
|
+
readonly variadic: true;
|
|
9629
|
+
readonly description: "arguments passed through to the script";
|
|
9630
|
+
}];
|
|
9631
|
+
readonly options: readonly [];
|
|
9632
|
+
readonly subcommands: readonly [];
|
|
9599
9633
|
}, {
|
|
9600
9634
|
readonly name: "checkpoint-stop-gate";
|
|
9601
9635
|
readonly description: "Stop-hook checkpoint + company-scope gate (reads the hook payload on stdin)";
|
|
@@ -10431,6 +10465,10 @@ export declare const COMMAND_CATALOG: readonly [{
|
|
|
10431
10465
|
readonly flags: "--assignee <uid|me|none>";
|
|
10432
10466
|
readonly description: "Assign a person or agent uid, yourself, or clear";
|
|
10433
10467
|
readonly hidden: false;
|
|
10468
|
+
}, {
|
|
10469
|
+
readonly flags: "--force";
|
|
10470
|
+
readonly description: "Override another holder's assignment";
|
|
10471
|
+
readonly hidden: false;
|
|
10434
10472
|
}, {
|
|
10435
10473
|
readonly flags: "--company <slug|uid>";
|
|
10436
10474
|
readonly description: "Company slug or cloud uid";
|
|
@@ -10449,6 +10487,138 @@ export declare const COMMAND_CATALOG: readonly [{
|
|
|
10449
10487
|
readonly hidden: false;
|
|
10450
10488
|
}];
|
|
10451
10489
|
readonly subcommands: readonly [];
|
|
10490
|
+
}, {
|
|
10491
|
+
readonly name: "claim";
|
|
10492
|
+
readonly description: "Assign a story to yourself and move it to in_progress";
|
|
10493
|
+
readonly aliases: readonly [];
|
|
10494
|
+
readonly hidden: false;
|
|
10495
|
+
readonly helpOption: true;
|
|
10496
|
+
readonly helpCommand: false;
|
|
10497
|
+
readonly usage: "[options]";
|
|
10498
|
+
readonly helpText: readonly [];
|
|
10499
|
+
readonly arguments: readonly [];
|
|
10500
|
+
readonly options: readonly [{
|
|
10501
|
+
readonly flags: "--story <id>";
|
|
10502
|
+
readonly description: "Story id, e.g. US-001";
|
|
10503
|
+
readonly hidden: false;
|
|
10504
|
+
}, {
|
|
10505
|
+
readonly flags: "--force";
|
|
10506
|
+
readonly description: "Take the story even when someone else holds it";
|
|
10507
|
+
readonly hidden: false;
|
|
10508
|
+
}, {
|
|
10509
|
+
readonly flags: "--company <slug|uid>";
|
|
10510
|
+
readonly description: "Company slug or cloud uid";
|
|
10511
|
+
readonly hidden: false;
|
|
10512
|
+
}, {
|
|
10513
|
+
readonly flags: "--project <slug>";
|
|
10514
|
+
readonly description: "HQ project slug / projectId";
|
|
10515
|
+
readonly hidden: false;
|
|
10516
|
+
}, {
|
|
10517
|
+
readonly flags: "--thread-id <id>";
|
|
10518
|
+
readonly description: "Explicit work thread id";
|
|
10519
|
+
readonly hidden: false;
|
|
10520
|
+
}, {
|
|
10521
|
+
readonly flags: "--json";
|
|
10522
|
+
readonly description: "Print machine-readable JSON";
|
|
10523
|
+
readonly hidden: false;
|
|
10524
|
+
}];
|
|
10525
|
+
readonly subcommands: readonly [];
|
|
10526
|
+
}, {
|
|
10527
|
+
readonly name: "overlap";
|
|
10528
|
+
readonly description: "List other sessions working on the same story, branch, or files";
|
|
10529
|
+
readonly aliases: readonly [];
|
|
10530
|
+
readonly hidden: false;
|
|
10531
|
+
readonly helpOption: true;
|
|
10532
|
+
readonly helpCommand: false;
|
|
10533
|
+
readonly usage: "[options]";
|
|
10534
|
+
readonly helpText: readonly [];
|
|
10535
|
+
readonly arguments: readonly [];
|
|
10536
|
+
readonly options: readonly [{
|
|
10537
|
+
readonly flags: "--company <slug|uid>";
|
|
10538
|
+
readonly description: "Company slug or cloud uid";
|
|
10539
|
+
readonly hidden: false;
|
|
10540
|
+
}, {
|
|
10541
|
+
readonly flags: "--session <sid>";
|
|
10542
|
+
readonly description: "Your session id";
|
|
10543
|
+
readonly hidden: false;
|
|
10544
|
+
}, {
|
|
10545
|
+
readonly flags: "--repo <name>";
|
|
10546
|
+
readonly description: "Repository name";
|
|
10547
|
+
readonly hidden: false;
|
|
10548
|
+
}, {
|
|
10549
|
+
readonly flags: "--branch <branch>";
|
|
10550
|
+
readonly description: "Current branch";
|
|
10551
|
+
readonly hidden: false;
|
|
10552
|
+
}, {
|
|
10553
|
+
readonly flags: "--project <id>";
|
|
10554
|
+
readonly description: "Project id";
|
|
10555
|
+
readonly hidden: false;
|
|
10556
|
+
}, {
|
|
10557
|
+
readonly flags: "--story <id>";
|
|
10558
|
+
readonly description: "Story id";
|
|
10559
|
+
readonly hidden: false;
|
|
10560
|
+
}, {
|
|
10561
|
+
readonly flags: "--file <path>";
|
|
10562
|
+
readonly description: "Repo-relative file you are changing (repeatable)";
|
|
10563
|
+
readonly hidden: false;
|
|
10564
|
+
}, {
|
|
10565
|
+
readonly flags: "--files-json <json>";
|
|
10566
|
+
readonly description: "JSON array of repo-relative file paths";
|
|
10567
|
+
readonly hidden: false;
|
|
10568
|
+
}, {
|
|
10569
|
+
readonly flags: "--json";
|
|
10570
|
+
readonly description: "Print machine-readable JSON";
|
|
10571
|
+
readonly hidden: false;
|
|
10572
|
+
}];
|
|
10573
|
+
readonly subcommands: readonly [];
|
|
10574
|
+
}, {
|
|
10575
|
+
readonly name: "suggest";
|
|
10576
|
+
readonly description: "Rank teammates and agents to pick up a story";
|
|
10577
|
+
readonly aliases: readonly [];
|
|
10578
|
+
readonly hidden: false;
|
|
10579
|
+
readonly helpOption: true;
|
|
10580
|
+
readonly helpCommand: false;
|
|
10581
|
+
readonly usage: "[options]";
|
|
10582
|
+
readonly helpText: readonly [];
|
|
10583
|
+
readonly arguments: readonly [];
|
|
10584
|
+
readonly options: readonly [{
|
|
10585
|
+
readonly flags: "--company <slug|uid>";
|
|
10586
|
+
readonly description: "Company slug or cloud uid";
|
|
10587
|
+
readonly hidden: false;
|
|
10588
|
+
}, {
|
|
10589
|
+
readonly flags: "--project <id>";
|
|
10590
|
+
readonly description: "Project id";
|
|
10591
|
+
readonly hidden: false;
|
|
10592
|
+
}, {
|
|
10593
|
+
readonly flags: "--story <id>";
|
|
10594
|
+
readonly description: "Story id";
|
|
10595
|
+
readonly hidden: false;
|
|
10596
|
+
}, {
|
|
10597
|
+
readonly flags: "--json";
|
|
10598
|
+
readonly description: "Print machine-readable JSON";
|
|
10599
|
+
readonly hidden: false;
|
|
10600
|
+
}];
|
|
10601
|
+
readonly subcommands: readonly [];
|
|
10602
|
+
}, {
|
|
10603
|
+
readonly name: "roster";
|
|
10604
|
+
readonly description: "Show each member's daemon and session reporting state";
|
|
10605
|
+
readonly aliases: readonly [];
|
|
10606
|
+
readonly hidden: false;
|
|
10607
|
+
readonly helpOption: true;
|
|
10608
|
+
readonly helpCommand: false;
|
|
10609
|
+
readonly usage: "[options]";
|
|
10610
|
+
readonly helpText: readonly [];
|
|
10611
|
+
readonly arguments: readonly [];
|
|
10612
|
+
readonly options: readonly [{
|
|
10613
|
+
readonly flags: "--company <slug|uid>";
|
|
10614
|
+
readonly description: "Company slug or cloud uid";
|
|
10615
|
+
readonly hidden: false;
|
|
10616
|
+
}, {
|
|
10617
|
+
readonly flags: "--json";
|
|
10618
|
+
readonly description: "Print machine-readable JSON";
|
|
10619
|
+
readonly hidden: false;
|
|
10620
|
+
}];
|
|
10621
|
+
readonly subcommands: readonly [];
|
|
10452
10622
|
}, {
|
|
10453
10623
|
readonly name: "project";
|
|
10454
10624
|
readonly description: "Set a project Board view or register its project channel";
|
|
@@ -10612,6 +10782,43 @@ export declare const COMMAND_CATALOG: readonly [{
|
|
|
10612
10782
|
readonly hidden: false;
|
|
10613
10783
|
}];
|
|
10614
10784
|
readonly subcommands: readonly [];
|
|
10785
|
+
}, {
|
|
10786
|
+
readonly name: "reassign";
|
|
10787
|
+
readonly description: "Move project ownership to another person or agent";
|
|
10788
|
+
readonly aliases: readonly [];
|
|
10789
|
+
readonly hidden: false;
|
|
10790
|
+
readonly helpOption: true;
|
|
10791
|
+
readonly helpCommand: false;
|
|
10792
|
+
readonly usage: "[options] <projectId>";
|
|
10793
|
+
readonly helpText: readonly [];
|
|
10794
|
+
readonly arguments: readonly [{
|
|
10795
|
+
readonly name: "projectId";
|
|
10796
|
+
readonly required: true;
|
|
10797
|
+
readonly variadic: false;
|
|
10798
|
+
readonly description: "";
|
|
10799
|
+
}];
|
|
10800
|
+
readonly options: readonly [{
|
|
10801
|
+
readonly flags: "--company <slug|uid>";
|
|
10802
|
+
readonly description: "Company slug or cloud uid";
|
|
10803
|
+
readonly hidden: false;
|
|
10804
|
+
}, {
|
|
10805
|
+
readonly flags: "--to <uid|email|name>";
|
|
10806
|
+
readonly description: "New owner (uid, email, or directory name)";
|
|
10807
|
+
readonly hidden: false;
|
|
10808
|
+
}, {
|
|
10809
|
+
readonly flags: "--include-open-stories";
|
|
10810
|
+
readonly description: "Also reassign the project's open stories";
|
|
10811
|
+
readonly hidden: false;
|
|
10812
|
+
}, {
|
|
10813
|
+
readonly flags: "--note <text>";
|
|
10814
|
+
readonly description: "Handoff note";
|
|
10815
|
+
readonly hidden: false;
|
|
10816
|
+
}, {
|
|
10817
|
+
readonly flags: "--json";
|
|
10818
|
+
readonly description: "Print machine-readable JSON";
|
|
10819
|
+
readonly hidden: false;
|
|
10820
|
+
}];
|
|
10821
|
+
readonly subcommands: readonly [];
|
|
10615
10822
|
}, {
|
|
10616
10823
|
readonly name: "member";
|
|
10617
10824
|
readonly description: "Manage project members";
|
|
@@ -10840,6 +11047,38 @@ export declare const COMMAND_CATALOG: readonly [{
|
|
|
10840
11047
|
readonly hidden: false;
|
|
10841
11048
|
}];
|
|
10842
11049
|
readonly subcommands: readonly [];
|
|
11050
|
+
}, {
|
|
11051
|
+
readonly name: "auto-bind";
|
|
11052
|
+
readonly description: "Bind a needs_project session to the project its repo and branch belong to (local-only, fail-open)";
|
|
11053
|
+
readonly aliases: readonly [];
|
|
11054
|
+
readonly hidden: false;
|
|
11055
|
+
readonly helpOption: true;
|
|
11056
|
+
readonly helpCommand: false;
|
|
11057
|
+
readonly usage: "[options]";
|
|
11058
|
+
readonly helpText: readonly [];
|
|
11059
|
+
readonly arguments: readonly [];
|
|
11060
|
+
readonly options: readonly [{
|
|
11061
|
+
readonly flags: "--session <sid>";
|
|
11062
|
+
readonly description: "Canonical session id";
|
|
11063
|
+
readonly hidden: false;
|
|
11064
|
+
}, {
|
|
11065
|
+
readonly flags: "--cwd <dir>";
|
|
11066
|
+
readonly description: "Working directory to read the repo and branch from";
|
|
11067
|
+
readonly hidden: false;
|
|
11068
|
+
}, {
|
|
11069
|
+
readonly flags: "--company <slug>";
|
|
11070
|
+
readonly description: "Company slug (defaults to the session's company)";
|
|
11071
|
+
readonly hidden: false;
|
|
11072
|
+
}, {
|
|
11073
|
+
readonly flags: "--dry-run";
|
|
11074
|
+
readonly description: "Print the decision without binding";
|
|
11075
|
+
readonly hidden: false;
|
|
11076
|
+
}, {
|
|
11077
|
+
readonly flags: "--json";
|
|
11078
|
+
readonly description: "Print machine-readable JSON";
|
|
11079
|
+
readonly hidden: false;
|
|
11080
|
+
}];
|
|
11081
|
+
readonly subcommands: readonly [];
|
|
10843
11082
|
}, {
|
|
10844
11083
|
readonly name: "organize";
|
|
10845
11084
|
readonly description: "List or submit one-time project/task decisions (US-007B / US-005B)";
|