luckiest-co 1.0.35 → 1.0.36
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/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/bin/bump-version.js +62 -0
- package/bin/sync-plugin-repo.js +57 -0
- package/package.json +8 -2
- package/skills/luckiest-charms/SKILL.md +1 -0
- package/skills/luckiest-finish/SKILL.md +1 -0
- package/skills/luckiest-go/SKILL.md +1 -0
- package/skills/luckiest-helpers/SKILL.md +1 -0
- package/skills/luckiest-home/SKILL.md +1 -0
- package/skills/luckiest-leaderboard/SKILL.md +1 -0
- package/skills/luckiest-merge/SKILL.md +1 -0
- package/skills/luckiest-next/SKILL.md +1 -0
- package/skills/luckiest-overlaps/SKILL.md +1 -0
- package/skills/luckiest-plan/SKILL.md +1 -0
- package/skills/luckiest-skills/SKILL.md +1 -0
- package/skills/luckiest-start/SKILL.md +1 -0
- package/skills/luckiest-status/SKILL.md +1 -0
- package/skills/luckiest-updates/SKILL.md +1 -0
- package/skills/luckiest-vouch/SKILL.md +1 -0
- package/skills/luckiest-wishes/SKILL.md +1 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// Release bump: patch-bumps the npm version and the plugin version, then dates
|
|
4
|
+
// the CHANGELOG (turns "## Unreleased" into the release header, or adds one).
|
|
5
|
+
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
|
|
9
|
+
const green = '\x1b[32m';
|
|
10
|
+
const reset = '\x1b[0m';
|
|
11
|
+
|
|
12
|
+
const VERSION_RE = /("version":\s*")(\d+)\.(\d+)\.(\d+)(")/;
|
|
13
|
+
|
|
14
|
+
const patch = (v) => v.replace(/\d+$/, (n) => Number(n) + 1);
|
|
15
|
+
|
|
16
|
+
/** Bumps all four release files in dir. Returns { npm, plugin }. Writes nothing if the plugin versions disagree. */
|
|
17
|
+
function bumpVersion({ dir = path.join(__dirname, '..'), date = new Date().toLocaleDateString('en-CA') } = {}) {
|
|
18
|
+
const files = {
|
|
19
|
+
pkg: path.join(dir, 'package.json'),
|
|
20
|
+
plugin: path.join(dir, '.claude-plugin/plugin.json'),
|
|
21
|
+
market: path.join(dir, '.claude-plugin/marketplace.json'),
|
|
22
|
+
changelog: path.join(dir, 'CHANGELOG.md'),
|
|
23
|
+
};
|
|
24
|
+
const text = Object.fromEntries(Object.entries(files).map(([k, f]) => [k, fs.readFileSync(f, 'utf8')]));
|
|
25
|
+
const current = (k) => {
|
|
26
|
+
const m = text[k].match(VERSION_RE);
|
|
27
|
+
if (!m) throw new Error(`No version found in ${files[k]}`);
|
|
28
|
+
return `${m[2]}.${m[3]}.${m[4]}`;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const oldPlugin = current('plugin');
|
|
32
|
+
if (current('market') !== oldPlugin) {
|
|
33
|
+
throw new Error(`plugin.json (${oldPlugin}) and marketplace.json (${current('market')}) disagree. Fix them by hand first.`);
|
|
34
|
+
}
|
|
35
|
+
const npm = patch(current('pkg'));
|
|
36
|
+
const plugin = patch(oldPlugin);
|
|
37
|
+
|
|
38
|
+
// ponytail: replaces the first "version" in each file, which is the right one in all three today.
|
|
39
|
+
const write = (k, v) => fs.writeFileSync(files[k], text[k].replace(VERSION_RE, `$1${v}$5`));
|
|
40
|
+
write('pkg', npm);
|
|
41
|
+
write('plugin', plugin);
|
|
42
|
+
write('market', plugin);
|
|
43
|
+
// An "## Unreleased" section becomes the dated header, notes and all. Otherwise a fresh header goes on top.
|
|
44
|
+
const header = `## ${plugin} — ${date} (npm luckiest-co ${npm})`;
|
|
45
|
+
const unreleased = /^## Unreleased$/m;
|
|
46
|
+
fs.writeFileSync(files.changelog, unreleased.test(text.changelog)
|
|
47
|
+
? text.changelog.replace(unreleased, header)
|
|
48
|
+
: `${header}\n\n${text.changelog}`);
|
|
49
|
+
return { npm, plugin };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (require.main === module) {
|
|
53
|
+
try {
|
|
54
|
+
const { npm, plugin } = bumpVersion();
|
|
55
|
+
console.log(` ${green}Bumped to npm luckiest-co ${npm}, plugin ${plugin}.${reset} Check the notes under the new CHANGELOG.md header.`);
|
|
56
|
+
} catch (err) {
|
|
57
|
+
console.error(` ${err.message}`);
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
module.exports = { bumpVersion };
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// Plugin repo sync: mirrors this package into the public marketplace repo
|
|
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.
|
|
6
|
+
|
|
7
|
+
const { execFileSync } = require('child_process');
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const os = require('os');
|
|
10
|
+
const path = require('path');
|
|
11
|
+
|
|
12
|
+
const green = '\x1b[32m';
|
|
13
|
+
const yellow = '\x1b[33m';
|
|
14
|
+
const reset = '\x1b[0m';
|
|
15
|
+
|
|
16
|
+
const REPO = process.env.LUCKIEST_PLUGIN_REPO || 'luckiestco/luckiest-plugin';
|
|
17
|
+
|
|
18
|
+
const sh = (cmd, args, cwd) => execFileSync(cmd, args, { cwd, encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] }).trimEnd();
|
|
19
|
+
const versionOf = (dir, file) => JSON.parse(fs.readFileSync(path.join(dir, file), 'utf8')).version;
|
|
20
|
+
|
|
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 } = {}) {
|
|
23
|
+
const plugin = versionOf(src, '.claude-plugin/plugin.json');
|
|
24
|
+
const npm = versionOf(src, 'package.json');
|
|
25
|
+
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'luckiest-plugin-sync-'));
|
|
26
|
+
sh('git', ['clone', '--depth', '1', remote, dir]);
|
|
27
|
+
|
|
28
|
+
if (versionOf(dir, '.claude-plugin/plugin.json') === plugin) return { status: 'synced', dir, changes: [] };
|
|
29
|
+
|
|
30
|
+
// --checksum: a same-size edit with a matching mtime is otherwise skipped (a version bump is same-size).
|
|
31
|
+
sh('rsync', ['-a', '--checksum', '--delete', '--exclude', '.git', '--exclude', '.DS_Store', '--exclude', '__pycache__', `${src}/`, `${dir}/`]);
|
|
32
|
+
const changes = sh('git', ['status', '--porcelain'], dir).split('\n').filter(Boolean);
|
|
33
|
+
if (dryRun) return { status: 'dry-run', dir, changes };
|
|
34
|
+
|
|
35
|
+
const branch = `sync-${plugin}`;
|
|
36
|
+
const title = `Sync plugin ${plugin} (npm luckiest-co ${npm})`;
|
|
37
|
+
sh('git', ['switch', '-c', branch], dir);
|
|
38
|
+
sh('git', ['add', '-A'], dir);
|
|
39
|
+
sh('git', ['commit', '-m', title], dir);
|
|
40
|
+
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 };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (require.main === module) {
|
|
46
|
+
try {
|
|
47
|
+
const { status, dir, changes, url } = syncPluginRepo({ dryRun: process.argv.includes('--dry-run') });
|
|
48
|
+
if (status === 'synced') console.log(` ${green}${REPO} already has this plugin version.${reset}`);
|
|
49
|
+
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}`);
|
|
51
|
+
} catch (err) {
|
|
52
|
+
console.error(` ${(err.stderr || err.message).toString().trim()}`);
|
|
53
|
+
process.exit(1);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
module.exports = { syncPluginRepo };
|
package/package.json
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "luckiest-co",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.36",
|
|
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"
|
|
7
7
|
},
|
|
8
|
+
"scripts": {
|
|
9
|
+
"prepublishOnly": "node bin/check-version.js",
|
|
10
|
+
"bump": "node bin/bump-version.js",
|
|
11
|
+
"sync-plugin": "node bin/sync-plugin-repo.js"
|
|
12
|
+
},
|
|
8
13
|
"files": [
|
|
9
14
|
"bin",
|
|
10
15
|
"commands",
|
|
@@ -15,7 +20,8 @@
|
|
|
15
20
|
".claude-plugin",
|
|
16
21
|
"!**/__pycache__",
|
|
17
22
|
"!**/*.pyc",
|
|
18
|
-
"!bin/*.test.js"
|
|
23
|
+
"!bin/*.test.js",
|
|
24
|
+
"!bin/check-version.js"
|
|
19
25
|
],
|
|
20
26
|
"license": "SEE LICENSE IN LICENSE",
|
|
21
27
|
"engines": {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: luckiest-plan
|
|
3
|
+
user-invocable: false
|
|
3
4
|
description: "Use when the user says /luckiest plan or luckiest plan, or wants to plan a feature, a launch, or their next piece of work before building it, even if they do not say plan (for example \"what should I build next\" or \"break this down into tasks\"). Looks at the project first, drafts 3 to 7 tasks with a suggested skill, model, and runnable check each, saves the context for /luckiest go, and stages the plan after one approval question."
|
|
4
5
|
---
|
|
5
6
|
|