@mmerterden/multi-agent-pipeline 13.2.0 → 13.3.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 +50 -0
- package/install/_plugin-skills.mjs +246 -0
- package/install/codex.mjs +46 -6
- package/install/copilot.mjs +28 -7
- package/install/templates/codex-instructions.md +23 -0
- package/package.json +1 -1
- package/pipeline/commands/multi-agent/ios-coding-standard/SKILL.md +50 -50
- package/pipeline/multi-agent-refs/cross-cli-contract.md +32 -1
- package/pipeline/scripts/build-stack-plugins.mjs +50 -4
- package/pipeline/skills/shared/core/multi-agent-ios-coding-standard/SKILL.md +50 -50
- package/pipeline/skills/shared/external/ios-coding-standard/references/STANDARD.md +37 -37
- package/pipeline/skills/shared/external/ios-coding-standard/references/lint-local.sh +5 -5
- package/pipeline/skills/shared/external/ios-coding-standard/references/rules.yml +108 -108
- package/pipeline/skills/shared/external/ios-coding-standard/references/swiftlint.draft.yml +25 -25
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# SwiftLint configuration generated from rules.yml
|
|
1
|
+
# SwiftLint configuration generated from rules.yml - LOCAL USE ONLY.
|
|
2
2
|
#
|
|
3
3
|
# By decision this is NOT part of the project: no committed .swiftlint.yml, no build phase, no
|
|
4
4
|
# CI job. Run it through ./lint-local.sh, which resolves the placeholders below and keeps the
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
# ./lint-local.sh Domains/<Module> --strict # then only new violations surface
|
|
9
9
|
#
|
|
10
10
|
# Because there is no CI gate, the ratchet is a habit rather than a wall: run it before opening
|
|
11
|
-
# a PR. That is weaker than a gate and the audit says so
|
|
11
|
+
# a PR. That is weaker than a gate and the audit says so - adopting it project-wide stays an
|
|
12
12
|
# open decision, not a forgotten one.
|
|
13
13
|
#
|
|
14
14
|
# Every custom rule identifier IS its rules.yml ID, lowercased, so a CI failure points
|
|
@@ -52,13 +52,13 @@ opt_in_rules:
|
|
|
52
52
|
- prohibited_super_call
|
|
53
53
|
|
|
54
54
|
disabled_rules:
|
|
55
|
-
# WARN-02 owns TODO policy (untagged only); the built-in flags every TODO
|
|
55
|
+
# WARN-02 owns TODO policy (untagged only); the built-in flags every TODO - pure noise.
|
|
56
56
|
- todo
|
|
57
57
|
- line_length
|
|
58
58
|
- trailing_comma
|
|
59
59
|
- opening_brace
|
|
60
60
|
- statement_position
|
|
61
|
-
# SwiftUI's own presentation API is `sheet(isPresented:onDismiss:) { content }`
|
|
61
|
+
# SwiftUI's own presentation API is `sheet(isPresented:onDismiss:) { content }` - a closure
|
|
62
62
|
# argument plus a trailing view builder. The rule fires on Apple's documented shape, so
|
|
63
63
|
# obeying it would make every sheet read worse than the framework intends.
|
|
64
64
|
- multiple_closures_with_trailing_closure
|
|
@@ -74,14 +74,14 @@ function_body_length:
|
|
|
74
74
|
warning: 40
|
|
75
75
|
error: 100
|
|
76
76
|
|
|
77
|
-
# READ-07
|
|
77
|
+
# READ-07 - the component names are bound to an external design mapping and cannot be
|
|
78
78
|
# shortened, so the ceiling reflects the codebase rather than SwiftLint's 40-char default.
|
|
79
79
|
type_name:
|
|
80
80
|
max_length:
|
|
81
81
|
warning: 62
|
|
82
82
|
error: 75
|
|
83
83
|
|
|
84
|
-
# STRUCT-01
|
|
84
|
+
# STRUCT-01 - a pure constants namespace groups by nesting (`AppConstant.DeepLink.Path`);
|
|
85
85
|
# two levels is the depth that grouping needs, and nothing deeper is allowed.
|
|
86
86
|
nesting:
|
|
87
87
|
type_level: 2
|
|
@@ -92,14 +92,14 @@ identifier_name:
|
|
|
92
92
|
cyclomatic_complexity:
|
|
93
93
|
warning: 10
|
|
94
94
|
|
|
95
|
-
# READ-09
|
|
95
|
+
# READ-09 - the built-in takes no per-rule `excluded`; Package.swift is excluded globally below
|
|
96
96
|
file_header:
|
|
97
|
-
# Author is the FULL git identity, department included
|
|
97
|
+
# Author is the FULL git identity, department included - "NAME - <Department> Mudurlugu".
|
|
98
98
|
# A bare name is not enough: it does not say which team owns the file.
|
|
99
99
|
required_pattern: '\A//\n// .*\.swift\n// .*\n//(?:\n//.*)*?\n// Created by .+ - .+ on \d{2}\.\d{2}\.\d{4}\.\n//\n'
|
|
100
100
|
|
|
101
|
-
# VIS-04
|
|
102
|
-
# An extension is a grouping, not an API
|
|
101
|
+
# VIS-04 - only the module's public surface must be documented
|
|
102
|
+
# An extension is a grouping, not an API - its members carry the docs. Requiring a comment on
|
|
103
103
|
# the `extension` line itself only produces restatements of the MARK above it. A memberwise
|
|
104
104
|
# init is likewise self-describing.
|
|
105
105
|
missing_docs:
|
|
@@ -120,7 +120,7 @@ custom_rules:
|
|
|
120
120
|
sec_01_no_over_persistence:
|
|
121
121
|
name: "SEC-01 transient value being persisted"
|
|
122
122
|
regex: '(credentialStore|keychain|UserDefaults|FileManager)[^\n]*\b((TRANSIENT))\b'
|
|
123
|
-
message: "This value is required-transient. Persisting it
|
|
123
|
+
message: "This value is required-transient. Persisting it - Keychain included - creates a cleanup obligation with no owner. Hold it in the flow's model and drop it."
|
|
124
124
|
severity: error
|
|
125
125
|
|
|
126
126
|
sec_01_keychain_sync:
|
|
@@ -132,7 +132,7 @@ custom_rules:
|
|
|
132
132
|
sec_01_keychain_accessibility_missing:
|
|
133
133
|
name: "SEC-01 keychain write without an accessibility class"
|
|
134
134
|
regex: 'kSecClassGenericPassword(?:(?!kSecAttrAccessible)[\s\S]){0,400}SecItemAdd'
|
|
135
|
-
message: "Declare kSecAttrAccessible explicitly
|
|
135
|
+
message: "Declare kSecAttrAccessible explicitly - device-only unless there is a documented reason."
|
|
136
136
|
severity: error
|
|
137
137
|
|
|
138
138
|
sec_02_hardcoded_secret:
|
|
@@ -174,10 +174,10 @@ custom_rules:
|
|
|
174
174
|
|
|
175
175
|
sec_09_commented_out_compilation_condition:
|
|
176
176
|
name: "SEC-09 compilation condition commented out"
|
|
177
|
-
# [ \t]* not \s*
|
|
177
|
+
# [ \t]* not \s* - \s matches newlines, so "//" ending a file header plus a real
|
|
178
178
|
# "#if" two lines below would match as one commented-out directive.
|
|
179
179
|
regex: '^[ \t]*//[ \t]*#(if|endif|else)\b'
|
|
180
|
-
message: "A commented-out #if DEBUG is not a guard
|
|
180
|
+
message: "A commented-out #if DEBUG is not a guard - the code inside it ships. Restore the directive or delete the code."
|
|
181
181
|
severity: error
|
|
182
182
|
|
|
183
183
|
# ── TEST ────────────────────────────────────────────────────────────────
|
|
@@ -238,16 +238,16 @@ custom_rules:
|
|
|
238
238
|
|
|
239
239
|
# ── CONC ────────────────────────────────────────────────────────────────
|
|
240
240
|
# Production code only. A test double is constructed inside one test and mutated by that
|
|
241
|
-
# test's single task, so the hatch carries no concurrency risk there
|
|
241
|
+
# test's single task, so the hatch carries no concurrency risk there - flagging every spy
|
|
242
242
|
# would bury the production hits that do matter.
|
|
243
243
|
conc_03_escape_hatch:
|
|
244
244
|
name: "CONC-03 concurrency escape hatch"
|
|
245
245
|
regex: '(@preconcurrency|nonisolated\(unsafe\)|@unchecked\s+Sendable)'
|
|
246
246
|
included: ".*/Sources/.*"
|
|
247
|
-
message: "Migration tool, not a design tool. Add a standard:exception marker with a removal condition
|
|
247
|
+
message: "Migration tool, not a design tool. Add a standard:exception marker with a removal condition - these are counted."
|
|
248
248
|
severity: warning
|
|
249
249
|
|
|
250
|
-
# SVC-07
|
|
250
|
+
# SVC-07 - a repository protocol method names the service it calls. The legitimate
|
|
251
251
|
# exceptions (variants over one service, no endpoint yet) are meant to surface here and be
|
|
252
252
|
# answered with a standard:exception marker, not to be silently allowed by the pattern.
|
|
253
253
|
svc_07_service_named_method:
|
|
@@ -257,7 +257,7 @@ custom_rules:
|
|
|
257
257
|
message: "Name it `send<ServiceName>` (check-open-status -> sendCheckOpenStatus), or mark it standard:exception(SVC-07) with the reason."
|
|
258
258
|
severity: warning
|
|
259
259
|
|
|
260
|
-
# SVC-08
|
|
260
|
+
# SVC-08 - arithmetic or a policy default inside a mapper. Optional lowering (`?? ""`,
|
|
261
261
|
# `?? false`, `?? []`, `?? nil`) is deliberately not matched; a literal number or a division is.
|
|
262
262
|
svc_08_rule_in_mapper:
|
|
263
263
|
name: "SVC-08 calculation or policy default inside a mapper"
|
|
@@ -266,24 +266,24 @@ custom_rules:
|
|
|
266
266
|
message: "A mapper moves values. Carry the wire value and do the arithmetic, clamp or default in the view model."
|
|
267
267
|
severity: warning
|
|
268
268
|
|
|
269
|
-
# READ-04b
|
|
269
|
+
# READ-04b - a component file under Presentation/Components must carry a preview. Reported
|
|
270
270
|
# per file that declares a View and has no #Preview.
|
|
271
271
|
# READ-04b is NOT a swiftlint rule: a regex matches a LINE, and "this file has no #Preview"
|
|
272
272
|
# is a statement about the whole file. Matching `struct X: View {` under Components/ flags
|
|
273
|
-
# every component, previewed or not
|
|
273
|
+
# every component, previewed or not - 25 false positives on first run. The check lives in the
|
|
274
274
|
# standard's structural pass instead (component files vs files containing #Preview).
|
|
275
275
|
|
|
276
|
-
# PLAT-01
|
|
276
|
+
# PLAT-01 - raw SwiftUI presentation in a feature module. The app ships an OS-independent
|
|
277
277
|
# wrapper; the system API drifts with every iOS release (the iOS 26 partial-detent inset).
|
|
278
278
|
plat_01_raw_presentation:
|
|
279
279
|
name: "PLAT-01 raw system presentation instead of the app's sheet"
|
|
280
280
|
regex: '(?<![\w.])\.sheet\('
|
|
281
281
|
included: ".*/Sources/.*"
|
|
282
282
|
excluded_match_kinds: [comment, doccomment]
|
|
283
|
-
message: "Use the app's own sheet wrapper. System .sheet only for OS-owned surfaces (share, Siri, photo picker)
|
|
283
|
+
message: "Use the app's own sheet wrapper. System .sheet only for OS-owned surfaces (share, Siri, photo picker) - mark those standard:exception(PLAT-01)."
|
|
284
284
|
severity: warning
|
|
285
285
|
|
|
286
|
-
# PLAT-03
|
|
286
|
+
# PLAT-03 - an asset URL on someone else's host.
|
|
287
287
|
plat_03_third_party_asset_host:
|
|
288
288
|
name: "PLAT-03 asset URL on a third-party host"
|
|
289
289
|
regex: 'https?://(?!([\w.-]*\.)?(example\.com|cdn\.example\.com))[\w.-]+/[^"]*\.(png|jpg|jpeg|svg|webp|gif)'
|
|
@@ -341,7 +341,7 @@ custom_rules:
|
|
|
341
341
|
perf_04_formatter_per_render:
|
|
342
342
|
name: "PERF-04 formatter constructed per render"
|
|
343
343
|
regex: '(DateFormatter|NumberFormatter|RelativeDateTimeFormatter)\(\)'
|
|
344
|
-
message: "Hoist it out of the render path
|
|
344
|
+
message: "Hoist it out of the render path - construction is expensive and repeats every update."
|
|
345
345
|
severity: warning
|
|
346
346
|
included: ".*(View|Scene)\\.swift"
|
|
347
347
|
|
|
@@ -361,7 +361,7 @@ custom_rules:
|
|
|
361
361
|
warn_02_untagged_todo:
|
|
362
362
|
name: "WARN-02 TODO without an owner or ticket"
|
|
363
363
|
regex: '//\s*TODO(?!\[)'
|
|
364
|
-
message: "Tag it
|
|
364
|
+
message: "Tag it - // TODO[TICKET-123]: ... - or it is a note to someone who has left."
|
|
365
365
|
severity: warning
|
|
366
366
|
|
|
367
367
|
warn_02_fixme:
|