@nanonets/graft 0.23.0 → 0.24.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.
- package/README.md +4 -4
- package/dist/ai/crux.d.ts +31 -3
- package/dist/ai/crux.d.ts.map +1 -1
- package/dist/ai/crux.js +88 -10
- package/dist/ai/crux.js.map +1 -1
- package/dist/ai/llm/openai.d.ts +101 -0
- package/dist/ai/llm/openai.d.ts.map +1 -1
- package/dist/ai/llm/openai.js +396 -6
- package/dist/ai/llm/openai.js.map +1 -1
- package/dist/ai/llm/recover-tool.d.ts +2 -0
- package/dist/ai/llm/recover-tool.d.ts.map +1 -1
- package/dist/ai/llm/recover-tool.js +1 -1
- package/dist/ai/llm/recover-tool.js.map +1 -1
- package/dist/ai/synthesize.d.ts.map +1 -1
- package/dist/ai/synthesize.js +100 -1
- package/dist/ai/synthesize.js.map +1 -1
- package/dist/claude/format.d.ts +21 -0
- package/dist/claude/format.d.ts.map +1 -1
- package/dist/claude/format.js +46 -1
- package/dist/claude/format.js.map +1 -1
- package/dist/claude/hooks.d.ts +5 -9
- package/dist/claude/hooks.d.ts.map +1 -1
- package/dist/claude/hooks.js +71 -58
- package/dist/claude/hooks.js.map +1 -1
- package/dist/claude/init.js +3 -3
- package/dist/claude/init.js.map +1 -1
- package/dist/claude/note-signals.d.ts +28 -0
- package/dist/claude/note-signals.d.ts.map +1 -0
- package/dist/claude/note-signals.js +325 -0
- package/dist/claude/note-signals.js.map +1 -0
- package/dist/claude/shim-template.d.ts.map +1 -1
- package/dist/claude/shim-template.js +17 -6
- package/dist/claude/shim-template.js.map +1 -1
- package/dist/claude/skill-template.d.ts.map +1 -1
- package/dist/claude/skill-template.js +49 -18
- package/dist/claude/skill-template.js.map +1 -1
- package/dist/claude/state.d.ts +4 -3
- package/dist/claude/state.d.ts.map +1 -1
- package/dist/claude/state.js.map +1 -1
- package/dist/claude/sync-run.js +1 -1
- package/dist/claude/sync-run.js.map +1 -1
- package/dist/cli-picker.d.ts +12 -5
- package/dist/cli-picker.d.ts.map +1 -1
- package/dist/cli-picker.js +24 -8
- package/dist/cli-picker.js.map +1 -1
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +149 -43
- package/dist/cli.js.map +1 -1
- package/dist/context/batches.d.ts +29 -0
- package/dist/context/batches.d.ts.map +1 -0
- package/dist/context/batches.js +130 -0
- package/dist/context/batches.js.map +1 -0
- package/dist/context/build.d.ts +7 -2
- package/dist/context/build.d.ts.map +1 -1
- package/dist/context/build.js +84 -50
- package/dist/context/build.js.map +1 -1
- package/dist/context/node-file.d.ts.map +1 -1
- package/dist/context/node-file.js +41 -4
- package/dist/context/node-file.js.map +1 -1
- package/dist/engine.d.ts +2 -0
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +1 -0
- package/dist/engine.js.map +1 -1
- package/dist/graph/cards.d.ts.map +1 -1
- package/dist/graph/cards.js +9 -4
- package/dist/graph/cards.js.map +1 -1
- package/dist/graph/enrich.d.ts.map +1 -1
- package/dist/graph/enrich.js +8 -3
- package/dist/graph/enrich.js.map +1 -1
- package/dist/graph/generic.d.ts.map +1 -1
- package/dist/graph/generic.js +207 -6
- package/dist/graph/generic.js.map +1 -1
- package/dist/graph/lsp/client.d.ts +18 -0
- package/dist/graph/lsp/client.d.ts.map +1 -1
- package/dist/graph/lsp/client.js +40 -2
- package/dist/graph/lsp/client.js.map +1 -1
- package/dist/graph/lsp/enrich.d.ts.map +1 -1
- package/dist/graph/lsp/enrich.js +9 -1
- package/dist/graph/lsp/enrich.js.map +1 -1
- package/dist/graph/lsp/registry.d.ts +7 -0
- package/dist/graph/lsp/registry.d.ts.map +1 -1
- package/dist/graph/lsp/registry.js +27 -2
- package/dist/graph/lsp/registry.js.map +1 -1
- package/dist/graph/queries/gleam.scm +51 -0
- package/dist/graph/resolve.d.ts.map +1 -1
- package/dist/graph/resolve.js +65 -3
- package/dist/graph/resolve.js.map +1 -1
- package/dist/graph/workspace-cli.d.ts +2 -0
- package/dist/graph/workspace-cli.d.ts.map +1 -1
- package/dist/graph/workspace-cli.js +1 -1
- package/dist/graph/workspace-cli.js.map +1 -1
- package/dist/init-guard.d.ts +11 -0
- package/dist/init-guard.d.ts.map +1 -0
- package/dist/init-guard.js +21 -0
- package/dist/init-guard.js.map +1 -0
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +2 -1
- package/dist/mcp/tools.js.map +1 -1
- package/dist/notes/branches.d.ts +7 -1
- package/dist/notes/branches.d.ts.map +1 -1
- package/dist/notes/branches.js +31 -3
- package/dist/notes/branches.js.map +1 -1
- package/dist/notes/cold-start.d.ts +12 -2
- package/dist/notes/cold-start.d.ts.map +1 -1
- package/dist/notes/cold-start.js +46 -5
- package/dist/notes/cold-start.js.map +1 -1
- package/dist/notes/credit.d.ts +37 -0
- package/dist/notes/credit.d.ts.map +1 -0
- package/dist/notes/credit.js +78 -0
- package/dist/notes/credit.js.map +1 -0
- package/dist/notes/find-notes.d.ts +17 -0
- package/dist/notes/find-notes.d.ts.map +1 -0
- package/dist/notes/find-notes.js +48 -0
- package/dist/notes/find-notes.js.map +1 -0
- package/dist/notes/flatten.d.ts +31 -0
- package/dist/notes/flatten.d.ts.map +1 -0
- package/dist/notes/flatten.js +73 -0
- package/dist/notes/flatten.js.map +1 -0
- package/dist/notes/git-facts.d.ts +7 -1
- package/dist/notes/git-facts.d.ts.map +1 -1
- package/dist/notes/git-facts.js +12 -2
- package/dist/notes/git-facts.js.map +1 -1
- package/dist/notes/home.d.ts +24 -6
- package/dist/notes/home.d.ts.map +1 -1
- package/dist/notes/home.js +82 -15
- package/dist/notes/home.js.map +1 -1
- package/dist/notes/learning-fields.d.ts +102 -0
- package/dist/notes/learning-fields.d.ts.map +1 -0
- package/dist/notes/learning-fields.js +214 -0
- package/dist/notes/learning-fields.js.map +1 -0
- package/dist/notes/memory-notes.d.ts +71 -0
- package/dist/notes/memory-notes.d.ts.map +1 -0
- package/dist/notes/memory-notes.js +239 -0
- package/dist/notes/memory-notes.js.map +1 -0
- package/dist/notes/note-gate.d.ts +42 -0
- package/dist/notes/note-gate.d.ts.map +1 -0
- package/dist/notes/note-gate.js +181 -0
- package/dist/notes/note-gate.js.map +1 -0
- package/dist/notes/notes.d.ts +29 -77
- package/dist/notes/notes.d.ts.map +1 -1
- package/dist/notes/notes.js +69 -228
- package/dist/notes/notes.js.map +1 -1
- package/dist/notes/pr-reviews.d.ts +35 -7
- package/dist/notes/pr-reviews.d.ts.map +1 -1
- package/dist/notes/pr-reviews.js +156 -46
- package/dist/notes/pr-reviews.js.map +1 -1
- package/dist/notes/secrets.d.ts +28 -0
- package/dist/notes/secrets.d.ts.map +1 -0
- package/dist/notes/secrets.js +362 -0
- package/dist/notes/secrets.js.map +1 -0
- package/dist/notes/session-cost.d.ts +2 -0
- package/dist/notes/session-cost.d.ts.map +1 -1
- package/dist/notes/session-cost.js +8 -3
- package/dist/notes/session-cost.js.map +1 -1
- package/dist/notes/targets.d.ts +37 -0
- package/dist/notes/targets.d.ts.map +1 -0
- package/dist/notes/targets.js +108 -0
- package/dist/notes/targets.js.map +1 -0
- package/dist/notes/team-check.d.ts +22 -0
- package/dist/notes/team-check.d.ts.map +1 -0
- package/dist/notes/team-check.js +130 -0
- package/dist/notes/team-check.js.map +1 -0
- package/dist/notes/trail-home.d.ts +3 -0
- package/dist/notes/trail-home.d.ts.map +1 -0
- package/dist/notes/trail-home.js +12 -0
- package/dist/notes/trail-home.js.map +1 -0
- package/dist/search/grep-cli.d.ts +5 -2
- package/dist/search/grep-cli.d.ts.map +1 -1
- package/dist/search/grep-cli.js +11 -4
- package/dist/search/grep-cli.js.map +1 -1
- package/dist/search/ignored-code.d.ts +9 -0
- package/dist/search/ignored-code.d.ts.map +1 -0
- package/dist/search/ignored-code.js +73 -0
- package/dist/search/ignored-code.js.map +1 -0
- package/dist/skills/answers-prompt.d.ts +13 -0
- package/dist/skills/answers-prompt.d.ts.map +1 -0
- package/dist/skills/answers-prompt.js +83 -0
- package/dist/skills/answers-prompt.js.map +1 -0
- package/dist/skills/never-save.d.ts +5 -0
- package/dist/skills/never-save.d.ts.map +1 -0
- package/dist/skills/never-save.js +158 -0
- package/dist/skills/never-save.js.map +1 -0
- package/dist/skills/params.d.ts +39 -0
- package/dist/skills/params.d.ts.map +1 -0
- package/dist/skills/params.js +275 -0
- package/dist/skills/params.js.map +1 -0
- package/dist/skills/ran-less.d.ts +5 -0
- package/dist/skills/ran-less.d.ts.map +1 -0
- package/dist/skills/ran-less.js +51 -0
- package/dist/skills/ran-less.js.map +1 -0
- package/dist/skills/risk-delta.d.ts +32 -0
- package/dist/skills/risk-delta.d.ts.map +1 -0
- package/dist/skills/risk-delta.js +56 -0
- package/dist/skills/risk-delta.js.map +1 -0
- package/dist/skills/risk.d.ts +73 -0
- package/dist/skills/risk.d.ts.map +1 -0
- package/dist/skills/risk.js +396 -0
- package/dist/skills/risk.js.map +1 -0
- package/dist/skills/types.d.ts +422 -0
- package/dist/skills/types.d.ts.map +1 -0
- package/dist/skills/types.js +2 -0
- package/dist/skills/types.js.map +1 -0
- package/dist/telemetry/contract.d.ts.map +1 -1
- package/dist/telemetry/contract.js +8 -6
- package/dist/telemetry/contract.js.map +1 -1
- package/dist/telemetry/notice.d.ts.map +1 -1
- package/dist/telemetry/notice.js +3 -1
- package/dist/telemetry/notice.js.map +1 -1
- package/dist/trace/check-reads.d.ts +36 -0
- package/dist/trace/check-reads.d.ts.map +1 -0
- package/dist/trace/check-reads.js +57 -0
- package/dist/trace/check-reads.js.map +1 -0
- package/dist/trace/host.d.ts +40 -0
- package/dist/trace/host.d.ts.map +1 -0
- package/dist/trace/host.js +84 -0
- package/dist/trace/host.js.map +1 -0
- package/dist/trace/redact.d.ts +8 -0
- package/dist/trace/redact.d.ts.map +1 -0
- package/dist/trace/redact.js +63 -0
- package/dist/trace/redact.js.map +1 -0
- package/dist/trace/seen-cache.d.ts +9 -0
- package/dist/trace/seen-cache.d.ts.map +1 -0
- package/dist/trace/seen-cache.js +46 -0
- package/dist/trace/seen-cache.js.map +1 -0
- package/dist/trace/shell-scan.d.ts +52 -0
- package/dist/trace/shell-scan.d.ts.map +1 -0
- package/dist/trace/shell-scan.js +318 -0
- package/dist/trace/shell-scan.js.map +1 -0
- package/dist/trace/shell-words.d.ts +91 -0
- package/dist/trace/shell-words.d.ts.map +1 -0
- package/dist/trace/shell-words.js +558 -0
- package/dist/trace/shell-words.js.map +1 -0
- package/dist/trace/shell.d.ts +91 -0
- package/dist/trace/shell.d.ts.map +1 -0
- package/dist/trace/shell.js +435 -0
- package/dist/trace/shell.js.map +1 -0
- package/dist/trace/state.d.ts +27 -0
- package/dist/trace/state.d.ts.map +1 -0
- package/dist/trace/state.js +98 -0
- package/dist/trace/state.js.map +1 -0
- package/dist/trace/tamper-code.d.ts +9 -0
- package/dist/trace/tamper-code.d.ts.map +1 -0
- package/dist/trace/tamper-code.js +174 -0
- package/dist/trace/tamper-code.js.map +1 -0
- package/dist/trace/tamper-git.d.ts +12 -0
- package/dist/trace/tamper-git.d.ts.map +1 -0
- package/dist/trace/tamper-git.js +77 -0
- package/dist/trace/tamper-git.js.map +1 -0
- package/dist/trace/types.d.ts +477 -0
- package/dist/trace/types.d.ts.map +1 -0
- package/dist/trace/types.js +12 -0
- package/dist/trace/types.js.map +1 -0
- package/dist/trace/walls-glob.d.ts +11 -0
- package/dist/trace/walls-glob.d.ts.map +1 -0
- package/dist/trace/walls-glob.js +264 -0
- package/dist/trace/walls-glob.js.map +1 -0
- package/dist/trace/walls-quoted.d.ts +25 -0
- package/dist/trace/walls-quoted.d.ts.map +1 -0
- package/dist/trace/walls-quoted.js +81 -0
- package/dist/trace/walls-quoted.js.map +1 -0
- package/dist/upkeep.d.ts +1 -1
- package/dist/upkeep.d.ts.map +1 -1
- package/dist/upkeep.js +4 -1
- package/dist/upkeep.js.map +1 -1
- package/dist/util/actions-folder.d.ts +2 -0
- package/dist/util/actions-folder.d.ts.map +1 -0
- package/dist/util/actions-folder.js +9 -0
- package/dist/util/actions-folder.js.map +1 -0
- package/dist/util/front-matter.d.ts +31 -4
- package/dist/util/front-matter.d.ts.map +1 -1
- package/dist/util/front-matter.js +95 -3
- package/dist/util/front-matter.js.map +1 -1
- package/dist/util/private-file.d.ts +14 -0
- package/dist/util/private-file.d.ts.map +1 -0
- package/dist/util/private-file.js +82 -0
- package/dist/util/private-file.js.map +1 -0
- package/dist/util/private-fs.d.ts +25 -0
- package/dist/util/private-fs.d.ts.map +1 -0
- package/dist/util/private-fs.js +253 -0
- package/dist/util/private-fs.js.map +1 -0
- package/dist/util/state.d.ts.map +1 -1
- package/dist/util/state.js +3 -0
- package/dist/util/state.js.map +1 -1
- package/dist/viewer/app.js +2 -2
- package/package.json +5 -5
- package/scripts/run-tests.mjs +14 -2
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether a text holds a secret: the check every save runs before a skill
|
|
3
|
+
* step, a lesson or a learning is written. A text with one is refused, not
|
|
4
|
+
* scrubbed: a scrubbed command no longer works, and a missed shape in a
|
|
5
|
+
* shared file is the worst case. Matches the shapes that turn up in real
|
|
6
|
+
* sessions: provider keys, vendor keys (a short prefix and a long random
|
|
7
|
+
* body), names like `TRAIL_API_KEY=` with a real value, bearer and basic
|
|
8
|
+
* logins, private keys, passwords in URLs and commands, and long random
|
|
9
|
+
* strings.
|
|
10
|
+
*
|
|
11
|
+
* Not secrets: git shas and other hex digests (the same shape as a hash of
|
|
12
|
+
* anything), versions, UUIDs (session, run and request ids show up in paths
|
|
13
|
+
* and commands; a UUID only counts when it is assigned to a secret's name),
|
|
14
|
+
* paths (macOS temp folders `/var/folders/<2>/<random>/T/` included: the
|
|
15
|
+
* random folder name is the system's, D62), placeholders (`$TOKEN`,
|
|
16
|
+
* `${TOKEN}`, `<token>`, `***`) and words.
|
|
17
|
+
*
|
|
18
|
+
* The reason names the kind of secret, never the secret.
|
|
19
|
+
*
|
|
20
|
+
* Every check is linear in the text: it runs on every save and in hooks, on
|
|
21
|
+
* texts of any length. A pattern that starts at every position of a long run
|
|
22
|
+
* and reads to the run's end (`aaaa…`, `sk-sk-sk-…`, `a.a.a.…`) is quadratic,
|
|
23
|
+
* so each one here starts only where a match can start, or is a short loop
|
|
24
|
+
* that reads a run once.
|
|
25
|
+
*/
|
|
26
|
+
const PRIVATE_KEY = /-----BEGIN (?:[A-Z0-9]+ )*PRIVATE KEY(?: BLOCK)?-----/;
|
|
27
|
+
/** Keys whose provider prefix says what they are. */
|
|
28
|
+
const PROVIDER_KEYS = [
|
|
29
|
+
/\b[sr]k_(?:live|test)_[A-Za-z0-9]{16,}/,
|
|
30
|
+
/\bgh[pousr]_[A-Za-z0-9]{20,}/,
|
|
31
|
+
/\bgithub_pat_[A-Za-z0-9_]{20,}/,
|
|
32
|
+
/\bglpat-[A-Za-z0-9_-]{20,}/,
|
|
33
|
+
/\bnpm_[A-Za-z0-9]{30,}/,
|
|
34
|
+
/\bhf_[A-Za-z0-9]{30,}/,
|
|
35
|
+
/\bxox[abprs]-[A-Za-z0-9-]{10,}/,
|
|
36
|
+
/\b(?:AKIA|ASIA)[0-9A-Z]{16}\b/,
|
|
37
|
+
/\bAIza[0-9A-Za-z_-]{30,}/,
|
|
38
|
+
/\bya29\.[A-Za-z0-9_-]{20,}/,
|
|
39
|
+
/\bSG\.[A-Za-z0-9_-]{16,}\.[A-Za-z0-9_-]{16,}/,
|
|
40
|
+
/\bGOCSPX-[A-Za-z0-9_-]{20,}/,
|
|
41
|
+
// A Telegram bot token, often inside its API link (`/bot123:AA…`).
|
|
42
|
+
/(?<!\d)\d{6,12}:AA[A-Za-z0-9_-]{30,}/,
|
|
43
|
+
];
|
|
44
|
+
/**
|
|
45
|
+
* Keys with a prefix and a body that holds a digit (`sk-…`, `sb_secret_…`; the
|
|
46
|
+
* digit keeps out names like `sk-learn-…`), with the body's least length. Only
|
|
47
|
+
* the first prefix in a run of key characters is looked at: a later one in the
|
|
48
|
+
* same run has less of that run after it, so it can't hold a key where the
|
|
49
|
+
* first didn't, and a lookahead tried at each of them (`sk-sk-sk-…`) is
|
|
50
|
+
* quadratic.
|
|
51
|
+
*/
|
|
52
|
+
const DIGIT_KEYS = [
|
|
53
|
+
[/\bsk-([A-Za-z0-9_-]*)/g, 16],
|
|
54
|
+
[/\bsb_secret_([A-Za-z0-9_-]*)/g, 20],
|
|
55
|
+
];
|
|
56
|
+
function digitKey(text) {
|
|
57
|
+
for (const [re, min] of DIGIT_KEYS) {
|
|
58
|
+
for (const m of text.matchAll(re))
|
|
59
|
+
if (m[1].length >= min && /\d/.test(m[1]))
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
/** Links that are a credential: whoever has one can post. */
|
|
65
|
+
const WEBHOOKS = [/hooks\.slack\.com\/(?:services|workflows|triggers)\/[A-Za-z0-9_/-]{20,}/, /discord(?:app)?\.com\/api\/webhooks\/\d+\/[A-Za-z0-9_-]{20,}/];
|
|
66
|
+
/** A link with its scheme (`https://…`) or without one (`docs.example.test/d/…`); see linkSpans. */
|
|
67
|
+
const SCHEMED = /[a-z][a-z0-9+.-]*:\/\/[^\s'"<>`]+/iy;
|
|
68
|
+
const BARE = /(?:[a-z0-9-]+\.)+[a-z]{2,}\/[^\s'"<>`]*/iy;
|
|
69
|
+
const HOST_RUN = /(?:[a-z0-9-]+\.)*[a-z0-9-]*/iy;
|
|
70
|
+
const LINK_START = /\b[a-z0-9-]/gi;
|
|
71
|
+
const LETTER_START = /\b[a-z]/gi;
|
|
72
|
+
/** From the first place a link can start in a run of scheme characters to the run's end. */
|
|
73
|
+
const SCHEME_RUN = /\b[a-z0-9-][a-z0-9+.-]*/gi;
|
|
74
|
+
/** The length of `re`'s (sticky) match at `i`, or -1. */
|
|
75
|
+
function at(re, text, i) {
|
|
76
|
+
re.lastIndex = i;
|
|
77
|
+
return re.test(text) ? re.lastIndex - i : -1;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* The links in `text` as [start, end], in order: what the pattern
|
|
81
|
+
* /\b[a-z][a-z0-9+.-]*:\/\/[^\s'"<>`]+|\b(?:[a-z0-9-]+\.)+[a-z]{2,}\/[^\s'"<>`]*\/gi
|
|
82
|
+
* finds. That pattern reads a long run that is neither (`a.a.a.…`) to its end
|
|
83
|
+
* from each of its positions; here each run of scheme characters is read once.
|
|
84
|
+
* A link with a scheme starts at the run's first letter after a non-word
|
|
85
|
+
* character, when `://` ends the run. One without needs a dot in the run, and
|
|
86
|
+
* every start in one run of host labels reaches the same last label, so where
|
|
87
|
+
* one failed the rest of those labels are skipped.
|
|
88
|
+
*/
|
|
89
|
+
function linkSpans(text) {
|
|
90
|
+
const spans = [];
|
|
91
|
+
SCHEME_RUN.lastIndex = 0;
|
|
92
|
+
for (let run; (run = SCHEME_RUN.exec(text));) {
|
|
93
|
+
const start = run.index;
|
|
94
|
+
const end = start + run[0].length;
|
|
95
|
+
const schemed = text.startsWith("://", end) && /[^\s'"<>`]/.test(text[end + 3] ?? " ");
|
|
96
|
+
if (!schemed && !run[0].includes("."))
|
|
97
|
+
continue;
|
|
98
|
+
let first = end;
|
|
99
|
+
if (schemed) {
|
|
100
|
+
LETTER_START.lastIndex = 1;
|
|
101
|
+
first = /[a-z]/i.test(run[0][0]) ? start : start + (LETTER_START.exec(run[0])?.index ?? run[0].length);
|
|
102
|
+
}
|
|
103
|
+
let span = null;
|
|
104
|
+
// A link without a scheme can start before the one with a scheme.
|
|
105
|
+
for (let i = start, noHost = start; !span;) {
|
|
106
|
+
LINK_START.lastIndex = i;
|
|
107
|
+
const p = LINK_START.exec(text)?.index;
|
|
108
|
+
if (p === undefined || p >= first)
|
|
109
|
+
break;
|
|
110
|
+
if (p >= noHost) {
|
|
111
|
+
const len = at(BARE, text, p);
|
|
112
|
+
if (len > 0)
|
|
113
|
+
span = [p, p + len];
|
|
114
|
+
else
|
|
115
|
+
noHost = p + at(HOST_RUN, text, p);
|
|
116
|
+
}
|
|
117
|
+
i = Math.max(p + 1, noHost);
|
|
118
|
+
}
|
|
119
|
+
if (!span && first < end)
|
|
120
|
+
span = [first, first + at(SCHEMED, text, first)];
|
|
121
|
+
if (span) {
|
|
122
|
+
spans.push(span);
|
|
123
|
+
SCHEME_RUN.lastIndex = span[1];
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return spans;
|
|
127
|
+
}
|
|
128
|
+
/** `text` with each link replaced by a space. */
|
|
129
|
+
function withoutLinks(text) {
|
|
130
|
+
let out = "";
|
|
131
|
+
let from = 0;
|
|
132
|
+
for (const [a, b] of linkSpans(text)) {
|
|
133
|
+
out += `${text.slice(from, a)} `;
|
|
134
|
+
from = b;
|
|
135
|
+
}
|
|
136
|
+
return out + text.slice(from);
|
|
137
|
+
}
|
|
138
|
+
/** A login in a link: `postgres://user:pass@host`. */
|
|
139
|
+
const URL_LOGIN = /[a-z][a-z0-9+.-]*:\/\/[^\s:/@'"]+:([^\s@/'"]+)@([^\s/'"?#]+)/iy;
|
|
140
|
+
/**
|
|
141
|
+
* Each login in a link, in order: what URL_LOGIN finds tried after every word
|
|
142
|
+
* boundary. It starts in the run of scheme characters before a `://`, and
|
|
143
|
+
* every letter after a non-word character in that run gives the same answer,
|
|
144
|
+
* so only the first is tried and each run is read once.
|
|
145
|
+
*/
|
|
146
|
+
function* urlLogins(text) {
|
|
147
|
+
let after = 0;
|
|
148
|
+
for (let c = text.indexOf("://"); c >= 0; c = text.indexOf("://", c + 1)) {
|
|
149
|
+
let p = c;
|
|
150
|
+
while (p > after && /[a-z0-9+.-]/i.test(text[p - 1]))
|
|
151
|
+
p--;
|
|
152
|
+
while (p < c && !(/[a-z]/i.test(text[p]) && (p === 0 || !/\w/.test(text[p - 1]))))
|
|
153
|
+
p++;
|
|
154
|
+
if (p === c)
|
|
155
|
+
continue;
|
|
156
|
+
URL_LOGIN.lastIndex = p;
|
|
157
|
+
const hit = URL_LOGIN.exec(text);
|
|
158
|
+
if (hit) {
|
|
159
|
+
yield hit;
|
|
160
|
+
after = URL_LOGIN.lastIndex;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/** Query keys that carry a key or a signature (`token=`, `api_key=` and the like are caught by name below). */
|
|
165
|
+
const KEYED = /[?&#](?:key|sig|signature|x-amz-signature|x-goog-signature|auth)=([^&#\s'"]+)/gi;
|
|
166
|
+
/**
|
|
167
|
+
* A macOS temp folder's own part: `/var/folders/<2>/<random>/` (lowercase, digits, `_`), then `T`, `C` or `0`.
|
|
168
|
+
* Taken out with its last slash before the random-string checks (D62): what follows is read on its own, so a
|
|
169
|
+
* random name in the folder is still caught.
|
|
170
|
+
*/
|
|
171
|
+
const MAC_TEMP = /(?:\/private)?\/var\/folders\/[a-z0-9_+-]{2}\/[a-z0-9_+-]{20,40}(?:\/[A-Z0-9])?(?:\/|(?=[\s'"`;|&)<>:,]|$))/g;
|
|
172
|
+
/**
|
|
173
|
+
* A JWT: `eyJ….eyJ….…`, each part at least 10 characters. A part ends at a dot,
|
|
174
|
+
* so the first part is the rest of its run; only the first `eyJ` in a run is
|
|
175
|
+
* looked at (a later one has less of the run after it), as with DIGIT_KEYS.
|
|
176
|
+
*/
|
|
177
|
+
function jwt(text) {
|
|
178
|
+
const rest = /\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10}/y;
|
|
179
|
+
for (const m of text.matchAll(/\beyJ[A-Za-z0-9_-]*/g)) {
|
|
180
|
+
if (m[0].length < 13)
|
|
181
|
+
continue;
|
|
182
|
+
rest.lastIndex = m.index + m[0].length;
|
|
183
|
+
if (rest.test(text))
|
|
184
|
+
return true;
|
|
185
|
+
}
|
|
186
|
+
return false;
|
|
187
|
+
}
|
|
188
|
+
const UUID = /\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b/gi;
|
|
189
|
+
/**
|
|
190
|
+
* Where a value stands in for the secret or reads it at run time: the safe way
|
|
191
|
+
* to write one down. `$TOKEN`, `${TOKEN}`, `$(gh auth token)`, `${#TOKEN}`,
|
|
192
|
+
* backticks, `%s` formats, `<token>`, `***`.
|
|
193
|
+
*/
|
|
194
|
+
const PLACEHOLDER = /^(?:\$|`|%|\{|<|\*{3}|x{3,}|\.{3}|\[redacted\]|changeme$|password$|secret$|your[_-]|example)/i;
|
|
195
|
+
/** A value that says it is a stand-in: `sb_secret_placeholder`, `fake-key-for-tests`, `nn...`. */
|
|
196
|
+
const STAND_IN = /placeholder|example|dummy|redacted|changeme|(?:^|[_-])(?:fake|test|invalid|wrong|bogus)(?:[_-]|$)|(?:\.{3}|…)$/i;
|
|
197
|
+
/** A pattern, not a value: `(.+)`, `[^&]*`, `.*`, `\d+` (a grep or sed that looks for secrets). */
|
|
198
|
+
const PATTERN = /^[()[\]|\\^]|\.[*+?{]|\[\^|\\[dswbDSW]|\(\?|\]\{\d/;
|
|
199
|
+
/**
|
|
200
|
+
* …or a bracket with a range in it (`[a-z0-9]`). Only the first `[` after a
|
|
201
|
+
* `]` is looked at: a later one before the same `]` holds less of it.
|
|
202
|
+
*/
|
|
203
|
+
function bracketRange(v) {
|
|
204
|
+
for (const m of v.matchAll(/\[([^\]]*)(\]?)/g))
|
|
205
|
+
if (m[2] && /\w-\w/.test(m[1]))
|
|
206
|
+
return true;
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
/** Another variable's name: `VENDOR_API_KEY`. */
|
|
210
|
+
const ENV_NAME = /^[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)+$/;
|
|
211
|
+
const LOCAL_HOST = /^(?:localhost|127\.0\.0\.1|0\.0\.0\.0|\[::1\]|host\.docker\.internal)(?::\d+)?$/i;
|
|
212
|
+
/**
|
|
213
|
+
* Names that hold a secret: `TRAIL_API_KEY`, `DB_PASSWORD`, `client_secret`,
|
|
214
|
+
* `token`. A name starts where its run of name characters starts: that is
|
|
215
|
+
* where every match of the unanchored pattern began, and starting at each
|
|
216
|
+
* position of a long run made it quadratic.
|
|
217
|
+
*/
|
|
218
|
+
const SECRET_NAME = /(?<![A-Za-z0-9_.-])[A-Za-z0-9_.-]*(?:password|passwd|pwd|secret|token|api[_-]?key|private[_-]?key|access[_-]?key|auth[_-]?key)[A-Za-z0-9_-]*/gi;
|
|
219
|
+
/** …unless the name is about the secret rather than holding it: `MAX_TOKENS`, `TOKEN_TTL`, `API_KEY_ID`. */
|
|
220
|
+
const ABOUT_A_SECRET = /tokens\b|tokeniz|(?:^|[_.-])(?:max|min|num)[_-]|[_.-](?:ttl|expiry|expires?|expiration|length|len|count|limit|max|min|size|timeout|url|uri|path|file|dir|name|type|header|endpoint|id|env|var|field|policy|rotation|days|hours|seconds)$/i;
|
|
221
|
+
/** …in camelCase: `APIKeyID`, `tokenUrl`, `secretName`. */
|
|
222
|
+
const ABOUT_A_SECRET_CAMEL = /[a-z0-9](?:Id|ID|Ids|IDs|Name|Url|URL|Uri|URI|Path|File|Type|Header|Env|Length|Count|Ttl|TTL|Expiry|Field)$/;
|
|
223
|
+
/** `= value` or `: value`, not `==`, `===` or `::`. The value ends where code or a query would go on. */
|
|
224
|
+
const ASSIGNED = /^['"]?\s*(?::(?!:)|=(?!=))\s*['"]?([^\s'",;}\\)\]&>]{1,257})/;
|
|
225
|
+
/**
|
|
226
|
+
* An assigned value is judged by its first 256 characters. A value can hold the
|
|
227
|
+
* next name (`token=/a/token=/b/…`), so reading each one to its end is
|
|
228
|
+
* quadratic. The cut is marked with a character no check accepts, so a cut
|
|
229
|
+
* value is never plainer than the whole one: what ends there (`…_fake`,
|
|
230
|
+
* `ENV_NAME`) does not count.
|
|
231
|
+
*/
|
|
232
|
+
const MAX_VALUE = 256;
|
|
233
|
+
const cutValue = (v) => (v.length > MAX_VALUE ? `${v.slice(0, MAX_VALUE)}\u0000` : v);
|
|
234
|
+
const SECRET_FLAG = /(?:^|\s)--?(?:password|passwd|pass|token|api-?key|secret|client-secret)(?:=|\s+)['"]?([^\s'"]+)/gi;
|
|
235
|
+
/**
|
|
236
|
+
* A value too plain to be a secret: a placeholder, a word, a reference, a path.
|
|
237
|
+
* The checks read from the start first; the ones that look anywhere in the
|
|
238
|
+
* value come last.
|
|
239
|
+
*/
|
|
240
|
+
function plainValue(v) {
|
|
241
|
+
if (v.length < 4 || PLACEHOLDER.test(v) || ENV_NAME.test(v) || /^(?:\/|~\/|\.\.?\/)/.test(v))
|
|
242
|
+
return true;
|
|
243
|
+
// "token: always in the keychain" is advice, not a token; `{ API_KEY: _omit }` renames it.
|
|
244
|
+
if (/^_?[A-Za-z]+$/.test(v) && v.length < 16)
|
|
245
|
+
return true;
|
|
246
|
+
// process.env.API_KEY, os.environ[…], settings.token, z.string(), crypto.randomUUID(), secretFor(…), "…".length
|
|
247
|
+
if (/^[A-Za-z_]\w*(?:\.\w+)+[[(]?$|^[A-Za-z_]\w*(?:\.\w+)*[[(]|^\.[A-Za-z_]\w*$/.test(v))
|
|
248
|
+
return true;
|
|
249
|
+
return STAND_IN.test(v) || PATTERN.test(v) || bracketRange(v);
|
|
250
|
+
}
|
|
251
|
+
/** Random-looking: letters and digits in short pieces, not words. `getS3BucketPolicy` is words. */
|
|
252
|
+
function looksRandom(run) {
|
|
253
|
+
if (!/[A-Z]/.test(run) || !/[a-z]/.test(run) || !/\d/.test(run))
|
|
254
|
+
return false;
|
|
255
|
+
const pieces = run.match(/[A-Z]?[a-z]+|[A-Z]+(?![a-z])|\d+/g) ?? [];
|
|
256
|
+
const avg = pieces.reduce((n, p) => n + p.length, 0) / Math.max(1, pieces.length);
|
|
257
|
+
return avg < 2.5;
|
|
258
|
+
}
|
|
259
|
+
/** `src/server/routes/v1/Admin.ts`: words between slashes, not an opaque blob. */
|
|
260
|
+
function looksLikePath(tok) {
|
|
261
|
+
const segs = tok.replace(/^\.{0,2}\//, "").replace(/\/$/, "").split("/");
|
|
262
|
+
return segs.length >= 2 && segs.every((seg) => seg.length > 0 && seg.length <= 40 && (seg.match(/[A-Z]/g) ?? []).length <= 2);
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Object ids with the same shape as a vendor key, which APIs hand out in the
|
|
266
|
+
* open: Stripe's `cus_`/`price_`, Vercel's `team_`/`prj_`, the model APIs'
|
|
267
|
+
* `msg_`/`file-`. A secret under one of these names is still caught by its
|
|
268
|
+
* name (`API_KEY=…`).
|
|
269
|
+
*/
|
|
270
|
+
const OPEN_ID_PREFIXES = new Set([
|
|
271
|
+
"acct", "batch", "ch", "cus", "dpl", "evt", "file", "in", "msg", "org", "pay", "pdt", "pi", "pm", "po", "price", "prj", "prod", "re", "req", "run", "seti", "sub", "team", "toolu", "txn", "user",
|
|
272
|
+
]);
|
|
273
|
+
/** A vendor key: a short lowercase prefix, then a long random body (`ab_…`, `abc-…`, or a prefix glued to hex). */
|
|
274
|
+
function vendorKey(text) {
|
|
275
|
+
for (const m of text.matchAll(/\b([a-z]{2,5})([_-]?)([A-Za-z0-9]+)\b/g)) {
|
|
276
|
+
const [, prefix, sep, body] = m;
|
|
277
|
+
if (sep && OPEN_ID_PREFIXES.has(prefix))
|
|
278
|
+
continue;
|
|
279
|
+
const mixed = (body.match(/\d/g) ?? []).length >= 2 && (body.match(/[A-Za-z]/g) ?? []).length >= 2;
|
|
280
|
+
if (sep === "_" && body.length >= 16 && mixed)
|
|
281
|
+
return true;
|
|
282
|
+
if (sep === "-" && body.length >= 24 && mixed)
|
|
283
|
+
return true;
|
|
284
|
+
// `ab` + 64 hex: the prefix has a letter hex doesn't, so it isn't a digest.
|
|
285
|
+
if (sep === "" && body.length >= 32 && /[g-z]/.test(prefix) && /^[0-9a-f]+$/.test(body))
|
|
286
|
+
return true;
|
|
287
|
+
}
|
|
288
|
+
return false;
|
|
289
|
+
}
|
|
290
|
+
/** Why `text` can't be saved as it is, or null when it holds no secret. */
|
|
291
|
+
export function secretReason(text) {
|
|
292
|
+
if (typeof text !== "string" || !text)
|
|
293
|
+
return null;
|
|
294
|
+
if (PRIVATE_KEY.test(text))
|
|
295
|
+
return "a private key";
|
|
296
|
+
if (digitKey(text) || PROVIDER_KEYS.some((re) => re.test(text)))
|
|
297
|
+
return "an API key";
|
|
298
|
+
if (jwt(text))
|
|
299
|
+
return "a signed token (JWT)";
|
|
300
|
+
// Ids are ids: a UUID is judged only where it is assigned to a secret's name, below.
|
|
301
|
+
const noIds = text.replace(UUID, " ").replace(MAC_TEMP, " ");
|
|
302
|
+
if (vendorKey(noIds))
|
|
303
|
+
return "an API key";
|
|
304
|
+
if (WEBHOOKS.some((re) => re.test(text)))
|
|
305
|
+
return "a webhook link";
|
|
306
|
+
for (const [a, b] of linkSpans(text)) {
|
|
307
|
+
const link = text.slice(a, b);
|
|
308
|
+
for (const m of link.matchAll(KEYED)) {
|
|
309
|
+
if (m[1].length >= 8 && !plainValue(m[1]))
|
|
310
|
+
return "a key in a link";
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
for (const m of text.matchAll(/\bbearer\s+([^\s'"]+)/gi)) {
|
|
314
|
+
if (!plainValue(m[1]) && m[1].length >= 8)
|
|
315
|
+
return "a bearer token";
|
|
316
|
+
}
|
|
317
|
+
if (/\bauthorization:\s*basic\s+[A-Za-z0-9+/=]{8,}/i.test(text))
|
|
318
|
+
return "a login in an Authorization header";
|
|
319
|
+
// postgres://user:pass@host, https://user:pass@host
|
|
320
|
+
for (const m of urlLogins(text)) {
|
|
321
|
+
if (!PLACEHOLDER.test(m[1]) && !LOCAL_HOST.test(m[2]))
|
|
322
|
+
return "a password in a URL";
|
|
323
|
+
}
|
|
324
|
+
// curl -u user:pass, --user=user:pass; not `date -u +%H:%M` or `docker run -u 1000:1000`.
|
|
325
|
+
for (const m of text.matchAll(/(?:^|\s)(?:-u|--user)[\s=]+['"]?([A-Za-z0-9_][\w.@-]*):([^\s'"]+)/g)) {
|
|
326
|
+
if (/^\d+$/.test(m[1]) && /^\d+$/.test(m[2]))
|
|
327
|
+
continue;
|
|
328
|
+
if (!PLACEHOLDER.test(m[2]) && !STAND_IN.test(m[2]))
|
|
329
|
+
return "a password in a command";
|
|
330
|
+
}
|
|
331
|
+
// DB_PASSWORD=…, TRAIL_API_KEY: …, "client_secret": "…"
|
|
332
|
+
for (const m of text.matchAll(SECRET_NAME)) {
|
|
333
|
+
// `${API_KEY:?set it}` reads a variable; it assigns nothing.
|
|
334
|
+
if (ABOUT_A_SECRET.test(m[0]) || ABOUT_A_SECRET_CAMEL.test(m[0]) || /[{$]/.test(text[m.index - 1] ?? ""))
|
|
335
|
+
continue;
|
|
336
|
+
const value = ASSIGNED.exec(text.slice(m.index + m[0].length))?.[1];
|
|
337
|
+
if (value && !plainValue(cutValue(value)))
|
|
338
|
+
return "a password or token";
|
|
339
|
+
}
|
|
340
|
+
for (const m of text.matchAll(SECRET_FLAG)) {
|
|
341
|
+
if (!plainValue(m[1]))
|
|
342
|
+
return "a password or token";
|
|
343
|
+
}
|
|
344
|
+
// Long random strings, outside links: a link's path and ids (deployments,
|
|
345
|
+
// documents, uploads, click ids) look random and aren't secrets; a link that
|
|
346
|
+
// carries one was judged above, by its query key or its host.
|
|
347
|
+
for (const run of withoutLinks(noIds).match(/[A-Za-z0-9+/_=.-]{32,}/g) ?? []) {
|
|
348
|
+
if (looksLikePath(run) || /^[A-Za-z_][\w-]*(?:\.[A-Za-z_][\w-]*)+$/.test(run))
|
|
349
|
+
continue;
|
|
350
|
+
// `SHA=<digest>`: the name and the value apart; base64 padding stays on its value.
|
|
351
|
+
for (const part of run.split(/=+(?=.)/)) {
|
|
352
|
+
// Hex digests, and ids built on one (`AC` + 32 hex), have one case only.
|
|
353
|
+
if (part.length < 32 || /^[A-Za-z]{0,5}[_-]?(?:[0-9a-f]+|[0-9A-F]+)=*$/.test(part))
|
|
354
|
+
continue;
|
|
355
|
+
const bare = /^[A-Za-z0-9]+$/.test(part);
|
|
356
|
+
if ((bare || part.length >= 40) && looksRandom(part))
|
|
357
|
+
return "a long secret-looking string";
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
return null;
|
|
361
|
+
}
|
|
362
|
+
//# sourceMappingURL=secrets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../src/notes/secrets.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,6 +7,8 @@ export interface SessionCost {
|
|
|
7
7
|
countedFrom: number;
|
|
8
8
|
/** Files the agent edited or wrote in that stretch, absolute, in order. */
|
|
9
9
|
edited: string[];
|
|
10
|
+
/** Files the agent opened with Read in that stretch, absolute, in order. */
|
|
11
|
+
read: string[];
|
|
10
12
|
}
|
|
11
13
|
/** With nothing in the transcript naming what the note is about, at most this much active time counts. */
|
|
12
14
|
export declare const FALLBACK_ACTIVE_MS: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-cost.d.ts","sourceRoot":"","sources":["../../src/notes/session-cost.ts"],"names":[],"mappings":"AA2BA,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,SAAS,EAAE,MAAM,CAAC;IAClB,0FAA0F;IAC1F,WAAW,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,MAAM,EAAE,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"session-cost.d.ts","sourceRoot":"","sources":["../../src/notes/session-cost.ts"],"names":[],"mappings":"AA2BA,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,SAAS,EAAE,MAAM,CAAC;IAClB,0FAA0F;IAC1F,WAAW,EAAE,MAAM,CAAC;IACpB,2EAA2E;IAC3E,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,4EAA4E;IAC5E,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAGD,0GAA0G;AAC1G,eAAO,MAAM,kBAAkB,QAAiB,CAAC;AAIjD,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,MAAkB,GAAG,MAAM,CAE/E;AAeD,oEAAoE;AACpE,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,SAAa,GAAG,MAAM,GAAG,IAAI,CAmB9F;AAoBD,eAAO,MAAM,SAAS,QAAoF,CAAC;AAK3G;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,GAAE,MAAM,EAAO,GAAG,MAAM,EAAE,CAcvE;AAgDD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,SAAa,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,WAAW,GAAG,IAAI,CAyEvG;AAgBD,yFAAyF;AACzF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,SAAa,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,WAAW,GAAG,IAAI,CAQtH"}
|
|
@@ -229,17 +229,22 @@ export function costFromTranscript(text, now = Date.now(), terms) {
|
|
|
229
229
|
tokens += (u.input_tokens ?? 0) + (u.cache_creation_input_tokens ?? 0) + (u.output_tokens ?? 0);
|
|
230
230
|
}
|
|
231
231
|
const edited = [];
|
|
232
|
+
const read = [];
|
|
232
233
|
for (const e of after) {
|
|
233
234
|
for (const b of blocks(e)) {
|
|
234
|
-
if (b.type !== "tool_use"
|
|
235
|
+
if (b.type !== "tool_use")
|
|
235
236
|
continue;
|
|
236
237
|
const input = (b.input ?? {});
|
|
237
238
|
const file = typeof input.file_path === "string" ? input.file_path : input.notebook_path;
|
|
238
|
-
if (typeof file
|
|
239
|
+
if (typeof file !== "string" || !file)
|
|
240
|
+
continue;
|
|
241
|
+
if (EDIT_TOOLS.has(String(b.name)) && !edited.includes(file))
|
|
239
242
|
edited.push(file);
|
|
243
|
+
else if (b.name === "Read" && !read.includes(file))
|
|
244
|
+
read.push(file);
|
|
240
245
|
}
|
|
241
246
|
}
|
|
242
|
-
return { minutes: Math.max(1, Math.round(activeMs / 60_000)), tokens, startedAt, countedFrom: times[0], edited };
|
|
247
|
+
return { minutes: Math.max(1, Math.round(activeMs / 60_000)), tokens, startedAt, countedFrom: times[0], edited, read };
|
|
243
248
|
}
|
|
244
249
|
/** The entries in the last `budgetMs` of active time before `now`, oldest first. */
|
|
245
250
|
function lastActive(entries, now, budgetMs) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-cost.js","sourceRoot":"","sources":["../../src/notes/session-cost.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC1E,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"session-cost.js","sourceRoot":"","sources":["../../src/notes/session-cost.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export interface NoteTarget {
|
|
2
|
+
/** A folder in the repo the note goes to. */
|
|
3
|
+
dir: string;
|
|
4
|
+
/** What the session touched there, relative to the top of that checkout. */
|
|
5
|
+
touches: string[];
|
|
6
|
+
/** What it only read there, same form; set when the session said what it read. */
|
|
7
|
+
read?: string[];
|
|
8
|
+
}
|
|
9
|
+
/** Most files one note lists per repo, and the longest path it may list (a note's reader keeps the same caps). */
|
|
10
|
+
export declare const TOUCH_LIMIT = 10;
|
|
11
|
+
export declare const TOUCH_CHARS = 300;
|
|
12
|
+
/**
|
|
13
|
+
* Which repos a session's note belongs in, and what it touched in each.
|
|
14
|
+
*
|
|
15
|
+
* The repo the note was saved from gets the files it has uncommitted or
|
|
16
|
+
* committed since `since`. Every other repo the session edited (`edited`:
|
|
17
|
+
* absolute paths, from the agent's transcript) gets the note too, with its
|
|
18
|
+
* own files, so a session that changed a backend and the library it calls
|
|
19
|
+
* leaves a note in both. Saved from a folder that holds several repos, the
|
|
20
|
+
* note goes to each repo the session changed, or stays with the folder when
|
|
21
|
+
* it changed none. Two worktrees of one repo are one repo.
|
|
22
|
+
*
|
|
23
|
+
* `session.read`, when the transcript was found: the files the session opened.
|
|
24
|
+
* Then the transcript says what was touched, and the working tree's other
|
|
25
|
+
* uncommitted files, there before the session began, are left out.
|
|
26
|
+
*/
|
|
27
|
+
export declare function noteTargets(dir: string, edited?: string[], since?: number, session?: {
|
|
28
|
+
read: string[];
|
|
29
|
+
}): NoteTarget[];
|
|
30
|
+
/**
|
|
31
|
+
* Files of the checkout at `dir` that a note's text names by path. A session
|
|
32
|
+
* that only read code edits nothing, so without these its note would touch no
|
|
33
|
+
* file, and nothing that looks a note up by file (`trail check`, the ranked
|
|
34
|
+
* search) would ever find it.
|
|
35
|
+
*/
|
|
36
|
+
export declare function mentionedFiles(dir: string, body: string): string[];
|
|
37
|
+
//# sourceMappingURL=targets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"targets.d.ts","sourceRoot":"","sources":["../../src/notes/targets.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,UAAU;IACzB,6CAA6C;IAC7C,GAAG,EAAE,MAAM,CAAC;IACZ,4EAA4E;IAC5E,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,kFAAkF;IAClF,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,kHAAkH;AAClH,eAAO,MAAM,WAAW,KAAK,CAAC;AAC9B,eAAO,MAAM,WAAW,MAAM,CAAC;AAE/B;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,EAAO,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;IAAE,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,UAAU,EAAE,CA6C1H;AAKD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CASlE"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a session's learning goes: the repos it changed, with the files it
|
|
3
|
+
* touched in each, and the files its text names by path.
|
|
4
|
+
*/
|
|
5
|
+
import { existsSync } from "node:fs";
|
|
6
|
+
import { homedir } from "node:os";
|
|
7
|
+
import { dirname, join, relative, sep } from "node:path";
|
|
8
|
+
import { changedFiles, ownPath } from "./git-facts.js";
|
|
9
|
+
import { checkoutRoot, childCheckouts, repoPlace } from "./home.js";
|
|
10
|
+
/** Most files one note lists per repo, and the longest path it may list (a note's reader keeps the same caps). */
|
|
11
|
+
export const TOUCH_LIMIT = 10;
|
|
12
|
+
export const TOUCH_CHARS = 300;
|
|
13
|
+
/**
|
|
14
|
+
* Which repos a session's note belongs in, and what it touched in each.
|
|
15
|
+
*
|
|
16
|
+
* The repo the note was saved from gets the files it has uncommitted or
|
|
17
|
+
* committed since `since`. Every other repo the session edited (`edited`:
|
|
18
|
+
* absolute paths, from the agent's transcript) gets the note too, with its
|
|
19
|
+
* own files, so a session that changed a backend and the library it calls
|
|
20
|
+
* leaves a note in both. Saved from a folder that holds several repos, the
|
|
21
|
+
* note goes to each repo the session changed, or stays with the folder when
|
|
22
|
+
* it changed none. Two worktrees of one repo are one repo.
|
|
23
|
+
*
|
|
24
|
+
* `session.read`, when the transcript was found: the files the session opened.
|
|
25
|
+
* Then the transcript says what was touched, and the working tree's other
|
|
26
|
+
* uncommitted files, there before the session began, are left out.
|
|
27
|
+
*/
|
|
28
|
+
export function noteTargets(dir, edited = [], since, session) {
|
|
29
|
+
const here = repoPlace(dir);
|
|
30
|
+
const byKey = new Map();
|
|
31
|
+
const entryFor = (checkout) => {
|
|
32
|
+
const key = repoPlace(checkout).key;
|
|
33
|
+
const entry = byKey.get(key) ?? { dir: checkout, files: [], read: [] };
|
|
34
|
+
byKey.set(key, entry);
|
|
35
|
+
return entry;
|
|
36
|
+
};
|
|
37
|
+
const add = (checkout, files) => {
|
|
38
|
+
const entry = entryFor(checkout);
|
|
39
|
+
for (const f of files)
|
|
40
|
+
if (f && !ownPath(f) && !entry.files.includes(f))
|
|
41
|
+
entry.files.push(f);
|
|
42
|
+
};
|
|
43
|
+
const uncommitted = !session;
|
|
44
|
+
if (here.git)
|
|
45
|
+
add(here.checkout, changedFiles(here.checkout, since, TOUCH_LIMIT, uncommitted));
|
|
46
|
+
else if (edited.length === 0)
|
|
47
|
+
for (const c of childCheckouts(here.checkout))
|
|
48
|
+
add(c, changedFiles(c, since, TOUCH_LIMIT, uncommitted));
|
|
49
|
+
// The agent's own files (memory, plans, scratch under ~/.claude) aren't what a note is about.
|
|
50
|
+
const agentFiles = join(homedir(), ".claude") + sep;
|
|
51
|
+
const place = (f) => {
|
|
52
|
+
if (f.startsWith(agentFiles))
|
|
53
|
+
return null;
|
|
54
|
+
const top = checkoutRoot(dirname(f));
|
|
55
|
+
if (top)
|
|
56
|
+
return [top, relative(top, f).split(sep).join("/")];
|
|
57
|
+
if (!here.git && !relative(here.checkout, f).startsWith(".."))
|
|
58
|
+
return [here.checkout, relative(here.checkout, f).split(sep).join("/")];
|
|
59
|
+
return null;
|
|
60
|
+
};
|
|
61
|
+
for (const f of edited) {
|
|
62
|
+
const at = place(f);
|
|
63
|
+
if (at)
|
|
64
|
+
add(at[0], [at[1]]);
|
|
65
|
+
}
|
|
66
|
+
for (const f of session?.read ?? []) {
|
|
67
|
+
const at = place(f);
|
|
68
|
+
if (!at || ownPath(at[1]))
|
|
69
|
+
continue;
|
|
70
|
+
const entry = byKey.get(repoPlace(at[0]).key);
|
|
71
|
+
// Reads only add to a repo the note already goes to: opening a file elsewhere doesn't make the note about that repo.
|
|
72
|
+
if (entry && !entry.files.includes(at[1]) && !entry.read.includes(at[1]))
|
|
73
|
+
entry.read.push(at[1]);
|
|
74
|
+
else if (!entry && repoPlace(at[0]).key === here.key)
|
|
75
|
+
entryFor(here.checkout).read.push(at[1]);
|
|
76
|
+
}
|
|
77
|
+
const out = [...byKey.entries()]
|
|
78
|
+
.filter(([key, e]) => e.files.length > 0 || key === here.key)
|
|
79
|
+
.map(([, e]) => ({ dir: e.dir, touches: e.files.slice(0, TOUCH_LIMIT), ...(session ? { read: e.read.slice(0, TOUCH_LIMIT) } : {}) }));
|
|
80
|
+
// The repo it was saved from first; a folder of repos only when nothing else was touched.
|
|
81
|
+
out.sort((a, b) => Number(repoPlace(b.dir).key === here.key) - Number(repoPlace(a.dir).key === here.key));
|
|
82
|
+
const touched = out.filter((t) => t.touches.length > 0);
|
|
83
|
+
if (!here.git && touched.length > 0)
|
|
84
|
+
return touched;
|
|
85
|
+
return out.length ? out : [{ dir: here.checkout, touches: [] }];
|
|
86
|
+
}
|
|
87
|
+
/** A path-shaped word in a note: `client.go`, `src/a/b.ts:12-30`, `x.go#Fn`. */
|
|
88
|
+
const MENTION = /(?:^|[\s(`'"\[])((?:[\w.-]+\/)*[\w-][\w.-]*\.[A-Za-z][A-Za-z0-9]{0,5})(?=$|[\s:#)`'",.;\]])/gm;
|
|
89
|
+
/**
|
|
90
|
+
* Files of the checkout at `dir` that a note's text names by path. A session
|
|
91
|
+
* that only read code edits nothing, so without these its note would touch no
|
|
92
|
+
* file, and nothing that looks a note up by file (`trail check`, the ranked
|
|
93
|
+
* search) would ever find it.
|
|
94
|
+
*/
|
|
95
|
+
export function mentionedFiles(dir, body) {
|
|
96
|
+
const out = [];
|
|
97
|
+
for (const m of body.matchAll(MENTION)) {
|
|
98
|
+
const f = m[1].replace(/^\.\//, "");
|
|
99
|
+
if (out.includes(f) || ownPath(f) || f.startsWith(".."))
|
|
100
|
+
continue;
|
|
101
|
+
if (existsSync(join(dir, f)))
|
|
102
|
+
out.push(f);
|
|
103
|
+
if (out.length >= TOUCH_LIMIT)
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
return out;
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=targets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"targets.js","sourceRoot":"","sources":["../../src/notes/targets.ts"],"names":[],"mappings":"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"}
|