pumuki 6.3.264 → 6.3.266
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.266] - 2026-05-14
|
|
4
|
+
|
|
5
|
+
- iOS: `skills.ios.no-dispatchgroup` now emits actionable AST-style evidence for `DispatchGroup` usage, including exact lines, primary/related nodes and remediation toward `TaskGroup` or other Swift concurrency boundaries.
|
|
6
|
+
|
|
7
|
+
## [6.3.265] - 2026-05-14
|
|
8
|
+
|
|
9
|
+
- 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.
|
|
10
|
+
|
|
3
11
|
## [6.3.264] - 2026-05-14
|
|
4
12
|
|
|
5
13
|
- 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.
|
|
@@ -15,11 +15,13 @@ import {
|
|
|
15
15
|
collectSwiftXCTUnwrapLines,
|
|
16
16
|
collectSwiftAnyViewLines,
|
|
17
17
|
collectSwiftCallbackStyleSignatureLines,
|
|
18
|
+
collectSwiftDispatchGroupLines,
|
|
18
19
|
hasSwiftAnyViewUsage,
|
|
19
20
|
hasSwiftAsyncWithoutAwaitUsage,
|
|
20
21
|
hasSwiftCallbackStyleSignature,
|
|
21
22
|
hasSwiftCornerRadiusUsage,
|
|
22
23
|
hasSwiftDispatchGroupUsage,
|
|
24
|
+
collectSwiftDispatchQueueLines,
|
|
23
25
|
hasSwiftDispatchQueueUsage,
|
|
24
26
|
hasSwiftDispatchSemaphoreUsage,
|
|
25
27
|
hasSwiftAdHocLoggingUsage,
|
|
@@ -506,6 +508,8 @@ OperationQueue()
|
|
|
506
508
|
assert.equal(hasSwiftDispatchGroupUsage(source), true);
|
|
507
509
|
assert.equal(hasSwiftDispatchSemaphoreUsage(source), true);
|
|
508
510
|
assert.equal(hasSwiftOperationQueueUsage(source), true);
|
|
511
|
+
assert.deepEqual(collectSwiftDispatchQueueLines(source), [2]);
|
|
512
|
+
assert.deepEqual(collectSwiftDispatchGroupLines(source), [3]);
|
|
509
513
|
});
|
|
510
514
|
|
|
511
515
|
test('hasSwiftTaskDetachedUsage detecta Task.detached y evita Task normal', () => {
|
|
@@ -457,6 +457,10 @@ export const hasSwiftDispatchQueueUsage = (source: string): boolean => {
|
|
|
457
457
|
});
|
|
458
458
|
};
|
|
459
459
|
|
|
460
|
+
export const collectSwiftDispatchQueueLines = (source: string): readonly number[] => {
|
|
461
|
+
return sortedUniqueLines(collectSwiftRegexLines(source, /\bDispatchQueue\s*\./));
|
|
462
|
+
};
|
|
463
|
+
|
|
460
464
|
export const hasSwiftDispatchGroupUsage = (source: string): boolean => {
|
|
461
465
|
return scanCodeLikeSource(source, ({ source: swiftSource, index, current }) => {
|
|
462
466
|
if (current !== 'D') {
|
|
@@ -467,6 +471,10 @@ export const hasSwiftDispatchGroupUsage = (source: string): boolean => {
|
|
|
467
471
|
});
|
|
468
472
|
};
|
|
469
473
|
|
|
474
|
+
export const collectSwiftDispatchGroupLines = (source: string): readonly number[] => {
|
|
475
|
+
return sortedUniqueLines(collectSwiftRegexLines(source, /\bDispatchGroup\b/));
|
|
476
|
+
};
|
|
477
|
+
|
|
470
478
|
export const hasSwiftDispatchSemaphoreUsage = (source: string): boolean => {
|
|
471
479
|
return scanCodeLikeSource(source, ({ source: swiftSource, index, current }) => {
|
|
472
480
|
if (current !== 'D') {
|
|
@@ -647,8 +647,8 @@ const textDetectorRegistry: ReadonlyArray<TextDetectorRegistryEntry> = [
|
|
|
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
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, ruleId: 'heuristics.ios.dispatchqueue.ast', code: 'HEURISTICS_IOS_DISPATCHQUEUE_AST', message: 'AST heuristic detected DispatchQueue usage.' },
|
|
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.' },
|
|
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
|
+
{ platform: 'ios', pathCheck: isIOSSwiftPath, excludePaths: [isSwiftTestPath], detect: TextIOS.hasSwiftDispatchGroupUsage, locateLines: TextIOS.collectSwiftDispatchGroupLines, primaryNode: (lines) => ({ kind: 'call', name: 'GCD DispatchGroup call', lines }), relatedNodes: (lines) => [{ kind: 'call', name: 'replacement: structured concurrency TaskGroup or async aggregation boundary', lines }], why: 'DispatchGroup is an unstructured coordination primitive that makes asynchronous control flow and cancellation implicit instead of modeled by Swift concurrency.', impact: 'Group coordination is harder to reason about and can hide waiting or deadlock risks in production code paths that should be expressed through TaskGroup or async aggregation.', expected_fix: 'Use TaskGroup, async let, await aggregation, actors or explicit async APIs. Keep DispatchGroup only inside approved legacy bridge layers with documented ownership and migration scope.', 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.' },
|
|
654
654
|
{ platform: 'ios', pathCheck: isIOSSwiftPath, excludePaths: [isSwiftTestPath], detect: TextIOS.hasSwiftTaskDetachedUsage, ruleId: 'heuristics.ios.task-detached.ast', code: 'HEURISTICS_IOS_TASK_DETACHED_AST', message: 'AST heuristic detected Task.detached 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.266)
|
|
10
|
+
|
|
11
|
+
- Published `pumuki@6.3.266` with AST-style line/node evidence for `skills.ios.no-dispatchgroup`, making GCD `DispatchGroup` usage remediable through `TaskGroup` or structured async aggregation boundaries.
|
|
12
|
+
|
|
13
|
+
### 2026-05-14 (v6.3.265)
|
|
14
|
+
|
|
15
|
+
- 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.
|
|
16
|
+
|
|
9
17
|
### 2026-05-14 (v6.3.264)
|
|
10
18
|
|
|
11
19
|
- 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.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pumuki",
|
|
3
|
-
"version": "6.3.
|
|
3
|
+
"version": "6.3.266",
|
|
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": {
|