haansi 0.1.42 → 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 +186 -14
- package/package.json +1 -1
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"
|
|
@@ -21684,7 +21684,7 @@ var init_taxonomy = __esm({
|
|
|
21684
21684
|
icon: "CalendarDays",
|
|
21685
21685
|
aliases: ["weekly_digest", "weekly-digest", "status_report"],
|
|
21686
21686
|
autoApproved: true,
|
|
21687
|
-
producedBy: ["POST /api/v1/memory"
|
|
21687
|
+
producedBy: ["POST /api/v1/memory"]
|
|
21688
21688
|
},
|
|
21689
21689
|
report_sop: {
|
|
21690
21690
|
category: "report",
|
|
@@ -22262,6 +22262,10 @@ var init_table_registry = __esm({
|
|
|
22262
22262
|
entry("intelligence", INTELLIGENCE_DB, "digest_access_log", "direct", {
|
|
22263
22263
|
scopingColumn: "organization_id"
|
|
22264
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
|
+
}),
|
|
22265
22269
|
entry("intelligence", INTELLIGENCE_DB, "activity_graph_edges", "direct", {
|
|
22266
22270
|
scopingColumn: "organization_id"
|
|
22267
22271
|
}),
|
|
@@ -80395,13 +80399,7 @@ var init_config = __esm({
|
|
|
80395
80399
|
}
|
|
80396
80400
|
});
|
|
80397
80401
|
|
|
80398
|
-
// src/
|
|
80399
|
-
var list_exports = {};
|
|
80400
|
-
__export(list_exports, {
|
|
80401
|
-
list: () => list,
|
|
80402
|
-
saveKnowledge: () => saveKnowledge,
|
|
80403
|
-
searchKnowledge: () => searchKnowledge
|
|
80404
|
-
});
|
|
80402
|
+
// src/lib/api.ts
|
|
80405
80403
|
function resolveToken5() {
|
|
80406
80404
|
if (process.env.HAANSI_TOKEN) return process.env.HAANSI_TOKEN;
|
|
80407
80405
|
if ((0, import_node_fs8.existsSync)(CREDENTIALS_FILE7)) {
|
|
@@ -80443,6 +80441,24 @@ async function apiPost2(path2, body, token, apiUrl2) {
|
|
|
80443
80441
|
}
|
|
80444
80442
|
return response.json();
|
|
80445
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
|
+
});
|
|
80446
80462
|
async function list(options) {
|
|
80447
80463
|
const apiUrl2 = apiUrl();
|
|
80448
80464
|
const token = resolveToken5();
|
|
@@ -80508,15 +80524,156 @@ async function saveKnowledge(options) {
|
|
|
80508
80524
|
console.log(` Solution: ${data.solution_summary}`);
|
|
80509
80525
|
console.log("\nThis is now searchable via `haansi search-solutions`.");
|
|
80510
80526
|
}
|
|
80511
|
-
var import_node_fs8, import_node_path7, import_node_os7, CREDENTIALS_FILE7;
|
|
80512
80527
|
var init_list = __esm({
|
|
80513
80528
|
"src/commands/list.ts"() {
|
|
80514
80529
|
"use strict";
|
|
80515
|
-
import_node_fs8 = require("node:fs");
|
|
80516
|
-
import_node_path7 = require("node:path");
|
|
80517
|
-
import_node_os7 = require("node:os");
|
|
80518
80530
|
init_paths();
|
|
80519
|
-
|
|
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();
|
|
80520
80677
|
}
|
|
80521
80678
|
});
|
|
80522
80679
|
|
|
@@ -80682,6 +80839,16 @@ Active selection (${selection.source}): ${selection.agents.join(", ")}`
|
|
|
80682
80839
|
await saveKnowledge2({ problem, solution, sessionType, complexity, tags });
|
|
80683
80840
|
break;
|
|
80684
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
|
+
}
|
|
80685
80852
|
case "help":
|
|
80686
80853
|
default: {
|
|
80687
80854
|
printUsage();
|
|
@@ -80710,6 +80877,11 @@ Commands:
|
|
|
80710
80877
|
search-knowledge <query> Search knowledge artifacts (cards, decisions, etc.)
|
|
80711
80878
|
save-knowledge Save a problem/solution for future retrieval
|
|
80712
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
|
+
|
|
80713
80885
|
daemon Run the collector on a schedule (every 30 min)
|
|
80714
80886
|
mcp-server Start the Haansi MCP server (used by the agent)
|
|
80715
80887
|
setup-mcp [target] [--agent <sel>]
|