pumuki 6.3.263 → 6.3.265
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
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [6.3.265] - 2026-05-14
|
|
4
|
+
|
|
5
|
+
- iOS: `skills.ios.no-dispatchqueue` now emits actionable AST-style evidence for GCD `DispatchQueue` calls, including exact lines, primary/related nodes and remediation toward Swift structured concurrency.
|
|
6
|
+
|
|
7
|
+
## [6.3.264] - 2026-05-14
|
|
8
|
+
|
|
9
|
+
- iOS: `skills.ios.no-callback-style` now emits actionable AST-style evidence for escaping callback signatures outside approved bridge layers, including exact lines, primary/related nodes and remediation toward `async/await` APIs or explicit adapters.
|
|
10
|
+
|
|
3
11
|
## [6.3.263] - 2026-05-14
|
|
4
12
|
|
|
5
13
|
- iOS: `skills.ios.no-anyview` now emits actionable AST-style evidence for SwiftUI `AnyView`, including exact lines, primary/related nodes and remediation toward concrete view composition or `@ViewBuilder` branches.
|
|
@@ -14,11 +14,13 @@ import {
|
|
|
14
14
|
collectSwiftXCTestAssertionLines,
|
|
15
15
|
collectSwiftXCTUnwrapLines,
|
|
16
16
|
collectSwiftAnyViewLines,
|
|
17
|
+
collectSwiftCallbackStyleSignatureLines,
|
|
17
18
|
hasSwiftAnyViewUsage,
|
|
18
19
|
hasSwiftAsyncWithoutAwaitUsage,
|
|
19
20
|
hasSwiftCallbackStyleSignature,
|
|
20
21
|
hasSwiftCornerRadiusUsage,
|
|
21
22
|
hasSwiftDispatchGroupUsage,
|
|
23
|
+
collectSwiftDispatchQueueLines,
|
|
22
24
|
hasSwiftDispatchQueueUsage,
|
|
23
25
|
hasSwiftDispatchSemaphoreUsage,
|
|
24
26
|
hasSwiftAdHocLoggingUsage,
|
|
@@ -483,11 +485,14 @@ func run(handler: @MainActor @escaping () -> Void) {}
|
|
|
483
485
|
`;
|
|
484
486
|
assert.equal(hasSwiftCallbackStyleSignature(completionSignature), true);
|
|
485
487
|
assert.equal(hasSwiftCallbackStyleSignature(handlerSignature), true);
|
|
488
|
+
assert.deepEqual(collectSwiftCallbackStyleSignatureLines(completionSignature), [2]);
|
|
489
|
+
assert.deepEqual(collectSwiftCallbackStyleSignatureLines(handlerSignature), [2]);
|
|
486
490
|
});
|
|
487
491
|
|
|
488
492
|
test('hasSwiftCallbackStyleSignature ignora usos fuera de firmas callback', () => {
|
|
489
493
|
const source = `\n// @escaping completion: @escaping () -> Void\nlet text = "@escaping completion: @escaping () -> Void"\n`;
|
|
490
494
|
assert.equal(hasSwiftCallbackStyleSignature(source), false);
|
|
495
|
+
assert.deepEqual(collectSwiftCallbackStyleSignatureLines(source), []);
|
|
491
496
|
});
|
|
492
497
|
|
|
493
498
|
test('detecta primitivas GCD y OperationQueue en codigo ejecutable', () => {
|
|
@@ -502,6 +507,7 @@ OperationQueue()
|
|
|
502
507
|
assert.equal(hasSwiftDispatchGroupUsage(source), true);
|
|
503
508
|
assert.equal(hasSwiftDispatchSemaphoreUsage(source), true);
|
|
504
509
|
assert.equal(hasSwiftOperationQueueUsage(source), true);
|
|
510
|
+
assert.deepEqual(collectSwiftDispatchQueueLines(source), [2]);
|
|
505
511
|
});
|
|
506
512
|
|
|
507
513
|
test('hasSwiftTaskDetachedUsage detecta Task.detached y evita Task normal', () => {
|
|
@@ -398,6 +398,15 @@ export const collectSwiftAnyViewLines = (source: string): readonly number[] => {
|
|
|
398
398
|
return sortedUniqueLines(collectSwiftRegexLines(source, /\bAnyView\b/));
|
|
399
399
|
};
|
|
400
400
|
|
|
401
|
+
export const collectSwiftCallbackStyleSignatureLines = (source: string): readonly number[] => {
|
|
402
|
+
return sortedUniqueLines(
|
|
403
|
+
collectSwiftRegexLines(
|
|
404
|
+
source,
|
|
405
|
+
/\b(?:completion|completionHandler|callback|handler)\s*:\s*(?:@[A-Za-z_][A-Za-z0-9_]*(?:\([^)]*\))?\s+)*@escaping\b/
|
|
406
|
+
)
|
|
407
|
+
);
|
|
408
|
+
};
|
|
409
|
+
|
|
401
410
|
export const hasSwiftNonLazyScrollForEachUsage = (source: string): boolean => {
|
|
402
411
|
const swiftSource = sanitizeSwiftSourceForMultilineRegex(source);
|
|
403
412
|
const nonLazyScrollableCollectionPattern =
|
|
@@ -448,6 +457,10 @@ export const hasSwiftDispatchQueueUsage = (source: string): boolean => {
|
|
|
448
457
|
});
|
|
449
458
|
};
|
|
450
459
|
|
|
460
|
+
export const collectSwiftDispatchQueueLines = (source: string): readonly number[] => {
|
|
461
|
+
return sortedUniqueLines(collectSwiftRegexLines(source, /\bDispatchQueue\s*\./));
|
|
462
|
+
};
|
|
463
|
+
|
|
451
464
|
export const hasSwiftDispatchGroupUsage = (source: string): boolean => {
|
|
452
465
|
return scanCodeLikeSource(source, ({ source: swiftSource, index, current }) => {
|
|
453
466
|
if (current !== 'D') {
|
|
@@ -646,8 +646,8 @@ const textDetectorRegistry: ReadonlyArray<TextDetectorRegistryEntry> = [
|
|
|
646
646
|
{ platform: 'ios', pathCheck: isIOSSwiftPath, excludePaths: [isSwiftTestPath], detect: TextIOS.hasSwiftAnyViewUsage, locateLines: TextIOS.collectSwiftAnyViewLines, primaryNode: (lines) => ({ kind: 'call', name: 'type erasure wrapper AnyView', lines }), relatedNodes: (lines) => [{ kind: 'call', name: 'replacement: concrete View composition or @ViewBuilder branch', lines }], why: 'AnyView erases SwiftUI view identity and type information, hiding structural changes from the compiler and making diffing less predictable.', impact: 'SwiftUI may lose optimization opportunities, navigation/sheet branches become harder to reason about, and remediating UI regressions requires reading dynamic wrappers instead of concrete view composition.', expected_fix: 'Replace AnyView with concrete some View composition, @ViewBuilder branching, generic View parameters, or small extracted subviews that preserve static SwiftUI identity.', ruleId: 'heuristics.ios.anyview.ast', code: 'HEURISTICS_IOS_ANYVIEW_AST', message: 'AST heuristic detected AnyView usage.' },
|
|
647
647
|
{ platform: 'ios', pathCheck: isIOSSwiftPath, excludePaths: [isSwiftTestPath], detect: TextIOS.hasSwiftForceTryUsage, locateLines: TextIOS.collectSwiftForceTryLines, primaryNode: (lines) => ({ kind: 'call', name: 'force try expression try!', lines }), relatedNodes: (lines) => [{ kind: 'call', name: 'replacement: do/catch or throwing boundary', lines }], why: 'Force try converts a throwable operation into an unconditional runtime crash instead of preserving the typed error boundary.', impact: 'A recoverable domain, network, persistence or decoding error can terminate the app and bypass user-facing recovery, telemetry and tests.', expected_fix: 'Replace try! with do/catch, try await propagation, throws on the current boundary, or a guarded fallback that handles the error explicitly.', ruleId: 'heuristics.ios.force-try.ast', code: 'HEURISTICS_IOS_FORCE_TRY_AST', message: 'AST heuristic detected force try usage.' },
|
|
648
648
|
{ platform: 'ios', pathCheck: isIOSSwiftPath, excludePaths: [isSwiftTestPath], detect: TextIOS.hasSwiftForceCastUsage, locateLines: TextIOS.collectSwiftForceCastLines, primaryNode: (lines) => ({ kind: 'call', name: 'force cast expression as!', lines }), relatedNodes: (lines) => [{ kind: 'call', name: 'replacement: conditional cast or typed boundary', lines }], why: 'Force cast converts a type mismatch into an unconditional runtime crash instead of preserving a checked domain or presentation boundary.', impact: 'Unexpected payloads, dependency substitutions or navigation models can terminate the app instead of producing a recoverable validation path.', expected_fix: 'Replace as! with as?, guard let, pattern matching, generic constraints, protocol boundaries, or a typed mapper that validates the runtime value explicitly.', ruleId: 'heuristics.ios.force-cast.ast', code: 'HEURISTICS_IOS_FORCE_CAST_AST', message: 'AST heuristic detected force cast usage.' },
|
|
649
|
-
{ platform: 'ios', pathCheck: isIOSSwiftPath, excludePaths: [isSwiftTestPath, isApprovedIOSBridgePath], detect: TextIOS.hasSwiftCallbackStyleSignature, ruleId: 'heuristics.ios.callback-style.ast', code: 'HEURISTICS_IOS_CALLBACK_STYLE_AST', message: 'AST heuristic detected callback-style API signature outside bridge layers.' },
|
|
650
|
-
{ platform: 'ios', pathCheck: isIOSSwiftPath, excludePaths: [isSwiftTestPath], detect: TextIOS.hasSwiftDispatchQueueUsage, ruleId: 'heuristics.ios.dispatchqueue.ast', code: 'HEURISTICS_IOS_DISPATCHQUEUE_AST', message: 'AST heuristic detected DispatchQueue usage.' },
|
|
649
|
+
{ platform: 'ios', pathCheck: isIOSSwiftPath, excludePaths: [isSwiftTestPath, isApprovedIOSBridgePath], detect: TextIOS.hasSwiftCallbackStyleSignature, locateLines: TextIOS.collectSwiftCallbackStyleSignatureLines, primaryNode: (lines) => ({ kind: 'call', name: 'escaping callback-style API signature', lines }), relatedNodes: (lines) => [{ kind: 'call', name: 'replacement: async/await API or explicit bridge adapter', lines }], why: 'Callback-style completion APIs outside bridge layers bypass Swift structured concurrency and make cancellation, isolation and error flow implicit.', impact: 'Consumers must reason about escaping lifetime, actor hops and callback ordering manually, which increases race, leak and flaky-test risk in production iOS flows.', expected_fix: 'Expose async/await or AsyncSequence APIs in production boundaries. Keep callbacks only inside approved bridge/adapters that wrap legacy SDKs and document the conversion point explicitly.', ruleId: 'heuristics.ios.callback-style.ast', code: 'HEURISTICS_IOS_CALLBACK_STYLE_AST', message: 'AST heuristic detected callback-style API signature outside bridge layers.' },
|
|
650
|
+
{ platform: 'ios', pathCheck: isIOSSwiftPath, excludePaths: [isSwiftTestPath], detect: TextIOS.hasSwiftDispatchQueueUsage, locateLines: TextIOS.collectSwiftDispatchQueueLines, primaryNode: (lines) => ({ kind: 'call', name: 'GCD DispatchQueue call', lines }), relatedNodes: (lines) => [{ kind: 'call', name: 'replacement: structured concurrency Task/actor/MainActor boundary', lines }], why: 'DispatchQueue introduces unstructured GCD scheduling in production Swift code instead of preserving Swift concurrency cancellation, priority and actor isolation semantics.', impact: 'Manual queue hops make ordering, cancellation and main-actor safety harder to reason about, increasing race and flaky UI update risk.', expected_fix: 'Use async/await, Task, TaskGroup, actors, MainActor.run or isolated async APIs. Keep GCD only inside explicitly approved legacy bridge layers with documented ownership.', ruleId: 'heuristics.ios.dispatchqueue.ast', code: 'HEURISTICS_IOS_DISPATCHQUEUE_AST', message: 'AST heuristic detected DispatchQueue usage.' },
|
|
651
651
|
{ platform: 'ios', pathCheck: isIOSSwiftPath, excludePaths: [isSwiftTestPath], detect: TextIOS.hasSwiftDispatchGroupUsage, ruleId: 'heuristics.ios.dispatchgroup.ast', code: 'HEURISTICS_IOS_DISPATCHGROUP_AST', message: 'AST heuristic detected DispatchGroup usage.' },
|
|
652
652
|
{ platform: 'ios', pathCheck: isIOSSwiftPath, excludePaths: [isSwiftTestPath], detect: TextIOS.hasSwiftDispatchSemaphoreUsage, ruleId: 'heuristics.ios.dispatchsemaphore.ast', code: 'HEURISTICS_IOS_DISPATCHSEMAPHORE_AST', message: 'AST heuristic detected DispatchSemaphore usage.' },
|
|
653
653
|
{ platform: 'ios', pathCheck: isIOSSwiftPath, excludePaths: [isSwiftTestPath], detect: TextIOS.hasSwiftOperationQueueUsage, ruleId: 'heuristics.ios.operation-queue.ast', code: 'HEURISTICS_IOS_OPERATION_QUEUE_AST', message: 'AST heuristic detected OperationQueue usage.' },
|
|
@@ -6,6 +6,14 @@ This file keeps only the operational highlights and rollout notes that matter wh
|
|
|
6
6
|
|
|
7
7
|
## 2026-04 (CLI stability and macOS notifications)
|
|
8
8
|
|
|
9
|
+
### 2026-05-14 (v6.3.265)
|
|
10
|
+
|
|
11
|
+
- Published `pumuki@6.3.265` with AST-style line/node evidence for `skills.ios.no-dispatchqueue`, making GCD `DispatchQueue` usage remediable through Swift structured concurrency, actors, `Task` or `MainActor` boundaries.
|
|
12
|
+
|
|
13
|
+
### 2026-05-14 (v6.3.264)
|
|
14
|
+
|
|
15
|
+
- Published `pumuki@6.3.264` with AST-style line/node evidence for `skills.ios.no-callback-style`, making escaping callback APIs outside bridge layers remediable through `async/await`, `AsyncSequence` or explicit legacy adapters.
|
|
16
|
+
|
|
9
17
|
### 2026-05-14 (v6.3.263)
|
|
10
18
|
|
|
11
19
|
- Published `pumuki@6.3.263` with AST-style line/node evidence for `skills.ios.no-anyview`, making SwiftUI `AnyView` type erasure remediable through concrete composition, generics or `@ViewBuilder` branches.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pumuki",
|
|
3
|
-
"version": "6.3.
|
|
3
|
+
"version": "6.3.265",
|
|
4
4
|
"description": "Enterprise-grade AST Intelligence System with multi-platform support (iOS, Android, Backend, Frontend) and Feature-First + DDD + Clean Architecture enforcement. Includes dynamic violations API for intelligent querying.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|