allye-pi 2.5.1 → 2.6.0
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/LICENSE +21 -0
- package/README.md +48 -2
- package/docs/install-omp.md +9 -1
- package/docs/install-pi.md +11 -3
- package/package.json +4 -3
- package/packages/allye-pi/src/index.ts +11 -71
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Allye Assistant
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -83,10 +83,56 @@ Then add the `allye` MCP server as described in [install-pi.md](docs/install-pi.
|
|
|
83
83
|
export ALLYE_PAT=pat_... # Allye → Settings → API
|
|
84
84
|
./install.sh list --scope team # approved skills you can see
|
|
85
85
|
./install.sh install claude team-standards # claude | codex | opencode | pi | omp
|
|
86
|
+
./install.sh install claude team-standards --reinstall # replace an edited copy (kept as a backup)
|
|
86
87
|
./install.sh status # offline integrity check
|
|
87
88
|
```
|
|
88
89
|
|
|
89
|
-
Each install downloads the skill's approved release, verifies every file and the canonical hash, opens a distribution for this machine, verifies the API-signed execution token, publishes the files into the harness's user skills directory with a provenance sidecar, and records the result on the API.
|
|
90
|
+
Each install downloads the skill's approved release, verifies every file and the canonical hash, opens a distribution for this machine, verifies the API-signed execution token, publishes the files into the harness's user skills directory with a provenance sidecar, and records the result on the API. The API decides which runtimes may receive skills; the installer reports its decision rather than working around it. Requires `bash`, `curl`, `jq` and Node.js 18+. The installer speaks compatibility contract `1.1.0`.
|
|
91
|
+
|
|
92
|
+
Until the allye-api PROD release that supports contract `1.1.0`, the installer works only against HML (`ALLYE_API_URL` pointing at the HML API). Against PROD it fails with `409 RUNTIME_INCOMPATIBLE` or an execution-context error about a missing signing key, and changes nothing.
|
|
93
|
+
|
|
94
|
+
### Who can install
|
|
95
|
+
|
|
96
|
+
Any member with view access to a skill can install it: any tenant member for an organization skill, members of the skill's team for a team skill, the author for a personal skill. Each person's installs are recorded separately. The installer needs no team for the install itself; use `--team <id>` (or `ALLYE_TEAM_ID`) only when a skill slug matches skills in several teams, so the slug can be resolved (or pass the skill id instead). If view access is lost while an install is in progress, the API answers `409`, the installer rolls the swap back and tells you to get access and rerun.
|
|
97
|
+
|
|
98
|
+
### Where skills go
|
|
99
|
+
|
|
100
|
+
| Runtime | Skills directory |
|
|
101
|
+
|---|---|
|
|
102
|
+
| `claude` | `~/.claude/skills` |
|
|
103
|
+
| `codex` | `$CODEX_HOME/skills` when `CODEX_HOME` is set, otherwise `~/.codex/skills` |
|
|
104
|
+
| `opencode` | `${XDG_CONFIG_HOME:-~/.config}/opencode/allye-skills` |
|
|
105
|
+
| `pi` | `$PI_CODING_AGENT_DIR/skills` when set, otherwise `~/.pi/agent/skills` |
|
|
106
|
+
| `omp` | `~/.omp/agent/skills` |
|
|
107
|
+
|
|
108
|
+
`CODEX_HOME` and `PI_CODING_AGENT_DIR` must be absolute paths; only the empty string means unset, a trailing `/` is stripped (`/` itself stays `/`), and a relative value stops that runtime's install before any request (other runtimes are unaffected). An empty or relative `XDG_CONFIG_HOME` is treated as unset. OpenCode does not discover this directory by itself: the `allye-opencode` plugin adds it to `skills.paths` when it is a real directory (not a symlink) owned by you and not group- or world-writable, so restart OpenCode after the first install creates it. The installer refuses to install into an `allye-skills` directory that is a symlink or group/world-writable (fix with `chmod go-w <dir>`); it does not check ownership, so the plugin additionally ignores a directory that is not owned by you. OMP presents itself to the API as runtime `pi`; Pi and OMP skills are installed as plain directories, with no package receipt.
|
|
109
|
+
|
|
110
|
+
Changing `CODEX_HOME` or `PI_CODING_AGENT_DIR` changes the install target, and the installer does not migrate skills left in the old directory (for example `~/.codex/skills`). Those copies stay where they are; a copy found under the new directory is handled as in the next section.
|
|
111
|
+
|
|
112
|
+
### Edited, deleted and moved copies
|
|
113
|
+
|
|
114
|
+
| State of `<skills dir>/<name>` | What the installer does |
|
|
115
|
+
|---|---|
|
|
116
|
+
| Missing (first install or deleted) | Installs it again; the API records a reinstall when it already had an install for this machine |
|
|
117
|
+
| Unchanged copy of the same release | Reports "already installed"; nothing is sent |
|
|
118
|
+
| Unchanged copy of an older release | Updates it |
|
|
119
|
+
| Edited by you | Refuses and changes nothing; rerun with `--reinstall` |
|
|
120
|
+
| Not installed by the installer, or installed from another skill | Never touched, with or without `--reinstall` |
|
|
121
|
+
| Contains a symlink or special file | Refuses and names the entry; with or without `--reinstall` |
|
|
122
|
+
|
|
123
|
+
`--reinstall` replaces an edited copy with the approved release and keeps your edited folder at `~/.allye/backups/<adapter-id>/<name>.allye.backup.<UTC ts>` (`.<pid>` is appended if that name exists), outside every skills directory so no harness loads it. Backup directories are created with mode 0700, and the installer refuses to keep backups in a `~/.allye`, `backups` or `backups/<id>` that is a symlink, owned by someone else or group/world-writable (it changes nothing; fix the directory and rerun). The installer prints the path; backups are never overwritten or deleted, and `./install.sh status` does not list them. If anything fails before the install is recorded, your edited folder is put back.
|
|
124
|
+
|
|
125
|
+
A copy records the machine and skills path it was installed for (as a digest; the hostname and path never leave the machine). After a hostname change, a different home or a changed `CODEX_HOME`, `PI_CODING_AGENT_DIR` or `XDG_CONFIG_HOME`, existing copies are "other-target": an unchanged one is reinstalled automatically here with no backup, while an edited one needs `--reinstall`.
|
|
126
|
+
|
|
127
|
+
If an earlier run could not finish moving your edited folder (a failed restore, a failed backup move, or a killed run), it leaves `<skills dir>/.allye-backup.<name>.<UTC ts>.<pid>`. The installer then refuses to install `<name>`, prints each such path and sends nothing. Move the folder into `~/.allye/backups/<adapter-id>/` to keep it, or delete it, then rerun.
|
|
128
|
+
|
|
129
|
+
### Errors
|
|
130
|
+
|
|
131
|
+
- `409 DISTRIBUTION_NOT_AUTHORIZED`: you need view access to the skill (team membership or authorship); get access and rerun.
|
|
132
|
+
- `410 MARKETPLACE_RETIRED`: the skill is a retired, read-only marketplace skill; nothing was installed. Use an organization or team skill.
|
|
133
|
+
- `422 TEAM_SELECTION_REQUIRED`: the slug matches skills in several teams; rerun with `--team <team>` or use the skill id.
|
|
134
|
+
- `409 RUNTIME_INCOMPATIBLE`: the API has no `1.1.0` profile, which is the case on PROD before the allye-api release. Use HML or wait for that release; there is nothing to reset and no admin to ask.
|
|
135
|
+
- `400` mentioning a request field such as `idempotencyKey` or `target`: the API and the installer disagree on the request shape. Upgrade the installer; there is nothing to reset and no admin to ask.
|
|
90
136
|
|
|
91
137
|
## Repository layout
|
|
92
138
|
|
|
@@ -125,4 +171,4 @@ Releases are automated by semantic-release on every push to `main` (Conventional
|
|
|
125
171
|
|
|
126
172
|
## License
|
|
127
173
|
|
|
128
|
-
MIT
|
|
174
|
+
MIT, see [LICENSE](LICENSE).
|
package/docs/install-omp.md
CHANGED
|
@@ -22,10 +22,18 @@ OMP has a native MCP client (no `pi-mcp-adapter`). Add the server once, at user
|
|
|
22
22
|
|
|
23
23
|
OMP also loads servers from a project `.mcp.json`. Do not add tokens or OAuth client metadata: OMP discovers the OAuth endpoints and opens the browser on first use.
|
|
24
24
|
|
|
25
|
-
Because OMP's MCP client is not the in-process `pi-mcp-adapter` bridge, the extension does not
|
|
25
|
+
Because OMP's MCP client is not the in-process `pi-mcp-adapter` bridge (as in OMP today), the extension does not resolve the project. It injects only the git remote and any unverified `.allye/project.json` claim; the bootstrap tells the agent to call `projects.project_resolve` itself. The team follows the project, so no team selection is needed.
|
|
26
26
|
|
|
27
27
|
## Confirm
|
|
28
28
|
|
|
29
29
|
Tell the user:
|
|
30
30
|
|
|
31
31
|
> Allye is installed for OMP: the `allye-pi` extension (bootstrap and Bridge) and the `allye` MCP server. Start a new OMP session and run `/bridge survey` (or another mode).
|
|
32
|
+
|
|
33
|
+
## Organization skills
|
|
34
|
+
|
|
35
|
+
`./install.sh install omp <skill>` (see the [README](../README.md#your-organizations-skills)) installs into `~/.omp/agent/skills`. OMP presents itself to the API as runtime `pi`, and the skill is installed as a plain directory, with no package receipt.
|
|
36
|
+
|
|
37
|
+
- Edited copies: `./install.sh install omp <skill> --reinstall` replaces your edited copy and keeps it at `~/.allye/backups/omp/<skill>.allye.backup.<UTC ts>`. A copy of the same release on the same target is already installed (a no-op); older-release copies are updated, and copies recorded for another target (after a hostname or skills-path change) are reinstalled when unchanged, while an edited one needs `--reinstall`. Foreign or unmanaged folders are never touched.
|
|
38
|
+
- Leftovers: if the installer reports a `.allye-backup.<skill>.*` entry in the skills directory, an earlier run kept your edited folder there. Move it into `~/.allye/backups/omp/` or delete it, then rerun.
|
|
39
|
+
- Any member with view access to a skill can install it. If the installer is too old for the API, upgrade the installer; there is nothing to ask an admin to reset. Until the allye-api PROD release the installer works only against HML. See the [README](../README.md#your-organizations-skills).
|
package/docs/install-pi.md
CHANGED
|
@@ -4,7 +4,7 @@ Allye for Pi is the native package `allye-pi`. It:
|
|
|
4
4
|
|
|
5
5
|
- exposes the Bridge skill (`/bridge <mode>`) from the package's `skills/` directory;
|
|
6
6
|
- adds the Allye bootstrap (`bootstrap/allye.md`) to the system prompt;
|
|
7
|
-
-
|
|
7
|
+
- identifies the repository's project (it loads no startup or per-prompt memory context): when an in-process MCP bridge is available it resolves the git remote with `projects.project_resolve` and verifies any `.allye/project.json` claim against it, injecting "this repo = project X / app Y (team Z)", the ambiguous candidates, or the disagreement to ask the user about.
|
|
8
8
|
|
|
9
9
|
It never edits Pi's MCP configuration or reads credentials.
|
|
10
10
|
|
|
@@ -32,11 +32,11 @@ Do not pass headers, bearer tokens or OAuth client ids: Pi discovers the OAuth e
|
|
|
32
32
|
|
|
33
33
|
On older Pi versions without `pi mcp`, install `pi-mcp-adapter` (`pi install npm:pi-mcp-adapter`), define one server named `allye` (`{"type": "http", "url": "https://mcp.allye.app/mcp"}` under `mcpServers`) in the effective source shown by `/mcp` — for example `~/.pi/agent/mcp.json` or `~/.config/mcp/mcp.json` — then run `/mcp-auth allye` and `/mcp reconnect allye`.
|
|
34
34
|
|
|
35
|
-
The extension
|
|
35
|
+
The extension resolves the repository's project only when `pi-mcp-adapter` exposes its in-process bridge. Otherwise it injects only the git remote and any unverified link claim, and the bootstrap tells the agent to call `projects.project_resolve` itself.
|
|
36
36
|
|
|
37
37
|
## Teams
|
|
38
38
|
|
|
39
|
-
The team follows the project: the extension never blocks work on team selection. A default team is needed only to create projects; `/allye-team <name|prefix|id>` sets it through the `team` tool (`team_set_default`). Set `ALLYE_PI_NATIVE_BOOTSTRAP=0` to skip the
|
|
39
|
+
The team follows the project: the extension never blocks work on team selection. A default team is needed only to create projects; `/allye-team <name|prefix|id>` sets it through the `team` tool (`team_set_default`). Set `ALLYE_PI_NATIVE_BOOTSTRAP=0` to skip the repository block (the bootstrap text and the Bridge skill stay available), or `ALLYE_PI_MCP=0` to disable MCP calls from the extension.
|
|
40
40
|
|
|
41
41
|
## Local development
|
|
42
42
|
|
|
@@ -48,3 +48,11 @@ npm run typecheck
|
|
|
48
48
|
npm run test:pi
|
|
49
49
|
pi -e ./packages/allye-pi/src/index.ts -p "Which Allye tools and Bridge modes are available?"
|
|
50
50
|
```
|
|
51
|
+
|
|
52
|
+
## Organization skills
|
|
53
|
+
|
|
54
|
+
`./install.sh install pi <skill>` (see the [README](../README.md#your-organizations-skills)) installs into `$PI_CODING_AGENT_DIR/skills` when `PI_CODING_AGENT_DIR` is set, otherwise `~/.pi/agent/skills`. The value must be an absolute path; only the empty string means unset, a trailing `/` is stripped, and a relative value stops the Pi install before any request. Changing it changes the install target; copies left in the old directory are not migrated. The API sees runtime `pi` and the skill is installed as a plain directory, with no package receipt.
|
|
55
|
+
|
|
56
|
+
- Edited copies: `./install.sh install pi <skill> --reinstall` replaces your edited copy and keeps it at `~/.allye/backups/pi/<skill>.allye.backup.<UTC ts>`. A copy of the same release on the same target is already installed (a no-op); older-release copies are updated, and copies recorded for another target (after a hostname or skills-path change) are reinstalled when unchanged, while an edited one needs `--reinstall`. Foreign or unmanaged folders are never touched.
|
|
57
|
+
- Leftovers: if the installer reports a `.allye-backup.<skill>.*` entry in the skills directory, an earlier run kept your edited folder there. Move it into `~/.allye/backups/pi/` or delete it, then rerun.
|
|
58
|
+
- Any member with view access to a skill can install it. If the installer is too old for the API, upgrade the installer; there is nothing to ask an admin to reset. Until the allye-api PROD release the installer works only against HML. See the [README](../README.md#your-organizations-skills).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "allye-pi",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.0",
|
|
4
4
|
"description": "Allye extension for Pi and OMP: the Allye bootstrap, the Bridge skill and the repository-to-project link",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -43,11 +43,12 @@
|
|
|
43
43
|
"scripts": {
|
|
44
44
|
"typecheck": "tsc --noEmit -p packages/allye-pi/tsconfig.json",
|
|
45
45
|
"test:pi": "node --experimental-strip-types --test packages/allye-pi/src/index.test.ts",
|
|
46
|
+
"test:opencode": "node --experimental-strip-types --test packages/allye-opencode/src/skills-paths.test.ts",
|
|
46
47
|
"test:installer": "bash install/test-validation.sh && bash install/test-installer.sh",
|
|
47
48
|
"test:bootstrap": "bash test/test-bootstrap.sh && bash hooks/test-session-start.sh",
|
|
48
49
|
"test:agents": "node test/test-agents.mjs",
|
|
49
|
-
"test:skills": "node test/test-skills-text.mjs && node test/test-ci-proof.mjs",
|
|
50
|
-
"test": "npm run test:bootstrap && npm run test:agents && npm run test:skills && npm run test:installer && npm run test:pi"
|
|
50
|
+
"test:skills": "node test/test-skills-text.mjs && node test/test-ci-proof.mjs && node test/test-ci-workflows.mjs",
|
|
51
|
+
"test": "npm run test:bootstrap && npm run test:agents && npm run test:skills && npm run test:installer && npm run test:pi && npm run test:opencode"
|
|
51
52
|
},
|
|
52
53
|
"repository": {
|
|
53
54
|
"type": "git",
|
|
@@ -9,14 +9,14 @@ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
|
|
|
9
9
|
*
|
|
10
10
|
* - Exposes the repository's skills/ directory (Bridge) through resources_discover.
|
|
11
11
|
* - Adds the shared bootstrap (bootstrap/allye.md) to the system prompt.
|
|
12
|
-
* -
|
|
13
|
-
*
|
|
14
|
-
*
|
|
12
|
+
* - Identifies the repo's project with `projects.project_resolve` (through the
|
|
13
|
+
* configured MCP bridge when one is available), verifying any
|
|
14
|
+
* `.allye/project.json` claim against the git remote. It loads no startup or
|
|
15
|
+
* per-prompt memory context.
|
|
15
16
|
* The team follows the project: nothing is gated on team selection.
|
|
16
17
|
*/
|
|
17
18
|
|
|
18
19
|
const MCP_SERVER = "allye";
|
|
19
|
-
const MAX_CONTEXT_CHARS = 12_000;
|
|
20
20
|
const LINK_FILE = ".allye/project.json";
|
|
21
21
|
const PROJECT_KEY = /^[A-Z][A-Z0-9]{1,9}$/;
|
|
22
22
|
const APP_NAME = /^[A-Za-z0-9._-]{1,120}$/;
|
|
@@ -25,11 +25,6 @@ const MAX_CANDIDATES = 10;
|
|
|
25
25
|
const MAX_REPO_CHARS = 4_000;
|
|
26
26
|
|
|
27
27
|
type McpResult = { content?: Array<{ type?: string; text?: string }> };
|
|
28
|
-
export type StartupContext = {
|
|
29
|
-
text: string;
|
|
30
|
-
repo: string;
|
|
31
|
-
allyeUnavailable: boolean;
|
|
32
|
-
};
|
|
33
28
|
type ActiveMcpToolCaller = (
|
|
34
29
|
serverName: string,
|
|
35
30
|
toolName: string,
|
|
@@ -83,7 +78,7 @@ async function callAllye(toolName: string, args: Record<string, unknown>): Promi
|
|
|
83
78
|
// pi-mcp-adapter may expose an in-process bridge for cooperating extensions.
|
|
84
79
|
// Without it, the agent still reaches Allye through its own MCP tools.
|
|
85
80
|
const bridge = (globalThis as McpBridgeRuntime).__piMcpAdapterActiveToolCaller;
|
|
86
|
-
if (!bridge) throw new Error("no in-process MCP bridge is available
|
|
81
|
+
if (!bridge) throw new Error("no in-process MCP bridge is available");
|
|
87
82
|
return resultText(await bridge(MCP_SERVER, toolName, args));
|
|
88
83
|
}
|
|
89
84
|
|
|
@@ -300,82 +295,27 @@ async function buildRepoContext(cwd: string, online: boolean): Promise<string> {
|
|
|
300
295
|
}
|
|
301
296
|
}
|
|
302
297
|
|
|
303
|
-
export function
|
|
304
|
-
return {
|
|
305
|
-
text: `## Allye context not preloaded\n${reason}\nUse the Allye MCP tools directly when the task needs them: call \`initialize\` first.`,
|
|
306
|
-
repo,
|
|
307
|
-
allyeUnavailable: true,
|
|
308
|
-
};
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
async function loadStartupContext(cwd: string): Promise<StartupContext> {
|
|
312
|
-
if (!mcpBridgeAvailable()) {
|
|
313
|
-
return unavailableStartupContext("No in-process MCP bridge is available in this session.", await loadRepoContext(cwd, false));
|
|
314
|
-
}
|
|
315
|
-
try {
|
|
316
|
-
const initialization = await callAllye("initialize", { action: "init", include_user_docs: true });
|
|
317
|
-
const preferences = await callAllye("intelligence", { action: "memory_preferences" });
|
|
318
|
-
return {
|
|
319
|
-
text: [initialization, preferences].filter(Boolean).map((section) => limitText(section, MAX_CONTEXT_CHARS)).join("\n\n"),
|
|
320
|
-
repo: await loadRepoContext(cwd, true),
|
|
321
|
-
allyeUnavailable: false,
|
|
322
|
-
};
|
|
323
|
-
} catch (error) {
|
|
324
|
-
return unavailableStartupContext(
|
|
325
|
-
`Allye context could not be preloaded: ${error instanceof Error ? error.message : String(error)}`,
|
|
326
|
-
await loadRepoContext(cwd, false),
|
|
327
|
-
);
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
async function loadPromptContext(prompt: string): Promise<string> {
|
|
332
|
-
try {
|
|
333
|
-
return limitText(await callAllye("intelligence", {
|
|
334
|
-
action: "memory_search",
|
|
335
|
-
query: prompt,
|
|
336
|
-
limit: 5,
|
|
337
|
-
return_content: true,
|
|
338
|
-
}), MAX_CONTEXT_CHARS);
|
|
339
|
-
} catch {
|
|
340
|
-
return "";
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
export function buildSystemSections(bootstrap: string, startup: StartupContext, firstPrompt: boolean, nativeBootstrap = true): string[] {
|
|
298
|
+
export function buildSystemSections(bootstrap: string, repo: string, nativeBootstrap = true): string[] {
|
|
345
299
|
const sections: string[] = [];
|
|
346
300
|
if (bootstrap) sections.push(`<allye-bootstrap>\n${bootstrap.trim()}\n</allye-bootstrap>`);
|
|
347
|
-
if (
|
|
348
|
-
if (nativeBootstrap && startup.repo) sections.push(`<allye-repo>\n${startup.repo}\n</allye-repo>`);
|
|
301
|
+
if (nativeBootstrap && repo) sections.push(`<allye-repo>\n${repo}\n</allye-repo>`);
|
|
349
302
|
return sections;
|
|
350
303
|
}
|
|
351
304
|
|
|
352
305
|
export default function allyePiExtension(pi: ExtensionAPI): void {
|
|
353
306
|
const nativeBootstrap = process.env.ALLYE_PI_NATIVE_BOOTSTRAP !== "0";
|
|
354
|
-
let startupContext = unavailableStartupContext("Allye context has not been loaded yet.");
|
|
355
307
|
let bootstrap = "";
|
|
356
|
-
let
|
|
308
|
+
let repo = "";
|
|
357
309
|
|
|
358
310
|
pi.on("resources_discover", () => ({ skillPaths: [skillsPath()] }));
|
|
359
311
|
|
|
360
312
|
pi.on("session_start", async (_event, ctx) => {
|
|
361
|
-
firstPrompt = true;
|
|
362
313
|
bootstrap = loadBootstrap();
|
|
363
|
-
if (nativeBootstrap)
|
|
364
|
-
if (ctx.hasUI) ctx.ui.setStatus("allye", "loading Allye context…");
|
|
365
|
-
startupContext = await loadStartupContext(ctx.cwd ?? process.cwd());
|
|
366
|
-
if (ctx.hasUI) ctx.ui.setStatus("allye", startupContext.allyeUnavailable ? "Allye: context not preloaded" : "Allye ready");
|
|
367
|
-
}
|
|
314
|
+
if (nativeBootstrap) repo = await loadRepoContext(ctx.cwd ?? process.cwd(), mcpBridgeAvailable());
|
|
368
315
|
});
|
|
369
316
|
|
|
370
|
-
pi.on("before_agent_start",
|
|
371
|
-
const sections = buildSystemSections(bootstrap,
|
|
372
|
-
if (firstPrompt) {
|
|
373
|
-
firstPrompt = false;
|
|
374
|
-
if (nativeBootstrap && !startupContext.allyeUnavailable) {
|
|
375
|
-
const relevant = await loadPromptContext(event.prompt);
|
|
376
|
-
if (relevant) sections.push(`<allye-relevant-memory>\n${relevant}\n</allye-relevant-memory>`);
|
|
377
|
-
}
|
|
378
|
-
}
|
|
317
|
+
pi.on("before_agent_start", (event) => {
|
|
318
|
+
const sections = buildSystemSections(bootstrap, repo, nativeBootstrap);
|
|
379
319
|
return sections.length ? { systemPrompt: `${event.systemPrompt}\n\n${sections.join("\n\n")}` } : undefined;
|
|
380
320
|
});
|
|
381
321
|
|