@zihanw/pi-forge 0.4.1 → 0.5.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/CHANGELOG.md +79 -1
- package/README.md +12 -11
- package/README.zh-CN.md +3 -5
- package/SUBAGENT_ADAPTER_CONTRACT.md +3 -1
- package/dist/agent-profile.d.ts +18 -62
- package/dist/agent-profile.d.ts.map +1 -1
- package/dist/agent-profile.js +27 -249
- package/dist/agent-profile.js.map +1 -1
- package/dist/codecs/agent-profile.d.ts +53 -0
- package/dist/codecs/agent-profile.d.ts.map +1 -0
- package/dist/codecs/agent-profile.js +176 -0
- package/dist/codecs/agent-profile.js.map +1 -0
- package/dist/codecs/index.d.ts +5 -0
- package/dist/codecs/index.d.ts.map +1 -0
- package/dist/codecs/index.js +3 -0
- package/dist/codecs/index.js.map +1 -0
- package/dist/codecs/prompt-stack.d.ts +18 -0
- package/dist/codecs/prompt-stack.d.ts.map +1 -0
- package/dist/codecs/prompt-stack.js +479 -0
- package/dist/codecs/prompt-stack.js.map +1 -0
- package/dist/compile-cycle.d.ts +18 -0
- package/dist/compile-cycle.d.ts.map +1 -0
- package/dist/compile-cycle.js +13 -0
- package/dist/compile-cycle.js.map +1 -0
- package/dist/compiler.d.ts +10 -4
- package/dist/compiler.d.ts.map +1 -1
- package/dist/compiler.js +53 -19
- package/dist/compiler.js.map +1 -1
- package/dist/context-diff-history.d.ts +61 -0
- package/dist/context-diff-history.d.ts.map +1 -0
- package/dist/context-diff-history.js +84 -0
- package/dist/context-diff-history.js.map +1 -0
- package/dist/context-diff-snapshot.d.ts +19 -0
- package/dist/context-diff-snapshot.d.ts.map +1 -0
- package/dist/context-diff-snapshot.js +146 -0
- package/dist/context-diff-snapshot.js.map +1 -0
- package/dist/context-diff.d.ts +70 -0
- package/dist/context-diff.d.ts.map +1 -0
- package/dist/context-diff.js +259 -0
- package/dist/context-diff.js.map +1 -0
- package/dist/extension-registry.d.ts.map +1 -1
- package/dist/extension-registry.js +5 -2
- package/dist/extension-registry.js.map +1 -1
- package/dist/forge-config.d.ts +0 -105
- package/dist/forge-config.d.ts.map +1 -1
- package/dist/forge-config.js +1 -313
- package/dist/forge-config.js.map +1 -1
- package/dist/forge-v1/analyzer.d.ts +3 -0
- package/dist/forge-v1/analyzer.d.ts.map +1 -0
- package/dist/forge-v1/analyzer.js +50 -0
- package/dist/forge-v1/analyzer.js.map +1 -0
- package/dist/forge-v1/index.d.ts +6 -0
- package/dist/forge-v1/index.d.ts.map +1 -0
- package/dist/forge-v1/index.js +13 -0
- package/dist/forge-v1/index.js.map +1 -0
- package/dist/forge-v1/parser.d.ts +3 -0
- package/dist/forge-v1/parser.d.ts.map +1 -0
- package/dist/forge-v1/parser.js +186 -0
- package/dist/forge-v1/parser.js.map +1 -0
- package/dist/forge-v1/renderer.d.ts +9 -0
- package/dist/forge-v1/renderer.d.ts.map +1 -0
- package/dist/forge-v1/renderer.js +181 -0
- package/dist/forge-v1/renderer.js.map +1 -0
- package/dist/forge-v1/types.d.ts +87 -0
- package/dist/forge-v1/types.d.ts.map +1 -0
- package/dist/forge-v1/types.js +4 -0
- package/dist/forge-v1/types.js.map +1 -0
- package/dist/index.d.ts +12 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +54 -83
- package/dist/index.js.map +1 -1
- package/dist/lifecycle.d.ts +8 -5
- package/dist/lifecycle.d.ts.map +1 -1
- package/dist/lifecycle.js +45 -112
- package/dist/lifecycle.js.map +1 -1
- package/dist/loader.d.ts +5 -8
- package/dist/loader.d.ts.map +1 -1
- package/dist/loader.js +10 -467
- package/dist/loader.js.map +1 -1
- package/dist/macro-engine.d.ts +9 -14
- package/dist/macro-engine.d.ts.map +1 -1
- package/dist/macro-engine.js +5 -238
- package/dist/macro-engine.js.map +1 -1
- package/dist/payload-capture.d.ts +10 -0
- package/dist/payload-capture.d.ts.map +1 -1
- package/dist/payload-capture.js +39 -9
- package/dist/payload-capture.js.map +1 -1
- package/dist/payload-command.d.ts +8 -6
- package/dist/payload-command.d.ts.map +1 -1
- package/dist/payload-command.js +36 -6
- package/dist/payload-command.js.map +1 -1
- package/dist/payload-state.d.ts +19 -0
- package/dist/payload-state.d.ts.map +1 -0
- package/dist/payload-state.js +19 -0
- package/dist/payload-state.js.map +1 -0
- package/dist/preset-command.d.ts +4 -4
- package/dist/preset-command.d.ts.map +1 -1
- package/dist/preset-command.js +33 -104
- package/dist/preset-command.js.map +1 -1
- package/dist/preview.d.ts +4 -4
- package/dist/preview.d.ts.map +1 -1
- package/dist/preview.js +34 -11
- package/dist/preview.js.map +1 -1
- package/dist/profile-command.d.ts +2 -2
- package/dist/profile-command.d.ts.map +1 -1
- package/dist/profile-command.js +15 -14
- package/dist/profile-command.js.map +1 -1
- package/dist/profile-service.d.ts.map +1 -1
- package/dist/profile-service.js +23 -39
- package/dist/profile-service.js.map +1 -1
- package/dist/prompt-analysis.d.ts +24 -0
- package/dist/prompt-analysis.d.ts.map +1 -0
- package/dist/prompt-analysis.js +84 -0
- package/dist/prompt-analysis.js.map +1 -0
- package/dist/prompt-runtime.d.ts +19 -0
- package/dist/prompt-runtime.d.ts.map +1 -0
- package/dist/prompt-runtime.js +30 -0
- package/dist/prompt-runtime.js.map +1 -0
- package/dist/regex.js +6 -12
- package/dist/regex.js.map +1 -1
- package/dist/render-helpers.d.ts +2 -10
- package/dist/render-helpers.d.ts.map +1 -1
- package/dist/render-helpers.js +3 -53
- package/dist/render-helpers.js.map +1 -1
- package/dist/repositories/agent-profile.d.ts +36 -0
- package/dist/repositories/agent-profile.d.ts.map +1 -0
- package/dist/repositories/agent-profile.js +153 -0
- package/dist/repositories/agent-profile.js.map +1 -0
- package/dist/repositories/index.d.ts +3 -0
- package/dist/repositories/index.d.ts.map +1 -0
- package/dist/repositories/index.js +3 -0
- package/dist/repositories/index.js.map +1 -0
- package/dist/repositories/prompt-stack.d.ts +57 -0
- package/dist/repositories/prompt-stack.d.ts.map +1 -0
- package/dist/repositories/prompt-stack.js +175 -0
- package/dist/repositories/prompt-stack.js.map +1 -0
- package/dist/runtime/profile-runtime.d.ts +2 -2
- package/dist/runtime/profile-runtime.d.ts.map +1 -1
- package/dist/runtime/profile-runtime.js +13 -10
- package/dist/runtime/profile-runtime.js.map +1 -1
- package/dist/runtime/prompt-stack-runtime.d.ts +4 -3
- package/dist/runtime/prompt-stack-runtime.d.ts.map +1 -1
- package/dist/runtime/prompt-stack-runtime.js +42 -57
- package/dist/runtime/prompt-stack-runtime.js.map +1 -1
- package/dist/runtime/tool-policy-runtime.d.ts +2 -2
- package/dist/runtime/tool-policy-runtime.d.ts.map +1 -1
- package/dist/runtime/tool-policy-runtime.js +16 -6
- package/dist/runtime/tool-policy-runtime.js.map +1 -1
- package/dist/runtime/web-editor-runtime.d.ts +2 -1
- package/dist/runtime/web-editor-runtime.d.ts.map +1 -1
- package/dist/runtime/web-editor-runtime.js +8 -3
- package/dist/runtime/web-editor-runtime.js.map +1 -1
- package/dist/session-adapter.d.ts +17 -0
- package/dist/session-adapter.d.ts.map +1 -0
- package/dist/session-adapter.js +57 -0
- package/dist/session-adapter.js.map +1 -0
- package/dist/slot-renderers.d.ts +16 -3
- package/dist/slot-renderers.d.ts.map +1 -1
- package/dist/slot-renderers.js +15 -63
- package/dist/slot-renderers.js.map +1 -1
- package/dist/stack-migration.d.ts +6 -0
- package/dist/stack-migration.d.ts.map +1 -1
- package/dist/stack-migration.js +49 -52
- package/dist/stack-migration.js.map +1 -1
- package/dist/subagent/fingerprints.d.ts +24 -0
- package/dist/subagent/fingerprints.d.ts.map +1 -0
- package/dist/subagent/fingerprints.js +81 -0
- package/dist/subagent/fingerprints.js.map +1 -0
- package/dist/subagent/host-port.d.ts +296 -0
- package/dist/subagent/host-port.d.ts.map +1 -0
- package/dist/subagent/host-port.js +560 -0
- package/dist/subagent/host-port.js.map +1 -0
- package/dist/subagent/index.d.ts +10 -10
- package/dist/subagent/index.d.ts.map +1 -1
- package/dist/subagent/index.js +9 -10
- package/dist/subagent/index.js.map +1 -1
- package/dist/subagent-host.d.ts +99 -18
- package/dist/subagent-host.d.ts.map +1 -1
- package/dist/subagent-host.js +143 -146
- package/dist/subagent-host.js.map +1 -1
- package/dist/template-render.d.ts +18 -0
- package/dist/template-render.d.ts.map +1 -0
- package/dist/template-render.js +232 -0
- package/dist/template-render.js.map +1 -0
- package/dist/types.d.ts +40 -27
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/ui-contribution/contrib-port.d.ts +170 -0
- package/dist/ui-contribution/contrib-port.d.ts.map +1 -0
- package/dist/ui-contribution/contrib-port.js +640 -0
- package/dist/ui-contribution/contrib-port.js.map +1 -0
- package/dist/ui-contribution/index.d.ts +3 -0
- package/dist/ui-contribution/index.d.ts.map +1 -0
- package/dist/ui-contribution/index.js +2 -0
- package/dist/ui-contribution/index.js.map +1 -0
- package/dist/web-editor/client-script.generated.d.ts.map +1 -1
- package/dist/web-editor/client-script.generated.js +1 -1
- package/dist/web-editor/client-script.generated.js.map +1 -1
- package/dist/web-editor/client-styles.generated.d.ts.map +1 -1
- package/dist/web-editor/client-styles.generated.js +1 -1
- package/dist/web-editor/client-styles.generated.js.map +1 -1
- package/dist/web-editor/contrib-service.d.ts +41 -0
- package/dist/web-editor/contrib-service.d.ts.map +1 -0
- package/dist/web-editor/contrib-service.js +174 -0
- package/dist/web-editor/contrib-service.js.map +1 -0
- package/dist/web-editor/line-diff.d.ts +28 -0
- package/dist/web-editor/line-diff.d.ts.map +1 -0
- package/dist/web-editor/line-diff.js +216 -0
- package/dist/web-editor/line-diff.js.map +1 -0
- package/dist/web-editor/schema-form.d.ts +63 -0
- package/dist/web-editor/schema-form.d.ts.map +1 -0
- package/dist/web-editor/schema-form.js +213 -0
- package/dist/web-editor/schema-form.js.map +1 -0
- package/dist/web-editor/server.d.ts.map +1 -1
- package/dist/web-editor/server.js +72 -74
- package/dist/web-editor/server.js.map +1 -1
- package/dist/web-editor/styles.d.ts.map +1 -1
- package/dist/web-editor/styles.js +201 -21
- package/dist/web-editor/styles.js.map +1 -1
- package/dist/web-editor/types.d.ts +12 -35
- package/dist/web-editor/types.d.ts.map +1 -1
- package/dist/web-host.d.ts +6 -2
- package/dist/web-host.d.ts.map +1 -1
- package/dist/web-host.js +33 -103
- package/dist/web-host.js.map +1 -1
- package/dist/workspace.d.ts +74 -0
- package/dist/workspace.d.ts.map +1 -0
- package/dist/workspace.js +351 -0
- package/dist/workspace.js.map +1 -0
- package/docs/README.md +7 -4
- package/docs/concepts/agent-profiles.md +1 -1
- package/docs/concepts/prompt-stacks.md +5 -5
- package/docs/design/0.5.1-plan.md +237 -0
- package/docs/design/README.md +21 -3
- package/docs/design/architecture-0.5.md +222 -0
- package/docs/design/archive/0.5-full-proposal/0.5-consumer-audit.md +62 -0
- package/docs/design/archive/0.5-full-proposal/0.5-inventory.md +208 -0
- package/docs/design/archive/0.5-full-proposal/0.5-phase0-decision-drafts.md +237 -0
- package/docs/design/archive/0.5-full-proposal/README.md +12 -0
- package/docs/design/archive/0.5-full-proposal/architecture-0.5.md +423 -0
- package/docs/design/archive/0.5-full-proposal/host-discovery-spike.md +103 -0
- package/docs/design/archive/0.5-full-proposal/template-language-spike.md +156 -0
- package/docs/design/context-diff-plan.md +78 -0
- package/docs/design/decision-template.md +33 -0
- package/docs/design/roadmap-0.4-archive.md +1 -1
- package/docs/design/subagents/interface-design.md +1 -1
- package/docs/development/architecture-rules.md +148 -0
- package/docs/development/release.md +7 -1
- package/docs/development/roadmap.md +37 -5
- package/docs/development/scoped-global-profiles-stacks.md +1 -1
- package/docs/development/setup.md +6 -4
- package/docs/getting-started.md +5 -4
- package/docs/guides/custom-macros-and-slots.md +8 -7
- package/docs/guides/debugging.md +1 -1
- package/docs/guides/delegation.md +18 -22
- package/docs/guides/migrating-to-0.5.md +107 -0
- package/docs/guides/use-cases.md +7 -11
- package/docs/guides/web-editor.md +6 -10
- package/docs/reference/commands.md +4 -3
- package/docs/reference/configuration.md +17 -18
- package/docs/reference/features.md +34 -80
- package/docs/reference/macros-and-slots.md +70 -49
- package/docs/reference/public-api.md +76 -17
- package/docs/reference/stack-schema.md +15 -10
- package/docs/reference/subagent-host-port.md +49 -0
- package/docs/reference/ui-contribution-port.md +51 -0
- package/docs/zh-CN/README.md +3 -3
- package/docs/zh-CN/concepts/agent-profiles.md +1 -1
- package/docs/zh-CN/concepts/prompt-stacks.md +5 -5
- package/docs/zh-CN/getting-started.md +3 -2
- package/docs/zh-CN/guides/delegation.md +10 -12
- package/docs/zh-CN/guides/migrating-to-0.5.md +92 -0
- package/docs/zh-CN/guides/web-editor.md +4 -4
- package/docs/zh-CN/reference/commands.md +3 -2
- package/examples/custom-system-status-extension/README.md +3 -3
- package/examples/custom-system-status-extension/index.ts +2 -1
- package/examples/custom-system-status-extension/prompt-stack.json +4 -3
- package/examples/default-prompt-stack.json +9 -4
- package/examples/image-reader-prompt-stack.json +16 -26
- package/examples/reviewer-prompt-stack.json +13 -24
- package/package.json +106 -120
- package/dist/runtime/subagent-runtime.d.ts +0 -45
- package/dist/runtime/subagent-runtime.d.ts.map +0 -1
- package/dist/runtime/subagent-runtime.js +0 -343
- package/dist/runtime/subagent-runtime.js.map +0 -1
- package/dist/runtime-state.d.ts +0 -30
- package/dist/runtime-state.d.ts.map +0 -1
- package/dist/runtime-state.js +0 -17
- package/dist/runtime-state.js.map +0 -1
- package/dist/sillytavern-importer/items.d.ts +0 -3
- package/dist/sillytavern-importer/items.d.ts.map +0 -1
- package/dist/sillytavern-importer/items.js +0 -88
- package/dist/sillytavern-importer/items.js.map +0 -1
- package/dist/sillytavern-importer/macros.d.ts +0 -15
- package/dist/sillytavern-importer/macros.d.ts.map +0 -1
- package/dist/sillytavern-importer/macros.js +0 -141
- package/dist/sillytavern-importer/macros.js.map +0 -1
- package/dist/sillytavern-importer/prompt-order.d.ts +0 -6
- package/dist/sillytavern-importer/prompt-order.d.ts.map +0 -1
- package/dist/sillytavern-importer/prompt-order.js +0 -38
- package/dist/sillytavern-importer/prompt-order.js.map +0 -1
- package/dist/sillytavern-importer/regex.d.ts +0 -3
- package/dist/sillytavern-importer/regex.d.ts.map +0 -1
- package/dist/sillytavern-importer/regex.js +0 -275
- package/dist/sillytavern-importer/regex.js.map +0 -1
- package/dist/sillytavern-importer/report.d.ts +0 -21
- package/dist/sillytavern-importer/report.d.ts.map +0 -1
- package/dist/sillytavern-importer/report.js +0 -166
- package/dist/sillytavern-importer/report.js.map +0 -1
- package/dist/sillytavern-importer/types.d.ts +0 -106
- package/dist/sillytavern-importer/types.d.ts.map +0 -1
- package/dist/sillytavern-importer/types.js +0 -2
- package/dist/sillytavern-importer/types.js.map +0 -1
- package/dist/sillytavern-importer.d.ts +0 -5
- package/dist/sillytavern-importer.d.ts.map +0 -1
- package/dist/sillytavern-importer.js +0 -117
- package/dist/sillytavern-importer.js.map +0 -1
- package/dist/subagent/canonical.d.ts +0 -22
- package/dist/subagent/canonical.d.ts.map +0 -1
- package/dist/subagent/canonical.js +0 -24
- package/dist/subagent/canonical.js.map +0 -1
- package/dist/subagent/context.d.ts +0 -8
- package/dist/subagent/context.d.ts.map +0 -1
- package/dist/subagent/context.js +0 -125
- package/dist/subagent/context.js.map +0 -1
- package/dist/subagent/contract.d.ts +0 -10
- package/dist/subagent/contract.d.ts.map +0 -1
- package/dist/subagent/contract.js +0 -10
- package/dist/subagent/contract.js.map +0 -1
- package/dist/subagent/plan.d.ts +0 -18
- package/dist/subagent/plan.d.ts.map +0 -1
- package/dist/subagent/plan.js +0 -157
- package/dist/subagent/plan.js.map +0 -1
- package/dist/subagent/preflight.d.ts +0 -4
- package/dist/subagent/preflight.d.ts.map +0 -1
- package/dist/subagent/preflight.js +0 -108
- package/dist/subagent/preflight.js.map +0 -1
- package/dist/subagent/request.d.ts +0 -4
- package/dist/subagent/request.d.ts.map +0 -1
- package/dist/subagent/request.js +0 -154
- package/dist/subagent/request.js.map +0 -1
- package/dist/subagent/response.d.ts +0 -8
- package/dist/subagent/response.d.ts.map +0 -1
- package/dist/subagent/response.js +0 -155
- package/dist/subagent/response.js.map +0 -1
- package/dist/subagent/tools.d.ts +0 -4
- package/dist/subagent/tools.d.ts.map +0 -1
- package/dist/subagent/tools.js +0 -42
- package/dist/subagent/tools.js.map +0 -1
- package/dist/subagent/types.d.ts +0 -272
- package/dist/subagent/types.d.ts.map +0 -1
- package/dist/subagent/types.js +0 -3
- package/dist/subagent/types.js.map +0 -1
- package/dist/subagent/validation.d.ts +0 -35
- package/dist/subagent/validation.d.ts.map +0 -1
- package/dist/subagent/validation.js +0 -314
- package/dist/subagent/validation.js.map +0 -1
- package/dist/subagent-command.d.ts +0 -5
- package/dist/subagent-command.d.ts.map +0 -1
- package/dist/subagent-command.js +0 -249
- package/dist/subagent-command.js.map +0 -1
- package/dist/subagent-profile-tool.d.ts +0 -49
- package/dist/subagent-profile-tool.d.ts.map +0 -1
- package/dist/subagent-profile-tool.js +0 -125
- package/dist/subagent-profile-tool.js.map +0 -1
- package/dist/subagent-tool.d.ts +0 -77
- package/dist/subagent-tool.d.ts.map +0 -1
- package/dist/subagent-tool.js +0 -559
- package/dist/subagent-tool.js.map +0 -1
- package/docs/guides/sillytavern-import.md +0 -47
- package/docs/reference/subagent-adapter.md +0 -204
- package/examples/sillytavern-dm-writer-prompt-stack.json +0 -190
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
# pi-forge 0.5.1 — Combined Release Plan
|
|
2
|
+
|
|
3
|
+
Status: active. Target release: 0.5.1 (first feature release after 0.5.0).
|
|
4
|
+
Owner of truth: this document. Supersedes/folds in:
|
|
5
|
+
- `docs/design/context-diff-plan.md` (context diff, now Lane 2)
|
|
6
|
+
- The subagent UI-contribution discussion from the 0.5.x review thread (now Lane 1)
|
|
7
|
+
|
|
8
|
+
Theme: **observability + subagent usability**. 0.5.0 was the architecture-split
|
|
9
|
+
release; 0.5.1 ships per-turn prompt observability and makes the optional
|
|
10
|
+
subagent package configurable without hand-editing JSON.
|
|
11
|
+
|
|
12
|
+
## Lane ordering (deliberate)
|
|
13
|
+
|
|
14
|
+
**Lane 1 ships first.** Its tab-registry refactor turns the web editor's tab
|
|
15
|
+
system data-driven, which Lane 2's Preview dock builds on. Both lanes touch the
|
|
16
|
+
client build pipeline and the tab area — do not run them in parallel in the
|
|
17
|
+
same working tree.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Lane 1 — UI contribution framework + subagent config UI
|
|
22
|
+
|
|
23
|
+
### Goal
|
|
24
|
+
|
|
25
|
+
Let the optional `@zihanw/pi-forge-subagents` package own its configuration UI
|
|
26
|
+
(schema, validation, defaults, file writes) while the rendered settings tab
|
|
27
|
+
appears inside the pi-forge web editor when — and only when — the subagent
|
|
28
|
+
package is installed.
|
|
29
|
+
|
|
30
|
+
Non-goal: arbitrary JS/component injection into the forge web UI. The event bus
|
|
31
|
+
carries JSON only; that rule does not bend for UI.
|
|
32
|
+
|
|
33
|
+
### Architecture (schema-driven contribution, "plan A")
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
┌─ pi-forge-subagents ─────────────┐ ┌─ pi-forge ─────────────────┐
|
|
37
|
+
│ UI contribution provider: │ bus │ web host discovers provider │
|
|
38
|
+
│ · getContribution() → { tabId, │ ◄────── │ at startup (capability │
|
|
39
|
+
│ title, icon, schema, values } │ JSON │ negotiation) │
|
|
40
|
+
│ · writeValues(patch) → validate │ ──────► │ generic schema-form tab │
|
|
41
|
+
│ + write subagents.json │ │ (self-contained Vue comp.) │
|
|
42
|
+
└──────────────────────────────────┘ │ PUT /api/contrib/<id> proxy │
|
|
43
|
+
└─────────────────────────────┘
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
- **Contribution protocol**: new versioned port, separate version counter from
|
|
47
|
+
the v1 host port. All payloads are plain recursively-validated JSON (schema +
|
|
48
|
+
values), same discipline as `host-port.ts`.
|
|
49
|
+
- **Forge side** is fully generic: it knows nothing about subagents. No
|
|
50
|
+
provider discovered → no contributed tab, zero cost.
|
|
51
|
+
- **Config ownership stays put**: `subagents.json` (project/global + legacy
|
|
52
|
+
fallback) remains owned and written by the subagent package. Forge's web
|
|
53
|
+
server only proxies the bus call.
|
|
54
|
+
|
|
55
|
+
### Forge-side changes (~1.5–2d)
|
|
56
|
+
|
|
57
|
+
1. Tab registry: replace the hardcoded `"policy" | "regex" | "stack"` union in
|
|
58
|
+
`vue-tab-host.ts` with a data-driven registry (string tab ids, dynamic
|
|
59
|
+
buttons in `App.vue`).
|
|
60
|
+
2. Generic schema-form renderer: self-contained Vue component, bridged via the
|
|
61
|
+
vue-host mechanism. Restricted field types for v1: boolean, number, enum,
|
|
62
|
+
string, plus a record/table shape for per-profile entries. **Do NOT add
|
|
63
|
+
imperative code to `legacy-editor.ts`.**
|
|
64
|
+
3. Web server: `PUT /api/contrib/<tabId>` route proxying `writeValues` over the
|
|
65
|
+
bus; contribution descriptors fetched at page load through `/api/contrib`.
|
|
66
|
+
4. Contribution discovery: web host acts as client toward the provider port;
|
|
67
|
+
tolerate provider disappear/reappear across sessions.
|
|
68
|
+
|
|
69
|
+
### Subagents-side changes (~1d)
|
|
70
|
+
|
|
71
|
+
1. Provider endpoint implementing the contribution protocol.
|
|
72
|
+
2. `ForgeSubagentSettings` → schema mapping (backend, timeoutMs,
|
|
73
|
+
approval flag, summary-in-description flag, per-profile
|
|
74
|
+
enabled/backend/timeout table).
|
|
75
|
+
3. Server-side re-validation on write, reusing existing validators
|
|
76
|
+
(`isValidSubagentTimeoutMs` et al.). Never trust the web client.
|
|
77
|
+
4. TUI companion: `/forge-agent config` subcommand for the same settings
|
|
78
|
+
(internal to the package, no cross-repo coordination).
|
|
79
|
+
|
|
80
|
+
### Known v1 limitation
|
|
81
|
+
|
|
82
|
+
Pure schema cannot express "dropdown fed by live forge data" (e.g. a profileId
|
|
83
|
+
picker backed by `listProfiles`). v1: plain text input + validation errors.
|
|
84
|
+
v2 candidate: a "remote data source" field type. Do not gold-plate v1.
|
|
85
|
+
|
|
86
|
+
### Lane 1B — subagent call-time UX (subagents package only)
|
|
87
|
+
|
|
88
|
+
Two usability extras that live entirely in `@zihanw/pi-forge-subagents`; no
|
|
89
|
+
forge-side coupling, safe to build in parallel with the forge contribution
|
|
90
|
+
framework.
|
|
91
|
+
|
|
92
|
+
**1. Call-time model override** (~0.5d)
|
|
93
|
+
|
|
94
|
+
Main agent may pick the execution model per `forge_subagent` call; default
|
|
95
|
+
remains the profile's model. Feasibility already verified: the wire carries
|
|
96
|
+
model facts (`ForgeBackendFacts.model`, `ForgePrepareResponse.model`), and the
|
|
97
|
+
pi-subagent-runtime subprocess backend already spawns with `--model` — only
|
|
98
|
+
the tool surface lacks the knob.
|
|
99
|
+
|
|
100
|
+
- Add optional `model` parameter (`provider/id` string, parsed + validated) to
|
|
101
|
+
`ForgeSubagentParameters`.
|
|
102
|
+
- Resolution order: `model` param > profile default.
|
|
103
|
+
- Same policy as the `backend` param: override allowed for interactively
|
|
104
|
+
approved runs; unattended invocation is pinned to the profile/configured
|
|
105
|
+
model.
|
|
106
|
+
- Approval summary's existing `Model:` line shows the effective model for free.
|
|
107
|
+
- Update tool description accordingly.
|
|
108
|
+
|
|
109
|
+
**2. Restore rich TUI rendering for subagent runs** (~0.5–1d)
|
|
110
|
+
|
|
111
|
+
The 0.4 tool shipped `renderCall`/`renderResult` (pi-tui Container/Markdown,
|
|
112
|
+
collapsed/expanded states, live progress, usage stats); the 0.5 split dropped
|
|
113
|
+
them, falling back to the default tool display. Streaming infrastructure is
|
|
114
|
+
still intact (`onUpdate` progress pushes, `details.progress` ring buffer at
|
|
115
|
+
`MAX_PROGRESS_ITEMS`).
|
|
116
|
+
|
|
117
|
+
- Port the 0.4.1 renderers from git history (`v0.4.1:src/subagent-tool.ts`)
|
|
118
|
+
into `forge-subagent.ts`, adapted to the current details shape and including
|
|
119
|
+
the approval receipt.
|
|
120
|
+
- `@earendil-works/pi-tui` is already an optional peer dependency.
|
|
121
|
+
- Reference the historical render tests where recoverable.
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Lane 2 — Context diff (folded from context-diff-plan.md)
|
|
126
|
+
|
|
127
|
+
### Goal
|
|
128
|
+
|
|
129
|
+
Per-turn observability for prompt changes so users can optimize KV-cache reuse:
|
|
130
|
+
|
|
131
|
+
- Mark which blocks of the prompt changed after each turn.
|
|
132
|
+
- Show token delta (added/removed/modified) vs the previous turn.
|
|
133
|
+
- Mark where the KV-cache prefix survives ("cache boundary").
|
|
134
|
+
|
|
135
|
+
Secondary goal: merge with live preview — while editing a stack,
|
|
136
|
+
debounce-compile and diff against the previous compile, so edits show their
|
|
137
|
+
prompt/token impact immediately.
|
|
138
|
+
|
|
139
|
+
### Existing building blocks
|
|
140
|
+
|
|
141
|
+
- `src/payload-capture.ts` — real provider request payload (secret-redacted),
|
|
142
|
+
with deliberately rough `approxTokens` (chars/4).
|
|
143
|
+
- Pi's authoritative assistant `message_end` usage — input, output, cache read,
|
|
144
|
+
and cache write token buckets correlated FIFO with captured provider requests.
|
|
145
|
+
- `src/preview.ts` — edit-time compile output split into sections (system +
|
|
146
|
+
per-message), each with chars/approxTokens.
|
|
147
|
+
- Legacy editor already polls payload state every 2s.
|
|
148
|
+
|
|
149
|
+
### Two data sources
|
|
150
|
+
|
|
151
|
+
| Scenario | Source | Question answered |
|
|
152
|
+
|---|---|---|
|
|
153
|
+
| Edit time (live preview merge point) | debounced compile vs previous compile | "what does this edit change, how many tokens" |
|
|
154
|
+
| Run time (request structure) | diff of consecutive real payloads | "where would the reusable serialized prefix end, and what changed" |
|
|
155
|
+
| Run time (provider truth) | correlated assistant usage | "how many prompt tokens and cache reads/writes did the provider report" |
|
|
156
|
+
|
|
157
|
+
### Core engine: `src/context-diff.ts` (host-neutral pure functions)
|
|
158
|
+
|
|
159
|
+
```
|
|
160
|
+
TurnSnapshot { turnId, capturedAt, stackId, blocks: Block[] }
|
|
161
|
+
Block { key, role, text, chars, approxTokens, hash }
|
|
162
|
+
TurnDiff { blocks: DiffBlock[], prefixTokens, prefixRatio, deltaTokens, summary }
|
|
163
|
+
DiffBlock { status: same|added|removed|modified, before?, after?, tokenDelta }
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Cache-boundary algorithm: KV-cache hits depend on the longest common prefix of
|
|
167
|
+
the serialized request. Walk the block arrays in order while hashes match; at
|
|
168
|
+
the first mismatch, trim a char-level common prefix inside that block and
|
|
169
|
+
convert to tokens. Render a boundary marker: "cache valid up to ~18,204 tokens
|
|
170
|
+
(63% of prompt)". No Myers diff needed — prefix + block classification
|
|
171
|
+
suffices.
|
|
172
|
+
|
|
173
|
+
Honesty note: diff token figures remain chars/4 estimates and are always labeled
|
|
174
|
+
as such. Provider prompt/cache usage is displayed separately. Cache hit rate is
|
|
175
|
+
`cacheRead / (input + cacheRead + cacheWrite)` only after cache activity has
|
|
176
|
+
been observed for that provider/model; an all-zero normalized cache bucket is
|
|
177
|
+
otherwise reported as unavailable because it cannot distinguish a true miss
|
|
178
|
+
from a provider that did not report cache detail.
|
|
179
|
+
|
|
180
|
+
### UI
|
|
181
|
+
|
|
182
|
+
Promote the Preview modal into a dockable right-side panel with three tabs:
|
|
183
|
+
|
|
184
|
+
- **Compiled** — current preview content, auto-refresh with 500ms debounce
|
|
185
|
+
while editing (this is the live preview).
|
|
186
|
+
- **Draft diff** and **Run diff** — git-style unified/split line views with
|
|
187
|
+
old/new line numbers, inline changed spans, and selectable changes-only,
|
|
188
|
+
three-line, or full context. Run metadata keeps estimated reusable prefix
|
|
189
|
+
separate from actual provider usage and cache-hit rate.
|
|
190
|
+
|
|
191
|
+
Run-time mode: payload poll captures a new payload → rolling history (last 20
|
|
192
|
+
turns) → auto-compute diff.
|
|
193
|
+
Edit mode: diff current edited compile vs the active on-disk version.
|
|
194
|
+
|
|
195
|
+
Implementation constraint: self-contained Vue component bridged via the
|
|
196
|
+
vue-host mechanism, riding Lane 1's data-driven dock/tab registry. Do NOT add
|
|
197
|
+
more imperative code to `legacy-editor.ts`. Do NOT refactor the legacy editor
|
|
198
|
+
in the same lane.
|
|
199
|
+
|
|
200
|
+
### Phases / estimate
|
|
201
|
+
|
|
202
|
+
| Phase | Content | Effort |
|
|
203
|
+
|---|---|---|
|
|
204
|
+
| 0 | Design freeze + golden fixtures (turn payload sets) | 0.5d |
|
|
205
|
+
| 1 | `context-diff.ts` engine + unit tests (prefix/add/remove/modify/token rollups) | 1d |
|
|
206
|
+
| 2 | Server endpoint + rolling snapshot state on the web host | 0.5d |
|
|
207
|
+
| 3 | Web UI: preview dock + Diff view (self-contained Vue, bridged, on Lane 1's registry) | 1.5d |
|
|
208
|
+
| 4 | Browser tests + docs + changelog | 0.5–1d |
|
|
209
|
+
|
|
210
|
+
Lane 2 total ~4–5 working days. Descope option (~3d): run-time diff only,
|
|
211
|
+
live preview reduced to plain auto-refresh without edit-time diffing.
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## Combined estimate
|
|
216
|
+
|
|
217
|
+
| Lane | Content | Effort |
|
|
218
|
+
|---|---|---|
|
|
219
|
+
| 1 | UI contribution framework (forge) + provider & config UI (subagents) | ~2.5–3d |
|
|
220
|
+
| 1B | Call-time model override + rich TUI restore (subagents only) | ~1–1.5d |
|
|
221
|
+
| 2 | Context diff engine + dock UI | ~4–5d |
|
|
222
|
+
|
|
223
|
+
~8.5–9.5 working days total, ~2 calendar weeks with review. Both lanes require
|
|
224
|
+
coordinated releases: forge 0.5.1 must understand the contribution protocol
|
|
225
|
+
before (or simultaneously with) subagents 0.5.1 advertising it — the
|
|
226
|
+
capability negotiation makes order-independent rollout safe. Lane 1B lives
|
|
227
|
+
entirely in subagents 0.5.1 and ships with it; the promo should present both
|
|
228
|
+
packages together.
|
|
229
|
+
|
|
230
|
+
## Release narrative
|
|
231
|
+
|
|
232
|
+
0.5.1 headlines "observability + subagent UX". The promo video leads with the
|
|
233
|
+
context diff money shot (edit one system-prompt line, watch the cache-boundary
|
|
234
|
+
marker jump). Promo pipeline follows the AIGC/VIDEO_PRODUCTION ep02 reference:
|
|
235
|
+
`PLAN.md` → script draft → `narration.json` → roughcut → review; terminology
|
|
236
|
+
rule: plain words first, formal term named once ("KV cache" on first mention,
|
|
237
|
+
then "prefix cache / cache reuse region").
|
package/docs/design/README.md
CHANGED
|
@@ -1,8 +1,26 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Architecture and design
|
|
2
2
|
|
|
3
3
|
[Documentation](../README.md)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
The active plan defines the executable forward-looking work. Archived documents preserve the long-term target, decisions, reviews, spikes, and implementation history; they are not the authoritative description of current user behavior. Use the [guides](../README.md#guides) and [reference](../README.md#reference) for released behavior.
|
|
6
|
+
|
|
7
|
+
## Active 0.5.0 plan
|
|
8
|
+
|
|
9
|
+
- [Lean 0.5.0 architecture plan](architecture-0.5.md) — executable breaking-cleanup scope, accepted decisions, implementation lanes, and release gates.
|
|
10
|
+
- [Architecture and development rules](../development/architecture-rules.md) — dependency direction and ownership rules for the full target.
|
|
11
|
+
- [Architecture decision template](decision-template.md) — structure for future boundary/product decisions.
|
|
12
|
+
|
|
13
|
+
## Archived 0.5 full proposal
|
|
14
|
+
|
|
15
|
+
The original six-phase target remains the long-term goal and is preserved here:
|
|
16
|
+
|
|
17
|
+
- [Full proposal index](archive/0.5-full-proposal/README.md)
|
|
18
|
+
- [Full 0.5 architecture plan](archive/0.5-full-proposal/architecture-0.5.md)
|
|
19
|
+
- [Migration inventory](archive/0.5-full-proposal/0.5-inventory.md)
|
|
20
|
+
- [Public-consumer audit](archive/0.5-full-proposal/0.5-consumer-audit.md)
|
|
21
|
+
- [Phase-0 decision drafts](archive/0.5-full-proposal/0.5-phase0-decision-drafts.md)
|
|
22
|
+
- [Template-language spike](archive/0.5-full-proposal/template-language-spike.md)
|
|
23
|
+
- [Pi host-discovery spike](archive/0.5-full-proposal/host-discovery-spike.md)
|
|
6
24
|
|
|
7
25
|
## Subagent design history
|
|
8
26
|
|
|
@@ -14,4 +32,4 @@ These documents preserve decisions, reviews, spikes, and implementation history.
|
|
|
14
32
|
|
|
15
33
|
- [0.4 roadmap and implementation log](roadmap-0.4-archive.md)
|
|
16
34
|
|
|
17
|
-
The
|
|
35
|
+
The 0.5 host boundary is in the [subagent host port contract](../reference/subagent-host-port.md); accepted work ordering is in the [roadmap](../development/roadmap.md).
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
# pi-forge 0.5.0 architecture plan (lean)
|
|
2
|
+
|
|
3
|
+
[Documentation](../README.md) · [Roadmap](../development/roadmap.md) · [Architecture rules](../development/architecture-rules.md)
|
|
4
|
+
|
|
5
|
+
Status: accepted lean 0.5.0 scope
|
|
6
|
+
|
|
7
|
+
Date: 2026-08-18
|
|
8
|
+
|
|
9
|
+
The long-term architecture goal is unchanged. The original six-phase target plan and Phase-0 evidence are archived in [0.5 full architecture proposal](archive/0.5-full-proposal/README.md). This page is the executable 0.5.0 scope; 0.5.x continues toward the full target.
|
|
10
|
+
|
|
11
|
+
## Goal
|
|
12
|
+
|
|
13
|
+
0.5.0 is a breaking cleanup release plus the minimum foundation for later work:
|
|
14
|
+
|
|
15
|
+
- deterministic immutable prompt compilation;
|
|
16
|
+
- prompt-stack schema v2;
|
|
17
|
+
- minimal repository/codec persistence seam;
|
|
18
|
+
- optional subagents behind a versioned host port;
|
|
19
|
+
- an explicit public package surface.
|
|
20
|
+
|
|
21
|
+
It is not a platformization release.
|
|
22
|
+
|
|
23
|
+
## Accepted 0.5.0 decisions
|
|
24
|
+
|
|
25
|
+
1. **SillyTavern is removed completely.** 0.4 is the last supported conversion path. Commands, importer, regex emulation, example, guide, and tests are deleted.
|
|
26
|
+
2. **Mutable variables are removed.** Turn/session stores, `setvar`/`setturnvar`/`setsessionvar`/clear/get variable macros, `variables` slot, and `pi-forge-variable-state` entries are removed. Static values become immutable `parameters` in schema v2.
|
|
27
|
+
3. **`forge-v1` replaces the macro implementation.** One parsed grammar with interpolation, a finite filter set, and `if`/`else` over documented environment predicates. No includes, loops, function calls, general expressions, or ambient access.
|
|
28
|
+
4. **The trusted extension port is retained and redesigned in this release.** `registerMacro` and `registerSlot` survive with a pure contract. The contract is specified in [Extension port contract](#extension-port-contract-050).
|
|
29
|
+
5. **Regex `display` and `both` are removed.** Valid effects become `outgoing` and `finalize`. `finalize` behavior is retained with explicit ownership in [Finalize regex ownership](#finalize-regex-ownership-050).
|
|
30
|
+
6. **Subagents move to an optional `pi-forge-subagents` package.** The main package removes the hard dependency on `@zihanw/pi-subagent-runtime`. The main package keeps `@zihanw/pi-forge/subagent` as a versioned host port with data-only event-bus messages. The `/subagent` entry owns a minimal Forge DTO host contract — wire messages, recursive validators, transport, and client/host lifecycle — plus a Forge-owned canonical fingerprint helper that stays byte-compatible with the runtime's `sha256:v1` canonical JSON. The 0.4 execution contract (the Forge host product types layered over the runtime's portable contract: request, preflight, plan, response, context, tool negotiation, and their validators) moves to the optional package with names unchanged; the optional package imports the runtime's portable leaves directly.
|
|
31
|
+
7. **The 0.5.0 host port has a minimal operation catalogue and mandatory lifecycle rules.** Operations are discovery, profile listing/snapshot, and prompt preparation. Correlation IDs, payload validation, timeouts, host generation, duplicate-host failure, disposal/`unavailable`, and listener cleanup are part of host port v1, not deferred.
|
|
32
|
+
8. **`ForgeWorkspace` is the minimal resource-state owner, and all stack/profile persistence goes through minimal repositories and codecs in 0.5.0.** Repositories own scoped discovery and mutation; codecs own parse/normalize/validate/serialize. Expected-fingerprint writes and guaranteed atomic replacement are 0.5.x work.
|
|
33
|
+
9. **Configuration ownership uses dedicated optional-package files.** Main package owns `webEditor.*` in `.pi/forge/config.json` and its global equivalent. The optional package owns `.pi/forge/subagents.json` and `~/.pi/forge/subagents.json`. Main pi-forge does not read, write, validate, or clean subagent configuration. Legacy `config.json.subagents` is read-only fallback material for the optional package, with warnings and no automatic migration.
|
|
34
|
+
10. **Web editor delegation UI is removed from the main package in 0.5.0.** The optional package ships config-only for delegation. A small standalone optional-package editor page is the 0.5.x path; a main-editor contribution port is not designed now.
|
|
35
|
+
11. **Pi session custom entries:** newly written stack/profile entries use a `schemaVersion` envelope. Unversioned 0.4 entries are decoded through legacy readers. `pi-forge-variable-state` is never restored or written; one bounded diagnostic is emitted per restoration.
|
|
36
|
+
12. **Public surfaces are exactly three intentional entry points:** package root default factory, package root named extension API (`registerMacro`, `registerSlot`, and their contract types), and `@zihanw/pi-forge/subagent`. All other root re-exports and `src/*` aliases are removed. `check-package` enforces this allowlist.
|
|
37
|
+
13. **Migration is a small utility plus release notes, not a framework.** A v1-to-v2 script converts mechanical `variables`/macro fields with explicit diagnostics; removed behavior is never silently approximated.
|
|
38
|
+
|
|
39
|
+
## Accepted 0.5.1 amendment: generic settings contributions
|
|
40
|
+
|
|
41
|
+
Dogfooding invalidated decisions 10 and 12 as forward-looking constraints, while preserving their 0.5.0 historical outcome. The accepted 0.5.1 amendment is:
|
|
42
|
+
|
|
43
|
+
1. `@zihanw/pi-forge/ui-contribution` is a fourth intentional, experimental entry point. It is a generic, versioned, data-only event-bus port; main pi-forge owns the renderer and HTTP proxy but has no subagent-specific schema or persistence logic.
|
|
44
|
+
2. Optional packages may contribute restricted schema-driven Settings pages. Schemas and values are recursively validated JSON data; provider handlers may be asynchronous and receive generation-bound cancellation before side effects.
|
|
45
|
+
3. `pi-forge-subagents` remains the sole owner of both `subagents.json` files. It obtains profile choices only through `/subagent`, contributes plain settings descriptors through `/ui-contribution`, and performs all subagent validation and persistence itself.
|
|
46
|
+
4. This amendment does not authorize a general plugin UI/component runtime, arbitrary browser code, a second resource registry, or main-package reads/writes of optional-package configuration.
|
|
47
|
+
|
|
48
|
+
## Extension port contract (0.5.0)
|
|
49
|
+
|
|
50
|
+
The 0.5.0 extension contract is part of the breaking release. It is a trusted-extension port, not a security boundary.
|
|
51
|
+
|
|
52
|
+
- `PromptEnvironment` is a deep-frozen, JSON-compatible snapshot with three path roots:
|
|
53
|
+
- `runtime.*` — documented built-in runtime facts;
|
|
54
|
+
- `parameters.*` — immutable stack parameters;
|
|
55
|
+
- `extensions.*` — registered extension values.
|
|
56
|
+
- `registerMacro` registers a named, zero-argument pure value renderer:
|
|
57
|
+
- inputs: `{ env: PromptEnvironment; helpers: PromptRenderHelpers }`;
|
|
58
|
+
- declaration: `{ name, description?, source?, dependencies: string[] }`;
|
|
59
|
+
- returns a `string`; `throw` produces a compiler error diagnostic and no partial output;
|
|
60
|
+
- addressed in templates as `{{ extensions.<name> }}`.
|
|
61
|
+
- `registerSlot` keeps option-schema validation and is addressed by `kind: "slot"`:
|
|
62
|
+
- inputs: `{ item, options, env, helpers }`;
|
|
63
|
+
- same declaration, return, and error semantics as macros.
|
|
64
|
+
- Dependency declarations are authoritative for the analyzer. A renderer must only read declared paths; undeclared reads are contract violations, not enforced isolation.
|
|
65
|
+
- Output limits are enforced by the compiler: 100,000 characters per compiled template and 16,384 characters per extension macro/slot value.
|
|
66
|
+
- Registration identity is name-based and global within the Forge extension loader. Duplicate registration throws; unregistration returns a disposer. The workspace owns load/reload/dispose ordering and reuses the current trusted extension discovery directories.
|
|
67
|
+
- Preview, runtime, and subagent preparation use the same analyzer output. No consumer may parse template syntax independently.
|
|
68
|
+
|
|
69
|
+
## Finalize regex ownership (0.5.0)
|
|
70
|
+
|
|
71
|
+
`finalize` is retained, but is explicitly outside deterministic prompt compilation:
|
|
72
|
+
|
|
73
|
+
- **Owner:** the lifecycle/transcript adapter, not the compiler.
|
|
74
|
+
- **Order:** after the provider returns a finalized assistant message, before that message is stored in the transcript.
|
|
75
|
+
- **Constraints:** `stage: "compiled"`, `targets: ["messages"]`, and assistant roles only, as validated today.
|
|
76
|
+
- **Preview:** preview and runtime prompt compilation never apply `finalize`. Preview reports an informational diagnostic that finalize rules are not represented.
|
|
77
|
+
- **Restoration:** the original model output is not preserved. This remains a documented, user-enabled destructive transform carried over from 0.4.
|
|
78
|
+
- **Tests:** 0.5.0 adds characterization coverage for finalize ordering and non-application during preview.
|
|
79
|
+
|
|
80
|
+
## Minimal target state
|
|
81
|
+
|
|
82
|
+
```mermaid
|
|
83
|
+
flowchart LR
|
|
84
|
+
Adapters["Commands + lifecycle + web editor"] --> Workspace["ForgeWorkspace"]
|
|
85
|
+
Workspace --> Repos["Minimal repositories + codecs"]
|
|
86
|
+
Workspace --> Compiler["forge-v1 compiler"]
|
|
87
|
+
Compiler --> Extensions["Trusted extension port"]
|
|
88
|
+
Workspace -. "event-bus host port v1" .-> Optional["pi-forge-subagents"]
|
|
89
|
+
WebEditor["Generic Settings renderer"] -. "UI contribution port v1" .-> Optional
|
|
90
|
+
Optional --> Runtime["pi-subagent-runtime"]
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
The final layered target (core modules, full application services, complete host catalogue, fingerprint/atomic persistence) remains the archived full plan and is reached in 0.5.x.
|
|
94
|
+
|
|
95
|
+
## Implementation lanes
|
|
96
|
+
|
|
97
|
+
Only one lane is active at a time. Each lane ends with `npm run verify` green and committed.
|
|
98
|
+
|
|
99
|
+
### Lane 0: documentation convergence
|
|
100
|
+
|
|
101
|
+
Archive the full proposal, make this lean plan active, and simplify repository guidance and PR requirements.
|
|
102
|
+
|
|
103
|
+
### Lane 1a: removals only
|
|
104
|
+
|
|
105
|
+
- Remove SillyTavern code, tests, examples, and guides.
|
|
106
|
+
- Remove mutable variable stores, variable session entries, variable macros, and the `variables` slot.
|
|
107
|
+
- Remove regex `display`/`both` and make them validation errors.
|
|
108
|
+
- Keep static `stack.variables` working through the existing compiler until schema v2 lands in Lane 1b.
|
|
109
|
+
- Update only tests that cover removed behavior.
|
|
110
|
+
|
|
111
|
+
### Lane 1b: compiler, schema v2, and extension contract
|
|
112
|
+
|
|
113
|
+
- Implement `forge-v1` parse/analyze/render.
|
|
114
|
+
- Introduce frozen `PromptEnvironment` and make preview/runtime/subagent preparation share one compiler entry.
|
|
115
|
+
- Introduce schema v2 with immutable `parameters`.
|
|
116
|
+
- Implement the [extension port contract](#extension-port-contract-050).
|
|
117
|
+
- Retain `finalize` under the ownership rule above and add its characterization coverage here.
|
|
118
|
+
- Add compiler/schema/extension conformance coverage.
|
|
119
|
+
|
|
120
|
+
### Lane 1c: migration and documentation
|
|
121
|
+
|
|
122
|
+
- Add the small v1-to-v2 migration script with explicit diagnostics.
|
|
123
|
+
- Migrate examples and update English and Chinese user-facing compiler/schema/extension docs.
|
|
124
|
+
- Update changelog and migration notes for the Lane 1 breaks.
|
|
125
|
+
|
|
126
|
+
### Lane 1d: compiler/extension conformance
|
|
127
|
+
|
|
128
|
+
- Make custom slot extensions symmetric with macros: pure `{ item, options, env, helpers }` render context, declared `dependencies`, and the same 16,384-character output limit.
|
|
129
|
+
- Resolve declared extension dependencies when populating `env.extensions` for slot rendering.
|
|
130
|
+
- Introduce a reusable prompt dependency analysis plan (direct dependencies, transitive extension closure, slot dependencies, diagnostics) shared by runtime compilation, preview, and subagent preparation.
|
|
131
|
+
- Create one compilation context per provider-preparation cycle with a single runtime/timestamp snapshot, frozen base environment, and request-local extension cache shared between system and message compilation; this applies to the runtime lifecycle (`before_agent_start` + `context`), preview rendering, and subagent host preparation alike. Cache entries are keyed by name and frozen environment snapshot; `latestUserMessage` is the one captured field that can change between phases, and `setLatestUserMessage` invalidates the cache only when the value actually changes, so env-dependent macros observe the current value instead of a stale pre-phase snapshot. Tradeoff: when the value does change, the whole request-local cache is dropped, so a stateful/non-deterministic macro appearing in both phases may render different values per phase (system keeps the pre-invalidation value, messages get a fresh one); the two phases still share one explicit timestamp snapshot.
|
|
132
|
+
- Keep dependency analysis eager, but resolve extension values lazily during rendering so unreachable branches do not execute extensions.
|
|
133
|
+
- Support nested `{% if %}` blocks with a recursion-depth guard.
|
|
134
|
+
- Fix parser conformance issues such as empty-string comparisons and strict undefined handling.
|
|
135
|
+
- Clarify or document `maxChars` best-effort semantics and separate empty-system-prompt fallback from compile failure.
|
|
136
|
+
- Add focused conformance tests for all of the above.
|
|
137
|
+
|
|
138
|
+
### Lane 2a: minimal repositories and codecs
|
|
139
|
+
|
|
140
|
+
- Extract stack/profile codecs as the single parse/normalize/validate/serialize source: `src/codecs/prompt-stack.ts` and `src/codecs/agent-profile.ts` own parse/normalize/validate/serialize, and the loaders (and migration tooling) delegate to them; repositories (`src/repositories/`) are the only read/write/delete path for domain resources — reads (directory enumeration + file reads through the codecs) and mutations (scope/containment/symlink-checked writes and deletes) both live there, and `loader.ts`/`agent-profile.ts` only delegate.
|
|
141
|
+
- Extract scoped repositories as the only domain resource read/write/delete path, including scope and containment validation. Legacy stack migration is a documented byte-preserving exception: its raw IO lives in the repository (read/copy/delete for `.pi/prompt-stacks`), while canonicalization happens on every subsequent load through the codecs.
|
|
142
|
+
- Remove direct domain-resource writes from web host, commands, and profile service.
|
|
143
|
+
- Do not add expected-fingerprint conflicts or guaranteed atomic replacement yet; characterize current replacement behavior with tests.
|
|
144
|
+
|
|
145
|
+
### Lane 2b: ForgeWorkspace and host port v1
|
|
146
|
+
|
|
147
|
+
- Introduce `ForgeWorkspace` as the minimal snapshot owner over the Lane 2a repositories: one immutable scoped stack/profile snapshot plus active selection/provenance, owning host registration/generation/disposal.
|
|
148
|
+
- Publish `@zihanw/pi-forge/subagent` host port v1 over the Pi event bus with mandatory lifecycle rules and the three minimal operations (discovery, profile listing/snapshot, and prompt preparation). The port is transport-neutral (`ForgeHostTransport`), uses plain validated data messages, and never crosses live contexts or internal registries.
|
|
149
|
+
- Mandatory lifecycle semantics: clients subscribe before announcing/discovering and use bounded timeouts; duplicate live hosts fail with an explicit `host.duplicate` error; disposal sends `unavailable` and invalidates connections; all transient and persistent listeners are cleaned up. `request`/`reply` wire messages carry `hostId` + `generation`, so stale-generation and wrong-host requests are rejected server-side and mismatched replies are ignored client-side.
|
|
150
|
+
- Host-owned preparation: the client sends only a profile selector, task, prompt-compilation access facts (`level`/`network`/`allowProcess`) and backend facts (model/thinking/tool catalog); the workspace resolves the profile + stack from its snapshot and compiles the prompt itself, returning an immutable preparation artifact (system prompt, messages, effective tools, diagnostics, and profile snapshot). No execution/runtime material (access workspace model, limits, `resultProjection`/`parent`/`remoteEgressConsent`, or a base prompt) crosses the boundary. Each operation has a recursive, exact-field, JSON-compatible validator (plain objects only, enums enforced) at the wire boundary.
|
|
151
|
+
- `ForgeWorkspace` snapshots are genuinely immutable (deep-frozen clones), and the host port is wired into the real extension lifecycle (`pi.events` transport; reload on session start/tree/compact; dispose on session shutdown, before subagent teardown). The host can only be started after the first snapshot exists (`startHostPort` throws otherwise), so `host available` ⇒ `snapshotKnown`; `reload` honors project trust (untrusted workspaces expose global resources only). The base system prompt is host-owned and intentionally empty for delegated subagents — the prompt stack composes the system prompt, and the host rejects unknown request fields so no prompt-runtime material can be smuggled across the boundary.
|
|
152
|
+
- Cover timeout, duplicate-host failure, generation/stale-request rejection, disposal, listener cleanup, operation validators, immutability, and a real-factory integration discovery->list->prepare->dispose flow in tests.
|
|
153
|
+
|
|
154
|
+
### Lane 3: subagent extraction
|
|
155
|
+
|
|
156
|
+
- Create `pi-forge-subagents` by moving current subagent commands, tools, config parsing/writing, and execution code.
|
|
157
|
+
- Optional package depends only on documented host-port messages and owns the dedicated `subagents.json` files, with read-only legacy fallback.
|
|
158
|
+
- Remove main-package delegation UI and all subagent configuration reads/writes.
|
|
159
|
+
- Main package installs and passes verification without the subagent runtime.
|
|
160
|
+
- Optional package passes packed-install smoke tests.
|
|
161
|
+
|
|
162
|
+
### Lane 3.5: host-neutrality hardening
|
|
163
|
+
|
|
164
|
+
Emergent lane recorded after the fact; executed in three stages.
|
|
165
|
+
|
|
166
|
+
- Stage 1: make the prompt compiler host-neutral.
|
|
167
|
+
- Stage 2: make `ForgeWorkspace` the single resource-state owner.
|
|
168
|
+
- Stage 3: align subagent docs/config with the optional package and make the packed smoke portable. The optional package gains profile discovery, the `/forge-agent` command, legacy config fallback, and tool-description summary refresh.
|
|
169
|
+
|
|
170
|
+
### Lane 4: public surface and release
|
|
171
|
+
|
|
172
|
+
Lane 4a: Forge-native host contract (both packages).
|
|
173
|
+
|
|
174
|
+
- The main package drops the `@zihanw/pi-subagent-runtime` dependency entirely. (An earlier draft of this lane kept the runtime as the `/subagent` contract library; that contradicted decision 6 and the release gates and is removed.) `/subagent` owns the minimal Forge DTO host contract described in decision 6.
|
|
175
|
+
- Workspace prompt preparation becomes Forge-native: resolve profile and stack from the snapshot, compile through the shared compilation context, filter the client tool catalog through stack policy, and return the `prepare` DTO directly. The synthetic AgentRequest/preflight/prompt-runtime construction is removed.
|
|
176
|
+
- The 0.4 execution contract modules move to the optional package per decision 6; contract tests move with the code.
|
|
177
|
+
|
|
178
|
+
Lane 4b: main-package public-surface cut.
|
|
179
|
+
|
|
180
|
+
- Root exports reduce to the default factory plus `registerMacro`/`registerSlot` and their contract types; `/subagent` exports the host contract only; `src/*` aliases are removed.
|
|
181
|
+
- `check-package` flips from requiring legacy aliases to forbidding them and enforcing the three-entry allowlist; public-API tests assert exact export name sets; packed-install smoke assertions follow the trimmed surface.
|
|
182
|
+
|
|
183
|
+
Lane 4c: optional-package packed smoke.
|
|
184
|
+
|
|
185
|
+
- The optional package gains its own `check:packed`: pack both packages, install into a temporary consumer, load the extension, and run discover → listProfiles → prepare → dispose over a loopback `ForgeHostTransport` against a fixture workspace.
|
|
186
|
+
|
|
187
|
+
Lane 4d: documentation and changelog.
|
|
188
|
+
|
|
189
|
+
- Update English and Chinese user-facing docs for breaking changes: rewrite the public-API policy for the three surfaces, replace the subagent adapter contract reference with the host-port contract, complete the 0.5 migration guide (Lanes 2–4) in English and Chinese, and fix stale README references.
|
|
190
|
+
- Write changelog entries for Lanes 3.5 and 4 and one-page migration notes.
|
|
191
|
+
|
|
192
|
+
Lane 4e: release.
|
|
193
|
+
|
|
194
|
+
- Run main-only and main-plus-optional packed-install verification (`check:packed` smoke), version both packages 0.5.0, publish main then optional, smoke the published artifacts, and tag.
|
|
195
|
+
|
|
196
|
+
## Release gates
|
|
197
|
+
|
|
198
|
+
- `npm run verify` passes.
|
|
199
|
+
- All stack/profile persistence goes through minimal repositories and codecs.
|
|
200
|
+
- Runtime and preview compile through one `forge-v1` entry point.
|
|
201
|
+
- Host port v1 passes discovery, timeout, generation, duplicate-host, and disposal tests.
|
|
202
|
+
- `finalize` ordering and preview exclusion are characterized.
|
|
203
|
+
- Schema v2, extension contract, and migration notes are documented.
|
|
204
|
+
- Main package has no subagent runtime dependency and passes packed smoke tests alone.
|
|
205
|
+
- Optional package passes packed smoke tests through host port v1 and owns only its dedicated config files.
|
|
206
|
+
- UI contribution port passes schema validation, async generation cancellation, provider churn, and packed optional-consumer tests.
|
|
207
|
+
- No non-allowlisted root exports or `src/*` aliases remain.
|
|
208
|
+
- User-facing breaking changes are documented in English and Chinese.
|
|
209
|
+
|
|
210
|
+
## Deferred to 0.5.x
|
|
211
|
+
|
|
212
|
+
These items come from the archived full plan and are intentionally not part of 0.5.0:
|
|
213
|
+
|
|
214
|
+
- expected-fingerprint conflict writes and guaranteed atomic file replacement;
|
|
215
|
+
- physical `pi-forge-core` package and enforced module/package boundaries;
|
|
216
|
+
- automatic dependency-direction checking;
|
|
217
|
+
- full `PromptStackService` / `AgentProfileService` application facades;
|
|
218
|
+
- complete host RPC operation catalogue, progress events, and richer lifecycle features beyond host port v1;
|
|
219
|
+
- optional-package standalone delegation UI and arbitrary contributed UI components;
|
|
220
|
+
- full public-surface classification register and consumer audit repeat;
|
|
221
|
+
- rolling Pi compatibility matrix and scheduled latest-Pi probe;
|
|
222
|
+
- sandbox, staged writes, new prompt features, richer imports, and orchestration.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# 0.5 public-consumer audit
|
|
2
|
+
|
|
3
|
+
[Design index](README.md) · [0.5 migration inventory](0.5-inventory.md) · [0.5 decision drafts](0.5-phase0-decision-drafts.md)
|
|
4
|
+
|
|
5
|
+
Status: completed Phase 0 evidence; public-surface decision pending
|
|
6
|
+
|
|
7
|
+
Date: 2026-08-17
|
|
8
|
+
|
|
9
|
+
## Scope and method
|
|
10
|
+
|
|
11
|
+
This audit identifies known consumers of surfaces that Phase 6 may remove or
|
|
12
|
+
replace. It covers the repository, published npm metadata, the Pi package
|
|
13
|
+
directory, public web searches for exact import strings, and an unauthenticated
|
|
14
|
+
GitHub code-search attempt. It cannot prove that no private or unindexed
|
|
15
|
+
consumer exists.
|
|
16
|
+
|
|
17
|
+
## Findings
|
|
18
|
+
|
|
19
|
+
| Surface | Known consumer / evidence | Confidence | 0.5 implication |
|
|
20
|
+
|---|---|---|---|
|
|
21
|
+
| Default package entry | `pi.extensions` in the published manifest | High | Retain as main extension entry |
|
|
22
|
+
| `@zihanw/pi-forge/subagent` | Public-API packaged-import test; reference documentation | High | Retain only as the deliberate versioned host port |
|
|
23
|
+
| Root macro/slot registration | Custom-system-status example, user guide, and Pi package listing | High | Acknowledge a real documented integration path; publish a migration or replacement contract |
|
|
24
|
+
| Root profile/resource helper exports | Repository tests and root barrel only | Medium | No named external consumer found; do not preserve by default |
|
|
25
|
+
| `@zihanw/pi-forge/src/*` aliases | Compatibility documentation and package manifest | Medium | No named external consumer found; announce removal and retain no new alias |
|
|
26
|
+
| Root documentation pointers | Package `files` allowlist, root `PUBLIC_API.md`, root `SUBAGENT_ADAPTER_CONTRACT.md` | High | Decide whether to retain as offline redirect files |
|
|
27
|
+
| SillyTavern converter/command | Released docs, examples, and tests | High | User-facing migration obligation, but planned removal is explicit |
|
|
28
|
+
|
|
29
|
+
The local repository contains no package-style import other than its own
|
|
30
|
+
`@zihanw/pi-forge/subagent` public-surface test. It contains no downstream
|
|
31
|
+
repository or fixture that imports a `src/*` alias.
|
|
32
|
+
|
|
33
|
+
## Published-package observations
|
|
34
|
+
|
|
35
|
+
- npm reported `@zihanw/pi-forge` 0.4.1 as `latest` on 2026-08-17. Its manifest
|
|
36
|
+
contains the root and `/subagent` exports, the three `src/*` compatibility
|
|
37
|
+
patterns, and `@zihanw/pi-subagent-runtime` as a hard dependency.
|
|
38
|
+
- The same manifest identifies Pi SDK packages and `typebox` as wildcard peers.
|
|
39
|
+
- The Pi package directory is discoverable and documents `registerMacro` and
|
|
40
|
+
`registerSlot` as reusable-package APIs. At crawl time it displayed stale
|
|
41
|
+
0.3.2 package metadata, despite npm reporting 0.4.1. It is useful evidence of
|
|
42
|
+
discoverability, not an authoritative release or consumer record.
|
|
43
|
+
|
|
44
|
+
## Search results and limitations
|
|
45
|
+
|
|
46
|
+
- Exact public-web searches for `@zihanw/pi-forge`,
|
|
47
|
+
`@zihanw/pi-forge/subagent`, and `@zihanw/pi-forge/src/` found the package
|
|
48
|
+
listing and this repository's published material, but no independent source
|
|
49
|
+
import.
|
|
50
|
+
- Unauthenticated GitHub code search rejected the exact-import query with HTTP
|
|
51
|
+
401. A maintainer with appropriate access should repeat it, including private
|
|
52
|
+
organization repositories, before a release removes compatibility exports.
|
|
53
|
+
- npm does not provide a reliable reverse-dependency list for this extension;
|
|
54
|
+
download counts cannot identify source/API consumers.
|
|
55
|
+
|
|
56
|
+
## Required release follow-up
|
|
57
|
+
|
|
58
|
+
Before Phase 6, repeat the search with maintainer GitHub credentials, inspect
|
|
59
|
+
support/issues/discussions for named integrations, and add every discovered
|
|
60
|
+
consumer to the public-surface decision register. The absence of a discovered
|
|
61
|
+
consumer supports removal only under the 0.5 breaking-release policy; it is not
|
|
62
|
+
a claim that no consumer exists.
|