@indigoai-us/hq-cli 5.345.80 → 5.345.81

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 CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [5.345.81] — 2026-10-11
6
+ - HQ Storage (`hq storage status|prune|offload|fetch`) is available behind the Indigo-only `hq-storage` flag and fails closed when the flag is off. Requires @indigoai-us/hq-cloud 6.18.61, whose sync skips `.hq-offload/` and supports cloud-only `.hqcloud` placeholders.
7
+ - `hq storage status` reports local autosave history and cloud file-version usage per company, grouped by age. `hq storage prune` deletes old noncurrent cloud file versions in companies where you are an owner or admin, and never touches the current version. A version's age counts from when it was replaced, so a recent undo copy of an old file is kept. `status --json` marks each company with `can_delete`, and still shows local usage when you are signed out.
8
+ - `hq storage offload` moves old versions of big files out of local autosave history into your personal HQ cloud storage, checks each upload, then replaces them in history with a small link. `hq storage fetch` downloads a moved file and checks it before putting it back, and `--git-blob <sha> --out <file>` gets an old version from history. `hq storage status` now shows how much could be moved. Moving idle current files (`--current`) reports unavailable for now, because HQ sync would treat the replaced file as deleted. Offload also reports "update HQ sync" until the installed HQ sync skips the offload folder. Without a terminal, prune and offload need `--yes` and exit with an error otherwise.
9
+ - `hq storage fetch` also restores files whose placeholder HQ sync updated after a teammate changed them. It downloads the newer version from the company's cloud storage, only if you are an active member of that company, and checks its size and version tag before putting it back. If a teammate deleted the file, fetch stops and says so. `--force-orphan --out <file>` gets your own earlier copy from your personal HQ cloud storage into a file outside your HQ folder, so it is never synced back to the team. `hq storage status --json` now reports `offload.current_available` and `offload.current_reason`, which stay false while moving current files is turned off.
10
+ - `hq storage status`, `prune` and `offload` first clear expired local backups when HQ supports it. Results now say when space held by the 24-hour prune backup is freed (`reclaim_after`, `pending_reclaim_bytes`); a preview includes the expected time. History offload frees space right away, since every moved file is already checked in the cloud. When old branches or tags keep old history, prune reports them as a list instead of an error message. A cloud prune refused by permissions now says only owners and admins can delete old versions for that company.
11
+
5
12
  ## [5.345.80] — 2026-10-11
6
13
  - The version gate no longer treats a pnpm global install that Node resolved
7
14
  into `store/v11/links` as a local dependency, so it can self-update instead
@@ -2902,6 +2902,148 @@ export declare const COMMAND_CATALOG: readonly [{
2902
2902
  readonly defaultValue: "<runtime-path>";
2903
2903
  }];
2904
2904
  readonly subcommands: readonly [];
2905
+ }, {
2906
+ readonly name: "storage";
2907
+ readonly description: "See how much space HQ backups use and delete old ones";
2908
+ readonly aliases: readonly [];
2909
+ readonly hidden: false;
2910
+ readonly helpOption: true;
2911
+ readonly helpCommand: true;
2912
+ readonly usage: "[options] [command]";
2913
+ readonly helpText: readonly [];
2914
+ readonly arguments: readonly [];
2915
+ readonly options: readonly [];
2916
+ readonly subcommands: readonly [{
2917
+ readonly name: "status";
2918
+ readonly description: "Show local autosave history and cloud file history sizes";
2919
+ readonly aliases: readonly [];
2920
+ readonly hidden: false;
2921
+ readonly helpOption: true;
2922
+ readonly helpCommand: false;
2923
+ readonly usage: "[options]";
2924
+ readonly helpText: readonly [];
2925
+ readonly arguments: readonly [];
2926
+ readonly options: readonly [{
2927
+ readonly flags: "--json";
2928
+ readonly description: "Print JSON";
2929
+ readonly hidden: false;
2930
+ }, {
2931
+ readonly flags: "--company <slug>";
2932
+ readonly description: "Only this company (must be one of yours)";
2933
+ readonly hidden: false;
2934
+ }];
2935
+ readonly subcommands: readonly [];
2936
+ }, {
2937
+ readonly name: "prune";
2938
+ readonly description: "Delete local autosave history and old cloud file versions before a date";
2939
+ readonly aliases: readonly [];
2940
+ readonly hidden: false;
2941
+ readonly helpOption: true;
2942
+ readonly helpCommand: false;
2943
+ readonly usage: "[options]";
2944
+ readonly helpText: readonly [];
2945
+ readonly arguments: readonly [];
2946
+ readonly options: readonly [{
2947
+ readonly flags: "--local-before <date>";
2948
+ readonly description: "Prune local autosave history before YYYY-MM-DD";
2949
+ readonly hidden: false;
2950
+ }, {
2951
+ readonly flags: "--cloud-before <date>";
2952
+ readonly description: "Delete old (noncurrent) cloud file versions before YYYY-MM-DD";
2953
+ readonly hidden: false;
2954
+ }, {
2955
+ readonly flags: "--company <slug>";
2956
+ readonly description: "Only this company (must be one of yours)";
2957
+ readonly hidden: false;
2958
+ }, {
2959
+ readonly flags: "--dry-run";
2960
+ readonly description: "Show what would be deleted without deleting";
2961
+ readonly hidden: false;
2962
+ }, {
2963
+ readonly flags: "--yes";
2964
+ readonly description: "Skip the confirmation prompt";
2965
+ readonly hidden: false;
2966
+ }, {
2967
+ readonly flags: "--json";
2968
+ readonly description: "Print JSON";
2969
+ readonly hidden: false;
2970
+ }];
2971
+ readonly subcommands: readonly [];
2972
+ }, {
2973
+ readonly name: "offload";
2974
+ readonly description: "Move big files to your personal HQ cloud storage and leave links behind (old versions in history; idle current files)";
2975
+ readonly aliases: readonly [];
2976
+ readonly hidden: false;
2977
+ readonly helpOption: true;
2978
+ readonly helpCommand: false;
2979
+ readonly usage: "[options]";
2980
+ readonly helpText: readonly [];
2981
+ readonly arguments: readonly [];
2982
+ readonly options: readonly [{
2983
+ readonly flags: "--min-size <size>";
2984
+ readonly description: "Only files at least this big, e.g. 50MB (env HQ_OFFLOAD_MIN_BYTES)";
2985
+ readonly hidden: false;
2986
+ }, {
2987
+ readonly flags: "--idle-days <days>";
2988
+ readonly description: "Current files must be untouched this many days";
2989
+ readonly hidden: false;
2990
+ readonly defaultValue: "14";
2991
+ }, {
2992
+ readonly flags: "--history";
2993
+ readonly description: "Only old versions in local autosave history";
2994
+ readonly hidden: false;
2995
+ }, {
2996
+ readonly flags: "--current";
2997
+ readonly description: "Only idle files in the working tree";
2998
+ readonly hidden: false;
2999
+ }, {
3000
+ readonly flags: "--dry-run";
3001
+ readonly description: "Show what would move without uploading or changing anything";
3002
+ readonly hidden: false;
3003
+ }, {
3004
+ readonly flags: "--yes";
3005
+ readonly description: "Skip the confirmation prompt";
3006
+ readonly hidden: false;
3007
+ }, {
3008
+ readonly flags: "--json";
3009
+ readonly description: "Print JSON";
3010
+ readonly hidden: false;
3011
+ }];
3012
+ readonly subcommands: readonly [];
3013
+ }, {
3014
+ readonly name: "fetch";
3015
+ readonly description: "Download a file moved to HQ cloud storage, check it, and put it back in place";
3016
+ readonly aliases: readonly [];
3017
+ readonly hidden: false;
3018
+ readonly helpOption: true;
3019
+ readonly helpCommand: false;
3020
+ readonly usage: "[options] [path]";
3021
+ readonly helpText: readonly [];
3022
+ readonly arguments: readonly [{
3023
+ readonly name: "path";
3024
+ readonly required: false;
3025
+ readonly variadic: false;
3026
+ readonly description: "";
3027
+ }];
3028
+ readonly options: readonly [{
3029
+ readonly flags: "--git-blob <sha>";
3030
+ readonly description: "Download an old version from history by its git blob id";
3031
+ readonly hidden: false;
3032
+ }, {
3033
+ readonly flags: "--out <file>";
3034
+ readonly description: "Where to write the --git-blob or --force-orphan download";
3035
+ readonly hidden: false;
3036
+ }, {
3037
+ readonly flags: "--force-orphan";
3038
+ readonly description: "For a file a teammate deleted: write your own personal-vault copy to --out (outside HQ). It is never synced back to your team.";
3039
+ readonly hidden: false;
3040
+ }, {
3041
+ readonly flags: "--json";
3042
+ readonly description: "Print JSON";
3043
+ readonly hidden: false;
3044
+ }];
3045
+ readonly subcommands: readonly [];
3046
+ }];
2905
3047
  }, {
2906
3048
  readonly name: "skill";
2907
3049
  readonly description: "Create, stage, promote, and discuss company skills";
@@ -3501,6 +3501,179 @@ export const COMMAND_CATALOG = [
3501
3501
  ],
3502
3502
  "subcommands": []
3503
3503
  },
3504
+ {
3505
+ "name": "storage",
3506
+ "description": "See how much space HQ backups use and delete old ones",
3507
+ "aliases": [],
3508
+ "hidden": false,
3509
+ "helpOption": true,
3510
+ "helpCommand": true,
3511
+ "usage": "[options] [command]",
3512
+ "helpText": [],
3513
+ "arguments": [],
3514
+ "options": [],
3515
+ "subcommands": [
3516
+ {
3517
+ "name": "status",
3518
+ "description": "Show local autosave history and cloud file history sizes",
3519
+ "aliases": [],
3520
+ "hidden": false,
3521
+ "helpOption": true,
3522
+ "helpCommand": false,
3523
+ "usage": "[options]",
3524
+ "helpText": [],
3525
+ "arguments": [],
3526
+ "options": [
3527
+ {
3528
+ "flags": "--json",
3529
+ "description": "Print JSON",
3530
+ "hidden": false
3531
+ },
3532
+ {
3533
+ "flags": "--company <slug>",
3534
+ "description": "Only this company (must be one of yours)",
3535
+ "hidden": false
3536
+ }
3537
+ ],
3538
+ "subcommands": []
3539
+ },
3540
+ {
3541
+ "name": "prune",
3542
+ "description": "Delete local autosave history and old cloud file versions before a date",
3543
+ "aliases": [],
3544
+ "hidden": false,
3545
+ "helpOption": true,
3546
+ "helpCommand": false,
3547
+ "usage": "[options]",
3548
+ "helpText": [],
3549
+ "arguments": [],
3550
+ "options": [
3551
+ {
3552
+ "flags": "--local-before <date>",
3553
+ "description": "Prune local autosave history before YYYY-MM-DD",
3554
+ "hidden": false
3555
+ },
3556
+ {
3557
+ "flags": "--cloud-before <date>",
3558
+ "description": "Delete old (noncurrent) cloud file versions before YYYY-MM-DD",
3559
+ "hidden": false
3560
+ },
3561
+ {
3562
+ "flags": "--company <slug>",
3563
+ "description": "Only this company (must be one of yours)",
3564
+ "hidden": false
3565
+ },
3566
+ {
3567
+ "flags": "--dry-run",
3568
+ "description": "Show what would be deleted without deleting",
3569
+ "hidden": false
3570
+ },
3571
+ {
3572
+ "flags": "--yes",
3573
+ "description": "Skip the confirmation prompt",
3574
+ "hidden": false
3575
+ },
3576
+ {
3577
+ "flags": "--json",
3578
+ "description": "Print JSON",
3579
+ "hidden": false
3580
+ }
3581
+ ],
3582
+ "subcommands": []
3583
+ },
3584
+ {
3585
+ "name": "offload",
3586
+ "description": "Move big files to your personal HQ cloud storage and leave links behind (old versions in history; idle current files)",
3587
+ "aliases": [],
3588
+ "hidden": false,
3589
+ "helpOption": true,
3590
+ "helpCommand": false,
3591
+ "usage": "[options]",
3592
+ "helpText": [],
3593
+ "arguments": [],
3594
+ "options": [
3595
+ {
3596
+ "flags": "--min-size <size>",
3597
+ "description": "Only files at least this big, e.g. 50MB (env HQ_OFFLOAD_MIN_BYTES)",
3598
+ "hidden": false
3599
+ },
3600
+ {
3601
+ "flags": "--idle-days <days>",
3602
+ "description": "Current files must be untouched this many days",
3603
+ "hidden": false,
3604
+ "defaultValue": "14"
3605
+ },
3606
+ {
3607
+ "flags": "--history",
3608
+ "description": "Only old versions in local autosave history",
3609
+ "hidden": false
3610
+ },
3611
+ {
3612
+ "flags": "--current",
3613
+ "description": "Only idle files in the working tree",
3614
+ "hidden": false
3615
+ },
3616
+ {
3617
+ "flags": "--dry-run",
3618
+ "description": "Show what would move without uploading or changing anything",
3619
+ "hidden": false
3620
+ },
3621
+ {
3622
+ "flags": "--yes",
3623
+ "description": "Skip the confirmation prompt",
3624
+ "hidden": false
3625
+ },
3626
+ {
3627
+ "flags": "--json",
3628
+ "description": "Print JSON",
3629
+ "hidden": false
3630
+ }
3631
+ ],
3632
+ "subcommands": []
3633
+ },
3634
+ {
3635
+ "name": "fetch",
3636
+ "description": "Download a file moved to HQ cloud storage, check it, and put it back in place",
3637
+ "aliases": [],
3638
+ "hidden": false,
3639
+ "helpOption": true,
3640
+ "helpCommand": false,
3641
+ "usage": "[options] [path]",
3642
+ "helpText": [],
3643
+ "arguments": [
3644
+ {
3645
+ "name": "path",
3646
+ "required": false,
3647
+ "variadic": false,
3648
+ "description": ""
3649
+ }
3650
+ ],
3651
+ "options": [
3652
+ {
3653
+ "flags": "--git-blob <sha>",
3654
+ "description": "Download an old version from history by its git blob id",
3655
+ "hidden": false
3656
+ },
3657
+ {
3658
+ "flags": "--out <file>",
3659
+ "description": "Where to write the --git-blob or --force-orphan download",
3660
+ "hidden": false
3661
+ },
3662
+ {
3663
+ "flags": "--force-orphan",
3664
+ "description": "For a file a teammate deleted: write your own personal-vault copy to --out (outside HQ). It is never synced back to your team.",
3665
+ "hidden": false
3666
+ },
3667
+ {
3668
+ "flags": "--json",
3669
+ "description": "Print JSON",
3670
+ "hidden": false
3671
+ }
3672
+ ],
3673
+ "subcommands": []
3674
+ }
3675
+ ]
3676
+ },
3504
3677
  {
3505
3678
  "name": "skill",
3506
3679
  "description": "Create, stage, promote, and discuss company skills",
@@ -8,6 +8,8 @@ export async function runCommandHelp(argv) {
8
8
  .version(CLI_VERSION)
9
9
  .option("--verbose", "Show verbose diagnostics, including SDK runtime warnings");
10
10
  registerCommandCatalog(program);
11
+ const { hideStorageInCatalog } = await import("./lib/storage-feature-flag.js");
12
+ hideStorageInCatalog(program);
11
13
  await program.parseAsync([...argv]);
12
14
  }
13
15
  //# sourceMappingURL=command-help.js.map
@@ -280,6 +280,12 @@ export declare const REGISTRATION_PLAN: readonly [{
280
280
  readonly parent: "program";
281
281
  readonly module: "./commands/access.js";
282
282
  readonly exportName: "registerAccessCommand";
283
+ }, {
284
+ readonly type: "registrar";
285
+ readonly root: "storage";
286
+ readonly parent: "program";
287
+ readonly module: "./commands/storage.js";
288
+ readonly exportName: "registerStorageCommand";
283
289
  }, {
284
290
  readonly type: "registrar";
285
291
  readonly root: "skill";
@@ -49,6 +49,7 @@ export const REGISTRATION_PLAN = [
49
49
  { type: "registrar", root: "files", parent: "program", module: "./commands/files.js", exportName: "registerFilesCommand", result: "files" },
50
50
  { type: "registrar", root: "files", parent: "files", module: "./commands/files-browse.js", exportName: "registerFilesBrowseCommands" },
51
51
  { type: "registrar", root: "access", parent: "program", module: "./commands/access.js", exportName: "registerAccessCommand" },
52
+ { type: "registrar", root: "storage", parent: "program", module: "./commands/storage.js", exportName: "registerStorageCommand" },
52
53
  { type: "registrar", root: "skill", parent: "program", module: "./commands/skill.js", exportName: "registerSkillCommand" },
53
54
  { type: "registrar", root: "members", parent: "program", module: "./commands/members.js", exportName: "registerMembersCommand" },
54
55
  { type: "registrar", root: "people", parent: "program", module: "./commands/people.js", exportName: "registerPeopleCommand" },
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Shared calls into core `hq-storage.sh` for `hq storage` status, prune and
3
+ * offload.
4
+ *
5
+ * - `runCoreScript` turns one script run into a JSON report. Exit 4 from
6
+ * `prune` ("would free nothing") becomes a structured refusal with the
7
+ * branches, tags or stash that hold the old history, never raw stderr.
8
+ * - `dropExpiredBackups` runs core `drop-backups --expired` right before a
9
+ * real prune or offload (never for status, dry runs or fetch). With no
10
+ * expired backup it takes no lock and runs no gc; it never expires reflogs.
11
+ * A failure is reported but never blocks the command.
12
+ * - `checkPreconditions` runs core `check` so offload can refuse before it
13
+ * uploads anything. Exit 5 from a core rewrite (a failed precondition)
14
+ * becomes a structured refusal with plain text, never raw stderr.
15
+ * - Backups: by default core keeps a backup ref for 24 h after prune or
16
+ * strip-large, so space comes back after `reclaim_after`, not at once.
17
+ * `withReclaim` adds `backup_ref`, `reclaim_after` and
18
+ * `pending_reclaim_bytes` to a result so a UI can say when space is freed.
19
+ */
20
+ import type { LocalReport, ScriptRunner } from "./storage.js";
21
+ /** Core's default backup grace period (`HQ_STORAGE_BACKUP_GRACE_HOURS`). */
22
+ export declare const BACKUP_GRACE_HOURS = 24;
23
+ /**
24
+ * Git's default expiry for reflog entries that point at rewritten history
25
+ * (gc.reflogExpireUnreachable). Core that keeps undo history frees the space
26
+ * a prune or offload rewrote only after these entries age out.
27
+ */
28
+ export declare const UNDO_WINDOW_DAYS = 30;
29
+ /** Whether the installed core keeps git's undo history (never expires reflogs early). */
30
+ export declare function coreKeepsUndo(script: string): boolean;
31
+ /** Hours after a rewrite until its space is freed, for this core. */
32
+ export declare function reclaimWindowHours(script: string): number;
33
+ export interface HoldingRef {
34
+ name: string;
35
+ commit_date: string | null;
36
+ }
37
+ export interface ReclaimReport {
38
+ available: boolean;
39
+ dropped?: number;
40
+ freed_bytes?: number;
41
+ reason?: string;
42
+ }
43
+ /** Whether the installed core script has a `case` arm for `sub`. */
44
+ export declare function coreSupports(script: string, sub: string): boolean;
45
+ /** Whether the installed core script mentions a flag, e.g. `--no-backup`. */
46
+ export declare function coreHasFlag(script: string, flag: string): boolean;
47
+ /**
48
+ * Structured exit-4 refusal. Newer core prints
49
+ * `{"refused":"nothing_to_free","holding_refs":[...],"holding_refs_count":N}`
50
+ * on stdout. Older core printed only a stderr line naming `(ref, ref)`; the
51
+ * ref names are taken from it and the line itself (which tells the user to
52
+ * delete them) is dropped.
53
+ */
54
+ export declare function parseRefusal(stdout: string, stderr: string): LocalReport;
55
+ /** Core exit code for a failed precondition (remote-tracking branches, ...). */
56
+ export declare const CORE_PRECONDITION_EXIT = 5;
57
+ /** Plain text for a precondition refusal from core that printed no message. */
58
+ export declare const PRECONDITION_FALLBACK = "HQ is not in a state where its history can be rewritten. Nothing was changed.";
59
+ export interface PreconditionRefusal {
60
+ refused: string;
61
+ message: string;
62
+ }
63
+ /** `{"refused":"<code>","message":".."}` on stdout, or a plain fallback. */
64
+ export declare function parsePreconditionRefusal(stdout: string): PreconditionRefusal;
65
+ /** Run one core subcommand and return its JSON as a report. */
66
+ export declare function runCoreScript(runScript: ScriptRunner, script: string, args: string[]): Promise<LocalReport>;
67
+ /**
68
+ * Run core `drop-backups --expired` when the script has it; undefined when it
69
+ * does not. Call only right before a real prune or offload.
70
+ */
71
+ export declare function dropExpiredBackups(runScript: ScriptRunner, script: string): Promise<ReclaimReport | undefined>;
72
+ /**
73
+ * Core `check`: undefined when core lacks it (or it fails to run), else null
74
+ * when every precondition holds, or the refusal.
75
+ */
76
+ export declare function checkPreconditions(runScript: ScriptRunner, script: string, forCmd: "prune" | "strip-large"): Promise<PreconditionRefusal | null | undefined>;
77
+ export declare function reclaimEstimate(now: Date, hours?: number): string;
78
+ /**
79
+ * Backup fields for a prune or strip-large result.
80
+ * - dry run: `reclaim_after` is an estimate (now + `windowHours`: 24 h for
81
+ * the backup, or 30 days when core keeps undo history) and all of
82
+ * `expectedBytes` is pending.
83
+ * - real run: core's `backup_ref` / `reclaim_after`; `pending_reclaim_bytes`
84
+ * is core's value when it reports one, else `expectedBytes - freed` while a
85
+ * backup is held, else 0.
86
+ */
87
+ export declare function reclaimFields(core: Record<string, unknown>, opts: {
88
+ dryRun: boolean;
89
+ now: Date;
90
+ expectedBytes: number;
91
+ freedBytes: number;
92
+ windowHours?: number;
93
+ }): {
94
+ backup_ref: string | null;
95
+ reclaim_after: string | null;
96
+ pending_reclaim_bytes: number;
97
+ };
98
+ //# sourceMappingURL=storage-core.d.ts.map