envseed 0.2.1 → 0.3.1
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/container-replicator.mjs +20 -0
- package/lib/hook-handler.mjs +48 -9
- package/lib/log-incident.mjs +90 -16
- package/lib/overlay/envseed-overlay +0 -0
- package/lib/overlay/growing-plant-1-frames/000.png +0 -0
- package/lib/overlay/growing-plant-1-frames/001.png +0 -0
- package/lib/overlay/growing-plant-1-frames/002.png +0 -0
- package/lib/overlay/growing-plant-1-frames/003.png +0 -0
- package/lib/overlay/growing-plant-1-frames/004.png +0 -0
- package/lib/overlay/growing-plant-1-frames/005.png +0 -0
- package/lib/overlay/growing-plant-1-frames/006.png +0 -0
- package/lib/overlay/growing-plant-1-frames/007.png +0 -0
- package/lib/overlay/growing-plant-1-frames/008.png +0 -0
- package/lib/overlay/growing-plant-1-frames/009.png +0 -0
- package/lib/overlay/growing-plant-1-frames/010.png +0 -0
- package/lib/overlay/growing-plant-1-frames/011.png +0 -0
- package/lib/overlay/growing-plant-1-frames/012.png +0 -0
- package/lib/overlay/growing-plant-1-frames/013.png +0 -0
- package/lib/overlay/growing-plant-1-frames/014.png +0 -0
- package/lib/overlay/growing-plant-1-frames/015.png +0 -0
- package/lib/overlay/growing-plant-1-frames/016.png +0 -0
- package/lib/overlay/growing-plant-1-frames/017.png +0 -0
- package/lib/overlay/growing-plant-1-frames/018.png +0 -0
- package/lib/overlay/growing-plant-1-frames/019.png +0 -0
- package/lib/overlay/growing-plant-1-frames/020.png +0 -0
- package/lib/overlay/growing-plant-1-frames/021.png +0 -0
- package/lib/overlay/growing-plant-1-frames/022.png +0 -0
- package/lib/overlay/growing-plant-1-frames/023.png +0 -0
- package/lib/overlay/growing-plant-1-frames/024.png +0 -0
- package/lib/overlay/growing-plant-1-frames/025.png +0 -0
- package/lib/overlay/growing-plant-1-frames/026.png +0 -0
- package/lib/overlay/growing-plant-1-frames/027.png +0 -0
- package/lib/overlay/growing-plant-1-frames/028.png +0 -0
- package/lib/overlay/growing-plant-1-frames/029.png +0 -0
- package/lib/overlay/growing-plant-1-frames/030.png +0 -0
- package/lib/overlay/growing-plant-1-frames/031.png +0 -0
- package/lib/overlay/growing-plant-1-frames/032.png +0 -0
- package/lib/overlay/growing-plant-1-frames/033.png +0 -0
- package/lib/overlay/growing-plant-1-frames/034.png +0 -0
- package/lib/overlay/growing-plant-1-frames/035.png +0 -0
- package/lib/overlay/growing-plant-1-frames/036.png +0 -0
- package/lib/overlay/growing-plant-1-frames/037.png +0 -0
- package/lib/overlay/growing-plant-1-frames/038.png +0 -0
- package/lib/overlay/growing-plant-1-frames/039.png +0 -0
- package/lib/overlay/growing-plant-1-frames/040.png +0 -0
- package/lib/overlay/growing-plant-1-frames/041.png +0 -0
- package/lib/overlay/growing-plant-1-frames/042.png +0 -0
- package/lib/overlay/growing-plant-1-frames/043.png +0 -0
- package/lib/overlay/growing-plant-1-frames/044.png +0 -0
- package/lib/overlay/growing-plant-1-frames/045.png +0 -0
- package/lib/overlay/growing-plant-1-frames/046.png +0 -0
- package/lib/overlay/growing-plant-1.apng +0 -0
- package/lib/overlay/growing-plant-2-frames/000.png +0 -0
- package/lib/overlay/growing-plant-2-frames/001.png +0 -0
- package/lib/overlay/growing-plant-2-frames/002.png +0 -0
- package/lib/overlay/growing-plant-2-frames/003.png +0 -0
- package/lib/overlay/growing-plant-2-frames/004.png +0 -0
- package/lib/overlay/growing-plant-2-frames/005.png +0 -0
- package/lib/overlay/growing-plant-2-frames/006.png +0 -0
- package/lib/overlay/growing-plant-2-frames/007.png +0 -0
- package/lib/overlay/growing-plant-2-frames/008.png +0 -0
- package/lib/overlay/growing-plant-2-frames/009.png +0 -0
- package/lib/overlay/growing-plant-2-frames/010.png +0 -0
- package/lib/overlay/growing-plant-2-frames/011.png +0 -0
- package/lib/overlay/growing-plant-2-frames/012.png +0 -0
- package/lib/overlay/growing-plant-2-frames/013.png +0 -0
- package/lib/overlay/growing-plant-2-frames/014.png +0 -0
- package/lib/overlay/growing-plant-2-frames/015.png +0 -0
- package/lib/overlay/growing-plant-2-frames/016.png +0 -0
- package/lib/overlay/growing-plant-2-frames/017.png +0 -0
- package/lib/overlay/growing-plant-2-frames/018.png +0 -0
- package/lib/overlay/growing-plant-2-frames/019.png +0 -0
- package/lib/overlay/growing-plant-2-frames/020.png +0 -0
- package/lib/overlay/growing-plant-2-frames/021.png +0 -0
- package/lib/overlay/growing-plant-2-frames/022.png +0 -0
- package/lib/overlay/growing-plant-2-frames/023.png +0 -0
- package/lib/overlay/growing-plant-2-frames/024.png +0 -0
- package/lib/overlay/growing-plant-2-frames/025.png +0 -0
- package/lib/overlay/growing-plant-2-frames/026.png +0 -0
- package/lib/overlay/growing-plant-2-frames/027.png +0 -0
- package/lib/overlay/growing-plant-2-frames/028.png +0 -0
- package/lib/overlay/growing-plant-2-frames/029.png +0 -0
- package/lib/overlay/growing-plant-2-frames/030.png +0 -0
- package/lib/overlay/growing-plant-2-frames/031.png +0 -0
- package/lib/overlay/growing-plant-2-frames/032.png +0 -0
- package/lib/overlay/growing-plant-2-frames/033.png +0 -0
- package/lib/overlay/growing-plant-2-frames/034.png +0 -0
- package/lib/overlay/growing-plant-2-frames/035.png +0 -0
- package/lib/overlay/growing-plant-2-frames/036.png +0 -0
- package/lib/overlay/growing-plant-2-frames/037.png +0 -0
- package/lib/overlay/growing-plant-2-frames/038.png +0 -0
- package/lib/overlay/growing-plant-2-frames/039.png +0 -0
- package/lib/overlay/growing-plant-2-frames/040.png +0 -0
- package/lib/overlay/growing-plant-2-frames/041.png +0 -0
- package/lib/overlay/growing-plant-2-frames/042.png +0 -0
- package/lib/overlay/growing-plant-2-frames/043.png +0 -0
- package/lib/overlay/growing-plant-2-frames/044.png +0 -0
- package/lib/overlay/growing-plant-2-frames/045.png +0 -0
- package/lib/overlay/growing-plant-2-frames/046.png +0 -0
- package/lib/overlay/growing-plant-2-frames/047.png +0 -0
- package/lib/overlay/growing-plant-2-frames/048.png +0 -0
- package/lib/overlay/growing-plant-2-frames/049.png +0 -0
- package/lib/overlay/growing-plant-2-frames/050.png +0 -0
- package/lib/overlay/growing-plant-2-frames/051.png +0 -0
- package/lib/overlay/growing-plant-2-frames/052.png +0 -0
- package/lib/overlay/growing-plant-2-frames/053.png +0 -0
- package/lib/overlay/growing-plant-2-frames/054.png +0 -0
- package/lib/overlay/growing-plant-2-frames/055.png +0 -0
- package/lib/overlay/growing-plant-2-frames/056.png +0 -0
- package/lib/overlay/growing-plant-2.apng +0 -0
- package/lib/overlay/growing-seed-frames/000.png +0 -0
- package/lib/overlay/growing-seed-frames/001.png +0 -0
- package/lib/overlay/growing-seed-frames/002.png +0 -0
- package/lib/overlay/growing-seed-frames/003.png +0 -0
- package/lib/overlay/growing-seed-frames/004.png +0 -0
- package/lib/overlay/growing-seed-frames/005.png +0 -0
- package/lib/overlay/growing-seed-frames/006.png +0 -0
- package/lib/overlay/growing-seed-frames/007.png +0 -0
- package/lib/overlay/growing-seed-frames/008.png +0 -0
- package/lib/overlay/growing-seed-frames/009.png +0 -0
- package/lib/overlay/growing-seed-frames/010.png +0 -0
- package/lib/overlay/growing-seed-frames/011.png +0 -0
- package/lib/overlay/growing-seed-frames/012.png +0 -0
- package/lib/overlay/growing-seed-frames/013.png +0 -0
- package/lib/overlay/growing-seed-frames/014.png +0 -0
- package/lib/overlay/growing-seed-frames/015.png +0 -0
- package/lib/overlay/growing-seed-frames/016.png +0 -0
- package/lib/overlay/growing-seed-frames/017.png +0 -0
- package/lib/overlay/growing-seed-frames/018.png +0 -0
- package/lib/overlay/growing-seed-frames/019.png +0 -0
- package/lib/overlay/growing-seed-frames/020.png +0 -0
- package/lib/overlay/growing-seed-frames/021.png +0 -0
- package/lib/overlay/growing-seed-frames/022.png +0 -0
- package/lib/overlay/growing-seed-frames/023.png +0 -0
- package/lib/overlay/growing-seed-frames/024.png +0 -0
- package/lib/overlay/growing-seed-frames/025.png +0 -0
- package/lib/overlay/growing-seed-frames/026.png +0 -0
- package/lib/overlay/growing-seed-frames/027.png +0 -0
- package/lib/overlay/growing-seed-frames/028.png +0 -0
- package/lib/overlay/growing-seed-frames/029.png +0 -0
- package/lib/overlay/growing-seed-frames/030.png +0 -0
- package/lib/overlay/growing-seed-frames/031.png +0 -0
- package/lib/overlay/growing-seed-frames/032.png +0 -0
- package/lib/overlay/growing-seed-frames/033.png +0 -0
- package/lib/overlay/growing-seed-frames/034.png +0 -0
- package/lib/overlay/growing-seed-frames/035.png +0 -0
- package/lib/overlay/growing-seed-frames/036.png +0 -0
- package/lib/overlay/growing-seed-frames/037.png +0 -0
- package/lib/overlay/growing-seed-frames/038.png +0 -0
- package/lib/overlay/growing-seed-frames/039.png +0 -0
- package/lib/overlay/growing-seed-frames/040.png +0 -0
- package/lib/overlay/growing-seed-frames/041.png +0 -0
- package/lib/overlay/growing-seed-frames/042.png +0 -0
- package/lib/overlay/growing-seed-frames/043.png +0 -0
- package/lib/overlay/growing-seed-frames/044.png +0 -0
- package/lib/overlay/growing-seed-frames/045.png +0 -0
- package/lib/overlay/growing-seed-frames/046.png +0 -0
- package/lib/overlay/growing-seed-frames/047.png +0 -0
- package/lib/overlay/growing-seed-frames/048.png +0 -0
- package/lib/overlay/growing-seed-frames/049.png +0 -0
- package/lib/overlay/growing-seed-frames/050.png +0 -0
- package/lib/overlay/growing-seed-frames/051.png +0 -0
- package/lib/overlay/growing-seed-frames/052.png +0 -0
- package/lib/overlay/growing-seed-frames/053.png +0 -0
- package/lib/overlay/growing-seed-frames/054.png +0 -0
- package/lib/overlay/growing-seed-frames/055.png +0 -0
- package/lib/overlay/growing-seed-frames/056.png +0 -0
- package/lib/overlay/growing-seed.apng +0 -0
- package/lib/overlay/icon-frames/000.png +0 -0
- package/lib/overlay/icon-frames/001.png +0 -0
- package/lib/overlay/icon-frames/002.png +0 -0
- package/lib/overlay/icon-frames/003.png +0 -0
- package/lib/overlay/icon-frames/004.png +0 -0
- package/lib/overlay/icon-frames/005.png +0 -0
- package/lib/overlay/icon-frames/006.png +0 -0
- package/lib/overlay/icon-frames/007.png +0 -0
- package/lib/overlay/icon-frames/008.png +0 -0
- package/lib/overlay/icon-frames/009.png +0 -0
- package/lib/overlay/icon-frames/010.png +0 -0
- package/lib/overlay/icon-frames/011.png +0 -0
- package/lib/overlay/icon-frames/012.png +0 -0
- package/lib/overlay/icon-frames/013.png +0 -0
- package/lib/overlay/icon-frames/014.png +0 -0
- package/lib/overlay/icon-frames/015.png +0 -0
- package/lib/overlay/icon-frames/016.png +0 -0
- package/lib/overlay/icon-frames/017.png +0 -0
- package/lib/overlay/icon-frames/018.png +0 -0
- package/lib/overlay/icon-frames/019.png +0 -0
- package/lib/overlay/icon-frames/020.png +0 -0
- package/lib/overlay/icon-frames/021.png +0 -0
- package/lib/overlay/icon-frames/022.png +0 -0
- package/lib/overlay/icon-frames/023.png +0 -0
- package/lib/overlay/icon-frames/024.png +0 -0
- package/lib/overlay/icon-frames/025.png +0 -0
- package/lib/overlay/icon-frames/026.png +0 -0
- package/lib/overlay/icon-frames/027.png +0 -0
- package/lib/overlay/icon-frames/028.png +0 -0
- package/lib/overlay/icon-frames/029.png +0 -0
- package/lib/overlay/icon-frames/030.png +0 -0
- package/lib/overlay/icon-frames/031.png +0 -0
- package/lib/overlay/icon-frames/032.png +0 -0
- package/lib/overlay/icon-frames/033.png +0 -0
- package/lib/overlay/icon-frames/034.png +0 -0
- package/lib/overlay/icon-frames/035.png +0 -0
- package/lib/overlay/icon-frames/036.png +0 -0
- package/lib/overlay/icon-frames/037.png +0 -0
- package/lib/overlay/icon-frames/038.png +0 -0
- package/lib/overlay/icon-frames/039.png +0 -0
- package/lib/overlay/icon-frames/040.png +0 -0
- package/lib/overlay/icon-frames/041.png +0 -0
- package/lib/overlay/icon-frames/042.png +0 -0
- package/lib/overlay/icon-frames/043.png +0 -0
- package/lib/overlay/icon-frames/044.png +0 -0
- package/lib/overlay/icon-frames/045.png +0 -0
- package/lib/overlay/icon-frames/046.png +0 -0
- package/lib/overlay/icon-frames/047.png +0 -0
- package/lib/overlay/icon-frames/048.png +0 -0
- package/lib/overlay/icon-frames/049.png +0 -0
- package/lib/overlay/icon-frames/050.png +0 -0
- package/lib/overlay/icon-frames/051.png +0 -0
- package/lib/overlay/icon-frames/052.png +0 -0
- package/lib/overlay/icon-frames/053.png +0 -0
- package/lib/overlay/icon-frames/054.png +0 -0
- package/lib/overlay/icon-frames/055.png +0 -0
- package/lib/overlay/icon-frames/056.png +0 -0
- package/lib/overlay/icon.apng +0 -0
- package/lib/overlay/icon.gif +0 -0
- package/lib/overlay/icon.png +0 -0
- package/lib/overlay/overlay.swift +574 -0
- package/lib/overlay/plant-seeds-frames/000.png +0 -0
- package/lib/overlay/plant-seeds-frames/001.png +0 -0
- package/lib/overlay/plant-seeds-frames/002.png +0 -0
- package/lib/overlay/plant-seeds-frames/003.png +0 -0
- package/lib/overlay/plant-seeds-frames/004.png +0 -0
- package/lib/overlay/plant-seeds-frames/005.png +0 -0
- package/lib/overlay/plant-seeds-frames/006.png +0 -0
- package/lib/overlay/plant-seeds-frames/007.png +0 -0
- package/lib/overlay/plant-seeds-frames/008.png +0 -0
- package/lib/overlay/plant-seeds-frames/009.png +0 -0
- package/lib/overlay/plant-seeds-frames/010.png +0 -0
- package/lib/overlay/plant-seeds-frames/011.png +0 -0
- package/lib/overlay/plant-seeds-frames/012.png +0 -0
- package/lib/overlay/plant-seeds-frames/013.png +0 -0
- package/lib/overlay/plant-seeds-frames/014.png +0 -0
- package/lib/overlay/plant-seeds-frames/015.png +0 -0
- package/lib/overlay/plant-seeds-frames/016.png +0 -0
- package/lib/overlay/plant-seeds-frames/017.png +0 -0
- package/lib/overlay/plant-seeds-frames/018.png +0 -0
- package/lib/overlay/plant-seeds-frames/019.png +0 -0
- package/lib/overlay/plant-seeds-frames/020.png +0 -0
- package/lib/overlay/plant-seeds-frames/021.png +0 -0
- package/lib/overlay/plant-seeds-frames/022.png +0 -0
- package/lib/overlay/plant-seeds-frames/023.png +0 -0
- package/lib/overlay/plant-seeds-frames/024.png +0 -0
- package/lib/overlay/plant-seeds-frames/025.png +0 -0
- package/lib/overlay/plant-seeds-frames/026.png +0 -0
- package/lib/overlay/plant-seeds-frames/027.png +0 -0
- package/lib/overlay/plant-seeds-frames/028.png +0 -0
- package/lib/overlay/plant-seeds-frames/029.png +0 -0
- package/lib/overlay/plant-seeds-frames/030.png +0 -0
- package/lib/overlay/plant-seeds-frames/031.png +0 -0
- package/lib/overlay/plant-seeds-frames/032.png +0 -0
- package/lib/overlay/plant-seeds-frames/033.png +0 -0
- package/lib/overlay/plant-seeds-frames/034.png +0 -0
- package/lib/overlay/plant-seeds-frames/035.png +0 -0
- package/lib/overlay/plant-seeds-frames/036.png +0 -0
- package/lib/overlay/plant-seeds-frames/037.png +0 -0
- package/lib/overlay/plant-seeds-frames/038.png +0 -0
- package/lib/overlay/plant-seeds-frames/039.png +0 -0
- package/lib/overlay/plant-seeds-frames/040.png +0 -0
- package/lib/overlay/plant-seeds-frames/041.png +0 -0
- package/lib/overlay/plant-seeds-frames/042.png +0 -0
- package/lib/overlay/plant-seeds-frames/043.png +0 -0
- package/lib/overlay/plant-seeds-frames/044.png +0 -0
- package/lib/overlay/plant-seeds-frames/045.png +0 -0
- package/lib/overlay/plant-seeds.apng +0 -0
- package/lib/overlay/watering-can-frames/000.png +0 -0
- package/lib/overlay/watering-can-frames/001.png +0 -0
- package/lib/overlay/watering-can-frames/002.png +0 -0
- package/lib/overlay/watering-can-frames/003.png +0 -0
- package/lib/overlay/watering-can-frames/004.png +0 -0
- package/lib/overlay/watering-can-frames/005.png +0 -0
- package/lib/overlay/watering-can-frames/006.png +0 -0
- package/lib/overlay/watering-can-frames/007.png +0 -0
- package/lib/overlay/watering-can-frames/008.png +0 -0
- package/lib/overlay/watering-can-frames/009.png +0 -0
- package/lib/overlay/watering-can-frames/010.png +0 -0
- package/lib/overlay/watering-can-frames/011.png +0 -0
- package/lib/overlay/watering-can-frames/012.png +0 -0
- package/lib/overlay/watering-can-frames/013.png +0 -0
- package/lib/overlay/watering-can-frames/014.png +0 -0
- package/lib/overlay/watering-can-frames/015.png +0 -0
- package/lib/overlay/watering-can-frames/016.png +0 -0
- package/lib/overlay/watering-can-frames/017.png +0 -0
- package/lib/overlay/watering-can-frames/018.png +0 -0
- package/lib/overlay/watering-can-frames/019.png +0 -0
- package/lib/overlay/watering-can-frames/020.png +0 -0
- package/lib/overlay/watering-can-frames/021.png +0 -0
- package/lib/overlay/watering-can-frames/022.png +0 -0
- package/lib/overlay/watering-can-frames/023.png +0 -0
- package/lib/overlay/watering-can-frames/024.png +0 -0
- package/lib/overlay/watering-can-frames/025.png +0 -0
- package/lib/overlay/watering-can-frames/026.png +0 -0
- package/lib/overlay/watering-can-frames/027.png +0 -0
- package/lib/overlay/watering-can-frames/028.png +0 -0
- package/lib/overlay/watering-can-frames/029.png +0 -0
- package/lib/overlay/watering-can-frames/030.png +0 -0
- package/lib/overlay/watering-can-frames/031.png +0 -0
- package/lib/overlay/watering-can-frames/032.png +0 -0
- package/lib/overlay/watering-can-frames/033.png +0 -0
- package/lib/overlay/watering-can-frames/034.png +0 -0
- package/lib/overlay/watering-can-frames/035.png +0 -0
- package/lib/overlay/watering-can-frames/036.png +0 -0
- package/lib/overlay/watering-can-frames/037.png +0 -0
- package/lib/overlay/watering-can-frames/038.png +0 -0
- package/lib/overlay/watering-can-frames/039.png +0 -0
- package/lib/overlay/watering-can-frames/040.png +0 -0
- package/lib/overlay/watering-can-frames/041.png +0 -0
- package/lib/overlay/watering-can-frames/042.png +0 -0
- package/lib/overlay/watering-can-frames/043.png +0 -0
- package/lib/overlay/watering-can.apng +0 -0
- package/lib/polling-agent.mjs +249 -0
- package/lib/redaction-review.mjs +71 -10
- package/lib/simulation-orchestrator.mjs +3 -0
- package/lib/source-query-client.mjs +99 -0
- package/package.json +1 -1
- package/postinstall.mjs +1 -0
|
@@ -16,6 +16,7 @@ import path from 'node:path';
|
|
|
16
16
|
import { execSync, spawn } from 'node:child_process';
|
|
17
17
|
import { DATA_DIR, INSTALL_DIR } from './utils.mjs';
|
|
18
18
|
import { launchRedactionReview } from './redaction-review.mjs';
|
|
19
|
+
import { querySource } from './source-query-client.mjs';
|
|
19
20
|
|
|
20
21
|
const REPLICAS_DIR = path.join(DATA_DIR, 'replicas');
|
|
21
22
|
const LOCK_DIR = path.join(DATA_DIR, '.locks');
|
|
@@ -440,6 +441,25 @@ If something is fundamentally broken, document it in env-status.json and do your
|
|
|
440
441
|
envStatus = JSON.parse(fs.readFileSync(envStatusPath, 'utf8'));
|
|
441
442
|
} catch {}
|
|
442
443
|
|
|
444
|
+
// If running remotely and Opus reported missing files, fetch them via source queries
|
|
445
|
+
if (process.env.ENVSEED_REMOTE === '1' && envStatus.missingFiles?.length > 0) {
|
|
446
|
+
const incidentId = process.env.ENVSEED_INCIDENT_ID;
|
|
447
|
+
const apiEndpoint = process.env.ENVSEED_API_ENDPOINT;
|
|
448
|
+
const apiKey = loadConfig()?.apiKey;
|
|
449
|
+
if (incidentId && apiEndpoint) {
|
|
450
|
+
for (const filePath of envStatus.missingFiles) {
|
|
451
|
+
try {
|
|
452
|
+
const result = await querySource(incidentId, filePath, apiEndpoint, apiKey || '');
|
|
453
|
+
if (result.success && result.data) {
|
|
454
|
+
const destPath = path.join(replicaOutputDir, '..', 'workspace', filePath);
|
|
455
|
+
fs.mkdirSync(path.dirname(destPath), { recursive: true });
|
|
456
|
+
fs.writeFileSync(destPath, result.data);
|
|
457
|
+
}
|
|
458
|
+
} catch {}
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
443
463
|
// If Opus generated a Dockerfile, try building it
|
|
444
464
|
if (fs.existsSync(generatedDockerfile)) {
|
|
445
465
|
try {
|
package/lib/hook-handler.mjs
CHANGED
|
@@ -1,11 +1,40 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import { spawn } from 'node:child_process';
|
|
3
|
+
import { spawn, spawnSync } from 'node:child_process';
|
|
4
4
|
import { readStdin, DATA_DIR, INSTALL_DIR } from './utils.mjs';
|
|
5
5
|
import { trackSession } from './session-tracker.mjs';
|
|
6
6
|
|
|
7
7
|
const PENDING_FILE = path.join(DATA_DIR, 'pending-alerts.jsonl');
|
|
8
8
|
const BACKGROUND_SCRIPT = path.join(path.dirname(new URL(import.meta.url).pathname), 'background-analyzer.mjs');
|
|
9
|
+
const OVERLAY_BINARY = path.join(path.dirname(new URL(import.meta.url).pathname), 'overlay', 'envseed-overlay');
|
|
10
|
+
const OVERLAY_SOURCE = path.join(path.dirname(new URL(import.meta.url).pathname), 'overlay', 'overlay.swift');
|
|
11
|
+
|
|
12
|
+
function tryShowOverlay(sessionId, cwd, summary) {
|
|
13
|
+
const args = [sessionId || 'auto', cwd || '', summary || ''];
|
|
14
|
+
|
|
15
|
+
// Try prebuilt binary first, then compile from source, return true if launched
|
|
16
|
+
try {
|
|
17
|
+
if (fs.existsSync(OVERLAY_BINARY)) {
|
|
18
|
+
const child = spawn(OVERLAY_BINARY, args, { detached: true, stdio: 'ignore' });
|
|
19
|
+
child.unref();
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
} catch { /* binary failed (e.g. Santa, wrong arch) — try compiling */ }
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
if (fs.existsSync(OVERLAY_SOURCE)) {
|
|
26
|
+
const compiled = OVERLAY_BINARY + '-compiled';
|
|
27
|
+
const result = spawnSync('swiftc', [OVERLAY_SOURCE, '-o', compiled, '-framework', 'Cocoa'], { timeout: 15000 });
|
|
28
|
+
if (result.status === 0 && fs.existsSync(compiled)) {
|
|
29
|
+
const child = spawn(compiled, args, { detached: true, stdio: 'ignore' });
|
|
30
|
+
child.unref();
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
} catch { /* compile failed — no Swift toolchain, not macOS, etc. */ }
|
|
35
|
+
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
9
38
|
|
|
10
39
|
function loadConfig() {
|
|
11
40
|
try {
|
|
@@ -53,11 +82,17 @@ async function main() {
|
|
|
53
82
|
// Only show if the assessment STARTS with [GOOD OPPORTUNITY]
|
|
54
83
|
const isGood = /^\[GOOD OPPORTUNITY\]/i.test(p.assessment.trim());
|
|
55
84
|
if (isGood) {
|
|
56
|
-
// Strip the tag prefix
|
|
85
|
+
// Strip the tag prefix for context
|
|
57
86
|
const body = p.assessment.trim().replace(/^\[GOOD OPPORTUNITY\]\s*[-—]?\s*/i, '');
|
|
58
|
-
|
|
59
|
-
const
|
|
60
|
-
|
|
87
|
+
// Try native overlay first; fall back to chat text
|
|
88
|
+
const summaryLine = body.split('\n')[0].slice(0, 120);
|
|
89
|
+
const overlayShown = tryShowOverlay(event.session_id, event.cwd, summaryLine);
|
|
90
|
+
if (!overlayShown) {
|
|
91
|
+
messages.push(`\u{1F6A8} ${body.split('\n').slice(0, 3).join('\n')}\n\nType /log-incident to archive this for eval development.`);
|
|
92
|
+
}
|
|
93
|
+
// Stash full assessment in hookSpecificOutput so Claude has context
|
|
94
|
+
if (!output._assessmentDetails) output._assessmentDetails = [];
|
|
95
|
+
output._assessmentDetails.push(body);
|
|
61
96
|
}
|
|
62
97
|
// [INTERESTING] and [LOW] are silently logged but not shown
|
|
63
98
|
}
|
|
@@ -75,14 +110,18 @@ async function main() {
|
|
|
75
110
|
const hookEventName = event.hook_event_name;
|
|
76
111
|
if (hookEventName === 'PreToolUse' || hookEventName === 'PostToolUse' ||
|
|
77
112
|
hookEventName === 'SessionStart' || hookEventName === 'UserPromptSubmit') {
|
|
78
|
-
output.
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
113
|
+
const details = output._assessmentDetails || [];
|
|
114
|
+
output.hookSpecificOutput = {
|
|
115
|
+
hookEventName,
|
|
116
|
+
additionalContext: details.length > 0
|
|
117
|
+
? `[envseed] \u{1F6A8} Opportunity detected. Assessment: ${details.join(' | ')}. The user can type /log-incident to archive this for eval development.`
|
|
118
|
+
: messages.map(m => `[envseed] ${m}`).join(' | '),
|
|
119
|
+
};
|
|
82
120
|
}
|
|
83
121
|
}
|
|
84
122
|
|
|
85
123
|
// 2. Output pending alerts (fast — just string concat)
|
|
124
|
+
delete output._assessmentDetails;
|
|
86
125
|
if (Object.keys(output).length > 0) {
|
|
87
126
|
process.stdout.write(JSON.stringify(output));
|
|
88
127
|
}
|
package/lib/log-incident.mjs
CHANGED
|
@@ -259,11 +259,11 @@ async function main() {
|
|
|
259
259
|
if (redactionResult.skipped) {
|
|
260
260
|
log(' Redaction review disabled in config');
|
|
261
261
|
} else if (redactionResult.timedOut) {
|
|
262
|
-
log(' Redaction review timed out
|
|
262
|
+
log(' Redaction review timed out, using snapshot as-is');
|
|
263
263
|
} else if (redactionResult.redacted) {
|
|
264
264
|
log(' Redaction review completed');
|
|
265
265
|
} else {
|
|
266
|
-
log(' Redaction review did not complete
|
|
266
|
+
log(' Redaction review did not complete, using original snapshot');
|
|
267
267
|
}
|
|
268
268
|
}
|
|
269
269
|
|
|
@@ -295,24 +295,53 @@ async function main() {
|
|
|
295
295
|
log(' (incident saved locally, upload can be retried with: envseed incident <id> upload)');
|
|
296
296
|
}
|
|
297
297
|
|
|
298
|
-
// 6.
|
|
298
|
+
// 6. Start simulations (remote or local)
|
|
299
299
|
log('5/5 Starting simulations...');
|
|
300
|
-
|
|
300
|
+
// Re-read config (already loaded at top for credential check, but use fresh copy)
|
|
301
|
+
const simConfig = {};
|
|
301
302
|
try {
|
|
302
|
-
Object.assign(
|
|
303
|
+
Object.assign(simConfig, JSON.parse(fs.readFileSync(path.join(INSTALL_DIR, 'config.json'), 'utf8')));
|
|
303
304
|
} catch {}
|
|
304
305
|
|
|
305
|
-
|
|
306
|
+
const libDir = path.dirname(new URL(import.meta.url).pathname);
|
|
307
|
+
|
|
308
|
+
if (simConfig.enableSimulations === false) {
|
|
306
309
|
log(' Simulations disabled in config');
|
|
310
|
+
} else if (simConfig.remoteReplication && s3Result.success) {
|
|
311
|
+
// Remote mode: POST /reconstruct to launch EC2 worker, spawn polling agent
|
|
312
|
+
log(' Triggering remote replication...');
|
|
313
|
+
try {
|
|
314
|
+
const reconstructRes = await httpPost(
|
|
315
|
+
`${simConfig.uploadEndpoint}/reconstruct/${incidentId}`,
|
|
316
|
+
{ apiEndpoint: simConfig.uploadEndpoint },
|
|
317
|
+
simConfig.apiKey,
|
|
318
|
+
);
|
|
319
|
+
if (reconstructRes.success) {
|
|
320
|
+
log(` Worker launched: instance ${reconstructRes.body?.instanceId || 'pending'}`);
|
|
321
|
+
log(` Job ID: ${reconstructRes.body?.jobId || 'unknown'}`);
|
|
322
|
+
|
|
323
|
+
// Spawn polling agent to serve source queries
|
|
324
|
+
const pollingScript = path.join(libDir, 'polling-agent.mjs');
|
|
325
|
+
const pollingChild = spawn('node', [
|
|
326
|
+
pollingScript, incidentId, cwd, simConfig.uploadEndpoint, simConfig.apiKey,
|
|
327
|
+
], { detached: true, stdio: 'ignore' });
|
|
328
|
+
pollingChild.unref();
|
|
329
|
+
log(` Polling agent spawned (PID ${pollingChild.pid})`);
|
|
330
|
+
} else {
|
|
331
|
+
log(` Remote replication failed: ${reconstructRes.error || 'unknown error'}`);
|
|
332
|
+
log(' Falling back to local simulations...');
|
|
333
|
+
spawnLocalOrchestrator(libDir, incidentId, log);
|
|
334
|
+
}
|
|
335
|
+
} catch (err) {
|
|
336
|
+
log(` Remote replication error: ${err.message}`);
|
|
337
|
+
log(' Falling back to local simulations...');
|
|
338
|
+
spawnLocalOrchestrator(libDir, incidentId, log);
|
|
339
|
+
}
|
|
307
340
|
} else {
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
});
|
|
313
|
-
child.unref();
|
|
314
|
-
log(` Orchestrator spawned (PID ${child.pid})`);
|
|
315
|
-
log(` Check progress: envseed incident ${incidentId}`);
|
|
341
|
+
if (simConfig.remoteReplication && !s3Result.success) {
|
|
342
|
+
log(' Remote replication requires S3 upload — falling back to local');
|
|
343
|
+
}
|
|
344
|
+
spawnLocalOrchestrator(libDir, incidentId, log);
|
|
316
345
|
}
|
|
317
346
|
|
|
318
347
|
// Write initial status
|
|
@@ -320,8 +349,9 @@ async function main() {
|
|
|
320
349
|
started: new Date().toISOString(),
|
|
321
350
|
archivalComplete: true,
|
|
322
351
|
s3Uploaded: s3Result.success,
|
|
323
|
-
|
|
324
|
-
|
|
352
|
+
remote: !!(simConfig.remoteReplication && s3Result.success),
|
|
353
|
+
simulationsStarted: simConfig.enableSimulations !== false,
|
|
354
|
+
totalPlanned: simConfig.simulationCount || 2,
|
|
325
355
|
completed: 0,
|
|
326
356
|
failed: 0,
|
|
327
357
|
running: 0,
|
|
@@ -333,6 +363,50 @@ async function main() {
|
|
|
333
363
|
if (s3Result.success) log(`S3 path: ${s3Result.s3Path}`);
|
|
334
364
|
}
|
|
335
365
|
|
|
366
|
+
function spawnLocalOrchestrator(libDir, incidentId, log) {
|
|
367
|
+
const orchestratorScript = path.join(libDir, 'simulation-orchestrator.mjs');
|
|
368
|
+
const child = spawn('node', [orchestratorScript, incidentId], {
|
|
369
|
+
detached: true,
|
|
370
|
+
stdio: 'ignore',
|
|
371
|
+
});
|
|
372
|
+
child.unref();
|
|
373
|
+
log(` Local orchestrator spawned (PID ${child.pid})`);
|
|
374
|
+
log(` Check progress: envseed incident ${incidentId}`);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
async function httpPost(url, body, apiKey) {
|
|
378
|
+
const https = await import('node:https');
|
|
379
|
+
const { URL } = await import('node:url');
|
|
380
|
+
return new Promise((resolve, reject) => {
|
|
381
|
+
const parsed = new URL(url);
|
|
382
|
+
const bodyStr = JSON.stringify(body);
|
|
383
|
+
const req = https.request({
|
|
384
|
+
method: 'POST',
|
|
385
|
+
hostname: parsed.hostname,
|
|
386
|
+
path: parsed.pathname,
|
|
387
|
+
headers: {
|
|
388
|
+
'Content-Type': 'application/json',
|
|
389
|
+
'Content-Length': Buffer.byteLength(bodyStr),
|
|
390
|
+
'x-api-key': apiKey,
|
|
391
|
+
},
|
|
392
|
+
}, (res) => {
|
|
393
|
+
let data = '';
|
|
394
|
+
res.on('data', (chunk) => { data += chunk; });
|
|
395
|
+
res.on('end', () => {
|
|
396
|
+
try {
|
|
397
|
+
const parsed = JSON.parse(data);
|
|
398
|
+
resolve({ success: res.statusCode === 200, body: parsed, error: parsed.error });
|
|
399
|
+
} catch {
|
|
400
|
+
resolve({ success: false, error: data });
|
|
401
|
+
}
|
|
402
|
+
});
|
|
403
|
+
});
|
|
404
|
+
req.on('error', reject);
|
|
405
|
+
req.write(bodyStr);
|
|
406
|
+
req.end();
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
|
|
336
410
|
main().catch(err => {
|
|
337
411
|
process.stderr.write(`log-incident error: ${err.message}\n${err.stack}\n`);
|
|
338
412
|
process.exit(1);
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|