getprismo 0.1.57 → 0.1.59

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.
@@ -980,6 +980,7 @@ module.exports = function createAgent(deps) {
980
980
  openWorkspace,
981
981
  parseCommand,
982
982
  renderAgentTerminal,
983
+ registerSelfRepair,
983
984
  reportAutoDetect,
984
985
  reportProgress,
985
986
  runAgent,
@@ -135,6 +135,7 @@ function createCli(deps) {
135
135
  buildMultiSessionTimeline: _timeline,
136
136
  buildSyncPayload,
137
137
  loadConfig,
138
+ registerSelfRepair,
138
139
  buildReceipt: _receipt,
139
140
  buildReplay: _replay,
140
141
  runFirewall: _firewall,
@@ -841,15 +842,37 @@ function createCli(deps) {
841
842
  else console.log(renderPlannerTerminal(result));
842
843
  return;
843
844
  }
845
+ const tier = (tierIndex >= 0 ? ownArgs[tierIndex + 1] : null) || "mild";
844
846
  const result = await runRepair(target, cause, {
845
847
  limit: parsePositiveInt(limitIndex >= 0 ? ownArgs[limitIndex + 1] : null, 5),
846
848
  tokenBudget: parseTokenBudget(budgetIndex >= 0 ? ownArgs[budgetIndex + 1] : null),
847
849
  scope: scopeIndex >= 0 ? ownArgs[scopeIndex + 1] : null,
848
- tier: tierIndex >= 0 ? ownArgs[tierIndex + 1] : null,
850
+ tier,
849
851
  commandArgs,
850
852
  });
851
- if (json) console.log(JSON.stringify(result, null, 2));
852
- else console.log(renderRepairTerminal(result));
853
+ // Register a completed manual repair with the cloud so the backend
854
+ // verification loop measures it like a dashboard-queued repair —
855
+ // otherwise hand-run repairs never become verified savings.
856
+ let registered = false;
857
+ if (result.status === "completed" && typeof registerSelfRepair === "function") {
858
+ const config = loadConfig();
859
+ if (config && config.token) {
860
+ registered = await registerSelfRepair(config, {
861
+ generatedAt: result.generatedAt,
862
+ decision: { cause: result.cause, tier },
863
+ outcome: {
864
+ status: result.status,
865
+ statusMessage: result.statusMessage,
866
+ generatedFiles: (result.result && result.result.generatedFiles) || [],
867
+ },
868
+ });
869
+ }
870
+ }
871
+ if (json) console.log(JSON.stringify({ ...result, registered }, null, 2));
872
+ else {
873
+ console.log(renderRepairTerminal(result));
874
+ if (registered) console.log("\nReported to Prismo Cloud — savings will verify as new sessions come in.");
875
+ }
853
876
  if (result.status === "failed") process.exitCode = 1;
854
877
  return;
855
878
  }
@@ -13,9 +13,16 @@ module.exports = function createEnforce(deps) {
13
13
  const MAX_COMMAND_FAILURES = 3;
14
14
  const MAX_TRACKED_SESSIONS = 8;
15
15
  const DENIAL_LOG_LIMIT = 50;
16
- // Conservative token estimate for a denied loop retry (one round of
17
- // command output that never entered context).
16
+ // Tokens a denied retry keeps out of context. A repeated quiet command saves
17
+ // little; a repeated noisy one (tests, builds, installs) would have dumped a
18
+ // full round of output, so it saves far more.
18
19
  const LOOP_DENY_TOKEN_ESTIMATE = 2000;
20
+ const NOISY_LOOP_TOKEN_ESTIMATE = 12000;
21
+ const NOISY_LOOP_RE = /\b(test|jest|vitest|pytest|build|webpack|vite|tsc|install|lint|eslint|playwright|cypress|coverage)\b/i;
22
+
23
+ function loopTokenEstimate(command) {
24
+ return NOISY_LOOP_RE.test(String(command || "")) ? NOISY_LOOP_TOKEN_ESTIMATE : LOOP_DENY_TOKEN_ESTIMATE;
25
+ }
19
26
 
20
27
  function blockedContextPath(root) {
21
28
  return path.join(root, ".prismo", "blocked-context.txt");
@@ -106,7 +113,7 @@ module.exports = function createEnforce(deps) {
106
113
  reason,
107
114
  failures: payload.failures || 0,
108
115
  attempts: payload.attempts || 0,
109
- estimatedTokensSaved: LOOP_DENY_TOKEN_ESTIMATE,
116
+ estimatedTokensSaved: Number(payload.estimatedTokensSaved) || LOOP_DENY_TOKEN_ESTIMATE,
110
117
  sessionId,
111
118
  }, ...loopStops].slice(0, DENIAL_LOG_LIMIT);
112
119
  writeState(root, state);
@@ -232,10 +239,12 @@ module.exports = function createEnforce(deps) {
232
239
  const deniedByFailures = !record.succeeded && record.outcomes > 0 && record.failures >= MAX_COMMAND_FAILURES;
233
240
  const deniedByAttempts = record.outcomes === 0 && record.attempts >= MAX_IDENTICAL_COMMANDS;
234
241
  if (deniedByFailures || deniedByAttempts) {
235
- recordDenial(root, state, "loop", command, LOOP_DENY_TOKEN_ESTIMATE);
242
+ const loopTokens = loopTokenEstimate(command);
243
+ recordDenial(root, state, "loop", command, loopTokens);
236
244
  recordLoopStop(root, state, {
237
245
  command,
238
246
  sessionId,
247
+ estimatedTokensSaved: loopTokens,
239
248
  reason: deniedByFailures ? "repeated-failing-command" : "repeated-identical-command",
240
249
  failures: record.failures,
241
250
  attempts: record.attempts,
@@ -383,6 +383,7 @@ const {
383
383
  const {
384
384
  renderAgentTerminal,
385
385
  runAgent,
386
+ registerSelfRepair,
386
387
  VALID_MODES: AGENT_VALID_MODES,
387
388
  } = require("./prismo-dev/agent")({
388
389
  fs,
@@ -479,6 +480,7 @@ const { runCli } = require("./prismo-dev/cli")({
479
480
  NPX_COMMAND,
480
481
  DEFAULT_PRISMO_PROXY_URL,
481
482
  AGENT_VALID_MODES,
483
+ registerSelfRepair,
482
484
  openUrl,
483
485
  printStep,
484
486
  getPositionals,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "getprismo",
3
- "version": "0.1.57",
3
+ "version": "0.1.59",
4
4
  "description": "Local AI coding workflow scanner for Codex, Claude Code, Cursor, and token-waste diagnostics.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/shanirsh/prismodev#readme",