luckiest-co 1.0.49 → 1.0.51

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
  "name": "luckiest",
10
10
  "source": "./",
11
11
  "description": "Plan, go, finish, plus bundled free Luckiest skills that work in Claude Code, web chat, and Cowork.",
12
- "version": "0.1.48",
12
+ "version": "0.1.50",
13
13
  "author": { "name": "Luckiest" }
14
14
  }
15
15
  ]
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "luckiest",
3
3
  "description": "Plan, go, finish. Guided planning, progress dashboards, and your luckiest.co tribe inside Claude Code.",
4
- "version": "0.1.48",
4
+ "version": "0.1.50",
5
5
  "author": { "name": "Luckiest" }
6
6
  }
@@ -2,7 +2,10 @@
2
2
 
3
3
  // Plugin repo sync: mirrors this package into the public marketplace repo
4
4
  // (luckiestco/luckiest-plugin) and opens a PR there. Run after the release is
5
- // bumped and published. --dry-run stops before anything is pushed.
5
+ // bumped and published. --dry-run stops before anything is pushed. --merge
6
+ // squash-merges the PR it opened (the release workflow uses this). With GH_TOKEN
7
+ // set (CI), git pushes through `gh auth setup-git`, so the token never lands in
8
+ // a URL or a log.
6
9
 
7
10
  const { execFileSync } = require('child_process');
8
11
  const fs = require('fs');
@@ -18,10 +21,25 @@ const REPO = process.env.LUCKIEST_PLUGIN_REPO || 'luckiestco/luckiest-plugin';
18
21
  const sh = (cmd, args, cwd) => execFileSync(cmd, args, { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] }).trimEnd();
19
22
  const versionOf = (dir, file) => JSON.parse(fs.readFileSync(path.join(dir, file), 'utf8')).version;
20
23
 
21
- /** Returns { status: 'synced' | 'dry-run' | 'pr', dir, changes, url }. */
22
- function syncPluginRepo({ src = path.join(__dirname, '..'), remote = `https://github.com/${REPO}.git`, dryRun = false } = {}) {
24
+ const gitHas = (key, cwd) => {
25
+ try {
26
+ return Boolean(sh('git', ['config', key], cwd));
27
+ } catch {
28
+ return false;
29
+ }
30
+ };
31
+
32
+ /** Returns { status: 'synced' | 'dry-run' | 'pr', dir, changes, url, merged }. */
33
+ function syncPluginRepo({
34
+ src = path.join(__dirname, '..'),
35
+ remote = `https://github.com/${REPO}.git`,
36
+ dryRun = false,
37
+ merge = false,
38
+ gh = (args, cwd) => sh('gh', args, cwd),
39
+ } = {}) {
23
40
  const plugin = versionOf(src, '.claude-plugin/plugin.json');
24
41
  const npm = versionOf(src, 'package.json');
42
+ if (process.env.GH_TOKEN && remote.startsWith('https://github.com/')) gh(['auth', 'setup-git']);
25
43
  const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'luckiest-plugin-sync-'));
26
44
  sh('git', ['clone', '--depth', '1', remote, dir]);
27
45
 
@@ -36,18 +54,24 @@ function syncPluginRepo({ src = path.join(__dirname, '..'), remote = `https://gi
36
54
  const title = `Sync plugin ${plugin} (npm luckiest-co ${npm})`;
37
55
  sh('git', ['switch', '-c', branch], dir);
38
56
  sh('git', ['add', '-A'], dir);
39
- sh('git', ['commit', '-m', title], dir);
57
+ // CI runners have no git identity; commit as the release bot there.
58
+ const who = gitHas('user.name', dir) && gitHas('user.email', dir) ? [] : ['-c', 'user.name=luckiest-release', '-c', 'user.email=release@luckiest.co'];
59
+ sh('git', [...who, 'commit', '-m', title], dir);
40
60
  sh('git', ['push', '-u', 'origin', branch], dir);
41
- const url = sh('gh', ['pr', 'create', '--repo', REPO, '--head', branch, '--title', title, '--body', `Mirrors packages/luckiest-plugin at plugin ${plugin}.`], dir);
42
- return { status: 'pr', dir, changes, url };
61
+ const url = gh(['pr', 'create', '--repo', REPO, '--head', branch, '--title', title, '--body', `Mirrors packages/luckiest-plugin at plugin ${plugin}.`], dir);
62
+ if (merge) gh(['pr', 'merge', url, '--repo', REPO, '--squash', '--delete-branch'], dir);
63
+ return { status: 'pr', dir, changes, url, merged: merge };
43
64
  }
44
65
 
45
66
  if (require.main === module) {
46
67
  try {
47
- const { status, dir, changes, url } = syncPluginRepo({ dryRun: process.argv.includes('--dry-run') });
68
+ const { status, dir, changes, url, merged } = syncPluginRepo({
69
+ dryRun: process.argv.includes('--dry-run'),
70
+ merge: process.argv.includes('--merge'),
71
+ });
48
72
  if (status === 'synced') console.log(` ${green}${REPO} already has this plugin version.${reset}`);
49
73
  if (status === 'dry-run') console.log(` ${yellow}Dry run, nothing pushed.${reset} ${changes.length} changed files in ${dir}:\n${changes.map((c) => ` ${c}`).join('\n')}`);
50
- if (status === 'pr') console.log(` ${green}Opened ${url}${reset}`);
74
+ if (status === 'pr') console.log(` ${green}${merged ? 'Opened and merged' : 'Opened'} ${url}${reset}`);
51
75
  } catch (err) {
52
76
  console.error(` ${(err.stderr || err.message).toString().trim()}`);
53
77
  process.exit(1);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "luckiest-co",
3
- "version": "1.0.49",
3
+ "version": "1.0.51",
4
4
  "description": "Luckiest for Claude Code: plan, go, finish. Your luckiest.co skills and tribe, inside Claude.",
5
5
  "bin": {
6
6
  "luckiest-co": "./bin/install.js"
@@ -21,7 +21,8 @@
21
21
  "!**/__pycache__",
22
22
  "!**/*.pyc",
23
23
  "!bin/*.test.js",
24
- "!bin/check-version.js"
24
+ "!bin/check-version.js",
25
+ "!bin/release-check.js"
25
26
  ],
26
27
  "license": "SEE LICENSE IN LICENSE",
27
28
  "engines": {