@thenavidm/slipway 0.1.19 → 0.1.20

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
@@ -2,6 +2,10 @@
2
2
 
3
3
  What changed in Slipway, newest first.
4
4
 
5
+ ## 0.1.20, 2026-10-05: what Gumloop and Wistia needed
6
+
7
+ - **Each answer from `which` stays on one line.** A description wrapped to a width, or one whose summary line has no full stop, put a line break inside its first sentence, so `which` printed the rest of that sentence on a line of its own, cut off mid-word: Gumloop's `start-flow` read "This endpoint is used to trigger a flow run via API" and then "Explicit confirmation is re…". A line break now ends the first sentence when a blank line or a capital letter follows it, and reads as a space otherwise. 57 tools on eight servers had such a line, 27 of them Wistia's. The summaries `search_tools` returns are made the same way.
8
+
5
9
  ## 0.1.19, 2026-10-05: what Lemon Squeezy needed
6
10
 
7
11
  - **`which` answers with a command's help when one fits well ahead of the rest.** An agent asked `which` for the command and then read that command's `--help`, and each request carries the whole conversation. On Lemon Squeezy, `which cancel subscription` and then `cancel-subscription --help` cost Codex a median of 83,076 input tokens, where its 2.x CLI guessed the command's name and read its help in two requests for 61,541. When the first answer scores at least half again as much as the second, its help now follows the list, and three runs took 61,903, 61,913 and 61,908 in two requests. A close second gets the list alone: Gumroad's `which refund` fits refunding a sale and its refund policy alike, and the help shown would be a guess between them.
package/dist/search.d.ts CHANGED
@@ -14,5 +14,9 @@ export declare function searchTools(tools: readonly Tool[], query: string, limit
14
14
  /** Edit distance, for "did you mean" on a mistyped command. */
15
15
  export declare function distance(a: string, b: string): number;
16
16
  export declare function didYouMean(input: string, candidates: readonly string[]): string | undefined;
17
- /** The first sentence of a description, for one-line listings. */
17
+ /**
18
+ * The first sentence of a description, for one-line listings. A description wrapped to a width
19
+ * reads on as one line, and a summary line with no full stop ends at its line break: Gumloop's
20
+ * "List saved flows" is followed by "Read operation." on the next line.
21
+ */
18
22
  export declare function firstSentence(text: string, max?: number): string;
package/dist/search.js CHANGED
@@ -140,8 +140,12 @@ export function didYouMean(input, candidates) {
140
140
  }
141
141
  return best?.candidate;
142
142
  }
143
- /** The first sentence of a description, for one-line listings. */
143
+ /**
144
+ * The first sentence of a description, for one-line listings. A description wrapped to a width
145
+ * reads on as one line, and a summary line with no full stop ends at its line break: Gumloop's
146
+ * "List saved flows" is followed by "Read operation." on the next line.
147
+ */
144
148
  export function firstSentence(text, max = 100) {
145
- const first = text.trim().split(/(?<=[.!?])\s/)[0] ?? "";
149
+ const first = (text.trim().split(/(?<=[.!?])\s|\n\s*\n|\n(?=\s*[A-Z])/)[0] ?? "").replace(/\s+/g, " ").trim();
146
150
  return first.length > max ? `${first.slice(0, max - 1).trimEnd()}…` : first;
147
151
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thenavidm/slipway",
3
- "version": "0.1.19",
3
+ "version": "0.1.20",
4
4
  "description": "Slipway, the TypeScript framework for MCP servers and agent-native CLIs. One tool definition ships an MCP server and a CLI, with write safety, typed results and release checks built in.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",