pumuki 6.3.117 → 6.3.119
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 +13 -0
- package/VERSION +1 -1
- package/integrations/lifecycle/cli.ts +20 -0
- package/integrations/mcp/enterpriseServer.ts +40 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,19 @@ This project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [6.3.119] - 2026-04-28
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- **Contrato CLI estable para menú:** `pumuki menu --help` deja de fallar como comando desconocido y `pumuki menu` delega en el runtime de menú existente (`pumuki-framework`), cerrando `PUMUKI-INC-111` para consumers como RuralGo.
|
|
14
|
+
|
|
15
|
+
## [6.3.118] - 2026-04-28
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- **Guard PRE_WRITE para editores/agentes vía MCP:** el catálogo enterprise expone `pre_write_guard`, una tool no mutante que ejecuta `audit --stage=PRE_WRITE --json` y devuelve `findings` accionables antes de permitir continuar una edición/restauración de ficheros.
|
|
20
|
+
- **Cierre operativo de `PUMUKI-INC-109`:** RuralGo ya tiene una ruta MCP explícita para bloquear antes de escribir, no sólo en commit/gate posterior.
|
|
21
|
+
|
|
9
22
|
## [6.3.117] - 2026-04-28
|
|
10
23
|
|
|
11
24
|
### Fixed
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
v6.3.
|
|
1
|
+
v6.3.119
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { mkdirSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { spawnSync } from 'node:child_process';
|
|
2
3
|
import { dirname, isAbsolute, relative, resolve } from 'node:path';
|
|
3
4
|
import type { GatePolicy } from '../../core/gate/GatePolicy';
|
|
4
5
|
import { runPlatformGate } from '../git/runPlatformGate';
|
|
@@ -84,6 +85,7 @@ type LifecycleCommand =
|
|
|
84
85
|
| 'update'
|
|
85
86
|
| 'doctor'
|
|
86
87
|
| 'status'
|
|
88
|
+
| 'menu'
|
|
87
89
|
| 'watch'
|
|
88
90
|
| 'loop'
|
|
89
91
|
| 'sdd'
|
|
@@ -190,6 +192,7 @@ Pumuki lifecycle commands:
|
|
|
190
192
|
pumuki doctor [--remote-checks] [--deep] [--parity] [--json]
|
|
191
193
|
pumuki audit [--stage=PRE_WRITE|PRE_COMMIT|PRE_PUSH|CI] [--engine] [--json]
|
|
192
194
|
pumuki status [--json] [--remote-checks]
|
|
195
|
+
pumuki menu
|
|
193
196
|
pumuki watch [--stage=PRE_COMMIT|PRE_PUSH|CI] [--scope=workingTree|staged|repoAndStaged|repo] [--severity=critical|high|medium|low] [--interval-ms=<n>] [--notify-cooldown-ms=<n>] [--no-notify] [--once|--iterations=<n>] [--json]
|
|
194
197
|
pumuki loop run --objective=<text> [--max-attempts=<n>] [--json]
|
|
195
198
|
pumuki loop status --session=<session-id> [--json]
|
|
@@ -229,6 +232,7 @@ const isLifecycleCommand = (value: string): value is LifecycleCommand =>
|
|
|
229
232
|
value === 'update' ||
|
|
230
233
|
value === 'doctor' ||
|
|
231
234
|
value === 'status' ||
|
|
235
|
+
value === 'menu' ||
|
|
232
236
|
value === 'watch' ||
|
|
233
237
|
value === 'loop' ||
|
|
234
238
|
value === 'sdd' ||
|
|
@@ -559,6 +563,19 @@ const printHotspotsPublishDiagnostics = (diagnostics: HotspotsPublishDiagnostics
|
|
|
559
563
|
}
|
|
560
564
|
};
|
|
561
565
|
|
|
566
|
+
const runFrameworkMenuShim = (argv: ReadonlyArray<string>): number => {
|
|
567
|
+
const frameworkMenuBin = resolve(__dirname, '../../bin/pumuki-framework.js');
|
|
568
|
+
const result = spawnSync(process.execPath, [frameworkMenuBin, ...argv], {
|
|
569
|
+
stdio: 'inherit',
|
|
570
|
+
env: process.env,
|
|
571
|
+
});
|
|
572
|
+
if (result.error) {
|
|
573
|
+
writeError(`[pumuki] menu failed to start: ${result.error.message}`);
|
|
574
|
+
return 1;
|
|
575
|
+
}
|
|
576
|
+
return typeof result.status === 'number' ? result.status : 1;
|
|
577
|
+
};
|
|
578
|
+
|
|
562
579
|
export const parseLifecycleCliArgs = (argv: ReadonlyArray<string>): ParsedArgs => {
|
|
563
580
|
const commandRaw = argv[0];
|
|
564
581
|
if (!commandRaw || commandRaw === '--help' || commandRaw === '-h') {
|
|
@@ -2463,6 +2480,9 @@ export const runLifecycleCli = async (
|
|
|
2463
2480
|
}
|
|
2464
2481
|
return 0;
|
|
2465
2482
|
}
|
|
2483
|
+
case 'menu': {
|
|
2484
|
+
return runFrameworkMenuShim(argv.slice(1));
|
|
2485
|
+
}
|
|
2466
2486
|
case 'watch': {
|
|
2467
2487
|
const watchResult = await activeDependencies.runLifecycleWatch(
|
|
2468
2488
|
{
|
|
@@ -4,7 +4,7 @@ import type { Server } from 'node:http';
|
|
|
4
4
|
import { execFileSync as runBinarySync } from 'node:child_process';
|
|
5
5
|
import { existsSync } from 'node:fs';
|
|
6
6
|
import { join } from 'node:path';
|
|
7
|
-
import { readLifecycleStatus } from '../lifecycle';
|
|
7
|
+
import { readLifecycleStatus, runLifecycleAudit } from '../lifecycle';
|
|
8
8
|
import { resolveMcpEnterpriseExperimentalFeature } from '../policy/experimentalFeatures';
|
|
9
9
|
import { evaluateSddPolicy, readSddStatus } from '../sdd';
|
|
10
10
|
import type { SddStage } from '../sdd';
|
|
@@ -75,6 +75,7 @@ const ENTERPRISE_RESOURCE_DESCRIPTORS: ReadonlyArray<{
|
|
|
75
75
|
];
|
|
76
76
|
|
|
77
77
|
const ENTERPRISE_TOOLS = [
|
|
78
|
+
'pre_write_guard',
|
|
78
79
|
'ai_gate_check',
|
|
79
80
|
'pre_flight_check',
|
|
80
81
|
'auto_execute_ai_start',
|
|
@@ -91,6 +92,12 @@ const ENTERPRISE_TOOL_DESCRIPTORS: ReadonlyArray<{
|
|
|
91
92
|
mutating: boolean;
|
|
92
93
|
safeByDefault: boolean;
|
|
93
94
|
}> = [
|
|
95
|
+
{
|
|
96
|
+
name: 'pre_write_guard',
|
|
97
|
+
description: 'Runs the PRE_WRITE audit gate and returns actionable findings before an editor/agent writes code.',
|
|
98
|
+
mutating: false,
|
|
99
|
+
safeByDefault: true,
|
|
100
|
+
},
|
|
94
101
|
{
|
|
95
102
|
name: 'ai_gate_check',
|
|
96
103
|
description: 'Reads .ai_evidence.json and reports AI gate compatibility status.',
|
|
@@ -382,13 +389,41 @@ const evaluateCriticalToolGuard = (
|
|
|
382
389
|
}
|
|
383
390
|
};
|
|
384
391
|
|
|
385
|
-
const executeEnterpriseTool = (
|
|
392
|
+
const executeEnterpriseTool = async (
|
|
386
393
|
repoRoot: string,
|
|
387
394
|
toolName: EnterpriseToolName,
|
|
388
395
|
args: Record<string, string | number | boolean | bigint | symbol | null | Date | object>,
|
|
389
396
|
dryRun: boolean
|
|
390
|
-
): EnterpriseToolExecution => {
|
|
397
|
+
): Promise<EnterpriseToolExecution> => {
|
|
391
398
|
switch (toolName) {
|
|
399
|
+
case 'pre_write_guard': {
|
|
400
|
+
const audit = await runLifecycleAudit({
|
|
401
|
+
repoRoot,
|
|
402
|
+
stage: 'PRE_WRITE',
|
|
403
|
+
auditMode: 'gate',
|
|
404
|
+
});
|
|
405
|
+
return {
|
|
406
|
+
name: toolName,
|
|
407
|
+
success: audit.gate_exit_code === 0 && audit.blocking_findings_count === 0,
|
|
408
|
+
dryRun: true,
|
|
409
|
+
executed: true,
|
|
410
|
+
warnings: audit.blocking_findings_count > 0
|
|
411
|
+
? ['PRE_WRITE guard blocked before editor write; inspect result.findings.']
|
|
412
|
+
: [],
|
|
413
|
+
data: {
|
|
414
|
+
...audit,
|
|
415
|
+
next_action: audit.blocking_findings_count > 0
|
|
416
|
+
? {
|
|
417
|
+
kind: 'inspect_findings',
|
|
418
|
+
message: 'Corrige los findings bloqueantes antes de escribir o restaurar ficheros.',
|
|
419
|
+
}
|
|
420
|
+
: {
|
|
421
|
+
kind: 'continue',
|
|
422
|
+
message: 'PRE_WRITE guard passed.',
|
|
423
|
+
},
|
|
424
|
+
},
|
|
425
|
+
};
|
|
426
|
+
}
|
|
392
427
|
case 'ai_gate_check': {
|
|
393
428
|
const stage = toSddStage(args.stage, 'PRE_COMMIT');
|
|
394
429
|
const execution = runEnterpriseAiGateCheck({
|
|
@@ -741,7 +776,7 @@ export const startEnterpriseMcpServer = (
|
|
|
741
776
|
return;
|
|
742
777
|
}
|
|
743
778
|
void readJsonBody(req)
|
|
744
|
-
.then((body) => {
|
|
779
|
+
.then(async (body) => {
|
|
745
780
|
if (typeof body !== 'object' || body === null) {
|
|
746
781
|
sendJson(res, 400, {
|
|
747
782
|
error: 'Invalid request body.',
|
|
@@ -814,7 +849,7 @@ export const startEnterpriseMcpServer = (
|
|
|
814
849
|
}
|
|
815
850
|
let result: EnterpriseToolExecution;
|
|
816
851
|
try {
|
|
817
|
-
result = executeEnterpriseTool(
|
|
852
|
+
result = await executeEnterpriseTool(
|
|
818
853
|
repoRoot,
|
|
819
854
|
toolName,
|
|
820
855
|
args,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pumuki",
|
|
3
|
-
"version": "6.3.
|
|
3
|
+
"version": "6.3.119",
|
|
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": {
|