@laitszkin/apollo-toolkit 3.1.0 → 3.1.2
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/CHANGELOG.md +12 -0
- package/README.md +6 -2
- package/analyse-app-logs/scripts/__pycache__/filter_logs_by_time.cpython-312.pyc +0 -0
- package/analyse-app-logs/scripts/__pycache__/log_cli_utils.cpython-312.pyc +0 -0
- package/analyse-app-logs/scripts/__pycache__/search_logs.cpython-312.pyc +0 -0
- package/commit-and-push/SKILL.md +4 -1
- package/docs-to-voice/scripts/__pycache__/docs_to_voice.cpython-312.pyc +0 -0
- package/generate-spec/scripts/__pycache__/create-specscpython-312.pyc +0 -0
- package/katex/scripts/__pycache__/render_katex.cpython-312.pyc +0 -0
- package/lib/cli.js +22 -13
- package/lib/installer.js +61 -15
- package/open-github-issue/scripts/__pycache__/open_github_issue.cpython-312.pyc +0 -0
- package/package.json +1 -1
- package/read-github-issue/scripts/__pycache__/find_issues.cpython-312.pyc +0 -0
- package/read-github-issue/scripts/__pycache__/read_issue.cpython-312.pyc +0 -0
- package/resolve-review-comments/scripts/__pycache__/review_threads.cpython-312.pyc +0 -0
- package/scripts/install_skills.ps1 +16 -12
- package/scripts/install_skills.sh +19 -17
- package/text-to-short-video/scripts/__pycache__/enforce_video_aspect_ratio.cpython-312.pyc +0 -0
- package/version-release/SKILL.md +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,18 @@ All notable changes to this repository are documented in this file.
|
|
|
7
7
|
### Changed
|
|
8
8
|
- None yet.
|
|
9
9
|
|
|
10
|
+
## [v3.1.2] - 2026-04-23
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- Tighten `commit-and-push` so emitted UI git directives such as `::git-stage`, `::git-commit`, and `::git-push` never count as evidence that staging, commit creation, or remote push actually happened.
|
|
14
|
+
- Tighten `version-release` so release flows require real git mutations for staging, commit/tag creation, and push verification instead of treating UI git directives as proof that the release commit or tag exists.
|
|
15
|
+
|
|
16
|
+
## [v3.1.1] - 2026-04-22
|
|
17
|
+
|
|
18
|
+
### Changed
|
|
19
|
+
- Fix Apollo Toolkit installers so `codex`-only skills stay scoped to Codex targets, while shared skills continue to install across the selected destinations.
|
|
20
|
+
- Align the CLI welcome/help text, non-interactive guidance, and README examples with the supported `agents` target and current installer behavior.
|
|
21
|
+
|
|
10
22
|
## [v3.1.0] - 2026-04-22
|
|
11
23
|
|
|
12
24
|
### Added
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Apollo Toolkit Skills
|
|
2
2
|
|
|
3
|
-
A curated skill catalog for Codex, OpenClaw, Trae, and Claude Code with a managed installer that keeps the toolkit in `~/.apollo-toolkit` and copies each skill into the targets you choose.
|
|
3
|
+
A curated skill catalog for Codex, OpenClaw, Trae, Agents, and Claude Code with a managed installer that keeps the toolkit in `~/.apollo-toolkit` and copies each skill into the targets you choose.
|
|
4
4
|
|
|
5
5
|
## Included skills
|
|
6
6
|
|
|
@@ -63,7 +63,7 @@ npx @laitszkin/apollo-toolkit
|
|
|
63
63
|
The interactive installer:
|
|
64
64
|
- shows a branded `Apollo Toolkit` terminal welcome screen with a short staged reveal
|
|
65
65
|
- installs a managed copy into `~/.apollo-toolkit`
|
|
66
|
-
- lets you multi-select `codex`, `openclaw`, `trae`, `claude-code`, or `all`
|
|
66
|
+
- lets you multi-select `codex`, `openclaw`, `trae`, `agents`, `claude-code`, or `all`
|
|
67
67
|
- copies `~/.apollo-toolkit/<skill>` into each selected target
|
|
68
68
|
- removes stale previously installed skill directories that existed in the previous installed version but no longer exist in the current package skill list
|
|
69
69
|
- replaces legacy symlink-based installs created by older Apollo Toolkit installers with real copied directories
|
|
@@ -91,6 +91,7 @@ apltk open-github-issue --help
|
|
|
91
91
|
|
|
92
92
|
```bash
|
|
93
93
|
npx @laitszkin/apollo-toolkit codex
|
|
94
|
+
npx @laitszkin/apollo-toolkit agents
|
|
94
95
|
npx @laitszkin/apollo-toolkit claude-code
|
|
95
96
|
npx @laitszkin/apollo-toolkit codex openclaw
|
|
96
97
|
npx @laitszkin/apollo-toolkit all
|
|
@@ -103,6 +104,7 @@ APOLLO_TOOLKIT_HOME=~/custom-toolkit npx @laitszkin/apollo-toolkit codex
|
|
|
103
104
|
CODEX_SKILLS_DIR=~/custom-codex-skills npx @laitszkin/apollo-toolkit codex
|
|
104
105
|
OPENCLAW_HOME=~/.openclaw npx @laitszkin/apollo-toolkit openclaw
|
|
105
106
|
TRAE_SKILLS_DIR=~/.trae/skills npx @laitszkin/apollo-toolkit trae
|
|
107
|
+
AGENTS_SKILLS_DIR=~/.agents/skills npx @laitszkin/apollo-toolkit agents
|
|
106
108
|
CLAUDE_CODE_SKILLS_DIR=~/.claude/skills npx @laitszkin/apollo-toolkit claude-code
|
|
107
109
|
```
|
|
108
110
|
|
|
@@ -120,12 +122,14 @@ Installers still live in `scripts/` for local repository usage and curl / iwr in
|
|
|
120
122
|
./scripts/install_skills.sh codex
|
|
121
123
|
./scripts/install_skills.sh openclaw
|
|
122
124
|
./scripts/install_skills.sh trae
|
|
125
|
+
./scripts/install_skills.sh agents
|
|
123
126
|
./scripts/install_skills.sh all
|
|
124
127
|
```
|
|
125
128
|
|
|
126
129
|
```powershell
|
|
127
130
|
./scripts/install_skills.ps1
|
|
128
131
|
./scripts/install_skills.ps1 codex
|
|
132
|
+
./scripts/install_skills.ps1 agents
|
|
129
133
|
./scripts/install_skills.ps1 all
|
|
130
134
|
```
|
|
131
135
|
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/commit-and-push/SKILL.md
CHANGED
|
@@ -15,7 +15,7 @@ description: "Guide the agent to submit local changes with commit and push only
|
|
|
15
15
|
## Standards
|
|
16
16
|
|
|
17
17
|
- Evidence: Inspect git state and classify the change set before deciding which quality gates apply, then compare the actual pending diff against root `CHANGELOG.md` `Unreleased` before committing, while also distinguishing the staged surface from additional unstaged work before deciding commit scope.
|
|
18
|
-
- Execution: Run the required quality-gate skills when applicable, and treat every conditional gate whose scenario is met as blocking before submission; hand the repository to `submission-readiness-check` for readiness classification, invoke `archive-specs` directly whenever completed plan sets should be converted or project docs need alignment, preserve staging intent, honor any explicit user-specified target branch, and when the worktree is already clean inspect local `HEAD`, upstream state, and the most recent relevant commit before deciding the request is a no-op; when worktree-based delivery is involved, verify where the authoritative target branch lives before moving history, re-validate on that target branch after replay or merge, and remove the temporary worktree only after the target branch is safely updated; when the user asks for multiple commits or a narrower staged subset, keep those commit boundaries explicit instead of broadening scope implicitly; then commit and push without release steps; run dependent git mutations sequentially and verify the remote branch actually contains the new local `HEAD` before reporting success.
|
|
18
|
+
- Execution: Run the required quality-gate skills when applicable, and treat every conditional gate whose scenario is met as blocking before submission; hand the repository to `submission-readiness-check` for readiness classification, invoke `archive-specs` directly whenever completed plan sets should be converted or project docs need alignment, preserve staging intent, honor any explicit user-specified target branch, and when the worktree is already clean inspect local `HEAD`, upstream state, and the most recent relevant commit before deciding the request is a no-op; when worktree-based delivery is involved, verify where the authoritative target branch lives before moving history, re-validate on that target branch after replay or merge, and remove the temporary worktree only after the target branch is safely updated; when the user asks for multiple commits or a narrower staged subset, keep those commit boundaries explicit instead of broadening scope implicitly; then commit and push without release steps; run dependent git mutations sequentially and verify the remote branch actually contains the new local `HEAD` before reporting success, and never treat UI directives such as `::git-stage`, `::git-commit`, or `::git-push` as substitutes for actual git commands or as evidence that submission already happened.
|
|
19
19
|
- Quality: Re-run relevant validation for runtime changes, preserve unrelated local work safely when branch switching or post-push local sync is required, do not bypass blocking readiness findings such as missing/stale `Unreleased` bullets or unsynchronized project docs, and never collapse intentionally separated commit scopes just because related unstaged changes are present.
|
|
20
20
|
- Output: Produce a concise Conventional Commit, push it to the intended branch, and report any temporary stash/restore, commit-scope separation, or local branch sync that was required.
|
|
21
21
|
|
|
@@ -71,6 +71,7 @@ Load only when needed:
|
|
|
71
71
|
- Preserve user staging intent where possible.
|
|
72
72
|
- If the user explicitly asks for separate commits, or the staged set is already a deliberate subset of the worktree, keep those scopes separated and do not auto-stage the remaining diff unless the user expands the requested scope.
|
|
73
73
|
- If the user later broadens the requested scope, restate the new grouping, verify it against the actual staged/unstaged surfaces, and only then create the additional commit(s).
|
|
74
|
+
- Use actual `git add` / `git commit` operations; do not emit UI git directives as a stand-in for repository mutations.
|
|
74
75
|
- Write a concise Conventional Commit message using `references/commit-messages.md`.
|
|
75
76
|
7. Push
|
|
76
77
|
- Push commit(s) to the intended branch.
|
|
@@ -79,6 +80,7 @@ Load only when needed:
|
|
|
79
80
|
- If the push result is ambiguous, out of order, or the hashes do not match, rerun the missing git step sequentially and re-check before reporting success.
|
|
80
81
|
- Confirm the local branch state matches the user's requested destination when post-push synchronization was requested.
|
|
81
82
|
- When the user explicitly asks to merge work back from a temporary worktree and delete that worktree, do the final verification on the authoritative target branch first, then remove the temporary worktree and prune stale worktree records before reporting completion.
|
|
83
|
+
- Do not claim success based on emitted UI directives or optimistic status text alone; remote-hash verification is the required evidence.
|
|
82
84
|
|
|
83
85
|
## Notes
|
|
84
86
|
|
|
@@ -88,6 +90,7 @@ Load only when needed:
|
|
|
88
90
|
- Never downgrade `discover-edge-cases` or `harden-app-security` to optional follow-up when the change risk says they apply.
|
|
89
91
|
- Never claim the repository is ready to commit while root `CHANGELOG.md` `Unreleased` is missing the current change or still describes superseded work.
|
|
90
92
|
- Never fabricate a commit/push result when the worktree is already clean; either identify the exact existing commit/upstream state that satisfies the user's request or say that no matching new submission exists.
|
|
93
|
+
- Never treat `::git-stage`, `::git-commit`, `::git-push`, or similar UI helpers as proof that repository history was mutated; rely on actual git command results plus local/remote hash checks.
|
|
91
94
|
- Never delete a temporary worktree before the target branch has been updated, tested, and verified to contain the intended final content.
|
|
92
95
|
- Never auto-stage or auto-merge unrelated unstaged changes into a commit when the user or current index state already defines narrower commit boundaries.
|
|
93
96
|
- If release/version/tag work is requested, use `version-release` instead.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/lib/cli.js
CHANGED
|
@@ -3,6 +3,7 @@ const fs = require('node:fs');
|
|
|
3
3
|
const path = require('node:path');
|
|
4
4
|
|
|
5
5
|
const {
|
|
6
|
+
TARGET_DEFINITIONS,
|
|
6
7
|
VALID_MODES,
|
|
7
8
|
installLinks,
|
|
8
9
|
normalizeModes,
|
|
@@ -15,11 +16,7 @@ const { checkForPackageUpdate } = require('./updater');
|
|
|
15
16
|
|
|
16
17
|
const TARGET_OPTIONS = [
|
|
17
18
|
{ id: 'all', label: 'All', description: 'Install every supported target below' },
|
|
18
|
-
|
|
19
|
-
{ id: 'openclaw', label: 'OpenClaw', description: '~/.openclaw/workspace*/skills' },
|
|
20
|
-
{ id: 'trae', label: 'Trae', description: '~/.trae/skills' },
|
|
21
|
-
{ id: 'agents', label: 'Agents', description: '~/.agents/skills' },
|
|
22
|
-
{ id: 'claude-code', label: 'Claude Code', description: '~/.claude/skills' },
|
|
19
|
+
...TARGET_DEFINITIONS,
|
|
23
20
|
];
|
|
24
21
|
|
|
25
22
|
const WORDMARK_LINES = [
|
|
@@ -64,6 +61,22 @@ function buildBanner({ version, colorEnabled }) {
|
|
|
64
61
|
].join('\n');
|
|
65
62
|
}
|
|
66
63
|
|
|
64
|
+
function buildModeUsagePattern() {
|
|
65
|
+
return `${VALID_MODES.join('|')}|all`;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function buildInteractiveModeHint() {
|
|
69
|
+
const quotedModes = [...VALID_MODES, 'all'].map((mode) => `\`${mode}\``);
|
|
70
|
+
return `${quotedModes.slice(0, -1).join(', ')}, or ${quotedModes.at(-1)}`;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function buildSupportedTargetLines({ colorEnabled }) {
|
|
74
|
+
const labelWidth = TARGET_DEFINITIONS.reduce((max, target) => Math.max(max, target.label.length), 0);
|
|
75
|
+
return TARGET_DEFINITIONS.map((target) => (
|
|
76
|
+
` ${color(target.label.padEnd(labelWidth, ' '), '1', colorEnabled)} ${target.description}`
|
|
77
|
+
)).join('\n');
|
|
78
|
+
}
|
|
79
|
+
|
|
67
80
|
function buildWelcomeScreen({ version, colorEnabled, stage = 4 }) {
|
|
68
81
|
const lines = [buildBanner({ version, colorEnabled })];
|
|
69
82
|
|
|
@@ -90,11 +103,7 @@ function buildWelcomeScreen({ version, colorEnabled, stage = 4 }) {
|
|
|
90
103
|
lines.push(
|
|
91
104
|
'',
|
|
92
105
|
color('Supported targets:', '2', colorEnabled),
|
|
93
|
-
|
|
94
|
-
` ${color('OpenClaw', '1', colorEnabled)} ~/.openclaw/workspace*/skills`,
|
|
95
|
-
` ${color('Trae', '1', colorEnabled)} ~/.trae/skills`,
|
|
96
|
-
` ${color('Agents', '1', colorEnabled)} ~/.agents/skills`,
|
|
97
|
-
` ${color('Claude Code', '1', colorEnabled)} ~/.claude/skills`,
|
|
106
|
+
buildSupportedTargetLines({ colorEnabled }),
|
|
98
107
|
);
|
|
99
108
|
}
|
|
100
109
|
|
|
@@ -123,8 +132,8 @@ function buildHelpText({ version, colorEnabled }) {
|
|
|
123
132
|
buildBanner({ version, colorEnabled }),
|
|
124
133
|
'',
|
|
125
134
|
'Usage:',
|
|
126
|
-
|
|
127
|
-
|
|
135
|
+
` apltk [install] [${buildModeUsagePattern()}]...`,
|
|
136
|
+
` apollo-toolkit [install] [${buildModeUsagePattern()}]...`,
|
|
128
137
|
' apltk tools',
|
|
129
138
|
' apltk <tool> [...args]',
|
|
130
139
|
' apltk tools <tool> [...args]',
|
|
@@ -270,7 +279,7 @@ function renderSelectionScreen({ output, version, cursor, selected, message, env
|
|
|
270
279
|
|
|
271
280
|
async function promptForModes({ stdin, stdout, version, env }) {
|
|
272
281
|
if (!stdin.isTTY || !stdout.isTTY) {
|
|
273
|
-
throw new Error(
|
|
282
|
+
throw new Error(`Interactive install requires a TTY. Re-run with targets like ${buildInteractiveModeHint()}.`);
|
|
274
283
|
}
|
|
275
284
|
|
|
276
285
|
await animateWelcomeScreen({ output: stdout, version, env });
|
package/lib/installer.js
CHANGED
|
@@ -3,7 +3,14 @@ const fsp = require('node:fs/promises');
|
|
|
3
3
|
const os = require('node:os');
|
|
4
4
|
const path = require('node:path');
|
|
5
5
|
|
|
6
|
-
const
|
|
6
|
+
const TARGET_DEFINITIONS = Object.freeze([
|
|
7
|
+
{ id: 'codex', label: 'Codex', description: '~/.codex/skills' },
|
|
8
|
+
{ id: 'openclaw', label: 'OpenClaw', description: '~/.openclaw/workspace*/skills' },
|
|
9
|
+
{ id: 'trae', label: 'Trae', description: '~/.trae/skills' },
|
|
10
|
+
{ id: 'agents', label: 'Agents', description: '~/.agents/skills' },
|
|
11
|
+
{ id: 'claude-code', label: 'Claude Code', description: '~/.claude/skills' },
|
|
12
|
+
]);
|
|
13
|
+
const VALID_MODES = TARGET_DEFINITIONS.map(({ id }) => id);
|
|
7
14
|
const COPY_FILES = new Set(['AGENTS.md', 'CHANGELOG.md', 'LICENSE', 'README.md', 'package.json']);
|
|
8
15
|
const COPY_DIRS = new Set(['scripts']);
|
|
9
16
|
|
|
@@ -63,7 +70,7 @@ function normalizeModes(inputModes) {
|
|
|
63
70
|
|
|
64
71
|
async function listSkillNames(rootDir, modes = []) {
|
|
65
72
|
const entries = await fsp.readdir(rootDir, { withFileTypes: true });
|
|
66
|
-
const skillNames =
|
|
73
|
+
const skillNames = new Set();
|
|
67
74
|
|
|
68
75
|
for (const entry of entries) {
|
|
69
76
|
if (!entry.isDirectory()) {
|
|
@@ -71,7 +78,7 @@ async function listSkillNames(rootDir, modes = []) {
|
|
|
71
78
|
}
|
|
72
79
|
|
|
73
80
|
if (fs.existsSync(path.join(rootDir, entry.name, 'SKILL.md'))) {
|
|
74
|
-
skillNames.
|
|
81
|
+
skillNames.add(entry.name);
|
|
75
82
|
}
|
|
76
83
|
}
|
|
77
84
|
|
|
@@ -82,13 +89,42 @@ async function listSkillNames(rootDir, modes = []) {
|
|
|
82
89
|
const codexEntries = await fsp.readdir(codexDir, { withFileTypes: true });
|
|
83
90
|
for (const entry of codexEntries) {
|
|
84
91
|
if (entry.isDirectory() && fs.existsSync(path.join(codexDir, entry.name, 'SKILL.md'))) {
|
|
85
|
-
skillNames.
|
|
92
|
+
skillNames.add(entry.name);
|
|
86
93
|
}
|
|
87
94
|
}
|
|
88
95
|
}
|
|
89
96
|
}
|
|
90
97
|
|
|
91
|
-
return skillNames.sort();
|
|
98
|
+
return [...skillNames].sort();
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
async function listCodexSkillNames(rootDir) {
|
|
102
|
+
const codexDir = path.join(rootDir, 'codex');
|
|
103
|
+
if (!fs.existsSync(codexDir)) {
|
|
104
|
+
return [];
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const entries = await fsp.readdir(codexDir, { withFileTypes: true });
|
|
108
|
+
return entries
|
|
109
|
+
.filter((entry) => entry.isDirectory() && fs.existsSync(path.join(codexDir, entry.name, 'SKILL.md')))
|
|
110
|
+
.map((entry) => entry.name)
|
|
111
|
+
.sort();
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function getTargetSkillNames({ targetMode, sharedSkillNames, codexSkillNames }) {
|
|
115
|
+
if (targetMode !== 'codex') {
|
|
116
|
+
return sharedSkillNames;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return [...new Set([...sharedSkillNames, ...codexSkillNames])].sort();
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function resolveInstallSourcePath({ toolkitHome, targetMode, skillName, codexSkillNames }) {
|
|
123
|
+
if (targetMode === 'codex' && codexSkillNames.includes(skillName)) {
|
|
124
|
+
return path.join(toolkitHome, 'codex', skillName);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return path.join(toolkitHome, skillName);
|
|
92
128
|
}
|
|
93
129
|
|
|
94
130
|
function shouldCopyEntry(sourceRoot, entry) {
|
|
@@ -265,24 +301,33 @@ async function replaceWithCopy(sourcePath, targetPath) {
|
|
|
265
301
|
|
|
266
302
|
async function installLinks({ toolkitHome, modes, env = process.env, previousSkillNames = [] }) {
|
|
267
303
|
const normalizedModes = normalizeModes(modes);
|
|
268
|
-
const
|
|
304
|
+
const sharedSkillNames = await listSkillNames(toolkitHome);
|
|
305
|
+
const codexSkillNames = normalizedModes.includes('codex') ? await listCodexSkillNames(toolkitHome) : [];
|
|
306
|
+
const skillNames = normalizedModes.includes('codex')
|
|
307
|
+
? [...new Set([...sharedSkillNames, ...codexSkillNames])].sort()
|
|
308
|
+
: sharedSkillNames;
|
|
269
309
|
const targets = await getTargetRoots(normalizedModes, env);
|
|
270
310
|
const copiedPaths = [];
|
|
271
|
-
const staleSkillNames = previousSkillNames.filter((skillName) => !skillNames.includes(skillName));
|
|
272
311
|
|
|
273
312
|
for (const target of targets) {
|
|
313
|
+
const targetSkillNames = getTargetSkillNames({
|
|
314
|
+
targetMode: target.mode,
|
|
315
|
+
sharedSkillNames,
|
|
316
|
+
codexSkillNames,
|
|
317
|
+
});
|
|
318
|
+
const staleSkillNames = previousSkillNames.filter((skillName) => !targetSkillNames.includes(skillName));
|
|
319
|
+
|
|
274
320
|
await ensureDirectory(target.root);
|
|
275
321
|
for (const staleSkillName of staleSkillNames) {
|
|
276
322
|
await fsp.rm(path.join(target.root, staleSkillName), { recursive: true, force: true });
|
|
277
323
|
}
|
|
278
|
-
for (const skillName of
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
}
|
|
324
|
+
for (const skillName of targetSkillNames) {
|
|
325
|
+
const sourcePath = resolveInstallSourcePath({
|
|
326
|
+
toolkitHome,
|
|
327
|
+
targetMode: target.mode,
|
|
328
|
+
skillName,
|
|
329
|
+
codexSkillNames,
|
|
330
|
+
});
|
|
286
331
|
const targetPath = path.join(target.root, skillName);
|
|
287
332
|
await replaceWithCopy(sourcePath, targetPath);
|
|
288
333
|
copiedPaths.push({ target: target.label, path: targetPath, skillName });
|
|
@@ -298,6 +343,7 @@ async function installLinks({ toolkitHome, modes, env = process.env, previousSki
|
|
|
298
343
|
|
|
299
344
|
module.exports = {
|
|
300
345
|
expandUserPath,
|
|
346
|
+
TARGET_DEFINITIONS,
|
|
301
347
|
VALID_MODES,
|
|
302
348
|
getTargetRoots,
|
|
303
349
|
installLinks,
|
|
Binary file
|
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -110,15 +110,16 @@ else {
|
|
|
110
110
|
$RepoRoot = $ToolkitHome
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
function Get-
|
|
113
|
+
function Get-SkillPathGroups {
|
|
114
114
|
param([string[]]$SelectedModes)
|
|
115
115
|
|
|
116
116
|
$dirs = Get-ChildItem -Path $RepoRoot -Directory | Sort-Object Name
|
|
117
|
-
$
|
|
117
|
+
$sharedSkills = @()
|
|
118
|
+
$codexSkills = @()
|
|
118
119
|
|
|
119
120
|
foreach ($dir in $dirs) {
|
|
120
121
|
if (Test-Path -LiteralPath (Join-Path $dir.FullName "SKILL.md") -PathType Leaf) {
|
|
121
|
-
$
|
|
122
|
+
$sharedSkills += $dir.FullName
|
|
122
123
|
}
|
|
123
124
|
}
|
|
124
125
|
|
|
@@ -129,17 +130,20 @@ function Get-SkillPaths {
|
|
|
129
130
|
$codexDirs = Get-ChildItem -Path $codexDir -Directory | Sort-Object Name
|
|
130
131
|
foreach ($dir in $codexDirs) {
|
|
131
132
|
if (Test-Path -LiteralPath (Join-Path $dir.FullName "SKILL.md") -PathType Leaf) {
|
|
132
|
-
$
|
|
133
|
+
$codexSkills += $dir.FullName
|
|
133
134
|
}
|
|
134
135
|
}
|
|
135
136
|
}
|
|
136
137
|
}
|
|
137
138
|
|
|
138
|
-
if ($
|
|
139
|
+
if ($sharedSkills.Count -eq 0) {
|
|
139
140
|
throw "No skill folders found in: $RepoRoot"
|
|
140
141
|
}
|
|
141
142
|
|
|
142
|
-
|
|
143
|
+
[PSCustomObject]@{
|
|
144
|
+
Shared = $sharedSkills
|
|
145
|
+
Codex = $codexSkills
|
|
146
|
+
}
|
|
143
147
|
}
|
|
144
148
|
|
|
145
149
|
function Add-ModeOnce {
|
|
@@ -343,15 +347,15 @@ if ($Modes.Count -gt 0 -and ($Modes[0] -eq "-h" -or $Modes[0] -eq "--help")) {
|
|
|
343
347
|
}
|
|
344
348
|
|
|
345
349
|
$selectedModes = Resolve-Modes -Requested $Modes
|
|
346
|
-
$
|
|
350
|
+
$skillPathGroups = Get-SkillPathGroups -SelectedModes $selectedModes
|
|
347
351
|
|
|
348
352
|
foreach ($mode in $selectedModes) {
|
|
349
353
|
switch ($mode) {
|
|
350
|
-
"codex" { Install-Codex -SkillPaths $
|
|
351
|
-
"openclaw" { Install-OpenClaw -SkillPaths $
|
|
352
|
-
"trae" { Install-Trae -SkillPaths $
|
|
353
|
-
"agents" { Install-Agents -SkillPaths $
|
|
354
|
-
"claude-code" { Install-ClaudeCode -SkillPaths $
|
|
354
|
+
"codex" { Install-Codex -SkillPaths ($skillPathGroups.Shared + $skillPathGroups.Codex) }
|
|
355
|
+
"openclaw" { Install-OpenClaw -SkillPaths $skillPathGroups.Shared }
|
|
356
|
+
"trae" { Install-Trae -SkillPaths $skillPathGroups.Shared }
|
|
357
|
+
"agents" { Install-Agents -SkillPaths $skillPathGroups.Shared }
|
|
358
|
+
"claude-code" { Install-ClaudeCode -SkillPaths $skillPathGroups.Shared }
|
|
355
359
|
default { throw "Unknown mode: $mode" }
|
|
356
360
|
}
|
|
357
361
|
}
|
|
@@ -78,14 +78,16 @@ else
|
|
|
78
78
|
SCRIPT_DIR="$REPO_ROOT/scripts"
|
|
79
79
|
fi
|
|
80
80
|
SELECTED_MODES=()
|
|
81
|
-
|
|
81
|
+
SHARED_SKILL_PATHS=()
|
|
82
|
+
CODEX_SKILL_PATHS=()
|
|
82
83
|
|
|
83
84
|
collect_skills() {
|
|
84
85
|
local dir
|
|
85
|
-
|
|
86
|
+
SHARED_SKILL_PATHS=()
|
|
87
|
+
CODEX_SKILL_PATHS=()
|
|
86
88
|
while IFS= read -r dir; do
|
|
87
89
|
if [[ -f "$dir/SKILL.md" ]]; then
|
|
88
|
-
|
|
90
|
+
SHARED_SKILL_PATHS+=("$dir")
|
|
89
91
|
fi
|
|
90
92
|
done < <(find "$REPO_ROOT" -mindepth 1 -maxdepth 1 -type d | sort)
|
|
91
93
|
|
|
@@ -95,13 +97,13 @@ collect_skills() {
|
|
|
95
97
|
if [[ -d "$codex_dir" ]]; then
|
|
96
98
|
while IFS= read -r dir; do
|
|
97
99
|
if [[ -f "$dir/SKILL.md" ]]; then
|
|
98
|
-
|
|
100
|
+
CODEX_SKILL_PATHS+=("$dir")
|
|
99
101
|
fi
|
|
100
102
|
done < <(find "$codex_dir" -mindepth 1 -maxdepth 1 -type d | sort)
|
|
101
103
|
fi
|
|
102
104
|
fi
|
|
103
105
|
|
|
104
|
-
if [[ ${#
|
|
106
|
+
if [[ ${#SHARED_SKILL_PATHS[@]} -eq 0 ]]; then
|
|
105
107
|
echo "No skill folders found in: $REPO_ROOT" >&2
|
|
106
108
|
exit 1
|
|
107
109
|
fi
|
|
@@ -124,17 +126,17 @@ replace_with_copy() {
|
|
|
124
126
|
}
|
|
125
127
|
|
|
126
128
|
install_codex() {
|
|
127
|
-
local codex_skills_dir
|
|
129
|
+
local codex_skills_dir src
|
|
128
130
|
codex_skills_dir="$(expand_user_path "${CODEX_SKILLS_DIR:-$HOME/.codex/skills}")"
|
|
129
131
|
|
|
130
132
|
echo "Installing to codex: $codex_skills_dir"
|
|
131
|
-
for src in "${
|
|
133
|
+
for src in "${SHARED_SKILL_PATHS[@]}" "${CODEX_SKILL_PATHS[@]}"; do
|
|
132
134
|
replace_with_copy "$src" "$codex_skills_dir"
|
|
133
135
|
done
|
|
134
136
|
}
|
|
135
137
|
|
|
136
138
|
install_openclaw() {
|
|
137
|
-
local openclaw_home workspace skills_dir
|
|
139
|
+
local openclaw_home workspace skills_dir src
|
|
138
140
|
local -a workspaces
|
|
139
141
|
|
|
140
142
|
openclaw_home="$(expand_user_path "${OPENCLAW_HOME:-$HOME/.openclaw}")"
|
|
@@ -152,38 +154,38 @@ install_openclaw() {
|
|
|
152
154
|
for workspace in "${workspaces[@]}"; do
|
|
153
155
|
skills_dir="$workspace/skills"
|
|
154
156
|
echo "Installing to openclaw workspace: $skills_dir"
|
|
155
|
-
for src in "${
|
|
157
|
+
for src in "${SHARED_SKILL_PATHS[@]}"; do
|
|
156
158
|
replace_with_copy "$src" "$skills_dir"
|
|
157
159
|
done
|
|
158
160
|
done
|
|
159
161
|
}
|
|
160
162
|
|
|
161
163
|
install_trae() {
|
|
162
|
-
local trae_skills_dir
|
|
164
|
+
local trae_skills_dir src
|
|
163
165
|
trae_skills_dir="$(expand_user_path "${TRAE_SKILLS_DIR:-$HOME/.trae/skills}")"
|
|
164
166
|
|
|
165
167
|
echo "Installing to trae: $trae_skills_dir"
|
|
166
|
-
for src in "${
|
|
168
|
+
for src in "${SHARED_SKILL_PATHS[@]}"; do
|
|
167
169
|
replace_with_copy "$src" "$trae_skills_dir"
|
|
168
170
|
done
|
|
169
171
|
}
|
|
170
172
|
|
|
171
173
|
install_agents() {
|
|
172
|
-
local agents_skills_dir
|
|
174
|
+
local agents_skills_dir src
|
|
173
175
|
agents_skills_dir="$(expand_user_path "${AGENTS_SKILLS_DIR:-$HOME/.agents/skills}")"
|
|
174
176
|
|
|
175
177
|
echo "Installing to agents: $agents_skills_dir"
|
|
176
|
-
for src in "${
|
|
178
|
+
for src in "${SHARED_SKILL_PATHS[@]}"; do
|
|
177
179
|
replace_with_copy "$src" "$agents_skills_dir"
|
|
178
180
|
done
|
|
179
181
|
}
|
|
180
182
|
|
|
181
183
|
install_claude_code() {
|
|
182
|
-
local claude_code_skills_dir
|
|
184
|
+
local claude_code_skills_dir src
|
|
183
185
|
claude_code_skills_dir="$(expand_user_path "${CLAUDE_CODE_SKILLS_DIR:-$HOME/.claude/skills}")"
|
|
184
186
|
|
|
185
187
|
echo "Installing to claude-code: $claude_code_skills_dir"
|
|
186
|
-
for src in "${
|
|
188
|
+
for src in "${SHARED_SKILL_PATHS[@]}"; do
|
|
187
189
|
replace_with_copy "$src" "$claude_code_skills_dir"
|
|
188
190
|
done
|
|
189
191
|
}
|
|
@@ -233,7 +235,7 @@ read_choice_from_user() {
|
|
|
233
235
|
elif [[ -r /dev/tty ]]; then
|
|
234
236
|
read -r -p "$prompt" result < /dev/tty
|
|
235
237
|
else
|
|
236
|
-
echo "Interactive input unavailable. Pass mode arguments (e.g. codex/openclaw/trae/all)." >&2
|
|
238
|
+
echo "Interactive input unavailable. Pass mode arguments (e.g. codex/openclaw/trae/agents/claude-code/all)." >&2
|
|
237
239
|
exit 1
|
|
238
240
|
fi
|
|
239
241
|
|
|
@@ -264,7 +266,7 @@ choose_modes_interactive() {
|
|
|
264
266
|
3) add_mode_once "trae" ;;
|
|
265
267
|
4) add_mode_once "agents" ;;
|
|
266
268
|
5) add_mode_once "claude-code" ;;
|
|
267
|
-
6) add_mode_once "codex"; add_mode_once "openclaw"; add_mode_once "trae"; add_mode_once "claude-code" ;;
|
|
269
|
+
6) add_mode_once "codex"; add_mode_once "openclaw"; add_mode_once "trae"; add_mode_once "agents"; add_mode_once "claude-code" ;;
|
|
268
270
|
*)
|
|
269
271
|
echo "Invalid choice: $raw_choice" >&2
|
|
270
272
|
exit 1
|
|
Binary file
|
package/version-release/SKILL.md
CHANGED
|
@@ -15,7 +15,7 @@ description: "Guide the agent to prepare and publish a versioned release (versio
|
|
|
15
15
|
## Standards
|
|
16
16
|
|
|
17
17
|
- Evidence: Inspect the active change set, current version files, existing tag format, existing remote tags/releases, and root `CHANGELOG.md` `Unreleased` content before touching version files, tags, or release metadata.
|
|
18
|
-
- Execution: Use this workflow only for explicit release intent, run the required quality gates when applicable, and treat every conditional gate whose scenario is met as blocking before versioning or publication; hand the repository to `submission-readiness-check` before versioning work, invoke `archive-specs` directly whenever completed plan sets should be converted or project docs need alignment, and if the worktree is already clean inspect the current version, local/remote tag state, and existing GitHub release state before deciding whether the request is already satisfied; when the user explicitly wants the same prerelease version to point at newer fixes, retarget the existing prerelease tag and GitHub release instead of inventing an extra version bump; when editing an existing GitHub prerelease during that retarget flow, use a GitHub-accepted release target such as the intended branch name if the tool or API rejects a raw commit SHA for `target_commitish`; otherwise cut the release directly from `CHANGELOG.md` `Unreleased`, update versions and docs, commit, tag, push, and publish the GitHub release with actual release tooling rather than PR-surrogate directives; run git mutations sequentially and verify both the branch tip and release tag exist remotely before publishing the GitHub release.
|
|
18
|
+
- Execution: Use this workflow only for explicit release intent, run the required quality gates when applicable, and treat every conditional gate whose scenario is met as blocking before versioning or publication; hand the repository to `submission-readiness-check` before versioning work, invoke `archive-specs` directly whenever completed plan sets should be converted or project docs need alignment, and if the worktree is already clean inspect the current version, local/remote tag state, and existing GitHub release state before deciding whether the request is already satisfied; when the user explicitly wants the same prerelease version to point at newer fixes, retarget the existing prerelease tag and GitHub release instead of inventing an extra version bump; when editing an existing GitHub prerelease during that retarget flow, use a GitHub-accepted release target such as the intended branch name if the tool or API rejects a raw commit SHA for `target_commitish`; otherwise cut the release directly from `CHANGELOG.md` `Unreleased`, update versions and docs, commit, tag, push, and publish the GitHub release with actual release tooling rather than PR-surrogate directives; run git mutations sequentially and verify both the branch tip and release tag exist remotely before publishing the GitHub release, and never treat UI git directives such as `::git-stage`, `::git-commit`, or `::git-push` as evidence that the release commit or tag already exists.
|
|
19
19
|
- Quality: Never guess versions, align user-facing docs with actual code, do not bypass readiness blockers from `submission-readiness-check`, do not reconstruct release notes from `git diff` when curated changelog content already exists, and do not report release success until the commit, tag, and GitHub release all exist for the same version.
|
|
20
20
|
- Output: Produce a versioned release commit and tag, publish a matching GitHub release, and keep changelog plus relevant repository documentation synchronized.
|
|
21
21
|
|
|
@@ -92,6 +92,7 @@ Load only when needed:
|
|
|
92
92
|
- For new-version flows, create the version tag locally after commit.
|
|
93
93
|
- For prerelease retarget flows, move the existing tag locally only after the new fix commit exists, and verify the target commit hash before rewriting the tag.
|
|
94
94
|
- Re-read the version files after editing and before tagging to confirm they all match the intended release version.
|
|
95
|
+
- Use actual git mutations for staging, commit creation, and tag creation; do not substitute UI git directives for these steps.
|
|
95
96
|
9. Push
|
|
96
97
|
- Push commit(s) and the release tag to the current branch before publishing the GitHub release when the hosting platform requires the tag to exist remotely.
|
|
97
98
|
- For prerelease retarget flows, push the rewritten tag explicitly (for example `--force-with-lease` for the single tag only), then verify the remote tag hash matches local `HEAD` before touching the GitHub release.
|
|
@@ -117,5 +118,6 @@ Load only when needed:
|
|
|
117
118
|
- Never downgrade `discover-edge-cases` or `harden-app-security` to optional follow-up when the release risk says they apply.
|
|
118
119
|
- Never claim a release is complete without checking the actual release version, creating the matching tag, and publishing the matching GitHub release.
|
|
119
120
|
- Never treat a PR creation step, release-page URL guess, or tag-only push as evidence that the GitHub release exists.
|
|
121
|
+
- Never treat `::git-stage`, `::git-commit`, `::git-push`, or similar UI helpers as proof that the release commit, pushed tag, or remote branch update actually happened.
|
|
120
122
|
- If tests are required by repository conventions, run them before commit.
|
|
121
123
|
- If a new branch is required, follow `references/branch-naming.md`.
|