haansi 0.1.7 → 0.1.9

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 +180 -26
  2. package/package.json +1 -1
package/dist/haansi.js CHANGED
@@ -34,6 +34,36 @@ 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
+ // package.json
38
+ var require_package = __commonJS({
39
+ "package.json"(exports2, module2) {
40
+ module2.exports = {
41
+ name: "haansi",
42
+ version: "0.1.9",
43
+ description: "Haansi CLI - Session collector and MCP server for Claude Code",
44
+ bin: {
45
+ haansi: "./dist/haansi.js"
46
+ },
47
+ files: [
48
+ "dist/",
49
+ "README.md"
50
+ ],
51
+ scripts: {
52
+ build: "node build.mjs",
53
+ prepublishOnly: "npm run build"
54
+ },
55
+ devDependencies: {
56
+ esbuild: "^0.27.0",
57
+ typescript: "^5.7.2",
58
+ "@types/node": "^22.10.1"
59
+ },
60
+ engines: {
61
+ node: ">=18.0.0"
62
+ }
63
+ };
64
+ }
65
+ });
66
+
37
67
  // src/commands/init.ts
38
68
  var init_exports = {};
39
69
  __export(init_exports, {
@@ -106,7 +136,7 @@ var init_init = __esm({
106
136
  });
107
137
 
108
138
  // ../../node_modules/dotenv/package.json
109
- var require_package = __commonJS({
139
+ var require_package2 = __commonJS({
110
140
  "../../node_modules/dotenv/package.json"(exports2, module2) {
111
141
  module2.exports = {
112
142
  name: "dotenv",
@@ -180,7 +210,7 @@ var require_main = __commonJS({
180
210
  var path = require("path");
181
211
  var os = require("os");
182
212
  var crypto6 = require("crypto");
183
- var packageJson = require_package();
213
+ var packageJson = require_package2();
184
214
  var version3 = packageJson.version;
185
215
  var LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;
186
216
  function parse4(src) {
@@ -56673,6 +56703,14 @@ var init_mcp_server2 = __esm({
56673
56703
  type: "string",
56674
56704
  description: "Project path or identifier"
56675
56705
  },
56706
+ git_branch: {
56707
+ type: "string",
56708
+ description: "Current git branch name"
56709
+ },
56710
+ git_remote_url: {
56711
+ type: "string",
56712
+ description: "Git remote origin URL (e.g. github.com/org/repo)"
56713
+ },
56676
56714
  tags: {
56677
56715
  type: "array",
56678
56716
  items: { type: "string" },
@@ -56802,6 +56840,8 @@ var init_mcp_server2 = __esm({
56802
56840
  files_modified,
56803
56841
  complexity,
56804
56842
  project_path,
56843
+ git_branch,
56844
+ git_remote_url,
56805
56845
  tags,
56806
56846
  model,
56807
56847
  source_tool,
@@ -56825,6 +56865,8 @@ var init_mcp_server2 = __esm({
56825
56865
  files_modified,
56826
56866
  complexity,
56827
56867
  project_path,
56868
+ git_branch,
56869
+ git_remote_url,
56828
56870
  tags,
56829
56871
  model,
56830
56872
  source_tool
@@ -57123,7 +57165,9 @@ var init_config = __esm({
57123
57165
  // src/commands/list.ts
57124
57166
  var list_exports = {};
57125
57167
  __export(list_exports, {
57126
- list: () => list
57168
+ list: () => list,
57169
+ saveKnowledge: () => saveKnowledge,
57170
+ searchKnowledge: () => searchKnowledge
57127
57171
  });
57128
57172
  function resolveToken4() {
57129
57173
  if (process.env.HAANSI_TOKEN) return process.env.HAANSI_TOKEN;
@@ -57146,6 +57190,21 @@ async function apiGet3(path, token, apiUrl) {
57146
57190
  }
57147
57191
  return response.json();
57148
57192
  }
57193
+ async function apiPost2(path, body, token, apiUrl) {
57194
+ const response = await fetch(`${apiUrl}/api/v1${path}`, {
57195
+ method: "POST",
57196
+ headers: {
57197
+ Authorization: `Bearer ${token}`,
57198
+ "Content-Type": "application/json"
57199
+ },
57200
+ body: JSON.stringify(body)
57201
+ });
57202
+ if (!response.ok) {
57203
+ const text = await response.text().catch(() => "");
57204
+ throw new Error(`API error ${response.status}: ${text.slice(0, 200)}`);
57205
+ }
57206
+ return response.json();
57207
+ }
57149
57208
  async function list(options) {
57150
57209
  const apiUrl = process.env.HAANSI_API_URL ?? DEFAULT_API_URL5;
57151
57210
  const token = resolveToken4();
@@ -57172,6 +57231,41 @@ async function list(options) {
57172
57231
  console.log(`
57173
57232
  ${data.results.length} result(s)`);
57174
57233
  }
57234
+ async function searchKnowledge(options) {
57235
+ const apiUrl = process.env.HAANSI_API_URL ?? DEFAULT_API_URL5;
57236
+ const token = resolveToken4();
57237
+ let url2 = `/sessions/knowledge/search?q=${encodeURIComponent(options.query)}&limit=${options.limit}`;
57238
+ if (options.artifactType) {
57239
+ url2 += `&artifact_type=${encodeURIComponent(options.artifactType)}`;
57240
+ }
57241
+ const data = await apiGet3(url2, token, apiUrl);
57242
+ if (!data.results || data.results.length === 0) {
57243
+ console.log("No knowledge artifacts found matching your query.");
57244
+ return;
57245
+ }
57246
+ const separator = "\n" + "\u2500".repeat(60) + "\n";
57247
+ console.log(data.results.join(separator));
57248
+ console.log(`
57249
+ ${data.results.length} result(s)`);
57250
+ }
57251
+ async function saveKnowledge(options) {
57252
+ const apiUrl = process.env.HAANSI_API_URL ?? DEFAULT_API_URL5;
57253
+ const token = resolveToken4();
57254
+ const body = {
57255
+ problem_description: options.problem,
57256
+ solution_summary: options.solution,
57257
+ source_tool: "haansi-cli"
57258
+ };
57259
+ if (options.sessionType) body.session_type = options.sessionType;
57260
+ if (options.complexity) body.complexity = options.complexity;
57261
+ if (options.tags) body.tags = options.tags;
57262
+ const data = await apiPost2("/sessions/knowledge", body, token, apiUrl);
57263
+ console.log("Knowledge saved successfully.");
57264
+ console.log(` ID: ${data.id}`);
57265
+ console.log(` Problem: ${data.problem_description}`);
57266
+ console.log(` Solution: ${data.solution_summary}`);
57267
+ console.log("\nThis is now searchable via `haansi search-solutions`.");
57268
+ }
57175
57269
  var import_node_fs5, import_node_path5, import_node_os5, DEFAULT_API_URL5, CREDENTIALS_FILE5;
57176
57270
  var init_list = __esm({
57177
57271
  "src/commands/list.ts"() {
@@ -57185,8 +57279,13 @@ var init_list = __esm({
57185
57279
  });
57186
57280
 
57187
57281
  // src/index.ts
57282
+ var { version: VERSION } = require_package();
57188
57283
  var command = process.argv[2];
57189
57284
  async function run2() {
57285
+ if (command === "--version" || command === "-v") {
57286
+ console.log(VERSION);
57287
+ return;
57288
+ }
57190
57289
  switch (command) {
57191
57290
  case "init": {
57192
57291
  const { init: init2 } = await Promise.resolve().then(() => (init_init(), init_exports));
@@ -57237,11 +57336,13 @@ Collector done: ${uploaded} uploaded, ${skipped} unchanged, ${errors} errors`
57237
57336
  await config6(process.argv.slice(3));
57238
57337
  break;
57239
57338
  }
57339
+ // ── Solution & Knowledge commands (consistent with MCP tool names) ──
57340
+ case "search-solutions":
57240
57341
  case "search": {
57241
57342
  const { list: list2 } = await Promise.resolve().then(() => (init_list(), list_exports));
57242
57343
  const query = process.argv[3];
57243
57344
  if (!query || query.startsWith("--")) {
57244
- console.error("Usage: haansi search <query> [--limit <n>]");
57345
+ console.error("Usage: haansi search-solutions <query> [--limit <n>]");
57245
57346
  process.exit(1);
57246
57347
  }
57247
57348
  const limitIdx = process.argv.indexOf("--limit");
@@ -57249,6 +57350,7 @@ Collector done: ${uploaded} uploaded, ${skipped} unchanged, ${errors} errors`
57249
57350
  await list2({ search: query, limit });
57250
57351
  break;
57251
57352
  }
57353
+ case "list-solutions":
57252
57354
  case "list": {
57253
57355
  const { list: list2 } = await Promise.resolve().then(() => (init_list(), list_exports));
57254
57356
  const searchIdx = process.argv.indexOf("--search");
@@ -57258,6 +57360,43 @@ Collector done: ${uploaded} uploaded, ${skipped} unchanged, ${errors} errors`
57258
57360
  await list2({ search, limit });
57259
57361
  break;
57260
57362
  }
57363
+ case "search-knowledge": {
57364
+ const { searchKnowledge: searchKnowledge2 } = await Promise.resolve().then(() => (init_list(), list_exports));
57365
+ const query = process.argv[3];
57366
+ if (!query || query.startsWith("--")) {
57367
+ console.error(
57368
+ "Usage: haansi search-knowledge <query> [--type <artifact_type>] [--limit <n>]"
57369
+ );
57370
+ process.exit(1);
57371
+ }
57372
+ const typeIdx = process.argv.indexOf("--type");
57373
+ const artifactType = typeIdx !== -1 ? process.argv[typeIdx + 1] : void 0;
57374
+ const limitIdx = process.argv.indexOf("--limit");
57375
+ const limit = limitIdx !== -1 ? parseInt(process.argv[limitIdx + 1], 10) : 10;
57376
+ await searchKnowledge2({ query, artifactType, limit });
57377
+ break;
57378
+ }
57379
+ case "save-knowledge": {
57380
+ const { saveKnowledge: saveKnowledge2 } = await Promise.resolve().then(() => (init_list(), list_exports));
57381
+ const problemIdx = process.argv.indexOf("--problem");
57382
+ const solutionIdx = process.argv.indexOf("--solution");
57383
+ if (problemIdx === -1 || solutionIdx === -1) {
57384
+ console.error(
57385
+ 'Usage: haansi save-knowledge --problem "description" --solution "summary" [--type <session_type>] [--complexity <simple|moderate|complex>] [--tags tag1,tag2]'
57386
+ );
57387
+ process.exit(1);
57388
+ }
57389
+ const problem = process.argv[problemIdx + 1];
57390
+ const solution = process.argv[solutionIdx + 1];
57391
+ const typeIdx = process.argv.indexOf("--type");
57392
+ const sessionType = typeIdx !== -1 ? process.argv[typeIdx + 1] : void 0;
57393
+ const complexityIdx = process.argv.indexOf("--complexity");
57394
+ const complexity = complexityIdx !== -1 ? process.argv[complexityIdx + 1] : void 0;
57395
+ const tagsIdx = process.argv.indexOf("--tags");
57396
+ const tags = tagsIdx !== -1 ? process.argv[tagsIdx + 1].split(",") : void 0;
57397
+ await saveKnowledge2({ problem, solution, sessionType, complexity, tags });
57398
+ break;
57399
+ }
57261
57400
  case "help":
57262
57401
  default: {
57263
57402
  printUsage();
@@ -57268,37 +57407,52 @@ Collector done: ${uploaded} uploaded, ${skipped} unchanged, ${errors} errors`
57268
57407
  }
57269
57408
  function printUsage() {
57270
57409
  console.log(`
57271
- Haansi CLI \u2014 Session collector and MCP server for Claude Code
57410
+ Haansi CLI v${VERSION} \u2014 Session collector and MCP server for Claude Code
57272
57411
 
57273
57412
  Usage:
57274
57413
  haansi <command> [options]
57275
57414
 
57276
57415
  Commands:
57277
- init Authenticate and save your API token
57278
- collect Upload new/changed Claude sessions once
57279
- config get [key] Show your preferences (e.g. session_mode)
57280
- config set <key> <val> Update a preference
57281
- search <query> Semantic search over mined solutions
57282
- list List recent mined solutions
57283
- daemon Run the collector on a schedule (every 30 min)
57284
- mcp-server Start the Haansi MCP server (used by Claude Code)
57285
- setup-mcp Add haansi-solutions MCP entry to ~/.claude.json
57286
- setup-daemon Install launchd service to auto-start daemon on login (macOS)
57287
- help Show this help message
57288
-
57289
- Options for search/list:
57290
- --limit <n> Number of results (default: 5 for search, 10 for list)
57416
+ init Authenticate and save your API token
57417
+ collect Upload new/changed Claude sessions once
57418
+ config get [key] Show your preferences (e.g. session_mode)
57419
+ config set <key> <val> Update a preference
57420
+
57421
+ search-solutions <query> Semantic search over mined solutions
57422
+ list-solutions List recent mined solutions
57423
+ search-knowledge <query> Search knowledge artifacts (cards, decisions, etc.)
57424
+ save-knowledge Save a problem/solution for future retrieval
57425
+
57426
+ daemon Run the collector on a schedule (every 30 min)
57427
+ mcp-server Start the Haansi MCP server (used by Claude Code)
57428
+ setup-mcp Add haansi-solutions MCP entry to ~/.claude.json
57429
+ setup-daemon Install launchd service to auto-start daemon on login (macOS)
57430
+ help Show this help message
57431
+
57432
+ Options:
57433
+ --version, -v Show installed version
57434
+ --limit <n> Number of results (default: 5 for search, 10 for list)
57435
+
57436
+ Options for search-knowledge:
57437
+ --type <artifact_type> Filter by type (knowledge_card, decision_record, etc.)
57438
+
57439
+ Options for save-knowledge:
57440
+ --problem "description" Problem description (required)
57441
+ --solution "summary" Solution summary (required)
57442
+ --type <session_type> Session type (bug_fix, feature, refactor, general)
57443
+ --complexity <level> simple, moderate, or complex
57444
+ --tags tag1,tag2 Comma-separated tags
57291
57445
 
57292
57446
  Options for collect:
57293
- --force-all Re-upload all sessions, not just new ones
57294
- --dry-run Scan without uploading
57295
- --limit <n> Upload at most n sessions
57447
+ --force-all Re-upload all sessions, not just new ones
57448
+ --dry-run Scan without uploading
57449
+ --limit <n> Upload at most n sessions
57296
57450
 
57297
57451
  Environment variables:
57298
- HAANSI_TOKEN API token (or use \`haansi init\` to save it)
57299
- HAANSI_API_URL API base URL (default: https://api.haansi.co)
57300
- CLAUDE_PROJECT_PATH Collect from a specific project path only
57301
- CLAUDE_COLLECT_SCHEDULE Cron expression for daemon (default: */30 * * * *)
57452
+ HAANSI_TOKEN API token (or use \`haansi init\` to save it)
57453
+ HAANSI_API_URL API base URL (default: https://api.haansi.co)
57454
+ CLAUDE_PROJECT_PATH Collect from a specific project path only
57455
+ CLAUDE_COLLECT_SCHEDULE Cron expression for daemon (default: */30 * * * *)
57302
57456
  `);
57303
57457
  }
57304
57458
  run2().catch((err) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "haansi",
3
- "version": "0.1.7",
3
+ "version": "0.1.9",
4
4
  "description": "Haansi CLI - Session collector and MCP server for Claude Code",
5
5
  "bin": {
6
6
  "haansi": "./dist/haansi.js"