@laitszkin/apollo-toolkit 3.0.4 → 3.1.1

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 (29) hide show
  1. package/AGENTS.md +1 -0
  2. package/CHANGELOG.md +11 -0
  3. package/README.md +7 -2
  4. package/analyse-app-logs/scripts/__pycache__/filter_logs_by_time.cpython-312.pyc +0 -0
  5. package/analyse-app-logs/scripts/__pycache__/log_cli_utils.cpython-312.pyc +0 -0
  6. package/analyse-app-logs/scripts/__pycache__/search_logs.cpython-312.pyc +0 -0
  7. package/docs-to-voice/scripts/__pycache__/docs_to_voice.cpython-312.pyc +0 -0
  8. package/generate-spec/scripts/__pycache__/create-specscpython-312.pyc +0 -0
  9. package/iterative-code-quality/LICENSE +21 -0
  10. package/iterative-code-quality/README.md +30 -0
  11. package/iterative-code-quality/SKILL.md +153 -0
  12. package/iterative-code-quality/agents/openai.yaml +4 -0
  13. package/iterative-code-quality/references/iteration-gates.md +73 -0
  14. package/iterative-code-quality/references/logging-alignment.md +67 -0
  15. package/iterative-code-quality/references/module-boundaries.md +61 -0
  16. package/iterative-code-quality/references/naming-and-simplification.md +71 -0
  17. package/iterative-code-quality/references/repository-scan.md +59 -0
  18. package/iterative-code-quality/references/testing-strategy.md +78 -0
  19. package/katex/scripts/__pycache__/render_katex.cpython-312.pyc +0 -0
  20. package/lib/cli.js +22 -13
  21. package/lib/installer.js +61 -15
  22. package/open-github-issue/scripts/__pycache__/open_github_issue.cpython-312.pyc +0 -0
  23. package/package.json +1 -1
  24. package/read-github-issue/scripts/__pycache__/find_issues.cpython-312.pyc +0 -0
  25. package/read-github-issue/scripts/__pycache__/read_issue.cpython-312.pyc +0 -0
  26. package/resolve-review-comments/scripts/__pycache__/review_threads.cpython-312.pyc +0 -0
  27. package/scripts/install_skills.ps1 +16 -12
  28. package/scripts/install_skills.sh +19 -17
  29. package/text-to-short-video/scripts/__pycache__/enforce_video_aspect_ratio.cpython-312.pyc +0 -0
package/AGENTS.md CHANGED
@@ -53,6 +53,7 @@ This repository enables users to install and run a curated set of reusable agent
53
53
  - Users can investigate gated or shadow LLM APIs by capturing real client request shapes, replaying verified traffic patterns, and attributing the likely underlying model through black-box fingerprinting.
54
54
  - Users can build and maintain Solana programs and Rust clients using official Solana development workflows.
55
55
  - Users can add focused observability to opaque workflows through targeted logs, metrics, traces, and tests.
56
+ - Users can iteratively improve repository code quality through behavior-neutral naming, simplification, module-boundary, logging, and test-coverage passes.
56
57
  - Users can build against Jupiter's official Solana swap, token, price, lending, trigger, recurring, and portfolio APIs with an evidence-based development guide.
57
58
  - Users can render and embed math formulas with KaTeX using official documentation-backed guidance and reusable rendering scripts.
58
59
  - Users can debug software systematically by reproducing causes, validating fixes, and testing outcomes.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,17 @@ All notable changes to this repository are documented in this file.
7
7
  ### Changed
8
8
  - None yet.
9
9
 
10
+ ## [v3.1.1] - 2026-04-22
11
+
12
+ ### Changed
13
+ - Fix Apollo Toolkit installers so `codex`-only skills stay scoped to Codex targets, while shared skills continue to install across the selected destinations.
14
+ - Align the CLI welcome/help text, non-interactive guidance, and README examples with the supported `agents` target and current installer behavior.
15
+
16
+ ## [v3.1.0] - 2026-04-22
17
+
18
+ ### Added
19
+ - Add `iterative-code-quality`, a new repository-wide improvement skill that performs repeated behavior-neutral passes for naming cleanup, function simplification, module-boundary refactors, logging alignment, and risk-based test coverage, then synchronizes project docs and `AGENTS.md`.
20
+
10
21
  ## [v3.0.4] - 2026-04-22
11
22
 
12
23
  ### Changed
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
 
@@ -24,6 +24,7 @@ A curated skill catalog for Codex, OpenClaw, Trae, and Claude Code with a manage
24
24
  - harden-app-security
25
25
  - implement-specs
26
26
  - improve-observability
27
+ - iterative-code-quality
27
28
  - jupiter-development
28
29
  - katex
29
30
  - learn-skill-from-conversations
@@ -62,7 +63,7 @@ npx @laitszkin/apollo-toolkit
62
63
  The interactive installer:
63
64
  - shows a branded `Apollo Toolkit` terminal welcome screen with a short staged reveal
64
65
  - installs a managed copy into `~/.apollo-toolkit`
65
- - lets you multi-select `codex`, `openclaw`, `trae`, `claude-code`, or `all`
66
+ - lets you multi-select `codex`, `openclaw`, `trae`, `agents`, `claude-code`, or `all`
66
67
  - copies `~/.apollo-toolkit/<skill>` into each selected target
67
68
  - removes stale previously installed skill directories that existed in the previous installed version but no longer exist in the current package skill list
68
69
  - replaces legacy symlink-based installs created by older Apollo Toolkit installers with real copied directories
@@ -90,6 +91,7 @@ apltk open-github-issue --help
90
91
 
91
92
  ```bash
92
93
  npx @laitszkin/apollo-toolkit codex
94
+ npx @laitszkin/apollo-toolkit agents
93
95
  npx @laitszkin/apollo-toolkit claude-code
94
96
  npx @laitszkin/apollo-toolkit codex openclaw
95
97
  npx @laitszkin/apollo-toolkit all
@@ -102,6 +104,7 @@ APOLLO_TOOLKIT_HOME=~/custom-toolkit npx @laitszkin/apollo-toolkit codex
102
104
  CODEX_SKILLS_DIR=~/custom-codex-skills npx @laitszkin/apollo-toolkit codex
103
105
  OPENCLAW_HOME=~/.openclaw npx @laitszkin/apollo-toolkit openclaw
104
106
  TRAE_SKILLS_DIR=~/.trae/skills npx @laitszkin/apollo-toolkit trae
107
+ AGENTS_SKILLS_DIR=~/.agents/skills npx @laitszkin/apollo-toolkit agents
105
108
  CLAUDE_CODE_SKILLS_DIR=~/.claude/skills npx @laitszkin/apollo-toolkit claude-code
106
109
  ```
107
110
 
@@ -119,12 +122,14 @@ Installers still live in `scripts/` for local repository usage and curl / iwr in
119
122
  ./scripts/install_skills.sh codex
120
123
  ./scripts/install_skills.sh openclaw
121
124
  ./scripts/install_skills.sh trae
125
+ ./scripts/install_skills.sh agents
122
126
  ./scripts/install_skills.sh all
123
127
  ```
124
128
 
125
129
  ```powershell
126
130
  ./scripts/install_skills.ps1
127
131
  ./scripts/install_skills.ps1 codex
132
+ ./scripts/install_skills.ps1 agents
128
133
  ./scripts/install_skills.ps1 all
129
134
  ```
130
135
 
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 LaiTszKin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,30 @@
1
+ # iterative-code-quality
2
+
3
+ Improve an existing repository through repeated, evidence-backed code-quality passes while preserving intended business behavior and macro architecture.
4
+
5
+ ## Core capabilities
6
+
7
+ - Scans the full codebase and builds a prioritized quality backlog before editing.
8
+ - Clarifies ambiguous variable, parameter, field, helper, and test-data names.
9
+ - Simplifies complex functions and extracts reusable helpers only when they centralize real behavior.
10
+ - Splits mixed-responsibility code into narrower modules without changing macro architecture.
11
+ - Repairs stale or missing logs and adds tests for important observability contracts.
12
+ - Adds high-value unit, property-based, integration, or E2E tests based on risk.
13
+ - Repeats the pass cycle until remaining issues are low-value, blocked, or require explicit product/architecture approval.
14
+ - Synchronizes project docs and `AGENTS.md` through `align-project-documents` and `maintain-project-constraints` after implementation.
15
+
16
+ ## Repository structure
17
+
18
+ - `SKILL.md`: Main iterative workflow, dependencies, guardrails, and output contract.
19
+ - `agents/openai.yaml`: Agent interface metadata and default prompt.
20
+ - `references/`: Focused guides for scanning, naming, simplification, module boundaries, logging, testing, and iteration gates.
21
+
22
+ ## Typical usage
23
+
24
+ ```text
25
+ Use $iterative-code-quality to improve this repository's code quality end to end without changing business behavior or macro architecture.
26
+ ```
27
+
28
+ ## License
29
+
30
+ MIT. See `LICENSE`.
@@ -0,0 +1,153 @@
1
+ ---
2
+ name: iterative-code-quality
3
+ description: >-
4
+ Improve an existing codebase through repeated evidence-based code-quality
5
+ passes: clarify poor variable names, simplify or extract reusable functions,
6
+ split oversized code into single-responsibility modules, repair stale or
7
+ missing logs, and add high-value tests while preserving business behavior and
8
+ macro architecture. Use when users ask for comprehensive refactoring, code
9
+ cleanup, maintainability hardening, naming cleanup, log alignment, or test
10
+ coverage improvement across a repository.
11
+ ---
12
+
13
+ # Iterative Code Quality
14
+
15
+ ## Dependencies
16
+
17
+ - Required: `align-project-documents` and `maintain-project-constraints` after implementation changes are complete.
18
+ - Conditional: `systematic-debug` when a new or existing test reveals a real business-logic defect that must be fixed.
19
+ - Optional: `discover-edge-cases` for high-risk boundary exploration before choosing missing tests; `improve-observability` for complex telemetry design.
20
+ - Fallback: If required completion dependencies are unavailable, finish code and tests, then report exactly which documentation or constraint sync step could not run.
21
+
22
+ ## Standards
23
+
24
+ - Evidence: Read repository docs, project constraints, source, tests, logs, and entrypoints before editing; every rename, extraction, split, log update, or test must be backed by code context.
25
+ - Execution: Work in bounded passes, prioritize behavior-neutral improvements with the highest maintainability and test value, validate after each pass, and repeat until the remaining quality gaps are low-value or unsafe to change.
26
+ - Quality: Preserve business behavior and macro architecture unless tests expose an existing logic defect; avoid style-only churn, compatibility theater, broad rewrites, and unverified "cleanup".
27
+ - Output: Deliver a concise pass-by-pass summary, changed behavior-neutral surfaces, test coverage added, validation results, unresolved risks, and documentation/`AGENTS.md` sync status.
28
+
29
+ ## Goal
30
+
31
+ Raise code quality across an existing repository without changing intended product behavior or the system's macro architecture.
32
+
33
+ This skill is intentionally implementation-oriented, not report-only. It should identify high-value improvements, apply them, test them, and keep iterating until further changes would be speculative, low-value, or architecture-changing.
34
+
35
+ ## Required Reference Loading
36
+
37
+ Load references only when they match the active pass:
38
+
39
+ - `references/repository-scan.md`: scope mapping, generated-file exclusions, and quality backlog selection.
40
+ - `references/naming-and-simplification.md`: variable renames, function simplification, reusable extraction, and behavior-preservation checks.
41
+ - `references/module-boundaries.md`: single-responsibility split heuristics and safe module extraction rules.
42
+ - `references/logging-alignment.md`: stale log detection, missing log criteria, and behavior-neutral observability updates.
43
+ - `references/testing-strategy.md`: risk-based unit, property, integration, and E2E coverage selection.
44
+ - `references/iteration-gates.md`: multi-pass quality gates, stopping criteria, and validation cadence.
45
+
46
+ ## Workflow
47
+
48
+ ### 1) Establish the repository baseline
49
+
50
+ - Read root guidance first: `AGENTS.md`, `README*`, major docs, package manifests, task runners, CI configs, and test setup.
51
+ - Map runtime entrypoints, domain modules, external integrations, logging/telemetry utilities, and existing test suites.
52
+ - Identify generated, vendored, lock, build-output, fixture, or snapshot files; exclude them from refactoring unless evidence shows they are human-maintained source.
53
+ - Run or inspect the most relevant existing validation commands before editing when feasible, so pre-existing failures are distinguishable from new regressions.
54
+ - Build an initial quality backlog with concrete file/function/test targets before changing code.
55
+ - Use `references/repository-scan.md` for the scan checklist and backlog scoring.
56
+
57
+ ### 2) Execute bounded improvement passes
58
+
59
+ Run focused passes in the order that fits the repository evidence. A typical order is:
60
+
61
+ 1. Naming clarity for variables, parameters, fields, local helpers, and test data.
62
+ 2. Function simplification and reusable extraction for duplicated or hard-coded workflows.
63
+ 3. Single-responsibility module splits for oversized or mixed-concern code.
64
+ 4. Logging alignment for stale, misleading, missing, or low-context diagnostics.
65
+ 5. Risk-based test coverage for high-value business logic and boundary cases.
66
+
67
+ For each pass:
68
+
69
+ - Read all directly affected callers, tests, and public interfaces before editing.
70
+ - Keep the pass small enough to validate and review; split broad cleanups into multiple passes.
71
+ - Prefer repository-native abstractions over new parallel frameworks.
72
+ - Preserve public behavior, data contracts, side effects, error classes, and macro architecture.
73
+ - Add or update tests in the same pass when the change touches non-trivial logic, observability contracts, or extracted helpers.
74
+ - Validate the touched scope before starting another pass.
75
+
76
+ ### 3) Rename for clarity without churn
77
+
78
+ - Rename only when the current name hides domain meaning, confuses ownership, conflicts with real units, or makes tests/logs misleading.
79
+ - Prefer names that encode domain role, unit, lifecycle stage, or canonical owner.
80
+ - Update all references, tests, fixtures, structured log fields, docs, and comments that describe the renamed concept.
81
+ - Avoid renaming stable public API fields or persisted schema names unless the user explicitly requested a breaking migration.
82
+ - Use `references/naming-and-simplification.md` before broad rename passes.
83
+
84
+ ### 4) Simplify and extract reusable functions
85
+
86
+ - Simplify functions when branches, temporary state, repeated transformations, or hard-coded workflows obscure the invariant.
87
+ - Extract helpers only when they reduce duplication, centralize one business rule, clarify caller intent, or make a behavior testable.
88
+ - Keep helper placement aligned with current module ownership.
89
+ - Do not create abstractions for one-off code unless they isolate a meaningful domain rule or external contract.
90
+ - Preserve observable behavior unless a test proves the current behavior is a defect.
91
+
92
+ ### 5) Split modules by responsibility
93
+
94
+ - Split code only when one file/module owns multiple change reasons, domain boundaries, external integrations, or lifecycle stages.
95
+ - Define the new module's responsibility before moving code.
96
+ - Keep interfaces narrow, explicit, and consistent with existing project style.
97
+ - Avoid macro-architecture changes such as new layers, new service boundaries, new persistence strategies, or framework swaps unless the user explicitly expands scope.
98
+ - Use `references/module-boundaries.md` for extraction rules and anti-patterns.
99
+
100
+ ### 6) Repair logging and observability drift
101
+
102
+ - Compare log messages, event names, structured fields, metrics, and trace names against the current code ownership model.
103
+ - Fix stale terminology after renames or refactors so logs describe the live workflow.
104
+ - Add logs only at high-value decision points: branch selection, skipped work, external dependency outcome, persistence side effect, retry/rollback, and final outcome.
105
+ - Use structured fields already accepted by the project; never log secrets, tokens, full sensitive payloads, or personal data.
106
+ - Add tests or assertions for important log fields when the project has log-capture helpers.
107
+ - Use `references/logging-alignment.md` for detailed criteria.
108
+
109
+ ### 7) Add high-value tests
110
+
111
+ - Start from risk, not coverage percentage.
112
+ - Prioritize tests for business rules, state transitions, error handling, extracted helpers, edge cases, observability contracts, and integration boundaries.
113
+ - Use unit tests for local logic, property-based tests for invariants and generated input spaces, integration tests for cross-module chains, and E2E tests only when external services are stable or can be controlled reliably.
114
+ - Mock or fake external services unless the real service contract is the subject under test.
115
+ - If a new test exposes an existing business-logic bug, invoke `systematic-debug`, fix the true owner, and keep the regression test.
116
+ - Use `references/testing-strategy.md` for coverage selection and required `N/A` reasoning.
117
+
118
+ ### 8) Iterate until quality gates pass
119
+
120
+ - After each pass, run the narrowest relevant tests first, then broaden validation when confidence increases.
121
+ - Re-scan touched areas for new naming drift, duplicated helper candidates, module-boundary cracks, logging drift, and missing tests.
122
+ - Repeat the full pass cycle when significant gaps remain and can be fixed safely without changing business behavior or macro architecture.
123
+ - Stop only when remaining issues are low-value, speculative, blocked, or require explicit product/architecture approval.
124
+ - Use `references/iteration-gates.md` for stopping criteria.
125
+
126
+ ### 9) Synchronize docs and constraints
127
+
128
+ After code and tests are complete:
129
+
130
+ - Invoke `align-project-documents` when README, docs, architecture notes, debugging docs, setup instructions, or test guidance may have drifted.
131
+ - Invoke `maintain-project-constraints` to verify `AGENTS.md` still reflects architecture, business flow, common commands, macro purpose, and coding conventions.
132
+ - Update only documentation that is affected by real code, command, logging, or test changes.
133
+
134
+ ## Hard Guardrails
135
+
136
+ - Do not change intended business logic while refactoring.
137
+ - Do not change macro architecture, framework choice, storage model, deployment model, or service boundaries unless the user explicitly approves that expanded scope.
138
+ - Do not use one-off scripts to rewrite product code.
139
+ - Do not perform style-only churn that does not improve naming, reuse, modularity, observability, or test confidence.
140
+ - Do not weaken tests to make refactors pass; update tests to stable invariants or fix the implementation defect.
141
+ - Do not add E2E tests that depend on unreliable external services when a controlled integration test can prove the same business risk.
142
+
143
+ ## Completion Report
144
+
145
+ Return:
146
+
147
+ 1. Passes completed and why they were ordered that way.
148
+ 2. Key files changed and the quality issue each change resolved.
149
+ 3. Business behavior preservation evidence.
150
+ 4. Tests added or updated, including property/integration/E2E `N/A` reasons where relevant.
151
+ 5. Validation commands and results.
152
+ 6. Documentation and `AGENTS.md` synchronization status.
153
+ 7. Remaining quality gaps, blockers, or deferred architecture/product decisions.
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Iterative Code Quality"
3
+ short_description: "Refactor names, functions, modules, logs, and tests in repeated behavior-safe passes"
4
+ default_prompt: "Use $iterative-code-quality to scan this repository, build an evidence-backed quality backlog, then iteratively clarify variable names, simplify or extract reusable functions, split code into single-responsibility modules, repair stale or missing logs, and add high-value unit/property/integration/E2E tests while preserving business behavior and macro architecture; after code and tests are complete, run $align-project-documents and $maintain-project-constraints to synchronize docs and AGENTS.md."
@@ -0,0 +1,73 @@
1
+ # Iteration Gates And Stopping Criteria
2
+
3
+ ## Pass discipline
4
+
5
+ Each pass must have:
6
+
7
+ - a concrete quality target,
8
+ - a bounded file/symbol scope,
9
+ - expected behavior-neutral outcome,
10
+ - validation plan,
11
+ - rollback point if evidence contradicts the change.
12
+
13
+ Avoid starting a broad second pass before validating the first.
14
+
15
+ ## Validation cadence
16
+
17
+ Run validation from narrow to broad:
18
+
19
+ 1. Formatter or type check for touched files when available.
20
+ 2. Unit tests for touched helpers and modules.
21
+ 3. Integration tests for affected chains.
22
+ 4. Broader suite or build once multiple passes interact.
23
+
24
+ If validation fails:
25
+
26
+ - determine whether the failure is pre-existing, stale test expectation, test isolation issue, or real product bug,
27
+ - fix the true owner,
28
+ - keep regression coverage for real defects,
29
+ - do not mask failures by weakening assertions.
30
+
31
+ ## Re-scan after each pass
32
+
33
+ Inspect touched areas for:
34
+
35
+ - new naming drift from moved or extracted concepts,
36
+ - duplicated logic that remains after extraction,
37
+ - module boundaries that are still mixed,
38
+ - logs that now use stale names,
39
+ - tests that cover only the happy path,
40
+ - documentation or `AGENTS.md` drift.
41
+
42
+ ## Continue when
43
+
44
+ Repeat the cycle when:
45
+
46
+ - high-impact unclear names remain,
47
+ - duplicated or hard-coded workflows still have safe extraction paths,
48
+ - a module still mixes distinct responsibilities and can be split locally,
49
+ - logs are still misleading or missing at critical decisions,
50
+ - high-value business logic remains untested and is testable.
51
+
52
+ ## Stop when
53
+
54
+ Stop when remaining candidates are:
55
+
56
+ - low-value style preference,
57
+ - speculative without concrete evidence,
58
+ - public contract migrations,
59
+ - macro-architecture changes,
60
+ - product behavior changes needing user approval,
61
+ - blocked by unavailable credentials, unstable external systems, or missing documentation,
62
+ - untestable with the current repository tooling and too risky to change safely.
63
+
64
+ ## Completion evidence
65
+
66
+ The final report should make the stopping point auditable:
67
+
68
+ - passes completed,
69
+ - validation commands and outcomes,
70
+ - tests added by risk category,
71
+ - behavior-preservation evidence,
72
+ - docs and constraints sync status,
73
+ - deferred items with reason and required approval or dependency.
@@ -0,0 +1,67 @@
1
+ # Logging Alignment And Missing Observability
2
+
3
+ ## Purpose
4
+
5
+ Keep logs and diagnostics synchronized with the real code path while preserving behavior.
6
+
7
+ ## Stale log signals
8
+
9
+ Update logs when they:
10
+
11
+ - mention retired owners, lifecycle stages, resource names, or field names,
12
+ - describe a branch that no longer matches the condition,
13
+ - use generic text like `failed` without the operation or reason,
14
+ - report aggregate success without identifiers that let operators reconcile details,
15
+ - keep compatibility-era names after code has moved to a new canonical model,
16
+ - conflict with structured field names or metrics in the same path.
17
+
18
+ ## Missing log criteria
19
+
20
+ Add logs only where they answer a concrete debugging question.
21
+
22
+ High-value locations:
23
+
24
+ - workflow start and final outcome for long-running jobs,
25
+ - branch selection or skipped work with reason code,
26
+ - validation rejection with safe context,
27
+ - external dependency outcome including status class, retry count, request id, and latency when available,
28
+ - persistence side effect or emitted command,
29
+ - rollback, compensation, idempotency, duplicate, or replay decisions.
30
+
31
+ Low-value locations:
32
+
33
+ - every line of a tight loop,
34
+ - logs that only restate the function name,
35
+ - dumping raw payloads,
36
+ - duplicating an exception already logged with equal context,
37
+ - noisy success logs in hot paths without operational value.
38
+
39
+ ## Structured field rules
40
+
41
+ - Reuse the project's existing logger, field naming, metric naming, and trace conventions.
42
+ - Prefer stable identifiers, counts, reason codes, status classes, and lifecycle stages.
43
+ - Keep field names aligned with canonical owners, not stale compatibility projections.
44
+ - Do not log secrets, tokens, private keys, passwords, raw personal data, or full sensitive payloads.
45
+ - Avoid high-cardinality values unless they are necessary identifiers already used by the project.
46
+
47
+ ## Behavior-neutral updates
48
+
49
+ Logging changes must not:
50
+
51
+ - alter retry, error, persistence, or branch behavior,
52
+ - swallow exceptions,
53
+ - add blocking network calls,
54
+ - create expensive serialization in hot paths,
55
+ - change public output unless logs are the product output.
56
+
57
+ ## Tests
58
+
59
+ Add or update tests when:
60
+
61
+ - the project already captures logs in tests,
62
+ - branch-specific reason codes matter,
63
+ - stale field names were renamed,
64
+ - extracted helpers need observability contracts,
65
+ - aggregate and detail telemetry must stay reconcilable.
66
+
67
+ Assert stable fields and event names, not timestamps or full formatted strings.
@@ -0,0 +1,61 @@
1
+ # Module Boundary And Single Responsibility Refactoring
2
+
3
+ ## When to split a module
4
+
5
+ Split only when the module has multiple independent reasons to change, such as:
6
+
7
+ - domain rules mixed with IO, formatting, CLI parsing, or external service calls,
8
+ - unrelated workflows sharing one file because of history, not ownership,
9
+ - test setup forced to instantiate unrelated dependencies,
10
+ - large files where local changes frequently touch distant concepts,
11
+ - circular or awkward imports caused by unclear ownership,
12
+ - logging, validation, persistence, and presentation all living in one function or class.
13
+
14
+ ## Before splitting
15
+
16
+ Define:
17
+
18
+ - the current module's actual responsibilities,
19
+ - the target responsibility of each new module,
20
+ - which module owns the canonical business rule,
21
+ - which interfaces must remain stable,
22
+ - which tests prove behavior did not change.
23
+
24
+ ## Safe split patterns
25
+
26
+ - Move pure domain logic into a domain-owned helper module.
27
+ - Move external adapter code into an integration or infrastructure-adjacent module if the repository already uses that boundary.
28
+ - Move formatting/reporting away from computation.
29
+ - Move test helpers into existing test utility locations rather than production modules.
30
+ - Keep orchestration modules thin: validate inputs, call owners, handle outcomes.
31
+
32
+ ## Interface design
33
+
34
+ Use narrow interfaces:
35
+
36
+ - pass only data the callee needs,
37
+ - return explicit result objects or existing domain types,
38
+ - avoid leaking framework/request/database objects into pure domain modules,
39
+ - preserve existing error taxonomy,
40
+ - keep naming aligned with current project vocabulary.
41
+
42
+ ## Anti-patterns
43
+
44
+ Avoid:
45
+
46
+ - creating a generic `utils` dumping ground,
47
+ - moving code only to reduce file length,
48
+ - adding new layers that duplicate existing architecture,
49
+ - introducing dependency injection frameworks or service locators without explicit approval,
50
+ - splitting tightly coupled state machines before defining the state owner,
51
+ - changing public boundaries during a cleanup pass.
52
+
53
+ ## Validation checklist
54
+
55
+ After a split:
56
+
57
+ - imports remain acyclic or no worse than before,
58
+ - public entrypoints still call the same behavior,
59
+ - tests cover moved logic and orchestration glue,
60
+ - logs still carry the same correlation identifiers,
61
+ - docs or `AGENTS.md` are updated only if the visible architecture or command surface changed.
@@ -0,0 +1,71 @@
1
+ # Naming And Function Simplification
2
+
3
+ ## Naming improvements
4
+
5
+ Rename only when the current name creates real ambiguity.
6
+
7
+ Good rename reasons:
8
+
9
+ - hides domain role, unit, quantity, ownership, or lifecycle stage,
10
+ - uses stale terminology after a refactor,
11
+ - collides with another concept in the same scope,
12
+ - makes boolean, enum, or state-transition meaning unclear,
13
+ - forces readers to inspect implementation before understanding intent.
14
+
15
+ Avoid renaming when:
16
+
17
+ - the name is already clear in local context,
18
+ - the change is pure personal preference,
19
+ - the name is part of a stable external API, database schema, event contract, or migration-sensitive field,
20
+ - the rename would create broad churn without reducing ambiguity.
21
+
22
+ ## Naming patterns
23
+
24
+ - Prefer domain nouns over implementation nouns: `selectedAccount` over `item`.
25
+ - Include units for quantities: `timeoutMs`, `amountCents`, `windowDays`.
26
+ - Use booleans that read as predicates: `isEligible`, `hasPendingRetry`, `shouldPersist`.
27
+ - Name collections by contents: `pendingInvoices`, not `list`.
28
+ - Name state transitions by lifecycle: `markSettlementComplete`, not `updateStatus`.
29
+ - Keep test data names meaningful: `expiredSubscription`, `duplicateEvent`, `unauthorizedActor`.
30
+
31
+ ## Function simplification signals
32
+
33
+ Simplify functions that contain:
34
+
35
+ - repeated guard clauses or duplicated validation,
36
+ - mixed parsing, validation, orchestration, persistence, and formatting,
37
+ - nested branches that hide the main path,
38
+ - temporary variables whose names encode implementation steps rather than domain state,
39
+ - hard-coded workflow steps repeated in multiple callers,
40
+ - comments explaining what code structure should make obvious.
41
+
42
+ ## Safe simplification moves
43
+
44
+ - Extract pure transformations and validations into small helpers.
45
+ - Replace repeated literal mappings with a named table or function.
46
+ - Flatten nested conditionals with explicit guard clauses when it clarifies failure paths.
47
+ - Centralize one business rule behind one function when multiple callers duplicate it.
48
+ - Split orchestration from local computation when tests need a deterministic unit.
49
+ - Delete dead compatibility paths only when reachability evidence and tests support deletion.
50
+
51
+ ## Extraction rules
52
+
53
+ Create a reusable helper only when at least one condition is true:
54
+
55
+ - two or more call sites duplicate the same rule,
56
+ - the extracted logic has a clear domain name and stable contract,
57
+ - the helper makes a high-value invariant testable,
58
+ - the helper isolates an external dependency contract or side-effect boundary,
59
+ - the current function has multiple reasons to change.
60
+
61
+ Keep extracted helpers close to the owner module unless the repository already has a shared utility location for that domain.
62
+
63
+ ## Behavior preservation checklist
64
+
65
+ Before and after simplification, verify:
66
+
67
+ - inputs, outputs, exceptions, side effects, and ordering are unchanged,
68
+ - persisted data and emitted events keep the same contract,
69
+ - public API and CLI behavior remain stable,
70
+ - log fields remain compatible unless stale names were intentionally corrected,
71
+ - existing tests still pass and new tests cover extracted rules.
@@ -0,0 +1,59 @@
1
+ # Repository Scan And Backlog Selection
2
+
3
+ ## Purpose
4
+
5
+ Build a factual map before changing code, then choose the highest-value quality improvements.
6
+
7
+ ## Required scan
8
+
9
+ - Read `AGENTS.md`, `README*`, project docs, manifests, task runners, CI configs, and test setup.
10
+ - List entrypoints: CLI commands, servers, workers, jobs, frontend routes, scripts, libraries, or public packages.
11
+ - Identify core domain modules, external integrations, persistence boundaries, logging utilities, and test helpers.
12
+ - Inspect current git state before editing so unrelated user changes are not overwritten.
13
+ - Identify generated, vendored, lock, snapshot, build-output, and fixture files; exclude them from refactoring unless they are human-maintained source.
14
+
15
+ ## Code quality backlog signals
16
+
17
+ Prioritize files or functions with:
18
+
19
+ - high fan-in or many call sites,
20
+ - critical business rules or money/security/data-integrity decisions,
21
+ - duplicated condition trees, conversions, validation, or external-call choreography,
22
+ - unclear naming around ownership, units, state, or lifecycle,
23
+ - large functions that mix parsing, validation, orchestration, side effects, and formatting,
24
+ - log messages that describe old concepts or omit branch/failure context,
25
+ - low or missing tests around meaningful invariants and edge cases.
26
+
27
+ ## Evidence to capture
28
+
29
+ For each candidate record:
30
+
31
+ - file path and symbol name,
32
+ - observed quality problem,
33
+ - why it matters to maintainability or correctness confidence,
34
+ - expected behavior-neutral change,
35
+ - tests or validations needed to prove safety,
36
+ - reason to defer if the candidate requires product or architecture approval.
37
+
38
+ ## Exclusion rules
39
+
40
+ Do not refactor:
41
+
42
+ - third-party, generated, or compiled artifacts,
43
+ - snapshots where churn would hide signal,
44
+ - code the user marked as actively edited elsewhere,
45
+ - public schema/API names that require migration planning,
46
+ - areas that cannot be validated and are not causing a clear quality risk.
47
+
48
+ ## Backlog scoring
49
+
50
+ Prefer a small set of high-confidence improvements over an exhaustive sweep.
51
+
52
+ Score each candidate by:
53
+
54
+ 1. **Impact**: criticality, call frequency, future change risk.
55
+ 2. **Confidence**: evidence that the change is behavior-neutral.
56
+ 3. **Validation**: ability to test or otherwise prove equivalence.
57
+ 4. **Blast radius**: number of modules, public contracts, and migrations affected.
58
+
59
+ Start with high-impact, high-confidence, low-blast-radius items. Escalate broad changes only when smaller passes cannot resolve the root problem.
@@ -0,0 +1,78 @@
1
+ # Risk-Based Testing Strategy
2
+
3
+ ## Principle
4
+
5
+ Choose tests from the risk inventory, not from a generic coverage target.
6
+
7
+ For every non-trivial pass, ask what could regress silently if the cleanup were wrong.
8
+
9
+ ## Unit tests
10
+
11
+ Use for:
12
+
13
+ - extracted helpers,
14
+ - renamed or simplified business rules,
15
+ - validation and rejection logic,
16
+ - branch-specific errors and side effects,
17
+ - formatting or parsing boundaries.
18
+
19
+ Good oracles:
20
+
21
+ - exact return values,
22
+ - exact domain state transitions,
23
+ - exact error class or reason code,
24
+ - emitted side effect or explicit lack of side effect.
25
+
26
+ ## Property-based tests
27
+
28
+ Use when logic has invariants or broad input space:
29
+
30
+ - serialization or parsing round trips,
31
+ - sorting, grouping, deduplication, aggregation,
32
+ - authorization or eligibility predicates,
33
+ - idempotency, retry, replay, and state-machine transitions,
34
+ - generated mocked external-service states.
35
+
36
+ Record `N/A` only with a concrete reason, such as "no generated input space; pass only renamed local variables."
37
+
38
+ ## Integration tests
39
+
40
+ Use when the risk spans modules:
41
+
42
+ - orchestration calling extracted domain helpers,
43
+ - persistence plus domain transition,
44
+ - API/CLI handler plus service layer,
45
+ - logging contract across a real execution path,
46
+ - adapter behavior with mocked external services.
47
+
48
+ For external services, prefer mocks, fakes, local emulators, or recorded stable fixtures unless the real contract is explicitly under test.
49
+
50
+ ## E2E tests
51
+
52
+ Use only when:
53
+
54
+ - the project already has reliable E2E infrastructure,
55
+ - the path is user-critical,
56
+ - required external services are stable, controlled, or safely mocked,
57
+ - the same confidence cannot be gained from faster integration tests.
58
+
59
+ If E2E is unreliable or too costly, add stronger integration coverage and state the reason.
60
+
61
+ ## Edge and adversarial coverage
62
+
63
+ Consider:
64
+
65
+ - null, empty, malformed, duplicate, oversized, and boundary inputs,
66
+ - unauthorized actors and invalid transitions,
67
+ - stale, duplicate, out-of-order, or replayed events,
68
+ - dependency timeout, 429/500, partial response, and inconsistent response,
69
+ - partial write, rollback, compensation, and idempotency behavior,
70
+ - concurrency or shared-state contamination when the code is stateful.
71
+
72
+ ## Test hygiene
73
+
74
+ - Keep tests deterministic and close to the behavior owner.
75
+ - Prefer table-driven cases for many similar business permutations.
76
+ - Preserve failing seeds or examples from property-based tests.
77
+ - Do not weaken existing tests to fit the refactor.
78
+ - If old tests asserted implementation details, rewrite them around stable behavior while preserving the business invariant.
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
- { id: 'codex', label: 'Codex', description: '~/.codex/skills' },
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
- ` ${color('Codex', '1', colorEnabled)} ~/.codex/skills`,
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
- ' apltk [install] [codex|openclaw|trae|agents|claude-code|all]...',
127
- ' apollo-toolkit [install] [codex|openclaw|trae|agents|claude-code|all]...',
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('Interactive install requires a TTY. Re-run with targets like `codex`, `openclaw`, `trae`, `claude-code`, or `all`.');
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 VALID_MODES = ['codex', 'openclaw', 'trae', 'agents', 'claude-code'];
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.push(entry.name);
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.push(entry.name);
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 skillNames = await listSkillNames(toolkitHome, normalizedModes);
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 skillNames) {
279
- // For codex skills, use the ./codex/ subdirectory as source
280
- let sourcePath;
281
- if (normalizedModes.includes('codex') && fs.existsSync(path.join(toolkitHome, 'codex', skillName))) {
282
- sourcePath = path.join(toolkitHome, 'codex', skillName);
283
- } else {
284
- sourcePath = path.join(toolkitHome, skillName);
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,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@laitszkin/apollo-toolkit",
3
- "version": "3.0.4",
3
+ "version": "3.1.1",
4
4
  "description": "Apollo Toolkit npm installer for managed skill copying across Codex, OpenClaw, and Trae.",
5
5
  "license": "MIT",
6
6
  "author": "LaiTszKin",
@@ -110,15 +110,16 @@ else {
110
110
  $RepoRoot = $ToolkitHome
111
111
  }
112
112
 
113
- function Get-SkillPaths {
113
+ function Get-SkillPathGroups {
114
114
  param([string[]]$SelectedModes)
115
115
 
116
116
  $dirs = Get-ChildItem -Path $RepoRoot -Directory | Sort-Object Name
117
- $skills = @()
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
- $skills += $dir.FullName
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
- $skills += $dir.FullName
133
+ $codexSkills += $dir.FullName
133
134
  }
134
135
  }
135
136
  }
136
137
  }
137
138
 
138
- if ($skills.Count -eq 0) {
139
+ if ($sharedSkills.Count -eq 0) {
139
140
  throw "No skill folders found in: $RepoRoot"
140
141
  }
141
142
 
142
- return $skills
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
- $skillPaths = Get-SkillPaths -SelectedModes $selectedModes
350
+ $skillPathGroups = Get-SkillPathGroups -SelectedModes $selectedModes
347
351
 
348
352
  foreach ($mode in $selectedModes) {
349
353
  switch ($mode) {
350
- "codex" { Install-Codex -SkillPaths $skillPaths }
351
- "openclaw" { Install-OpenClaw -SkillPaths $skillPaths }
352
- "trae" { Install-Trae -SkillPaths $skillPaths }
353
- "agents" { Install-Agents -SkillPaths $skillPaths }
354
- "claude-code" { Install-ClaudeCode -SkillPaths $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
- SKILL_PATHS=()
81
+ SHARED_SKILL_PATHS=()
82
+ CODEX_SKILL_PATHS=()
82
83
 
83
84
  collect_skills() {
84
85
  local dir
85
- SKILL_PATHS=()
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
- SKILL_PATHS+=("$dir")
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
- SKILL_PATHS+=("$dir")
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 [[ ${#SKILL_PATHS[@]} -eq 0 ]]; then
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 "${SKILL_PATHS[@]}"; do
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 "${SKILL_PATHS[@]}"; do
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 "${SKILL_PATHS[@]}"; do
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 "${SKILL_PATHS[@]}"; do
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 "${SKILL_PATHS[@]}"; do
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