mirror of
https://github.com/binaricat/Netcatty.git
synced 2026-10-09 15:58:34 +00:00
fe2f14f032
* fix(#3289): automated AI fix * fix: address Codex review on PR #3290 * fix: address Codex review on PR #3290 * fix: address Codex review on PR #3290 * fix: address Codex review on PR #3290 * fix: address Codex review on PR #3290 * fix: address Codex review on PR #3290 * fix: address Codex review on PR #3290 * fix: address Codex review on PR #3290 * fix: address Codex review on PR #3290 * fix: address Codex review on PR #3290 * fix: address Codex review on PR #3290 * fix: address Codex review on PR #3290 * fix: address Codex review on PR #3290 * fix: address Codex review on PR #3290 * fix: address Codex review on PR #3290 * fix: address Codex review on PR #3290 * fix: address Codex review on PR #3290 * fix: address Codex review on PR #3290 * fix: address Codex review on PR #3290 * fix: address Codex review on PR #3290 * fix: address Codex review on PR #3290 * fix: address Codex review on PR #3290 * fix(ai): apply note attachment budgets synchronously * fix(ai): reuse normalized note search fields while typing * fix(ai): retain draft state binding in panel host * fix(ai): reject carriage returns in note references * fix(ai): protect continuation before pruning note payloads * refactor(ai): keep note mentions as lightweight references * fix(ai): gate note references on reader availability * fix(ai): retain note references ahead of replay prose * refactor(ai): share one instruction across note references * fix(ai): keep accepted note references within replay space * Bound agent note reads and add resumable literal search * Preserve compact note requests and announce picker selection * Retain mixed attachment context in compact note replay * Keep imported long note identities readable * Keep note picker selection and untitled labels consistent --------- Co-authored-by: netcatty-bot <308658023+netcatty-bot@users.noreply.github.com> Co-authored-by: bincxz <16399091+binaricat@users.noreply.github.com>
55 lines
3.1 KiB
TypeScript
55 lines
3.1 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
import { createVaultNoteAttachment, formatVaultNoteReferences, vaultNoteReferencesFit } from "./vaultNoteAttachment.ts";
|
|
import { buildPromptWithTerminalSelectionAttachments, createTerminalSelectionAttachment, isInlineTextAttachment } from "./terminalSelectionAttachment.ts";
|
|
|
|
test("mentions carry identity without copying even large note bodies", () => {
|
|
const note = { id: "note-1", title: "Runbook", content: "secret body".repeat(200_000) };
|
|
const attachment = createVaultNoteAttachment(note)!;
|
|
assert.equal(attachment.vaultNoteId, note.id);
|
|
assert.equal(attachment.base64Data, "");
|
|
assert.equal(attachment.dataUrl, "");
|
|
assert.ok(JSON.stringify(attachment).length < 400);
|
|
assert.ok(isInlineTextAttachment(attachment));
|
|
const prompt = buildPromptWithTerminalSelectionAttachments("summarize", [attachment]);
|
|
assert.match(prompt, /vault_notes_get/);
|
|
assert.match(prompt, /latest content/);
|
|
assert.doesNotMatch(prompt, /secret body/);
|
|
});
|
|
|
|
test("same titled notes keep distinct exact IDs including imported special characters", () => {
|
|
for (const id of ["note-a", "note-b", ' quoted"\\id\r\n ']) {
|
|
const attachment = createVaultNoteAttachment({ id, title: "Same title" })!;
|
|
const reference = formatVaultNoteReferences([attachment]).split("\n")[0];
|
|
const [metadata] = JSON.parse(reference.slice("[Vault note references: ".length, -1));
|
|
assert.equal(metadata.noteId, id);
|
|
assert.equal(metadata.title, "Same title");
|
|
}
|
|
});
|
|
|
|
test("invalid IDs are rejected and displayed titles remain bounded without broken emoji", () => {
|
|
assert.equal(createVaultNoteAttachment({ id: " ", title: "x" }), null);
|
|
assert.equal(createVaultNoteAttachment({ id: "a".repeat(201), title: "x" }), null);
|
|
const attachment = createVaultNoteAttachment({ id: "ok", title: "😀".repeat(200) })!;
|
|
assert.equal(Array.from(attachment.vaultNoteTitle!).length, 120);
|
|
});
|
|
|
|
test("note-only sends and mixed terminal selections retain both kinds of context", () => {
|
|
const note = createVaultNoteAttachment({ id: "empty-note", title: "" })!;
|
|
const terminal = createTerminalSelectionAttachment("systemctl status nginx")!;
|
|
assert.match(buildPromptWithTerminalSelectionAttachments("", [note]), /empty-note/);
|
|
const prompt = buildPromptWithTerminalSelectionAttachments("compare", [note, terminal]);
|
|
assert.match(prompt, /systemctl status nginx/);
|
|
assert.match(prompt, /empty-note/);
|
|
assert.match(prompt, /^compare/);
|
|
});
|
|
|
|
test("reference limit reserves replay space and does not count ordinary files", () => {
|
|
const notes = Array.from({length: 10}, (_, i) => createVaultNoteAttachment({id: String(i).padEnd(200, "x"), title: "t".repeat(120)})!);
|
|
assert.equal(vaultNoteReferencesFit(notes), false);
|
|
const accepted = notes.filter((_, index) => vaultNoteReferencesFit(notes.slice(0, index + 1)));
|
|
assert.ok(accepted.length > 0);
|
|
assert.ok(formatVaultNoteReferences(accepted).length <= 1000);
|
|
assert.equal(vaultNoteReferencesFit([...accepted, {id: "file", filename: "file", mediaType: "text/plain", dataUrl: "", base64Data: "x".repeat(2_000_000)}]), true);
|
|
});
|