@indigoai-us/hq-cloud 5.1.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 (108) hide show
  1. package/dist/auth.d.ts +21 -0
  2. package/dist/auth.d.ts.map +1 -0
  3. package/dist/auth.js +116 -0
  4. package/dist/auth.js.map +1 -0
  5. package/dist/cli/accept.d.ts +29 -0
  6. package/dist/cli/accept.d.ts.map +1 -0
  7. package/dist/cli/accept.js +67 -0
  8. package/dist/cli/accept.js.map +1 -0
  9. package/dist/cli/conflict.d.ts +33 -0
  10. package/dist/cli/conflict.d.ts.map +1 -0
  11. package/dist/cli/conflict.js +91 -0
  12. package/dist/cli/conflict.js.map +1 -0
  13. package/dist/cli/index.d.ts +19 -0
  14. package/dist/cli/index.d.ts.map +1 -0
  15. package/dist/cli/index.js +14 -0
  16. package/dist/cli/index.js.map +1 -0
  17. package/dist/cli/invite.d.ts +51 -0
  18. package/dist/cli/invite.d.ts.map +1 -0
  19. package/dist/cli/invite.js +120 -0
  20. package/dist/cli/invite.js.map +1 -0
  21. package/dist/cli/invite.test.d.ts +5 -0
  22. package/dist/cli/invite.test.d.ts.map +1 -0
  23. package/dist/cli/invite.test.js +175 -0
  24. package/dist/cli/invite.test.js.map +1 -0
  25. package/dist/cli/promote.d.ts +30 -0
  26. package/dist/cli/promote.d.ts.map +1 -0
  27. package/dist/cli/promote.js +79 -0
  28. package/dist/cli/promote.js.map +1 -0
  29. package/dist/cli/share.d.ts +33 -0
  30. package/dist/cli/share.d.ts.map +1 -0
  31. package/dist/cli/share.js +153 -0
  32. package/dist/cli/share.js.map +1 -0
  33. package/dist/cli/share.test.d.ts +5 -0
  34. package/dist/cli/share.test.d.ts.map +1 -0
  35. package/dist/cli/share.test.js +121 -0
  36. package/dist/cli/share.test.js.map +1 -0
  37. package/dist/cli/sync.d.ts +30 -0
  38. package/dist/cli/sync.d.ts.map +1 -0
  39. package/dist/cli/sync.js +138 -0
  40. package/dist/cli/sync.js.map +1 -0
  41. package/dist/cli/sync.test.d.ts +5 -0
  42. package/dist/cli/sync.test.d.ts.map +1 -0
  43. package/dist/cli/sync.test.js +172 -0
  44. package/dist/cli/sync.test.js.map +1 -0
  45. package/dist/cognito-auth.d.ts +70 -0
  46. package/dist/cognito-auth.d.ts.map +1 -0
  47. package/dist/cognito-auth.js +280 -0
  48. package/dist/cognito-auth.js.map +1 -0
  49. package/dist/context.d.ts +30 -0
  50. package/dist/context.d.ts.map +1 -0
  51. package/dist/context.js +117 -0
  52. package/dist/context.js.map +1 -0
  53. package/dist/context.test.d.ts +7 -0
  54. package/dist/context.test.d.ts.map +1 -0
  55. package/dist/context.test.js +148 -0
  56. package/dist/context.test.js.map +1 -0
  57. package/dist/daemon-worker.d.ts +6 -0
  58. package/dist/daemon-worker.d.ts.map +1 -0
  59. package/dist/daemon-worker.js +26 -0
  60. package/dist/daemon-worker.js.map +1 -0
  61. package/dist/daemon.d.ts +10 -0
  62. package/dist/daemon.d.ts.map +1 -0
  63. package/dist/daemon.js +88 -0
  64. package/dist/daemon.js.map +1 -0
  65. package/dist/ignore.d.ts +10 -0
  66. package/dist/ignore.d.ts.map +1 -0
  67. package/dist/ignore.js +54 -0
  68. package/dist/ignore.js.map +1 -0
  69. package/dist/index.d.ts +33 -0
  70. package/dist/index.d.ts.map +1 -0
  71. package/dist/index.js +138 -0
  72. package/dist/index.js.map +1 -0
  73. package/dist/journal.d.ts +12 -0
  74. package/dist/journal.d.ts.map +1 -0
  75. package/dist/journal.js +42 -0
  76. package/dist/journal.js.map +1 -0
  77. package/dist/s3.d.ts +15 -0
  78. package/dist/s3.d.ts.map +1 -0
  79. package/dist/s3.js +129 -0
  80. package/dist/s3.js.map +1 -0
  81. package/dist/types.d.ts +52 -0
  82. package/dist/types.d.ts.map +1 -0
  83. package/dist/types.js +5 -0
  84. package/dist/types.js.map +1 -0
  85. package/dist/vault-client.d.ts +164 -0
  86. package/dist/vault-client.d.ts.map +1 -0
  87. package/dist/vault-client.js +209 -0
  88. package/dist/vault-client.js.map +1 -0
  89. package/dist/vault-client.test.d.ts +7 -0
  90. package/dist/vault-client.test.d.ts.map +1 -0
  91. package/dist/vault-client.test.js +257 -0
  92. package/dist/vault-client.test.js.map +1 -0
  93. package/dist/watcher.d.ts +18 -0
  94. package/dist/watcher.d.ts.map +1 -0
  95. package/dist/watcher.js +106 -0
  96. package/dist/watcher.js.map +1 -0
  97. package/package.json +32 -0
  98. package/src/auth.ts +146 -0
  99. package/src/cognito-auth.ts +375 -0
  100. package/src/daemon-worker.ts +32 -0
  101. package/src/daemon.ts +97 -0
  102. package/src/ignore.ts +61 -0
  103. package/src/index.ts +182 -0
  104. package/src/journal.ts +63 -0
  105. package/src/s3.ts +178 -0
  106. package/src/types.ts +59 -0
  107. package/src/watcher.ts +130 -0
  108. package/tsconfig.json +8 -0
package/dist/auth.d.ts ADDED
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Authentication — OAuth flow with IndigoAI
3
+ * Opens browser for sign-in, receives tokens via localhost callback
4
+ */
5
+ import type { Credentials } from "./types.js";
6
+ export declare function hasCredentials(): boolean;
7
+ export declare function readCredentials(): Credentials | null;
8
+ export declare function writeCredentials(creds: Credentials): void;
9
+ export declare function clearCredentials(): void;
10
+ /**
11
+ * Start OAuth flow:
12
+ * 1. Open browser to AUTH_URL with callback port
13
+ * 2. Start localhost server to receive tokens
14
+ * 3. Store credentials
15
+ */
16
+ export declare function authenticate(): Promise<Credentials>;
17
+ /**
18
+ * Refresh temporary AWS credentials using refresh token
19
+ */
20
+ export declare function refreshAwsCredentials(creds: Credentials): Promise<Credentials>;
21
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAU9C,wBAAgB,cAAc,IAAI,OAAO,CAExC;AAED,wBAAgB,eAAe,IAAI,WAAW,GAAG,IAAI,CAQpD;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAKzD;AAED,wBAAgB,gBAAgB,IAAI,IAAI,CAIvC;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,WAAW,CAAC,CA0DzD;AAED;;GAEG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,WAAW,GACjB,OAAO,CAAC,WAAW,CAAC,CA4BtB"}
package/dist/auth.js ADDED
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Authentication — OAuth flow with IndigoAI
3
+ * Opens browser for sign-in, receives tokens via localhost callback
4
+ */
5
+ import * as fs from "fs";
6
+ import * as path from "path";
7
+ import * as http from "http";
8
+ import open from "open";
9
+ const AUTH_URL = "https://hq.indigoai.com/auth";
10
+ const CALLBACK_PORT = 19847;
11
+ const CREDS_DIR = path.join(process.env.HOME || process.env.USERPROFILE || "~", ".hq");
12
+ const CREDS_FILE = path.join(CREDS_DIR, "credentials.json");
13
+ export function hasCredentials() {
14
+ return fs.existsSync(CREDS_FILE);
15
+ }
16
+ export function readCredentials() {
17
+ if (!fs.existsSync(CREDS_FILE))
18
+ return null;
19
+ try {
20
+ const content = fs.readFileSync(CREDS_FILE, "utf-8");
21
+ return JSON.parse(content);
22
+ }
23
+ catch {
24
+ return null;
25
+ }
26
+ }
27
+ export function writeCredentials(creds) {
28
+ if (!fs.existsSync(CREDS_DIR)) {
29
+ fs.mkdirSync(CREDS_DIR, { recursive: true });
30
+ }
31
+ fs.writeFileSync(CREDS_FILE, JSON.stringify(creds, null, 2), { mode: 0o600 });
32
+ }
33
+ export function clearCredentials() {
34
+ if (fs.existsSync(CREDS_FILE)) {
35
+ fs.unlinkSync(CREDS_FILE);
36
+ }
37
+ }
38
+ /**
39
+ * Start OAuth flow:
40
+ * 1. Open browser to AUTH_URL with callback port
41
+ * 2. Start localhost server to receive tokens
42
+ * 3. Store credentials
43
+ */
44
+ export async function authenticate() {
45
+ return new Promise((resolve, reject) => {
46
+ const server = http.createServer((req, res) => {
47
+ const url = new URL(req.url || "", `http://localhost:${CALLBACK_PORT}`);
48
+ if (url.pathname === "/callback") {
49
+ const token = url.searchParams.get("token");
50
+ const refreshToken = url.searchParams.get("refresh_token");
51
+ const userId = url.searchParams.get("user_id");
52
+ const bucket = url.searchParams.get("bucket");
53
+ const region = url.searchParams.get("region") || "us-east-1";
54
+ const teamId = url.searchParams.get("team_id");
55
+ if (!token || !refreshToken || !userId || !bucket) {
56
+ res.writeHead(400, { "Content-Type": "text/html" });
57
+ res.end("<h1>Authentication failed</h1><p>Missing required parameters. Please try again.</p>");
58
+ server.close();
59
+ reject(new Error("Authentication failed: missing parameters"));
60
+ return;
61
+ }
62
+ const creds = {
63
+ accessKeyId: "", // Will be populated via STS
64
+ secretAccessKey: "",
65
+ refreshToken,
66
+ userId,
67
+ bucket,
68
+ region,
69
+ ...(teamId ? { teamId } : {}),
70
+ };
71
+ writeCredentials(creds);
72
+ res.writeHead(200, { "Content-Type": "text/html" });
73
+ res.end("<h1>Authenticated!</h1><p>You can close this window and return to your terminal.</p>");
74
+ server.close();
75
+ resolve(creds);
76
+ }
77
+ });
78
+ server.listen(CALLBACK_PORT, () => {
79
+ const authUrl = `${AUTH_URL}?callback=http://localhost:${CALLBACK_PORT}/callback`;
80
+ console.log(` Opening browser for authentication...`);
81
+ console.log(` If browser doesn't open, visit: ${authUrl}`);
82
+ open(authUrl).catch(() => {
83
+ // If open fails, user can manually visit the URL
84
+ });
85
+ });
86
+ // Timeout after 5 minutes
87
+ setTimeout(() => {
88
+ server.close();
89
+ reject(new Error("Authentication timed out after 5 minutes"));
90
+ }, 5 * 60 * 1000);
91
+ });
92
+ }
93
+ /**
94
+ * Refresh temporary AWS credentials using refresh token
95
+ */
96
+ export async function refreshAwsCredentials(creds) {
97
+ const response = await fetch("https://hq.indigoai.com/api/auth/refresh", {
98
+ method: "POST",
99
+ headers: { "Content-Type": "application/json" },
100
+ body: JSON.stringify({ refreshToken: creds.refreshToken }),
101
+ });
102
+ if (!response.ok) {
103
+ throw new Error(`Failed to refresh credentials: ${response.statusText}`);
104
+ }
105
+ const data = (await response.json());
106
+ const updated = {
107
+ ...creds,
108
+ accessKeyId: data.accessKeyId,
109
+ secretAccessKey: data.secretAccessKey,
110
+ sessionToken: data.sessionToken,
111
+ expiration: data.expiration,
112
+ };
113
+ writeCredentials(updated);
114
+ return updated;
115
+ }
116
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * `hq accept` command — accept a membership invite (VLT-7 US-003).
3
+ *
4
+ * Parses magic links (hq://accept/<token> or raw tokens), resolves the
5
+ * caller's identity from Cognito, and calls VaultClient.acceptInvite().
6
+ */
7
+ import type { VaultServiceConfig } from "../types.js";
8
+ import type { Membership } from "../vault-client.js";
9
+ export interface AcceptOptions {
10
+ /** Raw token or magic link (hq://accept/<token>) */
11
+ tokenOrLink: string;
12
+ /** Caller's person UID (from Cognito) */
13
+ callerUid: string;
14
+ /** Vault service config */
15
+ vaultConfig: VaultServiceConfig;
16
+ }
17
+ export interface AcceptResult {
18
+ membership: Membership;
19
+ companySlug?: string;
20
+ }
21
+ /**
22
+ * Parse a magic link or raw token into the raw invite token.
23
+ */
24
+ export declare function parseToken(tokenOrLink: string): string;
25
+ /**
26
+ * Accept a membership invite.
27
+ */
28
+ export declare function accept(options: AcceptOptions): Promise<AcceptResult>;
29
+ //# sourceMappingURL=accept.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accept.d.ts","sourceRoot":"","sources":["../../src/cli/accept.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAQtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,MAAM,WAAW,aAAa;IAC5B,oDAAoD;IACpD,WAAW,EAAE,MAAM,CAAC;IACpB,yCAAyC;IACzC,SAAS,EAAE,MAAM,CAAC;IAClB,2BAA2B;IAC3B,WAAW,EAAE,kBAAkB,CAAC;CACjC;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,UAAU,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAgBtD;AAED;;GAEG;AACH,wBAAsB,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAyC1E"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * `hq accept` command — accept a membership invite (VLT-7 US-003).
3
+ *
4
+ * Parses magic links (hq://accept/<token> or raw tokens), resolves the
5
+ * caller's identity from Cognito, and calls VaultClient.acceptInvite().
6
+ */
7
+ import { VaultClient, VaultAuthError, VaultNotFoundError, VaultConflictError, VaultPermissionDeniedError, } from "../vault-client.js";
8
+ /**
9
+ * Parse a magic link or raw token into the raw invite token.
10
+ */
11
+ export function parseToken(tokenOrLink) {
12
+ const trimmed = tokenOrLink.trim();
13
+ // hq://accept/<token>
14
+ if (trimmed.startsWith("hq://accept/")) {
15
+ return trimmed.slice("hq://accept/".length);
16
+ }
17
+ // https://hq.indigoai.com/accept/<token> (future web route)
18
+ const httpsPrefix = "https://hq.indigoai.com/accept/";
19
+ if (trimmed.startsWith(httpsPrefix)) {
20
+ return trimmed.slice(httpsPrefix.length);
21
+ }
22
+ // Raw token
23
+ return trimmed;
24
+ }
25
+ /**
26
+ * Accept a membership invite.
27
+ */
28
+ export async function accept(options) {
29
+ const { tokenOrLink, callerUid, vaultConfig } = options;
30
+ const token = parseToken(tokenOrLink);
31
+ if (!token) {
32
+ throw new Error("No invite token provided. Usage: /accept <token-or-magic-link>");
33
+ }
34
+ const client = new VaultClient(vaultConfig);
35
+ try {
36
+ const result = await client.acceptInvite(token, callerUid);
37
+ const membership = result.membership;
38
+ // Try to resolve company slug for display
39
+ let companySlug;
40
+ if (membership.companyUid) {
41
+ try {
42
+ const entity = await client.entity.get(membership.companyUid);
43
+ companySlug = entity.slug;
44
+ }
45
+ catch {
46
+ // Non-critical — just display UID instead
47
+ }
48
+ }
49
+ return { membership, companySlug };
50
+ }
51
+ catch (err) {
52
+ if (err instanceof VaultAuthError) {
53
+ throw new Error("Authentication failed — run `hq auth` to refresh your session");
54
+ }
55
+ if (err instanceof VaultConflictError) {
56
+ throw new Error("This invite was already accepted");
57
+ }
58
+ if (err instanceof VaultNotFoundError) {
59
+ throw new Error("Invite not found or expired");
60
+ }
61
+ if (err instanceof VaultPermissionDeniedError) {
62
+ throw new Error("This invite was for a different person");
63
+ }
64
+ throw err;
65
+ }
66
+ }
67
+ //# sourceMappingURL=accept.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accept.js","sourceRoot":"","sources":["../../src/cli/accept.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EACL,WAAW,EACX,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,0BAA0B,GAC3B,MAAM,oBAAoB,CAAC;AAiB5B;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,WAAmB;IAC5C,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,EAAE,CAAC;IAEnC,sBAAsB;IACtB,IAAI,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;QACvC,OAAO,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;IAC9C,CAAC;IAED,4DAA4D;IAC5D,MAAM,WAAW,GAAG,iCAAiC,CAAC;IACtD,IAAI,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QACpC,OAAO,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3C,CAAC;IAED,YAAY;IACZ,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,OAAsB;IACjD,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IACxD,MAAM,KAAK,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IAEtC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;IACpF,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,WAAW,CAAC,WAAW,CAAC,CAAC;IAE5C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAC3D,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;QAErC,0CAA0C;QAC1C,IAAI,WAA+B,CAAC;QACpC,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;YAC1B,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;gBAC9D,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC;YAC5B,CAAC;YAAC,MAAM,CAAC;gBACP,0CAA0C;YAC5C,CAAC;QACH,CAAC;QAED,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,CAAC;IACrC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,cAAc,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAC;QACnF,CAAC;QACD,IAAI,GAAG,YAAY,kBAAkB,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;QACtD,CAAC;QACD,IAAI,GAAG,YAAY,kBAAkB,EAAE,CAAC;YACtC,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACjD,CAAC;QACD,IAAI,GAAG,YAAY,0BAA0B,EAAE,CAAC;YAC9C,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC5D,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;AACH,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Conflict resolution for hq share/sync (VLT-5 US-002).
3
+ *
4
+ * Interactive prompts in terminal mode; deterministic resolution via
5
+ * --on-conflict flag for worker/skill callers.
6
+ */
7
+ export type ConflictStrategy = "overwrite" | "keep" | "abort";
8
+ export interface ConflictInfo {
9
+ path: string;
10
+ localHash?: string;
11
+ remoteHash?: string;
12
+ localModified?: Date;
13
+ remoteModified?: Date;
14
+ direction: "push" | "pull";
15
+ }
16
+ export type ConflictResolution = "overwrite" | "keep" | "skip" | "diff" | "abort";
17
+ /**
18
+ * Resolve a conflict interactively or via strategy flag.
19
+ *
20
+ * In non-interactive mode (strategy provided), returns deterministically:
21
+ * overwrite → "overwrite"
22
+ * keep → "keep"
23
+ * abort → "abort"
24
+ *
25
+ * In interactive mode (strategy undefined), prompts the user.
26
+ */
27
+ export declare function resolveConflict(conflict: ConflictInfo, strategy?: ConflictStrategy): Promise<ConflictResolution>;
28
+ /**
29
+ * Show a simple diff between local and remote content.
30
+ * Returns the content strings for display.
31
+ */
32
+ export declare function showDiff(localPath: string, remoteContent: Buffer): void;
33
+ //# sourceMappingURL=conflict.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conflict.d.ts","sourceRoot":"","sources":["../../src/cli/conflict.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,MAAM,MAAM,gBAAgB,GAAG,WAAW,GAAG,MAAM,GAAG,OAAO,CAAC;AAE9D,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,IAAI,CAAC;IACrB,cAAc,CAAC,EAAE,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC;CAC5B;AAED,MAAM,MAAM,kBAAkB,GAAG,WAAW,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAElF;;;;;;;;;GASG;AACH,wBAAsB,eAAe,CACnC,QAAQ,EAAE,YAAY,EACtB,QAAQ,CAAC,EAAE,gBAAgB,GAC1B,OAAO,CAAC,kBAAkB,CAAC,CAM7B;AAuDD;;;GAGG;AACH,wBAAgB,QAAQ,CACtB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,GACpB,IAAI,CAcN"}
@@ -0,0 +1,91 @@
1
+ /**
2
+ * Conflict resolution for hq share/sync (VLT-5 US-002).
3
+ *
4
+ * Interactive prompts in terminal mode; deterministic resolution via
5
+ * --on-conflict flag for worker/skill callers.
6
+ */
7
+ import * as fs from "fs";
8
+ import * as readline from "readline";
9
+ /**
10
+ * Resolve a conflict interactively or via strategy flag.
11
+ *
12
+ * In non-interactive mode (strategy provided), returns deterministically:
13
+ * overwrite → "overwrite"
14
+ * keep → "keep"
15
+ * abort → "abort"
16
+ *
17
+ * In interactive mode (strategy undefined), prompts the user.
18
+ */
19
+ export async function resolveConflict(conflict, strategy) {
20
+ if (strategy) {
21
+ return strategy === "abort" ? "abort" : strategy;
22
+ }
23
+ return promptConflict(conflict);
24
+ }
25
+ async function promptConflict(conflict) {
26
+ const rl = readline.createInterface({
27
+ input: process.stdin,
28
+ output: process.stderr,
29
+ });
30
+ const direction = conflict.direction === "push"
31
+ ? "Remote has a newer version"
32
+ : "Local file has uncommitted edits";
33
+ console.error(`\n Conflict: ${conflict.path}`);
34
+ console.error(` ${direction}`);
35
+ if (conflict.localModified) {
36
+ console.error(` Local modified: ${conflict.localModified.toISOString()}`);
37
+ }
38
+ if (conflict.remoteModified) {
39
+ console.error(` Remote modified: ${conflict.remoteModified.toISOString()}`);
40
+ }
41
+ const options = conflict.direction === "push"
42
+ ? "[o]verwrite remote / [k]eep remote / [d]iff / [a]bort"
43
+ : "[o]verwrite local / [k]eep local / [d]iff / [s]kip";
44
+ const answer = await new Promise((resolve) => {
45
+ rl.question(` ${options}: `, (ans) => {
46
+ rl.close();
47
+ resolve(ans.trim().toLowerCase());
48
+ });
49
+ });
50
+ switch (answer) {
51
+ case "o":
52
+ case "overwrite":
53
+ return "overwrite";
54
+ case "k":
55
+ case "keep":
56
+ return "keep";
57
+ case "d":
58
+ case "diff":
59
+ return "diff";
60
+ case "s":
61
+ case "skip":
62
+ return "skip";
63
+ case "a":
64
+ case "abort":
65
+ return "abort";
66
+ default:
67
+ // Default to keep (safe option)
68
+ console.error(" Unrecognized choice, keeping current version.");
69
+ return "keep";
70
+ }
71
+ }
72
+ /**
73
+ * Show a simple diff between local and remote content.
74
+ * Returns the content strings for display.
75
+ */
76
+ export function showDiff(localPath, remoteContent) {
77
+ const localContent = fs.existsSync(localPath)
78
+ ? fs.readFileSync(localPath, "utf-8")
79
+ : "(file does not exist locally)";
80
+ const remoteStr = remoteContent.toString("utf-8");
81
+ console.error("\n--- LOCAL ---");
82
+ console.error(localContent.slice(0, 2000));
83
+ if (localContent.length > 2000)
84
+ console.error("... (truncated)");
85
+ console.error("\n--- REMOTE ---");
86
+ console.error(remoteStr.slice(0, 2000));
87
+ if (remoteStr.length > 2000)
88
+ console.error("... (truncated)");
89
+ console.error("");
90
+ }
91
+ //# sourceMappingURL=conflict.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conflict.js","sourceRoot":"","sources":["../../src/cli/conflict.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * hq-cloud CLI entry points.
3
+ *
4
+ * Registers `hq share`, `hq sync`, and membership commands.
5
+ * These are consumed by @indigoai-us/hq-cli or invoked directly.
6
+ */
7
+ export { share } from "./share.js";
8
+ export type { ShareOptions, ShareResult } from "./share.js";
9
+ export { sync } from "./sync.js";
10
+ export type { SyncOptions, SyncResult } from "./sync.js";
11
+ export { resolveConflict, showDiff } from "./conflict.js";
12
+ export type { ConflictStrategy, ConflictInfo, ConflictResolution } from "./conflict.js";
13
+ export { invite, listInvites, revokeInvite } from "./invite.js";
14
+ export type { InviteOptions, InviteResult, InviteListOptions, InviteRevokeOptions } from "./invite.js";
15
+ export { accept, parseToken } from "./accept.js";
16
+ export type { AcceptOptions, AcceptResult } from "./accept.js";
17
+ export { promote } from "./promote.js";
18
+ export type { PromoteOptions, PromoteResult } from "./promote.js";
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE5D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEzD,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC1D,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAGxF,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAChE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEvG,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACjD,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE/D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * hq-cloud CLI entry points.
3
+ *
4
+ * Registers `hq share`, `hq sync`, and membership commands.
5
+ * These are consumed by @indigoai-us/hq-cli or invoked directly.
6
+ */
7
+ export { share } from "./share.js";
8
+ export { sync } from "./sync.js";
9
+ export { resolveConflict, showDiff } from "./conflict.js";
10
+ // Membership commands (VLT-7)
11
+ export { invite, listInvites, revokeInvite } from "./invite.js";
12
+ export { accept, parseToken } from "./accept.js";
13
+ export { promote } from "./promote.js";
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGnC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAG1D,8BAA8B;AAC9B,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAGhE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGjD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * `hq invite` command — create pending membership + magic link (VLT-7 US-002).
3
+ *
4
+ * Thin UX layer over VaultClient.createInvite(). Handles arg parsing,
5
+ * validation (paths only with guest role), and formats the magic link output.
6
+ */
7
+ import type { VaultServiceConfig } from "../types.js";
8
+ import type { MembershipRole, Membership } from "../vault-client.js";
9
+ export interface InviteOptions {
10
+ /** Target — email address or person slug/uid */
11
+ target: string;
12
+ /** Role for the invitee (default: member) */
13
+ role?: MembershipRole;
14
+ /** Comma-separated allowed prefixes (only valid with role=guest) */
15
+ paths?: string;
16
+ /** Company slug or UID (defaults to active company) */
17
+ company?: string;
18
+ /** Vault service config */
19
+ vaultConfig: VaultServiceConfig;
20
+ /** Caller's person UID */
21
+ callerUid: string;
22
+ }
23
+ export interface InviteResult {
24
+ inviteToken: string;
25
+ magicLink: string;
26
+ membership: Membership;
27
+ }
28
+ export interface InviteListOptions {
29
+ company?: string;
30
+ vaultConfig: VaultServiceConfig;
31
+ callerUid: string;
32
+ }
33
+ export interface InviteRevokeOptions {
34
+ tokenOrKey: string;
35
+ /** Company slug or UID — required so the server can authorize the caller */
36
+ company: string;
37
+ vaultConfig: VaultServiceConfig;
38
+ }
39
+ /**
40
+ * Create a pending membership invite and return a magic link.
41
+ */
42
+ export declare function invite(options: InviteOptions): Promise<InviteResult>;
43
+ /**
44
+ * List pending invites for a company.
45
+ */
46
+ export declare function listInvites(options: InviteListOptions): Promise<Membership[]>;
47
+ /**
48
+ * Revoke a pending invite.
49
+ */
50
+ export declare function revokeInvite(options: InviteRevokeOptions): Promise<void>;
51
+ //# sourceMappingURL=invite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invite.d.ts","sourceRoot":"","sources":["../../src/cli/invite.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAQtD,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErE,MAAM,WAAW,aAAa;IAC5B,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,oEAAoE;IACpE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2BAA2B;IAC3B,WAAW,EAAE,kBAAkB,CAAC;IAChC,0BAA0B;IAC1B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,UAAU,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,kBAAkB,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,4EAA4E;IAC5E,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,kBAAkB,CAAC;CACjC;AAED;;GAEG;AACH,wBAAsB,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAiD1E;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAgBnF;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmB9E"}
@@ -0,0 +1,120 @@
1
+ /**
2
+ * `hq invite` command — create pending membership + magic link (VLT-7 US-002).
3
+ *
4
+ * Thin UX layer over VaultClient.createInvite(). Handles arg parsing,
5
+ * validation (paths only with guest role), and formats the magic link output.
6
+ */
7
+ import { VaultClient, VaultAuthError, VaultPermissionDeniedError, VaultNotFoundError, VaultConflictError, } from "../vault-client.js";
8
+ /**
9
+ * Create a pending membership invite and return a magic link.
10
+ */
11
+ export async function invite(options) {
12
+ const { target, role = "member", paths, company, vaultConfig, callerUid } = options;
13
+ // Validate: --paths only with --role guest
14
+ if (paths && role !== "guest") {
15
+ throw new Error("--paths is only valid with --role guest (allowedPrefixes are only meaningful for the guest role)");
16
+ }
17
+ const client = new VaultClient(vaultConfig);
18
+ // Resolve company UID
19
+ const companyUid = await resolveCompanyUid(client, company);
20
+ // Parse paths
21
+ const allowedPrefixes = paths
22
+ ? paths.split(",").map((p) => p.trim()).filter(Boolean)
23
+ : undefined;
24
+ // Determine if target is email or person identifier
25
+ const isEmail = target.includes("@");
26
+ try {
27
+ const result = await client.createInvite({
28
+ ...(isEmail ? { inviteeEmail: target } : { personUid: target }),
29
+ companyUid,
30
+ role,
31
+ allowedPrefixes,
32
+ invitedBy: callerUid,
33
+ });
34
+ const magicLink = `hq://accept/${result.inviteToken}`;
35
+ return {
36
+ inviteToken: result.inviteToken,
37
+ magicLink,
38
+ membership: result.membership,
39
+ };
40
+ }
41
+ catch (err) {
42
+ if (err instanceof VaultAuthError) {
43
+ throw new Error("Authentication failed — run `hq auth` to refresh your session");
44
+ }
45
+ if (err instanceof VaultPermissionDeniedError) {
46
+ throw new Error("Permission denied — only admins and owners can invite members");
47
+ }
48
+ if (err instanceof VaultConflictError) {
49
+ throw new Error("This person already has a membership or pending invite for this company");
50
+ }
51
+ throw err;
52
+ }
53
+ }
54
+ /**
55
+ * List pending invites for a company.
56
+ */
57
+ export async function listInvites(options) {
58
+ const { company, vaultConfig } = options;
59
+ const client = new VaultClient(vaultConfig);
60
+ const companyUid = await resolveCompanyUid(client, company);
61
+ try {
62
+ return await client.listPendingInvites(companyUid);
63
+ }
64
+ catch (err) {
65
+ if (err instanceof VaultAuthError) {
66
+ throw new Error("Authentication failed — run `hq auth` to refresh your session");
67
+ }
68
+ if (err instanceof VaultPermissionDeniedError) {
69
+ throw new Error("Permission denied — only admins and owners can list invites");
70
+ }
71
+ throw err;
72
+ }
73
+ }
74
+ /**
75
+ * Revoke a pending invite.
76
+ */
77
+ export async function revokeInvite(options) {
78
+ const { tokenOrKey, company, vaultConfig } = options;
79
+ const client = new VaultClient(vaultConfig);
80
+ const companyUid = await resolveCompanyUid(client, company);
81
+ try {
82
+ await client.revokeMembership(tokenOrKey, companyUid);
83
+ }
84
+ catch (err) {
85
+ if (err instanceof VaultAuthError) {
86
+ throw new Error("Authentication failed — run `hq auth` to refresh your session");
87
+ }
88
+ if (err instanceof VaultPermissionDeniedError) {
89
+ throw new Error("Permission denied — only admins and owners can revoke invites");
90
+ }
91
+ if (err instanceof VaultNotFoundError) {
92
+ throw new Error("Invite not found — it may have already been accepted or revoked");
93
+ }
94
+ throw err;
95
+ }
96
+ }
97
+ // ---------------------------------------------------------------------------
98
+ // Helpers
99
+ // ---------------------------------------------------------------------------
100
+ async function resolveCompanyUid(client, companyRef) {
101
+ if (!companyRef) {
102
+ throw new Error("No company specified. Use --company <slug> or set up .hq/config.json");
103
+ }
104
+ // If already a UID, return it
105
+ if (companyRef.startsWith("cmp_")) {
106
+ return companyRef;
107
+ }
108
+ // Resolve slug → UID via entity registry
109
+ try {
110
+ const entity = await client.entity.findBySlug("company", companyRef);
111
+ return entity.uid;
112
+ }
113
+ catch (err) {
114
+ if (err instanceof VaultNotFoundError) {
115
+ throw new Error(`Company "${companyRef}" not found in the vault registry`);
116
+ }
117
+ throw err;
118
+ }
119
+ }
120
+ //# sourceMappingURL=invite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invite.js","sourceRoot":"","sources":["../../src/cli/invite.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * invite CLI command tests (VLT-7 US-002).
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=invite.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"invite.test.d.ts","sourceRoot":"","sources":["../../src/cli/invite.test.ts"],"names":[],"mappings":"AAAA;;GAEG"}