@wipcomputer/wip-release 1.9.11 → 1.9.12

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/cli.js +8 -1
  2. package/core.mjs +101 -0
  3. package/package.json +1 -1
package/cli.js CHANGED
@@ -125,6 +125,12 @@ Release notes (highest priority wins, files ALWAYS beat --notes flag):
125
125
  4. --notes="text" Fallback only (use for repos without release notes files)
126
126
  Written notes on disk always take priority over a CLI one-liner.
127
127
 
128
+ Skill publish to website:
129
+ Add .publish-skill.json to repo root: { "name": "my-tool" }
130
+ Set WIP_WEBSITE_REPO env var to your website repo path.
131
+ After release, SKILL.md is copied to {website}/wip.computer/install/{name}.txt
132
+ and deploy.sh is run to push to VPS.
133
+
128
134
  Pipeline:
129
135
  1. Bump package.json version
130
136
  2. Sync SKILL.md version (if exists)
@@ -133,7 +139,8 @@ Pipeline:
133
139
  5. Push to remote
134
140
  6. npm publish (via 1Password)
135
141
  7. GitHub Packages publish
136
- 8. GitHub release create`);
142
+ 8. GitHub release create
143
+ 9. Publish SKILL.md to website (if configured)`);
137
144
  process.exit(level ? 0 : 1);
138
145
  }
139
146
 
package/core.mjs CHANGED
@@ -458,6 +458,78 @@ export function publishClawHub(repoPath, newVersion, notes) {
458
458
  return true;
459
459
  }
460
460
 
461
+ // ── Skill Publish ────────────────────────────────────────────────────
462
+
463
+ /**
464
+ * Publish SKILL.md to website as plain text.
465
+ *
466
+ * Reads .publish-skill.json from repo root:
467
+ * { "name": "memory-crystal" }
468
+ *
469
+ * Uses WIP_WEBSITE_REPO env var for website repo path.
470
+ * Copies SKILL.md to {website}/wip.computer/install/{name}.txt
471
+ * Then runs deploy.sh to push to VPS.
472
+ *
473
+ * Non-blocking: returns result, never throws.
474
+ */
475
+ export function publishSkillToWebsite(repoPath) {
476
+ const configPath = join(repoPath, '.publish-skill.json');
477
+ if (!existsSync(configPath)) return { skipped: true, reason: 'no .publish-skill.json' };
478
+
479
+ const websiteRepo = process.env.WIP_WEBSITE_REPO;
480
+ if (!websiteRepo) return { skipped: true, reason: 'WIP_WEBSITE_REPO not set' };
481
+
482
+ let config;
483
+ try {
484
+ config = JSON.parse(readFileSync(configPath, 'utf8'));
485
+ } catch (e) {
486
+ return { ok: false, error: `bad .publish-skill.json: ${e.message}` };
487
+ }
488
+
489
+ if (!config.name) return { ok: false, error: '.publish-skill.json missing "name"' };
490
+
491
+ // Find SKILL.md: check root, then skills/*/SKILL.md
492
+ let skillFile = join(repoPath, 'SKILL.md');
493
+ if (!existsSync(skillFile)) {
494
+ const skillsDir = join(repoPath, 'skills');
495
+ if (existsSync(skillsDir)) {
496
+ for (const sub of readdirSync(skillsDir)) {
497
+ const candidate = join(skillsDir, sub, 'SKILL.md');
498
+ if (existsSync(candidate)) { skillFile = candidate; break; }
499
+ }
500
+ }
501
+ }
502
+ if (!existsSync(skillFile)) return { ok: false, error: 'no SKILL.md found' };
503
+
504
+ // Copy to website install dir
505
+ const installDir = join(websiteRepo, 'wip.computer', 'install');
506
+ if (!existsSync(installDir)) {
507
+ try { mkdirSync(installDir, { recursive: true }); } catch {}
508
+ }
509
+
510
+ const targetFile = join(installDir, `${config.name}.txt`);
511
+ try {
512
+ const content = readFileSync(skillFile, 'utf8');
513
+ writeFileSync(targetFile, content);
514
+ } catch (e) {
515
+ return { ok: false, error: `copy failed: ${e.message}` };
516
+ }
517
+
518
+ // Deploy to VPS (non-blocking ... warn on failure)
519
+ const deployScript = join(websiteRepo, 'deploy.sh');
520
+ if (existsSync(deployScript)) {
521
+ try {
522
+ execSync(`bash deploy.sh`, { cwd: websiteRepo, stdio: 'pipe', timeout: 30000 });
523
+ } catch (e) {
524
+ return { ok: true, deployed: false, target: config.name, error: `deploy failed: ${e.message}` };
525
+ }
526
+ } else {
527
+ return { ok: true, deployed: false, target: config.name, error: 'no deploy.sh found' };
528
+ }
529
+
530
+ return { ok: true, deployed: true, target: config.name };
531
+ }
532
+
461
533
  // ── Helpers ──────────────────────────────────────────────────────────
462
534
 
463
535
  function getNpmToken() {
@@ -745,6 +817,19 @@ export async function release({ repoPath, level, notes, notesSource, dryRun, noP
745
817
  console.log(` [dry run] Would publish to GitHub Packages`);
746
818
  console.log(` [dry run] Would create GitHub release v${newVersion}`);
747
819
  if (hasSkill) console.log(` [dry run] Would publish to ClawHub`);
820
+ // Skill-to-website dry run
821
+ const publishConfig = join(repoPath, '.publish-skill.json');
822
+ if (existsSync(publishConfig)) {
823
+ try {
824
+ const pc = JSON.parse(readFileSync(publishConfig, 'utf8'));
825
+ const envSet = !!process.env.WIP_WEBSITE_REPO;
826
+ if (pc.name && envSet) {
827
+ console.log(` [dry run] Would publish SKILL.md to website: install/${pc.name}.txt`);
828
+ } else if (pc.name && !envSet) {
829
+ console.log(` [dry run] Would publish to website but WIP_WEBSITE_REPO not set`);
830
+ }
831
+ } catch {}
832
+ }
748
833
  }
749
834
  console.log('');
750
835
  console.log(` Dry run complete. No changes made.`);
@@ -878,6 +963,22 @@ export async function release({ repoPath, level, notes, notesSource, dryRun, noP
878
963
  }
879
964
  }
880
965
  }
966
+
967
+ // 9.5. Publish SKILL.md to website as plain text
968
+ const skillWebResult = publishSkillToWebsite(repoPath);
969
+ if (skillWebResult.skipped) {
970
+ // Silent skip ... no config or env var
971
+ } else if (skillWebResult.ok) {
972
+ const deployNote = skillWebResult.deployed ? '' : ' (copied, deploy skipped)';
973
+ distResults.push({ target: 'Website', status: 'ok', detail: `install/${skillWebResult.target}.txt${deployNote}` });
974
+ console.log(` ✓ Published to website: install/${skillWebResult.target}.txt${deployNote}`);
975
+ if (!skillWebResult.deployed && skillWebResult.error) {
976
+ console.log(` ! ${skillWebResult.error}`);
977
+ }
978
+ } else {
979
+ distResults.push({ target: 'Website', status: 'failed', detail: skillWebResult.error });
980
+ console.log(` ✗ Website publish failed: ${skillWebResult.error}`);
981
+ }
881
982
  }
882
983
 
883
984
  // Distribution summary (#104)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wipcomputer/wip-release",
3
- "version": "1.9.11",
3
+ "version": "1.9.12",
4
4
  "type": "module",
5
5
  "description": "One-command release pipeline. Bumps version, updates changelog + SKILL.md, publishes to npm + GitHub.",
6
6
  "main": "core.mjs",