@xxkeefer/mrkl 0.2.4 → 0.2.14

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 +30 -12
  2. package/dist/cli.mjs +10 -2
  3. package/package.json +10 -8
package/README.md CHANGED
@@ -28,7 +28,7 @@ Most task trackers live outside your codebase. mrkl keeps tasks as markdown file
28
28
  ## Install
29
29
 
30
30
  ```sh
31
- npm install -g @xxkeefer/mrkl
31
+ pnpm add -g @xxkeefer/mrkl
32
32
  ```
33
33
 
34
34
  Or use without installing:
@@ -186,6 +186,30 @@ your-project/
186
186
 
187
187
  Commit `.config/mrkl/` and `.tasks/` to version control. They're designed to be tracked alongside your code.
188
188
 
189
+ ## Team Workflow
190
+
191
+ When using mrkl with **git worktrees** or **protected branches**, task IDs can conflict if multiple branches create tasks concurrently. The fix is a simple convention: **separate planning from execution.**
192
+
193
+ 1. **Plan** — Create tasks on a `planning/` branch, merge to main via PR
194
+ 2. **Execute** — Branch feature work from main (which has all tasks)
195
+ 3. **Ad-hoc** — Mid-sprint tasks follow the same pattern at smaller scale
196
+
197
+ ```sh
198
+ # Sprint planning
199
+ git checkout -b planning/sprint-3 main
200
+ mrkl create feat "user authentication"
201
+ mrkl create fix "login redirect loop"
202
+ # commit, PR, merge to main
203
+
204
+ # Feature work (branch from main after planning merges)
205
+ git checkout -b feature/MRKL-019_user-auth main
206
+ # ... do the work ...
207
+ mrkl done MRKL-019
208
+ # commit, PR, merge to main
209
+ ```
210
+
211
+ The counter only increments on planning branches — one at a time — so IDs never conflict. See **[docs/workflow.md](docs/workflow.md)** for the full guide with examples and edge cases.
212
+
189
213
  ## Configuration
190
214
 
191
215
  Configuration lives in `.config/mrkl/mrkl.toml` (or `mrkl.toml` at the project root):
@@ -205,27 +229,21 @@ tasks_dir = ".tasks"
205
229
  ```sh
206
230
  git clone https://github.com/xxKeefer/mrkl.git
207
231
  cd mrkl
208
- npm install
232
+ pnpm install
209
233
 
210
234
  # Run tests
211
- npm test
235
+ pnpm test
212
236
 
213
237
  # Run CLI in development
214
- npx tsx src/cli.ts list
238
+ pnpm tsx src/cli.ts list
215
239
 
216
240
  # Build
217
- npm run build
241
+ pnpm build
218
242
  ```
219
243
 
220
244
  ## Contributing
221
245
 
222
- Contributions are welcome. Please open an issue first to discuss what you'd like to change.
223
-
224
- 1. Fork the repo
225
- 2. Create your branch (`git checkout -b feat/my-feature`)
226
- 3. Commit your changes using [conventional commits](https://www.conventionalcommits.org/)
227
- 4. Push to your branch (`git push origin feat/my-feature`)
228
- 5. Open a Pull Request
246
+ Contributions are welcome! See **[CONTRIBUTING.md](CONTRIBUTING.md)** for branch protection rules, merge strategy, and development setup.
229
247
 
230
248
  ## License
231
249
 
package/dist/cli.mjs CHANGED
@@ -117,6 +117,11 @@ function parse(content, filename) {
117
117
  };
118
118
  }
119
119
 
120
+ function normalizeTitle(raw) {
121
+ const result = raw.trim().toLowerCase().replace(/[/\\]/g, "-").replace(/[<>:"|?*\x00-\x1f]/g, "").replace(/-{2,}/g, "-").replace(/ {2,}/g, " ").replace(/^-+|-+$/g, "");
122
+ if (!result) throw new Error("Title is empty after normalisation");
123
+ return result;
124
+ }
120
125
  function createTask(opts) {
121
126
  const config = loadConfig(opts.dir);
122
127
  const num = nextId(opts.dir);
@@ -127,7 +132,7 @@ function createTask(opts) {
127
132
  type: opts.type,
128
133
  status: "todo",
129
134
  created: today,
130
- title: opts.title,
135
+ title: normalizeTitle(opts.title),
131
136
  description: opts.description ?? "",
132
137
  acceptance_criteria: opts.acceptance_criteria ?? []
133
138
  };
@@ -224,7 +229,7 @@ const createCommand = defineCommand({
224
229
  type: args.type,
225
230
  title: args.title,
226
231
  description: args.desc,
227
- acceptance_criteria: args.ac ? [args.ac] : void 0
232
+ acceptance_criteria: args.ac ? Array.isArray(args.ac) ? args.ac : [args.ac] : void 0
228
233
  });
229
234
  consola.success(`Created ${task.id}: ${task.title}`);
230
235
  } catch (err) {
@@ -304,8 +309,11 @@ const main = defineCommand({
304
309
  subCommands: {
305
310
  init: initCommand,
306
311
  create: createCommand,
312
+ c: createCommand,
307
313
  list: listCommand,
308
314
  done: doneCommand
309
315
  }
310
316
  });
311
317
  runMain(main);
318
+
319
+ export { main };
package/package.json CHANGED
@@ -1,17 +1,11 @@
1
1
  {
2
2
  "name": "@xxkeefer/mrkl",
3
- "version": "0.2.4",
3
+ "version": "0.2.14",
4
4
  "type": "module",
5
5
  "description": "Lightweight CLI tool for structured markdown task tracking",
6
6
  "bin": {
7
7
  "mrkl": "./dist/cli.mjs"
8
8
  },
9
- "scripts": {
10
- "build": "unbuild",
11
- "dev": "node --import tsx src/cli.ts",
12
- "test": "vitest run",
13
- "release": "./scripts/release.sh"
14
- },
15
9
  "keywords": [
16
10
  "cli",
17
11
  "task",
@@ -38,8 +32,16 @@
38
32
  },
39
33
  "devDependencies": {
40
34
  "@types/node": "^25.3.3",
35
+ "changelogen": "^0.6.2",
41
36
  "typescript": "^5.7.0",
42
37
  "unbuild": "^3.3.1",
43
38
  "vitest": "^3.0.0"
39
+ },
40
+ "scripts": {
41
+ "build": "unbuild",
42
+ "dev": "node --import tsx src/cli.ts",
43
+ "test": "vitest run",
44
+ "changelog": "changelogen --output",
45
+ "changelog:preview": "changelogen --no-output"
44
46
  }
45
- }
47
+ }