pumuki 6.3.104 → 6.3.106
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 +14 -0
- package/VERSION +1 -1
- package/docs/operations/RELEASE_NOTES.md +12 -0
- package/integrations/lifecycle/cli.ts +50 -15
- package/integrations/lifecycle/cliSdd.ts +4 -4
- package/integrations/mcp/autoExecuteAiStart.ts +37 -6
- package/integrations/sdd/policy.ts +28 -20
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,20 @@ This project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [6.3.106] - 2026-04-22
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- **Activación advisory de SDD/PRE_WRITE fijada al runtime diagnosticado:** `sdd validate` deja de devolver `activation_command` con `pumuki@latest` cuando el namespace experimental está desactivado por defecto.
|
|
14
|
+
- **Session guidance reproducible en SDD:** las instrucciones de `session --refresh` y `session --open` también quedan fijadas a la versión efectiva del runtime en lugar de depender de `latest`.
|
|
15
|
+
|
|
16
|
+
## [6.3.105] - 2026-04-22
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- **Remediaciones PRE_WRITE fijadas a la versión diagnosticada:** `sdd validate`, `auto_execute_ai_start` y la remediación por defecto dejan de recomendar `pumuki@latest` y pasan a devolver comandos con la versión efectiva del runtime (`pumuki@6.3.105` en esta línea).
|
|
21
|
+
- **Backport útil de `PUMUKI-INC-089` a la línea publicada:** `main` mantiene la ruta reproducible para `install`, `policy reconcile --strict --json` y la revalidación `PRE_WRITE` sin exigir al consumer adivinar la versión correcta.
|
|
22
|
+
|
|
9
23
|
## [6.3.104] - 2026-04-22
|
|
10
24
|
|
|
11
25
|
### Fixed
|
package/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
v6.3.
|
|
1
|
+
v6.3.106
|
|
@@ -6,6 +6,18 @@ 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-04-22 (v6.3.106)
|
|
10
|
+
|
|
11
|
+
- **Cierre útil del literal residual en RuralGo:** `sdd validate --stage=PRE_WRITE --json` ya no recomienda activar SDD con `pumuki@latest`; devuelve el mismo runtime versionado que está diagnosticando.
|
|
12
|
+
- **Guía de sesión SDD alineada:** `session --refresh` y `session --open` quedan versionados para evitar drift en repos consumidores.
|
|
13
|
+
- **Rollout recomendado:** publicar `pumuki@6.3.106`, repin inmediato en `RuralGo` y revalidar `sdd validate --stage=PRE_WRITE --json` comprobando `activation_command` fijo a `6.3.106`.
|
|
14
|
+
|
|
15
|
+
### 2026-04-22 (v6.3.105)
|
|
16
|
+
|
|
17
|
+
- **Remediación reproducible en la línea publicada:** las rutas bloqueantes de `PRE_WRITE` dejan de sugerir `pumuki@latest` y fijan la versión efectiva del runtime al construir `next_action.command`.
|
|
18
|
+
- **Cobertura MCP alineada:** `auto_execute_ai_start` devuelve las mismas remediaciones versionadas que `sdd validate` para evidence invalid/stale, `active_rule_ids` vacío y policy reconcile estricto.
|
|
19
|
+
- **Rollout recomendado:** publicar `pumuki@6.3.105`, repin inmediato en `RuralGo` y revalidar el command contract de `PRE_WRITE` en `sdd validate`, `auto_execute_ai_start` y hooks reales.
|
|
20
|
+
|
|
9
21
|
### 2026-04-22 (v6.3.104)
|
|
10
22
|
|
|
11
23
|
- **RuralGo hub-aware diagnostics:** `TRACKING_CANONICAL_IN_PROGRESS_INVALID` pasa a enriquecer su mensaje usando `docs/RURALGO_SEGUIMIENTO.md` cuando ese hub es el board canónico del consumer.
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
} from './doctor';
|
|
12
12
|
import { runLifecycleInstall } from './install';
|
|
13
13
|
import { runLifecycleRemove } from './remove';
|
|
14
|
+
import { getCurrentPumukiVersion } from './packageInfo';
|
|
14
15
|
import { readLifecycleStatus } from './status';
|
|
15
16
|
import {
|
|
16
17
|
readLifecycleExperimentalFeaturesSnapshot,
|
|
@@ -1615,10 +1616,26 @@ const printDoctorReport = (
|
|
|
1615
1616
|
};
|
|
1616
1617
|
|
|
1617
1618
|
const PRE_WRITE_TELEMETRY_CHAIN = 'pumuki->mcp->ai_gate->ai_evidence';
|
|
1618
|
-
const
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1619
|
+
const buildPinnedPumukiNpxCommand = (params: {
|
|
1620
|
+
repoRoot?: string;
|
|
1621
|
+
executableAndArgs: string;
|
|
1622
|
+
}): string =>
|
|
1623
|
+
`npx --yes --package pumuki@${getCurrentPumukiVersion({ repoRoot: params.repoRoot })} ${params.executableAndArgs}`;
|
|
1624
|
+
const buildPreWriteInstallRemediationCommand = (repoRoot?: string): string =>
|
|
1625
|
+
buildPinnedPumukiNpxCommand({ repoRoot, executableAndArgs: 'pumuki install' });
|
|
1626
|
+
const buildPreWriteValidateCommand = (params: {
|
|
1627
|
+
repoRoot?: string;
|
|
1628
|
+
stage: SddStage;
|
|
1629
|
+
}): string =>
|
|
1630
|
+
buildPinnedPumukiNpxCommand({
|
|
1631
|
+
repoRoot: params.repoRoot,
|
|
1632
|
+
executableAndArgs: `pumuki sdd validate --stage=${params.stage} --json`,
|
|
1633
|
+
});
|
|
1634
|
+
const buildPreWritePolicyReconcileCommand = (repoRoot?: string): string =>
|
|
1635
|
+
`${buildPinnedPumukiNpxCommand({
|
|
1636
|
+
repoRoot,
|
|
1637
|
+
executableAndArgs: 'pumuki policy reconcile --strict --json',
|
|
1638
|
+
})} && ${buildPreWriteValidateCommand({ repoRoot, stage: 'PRE_WRITE' })}`;
|
|
1622
1639
|
|
|
1623
1640
|
type PreWriteValidationEnvelope = {
|
|
1624
1641
|
sdd: SddEvaluateResult;
|
|
@@ -1653,10 +1670,19 @@ export type PreWriteOpenSpecBootstrapTrace = {
|
|
|
1653
1670
|
details?: string;
|
|
1654
1671
|
};
|
|
1655
1672
|
|
|
1656
|
-
export const
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
`
|
|
1673
|
+
export const buildPreWriteExperimentalEnableAdvisoryCommand = (
|
|
1674
|
+
repoRoot: string = process.cwd()
|
|
1675
|
+
): string =>
|
|
1676
|
+
`PUMUKI_EXPERIMENTAL_PRE_WRITE=advisory ${buildPinnedPumukiNpxCommand(
|
|
1677
|
+
getCurrentPumukiVersion({ repoRoot })
|
|
1678
|
+
)} sdd validate --stage=PRE_WRITE --json`;
|
|
1679
|
+
export const buildSddExperimentalEnableAdvisoryCommand = (
|
|
1680
|
+
stage: SddStage,
|
|
1681
|
+
repoRoot: string = process.cwd()
|
|
1682
|
+
): string =>
|
|
1683
|
+
`PUMUKI_EXPERIMENTAL_SDD=advisory ${buildPinnedPumukiNpxCommand(
|
|
1684
|
+
getCurrentPumukiVersion({ repoRoot })
|
|
1685
|
+
)} sdd validate --stage=${stage} --json`;
|
|
1660
1686
|
const buildAnalyticsExperimentalEnableCommand = (action: AnalyticsHotspotsCommand): string =>
|
|
1661
1687
|
`PUMUKI_EXPERIMENTAL_ANALYTICS=advisory npx --yes --package pumuki@latest pumuki analytics hotspots ${action} --json`;
|
|
1662
1688
|
const SAAS_INGESTION_ENABLE_ADVISORY_COMMAND =
|
|
@@ -1813,8 +1839,11 @@ const PRE_WRITE_HINTS_BY_CODE: Readonly<Record<string, string>> = {
|
|
|
1813
1839
|
MCP_ENTERPRISE_RECEIPT_REPO_ROOT_MISMATCH: 'Genera el recibo MCP en este mismo repositorio.',
|
|
1814
1840
|
};
|
|
1815
1841
|
|
|
1816
|
-
const
|
|
1817
|
-
|
|
1842
|
+
const buildPreWriteDefaultRemediation = (repoRoot?: string): string =>
|
|
1843
|
+
`Corrige la causa bloqueante y vuelve a ejecutar: ${buildPinnedPumukiNpxCommand({
|
|
1844
|
+
repoRoot,
|
|
1845
|
+
executableAndArgs: 'pumuki-pre-write',
|
|
1846
|
+
})}`;
|
|
1818
1847
|
|
|
1819
1848
|
export const PRE_WRITE_OPENSPEC_AUTOREMEDIABLE_CODES = new Set<string>([
|
|
1820
1849
|
'OPENSPEC_MISSING',
|
|
@@ -1838,7 +1867,7 @@ export const resolvePreWriteNextAction = (params: {
|
|
|
1838
1867
|
if (!params.sdd.decision.allowed && PRE_WRITE_OPENSPEC_AUTOREMEDIABLE_CODES.has(params.sdd.decision.code)) {
|
|
1839
1868
|
return {
|
|
1840
1869
|
reason: params.sdd.decision.code,
|
|
1841
|
-
command:
|
|
1870
|
+
command: buildPreWriteInstallRemediationCommand(params.aiGate?.repo_state.repo_root),
|
|
1842
1871
|
};
|
|
1843
1872
|
}
|
|
1844
1873
|
if (!params.aiGate || params.aiGate.allowed) {
|
|
@@ -1850,7 +1879,7 @@ export const resolvePreWriteNextAction = (params: {
|
|
|
1850
1879
|
if (policyReconcileViolation) {
|
|
1851
1880
|
return {
|
|
1852
1881
|
reason: policyReconcileViolation.code,
|
|
1853
|
-
command:
|
|
1882
|
+
command: buildPreWritePolicyReconcileCommand(params.aiGate.repo_state.repo_root),
|
|
1854
1883
|
};
|
|
1855
1884
|
}
|
|
1856
1885
|
const atomicSliceViolation = params.aiGate.violations.find((violation) =>
|
|
@@ -1866,7 +1895,10 @@ export const resolvePreWriteNextAction = (params: {
|
|
|
1866
1895
|
return {
|
|
1867
1896
|
reason: atomicSliceViolation.code,
|
|
1868
1897
|
command:
|
|
1869
|
-
`${firstSliceCommand} &&
|
|
1898
|
+
`${firstSliceCommand} && ${buildPreWriteValidateCommand({
|
|
1899
|
+
repoRoot: params.aiGate.repo_state.repo_root,
|
|
1900
|
+
stage: 'PRE_WRITE',
|
|
1901
|
+
})}`,
|
|
1870
1902
|
};
|
|
1871
1903
|
}
|
|
1872
1904
|
const hasMcpViolation = params.aiGate.violations.some((violation) =>
|
|
@@ -1877,7 +1909,10 @@ export const resolvePreWriteNextAction = (params: {
|
|
|
1877
1909
|
}
|
|
1878
1910
|
return {
|
|
1879
1911
|
reason: 'MCP_ENTERPRISE_RECEIPT',
|
|
1880
|
-
command:
|
|
1912
|
+
command: buildPinnedPumukiNpxCommand({
|
|
1913
|
+
repoRoot: params.aiGate.repo_state.repo_root,
|
|
1914
|
+
executableAndArgs: 'pumuki-pre-write',
|
|
1915
|
+
}),
|
|
1881
1916
|
};
|
|
1882
1917
|
};
|
|
1883
1918
|
|
|
@@ -1888,7 +1923,7 @@ export const resolvePreWriteBlockedRemediation = (params: {
|
|
|
1888
1923
|
if (params.nextAction?.command) {
|
|
1889
1924
|
return params.nextAction.command;
|
|
1890
1925
|
}
|
|
1891
|
-
return PRE_WRITE_HINTS_BY_CODE[params.causeCode] ??
|
|
1926
|
+
return PRE_WRITE_HINTS_BY_CODE[params.causeCode] ?? buildPreWriteDefaultRemediation();
|
|
1892
1927
|
};
|
|
1893
1928
|
|
|
1894
1929
|
const wrapPreWritePanelLine = (value: string, width: number): string[] => {
|
|
@@ -36,7 +36,7 @@ import {
|
|
|
36
36
|
buildPreWriteExperimentalDisabledResult,
|
|
37
37
|
buildSddExperimentalEnableAdvisoryCommand,
|
|
38
38
|
runRawPreWriteAiGateCheck,
|
|
39
|
-
|
|
39
|
+
buildPreWriteExperimentalEnableAdvisoryCommand,
|
|
40
40
|
} from './cli';
|
|
41
41
|
|
|
42
42
|
export const runSddCommand = async (parsed: ParsedArgs, activeDependencies: LifecycleCliDependencies): Promise<number> => {
|
|
@@ -106,7 +106,7 @@ export const runSddCommand = async (parsed: ParsedArgs, activeDependencies: Life
|
|
|
106
106
|
},
|
|
107
107
|
next_action: {
|
|
108
108
|
reason: 'PRE_WRITE_EXPERIMENTAL_DISABLED',
|
|
109
|
-
command:
|
|
109
|
+
command: buildPreWriteExperimentalEnableAdvisoryCommand(process.cwd()),
|
|
110
110
|
},
|
|
111
111
|
},
|
|
112
112
|
null,
|
|
@@ -127,7 +127,7 @@ export const runSddCommand = async (parsed: ParsedArgs, activeDependencies: Life
|
|
|
127
127
|
`[pumuki][sdd] pre-write enforcement: mode=${preWriteEnforcement.mode} source=${preWriteEnforcement.source} blocking=no`
|
|
128
128
|
);
|
|
129
129
|
writeInfo(
|
|
130
|
-
`[pumuki][sdd] next action (PRE_WRITE_EXPERIMENTAL_DISABLED): ${
|
|
130
|
+
`[pumuki][sdd] next action (PRE_WRITE_EXPERIMENTAL_DISABLED): ${buildPreWriteExperimentalEnableAdvisoryCommand(process.cwd())}`
|
|
131
131
|
);
|
|
132
132
|
}
|
|
133
133
|
return 0;
|
|
@@ -209,7 +209,7 @@ export const runSddCommand = async (parsed: ParsedArgs, activeDependencies: Life
|
|
|
209
209
|
!aiGate && result.decision.code === 'SDD_EXPERIMENTAL_DISABLED'
|
|
210
210
|
? {
|
|
211
211
|
reason: 'SDD_EXPERIMENTAL_DISABLED',
|
|
212
|
-
command: buildSddExperimentalEnableAdvisoryCommand(result.stage),
|
|
212
|
+
command: buildSddExperimentalEnableAdvisoryCommand(result.stage, process.cwd()),
|
|
213
213
|
}
|
|
214
214
|
: undefined;
|
|
215
215
|
if (parsed.json) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { evaluateAiGate, type AiGateStage, type AiGateViolation } from '../gate/evaluateAiGate';
|
|
2
2
|
import { collectWorktreeAtomicSlices } from '../git/worktreeAtomicSlices';
|
|
3
|
+
import { getCurrentPumukiVersion } from '../lifecycle/packageInfo';
|
|
3
4
|
import { resolveLearningContextExperimentalFeature } from '../policy/experimentalFeatures';
|
|
4
5
|
import { readSddLearningContext, type SddLearningContext } from '../sdd/learningInsights';
|
|
5
6
|
|
|
@@ -56,6 +57,12 @@ const confidenceFromViolation = (violationCode: string | null): number => {
|
|
|
56
57
|
return 50;
|
|
57
58
|
};
|
|
58
59
|
|
|
60
|
+
const buildPinnedPumukiNpxCommand = (params: {
|
|
61
|
+
repoRoot: string;
|
|
62
|
+
executableAndArgs: string;
|
|
63
|
+
}): string =>
|
|
64
|
+
`npx --yes --package pumuki@${getCurrentPumukiVersion({ repoRoot: params.repoRoot })} ${params.executableAndArgs}`;
|
|
65
|
+
|
|
59
66
|
const nextActionFromViolation = (
|
|
60
67
|
violation: AiGateViolation | undefined,
|
|
61
68
|
repoRoot: string
|
|
@@ -74,7 +81,10 @@ const nextActionFromViolation = (
|
|
|
74
81
|
return {
|
|
75
82
|
kind: 'run_command',
|
|
76
83
|
message: 'Regenera o refresca evidencia y vuelve a evaluar PRE_WRITE.',
|
|
77
|
-
command:
|
|
84
|
+
command: buildPinnedPumukiNpxCommand({
|
|
85
|
+
repoRoot,
|
|
86
|
+
executableAndArgs: 'pumuki sdd validate --stage=PRE_WRITE --json',
|
|
87
|
+
}),
|
|
78
88
|
};
|
|
79
89
|
case 'EVIDENCE_ACTIVE_RULE_IDS_EMPTY_FOR_CODE_CHANGES':
|
|
80
90
|
return {
|
|
@@ -82,7 +92,13 @@ const nextActionFromViolation = (
|
|
|
82
92
|
message:
|
|
83
93
|
'No hay active_rule_ids para plataforma de código detectada. Reconciliación strict de policy/skills y revalidación PRE_WRITE.',
|
|
84
94
|
command:
|
|
85
|
-
|
|
95
|
+
`${buildPinnedPumukiNpxCommand({
|
|
96
|
+
repoRoot,
|
|
97
|
+
executableAndArgs: 'pumuki policy reconcile --strict --json',
|
|
98
|
+
})} && ${buildPinnedPumukiNpxCommand({
|
|
99
|
+
repoRoot,
|
|
100
|
+
executableAndArgs: 'pumuki sdd validate --stage=PRE_WRITE --json',
|
|
101
|
+
})}`,
|
|
86
102
|
};
|
|
87
103
|
case 'EVIDENCE_PLATFORM_SKILLS_SCOPE_INCOMPLETE':
|
|
88
104
|
case 'EVIDENCE_PLATFORM_SKILLS_BUNDLES_MISSING':
|
|
@@ -91,7 +107,10 @@ const nextActionFromViolation = (
|
|
|
91
107
|
kind: 'run_command',
|
|
92
108
|
message:
|
|
93
109
|
'Completa cobertura de skills por plataforma (prefijos + bundles) y revalida PRE_WRITE.',
|
|
94
|
-
command:
|
|
110
|
+
command: buildPinnedPumukiNpxCommand({
|
|
111
|
+
repoRoot,
|
|
112
|
+
executableAndArgs: 'pumuki sdd validate --stage=PRE_WRITE --json',
|
|
113
|
+
}),
|
|
95
114
|
};
|
|
96
115
|
case 'EVIDENCE_PLATFORM_CRITICAL_SKILLS_RULES_MISSING':
|
|
97
116
|
case 'EVIDENCE_CROSS_PLATFORM_CRITICAL_ENFORCEMENT_INCOMPLETE':
|
|
@@ -100,7 +119,13 @@ const nextActionFromViolation = (
|
|
|
100
119
|
message:
|
|
101
120
|
'Reconcilia policy/skills en modo estricto (incluida skills.ios.critical-test-quality cuando aplique) y revalida PRE_WRITE.',
|
|
102
121
|
command:
|
|
103
|
-
|
|
122
|
+
`${buildPinnedPumukiNpxCommand({
|
|
123
|
+
repoRoot,
|
|
124
|
+
executableAndArgs: 'pumuki policy reconcile --strict --json',
|
|
125
|
+
})} && ${buildPinnedPumukiNpxCommand({
|
|
126
|
+
repoRoot,
|
|
127
|
+
executableAndArgs: 'pumuki sdd validate --stage=PRE_WRITE --json',
|
|
128
|
+
})}`,
|
|
104
129
|
};
|
|
105
130
|
case 'EVIDENCE_PREWRITE_WORKTREE_OVER_LIMIT':
|
|
106
131
|
case 'EVIDENCE_PREWRITE_WORKTREE_WARN':
|
|
@@ -117,7 +142,10 @@ const nextActionFromViolation = (
|
|
|
117
142
|
message:
|
|
118
143
|
`Particiona el worktree en slices atómicos por scope. Primer lote sugerido: ${firstSlice?.scope ?? 'scope-desconocido'}.`,
|
|
119
144
|
command:
|
|
120
|
-
`${firstSlice?.staged_command ?? 'git add -p'} &&
|
|
145
|
+
`${firstSlice?.staged_command ?? 'git add -p'} && ${buildPinnedPumukiNpxCommand({
|
|
146
|
+
repoRoot,
|
|
147
|
+
executableAndArgs: 'pumuki sdd validate --stage=PRE_WRITE --json',
|
|
148
|
+
})}`,
|
|
121
149
|
};
|
|
122
150
|
}
|
|
123
151
|
}
|
|
@@ -126,7 +154,10 @@ const nextActionFromViolation = (
|
|
|
126
154
|
message:
|
|
127
155
|
'Particiona el worktree en slices atómicos y revalida PRE_WRITE para continuar sin fricción.',
|
|
128
156
|
command:
|
|
129
|
-
|
|
157
|
+
`git status --short && git add -p && ${buildPinnedPumukiNpxCommand({
|
|
158
|
+
repoRoot,
|
|
159
|
+
executableAndArgs: 'pumuki sdd validate --stage=PRE_WRITE --json',
|
|
160
|
+
})}`,
|
|
130
161
|
};
|
|
131
162
|
case 'GITFLOW_PROTECTED_BRANCH':
|
|
132
163
|
return {
|
|
@@ -13,6 +13,7 @@ import {
|
|
|
13
13
|
refreshSddSession,
|
|
14
14
|
} from './sessionStore';
|
|
15
15
|
import { resolveDegradedMode } from '../gate/degradedMode';
|
|
16
|
+
import { getCurrentPumukiVersion } from '../lifecycle/packageInfo';
|
|
16
17
|
import { resolveSddCompletenessEnforcement } from '../policy/sddCompletenessEnforcement';
|
|
17
18
|
import { resolveSddExperimentalFeature } from '../policy/experimentalFeatures';
|
|
18
19
|
import type {
|
|
@@ -22,16 +23,20 @@ import type {
|
|
|
22
23
|
SddStatusPayload,
|
|
23
24
|
} from './types';
|
|
24
25
|
|
|
25
|
-
const SDD_SESSION_REFRESH_COMMAND =
|
|
26
|
-
'npx --yes --package pumuki@latest pumuki sdd session --refresh --ttl-minutes=90';
|
|
27
|
-
const SDD_SESSION_OPEN_AUTO_COMMAND =
|
|
28
|
-
'npx --yes --package pumuki@latest pumuki sdd session --open --change=auto';
|
|
29
|
-
const SDD_SESSION_OPEN_EXPLICIT_COMMAND =
|
|
30
|
-
'npx --yes --package pumuki@latest pumuki sdd session --open --change=<id>';
|
|
31
26
|
const SDD_COMPLETENESS_CONTRACT_VERSION = '1.0';
|
|
32
27
|
|
|
33
|
-
const
|
|
34
|
-
`
|
|
28
|
+
const buildPinnedPumukiNpxCommand = (version: string): string =>
|
|
29
|
+
`npx --yes --package pumuki@${version} pumuki`;
|
|
30
|
+
const buildSddSessionRefreshCommand = (repoRoot: string): string =>
|
|
31
|
+
`${buildPinnedPumukiNpxCommand(getCurrentPumukiVersion({ repoRoot }))} sdd session --refresh --ttl-minutes=90`;
|
|
32
|
+
const buildSddSessionOpenAutoCommand = (repoRoot: string): string =>
|
|
33
|
+
`${buildPinnedPumukiNpxCommand(getCurrentPumukiVersion({ repoRoot }))} sdd session --open --change=auto`;
|
|
34
|
+
const buildSddSessionOpenExplicitCommand = (repoRoot: string): string =>
|
|
35
|
+
`${buildPinnedPumukiNpxCommand(getCurrentPumukiVersion({ repoRoot }))} sdd session --open --change=<id>`;
|
|
36
|
+
const buildSddExperimentalEnableCommand = (stage: SddStage, repoRoot: string): string =>
|
|
37
|
+
`PUMUKI_EXPERIMENTAL_SDD=advisory ${buildPinnedPumukiNpxCommand(
|
|
38
|
+
getCurrentPumukiVersion({ repoRoot })
|
|
39
|
+
)} sdd validate --stage=${stage} --json`;
|
|
35
40
|
|
|
36
41
|
const resolveMissingSessionGuidance = (repoRoot: string): {
|
|
37
42
|
message: string;
|
|
@@ -40,15 +45,17 @@ const resolveMissingSessionGuidance = (repoRoot: string): {
|
|
|
40
45
|
suggestedChangeId?: string;
|
|
41
46
|
availableChangeIds: ReadonlyArray<string>;
|
|
42
47
|
} => {
|
|
48
|
+
const sessionOpenAutoCommand = buildSddSessionOpenAutoCommand(repoRoot);
|
|
49
|
+
const sessionOpenExplicitCommand = buildSddSessionOpenExplicitCommand(repoRoot);
|
|
43
50
|
const availableChangeIds = listActiveOpenSpecChangeIds(repoRoot);
|
|
44
51
|
if (availableChangeIds.length === 1) {
|
|
45
52
|
const suggestedChangeId = availableChangeIds[0] ?? '';
|
|
46
53
|
const command =
|
|
47
|
-
|
|
54
|
+
`${buildPinnedPumukiNpxCommand(getCurrentPumukiVersion({ repoRoot }))} sdd session --open --change=${suggestedChangeId}`;
|
|
48
55
|
return {
|
|
49
56
|
message: `SDD session is not active. Run \`${command}\` and retry.`,
|
|
50
57
|
command,
|
|
51
|
-
fallbackCommand:
|
|
58
|
+
fallbackCommand: sessionOpenAutoCommand,
|
|
52
59
|
suggestedChangeId,
|
|
53
60
|
availableChangeIds,
|
|
54
61
|
};
|
|
@@ -56,17 +63,17 @@ const resolveMissingSessionGuidance = (repoRoot: string): {
|
|
|
56
63
|
if (availableChangeIds.length > 1) {
|
|
57
64
|
return {
|
|
58
65
|
message:
|
|
59
|
-
`SDD session is not active. Run \`${
|
|
66
|
+
`SDD session is not active. Run \`${sessionOpenExplicitCommand}\` ` +
|
|
60
67
|
`with one active change id. Active changes: ${availableChangeIds.join(', ')}.`,
|
|
61
|
-
command:
|
|
62
|
-
fallbackCommand:
|
|
68
|
+
command: sessionOpenExplicitCommand,
|
|
69
|
+
fallbackCommand: sessionOpenExplicitCommand,
|
|
63
70
|
availableChangeIds,
|
|
64
71
|
};
|
|
65
72
|
}
|
|
66
73
|
return {
|
|
67
|
-
message: `SDD session is not active. Run \`${
|
|
68
|
-
command:
|
|
69
|
-
fallbackCommand:
|
|
74
|
+
message: `SDD session is not active. Run \`${sessionOpenAutoCommand}\` and retry.`,
|
|
75
|
+
command: sessionOpenAutoCommand,
|
|
76
|
+
fallbackCommand: sessionOpenAutoCommand,
|
|
70
77
|
availableChangeIds,
|
|
71
78
|
};
|
|
72
79
|
};
|
|
@@ -181,8 +188,9 @@ const evaluateSessionRequirements = (params: {
|
|
|
181
188
|
);
|
|
182
189
|
}
|
|
183
190
|
if (!status.session.valid || !status.session.changeId) {
|
|
191
|
+
const refreshCommand = buildSddSessionRefreshCommand(params.repoRoot);
|
|
184
192
|
const details: Record<string, string | boolean> = {
|
|
185
|
-
command:
|
|
193
|
+
command: refreshCommand,
|
|
186
194
|
autoRefreshEnabled: params.autoRefreshEnabled,
|
|
187
195
|
autoRefreshAttempted: params.autoRefreshAttempted,
|
|
188
196
|
};
|
|
@@ -191,8 +199,8 @@ const evaluateSessionRequirements = (params: {
|
|
|
191
199
|
}
|
|
192
200
|
const message =
|
|
193
201
|
params.autoRefreshAttempted && params.autoRefreshError
|
|
194
|
-
? `SDD session is invalid or expired. Auto-refresh failed (${params.autoRefreshError}). Run \`${
|
|
195
|
-
: `SDD session is invalid or expired. Run \`${
|
|
202
|
+
? `SDD session is invalid or expired. Auto-refresh failed (${params.autoRefreshError}). Run \`${refreshCommand}\` or reopen it.`
|
|
203
|
+
: `SDD session is invalid or expired. Run \`${refreshCommand}\` or reopen it.`;
|
|
196
204
|
return blocked(
|
|
197
205
|
'SDD_SESSION_INVALID',
|
|
198
206
|
message,
|
|
@@ -327,7 +335,7 @@ export const evaluateSddPolicy = (params: {
|
|
|
327
335
|
experimentalSource: sddExperimentalFeature.source,
|
|
328
336
|
activation_env: sddExperimentalFeature.activationVariable,
|
|
329
337
|
legacy_activation_env: sddExperimentalFeature.legacyActivationVariable,
|
|
330
|
-
activation_command: buildSddExperimentalEnableCommand(params.stage),
|
|
338
|
+
activation_command: buildSddExperimentalEnableCommand(params.stage, params.repoRoot),
|
|
331
339
|
},
|
|
332
340
|
},
|
|
333
341
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pumuki",
|
|
3
|
-
"version": "6.3.
|
|
3
|
+
"version": "6.3.106",
|
|
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": {
|