specrails-core 4.10.0 → 4.10.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "specrails-core",
3
- "version": "4.10.0",
3
+ "version": "4.10.1",
4
4
  "description": "AI agent workflow system for Claude Code — installs 12 specialized agents, orchestration commands, and persona-driven product discovery into any repository",
5
5
  "type": "module",
6
6
  "bin": {
@@ -6,9 +6,9 @@ Full OpenSpec lifecycle with specialized agents: architect designs, developer im
6
6
 
7
7
  **Input:** $ARGUMENTS — accepts three modes:
8
8
 
9
- 1. **Issue numbers** (recommended): `#85, #71, #63` — implement these specific GitHub Issues directly. Skips exploration and selection.
9
+ 1. **Ticket numbers** (recommended): `#85, #71, #63` — implement these specific tickets from the local backlog (`local-tickets.json`). Skips exploration and selection.
10
10
  2. **Text description** (single feature): `"add price history chart"` — implement a single feature from a description. Skips exploration and selection.
11
- 3. **Area names** (fallback): `Analytics, UI, Testing` — explores areas and picks the best items. Only use if no backlog issues exist.
11
+ 3. **Area names** (fallback): `Analytics, UI, Testing` — explores areas and picks the best items. Only use if no backlog tickets exist.
12
12
 
13
13
  **IMPORTANT:** Before running, ensure Read/Write/Bash/Glob/Grep permissions are set to "allow" — background agents cannot request permissions interactively.
14
14
 
@@ -21,7 +21,7 @@ Your working directory may NOT be the user's source repository. **Repo-resident*
21
21
  Rules used throughout this pipeline:
22
22
  - **openspec reads/writes** → `${SPECRAILS_REPO_DIR:-.}/openspec/...`
23
23
  - **git commands** → `git -C "${SPECRAILS_REPO_DIR:-.}" ...`
24
- - **`gh` commands** (issue/PR — they need the repo's remote) → run them from the repo: `(cd "${SPECRAILS_REPO_DIR:-.}" && gh ...)`
24
+ - **`gh` commands** (PR — they need the repo's remote) → run them from the repo: `(cd "${SPECRAILS_REPO_DIR:-.}" && gh ...)`
25
25
  - **worktree merge-back** → the merge *target* side (the main working tree) is `${SPECRAILS_REPO_DIR:-.}/<file>`
26
26
 
27
27
  **Run-state stays with the working directory** (NOT the repo): `.claude/pipeline-state/`, `.claude/agent-memory/`, `.claude/backlog-cache.json`, and the dry-run cache `.claude/.dry-run/` are all written relative to the current directory. **Profile/agent files** (`.claude/agents/sr-*.md`) are likewise resolved relative to the current directory — do NOT prefix them with `${SPECRAILS_REPO_DIR:-.}`.
@@ -40,22 +40,13 @@ Check the environment variable `CLAUDE_CODE_ENTRYPOINT`. If it contains `remote_
40
40
 
41
41
  #### 1. Backlog provider availability
42
42
 
43
- Read `.specrails/backlog-config.json` and extract `BACKLOG_PROVIDER`.
44
-
45
- **If `BACKLOG_PROVIDER=local`:**
46
43
  ```bash
47
44
  [[ -f ".specrails/local-tickets.json" ]] && echo "Local tickets storage: OK" || echo "WARNING: local-tickets.json not found"
48
45
  ```
49
46
  - Set `LOCAL_TICKETS_AVAILABLE=true/false` based on file existence.
50
- - Set `GH_AVAILABLE=false` (GitHub CLI not needed for local provider).
47
+ - Set `GH_AVAILABLE=false` (backlog is always local).
51
48
  - Set `BACKLOG_AVAILABLE=true` if local-tickets.json exists.
52
49
 
53
- **Otherwise:**
54
- ```bash
55
- gh auth status 2>&1
56
- ```
57
- - Set `GH_AVAILABLE=true/false` for later phases.
58
-
59
50
  #### 2. OpenSpec CLI
60
51
 
61
52
  ```bash
@@ -312,13 +303,10 @@ Initialize conflict-tracking variables:
312
303
  - Set `SINGLE_MODE = true`. No worktrees, no parallelism.
313
304
  - **Skip Phase 1 and Phase 2** — go directly to Phase 3a.
314
305
 
315
- **If the user passed issue/ticket references** (e.g. `#85, #71` for GitHub, `#1, #2` for local tickets, or `PROJ-85, PROJ-71` for JIRA):
316
- - Fetch each issue/ticket:
317
- ```bash
318
- {{BACKLOG_VIEW_CMD}}
319
- ```
320
- - Extract area, value, effort, and feature details from each issue body.
321
- - If only 1 issue: set `SINGLE_MODE = true`.
306
+ **If the user passed ticket references** (e.g. `#85, #71` or `#1, #2`):
307
+ - Fetch each ticket from `.specrails/local-tickets.json` at `tickets["{id}"]`.
308
+ - Extract area, value, effort, and feature details from each ticket body.
309
+ - If only 1 ticket: set `SINGLE_MODE = true`.
322
310
  - **Skip Phase 1 and Phase 2** — go directly to confirmation table.
323
311
 
324
312
  #### Phase 0 snapshot capture
@@ -362,48 +350,7 @@ If the write succeeds: set `SNAPSHOTS_CAPTURED=true`.
362
350
 
363
351
  If the write fails: print `[backlog-cache] Warning: could not write cache. Conflict detection disabled for this run.` and set `SNAPSHOTS_CAPTURED=false`. Do NOT abort the pipeline.
364
352
 
365
- ##### If `GH_AVAILABLE=true` and input mode was issue numbers (GitHub/JIRA):
366
-
367
- For each resolved issue number, run:
368
-
369
- ```bash
370
- (cd "${SPECRAILS_REPO_DIR:-.}" && gh issue view {number} --json number,title,state,assignees,labels,body,updatedAt)
371
- ```
372
-
373
- Build a snapshot object for each issue:
374
- - `number`: integer issue number
375
- - `title`: issue title string
376
- - `state`: `"open"` or `"closed"`
377
- - `assignees`: array of assignee login names, sorted alphabetically
378
- - `labels`: array of label names, sorted alphabetically
379
- - `body_sha`: SHA-256 of the raw body string — compute with:
380
- ```bash
381
- echo -n "{body}" | sha256sum | cut -d' ' -f1
382
- ```
383
- If `sha256sum` is not available, fall back to `openssl dgst -sha256 -r` or `shasum -a 256`.
384
- - `updated_at`: the `updatedAt` value from the GitHub API response
385
- - `captured_at`: current local time in ISO 8601 format
386
-
387
- Write the following JSON to `.claude/backlog-cache.json` (overwrite fully — this establishes a fresh baseline for this run):
388
-
389
- ```json
390
- {
391
- "schema_version": "1",
392
- "provider": "github",
393
- "last_updated": "<ISO 8601 timestamp>",
394
- "written_by": "implement",
395
- "issues": {
396
- "<number>": { <snapshot object> },
397
- ...
398
- }
399
- }
400
- ```
401
-
402
- If the write succeeds: set `SNAPSHOTS_CAPTURED=true`.
403
-
404
- If the write fails (e.g., `.claude/` directory does not exist): print `[backlog-cache] Warning: could not write cache. Conflict detection disabled for this run.` and set `SNAPSHOTS_CAPTURED=false`. Do NOT abort the pipeline.
405
-
406
- ##### Otherwise (no backlog available or non-issue input):
353
+ ##### Otherwise (no backlog available or non-ticket input):
407
354
 
408
355
  Set `SNAPSHOTS_CAPTURED=false`. Print: `[conflict-check] Snapshot skipped — backlog unavailable or non-issue input.`
409
356
 
@@ -509,19 +456,9 @@ Pick the single idea with the best impact/effort ratio from each exploration. Pr
509
456
 
510
457
  **Guard:** If `SNAPSHOTS_CAPTURED=false` OR `DRY_RUN=true`, print `[conflict-check] Skipped — SNAPSHOTS_CAPTURED=false (or dry-run mode).` and proceed directly to Phase 3a.
511
458
 
512
- Otherwise, re-fetch each issue in scope and diff against the Phase 0 snapshot:
513
-
514
- **If `BACKLOG_PROVIDER=local`:** For each ticket ID in `ISSUE_REFS`, read `.specrails/local-tickets.json` and extract the ticket at `tickets["{id}"]`. If the ticket does not exist (deleted): treat as a CRITICAL conflict — field `"state"`, was `<cached state>`, now `"deleted"`. Otherwise, reconstruct a current snapshot using the same mapping as the Phase 0 local snapshot.
515
-
516
- **If `BACKLOG_PROVIDER=github`:** For each issue number in `ISSUE_REFS`:
517
-
518
- ```bash
519
- (cd "${SPECRAILS_REPO_DIR:-.}" && gh issue view {number} --json number,title,state,assignees,labels,body,updatedAt)
520
- ```
521
-
522
- If the `gh` command returns non-zero (issue deleted or inaccessible): treat as a CRITICAL conflict — field `"state"`, was `<cached state>`, now `"deleted"`.
459
+ Otherwise, re-fetch each ticket in scope and diff against the Phase 0 snapshot:
523
460
 
524
- In both cases, reconstruct a current snapshot (same shape as Phase 0: sort `assignees` and `labels`, compute `body_sha`).
461
+ For each ticket ID in `ISSUE_REFS`, read `.specrails/local-tickets.json` and extract the ticket at `tickets["{id}"]`. If the ticket does not exist (deleted): treat as a CRITICAL conflict — field `"state"`, was `<cached state>`, now `"deleted"`. Otherwise, reconstruct a current snapshot using the same mapping as the Phase 0 local snapshot (sort `assignees` and `labels`, compute `body_sha`).
525
462
 
526
463
  **Short-circuit:** If `current.updatedAt == cached.updated_at`, mark the issue as clean and skip field comparison.
527
464
 
@@ -1223,14 +1160,9 @@ When `DRY_RUN=true`, the reviewer still writes `confidence-score.json` (it is an
1223
1160
 
1224
1161
  This check is independent of Phase 3a.0. Even if the user chose to continue through a conflict at Phase 3a.0, this gate re-checks all in-scope issues against the Phase 0 snapshot. It is the final gate before any code reaches git.
1225
1162
 
1226
- Re-fetch each issue in `ISSUE_REFS` and diff against `.claude/backlog-cache.json` using the same algorithm as Phase 3a.0:
1227
-
1228
- **If `BACKLOG_PROVIDER=local`:** Read `.specrails/local-tickets.json` and extract each ticket by ID.
1163
+ Re-fetch each ticket in `ISSUE_REFS` and diff against `.claude/backlog-cache.json` using the same algorithm as Phase 3a.0:
1229
1164
 
1230
- **If `BACKLOG_PROVIDER=github`:**
1231
- ```bash
1232
- (cd "${SPECRAILS_REPO_DIR:-.}" && gh issue view {number} --json number,title,state,assignees,labels,body,updatedAt)
1233
- ```
1165
+ Read `.specrails/local-tickets.json` and extract each ticket by ID.
1234
1166
 
1235
1167
  If the cache file is missing or malformed JSON at this point: log `[conflict-check] Warning: cache file missing or unreadable. Skipping diff for this run.` and proceed to Phase 4c (treat as clean).
1236
1168
 
@@ -1264,9 +1196,6 @@ Record skipped operations to `.cache-manifest.json` under `skipped_operations`:
1264
1196
  - If `BACKLOG_PROVIDER=local` and `BACKLOG_WRITE=true`:
1265
1197
  - `"local: ticket comment #{id}"` for each ticket in scope
1266
1198
  - `"local: ticket status update #{id}"` for each fully resolved ticket
1267
- - If `BACKLOG_PROVIDER=github` and `BACKLOG_WRITE=true`:
1268
- - `"github: issue comment #N"` for each issue in scope
1269
- - `"github: issue close #N (via PR merge)"` for each fully resolved issue
1270
1199
 
1271
1200
  Then skip the rest of Phase 4c and proceed directly to Phase 4e.
1272
1201
 
@@ -1324,15 +1253,12 @@ All implementation is complete and CI checks pass.
1324
1253
  ```bash
1325
1254
  {{BACKLOG_COMMENT_CMD}}
1326
1255
  ```
1327
- - **Local:** Update the ticket status to `"done"` using `{{BACKLOG_UPDATE_CMD}}` and add a comment: `"Implemented in PR #XX. All acceptance criteria met."` via `{{BACKLOG_COMMENT_CMD}}`. Local tickets are closed directly there is no auto-close-on-merge mechanism.
1328
- - **GitHub:** `(cd "${SPECRAILS_REPO_DIR:-.}" && gh issue comment {number} --body "Implemented in PR #XX. All acceptance criteria met.")` — do NOT close the issue explicitly. Use `Closes #N` in the PR body so GitHub auto-closes on merge.
1329
- - **JIRA:** `jira issue comment {key} --message "Implemented in PR #XX. All acceptance criteria met."`
1330
- - For GitHub/JIRA: ensure the PR body includes `Closes #N` for each fully resolved issue (auto-closes on merge)
1256
+ - Update the ticket status to `"done"` using `{{BACKLOG_UPDATE_CMD}}` and add a comment: `"Implemented in PR #XX. All acceptance criteria met."` via `{{BACKLOG_COMMENT_CMD}}`. Tickets are closed directly in `local-tickets.json`.
1331
1257
  - For partially resolved issues/tickets: add a comment noting progress:
1332
1258
  ```bash
1333
1259
  {{BACKLOG_PARTIAL_COMMENT_CMD}}
1334
1260
  ```
1335
- - **Local:** Additionally update the ticket status to `"in_progress"` via `{{BACKLOG_UPDATE_CMD}}` if it is still `"todo"`.
1261
+ - Additionally update the ticket status to `"in_progress"` via `{{BACKLOG_UPDATE_CMD}}` if it is still `"todo"`.
1336
1262
 
1337
1263
  **If `BACKLOG_WRITE=false`:**
1338
1264
  - Do NOT create, modify, or comment on any issues/tickets.
@@ -1343,8 +1269,8 @@ All implementation is complete and CI checks pass.
1343
1269
  The following tickets should be updated:
1344
1270
  | Ticket | Status | Suggested Action |
1345
1271
  |--------|--------|-----------------|
1346
- | #85 / PROJ-85 | Fully implemented | Close / move to Done |
1347
- | #71 / PROJ-71 | Partial progress | Comment: "X completed, Y remaining" |
1272
+ | #85 | Fully implemented | Mark as Done in local-tickets.json |
1273
+ | #71 | Partial progress | Update to "in_progress": "X completed, Y remaining" |
1348
1274
  ```
1349
1275
 
1350
1276
  **Pipeline state:** update `ship` → `done` if git operations and PR creation succeeded, or `failed` with error context describing which step failed (e.g. `"git push failed: <exit code>"`, `"gh pr create failed"`, `"security gate blocked ship"`). If `DRY_RUN=true`: update `ship` → `skipped`.