@mmerterden/multi-agent-pipeline 14.2.2 → 15.0.0
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 +76 -6
- package/README.md +15 -8
- package/README.tr.md +15 -8
- package/docs/FIGMA_PIPELINE.md +3 -3
- package/docs/adr/0006-skills-core-external-split.md +1 -1
- package/docs/adr/0009-claude-stack-skills-plugin-only.md +31 -0
- package/docs/adr/README.md +1 -0
- package/docs/architecture.md +7 -7
- package/docs/ecosystem.md +28 -28
- package/docs/features.md +5 -5
- package/index.js +2 -0
- package/install/_codex-agents.mjs +11 -2
- package/install/_common.mjs +65 -1
- package/install/_dev-only-files.mjs +0 -1
- package/install/_platform-filter.mjs +73 -7
- package/install/_plugin-skills.mjs +19 -8
- package/install/claude.mjs +144 -59
- package/install/codex.mjs +28 -3
- package/install/copilot.mjs +36 -11
- package/install/index.mjs +6 -2
- package/install/templates/codex-instructions.md +1 -1
- package/install/templates/copilot-instructions.md +3 -3
- package/package.json +1 -2
- package/pipeline/commands/multi-agent/SKILL.md +2 -0
- package/pipeline/commands/multi-agent/analysis/SKILL.md +3 -3
- package/pipeline/commands/multi-agent/analysis-resolve/SKILL.md +2 -2
- package/pipeline/commands/multi-agent/build-optimize/SKILL.md +9 -9
- package/pipeline/commands/multi-agent/channels/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/complaint-analysis/SKILL.md +186 -0
- package/pipeline/commands/multi-agent/dev/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/dev-autopilot/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/dev-local/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/dev-local-autopilot/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/garbage-collect/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/help/SKILL.md +19 -4
- package/pipeline/commands/multi-agent/ios-coding-standard/SKILL.md +2 -2
- package/pipeline/commands/multi-agent/jira/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/prune-prompts/SKILL.md +81 -0
- package/pipeline/commands/multi-agent/resume/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/{ship → resume-local}/SKILL.md +8 -8
- package/pipeline/commands/multi-agent/setup/SKILL.md +5 -5
- package/pipeline/commands/multi-agent/stack/SKILL.md +55 -43
- package/pipeline/commands/multi-agent/store-ready/SKILL.md +3 -3
- package/pipeline/commands/multi-agent/sync/SKILL.md +18 -11
- package/pipeline/commands/multi-agent/testflight-validation/SKILL.md +1 -1
- package/pipeline/commands/multi-agent/uninstall/SKILL.md +2 -0
- package/pipeline/commands/multi-agent/update/SKILL.md +1 -1
- package/pipeline/lib/issue-fetcher.sh +1 -1
- package/pipeline/lib/parse-complaints.sh +306 -0
- package/pipeline/multi-agent-refs/channels/wiki.md +3 -3
- package/pipeline/multi-agent-refs/complaint-analysis-template.md +99 -0
- package/pipeline/multi-agent-refs/component-dispatch.md +6 -6
- package/pipeline/multi-agent-refs/cross-cli-contract.md +16 -16
- package/pipeline/multi-agent-refs/features/external-context-injection.md +1 -1
- package/pipeline/multi-agent-refs/features/stack-skill-routing.md +5 -5
- package/pipeline/multi-agent-refs/generate-issue.md +1 -1
- package/pipeline/multi-agent-refs/phases/modes.md +1 -1
- package/pipeline/multi-agent-refs/phases/phase-0-init.md +1 -1
- package/pipeline/multi-agent-refs/phases/phase-1-analysis.md +7 -7
- package/pipeline/multi-agent-refs/phases/phase-2-planning.md +5 -5
- package/pipeline/multi-agent-refs/phases/phase-3-dev.md +3 -3
- package/pipeline/multi-agent-refs/phases/phase-4-review.md +12 -12
- package/pipeline/multi-agent-refs/phases/phase-5-test.md +1 -1
- package/pipeline/multi-agent-refs/tracker-contract.md +1 -1
- package/pipeline/multi-agent-refs/wiki-capture.md +2 -2
- package/pipeline/preferences-template.json +13 -5
- package/pipeline/rules/figma-pipeline.md +2 -2
- package/pipeline/schemas/agent-state.schema.json +1 -1
- package/pipeline/schemas/complaint-analysis-spec.schema.json +216 -0
- package/pipeline/schemas/migrations/prefs-2.5.0-to-2.6.0.mjs +46 -0
- package/pipeline/schemas/prefs.schema.json +276 -66
- package/pipeline/schemas/token-budget.json +2 -2
- package/pipeline/scripts/_stack-routing.mjs +79 -0
- package/pipeline/scripts/audit-log-rotate.sh +4 -1
- package/pipeline/scripts/build-skills-index.mjs +11 -0
- package/pipeline/scripts/build-stack-plugins.mjs +28 -60
- package/pipeline/scripts/check-derived-drift.mjs +52 -28
- package/pipeline/scripts/gc-worktrees.sh +4 -1
- package/pipeline/scripts/gen-skills-index.mjs +1 -1
- package/pipeline/scripts/match-skills.mjs +8 -2
- package/pipeline/scripts/migrate-prefs.mjs +28 -20
- package/pipeline/scripts/phase-tracker.sh +13 -5
- package/pipeline/scripts/phase0-exit-gate.mjs +3 -2
- package/pipeline/scripts/run-aggregator.mjs +7 -2
- package/pipeline/scripts/scan-agent-config.sh +1 -1
- package/pipeline/scripts/skill-conformance.mjs +165 -30
- package/pipeline/scripts/smoke-cross-cli-behavior.sh +1 -1
- package/pipeline/scripts/test-gap-rules/android.json +25 -0
- package/pipeline/scripts/test-gap-rules/ios.json +34 -0
- package/pipeline/scripts/test-gap-rules/node.json +29 -0
- package/pipeline/scripts/test-gap-rules/python.json +25 -0
- package/pipeline/scripts/uninstall.mjs +158 -11
- package/pipeline/scripts/validate-complaint-doc.mjs +229 -0
- package/pipeline/scripts/validate-reviewer.mjs +9 -3
- package/pipeline/skills/.skill-manifest.json +156 -108
- package/pipeline/skills/.skills-index.json +449 -12
- package/pipeline/skills/shared/README.md +14 -10
- package/pipeline/skills/shared/core/multi-agent-analysis-resolve/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-build-optimize/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-complaint-analysis/SKILL.md +49 -0
- package/pipeline/skills/shared/core/multi-agent-dev/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-dev-autopilot/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-dev-local/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-dev-local-autopilot/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-ios-coding-standard/SKILL.md +2 -2
- package/pipeline/skills/shared/core/multi-agent-prune-prompts/SKILL.md +83 -0
- package/pipeline/skills/shared/core/{multi-agent-ship → multi-agent-resume-local}/SKILL.md +6 -6
- package/pipeline/skills/shared/core/multi-agent-stack/SKILL.md +79 -22
- package/pipeline/skills/shared/core/multi-agent-store-ready/SKILL.md +1 -1
- package/pipeline/skills/shared/core/multi-agent-sync/SKILL.md +8 -8
- package/pipeline/skills/shared/core/multi-agent-testflight-validation/SKILL.md +1 -1
- package/pipeline/skills/shared/external/ios-coding-standard/modules/_TEMPLATE.yml +2 -2
- package/pipeline/skills/shared/external/ios-coding-standard/references/rules.yml +368 -33
- package/pipeline/skills/shared/external/ios-coding-standard/references/swiftlint.draft.yml +1 -2
- package/pipeline/skills/shared/external/ios-coding-standard/scripts/check_structure.py +765 -0
- package/pipeline/skills/shared/external/ios-module-structure/SKILL.md +75 -0
- package/pipeline/skills/shared/external/ios-module-structure/modules/_TEMPLATE.yml +131 -0
- package/pipeline/skills/shared/external/ios-module-structure/references/rules.yml +559 -0
- package/pipeline/skills/shared/external/ios-module-structure/scripts/check_structure.py +765 -0
- package/pipeline/skills/shared/external/localization-reuse-map/example-mapping.json +53 -10
- package/pipeline/skills/shared/external/localization-reuse-map/reference/sources-and-recipes.md +4 -3
- package/pipeline/skills/skills-index.md +7 -4
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ios-module-structure
|
|
3
|
+
description: "The ios-module-structure rule registry: stable-ID rules over where a declaration lives, what its file is called and what its folder must contain beside it, plus a checker that runs them against one module. Use when auditing or refactoring a module's tree, or when a review wants a rule ID rather than a preference about layout."
|
|
4
|
+
user-invocable: true
|
|
5
|
+
standards-registry: references/rules.yml
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Module structure
|
|
9
|
+
|
|
10
|
+
The registry is `references/rules.yml`. Sibling to the coding-standard registry: that one governs
|
|
11
|
+
what is inside a file, this one governs the tree - which folder a declaration lives in, what its
|
|
12
|
+
file is called, and what has to sit beside it.
|
|
13
|
+
|
|
14
|
+
| File | What it is | When to read it |
|
|
15
|
+
|---|---|---|
|
|
16
|
+
| `references/rules.yml` | the rules, with stable IDs, severity, enforcement kind and the predicate each one runs | before asserting that a layout is or is not a violation |
|
|
17
|
+
| `scripts/check_structure.py` | the checker: resolves the module's bindings, runs the predicates, reports by ID | every audit; never eyeball a tree you can measure |
|
|
18
|
+
| `modules/<Module>.yml` | per-module overlay: role bindings, dialect choices, vocabulary, carve-outs. **Project-local, never shipped** - it lives in the installed copy, never in the authoring source | before auditing a module, and before raising any slot-bound rule |
|
|
19
|
+
| `modules/_TEMPLATE.yml` | the overlay's shape and the evidence each binding wants | when onboarding a module |
|
|
20
|
+
|
|
21
|
+
**Maturity: 0.x, iOS/Swift only.** The registry declares `scope.languages`, and the checker
|
|
22
|
+
refuses a module that holds none of that language rather than reporting a clean run. A second
|
|
23
|
+
language would be a second rules file passed to `--rules`, not a change to the checker.
|
|
24
|
+
|
|
25
|
+
## The one idea
|
|
26
|
+
|
|
27
|
+
A rule here never names a path or a type. It names a **role**, and the module's overlay binds that
|
|
28
|
+
role to its own spelling. `STRUCT-07` does not say "a file under Subviews/ needs a Configuration
|
|
29
|
+
beside it"; it says every file playing `subview.view` has the `subview.configuration` file beside
|
|
30
|
+
it. A module that spells those two differently rebinds; a module that has no such shape leaves the
|
|
31
|
+
role empty and the rule switches off.
|
|
32
|
+
|
|
33
|
+
That is what lets one registry serve two modules whose trees share almost nothing, without either
|
|
34
|
+
becoming a hundred findings.
|
|
35
|
+
|
|
36
|
+
## How to use it
|
|
37
|
+
|
|
38
|
+
1. **Cite, do not paraphrase.** Reference `STRUCT-04`, `VOCAB-01`. A finding without an ID is a
|
|
39
|
+
preference about folders, and the author cannot look it up to disagree.
|
|
40
|
+
2. **A rule not in the registry is not a rule.** If an audit wants one, propose it as
|
|
41
|
+
`status: proposed` with a rationale rather than enforcing it silently.
|
|
42
|
+
3. **An unbound slot or role DISABLES its rules, and the run reports that.** Never read a clean run
|
|
43
|
+
without reading its `DISABLED` block - that block is the coverage you did not have.
|
|
44
|
+
4. **Severity decides whether it blocks.** `blocking` stops the change, `important` is fixed in the
|
|
45
|
+
same pass, `suggestion` is optional.
|
|
46
|
+
5. **Exceptions are marked in code, with an expiry:**
|
|
47
|
+
`// standard:exception(<RULE-ID>) <reason> <expiry:YYYY-MM-DD>`. An unmarked deviation is a
|
|
48
|
+
finding; a marked one is a decision.
|
|
49
|
+
6. **When a finding looks wrong, fix the overlay before the code.** A rule firing on a whole module
|
|
50
|
+
is almost always a dialect the overlay has not declared. Changing the code to satisfy a
|
|
51
|
+
mis-bound rule is the expensive mistake this registry exists to prevent.
|
|
52
|
+
|
|
53
|
+
## Running it
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
python3 "$HOME/.claude/skills/ios-module-structure/scripts/check_structure.py" \
|
|
57
|
+
--rules "$HOME/.claude/skills/ios-module-structure/references/rules.yml" \
|
|
58
|
+
--overlay "$HOME/.claude/skills/ios-module-structure/modules/<Module>.yml" \
|
|
59
|
+
--root "<path/to/module>"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
`--only <RULE-ID>` runs one rule, `--screen <Name>` one screen, `--format json` gives a machine
|
|
63
|
+
result. Exit is 1 when there is any finding, 0 otherwise; notes and disabled rules never affect it.
|
|
64
|
+
|
|
65
|
+
Requires PyYAML - the registry and the overlay are YAML.
|
|
66
|
+
|
|
67
|
+
## Dialect slots, and why a rule becomes one
|
|
68
|
+
|
|
69
|
+
Some layouts are a choice, not a defect: two shapes are each coherent and the cost is only in
|
|
70
|
+
mixing them. Those rules bind to a slot in `module_overlay_slots` and the overlay picks a value.
|
|
71
|
+
A slot is only legitimate when **both** values are genuinely defensible - a module with no analytics
|
|
72
|
+
surface has not chosen a different dialect, it is missing the surface, so that stays a rule.
|
|
73
|
+
|
|
74
|
+
The test when you are tempted to add one: can you write the second value's paragraph without it
|
|
75
|
+
reading as an excuse? If not, it is a rule.
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
########################################################################
|
|
2
|
+
# Module overlay template.
|
|
3
|
+
#
|
|
4
|
+
# Copy to `modules/<YourModule>.yml` in your own project and fill it in from EVIDENCE IN YOUR OWN
|
|
5
|
+
# CODE. A real overlay is never shipped with this skill: it quotes module paths, directory
|
|
6
|
+
# spellings and file counts, so it describes one codebase and would bind another codebase's slots
|
|
7
|
+
# to the wrong dialect.
|
|
8
|
+
#
|
|
9
|
+
# The rule that makes this safe: an UNBOUND slot or role DISABLES its rules. Leaving one empty
|
|
10
|
+
# costs you those checks and the run says so. Guessing a value costs you a hundred findings against
|
|
11
|
+
# a module that made the other defensible choice - a migration proposal wearing a structure pass.
|
|
12
|
+
# Empty beats guessed.
|
|
13
|
+
#
|
|
14
|
+
# Every `*_evidence` field wants a COUNT, not a preference. The count is the only thing that
|
|
15
|
+
# distinguishes "this module chose a shape" from "this module has a defect". No count, no binding.
|
|
16
|
+
########################################################################
|
|
17
|
+
|
|
18
|
+
module: <YourModule>
|
|
19
|
+
path: <Path/To/Module>
|
|
20
|
+
role: feature # feature | common | app
|
|
21
|
+
registry_version: 1.0.0
|
|
22
|
+
updated: <YYYY-MM-DD>
|
|
23
|
+
|
|
24
|
+
description: >
|
|
25
|
+
One paragraph: how many targets, which of them carry screens, and what a screen's folders are.
|
|
26
|
+
|
|
27
|
+
# --- Dialect slots -----------------------------------------------------
|
|
28
|
+
# See `references/rules.yml -> module_overlay_slots` for what each governs and which values are
|
|
29
|
+
# defensible. Bind only what you can evidence.
|
|
30
|
+
dialect:
|
|
31
|
+
# Does every screen carry the same layer folders, or only the ones it needs?
|
|
32
|
+
ScreenLayerShape:
|
|
33
|
+
ScreenLayerShape_evidence: >
|
|
34
|
+
Count screens against each layer folder, e.g. "N of N carry X; M of N carry Y". A uniform count
|
|
35
|
+
means `layered`; a spread means `organic` and a missing folder is a fact, not a finding.
|
|
36
|
+
|
|
37
|
+
# Where does a service operation's request/response pair live?
|
|
38
|
+
ServiceModelDir:
|
|
39
|
+
ServiceModelDir_evidence: >
|
|
40
|
+
Count directories holding a pair under each candidate parent.
|
|
41
|
+
|
|
42
|
+
# Does every operation model both halves, or only the ones with a body?
|
|
43
|
+
ServiceModelPairing:
|
|
44
|
+
ServiceModelPairing_evidence: >
|
|
45
|
+
Count request models against response models. Close counts mean `both`; a large gap means
|
|
46
|
+
`response-only`.
|
|
47
|
+
|
|
48
|
+
# Does each screen ship its own construction seam, or does one factory build them all?
|
|
49
|
+
ScreenAssemblyShape:
|
|
50
|
+
ScreenAssemblyShape_evidence: >
|
|
51
|
+
Count factory files against screens. One each means per-screen-factory.
|
|
52
|
+
|
|
53
|
+
# Does UI state live in its own type, or on the view model?
|
|
54
|
+
UIStateHolder:
|
|
55
|
+
UIStateHolder_evidence: >
|
|
56
|
+
Count separate state types against screens. Zero means view-model-owned.
|
|
57
|
+
|
|
58
|
+
# Does an extracted view get a folder and a value type, or sit loose?
|
|
59
|
+
SubviewShape:
|
|
60
|
+
SubviewShape_evidence: >
|
|
61
|
+
Count view+value pairs against loose extracted views.
|
|
62
|
+
|
|
63
|
+
# Does the entry file compose its own fragments, or hand them to named views?
|
|
64
|
+
ScreenCompositionShape:
|
|
65
|
+
ScreenCompositionShape_evidence: >
|
|
66
|
+
Count view members on entry files against extracted view files. This one decides whether a
|
|
67
|
+
long entry file is the module's shape or a pile of un-extracted fragments; get it wrong in
|
|
68
|
+
either direction and the run is useless.
|
|
69
|
+
|
|
70
|
+
# Where is copy resolved?
|
|
71
|
+
CopyResolution:
|
|
72
|
+
CopyResolution_evidence: >
|
|
73
|
+
Count per-screen copy types against screens.
|
|
74
|
+
|
|
75
|
+
# --- Roles -------------------------------------------------------------
|
|
76
|
+
# Globs are relative to `path`. A role may bind to one glob or to a list of them. Roles other than
|
|
77
|
+
# screen.root are relative to a screen directory.
|
|
78
|
+
#
|
|
79
|
+
# Leave a role empty when the module genuinely has no such thing - the rules that read it are then
|
|
80
|
+
# reported as lost coverage, which is the honest answer.
|
|
81
|
+
roles:
|
|
82
|
+
screen.root: # e.g. "Sources/*/Screens/*"
|
|
83
|
+
screen.entry:
|
|
84
|
+
screen.viewmodel:
|
|
85
|
+
screen.state:
|
|
86
|
+
screen.analytics:
|
|
87
|
+
screen.factory:
|
|
88
|
+
screen.mapper:
|
|
89
|
+
service.dir:
|
|
90
|
+
service.request:
|
|
91
|
+
service.response:
|
|
92
|
+
subview.view:
|
|
93
|
+
subview.configuration:
|
|
94
|
+
repository.live:
|
|
95
|
+
repository.mock:
|
|
96
|
+
shared.root:
|
|
97
|
+
test.root:
|
|
98
|
+
|
|
99
|
+
# --- Vocabulary --------------------------------------------------------
|
|
100
|
+
# Names and spellings the rules need in order to generate a check. An unfilled key disables the
|
|
101
|
+
# rules that read it.
|
|
102
|
+
vocabulary:
|
|
103
|
+
LayerDirs: [] # the folders `layered` expects on every screen
|
|
104
|
+
PresentationDir: []
|
|
105
|
+
SubviewViewSuffix:
|
|
106
|
+
SubviewConfigurationSuffix:
|
|
107
|
+
BooleanPrefixes: # a regex, e.g. "^(is|has|can|shows)[A-Z]"
|
|
108
|
+
IndexLabel: # a regex for the accepted parameter label
|
|
109
|
+
SectionHeadings: [] # the closed set of section headings, if the module declares one
|
|
110
|
+
BareVerbs: [] # verbs a presentation type may not use alone
|
|
111
|
+
ForbiddenTypeSuffixes: [] # last words that describe no role
|
|
112
|
+
|
|
113
|
+
# --- Limits ------------------------------------------------------------
|
|
114
|
+
limits:
|
|
115
|
+
source_target:
|
|
116
|
+
source_ceiling:
|
|
117
|
+
test_target:
|
|
118
|
+
test_ceiling:
|
|
119
|
+
|
|
120
|
+
# --- Carve-outs --------------------------------------------------------
|
|
121
|
+
# Declared per rule ID. Each is a decision with a reason, not a way to quiet the tool. A carve-out
|
|
122
|
+
# with no reason is a finding you hid from yourself.
|
|
123
|
+
#
|
|
124
|
+
# screens: [Name, ...] the rule does not describe these screens
|
|
125
|
+
# paths: [glob, ...] the rule does not describe files at these paths
|
|
126
|
+
# patterns: [regex, ...] the rule does not describe findings whose detail matches
|
|
127
|
+
exemptions: {}
|
|
128
|
+
# RULE-ID:
|
|
129
|
+
# screens: []
|
|
130
|
+
# reason: >
|
|
131
|
+
# Why this is a decision rather than a defect.
|