@neurcode-ai/cli 0.9.28 â 0.9.29
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/dist/api-client.d.ts +58 -0
- package/dist/api-client.d.ts.map +1 -1
- package/dist/api-client.js +38 -0
- package/dist/api-client.js.map +1 -1
- package/dist/commands/plan.d.ts.map +1 -1
- package/dist/commands/plan.js +244 -64
- package/dist/commands/plan.js.map +1 -1
- package/dist/commands/prompt.d.ts.map +1 -1
- package/dist/commands/prompt.js +24 -1
- package/dist/commands/prompt.js.map +1 -1
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +15 -13
- package/dist/commands/verify.js.map +1 -1
- package/package.json +1 -1
package/dist/commands/plan.js
CHANGED
|
@@ -319,6 +319,29 @@ function resolveSnapshotMaxBytes(mode) {
|
|
|
319
319
|
return envOverride;
|
|
320
320
|
return mode === 'full' ? 0 : 256 * 1024;
|
|
321
321
|
}
|
|
322
|
+
function resolveSnapshotBatchSize(mode) {
|
|
323
|
+
const envOverride = parsePositiveInt(process.env.NEURCODE_PLAN_SNAPSHOT_BATCH_SIZE);
|
|
324
|
+
if (typeof envOverride === 'number' && envOverride > 0) {
|
|
325
|
+
return Math.min(100, Math.max(1, envOverride));
|
|
326
|
+
}
|
|
327
|
+
return mode === 'full' ? 30 : 20;
|
|
328
|
+
}
|
|
329
|
+
function resolveSnapshotBatchTimeoutMs(singleRequestTimeoutMs, mode) {
|
|
330
|
+
const envOverride = parsePositiveInt(process.env.NEURCODE_PLAN_SNAPSHOT_BATCH_TIMEOUT_MS);
|
|
331
|
+
if (typeof envOverride === 'number' && envOverride > 0)
|
|
332
|
+
return envOverride;
|
|
333
|
+
const multiplier = mode === 'full' ? 5 : 4;
|
|
334
|
+
return Math.max(singleRequestTimeoutMs * multiplier, 12000);
|
|
335
|
+
}
|
|
336
|
+
function isBatchSnapshotEndpointUnsupported(error) {
|
|
337
|
+
if (!(error instanceof Error))
|
|
338
|
+
return false;
|
|
339
|
+
const message = error.message.toLowerCase();
|
|
340
|
+
return (message.includes('status 404') ||
|
|
341
|
+
message.includes('not found') ||
|
|
342
|
+
message.includes('not_found') ||
|
|
343
|
+
message.includes('method not allowed'));
|
|
344
|
+
}
|
|
322
345
|
function getSnapshotManifestPath(projectRoot) {
|
|
323
346
|
return (0, path_1.join)(projectRoot, '.neurcode', 'snapshot-manifest.json');
|
|
324
347
|
}
|
|
@@ -390,6 +413,7 @@ function emitCachedPlanHit(input) {
|
|
|
390
413
|
sessionId: input.response.sessionId || null,
|
|
391
414
|
projectId: input.projectId || null,
|
|
392
415
|
timestamp: input.response.timestamp,
|
|
416
|
+
telemetry: input.response.telemetry,
|
|
393
417
|
message: persistedPlan
|
|
394
418
|
? `Using ${input.mode === 'near' ? 'near-' : ''}cached plan`
|
|
395
419
|
: 'Plan generated but could not be persisted (missing planId)',
|
|
@@ -1088,29 +1112,56 @@ async function planCommand(intent, options) {
|
|
|
1088
1112
|
const snapshotMaxFiles = resolveSnapshotMaxFiles(snapshotMode, options.snapshotMaxFiles);
|
|
1089
1113
|
const snapshotBudgetMs = resolveSnapshotBudgetMs(snapshotMode, options.snapshotBudgetMs);
|
|
1090
1114
|
const snapshotMaxBytes = resolveSnapshotMaxBytes(snapshotMode);
|
|
1115
|
+
let snapshotSummary;
|
|
1091
1116
|
if (isReadOnlyAnalysis) {
|
|
1092
1117
|
console.log(chalk.dim('\nđ Analysis mode: skipping pre-flight file snapshots'));
|
|
1118
|
+
snapshotSummary = {
|
|
1119
|
+
mode: snapshotMode,
|
|
1120
|
+
attempted: 0,
|
|
1121
|
+
processed: 0,
|
|
1122
|
+
saved: 0,
|
|
1123
|
+
failed: 0,
|
|
1124
|
+
skippedUnchanged: 0,
|
|
1125
|
+
skippedMissing: 0,
|
|
1126
|
+
skippedLarge: 0,
|
|
1127
|
+
skippedBudget: 0,
|
|
1128
|
+
capped: 0,
|
|
1129
|
+
usedBatchApi: false,
|
|
1130
|
+
batchFallbackToSingle: false,
|
|
1131
|
+
durationMs: 0,
|
|
1132
|
+
};
|
|
1093
1133
|
}
|
|
1094
1134
|
else if (snapshotMode === 'off') {
|
|
1095
1135
|
console.log(chalk.dim('\n⥠Snapshot capture disabled (snapshot mode: off)'));
|
|
1136
|
+
snapshotSummary = {
|
|
1137
|
+
mode: snapshotMode,
|
|
1138
|
+
attempted: 0,
|
|
1139
|
+
processed: 0,
|
|
1140
|
+
saved: 0,
|
|
1141
|
+
failed: 0,
|
|
1142
|
+
skippedUnchanged: 0,
|
|
1143
|
+
skippedMissing: 0,
|
|
1144
|
+
skippedLarge: 0,
|
|
1145
|
+
skippedBudget: 0,
|
|
1146
|
+
capped: 0,
|
|
1147
|
+
usedBatchApi: false,
|
|
1148
|
+
batchFallbackToSingle: false,
|
|
1149
|
+
durationMs: 0,
|
|
1150
|
+
};
|
|
1096
1151
|
}
|
|
1097
1152
|
else if (modifyFiles.length > 0) {
|
|
1153
|
+
const snapshotStartedAt = Date.now();
|
|
1098
1154
|
const snapshotCandidates = modifyFiles.slice(0, snapshotMaxFiles);
|
|
1099
1155
|
const cappedCount = Math.max(0, modifyFiles.length - snapshotCandidates.length);
|
|
1100
|
-
const snapshotConcurrency = Math.min(16, Math.max(1, parsePositiveInt(process.env.NEURCODE_PLAN_SNAPSHOT_CONCURRENCY) ?? (snapshotMode === 'full' ? 8 : 6)));
|
|
1101
1156
|
const snapshotTimeoutMs = Math.max(1000, parsePositiveInt(process.env.NEURCODE_PLAN_SNAPSHOT_TIMEOUT_MS) ?? (snapshotMode === 'full' ? 15000 : 8000));
|
|
1157
|
+
const snapshotConcurrency = Math.min(16, Math.max(1, parsePositiveInt(process.env.NEURCODE_PLAN_SNAPSHOT_CONCURRENCY) ?? (snapshotMode === 'full' ? 8 : 6)));
|
|
1158
|
+
const snapshotBatchSize = resolveSnapshotBatchSize(snapshotMode);
|
|
1159
|
+
const snapshotBatchTimeoutMs = resolveSnapshotBatchTimeoutMs(snapshotTimeoutMs, snapshotMode);
|
|
1102
1160
|
const deadline = snapshotBudgetMs > 0 ? Date.now() + snapshotBudgetMs : 0;
|
|
1103
1161
|
const forceResnapshot = process.env.NEURCODE_PLAN_SNAPSHOT_FORCE === '1';
|
|
1104
1162
|
console.log(chalk.dim(`\nđ¸ Capturing pre-flight snapshots for ${snapshotCandidates.length}/${modifyFiles.length} file(s)` +
|
|
1105
|
-
` [mode=${snapshotMode}, concurrency=${snapshotConcurrency}` +
|
|
1163
|
+
` [mode=${snapshotMode}, batch=${snapshotBatchSize}, fallback-concurrency=${snapshotConcurrency}` +
|
|
1106
1164
|
`${snapshotBudgetMs > 0 ? `, budget=${snapshotBudgetMs}ms` : ', budget=unbounded'}]...`));
|
|
1107
|
-
let snapshotsSaved = 0;
|
|
1108
|
-
let snapshotsFailed = 0;
|
|
1109
|
-
let snapshotsSkippedMissing = 0;
|
|
1110
|
-
let snapshotsSkippedUnchanged = 0;
|
|
1111
|
-
let snapshotsSkippedLarge = 0;
|
|
1112
|
-
let snapshotsProcessed = 0;
|
|
1113
|
-
let budgetExhausted = false;
|
|
1114
1165
|
const withTimeout = async (promise, timeoutMs) => {
|
|
1115
1166
|
return await Promise.race([
|
|
1116
1167
|
promise,
|
|
@@ -1119,70 +1170,164 @@ async function planCommand(intent, options) {
|
|
|
1119
1170
|
};
|
|
1120
1171
|
const manifest = loadSnapshotManifest(cwd);
|
|
1121
1172
|
let manifestDirty = false;
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1173
|
+
const preparedSnapshots = [];
|
|
1174
|
+
let snapshotsProcessed = 0;
|
|
1175
|
+
let snapshotsSaved = 0;
|
|
1176
|
+
let snapshotsFailed = 0;
|
|
1177
|
+
let snapshotsSkippedMissing = 0;
|
|
1178
|
+
let snapshotsSkippedUnchanged = 0;
|
|
1179
|
+
let snapshotsSkippedLarge = 0;
|
|
1180
|
+
let snapshotsSkippedBudget = 0;
|
|
1181
|
+
let usedBatchApi = false;
|
|
1182
|
+
let batchFallbackToSingle = false;
|
|
1183
|
+
for (const current of snapshotCandidates) {
|
|
1184
|
+
if (deadline > 0 && Date.now() >= deadline) {
|
|
1185
|
+
snapshotsSkippedBudget = snapshotCandidates.length - snapshotsProcessed;
|
|
1186
|
+
break;
|
|
1187
|
+
}
|
|
1188
|
+
snapshotsProcessed++;
|
|
1189
|
+
try {
|
|
1190
|
+
const normalizedPath = toUnixPath(current.path);
|
|
1191
|
+
const filePath = (0, path_1.resolve)(cwd, current.path);
|
|
1192
|
+
if (!(0, fs_1.existsSync)(filePath)) {
|
|
1193
|
+
snapshotsSkippedMissing++;
|
|
1194
|
+
if (process.env.DEBUG) {
|
|
1195
|
+
console.log(chalk.yellow(` â ď¸ Skipping ${current.path} (file not found locally)`));
|
|
1196
|
+
}
|
|
1197
|
+
continue;
|
|
1130
1198
|
}
|
|
1131
|
-
const
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
const filePath = (0, path_1.resolve)(cwd, current.path);
|
|
1138
|
-
if (!(0, fs_1.existsSync)(filePath)) {
|
|
1139
|
-
snapshotsSkippedMissing++;
|
|
1140
|
-
if (process.env.DEBUG) {
|
|
1141
|
-
console.log(chalk.yellow(` â ď¸ Skipping ${current.path} (file not found locally)`));
|
|
1142
|
-
}
|
|
1143
|
-
continue;
|
|
1199
|
+
const fileContent = (0, fs_1.readFileSync)(filePath, 'utf-8');
|
|
1200
|
+
const fileSize = Buffer.byteLength(fileContent, 'utf-8');
|
|
1201
|
+
if (snapshotMaxBytes > 0 && fileSize > snapshotMaxBytes) {
|
|
1202
|
+
snapshotsSkippedLarge++;
|
|
1203
|
+
if (process.env.DEBUG) {
|
|
1204
|
+
console.log(chalk.yellow(` â ď¸ Skipping ${current.path} (size ${fileSize}B > ${snapshotMaxBytes}B)`));
|
|
1144
1205
|
}
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1206
|
+
continue;
|
|
1207
|
+
}
|
|
1208
|
+
const fileHash = computeSnapshotHash(fileContent);
|
|
1209
|
+
const previous = manifest.entries[normalizedPath];
|
|
1210
|
+
if (snapshotMode === 'auto' &&
|
|
1211
|
+
!forceResnapshot &&
|
|
1212
|
+
previous &&
|
|
1213
|
+
previous.sha256 === fileHash &&
|
|
1214
|
+
previous.size === fileSize) {
|
|
1215
|
+
snapshotsSkippedUnchanged++;
|
|
1216
|
+
continue;
|
|
1217
|
+
}
|
|
1218
|
+
preparedSnapshots.push({
|
|
1219
|
+
path: current.path,
|
|
1220
|
+
normalizedPath,
|
|
1221
|
+
content: fileContent,
|
|
1222
|
+
size: fileSize,
|
|
1223
|
+
sha256: fileHash,
|
|
1224
|
+
});
|
|
1225
|
+
}
|
|
1226
|
+
catch (error) {
|
|
1227
|
+
snapshotsFailed++;
|
|
1228
|
+
if (process.env.DEBUG) {
|
|
1229
|
+
console.warn(chalk.yellow(` â ď¸ Failed to prepare snapshot for ${current.path}: ${error instanceof Error ? error.message : 'Unknown error'}`));
|
|
1230
|
+
}
|
|
1231
|
+
}
|
|
1232
|
+
}
|
|
1233
|
+
const reason = `Pre-Plan Snapshot for "${intent.trim()}"`;
|
|
1234
|
+
const markSnapshotSaved = (snapshot, snapshotAt) => {
|
|
1235
|
+
snapshotsSaved++;
|
|
1236
|
+
manifest.entries[snapshot.normalizedPath] = {
|
|
1237
|
+
sha256: snapshot.sha256,
|
|
1238
|
+
size: snapshot.size,
|
|
1239
|
+
snapshotAt: snapshotAt || new Date().toISOString(),
|
|
1240
|
+
};
|
|
1241
|
+
manifestDirty = true;
|
|
1242
|
+
};
|
|
1243
|
+
let pendingFallbackSnapshots = [];
|
|
1244
|
+
if (preparedSnapshots.length > 0) {
|
|
1245
|
+
try {
|
|
1246
|
+
usedBatchApi = true;
|
|
1247
|
+
for (let idx = 0; idx < preparedSnapshots.length; idx += snapshotBatchSize) {
|
|
1248
|
+
if (deadline > 0 && Date.now() >= deadline) {
|
|
1249
|
+
const remaining = preparedSnapshots.length - idx;
|
|
1250
|
+
snapshotsSkippedBudget += Math.max(0, remaining);
|
|
1251
|
+
break;
|
|
1252
|
+
}
|
|
1253
|
+
const chunk = preparedSnapshots.slice(idx, idx + snapshotBatchSize);
|
|
1254
|
+
const result = await withTimeout(client.saveFileVersionsBatch(chunk.map((snapshot) => ({
|
|
1255
|
+
filePath: snapshot.path,
|
|
1256
|
+
fileContent: snapshot.content,
|
|
1257
|
+
changeType: 'modify',
|
|
1258
|
+
linesAdded: 0,
|
|
1259
|
+
linesRemoved: 0,
|
|
1260
|
+
})), finalProjectId, reason), snapshotBatchTimeoutMs);
|
|
1261
|
+
const chunkByPath = new Map();
|
|
1262
|
+
for (const snapshot of chunk) {
|
|
1263
|
+
chunkByPath.set(snapshot.path, snapshot);
|
|
1264
|
+
}
|
|
1265
|
+
for (const saved of result.saved || []) {
|
|
1266
|
+
const prepared = chunkByPath.get(saved.filePath);
|
|
1267
|
+
if (!prepared)
|
|
1268
|
+
continue;
|
|
1269
|
+
markSnapshotSaved(prepared, saved.version?.createdAt);
|
|
1270
|
+
chunkByPath.delete(saved.filePath);
|
|
1271
|
+
}
|
|
1272
|
+
for (const failed of result.failed || []) {
|
|
1273
|
+
if (chunkByPath.has(failed.filePath)) {
|
|
1274
|
+
chunkByPath.delete(failed.filePath);
|
|
1275
|
+
}
|
|
1276
|
+
snapshotsFailed++;
|
|
1149
1277
|
if (process.env.DEBUG) {
|
|
1150
|
-
console.
|
|
1278
|
+
console.warn(chalk.yellow(` â ď¸ Failed to save snapshot for ${failed.filePath}: ${failed.error}`));
|
|
1151
1279
|
}
|
|
1152
|
-
continue;
|
|
1153
1280
|
}
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
!forceResnapshot &&
|
|
1158
|
-
previous &&
|
|
1159
|
-
previous.sha256 === fileHash &&
|
|
1160
|
-
previous.size === fileSize) {
|
|
1161
|
-
snapshotsSkippedUnchanged++;
|
|
1162
|
-
continue;
|
|
1281
|
+
// Any residual paths were not explicitly reported by API; preserve via fallback.
|
|
1282
|
+
if (chunkByPath.size > 0) {
|
|
1283
|
+
pendingFallbackSnapshots.push(...chunkByPath.values());
|
|
1163
1284
|
}
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
if (process.env.DEBUG) {
|
|
1174
|
-
console.log(chalk.green(` â Snapshot saved: ${current.path}`));
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
catch (error) {
|
|
1288
|
+
// Backward compatibility: old API versions won't have save-batch endpoint.
|
|
1289
|
+
if (isBatchSnapshotEndpointUnsupported(error)) {
|
|
1290
|
+
batchFallbackToSingle = true;
|
|
1291
|
+
pendingFallbackSnapshots = [...preparedSnapshots];
|
|
1292
|
+
if (process.env.DEBUG || !options.json) {
|
|
1293
|
+
console.log(chalk.dim(' Batch snapshot endpoint unavailable; falling back to single-file snapshot uploads.'));
|
|
1175
1294
|
}
|
|
1176
1295
|
}
|
|
1177
|
-
|
|
1178
|
-
snapshotsFailed
|
|
1296
|
+
else {
|
|
1297
|
+
snapshotsFailed += preparedSnapshots.length;
|
|
1179
1298
|
if (process.env.DEBUG) {
|
|
1180
|
-
console.warn(chalk.yellow(` â ď¸
|
|
1299
|
+
console.warn(chalk.yellow(` â ď¸ Batch snapshot upload failed: ${error instanceof Error ? error.message : 'Unknown error'}`));
|
|
1181
1300
|
}
|
|
1182
1301
|
}
|
|
1183
1302
|
}
|
|
1184
|
-
}
|
|
1185
|
-
|
|
1303
|
+
}
|
|
1304
|
+
if (pendingFallbackSnapshots.length > 0) {
|
|
1305
|
+
let fallbackCursor = 0;
|
|
1306
|
+
const fallbackWorkers = Array.from({ length: Math.min(snapshotConcurrency, pendingFallbackSnapshots.length) }, async () => {
|
|
1307
|
+
while (true) {
|
|
1308
|
+
const index = fallbackCursor++;
|
|
1309
|
+
if (index >= pendingFallbackSnapshots.length) {
|
|
1310
|
+
return;
|
|
1311
|
+
}
|
|
1312
|
+
const snapshot = pendingFallbackSnapshots[index];
|
|
1313
|
+
if (deadline > 0 && Date.now() >= deadline) {
|
|
1314
|
+
snapshotsSkippedBudget++;
|
|
1315
|
+
continue;
|
|
1316
|
+
}
|
|
1317
|
+
try {
|
|
1318
|
+
await withTimeout(client.saveFileVersion(snapshot.path, snapshot.content, finalProjectId, reason, 'modify', 0, 0), snapshotTimeoutMs);
|
|
1319
|
+
markSnapshotSaved(snapshot);
|
|
1320
|
+
}
|
|
1321
|
+
catch (error) {
|
|
1322
|
+
snapshotsFailed++;
|
|
1323
|
+
if (process.env.DEBUG) {
|
|
1324
|
+
console.warn(chalk.yellow(` â ď¸ Failed to save snapshot for ${snapshot.path}: ${error instanceof Error ? error.message : 'Unknown error'}`));
|
|
1325
|
+
}
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
});
|
|
1329
|
+
await Promise.all(fallbackWorkers);
|
|
1330
|
+
}
|
|
1186
1331
|
if (manifestDirty) {
|
|
1187
1332
|
try {
|
|
1188
1333
|
manifest.updatedAt = new Date().toISOString();
|
|
@@ -1194,7 +1339,6 @@ async function planCommand(intent, options) {
|
|
|
1194
1339
|
}
|
|
1195
1340
|
}
|
|
1196
1341
|
}
|
|
1197
|
-
const snapshotsSkippedBudget = Math.max(0, snapshotCandidates.length - snapshotsProcessed);
|
|
1198
1342
|
if (snapshotsSaved > 0) {
|
|
1199
1343
|
console.log(chalk.green(`\nâ
${snapshotsSaved} pre-flight snapshot(s) saved successfully`));
|
|
1200
1344
|
console.log(chalk.dim(' You can revert these files using: neurcode revert <filePath> --to-version <version>'));
|
|
@@ -1221,10 +1365,42 @@ async function planCommand(intent, options) {
|
|
|
1221
1365
|
if (snapshotsSkippedBudget > 0) {
|
|
1222
1366
|
console.log(chalk.dim(` ${snapshotsSkippedBudget} file(s) deferred by snapshot budget`));
|
|
1223
1367
|
}
|
|
1224
|
-
if (
|
|
1225
|
-
console.log(chalk.dim(
|
|
1368
|
+
if (usedBatchApi) {
|
|
1369
|
+
console.log(chalk.dim(` Snapshot transport: batch${batchFallbackToSingle ? ' (with single-file fallback)' : ''}`));
|
|
1226
1370
|
}
|
|
1227
1371
|
console.log('');
|
|
1372
|
+
snapshotSummary = {
|
|
1373
|
+
mode: snapshotMode,
|
|
1374
|
+
attempted: snapshotCandidates.length,
|
|
1375
|
+
processed: snapshotsProcessed,
|
|
1376
|
+
saved: snapshotsSaved,
|
|
1377
|
+
failed: snapshotsFailed,
|
|
1378
|
+
skippedUnchanged: snapshotsSkippedUnchanged,
|
|
1379
|
+
skippedMissing: snapshotsSkippedMissing,
|
|
1380
|
+
skippedLarge: snapshotsSkippedLarge,
|
|
1381
|
+
skippedBudget: snapshotsSkippedBudget,
|
|
1382
|
+
capped: cappedCount,
|
|
1383
|
+
usedBatchApi,
|
|
1384
|
+
batchFallbackToSingle,
|
|
1385
|
+
durationMs: Date.now() - snapshotStartedAt,
|
|
1386
|
+
};
|
|
1387
|
+
}
|
|
1388
|
+
else {
|
|
1389
|
+
snapshotSummary = {
|
|
1390
|
+
mode: snapshotMode,
|
|
1391
|
+
attempted: 0,
|
|
1392
|
+
processed: 0,
|
|
1393
|
+
saved: 0,
|
|
1394
|
+
failed: 0,
|
|
1395
|
+
skippedUnchanged: 0,
|
|
1396
|
+
skippedMissing: 0,
|
|
1397
|
+
skippedLarge: 0,
|
|
1398
|
+
skippedBudget: 0,
|
|
1399
|
+
capped: 0,
|
|
1400
|
+
usedBatchApi: false,
|
|
1401
|
+
batchFallbackToSingle: false,
|
|
1402
|
+
durationMs: 0,
|
|
1403
|
+
};
|
|
1228
1404
|
}
|
|
1229
1405
|
// Step 3: Post-Generation Hallucination Check (DEEP SCAN)
|
|
1230
1406
|
// Scan ALL plan content for phantom packages - not just summaries, but full proposed code
|
|
@@ -1369,6 +1545,8 @@ async function planCommand(intent, options) {
|
|
|
1369
1545
|
sessionId: response.sessionId || null,
|
|
1370
1546
|
projectId: finalProjectId || null,
|
|
1371
1547
|
timestamp: response.timestamp,
|
|
1548
|
+
telemetry: response.telemetry,
|
|
1549
|
+
snapshot: snapshotSummary,
|
|
1372
1550
|
message: missingPlanMessage,
|
|
1373
1551
|
plan: response.plan,
|
|
1374
1552
|
});
|
|
@@ -1415,6 +1593,8 @@ async function planCommand(intent, options) {
|
|
|
1415
1593
|
sessionId: response.sessionId || null,
|
|
1416
1594
|
projectId: finalProjectId || null,
|
|
1417
1595
|
timestamp: response.timestamp,
|
|
1596
|
+
telemetry: response.telemetry,
|
|
1597
|
+
snapshot: snapshotSummary,
|
|
1418
1598
|
message: 'Plan generated and persisted',
|
|
1419
1599
|
plan: response.plan,
|
|
1420
1600
|
});
|