haansi 0.1.7 → 0.1.8
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 +168 -26
- 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.8",
|
|
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
|
|
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 =
|
|
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) {
|
|
@@ -57123,7 +57153,9 @@ var init_config = __esm({
|
|
|
57123
57153
|
// src/commands/list.ts
|
|
57124
57154
|
var list_exports = {};
|
|
57125
57155
|
__export(list_exports, {
|
|
57126
|
-
list: () => list
|
|
57156
|
+
list: () => list,
|
|
57157
|
+
saveKnowledge: () => saveKnowledge,
|
|
57158
|
+
searchKnowledge: () => searchKnowledge
|
|
57127
57159
|
});
|
|
57128
57160
|
function resolveToken4() {
|
|
57129
57161
|
if (process.env.HAANSI_TOKEN) return process.env.HAANSI_TOKEN;
|
|
@@ -57146,6 +57178,21 @@ async function apiGet3(path, token, apiUrl) {
|
|
|
57146
57178
|
}
|
|
57147
57179
|
return response.json();
|
|
57148
57180
|
}
|
|
57181
|
+
async function apiPost2(path, body, token, apiUrl) {
|
|
57182
|
+
const response = await fetch(`${apiUrl}/api/v1${path}`, {
|
|
57183
|
+
method: "POST",
|
|
57184
|
+
headers: {
|
|
57185
|
+
Authorization: `Bearer ${token}`,
|
|
57186
|
+
"Content-Type": "application/json"
|
|
57187
|
+
},
|
|
57188
|
+
body: JSON.stringify(body)
|
|
57189
|
+
});
|
|
57190
|
+
if (!response.ok) {
|
|
57191
|
+
const text = await response.text().catch(() => "");
|
|
57192
|
+
throw new Error(`API error ${response.status}: ${text.slice(0, 200)}`);
|
|
57193
|
+
}
|
|
57194
|
+
return response.json();
|
|
57195
|
+
}
|
|
57149
57196
|
async function list(options) {
|
|
57150
57197
|
const apiUrl = process.env.HAANSI_API_URL ?? DEFAULT_API_URL5;
|
|
57151
57198
|
const token = resolveToken4();
|
|
@@ -57172,6 +57219,41 @@ async function list(options) {
|
|
|
57172
57219
|
console.log(`
|
|
57173
57220
|
${data.results.length} result(s)`);
|
|
57174
57221
|
}
|
|
57222
|
+
async function searchKnowledge(options) {
|
|
57223
|
+
const apiUrl = process.env.HAANSI_API_URL ?? DEFAULT_API_URL5;
|
|
57224
|
+
const token = resolveToken4();
|
|
57225
|
+
let url2 = `/sessions/knowledge/search?q=${encodeURIComponent(options.query)}&limit=${options.limit}`;
|
|
57226
|
+
if (options.artifactType) {
|
|
57227
|
+
url2 += `&artifact_type=${encodeURIComponent(options.artifactType)}`;
|
|
57228
|
+
}
|
|
57229
|
+
const data = await apiGet3(url2, token, apiUrl);
|
|
57230
|
+
if (!data.results || data.results.length === 0) {
|
|
57231
|
+
console.log("No knowledge artifacts found matching your query.");
|
|
57232
|
+
return;
|
|
57233
|
+
}
|
|
57234
|
+
const separator = "\n" + "\u2500".repeat(60) + "\n";
|
|
57235
|
+
console.log(data.results.join(separator));
|
|
57236
|
+
console.log(`
|
|
57237
|
+
${data.results.length} result(s)`);
|
|
57238
|
+
}
|
|
57239
|
+
async function saveKnowledge(options) {
|
|
57240
|
+
const apiUrl = process.env.HAANSI_API_URL ?? DEFAULT_API_URL5;
|
|
57241
|
+
const token = resolveToken4();
|
|
57242
|
+
const body = {
|
|
57243
|
+
problem_description: options.problem,
|
|
57244
|
+
solution_summary: options.solution,
|
|
57245
|
+
source_tool: "haansi-cli"
|
|
57246
|
+
};
|
|
57247
|
+
if (options.sessionType) body.session_type = options.sessionType;
|
|
57248
|
+
if (options.complexity) body.complexity = options.complexity;
|
|
57249
|
+
if (options.tags) body.tags = options.tags;
|
|
57250
|
+
const data = await apiPost2("/sessions/knowledge", body, token, apiUrl);
|
|
57251
|
+
console.log("Knowledge saved successfully.");
|
|
57252
|
+
console.log(` ID: ${data.id}`);
|
|
57253
|
+
console.log(` Problem: ${data.problem_description}`);
|
|
57254
|
+
console.log(` Solution: ${data.solution_summary}`);
|
|
57255
|
+
console.log("\nThis is now searchable via `haansi search-solutions`.");
|
|
57256
|
+
}
|
|
57175
57257
|
var import_node_fs5, import_node_path5, import_node_os5, DEFAULT_API_URL5, CREDENTIALS_FILE5;
|
|
57176
57258
|
var init_list = __esm({
|
|
57177
57259
|
"src/commands/list.ts"() {
|
|
@@ -57185,8 +57267,13 @@ var init_list = __esm({
|
|
|
57185
57267
|
});
|
|
57186
57268
|
|
|
57187
57269
|
// src/index.ts
|
|
57270
|
+
var { version: VERSION } = require_package();
|
|
57188
57271
|
var command = process.argv[2];
|
|
57189
57272
|
async function run2() {
|
|
57273
|
+
if (command === "--version" || command === "-v") {
|
|
57274
|
+
console.log(VERSION);
|
|
57275
|
+
return;
|
|
57276
|
+
}
|
|
57190
57277
|
switch (command) {
|
|
57191
57278
|
case "init": {
|
|
57192
57279
|
const { init: init2 } = await Promise.resolve().then(() => (init_init(), init_exports));
|
|
@@ -57237,11 +57324,13 @@ Collector done: ${uploaded} uploaded, ${skipped} unchanged, ${errors} errors`
|
|
|
57237
57324
|
await config6(process.argv.slice(3));
|
|
57238
57325
|
break;
|
|
57239
57326
|
}
|
|
57327
|
+
// ── Solution & Knowledge commands (consistent with MCP tool names) ──
|
|
57328
|
+
case "search-solutions":
|
|
57240
57329
|
case "search": {
|
|
57241
57330
|
const { list: list2 } = await Promise.resolve().then(() => (init_list(), list_exports));
|
|
57242
57331
|
const query = process.argv[3];
|
|
57243
57332
|
if (!query || query.startsWith("--")) {
|
|
57244
|
-
console.error("Usage: haansi search <query> [--limit <n>]");
|
|
57333
|
+
console.error("Usage: haansi search-solutions <query> [--limit <n>]");
|
|
57245
57334
|
process.exit(1);
|
|
57246
57335
|
}
|
|
57247
57336
|
const limitIdx = process.argv.indexOf("--limit");
|
|
@@ -57249,6 +57338,7 @@ Collector done: ${uploaded} uploaded, ${skipped} unchanged, ${errors} errors`
|
|
|
57249
57338
|
await list2({ search: query, limit });
|
|
57250
57339
|
break;
|
|
57251
57340
|
}
|
|
57341
|
+
case "list-solutions":
|
|
57252
57342
|
case "list": {
|
|
57253
57343
|
const { list: list2 } = await Promise.resolve().then(() => (init_list(), list_exports));
|
|
57254
57344
|
const searchIdx = process.argv.indexOf("--search");
|
|
@@ -57258,6 +57348,43 @@ Collector done: ${uploaded} uploaded, ${skipped} unchanged, ${errors} errors`
|
|
|
57258
57348
|
await list2({ search, limit });
|
|
57259
57349
|
break;
|
|
57260
57350
|
}
|
|
57351
|
+
case "search-knowledge": {
|
|
57352
|
+
const { searchKnowledge: searchKnowledge2 } = await Promise.resolve().then(() => (init_list(), list_exports));
|
|
57353
|
+
const query = process.argv[3];
|
|
57354
|
+
if (!query || query.startsWith("--")) {
|
|
57355
|
+
console.error(
|
|
57356
|
+
"Usage: haansi search-knowledge <query> [--type <artifact_type>] [--limit <n>]"
|
|
57357
|
+
);
|
|
57358
|
+
process.exit(1);
|
|
57359
|
+
}
|
|
57360
|
+
const typeIdx = process.argv.indexOf("--type");
|
|
57361
|
+
const artifactType = typeIdx !== -1 ? process.argv[typeIdx + 1] : void 0;
|
|
57362
|
+
const limitIdx = process.argv.indexOf("--limit");
|
|
57363
|
+
const limit = limitIdx !== -1 ? parseInt(process.argv[limitIdx + 1], 10) : 10;
|
|
57364
|
+
await searchKnowledge2({ query, artifactType, limit });
|
|
57365
|
+
break;
|
|
57366
|
+
}
|
|
57367
|
+
case "save-knowledge": {
|
|
57368
|
+
const { saveKnowledge: saveKnowledge2 } = await Promise.resolve().then(() => (init_list(), list_exports));
|
|
57369
|
+
const problemIdx = process.argv.indexOf("--problem");
|
|
57370
|
+
const solutionIdx = process.argv.indexOf("--solution");
|
|
57371
|
+
if (problemIdx === -1 || solutionIdx === -1) {
|
|
57372
|
+
console.error(
|
|
57373
|
+
'Usage: haansi save-knowledge --problem "description" --solution "summary" [--type <session_type>] [--complexity <simple|moderate|complex>] [--tags tag1,tag2]'
|
|
57374
|
+
);
|
|
57375
|
+
process.exit(1);
|
|
57376
|
+
}
|
|
57377
|
+
const problem = process.argv[problemIdx + 1];
|
|
57378
|
+
const solution = process.argv[solutionIdx + 1];
|
|
57379
|
+
const typeIdx = process.argv.indexOf("--type");
|
|
57380
|
+
const sessionType = typeIdx !== -1 ? process.argv[typeIdx + 1] : void 0;
|
|
57381
|
+
const complexityIdx = process.argv.indexOf("--complexity");
|
|
57382
|
+
const complexity = complexityIdx !== -1 ? process.argv[complexityIdx + 1] : void 0;
|
|
57383
|
+
const tagsIdx = process.argv.indexOf("--tags");
|
|
57384
|
+
const tags = tagsIdx !== -1 ? process.argv[tagsIdx + 1].split(",") : void 0;
|
|
57385
|
+
await saveKnowledge2({ problem, solution, sessionType, complexity, tags });
|
|
57386
|
+
break;
|
|
57387
|
+
}
|
|
57261
57388
|
case "help":
|
|
57262
57389
|
default: {
|
|
57263
57390
|
printUsage();
|
|
@@ -57268,37 +57395,52 @@ Collector done: ${uploaded} uploaded, ${skipped} unchanged, ${errors} errors`
|
|
|
57268
57395
|
}
|
|
57269
57396
|
function printUsage() {
|
|
57270
57397
|
console.log(`
|
|
57271
|
-
Haansi CLI \u2014 Session collector and MCP server for Claude Code
|
|
57398
|
+
Haansi CLI v${VERSION} \u2014 Session collector and MCP server for Claude Code
|
|
57272
57399
|
|
|
57273
57400
|
Usage:
|
|
57274
57401
|
haansi <command> [options]
|
|
57275
57402
|
|
|
57276
57403
|
Commands:
|
|
57277
|
-
init
|
|
57278
|
-
collect
|
|
57279
|
-
config get [key]
|
|
57280
|
-
config set <key> <val>
|
|
57281
|
-
|
|
57282
|
-
|
|
57283
|
-
|
|
57284
|
-
|
|
57285
|
-
|
|
57286
|
-
|
|
57287
|
-
|
|
57288
|
-
|
|
57289
|
-
|
|
57290
|
-
|
|
57404
|
+
init Authenticate and save your API token
|
|
57405
|
+
collect Upload new/changed Claude sessions once
|
|
57406
|
+
config get [key] Show your preferences (e.g. session_mode)
|
|
57407
|
+
config set <key> <val> Update a preference
|
|
57408
|
+
|
|
57409
|
+
search-solutions <query> Semantic search over mined solutions
|
|
57410
|
+
list-solutions List recent mined solutions
|
|
57411
|
+
search-knowledge <query> Search knowledge artifacts (cards, decisions, etc.)
|
|
57412
|
+
save-knowledge Save a problem/solution for future retrieval
|
|
57413
|
+
|
|
57414
|
+
daemon Run the collector on a schedule (every 30 min)
|
|
57415
|
+
mcp-server Start the Haansi MCP server (used by Claude Code)
|
|
57416
|
+
setup-mcp Add haansi-solutions MCP entry to ~/.claude.json
|
|
57417
|
+
setup-daemon Install launchd service to auto-start daemon on login (macOS)
|
|
57418
|
+
help Show this help message
|
|
57419
|
+
|
|
57420
|
+
Options:
|
|
57421
|
+
--version, -v Show installed version
|
|
57422
|
+
--limit <n> Number of results (default: 5 for search, 10 for list)
|
|
57423
|
+
|
|
57424
|
+
Options for search-knowledge:
|
|
57425
|
+
--type <artifact_type> Filter by type (knowledge_card, decision_record, etc.)
|
|
57426
|
+
|
|
57427
|
+
Options for save-knowledge:
|
|
57428
|
+
--problem "description" Problem description (required)
|
|
57429
|
+
--solution "summary" Solution summary (required)
|
|
57430
|
+
--type <session_type> Session type (bug_fix, feature, refactor, general)
|
|
57431
|
+
--complexity <level> simple, moderate, or complex
|
|
57432
|
+
--tags tag1,tag2 Comma-separated tags
|
|
57291
57433
|
|
|
57292
57434
|
Options for collect:
|
|
57293
|
-
--force-all
|
|
57294
|
-
--dry-run
|
|
57295
|
-
--limit <n>
|
|
57435
|
+
--force-all Re-upload all sessions, not just new ones
|
|
57436
|
+
--dry-run Scan without uploading
|
|
57437
|
+
--limit <n> Upload at most n sessions
|
|
57296
57438
|
|
|
57297
57439
|
Environment variables:
|
|
57298
|
-
HAANSI_TOKEN
|
|
57299
|
-
HAANSI_API_URL
|
|
57300
|
-
CLAUDE_PROJECT_PATH
|
|
57301
|
-
CLAUDE_COLLECT_SCHEDULE
|
|
57440
|
+
HAANSI_TOKEN API token (or use \`haansi init\` to save it)
|
|
57441
|
+
HAANSI_API_URL API base URL (default: https://api.haansi.co)
|
|
57442
|
+
CLAUDE_PROJECT_PATH Collect from a specific project path only
|
|
57443
|
+
CLAUDE_COLLECT_SCHEDULE Cron expression for daemon (default: */30 * * * *)
|
|
57302
57444
|
`);
|
|
57303
57445
|
}
|
|
57304
57446
|
run2().catch((err) => {
|