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.
Files changed (2) hide show
  1. package/dist/haansi.js +189 -19
  2. 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.41",
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", "POST /api/v1/memory/reports/work"]
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/commands/list.ts
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
- CREDENTIALS_FILE7 = (0, import_node_path7.join)((0, import_node_os7.homedir)(), ".haansi", "credentials.json");
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.41",
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
  }