UNPKG

akm-cli

Version:

akm (Agent Knowledge Manager) — a portable, local-first capability library for AI agents. Discover, load, share, and improve reusable skills, scripts, workflows, and knowledge across any shell-capable coding agent, including Claude Code, OpenCode, and Cur

54 lines (53 loc) • 2.52 kB
// This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. /** * ANSI escape sequences (CSI color/cursor codes). Defensive only: the builder * always passes `--no-pretty`, but a user profile may override that. * Constructed from a char code so no literal control character appears in * source (lint-friendly, same bytes). */ const ANSI_ESCAPE_RE = new RegExp(`${String.fromCharCode(27)}\\[[0-9;?]*[ -/]*[@-~]`, "g"); /** * Aider's own announcement lines — banner, model/repo configuration echo, * chat-history notices, edit/commit/usage reports. All patterns are anchored * at line start and match documented phrasings only; anything else is treated * as reply content. */ const NOISE_LINE_PATTERNS = [ /^aider v\d/, // version banner /^(Main model|Weak model|Editor model|Model):\s/, // model announcements /^Git repo:\s/, // repo detection /^Repo-map:\s/, // repo-map status /^Added .+ to the chat\.?$/, // file add notices /^Restored previous conversation history\.?$/, // chat-history reload notice /^Use \/help\b/, // onboarding hint line /^Tokens: .+/, // usage/cost footer /^Cost: .+/, // standalone cost footer /^Applied edit to .+/, // edit application notices /^Commit [0-9a-f]{6,}\b/, // auto-commit notices /^You can use \/undo\b/, // undo hint after auto-commit /^[─━-]{4,}$/, // ── / ━━ / ---- separator rules ]; function isNoiseLine(line) { return NOISE_LINE_PATTERNS.some((pattern) => pattern.test(line)); } /** * Normalize a raw aider run result into `{ text, sessionId? }`. * See the module doc for the stdout shape handled. */ export const aiderResultExtractor = (result) => { const raw = result.stdout.replace(ANSI_ESCAPE_RE, "").trim(); const kept = raw .split("\n") .filter((line) => !isNoiseLine(line.trim())) .join("\n") .trim(); // Never return empty text when stdout had content: an all-noise filter // outcome means the patterns over-matched for this capture, so fall back to // the full trimmed stdout (downstream parsing still gets material). const text = kept.length > 0 ? kept : raw; // No session model (chat-history files, not ids): only a spawn-layer id // passes through; output never supplies one. return result.sessionId === undefined ? { text } : { text, sessionId: result.sessionId }; };