@indigoai-us/hq-cli 5.345.177 → 5.345.179
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 +50 -0
- package/dist/command-catalog.generated.d.ts +79 -1
- package/dist/command-catalog.generated.js +96 -1
- package/dist/commands/bot-jobs.d.ts +11 -9
- package/dist/commands/bot-jobs.js +56 -21
- package/dist/commands/bot.d.ts +13 -0
- package/dist/commands/bot.js +230 -21
- package/dist/commands/cloud.d.ts +49 -0
- package/dist/commands/cloud.js +155 -15
- package/dist/commands/daemon.d.ts +2 -0
- package/dist/commands/daemon.js +15 -4
- package/dist/commands/dm-attach.js +15 -3
- package/dist/commands/integrations-core.d.ts +2 -0
- package/dist/commands/integrations-core.js +1 -0
- package/dist/commands/library-add.d.ts +9 -0
- package/dist/commands/library-add.js +19 -2
- package/dist/commands/run.js +9 -1
- package/dist/commands/sources.d.ts +89 -0
- package/dist/commands/sources.js +363 -1
- package/dist/lib/bot/config.d.ts +2 -0
- package/dist/lib/bot/fleet-default-flag.d.ts +31 -0
- package/dist/lib/bot/fleet-default-flag.js +127 -0
- package/dist/lib/bot/fleet-local.d.ts +30 -1
- package/dist/lib/bot/fleet-local.js +86 -11
- package/dist/lib/bot/index.d.ts +1 -0
- package/dist/lib/bot/index.js +1 -0
- package/dist/lib/bot/jobs/hot-signal-sync.d.ts +109 -0
- package/dist/lib/bot/jobs/hot-signal-sync.js +177 -0
- package/dist/lib/bot/local-config.js +1 -1
- package/dist/lib/bot/local-jobs.d.ts +40 -4
- package/dist/lib/bot/local-jobs.js +72 -5
- package/dist/lib/bot/run.d.ts +15 -0
- package/dist/lib/bot/run.js +61 -0
- package/dist/lib/daemon/catalog.d.ts +2 -0
- package/dist/lib/daemon/catalog.js +7 -2
- package/dist/lib/daemon/config.d.ts +2 -1
- package/dist/lib/daemon/config.js +4 -3
- package/dist/lib/daemon/handoff.d.ts +4 -0
- package/dist/lib/daemon/handoff.js +6 -2
- package/dist/lib/daemon/install.d.ts +70 -2
- package/dist/lib/daemon/install.js +185 -27
- package/dist/lib/daemon/legacy.d.ts +9 -3
- package/dist/lib/daemon/legacy.js +11 -4
- package/dist/lib/daemon/migrate.js +1 -1
- package/dist/lib/daemon/run.d.ts +3 -2
- package/dist/lib/daemon/run.js +10 -6
- package/dist/lib/doctor/checks/anywhere.d.ts +6 -0
- package/dist/lib/doctor/checks/anywhere.js +35 -6
- package/dist/lib/hot-channels/adapters/__fixtures__/dummy.d.ts +33 -0
- package/dist/lib/hot-channels/adapters/__fixtures__/dummy.js +53 -0
- package/dist/lib/hot-channels/adapters/__fixtures__/meeting-providers.d.ts +38 -0
- package/dist/lib/hot-channels/adapters/__fixtures__/meeting-providers.js +64 -0
- package/dist/lib/hot-channels/adapters/attio.d.ts +67 -0
- package/dist/lib/hot-channels/adapters/attio.js +374 -0
- package/dist/lib/hot-channels/adapters/gmail.d.ts +111 -0
- package/dist/lib/hot-channels/adapters/gmail.js +413 -0
- package/dist/lib/hot-channels/adapters/index.d.ts +23 -0
- package/dist/lib/hot-channels/adapters/index.js +39 -0
- package/dist/lib/hot-channels/adapters/linear.d.ts +79 -0
- package/dist/lib/hot-channels/adapters/linear.js +321 -0
- package/dist/lib/hot-channels/adapters/meeting-providers.d.ts +86 -0
- package/dist/lib/hot-channels/adapters/meeting-providers.js +253 -0
- package/dist/lib/hot-channels/adapters/meetings.d.ts +81 -0
- package/dist/lib/hot-channels/adapters/meetings.js +523 -0
- package/dist/lib/hot-channels/adapters/slack.d.ts +70 -0
- package/dist/lib/hot-channels/adapters/slack.js +277 -0
- package/dist/lib/hot-channels/alert.d.ts +78 -0
- package/dist/lib/hot-channels/alert.js +179 -0
- package/dist/lib/hot-channels/audience.d.ts +15 -0
- package/dist/lib/hot-channels/audience.js +25 -0
- package/dist/lib/hot-channels/contract.d.ts +140 -0
- package/dist/lib/hot-channels/contract.js +20 -0
- package/dist/lib/hot-channels/cursors.d.ts +41 -0
- package/dist/lib/hot-channels/cursors.js +84 -0
- package/dist/lib/hot-channels/index.d.ts +10 -0
- package/dist/lib/hot-channels/index.js +10 -0
- package/dist/lib/hot-channels/landing.d.ts +83 -0
- package/dist/lib/hot-channels/landing.js +175 -0
- package/dist/lib/hot-channels/ledger.d.ts +101 -0
- package/dist/lib/hot-channels/ledger.js +186 -0
- package/dist/lib/hot-channels/loop.d.ts +74 -0
- package/dist/lib/hot-channels/loop.js +219 -0
- package/dist/lib/hot-channels/prompts/signals-pass.md +22 -0
- package/dist/lib/hot-channels/registry.d.ts +28 -0
- package/dist/lib/hot-channels/registry.js +121 -0
- package/dist/lib/hot-channels/run.d.ts +137 -0
- package/dist/lib/hot-channels/run.js +324 -0
- package/dist/lib/hot-channels/signals-pass.d.ts +150 -0
- package/dist/lib/hot-channels/signals-pass.js +581 -0
- package/dist/lib/hot-channels/sync-lock.d.ts +51 -0
- package/dist/lib/hot-channels/sync-lock.js +224 -0
- package/dist/lib/install/hook-target.d.ts +6 -2
- package/dist/lib/install/hook-target.js +9 -4
- package/dist/lib/lanes/loop.d.ts +10 -0
- package/dist/lib/lanes/loop.js +18 -1
- package/dist/lib/mesh/live/daemon/work-subscribe.d.ts +1 -0
- package/dist/lib/mesh/live/daemon/work-subscribe.js +26 -6
- package/dist/run/hq-plugin.d.ts +3 -0
- package/dist/run/hq-plugin.js +18 -0
- package/package.json +7 -7
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,56 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [5.345.179] — 2026-10-29
|
|
6
|
+
- Conduct loop lanes now count a phase's absolute `deadline` from when the lane starts the phase, so time the envelope spent waiting in the queue no longer eats its run budget. An unparsable `deadline` now falls back to the phase's normal budget instead of an invalid one.
|
|
7
|
+
- Pins hq-fleet-local v0.4.13 so a personal bot's first-start kickoff waits for HQ Fleet Runtime to attach before delivery instead of being dropped during startup.
|
|
8
|
+
- `hq sources sync` runs every hot channel now for the signed-in person: each adapter once per integration connection the person created or was granted, through the HQ integration gateway. It prints sources landed per adapter and connection. A signed-out session or a revoked connection prints a reconnect prompt naming the connection, exits non-zero, and leaves the cursor unchanged. Use `--adapter <id>` to run one adapter and `--company <slug>` to pick the company. Catalog channels with no adapter in this build report "adapter not available in this hq version".
|
|
9
|
+
- `hq sources runs --today` shows the hot-channel run log for the signed-in person: per adapter, the sources each run landed and the signals it generated, with start and finish times and any error. Cursors live at `sources/_cursors/@{personKey}/` and each run appends to `sources/_runs/@{personKey}/{day}.jsonl`, where the person key is a short hash of the person's email.
|
|
10
|
+
- `hq bot run` registers a built-in hot-channel sync job for the bot's company: daily at 06:30 in the computer's time zone, run inside the bot with no model turn. If the computer was asleep at 06:30, the job runs once when it wakes and the ledger records `catchUp: true`. No crontab or launchd entry is written. Change the time with the new `hq bot jobs <bot> --reschedule <jobId> --every "..."` (or `--cron`); a removed job is not added back.
|
|
11
|
+
- Only one hot-channel sync runs at a time per person and company. If the bot's scheduled run and `hq sources sync` overlap, the second one lands nothing, says another sync is running, and writes a `skipped` line to the run log.
|
|
12
|
+
- Linear: issues assigned to you that changed since the last sync land as source documents.
|
|
13
|
+
- Slack: threads HQ has saved to your company vault that you are part of become one signal each, pointing at the thread with no message text copied. A Slack rate-limit pause is reported with a prompt to retry or reconnect.
|
|
14
|
+
- Attio: activity HQ has saved to your company vault becomes signals only when it is about you (changes you made, records you own, comments or notes that mention or are assigned to you), with no payload copied.
|
|
15
|
+
- Meetings: transcripts already in `sources/meetings/` that you attended land as short pointer documents under `sources/meeting-events/`, with no transcript text copied.
|
|
16
|
+
- Gmail ships behind the `hq.hot-channel-gmail` flag. While the flag is off, Gmail is listed as `gated` and never called. With it on, new INBOX mail lands as header-only pointers (never the body or snippet) with a read-only scope.
|
|
17
|
+
- Newly landed sources are turned into signals with your own logged-in `claude`: up to 20 documents per run, each signal linked to its source and listed in the day's signal index. Signals from meetings, Slack and Attio use the full saved content each pointer names (up to 200 KB). A logged-out `claude`, a timeout, bad output, or any other error in one adapter's signals step marks that adapter failed in the run log and the run continues with the next adapter.
|
|
18
|
+
- One malformed event from a channel is skipped and counted as rejected in the run log, with the reason, instead of stopping that channel on every later run.
|
|
19
|
+
- Hot-channel syncs alert when sources land but no signals come out: the bot DMs you and `hq sources sync` prints the alert, at most once an hour per connection. Set `signals_alert_channel: <Slack channel id>` in the company's `settings/signals/preferences.yaml` to also post it to Slack.
|
|
20
|
+
- Contributors: adding a hot channel is one adapter file plus one catalog entry, with end-to-end tests for both run triggers.
|
|
21
|
+
- On Windows, `hq daemon install` now registers a scheduled task named for the current user (`ai.getindigo.hq-daemon-<SID>`, or a sanitised username when the SID cannot be read), so two people who share a PC no longer overwrite each other's daemon. Status, uninstall, `hq doctor` and the handoff and legacy lookups use the same per-user name. An older shared `ai.getindigo.hq-daemon` task that runs as the current user is moved to the new name and kept running; one that belongs to another Windows user, or whose owner cannot be read, is left untouched and `hq` says so.
|
|
22
|
+
- `hq daemon uninstall` on Windows now works for users who upgraded from the shared task and have not re-run install: it checks schtasks for the per-user task instead of trusting the shared XML file, treats a per-user task that is already gone as removed, and also removes this user's task registered under the username form. A task owner stored as a bare user name is no longer treated as `DOMAIN\user`, so another domain's user of the same name keeps their task.
|
|
23
|
+
|
|
24
|
+
## [5.345.178] — 2026-10-29
|
|
25
|
+
- `hq dm send --attach` now uploads the bytes it read with their exact length, so a file changed after the size check no longer stalls and fails with `Upload failed (HTTP 400)`. A refused upload now names the storage error (for example `RequestTimeout`).
|
|
26
|
+
- `hq daemon disable mesh` now keeps `mesh` off on machines where it is not on by default,
|
|
27
|
+
such as an agent kit with `sync-core` turned on. In 5.345.176 the disable was not saved
|
|
28
|
+
there, so `sync-core` turned `mesh` back on; the 5.345.176 note that disabling `mesh`
|
|
29
|
+
still turns it off held only for machine types that run `mesh` by default.
|
|
30
|
+
- `hq run` now skips `# @optional` secrets the caller cannot read or that are missing, instead of failing the whole run. Required secrets still fail.
|
|
31
|
+
- The company-gated HQ Fleet default now supports new personal Claude, Codex and Grok bots. Codex and Grok bots stay stopped until their own provider sign-in succeeds; creation and status show the sign-in command. Cancelled sign-in can be retried without creating another bot. Existing bots and the explicit legacy runner are preserved.
|
|
32
|
+
- Where the company flag `agents.local-bots-hq-fleet-default` is on, `hq bot create`
|
|
33
|
+
makes personal Claude bots (the setup bot included) on the HQ Fleet Runtime.
|
|
34
|
+
These bots run on the owner's Claude Code login and need no sign-in of their own.
|
|
35
|
+
`--legacy-runtime` keeps the model-CLI runner, and Codex and Grok bots keep it
|
|
36
|
+
unless `--hq-fleet-runtime` is passed. `--hq-fleet-runtime` now takes
|
|
37
|
+
`--runtime claude|codex|grok` and `--model` to choose the bot's model login.
|
|
38
|
+
- HQ Fleet Runtime bots send their intro and run their kickoff on first start.
|
|
39
|
+
`hq bot status` and `hq bot list` read their status file.
|
|
40
|
+
`hq bot adopt` and `hq bot restore` bring them back on the runtime instead of as
|
|
41
|
+
Claude CLI bots. The bot's saved settings now keep the model login it uses.
|
|
42
|
+
- Pins hq-fleet-local v0.4.12. On that release a bot gives its owner the owner's
|
|
43
|
+
companies that turned the flag on, and gives a teammate only the ones the
|
|
44
|
+
teammate also belongs to. A tool call is blocked when an HQ check cannot run.
|
|
45
|
+
- The fleet-default flag is read for the owner's own active memberships, and a
|
|
46
|
+
bot is given only the companies that turned it on. `HQ_BOT_FLEET_DEFAULT=1`
|
|
47
|
+
skips the flag and gives the bot every active membership whose company
|
|
48
|
+
folder is on the computer.
|
|
49
|
+
- HQ Fleet Runtime bots install a smaller runtime (the mcp and anthropic extras
|
|
50
|
+
only), so creating one takes less time and disk space.
|
|
51
|
+
- `hq sync pull`, `push` and `now` (including `pull --all` and the first sync after setup) now refresh the HQ session when the access token expires during a long run and retry the rejected request once. Before, the sync read the token once at the start, so a run that outlasted the one-hour token failed every remaining target with 401 Unauthorized. If the session is rejected, the sync stops with "Run `hq login`, then rerun the sync". A network or server failure during the refresh gets its own message. The refreshed token must belong to the account that started the run: if a mid-run `hq login` or the machine-identity fallback changes the account, the sync stops instead of continuing as a different account. Feedback 3d3fab0b-9475-472d-91ce-9e7aa5a7443c.
|
|
52
|
+
- A sync run's account is now fixed once the run starts. If the session would switch to another account mid-run, including a fallback to this computer's machine credentials after a rejected refresh, the sync stops with an explanation instead of continuing as that account. A run whose starting token does not identify an account does not start.
|
|
53
|
+
- The daemon now records the newest change number the server announced for each vault, so the sync engine can skip background requests when it already has that change once it reads this.
|
|
54
|
+
|
|
5
55
|
## [5.345.177] — 2026-10-28
|
|
6
56
|
- The new sync engine now installs as release v0.1.21, and company vaults move to full mode only on v0.1.21 or later. A remote delete the server refuses because the file changed now re-reads the server's changes within seconds instead of waiting for the hourly check. Deleting a file that is already gone on the server now counts as done instead of stopping the sync until someone repairs it, and a held remote delete no longer stops the rest of the sync. A file this machine just replaced is no longer downloaded again or turned into a conflict copy while the server catches up.
|
|
7
57
|
|
|
@@ -5150,6 +5150,72 @@ export declare const COMMAND_CATALOG: readonly [{
|
|
|
5150
5150
|
readonly hidden: false;
|
|
5151
5151
|
}];
|
|
5152
5152
|
readonly subcommands: readonly [];
|
|
5153
|
+
}, {
|
|
5154
|
+
readonly name: "runs";
|
|
5155
|
+
readonly description: "Show the hot-channel run log: sources landed and signals generated per adapter";
|
|
5156
|
+
readonly aliases: readonly [];
|
|
5157
|
+
readonly hidden: false;
|
|
5158
|
+
readonly helpOption: true;
|
|
5159
|
+
readonly helpCommand: false;
|
|
5160
|
+
readonly usage: "[options]";
|
|
5161
|
+
readonly helpText: readonly [];
|
|
5162
|
+
readonly arguments: readonly [];
|
|
5163
|
+
readonly options: readonly [{
|
|
5164
|
+
readonly flags: "--today";
|
|
5165
|
+
readonly description: "Show today's runs (UTC); the default";
|
|
5166
|
+
readonly hidden: false;
|
|
5167
|
+
}, {
|
|
5168
|
+
readonly flags: "--date <YYYY-MM-DD>";
|
|
5169
|
+
readonly description: "Show runs for this UTC day";
|
|
5170
|
+
readonly hidden: false;
|
|
5171
|
+
}, {
|
|
5172
|
+
readonly flags: "--company <slug>";
|
|
5173
|
+
readonly description: "Company slug (defaults to .hq/config.json activeCompany)";
|
|
5174
|
+
readonly hidden: false;
|
|
5175
|
+
}, {
|
|
5176
|
+
readonly flags: "--email <address>";
|
|
5177
|
+
readonly description: "Whose runs to show (defaults to the signed-in person)";
|
|
5178
|
+
readonly hidden: false;
|
|
5179
|
+
}, {
|
|
5180
|
+
readonly flags: "--format <fmt>";
|
|
5181
|
+
readonly description: "Output format: table | json (default: table for TTY, json piped)";
|
|
5182
|
+
readonly hidden: false;
|
|
5183
|
+
}, {
|
|
5184
|
+
readonly flags: "--hq-root <path>";
|
|
5185
|
+
readonly description: "Local HQ tree root (default: <runtime-path>)";
|
|
5186
|
+
readonly hidden: false;
|
|
5187
|
+
readonly defaultValue: "<runtime-path>";
|
|
5188
|
+
}];
|
|
5189
|
+
readonly subcommands: readonly [];
|
|
5190
|
+
}, {
|
|
5191
|
+
readonly name: "sync";
|
|
5192
|
+
readonly description: "Run every hot channel now: each adapter once per connection you can use";
|
|
5193
|
+
readonly aliases: readonly [];
|
|
5194
|
+
readonly hidden: false;
|
|
5195
|
+
readonly helpOption: true;
|
|
5196
|
+
readonly helpCommand: false;
|
|
5197
|
+
readonly usage: "[options]";
|
|
5198
|
+
readonly helpText: readonly [];
|
|
5199
|
+
readonly arguments: readonly [];
|
|
5200
|
+
readonly options: readonly [{
|
|
5201
|
+
readonly flags: "--adapter <id>";
|
|
5202
|
+
readonly description: "Run one adapter only (a catalog provider or adapter id)";
|
|
5203
|
+
readonly hidden: false;
|
|
5204
|
+
}, {
|
|
5205
|
+
readonly flags: "--company <slug>";
|
|
5206
|
+
readonly description: "Company slug (defaults to .hq/config.json activeCompany)";
|
|
5207
|
+
readonly hidden: false;
|
|
5208
|
+
}, {
|
|
5209
|
+
readonly flags: "--json";
|
|
5210
|
+
readonly description: "Print the run report as JSON";
|
|
5211
|
+
readonly hidden: false;
|
|
5212
|
+
}, {
|
|
5213
|
+
readonly flags: "--hq-root <path>";
|
|
5214
|
+
readonly description: "Local HQ tree root (default: <runtime-path>)";
|
|
5215
|
+
readonly hidden: false;
|
|
5216
|
+
readonly defaultValue: "<runtime-path>";
|
|
5217
|
+
}];
|
|
5218
|
+
readonly subcommands: readonly [];
|
|
5153
5219
|
}];
|
|
5154
5220
|
}, {
|
|
5155
5221
|
readonly name: "signals";
|
|
@@ -18691,7 +18757,7 @@ export declare const COMMAND_CATALOG: readonly [{
|
|
|
18691
18757
|
readonly subcommands: readonly [];
|
|
18692
18758
|
}, {
|
|
18693
18759
|
readonly name: "jobs";
|
|
18694
|
-
readonly description: "Show, schedule, or remove a bot's recurring jobs (
|
|
18760
|
+
readonly description: "Show, schedule, reschedule, or remove a bot's recurring jobs (they run on this computer while the bot runs)";
|
|
18695
18761
|
readonly aliases: readonly [];
|
|
18696
18762
|
readonly hidden: false;
|
|
18697
18763
|
readonly helpOption: true;
|
|
@@ -18728,6 +18794,10 @@ export declare const COMMAND_CATALOG: readonly [{
|
|
|
18728
18794
|
readonly flags: "--rm <jobId>";
|
|
18729
18795
|
readonly description: "Remove a scheduled job";
|
|
18730
18796
|
readonly hidden: false;
|
|
18797
|
+
}, {
|
|
18798
|
+
readonly flags: "--reschedule <jobId>";
|
|
18799
|
+
readonly description: "Change a job's schedule (with --every or --cron)";
|
|
18800
|
+
readonly hidden: false;
|
|
18731
18801
|
}, {
|
|
18732
18802
|
readonly flags: "--json";
|
|
18733
18803
|
readonly description: "Print machine-readable JSON";
|
|
@@ -18787,10 +18857,18 @@ export declare const COMMAND_CATALOG: readonly [{
|
|
|
18787
18857
|
readonly flags: "--runtime <runtime>";
|
|
18788
18858
|
readonly description: "Model CLI to run the bot with: claude|codex|grok";
|
|
18789
18859
|
readonly hidden: false;
|
|
18860
|
+
}, {
|
|
18861
|
+
readonly flags: "--provider <provider>";
|
|
18862
|
+
readonly description: "HQ Fleet provider: claude|codex|grok (interactive Fleet creation prompts when omitted)";
|
|
18863
|
+
readonly hidden: false;
|
|
18790
18864
|
}, {
|
|
18791
18865
|
readonly flags: "--hq-fleet-runtime";
|
|
18792
18866
|
readonly description: "Create this personal bot with the local HQ Fleet Runtime";
|
|
18793
18867
|
readonly hidden: false;
|
|
18868
|
+
}, {
|
|
18869
|
+
readonly flags: "--legacy-runtime";
|
|
18870
|
+
readonly description: "Run this bot with the model CLI even where the HQ Fleet Runtime is the default";
|
|
18871
|
+
readonly hidden: false;
|
|
18794
18872
|
}, {
|
|
18795
18873
|
readonly flags: "--model <model>";
|
|
18796
18874
|
readonly description: "Model override passed to the runtime CLI";
|
|
@@ -6243,6 +6243,86 @@ export const COMMAND_CATALOG = [
|
|
|
6243
6243
|
}
|
|
6244
6244
|
],
|
|
6245
6245
|
"subcommands": []
|
|
6246
|
+
},
|
|
6247
|
+
{
|
|
6248
|
+
"name": "runs",
|
|
6249
|
+
"description": "Show the hot-channel run log: sources landed and signals generated per adapter",
|
|
6250
|
+
"aliases": [],
|
|
6251
|
+
"hidden": false,
|
|
6252
|
+
"helpOption": true,
|
|
6253
|
+
"helpCommand": false,
|
|
6254
|
+
"usage": "[options]",
|
|
6255
|
+
"helpText": [],
|
|
6256
|
+
"arguments": [],
|
|
6257
|
+
"options": [
|
|
6258
|
+
{
|
|
6259
|
+
"flags": "--today",
|
|
6260
|
+
"description": "Show today's runs (UTC); the default",
|
|
6261
|
+
"hidden": false
|
|
6262
|
+
},
|
|
6263
|
+
{
|
|
6264
|
+
"flags": "--date <YYYY-MM-DD>",
|
|
6265
|
+
"description": "Show runs for this UTC day",
|
|
6266
|
+
"hidden": false
|
|
6267
|
+
},
|
|
6268
|
+
{
|
|
6269
|
+
"flags": "--company <slug>",
|
|
6270
|
+
"description": "Company slug (defaults to .hq/config.json activeCompany)",
|
|
6271
|
+
"hidden": false
|
|
6272
|
+
},
|
|
6273
|
+
{
|
|
6274
|
+
"flags": "--email <address>",
|
|
6275
|
+
"description": "Whose runs to show (defaults to the signed-in person)",
|
|
6276
|
+
"hidden": false
|
|
6277
|
+
},
|
|
6278
|
+
{
|
|
6279
|
+
"flags": "--format <fmt>",
|
|
6280
|
+
"description": "Output format: table | json (default: table for TTY, json piped)",
|
|
6281
|
+
"hidden": false
|
|
6282
|
+
},
|
|
6283
|
+
{
|
|
6284
|
+
"flags": "--hq-root <path>",
|
|
6285
|
+
"description": "Local HQ tree root (default: <runtime-path>)",
|
|
6286
|
+
"hidden": false,
|
|
6287
|
+
"defaultValue": "<runtime-path>"
|
|
6288
|
+
}
|
|
6289
|
+
],
|
|
6290
|
+
"subcommands": []
|
|
6291
|
+
},
|
|
6292
|
+
{
|
|
6293
|
+
"name": "sync",
|
|
6294
|
+
"description": "Run every hot channel now: each adapter once per connection you can use",
|
|
6295
|
+
"aliases": [],
|
|
6296
|
+
"hidden": false,
|
|
6297
|
+
"helpOption": true,
|
|
6298
|
+
"helpCommand": false,
|
|
6299
|
+
"usage": "[options]",
|
|
6300
|
+
"helpText": [],
|
|
6301
|
+
"arguments": [],
|
|
6302
|
+
"options": [
|
|
6303
|
+
{
|
|
6304
|
+
"flags": "--adapter <id>",
|
|
6305
|
+
"description": "Run one adapter only (a catalog provider or adapter id)",
|
|
6306
|
+
"hidden": false
|
|
6307
|
+
},
|
|
6308
|
+
{
|
|
6309
|
+
"flags": "--company <slug>",
|
|
6310
|
+
"description": "Company slug (defaults to .hq/config.json activeCompany)",
|
|
6311
|
+
"hidden": false
|
|
6312
|
+
},
|
|
6313
|
+
{
|
|
6314
|
+
"flags": "--json",
|
|
6315
|
+
"description": "Print the run report as JSON",
|
|
6316
|
+
"hidden": false
|
|
6317
|
+
},
|
|
6318
|
+
{
|
|
6319
|
+
"flags": "--hq-root <path>",
|
|
6320
|
+
"description": "Local HQ tree root (default: <runtime-path>)",
|
|
6321
|
+
"hidden": false,
|
|
6322
|
+
"defaultValue": "<runtime-path>"
|
|
6323
|
+
}
|
|
6324
|
+
],
|
|
6325
|
+
"subcommands": []
|
|
6246
6326
|
}
|
|
6247
6327
|
]
|
|
6248
6328
|
},
|
|
@@ -22774,7 +22854,7 @@ export const COMMAND_CATALOG = [
|
|
|
22774
22854
|
},
|
|
22775
22855
|
{
|
|
22776
22856
|
"name": "jobs",
|
|
22777
|
-
"description": "Show, schedule, or remove a bot's recurring jobs (
|
|
22857
|
+
"description": "Show, schedule, reschedule, or remove a bot's recurring jobs (they run on this computer while the bot runs)",
|
|
22778
22858
|
"aliases": [],
|
|
22779
22859
|
"hidden": false,
|
|
22780
22860
|
"helpOption": true,
|
|
@@ -22820,6 +22900,11 @@ export const COMMAND_CATALOG = [
|
|
|
22820
22900
|
"description": "Remove a scheduled job",
|
|
22821
22901
|
"hidden": false
|
|
22822
22902
|
},
|
|
22903
|
+
{
|
|
22904
|
+
"flags": "--reschedule <jobId>",
|
|
22905
|
+
"description": "Change a job's schedule (with --every or --cron)",
|
|
22906
|
+
"hidden": false
|
|
22907
|
+
},
|
|
22823
22908
|
{
|
|
22824
22909
|
"flags": "--json",
|
|
22825
22910
|
"description": "Print machine-readable JSON",
|
|
@@ -22893,11 +22978,21 @@ export const COMMAND_CATALOG = [
|
|
|
22893
22978
|
"description": "Model CLI to run the bot with: claude|codex|grok",
|
|
22894
22979
|
"hidden": false
|
|
22895
22980
|
},
|
|
22981
|
+
{
|
|
22982
|
+
"flags": "--provider <provider>",
|
|
22983
|
+
"description": "HQ Fleet provider: claude|codex|grok (interactive Fleet creation prompts when omitted)",
|
|
22984
|
+
"hidden": false
|
|
22985
|
+
},
|
|
22896
22986
|
{
|
|
22897
22987
|
"flags": "--hq-fleet-runtime",
|
|
22898
22988
|
"description": "Create this personal bot with the local HQ Fleet Runtime",
|
|
22899
22989
|
"hidden": false
|
|
22900
22990
|
},
|
|
22991
|
+
{
|
|
22992
|
+
"flags": "--legacy-runtime",
|
|
22993
|
+
"description": "Run this bot with the model CLI even where the HQ Fleet Runtime is the default",
|
|
22994
|
+
"hidden": false
|
|
22995
|
+
},
|
|
22901
22996
|
{
|
|
22902
22997
|
"flags": "--model <model>",
|
|
22903
22998
|
"description": "Model override passed to the runtime CLI",
|
|
@@ -5,17 +5,17 @@
|
|
|
5
5
|
* hq bot jobs <botName> --add "<what to do>" --every "<plain english>"
|
|
6
6
|
* hq bot jobs <botName> --add "<what to do>" --cron "0 9 * * 1-5"
|
|
7
7
|
* hq bot jobs <botName> --rm <jobId>
|
|
8
|
+
* hq bot jobs <botName> --reschedule <jobId> --every "<plain english>"
|
|
8
9
|
*
|
|
9
|
-
* The schedule lives
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* a
|
|
13
|
-
*
|
|
14
|
-
* The routes are self-only per agent, so every call uses the BOT's own machine
|
|
15
|
-
* identity — the same credential path its turns use — not the owner's session.
|
|
10
|
+
* The schedule lives with the bot: its jobs sit in the bot's own folder
|
|
11
|
+
* (lib/bot/local-jobs.ts) and the bot's inbox loop fires them while it runs
|
|
12
|
+
* (see lib/bot/job-run.ts). Nothing here writes a crontab, a launchd plist, or
|
|
13
|
+
* a systemd unit — by rule. Schedules are still written in the EventBridge form
|
|
14
|
+
* and held to the same limits, so a job reads the same wherever it runs.
|
|
16
15
|
*/
|
|
17
16
|
import type { Command } from "commander";
|
|
18
|
-
import {
|
|
17
|
+
import { type LocalJobsApi } from "../lib/bot/local-jobs.js";
|
|
18
|
+
import { type BotJobRecord, type CreateJobInput } from "../lib/bot/api.js";
|
|
19
19
|
import { type BotConfig, type BotKind } from "../lib/bot/config.js";
|
|
20
20
|
/** Mirrors hq-pro-agents `MIN_RECURRING_INTERVAL_SECONDS`. */
|
|
21
21
|
export declare const MIN_RECURRING_INTERVAL_SECONDS: number;
|
|
@@ -100,7 +100,7 @@ export interface BotJobsDeps {
|
|
|
100
100
|
};
|
|
101
101
|
botTokenSupplier(dir: string): () => Promise<string>;
|
|
102
102
|
/** Test seam: the jobs client for a bot directory. */
|
|
103
|
-
apiFor?(dir: string):
|
|
103
|
+
apiFor?(dir: string): LocalJobsApi;
|
|
104
104
|
parseSchedule?: typeof parseScheduleText;
|
|
105
105
|
timezone?: () => string;
|
|
106
106
|
out?: (line: string) => void;
|
|
@@ -113,6 +113,8 @@ export interface BotJobsOptions {
|
|
|
113
113
|
cron?: string;
|
|
114
114
|
tz?: string;
|
|
115
115
|
rm?: string;
|
|
116
|
+
/** Change an existing job's schedule, keeping its id, instruction and history. */
|
|
117
|
+
reschedule?: string;
|
|
116
118
|
json?: boolean;
|
|
117
119
|
quiet?: boolean;
|
|
118
120
|
}
|
|
@@ -5,14 +5,13 @@
|
|
|
5
5
|
* hq bot jobs <botName> --add "<what to do>" --every "<plain english>"
|
|
6
6
|
* hq bot jobs <botName> --add "<what to do>" --cron "0 9 * * 1-5"
|
|
7
7
|
* hq bot jobs <botName> --rm <jobId>
|
|
8
|
+
* hq bot jobs <botName> --reschedule <jobId> --every "<plain english>"
|
|
8
9
|
*
|
|
9
|
-
* The schedule lives
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* a
|
|
13
|
-
*
|
|
14
|
-
* The routes are self-only per agent, so every call uses the BOT's own machine
|
|
15
|
-
* identity — the same credential path its turns use — not the owner's session.
|
|
10
|
+
* The schedule lives with the bot: its jobs sit in the bot's own folder
|
|
11
|
+
* (lib/bot/local-jobs.ts) and the bot's inbox loop fires them while it runs
|
|
12
|
+
* (see lib/bot/job-run.ts). Nothing here writes a crontab, a launchd plist, or
|
|
13
|
+
* a systemd unit — by rule. Schedules are still written in the EventBridge form
|
|
14
|
+
* and held to the same limits, so a job reads the same wherever it runs.
|
|
16
15
|
*/
|
|
17
16
|
import chalk from "chalk";
|
|
18
17
|
import { localJobsClient } from "../lib/bot/local-jobs.js";
|
|
@@ -365,12 +364,56 @@ export async function runBotJobs(nameArg, opts, deps) {
|
|
|
365
364
|
client = deps.apiFor ? deps.apiFor(dir) : localJobsClient(dir);
|
|
366
365
|
return client;
|
|
367
366
|
};
|
|
368
|
-
if (opts.add
|
|
369
|
-
refuse("Add
|
|
367
|
+
if ([opts.add, opts.rm, opts.reschedule].filter((value) => value !== undefined).length > 1) {
|
|
368
|
+
refuse("Add, remove, or reschedule one job at a time, not several in the same command.");
|
|
370
369
|
}
|
|
371
370
|
if (opts.quiet && opts.add === undefined) {
|
|
372
371
|
refuse("Use --quiet with --add to set a scheduled job's delivery option.");
|
|
373
372
|
}
|
|
373
|
+
// Shared by --add and --reschedule: one schedule from --every or --cron, in
|
|
374
|
+
// the stored form, held to the same floor.
|
|
375
|
+
const scheduleFromOptions = () => {
|
|
376
|
+
if (!opts.every && !opts.cron) {
|
|
377
|
+
refuse(`Say how often it should run: --every "every weekday at 9am", or --cron "0 9 * * 1-5".`);
|
|
378
|
+
}
|
|
379
|
+
if (opts.every && opts.cron)
|
|
380
|
+
refuse("Use --every or --cron, not both.");
|
|
381
|
+
const timezone = opts.tz?.trim() || (deps.timezone ?? machineTimezone)();
|
|
382
|
+
// An unknown zone would throw RangeError on every inbox poll; refuse it now.
|
|
383
|
+
try {
|
|
384
|
+
new Intl.DateTimeFormat("en-US", { timeZone: timezone });
|
|
385
|
+
}
|
|
386
|
+
catch {
|
|
387
|
+
refuse(`"${timezone}" is not a known IANA time zone (for example America/New_York or Europe/London).`);
|
|
388
|
+
}
|
|
389
|
+
const parse = deps.parseSchedule ?? parseScheduleText;
|
|
390
|
+
return opts.every ? parse(opts.every, { timezone }) : { cron: opts.cron, timezone };
|
|
391
|
+
};
|
|
392
|
+
if (opts.reschedule !== undefined) {
|
|
393
|
+
const jobId = opts.reschedule.trim();
|
|
394
|
+
if (!jobId)
|
|
395
|
+
refuse("Say which job to reschedule: --reschedule <jobId>");
|
|
396
|
+
const schedule = scheduleFromOptions();
|
|
397
|
+
const cron = toEventBridgeCron(schedule.cron);
|
|
398
|
+
assertScheduleWithinFloor(cron);
|
|
399
|
+
const api = await jobsApi();
|
|
400
|
+
if (!api.rescheduleJob)
|
|
401
|
+
refuse(`${name}'s jobs cannot be rescheduled in place. Remove the job and add it again.`);
|
|
402
|
+
let updated;
|
|
403
|
+
try {
|
|
404
|
+
updated = await api.rescheduleJob(config.agentUid, jobId, { cron, timezone: schedule.timezone });
|
|
405
|
+
}
|
|
406
|
+
catch (err) {
|
|
407
|
+
refuse(jobsErrorMessage(err, ctx));
|
|
408
|
+
}
|
|
409
|
+
if (opts.json) {
|
|
410
|
+
out(JSON.stringify({ ok: true, job: updated }, null, 2));
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
const words = schedule.human || describeSchedule(updated);
|
|
414
|
+
out(chalk.green(`Rescheduled ${updated.jobId}: ${name} now runs it ${words}.`));
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
374
417
|
if (opts.rm !== undefined) {
|
|
375
418
|
const jobId = opts.rm.trim();
|
|
376
419
|
if (!jobId)
|
|
@@ -389,16 +432,7 @@ export async function runBotJobs(nameArg, opts, deps) {
|
|
|
389
432
|
if (opts.quiet && !(await quietOptionEnabled())) {
|
|
390
433
|
refuse(`--quiet requires the ${BOT_JOB_QUIET_OPTION_FLAG} flag, which is currently disabled.`);
|
|
391
434
|
}
|
|
392
|
-
|
|
393
|
-
refuse(`Say how often it should run: --every "every weekday at 9am", or --cron "0 9 * * 1-5".`);
|
|
394
|
-
}
|
|
395
|
-
if (opts.every && opts.cron)
|
|
396
|
-
refuse("Use --every or --cron, not both.");
|
|
397
|
-
const timezone = opts.tz?.trim() || (deps.timezone ?? machineTimezone)();
|
|
398
|
-
const parse = deps.parseSchedule ?? parseScheduleText;
|
|
399
|
-
const schedule = opts.every
|
|
400
|
-
? parse(opts.every, { timezone })
|
|
401
|
-
: { cron: opts.cron, timezone };
|
|
435
|
+
const schedule = scheduleFromOptions();
|
|
402
436
|
const body = buildCreateJobBody({ prompt: opts.add, cron: schedule.cron, timezone: schedule.timezone, quiet: opts.quiet });
|
|
403
437
|
const api = await jobsApi();
|
|
404
438
|
let created;
|
|
@@ -412,7 +446,7 @@ export async function runBotJobs(nameArg, opts, deps) {
|
|
|
412
446
|
out(JSON.stringify({ ok: true, job: created }, null, 2));
|
|
413
447
|
return;
|
|
414
448
|
}
|
|
415
|
-
const words =
|
|
449
|
+
const words = schedule.human || describeSchedule(created);
|
|
416
450
|
out(chalk.green(`Scheduled ${created.jobId}: ${name} will ${body.prompt.replace(/\s+/g, " ").slice(0, 120)} — ${words}.`));
|
|
417
451
|
out(chalk.gray(`It runs on this computer while ${name} is running. If a run is due while the computer is asleep or ` +
|
|
418
452
|
`${name} is stopped, it runs once, as a catch-up, the next time ${name} is running.`));
|
|
@@ -432,13 +466,14 @@ export async function runBotJobs(nameArg, opts, deps) {
|
|
|
432
466
|
export function registerBotJobsCommand(bot, deps) {
|
|
433
467
|
bot
|
|
434
468
|
.command("jobs <name>")
|
|
435
|
-
.description("Show, schedule, or remove a bot's recurring jobs (
|
|
469
|
+
.description("Show, schedule, reschedule, or remove a bot's recurring jobs (they run on this computer while the bot runs)")
|
|
436
470
|
.option("--add <what>", "Schedule new work, in plain language")
|
|
437
471
|
.option("--every <when>", 'How often, in plain language (e.g. "every weekday at 9am")')
|
|
438
472
|
.option("--cron <expr>", 'How often, as a cron expression (e.g. "0 9 * * 1-5")')
|
|
439
473
|
.option("--tz <zone>", "IANA timezone for the schedule (default: this computer's)")
|
|
440
474
|
.option("--quiet", "Skip owner DMs after successful runs (requires rollout flag)")
|
|
441
475
|
.option("--rm <jobId>", "Remove a scheduled job")
|
|
476
|
+
.option("--reschedule <jobId>", "Change a job's schedule (with --every or --cron)")
|
|
442
477
|
.option("--json", "Print machine-readable JSON")
|
|
443
478
|
.action(async (name, opts) => {
|
|
444
479
|
try {
|
package/dist/commands/bot.d.ts
CHANGED
|
@@ -12,6 +12,9 @@ export interface BotRow {
|
|
|
12
12
|
agentUid: string;
|
|
13
13
|
ownerUid: string;
|
|
14
14
|
runtime: BotRuntimeId;
|
|
15
|
+
needsSignIn?: boolean;
|
|
16
|
+
authCommand?: string;
|
|
17
|
+
serviceInstallPending?: boolean;
|
|
15
18
|
model?: string;
|
|
16
19
|
/** Thinking level the bot runs with (its setting, or the default). */
|
|
17
20
|
effort: string;
|
|
@@ -135,7 +138,9 @@ export declare function resolveCreateKind(opts: {
|
|
|
135
138
|
};
|
|
136
139
|
export interface BotCreateOptions {
|
|
137
140
|
runtime?: string;
|
|
141
|
+
provider?: string;
|
|
138
142
|
hqFleetRuntime?: boolean;
|
|
143
|
+
legacyRuntime?: boolean;
|
|
139
144
|
model?: string;
|
|
140
145
|
effort?: string;
|
|
141
146
|
autoApprove?: boolean;
|
|
@@ -374,4 +379,12 @@ export interface RemoteBotRow {
|
|
|
374
379
|
ownerUid: string | null;
|
|
375
380
|
}
|
|
376
381
|
export declare function registerBotCommand(program: Command): void;
|
|
382
|
+
/**
|
|
383
|
+
* The company a bot's hot-signal-sync job syncs: the bot's own company, else
|
|
384
|
+
* the first company it serves. Null = none, and no job is registered. There is
|
|
385
|
+
* no fallback to the HQ's active company: a personal bot syncs a company only
|
|
386
|
+
* when it was given one explicitly (`--company`), so the job never writes into
|
|
387
|
+
* a vault the bot does not belong to.
|
|
388
|
+
*/
|
|
389
|
+
export declare function hotSignalSyncCompany(config: Pick<BotConfig, "companySlug" | "kind" | "companies" | "workerId">): string | null;
|
|
377
390
|
//# sourceMappingURL=bot.d.ts.map
|