@indigoai-us/hq-cli 5.115.0 → 5.115.2

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 (34) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/assets/scaffold/core/scripts/qmd-reindex-after-sync.sh +10 -87
  3. package/dist/commands/bot.js +32 -7
  4. package/dist/commands/index-cmd.d.ts +8 -1
  5. package/dist/commands/index-cmd.js +15 -5
  6. package/dist/commands/onboard-identity-guard.d.ts +1 -1
  7. package/dist/commands/onboard.js +1 -1
  8. package/dist/lib/bot/api.d.ts +5 -0
  9. package/dist/lib/bot/api.js +2 -0
  10. package/dist/lib/bot/prompt.d.ts +8 -1
  11. package/dist/lib/bot/prompt.js +10 -2
  12. package/dist/lib/bot/run.js +1 -1
  13. package/dist/lib/core-utils/qmd-reindex-after-sync.d.ts +4 -1
  14. package/dist/lib/core-utils/qmd-reindex-after-sync.js +11 -2
  15. package/dist/lib/onboarding/checkpoint.d.ts +13 -0
  16. package/dist/lib/onboarding/checkpoint.js +44 -0
  17. package/dist/lib/onboarding/cli/onboard.d.ts +53 -0
  18. package/dist/lib/onboarding/cli/onboard.js +135 -0
  19. package/dist/lib/onboarding/cli/prompts.d.ts +28 -0
  20. package/dist/lib/onboarding/cli/prompts.js +83 -0
  21. package/dist/lib/onboarding/errors.d.ts +33 -0
  22. package/dist/lib/onboarding/errors.js +59 -0
  23. package/dist/lib/onboarding/index.d.ts +17 -0
  24. package/dist/lib/onboarding/index.js +16 -0
  25. package/dist/lib/onboarding/orchestrator.d.ts +47 -0
  26. package/dist/lib/onboarding/orchestrator.js +569 -0
  27. package/dist/lib/onboarding/types.d.ts +79 -0
  28. package/dist/lib/onboarding/types.js +8 -0
  29. package/dist/lib/search-index/background.js +2 -200
  30. package/dist/lib/search-index/embed-lock.d.ts +38 -0
  31. package/dist/lib/search-index/embed-lock.js +286 -0
  32. package/dist/lib/search-index/index.d.ts +1 -0
  33. package/dist/lib/search-index/index.js +4 -1
  34. package/package.json +1 -2
@@ -0,0 +1,135 @@
1
+ /**
2
+ * CLI onboard entry point (VLT-9 US-002; vendored from @indigoai-us/hq-onboarding).
3
+ *
4
+ * Programmatic API for the /onboard command. The slash command calls
5
+ * these functions; they can also be consumed by integration tests.
6
+ */
7
+ import { VaultClient, VaultConflictError, VaultNotFoundError } from "@indigoai-us/hq-cloud";
8
+ import { createCompanyFlow, joinCompanyFlow, resumeOnboarding, } from "../orchestrator.js";
9
+ import { readCheckpoint, getCheckpointPath } from "../checkpoint.js";
10
+ import { formatProgress, formatSummary, formatError } from "./prompts.js";
11
+ const CREATE_STEPS = 6;
12
+ const JOIN_STEPS = 6;
13
+ /**
14
+ * Decide whether `create-company` may proceed for a slug.
15
+ *
16
+ * A company that already exists in the CALLER's namespace is not "taken": it
17
+ * is theirs — typically left behind by an earlier run that created the
18
+ * entity and then died before the bucket, membership, or config were done
19
+ * (there may be no local checkpoint or company folder at all). The flow
20
+ * resumes against it instead of refusing. Only a slug held by a different
21
+ * account is refused.
22
+ */
23
+ export async function checkCompanySlugAvailability(client, slug) {
24
+ const mine = await client.entity.findInMyNamespace("company", slug);
25
+ if (mine)
26
+ return { kind: "mine", uid: mine.uid };
27
+ try {
28
+ await client.entity.findBySlug("company", slug);
29
+ return { kind: "taken" };
30
+ }
31
+ catch (err) {
32
+ // VaultNotFoundError = slug available, continue
33
+ const isNotFound = err instanceof VaultNotFoundError ||
34
+ (err instanceof Error && err.name === "VaultNotFoundError");
35
+ if (isNotFound)
36
+ return { kind: "available" };
37
+ // Several other tenants hold the slug (server answers 409): not ours.
38
+ const isConflict = err instanceof VaultConflictError ||
39
+ (err instanceof Error && err.name === "VaultConflictError");
40
+ if (isConflict)
41
+ return { kind: "taken" };
42
+ throw err;
43
+ }
44
+ }
45
+ /**
46
+ * Run the /onboard CLI flow.
47
+ */
48
+ export async function runOnboardCli(options) {
49
+ const { mode, vaultConfig, hqRoot, log = console.log } = options;
50
+ let stepCounter = 0;
51
+ const onProgress = (event) => {
52
+ if (event.status === "running")
53
+ stepCounter++;
54
+ const total = mode === "create-company" ? CREATE_STEPS : JOIN_STEPS;
55
+ log(formatProgress(event, stepCounter, total));
56
+ };
57
+ const config = { vaultConfig, hqRoot };
58
+ try {
59
+ if (mode === "resume") {
60
+ const checkpoint = await readCheckpoint(hqRoot);
61
+ if (!checkpoint) {
62
+ return { success: false, error: "No checkpoint found. Run /onboard to start." };
63
+ }
64
+ log(`Resuming ${checkpoint.mode} flow from step ${checkpoint.completedSteps.length + 1}...`);
65
+ const result = await resumeOnboarding(config, onProgress);
66
+ log("");
67
+ log(formatSummary(result));
68
+ return { success: true, result };
69
+ }
70
+ if (mode === "dry-run") {
71
+ log("DRY RUN — simulating create-company flow:");
72
+ log(" 1. Create person entity");
73
+ log(" 2. Create company entity");
74
+ log(" 3. Provision S3 bucket + KMS key");
75
+ log(" 4. Bootstrap owner membership");
76
+ log(" 5. Verify STS credential vending");
77
+ log(" 6. Write .hq/config.json");
78
+ log("");
79
+ log("No resources will be created. Run /onboard to execute.");
80
+ return { success: true };
81
+ }
82
+ if (mode === "create-company") {
83
+ // Validate slug availability
84
+ if (options.companySlug) {
85
+ const client = new VaultClient(vaultConfig);
86
+ const availability = await checkCompanySlugAvailability(client, options.companySlug);
87
+ if (availability.kind === "taken") {
88
+ return {
89
+ success: false,
90
+ error: `Company slug "${options.companySlug}" is already taken. Choose another.`,
91
+ };
92
+ }
93
+ if (availability.kind === "mine") {
94
+ log(`Company "${options.companySlug}" already exists in your account (${availability.uid}) — finishing its setup.`);
95
+ }
96
+ }
97
+ const input = {
98
+ mode: "create-company",
99
+ personName: options.personName,
100
+ personEmail: options.personEmail,
101
+ companyName: options.companyName,
102
+ companySlug: options.companySlug,
103
+ };
104
+ log(`Creating company "${input.companyName}" (${input.companySlug})...`);
105
+ log("");
106
+ const result = await createCompanyFlow(input, config, onProgress);
107
+ log("");
108
+ log(formatSummary(result));
109
+ return { success: true, result };
110
+ }
111
+ if (mode === "join-company") {
112
+ const input = {
113
+ mode: "join-company",
114
+ personName: options.personName,
115
+ personEmail: options.personEmail,
116
+ inviteToken: options.inviteToken,
117
+ };
118
+ log("Joining company via invite...");
119
+ log("");
120
+ const result = await joinCompanyFlow(input, config, onProgress);
121
+ log("");
122
+ log(formatSummary(result));
123
+ return { success: true, result };
124
+ }
125
+ return { success: false, error: `Unknown mode: ${mode}` };
126
+ }
127
+ catch (err) {
128
+ const checkpointPath = getCheckpointPath(hqRoot);
129
+ const errorMsg = err instanceof Error ? err.message : String(err);
130
+ log("");
131
+ log(formatError(err instanceof Error ? err : new Error(errorMsg), checkpointPath));
132
+ return { success: false, error: errorMsg };
133
+ }
134
+ }
135
+ //# sourceMappingURL=onboard.js.map
@@ -0,0 +1,28 @@
1
+ /**
2
+ * CLI prompt helpers for /onboard command (VLT-9 US-002; vendored from @indigoai-us/hq-onboarding).
3
+ *
4
+ * Provides typed prompt interfaces the slash command can call.
5
+ * These are library functions — the actual UX is in onboard.md.
6
+ */
7
+ import type { OnboardingResult, OnboardingProgress } from "../types.js";
8
+ /**
9
+ * Format a progress event for CLI display.
10
+ */
11
+ export declare function formatProgress(event: OnboardingProgress, stepNumber: number, totalSteps: number): string;
12
+ /**
13
+ * Format the success summary box.
14
+ */
15
+ export declare function formatSummary(result: OnboardingResult): string;
16
+ /**
17
+ * Format an error for CLI display with recovery hints.
18
+ */
19
+ export declare function formatError(error: Error, checkpointPath: string): string;
20
+ /**
21
+ * Validate a company slug: lowercase, alphanumeric + hyphens, 3-40 chars.
22
+ */
23
+ export declare function validateSlug(slug: string): string | null;
24
+ /**
25
+ * Validate email format.
26
+ */
27
+ export declare function validateEmail(email: string): string | null;
28
+ //# sourceMappingURL=prompts.d.ts.map
@@ -0,0 +1,83 @@
1
+ /**
2
+ * CLI prompt helpers for /onboard command (VLT-9 US-002; vendored from @indigoai-us/hq-onboarding).
3
+ *
4
+ * Provides typed prompt interfaces the slash command can call.
5
+ * These are library functions — the actual UX is in onboard.md.
6
+ */
7
+ /**
8
+ * Format a progress event for CLI display.
9
+ */
10
+ export function formatProgress(event, stepNumber, totalSteps) {
11
+ const statusIcon = {
12
+ pending: "○",
13
+ running: "◉",
14
+ done: "✓",
15
+ skipped: "→",
16
+ failed: "✗",
17
+ }[event.status];
18
+ const detail = event.detail ? ` — ${event.detail}` : "";
19
+ return ` ${statusIcon} Step ${stepNumber}/${totalSteps}: ${event.step}${detail}`;
20
+ }
21
+ /**
22
+ * Format the success summary box.
23
+ */
24
+ export function formatSummary(result) {
25
+ const lines = [
26
+ "┌─────────────────────────────────────────────┐",
27
+ "│ HQ Onboarding Complete │",
28
+ "├─────────────────────────────────────────────┤",
29
+ `│ Company: ${result.companySlug.padEnd(33)}│`,
30
+ `│ UID: ${result.companyUid.padEnd(33)}│`,
31
+ `│ Person: ${result.personUid.padEnd(33)}│`,
32
+ `│ Role: ${result.role.padEnd(33)}│`,
33
+ ];
34
+ if (result.bucketName) {
35
+ lines.push(`│ Bucket: ${result.bucketName.padEnd(33)}│`);
36
+ }
37
+ lines.push("├─────────────────────────────────────────────┤");
38
+ lines.push("│ Next steps: │");
39
+ if (result.role === "owner") {
40
+ lines.push("│ • Run /invite <email> to add team │");
41
+ lines.push("│ • Run hq sync to push files │");
42
+ }
43
+ else {
44
+ lines.push("│ • Run hq sync to pull latest files │");
45
+ }
46
+ lines.push("└─────────────────────────────────────────────┘");
47
+ return lines.join("\n");
48
+ }
49
+ /**
50
+ * Format an error for CLI display with recovery hints.
51
+ */
52
+ export function formatError(error, checkpointPath) {
53
+ const lines = [
54
+ `ERROR: ${error.message}`,
55
+ "",
56
+ `Checkpoint saved to: ${checkpointPath}`,
57
+ "To retry: /onboard --resume",
58
+ ];
59
+ return lines.join("\n");
60
+ }
61
+ /**
62
+ * Validate a company slug: lowercase, alphanumeric + hyphens, 3-40 chars.
63
+ */
64
+ export function validateSlug(slug) {
65
+ if (slug.length < 3)
66
+ return "Slug must be at least 3 characters";
67
+ if (slug.length > 40)
68
+ return "Slug must be at most 40 characters";
69
+ if (!/^[a-z0-9][a-z0-9-]*[a-z0-9]$/.test(slug)) {
70
+ return "Slug must be lowercase alphanumeric with hyphens (e.g. 'my-company')";
71
+ }
72
+ return null;
73
+ }
74
+ /**
75
+ * Validate email format.
76
+ */
77
+ export function validateEmail(email) {
78
+ if (!email.includes("@") || !email.includes(".")) {
79
+ return "Invalid email format";
80
+ }
81
+ return null;
82
+ }
83
+ //# sourceMappingURL=prompts.js.map
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Onboarding error classes (VLT-9 US-001; vendored from @indigoai-us/hq-onboarding).
3
+ *
4
+ * Each failure class maps to a distinct step in the onboarding flow,
5
+ * making it easy for the installer to show targeted recovery hints.
6
+ */
7
+ export declare class OnboardingError extends Error {
8
+ readonly step: string;
9
+ readonly cause?: Error | undefined;
10
+ constructor(message: string, step: string, cause?: Error | undefined);
11
+ }
12
+ export declare class PersonCreationError extends OnboardingError {
13
+ constructor(message: string, cause?: Error);
14
+ }
15
+ export declare class CompanyCreationError extends OnboardingError {
16
+ constructor(message: string, cause?: Error);
17
+ }
18
+ export declare class ProvisioningError extends OnboardingError {
19
+ constructor(message: string, cause?: Error);
20
+ }
21
+ export declare class MembershipBootstrapError extends OnboardingError {
22
+ constructor(message: string, cause?: Error);
23
+ }
24
+ export declare class FirstSyncError extends OnboardingError {
25
+ constructor(message: string, cause?: Error);
26
+ }
27
+ export declare class InviteAcceptError extends OnboardingError {
28
+ constructor(message: string, cause?: Error);
29
+ }
30
+ export declare class StsVerifyError extends OnboardingError {
31
+ constructor(message: string, cause?: Error);
32
+ }
33
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Onboarding error classes (VLT-9 US-001; vendored from @indigoai-us/hq-onboarding).
3
+ *
4
+ * Each failure class maps to a distinct step in the onboarding flow,
5
+ * making it easy for the installer to show targeted recovery hints.
6
+ */
7
+ export class OnboardingError extends Error {
8
+ step;
9
+ cause;
10
+ constructor(message, step, cause) {
11
+ super(message);
12
+ this.step = step;
13
+ this.cause = cause;
14
+ this.name = "OnboardingError";
15
+ }
16
+ }
17
+ export class PersonCreationError extends OnboardingError {
18
+ constructor(message, cause) {
19
+ super(message, "create-person", cause);
20
+ this.name = "PersonCreationError";
21
+ }
22
+ }
23
+ export class CompanyCreationError extends OnboardingError {
24
+ constructor(message, cause) {
25
+ super(message, "create-company", cause);
26
+ this.name = "CompanyCreationError";
27
+ }
28
+ }
29
+ export class ProvisioningError extends OnboardingError {
30
+ constructor(message, cause) {
31
+ super(message, "provision-bucket", cause);
32
+ this.name = "ProvisioningError";
33
+ }
34
+ }
35
+ export class MembershipBootstrapError extends OnboardingError {
36
+ constructor(message, cause) {
37
+ super(message, "bootstrap-membership", cause);
38
+ this.name = "MembershipBootstrapError";
39
+ }
40
+ }
41
+ export class FirstSyncError extends OnboardingError {
42
+ constructor(message, cause) {
43
+ super(message, "first-sync", cause);
44
+ this.name = "FirstSyncError";
45
+ }
46
+ }
47
+ export class InviteAcceptError extends OnboardingError {
48
+ constructor(message, cause) {
49
+ super(message, "accept-invite", cause);
50
+ this.name = "InviteAcceptError";
51
+ }
52
+ }
53
+ export class StsVerifyError extends OnboardingError {
54
+ constructor(message, cause) {
55
+ super(message, "verify-sts", cause);
56
+ this.name = "StsVerifyError";
57
+ }
58
+ }
59
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Onboarding orchestrator (formerly the npm package `@indigoai-us/hq-onboarding`,
3
+ * vendored into hq-cli in 2026-09 because nobody owned the package and its
4
+ * company-create step no longer matched the vault-service's authorization).
5
+ *
6
+ * Composes entities, bucket provisioning, STS, sync, membership, and
7
+ * invite/accept into create-company and join-company flows with
8
+ * checkpoint/resume.
9
+ */
10
+ export { createCompanyFlow, joinCompanyFlow, resumeOnboarding, onboardingContract, } from "./orchestrator.js";
11
+ export { readCheckpoint, writeCheckpoint, deleteCheckpoint, getCheckpointPath, isStepComplete, } from "./checkpoint.js";
12
+ export { OnboardingError, PersonCreationError, CompanyCreationError, ProvisioningError, MembershipBootstrapError, FirstSyncError, InviteAcceptError, StsVerifyError, } from "./errors.js";
13
+ export type { OnboardingInput, CreateCompanyInput, JoinCompanyInput, OnboardingConfig, OnboardingResult, OnboardingProgress, OnboardingStep, StepStatus, ProgressCallback, OnboardingCheckpoint, DesktopInstallerContract, HqConfig, } from "./types.js";
14
+ export { runOnboardCli } from "./cli/onboard.js";
15
+ export type { OnboardCliOptions, OnboardCliResult } from "./cli/onboard.js";
16
+ export { formatProgress, formatSummary, formatError, validateSlug, validateEmail } from "./cli/prompts.js";
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Onboarding orchestrator (formerly the npm package `@indigoai-us/hq-onboarding`,
3
+ * vendored into hq-cli in 2026-09 because nobody owned the package and its
4
+ * company-create step no longer matched the vault-service's authorization).
5
+ *
6
+ * Composes entities, bucket provisioning, STS, sync, membership, and
7
+ * invite/accept into create-company and join-company flows with
8
+ * checkpoint/resume.
9
+ */
10
+ export { createCompanyFlow, joinCompanyFlow, resumeOnboarding, onboardingContract, } from "./orchestrator.js";
11
+ export { readCheckpoint, writeCheckpoint, deleteCheckpoint, getCheckpointPath, isStepComplete, } from "./checkpoint.js";
12
+ export { OnboardingError, PersonCreationError, CompanyCreationError, ProvisioningError, MembershipBootstrapError, FirstSyncError, InviteAcceptError, StsVerifyError, } from "./errors.js";
13
+ // CLI
14
+ export { runOnboardCli } from "./cli/onboard.js";
15
+ export { formatProgress, formatSummary, formatError, validateSlug, validateEmail } from "./cli/prompts.js";
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Onboarding orchestrator (VLT-9 US-001; vendored from @indigoai-us/hq-onboarding).
3
+ *
4
+ * Composes VLT-1 (entities), VLT-2 (bucket provisioning), VLT-3 (STS),
5
+ * VLT-5 (sync), VLT-6 (membership), and VLT-7 (invite/accept) into two
6
+ * end-to-end flows:
7
+ *
8
+ * createCompanyFlow — founder creates a new company + vault
9
+ * joinCompanyFlow — invitee accepts an invite and syncs
10
+ *
11
+ * Each step is idempotent via checkpoint/resume. Progress events are
12
+ * emitted via callback for the installer UI.
13
+ */
14
+ import type { CreateCompanyInput, JoinCompanyInput, OnboardingConfig, OnboardingResult, ProgressCallback, DesktopInstallerContract } from "./types.js";
15
+ /**
16
+ * Create-company flow for founders.
17
+ *
18
+ * Steps:
19
+ * 1. Create person entity
20
+ * 2. Create company entity (the vault-service makes the caller its owner)
21
+ * 3. Provision bucket + KMS via vault-service
22
+ * 4. Bootstrap owner membership (library-direct, bypasses handler auth)
23
+ * 5. Verify STS vend works end-to-end
24
+ * 6. Write .hq/config.json
25
+ */
26
+ export declare function createCompanyFlow(input: CreateCompanyInput, config: OnboardingConfig, onProgress?: ProgressCallback): Promise<OnboardingResult>;
27
+ /**
28
+ * Join-company flow for invitees.
29
+ *
30
+ * Steps:
31
+ * 1. Parse invite token
32
+ * 2. Create person entity (if not already registered)
33
+ * 3. Accept invite
34
+ * 4. Verify STS vend
35
+ * 5. First sync to pull initial vault contents
36
+ * 6. Write .hq/config.json
37
+ */
38
+ export declare function joinCompanyFlow(input: JoinCompanyInput, config: OnboardingConfig, onProgress?: ProgressCallback): Promise<OnboardingResult>;
39
+ /**
40
+ * Resume an interrupted onboarding flow from checkpoint.
41
+ */
42
+ export declare function resumeOnboarding(config: OnboardingConfig, onProgress?: ProgressCallback): Promise<OnboardingResult>;
43
+ /**
44
+ * Desktop installer contract implementation.
45
+ */
46
+ export declare const onboardingContract: DesktopInstallerContract;
47
+ //# sourceMappingURL=orchestrator.d.ts.map