pumuki-ast-hooks 5.6.7 → 5.6.8

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.
@@ -65,6 +65,15 @@ function getStagedFilesSafe() {
65
65
  }
66
66
  }
67
67
 
68
+ function getRecentCommitSubjects(limit = 10) {
69
+ try {
70
+ const output = execSync(`git log -n ${limit} --pretty=%s`, { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] });
71
+ return String(output || '').split('\n').map(s => s.trim()).filter(Boolean);
72
+ } catch (e) {
73
+ return [];
74
+ }
75
+ }
76
+
68
77
  function proposeHumanIntent({ evidence, branch, stagedFiles }) {
69
78
  const safeEvidence = (evidence && typeof evidence === 'object') ? evidence : {};
70
79
  const safeBranch = branch || safeEvidence.current_context?.current_branch || 'unknown';
@@ -91,6 +100,20 @@ function proposeHumanIntent({ evidence, branch, stagedFiles }) {
91
100
  const platformLabel = platforms.length > 0 ? platforms.join('+') : (detectedPlatforms.length > 0 ? detectedPlatforms.join('+') : 'repo');
92
101
 
93
102
  let primaryGoal = `Continue work on ${platformLabel} changes`;
103
+ if (platformLabel === 'repo' && staged.length === 0 && detectedPlatforms.length === 0) {
104
+ const subjects = getRecentCommitSubjects(12).join(' | ').toLowerCase();
105
+ if (subjects.includes('token economy')) {
106
+ primaryGoal = 'Continue token economy improvements (docs + MCP outputs)';
107
+ } else if (subjects.includes('release') || subjects.includes('publish') || subjects.includes('version')) {
108
+ primaryGoal = 'Continue release/publish workflow maintenance';
109
+ } else if (subjects.includes('gitflow')) {
110
+ primaryGoal = 'Continue Git Flow automation maintenance';
111
+ } else if (subjects.includes('mcp')) {
112
+ primaryGoal = 'Continue MCP automation maintenance';
113
+ } else if (subjects.includes('readme') || subjects.includes('docs')) {
114
+ primaryGoal = 'Continue documentation improvements';
115
+ }
116
+ }
94
117
  if (gateStatus === 'BLOCKED') {
95
118
  primaryGoal = `Unblock AI gate by fixing ${platformLabel} violations`;
96
119
  }
@@ -250,7 +273,33 @@ const commands = {
250
273
  const stagedFiles = getStagedFilesSafe();
251
274
  const proposed = proposeHumanIntent({ evidence, branch, stagedFiles });
252
275
 
253
- console.log('\n💡 Suggested Human Intent (proposal only):');
276
+ const shouldSave = !process.argv.includes('--no-save');
277
+ if (shouldSave) {
278
+ const now = new Date();
279
+ const expiresAt = new Date(Date.now() + 24 * 3600000).toISOString();
280
+ evidence.human_intent = {
281
+ primary_goal: proposed.primary_goal,
282
+ secondary_goals: proposed.secondary_goals || [],
283
+ non_goals: proposed.non_goals || [],
284
+ constraints: proposed.constraints || [],
285
+ confidence_level: proposed.confidence_level || 'medium',
286
+ set_by: 'wrap-up',
287
+ set_at: now.toISOString(),
288
+ expires_at: expiresAt,
289
+ preserved_at: now.toISOString(),
290
+ preservation_count: 0
291
+ };
292
+
293
+ try {
294
+ fs.writeFileSync(evidencePath, JSON.stringify(evidence, null, 2), 'utf8');
295
+ } catch (e) {
296
+ if (process.env.DEBUG) {
297
+ process.stderr.write(`[wrap-up] Failed to save human_intent: ${e && e.message ? e.message : String(e)}\n`);
298
+ }
299
+ }
300
+ }
301
+
302
+ console.log(`\n💡 Suggested Human Intent (${shouldSave ? 'auto-saved' : 'proposal only'}):`);
254
303
  console.log(` Primary Goal: ${proposed.primary_goal}`);
255
304
  console.log(` Secondary: ${(proposed.secondary_goals || []).join(', ') || '(none)'}`);
256
305
  console.log(` Constraints: ${(proposed.constraints || []).join(', ') || '(none)'}`);
@@ -259,9 +308,14 @@ const commands = {
259
308
  console.log(` Gate: ${(proposed.derived_from && proposed.derived_from.gate_status) || '(unknown)'}`);
260
309
 
261
310
  const suggestedCmd = `ast-hooks intent set --goal="${proposed.primary_goal}" --confidence=${proposed.confidence_level || 'medium'} --expires=24h`;
262
- console.log('\n✅ To apply it, run:');
263
- console.log(` ${suggestedCmd}`);
264
- console.log('');
311
+ if (shouldSave) {
312
+ console.log('\n✅ Saved to .AI_EVIDENCE.json');
313
+ console.log('');
314
+ } else {
315
+ console.log('\n✅ To apply it, run:');
316
+ console.log(` ${suggestedCmd}`);
317
+ console.log('');
318
+ }
265
319
  } catch (error) {
266
320
  if (process.env.DEBUG) {
267
321
  process.stderr.write(`[wrap-up] Intent suggestion failed: ${error && error.message ? error.message : String(error)}\n`);
@@ -582,4 +636,4 @@ if (require.main === module) {
582
636
  commands[command]();
583
637
  }
584
638
 
585
- module.exports = { commands };
639
+ module.exports = { commands, proposeHumanIntent };
@@ -715,11 +715,19 @@ function cleanupStaleBranches(params) {
715
715
  */
716
716
  async function autoExecuteAIStart(params) {
717
717
  const useCase = getCompositionRoot().getAutoExecuteAIStartUseCase();
718
+ const tokenEconomyRule = 'TOKEN_ECONOMY: Prioritize token/cost efficiency. Batch related checks, avoid redundant scans, reuse cached context where possible, ask the user for missing info instead of exploring blindly, and keep responses concise.';
718
719
 
719
720
  try {
720
- const result = await useCase.execute({
721
- force: params.forceAnalysis || false
722
- });
721
+ const orchestrator = getCompositionRoot().getOrchestrator();
722
+ const analysis = await orchestrator.analyzeContext();
723
+
724
+ const platforms = Array.isArray(analysis?.platforms)
725
+ ? analysis.platforms.map(p => (p && typeof p === 'object' ? (p.platform || p.name) : p)).filter(Boolean)
726
+ : [];
727
+
728
+ const confidence = Number.isFinite(analysis?.confidence) ? analysis.confidence : 0;
729
+
730
+ const result = await useCase.execute(platforms, confidence);
723
731
 
724
732
  if (result.action === 'auto-executed') {
725
733
  sendNotification(
@@ -731,6 +739,7 @@ async function autoExecuteAIStart(params) {
731
739
 
732
740
  return {
733
741
  success: true,
742
+ framework_rules: [tokenEconomyRule],
734
743
  ...result
735
744
  };
736
745
 
@@ -738,6 +747,7 @@ async function autoExecuteAIStart(params) {
738
747
  return {
739
748
  success: false,
740
749
  action: 'error',
750
+ framework_rules: [tokenEconomyRule],
741
751
  message: `Failed to execute AI Start: ${error.message}`
742
752
  };
743
753
  }
@@ -1144,6 +1154,9 @@ function extractCriticalPatterns(content, platform) {
1144
1154
  patterns.push({ platform: 'gold', rule: '✅ OBLIGATORIO composición > herencia', severity: 'MANDATORY' });
1145
1155
  }
1146
1156
 
1157
+ /**
1158
+ * Returns the patterns for the given platforms.
1159
+ */
1147
1160
  return patterns;
1148
1161
  }
1149
1162
 
@@ -1306,6 +1319,7 @@ async function aiGateCheck() {
1306
1319
  const normalizedPlatforms = Array.from(new Set(platformsForRules));
1307
1320
 
1308
1321
  let mandatoryRules = null;
1322
+ const tokenEconomyRule = 'TOKEN_ECONOMY: Prioritize token/cost efficiency. Batch related checks, avoid redundant scans, reuse cached context where possible, ask the user for missing info instead of exploring blindly, and keep responses concise.';
1309
1323
  try {
1310
1324
  const rulesData = await loadPlatformRules(normalizedPlatforms);
1311
1325
  const rulesSample = rulesData.criticalRules.slice(0, 5).map(r => r.rule || r);
@@ -1316,7 +1330,8 @@ async function aiGateCheck() {
1316
1330
  rulesLoaded: Object.keys(rulesData.rules),
1317
1331
  totalRulesCount: rulesCount,
1318
1332
  rulesSample,
1319
- proofOfRead: `✅ VERIFIED: ${rulesCount} critical rules loaded from ${Object.keys(rulesData.rules).join(', ')}`
1333
+ proofOfRead: `✅ VERIFIED: ${rulesCount} critical rules loaded from ${Object.keys(rulesData.rules).join(', ')}`,
1334
+ framework_rules: [tokenEconomyRule]
1320
1335
  };
1321
1336
  } catch (error) {
1322
1337
  if (process.env.DEBUG) {
@@ -1328,7 +1343,8 @@ async function aiGateCheck() {
1328
1343
  criticalRules: [],
1329
1344
  rulesLoaded: [],
1330
1345
  status: 'FAILED_TO_LOAD',
1331
- error: `Failed to load rules content: ${error && error.message ? error.message : String(error)}`
1346
+ error: `Failed to load rules content: ${error && error.message ? error.message : String(error)}`,
1347
+ framework_rules: [tokenEconomyRule]
1332
1348
  };
1333
1349
  }
1334
1350
 
@@ -1373,7 +1389,7 @@ async function aiGateCheck() {
1373
1389
  : `✅ ALLOWED: Gate check passed with ${warnings.length} warning(s).`,
1374
1390
  instructions: finalBlocked
1375
1391
  ? 'Fix violations before proceeding. Run ai-start if needed.'
1376
- : `✅ ${mandatoryRules.totalRulesCount} RULES LOADED. Sample: ${mandatoryRules.rulesSample.slice(0, 2).join(' | ')}... Review ALL rules in mandatory_rules.criticalRules before ANY code generation.`,
1392
+ : `✅ ${mandatoryRules.totalRulesCount} RULES LOADED. Sample: ${mandatoryRules.rulesSample.slice(0, 2).join(' | ')}... Review ALL rules in mandatory_rules.criticalRules before ANY code generation. Also follow mandatory_rules.framework_rules (token economy).`,
1377
1393
  cognitive_context: humanIntent?.primary_goal
1378
1394
  ? `🎯 USER INTENT: ${humanIntent.primary_goal} (confidence: ${humanIntent.confidence_level || 'unset'})`
1379
1395
  : null,
@@ -1444,18 +1460,25 @@ async function aiGateCheck() {
1444
1460
  platforms: ['backend', 'frontend', 'ios', 'android'],
1445
1461
  criticalRules: [],
1446
1462
  rulesLoaded: [],
1463
+ framework_rules: ['TOKEN_ECONOMY: Prioritize token/cost efficiency. Batch related checks, avoid redundant scans, reuse cached context where possible, ask the user for missing info instead of exploring blindly, and keep responses concise.'],
1447
1464
  warning: '⚠️ AI MUST read and follow these rules before ANY code generation or modification',
1448
1465
  error: 'Rules could not be loaded due to timeout'
1449
1466
  },
1450
1467
  summary: '🚫 BLOCKED: Gate check timed out.',
1451
- instructions: 'DO NOT proceed with user task. Retry the gate check.'
1468
+ instructions: 'DO NOT proceed with user task. Retry the gate check.',
1469
+ cognitive_context: null,
1470
+ human_intent: null,
1471
+ semantic_snapshot: null,
1472
+ auto_intent: null,
1473
+ session: {
1474
+ id: gateSession.sessionId,
1475
+ checkCount: gateSession.checkCount,
1476
+ validFor: gateSession.GATE_VALIDITY_MS / 60000 + ' minutes'
1477
+ }
1452
1478
  };
1453
1479
  gateSession.recordCheck(timeoutResult);
1454
1480
  return timeoutResult;
1455
1481
  }
1456
- /**
1457
- * Read platform rules handler - returns critical rules for a specific platform
1458
- */
1459
1482
  async function readPlatformRulesHandler(params) {
1460
1483
  const platform = params.platform;
1461
1484
  if (!platform) {
@@ -1693,10 +1716,12 @@ function suggestHumanIntent() {
1693
1716
  */
1694
1717
  function preFlightCheck(params) {
1695
1718
  const { action_type, target_file, proposed_code, bypass_tdd } = params;
1719
+ const tokenEconomyRule = 'TOKEN_ECONOMY: Prioritize token/cost efficiency. Batch related checks, avoid redundant scans, reuse cached context where possible, ask the user for missing info instead of exploring blindly, and keep responses concise.';
1696
1720
 
1697
1721
  if (!action_type || !target_file) {
1698
1722
  return {
1699
1723
  success: false,
1724
+ framework_rules: [tokenEconomyRule],
1700
1725
  error: 'action_type and target_file are required',
1701
1726
  hint: 'Call with: { action_type: "edit"|"create_file", target_file: "/path/to/file.ts", proposed_code: "..." }'
1702
1727
  };
@@ -1716,6 +1741,7 @@ function preFlightCheck(params) {
1716
1741
  success: false,
1717
1742
  allowed: false,
1718
1743
  blocked: true,
1744
+ framework_rules: [tokenEconomyRule],
1719
1745
  reason: validation.enforcement_message,
1720
1746
  violations: validation.violations,
1721
1747
  tdd_status: validation.tddStatus,
@@ -1741,6 +1767,7 @@ function preFlightCheck(params) {
1741
1767
  success: false,
1742
1768
  allowed: false,
1743
1769
  blocked: true,
1770
+ framework_rules: [tokenEconomyRule],
1744
1771
  reason: '🚫 AST INTELLIGENCE BLOCKED: Critical/High violations detected in proposed code',
1745
1772
  ast_violations: blocking,
1746
1773
  ast_summary: astAnalysis.summary,
@@ -1765,6 +1792,7 @@ function preFlightCheck(params) {
1765
1792
  success: true,
1766
1793
  allowed: true,
1767
1794
  has_warnings: true,
1795
+ framework_rules: [tokenEconomyRule],
1768
1796
  warnings: validation.violations.filter(v => v.severity === 'WARNING'),
1769
1797
  ast_analysis: astAnalysis,
1770
1798
  message: '⚠️ Proceed with caution - review warnings',
@@ -1777,6 +1805,7 @@ function preFlightCheck(params) {
1777
1805
  return {
1778
1806
  success: true,
1779
1807
  allowed: true,
1808
+ framework_rules: [tokenEconomyRule],
1780
1809
  message: '✅ Pre-flight check PASSED - proceed with implementation',
1781
1810
  ast_analysis: astAnalysis,
1782
1811
  tdd_status: validation.tddStatus,
@@ -7,3 +7,6 @@
7
7
  {"timestamp":"2026-01-11T00:48:11.264Z","level":"info","component":"TokenMonitor","event":"TOKEN_MONITOR_RESULT","data":{"level":"ok","percentUsed":10,"tokensUsed":100000,"maxTokens":1000000,"source":"realtime","stale":false},"context":{"message":"Result level=ok percent=10% used=100000/1000000 source=realtime"}}
8
8
  {"timestamp":"2026-01-11T00:48:11.267Z","level":"info","component":"TokenMonitor","event":"TOKEN_MONITOR_RESULT","data":{"level":"warning","percentUsed":91,"tokensUsed":910000,"maxTokens":1000000,"source":"fallback","stale":false},"context":{"message":"Result level=warning percent=91% used=910000/1000000 source=fallback"}}
9
9
  {"timestamp":"2026-01-11T00:48:11.267Z","level":"info","component":"TokenMonitor","event":"TOKEN_MONITOR_RESULT","data":{"level":"critical","percentUsed":98,"tokensUsed":980000,"maxTokens":1000000,"source":"realtime","stale":true},"context":{"message":"Result level=critical percent=98% used=980000/1000000 source=realtime (stale)"}}
10
+ {"timestamp":"2026-01-11T14:18:34.198Z","level":"info","component":"TokenMonitor","event":"TOKEN_MONITOR_RESULT","data":{"level":"ok","percentUsed":10,"tokensUsed":100000,"maxTokens":1000000,"source":"realtime","stale":false},"context":{"message":"Result level=ok percent=10% used=100000/1000000 source=realtime"}}
11
+ {"timestamp":"2026-01-11T14:18:34.200Z","level":"info","component":"TokenMonitor","event":"TOKEN_MONITOR_RESULT","data":{"level":"warning","percentUsed":91,"tokensUsed":910000,"maxTokens":1000000,"source":"fallback","stale":false},"context":{"message":"Result level=warning percent=91% used=910000/1000000 source=fallback"}}
12
+ {"timestamp":"2026-01-11T14:18:34.201Z","level":"info","component":"TokenMonitor","event":"TOKEN_MONITOR_RESULT","data":{"level":"critical","percentUsed":98,"tokensUsed":980000,"maxTokens":1000000,"source":"realtime","stale":true},"context":{"message":"Result level=critical percent=98% used=980000/1000000 source=realtime (stale)"}}