@indigoai-us/hq-cli 5.134.0 → 5.136.0

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 (38) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/command-catalog.generated.d.ts +71 -0
  3. package/dist/command-catalog.generated.js +93 -0
  4. package/dist/commands/bot-jobs.d.ts +127 -0
  5. package/dist/commands/bot-jobs.js +445 -0
  6. package/dist/commands/bot.js +3 -0
  7. package/dist/commands/lanes.d.ts +4 -2
  8. package/dist/commands/lanes.js +150 -2
  9. package/dist/lib/bot/api.d.ts +66 -0
  10. package/dist/lib/bot/api.js +38 -0
  11. package/dist/lib/bot/index.d.ts +3 -0
  12. package/dist/lib/bot/index.js +3 -0
  13. package/dist/lib/bot/inflight.d.ts +42 -0
  14. package/dist/lib/bot/job-completions.d.ts +91 -0
  15. package/dist/lib/bot/job-completions.js +132 -0
  16. package/dist/lib/bot/job-run.d.ts +109 -0
  17. package/dist/lib/bot/job-run.js +246 -0
  18. package/dist/lib/bot/paths.d.ts +9 -1
  19. package/dist/lib/bot/paths.js +14 -0
  20. package/dist/lib/bot/prompt.d.ts +12 -0
  21. package/dist/lib/bot/prompt.js +31 -0
  22. package/dist/lib/bot/room-policy.d.ts +18 -1
  23. package/dist/lib/bot/room-policy.js +20 -2
  24. package/dist/lib/bot/run.d.ts +23 -1
  25. package/dist/lib/bot/run.js +404 -7
  26. package/dist/lib/lanes/config.d.ts +7 -0
  27. package/dist/lib/lanes/config.js +28 -1
  28. package/dist/lib/lanes/index.d.ts +5 -1
  29. package/dist/lib/lanes/index.js +3 -1
  30. package/dist/lib/lanes/monitor.d.ts +48 -0
  31. package/dist/lib/lanes/monitor.js +409 -0
  32. package/dist/lib/lanes/spawn.d.ts +10 -1
  33. package/dist/lib/lanes/spawn.js +60 -5
  34. package/dist/lib/lanes/types.d.ts +6 -0
  35. package/dist/lib/lanes/types.js +1 -1
  36. package/dist/lib/lanes/watch.d.ts +22 -0
  37. package/dist/lib/lanes/watch.js +122 -0
  38. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -2,6 +2,34 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [5.136.0] — 2026-09-23
6
+
7
+ ### Added
8
+
9
+ - Your local bots can now do work on a repeating schedule. Ask a company bot for something regular — "check the overnight errors every weekday morning" — and it sets the schedule up itself; you can also see and remove its schedules with `hq bot jobs <name>`. The schedule is kept in the cloud, not on your computer. If the Mac is asleep when a run is due, the run happens as a catch-up when it wakes, as long as that is within about an hour, and the bot's report says it ran late; after a longer outage that run is skipped and the job carries on at its next scheduled time. Personal bots can't schedule work yet.
10
+
11
+ ## [5.135.0] — 2026-09-23
12
+
13
+ ### Added
14
+
15
+ - Claude lanes now set Claude Code's `CLAUDE_CODE_AUTO_COMPACT_WINDOW=200000`
16
+ control on fresh launches and session resumes.
17
+ `providers.claude.auto_compact_tokens` sets a positive-integer override, and
18
+ Codex and Grok launch environments are unchanged.
19
+
20
+ - Added `hq lanes watch` for bounded state and question polling, plus
21
+ `hq lanes monitor-check` for Claude Monitor coverage with distinct exit codes
22
+ for uncovered lanes and unreadable evidence. The reminder text is available
23
+ from `hq lanes monitor-check --reminder`.
24
+ - Corrected watch JSONL output and question status transitions, bounded Monitor
25
+ recommendations to the watch limit, and made stale or unreadable Monitor
26
+ evidence fail closed.
27
+
28
+ - Lanes can opt selected Codex model ids into fast mode with
29
+ `providers.codex.fast_mode_models`. Matching fresh and resumed runs pass
30
+ Codex's `service_tier="fast"` and `fast_mode` settings and record the
31
+ decision in the lane record and `spawn.json`.
32
+
5
33
  ## [5.134.0] — 2026-09-22
6
34
 
7
35
  ### Fixed
@@ -6744,6 +6744,46 @@ export declare const COMMAND_CATALOG: readonly [{
6744
6744
  readonly description: "JSON on stdout (always)";
6745
6745
  }];
6746
6746
  readonly subcommands: readonly [];
6747
+ }, {
6748
+ readonly name: "watch";
6749
+ readonly description: "Watch lane state and question changes until all lanes are terminal";
6750
+ readonly aliases: readonly [];
6751
+ readonly hidden: false;
6752
+ readonly usage: "[options] <lane-id...>";
6753
+ readonly arguments: readonly [{
6754
+ readonly name: "lane-id";
6755
+ readonly required: true;
6756
+ readonly variadic: true;
6757
+ }];
6758
+ readonly options: readonly [{
6759
+ readonly flags: "--interval-ms <ms>";
6760
+ readonly description: "Polling interval, bounded to 100ms–30s";
6761
+ }, {
6762
+ readonly flags: "--json";
6763
+ readonly description: "JSON on stdout (always)";
6764
+ }];
6765
+ readonly subcommands: readonly [];
6766
+ }, {
6767
+ readonly name: "monitor-check";
6768
+ readonly description: "Check that active Claude senior lanes have live Monitor watch tasks";
6769
+ readonly aliases: readonly [];
6770
+ readonly hidden: false;
6771
+ readonly usage: "[options]";
6772
+ readonly arguments: readonly [];
6773
+ readonly options: readonly [{
6774
+ readonly flags: "--session <id>";
6775
+ readonly description: "Senior session id";
6776
+ }, {
6777
+ readonly flags: "--engine <engine>";
6778
+ readonly description: "claude | codex | grok; defaults to HQ_CONDUCT_ENGINE or claude";
6779
+ }, {
6780
+ readonly flags: "--reminder";
6781
+ readonly description: "Print the senior Monitor reminder text";
6782
+ }, {
6783
+ readonly flags: "--json";
6784
+ readonly description: "JSON on stdout";
6785
+ }];
6786
+ readonly subcommands: readonly [];
6747
6787
  }, {
6748
6788
  readonly name: "show";
6749
6789
  readonly description: "Show one lane";
@@ -7278,6 +7318,37 @@ export declare const COMMAND_CATALOG: readonly [{
7278
7318
  readonly description: "Expected transfer size";
7279
7319
  }];
7280
7320
  readonly subcommands: readonly [];
7321
+ }, {
7322
+ readonly name: "jobs";
7323
+ readonly description: "Show, schedule, or remove a bot's recurring jobs (the schedule runs in the cloud, not on this computer)";
7324
+ readonly aliases: readonly [];
7325
+ readonly hidden: false;
7326
+ readonly usage: "[options] <name>";
7327
+ readonly arguments: readonly [{
7328
+ readonly name: "name";
7329
+ readonly required: true;
7330
+ readonly variadic: false;
7331
+ }];
7332
+ readonly options: readonly [{
7333
+ readonly flags: "--add <what>";
7334
+ readonly description: "Schedule new work, in plain language";
7335
+ }, {
7336
+ readonly flags: "--every <when>";
7337
+ readonly description: "How often, in plain language (e.g. \"every weekday at 9am\")";
7338
+ }, {
7339
+ readonly flags: "--cron <expr>";
7340
+ readonly description: "How often, as a cron expression (e.g. \"0 9 * * 1-5\")";
7341
+ }, {
7342
+ readonly flags: "--tz <zone>";
7343
+ readonly description: "IANA timezone for the schedule (default: this computer's)";
7344
+ }, {
7345
+ readonly flags: "--rm <jobId>";
7346
+ readonly description: "Remove a scheduled job";
7347
+ }, {
7348
+ readonly flags: "--json";
7349
+ readonly description: "Print machine-readable JSON";
7350
+ }];
7351
+ readonly subcommands: readonly [];
7281
7352
  }, {
7282
7353
  readonly name: "promote";
7283
7354
  readonly description: "Move this local bot to cloud compute, preserving its identity and private context";
@@ -8716,6 +8716,58 @@ export const COMMAND_CATALOG = [
8716
8716
  ],
8717
8717
  "subcommands": []
8718
8718
  },
8719
+ {
8720
+ "name": "watch",
8721
+ "description": "Watch lane state and question changes until all lanes are terminal",
8722
+ "aliases": [],
8723
+ "hidden": false,
8724
+ "usage": "[options] <lane-id...>",
8725
+ "arguments": [
8726
+ {
8727
+ "name": "lane-id",
8728
+ "required": true,
8729
+ "variadic": true
8730
+ }
8731
+ ],
8732
+ "options": [
8733
+ {
8734
+ "flags": "--interval-ms <ms>",
8735
+ "description": "Polling interval, bounded to 100ms–30s"
8736
+ },
8737
+ {
8738
+ "flags": "--json",
8739
+ "description": "JSON on stdout (always)"
8740
+ }
8741
+ ],
8742
+ "subcommands": []
8743
+ },
8744
+ {
8745
+ "name": "monitor-check",
8746
+ "description": "Check that active Claude senior lanes have live Monitor watch tasks",
8747
+ "aliases": [],
8748
+ "hidden": false,
8749
+ "usage": "[options]",
8750
+ "arguments": [],
8751
+ "options": [
8752
+ {
8753
+ "flags": "--session <id>",
8754
+ "description": "Senior session id"
8755
+ },
8756
+ {
8757
+ "flags": "--engine <engine>",
8758
+ "description": "claude | codex | grok; defaults to HQ_CONDUCT_ENGINE or claude"
8759
+ },
8760
+ {
8761
+ "flags": "--reminder",
8762
+ "description": "Print the senior Monitor reminder text"
8763
+ },
8764
+ {
8765
+ "flags": "--json",
8766
+ "description": "JSON on stdout"
8767
+ }
8768
+ ],
8769
+ "subcommands": []
8770
+ },
8719
8771
  {
8720
8772
  "name": "show",
8721
8773
  "description": "Show one lane",
@@ -9411,6 +9463,47 @@ export const COMMAND_CATALOG = [
9411
9463
  ],
9412
9464
  "subcommands": []
9413
9465
  },
9466
+ {
9467
+ "name": "jobs",
9468
+ "description": "Show, schedule, or remove a bot's recurring jobs (the schedule runs in the cloud, not on this computer)",
9469
+ "aliases": [],
9470
+ "hidden": false,
9471
+ "usage": "[options] <name>",
9472
+ "arguments": [
9473
+ {
9474
+ "name": "name",
9475
+ "required": true,
9476
+ "variadic": false
9477
+ }
9478
+ ],
9479
+ "options": [
9480
+ {
9481
+ "flags": "--add <what>",
9482
+ "description": "Schedule new work, in plain language"
9483
+ },
9484
+ {
9485
+ "flags": "--every <when>",
9486
+ "description": "How often, in plain language (e.g. \"every weekday at 9am\")"
9487
+ },
9488
+ {
9489
+ "flags": "--cron <expr>",
9490
+ "description": "How often, as a cron expression (e.g. \"0 9 * * 1-5\")"
9491
+ },
9492
+ {
9493
+ "flags": "--tz <zone>",
9494
+ "description": "IANA timezone for the schedule (default: this computer's)"
9495
+ },
9496
+ {
9497
+ "flags": "--rm <jobId>",
9498
+ "description": "Remove a scheduled job"
9499
+ },
9500
+ {
9501
+ "flags": "--json",
9502
+ "description": "Print machine-readable JSON"
9503
+ }
9504
+ ],
9505
+ "subcommands": []
9506
+ },
9414
9507
  {
9415
9508
  "name": "promote",
9416
9509
  "description": "Move this local bot to cloud compute, preserving its identity and private context",
@@ -0,0 +1,127 @@
1
+ /**
2
+ * `hq bot jobs` — a local bot's recurring scheduled work.
3
+ *
4
+ * hq bot jobs <botName> list
5
+ * hq bot jobs <botName> --add "<what to do>" --every "<plain english>"
6
+ * hq bot jobs <botName> --add "<what to do>" --cron "0 9 * * 1-5"
7
+ * hq bot jobs <botName> --rm <jobId>
8
+ *
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.
16
+ */
17
+ import { execFileSync } from "node:child_process";
18
+ import type { Command } from "commander";
19
+ import { BotApi, type BotJobRecord, type CreateJobInput } from "../lib/bot/api.js";
20
+ import { type BotConfig, type BotKind } from "../lib/bot/config.js";
21
+ /** Mirrors hq-pro-agents `MIN_RECURRING_INTERVAL_SECONDS`. */
22
+ export declare const MIN_RECURRING_INTERVAL_SECONDS: number;
23
+ /** Mirrors hq-pro-agents `DEFAULT_MAX_ACTIVE_JOBS_PER_AGENT`. */
24
+ export declare const MAX_ACTIVE_JOBS_PER_AGENT = 25;
25
+ /** Mirrors hq-pro-agents `MAX_PROMPT_BYTES`. */
26
+ export declare const MAX_PROMPT_BYTES: number;
27
+ export declare class BotJobsError extends Error {
28
+ readonly expected: true;
29
+ }
30
+ /** The machine's own IANA zone, so "9am" means 9am where the owner lives. */
31
+ export declare function machineTimezone(): string;
32
+ /**
33
+ * Standard 5-field cron → the EventBridge form the cloud stores.
34
+ *
35
+ * EventBridge cron has SIX fields (a trailing year), numbers its days of week
36
+ * 1–7 with SUNDAY = 1 (standard cron uses 0–6 with SUNDAY = 0), and refuses
37
+ * `*` in BOTH the day-of-month and day-of-week fields — exactly one must be
38
+ * `?`. An expression that is already `cron(...)` or `rate(...)` is passed
39
+ * through untouched.
40
+ */
41
+ export declare function toEventBridgeCron(expr: string): string;
42
+ /**
43
+ * The smallest gap a recurring expression can produce, in seconds, or null
44
+ * when it is not a recognised rate()/cron() form. Mirrors hq-pro-agents
45
+ * `recurringIntervalSeconds` so the CLI can refuse a sub-floor schedule with
46
+ * the server's own reason instead of a round-trip and a raw 400.
47
+ */
48
+ export declare function recurringIntervalSeconds(expr: string): number | null;
49
+ /** Refuse a schedule the cloud would refuse, with the cloud's own reason. */
50
+ export declare function assertScheduleWithinFloor(expr: string): void;
51
+ export interface ParsedSchedule {
52
+ /** Standard 5-field cron, as the HQ helper emits it. */
53
+ cron: string;
54
+ timezone: string;
55
+ /** Plain words for the schedule, when the helper supplied them. */
56
+ human?: string;
57
+ }
58
+ export declare function scheduleHelperPath(hqRoot: string): string;
59
+ /**
60
+ * Plain English → cron, using HQ's OWN helper (`core/scripts/jobs-schedule-parse.sh`)
61
+ * so `hq bot jobs --every` and the `/schedule` command agree on what "every
62
+ * weekday morning" means. When the helper is not in this HQ root, the caller is
63
+ * told to pass `--cron` instead rather than getting a second, divergent parser.
64
+ */
65
+ export declare function parseScheduleText(text: string, opts: {
66
+ hqRoot: string;
67
+ timezone: string;
68
+ exec?: typeof execFileSync;
69
+ exists?: (p: string) => boolean;
70
+ }): ParsedSchedule;
71
+ /** The create body the cloud expects, with the client-side limits enforced first. */
72
+ export declare function buildCreateJobBody(input: {
73
+ prompt: string;
74
+ cron: string;
75
+ timezone: string;
76
+ context?: Record<string, unknown>;
77
+ }): CreateJobInput;
78
+ /** A schedule in plain words, falling back to the raw expression. */
79
+ export declare function describeSchedule(job: BotJobRecord): string;
80
+ /** A small humaniser for the shapes `--every` actually produces. */
81
+ export declare function cronInWords(expr: string): string | null;
82
+ /** "never run yet" / "succeeded 2026-09-15 09:00 UTC". */
83
+ export declare function describeLastRun(job: BotJobRecord): string;
84
+ export declare function formatJobsList(botName: string, jobs: BotJobRecord[]): string;
85
+ /**
86
+ * Turn a jobs-route failure into one plain line.
87
+ *
88
+ * Personal bots are refused by the cloud today: their JWT carries the owner's
89
+ * `per_…` company claim and the jobs routes require a `cmp_…`, so the fail-closed
90
+ * guard answers 403 `CROSS_AGENT_JOB` (hq-pro-agents jobs/errors.ts
91
+ * `CrossAgentJobError`). That server fix is a separate change; until it lands the
92
+ * refusal must read as "not available yet for this kind of bot", not as a raw 403.
93
+ * Once the server accepts personal bots the refusal simply stops happening — no
94
+ * client change needed.
95
+ *
96
+ * ONLY that exact code is rewritten. Every other 403, and every 404, keeps its
97
+ * real message: masking them would hide a genuinely missing job or a different
98
+ * permission problem behind copy about the wrong thing.
99
+ */
100
+ export declare function jobsErrorMessage(err: unknown, ctx: {
101
+ botName: string;
102
+ kind: BotKind;
103
+ }): string;
104
+ export interface BotJobsDeps {
105
+ requireBot(name: string): {
106
+ name: string;
107
+ dir: string;
108
+ config: BotConfig;
109
+ };
110
+ botTokenSupplier(dir: string): () => Promise<string>;
111
+ /** Test seam: the jobs client for a bot directory. */
112
+ apiFor?(dir: string): Pick<BotApi, "listJobs" | "createJob" | "cancelJob">;
113
+ parseSchedule?: typeof parseScheduleText;
114
+ timezone?: () => string;
115
+ out?: (line: string) => void;
116
+ }
117
+ export interface BotJobsOptions {
118
+ add?: string;
119
+ every?: string;
120
+ cron?: string;
121
+ tz?: string;
122
+ rm?: string;
123
+ json?: boolean;
124
+ }
125
+ export declare function runBotJobs(nameArg: string, opts: BotJobsOptions, deps: BotJobsDeps): Promise<void>;
126
+ export declare function registerBotJobsCommand(bot: Command, deps: BotJobsDeps): void;
127
+ //# sourceMappingURL=bot-jobs.d.ts.map