haansi 0.1.29 → 0.1.31
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/dist/haansi.js +1274 -208
- package/package.json +1 -1
package/dist/haansi.js
CHANGED
|
@@ -34,12 +34,68 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
34
34
|
));
|
|
35
35
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
36
36
|
|
|
37
|
+
// ../../packages/@company/config/src/service-urls.ts
|
|
38
|
+
var SERVICE_URL_DEFAULTS, HAANSI_API_V1_BASE_URL;
|
|
39
|
+
var init_service_urls = __esm({
|
|
40
|
+
"../../packages/@company/config/src/service-urls.ts"() {
|
|
41
|
+
SERVICE_URL_DEFAULTS = Object.freeze({
|
|
42
|
+
haansiApiBaseUrl: "https://api.haansi.co",
|
|
43
|
+
localApiBaseUrl: "http://localhost:3000",
|
|
44
|
+
localWebAppUrl: "http://localhost:3001",
|
|
45
|
+
localDeliveryServiceUrl: "http://localhost:3200",
|
|
46
|
+
platformKnowledgeMcpUrl: "http://localhost:3300/mcp",
|
|
47
|
+
sessionSolutionsMcpUrl: "http://localhost:3301/mcp",
|
|
48
|
+
codeContextMcpUrl: "http://localhost:3302/mcp"
|
|
49
|
+
});
|
|
50
|
+
HAANSI_API_V1_BASE_URL = `${SERVICE_URL_DEFAULTS.haansiApiBaseUrl}/api/v1`;
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// src/lib/paths.ts
|
|
55
|
+
function apiUrl() {
|
|
56
|
+
return process.env.HAANSI_API_URL ?? DEFAULT_API_URL;
|
|
57
|
+
}
|
|
58
|
+
function resolveToken() {
|
|
59
|
+
if (process.env.HAANSI_TOKEN) return process.env.HAANSI_TOKEN;
|
|
60
|
+
if ((0, import_node_fs.existsSync)(CREDENTIALS_FILE)) {
|
|
61
|
+
try {
|
|
62
|
+
const creds = JSON.parse((0, import_node_fs.readFileSync)(CREDENTIALS_FILE, "utf-8"));
|
|
63
|
+
if (typeof creds.token === "string" && creds.token) return creds.token;
|
|
64
|
+
} catch {
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
function resolveHaansiBin() {
|
|
70
|
+
try {
|
|
71
|
+
const binPath = (0, import_node_child_process.execSync)("which haansi", { encoding: "utf-8" }).trim();
|
|
72
|
+
if (binPath) return binPath;
|
|
73
|
+
} catch {
|
|
74
|
+
}
|
|
75
|
+
return "haansi";
|
|
76
|
+
}
|
|
77
|
+
var import_node_fs, import_node_path, import_node_os, import_node_child_process, DEFAULT_API_URL, HAANSI_DIR, CREDENTIALS_FILE, CONFIG_FILE;
|
|
78
|
+
var init_paths = __esm({
|
|
79
|
+
"src/lib/paths.ts"() {
|
|
80
|
+
"use strict";
|
|
81
|
+
import_node_fs = require("node:fs");
|
|
82
|
+
import_node_path = require("node:path");
|
|
83
|
+
import_node_os = require("node:os");
|
|
84
|
+
import_node_child_process = require("node:child_process");
|
|
85
|
+
init_service_urls();
|
|
86
|
+
DEFAULT_API_URL = SERVICE_URL_DEFAULTS.haansiApiBaseUrl;
|
|
87
|
+
HAANSI_DIR = (0, import_node_path.join)((0, import_node_os.homedir)(), ".haansi");
|
|
88
|
+
CREDENTIALS_FILE = (0, import_node_path.join)(HAANSI_DIR, "credentials.json");
|
|
89
|
+
CONFIG_FILE = (0, import_node_path.join)(HAANSI_DIR, "config.json");
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
|
|
37
93
|
// package.json
|
|
38
94
|
var require_package = __commonJS({
|
|
39
95
|
"package.json"(exports2, module2) {
|
|
40
96
|
module2.exports = {
|
|
41
97
|
name: "haansi",
|
|
42
|
-
version: "0.1.
|
|
98
|
+
version: "0.1.31",
|
|
43
99
|
description: "Haansi CLI - Session collector and MCP server for Claude Code & OpenAI Codex",
|
|
44
100
|
bin: {
|
|
45
101
|
haansi: "./dist/haansi.js"
|
|
@@ -70,9 +126,9 @@ __export(auth_login_exports, {
|
|
|
70
126
|
authLogin: () => authLogin
|
|
71
127
|
});
|
|
72
128
|
function openBrowser(url2) {
|
|
73
|
-
const cmd = (0,
|
|
129
|
+
const cmd = (0, import_node_os2.platform)() === "darwin" ? "open" : (0, import_node_os2.platform)() === "win32" ? "start" : "xdg-open";
|
|
74
130
|
try {
|
|
75
|
-
(0,
|
|
131
|
+
(0, import_node_child_process2.exec)(`${cmd} ${JSON.stringify(url2)}`);
|
|
76
132
|
return true;
|
|
77
133
|
} catch {
|
|
78
134
|
return false;
|
|
@@ -82,7 +138,7 @@ function sleep(ms) {
|
|
|
82
138
|
return new Promise((resolve4) => setTimeout(resolve4, ms));
|
|
83
139
|
}
|
|
84
140
|
async function authLogin() {
|
|
85
|
-
const apiUrl2 =
|
|
141
|
+
const apiUrl2 = apiUrl();
|
|
86
142
|
console.log("Haansi CLI \u2014 Browser Login\n");
|
|
87
143
|
const initiateRes = await fetch(`${apiUrl2}/api/v1/auth/extension/initiate`, {
|
|
88
144
|
method: "POST",
|
|
@@ -156,9 +212,9 @@ If the browser didn't open, visit this URL:
|
|
|
156
212
|
);
|
|
157
213
|
}
|
|
158
214
|
const { token: hskToken } = await tokenRes.json();
|
|
159
|
-
(0,
|
|
160
|
-
(0,
|
|
161
|
-
|
|
215
|
+
(0, import_node_fs2.mkdirSync)(HAANSI_DIR2, { recursive: true });
|
|
216
|
+
(0, import_node_fs2.writeFileSync)(
|
|
217
|
+
CREDENTIALS_FILE2,
|
|
162
218
|
JSON.stringify({ token: hskToken }, null, 2),
|
|
163
219
|
{
|
|
164
220
|
encoding: "utf-8",
|
|
@@ -167,22 +223,22 @@ If the browser didn't open, visit this URL:
|
|
|
167
223
|
);
|
|
168
224
|
console.log(`
|
|
169
225
|
Authenticated successfully${orgName ? ` (${orgName})` : ""}!`);
|
|
170
|
-
console.log(`Token saved to ${
|
|
226
|
+
console.log(`Token saved to ${CREDENTIALS_FILE2}`);
|
|
171
227
|
console.log(
|
|
172
228
|
"Run `haansi collect` to upload sessions or `haansi setup-mcp` to configure Claude Code."
|
|
173
229
|
);
|
|
174
230
|
}
|
|
175
|
-
var
|
|
231
|
+
var import_node_child_process2, import_node_fs2, import_node_path2, import_node_os2, HAANSI_DIR2, CREDENTIALS_FILE2, POLL_INTERVAL_MS, TIMEOUT_MS;
|
|
176
232
|
var init_auth_login = __esm({
|
|
177
233
|
"src/commands/auth-login.ts"() {
|
|
178
234
|
"use strict";
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
235
|
+
import_node_child_process2 = require("node:child_process");
|
|
236
|
+
import_node_fs2 = require("node:fs");
|
|
237
|
+
import_node_path2 = require("node:path");
|
|
238
|
+
import_node_os2 = require("node:os");
|
|
239
|
+
init_paths();
|
|
240
|
+
HAANSI_DIR2 = (0, import_node_path2.join)((0, import_node_os2.homedir)(), ".haansi");
|
|
241
|
+
CREDENTIALS_FILE2 = (0, import_node_path2.join)(HAANSI_DIR2, "credentials.json");
|
|
186
242
|
POLL_INTERVAL_MS = 2e3;
|
|
187
243
|
TIMEOUT_MS = 5 * 60 * 1e3;
|
|
188
244
|
}
|
|
@@ -220,7 +276,7 @@ async function validateToken(token, apiUrl2) {
|
|
|
220
276
|
}
|
|
221
277
|
}
|
|
222
278
|
async function init() {
|
|
223
|
-
const apiUrl2 =
|
|
279
|
+
const apiUrl2 = apiUrl();
|
|
224
280
|
console.log("Haansi CLI \u2014 Setup\n");
|
|
225
281
|
console.log(
|
|
226
282
|
"Tip: For interactive login, run `haansi auth login` to authenticate via browser.\n"
|
|
@@ -240,28 +296,28 @@ async function init() {
|
|
|
240
296
|
}
|
|
241
297
|
console.log("\nValidating token...");
|
|
242
298
|
await validateToken(token, apiUrl2);
|
|
243
|
-
(0,
|
|
244
|
-
(0,
|
|
299
|
+
(0, import_node_fs3.mkdirSync)(HAANSI_DIR3, { recursive: true });
|
|
300
|
+
(0, import_node_fs3.writeFileSync)(CREDENTIALS_FILE3, JSON.stringify({ token }, null, 2), {
|
|
245
301
|
encoding: "utf-8",
|
|
246
302
|
mode: 384
|
|
247
303
|
});
|
|
248
304
|
console.log(`
|
|
249
|
-
Token saved to ${
|
|
305
|
+
Token saved to ${CREDENTIALS_FILE3}`);
|
|
250
306
|
console.log(
|
|
251
307
|
"Run `haansi daemon` to start collecting or `haansi setup-mcp` to configure your coding agent(s) (Claude Code / Codex)."
|
|
252
308
|
);
|
|
253
309
|
}
|
|
254
|
-
var readline,
|
|
310
|
+
var readline, import_node_fs3, import_node_path3, import_node_os3, HAANSI_DIR3, CREDENTIALS_FILE3;
|
|
255
311
|
var init_init = __esm({
|
|
256
312
|
"src/commands/init.ts"() {
|
|
257
313
|
"use strict";
|
|
258
314
|
readline = __toESM(require("node:readline"));
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
315
|
+
import_node_fs3 = require("node:fs");
|
|
316
|
+
import_node_path3 = require("node:path");
|
|
317
|
+
import_node_os3 = require("node:os");
|
|
318
|
+
init_paths();
|
|
319
|
+
HAANSI_DIR3 = (0, import_node_path3.join)((0, import_node_os3.homedir)(), ".haansi");
|
|
320
|
+
CREDENTIALS_FILE3 = (0, import_node_path3.join)(HAANSI_DIR3, "credentials.json");
|
|
265
321
|
}
|
|
266
322
|
});
|
|
267
323
|
|
|
@@ -339,7 +395,7 @@ var require_main = __commonJS({
|
|
|
339
395
|
var fs = require("fs");
|
|
340
396
|
var path = require("path");
|
|
341
397
|
var os = require("os");
|
|
342
|
-
var
|
|
398
|
+
var crypto8 = require("crypto");
|
|
343
399
|
var packageJson = require_package2();
|
|
344
400
|
var version3 = packageJson.version;
|
|
345
401
|
var LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;
|
|
@@ -558,7 +614,7 @@ var require_main = __commonJS({
|
|
|
558
614
|
const authTag = ciphertext.subarray(-16);
|
|
559
615
|
ciphertext = ciphertext.subarray(12, -16);
|
|
560
616
|
try {
|
|
561
|
-
const aesgcm =
|
|
617
|
+
const aesgcm = crypto8.createDecipheriv("aes-256-gcm", key, nonce);
|
|
562
618
|
aesgcm.setAuthTag(authTag);
|
|
563
619
|
return `${aesgcm.update(ciphertext)}${aesgcm.final()}`;
|
|
564
620
|
} catch (error2) {
|
|
@@ -623,61 +679,1039 @@ var require_main = __commonJS({
|
|
|
623
679
|
}
|
|
624
680
|
});
|
|
625
681
|
|
|
626
|
-
//
|
|
627
|
-
function
|
|
628
|
-
|
|
629
|
-
|
|
682
|
+
// ../../packages/@company/observability/node_modules/uuid/dist/esm-node/rng.js
|
|
683
|
+
function rng() {
|
|
684
|
+
if (poolPtr > rnds8Pool.length - 16) {
|
|
685
|
+
import_crypto.default.randomFillSync(rnds8Pool);
|
|
686
|
+
poolPtr = 0;
|
|
687
|
+
}
|
|
688
|
+
return rnds8Pool.slice(poolPtr, poolPtr += 16);
|
|
689
|
+
}
|
|
690
|
+
var import_crypto, rnds8Pool, poolPtr;
|
|
691
|
+
var init_rng = __esm({
|
|
692
|
+
"../../packages/@company/observability/node_modules/uuid/dist/esm-node/rng.js"() {
|
|
693
|
+
import_crypto = __toESM(require("crypto"));
|
|
694
|
+
rnds8Pool = new Uint8Array(256);
|
|
695
|
+
poolPtr = rnds8Pool.length;
|
|
696
|
+
}
|
|
697
|
+
});
|
|
698
|
+
|
|
699
|
+
// ../../packages/@company/observability/node_modules/uuid/dist/esm-node/stringify.js
|
|
700
|
+
function unsafeStringify(arr, offset = 0) {
|
|
701
|
+
return byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]];
|
|
702
|
+
}
|
|
703
|
+
var byteToHex;
|
|
704
|
+
var init_stringify = __esm({
|
|
705
|
+
"../../packages/@company/observability/node_modules/uuid/dist/esm-node/stringify.js"() {
|
|
706
|
+
byteToHex = [];
|
|
707
|
+
for (let i = 0; i < 256; ++i) {
|
|
708
|
+
byteToHex.push((i + 256).toString(16).slice(1));
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
});
|
|
712
|
+
|
|
713
|
+
// ../../packages/@company/observability/node_modules/uuid/dist/esm-node/native.js
|
|
714
|
+
var import_crypto2, native_default;
|
|
715
|
+
var init_native = __esm({
|
|
716
|
+
"../../packages/@company/observability/node_modules/uuid/dist/esm-node/native.js"() {
|
|
717
|
+
import_crypto2 = __toESM(require("crypto"));
|
|
718
|
+
native_default = {
|
|
719
|
+
randomUUID: import_crypto2.default.randomUUID
|
|
720
|
+
};
|
|
721
|
+
}
|
|
722
|
+
});
|
|
723
|
+
|
|
724
|
+
// ../../packages/@company/observability/node_modules/uuid/dist/esm-node/v4.js
|
|
725
|
+
function v4(options, buf, offset) {
|
|
726
|
+
if (native_default.randomUUID && !buf && !options) {
|
|
727
|
+
return native_default.randomUUID();
|
|
728
|
+
}
|
|
729
|
+
options = options || {};
|
|
730
|
+
const rnds = options.random || (options.rng || rng)();
|
|
731
|
+
rnds[6] = rnds[6] & 15 | 64;
|
|
732
|
+
rnds[8] = rnds[8] & 63 | 128;
|
|
733
|
+
if (buf) {
|
|
734
|
+
offset = offset || 0;
|
|
735
|
+
for (let i = 0; i < 16; ++i) {
|
|
736
|
+
buf[offset + i] = rnds[i];
|
|
737
|
+
}
|
|
738
|
+
return buf;
|
|
739
|
+
}
|
|
740
|
+
return unsafeStringify(rnds);
|
|
630
741
|
}
|
|
631
|
-
var
|
|
742
|
+
var v4_default;
|
|
743
|
+
var init_v4 = __esm({
|
|
744
|
+
"../../packages/@company/observability/node_modules/uuid/dist/esm-node/v4.js"() {
|
|
745
|
+
init_native();
|
|
746
|
+
init_rng();
|
|
747
|
+
init_stringify();
|
|
748
|
+
v4_default = v4;
|
|
749
|
+
}
|
|
750
|
+
});
|
|
751
|
+
|
|
752
|
+
// ../../packages/@company/observability/node_modules/uuid/dist/esm-node/index.js
|
|
753
|
+
var init_esm_node = __esm({
|
|
754
|
+
"../../packages/@company/observability/node_modules/uuid/dist/esm-node/index.js"() {
|
|
755
|
+
init_v4();
|
|
756
|
+
}
|
|
757
|
+
});
|
|
758
|
+
|
|
759
|
+
// ../../packages/@company/observability/src/types.ts
|
|
760
|
+
var init_types = __esm({
|
|
761
|
+
"../../packages/@company/observability/src/types.ts"() {
|
|
762
|
+
"use strict";
|
|
763
|
+
}
|
|
764
|
+
});
|
|
765
|
+
|
|
766
|
+
// ../../packages/@company/cloud/src/provider-registry.ts
|
|
767
|
+
var ProviderRegistry, cloudRegistry;
|
|
768
|
+
var init_provider_registry = __esm({
|
|
769
|
+
"../../packages/@company/cloud/src/provider-registry.ts"() {
|
|
770
|
+
"use strict";
|
|
771
|
+
ProviderRegistry = class {
|
|
772
|
+
_provider = null;
|
|
773
|
+
_config = null;
|
|
774
|
+
_storage = null;
|
|
775
|
+
_loggerBackend = null;
|
|
776
|
+
_metricsBackend = null;
|
|
777
|
+
_messageQueueParser = null;
|
|
778
|
+
_secretsManager = null;
|
|
779
|
+
_databaseSslResolver = null;
|
|
780
|
+
get provider() {
|
|
781
|
+
return this._provider;
|
|
782
|
+
}
|
|
783
|
+
get config() {
|
|
784
|
+
return this._config;
|
|
785
|
+
}
|
|
786
|
+
register(config6) {
|
|
787
|
+
this._provider = config6.provider;
|
|
788
|
+
this._config = config6;
|
|
789
|
+
}
|
|
790
|
+
// ── Setters (called by cloud-gcp / cloud-aws register functions) ──────────
|
|
791
|
+
setStorage(client) {
|
|
792
|
+
this._storage = client;
|
|
793
|
+
}
|
|
794
|
+
setLoggerBackend(backend) {
|
|
795
|
+
this._loggerBackend = backend;
|
|
796
|
+
}
|
|
797
|
+
setMetricsBackend(backend) {
|
|
798
|
+
this._metricsBackend = backend;
|
|
799
|
+
}
|
|
800
|
+
setMessageQueueParser(parser) {
|
|
801
|
+
this._messageQueueParser = parser;
|
|
802
|
+
}
|
|
803
|
+
setSecretsManager(manager) {
|
|
804
|
+
this._secretsManager = manager;
|
|
805
|
+
}
|
|
806
|
+
setDatabaseSslResolver(resolver) {
|
|
807
|
+
this._databaseSslResolver = resolver;
|
|
808
|
+
}
|
|
809
|
+
// ── Getters (called by consumers) ─────────────────────────────────────────
|
|
810
|
+
getStorage() {
|
|
811
|
+
if (!this._storage) {
|
|
812
|
+
throw new Error(
|
|
813
|
+
"No storage client registered. Call bootstrapCloudProvider() at startup."
|
|
814
|
+
);
|
|
815
|
+
}
|
|
816
|
+
return this._storage;
|
|
817
|
+
}
|
|
818
|
+
getLoggerBackend() {
|
|
819
|
+
return this._loggerBackend;
|
|
820
|
+
}
|
|
821
|
+
getMetricsBackend() {
|
|
822
|
+
return this._metricsBackend;
|
|
823
|
+
}
|
|
824
|
+
getMessageQueueParser() {
|
|
825
|
+
return this._messageQueueParser;
|
|
826
|
+
}
|
|
827
|
+
getSecretsManager() {
|
|
828
|
+
if (!this._secretsManager) {
|
|
829
|
+
throw new Error(
|
|
830
|
+
"No secrets manager registered. Call bootstrapCloudProvider() at startup."
|
|
831
|
+
);
|
|
832
|
+
}
|
|
833
|
+
return this._secretsManager;
|
|
834
|
+
}
|
|
835
|
+
getDatabaseSslConfig(connectionString) {
|
|
836
|
+
if (!this._databaseSslResolver) {
|
|
837
|
+
return {
|
|
838
|
+
ssl: process.env.NODE_ENV === "production" ? { rejectUnauthorized: true } : false
|
|
839
|
+
};
|
|
840
|
+
}
|
|
841
|
+
return this._databaseSslResolver(connectionString);
|
|
842
|
+
}
|
|
843
|
+
/**
|
|
844
|
+
* Reset all registrations. Primarily for testing.
|
|
845
|
+
*/
|
|
846
|
+
reset() {
|
|
847
|
+
this._provider = null;
|
|
848
|
+
this._config = null;
|
|
849
|
+
this._storage = null;
|
|
850
|
+
this._loggerBackend = null;
|
|
851
|
+
this._metricsBackend = null;
|
|
852
|
+
this._messageQueueParser = null;
|
|
853
|
+
this._secretsManager = null;
|
|
854
|
+
this._databaseSslResolver = null;
|
|
855
|
+
}
|
|
856
|
+
};
|
|
857
|
+
cloudRegistry = new ProviderRegistry();
|
|
858
|
+
}
|
|
859
|
+
});
|
|
860
|
+
|
|
861
|
+
// ../../packages/@company/cloud/src/bootstrap.ts
|
|
862
|
+
function bootstrapCloudProvider(override) {
|
|
863
|
+
const provider = override ?? process.env.CLOUD_PROVIDER;
|
|
864
|
+
if (!provider || provider === "local") {
|
|
865
|
+
return;
|
|
866
|
+
}
|
|
867
|
+
const pkg = PROVIDER_PACKAGES[provider];
|
|
868
|
+
if (!pkg) {
|
|
869
|
+
throw new Error(
|
|
870
|
+
`Unknown CLOUD_PROVIDER "${provider}". Supported: ${Object.keys(PROVIDER_PACKAGES).join(", ")}, local`
|
|
871
|
+
);
|
|
872
|
+
}
|
|
873
|
+
try {
|
|
874
|
+
const mod = _require(pkg);
|
|
875
|
+
const registerFnName = `register${provider.charAt(0).toUpperCase() + provider.slice(1)}Provider`;
|
|
876
|
+
const registerFn = mod[registerFnName] ?? mod.default;
|
|
877
|
+
if (typeof registerFn !== "function") {
|
|
878
|
+
throw new Error(
|
|
879
|
+
`${pkg} does not export ${registerFnName}() or a default registration function`
|
|
880
|
+
);
|
|
881
|
+
}
|
|
882
|
+
registerFn();
|
|
883
|
+
} catch (err) {
|
|
884
|
+
if (err.code === "ERR_MODULE_NOT_FOUND" || err.code === "MODULE_NOT_FOUND") {
|
|
885
|
+
throw new Error(
|
|
886
|
+
`CLOUD_PROVIDER is "${provider}" but ${pkg} is not installed. Add it to your service's package.json dependencies.`
|
|
887
|
+
);
|
|
888
|
+
}
|
|
889
|
+
throw err;
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
var PROVIDER_PACKAGES, _require;
|
|
893
|
+
var init_bootstrap = __esm({
|
|
894
|
+
"../../packages/@company/cloud/src/bootstrap.ts"() {
|
|
895
|
+
"use strict";
|
|
896
|
+
PROVIDER_PACKAGES = {
|
|
897
|
+
gcp: "@company/cloud-gcp",
|
|
898
|
+
aws: "@company/cloud-aws"
|
|
899
|
+
};
|
|
900
|
+
_require = require;
|
|
901
|
+
}
|
|
902
|
+
});
|
|
903
|
+
|
|
904
|
+
// ../../packages/@company/cloud/src/storage-uri.ts
|
|
905
|
+
function storageUri(bucket, path) {
|
|
906
|
+
const provider = cloudRegistry.provider;
|
|
907
|
+
const scheme = provider === "aws" ? "s3" : provider === "gcp" ? "gs" : "file";
|
|
908
|
+
return `${scheme}://${bucket}/${path}`;
|
|
909
|
+
}
|
|
910
|
+
var init_storage_uri = __esm({
|
|
911
|
+
"../../packages/@company/cloud/src/storage-uri.ts"() {
|
|
912
|
+
"use strict";
|
|
913
|
+
init_provider_registry();
|
|
914
|
+
}
|
|
915
|
+
});
|
|
916
|
+
|
|
917
|
+
// ../../packages/@company/cloud/src/index.ts
|
|
918
|
+
var src_exports = {};
|
|
919
|
+
__export(src_exports, {
|
|
920
|
+
ProviderRegistry: () => ProviderRegistry,
|
|
921
|
+
bootstrapCloudProvider: () => bootstrapCloudProvider,
|
|
922
|
+
cloudRegistry: () => cloudRegistry,
|
|
923
|
+
storageUri: () => storageUri
|
|
924
|
+
});
|
|
925
|
+
var init_src = __esm({
|
|
926
|
+
"../../packages/@company/cloud/src/index.ts"() {
|
|
927
|
+
init_provider_registry();
|
|
928
|
+
init_bootstrap();
|
|
929
|
+
init_storage_uri();
|
|
930
|
+
}
|
|
931
|
+
});
|
|
932
|
+
|
|
933
|
+
// ../../packages/@company/observability/src/logger.ts
|
|
934
|
+
function getCloudBackend() {
|
|
935
|
+
if (_cloudBackend === void 0) {
|
|
936
|
+
try {
|
|
937
|
+
const { cloudRegistry: cloudRegistry2 } = (
|
|
938
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
939
|
+
(init_src(), __toCommonJS(src_exports))
|
|
940
|
+
);
|
|
941
|
+
_cloudBackend = cloudRegistry2.getLoggerBackend();
|
|
942
|
+
} catch {
|
|
943
|
+
_cloudBackend = null;
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
return _cloudBackend;
|
|
947
|
+
}
|
|
948
|
+
function normKey(key) {
|
|
949
|
+
return key.toLowerCase().replace(/[_\-]/g, "");
|
|
950
|
+
}
|
|
951
|
+
function isSensitiveKey(key) {
|
|
952
|
+
return SENSITIVE_KEY_RE.test(normKey(key));
|
|
953
|
+
}
|
|
954
|
+
function sanitizeMetadata(obj, depth = 0) {
|
|
955
|
+
if (depth > 5) return obj;
|
|
956
|
+
const result = {};
|
|
957
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
958
|
+
if (isSensitiveKey(k)) {
|
|
959
|
+
result[k] = "[REDACTED]";
|
|
960
|
+
} else if (v !== null && typeof v === "object" && !Array.isArray(v) && !(v instanceof Date)) {
|
|
961
|
+
result[k] = sanitizeMetadata(v, depth + 1);
|
|
962
|
+
} else {
|
|
963
|
+
result[k] = v;
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
return result;
|
|
967
|
+
}
|
|
968
|
+
function normalizeErrorMetadata(error2, metadata) {
|
|
969
|
+
if (!error2) return metadata;
|
|
970
|
+
if (error2 instanceof Error) {
|
|
971
|
+
return {
|
|
972
|
+
error: {
|
|
973
|
+
message: error2.message,
|
|
974
|
+
name: error2.name,
|
|
975
|
+
// Omit stack in production — it exposes internal file paths and code structure
|
|
976
|
+
...process.env.NODE_ENV !== "production" && {
|
|
977
|
+
stack: error2.stack
|
|
978
|
+
}
|
|
979
|
+
},
|
|
980
|
+
...metadata
|
|
981
|
+
};
|
|
982
|
+
}
|
|
983
|
+
if (typeof error2 === "object" && error2 !== null && !Array.isArray(error2)) {
|
|
984
|
+
return { ...error2, ...metadata };
|
|
985
|
+
}
|
|
986
|
+
return { error: String(error2), ...metadata };
|
|
987
|
+
}
|
|
988
|
+
function createLogger(serviceName, projectId) {
|
|
989
|
+
return new StructuredLogger(
|
|
990
|
+
serviceName,
|
|
991
|
+
projectId === null ? void 0 : projectId || process.env.GCP_PROJECT_ID
|
|
992
|
+
);
|
|
993
|
+
}
|
|
994
|
+
var import_async_hooks, _cloudBackend, SENSITIVE_KEY_RE, traceStorage, StructuredLogger, TraceContext;
|
|
632
995
|
var init_logger = __esm({
|
|
633
|
-
"
|
|
996
|
+
"../../packages/@company/observability/src/logger.ts"() {
|
|
634
997
|
"use strict";
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
998
|
+
import_async_hooks = require("async_hooks");
|
|
999
|
+
init_esm_node();
|
|
1000
|
+
init_types();
|
|
1001
|
+
SENSITIVE_KEY_RE = /^(password|passwd|secret|token|apikey|authorization|auth|authtoken|authkey|credentials?|connectionstring|privatekey)$/;
|
|
1002
|
+
traceStorage = new import_async_hooks.AsyncLocalStorage();
|
|
1003
|
+
StructuredLogger = class {
|
|
1004
|
+
serviceName;
|
|
1005
|
+
isLocal;
|
|
1006
|
+
projectId;
|
|
1007
|
+
constructor(serviceName, projectId) {
|
|
1008
|
+
this.serviceName = serviceName;
|
|
1009
|
+
this.projectId = projectId ?? void 0;
|
|
1010
|
+
this.isLocal = process.env.NODE_ENV === "development" || !this.projectId;
|
|
1011
|
+
if (!this.isLocal && !getCloudBackend()) {
|
|
1012
|
+
console.error(
|
|
1013
|
+
`[StructuredLogger] WARNING: No cloud logger backend registered for service "${serviceName}". Falling back to console logging. Register a cloud provider to enable cloud logging.`
|
|
1014
|
+
);
|
|
1015
|
+
}
|
|
641
1016
|
}
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
1017
|
+
/**
|
|
1018
|
+
* Write a structured log entry. Sanitises metadata before writing so that
|
|
1019
|
+
* PII / secrets never reach cloud logging.
|
|
1020
|
+
*/
|
|
1021
|
+
async write(entry) {
|
|
1022
|
+
const logEntry = {
|
|
1023
|
+
...entry,
|
|
1024
|
+
serviceName: this.serviceName,
|
|
1025
|
+
timestamp: entry.timestamp || /* @__PURE__ */ new Date(),
|
|
1026
|
+
metadata: entry.metadata ? sanitizeMetadata(entry.metadata) : void 0
|
|
1027
|
+
};
|
|
1028
|
+
const backend = getCloudBackend();
|
|
1029
|
+
if (this.isLocal || !backend) {
|
|
1030
|
+
this.consoleLog(logEntry);
|
|
1031
|
+
} else {
|
|
1032
|
+
try {
|
|
1033
|
+
await backend.writeLog({
|
|
1034
|
+
severity: logEntry.severity,
|
|
1035
|
+
message: logEntry.message,
|
|
1036
|
+
timestamp: logEntry.timestamp,
|
|
1037
|
+
traceId: logEntry.traceId,
|
|
1038
|
+
spanId: logEntry.spanId,
|
|
1039
|
+
userId: logEntry.userId,
|
|
1040
|
+
organizationId: logEntry.organizationId,
|
|
1041
|
+
serviceName: logEntry.serviceName,
|
|
1042
|
+
metadata: logEntry.metadata
|
|
1043
|
+
});
|
|
1044
|
+
} catch (e) {
|
|
1045
|
+
console.error("[StructuredLogger] Cloud Logging write failed:", e);
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
646
1048
|
}
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
1049
|
+
/**
|
|
1050
|
+
* Console logging for local development
|
|
1051
|
+
*/
|
|
1052
|
+
consoleLog(entry) {
|
|
1053
|
+
const timestamp = entry.timestamp?.toISOString() || (/* @__PURE__ */ new Date()).toISOString();
|
|
1054
|
+
const traceInfo = entry.traceId ? ` [trace: ${entry.traceId.slice(0, 8)}]` : "";
|
|
1055
|
+
const orgInfo = entry.organizationId ? ` [org: ${entry.organizationId.slice(0, 8)}]` : "";
|
|
1056
|
+
const prefix = `[${timestamp}] [${entry.severity}] [${this.serviceName}]${traceInfo}${orgInfo}`;
|
|
1057
|
+
const message = `${prefix} ${entry.message}`;
|
|
1058
|
+
const metadata = entry.metadata ? `
|
|
1059
|
+
${JSON.stringify(entry.metadata, null, 2)}` : "";
|
|
1060
|
+
switch (entry.severity) {
|
|
1061
|
+
case "ERROR" /* ERROR */:
|
|
1062
|
+
case "CRITICAL" /* CRITICAL */:
|
|
1063
|
+
case "ALERT" /* ALERT */:
|
|
1064
|
+
case "EMERGENCY" /* EMERGENCY */:
|
|
1065
|
+
console.error(message + metadata);
|
|
1066
|
+
break;
|
|
1067
|
+
case "WARNING" /* WARNING */:
|
|
1068
|
+
console.warn(message + metadata);
|
|
1069
|
+
break;
|
|
1070
|
+
default:
|
|
1071
|
+
console.log(message + metadata);
|
|
650
1072
|
}
|
|
651
1073
|
}
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
1074
|
+
// ─── Convenience level methods ──────────────────────────────────────────────
|
|
1075
|
+
async debug(message, metadata, context) {
|
|
1076
|
+
await this.write({
|
|
1077
|
+
severity: "DEBUG" /* DEBUG */,
|
|
1078
|
+
message,
|
|
1079
|
+
metadata,
|
|
1080
|
+
...context
|
|
1081
|
+
});
|
|
1082
|
+
}
|
|
1083
|
+
async info(message, metadata, context) {
|
|
1084
|
+
await this.write({
|
|
1085
|
+
severity: "INFO" /* INFO */,
|
|
1086
|
+
message,
|
|
1087
|
+
metadata,
|
|
1088
|
+
...context
|
|
1089
|
+
});
|
|
1090
|
+
}
|
|
1091
|
+
async notice(message, metadata, context) {
|
|
1092
|
+
await this.write({
|
|
1093
|
+
severity: "NOTICE" /* NOTICE */,
|
|
1094
|
+
message,
|
|
1095
|
+
metadata,
|
|
1096
|
+
...context
|
|
1097
|
+
});
|
|
1098
|
+
}
|
|
1099
|
+
async warning(message, metadata, context) {
|
|
1100
|
+
await this.write({
|
|
1101
|
+
severity: "WARNING" /* WARNING */,
|
|
1102
|
+
message,
|
|
1103
|
+
metadata,
|
|
1104
|
+
...context
|
|
1105
|
+
});
|
|
1106
|
+
}
|
|
1107
|
+
async warn(message, metadata, context) {
|
|
1108
|
+
await this.warning(message, metadata, context);
|
|
1109
|
+
}
|
|
1110
|
+
async error(message, error2, metadata, context) {
|
|
1111
|
+
const errorMetadata = normalizeErrorMetadata(error2, metadata);
|
|
1112
|
+
await this.write({
|
|
1113
|
+
severity: "ERROR" /* ERROR */,
|
|
1114
|
+
message,
|
|
1115
|
+
metadata: errorMetadata,
|
|
1116
|
+
...context
|
|
1117
|
+
});
|
|
1118
|
+
}
|
|
1119
|
+
async critical(message, error2, metadata, context) {
|
|
1120
|
+
const errorMetadata = normalizeErrorMetadata(error2, metadata);
|
|
1121
|
+
await this.write({
|
|
1122
|
+
severity: "CRITICAL" /* CRITICAL */,
|
|
1123
|
+
message,
|
|
1124
|
+
metadata: errorMetadata,
|
|
1125
|
+
...context
|
|
1126
|
+
});
|
|
1127
|
+
}
|
|
1128
|
+
};
|
|
1129
|
+
TraceContext = class {
|
|
1130
|
+
static generateTraceId() {
|
|
1131
|
+
return v4_default();
|
|
1132
|
+
}
|
|
1133
|
+
static generateSpanId() {
|
|
1134
|
+
return v4_default().slice(0, 16);
|
|
1135
|
+
}
|
|
1136
|
+
/**
|
|
1137
|
+
* Return the trace IDs for the current async execution context.
|
|
1138
|
+
* Returns { traceId: null, spanId: null } when called outside any trace context.
|
|
1139
|
+
*/
|
|
1140
|
+
static getTrace() {
|
|
1141
|
+
const store = traceStorage.getStore();
|
|
1142
|
+
return {
|
|
1143
|
+
traceId: store?.traceId ?? null,
|
|
1144
|
+
spanId: store?.spanId ?? null
|
|
1145
|
+
};
|
|
1146
|
+
}
|
|
1147
|
+
/**
|
|
1148
|
+
* Run fn inside a scoped trace context. All async continuations started
|
|
1149
|
+
* within fn (awaits, Promise chains, timer callbacks) automatically inherit
|
|
1150
|
+
* this context — this is the correct way to scope a single HTTP request.
|
|
1151
|
+
*
|
|
1152
|
+
* Used by traceMiddleware: TraceContext.runInContext(traceId, spanId, next)
|
|
1153
|
+
*/
|
|
1154
|
+
static runInContext(traceId, spanId, fn) {
|
|
1155
|
+
return traceStorage.run({ traceId, spanId }, fn);
|
|
1156
|
+
}
|
|
1157
|
+
/**
|
|
1158
|
+
* Run an async function with a new (or supplied) trace context.
|
|
1159
|
+
* Preferred API for background jobs, workers, and test isolation.
|
|
1160
|
+
*/
|
|
1161
|
+
static async runWithTrace(fn, traceId) {
|
|
1162
|
+
const id = traceId || this.generateTraceId();
|
|
1163
|
+
const spanId = this.generateSpanId();
|
|
1164
|
+
return traceStorage.run({ traceId: id, spanId }, fn);
|
|
1165
|
+
}
|
|
1166
|
+
/**
|
|
1167
|
+
* @deprecated No-op. AsyncLocalStorage replaced process-global static fields.
|
|
1168
|
+
* Use `TraceContext.runWithTrace(fn)` for background jobs or rely on the
|
|
1169
|
+
* traceMiddleware (which calls runInContext automatically) for HTTP requests.
|
|
1170
|
+
*/
|
|
1171
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1172
|
+
static setTrace(_traceId, _spanId) {
|
|
1173
|
+
}
|
|
1174
|
+
/**
|
|
1175
|
+
* @deprecated No-op — AsyncLocalStorage context is automatically scoped.
|
|
1176
|
+
*/
|
|
1177
|
+
static clear() {
|
|
1178
|
+
}
|
|
1179
|
+
};
|
|
1180
|
+
}
|
|
1181
|
+
});
|
|
1182
|
+
|
|
1183
|
+
// ../../packages/@company/observability/src/metrics.ts
|
|
1184
|
+
function getCloudBackend2() {
|
|
1185
|
+
if (_cloudBackend2 === void 0) {
|
|
1186
|
+
try {
|
|
1187
|
+
const { cloudRegistry: cloudRegistry2 } = (
|
|
1188
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
1189
|
+
(init_src(), __toCommonJS(src_exports))
|
|
1190
|
+
);
|
|
1191
|
+
_cloudBackend2 = cloudRegistry2.getMetricsBackend();
|
|
1192
|
+
} catch {
|
|
1193
|
+
_cloudBackend2 = null;
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
return _cloudBackend2;
|
|
1197
|
+
}
|
|
1198
|
+
var _cloudBackend2, MetricsService;
|
|
1199
|
+
var init_metrics = __esm({
|
|
1200
|
+
"../../packages/@company/observability/src/metrics.ts"() {
|
|
1201
|
+
"use strict";
|
|
1202
|
+
init_types();
|
|
1203
|
+
MetricsService = class {
|
|
1204
|
+
projectId;
|
|
1205
|
+
serviceName;
|
|
1206
|
+
isLocal;
|
|
1207
|
+
constructor(serviceName, projectId) {
|
|
1208
|
+
this.serviceName = serviceName;
|
|
1209
|
+
this.projectId = projectId === null ? "" : projectId || process.env.GCP_PROJECT_ID || "";
|
|
1210
|
+
this.isLocal = process.env.NODE_ENV === "development" || !this.projectId;
|
|
1211
|
+
if (!this.isLocal && !getCloudBackend2()) {
|
|
1212
|
+
console.error(
|
|
1213
|
+
`[MetricsService] WARNING: No cloud metrics backend registered for service "${serviceName}". Metrics will be logged to console only. Register a cloud provider to enable cloud metrics.`
|
|
1214
|
+
);
|
|
655
1215
|
}
|
|
656
1216
|
}
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
1217
|
+
/**
|
|
1218
|
+
* Record a custom metric
|
|
1219
|
+
*/
|
|
1220
|
+
async recordMetric(metric) {
|
|
1221
|
+
if (this.isLocal) {
|
|
1222
|
+
console.log("[METRIC]", {
|
|
1223
|
+
name: metric.name,
|
|
1224
|
+
value: metric.value,
|
|
1225
|
+
type: metric.type,
|
|
1226
|
+
labels: metric.labels,
|
|
1227
|
+
unit: metric.unit
|
|
1228
|
+
});
|
|
1229
|
+
return;
|
|
1230
|
+
}
|
|
1231
|
+
const backend = getCloudBackend2();
|
|
1232
|
+
if (!backend) {
|
|
1233
|
+
console.warn("Metrics backend not initialized");
|
|
1234
|
+
return;
|
|
1235
|
+
}
|
|
1236
|
+
try {
|
|
1237
|
+
await backend.writeMetric({
|
|
1238
|
+
name: metric.name,
|
|
1239
|
+
value: metric.value,
|
|
1240
|
+
type: metric.type,
|
|
1241
|
+
labels: metric.labels,
|
|
1242
|
+
timestamp: metric.timestamp,
|
|
1243
|
+
unit: metric.unit,
|
|
1244
|
+
serviceName: this.serviceName
|
|
1245
|
+
});
|
|
1246
|
+
} catch (error2) {
|
|
1247
|
+
console.error("Failed to record metric:", error2);
|
|
660
1248
|
}
|
|
661
1249
|
}
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
1250
|
+
/**
|
|
1251
|
+
* Record API request metrics
|
|
1252
|
+
*/
|
|
1253
|
+
async recordAPICall(metrics) {
|
|
1254
|
+
await this.recordMetric({
|
|
1255
|
+
name: "api/requests_total",
|
|
1256
|
+
value: 1,
|
|
1257
|
+
type: "COUNTER" /* COUNTER */,
|
|
1258
|
+
labels: {
|
|
1259
|
+
endpoint: metrics.endpoint,
|
|
1260
|
+
method: metrics.method,
|
|
1261
|
+
status_code: metrics.statusCode.toString(),
|
|
1262
|
+
organization_id: metrics.organizationId || "unknown"
|
|
1263
|
+
}
|
|
1264
|
+
});
|
|
1265
|
+
await this.recordMetric({
|
|
1266
|
+
name: "api/request_duration_ms",
|
|
1267
|
+
value: metrics.duration,
|
|
1268
|
+
type: "HISTOGRAM" /* HISTOGRAM */,
|
|
1269
|
+
labels: {
|
|
1270
|
+
endpoint: metrics.endpoint,
|
|
1271
|
+
method: metrics.method
|
|
1272
|
+
},
|
|
1273
|
+
unit: "ms"
|
|
1274
|
+
});
|
|
1275
|
+
if (metrics.statusCode >= 400) {
|
|
1276
|
+
await this.recordMetric({
|
|
1277
|
+
name: "api/errors_total",
|
|
1278
|
+
value: 1,
|
|
1279
|
+
type: "COUNTER" /* COUNTER */,
|
|
1280
|
+
labels: {
|
|
1281
|
+
endpoint: metrics.endpoint,
|
|
1282
|
+
method: metrics.method,
|
|
1283
|
+
status_code: metrics.statusCode.toString(),
|
|
1284
|
+
organization_id: metrics.organizationId || "unknown"
|
|
1285
|
+
}
|
|
1286
|
+
});
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
/**
|
|
1290
|
+
* Record LLM usage metrics
|
|
1291
|
+
*/
|
|
1292
|
+
async recordLLMCall(metrics) {
|
|
1293
|
+
await this.recordMetric({
|
|
1294
|
+
name: "llm/calls_total",
|
|
1295
|
+
value: 1,
|
|
1296
|
+
type: "COUNTER" /* COUNTER */,
|
|
1297
|
+
labels: {
|
|
1298
|
+
model: metrics.model,
|
|
1299
|
+
success: metrics.success.toString(),
|
|
1300
|
+
organization_id: metrics.organizationId || "unknown"
|
|
1301
|
+
}
|
|
1302
|
+
});
|
|
1303
|
+
await this.recordMetric({
|
|
1304
|
+
name: "llm/tokens_total",
|
|
1305
|
+
value: metrics.totalTokens,
|
|
1306
|
+
type: "COUNTER" /* COUNTER */,
|
|
1307
|
+
labels: {
|
|
1308
|
+
model: metrics.model,
|
|
1309
|
+
type: "total",
|
|
1310
|
+
organization_id: metrics.organizationId || "unknown"
|
|
1311
|
+
}
|
|
1312
|
+
});
|
|
1313
|
+
await this.recordMetric({
|
|
1314
|
+
name: "llm/tokens_total",
|
|
1315
|
+
value: metrics.inputTokens,
|
|
1316
|
+
type: "COUNTER" /* COUNTER */,
|
|
1317
|
+
labels: {
|
|
1318
|
+
model: metrics.model,
|
|
1319
|
+
type: "input",
|
|
1320
|
+
organization_id: metrics.organizationId || "unknown"
|
|
1321
|
+
}
|
|
1322
|
+
});
|
|
1323
|
+
await this.recordMetric({
|
|
1324
|
+
name: "llm/tokens_total",
|
|
1325
|
+
value: metrics.outputTokens,
|
|
1326
|
+
type: "COUNTER" /* COUNTER */,
|
|
1327
|
+
labels: {
|
|
1328
|
+
model: metrics.model,
|
|
1329
|
+
type: "output",
|
|
1330
|
+
organization_id: metrics.organizationId || "unknown"
|
|
1331
|
+
}
|
|
1332
|
+
});
|
|
1333
|
+
await this.recordMetric({
|
|
1334
|
+
name: "llm/request_duration_ms",
|
|
1335
|
+
value: metrics.duration,
|
|
1336
|
+
type: "HISTOGRAM" /* HISTOGRAM */,
|
|
1337
|
+
labels: {
|
|
1338
|
+
model: metrics.model
|
|
1339
|
+
},
|
|
1340
|
+
unit: "ms"
|
|
1341
|
+
});
|
|
1342
|
+
if (!metrics.success) {
|
|
1343
|
+
await this.recordMetric({
|
|
1344
|
+
name: "llm/errors_total",
|
|
1345
|
+
value: 1,
|
|
1346
|
+
type: "COUNTER" /* COUNTER */,
|
|
1347
|
+
labels: {
|
|
1348
|
+
model: metrics.model,
|
|
1349
|
+
error_type: metrics.error || "unknown"
|
|
1350
|
+
}
|
|
1351
|
+
});
|
|
669
1352
|
}
|
|
670
1353
|
}
|
|
671
|
-
|
|
672
|
-
|
|
1354
|
+
/**
|
|
1355
|
+
* Record data capture metrics
|
|
1356
|
+
*/
|
|
1357
|
+
async recordDataCapture(metrics) {
|
|
1358
|
+
await this.recordMetric({
|
|
1359
|
+
name: "data_capture/operations_total",
|
|
1360
|
+
value: 1,
|
|
1361
|
+
type: "COUNTER" /* COUNTER */,
|
|
1362
|
+
labels: {
|
|
1363
|
+
integration: metrics.integration,
|
|
1364
|
+
operation: metrics.operation,
|
|
1365
|
+
success: metrics.success.toString()
|
|
1366
|
+
}
|
|
1367
|
+
});
|
|
1368
|
+
await this.recordMetric({
|
|
1369
|
+
name: "data_capture/records_processed",
|
|
1370
|
+
value: metrics.recordsProcessed,
|
|
1371
|
+
type: "COUNTER" /* COUNTER */,
|
|
1372
|
+
labels: {
|
|
1373
|
+
integration: metrics.integration,
|
|
1374
|
+
operation: metrics.operation
|
|
1375
|
+
}
|
|
1376
|
+
});
|
|
1377
|
+
await this.recordMetric({
|
|
1378
|
+
name: "data_capture/duration_ms",
|
|
1379
|
+
value: metrics.duration,
|
|
1380
|
+
type: "HISTOGRAM" /* HISTOGRAM */,
|
|
1381
|
+
labels: {
|
|
1382
|
+
integration: metrics.integration,
|
|
1383
|
+
operation: metrics.operation
|
|
1384
|
+
},
|
|
1385
|
+
unit: "ms"
|
|
1386
|
+
});
|
|
1387
|
+
if (!metrics.success) {
|
|
1388
|
+
await this.recordMetric({
|
|
1389
|
+
name: "data_capture/errors_total",
|
|
1390
|
+
value: 1,
|
|
1391
|
+
type: "COUNTER" /* COUNTER */,
|
|
1392
|
+
labels: {
|
|
1393
|
+
integration: metrics.integration,
|
|
1394
|
+
operation: metrics.operation,
|
|
1395
|
+
error_type: metrics.error || "unknown"
|
|
1396
|
+
}
|
|
1397
|
+
});
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
/**
|
|
1401
|
+
* Record usage metrics for billing/quota tracking
|
|
1402
|
+
*/
|
|
1403
|
+
async recordUsage(metrics) {
|
|
1404
|
+
await this.recordMetric({
|
|
1405
|
+
name: "usage/api_calls",
|
|
1406
|
+
value: metrics.apiCalls,
|
|
1407
|
+
type: "GAUGE" /* GAUGE */,
|
|
1408
|
+
labels: {
|
|
1409
|
+
organization_id: metrics.organizationId
|
|
1410
|
+
},
|
|
1411
|
+
timestamp: metrics.timestamp
|
|
1412
|
+
});
|
|
1413
|
+
await this.recordMetric({
|
|
1414
|
+
name: "usage/llm_tokens",
|
|
1415
|
+
value: metrics.llmTokens,
|
|
1416
|
+
type: "GAUGE" /* GAUGE */,
|
|
1417
|
+
labels: {
|
|
1418
|
+
organization_id: metrics.organizationId
|
|
1419
|
+
},
|
|
1420
|
+
timestamp: metrics.timestamp
|
|
1421
|
+
});
|
|
1422
|
+
await this.recordMetric({
|
|
1423
|
+
name: "usage/storage_bytes",
|
|
1424
|
+
value: metrics.storageBytes,
|
|
1425
|
+
type: "GAUGE" /* GAUGE */,
|
|
1426
|
+
labels: {
|
|
1427
|
+
organization_id: metrics.organizationId
|
|
1428
|
+
},
|
|
1429
|
+
unit: "bytes",
|
|
1430
|
+
timestamp: metrics.timestamp
|
|
1431
|
+
});
|
|
1432
|
+
}
|
|
1433
|
+
/**
|
|
1434
|
+
* Record custom business metric
|
|
1435
|
+
*/
|
|
1436
|
+
async recordCounter(name, value = 1, labels) {
|
|
1437
|
+
await this.recordMetric({
|
|
1438
|
+
name,
|
|
1439
|
+
value,
|
|
1440
|
+
type: "COUNTER" /* COUNTER */,
|
|
1441
|
+
labels
|
|
1442
|
+
});
|
|
1443
|
+
}
|
|
1444
|
+
async recordGauge(name, value, labels) {
|
|
1445
|
+
await this.recordMetric({
|
|
1446
|
+
name,
|
|
1447
|
+
value,
|
|
1448
|
+
type: "GAUGE" /* GAUGE */,
|
|
1449
|
+
labels
|
|
1450
|
+
});
|
|
1451
|
+
}
|
|
1452
|
+
async recordHistogram(name, value, labels, unit) {
|
|
1453
|
+
await this.recordMetric({
|
|
1454
|
+
name,
|
|
1455
|
+
value,
|
|
1456
|
+
type: "HISTOGRAM" /* HISTOGRAM */,
|
|
1457
|
+
labels,
|
|
1458
|
+
unit
|
|
1459
|
+
});
|
|
1460
|
+
}
|
|
1461
|
+
};
|
|
1462
|
+
}
|
|
1463
|
+
});
|
|
1464
|
+
|
|
1465
|
+
// ../../packages/@company/observability/src/observability-service.ts
|
|
1466
|
+
function createObservabilityService(serviceName, projectId) {
|
|
1467
|
+
return new ObservabilityService(serviceName, projectId);
|
|
1468
|
+
}
|
|
1469
|
+
var ObservabilityService;
|
|
1470
|
+
var init_observability_service = __esm({
|
|
1471
|
+
"../../packages/@company/observability/src/observability-service.ts"() {
|
|
1472
|
+
"use strict";
|
|
1473
|
+
init_logger();
|
|
1474
|
+
init_metrics();
|
|
1475
|
+
init_types();
|
|
1476
|
+
ObservabilityService = class {
|
|
1477
|
+
logger;
|
|
1478
|
+
metrics;
|
|
1479
|
+
serviceName;
|
|
1480
|
+
constructor(serviceName, projectId) {
|
|
1481
|
+
this.serviceName = serviceName;
|
|
1482
|
+
this.logger = new StructuredLogger(serviceName, projectId);
|
|
1483
|
+
this.metrics = new MetricsService(serviceName, projectId);
|
|
1484
|
+
}
|
|
1485
|
+
/**
|
|
1486
|
+
* Track API request with both logging and metrics
|
|
1487
|
+
*/
|
|
1488
|
+
async trackAPIRequest(metrics, error2) {
|
|
1489
|
+
await this.metrics.recordAPICall(metrics);
|
|
1490
|
+
const { traceId, spanId } = TraceContext.getTrace();
|
|
1491
|
+
const severity = metrics.statusCode >= 500 ? "ERROR" /* ERROR */ : metrics.statusCode >= 400 ? "WARNING" /* WARNING */ : "INFO" /* INFO */;
|
|
1492
|
+
await this.logger.write({
|
|
1493
|
+
severity,
|
|
1494
|
+
message: `${metrics.method} ${metrics.endpoint} ${metrics.statusCode} ${metrics.duration}ms`,
|
|
1495
|
+
traceId: traceId || void 0,
|
|
1496
|
+
spanId: spanId || void 0,
|
|
1497
|
+
organizationId: metrics.organizationId,
|
|
1498
|
+
userId: metrics.userId,
|
|
1499
|
+
metadata: {
|
|
1500
|
+
endpoint: metrics.endpoint,
|
|
1501
|
+
method: metrics.method,
|
|
1502
|
+
statusCode: metrics.statusCode,
|
|
1503
|
+
duration: metrics.duration,
|
|
1504
|
+
error: error2 ? {
|
|
1505
|
+
message: error2.message,
|
|
1506
|
+
...process.env.NODE_ENV !== "production" && {
|
|
1507
|
+
stack: error2.stack
|
|
1508
|
+
}
|
|
1509
|
+
} : void 0
|
|
1510
|
+
}
|
|
1511
|
+
});
|
|
1512
|
+
}
|
|
1513
|
+
/**
|
|
1514
|
+
* Track LLM call with both logging and metrics
|
|
1515
|
+
*/
|
|
1516
|
+
async trackLLMCall(metrics, error2) {
|
|
1517
|
+
await this.metrics.recordLLMCall(metrics);
|
|
1518
|
+
const { traceId, spanId } = TraceContext.getTrace();
|
|
1519
|
+
const severity = metrics.success ? "INFO" /* INFO */ : "ERROR" /* ERROR */;
|
|
1520
|
+
await this.logger.write({
|
|
1521
|
+
severity,
|
|
1522
|
+
message: `LLM call to ${metrics.model}: ${metrics.totalTokens} tokens in ${metrics.duration}ms`,
|
|
1523
|
+
traceId: traceId || void 0,
|
|
1524
|
+
spanId: spanId || void 0,
|
|
1525
|
+
organizationId: metrics.organizationId,
|
|
1526
|
+
metadata: {
|
|
1527
|
+
model: metrics.model,
|
|
1528
|
+
inputTokens: metrics.inputTokens,
|
|
1529
|
+
outputTokens: metrics.outputTokens,
|
|
1530
|
+
totalTokens: metrics.totalTokens,
|
|
1531
|
+
duration: metrics.duration,
|
|
1532
|
+
success: metrics.success,
|
|
1533
|
+
error: error2 ? {
|
|
1534
|
+
message: error2.message,
|
|
1535
|
+
...process.env.NODE_ENV !== "production" && {
|
|
1536
|
+
stack: error2.stack
|
|
1537
|
+
}
|
|
1538
|
+
} : void 0
|
|
1539
|
+
}
|
|
1540
|
+
});
|
|
1541
|
+
}
|
|
1542
|
+
/**
|
|
1543
|
+
* Track data capture operation
|
|
1544
|
+
*/
|
|
1545
|
+
async trackDataCapture(metrics, error2) {
|
|
1546
|
+
await this.metrics.recordDataCapture(metrics);
|
|
1547
|
+
const { traceId, spanId } = TraceContext.getTrace();
|
|
1548
|
+
const severity = metrics.success ? "INFO" /* INFO */ : "ERROR" /* ERROR */;
|
|
1549
|
+
await this.logger.write({
|
|
1550
|
+
severity,
|
|
1551
|
+
message: `${metrics.integration} ${metrics.operation}: ${metrics.recordsProcessed} records in ${metrics.duration}ms`,
|
|
1552
|
+
traceId: traceId || void 0,
|
|
1553
|
+
spanId: spanId || void 0,
|
|
1554
|
+
metadata: {
|
|
1555
|
+
integration: metrics.integration,
|
|
1556
|
+
operation: metrics.operation,
|
|
1557
|
+
recordsProcessed: metrics.recordsProcessed,
|
|
1558
|
+
duration: metrics.duration,
|
|
1559
|
+
success: metrics.success,
|
|
1560
|
+
error: error2 ? {
|
|
1561
|
+
message: error2.message,
|
|
1562
|
+
...process.env.NODE_ENV !== "production" && {
|
|
1563
|
+
stack: error2.stack
|
|
1564
|
+
}
|
|
1565
|
+
} : void 0
|
|
1566
|
+
}
|
|
1567
|
+
});
|
|
1568
|
+
}
|
|
1569
|
+
/**
|
|
1570
|
+
* Track organization usage
|
|
1571
|
+
*/
|
|
1572
|
+
async trackUsage(metrics) {
|
|
1573
|
+
await this.metrics.recordUsage(metrics);
|
|
1574
|
+
await this.logger.info(
|
|
1575
|
+
`Usage recorded for organization ${metrics.organizationId}`,
|
|
1576
|
+
{
|
|
1577
|
+
apiCalls: metrics.apiCalls,
|
|
1578
|
+
llmTokens: metrics.llmTokens,
|
|
1579
|
+
storageBytes: metrics.storageBytes
|
|
1580
|
+
},
|
|
1581
|
+
{
|
|
1582
|
+
organizationId: metrics.organizationId
|
|
1583
|
+
}
|
|
1584
|
+
);
|
|
1585
|
+
}
|
|
1586
|
+
/**
|
|
1587
|
+
* Convenience methods for logging
|
|
1588
|
+
*/
|
|
1589
|
+
async debug(message, metadata) {
|
|
1590
|
+
const { traceId, spanId } = TraceContext.getTrace();
|
|
1591
|
+
await this.logger.debug(message, metadata, {
|
|
1592
|
+
traceId: traceId || void 0,
|
|
1593
|
+
spanId: spanId || void 0
|
|
1594
|
+
});
|
|
1595
|
+
}
|
|
1596
|
+
async info(message, metadata) {
|
|
1597
|
+
const { traceId, spanId } = TraceContext.getTrace();
|
|
1598
|
+
await this.logger.info(message, metadata, {
|
|
1599
|
+
traceId: traceId || void 0,
|
|
1600
|
+
spanId: spanId || void 0
|
|
1601
|
+
});
|
|
1602
|
+
}
|
|
1603
|
+
async warning(message, metadata) {
|
|
1604
|
+
const { traceId, spanId } = TraceContext.getTrace();
|
|
1605
|
+
await this.logger.warning(message, metadata, {
|
|
1606
|
+
traceId: traceId || void 0,
|
|
1607
|
+
spanId: spanId || void 0
|
|
1608
|
+
});
|
|
1609
|
+
}
|
|
1610
|
+
/**
|
|
1611
|
+
* Alias for warning() to match console.warn() convention
|
|
1612
|
+
*/
|
|
1613
|
+
async warn(message, metadata) {
|
|
1614
|
+
return this.warning(message, metadata);
|
|
1615
|
+
}
|
|
1616
|
+
async error(message, error2, metadata) {
|
|
1617
|
+
const { traceId, spanId } = TraceContext.getTrace();
|
|
1618
|
+
await this.logger.error(message, error2, metadata, {
|
|
1619
|
+
traceId: traceId || void 0,
|
|
1620
|
+
spanId: spanId || void 0
|
|
1621
|
+
});
|
|
1622
|
+
}
|
|
1623
|
+
async critical(message, error2, metadata) {
|
|
1624
|
+
const { traceId, spanId } = TraceContext.getTrace();
|
|
1625
|
+
await this.logger.critical(message, error2, metadata, {
|
|
1626
|
+
traceId: traceId || void 0,
|
|
1627
|
+
spanId: spanId || void 0
|
|
1628
|
+
});
|
|
1629
|
+
}
|
|
1630
|
+
/**
|
|
1631
|
+
* @deprecated No-op. Use `withTrace(fn)` instead.
|
|
1632
|
+
* Direct setTrace/endTrace are not safe under concurrency and have no effect
|
|
1633
|
+
* with the AsyncLocalStorage-based TraceContext.
|
|
1634
|
+
*/
|
|
1635
|
+
startTrace(traceId) {
|
|
1636
|
+
return traceId || TraceContext.generateTraceId();
|
|
1637
|
+
}
|
|
1638
|
+
/**
|
|
1639
|
+
* @deprecated No-op — AsyncLocalStorage context is automatically scoped.
|
|
1640
|
+
*/
|
|
1641
|
+
endTrace() {
|
|
1642
|
+
}
|
|
1643
|
+
/**
|
|
1644
|
+
* Run a function with automatic trace context.
|
|
1645
|
+
* Preferred API for background jobs and standalone traces.
|
|
1646
|
+
*/
|
|
1647
|
+
async withTrace(fn, traceId) {
|
|
1648
|
+
return TraceContext.runWithTrace(fn, traceId);
|
|
673
1649
|
}
|
|
674
1650
|
};
|
|
675
1651
|
}
|
|
676
1652
|
});
|
|
677
1653
|
|
|
1654
|
+
// ../../packages/@company/observability/src/middleware.ts
|
|
1655
|
+
var init_middleware = __esm({
|
|
1656
|
+
"../../packages/@company/observability/src/middleware.ts"() {
|
|
1657
|
+
"use strict";
|
|
1658
|
+
init_logger();
|
|
1659
|
+
}
|
|
1660
|
+
});
|
|
1661
|
+
|
|
1662
|
+
// ../../packages/@company/observability/src/health.ts
|
|
1663
|
+
var init_health = __esm({
|
|
1664
|
+
"../../packages/@company/observability/src/health.ts"() {
|
|
1665
|
+
"use strict";
|
|
1666
|
+
}
|
|
1667
|
+
});
|
|
1668
|
+
|
|
1669
|
+
// ../../packages/@company/observability/src/degradation.ts
|
|
1670
|
+
var init_degradation = __esm({
|
|
1671
|
+
"../../packages/@company/observability/src/degradation.ts"() {
|
|
1672
|
+
"use strict";
|
|
1673
|
+
init_types();
|
|
1674
|
+
init_observability_service();
|
|
1675
|
+
}
|
|
1676
|
+
});
|
|
1677
|
+
|
|
1678
|
+
// ../../packages/@company/observability/src/index.ts
|
|
1679
|
+
var defaultObservability, getDefaultObservability, observability;
|
|
1680
|
+
var init_src2 = __esm({
|
|
1681
|
+
"../../packages/@company/observability/src/index.ts"() {
|
|
1682
|
+
init_observability_service();
|
|
1683
|
+
init_observability_service();
|
|
1684
|
+
init_logger();
|
|
1685
|
+
init_metrics();
|
|
1686
|
+
init_middleware();
|
|
1687
|
+
init_health();
|
|
1688
|
+
init_degradation();
|
|
1689
|
+
init_types();
|
|
1690
|
+
defaultObservability = null;
|
|
1691
|
+
getDefaultObservability = () => {
|
|
1692
|
+
if (!defaultObservability) {
|
|
1693
|
+
defaultObservability = createObservabilityService(
|
|
1694
|
+
process.env.SERVICE_NAME || "haansi-platform"
|
|
1695
|
+
);
|
|
1696
|
+
}
|
|
1697
|
+
return defaultObservability;
|
|
1698
|
+
};
|
|
1699
|
+
observability = new Proxy(
|
|
1700
|
+
{},
|
|
1701
|
+
{
|
|
1702
|
+
get(_target, prop) {
|
|
1703
|
+
const instance = getDefaultObservability();
|
|
1704
|
+
const value = instance[prop];
|
|
1705
|
+
return typeof value === "function" ? value.bind(instance) : value;
|
|
1706
|
+
}
|
|
1707
|
+
}
|
|
1708
|
+
);
|
|
1709
|
+
}
|
|
1710
|
+
});
|
|
1711
|
+
|
|
678
1712
|
// ../service-capture/common/agents/types.ts
|
|
679
1713
|
var AGENT_IDS;
|
|
680
|
-
var
|
|
1714
|
+
var init_types2 = __esm({
|
|
681
1715
|
"../service-capture/common/agents/types.ts"() {
|
|
682
1716
|
"use strict";
|
|
683
1717
|
AGENT_IDS = ["claude-code", "codex"];
|
|
@@ -926,7 +1960,7 @@ __export(agents_exports, {
|
|
|
926
1960
|
var init_agents = __esm({
|
|
927
1961
|
"../service-capture/common/agents/index.ts"() {
|
|
928
1962
|
"use strict";
|
|
929
|
-
|
|
1963
|
+
init_types2();
|
|
930
1964
|
init_claude_code();
|
|
931
1965
|
init_codex();
|
|
932
1966
|
init_registry();
|
|
@@ -936,7 +1970,8 @@ var init_agents = __esm({
|
|
|
936
1970
|
// ../service-capture/claude-sessions/collector.ts
|
|
937
1971
|
var collector_exports = {};
|
|
938
1972
|
__export(collector_exports, {
|
|
939
|
-
collect: () => collect
|
|
1973
|
+
collect: () => collect,
|
|
1974
|
+
uploadSession: () => uploadSession
|
|
940
1975
|
});
|
|
941
1976
|
function edgeScrub(content) {
|
|
942
1977
|
let result = content;
|
|
@@ -1031,15 +2066,15 @@ function extractGitInfo(projectDir, sessionTimestamp, sessionBranch) {
|
|
|
1031
2066
|
}
|
|
1032
2067
|
return result;
|
|
1033
2068
|
}
|
|
1034
|
-
function
|
|
2069
|
+
function resolveToken2() {
|
|
1035
2070
|
if (process.env.HAANSI_TOKEN) return process.env.HAANSI_TOKEN;
|
|
1036
|
-
if ((0, import_fs3.existsSync)(
|
|
2071
|
+
if ((0, import_fs3.existsSync)(CREDENTIALS_FILE4)) {
|
|
1037
2072
|
try {
|
|
1038
|
-
const creds = JSON.parse((0, import_fs3.readFileSync)(
|
|
2073
|
+
const creds = JSON.parse((0, import_fs3.readFileSync)(CREDENTIALS_FILE4, "utf-8"));
|
|
1039
2074
|
if (creds.token) return creds.token;
|
|
1040
2075
|
} catch {
|
|
1041
2076
|
logger.warn("Could not parse credentials file", {
|
|
1042
|
-
file:
|
|
2077
|
+
file: CREDENTIALS_FILE4
|
|
1043
2078
|
});
|
|
1044
2079
|
}
|
|
1045
2080
|
}
|
|
@@ -1050,6 +2085,11 @@ function resolveAgentIds(agents) {
|
|
|
1050
2085
|
const installed = detectInstalled().map((a) => a.id);
|
|
1051
2086
|
return installed.length > 0 ? installed : ["claude-code"];
|
|
1052
2087
|
}
|
|
2088
|
+
function canResolveGit(session) {
|
|
2089
|
+
if (session.gitRemoteUrl || session.gitCommit) return true;
|
|
2090
|
+
if (!session.cwd) return false;
|
|
2091
|
+
return (0, import_fs3.existsSync)(effectiveGitDir(session.cwd));
|
|
2092
|
+
}
|
|
1053
2093
|
function discoverSessions(agentIds) {
|
|
1054
2094
|
const sessions = [];
|
|
1055
2095
|
for (const id of agentIds) {
|
|
@@ -1111,21 +2151,32 @@ async function uploadSession(sessionId, content, apiUrl2, token, agentSource, gi
|
|
|
1111
2151
|
if (gitInfo?.gitRemoteUrl) headers["x-git-remote-url"] = gitInfo.gitRemoteUrl;
|
|
1112
2152
|
if (gitInfo?.gitCommit) headers["x-git-commit"] = gitInfo.gitCommit;
|
|
1113
2153
|
if (gitInfo?.gitBranch) headers["x-git-branch"] = gitInfo.gitBranch;
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
2154
|
+
for (let attempt = 0; ; attempt += 1) {
|
|
2155
|
+
const response = await fetch(`${apiUrl2}/api/v1/capture/sessions/raw`, {
|
|
2156
|
+
method: "POST",
|
|
2157
|
+
headers,
|
|
2158
|
+
body: new Uint8Array(body)
|
|
2159
|
+
});
|
|
2160
|
+
if (response.ok) return;
|
|
2161
|
+
if (response.status === 429 && attempt < UPLOAD_RATE_LIMIT_RETRIES) {
|
|
2162
|
+
const retryAfter = Number(response.headers.get("Retry-After"));
|
|
2163
|
+
const waitMs = Number.isFinite(retryAfter) && retryAfter > 0 ? retryAfter * 1e3 : DEFAULT_RATE_LIMIT_WAIT_MS;
|
|
2164
|
+
await new Promise((resolve4) => setTimeout(resolve4, waitMs));
|
|
2165
|
+
continue;
|
|
2166
|
+
}
|
|
1120
2167
|
const text = await response.text().catch(() => "");
|
|
1121
|
-
|
|
2168
|
+
const err = new Error(
|
|
1122
2169
|
`Upload failed (${response.status}): ${text.slice(0, 200)}`
|
|
1123
2170
|
);
|
|
2171
|
+
if (response.status === 429) {
|
|
2172
|
+
err.rateLimited = true;
|
|
2173
|
+
}
|
|
2174
|
+
throw err;
|
|
1124
2175
|
}
|
|
1125
2176
|
}
|
|
1126
2177
|
async function collect(options) {
|
|
1127
|
-
const apiUrl2 = process.env.HAANSI_API_URL ??
|
|
1128
|
-
const token =
|
|
2178
|
+
const apiUrl2 = process.env.HAANSI_API_URL ?? DEFAULT_API_URL2;
|
|
2179
|
+
const token = resolveToken2();
|
|
1129
2180
|
if (!token && !options.dryRun) {
|
|
1130
2181
|
throw new Error(
|
|
1131
2182
|
"HAANSI_TOKEN is required. Set it as env var or in ~/.haansi/credentials.json"
|
|
@@ -1142,11 +2193,14 @@ async function collect(options) {
|
|
|
1142
2193
|
let uploaded = 0;
|
|
1143
2194
|
let skipped = 0;
|
|
1144
2195
|
let errors = 0;
|
|
2196
|
+
let deferred = 0;
|
|
1145
2197
|
const remoteMap = options.forceAll ? /* @__PURE__ */ new Map() : await getUploadedSessions(apiUrl2, token);
|
|
1146
2198
|
const toUpload = [];
|
|
1147
2199
|
for (const session of localSessions) {
|
|
1148
2200
|
const remote = remoteMap.get(session.sessionId);
|
|
1149
|
-
|
|
2201
|
+
const contentUnchanged = !!remote && remote.lineCount >= session.lineCount;
|
|
2202
|
+
const worthRetryingForGit = !remote?.hasGitMeta && canResolveGit(session);
|
|
2203
|
+
if (contentUnchanged && !worthRetryingForGit) {
|
|
1150
2204
|
skipped++;
|
|
1151
2205
|
} else {
|
|
1152
2206
|
toUpload.push(session);
|
|
@@ -1216,11 +2270,22 @@ async function collect(options) {
|
|
|
1216
2270
|
}
|
|
1217
2271
|
);
|
|
1218
2272
|
} catch (err) {
|
|
1219
|
-
|
|
1220
|
-
|
|
2273
|
+
if (err?.rateLimited) {
|
|
2274
|
+
deferred++;
|
|
2275
|
+
void logger.info(`Rate limited, will retry next run: ${shortId}`);
|
|
2276
|
+
} else {
|
|
2277
|
+
errors++;
|
|
2278
|
+
logger.error(`Failed to upload ${shortId}`, { err: err.message });
|
|
2279
|
+
}
|
|
1221
2280
|
}
|
|
1222
2281
|
}
|
|
1223
|
-
|
|
2282
|
+
if (deferred > 0) {
|
|
2283
|
+
void logger.info(
|
|
2284
|
+
`${deferred} session(s) deferred by the upload rate limit \u2014 they remain queued`,
|
|
2285
|
+
{ deferred, uploaded }
|
|
2286
|
+
);
|
|
2287
|
+
}
|
|
2288
|
+
return { uploaded, skipped, errors, deferred };
|
|
1224
2289
|
}
|
|
1225
2290
|
async function main() {
|
|
1226
2291
|
const forceAll = process.argv.includes("--force-all");
|
|
@@ -1228,14 +2293,18 @@ async function main() {
|
|
|
1228
2293
|
const limitIdx = process.argv.indexOf("--limit");
|
|
1229
2294
|
const limit = limitIdx !== -1 ? parseInt(process.argv[limitIdx + 1], 10) : void 0;
|
|
1230
2295
|
logger.info("Collector starting", { forceAll, dryRun });
|
|
1231
|
-
const {
|
|
2296
|
+
const {
|
|
2297
|
+
uploaded: _uploaded,
|
|
2298
|
+
skipped: _skipped,
|
|
2299
|
+
errors
|
|
2300
|
+
} = await collect({
|
|
1232
2301
|
forceAll,
|
|
1233
2302
|
dryRun,
|
|
1234
2303
|
limit
|
|
1235
2304
|
});
|
|
1236
2305
|
if (errors > 0) process.exit(1);
|
|
1237
2306
|
}
|
|
1238
|
-
var import_dotenv, import_path3, import_fs3, import_os3, import_zlib, import_child_process, logger,
|
|
2307
|
+
var import_dotenv, import_path3, import_fs3, import_os3, import_zlib, import_child_process, logger, DEFAULT_API_URL2, CREDENTIALS_FILE4, MIN_LINES, EDGE_SCRUB_PATTERNS, GIT_BIN_CANDIDATES, resolvedGitBin, UPLOAD_RATE_LIMIT_RETRIES, DEFAULT_RATE_LIMIT_WAIT_MS;
|
|
1239
2308
|
var init_collector = __esm({
|
|
1240
2309
|
"../service-capture/claude-sessions/collector.ts"() {
|
|
1241
2310
|
"use strict";
|
|
@@ -1245,12 +2314,13 @@ var init_collector = __esm({
|
|
|
1245
2314
|
import_os3 = require("os");
|
|
1246
2315
|
import_zlib = require("zlib");
|
|
1247
2316
|
import_child_process = require("child_process");
|
|
1248
|
-
|
|
2317
|
+
init_src2();
|
|
2318
|
+
init_service_urls();
|
|
1249
2319
|
init_agents();
|
|
1250
2320
|
(0, import_dotenv.config)({ path: (0, import_path3.resolve)(__dirname, "../../../.env") });
|
|
1251
2321
|
logger = createLogger("session-collector");
|
|
1252
|
-
|
|
1253
|
-
|
|
2322
|
+
DEFAULT_API_URL2 = SERVICE_URL_DEFAULTS.haansiApiBaseUrl;
|
|
2323
|
+
CREDENTIALS_FILE4 = (0, import_path3.join)((0, import_os3.homedir)(), ".haansi", "credentials.json");
|
|
1254
2324
|
MIN_LINES = 4;
|
|
1255
2325
|
EDGE_SCRUB_PATTERNS = [
|
|
1256
2326
|
{
|
|
@@ -1297,6 +2367,8 @@ var init_collector = __esm({
|
|
|
1297
2367
|
"/usr/local/bin/git",
|
|
1298
2368
|
"/usr/bin/git"
|
|
1299
2369
|
];
|
|
2370
|
+
UPLOAD_RATE_LIMIT_RETRIES = 2;
|
|
2371
|
+
DEFAULT_RATE_LIMIT_WAIT_MS = 6e4;
|
|
1300
2372
|
if (require.main === module) {
|
|
1301
2373
|
main().catch((err) => {
|
|
1302
2374
|
logger.error("Collector failed", err);
|
|
@@ -1306,44 +2378,6 @@ var init_collector = __esm({
|
|
|
1306
2378
|
}
|
|
1307
2379
|
});
|
|
1308
2380
|
|
|
1309
|
-
// src/lib/paths.ts
|
|
1310
|
-
function apiUrl() {
|
|
1311
|
-
return process.env.HAANSI_API_URL ?? DEFAULT_API_URL4;
|
|
1312
|
-
}
|
|
1313
|
-
function resolveToken2() {
|
|
1314
|
-
if (process.env.HAANSI_TOKEN) return process.env.HAANSI_TOKEN;
|
|
1315
|
-
if ((0, import_node_fs3.existsSync)(CREDENTIALS_FILE4)) {
|
|
1316
|
-
try {
|
|
1317
|
-
const creds = JSON.parse((0, import_node_fs3.readFileSync)(CREDENTIALS_FILE4, "utf-8"));
|
|
1318
|
-
if (typeof creds.token === "string" && creds.token) return creds.token;
|
|
1319
|
-
} catch {
|
|
1320
|
-
}
|
|
1321
|
-
}
|
|
1322
|
-
return null;
|
|
1323
|
-
}
|
|
1324
|
-
function resolveHaansiBin() {
|
|
1325
|
-
try {
|
|
1326
|
-
const binPath = (0, import_node_child_process2.execSync)("which haansi", { encoding: "utf-8" }).trim();
|
|
1327
|
-
if (binPath) return binPath;
|
|
1328
|
-
} catch {
|
|
1329
|
-
}
|
|
1330
|
-
return "haansi";
|
|
1331
|
-
}
|
|
1332
|
-
var import_node_fs3, import_node_path3, import_node_os3, import_node_child_process2, DEFAULT_API_URL4, HAANSI_DIR3, CREDENTIALS_FILE4, CONFIG_FILE;
|
|
1333
|
-
var init_paths = __esm({
|
|
1334
|
-
"src/lib/paths.ts"() {
|
|
1335
|
-
"use strict";
|
|
1336
|
-
import_node_fs3 = require("node:fs");
|
|
1337
|
-
import_node_path3 = require("node:path");
|
|
1338
|
-
import_node_os3 = require("node:os");
|
|
1339
|
-
import_node_child_process2 = require("node:child_process");
|
|
1340
|
-
DEFAULT_API_URL4 = "https://api.haansi.co";
|
|
1341
|
-
HAANSI_DIR3 = (0, import_node_path3.join)((0, import_node_os3.homedir)(), ".haansi");
|
|
1342
|
-
CREDENTIALS_FILE4 = (0, import_node_path3.join)(HAANSI_DIR3, "credentials.json");
|
|
1343
|
-
CONFIG_FILE = (0, import_node_path3.join)(HAANSI_DIR3, "config.json");
|
|
1344
|
-
}
|
|
1345
|
-
});
|
|
1346
|
-
|
|
1347
2381
|
// src/lib/agent-selection.ts
|
|
1348
2382
|
var agent_selection_exports = {};
|
|
1349
2383
|
__export(agent_selection_exports, {
|
|
@@ -1391,7 +2425,7 @@ function saveAgents(agents) {
|
|
|
1391
2425
|
}
|
|
1392
2426
|
}
|
|
1393
2427
|
cfg.agents = agents;
|
|
1394
|
-
(0, import_node_fs4.mkdirSync)(
|
|
2428
|
+
(0, import_node_fs4.mkdirSync)(HAANSI_DIR, { recursive: true });
|
|
1395
2429
|
(0, import_node_fs4.writeFileSync)(CONFIG_FILE, JSON.stringify(cfg, null, 2) + "\n", {
|
|
1396
2430
|
encoding: "utf-8",
|
|
1397
2431
|
mode: 384
|
|
@@ -1864,19 +2898,19 @@ var require_scheduler = __commonJS({
|
|
|
1864
2898
|
});
|
|
1865
2899
|
|
|
1866
2900
|
// ../../node_modules/node-cron/node_modules/uuid/dist/esm-node/rng.js
|
|
1867
|
-
function
|
|
1868
|
-
if (
|
|
1869
|
-
|
|
1870
|
-
|
|
2901
|
+
function rng2() {
|
|
2902
|
+
if (poolPtr2 > rnds8Pool2.length - 16) {
|
|
2903
|
+
import_crypto3.default.randomFillSync(rnds8Pool2);
|
|
2904
|
+
poolPtr2 = 0;
|
|
1871
2905
|
}
|
|
1872
|
-
return
|
|
2906
|
+
return rnds8Pool2.slice(poolPtr2, poolPtr2 += 16);
|
|
1873
2907
|
}
|
|
1874
|
-
var
|
|
1875
|
-
var
|
|
2908
|
+
var import_crypto3, rnds8Pool2, poolPtr2;
|
|
2909
|
+
var init_rng2 = __esm({
|
|
1876
2910
|
"../../node_modules/node-cron/node_modules/uuid/dist/esm-node/rng.js"() {
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
|
|
2911
|
+
import_crypto3 = __toESM(require("crypto"));
|
|
2912
|
+
rnds8Pool2 = new Uint8Array(256);
|
|
2913
|
+
poolPtr2 = rnds8Pool2.length;
|
|
1880
2914
|
}
|
|
1881
2915
|
});
|
|
1882
2916
|
|
|
@@ -1902,19 +2936,19 @@ var init_validate = __esm({
|
|
|
1902
2936
|
|
|
1903
2937
|
// ../../node_modules/node-cron/node_modules/uuid/dist/esm-node/stringify.js
|
|
1904
2938
|
function stringify(arr, offset = 0) {
|
|
1905
|
-
const uuid3 = (
|
|
2939
|
+
const uuid3 = (byteToHex2[arr[offset + 0]] + byteToHex2[arr[offset + 1]] + byteToHex2[arr[offset + 2]] + byteToHex2[arr[offset + 3]] + "-" + byteToHex2[arr[offset + 4]] + byteToHex2[arr[offset + 5]] + "-" + byteToHex2[arr[offset + 6]] + byteToHex2[arr[offset + 7]] + "-" + byteToHex2[arr[offset + 8]] + byteToHex2[arr[offset + 9]] + "-" + byteToHex2[arr[offset + 10]] + byteToHex2[arr[offset + 11]] + byteToHex2[arr[offset + 12]] + byteToHex2[arr[offset + 13]] + byteToHex2[arr[offset + 14]] + byteToHex2[arr[offset + 15]]).toLowerCase();
|
|
1906
2940
|
if (!validate_default(uuid3)) {
|
|
1907
2941
|
throw TypeError("Stringified UUID is invalid");
|
|
1908
2942
|
}
|
|
1909
2943
|
return uuid3;
|
|
1910
2944
|
}
|
|
1911
|
-
var
|
|
1912
|
-
var
|
|
2945
|
+
var byteToHex2, stringify_default;
|
|
2946
|
+
var init_stringify2 = __esm({
|
|
1913
2947
|
"../../node_modules/node-cron/node_modules/uuid/dist/esm-node/stringify.js"() {
|
|
1914
2948
|
init_validate();
|
|
1915
|
-
|
|
2949
|
+
byteToHex2 = [];
|
|
1916
2950
|
for (let i = 0; i < 256; ++i) {
|
|
1917
|
-
|
|
2951
|
+
byteToHex2.push((i + 256).toString(16).substr(1));
|
|
1918
2952
|
}
|
|
1919
2953
|
stringify_default = stringify;
|
|
1920
2954
|
}
|
|
@@ -1928,7 +2962,7 @@ function v1(options, buf, offset) {
|
|
|
1928
2962
|
let node = options.node || _nodeId;
|
|
1929
2963
|
let clockseq = options.clockseq !== void 0 ? options.clockseq : _clockseq;
|
|
1930
2964
|
if (node == null || clockseq == null) {
|
|
1931
|
-
const seedBytes = options.random || (options.rng ||
|
|
2965
|
+
const seedBytes = options.random || (options.rng || rng2)();
|
|
1932
2966
|
if (node == null) {
|
|
1933
2967
|
node = _nodeId = [seedBytes[0] | 1, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]];
|
|
1934
2968
|
}
|
|
@@ -1972,8 +3006,8 @@ function v1(options, buf, offset) {
|
|
|
1972
3006
|
var _nodeId, _clockseq, _lastMSecs, _lastNSecs, v1_default;
|
|
1973
3007
|
var init_v1 = __esm({
|
|
1974
3008
|
"../../node_modules/node-cron/node_modules/uuid/dist/esm-node/v1.js"() {
|
|
1975
|
-
|
|
1976
|
-
|
|
3009
|
+
init_rng2();
|
|
3010
|
+
init_stringify2();
|
|
1977
3011
|
_lastMSecs = 0;
|
|
1978
3012
|
_lastNSecs = 0;
|
|
1979
3013
|
v1_default = v1;
|
|
@@ -2059,7 +3093,7 @@ function v35_default(name, version3, hashfunc) {
|
|
|
2059
3093
|
var DNS, URL2;
|
|
2060
3094
|
var init_v35 = __esm({
|
|
2061
3095
|
"../../node_modules/node-cron/node_modules/uuid/dist/esm-node/v35.js"() {
|
|
2062
|
-
|
|
3096
|
+
init_stringify2();
|
|
2063
3097
|
init_parse();
|
|
2064
3098
|
DNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
|
|
2065
3099
|
URL2 = "6ba7b811-9dad-11d1-80b4-00c04fd430c8";
|
|
@@ -2073,12 +3107,12 @@ function md5(bytes) {
|
|
|
2073
3107
|
} else if (typeof bytes === "string") {
|
|
2074
3108
|
bytes = Buffer.from(bytes, "utf8");
|
|
2075
3109
|
}
|
|
2076
|
-
return
|
|
3110
|
+
return import_crypto4.default.createHash("md5").update(bytes).digest();
|
|
2077
3111
|
}
|
|
2078
|
-
var
|
|
3112
|
+
var import_crypto4, md5_default;
|
|
2079
3113
|
var init_md5 = __esm({
|
|
2080
3114
|
"../../node_modules/node-cron/node_modules/uuid/dist/esm-node/md5.js"() {
|
|
2081
|
-
|
|
3115
|
+
import_crypto4 = __toESM(require("crypto"));
|
|
2082
3116
|
md5_default = md5;
|
|
2083
3117
|
}
|
|
2084
3118
|
});
|
|
@@ -2095,9 +3129,9 @@ var init_v3 = __esm({
|
|
|
2095
3129
|
});
|
|
2096
3130
|
|
|
2097
3131
|
// ../../node_modules/node-cron/node_modules/uuid/dist/esm-node/v4.js
|
|
2098
|
-
function
|
|
3132
|
+
function v42(options, buf, offset) {
|
|
2099
3133
|
options = options || {};
|
|
2100
|
-
const rnds = options.random || (options.rng ||
|
|
3134
|
+
const rnds = options.random || (options.rng || rng2)();
|
|
2101
3135
|
rnds[6] = rnds[6] & 15 | 64;
|
|
2102
3136
|
rnds[8] = rnds[8] & 63 | 128;
|
|
2103
3137
|
if (buf) {
|
|
@@ -2109,12 +3143,12 @@ function v4(options, buf, offset) {
|
|
|
2109
3143
|
}
|
|
2110
3144
|
return stringify_default(rnds);
|
|
2111
3145
|
}
|
|
2112
|
-
var
|
|
2113
|
-
var
|
|
3146
|
+
var v4_default2;
|
|
3147
|
+
var init_v42 = __esm({
|
|
2114
3148
|
"../../node_modules/node-cron/node_modules/uuid/dist/esm-node/v4.js"() {
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
3149
|
+
init_rng2();
|
|
3150
|
+
init_stringify2();
|
|
3151
|
+
v4_default2 = v42;
|
|
2118
3152
|
}
|
|
2119
3153
|
});
|
|
2120
3154
|
|
|
@@ -2125,12 +3159,12 @@ function sha1(bytes) {
|
|
|
2125
3159
|
} else if (typeof bytes === "string") {
|
|
2126
3160
|
bytes = Buffer.from(bytes, "utf8");
|
|
2127
3161
|
}
|
|
2128
|
-
return
|
|
3162
|
+
return import_crypto5.default.createHash("sha1").update(bytes).digest();
|
|
2129
3163
|
}
|
|
2130
|
-
var
|
|
3164
|
+
var import_crypto5, sha1_default;
|
|
2131
3165
|
var init_sha1 = __esm({
|
|
2132
3166
|
"../../node_modules/node-cron/node_modules/uuid/dist/esm-node/sha1.js"() {
|
|
2133
|
-
|
|
3167
|
+
import_crypto5 = __toESM(require("crypto"));
|
|
2134
3168
|
sha1_default = sha1;
|
|
2135
3169
|
}
|
|
2136
3170
|
});
|
|
@@ -2177,21 +3211,21 @@ __export(esm_node_exports, {
|
|
|
2177
3211
|
stringify: () => stringify_default,
|
|
2178
3212
|
v1: () => v1_default,
|
|
2179
3213
|
v3: () => v3_default,
|
|
2180
|
-
v4: () =>
|
|
3214
|
+
v4: () => v4_default2,
|
|
2181
3215
|
v5: () => v5_default,
|
|
2182
3216
|
validate: () => validate_default,
|
|
2183
3217
|
version: () => version_default
|
|
2184
3218
|
});
|
|
2185
|
-
var
|
|
3219
|
+
var init_esm_node2 = __esm({
|
|
2186
3220
|
"../../node_modules/node-cron/node_modules/uuid/dist/esm-node/index.js"() {
|
|
2187
3221
|
init_v1();
|
|
2188
3222
|
init_v3();
|
|
2189
|
-
|
|
3223
|
+
init_v42();
|
|
2190
3224
|
init_v5();
|
|
2191
3225
|
init_nil();
|
|
2192
3226
|
init_version();
|
|
2193
3227
|
init_validate();
|
|
2194
|
-
|
|
3228
|
+
init_stringify2();
|
|
2195
3229
|
init_parse();
|
|
2196
3230
|
}
|
|
2197
3231
|
});
|
|
@@ -2203,7 +3237,7 @@ var require_scheduled_task = __commonJS({
|
|
|
2203
3237
|
var EventEmitter = require("events");
|
|
2204
3238
|
var Task = require_task();
|
|
2205
3239
|
var Scheduler = require_scheduler();
|
|
2206
|
-
var uuid3 = (
|
|
3240
|
+
var uuid3 = (init_esm_node2(), __toCommonJS(esm_node_exports));
|
|
2207
3241
|
var ScheduledTask = class extends EventEmitter {
|
|
2208
3242
|
constructor(cronExpression, func, options) {
|
|
2209
3243
|
super();
|
|
@@ -2248,7 +3282,7 @@ var require_background_scheduled_task = __commonJS({
|
|
|
2248
3282
|
var EventEmitter = require("events");
|
|
2249
3283
|
var path = require("path");
|
|
2250
3284
|
var { fork } = require("child_process");
|
|
2251
|
-
var uuid3 = (
|
|
3285
|
+
var uuid3 = (init_esm_node2(), __toCommonJS(esm_node_exports));
|
|
2252
3286
|
var daemonPath = `${__dirname}/daemon.js`;
|
|
2253
3287
|
var BackgroundScheduledTask = class extends EventEmitter {
|
|
2254
3288
|
constructor(cronExpression, taskPath, options) {
|
|
@@ -2314,7 +3348,7 @@ var require_storage = __commonJS({
|
|
|
2314
3348
|
return {
|
|
2315
3349
|
save: (task) => {
|
|
2316
3350
|
if (!task.options) {
|
|
2317
|
-
const uuid3 = (
|
|
3351
|
+
const uuid3 = (init_esm_node2(), __toCommonJS(esm_node_exports));
|
|
2318
3352
|
task.options = {};
|
|
2319
3353
|
task.options.name = uuid3.v4();
|
|
2320
3354
|
}
|
|
@@ -2432,10 +3466,11 @@ var init_collector_daemon = __esm({
|
|
|
2432
3466
|
import_path4 = require("path");
|
|
2433
3467
|
import_node_cron = __toESM(require_node_cron());
|
|
2434
3468
|
init_collector();
|
|
2435
|
-
|
|
3469
|
+
init_src2();
|
|
2436
3470
|
(0, import_dotenv2.config)({ path: (0, import_path4.resolve)(__dirname, "../../../.env") });
|
|
2437
3471
|
logger2 = createLogger("collector-daemon");
|
|
2438
|
-
IN_MEMORY_VERSION =
|
|
3472
|
+
IN_MEMORY_VERSION = // eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
3473
|
+
require_package().version;
|
|
2439
3474
|
SCHEDULE = process.env.HAANSI_COLLECT_SCHEDULE ?? process.env.CLAUDE_COLLECT_SCHEDULE ?? "*/30 * * * *";
|
|
2440
3475
|
main2().catch((err) => {
|
|
2441
3476
|
logger2.error("Daemon failed to start", err);
|
|
@@ -2659,14 +3694,39 @@ var init_taxonomy = __esm({
|
|
|
2659
3694
|
});
|
|
2660
3695
|
|
|
2661
3696
|
// ../../packages/@company/types/src/embedding.ts
|
|
3697
|
+
var EMBEDDING_DEFAULTS, EMBEDDING_COLUMN, SUMMARY_EMBEDDING_COLUMN;
|
|
2662
3698
|
var init_embedding = __esm({
|
|
2663
3699
|
"../../packages/@company/types/src/embedding.ts"() {
|
|
2664
3700
|
"use strict";
|
|
3701
|
+
EMBEDDING_DEFAULTS = {
|
|
3702
|
+
// `as const` gives a literal string type for the provider field, which
|
|
3703
|
+
// is assignable to llm-client's LLMProvider union without forcing
|
|
3704
|
+
// @company/types to import that union (which would re-introduce the
|
|
3705
|
+
// dependency edge we want to keep absent).
|
|
3706
|
+
// CUTOVER (2026-07-17): in-house model is now the active config. Reads +
|
|
3707
|
+
// writes + backfills all target the local-768 columns. The old OpenAI 1536
|
|
3708
|
+
// columns (`embedding` / `summary_embedding`) are retained but dormant —
|
|
3709
|
+
// roll back by flipping this whole object back to
|
|
3710
|
+
// { provider:"openai", model:"text-embedding-3-small", dimensions:1536,
|
|
3711
|
+
// column:"embedding", summaryColumn:"summary_embedding" }
|
|
3712
|
+
// (a later contract migration drops the dormant columns). Readers alias
|
|
3713
|
+
// `<column> AS embedding` so result-row field names stay stable.
|
|
3714
|
+
provider: "local",
|
|
3715
|
+
model: "Alibaba-NLP/gte-base-en-v1.5",
|
|
3716
|
+
dimensions: 768,
|
|
3717
|
+
// The ACTIVE dense-vector column that every reader + writer + backfill targets.
|
|
3718
|
+
column: "embedding_v2",
|
|
3719
|
+
// The active summary-embedding column (process_registry's second vector,
|
|
3720
|
+
// used by the process matcher).
|
|
3721
|
+
summaryColumn: "summary_embedding_v2"
|
|
3722
|
+
};
|
|
3723
|
+
EMBEDDING_COLUMN = EMBEDDING_DEFAULTS.column;
|
|
3724
|
+
SUMMARY_EMBEDDING_COLUMN = EMBEDDING_DEFAULTS.summaryColumn;
|
|
2665
3725
|
}
|
|
2666
3726
|
});
|
|
2667
3727
|
|
|
2668
3728
|
// ../../packages/@company/types/src/index.ts
|
|
2669
|
-
var
|
|
3729
|
+
var init_src3 = __esm({
|
|
2670
3730
|
"../../packages/@company/types/src/index.ts"() {
|
|
2671
3731
|
init_timeline();
|
|
2672
3732
|
init_artifact();
|
|
@@ -3353,7 +4413,7 @@ function createZodEnum(values, params) {
|
|
|
3353
4413
|
});
|
|
3354
4414
|
}
|
|
3355
4415
|
var ParseInputLazyPath, handleResult, ZodType, cuidRegex, cuid2Regex, ulidRegex, uuidRegex, nanoidRegex, jwtRegex, durationRegex, emailRegex, _emojiRegex, emojiRegex, ipv4Regex, ipv4CidrRegex, ipv6Regex, ipv6CidrRegex, base64Regex, base64urlRegex, dateRegexSource, dateRegex, ZodString, ZodNumber, ZodBigInt, ZodBoolean, ZodDate, ZodSymbol, ZodUndefined, ZodNull, ZodAny, ZodUnknown, ZodNever, ZodVoid, ZodArray, ZodObject, ZodUnion, getDiscriminator, ZodDiscriminatedUnion, ZodIntersection, ZodTuple, ZodRecord, ZodMap, ZodSet, ZodFunction, ZodLazy, ZodLiteral, ZodEnum, ZodNativeEnum, ZodPromise, ZodEffects, ZodOptional, ZodNullable, ZodDefault, ZodCatch, ZodNaN, BRAND, ZodBranded, ZodPipeline, ZodReadonly, late, ZodFirstPartyTypeKind, stringType, numberType, nanType, bigIntType, booleanType, dateType, symbolType, undefinedType, nullType, anyType, unknownType, neverType, voidType, arrayType, objectType, strictObjectType, unionType, discriminatedUnionType, intersectionType, tupleType, recordType, mapType, setType, functionType, lazyType, literalType, enumType, nativeEnumType, promiseType, effectsType, optionalType, nullableType, preprocessType, pipelineType;
|
|
3356
|
-
var
|
|
4416
|
+
var init_types3 = __esm({
|
|
3357
4417
|
"../../node_modules/zod/v3/types.js"() {
|
|
3358
4418
|
init_ZodError();
|
|
3359
4419
|
init_errors();
|
|
@@ -6606,7 +7666,7 @@ var init_external = __esm({
|
|
|
6606
7666
|
init_parseUtil();
|
|
6607
7667
|
init_typeAliases();
|
|
6608
7668
|
init_util();
|
|
6609
|
-
|
|
7669
|
+
init_types3();
|
|
6610
7670
|
init_ZodError();
|
|
6611
7671
|
}
|
|
6612
7672
|
});
|
|
@@ -14367,7 +15427,7 @@ var init_classic = __esm({
|
|
|
14367
15427
|
});
|
|
14368
15428
|
|
|
14369
15429
|
// ../../node_modules/zod/v4/index.js
|
|
14370
|
-
var
|
|
15430
|
+
var init_v43 = __esm({
|
|
14371
15431
|
"../../node_modules/zod/v4/index.js"() {
|
|
14372
15432
|
init_classic();
|
|
14373
15433
|
init_classic();
|
|
@@ -14388,9 +15448,9 @@ function assertCompleteRequestResourceTemplate(request) {
|
|
|
14388
15448
|
void request;
|
|
14389
15449
|
}
|
|
14390
15450
|
var LATEST_PROTOCOL_VERSION, DEFAULT_NEGOTIATED_PROTOCOL_VERSION, SUPPORTED_PROTOCOL_VERSIONS, RELATED_TASK_META_KEY, JSONRPC_VERSION, AssertObjectSchema, ProgressTokenSchema, CursorSchema, TaskCreationParamsSchema, TaskMetadataSchema, RelatedTaskMetadataSchema, RequestMetaSchema, BaseRequestParamsSchema, TaskAugmentedRequestParamsSchema, isTaskAugmentedRequestParams, RequestSchema, NotificationsParamsSchema, NotificationSchema, ResultSchema, RequestIdSchema, JSONRPCRequestSchema, isJSONRPCRequest, JSONRPCNotificationSchema, isJSONRPCNotification, JSONRPCResultResponseSchema, isJSONRPCResultResponse, ErrorCode, JSONRPCErrorResponseSchema, isJSONRPCErrorResponse, JSONRPCMessageSchema, JSONRPCResponseSchema, EmptyResultSchema, CancelledNotificationParamsSchema, CancelledNotificationSchema, IconSchema, IconsSchema, BaseMetadataSchema, ImplementationSchema, FormElicitationCapabilitySchema, ElicitationCapabilitySchema, ClientTasksCapabilitySchema, ServerTasksCapabilitySchema, ClientCapabilitiesSchema, InitializeRequestParamsSchema, InitializeRequestSchema, isInitializeRequest, ServerCapabilitiesSchema, InitializeResultSchema, InitializedNotificationSchema, PingRequestSchema, ProgressSchema, ProgressNotificationParamsSchema, ProgressNotificationSchema, PaginatedRequestParamsSchema, PaginatedRequestSchema, PaginatedResultSchema, TaskStatusSchema, TaskSchema, CreateTaskResultSchema, TaskStatusNotificationParamsSchema, TaskStatusNotificationSchema, GetTaskRequestSchema, GetTaskResultSchema, GetTaskPayloadRequestSchema, GetTaskPayloadResultSchema, ListTasksRequestSchema, ListTasksResultSchema, CancelTaskRequestSchema, CancelTaskResultSchema, ResourceContentsSchema, TextResourceContentsSchema, Base64Schema, BlobResourceContentsSchema, RoleSchema, AnnotationsSchema, ResourceSchema, ResourceTemplateSchema, ListResourcesRequestSchema, ListResourcesResultSchema, ListResourceTemplatesRequestSchema, ListResourceTemplatesResultSchema, ResourceRequestParamsSchema, ReadResourceRequestParamsSchema, ReadResourceRequestSchema, ReadResourceResultSchema, ResourceListChangedNotificationSchema, SubscribeRequestParamsSchema, SubscribeRequestSchema, UnsubscribeRequestParamsSchema, UnsubscribeRequestSchema, ResourceUpdatedNotificationParamsSchema, ResourceUpdatedNotificationSchema, PromptArgumentSchema, PromptSchema, ListPromptsRequestSchema, ListPromptsResultSchema, GetPromptRequestParamsSchema, GetPromptRequestSchema, TextContentSchema, ImageContentSchema, AudioContentSchema, ToolUseContentSchema, EmbeddedResourceSchema, ResourceLinkSchema, ContentBlockSchema, PromptMessageSchema, GetPromptResultSchema, PromptListChangedNotificationSchema, ToolAnnotationsSchema, ToolExecutionSchema, ToolSchema, ListToolsRequestSchema, ListToolsResultSchema, CallToolResultSchema, CompatibilityCallToolResultSchema, CallToolRequestParamsSchema, CallToolRequestSchema, ToolListChangedNotificationSchema, ListChangedOptionsBaseSchema, LoggingLevelSchema, SetLevelRequestParamsSchema, SetLevelRequestSchema, LoggingMessageNotificationParamsSchema, LoggingMessageNotificationSchema, ModelHintSchema, ModelPreferencesSchema, ToolChoiceSchema, ToolResultContentSchema, SamplingContentSchema, SamplingMessageContentBlockSchema, SamplingMessageSchema, CreateMessageRequestParamsSchema, CreateMessageRequestSchema, CreateMessageResultSchema, CreateMessageResultWithToolsSchema, BooleanSchemaSchema, StringSchemaSchema, NumberSchemaSchema, UntitledSingleSelectEnumSchemaSchema, TitledSingleSelectEnumSchemaSchema, LegacyTitledEnumSchemaSchema, SingleSelectEnumSchemaSchema, UntitledMultiSelectEnumSchemaSchema, TitledMultiSelectEnumSchemaSchema, MultiSelectEnumSchemaSchema, EnumSchemaSchema, PrimitiveSchemaDefinitionSchema, ElicitRequestFormParamsSchema, ElicitRequestURLParamsSchema, ElicitRequestParamsSchema, ElicitRequestSchema, ElicitationCompleteNotificationParamsSchema, ElicitationCompleteNotificationSchema, ElicitResultSchema, ResourceTemplateReferenceSchema, PromptReferenceSchema, CompleteRequestParamsSchema, CompleteRequestSchema, CompleteResultSchema, RootSchema, ListRootsRequestSchema, ListRootsResultSchema, RootsListChangedNotificationSchema, ClientRequestSchema, ClientNotificationSchema, ClientResultSchema, ServerRequestSchema, ServerNotificationSchema, ServerResultSchema, McpError, UrlElicitationRequiredError;
|
|
14391
|
-
var
|
|
15451
|
+
var init_types4 = __esm({
|
|
14392
15452
|
"../service-capture/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js"() {
|
|
14393
|
-
|
|
15453
|
+
init_v43();
|
|
14394
15454
|
LATEST_PROTOCOL_VERSION = "2025-11-25";
|
|
14395
15455
|
DEFAULT_NEGOTIATED_PROTOCOL_VERSION = "2025-03-26";
|
|
14396
15456
|
SUPPORTED_PROTOCOL_VERSIONS = [LATEST_PROTOCOL_VERSION, "2025-06-18", "2025-03-26", "2024-11-05", "2024-10-07"];
|
|
@@ -17554,7 +18614,7 @@ var DEFAULT_REQUEST_TIMEOUT_MSEC, Protocol;
|
|
|
17554
18614
|
var init_protocol = __esm({
|
|
17555
18615
|
"../service-capture/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js"() {
|
|
17556
18616
|
init_zod_compat();
|
|
17557
|
-
|
|
18617
|
+
init_types4();
|
|
17558
18618
|
init_interfaces();
|
|
17559
18619
|
init_zod_json_schema_compat();
|
|
17560
18620
|
DEFAULT_REQUEST_TIMEOUT_MSEC = 6e4;
|
|
@@ -31136,7 +32196,7 @@ var Server;
|
|
|
31136
32196
|
var init_server2 = __esm({
|
|
31137
32197
|
"../service-capture/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js"() {
|
|
31138
32198
|
init_protocol();
|
|
31139
|
-
|
|
32199
|
+
init_types4();
|
|
31140
32200
|
init_ajv_provider();
|
|
31141
32201
|
init_zod_compat();
|
|
31142
32202
|
init_server();
|
|
@@ -31706,7 +32766,7 @@ var init_mcp = __esm({
|
|
|
31706
32766
|
init_server2();
|
|
31707
32767
|
init_zod_compat();
|
|
31708
32768
|
init_zod_json_schema_compat();
|
|
31709
|
-
|
|
32769
|
+
init_types4();
|
|
31710
32770
|
init_completable();
|
|
31711
32771
|
init_uriTemplate();
|
|
31712
32772
|
init_toolNameValidation();
|
|
@@ -32447,7 +33507,7 @@ function serializeMessage(message) {
|
|
|
32447
33507
|
var ReadBuffer;
|
|
32448
33508
|
var init_stdio = __esm({
|
|
32449
33509
|
"../service-capture/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js"() {
|
|
32450
|
-
|
|
33510
|
+
init_types4();
|
|
32451
33511
|
ReadBuffer = class {
|
|
32452
33512
|
append(chunk) {
|
|
32453
33513
|
this._buffer = this._buffer ? Buffer.concat([this._buffer, chunk]) : chunk;
|
|
@@ -51347,14 +52407,14 @@ var require_etag = __commonJS({
|
|
|
51347
52407
|
"../../node_modules/etag/index.js"(exports2, module2) {
|
|
51348
52408
|
"use strict";
|
|
51349
52409
|
module2.exports = etag;
|
|
51350
|
-
var
|
|
52410
|
+
var crypto8 = require("crypto");
|
|
51351
52411
|
var Stats = require("fs").Stats;
|
|
51352
52412
|
var toString = Object.prototype.toString;
|
|
51353
52413
|
function entitytag(entity) {
|
|
51354
52414
|
if (entity.length === 0) {
|
|
51355
52415
|
return '"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk"';
|
|
51356
52416
|
}
|
|
51357
|
-
var hash2 =
|
|
52417
|
+
var hash2 = crypto8.createHash("sha1").update(entity, "utf8").digest("base64").substring(0, 27);
|
|
51358
52418
|
var len = typeof entity === "string" ? Buffer.byteLength(entity, "utf8") : entity.length;
|
|
51359
52419
|
return '"' + len.toString(16) + "-" + hash2 + '"';
|
|
51360
52420
|
}
|
|
@@ -54769,17 +55829,17 @@ var require_content_disposition = __commonJS({
|
|
|
54769
55829
|
// ../service-capture/node_modules/cookie-signature/index.js
|
|
54770
55830
|
var require_cookie_signature = __commonJS({
|
|
54771
55831
|
"../service-capture/node_modules/cookie-signature/index.js"(exports2) {
|
|
54772
|
-
var
|
|
55832
|
+
var crypto8 = require("crypto");
|
|
54773
55833
|
exports2.sign = function(val, secret) {
|
|
54774
55834
|
if ("string" != typeof val) throw new TypeError("Cookie value must be provided as a string.");
|
|
54775
55835
|
if (null == secret) throw new TypeError("Secret key must be provided.");
|
|
54776
|
-
return val + "." +
|
|
55836
|
+
return val + "." + crypto8.createHmac("sha256", secret).update(val).digest("base64").replace(/\=+$/, "");
|
|
54777
55837
|
};
|
|
54778
55838
|
exports2.unsign = function(input, secret) {
|
|
54779
55839
|
if ("string" != typeof input) throw new TypeError("Signed cookie string must be provided.");
|
|
54780
55840
|
if (null == secret) throw new TypeError("Secret key must be provided.");
|
|
54781
55841
|
var tentativeValue = input.slice(0, input.lastIndexOf(".")), expectedInput = exports2.sign(tentativeValue, secret), expectedBuffer = Buffer.from(expectedInput), inputBuffer = Buffer.from(input);
|
|
54782
|
-
return expectedBuffer.length === inputBuffer.length &&
|
|
55842
|
+
return expectedBuffer.length === inputBuffer.length && crypto8.timingSafeEqual(expectedBuffer, inputBuffer) ? tentativeValue : false;
|
|
54783
55843
|
};
|
|
54784
55844
|
}
|
|
54785
55845
|
});
|
|
@@ -56174,13 +57234,13 @@ function writeFromReadableStream(stream, writable) {
|
|
|
56174
57234
|
}
|
|
56175
57235
|
return writeFromReadableStreamDefaultReader(stream.getReader(), writable);
|
|
56176
57236
|
}
|
|
56177
|
-
var import_http2, import_http22, import_stream,
|
|
57237
|
+
var import_http2, import_http22, import_stream, import_crypto6, RequestError, toRequestError, GlobalRequest, Request, newHeadersFromIncoming, wrapBodyStream, newRequestFromIncoming, getRequestCache, requestCache, incomingKey, urlKey, headersKey, abortControllerKey, getAbortController, requestPrototype, newRequest, responseCache, getResponseCache, cacheKey, GlobalResponse, Response2, buildOutgoingHttpHeaders, X_ALREADY_SENT, outgoingEnded, handleRequestError, handleFetchError, handleResponseError, flushHeaders, responseViaCache, isPromise, responseViaResponseObject, getRequestListener;
|
|
56178
57238
|
var init_dist = __esm({
|
|
56179
57239
|
"../../node_modules/@hono/node-server/dist/index.mjs"() {
|
|
56180
57240
|
import_http2 = require("http2");
|
|
56181
57241
|
import_http22 = require("http2");
|
|
56182
57242
|
import_stream = require("stream");
|
|
56183
|
-
|
|
57243
|
+
import_crypto6 = __toESM(require("crypto"), 1);
|
|
56184
57244
|
RequestError = class extends Error {
|
|
56185
57245
|
constructor(message, options) {
|
|
56186
57246
|
super(message, options);
|
|
@@ -56450,7 +57510,7 @@ var init_dist = __esm({
|
|
|
56450
57510
|
};
|
|
56451
57511
|
X_ALREADY_SENT = "x-hono-already-sent";
|
|
56452
57512
|
if (typeof global.crypto === "undefined") {
|
|
56453
|
-
global.crypto =
|
|
57513
|
+
global.crypto = import_crypto6.default;
|
|
56454
57514
|
}
|
|
56455
57515
|
outgoingEnded = Symbol("outgoingEnded");
|
|
56456
57516
|
handleRequestError = () => new Response(null, {
|
|
@@ -56669,7 +57729,7 @@ var init_dist = __esm({
|
|
|
56669
57729
|
var WebStandardStreamableHTTPServerTransport;
|
|
56670
57730
|
var init_webStandardStreamableHttp = __esm({
|
|
56671
57731
|
"../service-capture/node_modules/@modelcontextprotocol/sdk/dist/esm/server/webStandardStreamableHttp.js"() {
|
|
56672
|
-
|
|
57732
|
+
init_types4();
|
|
56673
57733
|
WebStandardStreamableHTTPServerTransport = class {
|
|
56674
57734
|
constructor(options = {}) {
|
|
56675
57735
|
this._started = false;
|
|
@@ -57459,7 +58519,7 @@ async function main3() {
|
|
|
57459
58519
|
}
|
|
57460
58520
|
warmupInBackground();
|
|
57461
58521
|
}
|
|
57462
|
-
var import_dotenv3, import_path5, import_fs5, import_os4,
|
|
58522
|
+
var import_dotenv3, import_path5, import_fs5, import_os4, DEFAULT_API_URL3, CREDENTIALS_FILE5, API_URL, AGENT_SOURCE, DEFAULT_SOURCE_TOOL, TOKEN, contextSchema, isCollecting, lastCollectTime, COLLECT_COOLDOWN_MS, mcpServer, server;
|
|
57463
58523
|
var init_mcp_server2 = __esm({
|
|
57464
58524
|
"../service-capture/claude-sessions/mcp-server.ts"() {
|
|
57465
58525
|
"use strict";
|
|
@@ -57469,14 +58529,17 @@ var init_mcp_server2 = __esm({
|
|
|
57469
58529
|
import_os4 = require("os");
|
|
57470
58530
|
init_collector();
|
|
57471
58531
|
init_http_timeout();
|
|
57472
|
-
|
|
58532
|
+
init_service_urls();
|
|
58533
|
+
init_src3();
|
|
57473
58534
|
init_mcp();
|
|
57474
58535
|
init_stdio2();
|
|
57475
|
-
|
|
58536
|
+
init_types4();
|
|
57476
58537
|
(0, import_dotenv3.config)({ path: (0, import_path5.resolve)(__dirname, "../../../.env") });
|
|
57477
|
-
|
|
58538
|
+
DEFAULT_API_URL3 = SERVICE_URL_DEFAULTS.haansiApiBaseUrl;
|
|
57478
58539
|
CREDENTIALS_FILE5 = (0, import_path5.join)((0, import_os4.homedir)(), ".haansi", "credentials.json");
|
|
57479
|
-
API_URL = process.env.HAANSI_API_URL ??
|
|
58540
|
+
API_URL = process.env.HAANSI_API_URL ?? DEFAULT_API_URL3;
|
|
58541
|
+
AGENT_SOURCE = process.env.HAANSI_AGENT_SOURCE?.toLowerCase();
|
|
58542
|
+
DEFAULT_SOURCE_TOOL = AGENT_SOURCE === "codex" ? "codex-mcp" : "claude-code-mcp";
|
|
57480
58543
|
TOKEN = resolveToken3();
|
|
57481
58544
|
if (!TOKEN) {
|
|
57482
58545
|
process.exit(1);
|
|
@@ -57616,7 +58679,7 @@ var init_mcp_server2 = __esm({
|
|
|
57616
58679
|
},
|
|
57617
58680
|
source_tool: {
|
|
57618
58681
|
type: "string",
|
|
57619
|
-
description:
|
|
58682
|
+
description: `Tool that saved this (default: "${DEFAULT_SOURCE_TOOL}")`
|
|
57620
58683
|
},
|
|
57621
58684
|
_context: contextSchema
|
|
57622
58685
|
},
|
|
@@ -57735,7 +58798,7 @@ var init_mcp_server2 = __esm({
|
|
|
57735
58798
|
git_commit,
|
|
57736
58799
|
tags,
|
|
57737
58800
|
model,
|
|
57738
|
-
source_tool
|
|
58801
|
+
source_tool: source_tool ?? DEFAULT_SOURCE_TOOL
|
|
57739
58802
|
},
|
|
57740
58803
|
{ extraHeaders }
|
|
57741
58804
|
);
|
|
@@ -57830,7 +58893,7 @@ function parseTarget(arg) {
|
|
|
57830
58893
|
);
|
|
57831
58894
|
}
|
|
57832
58895
|
function exchangeUrl() {
|
|
57833
|
-
return `${apiUrl().replace(/\/+$/, "")}/api/v1/
|
|
58896
|
+
return `${apiUrl().replace(/\/+$/, "")}/api/v1/memory/exchange/mcp`;
|
|
57834
58897
|
}
|
|
57835
58898
|
function setupClaudeMcp(target) {
|
|
57836
58899
|
let config6 = {};
|
|
@@ -57850,12 +58913,13 @@ function setupClaudeMcp(target) {
|
|
|
57850
58913
|
const haansiBin = resolveHaansiBin();
|
|
57851
58914
|
config6.mcpServers["haansi-solutions"] = {
|
|
57852
58915
|
command: haansiBin,
|
|
57853
|
-
args: ["mcp-server"]
|
|
58916
|
+
args: ["mcp-server"],
|
|
58917
|
+
env: { HAANSI_AGENT_SOURCE: "claude-code" }
|
|
57854
58918
|
};
|
|
57855
58919
|
installed.push(`haansi-solutions (stdio \u2192 ${haansiBin} mcp-server)`);
|
|
57856
58920
|
}
|
|
57857
58921
|
if (target === "all" || target === "exchange") {
|
|
57858
|
-
const token =
|
|
58922
|
+
const token = resolveToken();
|
|
57859
58923
|
if (!token) {
|
|
57860
58924
|
warnings.push(
|
|
57861
58925
|
"haansi-exchange not registered: no token found. Run `haansi auth login` first, or set HAANSI_TOKEN."
|
|
@@ -57894,12 +58958,13 @@ function setupCodexMcp(target) {
|
|
|
57894
58958
|
const haansiBin = resolveHaansiBin();
|
|
57895
58959
|
content = upsertTomlTable(content, "mcp_servers.haansi-solutions", {
|
|
57896
58960
|
command: tomlString(haansiBin),
|
|
57897
|
-
args: tomlStringArray(["mcp-server"])
|
|
58961
|
+
args: tomlStringArray(["mcp-server"]),
|
|
58962
|
+
env: tomlInlineTable({ HAANSI_AGENT_SOURCE: "codex" })
|
|
57898
58963
|
});
|
|
57899
58964
|
installed.push(`haansi-solutions (stdio \u2192 ${haansiBin} mcp-server)`);
|
|
57900
58965
|
}
|
|
57901
58966
|
if (target === "all" || target === "exchange") {
|
|
57902
|
-
const token =
|
|
58967
|
+
const token = resolveToken();
|
|
57903
58968
|
if (!token) {
|
|
57904
58969
|
warnings.push(
|
|
57905
58970
|
"haansi-exchange not registered: no token found. Run `haansi auth login` first, or set HAANSI_TOKEN."
|
|
@@ -58096,7 +59161,7 @@ async function config5(args) {
|
|
|
58096
59161
|
process.exit(1);
|
|
58097
59162
|
return;
|
|
58098
59163
|
}
|
|
58099
|
-
const apiUrl2 =
|
|
59164
|
+
const apiUrl2 = apiUrl();
|
|
58100
59165
|
const subcommand = args[0];
|
|
58101
59166
|
if (subcommand === "get") {
|
|
58102
59167
|
const key = args[1];
|
|
@@ -58177,14 +59242,14 @@ Supported keys:
|
|
|
58177
59242
|
if (subcommand !== void 0) process.exit(1);
|
|
58178
59243
|
}
|
|
58179
59244
|
}
|
|
58180
|
-
var import_node_fs7, import_node_path6, import_node_os6,
|
|
59245
|
+
var import_node_fs7, import_node_path6, import_node_os6, CREDENTIALS_FILE6, VALID_SESSION_MODES;
|
|
58181
59246
|
var init_config = __esm({
|
|
58182
59247
|
"src/commands/config.ts"() {
|
|
58183
59248
|
"use strict";
|
|
58184
59249
|
import_node_fs7 = require("node:fs");
|
|
58185
59250
|
import_node_path6 = require("node:path");
|
|
58186
59251
|
import_node_os6 = require("node:os");
|
|
58187
|
-
|
|
59252
|
+
init_paths();
|
|
58188
59253
|
CREDENTIALS_FILE6 = (0, import_node_path6.join)((0, import_node_os6.homedir)(), ".haansi", "credentials.json");
|
|
58189
59254
|
VALID_SESSION_MODES = ["private", "org"];
|
|
58190
59255
|
}
|
|
@@ -58235,7 +59300,7 @@ async function apiPost2(path, body, token, apiUrl2) {
|
|
|
58235
59300
|
return response.json();
|
|
58236
59301
|
}
|
|
58237
59302
|
async function list(options) {
|
|
58238
|
-
const apiUrl2 =
|
|
59303
|
+
const apiUrl2 = apiUrl();
|
|
58239
59304
|
const token = resolveToken5();
|
|
58240
59305
|
let data;
|
|
58241
59306
|
if (options.search) {
|
|
@@ -58261,7 +59326,7 @@ async function list(options) {
|
|
|
58261
59326
|
${data.results.length} result(s)`);
|
|
58262
59327
|
}
|
|
58263
59328
|
async function searchKnowledge(options) {
|
|
58264
|
-
const apiUrl2 =
|
|
59329
|
+
const apiUrl2 = apiUrl();
|
|
58265
59330
|
const token = resolveToken5();
|
|
58266
59331
|
let url2 = `/memory/solutions/knowledge/search?q=${encodeURIComponent(options.query)}&limit=${options.limit}`;
|
|
58267
59332
|
if (options.artifactType) {
|
|
@@ -58278,7 +59343,7 @@ async function searchKnowledge(options) {
|
|
|
58278
59343
|
${data.results.length} result(s)`);
|
|
58279
59344
|
}
|
|
58280
59345
|
async function saveKnowledge(options) {
|
|
58281
|
-
const apiUrl2 =
|
|
59346
|
+
const apiUrl2 = apiUrl();
|
|
58282
59347
|
const token = resolveToken5();
|
|
58283
59348
|
const body = {
|
|
58284
59349
|
problem_description: options.problem,
|
|
@@ -58299,19 +59364,20 @@ async function saveKnowledge(options) {
|
|
|
58299
59364
|
console.log(` Solution: ${data.solution_summary}`);
|
|
58300
59365
|
console.log("\nThis is now searchable via `haansi search-solutions`.");
|
|
58301
59366
|
}
|
|
58302
|
-
var import_node_fs8, import_node_path7, import_node_os7,
|
|
59367
|
+
var import_node_fs8, import_node_path7, import_node_os7, CREDENTIALS_FILE7;
|
|
58303
59368
|
var init_list = __esm({
|
|
58304
59369
|
"src/commands/list.ts"() {
|
|
58305
59370
|
"use strict";
|
|
58306
59371
|
import_node_fs8 = require("node:fs");
|
|
58307
59372
|
import_node_path7 = require("node:path");
|
|
58308
59373
|
import_node_os7 = require("node:os");
|
|
58309
|
-
|
|
59374
|
+
init_paths();
|
|
58310
59375
|
CREDENTIALS_FILE7 = (0, import_node_path7.join)((0, import_node_os7.homedir)(), ".haansi", "credentials.json");
|
|
58311
59376
|
}
|
|
58312
59377
|
});
|
|
58313
59378
|
|
|
58314
59379
|
// src/index.ts
|
|
59380
|
+
init_paths();
|
|
58315
59381
|
var { version: VERSION } = require_package();
|
|
58316
59382
|
var command = process.argv[2];
|
|
58317
59383
|
function getFlag(flag) {
|
|
@@ -58535,7 +59601,7 @@ Options for collect:
|
|
|
58535
59601
|
|
|
58536
59602
|
Environment variables:
|
|
58537
59603
|
HAANSI_TOKEN API token (or use \`haansi init\` to save it)
|
|
58538
|
-
HAANSI_API_URL API base URL (default:
|
|
59604
|
+
HAANSI_API_URL API base URL (default: ${DEFAULT_API_URL})
|
|
58539
59605
|
CODEX_HOME Codex home dir (default: ~/.codex)
|
|
58540
59606
|
HAANSI_AGENTS Daemon: comma-separated agents (claude-code,codex)
|
|
58541
59607
|
HAANSI_COLLECT_SCHEDULE Cron expression for daemon (default: */30 * * * *)
|