@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,423 @@
|
|
|
1
|
+
# pi-forge 0.5.0 architecture plan
|
|
2
|
+
|
|
3
|
+
[Documentation](../../../README.md) · [Development rules](../../../development/architecture-rules.md) · [Roadmap](../../../development/roadmap.md)
|
|
4
|
+
|
|
5
|
+
Status: proposed
|
|
6
|
+
|
|
7
|
+
Date: 2026-08-17
|
|
8
|
+
|
|
9
|
+
0.5 is a deliberately breaking stabilization release. Its purpose is to make the extension understandable and evolvable before adding more features. Compatibility is preserved only where it has a demonstrated consumer and does not compromise the target boundaries.
|
|
10
|
+
|
|
11
|
+
## Problem statement
|
|
12
|
+
|
|
13
|
+
The 0.4 implementation is well tested, but feature throughput has outpaced architectural consolidation. Prompt stacks, profiles, web editing, mutable variables, imports, payload debugging, and subagents share state and orchestration paths. Several adapters perform application or persistence work directly, and internal file-shaped exports constrain reorganization.
|
|
14
|
+
|
|
15
|
+
The problem is not primarily file size. It is unclear ownership and too many ways to load, validate, mutate, compile, or present the same resources.
|
|
16
|
+
|
|
17
|
+
## Release goals
|
|
18
|
+
|
|
19
|
+
0.5 will:
|
|
20
|
+
|
|
21
|
+
- establish a one-directional architecture with explicit domain, application, port, infrastructure, and adapter layers;
|
|
22
|
+
- make a `ForgeWorkspace` the owner of coherent prompt-stack/profile resource state;
|
|
23
|
+
- unify stack/profile persistence behind scoped repositories and codecs while keeping their domain models separate;
|
|
24
|
+
- make prompt compilation deterministic over a normalized immutable environment;
|
|
25
|
+
- remove mutable turn/session variables and render-time variable mutation;
|
|
26
|
+
- replace the macro implementation only through an explicit template-engine contract, preserving a legacy reader only when migration requires it;
|
|
27
|
+
- extract optional subagent integration from the main extension through a versioned host port;
|
|
28
|
+
- remove or sharply reduce SillyTavern-specific functionality;
|
|
29
|
+
- replace wildcard internal exports with intentional package entry points;
|
|
30
|
+
- simplify commands and the web editor into adapters over shared application services.
|
|
31
|
+
|
|
32
|
+
## Non-goals
|
|
33
|
+
|
|
34
|
+
0.5 will not add orchestration, background agents, pipelines, retries, queues, new regex modes, richer imports, or new editor product surfaces. Sandbox and staged-write work remains deferred until the package and host boundaries are stable.
|
|
35
|
+
|
|
36
|
+
The refactor does not merge profiles, stacks, and compilation into one domain object. They share infrastructure and an application facade, but retain distinct responsibilities.
|
|
37
|
+
|
|
38
|
+
## Accepted architectural decisions
|
|
39
|
+
|
|
40
|
+
### Breaking cleanup is preferred to indefinite compatibility
|
|
41
|
+
|
|
42
|
+
0.5 may change JSON schema, public TypeScript APIs, commands, package exports, and internal storage coordination. Every user-visible break must have an explicit migration note; not every 0.4 feature requires a compatibility implementation.
|
|
43
|
+
|
|
44
|
+
### Mutable variables are removed
|
|
45
|
+
|
|
46
|
+
The following 0.4 behavior is removed from the 0.5 core design:
|
|
47
|
+
|
|
48
|
+
- turn and session variable stores;
|
|
49
|
+
- `setvar`, `setturnvar`, `setsessionvar`, and clear-variable macros;
|
|
50
|
+
- variable persistence in Pi session entries;
|
|
51
|
+
- the `variables` slot;
|
|
52
|
+
- render-time mutation through custom macro/slot contexts.
|
|
53
|
+
|
|
54
|
+
Templates receive an immutable context containing built-in runtime values. Static reusable values are retained as an immutable `parameters` object in stack schema v2; the v1 `stack.variables` string/JSON inconsistency is resolved by the v2 codec.
|
|
55
|
+
|
|
56
|
+
### SillyTavern is not a core architecture driver
|
|
57
|
+
|
|
58
|
+
The current fidelity-oriented importer, regex translation, report surface, command, guide, and dedicated example are removed from the core 0.5 scope.
|
|
59
|
+
|
|
60
|
+
Decision: **complete removal**. 0.4 is documented as the last supported conversion path. A richer converter can later live in a separate package without shaping the prompt compiler.
|
|
61
|
+
|
|
62
|
+
### Subagents become optional integration
|
|
63
|
+
|
|
64
|
+
The main extension retains profile/stack resolution and prompt preparation. A separate `pi-forge-subagents` extension owns delegation configuration, tools, commands, approval/progress UI, execution adaptation, and its dependency on `@zihanw/pi-subagent-runtime`.
|
|
65
|
+
|
|
66
|
+
The extraction must use a versioned Forge host port. It may not import internal runtime state, duplicate the active resource workspace, or make ordinary stack/profile usage depend on a subagent package.
|
|
67
|
+
|
|
68
|
+
Confirmed decisions:
|
|
69
|
+
|
|
70
|
+
- `@zihanw/pi-forge/subagent` remains a main-package entry point, but is cleaned into a versioned host port / host-neutral contract rather than re-exporting internal host preparation modules.
|
|
71
|
+
- The main package removes the hard dependency on `@zihanw/pi-subagent-runtime`; that dependency moves to `pi-forge-subagents` or becomes an optional peer dependency.
|
|
72
|
+
- The optional package may depend on the main package only through documented public ports.
|
|
73
|
+
|
|
74
|
+
### Schemas and public APIs restart deliberately
|
|
75
|
+
|
|
76
|
+
Prompt-stack schema v2 describes the cleaned compiler and template model. Agent-profile v2 is introduced only if its stored shape must change. The package no longer exports implementation modules through `src/*`; public surfaces are explicit entry points with documented stability.
|
|
77
|
+
|
|
78
|
+
## Confirmed 0.5.0 planning decisions
|
|
79
|
+
|
|
80
|
+
The following decisions were confirmed while this plan was in proposed status. Items still open are marked explicitly.
|
|
81
|
+
|
|
82
|
+
### Architecture direction
|
|
83
|
+
|
|
84
|
+
- A1: Target diagrams use port dependencies: `PromptStackService` / `AgentProfileService` depend on repository/host ports; `StackRepo` / `ProfileRepo` implement those ports.
|
|
85
|
+
- A2: Add an automatic dependency-direction check (`check:architecture`) during Phase 1/2.
|
|
86
|
+
- A3: When `src/*` exports are removed, update `scripts/check-package.mjs`, `docs/reference/public-api.md`, and public-API tests in the same change.
|
|
87
|
+
- A4: The release is referred to consistently as 0.5.0.
|
|
88
|
+
|
|
89
|
+
### Component ownership
|
|
90
|
+
|
|
91
|
+
- B1: `@zihanw/pi-forge/subagent` remains in the main package as a versioned host port / host-neutral contract, but its internal implementation surface is cleaned.
|
|
92
|
+
- B2: Remove the main package hard dependency on `@zihanw/pi-subagent-runtime`.
|
|
93
|
+
- B3: Forge extension loading/unloading and registry coordination are owned by `ForgeWorkspace`.
|
|
94
|
+
- B4: Tool-policy synchronization is defined as a port (`ToolPolicyPort`), called by `PromptStackService`; Pi adapter implements it.
|
|
95
|
+
- B5: Debug/payload/browser presentation state is a separate state slice, not part of the `ForgeWorkspace` resource snapshot.
|
|
96
|
+
|
|
97
|
+
### Schema and feature decisions
|
|
98
|
+
|
|
99
|
+
- B6: SillyTavern is removed completely from 0.5.0 core; 0.4 is the last supported conversion path.
|
|
100
|
+
- B7: Template language is still open; it will be decided after a spike.
|
|
101
|
+
- B8: Static reusable values are retained as immutable `parameters` in stack schema v2; the v1 `variables` codec inconsistency is fixed in v2.
|
|
102
|
+
- B9: Cross-extension host discovery will be decided after a focused spike; no final mechanism is assumed yet.
|
|
103
|
+
|
|
104
|
+
### Process decisions
|
|
105
|
+
|
|
106
|
+
- C1: Phase 0 produces an explicit inventory deliverable (for example `docs/design/0.5-inventory.md` or a comparable checklist).
|
|
107
|
+
- C2: Chinese documentation is updated for user-facing breaking changes; internal architecture documentation is not required to be fully synchronized.
|
|
108
|
+
- C3: No formal owner field is used; maintainer and agents together drive and review decisions.
|
|
109
|
+
|
|
110
|
+
## Current 0.4 architecture
|
|
111
|
+
|
|
112
|
+
```mermaid
|
|
113
|
+
flowchart TB
|
|
114
|
+
Pi["Pi host"] --> Entry["index.ts composition root"]
|
|
115
|
+
Entry --> Lifecycle["Lifecycle"]
|
|
116
|
+
Entry --> StackRuntime["Stack runtime"]
|
|
117
|
+
Entry --> ProfileRuntime["Profile runtime"]
|
|
118
|
+
Entry --> PolicyRuntime["Policy runtime"]
|
|
119
|
+
Entry --> WebRuntime["Web-editor runtime"]
|
|
120
|
+
Entry --> SubRuntime["Subagent runtime"]
|
|
121
|
+
|
|
122
|
+
State[("Shared PiForgeRuntimeState")]
|
|
123
|
+
Lifecycle --> State
|
|
124
|
+
StackRuntime --> State
|
|
125
|
+
ProfileRuntime --> State
|
|
126
|
+
PolicyRuntime --> State
|
|
127
|
+
WebRuntime --> State
|
|
128
|
+
SubRuntime --> State
|
|
129
|
+
|
|
130
|
+
StackRuntime --> StackLoader["Stack loader + validation"]
|
|
131
|
+
ProfileRuntime --> ProfileLoader["Profile loader + resolution"]
|
|
132
|
+
ProfileRuntime --> StackRuntime
|
|
133
|
+
StackRuntime --> ProfileRuntime
|
|
134
|
+
|
|
135
|
+
Lifecycle --> Compiler["Compiler"]
|
|
136
|
+
Compiler --> Macros["Stateful macros + variables"]
|
|
137
|
+
Compiler --> Slots["Slot registry"]
|
|
138
|
+
Compiler --> Regex["Regex transforms"]
|
|
139
|
+
|
|
140
|
+
WebRuntime --> WebHost["Web host"]
|
|
141
|
+
WebHost --> DirectIO["Direct stack filesystem mutations"]
|
|
142
|
+
WebHost --> ProfileService["Profile service"]
|
|
143
|
+
WebHost --> SubRuntime
|
|
144
|
+
|
|
145
|
+
SubRuntime --> SubHost["Forge host preparation"]
|
|
146
|
+
SubHost --> Compiler
|
|
147
|
+
SubRuntime --> ExternalRuntime["pi-subagent-runtime"]
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
The high-risk connections are shared state ownership, circular stack/profile coordination, direct persistence in adapters, and optional subagent concerns reaching the core editor and composition root.
|
|
151
|
+
|
|
152
|
+
## Target package and component architecture
|
|
153
|
+
|
|
154
|
+
```mermaid
|
|
155
|
+
flowchart TB
|
|
156
|
+
subgraph Main["@zihanw/pi-forge"]
|
|
157
|
+
PiAdapters["Pi lifecycle + command adapters"]
|
|
158
|
+
WebAdapters["HTTP + browser adapters"]
|
|
159
|
+
Workspace["ForgeWorkspace"]
|
|
160
|
+
StackService["PromptStackService"]
|
|
161
|
+
ProfileService["AgentProfileService"]
|
|
162
|
+
PiPorts["Pi runtime/environment adapters"]
|
|
163
|
+
|
|
164
|
+
PiAdapters --> Workspace
|
|
165
|
+
WebAdapters --> Workspace
|
|
166
|
+
Workspace --> StackService
|
|
167
|
+
Workspace --> ProfileService
|
|
168
|
+
ProfileService --> StackService
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
subgraph Core["@zihanw/pi-forge-core"]
|
|
172
|
+
ResourceCore["Scoped resources + catalogs"]
|
|
173
|
+
StackDomain["Prompt-stack schema + codec"]
|
|
174
|
+
ProfileDomain["Agent-profile schema + codec"]
|
|
175
|
+
Compiler["PromptCompiler"]
|
|
176
|
+
Templates["TemplateEngine registry"]
|
|
177
|
+
Diagnostics["Common diagnostics"]
|
|
178
|
+
Ports["Repository + host ports"]
|
|
179
|
+
|
|
180
|
+
Compiler --> StackDomain
|
|
181
|
+
Compiler --> Templates
|
|
182
|
+
StackDomain --> ResourceCore
|
|
183
|
+
ProfileDomain --> ResourceCore
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
subgraph Infra["Main extension infrastructure"]
|
|
187
|
+
StackRepo["PromptStackRepository"]
|
|
188
|
+
ProfileRepo["AgentProfileRepository"]
|
|
189
|
+
AtomicFiles["Atomic scoped file store"]
|
|
190
|
+
|
|
191
|
+
StackRepo --> AtomicFiles
|
|
192
|
+
ProfileRepo --> AtomicFiles
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
StackService --> StackDomain
|
|
196
|
+
StackService --> Compiler
|
|
197
|
+
StackService --> Ports
|
|
198
|
+
ProfileService --> ProfileDomain
|
|
199
|
+
ProfileService --> Ports
|
|
200
|
+
PiPorts --> Ports
|
|
201
|
+
StackRepo -.->|implements| Ports
|
|
202
|
+
ProfileRepo -.->|implements| Ports
|
|
203
|
+
|
|
204
|
+
subgraph Optional["pi-forge-subagents"]
|
|
205
|
+
SubAdapters["Commands + tools + approval UI"]
|
|
206
|
+
SubHost["ForgeHostPort client"]
|
|
207
|
+
SubRuntime["pi-subagent-runtime"]
|
|
208
|
+
|
|
209
|
+
SubAdapters --> SubHost
|
|
210
|
+
SubAdapters --> SubRuntime
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
Workspace -. "versioned host capability" .-> SubHost
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
`pi-forge-core` is host-neutral: it does not import the Pi extension API, HTTP, browser, TUI, or subagent runtime. If physical package extraction would delay boundary work, the same structure may land first as enforced internal modules and become a package before the subagent split.
|
|
217
|
+
|
|
218
|
+
## Target responsibilities
|
|
219
|
+
|
|
220
|
+
### ForgeWorkspace
|
|
221
|
+
|
|
222
|
+
- Own one immutable workspace snapshot containing scoped stack/profile catalogs and active selection/provenance references.
|
|
223
|
+
- Own Forge extension loading/unloading and registry coordination; coordinate resource reload and snapshot publication without circular runtime callbacks.
|
|
224
|
+
- Expose application services and resource-change subscriptions to adapters.
|
|
225
|
+
- Keep payload debugging and browser presentation state outside the resource snapshot.
|
|
226
|
+
|
|
227
|
+
### PromptStackService
|
|
228
|
+
|
|
229
|
+
- List, resolve, validate, create, update, fork, delete, activate, preview, and compile stacks.
|
|
230
|
+
- Own auto-activation selection and active-stack state transitions.
|
|
231
|
+
- Coordinate tool-policy changes through a `ToolPolicyPort` rather than calling UI, Pi API, or persistence code directly.
|
|
232
|
+
|
|
233
|
+
### AgentProfileService
|
|
234
|
+
|
|
235
|
+
- List, resolve, validate, create, update, delete, preflight, apply, and report provenance/drift.
|
|
236
|
+
- Apply model, thinking, and stack transactionally through a runtime-controller port.
|
|
237
|
+
- Resolve stack references through the workspace catalog, not through a separate loader.
|
|
238
|
+
|
|
239
|
+
### Repositories and codecs
|
|
240
|
+
|
|
241
|
+
- Repositories implement scoped discovery and safe mutation.
|
|
242
|
+
- Codecs are the only schema parsing, normalization, validation, serialization, and fingerprint source.
|
|
243
|
+
- Updates/deletes carry expected fingerprints to prevent overwriting unseen external changes.
|
|
244
|
+
- Filesystem writes use atomic replacement where the platform permits it.
|
|
245
|
+
|
|
246
|
+
### PromptCompiler and TemplateEngine
|
|
247
|
+
|
|
248
|
+
- Consume a normalized immutable `PromptEnvironment`, not a live Pi context.
|
|
249
|
+
- Return system prompt, prepared messages, sources, diagnostics, template dependencies, and an explicit variable/parameter receipt if parameters are retained.
|
|
250
|
+
- Keep history placement, structured runtime slots, tool/skill selection, and outgoing deterministic transforms as separate compiler stages.
|
|
251
|
+
- Use an engine contract with parse, analyze, and render operations. A restricted Jinja-like engine is a candidate, not yet an accepted dependency.
|
|
252
|
+
|
|
253
|
+
### Adapters
|
|
254
|
+
|
|
255
|
+
- Parse external input and render typed service results.
|
|
256
|
+
- Contain no resource persistence or duplicated schema validation.
|
|
257
|
+
- Browser view models and HTTP status mapping remain outside application/domain state.
|
|
258
|
+
|
|
259
|
+
## Proposed source layout
|
|
260
|
+
|
|
261
|
+
The exact filenames may evolve, but ownership should converge on:
|
|
262
|
+
|
|
263
|
+
```text
|
|
264
|
+
packages/
|
|
265
|
+
core/
|
|
266
|
+
src/resources/
|
|
267
|
+
src/prompt-stacks/
|
|
268
|
+
src/profiles/
|
|
269
|
+
src/compiler/
|
|
270
|
+
src/templates/
|
|
271
|
+
src/ports/
|
|
272
|
+
pi-forge/
|
|
273
|
+
src/application/
|
|
274
|
+
src/infrastructure/
|
|
275
|
+
src/adapters/pi/
|
|
276
|
+
src/adapters/commands/
|
|
277
|
+
src/adapters/web/
|
|
278
|
+
pi-forge-subagents/
|
|
279
|
+
src/host/
|
|
280
|
+
src/runtime/
|
|
281
|
+
src/adapters/commands/
|
|
282
|
+
src/adapters/tools/
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
Moving to a workspace is an implementation choice, not permission to move files before their interfaces and ownership are characterized.
|
|
286
|
+
|
|
287
|
+
## Feature disposition
|
|
288
|
+
|
|
289
|
+
| 0.4 capability | 0.5 disposition |
|
|
290
|
+
|---|---|
|
|
291
|
+
| Ordered prompt blocks and runtime slots | Keep and move into the v2 compiler |
|
|
292
|
+
| Scoped global/project resources | Keep behind common repositories/catalogs |
|
|
293
|
+
| Tool policy and model-visible skill filtering | Keep stack-owned |
|
|
294
|
+
| One-shot profiles, transactional apply, provenance, drift | Keep in `AgentProfileService` |
|
|
295
|
+
| Web stack/profile editor | Keep as adapters over services; simplify during migration |
|
|
296
|
+
| Prompt preview and redacted payload debugging | Keep; isolate debugging state |
|
|
297
|
+
| Turn/session variables and mutation macros | Remove |
|
|
298
|
+
| Static stack variables | Keep as immutable `parameters` in schema v2; fix the v1 string/JSON codec inconsistency |
|
|
299
|
+
| Current custom macro API | Break and replace with the template/slot extension contract |
|
|
300
|
+
| SillyTavern fidelity importer and regex emulation | Remove completely; 0.4 is the last supported conversion path |
|
|
301
|
+
| Regex history/compiled transforms | Keep initially; no new modes during 0.5 |
|
|
302
|
+
| Destructive finalized-transcript regex | Audit separately before schema v2 is frozen |
|
|
303
|
+
| Foreground subagent integration | Move to optional `pi-forge-subagents`; `@zihanw/pi-forge/subagent` remains as a versioned host port/contract |
|
|
304
|
+
| `src/*` package exports | Remove; update `check-package.mjs`, public API docs/tests in the same change |
|
|
305
|
+
| Legacy prompt-stack storage migration command | Remove after documenting the required pre-0.5 migration path |
|
|
306
|
+
|
|
307
|
+
## Implementation phases
|
|
308
|
+
|
|
309
|
+
### Phase 0: freeze and characterize
|
|
310
|
+
|
|
311
|
+
- Announce the 0.5 feature freeze in repository guidance and roadmap.
|
|
312
|
+
- Produce an explicit inventory deliverable covering public exports, persisted entries, commands, schemas, examples, and real internal consumers.
|
|
313
|
+
- Add characterization tests around any behavior that will move before changing ownership.
|
|
314
|
+
- Run the template-language spike and cross-extension host-discovery spike; record their findings before the affected phases start.
|
|
315
|
+
- Decide the remaining implementation gates listed under open decisions.
|
|
316
|
+
|
|
317
|
+
Exit: the removal/migration inventory is reviewed, and no unplanned feature work is in flight.
|
|
318
|
+
|
|
319
|
+
### Phase 1: resource core and repositories
|
|
320
|
+
|
|
321
|
+
- Introduce common diagnostic and loaded-resource envelopes.
|
|
322
|
+
- Extract stack/profile codecs.
|
|
323
|
+
- Implement repository ports and guarded filesystem repositories.
|
|
324
|
+
- Add the automatic dependency-direction check (`check:architecture`) so adapter/domain boundaries are enforced from this phase onward.
|
|
325
|
+
- Move all stack mutations out of `web-host.ts` and import commands.
|
|
326
|
+
|
|
327
|
+
Exit: every domain resource mutation uses a repository and has consistent stale-write/path-safety behavior.
|
|
328
|
+
|
|
329
|
+
### Phase 2: application services and workspace
|
|
330
|
+
|
|
331
|
+
- Consolidate stack operations into `PromptStackService`.
|
|
332
|
+
- Consolidate profile operations into `AgentProfileService`.
|
|
333
|
+
- Introduce `ForgeWorkspace` and publish coherent reload snapshots.
|
|
334
|
+
- Split debug/browser state away from resource state into a separate state slice.
|
|
335
|
+
- Replace circular stack/profile runtime wiring with workspace-owned services and ports.
|
|
336
|
+
|
|
337
|
+
Exit: commands, lifecycle, and web host use services; `PiForgeRuntimeState` is removed or reduced to adapter-owned state with no domain ownership.
|
|
338
|
+
|
|
339
|
+
### Phase 3: compiler and schema v2
|
|
340
|
+
|
|
341
|
+
- Define normalized `PromptEnvironment`, compiler result, and template-engine contracts.
|
|
342
|
+
- Remove mutable variables and session variable persistence.
|
|
343
|
+
- Select and implement the v2 template syntax.
|
|
344
|
+
- Make template dependency analysis authoritative.
|
|
345
|
+
- Decide the retained regex surface and freeze prompt-stack schema v2.
|
|
346
|
+
|
|
347
|
+
Exit: compilation is deterministic over immutable inputs, previews and runtime use the same entry point, and v1-to-v2 migration behavior is documented and tested.
|
|
348
|
+
|
|
349
|
+
### Phase 4: adapter cleanup
|
|
350
|
+
|
|
351
|
+
- Reduce Pi lifecycle modules to event adaptation.
|
|
352
|
+
- Reduce commands and HTTP handlers to parsing/result rendering.
|
|
353
|
+
- Split web view-model construction from application workflows.
|
|
354
|
+
- Remove SillyTavern surfaces from commands, web editor, docs, examples, and tests; update Chinese user docs for user-facing breaking changes.
|
|
355
|
+
|
|
356
|
+
Exit: dependency checks show adapters pointing inward with no direct resource persistence.
|
|
357
|
+
|
|
358
|
+
### Phase 5: subagent extraction and packages
|
|
359
|
+
|
|
360
|
+
- Validate cross-extension capability discovery with a focused spike.
|
|
361
|
+
- Publish the versioned Forge host port and clean `@zihanw/pi-forge/subagent` into that stable surface.
|
|
362
|
+
- Remove the main package hard dependency on `@zihanw/pi-subagent-runtime`.
|
|
363
|
+
- Move subagent configuration, commands, tools, UI, and runtime adaptation into `pi-forge-subagents`.
|
|
364
|
+
- Ensure main pi-forge installs and runs without subagent dependencies.
|
|
365
|
+
- Remove subagent UI/configuration from the core web editor unless an explicit contribution port is accepted.
|
|
366
|
+
|
|
367
|
+
Exit: ordinary stacks/profiles have no dependency on the optional package, and the optional extension consumes only documented public ports.
|
|
368
|
+
|
|
369
|
+
### Phase 6: public surface and release
|
|
370
|
+
|
|
371
|
+
- Replace root re-export sprawl with explicit package entry points.
|
|
372
|
+
- Remove `src/*` aliases and 0.4 compatibility barrels; update `check-package.mjs`, public API docs, and public API tests in the same change.
|
|
373
|
+
- Complete migration guide, changelog, package checks, and documentation rewrite; use 0.5.0 naming consistently.
|
|
374
|
+
- Run packed-install tests against supported Pi versions with and without `pi-forge-subagents`.
|
|
375
|
+
|
|
376
|
+
Exit: all release gates below pass.
|
|
377
|
+
|
|
378
|
+
## Open implementation-gate decisions
|
|
379
|
+
|
|
380
|
+
These are the remaining decisions that must be resolved before their affected implementation phases begin:
|
|
381
|
+
|
|
382
|
+
1. **Template language (spike completed; decision pending):** the Phase-0 [template-language spike](template-language-spike.md) rejects a broad Jinja-like engine and recommends a closed `forge-v1` AST grammar. Accept the exact grammar, environment schema, filter/condition set, extension-port disposition, schema representation, and migration behavior before Phase 3.
|
|
383
|
+
2. **Static parameters (decided):** retain a JSON-compatible immutable `parameters` object in stack schema v2; do not remove static reusable values.
|
|
384
|
+
3. **SillyTavern migration (decided):** complete removal; 0.4 is the last supported conversion path. No converter is retained in 0.5.0 core.
|
|
385
|
+
4. **Cross-extension host discovery (spike completed; decision pending):** the Phase-0 [Pi host-discovery spike](host-discovery-spike.md) validated Pi's shared in-process event bus across both extension load orders. It recommends a versioned, session-scoped event-bus RPC port with explicit duplicate-host detection and disposal; accept the protocol, operation catalogue, and package versioning before Phase 5.
|
|
386
|
+
5. **Pi session custom-entry versioning (open):** define explicit version, restoration, branch-navigation, malformed-entry, and migration semantics for prompt-stack selection and profile provenance entries. Define how removed variable entries are handled without recreating mutable state. Resolve before Phase 2/3 changes session restoration.
|
|
387
|
+
6. **Configuration ownership after subagent extraction (open):** `webEditor.*` remains owned by the main package. Decide whether `subagents.*`, which must be owned and written only by `pi-forge-subagents`, remains a namespaced section of `.pi/forge/config.json` or moves to dedicated optional-package configuration files; include migration and behavior when the optional package is absent. Resolve before Phase 4/5 changes configuration adapters.
|
|
388
|
+
7. **Final public-surface classification (open):** before Phase 6, use the Phase-0 inventory to classify every root and subpath surface as stable, experimental, internal, or removed; record named consumers, target entry points, and migration notices. Phase 6 must implement this accepted register rather than decide exports during removal.
|
|
389
|
+
8. **Pi compatibility policy (open):** define the minimum supported Pi version and rolling tested-version release matrix separately from wildcard host peers. Include packed main-only and main-plus-optional-package tests, plus a release-time npm `latest` probe. Resolve before Phase 1 establishes the supported CI matrix.
|
|
390
|
+
|
|
391
|
+
## Migration policy
|
|
392
|
+
|
|
393
|
+
- Provide a v1-to-v2 stack migration command or standalone script for mechanically convertible fields.
|
|
394
|
+
- Mutable variable behavior that cannot be preserved becomes an explicit migration diagnostic, not a silent approximation.
|
|
395
|
+
- Recommend running the final 0.4 release to convert legacy `.pi/prompt-stacks` storage before upgrading if 0.5 removes that migration command.
|
|
396
|
+
- Agent profiles retain IDs and scoped stack references where possible; migration rewrites only schema fields that actually change.
|
|
397
|
+
- SillyTavern users must convert with 0.4 before upgrading; 0.5.0 core does not retain a converter.
|
|
398
|
+
- No compatibility shim is accepted without a named consumer, test, warning/removal version, and owner.
|
|
399
|
+
|
|
400
|
+
## Release gates
|
|
401
|
+
|
|
402
|
+
0.5 is ready only when:
|
|
403
|
+
|
|
404
|
+
- dependency direction is checked automatically;
|
|
405
|
+
- all resource persistence is repository-owned;
|
|
406
|
+
- workspace reload and profile application have transactional/integration coverage;
|
|
407
|
+
- runtime and preview compilation share one compiler entry point;
|
|
408
|
+
- mutable variables and their persisted entries are removed or explicitly migrated;
|
|
409
|
+
- schema v2 and public entry points are documented without `src/*` exports;
|
|
410
|
+
- main pi-forge passes verification without installing the subagent extension/runtime;
|
|
411
|
+
- the optional subagent package passes host-version, preparation, approval, cancellation, and packed-install tests;
|
|
412
|
+
- current and target architecture diagrams match the implementation;
|
|
413
|
+
- English user documentation is updated and Chinese user-facing documentation is updated for breaking changes (internal architecture docs are not required to be fully synchronized);
|
|
414
|
+
- `npm run verify` and packed-install smoke tests pass on the documented Pi compatibility range.
|
|
415
|
+
|
|
416
|
+
## Deferred until after 0.5
|
|
417
|
+
|
|
418
|
+
- New prompt composition features.
|
|
419
|
+
- New import formats or high-fidelity external-preset emulation.
|
|
420
|
+
- Sandbox and staged subagent writes.
|
|
421
|
+
- Background/resumable agents, chains, queues, or orchestration.
|
|
422
|
+
- New web-editor surfaces unrelated to the migration.
|
|
423
|
+
- Additional regex or transcript-rewriting behavior.
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# Pi cross-extension host-discovery spike
|
|
2
|
+
|
|
3
|
+
[Design index](../../README.md) · [0.5 architecture plan](../../architecture-0.5.md) · [0.5 migration inventory](0.5-inventory.md)
|
|
4
|
+
|
|
5
|
+
Status: completed Phase 0 spike; architecture decision pending
|
|
6
|
+
|
|
7
|
+
Date: 2026-08-17
|
|
8
|
+
|
|
9
|
+
## Question
|
|
10
|
+
|
|
11
|
+
Can a separately installed `pi-forge-subagents` Pi extension reliably discover
|
|
12
|
+
and use the active main `pi-forge` extension without importing its internal
|
|
13
|
+
runtime state or relying on a process-global registry?
|
|
14
|
+
|
|
15
|
+
## Environment and method
|
|
16
|
+
|
|
17
|
+
- Tested against the repository's installed
|
|
18
|
+
`@earendil-works/pi-coding-agent` 0.83.0 fixture.
|
|
19
|
+
- Used Pi's exported `createEventBus`, `createExtensionRuntime`, and actual
|
|
20
|
+
`loadExtensionFromFactory` loader. The factories used only `pi.events`.
|
|
21
|
+
- This was an in-memory Phase-0 harness, not a shipped extension or production
|
|
22
|
+
host-port implementation.
|
|
23
|
+
|
|
24
|
+
The harness covered both extension load orders, compatible and incompatible
|
|
25
|
+
versions, and unregistering a host listener. All cases passed:
|
|
26
|
+
|
|
27
|
+
| Case | Result |
|
|
28
|
+
|---|---|
|
|
29
|
+
| Host factory loads before client factory | Client discovery receives one compatible host reply |
|
|
30
|
+
| Client factory loads before host factory | Client's availability listener receives the later host announcement |
|
|
31
|
+
| Client requires an unsupported version | No host is accepted |
|
|
32
|
+
| Host unregisters its listener | A subsequent discovery request receives no reply |
|
|
33
|
+
|
|
34
|
+
## Observations
|
|
35
|
+
|
|
36
|
+
1. `ExtensionAPI.events` is a shared event bus across extension factories
|
|
37
|
+
loaded into the same Pi runtime.
|
|
38
|
+
2. The bus exposes only `emit(channel, data)` and `on(channel, handler)`, with
|
|
39
|
+
an unsubscribe function. It does not expose a service registry, request
|
|
40
|
+
return values, sender identity, serialization, timeout, version negotiation,
|
|
41
|
+
duplicate-host handling, or lifecycle ownership.
|
|
42
|
+
3. Pi wraps each event handler in an asynchronous error boundary. `emit()` is
|
|
43
|
+
therefore fire-and-forget; callers must not depend on handler order or a
|
|
44
|
+
synchronous reply, even though a handler with no initial `await` may appear
|
|
45
|
+
to reply synchronously in a simple test.
|
|
46
|
+
4. The bus is in-process. It can coordinate packages loaded into one Pi
|
|
47
|
+
invocation, but it is not a cross-process, remote, or security boundary.
|
|
48
|
+
5. A direct import of a module-level workspace singleton remains unsuitable:
|
|
49
|
+
Pi package installation can produce independent package instances, and that
|
|
50
|
+
mechanism provides no duplicate-host or reload semantics.
|
|
51
|
+
|
|
52
|
+
## Recommended decision candidate
|
|
53
|
+
|
|
54
|
+
Use Pi's event bus as the transport for a **versioned, session-scoped Forge host
|
|
55
|
+
RPC protocol**. Do not use a process registry or a direct reference to
|
|
56
|
+
`ForgeWorkspace`.
|
|
57
|
+
|
|
58
|
+
The port must use plain, validated data messages rather than function callbacks
|
|
59
|
+
or the return value of `emit()`. A minimal protocol has these message families:
|
|
60
|
+
|
|
61
|
+
| Channel family | Direction | Required behavior |
|
|
62
|
+
|---|---|---|
|
|
63
|
+
| `@zihanw/pi-forge/host/v1/discover` | Client → host | Carries request ID, client identity/version, and supported protocol range |
|
|
64
|
+
| `@zihanw/pi-forge/host/v1/available` | Host → clients | Announces host ID, protocol version, capability set, and lifecycle generation after discovery listener registration |
|
|
65
|
+
| `@zihanw/pi-forge/host/v1/reply` | Host → client | Correlates discovery or operation result with request ID; carries typed success/failure data |
|
|
66
|
+
| `@zihanw/pi-forge/host/v1/request` | Client → host | Invokes only documented operations using validated request data |
|
|
67
|
+
| `@zihanw/pi-forge/host/v1/update` | Host → client | Optional bounded progress/resource-change events correlated to subscription or run IDs |
|
|
68
|
+
| `@zihanw/pi-forge/host/v1/unavailable` | Host → clients | Invalidates host ID/generation during disposal or replacement |
|
|
69
|
+
|
|
70
|
+
The final operation catalogue is still open, but must expose results and
|
|
71
|
+
snapshots—not Pi contexts, `ForgeWorkspace`, loaded resource objects, web-editor
|
|
72
|
+
state, callbacks, or internal registries. Cancellation must be a request by
|
|
73
|
+
run ID; it must not transfer `AbortSignal` objects through the port.
|
|
74
|
+
|
|
75
|
+
## Required protocol rules before implementation
|
|
76
|
+
|
|
77
|
+
- Clients subscribe to reply, availability, update, and unavailable events
|
|
78
|
+
before announcing/discovering; they use a bounded timeout and clean up all
|
|
79
|
+
listeners.
|
|
80
|
+
- A host registers discovery/request listeners before sending `available`.
|
|
81
|
+
- Host and client validate every message and ignore unknown protocol versions,
|
|
82
|
+
malformed payloads, stale generations, and unrelated request IDs.
|
|
83
|
+
- More than one live compatible host is an explicit `host.duplicate` failure;
|
|
84
|
+
the client must not silently choose a host by load order. Incompatible hosts
|
|
85
|
+
are reported distinctly.
|
|
86
|
+
- `ForgeWorkspace` owns host registration, generation, and disposal. On Pi
|
|
87
|
+
session shutdown/reload it sends `unavailable`, unregisters listeners, and
|
|
88
|
+
rejects new work; clients invalidate outstanding handles and report a clear
|
|
89
|
+
unavailable diagnostic.
|
|
90
|
+
- The port is an integration contract, not a trust boundary. Pi extensions
|
|
91
|
+
already execute in the same trusted process; the host must not transmit raw
|
|
92
|
+
credentials, arbitrary live contexts, or undeclared project data.
|
|
93
|
+
- The optional package must remain usable as an ordinary Pi extension only when
|
|
94
|
+
the main host is present and protocol-compatible. Its absence must leave the
|
|
95
|
+
main pi-forge extension fully functional.
|
|
96
|
+
|
|
97
|
+
## Limits and follow-up
|
|
98
|
+
|
|
99
|
+
This validates the event-bus transport in Pi 0.83.0 only. The Phase-0 Pi
|
|
100
|
+
compatibility gate still needs a documented range and packed-install matrix that
|
|
101
|
+
includes the release-time Pi version. The protocol, public operations, package
|
|
102
|
+
versioning, configuration ownership, and migration remain architecture decisions
|
|
103
|
+
to be accepted before Phase 5 implementation.
|