pumuki 6.3.270 → 6.3.271
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 +4 -0
- package/VERSION +1 -1
- package/core/facts/detectors/text/android.test.ts +538 -0
- package/core/facts/detectors/text/android.ts +436 -0
- package/core/facts/detectors/text/ios.test.ts +328 -1
- package/core/facts/detectors/text/ios.ts +241 -0
- package/core/facts/detectors/typescript/index.test.ts +393 -0
- package/core/facts/detectors/typescript/index.ts +316 -0
- package/core/facts/extractHeuristicFacts.ts +70 -1
- package/core/rules/presets/heuristics/android.test.ts +91 -1
- package/core/rules/presets/heuristics/android.ts +360 -0
- package/core/rules/presets/heuristics/ios.test.ts +54 -1
- package/core/rules/presets/heuristics/ios.ts +243 -2
- package/core/rules/presets/heuristics/typescript.test.ts +50 -2
- package/core/rules/presets/heuristics/typescript.ts +162 -0
- package/docs/operations/RELEASE_NOTES.md +4 -0
- package/integrations/config/skillsDetectorRegistry.ts +501 -0
- package/integrations/config/skillsRuleClassification.ts +127 -3
- package/integrations/git/runPlatformGate.ts +4 -1
- package/integrations/lifecycle/preWriteAutomation.ts +1 -0
- package/integrations/lifecycle/preWriteLease.ts +41 -4
- package/package.json +1 -1
- package/scripts/classify-skills-rules.ts +2 -2
- package/scripts/framework-menu-consumer-actions-lib.ts +9 -9
- package/scripts/framework-menu-consumer-runtime-actions.ts +53 -117
- package/scripts/framework-menu-consumer-runtime-audit.ts +66 -0
- package/scripts/framework-menu-consumer-runtime-menu.ts +4 -4
- package/scripts/framework-menu-gate-lib.ts +86 -1
- package/scripts/framework-menu-layout-data.ts +3 -3
- package/scripts/framework-menu-legacy-audit-render-sections.ts +6 -0
- package/scripts/framework-menu.ts +10 -6
- package/scripts/package-install-smoke-consumer-npm-lib.ts +10 -4
- package/scripts/package-install-smoke-lifecycle-lib.ts +19 -0
|
@@ -37,8 +37,8 @@ export const renderConsumerRuntimeClassicMenu = (
|
|
|
37
37
|
): string => {
|
|
38
38
|
const groupedActions = resolveConsumerMenuLayout(actions);
|
|
39
39
|
const lines = [
|
|
40
|
-
'PUMUKI
|
|
41
|
-
'AST Intelligence
|
|
40
|
+
'PUMUKI',
|
|
41
|
+
'Advanced Project Audit — AST Intelligence & Quality Gate',
|
|
42
42
|
'A. Switch to advanced menu',
|
|
43
43
|
'',
|
|
44
44
|
...groupedActions.flatMap((group) => [
|
|
@@ -68,8 +68,8 @@ export const renderConsumerRuntimeModernMenu = (
|
|
|
68
68
|
});
|
|
69
69
|
const groupedActions = resolveConsumerMenuLayout(params.actions);
|
|
70
70
|
const lines = [
|
|
71
|
-
'PUMUKI
|
|
72
|
-
'AST Intelligence
|
|
71
|
+
'PUMUKI',
|
|
72
|
+
'Advanced Project Audit — AST Intelligence & Quality Gate',
|
|
73
73
|
`Status: ${renderBadge(menuStatus.label, menuStatus.level, tokens)}`,
|
|
74
74
|
'A. Switch to advanced menu',
|
|
75
75
|
'',
|
|
@@ -104,6 +104,16 @@ export const runStagedGateSilent = async (): Promise<void> => {
|
|
|
104
104
|
await runMenuAuditGate(gateParams);
|
|
105
105
|
};
|
|
106
106
|
|
|
107
|
+
export const runStagedGateSilentWithBlocked = async (): Promise<
|
|
108
|
+
ConsumerRuntimeGateResult | void
|
|
109
|
+
> => {
|
|
110
|
+
const gateParams = buildMenuGateParams({
|
|
111
|
+
stage: 'PRE_COMMIT',
|
|
112
|
+
scope: { kind: 'staged' },
|
|
113
|
+
});
|
|
114
|
+
return await runMenuAuditGateWithBlocked(gateParams);
|
|
115
|
+
};
|
|
116
|
+
|
|
107
117
|
export const runRepoGateSilent = async (): Promise<void> => {
|
|
108
118
|
const gateParams = buildMenuGateParams({
|
|
109
119
|
stage: 'PRE_COMMIT',
|
|
@@ -112,6 +122,16 @@ export const runRepoGateSilent = async (): Promise<void> => {
|
|
|
112
122
|
await runMenuAuditGate(gateParams);
|
|
113
123
|
};
|
|
114
124
|
|
|
125
|
+
export const runRepoGateSilentWithBlocked = async (): Promise<
|
|
126
|
+
ConsumerRuntimeGateResult | void
|
|
127
|
+
> => {
|
|
128
|
+
const gateParams = buildMenuGateParams({
|
|
129
|
+
stage: 'PRE_COMMIT',
|
|
130
|
+
scope: { kind: 'repo' },
|
|
131
|
+
});
|
|
132
|
+
return await runMenuAuditGateWithBlocked(gateParams);
|
|
133
|
+
};
|
|
134
|
+
|
|
115
135
|
export const runRepoAndStagedGateSilent = async (): Promise<void> => {
|
|
116
136
|
const gateParams = buildMenuGateParams({
|
|
117
137
|
stage: 'PRE_COMMIT',
|
|
@@ -120,6 +140,16 @@ export const runRepoAndStagedGateSilent = async (): Promise<void> => {
|
|
|
120
140
|
await runMenuAuditGate(gateParams);
|
|
121
141
|
};
|
|
122
142
|
|
|
143
|
+
export const runRepoAndStagedGateSilentWithBlocked = async (): Promise<
|
|
144
|
+
ConsumerRuntimeGateResult | void
|
|
145
|
+
> => {
|
|
146
|
+
const gateParams = buildMenuGateParams({
|
|
147
|
+
stage: 'PRE_COMMIT',
|
|
148
|
+
scope: { kind: 'repoAndStaged' },
|
|
149
|
+
});
|
|
150
|
+
return await runMenuAuditGateWithBlocked(gateParams);
|
|
151
|
+
};
|
|
152
|
+
|
|
123
153
|
export const runRepoAndStagedPrePushGateSilent = async (): Promise<
|
|
124
154
|
ConsumerRuntimeGateResult | void
|
|
125
155
|
> => {
|
|
@@ -134,6 +164,16 @@ export const runWorkingTreeGateSilent = async (): Promise<void> => {
|
|
|
134
164
|
await runMenuAuditGate(gateParams);
|
|
135
165
|
};
|
|
136
166
|
|
|
167
|
+
export const runWorkingTreeGateSilentWithBlocked = async (): Promise<
|
|
168
|
+
ConsumerRuntimeGateResult | void
|
|
169
|
+
> => {
|
|
170
|
+
const gateParams = buildMenuGateParams({
|
|
171
|
+
stage: 'PRE_COMMIT',
|
|
172
|
+
scope: { kind: 'workingTree' },
|
|
173
|
+
});
|
|
174
|
+
return await runMenuAuditGateWithBlocked(gateParams);
|
|
175
|
+
};
|
|
176
|
+
|
|
137
177
|
export const runWorkingTreePrePushGateSilent = async (): Promise<void> => {
|
|
138
178
|
const gateParams = buildMenuGateParams({
|
|
139
179
|
stage: 'PRE_PUSH',
|
|
@@ -142,6 +182,16 @@ export const runWorkingTreePrePushGateSilent = async (): Promise<void> => {
|
|
|
142
182
|
await runMenuAuditGate(gateParams);
|
|
143
183
|
};
|
|
144
184
|
|
|
185
|
+
export const runWorkingTreePrePushGateSilentWithBlocked = async (): Promise<
|
|
186
|
+
ConsumerRuntimeGateResult | void
|
|
187
|
+
> => {
|
|
188
|
+
const gateParams = buildMenuGateParams({
|
|
189
|
+
stage: 'PRE_PUSH',
|
|
190
|
+
scope: { kind: 'workingTree' },
|
|
191
|
+
});
|
|
192
|
+
return await runMenuAuditGateWithBlocked(gateParams);
|
|
193
|
+
};
|
|
194
|
+
|
|
145
195
|
export const runUnstagedGateSilent = async (): Promise<void> => {
|
|
146
196
|
const gateParams = buildMenuGateParams({
|
|
147
197
|
stage: 'PRE_COMMIT',
|
|
@@ -150,10 +200,29 @@ export const runUnstagedGateSilent = async (): Promise<void> => {
|
|
|
150
200
|
await runMenuAuditGate(gateParams);
|
|
151
201
|
};
|
|
152
202
|
|
|
203
|
+
export const runUnstagedGateSilentWithBlocked = async (): Promise<
|
|
204
|
+
ConsumerRuntimeGateResult | void
|
|
205
|
+
> => {
|
|
206
|
+
const gateParams = buildMenuGateParams({
|
|
207
|
+
stage: 'PRE_COMMIT',
|
|
208
|
+
scope: { kind: 'unstaged' },
|
|
209
|
+
});
|
|
210
|
+
return await runMenuAuditGateWithBlocked(gateParams);
|
|
211
|
+
};
|
|
212
|
+
|
|
153
213
|
const runMenuAuditGate = async (
|
|
154
214
|
gateParams: ReturnType<typeof buildMenuGateParams>
|
|
155
215
|
): Promise<void> => {
|
|
156
|
-
await
|
|
216
|
+
await runMenuAuditGateWithBlocked(gateParams);
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
const runMenuAuditGateWithBlocked = async (
|
|
220
|
+
gateParams: ReturnType<typeof buildMenuGateParams>,
|
|
221
|
+
dependencies: MenuGateDependencies = defaultDependencies
|
|
222
|
+
): Promise<ConsumerRuntimeGateResult | void> => {
|
|
223
|
+
let blocked: ConsumerRuntimeGateResult['blocked'];
|
|
224
|
+
|
|
225
|
+
await dependencies.runPlatformGate({
|
|
157
226
|
...gateParams,
|
|
158
227
|
auditMode: 'engine',
|
|
159
228
|
sddDecisionOverride: {
|
|
@@ -163,6 +232,19 @@ const runMenuAuditGate = async (
|
|
|
163
232
|
},
|
|
164
233
|
dependencies: {
|
|
165
234
|
printGateFindings: () => {},
|
|
235
|
+
notifyGateBlocked: (params) => {
|
|
236
|
+
blocked = {
|
|
237
|
+
stage: params.stage,
|
|
238
|
+
totalViolations: params.totalViolations,
|
|
239
|
+
causeCode: params.causeCode,
|
|
240
|
+
causeMessage: params.causeMessage,
|
|
241
|
+
remediation: params.remediation,
|
|
242
|
+
};
|
|
243
|
+
return {
|
|
244
|
+
delivered: false,
|
|
245
|
+
reason: 'menu-silent-capture',
|
|
246
|
+
};
|
|
247
|
+
},
|
|
166
248
|
evaluatePlatformGateFindings: (params) =>
|
|
167
249
|
evaluatePlatformGateFindings(params, {
|
|
168
250
|
loadHeuristicsConfig: () => ({
|
|
@@ -172,6 +254,8 @@ const runMenuAuditGate = async (
|
|
|
172
254
|
}),
|
|
173
255
|
},
|
|
174
256
|
});
|
|
257
|
+
|
|
258
|
+
return blocked ? { blocked } : undefined;
|
|
175
259
|
};
|
|
176
260
|
|
|
177
261
|
const runRepoAndStagedPrePushGateSilentWithDependencies = async (
|
|
@@ -198,5 +282,6 @@ const runRepoAndStagedPrePushGateSilentWithDependencies = async (
|
|
|
198
282
|
};
|
|
199
283
|
|
|
200
284
|
export const __testables = {
|
|
285
|
+
runMenuAuditGateWithBlocked,
|
|
201
286
|
runRepoAndStagedPrePushGateSilentWithDependencies,
|
|
202
287
|
};
|
|
@@ -3,7 +3,7 @@ import type { MenuLayoutGroup } from './framework-menu-layout-types';
|
|
|
3
3
|
export const CONSUMER_MENU_LAYOUT: ReadonlyArray<MenuLayoutGroup> = [
|
|
4
4
|
{
|
|
5
5
|
key: 'read-only-gates',
|
|
6
|
-
title: '
|
|
6
|
+
title: 'Legacy Audit Flows',
|
|
7
7
|
itemIds: ['1', '2', '3', '4'],
|
|
8
8
|
},
|
|
9
9
|
{
|
|
@@ -13,12 +13,12 @@ export const CONSUMER_MENU_LAYOUT: ReadonlyArray<MenuLayoutGroup> = [
|
|
|
13
13
|
},
|
|
14
14
|
{
|
|
15
15
|
key: 'export',
|
|
16
|
-
title: 'Legacy
|
|
16
|
+
title: 'Legacy Export',
|
|
17
17
|
itemIds: ['8'],
|
|
18
18
|
},
|
|
19
19
|
{
|
|
20
20
|
key: 'legacy-read-only-diagnostics',
|
|
21
|
-
title: 'Legacy
|
|
21
|
+
title: 'Legacy Diagnostics',
|
|
22
22
|
itemIds: ['5', '6', '7', '9'],
|
|
23
23
|
},
|
|
24
24
|
{
|
|
@@ -12,9 +12,15 @@ export const formatLegacyStatusLine = (summary: LegacyAuditSummary): string => {
|
|
|
12
12
|
};
|
|
13
13
|
|
|
14
14
|
const formatPlatformBlock = (platform: PlatformSummary): string => {
|
|
15
|
+
const total =
|
|
16
|
+
platform.bySeverity.CRITICAL
|
|
17
|
+
+ platform.bySeverity.HIGH
|
|
18
|
+
+ platform.bySeverity.MEDIUM
|
|
19
|
+
+ platform.bySeverity.LOW;
|
|
15
20
|
const lines = [
|
|
16
21
|
`┌ Platform: ${platform.platform}`,
|
|
17
22
|
`│ ● CRITICAL: ${platform.bySeverity.CRITICAL} ● HIGH: ${platform.bySeverity.HIGH} ● MEDIUM: ${platform.bySeverity.MEDIUM} ● LOW: ${platform.bySeverity.LOW}`,
|
|
23
|
+
`│ TOTAL: ${total}`,
|
|
18
24
|
`│ Files affected: ${platform.filesAffected}`,
|
|
19
25
|
'│ Top violations:',
|
|
20
26
|
];
|
|
@@ -11,12 +11,16 @@ import {
|
|
|
11
11
|
runRepoAndStagedGate,
|
|
12
12
|
runRepoAndStagedGateSilent,
|
|
13
13
|
runRepoGateSilent,
|
|
14
|
+
runRepoGateSilentWithBlocked,
|
|
14
15
|
runStagedGate,
|
|
15
16
|
runStagedGateSilent,
|
|
17
|
+
runStagedGateSilentWithBlocked,
|
|
16
18
|
runWorkingTreeGateSilent,
|
|
19
|
+
runWorkingTreeGateSilentWithBlocked,
|
|
17
20
|
runRepoAndStagedPrePushGateSilent,
|
|
18
21
|
runWorkingTreePrePushGateSilent,
|
|
19
|
-
|
|
22
|
+
runWorkingTreePrePushGateSilentWithBlocked,
|
|
23
|
+
runUnstagedGateSilentWithBlocked,
|
|
20
24
|
} from './framework-menu-gate-lib';
|
|
21
25
|
import { createFrameworkMenuPrompts } from './framework-menu-prompts';
|
|
22
26
|
import { resolveDefaultRangeFrom } from './framework-menu-runners';
|
|
@@ -60,12 +64,12 @@ const menu = async (): Promise<void> => {
|
|
|
60
64
|
printActiveSkillsBundles,
|
|
61
65
|
});
|
|
62
66
|
const consumerRuntime = createConsumerMenuRuntime({
|
|
63
|
-
runRepoGate:
|
|
67
|
+
runRepoGate: runRepoGateSilentWithBlocked,
|
|
64
68
|
runRepoAndStagedGate: runRepoAndStagedPrePushGateSilent,
|
|
65
|
-
runStagedGate:
|
|
66
|
-
runUnstagedGate:
|
|
67
|
-
runWorkingTreeGate:
|
|
68
|
-
runWorkingTreePreCommitGate:
|
|
69
|
+
runStagedGate: runStagedGateSilentWithBlocked,
|
|
70
|
+
runUnstagedGate: runUnstagedGateSilentWithBlocked,
|
|
71
|
+
runWorkingTreeGate: runWorkingTreePrePushGateSilentWithBlocked,
|
|
72
|
+
runWorkingTreePreCommitGate: runWorkingTreeGateSilentWithBlocked,
|
|
69
73
|
write: (text) => {
|
|
70
74
|
output.write(text);
|
|
71
75
|
},
|
|
@@ -15,10 +15,11 @@ import packageJson from '../package.json';
|
|
|
15
15
|
const runNpmStep = (
|
|
16
16
|
workspace: SmokeWorkspace,
|
|
17
17
|
args: string[],
|
|
18
|
-
context: string
|
|
18
|
+
context: string,
|
|
19
|
+
env?: NodeJS.ProcessEnv
|
|
19
20
|
): void => {
|
|
20
21
|
assertSuccess(
|
|
21
|
-
runCommand({ cwd: workspace.consumerRepo, executable: 'npm', args }),
|
|
22
|
+
runCommand({ cwd: workspace.consumerRepo, executable: 'npm', args, env }),
|
|
22
23
|
context
|
|
23
24
|
);
|
|
24
25
|
};
|
|
@@ -29,10 +30,15 @@ export const installTarballIntoConsumerRepo = (
|
|
|
29
30
|
runNpmStep(workspace, ['init', '-y'], 'npm init');
|
|
30
31
|
writeFileSync(
|
|
31
32
|
join(workspace.consumerRepo, '.gitignore'),
|
|
32
|
-
'node_modules/\n.ai_evidence.json\n',
|
|
33
|
+
'node_modules/\n.ai_evidence.json\n.pumuki/context/\n',
|
|
33
34
|
'utf8'
|
|
34
35
|
);
|
|
35
|
-
runNpmStep(
|
|
36
|
+
runNpmStep(
|
|
37
|
+
workspace,
|
|
38
|
+
['install', workspace.tarballPath ?? ''],
|
|
39
|
+
'npm install <tarball>',
|
|
40
|
+
{ PUMUKI_SKIP_POSTINSTALL: '1' }
|
|
41
|
+
);
|
|
36
42
|
};
|
|
37
43
|
|
|
38
44
|
export const verifyInstalledPackageCanBeRequired = (
|
|
@@ -50,6 +50,25 @@ export const runLifecycleInstallStep = (workspace: SmokeWorkspace): void => {
|
|
|
50
50
|
};
|
|
51
51
|
|
|
52
52
|
export const runLifecyclePreWriteStep = (workspace: SmokeWorkspace): void => {
|
|
53
|
+
const contextCommand = resolveConsumerPumukiCommand({
|
|
54
|
+
consumerRepo: workspace.consumerRepo,
|
|
55
|
+
binary: 'pumuki',
|
|
56
|
+
args: ['context', 'init'],
|
|
57
|
+
});
|
|
58
|
+
const contextResult = runCommand({
|
|
59
|
+
cwd: workspace.consumerRepo,
|
|
60
|
+
executable: contextCommand.executable,
|
|
61
|
+
args: contextCommand.args,
|
|
62
|
+
env: {
|
|
63
|
+
PUMUKI_DISABLE_SYSTEM_NOTIFICATIONS: '1',
|
|
64
|
+
PUMUKI_SYSTEM_NOTIFICATIONS: '0',
|
|
65
|
+
PUMUKI_NOTIFICATIONS: '0',
|
|
66
|
+
},
|
|
67
|
+
});
|
|
68
|
+
pushCommandLog(workspace.commandLog, contextResult);
|
|
69
|
+
assertNoFatalOutput(contextResult, 'pumuki context init');
|
|
70
|
+
assertSuccess(contextResult, 'pumuki context init');
|
|
71
|
+
|
|
53
72
|
const command = resolveConsumerPumukiCommand({
|
|
54
73
|
consumerRepo: workspace.consumerRepo,
|
|
55
74
|
binary: 'pumuki-pre-write',
|