gentle-pi 3.7.0 → 4.0.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 +37 -6
- package/assets/agents/gentle-ai-explore.md +4 -4
- package/assets/agents/gentle-ai-verify.md +6 -4
- package/assets/agents/gentle-ai-worker.md +7 -9
- package/assets/orchestrator-delegation.md +40 -41
- package/assets/orchestrator-memory.md +1 -22
- package/assets/orchestrator-skills.md +1 -1
- package/assets/orchestrator.md +12 -24
- package/assets/support/strict-tdd-verify.md +4 -266
- package/assets/support/strict-tdd.md +8 -360
- package/bin/gentle-shell.mjs +254 -29
- package/docs/delegated-verification.md +26 -1
- package/docs/gentle-agents-activity.md +24 -0
- package/docs/gentle-shell.md +92 -28
- package/docs/native-authority-architecture.md +2 -2
- package/docs/prompt-history.md +280 -0
- package/docs/readme-reference.md +112 -206
- package/docs/telemetry.md +1 -1
- package/docs/yolo-mode.md +86 -0
- package/extensions/child-context.ts +26 -0
- package/extensions/child-safety.ts +23 -0
- package/extensions/gentle-agents.ts +429 -262
- package/extensions/gentle-ai.ts +781 -683
- package/extensions/gentle-shell.ts +1375 -88
- package/extensions/gentle-stats.ts +101 -0
- package/extensions/gentle-todo.ts +18 -7
- package/extensions/history/atomic-write.ts +38 -0
- package/extensions/history/hide-prompts.ts +183 -0
- package/extensions/history/index.ts +1419 -0
- package/extensions/history/load-shared-history.ts +39 -0
- package/extensions/history/selector-helpers.ts +538 -0
- package/extensions/history/session-scan.ts +233 -0
- package/extensions/history/store.ts +1119 -0
- package/extensions/nan-provider.ts +6 -0
- package/extensions/quiet-tools.ts +179 -87
- package/extensions/resume-hint.ts +60 -0
- package/extensions/skill-registry.ts +16 -12
- package/extensions/startup-banner.ts +60 -31
- package/lib/agent-assets.ts +604 -0
- package/lib/agent-profile-pin.ts +12 -0
- package/lib/agents-message-delivery.ts +181 -0
- package/lib/agents-protocol.ts +60 -0
- package/lib/agents-runner.ts +96 -98
- package/lib/agents-view.ts +26 -3
- package/lib/agents-widget.ts +16 -9
- package/lib/append-system-prompt.ts +21 -0
- package/lib/bounded-writer-admission.ts +147 -0
- package/lib/card-style-policy.ts +60 -0
- package/lib/child-context-files.ts +166 -0
- package/lib/codemode-renderer.ts +185 -0
- package/lib/command-palette-catalog.ts +3 -9
- package/lib/command-palette.ts +25 -14
- package/lib/destructive-command-guard.ts +144 -0
- package/lib/gentle-ai-elapsed-store.ts +87 -0
- package/lib/gentle-ai-renderer.ts +196 -39
- package/lib/gentle-shell-launcher.ts +24 -13
- package/lib/gentle-shell-resume-hint.ts +176 -0
- package/lib/history-capture-policy.ts +95 -0
- package/lib/model-routing-authority.ts +5 -1
- package/lib/nan-provider.ts +227 -0
- package/lib/native-review-cli.ts +49 -108
- package/lib/odd-phase-inference.ts +231 -0
- package/lib/odd-phase.ts +141 -0
- package/lib/overlay-repaint.ts +26 -0
- package/lib/pi-tui-keys.ts +53 -0
- package/lib/review-candidate-view-owner.ts +67 -17
- package/lib/review-candidate-view.ts +112 -25
- package/lib/review-reminder-receipt.ts +48 -8
- package/lib/review-risk-assessment.ts +156 -11
- package/lib/review-sidebar-state.ts +223 -0
- package/lib/selection-engine.ts +515 -0
- package/lib/session-messaging-grants.ts +135 -0
- package/lib/session-worktree-registry.ts +14 -2
- package/lib/shell-bar.ts +179 -24
- package/lib/shell-card.ts +287 -18
- package/lib/shell-changes-view.ts +2 -1
- package/lib/shell-prompt.ts +102 -6
- package/lib/shell-sidebar-layout.ts +78 -14
- package/lib/shell-sidebar.ts +15 -1
- package/lib/shell-todo.ts +23 -13
- package/lib/shell-usage-view.ts +9 -4
- package/lib/shell-usage.ts +66 -10
- package/lib/stats-collector.ts +381 -0
- package/lib/stats-view.ts +431 -0
- package/lib/theme-customization.ts +52 -0
- package/lib/vim-editor-adapter.ts +379 -0
- package/lib/vim-normal-engine.ts +154 -0
- package/lib/vim-operator-engine.ts +416 -0
- package/lib/vim-policy.ts +49 -0
- package/lib/vim-visual-engine.ts +107 -0
- package/lib/visual-customization-policy.ts +108 -0
- package/lib/visual-customize-view.ts +330 -0
- package/lib/visual-profiles.ts +228 -0
- package/lib/yolo-session-policy.ts +240 -0
- package/package.json +20 -8
- package/runtime/gentle-shell-launcher.mjs +23 -12
- package/runtime/gentle-shell-resume-hint.mjs +177 -0
- package/runtime/native-review-cli.mjs +49 -108
- package/runtime/review-risk-assessment.mjs +154 -9
- package/scripts/build-runtime-modules.mjs +1 -0
- package/scripts/gentle-ai-installer.mjs +14 -13
- package/scripts/mirror-odd-routing.mjs +2 -2
- package/scripts/run-test-suite.mjs +76 -0
- package/scripts/test-packed-runner.mjs +31 -14
- package/scripts/verify-package-files.mjs +11 -22
- package/skills/branch-pr/SKILL.md +24 -52
- package/skills/chained-pr/SKILL.md +31 -15
- package/skills/chained-pr/references/chaining-details.md +31 -20
- package/skills/gentle-ai/SKILL.md +9 -15
- package/skills/issue-creation/SKILL.md +8 -2
- package/skills/issue-creation/references/delegated-workflow-actions.md +19 -0
- package/skills/work-unit-commits/SKILL.md +4 -3
- package/tests/agent-profiles.test.ts +18 -0
- package/tests/agents-fake-child.ts +2 -2
- package/tests/agents-message-delivery.test.ts +106 -0
- package/tests/agents-protocol.test.ts +40 -0
- package/tests/agents-runner.test.ts +378 -89
- package/tests/agents-view-thread-identity.test.ts +169 -0
- package/tests/agents-view.test.ts +8 -2
- package/tests/agents-widget.test.ts +154 -15
- package/tests/append-system-prompt-route.test.ts +160 -0
- package/tests/append-system-prompt.test.ts +46 -0
- package/tests/artifact-language.test.ts +19 -213
- package/tests/ask-user-question.test.ts +44 -1
- package/tests/asset-installation-runtime.test.ts +5 -16
- package/tests/autonomous-guard.test.ts +69 -1
- package/tests/bounded-writer-admission.test.ts +95 -0
- package/tests/branch-pr-skill.test.ts +43 -0
- package/tests/card-style-policy.test.ts +55 -0
- package/tests/chained-pr-skill.test.ts +124 -0
- package/tests/child-context-files.test.ts +255 -0
- package/tests/child-safety.test.ts +82 -0
- package/tests/codemode-rendering.test.ts +491 -0
- package/tests/command-palette.test.ts +39 -3
- package/tests/delegated-key-learnings-contract.test.ts +0 -76
- package/tests/destructive-command-guard.test.ts +84 -0
- package/tests/devbinary/native-review-parity.devtest.ts +170 -2
- package/tests/devbinary/non-git-subagent-bootstrap.devtest.ts +193 -0
- package/tests/fixtures/stats/sessions/--work-alpha--/2026-09-28T10-00-00-000Z_aaa.jsonl +7 -0
- package/tests/fixtures/stats/sessions/--work-alpha--/2026-09-29T23-00-00-000Z_bbb.jsonl +3 -0
- package/tests/fixtures/stats/sessions/--work-alpha--/2026-09-30T08-00-00-000Z_ddd.jsonl +2 -0
- package/tests/fixtures/stats/sessions/--work-alpha--/2026-09-30T09-00-00-000Z_eee.jsonl +3 -0
- package/tests/fixtures/stats/sessions/--work-alpha--/run-1/session.jsonl +2 -0
- package/tests/fixtures/stats/sessions/--work-beta--/2026-09-01T12-00-00-000Z_ccc.jsonl +2 -0
- package/tests/fixtures/stats/user-pi/sessions/--work-alpha--/2026-09-28T10-00-00-000Z_aaa.jsonl +2 -0
- package/tests/fixtures/stats/user-pi/sessions/--work-alpha--/2026-09-29T23-00-00-000Z_bbb.jsonl +4 -0
- package/tests/fixtures/stats/user-pi/sessions/--work-gamma--/2026-09-20T09-00-00-000Z_fff.jsonl +3 -0
- package/tests/generic-agent-tools.test.ts +54 -0
- package/tests/gentle-agents.test.ts +1047 -252
- package/tests/gentle-ai-binary.test.ts +3 -3
- package/tests/gentle-ai-elapsed-store.test.ts +68 -0
- package/tests/gentle-ai-installer.test.ts +68 -54
- package/tests/gentle-ai-renderer.test.ts +487 -8
- package/tests/gentle-ai.test.ts +288 -65
- package/tests/gentle-card-text.ts +2 -1
- package/tests/gentle-shell-bin.test.ts +651 -114
- package/tests/gentle-shell-launcher.test.ts +99 -52
- package/tests/gentle-shell-resume-hint.test.ts +270 -0
- package/tests/gentle-shell.test.ts +3839 -187
- package/tests/gentle-stats.test.ts +152 -0
- package/tests/gentle-theme.test.ts +4 -1
- package/tests/gentle-todo.test.ts +80 -8
- package/tests/history-atomic-write.test.ts +57 -0
- package/tests/history-capture-policy.test.ts +102 -0
- package/tests/history-command-registration.test.ts +164 -0
- package/tests/history-dedupe-entries.test.ts +123 -0
- package/tests/history-delete-backfill.test.ts +190 -0
- package/tests/history-delete-confirm.test.ts +460 -0
- package/tests/history-dispatch.test.ts +180 -0
- package/tests/history-drain-hidden.test.ts +110 -0
- package/tests/history-drain-order.test.ts +98 -0
- package/tests/history-expanded-globals.test.ts +62 -0
- package/tests/history-gc.test.ts +832 -0
- package/tests/history-header-layout.test.ts +265 -0
- package/tests/history-hide-prompts.test.ts +275 -0
- package/tests/history-lazy-windowing.test.ts +508 -0
- package/tests/history-legacy-migrate-v2.test.ts +297 -0
- package/tests/history-load-shared-history.test.ts +53 -0
- package/tests/history-max-results-cap.test.ts +76 -0
- package/tests/history-multi-reader.test.ts +203 -0
- package/tests/history-off-path.test.ts +170 -0
- package/tests/history-openflow-integration.test.ts +173 -0
- package/tests/history-overlay-margin.test.ts +326 -0
- package/tests/history-preview-layout.test.ts +93 -0
- package/tests/history-registry.test.ts +143 -0
- package/tests/history-scope-delete.test.ts +411 -0
- package/tests/history-search-caret-keys.test.ts +142 -0
- package/tests/history-seed-bootstrap.test.ts +170 -0
- package/tests/history-seed-regen.test.ts +129 -0
- package/tests/history-selector-windowing.test.ts +94 -0
- package/tests/history-session-scan-directory.test.ts +87 -0
- package/tests/history-session-scan-extract.test.ts +583 -0
- package/tests/history-session-writer.test.ts +351 -0
- package/tests/history-store-paths.test.ts +79 -0
- package/tests/history-tombstone-exact.test.ts +139 -0
- package/tests/history-wheel-mouse.test.ts +242 -0
- package/tests/inprocess-reviewer.test.ts +29 -19
- package/tests/issue-creation-skill.test.ts +61 -0
- package/tests/model-routing-authority.test.ts +16 -0
- package/tests/nan-provider.test.ts +471 -0
- package/tests/native-review-capability-contract.test.ts +7 -1
- package/tests/native-review-cli.test.ts +6 -120
- package/tests/native-review-parity-runtime.test.ts +100 -3
- package/tests/odd-integration.test.ts +67 -0
- package/tests/odd-phase-inference.test.ts +213 -0
- package/tests/odd-phase-loader.test.ts +253 -0
- package/tests/odd-phase.test.ts +307 -0
- package/tests/odd-routing-canonical-ratchet.test.ts +11 -6
- package/tests/odd-routing-contract.test.ts +86 -35
- package/tests/orchestrator-budget.test.ts +14 -39
- package/tests/orchestrator-rdd-ownership.test.ts +3 -3
- package/tests/overlay-repaint.test.ts +74 -0
- package/tests/package-manifest.test.ts +252 -115
- package/tests/packed-runner-owned-path.test.ts +46 -0
- package/tests/persona-single-channel.test.ts +6 -6
- package/tests/provider-defect-handoff.test.ts +3 -11
- package/tests/quiet-bash-runtime.test.ts +76 -0
- package/tests/quiet-tool-rendering.test.ts +409 -184
- package/tests/rdd-aware-verification-contract.test.ts +76 -1
- package/tests/rdd-status-line.test.ts +9 -4
- package/tests/resume-hint-extension.test.ts +122 -0
- package/tests/review-agent-end-preflight.test.ts +176 -12
- package/tests/review-candidate-owner-retry.test.ts +22 -1
- package/tests/review-candidate-view.test.ts +298 -0
- package/tests/review-contract-prompt.test.ts +108 -43
- package/tests/review-controller-lock-status.test.ts +0 -1
- package/tests/review-controller-native-routing.test.ts +611 -5
- package/tests/review-controller-workspace-root.test.ts +163 -4
- package/tests/review-host-relay-routing.test.ts +338 -2
- package/tests/review-integration-v2-forward.test.ts +200 -0
- package/tests/review-ledger-contract.test.ts +10 -34
- package/tests/review-reminder-receipt.test.ts +47 -1
- package/tests/review-risk-assessment.test.ts +498 -6
- package/tests/review-sidebar-state.test.ts +402 -0
- package/tests/run-test-suite.test.ts +124 -0
- package/tests/runtime-harness.mjs +145 -786
- package/tests/runtime-metrics-children.test.ts +16 -23
- package/tests/selection-engine.test.ts +421 -0
- package/tests/session-messaging-grants.test.ts +255 -0
- package/tests/session-worktree-registry.test.ts +77 -0
- package/tests/shell-bar.test.ts +382 -1
- package/tests/shell-card.test.ts +353 -1
- package/tests/shell-changes-view.test.ts +52 -0
- package/tests/shell-prompt.test.ts +94 -2
- package/tests/shell-sidebar-layout.test.ts +325 -21
- package/tests/shell-sidebar-scroll-benchmark.test.ts +255 -0
- package/tests/shell-todo.test.ts +87 -1
- package/tests/shell-usage-view.test.ts +27 -0
- package/tests/shell-usage.test.ts +73 -0
- package/tests/skill-registry.test.ts +50 -1
- package/tests/startup-banner.test.ts +130 -2
- package/tests/stats-collector.test.ts +195 -0
- package/tests/stats-view.test.ts +202 -0
- package/tests/telemetry-trigger.test.ts +81 -20
- package/tests/theme-customization.test.ts +72 -0
- package/tests/vim-editor-adapter-host-resolution.test.ts +37 -0
- package/tests/vim-editor-adapter.test.ts +804 -0
- package/tests/vim-normal-engine.test.ts +101 -0
- package/tests/vim-operator-engine.test.ts +215 -0
- package/tests/vim-policy.test.ts +19 -0
- package/tests/vim-visual-engine.test.ts +52 -0
- package/tests/visual-customization-policy.test.ts +110 -0
- package/tests/visual-customize-view.test.ts +418 -0
- package/tests/visual-profiles.test.ts +87 -0
- package/tests/yolo-customize.test.ts +256 -0
- package/tests/yolo-mode-runtime.test.ts +161 -0
- package/tests/yolo-mode.test.ts +261 -0
- package/tests/yolo-session-policy.test.ts +59 -0
- package/themes/Gentle.json +2 -1
- package/themes/Gentleman-Cute.json +2 -1
- package/themes/Gentleman-Sexy.json +2 -1
- package/assets/agents/sdd-apply.md +0 -159
- package/assets/agents/sdd-archive.md +0 -228
- package/assets/agents/sdd-design.md +0 -49
- package/assets/agents/sdd-explore.md +0 -48
- package/assets/agents/sdd-init.md +0 -56
- package/assets/agents/sdd-onboard.md +0 -52
- package/assets/agents/sdd-proposal.md +0 -64
- package/assets/agents/sdd-remediate.md +0 -37
- package/assets/agents/sdd-research.md +0 -49
- package/assets/agents/sdd-spec.md +0 -192
- package/assets/agents/sdd-status.md +0 -54
- package/assets/agents/sdd-tasks.md +0 -108
- package/assets/agents/sdd-verify.md +0 -124
- package/assets/chains/sdd-full.chain.md +0 -83
- package/assets/chains/sdd-plan.chain.md +0 -56
- package/assets/chains/sdd-verify.chain.md +0 -43
- package/assets/sdd-orchestrator-workflow.md +0 -319
- package/assets/support/sdd-status-contract.md +0 -77
- package/docs/assets/diagrams/sdd-cycle.svg +0 -14
- package/extensions/sdd-init.ts +0 -816
- package/lib/openspec-deltas.ts +0 -156
- package/lib/sdd-preflight.ts +0 -1066
- package/lib/sdd-research-capabilities.ts +0 -94
- package/lib/sdd-status.ts +0 -26
- package/tests/fixtures/legacy/sdd-research-v2.5.0.md +0 -54
- package/tests/fixtures/native-review-cli/v2.1.3/bind-sdd.json +0 -25
- package/tests/fixtures/v0.10.7/assets/agents/sdd-apply.md +0 -132
- package/tests/openspec-deltas.test.ts +0 -209
- package/tests/sdd-agent-tools.test.ts +0 -156
- package/tests/sdd-archive-replay.test.ts +0 -82
- package/tests/sdd-classical-continuation.test.ts +0 -74
- package/tests/sdd-execution-routing-contract.test.ts +0 -44
- package/tests/sdd-managed-runtime-settlement.test.ts +0 -155
- package/tests/sdd-native-managed-uptake.test.ts +0 -243
- package/tests/sdd-no-attempts-contract.test.ts +0 -15
- package/tests/sdd-odd-integration.test.ts +0 -33
- package/tests/sdd-optional-research.test.ts +0 -124
- package/tests/sdd-planning-routing-contract.test.ts +0 -45
- package/tests/sdd-preflight-rpc-input.test.ts +0 -125
- package/tests/sdd-preflight.test.ts +0 -541
- package/tests/sdd-research-capabilities.test.ts +0 -114
- package/tests/sdd-research-live.test.ts +0 -241
- package/tests/sdd-selection-transport.test.ts +0 -653
- package/tests/sdd-status.test.ts +0 -9
- package/tests/sdd-task-truth.test.ts +0 -43
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { mkdtempSync, mkdirSync, realpathSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import test from "node:test";
|
|
6
|
+
import { resolveInstalledJitiStaticEntry } from "../scripts/test-packed-runner.mjs";
|
|
7
|
+
|
|
8
|
+
function withAliasedConsumer(run: (consumer: string, sdkManifest: string, jitiRoot: string) => void): void {
|
|
9
|
+
const disposable = mkdtempSync(join(tmpdir(), "packed-owned-path-"));
|
|
10
|
+
try {
|
|
11
|
+
const actual = join(disposable, "actual");
|
|
12
|
+
const consumer = join(disposable, "alias", "consumer");
|
|
13
|
+
const actualConsumer = join(actual, "consumer");
|
|
14
|
+
const sdkRoot = join(actualConsumer, "node_modules", "@earendil-works", "pi-coding-agent");
|
|
15
|
+
const jitiRoot = join(actualConsumer, "node_modules", "jiti");
|
|
16
|
+
mkdirSync(sdkRoot, { recursive: true });
|
|
17
|
+
mkdirSync(join(jitiRoot, "dist"), { recursive: true });
|
|
18
|
+
symlinkSync(actual, join(disposable, "alias"), "dir");
|
|
19
|
+
writeFileSync(join(sdkRoot, "package.json"), JSON.stringify({ name: "@earendil-works/pi-coding-agent", version: "0.87.1", dependencies: { jiti: "2.7.0" } }));
|
|
20
|
+
writeFileSync(join(jitiRoot, "package.json"), JSON.stringify({ name: "jiti", version: "2.7.0", exports: { "./static": { types: "./dist/jiti.d.ts", import: "./dist/jiti.mjs" }, "./package.json": "./package.json" } }));
|
|
21
|
+
run(consumer, join(consumer, "node_modules", "@earendil-works", "pi-coding-agent", "package.json"), jitiRoot);
|
|
22
|
+
} finally {
|
|
23
|
+
rmSync(disposable, { recursive: true, force: true });
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const checks = { sdkManifest: "sdk-manifest", sdkVersion: "sdk-version", jitiManifest: "jiti-manifest-owned", jitiStaticExport: "jiti-static-export", jitiEntry: "jiti-entry-owned", jitiVersion: "jiti-version" };
|
|
28
|
+
|
|
29
|
+
test("accepts a canonical Jiti manifest beneath an aliased ancestor", () => {
|
|
30
|
+
withAliasedConsumer((consumer, sdkManifest, jitiRoot) => {
|
|
31
|
+
writeFileSync(join(jitiRoot, "dist", "jiti.mjs"), "export const createJiti = () => {};\n");
|
|
32
|
+
const seen: string[] = [];
|
|
33
|
+
const entry = resolveInstalledJitiStaticEntry(consumer, sdkManifest, "0.87.1", (check: string) => seen.push(check), checks);
|
|
34
|
+
assert.equal(entry, join(consumer, "node_modules", "jiti", "dist", "jiti.mjs"));
|
|
35
|
+
assert.equal(realpathSync.native(entry), join(realpathSync.native(jitiRoot), "dist", "jiti.mjs"));
|
|
36
|
+
assert.ok(seen.includes("jiti-manifest-owned"));
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test("rejects a symlink within the owned Jiti static entry", () => {
|
|
41
|
+
withAliasedConsumer((consumer, sdkManifest, jitiRoot) => {
|
|
42
|
+
writeFileSync(join(jitiRoot, "dist", "real.mjs"), "export const createJiti = () => {};\n");
|
|
43
|
+
symlinkSync("real.mjs", join(jitiRoot, "dist", "jiti.mjs"));
|
|
44
|
+
assert.throws(() => resolveInstalledJitiStaticEntry(consumer, sdkManifest, "0.87.1", () => {}, checks), /refusing symbolic link in owned package/);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
@@ -262,7 +262,7 @@ test("Table A rule: wrapper :180/:181 + orchestrator :9,:12 self-description MER
|
|
|
262
262
|
);
|
|
263
263
|
assert.match(
|
|
264
264
|
prompt,
|
|
265
|
-
/I am el Gentleman: a Pi-specific coding-agent harness for controlled development, with a senior architect persona\. I run Organic Driven Development
|
|
265
|
+
/I am el Gentleman: a Pi-specific coding-agent harness for controlled development, with a senior architect persona\. I run Organic Driven Development, coordinate subagents, track substantial work, run commands, and edit files\. I am not a generic chatbot\./,
|
|
266
266
|
`[${persona}] the richer translated self-description paragraph (orchestrator :9,:12) must survive in the wrapper`,
|
|
267
267
|
);
|
|
268
268
|
}
|
|
@@ -290,12 +290,12 @@ test("Table A rule: persona-mode selection (trimmed) survives; language clause N
|
|
|
290
290
|
}
|
|
291
291
|
});
|
|
292
292
|
|
|
293
|
-
test("Table A rule:
|
|
293
|
+
test("Table A rule: ODD and subagents core-capabilities bullet survives (KEEP once)", () => {
|
|
294
294
|
for (const persona of ["gentleman", "neutral"] as const) {
|
|
295
295
|
const prompt = __testing.buildGentlePrompt(persona);
|
|
296
296
|
assert.match(
|
|
297
297
|
prompt,
|
|
298
|
-
/Mention ODD as the
|
|
298
|
+
/Mention ODD as the development workflow and subagents as a core capability\./,
|
|
299
299
|
`[${persona}] wrapper :182 rule must survive`,
|
|
300
300
|
);
|
|
301
301
|
}
|
|
@@ -385,10 +385,10 @@ test("Table B rule: LB5 exceptions kept verbatim in orchestrator (unique)", () =
|
|
|
385
385
|
/Ask a subagent to produce Spanish only when its output is intended to be pasted directly to the user/,
|
|
386
386
|
`[${persona}] LB5 exceptions bullet 2 must remain verbatim`,
|
|
387
387
|
);
|
|
388
|
-
assert.
|
|
388
|
+
assert.doesNotMatch(
|
|
389
389
|
prompt,
|
|
390
390
|
/SDD\/OpenSpec artifact content may follow the project's established language/,
|
|
391
|
-
`[${persona}]
|
|
391
|
+
`[${persona}] retired artifact exception must be absent`,
|
|
392
392
|
);
|
|
393
393
|
}
|
|
394
394
|
});
|
|
@@ -439,7 +439,7 @@ test("dup guard (exact-string): 'Do not claim portability outside the Pi runtime
|
|
|
439
439
|
|
|
440
440
|
test("dup guard (exact-string): identity self-description sentence occurs exactly once", () => {
|
|
441
441
|
const selfDescription =
|
|
442
|
-
"I am el Gentleman: a Pi-specific coding-agent harness for controlled development, with a senior architect persona. I run Organic Driven Development
|
|
442
|
+
"I am el Gentleman: a Pi-specific coding-agent harness for controlled development, with a senior architect persona. I run Organic Driven Development, coordinate subagents, track substantial work, run commands, and edit files. I am not a generic chatbot.";
|
|
443
443
|
for (const persona of ["gentleman", "neutral"] as const) {
|
|
444
444
|
const prompt = __testing.buildGentlePrompt(persona);
|
|
445
445
|
assert.equal(
|
|
@@ -17,10 +17,7 @@ import test from "node:test";
|
|
|
17
17
|
|
|
18
18
|
const REPO_ROOT = join(import.meta.dirname, "..");
|
|
19
19
|
const DELEGATION_PATH = join(REPO_ROOT, "assets", "orchestrator-delegation.md");
|
|
20
|
-
const SDD_WORKFLOW_PATH = join(REPO_ROOT, "assets", "sdd-orchestrator-workflow.md");
|
|
21
|
-
|
|
22
20
|
const DELEGATION = readFileSync(DELEGATION_PATH, "utf8");
|
|
23
|
-
const SDD_WORKFLOW = readFileSync(SDD_WORKFLOW_PATH, "utf8");
|
|
24
21
|
|
|
25
22
|
const CHOICE_TOKENS = ["report_and_continue", "continue_without_reporting", "stop_here"] as const;
|
|
26
23
|
|
|
@@ -230,17 +227,12 @@ test("orchestrator-delegation.md does NOT reference the rc.3 canon", () => {
|
|
|
230
227
|
});
|
|
231
228
|
|
|
232
229
|
// ---------------------------------------------------------------------------
|
|
233
|
-
// 3 —
|
|
230
|
+
// 3 — The retained delegation contract owns the complete handoff
|
|
234
231
|
// ---------------------------------------------------------------------------
|
|
235
232
|
|
|
236
|
-
test("
|
|
237
|
-
assert.match(SDD_WORKFLOW, /## Provider Defect Handoff/);
|
|
238
|
-
assert.match(
|
|
239
|
-
SDD_WORKFLOW,
|
|
240
|
-
/The full contract lives in `assets\/orchestrator-delegation\.md` under `#### Gentle AI Provider Defect Handoff \(MANDATORY\)`/i,
|
|
241
|
-
);
|
|
233
|
+
test("retained delegation owns the complete provider defect handoff", () => {
|
|
242
234
|
assert.match(DELEGATION, /^#### Gentle AI Provider Defect Handoff \(MANDATORY\)$/m);
|
|
243
|
-
assert.
|
|
235
|
+
assert.match(DELEGATION, /Both continue choices execute that exact captured decline invocation exactly once/);
|
|
244
236
|
});
|
|
245
237
|
|
|
246
238
|
test("the complete delegation handoff invokes `gentle-ai review mode disable` exactly once", () => {
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { spawnSync } from "node:child_process";
|
|
3
|
+
import { existsSync, mkdirSync, mkdtempSync, rmSync } from "node:fs";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import test from "node:test";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
|
|
9
|
+
async function proveNativeBash() {
|
|
10
|
+
const { createAgentSessionFromServices, createAgentSessionRuntime, createAgentSessionServices,
|
|
11
|
+
ModelRuntime, SessionManager, SettingsManager } = await import("@earendil-works/pi-coding-agent");
|
|
12
|
+
const cwd = process.cwd();
|
|
13
|
+
const agentDir = process.env.PI_CODING_AGENT_DIR!;
|
|
14
|
+
const shellPath = process.env.GENTLE_TEST_SHELL!;
|
|
15
|
+
// Hide Windows default discovery only inside this isolated child. The explicit
|
|
16
|
+
// shell remains usable; on POSIX the prefix also detects a recreated executor.
|
|
17
|
+
for (const key of Object.keys(process.env)) if (key.toLowerCase() === "path") process.env[key] = "";
|
|
18
|
+
process.env.ProgramFiles = join(cwd, "absent-git");
|
|
19
|
+
process.env["ProgramFiles(x86)"] = join(cwd, "absent-git-x86");
|
|
20
|
+
const modelRuntime = await ModelRuntime.create({ authPath: join(agentDir, "empty-auth.json"),
|
|
21
|
+
modelsPath: null, modelsStorePath: join(agentDir, "models-store.json"), allowModelNetwork: false });
|
|
22
|
+
for (const quiet of [false, true]) {
|
|
23
|
+
const runtime = await createAgentSessionRuntime(async ({ cwd, sessionManager, sessionStartEvent }) => {
|
|
24
|
+
const services = await createAgentSessionServices({ cwd, agentDir, modelRuntime,
|
|
25
|
+
settingsManager: SettingsManager.inMemory({ shellPath, shellCommandPrefix: "printf configured-prefix;",
|
|
26
|
+
retry: { enabled: false }, compaction: { enabled: false } }),
|
|
27
|
+
resourceLoaderOptions: { noExtensions: true, noSkills: true, noPromptTemplates: true,
|
|
28
|
+
noThemes: true, noContextFiles: true,
|
|
29
|
+
additionalExtensionPaths: quiet ? [fileURLToPath(new URL("../extensions/quiet-tools.ts", import.meta.url))] : [] },
|
|
30
|
+
});
|
|
31
|
+
assert.deepEqual(services.resourceLoader.getExtensions().errors, []);
|
|
32
|
+
return { ...(await createAgentSessionFromServices({ services, sessionManager, sessionStartEvent, tools: ["bash"] })),
|
|
33
|
+
services, diagnostics: services.diagnostics };
|
|
34
|
+
}, { cwd, agentDir, sessionManager: SessionManager.inMemory(cwd) });
|
|
35
|
+
try {
|
|
36
|
+
await runtime.session.bindExtensions({ mode: "print" });
|
|
37
|
+
const bash = runtime.session.agent.state.tools.find(tool => tool.name === "bash");
|
|
38
|
+
assert.ok(bash);
|
|
39
|
+
const result = await bash.execute("configured-shell", { command: "printf native-ok" }, new AbortController().signal);
|
|
40
|
+
assert.equal(result.content.filter(part => part.type === "text").map(part => part.text).join("\n"),
|
|
41
|
+
"configured-prefixnative-ok", `quiet=${quiet}: native effective shell settings must survive`);
|
|
42
|
+
assert.equal(runtime.session.messages.length, 0);
|
|
43
|
+
console.log(`native Bash configured settings: quiet=${quiet} passed`);
|
|
44
|
+
} finally { await runtime.dispose(); }
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (process.env.GENTLE_TEST_BASH_CHILD === "1") {
|
|
49
|
+
await proveNativeBash();
|
|
50
|
+
} else {
|
|
51
|
+
test("quiet tools preserve actual SDK configured Bash execution (#107)", (t) => {
|
|
52
|
+
const candidates = process.platform === "win32"
|
|
53
|
+
? [join(process.env.ProgramFiles ?? "C:\\Program Files", "Git", "bin", "bash.exe"), "C:\\Program Files\\Git\\usr\\bin\\bash.exe"]
|
|
54
|
+
: ["/bin/bash", "/usr/bin/bash"];
|
|
55
|
+
const shell = candidates.find(existsSync);
|
|
56
|
+
if (!shell) { t.skip("requires an installed Bash; no binary installation is performed"); return; }
|
|
57
|
+
const root = mkdtempSync(join(tmpdir(), "gentle-quiet-bash-sdk-"));
|
|
58
|
+
const cwd = join(root, "project");
|
|
59
|
+
const home = join(root, "home");
|
|
60
|
+
const agentDir = join(home, "agent");
|
|
61
|
+
for (const path of [cwd, agentDir]) mkdirSync(path, { recursive: true });
|
|
62
|
+
const env = { ...process.env, HOME: home, USERPROFILE: home, XDG_CONFIG_HOME: join(home, "config"),
|
|
63
|
+
PI_CODING_AGENT_DIR: agentDir, GENTLE_PI_AGENT_HOME: agentDir, GENTLE_PI_CONFIG_HOME: join(home, "gentle-config"),
|
|
64
|
+
PI_OFFLINE: "1", GENTLE_PI_QUIET_TOOLS: "1", GENTLE_TEST_BASH_CHILD: "1", GENTLE_TEST_SHELL: shell };
|
|
65
|
+
try {
|
|
66
|
+
const result = spawnSync(process.execPath, ["--experimental-strip-types", fileURLToPath(import.meta.url)],
|
|
67
|
+
{ cwd, env, encoding: "utf8", timeout: 30_000 });
|
|
68
|
+
assert.ifError(result.error);
|
|
69
|
+
assert.equal(result.status, 0, `${result.stdout}\n${result.stderr}\nfixture: ${root}`);
|
|
70
|
+
assert.match(result.stdout, /quiet=false passed/);
|
|
71
|
+
assert.match(result.stdout, /quiet=true passed/);
|
|
72
|
+
} finally {
|
|
73
|
+
rmSync(root, { recursive: true, force: true });
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
}
|