@basestream/cli 0.2.7 → 0.2.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/cli.mjs +41 -22
  2. package/package.json +1 -1
package/dist/cli.mjs CHANGED
@@ -258,14 +258,20 @@ var HOOK_TIMEOUT = 60;
258
258
  var CLAUDE_MD_MARKER = "<!-- basestream -->";
259
259
  var CLAUDE_MD_RULE = `${CLAUDE_MD_MARKER}
260
260
  - Before starting any non-trivial task, if the reason or context behind the work isn't already clear, ask: "What's the context for this?" Skip this for small tasks, typo fixes, or anything self-explanatory.
261
- - After completing any meaningful work (fixing a bug, implementing a feature, making a significant change), invoke /bs-summarize to keep the session summary up to date. Include the "why" if it was provided.
261
+ - After writing or editing any file, you MUST invoke /bs-summarize before your next response. No exceptions \u2014 this keeps the session record accurate even if the conversation ends unexpectedly.
262
262
  <!-- /basestream -->`;
263
263
  var SKILL_CONTENT = `---
264
264
  name: bs-summarize
265
265
  description: Update the Basestream session summary with what's been accomplished so far
266
266
  ---
267
267
 
268
- First, read the existing summary file at \`~/.basestream/sessions/\${CLAUDE_SESSION_ID}-summary.md\` if it exists \u2014 this is the running record of work done so far this session.
268
+ First, find the current session ID:
269
+ \`\`\`
270
+ cat ~/.basestream/current-session-id
271
+ \`\`\`
272
+ If the file doesn't exist, skip this skill entirely \u2014 the session hasn't registered with Basestream yet (this happens on the very first turn of a brand new install before any Stop hook has fired).
273
+
274
+ Read the existing summary file at \`~/.basestream/sessions/{sessionId}-summary.md\` if it exists \u2014 this is the running record of work done so far this session.
269
275
 
270
276
  Then write an updated summary that aggregates the previous summary with everything that has happened since. Focus on:
271
277
  - Why the work was done (if context was provided \u2014 skip if not known)
@@ -275,7 +281,7 @@ Then write an updated summary that aggregates the previous summary with everythi
275
281
 
276
282
  Do not just append \u2014 synthesize everything into a single cohesive summary. Merge related work together, avoid repeating the same point twice, and drop anything superseded by later changes. Be concise \u2014 let the scope of the work determine the length. A small fix deserves one sentence; a large multi-part session can be a short paragraph. Plain prose, no bullet points.
277
283
 
278
- Write the result to \`~/.basestream/sessions/\${CLAUDE_SESSION_ID}-summary.md\`, overwriting the file.
284
+ Write the result to \`~/.basestream/sessions/{sessionId}-summary.md\`, overwriting the file.
279
285
  `;
280
286
  var BASESTREAM_DIR2 = path2.join(os2.homedir(), ".basestream");
281
287
  var REQUIRED_PERMISSIONS = [
@@ -289,7 +295,10 @@ function injectClaudeMdRule() {
289
295
  }
290
296
  let updated;
291
297
  if (existing.includes(CLAUDE_MD_MARKER)) {
292
- updated = existing.replace(/<!-- basestream -->[\s\S]*?<!-- \/basestream -->/, CLAUDE_MD_RULE);
298
+ updated = existing.replace(
299
+ /<!-- basestream -->[\s\S]*?<!-- \/basestream -->/,
300
+ CLAUDE_MD_RULE
301
+ );
293
302
  fs2.writeFileSync(CLAUDE_MD_PATH, updated);
294
303
  check("Updated Basestream rules in ~/.claude/CLAUDE.md");
295
304
  } else {
@@ -367,7 +376,9 @@ function injectClaudeCodeHook() {
367
376
  );
368
377
  if (ourEntryIndex !== -1) {
369
378
  const entry = existing[ourEntryIndex];
370
- const hookIndex = entry.hooks.findIndex((h) => h.command?.includes(HOOK_MARKER));
379
+ const hookIndex = entry.hooks.findIndex(
380
+ (h) => h.command?.includes(HOOK_MARKER)
381
+ );
371
382
  const hook = entry.hooks[hookIndex];
372
383
  if (hook.command === HOOK_COMMAND && hook.timeout === HOOK_TIMEOUT) {
373
384
  check("Claude Code hook already installed");
@@ -416,9 +427,13 @@ async function init() {
416
427
  console.log();
417
428
  console.log(` ${c.dim("That's it. One last step:")}`);
418
429
  console.log();
419
- console.log(` ${c.bold("Restart Claude Code")} for the hook to take effect.`);
430
+ console.log(
431
+ ` ${c.bold("Restart Claude Code")} for the hook to take effect.`
432
+ );
420
433
  console.log();
421
- console.log(` ${c.dim("After that, every session is automatically tracked.")}`);
434
+ console.log(
435
+ ` ${c.dim("After that, every session is automatically tracked.")}`
436
+ );
422
437
  console.log();
423
438
  }
424
439
 
@@ -607,9 +622,13 @@ function analyzeTranscript(transcriptPath, acc) {
607
622
  if (!fs5.existsSync(transcriptPath)) return acc;
608
623
  const content = fs5.readFileSync(transcriptPath, "utf-8");
609
624
  const lines = content.split("\n").filter(Boolean);
625
+ let firstTimestamp;
610
626
  for (const line of lines) {
611
627
  const entry = parseTranscriptLine(line);
612
628
  if (!entry) continue;
629
+ if (!firstTimestamp && entry.timestamp) {
630
+ firstTimestamp = entry.timestamp;
631
+ }
613
632
  const message = entry.message;
614
633
  const contentBlocks = Array.isArray(message?.content) ? message.content : [];
615
634
  if (entry.type === "assistant" && contentBlocks.length > 0) {
@@ -638,7 +657,7 @@ function analyzeTranscript(transcriptPath, acc) {
638
657
  for (const block of contentBlocks) {
639
658
  if (block.type === "tool_result") {
640
659
  const resultContent = typeof block.content === "string" ? block.content : Array.isArray(block.content) ? block.content.map((c2) => c2.text || "").join("\n") : "";
641
- const shaMatch = resultContent.match(/\[([a-f0-9]{7,12})\]\s/);
660
+ const shaMatch = resultContent.match(/\[(?:[^\]]+?\s)?([a-f0-9]{7,12})\]/);
642
661
  if (shaMatch) {
643
662
  acc.commitShas.add(shaMatch[1]);
644
663
  }
@@ -646,6 +665,9 @@ function analyzeTranscript(transcriptPath, acc) {
646
665
  }
647
666
  }
648
667
  }
668
+ if (firstTimestamp) {
669
+ acc.startedAt = firstTimestamp;
670
+ }
649
671
  return acc;
650
672
  }
651
673
  function categorizeWork(acc) {
@@ -668,14 +690,10 @@ function categorizeWork(acc) {
668
690
  else category = WorkCategory.FEATURE;
669
691
  } else {
670
692
  const tools = acc.toolCalls.map((t) => t.tool);
671
- const writeTools = tools.filter(
672
- (t) => ["Write", "Edit", "NotebookEdit"].includes(t)
673
- );
674
693
  const readTools = tools.filter(
675
694
  (t) => ["Read", "Grep", "Glob", "WebFetch", "WebSearch"].includes(t)
676
695
  );
677
- if (writeTools.length > 0) category = WorkCategory.FEATURE;
678
- else if (readTools.length > tools.length / 2) category = WorkCategory.REFACTOR;
696
+ if (readTools.length > tools.length / 2) category = WorkCategory.REFACTOR;
679
697
  }
680
698
  let complexity = Complexity.LOW;
681
699
  if (fileCount >= 7 || acc.toolCalls.length >= 30) complexity = Complexity.HIGH;
@@ -801,6 +819,7 @@ async function hookStop() {
801
819
  if (!session_id) process.exit(0);
802
820
  ensureDirs();
803
821
  pruneOldLogs();
822
+ fs5.writeFileSync(path5.join(BASESTREAM_DIR, "current-session-id"), session_id);
804
823
  const log = makeLogger(session_id);
805
824
  log("hook fired", "cwd=" + cwd);
806
825
  let acc = readSessionAccumulator(session_id);
@@ -943,18 +962,18 @@ var HELP = `
943
962
  basestream \u2014 AI work intelligence for teams
944
963
 
945
964
  Usage:
946
- npx @basestream/cli init Set up everything (hooks, auth, buffer)
965
+ npx @basestream/cli <command>
947
966
 
948
967
  Commands:
949
- basestream init Detect AI tools, inject hooks, authenticate
950
- basestream login Authenticate with your Basestream account
951
- basestream status Show this week's logged sessions
952
- basestream sync Manually sync buffered entries to Basestream
953
- basestream uninstall Remove the Claude Code tracking hook
968
+ init Detect AI tools, inject hooks, authenticate
969
+ login Authenticate with your Basestream account
970
+ status Show this week's logged sessions
971
+ sync Manually sync buffered entries to Basestream
972
+ uninstall Remove the Claude Code tracking hook
954
973
 
955
974
  Options:
956
- --help, -h Show this help message
957
- --version, -v Show version
975
+ --help, -h Show this help message
976
+ --version, -v Show version
958
977
  `;
959
978
  async function main() {
960
979
  const command = process.argv[2];
@@ -963,7 +982,7 @@ async function main() {
963
982
  process.exit(0);
964
983
  }
965
984
  if (command === "--version" || command === "-v") {
966
- console.log(true ? "0.2.7" : "dev");
985
+ console.log(true ? "0.2.9" : "dev");
967
986
  process.exit(0);
968
987
  }
969
988
  switch (command || "init") {
package/package.json CHANGED
@@ -18,5 +18,5 @@
18
18
  "unlink:cli": "npm unlink -g @basestream/cli"
19
19
  },
20
20
  "type": "module",
21
- "version": "0.2.7"
21
+ "version": "0.2.9"
22
22
  }