@nanonets/graft 0.23.1 → 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.js +1 -1
- package/dist/claude/format.js.map +1 -1
- package/dist/claude/hooks.d.ts +0 -18
- package/dist/claude/hooks.d.ts.map +1 -1
- package/dist/claude/hooks.js +24 -77
- 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 +10 -4
- 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 +131 -38
- 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/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 +2 -0
- package/dist/notes/git-facts.d.ts.map +1 -1
- package/dist/notes/git-facts.js +6 -0
- 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 -85
- package/dist/notes/notes.d.ts.map +1 -1
- package/dist/notes/notes.js +69 -254
- 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/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/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,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What `trail note` checks before it saves a learning for the team: that a
|
|
3
|
+
* teammate's Claude would act differently for reading it. A learning that
|
|
4
|
+
* names no code never reaches anyone (learnings arrive when Claude opens the
|
|
5
|
+
* files they name), one about setting trail up isn't about the repo, status
|
|
6
|
+
* ("PR is open") is wrong by next week, a decision without its reason can't be
|
|
7
|
+
* weighed, and a second copy of a learning buries the first.
|
|
8
|
+
*
|
|
9
|
+
* Each check that fails says how to fix it, and the agent saves again. A long
|
|
10
|
+
* learning only gets a warning. `--anyway` saves past the checks, for when
|
|
11
|
+
* one of them is wrong.
|
|
12
|
+
*/
|
|
13
|
+
import { execFileSync } from "node:child_process";
|
|
14
|
+
import { existsSync } from "node:fs";
|
|
15
|
+
import { join } from "node:path";
|
|
16
|
+
import { trailOwnPath } from "./git-facts.js";
|
|
17
|
+
import { noteName, notePlace, SECTIONS, shortDate } from "./notes.js";
|
|
18
|
+
/** Past this many words a learning gets skimmed: a warning, never a refusal. */
|
|
19
|
+
export const LONG_NOTE_WORDS = 250;
|
|
20
|
+
/** Setting trail (or graft) up, said in a title or body. */
|
|
21
|
+
const SETUP_TALK = /\b(?:trail|graft)\b[^.\n]{0,40}\b(?:init|setup|set up|install(?:ed|ing)?|hooks?|wiring|wired)\b|\b(?:setting up|set up|install(?:ed|ing)?|wiring)\b[^.\n]{0,20}\b(?:trail|graft)\b/i;
|
|
22
|
+
/** Status: true when written, wrong a week later. */
|
|
23
|
+
const STATUS = [
|
|
24
|
+
/\b(?:PR|pull request|MR)\s*#?\d*\s+(?:is|was|got|has been|now)\s+(?:open|opened|merged|closed|approved|up|green|fixed|pushed)\b/i,
|
|
25
|
+
/\bnot (?:merged|pushed|released|published|deployed|reviewed) yet\b/i,
|
|
26
|
+
/\bpushed and not merged\b/i,
|
|
27
|
+
/\b(?:today|tomorrow|yesterday|tonight|this (?:morning|afternoon|evening|week))\b/i,
|
|
28
|
+
/\b(?:waiting on|blocked on|still open|awaiting review|in review)\b/i,
|
|
29
|
+
];
|
|
30
|
+
/** A reason: a cause, an error, a number, or a word that brings one. */
|
|
31
|
+
const WHY = /\b(?:because|since|so that|so|otherwise|or else|else|due to|caused?|causes|causing|means|meant|breaks?|broke|broken|fails?|failed|failing|errors?|exceptions?|crash(?:es|ed)?|hangs?|leaks?|slow(?:er)?|faster|cheaper|costs?|instead|to avoid|to keep|to stop|to prevent|in order to|unless|only if|rejects?|refuses?|blocks?|loses?|lost|drops?|wipes?|overwrites?|but|though|doubles?|twice|half|latency|memory|wrong|incorrect|missing|stale|races?|timeouts?|times out|deadlocks?|conflicts?|regress(?:es|ion)?|can't|cannot|won't|doesn't|don't|isn't|aren't|never)\b|\d|["“][^"”]{4,}["”]|→|=>/i;
|
|
32
|
+
const STOP = new Set("the and for with from that this what when where which into does how why are was were not but you your our out its it's can should would could about after before over under use using used fix find make".split(" "));
|
|
33
|
+
function words(s) {
|
|
34
|
+
return new Set(s.toLowerCase().split(/[^a-z0-9_]+/).filter((t) => t.length >= 3 && !STOP.has(t)));
|
|
35
|
+
}
|
|
36
|
+
function jaccard(a, b) {
|
|
37
|
+
if (!a.size || !b.size)
|
|
38
|
+
return 0;
|
|
39
|
+
let both = 0;
|
|
40
|
+
for (const t of a)
|
|
41
|
+
if (b.has(t))
|
|
42
|
+
both++;
|
|
43
|
+
return both / (a.size + b.size - both);
|
|
44
|
+
}
|
|
45
|
+
/** The body without fenced code, which quotes errors and commands rather than saying status. */
|
|
46
|
+
function prose(body) {
|
|
47
|
+
return body.replace(/```[\s\S]*?```/g, "");
|
|
48
|
+
}
|
|
49
|
+
/** The lines a reason belongs on: under Decided and Tried and ruled out, or the whole body when it has neither. */
|
|
50
|
+
function decisionLines(body) {
|
|
51
|
+
const lines = prose(body).split(/\r?\n/);
|
|
52
|
+
const wanted = new Set([SECTIONS[0].heading.toLowerCase(), SECTIONS[1].heading.toLowerCase()]);
|
|
53
|
+
const out = [];
|
|
54
|
+
let section = null;
|
|
55
|
+
let sawSection = false;
|
|
56
|
+
for (const raw of lines) {
|
|
57
|
+
const l = raw.trim();
|
|
58
|
+
const h = /^#{1,6}\s+(.*)$/.exec(l);
|
|
59
|
+
if (h) {
|
|
60
|
+
section = h[1].trim().toLowerCase();
|
|
61
|
+
if (wanted.has(section))
|
|
62
|
+
sawSection = true;
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (l && section && wanted.has(section))
|
|
66
|
+
out.push(l);
|
|
67
|
+
}
|
|
68
|
+
if (sawSection)
|
|
69
|
+
return out;
|
|
70
|
+
return lines.map((l) => l.trim()).filter((l) => l && !l.startsWith("#"));
|
|
71
|
+
}
|
|
72
|
+
function clip(s, n = 70) {
|
|
73
|
+
const t = s.trim().replace(/^[-*]\s+/, "");
|
|
74
|
+
return t.length > n ? `${t.slice(0, n - 1).trimEnd()}…` : t;
|
|
75
|
+
}
|
|
76
|
+
/** The learning this one repeats: same files, and much the same title or text. */
|
|
77
|
+
export function repeatOf(input, existing) {
|
|
78
|
+
const files = new Set(input.touches.map((t) => t.split("#")[0]));
|
|
79
|
+
const title = words(input.title);
|
|
80
|
+
const body = words(input.body);
|
|
81
|
+
for (const n of existing) {
|
|
82
|
+
if (input.replaces && n.id === input.replaces)
|
|
83
|
+
continue;
|
|
84
|
+
const shared = n.touches.some((t) => files.has(t.split("#")[0]));
|
|
85
|
+
const sameTitle = jaccard(title, words(n.title));
|
|
86
|
+
const sameBody = jaccard(body, words(n.body));
|
|
87
|
+
if (shared ? sameTitle >= 0.5 || sameBody >= 0.5 : (input.personal || !files.size) && sameTitle >= 0.6)
|
|
88
|
+
return n;
|
|
89
|
+
}
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
/** The checks, on a learning about to be saved. `existing`: the learnings already there. */
|
|
93
|
+
export function gateNote(input, existing) {
|
|
94
|
+
const problems = [];
|
|
95
|
+
const warnings = [];
|
|
96
|
+
const text = `${input.title}\n${prose(input.body)}`;
|
|
97
|
+
if (!input.personal) {
|
|
98
|
+
const code = input.files.filter((f) => !trailOwnPath(f));
|
|
99
|
+
const onlyTrail = input.files.length > 0 && code.length === 0;
|
|
100
|
+
if (!code.length && !input.namesSymbol) {
|
|
101
|
+
problems.push(SETUP_TALK.test(text) || onlyTrail
|
|
102
|
+
? "It reads as a note about setting trail up, not this repo's code. Skip it, or keep it with --personal if it's about your machine."
|
|
103
|
+
: "It names no file or function in this repo. Name what it's about (`src/x.ts`, `parseConfig`), so a teammate's Claude gets it when it opens that file.");
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
for (const line of text.split(/\r?\n/)) {
|
|
107
|
+
if (STATUS.some((re) => re.test(line))) {
|
|
108
|
+
problems.push(`"${clip(line)}" is status: true today, wrong next week. Keep what stays true (the cause, the rule, the why) and put status in the PR.`);
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (!input.personal && !decisionLines(input.body).some((l) => WHY.test(l))) {
|
|
113
|
+
problems.push('No line says why. Give each decision its reason: the cause, the error it hit, or the number that settled it ("because…", "otherwise…", "fails with…").');
|
|
114
|
+
}
|
|
115
|
+
const twin = repeatOf(input, existing);
|
|
116
|
+
if (twin) {
|
|
117
|
+
problems.push(`It repeats ${notePlace(twin)} ("${clip(twin.title, 50)}"${twin.author ? `, ${twin.author}` : ""}, ${shortDate(twin.date)}). If it updates that one, add --replaces ${noteName(twin)}: the old file stays as the record and yours is read instead. If it's different, say how in the title.`);
|
|
118
|
+
}
|
|
119
|
+
const count = input.body.split(/\s+/).filter(Boolean).length;
|
|
120
|
+
if (count > LONG_NOTE_WORDS)
|
|
121
|
+
warnings.push(`long: ${count} words. Long learnings get skimmed; cut it to the fact and the why.`);
|
|
122
|
+
return { problems, warnings };
|
|
123
|
+
}
|
|
124
|
+
/** `parseConfig`, `Client.Do`, `default_retry_max`, `retry()`: words in a note shaped like code. */
|
|
125
|
+
const BACKTICKED = /`([A-Za-z_$][\w$]*(?:(?:\.|::|#)[A-Za-z_$][\w$]*)*)(?:\(\))?`/g;
|
|
126
|
+
const CODE_SHAPED = /\b([a-z]+[A-Z][\w]*|[A-Z][a-z0-9]+[A-Z][\w]*|[a-z][a-z0-9]*_[a-z0-9_]+|[A-Za-z_]\w*(?=\(\)))\b/g;
|
|
127
|
+
/** The names a note uses that might be symbols, most likely first: backticked, then code-shaped. At most `limit`. */
|
|
128
|
+
export function symbolCandidates(text, limit = 8) {
|
|
129
|
+
const out = [];
|
|
130
|
+
const add = (s) => {
|
|
131
|
+
const name = s.split(/\.|::|#/).pop();
|
|
132
|
+
if (name.length < 3 || /\.[A-Za-z]{1,5}$/.test(s) || out.includes(name))
|
|
133
|
+
return;
|
|
134
|
+
out.push(name);
|
|
135
|
+
};
|
|
136
|
+
for (const m of text.matchAll(BACKTICKED))
|
|
137
|
+
add(m[1]);
|
|
138
|
+
for (const m of text.matchAll(CODE_SHAPED))
|
|
139
|
+
add(m[1]);
|
|
140
|
+
return out.slice(0, limit);
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Whether any of `names` is in the repo's code: a whole-word `git grep` over
|
|
144
|
+
* tracked files, leaving out trail's own files and markdown, which would find
|
|
145
|
+
* the note's own words. Outside git, false: the files it names still count.
|
|
146
|
+
*/
|
|
147
|
+
export function namesRepoSymbol(repo, names) {
|
|
148
|
+
if (!names.length)
|
|
149
|
+
return false;
|
|
150
|
+
for (const name of names) {
|
|
151
|
+
try {
|
|
152
|
+
execFileSync("git", ["grep", "-q", "-w", "-F", "-e", name, "--", ".", ":(exclude).trail", ":(exclude).claude", ":(exclude)*.md"], {
|
|
153
|
+
cwd: repo,
|
|
154
|
+
stdio: "ignore",
|
|
155
|
+
});
|
|
156
|
+
return true;
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
/* not found, or not a repo */
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return false;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Of `files` (relative to the checkout at `repo`), the ones git tracks. A
|
|
166
|
+
* learning's `touches:` lists these, plus files the session itself edited:
|
|
167
|
+
* an untracked file that was already lying around (a token, a scratch file)
|
|
168
|
+
* is never what a learning is about. Outside git, every file that exists.
|
|
169
|
+
*/
|
|
170
|
+
export function trackedFiles(repo, files) {
|
|
171
|
+
if (!files.length)
|
|
172
|
+
return new Set();
|
|
173
|
+
try {
|
|
174
|
+
const out = execFileSync("git", ["ls-files", "-z", "--", ...files], { cwd: repo, encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] });
|
|
175
|
+
return new Set(out.split("\0").filter(Boolean));
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
return new Set(files.filter((f) => existsSync(join(repo, f))));
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=note-gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"note-gate.js","sourceRoot":"","sources":["../../src/notes/note-gate.ts"],"names":[],"mappings":"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"}
|
package/dist/notes/notes.d.ts
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
|
+
import type { NoteHit } from "./find-notes.js";
|
|
2
|
+
import { type LearningFields } from "./learning-fields.js";
|
|
3
|
+
export { findNotes, type NoteHit } from "./find-notes.js";
|
|
4
|
+
export { mentionedFiles, noteTargets, type NoteTarget } from "./targets.js";
|
|
5
|
+
export { commitLines, namesLabel, PR_SPEEDUP, setupCommitLine, TOKEN_CREDIT_FLOOR, tokensLabel, tokensWorthSaying } from "./credit.js";
|
|
1
6
|
export interface NoteCost {
|
|
2
7
|
minutes?: number;
|
|
3
8
|
tokens?: number;
|
|
4
9
|
}
|
|
5
|
-
|
|
10
|
+
/** A learning. Its id, kind, scope, status and the rest are in `LearningFields`. */
|
|
11
|
+
export interface Note extends LearningFields {
|
|
6
12
|
/** Where the note is: an absolute path on this machine. */
|
|
7
13
|
path: string;
|
|
8
14
|
title: string;
|
|
@@ -16,12 +22,14 @@ export interface Note {
|
|
|
16
22
|
body: string;
|
|
17
23
|
/** Written by someone other than whoever is asking. */
|
|
18
24
|
teammate?: boolean;
|
|
19
|
-
/** `repo`: in the repo's `.trail/learnings/`, for everyone. `personal`: in ~/.trail, this machine only. */
|
|
20
|
-
scope?: "repo" | "personal";
|
|
21
25
|
/** A rule or preference for every session here, not knowledge about one
|
|
22
26
|
* task: what the user kept having to tell Claude. The session-start hook
|
|
23
27
|
* lists these up front, since no single task would bring them up. */
|
|
24
28
|
standing?: boolean;
|
|
29
|
+
/** The file name of an earlier learning this one takes over from. The old
|
|
30
|
+
* file stays, as the record of what that session knew, but `listNotes`
|
|
31
|
+
* reads this one instead. */
|
|
32
|
+
replaces?: string;
|
|
25
33
|
/** Found on a teammate's pushed branch (`origin/kumar/jitter`) rather than in
|
|
26
34
|
* this checkout. `path` is then `<ref>:.trail/learnings/<name>`, readable
|
|
27
35
|
* with `git show`, and the whole body travels with the note. */
|
|
@@ -44,7 +52,11 @@ export declare const SECTIONS: readonly [{
|
|
|
44
52
|
readonly label: "watch out";
|
|
45
53
|
}];
|
|
46
54
|
export declare function renderNote(n: Omit<Note, "path">): string;
|
|
47
|
-
/**
|
|
55
|
+
/**
|
|
56
|
+
* A note file, or null when it isn't one (no title in its frontmatter), or
|
|
57
|
+
* when its front matter is refused (anchors, aliases, a list for a title) or
|
|
58
|
+
* isn't valid YAML, which says so once on stderr.
|
|
59
|
+
*/
|
|
48
60
|
export declare function parseNote(text: string, path: string): Note | null;
|
|
49
61
|
/** The file name a note is known by, wherever it sits: one learning on a branch and in the tree is one learning. */
|
|
50
62
|
export declare function noteName(n: Note): string;
|
|
@@ -75,73 +87,32 @@ export interface WriteNoteInput {
|
|
|
75
87
|
cost?: NoteCost;
|
|
76
88
|
touches?: string[];
|
|
77
89
|
standing?: boolean;
|
|
90
|
+
/** The fields a new learning may be given; its id, status and scope come from where it is written. */
|
|
91
|
+
kind?: LearningFields["kind"];
|
|
92
|
+
replaces?: string;
|
|
93
|
+
src?: LearningFields["src"];
|
|
94
|
+
evidence?: string;
|
|
95
|
+
/** Personal only: defaults to this repo. */
|
|
96
|
+
applies?: string;
|
|
78
97
|
}
|
|
79
98
|
/**
|
|
80
99
|
* Write a new learning for the repo `dir` is in, and return it: into the
|
|
81
100
|
* repo's `.trail/learnings/` (made if needed), or with `scope: "personal"`,
|
|
82
101
|
* or outside git, into ~/.trail. Never overwrites: a second one with the same
|
|
83
|
-
* name on the same day gets `-2`, `-3`.
|
|
102
|
+
* name on the same day gets `-2`, `-3`. Its id is 8 hex digits from the file
|
|
103
|
+
* name it gets (`newLearningId`), written into the file.
|
|
84
104
|
*/
|
|
85
105
|
export declare function writeNote(dir: string, input: WriteNoteInput, scope?: LearningScope): Note;
|
|
86
106
|
/**
|
|
87
107
|
* The standing learnings for `dir`: the team's in the checkout and the
|
|
88
108
|
* person's own, never ones on a teammate's unmerged branch, which nobody has
|
|
89
|
-
* reviewed yet.
|
|
109
|
+
* reviewed yet, and only live ones (nothing retired or replaced).
|
|
90
110
|
*/
|
|
91
111
|
export declare function standingLearnings(dir: string): Note[];
|
|
92
112
|
/** Where a learning is, as the agent and the person read it: `.trail/learnings/x.md`, `~/.trail/…`, or `origin/b:.trail/…`. */
|
|
93
113
|
export declare function notePlace(n: Note): string;
|
|
94
|
-
export interface NoteTarget {
|
|
95
|
-
/** A folder in the repo the note goes to. */
|
|
96
|
-
dir: string;
|
|
97
|
-
/** What the session touched there, relative to the top of that checkout. */
|
|
98
|
-
touches: string[];
|
|
99
|
-
/** What it only read there, same form; set when the session said what it read. */
|
|
100
|
-
read?: string[];
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* Which repos a session's note belongs in, and what it touched in each.
|
|
104
|
-
*
|
|
105
|
-
* The repo the note was saved from gets the files it has uncommitted or
|
|
106
|
-
* committed since `since`. Every other repo the session edited (`edited`:
|
|
107
|
-
* absolute paths, from the agent's transcript) gets the note too, with its
|
|
108
|
-
* own files, so a session that changed a backend and the library it calls
|
|
109
|
-
* leaves a note in both. Saved from a folder that holds several repos, the
|
|
110
|
-
* note goes to each repo the session changed, or stays with the folder when
|
|
111
|
-
* it changed none. Two worktrees of one repo are one repo.
|
|
112
|
-
*
|
|
113
|
-
* `session.read`, when the transcript was found: the files the session opened.
|
|
114
|
-
* Then the transcript says what was touched, and the working tree's other
|
|
115
|
-
* uncommitted files, there before the session began, are left out.
|
|
116
|
-
*/
|
|
117
|
-
export declare function noteTargets(dir: string, edited?: string[], since?: number, session?: {
|
|
118
|
-
read: string[];
|
|
119
|
-
}): NoteTarget[];
|
|
120
|
-
/**
|
|
121
|
-
* Files of the checkout at `dir` that a note's text names by path. A session
|
|
122
|
-
* that only read code edits nothing, so without these its note would touch no
|
|
123
|
-
* file, and nothing that looks a note up by file (`trail check`, the ranked
|
|
124
|
-
* search) would ever find it.
|
|
125
|
-
*/
|
|
126
|
-
export declare function mentionedFiles(dir: string, body: string): string[];
|
|
127
|
-
export interface NoteHit {
|
|
128
|
-
note: Note;
|
|
129
|
-
score: number;
|
|
130
|
-
/** Files the note touches that this query's results also point into. */
|
|
131
|
-
shared: string[];
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* The notes worth showing next to a query's results: ones whose title or body
|
|
135
|
-
* share the query's words, or that touch a file the results point into. At
|
|
136
|
-
* most `limit`, best first. A note has to clear a bar — two of the query's
|
|
137
|
-
* words, or one in its title, or a shared file — so an unrelated note never
|
|
138
|
-
* rides along just because it exists.
|
|
139
|
-
*/
|
|
140
|
-
export declare function findNotes(notes: Note[], query: string, files?: string[], limit?: number): NoteHit[];
|
|
141
114
|
/** `2026-10-07` → `Oct 7`; anything else as it came. */
|
|
142
115
|
export declare function shortDate(date: string): string;
|
|
143
|
-
/** `~9.6k tokens`, `~600 tokens`. */
|
|
144
|
-
export declare function tokensLabel(n: number): string;
|
|
145
116
|
/** `took 12 min and ~9.6k tokens to work out`, or null when the note has no cost. */
|
|
146
117
|
export declare function costLabel(cost?: NoteCost): string | null;
|
|
147
118
|
/** What reading a note costs an agent, in tokens: its text at ~4 characters a token. */
|
|
@@ -151,7 +122,7 @@ export declare function readingTokens(n: Note): number;
|
|
|
151
122
|
* it costs. 0 when it carries no token cost, or reading it costs as much.
|
|
152
123
|
*/
|
|
153
124
|
export declare function savedByNote(n: Note): number;
|
|
154
|
-
/** `
|
|
125
|
+
/** `Maya's learning`, `a learning`, `Kumar's learning on kumar/jitter`. */
|
|
155
126
|
export declare function whoseLearning(n: Note): string;
|
|
156
127
|
/**
|
|
157
128
|
* The block `ask` prints above its results: whose learning each is, when,
|
|
@@ -159,39 +130,12 @@ export declare function whoseLearning(n: Note): string;
|
|
|
159
130
|
* where to read the rest. A learning on a teammate's unmerged branch says so,
|
|
160
131
|
* with the `git show` that prints it, since there's no file here to open. An agent
|
|
161
132
|
* relays the cost when it says what the turn saved, which is how the saving
|
|
162
|
-
* becomes countable.
|
|
133
|
+
* becomes countable. Every field is flattened to one line: a learning's text
|
|
134
|
+
* comes from whoever wrote it, and a line of its own could pass for trail's.
|
|
163
135
|
*/
|
|
164
136
|
export declare function formatNoteHits(hits: NoteHit[]): string[];
|
|
165
137
|
/** The line an agent closes its reply with after saving a learning just for the user. */
|
|
166
138
|
export declare const PERSONAL_SAVED_LINE = "\uD83D\uDCDD Saved just for you \u00B7 stays on this machine, out of the repo";
|
|
167
|
-
/** `Anay`, `Anay and Rushil`, `Anay, Rushil and 3 others`. */
|
|
168
|
-
export declare function namesLabel(names: string[]): string;
|
|
169
|
-
/** What starting from a teammate's learning is worth when its tokens are too few to say: time to a PR. */
|
|
170
|
-
export declare const PR_SPEEDUP = "3x faster";
|
|
171
|
-
/**
|
|
172
|
-
* Below this many tokens, what a learning saves is too small a number to
|
|
173
|
-
* impress, so trail credits it as a faster PR instead.
|
|
174
|
-
*/
|
|
175
|
-
export declare const TOKEN_CREDIT_FLOOR = 80000;
|
|
176
|
-
/** Whether a token count is big enough to be the credit. */
|
|
177
|
-
export declare function tokensWorthSaying(tokens: number | undefined): boolean;
|
|
178
|
-
/**
|
|
179
|
-
* The lines that close a reply after a team learning is saved, one for each
|
|
180
|
-
* way the turn can end, since only the agent knows whether it committed the
|
|
181
|
-
* learning by then. Uncommitted, it makes the case for committing: who else
|
|
182
|
-
* works on the same files, and the head start their agents would get, which
|
|
183
|
-
* is what the learning took to work out, or a faster PR when that's small.
|
|
184
|
-
*/
|
|
185
|
-
export declare function commitLines(note: Pick<Note, "cost">, teammates: string[], where?: "files" | "repo"): {
|
|
186
|
-
committed: string;
|
|
187
|
-
uncommitted: string;
|
|
188
|
-
};
|
|
189
|
-
/**
|
|
190
|
-
* The line asking for trail's shared setup to be committed, once: `.trail/`
|
|
191
|
-
* and the SessionStart entry in `.claude/settings.json` are what let a
|
|
192
|
-
* teammate's Claude read the learnings before they install anything.
|
|
193
|
-
*/
|
|
194
|
-
export declare function setupCommitLine(teammates: string[]): string;
|
|
195
139
|
/**
|
|
196
140
|
* What starting from these learnings is worth, for the agent's closing line:
|
|
197
141
|
* the tokens they saved, less what reading them costs, when that's worth
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"notes.d.ts","sourceRoot":"","sources":["../../src/notes/notes.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"notes.d.ts","sourceRoot":"","sources":["../../src/notes/notes.ts"],"names":[],"mappings":"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"}
|