@matuto-ai/pi-broker-connector 0.3.0 → 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 +8 -4
- package/package.json +44 -9
- package/src/private-input.mjs +22 -13
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A native Pi extension providing durable, session-bound messaging through the [Psst broker](https://github.com/matuto-ai/psst). Runs **inside the Pi process in your existing sandbox**. No host launcher, local model, provider subscription, or additional service is required by the connector.
|
|
4
4
|
|
|
5
|
-
**Version 0.3.
|
|
5
|
+
**Version 0.3.1:** native private setup, persistent installation selection and automatic reconnection of independent Pi sessions, retaining automatic native delivery and transport-auth pause protection. Tested with the official Pi 1.4.0 SDK and a local fixture model; live authenticated user-sandbox acceptance remains a separate step.
|
|
6
6
|
|
|
7
7
|
## Requirements
|
|
8
8
|
|
|
@@ -33,7 +33,7 @@ This uses the default branch. To pin a reviewed commit, append `@` and its exact
|
|
|
33
33
|
### From npm (only after publication)
|
|
34
34
|
|
|
35
35
|
```sh
|
|
36
|
-
pi install npm:@matuto-ai/pi-broker-connector@0.3.
|
|
36
|
+
pi install npm:@matuto-ai/pi-broker-connector@0.3.1
|
|
37
37
|
```
|
|
38
38
|
|
|
39
39
|
The command requires the version to be present on npm. If publication is still pending, use a reviewed checkout instead.
|
|
@@ -79,7 +79,7 @@ Use the existing bundle path; keep its `token` next to `connection.json`. After
|
|
|
79
79
|
Install or update **inside the same sandbox**, then use `/reload` in the running Pi:
|
|
80
80
|
|
|
81
81
|
```sh
|
|
82
|
-
pi install npm:@matuto-ai/pi-broker-connector@0.3.
|
|
82
|
+
pi install npm:@matuto-ai/pi-broker-connector@0.3.1
|
|
83
83
|
```
|
|
84
84
|
|
|
85
85
|
This installer command is not a second agent session. No sandbox recreation or Pi process restart is required. Version 0.1.1 does not have `/psst-connect`; 0.1.2 adds that command, while automatic delivery requires 0.2.0 or later.
|
|
@@ -177,7 +177,7 @@ Tests cover private bundle validation, exact session isolation, duplicate owners
|
|
|
177
177
|
|
|
178
178
|
## Publishing
|
|
179
179
|
|
|
180
|
-
This release uses package version `0.3.
|
|
180
|
+
This release uses package version `0.3.1` and matching GitHub release tag `v0.3.1`. The release workflow publishes the package only after its checks pass.
|
|
181
181
|
|
|
182
182
|
The release workflow follows the existing Pi plugin convention: a published GitHub release triggers checks and npm publishing. It requires a `v<package.version>` tag and runs the native host gate before publishing. Nothing is published by CI on pull requests or ordinary pushes.
|
|
183
183
|
|
|
@@ -240,3 +240,7 @@ component, connects to a real fixture HTTPS broker, and recreates HOME while
|
|
|
240
240
|
preserving the agent directory. It asserts one credential and two distinct
|
|
241
241
|
sessions without a second setup. No model turn or authenticated user-sandbox
|
|
242
242
|
acceptance is claimed. The broker checkout must include its enrollment TLS fixture.
|
|
243
|
+
|
|
244
|
+
### Masked-field keyboard regression tests
|
|
245
|
+
|
|
246
|
+
`npm test` requires Python 3 on Linux for the real POSIX PTY keyboard tests. They use only synthetic input and the pinned official Pi TUI 1.4.0 development dependency. Runtime imports resolve through Pi’s native extension loader; no terminal keyboard mode is changed by the connector itself. Legacy text/paste and Kitty printable input are supported, while control keys use the public host decoder. This does not claim complete xterm `modifyOtherKeys` printable-key support.
|
package/package.json
CHANGED
|
@@ -1,15 +1,50 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@matuto-ai/pi-broker-connector",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Session-bound Psst broker messaging tools for Pi",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
|
-
"repository": {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
"
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
"
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "git+https://github.com/matuto-ai/pi-broker-connector.git"
|
|
10
|
+
},
|
|
11
|
+
"engines": {
|
|
12
|
+
"node": ">=24.19.0 <25"
|
|
13
|
+
},
|
|
14
|
+
"keywords": [
|
|
15
|
+
"pi-package",
|
|
16
|
+
"pi",
|
|
17
|
+
"psst",
|
|
18
|
+
"broker"
|
|
19
|
+
],
|
|
20
|
+
"files": [
|
|
21
|
+
"extensions/",
|
|
22
|
+
"src/",
|
|
23
|
+
"vendor/",
|
|
24
|
+
"README.md",
|
|
25
|
+
"LICENSE"
|
|
26
|
+
],
|
|
27
|
+
"pi": {
|
|
28
|
+
"extensions": [
|
|
29
|
+
"./extensions/psst.ts"
|
|
30
|
+
]
|
|
31
|
+
},
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"@earendil-works/pi-coding-agent": "*",
|
|
34
|
+
"typebox": "*",
|
|
35
|
+
"@earendil-works/pi-tui": "^1.4.0"
|
|
36
|
+
},
|
|
37
|
+
"scripts": {
|
|
38
|
+
"test": "node --test test/*.test.mjs",
|
|
39
|
+
"check": "node scripts/check.mjs",
|
|
40
|
+
"test:host": "node --test test/native-host.probe.mjs",
|
|
41
|
+
"prepack": "npm run check && npm test"
|
|
42
|
+
},
|
|
43
|
+
"publishConfig": {
|
|
44
|
+
"access": "public",
|
|
45
|
+
"registry": "https://registry.npmjs.org/"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@earendil-works/pi-tui": "1.4.0"
|
|
49
|
+
}
|
|
15
50
|
}
|
package/src/private-input.mjs
CHANGED
|
@@ -1,25 +1,34 @@
|
|
|
1
|
+
import { matchesKey, isKeyRelease, decodeKittyPrintable } from '@earendil-works/pi-tui';
|
|
1
2
|
import { LocalError } from '../vendor/broker/reference/errors.mjs';
|
|
2
3
|
|
|
3
4
|
// A focused native component: the value never enters Pi's editor or a message.
|
|
4
|
-
//
|
|
5
|
+
// Use public host decoders for control keys and Kitty printable input; legacy text/paste stays masked.
|
|
5
6
|
export function maskedPairingComponent({done,requestRender}) {
|
|
6
|
-
let value='',closed=false,pasting=false;
|
|
7
|
-
const finish=result=>{if(closed)return;closed=true;value='';done(result);};
|
|
7
|
+
let value='',closed=false,pasting=false,paste='',invalidPaste=false,hint=false;
|
|
8
|
+
const finish=result=>{if(closed)return;closed=true;value='';paste='';done(result);};
|
|
9
|
+
const append=data=>{if(/^[A-Za-z0-9_-]+$/.test(data)&&value.length+data.length<=43){value+=data;hint=false;}};
|
|
8
10
|
return {
|
|
9
|
-
render(width){return ['Psst: enter the one-time pairing secret (hidden)', '*'.repeat(value.length), 'Enter: connect Esc: cancel'].map(line=>line.slice(0,Math.max(0,width)));},
|
|
11
|
+
render(width){return ['Psst: enter the one-time pairing secret (hidden)', '*'.repeat(value.length), hint?'Paste the complete 43-character pairing secret.':'Enter: connect Esc or Ctrl+C: cancel'].map(line=>line.slice(0,Math.max(0,width)));},
|
|
10
12
|
invalidate(){},
|
|
11
13
|
handleInput(data){
|
|
12
|
-
if(closed)return;
|
|
13
|
-
if(data
|
|
14
|
-
if(data
|
|
15
|
-
if(data
|
|
16
|
-
// Pi
|
|
17
|
-
if(data.startsWith('\x1b[200~')){pasting=true;data=data.slice(6);}
|
|
18
|
-
if(
|
|
19
|
-
|
|
14
|
+
if(closed||typeof data!=='string'||isKeyRelease(data))return;
|
|
15
|
+
if(matchesKey(data,'escape')||matchesKey(data,'ctrl+c')){finish(undefined);return;}
|
|
16
|
+
if(matchesKey(data,'enter')){if(!pasting){if(/^[A-Za-z0-9_-]{43}$/.test(value))finish(value);else{hint=true;requestRender();}}return;}
|
|
17
|
+
if(!pasting&&matchesKey(data,'backspace')){value=value.slice(0,-1);hint=false;requestRender();return;}
|
|
18
|
+
// Pi normally wraps a whole paste; tolerate marker/body/end delivered separately.
|
|
19
|
+
if(data.startsWith('\x1b[200~')){pasting=true;paste='';invalidPaste=false;data=data.slice(6);}
|
|
20
|
+
if(pasting){
|
|
21
|
+
const end=data.indexOf('\x1b[201~');
|
|
22
|
+
const body=end<0?data:data.slice(0,end);
|
|
23
|
+
if(!/^[A-Za-z0-9_-]*$/.test(body)||paste.length+body.length>43)invalidPaste=true;
|
|
24
|
+
if(!invalidPaste)paste+=body;
|
|
25
|
+
if(end>=0){if(data.slice(end+6))invalidPaste=true;if(!invalidPaste)append(paste);else hint=true;paste='';pasting=false;invalidPaste=false;}
|
|
26
|
+
}else{
|
|
27
|
+
append(decodeKittyPrintable(data)??data);
|
|
28
|
+
}
|
|
20
29
|
requestRender();
|
|
21
30
|
},
|
|
22
|
-
dispose(){closed=true;value='';},
|
|
31
|
+
dispose(){closed=true;value='';paste='';},
|
|
23
32
|
};
|
|
24
33
|
}
|
|
25
34
|
export async function promptPairingSecret(ctx) {
|