@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,156 @@
|
|
|
1
|
+
# Template-language and compiler 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
|
+
Which template language can replace 0.4 macros while keeping prompt compilation
|
|
12
|
+
deterministic over immutable inputs, statically analyzable, migrationable, and
|
|
13
|
+
free of arbitrary evaluation or template loading?
|
|
14
|
+
|
|
15
|
+
## Characterized 0.4 surface
|
|
16
|
+
|
|
17
|
+
The current macro language mixes four separate concerns:
|
|
18
|
+
|
|
19
|
+
| Concern | 0.4 behavior | 0.5 direction |
|
|
20
|
+
|---|---|---|
|
|
21
|
+
| Immutable runtime values | Latest user message, date/time, cwd, selected tools, active model | Keep as explicit values in `PromptEnvironment` |
|
|
22
|
+
| Static reusable values | `stack.variables`, referenced as `{{name}}` | Keep as JSON-compatible immutable `parameters` |
|
|
23
|
+
| Text transforms | `trim`, `upper`, `lower`, `json`, `xml`, including nesting | Retain only as a finite, pure filter set if accepted |
|
|
24
|
+
| Control flow | `ifvar`, `ifeq`, `iftools`, `ifslot`, with lazy branches | Replace only with a parsed, side-effect-free conditional form if accepted |
|
|
25
|
+
| Mutable state | Turn/session variables plus set/get/clear macros and `variables` slot | Remove; emit migration diagnostics |
|
|
26
|
+
| Executable extension code | Trusted custom macro and slot renderers receive live runtime objects | Replace only through a separately accepted, immutable template/slot port |
|
|
27
|
+
|
|
28
|
+
The current examples demonstrate simple parameter and runtime interpolation;
|
|
29
|
+
the image-reader and SillyTavern examples also depend on nested filters,
|
|
30
|
+
conditionals, and mutable variables. SillyTavern is already removed from 0.5
|
|
31
|
+
scope. Any remaining non-mechanical construct must be diagnosed by migration,
|
|
32
|
+
not silently approximated.
|
|
33
|
+
|
|
34
|
+
## Requirements
|
|
35
|
+
|
|
36
|
+
The v2 engine must provide one `parse → analyze → render` contract and meet all
|
|
37
|
+
of the following:
|
|
38
|
+
|
|
39
|
+
- parsing has no filesystem, network, process, clock, environment, or Pi access;
|
|
40
|
+
- rendering receives only a frozen normalized environment and parsed template;
|
|
41
|
+
- undefined paths, invalid filters, invalid conditions, parse errors, recursion,
|
|
42
|
+
and output-limit breaches are typed errors, never silent mutation or ambient
|
|
43
|
+
fallback;
|
|
44
|
+
- analysis returns source-spanned dependencies on environment paths, filters,
|
|
45
|
+
control predicates, and registered template/slot capabilities;
|
|
46
|
+
- no includes, extends, imports, macros, function calls, loops, arbitrary
|
|
47
|
+
property traversal, or general expression evaluation;
|
|
48
|
+
- whitespace is preserved unless a deliberately documented syntax construct
|
|
49
|
+
changes it; rendering has a bounded output size;
|
|
50
|
+
- preview, parent runtime, and subagent preparation invoke the same engine and
|
|
51
|
+
receive recorded environment/provenance values.
|
|
52
|
+
|
|
53
|
+
## Candidate comparison
|
|
54
|
+
|
|
55
|
+
| Candidate | Parse/analyze/render fit | Restriction and determinism | Migration fit | Result |
|
|
56
|
+
|---|---|---|---|---|
|
|
57
|
+
| General Jinja-like engine (Nunjucks) | Has parsing/rendering and strict-undefined option | Fails the trust requirement: its own documentation says it does not sandbox user-defined templates; it supports loaders, includes, extensions, async behavior, and a rich expression language | Familiar delimiters, but an unsafe/surplus language would need a fragile denylist | Reject |
|
|
58
|
+
| Restricted LiquidJS wrapper | Provides parsed templates and documented static analysis | Better parser option, but its Liquid tags, includes, filters, and plugin model would still require a security-sensitive allowlist/wrapper; syntax is not Jinja-compatible | Requires a new Liquid migration plus wrapper-specific dependency semantics | Do not adopt for 0.5 |
|
|
59
|
+
| Small Forge AST grammar | Contract is designed exactly for parse/analyze/render and the allowed syntax is closed | No ambient capabilities or loaders by construction; all values and filters are explicit | Breaking but small, predictable, and mechanically migrates common interpolation | Recommended candidate |
|
|
60
|
+
|
|
61
|
+
Nunjucks documents both its lack of sandboxing and its extensible loaders,
|
|
62
|
+
includes, custom tags, and asynchronous behavior. [Nunjucks API](https://mozilla.github.io/nunjucks/api.html)
|
|
63
|
+
LiquidJS documents parsed-template reuse and static analysis, but is a broader
|
|
64
|
+
Liquid language with tags and plugins rather than the deliberately closed v2
|
|
65
|
+
language. [LiquidJS static analysis](https://liquidjs.com/tutorials/static-analysis.html)
|
|
66
|
+
|
|
67
|
+
## Recommended decision candidate: `forge-v1`
|
|
68
|
+
|
|
69
|
+
Adopt a small parsed Forge template grammar. It resembles Jinja only at the
|
|
70
|
+
delimiter level; it must not claim Jinja compatibility.
|
|
71
|
+
|
|
72
|
+
### Closed grammar
|
|
73
|
+
|
|
74
|
+
```text
|
|
75
|
+
text := any text outside delimiters
|
|
76
|
+
output := "{{" path filters? "}}"
|
|
77
|
+
filters := ("|" filterName)*
|
|
78
|
+
if-block := "{% if" predicate "%}" template
|
|
79
|
+
("{% else %}" template)? "{% endif %}"
|
|
80
|
+
path := identifier ("." identifier)*
|
|
81
|
+
predicate := path | path "==" json-string | path "!=" json-string
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
The only initially proposed paths are `parameters.*` and documented
|
|
85
|
+
`runtime.*` fields. No bracket access, method invocation, object construction,
|
|
86
|
+
numeric arithmetic, loops, user-defined functions, imports, includes, extends,
|
|
87
|
+
macro definitions, or arbitrary expressions are in the grammar.
|
|
88
|
+
|
|
89
|
+
The initially proposed filters are `trim`, `upper`, `lower`, `json`, and `xml`.
|
|
90
|
+
They are pure, unary, versioned built-ins; unknown filters are errors. Tool and
|
|
91
|
+
slot conditions, if retained, must be represented as documented boolean values
|
|
92
|
+
in the environment rather than callable helpers. The exact v2 environment field
|
|
93
|
+
names remain part of the architecture decision.
|
|
94
|
+
|
|
95
|
+
### Engine contract
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
interface TemplateEngine {
|
|
99
|
+
readonly id: "forge-v1";
|
|
100
|
+
readonly version: 1;
|
|
101
|
+
parse(source: string): TemplateParseResult;
|
|
102
|
+
analyze(ast: TemplateAst): readonly TemplateDependency[];
|
|
103
|
+
render(ast: TemplateAst, environment: PromptEnvironment): TemplateRenderResult;
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
`PromptEnvironment` is a frozen, JSON-compatible snapshot. It must carry an
|
|
108
|
+
explicit timestamp and timezone/formatting policy, cwd, model identity, selected
|
|
109
|
+
tool facts, latest-user-message data, static parameters, and the Pi-derived
|
|
110
|
+
inputs required by slots as separate structured values. The compiler—not the
|
|
111
|
+
engine—owns history placement, structured slots, tool/skill policy, base-system
|
|
112
|
+
prompt handling, message assembly, and regex stages.
|
|
113
|
+
|
|
114
|
+
The render receipt must identify engine ID/version, template dependencies,
|
|
115
|
+
environment/provenance fingerprint, diagnostics, and output size. Dependencies
|
|
116
|
+
are authoritative for preview and subagent preparation; no consumer may
|
|
117
|
+
re-parse syntax independently.
|
|
118
|
+
|
|
119
|
+
### Extension boundary implication
|
|
120
|
+
|
|
121
|
+
The current `registerMacro()` API cannot cross this boundary unchanged because
|
|
122
|
+
it receives live runtime objects and can mutate or observe ambient state. The
|
|
123
|
+
template decision does not yet authorize a replacement API. If custom template
|
|
124
|
+
values, filters, or slots remain in 0.5, a separate accepted port must give them
|
|
125
|
+
only frozen input, declared dependency/capability metadata, bounded output, and
|
|
126
|
+
a pure-rendering contract. Trusted extension code is not a security boundary;
|
|
127
|
+
the core engine nevertheless must remain deterministic when no such extension
|
|
128
|
+
port participates.
|
|
129
|
+
|
|
130
|
+
## Migration disposition
|
|
131
|
+
|
|
132
|
+
| 0.4 construct | Candidate v2 migration | Result when not mechanical |
|
|
133
|
+
|---|---|---|
|
|
134
|
+
| `{{name}}` for a known static value | `{{ parameters.name }}` | Warn when name could be a custom macro or ambiguous |
|
|
135
|
+
| `{{lastUserMessage}}`, date/time, cwd, model, selected tools | Corresponding documented `runtime.*` path | Mechanical only after field names are accepted |
|
|
136
|
+
| Nested value filters | Equivalent output plus pipeline where semantics match | Diagnose when nested arguments or behavior differ |
|
|
137
|
+
| `ifvar` / `ifeq` | Parsed `if` predicate where semantics match | Diagnose `iftools`/`ifslot` until boolean environment fields are accepted |
|
|
138
|
+
| Custom macros and slots | New port only after its decision | Diagnose; no compatibility execution shim |
|
|
139
|
+
| Set/get/clear variable macros and `variables` slot | None | Error-level migration diagnostic; removed behavior |
|
|
140
|
+
| Unknown macros / unresolved-policy behavior | None | Error-level diagnostic in v2; no keep/warn rendering policy |
|
|
141
|
+
|
|
142
|
+
The migration tool must preserve the original source, produce a field/item-level
|
|
143
|
+
report, and refuse a partly transformed file unless the user explicitly accepts
|
|
144
|
+
diagnostics. It must not rewrite SillyTavern inputs in 0.5.
|
|
145
|
+
|
|
146
|
+
## Required acceptance and implementation evidence
|
|
147
|
+
|
|
148
|
+
Before Phase 3 implementation, accept the grammar, exact environment schema,
|
|
149
|
+
filter/condition set, undefined/error semantics, output limits, engine ID in
|
|
150
|
+
stack schema v2, extension-port disposition, and migration behavior.
|
|
151
|
+
|
|
152
|
+
Implementation then needs characterization and conformance coverage for parser
|
|
153
|
+
errors, source spans, strict undefined values, filters, nested/else conditionals,
|
|
154
|
+
whitespace, output limits, deterministic repeated render, dependency receipts,
|
|
155
|
+
preview/runtime identity, and migration diagnostics for every removed mutable or
|
|
156
|
+
custom-macro construct.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Context Diff — design plan (post-0.5.0)
|
|
2
|
+
|
|
3
|
+
Status: folded into `docs/design/0.5.1-plan.md` as Lane 2 — that file is now the owner of truth. Kept for discussion history.
|
|
4
|
+
|
|
5
|
+
Implemented follow-up: the dock now provides git-style line diffs and correlates
|
|
6
|
+
captured requests with Pi's assistant usage. The structural cache-prefix figure
|
|
7
|
+
remains a chars/4 estimate; provider-reported cache hit rate is shown separately
|
|
8
|
+
and is unavailable until cache reporting is observed for that provider/model.
|
|
9
|
+
|
|
10
|
+
Original status: planned. Target release: 0.5.1 (first feature release after 0.5.0).
|
|
11
|
+
|
|
12
|
+
## Goal
|
|
13
|
+
|
|
14
|
+
Per-turn observability for prompt changes so users can optimize KV-cache reuse:
|
|
15
|
+
|
|
16
|
+
- Mark which blocks of the prompt changed after each turn.
|
|
17
|
+
- Show how many tokens were added/removed/modified (delta vs the previous turn).
|
|
18
|
+
- Mark where the KV-cache prefix survives ("cache boundary").
|
|
19
|
+
|
|
20
|
+
Secondary goal: merge with live preview — while editing a stack, debounce-compile and diff against the previous compile, so edits show their prompt/token impact immediately.
|
|
21
|
+
|
|
22
|
+
## Existing building blocks
|
|
23
|
+
|
|
24
|
+
- `src/payload-capture.ts` — captures the real provider request payload (secret-redacted), with `approxTokens` (chars/4) estimation. `SAFE_TOKEN_METADATA_KEYS` already whitelists `cached_tokens` etc., so real cache-hit numbers can be surfaced if response usage ever becomes available.
|
|
25
|
+
- `src/preview.ts` — edit-time compile output split into sections (system + per-message), each with chars/approxTokens.
|
|
26
|
+
- Legacy editor already polls payload state every 2s.
|
|
27
|
+
|
|
28
|
+
## Two data sources
|
|
29
|
+
|
|
30
|
+
| Scenario | Source | Question answered |
|
|
31
|
+
|---|---|---|
|
|
32
|
+
| Edit time (live preview merge point) | debounced compile vs previous compile | "what does this edit change, how many tokens" |
|
|
33
|
+
| Run time (KV-cache truth) | diff of consecutive real payloads | "where did the cache break, how many extra tokens this turn" |
|
|
34
|
+
|
|
35
|
+
## Core engine: `src/context-diff.ts` (host-neutral pure functions)
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
TurnSnapshot { turnId, capturedAt, stackId, blocks: Block[] }
|
|
39
|
+
Block { key, role, text, chars, approxTokens, hash }
|
|
40
|
+
TurnDiff { blocks: DiffBlock[], prefixTokens, prefixRatio, deltaTokens, summary }
|
|
41
|
+
DiffBlock { status: same|added|removed|modified, before?, after?, tokenDelta }
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Cache-boundary algorithm: KV-cache hits depend on the longest common prefix of the serialized request. Walk the block arrays in order while hashes match; at the first mismatch, trim a char-level common prefix inside that block and convert to tokens. Render a boundary marker: "cache valid up to ~18,204 tokens (63% of prompt)". No Myers diff needed — prefix + block classification suffices.
|
|
45
|
+
|
|
46
|
+
Honesty note: tokens are chars/4 estimates. Relative deltas are accurate; absolute boundary claims must be labeled "approx" in UI and in promo material.
|
|
47
|
+
|
|
48
|
+
## UI
|
|
49
|
+
|
|
50
|
+
Promote the Preview modal into a dockable right-side panel with two tabs:
|
|
51
|
+
|
|
52
|
+
- **Compiled** — current preview content, auto-refresh with 500ms debounce while editing (this is the live preview).
|
|
53
|
+
- **Diff** — top summary strip (`Turn N · +412 tokens vs previous · cache boundary ~63% · 2 blocks changed`), block list with green/red/yellow gutters and per-block token chips, scissor-line boundary marker.
|
|
54
|
+
|
|
55
|
+
Run-time mode: payload poll captures a new payload → store in rolling history (last 20 turns) → auto-compute diff.
|
|
56
|
+
Edit mode: diff current edited compile vs the active on-disk version.
|
|
57
|
+
|
|
58
|
+
Implementation constraint: write the panel as a self-contained Vue component bridged in via the vue-host mechanism. Do NOT add more imperative code to `legacy-editor.ts`. Do NOT refactor the legacy editor in the same lane.
|
|
59
|
+
|
|
60
|
+
## Phases / estimate
|
|
61
|
+
|
|
62
|
+
| Phase | Content | Effort |
|
|
63
|
+
|---|---|---|
|
|
64
|
+
| 0 | Design freeze + golden fixtures (turn payload sets) | 0.5d |
|
|
65
|
+
| 1 | `context-diff.ts` engine + unit tests (prefix/add/remove/modify/token rollups) | 1d |
|
|
66
|
+
| 2 | Server endpoint + rolling snapshot state on the web host | 0.5d |
|
|
67
|
+
| 3 | Web UI: preview dock + Diff view (self-contained Vue, bridged) | 1.5d |
|
|
68
|
+
| 4 | Browser tests + docs + changelog | 0.5–1d |
|
|
69
|
+
|
|
70
|
+
Total ~4–5 working days; ~1 calendar week with review. Descope option (~3d): run-time diff only, live preview reduced to plain auto-refresh without edit-time diffing.
|
|
71
|
+
|
|
72
|
+
## Release narrative
|
|
73
|
+
|
|
74
|
+
Do not fold into 0.5.0 — 0.5.0 ships as the architecture-split release; context diff headlines 0.5.1 as "observability". The promo video leads with this feature (money shot: edit one system-prompt line, watch the cache-boundary marker jump to the top).
|
|
75
|
+
|
|
76
|
+
## Promo video pipeline (reference: AIGC/VIDEO_PRODUCTION ep02)
|
|
77
|
+
|
|
78
|
+
Reuse the ep02 pipeline: `PLAN.md` → script draft → `narration.json` (production source of truth) → roughcut → review. Terminology follows the ep02 rule: say it in plain words first, name the formal term once ("KV cache" on first mention, then "prefix cache / cache reuse region").
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Architecture decision: title
|
|
2
|
+
|
|
3
|
+
[Design index](README.md)
|
|
4
|
+
|
|
5
|
+
Status: proposed
|
|
6
|
+
|
|
7
|
+
Date: YYYY-MM-DD
|
|
8
|
+
|
|
9
|
+
Owners: maintainer names or roles
|
|
10
|
+
|
|
11
|
+
## Context
|
|
12
|
+
|
|
13
|
+
Describe the concrete problem, current constraints, and evidence that a decision is needed.
|
|
14
|
+
|
|
15
|
+
## Decision
|
|
16
|
+
|
|
17
|
+
State the chosen behavior and ownership boundary precisely. Include a small interface or diagram when it makes the boundary easier to verify.
|
|
18
|
+
|
|
19
|
+
## Consequences
|
|
20
|
+
|
|
21
|
+
Describe what becomes easier, what becomes harder or impossible, and which compatibility or operational costs are accepted.
|
|
22
|
+
|
|
23
|
+
## Migration
|
|
24
|
+
|
|
25
|
+
List the implementation order, compatibility period if any, user migration, and removal condition for temporary shims.
|
|
26
|
+
|
|
27
|
+
## Alternatives considered
|
|
28
|
+
|
|
29
|
+
Record the serious alternatives and why they were rejected. Do not use this section to restate obviously inferior options.
|
|
30
|
+
|
|
31
|
+
## Verification
|
|
32
|
+
|
|
33
|
+
Define the tests, dependency checks, documentation, and release evidence that prove the decision was implemented.
|
|
@@ -10,7 +10,7 @@ This file was the forward-looking product roadmap during 0.4 development. Comple
|
|
|
10
10
|
- [Feature inventory](../reference/features.md): implemented profile, prompt-stack, web-editor, payload, extension, packaging, and experimental subagent behavior.
|
|
11
11
|
- [Changelog](../../CHANGELOG.md): release and unreleased change history.
|
|
12
12
|
- [Subagent interface design](subagents/interface-design.md): accepted request/response architecture, context model, responsibility boundaries, and implementation history.
|
|
13
|
-
-
|
|
13
|
+
- Subagent adapter contract: the 0.4 exported contract documented the execution surface that moved to `@zihanw/pi-forge-subagents` in 0.5; see the [subagent host port contract](../reference/subagent-host-port.md) for the current boundary.
|
|
14
14
|
- [SDK spike findings](subagents/sdk-spike-findings.md): historical real Pi SDK findings for model/auth resolution, exact prompt preparation, dynamic tools, media, timeout, and cleanup.
|
|
15
15
|
- [Subagent design review](subagents/design-review.md): issues that drove resolution, preflight, enforcement, task-preservation, fingerprint, and response revisions.
|
|
16
16
|
- [Public API policy](../reference/public-api.md): stable, experimental, and internal compatibility surfaces.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Subagent request/response design
|
|
2
2
|
|
|
3
|
-
Status: historical design and implementation record for the completed 0.4 path. Execution ownership (backend registry, preflight binding, plan sealing, conversation/execution fingerprints, lifecycle, and the fresh-process `pi-subprocess-readonly`/`pi-rpc-readonly` backends) lives in `@zihanw/pi-subagent-runtime`; the former in-package registry and `pi-sdk-isolated` compatibility backend were removed in that migration. The broader Pi SDK spike is recorded in the [SDK spike findings](sdk-spike-findings.md) (harness since removed), and the
|
|
3
|
+
Status: historical design and implementation record for the completed 0.4 path. Execution ownership (backend registry, preflight binding, plan sealing, conversation/execution fingerprints, lifecycle, and the fresh-process `pi-subprocess-readonly`/`pi-rpc-readonly` backends) lives in `@zihanw/pi-subagent-runtime`; the former in-package registry and `pi-sdk-isolated` compatibility backend were removed in that migration. The broader Pi SDK spike is recorded in the [SDK spike findings](sdk-spike-findings.md) (harness since removed), and the 0.5 boundary is documented in the [subagent host port contract](../../reference/subagent-host-port.md).
|
|
4
4
|
|
|
5
5
|
## Goals
|
|
6
6
|
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# Architecture and development rules
|
|
2
|
+
|
|
3
|
+
[Documentation](../README.md) · [0.5 architecture plan](../design/architecture-0.5.md)
|
|
4
|
+
|
|
5
|
+
These rules keep implementation throughput from outrunning architectural understanding. They apply to humans and coding agents. The intent is not to slow local implementation; it is to make boundary changes scarce, explicit, and reviewable.
|
|
6
|
+
|
|
7
|
+
## Decision authority
|
|
8
|
+
|
|
9
|
+
Implementation may move quickly inside an accepted boundary. A change to a boundary, persistent model, public contract, or product concept requires an explicit design decision before implementation.
|
|
10
|
+
|
|
11
|
+
Agents may draft decisions, diagrams, interfaces, migration plans, and implementation slices. A human maintainer accepts the decision and its tradeoffs.
|
|
12
|
+
|
|
13
|
+
## Development mode for 0.5
|
|
14
|
+
|
|
15
|
+
Until the 0.5 release gates are complete:
|
|
16
|
+
|
|
17
|
+
- Feature development is frozen unless the feature is explicitly added to the 0.5 plan.
|
|
18
|
+
- Only one boundary-changing initiative should be active at a time.
|
|
19
|
+
- Simplification and removal are preferred over compatibility layers without a demonstrated consumer.
|
|
20
|
+
- A completed slice must leave the repository in a coherent, documented, verified state; partial architecture migrations must not silently become permanent.
|
|
21
|
+
|
|
22
|
+
## Required dependency direction
|
|
23
|
+
|
|
24
|
+
```mermaid
|
|
25
|
+
flowchart LR
|
|
26
|
+
Adapters["Adapters<br/>Pi lifecycle · commands · HTTP · browser"]
|
|
27
|
+
Application["Application<br/>ForgeWorkspace · stack/profile services"]
|
|
28
|
+
Domain["Domain/core<br/>schemas · catalogs · compiler · templates"]
|
|
29
|
+
Ports["Ports<br/>repositories · runtime controller · host capabilities"]
|
|
30
|
+
Infrastructure["Infrastructure<br/>filesystem · Pi SDK · process registry"]
|
|
31
|
+
|
|
32
|
+
Adapters --> Application
|
|
33
|
+
Application --> Domain
|
|
34
|
+
Application --> Ports
|
|
35
|
+
Infrastructure --> Ports
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Infrastructure implements inward-facing ports. Domain/core code must not import adapters or infrastructure implementations.
|
|
39
|
+
|
|
40
|
+
Until the target directory/package structure exists, apply the rule to logical ownership rather than relying on current file locations.
|
|
41
|
+
|
|
42
|
+
## Component rules
|
|
43
|
+
|
|
44
|
+
### Domain and compiler
|
|
45
|
+
|
|
46
|
+
- Domain types contain no command, HTTP, browser, TUI, or filesystem behavior.
|
|
47
|
+
- Prompt compilation consumes a normalized, immutable prompt environment rather than a live Pi context.
|
|
48
|
+
- Compilation returns prompt output, diagnostics, dependencies, and any explicit state transition. Renderers must not silently mutate shared state.
|
|
49
|
+
- Template dependency analysis is part of the template-engine contract; subagents and previews must not reverse-engineer template syntax independently.
|
|
50
|
+
- Tool policy remains stack-owned. Profiles may reference a stack but must not duplicate the policy.
|
|
51
|
+
|
|
52
|
+
### Application services
|
|
53
|
+
|
|
54
|
+
- `ForgeWorkspace` owns a coherent workspace snapshot and coordinates resource reloads.
|
|
55
|
+
- `PromptStackService` owns stack resolution, mutation, activation, validation, and preview/compile entry points.
|
|
56
|
+
- `AgentProfileService` owns profile resolution, mutation, preflight, transactional application, provenance, and drift.
|
|
57
|
+
- Services expose typed results. Adapters translate those results into command messages, HTTP statuses, and UI view models.
|
|
58
|
+
|
|
59
|
+
### Persistence
|
|
60
|
+
|
|
61
|
+
- All profile and stack reads/writes/deletes go through repositories.
|
|
62
|
+
- Repositories use codecs as the single source of parsing, normalization, validation, and serialization.
|
|
63
|
+
- Mutations validate scope and containment. No adapter may call `writeFileSync` or `unlinkSync` for a domain resource.
|
|
64
|
+
- **Lean 0.5.0 interim:** repositories and codecs are introduced in minimal form. Expected-fingerprint writes, fingerprinting in codecs, and guaranteed atomic file replacement are 0.5.x work. Current replacement semantics remain characterized by tests until then.
|
|
65
|
+
|
|
66
|
+
### State
|
|
67
|
+
|
|
68
|
+
- Every mutable value has one named owner.
|
|
69
|
+
- Debug payload capture, browser presentation state, prompt resource state, and session provenance are separate state slices.
|
|
70
|
+
- Reload produces a complete snapshot before publishing it. Consumers must not observe a half-reloaded stack/profile graph.
|
|
71
|
+
- New session-persisted state requires a version, restoration semantics, migration behavior, and an architecture decision.
|
|
72
|
+
|
|
73
|
+
### Adapters and optional packages
|
|
74
|
+
|
|
75
|
+
- Commands and HTTP handlers parse input, invoke an application service, and render a result; they do not implement domain workflows.
|
|
76
|
+
- Browser view models must not leak into core runtime state.
|
|
77
|
+
- Optional extensions use versioned host ports and fail clearly when the required host version is unavailable.
|
|
78
|
+
- `pi-forge-subagents` must not load an independent conflicting copy of the active Forge workspace or reach into pi-forge internals.
|
|
79
|
+
|
|
80
|
+
### Public APIs
|
|
81
|
+
|
|
82
|
+
- Public API is an allowlist of package entry points, not a side effect of file placement.
|
|
83
|
+
- The 0.5 release removes the broad `src/*` compatibility surface.
|
|
84
|
+
- A public type should describe a stable domain or port, not an internal runtime object.
|
|
85
|
+
- Breaking changes belong in the changelog and the 0.5 migration guide.
|
|
86
|
+
|
|
87
|
+
## Change classification
|
|
88
|
+
|
|
89
|
+
### Local change
|
|
90
|
+
|
|
91
|
+
A local change stays within one accepted component and preserves schemas, state ownership, dependency direction, and public behavior. It needs focused tests and ordinary review.
|
|
92
|
+
|
|
93
|
+
Examples include fixing a renderer, improving a view mapper, or extracting a private helper within one service.
|
|
94
|
+
|
|
95
|
+
### Boundary-affecting change
|
|
96
|
+
|
|
97
|
+
A boundary-affecting change moves responsibility, adds a dependency across components, changes an application port, or introduces a new state owner. It requires an accepted architecture decision or an amendment to the 0.5 plan.
|
|
98
|
+
|
|
99
|
+
### Product-affecting change
|
|
100
|
+
|
|
101
|
+
A product-affecting change adds/removes a feature, changes a schema, alters persistence or trust semantics, or changes a public API/package. It requires an accepted decision, migration notes, documentation updates, and explicit human review.
|
|
102
|
+
|
|
103
|
+
## Architecture-decision triggers
|
|
104
|
+
|
|
105
|
+
An architecture decision is required when changing any of the following:
|
|
106
|
+
|
|
107
|
+
- package or extension boundaries;
|
|
108
|
+
- JSON schemas or persisted session entries;
|
|
109
|
+
- public exports or compatibility promises;
|
|
110
|
+
- `ForgeWorkspace` or another state owner;
|
|
111
|
+
- compiler/template semantics;
|
|
112
|
+
- filesystem repository guarantees;
|
|
113
|
+
- trust, approval, tool-policy, or provider-egress boundaries;
|
|
114
|
+
- cross-extension discovery;
|
|
115
|
+
- removal or addition of a product-level feature.
|
|
116
|
+
|
|
117
|
+
Use the [architecture decision template](../design/decision-template.md). Small decisions can amend the active 0.5 plan instead of creating a separate document if the alternatives and consequences remain clear.
|
|
118
|
+
|
|
119
|
+
## Pull-request requirements
|
|
120
|
+
|
|
121
|
+
During lean 0.5.0, every pull request states summary, breaking impact, and verification, as in the repository template. Boundary- or product-affecting changes must link to the accepted decision in the [lean 0.5 plan](../design/architecture-0.5.md); a separate decision document is not required for decisions already accepted there.
|
|
122
|
+
|
|
123
|
+
For full-target 0.5.x work, pull requests additionally state change classification, affected components, dependency-direction/state/schema/public-API impact, and the linked decision.
|
|
124
|
+
|
|
125
|
+
## Definition of done
|
|
126
|
+
|
|
127
|
+
A slice is complete when:
|
|
128
|
+
|
|
129
|
+
1. Ownership and dependency direction match the accepted architecture.
|
|
130
|
+
2. Behavior is covered at the narrowest useful level; cross-adapter behavior has integration coverage.
|
|
131
|
+
3. No domain persistence remains in command, HTTP, or browser-host adapters.
|
|
132
|
+
4. Public and persisted changes include migration notes.
|
|
133
|
+
5. Current and target documentation reflect any moved boundary.
|
|
134
|
+
6. Generated artifacts are synchronized.
|
|
135
|
+
7. `npm run verify` passes for release-sized or cross-cutting work.
|
|
136
|
+
|
|
137
|
+
## Review stop conditions
|
|
138
|
+
|
|
139
|
+
Stop and request architectural review when an implementation needs to:
|
|
140
|
+
|
|
141
|
+
- import an adapter from domain/application code;
|
|
142
|
+
- access `PiForgeRuntimeState` from a new component;
|
|
143
|
+
- add mutable template variables or render-time side effects;
|
|
144
|
+
- write a resource outside a repository;
|
|
145
|
+
- add a wildcard export;
|
|
146
|
+
- duplicate profile/stack loading in another extension;
|
|
147
|
+
- retain a compatibility layer with no named consumer or removal date;
|
|
148
|
+
- introduce a second boundary-changing initiative before the current one is complete.
|
|
@@ -6,12 +6,18 @@
|
|
|
6
6
|
|
|
7
7
|
1. Confirm the changelog and user documentation describe the intended version and experimental surfaces accurately.
|
|
8
8
|
2. Publish and smoke-test any required `@zihanw/pi-subagent-runtime` version first.
|
|
9
|
-
3. Install dependencies from the lockfile and run `npm run verify
|
|
9
|
+
3. Install dependencies from the lockfile and run `npm run verify`; require the
|
|
10
|
+
Ubuntu, macOS, and Windows GitHub Actions jobs to pass for the release commit.
|
|
10
11
|
4. Test a packed installation against the documented minimum and current Pi versions.
|
|
11
12
|
5. Exercise ordinary stack/profile use independently of delegation.
|
|
12
13
|
6. Exercise both configured foreground backends and confirm unsupported host capabilities fail closed before provider transport.
|
|
13
14
|
7. Inspect `npm pack --dry-run` for package size and unexpected or missing files.
|
|
14
15
|
|
|
16
|
+
The macOS and Windows jobs run the same complete verification surface as Linux,
|
|
17
|
+
including the real-browser editor suite against the hosted runner's system
|
|
18
|
+
Chrome. Compatibility-version and scheduled latest-Pi probes remain Linux-only;
|
|
19
|
+
they test dependency drift rather than operating-system behavior.
|
|
20
|
+
|
|
15
21
|
## Dependency policy
|
|
16
22
|
|
|
17
23
|
Published manifests use wildcard peer dependencies for Pi-host-provided SDK packages. Exact versions belong in development dependencies and the lockfile so tests are reproducible without restricting compatible host releases.
|
|
@@ -4,6 +4,37 @@
|
|
|
4
4
|
|
|
5
5
|
This file contains forward-looking product work only. Completed capability belongs in the [feature inventory](../reference/features.md), release history in the root [changelog](../../CHANGELOG.md), and completed investigation in the [design archive](../design/README.md).
|
|
6
6
|
|
|
7
|
+
## 0.5.0 breaking cleanup (lean)
|
|
8
|
+
|
|
9
|
+
0.5.0 is a deliberately breaking cleanup release plus the minimum foundation for 0.5.x. Net-new feature work is frozen.
|
|
10
|
+
|
|
11
|
+
The authoritative scope, accepted decisions, implementation lanes, and release gates are in the [lean 0.5 architecture plan](../design/architecture-0.5.md). The original six-phase architecture target remains the long-term goal and is archived in the [full proposal](../design/archive/0.5-full-proposal/README.md).
|
|
12
|
+
|
|
13
|
+
Implementation order:
|
|
14
|
+
|
|
15
|
+
0. Documentation convergence: archive the full proposal and make the lean plan active.
|
|
16
|
+
1a. Removals only: remove SillyTavern, mutable variable state/macros/slot, variable session entries, and regex `display`/`both`.
|
|
17
|
+
1b. Compiler, schema v2, and extension contract: implement `forge-v1`, frozen `PromptEnvironment`, immutable `parameters`, and the redesigned trusted extension port; retain `finalize` under lifecycle-adapter ownership.
|
|
18
|
+
1c. Migration and documentation: v1-to-v2 utility, example migration, and English/Chinese breaking notes.
|
|
19
|
+
1d. Compiler/extension conformance: pure slot contract symmetry, slot dependency resolution, shared dependency analysis/compilation context, lazy extension evaluation, nested conditionals, parser fixes, and focused conformance tests.
|
|
20
|
+
2a. Minimal repositories and codecs: make repositories/codecs the only stack/profile read/write path; defer fingerprint and atomic writes.
|
|
21
|
+
2b. ForgeWorkspace and host port v1: minimal snapshot owner plus `/subagent` discovery, profile listing/snapshot, and prepare with mandatory lifecycle semantics.
|
|
22
|
+
3. Subagent extraction: move subagent code into `pi-forge-subagents`; remove the main-package hard dependency and delegation UI; optional package owns dedicated `subagents.json` files.
|
|
23
|
+
3.5. Host-neutrality hardening: host-neutral prompt compiler, `ForgeWorkspace` as the single resource-state owner, optional-package docs/config alignment, and portable packed smoke.
|
|
24
|
+
4. Public surface and release: (4a) Forge-native host contract — main drops the runtime dependency and the synthetic preparation model, and the 0.4 execution contract moves to the optional package; (4b) public-surface cut — root default, root named extension API, and `/subagent` only, `src/*` aliases removed, package checks flipped to the allowlist; (4c) optional-package packed smoke over a loopback transport; (4d) migration notes and English/Chinese docs; (4e) packed-install verification and the 0.5.0 release.
|
|
25
|
+
|
|
26
|
+
Only one lane is active at a time. Sandbox, staged writes, new prompt features, richer imports, and the remaining full-plan architecture work remain deferred until after this sequence.
|
|
27
|
+
|
|
28
|
+
## 0.5.x continuation
|
|
29
|
+
|
|
30
|
+
After 0.5.0, continue toward the archived full target in small increments:
|
|
31
|
+
|
|
32
|
+
- expected-fingerprint writes, codec fingerprinting, and atomic persistence;
|
|
33
|
+
- full `PromptStackService` / `AgentProfileService` / `ForgeWorkspace` ownership;
|
|
34
|
+
- physical `pi-forge-core` boundaries and dependency-direction checking;
|
|
35
|
+
- complete host RPC catalogue, progress events, and optional subagent UI;
|
|
36
|
+
- public-surface classification and rolling Pi compatibility matrix.
|
|
37
|
+
|
|
7
38
|
## 0.4 baseline
|
|
8
39
|
|
|
9
40
|
The profile UI, foreground-delegation dogfooding, dependency compatibility work, and documentation reorganization are complete and merged to `main`. Runtime beta.2 is published, and the packed 0.4.0 extension passes the full verification surface against the documented Pi versions.
|
|
@@ -12,25 +43,26 @@ The 0.4.1 release adds scoped global profiles and prompt stacks with project-ove
|
|
|
12
43
|
|
|
13
44
|
Stable 0.4 does not imply that the subagent adapter or runtime has become stable. Prompt stacks and ordinary profile use remain independent of delegation.
|
|
14
45
|
|
|
15
|
-
##
|
|
46
|
+
## Deferred candidates
|
|
16
47
|
|
|
17
48
|
### Sandbox and staged writes
|
|
18
49
|
|
|
19
50
|
Evaluate an optional backend that can honestly enforce roots, process behavior, symlink containment, and requested network policy. Keep shared-user as an explicit compatibility boundary. Design writes as a separately approved staged patch/change set; do not add write/edit/shell tools directly to the shared-user child.
|
|
20
51
|
|
|
21
|
-
###
|
|
52
|
+
### History and prompt diagnostics
|
|
22
53
|
|
|
23
|
-
|
|
54
|
+
Candidate history controls need concrete use cases and dangling tool-pair tests. Provider-payload rewriting and display-only streaming regex remain deferred until a stable, previewable lifecycle hook exists. SillyTavern fidelity is no longer a core roadmap goal; 0.5 removes it.
|
|
24
55
|
|
|
25
56
|
## Product guardrails
|
|
26
57
|
|
|
27
58
|
- Prompt-stack JSON stays declarative; executable customization stays in trusted extensions/packages.
|
|
59
|
+
- Prompt rendering moves toward immutable inputs and explicit outputs; do not add mutable variable behavior during 0.5.
|
|
28
60
|
- Profiles remain one-shot presets, not continuous runtime owners.
|
|
29
61
|
- Tool and skill policy stays in prompt stacks, not profiles.
|
|
30
62
|
- Skill filtering is model-visible prompt filtering, not an invocation or security boundary.
|
|
31
|
-
- Delegation remains opt-in, foreground, clean-context, and fail-closed on missing capabilities.
|
|
63
|
+
- Delegation remains opt-in, foreground, clean-context, and fail-closed on missing capabilities, and lives in the optional package.
|
|
32
64
|
- Do not report shared-user read-only policy as an OS sandbox.
|
|
33
|
-
- New editor workflows
|
|
65
|
+
- New editor product workflows are frozen; migration changes retain real-browser coverage.
|
|
34
66
|
- Run the full verification and package checks before release.
|
|
35
67
|
|
|
36
68
|
The detailed completed 0.4 plan is retained in the [historical roadmap](../design/roadmap-0.4-archive.md).
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
[Documentation](../README.md) · [Roadmap](roadmap.md)
|
|
4
4
|
|
|
5
|
-
Status: accepted design; implementation complete for 0.4.1 (identity, catalogs, scoped stacks/profiles, persistence, auto-activation, delegation, zh-CN docs, and web-editor global create/fork/import with explicit scope).
|
|
5
|
+
Status: accepted design; implementation complete for 0.4.1 (identity, catalogs, scoped stacks/profiles, persistence, auto-activation, delegation, zh-CN docs, and web-editor global create/fork/import with explicit scope). Historical record: the delegation-policy references to `.pi/forge/config.json` `subagents.*` below are superseded in 0.5 — delegation configuration moved to the optional package's dedicated `subagents.json` files (see the [0.5 migration guide](../guides/migrating-to-0.5.md)).
|
|
6
6
|
|
|
7
7
|
## Confirmed design decisions
|
|
8
8
|
|
|
@@ -14,6 +14,8 @@ pi
|
|
|
14
14
|
|
|
15
15
|
Trust the project in Pi and use `/reload` when needed.
|
|
16
16
|
|
|
17
|
+
Before making structural changes, read the [architecture and development rules](architecture-rules.md) and the active [0.5 architecture plan](../design/architecture-0.5.md). Boundary, schema, persistence, public API, and product changes require an accepted architecture decision before implementation.
|
|
18
|
+
|
|
17
19
|
The npm package loads compiled `dist/index.js` and intentionally omits physical `src/` files. Clone or fork the repository to inspect or modify source; do not edit generated files in `node_modules`.
|
|
18
20
|
|
|
19
21
|
## Load the extension
|
|
@@ -67,9 +69,9 @@ Document the tested range separately from peer constraints. Pi-coupled experimen
|
|
|
67
69
|
|
|
68
70
|
## Package boundaries
|
|
69
71
|
|
|
70
|
-
- `@zihanw/pi-forge` is the Pi extension and stable macro/slot registration surface.
|
|
71
|
-
- `@zihanw/pi-forge/subagent` is the
|
|
72
|
-
- `@zihanw/pi-
|
|
73
|
-
-
|
|
72
|
+
- `@zihanw/pi-forge` is the Pi extension (default export) and the stable macro/slot registration surface; no other root exports or `src/*` aliases exist.
|
|
73
|
+
- `@zihanw/pi-forge/subagent` is the experimental versioned host-port entry point (wire DTOs, validators, transport, client/host lifecycle, canonical fingerprints).
|
|
74
|
+
- `@zihanw/pi-forge-subagents` is the optional package owning subagent execution, configuration, and the 0.4 execution contract.
|
|
75
|
+
- `@zihanw/pi-subagent-runtime` owns execution lifecycle and fresh-process backends (a dependency of the optional package, not of the main package).
|
|
74
76
|
|
|
75
77
|
See the [public API policy](../reference/public-api.md).
|
package/docs/getting-started.md
CHANGED
|
@@ -70,11 +70,12 @@ Profiles live in `.pi/forge/agent-profiles/*.json` by default; `/profile save gl
|
|
|
70
70
|
|---|---|
|
|
71
71
|
| `.pi/forge/prompt-stacks/` | Project prompt stacks |
|
|
72
72
|
| `.pi/forge/agent-profiles/` | Project agent profiles |
|
|
73
|
-
| `.pi/forge/config.json` | Trusted project configuration
|
|
73
|
+
| `.pi/forge/config.json` | Trusted project configuration (`webEditor.*`) |
|
|
74
74
|
| `.pi/forge/extensions/` | Trusted project macro/slot registration code |
|
|
75
75
|
| `~/.pi/forge/prompt-stacks/` | User-global prompt stacks |
|
|
76
76
|
| `~/.pi/forge/agent-profiles/` | User-global agent profiles |
|
|
77
|
-
| `~/.pi/forge/config.json` | User defaults
|
|
77
|
+
| `~/.pi/forge/config.json` | User defaults (`webEditor.*`) |
|
|
78
|
+
| `.pi/forge/subagents.json` / `~/.pi/forge/subagents.json` | Delegation authorization owned by the optional `@zihanw/pi-forge-subagents` package |
|
|
78
79
|
| `~/.pi/forge/extensions/` | Trusted user macro/slot registration code |
|
|
79
80
|
|
|
80
81
|
Legacy `.pi/prompt-stacks/*.json` files remain readable. Command-created stacks go to `.pi/forge/prompt-stacks`; use the web editor's `global` scope selector to create stacks in `~/.pi/forge/prompt-stacks`. Same-named new-location files shadow legacy ones. Migrate safely with:
|
|
@@ -89,7 +90,7 @@ Add `--overwrite` only when target replacement is intended. Add `--delete-legacy
|
|
|
89
90
|
## Where to go next
|
|
90
91
|
|
|
91
92
|
- Learn the [prompt-stack model](concepts/prompt-stacks.md).
|
|
92
|
-
- Fork a [focused reviewer](../examples/reviewer-prompt-stack.json)
|
|
93
|
-
- Use the [SillyTavern importer](guides/sillytavern-import.md).
|
|
93
|
+
- Fork a [focused reviewer](../examples/reviewer-prompt-stack.json).
|
|
94
94
|
- Learn [macros and slots](reference/macros-and-slots.md).
|
|
95
|
+
- Read the [0.5 migration guide](guides/migrating-to-0.5.md).
|
|
95
96
|
- Inspect the [complete commands](reference/commands.md) and [stack schema](reference/stack-schema.md).
|
|
@@ -15,8 +15,9 @@ Modules receive the pi-forge API directly, so they do not need to import the pac
|
|
|
15
15
|
export default function register(api) {
|
|
16
16
|
api.registerMacro({
|
|
17
17
|
name: "ticketId",
|
|
18
|
-
description: "Current ticket id from
|
|
19
|
-
|
|
18
|
+
description: "Current ticket id from static parameters.",
|
|
19
|
+
dependencies: ["parameters.ticket.id"],
|
|
20
|
+
render: ({ env, helpers }) => String(env.parameters["ticket.id"]),
|
|
20
21
|
});
|
|
21
22
|
|
|
22
23
|
api.registerSlot({
|
|
@@ -25,10 +26,10 @@ export default function register(api) {
|
|
|
25
26
|
options: {
|
|
26
27
|
heading: { type: "string", default: "Ticket context" },
|
|
27
28
|
},
|
|
28
|
-
render: (
|
|
29
|
-
String(
|
|
30
|
-
"- Ticket: " +
|
|
31
|
-
"- Project: " +
|
|
29
|
+
render: ({ item, options, env, helpers }) => [
|
|
30
|
+
String(options.heading ?? "Ticket context") + ":",
|
|
31
|
+
"- Ticket: " + String(env.parameters["ticket.id"]),
|
|
32
|
+
"- Project: " + helpers.normalizePath(String(env.runtime.cwd)),
|
|
32
33
|
].join("\n"),
|
|
33
34
|
});
|
|
34
35
|
}
|
|
@@ -57,7 +58,7 @@ Use the slot declaratively:
|
|
|
57
58
|
- Missing custom slots are validation warnings until their module is loaded.
|
|
58
59
|
- Registration ownership is disposed when the runtime shuts down.
|
|
59
60
|
|
|
60
|
-
The API provides `
|
|
61
|
+
The API provides `forgeDir`, `extensionPath`, helpers, registration functions, and `getRegisteredMacros()` / `getRegisteredSlots()`. Custom macro renderers receive a frozen `{ env, helpers }` and dependencies from the declaration. Global `forgeDir` is `~/.pi/forge`; project `forgeDir` is `<project>/.pi/forge`.
|
|
61
62
|
|
|
62
63
|
Reusable Pi packages may import `registerMacro` and `registerSlot` from `@zihanw/pi-forge`. The directory loaders are intended for small trusted customizations without package boilerplate.
|
|
63
64
|
|
package/docs/guides/debugging.md
CHANGED
|
@@ -30,7 +30,7 @@ Saved payloads can contain prompt and conversation content. Keep them out of ver
|
|
|
30
30
|
|
|
31
31
|
## Common checks
|
|
32
32
|
|
|
33
|
-
- Unexpected duplicate task: set the `chat-history` slot's `includeLastUserMessage` to `false` when a later block uses `{{lastUserMessage}}`.
|
|
33
|
+
- Unexpected duplicate task: set the `chat-history` slot's `includeLastUserMessage` to `false` when a later block uses `{{ runtime.lastUserMessage }}`.
|
|
34
34
|
- Missing tool: inspect stack `allow`/`deny` policy and `/preset status`; the tool-call guard enforces the selected stack even if another extension modifies active tools.
|
|
35
35
|
- Skill still visible: use `replace` mode when Pi's base prompt must not include its own skill listing.
|
|
36
36
|
- Missing custom slot: trust the project, check `.pi/forge/extensions`, reload, and inspect diagnostics.
|