@benzotti/jedi 0.1.36 → 0.1.38

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.
@@ -9,7 +9,7 @@
9
9
  # - Set CLICKUP_API_TOKEN secret for ClickUp ticket integration
10
10
  # - Set JEDI_COMMIT_LEARNINGS=true repo variable to persist learnings in git
11
11
  # - Set JEDI_LEARNINGS_REPO variable to push learnings to a central repo (e.g. org/jedi-learnings)
12
- # - Set JEDI_LEARNINGS_TOKEN secret (PAT with repo access) when using an external learnings repo
12
+ # - Set JEDI_LEARNINGS_TOKEN secret (PAT with Contents read/write on the learnings repo)
13
13
  # - Run `npx @benzotti/jedi init` locally to customise framework files
14
14
  #
15
15
  # Usage: Comment on any issue or PR with "Hey Jedi" followed by a command:
@@ -127,10 +127,10 @@ jobs:
127
127
  if: vars.JEDI_LEARNINGS_REPO != ''
128
128
  run: |
129
129
  LEARNINGS_DIR=".jdi/framework/learnings"
130
+ REMOTE_SUBDIR="jedi/learnings"
130
131
  mkdir -p "$LEARNINGS_DIR"
131
132
 
132
- # Clone only the directory for this repo's learnings (sparse checkout)
133
- REPO_SUBDIR="${{ github.repository }}"
133
+ # Clone only the learnings directory (sparse checkout)
134
134
  TMPDIR=$(mktemp -d)
135
135
  git clone --depth 1 --filter=blob:none --sparse \
136
136
  "https://x-access-token:${LEARNINGS_TOKEN}@github.com/${LEARNINGS_REPO}.git" \
@@ -140,13 +140,13 @@ jobs:
140
140
  }
141
141
 
142
142
  cd "$TMPDIR"
143
- git sparse-checkout set "$REPO_SUBDIR" 2>/dev/null || true
143
+ git sparse-checkout set "$REMOTE_SUBDIR" 2>/dev/null || true
144
144
  cd - > /dev/null
145
145
 
146
146
  # Copy learnings from external repo into local framework
147
147
  # External learnings serve as baseline; cache/local files take precedence
148
- if [ -d "$TMPDIR/$REPO_SUBDIR" ]; then
149
- for f in "$TMPDIR/$REPO_SUBDIR"/*.md; do
148
+ if [ -d "$TMPDIR/$REMOTE_SUBDIR" ]; then
149
+ for f in "$TMPDIR/$REMOTE_SUBDIR"/*.md; do
150
150
  [ -f "$f" ] || continue
151
151
  BASENAME=$(basename "$f")
152
152
  # Only copy if local file doesn't exist (cache/committed files take precedence)
@@ -156,7 +156,7 @@ jobs:
156
156
  fi
157
157
  done
158
158
  else
159
- echo "No shared learnings found for ${{ github.repository }} — continuing"
159
+ echo "No shared learnings found — continuing"
160
160
  fi
161
161
 
162
162
  rm -rf "$TMPDIR"
@@ -292,8 +292,8 @@ jobs:
292
292
  # Where learnings are committed:
293
293
  # - Same repo (default): .jdi/framework/learnings/ on main
294
294
  # - External repo: set JEDI_LEARNINGS_REPO (e.g. org/jedi-learnings)
295
- # and JEDI_LEARNINGS_TOKEN secret. Learnings are namespaced under
296
- # <owner>/<repo>/ in the external repo to support multiple projects.
295
+ # and JEDI_LEARNINGS_TOKEN secret. Learnings are stored under
296
+ # jedi/learnings/ in the external repo and merged (not replaced).
297
297
  - name: Commit learnings to repo
298
298
  if: >-
299
299
  steps.check.outputs.skip != 'true'
@@ -301,6 +301,7 @@ jobs:
301
301
  && vars.JEDI_COMMIT_LEARNINGS == 'true'
302
302
  run: |
303
303
  LEARNINGS_SRC=".jdi/framework/learnings"
304
+ REMOTE_SUBDIR="jedi/learnings"
304
305
 
305
306
  # Only proceed if there are learnings files with content
306
307
  if [ ! -d "$LEARNINGS_SRC" ]; then
@@ -327,8 +328,7 @@ jobs:
327
328
  git config user.email "jedi[bot]@users.noreply.github.com"
328
329
 
329
330
  if [ -n "$LEARNINGS_REPO" ]; then
330
- # ── External repo: clone, copy learnings, push ──
331
- REPO_SUBDIR="${{ github.repository }}"
331
+ # ── External repo: clone, merge learnings, push ──
332
332
  TMPDIR=$(mktemp -d)
333
333
 
334
334
  git clone --depth 1 \
@@ -338,13 +338,33 @@ jobs:
338
338
  exit 0
339
339
  }
340
340
 
341
- mkdir -p "$TMPDIR/$REPO_SUBDIR"
342
- cp "$LEARNINGS_SRC"/*.md "$TMPDIR/$REPO_SUBDIR/"
341
+ mkdir -p "$TMPDIR/$REMOTE_SUBDIR"
342
+
343
+ # Merge learnings: append new lines from local that don't exist in remote
344
+ for f in "$LEARNINGS_SRC"/*.md; do
345
+ [ -f "$f" ] || continue
346
+ BASENAME=$(basename "$f")
347
+ REMOTE_FILE="$TMPDIR/$REMOTE_SUBDIR/$BASENAME"
348
+
349
+ if [ -f "$REMOTE_FILE" ]; then
350
+ # Append lines from local that aren't already in the remote file
351
+ while IFS= read -r line; do
352
+ [ -z "$line" ] && continue
353
+ if ! grep -qFx "$line" "$REMOTE_FILE" 2>/dev/null; then
354
+ echo "$line" >> "$REMOTE_FILE"
355
+ fi
356
+ done < "$f"
357
+ echo "Merged learning: $BASENAME"
358
+ else
359
+ cp "$f" "$REMOTE_FILE"
360
+ echo "Added new learning: $BASENAME"
361
+ fi
362
+ done
343
363
 
344
364
  cd "$TMPDIR"
345
365
  git config user.name "jedi[bot]"
346
366
  git config user.email "jedi[bot]@users.noreply.github.com"
347
- git add "$REPO_SUBDIR"/*.md
367
+ git add "$REMOTE_SUBDIR"/*.md
348
368
 
349
369
  if git diff --cached --quiet; then
350
370
  echo "Learnings unchanged in external repo — nothing to commit"
@@ -354,7 +374,7 @@ jobs:
354
374
  Source: PR #${{ steps.check.outputs.pr_number }} on ${{ github.repository }}
355
375
  Learnings accumulated from PR reviews and feedback."
356
376
  git push
357
- echo "Learnings committed to ${LEARNINGS_REPO}/${REPO_SUBDIR}"
377
+ echo "Learnings committed to ${LEARNINGS_REPO}/$REMOTE_SUBDIR"
358
378
  fi
359
379
 
360
380
  cd - > /dev/null
package/dist/index.js CHANGED
@@ -11593,6 +11593,9 @@ function parseComment(comment, isFollowUp) {
11593
11593
  const description = body.replace(/(https?:\/\/[^\s]*clickup\.com\/t\/[a-z0-9]+)/i, "").replace(/\s+/g, " ").trim();
11594
11594
  const lower = body.toLowerCase();
11595
11595
  const base = { clickUpUrl, fullFlow: false, isFeedback: false, isApproval: false, dryRun: hasDryRun };
11596
+ if (/\b(approved?|lgtm|looks?\s*good|ship\s*it)\b/i.test(lower)) {
11597
+ return { ...base, command: "plan", description: body, clickUpUrl: null, isFeedback: true, isApproval: true };
11598
+ }
11596
11599
  if (lower.startsWith("ping") || lower.startsWith("status")) {
11597
11600
  return { ...base, command: "ping", description: "", clickUpUrl: null };
11598
11601
  }
@@ -11617,9 +11620,6 @@ function parseComment(comment, isFollowUp) {
11617
11620
  }
11618
11621
  return { ...base, command: "quick", description };
11619
11622
  }
11620
- if (/\b(approved?|lgtm|looks?\s*good|ship\s*it)\b/i.test(lower)) {
11621
- return { ...base, command: "plan", description: body, clickUpUrl: null, isFeedback: true, isApproval: true };
11622
- }
11623
11623
  if (isFollowUp) {
11624
11624
  return { ...base, command: "plan", description: body, clickUpUrl: null, isFeedback: true };
11625
11625
  }
@@ -12294,7 +12294,7 @@ var stateCommand = defineCommand({
12294
12294
  // package.json
12295
12295
  var package_default = {
12296
12296
  name: "@benzotti/jedi",
12297
- version: "0.1.36",
12297
+ version: "0.1.38",
12298
12298
  description: "JDI - Context-efficient AI development framework for Claude Code",
12299
12299
  type: "module",
12300
12300
  bin: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@benzotti/jedi",
3
- "version": "0.1.36",
3
+ "version": "0.1.38",
4
4
  "description": "JDI - Context-efficient AI development framework for Claude Code",
5
5
  "type": "module",
6
6
  "bin": {