@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.
Files changed (100) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/dist/command-catalog.generated.d.ts +79 -1
  3. package/dist/command-catalog.generated.js +96 -1
  4. package/dist/commands/bot-jobs.d.ts +11 -9
  5. package/dist/commands/bot-jobs.js +56 -21
  6. package/dist/commands/bot.d.ts +13 -0
  7. package/dist/commands/bot.js +230 -21
  8. package/dist/commands/cloud.d.ts +49 -0
  9. package/dist/commands/cloud.js +155 -15
  10. package/dist/commands/daemon.d.ts +2 -0
  11. package/dist/commands/daemon.js +15 -4
  12. package/dist/commands/dm-attach.js +15 -3
  13. package/dist/commands/integrations-core.d.ts +2 -0
  14. package/dist/commands/integrations-core.js +1 -0
  15. package/dist/commands/library-add.d.ts +9 -0
  16. package/dist/commands/library-add.js +19 -2
  17. package/dist/commands/run.js +9 -1
  18. package/dist/commands/sources.d.ts +89 -0
  19. package/dist/commands/sources.js +363 -1
  20. package/dist/lib/bot/config.d.ts +2 -0
  21. package/dist/lib/bot/fleet-default-flag.d.ts +31 -0
  22. package/dist/lib/bot/fleet-default-flag.js +127 -0
  23. package/dist/lib/bot/fleet-local.d.ts +30 -1
  24. package/dist/lib/bot/fleet-local.js +86 -11
  25. package/dist/lib/bot/index.d.ts +1 -0
  26. package/dist/lib/bot/index.js +1 -0
  27. package/dist/lib/bot/jobs/hot-signal-sync.d.ts +109 -0
  28. package/dist/lib/bot/jobs/hot-signal-sync.js +177 -0
  29. package/dist/lib/bot/local-config.js +1 -1
  30. package/dist/lib/bot/local-jobs.d.ts +40 -4
  31. package/dist/lib/bot/local-jobs.js +72 -5
  32. package/dist/lib/bot/run.d.ts +15 -0
  33. package/dist/lib/bot/run.js +61 -0
  34. package/dist/lib/daemon/catalog.d.ts +2 -0
  35. package/dist/lib/daemon/catalog.js +7 -2
  36. package/dist/lib/daemon/config.d.ts +2 -1
  37. package/dist/lib/daemon/config.js +4 -3
  38. package/dist/lib/daemon/handoff.d.ts +4 -0
  39. package/dist/lib/daemon/handoff.js +6 -2
  40. package/dist/lib/daemon/install.d.ts +70 -2
  41. package/dist/lib/daemon/install.js +185 -27
  42. package/dist/lib/daemon/legacy.d.ts +9 -3
  43. package/dist/lib/daemon/legacy.js +11 -4
  44. package/dist/lib/daemon/migrate.js +1 -1
  45. package/dist/lib/daemon/run.d.ts +3 -2
  46. package/dist/lib/daemon/run.js +10 -6
  47. package/dist/lib/doctor/checks/anywhere.d.ts +6 -0
  48. package/dist/lib/doctor/checks/anywhere.js +35 -6
  49. package/dist/lib/hot-channels/adapters/__fixtures__/dummy.d.ts +33 -0
  50. package/dist/lib/hot-channels/adapters/__fixtures__/dummy.js +53 -0
  51. package/dist/lib/hot-channels/adapters/__fixtures__/meeting-providers.d.ts +38 -0
  52. package/dist/lib/hot-channels/adapters/__fixtures__/meeting-providers.js +64 -0
  53. package/dist/lib/hot-channels/adapters/attio.d.ts +67 -0
  54. package/dist/lib/hot-channels/adapters/attio.js +374 -0
  55. package/dist/lib/hot-channels/adapters/gmail.d.ts +111 -0
  56. package/dist/lib/hot-channels/adapters/gmail.js +413 -0
  57. package/dist/lib/hot-channels/adapters/index.d.ts +23 -0
  58. package/dist/lib/hot-channels/adapters/index.js +39 -0
  59. package/dist/lib/hot-channels/adapters/linear.d.ts +79 -0
  60. package/dist/lib/hot-channels/adapters/linear.js +321 -0
  61. package/dist/lib/hot-channels/adapters/meeting-providers.d.ts +86 -0
  62. package/dist/lib/hot-channels/adapters/meeting-providers.js +253 -0
  63. package/dist/lib/hot-channels/adapters/meetings.d.ts +81 -0
  64. package/dist/lib/hot-channels/adapters/meetings.js +523 -0
  65. package/dist/lib/hot-channels/adapters/slack.d.ts +70 -0
  66. package/dist/lib/hot-channels/adapters/slack.js +277 -0
  67. package/dist/lib/hot-channels/alert.d.ts +78 -0
  68. package/dist/lib/hot-channels/alert.js +179 -0
  69. package/dist/lib/hot-channels/audience.d.ts +15 -0
  70. package/dist/lib/hot-channels/audience.js +25 -0
  71. package/dist/lib/hot-channels/contract.d.ts +140 -0
  72. package/dist/lib/hot-channels/contract.js +20 -0
  73. package/dist/lib/hot-channels/cursors.d.ts +41 -0
  74. package/dist/lib/hot-channels/cursors.js +84 -0
  75. package/dist/lib/hot-channels/index.d.ts +10 -0
  76. package/dist/lib/hot-channels/index.js +10 -0
  77. package/dist/lib/hot-channels/landing.d.ts +83 -0
  78. package/dist/lib/hot-channels/landing.js +175 -0
  79. package/dist/lib/hot-channels/ledger.d.ts +101 -0
  80. package/dist/lib/hot-channels/ledger.js +186 -0
  81. package/dist/lib/hot-channels/loop.d.ts +74 -0
  82. package/dist/lib/hot-channels/loop.js +219 -0
  83. package/dist/lib/hot-channels/prompts/signals-pass.md +22 -0
  84. package/dist/lib/hot-channels/registry.d.ts +28 -0
  85. package/dist/lib/hot-channels/registry.js +121 -0
  86. package/dist/lib/hot-channels/run.d.ts +137 -0
  87. package/dist/lib/hot-channels/run.js +324 -0
  88. package/dist/lib/hot-channels/signals-pass.d.ts +150 -0
  89. package/dist/lib/hot-channels/signals-pass.js +581 -0
  90. package/dist/lib/hot-channels/sync-lock.d.ts +51 -0
  91. package/dist/lib/hot-channels/sync-lock.js +224 -0
  92. package/dist/lib/install/hook-target.d.ts +6 -2
  93. package/dist/lib/install/hook-target.js +9 -4
  94. package/dist/lib/lanes/loop.d.ts +10 -0
  95. package/dist/lib/lanes/loop.js +18 -1
  96. package/dist/lib/mesh/live/daemon/work-subscribe.d.ts +1 -0
  97. package/dist/lib/mesh/live/daemon/work-subscribe.js +26 -6
  98. package/dist/run/hq-plugin.d.ts +3 -0
  99. package/dist/run/hq-plugin.js +18 -0
  100. 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 (the schedule runs in the cloud, not on this computer)";
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 (the schedule runs in the cloud, not on this computer)",
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 in the cloud, never on this computer: hq-pro-agents holds
10
- * the job and fires it on an EventBridge schedule, and the bot's inbox loop
11
- * runs the fired run (see lib/bot/job-run.ts). Nothing here writes a crontab,
12
- * a launchd plist, or a systemd unit — by rule.
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 { BotApi, type BotJobRecord, type CreateJobInput } from "../lib/bot/api.js";
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): Pick<BotApi, "listJobs" | "createJob" | "cancelJob">;
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 in the cloud, never on this computer: hq-pro-agents holds
10
- * the job and fires it on an EventBridge schedule, and the bot's inbox loop
11
- * runs the fired run (see lib/bot/job-run.ts). Nothing here writes a crontab,
12
- * a launchd plist, or a systemd unit — by rule.
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 !== undefined && opts.rm !== undefined) {
369
- refuse("Add a job or remove one, not both in the same command.");
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
- if (!opts.every && !opts.cron) {
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 = ("human" in schedule && schedule.human) || describeSchedule(created);
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 (the schedule runs in the cloud, not on this computer)")
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 {
@@ -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