@dev_desh/flux-cap 0.1.4 → 0.2.0

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 (3) hide show
  1. package/README.md +25 -0
  2. package/dist/index.js +140 -47
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -294,6 +294,31 @@ src/
294
294
 
295
295
  This is currently a personal learning project, but feedback and suggestions are welcome!
296
296
 
297
+ How to control version bumps:
298
+
299
+ ### Method 1: Use GitHub Labels
300
+ Add these labels to your repository and apply them to PRs:
301
+ - `major` or `breaking` → Major version bump
302
+ - `minor` or `feature` → Minor version bump
303
+ - `patch` or `bugfix` → Patch version bump
304
+
305
+ ### Method 2: Use PR Title Syntax
306
+ Start your PR title with the version type in brackets:
307
+ - `[major] Remove deprecated API endpoints`
308
+ - `[minor] Add new search command`
309
+ - `[patch] Fix memory leak in dump command`
310
+
311
+ ### Method 3: Automatic Detection (Conservative)
312
+ The system will now only auto-detect major bumps with very explicit indicators like:
313
+ - "breaking change"
314
+ - "breaking:"
315
+ - "major:"
316
+ - "!breaking"
317
+ - "remove api"
318
+ - "delete command"
319
+
320
+ **Everything else defaults to patch unless you have clear feature indicators for minor.**
321
+
297
322
  ## License
298
323
 
299
324
  MIT
package/dist/index.js CHANGED
@@ -20645,7 +20645,7 @@ var FLUX_DEFAULT_CONFIG = {
20645
20645
  hideUncommittedChanges: false
20646
20646
  },
20647
20647
  search: {
20648
- searchFields: ["message", "workingDir", "branch", "tags"],
20648
+ searchFields: ["message", "workingDir", "branch", "tags", "id"],
20649
20649
  resultLimit: 10,
20650
20650
  fuseOptions: {
20651
20651
  threshold: 0.3,
@@ -20688,7 +20688,6 @@ async function getFluxPath() {
20688
20688
  let fullPath = cwd.split(path.sep);
20689
20689
  while (true) {
20690
20690
  let parentPath = fullPath.join(path.sep) + "/.flux";
20691
- console.log(`testing ${parentPath}`);
20692
20691
  if (fs.existsSync(parentPath)) {
20693
20692
  return parentPath.split(".flux")[0];
20694
20693
  break;
@@ -20763,9 +20762,79 @@ function getMonthString() {
20763
20762
  const month = String(currentDate.getMonth() + 1).padStart(2, "0");
20764
20763
  return `${year}-${month}`;
20765
20764
  }
20766
- function searchResultFormat({ message, timestamp, score, index }) {
20767
- const formattedTimestamp = new Date(timestamp).toLocaleString();
20768
- return `${index !== undefined ? index + 1 : ""}. [${score || "0.00"}] [${formattedTimestamp}] ${message}`;
20765
+ function displaySearchResults(results, query) {
20766
+ if (results.length === 0) {
20767
+ if (query) {
20768
+ console.log(`No brain dumps found matching "${query}"`);
20769
+ } else {
20770
+ console.log("No brain dumps found. Try 'flux dump' to create your first one!");
20771
+ }
20772
+ return;
20773
+ }
20774
+ const queryText = query ? ` for "${query}"` : "";
20775
+ console.log(`
20776
+ Found ${results.length} brain dump${results.length === 1 ? "" : "s"}${queryText}:
20777
+ `);
20778
+ const terminalWidth = process.stdout.columns || 80;
20779
+ const maxIndexWidth = results.length.toString().length;
20780
+ results.forEach((result, index) => {
20781
+ const dump = result.item;
20782
+ const score = result.score?.toFixed(2) || "0.00";
20783
+ const shortId = dump.id.substring(0, 8);
20784
+ const indexStr = `${(index + 1).toString().padStart(maxIndexWidth)}`;
20785
+ const scoreStr = `[${score}]`;
20786
+ const idStr = `${shortId}`;
20787
+ const headerLine = `${indexStr} ${idStr} ${scoreStr}`;
20788
+ console.log(headerLine);
20789
+ const messageIndent = " ".repeat(maxIndexWidth + 1);
20790
+ const lines = dump.message.split(`
20791
+ `).map((l) => l.trim()).filter((l) => l.length > 0);
20792
+ const availableWidth = terminalWidth - messageIndent.length - 2;
20793
+ if (lines.length === 0) {
20794
+ console.log(`${messageIndent}(empty message)`);
20795
+ } else {
20796
+ lines.forEach((line, lineIndex) => {
20797
+ if (lineIndex < 3) {
20798
+ const truncatedLine = line.length > availableWidth ? line.substring(0, availableWidth - 3) + "..." : line;
20799
+ console.log(`${messageIndent}${truncatedLine}`);
20800
+ }
20801
+ });
20802
+ if (lines.length > 3) {
20803
+ console.log(`${messageIndent}... (+${lines.length - 3} more line${lines.length - 3 === 1 ? "" : "s"})`);
20804
+ }
20805
+ }
20806
+ const contextInfo = [];
20807
+ const date = new Date(dump.timestamp);
20808
+ const timeAgo = getTimeAgo(date);
20809
+ contextInfo.push("----------------");
20810
+ contextInfo.push(`${timeAgo}`);
20811
+ contextInfo.push("----------------");
20812
+ contextInfo.push(`
20813
+ `);
20814
+ if (dump.branch && dump.branch !== "main") {
20815
+ contextInfo.push(`${dump.branch}${dump.hasUncommittedChanges ? " (uncommitted)" : ""}`);
20816
+ }
20817
+ if (contextInfo.length > 0) {
20818
+ console.log(`${messageIndent}${contextInfo.join(" • ")}`);
20819
+ }
20820
+ console.log("");
20821
+ });
20822
+ console.log(`!! Use the 8-character ID (like ${results[0]?.item.id.substring(0, 8)}) to reference specific dumps
20823
+ `);
20824
+ }
20825
+ function getTimeAgo(date) {
20826
+ const now = new Date;
20827
+ const diffMs = now.getTime() - date.getTime();
20828
+ const diffMins = Math.floor(diffMs / (1000 * 60));
20829
+ const diffHours = Math.floor(diffMins / 60);
20830
+ const diffDays = Math.floor(diffHours / 24);
20831
+ if (diffMins < 60)
20832
+ return `${diffMins}m ago`;
20833
+ if (diffHours < 24)
20834
+ return `${diffHours}h ago`;
20835
+ if (diffDays < 7)
20836
+ return `${diffDays}d ago`;
20837
+ return date.toLocaleDateString();
20769
20838
  }
20770
20839
  // node_modules/@inquirer/core/dist/lib/key.js
20771
20840
  var isUpKey = (key, keybindings = []) => key.name === "up" || keybindings.includes("vim") && key.name === "k" || keybindings.includes("emacs") && key.ctrl && key.name === "p";
@@ -23780,7 +23849,36 @@ var resetFluxCommand = async () => {
23780
23849
 
23781
23850
  // src/commands/dump.command.ts
23782
23851
  import { randomUUID as randomUUID2 } from "crypto";
23783
- async function brainDumpAddCommand(message) {
23852
+ async function handleBrainDump(message, options) {
23853
+ try {
23854
+ let finalMessage;
23855
+ if (options.multiline) {
23856
+ console.log("Opening editor for multiline input...");
23857
+ const initialText = message ? message.join(" ") : "";
23858
+ const multilineInput = await dist_default5({
23859
+ message: "Enter your brain dump (save & exit when done):",
23860
+ default: initialText,
23861
+ waitForUserInput: false
23862
+ });
23863
+ if (!multilineInput.trim()) {
23864
+ console.log("Brain dump cancelled - no content provided");
23865
+ return;
23866
+ }
23867
+ finalMessage = multilineInput.trim();
23868
+ } else {
23869
+ if (!message || message.length === 0) {
23870
+ console.log('Please provide a message: flux dump "your message"');
23871
+ return;
23872
+ }
23873
+ finalMessage = message.join(" ");
23874
+ }
23875
+ await brainDumpAddCommand(finalMessage, { multiline: options.multiline });
23876
+ } catch (error) {
23877
+ console.error("Error creating brain dump:", error instanceof Error ? error.message : "Unknown error");
23878
+ process.exit(1);
23879
+ }
23880
+ }
23881
+ async function brainDumpAddCommand(message, options = {}) {
23784
23882
  const fluxPath = await getFluxPath();
23785
23883
  const fs3 = await import("fs");
23786
23884
  console.log("Creating brain dump...");
@@ -23793,7 +23891,7 @@ async function brainDumpAddCommand(message) {
23793
23891
  const newDump = {
23794
23892
  id: randomUUID2(),
23795
23893
  timestamp: new Date().toISOString(),
23796
- message: message.join(" "),
23894
+ message,
23797
23895
  workingDir,
23798
23896
  branch,
23799
23897
  hasUncommittedChanges
@@ -23801,7 +23899,11 @@ async function brainDumpAddCommand(message) {
23801
23899
  const data = JSON.parse(fs3.readFileSync(`${fluxPath}${FLUX_BRAIN_DUMP_PATH}/${monthString}.json`, "utf8"));
23802
23900
  config.sorted ? data.dumps.unshift(newDump) : data.dumps.push(newDump);
23803
23901
  fs3.writeFileSync(`${fluxPath}${FLUX_BRAIN_DUMP_PATH}/${monthString}.json`, JSON.stringify(data, null, 2));
23804
- console.log(`✅ Brain dump saved: "${message.join(" ")}"`);
23902
+ const displayMessage = message.length > 50 ? message.substring(0, 47) + "..." : message;
23903
+ const preview = message.includes(`
23904
+ `) ? `${message.split(`
23905
+ `)[0]}... (multiline)` : displayMessage;
23906
+ console.log(`✅ Brain dump saved: "${preview}"`);
23805
23907
  }
23806
23908
 
23807
23909
  // node_modules/fuse.js/dist/fuse.mjs
@@ -25113,48 +25215,40 @@ async function searchBrainDumpCommand(query) {
25113
25215
  console.log("Searching all brain dumps...");
25114
25216
  const fluxPath = await getFluxPath();
25115
25217
  const config = await getConfigFile(fluxPath);
25116
- const monthString = getMonthString();
25218
+ const searchQuery = query.join(" ").trim();
25117
25219
  let searchResults = [];
25118
25220
  const allFilePaths = await getAllBrainDumpFilePaths(fluxPath);
25119
25221
  for await (const filePath of allFilePaths) {
25120
25222
  const fileData = JSON.parse(fs3.readFileSync(filePath, "utf8"));
25121
- const fuse = createFuseInstance(fileData.dumps, config);
25122
- const results = fuse.search(query.join(" "));
25123
- searchResults.push(...results);
25124
- if (searchResults.length > 30) {
25125
- break;
25223
+ if (searchQuery) {
25224
+ const fuse = createFuseInstance(fileData.dumps, config);
25225
+ const results = fuse.search(searchQuery);
25226
+ searchResults.push(...results);
25227
+ } else {
25228
+ const recentDumps = fileData.dumps.filter((dump) => dump && dump.message && dump.message.trim() !== "").map((dump) => ({
25229
+ item: dump,
25230
+ score: 0,
25231
+ timestamp: new Date(dump.timestamp).getTime()
25232
+ }));
25233
+ searchResults.push(...recentDumps);
25126
25234
  }
25127
25235
  }
25128
- if (query.length > 0) {
25129
- if (searchResults.length === 0) {
25130
- console.log("No brain dumps found matching the query.");
25131
- return;
25132
- }
25133
- const resultLimit = config?.search?.resultLimit || 10;
25134
- const limitedResults = searchResults.slice(0, resultLimit);
25135
- console.log(`Found ${searchResults.length} brain dumps matching the query${searchResults.length > resultLimit ? ` (showing first ${resultLimit})` : ""}:`);
25136
- limitedResults.forEach((result, index) => {
25137
- const dump = result.item;
25138
- console.log(searchResultFormat({ index, timestamp: dump.timestamp, message: dump.message, score: result.score?.toFixed(2) }));
25139
- });
25236
+ if (searchQuery) {
25237
+ searchResults.sort((a, b) => (a.score || 0) - (b.score || 0));
25140
25238
  } else {
25141
- const resultLimit = config?.search?.resultLimit || 3;
25142
- let totalCount = 0;
25143
- for await (const filePath of allFilePaths) {
25144
- if (totalCount >= resultLimit) {
25145
- break;
25146
- }
25147
- const fileData = JSON.parse(fs3.readFileSync(filePath, "utf8"));
25148
- for (let i = 0;i < fileData.dumps.length && totalCount < resultLimit; i++) {
25149
- const dump = fileData.dumps[i];
25150
- if (!dump || !dump.message || dump.message.trim() === "") {
25151
- continue;
25152
- }
25153
- totalCount += 1;
25154
- console.log(searchResultFormat({ index: totalCount, timestamp: dump.timestamp, message: dump.message, score: "0.00" }));
25155
- }
25156
- }
25239
+ searchResults.sort((a, b) => {
25240
+ const timeA = new Date(a.item.timestamp).getTime();
25241
+ const timeB = new Date(b.item.timestamp).getTime();
25242
+ return timeB - timeA;
25243
+ });
25244
+ }
25245
+ const resultLimit = config?.search?.resultLimit || (searchQuery ? 10 : 5);
25246
+ const limitedResults = searchResults.slice(0, resultLimit);
25247
+ if (searchResults.length > limitedResults.length) {
25248
+ console.log(`
25249
+ (Showing ${limitedResults.length} of ${searchResults.length} results)`);
25157
25250
  }
25251
+ displaySearchResults(limitedResults, searchQuery || undefined);
25158
25252
  }
25159
25253
 
25160
25254
  // src/commands/config.command.ts
@@ -25175,7 +25269,7 @@ async function configCommand(fields) {
25175
25269
  var package_default = {
25176
25270
  name: "@dev_desh/flux-cap",
25177
25271
  type: "module",
25178
- version: "0.1.4",
25272
+ version: "0.2.0",
25179
25273
  description: "Git-aware CLI context manager for ADHD developers",
25180
25274
  bin: {
25181
25275
  flux: "./dist/index.js"
@@ -25229,12 +25323,11 @@ var program2 = new Command;
25229
25323
  program2.name(`flux`).description("Git-aware CLI context manager for ADHD developers").version(package_default.version);
25230
25324
  program2.command("init").description("Initialize flux in the current repository").action(initFluxCommand);
25231
25325
  program2.command("reset").description("Resets flux in the current repository").action(resetFluxCommand);
25232
- program2.command("dump <message...>").description("Add a brain dump with a message. You can also include tags by using #tag in the message.").action(brainDumpAddCommand);
25326
+ program2.command("dump [message...]").option("-m, --multiline", "Enable multiline input mode").description("Add a brain dump with a message. Use --multiline for multi-line input.").action(async (message, options) => {
25327
+ await handleBrainDump(message, options);
25328
+ });
25233
25329
  program2.command("search [query...]").description("Search brain dumps with a query. If no query is provided, lists all brain dumps for the current month.").action((query) => {
25234
25330
  searchBrainDumpCommand(query ? query : [""]);
25235
25331
  });
25236
25332
  program2.command("config <fields...>").description("Update configuration fields. Example: flux config search.limit 10").action(configCommand);
25237
- program2.command("test").action(async () => {
25238
- console.log(`Path is - ${await getFluxPath()}`);
25239
- });
25240
25333
  program2.parse(process.argv);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dev_desh/flux-cap",
3
3
  "type": "module",
4
- "version": "0.1.4",
4
+ "version": "0.2.0",
5
5
  "description": "Git-aware CLI context manager for ADHD developers",
6
6
  "bin": {
7
7
  "flux": "./dist/index.js"