pi-beyin 0.1.7 → 0.1.9
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 +35 -13
- package/THIRD-PARTY-NOTICES.md +33 -0
- package/extensions/context.ts +17 -7
- package/extensions/damitma.ts +17 -3
- package/extensions/jev.ts +3 -1
- package/package.json +3 -2
- package/skills/brain/SKILL.md +3 -3
- package/skills/brain-doctor/SKILL.md +1 -1
- package/skills/brain-update/SKILL.md +1 -1
- package/tools/pi-harness-patch.py +3 -3
package/README.md
CHANGED
|
@@ -26,6 +26,26 @@ text found in notes, imported transcripts or tool output.
|
|
|
26
26
|
|
|
27
27
|
The extensions without a vault are no-ops; `context` and `damitma` have nothing to read.
|
|
28
28
|
|
|
29
|
+
## Who this is for
|
|
30
|
+
|
|
31
|
+
- You already use a **beyin vault** — a directory with `beyin.py` that brings its own installer and updater.
|
|
32
|
+
- You run **pi** and want that vault wired into pi.
|
|
33
|
+
- You have **CommandCode** access if you want Jev and the advisor tools. Without it, context injection,
|
|
34
|
+
the receipt reminder and the distillation offer still work; only scoring and the `beyin_jev_*` tools
|
|
35
|
+
stay inert.
|
|
36
|
+
|
|
37
|
+
With CommandCode, install the official provider so Jev can reuse its key instead of a separate secret:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
pi install npm:@commandcode/pi-commandcode-provider
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Otherwise put `CMD_API_KEY=...` in `~/.config/beyin/jev-commandcode.env` (or export it).
|
|
44
|
+
|
|
45
|
+
The harness patch only knows the code shapes it was written against. On an unfamiliar vault it prints
|
|
46
|
+
warnings, leaves the files untouched (fail-soft) and `receipt --harness pi` stays unavailable until the
|
|
47
|
+
patterns match — nothing breaks, the work is just labelled with another harness.
|
|
48
|
+
|
|
29
49
|
## Install
|
|
30
50
|
|
|
31
51
|
```bash
|
|
@@ -50,7 +70,9 @@ the context twice.
|
|
|
50
70
|
|
|
51
71
|
Environment: `BEYIN_VAULT`, `BEYIN_PYTHON`, `BEYIN_HOOK_CONFIG`, `BEYIN_DAMITMA_CONFIG`,
|
|
52
72
|
`BEYIN_JEV_CONFIG`, `BEYIN_CONTEXT_CHARS`, `BEYIN_REMINDERS=0`, `BEYIN_INCLUDE_VAULT=1`,
|
|
53
|
-
`BEYIN_DAMITMA=0`, `BEYIN_JEV=0`, `BEYIN_DISABLE=1`, `BEYIN_DEBUG=1`, `BEYIN_PI_PATCH`,
|
|
73
|
+
`BEYIN_DAMITMA=0`, `BEYIN_JEV=0`, `BEYIN_DISABLE=1`, `BEYIN_DEBUG=1`, `BEYIN_PI_PATCH`, `BEYIN_LANG` (`tr`
|
|
74
|
+
by default; `en` switches the injected notices and command descriptions to English — the
|
|
75
|
+
`beyin_jev_*` tool schema text is still Turkish),
|
|
54
76
|
`BEYIN_JEV_MODEL`, `BEYIN_JEV_API_KEY` / `CMD_API_KEY` / `COMMAND_CODE_API_KEY`,
|
|
55
77
|
`BEYIN_FORCE_REMINDER=1`.
|
|
56
78
|
|
|
@@ -77,20 +99,20 @@ The extensions call `beyin.py` (read-only unless the agent runs a write command)
|
|
|
77
99
|
A vault whose `beyin.py` does not accept `--harness pi` needs `tools/pi-harness-patch.py ensure
|
|
78
100
|
--vault <vault>` (the extension does this on session start).
|
|
79
101
|
|
|
80
|
-
##
|
|
102
|
+
## Scope
|
|
81
103
|
|
|
82
|
-
|
|
83
|
-
|
|
104
|
+
This package is the **pi side**: extensions, skills and the harness patch. The vault and its `beyin.py`
|
|
105
|
+
CLI are yours to install and update separately; this package never needs to know their version.
|
|
84
106
|
|
|
85
|
-
- `tools/pi-harness-patch.py` is the only
|
|
86
|
-
list in
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
- The skills here are **copies for pi**, not links into the vault.
|
|
90
|
-
under `.claude/skills
|
|
91
|
-
- Notifications
|
|
92
|
-
suggestion and the `beyin_jev_*` tool descriptions ship
|
|
93
|
-
|
|
107
|
+
- `tools/pi-harness-patch.py` is the only piece that touches the vault's Python: it adds `pi` to the
|
|
108
|
+
harness list in five managed modules and re-syncs the install manifest so updates plan cleanly.
|
|
109
|
+
An update of the vault reverts those edits; the extension calls `ensure` on session start, so they
|
|
110
|
+
come back by themselves. `status` is read-only.
|
|
111
|
+
- The skills here are **copies for pi**, not links into the vault. Other harnesses keep their own copies
|
|
112
|
+
under `.claude/skills/`; pi does not read that directory.
|
|
113
|
+
- Notifications live in the adapter: the injected context, the receipt reminder, the distillation
|
|
114
|
+
suggestion and the `beyin_jev_*` tool descriptions ship here. They are written in Turkish today (the
|
|
115
|
+
author's language); anything a *skill* writes follows the user's language.
|
|
94
116
|
|
|
95
117
|
## Project memory skills
|
|
96
118
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Third-party notices
|
|
2
|
+
|
|
3
|
+
## beyin
|
|
4
|
+
|
|
5
|
+
`tools/pi-harness-patch.py` contains short source excerpts from the beyin vault code that it patches
|
|
6
|
+
(the harness tuples, the Jev request headers and the assessment entry point). Those excerpts remain
|
|
7
|
+
under beyin's license:
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
MIT License
|
|
11
|
+
|
|
12
|
+
Copyright (c) 2026 Forn
|
|
13
|
+
|
|
14
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
15
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
16
|
+
in the Software without restriction, including without limitation the rights
|
|
17
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
18
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
19
|
+
furnished to do so, subject to the following conditions:
|
|
20
|
+
|
|
21
|
+
The above copyright notice and this permission notice shall be included in all
|
|
22
|
+
copies or substantial portions of the Software.
|
|
23
|
+
|
|
24
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
25
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
26
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
27
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
28
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
29
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
30
|
+
SOFTWARE.
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Everything else in this repository is MIT, see [LICENSE](LICENSE).
|
package/extensions/context.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* pi-native bridge for the beyin vault (the pi equivalent of the beyin hook).
|
|
3
3
|
*
|
|
4
4
|
* Beyin's OMP/OpenCode/Claude/Codex hooks do not run in pi. This extension pulls
|
|
5
5
|
* relevant notes from the local second brain on every user prompt and injects them
|
|
@@ -43,6 +43,8 @@ const REMINDERS = process.env.BEYIN_REMINDERS !== "0";
|
|
|
43
43
|
const INCLUDE_VAULT = process.env.BEYIN_INCLUDE_VAULT === "1";
|
|
44
44
|
const DISABLED = process.env.BEYIN_DISABLE === "1";
|
|
45
45
|
const DEBUG = process.env.BEYIN_DEBUG === "1";
|
|
46
|
+
/** Model-facing fixed texts: "tr" (default) or "en" via BEYIN_LANG. */
|
|
47
|
+
const LANG = /^en/i.test(process.env.BEYIN_LANG || "") ? "en" : "tr";
|
|
46
48
|
|
|
47
49
|
const SYNTHETIC_PREFIXES = [
|
|
48
50
|
"<task-notification>",
|
|
@@ -647,13 +649,21 @@ export default function beyinContext(pi: ExtensionAPI) {
|
|
|
647
649
|
// Receipt reminder from the previous turn (full mode only); then reset the flags for the new turn.
|
|
648
650
|
let reminder: string | undefined;
|
|
649
651
|
if (REMINDERS && mode === "full" && prevEdited && !prevRecorded) {
|
|
652
|
+
const receiptCmd = `python3 ${path.join(VAULT, "beyin.py")} receipt --harness pi --event-id EVENT_ID --summary "..." --ref <vault-relative-path>`;
|
|
650
653
|
reminder =
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
654
|
+
LANG === "en"
|
|
655
|
+
? "## Second brain — record required\n" +
|
|
656
|
+
"The previous turn edited files without recording anything in the second brain. " +
|
|
657
|
+
"Record BEFORE answering this message: for a vault file run " +
|
|
658
|
+
`\`${receiptCmd}\`; ` +
|
|
659
|
+
"for work outside the vault write a short result/task note with `note-create`/`task-create`. " +
|
|
660
|
+
"If there is a durable lesson, distill it under `knowledge/`. Then answer normally."
|
|
661
|
+
: "## İkinci beyin — kayıt gerekli\n" +
|
|
662
|
+
"Önceki turda dosya düzenlendi ve ikinci beyne kayıt düşülmedi. " +
|
|
663
|
+
"Bu mesajı yanıtlamadan ÖNCE kaydet: vault dosyasıysa " +
|
|
664
|
+
`\`${receiptCmd}\`; ` +
|
|
665
|
+
"vault dışı bir işse `note-create`/`task-create` ile vault'a kısa bir sonuç/görev notu yaz. " +
|
|
666
|
+
"Kalıcı bir öğrenim varsa `knowledge/` altına damıt. Sonra normal yanıtı ver.";
|
|
657
667
|
}
|
|
658
668
|
prevEdited = false;
|
|
659
669
|
prevRecorded = false;
|
package/extensions/damitma.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Beyin distillation — a knowledge-distillation SUGGESTION at turn/session end.
|
|
3
3
|
*
|
|
4
4
|
* Why: in beyin's bare form the concept/distillation work is done by the active
|
|
5
|
-
* agent, not a background model
|
|
5
|
+
* agent, not a background model. But the
|
|
6
6
|
* "was the lesson distilled" step could be skipped silently. If a turn wrote a record
|
|
7
7
|
* to the second brain without distilling under `knowledge/`, this extension injects a
|
|
8
8
|
* short "offer distillation candidates" instruction at the end of the turn.
|
|
@@ -43,6 +43,8 @@ const HOOK_CONFIG_FILE = process.env.BEYIN_HOOK_CONFIG || path.join(HOME, ".conf
|
|
|
43
43
|
const DEFAULT_EXCLUDES: string[] = [];
|
|
44
44
|
const DISABLED = process.env.BEYIN_DAMITMA === "0" || process.env.BEYIN_DISABLE === "1";
|
|
45
45
|
const DEBUG = process.env.BEYIN_DEBUG === "1";
|
|
46
|
+
/** Model-facing fixed texts: "tr" (default) or "en" via BEYIN_LANG. */
|
|
47
|
+
const LANG = /^en/i.test(process.env.BEYIN_LANG || "") ? "en" : "tr";
|
|
46
48
|
|
|
47
49
|
const RECEIPT_RE = /(?:^|\s)beyin\.py\s+(?:receipt|note-create|task-create|task-update)\b/;
|
|
48
50
|
const KNOWLEDGE_RE = /(^|[\\/])knowledge[\\/]/;
|
|
@@ -127,6 +129,18 @@ function insideVault(p: string): boolean {
|
|
|
127
129
|
}
|
|
128
130
|
|
|
129
131
|
function instruction(maxCandidates: number): string {
|
|
132
|
+
if (LANG === "en") {
|
|
133
|
+
return [
|
|
134
|
+
"## Second brain — distillation offer",
|
|
135
|
+
"This turn wrote to the second brain but nothing was distilled under `knowledge/`.",
|
|
136
|
+
"Now give the user a SHORT distillation offer (a short visible list):",
|
|
137
|
+
`- At most ${maxCandidates} candidates. One line each: **title** — one sentence — source (file/receipt path).`,
|
|
138
|
+
"- Offer only reusable lessons/decisions/concepts/methods; never invent candidates to fill a quota, never offer transient detail.",
|
|
139
|
+
'- If there is no durable lesson, skip the offer and say "nothing durable to distill" in one sentence.',
|
|
140
|
+
"- Write nothing under `knowledge/` before the user approves. After approval, write it with `beyin.py note-create` and add it to the receipt refs.",
|
|
141
|
+
"- If improving an existing knowledge note is enough, say so; do not open a new file.",
|
|
142
|
+
].join("\n");
|
|
143
|
+
}
|
|
130
144
|
return [
|
|
131
145
|
"## İkinci beyin — damıtma önerisi",
|
|
132
146
|
"Bu turda ikinci beyne kayıt düşüldü ama kalıcı bilgi `knowledge/` altına damıtılmadı.",
|
|
@@ -226,13 +240,13 @@ export default function beyinDamitma(pi: ExtensionAPI) {
|
|
|
226
240
|
|
|
227
241
|
// Manual trigger: /damitma — asks for the same suggestion right now.
|
|
228
242
|
pi.registerCommand("damitma", {
|
|
229
|
-
description: "İkinci beyin damıtma önerisini şimdi iste",
|
|
243
|
+
description: LANG === "en" ? "Ask for the second-brain distillation offer now" : "İkinci beyin damıtma önerisini şimdi iste",
|
|
230
244
|
handler: async (_args, ctx: ExtensionContext) => {
|
|
231
245
|
pi.sendMessage(
|
|
232
246
|
{ customType: "beyin-damitma", display: false, content: instruction(config.maxCandidates) },
|
|
233
247
|
{ triggerTurn: true },
|
|
234
248
|
);
|
|
235
|
-
ctx.ui.notify("Damıtma önerisi istendi", "info");
|
|
249
|
+
ctx.ui.notify(LANG === "en" ? "Distillation offer requested" : "Damıtma önerisi istendi", "info");
|
|
236
250
|
},
|
|
237
251
|
});
|
|
238
252
|
}
|
package/extensions/jev.ts
CHANGED
|
@@ -40,6 +40,8 @@ const DEFAULT_MODEL = "typesafe/jev";
|
|
|
40
40
|
const KEY_FILE = path.join(HOME, ".config", "beyin", "jev-commandcode.env");
|
|
41
41
|
const CONFIG_FILE = path.join(HOME, ".config", "beyin", "jev.json");
|
|
42
42
|
const DEBUG = process.env.BEYIN_DEBUG === "1";
|
|
43
|
+
/** User-facing fixed texts: "tr" (default) or "en" via BEYIN_LANG. */
|
|
44
|
+
const LANG = /^en/i.test(process.env.BEYIN_LANG || "") ? "en" : "tr";
|
|
43
45
|
|
|
44
46
|
// Latest session context, needed to use pi's auth API (without touching auth.json directly).
|
|
45
47
|
let latestContext: ExtensionContext | undefined;
|
|
@@ -279,7 +281,7 @@ export default function beyinJev(pi: ExtensionAPI) {
|
|
|
279
281
|
});
|
|
280
282
|
|
|
281
283
|
pi.registerCommand("jev-test", {
|
|
282
|
-
description: "CommandCode destekli Jev (typesafe/jev) classifier'ını dene",
|
|
284
|
+
description: LANG === "en" ? "Try the CommandCode-backed Jev (typesafe/jev) classifier" : "CommandCode destekli Jev (typesafe/jev) classifier'ını dene",
|
|
283
285
|
handler: async (args, ctx: ExtensionContext) => {
|
|
284
286
|
const model = ctx.modelRegistry.findOfType("classifier", PROVIDER, MODEL_ID);
|
|
285
287
|
if (!model) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-beyin",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"description": "pi-native bridge for the beyin second brain: context injection, distillation reminders, and Jev advisor tools.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|
|
@@ -34,7 +34,8 @@
|
|
|
34
34
|
"skills",
|
|
35
35
|
"tools",
|
|
36
36
|
"README.md",
|
|
37
|
-
"LICENSE"
|
|
37
|
+
"LICENSE",
|
|
38
|
+
"THIRD-PARTY-NOTICES.md"
|
|
38
39
|
],
|
|
39
40
|
"scripts": {
|
|
40
41
|
"test": "bash test/run.sh",
|
package/skills/brain/SKILL.md
CHANGED
|
@@ -70,7 +70,7 @@ your behalf.
|
|
|
70
70
|
|
|
71
71
|
## Turning results into permanent knowledge
|
|
72
72
|
|
|
73
|
-
The active agent
|
|
73
|
+
The active agent produces the concept and link notes. If a result contains reusable knowledge, first read
|
|
74
74
|
`knowledge/index.md` and only the relevant concept. Improve the existing note with its sources, or create
|
|
75
75
|
`knowledge/concepts/<topic>.md`: short description, key points, reasoning/limits and sources. If the source is
|
|
76
76
|
the user's own statement, say so explicitly. If two topics have a real relationship, create a reasoned connection
|
|
@@ -236,14 +236,14 @@ the applications are closed. In sparse-check or manual mode, refresh the source
|
|
|
236
236
|
information is needed; don't assume an old session context is current. Work started earlier may have finished;
|
|
237
237
|
turning it off stops the next jobs.
|
|
238
238
|
|
|
239
|
-
The default
|
|
239
|
+
The default engine makes no automatic call to Luna, Sonnet or any other model. The Jev auto_context feature,
|
|
240
240
|
which the user enables explicitly and separately, is a limited, optional remote consultation outside that rule.
|
|
241
241
|
Local checks consume no tokens; the results the agent writes and the context it reads or adds count toward the
|
|
242
242
|
client's usage. A character limit is not a guarantee of token count or cost. A 15-minute agent automation the
|
|
243
243
|
user installed separately is not governed by this setting; examine it separately. Don't add a paid scheduler, a
|
|
244
244
|
model runner or a new dependency without being asked.
|
|
245
245
|
|
|
246
|
-
|
|
246
|
+
The `updates` section inside `doctor` shows the latest version check; a network error does not prove being
|
|
247
247
|
up to date. Use `beyin.py update --check --metadata-only` only for a version question. Route an update request to
|
|
248
248
|
the `brain-update` skill.
|
|
249
249
|
|
|
@@ -64,7 +64,7 @@ Tell the user three things: the part that works, the unverified/broken part, and
|
|
|
64
64
|
one. Give a short, concrete result instead of raw JSON. If the user's existing approval covers the safe fix, don't
|
|
65
65
|
ask again for nothing.
|
|
66
66
|
|
|
67
|
-
|
|
67
|
+
The `updates` section inside `doctor` shows the latest version check; a network error does not prove being up
|
|
68
68
|
to date. Use `beyin.py update --check --metadata-only` only for a version question. Route an update request to the
|
|
69
69
|
`brain-update` skill.
|
|
70
70
|
|
|
@@ -33,7 +33,7 @@ user step.
|
|
|
33
33
|
In the result message give the previous→new version, the verification result and any step left open. Don't share
|
|
34
34
|
tokens, local user paths, personal settings dumps or raw logs.
|
|
35
35
|
|
|
36
|
-
If `--metadata-only` is not recognized (
|
|
36
|
+
If `--metadata-only` is not recognized (older beyin), fall back to the existing `update --check`. Version
|
|
37
37
|
notifications are an on-by-default daily GitHub metadata check; they post no notes. Apply an off/on request with
|
|
38
38
|
`preferences --update-notifications off/on`. To silence one version use `update --dismiss X.Y.Z`. A metadata-only
|
|
39
39
|
result is not proof that the package can be installed.
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
"""Add "pi" as a first-class
|
|
2
|
+
"""Add "pi" as a first-class beyin harness, update-safely.
|
|
3
3
|
|
|
4
4
|
Why this exists
|
|
5
5
|
---------------
|
|
6
|
-
|
|
6
|
+
beyin knows the harnesses codex/claude/antigravity/hermes/opencode/omp, but not
|
|
7
7
|
pi. That blocks `beyin.py receipt --harness pi` and `context --harness pi`, so pi
|
|
8
|
-
work is mislabeled.
|
|
8
|
+
work is mislabeled. pi runs outside beyin's own hooks, so the fix has to live here.
|
|
9
9
|
|
|
10
10
|
How it stays update-safe
|
|
11
11
|
------------------------
|