@varman96/paper 1.0.10 → 1.0.12

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 (3) hide show
  1. package/README.md +5 -1
  2. package/dist/paper.js +27 -25
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -112,6 +112,10 @@ Paper is used after a command has failed. `paper run <command>` executes the tar
112
112
 
113
113
  If the target succeeds, `.paper/incident_report.md` is unchanged. If it exits nonzero or is terminated by a signal, Paper traps that failure, captures the evidence locally, writes a structured Incident Report to `.paper/incident_report.md`, and prints `COMMAND FAILED`. The report contains the command, exit code, working directory, timestamp, and stderr or stack trace. Once the report is persisted, Paper exits successfully; Paper-owned failures, such as inability to update instructions or write the report, exit nonzero.
114
114
 
115
+ `.paper/latest.json` is the complete incident artifact: structured fields (command, args, exit code, signal, working directory, ISO timestamp, full stderr or its last 200KB with `"truncated": true`, and the last 50 lines of stdout) plus the full markdown report in the `"incident_report"` field. Any agent, script, or MCP can consume the failure from this one file without parsing prose.
116
+
117
+ The managed instruction directs agents to read `.paper/latest.json` when `COMMAND FAILED` appears, because their tool output may be truncated.
118
+
115
119
  The Paper instruction tells coding agents where to find the Incident Report, so an agent can investigate the failure without the user manually copying terminal output. Paper does not diagnose or fix the failure.
116
120
 
117
121
  Paper creates persistent local context and makes it discoverable to the agent. Its operation is local-only and air-gapped: there are no model API calls, telemetry, or command-output uploads.
@@ -124,7 +128,7 @@ Once the incident is resolved, remove it from the active workspace with:
124
128
  paper shelf
125
129
  ```
126
130
 
127
- Paper moves `.paper/incident_report.md` out of the repository with a rename and prints the stored path. On Windows, shelved reports are stored under `%LOCALAPPDATA%\Paper\shelf\<repository-hash>\`; on other platforms, under `$XDG_DATA_HOME/Paper/shelf/<repository-hash>/` or `~/.local/share/Paper/shelf/<repository-hash>/`. The report is preserved as a timestamped `.md` file under a repository-specific 16-character SHA-256 directory, but is no longer the active report. The active report is removed from `.paper`, its contents are preserved, and the instruction file is not changed. With no active report, or if the move fails, Paper exits nonzero; a failed move preserves the active report.
131
+ Paper moves `.paper/incident_report.md` out of the repository with a rename and prints the stored path. On Windows, shelved reports are stored under `%LOCALAPPDATA%\Paper\shelf\<repository-hash>\`; on other platforms, under `$XDG_DATA_HOME/Paper/shelf/<repository-hash>/` or `~/.local/share/Paper/shelf/<repository-hash>/`. The report is preserved as a timestamped `.md` file under a repository-specific 16-character SHA-256 directory, but is no longer the active report. The active report is removed from `.paper`, its contents are preserved, and the instruction file is not changed. `paper shelf` removes `.paper/latest.json` rather than archiving it: the shelf holds `.md` reports only, and a leftover JSON would describe the wrong incident. With no active report, or if the move fails, Paper exits nonzero; a failed move preserves the active report.
128
132
 
129
133
  ### Recovering a shelved incident
130
134
 
package/dist/paper.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import{spawn as B}from"node:child_process";import{createHash as Z}from"node:crypto";import{realpathSync as V,statSync as X}from"node:fs";import{lstat as q,mkdir as P,readFile as K,rename as Y,stat as F,writeFile as M}from"node:fs/promises";import{homedir as R,platform as O}from"node:os";import{basename as k,dirname as m,extname as J,join as a,resolve as y}from"node:path";import{fileURLToPath as Q}from"node:url";var I=[["1. Scope",[["what-failing","What is failing?"],["still-working","What is still working?"],["failure-breadth","How broad is the failure?"],["deterministic","Is it deterministic?"]]],["2. Delta",[["changed-recently","What changed recently?"],["did-not-change","What did not change?"],["git-runtime-environment-differences","Relevant git/runtime/environment differences"]]],["3. Failure Boundary",[["expected-at-boundary","Expected behavior at the boundary"],["observed-at-boundary","Observed behavior at the boundary"],["input-payload","Exact input/payload entering the boundary"],["output-error","Exact output/error leaving the boundary"]]],["4. Execution Path",[["origin","Origin"],["intermediate-components","Intermediate components"],["first-confirmed-divergence","First confirmed divergence"],["runtime-environment-hops","Runtime/environment at relevant hops"]]],["5. Evidence",[["exit-code","Exit code"],["stderr-stack-trace","stderr / stack trace"],["status-codes","Status codes"],["commands","Commands"],["changed-files","Changed files"],["git-diff-stat","git diff/stat"],["runtime-versions","Runtime versions"],["other-receipts","Other deterministic receipts"]]],["6. Falsified Hypotheses",[["hypothesis","Hypothesis"],["test-check","Test/check performed"],["result","Result"],["why-ruled-out","Why it is ruled out"]]],["7. Current Working Hypothesis",[["working-hypothesis","Hypothesis"],["supporting-evidence","Evidence supporting it"],["opposing-evidence","Evidence against it"]]],["8. Next Test",[["smallest-action","Smallest action to isolate or test next"]]]],Se=I.flatMap(([,e])=>e);function T(e={}){let t=I.flatMap(([n,r])=>{let s=r.flatMap(([o,i])=>{let c=String(e[o]??"").trim();return c?[`### ${i}
2
+ import{spawn as J}from"node:child_process";import{createHash as V}from"node:crypto";import{realpathSync as X,statSync as q}from"node:fs";import{lstat as Y,mkdir as x,readFile as K,rename as _,rm as Q,stat as W,writeFile as I}from"node:fs/promises";import{homedir as A,platform as H}from"node:os";import{basename as N,dirname as w,extname as ee,join as a,resolve as y}from"node:path";import{fileURLToPath as te}from"node:url";var $=[["1. Scope",[["what-failing","What is failing?"],["still-working","What is still working?"],["failure-breadth","How broad is the failure?"],["deterministic","Is it deterministic?"]]],["2. Delta",[["changed-recently","What changed recently?"],["did-not-change","What did not change?"],["git-runtime-environment-differences","Relevant git/runtime/environment differences"]]],["3. Failure Boundary",[["expected-at-boundary","Expected behavior at the boundary"],["observed-at-boundary","Observed behavior at the boundary"],["input-payload","Exact input/payload entering the boundary"],["output-error","Exact output/error leaving the boundary"]]],["4. Execution Path",[["origin","Origin"],["intermediate-components","Intermediate components"],["first-confirmed-divergence","First confirmed divergence"],["runtime-environment-hops","Runtime/environment at relevant hops"]]],["5. Evidence",[["exit-code","Exit code"],["stderr-stack-trace","stderr / stack trace"],["status-codes","Status codes"],["commands","Commands"],["changed-files","Changed files"],["git-diff-stat","git diff/stat"],["runtime-versions","Runtime versions"],["other-receipts","Other deterministic receipts"]]],["6. Falsified Hypotheses",[["hypothesis","Hypothesis"],["test-check","Test/check performed"],["result","Result"],["why-ruled-out","Why it is ruled out"]]],["7. Current Working Hypothesis",[["working-hypothesis","Hypothesis"],["supporting-evidence","Evidence supporting it"],["opposing-evidence","Evidence against it"]]],["8. Next Test",[["smallest-action","Smallest action to isolate or test next"]]]],je=$.flatMap(([,e])=>e);function S(e={}){let t=$.flatMap(([n,r])=>{let s=r.flatMap(([o,i])=>{let c=String(e[o]??"").trim();return c?[`### ${i}
3
3
 
4
4
  ${c}`]:[]});return s.length?[`## ${n}
5
5
 
@@ -9,7 +9,7 @@ ${s.join(`
9
9
 
10
10
  ${t.join(`
11
11
 
12
- `)}`:""}`}var $={name:"@varman96/paper",version:"1.0.10",description:"Paper captures command failures locally in a structured Incident Report for coding-agent investigation. Local-first. No telemetry.",main:"dist/paper.js",bin:{paper:"./dist/paper.js"},files:["dist/paper.js","README.md","LICENSE"],directories:{test:"test"},scripts:{"alpha:issue":"node scripts/issue-alpha-access.js","alpha:revoke":"node scripts/revoke-alpha-access.js","fail:test":"node scripts/fail-test.js",paper:"node scripts/paper.js","paper:dev":"node scripts/paper.js","build:cli":"node scripts/build-cli.js",prepack:"npm run build:cli","deploy:production":"wrangler deploy --env production",test:"node test/run-tests.js","test:fast":"node test/run-tests.js --fast","test:browser":"node test/run-tests.js --browser","test:alpha-browser":"node test/alpha-access.browser.js"},repository:{type:"git",url:"git+https://github.com/varman96/paper-cli.git"},keywords:["debugging","cli","developer-tools","coding-agents","ai-coding","incident-report","terminal","error-logs","claude-code","cursor","codex"],author:"",license:"SEE LICENSE IN LICENSE",type:"module",bugs:{url:"https://github.com/varman96/paper-cli/issues"},homepage:"https://paper-ai.paperhq.workers.dev/",devDependencies:{"@biomejs/biome":"2.5.14",esbuild:"^0.28.1",wrangler:"^4.132.0"}};var ee=`Paper captures a failed command and writes a local Incident Report.
12
+ `)}`:""}`}var R={name:"@varman96/paper",version:"1.0.12",description:"Paper captures command failures locally in a structured Incident Report for coding-agent investigation. Local-first. No telemetry.",main:"dist/paper.js",bin:{paper:"./dist/paper.js"},files:["dist/paper.js","README.md","LICENSE"],directories:{test:"test"},scripts:{"alpha:issue":"node scripts/issue-alpha-access.js","alpha:revoke":"node scripts/revoke-alpha-access.js","fail:test":"node scripts/fail-test.js",paper:"node scripts/paper.js","paper:dev":"node scripts/paper.js","build:cli":"node scripts/build-cli.js",prepack:"npm run build:cli","deploy:production":"wrangler deploy --env production",test:"node test/run-tests.js","test:fast":"node test/run-tests.js --fast","test:browser":"node test/run-tests.js --browser","test:alpha-browser":"node test/alpha-access.browser.js"},repository:{type:"git",url:"git+https://github.com/varman96/paper-cli.git"},keywords:["debugging","cli","developer-tools","coding-agents","ai-coding","incident-report","terminal","error-logs","claude-code","cursor","codex"],author:"",license:"SEE LICENSE IN LICENSE",type:"module",bugs:{url:"https://github.com/varman96/paper-cli/issues"},homepage:"https://paper-ai.paperhq.workers.dev/",devDependencies:{"@biomejs/biome":"2.5.14",esbuild:"^0.28.1",wrangler:"^4.132.0"}};var ne=`Paper captures a failed command and writes a local Incident Report.
13
13
 
14
14
  Usage: paper run <command>
15
15
 
@@ -22,43 +22,45 @@ Report: .paper/incident_report.md
22
22
  paper shelf Move the active Incident Report out of the workspace
23
23
 
24
24
  --help Show this help
25
- --version Show the version`,x=["<!-- paper:start -->","## Paper Incident Workflow","","When `.paper/incident_report.md` exists, read it before investigating.","","Treat the Incident Report as the current evidence anchor, not as infallible truth. Use it to establish the known failure boundary, then inspect the repository, runtime, tests, configuration, and other source-of-truth evidence as needed.","","Diagnose the issue using this trace:","","### 1. Establish the Failing Invariant","","Identify the exact boundary contract that was violated.","","State:","","Invariant Expected:","The concrete behavior or state that should have held.","","Invariant Observed:","The concrete behavior or state actually observed.","","Use precise system evidence where available:","- exit codes","- status codes","- errno","- ports","- file paths","- symbols","- stack frames","- environment values","- process state","- exact command output","","Do not replace concrete evidence with vague summaries.","","### 2. State Elimination","","Shrink the search space by explicitly ruling out competing explanations using verified evidence.","","For each relevant factor, state whether it is:","- confirmed working","- confirmed failing","- still unverified","","Examples:","- config parsed successfully","- network route reachable","- dependency present or missing","- process listening or not listening","- expected environment variable present or absent","","Do not mark a hypothesis ruled out without evidence.","","Do not repeat theories already ruled out by the Incident Report unless new evidence justifies reopening them.","","### 3. Single-Point Attribution","","Narrow the diagnosis to the smallest confirmed fault boundary.","","State:","","Fault Location:","The exact file, line, symbol, process, dependency, configuration value, environment delta, or runtime boundary responsible.","","Mechanism:","The concrete way that fault caused the observed invariant violation.","","Do not invent a root cause if the evidence only supports a narrower failure boundary.","","If the mechanism is not yet verified, label it as unverified and continue investigating.","","Newer source-of-truth evidence overrides stale or incorrect Incident Report content.","","### 4. Proposed Action Packet \u2014 Zero Execution","","Once the failure is sufficiently explained, STOP before remediation.","","Do not:","- modify files","- start or stop services","- change configuration","- install dependencies","- run a fix","- apply a patch","- mutate the environment","","unless the user explicitly asked for remediation.","","Report:","","What I found:","A concise diagnosis grounded in the Incident Report and verified evidence gathered afterward.","","Proposed fix:","The smallest intervention that addresses the confirmed mechanism.","","Diff preview:","Describe the expected code/config change if applicable. Do not apply it.","","Verification test:","Name the smallest test or command that would verify the proposed fix.","","Clearly distinguish:","- evidence already present in the Incident Report","- findings established during investigation","- hypotheses that remain unverified","","Once the current failure is sufficiently explained, stop widening the investigation unless new evidence connects another issue to the same failure.","","Important behavior:","- The agent may inspect the repo/runtime normally.","- The Incident Report is not the only source of truth.","- The agent must not hallucinate missing telemetry.","- The agent must not convert an unverified hypothesis into a confirmed diagnosis.","- The agent must not execute remediation unless explicitly asked.","- The diagnostic trace is investigative structure, not verbose prose. Keep each section concise and evidence-based.","<!-- paper:end -->"].join(`
26
- `),d=class extends Error{constructor(t,n,r,s){super(n),this.name="PaperCliError",this.causeLabel=t,this.state=r,this.directive=s}};function A(e){return e instanceof d?[e.causeLabel,e.message,"",e.state,"",e.directive].join(`
25
+ --version Show the version`,P=["<!-- paper:start -->","## Paper Incident Workflow","","When `.paper/incident_report.md` exists, read it before investigating.","","When `paper run` prints COMMAND FAILED, read `.paper/latest.json` before doing anything else.","Your tool output may be truncated \u2014 the JSON holds the complete stderr and the full incident report.","Do not diagnose from truncated output.","","Treat the Incident Report as the current evidence anchor, not as infallible truth. Use it to establish the known failure boundary, then inspect the repository, runtime, tests, configuration, and other source-of-truth evidence as needed.","","Diagnose the issue using this trace:","","### 1. Establish the Failing Invariant","","Identify the exact boundary contract that was violated.","","State:","","Invariant Expected:","The concrete behavior or state that should have held.","","Invariant Observed:","The concrete behavior or state actually observed.","","Use precise system evidence where available:","- exit codes","- status codes","- errno","- ports","- file paths","- symbols","- stack frames","- environment values","- process state","- exact command output","","Do not replace concrete evidence with vague summaries.","","### 2. State Elimination","","Shrink the search space by explicitly ruling out competing explanations using verified evidence.","","For each relevant factor, state whether it is:","- confirmed working","- confirmed failing","- still unverified","","Examples:","- config parsed successfully","- network route reachable","- dependency present or missing","- process listening or not listening","- expected environment variable present or absent","","Do not mark a hypothesis ruled out without evidence.","","Do not repeat theories already ruled out by the Incident Report unless new evidence justifies reopening them.","","### 3. Single-Point Attribution","","Narrow the diagnosis to the smallest confirmed fault boundary.","","State:","","Fault Location:","The exact file, line, symbol, process, dependency, configuration value, environment delta, or runtime boundary responsible.","","Mechanism:","The concrete way that fault caused the observed invariant violation.","","Do not invent a root cause if the evidence only supports a narrower failure boundary.","","If the mechanism is not yet verified, label it as unverified and continue investigating.","","Newer source-of-truth evidence overrides stale or incorrect Incident Report content.","","### 4. Proposed Action Packet \u2014 Zero Execution","","Once the failure is sufficiently explained, STOP before remediation.","","Do not:","- modify files","- start or stop services","- change configuration","- install dependencies","- run a fix","- apply a patch","- mutate the environment","","unless the user explicitly asked for remediation.","","Report:","","What I found:","A concise diagnosis grounded in the Incident Report and verified evidence gathered afterward.","","Proposed fix:","The smallest intervention that addresses the confirmed mechanism.","","Diff preview:","Describe the expected code/config change if applicable. Do not apply it.","","Verification test:","Name the smallest test or command that would verify the proposed fix.","","Clearly distinguish:","- evidence already present in the Incident Report","- findings established during investigation","- hypotheses that remain unverified","","Once the current failure is sufficiently explained, stop widening the investigation unless new evidence connects another issue to the same failure.","","Important behavior:","- The agent may inspect the repo/runtime normally.","- The Incident Report is not the only source of truth.","- The agent must not hallucinate missing telemetry.","- The agent must not convert an unverified hypothesis into a confirmed diagnosis.","- The agent must not execute remediation unless explicitly asked.","- The diagnostic trace is investigative structure, not verbose prose. Keep each section concise and evidence-based.","<!-- paper:end -->"].join(`
26
+ `),p=class extends Error{constructor(t,n,r,s){super(n),this.name="PaperCliError",this.causeLabel=t,this.state=r,this.directive=s}};function k(e){return e instanceof p?[e.causeLabel,e.message,"",e.state,"",e.directive].join(`
27
27
  `):["PAPER OPERATION FAILED",e?.message||"Paper encountered an unclassified local operation failure.","","Paper stopped before the requested operation completed.","","Resolve the reported local error and run Paper again."].join(`
28
- `)}function te({modulePath:e=Q(import.meta.url),invokedPath:t=process.argv[1],resolvePath:n=V.native}={}){if(!t)return{isCli:!1,startupFailure:!1};try{return{isCli:n(y(e))===n(y(t)),startupFailure:!1}}catch{let r=k(e).toLowerCase(),s=k(t).toLowerCase();return{isCli:!1,startupFailure:r===s}}}async function ne(e){try{let t=await F(e);return t.isDirectory()||t.isFile()}catch{return!1}}async function E(e=process.cwd()){let t=y(e);for(;;){if(await ne(a(t,".git")))return t;let n=m(t);if(n===t)return y(e);t=n}}async function b(e,t){try{let n=await F(e);return t==="directory"?n.isDirectory():t==="file"?n.isFile():!0}catch{return!1}}async function v(e){try{if((await q(e)).isSymbolicLink())throw new Error(`Refusing to write through a symbolic link: ${e}`)}catch(t){if(t.code!=="ENOENT")throw t}}async function re(e){let t=[],n=["AGENTS.md","CLAUDE.md","GEMINI.md",a(".github","copilot-instructions.md"),".cursorrules",a(".cursor","rules.md"),a(".cursor","instructions.md")];for(let r of n)await b(a(e,r),"file")&&t.push(a(e,r));return await b(a(e,".cursor","rules"),"directory")&&t.push(a(e,".cursor","rules","paper.mdc")),t.length?t:[a(e,"AGENTS.md")]}function ie(e){let t=/<!-- paper:start -->[\s\S]*?<!-- paper:end -->/g;if(e.match(t)?.length){let r=0,s=e.replace(t,()=>r++===0?x:"");return{next:s,changed:s!==e}}return{next:e?`${e}${e.endsWith(`
28
+ `)}function re({modulePath:e=te(import.meta.url),invokedPath:t=process.argv[1],resolvePath:n=X.native}={}){if(!t)return{isCli:!1,startupFailure:!1};try{return{isCli:n(y(e))===n(y(t)),startupFailure:!1}}catch{let r=N(e).toLowerCase(),s=N(t).toLowerCase();return{isCli:!1,startupFailure:r===s}}}async function ie(e){try{let t=await W(e);return t.isDirectory()||t.isFile()}catch{return!1}}async function T(e=process.cwd()){let t=y(e);for(;;){if(await ie(a(t,".git")))return t;let n=w(t);if(n===t)return y(e);t=n}}async function b(e,t){try{let n=await W(e);return t==="directory"?n.isDirectory():t==="file"?n.isFile():!0}catch{return!1}}async function v(e){try{if((await Y(e)).isSymbolicLink())throw new Error(`Refusing to write through a symbolic link: ${e}`)}catch(t){if(t.code!=="ENOENT")throw t}}async function se(e){let t=[],n=["AGENTS.md","CLAUDE.md","GEMINI.md",a(".github","copilot-instructions.md"),".cursorrules",a(".cursor","rules.md"),a(".cursor","instructions.md")];for(let r of n)await b(a(e,r),"file")&&t.push(a(e,r));return await b(a(e,".cursor","rules"),"directory")&&t.push(a(e,".cursor","rules","paper.mdc")),t.length?t:[a(e,"AGENTS.md")]}function oe(e){let t=/<!-- paper:start -->[\s\S]*?<!-- paper:end -->/g;if(e.match(t)?.length){let r=0,s=e.replace(t,()=>r++===0?P:"");return{next:s,changed:s!==e}}return{next:e?`${e}${e.endsWith(`
29
29
  `)?`
30
30
  `:`
31
31
 
32
- `}${x}
33
- `:`${x}
34
- `,changed:!0}}async function se(e=process.cwd()){let t=await E(e),n=await re(t),r=[],s=[];for(let o of n){await v(o),await v(m(o)),await v(m(m(o)));let i="";try{i=await K(o,"utf8")}catch(f){if(f.code!=="ENOENT")throw f}let{next:c,changed:p}=ie(i);p&&(await P(m(o),{recursive:!0}),await M(o,c,"utf8"),r.push(o),i||s.push(o))}return{repoRoot:t,targetPaths:n,changedPaths:r,created:s.length>0,changed:r.length>0}}async function oe(e,t){let n=a(e,".paper","incident_report.md");return await v(a(e,".paper")),await v(n),await P(m(n),{recursive:!0}),await M(n,t,"utf8"),n}function ae(e=process.env,t=O()){return t==="win32"?e.LOCALAPPDATA||a(R(),"AppData","Local","Paper"):a(e.XDG_DATA_HOME||a(R(),".local","share"),"Paper")}function ce(e,t=process.env,n=O()){let r=Z("sha256").update(y(e)).digest("hex").slice(0,16);return a(ae(t,n),"shelf",r)}function de(e=new Date){return e.toISOString().replace(/[:.]/g,"-")}async function pe(e,t){let n=0;for(;;){let r=a(e,`${t}${n?`-${n}`:""}.md`);if(!await b(r,"file"))return r;n+=1}}async function le(){let e=await E(),t=a(e,".paper","incident_report.md");if(!await b(t,"file"))throw new d("NO ACTIVE INCIDENT","Paper could not find an active Incident Report.","No files were changed.","Run `paper run <command>` to capture a failure first.");let n=ce(e),r=await pe(n,de());try{await P(n,{recursive:!0}),await Y(t,r)}catch(s){throw new d("INCIDENT SHELF FAILED",`Paper could not move the Incident Report out of the workspace${s?.code?` (${s.code})`:"."}`,"The active Incident Report was preserved in the workspace.","Restore access to the Paper shelf location and run `paper shelf` again.")}process.stdout.write(`INCIDENT SHELVED
32
+ `}${P}
33
+ `:`${P}
34
+ `,changed:!0}}async function ae(e=process.cwd()){let t=await T(e),n=await se(t),r=[],s=[];for(let o of n){await v(o),await v(w(o)),await v(w(w(o)));let i="";try{i=await K(o,"utf8")}catch(h){if(h.code!=="ENOENT")throw h}let{next:c,changed:d}=oe(i);d&&(await x(w(o),{recursive:!0}),await I(o,c,"utf8"),r.push(o),i||s.push(o))}return{repoRoot:t,targetPaths:n,changedPaths:r,created:s.length>0,changed:r.length>0}}async function ce(e,t){let n=a(e,".paper","incident_report.md");return await v(a(e,".paper")),await v(n),await x(w(n),{recursive:!0}),await I(n,t,"utf8"),n}var C=200*1024,de=50;async function pe(e,t,n,r,s){let o=a(e,".paper","latest.json");await v(a(e,".paper")),await v(o);let i=r.stderr||"",c=!1,d=Buffer.from(i,"utf8");d.length>C&&(i=d.subarray(-C).toString("utf8"),c=!0);let h={command:t,args:n,exit_code:r.code,signal:r.signal??null,working_directory:e,timestamp:new Date().toISOString(),stderr:i,...c?{truncated:!0}:{},stdout_tail:(r.stdout||"").split(/\r?\n/).filter((u,g,E)=>u||g<E.length-1).slice(-de).join(`
35
+ `),incident_report:s};await x(w(o),{recursive:!0});let f=`${o}.${process.pid}.tmp`;return await I(f,`${JSON.stringify(h,null,2)}
36
+ `,"utf8"),await _(f,o),o}function le(e=process.env,t=H()){return t==="win32"?e.LOCALAPPDATA||a(A(),"AppData","Local","Paper"):a(e.XDG_DATA_HOME||a(A(),".local","share"),"Paper")}function ue(e,t=process.env,n=H()){let r=V("sha256").update(y(e)).digest("hex").slice(0,16);return a(le(t,n),"shelf",r)}function he(e=new Date){return e.toISOString().replace(/[:.]/g,"-")}async function fe(e,t){let n=0;for(;;){let r=a(e,`${t}${n?`-${n}`:""}.md`);if(!await b(r,"file"))return r;n+=1}}async function me(){let e=await T(),t=a(e,".paper","incident_report.md");if(!await b(t,"file"))throw new p("NO ACTIVE INCIDENT","Paper could not find an active Incident Report.","No files were changed.","Run `paper run <command>` to capture a failure first.");let n=ue(e),r=await fe(n,he());try{await x(n,{recursive:!0}),await _(t,r)}catch(s){throw new p("INCIDENT SHELF FAILED",`Paper could not move the Incident Report out of the workspace${s?.code?` (${s.code})`:"."}`,"The active Incident Report was preserved in the workspace.","Restore access to the Paper shelf location and run `paper shelf` again.")}await Q(a(e,".paper","latest.json"),{force:!0}).catch(()=>{}),process.stdout.write(`INCIDENT SHELVED
35
37
  Moved the active Incident Report out of the workspace.
36
38
 
37
39
  Stored at:
38
40
  ${r}
39
- `)}function H(e,t){return[e,...t].join(" ")}function ue(e){if(process.platform!=="win32"||J(e)||/[\\/]/.test(e))return e;let t=(process.env.PATHEXT||".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean),n=(process.env.PATH||"").split(";");for(let r of n)for(let s of t){let o=a(r||".",`${e}${s}`);try{if(X(o).isFile())return`${e}${s}`}catch{}}return e}function he(e,t,n){return new Promise((r,s)=>{let o=!1,i=ue(e),c=process.platform==="win32"&&/\.cmd$/i.test(i),p=B(c?process.env.ComSpec||"cmd.exe":i,c?["/d","/s","/c",i,...t]:t,{cwd:n,windowsHide:!0,stdio:["inherit","pipe","pipe"]}),f="",g="";p.stdout.on("data",u=>{f+=u}),p.stderr.on("data",u=>{g+=u}),p.once("error",u=>{o||(o=!0,s(u))}),p.once("close",(u,w)=>{o||(o=!0,r({code:u,signal:w,stdout:f,stderr:g}))})})}function fe(e,t,n){let r=n.signal?`Process terminated by signal ${n.signal}`:`Process exited with code ${n.code}`;return[`$ ${H(e,t)}`,n.stdout,n.stderr,r].filter(Boolean).join(`
40
- `)}function me(e,t){let n=`\`${e}\``;return t?.code==="ENOENT"?new d("BINARY MISSING",`${n} was not found in the active PATH.`,"Execution stopped before the target command started.",`Install ${n} or run Paper with a command that exists in this shell.`):t?.code==="EACCES"?new d("PERMISSION DENIED",`Paper could not execute ${n} from this shell.`,"Execution stopped before the target command started.",`Restore execute permission for ${n} or run Paper with an executable command.`):new d("TARGET START FAILED",`Paper could not start ${n}${t?.message?`: ${t.message}`:"."}`,"Execution stopped before the target command started.",`Run ${n} directly in this shell to verify that it can start, then run Paper again.`)}function ge(e,t,n){return new d("REPORT WRITE FAILED",`Paper could not persist the Incident Report at \`${t}\`${e?.code?` (${e.code})`:"."}`,n?"The target command finished, but the report was not persisted.":"Paper stopped before the target command started.","Restore write access to the report location and run Paper again.")}function we(e){return new d("AGENT RULES WRITE FAILED",`Paper could not update the repository instruction file${e?.code?` (${e.code})`:"."}`,"Execution stopped before the target command started.","Restore write access to the repository instruction file and run Paper again.")}async function ve(e,t){let n=await E();try{await se()}catch(i){throw we(i)}let r;try{r=await he(e,t,n)}catch(i){throw me(e,i)}let s=a(n,".paper","incident_report.md");r.stdout&&process.stdout.write(r.stdout),r.stderr&&process.stderr.write(r.stderr);let o=`\`${H(e,t)}\``;if(r.code!==0||r.signal){let i=Ne(fe(e,t,r));try{await oe(n,i)}catch(p){throw ge(p,s,!0)}let c=r.signal?`signal ${r.signal}`:`code ${r.code}`;process.stderr.write(`COMMAND FAILED
41
+ `)}function z(e,t){return[e,...t].join(" ")}function ge(e){if(process.platform!=="win32"||ee(e)||/[\\/]/.test(e))return e;let t=(process.env.PATHEXT||".COM;.EXE;.BAT;.CMD").split(";").filter(Boolean),n=(process.env.PATH||"").split(";");for(let r of n)for(let s of t){let o=a(r||".",`${e}${s}`);try{if(q(o).isFile())return`${e}${s}`}catch{}}return e}function we(e,t,n){return new Promise((r,s)=>{let o=!1,i=ge(e),c=process.platform==="win32"&&/\.cmd$/i.test(i),d=J(c?process.env.ComSpec||"cmd.exe":i,c?["/d","/s","/c",i,...t]:t,{cwd:n,windowsHide:!0,stdio:["inherit","pipe","pipe"]}),h="",f="";d.stdout.on("data",u=>{h+=u}),d.stderr.on("data",u=>{f+=u}),d.once("error",u=>{o||(o=!0,s(u))}),d.once("close",(u,g)=>{o||(o=!0,r({code:u,signal:g,stdout:h,stderr:f}))})})}function ve(e,t,n){let r=n.signal?`Process terminated by signal ${n.signal}`:`Process exited with code ${n.code}`;return[`$ ${z(e,t)}`,n.stdout,n.stderr,r].filter(Boolean).join(`
42
+ `)}function ye(e,t){let n=`\`${e}\``;return t?.code==="ENOENT"?new p("BINARY MISSING",`${n} was not found in the active PATH.`,"Execution stopped before the target command started.",`Install ${n} or run Paper with a command that exists in this shell.`):t?.code==="EACCES"?new p("PERMISSION DENIED",`Paper could not execute ${n} from this shell.`,"Execution stopped before the target command started.",`Restore execute permission for ${n} or run Paper with an executable command.`):new p("TARGET START FAILED",`Paper could not start ${n}${t?.message?`: ${t.message}`:"."}`,"Execution stopped before the target command started.",`Run ${n} directly in this shell to verify that it can start, then run Paper again.`)}function be(e,t,n){return new p("REPORT WRITE FAILED",`Paper could not persist the Incident Report at \`${t}\`${e?.code?` (${e.code})`:"."}`,n?"The target command finished, but the report was not persisted.":"Paper stopped before the target command started.","Restore write access to the report location and run Paper again.")}function xe(e){return new p("AGENT RULES WRITE FAILED",`Paper could not update the repository instruction file${e?.code?` (${e.code})`:"."}`,"Execution stopped before the target command started.","Restore write access to the repository instruction file and run Paper again.")}async function Ee(e,t){let n=await T();try{await ae()}catch(i){throw xe(i)}let r;try{r=await we(e,t,n)}catch(i){throw ye(e,i)}let s=a(n,".paper","incident_report.md");r.stdout&&process.stdout.write(r.stdout),r.stderr&&process.stderr.write(r.stderr);let o=`\`${z(e,t)}\``;if(r.code!==0||r.signal){let i=Le(ve(e,t,r));try{await ce(n,i),await pe(n,e,t,r,i)}catch(d){throw be(d,s,!0)}let c=r.signal?`signal ${r.signal}`:`code ${r.code}`;process.stderr.write(`COMMAND FAILED
41
43
  ${o} exited with ${c}.
42
44
 
43
45
  Paper captured the failure and persisted the Incident Report at \`${s}\`.
44
- `)}}var ye=[/\b(?:error|fatal|exception|panic|failed|failure|traceback|segmentation fault|command not found|exited with code)\b|ERR!/i,/\b(?:HTTP\/\d(?:\.\d)?\s+)?[45]\d{2}\b/i,/\b(?:exit(?:ed| status| code)?|status code)\s*[:=]?\s*[1-9]\d*/i],be=/HTTP\/\d(?:\.\d)?\s+[1-5]\d{2}\b|\bstatus(?: code)?\s*[:=]?\s*[1-5]\d{2}\b/i,xe=/\b(?:exited with code|exit(?: status| code)?|status code)\s*[:=]?\s*[1-9]\d*/i,W=/^\s*(?:at\s+.+|File\s+["'].+["'],\s*line\s+\d+|[\w.]+\.[\w$]+\([^)]*:\d+(?::\d+)?\))/i,_=/^\s*(?:[$>]|(?:curl|wget|git|docker|kubectl|wrangler|npm|npx|node|python(?:\d+)?|pytest|cargo|go|dotnet|java|bun|deno|yarn|pnpm)\b)/i,Pe=/\b(?:node(?:\.js)?|npm|npx|pnpm|yarn|bun|deno|python(?:\d+)?|pytest|ruby|java|dotnet|cargo|rustc|go version|windows|linux|darwin|macos|runtime|version)\b/i,Ee=/(?:[A-Za-z]:[\\/][^\s,;()[\]{}]+|(?:\.{0,2}[\\/])?[A-Za-z0-9_.-]+(?:[\\/][A-Za-z0-9_.-]+)+\.[A-Za-z0-9_.-]+)/g,N=/^\s*(?:\+\s*)?(?:CategoryInfo|FullyQualifiedErrorId)\b/i,S=/^\s*At line:\d+ char:\d+\s*$/i,C=/^\s*(?:\+\s*)?~+\s*$/,D=/^\s*\+\s*npm(?:\.cmd)?\b/i,Ie=/^\s*\+\s*curl(?:\.exe)?\b/i,Te=/^\s*\|\s*(?:node|npm|npx)\b/i,j=/^\s*(?:npm(?:\.cmd)?|curl(?:\.exe)?)\s*:\s+/i,$e=/^\s*[a-z]:\/\//i;function Re(e=""){let t=String(e??""),n=t.replace(/\r\n?/g,`
46
+ `)}}var Pe=[/\b(?:error|fatal|exception|panic|failed|failure|traceback|segmentation fault|command not found|exited with code)\b|ERR!/i,/\b(?:HTTP\/\d(?:\.\d)?\s+)?[45]\d{2}\b/i,/\b(?:exit(?:ed| status| code)?|status code)\s*[:=]?\s*[1-9]\d*/i],Ie=/HTTP\/\d(?:\.\d)?\s+[1-5]\d{2}\b|\bstatus(?: code)?\s*[:=]?\s*[1-5]\d{2}\b/i,Te=/\b(?:exited with code|exit(?: status| code)?|status code)\s*[:=]?\s*[1-9]\d*/i,B=/^\s*(?:at\s+.+|File\s+["'].+["'],\s*line\s+\d+|[\w.]+\.[\w$]+\([^)]*:\d+(?::\d+)?\))/i,G=/^\s*(?:[$>]|(?:curl|wget|git|docker|kubectl|wrangler|npm|npx|node|python(?:\d+)?|pytest|cargo|go|dotnet|java|bun|deno|yarn|pnpm)\b)/i,$e=/\b(?:node(?:\.js)?|npm|npx|pnpm|yarn|bun|deno|python(?:\d+)?|pytest|ruby|java|dotnet|cargo|rustc|go version|windows|linux|darwin|macos|runtime|version)\b/i,Se=/(?:[A-Za-z]:[\\/][^\s,;()[\]{}]+|(?:\.{0,2}[\\/])?[A-Za-z0-9_.-]+(?:[\\/][A-Za-z0-9_.-]+)+\.[A-Za-z0-9_.-]+)/g,D=/^\s*(?:\+\s*)?(?:CategoryInfo|FullyQualifiedErrorId)\b/i,L=/^\s*At line:\d+ char:\d+\s*$/i,j=/^\s*(?:\+\s*)?~+\s*$/,M=/^\s*\+\s*npm(?:\.cmd)?\b/i,Re=/^\s*\+\s*curl(?:\.exe)?\b/i,Ae=/^\s*\|\s*(?:node|npm|npx)\b/i,O=/^\s*(?:npm(?:\.cmd)?|curl(?:\.exe)?)\s*:\s+/i,Ne=/^\s*[a-z]:\/\//i;function ke(e=""){let t=String(e??""),n=t.replace(/\r\n?/g,`
45
47
  `).split(`
46
- `);if(!(n.some(i=>N.test(i))&&n.some(i=>j.test(i))))return t;let s=[],o=!1;for(let i of n){if(N.test(i)){o=!0;continue}if(o){if(!i.trim()){o=!1,s.push(i);continue}if(S.test(i)||C.test(i)||D.test(i))continue;if(W.test(i)||_.test(i))o=!1;else continue}if(S.test(i)||C.test(i)||D.test(i)||Te.test(i))continue;if(Ie.test(i)){let p=i.replace(/^\s*\+\s*/,"");s.at(-1)!==p&&s.push(p);continue}if($e.test(i))continue;let c=i.replace(j,"");s.at(-1)!==c&&s.push(c)}return s.join(`
47
- `)}function h(e){return[...new Set(e.map(t=>t.trim()).filter(Boolean))]}function ke(e){return h([...e.matchAll(Ee)].map(([t])=>t.replace(/[.:]+$/,"")).filter(t=>!/^HTTP\/\d(?:\.\d)?$/i.test(t)&&!/^[a-z]:\/\//i.test(t)))}function Ae(e=""){let t=Re(e),r=t.replace(/\r\n?/g,`
48
+ `);if(!(n.some(i=>D.test(i))&&n.some(i=>O.test(i))))return t;let s=[],o=!1;for(let i of n){if(D.test(i)){o=!0;continue}if(o){if(!i.trim()){o=!1,s.push(i);continue}if(L.test(i)||j.test(i)||M.test(i))continue;if(B.test(i)||G.test(i))o=!1;else continue}if(L.test(i)||j.test(i)||M.test(i)||Ae.test(i))continue;if(Re.test(i)){let d=i.replace(/^\s*\+\s*/,"");s.at(-1)!==d&&s.push(d);continue}if(Ne.test(i))continue;let c=i.replace(O,"");s.at(-1)!==c&&s.push(c)}return s.join(`
49
+ `)}function m(e){return[...new Set(e.map(t=>t.trim()).filter(Boolean))]}function Ce(e){return m([...e.matchAll(Se)].map(([t])=>t.replace(/[.:]+$/,"")).filter(t=>!/^HTTP\/\d(?:\.\d)?$/i.test(t)&&!/^[a-z]:\/\//i.test(t)))}function De(e=""){let t=ke(e),r=t.replace(/\r\n?/g,`
48
50
  `).split(`
49
- `).filter(l=>l.trim()),s=h(r.filter(l=>ye.some(G=>G.test(l)))),o=h(r.filter(l=>W.test(l))),i=h(r.filter(l=>_.test(l))),c=h(r.filter(l=>Pe.test(l))),p=h(r.filter(l=>be.test(l))),f=h(r.filter(l=>xe.test(l))),g=ke(t),u=h([...s,...o]).join(`
50
- `),w=i.join(`
51
- `),z=g.length?`${g.join(`
51
+ `).filter(l=>l.trim()),s=m(r.filter(l=>Pe.some(U=>U.test(l)))),o=m(r.filter(l=>B.test(l))),i=m(r.filter(l=>G.test(l))),c=m(r.filter(l=>$e.test(l))),d=m(r.filter(l=>Ie.test(l))),h=m(r.filter(l=>Te.test(l))),f=Ce(t),u=m([...s,...o]).join(`
52
+ `),g=i.join(`
53
+ `),E=f.length?`${f.join(`
52
54
  `)}
53
55
 
54
56
  ${t}`:t;return{"what-failing":s.join(`
55
57
  `),"observed-at-boundary":s.join(`
56
- `),"input-payload":w,"output-error":u,origin:w,"first-confirmed-divergence":s[0]||o[0]||"","runtime-environment-hops":c.join(`
57
- `),"exit-code":f.join(`
58
- `),"stderr-stack-trace":u,"status-codes":p.join(`
59
- `),commands:w,"runtime-versions":c.join(`
60
- `),"other-receipts":z}}function Ne(e=""){return T(Ae(e))}var L=te();if(L.startupFailure)process.stderr.write(`${A(new d("CLI ENTRYPOINT MISMATCH","Paper loaded, but the executable path could not be resolved to the active CLI entrypoint.","No target command was started.","Reinstall or relink Paper and run the command again."))}
61
- `),process.exitCode=1;else if(L.isCli)try{let e=process.argv.slice(2);if(e[0]==="--help")process.stdout.write(`${ee}
62
- `);else if(e[0]==="--version")process.stdout.write(`${$.version}
63
- `);else if(e[0]==="shelf"&&e.length===1)await le();else if(e.length){if(e[0]!=="run")throw new d("INVALID COMMAND","Paper expected `run` before the target command.","No target command was started.","Use `paper run <command>`.");if(e.length===1)throw new d("NO COMMAND","Paper needs a command to capture.","No target command was started.","Use `paper run <command>`. ");await ve(e[1],e.slice(2))}else throw new d("NO COMMAND","Paper needs a command to capture.","No target command was started.","Use `paper run <command>`.")}catch(e){process.stderr.write(`${A(e)}
64
- `),process.exitCode=1}export{x as MANAGED_AGENT_RULES_BLOCK,d as PaperCliError,Ne as buildTerminalPacket,re as detectAgentInstructionPaths,se as ensureManagedAgentRules,Ae as extractTerminalPacket,E as findRepoRoot,A as formatPaperCliError,Re as normalizeTerminalOutput,te as resolveCliEntrypoint,ce as shelfPathForRepo,oe as writeIncidentReport};
58
+ `),"input-payload":g,"output-error":u,origin:g,"first-confirmed-divergence":s[0]||o[0]||"","runtime-environment-hops":c.join(`
59
+ `),"exit-code":h.join(`
60
+ `),"stderr-stack-trace":u,"status-codes":d.join(`
61
+ `),commands:g,"runtime-versions":c.join(`
62
+ `),"other-receipts":E}}function Le(e=""){return S(De(e))}var F=re();if(F.startupFailure)process.stderr.write(`${k(new p("CLI ENTRYPOINT MISMATCH","Paper loaded, but the executable path could not be resolved to the active CLI entrypoint.","No target command was started.","Reinstall or relink Paper and run the command again."))}
63
+ `),process.exitCode=1;else if(F.isCli)try{let e=process.argv.slice(2);if(e[0]==="--help")process.stdout.write(`${ne}
64
+ `);else if(e[0]==="--version")process.stdout.write(`${R.version}
65
+ `);else if(e[0]==="shelf"&&e.length===1)await me();else if(e.length){if(e[0]!=="run")throw new p("INVALID COMMAND","Paper expected `run` before the target command.","No target command was started.","Use `paper run <command>`.");if(e.length===1)throw new p("NO COMMAND","Paper needs a command to capture.","No target command was started.","Use `paper run <command>`. ");await Ee(e[1],e.slice(2))}else throw new p("NO COMMAND","Paper needs a command to capture.","No target command was started.","Use `paper run <command>`.")}catch(e){process.stderr.write(`${k(e)}
66
+ `),process.exitCode=1}export{P as MANAGED_AGENT_RULES_BLOCK,p as PaperCliError,Le as buildTerminalPacket,se as detectAgentInstructionPaths,ae as ensureManagedAgentRules,De as extractTerminalPacket,T as findRepoRoot,k as formatPaperCliError,ke as normalizeTerminalOutput,re as resolveCliEntrypoint,ue as shelfPathForRepo,ce as writeIncidentReport,pe as writeLatestJson};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@varman96/paper",
3
- "version": "1.0.10",
3
+ "version": "1.0.12",
4
4
  "description": "Paper captures command failures locally in a structured Incident Report for coding-agent investigation. Local-first. No telemetry.",
5
5
  "main": "dist/paper.js",
6
6
  "bin": {