aiur-cli 0.0.9-nightly.5a0d430 → 0.0.9-nightly.f31ca99
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/bin/aiur.js +37 -17
- package/libexec/aiur-capabilities.sh +12 -0
- package/libexec/aiur-engine.sh +180 -44
- package/libexec/aiur-epic.sh +41 -0
- package/libexec/aiur-queue.sh +107 -0
- package/package.json +7 -4
package/bin/aiur.js
CHANGED
|
@@ -165,8 +165,8 @@ function ensureTmux() {
|
|
|
165
165
|
// True only when the pinned opencode is on PATH; a wrong (e.g. newer,
|
|
166
166
|
// unverified) version must be replaced with the pin, so presence alone
|
|
167
167
|
// isn't enough.
|
|
168
|
-
function opencodeMatchesPin() {
|
|
169
|
-
const result = safeSpawn(
|
|
168
|
+
function opencodeMatchesPin(command = "opencode") {
|
|
169
|
+
const result = safeSpawn(command, ["--version"], { encoding: "utf8" });
|
|
170
170
|
return !result.error && result.status === 0 && (result.stdout || "").trim() === opencodeVersion();
|
|
171
171
|
}
|
|
172
172
|
|
|
@@ -185,40 +185,60 @@ function installOpencode() {
|
|
|
185
185
|
return !result.error && result.status === 0;
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
+
// npm's global bin may be shadowed by another OpenCode on the incoming PATH.
|
|
189
|
+
// Verify the actual installed executable before making it the release's choice.
|
|
190
|
+
function selectGlobalOpencode() {
|
|
191
|
+
const result = safeSpawn("npm", ["prefix", "-g"], { encoding: "utf8" });
|
|
192
|
+
if (result.error || result.status !== 0) return false;
|
|
193
|
+
const prefix = (result.stdout || "").trim();
|
|
194
|
+
if (!path.isAbsolute(prefix)) return false;
|
|
195
|
+
const bin = path.join(prefix, "bin");
|
|
196
|
+
if (!opencodeMatchesPin(path.join(bin, "opencode"))) return false;
|
|
197
|
+
process.env.PATH = `${bin}${path.delimiter}${process.env.PATH || ""}`;
|
|
198
|
+
return true;
|
|
199
|
+
}
|
|
200
|
+
|
|
188
201
|
// opencode powers the interactive "take the wheel" panes. Non-fatal: everything
|
|
189
202
|
// else works without it.
|
|
190
203
|
function ensureOpencode() {
|
|
191
|
-
if (opencodeMatchesPin()) return;
|
|
204
|
+
if (opencodeMatchesPin() || selectGlobalOpencode()) return;
|
|
192
205
|
if (process.env.AIUR_SKIP_OPENCODE_INSTALL !== "1") {
|
|
193
206
|
process.stderr.write(
|
|
194
207
|
`aiur: provisioning opencode@${opencodeVersion()} (one-time, for the interactive 'take the wheel' panes)…\n`,
|
|
195
208
|
);
|
|
196
209
|
installOpencode();
|
|
197
|
-
if (opencodeMatchesPin()) return;
|
|
210
|
+
if (opencodeMatchesPin() || selectGlobalOpencode()) return;
|
|
198
211
|
}
|
|
199
212
|
process.stderr.write(
|
|
200
|
-
|
|
213
|
+
`aiur: opencode@${opencodeVersion()} is unavailable. The interactive 'take the wheel' ` +
|
|
201
214
|
"feature needs it; everything else works without it. " +
|
|
202
|
-
|
|
215
|
+
`Install with: npm install -g opencode-ai@${opencodeVersion()}, ` +
|
|
216
|
+
"and put npm's global bin ahead of other opencode binaries on PATH.\n",
|
|
203
217
|
);
|
|
204
218
|
}
|
|
205
219
|
|
|
206
|
-
//
|
|
207
|
-
//
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
220
|
+
// Match the shared engine's first-argument dispatch: only session launch paths
|
|
221
|
+
// need interactive tools. Unknown commands still reach the engine's usage error.
|
|
222
|
+
function requiresInteractiveTools(argv) {
|
|
223
|
+
const command = argv[0] || "";
|
|
224
|
+
if (["", "run", "restart", "--bg"].includes(command)) return true;
|
|
225
|
+
const nonLaunchCommands = new Set([
|
|
226
|
+
"__identity", "help", "-h", "-help", "--h", "--help", "--version", "--todo", "--only",
|
|
227
|
+
"init", "findings", "ask", "asks", "status", "usage", "agents", "commands", "units",
|
|
228
|
+
"build-orders", "queue", "analytics", "github-cost", "github-usage", "alerts", "watch", "set",
|
|
229
|
+
"upgrade", "pause", "resume", "reset-budget", "message", "cleanup-stale", "stop",
|
|
230
|
+
"executor-answer", "executor-escalate", "executor-moot", "executor-listen", "executor-wait",
|
|
231
|
+
"executor-emit", "executor-subscribe", "executor-unsubscribe", "executor-subscriptions",
|
|
232
|
+
"executor-roster", "executor-fast-forward", "executor-claim", "executor-release", "executor-revoke",
|
|
233
|
+
]);
|
|
234
|
+
if (nonLaunchCommands.has(command)) return false;
|
|
235
|
+
return command.startsWith("-") || fs.existsSync(command);
|
|
216
236
|
}
|
|
217
237
|
|
|
218
238
|
function main() {
|
|
219
239
|
const releaseDir = resolveReleaseDir();
|
|
220
240
|
|
|
221
|
-
if (
|
|
241
|
+
if (requiresInteractiveTools(process.argv.slice(2))) {
|
|
222
242
|
ensureTmux();
|
|
223
243
|
ensureOpencode();
|
|
224
244
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Read-only capability report through the daemon's local control RPC.
|
|
2
|
+
cmd_capabilities() {
|
|
3
|
+
local opts="" arg
|
|
4
|
+
for arg in "$@"; do
|
|
5
|
+
case "$arg" in
|
|
6
|
+
--json) opts="json: true" ;;
|
|
7
|
+
-*) echo "aiur: capabilities received an unknown option: $arg" >&2; exit 64 ;;
|
|
8
|
+
*) echo "aiur: capabilities does not accept positional arguments" >&2; exit 64 ;;
|
|
9
|
+
esac
|
|
10
|
+
done
|
|
11
|
+
run_control_rpc "Aiur.AgentControlCLI.capabilities([$opts])"
|
|
12
|
+
}
|
package/libexec/aiur-engine.sh
CHANGED
|
@@ -20,9 +20,7 @@
|
|
|
20
20
|
#
|
|
21
21
|
# The release is self-contained (bundled ERTS), so it runs without mise/Elixir on
|
|
22
22
|
# PATH. Dev's build-if-stale step lives in the aiurdev shim, not here.
|
|
23
|
-
|
|
24
23
|
set -euo pipefail
|
|
25
|
-
|
|
26
24
|
# Raise the soft open-file limit toward the hard maximum. High agent concurrency
|
|
27
25
|
# spawns many tmux/opencode/git subprocesses + sockets; on hosts with a low
|
|
28
26
|
# default (macOS ships 256) that exhausts file descriptors (:emfile) and crashes
|
|
@@ -34,7 +32,6 @@ elif [ -n "${__aiur_hard_nofile}" ]; then
|
|
|
34
32
|
ulimit -Sn "${__aiur_hard_nofile}" 2>/dev/null || true
|
|
35
33
|
fi
|
|
36
34
|
unset __aiur_hard_nofile
|
|
37
|
-
|
|
38
35
|
# Export the effective soft limit after the best-effort raise. The BEAM uses
|
|
39
36
|
# this inherited value for FD-headroom admission on hosts without procfs,
|
|
40
37
|
# avoiding a runtime `ulimit` subprocess precisely when descriptors are scarce.
|
|
@@ -45,7 +42,6 @@ else
|
|
|
45
42
|
unset AIUR_NOFILE_SOFT_LIMIT
|
|
46
43
|
fi
|
|
47
44
|
unset __aiur_soft_nofile
|
|
48
|
-
|
|
49
45
|
# Preserve the shell that initiated the run as a best-effort Executor root.
|
|
50
46
|
# An explicit positive override wins (service managers may know a better root);
|
|
51
47
|
# otherwise the engine's parent is the nearest identity available before tmux
|
|
@@ -57,12 +53,10 @@ if ! [[ "${AIUR_OPERATOR_PID:-}" =~ ^[1-9][0-9]*$ ]]; then
|
|
|
57
53
|
unset AIUR_OPERATOR_PID
|
|
58
54
|
fi
|
|
59
55
|
fi
|
|
60
|
-
|
|
61
56
|
die() {
|
|
62
57
|
echo "❌ $*" >&2
|
|
63
58
|
exit 1
|
|
64
59
|
}
|
|
65
|
-
|
|
66
60
|
legacy_config_path() {
|
|
67
61
|
while [ "$#" -gt 0 ]; do
|
|
68
62
|
case "$1" in
|
|
@@ -203,7 +197,6 @@ warn_if_cli_behind_release_checkout() {
|
|
|
203
197
|
fi
|
|
204
198
|
}
|
|
205
199
|
|
|
206
|
-
# --- distribution identity (per-instance: keyed by the aiur project root) -----
|
|
207
200
|
|
|
208
201
|
# The aiur project root used to key this instance. AIUR_REPO_ROOT (set by the dev
|
|
209
202
|
# shim) wins. Otherwise walk up from $PWD to the first dir holding a REPO-LOCAL
|
|
@@ -311,7 +304,6 @@ aiur_print_identity() {
|
|
|
311
304
|
printf 'AIUR_COOKIE_FILE=%s\n' "$AIUR_COOKIE_FILE"
|
|
312
305
|
}
|
|
313
306
|
|
|
314
|
-
# --- BEAM distribution (cookie + named node) ---------------------------------
|
|
315
307
|
|
|
316
308
|
ensure_bg_state_dir() {
|
|
317
309
|
aiur_resolve_identity
|
|
@@ -368,7 +360,6 @@ prepare_distribution() {
|
|
|
368
360
|
export AIUR_ERLANG_COOKIE="$RELEASE_COOKIE"
|
|
369
361
|
}
|
|
370
362
|
|
|
371
|
-
# --- release resolution ------------------------------------------------------
|
|
372
363
|
|
|
373
364
|
release_dir=""
|
|
374
365
|
vsn_dir=""
|
|
@@ -405,7 +396,6 @@ resolve_release() {
|
|
|
405
396
|
fi
|
|
406
397
|
}
|
|
407
398
|
|
|
408
|
-
# --- argv round-trip (System.argv is empty under `elixir --eval`) -------------
|
|
409
399
|
|
|
410
400
|
argv_file=""
|
|
411
401
|
init_argv_file() {
|
|
@@ -450,6 +440,9 @@ usage() {
|
|
|
450
440
|
Usage: aiur [--interactive] [--no-dashboard] [--executor] [--pause] [--max-agents <n>] [--logs-root <path>] [--port <port>] [--host <host>] [config-path]
|
|
451
441
|
aiur run [--bg] [--no-dashboard] [--executor] [--debug] explicit launch form (foreground unless --bg)
|
|
452
442
|
aiur init [--force] scaffold .aiur/config (interactive setup wizard)
|
|
443
|
+
aiur login <harness> <name> [--dir <path>] sign in to a supported backend account
|
|
444
|
+
aiur accounts [<harness>] [--json] list registered accounts
|
|
445
|
+
aiur logout <harness> <name> [--purge] remove a backend account
|
|
453
446
|
aiur --bg [--no-dashboard] [--executor] [--debug] start detached; dashboard on unless suppressed
|
|
454
447
|
aiur stop stop the running session
|
|
455
448
|
aiur restart [--no-build] [run flags] stop, refresh the build, start again (detached)
|
|
@@ -460,18 +453,26 @@ Usage: aiur [--interactive] [--no-dashboard] [--executor] [--pause] [--max-agent
|
|
|
460
453
|
aiur executor-escalate <decision-id> --expected-version <n> --reason <text> [--executor-id <id>]
|
|
461
454
|
aiur executor-moot <decision-id> --expected-version <n> --reason-class <class> [--reason <text>] [--executor-id <id>]
|
|
462
455
|
aiur units [--scope live|unfinished|all|none] [--condition active|alert|paused|queued|finished]... [--format auto|table|records] [--json]
|
|
456
|
+
aiur queue show [--queue NAME] [--json] read queue; add/remove/reorder/hold/release/recover/clear steer it
|
|
463
457
|
aiur build-orders [<root>] [--json] show the Build Order catalog or one root
|
|
458
|
+
aiur epic set <epic> <ids...> [--as <who>] [--source cli|backfill-agent] [--json]
|
|
459
|
+
aiur epic clear <ids...> [--as <who>] [--json]
|
|
460
|
+
aiur epic show [<ids...>] [--json]
|
|
461
|
+
aiur epic list [--json]
|
|
464
462
|
aiur analytics [--range run|full] [--since <ISO-8601>] [--until <ISO-8601>] [--build-order <id>] [--json]
|
|
465
463
|
aiur github-cost [--budget graphql|core|all] [--format auto|table|records] [--json] rank GitHub API spend by call site
|
|
464
|
+
aiur capabilities [--json] read-only instance capability report
|
|
466
465
|
aiur github-usage [--json] per-actor (daemon vs agent) GitHub usage and ceilings
|
|
467
466
|
aiur alerts [--needs-attention] show structured alert feed
|
|
468
467
|
aiur watch [--full|--changes] [--interval <secs>] server-side status board
|
|
469
|
-
aiur
|
|
468
|
+
aiur listen [--topic <pattern> | --ticket <id>] stream events as JSON lines
|
|
469
|
+
aiur executor-listen [--topic <pattern>] deprecated alias for listen
|
|
470
470
|
aiur executor-wait [--timeout <seconds>] [--json] block until Executor work arrives
|
|
471
471
|
aiur executor-fast-forward <wake-id> [--as <id>] acknowledge an externally covered wake prefix
|
|
472
472
|
aiur executor-emit <topic> --payload <json> publish an Executor event
|
|
473
473
|
aiur executor-subscribe|executor-unsubscribe <pattern>
|
|
474
474
|
aiur executor-subscriptions list persistent Executor bindings
|
|
475
|
+
aiur workspace-recover <ticket-identifier> <generation> release a held workspace after verified provider exit
|
|
475
476
|
aiur executor-roster [--json] list Executor consumers with their liveness evidence
|
|
476
477
|
aiur executor-claim [--as <id>] claim the wake stream, or refuse and name the live owner
|
|
477
478
|
aiur executor-release [--as <id>] give up this consumer's claim
|
|
@@ -488,14 +489,13 @@ Usage: aiur [--interactive] [--no-dashboard] [--executor] [--pause] [--max-agent
|
|
|
488
489
|
aiur ask <title> [--body <text>|--body-file <path>] [--urgency low|normal|high] [--blocking]
|
|
489
490
|
aiur ask --done <id> [--note <text>] create or resolve an operator request
|
|
490
491
|
aiur asks [--open|--all] [--json] inspect current-repository operator requests
|
|
492
|
+
aiur doctor [--repair] check mise shims; repair only with consent
|
|
491
493
|
aiur cleanup-stale [--dry-run] list/reap stale manual-smoke leftovers
|
|
492
494
|
aiur --version
|
|
493
|
-
|
|
494
495
|
Bare aiur: start or attach to this directory's interactive session.
|
|
495
496
|
EOF
|
|
496
497
|
}
|
|
497
498
|
|
|
498
|
-
# --- one-shot: --version (no tmux) -------------------------------------------
|
|
499
499
|
|
|
500
500
|
run_version() {
|
|
501
501
|
resolve_release
|
|
@@ -511,7 +511,6 @@ run_version() {
|
|
|
511
511
|
exec "${release_cmd[@]}"
|
|
512
512
|
}
|
|
513
513
|
|
|
514
|
-
# --- one-shot: init (interactive wizard, distribution-free, no tmux) ----------
|
|
515
514
|
|
|
516
515
|
run_init() {
|
|
517
516
|
resolve_release
|
|
@@ -522,6 +521,47 @@ run_init() {
|
|
|
522
521
|
exec "${release_cmd[@]}"
|
|
523
522
|
}
|
|
524
523
|
|
|
524
|
+
run_local_cli() {
|
|
525
|
+
resolve_release
|
|
526
|
+
build_init_cmd
|
|
527
|
+
init_argv_file
|
|
528
|
+
write_argv "$@"
|
|
529
|
+
export AIUR_ARGV_FILE="$argv_file"
|
|
530
|
+
exec "${release_cmd[@]}"
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
run_claude_login() {
|
|
534
|
+
resolve_release
|
|
535
|
+
local profile_dir
|
|
536
|
+
build_init_cmd
|
|
537
|
+
init_argv_file
|
|
538
|
+
write_argv "__login_prepare" "${@:2}"
|
|
539
|
+
export AIUR_ARGV_FILE="$argv_file"
|
|
540
|
+
profile_dir="$("${release_cmd[@]}")" || return $?
|
|
541
|
+
[ -n "$profile_dir" ] || { echo "aiur: account profile directory is unavailable" >&2; return 1; }
|
|
542
|
+
exec env "CLAUDE_CONFIG_DIR=$profile_dir" claude
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
run_account_login() {
|
|
546
|
+
local harness="$2"
|
|
547
|
+
case "$harness" in
|
|
548
|
+
kimi|deepseek|openrouter) run_local_cli "$@"; return $? ;;
|
|
549
|
+
esac
|
|
550
|
+
resolve_release
|
|
551
|
+
local profile_dir
|
|
552
|
+
build_init_cmd
|
|
553
|
+
init_argv_file
|
|
554
|
+
write_argv "__login_prepare" "$harness" "${@:3}"
|
|
555
|
+
export AIUR_ARGV_FILE="$argv_file"
|
|
556
|
+
profile_dir="$("${release_cmd[@]}")" || return $?
|
|
557
|
+
[ -n "$profile_dir" ] || { echo "aiur: account profile directory is unavailable" >&2; return 1; }
|
|
558
|
+
case "$harness" in
|
|
559
|
+
claude) exec env "CLAUDE_CONFIG_DIR=$profile_dir" claude ;;
|
|
560
|
+
codex) exec env "CODEX_HOME=$profile_dir" codex ;;
|
|
561
|
+
*) echo "aiur: unsupported account harness: $harness" >&2; return 64 ;;
|
|
562
|
+
esac
|
|
563
|
+
}
|
|
564
|
+
|
|
525
565
|
# --- one-shot: --todo (control RPC; requires a running daemon) ----------------
|
|
526
566
|
|
|
527
567
|
parsed_todo_only=0
|
|
@@ -723,22 +763,10 @@ scrub_run_only_env() {
|
|
|
723
763
|
}
|
|
724
764
|
|
|
725
765
|
run_argv=()
|
|
726
|
-
# Default dashboard bind host.
|
|
727
|
-
#
|
|
728
|
-
# fall back to loopback when Tailscale is absent, or when dashboard credentials
|
|
729
|
-
# are unset (a non-loopback bind requires them, so we stay on loopback rather
|
|
730
|
-
# than refuse to start). The BEAM applies this below an explicit `server.host`,
|
|
731
|
-
# while an explicit `--host` remains the highest-precedence value.
|
|
766
|
+
# Default dashboard bind host. Remote access is an explicit operator choice.
|
|
767
|
+
# The BEAM applies this below `server.host`; `--host` has highest precedence.
|
|
732
768
|
default_dashboard_host() {
|
|
733
|
-
|
|
734
|
-
if command -v tailscale >/dev/null 2>&1; then
|
|
735
|
-
ip="$(tailscale ip -4 2>/dev/null | grep -m1 -E '^100\.[0-9]+\.[0-9]+\.[0-9]+$' || true)"
|
|
736
|
-
fi
|
|
737
|
-
if [ -n "$ip" ] && [ -n "${AIUR_DASHBOARD_USERNAME:-}" ] && [ -n "${AIUR_DASHBOARD_PASSWORD:-}" ]; then
|
|
738
|
-
printf '%s' "$ip"
|
|
739
|
-
else
|
|
740
|
-
printf '127.0.0.1'
|
|
741
|
-
fi
|
|
769
|
+
printf '%s' "${AIUR_DEFAULT_DASHBOARD_HOST:-127.0.0.1}"
|
|
742
770
|
}
|
|
743
771
|
|
|
744
772
|
build_run_argv() {
|
|
@@ -981,7 +1009,7 @@ run_session() {
|
|
|
981
1009
|
AIUR_SESSION_TMPFILE AIUR_AGENT_TMPFILE AIUR_WORKSPACE_ROOT_FILE AIUR_ALERT_LEDGER_PATH_FILE \
|
|
982
1010
|
ELIXIR_ERL_OPTIONS AIUR_LOGS_ROOT AIUR_OPENCODE_BRIDGE_PORT AIUR_DEFAULT_DASHBOARD_HOST AIUR_DEBUG AIUR_DEV_TEST_TICKET_IDS \
|
|
983
1011
|
AIUR_OPERATOR_PID AIUR_LAUNCHER_PID AIUR_NOFILE_SOFT_LIMIT ERL_CRASH_DUMP ERL_CRASH_DUMP_SECONDS \
|
|
984
|
-
AIUR_BG_STATE_DIR AIUR_CLI_VERSION; do
|
|
1012
|
+
AIUR_BG_STATE_DIR AIUR_INSTANCE_KEY AIUR_CLI_VERSION; do
|
|
985
1013
|
if [ -n "${!v:-}" ]; then printf 'export %s=%q\n' "$v" "${!v}"; fi
|
|
986
1014
|
done
|
|
987
1015
|
printf 'capture=%q\n' "$startup_capture"
|
|
@@ -2620,8 +2648,8 @@ parse_issue_targets() {
|
|
|
2620
2648
|
|
|
2621
2649
|
[ "${#parsed_targets[@]}" -gt 0 ]
|
|
2622
2650
|
}
|
|
2623
|
-
|
|
2624
2651
|
cmd_status() {
|
|
2652
|
+
[ ! -f "$engine_dir/aiur-mise-doctor" ] || bash "$engine_dir/aiur-mise-doctor" --check || true
|
|
2625
2653
|
[ "$#" -eq 0 ] || die "status does not accept arguments"
|
|
2626
2654
|
run_control_rpc "Aiur.AgentControlCLI.status()"
|
|
2627
2655
|
}
|
|
@@ -2633,6 +2661,44 @@ cmd_usage() {
|
|
|
2633
2661
|
run_control_rpc "Aiur.AgentControlCLI.usage()"
|
|
2634
2662
|
}
|
|
2635
2663
|
|
|
2664
|
+
cmd_accounts() {
|
|
2665
|
+
local json_arg=false harness="" arg encoded expression
|
|
2666
|
+
for arg in "$@"; do
|
|
2667
|
+
case "$arg" in
|
|
2668
|
+
--json)
|
|
2669
|
+
[ "$json_arg" = false ] || die "accounts accepts --json only once"
|
|
2670
|
+
json_arg=true
|
|
2671
|
+
;;
|
|
2672
|
+
--all)
|
|
2673
|
+
;;
|
|
2674
|
+
-*)
|
|
2675
|
+
die "accounts accepts an optional harness and --json"
|
|
2676
|
+
;;
|
|
2677
|
+
*)
|
|
2678
|
+
[ -z "$harness" ] || die "accounts accepts only one harness"
|
|
2679
|
+
harness="$arg"
|
|
2680
|
+
;;
|
|
2681
|
+
esac
|
|
2682
|
+
done
|
|
2683
|
+
|
|
2684
|
+
resolve_release || return $?
|
|
2685
|
+
prepare_distribution || die "distribution setup failed; cannot contact aiur"
|
|
2686
|
+
resolve_control_identity_from_records
|
|
2687
|
+
if [ "$(probe_node_liveness)" = "down" ]; then
|
|
2688
|
+
# The local one-shot CLI renders the identity and marks usage unavailable.
|
|
2689
|
+
# It never makes a provider request.
|
|
2690
|
+
run_local_cli accounts "$@"
|
|
2691
|
+
else
|
|
2692
|
+
if [ -n "$harness" ]; then
|
|
2693
|
+
encoded="$(printf '%s' "$harness" | base64 | tr -d '\n')"
|
|
2694
|
+
expression="Aiur.AgentControlCLI.accounts($json_arg, Base.decode64!(\"$encoded\"))"
|
|
2695
|
+
else
|
|
2696
|
+
expression="Aiur.AgentControlCLI.accounts($json_arg)"
|
|
2697
|
+
fi
|
|
2698
|
+
run_control_rpc "$expression"
|
|
2699
|
+
fi
|
|
2700
|
+
}
|
|
2701
|
+
|
|
2636
2702
|
cmd_pause_resume() {
|
|
2637
2703
|
local command="$1"
|
|
2638
2704
|
shift
|
|
@@ -2680,6 +2746,16 @@ cmd_reset_budget() {
|
|
|
2680
2746
|
run_control_rpc "$expression"
|
|
2681
2747
|
}
|
|
2682
2748
|
|
|
2749
|
+
# Requires the operator to name the exact ticket and generation shown by
|
|
2750
|
+
# status. The daemon independently verifies the recorded boot proof.
|
|
2751
|
+
cmd_workspace_recover() {
|
|
2752
|
+
[ "$#" -eq 2 ] || { echo "aiur: workspace-recover expects a ticket identifier and generation (e.g. aiur workspace-recover ENG-123 7)" >&2; exit 64; }
|
|
2753
|
+
local ticket="$1" generation="$2" encoded
|
|
2754
|
+
[[ "$generation" =~ ^[1-9][0-9]*$ ]] || { echo "aiur: workspace-recover generation must be a positive integer" >&2; exit 64; }
|
|
2755
|
+
encoded="$(printf '%s' "$ticket" | base64 | tr -d '\n')"
|
|
2756
|
+
run_control_rpc "Aiur.AgentControlCLI.recover_workspace(Base.decode64!(\"$encoded\"), $generation)"
|
|
2757
|
+
}
|
|
2758
|
+
|
|
2683
2759
|
# `aiur message <issue> <text>` — deliver Executor text to one running agent.
|
|
2684
2760
|
# The text is base64-encoded for the RPC hop so arbitrary content (quotes,
|
|
2685
2761
|
# backslashes, `#{}`, newlines) survives without Elixir-string escaping.
|
|
@@ -3073,7 +3149,6 @@ cmd_github_cost() {
|
|
|
3073
3149
|
|
|
3074
3150
|
run_control_rpc "Aiur.AgentControlCLI.github_cost([$opts])"
|
|
3075
3151
|
}
|
|
3076
|
-
|
|
3077
3152
|
# `aiur github-usage` — per-actor (daemon vs each agent workspace) Core/GraphQL
|
|
3078
3153
|
# usage and ceilings from the shared admission broker. Read-only; it reads the
|
|
3079
3154
|
# broker database and issues no GitHub request of its own.
|
|
@@ -3092,10 +3167,8 @@ cmd_github_usage() {
|
|
|
3092
3167
|
|
|
3093
3168
|
local opts=""
|
|
3094
3169
|
[ "$json" -eq 1 ] && opts="json: true"
|
|
3095
|
-
|
|
3096
3170
|
run_control_rpc "Aiur.AgentControlCLI.github_usage([$opts])"
|
|
3097
3171
|
}
|
|
3098
|
-
|
|
3099
3172
|
# `aiur alerts` — newline-delimited structured alert feed from persisted
|
|
3100
3173
|
# per-agent logs. `--needs-attention` filters to Executor-actionable alerts.
|
|
3101
3174
|
cmd_alerts() {
|
|
@@ -3161,21 +3234,61 @@ cmd_watch() {
|
|
|
3161
3234
|
fi
|
|
3162
3235
|
}
|
|
3163
3236
|
|
|
3164
|
-
|
|
3165
|
-
|
|
3237
|
+
listen_clock() { printf '%s' "$SECONDS"; }
|
|
3238
|
+
|
|
3239
|
+
cmd_listen() {
|
|
3240
|
+
local topic="executor.#" ticket="" arg
|
|
3166
3241
|
while [ "$#" -gt 0 ]; do
|
|
3167
3242
|
arg="$1"
|
|
3168
3243
|
case "$arg" in
|
|
3169
3244
|
--topic) shift; topic="${1:-}" ;;
|
|
3170
3245
|
--topic=*) topic="${arg#--topic=}" ;;
|
|
3171
|
-
|
|
3246
|
+
--ticket) shift; ticket="${1:-}" ;;
|
|
3247
|
+
--ticket=*) ticket="${arg#--ticket=}" ;;
|
|
3248
|
+
*) echo "aiur: listen accepts --topic <pattern> or --ticket <id>" >&2; exit 64 ;;
|
|
3172
3249
|
esac
|
|
3173
|
-
[ -n "$topic" ] || { echo "aiur: executor-listen requires a topic" >&2; exit 64; }
|
|
3174
3250
|
shift
|
|
3175
3251
|
done
|
|
3252
|
+
if [ -n "$ticket" ]; then
|
|
3253
|
+
[[ "$ticket" =~ ^[0-9]+$ ]] || { echo "aiur: listen --ticket expects a numeric ticket id" >&2; exit 64; }
|
|
3254
|
+
[ "$topic" = "executor.#" ] || { echo "aiur: listen cannot combine --ticket and --topic" >&2; exit 64; }
|
|
3255
|
+
topic="ticket.${ticket}.#"
|
|
3256
|
+
fi
|
|
3257
|
+
[ -n "$topic" ] || { echo "aiur: listen requires a topic" >&2; exit 64; }
|
|
3176
3258
|
local encoded
|
|
3177
3259
|
encoded="$(printf '%s' "$topic" | base64 | tr -d '\n')"
|
|
3178
|
-
|
|
3260
|
+
run_control_rpc "Aiur.AgentControlCLI.executor_listen_validate(Base.decode64!(\"$encoded\"))" || return $?
|
|
3261
|
+
# A stream that stayed up 30s had a live connection, so losing it starts a
|
|
3262
|
+
# new outage. Each outage gets a bounded backoff totalling ~10 minutes, long
|
|
3263
|
+
# enough to outlast a normal `aiur restart`.
|
|
3264
|
+
# ponytail: attempt duration stands in for "connected"; a wedged daemon whose
|
|
3265
|
+
# RPC hangs 30s+ before failing keeps the listener retrying past the budget.
|
|
3266
|
+
# Upgrade to a listener-ready signal if that case shows up in practice.
|
|
3267
|
+
local waited=0 delay=2 started status
|
|
3268
|
+
while :; do
|
|
3269
|
+
started="$(listen_clock)"
|
|
3270
|
+
status=0
|
|
3271
|
+
# Subshell: a `die` inside (e.g. the release dir missing mid-rebuild during
|
|
3272
|
+
# `aiurdev restart`) fails this attempt with exit 1 instead of the listener.
|
|
3273
|
+
(run_control_stream "Aiur.AgentControlCLI.executor_listen(topic: Base.decode64!(\"$encoded\"))") || status=$?
|
|
3274
|
+
[ "$status" -eq 0 ] && return 0
|
|
3275
|
+
if [ "$status" -ne 1 ] || [ "${AIUR_LISTEN_RECONNECT:-1}" -ne 1 ]; then
|
|
3276
|
+
echo "aiur: listen stopped after streaming control RPC failure (exit ${status}); restart the command after correcting the daemon error" >&2
|
|
3277
|
+
return "$status"
|
|
3278
|
+
fi
|
|
3279
|
+
if [ $(($(listen_clock) - started)) -ge 30 ]; then
|
|
3280
|
+
waited=0
|
|
3281
|
+
delay=2
|
|
3282
|
+
fi
|
|
3283
|
+
if [ "$waited" -ge 600 ]; then
|
|
3284
|
+
echo "aiur: listen could not reconnect within ${waited} seconds; daemon may be unavailable" >&2
|
|
3285
|
+
return 1
|
|
3286
|
+
fi
|
|
3287
|
+
echo "aiur: listen lost the daemon stream (exit ${status}); reconnecting in ${delay} seconds" >&2
|
|
3288
|
+
sleep "$delay"
|
|
3289
|
+
waited=$((waited + delay))
|
|
3290
|
+
delay=$((delay * 2 > 60 ? 60 : delay * 2))
|
|
3291
|
+
done
|
|
3179
3292
|
}
|
|
3180
3293
|
|
|
3181
3294
|
cmd_executor_wait() {
|
|
@@ -4061,8 +4174,8 @@ cmd_upgrade() {
|
|
|
4061
4174
|
}
|
|
4062
4175
|
|
|
4063
4176
|
# --- dispatch ----------------------------------------------------------------
|
|
4064
|
-
|
|
4065
4177
|
dispatch_run() {
|
|
4178
|
+
[ ! -f "$engine_dir/aiur-mise-doctor" ] || bash "$engine_dir/aiur-mise-doctor" --check || true
|
|
4066
4179
|
local mode="foreground" arg
|
|
4067
4180
|
local args=()
|
|
4068
4181
|
|
|
@@ -4080,7 +4193,6 @@ dispatch_run() {
|
|
|
4080
4193
|
# `set -u` — happens for a bare `--bg` run. Guard the expansion.
|
|
4081
4194
|
run_session "$mode" "${args[@]+"${args[@]}"}"
|
|
4082
4195
|
}
|
|
4083
|
-
|
|
4084
4196
|
aiur_engine_main() {
|
|
4085
4197
|
local cmd="${1:-}"
|
|
4086
4198
|
# Names the running subcommand in control-RPC diagnostics so a failure says
|
|
@@ -4106,6 +4218,16 @@ aiur_engine_main() {
|
|
|
4106
4218
|
init)
|
|
4107
4219
|
run_init "$@"
|
|
4108
4220
|
;;
|
|
4221
|
+
login)
|
|
4222
|
+
run_account_login "$@"
|
|
4223
|
+
;;
|
|
4224
|
+
accounts)
|
|
4225
|
+
shift
|
|
4226
|
+
cmd_accounts "$@"
|
|
4227
|
+
;;
|
|
4228
|
+
logout)
|
|
4229
|
+
run_local_cli "$@"
|
|
4230
|
+
;;
|
|
4109
4231
|
findings)
|
|
4110
4232
|
run_findings "$@"
|
|
4111
4233
|
;;
|
|
@@ -4119,6 +4241,7 @@ aiur_engine_main() {
|
|
|
4119
4241
|
shift
|
|
4120
4242
|
dispatch_run "$@"
|
|
4121
4243
|
;;
|
|
4244
|
+
doctor) shift; exec bash "$engine_dir/aiur-mise-doctor" "$@" ;;
|
|
4122
4245
|
status)
|
|
4123
4246
|
shift
|
|
4124
4247
|
cmd_status "$@"
|
|
@@ -4151,6 +4274,11 @@ aiur_engine_main() {
|
|
|
4151
4274
|
shift
|
|
4152
4275
|
cmd_units "$@"
|
|
4153
4276
|
;;
|
|
4277
|
+
queue)
|
|
4278
|
+
shift
|
|
4279
|
+
cmd_queue "$@"
|
|
4280
|
+
;;
|
|
4281
|
+
epic) shift; cmd_epic "$@" ;;
|
|
4154
4282
|
build-orders)
|
|
4155
4283
|
shift
|
|
4156
4284
|
cmd_build_orders "$@"
|
|
@@ -4163,6 +4291,8 @@ aiur_engine_main() {
|
|
|
4163
4291
|
shift
|
|
4164
4292
|
cmd_github_cost "$@"
|
|
4165
4293
|
;;
|
|
4294
|
+
capabilities)
|
|
4295
|
+
shift; cmd_capabilities "$@" ;;
|
|
4166
4296
|
github-usage)
|
|
4167
4297
|
shift
|
|
4168
4298
|
cmd_github_usage "$@"
|
|
@@ -4175,9 +4305,9 @@ aiur_engine_main() {
|
|
|
4175
4305
|
shift
|
|
4176
4306
|
cmd_watch "$@"
|
|
4177
4307
|
;;
|
|
4178
|
-
executor-listen)
|
|
4308
|
+
listen|executor-listen)
|
|
4179
4309
|
shift
|
|
4180
|
-
|
|
4310
|
+
cmd_listen "$@"
|
|
4181
4311
|
;;
|
|
4182
4312
|
executor-wait)
|
|
4183
4313
|
shift
|
|
@@ -4231,6 +4361,10 @@ aiur_engine_main() {
|
|
|
4231
4361
|
shift
|
|
4232
4362
|
cmd_reset_budget "$@"
|
|
4233
4363
|
;;
|
|
4364
|
+
workspace-recover)
|
|
4365
|
+
shift
|
|
4366
|
+
cmd_workspace_recover "$@"
|
|
4367
|
+
;;
|
|
4234
4368
|
message)
|
|
4235
4369
|
shift
|
|
4236
4370
|
cmd_message "$@"
|
|
@@ -4266,7 +4400,9 @@ aiur_engine_main() {
|
|
|
4266
4400
|
;;
|
|
4267
4401
|
esac
|
|
4268
4402
|
}
|
|
4269
|
-
|
|
4403
|
+
source "$(dirname "${BASH_SOURCE[0]}")/aiur-queue.sh"
|
|
4404
|
+
source "$(dirname "${BASH_SOURCE[0]}")/aiur-epic.sh"
|
|
4405
|
+
source "$(dirname "${BASH_SOURCE[0]}")/aiur-capabilities.sh"
|
|
4270
4406
|
if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
|
|
4271
4407
|
aiur_engine_main "$@"
|
|
4272
4408
|
fi
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Shared launcher epic command parser. Sourced by aiur-engine.sh.
|
|
2
|
+
cmd_epic() {
|
|
3
|
+
local action="${1:-}" epic="" who="${USER:-}" source="cli" json=0 ids="" count=0 arg n opts
|
|
4
|
+
[ "$#" -gt 0 ] && shift
|
|
5
|
+
case "$action" in
|
|
6
|
+
set) [ "$#" -gt 0 ] || { echo 'aiur: epic set requires an epic' >&2; exit 64; }; epic="$1"; shift
|
|
7
|
+
[[ "$epic" =~ ^[a-z0-9][a-z0-9_-]{0,63}$ ]] || { echo 'aiur: invalid epic key' >&2; exit 64; } ;;
|
|
8
|
+
clear|show|list) ;;
|
|
9
|
+
*) echo 'aiur: epic requires set, clear, show or list' >&2; exit 64 ;;
|
|
10
|
+
esac
|
|
11
|
+
while [ "$#" -gt 0 ]; do
|
|
12
|
+
arg="$1"
|
|
13
|
+
case "$arg" in
|
|
14
|
+
--json) json=1 ;;
|
|
15
|
+
--as)
|
|
16
|
+
[[ "$action" == set || "$action" == clear ]] && [ "$#" -ge 2 ] || { echo 'aiur: invalid --as' >&2; exit 64; }
|
|
17
|
+
who="$2"; shift ;;
|
|
18
|
+
--source)
|
|
19
|
+
[ "$action" = set ] && [ "$#" -ge 2 ] || { echo 'aiur: invalid --source' >&2; exit 64; }
|
|
20
|
+
source="$2"; shift
|
|
21
|
+
[[ "$source" == cli || "$source" == backfill-agent ]] || { echo 'aiur: invalid epic source' >&2; exit 64; } ;;
|
|
22
|
+
-*) echo 'aiur: unknown epic option' >&2; exit 64 ;;
|
|
23
|
+
*)
|
|
24
|
+
[ "$action" != list ] && [[ "$arg" =~ ^#?[1-9][0-9]{0,9}$ ]] || { echo 'aiur: invalid epic ticket id' >&2; exit 64; }
|
|
25
|
+
n="${arg#\#}"; [ -n "$ids" ] && ids="$ids, "; ids="$ids$n"; count=$((count + 1)) ;;
|
|
26
|
+
esac
|
|
27
|
+
shift
|
|
28
|
+
done
|
|
29
|
+
[ "$count" -le 200 ] || { echo 'aiur: epic accepts at most 200 ids' >&2; exit 64; }
|
|
30
|
+
opts="action: :$action"
|
|
31
|
+
if [[ "$action" == set || "$action" == clear ]]; then
|
|
32
|
+
[ "$count" -gt 0 ] && [[ "$who" =~ ^[A-Za-z0-9._-]{1,64}$ ]] || { echo 'aiur: epic write requires ids and a valid --as or USER' >&2; exit 64; }
|
|
33
|
+
[ "$action" = set ] && opts="$opts, epic: Base.decode64!(\"$(encode_control_value "$epic")\")"
|
|
34
|
+
opts="$opts, ids: [$ids], who: Base.decode64!(\"$(encode_control_value "$who")\")"
|
|
35
|
+
[ "$action" = set ] && { if [ "$source" = cli ]; then opts="$opts, source: :cli"; else opts="$opts, source: :\"backfill-agent\""; fi; }
|
|
36
|
+
elif [ "$count" -gt 0 ]; then
|
|
37
|
+
opts="$opts, ids: [$ids]"
|
|
38
|
+
fi
|
|
39
|
+
[ "$json" -eq 1 ] && opts="$opts, json: true"
|
|
40
|
+
run_control_rpc "Aiur.AgentControlCLI.epic([$opts])"
|
|
41
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Queue commands shared by the installed CLI and aiurdev.
|
|
2
|
+
queue_usage_error() { echo "aiur: queue $*" >&2; exit 64; }
|
|
3
|
+
queue_string() { printf 'Base.decode64!("%s")' "$(printf '%s' "$1" | base64 | tr -d '\n')"; }
|
|
4
|
+
queue_workspace_guard() {
|
|
5
|
+
if [ -n "${AIUR_AGENT_WORKSPACE:-}" ] || [[ "$PWD" == */aiur-workspaces/* ]] ||
|
|
6
|
+
[[ "${AIUR_PROJECT_ROOT:-}" == */aiur-workspaces/* ]] || [[ "${AIUR_REPO_ROOT:-}" == */aiur-workspaces/* ]]; then
|
|
7
|
+
echo 'aiur queue changes are blocked inside agent workspaces' >&2
|
|
8
|
+
exit 64
|
|
9
|
+
fi
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
cmd_queue() {
|
|
13
|
+
local verb="${1:-}" json=0 queue="" after="" at="" to="" root="" start_on="" opts="" id status=0 force=0 remove_markers=0 yes=0
|
|
14
|
+
local ids=()
|
|
15
|
+
case "$verb" in
|
|
16
|
+
show) ;;
|
|
17
|
+
add|set|remove|reorder|hold|release|recover|clear) queue_workspace_guard ;;
|
|
18
|
+
*) queue_usage_error 'expects show, add, set, remove, reorder, hold, release, recover, or clear' ;;
|
|
19
|
+
esac
|
|
20
|
+
shift
|
|
21
|
+
while [ "$#" -gt 0 ]; do
|
|
22
|
+
case "$1" in
|
|
23
|
+
--force) [ "$verb" = recover ] && [ "$force" -eq 0 ] || queue_usage_error '--force requires recover'; force=1 ;;
|
|
24
|
+
--remove-markers) [ "$verb" = clear ] && [ "$remove_markers" -eq 0 ] || queue_usage_error '--remove-markers requires clear'; remove_markers=1 ;;
|
|
25
|
+
--yes) [ "$verb" = clear ] && [ "$yes" -eq 0 ] || queue_usage_error '--yes requires clear'; yes=1 ;;
|
|
26
|
+
--json) [ "$verb" = show ] || queue_usage_error '--json requires show'; json=1 ;;
|
|
27
|
+
--queue)
|
|
28
|
+
[ "$#" -ge 2 ] && [ -n "$2" ] && [[ "$2" != -* ]] || queue_usage_error '--queue requires a name'
|
|
29
|
+
case "$verb" in show|add|hold|release) ;; *) queue_usage_error "--queue is not valid for $verb" ;; esac
|
|
30
|
+
[ -z "$queue" ] || queue_usage_error 'duplicate --queue'
|
|
31
|
+
queue="$2"; shift ;;
|
|
32
|
+
--start-on)
|
|
33
|
+
{ [ "$verb" = add ] || [ "$verb" = set ]; } && [ "$#" -ge 2 ] && [ -z "$start_on" ] || queue_usage_error '--start-on requires add or set and a trigger'
|
|
34
|
+
case "$2" in
|
|
35
|
+
issue_closed|pr_merged|pr_approved|pr_ci_green|pr_opened) ;;
|
|
36
|
+
default) [ "$verb" = set ] || queue_usage_error 'default requires queue set' ;;
|
|
37
|
+
*) queue_usage_error '--start-on must be one of: issue_closed, pr_merged, pr_approved, pr_ci_green, pr_opened (set also accepts default)' ;;
|
|
38
|
+
esac
|
|
39
|
+
start_on="$2"; shift ;;
|
|
40
|
+
--after)
|
|
41
|
+
[ "$verb" = add ] && [ "$#" -ge 2 ] && [[ "$2" =~ ^[1-9][0-9]*$ ]] && [ -z "$after" ] || queue_usage_error '--after requires add and a positive ticket ID'
|
|
42
|
+
after="$2"; shift ;;
|
|
43
|
+
--at)
|
|
44
|
+
[ "$verb" = add ] && [ "$#" -ge 2 ] && [[ "$2" =~ ^(0|[1-9][0-9]*)$ ]] && [ -z "$at" ] || queue_usage_error '--at requires add and a non-negative position'
|
|
45
|
+
at="$2"; shift ;;
|
|
46
|
+
--to)
|
|
47
|
+
[ "$verb" = reorder ] && [ "$#" -ge 2 ] && [[ "$2" =~ ^(0|[1-9][0-9]*)$ ]] && [ -z "$to" ] || queue_usage_error '--to requires reorder and a non-negative position'
|
|
48
|
+
to="$2"; shift ;;
|
|
49
|
+
--build-order)
|
|
50
|
+
[ "$verb" = add ] && [ "$#" -ge 2 ] && [[ "$2" =~ ^[1-9][0-9]*$ ]] && [ -z "$root" ] || queue_usage_error '--build-order requires add and a positive root ID'
|
|
51
|
+
root="$2"; shift ;;
|
|
52
|
+
-*) queue_usage_error "received an unknown argument: $1" ;;
|
|
53
|
+
*)
|
|
54
|
+
if [ "$verb" = set ]; then
|
|
55
|
+
[ -z "$queue" ] && [ -n "$1" ] || queue_usage_error 'set requires exactly one queue name'
|
|
56
|
+
queue="$1"; shift; continue
|
|
57
|
+
fi
|
|
58
|
+
[[ "$1" =~ ^[1-9][0-9]*$ ]] || queue_usage_error "invalid ticket ID: $1"
|
|
59
|
+
for id in "${ids[@]}"; do [ "$id" != "$1" ] || queue_usage_error "duplicate ticket ID: $1"; done
|
|
60
|
+
ids+=("$1") ;;
|
|
61
|
+
esac
|
|
62
|
+
shift
|
|
63
|
+
done
|
|
64
|
+
case "$verb" in
|
|
65
|
+
show) [ "${#ids[@]}" -eq 0 ] || queue_usage_error 'show does not take ticket IDs' ;;
|
|
66
|
+
add)
|
|
67
|
+
if [ -n "$root" ]; then
|
|
68
|
+
[ "${#ids[@]}" -eq 0 ] && [ -z "$after$at" ] || queue_usage_error '--build-order cannot be combined with ticket IDs, --after, or --at'
|
|
69
|
+
else
|
|
70
|
+
[ "${#ids[@]}" -gt 0 ] || queue_usage_error 'add requires ticket IDs or --build-order'
|
|
71
|
+
fi ;;
|
|
72
|
+
set) [ -n "$queue" ] && [ -n "$start_on" ] || queue_usage_error 'set requires a queue name and --start-on TRIGGER|default' ;;
|
|
73
|
+
recover) [ "${#ids[@]}" -eq 0 ] || queue_usage_error 'recover does not take ticket IDs' ;;
|
|
74
|
+
clear)
|
|
75
|
+
[ "${#ids[@]}" -eq 0 ] && [ "$remove_markers" -eq 1 ] || queue_usage_error 'clear requires --remove-markers and no ticket IDs'
|
|
76
|
+
[ "$yes" -eq 1 ] || { echo 'aiur: queue clear requires --yes; removes all queue membership and markers, keeping todo' >&2; exit 1; } ;;
|
|
77
|
+
remove) [ "${#ids[@]}" -gt 0 ] || queue_usage_error 'remove requires ticket IDs' ;;
|
|
78
|
+
reorder) [ "${#ids[@]}" -eq 1 ] && [ -n "$to" ] || queue_usage_error 'reorder requires one ticket ID and --to POS' ;;
|
|
79
|
+
hold|release)
|
|
80
|
+
{ [ "${#ids[@]}" -eq 1 ] && [ -z "$queue" ]; } ||
|
|
81
|
+
{ [ "${#ids[@]}" -eq 0 ] && [ -n "$queue" ]; } || queue_usage_error "$verb requires one ticket ID or --queue NAME" ;;
|
|
82
|
+
esac
|
|
83
|
+
if [ "$verb" != show ]; then
|
|
84
|
+
opts="verb: :$verb, caller_agent_workspace: $(queue_string "${AIUR_AGENT_WORKSPACE:-}")"
|
|
85
|
+
fi
|
|
86
|
+
[ "$force" -eq 1 ] && opts="$opts, force: true"
|
|
87
|
+
[ "$remove_markers" -eq 1 ] && opts="$opts, remove_markers: true"
|
|
88
|
+
[ "$yes" -eq 1 ] && opts="$opts, yes: true"
|
|
89
|
+
[ "$json" -eq 1 ] && opts="json: true"
|
|
90
|
+
[ -n "$queue" ] && opts="${opts:+$opts, }queue: $(queue_string "$queue")"
|
|
91
|
+
[ -n "$start_on" ] && opts="$opts, start_on: $(queue_string "$start_on")"
|
|
92
|
+
[ -n "$root" ] && opts="$opts, build_order: $root"
|
|
93
|
+
[ -n "$after" ] && opts="$opts, after: \"$after\""
|
|
94
|
+
[ -n "$at" ] && opts="$opts, at: $at"
|
|
95
|
+
[ -n "$to" ] && opts="$opts, to: $to"
|
|
96
|
+
if [ "${#ids[@]}" -gt 0 ]; then
|
|
97
|
+
opts="$opts, ids: ["
|
|
98
|
+
for id in "${ids[@]}"; do opts="$opts\"$id\","; done
|
|
99
|
+
opts="${opts%,}]"
|
|
100
|
+
fi
|
|
101
|
+
if [ "$verb" = add ] || [ "$verb" = remove ]; then
|
|
102
|
+
AIUR_CONTROL_RPC_TIMEOUT_SECONDS="$(todo_rpc_seconds "${#ids[@]}" 0)"
|
|
103
|
+
fi
|
|
104
|
+
AIUR_CONTROL_COMMAND="queue $verb" run_control_rpc "Aiur.AgentControlCLI.queue([$opts])" || status=$?
|
|
105
|
+
if [ "$status" -eq 124 ]; then echo 'aiur: queue outcome unknown; run aiur queue show before retrying' >&2; fi
|
|
106
|
+
return "$status"
|
|
107
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aiur-cli",
|
|
3
|
-
"version": "0.0.9-nightly.
|
|
3
|
+
"version": "0.0.9-nightly.f31ca99",
|
|
4
4
|
"description": "AI Unit Runtime for Executors.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://github.com/aiur-team/aiur",
|
|
@@ -18,6 +18,9 @@
|
|
|
18
18
|
"files": [
|
|
19
19
|
"bin/aiur.js",
|
|
20
20
|
"libexec/aiur-engine.sh",
|
|
21
|
+
"libexec/aiur-queue.sh",
|
|
22
|
+
"libexec/aiur-epic.sh",
|
|
23
|
+
"libexec/aiur-capabilities.sh",
|
|
21
24
|
"libexec/aiur-pane-ctrlc",
|
|
22
25
|
"scripts/postinstall.mjs",
|
|
23
26
|
"share/aiur.tmux.conf"
|
|
@@ -35,8 +38,8 @@
|
|
|
35
38
|
],
|
|
36
39
|
"opencodeVersion": "1.17.10",
|
|
37
40
|
"optionalDependencies": {
|
|
38
|
-
"aiur-cli-linux-x64": "0.0.9-nightly.
|
|
39
|
-
"aiur-cli-linux-arm64": "0.0.9-nightly.
|
|
40
|
-
"aiur-cli-darwin-arm64": "0.0.9-nightly.
|
|
41
|
+
"aiur-cli-linux-x64": "0.0.9-nightly.f31ca99",
|
|
42
|
+
"aiur-cli-linux-arm64": "0.0.9-nightly.f31ca99",
|
|
43
|
+
"aiur-cli-darwin-arm64": "0.0.9-nightly.f31ca99"
|
|
41
44
|
}
|
|
42
45
|
}
|