@indigoai-us/hq-cli 5.345.198 → 5.345.199
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 +45 -0
- package/dist/command-catalog.generated.d.ts +106 -6
- package/dist/command-catalog.generated.js +130 -6
- package/dist/commands/bot-events.d.ts +19 -0
- package/dist/commands/bot-events.js +46 -0
- package/dist/commands/bot-jobs.d.ts +2 -0
- package/dist/commands/bot-jobs.js +43 -2
- package/dist/commands/bot.d.ts +5 -0
- package/dist/commands/bot.js +33 -1
- package/dist/commands/lanes-report.d.ts +2 -1
- package/dist/commands/lanes-report.js +44 -1
- package/dist/commands/lanes.d.ts +9 -0
- package/dist/commands/lanes.js +95 -9
- package/dist/commands/meetings.js +1 -21
- package/dist/commands/signals-run.d.ts +2 -0
- package/dist/commands/signals-run.js +6 -1
- package/dist/lanes-drain-hook.js +9 -0
- package/dist/lib/bot/api.d.ts +5 -0
- package/dist/lib/bot/claude-login.d.ts +31 -0
- package/dist/lib/bot/claude-login.js +160 -0
- package/dist/lib/bot/events.d.ts +18 -0
- package/dist/lib/bot/events.js +160 -0
- package/dist/lib/bot/executive-settings.d.ts +10 -0
- package/dist/lib/bot/executive-settings.js +43 -0
- package/dist/lib/bot/fleet-cron.js +4 -0
- package/dist/lib/bot/fleet-local.js +10 -10
- package/dist/lib/bot/job-run.js +1 -1
- package/dist/lib/bot/jobs/hot-signal-sync.d.ts +8 -0
- package/dist/lib/bot/jobs/hot-signal-sync.js +2 -0
- package/dist/lib/bot/jobs/meeting-detect.d.ts +28 -0
- package/dist/lib/bot/jobs/meeting-detect.js +176 -0
- package/dist/lib/bot/jobs/meeting-rider.d.ts +53 -0
- package/dist/lib/bot/jobs/meeting-rider.js +284 -0
- package/dist/lib/bot/jobs/signal-to-lane.d.ts +32 -0
- package/dist/lib/bot/jobs/signal-to-lane.js +169 -0
- package/dist/lib/bot/local-jobs.d.ts +15 -2
- package/dist/lib/bot/local-jobs.js +24 -7
- package/dist/lib/bot/run.d.ts +7 -49
- package/dist/lib/bot/run.js +100 -4
- package/dist/lib/bot/status.d.ts +21 -0
- package/dist/lib/doctor/checks/bots.d.ts +6 -0
- package/dist/lib/doctor/checks/bots.js +47 -1
- package/dist/lib/hot-channels/adapters/meetings.d.ts +1 -0
- package/dist/lib/hot-channels/adapters/meetings.js +3 -1
- package/dist/lib/hot-channels/meeting-source-ref.d.ts +3 -0
- package/dist/lib/hot-channels/meeting-source-ref.js +7 -0
- package/dist/lib/hot-channels/schedule.js +2 -2
- package/dist/lib/hot-channels/signals-pass.d.ts +9 -32
- package/dist/lib/hot-channels/signals-pass.js +51 -17
- package/dist/lib/lanes/admission.d.ts +2 -0
- package/dist/lib/lanes/admission.js +4 -0
- package/dist/lib/lanes/approval-gate.js +4 -1
- package/dist/lib/lanes/links.d.ts +8 -1
- package/dist/lib/lanes/links.js +84 -3
- package/dist/lib/lanes/outcome.d.ts +154 -0
- package/dist/lib/lanes/outcome.js +151 -0
- package/dist/lib/lanes/reconcile.js +1 -0
- package/dist/lib/lanes/signal-brief-template.d.ts +7 -0
- package/dist/lib/lanes/signal-brief-template.js +40 -0
- package/dist/lib/lanes/signal-lane.d.ts +24 -0
- package/dist/lib/lanes/signal-lane.js +99 -0
- package/dist/lib/lanes/source-report.d.ts +37 -0
- package/dist/lib/lanes/source-report.js +66 -0
- package/dist/lib/lanes/spawn.d.ts +6 -0
- package/dist/lib/lanes/spawn.js +21 -0
- package/dist/lib/lanes/store.d.ts +3 -0
- package/dist/lib/lanes/store.js +64 -0
- package/dist/lib/lanes/story-ledger.d.ts +3 -0
- package/dist/lib/lanes/story-ledger.js +1 -0
- package/dist/lib/lanes/types.d.ts +137 -0
- package/dist/lib/lanes/types.js +17 -2
- package/dist/lib/lanes/watcher.js +4 -0
- package/dist/lib/live-meetings.d.ts +19 -0
- package/dist/lib/live-meetings.js +23 -0
- package/dist/lib/mesh/live/daemon/doctor.js +6 -7
- package/dist/lib/mesh/live/spool.d.ts +8 -0
- package/dist/lib/mesh/live/spool.js +59 -40
- package/dist/lib/plan-limit-nag.d.ts +30 -4
- package/dist/lib/plan-limit-nag.js +68 -17
- package/dist/lib/signals/engine.d.ts +4 -0
- package/dist/lib/signals/engine.js +25 -5
- package/dist/lib/signals/incremental.d.ts +42 -0
- package/dist/lib/signals/incremental.js +191 -0
- package/dist/lib/signals/prior-signals.d.ts +11 -0
- package/dist/lib/signals/prior-signals.js +44 -0
- package/dist/lib/signals/reply.js +6 -1
- package/dist/lib/signals/settings.d.ts +5 -0
- package/dist/lib/signals/settings.js +17 -0
- package/dist/lib/signals/steps/extract.d.ts +23 -2
- package/dist/lib/signals/steps/extract.js +142 -9
- package/dist/lib/signals/steps/types.d.ts +1 -0
- package/dist/lib/signals/write-guard.js +7 -0
- package/dist/utils/cognito-callback-port.d.ts +15 -0
- package/dist/utils/cognito-callback-port.js +51 -0
- package/dist/utils/cognito-config.js +2 -3
- package/dist/utils/cognito-session.d.ts +7 -6
- package/dist/utils/cognito-session.js +14 -14
- package/dist/utils/interactive-caller.d.ts +15 -0
- package/dist/utils/interactive-caller.js +70 -0
- package/dist/utils/login-browser.js +3 -1
- package/dist/utils/resident-package-preload.js +4 -0
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,51 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [5.345.199] — 2026-11-04
|
|
6
|
+
- `hq bot status <name>` shows the bot's last reported failure: when, the
|
|
7
|
+
failure class, the plain-language cause and fix the owner was sent, the HQ
|
|
8
|
+
report id, and whether the report was uploaded and the owner DM sent. The
|
|
9
|
+
JSON output carries it as `status.lastFailure`. HQ Fleet Runtime bots write
|
|
10
|
+
it when a turn ends in the canned away line.
|
|
11
|
+
- `hq doctor` checks that a Claude bot on the HQ Fleet Runtime can read a
|
|
12
|
+
Claude Code login the way the runtime reads it (ANTHROPIC_TOKEN,
|
|
13
|
+
CLAUDE_CODE_OAUTH_TOKEN, ANTHROPIC_API_KEY, the HQ Fleet login file,
|
|
14
|
+
~/.claude/.credentials.json, then the macOS Keychain item "Claude
|
|
15
|
+
Code-credentials") and fails with the sources it checked and the fix
|
|
16
|
+
(`claude /login`, then `hq bot restart <name>`). It also fails on a bot's
|
|
17
|
+
last reported failure until a later turn works.
|
|
18
|
+
- `hq bot create` with the Claude provider refuses, before creating any
|
|
19
|
+
identity, when no Claude Code login is readable on this computer, naming
|
|
20
|
+
the sources it checked and the fix.
|
|
21
|
+
- The HQ Fleet profile's bootstrap marker records the hq-cli version that
|
|
22
|
+
installed it, so a bot's failure reports name it.
|
|
23
|
+
- `hq bot create` and `hq bot update` now install HQ Fleet Local 0.4.24 on hq-fleet-runtime d257fdd1, the release that uploads failure reports and DMs the owner.
|
|
24
|
+
- Local CLI bots can run jobs when an event arrives with `hq bot jobs --on` and payload filters. Add `hq bot events emit` and `tail`, durable event queues with journal rotation, and a registry for built-in event handlers that run without a model turn.
|
|
25
|
+
- Lane envelopes can include a structured outcome with gathered facts and next steps. Process and subagent lanes retain it, and `hq lanes status <lane-id> --json` exposes it.
|
|
26
|
+
- The Executive can ride an attended meeting in-process, extract signals every 20 seconds, resume after a bot restart, and emit one meeting-ended event after three terminal polls. The rider respects the desktop opt-out setting.
|
|
27
|
+
- The Executive detects attended live meetings every minute while the desktop is closed, using the same meeting rider setting. Bot status now shows the Executive selection, rider preference, and latest detection source and time.
|
|
28
|
+
- Create an Executive lane directly from an action-item signal with `hq lanes create --company <slug> --signal <id>`. Repeating the command returns the existing lane. Generated briefs include your standing rules, and workers report through your conductor's link.
|
|
29
|
+
- Browser sign-in now refuses a callback port that is not registered with
|
|
30
|
+
Cognito (8765, 3000, 53682). A stray `HQ_COGNITO_CALLBACK_PORT` such as
|
|
31
|
+
57726 opened a sign-in tab that failed with `redirect_mismatch`; the CLI now
|
|
32
|
+
uses 8765 instead and prints a warning on stderr.
|
|
33
|
+
- Background `hq` processes no longer open a browser sign-in tab on their own.
|
|
34
|
+
When a token refresh failed, any caller (daemon, lane, bot, monitor,
|
|
35
|
+
`hq mcp serve`, the sync runner, or a launchd task) fell back to a browser
|
|
36
|
+
sign-in that nobody had started. The implicit sign-in now runs only when
|
|
37
|
+
stdin and stdout are terminals and none of those markers is present; other
|
|
38
|
+
callers get an error that says to run `hq login`. `hq login` is unchanged.
|
|
39
|
+
- The plan-limit warning now says which account it is about ("your personal
|
|
40
|
+
account" or "the <slug> company"), shows storage in GB instead of raw bytes,
|
|
41
|
+
and no longer claims that new files and new secrets are paused. After
|
|
42
|
+
`hq dm --attach` it used to print "storage 47012700666 of 10737418240. New
|
|
43
|
+
files and new secrets are paused." right after the uploads had succeeded.
|
|
44
|
+
- `hq mesh session status` and `hq mesh daemon doctor` no longer crash when a local work-mesh queue file (usually `dead-letter.jsonl`) is larger than 512 MB. Queue counts are now read line by line.
|
|
45
|
+
- The Morning signals job now carries prior signals from the same source into extraction, refreshes longer final-pass bodies in place, and reports new, updated and skipped counts. Live meeting signal IDs and index rows remain stable through the final pass.
|
|
46
|
+
- `hq signals run --company <slug> --source meeting:<id> --incremental` extracts signals while a meeting transcript grows. Landed documents use `<channel>:<file>`. Each source keeps a cursor and prior signal IDs, so unchanged content costs no model turn. Incremental runs default to 12 turns and $0.40, preserve meeting signal references across transcript revisions, and retain signal events for retry.
|
|
47
|
+
- The personal Executive now opens conductor lanes from newly written action-item signals, with one event job per served company and deferred retries when no conductor is linked.
|
|
48
|
+
- `hq lanes report --company <slug> --source <ref>` reports source-linked lane outcomes, pending decisions, progress, and remaining work in text or JSON. Owner wording can be customized in `personal/settings/executive/report.md`.
|
|
49
|
+
|
|
5
50
|
## [5.345.198] — 2026-11-04
|
|
6
51
|
- A personal bot that locked itself to its HQ's only company no longer resumes old conversations under that lock after the HQ gains a second company, loses its only company, or switches to a different one. On restart it archives those conversations and starts fresh, as it already did when a bot's company settings changed. A company bot whose bot.json lists "personal" as well as its company now starts normally after this upgrade, including with unfinished work, instead of stopping with "could not isolate previous company conversations". A personal bot no longer treats an extra top-level manifest key such as `version:` or `deployments:` as a company, and it reads a manifest saved with a UTF-8 byte order mark.
|
|
7
52
|
- A local bot no longer asks "Which company is this for?" in every channel when its HQ has only one company. A personal bot (including one created before bot kinds existed) with no company in bot.json now locks its sessions to the HQ's only company, scheduled jobs included. A bot with two or more real companies stays unbound and does not guess. A "personal" entry in a company bot's membership list no longer counts as a second company.
|
|
@@ -5545,6 +5545,14 @@ export declare const COMMAND_CATALOG: readonly [{
|
|
|
5545
5545
|
readonly flags: "--company <slug>";
|
|
5546
5546
|
readonly description: "Run one company (default: every company listed in the companies manifest)";
|
|
5547
5547
|
readonly hidden: false;
|
|
5548
|
+
}, {
|
|
5549
|
+
readonly flags: "--source <ref>";
|
|
5550
|
+
readonly description: "Read a growing source: meeting:<id> or <channel>:<file> (needs --incremental and --company)";
|
|
5551
|
+
readonly hidden: false;
|
|
5552
|
+
}, {
|
|
5553
|
+
readonly flags: "--incremental";
|
|
5554
|
+
readonly description: "Extract only new signals from --source, retaining a cursor and prior signal ids";
|
|
5555
|
+
readonly hidden: false;
|
|
5548
5556
|
}, {
|
|
5549
5557
|
readonly flags: "--dry-run";
|
|
5550
5558
|
readonly description: "Print what would run; run no mutating step and write nothing";
|
|
@@ -15390,6 +15398,10 @@ export declare const COMMAND_CATALOG: readonly [{
|
|
|
15390
15398
|
readonly flags: "--company <slug>";
|
|
15391
15399
|
readonly description: "Select the company by slug";
|
|
15392
15400
|
readonly hidden: false;
|
|
15401
|
+
}, {
|
|
15402
|
+
readonly flags: "--source <ref>";
|
|
15403
|
+
readonly description: "Report lanes for a source (requires --company; excludes --since)";
|
|
15404
|
+
readonly hidden: false;
|
|
15393
15405
|
}, {
|
|
15394
15406
|
readonly flags: "--since <iso>";
|
|
15395
15407
|
readonly description: "Report activity from this ISO timestamp";
|
|
@@ -15859,7 +15871,23 @@ export declare const COMMAND_CATALOG: readonly [{
|
|
|
15859
15871
|
readonly hidden: false;
|
|
15860
15872
|
}, {
|
|
15861
15873
|
readonly flags: "--project <slug>";
|
|
15862
|
-
readonly description: "HQ project slug";
|
|
15874
|
+
readonly description: "HQ project slug (executive-bot for --signal)";
|
|
15875
|
+
readonly hidden: false;
|
|
15876
|
+
}, {
|
|
15877
|
+
readonly flags: "--signal <id>";
|
|
15878
|
+
readonly description: "Create one lane for a company signal";
|
|
15879
|
+
readonly hidden: false;
|
|
15880
|
+
}, {
|
|
15881
|
+
readonly flags: "--rules-file <path>";
|
|
15882
|
+
readonly description: "Standing rules for a signal lane";
|
|
15883
|
+
readonly hidden: false;
|
|
15884
|
+
}, {
|
|
15885
|
+
readonly flags: "--any-type";
|
|
15886
|
+
readonly description: "Allow signal types other than action_item";
|
|
15887
|
+
readonly hidden: false;
|
|
15888
|
+
}, {
|
|
15889
|
+
readonly flags: "--link <id>";
|
|
15890
|
+
readonly description: "Conductor link for a signal lane";
|
|
15863
15891
|
readonly hidden: false;
|
|
15864
15892
|
}, {
|
|
15865
15893
|
readonly flags: "--story <id>";
|
|
@@ -15879,7 +15907,7 @@ export declare const COMMAND_CATALOG: readonly [{
|
|
|
15879
15907
|
readonly hidden: false;
|
|
15880
15908
|
}, {
|
|
15881
15909
|
readonly flags: "--brief-file <path>";
|
|
15882
|
-
readonly description: "Path to the lane brief";
|
|
15910
|
+
readonly description: "Path to the lane brief (generated for --signal)";
|
|
15883
15911
|
readonly hidden: false;
|
|
15884
15912
|
}, {
|
|
15885
15913
|
readonly flags: "--worker <name>";
|
|
@@ -16435,17 +16463,22 @@ export declare const COMMAND_CATALOG: readonly [{
|
|
|
16435
16463
|
readonly subcommands: readonly [];
|
|
16436
16464
|
}, {
|
|
16437
16465
|
readonly name: "status";
|
|
16438
|
-
readonly description: "Summarize project stories, lanes, PRs, blockers, and pending questions";
|
|
16466
|
+
readonly description: "Summarize project stories, lanes, PRs, blockers, and pending questions; with a lane id, report that lane's outcome";
|
|
16439
16467
|
readonly aliases: readonly [];
|
|
16440
16468
|
readonly hidden: false;
|
|
16441
16469
|
readonly helpOption: true;
|
|
16442
16470
|
readonly helpCommand: false;
|
|
16443
|
-
readonly usage: "[options]";
|
|
16471
|
+
readonly usage: "[options] [lane-id]";
|
|
16444
16472
|
readonly helpText: readonly [];
|
|
16445
|
-
readonly arguments: readonly [
|
|
16473
|
+
readonly arguments: readonly [{
|
|
16474
|
+
readonly name: "lane-id";
|
|
16475
|
+
readonly required: false;
|
|
16476
|
+
readonly variadic: false;
|
|
16477
|
+
readonly description: "Report one lane's state and outcome block instead of a project";
|
|
16478
|
+
}];
|
|
16446
16479
|
readonly options: readonly [{
|
|
16447
16480
|
readonly flags: "--project <slug>";
|
|
16448
|
-
readonly description: "HQ project slug";
|
|
16481
|
+
readonly description: "HQ project slug (required without a lane id)";
|
|
16449
16482
|
readonly hidden: false;
|
|
16450
16483
|
}, {
|
|
16451
16484
|
readonly flags: "--company <slug|uid>";
|
|
@@ -19072,6 +19105,15 @@ export declare const COMMAND_CATALOG: readonly [{
|
|
|
19072
19105
|
readonly flags: "--cron <expr>";
|
|
19073
19106
|
readonly description: "How often, as a cron expression (e.g. \"0 9 * * 1-5\")";
|
|
19074
19107
|
readonly hidden: false;
|
|
19108
|
+
}, {
|
|
19109
|
+
readonly flags: "--on <event>";
|
|
19110
|
+
readonly description: "Run when this event is emitted";
|
|
19111
|
+
readonly hidden: false;
|
|
19112
|
+
}, {
|
|
19113
|
+
readonly flags: "--filter <key=value>";
|
|
19114
|
+
readonly description: "Match an event payload field (repeatable)";
|
|
19115
|
+
readonly hidden: false;
|
|
19116
|
+
readonly defaultValue: readonly [];
|
|
19075
19117
|
}, {
|
|
19076
19118
|
readonly flags: "--tz <zone>";
|
|
19077
19119
|
readonly description: "IANA timezone for the schedule (default: this computer's)";
|
|
@@ -19094,6 +19136,64 @@ export declare const COMMAND_CATALOG: readonly [{
|
|
|
19094
19136
|
readonly hidden: false;
|
|
19095
19137
|
}];
|
|
19096
19138
|
readonly subcommands: readonly [];
|
|
19139
|
+
}, {
|
|
19140
|
+
readonly name: "events";
|
|
19141
|
+
readonly description: "Emit and inspect local bot events";
|
|
19142
|
+
readonly aliases: readonly [];
|
|
19143
|
+
readonly hidden: false;
|
|
19144
|
+
readonly helpOption: true;
|
|
19145
|
+
readonly helpCommand: true;
|
|
19146
|
+
readonly usage: "[options] [command]";
|
|
19147
|
+
readonly helpText: readonly [];
|
|
19148
|
+
readonly arguments: readonly [];
|
|
19149
|
+
readonly options: readonly [];
|
|
19150
|
+
readonly subcommands: readonly [{
|
|
19151
|
+
readonly name: "emit";
|
|
19152
|
+
readonly description: "";
|
|
19153
|
+
readonly aliases: readonly [];
|
|
19154
|
+
readonly hidden: false;
|
|
19155
|
+
readonly helpOption: true;
|
|
19156
|
+
readonly helpCommand: false;
|
|
19157
|
+
readonly usage: "[options] <event>";
|
|
19158
|
+
readonly helpText: readonly [];
|
|
19159
|
+
readonly arguments: readonly [{
|
|
19160
|
+
readonly name: "event";
|
|
19161
|
+
readonly required: true;
|
|
19162
|
+
readonly variadic: false;
|
|
19163
|
+
readonly description: "";
|
|
19164
|
+
}];
|
|
19165
|
+
readonly options: readonly [{
|
|
19166
|
+
readonly flags: "--bot <name>";
|
|
19167
|
+
readonly description: "Bot receiving the event";
|
|
19168
|
+
readonly hidden: false;
|
|
19169
|
+
}, {
|
|
19170
|
+
readonly flags: "--json <payload>";
|
|
19171
|
+
readonly description: "JSON object under 16 KB";
|
|
19172
|
+
readonly hidden: false;
|
|
19173
|
+
}];
|
|
19174
|
+
readonly subcommands: readonly [];
|
|
19175
|
+
}, {
|
|
19176
|
+
readonly name: "tail";
|
|
19177
|
+
readonly description: "";
|
|
19178
|
+
readonly aliases: readonly [];
|
|
19179
|
+
readonly hidden: false;
|
|
19180
|
+
readonly helpOption: true;
|
|
19181
|
+
readonly helpCommand: false;
|
|
19182
|
+
readonly usage: "[options] <name>";
|
|
19183
|
+
readonly helpText: readonly [];
|
|
19184
|
+
readonly arguments: readonly [{
|
|
19185
|
+
readonly name: "name";
|
|
19186
|
+
readonly required: true;
|
|
19187
|
+
readonly variadic: false;
|
|
19188
|
+
readonly description: "";
|
|
19189
|
+
}];
|
|
19190
|
+
readonly options: readonly [{
|
|
19191
|
+
readonly flags: "--json";
|
|
19192
|
+
readonly description: "Print the last 50 events as a JSON array";
|
|
19193
|
+
readonly hidden: false;
|
|
19194
|
+
}];
|
|
19195
|
+
readonly subcommands: readonly [];
|
|
19196
|
+
}];
|
|
19097
19197
|
}, {
|
|
19098
19198
|
readonly name: "promote";
|
|
19099
19199
|
readonly description: "Move this local bot to cloud compute, preserving its identity and private context";
|
|
@@ -6723,6 +6723,16 @@ export const COMMAND_CATALOG = [
|
|
|
6723
6723
|
"description": "Run one company (default: every company listed in the companies manifest)",
|
|
6724
6724
|
"hidden": false
|
|
6725
6725
|
},
|
|
6726
|
+
{
|
|
6727
|
+
"flags": "--source <ref>",
|
|
6728
|
+
"description": "Read a growing source: meeting:<id> or <channel>:<file> (needs --incremental and --company)",
|
|
6729
|
+
"hidden": false
|
|
6730
|
+
},
|
|
6731
|
+
{
|
|
6732
|
+
"flags": "--incremental",
|
|
6733
|
+
"description": "Extract only new signals from --source, retaining a cursor and prior signal ids",
|
|
6734
|
+
"hidden": false
|
|
6735
|
+
},
|
|
6726
6736
|
{
|
|
6727
6737
|
"flags": "--dry-run",
|
|
6728
6738
|
"description": "Print what would run; run no mutating step and write nothing",
|
|
@@ -18754,6 +18764,11 @@ export const COMMAND_CATALOG = [
|
|
|
18754
18764
|
"description": "Select the company by slug",
|
|
18755
18765
|
"hidden": false
|
|
18756
18766
|
},
|
|
18767
|
+
{
|
|
18768
|
+
"flags": "--source <ref>",
|
|
18769
|
+
"description": "Report lanes for a source (requires --company; excludes --since)",
|
|
18770
|
+
"hidden": false
|
|
18771
|
+
},
|
|
18757
18772
|
{
|
|
18758
18773
|
"flags": "--since <iso>",
|
|
18759
18774
|
"description": "Report activity from this ISO timestamp",
|
|
@@ -19323,7 +19338,27 @@ export const COMMAND_CATALOG = [
|
|
|
19323
19338
|
},
|
|
19324
19339
|
{
|
|
19325
19340
|
"flags": "--project <slug>",
|
|
19326
|
-
"description": "HQ project slug",
|
|
19341
|
+
"description": "HQ project slug (executive-bot for --signal)",
|
|
19342
|
+
"hidden": false
|
|
19343
|
+
},
|
|
19344
|
+
{
|
|
19345
|
+
"flags": "--signal <id>",
|
|
19346
|
+
"description": "Create one lane for a company signal",
|
|
19347
|
+
"hidden": false
|
|
19348
|
+
},
|
|
19349
|
+
{
|
|
19350
|
+
"flags": "--rules-file <path>",
|
|
19351
|
+
"description": "Standing rules for a signal lane",
|
|
19352
|
+
"hidden": false
|
|
19353
|
+
},
|
|
19354
|
+
{
|
|
19355
|
+
"flags": "--any-type",
|
|
19356
|
+
"description": "Allow signal types other than action_item",
|
|
19357
|
+
"hidden": false
|
|
19358
|
+
},
|
|
19359
|
+
{
|
|
19360
|
+
"flags": "--link <id>",
|
|
19361
|
+
"description": "Conductor link for a signal lane",
|
|
19327
19362
|
"hidden": false
|
|
19328
19363
|
},
|
|
19329
19364
|
{
|
|
@@ -19348,7 +19383,7 @@ export const COMMAND_CATALOG = [
|
|
|
19348
19383
|
},
|
|
19349
19384
|
{
|
|
19350
19385
|
"flags": "--brief-file <path>",
|
|
19351
|
-
"description": "Path to the lane brief",
|
|
19386
|
+
"description": "Path to the lane brief (generated for --signal)",
|
|
19352
19387
|
"hidden": false
|
|
19353
19388
|
},
|
|
19354
19389
|
{
|
|
@@ -20037,18 +20072,25 @@ export const COMMAND_CATALOG = [
|
|
|
20037
20072
|
},
|
|
20038
20073
|
{
|
|
20039
20074
|
"name": "status",
|
|
20040
|
-
"description": "Summarize project stories, lanes, PRs, blockers, and pending questions",
|
|
20075
|
+
"description": "Summarize project stories, lanes, PRs, blockers, and pending questions; with a lane id, report that lane's outcome",
|
|
20041
20076
|
"aliases": [],
|
|
20042
20077
|
"hidden": false,
|
|
20043
20078
|
"helpOption": true,
|
|
20044
20079
|
"helpCommand": false,
|
|
20045
|
-
"usage": "[options]",
|
|
20080
|
+
"usage": "[options] [lane-id]",
|
|
20046
20081
|
"helpText": [],
|
|
20047
|
-
"arguments": [
|
|
20082
|
+
"arguments": [
|
|
20083
|
+
{
|
|
20084
|
+
"name": "lane-id",
|
|
20085
|
+
"required": false,
|
|
20086
|
+
"variadic": false,
|
|
20087
|
+
"description": "Report one lane's state and outcome block instead of a project"
|
|
20088
|
+
}
|
|
20089
|
+
],
|
|
20048
20090
|
"options": [
|
|
20049
20091
|
{
|
|
20050
20092
|
"flags": "--project <slug>",
|
|
20051
|
-
"description": "HQ project slug",
|
|
20093
|
+
"description": "HQ project slug (required without a lane id)",
|
|
20052
20094
|
"hidden": false
|
|
20053
20095
|
},
|
|
20054
20096
|
{
|
|
@@ -23249,6 +23291,17 @@ export const COMMAND_CATALOG = [
|
|
|
23249
23291
|
"description": "How often, as a cron expression (e.g. \"0 9 * * 1-5\")",
|
|
23250
23292
|
"hidden": false
|
|
23251
23293
|
},
|
|
23294
|
+
{
|
|
23295
|
+
"flags": "--on <event>",
|
|
23296
|
+
"description": "Run when this event is emitted",
|
|
23297
|
+
"hidden": false
|
|
23298
|
+
},
|
|
23299
|
+
{
|
|
23300
|
+
"flags": "--filter <key=value>",
|
|
23301
|
+
"description": "Match an event payload field (repeatable)",
|
|
23302
|
+
"hidden": false,
|
|
23303
|
+
"defaultValue": []
|
|
23304
|
+
},
|
|
23252
23305
|
{
|
|
23253
23306
|
"flags": "--tz <zone>",
|
|
23254
23307
|
"description": "IANA timezone for the schedule (default: this computer's)",
|
|
@@ -23277,6 +23330,77 @@ export const COMMAND_CATALOG = [
|
|
|
23277
23330
|
],
|
|
23278
23331
|
"subcommands": []
|
|
23279
23332
|
},
|
|
23333
|
+
{
|
|
23334
|
+
"name": "events",
|
|
23335
|
+
"description": "Emit and inspect local bot events",
|
|
23336
|
+
"aliases": [],
|
|
23337
|
+
"hidden": false,
|
|
23338
|
+
"helpOption": true,
|
|
23339
|
+
"helpCommand": true,
|
|
23340
|
+
"usage": "[options] [command]",
|
|
23341
|
+
"helpText": [],
|
|
23342
|
+
"arguments": [],
|
|
23343
|
+
"options": [],
|
|
23344
|
+
"subcommands": [
|
|
23345
|
+
{
|
|
23346
|
+
"name": "emit",
|
|
23347
|
+
"description": "",
|
|
23348
|
+
"aliases": [],
|
|
23349
|
+
"hidden": false,
|
|
23350
|
+
"helpOption": true,
|
|
23351
|
+
"helpCommand": false,
|
|
23352
|
+
"usage": "[options] <event>",
|
|
23353
|
+
"helpText": [],
|
|
23354
|
+
"arguments": [
|
|
23355
|
+
{
|
|
23356
|
+
"name": "event",
|
|
23357
|
+
"required": true,
|
|
23358
|
+
"variadic": false,
|
|
23359
|
+
"description": ""
|
|
23360
|
+
}
|
|
23361
|
+
],
|
|
23362
|
+
"options": [
|
|
23363
|
+
{
|
|
23364
|
+
"flags": "--bot <name>",
|
|
23365
|
+
"description": "Bot receiving the event",
|
|
23366
|
+
"hidden": false
|
|
23367
|
+
},
|
|
23368
|
+
{
|
|
23369
|
+
"flags": "--json <payload>",
|
|
23370
|
+
"description": "JSON object under 16 KB",
|
|
23371
|
+
"hidden": false
|
|
23372
|
+
}
|
|
23373
|
+
],
|
|
23374
|
+
"subcommands": []
|
|
23375
|
+
},
|
|
23376
|
+
{
|
|
23377
|
+
"name": "tail",
|
|
23378
|
+
"description": "",
|
|
23379
|
+
"aliases": [],
|
|
23380
|
+
"hidden": false,
|
|
23381
|
+
"helpOption": true,
|
|
23382
|
+
"helpCommand": false,
|
|
23383
|
+
"usage": "[options] <name>",
|
|
23384
|
+
"helpText": [],
|
|
23385
|
+
"arguments": [
|
|
23386
|
+
{
|
|
23387
|
+
"name": "name",
|
|
23388
|
+
"required": true,
|
|
23389
|
+
"variadic": false,
|
|
23390
|
+
"description": ""
|
|
23391
|
+
}
|
|
23392
|
+
],
|
|
23393
|
+
"options": [
|
|
23394
|
+
{
|
|
23395
|
+
"flags": "--json",
|
|
23396
|
+
"description": "Print the last 50 events as a JSON array",
|
|
23397
|
+
"hidden": false
|
|
23398
|
+
}
|
|
23399
|
+
],
|
|
23400
|
+
"subcommands": []
|
|
23401
|
+
}
|
|
23402
|
+
]
|
|
23403
|
+
},
|
|
23280
23404
|
{
|
|
23281
23405
|
"name": "promote",
|
|
23282
23406
|
"description": "Move this local bot to cloud compute, preserving its identity and private context",
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Command } from "commander";
|
|
2
|
+
import { type BotConfig } from "../lib/bot/config.js";
|
|
3
|
+
export interface BotEventsDeps {
|
|
4
|
+
requireBot(name: string): {
|
|
5
|
+
name: string;
|
|
6
|
+
dir: string;
|
|
7
|
+
config: BotConfig;
|
|
8
|
+
};
|
|
9
|
+
out?: (line: string) => void;
|
|
10
|
+
}
|
|
11
|
+
export declare function runBotEventEmit(event: string, opts: {
|
|
12
|
+
bot: string;
|
|
13
|
+
json: string;
|
|
14
|
+
}, deps: BotEventsDeps): void;
|
|
15
|
+
export declare function runBotEventsTail(name: string, opts: {
|
|
16
|
+
json?: boolean;
|
|
17
|
+
}, deps: BotEventsDeps): void;
|
|
18
|
+
export declare function registerBotEventsCommand(bot: Command, deps: BotEventsDeps): void;
|
|
19
|
+
//# sourceMappingURL=bot-events.d.ts.map
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { emitBotEvent, tailBotEvents } from "../lib/bot/events.js";
|
|
2
|
+
import { HQ_FLEET_RUNTIME_ENGINE_ID } from "../lib/bot/config.js";
|
|
3
|
+
export function runBotEventEmit(event, opts, deps) {
|
|
4
|
+
const { dir, config } = deps.requireBot(opts.bot);
|
|
5
|
+
if (config.engine?.id === HQ_FLEET_RUNTIME_ENGINE_ID)
|
|
6
|
+
throw new Error("Event journals require a local CLI bot; HQ Fleet Runtime does not drain them.");
|
|
7
|
+
let payload;
|
|
8
|
+
try {
|
|
9
|
+
payload = JSON.parse(opts.json);
|
|
10
|
+
}
|
|
11
|
+
catch {
|
|
12
|
+
throw new Error("Event payload must be valid JSON.");
|
|
13
|
+
}
|
|
14
|
+
const record = emitBotEvent(dir, event, payload);
|
|
15
|
+
(deps.out ?? console.log)(JSON.stringify(record));
|
|
16
|
+
}
|
|
17
|
+
export function runBotEventsTail(name, opts, deps) {
|
|
18
|
+
const { dir } = deps.requireBot(name);
|
|
19
|
+
const records = tailBotEvents(dir);
|
|
20
|
+
const out = deps.out ?? console.log;
|
|
21
|
+
if (opts.json)
|
|
22
|
+
out(JSON.stringify(records, null, 2));
|
|
23
|
+
else
|
|
24
|
+
for (const record of records)
|
|
25
|
+
out(`${record.at} ${record.event} ${JSON.stringify(record.payload)}`);
|
|
26
|
+
}
|
|
27
|
+
export function registerBotEventsCommand(bot, deps) {
|
|
28
|
+
const events = bot.command("events").description("Emit and inspect local bot events");
|
|
29
|
+
const action = (fn) => {
|
|
30
|
+
try {
|
|
31
|
+
fn();
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
35
|
+
process.exitCode = 1;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
events.command("emit <event>")
|
|
39
|
+
.requiredOption("--bot <name>", "Bot receiving the event")
|
|
40
|
+
.requiredOption("--json <payload>", "JSON object under 16 KB")
|
|
41
|
+
.action((event, opts) => action(() => runBotEventEmit(event, opts, deps)));
|
|
42
|
+
events.command("tail <name>")
|
|
43
|
+
.option("--json", "Print the last 50 events as a JSON array")
|
|
44
|
+
.action((name, opts) => action(() => runBotEventsTail(name, opts, deps)));
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=bot-events.js.map
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* back when it checks what is due.
|
|
17
17
|
*/
|
|
18
18
|
import chalk from "chalk";
|
|
19
|
-
import { localJobsClient } from "../lib/bot/local-jobs.js";
|
|
19
|
+
import { addLocalJob, localJobsClient, readLocalJobs, toJobRecord } from "../lib/bot/local-jobs.js";
|
|
20
20
|
import { BotApiError } from "../lib/bot/api.js";
|
|
21
21
|
import { effectiveBotKind, HQ_FLEET_RUNTIME_ENGINE_ID } from "../lib/bot/config.js";
|
|
22
22
|
import { fleetCronOps, fleetOwnerOrigin, fleetScheduleFromLegacy } from "../lib/bot/fleet-cron.js";
|
|
@@ -318,6 +318,10 @@ export function fleetJobsClient(config, ops, timezone) {
|
|
|
318
318
|
// ─── Reading jobs back ───────────────────────────────────────────────────────
|
|
319
319
|
/** A schedule in plain words, falling back to the raw expression. */
|
|
320
320
|
export function describeSchedule(job) {
|
|
321
|
+
if (job.trigger) {
|
|
322
|
+
const filters = Object.entries(job.trigger.filter ?? {}).map(([key, value]) => `${key}=${value}`).join(", ");
|
|
323
|
+
return `on ${job.trigger.event}${filters ? ` (${filters})` : ""}`;
|
|
324
|
+
}
|
|
321
325
|
const schedule = job.schedule;
|
|
322
326
|
if (!schedule)
|
|
323
327
|
return "on a schedule";
|
|
@@ -391,7 +395,7 @@ export function formatJobsList(botName, jobs, showQuietOption = false) {
|
|
|
391
395
|
lines.push(` runs ${describeSchedule(job)}`);
|
|
392
396
|
if (showQuietOption && isQuietJobContext(job.context))
|
|
393
397
|
lines.push(" delivery: quiet after successful runs");
|
|
394
|
-
lines.push(` next run: ${job.nextRunAt ? `${utcMinute(job.nextRunAt)} UTC` : "not scheduled yet"}`);
|
|
398
|
+
lines.push(` next run: ${job.trigger ? "when a matching event arrives" : job.nextRunAt ? `${utcMinute(job.nextRunAt)} UTC` : "not scheduled yet"}`);
|
|
395
399
|
lines.push(` last run: ${describeLastRun(job)}`);
|
|
396
400
|
}
|
|
397
401
|
return lines.join("\n");
|
|
@@ -454,6 +458,11 @@ export async function runBotJobs(nameArg, opts, deps) {
|
|
|
454
458
|
if (opts.quiet && opts.add === undefined) {
|
|
455
459
|
refuse("Use --quiet with --add to set a scheduled job's delivery option.");
|
|
456
460
|
}
|
|
461
|
+
if (opts.on !== undefined && (opts.add === undefined || opts.every !== undefined || opts.cron !== undefined || opts.tz !== undefined)) {
|
|
462
|
+
refuse("Use --on with --add and without --every, --cron, or --tz.");
|
|
463
|
+
}
|
|
464
|
+
if (opts.filter?.length && opts.on === undefined)
|
|
465
|
+
refuse("Use --filter with --on.");
|
|
457
466
|
// Shared by --add and --reschedule: one schedule from --every or --cron, in
|
|
458
467
|
// the stored form, held to the same floor.
|
|
459
468
|
const scheduleFromOptions = () => {
|
|
@@ -516,6 +525,36 @@ export async function runBotJobs(nameArg, opts, deps) {
|
|
|
516
525
|
if (opts.quiet && !(await quietOptionEnabled())) {
|
|
517
526
|
refuse(`--quiet requires the ${BOT_JOB_QUIET_OPTION_FLAG} flag, which is currently disabled.`);
|
|
518
527
|
}
|
|
528
|
+
if (opts.on !== undefined) {
|
|
529
|
+
if (fleet)
|
|
530
|
+
refuse("Event jobs require a local CLI bot; HQ Fleet Runtime does not drain this event journal.");
|
|
531
|
+
const event = opts.on.trim();
|
|
532
|
+
if (!event || event.length > 256 || /[\r\n]/.test(event))
|
|
533
|
+
refuse("Event name must be 1–256 characters without newlines.");
|
|
534
|
+
const prompt = opts.add.trim();
|
|
535
|
+
if (!prompt || Buffer.byteLength(prompt, "utf8") > MAX_PROMPT_BYTES)
|
|
536
|
+
refuse("Job instruction must be non-empty and at most 16 KB.");
|
|
537
|
+
const filter = Object.create(null);
|
|
538
|
+
for (const entry of opts.filter ?? []) {
|
|
539
|
+
const split = entry.indexOf("=");
|
|
540
|
+
if (split < 1 || !entry.slice(0, split).trim())
|
|
541
|
+
refuse("Each --filter must be key=value.");
|
|
542
|
+
const key = entry.slice(0, split).trim();
|
|
543
|
+
if (Object.hasOwn(filter, key))
|
|
544
|
+
refuse(`Duplicate filter key: ${key}`);
|
|
545
|
+
filter[key] = entry.slice(split + 1);
|
|
546
|
+
}
|
|
547
|
+
if (readLocalJobs(dir).length >= MAX_ACTIVE_JOBS_PER_AGENT)
|
|
548
|
+
refuse(`${name} already has the maximum of ${MAX_ACTIVE_JOBS_PER_AGENT} jobs. Remove one first.`);
|
|
549
|
+
const created = toJobRecord(addLocalJob(dir, {
|
|
550
|
+
prompt,
|
|
551
|
+
timezone: localZone,
|
|
552
|
+
trigger: { kind: "event", event, ...(Object.keys(filter).length ? { filter } : {}) },
|
|
553
|
+
...(opts.quiet ? { context: { [JOB_RUN_OPTIONS_CONTEXT_KEY]: { quiet: true } } } : {}),
|
|
554
|
+
}));
|
|
555
|
+
out(opts.json ? JSON.stringify({ ok: true, job: created }, null, 2) : `Added ${created.jobId}: ${name} runs it ${describeSchedule(created)}.`);
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
519
558
|
const schedule = scheduleFromOptions();
|
|
520
559
|
const body = buildCreateJobBody({ prompt: opts.add, cron: schedule.cron, timezone: schedule.timezone, quiet: opts.quiet });
|
|
521
560
|
const api = await jobsApi();
|
|
@@ -558,6 +597,8 @@ export function registerBotJobsCommand(bot, deps) {
|
|
|
558
597
|
.option("--add <what>", "Schedule new work, in plain language")
|
|
559
598
|
.option("--every <when>", 'How often, in plain language (e.g. "every weekday at 9am")')
|
|
560
599
|
.option("--cron <expr>", 'How often, as a cron expression (e.g. "0 9 * * 1-5")')
|
|
600
|
+
.option("--on <event>", "Run when this event is emitted")
|
|
601
|
+
.option("--filter <key=value>", "Match an event payload field (repeatable)", (value, values) => [...values, value], [])
|
|
561
602
|
.option("--tz <zone>", "IANA timezone for the schedule (default: this computer's)")
|
|
562
603
|
.option("--quiet", "Skip owner DMs after successful runs (requires rollout flag)")
|
|
563
604
|
.option("--rm <jobId>", "Remove a scheduled job")
|
package/dist/commands/bot.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Command } from "commander";
|
|
2
2
|
import { type RuntimeSignInCheck, type RuntimeSignInIssue } from "../lib/bot/runtime-sign-in.js";
|
|
3
|
+
import { type ClaudeLoginCheck } from "../lib/bot/claude-login.js";
|
|
3
4
|
import type { BotStatusFile } from "../lib/bot/status.js";
|
|
4
5
|
import { probeBotRuntime, type RuntimeProbeResult } from "../lib/bot/probe.js";
|
|
5
6
|
import { type SpawnInteractive } from "../lib/bot/runtime-auth.js";
|
|
@@ -115,6 +116,10 @@ export declare function spawnDetachedRun(name: string, dir: string): number;
|
|
|
115
116
|
* "unreadable output: trailing characters").
|
|
116
117
|
*/
|
|
117
118
|
/** Seams for the self-stop path, replaced in tests. */
|
|
119
|
+
export declare const botCreateSeams: {
|
|
120
|
+
/** The Claude Code login read the way the HQ Fleet Runtime reads it. */
|
|
121
|
+
claudeLogin: () => ClaudeLoginCheck;
|
|
122
|
+
};
|
|
118
123
|
export declare const botStopSeams: {
|
|
119
124
|
/** True when this process runs inside the bot process `botPid` (one of its turns). */
|
|
120
125
|
isInsideBot: (botPid: number) => boolean;
|