haansi 0.1.41 → 0.1.43
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 +189 -19
- package/package.json +4 -6
package/dist/haansi.js
CHANGED
|
@@ -95,7 +95,7 @@ var require_package = __commonJS({
|
|
|
95
95
|
"package.json"(exports2, module2) {
|
|
96
96
|
module2.exports = {
|
|
97
97
|
name: "haansi",
|
|
98
|
-
version: "0.1.
|
|
98
|
+
version: "0.1.43",
|
|
99
99
|
description: "Haansi CLI - Session collector and MCP server for Claude Code & OpenAI Codex",
|
|
100
100
|
bin: {
|
|
101
101
|
haansi: "./dist/haansi.js"
|
|
@@ -109,15 +109,13 @@ var require_package = __commonJS({
|
|
|
109
109
|
prepublishOnly: "npm run build"
|
|
110
110
|
},
|
|
111
111
|
devDependencies: {
|
|
112
|
+
"@company/pii": "*",
|
|
113
|
+
"@types/node": "^22.10.1",
|
|
112
114
|
esbuild: "^0.27.0",
|
|
113
|
-
typescript: "^5.7.2"
|
|
114
|
-
"@types/node": "^22.10.1"
|
|
115
|
+
typescript: "^5.7.2"
|
|
115
116
|
},
|
|
116
117
|
engines: {
|
|
117
118
|
node: ">=18.0.0"
|
|
118
|
-
},
|
|
119
|
-
dependencies: {
|
|
120
|
-
"@company/pii": "*"
|
|
121
119
|
}
|
|
122
120
|
};
|
|
123
121
|
}
|
|
@@ -21686,7 +21684,7 @@ var init_taxonomy = __esm({
|
|
|
21686
21684
|
icon: "CalendarDays",
|
|
21687
21685
|
aliases: ["weekly_digest", "weekly-digest", "status_report"],
|
|
21688
21686
|
autoApproved: true,
|
|
21689
|
-
producedBy: ["POST /api/v1/memory"
|
|
21687
|
+
producedBy: ["POST /api/v1/memory"]
|
|
21690
21688
|
},
|
|
21691
21689
|
report_sop: {
|
|
21692
21690
|
category: "report",
|
|
@@ -22264,6 +22262,10 @@ var init_table_registry = __esm({
|
|
|
22264
22262
|
entry("intelligence", INTELLIGENCE_DB, "digest_access_log", "direct", {
|
|
22265
22263
|
scopingColumn: "organization_id"
|
|
22266
22264
|
}),
|
|
22265
|
+
// Digests Phase 5 (migrations/digests/004): members' own work log entries.
|
|
22266
|
+
entry("intelligence", INTELLIGENCE_DB, "digest_work_logs", "direct", {
|
|
22267
|
+
scopingColumn: "organization_id"
|
|
22268
|
+
}),
|
|
22267
22269
|
entry("intelligence", INTELLIGENCE_DB, "activity_graph_edges", "direct", {
|
|
22268
22270
|
scopingColumn: "organization_id"
|
|
22269
22271
|
}),
|
|
@@ -80397,13 +80399,7 @@ var init_config = __esm({
|
|
|
80397
80399
|
}
|
|
80398
80400
|
});
|
|
80399
80401
|
|
|
80400
|
-
// src/
|
|
80401
|
-
var list_exports = {};
|
|
80402
|
-
__export(list_exports, {
|
|
80403
|
-
list: () => list,
|
|
80404
|
-
saveKnowledge: () => saveKnowledge,
|
|
80405
|
-
searchKnowledge: () => searchKnowledge
|
|
80406
|
-
});
|
|
80402
|
+
// src/lib/api.ts
|
|
80407
80403
|
function resolveToken5() {
|
|
80408
80404
|
if (process.env.HAANSI_TOKEN) return process.env.HAANSI_TOKEN;
|
|
80409
80405
|
if ((0, import_node_fs8.existsSync)(CREDENTIALS_FILE7)) {
|
|
@@ -80445,6 +80441,24 @@ async function apiPost2(path2, body, token, apiUrl2) {
|
|
|
80445
80441
|
}
|
|
80446
80442
|
return response.json();
|
|
80447
80443
|
}
|
|
80444
|
+
var import_node_fs8, import_node_path7, import_node_os7, CREDENTIALS_FILE7;
|
|
80445
|
+
var init_api2 = __esm({
|
|
80446
|
+
"src/lib/api.ts"() {
|
|
80447
|
+
"use strict";
|
|
80448
|
+
import_node_fs8 = require("node:fs");
|
|
80449
|
+
import_node_path7 = require("node:path");
|
|
80450
|
+
import_node_os7 = require("node:os");
|
|
80451
|
+
CREDENTIALS_FILE7 = (0, import_node_path7.join)((0, import_node_os7.homedir)(), ".haansi", "credentials.json");
|
|
80452
|
+
}
|
|
80453
|
+
});
|
|
80454
|
+
|
|
80455
|
+
// src/commands/list.ts
|
|
80456
|
+
var list_exports = {};
|
|
80457
|
+
__export(list_exports, {
|
|
80458
|
+
list: () => list,
|
|
80459
|
+
saveKnowledge: () => saveKnowledge,
|
|
80460
|
+
searchKnowledge: () => searchKnowledge
|
|
80461
|
+
});
|
|
80448
80462
|
async function list(options) {
|
|
80449
80463
|
const apiUrl2 = apiUrl();
|
|
80450
80464
|
const token = resolveToken5();
|
|
@@ -80510,15 +80524,156 @@ async function saveKnowledge(options) {
|
|
|
80510
80524
|
console.log(` Solution: ${data.solution_summary}`);
|
|
80511
80525
|
console.log("\nThis is now searchable via `haansi search-solutions`.");
|
|
80512
80526
|
}
|
|
80513
|
-
var import_node_fs8, import_node_path7, import_node_os7, CREDENTIALS_FILE7;
|
|
80514
80527
|
var init_list = __esm({
|
|
80515
80528
|
"src/commands/list.ts"() {
|
|
80516
80529
|
"use strict";
|
|
80517
|
-
import_node_fs8 = require("node:fs");
|
|
80518
|
-
import_node_path7 = require("node:path");
|
|
80519
|
-
import_node_os7 = require("node:os");
|
|
80520
80530
|
init_paths();
|
|
80521
|
-
|
|
80531
|
+
init_api2();
|
|
80532
|
+
}
|
|
80533
|
+
});
|
|
80534
|
+
|
|
80535
|
+
// src/commands/digest.ts
|
|
80536
|
+
var digest_exports = {};
|
|
80537
|
+
__export(digest_exports, {
|
|
80538
|
+
digest: () => digest,
|
|
80539
|
+
formatDigest: () => formatDigest,
|
|
80540
|
+
formatDigestList: () => formatDigestList,
|
|
80541
|
+
logWork: () => logWork,
|
|
80542
|
+
parseDigestRange: () => parseDigestRange,
|
|
80543
|
+
parseLogArgs: () => parseLogArgs,
|
|
80544
|
+
weekLabel: () => weekLabel
|
|
80545
|
+
});
|
|
80546
|
+
function weekLabel(start, end) {
|
|
80547
|
+
const s = /* @__PURE__ */ new Date(`${start}T00:00:00Z`);
|
|
80548
|
+
const e = /* @__PURE__ */ new Date(`${end}T00:00:00Z`);
|
|
80549
|
+
if (Number.isNaN(s.getTime()) || Number.isNaN(e.getTime())) return start;
|
|
80550
|
+
e.setUTCDate(e.getUTCDate() - 1);
|
|
80551
|
+
const fmt = (d) => d.toLocaleDateString("en-US", {
|
|
80552
|
+
month: "short",
|
|
80553
|
+
day: "numeric",
|
|
80554
|
+
timeZone: "UTC"
|
|
80555
|
+
});
|
|
80556
|
+
return `${fmt(s)} \u2013 ${fmt(e)}`;
|
|
80557
|
+
}
|
|
80558
|
+
function formatDigest(entry2) {
|
|
80559
|
+
const lines = [
|
|
80560
|
+
`${entry2.title} (${weekLabel(entry2.periodStart, entry2.periodEnd)})`,
|
|
80561
|
+
"",
|
|
80562
|
+
entry2.narrative?.summary?.text ?? entry2.summary
|
|
80563
|
+
];
|
|
80564
|
+
const highlights = entry2.narrative?.highlights ?? [];
|
|
80565
|
+
if (highlights.length) {
|
|
80566
|
+
lines.push("", ...highlights.map((h) => ` \u2022 ${h.text}`));
|
|
80567
|
+
}
|
|
80568
|
+
for (const section of entry2.narrative?.sections ?? []) {
|
|
80569
|
+
lines.push(
|
|
80570
|
+
"",
|
|
80571
|
+
section.heading,
|
|
80572
|
+
...section.items.map((i) => ` - ${i.text}`)
|
|
80573
|
+
);
|
|
80574
|
+
}
|
|
80575
|
+
if (entry2.status === "partial") {
|
|
80576
|
+
lines.push("", "(Facts only this week: no written summary.)");
|
|
80577
|
+
}
|
|
80578
|
+
return lines.join("\n");
|
|
80579
|
+
}
|
|
80580
|
+
function formatDigestList(entries) {
|
|
80581
|
+
return entries.map(
|
|
80582
|
+
(e) => `${weekLabel(e.periodStart, e.periodEnd).padEnd(16)} ${e.title}
|
|
80583
|
+
${" ".repeat(18)}${e.summary}`
|
|
80584
|
+
).join("\n\n");
|
|
80585
|
+
}
|
|
80586
|
+
function parseDigestRange(argv) {
|
|
80587
|
+
const i = argv.indexOf("--since");
|
|
80588
|
+
if (i !== -1) {
|
|
80589
|
+
const since = argv[i + 1];
|
|
80590
|
+
if (!since || !/^\d{4}-\d{2}-\d{2}$/.test(since)) {
|
|
80591
|
+
throw Object.assign(new Error("bad --since"), {
|
|
80592
|
+
publicMessage: "Usage: haansi digest --since YYYY-MM-DD"
|
|
80593
|
+
});
|
|
80594
|
+
}
|
|
80595
|
+
return { kind: "since", since };
|
|
80596
|
+
}
|
|
80597
|
+
if (argv.includes("--month")) return { kind: "month" };
|
|
80598
|
+
return { kind: "week" };
|
|
80599
|
+
}
|
|
80600
|
+
async function digest(range) {
|
|
80601
|
+
const apiUrl2 = apiUrl();
|
|
80602
|
+
const token = resolveToken5();
|
|
80603
|
+
const query = range.kind === "week" ? "limit=1" : range.kind === "month" ? "limit=5" : `from=${encodeURIComponent(range.since)}&limit=26`;
|
|
80604
|
+
const list2 = await apiGet3(
|
|
80605
|
+
`/memory/digests/entries?${query}`,
|
|
80606
|
+
token,
|
|
80607
|
+
apiUrl2
|
|
80608
|
+
);
|
|
80609
|
+
if (!list2.data?.length) {
|
|
80610
|
+
console.log(
|
|
80611
|
+
"No digests yet. They are written weekly once your accounts are linked; generate one from the Digests page."
|
|
80612
|
+
);
|
|
80613
|
+
return;
|
|
80614
|
+
}
|
|
80615
|
+
if (range.kind === "week") {
|
|
80616
|
+
const detail = await apiGet3(
|
|
80617
|
+
`/memory/digests/entries/${encodeURIComponent(list2.data[0].id)}`,
|
|
80618
|
+
token,
|
|
80619
|
+
apiUrl2
|
|
80620
|
+
);
|
|
80621
|
+
console.log(formatDigest(detail.data));
|
|
80622
|
+
return;
|
|
80623
|
+
}
|
|
80624
|
+
console.log(formatDigestList(list2.data));
|
|
80625
|
+
}
|
|
80626
|
+
function parseLogArgs(argv) {
|
|
80627
|
+
const flag = (name) => {
|
|
80628
|
+
const i = argv.indexOf(name);
|
|
80629
|
+
return i !== -1 ? argv[i + 1] : void 0;
|
|
80630
|
+
};
|
|
80631
|
+
const skip = /* @__PURE__ */ new Set();
|
|
80632
|
+
for (const name of ["--date", "--workstream"]) {
|
|
80633
|
+
const i = argv.indexOf(name);
|
|
80634
|
+
if (i !== -1) {
|
|
80635
|
+
skip.add(i);
|
|
80636
|
+
skip.add(i + 1);
|
|
80637
|
+
}
|
|
80638
|
+
}
|
|
80639
|
+
const text = argv.filter((_, i) => !skip.has(i)).join(" ").trim();
|
|
80640
|
+
if (!text) {
|
|
80641
|
+
throw Object.assign(new Error("no text"), {
|
|
80642
|
+
publicMessage: 'Usage: haansi log "what you did" [--date YYYY-MM-DD] [--workstream <id>]'
|
|
80643
|
+
});
|
|
80644
|
+
}
|
|
80645
|
+
const date4 = flag("--date");
|
|
80646
|
+
if (date4 !== void 0 && !/^\d{4}-\d{2}-\d{2}$/.test(date4)) {
|
|
80647
|
+
throw Object.assign(new Error("bad --date"), {
|
|
80648
|
+
publicMessage: "--date must be YYYY-MM-DD."
|
|
80649
|
+
});
|
|
80650
|
+
}
|
|
80651
|
+
return { text, date: date4, workstream: flag("--workstream") };
|
|
80652
|
+
}
|
|
80653
|
+
async function logWork(args) {
|
|
80654
|
+
const apiUrl2 = apiUrl();
|
|
80655
|
+
const token = resolveToken5();
|
|
80656
|
+
const result = await apiPost2(
|
|
80657
|
+
"/memory/digests/log",
|
|
80658
|
+
{
|
|
80659
|
+
text: args.text,
|
|
80660
|
+
// Noon UTC: the day the user named, whatever their timezone.
|
|
80661
|
+
loggedAt: args.date ? `${args.date}T12:00:00Z` : void 0,
|
|
80662
|
+
workstream: args.workstream
|
|
80663
|
+
},
|
|
80664
|
+
token,
|
|
80665
|
+
apiUrl2
|
|
80666
|
+
);
|
|
80667
|
+
const day = result.data?.loggedAt?.slice(0, 10);
|
|
80668
|
+
console.log(
|
|
80669
|
+
`Logged${day ? ` for ${day}` : ""}. It will be cited in your weekly digest.`
|
|
80670
|
+
);
|
|
80671
|
+
}
|
|
80672
|
+
var init_digest = __esm({
|
|
80673
|
+
"src/commands/digest.ts"() {
|
|
80674
|
+
"use strict";
|
|
80675
|
+
init_paths();
|
|
80676
|
+
init_api2();
|
|
80522
80677
|
}
|
|
80523
80678
|
});
|
|
80524
80679
|
|
|
@@ -80684,6 +80839,16 @@ Active selection (${selection.source}): ${selection.agents.join(", ")}`
|
|
|
80684
80839
|
await saveKnowledge2({ problem, solution, sessionType, complexity, tags });
|
|
80685
80840
|
break;
|
|
80686
80841
|
}
|
|
80842
|
+
case "log": {
|
|
80843
|
+
const { logWork: logWork2, parseLogArgs: parseLogArgs2 } = await Promise.resolve().then(() => (init_digest(), digest_exports));
|
|
80844
|
+
await logWork2(parseLogArgs2(process.argv.slice(3)));
|
|
80845
|
+
break;
|
|
80846
|
+
}
|
|
80847
|
+
case "digest": {
|
|
80848
|
+
const { digest: digest2, parseDigestRange: parseDigestRange2 } = await Promise.resolve().then(() => (init_digest(), digest_exports));
|
|
80849
|
+
await digest2(parseDigestRange2(process.argv.slice(3)));
|
|
80850
|
+
break;
|
|
80851
|
+
}
|
|
80687
80852
|
case "help":
|
|
80688
80853
|
default: {
|
|
80689
80854
|
printUsage();
|
|
@@ -80712,6 +80877,11 @@ Commands:
|
|
|
80712
80877
|
search-knowledge <query> Search knowledge artifacts (cards, decisions, etc.)
|
|
80713
80878
|
save-knowledge Save a problem/solution for future retrieval
|
|
80714
80879
|
|
|
80880
|
+
log "<what you did>" Add to your work journal; cited in your weekly
|
|
80881
|
+
digest. [--date YYYY-MM-DD] [--workstream <id>]
|
|
80882
|
+
digest [--week|--month|--since YYYY-MM-DD]
|
|
80883
|
+
Your weekly digest (default: the latest week)
|
|
80884
|
+
|
|
80715
80885
|
daemon Run the collector on a schedule (every 30 min)
|
|
80716
80886
|
mcp-server Start the Haansi MCP server (used by the agent)
|
|
80717
80887
|
setup-mcp [target] [--agent <sel>]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "haansi",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.43",
|
|
4
4
|
"description": "Haansi CLI - Session collector and MCP server for Claude Code & OpenAI Codex",
|
|
5
5
|
"bin": {
|
|
6
6
|
"haansi": "./dist/haansi.js"
|
|
@@ -14,14 +14,12 @@
|
|
|
14
14
|
"prepublishOnly": "npm run build"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
|
+
"@company/pii": "*",
|
|
18
|
+
"@types/node": "^22.10.1",
|
|
17
19
|
"esbuild": "^0.27.0",
|
|
18
|
-
"typescript": "^5.7.2"
|
|
19
|
-
"@types/node": "^22.10.1"
|
|
20
|
+
"typescript": "^5.7.2"
|
|
20
21
|
},
|
|
21
22
|
"engines": {
|
|
22
23
|
"node": ">=18.0.0"
|
|
23
|
-
},
|
|
24
|
-
"dependencies": {
|
|
25
|
-
"@company/pii": "*"
|
|
26
24
|
}
|
|
27
25
|
}
|