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.
Files changed (2) hide show
  1. package/dist/haansi.js +246 -64
  2. 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.18",
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(`${apiUrl}/api/v1/sessions/recent?limit=1`, {
210
- headers: { Authorization: `Bearer ${token}` }
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("/sessions/uploaded", apiUrl, token);
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("/sessions/recent?limit=1");
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
- `/sessions/search?q=${encodeURIComponent(query)}&top_k=${k}`,
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(`/sessions/recent?limit=${n}`, {
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
- "/sessions/knowledge",
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
- async function setupMcp() {
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
- config6.mcpServers = {};
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 server configured in ${CLAUDE_JSON}`);
57242
- console.log(` command: ${haansiBin} mcp-server`);
57243
- console.log(
57244
- "\nRestart Claude Code to activate the haansi-solutions MCP server."
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 resolveToken3() {
57525
+ function resolveToken4() {
57359
57526
  if (process.env.HAANSI_TOKEN) return process.env.HAANSI_TOKEN;
57360
- if ((0, import_node_fs5.existsSync)(CREDENTIALS_FILE5)) {
57527
+ if ((0, import_node_fs5.existsSync)(CREDENTIALS_FILE6)) {
57361
57528
  try {
57362
- const creds = JSON.parse((0, import_node_fs5.readFileSync)(CREDENTIALS_FILE5, "utf-8"));
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 = resolveToken3();
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 ?? DEFAULT_API_URL5;
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(`${apiUrl}/api/v1/users/me/preferences`, {
57384
- headers: { Authorization: `Bearer ${token}` }
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(`${apiUrl}/api/v1/users/me/preferences`, {
57428
- method: "PATCH",
57429
- headers: {
57430
- Authorization: `Bearer ${token}`,
57431
- "Content-Type": "application/json"
57432
- },
57433
- body: JSON.stringify({ [key]: value })
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, DEFAULT_API_URL5, CREDENTIALS_FILE5, VALID_SESSION_MODES;
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
- DEFAULT_API_URL5 = "https://api.haansi.co";
57462
- CREDENTIALS_FILE5 = (0, import_node_path5.join)((0, import_node_os5.homedir)(), ".haansi", "credentials.json");
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 resolveToken4() {
57647
+ function resolveToken5() {
57475
57648
  if (process.env.HAANSI_TOKEN) return process.env.HAANSI_TOKEN;
57476
- if ((0, import_node_fs6.existsSync)(CREDENTIALS_FILE6)) {
57649
+ if ((0, import_node_fs6.existsSync)(CREDENTIALS_FILE7)) {
57477
57650
  try {
57478
- const creds = JSON.parse((0, import_node_fs6.readFileSync)(CREDENTIALS_FILE6, "utf-8"));
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 ?? DEFAULT_API_URL6;
57513
- const token = resolveToken4();
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
- `/sessions/search?q=${encodeURIComponent(options.search)}&top_k=${options.limit}`,
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
- `/sessions/recent?limit=${options.limit}`,
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 ?? DEFAULT_API_URL6;
57539
- const token = resolveToken4();
57540
- let url2 = `/sessions/knowledge/search?q=${encodeURIComponent(options.query)}&limit=${options.limit}`;
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 ?? DEFAULT_API_URL6;
57556
- const token = resolveToken4();
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("/sessions/knowledge", body, token, apiUrl);
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, DEFAULT_API_URL6, CREDENTIALS_FILE6;
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
- DEFAULT_API_URL6 = "https://api.haansi.co";
57579
- CREDENTIALS_FILE6 = (0, import_node_path6.join)((0, import_node_os6.homedir)(), ".haansi", "credentials.json");
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
- await setupMcp2();
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 Add haansi-solutions MCP entry to ~/.claude.json
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
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "haansi",
3
- "version": "0.1.18",
3
+ "version": "0.1.23",
4
4
  "description": "Haansi CLI - Session collector and MCP server for Claude Code",
5
5
  "bin": {
6
6
  "haansi": "./dist/haansi.js"