@dev_desh/flux-cap 0.1.1 → 0.1.4
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/README.md +131 -62
- package/dist/index.js +114 -75
- package/package.json +15 -2
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# flux-cap
|
|
2
2
|
|
|
3
3
|
**A git-aware CLI context manager for ADHD developers**
|
|
4
4
|
|
|
@@ -6,81 +6,164 @@
|
|
|
6
6
|
|
|
7
7
|
flux-cap is a terminal-native tool that captures your thoughts, tracks your context, and integrates seamlessly with your git workflow. Built specifically for developers who context-switch frequently.
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Installation
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Install flux-cap globally using your preferred package manager:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Using npm
|
|
15
|
+
npm install -g @dev_desh/flux-cap
|
|
16
|
+
|
|
17
|
+
# Using pnpm
|
|
18
|
+
pnpm install -g @dev_desh/flux-cap
|
|
19
|
+
|
|
20
|
+
# Using bun
|
|
21
|
+
bun install -g @dev_desh/flux-cap
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Quick Start
|
|
25
|
+
|
|
26
|
+
### 1. Initialize flux-cap in your project root folder
|
|
27
|
+
```bash
|
|
28
|
+
flux init
|
|
29
|
+
```
|
|
30
|
+
*Interactive setup will ask about your privacy preferences*
|
|
31
|
+
|
|
32
|
+
### 2. Start capturing thoughts
|
|
33
|
+
```bash
|
|
34
|
+
flux dump "remember to add error handling to auth module"
|
|
35
|
+
flux dump "bug in user validation - check line 42"
|
|
36
|
+
flux dump "idea: add dark mode toggle"
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### 3. Search your brain dumps
|
|
40
|
+
```bash
|
|
41
|
+
# Search with a query
|
|
42
|
+
flux search "auth"
|
|
43
|
+
|
|
44
|
+
# List recent dumps (no query)
|
|
45
|
+
flux search
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
## Features
|
|
50
|
+
|
|
51
|
+
### Brain Dump System
|
|
12
52
|
- Instantly capture thoughts without breaking flow: `flux dump "fix auth validation bug"`
|
|
13
53
|
- Git-aware context tracking (branch, working directory, uncommitted changes)
|
|
14
54
|
- Monthly file organization for easy browsing
|
|
15
55
|
- Privacy-first design - you control what gets tracked
|
|
16
56
|
|
|
17
|
-
###
|
|
57
|
+
### Search
|
|
18
58
|
- Fuzzy search across all your brain dumps: `flux search "auth"`
|
|
19
59
|
- Configurable search fields (message, branch, working directory)
|
|
20
|
-
-
|
|
60
|
+
- Result ranking with relevance scores
|
|
21
61
|
- Multi-month search with automatic limits
|
|
22
62
|
|
|
23
|
-
###
|
|
63
|
+
### Privacy Controls
|
|
24
64
|
- Choose what information to track during setup
|
|
25
65
|
- Hide working directory paths, branch names, or git status
|
|
26
66
|
- All data stored locally in human-readable JSON
|
|
27
67
|
- Edit or delete your data anytime
|
|
28
68
|
|
|
29
|
-
###
|
|
69
|
+
### Git Integration
|
|
30
70
|
- Automatic branch context detection
|
|
31
71
|
- Uncommitted changes tracking
|
|
32
|
-
-
|
|
72
|
+
- .gitignore management
|
|
33
73
|
- Works in non-git directories too
|
|
34
74
|
|
|
35
|
-
|
|
75
|
+
### Parent Directory Support
|
|
76
|
+
- Initialize flux-cap once in your project root and use it from any subdirectory
|
|
77
|
+
- Automatically discovers `.flux` configuration by traversing up the directory tree
|
|
78
|
+
- No need to initialize in every subfolder - works project-wide
|
|
79
|
+
- Seamlessly handles monorepos and complex project structures
|
|
36
80
|
|
|
37
|
-
```bash
|
|
38
|
-
# Clone the repository
|
|
39
|
-
git clone https://github.com/yourusername/flux-cap
|
|
40
|
-
cd flux-cap
|
|
41
81
|
|
|
42
|
-
|
|
43
|
-
bun install
|
|
82
|
+
## Commands
|
|
44
83
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
84
|
+
| Command | Description | Example |
|
|
85
|
+
|---------|-------------|---------|
|
|
86
|
+
| `flux init` | Initialize flux-cap with privacy setup | `flux init` |
|
|
87
|
+
| `flux dump <message...>` | Capture a brain dump | `flux dump "fix the bug in auth.ts"` |
|
|
88
|
+
| `flux search [query...]` | Search brain dumps or list recent ones | `flux search "authentication"` |
|
|
89
|
+
| `flux config <fields...>` | View or update configuration | `flux config` |
|
|
90
|
+
| `flux reset` | Complete reset (deletes all data) | `flux reset` |
|
|
91
|
+
|
|
92
|
+
## Use Cases
|
|
93
|
+
|
|
94
|
+
### Context Switching
|
|
95
|
+
```bash
|
|
96
|
+
# Before switching tasks
|
|
97
|
+
flux dump "was working on user auth, next: add validation to login form"
|
|
48
98
|
|
|
49
|
-
|
|
99
|
+
# After interruption
|
|
100
|
+
flux search "auth" # Quickly find where you left off
|
|
101
|
+
```
|
|
50
102
|
|
|
51
|
-
###
|
|
103
|
+
### Bug Tracking
|
|
52
104
|
```bash
|
|
53
|
-
|
|
105
|
+
flux dump "weird bug in payment flow - users can't checkout"
|
|
106
|
+
flux dump "bug seems related to session timeout"
|
|
107
|
+
|
|
108
|
+
# Later...
|
|
109
|
+
flux search "payment bug"
|
|
54
110
|
```
|
|
55
|
-
*Interactive setup will ask about your privacy preferences*
|
|
56
111
|
|
|
57
|
-
###
|
|
112
|
+
### Idea Capture
|
|
58
113
|
```bash
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
bun run dev dump "idea: add dark mode toggle"
|
|
114
|
+
flux dump "idea: add keyboard shortcuts to dashboard"
|
|
115
|
+
flux dump "maybe use React.memo for performance optimization"
|
|
62
116
|
```
|
|
63
117
|
|
|
64
|
-
|
|
118
|
+
## Automated Versioning
|
|
119
|
+
|
|
120
|
+
flux-cap uses [Changesets](https://github.com/changesets/changesets) for automated semantic versioning:
|
|
121
|
+
|
|
122
|
+
### What happens when you merge a PR:
|
|
123
|
+
1. **Automatic Analysis**: GitHub Actions analyzes your PR changes
|
|
124
|
+
2. **Smart Version Bumping**: Determines appropriate version (major/minor/patch) based on:
|
|
125
|
+
- PR title and description
|
|
126
|
+
- Commit messages
|
|
127
|
+
- Files changed
|
|
128
|
+
3. **Changelog Generation**: Creates detailed changelog entries
|
|
129
|
+
4. **Version Updates**: Updates `package.json` automatically
|
|
130
|
+
5. **Git Integration**: Commits changes back to main branch
|
|
131
|
+
|
|
132
|
+
### Version Bump Rules:
|
|
133
|
+
- **Major** (`1.0.0 → 2.0.0`): Breaking changes, removed features, incompatible API changes
|
|
134
|
+
- **Minor** (`1.0.0 → 1.1.0`): New features, new commands, backwards-compatible enhancements
|
|
135
|
+
- **Patch** (`1.0.0 → 1.0.1`): Bug fixes, documentation updates, refactoring, performance improvements
|
|
136
|
+
|
|
137
|
+
### Manual Changesets:
|
|
65
138
|
```bash
|
|
66
|
-
#
|
|
67
|
-
bun run
|
|
139
|
+
# Add a changeset manually (if needed)
|
|
140
|
+
bun run changeset
|
|
68
141
|
|
|
69
|
-
#
|
|
70
|
-
bun run
|
|
71
|
-
```
|
|
142
|
+
# Check pending changesets
|
|
143
|
+
bun run changeset:status
|
|
72
144
|
|
|
73
|
-
|
|
145
|
+
# Apply version changes locally
|
|
146
|
+
bun run changeset:version
|
|
74
147
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
148
|
+
## Development
|
|
149
|
+
|
|
150
|
+
Want to contribute or run locally?
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
# Clone and setup
|
|
154
|
+
git clone https://github.com/yourusername/flux-cap
|
|
155
|
+
cd flux-cap
|
|
156
|
+
bun install
|
|
82
157
|
|
|
83
|
-
|
|
158
|
+
# Run in development mode
|
|
159
|
+
bun run dev <command>
|
|
160
|
+
|
|
161
|
+
# Build and test locally
|
|
162
|
+
bun run build
|
|
163
|
+
npm link
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Configuration
|
|
84
167
|
|
|
85
168
|
flux-cap stores configuration in `.flux/config.json`. You can customize:
|
|
86
169
|
|
|
@@ -119,7 +202,7 @@ flux-cap stores configuration in `.flux/config.json`. You can customize:
|
|
|
119
202
|
}
|
|
120
203
|
```
|
|
121
204
|
|
|
122
|
-
##
|
|
205
|
+
## Data Structure
|
|
123
206
|
|
|
124
207
|
```
|
|
125
208
|
.flux/
|
|
@@ -142,7 +225,7 @@ flux-cap stores configuration in `.flux/config.json`. You can customize:
|
|
|
142
225
|
}
|
|
143
226
|
```
|
|
144
227
|
|
|
145
|
-
##
|
|
228
|
+
## Use Cases
|
|
146
229
|
|
|
147
230
|
### Context Switching
|
|
148
231
|
```bash
|
|
@@ -168,7 +251,7 @@ flux dump "idea: add keyboard shortcuts to dashboard"
|
|
|
168
251
|
flux dump "maybe use React.memo for performance optimization"
|
|
169
252
|
```
|
|
170
253
|
|
|
171
|
-
##
|
|
254
|
+
## Development
|
|
172
255
|
|
|
173
256
|
Built with:
|
|
174
257
|
- **Bun** - Fast JavaScript runtime
|
|
@@ -190,7 +273,7 @@ src/
|
|
|
190
273
|
└── types/ # TypeScript definitions
|
|
191
274
|
```
|
|
192
275
|
|
|
193
|
-
##
|
|
276
|
+
## Roadmap
|
|
194
277
|
|
|
195
278
|
### Phase 2 (Coming Soon)
|
|
196
279
|
- [ ] ASCII Pomodoro timer with themes
|
|
@@ -207,28 +290,14 @@ src/
|
|
|
207
290
|
- [ ] Team collaboration features
|
|
208
291
|
- [ ] Cross-machine sync
|
|
209
292
|
|
|
210
|
-
##
|
|
293
|
+
## Contributing
|
|
211
294
|
|
|
212
295
|
This is currently a personal learning project, but feedback and suggestions are welcome!
|
|
213
296
|
|
|
214
|
-
##
|
|
297
|
+
## License
|
|
215
298
|
|
|
216
299
|
MIT
|
|
217
300
|
|
|
218
301
|
---
|
|
219
302
|
|
|
220
|
-
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
This README showcases:
|
|
224
|
-
- ✅ Clear value proposition for ADHD developers
|
|
225
|
-
- ✅ All implemented features with examples
|
|
226
|
-
- ✅ Complete command reference
|
|
227
|
-
- ✅ Configuration documentation
|
|
228
|
-
- ✅ Privacy-first messaging
|
|
229
|
-
- ✅ Data structure transparency
|
|
230
|
-
- ✅ Real use cases
|
|
231
|
-
- ✅ Development info
|
|
232
|
-
- ✅ Future roadmap
|
|
233
|
-
|
|
234
|
-
**Ready to ship this for UAT?** The README positions flux-cap as a professional, thoughtful developer tool.
|
|
303
|
+
Built for developers who think fast, context-switch often, and never want to lose a good idea.
|
package/dist/index.js
CHANGED
|
@@ -7861,10 +7861,10 @@ var require_lib2 = __commonJS((exports) => {
|
|
|
7861
7861
|
exports.analyse = analyse;
|
|
7862
7862
|
var detectFile = (filepath, opts = {}) => new Promise((resolve, reject) => {
|
|
7863
7863
|
let fd;
|
|
7864
|
-
const
|
|
7864
|
+
const fs2 = (0, node_1.default)();
|
|
7865
7865
|
const handler = (err, buffer) => {
|
|
7866
7866
|
if (fd) {
|
|
7867
|
-
|
|
7867
|
+
fs2.closeSync(fd);
|
|
7868
7868
|
}
|
|
7869
7869
|
if (err) {
|
|
7870
7870
|
reject(err);
|
|
@@ -7876,9 +7876,9 @@ var require_lib2 = __commonJS((exports) => {
|
|
|
7876
7876
|
};
|
|
7877
7877
|
const sampleSize = (opts === null || opts === undefined ? undefined : opts.sampleSize) || 0;
|
|
7878
7878
|
if (sampleSize > 0) {
|
|
7879
|
-
fd =
|
|
7879
|
+
fd = fs2.openSync(filepath, "r");
|
|
7880
7880
|
let sample = Buffer.allocUnsafe(sampleSize);
|
|
7881
|
-
|
|
7881
|
+
fs2.read(fd, sample, 0, sampleSize, opts.offset, (err, bytesRead) => {
|
|
7882
7882
|
if (err) {
|
|
7883
7883
|
handler(err, null);
|
|
7884
7884
|
} else {
|
|
@@ -7890,22 +7890,22 @@ var require_lib2 = __commonJS((exports) => {
|
|
|
7890
7890
|
});
|
|
7891
7891
|
return;
|
|
7892
7892
|
}
|
|
7893
|
-
|
|
7893
|
+
fs2.readFile(filepath, handler);
|
|
7894
7894
|
});
|
|
7895
7895
|
exports.detectFile = detectFile;
|
|
7896
7896
|
var detectFileSync = (filepath, opts = {}) => {
|
|
7897
|
-
const
|
|
7897
|
+
const fs2 = (0, node_1.default)();
|
|
7898
7898
|
if (opts && opts.sampleSize) {
|
|
7899
|
-
const fd =
|
|
7899
|
+
const fd = fs2.openSync(filepath, "r");
|
|
7900
7900
|
let sample = Buffer.allocUnsafe(opts.sampleSize);
|
|
7901
|
-
const bytesRead =
|
|
7901
|
+
const bytesRead = fs2.readSync(fd, sample, 0, opts.sampleSize, opts.offset);
|
|
7902
7902
|
if (bytesRead < opts.sampleSize) {
|
|
7903
7903
|
sample = sample.subarray(0, bytesRead);
|
|
7904
7904
|
}
|
|
7905
|
-
|
|
7905
|
+
fs2.closeSync(fd);
|
|
7906
7906
|
return (0, exports.detect)(sample);
|
|
7907
7907
|
}
|
|
7908
|
-
return (0, exports.detect)(
|
|
7908
|
+
return (0, exports.detect)(fs2.readFileSync(filepath));
|
|
7909
7909
|
};
|
|
7910
7910
|
exports.detectFileSync = detectFileSync;
|
|
7911
7911
|
exports.default = {
|
|
@@ -20625,7 +20625,7 @@ var {
|
|
|
20625
20625
|
} = import__.default;
|
|
20626
20626
|
|
|
20627
20627
|
// src/commands/init.command.ts
|
|
20628
|
-
import
|
|
20628
|
+
import fs2 from "fs";
|
|
20629
20629
|
|
|
20630
20630
|
// src/utils/constants.ts
|
|
20631
20631
|
var FLUX_FOLDER_PATH = ".flux/";
|
|
@@ -20681,21 +20681,41 @@ function getCurrentBranch(config) {
|
|
|
20681
20681
|
}
|
|
20682
20682
|
}
|
|
20683
20683
|
// src/utils/lib.ts
|
|
20684
|
+
import fs from "fs";
|
|
20685
|
+
import path from "path";
|
|
20686
|
+
async function getFluxPath() {
|
|
20687
|
+
const cwd = process.cwd();
|
|
20688
|
+
let fullPath = cwd.split(path.sep);
|
|
20689
|
+
while (true) {
|
|
20690
|
+
let parentPath = fullPath.join(path.sep) + "/.flux";
|
|
20691
|
+
console.log(`testing ${parentPath}`);
|
|
20692
|
+
if (fs.existsSync(parentPath)) {
|
|
20693
|
+
return parentPath.split(".flux")[0];
|
|
20694
|
+
break;
|
|
20695
|
+
}
|
|
20696
|
+
fullPath.pop();
|
|
20697
|
+
if (fullPath.length === 0) {
|
|
20698
|
+
break;
|
|
20699
|
+
}
|
|
20700
|
+
}
|
|
20701
|
+
console.error("No .flux directory found in the current or parent directories. Please run 'flux init' to initialize.");
|
|
20702
|
+
process.exit(1);
|
|
20703
|
+
}
|
|
20684
20704
|
async function createIfNotExists(folderPath, type, data) {
|
|
20685
20705
|
try {
|
|
20686
|
-
const
|
|
20687
|
-
if (!
|
|
20706
|
+
const fs2 = await import("fs");
|
|
20707
|
+
if (!fs2.existsSync(folderPath)) {
|
|
20688
20708
|
if (type === "file") {
|
|
20689
|
-
|
|
20709
|
+
fs2.writeFileSync(folderPath, data || "");
|
|
20690
20710
|
return;
|
|
20691
20711
|
}
|
|
20692
|
-
|
|
20712
|
+
fs2.mkdirSync(folderPath, { recursive: true });
|
|
20693
20713
|
} else {
|
|
20694
20714
|
if (type === "file") {
|
|
20695
20715
|
try {
|
|
20696
|
-
const stats =
|
|
20716
|
+
const stats = fs2.statSync(folderPath);
|
|
20697
20717
|
if (stats.size === 0 && data) {
|
|
20698
|
-
|
|
20718
|
+
fs2.writeFileSync(folderPath, data);
|
|
20699
20719
|
}
|
|
20700
20720
|
} catch (writeError) {
|
|
20701
20721
|
if (writeError.code === "EACCES" || writeError.code === "EPERM") {
|
|
@@ -20705,7 +20725,7 @@ async function createIfNotExists(folderPath, type, data) {
|
|
|
20705
20725
|
}
|
|
20706
20726
|
} else {
|
|
20707
20727
|
try {
|
|
20708
|
-
|
|
20728
|
+
fs2.accessSync(folderPath, fs2.constants.W_OK);
|
|
20709
20729
|
} catch (accessError) {
|
|
20710
20730
|
if (accessError.code === "EACCES" || accessError.code === "EPERM") {
|
|
20711
20731
|
throw new Error(`No write permissions for directory: ${folderPath}`);
|
|
@@ -20717,24 +20737,24 @@ async function createIfNotExists(folderPath, type, data) {
|
|
|
20717
20737
|
throw error;
|
|
20718
20738
|
}
|
|
20719
20739
|
}
|
|
20720
|
-
async function createBrainDumpFileIfNotExists(dateString) {
|
|
20721
|
-
await createIfNotExists(`${FLUX_BRAIN_DUMP_PATH}${dateString}.json`, "file", JSON.stringify({
|
|
20740
|
+
async function createBrainDumpFileIfNotExists(dateString, fluxPath) {
|
|
20741
|
+
await createIfNotExists(`${fluxPath}${FLUX_BRAIN_DUMP_PATH}${dateString}.json`, "file", JSON.stringify({
|
|
20722
20742
|
fluxVersion: "0.0.1",
|
|
20723
20743
|
month: dateString,
|
|
20724
20744
|
dumps: []
|
|
20725
20745
|
}));
|
|
20726
20746
|
}
|
|
20727
|
-
async function getConfigFile() {
|
|
20728
|
-
const
|
|
20729
|
-
const configPath = `${FLUX_CONFIG_PATH}`;
|
|
20730
|
-
let config = JSON.parse(
|
|
20747
|
+
async function getConfigFile(fluxPath) {
|
|
20748
|
+
const fs2 = await import("fs");
|
|
20749
|
+
const configPath = `${fluxPath}${FLUX_CONFIG_PATH}`;
|
|
20750
|
+
let config = JSON.parse(fs2.readFileSync(configPath, "utf8"));
|
|
20731
20751
|
return config;
|
|
20732
20752
|
}
|
|
20733
|
-
async function getAllBrainDumpFilePaths() {
|
|
20734
|
-
const
|
|
20735
|
-
const
|
|
20736
|
-
const files =
|
|
20737
|
-
return files.filter((file) => file.endsWith(".json")).map((file) =>
|
|
20753
|
+
async function getAllBrainDumpFilePaths(fluxPath) {
|
|
20754
|
+
const fs2 = await import("fs");
|
|
20755
|
+
const path2 = await import("path");
|
|
20756
|
+
const files = fs2.readdirSync(fluxPath + FLUX_BRAIN_DUMP_PATH);
|
|
20757
|
+
return files.filter((file) => file.endsWith(".json")).map((file) => path2.join(fluxPath + FLUX_BRAIN_DUMP_PATH, file));
|
|
20738
20758
|
}
|
|
20739
20759
|
// src/utils/helper.ts
|
|
20740
20760
|
function getMonthString() {
|
|
@@ -22328,16 +22348,16 @@ var dist_default4 = createPrompt((config, done) => {
|
|
|
22328
22348
|
`).trimEnd();
|
|
22329
22349
|
return `${lines}${cursorHide}`;
|
|
22330
22350
|
});
|
|
22331
|
-
// node_modules/@inquirer/external-editor/dist/index.js
|
|
22351
|
+
// node_modules/@inquirer/editor/node_modules/@inquirer/external-editor/dist/index.js
|
|
22332
22352
|
var import_chardet = __toESM(require_lib2(), 1);
|
|
22333
22353
|
var import_iconv_lite = __toESM(require_lib3(), 1);
|
|
22334
22354
|
import { spawn, spawnSync } from "child_process";
|
|
22335
22355
|
import { readFileSync, unlinkSync, writeFileSync } from "fs";
|
|
22336
|
-
import
|
|
22356
|
+
import path2 from "node:path";
|
|
22337
22357
|
import os from "node:os";
|
|
22338
22358
|
import { randomUUID } from "node:crypto";
|
|
22339
22359
|
|
|
22340
|
-
// node_modules/@inquirer/external-editor/dist/errors/CreateFileError.js
|
|
22360
|
+
// node_modules/@inquirer/editor/node_modules/@inquirer/external-editor/dist/errors/CreateFileError.js
|
|
22341
22361
|
class CreateFileError extends Error {
|
|
22342
22362
|
originalError;
|
|
22343
22363
|
constructor(originalError) {
|
|
@@ -22346,7 +22366,7 @@ class CreateFileError extends Error {
|
|
|
22346
22366
|
}
|
|
22347
22367
|
}
|
|
22348
22368
|
|
|
22349
|
-
// node_modules/@inquirer/external-editor/dist/errors/LaunchEditorError.js
|
|
22369
|
+
// node_modules/@inquirer/editor/node_modules/@inquirer/external-editor/dist/errors/LaunchEditorError.js
|
|
22350
22370
|
class LaunchEditorError extends Error {
|
|
22351
22371
|
originalError;
|
|
22352
22372
|
constructor(originalError) {
|
|
@@ -22355,7 +22375,7 @@ class LaunchEditorError extends Error {
|
|
|
22355
22375
|
}
|
|
22356
22376
|
}
|
|
22357
22377
|
|
|
22358
|
-
// node_modules/@inquirer/external-editor/dist/errors/ReadFileError.js
|
|
22378
|
+
// node_modules/@inquirer/editor/node_modules/@inquirer/external-editor/dist/errors/ReadFileError.js
|
|
22359
22379
|
class ReadFileError extends Error {
|
|
22360
22380
|
originalError;
|
|
22361
22381
|
constructor(originalError) {
|
|
@@ -22364,7 +22384,7 @@ class ReadFileError extends Error {
|
|
|
22364
22384
|
}
|
|
22365
22385
|
}
|
|
22366
22386
|
|
|
22367
|
-
// node_modules/@inquirer/external-editor/dist/errors/RemoveFileError.js
|
|
22387
|
+
// node_modules/@inquirer/editor/node_modules/@inquirer/external-editor/dist/errors/RemoveFileError.js
|
|
22368
22388
|
class RemoveFileError extends Error {
|
|
22369
22389
|
originalError;
|
|
22370
22390
|
constructor(originalError) {
|
|
@@ -22373,7 +22393,7 @@ class RemoveFileError extends Error {
|
|
|
22373
22393
|
}
|
|
22374
22394
|
}
|
|
22375
22395
|
|
|
22376
|
-
// node_modules/@inquirer/external-editor/dist/index.js
|
|
22396
|
+
// node_modules/@inquirer/editor/node_modules/@inquirer/external-editor/dist/index.js
|
|
22377
22397
|
function editAsync(text = "", callback, fileOptions) {
|
|
22378
22398
|
const editor = new ExternalEditor(text, fileOptions);
|
|
22379
22399
|
editor.runAsync((err, result) => {
|
|
@@ -22469,8 +22489,8 @@ class ExternalEditor {
|
|
|
22469
22489
|
const prefix = sanitizeAffix(this.fileOptions.prefix);
|
|
22470
22490
|
const postfix = sanitizeAffix(this.fileOptions.postfix);
|
|
22471
22491
|
const filename = `${prefix}${id}${postfix}`;
|
|
22472
|
-
const candidate =
|
|
22473
|
-
const baseResolved =
|
|
22492
|
+
const candidate = path2.resolve(baseDir, filename);
|
|
22493
|
+
const baseResolved = path2.resolve(baseDir) + path2.sep;
|
|
22474
22494
|
if (!candidate.startsWith(baseResolved)) {
|
|
22475
22495
|
throw new Error("Resolved temporary file escaped the base directory");
|
|
22476
22496
|
}
|
|
@@ -23408,9 +23428,9 @@ var import_run_async = __toESM(require_run_async(), 1);
|
|
|
23408
23428
|
var import_mute_stream2 = __toESM(require_lib(), 1);
|
|
23409
23429
|
import readline3 from "node:readline";
|
|
23410
23430
|
var _ = {
|
|
23411
|
-
set: (obj,
|
|
23431
|
+
set: (obj, path3 = "", value) => {
|
|
23412
23432
|
let pointer = obj;
|
|
23413
|
-
|
|
23433
|
+
path3.split(".").forEach((key, index, arr) => {
|
|
23414
23434
|
if (key === "__proto__" || key === "constructor")
|
|
23415
23435
|
return;
|
|
23416
23436
|
if (index === arr.length - 1) {
|
|
@@ -23421,8 +23441,8 @@ var _ = {
|
|
|
23421
23441
|
pointer = pointer[key];
|
|
23422
23442
|
});
|
|
23423
23443
|
},
|
|
23424
|
-
get: (obj,
|
|
23425
|
-
const travel = (regexp) => String.prototype.split.call(
|
|
23444
|
+
get: (obj, path3 = "", defaultValue) => {
|
|
23445
|
+
const travel = (regexp) => String.prototype.split.call(path3, regexp).filter(Boolean).reduce((res, key) => res == null ? res : res[key], obj);
|
|
23426
23446
|
const result = travel(/[,[\]]+?/) || travel(/[,.[\]]+?/);
|
|
23427
23447
|
return result === undefined || result === obj ? defaultValue : result;
|
|
23428
23448
|
}
|
|
@@ -23706,22 +23726,22 @@ async function initFluxCommand() {
|
|
|
23706
23726
|
process.exit(1);
|
|
23707
23727
|
}
|
|
23708
23728
|
try {
|
|
23709
|
-
if (
|
|
23729
|
+
if (fs2.existsSync(".git/")) {
|
|
23710
23730
|
console.log("Git repository detected.");
|
|
23711
23731
|
} else {
|
|
23712
23732
|
console.log("Not a git repository. Skipping git integration.");
|
|
23713
23733
|
}
|
|
23714
|
-
if (
|
|
23734
|
+
if (fs2.existsSync(".gitignore")) {
|
|
23715
23735
|
console.log("Gitignore file exists");
|
|
23716
|
-
const gitignoreContent =
|
|
23736
|
+
const gitignoreContent = fs2.readFileSync(".gitignore", "utf8");
|
|
23717
23737
|
if (gitignoreContent.includes(FLUX_FOLDER_PATH)) {
|
|
23718
23738
|
console.log(".flux is already in .gitignore");
|
|
23719
23739
|
} else {
|
|
23720
|
-
|
|
23740
|
+
fs2.appendFileSync(".gitignore", `
|
|
23721
23741
|
${FLUX_FOLDER_PATH}`);
|
|
23722
23742
|
}
|
|
23723
23743
|
} else {
|
|
23724
|
-
|
|
23744
|
+
fs2.writeFileSync(".gitignore", ".flux");
|
|
23725
23745
|
console.log("Created .gitignore file.");
|
|
23726
23746
|
}
|
|
23727
23747
|
} catch (error) {
|
|
@@ -23733,6 +23753,7 @@ ${FLUX_FOLDER_PATH}`);
|
|
|
23733
23753
|
}
|
|
23734
23754
|
var resetFluxCommand = async () => {
|
|
23735
23755
|
console.log("Resetting Flux Capacitor...");
|
|
23756
|
+
const fluxPath = await getFluxPath() + FLUX_FOLDER_PATH;
|
|
23736
23757
|
const { confirmed } = await dist_default14.prompt([{
|
|
23737
23758
|
type: "confirm",
|
|
23738
23759
|
name: "confirmed",
|
|
@@ -23744,8 +23765,8 @@ var resetFluxCommand = async () => {
|
|
|
23744
23765
|
return;
|
|
23745
23766
|
}
|
|
23746
23767
|
try {
|
|
23747
|
-
if (
|
|
23748
|
-
|
|
23768
|
+
if (fs2.existsSync(fluxPath)) {
|
|
23769
|
+
fs2.rmSync(fluxPath, { recursive: true, force: true });
|
|
23749
23770
|
console.log("Removed .flux directory and all its contents.");
|
|
23750
23771
|
} else {
|
|
23751
23772
|
console.log("Flux Capacitor is not initialized in this repository.");
|
|
@@ -23760,11 +23781,12 @@ var resetFluxCommand = async () => {
|
|
|
23760
23781
|
// src/commands/dump.command.ts
|
|
23761
23782
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
23762
23783
|
async function brainDumpAddCommand(message) {
|
|
23763
|
-
const
|
|
23784
|
+
const fluxPath = await getFluxPath();
|
|
23785
|
+
const fs3 = await import("fs");
|
|
23764
23786
|
console.log("Creating brain dump...");
|
|
23765
23787
|
const monthString = getMonthString();
|
|
23766
|
-
await createBrainDumpFileIfNotExists(monthString);
|
|
23767
|
-
const config = await getConfigFile();
|
|
23788
|
+
await createBrainDumpFileIfNotExists(monthString, fluxPath);
|
|
23789
|
+
const config = await getConfigFile(fluxPath);
|
|
23768
23790
|
const workingDir = await getWorkingDir(config);
|
|
23769
23791
|
const branch = getCurrentBranch(config);
|
|
23770
23792
|
const hasUncommittedChanges = getGitUncommittedChanges(config);
|
|
@@ -23776,9 +23798,9 @@ async function brainDumpAddCommand(message) {
|
|
|
23776
23798
|
branch,
|
|
23777
23799
|
hasUncommittedChanges
|
|
23778
23800
|
};
|
|
23779
|
-
const data = JSON.parse(
|
|
23801
|
+
const data = JSON.parse(fs3.readFileSync(`${fluxPath}${FLUX_BRAIN_DUMP_PATH}/${monthString}.json`, "utf8"));
|
|
23780
23802
|
config.sorted ? data.dumps.unshift(newDump) : data.dumps.push(newDump);
|
|
23781
|
-
|
|
23803
|
+
fs3.writeFileSync(`${fluxPath}${FLUX_BRAIN_DUMP_PATH}/${monthString}.json`, JSON.stringify(data, null, 2));
|
|
23782
23804
|
console.log(`✅ Brain dump saved: "${message.join(" ")}"`);
|
|
23783
23805
|
}
|
|
23784
23806
|
|
|
@@ -23854,14 +23876,14 @@ class KeyStore {
|
|
|
23854
23876
|
}
|
|
23855
23877
|
}
|
|
23856
23878
|
function createKey(key) {
|
|
23857
|
-
let
|
|
23879
|
+
let path3 = null;
|
|
23858
23880
|
let id = null;
|
|
23859
23881
|
let src = null;
|
|
23860
23882
|
let weight = 1;
|
|
23861
23883
|
let getFn = null;
|
|
23862
23884
|
if (isString(key) || isArray(key)) {
|
|
23863
23885
|
src = key;
|
|
23864
|
-
|
|
23886
|
+
path3 = createKeyPath(key);
|
|
23865
23887
|
id = createKeyId(key);
|
|
23866
23888
|
} else {
|
|
23867
23889
|
if (!hasOwn.call(key, "name")) {
|
|
@@ -23875,11 +23897,11 @@ function createKey(key) {
|
|
|
23875
23897
|
throw new Error(INVALID_KEY_WEIGHT_VALUE(name));
|
|
23876
23898
|
}
|
|
23877
23899
|
}
|
|
23878
|
-
|
|
23900
|
+
path3 = createKeyPath(name);
|
|
23879
23901
|
id = createKeyId(name);
|
|
23880
23902
|
getFn = key.getFn;
|
|
23881
23903
|
}
|
|
23882
|
-
return { path:
|
|
23904
|
+
return { path: path3, id, weight, src, getFn };
|
|
23883
23905
|
}
|
|
23884
23906
|
function createKeyPath(key) {
|
|
23885
23907
|
return isArray(key) ? key : key.split(".");
|
|
@@ -23887,34 +23909,34 @@ function createKeyPath(key) {
|
|
|
23887
23909
|
function createKeyId(key) {
|
|
23888
23910
|
return isArray(key) ? key.join(".") : key;
|
|
23889
23911
|
}
|
|
23890
|
-
function get(obj,
|
|
23912
|
+
function get(obj, path3) {
|
|
23891
23913
|
let list = [];
|
|
23892
23914
|
let arr = false;
|
|
23893
|
-
const deepGet = (obj2,
|
|
23915
|
+
const deepGet = (obj2, path4, index) => {
|
|
23894
23916
|
if (!isDefined(obj2)) {
|
|
23895
23917
|
return;
|
|
23896
23918
|
}
|
|
23897
|
-
if (!
|
|
23919
|
+
if (!path4[index]) {
|
|
23898
23920
|
list.push(obj2);
|
|
23899
23921
|
} else {
|
|
23900
|
-
let key =
|
|
23922
|
+
let key = path4[index];
|
|
23901
23923
|
const value = obj2[key];
|
|
23902
23924
|
if (!isDefined(value)) {
|
|
23903
23925
|
return;
|
|
23904
23926
|
}
|
|
23905
|
-
if (index ===
|
|
23927
|
+
if (index === path4.length - 1 && (isString(value) || isNumber(value) || isBoolean(value))) {
|
|
23906
23928
|
list.push(toString(value));
|
|
23907
23929
|
} else if (isArray(value)) {
|
|
23908
23930
|
arr = true;
|
|
23909
23931
|
for (let i = 0, len = value.length;i < len; i += 1) {
|
|
23910
|
-
deepGet(value[i],
|
|
23932
|
+
deepGet(value[i], path4, index + 1);
|
|
23911
23933
|
}
|
|
23912
|
-
} else if (
|
|
23913
|
-
deepGet(value,
|
|
23934
|
+
} else if (path4.length) {
|
|
23935
|
+
deepGet(value, path4, index + 1);
|
|
23914
23936
|
}
|
|
23915
23937
|
}
|
|
23916
23938
|
};
|
|
23917
|
-
deepGet(obj, isString(
|
|
23939
|
+
deepGet(obj, isString(path3) ? path3.split(".") : path3, 0);
|
|
23918
23940
|
return arr ? list : list[0];
|
|
23919
23941
|
}
|
|
23920
23942
|
var MatchOptions = {
|
|
@@ -25086,15 +25108,16 @@ function createFuseInstance(data, config) {
|
|
|
25086
25108
|
}
|
|
25087
25109
|
|
|
25088
25110
|
// src/commands/search.command.ts
|
|
25089
|
-
import
|
|
25111
|
+
import fs3 from "fs";
|
|
25090
25112
|
async function searchBrainDumpCommand(query) {
|
|
25091
25113
|
console.log("Searching all brain dumps...");
|
|
25092
|
-
const
|
|
25114
|
+
const fluxPath = await getFluxPath();
|
|
25115
|
+
const config = await getConfigFile(fluxPath);
|
|
25093
25116
|
const monthString = getMonthString();
|
|
25094
25117
|
let searchResults = [];
|
|
25095
|
-
const allFilePaths = await getAllBrainDumpFilePaths();
|
|
25118
|
+
const allFilePaths = await getAllBrainDumpFilePaths(fluxPath);
|
|
25096
25119
|
for await (const filePath of allFilePaths) {
|
|
25097
|
-
const fileData = JSON.parse(
|
|
25120
|
+
const fileData = JSON.parse(fs3.readFileSync(filePath, "utf8"));
|
|
25098
25121
|
const fuse = createFuseInstance(fileData.dumps, config);
|
|
25099
25122
|
const results = fuse.search(query.join(" "));
|
|
25100
25123
|
searchResults.push(...results);
|
|
@@ -25121,7 +25144,7 @@ async function searchBrainDumpCommand(query) {
|
|
|
25121
25144
|
if (totalCount >= resultLimit) {
|
|
25122
25145
|
break;
|
|
25123
25146
|
}
|
|
25124
|
-
const fileData = JSON.parse(
|
|
25147
|
+
const fileData = JSON.parse(fs3.readFileSync(filePath, "utf8"));
|
|
25125
25148
|
for (let i = 0;i < fileData.dumps.length && totalCount < resultLimit; i++) {
|
|
25126
25149
|
const dump = fileData.dumps[i];
|
|
25127
25150
|
if (!dump || !dump.message || dump.message.trim() === "") {
|
|
@@ -25137,7 +25160,7 @@ async function searchBrainDumpCommand(query) {
|
|
|
25137
25160
|
// src/commands/config.command.ts
|
|
25138
25161
|
async function configCommand(fields) {
|
|
25139
25162
|
console.log("This command is still to be implemented");
|
|
25140
|
-
const
|
|
25163
|
+
const fs4 = await import("fs");
|
|
25141
25164
|
const config = await getConfigFile();
|
|
25142
25165
|
const value = fields[fields.length - 1];
|
|
25143
25166
|
const keys = fields.slice(0, -1)[0]?.split(".").map((k) => k.trim()) || [];
|
|
@@ -25151,7 +25174,8 @@ async function configCommand(fields) {
|
|
|
25151
25174
|
// package.json
|
|
25152
25175
|
var package_default = {
|
|
25153
25176
|
name: "@dev_desh/flux-cap",
|
|
25154
|
-
|
|
25177
|
+
type: "module",
|
|
25178
|
+
version: "0.1.4",
|
|
25155
25179
|
description: "Git-aware CLI context manager for ADHD developers",
|
|
25156
25180
|
bin: {
|
|
25157
25181
|
flux: "./dist/index.js"
|
|
@@ -25165,8 +25189,15 @@ var package_default = {
|
|
|
25165
25189
|
build: "bun build src/index.ts --outdir dist --target node --format esm",
|
|
25166
25190
|
dev: "bun run src/index.ts",
|
|
25167
25191
|
prepublishOnly: "bun run build",
|
|
25192
|
+
publish: "npm publish --access=public",
|
|
25168
25193
|
"local-install": "bun run build && npm link",
|
|
25169
|
-
"local-uninstall": "npm unlink -g flux-cap"
|
|
25194
|
+
"local-uninstall": "npm unlink -g flux-cap",
|
|
25195
|
+
"local-reinstall": "bun run local-uninstall && bun run local-install",
|
|
25196
|
+
changeset: "changeset",
|
|
25197
|
+
"changeset:add": "changeset add",
|
|
25198
|
+
"changeset:status": "changeset status",
|
|
25199
|
+
"changeset:version": "changeset version",
|
|
25200
|
+
"changeset:publish": "changeset publish"
|
|
25170
25201
|
},
|
|
25171
25202
|
engines: {
|
|
25172
25203
|
node: ">=18.0.0"
|
|
@@ -25184,7 +25215,12 @@ var package_default = {
|
|
|
25184
25215
|
inquirer: "^13.2.5"
|
|
25185
25216
|
},
|
|
25186
25217
|
devDependencies: {
|
|
25218
|
+
"@changesets/cli": "^2.29.8",
|
|
25187
25219
|
"@types/inquirer": "^9.0.9"
|
|
25220
|
+
},
|
|
25221
|
+
repository: {
|
|
25222
|
+
type: "git",
|
|
25223
|
+
url: "https://github.com/kaustubh285/flux-cap"
|
|
25188
25224
|
}
|
|
25189
25225
|
};
|
|
25190
25226
|
|
|
@@ -25198,4 +25234,7 @@ program2.command("search [query...]").description("Search brain dumps with a que
|
|
|
25198
25234
|
searchBrainDumpCommand(query ? query : [""]);
|
|
25199
25235
|
});
|
|
25200
25236
|
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
|
+
});
|
|
25201
25240
|
program2.parse(process.argv);
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dev_desh/flux-cap",
|
|
3
|
-
"
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "0.1.4",
|
|
4
5
|
"description": "Git-aware CLI context manager for ADHD developers",
|
|
5
6
|
"bin": {
|
|
6
7
|
"flux": "./dist/index.js"
|
|
@@ -14,8 +15,15 @@
|
|
|
14
15
|
"build": "bun build src/index.ts --outdir dist --target node --format esm",
|
|
15
16
|
"dev": "bun run src/index.ts",
|
|
16
17
|
"prepublishOnly": "bun run build",
|
|
18
|
+
"publish": "npm publish --access=public",
|
|
17
19
|
"local-install": "bun run build && npm link",
|
|
18
|
-
"local-uninstall": "npm unlink -g flux-cap"
|
|
20
|
+
"local-uninstall": "npm unlink -g flux-cap",
|
|
21
|
+
"local-reinstall": "bun run local-uninstall && bun run local-install",
|
|
22
|
+
"changeset": "changeset",
|
|
23
|
+
"changeset:add": "changeset add",
|
|
24
|
+
"changeset:status": "changeset status",
|
|
25
|
+
"changeset:version": "changeset version",
|
|
26
|
+
"changeset:publish": "changeset publish"
|
|
19
27
|
},
|
|
20
28
|
"engines": {
|
|
21
29
|
"node": ">=18.0.0"
|
|
@@ -33,6 +41,11 @@
|
|
|
33
41
|
"inquirer": "^13.2.5"
|
|
34
42
|
},
|
|
35
43
|
"devDependencies": {
|
|
44
|
+
"@changesets/cli": "^2.29.8",
|
|
36
45
|
"@types/inquirer": "^9.0.9"
|
|
46
|
+
},
|
|
47
|
+
"repository": {
|
|
48
|
+
"type": "git",
|
|
49
|
+
"url": "https://github.com/kaustubh285/flux-cap"
|
|
37
50
|
}
|
|
38
51
|
}
|