@indigoai-us/hq-cli 5.345.109 → 5.345.110

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,10 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [5.345.110] — 2026-10-13
6
+ - The bundled sync runner now uses hq-cloud 6.18.69, which compacts the sync-state write-ahead log into a snapshot once the log grows past a size-scaled ratio of the snapshot, so large companies stop accumulating oversized sync-state files.
7
+ - Remove the three policy-family shell rollback copies after the native route's clean release soak. `hq core policy age-report`, `policy retire`, and `policy frontmatter` now use the native route regardless of the retained `core-native-policy` flag, which still gates `knowledge-prefs`.
8
+
5
9
  ## [5.345.109] — 2026-10-13
6
10
  - `hq` commands no longer fail with "The HQ CLI package is being updated" while
7
11
  the desktop app updates the CLI. They wait for the update (up to 4 minutes,
@@ -1,4 +1,5 @@
1
1
  import type { Command } from 'commander';
2
+ import { policyValidatorDiagnostic } from '../lib/policy-validator.js';
2
3
  import { type FrontmatterResult } from './core-policy-frontmatter.js';
3
4
  export type CorePolicyResult = {
4
5
  code: number;
@@ -7,7 +8,9 @@ export type CorePolicyResult = {
7
8
  };
8
9
  export declare function runPolicyAgeReport(args: readonly string[], root: string, env?: NodeJS.ProcessEnv, nowEpoch?: number, platform?: NodeJS.Platform): CorePolicyResult;
9
10
  export declare function runPolicyFrontmatter(args: readonly string[], cwd: string, env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform): FrontmatterResult;
10
- export declare function runPolicyRetire(args: readonly string[], root: string, cwd: string, env?: NodeJS.ProcessEnv, now?: Date): CorePolicyResult;
11
+ export declare function runPolicyRetire(args: readonly string[], root: string, cwd: string, env?: NodeJS.ProcessEnv, now?: Date, dependencies?: {
12
+ validatePolicy?: typeof policyValidatorDiagnostic;
13
+ }): CorePolicyResult;
11
14
  /** Fast-entry adapter; family gating and shell fallback happen before import. */
12
15
  export declare function runPolicyFast(args: readonly string[], _stdin: string, cwd: string, hqRoot: string | undefined, commandName: string): number;
13
16
  export declare function registerCorePolicyCommand(core: Command): void;
@@ -4,14 +4,15 @@
4
4
  import * as fs from 'node:fs';
5
5
  import * as path from 'node:path';
6
6
  import { policyValidatorDiagnostic } from '../lib/policy-validator.js';
7
- import { resolveLiveRoot, resolveBundledAsset } from '../utils/hq-roots.js';
8
- import { runBundledScript } from '../utils/run-bundled-script.js';
7
+ import { packageRoot, resolveLiveRoot } from '../utils/hq-roots.js';
9
8
  import { describeCoreCommand } from './core-command-catalog.js';
10
9
  import { runPolicyFrontmatter as runPolicyFrontmatterImpl } from './core-policy-frontmatter.js';
11
10
  import { awkCannotOpenFileDiagnostic } from '../lib/core-utils/awk-diagnostics.js';
12
- const POLICY_AGE_REPORT_ASSET = 'core/scripts/policy-age-report.sh';
13
- const POLICY_RETIRE_ASSET = 'core/scripts/policy-retire.sh';
14
- const POLICY_FRONTMATTER_ASSET = 'core/scripts/read-policy-frontmatter.sh';
11
+ const POLICY_AGE_REPORT_SCRIPT = 'core/scripts/policy-age-report.sh';
12
+ const POLICY_RETIRE_SCRIPT = 'core/scripts/policy-retire.sh';
13
+ function formerScriptPath(relativePath) {
14
+ return path.join(packageRoot(), 'assets/scaffold', relativePath);
15
+ }
15
16
  const AGE_HELP = [
16
17
  '# hq-core: public',
17
18
  '# policy-age-report.sh — measure policy usage and flag retirement candidates',
@@ -389,7 +390,7 @@ function bashTestGreaterOrEqual(left, right, scriptPath, line, platform) {
389
390
  return { value: BigInt(left) >= parsed, stderr: '' };
390
391
  }
391
392
  export function runPolicyAgeReport(args, root, env = process.env, nowEpoch = Math.floor(Date.now() / 1000), platform = process.platform) {
392
- const parsed = parseAgeOptions(args, resolveBundledAsset(POLICY_AGE_REPORT_ASSET));
393
+ const parsed = parseAgeOptions(args, formerScriptPath(POLICY_AGE_REPORT_SCRIPT));
393
394
  if (parsed.kind === 'help')
394
395
  return policyResult(0, AGE_HELP);
395
396
  if (parsed.kind === 'error')
@@ -448,13 +449,13 @@ export function runPolicyAgeReport(args, root, env = process.env, nowEpoch = Mat
448
449
  const singleIncident = ['user-correction', 'session-learning', 'back-pressure-failure'].includes(source) && (version || '1') === '1';
449
450
  const classes = [];
450
451
  if (fired === 0) {
451
- const comparison = bashTestGreaterOrEqual(ageDays, parsed.minAge, resolveBundledAsset(POLICY_AGE_REPORT_ASSET), 173, platform);
452
+ const comparison = bashTestGreaterOrEqual(ageDays, parsed.minAge, formerScriptPath(POLICY_AGE_REPORT_SCRIPT), 173, platform);
452
453
  stderr += comparison.stderr;
453
454
  if (comparison.value && usage.anyFiles)
454
455
  classes.push('never-fired');
455
456
  }
456
457
  if (fired > 0) {
457
- const comparison = bashTestGreaterOrEqual(lastAge, parsed.dormantDays, resolveBundledAsset(POLICY_AGE_REPORT_ASSET), 174, platform);
458
+ const comparison = bashTestGreaterOrEqual(lastAge, parsed.dormantDays, formerScriptPath(POLICY_AGE_REPORT_SCRIPT), 174, platform);
458
459
  stderr += comparison.stderr;
459
460
  if (comparison.value)
460
461
  classes.push('dormant');
@@ -464,7 +465,7 @@ export function runPolicyAgeReport(args, root, env = process.env, nowEpoch = Mat
464
465
  if (refs.renamed.length > 0)
465
466
  classes.push('renamed-refs');
466
467
  if (singleIncident) {
467
- const comparison = bashTestGreaterOrEqual(ageDays, parsed.incidentDays, resolveBundledAsset(POLICY_AGE_REPORT_ASSET), 178, platform);
468
+ const comparison = bashTestGreaterOrEqual(ageDays, parsed.incidentDays, formerScriptPath(POLICY_AGE_REPORT_SCRIPT), 178, platform);
468
469
  stderr += comparison.stderr;
469
470
  if (comparison.value && fired <= 1)
470
471
  classes.push('single-incident-old');
@@ -625,7 +626,7 @@ function rewriteStatus(content, status, reason, by, now) {
625
626
  }
626
627
  return Buffer.concat(output);
627
628
  }
628
- function setPolicyStatus(filePath, status, reason, by, env, now, cwd = process.cwd()) {
629
+ function setPolicyStatus(filePath, status, reason, by, env, now, cwd = process.cwd(), validatePolicy = policyValidatorDiagnostic) {
629
630
  const resolvedPath = path.isAbsolute(filePath) ? filePath : path.resolve(cwd, filePath);
630
631
  let content;
631
632
  try {
@@ -639,7 +640,7 @@ function setPolicyStatus(filePath, status, reason, by, env, now, cwd = process.c
639
640
  if (!firstLine(content)?.toString('latin1').startsWith('---')) {
640
641
  return { ok: false, error: `policy-retire: ${filePath} has no frontmatter\n` };
641
642
  }
642
- const diagnostic = policyValidatorDiagnostic(content.toString('utf8'), resolvedPath, env);
643
+ const diagnostic = validatePolicy(content.toString('utf8'), resolvedPath, env);
643
644
  if (diagnostic !== undefined) {
644
645
  // Bash command substitution in policy-retire.sh strips all trailing newlines
645
646
  // from the validator output before printf adds its single final newline.
@@ -929,8 +930,8 @@ function fromReport(options, root, cwd, env, now) {
929
930
  stdout += `policy-retire: ${selected} would be retired [${options.className}] (add --yes)\n`;
930
931
  return policyResult(0, stdout, stderr);
931
932
  }
932
- export function runPolicyRetire(args, root, cwd, env = process.env, now = new Date()) {
933
- const parsed = parseRetireOptions(args, resolveBundledAsset(POLICY_RETIRE_ASSET), env);
933
+ export function runPolicyRetire(args, root, cwd, env = process.env, now = new Date(), dependencies = {}) {
934
+ const parsed = parseRetireOptions(args, formerScriptPath(POLICY_RETIRE_SCRIPT), env);
934
935
  if (parsed.kind === 'help')
935
936
  return policyResult(0, RETIRE_HELP);
936
937
  if (parsed.kind === 'error')
@@ -946,14 +947,14 @@ export function runPolicyRetire(args, root, cwd, env = process.env, now = new Da
946
947
  if (file === undefined)
947
948
  return policyResult(3, '', `policy-retire: no policy found for '${options.target}'\n`);
948
949
  if (options.restore) {
949
- const updated = setPolicyStatus(file, 'active', '', options.by, env, now, cwd);
950
+ const updated = setPolicyStatus(file, 'active', '', options.by, env, now, cwd, dependencies.validatePolicy);
950
951
  if (!updated.ok)
951
952
  return policyResult(1, '', updated.error);
952
953
  return policyResult(0, `policy-retire: restored ${displayPolicyPath(file, root)}\n`);
953
954
  }
954
955
  if (!options.reason)
955
956
  return policyResult(2, '', 'policy-retire: --reason is required\n');
956
- const updated = setPolicyStatus(file, 'retired', options.reason, options.by, env, now, cwd);
957
+ const updated = setPolicyStatus(file, 'retired', options.reason, options.by, env, now, cwd, dependencies.validatePolicy);
957
958
  if (!updated.ok)
958
959
  return policyResult(1, '', updated.error);
959
960
  return policyResult(0, `policy-retire: retired ${displayPolicyPath(file, root)} — ${options.reason}\n`);
@@ -983,7 +984,7 @@ export function runPolicyFast(args, _stdin, cwd, hqRoot, commandName) {
983
984
  }
984
985
  export function registerCorePolicyCommand(core) {
985
986
  const group = core.command('policy').description('Policy maintenance commands');
986
- const register = (name, asset, summary, rootKind) => {
987
+ const register = (name, summary, rootKind) => {
987
988
  const command = group
988
989
  .command(name)
989
990
  .description(summary)
@@ -991,47 +992,24 @@ export function registerCorePolicyCommand(core) {
991
992
  .allowExcessArguments()
992
993
  .helpOption(false)
993
994
  .argument('[args...]', 'arguments passed through to the scaffold command');
994
- describeCoreCommand(command, { execution: 'native', asset, root: rootKind });
995
+ describeCoreCommand(command, { execution: 'native', root: rootKind });
995
996
  return command;
996
997
  };
997
- const ageReport = register('age-report', POLICY_AGE_REPORT_ASSET, 'Report policy usage and retirement candidates', 'live');
998
+ const ageReport = register('age-report', 'Report policy usage and retirement candidates', 'live');
998
999
  ageReport.action(async (args = [], _options, command) => {
999
1000
  const operands = command.args.length > 0 ? command.args : args;
1000
- const { coreNativePolicyEnabled } = await import('./core-native-policy-flag.js');
1001
- if (!await coreNativePolicyEnabled()) {
1002
- const root = resolveLiveRoot({ hqRoot: core.opts().hqRoot });
1003
- const result = runBundledScript({ asset: POLICY_AGE_REPORT_ASSET, args: operands, cwd: process.cwd(), hqRoot: root });
1004
- if (result.code !== 0)
1005
- process.exitCode = result.code;
1006
- return;
1007
- }
1008
1001
  const root = resolveLiveRoot({ hqRoot: core.opts().hqRoot });
1009
1002
  writeResult(runPolicyAgeReport(operands, root));
1010
1003
  });
1011
- const retire = register('retire', POLICY_RETIRE_ASSET, 'Retire or restore a policy', 'live');
1004
+ const retire = register('retire', 'Retire or restore a policy', 'live');
1012
1005
  retire.action(async (args = [], _options, command) => {
1013
1006
  const operands = command.args.length > 0 ? command.args : args;
1014
- const { coreNativePolicyEnabled } = await import('./core-native-policy-flag.js');
1015
- if (!await coreNativePolicyEnabled()) {
1016
- const root = resolveLiveRoot({ hqRoot: core.opts().hqRoot });
1017
- const result = runBundledScript({ asset: POLICY_RETIRE_ASSET, args: operands, cwd: process.cwd(), hqRoot: root });
1018
- if (result.code !== 0)
1019
- process.exitCode = result.code;
1020
- return;
1021
- }
1022
1007
  const root = resolveLiveRoot({ hqRoot: core.opts().hqRoot });
1023
1008
  writeResult(runPolicyRetire(operands, root, process.cwd()));
1024
1009
  });
1025
- const frontmatter = register('frontmatter', POLICY_FRONTMATTER_ASSET, 'Extract policy frontmatter', 'cwd');
1010
+ const frontmatter = register('frontmatter', 'Extract policy frontmatter', 'cwd');
1026
1011
  frontmatter.action(async (args = [], _options, command) => {
1027
1012
  const operands = command.args.length > 0 ? command.args : args;
1028
- const { coreNativePolicyEnabled } = await import('./core-native-policy-flag.js');
1029
- if (!await coreNativePolicyEnabled()) {
1030
- const result = runBundledScript({ asset: POLICY_FRONTMATTER_ASSET, args: operands, cwd: process.cwd() });
1031
- if (result.code !== 0)
1032
- process.exitCode = result.code;
1033
- return;
1034
- }
1035
1013
  writeResult(runPolicyFrontmatter(operands, process.cwd()));
1036
1014
  });
1037
1015
  }
@@ -306,17 +306,12 @@ export const SCAFFOLD_ONLY_ASSETS = [
306
306
  { asset: "core/scripts/lib/secret-patterns.sh", root: "live", summary: "Secret-pattern library sourced by the delegate rollback shells" },
307
307
  // Native knowledge-prefs retains its own shell companion until its family PR.
308
308
  { asset: "core/scripts/knowledge-prefs.sh", root: "live", summary: "Rollback companion for native knowledge-prefs" },
309
- // Rollback companions for the default-off native knowledge and policy routes.
310
- // policy-retire also runs the scaffold validator in-process when native, but
311
- // its bundled shell fallback needs both helper assets at these exact paths.
312
- { asset: "core/scripts/policy-age-report.sh", root: "live", summary: "Rollback companion for native policy age-report" },
313
- { asset: "core/scripts/policy-retire.sh", root: "live", summary: "Rollback companion for native policy retire" },
314
- { asset: "core/scripts/read-policy-frontmatter.sh", root: "cwd", summary: "Rollback companion for native policy frontmatter" },
309
+ // Retained policy helpers used by the policy validator and trigger tooling.
315
310
  { asset: "core/scripts/eval-trigger.sh", root: "live", summary: "Trigger grammar helper used by the policy validator companion" },
316
311
  { asset: "core/scripts/migrate-policy-triggers.sh", root: "live", summary: "Rollback shell for native migrate-policy-triggers" },
317
312
  { asset: "core/scripts/register-project.sh", root: "live", summary: "Rollback shell for native register-project" },
318
313
  { asset: "core/scripts/work-mesh-live-rebind.sh", root: "live", summary: "Rollback shell for native work-mesh-live-rebind" },
319
- { asset: ".claude/hooks/validate-policy-frontmatter.sh", root: "live", summary: "Policy validator companion used by policy-retire rollback" },
314
+ { asset: ".claude/hooks/validate-policy-frontmatter.sh", root: "live", summary: "Hook-time policy frontmatter validator" },
320
315
  // Wave 2a handoff shells remain bundled as the default-off rollback path.
321
316
  { asset: "core/scripts/handoff-finalize.sh", root: "live", summary: "Rollback shell for native handoff finalize" },
322
317
  { asset: "core/scripts/handoff-post.sh", root: "live", summary: "Rollback shell for native handoff post" },
@@ -372,11 +372,7 @@ export const FAST_SCAFFOLD_SCRIPTS = [
372
372
  modulePath: "./commands/core-policy.js",
373
373
  exportName: "runPolicyFast",
374
374
  flagKey: "hq-core-native-fast-route",
375
- familyFlagKey: "core-native-policy",
376
- asset: "core/scripts/read-policy-frontmatter.sh",
377
375
  root: "cwd",
378
- shellCwd: "caller",
379
- shellHqRoot: "none",
380
376
  },
381
377
  {
382
378
  name: "policy age-report",
@@ -384,11 +380,7 @@ export const FAST_SCAFFOLD_SCRIPTS = [
384
380
  modulePath: "./commands/core-policy.js",
385
381
  exportName: "runPolicyFast",
386
382
  flagKey: "hq-core-native-fast-route",
387
- familyFlagKey: "core-native-policy",
388
- asset: "core/scripts/policy-age-report.sh",
389
383
  root: "live",
390
- shellCwd: "caller",
391
- shellHqRoot: "live",
392
384
  },
393
385
  {
394
386
  name: "policy retire",
@@ -396,11 +388,7 @@ export const FAST_SCAFFOLD_SCRIPTS = [
396
388
  modulePath: "./commands/core-policy.js",
397
389
  exportName: "runPolicyFast",
398
390
  flagKey: "hq-core-native-fast-route",
399
- familyFlagKey: "core-native-policy",
400
- asset: "core/scripts/policy-retire.sh",
401
391
  root: "live",
402
- shellCwd: "caller",
403
- shellHqRoot: "live",
404
392
  },
405
393
  {
406
394
  name: "knowledge-prefs",