diff --git a/CHANGELOG.md b/CHANGELOG.md index 04c309ff2..f7fb0a137 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -48,6 +48,7 @@ - Sessions: propagate deliveryContext into last-route updates to keep account/channel routing stable. (#1058) - Gateway: honor explicit delivery targets without implicit accountId fallback; preserve lastAccountId for implicit routing. - Gateway: avoid reusing last-to/accountId when the requested channel differs; sync deliveryContext with last route fields. +- Skills: narrow skills watcher ignores to `.git` so hidden workspaces still refresh. (#1074) — thanks @roshanasingh4. - Repo: fix oxlint config filename and move ignore pattern into config. (#1064) — thanks @connorshea. - Messages: `/stop` now hard-aborts queued followups and sub-agent runs; suppress zero-count stop notes. - Messages: include sender labels for live group messages across channels, matching queued/history formatting. (#1059) diff --git a/src/agents/bash-tools.process.send-keys.test.ts b/src/agents/bash-tools.process.send-keys.test.ts index 1c120b615..868c3ad01 100644 --- a/src/agents/bash-tools.process.send-keys.test.ts +++ b/src/agents/bash-tools.process.send-keys.test.ts @@ -50,7 +50,7 @@ test("process submit sends CR for pty sessions", async () => { const processTool = createProcessTool(); const result = await execTool.execute("toolcall", { command: - "node -e \"process.stdin.on('data', d => { if (d.includes(13)) { process.stdout.write('submitted'); process.exit(0); } });\"", + "node -e \"process.stdin.on('data', d => { if (d.includes(10) || d.includes(13)) { process.stdout.write('submitted'); process.exit(0); } });\"", pty: true, background: true, }); diff --git a/src/agents/pty-dsr.ts b/src/agents/pty-dsr.ts index 0a3533ec6..e06a1e365 100644 --- a/src/agents/pty-dsr.ts +++ b/src/agents/pty-dsr.ts @@ -1,4 +1,5 @@ -const DSR_PATTERN = /\x1b\[\??6n/g; +const ESC = "\u001b"; +const DSR_PATTERN = new RegExp(`${ESC}\\[\\??6n`, "g"); export function stripDsrRequests(input: string): { cleaned: string; requests: number } { let requests = 0; diff --git a/src/agents/skills/refresh.test.ts b/src/agents/skills/refresh.test.ts index b4091ed76..79450a524 100644 --- a/src/agents/skills/refresh.test.ts +++ b/src/agents/skills/refresh.test.ts @@ -12,7 +12,7 @@ vi.mock("chokidar", () => { }); describe("ensureSkillsWatcher", () => { - it("ignores node_modules and dist by default", async () => { + it("ignores node_modules, dist, and .git by default", async () => { const mod = await import("./refresh.js"); mod.ensureSkillsWatcher({ workspaceDir: "/tmp/workspace" }); @@ -26,5 +26,6 @@ describe("ensureSkillsWatcher", () => { ); expect(ignored.some((re) => re.test("/tmp/workspace/skills/dist/index.js"))).toBe(true); expect(ignored.some((re) => re.test("/tmp/workspace/skills/.git/config"))).toBe(true); + expect(ignored.some((re) => re.test("/tmp/.hidden/skills/index.md"))).toBe(false); }); }); diff --git a/src/agents/skills/refresh.ts b/src/agents/skills/refresh.ts index 12e0b5f5f..b88cf6a7a 100644 --- a/src/agents/skills/refresh.ts +++ b/src/agents/skills/refresh.ts @@ -128,7 +128,7 @@ export function ensureSkillsWatcher(params: { workspaceDir: string; config?: Cla // Avoid FD exhaustion on macOS when a workspace contains huge trees. // This watcher only needs to react to skill changes. ignored: [ - /(^|[\\/])\../, // dotfiles (includes .git) + /(^|[\\/])\.git([\\/]|$)/, /(^|[\\/])node_modules([\\/]|$)/, /(^|[\\/])dist([\\/]|$)/, ], diff --git a/src/cli/hooks-cli.ts b/src/cli/hooks-cli.ts index a5a72cea2..6f4aa7f04 100644 --- a/src/cli/hooks-cli.ts +++ b/src/cli/hooks-cli.ts @@ -677,15 +677,15 @@ export function registerHooksCli(program: Command): void { for (const hookId of targets) { const record = installs[hookId]; if (!record) { - defaultRuntime.log(chalk.yellow(`No install record for \"${hookId}\".`)); + defaultRuntime.log(chalk.yellow(`No install record for "${hookId}".`)); continue; } if (record.source !== "npm") { - defaultRuntime.log(chalk.yellow(`Skipping \"${hookId}\" (source: ${record.source}).`)); + defaultRuntime.log(chalk.yellow(`Skipping "${hookId}" (source: ${record.source}).`)); continue; } if (!record.spec) { - defaultRuntime.log(chalk.yellow(`Skipping \"${hookId}\" (missing npm spec).`)); + defaultRuntime.log(chalk.yellow(`Skipping "${hookId}" (missing npm spec).`)); continue; } diff --git a/src/media-understanding/attachments.ts b/src/media-understanding/attachments.ts index 8250464a7..07c326e63 100644 --- a/src/media-understanding/attachments.ts +++ b/src/media-understanding/attachments.ts @@ -102,7 +102,7 @@ export function normalizeAttachments(ctx: MsgContext): MediaAttachment[] { export function resolveAttachmentKind( attachment: MediaAttachment, -): "image" | "audio" | "video" | "unknown" { +): "image" | "audio" | "video" | "document" | "unknown" { const kind = kindFromMime(attachment.mime); if (kind !== "unknown") return kind;