haansi 0.1.19 → 0.1.24

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 +186 -57
  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.19",
42
+ version: "0.1.24",
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)
@@ -1991,23 +1998,18 @@ var init_collector_daemon = __esm({
1991
1998
  }
1992
1999
  });
1993
2000
 
1994
- // ../../packages/@company/types/src/knowledge.ts
1995
- var init_knowledge = __esm({
1996
- "../../packages/@company/types/src/knowledge.ts"() {
1997
- "use strict";
1998
- }
1999
- });
2000
-
2001
- // ../../packages/@company/types/src/user.ts
2002
- var init_user = __esm({
2003
- "../../packages/@company/types/src/user.ts"() {
2004
- "use strict";
2001
+ // ../service-capture/claude-sessions/http-timeout.ts
2002
+ async function fetchWithTimeout(url2, init2 = {}, timeoutMs = 15e3) {
2003
+ const controller = new AbortController();
2004
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
2005
+ try {
2006
+ return await fetch(url2, { ...init2, signal: controller.signal });
2007
+ } finally {
2008
+ clearTimeout(timer);
2005
2009
  }
2006
- });
2007
-
2008
- // ../../packages/@company/types/src/integration.ts
2009
- var init_integration = __esm({
2010
- "../../packages/@company/types/src/integration.ts"() {
2010
+ }
2011
+ var init_http_timeout = __esm({
2012
+ "../service-capture/claude-sessions/http-timeout.ts"() {
2011
2013
  "use strict";
2012
2014
  }
2013
2015
  });
@@ -2040,7 +2042,7 @@ function normalizeComplexity(raw) {
2040
2042
  if (lower in COMPLEXITIES) return lower;
2041
2043
  return "moderate";
2042
2044
  }
2043
- var SESSION_TYPES, SESSION_TYPE_ALIASES, COMPLEXITIES;
2045
+ var SESSION_TYPES, SESSION_TYPE_ALIASES, COMPLEXITIES, ARTIFACT_TYPES, __seenAliases, ALIAS_REVERSE_MAP, ARTIFACT_TYPE_IDS, AUTO_APPROVED_ARTIFACT_TYPES;
2044
2046
  var init_taxonomy = __esm({
2045
2047
  "../../packages/@company/types/src/taxonomy.ts"() {
2046
2048
  "use strict";
@@ -2098,18 +2100,132 @@ var init_taxonomy = __esm({
2098
2100
  description: "Involved task with many steps or deep analysis"
2099
2101
  }
2100
2102
  };
2103
+ ARTIFACT_TYPES = {
2104
+ report_incident: {
2105
+ category: "report",
2106
+ label: "Incident Report",
2107
+ description: "Production-incident record + post-incident writeup: detection, timeline, root cause, resolution, follow-ups.",
2108
+ icon: "AlertTriangle",
2109
+ aliases: ["incident_summary", "incident", "postmortem", "post-mortem"],
2110
+ autoApproved: false,
2111
+ producedBy: [
2112
+ "POST /api/v1/memory/processes/incidents",
2113
+ "POST /api/v1/memory/reports/incident",
2114
+ "POST /api/v1/memory/processes/incidents/:id/postmortem"
2115
+ ]
2116
+ },
2117
+ report_decision: {
2118
+ category: "report",
2119
+ label: "Decision Record",
2120
+ description: "Architectural / product decision record with context, options considered, decision, and rationale.",
2121
+ icon: "Scale",
2122
+ aliases: ["decision_record", "decision-record", "adr"],
2123
+ autoApproved: false,
2124
+ producedBy: ["POST /api/v1/memory"]
2125
+ },
2126
+ report_work: {
2127
+ category: "report",
2128
+ label: "Work Report",
2129
+ description: "Periodic or one-off work-progress report \u2014 status updates, weekly digests, project rollups, team-activity summaries.",
2130
+ icon: "CalendarDays",
2131
+ aliases: ["weekly_digest", "weekly-digest", "status_report"],
2132
+ autoApproved: true,
2133
+ producedBy: ["POST /api/v1/memory", "POST /api/v1/memory/reports/work"]
2134
+ },
2135
+ report_sop: {
2136
+ category: "report",
2137
+ label: "Standard Operating Procedure",
2138
+ description: "Reusable step-by-step procedure or runbook. Placeholder \u2014 surface not yet specialized; written via generic POST /memory until a dedicated producer ships.",
2139
+ icon: "FileText",
2140
+ aliases: ["sop", "runbook"],
2141
+ autoApproved: false,
2142
+ producedBy: ["POST /api/v1/memory"]
2143
+ },
2144
+ report_onboarding: {
2145
+ category: "report",
2146
+ label: "Onboarding Packet",
2147
+ description: "Onboarding guide assembled from team knowledge, scoped to a project or role.",
2148
+ icon: "GraduationCap",
2149
+ aliases: ["onboarding_packet", "onboarding-packet"],
2150
+ autoApproved: false,
2151
+ producedBy: ["POST /api/v1/memory/reports/onboarding"]
2152
+ },
2153
+ report_pr: {
2154
+ category: "report",
2155
+ label: "PR Context",
2156
+ description: "Enriched pull-request description with linked Jira/Slack context, recent decisions, and reviewer hints.",
2157
+ icon: "GitPullRequest",
2158
+ aliases: ["pr_context", "pr-context"],
2159
+ autoApproved: true,
2160
+ producedBy: ["POST /api/v1/memory/reports/pr"]
2161
+ },
2162
+ expert: {
2163
+ category: "expert",
2164
+ label: "Expert Profile",
2165
+ description: "Per-person expertise profile across platforms \u2014 areas of focus, recent contributions, identity links.",
2166
+ icon: "Users",
2167
+ aliases: ["expert_profile", "expert-profile"],
2168
+ autoApproved: false,
2169
+ producedBy: ["POST /api/v1/memory/experts"]
2170
+ },
2171
+ solution_mined: {
2172
+ category: "solution",
2173
+ label: "Mined Solution",
2174
+ description: "Problem + solution mined automatically from a developer coding session (the distilled-path pipeline).",
2175
+ icon: "Lightbulb",
2176
+ aliases: ["solution", "mined_solution", "distilled_path"],
2177
+ autoApproved: true,
2178
+ producedBy: ["POST /api/v1/memory/solutions/mined"]
2179
+ },
2180
+ solution_qna: {
2181
+ category: "solution",
2182
+ label: "Q&A Solution",
2183
+ description: "Q&A answer marked verified by a user and distilled into reusable knowledge \u2014 promoted out of a conversation thread.",
2184
+ icon: "ThumbsUp",
2185
+ aliases: ["verified_answer", "verified-answer"],
2186
+ autoApproved: true,
2187
+ producedBy: ["POST /api/v1/memory/recall/messages/:id/feedback"]
2188
+ }
2189
+ };
2190
+ __seenAliases = /* @__PURE__ */ new Set();
2191
+ for (const [id, meta3] of Object.entries(ARTIFACT_TYPES)) {
2192
+ for (const a of meta3.aliases) {
2193
+ if (__seenAliases.has(a)) {
2194
+ throw new Error(
2195
+ `[taxonomy] alias "${a}" declared on multiple artifact types; last seen on "${id}"`
2196
+ );
2197
+ }
2198
+ __seenAliases.add(a);
2199
+ }
2200
+ }
2201
+ ALIAS_REVERSE_MAP = Object.freeze(
2202
+ Object.fromEntries(
2203
+ Object.entries(ARTIFACT_TYPES).flatMap(
2204
+ ([id, meta3]) => meta3.aliases.map((a) => [a, id])
2205
+ )
2206
+ )
2207
+ );
2208
+ ARTIFACT_TYPE_IDS = Object.keys(
2209
+ ARTIFACT_TYPES
2210
+ );
2211
+ AUTO_APPROVED_ARTIFACT_TYPES = ARTIFACT_TYPE_IDS.filter((id) => ARTIFACT_TYPES[id].autoApproved);
2212
+ }
2213
+ });
2214
+
2215
+ // ../../packages/@company/types/src/embedding.ts
2216
+ var init_embedding = __esm({
2217
+ "../../packages/@company/types/src/embedding.ts"() {
2218
+ "use strict";
2101
2219
  }
2102
2220
  });
2103
2221
 
2104
2222
  // ../../packages/@company/types/src/index.ts
2105
2223
  var init_src = __esm({
2106
2224
  "../../packages/@company/types/src/index.ts"() {
2107
- init_knowledge();
2108
- init_user();
2109
- init_integration();
2110
2225
  init_timeline();
2111
2226
  init_artifact();
2112
2227
  init_taxonomy();
2228
+ init_embedding();
2113
2229
  }
2114
2230
  });
2115
2231
 
@@ -56839,7 +56955,9 @@ async function apiGet2(path, options) {
56839
56955
  Authorization: `Bearer ${TOKEN}`,
56840
56956
  ...options?.extraHeaders
56841
56957
  };
56842
- const response = await fetch(`${API_URL}/api/v1${path}`, { headers });
56958
+ const response = await fetchWithTimeout(`${API_URL}/api/v1${path}`, {
56959
+ headers
56960
+ });
56843
56961
  if (!response.ok) {
56844
56962
  const body = await response.text().catch(() => "");
56845
56963
  throw new Error(`API error ${response.status}: ${body.slice(0, 200)}`);
@@ -56852,7 +56970,7 @@ async function apiPost(path, body, options) {
56852
56970
  "Content-Type": "application/json",
56853
56971
  ...options?.extraHeaders
56854
56972
  };
56855
- const response = await fetch(`${API_URL}/api/v1${path}`, {
56973
+ const response = await fetchWithTimeout(`${API_URL}/api/v1${path}`, {
56856
56974
  method: "POST",
56857
56975
  headers,
56858
56976
  body: JSON.stringify(body)
@@ -56863,16 +56981,14 @@ async function apiPost(path, body, options) {
56863
56981
  }
56864
56982
  return response.json();
56865
56983
  }
56866
- async function main3() {
56867
- try {
56868
- await apiGet2("/sessions/recent?limit=1");
56869
- } catch {
56870
- }
56871
- try {
56872
- await apiGet2("/users/me/preferences");
56873
- } catch {
56874
- }
56984
+ function warmupInBackground() {
56985
+ void apiGet2("/memory/solutions/recent?limit=1").catch(() => {
56986
+ });
56987
+ void apiGet2("/workspace/users/me/preferences").catch(() => {
56988
+ });
56875
56989
  triggerCollectInBackground();
56990
+ }
56991
+ async function main3() {
56876
56992
  const transportMode = process.env.MCP_TRANSPORT || "stdio";
56877
56993
  if (transportMode === "http") {
56878
56994
  const express = await Promise.resolve().then(() => __toESM(require_express2()));
@@ -56895,6 +57011,7 @@ async function main3() {
56895
57011
  const transport = new StdioServerTransport();
56896
57012
  await mcpServer.connect(transport);
56897
57013
  }
57014
+ warmupInBackground();
56898
57015
  }
56899
57016
  var import_dotenv3, import_path3, import_fs3, import_os2, DEFAULT_API_URL4, CREDENTIALS_FILE4, API_URL, TOKEN, contextSchema, isCollecting, lastCollectTime, COLLECT_COOLDOWN_MS, mcpServer, server;
56900
57017
  var init_mcp_server2 = __esm({
@@ -56905,6 +57022,7 @@ var init_mcp_server2 = __esm({
56905
57022
  import_fs3 = require("fs");
56906
57023
  import_os2 = require("os");
56907
57024
  init_collector();
57025
+ init_http_timeout();
56908
57026
  init_src();
56909
57027
  init_mcp();
56910
57028
  init_stdio2();
@@ -57081,7 +57199,7 @@ var init_mcp_server2 = __esm({
57081
57199
  extraHeaders["X-Session-Org-Id"] = String(_context.orgId);
57082
57200
  }
57083
57201
  const data = await apiGet2(
57084
- `/sessions/search?q=${encodeURIComponent(query)}&top_k=${k}`,
57202
+ `/memory/solutions/search?q=${encodeURIComponent(query)}&top_k=${k}`,
57085
57203
  { extraHeaders }
57086
57204
  );
57087
57205
  if (!data.results || data.results.length === 0) {
@@ -57113,7 +57231,7 @@ var init_mcp_server2 = __esm({
57113
57231
  if (_context?.orgId) {
57114
57232
  extraHeaders["X-Session-Org-Id"] = String(_context.orgId);
57115
57233
  }
57116
- const data = await apiGet2(`/sessions/recent?limit=${n}`, {
57234
+ const data = await apiGet2(`/memory/solutions/recent?limit=${n}`, {
57117
57235
  extraHeaders
57118
57236
  });
57119
57237
  if (!data.results || data.results.length === 0) {
@@ -57156,7 +57274,7 @@ var init_mcp_server2 = __esm({
57156
57274
  extraHeaders["X-Session-Org-Id"] = String(_context.orgId);
57157
57275
  }
57158
57276
  const data = await apiPost(
57159
- "/sessions/knowledge",
57277
+ "/memory/solutions/mined",
57160
57278
  {
57161
57279
  problem_description,
57162
57280
  solution_summary,
@@ -57270,7 +57388,7 @@ async function setupMcp(targetArg) {
57270
57388
  warnings.push(msg);
57271
57389
  } else {
57272
57390
  const apiUrl = process.env.HAANSI_API_URL ?? DEFAULT_API_URL5;
57273
- const exchangeUrl = `${apiUrl.replace(/\/+$/, "")}/api/v1/mcp/exchange`;
57391
+ const exchangeUrl = `${apiUrl.replace(/\/+$/, "")}/api/v1/access/exchange/mcp`;
57274
57392
  config6.mcpServers["haansi-exchange"] = {
57275
57393
  type: "http",
57276
57394
  url: exchangeUrl,
@@ -57423,9 +57541,12 @@ async function config5(args) {
57423
57541
  const subcommand = args[0];
57424
57542
  if (subcommand === "get") {
57425
57543
  const key = args[1];
57426
- const response = await fetch(`${apiUrl}/api/v1/users/me/preferences`, {
57427
- headers: { Authorization: `Bearer ${token}` }
57428
- });
57544
+ const response = await fetch(
57545
+ `${apiUrl}/api/v1/workspace/users/me/preferences`,
57546
+ {
57547
+ headers: { Authorization: `Bearer ${token}` }
57548
+ }
57549
+ );
57429
57550
  if (!response.ok) {
57430
57551
  const body = await response.text().catch(() => "");
57431
57552
  console.error(
@@ -57467,14 +57588,17 @@ async function config5(args) {
57467
57588
  process.exit(1);
57468
57589
  return;
57469
57590
  }
57470
- const response = await fetch(`${apiUrl}/api/v1/users/me/preferences`, {
57471
- method: "PATCH",
57472
- headers: {
57473
- Authorization: `Bearer ${token}`,
57474
- "Content-Type": "application/json"
57475
- },
57476
- body: JSON.stringify({ [key]: value })
57477
- });
57591
+ const response = await fetch(
57592
+ `${apiUrl}/api/v1/workspace/users/me/preferences`,
57593
+ {
57594
+ method: "PATCH",
57595
+ headers: {
57596
+ Authorization: `Bearer ${token}`,
57597
+ "Content-Type": "application/json"
57598
+ },
57599
+ body: JSON.stringify({ [key]: value })
57600
+ }
57601
+ );
57478
57602
  if (!response.ok) {
57479
57603
  const body = await response.text().catch(() => "");
57480
57604
  console.error(
@@ -57557,13 +57681,13 @@ async function list(options) {
57557
57681
  let data;
57558
57682
  if (options.search) {
57559
57683
  data = await apiGet3(
57560
- `/sessions/search?q=${encodeURIComponent(options.search)}&top_k=${options.limit}`,
57684
+ `/memory/solutions/search?q=${encodeURIComponent(options.search)}&top_k=${options.limit}`,
57561
57685
  token,
57562
57686
  apiUrl
57563
57687
  );
57564
57688
  } else {
57565
57689
  data = await apiGet3(
57566
- `/sessions/recent?limit=${options.limit}`,
57690
+ `/memory/solutions/recent?limit=${options.limit}`,
57567
57691
  token,
57568
57692
  apiUrl
57569
57693
  );
@@ -57580,7 +57704,7 @@ ${data.results.length} result(s)`);
57580
57704
  async function searchKnowledge(options) {
57581
57705
  const apiUrl = process.env.HAANSI_API_URL ?? DEFAULT_API_URL7;
57582
57706
  const token = resolveToken5();
57583
- let url2 = `/sessions/knowledge/search?q=${encodeURIComponent(options.query)}&limit=${options.limit}`;
57707
+ let url2 = `/memory/solutions/knowledge/search?q=${encodeURIComponent(options.query)}&limit=${options.limit}`;
57584
57708
  if (options.artifactType) {
57585
57709
  url2 += `&artifact_type=${encodeURIComponent(options.artifactType)}`;
57586
57710
  }
@@ -57605,7 +57729,12 @@ async function saveKnowledge(options) {
57605
57729
  if (options.sessionType) body.session_type = options.sessionType;
57606
57730
  if (options.complexity) body.complexity = options.complexity;
57607
57731
  if (options.tags) body.tags = options.tags;
57608
- const data = await apiPost2("/sessions/knowledge", body, token, apiUrl);
57732
+ const data = await apiPost2(
57733
+ "/memory/solutions/mined",
57734
+ body,
57735
+ token,
57736
+ apiUrl
57737
+ );
57609
57738
  console.log("Knowledge saved successfully.");
57610
57739
  console.log(` Problem: ${data.problem_description}`);
57611
57740
  console.log(` Solution: ${data.solution_summary}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "haansi",
3
- "version": "0.1.19",
3
+ "version": "0.1.24",
4
4
  "description": "Haansi CLI - Session collector and MCP server for Claude Code",
5
5
  "bin": {
6
6
  "haansi": "./dist/haansi.js"