( pi: ExtensionAPI, config: PiSidekickConfig | undefined, )
| 81 | * than hiding the command entirely. |
| 82 | */ |
| 83 | export function registerCtxAugCommand( |
| 84 | pi: ExtensionAPI, |
| 85 | config: PiSidekickConfig | undefined, |
| 86 | ): void { |
| 87 | const runner = new PiSubagentRunner(); |
| 88 | |
| 89 | pi.registerCommand("ctx-aug", { |
| 90 | description: "Augment your prompt with relevant project context (sidekick)", |
| 91 | handler: async (args, ctx) => { |
| 92 | const prompt = args.trim(); |
| 93 | |
| 94 | // Use Pi's session entry IDs for log correlation. The session |
| 95 | // manager's branch always has at least the current entry. |
| 96 | const branch = ctx.sessionManager.getBranch(); |
| 97 | const lastEntryId = |
| 98 | branch.length > 0 ? branch[branch.length - 1]?.id : "unknown"; |
| 99 | const sessionLabel = `pi-session-${lastEntryId}`; |
| 100 | |
| 101 | if (!config) { |
| 102 | ctx.ui.notify( |
| 103 | "/ctx-aug: Sidekick is not configured. Add `sidekick.model` to your magic-context.jsonc to enable this command.", |
| 104 | "warning", |
| 105 | ); |
| 106 | return; |
| 107 | } |
| 108 | |
| 109 | if (prompt.length === 0) { |
| 110 | ctx.ui.notify( |
| 111 | "/ctx-aug: Usage `/ctx-aug <your prompt>` — provide a prompt to augment with project memory context.", |
| 112 | "info", |
| 113 | ); |
| 114 | return; |
| 115 | } |
| 116 | |
| 117 | // Inform the user. In print/rpc mode this is a no-op (hasUI=false), |
| 118 | // which is correct: the user invoked /ctx-aug from a non-interactive |
| 119 | // context and just wants the augmented turn to fire. |
| 120 | if (ctx.hasUI) { |
| 121 | ctx.ui.notify( |
| 122 | "🔍 Preparing augmentation… 2-10s depending on your sidekick provider.", |
| 123 | "info", |
| 124 | ); |
| 125 | } |
| 126 | |
| 127 | sessionLog(sessionLabel, "/ctx-aug: spawning sidekick", { |
| 128 | model: config.model, |
| 129 | }); |
| 130 | |
| 131 | // Spawn sidekick as a Pi subprocess. The subagent inherits the |
| 132 | // current project's cwd so its tool calls (notably `ctx_search`) |
| 133 | // resolve against the same project identity as the invoking |
| 134 | // session. This is what makes cross-harness memory sharing work: |
| 135 | // sidekick sees the same memories whether spawned from Pi or |
| 136 | // OpenCode at the same cwd. |
| 137 | const projectIdentity = resolveProjectIdentity(ctx.cwd); |
| 138 | sessionLog(sessionLabel, "/ctx-aug: project identity", projectIdentity); |
| 139 | |
| 140 | const result = await runner.run({ |
no test coverage detected