@zihanw/pi-forge 0.4.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +41 -1
- package/README.md +11 -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/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 +49 -81
- package/dist/index.js.map +1 -1
- package/dist/lifecycle.d.ts +6 -5
- package/dist/lifecycle.d.ts.map +1 -1
- package/dist/lifecycle.js +43 -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-command.d.ts +6 -6
- package/dist/payload-command.d.ts.map +1 -1
- package/dist/payload-command.js.map +1 -1
- package/dist/payload-state.d.ts +16 -0
- package/dist/payload-state.d.ts.map +1 -0
- package/dist/payload-state.js +14 -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 +17 -8
- 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 +3 -3
- package/dist/runtime/tool-policy-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/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/server.d.ts.map +1 -1
- package/dist/web-editor/server.js +1 -68
- 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 +13 -0
- package/dist/web-editor/styles.js.map +1 -1
- package/dist/web-editor/types.d.ts +0 -35
- package/dist/web-editor/types.d.ts.map +1 -1
- package/dist/web-host.d.ts +4 -2
- package/dist/web-host.d.ts.map +1 -1
- package/dist/web-host.js +32 -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 +6 -4
- package/docs/concepts/agent-profiles.md +1 -1
- package/docs/concepts/prompt-stacks.md +5 -5
- package/docs/design/README.md +21 -3
- package/docs/design/architecture-0.5.md +211 -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 +72 -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/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 +5 -9
- 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 +64 -17
- package/docs/reference/stack-schema.md +14 -9
- package/docs/reference/subagent-host-port.md +49 -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 +4 -4
- 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 +101 -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
|
+
# 0.5.0 Phase-0 decision drafts
|
|
2
|
+
|
|
3
|
+
[Design index](README.md) · [Architecture decision template](../../decision-template.md) · [Migration inventory](0.5-inventory.md)
|
|
4
|
+
|
|
5
|
+
Status: proposed drafts; requires maintainer acceptance
|
|
6
|
+
|
|
7
|
+
Date: 2026-08-17
|
|
8
|
+
|
|
9
|
+
This document packages the remaining Phase-0 choices for review. It does not
|
|
10
|
+
authorize code, schema, package, or persistence changes. Each accepted section
|
|
11
|
+
may become a focused architecture decision or an amendment to the 0.5 plan.
|
|
12
|
+
|
|
13
|
+
## D1: Pi compatibility and release matrix
|
|
14
|
+
|
|
15
|
+
### Candidate decision
|
|
16
|
+
|
|
17
|
+
Support Pi 0.83.0 as the initial documented minimum, because it is the checked
|
|
18
|
+
development fixture and supplies the extension/event APIs used by pi-forge.
|
|
19
|
+
Treat compatibility as a rolling list of explicitly tested Pi versions, not a
|
|
20
|
+
semver range inferred from wildcard peers. Test 0.83.0 and npm `latest` (0.84.2
|
|
21
|
+
when this draft was written) for every 0.5 release candidate, including packed
|
|
22
|
+
main-only and main-plus-optional-subagent installs. Keep Pi packages as wildcard
|
|
23
|
+
optional peers so Pi supplies one coherent SDK instance.
|
|
24
|
+
|
|
25
|
+
### Alternatives
|
|
26
|
+
|
|
27
|
+
- Claim every Pi version through a semver range: reject, because wildcard peers
|
|
28
|
+
and Pi's frequent 0.x releases do not prove behavioral compatibility.
|
|
29
|
+
- Pin Pi dependencies inside pi-forge: reject, because it risks duplicate Pi
|
|
30
|
+
runtimes and conflicts with Pi package loading.
|
|
31
|
+
|
|
32
|
+
### Acceptance evidence
|
|
33
|
+
|
|
34
|
+
Document exact tested versions, Node version, packed-install commands, and
|
|
35
|
+
main-only/optional-package results in release notes. Run a scheduled latest-Pi
|
|
36
|
+
probe that reports compatibility but does not silently widen the supported list.
|
|
37
|
+
|
|
38
|
+
## D2: Pi session custom-entry versioning
|
|
39
|
+
|
|
40
|
+
### Candidate decision
|
|
41
|
+
|
|
42
|
+
Keep the existing prompt-stack and profile custom entry types, but make every
|
|
43
|
+
newly written payload an envelope with `schemaVersion: 1`. Read unversioned 0.4
|
|
44
|
+
entries through explicit legacy decoders only; do not rewrite historical Pi JSONL
|
|
45
|
+
entries. Ignore unknown versions and malformed entries with a bounded diagnostic.
|
|
46
|
+
|
|
47
|
+
The latest valid entry in the active branch remains authoritative. Restoring a
|
|
48
|
+
selector or provenance must never apply a profile or mutate Pi runtime state.
|
|
49
|
+
`pi-forge-variable-state` is never restored or written in 0.5; its presence
|
|
50
|
+
produces one migration diagnostic per restoration, not a variable store.
|
|
51
|
+
|
|
52
|
+
### Alternatives
|
|
53
|
+
|
|
54
|
+
- Rename all custom entry types: reject unless a real collision requires it;
|
|
55
|
+
existing type names are useful migration anchors.
|
|
56
|
+
- Continue unversioned free-form payloads: reject; it violates the state rules.
|
|
57
|
+
- Automatically append replacement entries while restoring: reject; opening a
|
|
58
|
+
historical session must not mutate it.
|
|
59
|
+
|
|
60
|
+
### Acceptance evidence
|
|
61
|
+
|
|
62
|
+
Characterization tests cover legacy/current/unknown/malformed entries, branch
|
|
63
|
+
selection, compaction/tree navigation, missing resources, and no variable-state
|
|
64
|
+
resurrection.
|
|
65
|
+
|
|
66
|
+
## D3: configuration ownership after subagent extraction
|
|
67
|
+
|
|
68
|
+
### Candidate decision
|
|
69
|
+
|
|
70
|
+
The main package owns `webEditor.*` in `.pi/forge/config.json` and its global
|
|
71
|
+
equivalent. The optional package owns all subagent configuration, parsing,
|
|
72
|
+
validation, mutation, and diagnostics in dedicated
|
|
73
|
+
`.pi/forge/subagents.json` and `~/.pi/forge/subagents.json` files. Main pi-forge
|
|
74
|
+
does not read, write, validate, or surface subagent policy when the optional
|
|
75
|
+
package is absent.
|
|
76
|
+
|
|
77
|
+
The optional package may read the 0.4 `config.json.subagents` section only in a
|
|
78
|
+
one-time migration mode. It writes no automatic migration, preserves the legacy
|
|
79
|
+
section, and reports conflicts rather than merging silently.
|
|
80
|
+
|
|
81
|
+
### Alternatives
|
|
82
|
+
|
|
83
|
+
- Keep a shared `config.json` namespaced section: lower migration cost, but
|
|
84
|
+
creates shared-file coordination and leaves main-package ownership ambiguous.
|
|
85
|
+
- Preserve main-package parsing of `subagents.*`: reject; it contradicts the
|
|
86
|
+
optional package boundary.
|
|
87
|
+
|
|
88
|
+
### Acceptance evidence
|
|
89
|
+
|
|
90
|
+
Test absent optional package, untrusted project, project/global precedence,
|
|
91
|
+
legacy-config migration, conflict reporting, and deletion/config cleanup.
|
|
92
|
+
|
|
93
|
+
## D4: resource repositories and workspace snapshots
|
|
94
|
+
|
|
95
|
+
### Candidate decision
|
|
96
|
+
|
|
97
|
+
Repositories own all stack/profile discovery and mutation. A codec is the only
|
|
98
|
+
source of parse, normalize, validate, serialize, and content fingerprint logic.
|
|
99
|
+
Every write/delete receives an expected fingerprint when replacing an existing
|
|
100
|
+
resource; mismatch returns a typed conflict without writing.
|
|
101
|
+
|
|
102
|
+
`ForgeWorkspace` serializes reloads and publishes an immutable complete
|
|
103
|
+
snapshot with a monotonic revision. There is no filesystem watcher in 0.5:
|
|
104
|
+
explicit reload and existing lifecycle-driven reload are the only refresh paths.
|
|
105
|
+
Invalid/missing resources appear as diagnostics in the published snapshot, while
|
|
106
|
+
resolution and activation fail closed. A selected active resource that becomes
|
|
107
|
+
invalid or disappears is not active until a later complete reload resolves it.
|
|
108
|
+
|
|
109
|
+
Filesystem repositories use temp-file-plus-rename replacement where supported,
|
|
110
|
+
validate containment before every mutation, and clean failed temporary files.
|
|
111
|
+
|
|
112
|
+
### Alternatives
|
|
113
|
+
|
|
114
|
+
- Keep synchronous adapter writes: reject; it preserves duplicate persistence
|
|
115
|
+
workflows and bypasses consistent conflict handling.
|
|
116
|
+
- Publish each catalog independently: reject; profiles could resolve against a
|
|
117
|
+
different stack generation.
|
|
118
|
+
- Add file watching during the refactor: defer; it is a new state/lifecycle
|
|
119
|
+
feature outside 0.5 scope.
|
|
120
|
+
|
|
121
|
+
### Acceptance evidence
|
|
122
|
+
|
|
123
|
+
Test external edit conflicts, atomic-write failures, reload serialization,
|
|
124
|
+
mixed valid/invalid catalogs, scoped shadowing, active deletion, and consumers
|
|
125
|
+
never observing half a stack/profile graph.
|
|
126
|
+
|
|
127
|
+
## D5: profile-application transaction semantics
|
|
128
|
+
|
|
129
|
+
### Candidate decision
|
|
130
|
+
|
|
131
|
+
`AgentProfileService` resolves and validates model, authentication, thinking,
|
|
132
|
+
stack, and tool policy before any Pi mutation. It delegates mutations to a
|
|
133
|
+
runtime-controller port in this order: model, thinking level, active stack/tool
|
|
134
|
+
policy. It records provenance only after all three succeed.
|
|
135
|
+
|
|
136
|
+
On failure, the service compensates in reverse order using the captured prior
|
|
137
|
+
state and reports every failed compensation. This is a best-effort transaction,
|
|
138
|
+
not an atomic Pi-host transaction; an unset prior model that Pi cannot restore
|
|
139
|
+
is an explicit residual failure. Adapters render the typed result but do not
|
|
140
|
+
attempt their own rollback.
|
|
141
|
+
|
|
142
|
+
### Alternatives
|
|
143
|
+
|
|
144
|
+
- Call Pi setters directly from commands/web handlers: reject; it duplicates
|
|
145
|
+
transaction behavior.
|
|
146
|
+
- Describe this as atomic: reject; Pi setters have externally visible effects
|
|
147
|
+
and no common rollback primitive.
|
|
148
|
+
|
|
149
|
+
### Acceptance evidence
|
|
150
|
+
|
|
151
|
+
Integration tests cover each failure point, unexpected thinking-level clamp,
|
|
152
|
+
missing stack after preflight, rollback failure, provenance write timing, and
|
|
153
|
+
browser/command equivalence.
|
|
154
|
+
|
|
155
|
+
## D6: regex and v1-to-v2 migration
|
|
156
|
+
|
|
157
|
+
### Candidate decision
|
|
158
|
+
|
|
159
|
+
Retain deterministic outgoing `history` and `compiled` regex transforms in v2,
|
|
160
|
+
after schema characterization. Remove `display`/`both` as unsupported 0.4
|
|
161
|
+
configuration and remove destructive `finalize` transforms: they alter stored
|
|
162
|
+
assistant transcript after streaming and sit outside deterministic compilation.
|
|
163
|
+
|
|
164
|
+
Provide one explicit v1-to-v2 migration utility with dry-run default, per-file
|
|
165
|
+
diagnostics, no overwrite unless requested, backup/copy before replacement, and
|
|
166
|
+
no source deletion. It mechanically converts only documented safe fields and
|
|
167
|
+
emits error-level diagnostics for mutable variables, custom macros/slots,
|
|
168
|
+
removed regex effects, and unsupported template constructs. Users run the final
|
|
169
|
+
0.4 storage migration before the v2 utility; 0.5 does not retain the legacy
|
|
170
|
+
storage migration command.
|
|
171
|
+
|
|
172
|
+
### Alternatives
|
|
173
|
+
|
|
174
|
+
- Retain `finalize`: requires a separate persistent-transcript ownership and
|
|
175
|
+
previewability decision; defer rather than retain incidentally.
|
|
176
|
+
- Silently drop unsupported fields: reject; migration must make behavior loss
|
|
177
|
+
visible.
|
|
178
|
+
- Keep both legacy storage and v2 migration commands indefinitely: reject;
|
|
179
|
+
conflicts with the breaking-cleanup policy.
|
|
180
|
+
|
|
181
|
+
### Acceptance evidence
|
|
182
|
+
|
|
183
|
+
Fixture coverage proves dry runs do not write, conflicts/backups are explicit,
|
|
184
|
+
repeated runs are idempotent, and every removed field is reported. The final
|
|
185
|
+
0.4→0.5 user guide documents exact ordering and recovery.
|
|
186
|
+
|
|
187
|
+
## D7: physical package topology
|
|
188
|
+
|
|
189
|
+
### Candidate decision
|
|
190
|
+
|
|
191
|
+
Do not publish `pi-forge-core` in 0.5. Establish its boundaries as enforced
|
|
192
|
+
internal modules first. Publish only `@zihanw/pi-forge` and the optional
|
|
193
|
+
`pi-forge-subagents` package in Phase 5. The optional package uses documented
|
|
194
|
+
`@zihanw/pi-forge/subagent` host-port messages and Pi wildcard peers; it has no
|
|
195
|
+
dependency on core internals, web-editor modules, or a private copy of runtime
|
|
196
|
+
state. Extract core as a third package only after 0.5 if a named consumer proves
|
|
197
|
+
that package boundary necessary.
|
|
198
|
+
|
|
199
|
+
### Alternatives
|
|
200
|
+
|
|
201
|
+
- Introduce a workspace and three published packages immediately: reject; it
|
|
202
|
+
adds package/version/build complexity before interfaces are characterized.
|
|
203
|
+
- Let optional subagents import internal core modules: reject; it defeats the
|
|
204
|
+
host-port boundary.
|
|
205
|
+
|
|
206
|
+
### Acceptance evidence
|
|
207
|
+
|
|
208
|
+
Packed installs prove main pi-forge works with no subagent runtime/package, and
|
|
209
|
+
the optional package works only through the versioned host protocol.
|
|
210
|
+
|
|
211
|
+
## D8: final public surface
|
|
212
|
+
|
|
213
|
+
### Candidate decision
|
|
214
|
+
|
|
215
|
+
Use the public-surface register in the migration inventory as the Phase-6
|
|
216
|
+
allowlist. The root default extension remains stable. `/subagent` is the sole
|
|
217
|
+
versioned experimental host port. `src/*` aliases and root subagent re-exports
|
|
218
|
+
are removed. Resource/catalog/loader/profile helpers become internal unless the
|
|
219
|
+
consumer audit names a consumer and an intentional domain/service entry is
|
|
220
|
+
accepted. Macro/slot registration remains provisional pending the immutable
|
|
221
|
+
template/slot-port decision. Retain the two root documentation pointer files as
|
|
222
|
+
offline redirects in the 0.5 package unless the package documentation layout
|
|
223
|
+
otherwise provides a stable equivalent.
|
|
224
|
+
|
|
225
|
+
### Acceptance evidence
|
|
226
|
+
|
|
227
|
+
Update package exports, `files`, package checks, public-API tests, reference
|
|
228
|
+
docs, changelog, and migration guide in one Phase-6 change. Test rejection of
|
|
229
|
+
all removed subpaths from a packed install.
|
|
230
|
+
|
|
231
|
+
## Maintainer choices required
|
|
232
|
+
|
|
233
|
+
1. Accept, amend, or reject the host-RPC and `forge-v1` template spike
|
|
234
|
+
candidates.
|
|
235
|
+
2. Choose D3 dedicated subagent files versus a namespaced shared config file.
|
|
236
|
+
3. Choose D6 removal versus separately designed retention of `finalize` regex.
|
|
237
|
+
4. Accept/amend D1, D2, D4, D5, D7, and D8 before their affected phases.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# 0.5.0 full architecture proposal (archive)
|
|
2
|
+
|
|
3
|
+
Status: archived 2026-08-18 as the long-term target.
|
|
4
|
+
|
|
5
|
+
The active, executable 0.5.0 scope is now the [lean 0.5.0 architecture plan](../../architecture-0.5.md). The documents here were the original Phase-0 proposal and evidence base. They remain authoritative for the long-term target architecture, not for current 0.5.0 lane sequencing.
|
|
6
|
+
|
|
7
|
+
- [Full 0.5 architecture plan](architecture-0.5.md) — original six-phase target and release gates.
|
|
8
|
+
- [Migration inventory](0.5-inventory.md) — 0.4 surface characterization.
|
|
9
|
+
- [Public-consumer audit](0.5-consumer-audit.md) — known external consumer evidence.
|
|
10
|
+
- [Phase-0 decision drafts](0.5-phase0-decision-drafts.md) — original open decisions D1-D8.
|
|
11
|
+
- [Template-language spike](template-language-spike.md) — evidence behind `forge-v1`.
|
|
12
|
+
- [Pi host-discovery spike](host-discovery-spike.md) — evidence behind the event-bus host port.
|
|
@@ -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.
|