haansi 0.1.18 → 0.1.23
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 +246 -64
- package/package.json +1 -1
package/dist/haansi.js
CHANGED
|
@@ -39,7 +39,7 @@ var require_package = __commonJS({
|
|
|
39
39
|
"package.json"(exports2, module2) {
|
|
40
40
|
module2.exports = {
|
|
41
41
|
name: "haansi",
|
|
42
|
-
version: "0.1.
|
|
42
|
+
version: "0.1.23",
|
|
43
43
|
description: "Haansi CLI - Session collector and MCP server for Claude Code",
|
|
44
44
|
bin: {
|
|
45
45
|
haansi: "./dist/haansi.js"
|
|
@@ -141,7 +141,7 @@ If the browser didn't open, visit this URL:
|
|
|
141
141
|
);
|
|
142
142
|
}
|
|
143
143
|
console.log("Creating CLI token...");
|
|
144
|
-
const tokenRes = await fetch(`${apiUrl}/api/v1/cli-tokens`, {
|
|
144
|
+
const tokenRes = await fetch(`${apiUrl}/api/v1/access/cli-tokens`, {
|
|
145
145
|
method: "POST",
|
|
146
146
|
headers: {
|
|
147
147
|
Authorization: `Bearer ${jwt2}`,
|
|
@@ -206,9 +206,12 @@ function prompt(question) {
|
|
|
206
206
|
});
|
|
207
207
|
}
|
|
208
208
|
async function validateToken(token, apiUrl) {
|
|
209
|
-
const response = await fetch(
|
|
210
|
-
|
|
211
|
-
|
|
209
|
+
const response = await fetch(
|
|
210
|
+
`${apiUrl}/api/v1/memory/solutions/recent?limit=1`,
|
|
211
|
+
{
|
|
212
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
213
|
+
}
|
|
214
|
+
);
|
|
212
215
|
if (!response.ok) {
|
|
213
216
|
const body = await response.text().catch(() => "");
|
|
214
217
|
throw new Error(
|
|
@@ -820,7 +823,11 @@ async function apiGet(path, apiUrl, token) {
|
|
|
820
823
|
}
|
|
821
824
|
async function getUploadedSessions(apiUrl, token) {
|
|
822
825
|
try {
|
|
823
|
-
const data = await apiGet(
|
|
826
|
+
const data = await apiGet(
|
|
827
|
+
"/capture/sessions/uploaded",
|
|
828
|
+
apiUrl,
|
|
829
|
+
token
|
|
830
|
+
);
|
|
824
831
|
const map2 = /* @__PURE__ */ new Map();
|
|
825
832
|
for (const s of data.sessions) {
|
|
826
833
|
map2.set(s.sessionId, {
|
|
@@ -845,7 +852,7 @@ async function uploadSession(sessionId, content, apiUrl, token, gitInfo) {
|
|
|
845
852
|
if (gitInfo?.gitRemoteUrl) headers["x-git-remote-url"] = gitInfo.gitRemoteUrl;
|
|
846
853
|
if (gitInfo?.gitCommit) headers["x-git-commit"] = gitInfo.gitCommit;
|
|
847
854
|
if (gitInfo?.gitBranch) headers["x-git-branch"] = gitInfo.gitBranch;
|
|
848
|
-
const response = await fetch(`${apiUrl}/api/v1/sessions/raw`, {
|
|
855
|
+
const response = await fetch(`${apiUrl}/api/v1/capture/sessions/raw`, {
|
|
849
856
|
method: "POST",
|
|
850
857
|
headers,
|
|
851
858
|
body: new Uint8Array(body)
|
|
@@ -2040,7 +2047,7 @@ function normalizeComplexity(raw) {
|
|
|
2040
2047
|
if (lower in COMPLEXITIES) return lower;
|
|
2041
2048
|
return "moderate";
|
|
2042
2049
|
}
|
|
2043
|
-
var SESSION_TYPES, SESSION_TYPE_ALIASES, COMPLEXITIES;
|
|
2050
|
+
var SESSION_TYPES, SESSION_TYPE_ALIASES, COMPLEXITIES, ARTIFACT_TYPES, __seenAliases, ALIAS_REVERSE_MAP, ARTIFACT_TYPE_IDS, AUTO_APPROVED_ARTIFACT_TYPES;
|
|
2044
2051
|
var init_taxonomy = __esm({
|
|
2045
2052
|
"../../packages/@company/types/src/taxonomy.ts"() {
|
|
2046
2053
|
"use strict";
|
|
@@ -2098,6 +2105,122 @@ var init_taxonomy = __esm({
|
|
|
2098
2105
|
description: "Involved task with many steps or deep analysis"
|
|
2099
2106
|
}
|
|
2100
2107
|
};
|
|
2108
|
+
ARTIFACT_TYPES = {
|
|
2109
|
+
report_incident: {
|
|
2110
|
+
category: "report",
|
|
2111
|
+
label: "Incident Report",
|
|
2112
|
+
description: "Production-incident record + post-incident writeup: detection, timeline, root cause, resolution, follow-ups.",
|
|
2113
|
+
icon: "AlertTriangle",
|
|
2114
|
+
aliases: ["incident_summary", "incident", "postmortem", "post-mortem"],
|
|
2115
|
+
autoApproved: false,
|
|
2116
|
+
producedBy: [
|
|
2117
|
+
"POST /api/v1/memory/processes/incidents",
|
|
2118
|
+
"POST /api/v1/memory/reports/incident",
|
|
2119
|
+
"POST /api/v1/memory/processes/incidents/:id/postmortem"
|
|
2120
|
+
]
|
|
2121
|
+
},
|
|
2122
|
+
report_decision: {
|
|
2123
|
+
category: "report",
|
|
2124
|
+
label: "Decision Record",
|
|
2125
|
+
description: "Architectural / product decision record with context, options considered, decision, and rationale.",
|
|
2126
|
+
icon: "Scale",
|
|
2127
|
+
aliases: ["decision_record", "decision-record", "adr"],
|
|
2128
|
+
autoApproved: false,
|
|
2129
|
+
producedBy: ["POST /api/v1/memory"]
|
|
2130
|
+
},
|
|
2131
|
+
report_work: {
|
|
2132
|
+
category: "report",
|
|
2133
|
+
label: "Work Report",
|
|
2134
|
+
description: "Periodic or one-off work-progress report \u2014 status updates, weekly digests, project rollups, team-activity summaries.",
|
|
2135
|
+
icon: "CalendarDays",
|
|
2136
|
+
aliases: ["weekly_digest", "weekly-digest", "status_report"],
|
|
2137
|
+
autoApproved: true,
|
|
2138
|
+
producedBy: ["POST /api/v1/memory", "POST /api/v1/memory/reports/work"]
|
|
2139
|
+
},
|
|
2140
|
+
report_sop: {
|
|
2141
|
+
category: "report",
|
|
2142
|
+
label: "Standard Operating Procedure",
|
|
2143
|
+
description: "Reusable step-by-step procedure or runbook. Placeholder \u2014 surface not yet specialized; written via generic POST /memory until a dedicated producer ships.",
|
|
2144
|
+
icon: "FileText",
|
|
2145
|
+
aliases: ["sop", "runbook"],
|
|
2146
|
+
autoApproved: false,
|
|
2147
|
+
producedBy: ["POST /api/v1/memory"]
|
|
2148
|
+
},
|
|
2149
|
+
report_onboarding: {
|
|
2150
|
+
category: "report",
|
|
2151
|
+
label: "Onboarding Packet",
|
|
2152
|
+
description: "Onboarding guide assembled from team knowledge, scoped to a project or role.",
|
|
2153
|
+
icon: "GraduationCap",
|
|
2154
|
+
aliases: ["onboarding_packet", "onboarding-packet"],
|
|
2155
|
+
autoApproved: false,
|
|
2156
|
+
producedBy: ["POST /api/v1/memory/reports/onboarding"]
|
|
2157
|
+
},
|
|
2158
|
+
report_pr: {
|
|
2159
|
+
category: "report",
|
|
2160
|
+
label: "PR Context",
|
|
2161
|
+
description: "Enriched pull-request description with linked Jira/Slack context, recent decisions, and reviewer hints.",
|
|
2162
|
+
icon: "GitPullRequest",
|
|
2163
|
+
aliases: ["pr_context", "pr-context"],
|
|
2164
|
+
autoApproved: true,
|
|
2165
|
+
producedBy: ["POST /api/v1/memory/reports/pr"]
|
|
2166
|
+
},
|
|
2167
|
+
expert: {
|
|
2168
|
+
category: "expert",
|
|
2169
|
+
label: "Expert Profile",
|
|
2170
|
+
description: "Per-person expertise profile across platforms \u2014 areas of focus, recent contributions, identity links.",
|
|
2171
|
+
icon: "Users",
|
|
2172
|
+
aliases: ["expert_profile", "expert-profile"],
|
|
2173
|
+
autoApproved: false,
|
|
2174
|
+
producedBy: ["POST /api/v1/memory/experts"]
|
|
2175
|
+
},
|
|
2176
|
+
solution_mined: {
|
|
2177
|
+
category: "solution",
|
|
2178
|
+
label: "Mined Solution",
|
|
2179
|
+
description: "Problem + solution mined automatically from a developer coding session (the distilled-path pipeline).",
|
|
2180
|
+
icon: "Lightbulb",
|
|
2181
|
+
aliases: ["solution", "mined_solution", "distilled_path"],
|
|
2182
|
+
autoApproved: true,
|
|
2183
|
+
producedBy: ["POST /api/v1/memory/solutions/mined"]
|
|
2184
|
+
},
|
|
2185
|
+
solution_qna: {
|
|
2186
|
+
category: "solution",
|
|
2187
|
+
label: "Q&A Solution",
|
|
2188
|
+
description: "Q&A answer marked verified by a user and distilled into reusable knowledge \u2014 promoted out of a conversation thread.",
|
|
2189
|
+
icon: "ThumbsUp",
|
|
2190
|
+
aliases: ["verified_answer", "verified-answer"],
|
|
2191
|
+
autoApproved: true,
|
|
2192
|
+
producedBy: ["POST /api/v1/memory/recall/messages/:id/feedback"]
|
|
2193
|
+
}
|
|
2194
|
+
};
|
|
2195
|
+
__seenAliases = /* @__PURE__ */ new Set();
|
|
2196
|
+
for (const [id, meta3] of Object.entries(ARTIFACT_TYPES)) {
|
|
2197
|
+
for (const a of meta3.aliases) {
|
|
2198
|
+
if (__seenAliases.has(a)) {
|
|
2199
|
+
throw new Error(
|
|
2200
|
+
`[taxonomy] alias "${a}" declared on multiple artifact types; last seen on "${id}"`
|
|
2201
|
+
);
|
|
2202
|
+
}
|
|
2203
|
+
__seenAliases.add(a);
|
|
2204
|
+
}
|
|
2205
|
+
}
|
|
2206
|
+
ALIAS_REVERSE_MAP = Object.freeze(
|
|
2207
|
+
Object.fromEntries(
|
|
2208
|
+
Object.entries(ARTIFACT_TYPES).flatMap(
|
|
2209
|
+
([id, meta3]) => meta3.aliases.map((a) => [a, id])
|
|
2210
|
+
)
|
|
2211
|
+
)
|
|
2212
|
+
);
|
|
2213
|
+
ARTIFACT_TYPE_IDS = Object.keys(
|
|
2214
|
+
ARTIFACT_TYPES
|
|
2215
|
+
);
|
|
2216
|
+
AUTO_APPROVED_ARTIFACT_TYPES = ARTIFACT_TYPE_IDS.filter((id) => ARTIFACT_TYPES[id].autoApproved);
|
|
2217
|
+
}
|
|
2218
|
+
});
|
|
2219
|
+
|
|
2220
|
+
// ../../packages/@company/types/src/embedding.ts
|
|
2221
|
+
var init_embedding = __esm({
|
|
2222
|
+
"../../packages/@company/types/src/embedding.ts"() {
|
|
2223
|
+
"use strict";
|
|
2101
2224
|
}
|
|
2102
2225
|
});
|
|
2103
2226
|
|
|
@@ -2110,6 +2233,7 @@ var init_src = __esm({
|
|
|
2110
2233
|
init_timeline();
|
|
2111
2234
|
init_artifact();
|
|
2112
2235
|
init_taxonomy();
|
|
2236
|
+
init_embedding();
|
|
2113
2237
|
}
|
|
2114
2238
|
});
|
|
2115
2239
|
|
|
@@ -56865,11 +56989,11 @@ async function apiPost(path, body, options) {
|
|
|
56865
56989
|
}
|
|
56866
56990
|
async function main3() {
|
|
56867
56991
|
try {
|
|
56868
|
-
await apiGet2("/
|
|
56992
|
+
await apiGet2("/memory/solutions/recent?limit=1");
|
|
56869
56993
|
} catch {
|
|
56870
56994
|
}
|
|
56871
56995
|
try {
|
|
56872
|
-
await apiGet2("/users/me/preferences");
|
|
56996
|
+
await apiGet2("/workspace/users/me/preferences");
|
|
56873
56997
|
} catch {
|
|
56874
56998
|
}
|
|
56875
56999
|
triggerCollectInBackground();
|
|
@@ -57081,7 +57205,7 @@ var init_mcp_server2 = __esm({
|
|
|
57081
57205
|
extraHeaders["X-Session-Org-Id"] = String(_context.orgId);
|
|
57082
57206
|
}
|
|
57083
57207
|
const data = await apiGet2(
|
|
57084
|
-
`/
|
|
57208
|
+
`/memory/solutions/search?q=${encodeURIComponent(query)}&top_k=${k}`,
|
|
57085
57209
|
{ extraHeaders }
|
|
57086
57210
|
);
|
|
57087
57211
|
if (!data.results || data.results.length === 0) {
|
|
@@ -57113,7 +57237,7 @@ var init_mcp_server2 = __esm({
|
|
|
57113
57237
|
if (_context?.orgId) {
|
|
57114
57238
|
extraHeaders["X-Session-Org-Id"] = String(_context.orgId);
|
|
57115
57239
|
}
|
|
57116
|
-
const data = await apiGet2(`/
|
|
57240
|
+
const data = await apiGet2(`/memory/solutions/recent?limit=${n}`, {
|
|
57117
57241
|
extraHeaders
|
|
57118
57242
|
});
|
|
57119
57243
|
if (!data.results || data.results.length === 0) {
|
|
@@ -57156,7 +57280,7 @@ var init_mcp_server2 = __esm({
|
|
|
57156
57280
|
extraHeaders["X-Session-Org-Id"] = String(_context.orgId);
|
|
57157
57281
|
}
|
|
57158
57282
|
const data = await apiPost(
|
|
57159
|
-
"/
|
|
57283
|
+
"/memory/solutions/mined",
|
|
57160
57284
|
{
|
|
57161
57285
|
problem_description,
|
|
57162
57286
|
solution_summary,
|
|
@@ -57218,7 +57342,26 @@ function resolveHaansiBin() {
|
|
|
57218
57342
|
}
|
|
57219
57343
|
return "haansi";
|
|
57220
57344
|
}
|
|
57221
|
-
|
|
57345
|
+
function resolveToken3() {
|
|
57346
|
+
if (process.env.HAANSI_TOKEN) return process.env.HAANSI_TOKEN;
|
|
57347
|
+
if ((0, import_node_fs3.existsSync)(CREDENTIALS_FILE5)) {
|
|
57348
|
+
try {
|
|
57349
|
+
const creds = JSON.parse((0, import_node_fs3.readFileSync)(CREDENTIALS_FILE5, "utf-8"));
|
|
57350
|
+
if (typeof creds.token === "string" && creds.token) return creds.token;
|
|
57351
|
+
} catch {
|
|
57352
|
+
}
|
|
57353
|
+
}
|
|
57354
|
+
return null;
|
|
57355
|
+
}
|
|
57356
|
+
function parseTarget(arg) {
|
|
57357
|
+
if (!arg || arg === "all") return "all";
|
|
57358
|
+
if (arg === "solutions" || arg === "exchange") return arg;
|
|
57359
|
+
throw new Error(
|
|
57360
|
+
`Unknown target: ${arg}. Use one of: solutions, exchange, all (default).`
|
|
57361
|
+
);
|
|
57362
|
+
}
|
|
57363
|
+
async function setupMcp(targetArg) {
|
|
57364
|
+
const target = parseTarget(targetArg);
|
|
57222
57365
|
let config6 = {};
|
|
57223
57366
|
if ((0, import_node_fs3.existsSync)(CLAUDE_JSON)) {
|
|
57224
57367
|
try {
|
|
@@ -57229,22 +57372,44 @@ async function setupMcp() {
|
|
|
57229
57372
|
);
|
|
57230
57373
|
}
|
|
57231
57374
|
}
|
|
57232
|
-
if (!config6.mcpServers) {
|
|
57233
|
-
|
|
57375
|
+
if (!config6.mcpServers) config6.mcpServers = {};
|
|
57376
|
+
const installed = [];
|
|
57377
|
+
const warnings = [];
|
|
57378
|
+
if (target === "all" || target === "solutions") {
|
|
57379
|
+
const haansiBin = resolveHaansiBin();
|
|
57380
|
+
config6.mcpServers["haansi-solutions"] = {
|
|
57381
|
+
command: haansiBin,
|
|
57382
|
+
args: ["mcp-server"]
|
|
57383
|
+
};
|
|
57384
|
+
installed.push(`haansi-solutions (stdio \u2192 ${haansiBin} mcp-server)`);
|
|
57385
|
+
}
|
|
57386
|
+
if (target === "all" || target === "exchange") {
|
|
57387
|
+
const token = resolveToken3();
|
|
57388
|
+
if (!token) {
|
|
57389
|
+
const msg = "haansi-exchange not registered: no token found. Run `haansi auth login` first, or set HAANSI_TOKEN.";
|
|
57390
|
+
if (target === "exchange") {
|
|
57391
|
+
console.error(msg);
|
|
57392
|
+
process.exit(1);
|
|
57393
|
+
}
|
|
57394
|
+
warnings.push(msg);
|
|
57395
|
+
} else {
|
|
57396
|
+
const apiUrl = process.env.HAANSI_API_URL ?? DEFAULT_API_URL5;
|
|
57397
|
+
const exchangeUrl = `${apiUrl.replace(/\/+$/, "")}/api/v1/access/exchange/mcp`;
|
|
57398
|
+
config6.mcpServers["haansi-exchange"] = {
|
|
57399
|
+
type: "http",
|
|
57400
|
+
url: exchangeUrl,
|
|
57401
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
57402
|
+
};
|
|
57403
|
+
installed.push(`haansi-exchange (http \u2192 ${exchangeUrl})`);
|
|
57404
|
+
}
|
|
57234
57405
|
}
|
|
57235
|
-
const haansiBin = resolveHaansiBin();
|
|
57236
|
-
config6.mcpServers["haansi-solutions"] = {
|
|
57237
|
-
command: haansiBin,
|
|
57238
|
-
args: ["mcp-server"]
|
|
57239
|
-
};
|
|
57240
57406
|
(0, import_node_fs3.writeFileSync)(CLAUDE_JSON, JSON.stringify(config6, null, 2) + "\n", "utf-8");
|
|
57241
|
-
console.log(`MCP
|
|
57242
|
-
console.log(`
|
|
57243
|
-
console.log(
|
|
57244
|
-
|
|
57245
|
-
);
|
|
57407
|
+
console.log(`MCP servers configured in ${CLAUDE_JSON}`);
|
|
57408
|
+
for (const entry of installed) console.log(` \u2022 ${entry}`);
|
|
57409
|
+
for (const w of warnings) console.log(` ! ${w}`);
|
|
57410
|
+
console.log("\nRestart Claude Code to activate the changes.");
|
|
57246
57411
|
}
|
|
57247
|
-
var import_node_fs3, import_node_path3, import_node_os3, import_node_child_process2, CLAUDE_JSON;
|
|
57412
|
+
var import_node_fs3, import_node_path3, import_node_os3, import_node_child_process2, CLAUDE_JSON, CREDENTIALS_FILE5, DEFAULT_API_URL5;
|
|
57248
57413
|
var init_setup_mcp = __esm({
|
|
57249
57414
|
"src/commands/setup-mcp.ts"() {
|
|
57250
57415
|
"use strict";
|
|
@@ -57253,6 +57418,8 @@ var init_setup_mcp = __esm({
|
|
|
57253
57418
|
import_node_os3 = require("node:os");
|
|
57254
57419
|
import_node_child_process2 = require("node:child_process");
|
|
57255
57420
|
CLAUDE_JSON = (0, import_node_path3.join)((0, import_node_os3.homedir)(), ".claude.json");
|
|
57421
|
+
CREDENTIALS_FILE5 = (0, import_node_path3.join)((0, import_node_os3.homedir)(), ".haansi", "credentials.json");
|
|
57422
|
+
DEFAULT_API_URL5 = "https://api.haansi.co";
|
|
57256
57423
|
}
|
|
57257
57424
|
});
|
|
57258
57425
|
|
|
@@ -57355,11 +57522,11 @@ var config_exports = {};
|
|
|
57355
57522
|
__export(config_exports, {
|
|
57356
57523
|
config: () => config5
|
|
57357
57524
|
});
|
|
57358
|
-
function
|
|
57525
|
+
function resolveToken4() {
|
|
57359
57526
|
if (process.env.HAANSI_TOKEN) return process.env.HAANSI_TOKEN;
|
|
57360
|
-
if ((0, import_node_fs5.existsSync)(
|
|
57527
|
+
if ((0, import_node_fs5.existsSync)(CREDENTIALS_FILE6)) {
|
|
57361
57528
|
try {
|
|
57362
|
-
const creds = JSON.parse((0, import_node_fs5.readFileSync)(
|
|
57529
|
+
const creds = JSON.parse((0, import_node_fs5.readFileSync)(CREDENTIALS_FILE6, "utf-8"));
|
|
57363
57530
|
if (creds.token) return creds.token;
|
|
57364
57531
|
} catch (err) {
|
|
57365
57532
|
console.error("Failed to read credentials file:", err);
|
|
@@ -57368,7 +57535,7 @@ function resolveToken3() {
|
|
|
57368
57535
|
return null;
|
|
57369
57536
|
}
|
|
57370
57537
|
async function config5(args) {
|
|
57371
|
-
const token =
|
|
57538
|
+
const token = resolveToken4();
|
|
57372
57539
|
if (!token) {
|
|
57373
57540
|
console.error(
|
|
57374
57541
|
"Error: No token found. Run `haansi init` or set HAANSI_TOKEN."
|
|
@@ -57376,13 +57543,16 @@ async function config5(args) {
|
|
|
57376
57543
|
process.exit(1);
|
|
57377
57544
|
return;
|
|
57378
57545
|
}
|
|
57379
|
-
const apiUrl = process.env.HAANSI_API_URL ??
|
|
57546
|
+
const apiUrl = process.env.HAANSI_API_URL ?? DEFAULT_API_URL6;
|
|
57380
57547
|
const subcommand = args[0];
|
|
57381
57548
|
if (subcommand === "get") {
|
|
57382
57549
|
const key = args[1];
|
|
57383
|
-
const response = await fetch(
|
|
57384
|
-
|
|
57385
|
-
|
|
57550
|
+
const response = await fetch(
|
|
57551
|
+
`${apiUrl}/api/v1/workspace/users/me/preferences`,
|
|
57552
|
+
{
|
|
57553
|
+
headers: { Authorization: `Bearer ${token}` }
|
|
57554
|
+
}
|
|
57555
|
+
);
|
|
57386
57556
|
if (!response.ok) {
|
|
57387
57557
|
const body = await response.text().catch(() => "");
|
|
57388
57558
|
console.error(
|
|
@@ -57424,14 +57594,17 @@ async function config5(args) {
|
|
|
57424
57594
|
process.exit(1);
|
|
57425
57595
|
return;
|
|
57426
57596
|
}
|
|
57427
|
-
const response = await fetch(
|
|
57428
|
-
|
|
57429
|
-
|
|
57430
|
-
|
|
57431
|
-
|
|
57432
|
-
|
|
57433
|
-
|
|
57434
|
-
|
|
57597
|
+
const response = await fetch(
|
|
57598
|
+
`${apiUrl}/api/v1/workspace/users/me/preferences`,
|
|
57599
|
+
{
|
|
57600
|
+
method: "PATCH",
|
|
57601
|
+
headers: {
|
|
57602
|
+
Authorization: `Bearer ${token}`,
|
|
57603
|
+
"Content-Type": "application/json"
|
|
57604
|
+
},
|
|
57605
|
+
body: JSON.stringify({ [key]: value })
|
|
57606
|
+
}
|
|
57607
|
+
);
|
|
57435
57608
|
if (!response.ok) {
|
|
57436
57609
|
const body = await response.text().catch(() => "");
|
|
57437
57610
|
console.error(
|
|
@@ -57451,15 +57624,15 @@ Supported keys:
|
|
|
57451
57624
|
if (subcommand !== void 0) process.exit(1);
|
|
57452
57625
|
}
|
|
57453
57626
|
}
|
|
57454
|
-
var import_node_fs5, import_node_path5, import_node_os5,
|
|
57627
|
+
var import_node_fs5, import_node_path5, import_node_os5, DEFAULT_API_URL6, CREDENTIALS_FILE6, VALID_SESSION_MODES;
|
|
57455
57628
|
var init_config = __esm({
|
|
57456
57629
|
"src/commands/config.ts"() {
|
|
57457
57630
|
"use strict";
|
|
57458
57631
|
import_node_fs5 = require("node:fs");
|
|
57459
57632
|
import_node_path5 = require("node:path");
|
|
57460
57633
|
import_node_os5 = require("node:os");
|
|
57461
|
-
|
|
57462
|
-
|
|
57634
|
+
DEFAULT_API_URL6 = "https://api.haansi.co";
|
|
57635
|
+
CREDENTIALS_FILE6 = (0, import_node_path5.join)((0, import_node_os5.homedir)(), ".haansi", "credentials.json");
|
|
57463
57636
|
VALID_SESSION_MODES = ["private", "org"];
|
|
57464
57637
|
}
|
|
57465
57638
|
});
|
|
@@ -57471,11 +57644,11 @@ __export(list_exports, {
|
|
|
57471
57644
|
saveKnowledge: () => saveKnowledge,
|
|
57472
57645
|
searchKnowledge: () => searchKnowledge
|
|
57473
57646
|
});
|
|
57474
|
-
function
|
|
57647
|
+
function resolveToken5() {
|
|
57475
57648
|
if (process.env.HAANSI_TOKEN) return process.env.HAANSI_TOKEN;
|
|
57476
|
-
if ((0, import_node_fs6.existsSync)(
|
|
57649
|
+
if ((0, import_node_fs6.existsSync)(CREDENTIALS_FILE7)) {
|
|
57477
57650
|
try {
|
|
57478
|
-
const creds = JSON.parse((0, import_node_fs6.readFileSync)(
|
|
57651
|
+
const creds = JSON.parse((0, import_node_fs6.readFileSync)(CREDENTIALS_FILE7, "utf-8"));
|
|
57479
57652
|
if (creds.token) return creds.token;
|
|
57480
57653
|
} catch (err) {
|
|
57481
57654
|
console.error("Failed to read credentials file:", err);
|
|
@@ -57509,18 +57682,18 @@ async function apiPost2(path, body, token, apiUrl) {
|
|
|
57509
57682
|
return response.json();
|
|
57510
57683
|
}
|
|
57511
57684
|
async function list(options) {
|
|
57512
|
-
const apiUrl = process.env.HAANSI_API_URL ??
|
|
57513
|
-
const token =
|
|
57685
|
+
const apiUrl = process.env.HAANSI_API_URL ?? DEFAULT_API_URL7;
|
|
57686
|
+
const token = resolveToken5();
|
|
57514
57687
|
let data;
|
|
57515
57688
|
if (options.search) {
|
|
57516
57689
|
data = await apiGet3(
|
|
57517
|
-
`/
|
|
57690
|
+
`/memory/solutions/search?q=${encodeURIComponent(options.search)}&top_k=${options.limit}`,
|
|
57518
57691
|
token,
|
|
57519
57692
|
apiUrl
|
|
57520
57693
|
);
|
|
57521
57694
|
} else {
|
|
57522
57695
|
data = await apiGet3(
|
|
57523
|
-
`/
|
|
57696
|
+
`/memory/solutions/recent?limit=${options.limit}`,
|
|
57524
57697
|
token,
|
|
57525
57698
|
apiUrl
|
|
57526
57699
|
);
|
|
@@ -57535,9 +57708,9 @@ async function list(options) {
|
|
|
57535
57708
|
${data.results.length} result(s)`);
|
|
57536
57709
|
}
|
|
57537
57710
|
async function searchKnowledge(options) {
|
|
57538
|
-
const apiUrl = process.env.HAANSI_API_URL ??
|
|
57539
|
-
const token =
|
|
57540
|
-
let url2 = `/
|
|
57711
|
+
const apiUrl = process.env.HAANSI_API_URL ?? DEFAULT_API_URL7;
|
|
57712
|
+
const token = resolveToken5();
|
|
57713
|
+
let url2 = `/memory/solutions/knowledge/search?q=${encodeURIComponent(options.query)}&limit=${options.limit}`;
|
|
57541
57714
|
if (options.artifactType) {
|
|
57542
57715
|
url2 += `&artifact_type=${encodeURIComponent(options.artifactType)}`;
|
|
57543
57716
|
}
|
|
@@ -57552,8 +57725,8 @@ async function searchKnowledge(options) {
|
|
|
57552
57725
|
${data.results.length} result(s)`);
|
|
57553
57726
|
}
|
|
57554
57727
|
async function saveKnowledge(options) {
|
|
57555
|
-
const apiUrl = process.env.HAANSI_API_URL ??
|
|
57556
|
-
const token =
|
|
57728
|
+
const apiUrl = process.env.HAANSI_API_URL ?? DEFAULT_API_URL7;
|
|
57729
|
+
const token = resolveToken5();
|
|
57557
57730
|
const body = {
|
|
57558
57731
|
problem_description: options.problem,
|
|
57559
57732
|
solution_summary: options.solution,
|
|
@@ -57562,21 +57735,26 @@ async function saveKnowledge(options) {
|
|
|
57562
57735
|
if (options.sessionType) body.session_type = options.sessionType;
|
|
57563
57736
|
if (options.complexity) body.complexity = options.complexity;
|
|
57564
57737
|
if (options.tags) body.tags = options.tags;
|
|
57565
|
-
const data = await apiPost2(
|
|
57738
|
+
const data = await apiPost2(
|
|
57739
|
+
"/memory/solutions/mined",
|
|
57740
|
+
body,
|
|
57741
|
+
token,
|
|
57742
|
+
apiUrl
|
|
57743
|
+
);
|
|
57566
57744
|
console.log("Knowledge saved successfully.");
|
|
57567
57745
|
console.log(` Problem: ${data.problem_description}`);
|
|
57568
57746
|
console.log(` Solution: ${data.solution_summary}`);
|
|
57569
57747
|
console.log("\nThis is now searchable via `haansi search-solutions`.");
|
|
57570
57748
|
}
|
|
57571
|
-
var import_node_fs6, import_node_path6, import_node_os6,
|
|
57749
|
+
var import_node_fs6, import_node_path6, import_node_os6, DEFAULT_API_URL7, CREDENTIALS_FILE7;
|
|
57572
57750
|
var init_list = __esm({
|
|
57573
57751
|
"src/commands/list.ts"() {
|
|
57574
57752
|
"use strict";
|
|
57575
57753
|
import_node_fs6 = require("node:fs");
|
|
57576
57754
|
import_node_path6 = require("node:path");
|
|
57577
57755
|
import_node_os6 = require("node:os");
|
|
57578
|
-
|
|
57579
|
-
|
|
57756
|
+
DEFAULT_API_URL7 = "https://api.haansi.co";
|
|
57757
|
+
CREDENTIALS_FILE7 = (0, import_node_path6.join)((0, import_node_os6.homedir)(), ".haansi", "credentials.json");
|
|
57580
57758
|
}
|
|
57581
57759
|
});
|
|
57582
57760
|
|
|
@@ -57638,7 +57816,8 @@ Collector done: ${uploaded} uploaded, ${skipped} unchanged, ${errors} errors`
|
|
|
57638
57816
|
}
|
|
57639
57817
|
case "setup-mcp": {
|
|
57640
57818
|
const { setupMcp: setupMcp2 } = await Promise.resolve().then(() => (init_setup_mcp(), setup_mcp_exports));
|
|
57641
|
-
|
|
57819
|
+
const targetArg = process.argv[3];
|
|
57820
|
+
await setupMcp2(targetArg);
|
|
57642
57821
|
break;
|
|
57643
57822
|
}
|
|
57644
57823
|
case "setup-daemon": {
|
|
@@ -57742,7 +57921,10 @@ Commands:
|
|
|
57742
57921
|
|
|
57743
57922
|
daemon Run the collector on a schedule (every 30 min)
|
|
57744
57923
|
mcp-server Start the Haansi MCP server (used by Claude Code)
|
|
57745
|
-
setup-mcp
|
|
57924
|
+
setup-mcp [target] Register MCP servers in ~/.claude.json
|
|
57925
|
+
target: solutions | exchange | all (default: all)
|
|
57926
|
+
- solutions: stdio, per-org search/save tools
|
|
57927
|
+
- exchange: http, cross-org marketplace (read-only)
|
|
57746
57928
|
setup-daemon Install launchd service to auto-start daemon on login (macOS)
|
|
57747
57929
|
help Show this help message
|
|
57748
57930
|
|