@sage-protocol/pi-adapter 0.2.2 → 0.3.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.
- package/README.md +33 -290
- package/SKILL.md +20 -2
- package/dist/sage-pi-adapter.d.ts +24 -11
- package/dist/sage-pi-adapter.d.ts.map +1 -1
- package/dist/sage-pi-adapter.js +242 -128
- package/dist/sage-pi-adapter.js.map +1 -1
- package/extensions/index.ts +303 -44
- package/package.json +2 -2
- package/skills/sage-bridge/SKILL.md +43 -5
package/README.md
CHANGED
|
@@ -2,333 +2,76 @@
|
|
|
2
2
|
|
|
3
3
|
Sage integration for the pi coding agent runtime.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
-
|
|
7
|
-
- Developer guide: `docs/developer.md`
|
|
5
|
+
- **Pi agent**: [earendil-works/pi](https://github.com/earendil-works/pi) — extensible terminal coding harness
|
|
6
|
+
- **Sage Protocol**: [sage-protocol/sage](https://github.com/sage-protocol/sage) — decentralized skill/library layer for AI agents
|
|
8
7
|
|
|
9
|
-
It
|
|
10
|
-
- Sage MCP tools in pi (`sage_search`, `sage_execute`, `sage_status`)
|
|
11
|
-
- **Dynamic identity context** — wallet, active libraries, and skill counts injected into every turn's system prompt
|
|
12
|
-
- Session hook integration (`sage skill context`, `sage suggest hook skill`)
|
|
13
|
-
- RLM capture hooks (`sage capture hook prompt/response`)
|
|
14
|
-
- Optional pre/post tool security scanning (`sage security scan-hook`)
|
|
8
|
+
## What It Does
|
|
15
9
|
|
|
16
|
-
Sage
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
Every pi session automatically gets Sage Protocol identity context injected into the system prompt. The agent knows who it's working for without any configuration.
|
|
21
|
-
|
|
22
|
-
What gets injected (example):
|
|
23
|
-
|
|
24
|
-
```
|
|
25
|
-
## Sage Protocol Context
|
|
26
|
-
Sage Protocol is a decentralized network for collaborative prompt, skill, and knowledge
|
|
27
|
-
curation on Base (L2). Skills and prompts live in libraries governed by DAOs. Creators
|
|
28
|
-
and curators earn when their work is used. SXXX is the governance token: hold it to
|
|
29
|
-
vote, create DAOs, and shape the protocol. Burns from activity create deflationary
|
|
30
|
-
pressure — early participants gain governance influence and economic upside as the
|
|
31
|
-
network grows. The more skills published, the more valuable discovery becomes for every
|
|
32
|
-
user and agent.
|
|
33
|
-
|
|
34
|
-
### Active Identity
|
|
35
|
-
- Wallet: 0x9794...507ca (privy, Base Sepolia)
|
|
36
|
-
- Active libraries (6): sage-entrypoints, impeccable-ui-review, sage-review-foundations, ...
|
|
37
|
-
- Libraries: 10 installed (48 skills, 12 prompts)
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
This makes every pi session "sage-aware" — the agent knows the active wallet, network, installed libraries, and available skill count. The context is fetched from the sage CLI (`wallet current`, `library active`, `library list`) and cached for 60 seconds to avoid redundant calls.
|
|
41
|
-
|
|
42
|
-
**Extension mode**: Identity context is appended to the system prompt on every turn via the `before_agent_start` hook.
|
|
43
|
-
|
|
44
|
-
**SDK mode**: Identity context is injected as a hook message at session start via `setupHooks`.
|
|
45
|
-
|
|
46
|
-
The feature is always-on when the sage CLI is available. If the CLI is missing or any query fails, the identity block is silently omitted — it never blocks the agent turn.
|
|
47
|
-
|
|
48
|
-
For model-driven patching, see `packages/sage-pi-adapter/SKILL.md`.
|
|
49
|
-
|
|
50
|
-
## Requirements
|
|
51
|
-
|
|
52
|
-
- Node project using `@mariozechner/pi-coding-agent`
|
|
53
|
-
- Sage CLI installed and on `PATH` (`sage`)
|
|
54
|
-
|
|
55
|
-
## Choose the Right Integration Mode
|
|
56
|
-
|
|
57
|
-
There are two different scenarios:
|
|
58
|
-
|
|
59
|
-
1. You own harness source code (SDK embedding with `createAgentSession`) -> use this package directly.
|
|
60
|
-
2. You only run installed `pi` CLI (`npm i -g @mariozechner/pi-coding-agent`) -> install this package with `pi install`.
|
|
61
|
-
|
|
62
|
-
This package now ships a pi extension entrypoint, so CLI users do not need to patch harness internals.
|
|
10
|
+
- Sage MCP tools (`sage_search`, `sage_execute`, `sage_status`, `sage_behavior`)
|
|
11
|
+
- **Visible skill loading** — shows loaded library/skill count at session start
|
|
12
|
+
- **Dynamic session context** — wallet, libraries, and skill routing injected via `sage skill context --format pi`
|
|
13
|
+
- Skill suggestions, RLM capture, and optional security scanning
|
|
63
14
|
|
|
64
15
|
## Install
|
|
65
16
|
|
|
66
17
|
```bash
|
|
67
|
-
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
For pi CLI extension mode:
|
|
71
|
-
|
|
72
|
-
```bash
|
|
18
|
+
# pi CLI extension (no source changes)
|
|
73
19
|
pi install npm:@sage-protocol/pi-adapter
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
For local development from this monorepo:
|
|
77
|
-
|
|
78
|
-
```bash
|
|
79
|
-
npm link /path/to/sage-protocol/packages/sage-pi-adapter
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
Verify extension mode:
|
|
83
|
-
|
|
84
|
-
```bash
|
|
85
|
-
pi list
|
|
86
|
-
# should include npm:@sage-protocol/pi-adapter
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
CI validates the packed tarball against the latest published `pi` CLI by running
|
|
90
|
-
`npx @mariozechner/pi-coding-agent@latest install` in an isolated HOME and local
|
|
91
|
-
project workspace.
|
|
92
|
-
|
|
93
|
-
## pi CLI Mode (No Harness Source Changes)
|
|
94
|
-
|
|
95
|
-
After `pi install npm:@sage-protocol/pi-adapter`, restart `pi` and use it normally.
|
|
96
|
-
|
|
97
|
-
What loads automatically in extension mode:
|
|
98
|
-
|
|
99
|
-
- custom tools: `sage_search`, `sage_execute`, `sage_status`
|
|
100
|
-
- prompt hooks: `sage suggest hook skill`
|
|
101
|
-
- capture hooks: `sage capture hook prompt/response`
|
|
102
|
-
- security hooks: `sage security scan-hook` on tool pre/post
|
|
103
|
-
|
|
104
|
-
Optional environment overrides:
|
|
105
|
-
|
|
106
|
-
```bash
|
|
107
|
-
export SAGE_BIN=sage
|
|
108
|
-
export SAGE_PROFILE=testnet
|
|
109
|
-
export SAGE_SUGGEST_LIMIT=3
|
|
110
|
-
export SAGE_SUGGEST_DEBOUNCE_MS=800
|
|
111
|
-
export SAGE_SECURITY_HOOKS=1
|
|
112
|
-
export SAGE_RLM_FEEDBACK=1
|
|
113
|
-
export SAGE_SHOW_HOOK_MESSAGES=1
|
|
114
|
-
export SAGE_ALLOW_BASH_CLI=0 # optional: force MCP-only routing; direct `sage ...` calls are allowed by default, and `env SAGE_ALLOW_BASH_CLI=1 sage ...` re-enables per command
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
Manual hook command check (hook reads prompt from env/stdin, not positional args):
|
|
118
|
-
|
|
119
|
-
```bash
|
|
120
|
-
PROMPT="cpp libraries" SAGE_SOURCE=pi-extension sage suggest hook skill --limit 3
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
`sage suggest hook skill "cpp libraries"` is expected to fail because hook mode does not accept positional query text.
|
|
124
|
-
|
|
125
|
-
Use plain query mode when testing manually without hook env:
|
|
126
|
-
|
|
127
|
-
```bash
|
|
128
|
-
sage suggest skill "cpp libraries"
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
## Recommended Project Config For Entrypoint Development
|
|
132
|
-
|
|
133
|
-
For a project-local pi setup where Sage owns routing and entrypoint behavior, keep pi
|
|
134
|
-
thin and explicitly point it at the Sage Pi export surface, not the raw Sage authoring root.
|
|
135
|
-
|
|
136
|
-
Recommended `.pi/settings.json` shape for local monorepo development:
|
|
137
20
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
"packages": [
|
|
141
|
-
"../packages/sage-pi-adapter",
|
|
142
|
-
{
|
|
143
|
-
"source": "../packages/sage-pi-export",
|
|
144
|
-
"skills": ["skills/*/SKILL.md"],
|
|
145
|
-
"extensions": [],
|
|
146
|
-
"prompts": [],
|
|
147
|
-
"themes": []
|
|
148
|
-
},
|
|
149
|
-
{
|
|
150
|
-
"source": "npm:oh-pi",
|
|
151
|
-
"extensions": ["!**"]
|
|
152
|
-
}
|
|
153
|
-
],
|
|
154
|
-
"skills": [
|
|
155
|
-
"-../.agents/skills/frontend-design/SKILL.md",
|
|
156
|
-
"-~/.pi/agent/skills/prompt-builder/SKILL.md",
|
|
157
|
-
"-~/.pi/agent/skills/sage/SKILL.md",
|
|
158
|
-
"-~/.pi/agent/skills/sage-codebase/SKILL.md"
|
|
159
|
-
],
|
|
160
|
-
"enableSkillCommands": true
|
|
161
|
-
}
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
Notes:
|
|
165
|
-
|
|
166
|
-
- Paths are relative to `.pi/settings.json`, so the `../packages/...` layout matches this monorepo shape.
|
|
167
|
-
- Prefer the curated `packages/sage-pi-export` surface over broad runtime roots such as `~/.local/share/sage/skills`, `~/.claude/skills`, or `~/.codex/skills`. Those runtime roots often contain backups, version snapshots, and third-party skills that create noisy Pi validation errors and collisions.
|
|
168
|
-
- Keep pi/OpenClaw as the transport and tool layer. Put routing policy and recurring entrypoint behavior in Sage skills and libraries instead of hard-coding them into the harness.
|
|
169
|
-
- Treat repo-authored Sage skills and entrypoint definitions as the authoring source, on-chain libraries as the shared distribution surface, and local sync as development convenience.
|
|
170
|
-
- A good pattern is one thin entrypoint library concept such as `sage-entrypoints` that dispatches into stable Sage-owned dependency libraries by key instead of duplicating their bodies.
|
|
171
|
-
- For example, an entrypoint layer can route into `code-review`, `ceo-plan-review`, or `vc-office-hours` from a stable dependency surface such as `sage-review-foundations` without embedding those skill bodies in the adapter or local config.
|
|
172
|
-
- `packages/sage/pi-export.manifest.json` is the source of truth for what Pi sees by default. `node scripts/util/sync-sage-pi-export.mjs` materializes that manifest into `packages/sage-pi-export/skills/` as symlinks to the real Sage-authored skills.
|
|
173
|
-
- If another plugin or harness layer also injects context automatically, avoid double-injection. Pick one place to do prompt/context steering.
|
|
174
|
-
|
|
175
|
-
## Harness Integration (Recommended)
|
|
176
|
-
|
|
177
|
-
```typescript
|
|
178
|
-
import { createAgentSession, createCodingTools } from '@mariozechner/pi-coding-agent';
|
|
179
|
-
import { createSageSessionConfig } from '@sage-protocol/pi-adapter';
|
|
180
|
-
|
|
181
|
-
export async function createSessionWithSage(model: any, cwd = process.cwd()) {
|
|
182
|
-
const sage = await createSageSessionConfig({
|
|
183
|
-
sageBin: 'sage',
|
|
184
|
-
source: 'pi-agent-core',
|
|
185
|
-
suggestLimit: 3,
|
|
186
|
-
enableRlmFeedback: true,
|
|
187
|
-
enableSecurityHooks: true,
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
const { session } = await createAgentSession({
|
|
191
|
-
model,
|
|
192
|
-
tools: sage.wrapToolsWithSecurity(createCodingTools(cwd)),
|
|
193
|
-
customTools: sage.customTools,
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
const disposeSageHooks = sage.setupHooks(session);
|
|
197
|
-
|
|
198
|
-
return {
|
|
199
|
-
session,
|
|
200
|
-
dispose: async () => {
|
|
201
|
-
disposeSageHooks();
|
|
202
|
-
await sage.mcpBridge.stop();
|
|
203
|
-
},
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
## Integrate Into an Existing Harness (Model-Directed)
|
|
209
|
-
|
|
210
|
-
If this package is on npm, you can ask a coding model to patch your harness directly.
|
|
211
|
-
|
|
212
|
-
Important: make sure the model is operating in the harness repository (for example `pi-mono`), not in `sage-protocol/packages/sage-pi-adapter`.
|
|
213
|
-
|
|
214
|
-
Preflight checks to include in your instruction:
|
|
215
|
-
|
|
216
|
-
```bash
|
|
217
|
-
npm view @sage-protocol/pi-adapter version
|
|
218
|
-
npm config get registry
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
Use this instruction block as-is:
|
|
222
|
-
|
|
223
|
-
```text
|
|
224
|
-
Install @sage-protocol/pi-adapter and patch the session bootstrap to:
|
|
225
|
-
1) create const sage = await createSageSessionConfig(...)
|
|
226
|
-
2) set customTools: sage.customTools
|
|
227
|
-
3) wrap base tools with tools: sage.wrapToolsWithSecurity(existingTools)
|
|
228
|
-
4) call const disposeSageHooks = sage.setupHooks(session) after createAgentSession
|
|
229
|
-
5) call disposeSageHooks() during teardown
|
|
230
|
-
6) keep existing model/provider/settings behavior unchanged
|
|
231
|
-
7) if current workspace is not the harness repo, switch to it first and patch there
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
Helpful search targets for the model:
|
|
235
|
-
|
|
236
|
-
```bash
|
|
237
|
-
rg "createAgentSession|createCodingTools|customTools|tools:" src
|
|
238
|
-
rg "dispose|shutdown|teardown|cleanup" src
|
|
239
|
-
rg "createAgentSession|createCodingTools|customTools|tools:" packages/coding-agent
|
|
240
|
-
rg "dispose|shutdown|teardown|cleanup" packages/coding-agent
|
|
21
|
+
# SDK embedding
|
|
22
|
+
npm install @sage-protocol/pi-adapter
|
|
241
23
|
```
|
|
242
24
|
|
|
243
|
-
|
|
25
|
+
## Quick Start
|
|
244
26
|
|
|
245
27
|
```typescript
|
|
28
|
+
import { createAgentSession, createCodingTools } from '@earendil-works/pi-coding-agent';
|
|
246
29
|
import { createSageSessionConfig } from '@sage-protocol/pi-adapter';
|
|
247
30
|
|
|
248
|
-
const sage = await createSageSessionConfig({
|
|
249
|
-
source: 'pi-agent-core',
|
|
250
|
-
enableSecurityHooks: true,
|
|
251
|
-
enableRlmFeedback: true,
|
|
252
|
-
});
|
|
253
|
-
|
|
31
|
+
const sage = await createSageSessionConfig({ source: 'pi-agent-core' });
|
|
254
32
|
const { session } = await createAgentSession({
|
|
255
|
-
|
|
256
|
-
tools: sage.wrapToolsWithSecurity(existingTools),
|
|
33
|
+
tools: sage.wrapToolsWithSecurity(createCodingTools(process.cwd())),
|
|
257
34
|
customTools: sage.customTools,
|
|
258
35
|
});
|
|
259
|
-
|
|
260
36
|
const disposeSageHooks = sage.setupHooks(session);
|
|
261
|
-
// on shutdown: disposeSageHooks()
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
## Plugin Pattern
|
|
265
|
-
|
|
266
|
-
If your harness has a plugin/bootstrap layer, wire Sage there:
|
|
267
|
-
|
|
268
|
-
1. Construct config with `createSageSessionConfig(...)`
|
|
269
|
-
2. Add `customTools: sage.customTools`
|
|
270
|
-
3. Wrap existing tools with `sage.wrapToolsWithSecurity(...)`
|
|
271
|
-
4. Call `const dispose = sage.setupHooks(session)` after session creation
|
|
272
|
-
5. Call `dispose()` during teardown (and optionally `sage.mcpBridge.stop()`)
|
|
273
|
-
|
|
274
|
-
If your harness uses a plugin registry, expose Sage as one plugin:
|
|
275
|
-
|
|
276
|
-
```typescript
|
|
277
|
-
export async function setupSagePlugin(runtime: {
|
|
278
|
-
makeSession: (config: any) => Promise<{ session: any }>;
|
|
279
|
-
tools: any[];
|
|
280
|
-
model: any;
|
|
281
|
-
}) {
|
|
282
|
-
const sage = await createSageSessionConfig({ source: 'pi-agent-core' });
|
|
283
|
-
|
|
284
|
-
const { session } = await runtime.makeSession({
|
|
285
|
-
model: runtime.model,
|
|
286
|
-
tools: sage.wrapToolsWithSecurity(runtime.tools),
|
|
287
|
-
customTools: sage.customTools,
|
|
288
|
-
});
|
|
289
|
-
|
|
290
|
-
const disposeSageHooks = sage.setupHooks(session);
|
|
291
|
-
|
|
292
|
-
return {
|
|
293
|
-
session,
|
|
294
|
-
dispose: async () => {
|
|
295
|
-
disposeSageHooks();
|
|
296
|
-
await sage.mcpBridge.stop();
|
|
297
|
-
},
|
|
298
|
-
};
|
|
299
|
-
}
|
|
300
37
|
```
|
|
301
38
|
|
|
302
|
-
## API
|
|
39
|
+
## API
|
|
303
40
|
|
|
304
41
|
`createSageSessionConfig(config)` returns:
|
|
305
42
|
|
|
306
43
|
```typescript
|
|
307
44
|
{
|
|
308
|
-
customTools: ToolDefinition[];
|
|
309
|
-
mcpBridge: SageMcpBridge;
|
|
310
|
-
setupHooks: (session: AgentSession) => () => void;
|
|
311
|
-
wrapToolsWithSecurity: (tools: ToolDefinition[]) => ToolDefinition[];
|
|
45
|
+
customTools: ToolDefinition[]; // sage_search, sage_execute, sage_status
|
|
46
|
+
mcpBridge: SageMcpBridge; // MCP process lifecycle
|
|
47
|
+
setupHooks: (session: AgentSession) => () => void; // hooks + teardown
|
|
48
|
+
wrapToolsWithSecurity: (tools: ToolDefinition[]) => ToolDefinition[]; // security wrap
|
|
312
49
|
}
|
|
313
50
|
```
|
|
314
51
|
|
|
315
|
-
Config
|
|
52
|
+
Config:
|
|
316
53
|
|
|
317
54
|
```typescript
|
|
318
55
|
interface SageP2Config {
|
|
319
|
-
sageBin?: string;
|
|
320
|
-
sageProfile?: string;
|
|
321
|
-
suggestLimit?: number;
|
|
322
|
-
suggestDebounceMs?: number;
|
|
323
|
-
timeoutMs?: number;
|
|
324
|
-
enableProvision?: boolean;
|
|
56
|
+
sageBin?: string; // default: "sage"
|
|
57
|
+
sageProfile?: string; // Sage config profile
|
|
58
|
+
suggestLimit?: number; // default: 3
|
|
59
|
+
suggestDebounceMs?: number; // default: 800
|
|
60
|
+
timeoutMs?: number; // default: 20_000
|
|
325
61
|
enableRlmFeedback?: boolean;
|
|
326
62
|
enableSecurityHooks?: boolean;
|
|
327
|
-
source?: string;
|
|
63
|
+
source?: string; // default: "pi"
|
|
328
64
|
env?: Record<string, string>;
|
|
329
65
|
}
|
|
330
66
|
```
|
|
331
67
|
|
|
68
|
+
## Docs
|
|
69
|
+
|
|
70
|
+
- [Usage Guide](./USAGE.md) — env vars, integration modes, project config
|
|
71
|
+
- [Setup](./docs/setup.md) — install and verify
|
|
72
|
+
- [Developer Guide](./docs/developer.md) — build, test, CI contract
|
|
73
|
+
- [SKILL.md](./SKILL.md) — agent-driven integration skill
|
|
74
|
+
|
|
332
75
|
## Validate
|
|
333
76
|
|
|
334
77
|
```bash
|
package/SKILL.md
CHANGED
|
@@ -20,12 +20,16 @@ Stop and report immediately (do not keep searching random directories) if any of
|
|
|
20
20
|
|
|
21
21
|
When stopping, report what is missing and ask for the harness repo path.
|
|
22
22
|
|
|
23
|
+
> **Pi upstream:** [earendil-works/pi](https://github.com/earendil-works/pi) — `@earendil-works/pi-coding-agent`
|
|
24
|
+
> **Sage upstream:** [sage-protocol/sage](https://github.com/sage-protocol/sage)
|
|
25
|
+
|
|
23
26
|
## Goal
|
|
24
27
|
|
|
25
28
|
Apply the Sage integration contract exactly:
|
|
26
29
|
|
|
27
30
|
1. For pi CLI users: `pi install npm:@sage-protocol/pi-adapter` (no harness code edits)
|
|
28
|
-
2. For source-owned harness users: apply SDK patch (`createSageSessionConfig`, `customTools`, `wrapToolsWithSecurity`, `setupHooks`)
|
|
31
|
+
2. For source-owned harness users: apply SDK patch (`createSageSessionConfig`, `customTools`, `wrapToolsWithSecurity`, `setupHooks`)
|
|
32
|
+
3. Package name: `@earendil-works/pi-coding-agent` (formerly `@mariozechner/pi-coding-agent`)
|
|
29
33
|
|
|
30
34
|
## Integration Modes (Important)
|
|
31
35
|
|
|
@@ -41,6 +45,18 @@ pi list
|
|
|
41
45
|
|
|
42
46
|
Then restart `pi` and verify `sage_status` is callable.
|
|
43
47
|
|
|
48
|
+
Bridge health expectation:
|
|
49
|
+
|
|
50
|
+
- Pi exposes Sage through `sage_search`, `sage_execute`, and `sage_status`.
|
|
51
|
+
- `sage_status` is the user-facing health surface. When the MCP bridge is
|
|
52
|
+
degraded, surface a readable bridge error and recovery hint instead of silent
|
|
53
|
+
retry exhaustion.
|
|
54
|
+
- Inside bridge startup/health code, probe low-level MCP (`tools/list` or a
|
|
55
|
+
minimal Sage MCP call). Do not recursively call the adapter-level
|
|
56
|
+
`sage_status` tool from inside the bridge.
|
|
57
|
+
- Recovery wording should point at the Sage MCP bridge (`sage mcp start`,
|
|
58
|
+
restart Pi/Sage bridge) unless the failing path is specifically the daemon.
|
|
59
|
+
|
|
44
60
|
For project-local monorepo development, prefer an explicit `.pi/settings.json` that
|
|
45
61
|
keeps pi thin and points at the Sage Pi export surface:
|
|
46
62
|
|
|
@@ -64,7 +80,7 @@ keeps pi thin and points at the Sage Pi export surface:
|
|
|
64
80
|
"-../.agents/skills/frontend-design/SKILL.md",
|
|
65
81
|
"-~/.pi/agent/skills/prompt-builder/SKILL.md",
|
|
66
82
|
"-~/.pi/agent/skills/sage/SKILL.md",
|
|
67
|
-
"-~/.pi/agent/skills/sage-
|
|
83
|
+
"-~/.pi/agent/skills/sage-workflow/SKILL.md"
|
|
68
84
|
],
|
|
69
85
|
"enableSkillCommands": true
|
|
70
86
|
}
|
|
@@ -195,6 +211,8 @@ Do not change existing model/provider behavior. Run build/tests for touched pack
|
|
|
195
211
|
- Base tools are wrapped with `wrapToolsWithSecurity`
|
|
196
212
|
- `setupHooks(session)` is called once per session
|
|
197
213
|
- Teardown calls `disposeSageHooks()`
|
|
214
|
+
- `sage_status` reports bridge health; broken bridge paths return a structured,
|
|
215
|
+
user-readable error quickly
|
|
198
216
|
- Build/tests pass for touched repo
|
|
199
217
|
|
|
200
218
|
## Source of Truth
|
|
@@ -81,17 +81,33 @@ export declare class SageMcpBridge {
|
|
|
81
81
|
private stopped;
|
|
82
82
|
private startPromise;
|
|
83
83
|
private stderrBuffer;
|
|
84
|
+
private degraded;
|
|
85
|
+
private lastHealthError;
|
|
86
|
+
private lastHealthCheckedAt;
|
|
87
|
+
private cachedToolNames;
|
|
84
88
|
constructor(command: string, args: string[], env?: Record<string, string>, requestTimeoutMs?: number);
|
|
85
89
|
isReady(): boolean;
|
|
90
|
+
isDegraded(): boolean;
|
|
91
|
+
getHealthSnapshot(): {
|
|
92
|
+
bridgeConnected: boolean;
|
|
93
|
+
degraded: boolean;
|
|
94
|
+
lastHealthError: string | null;
|
|
95
|
+
lastHealthCheckedAt: number | null;
|
|
96
|
+
availableToolCount: number;
|
|
97
|
+
availableToolNames: string[];
|
|
98
|
+
};
|
|
86
99
|
start(): Promise<void>;
|
|
100
|
+
probeHealth(timeoutMs?: number): Promise<boolean>;
|
|
87
101
|
stop(): Promise<void>;
|
|
88
|
-
listTools(): Promise<Array<{
|
|
102
|
+
listTools(timeoutMs?: number): Promise<Array<{
|
|
89
103
|
name: string;
|
|
90
104
|
description?: string;
|
|
91
105
|
}>>;
|
|
92
106
|
callTool(name: string, args: Record<string, unknown>): Promise<unknown>;
|
|
93
107
|
callCodeModeSearch(args: Record<string, unknown>): Promise<unknown>;
|
|
94
108
|
callCodeModeExecute(args: Record<string, unknown>): Promise<unknown>;
|
|
109
|
+
private assertReadyForToolCall;
|
|
110
|
+
private markDegradedFromError;
|
|
95
111
|
private callWithFallback;
|
|
96
112
|
private initialize;
|
|
97
113
|
private spawn;
|
|
@@ -108,24 +124,21 @@ export declare class SageHookRuntime {
|
|
|
108
124
|
constructor(config: Required<Pick<SageP2Config, "sageBin" | "timeoutMs">> & SageP2Config);
|
|
109
125
|
getSessionContext(sessionId?: string): Promise<string>;
|
|
110
126
|
/**
|
|
111
|
-
* Gather
|
|
127
|
+
* Gather skill visibility summary for user-facing display.
|
|
112
128
|
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
* string
|
|
116
|
-
*
|
|
117
|
-
* The result is cached for `identityCacheTtlMs` (default 60 s) to avoid
|
|
118
|
-
* redundant CLI calls on every turn.
|
|
129
|
+
* Runs `sage library list` and `sage library active` in parallel to
|
|
130
|
+
* produce a summary of what libraries, skills, and prompts are loaded.
|
|
131
|
+
* Returns empty string when the CLI is unavailable.
|
|
119
132
|
*/
|
|
120
|
-
|
|
121
|
-
private identityCacheTtlMs;
|
|
122
|
-
getIdentityContext(): Promise<string>;
|
|
133
|
+
getSkillVisibilitySummary(): Promise<string>;
|
|
123
134
|
suggestSkill(prompt: string, sessionId?: string): Promise<string>;
|
|
124
135
|
capturePrompt(prompt: string, sessionId?: string): Promise<void>;
|
|
125
136
|
captureResponse(response: string, usage: {
|
|
126
137
|
input?: string;
|
|
127
138
|
output?: string;
|
|
128
139
|
}, sessionId?: string): Promise<void>;
|
|
140
|
+
recordSuggestionUse(skillKeys: string[], sessionId?: string): Promise<void>;
|
|
141
|
+
recordExecutionOutcome(skillKey: string, status: "passed" | "failed" | "revised", queryPreview?: string, sessionId?: string): Promise<void>;
|
|
129
142
|
scanPreTool(toolName: string, toolInput: Record<string, unknown>, sessionId?: string): Promise<SecurityDecision | null>;
|
|
130
143
|
scanPostTool(toolName: string, toolInput: Record<string, unknown>, toolResult: unknown, sessionId?: string): Promise<SecurityDecision | null>;
|
|
131
144
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sage-pi-adapter.d.ts","sourceRoot":"","sources":["../src/sage-pi-adapter.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"sage-pi-adapter.d.ts","sourceRoot":"","sources":["../src/sage-pi-adapter.ts"],"names":[],"mappings":"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"}
|