@indigoai-us/hq-cli 5.311.3 → 5.311.4

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,9 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [5.311.4] — 2026-10-02
6
+ - Preserve existing local company starter files during cloud provisioning by having the CLI request that hq-pro skip blank starter seeding; older servers are detected before company creation.
7
+
5
8
  ## [5.311.3] — 2026-10-01
6
9
  - Match company file access checks against the company-anchored paths printed by `hq files browse`.
7
10
  - Record a placement resolved to the current host as local so the lane starts without dispatching back through Outpost pickup.
@@ -135,6 +135,8 @@ export interface VaultClient {
135
135
  checkSlugInMyNamespace(slug: string): Promise<{
136
136
  available: boolean;
137
137
  conflictingCompanyUid?: string;
138
+ /** Older hq-pro servers omit this field; absence means unsupported. */
139
+ skipStarterSeedSupported?: boolean;
138
140
  }>;
139
141
  /** Fetch a company entity by uid. Used to materialize the entity
140
142
  * after `checkSlugInMyNamespace` reports a same-namespace collision. */
@@ -143,6 +145,7 @@ export interface VaultClient {
143
145
  slug: string;
144
146
  name: string;
145
147
  ownerUid?: string;
148
+ skipStarterSeed?: boolean;
146
149
  }): Promise<VaultEntity>;
147
150
  /**
148
151
  * Soft-tombstone a company (`DELETE /entity/{uid}`). Owner-only. Leaves the
@@ -34,6 +34,25 @@ import * as yaml from "js-yaml";
34
34
  import { parseUserYaml } from "../utils/user-yaml-error.js";
35
35
  import { createSyncProgressRecorder, share, } from "@indigoai-us/hq-cloud";
36
36
  import { DEFAULT_HQ_ROOT, DEFAULT_VAULT_API_URL, ensureCognitoToken, buildVaultConfig, } from "../utils/cognito-session.js";
37
+ const SHARED_COMPANY_STARTER_PATHS = [
38
+ "README.md",
39
+ "board.json",
40
+ "knowledge/README.md",
41
+ "knowledge/design-styles/packs/.gitkeep",
42
+ "people/.gitkeep",
43
+ "policies/.gitkeep",
44
+ "projects/.gitkeep",
45
+ "repos/.gitkeep",
46
+ "skills/.gitkeep",
47
+ "sources/meetings/source.yaml",
48
+ "workspace/.gitignore",
49
+ "workspace/index.jsonl",
50
+ "workspace/sessions/.gitkeep",
51
+ ];
52
+ function hasLocalSharedStarterPath(hqRoot, slug) {
53
+ const companyDir = path.join(hqRoot, "companies", slug);
54
+ return SHARED_COMPANY_STARTER_PATHS.some((relativePath) => fs.existsSync(path.join(companyDir, relativePath)));
55
+ }
37
56
  /** Custom error class so the CLI runner can map to exit codes. */
38
57
  export class ProvisionError extends Error {
39
58
  code;
@@ -333,7 +352,11 @@ export function createDefaultVaultClient(apiUrl, accessToken) {
333
352
  const body = await safeBody(res);
334
353
  throw new ProvisionError(1, `Vault GET /entity/check-slug/me failed: ${res.status} ${res.statusText} — ${body}`);
335
354
  }
336
- return (await res.json());
355
+ const data = (await res.json());
356
+ return {
357
+ ...data,
358
+ skipStarterSeedSupported: data.skipStarterSeedSupported === true,
359
+ };
337
360
  });
338
361
  },
339
362
  async getCompanyByUid(uid) {
@@ -359,6 +382,8 @@ export function createDefaultVaultClient(apiUrl, accessToken) {
359
382
  };
360
383
  if (input.ownerUid)
361
384
  body.ownerUid = input.ownerUid;
385
+ if (input.skipStarterSeed)
386
+ body.skipStarterSeed = true;
362
387
  return withVaultRequest(url, {
363
388
  method: "POST",
364
389
  headers,
@@ -548,6 +573,7 @@ export async function provisionCompany(options) {
548
573
  // match the caller's own person UID(s) from `listMyPersonEntities`.
549
574
  const callerOwnedUids = new Set(persons.map((p) => p.uid));
550
575
  const callerIsOwner = !options.ownerUid || callerOwnedUids.has(options.ownerUid);
576
+ const hasLocalSharedStarterFiles = hasLocalSharedStarterPath(options.hqRoot, options.slug);
551
577
  let entity;
552
578
  let createdEntity = false;
553
579
  if (callerIsOwner) {
@@ -557,17 +583,24 @@ export async function provisionCompany(options) {
557
583
  entity = await vaultClient.getCompanyByUid(slugCheck.conflictingCompanyUid);
558
584
  }
559
585
  else {
586
+ if (hasLocalSharedStarterFiles && !slugCheck.skipStarterSeedSupported) {
587
+ throw new ProvisionError(1, "This hq-pro server does not support preserving local starter files during cloud provisioning; update hq-pro and retry");
588
+ }
560
589
  log(`slug available in caller's namespace — creating vault entity`);
561
590
  entity = await vaultClient.createCompanyEntity({
562
591
  slug: options.slug,
563
592
  name: options.name ?? options.slug,
564
593
  ownerUid: options.ownerUid,
594
+ ...(hasLocalSharedStarterFiles ? { skipStarterSeed: true } : {}),
565
595
  });
566
596
  createdEntity = true;
567
597
  log(`created vault entity uid=${entity.uid}`);
568
598
  }
569
599
  }
570
600
  else {
601
+ if (hasLocalSharedStarterFiles) {
602
+ throw new ProvisionError(1, "Cannot preserve local starter files when provisioning for a different owner");
603
+ }
571
604
  log(`--owner ${options.ownerUid} differs from caller's person(s); skipping namespace pre-check (server authoritatively gates per-target-namespace)`);
572
605
  entity = await vaultClient.createCompanyEntity({
573
606
  slug: options.slug,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@indigoai-us/hq-cli",
3
- "version": "5.311.3",
3
+ "version": "5.311.4",
4
4
  "description": "HQ by Indigo management CLI — modules and cloud sync",
5
5
  "main": "dist/index.js",
6
6
  "bin": {