getprismo 0.1.38 → 0.1.39
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/prismo-dev/agent.js
CHANGED
|
@@ -174,13 +174,32 @@ module.exports = function createAgent(deps) {
|
|
|
174
174
|
return url;
|
|
175
175
|
}
|
|
176
176
|
|
|
177
|
+
async function reportProgress(config, actionId, step, detail, options = {}) {
|
|
178
|
+
const endpoint = options.progressEndpoint || `${apiBase(config)}/v1/dev/workspace/actions/${actionId}/progress`;
|
|
179
|
+
try {
|
|
180
|
+
await requestJson("POST", endpoint, config.token, {
|
|
181
|
+
step,
|
|
182
|
+
detail: detail || null,
|
|
183
|
+
timestamp: new Date().toISOString(),
|
|
184
|
+
}, options.timeoutMs || 5000);
|
|
185
|
+
} catch (_) {}
|
|
186
|
+
}
|
|
187
|
+
|
|
177
188
|
async function executeAction(action, rootDir, options = {}) {
|
|
178
189
|
const root = repoRoot(path.resolve(rootDir || process.cwd()), action);
|
|
179
190
|
const parsed = parseCommand(action.command);
|
|
180
191
|
const startedAt = new Date().toISOString();
|
|
192
|
+
const config = options._config || null;
|
|
193
|
+
const progress = config ? (step, detail) => reportProgress(config, action.id, step, detail, options) : async () => {};
|
|
181
194
|
|
|
182
195
|
if (parsed.command === "doctor" || action.actionType === "doctor") {
|
|
196
|
+
await progress("scanning", "Scanning repo for context issues");
|
|
183
197
|
const result = runDoctor(root, { limit: options.limit || 3, applySuggestions: true, json: true });
|
|
198
|
+
const score = result.after?.score ?? result.scan?.score ?? null;
|
|
199
|
+
const issueCount = result.scan?.issues?.length || 0;
|
|
200
|
+
const generatedFiles = result.generatedFiles || result.optimize?.generatedFiles || [];
|
|
201
|
+
if (issueCount > 0) await progress("fixing", `Found ${issueCount} issue${issueCount === 1 ? "" : "s"}, applying fixes`);
|
|
202
|
+
await progress("done", `Score: ${score}/100, generated ${generatedFiles.length} file${generatedFiles.length === 1 ? "" : "s"}`);
|
|
184
203
|
return {
|
|
185
204
|
status: "completed",
|
|
186
205
|
statusMessage: "Doctor completed and applied safe ignore/context fixes.",
|
|
@@ -188,14 +207,16 @@ module.exports = function createAgent(deps) {
|
|
|
188
207
|
command: "doctor",
|
|
189
208
|
startedAt,
|
|
190
209
|
completedAt: new Date().toISOString(),
|
|
191
|
-
score
|
|
192
|
-
generatedFiles
|
|
210
|
+
score,
|
|
211
|
+
generatedFiles,
|
|
193
212
|
},
|
|
194
213
|
};
|
|
195
214
|
}
|
|
196
215
|
|
|
197
216
|
if (parsed.command === "sync" || action.actionType === "sync") {
|
|
217
|
+
await progress("syncing", "Syncing local telemetry to workspace");
|
|
198
218
|
const result = await runSync(root, { limit: options.limit || 20 });
|
|
219
|
+
await progress("done", result.synced ? "Sync completed" : "Sync failed");
|
|
199
220
|
return {
|
|
200
221
|
status: result.synced ? "completed" : "failed",
|
|
201
222
|
statusMessage: result.synced ? "Sync completed." : "Sync could not run because this machine is not connected.",
|
|
@@ -211,6 +232,7 @@ module.exports = function createAgent(deps) {
|
|
|
211
232
|
}
|
|
212
233
|
|
|
213
234
|
if (parsed.command === "guard" || action.actionType === "guard") {
|
|
235
|
+
await progress("guarding", "Running guardrail snapshot across sessions");
|
|
214
236
|
const result = await runGuard(root, {
|
|
215
237
|
tool: "all",
|
|
216
238
|
limit: options.limit || 5,
|
|
@@ -218,6 +240,8 @@ module.exports = function createAgent(deps) {
|
|
|
218
240
|
noSync: false,
|
|
219
241
|
watch: false,
|
|
220
242
|
});
|
|
243
|
+
const eventCount = result.events?.length || 0;
|
|
244
|
+
await progress("done", `Guard complete, ${eventCount} event${eventCount === 1 ? "" : "s"} recorded`);
|
|
221
245
|
return {
|
|
222
246
|
status: "completed",
|
|
223
247
|
statusMessage: "Guard snapshot completed. Start agent watch mode for continuous protection.",
|
|
@@ -226,14 +250,17 @@ module.exports = function createAgent(deps) {
|
|
|
226
250
|
startedAt,
|
|
227
251
|
completedAt: new Date().toISOString(),
|
|
228
252
|
guardRunning: Boolean(result.guardRunning),
|
|
229
|
-
events:
|
|
253
|
+
events: eventCount,
|
|
230
254
|
},
|
|
231
255
|
};
|
|
232
256
|
}
|
|
233
257
|
|
|
234
258
|
if (parsed.command === "context" || parsed.command === "optimize" || action.actionType === "context") {
|
|
235
259
|
const scope = parsed.args.find((arg) => !arg.startsWith("-")) || null;
|
|
260
|
+
await progress("generating", `Generating context pack${scope ? ` for ${scope}` : ""}`);
|
|
236
261
|
const result = runOptimize(root, { scope });
|
|
262
|
+
const generatedFiles = result.generatedFiles || [];
|
|
263
|
+
await progress("done", `Generated ${generatedFiles.length} file${generatedFiles.length === 1 ? "" : "s"}`);
|
|
237
264
|
return {
|
|
238
265
|
status: "completed",
|
|
239
266
|
statusMessage: "Context pack generated.",
|
|
@@ -242,7 +269,7 @@ module.exports = function createAgent(deps) {
|
|
|
242
269
|
startedAt,
|
|
243
270
|
completedAt: new Date().toISOString(),
|
|
244
271
|
scope,
|
|
245
|
-
generatedFiles
|
|
272
|
+
generatedFiles,
|
|
246
273
|
},
|
|
247
274
|
};
|
|
248
275
|
}
|
|
@@ -250,13 +277,16 @@ module.exports = function createAgent(deps) {
|
|
|
250
277
|
if (parsed.command === "shield" || action.actionType === "shield") {
|
|
251
278
|
const commandArgs = parseShieldArgs(parsed.args);
|
|
252
279
|
if (!commandArgs) {
|
|
280
|
+
await progress("rejected", "Command not on safe allowlist");
|
|
253
281
|
return {
|
|
254
282
|
status: "failed",
|
|
255
283
|
statusMessage: "Shield action was rejected because the command is not on the safe allowlist.",
|
|
256
284
|
result: { command: "shield", rejected: true, reason: "unsafe-shield-command" },
|
|
257
285
|
};
|
|
258
286
|
}
|
|
287
|
+
await progress("shielding", `Running shielded command: ${commandArgs.join(" ")}`);
|
|
259
288
|
const result = runShield(root, commandArgs);
|
|
289
|
+
await progress("done", result.exitCode === 0 ? "Command completed" : "Command failed");
|
|
260
290
|
return {
|
|
261
291
|
status: result.exitCode === 0 ? "completed" : "failed",
|
|
262
292
|
statusMessage: result.exitCode === 0 ? "Shielded command completed." : "Shielded command exited with an error.",
|
|
@@ -336,7 +366,7 @@ module.exports = function createAgent(deps) {
|
|
|
336
366
|
status: "running",
|
|
337
367
|
statusMessage: "Running locally through PrismoDev agent.",
|
|
338
368
|
}, options);
|
|
339
|
-
const result = await executeAction(action, rootDir, options);
|
|
369
|
+
const result = await executeAction(action, rootDir, { ...options, _config: config });
|
|
340
370
|
await updateAction(config, action.id, result, options);
|
|
341
371
|
results.push({ id: action.id, label: action.label, ...result });
|
|
342
372
|
}
|
|
@@ -448,10 +478,12 @@ module.exports = function createAgent(deps) {
|
|
|
448
478
|
|
|
449
479
|
const intervalMs = Math.max(5, Number(options.interval || 15)) * 1000;
|
|
450
480
|
const syncIntervalMs = Math.max(30, Number(options.syncInterval || 60)) * 1000;
|
|
481
|
+
const detectIntervalMs = Math.max(60, Number(options.detectInterval || 300)) * 1000;
|
|
451
482
|
let running = true;
|
|
452
483
|
let sleepResolve = null;
|
|
453
484
|
let firstRun = true;
|
|
454
485
|
let lastSyncAt = 0;
|
|
486
|
+
let lastDetectAt = 0;
|
|
455
487
|
|
|
456
488
|
if (options.open) {
|
|
457
489
|
const config = loadConfig();
|
|
@@ -479,9 +511,11 @@ module.exports = function createAgent(deps) {
|
|
|
479
511
|
const now = Date.now();
|
|
480
512
|
const shouldSync = options.noSync !== true && (lastSyncAt === 0 || now - lastSyncAt >= syncIntervalMs);
|
|
481
513
|
if (shouldSync) lastSyncAt = now;
|
|
514
|
+
const shouldDetect = options.autoDetect !== false && (firstRun || now - lastDetectAt >= detectIntervalMs);
|
|
515
|
+
if (shouldDetect) lastDetectAt = now;
|
|
482
516
|
const runOptions = {
|
|
483
517
|
...options,
|
|
484
|
-
autoDetect:
|
|
518
|
+
autoDetect: shouldDetect,
|
|
485
519
|
syncTelemetry: shouldSync,
|
|
486
520
|
};
|
|
487
521
|
firstRun = false;
|
|
@@ -506,6 +540,7 @@ module.exports = function createAgent(deps) {
|
|
|
506
540
|
parseCommand,
|
|
507
541
|
renderAgentTerminal,
|
|
508
542
|
reportAutoDetect,
|
|
543
|
+
reportProgress,
|
|
509
544
|
runAgent,
|
|
510
545
|
runAgentOnce,
|
|
511
546
|
runAutoDetect,
|
package/lib/prismo-dev/cli.js
CHANGED
|
@@ -345,7 +345,7 @@ function createCli(deps) {
|
|
|
345
345
|
dryRun: rest.includes("--dry-run"),
|
|
346
346
|
});
|
|
347
347
|
result.next = result.connector?.started
|
|
348
|
-
? [`${NPX_COMMAND} status
|
|
348
|
+
? [`${NPX_COMMAND} status`]
|
|
349
349
|
: [`${NPX_COMMAND} connector install`, `${NPX_COMMAND} status`];
|
|
350
350
|
}
|
|
351
351
|
if (result.connected && (rest.includes("--open") || !rest.includes("--no-open"))) {
|
|
@@ -424,6 +424,7 @@ function createCli(deps) {
|
|
|
424
424
|
const json = rest.includes("--json");
|
|
425
425
|
const intervalIndex = rest.indexOf("--interval");
|
|
426
426
|
const syncIntervalIndex = rest.indexOf("--sync-interval");
|
|
427
|
+
const detectIntervalIndex = rest.indexOf("--detect-interval");
|
|
427
428
|
const limitIndex = rest.indexOf("--limit");
|
|
428
429
|
const budgetIndex = rest.indexOf("--budget");
|
|
429
430
|
const modeIndex = rest.indexOf("--mode");
|
|
@@ -431,7 +432,7 @@ function createCli(deps) {
|
|
|
431
432
|
if (!AGENT_VALID_MODES.has(modeValue)) {
|
|
432
433
|
throw new Error(`Invalid agent mode: ${modeValue}. Valid modes: observe, suggest, autopilot`);
|
|
433
434
|
}
|
|
434
|
-
const positional = getPositionals(rest, new Set(["--interval", "--sync-interval", "--limit", "--budget", "--mode"]));
|
|
435
|
+
const positional = getPositionals(rest, new Set(["--interval", "--sync-interval", "--detect-interval", "--limit", "--budget", "--mode"]));
|
|
435
436
|
const target = positional[0] || process.cwd();
|
|
436
437
|
const agentOptions = {
|
|
437
438
|
json,
|
|
@@ -442,6 +443,7 @@ function createCli(deps) {
|
|
|
442
443
|
noSync: rest.includes("--no-sync"),
|
|
443
444
|
interval: parsePositiveInt(intervalIndex >= 0 ? rest[intervalIndex + 1] : null, 15),
|
|
444
445
|
syncInterval: parsePositiveInt(syncIntervalIndex >= 0 ? rest[syncIntervalIndex + 1] : null, 60),
|
|
446
|
+
detectInterval: parsePositiveInt(detectIntervalIndex >= 0 ? rest[detectIntervalIndex + 1] : null, 300),
|
|
445
447
|
limit: parsePositiveInt(limitIndex >= 0 ? rest[limitIndex + 1] : null, 5),
|
|
446
448
|
syncLimit: parsePositiveInt(limitIndex >= 0 ? rest[limitIndex + 1] : null, 20),
|
|
447
449
|
tokenBudget: parseTokenBudget(budgetIndex >= 0 ? rest[budgetIndex + 1] : null) || 600000,
|
|
@@ -405,20 +405,32 @@ module.exports = function createCloudSync(deps) {
|
|
|
405
405
|
function renderConnectTerminal(result) {
|
|
406
406
|
const lines = [];
|
|
407
407
|
lines.push("");
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
lines.push(
|
|
416
|
-
|
|
417
|
-
|
|
408
|
+
if (result.connected && result.connector?.started) {
|
|
409
|
+
lines.push("Prismo agent is running.");
|
|
410
|
+
lines.push("");
|
|
411
|
+
lines.push(`Device: ${result.device.name}`);
|
|
412
|
+
lines.push(`Mode: ${result.connector.mode || "autopilot"}`);
|
|
413
|
+
lines.push(`Poll: every ${result.connector.interval || 15}s`);
|
|
414
|
+
lines.push(`Sync: every ${result.connector.syncInterval || 60}s`);
|
|
415
|
+
lines.push("");
|
|
416
|
+
lines.push("Your agent will continuously scan, repair, and guard this repo.");
|
|
417
|
+
lines.push("Open the dashboard to see what it's doing.");
|
|
418
|
+
} else {
|
|
419
|
+
lines.push("PrismoDev Connect");
|
|
420
|
+
lines.push("");
|
|
421
|
+
lines.push(`Status: ${result.connected ? "connected" : "token needed"}`);
|
|
422
|
+
lines.push(`Config: ${result.configPath}`);
|
|
423
|
+
lines.push(`API: ${result.apiUrl}`);
|
|
424
|
+
lines.push(`Device: ${result.device.name}`);
|
|
425
|
+
if (result.connector) {
|
|
426
|
+
lines.push(`Connector: ${result.connector.started ? "started" : result.connector.installed ? "installed" : "not started"}`);
|
|
427
|
+
if (result.connector.reason) lines.push(`Note: ${result.connector.reason}`);
|
|
428
|
+
if (result.connector.error) lines.push(`Error: ${result.connector.error}`);
|
|
429
|
+
}
|
|
430
|
+
lines.push("");
|
|
431
|
+
lines.push("Next");
|
|
432
|
+
result.next.forEach((item, index) => lines.push(`${index + 1}. ${item}`));
|
|
418
433
|
}
|
|
419
|
-
lines.push("");
|
|
420
|
-
lines.push("Next");
|
|
421
|
-
result.next.forEach((item, index) => lines.push(`${index + 1}. ${item}`));
|
|
422
434
|
return lines.join("\n");
|
|
423
435
|
}
|
|
424
436
|
|
|
@@ -80,9 +80,10 @@ module.exports = function createConnector(deps) {
|
|
|
80
80
|
const root = path.resolve(rootDir || process.cwd());
|
|
81
81
|
const interval = Math.max(5, Number(options.interval || 15));
|
|
82
82
|
const syncInterval = Math.max(30, Number(options.syncInterval || 60));
|
|
83
|
+
const detectInterval = Math.max(60, Number(options.detectInterval || 300));
|
|
83
84
|
const mode = options.mode || "autopilot";
|
|
84
85
|
fs.mkdirSync(connectorDir(), { recursive: true });
|
|
85
|
-
const command = `${BACKGROUND_COMMAND} agent --watch --interval ${interval} --sync-interval ${syncInterval} --mode ${shellEscape(mode)} ${shellEscape(root)}`;
|
|
86
|
+
const command = `${BACKGROUND_COMMAND} agent --watch --interval ${interval} --sync-interval ${syncInterval} --detect-interval ${detectInterval} --mode ${shellEscape(mode)} ${shellEscape(root)}`;
|
|
86
87
|
const contents = [
|
|
87
88
|
"#!/bin/sh",
|
|
88
89
|
"set -eu",
|
|
@@ -97,6 +98,7 @@ module.exports = function createConnector(deps) {
|
|
|
97
98
|
root,
|
|
98
99
|
interval,
|
|
99
100
|
syncInterval,
|
|
101
|
+
detectInterval,
|
|
100
102
|
mode,
|
|
101
103
|
command,
|
|
102
104
|
platform: process.platform,
|
|
@@ -104,7 +106,7 @@ module.exports = function createConnector(deps) {
|
|
|
104
106
|
logPath: logPath(),
|
|
105
107
|
errorLogPath: errorLogPath(),
|
|
106
108
|
});
|
|
107
|
-
return { root, interval, syncInterval, mode, command };
|
|
109
|
+
return { root, interval, syncInterval, detectInterval, mode, command };
|
|
108
110
|
}
|
|
109
111
|
|
|
110
112
|
function writePlist() {
|
package/package.json
CHANGED