@yagni-app/code-staging 1.0.1-staging.1194.1 → 1.0.1-staging.1195.1

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.
@@ -46,6 +46,7 @@ import { makeAuthedFetch, makeTokenProvider } from "./tokenProvider.js";
46
46
  import { attributionHeaders, fetchCatalog as defaultFetchCatalog, fetchContextBrief as defaultFetchContextBrief, getToken, getTokenExpiresAt as defaultGetTokenExpiresAt, getWorkspaceId as defaultGetWorkspaceId, isDriverCaller, resolveBaseUrl, tokenExpiryNotice, } from "./config.js";
47
47
  import { buildYagniProvider } from "./provider.js";
48
48
  import { registerChipEditor } from "./chipEditor.js";
49
+ import { registerSlashCommandFilter } from "./slashCommandFilter.js";
49
50
  import { defaultMineBeatGit, fileMineBeatMarkers, maybeOfferMiningBeat as defaultMaybeOfferMiningBeat, } from "./mineBeat.js";
50
51
  import { makeFlywheelState } from "./flywheel.js";
51
52
  import { registerSilentTurnReminder } from "./silentTurnReminder.js";
@@ -219,6 +220,11 @@ export async function registerYagni(pi, deps = {}) {
219
220
  // temp path, and registers the input transform that turns chips into image
220
221
  // attachments for the model. No-op outside TUI mode.
221
222
  registerChipEditor(pi);
223
+ // Hide pi's built-in slash commands that contradict YAGNI's single-provider,
224
+ // single-identity model (e.g. /share gist upload, /login <provider>) from
225
+ // slash-discovery. TUI autocomplete only; the desktop palette already
226
+ // excludes built-ins, and this is a no-op in RPC/print modes.
227
+ registerSlashCommandFilter(pi);
222
228
  // The general subagent tool: delegate self-contained tasks (optionally in
223
229
  // parallel) to fresh-context agents defined in .claude/agents / .pi/agents,
224
230
  // riding the /go pipeline's child runner. /agents lists what's available.
@@ -0,0 +1,30 @@
1
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
2
+ /**
3
+ * Slash-command filtering for the CLI.
4
+ *
5
+ * pi ships its own built-in slash commands (see `BUILTIN_SLASH_COMMANDS` in
6
+ * pi's `core/slash-commands.js`) and bakes them directly into its interactive
7
+ * autocomplete provider (`createBaseAutocompleteProvider`). Most are
8
+ * pi-generic and harmless (`/new`, `/compact`, `/settings`), but a subset
9
+ * contradict YAGNI's single-provider, single-identity model — or leak pi
10
+ * features YAGNI deliberately does not surface — and only confuse a YAGNI Code
11
+ * user. We hide those from slash-discovery.
12
+ *
13
+ * Scope note: this filters DISCOVERY only. pi dispatches built-in commands in
14
+ * its own private `onSubmit` chain (not from the autocomplete list), so a
15
+ * hidden command can still be typed by hand — the same bar pi itself draws for
16
+ * its easter-egg commands, which are also absent from autocomplete. Removing
17
+ * them from the list is the whole intent: a YAGNI user should not be offered
18
+ * `/share` (ships a transcript to a GitHub gist) or `/login <provider>` (pi
19
+ * provider auth) when YAGNI's model is a single `yagni` provider.
20
+ *
21
+ * The desktop palette is unaffected: pi's RPC `get_commands` (which the desktop
22
+ * app reads) already returns extension commands + prompt templates + skills and
23
+ * never includes built-ins. This wrapper is inert outside interactive TUI mode,
24
+ * where `addAutocompleteProvider` is handed a no-op factory.
25
+ */
26
+ /** pi built-in slash commands hidden from YAGNI Code autocomplete. */
27
+ export declare const HIDDEN_BUILTIN_SLASH_COMMANDS: readonly string[];
28
+ /** Register the slash-command filter on `session_start` (TUI autocomplete only). */
29
+ export declare function registerSlashCommandFilter(pi: ExtensionAPI): void;
30
+ //# sourceMappingURL=slashCommandFilter.d.ts.map
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Slash-command filtering for the CLI.
3
+ *
4
+ * pi ships its own built-in slash commands (see `BUILTIN_SLASH_COMMANDS` in
5
+ * pi's `core/slash-commands.js`) and bakes them directly into its interactive
6
+ * autocomplete provider (`createBaseAutocompleteProvider`). Most are
7
+ * pi-generic and harmless (`/new`, `/compact`, `/settings`), but a subset
8
+ * contradict YAGNI's single-provider, single-identity model — or leak pi
9
+ * features YAGNI deliberately does not surface — and only confuse a YAGNI Code
10
+ * user. We hide those from slash-discovery.
11
+ *
12
+ * Scope note: this filters DISCOVERY only. pi dispatches built-in commands in
13
+ * its own private `onSubmit` chain (not from the autocomplete list), so a
14
+ * hidden command can still be typed by hand — the same bar pi itself draws for
15
+ * its easter-egg commands, which are also absent from autocomplete. Removing
16
+ * them from the list is the whole intent: a YAGNI user should not be offered
17
+ * `/share` (ships a transcript to a GitHub gist) or `/login <provider>` (pi
18
+ * provider auth) when YAGNI's model is a single `yagni` provider.
19
+ *
20
+ * The desktop palette is unaffected: pi's RPC `get_commands` (which the desktop
21
+ * app reads) already returns extension commands + prompt templates + skills and
22
+ * never includes built-ins. This wrapper is inert outside interactive TUI mode,
23
+ * where `addAutocompleteProvider` is handed a no-op factory.
24
+ */
25
+ /** pi built-in slash commands hidden from YAGNI Code autocomplete. */
26
+ export const HIDDEN_BUILTIN_SLASH_COMMANDS = [
27
+ "share", // ships a session transcript to a secret GitHub gist (off-brand + privacy footgun)
28
+ "login", // pi provider auth; YAGNI auth is `yagni login`, one provider
29
+ "logout", // pi provider auth; YAGNI auth is `yagni logout`
30
+ "scoped-models", // pi multi-model Ctrl+P cycling; YAGNI pins a single tier
31
+ "fork", // pi session-fork feature YAGNI never surfaces
32
+ "clone", // pi session-clone feature YAGNI never surfaces
33
+ "tree", // pi session-tree feature YAGNI never surfaces
34
+ "trust", // pi project-trust prompt; collides with YAGNI guardrails
35
+ "changelog", // pi's own changelog, not YAGNI's
36
+ ];
37
+ const HIDDEN = new Set(HIDDEN_BUILTIN_SLASH_COMMANDS);
38
+ /**
39
+ * True when the text before the cursor is a slash-COMMAND name being typed —
40
+ * a leading `/` plus a name with no interior `/` or space. This mirrors pi's
41
+ * own slash-command detection (its `applyCompletion` treats a prefix with an
42
+ * interior `/` as a file path, e.g. the absolute path `/usr/local/...`), so we
43
+ * never strip a legitimate file-named completion.
44
+ */
45
+ function isSlashCommandName(textBeforeCursor) {
46
+ return textBeforeCursor.startsWith("/")
47
+ && !textBeforeCursor.slice(1).includes("/")
48
+ && !textBeforeCursor.slice(1).includes(" ");
49
+ }
50
+ function filterHiddenSlashSuggestions(suggestions) {
51
+ const items = suggestions.items.filter((item) => !HIDDEN.has(item.value));
52
+ if (items.length === 0)
53
+ return null;
54
+ return { ...suggestions, items };
55
+ }
56
+ /** Wrap pi's built-in autocomplete provider so hidden built-ins never complete. */
57
+ function makeYagniAutocompleteProvider(current) {
58
+ return {
59
+ triggerCharacters: current.triggerCharacters,
60
+ async getSuggestions(lines, cursorLine, cursorCol, options) {
61
+ const textBeforeCursor = (lines[cursorLine] ?? "").slice(0, cursorCol);
62
+ if (!isSlashCommandName(textBeforeCursor)) {
63
+ return current.getSuggestions(lines, cursorLine, cursorCol, options);
64
+ }
65
+ const suggestions = await current.getSuggestions(lines, cursorLine, cursorCol, options);
66
+ return suggestions ? filterHiddenSlashSuggestions(suggestions) : null;
67
+ },
68
+ applyCompletion(lines, cursorLine, cursorCol, item, prefix) {
69
+ return current.applyCompletion(lines, cursorLine, cursorCol, item, prefix);
70
+ },
71
+ shouldTriggerFileCompletion(lines, cursorLine, cursorCol) {
72
+ return current.shouldTriggerFileCompletion?.(lines, cursorLine, cursorCol) ?? true;
73
+ },
74
+ };
75
+ }
76
+ /** Register the slash-command filter on `session_start` (TUI autocomplete only). */
77
+ export function registerSlashCommandFilter(pi) {
78
+ pi.on("session_start", (_event, ctx) => {
79
+ if (ctx.mode !== "tui" || !ctx.hasUI)
80
+ return;
81
+ try {
82
+ ctx.ui.addAutocompleteProvider(makeYagniAutocompleteProvider);
83
+ }
84
+ catch {
85
+ // Filtering is cosmetic; a failure must never break session start.
86
+ }
87
+ });
88
+ }
89
+ //# sourceMappingURL=slashCommandFilter.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yagni-app/code-staging",
3
- "version": "1.0.1-staging.1194.1",
3
+ "version": "1.0.1-staging.1195.1",
4
4
  "description": "YAGNI Code: a terminal coding agent that already knows your company. One YAGNI login routes the model and grounds the agent in your team's context.",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "author": "YAGNI, Inc. <jack@yagni.app> (https://yagni.app)",
@@ -41,5 +41,5 @@
41
41
  "turndown": "^7.2.4",
42
42
  "typebox": "^1.3.15"
43
43
  },
44
- "yagniSourceSha": "35074745ec6180e38a015e902c91bd2e10a1fa7d"
44
+ "yagniSourceSha": "94552f071c671de30adbf48b73c34999e9c831d2"
45
45
  }