@pennyfarthing/core 6.6.1 → 7.0.1

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # Pennyfarthing
2
2
 
3
- **v6.5.0** | *The outer loop goes once, the inner loop goes many times.*
3
+ **v7.0.0** | *The outer loop goes once, the inner loop goes many times.*
4
4
 
5
5
  <img src="pennyfarthing.png" alt="Pennyfarthing Logo" width="75" style="float:left; margin:10px" margin="10px">
6
6
 
@@ -30,7 +30,7 @@ Explore all themes with OCEAN spider charts, Chernoff faces, and 1020 character
30
30
  cd your-project
31
31
 
32
32
  # Install CLI (1.1 MB)
33
- npm install --save-dev pennyfarthing
33
+ npm install --save-dev @pennyfarthing/core
34
34
 
35
35
  # Initialize (creates symlinks, no file copying)
36
36
  npx pennyfarthing init
@@ -147,11 +147,8 @@ After initialization:
147
147
  ```
148
148
  your-project/
149
149
  ├── .claude/
150
- │ ├── agents/ # → symlink to node_modules/pennyfarthing/pennyfarthing-dist/agents/
151
- │ ├── commands/ # → symlink to node_modules/pennyfarthing/pennyfarthing-dist/commands/
152
- │ ├── skills/ # → symlink to node_modules/pennyfarthing/pennyfarthing-dist/skills/
153
- │ ├── personas/ # → symlink to node_modules/pennyfarthing/pennyfarthing-dist/personas/
154
- │ ├── scripts/ # → symlink to node_modules/pennyfarthing/pennyfarthing-dist/scripts/
150
+ │ ├── commands/ # → symlinks to @pennyfarthing/core commands
151
+ │ ├── skills/ # → symlinks to @pennyfarthing/core skills
155
152
  │ ├── project/ # YOUR customizations
156
153
  │ │ ├── agents/*-sidecar/ # Agent memory/learnings
157
154
  │ │ ├── docs/ # shared-context.md
@@ -159,6 +156,11 @@ your-project/
159
156
  │ ├── manifest.json # Installation manifest
160
157
  │ └── settings.local.json # Claude Code settings
161
158
  ├── .pennyfarthing/
159
+ │ ├── agents/ # → symlink to @pennyfarthing/core agents
160
+ │ ├── guides/ # → symlink to @pennyfarthing/core guides
161
+ │ ├── personas/ # → symlink to @pennyfarthing/core personas
162
+ │ ├── scripts/ # → symlink to @pennyfarthing/core scripts
163
+ │ ├── sidecars/ # Agent learning files
162
164
  │ └── config.local.yaml # Theme selection (gitignored)
163
165
  ├── sprint/
164
166
  │ ├── current-sprint.yaml # Active sprint
@@ -229,7 +231,7 @@ Override locally with `.claude/pennyfarthing/preferences.local.yaml` (gitignored
229
231
 
230
232
  ```bash
231
233
  # Update CLI
232
- npm update pennyfarthing
234
+ npm update @pennyfarthing/core
233
235
 
234
236
  # Update visual terminal (if installed)
235
237
  npm update @pennyfarthing/cyclist
@@ -250,17 +252,23 @@ pennyfarthing uninstall --all
250
252
 
251
253
  Archived sprint data (`sprint/archive/`, `sprint/context/`) is always preserved.
252
254
 
253
- ## What's New in v6.4
255
+ ## What's New in v7.0
254
256
 
255
- - **102 Themes** - 11 new themes added since v6.0
256
- - **20 Skills** - Expanded knowledge domains
257
- - **43 Commands** - More workflow entry points
258
- - **Sprint 10** - Customizable workflows and runtime permissions
257
+ - **BREAKING: Package Renamed** - `pennyfarthing` `@pennyfarthing/core`
258
+ - **BREAKING: Directory Restructure** - Content moved from `.claude/` to `.pennyfarthing/`
259
+ - **Cyclist Split** - Visual terminal is now optional `@pennyfarthing/cyclist` (160MB → 1.1MB core)
260
+ - **Customizable Workflow Engine** - YAML-based workflow definitions with story routing
261
+ - **BMAD Interoperability** - Parse and export BMAD format stories and epics
262
+ - **Runtime Permission Management** - Approval gates, spot grants, `/permissions` skill
263
+ - **Enhanced OTEL** - Tool enrichment for Bash, Read, Edit, Write, Grep/Glob spans
264
+ - **Agent Modernization** - All agents updated with status tags and shared behavior
265
+
266
+ See [CHANGELOG.md](CHANGELOG.md) for full migration guide.
259
267
 
260
268
  ## What's New in v6.5
261
269
 
262
270
  - **Simplified Installation** - Two packages for different needs:
263
- - `pennyfarthing` - CLI only (1.1 MB)
271
+ - `@pennyfarthing/core` - CLI only (1.1 MB)
264
272
  - `@pennyfarthing/cyclist` - Optional visual terminal with portraits (160 MB)
265
273
  - **Portrait Optimization** - Cyclist bundles only 128px and 256px portraits (saves 450MB)
266
274
  - **Agent Modernization** - All agents updated with status tags and consolidated shared behavior
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pennyfarthing/core",
3
- "version": "6.6.1",
3
+ "version": "7.0.1",
4
4
  "description": "Claude Code agent framework with TDD workflow and persona system",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1 +1 @@
1
- {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/version.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAoC1C;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAgBtC"}
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../../src/cli/utils/version.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAqC1C;AAED;;;GAGG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAgBtC"}
@@ -25,7 +25,8 @@ export function getPackageVersion() {
25
25
  }
26
26
  // Fallback to package.json
27
27
  const packagePaths = [
28
- join(__dirname, '../../../package.json'),
28
+ join(__dirname, '../../../../../package.json'), // From packages/core/dist/cli/utils/ in npm install
29
+ join(__dirname, '../../../package.json'), // From dist/cli/utils/ in local dev
29
30
  join(__dirname, '../../package.json')
30
31
  ];
31
32
  for (const packagePath of packagePaths) {
@@ -1 +1 @@
1
- {"version":3,"file":"version.js","sourceRoot":"","sources":["../../../src/cli/utils/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,gEAAgE;IAChE,MAAM,YAAY,GAAG;QACnB,IAAI,CAAC,SAAS,EAAE,kBAAkB,CAAC,EAAG,uBAAuB;QAC7D,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,EAAO,WAAW;QAClD,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,CAAS,+BAA+B;KACvE,CAAC;IAEF,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;QACvC,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC5B,IAAI,CAAC;gBACH,OAAO,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;YAClD,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;QACH,CAAC;IACH,CAAC;IAED,2BAA2B;IAC3B,MAAM,YAAY,GAAG;QACnB,IAAI,CAAC,SAAS,EAAE,uBAAuB,CAAC;QACxC,IAAI,CAAC,SAAS,EAAE,oBAAoB,CAAC;KACtC,CAAC;IAEF,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;QACvC,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC5B,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC;gBAC1D,OAAO,GAAG,CAAC,OAAO,CAAC;YACrB,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,WAAW,GAAG;QAClB,IAAI,CAAC,SAAS,EAAE,mCAAmC,CAAC,EAAG,qDAAqD;QAC5G,IAAI,CAAC,SAAS,EAAE,gCAAgC,CAAC;QACjD,IAAI,CAAC,SAAS,EAAE,6BAA6B,CAAC;QAC9C,IAAI,CAAC,SAAS,EAAE,0BAA0B,CAAC;QAC3C,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,oBAAoB,CAAC;KAC1C,CAAC;IAEF,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACrC,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC3B,OAAO,UAAU,CAAC;QACpB,CAAC;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;AAClF,CAAC"}
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../../src/cli/utils/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,gEAAgE;IAChE,MAAM,YAAY,GAAG;QACnB,IAAI,CAAC,SAAS,EAAE,kBAAkB,CAAC,EAAG,uBAAuB;QAC7D,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,EAAO,WAAW;QAClD,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,CAAS,+BAA+B;KACvE,CAAC;IAEF,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;QACvC,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC5B,IAAI,CAAC;gBACH,OAAO,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;YAClD,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;QACH,CAAC;IACH,CAAC;IAED,2BAA2B;IAC3B,MAAM,YAAY,GAAG;QACnB,IAAI,CAAC,SAAS,EAAE,6BAA6B,CAAC,EAAG,oDAAoD;QACrG,IAAI,CAAC,SAAS,EAAE,uBAAuB,CAAC,EAAS,oCAAoC;QACrF,IAAI,CAAC,SAAS,EAAE,oBAAoB,CAAC;KACtC,CAAC;IAEF,KAAK,MAAM,WAAW,IAAI,YAAY,EAAE,CAAC;QACvC,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC5B,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC;gBAC1D,OAAO,GAAG,CAAC,OAAO,CAAC;YACrB,CAAC;YAAC,MAAM,CAAC;gBACP,SAAS;YACX,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,WAAW,GAAG;QAClB,IAAI,CAAC,SAAS,EAAE,mCAAmC,CAAC,EAAG,qDAAqD;QAC5G,IAAI,CAAC,SAAS,EAAE,gCAAgC,CAAC;QACjD,IAAI,CAAC,SAAS,EAAE,6BAA6B,CAAC;QAC9C,IAAI,CAAC,SAAS,EAAE,0BAA0B,CAAC;QAC3C,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,oBAAoB,CAAC;KAC1C,CAAC;IAEF,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACrC,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC3B,OAAO,UAAU,CAAC;QACpB,CAAC;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAC;AAClF,CAAC"}
@@ -9,7 +9,7 @@ Loaded automatically by `/prime --agent <name>` on agent activation.
9
9
  ## Project Info
10
10
 
11
11
  **Project:** Pennyfarthing - Claude Code agent orchestration framework
12
- **Version:** 6.3.0
12
+ **Version:** 7.0.0
13
13
  **Type:** ES module with TypeScript (pnpm monorepo)
14
14
  **Node:** >=18.0.0
15
15
 
@@ -119,19 +119,64 @@ echo ""
119
119
  echo "Checking symlinks..."
120
120
  echo ""
121
121
 
122
- # Check .claude/pennyfarthing symlink
123
- if [[ -L ".claude/pennyfarthing" ]]; then
124
- TARGET=$(readlink ".claude/pennyfarthing")
125
- if [[ "$TARGET" == "../pennyfarthing-dist" ]]; then
126
- ok ".claude/pennyfarthing -> ../pennyfarthing-dist"
122
+ # Check .pennyfarthing/ symlinks (new structure)
123
+ PENNYFARTHING_SYMLINKS=("agents" "guides" "personas" "scripts")
124
+ for item in "${PENNYFARTHING_SYMLINKS[@]}"; do
125
+ link_path=".pennyfarthing/$item"
126
+ expected_target="../pennyfarthing-dist/$item"
127
+
128
+ if [[ -L "$link_path" ]]; then
129
+ actual_target=$(readlink "$link_path")
130
+ if [[ "$actual_target" == "$expected_target" ]]; then
131
+ ok ".pennyfarthing/$item -> $expected_target"
132
+ else
133
+ warn ".pennyfarthing/$item points to: $actual_target (expected $expected_target)"
134
+ fi
135
+ elif [[ -d "$link_path" ]]; then
136
+ fail ".pennyfarthing/$item is a directory, should be symlink"
137
+ if $FIX_MODE; then
138
+ rm -rf "$link_path"
139
+ ln -s "$expected_target" "$link_path"
140
+ fix ".pennyfarthing/$item symlink created"
141
+ fi
127
142
  else
128
- fail ".claude/pennyfarthing points to wrong target: $TARGET"
143
+ fail ".pennyfarthing/$item missing"
144
+ if $FIX_MODE; then
145
+ mkdir -p .pennyfarthing
146
+ ln -s "$expected_target" "$link_path"
147
+ fix ".pennyfarthing/$item symlink created"
148
+ fi
129
149
  fi
130
- elif [[ -d ".claude/pennyfarthing" ]]; then
131
- fail ".claude/pennyfarthing is a directory, should be symlink"
132
- else
133
- fail ".claude/pennyfarthing missing"
134
- fi
150
+ done
151
+
152
+ # Check .claude/ symlinks (commands and skills only)
153
+ CLAUDE_SYMLINKS=("commands" "skills")
154
+ for item in "${CLAUDE_SYMLINKS[@]}"; do
155
+ link_path=".claude/$item"
156
+ expected_target="../pennyfarthing-dist/$item"
157
+
158
+ if [[ -L "$link_path" ]]; then
159
+ actual_target=$(readlink "$link_path")
160
+ if [[ "$actual_target" == "$expected_target" ]]; then
161
+ ok ".claude/$item -> $expected_target"
162
+ else
163
+ warn ".claude/$item points to: $actual_target (expected $expected_target)"
164
+ fi
165
+ elif [[ -d "$link_path" ]]; then
166
+ warn ".claude/$item is a directory, should be symlink to pennyfarthing-dist/$item"
167
+ if $FIX_MODE; then
168
+ rm -rf "$link_path"
169
+ ln -s "$expected_target" "$link_path"
170
+ fix ".claude/$item symlink created"
171
+ fi
172
+ else
173
+ fail ".claude/$item missing"
174
+ if $FIX_MODE; then
175
+ ln -s "$expected_target" "$link_path"
176
+ fix ".claude/$item symlink created"
177
+ fi
178
+ fi
179
+ done
135
180
 
136
181
  # Check scripts directory/symlink
137
182
  if [[ -L "scripts" ]]; then
@@ -194,14 +239,15 @@ echo ""
194
239
  echo "Checking build..."
195
240
  echo ""
196
241
 
197
- # Check if dist/ is up to date
198
- if [[ -d "dist" ]]; then
242
+ # Check if packages/core/dist/ is up to date (monorepo structure)
243
+ CORE_DIST="packages/core/dist"
244
+ if [[ -d "$CORE_DIST" ]]; then
199
245
  # Check if any src file is newer than its dist counterpart
200
246
  OUTDATED=false
201
- for src_file in src/cli/commands/*.ts; do
247
+ for src_file in packages/core/src/cli/commands/*.ts; do
202
248
  if [[ -f "$src_file" ]]; then
203
249
  base=$(basename "$src_file" .ts)
204
- dist_file="dist/cli/commands/${base}.js"
250
+ dist_file="${CORE_DIST}/cli/commands/${base}.js"
205
251
  if [[ -f "$dist_file" ]]; then
206
252
  if [[ "$src_file" -nt "$dist_file" ]]; then
207
253
  OUTDATED=true
@@ -212,19 +258,19 @@ if [[ -d "dist" ]]; then
212
258
  done
213
259
 
214
260
  if $OUTDATED; then
215
- warn "dist/ may be outdated (run: npm run build)"
261
+ warn "packages/core/dist/ may be outdated (run: npm run build)"
216
262
  if $FIX_MODE; then
217
263
  npm run build >/dev/null 2>&1
218
- fix "Rebuilt dist/"
264
+ fix "Rebuilt packages"
219
265
  fi
220
266
  else
221
- ok "dist/ appears up to date"
267
+ ok "packages/core/dist/ appears up to date"
222
268
  fi
223
269
  else
224
- fail "dist/ directory missing"
270
+ fail "packages/core/dist/ missing"
225
271
  if $FIX_MODE; then
226
272
  npm run build >/dev/null 2>&1
227
- fix "Built dist/"
273
+ fix "Built packages"
228
274
  fi
229
275
  fi
230
276
 
@@ -260,30 +306,19 @@ echo ""
260
306
  echo "Checking file locations..."
261
307
  echo ""
262
308
 
263
- # Check for files that should be in pennyfarthing-dist but aren't
264
- # Only check directories that are NOT symlinks (symlink dirs are fine)
265
- MISPLACED=0
266
-
267
- # .claude/agents should be a symlink, not a real directory with files
268
- if [[ -d ".claude/agents" ]] && [[ ! -L ".claude/agents" ]]; then
269
- warn ".pennyfarthing/agents/ is a directory, should be symlink to pennyfarthing/agents"
270
- ((MISPLACED++))
271
- fi
272
-
273
- # .claude/commands should be a symlink
274
- if [[ -d ".claude/commands" ]] && [[ ! -L ".claude/commands" ]]; then
275
- warn ".claude/commands/ is a directory, should be symlink to pennyfarthing/commands"
276
- ((MISPLACED++))
277
- fi
278
-
279
- # .claude/skills should be a symlink
280
- if [[ -d ".claude/skills" ]] && [[ ! -L ".claude/skills" ]]; then
281
- warn ".claude/skills/ is a directory, should be symlink to pennyfarthing/skills"
282
- ((MISPLACED++))
309
+ # Check .pennyfarthing/sidecars exists (user-specific, not symlinked)
310
+ if [[ -d ".pennyfarthing/sidecars" ]]; then
311
+ SIDECAR_COUNT=$(find .pennyfarthing/sidecars -mindepth 1 -maxdepth 1 -type d 2>/dev/null | wc -l | tr -d ' ')
312
+ ok ".pennyfarthing/sidecars/ exists ($SIDECAR_COUNT agent sidecars)"
313
+ else
314
+ warn ".pennyfarthing/sidecars/ missing (agent learning files)"
283
315
  fi
284
316
 
285
- if [[ $MISPLACED -eq 0 ]]; then
286
- ok "All .claude/ directories properly symlinked"
317
+ # Check .claude/project exists (project-specific customizations)
318
+ if [[ -d ".claude/project" ]]; then
319
+ ok ".claude/project/ exists"
320
+ else
321
+ warn ".claude/project/ missing"
287
322
  fi
288
323
 
289
324
  echo ""