terminal-smart-cli 0.97.23 → 0.97.25
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/lib/meta.js +22 -1
- package/package.json +1 -1
package/lib/meta.js
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
const fs = require('fs');
|
|
10
10
|
const path = require('path');
|
|
11
11
|
const cp = require('child_process');
|
|
12
|
+
const crypto = require('crypto');
|
|
12
13
|
const compactor = require('./compactor');
|
|
13
14
|
const { api, ApiError } = require('./api');
|
|
14
15
|
const keyring = require('./keyring');
|
|
@@ -74,6 +75,11 @@ function artifactForMetaItem(item, st, dir = '') {
|
|
|
74
75
|
return `artifacts/${String(item && item.id || 'item').replace(/[^a-z0-9_-]/gi, '_')}.md`;
|
|
75
76
|
}
|
|
76
77
|
|
|
78
|
+
function artifactHash(file) {
|
|
79
|
+
try { return crypto.createHash('sha256').update(fs.readFileSync(file)).digest('hex'); }
|
|
80
|
+
catch (_) { return null; }
|
|
81
|
+
}
|
|
82
|
+
|
|
77
83
|
function normalizeMetaArtifact(relativePath, raw) {
|
|
78
84
|
let text = String(raw || '').trim().replace(/^```(?:json|gdscript|markdown|md)?\s*/i, '').replace(/\s*```\s*$/i, '').trim();
|
|
79
85
|
if (/\.json$/i.test(relativePath)) {
|
|
@@ -1393,6 +1399,13 @@ async function run(goal, opts = {}) {
|
|
|
1393
1399
|
const expectedOnDisk = expectedArtifact
|
|
1394
1400
|
? (path.isAbsolute(expectedArtifact) ? expectedArtifact : path.resolve(dir, expectedArtifact))
|
|
1395
1401
|
: null;
|
|
1402
|
+
const expectedBeforeHash = expectedOnDisk ? artifactHash(expectedOnDisk) : null;
|
|
1403
|
+
// Persist the starting fingerprint so a successful edit made immediately
|
|
1404
|
+
// before a pause is still provable in the next clean window.
|
|
1405
|
+
if (!item.artifactBaselineHash && expectedBeforeHash) {
|
|
1406
|
+
item.artifactBaselineHash = expectedBeforeHash;
|
|
1407
|
+
save(st, dir);
|
|
1408
|
+
}
|
|
1396
1409
|
if (!item.directArtifact && (item.attempts || 0) > 0 && expectedOnDisk && !fs.existsSync(expectedOnDisk)) {
|
|
1397
1410
|
item.directArtifact = true;
|
|
1398
1411
|
item.directModel = item.directModel || 'glm-5.2';
|
|
@@ -1647,7 +1660,11 @@ async function run(goal, opts = {}) {
|
|
|
1647
1660
|
}
|
|
1648
1661
|
|
|
1649
1662
|
const expectedNow = String(expectedArtifact || '').replace(/\\/g, '/').toLowerCase();
|
|
1650
|
-
const
|
|
1663
|
+
const expectedAfterHash = expectedOnDisk ? artifactHash(expectedOnDisk) : null;
|
|
1664
|
+
const expectedChangedNow = !!expectedAfterHash && expectedAfterHash !== expectedBeforeHash;
|
|
1665
|
+
const expectedChangedSinceBaseline = !!expectedAfterHash && !!item.artifactBaselineHash
|
|
1666
|
+
&& expectedAfterHash !== item.artifactBaselineHash;
|
|
1667
|
+
const wroteExpectedNow = expectedChangedNow || expectedChangedSinceBaseline || (out.actions || []).some(a => {
|
|
1651
1668
|
if (!['escrever_arquivo', 'editar_arquivo'].includes(a && a.name)) return false;
|
|
1652
1669
|
const target = String(a.target || '').replace(/\\/g, '/').toLowerCase();
|
|
1653
1670
|
return target === expectedNow || target.endsWith('/' + expectedNow);
|
|
@@ -1689,6 +1706,10 @@ async function run(goal, opts = {}) {
|
|
|
1689
1706
|
// (Bug real do teste MultiApps: flash-lite bloqueou itens cujos arquivos existiam no disco.)
|
|
1690
1707
|
let marks = [];
|
|
1691
1708
|
const written = (out.actions || []).filter(a => a.name === 'escrever_arquivo' || a.name === 'editar_arquivo').map(a => String(a.target || ''));
|
|
1709
|
+
// A confined command may legitimately edit the project (formatter, codemod,
|
|
1710
|
+
// migration script). Hash evidence ties that mutation to the exact expected
|
|
1711
|
+
// artifact instead of trusting the command narrative.
|
|
1712
|
+
if ((expectedChangedNow || expectedChangedSinceBaseline) && expectedArtifact) written.push(String(expectedArtifact));
|
|
1692
1713
|
const _basename = (p) => String(p).replace(/\\/g, '/').split('/').pop().toLowerCase();
|
|
1693
1714
|
const _fileHints = (txt) => (String(txt).match(/[\w.\-]+\.(kt|java|xml|gradle|json|md|txt|kts|properties|pro|png|webp|py|gd|js|ts|html|css|sh)\b/gi) || []).map(s => s.toLowerCase());
|
|
1694
1715
|
const itemFiles = _fileHints(item.desc);
|