spets 0.1.9 → 0.1.10
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/dist/index.js +140 -31
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -323,7 +323,13 @@ jobs:
|
|
|
323
323
|
- name: Checkout
|
|
324
324
|
uses: actions/checkout@v4
|
|
325
325
|
with:
|
|
326
|
-
fetch-depth:
|
|
326
|
+
fetch-depth: 1
|
|
327
|
+
persist-credentials: false
|
|
328
|
+
|
|
329
|
+
- name: Setup Git
|
|
330
|
+
run: |
|
|
331
|
+
git config user.name "github-actions[bot]"
|
|
332
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
327
333
|
|
|
328
334
|
- name: Parse Issue body
|
|
329
335
|
id: parse
|
|
@@ -344,17 +350,33 @@ jobs:
|
|
|
344
350
|
|
|
345
351
|
- name: Create and checkout branch
|
|
346
352
|
run: |
|
|
353
|
+
git remote set-url origin https://x-access-token:${gh("secrets.PAT_TOKEN")}@github.com/${gh("github.repository")}.git
|
|
347
354
|
git checkout -b ${gh("steps.parse.outputs.branch")}
|
|
348
355
|
git push -u origin ${gh("steps.parse.outputs.branch")}
|
|
349
|
-
env:
|
|
350
|
-
GH_TOKEN: ${gh("secrets.GITHUB_TOKEN")}
|
|
351
356
|
|
|
352
357
|
- name: Setup Node.js
|
|
353
358
|
uses: actions/setup-node@v4
|
|
354
359
|
with:
|
|
355
360
|
node-version: '20'
|
|
361
|
+
cache: 'npm'
|
|
362
|
+
|
|
363
|
+
- name: Cache global npm packages
|
|
364
|
+
uses: actions/cache@v4
|
|
365
|
+
with:
|
|
366
|
+
path: ~/.npm
|
|
367
|
+
key: ${gh("runner.os")}-npm-global-${gh("hashFiles('package-lock.json')")}
|
|
368
|
+
restore-keys: |
|
|
369
|
+
${gh("runner.os")}-npm-global-
|
|
370
|
+
|
|
371
|
+
- name: Cache Claude Code
|
|
372
|
+
id: cache-claude
|
|
373
|
+
uses: actions/cache@v4
|
|
374
|
+
with:
|
|
375
|
+
path: /usr/local/lib/node_modules/@anthropic-ai/claude-code
|
|
376
|
+
key: claude-code-${gh("runner.os")}-v1
|
|
356
377
|
|
|
357
378
|
- name: Install Claude Code
|
|
379
|
+
if: steps.cache-claude.outputs.cache-hit != 'true'
|
|
358
380
|
run: npm install -g @anthropic-ai/claude-code
|
|
359
381
|
|
|
360
382
|
- name: Install dependencies
|
|
@@ -370,13 +392,10 @@ jobs:
|
|
|
370
392
|
|
|
371
393
|
- name: Push changes
|
|
372
394
|
run: |
|
|
373
|
-
git
|
|
374
|
-
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
395
|
+
git remote set-url origin https://x-access-token:${gh("secrets.PAT_TOKEN")}@github.com/${gh("github.repository")}.git
|
|
375
396
|
git add -A
|
|
376
397
|
git diff --staged --quiet || git commit -m "Spets: Start workflow for #${gh("github.event.issue.number")}"
|
|
377
398
|
git push
|
|
378
|
-
env:
|
|
379
|
-
GH_TOKEN: ${gh("secrets.GITHUB_TOKEN")}
|
|
380
399
|
|
|
381
400
|
# Handle commands from Issue/PR comments
|
|
382
401
|
handle-command:
|
|
@@ -389,38 +408,108 @@ jobs:
|
|
|
389
408
|
runs-on: ubuntu-latest
|
|
390
409
|
|
|
391
410
|
steps:
|
|
392
|
-
- name: Find
|
|
411
|
+
- name: Find branch from Issue or PR
|
|
393
412
|
id: branch
|
|
413
|
+
env:
|
|
414
|
+
GH_TOKEN: ${gh("secrets.GITHUB_TOKEN")}
|
|
394
415
|
run: |
|
|
395
|
-
#
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
416
|
+
# Check if this is a PR (has pull_request field)
|
|
417
|
+
PR_BRANCH=$(gh api repos/${gh("github.repository")}/issues/${gh("github.event.issue.number")} --jq '.pull_request.url // empty' 2>/dev/null)
|
|
418
|
+
|
|
419
|
+
if [ -n "$PR_BRANCH" ]; then
|
|
420
|
+
# It's a PR - get head branch directly
|
|
421
|
+
BRANCH=$(gh api repos/${gh("github.repository")}/pulls/${gh("github.event.issue.number")} --jq '.head.ref')
|
|
422
|
+
echo "Found PR head branch: $BRANCH"
|
|
423
|
+
else
|
|
424
|
+
# It's an Issue - try to parse branch name from body
|
|
425
|
+
ISSUE_BODY=$(gh api repos/${gh("github.repository")}/issues/${gh("github.event.issue.number")} --jq '.body')
|
|
426
|
+
CUSTOM_BRANCH=$(echo "$ISSUE_BODY" | sed -n '/### Branch Name/,/###/{/###/!p;}' | sed '/^$/d' | head -1)
|
|
427
|
+
|
|
428
|
+
if [ -n "$CUSTOM_BRANCH" ]; then
|
|
429
|
+
BRANCH="$CUSTOM_BRANCH"
|
|
430
|
+
else
|
|
431
|
+
BRANCH="spets/${gh("github.event.issue.number")}"
|
|
432
|
+
fi
|
|
433
|
+
fi
|
|
434
|
+
|
|
435
|
+
echo "Checking for branch: $BRANCH"
|
|
436
|
+
|
|
437
|
+
# Check if branch exists on remote using gh api
|
|
438
|
+
if gh api "repos/${gh("github.repository")}/branches/$BRANCH" --silent 2>/dev/null; then
|
|
439
|
+
echo "name=$BRANCH" >> $GITHUB_OUTPUT
|
|
440
|
+
echo "exists=true" >> $GITHUB_OUTPUT
|
|
441
|
+
echo "Branch $BRANCH found!"
|
|
442
|
+
else
|
|
443
|
+
echo "exists=false" >> $GITHUB_OUTPUT
|
|
444
|
+
echo "expected=$BRANCH" >> $GITHUB_OUTPUT
|
|
445
|
+
echo "::error::Branch $BRANCH not found. Start workflow first by creating an Issue with 'spets' label."
|
|
399
446
|
fi
|
|
400
|
-
|
|
447
|
+
|
|
448
|
+
- name: Post error comment
|
|
449
|
+
if: steps.branch.outputs.exists == 'false'
|
|
450
|
+
run: |
|
|
451
|
+
gh issue comment ${gh("github.event.issue.number")} \\
|
|
452
|
+
-R "${gh("github.repository")}" \\
|
|
453
|
+
--body "\u274C **Spets Error**: Branch \\\`${gh("steps.branch.outputs.expected")}\\\` not found.
|
|
454
|
+
|
|
455
|
+
Please make sure the workflow was started properly. You can:
|
|
456
|
+
1. Add the \\\`spets\\\` label to this issue to trigger the start workflow
|
|
457
|
+
2. Or manually create the branch and run \\\`spets start\\\`"
|
|
401
458
|
env:
|
|
402
459
|
GH_TOKEN: ${gh("secrets.GITHUB_TOKEN")}
|
|
403
460
|
|
|
461
|
+
- name: Exit if branch not found
|
|
462
|
+
if: steps.branch.outputs.exists == 'false'
|
|
463
|
+
run: exit 1
|
|
464
|
+
|
|
404
465
|
- name: Checkout
|
|
405
466
|
uses: actions/checkout@v4
|
|
406
467
|
with:
|
|
407
468
|
ref: ${gh("steps.branch.outputs.name")}
|
|
408
|
-
fetch-depth:
|
|
469
|
+
fetch-depth: 1
|
|
470
|
+
persist-credentials: false
|
|
471
|
+
|
|
472
|
+
- name: Setup Git
|
|
473
|
+
run: |
|
|
474
|
+
git config user.name "github-actions[bot]"
|
|
475
|
+
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
409
476
|
|
|
410
477
|
- name: Setup Node.js
|
|
411
478
|
uses: actions/setup-node@v4
|
|
412
479
|
with:
|
|
413
480
|
node-version: '20'
|
|
481
|
+
cache: 'npm'
|
|
482
|
+
|
|
483
|
+
- name: Cache global npm packages
|
|
484
|
+
uses: actions/cache@v4
|
|
485
|
+
with:
|
|
486
|
+
path: ~/.npm
|
|
487
|
+
key: ${gh("runner.os")}-npm-global-${gh("hashFiles('package-lock.json')")}
|
|
488
|
+
restore-keys: |
|
|
489
|
+
${gh("runner.os")}-npm-global-
|
|
490
|
+
|
|
491
|
+
- name: Cache Claude Code
|
|
492
|
+
id: cache-claude
|
|
493
|
+
uses: actions/cache@v4
|
|
494
|
+
with:
|
|
495
|
+
path: /usr/local/lib/node_modules/@anthropic-ai/claude-code
|
|
496
|
+
key: claude-code-${gh("runner.os")}-v1
|
|
414
497
|
|
|
415
498
|
- name: Install Claude Code
|
|
499
|
+
if: steps.cache-claude.outputs.cache-hit != 'true'
|
|
416
500
|
run: npm install -g @anthropic-ai/claude-code
|
|
417
501
|
|
|
418
502
|
- name: Install dependencies
|
|
419
503
|
run: npm ci
|
|
420
504
|
|
|
421
505
|
- name: Run Spets command
|
|
506
|
+
id: spets
|
|
422
507
|
run: |
|
|
423
508
|
npx spets github --issue ${gh("github.event.issue.number")} --comment "$COMMENT"
|
|
509
|
+
# Check if PR should be created
|
|
510
|
+
if [[ "$COMMENT" == "/approve --pr"* ]]; then
|
|
511
|
+
echo "create_pr=true" >> $GITHUB_OUTPUT
|
|
512
|
+
fi
|
|
424
513
|
env:
|
|
425
514
|
COMMENT: ${gh("github.event.comment.body")}
|
|
426
515
|
CLAUDE_CODE_OAUTH_TOKEN: ${gh("secrets.CLAUDE_CODE_OAUTH_TOKEN")}
|
|
@@ -428,13 +517,33 @@ jobs:
|
|
|
428
517
|
|
|
429
518
|
- name: Push changes
|
|
430
519
|
run: |
|
|
431
|
-
git
|
|
432
|
-
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
520
|
+
git remote set-url origin https://x-access-token:${gh("secrets.PAT_TOKEN")}@github.com/${gh("github.repository")}.git
|
|
433
521
|
git add -A
|
|
434
522
|
git diff --staged --quiet || git commit -m "Spets: Update from #${gh("github.event.issue.number")}"
|
|
435
523
|
git push
|
|
524
|
+
|
|
525
|
+
- name: Create PR
|
|
526
|
+
if: steps.spets.outputs.create_pr == 'true'
|
|
527
|
+
run: |
|
|
528
|
+
PR_BODY="Closes #${gh("github.event.issue.number")}
|
|
529
|
+
|
|
530
|
+
---
|
|
531
|
+
|
|
532
|
+
## Spets Commands
|
|
533
|
+
|
|
534
|
+
| Command | Description |
|
|
535
|
+
|---------|-------------|
|
|
536
|
+
| \\\`/approve\\\` | Approve current step and continue |
|
|
537
|
+
| \\\`/approve --pr\\\` | Approve and create PR |
|
|
538
|
+
| \\\`/revise <feedback>\\\` | Request changes with feedback |
|
|
539
|
+
| \\\`/reject\\\` | Reject and stop workflow |"
|
|
540
|
+
|
|
541
|
+
gh pr create \\
|
|
542
|
+
--title "Spets: Issue #${gh("github.event.issue.number")}" \\
|
|
543
|
+
--body "$PR_BODY" \\
|
|
544
|
+
--repo ${gh("github.repository")}
|
|
436
545
|
env:
|
|
437
|
-
GH_TOKEN: ${gh("secrets.
|
|
546
|
+
GH_TOKEN: ${gh("secrets.PAT_TOKEN")}
|
|
438
547
|
`;
|
|
439
548
|
}
|
|
440
549
|
|
|
@@ -1514,28 +1623,28 @@ function installClaudePlugin() {
|
|
|
1514
1623
|
const claudeDir = join3(homedir(), ".claude");
|
|
1515
1624
|
const commandsDir = join3(claudeDir, "commands");
|
|
1516
1625
|
mkdirSync2(commandsDir, { recursive: true });
|
|
1517
|
-
const skillPath = join3(commandsDir, "
|
|
1626
|
+
const skillPath = join3(commandsDir, "spets.md");
|
|
1518
1627
|
writeFileSync2(skillPath, getClaudeSkillContent());
|
|
1519
1628
|
console.log("Installed Claude Code plugin.");
|
|
1520
1629
|
console.log(`Location: ${skillPath}`);
|
|
1521
1630
|
console.log("");
|
|
1522
1631
|
console.log("Usage in Claude Code:");
|
|
1523
|
-
console.log(' /
|
|
1632
|
+
console.log(' /spets "your task description"');
|
|
1524
1633
|
console.log("");
|
|
1525
1634
|
console.log("This skill runs deterministically within your Claude Code session.");
|
|
1526
1635
|
console.log("No additional Claude processes are spawned.");
|
|
1527
1636
|
}
|
|
1528
1637
|
async function uninstallPlugin(name) {
|
|
1529
1638
|
if (name === "claude") {
|
|
1530
|
-
const
|
|
1531
|
-
const
|
|
1639
|
+
const skillPath = join3(homedir(), ".claude", "commands", "spets.md");
|
|
1640
|
+
const legacySkillPath = join3(homedir(), ".claude", "commands", "sdd-do.md");
|
|
1532
1641
|
let uninstalled = false;
|
|
1533
|
-
if (existsSync3(
|
|
1534
|
-
rmSync(
|
|
1642
|
+
if (existsSync3(skillPath)) {
|
|
1643
|
+
rmSync(skillPath);
|
|
1535
1644
|
uninstalled = true;
|
|
1536
1645
|
}
|
|
1537
|
-
if (existsSync3(
|
|
1538
|
-
rmSync(
|
|
1646
|
+
if (existsSync3(legacySkillPath)) {
|
|
1647
|
+
rmSync(legacySkillPath);
|
|
1539
1648
|
uninstalled = true;
|
|
1540
1649
|
}
|
|
1541
1650
|
if (uninstalled) {
|
|
@@ -1551,11 +1660,11 @@ async function uninstallPlugin(name) {
|
|
|
1551
1660
|
async function listPlugins() {
|
|
1552
1661
|
console.log("Available plugins:");
|
|
1553
1662
|
console.log("");
|
|
1554
|
-
console.log(" claude - Claude Code /
|
|
1663
|
+
console.log(" claude - Claude Code /spets skill");
|
|
1555
1664
|
console.log("");
|
|
1556
|
-
const
|
|
1557
|
-
const
|
|
1558
|
-
const claudeInstalled = existsSync3(
|
|
1665
|
+
const skillPath = join3(homedir(), ".claude", "commands", "spets.md");
|
|
1666
|
+
const legacySkillPath = join3(homedir(), ".claude", "commands", "sdd-do.md");
|
|
1667
|
+
const claudeInstalled = existsSync3(skillPath) || existsSync3(legacySkillPath);
|
|
1559
1668
|
console.log("Installed:");
|
|
1560
1669
|
if (claudeInstalled) {
|
|
1561
1670
|
console.log(" - claude");
|
|
@@ -1564,7 +1673,7 @@ async function listPlugins() {
|
|
|
1564
1673
|
}
|
|
1565
1674
|
}
|
|
1566
1675
|
function getClaudeSkillContent() {
|
|
1567
|
-
return `#
|
|
1676
|
+
return `# Spets - Spec Driven Development
|
|
1568
1677
|
|
|
1569
1678
|
Spec-Driven Development workflow execution skill for Claude Code.
|
|
1570
1679
|
|
|
@@ -1573,7 +1682,7 @@ Spec-Driven Development workflow execution skill for Claude Code.
|
|
|
1573
1682
|
## When to Use This Skill
|
|
1574
1683
|
|
|
1575
1684
|
Automatically invoked when user uses:
|
|
1576
|
-
- \`/
|
|
1685
|
+
- \`/spets\` - Run Spets workflow
|
|
1577
1686
|
|
|
1578
1687
|
---
|
|
1579
1688
|
|