openpitstop 1.9.0 → 1.10.0

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.
Files changed (105) hide show
  1. package/PRIVACY.md +77 -90
  2. package/README.md +365 -887
  3. package/dist/agentBudget.d.ts +33 -0
  4. package/dist/agentBudget.js +165 -0
  5. package/dist/agentBudget.js.map +1 -0
  6. package/dist/analyzers/ledger/index.d.ts +2 -1
  7. package/dist/analyzers/ledger/index.js +10 -1
  8. package/dist/analyzers/ledger/index.js.map +1 -1
  9. package/dist/analyzers/types.d.ts +2 -0
  10. package/dist/candidate.d.ts +20 -0
  11. package/dist/candidate.js +87 -0
  12. package/dist/candidate.js.map +1 -0
  13. package/dist/cli.js +1 -1
  14. package/dist/cli.js.map +1 -1
  15. package/dist/commands/ask.d.ts +0 -8
  16. package/dist/commands/ask.js +36 -34
  17. package/dist/commands/ask.js.map +1 -1
  18. package/dist/commands/budget.d.ts +1 -0
  19. package/dist/commands/budget.js +12 -3
  20. package/dist/commands/budget.js.map +1 -1
  21. package/dist/commands/drive.js +77 -51
  22. package/dist/commands/drive.js.map +1 -1
  23. package/dist/commands/fix.d.ts +7 -0
  24. package/dist/commands/fix.js +90 -108
  25. package/dist/commands/fix.js.map +1 -1
  26. package/dist/commands/gate.js +6 -2
  27. package/dist/commands/gate.js.map +1 -1
  28. package/dist/commands/pen.d.ts +3 -1
  29. package/dist/commands/pen.js +31 -42
  30. package/dist/commands/pen.js.map +1 -1
  31. package/dist/commands/readyCheck.d.ts +1 -1
  32. package/dist/commands/readyCheck.js +6 -36
  33. package/dist/commands/readyCheck.js.map +1 -1
  34. package/dist/commands/scan.d.ts +6 -5
  35. package/dist/commands/scan.js +26 -28
  36. package/dist/commands/scan.js.map +1 -1
  37. package/dist/commands/verify.d.ts +3 -1
  38. package/dist/commands/verify.js +5 -1
  39. package/dist/commands/verify.js.map +1 -1
  40. package/dist/evidence.js +4 -0
  41. package/dist/evidence.js.map +1 -1
  42. package/dist/installer/targets.js +1 -1
  43. package/dist/installer/targets.js.map +1 -1
  44. package/dist/intent.d.ts +4 -7
  45. package/dist/intent.js +41 -77
  46. package/dist/intent.js.map +1 -1
  47. package/dist/pen/dynamic.d.ts +1 -24
  48. package/dist/pen/dynamic.js +10 -1
  49. package/dist/pen/dynamic.js.map +1 -1
  50. package/dist/pen/fix.js +5 -1
  51. package/dist/pen/fix.js.map +1 -1
  52. package/dist/repro/generate.js +1 -0
  53. package/dist/repro/generate.js.map +1 -1
  54. package/dist/repro/pen.js +1 -0
  55. package/dist/repro/pen.js.map +1 -1
  56. package/dist/repro/run.d.ts +1 -0
  57. package/dist/repro/run.js +17 -1
  58. package/dist/repro/run.js.map +1 -1
  59. package/dist/sandbox/container.d.ts +9 -0
  60. package/dist/sandbox/container.js +129 -0
  61. package/dist/sandbox/container.js.map +1 -0
  62. package/dist/sandbox/worker.d.ts +1 -0
  63. package/dist/sandbox/worker.js +41 -0
  64. package/dist/sandbox/worker.js.map +1 -0
  65. package/dist/scanCache.d.ts +27 -0
  66. package/dist/scanCache.js +89 -0
  67. package/dist/scanCache.js.map +1 -0
  68. package/dist/verify/acceptance.d.ts +5 -1
  69. package/dist/verify/acceptance.js +29 -16
  70. package/dist/verify/acceptance.js.map +1 -1
  71. package/dist/verify/architecture.d.ts +5 -1
  72. package/dist/verify/architecture.js +6 -1
  73. package/dist/verify/architecture.js.map +1 -1
  74. package/dist/verify/baseline.d.ts +5 -1
  75. package/dist/verify/baseline.js +5 -1
  76. package/dist/verify/baseline.js.map +1 -1
  77. package/dist/verify/chain.js +17 -0
  78. package/dist/verify/chain.js.map +1 -1
  79. package/dist/verify/flow.d.ts +2 -0
  80. package/dist/verify/flow.js +18 -3
  81. package/dist/verify/flow.js.map +1 -1
  82. package/dist/verify/gateMatrix.d.ts +4 -0
  83. package/dist/verify/gateMatrix.js +23 -12
  84. package/dist/verify/gateMatrix.js.map +1 -1
  85. package/dist/verify/holdout.d.ts +5 -1
  86. package/dist/verify/holdout.js +8 -2
  87. package/dist/verify/holdout.js.map +1 -1
  88. package/dist/verify/regression.d.ts +5 -1
  89. package/dist/verify/regression.js +6 -1
  90. package/dist/verify/regression.js.map +1 -1
  91. package/dist/verify/stack.d.ts +5 -1
  92. package/dist/verify/stack.js +6 -1
  93. package/dist/verify/stack.js.map +1 -1
  94. package/dist/verify/state.d.ts +5 -1
  95. package/dist/verify/state.js +6 -1
  96. package/dist/verify/state.js.map +1 -1
  97. package/dist/verify/verifier.d.ts +5 -1
  98. package/dist/verify/verifier.js +6 -1
  99. package/dist/verify/verifier.js.map +1 -1
  100. package/docs/release-controls.md +107 -0
  101. package/package.json +70 -69
  102. package/templates/pitstop.command.md +17 -5
  103. package/templates/pitstop.prompt.md +390 -390
  104. package/scripts/__pycache__/gen-gifs.cpython-313.pyc +0 -0
  105. package/scripts/gen-gifs.py +0 -231
@@ -0,0 +1,33 @@
1
+ export interface AgentLimits {
2
+ maxCalls: number;
3
+ maxSeconds: number;
4
+ maxPromptChars: number;
5
+ maxCostUsd?: number;
6
+ }
7
+ export declare const DEFAULT_AGENT_LIMITS: AgentLimits;
8
+ export declare function positiveLimit(value: string | number, name: string, integer?: boolean): number;
9
+ /** Parse quoted argv; never interpret shell syntax or split the substituted prompt. */
10
+ export declare function agentArgv(command: string, prompt: string): string[];
11
+ /** One shared allowance for ALL findings/rounds in a drive session. Reservations
12
+ * happen before launch, including unsuccessful launches; they are never refunded. */
13
+ export declare class AgentBudget {
14
+ readonly repo: string;
15
+ readonly limits: AgentLimits;
16
+ private now;
17
+ readonly id: `${string}-${string}-${string}-${string}-${string}`;
18
+ readonly startedAt: number;
19
+ calls: number;
20
+ promptChars: number;
21
+ allocatedUsd: number;
22
+ private lock?;
23
+ constructor(repo: string, limits: AgentLimits, now?: () => number);
24
+ remainingMs(): number;
25
+ acquire(): void;
26
+ release(): void;
27
+ reserve(command: string, prompt: string): {
28
+ argv: string[];
29
+ timeoutMs: number;
30
+ };
31
+ private save;
32
+ }
33
+ export declare function runBudgetedAgent(repo: string, command: string, prompt: string, budget: AgentBudget): Promise<number>;
@@ -0,0 +1,165 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { randomUUID } from "node:crypto";
4
+ import { execa } from "execa";
5
+ export const DEFAULT_AGENT_LIMITS = { maxCalls: 3, maxSeconds: 600, maxPromptChars: 48000 };
6
+ export function positiveLimit(value, name, integer = true) {
7
+ const n = Number(value);
8
+ if (!Number.isFinite(n) || n <= 0 || (integer && !Number.isSafeInteger(n)))
9
+ throw new Error(`${name} must be a positive ${integer ? "integer" : "number"}`);
10
+ return n;
11
+ }
12
+ /** Parse quoted argv; never interpret shell syntax or split the substituted prompt. */
13
+ export function agentArgv(command, prompt) {
14
+ const args = [];
15
+ let token = "", quote = "", started = false;
16
+ for (const ch of command) {
17
+ if (quote) {
18
+ if (ch === quote)
19
+ quote = "";
20
+ else
21
+ token += ch;
22
+ started = true;
23
+ }
24
+ else if (ch === '"' || ch === "'") {
25
+ quote = ch;
26
+ started = true;
27
+ }
28
+ else if (/\s/.test(ch)) {
29
+ if (started) {
30
+ args.push(token);
31
+ token = "";
32
+ started = false;
33
+ }
34
+ }
35
+ else {
36
+ token += ch;
37
+ started = true;
38
+ }
39
+ }
40
+ if (quote)
41
+ throw new Error("agent command contains an unclosed quote");
42
+ if (started)
43
+ args.push(token);
44
+ if (!args[0] || args[0].includes("{prompt}") || args.filter(a => a.includes("{prompt}")).length !== 1)
45
+ throw new Error("agent command must contain exactly one {prompt} argument");
46
+ return args.map(a => a.replace("{prompt}", prompt));
47
+ }
48
+ /** One shared allowance for ALL findings/rounds in a drive session. Reservations
49
+ * happen before launch, including unsuccessful launches; they are never refunded. */
50
+ export class AgentBudget {
51
+ repo;
52
+ limits;
53
+ now;
54
+ id = randomUUID();
55
+ startedAt;
56
+ calls = 0;
57
+ promptChars = 0;
58
+ allocatedUsd = 0;
59
+ lock;
60
+ constructor(repo, limits, now = Date.now) {
61
+ this.repo = repo;
62
+ this.limits = limits;
63
+ this.now = now;
64
+ for (const [name, value] of Object.entries(limits))
65
+ if (value !== undefined)
66
+ positiveLimit(value, name, name !== "maxCostUsd");
67
+ this.startedAt = now();
68
+ }
69
+ remainingMs() { return Math.max(0, this.limits.maxSeconds * 1000 - (this.now() - this.startedAt)); }
70
+ acquire() {
71
+ if (process.env.PITSTOP_DRIVE_ACTIVE)
72
+ throw new Error("nested drive is refused: the parent agent already has a shared budget");
73
+ fs.mkdirSync(path.join(this.repo, ".pitstop"), { recursive: true });
74
+ try {
75
+ this.lock = fs.openSync(path.join(this.repo, ".pitstop", "drive.lock"), "wx");
76
+ }
77
+ catch {
78
+ throw new Error("another drive session holds .pitstop/drive.lock; inspect it before removing a stale lock");
79
+ }
80
+ fs.writeFileSync(this.lock, JSON.stringify({ id: this.id, pid: process.pid, startedAt: this.startedAt }));
81
+ this.save();
82
+ }
83
+ release() {
84
+ if (this.lock === undefined)
85
+ return;
86
+ this.save();
87
+ fs.closeSync(this.lock);
88
+ this.lock = undefined;
89
+ fs.unlinkSync(path.join(this.repo, ".pitstop", "drive.lock"));
90
+ }
91
+ reserve(command, prompt) {
92
+ const argv = agentArgv(command, prompt);
93
+ if (this.calls >= this.limits.maxCalls)
94
+ throw new Error("global agent call limit reached");
95
+ const timeoutMs = this.remainingMs();
96
+ if (!timeoutMs)
97
+ throw new Error("global agent time limit reached");
98
+ if (this.promptChars + prompt.length > this.limits.maxPromptChars)
99
+ throw new Error("global agent prompt allowance exhausted");
100
+ if (this.limits.maxCostUsd !== undefined) {
101
+ const bin = path.basename(argv[0]).replace(/\.(exe|cmd)$/i, "").toLowerCase();
102
+ if (bin !== "claude" || !argv.some(a => a === "-p" || a === "--print"))
103
+ throw new Error("a dollar ceiling currently requires Claude CLI print mode; this provider cannot enforce it, so no agent was started");
104
+ if (argv.some(a => a.startsWith("--max-budget-usd")))
105
+ throw new Error("set the dollar ceiling with Pitstop --max-cost-usd, not duplicate agent flags");
106
+ const allocation = Math.floor(this.limits.maxCostUsd * 1e6 / this.limits.maxCalls) / 1e6;
107
+ if (allocation <= 0)
108
+ throw new Error("dollar ceiling is too small for this call allowance");
109
+ argv.splice(1, 0, "--max-budget-usd", String(allocation));
110
+ this.allocatedUsd += allocation;
111
+ }
112
+ this.calls++;
113
+ this.promptChars += prompt.length;
114
+ this.save();
115
+ return { argv, timeoutMs };
116
+ }
117
+ save() {
118
+ if (this.lock === undefined)
119
+ return;
120
+ const usage = { id: this.id, startedAt: new Date(this.startedAt).toISOString(), limits: this.limits,
121
+ calls: this.calls, promptChars: this.promptChars, elapsedMs: this.now() - this.startedAt,
122
+ allocatedUsd: this.allocatedUsd, actualCostUsd: null, actualTokens: null };
123
+ const dir = path.join(this.repo, ".pitstop");
124
+ const tmp = path.join(dir, `agent-budget-${this.id}.tmp`);
125
+ fs.writeFileSync(tmp, JSON.stringify(usage, null, 2));
126
+ fs.renameSync(tmp, path.join(dir, "agent-budget-latest.json"));
127
+ }
128
+ }
129
+ export async function runBudgetedAgent(repo, command, prompt, budget) {
130
+ const { argv: [bin, ...args], timeoutMs } = budget.reserve(command, prompt);
131
+ if (budget.limits.maxCostUsd !== undefined) {
132
+ const version = await execa(bin, ["--version"], { timeout: Math.min(timeoutMs, 5000), windowsHide: true });
133
+ const match = version.stdout.match(/\b(\d+)\.(\d+)\.(\d+)\b/);
134
+ const parts = match?.slice(1).map(Number);
135
+ if (!parts || !(parts[0] > 2 || (parts[0] === 2 && (parts[1] > 1 || (parts[1] === 1 && parts[2] >= 217)))))
136
+ throw new Error("dollar ceilings require Claude CLI 2.1.217 or later for subagent budget enforcement");
137
+ }
138
+ if (!budget.remainingMs())
139
+ throw new Error("global agent time limit reached");
140
+ const child = execa(bin, args, { cwd: repo, stdio: "inherit", reject: false, windowsHide: true,
141
+ detached: process.platform !== "win32", env: { PITSTOP_DRIVE_ACTIVE: budget.id } });
142
+ let timedOut = false;
143
+ const kill = async () => {
144
+ if (!child.pid)
145
+ return;
146
+ if (process.platform === "win32")
147
+ await execa("taskkill", ["/pid", String(child.pid), "/T", "/F"], { reject: false, windowsHide: true }).catch(() => { });
148
+ else {
149
+ try {
150
+ process.kill(-child.pid, "SIGKILL");
151
+ }
152
+ catch { }
153
+ }
154
+ };
155
+ const timer = setTimeout(() => { timedOut = true; void kill(); }, Math.min(timeoutMs, budget.remainingMs()));
156
+ try {
157
+ const result = await child;
158
+ return timedOut ? -1 : result.exitCode ?? -1;
159
+ }
160
+ finally {
161
+ clearTimeout(timer);
162
+ await kill();
163
+ }
164
+ }
165
+ //# sourceMappingURL=agentBudget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agentBudget.js","sourceRoot":"","sources":["../src/agentBudget.ts"],"names":[],"mappings":"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"}
@@ -8,7 +8,8 @@ import type { LedgerResult } from "../types.js";
8
8
  * it can leave the process; the request/response pairs the "gateway" receives
9
9
  * are recorded so evidence of a double-charge is real, not simulated.
10
10
  */
11
- export declare function runLedgerAnalyzer(repo: string): Promise<LedgerResult>;
11
+ export declare function runLedgerLocal(repo: string): Promise<LedgerResult>;
12
12
  export { discover } from "./discover.js";
13
13
  export { runAttacks } from "./attacks.js";
14
14
  export { analyzeEvidence } from "./evidence.js";
15
+ export declare function runLedgerAnalyzer(repo: string): Promise<LedgerResult>;
@@ -1,3 +1,4 @@
1
+ import { runIsolated } from "../../sandbox/container.js";
1
2
  import { discover } from "./discover.js";
2
3
  import { startHarness, newEvidencePath, readAbortReason, } from "./harness.js";
3
4
  import { runAttacks } from "./attacks.js";
@@ -11,7 +12,7 @@ import { analyzeEvidence, writeEvidenceFile, } from "./evidence.js";
11
12
  * it can leave the process; the request/response pairs the "gateway" receives
12
13
  * are recorded so evidence of a double-charge is real, not simulated.
13
14
  */
14
- export async function runLedgerAnalyzer(repo) {
15
+ export async function runLedgerLocal(repo) {
15
16
  const ts = new Date().toISOString().replace(/[:.]/g, "-");
16
17
  let discovery;
17
18
  try {
@@ -113,4 +114,12 @@ export async function runLedgerAnalyzer(repo) {
113
114
  export { discover } from "./discover.js";
114
115
  export { runAttacks } from "./attacks.js";
115
116
  export { analyzeEvidence } from "./evidence.js";
117
+ export async function runLedgerAnalyzer(repo) {
118
+ try {
119
+ return await runIsolated(repo, "ledger");
120
+ }
121
+ catch (error) {
122
+ return { status: "aborted", note: String(error), endpoints: [], evidence: [] };
123
+ }
124
+ }
116
125
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/analyzers/ledger/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/analyzers/ledger/index.ts"],"names":[],"mappings":"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"}
@@ -188,6 +188,8 @@ export interface Cluster {
188
188
  size: number;
189
189
  }
190
190
  export interface ScanResult {
191
+ /** Content-bound reuse metadata, present only for a stable full scan. */
192
+ cache?: import("../scanCache.js").ScanCache;
191
193
  timestamp: string;
192
194
  repo: string;
193
195
  /** `try` was produced by the quick `pitstop try` pass (tests/perf/reliability intentionally skipped). */
@@ -0,0 +1,20 @@
1
+ export interface CandidateBinding {
2
+ schema: 1;
3
+ repo: string;
4
+ digest: string;
5
+ head: string | null;
6
+ clean: boolean;
7
+ engine: string;
8
+ policy: string;
9
+ }
10
+ /** No source or secret contents are stored in evidence, only content digests. */
11
+ export declare function captureCandidate(repo: string): CandidateBinding | null;
12
+ export declare function activeCandidate(): CandidateBinding | null | undefined;
13
+ /** Capture BEFORE execution, including async work and early-return evidence. */
14
+ export declare function candidateRun<T extends object>(repo: string, run: () => Promise<T>): Promise<T & {
15
+ candidateBinding: CandidateBinding | null;
16
+ }>;
17
+ export declare function candidateRunSync<T extends object>(repo: string, run: () => T): T & {
18
+ candidateBinding: CandidateBinding | null;
19
+ };
20
+ export declare function candidateMismatch(repo: string, doc: any, current?: CandidateBinding | null): string | null;
@@ -0,0 +1,87 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { AsyncLocalStorage } from "node:async_hooks";
4
+ import { execFileSync } from "node:child_process";
5
+ import { createHash } from "node:crypto";
6
+ import { fileURLToPath } from "node:url";
7
+ import { hashSuiteFiles } from "./verify/holdout.js";
8
+ import { snapshotRepo } from "./scanCache.js";
9
+ const context = new AsyncLocalStorage();
10
+ const hash = (value) => createHash("sha256").update(JSON.stringify(value)).digest("hex");
11
+ const policies = ["architecture.json", "plan-latest.json", "acceptance-pin.json"];
12
+ function engineIdentity() {
13
+ const root = path.dirname(fileURLToPath(import.meta.url));
14
+ const files = [];
15
+ const walk = (dir) => {
16
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
17
+ const p = path.join(dir, entry.name);
18
+ if (entry.isDirectory())
19
+ walk(p);
20
+ else if (/\.(ts|js|json|cjs)$/.test(entry.name))
21
+ files.push([path.relative(root, p), hash(fs.readFileSync(p).toString("base64"))]);
22
+ }
23
+ };
24
+ walk(root);
25
+ walk(path.join(root, "../templates"));
26
+ return hash([files, fs.readFileSync(path.join(root, "../package.json"), "utf8"), process.version, process.platform]);
27
+ }
28
+ /** No source or secret contents are stored in evidence, only content digests. */
29
+ export function captureCandidate(repo) {
30
+ try {
31
+ repo = fs.realpathSync(repo);
32
+ const snapshot = snapshotRepo(repo);
33
+ if (!snapshot)
34
+ return null;
35
+ const policy = policies.map(name => {
36
+ const p = path.join(repo, ".pitstop", name);
37
+ if (!fs.existsSync(p))
38
+ return [name, null];
39
+ if (fs.lstatSync(p).isSymbolicLink())
40
+ throw new Error("policy symlink");
41
+ return [name, hash(fs.readFileSync(p).toString("base64"))];
42
+ });
43
+ let clean = false;
44
+ if (snapshot.head) {
45
+ const status = execFileSync("git", ["status", "--porcelain", "--untracked-files=all", "--", ".", ":(exclude).pitstop", ":(exclude)PITSTOP_*.md", ":(exclude)PITSTOP_*.html", ":(exclude)PITSTOP_*.svg"], { cwd: repo, encoding: "utf8", timeout: 5000, windowsHide: true, stdio: ["ignore", "pipe", "ignore"] });
46
+ clean = !status.trim();
47
+ }
48
+ const env = Object.entries(process.env).filter(([k]) => k.startsWith("PITSTOP_") || ["NODE_OPTIONS", "NODE_ENV"].includes(k)).sort();
49
+ return { schema: 1, repo, digest: snapshot.digest, head: snapshot.head, clean, engine: engineIdentity(), policy: hash([policy, env]) };
50
+ }
51
+ catch {
52
+ return null;
53
+ }
54
+ }
55
+ export function activeCandidate() { return context.getStore(); }
56
+ /** Capture BEFORE execution, including async work and early-return evidence. */
57
+ export async function candidateRun(repo, run) {
58
+ const binding = captureCandidate(repo);
59
+ return context.run(binding, async () => ({ ...await run(), candidateBinding: binding }));
60
+ }
61
+ export function candidateRunSync(repo, run) {
62
+ const binding = captureCandidate(repo);
63
+ return context.run(binding, () => ({ ...run(), candidateBinding: binding }));
64
+ }
65
+ export function candidateMismatch(repo, doc, current = captureCandidate(repo)) {
66
+ const binding = doc?.candidateBinding;
67
+ if (!binding || binding.schema !== 1)
68
+ return "evidence has no candidate binding; rerun this check";
69
+ if (!current)
70
+ return "current candidate cannot be fingerprinted safely";
71
+ if (JSON.stringify(binding) !== JSON.stringify(current))
72
+ return "repository, Git state, policy or verification engine changed; rerun this check";
73
+ try {
74
+ if (doc.contract?.path && createHash("sha256").update(fs.readFileSync(doc.contract.path, "utf8")).digest("hex") !== doc.contract.hash)
75
+ return "acceptance contract changed; rerun acceptance verification";
76
+ if (doc.suite?.dir && hashSuiteFiles(doc.suite.dir).hash !== doc.suite.hash)
77
+ return "holdout suite changed; rerun holdout verification";
78
+ }
79
+ catch {
80
+ return "external verification input is unavailable";
81
+ }
82
+ const sha = doc?.candidate?.commitSha ?? doc?.candidate?.sha ?? doc?.candidateSha;
83
+ if (sha && (sha !== current.head || !current.clean))
84
+ return "check ran on a commit that does not represent the current clean candidate";
85
+ return null;
86
+ }
87
+ //# sourceMappingURL=candidate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"candidate.js","sourceRoot":"","sources":["../src/candidate.ts"],"names":[],"mappings":"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"}
package/dist/cli.js CHANGED
@@ -82,7 +82,7 @@ function readVersion() {
82
82
  const program = new Command();
83
83
  program
84
84
  .name("pitstop")
85
- .description("OpenPitStop CLI")
85
+ .description('Repo-aware engineering for coding CLIs. Start with: pitstop ask "understand this repo"')
86
86
  .version(readVersion())
87
87
  .action(guidedFirstRun);
88
88
  program.addCommand(install);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,3 @@
1
1
  import { Command } from "commander";
2
- /**
3
- * `pitstop ask` — natural-language entry point. Tell it what you want in plain
4
- * English ("make this safe", "why is my score low") and it resolves to the
5
- * exact `pitstop` command, then prints a copy-paste block to run it.
6
- *
7
- * The slash-command templates route free-text `/pitstop <anything>` here so
8
- * users never need to remember command names.
9
- */
10
2
  export declare const askCmd: Command;
11
3
  export default askCmd;
@@ -1,48 +1,50 @@
1
1
  import { Command } from "commander";
2
2
  import chalk from "chalk";
3
3
  import boxen from "boxen";
4
- import { matchIntent } from "../intent.js";
5
- import { brandHeader } from "../brand.js";
6
- /**
7
- * `pitstop ask` — natural-language entry point. Tell it what you want in plain
8
- * English ("make this safe", "why is my score low") and it resolves to the
9
- * exact `pitstop` command, then prints a copy-paste block to run it.
10
- *
11
- * The slash-command templates route free-text `/pitstop <anything>` here so
12
- * users never need to remember command names.
13
- */
4
+ import path from "node:path";
5
+ import { fileURLToPath } from "node:url";
6
+ import { execa } from "execa";
7
+ import { matchIntent, INTENT_EXAMPLES } from "../intent.js";
14
8
  export const askCmd = new Command("ask")
15
- .description("Natural-language router: resolve a plain-English request to the right pitstop command. " +
16
- 'e.g. `pitstop ask "make this safe"` → `pitstop fix`.')
9
+ .description("Tell PitStop what to do in plain English. Local routing, no model credits. Checks run immediately; writes/live attacks need --execute.")
17
10
  .argument("<text...>", "what you want, in plain English")
18
- .option("--json", "print machine-readable JSON")
19
- .action((textArg, options) => {
11
+ .option("--repo <path>", "repository to work in", ".")
12
+ .option("--dry-run", "preview the command and its effects without running it")
13
+ .option("--execute", "allow the resolved write, live attack, installation or paid agent action")
14
+ .option("--json", "preview the routing decision as JSON (does not execute)")
15
+ .action(async (textArg, options) => {
20
16
  const text = textArg.join(" ");
21
- const match = matchIntent(text);
17
+ const resolved = matchIntent(text);
18
+ const repo = path.resolve(options.repo);
19
+ const needsExecution = !!resolved?.requiresExecution && !options.execute;
22
20
  if (options.json) {
23
- console.log(JSON.stringify({ text, ...(match ?? { command: null, label: null }) }, null, 2));
21
+ console.log(JSON.stringify({ text, repo, ...(resolved ?? { command: null, label: null }),
22
+ needsExecution, executes: false, modelCalls: 0 }, null, 2));
23
+ if (!resolved)
24
+ process.exitCode = 2;
24
25
  return;
25
26
  }
26
- console.log(brandHeader());
27
- if (!match) {
28
- console.log(boxen(chalk.yellow("I couldn't map that to a command yet.\n\n") +
29
- chalk.dim("Try one of: ") +
30
- "\n " +
31
- chalk.cyan("pitstop ask \"make this safe\"") +
32
- "\n " +
33
- chalk.cyan("pitstop ask \"why is my score low\"") +
34
- "\n " +
35
- chalk.cyan("pitstop ask \"what's next\"") +
36
- "\n " +
37
- chalk.cyan("pitstop ask \"is it verified\"") +
38
- "\n " +
39
- chalk.cyan("pitstop menu") +
40
- " — see every action", { title: " PITSTOP — Ask ", titleAlignment: "center", borderStyle: "round", padding: 1, borderColor: "yellow" }));
27
+ if (!resolved) {
28
+ console.log(chalk.yellow("I couldn't safely resolve that request. Nothing ran. Try one action at a time:"));
29
+ console.log(INTENT_EXAMPLES.slice(0, 6).map((e) => ` pitstop ask "${e.phrase}"`).join("\n"));
30
+ process.exitCode = 2;
41
31
  return;
42
32
  }
43
- console.log(boxen(`${chalk.bold("Understood: ")}${match.label}\n\n` +
44
- `${chalk.bold("Run:")} ${chalk.cyan(match.command)}\n`, { title: " PITSTOP — Ask ", titleAlignment: "center", borderStyle: "round", padding: 1, borderColor: "green" }));
45
- console.log(chalk.dim("Run it:") + "\n```bash\n" + match.command + "\n```");
33
+ console.log(boxen(`${chalk.bold(resolved.label)}\n${chalk.cyan(resolved.command)}\n\n${resolved.effect}\nLocal routing · 0 model calls`, { title: " PITSTOP — Ask ", borderStyle: "round", padding: 1, borderColor: "cyan" }));
34
+ if (options.dryRun)
35
+ return;
36
+ if (needsExecution) {
37
+ console.log("Preview only. Add --execute to this request to run the action above.");
38
+ process.exitCode = 2;
39
+ return;
40
+ }
41
+ // Fixed argv from the router; never execute natural language through a shell.
42
+ const extension = path.extname(fileURLToPath(import.meta.url));
43
+ const cli = fileURLToPath(new URL(`../cli${extension}`, import.meta.url));
44
+ const result = await execa(process.execPath, [...process.execArgv, cli, ...resolved.args], {
45
+ cwd: repo, stdio: "inherit", reject: false, windowsHide: true,
46
+ });
47
+ process.exitCode = result.exitCode ?? 1;
46
48
  });
47
49
  export default askCmd;
48
50
  //# sourceMappingURL=ask.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ask.js","sourceRoot":"","sources":["../../src/commands/ask.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,OAAO,CAAC,KAAK,CAAC;KACrC,WAAW,CACV,yFAAyF;IACvF,sDAAsD,CACzD;KACA,QAAQ,CAAC,WAAW,EAAE,iCAAiC,CAAC;KACxD,MAAM,CAAC,QAAQ,EAAE,6BAA6B,CAAC;KAC/C,MAAM,CAAC,CAAC,OAAiB,EAAE,OAA2B,EAAE,EAAE;IACzD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/B,MAAM,KAAK,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IAEhC,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,KAAK,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7F,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;IAC3B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,CACT,KAAK,CACH,KAAK,CAAC,MAAM,CAAC,2CAA2C,CAAC;YACvD,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC;YACzB,MAAM;YACN,KAAK,CAAC,IAAI,CAAC,gCAAgC,CAAC;YAC5C,MAAM;YACN,KAAK,CAAC,IAAI,CAAC,qCAAqC,CAAC;YACjD,MAAM;YACN,KAAK,CAAC,IAAI,CAAC,6BAA6B,CAAC;YACzC,MAAM;YACN,KAAK,CAAC,IAAI,CAAC,gCAAgC,CAAC;YAC5C,MAAM;YACN,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC;YAC1B,qBAAqB,EACvB,EAAE,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,WAAW,EAAE,QAAQ,EAAE,CAChH,CACF,CAAC;QACF,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CACT,KAAK,CACH,GAAG,KAAK,CAAC,IAAI,CAAC,cAAc,CAAC,GAAG,KAAK,CAAC,KAAK,MAAM;QAC/C,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,EACxD,EAAE,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,WAAW,EAAE,OAAO,EAAE,CAC/G,CACF,CAAC;IACF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,aAAa,GAAG,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC,CAAC;AAC9E,CAAC,CAAC,CAAC;AAEL,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"ask.js","sourceRoot":"","sources":["../../src/commands/ask.ts"],"names":[],"mappings":"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"}
@@ -27,6 +27,7 @@ interface BudgetEntry {
27
27
  auditCacheHits: number;
28
28
  totalComputeSeconds: number;
29
29
  loopRuns: number;
30
+ agentSession: Record<string, unknown> | null;
30
31
  }
31
32
  export declare function budget(repo: string): BudgetEntry;
32
33
  export declare const budgetCmd: Command;
@@ -11,7 +11,7 @@ function history(repo, glob) {
11
11
  const re = new RegExp(`^${glob}$`);
12
12
  const out = [];
13
13
  for (const f of fs.readdirSync(dir)) {
14
- if (!re.test(f))
14
+ if (!re.test(f) || f.endsWith("-latest.json"))
15
15
  continue;
16
16
  try {
17
17
  const data = JSON.parse(fs.readFileSync(path.join(dir, f), "utf8"));
@@ -59,6 +59,12 @@ export function budget(repo) {
59
59
  auditCacheHits,
60
60
  totalComputeSeconds,
61
61
  loopRuns: verifies.length,
62
+ agentSession: (() => { try {
63
+ return JSON.parse(fs.readFileSync(path.join(repo, ".pitstop", "agent-budget-latest.json"), "utf8"));
64
+ }
65
+ catch {
66
+ return null;
67
+ } })(),
62
68
  };
63
69
  }
64
70
  export const budgetCmd = new Command("budget")
@@ -75,13 +81,15 @@ export const budgetCmd = new Command("budget")
75
81
  console.log(JSON.stringify({ repo, ...b, readyCheck: rc }, null, 2));
76
82
  return;
77
83
  }
84
+ if (b.agentSession)
85
+ console.log(`Agent session: ${b.agentSession.calls} launches · ${b.agentSession.promptChars} prompt characters · actual provider cost unavailable`);
78
86
  const fmtMs = (ms) => (ms >= 1000 ? `${(ms / 1000).toFixed(1)}s` : `${ms}ms`);
79
87
  const lines = [];
80
88
  lines.push(`${chalk.bold("Full scans")}: ${b.scans.count} (reliability runs: ${b.scans.reliabilityRuns} · tests: ${fmtMs(b.scans.testMs)} · builds: ${fmtMs(b.scans.buildMs)})`);
81
89
  lines.push(`${chalk.bold("Verify runs")}: ${b.verifies.count} (last ${b.verifies.last})`);
82
90
  lines.push(`${chalk.bold("Pen tests")}: ${b.pens.count} (last ${b.pens.last})`);
83
91
  lines.push(`${chalk.bold("Ledger boots")}: ${b.ledgerRuns}`);
84
- lines.push(`${chalk.bold("Audit cache files")}: ${b.auditCacheHits} (each = one npm-audit network round-trip saved)`);
92
+ lines.push(`${chalk.bold("Audit cache files")}: ${b.auditCacheHits} (stored entries, not measured cache hits)`);
85
93
  lines.push("");
86
94
  lines.push(`${chalk.bold("Wall-clock compute")}: ${fmtMs((b.scans.testMs + b.scans.buildMs))} spent on test/build runs (models cost tokens; machines cost seconds — this is the honest meter).`);
87
95
  lines.push("");
@@ -89,10 +97,11 @@ export const budgetCmd = new Command("budget")
89
97
  lines.push(chalk.green("The tree is unchanged since the last scan — the next loop iteration should have used `scan --reuse`."));
90
98
  }
91
99
  else {
92
- lines.push(chalk.yellow("The tree HAS changed since the last scan — a re-scan is legitimate spend."));
100
+ lines.push(chalk.yellow(`A fresh scan is needed: ${rc.staleReason ?? "inputs changed"}.`));
93
101
  }
94
102
  lines.push("");
95
103
  lines.push(chalk.cyan("Cut the burn:"));
104
+ lines.push(" Local routing and verification make no model calls; agent-provider token spend is not measured.");
96
105
  lines.push(` ready-check before every re-scan (exit 0 = reuse the baseline)`);
97
106
  lines.push(` scan --reuse inside the loop; full scan only at the end`);
98
107
  lines.push(` verify during iteration, full reliability runs only on the final pass`);