@herbertgao/pi-extensions 2026.9.12 → 2026.9.13
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 +4 -4
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +8 -0
- package/node_modules/@herbertgao/pi-subagents/package.json +1 -1
- package/node_modules/@herbertgao/pi-subagents/src/agent-manager.ts +5 -4
- package/node_modules/@herbertgao/pi-subagents/src/mention-clone.ts +39 -16
- package/node_modules/@narumitw/pi-btw/README.md +21 -4
- package/node_modules/@narumitw/pi-btw/dist/index.ts +1668 -958
- package/node_modules/@narumitw/pi-btw/dist/index.ts.map +4 -4
- package/node_modules/@narumitw/pi-btw/docs/workflows.md +10 -2
- package/node_modules/@narumitw/pi-btw/package.json +1 -1
- package/node_modules/@narumitw/pi-btw/src/btw.ts +17 -79
- package/node_modules/@narumitw/pi-btw/src/conversation-context.ts +74 -0
- package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +196 -7
- package/node_modules/@narumitw/pi-btw/src/main-thread-updates.ts +40 -0
- package/node_modules/@narumitw/pi-btw/src/menu.ts +34 -2
- package/node_modules/@narumitw/pi-btw/src/settings.ts +49 -0
- package/node_modules/@narumitw/pi-btw/src/transcript-pager.ts +9 -1
- package/node_modules/@narumitw/pi-btw/src/workspace-layout.ts +559 -0
- package/node_modules/pi-multi-account/CHANGELOG.md +23 -0
- package/node_modules/pi-multi-account/README.md +38 -11
- package/node_modules/pi-multi-account/index.ts +371 -96
- package/node_modules/pi-multi-account/package.json +5 -4
- package/node_modules/pi-multi-account/provider-payload-stream.ts +36 -28
- package/node_modules/pi-multi-account/usage.ts +31 -2
- package/node_modules/pi-typesafe/README.md +3 -1
- package/node_modules/pi-typesafe/dist/auth.d.ts +10 -3
- package/node_modules/pi-typesafe/dist/auth.js +13 -7
- package/node_modules/pi-typesafe/dist/backends.d.ts +31 -0
- package/node_modules/pi-typesafe/dist/backends.js +33 -0
- package/node_modules/pi-typesafe/dist/client.d.ts +3 -9
- package/node_modules/pi-typesafe/dist/client.js +63 -39
- package/node_modules/pi-typesafe/dist/credentials.d.ts +11 -5
- package/node_modules/pi-typesafe/dist/credentials.js +15 -8
- package/node_modules/pi-typesafe/dist/extension.js +4 -1
- package/node_modules/pi-typesafe/dist/index.d.ts +1 -1
- package/node_modules/pi-typesafe/dist/index.js +1 -1
- package/node_modules/pi-typesafe/dist/login.d.ts +13 -7
- package/node_modules/pi-typesafe/dist/login.js +17 -8
- package/node_modules/pi-typesafe/dist/schema.js +19 -13
- package/node_modules/pi-typesafe/package.json +1 -1
- package/package.json +5 -5
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
|
|
2
|
+
import type { TypeSafeBackend } from "./backends.js";
|
|
2
3
|
import type { KeySource } from "./credentials.js";
|
|
3
4
|
export interface LoginResult {
|
|
4
5
|
/** Where the verified key was saved. */
|
|
@@ -7,9 +8,10 @@ export interface LoginResult {
|
|
|
7
8
|
models: number;
|
|
8
9
|
}
|
|
9
10
|
/**
|
|
10
|
-
* Prompt for a key (hidden input), verify it with a model listing, and store it for
|
|
11
|
-
* Resolves to undefined when the user cancels. Rejects with TypeSafeIntegrationError for an
|
|
12
|
-
* Refuses when TYPESAFE_API_KEY is set, because the environment would shadow the stored
|
|
11
|
+
* Prompt for a TypeSafe key (hidden input), verify it against api.typesafe.ai with a model listing, and store it for
|
|
12
|
+
* every pi-typesafe consumer. Resolves to undefined when the user cancels. Rejects with TypeSafeIntegrationError for an
|
|
13
|
+
* invalid or unverifiable key. Refuses when TYPESAFE_API_KEY is set, because the environment would shadow the stored
|
|
14
|
+
* key. Other backends have no login: their key is an environment variable only.
|
|
13
15
|
*/
|
|
14
16
|
export declare function loginWithPrompt(ctx: ExtensionCommandContext): Promise<LoginResult | undefined>;
|
|
15
17
|
export type EnsureApiKeyResult = {
|
|
@@ -20,8 +22,12 @@ export type EnsureApiKeyResult = {
|
|
|
20
22
|
login: LoginResult;
|
|
21
23
|
};
|
|
22
24
|
/**
|
|
23
|
-
* Use the configured key if there is one; otherwise run the login prompt. `undefined` means the user
|
|
24
|
-
* A store that must not be read throws `configuration` with the reason instead of prompting, so a
|
|
25
|
-
* problem stays visible; the result shape is frozen for existing callers.
|
|
25
|
+
* Use the configured key for the backend if there is one; otherwise run the login prompt. `undefined` means the user
|
|
26
|
+
* cancelled. A store that must not be read throws `configuration` with the reason instead of prompting, so a
|
|
27
|
+
* permissions problem stays visible; the result shape is frozen for existing callers. A backend without a login store
|
|
28
|
+
* (every backend except TypeSafe) throws `configuration` naming its environment variable instead of prompting, because
|
|
29
|
+
* the prompt would verify the key against the wrong service and store it where the TypeSafe key lives.
|
|
26
30
|
*/
|
|
27
|
-
export declare function ensureApiKey(ctx: ExtensionCommandContext
|
|
31
|
+
export declare function ensureApiKey(ctx: ExtensionCommandContext, options?: {
|
|
32
|
+
backend?: TypeSafeBackend;
|
|
33
|
+
}): Promise<EnsureApiKeyResult | undefined>;
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
import { DEFAULT_BACKEND, backendConfig, usesTypesafeKey } from "./backends.js";
|
|
1
2
|
import { createTypeSafe } from "./client.js";
|
|
2
3
|
import { keySituation, normalizeApiKey, storeApiKey } from "./credentials.js";
|
|
3
4
|
import { TypeSafeIntegrationError } from "./errors.js";
|
|
4
5
|
import { promptForApiKey } from "./key-prompt.js";
|
|
5
6
|
/**
|
|
6
|
-
* Prompt for a key (hidden input), verify it with a model listing, and store it for
|
|
7
|
-
* Resolves to undefined when the user cancels. Rejects with TypeSafeIntegrationError for an
|
|
8
|
-
* Refuses when TYPESAFE_API_KEY is set, because the environment would shadow the stored
|
|
7
|
+
* Prompt for a TypeSafe key (hidden input), verify it against api.typesafe.ai with a model listing, and store it for
|
|
8
|
+
* every pi-typesafe consumer. Resolves to undefined when the user cancels. Rejects with TypeSafeIntegrationError for an
|
|
9
|
+
* invalid or unverifiable key. Refuses when TYPESAFE_API_KEY is set, because the environment would shadow the stored
|
|
10
|
+
* key. Other backends have no login: their key is an environment variable only.
|
|
9
11
|
*/
|
|
10
12
|
export async function loginWithPrompt(ctx) {
|
|
11
13
|
if (process.env.TYPESAFE_API_KEY?.trim()) {
|
|
@@ -23,16 +25,23 @@ export async function loginWithPrompt(ctx) {
|
|
|
23
25
|
return { path: storeApiKey(key), models: models.length };
|
|
24
26
|
}
|
|
25
27
|
/**
|
|
26
|
-
* Use the configured key if there is one; otherwise run the login prompt. `undefined` means the user
|
|
27
|
-
* A store that must not be read throws `configuration` with the reason instead of prompting, so a
|
|
28
|
-
* problem stays visible; the result shape is frozen for existing callers.
|
|
28
|
+
* Use the configured key for the backend if there is one; otherwise run the login prompt. `undefined` means the user
|
|
29
|
+
* cancelled. A store that must not be read throws `configuration` with the reason instead of prompting, so a
|
|
30
|
+
* permissions problem stays visible; the result shape is frozen for existing callers. A backend without a login store
|
|
31
|
+
* (every backend except TypeSafe) throws `configuration` naming its environment variable instead of prompting, because
|
|
32
|
+
* the prompt would verify the key against the wrong service and store it where the TypeSafe key lives.
|
|
29
33
|
*/
|
|
30
|
-
export async function ensureApiKey(ctx) {
|
|
31
|
-
const
|
|
34
|
+
export async function ensureApiKey(ctx, options = {}) {
|
|
35
|
+
const backend = options.backend ?? DEFAULT_BACKEND;
|
|
36
|
+
const situation = keySituation(backend);
|
|
32
37
|
if (situation.kind === "environment" || situation.kind === "stored")
|
|
33
38
|
return { source: situation.kind };
|
|
34
39
|
if (situation.kind === "unusable")
|
|
35
40
|
throw new TypeSafeIntegrationError("configuration", situation.reason);
|
|
41
|
+
const config = backendConfig(backend);
|
|
42
|
+
if (!usesTypesafeKey(config)) {
|
|
43
|
+
throw new TypeSafeIntegrationError("configuration", `No ${config.label} key. Set ${config.keyEnv} in the environment; /typesafe login stores a TypeSafe key only.`);
|
|
44
|
+
}
|
|
36
45
|
const login = await loginWithPrompt(ctx);
|
|
37
46
|
return login ? { source: "stored", login } : undefined;
|
|
38
47
|
}
|
|
@@ -5,42 +5,48 @@ import { TypeSafeIntegrationError } from "./errors.js";
|
|
|
5
5
|
export const DEFAULT_MAX_INPUT_BYTES = 65_536;
|
|
6
6
|
/** Questions one request may ask. More than this needs `chunkEvaluationRequest`, which splits and fans out. */
|
|
7
7
|
export const DEFAULT_MAX_QUESTIONS = 32;
|
|
8
|
-
// The API accepts structured descriptions, not only strings.
|
|
9
|
-
|
|
8
|
+
// The API accepts structured descriptions, not only strings. The schema is the only shape guidance the model gets
|
|
9
|
+
// before its first call, so every field the agent authors says what it means.
|
|
10
|
+
const entry = (description) => Type.Union([
|
|
10
11
|
Type.String(),
|
|
11
12
|
Type.Null(),
|
|
12
13
|
Type.Array(Type.Unknown()),
|
|
13
14
|
Type.Record(Type.String(), Type.Unknown()),
|
|
14
|
-
]);
|
|
15
|
-
const instructions = Type.Optional(entry);
|
|
15
|
+
], description === undefined ? {} : { description });
|
|
16
|
+
const instructions = Type.Optional(entry("One judgment about the whole state, phrased as a question or a statement."));
|
|
16
17
|
const question = Type.Union([
|
|
17
18
|
Type.Object({
|
|
18
|
-
type: Type.Literal("noul"),
|
|
19
|
+
type: Type.Literal("noul", { description: "Yes or no: the probability the instructions hold." }),
|
|
19
20
|
instructions,
|
|
20
21
|
criteria: Type.Optional(Type.Union([
|
|
21
22
|
Type.Null(),
|
|
22
|
-
Type.Object({ true: Type.Optional(entry), false: Type.Optional(entry) }, { additionalProperties: false }),
|
|
23
|
-
])),
|
|
23
|
+
Type.Object({ true: Type.Optional(entry()), false: Type.Optional(entry()) }, { additionalProperties: false }),
|
|
24
|
+
], { description: "Optional: what counts as yes and what counts as no, { true, false }." })),
|
|
24
25
|
}, { additionalProperties: false }),
|
|
25
26
|
Type.Object({
|
|
26
|
-
type: Type.Literal("choice"),
|
|
27
|
+
type: Type.Literal("choice", { description: "Pick one criteria label." }),
|
|
27
28
|
instructions,
|
|
28
|
-
criteria: Type.Record(Type.String({ minLength: 1, maxLength: 200 }), entry, {
|
|
29
|
+
criteria: Type.Record(Type.String({ minLength: 1, maxLength: 200 }), entry(), {
|
|
30
|
+
minProperties: 1,
|
|
31
|
+
maxProperties: 64,
|
|
32
|
+
description: "The options as a map from label to when it applies: { billing: \"Charges and payments\", other: null }. 1–64 entries.",
|
|
33
|
+
}),
|
|
29
34
|
}, { additionalProperties: false }),
|
|
30
35
|
Type.Object({
|
|
31
|
-
type: Type.Literal("score"),
|
|
36
|
+
type: Type.Literal("score", { description: "Rate against the ordered criteria levels." }),
|
|
32
37
|
instructions,
|
|
33
|
-
criteria: Type.Array(entry, { minItems: 2, maxItems: 32 }),
|
|
38
|
+
criteria: Type.Array(entry(), { minItems: 2, maxItems: 32, description: "Ordered rubric levels, lowest first: [\"neutral\", \"angry\"]. 2–32 levels." }),
|
|
34
39
|
}, { additionalProperties: false }),
|
|
35
40
|
]);
|
|
36
41
|
/** The JSON schema used by both the Pi tool and the programmatic interface. */
|
|
37
42
|
export const evaluationSchema = Type.Object({
|
|
38
|
-
state: entry,
|
|
43
|
+
state: entry("What to judge: text, or an object whose fields the questions name."),
|
|
39
44
|
questions: Type.Record(Type.String({ minLength: 1, maxLength: 100 }), question, {
|
|
40
45
|
minProperties: 1,
|
|
41
46
|
maxProperties: DEFAULT_MAX_QUESTIONS,
|
|
47
|
+
description: "Questions keyed by a short id, as an object map, not an array: { \"urgent\": { type: \"noul\", instructions: ... } }.",
|
|
42
48
|
}),
|
|
43
|
-
model: Type.Optional(Type.String({ minLength: 1, maxLength: 100 })),
|
|
49
|
+
model: Type.Optional(Type.String({ minLength: 1, maxLength: 100, description: "Jev model id, e.g. jev-latest. Omit for the default." })),
|
|
44
50
|
}, { additionalProperties: false });
|
|
45
51
|
const usage = `Expected { state, questions: { <id>: { type: "choice", instructions, criteria: { label: description|null } } | { type: "score", instructions, criteria: [level0, level1, ...] } | { type: "noul", instructions } } }; 1–${DEFAULT_MAX_QUESTIONS} questions, Choice 1–64 options, Score 2–32 levels.`;
|
|
46
52
|
/** Paths and messages only; never the submitted values. */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-typesafe",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"description": "TypeSafe AI (Jev) decisions for Pi: batched Choice/Score/Noul evaluation tool, terminal playground, and a typed API other extensions build on.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@herbertgao/pi-extensions",
|
|
3
|
-
"version": "2026.9.
|
|
3
|
+
"version": "2026.9.13",
|
|
4
4
|
"description": "Aggregate installer for HerbertGao-maintained Pi extensions.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"extensions",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"@earendil-works/pi-tui": "^0.85.1",
|
|
44
44
|
"@herbertgao/pi-bark": "0.1.2",
|
|
45
45
|
"@herbertgao/pi-cc-extensions": "0.9.4",
|
|
46
|
-
"@herbertgao/pi-subagents": "0.18.
|
|
46
|
+
"@herbertgao/pi-subagents": "0.18.2",
|
|
47
47
|
"@herbertgao/resume-from": "0.2.2",
|
|
48
48
|
"@herbertgao/sol-pi": "0.3.1",
|
|
49
49
|
"@juicesharp/rpiv-ask-user-question": "2.11.0",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
56
56
|
"@mozilla/readability": "^0.6.0",
|
|
57
57
|
"@napi-rs/keyring": "^1.3.0",
|
|
58
|
-
"@narumitw/pi-btw": "0.
|
|
58
|
+
"@narumitw/pi-btw": "0.61.0",
|
|
59
59
|
"@narumitw/pi-caffeinate": "0.49.8",
|
|
60
60
|
"@narumitw/pi-tui-kit": "^0.64.0",
|
|
61
61
|
"@noble/ed25519": "^3.1.0",
|
|
@@ -91,8 +91,8 @@
|
|
|
91
91
|
"pi-jev-auto-mode": "0.4.1",
|
|
92
92
|
"pi-lens": "4.2.1",
|
|
93
93
|
"pi-mcp-adapter": "2.36.0",
|
|
94
|
-
"pi-multi-account": "1.
|
|
95
|
-
"pi-typesafe": "0.
|
|
94
|
+
"pi-multi-account": "1.23.0",
|
|
95
|
+
"pi-typesafe": "0.7.1",
|
|
96
96
|
"pi-web-access": "0.30.0",
|
|
97
97
|
"pidusage": "^4.0.1",
|
|
98
98
|
"promise.try": "^2.0.1",
|