akm-cli 0.9.16-alpha.2 → 0.9.16

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/CHANGELOG.md CHANGED
@@ -6,7 +6,23 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
- ## [0.9.16-alpha.2] - 2026-09-21
9
+ ## [0.9.16] - 2026-09-22
10
+
11
+ ### Fixed
12
+
13
+ - **Result documents larger than 64 KiB are no longer truncated on a piped
14
+ stdout.** `akm show`/`search`/`config get … | python3 -c …` (or `| head`, or
15
+ any other pipe) returned exactly 65,536 bytes — the Linux pipe-buffer size —
16
+ producing unparseable JSON, while the same command with `--output <file>`
17
+ wrote the complete document. The two stdout writers (`deliverRendered` for
18
+ json/yaml/text/md/html, `outputJsonl` for jsonl) used `console.log`, and on
19
+ Bun `console.log` issues a single `write(2)` against a non-blocking fd 1 and
20
+ silently discards whatever the kernel did not accept; a pipe accepts at most
21
+ one buffer's worth. Both now go through `writeStdout`
22
+ (`src/output/stdout.ts`), which uses `process.stdout.write` — that handles
23
+ the short write correctly, and the queued remainder keeps the process alive
24
+ until it drains. Byte-for-byte output is unchanged on every format; only the
25
+ transport moved.
10
26
 
11
27
  ### Added
12
28
 
@@ -16,6 +16,7 @@ import fs from "node:fs";
16
16
  import path from "node:path";
17
17
  import healthTemplate from "../assets/templates/html/health.html" with { type: "text" };
18
18
  import { getDirname } from "../runtime.js";
19
+ import { writeStdout } from "./stdout.js";
19
20
  const TEMPLATES_DIR = path.join(getDirname(import.meta.url), "../assets/templates/html");
20
21
  /**
21
22
  * Templates embedded at build time, keyed by command name.
@@ -103,5 +104,5 @@ export function deliverRendered(content, outputPath) {
103
104
  fs.writeFileSync(outputPath, content.endsWith("\n") ? content : `${content}\n`);
104
105
  return;
105
106
  }
106
- console.log(content);
107
+ writeStdout(content);
107
108
  }
@@ -0,0 +1,24 @@
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ /**
5
+ * The single stdout writer for result documents.
6
+ *
7
+ * WHY NOT `console.log`: on Bun, once `process.stdout` has been materialized
8
+ * as a Node-compat stream — which this CLI does unconditionally, since
9
+ * `--help`/`hints` write through it and `src/output/context.ts` reads
10
+ * `isTTY` — `console.log(bigString)` issues a SINGLE `write(2)` against a
11
+ * non-blocking fd 1 and silently discards whatever the kernel refused. A pipe
12
+ * accepts at most one buffer (65,536 bytes on Linux), so `akm show … |
13
+ * python3` lost everything past 64 KiB while `--output <file>` wrote the
14
+ * whole document. `process.stdout.write` handles the short write correctly on
15
+ * both runtimes, and the queued remainder keeps the event loop alive until it
16
+ * drains, so the natural exit at the end of `runCli` still flushes it.
17
+ *
18
+ * The trailing newline is UNCONDITIONAL because that is exactly what
19
+ * `console.log` appended: this is a transport fix, not a format change, and
20
+ * `tests/integration/output-baseline.test.ts` pins the bytes either way.
21
+ */
22
+ export function writeStdout(document) {
23
+ process.stdout.write(`${document}\n`);
24
+ }
@@ -1,6 +1,7 @@
1
1
  // This Source Code Form is subject to the terms of the Mozilla Public
2
2
  // License, v. 2.0. If a copy of the MPL was not distributed with this
3
3
  // file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
+ import { writeStdout } from "./stdout.js";
4
5
  import { addFormatters } from "./text/add.js";
5
6
  import { bundleCreateFormatters } from "./text/bundle-create.js";
6
7
  import { bundleShowFormatters } from "./text/bundle-show.js";
@@ -75,16 +76,16 @@ export function outputJsonl(command, shaped) {
75
76
  const r = shaped;
76
77
  const hits = Array.isArray(r.hits) ? r.hits : [];
77
78
  for (const hit of hits) {
78
- console.log(JSON.stringify(hit));
79
+ writeStdout(JSON.stringify(hit));
79
80
  }
80
81
  const registryHits = Array.isArray(r.registryHits) ? r.registryHits : [];
81
82
  for (const hit of registryHits) {
82
- console.log(JSON.stringify(hit));
83
+ writeStdout(JSON.stringify(hit));
83
84
  }
84
85
  return;
85
86
  }
86
87
  // For non-search commands, output the whole object as a single JSONL line
87
- console.log(JSON.stringify(shaped));
88
+ writeStdout(JSON.stringify(shaped));
88
89
  }
89
90
  // ── Dispatcher ────────────────────────────────────────────────────────────────
90
91
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "akm-cli",
3
- "version": "0.9.16-alpha.2",
3
+ "version": "0.9.16",
4
4
  "type": "module",
5
5
  "description": "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 Cursor.",
6
6
  "keywords": [