haansi 0.1.28 → 0.1.30
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 +1264 -199
- 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.30",
|
|
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,1028 @@ 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);
|
|
741
|
+
}
|
|
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 };
|
|
630
987
|
}
|
|
631
|
-
|
|
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
|
+
});
|
|
669
1287
|
}
|
|
670
1288
|
}
|
|
671
|
-
|
|
672
|
-
|
|
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
|
+
});
|
|
1352
|
+
}
|
|
1353
|
+
}
|
|
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
|
+
});
|
|
673
1460
|
}
|
|
674
1461
|
};
|
|
675
1462
|
}
|
|
676
1463
|
});
|
|
677
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);
|
|
1649
|
+
}
|
|
1650
|
+
};
|
|
1651
|
+
}
|
|
1652
|
+
});
|
|
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/index.ts
|
|
1670
|
+
var defaultObservability, getDefaultObservability, observability;
|
|
1671
|
+
var init_src2 = __esm({
|
|
1672
|
+
"../../packages/@company/observability/src/index.ts"() {
|
|
1673
|
+
init_observability_service();
|
|
1674
|
+
init_observability_service();
|
|
1675
|
+
init_logger();
|
|
1676
|
+
init_metrics();
|
|
1677
|
+
init_middleware();
|
|
1678
|
+
init_health();
|
|
1679
|
+
defaultObservability = null;
|
|
1680
|
+
getDefaultObservability = () => {
|
|
1681
|
+
if (!defaultObservability) {
|
|
1682
|
+
defaultObservability = createObservabilityService(
|
|
1683
|
+
process.env.SERVICE_NAME || "haansi-platform"
|
|
1684
|
+
);
|
|
1685
|
+
}
|
|
1686
|
+
return defaultObservability;
|
|
1687
|
+
};
|
|
1688
|
+
observability = new Proxy(
|
|
1689
|
+
{},
|
|
1690
|
+
{
|
|
1691
|
+
get(_target, prop) {
|
|
1692
|
+
const instance = getDefaultObservability();
|
|
1693
|
+
const value = instance[prop];
|
|
1694
|
+
return typeof value === "function" ? value.bind(instance) : value;
|
|
1695
|
+
}
|
|
1696
|
+
}
|
|
1697
|
+
);
|
|
1698
|
+
}
|
|
1699
|
+
});
|
|
1700
|
+
|
|
678
1701
|
// ../service-capture/common/agents/types.ts
|
|
679
1702
|
var AGENT_IDS;
|
|
680
|
-
var
|
|
1703
|
+
var init_types2 = __esm({
|
|
681
1704
|
"../service-capture/common/agents/types.ts"() {
|
|
682
1705
|
"use strict";
|
|
683
1706
|
AGENT_IDS = ["claude-code", "codex"];
|
|
@@ -926,7 +1949,7 @@ __export(agents_exports, {
|
|
|
926
1949
|
var init_agents = __esm({
|
|
927
1950
|
"../service-capture/common/agents/index.ts"() {
|
|
928
1951
|
"use strict";
|
|
929
|
-
|
|
1952
|
+
init_types2();
|
|
930
1953
|
init_claude_code();
|
|
931
1954
|
init_codex();
|
|
932
1955
|
init_registry();
|
|
@@ -945,24 +1968,54 @@ function edgeScrub(content) {
|
|
|
945
1968
|
}
|
|
946
1969
|
return result;
|
|
947
1970
|
}
|
|
1971
|
+
function resolveGitBin() {
|
|
1972
|
+
if (resolvedGitBin !== void 0) return resolvedGitBin;
|
|
1973
|
+
for (const bin of GIT_BIN_CANDIDATES) {
|
|
1974
|
+
try {
|
|
1975
|
+
(0, import_child_process.execFileSync)(bin, ["--version"], { timeout: 5e3, stdio: "pipe" });
|
|
1976
|
+
resolvedGitBin = bin;
|
|
1977
|
+
return bin;
|
|
1978
|
+
} catch {
|
|
1979
|
+
}
|
|
1980
|
+
}
|
|
1981
|
+
resolvedGitBin = null;
|
|
1982
|
+
return null;
|
|
1983
|
+
}
|
|
1984
|
+
function effectiveGitDir(cwd) {
|
|
1985
|
+
if ((0, import_fs3.existsSync)(cwd)) return cwd;
|
|
1986
|
+
const m = cwd.match(/^(.*)\/\.claude\/worktrees\/[^/]+/);
|
|
1987
|
+
if (m && (0, import_fs3.existsSync)(m[1])) return m[1];
|
|
1988
|
+
return cwd;
|
|
1989
|
+
}
|
|
948
1990
|
function extractGitInfo(projectDir, sessionTimestamp, sessionBranch) {
|
|
949
1991
|
const empty = {
|
|
950
1992
|
gitRemoteUrl: null,
|
|
951
1993
|
gitCommit: null,
|
|
952
1994
|
gitBranch: null
|
|
953
1995
|
};
|
|
1996
|
+
const gitBin = resolveGitBin();
|
|
1997
|
+
if (!gitBin) {
|
|
1998
|
+
logger.warn("Git metadata skipped \u2014 git binary not found", {
|
|
1999
|
+
projectDir,
|
|
2000
|
+
reason: "git-not-on-path",
|
|
2001
|
+
tried: GIT_BIN_CANDIDATES
|
|
2002
|
+
});
|
|
2003
|
+
return empty;
|
|
2004
|
+
}
|
|
2005
|
+
const dir = effectiveGitDir(projectDir);
|
|
954
2006
|
const opts = {
|
|
955
|
-
cwd:
|
|
2007
|
+
cwd: dir,
|
|
956
2008
|
timeout: 5e3,
|
|
957
2009
|
encoding: "utf-8",
|
|
958
2010
|
stdio: "pipe"
|
|
959
2011
|
};
|
|
960
|
-
const git = (args) => (0, import_child_process.execFileSync)(
|
|
2012
|
+
const git = (args) => (0, import_child_process.execFileSync)(gitBin, args, opts).trim();
|
|
961
2013
|
try {
|
|
962
2014
|
git(["rev-parse", "--is-inside-work-tree"]);
|
|
963
2015
|
} catch (err) {
|
|
964
2016
|
logger.warn("Git metadata skipped \u2014 cwd not a resolvable git repo", {
|
|
965
2017
|
projectDir,
|
|
2018
|
+
resolvedDir: dir,
|
|
966
2019
|
reason: err?.code === "ENOENT" ? "cwd-missing" : err?.status === 128 ? "not-a-git-repo" : "git-check-failed",
|
|
967
2020
|
error: err?.message?.slice(0, 200)
|
|
968
2021
|
});
|
|
@@ -1001,15 +2054,15 @@ function extractGitInfo(projectDir, sessionTimestamp, sessionBranch) {
|
|
|
1001
2054
|
}
|
|
1002
2055
|
return result;
|
|
1003
2056
|
}
|
|
1004
|
-
function
|
|
2057
|
+
function resolveToken2() {
|
|
1005
2058
|
if (process.env.HAANSI_TOKEN) return process.env.HAANSI_TOKEN;
|
|
1006
|
-
if ((0, import_fs3.existsSync)(
|
|
2059
|
+
if ((0, import_fs3.existsSync)(CREDENTIALS_FILE4)) {
|
|
1007
2060
|
try {
|
|
1008
|
-
const creds = JSON.parse((0, import_fs3.readFileSync)(
|
|
2061
|
+
const creds = JSON.parse((0, import_fs3.readFileSync)(CREDENTIALS_FILE4, "utf-8"));
|
|
1009
2062
|
if (creds.token) return creds.token;
|
|
1010
2063
|
} catch {
|
|
1011
2064
|
logger.warn("Could not parse credentials file", {
|
|
1012
|
-
file:
|
|
2065
|
+
file: CREDENTIALS_FILE4
|
|
1013
2066
|
});
|
|
1014
2067
|
}
|
|
1015
2068
|
}
|
|
@@ -1020,6 +2073,11 @@ function resolveAgentIds(agents) {
|
|
|
1020
2073
|
const installed = detectInstalled().map((a) => a.id);
|
|
1021
2074
|
return installed.length > 0 ? installed : ["claude-code"];
|
|
1022
2075
|
}
|
|
2076
|
+
function canResolveGit(session) {
|
|
2077
|
+
if (session.gitRemoteUrl || session.gitCommit) return true;
|
|
2078
|
+
if (!session.cwd) return false;
|
|
2079
|
+
return (0, import_fs3.existsSync)(effectiveGitDir(session.cwd));
|
|
2080
|
+
}
|
|
1023
2081
|
function discoverSessions(agentIds) {
|
|
1024
2082
|
const sessions = [];
|
|
1025
2083
|
for (const id of agentIds) {
|
|
@@ -1094,8 +2152,8 @@ async function uploadSession(sessionId, content, apiUrl2, token, agentSource, gi
|
|
|
1094
2152
|
}
|
|
1095
2153
|
}
|
|
1096
2154
|
async function collect(options) {
|
|
1097
|
-
const apiUrl2 = process.env.HAANSI_API_URL ??
|
|
1098
|
-
const token =
|
|
2155
|
+
const apiUrl2 = process.env.HAANSI_API_URL ?? DEFAULT_API_URL2;
|
|
2156
|
+
const token = resolveToken2();
|
|
1099
2157
|
if (!token && !options.dryRun) {
|
|
1100
2158
|
throw new Error(
|
|
1101
2159
|
"HAANSI_TOKEN is required. Set it as env var or in ~/.haansi/credentials.json"
|
|
@@ -1116,7 +2174,9 @@ async function collect(options) {
|
|
|
1116
2174
|
const toUpload = [];
|
|
1117
2175
|
for (const session of localSessions) {
|
|
1118
2176
|
const remote = remoteMap.get(session.sessionId);
|
|
1119
|
-
|
|
2177
|
+
const contentUnchanged = !!remote && remote.lineCount >= session.lineCount;
|
|
2178
|
+
const worthRetryingForGit = !remote?.hasGitMeta && canResolveGit(session);
|
|
2179
|
+
if (contentUnchanged && !worthRetryingForGit) {
|
|
1120
2180
|
skipped++;
|
|
1121
2181
|
} else {
|
|
1122
2182
|
toUpload.push(session);
|
|
@@ -1198,14 +2258,18 @@ async function main() {
|
|
|
1198
2258
|
const limitIdx = process.argv.indexOf("--limit");
|
|
1199
2259
|
const limit = limitIdx !== -1 ? parseInt(process.argv[limitIdx + 1], 10) : void 0;
|
|
1200
2260
|
logger.info("Collector starting", { forceAll, dryRun });
|
|
1201
|
-
const {
|
|
2261
|
+
const {
|
|
2262
|
+
uploaded: _uploaded,
|
|
2263
|
+
skipped: _skipped,
|
|
2264
|
+
errors
|
|
2265
|
+
} = await collect({
|
|
1202
2266
|
forceAll,
|
|
1203
2267
|
dryRun,
|
|
1204
2268
|
limit
|
|
1205
2269
|
});
|
|
1206
2270
|
if (errors > 0) process.exit(1);
|
|
1207
2271
|
}
|
|
1208
|
-
var import_dotenv, import_path3, import_fs3, import_os3, import_zlib, import_child_process, logger,
|
|
2272
|
+
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;
|
|
1209
2273
|
var init_collector = __esm({
|
|
1210
2274
|
"../service-capture/claude-sessions/collector.ts"() {
|
|
1211
2275
|
"use strict";
|
|
@@ -1215,12 +2279,13 @@ var init_collector = __esm({
|
|
|
1215
2279
|
import_os3 = require("os");
|
|
1216
2280
|
import_zlib = require("zlib");
|
|
1217
2281
|
import_child_process = require("child_process");
|
|
1218
|
-
|
|
2282
|
+
init_src2();
|
|
2283
|
+
init_service_urls();
|
|
1219
2284
|
init_agents();
|
|
1220
2285
|
(0, import_dotenv.config)({ path: (0, import_path3.resolve)(__dirname, "../../../.env") });
|
|
1221
2286
|
logger = createLogger("session-collector");
|
|
1222
|
-
|
|
1223
|
-
|
|
2287
|
+
DEFAULT_API_URL2 = SERVICE_URL_DEFAULTS.haansiApiBaseUrl;
|
|
2288
|
+
CREDENTIALS_FILE4 = (0, import_path3.join)((0, import_os3.homedir)(), ".haansi", "credentials.json");
|
|
1224
2289
|
MIN_LINES = 4;
|
|
1225
2290
|
EDGE_SCRUB_PATTERNS = [
|
|
1226
2291
|
{
|
|
@@ -1261,6 +2326,12 @@ var init_collector = __esm({
|
|
|
1261
2326
|
replacement: "[REDACTED:API_KEY]"
|
|
1262
2327
|
}
|
|
1263
2328
|
];
|
|
2329
|
+
GIT_BIN_CANDIDATES = [
|
|
2330
|
+
"git",
|
|
2331
|
+
"/opt/homebrew/bin/git",
|
|
2332
|
+
"/usr/local/bin/git",
|
|
2333
|
+
"/usr/bin/git"
|
|
2334
|
+
];
|
|
1264
2335
|
if (require.main === module) {
|
|
1265
2336
|
main().catch((err) => {
|
|
1266
2337
|
logger.error("Collector failed", err);
|
|
@@ -1270,44 +2341,6 @@ var init_collector = __esm({
|
|
|
1270
2341
|
}
|
|
1271
2342
|
});
|
|
1272
2343
|
|
|
1273
|
-
// src/lib/paths.ts
|
|
1274
|
-
function apiUrl() {
|
|
1275
|
-
return process.env.HAANSI_API_URL ?? DEFAULT_API_URL4;
|
|
1276
|
-
}
|
|
1277
|
-
function resolveToken2() {
|
|
1278
|
-
if (process.env.HAANSI_TOKEN) return process.env.HAANSI_TOKEN;
|
|
1279
|
-
if ((0, import_node_fs3.existsSync)(CREDENTIALS_FILE4)) {
|
|
1280
|
-
try {
|
|
1281
|
-
const creds = JSON.parse((0, import_node_fs3.readFileSync)(CREDENTIALS_FILE4, "utf-8"));
|
|
1282
|
-
if (typeof creds.token === "string" && creds.token) return creds.token;
|
|
1283
|
-
} catch {
|
|
1284
|
-
}
|
|
1285
|
-
}
|
|
1286
|
-
return null;
|
|
1287
|
-
}
|
|
1288
|
-
function resolveHaansiBin() {
|
|
1289
|
-
try {
|
|
1290
|
-
const binPath = (0, import_node_child_process2.execSync)("which haansi", { encoding: "utf-8" }).trim();
|
|
1291
|
-
if (binPath) return binPath;
|
|
1292
|
-
} catch {
|
|
1293
|
-
}
|
|
1294
|
-
return "haansi";
|
|
1295
|
-
}
|
|
1296
|
-
var import_node_fs3, import_node_path3, import_node_os3, import_node_child_process2, DEFAULT_API_URL4, HAANSI_DIR3, CREDENTIALS_FILE4, CONFIG_FILE;
|
|
1297
|
-
var init_paths = __esm({
|
|
1298
|
-
"src/lib/paths.ts"() {
|
|
1299
|
-
"use strict";
|
|
1300
|
-
import_node_fs3 = require("node:fs");
|
|
1301
|
-
import_node_path3 = require("node:path");
|
|
1302
|
-
import_node_os3 = require("node:os");
|
|
1303
|
-
import_node_child_process2 = require("node:child_process");
|
|
1304
|
-
DEFAULT_API_URL4 = "https://api.haansi.co";
|
|
1305
|
-
HAANSI_DIR3 = (0, import_node_path3.join)((0, import_node_os3.homedir)(), ".haansi");
|
|
1306
|
-
CREDENTIALS_FILE4 = (0, import_node_path3.join)(HAANSI_DIR3, "credentials.json");
|
|
1307
|
-
CONFIG_FILE = (0, import_node_path3.join)(HAANSI_DIR3, "config.json");
|
|
1308
|
-
}
|
|
1309
|
-
});
|
|
1310
|
-
|
|
1311
2344
|
// src/lib/agent-selection.ts
|
|
1312
2345
|
var agent_selection_exports = {};
|
|
1313
2346
|
__export(agent_selection_exports, {
|
|
@@ -1355,7 +2388,7 @@ function saveAgents(agents) {
|
|
|
1355
2388
|
}
|
|
1356
2389
|
}
|
|
1357
2390
|
cfg.agents = agents;
|
|
1358
|
-
(0, import_node_fs4.mkdirSync)(
|
|
2391
|
+
(0, import_node_fs4.mkdirSync)(HAANSI_DIR, { recursive: true });
|
|
1359
2392
|
(0, import_node_fs4.writeFileSync)(CONFIG_FILE, JSON.stringify(cfg, null, 2) + "\n", {
|
|
1360
2393
|
encoding: "utf-8",
|
|
1361
2394
|
mode: 384
|
|
@@ -1828,19 +2861,19 @@ var require_scheduler = __commonJS({
|
|
|
1828
2861
|
});
|
|
1829
2862
|
|
|
1830
2863
|
// ../../node_modules/node-cron/node_modules/uuid/dist/esm-node/rng.js
|
|
1831
|
-
function
|
|
1832
|
-
if (
|
|
1833
|
-
|
|
1834
|
-
|
|
2864
|
+
function rng2() {
|
|
2865
|
+
if (poolPtr2 > rnds8Pool2.length - 16) {
|
|
2866
|
+
import_crypto3.default.randomFillSync(rnds8Pool2);
|
|
2867
|
+
poolPtr2 = 0;
|
|
1835
2868
|
}
|
|
1836
|
-
return
|
|
2869
|
+
return rnds8Pool2.slice(poolPtr2, poolPtr2 += 16);
|
|
1837
2870
|
}
|
|
1838
|
-
var
|
|
1839
|
-
var
|
|
2871
|
+
var import_crypto3, rnds8Pool2, poolPtr2;
|
|
2872
|
+
var init_rng2 = __esm({
|
|
1840
2873
|
"../../node_modules/node-cron/node_modules/uuid/dist/esm-node/rng.js"() {
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
2874
|
+
import_crypto3 = __toESM(require("crypto"));
|
|
2875
|
+
rnds8Pool2 = new Uint8Array(256);
|
|
2876
|
+
poolPtr2 = rnds8Pool2.length;
|
|
1844
2877
|
}
|
|
1845
2878
|
});
|
|
1846
2879
|
|
|
@@ -1866,19 +2899,19 @@ var init_validate = __esm({
|
|
|
1866
2899
|
|
|
1867
2900
|
// ../../node_modules/node-cron/node_modules/uuid/dist/esm-node/stringify.js
|
|
1868
2901
|
function stringify(arr, offset = 0) {
|
|
1869
|
-
const uuid3 = (
|
|
2902
|
+
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();
|
|
1870
2903
|
if (!validate_default(uuid3)) {
|
|
1871
2904
|
throw TypeError("Stringified UUID is invalid");
|
|
1872
2905
|
}
|
|
1873
2906
|
return uuid3;
|
|
1874
2907
|
}
|
|
1875
|
-
var
|
|
1876
|
-
var
|
|
2908
|
+
var byteToHex2, stringify_default;
|
|
2909
|
+
var init_stringify2 = __esm({
|
|
1877
2910
|
"../../node_modules/node-cron/node_modules/uuid/dist/esm-node/stringify.js"() {
|
|
1878
2911
|
init_validate();
|
|
1879
|
-
|
|
2912
|
+
byteToHex2 = [];
|
|
1880
2913
|
for (let i = 0; i < 256; ++i) {
|
|
1881
|
-
|
|
2914
|
+
byteToHex2.push((i + 256).toString(16).substr(1));
|
|
1882
2915
|
}
|
|
1883
2916
|
stringify_default = stringify;
|
|
1884
2917
|
}
|
|
@@ -1892,7 +2925,7 @@ function v1(options, buf, offset) {
|
|
|
1892
2925
|
let node = options.node || _nodeId;
|
|
1893
2926
|
let clockseq = options.clockseq !== void 0 ? options.clockseq : _clockseq;
|
|
1894
2927
|
if (node == null || clockseq == null) {
|
|
1895
|
-
const seedBytes = options.random || (options.rng ||
|
|
2928
|
+
const seedBytes = options.random || (options.rng || rng2)();
|
|
1896
2929
|
if (node == null) {
|
|
1897
2930
|
node = _nodeId = [seedBytes[0] | 1, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]];
|
|
1898
2931
|
}
|
|
@@ -1936,8 +2969,8 @@ function v1(options, buf, offset) {
|
|
|
1936
2969
|
var _nodeId, _clockseq, _lastMSecs, _lastNSecs, v1_default;
|
|
1937
2970
|
var init_v1 = __esm({
|
|
1938
2971
|
"../../node_modules/node-cron/node_modules/uuid/dist/esm-node/v1.js"() {
|
|
1939
|
-
|
|
1940
|
-
|
|
2972
|
+
init_rng2();
|
|
2973
|
+
init_stringify2();
|
|
1941
2974
|
_lastMSecs = 0;
|
|
1942
2975
|
_lastNSecs = 0;
|
|
1943
2976
|
v1_default = v1;
|
|
@@ -2023,7 +3056,7 @@ function v35_default(name, version3, hashfunc) {
|
|
|
2023
3056
|
var DNS, URL2;
|
|
2024
3057
|
var init_v35 = __esm({
|
|
2025
3058
|
"../../node_modules/node-cron/node_modules/uuid/dist/esm-node/v35.js"() {
|
|
2026
|
-
|
|
3059
|
+
init_stringify2();
|
|
2027
3060
|
init_parse();
|
|
2028
3061
|
DNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
|
|
2029
3062
|
URL2 = "6ba7b811-9dad-11d1-80b4-00c04fd430c8";
|
|
@@ -2037,12 +3070,12 @@ function md5(bytes) {
|
|
|
2037
3070
|
} else if (typeof bytes === "string") {
|
|
2038
3071
|
bytes = Buffer.from(bytes, "utf8");
|
|
2039
3072
|
}
|
|
2040
|
-
return
|
|
3073
|
+
return import_crypto4.default.createHash("md5").update(bytes).digest();
|
|
2041
3074
|
}
|
|
2042
|
-
var
|
|
3075
|
+
var import_crypto4, md5_default;
|
|
2043
3076
|
var init_md5 = __esm({
|
|
2044
3077
|
"../../node_modules/node-cron/node_modules/uuid/dist/esm-node/md5.js"() {
|
|
2045
|
-
|
|
3078
|
+
import_crypto4 = __toESM(require("crypto"));
|
|
2046
3079
|
md5_default = md5;
|
|
2047
3080
|
}
|
|
2048
3081
|
});
|
|
@@ -2059,9 +3092,9 @@ var init_v3 = __esm({
|
|
|
2059
3092
|
});
|
|
2060
3093
|
|
|
2061
3094
|
// ../../node_modules/node-cron/node_modules/uuid/dist/esm-node/v4.js
|
|
2062
|
-
function
|
|
3095
|
+
function v42(options, buf, offset) {
|
|
2063
3096
|
options = options || {};
|
|
2064
|
-
const rnds = options.random || (options.rng ||
|
|
3097
|
+
const rnds = options.random || (options.rng || rng2)();
|
|
2065
3098
|
rnds[6] = rnds[6] & 15 | 64;
|
|
2066
3099
|
rnds[8] = rnds[8] & 63 | 128;
|
|
2067
3100
|
if (buf) {
|
|
@@ -2073,12 +3106,12 @@ function v4(options, buf, offset) {
|
|
|
2073
3106
|
}
|
|
2074
3107
|
return stringify_default(rnds);
|
|
2075
3108
|
}
|
|
2076
|
-
var
|
|
2077
|
-
var
|
|
3109
|
+
var v4_default2;
|
|
3110
|
+
var init_v42 = __esm({
|
|
2078
3111
|
"../../node_modules/node-cron/node_modules/uuid/dist/esm-node/v4.js"() {
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
3112
|
+
init_rng2();
|
|
3113
|
+
init_stringify2();
|
|
3114
|
+
v4_default2 = v42;
|
|
2082
3115
|
}
|
|
2083
3116
|
});
|
|
2084
3117
|
|
|
@@ -2089,12 +3122,12 @@ function sha1(bytes) {
|
|
|
2089
3122
|
} else if (typeof bytes === "string") {
|
|
2090
3123
|
bytes = Buffer.from(bytes, "utf8");
|
|
2091
3124
|
}
|
|
2092
|
-
return
|
|
3125
|
+
return import_crypto5.default.createHash("sha1").update(bytes).digest();
|
|
2093
3126
|
}
|
|
2094
|
-
var
|
|
3127
|
+
var import_crypto5, sha1_default;
|
|
2095
3128
|
var init_sha1 = __esm({
|
|
2096
3129
|
"../../node_modules/node-cron/node_modules/uuid/dist/esm-node/sha1.js"() {
|
|
2097
|
-
|
|
3130
|
+
import_crypto5 = __toESM(require("crypto"));
|
|
2098
3131
|
sha1_default = sha1;
|
|
2099
3132
|
}
|
|
2100
3133
|
});
|
|
@@ -2141,21 +3174,21 @@ __export(esm_node_exports, {
|
|
|
2141
3174
|
stringify: () => stringify_default,
|
|
2142
3175
|
v1: () => v1_default,
|
|
2143
3176
|
v3: () => v3_default,
|
|
2144
|
-
v4: () =>
|
|
3177
|
+
v4: () => v4_default2,
|
|
2145
3178
|
v5: () => v5_default,
|
|
2146
3179
|
validate: () => validate_default,
|
|
2147
3180
|
version: () => version_default
|
|
2148
3181
|
});
|
|
2149
|
-
var
|
|
3182
|
+
var init_esm_node2 = __esm({
|
|
2150
3183
|
"../../node_modules/node-cron/node_modules/uuid/dist/esm-node/index.js"() {
|
|
2151
3184
|
init_v1();
|
|
2152
3185
|
init_v3();
|
|
2153
|
-
|
|
3186
|
+
init_v42();
|
|
2154
3187
|
init_v5();
|
|
2155
3188
|
init_nil();
|
|
2156
3189
|
init_version();
|
|
2157
3190
|
init_validate();
|
|
2158
|
-
|
|
3191
|
+
init_stringify2();
|
|
2159
3192
|
init_parse();
|
|
2160
3193
|
}
|
|
2161
3194
|
});
|
|
@@ -2167,7 +3200,7 @@ var require_scheduled_task = __commonJS({
|
|
|
2167
3200
|
var EventEmitter = require("events");
|
|
2168
3201
|
var Task = require_task();
|
|
2169
3202
|
var Scheduler = require_scheduler();
|
|
2170
|
-
var uuid3 = (
|
|
3203
|
+
var uuid3 = (init_esm_node2(), __toCommonJS(esm_node_exports));
|
|
2171
3204
|
var ScheduledTask = class extends EventEmitter {
|
|
2172
3205
|
constructor(cronExpression, func, options) {
|
|
2173
3206
|
super();
|
|
@@ -2212,7 +3245,7 @@ var require_background_scheduled_task = __commonJS({
|
|
|
2212
3245
|
var EventEmitter = require("events");
|
|
2213
3246
|
var path = require("path");
|
|
2214
3247
|
var { fork } = require("child_process");
|
|
2215
|
-
var uuid3 = (
|
|
3248
|
+
var uuid3 = (init_esm_node2(), __toCommonJS(esm_node_exports));
|
|
2216
3249
|
var daemonPath = `${__dirname}/daemon.js`;
|
|
2217
3250
|
var BackgroundScheduledTask = class extends EventEmitter {
|
|
2218
3251
|
constructor(cronExpression, taskPath, options) {
|
|
@@ -2278,7 +3311,7 @@ var require_storage = __commonJS({
|
|
|
2278
3311
|
return {
|
|
2279
3312
|
save: (task) => {
|
|
2280
3313
|
if (!task.options) {
|
|
2281
|
-
const uuid3 = (
|
|
3314
|
+
const uuid3 = (init_esm_node2(), __toCommonJS(esm_node_exports));
|
|
2282
3315
|
task.options = {};
|
|
2283
3316
|
task.options.name = uuid3.v4();
|
|
2284
3317
|
}
|
|
@@ -2396,10 +3429,11 @@ var init_collector_daemon = __esm({
|
|
|
2396
3429
|
import_path4 = require("path");
|
|
2397
3430
|
import_node_cron = __toESM(require_node_cron());
|
|
2398
3431
|
init_collector();
|
|
2399
|
-
|
|
3432
|
+
init_src2();
|
|
2400
3433
|
(0, import_dotenv2.config)({ path: (0, import_path4.resolve)(__dirname, "../../../.env") });
|
|
2401
3434
|
logger2 = createLogger("collector-daemon");
|
|
2402
|
-
IN_MEMORY_VERSION =
|
|
3435
|
+
IN_MEMORY_VERSION = // eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
3436
|
+
require_package().version;
|
|
2403
3437
|
SCHEDULE = process.env.HAANSI_COLLECT_SCHEDULE ?? process.env.CLAUDE_COLLECT_SCHEDULE ?? "*/30 * * * *";
|
|
2404
3438
|
main2().catch((err) => {
|
|
2405
3439
|
logger2.error("Daemon failed to start", err);
|
|
@@ -2623,14 +3657,39 @@ var init_taxonomy = __esm({
|
|
|
2623
3657
|
});
|
|
2624
3658
|
|
|
2625
3659
|
// ../../packages/@company/types/src/embedding.ts
|
|
3660
|
+
var EMBEDDING_DEFAULTS, EMBEDDING_COLUMN, SUMMARY_EMBEDDING_COLUMN;
|
|
2626
3661
|
var init_embedding = __esm({
|
|
2627
3662
|
"../../packages/@company/types/src/embedding.ts"() {
|
|
2628
3663
|
"use strict";
|
|
3664
|
+
EMBEDDING_DEFAULTS = {
|
|
3665
|
+
// `as const` gives a literal string type for the provider field, which
|
|
3666
|
+
// is assignable to llm-client's LLMProvider union without forcing
|
|
3667
|
+
// @company/types to import that union (which would re-introduce the
|
|
3668
|
+
// dependency edge we want to keep absent).
|
|
3669
|
+
// CUTOVER (2026-07-17): in-house model is now the active config. Reads +
|
|
3670
|
+
// writes + backfills all target the local-768 columns. The old OpenAI 1536
|
|
3671
|
+
// columns (`embedding` / `summary_embedding`) are retained but dormant —
|
|
3672
|
+
// roll back by flipping this whole object back to
|
|
3673
|
+
// { provider:"openai", model:"text-embedding-3-small", dimensions:1536,
|
|
3674
|
+
// column:"embedding", summaryColumn:"summary_embedding" }
|
|
3675
|
+
// (a later contract migration drops the dormant columns). Readers alias
|
|
3676
|
+
// `<column> AS embedding` so result-row field names stay stable.
|
|
3677
|
+
provider: "local",
|
|
3678
|
+
model: "Alibaba-NLP/gte-base-en-v1.5",
|
|
3679
|
+
dimensions: 768,
|
|
3680
|
+
// The ACTIVE dense-vector column that every reader + writer + backfill targets.
|
|
3681
|
+
column: "embedding_v2",
|
|
3682
|
+
// The active summary-embedding column (process_registry's second vector,
|
|
3683
|
+
// used by the process matcher).
|
|
3684
|
+
summaryColumn: "summary_embedding_v2"
|
|
3685
|
+
};
|
|
3686
|
+
EMBEDDING_COLUMN = EMBEDDING_DEFAULTS.column;
|
|
3687
|
+
SUMMARY_EMBEDDING_COLUMN = EMBEDDING_DEFAULTS.summaryColumn;
|
|
2629
3688
|
}
|
|
2630
3689
|
});
|
|
2631
3690
|
|
|
2632
3691
|
// ../../packages/@company/types/src/index.ts
|
|
2633
|
-
var
|
|
3692
|
+
var init_src3 = __esm({
|
|
2634
3693
|
"../../packages/@company/types/src/index.ts"() {
|
|
2635
3694
|
init_timeline();
|
|
2636
3695
|
init_artifact();
|
|
@@ -3317,7 +4376,7 @@ function createZodEnum(values, params) {
|
|
|
3317
4376
|
});
|
|
3318
4377
|
}
|
|
3319
4378
|
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;
|
|
3320
|
-
var
|
|
4379
|
+
var init_types3 = __esm({
|
|
3321
4380
|
"../../node_modules/zod/v3/types.js"() {
|
|
3322
4381
|
init_ZodError();
|
|
3323
4382
|
init_errors();
|
|
@@ -6570,7 +7629,7 @@ var init_external = __esm({
|
|
|
6570
7629
|
init_parseUtil();
|
|
6571
7630
|
init_typeAliases();
|
|
6572
7631
|
init_util();
|
|
6573
|
-
|
|
7632
|
+
init_types3();
|
|
6574
7633
|
init_ZodError();
|
|
6575
7634
|
}
|
|
6576
7635
|
});
|
|
@@ -14331,7 +15390,7 @@ var init_classic = __esm({
|
|
|
14331
15390
|
});
|
|
14332
15391
|
|
|
14333
15392
|
// ../../node_modules/zod/v4/index.js
|
|
14334
|
-
var
|
|
15393
|
+
var init_v43 = __esm({
|
|
14335
15394
|
"../../node_modules/zod/v4/index.js"() {
|
|
14336
15395
|
init_classic();
|
|
14337
15396
|
init_classic();
|
|
@@ -14352,9 +15411,9 @@ function assertCompleteRequestResourceTemplate(request) {
|
|
|
14352
15411
|
void request;
|
|
14353
15412
|
}
|
|
14354
15413
|
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;
|
|
14355
|
-
var
|
|
15414
|
+
var init_types4 = __esm({
|
|
14356
15415
|
"../service-capture/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js"() {
|
|
14357
|
-
|
|
15416
|
+
init_v43();
|
|
14358
15417
|
LATEST_PROTOCOL_VERSION = "2025-11-25";
|
|
14359
15418
|
DEFAULT_NEGOTIATED_PROTOCOL_VERSION = "2025-03-26";
|
|
14360
15419
|
SUPPORTED_PROTOCOL_VERSIONS = [LATEST_PROTOCOL_VERSION, "2025-06-18", "2025-03-26", "2024-11-05", "2024-10-07"];
|
|
@@ -17518,7 +18577,7 @@ var DEFAULT_REQUEST_TIMEOUT_MSEC, Protocol;
|
|
|
17518
18577
|
var init_protocol = __esm({
|
|
17519
18578
|
"../service-capture/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js"() {
|
|
17520
18579
|
init_zod_compat();
|
|
17521
|
-
|
|
18580
|
+
init_types4();
|
|
17522
18581
|
init_interfaces();
|
|
17523
18582
|
init_zod_json_schema_compat();
|
|
17524
18583
|
DEFAULT_REQUEST_TIMEOUT_MSEC = 6e4;
|
|
@@ -31100,7 +32159,7 @@ var Server;
|
|
|
31100
32159
|
var init_server2 = __esm({
|
|
31101
32160
|
"../service-capture/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js"() {
|
|
31102
32161
|
init_protocol();
|
|
31103
|
-
|
|
32162
|
+
init_types4();
|
|
31104
32163
|
init_ajv_provider();
|
|
31105
32164
|
init_zod_compat();
|
|
31106
32165
|
init_server();
|
|
@@ -31670,7 +32729,7 @@ var init_mcp = __esm({
|
|
|
31670
32729
|
init_server2();
|
|
31671
32730
|
init_zod_compat();
|
|
31672
32731
|
init_zod_json_schema_compat();
|
|
31673
|
-
|
|
32732
|
+
init_types4();
|
|
31674
32733
|
init_completable();
|
|
31675
32734
|
init_uriTemplate();
|
|
31676
32735
|
init_toolNameValidation();
|
|
@@ -32411,7 +33470,7 @@ function serializeMessage(message) {
|
|
|
32411
33470
|
var ReadBuffer;
|
|
32412
33471
|
var init_stdio = __esm({
|
|
32413
33472
|
"../service-capture/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/stdio.js"() {
|
|
32414
|
-
|
|
33473
|
+
init_types4();
|
|
32415
33474
|
ReadBuffer = class {
|
|
32416
33475
|
append(chunk) {
|
|
32417
33476
|
this._buffer = this._buffer ? Buffer.concat([this._buffer, chunk]) : chunk;
|
|
@@ -51311,14 +52370,14 @@ var require_etag = __commonJS({
|
|
|
51311
52370
|
"../../node_modules/etag/index.js"(exports2, module2) {
|
|
51312
52371
|
"use strict";
|
|
51313
52372
|
module2.exports = etag;
|
|
51314
|
-
var
|
|
52373
|
+
var crypto8 = require("crypto");
|
|
51315
52374
|
var Stats = require("fs").Stats;
|
|
51316
52375
|
var toString = Object.prototype.toString;
|
|
51317
52376
|
function entitytag(entity) {
|
|
51318
52377
|
if (entity.length === 0) {
|
|
51319
52378
|
return '"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk"';
|
|
51320
52379
|
}
|
|
51321
|
-
var hash2 =
|
|
52380
|
+
var hash2 = crypto8.createHash("sha1").update(entity, "utf8").digest("base64").substring(0, 27);
|
|
51322
52381
|
var len = typeof entity === "string" ? Buffer.byteLength(entity, "utf8") : entity.length;
|
|
51323
52382
|
return '"' + len.toString(16) + "-" + hash2 + '"';
|
|
51324
52383
|
}
|
|
@@ -54733,17 +55792,17 @@ var require_content_disposition = __commonJS({
|
|
|
54733
55792
|
// ../service-capture/node_modules/cookie-signature/index.js
|
|
54734
55793
|
var require_cookie_signature = __commonJS({
|
|
54735
55794
|
"../service-capture/node_modules/cookie-signature/index.js"(exports2) {
|
|
54736
|
-
var
|
|
55795
|
+
var crypto8 = require("crypto");
|
|
54737
55796
|
exports2.sign = function(val, secret) {
|
|
54738
55797
|
if ("string" != typeof val) throw new TypeError("Cookie value must be provided as a string.");
|
|
54739
55798
|
if (null == secret) throw new TypeError("Secret key must be provided.");
|
|
54740
|
-
return val + "." +
|
|
55799
|
+
return val + "." + crypto8.createHmac("sha256", secret).update(val).digest("base64").replace(/\=+$/, "");
|
|
54741
55800
|
};
|
|
54742
55801
|
exports2.unsign = function(input, secret) {
|
|
54743
55802
|
if ("string" != typeof input) throw new TypeError("Signed cookie string must be provided.");
|
|
54744
55803
|
if (null == secret) throw new TypeError("Secret key must be provided.");
|
|
54745
55804
|
var tentativeValue = input.slice(0, input.lastIndexOf(".")), expectedInput = exports2.sign(tentativeValue, secret), expectedBuffer = Buffer.from(expectedInput), inputBuffer = Buffer.from(input);
|
|
54746
|
-
return expectedBuffer.length === inputBuffer.length &&
|
|
55805
|
+
return expectedBuffer.length === inputBuffer.length && crypto8.timingSafeEqual(expectedBuffer, inputBuffer) ? tentativeValue : false;
|
|
54747
55806
|
};
|
|
54748
55807
|
}
|
|
54749
55808
|
});
|
|
@@ -56138,13 +57197,13 @@ function writeFromReadableStream(stream, writable) {
|
|
|
56138
57197
|
}
|
|
56139
57198
|
return writeFromReadableStreamDefaultReader(stream.getReader(), writable);
|
|
56140
57199
|
}
|
|
56141
|
-
var import_http2, import_http22, import_stream,
|
|
57200
|
+
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;
|
|
56142
57201
|
var init_dist = __esm({
|
|
56143
57202
|
"../../node_modules/@hono/node-server/dist/index.mjs"() {
|
|
56144
57203
|
import_http2 = require("http2");
|
|
56145
57204
|
import_http22 = require("http2");
|
|
56146
57205
|
import_stream = require("stream");
|
|
56147
|
-
|
|
57206
|
+
import_crypto6 = __toESM(require("crypto"), 1);
|
|
56148
57207
|
RequestError = class extends Error {
|
|
56149
57208
|
constructor(message, options) {
|
|
56150
57209
|
super(message, options);
|
|
@@ -56414,7 +57473,7 @@ var init_dist = __esm({
|
|
|
56414
57473
|
};
|
|
56415
57474
|
X_ALREADY_SENT = "x-hono-already-sent";
|
|
56416
57475
|
if (typeof global.crypto === "undefined") {
|
|
56417
|
-
global.crypto =
|
|
57476
|
+
global.crypto = import_crypto6.default;
|
|
56418
57477
|
}
|
|
56419
57478
|
outgoingEnded = Symbol("outgoingEnded");
|
|
56420
57479
|
handleRequestError = () => new Response(null, {
|
|
@@ -56633,7 +57692,7 @@ var init_dist = __esm({
|
|
|
56633
57692
|
var WebStandardStreamableHTTPServerTransport;
|
|
56634
57693
|
var init_webStandardStreamableHttp = __esm({
|
|
56635
57694
|
"../service-capture/node_modules/@modelcontextprotocol/sdk/dist/esm/server/webStandardStreamableHttp.js"() {
|
|
56636
|
-
|
|
57695
|
+
init_types4();
|
|
56637
57696
|
WebStandardStreamableHTTPServerTransport = class {
|
|
56638
57697
|
constructor(options = {}) {
|
|
56639
57698
|
this._started = false;
|
|
@@ -57423,7 +58482,7 @@ async function main3() {
|
|
|
57423
58482
|
}
|
|
57424
58483
|
warmupInBackground();
|
|
57425
58484
|
}
|
|
57426
|
-
var import_dotenv3, import_path5, import_fs5, import_os4,
|
|
58485
|
+
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;
|
|
57427
58486
|
var init_mcp_server2 = __esm({
|
|
57428
58487
|
"../service-capture/claude-sessions/mcp-server.ts"() {
|
|
57429
58488
|
"use strict";
|
|
@@ -57433,14 +58492,17 @@ var init_mcp_server2 = __esm({
|
|
|
57433
58492
|
import_os4 = require("os");
|
|
57434
58493
|
init_collector();
|
|
57435
58494
|
init_http_timeout();
|
|
57436
|
-
|
|
58495
|
+
init_service_urls();
|
|
58496
|
+
init_src3();
|
|
57437
58497
|
init_mcp();
|
|
57438
58498
|
init_stdio2();
|
|
57439
|
-
|
|
58499
|
+
init_types4();
|
|
57440
58500
|
(0, import_dotenv3.config)({ path: (0, import_path5.resolve)(__dirname, "../../../.env") });
|
|
57441
|
-
|
|
58501
|
+
DEFAULT_API_URL3 = SERVICE_URL_DEFAULTS.haansiApiBaseUrl;
|
|
57442
58502
|
CREDENTIALS_FILE5 = (0, import_path5.join)((0, import_os4.homedir)(), ".haansi", "credentials.json");
|
|
57443
|
-
API_URL = process.env.HAANSI_API_URL ??
|
|
58503
|
+
API_URL = process.env.HAANSI_API_URL ?? DEFAULT_API_URL3;
|
|
58504
|
+
AGENT_SOURCE = process.env.HAANSI_AGENT_SOURCE?.toLowerCase();
|
|
58505
|
+
DEFAULT_SOURCE_TOOL = AGENT_SOURCE === "codex" ? "codex-mcp" : "claude-code-mcp";
|
|
57444
58506
|
TOKEN = resolveToken3();
|
|
57445
58507
|
if (!TOKEN) {
|
|
57446
58508
|
process.exit(1);
|
|
@@ -57580,7 +58642,7 @@ var init_mcp_server2 = __esm({
|
|
|
57580
58642
|
},
|
|
57581
58643
|
source_tool: {
|
|
57582
58644
|
type: "string",
|
|
57583
|
-
description:
|
|
58645
|
+
description: `Tool that saved this (default: "${DEFAULT_SOURCE_TOOL}")`
|
|
57584
58646
|
},
|
|
57585
58647
|
_context: contextSchema
|
|
57586
58648
|
},
|
|
@@ -57699,7 +58761,7 @@ var init_mcp_server2 = __esm({
|
|
|
57699
58761
|
git_commit,
|
|
57700
58762
|
tags,
|
|
57701
58763
|
model,
|
|
57702
|
-
source_tool
|
|
58764
|
+
source_tool: source_tool ?? DEFAULT_SOURCE_TOOL
|
|
57703
58765
|
},
|
|
57704
58766
|
{ extraHeaders }
|
|
57705
58767
|
);
|
|
@@ -57794,7 +58856,7 @@ function parseTarget(arg) {
|
|
|
57794
58856
|
);
|
|
57795
58857
|
}
|
|
57796
58858
|
function exchangeUrl() {
|
|
57797
|
-
return `${apiUrl().replace(/\/+$/, "")}/api/v1/
|
|
58859
|
+
return `${apiUrl().replace(/\/+$/, "")}/api/v1/memory/exchange/mcp`;
|
|
57798
58860
|
}
|
|
57799
58861
|
function setupClaudeMcp(target) {
|
|
57800
58862
|
let config6 = {};
|
|
@@ -57814,12 +58876,13 @@ function setupClaudeMcp(target) {
|
|
|
57814
58876
|
const haansiBin = resolveHaansiBin();
|
|
57815
58877
|
config6.mcpServers["haansi-solutions"] = {
|
|
57816
58878
|
command: haansiBin,
|
|
57817
|
-
args: ["mcp-server"]
|
|
58879
|
+
args: ["mcp-server"],
|
|
58880
|
+
env: { HAANSI_AGENT_SOURCE: "claude-code" }
|
|
57818
58881
|
};
|
|
57819
58882
|
installed.push(`haansi-solutions (stdio \u2192 ${haansiBin} mcp-server)`);
|
|
57820
58883
|
}
|
|
57821
58884
|
if (target === "all" || target === "exchange") {
|
|
57822
|
-
const token =
|
|
58885
|
+
const token = resolveToken();
|
|
57823
58886
|
if (!token) {
|
|
57824
58887
|
warnings.push(
|
|
57825
58888
|
"haansi-exchange not registered: no token found. Run `haansi auth login` first, or set HAANSI_TOKEN."
|
|
@@ -57858,12 +58921,13 @@ function setupCodexMcp(target) {
|
|
|
57858
58921
|
const haansiBin = resolveHaansiBin();
|
|
57859
58922
|
content = upsertTomlTable(content, "mcp_servers.haansi-solutions", {
|
|
57860
58923
|
command: tomlString(haansiBin),
|
|
57861
|
-
args: tomlStringArray(["mcp-server"])
|
|
58924
|
+
args: tomlStringArray(["mcp-server"]),
|
|
58925
|
+
env: tomlInlineTable({ HAANSI_AGENT_SOURCE: "codex" })
|
|
57862
58926
|
});
|
|
57863
58927
|
installed.push(`haansi-solutions (stdio \u2192 ${haansiBin} mcp-server)`);
|
|
57864
58928
|
}
|
|
57865
58929
|
if (target === "all" || target === "exchange") {
|
|
57866
|
-
const token =
|
|
58930
|
+
const token = resolveToken();
|
|
57867
58931
|
if (!token) {
|
|
57868
58932
|
warnings.push(
|
|
57869
58933
|
"haansi-exchange not registered: no token found. Run `haansi auth login` first, or set HAANSI_TOKEN."
|
|
@@ -58060,7 +59124,7 @@ async function config5(args) {
|
|
|
58060
59124
|
process.exit(1);
|
|
58061
59125
|
return;
|
|
58062
59126
|
}
|
|
58063
|
-
const apiUrl2 =
|
|
59127
|
+
const apiUrl2 = apiUrl();
|
|
58064
59128
|
const subcommand = args[0];
|
|
58065
59129
|
if (subcommand === "get") {
|
|
58066
59130
|
const key = args[1];
|
|
@@ -58141,14 +59205,14 @@ Supported keys:
|
|
|
58141
59205
|
if (subcommand !== void 0) process.exit(1);
|
|
58142
59206
|
}
|
|
58143
59207
|
}
|
|
58144
|
-
var import_node_fs7, import_node_path6, import_node_os6,
|
|
59208
|
+
var import_node_fs7, import_node_path6, import_node_os6, CREDENTIALS_FILE6, VALID_SESSION_MODES;
|
|
58145
59209
|
var init_config = __esm({
|
|
58146
59210
|
"src/commands/config.ts"() {
|
|
58147
59211
|
"use strict";
|
|
58148
59212
|
import_node_fs7 = require("node:fs");
|
|
58149
59213
|
import_node_path6 = require("node:path");
|
|
58150
59214
|
import_node_os6 = require("node:os");
|
|
58151
|
-
|
|
59215
|
+
init_paths();
|
|
58152
59216
|
CREDENTIALS_FILE6 = (0, import_node_path6.join)((0, import_node_os6.homedir)(), ".haansi", "credentials.json");
|
|
58153
59217
|
VALID_SESSION_MODES = ["private", "org"];
|
|
58154
59218
|
}
|
|
@@ -58199,7 +59263,7 @@ async function apiPost2(path, body, token, apiUrl2) {
|
|
|
58199
59263
|
return response.json();
|
|
58200
59264
|
}
|
|
58201
59265
|
async function list(options) {
|
|
58202
|
-
const apiUrl2 =
|
|
59266
|
+
const apiUrl2 = apiUrl();
|
|
58203
59267
|
const token = resolveToken5();
|
|
58204
59268
|
let data;
|
|
58205
59269
|
if (options.search) {
|
|
@@ -58225,7 +59289,7 @@ async function list(options) {
|
|
|
58225
59289
|
${data.results.length} result(s)`);
|
|
58226
59290
|
}
|
|
58227
59291
|
async function searchKnowledge(options) {
|
|
58228
|
-
const apiUrl2 =
|
|
59292
|
+
const apiUrl2 = apiUrl();
|
|
58229
59293
|
const token = resolveToken5();
|
|
58230
59294
|
let url2 = `/memory/solutions/knowledge/search?q=${encodeURIComponent(options.query)}&limit=${options.limit}`;
|
|
58231
59295
|
if (options.artifactType) {
|
|
@@ -58242,7 +59306,7 @@ async function searchKnowledge(options) {
|
|
|
58242
59306
|
${data.results.length} result(s)`);
|
|
58243
59307
|
}
|
|
58244
59308
|
async function saveKnowledge(options) {
|
|
58245
|
-
const apiUrl2 =
|
|
59309
|
+
const apiUrl2 = apiUrl();
|
|
58246
59310
|
const token = resolveToken5();
|
|
58247
59311
|
const body = {
|
|
58248
59312
|
problem_description: options.problem,
|
|
@@ -58263,19 +59327,20 @@ async function saveKnowledge(options) {
|
|
|
58263
59327
|
console.log(` Solution: ${data.solution_summary}`);
|
|
58264
59328
|
console.log("\nThis is now searchable via `haansi search-solutions`.");
|
|
58265
59329
|
}
|
|
58266
|
-
var import_node_fs8, import_node_path7, import_node_os7,
|
|
59330
|
+
var import_node_fs8, import_node_path7, import_node_os7, CREDENTIALS_FILE7;
|
|
58267
59331
|
var init_list = __esm({
|
|
58268
59332
|
"src/commands/list.ts"() {
|
|
58269
59333
|
"use strict";
|
|
58270
59334
|
import_node_fs8 = require("node:fs");
|
|
58271
59335
|
import_node_path7 = require("node:path");
|
|
58272
59336
|
import_node_os7 = require("node:os");
|
|
58273
|
-
|
|
59337
|
+
init_paths();
|
|
58274
59338
|
CREDENTIALS_FILE7 = (0, import_node_path7.join)((0, import_node_os7.homedir)(), ".haansi", "credentials.json");
|
|
58275
59339
|
}
|
|
58276
59340
|
});
|
|
58277
59341
|
|
|
58278
59342
|
// src/index.ts
|
|
59343
|
+
init_paths();
|
|
58279
59344
|
var { version: VERSION } = require_package();
|
|
58280
59345
|
var command = process.argv[2];
|
|
58281
59346
|
function getFlag(flag) {
|
|
@@ -58499,7 +59564,7 @@ Options for collect:
|
|
|
58499
59564
|
|
|
58500
59565
|
Environment variables:
|
|
58501
59566
|
HAANSI_TOKEN API token (or use \`haansi init\` to save it)
|
|
58502
|
-
HAANSI_API_URL API base URL (default:
|
|
59567
|
+
HAANSI_API_URL API base URL (default: ${DEFAULT_API_URL})
|
|
58503
59568
|
CODEX_HOME Codex home dir (default: ~/.codex)
|
|
58504
59569
|
HAANSI_AGENTS Daemon: comma-separated agents (claude-code,codex)
|
|
58505
59570
|
HAANSI_COLLECT_SCHEDULE Cron expression for daemon (default: */30 * * * *)
|