@pedrocivita/tocket 2.6.4 → 2.6.5

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 CHANGED
@@ -23,6 +23,10 @@ The Context Engineering Framework for Multi-Agent Workspaces. Agents forget ever
23
23
  <img src="docs/assets/tocket-dashboard.png" alt="Tocket CLI Dashboard" width="700" />
24
24
  </p>
25
25
 
26
+ ## What's new in 2.6.5
27
+
28
+ Meta-attention handoff: Jev judges chunks; workers read the filtered handoff. `tocket handoff --aware` scores `.context/` chunks and writes `.context/handoffs/` plus a receipt under `.context/attention/`. Conditional packs live in `.context/gotchas/`; `tocket packs load --query` writes `.context/active/packs.md`. `--dry-run` or no key uses the stub. Harness your context. Jev is the judge. decide, then work, then `tool_gate` stays the same, and agent auto-config is unchanged.
29
+
26
30
  ## What's new in 2.6.4
27
31
 
28
32
  - Windows follow-up: suite/triage/doctor/init print posix `toRepoRelative` paths; decide tests use `includesPath` (separators); Cursor `CURSOR_*` env detection is case-insensitive and init tests isolate `HOME` so `.cursorrules` is written.
@@ -152,7 +156,7 @@ See the [Developer Guide](docs/DEVELOPERS_GUIDE.md) for detailed safe-testing wo
152
156
  | `tocket generate` | Build structured payload XML (auto-fills scope from git, saves to `.tocket/`) |
153
157
  | `tocket diff` | Compare payload targets against actual git changes (verify executor compliance) |
154
158
  | `tocket sync` | Append session summary + git log to `.context/progress.md` |
155
- | `tocket handoff` | Generate clipboard-ready context summary for a new agent conversation |
159
+ | `tocket handoff` | Clipboard summary. `--aware` keeps only chunks Jev (or the stub) scores as relevant |
156
160
  | `tocket validate` | Check if the workspace has a valid Memory Bank |
157
161
  | `tocket focus` | Update the Current Focus in `activeContext.md` |
158
162
  | `tocket status` | Quick overview: workspace health, branch, focus, agents |
@@ -166,6 +170,7 @@ See the [Developer Guide](docs/DEVELOPERS_GUIDE.md) for detailed safe-testing wo
166
170
  | `tocket suite loop` | Copy mapper AppMap + optional last-run into `.context/appmaps/` and triage |
167
171
  | `tocket decide` | State + Choice handoff into `.context/decisions/` (Codila-style queues; does not run workers) |
168
172
  | `tocket work` | Read a decision and print a plan (default) or `--apply` a notebook receipt. Never calls Jev. |
173
+ | `tocket packs load` | Load gotcha packs from `.context/gotchas/` into `.context/active/packs.md` |
169
174
  | `tocket eject` | Remove all Tocket files (with confirmation) |
170
175
 
171
176
  ### CI-friendly flags
@@ -190,6 +195,15 @@ tocket diff --json
190
195
  # Handoff context to a new session
191
196
  tocket handoff --to stdout
192
197
 
198
+ # Meta-attention: Jev judges chunks; workers read the filtered handoff
199
+ tocket handoff --query "fix auth midflight" --aware
200
+ tocket handoff --aware --dry-run --to stdout
201
+ tocket handoff --aware --threshold 0.6 --query "fix auth midflight" --to stdout
202
+
203
+ # Conditional packs (Noul: load this pack?)
204
+ tocket packs load --query "frontend form" --dry-run
205
+ tocket packs load --query "frontend form" --to stdout
206
+
193
207
  # AppMap last-run (file-first; does not execute maps)
194
208
  tocket suite status
195
209
  tocket suite sync --from path/to/last-run.json
@@ -306,6 +320,8 @@ init (detect agent, write AGENTS.md + instruction files)
306
320
  | `tool_gate` | `allow` proceeds. `block` stops. `ask` escalates to a human. `--force` overrides. |
307
321
  | `--fork model` | Cheap model-router hook (bounded forks: agent, model, tool, action, human). |
308
322
  | Shadow-first | `--dry-run` / `--shadow` is log-only. Shadow apply still needs `--force`. |
323
+ | `tocket handoff --aware` | Meta-attention. Jev judges chunks; workers read the filtered handoff. |
324
+ | `tocket packs load` | Conditional gotcha packs into `.context/active/packs.md`. |
309
325
  | `tocket doctor` | Checks `.context/`, `AGENTS.md`, skill, last decision, key yes/no. |
310
326
  | Skill | `npx skills add pedrocivita/tocket --skill tocket`. Same rules as `AGENTS.md`. |
311
327
 
@@ -322,6 +338,10 @@ The `.context/` directory is the project's shared memory. Agents read it before
322
338
  | `progress.md` | Milestones and completed work | Per milestone |
323
339
  | `appmaps/` | Optional AppMap index + map copy + last-run + triage | `tocket suite loop` / `sync` |
324
340
  | `decisions/` | Choice/Noul handoff queues (`research/`, `write/`, `review/`) plus `*.applied.json` receipts | `tocket decide` / `tocket work` |
341
+ | `attention/` | Meta-attention receipts (per-chunk Noul and Score) | `tocket handoff --aware` / `tocket packs load` |
342
+ | `handoffs/` | Filtered session handoff markdown | `tocket handoff --aware` |
343
+ | `gotchas/` | Conditional section packs (`frontend.md`, `path-src-api.md`) | authors |
344
+ | `active/packs.md` | Packs the judge loaded for the current query | `tocket packs load` |
325
345
  | `AGENTS.md` (repo root) | Agent-first rules: decide vs work, `tool_gate`, do not re-ask Jev | `tocket init` / `tocket agents-md` |
326
346
 
327
347
  ### Triangulation
@@ -356,6 +376,10 @@ tocket handoff # copies context summary to clipboard
356
376
  tocket handoff --to stdout # print instead
357
377
  tocket handoff --commits 10 # include more history
358
378
  tocket handoff --since 1d # files modified in last day
379
+
380
+ # Filtered handoff (stub). Workers read this, not the whole Memory Bank.
381
+ tocket handoff --query "fix auth midflight" --aware --dry-run --to stdout
382
+ tocket packs load --query "frontend form" --dry-run --to stdout
359
383
  ```
360
384
 
361
385
  ## Who is this for?
@@ -2,7 +2,8 @@ import { existsSync, readFileSync, writeFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
3
  import { success, error as themeError, dim } from "../utils/theme.js";
4
4
  import { getRecentCommits, getCurrentBranch, getRecentlyModifiedFiles, isGitRepo, } from "../utils/git.js";
5
- import { extractFocus } from "../utils/context.js";
5
+ import { extractFocus, toRepoRelative } from "../utils/context.js";
6
+ import { AttentionError, formatAwareSummary, parseThreshold, queryFromFocus, runAwareHandoff, } from "../utils/attention.js";
6
7
  /** Extract the "## Open Decisions" section body from activeContext.md. */
7
8
  export function extractOpenDecisions(content) {
8
9
  const match = content.match(/## Open Decisions\s*\n+([\s\S]*?)(?=\n## |\n*$)/);
@@ -77,6 +78,12 @@ export function registerHandoffCommand(program) {
77
78
  .option("--to <target>", "Output target: clipboard (default), stdout, or file path")
78
79
  .option("--commits <n>", "Number of recent commits to include", "5")
79
80
  .option("--since <duration>", "Time window for modified files (e.g., 2h, 30m, 1d)", "2h")
81
+ .option("--aware", "Score .context/ chunks with Jev (or the stub) and emit only relevant ones")
82
+ .option("--query <text>", "Query for --aware (defaults to Current Focus)")
83
+ .option("--threshold <n>", "Keep a chunk when noul or score is at or above this (default 0.5)")
84
+ .option("--dry-run", "Force the deterministic stub (log-only)")
85
+ .option("--shadow", "Call Jev if TYPESAFE_API_KEY is set, but mark the attention receipt log-only")
86
+ .option("--id <id>", "Attention receipt id", "handoff")
80
87
  .action(async (options) => {
81
88
  const cwd = process.cwd();
82
89
  const contextDir = join(cwd, ".context");
@@ -90,9 +97,11 @@ export function registerHandoffCommand(program) {
90
97
  let focus = "";
91
98
  let openDecisions = "";
92
99
  let projectName = "Project";
100
+ let focusQuery = "";
93
101
  if (existsSync(activeContextPath)) {
94
102
  const content = readFileSync(activeContextPath, "utf-8");
95
103
  focus = extractFocus(content);
104
+ focusQuery = queryFromFocus(content);
96
105
  openDecisions = extractOpenDecisions(content);
97
106
  projectName = extractProjectName(content);
98
107
  }
@@ -101,6 +110,47 @@ export function registerHandoffCommand(program) {
101
110
  const branch = isGitRepo(cwd) ? getCurrentBranch(cwd) : "";
102
111
  const recentCommits = getRecentCommits(commitCount, cwd);
103
112
  const modifiedFiles = getRecentlyModifiedFiles(sinceMinutes, cwd);
113
+ if (options.aware) {
114
+ try {
115
+ const aware = await runAwareHandoff({
116
+ cwd,
117
+ query: options.query,
118
+ focus: focusQuery || focus,
119
+ projectName,
120
+ branch,
121
+ recentCommits,
122
+ modifiedFiles,
123
+ threshold: parseThreshold(options.threshold),
124
+ dryRun: options.dryRun === true,
125
+ shadow: options.shadow === true,
126
+ id: options.id,
127
+ });
128
+ const summary = formatAwareSummary(aware.record, toRepoRelative(cwd, aware.handoffPath), toRepoRelative(cwd, aware.attentionPath));
129
+ const target = options.to ?? "clipboard";
130
+ if (target === "stdout") {
131
+ console.log(aware.markdown);
132
+ console.error(dim(summary));
133
+ }
134
+ else if (target === "clipboard") {
135
+ const { default: clipboard } = await import("clipboardy");
136
+ clipboard.writeSync(aware.markdown);
137
+ console.log("\n" +
138
+ success("Aware handoff copied to clipboard.") +
139
+ "\n" +
140
+ dim(` ${summary}\n`));
141
+ }
142
+ else {
143
+ writeFileSync(target, aware.markdown, "utf-8");
144
+ console.log("\n" + success(summary) + "\n");
145
+ }
146
+ }
147
+ catch (err) {
148
+ const message = err instanceof Error ? err.message : String(err);
149
+ console.error(themeError(message));
150
+ process.exitCode = err instanceof AttentionError ? 2 : 1;
151
+ }
152
+ return;
153
+ }
104
154
  const data = {
105
155
  focus,
106
156
  branch,
@@ -1 +1 @@
1
- {"version":3,"file":"handoff.cmd.js","sourceRoot":"","sources":["../../src/commands/handoff.cmd.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"handoff.cmd.js","sourceRoot":"","sources":["../../src/commands/handoff.cmd.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerPacksCommand(program: Command): void;
@@ -0,0 +1,58 @@
1
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { toRepoRelative } from "../utils/context.js";
4
+ import { error as themeError, success } from "../utils/theme.js";
5
+ import { AttentionError, formatPacksSummary, parseThreshold, queryFromFocus, runPacksLoad, } from "../utils/attention.js";
6
+ export function registerPacksCommand(program) {
7
+ const packs = program
8
+ .command("packs")
9
+ .description("Conditional gotcha packs (.context/gotchas/) judged by Noul, written as an overlay");
10
+ packs
11
+ .command("load")
12
+ .description("Ask whether to load each pack, then write .context/active/packs.md")
13
+ .option("--query <text>", "Query or task the packs should match")
14
+ .option("--threshold <n>", "Keep a pack when noul or score is at or above this (default 0.5)")
15
+ .option("--dry-run", "Force the deterministic stub (log-only)")
16
+ .option("--shadow", "Call Jev if TYPESAFE_API_KEY is set, but mark the receipt log-only")
17
+ .option("--id <id>", "Attention receipt id", "packs")
18
+ .option("--to <target>", "Also send packs.md to stdout or a file path")
19
+ .action(async (options) => {
20
+ const cwd = process.cwd();
21
+ const contextDir = join(cwd, ".context");
22
+ if (!existsSync(contextDir)) {
23
+ console.error(themeError("No .context/ directory found. Run 'tocket init' first."));
24
+ process.exitCode = 1;
25
+ return;
26
+ }
27
+ let focus = "";
28
+ const activeContextPath = join(contextDir, "activeContext.md");
29
+ if (existsSync(activeContextPath)) {
30
+ focus = queryFromFocus(readFileSync(activeContextPath, "utf-8"));
31
+ }
32
+ try {
33
+ const loaded = await runPacksLoad({
34
+ cwd,
35
+ query: options.query,
36
+ focus,
37
+ threshold: parseThreshold(options.threshold),
38
+ dryRun: options.dryRun === true,
39
+ shadow: options.shadow === true,
40
+ id: options.id,
41
+ });
42
+ const summary = formatPacksSummary(loaded.record, toRepoRelative(cwd, loaded.packsPath));
43
+ if (options.to === "stdout") {
44
+ console.log(loaded.markdown);
45
+ }
46
+ else if (options.to && options.to !== "clipboard") {
47
+ writeFileSync(options.to, loaded.markdown, "utf-8");
48
+ }
49
+ console.log(success(summary));
50
+ }
51
+ catch (err) {
52
+ const message = err instanceof Error ? err.message : String(err);
53
+ console.error(themeError(message));
54
+ process.exitCode = err instanceof AttentionError ? 2 : 1;
55
+ }
56
+ });
57
+ }
58
+ //# sourceMappingURL=packs.cmd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"packs.cmd.js","sourceRoot":"","sources":["../../src/commands/packs.cmd.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -19,6 +19,7 @@ import { registerScaffoldCommand } from "./commands/scaffold.cmd.js";
19
19
  import { registerSuiteCommand } from "./commands/suite.cmd.js";
20
20
  import { registerDecideCommand } from "./commands/decide.cmd.js";
21
21
  import { registerWorkCommand } from "./commands/work.cmd.js";
22
+ import { registerPacksCommand } from "./commands/packs.cmd.js";
22
23
  const pkg = JSON.parse(readFileSync(join(import.meta.dirname, "..", "package.json"), "utf-8"));
23
24
  const program = new Command();
24
25
  program
@@ -42,6 +43,7 @@ registerScaffoldCommand(program);
42
43
  registerSuiteCommand(program);
43
44
  registerDecideCommand(program);
44
45
  registerWorkCommand(program);
46
+ registerPacksCommand(program);
45
47
  // No-args: show interactive dashboard (TTY) or help (non-TTY)
46
48
  const args = process.argv.slice(2);
47
49
  if (args.length === 0 && process.stdin.isTTY) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -272,6 +272,10 @@ Project context lives in \`.context/\`, not in chat history. **Read it before do
272
272
  techContext.md <- Tech stack, build tools, critical rules.
273
273
  productContext.md <- What the product is, who it's for, why it exists.
274
274
  progress.md <- What's done, what's next.
275
+ gotchas/ <- Optional section packs (frontend.md, path-src-api.md).
276
+ active/packs.md <- Packs loaded for the current query.
277
+ attention/ <- Meta-attention receipts. Jev judges chunks.
278
+ handoffs/ <- Filtered handoff markdown.
275
279
  \`\`\`
276
280
 
277
281
  ### Rules
@@ -383,6 +387,8 @@ Tocket is the shared notebook (\`.context/\`). Agents work. Tocket remembers. Je
383
387
  3. \`tocket decide\` is the judge (Jev or stub). \`tocket work\` is the plan (dry-run). \`tocket work --apply\` stamps a notebook receipt. Never re-decide.
384
388
  4. Honor \`tool_gate\`: \`allow\` proceeds, \`block\` stops, \`ask\` escalates to a human. Shadow / log-only is advice unless \`--force\`.
385
389
  5. Before bash, deploy, or browser: \`tocket decide --choice tool_gate:allow,block,ask\`, then \`tocket work\`.
390
+ 6. Meta-attention handoff: \`tocket handoff --aware\` asks Jev (or the stub) to score \`.context/\` chunks. Workers read the filtered handoff, not the whole Memory Bank.
391
+ 7. Conditional packs live in \`.context/gotchas/\`. \`tocket packs load --query\` writes the relevant packs to \`.context/active/packs.md\`.
386
392
 
387
393
  Optional \`TYPESAFE_API_KEY\` for live Jev. Without it, decide uses the stub. Prefer \`--dry-run\` or \`--shadow\` first.
388
394
  `;
@@ -434,6 +440,8 @@ export function tocketConventionsHint() {
434
440
  " AGENTS.md start here (any agent)",
435
441
  " .context/ shared notebook",
436
442
  " .context/decisions/ next move (tocket decide)",
443
+ " .context/attention/ meta-attention receipts",
444
+ " .context/gotchas/ conditional packs",
437
445
  ` ${TOCKET_SKILL_REL} official skill`,
438
446
  `One-shot: ${TOCKET_SKILLS_ADD}`,
439
447
  `Phrase: ${TOCKET_AGENT_PHRASE}`,
@@ -450,12 +458,16 @@ Tocket is the shared project notebook (\`.context/\`). Agents read and write tho
450
458
 
451
459
  **${TOCKET_AGENT_PHRASE}**
452
460
 
461
+ Harness your context. Jev is the judge, not the writer. Meta-attention handoff: Jev judges chunks; workers read the filtered handoff.
462
+
453
463
  ## When to use
454
464
 
455
465
  - Read \`AGENTS.md\` and \`.context/\` before expensive tools.
456
466
  - If \`.context/decisions/\` already has a handoff, honor it. Do not re-ask Jev.
457
467
  - \`tocket decide\` = judge (Jev or stub). \`tocket work\` = plan. \`tocket work --apply\` = receipt.
458
468
  - Honor \`tool_gate\` (\`allow|block|ask\`). Before bash/deploy/browser: \`--choice tool_gate:allow,block,ask\`, then \`tocket work\`.
469
+ - \`tocket handoff --aware --query "..."\` filters \`.context/\` chunks. Receipt: \`.context/attention/\`. Filtered handoff: \`.context/handoffs/\`.
470
+ - Gotcha packs live in \`.context/gotchas/\`. \`tocket packs load --query "..."\` writes \`.context/active/packs.md\`.
459
471
  - After work: update \`.context/activeContext.md\`.
460
472
 
461
473
  ## Setup
@@ -1 +1 @@
1
- {"version":3,"file":"memory-bank.js","sourceRoot":"","sources":["../../src/templates/memory-bank.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"memory-bank.js","sourceRoot":"","sources":["../../src/templates/memory-bank.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,268 @@
1
+ import { describe, it } from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { mkdtempSync, mkdirSync, writeFileSync, readFileSync, rmSync, } from "node:fs";
4
+ import { tmpdir } from "node:os";
5
+ import { join } from "node:path";
6
+ import { spawnSync } from "node:child_process";
7
+ import { ATTENTION_SCHEMA, chunkKept, collectContextChunks, collectGotchaPacks, parseThreshold, runAwareHandoff, runPacksLoad, splitMarkdown, stubRelevance, } from "../utils/attention.js";
8
+ import { includesPath } from "./helpers.js";
9
+ const cliPath = join(import.meta.dirname, "..", "index.js");
10
+ const NOW = "2026-09-21T18:00:00.000Z";
11
+ function runCli(args, cwd) {
12
+ const result = spawnSync(process.execPath, [cliPath, ...args], {
13
+ cwd,
14
+ encoding: "utf-8",
15
+ env: { ...process.env, TYPESAFE_API_KEY: "" },
16
+ });
17
+ return {
18
+ stdout: result.stdout ?? "",
19
+ stderr: result.stderr ?? "",
20
+ status: result.status ?? 1,
21
+ };
22
+ }
23
+ function writeContext(cwd) {
24
+ mkdirSync(join(cwd, ".context", "decisions"), { recursive: true });
25
+ mkdirSync(join(cwd, ".context", "gotchas"), { recursive: true });
26
+ writeFileSync(join(cwd, ".context", "activeContext.md"), [
27
+ "# Active Context - Demo",
28
+ "",
29
+ "## Current Focus",
30
+ "",
31
+ "Fix auth midflight token refresh.",
32
+ "",
33
+ "## Open Decisions",
34
+ "",
35
+ "- Windows posix path separators for the CLI.",
36
+ "",
37
+ ].join("\n"), "utf-8");
38
+ writeFileSync(join(cwd, ".context", "systemPatterns.md"), [
39
+ "# Patterns",
40
+ "",
41
+ "## Auth session",
42
+ "",
43
+ "The auth midflight refresh must retry once.",
44
+ "",
45
+ "### Retry budget",
46
+ "",
47
+ "Allow one auth midflight retry.",
48
+ "",
49
+ "## Unrelated billing",
50
+ "",
51
+ "Invoice export and tax tables for billing.",
52
+ "",
53
+ ].join("\n"), "utf-8");
54
+ writeFileSync(join(cwd, ".context", "gotchas", "auth.md"), "# Auth\n\nRetry the auth midflight refresh when the token expires.\n", "utf-8");
55
+ writeFileSync(join(cwd, ".context", "gotchas", "frontend.md"), "# Frontend\n\nValidate the frontend form before submit.\n", "utf-8");
56
+ writeFileSync(join(cwd, ".context", "gotchas", "path-src-api.md"), "# API paths\n\nRoute handlers under src/api.\n", "utf-8");
57
+ writeFileSync(join(cwd, ".context", "gotchas", "areas.md"), [
58
+ "# Areas",
59
+ "",
60
+ "## Frontend forms",
61
+ "",
62
+ "Frontend form labels and client validation.",
63
+ "",
64
+ "## Database",
65
+ "",
66
+ "Migration order for tables.",
67
+ "",
68
+ ].join("\n"), "utf-8");
69
+ writeFileSync(join(cwd, ".context", "decisions", "auth.json"), JSON.stringify({
70
+ schema: "tocket.decide/v0",
71
+ id: "auth-refresh",
72
+ destination: "write",
73
+ choice: "write",
74
+ state: "fix auth midflight token refresh",
75
+ }), "utf-8");
76
+ }
77
+ describe("attention chunks", () => {
78
+ it("splits headings and keeps subsections small", () => {
79
+ const chunks = splitMarkdown(".context/systemPatterns.md", [
80
+ "# Patterns",
81
+ "",
82
+ "## Architecture",
83
+ "",
84
+ "Intro paragraph.",
85
+ "",
86
+ "### Command Registration",
87
+ "",
88
+ "One file per command.",
89
+ "",
90
+ "## Billing",
91
+ "",
92
+ "Invoice export.",
93
+ "",
94
+ ].join("\n"));
95
+ const labels = chunks.map((chunk) => chunk.label);
96
+ assert.deepEqual(labels, ["Architecture", "Architecture / Command Registration", "Billing"]);
97
+ assert.ok(chunks.every((chunk) => chunk.text.length <= 700));
98
+ assert.ok(!chunks.some((chunk) => chunk.text.includes("# Patterns")));
99
+ });
100
+ it("splits a long section into parts", () => {
101
+ const para = "alpha ".repeat(80).trim();
102
+ const chunks = splitMarkdown(".context/progress.md", `## Milestone\n\n${para}\n\n${para}\n`, "relevant", 200);
103
+ assert.ok(chunks.length >= 2);
104
+ assert.ok(chunks.every((chunk) => chunk.text.length <= 200));
105
+ assert.ok(chunks[0].label.includes("(1)"));
106
+ });
107
+ it("scores overlap and omits unrelated text", () => {
108
+ const high = stubRelevance("fix auth midflight", "Fix auth midflight token refresh.");
109
+ const low = stubRelevance("fix auth midflight", "Windows posix path separators.");
110
+ assert.ok(high.noul >= 0.5);
111
+ assert.ok(low.noul < 0.5);
112
+ assert.equal(chunkKept(0.2, 0.8, 0.5), true);
113
+ assert.equal(chunkKept(0.8, 0.2, 0.5), true);
114
+ assert.equal(chunkKept(0.2, 0.2, 0.5), false);
115
+ assert.equal(chunkKept(0.55, 0.55, 0.6), false);
116
+ assert.equal(parseThreshold(), 0.5);
117
+ assert.throws(() => parseThreshold("2"), /between 0 and 1/);
118
+ });
119
+ });
120
+ describe("aware handoff", () => {
121
+ it("writes a filtered handoff and omits low-relevance chunks (stub, no network)", async () => {
122
+ const cwd = mkdtempSync(join(tmpdir(), "tocket-aware-"));
123
+ writeContext(cwd);
124
+ let called = 0;
125
+ const fetchImpl = (() => {
126
+ called += 1;
127
+ throw new Error("network");
128
+ });
129
+ const result = await runAwareHandoff({
130
+ cwd,
131
+ query: "fix auth midflight",
132
+ projectName: "Demo",
133
+ dryRun: true,
134
+ now: () => NOW,
135
+ fetchImpl,
136
+ id: "handoff",
137
+ });
138
+ assert.equal(called, 0);
139
+ assert.equal(result.record.schema, ATTENTION_SCHEMA);
140
+ assert.equal(result.record.source, "stub");
141
+ assert.equal(result.record.mode, "dry-run");
142
+ assert.equal(result.record.executes, false);
143
+ assert.equal(result.record.semantics, "log-only");
144
+ assert.match(result.markdown, /token refresh/);
145
+ assert.match(result.markdown, /retry once/);
146
+ assert.match(result.markdown, /auth midflight retry/);
147
+ assert.doesNotMatch(result.markdown, /Invoice export/);
148
+ assert.doesNotMatch(result.markdown, /posix path separators/);
149
+ assert.match(result.markdown, /### Omitted chunks/);
150
+ assert.match(result.markdown, /Unrelated billing/);
151
+ assert.match(result.markdown, /auth midflight refresh when the token expires/);
152
+ assert.doesNotMatch(result.markdown, /Validate the frontend form/);
153
+ assert.doesNotMatch(result.markdown, /Route handlers under src\/api/);
154
+ assert.ok(includesPath(result.attentionPath, ".context/attention/20260921T180000Z-handoff.json"));
155
+ assert.ok(includesPath(result.handoffPath, ".context/handoffs/20260921T180000Z-handoff.md"));
156
+ const onDisk = readFileSync(result.handoffPath, "utf-8");
157
+ assert.equal(onDisk, result.markdown);
158
+ assert.doesNotMatch(onDisk, /Invoice export/);
159
+ const receipt = JSON.parse(readFileSync(result.attentionPath, "utf-8"));
160
+ assert.equal(receipt.schema, ATTENTION_SCHEMA);
161
+ assert.ok(receipt.chunks.some((chunk) => chunk.kept && chunk.label === "Current Focus"));
162
+ assert.ok(receipt.chunks.some((chunk) => !chunk.kept && chunk.label === "Unrelated billing"));
163
+ rmSync(cwd, { recursive: true, force: true });
164
+ });
165
+ it("uses one batched Jev call and keeps only high scores", async () => {
166
+ const cwd = mkdtempSync(join(tmpdir(), "tocket-aware-live-"));
167
+ mkdirSync(join(cwd, ".context"), { recursive: true });
168
+ writeFileSync(join(cwd, ".context", "activeContext.md"), "## Current Focus\n\nAuth work.\n\n## Billing\n\nInvoices.\n", "utf-8");
169
+ const chunks = collectContextChunks(cwd);
170
+ assert.equal(chunks.length, 2);
171
+ let calls = 0;
172
+ const fetchImpl = (async () => {
173
+ calls += 1;
174
+ return {
175
+ ok: true,
176
+ status: 200,
177
+ text: async () => "",
178
+ json: async () => ({
179
+ model: "jev-test",
180
+ answers: {
181
+ c0_relevant: { noul: 0.91, confidence: 0.8 },
182
+ c0_relevance: { score: 0.2, confidence: 0.8 },
183
+ c1_relevant: { noul: 0.1, confidence: 0.8 },
184
+ c1_relevance: { score: 0.15, confidence: 0.8 },
185
+ },
186
+ }),
187
+ };
188
+ });
189
+ const result = await runAwareHandoff({
190
+ cwd,
191
+ query: "auth",
192
+ dryRun: false,
193
+ shadow: true,
194
+ apiKey: "test-key",
195
+ fetchImpl,
196
+ now: () => NOW,
197
+ });
198
+ assert.equal(calls, 1);
199
+ assert.equal(result.record.source, "jev");
200
+ assert.equal(result.record.mode, "shadow");
201
+ assert.equal(result.record.semantics, "log-only");
202
+ assert.match(result.markdown, /Auth work/);
203
+ assert.doesNotMatch(result.markdown, /Invoices/);
204
+ rmSync(cwd, { recursive: true, force: true });
205
+ });
206
+ it("prints a filtered handoff from the CLI without a key", () => {
207
+ const cwd = mkdtempSync(join(tmpdir(), "tocket-aware-cli-"));
208
+ writeContext(cwd);
209
+ const result = runCli([
210
+ "handoff",
211
+ "--aware",
212
+ "--dry-run",
213
+ "--query",
214
+ "fix auth midflight",
215
+ "--threshold",
216
+ "0.6",
217
+ "--to",
218
+ "stdout",
219
+ ], cwd);
220
+ assert.equal(result.status, 0);
221
+ assert.match(result.stdout, /token refresh/);
222
+ assert.doesNotMatch(result.stdout, /Invoice export/);
223
+ assert.doesNotMatch(result.stdout, /posix path separators/);
224
+ assert.match(result.stderr, /handoff aware/);
225
+ assert.match(result.stderr, /source=stub/);
226
+ assert.match(result.stderr, /mode=dry-run/);
227
+ rmSync(cwd, { recursive: true, force: true });
228
+ });
229
+ });
230
+ describe("packs load", () => {
231
+ it("loads only relevant gotcha packs into .context/active/packs.md", async () => {
232
+ const cwd = mkdtempSync(join(tmpdir(), "tocket-packs-"));
233
+ writeContext(cwd);
234
+ const packs = collectGotchaPacks(cwd);
235
+ assert.ok(packs.some((pack) => pack.label === "frontend"));
236
+ assert.ok(packs.some((pack) => pack.label === "Frontend forms"));
237
+ assert.ok(packs.some((pack) => pack.label === "path-src-api"));
238
+ const result = await runPacksLoad({
239
+ cwd,
240
+ query: "frontend form",
241
+ dryRun: true,
242
+ now: () => NOW,
243
+ id: "packs",
244
+ });
245
+ assert.equal(result.record.kind, "packs");
246
+ assert.equal(result.record.source, "stub");
247
+ assert.match(result.markdown, /Validate the frontend form/);
248
+ assert.match(result.markdown, /Frontend form labels/);
249
+ assert.doesNotMatch(result.markdown, /Route handlers under src\/api/);
250
+ assert.doesNotMatch(result.markdown, /Migration order/);
251
+ const onDisk = readFileSync(result.packsPath, "utf-8");
252
+ assert.equal(onDisk, result.markdown);
253
+ assert.ok(includesPath(result.packsPath, ".context/active/packs.md"));
254
+ assert.ok(includesPath(result.attentionPath, ".context/attention/20260921T180000Z-packs.json"));
255
+ rmSync(cwd, { recursive: true, force: true });
256
+ });
257
+ it("CLI packs load --dry-run omits the unrelated pack", () => {
258
+ const cwd = mkdtempSync(join(tmpdir(), "tocket-packs-cli-"));
259
+ writeContext(cwd);
260
+ const result = runCli(["packs", "load", "--query", "frontend form", "--dry-run", "--to", "stdout"], cwd);
261
+ assert.equal(result.status, 0);
262
+ assert.match(result.stdout, /Validate the frontend form/);
263
+ assert.doesNotMatch(result.stdout, /Route handlers under src\/api/);
264
+ assert.match(result.stdout, /packs load/);
265
+ rmSync(cwd, { recursive: true, force: true });
266
+ });
267
+ });
268
+ //# sourceMappingURL=attention.test.js.map