@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
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Daemon worker — runs as a detached child process
3
+ * Watches HQ directory and syncs changes to S3
4
+ */
5
+ import { SyncWatcher } from "./watcher.js";
6
+ const hqRoot = process.argv[2];
7
+ if (!hqRoot) {
8
+ console.error("Usage: daemon-worker <hq-root>");
9
+ process.exit(1);
10
+ }
11
+ const watcher = new SyncWatcher(hqRoot);
12
+ watcher.start();
13
+ // Handle graceful shutdown
14
+ process.on("SIGTERM", () => {
15
+ watcher.stop();
16
+ process.exit(0);
17
+ });
18
+ process.on("SIGINT", () => {
19
+ watcher.stop();
20
+ process.exit(0);
21
+ });
22
+ // Keep process alive
23
+ setInterval(() => {
24
+ // Heartbeat — could add remote change polling here
25
+ }, 30_000);
26
+ //# sourceMappingURL=daemon-worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon-worker.js","sourceRoot":"","sources":["../src/daemon-worker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAE/B,IAAI,CAAC,MAAM,EAAE,CAAC;IACZ,OAAO,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;IAChD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC;AACxC,OAAO,CAAC,KAAK,EAAE,CAAC;AAEhB,2BAA2B;AAC3B,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;IACzB,OAAO,CAAC,IAAI,EAAE,CAAC;IACf,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;IACxB,OAAO,CAAC,IAAI,EAAE,CAAC;IACf,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,qBAAqB;AACrB,WAAW,CAAC,GAAG,EAAE;IACf,mDAAmD;AACrD,CAAC,EAAE,MAAM,CAAC,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Background sync daemon management
3
+ * Manages a child process that runs the file watcher
4
+ */
5
+ import type { DaemonState } from "./types.js";
6
+ export declare function isDaemonRunning(hqRoot: string): boolean;
7
+ export declare function startDaemon(hqRoot: string): void;
8
+ export declare function stopDaemon(hqRoot: string): void;
9
+ export declare function getDaemonState(hqRoot: string): DaemonState | null;
10
+ //# sourceMappingURL=daemon.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAa9C,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAcvD;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CA2BhD;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAkB/C;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CASjE"}
package/dist/daemon.js ADDED
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Background sync daemon management
3
+ * Manages a child process that runs the file watcher
4
+ */
5
+ import * as fs from "fs";
6
+ import * as path from "path";
7
+ import { fork } from "child_process";
8
+ import { fileURLToPath } from "url";
9
+ const __filename = fileURLToPath(import.meta.url);
10
+ const __dirname = path.dirname(__filename);
11
+ function getPidFile(hqRoot) {
12
+ return path.join(hqRoot, ".hq-sync.pid");
13
+ }
14
+ function getStateFile(hqRoot) {
15
+ return path.join(hqRoot, ".hq-sync-daemon.json");
16
+ }
17
+ export function isDaemonRunning(hqRoot) {
18
+ const pidFile = getPidFile(hqRoot);
19
+ if (!fs.existsSync(pidFile))
20
+ return false;
21
+ const pid = parseInt(fs.readFileSync(pidFile, "utf-8").trim(), 10);
22
+ try {
23
+ // signal 0 tests if process exists without killing it
24
+ process.kill(pid, 0);
25
+ return true;
26
+ }
27
+ catch {
28
+ // Process not running, clean up stale PID file
29
+ fs.unlinkSync(pidFile);
30
+ return false;
31
+ }
32
+ }
33
+ export function startDaemon(hqRoot) {
34
+ if (isDaemonRunning(hqRoot)) {
35
+ console.log(" Sync daemon is already running.");
36
+ return;
37
+ }
38
+ const workerScript = path.join(__dirname, "daemon-worker.js");
39
+ const child = fork(workerScript, [hqRoot], {
40
+ detached: true,
41
+ stdio: "ignore",
42
+ });
43
+ child.unref();
44
+ if (child.pid) {
45
+ // Write PID file
46
+ fs.writeFileSync(getPidFile(hqRoot), String(child.pid));
47
+ // Write state
48
+ const state = {
49
+ pid: child.pid,
50
+ startedAt: new Date().toISOString(),
51
+ hqRoot,
52
+ };
53
+ fs.writeFileSync(getStateFile(hqRoot), JSON.stringify(state, null, 2));
54
+ }
55
+ }
56
+ export function stopDaemon(hqRoot) {
57
+ const pidFile = getPidFile(hqRoot);
58
+ if (!fs.existsSync(pidFile)) {
59
+ console.log(" No sync daemon running.");
60
+ return;
61
+ }
62
+ const pid = parseInt(fs.readFileSync(pidFile, "utf-8").trim(), 10);
63
+ try {
64
+ process.kill(pid, "SIGTERM");
65
+ }
66
+ catch {
67
+ // Already dead
68
+ }
69
+ // Clean up files
70
+ if (fs.existsSync(pidFile))
71
+ fs.unlinkSync(pidFile);
72
+ const stateFile = getStateFile(hqRoot);
73
+ if (fs.existsSync(stateFile))
74
+ fs.unlinkSync(stateFile);
75
+ }
76
+ export function getDaemonState(hqRoot) {
77
+ const stateFile = getStateFile(hqRoot);
78
+ if (!fs.existsSync(stateFile))
79
+ return null;
80
+ try {
81
+ const content = fs.readFileSync(stateFile, "utf-8");
82
+ return JSON.parse(content);
83
+ }
84
+ catch {
85
+ return null;
86
+ }
87
+ }
88
+ //# sourceMappingURL=daemon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Ignore file parser for .hqsyncignore
3
+ * Uses gitignore-compatible syntax
4
+ */
5
+ export declare function createIgnoreFilter(hqRoot: string): (filePath: string) => boolean;
6
+ /**
7
+ * Check if a file exceeds the max sync size (50MB default)
8
+ */
9
+ export declare function isWithinSizeLimit(filePath: string, maxBytes?: number): boolean;
10
+ //# sourceMappingURL=ignore.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ignore.d.ts","sourceRoot":"","sources":["../src/ignore.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAwBH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAkBhF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,QAAQ,SAAmB,GAC1B,OAAO,CAOT"}
package/dist/ignore.js ADDED
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Ignore file parser for .hqsyncignore
3
+ * Uses gitignore-compatible syntax
4
+ */
5
+ import * as fs from "fs";
6
+ import * as path from "path";
7
+ import ignore from "ignore";
8
+ // Default patterns that should never sync
9
+ const DEFAULT_IGNORES = [
10
+ ".git/",
11
+ ".git",
12
+ "node_modules/",
13
+ "dist/",
14
+ ".DS_Store",
15
+ "Thumbs.db",
16
+ "*.pid",
17
+ ".hq-sync.pid",
18
+ ".hq-sync-journal.json",
19
+ ".hq-sync-state.json",
20
+ "modules.lock",
21
+ "repos/",
22
+ ".env",
23
+ ".env.*",
24
+ ];
25
+ export function createIgnoreFilter(hqRoot) {
26
+ const ig = ignore();
27
+ // Add defaults
28
+ ig.add(DEFAULT_IGNORES);
29
+ // Read .hqsyncignore if it exists
30
+ const ignorePath = path.join(hqRoot, ".hqsyncignore");
31
+ if (fs.existsSync(ignorePath)) {
32
+ const content = fs.readFileSync(ignorePath, "utf-8");
33
+ ig.add(content);
34
+ }
35
+ return (filePath) => {
36
+ const relative = path.relative(hqRoot, filePath);
37
+ if (!relative || relative.startsWith(".."))
38
+ return true; // outside HQ root
39
+ return !ig.ignores(relative);
40
+ };
41
+ }
42
+ /**
43
+ * Check if a file exceeds the max sync size (50MB default)
44
+ */
45
+ export function isWithinSizeLimit(filePath, maxBytes = 50 * 1024 * 1024) {
46
+ try {
47
+ const stat = fs.statSync(filePath);
48
+ return stat.size <= maxBytes;
49
+ }
50
+ catch {
51
+ return false;
52
+ }
53
+ }
54
+ //# sourceMappingURL=ignore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ignore.js","sourceRoot":"","sources":["../src/ignore.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,0CAA0C;AAC1C,MAAM,eAAe,GAAG;IACtB,OAAO;IACP,MAAM;IACN,eAAe;IACf,OAAO;IACP,WAAW;IACX,WAAW;IACX,OAAO;IACP,cAAc;IACd,uBAAuB;IACvB,qBAAqB;IACrB,cAAc;IACd,QAAQ;IACR,MAAM;IACN,QAAQ;CACT,CAAC;AAEF,MAAM,UAAU,kBAAkB,CAAC,MAAc;IAC/C,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;IAEpB,eAAe;IACf,EAAE,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IAExB,kCAAkC;IAClC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACtD,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACrD,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,QAAgB,EAAW,EAAE;QACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QACjD,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC,CAAC,kBAAkB;QAC3E,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAC/B,QAAgB,EAChB,QAAQ,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI;IAE3B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACnC,OAAO,IAAI,CAAC,IAAI,IAAI,QAAQ,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @indigoai-us/hq-cloud — public API
3
+ * Used by @indigoai-us/hq-cli to manage cloud sync
4
+ */
5
+ import type { SyncStatus, PushResult, PullResult } from "./types.js";
6
+ export type { SyncStatus, PushResult, PullResult } from "./types.js";
7
+ export { browserLogin, refreshTokens, getValidAccessToken, loadCachedTokens, saveCachedTokens, clearCachedTokens, isExpiring, CognitoAuthError, } from "./cognito-auth.js";
8
+ export type { CognitoAuthConfig, CognitoTokens } from "./cognito-auth.js";
9
+ /**
10
+ * Initialize cloud sync — authenticate and provision bucket
11
+ */
12
+ export declare function initSync(hqRoot: string): Promise<void>;
13
+ /**
14
+ * Start the background sync daemon
15
+ */
16
+ export declare function startDaemon(hqRoot: string): Promise<void>;
17
+ /**
18
+ * Stop the background sync daemon
19
+ */
20
+ export declare function stopDaemon(hqRoot: string): Promise<void>;
21
+ /**
22
+ * Get current sync status
23
+ */
24
+ export declare function getStatus(hqRoot: string): Promise<SyncStatus>;
25
+ /**
26
+ * Force push all local files to S3
27
+ */
28
+ export declare function pushAll(hqRoot: string): Promise<PushResult>;
29
+ /**
30
+ * Force pull all remote files to local
31
+ */
32
+ export declare function pullAll(hqRoot: string): Promise<PullResult>;
33
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAaH,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAErE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAIrE,OAAO,EACL,YAAY,EACZ,aAAa,EACb,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,UAAU,EACV,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAE1E;;GAEG;AACH,wBAAsB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAa5D;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAK/D;AAED;;GAEG;AACH,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE9D;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAiBnE;AAED;;GAEG;AACH,wBAAsB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CA4BjE;AAED;;GAEG;AACH,wBAAsB,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAyBjE"}
package/dist/index.js ADDED
@@ -0,0 +1,138 @@
1
+ /**
2
+ * @indigoai-us/hq-cloud — public API
3
+ * Used by @indigoai-us/hq-cli to manage cloud sync
4
+ */
5
+ import * as fs from "fs";
6
+ import * as path from "path";
7
+ import { authenticate, hasCredentials, readCredentials } from "./auth.js";
8
+ import { startDaemon as _startDaemon, stopDaemon as _stopDaemon, isDaemonRunning, } from "./daemon.js";
9
+ import { readJournal, writeJournal, hashFile, updateEntry } from "./journal.js";
10
+ import { uploadFile, downloadFile, listRemoteFiles } from "./s3.js";
11
+ import { createIgnoreFilter, isWithinSizeLimit } from "./ignore.js";
12
+ // Cognito identity helpers — used by `hq auth refresh` and any consumer
13
+ // that needs a valid HQ access token (deploy skill, onboarding, etc.).
14
+ export { browserLogin, refreshTokens, getValidAccessToken, loadCachedTokens, saveCachedTokens, clearCachedTokens, isExpiring, CognitoAuthError, } from "./cognito-auth.js";
15
+ /**
16
+ * Initialize cloud sync — authenticate and provision bucket
17
+ */
18
+ export async function initSync(hqRoot) {
19
+ if (hasCredentials()) {
20
+ console.log(" Already authenticated. Use 'hq sync start' to begin syncing.");
21
+ return;
22
+ }
23
+ console.log(" Setting up IndigoAI cloud sync...");
24
+ const creds = await authenticate();
25
+ console.log(` ✓ Authenticated as ${creds.userId}`);
26
+ console.log(` ✓ Bucket: ${creds.bucket}`);
27
+ console.log(` ✓ Region: ${creds.region}`);
28
+ console.log();
29
+ console.log(" Run 'hq sync start' to begin syncing.");
30
+ }
31
+ /**
32
+ * Start the background sync daemon
33
+ */
34
+ export async function startDaemon(hqRoot) {
35
+ if (!hasCredentials()) {
36
+ throw new Error("Not authenticated. Run 'hq sync init' first.");
37
+ }
38
+ _startDaemon(hqRoot);
39
+ }
40
+ /**
41
+ * Stop the background sync daemon
42
+ */
43
+ export async function stopDaemon(hqRoot) {
44
+ _stopDaemon(hqRoot);
45
+ }
46
+ /**
47
+ * Get current sync status
48
+ */
49
+ export async function getStatus(hqRoot) {
50
+ const journal = readJournal(hqRoot);
51
+ const creds = readCredentials();
52
+ const running = isDaemonRunning(hqRoot);
53
+ const errors = [];
54
+ if (!creds) {
55
+ errors.push("Not authenticated — run 'hq sync init'");
56
+ }
57
+ return {
58
+ running,
59
+ lastSync: journal.lastSync || null,
60
+ fileCount: Object.keys(journal.files).length,
61
+ bucket: creds?.bucket || null,
62
+ errors,
63
+ };
64
+ }
65
+ /**
66
+ * Force push all local files to S3
67
+ */
68
+ export async function pushAll(hqRoot) {
69
+ const shouldSync = createIgnoreFilter(hqRoot);
70
+ const journal = readJournal(hqRoot);
71
+ let filesUploaded = 0;
72
+ let bytesUploaded = 0;
73
+ const files = walkDir(hqRoot, hqRoot, shouldSync);
74
+ for (const { absolutePath, relativePath } of files) {
75
+ if (!isWithinSizeLimit(absolutePath))
76
+ continue;
77
+ try {
78
+ const hash = hashFile(absolutePath);
79
+ const stat = fs.statSync(absolutePath);
80
+ await uploadFile(absolutePath, relativePath);
81
+ updateEntry(journal, relativePath, hash, stat.size, "up");
82
+ filesUploaded++;
83
+ bytesUploaded += stat.size;
84
+ }
85
+ catch (err) {
86
+ console.error(` Failed: ${relativePath} — ${err instanceof Error ? err.message : err}`);
87
+ }
88
+ }
89
+ writeJournal(hqRoot, journal);
90
+ return { filesUploaded, bytesUploaded };
91
+ }
92
+ /**
93
+ * Force pull all remote files to local
94
+ */
95
+ export async function pullAll(hqRoot) {
96
+ const journal = readJournal(hqRoot);
97
+ let filesDownloaded = 0;
98
+ let bytesDownloaded = 0;
99
+ const remoteFiles = await listRemoteFiles();
100
+ for (const file of remoteFiles) {
101
+ try {
102
+ const localPath = path.join(hqRoot, file.relativePath);
103
+ await downloadFile(file.relativePath, localPath);
104
+ const hash = hashFile(localPath);
105
+ updateEntry(journal, file.relativePath, hash, file.size, "down");
106
+ filesDownloaded++;
107
+ bytesDownloaded += file.size;
108
+ }
109
+ catch (err) {
110
+ console.error(` Failed: ${file.relativePath} — ${err instanceof Error ? err.message : err}`);
111
+ }
112
+ }
113
+ writeJournal(hqRoot, journal);
114
+ return { filesDownloaded, bytesDownloaded };
115
+ }
116
+ // Helper: recursively walk a directory
117
+ function walkDir(dir, root, filter) {
118
+ const results = [];
119
+ if (!fs.existsSync(dir))
120
+ return results;
121
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
122
+ for (const entry of entries) {
123
+ const absolutePath = path.join(dir, entry.name);
124
+ if (!filter(absolutePath))
125
+ continue;
126
+ if (entry.isDirectory()) {
127
+ results.push(...walkDir(absolutePath, root, filter));
128
+ }
129
+ else if (entry.isFile()) {
130
+ results.push({
131
+ absolutePath,
132
+ relativePath: path.relative(root, absolutePath),
133
+ });
134
+ }
135
+ }
136
+ return results;
137
+ }
138
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Sync journal — tracks file state for conflict detection
3
+ */
4
+ import type { SyncJournal, JournalEntry } from "./types.js";
5
+ export declare function getJournalPath(hqRoot: string): string;
6
+ export declare function readJournal(hqRoot: string): SyncJournal;
7
+ export declare function writeJournal(hqRoot: string, journal: SyncJournal): void;
8
+ export declare function hashFile(filePath: string): string;
9
+ export declare function updateEntry(journal: SyncJournal, relativePath: string, hash: string, size: number, direction: "up" | "down"): void;
10
+ export declare function getEntry(journal: SyncJournal, relativePath: string): JournalEntry | undefined;
11
+ export declare function removeEntry(journal: SyncJournal, relativePath: string): void;
12
+ //# sourceMappingURL=journal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"journal.d.ts","sourceRoot":"","sources":["../src/journal.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAI5D,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,CAOvD;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI,CAGvE;AAED,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGjD;AAED,wBAAgB,WAAW,CACzB,OAAO,EAAE,WAAW,EACpB,YAAY,EAAE,MAAM,EACpB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,IAAI,GAAG,MAAM,GACvB,IAAI,CAQN;AAED,wBAAgB,QAAQ,CACtB,OAAO,EAAE,WAAW,EACpB,YAAY,EAAE,MAAM,GACnB,YAAY,GAAG,SAAS,CAE1B;AAED,wBAAgB,WAAW,CACzB,OAAO,EAAE,WAAW,EACpB,YAAY,EAAE,MAAM,GACnB,IAAI,CAEN"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Sync journal — tracks file state for conflict detection
3
+ */
4
+ import * as fs from "fs";
5
+ import * as path from "path";
6
+ import * as crypto from "crypto";
7
+ const JOURNAL_FILE = ".hq-sync-journal.json";
8
+ export function getJournalPath(hqRoot) {
9
+ return path.join(hqRoot, JOURNAL_FILE);
10
+ }
11
+ export function readJournal(hqRoot) {
12
+ const journalPath = getJournalPath(hqRoot);
13
+ if (fs.existsSync(journalPath)) {
14
+ const content = fs.readFileSync(journalPath, "utf-8");
15
+ return JSON.parse(content);
16
+ }
17
+ return { version: "1", lastSync: "", files: {} };
18
+ }
19
+ export function writeJournal(hqRoot, journal) {
20
+ const journalPath = getJournalPath(hqRoot);
21
+ fs.writeFileSync(journalPath, JSON.stringify(journal, null, 2));
22
+ }
23
+ export function hashFile(filePath) {
24
+ const content = fs.readFileSync(filePath);
25
+ return crypto.createHash("sha256").update(content).digest("hex");
26
+ }
27
+ export function updateEntry(journal, relativePath, hash, size, direction) {
28
+ journal.files[relativePath] = {
29
+ hash,
30
+ size,
31
+ syncedAt: new Date().toISOString(),
32
+ direction,
33
+ };
34
+ journal.lastSync = new Date().toISOString();
35
+ }
36
+ export function getEntry(journal, relativePath) {
37
+ return journal.files[relativePath];
38
+ }
39
+ export function removeEntry(journal, relativePath) {
40
+ delete journal.files[relativePath];
41
+ }
42
+ //# sourceMappingURL=journal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"journal.js","sourceRoot":"","sources":["../src/journal.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AAGjC,MAAM,YAAY,GAAG,uBAAuB,CAAC;AAE7C,MAAM,UAAU,cAAc,CAAC,MAAc;IAC3C,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,MAAc;IACxC,MAAM,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IAC3C,IAAI,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACtD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAgB,CAAC;IAC5C,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAc,EAAE,OAAoB;IAC/D,MAAM,WAAW,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IAC3C,EAAE,CAAC,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,QAAgB;IACvC,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC1C,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,WAAW,CACzB,OAAoB,EACpB,YAAoB,EACpB,IAAY,EACZ,IAAY,EACZ,SAAwB;IAExB,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG;QAC5B,IAAI;QACJ,IAAI;QACJ,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAClC,SAAS;KACV,CAAC;IACF,OAAO,CAAC,QAAQ,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,QAAQ,CACtB,OAAoB,EACpB,YAAoB;IAEpB,OAAO,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,WAAW,CACzB,OAAoB,EACpB,YAAoB;IAEpB,OAAO,OAAO,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;AACrC,CAAC"}
package/dist/s3.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ /**
2
+ * S3 operations — upload, download, list, delete
3
+ */
4
+ export declare function uploadFile(localPath: string, relativePath: string): Promise<void>;
5
+ export declare function downloadFile(relativePath: string, localPath: string): Promise<void>;
6
+ export interface RemoteFile {
7
+ key: string;
8
+ relativePath: string;
9
+ size: number;
10
+ lastModified: Date;
11
+ etag: string;
12
+ }
13
+ export declare function listRemoteFiles(): Promise<RemoteFile[]>;
14
+ export declare function deleteRemoteFile(relativePath: string): Promise<void>;
15
+ //# sourceMappingURL=s3.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s3.d.ts","sourceRoot":"","sources":["../src/s3.ts"],"names":[],"mappings":"AAAA;;GAEG;AAqDH,wBAAsB,UAAU,CAC9B,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAaf;AAED,wBAAsB,YAAY,CAChC,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CA0Bf;AAED,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,IAAI,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC,CAgC7D;AAED,wBAAsB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAU1E"}
package/dist/s3.js ADDED
@@ -0,0 +1,129 @@
1
+ /**
2
+ * S3 operations — upload, download, list, delete
3
+ */
4
+ import * as fs from "fs";
5
+ import * as path from "path";
6
+ import { S3Client, PutObjectCommand, GetObjectCommand, ListObjectsV2Command, DeleteObjectCommand, } from "@aws-sdk/client-s3";
7
+ import { readCredentials, refreshAwsCredentials } from "./auth.js";
8
+ let s3Client = null;
9
+ function getConfig(creds) {
10
+ const prefix = creds.teamId
11
+ ? `teams/${creds.teamId}/users/${creds.userId}/hq/`
12
+ : `users/${creds.userId}/hq/`;
13
+ return {
14
+ bucket: creds.bucket,
15
+ region: creds.region,
16
+ userId: creds.userId,
17
+ prefix,
18
+ };
19
+ }
20
+ async function getClient() {
21
+ let creds = readCredentials();
22
+ if (!creds) {
23
+ throw new Error("Not authenticated. Run 'hq sync init' first.");
24
+ }
25
+ // Refresh if expired or missing access key
26
+ if (!creds.accessKeyId || (creds.expiration && new Date(creds.expiration) < new Date())) {
27
+ creds = await refreshAwsCredentials(creds);
28
+ }
29
+ if (!s3Client) {
30
+ s3Client = new S3Client({
31
+ region: creds.region,
32
+ credentials: {
33
+ accessKeyId: creds.accessKeyId,
34
+ secretAccessKey: creds.secretAccessKey,
35
+ sessionToken: creds.sessionToken,
36
+ },
37
+ });
38
+ }
39
+ return { client: s3Client, config: getConfig(creds) };
40
+ }
41
+ export async function uploadFile(localPath, relativePath) {
42
+ const { client, config } = await getClient();
43
+ const key = `${config.prefix}${relativePath}`;
44
+ const body = fs.readFileSync(localPath);
45
+ await client.send(new PutObjectCommand({
46
+ Bucket: config.bucket,
47
+ Key: key,
48
+ Body: body,
49
+ ContentType: getMimeType(relativePath),
50
+ }));
51
+ }
52
+ export async function downloadFile(relativePath, localPath) {
53
+ const { client, config } = await getClient();
54
+ const key = `${config.prefix}${relativePath}`;
55
+ const response = await client.send(new GetObjectCommand({
56
+ Bucket: config.bucket,
57
+ Key: key,
58
+ }));
59
+ if (!response.Body) {
60
+ throw new Error(`Empty response for ${key}`);
61
+ }
62
+ const dir = path.dirname(localPath);
63
+ if (!fs.existsSync(dir)) {
64
+ fs.mkdirSync(dir, { recursive: true });
65
+ }
66
+ const chunks = [];
67
+ const stream = response.Body;
68
+ for await (const chunk of stream) {
69
+ chunks.push(Buffer.from(chunk));
70
+ }
71
+ fs.writeFileSync(localPath, Buffer.concat(chunks));
72
+ }
73
+ export async function listRemoteFiles() {
74
+ const { client, config } = await getClient();
75
+ const files = [];
76
+ let continuationToken;
77
+ do {
78
+ const response = await client.send(new ListObjectsV2Command({
79
+ Bucket: config.bucket,
80
+ Prefix: config.prefix,
81
+ ContinuationToken: continuationToken,
82
+ }));
83
+ for (const obj of response.Contents || []) {
84
+ if (!obj.Key || !obj.Size)
85
+ continue;
86
+ const relativePath = obj.Key.replace(config.prefix, "");
87
+ if (!relativePath)
88
+ continue;
89
+ files.push({
90
+ key: obj.Key,
91
+ relativePath,
92
+ size: obj.Size,
93
+ lastModified: obj.LastModified || new Date(),
94
+ etag: obj.ETag || "",
95
+ });
96
+ }
97
+ continuationToken = response.NextContinuationToken;
98
+ } while (continuationToken);
99
+ return files;
100
+ }
101
+ export async function deleteRemoteFile(relativePath) {
102
+ const { client, config } = await getClient();
103
+ const key = `${config.prefix}${relativePath}`;
104
+ await client.send(new DeleteObjectCommand({
105
+ Bucket: config.bucket,
106
+ Key: key,
107
+ }));
108
+ }
109
+ function getMimeType(filePath) {
110
+ const ext = path.extname(filePath).toLowerCase();
111
+ const mimeTypes = {
112
+ ".md": "text/markdown",
113
+ ".json": "application/json",
114
+ ".yaml": "text/yaml",
115
+ ".yml": "text/yaml",
116
+ ".ts": "text/typescript",
117
+ ".js": "text/javascript",
118
+ ".txt": "text/plain",
119
+ ".html": "text/html",
120
+ ".css": "text/css",
121
+ ".png": "image/png",
122
+ ".jpg": "image/jpeg",
123
+ ".jpeg": "image/jpeg",
124
+ ".svg": "image/svg+xml",
125
+ ".pdf": "application/pdf",
126
+ };
127
+ return mimeTypes[ext] || "application/octet-stream";
128
+ }
129
+ //# sourceMappingURL=s3.js.map
package/dist/s3.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"s3.js","sourceRoot":"","sources":["../src/s3.ts"],"names":[],"mappings":"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"}