gentle-pi 4.3.0 → 4.5.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/README.md +10 -7
- package/assets/agents/gentle-ai-worker.md +1 -1
- package/assets/design-canvas/canvas.css +648 -0
- package/assets/design-canvas/canvas.js +1497 -0
- package/assets/design-canvas/index.html +88 -0
- package/assets/design-canvas/inspector.js +290 -0
- package/assets/orchestrator-delegation-reference.md +2 -2
- package/assets/orchestrator-verification.md +1 -1
- package/assets/orchestrator.md +2 -2
- package/bin/engram-guard +1 -1
- package/bin/gentle-shell.mjs +138 -155
- package/docs/bundled-install.md +47 -42
- package/docs/delegated-verification.md +6 -0
- package/docs/gentle-agents-activity.md +5 -1
- package/docs/gentle-music.md +82 -0
- package/docs/gentle-shell.md +80 -10
- package/docs/install-wizard.md +30 -6
- package/docs/permission-modes.md +7 -2
- package/docs/readme-reference.md +72 -55
- package/docs/session-profile-format.md +26 -0
- package/docs/voice.md +259 -0
- package/docs/yolo-mode.md +17 -2
- package/extensions/ask-user-choice.ts +4 -1
- package/extensions/gentle-agents.ts +187 -40
- package/extensions/gentle-ai.ts +1765 -1185
- package/extensions/gentle-design.ts +158 -0
- package/extensions/gentle-music.ts +354 -0
- package/extensions/gentle-shell.ts +418 -79
- package/extensions/gentle-voice.ts +11 -0
- package/extensions/session-scratch.ts +41 -22
- package/extensions/skill-registry.ts +63 -8
- package/lib/agent-profiles.ts +26 -0
- package/lib/agents-config.ts +35 -0
- package/lib/agents-protocol.ts +57 -1
- package/lib/agents-runner.ts +52 -3
- package/lib/agents-session-transport.ts +101 -6
- package/lib/agents-widget.ts +14 -1
- package/lib/auto-permission-memory.ts +48 -18
- package/lib/auto-permission-runtime.ts +21 -6
- package/lib/clipboard-image.ts +147 -0
- package/lib/command-palette-catalog.ts +3 -2
- package/lib/commit-slice-signal.ts +1 -1
- package/lib/context-backstop.ts +36 -0
- package/lib/design-canvas-server.ts +947 -0
- package/lib/design-comments.ts +437 -0
- package/lib/design-handoffs.ts +313 -0
- package/lib/design-open-browser.ts +58 -0
- package/lib/design-sources.ts +120 -0
- package/lib/external-editor.ts +31 -0
- package/lib/gentle-design.ts +513 -0
- package/lib/gentle-shell-bundled.ts +141 -57
- package/lib/gentle-shell-launcher.ts +11 -4
- package/lib/gentle-shell-startup-update.ts +61 -9
- package/lib/gentle-shell-uninstall.ts +33 -1
- package/lib/image-attachments.ts +150 -0
- package/lib/inprocess-reviewer.ts +33 -2
- package/lib/jobs-sidebar-state.ts +22 -3
- package/lib/jobs-widget.ts +112 -0
- package/lib/nan-provider.ts +3 -0
- package/lib/native-review-cli.ts +11 -4
- package/lib/notification-audio-native.ts +149 -13
- package/lib/notification-audio.ts +4 -0
- package/lib/notification-pulse-worker.ts +82 -18
- package/lib/notification-service.ts +5 -1
- package/lib/orchestrator-presence.ts +78 -8
- package/lib/orchestrator-scope.ts +10 -0
- package/lib/orchestrator-state.ts +11 -3
- package/lib/permission-mode-policy.ts +2 -2
- package/lib/review-host-relay.ts +11 -2
- package/lib/review-reminder-receipt.ts +24 -1
- package/lib/session-profile-append-controller.ts +713 -0
- package/lib/session-profile-disk-reader.ts +182 -0
- package/lib/session-profile-freeze.ts +2 -2
- package/lib/session-profile-persistence.ts +15 -7
- package/lib/session-scratch.ts +52 -3
- package/lib/session-worktree-registry.ts +7 -0
- package/lib/shell-bar.ts +6 -7
- package/lib/shell-changes.ts +81 -5
- package/lib/shell-prompt.ts +4 -4
- package/lib/shell-sidebar-layout.ts +27 -7
- package/lib/shell-todo.ts +1 -1
- package/lib/verifier-admission.ts +5 -4
- package/lib/vim-editor-adapter.ts +14 -10
- package/lib/voice-artifacts.ts +188 -0
- package/lib/voice-command.ts +576 -0
- package/lib/voice-install.ts +455 -0
- package/lib/voice-platform.ts +99 -0
- package/lib/voice-push-to-talk.ts +262 -0
- package/lib/voice-session.ts +460 -0
- package/lib/voice-settings.ts +50 -0
- package/lib/voice-ui.ts +158 -0
- package/lib/yolo-session-policy.ts +58 -22
- package/package.json +1 -1
- package/runtime/gentle-shell-bundled.mjs +140 -56
- package/runtime/gentle-shell-launcher.mjs +11 -4
- package/runtime/gentle-shell-startup-update.mjs +61 -9
- package/runtime/gentle-shell-uninstall.mjs +33 -1
- package/runtime/native-review-cli.mjs +11 -4
- package/scripts/bundled-engram-migration.mjs +0 -6
- package/scripts/bundled-install.mjs +209 -13
- package/scripts/gentle-ai-installer.mjs +10 -10
- package/scripts/installer-downloads.mjs +31 -7
- package/scripts/installer-preflight.mjs +6 -4
- package/scripts/installer-windows.mjs +37 -7
- package/scripts/main-channel.mjs +91 -17
- package/scripts/pi-update.mjs +37 -7
- package/scripts/verify-package-files.mjs +26 -2
- package/scripts/voice-worker.cjs +476 -0
- package/skills/design/SKILL.md +110 -0
- package/tests/agent-profiles.test.ts +24 -0
- package/tests/agents-config.test.ts +61 -0
- package/tests/agents-fake-child.ts +8 -1
- package/tests/agents-protocol.test.ts +32 -0
- package/tests/agents-runner.test.ts +226 -5
- package/tests/agents-session-transport.test.ts +53 -3
- package/tests/ask-user-choice.test.ts +30 -0
- package/tests/auto-mode.test.ts +17 -0
- package/tests/auto-permission-memory-diagnostics.test.ts +56 -0
- package/tests/auto-permission-runtime.test.ts +85 -1
- package/tests/autonomous-guard.test.ts +20 -0
- package/tests/bundled-install.test.ts +276 -5
- package/tests/clipboard-image.test.ts +114 -0
- package/tests/command-palette.test.ts +4 -4
- package/tests/context-backstop.test.ts +70 -4
- package/tests/delegate-for-reason-contract.test.ts +2 -1
- package/tests/design-canvas-assets.test.ts +710 -0
- package/tests/design-canvas-server.test.ts +1096 -0
- package/tests/design-comments.test.ts +201 -0
- package/tests/design-handoffs.test.ts +282 -0
- package/tests/design-open-browser.test.ts +70 -0
- package/tests/design-sources.test.ts +132 -0
- package/tests/engram-safety.test.ts +132 -57
- package/tests/external-editor.test.ts +84 -0
- package/tests/fixtures/primary-session-prompt/gentleman.golden.md +3 -3
- package/tests/gentle-agents.test.ts +369 -24
- package/tests/gentle-ai-binary.test.ts +1 -1
- package/tests/gentle-ai-installer.test.ts +51 -51
- package/tests/gentle-ai.test.ts +928 -448
- package/tests/gentle-design.test.ts +1313 -0
- package/tests/gentle-music.test.ts +452 -0
- package/tests/gentle-shell-bundled.test.ts +321 -248
- package/tests/gentle-shell-launcher.test.ts +29 -2
- package/tests/gentle-shell-startup-update.test.ts +77 -1
- package/tests/gentle-shell-uninstall.test.ts +59 -0
- package/tests/gentle-shell.test.ts +227 -27
- package/tests/gentle-todo.test.ts +11 -0
- package/tests/image-attachments.test.ts +119 -0
- package/tests/image-paste-chips.test.ts +236 -0
- package/tests/inprocess-reviewer.test.ts +55 -2
- package/tests/installer-bundles.test.ts +12 -6
- package/tests/installer-downloads.test.ts +32 -0
- package/tests/installer-posix-bootstrap.test.ts +8 -8
- package/tests/installer-preflight.test.ts +16 -0
- package/tests/installer-server.test.ts +2 -2
- package/tests/installer-windows-bootstrap.test.ts +61 -3
- package/tests/installer-windows-diagnostics.test.ts +111 -0
- package/tests/jobs-widget.test.ts +138 -0
- package/tests/main-channel-upgrade.test.ts +232 -2
- package/tests/main-channel.test.ts +140 -21
- package/tests/model-profiles-preservation.test.ts +2 -2
- package/tests/nan-provider.test.ts +36 -0
- package/tests/native-review-capability-contract.test.ts +11 -4
- package/tests/native-review-parity.test.ts +1 -1
- package/tests/notification-audio-native.test.ts +128 -9
- package/tests/notification-customize.test.ts +17 -5
- package/tests/odd-routing-canonical-ratchet.test.ts +2 -1
- package/tests/orchestrator-budget.test.ts +5 -2
- package/tests/orchestrator-presence.test.ts +100 -2
- package/tests/orchestrator-rdd-ownership.test.ts +2 -2
- package/tests/orchestrator-scope.test.ts +14 -0
- package/tests/orchestrator-state.test.ts +29 -0
- package/tests/package-files.test.ts +34 -0
- package/tests/package-manifest.test.ts +6 -6
- package/tests/permission-mode-policy.test.ts +10 -1
- package/tests/pi-update.test.ts +104 -4
- package/tests/rdd-aware-verification-contract.test.ts +1 -1
- package/tests/review-host-relay-routing.test.ts +88 -1
- package/tests/review-host-relay.test.ts +9 -2
- package/tests/review-json-arguments.test.ts +20 -3
- package/tests/review-loadout-rdd-off-sdk.test.ts +23 -2
- package/tests/review-relay-transport-agent.test.ts +26 -0
- package/tests/review-reminder-receipt.test.ts +31 -1
- package/tests/runtime-harness.mjs +188 -211
- package/tests/session-changes.test.ts +2 -1
- package/tests/session-profile-append-controller-fork.test.ts +458 -0
- package/tests/session-profile-append-controller-pi.test.ts +290 -0
- package/tests/session-profile-append-controller.test.ts +731 -0
- package/tests/session-profile-disk-reader-pi.test.ts +183 -0
- package/tests/session-profile-disk-reader.test.ts +311 -0
- package/tests/session-profile-freeze.test.ts +6 -4
- package/tests/session-scratch.test.ts +68 -2
- package/tests/session-worktree-registry.test.ts +13 -1
- package/tests/shell-bar.test.ts +18 -6
- package/tests/shell-changes.test.ts +148 -1
- package/tests/shell-prompt.test.ts +3 -3
- package/tests/shell-render-cache.test.ts +134 -1
- package/tests/shell-sidebar-layout.test.ts +67 -0
- package/tests/short-check-routing-contract.test.ts +1 -1
- package/tests/skill-collision-prefixes.test.ts +3 -1
- package/tests/skill-registry-watcher.test.ts +17 -5
- package/tests/skill-registry.test.ts +47 -3
- package/tests/task-size-routing-contract.test.ts +1 -1
- package/tests/test-strength-contract.test.ts +1 -1
- package/tests/verifier-admission.test.ts +18 -1
- package/tests/vim-editor-adapter.test.ts +2 -2
- package/tests/voice-command.test.ts +773 -0
- package/tests/voice-install.test.ts +323 -0
- package/tests/voice-platform.test.ts +176 -0
- package/tests/voice-push-to-talk.test.ts +444 -0
- package/tests/voice-session.test.ts +434 -0
- package/tests/voice-settings.test.ts +49 -0
- package/tests/voice-ui.test.ts +97 -0
- package/tests/voice-worker.test.ts +445 -0
- package/tests/weak-model-economy-prompt.test.ts +32 -0
- package/tests/windows-hidden-processes.test.ts +25 -2
- package/tests/yolo-customize.test.ts +5 -1
- package/tests/yolo-mode.test.ts +1 -1
- package/tests/yolo-session-policy-capture.test.ts +104 -0
|
@@ -11,6 +11,8 @@ import {
|
|
|
11
11
|
CONTEXT_BACKSTOP_TOKENS_ENV,
|
|
12
12
|
contextBackstopReached,
|
|
13
13
|
contextBackstopThreshold,
|
|
14
|
+
createThrottledContextMeasure,
|
|
15
|
+
type MeasuredContext,
|
|
14
16
|
} from "../lib/context-backstop.ts";
|
|
15
17
|
|
|
16
18
|
// Harness roadmap R1: the parent-context backstop was a fixed "~150k tokens" in prompt text, so the model had to
|
|
@@ -63,7 +65,7 @@ test("unknown tokens never count as reaching the backstop", () => {
|
|
|
63
65
|
type Handler = (event: unknown, ctx: ExtensionContext) => unknown;
|
|
64
66
|
type Patch = { content?: Array<{ type: string; text?: string }>; structuredContent?: unknown; isError?: boolean } | undefined;
|
|
65
67
|
|
|
66
|
-
function session(t: TestContext, child: boolean) {
|
|
68
|
+
function session(t: TestContext, child: boolean, options: { now?: () => number; minIntervalMs?: number } = {}) {
|
|
67
69
|
const cwd = realpathSync(mkdtempSync(join(tmpdir(), "context-backstop-")));
|
|
68
70
|
const configHome = mkdtempSync(join(tmpdir(), "context-backstop-config-"));
|
|
69
71
|
const previous = process.env.GENTLE_PI_CONFIG_HOME;
|
|
@@ -76,10 +78,19 @@ function session(t: TestContext, child: boolean) {
|
|
|
76
78
|
});
|
|
77
79
|
const handlers = new Map<string, Handler>();
|
|
78
80
|
const pi = { on: (name: string, handler: Handler) => { handlers.set(name, handler); }, events: { on() {}, emit() {} }, registerCommand() {}, registerTool() {} } as unknown as ExtensionAPI;
|
|
79
|
-
|
|
81
|
+
// Semantic tests without options keep per-call measuring (minIntervalMs 0); callers that pass
|
|
82
|
+
// options (a fake clock) keep the production window resolution.
|
|
83
|
+
const measureOptions = Object.keys(options).length === 0 ? { minIntervalMs: 0 } : options;
|
|
84
|
+
createGentleAiExtension({
|
|
85
|
+
nativeReviewCli: null,
|
|
86
|
+
processEnv: { GENTLE_PI_AGENTS_CHILD: child ? "1" : "0", GENTLE_AI_TELEMETRY: "0" },
|
|
87
|
+
contextBackstopMeasure: measureOptions,
|
|
88
|
+
})(pi);
|
|
80
89
|
let usage: ContextUsage | undefined = { tokens: 10_000, contextWindow: 1_000_000, percent: 1 };
|
|
90
|
+
let measures = 0;
|
|
81
91
|
const sessionManager = { getSessionId: () => "session-backstop", getCwd: () => cwd, getEntries: () => [], getBranch: () => [] };
|
|
82
|
-
const ctx = { cwd, hasUI: false, ui: { notify() {} }, sessionManager, getContextUsage: () => usage } as unknown as ExtensionContext;
|
|
92
|
+
const ctx = { cwd, hasUI: false, ui: { notify() {} }, sessionManager, getContextUsage: () => { measures++; return usage; } } as unknown as ExtensionContext;
|
|
93
|
+
const measureCount = () => measures;
|
|
83
94
|
const setTokens = (tokens: number | null, contextWindow = 1_000_000) => {
|
|
84
95
|
usage = { tokens, contextWindow, percent: tokens === null ? null : (tokens / contextWindow) * 100 };
|
|
85
96
|
};
|
|
@@ -87,7 +98,7 @@ function session(t: TestContext, child: boolean) {
|
|
|
87
98
|
toolName: "read", toolCallId: "call-read", isError: false, input: { path: "a.ts" },
|
|
88
99
|
content: [{ type: "text", text: "file body" }], structuredContent: { lines: 1 }, ...overrides,
|
|
89
100
|
}, ctx) as Promise<Patch>;
|
|
90
|
-
return { cwd, ctx, handlers, setTokens, read };
|
|
101
|
+
return { cwd, ctx, handlers, setTokens, read, measureCount, options };
|
|
91
102
|
}
|
|
92
103
|
|
|
93
104
|
test("the primary session gets one notice when its measured context first reaches the backstop", async (t) => {
|
|
@@ -157,3 +168,58 @@ test("a parent write result carries the notice after its own bookkeeping", async
|
|
|
157
168
|
assert.equal(result?.content?.[0]?.text, "Wrote src/a.ts");
|
|
158
169
|
assert.match(result?.content?.[1]?.text ?? "", /Context backstop/);
|
|
159
170
|
});
|
|
171
|
+
|
|
172
|
+
// The measurement behind the backstop (ctx.getContextUsage()) rebuilds the whole session
|
|
173
|
+
// projection, so it is sampled at most once per window per session instead of once per
|
|
174
|
+
// tool result. The window never decides the notice: it only decides when the context is
|
|
175
|
+
// looked at again.
|
|
176
|
+
test("the throttled measure samples once per window and the first sample of a session is immediate", () => {
|
|
177
|
+
let clock = 1_000;
|
|
178
|
+
const measure = createThrottledContextMeasure({ now: () => clock });
|
|
179
|
+
let calls = 0;
|
|
180
|
+
const sample = (value: MeasuredContext | undefined) => measure("session-a", () => { calls++; return value; });
|
|
181
|
+
assert.deepEqual(sample({ tokens: 10_000 }), { tokens: 10_000 }, "the first sample of a session measures immediately");
|
|
182
|
+
assert.equal(calls, 1);
|
|
183
|
+
clock = 2_000;
|
|
184
|
+
sample({ tokens: 10_000 });
|
|
185
|
+
assert.equal(calls, 1, "a sample inside the window skips the measurement");
|
|
186
|
+
clock = 6_001;
|
|
187
|
+
sample({ tokens: 10_000 });
|
|
188
|
+
assert.equal(calls, 2, "the window expired: measure again");
|
|
189
|
+
clock = 6_002;
|
|
190
|
+
sample({ tokens: 10_000 });
|
|
191
|
+
assert.equal(calls, 2, "the window restarts at every measurement");
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
test("the throttled measure is per session and a throwing measure never poisons the window", () => {
|
|
195
|
+
let clock = 0;
|
|
196
|
+
const measure = createThrottledContextMeasure({ now: () => clock });
|
|
197
|
+
assert.ok(measure("session-a", () => ({ tokens: 1 })), "session a measures");
|
|
198
|
+
assert.ok(measure("session-b", () => ({ tokens: 2 })), "session b inside the same window still measures");
|
|
199
|
+
assert.equal(measure("session-a", () => ({ tokens: 3 })), undefined, "session a inside its own window skips");
|
|
200
|
+
clock = 5_001;
|
|
201
|
+
let boom = false;
|
|
202
|
+
assert.equal(measure("session-a", () => { boom = true; throw new Error("boom"); }), undefined, "a throwing measure returns undefined");
|
|
203
|
+
assert.equal(boom, true, "the measure itself actually ran");
|
|
204
|
+
assert.equal(measure("session-a", () => ({ tokens: 4 }))?.tokens, undefined, "the failed measurement still consumed its window");
|
|
205
|
+
clock = 10_002;
|
|
206
|
+
assert.equal(measure("session-a", () => ({ tokens: 4 }))?.tokens, 4, "the next window measures again");
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
test("the extension samples the backstop context at most once per window per session", async (t) => {
|
|
210
|
+
let clock = 0;
|
|
211
|
+
const s = session(t, false, { now: () => clock });
|
|
212
|
+
assert.equal(s.measureCount(), 0);
|
|
213
|
+
await s.read();
|
|
214
|
+
assert.equal(s.measureCount(), 1, "the first tool result measures immediately");
|
|
215
|
+
await s.read();
|
|
216
|
+
await s.read();
|
|
217
|
+
assert.equal(s.measureCount(), 1, "tool results inside the window skip the measurement");
|
|
218
|
+
clock = 5_001;
|
|
219
|
+
s.setTokens(160_000);
|
|
220
|
+
const crossed = await s.read();
|
|
221
|
+
assert.equal(s.measureCount(), 2, "the window expired: measure again");
|
|
222
|
+
assert.match(crossed?.content?.[1]?.text ?? "", /Context backstop/, "a crossing is announced on the next sampled result");
|
|
223
|
+
await s.read();
|
|
224
|
+
assert.equal(s.measureCount(), 2, "and the window restarts after that sample");
|
|
225
|
+
});
|
|
@@ -244,9 +244,10 @@ test("T11/S4: the parent hands verify the whole spec, authorizes its probes and
|
|
|
244
244
|
// names every line that admits it. The pin still guards against accidental drift.
|
|
245
245
|
test("AC4/S4: the normative verification rule text is unchanged by the review protocol", () => {
|
|
246
246
|
const normative = sectionFrom(verification, "## Verification rule (normative)");
|
|
247
|
+
// Re-pinned on purpose: the runtime admission now also accepts a `Risk: item N` sentence (verifier-admission.ts).
|
|
247
248
|
assert.equal(
|
|
248
249
|
createHash("sha256").update(normative).digest("hex"),
|
|
249
|
-
"
|
|
250
|
+
"f052518b2905e4560d629397876057079aa71b45352272646261a611fb4a1e17",
|
|
250
251
|
"the normative Verification rule section changed",
|
|
251
252
|
);
|
|
252
253
|
assert.ok(verification.includes("or a delegated writer returns"), "the module must still load when a delegated writer returns");
|