@zihanw/pi-forge 0.3.0 → 0.3.2

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.
Files changed (156) hide show
  1. package/README.md +87 -2
  2. package/README.zh-CN.md +72 -2
  3. package/dist/compiler.d.ts +10 -0
  4. package/dist/compiler.d.ts.map +1 -0
  5. package/dist/compiler.js +490 -0
  6. package/dist/compiler.js.map +1 -0
  7. package/dist/extension-registry.d.ts +25 -0
  8. package/dist/extension-registry.d.ts.map +1 -0
  9. package/dist/extension-registry.js +6 -0
  10. package/dist/extension-registry.js.map +1 -0
  11. package/dist/forge-extensions.d.ts +28 -0
  12. package/dist/forge-extensions.d.ts.map +1 -0
  13. package/dist/forge-extensions.js +182 -0
  14. package/dist/forge-extensions.js.map +1 -0
  15. package/dist/index.d.ts +8 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +376 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/lifecycle.d.ts +14 -0
  20. package/dist/lifecycle.d.ts.map +1 -0
  21. package/dist/lifecycle.js +139 -0
  22. package/dist/lifecycle.js.map +1 -0
  23. package/dist/loader.d.ts +8 -0
  24. package/dist/loader.d.ts.map +1 -0
  25. package/dist/loader.js +345 -0
  26. package/dist/loader.js.map +1 -0
  27. package/dist/macro-engine.d.ts +23 -0
  28. package/dist/macro-engine.d.ts.map +1 -0
  29. package/dist/macro-engine.js +262 -0
  30. package/dist/macro-engine.js.map +1 -0
  31. package/dist/payload-capture.d.ts +15 -0
  32. package/dist/payload-capture.d.ts.map +1 -0
  33. package/dist/payload-capture.js +86 -0
  34. package/dist/payload-capture.js.map +1 -0
  35. package/dist/payload-command.d.ts +10 -0
  36. package/dist/payload-command.d.ts.map +1 -0
  37. package/dist/payload-command.js +112 -0
  38. package/dist/payload-command.js.map +1 -0
  39. package/dist/policy.d.ts +6 -0
  40. package/dist/policy.d.ts.map +1 -0
  41. package/dist/policy.js +38 -0
  42. package/dist/policy.js.map +1 -0
  43. package/dist/preset-command.d.ts +14 -0
  44. package/dist/preset-command.d.ts.map +1 -0
  45. package/dist/preset-command.js +232 -0
  46. package/dist/preset-command.js.map +1 -0
  47. package/dist/preview.d.ts +12 -0
  48. package/dist/preview.d.ts.map +1 -0
  49. package/dist/preview.js +179 -0
  50. package/dist/preview.js.map +1 -0
  51. package/dist/regex.d.ts +7 -0
  52. package/dist/regex.d.ts.map +1 -0
  53. package/dist/regex.js +432 -0
  54. package/dist/regex.js.map +1 -0
  55. package/dist/render-helpers.d.ts +44 -0
  56. package/dist/render-helpers.d.ts.map +1 -0
  57. package/dist/render-helpers.js +128 -0
  58. package/dist/render-helpers.js.map +1 -0
  59. package/dist/runtime-state.d.ts +26 -0
  60. package/dist/runtime-state.d.ts.map +1 -0
  61. package/dist/runtime-state.js +15 -0
  62. package/dist/runtime-state.js.map +1 -0
  63. package/dist/sillytavern-importer/items.d.ts +3 -0
  64. package/dist/sillytavern-importer/items.d.ts.map +1 -0
  65. package/dist/sillytavern-importer/items.js +88 -0
  66. package/dist/sillytavern-importer/items.js.map +1 -0
  67. package/dist/sillytavern-importer/macros.d.ts +15 -0
  68. package/dist/sillytavern-importer/macros.d.ts.map +1 -0
  69. package/dist/sillytavern-importer/macros.js +141 -0
  70. package/dist/sillytavern-importer/macros.js.map +1 -0
  71. package/dist/sillytavern-importer/prompt-order.d.ts +6 -0
  72. package/dist/sillytavern-importer/prompt-order.d.ts.map +1 -0
  73. package/dist/sillytavern-importer/prompt-order.js +38 -0
  74. package/dist/sillytavern-importer/prompt-order.js.map +1 -0
  75. package/dist/sillytavern-importer/regex.d.ts +3 -0
  76. package/dist/sillytavern-importer/regex.d.ts.map +1 -0
  77. package/dist/sillytavern-importer/regex.js +275 -0
  78. package/dist/sillytavern-importer/regex.js.map +1 -0
  79. package/dist/sillytavern-importer/report.d.ts +21 -0
  80. package/dist/sillytavern-importer/report.d.ts.map +1 -0
  81. package/dist/sillytavern-importer/report.js +166 -0
  82. package/dist/sillytavern-importer/report.js.map +1 -0
  83. package/dist/sillytavern-importer/types.d.ts +106 -0
  84. package/dist/sillytavern-importer/types.d.ts.map +1 -0
  85. package/dist/sillytavern-importer/types.js +2 -0
  86. package/dist/sillytavern-importer/types.js.map +1 -0
  87. package/dist/sillytavern-importer.d.ts +5 -0
  88. package/dist/sillytavern-importer.d.ts.map +1 -0
  89. package/dist/sillytavern-importer.js +117 -0
  90. package/dist/sillytavern-importer.js.map +1 -0
  91. package/dist/slot-renderers.d.ts +25 -0
  92. package/dist/slot-renderers.d.ts.map +1 -0
  93. package/dist/slot-renderers.js +334 -0
  94. package/dist/slot-renderers.js.map +1 -0
  95. package/dist/stack-migration.d.ts +29 -0
  96. package/dist/stack-migration.d.ts.map +1 -0
  97. package/dist/stack-migration.js +126 -0
  98. package/dist/stack-migration.js.map +1 -0
  99. package/dist/storage.d.ts +10 -0
  100. package/dist/storage.d.ts.map +1 -0
  101. package/dist/storage.js +36 -0
  102. package/dist/storage.js.map +1 -0
  103. package/dist/types.d.ts +173 -0
  104. package/dist/types.d.ts.map +1 -0
  105. package/dist/types.js +2 -0
  106. package/dist/types.js.map +1 -0
  107. package/dist/web-editor/index.d.ts +3 -0
  108. package/dist/web-editor/index.d.ts.map +1 -0
  109. package/dist/web-editor/index.js +2 -0
  110. package/dist/web-editor/index.js.map +1 -0
  111. package/dist/web-editor/page.d.ts +2 -0
  112. package/dist/web-editor/page.d.ts.map +1 -0
  113. package/dist/web-editor/page.js +3331 -0
  114. package/dist/web-editor/page.js.map +1 -0
  115. package/dist/web-editor/server.d.ts +4 -0
  116. package/dist/web-editor/server.d.ts.map +1 -0
  117. package/dist/web-editor/server.js +263 -0
  118. package/dist/web-editor/server.js.map +1 -0
  119. package/dist/web-editor/types.d.ts +125 -0
  120. package/dist/web-editor/types.d.ts.map +1 -0
  121. package/dist/web-editor/types.js +2 -0
  122. package/dist/web-editor/types.js.map +1 -0
  123. package/dist/web-host.d.ts +29 -0
  124. package/dist/web-host.d.ts.map +1 -0
  125. package/dist/web-host.js +174 -0
  126. package/dist/web-host.js.map +1 -0
  127. package/examples/custom-system-status-extension/README.md +85 -0
  128. package/examples/custom-system-status-extension/index.ts +136 -0
  129. package/examples/custom-system-status-extension/prompt-stack.json +39 -0
  130. package/examples/image-reader-prompt-stack.json +124 -0
  131. package/package.json +28 -2
  132. package/src/compiler.ts +2 -472
  133. package/src/extension-registry.ts +33 -0
  134. package/src/forge-extensions.ts +223 -0
  135. package/src/index.ts +208 -653
  136. package/src/lifecycle.ts +171 -0
  137. package/src/macro-engine.ts +358 -0
  138. package/src/payload-command.ts +138 -0
  139. package/src/preset-command.ts +280 -0
  140. package/src/preview.ts +226 -0
  141. package/src/render-helpers.ts +169 -0
  142. package/src/runtime-state.ts +40 -0
  143. package/src/sillytavern-importer/items.ts +98 -0
  144. package/src/sillytavern-importer/macros.ts +159 -0
  145. package/src/sillytavern-importer/prompt-order.ts +54 -0
  146. package/src/sillytavern-importer/regex.ts +270 -0
  147. package/src/sillytavern-importer/report.ts +202 -0
  148. package/src/sillytavern-importer/types.ts +120 -0
  149. package/src/sillytavern-importer.ts +55 -865
  150. package/src/slot-renderers.ts +414 -0
  151. package/src/storage.ts +17 -0
  152. package/src/types.ts +3 -14
  153. package/src/web-editor/page.ts +516 -30
  154. package/src/web-editor/server.ts +9 -4
  155. package/src/web-editor/types.ts +18 -4
  156. package/src/web-host.ts +16 -13
package/README.md CHANGED
@@ -50,7 +50,7 @@ Prefer clicking over typing JSON? pi-forge has a built-in web editor:
50
50
  /preset ui
51
51
  ```
52
52
 
53
- Drag, drop, edit, validate, inspect full previews and captured payloads, manage variables/context/regex rules in tabs, switch dark mode, recover through raw stack JSON, import, export, fork, and delete stacks — all in your browser. Stack metadata is collapsible so the active editor stays in view.
53
+ Drag, drop, create, edit, validate, inspect full previews and captured payloads, manage variables/context/regex rules in tabs, switch dark mode, recover through raw stack JSON, import, export, fork, and delete stacks — all in your browser. New stacks start from the default Pi prompt mirror layout. Stack metadata is collapsible so the active editor stays in view. The policy tab shows registered tools and loaded skills with selected-pattern chips and filtering, so allow/deny rules can be built from exact names while still supporting wildcards.
54
54
 
55
55
  Import accepts native pi-forge stack JSON and SillyTavern preset JSON. SillyTavern presets are converted to prompt stacks automatically; if a preset contains multiple `character_id` configs, the editor asks which one to use.
56
56
 
@@ -192,7 +192,7 @@ Items are arranged in order. When the stack is active, pi-forge:
192
192
  | `skills` | Loaded Pi skills |
193
193
  | `project-context` | Project instructions and context files |
194
194
  | `variables` | Static/session/turn template variables |
195
- | `date` / `cwd` / `date-cwd` | Current date and working directory |
195
+ | `date` / `cwd` / `date-cwd` | Current date, optional current time, and working directory |
196
196
  | `active-model` | Which model is being used |
197
197
  | `append-system-prompt` | User's appended system prompt text |
198
198
  | `pi-docs` | Pi documentation guidance |
@@ -257,6 +257,79 @@ Use these in block content to insert dynamic values:
257
257
  {{clearsessionvar::name}} clear a session variable
258
258
  ```
259
259
 
260
+ ### Filter and conditional macros
261
+
262
+ Nested macros are supported, and `::` separators are parsed only at the current macro depth.
263
+
264
+ | Macro | Expands to |
265
+ |-------|-----------|
266
+ | `{{trim::value}}` | `value` with leading/trailing whitespace removed |
267
+ | `{{upper::value}}` | Uppercase `value` |
268
+ | `{{lower::value}}` | Lowercase `value` |
269
+ | `{{json::value}}` | JSON string literal for `value` |
270
+ | `{{xml::value}}` | XML-escaped `value` |
271
+ | `{{ifvar::name::then::else}}` | `then` when a variable exists, otherwise `else` |
272
+ | `{{ifeq::name::expected::then::else}}` | `then` when a variable equals `expected`, otherwise `else` |
273
+ | `{{iftools::tool::then::else}}` | `then` when the selected tool list includes `tool`, otherwise `else` |
274
+ | `{{ifslot::slot::then::else}}` | `then` when the enabled stack items include `slot`, otherwise `else` |
275
+
276
+ Conditional branches are lazy: only the selected branch is expanded, so skipped branches cannot set or clear variables. The final `else` argument is optional and defaults to empty text.
277
+
278
+ ### Trusted custom macros and slots
279
+
280
+ Custom macros and slots are registered by trusted extension code, not embedded in prompt-stack JSON. For project-local customization, put registration modules in `.pi/forge/extensions/`. For machine-wide personal customization, put them in `~/.pi/forge/extensions/`. pi-forge loads global modules first, then project-local modules, after project trust and before stack validation. Both locations reload on `/preset reload`.
281
+
282
+ These modules receive the registration API from pi-forge, so they do not need to import `@zihanw/pi-forge` or know where pi-forge is installed.
283
+
284
+ ```ts
285
+ // .pi/forge/extensions/ticket-context.ts
286
+ export default function register(api) {
287
+ api.registerMacro({
288
+ name: "ticketId",
289
+ description: "Current ticket id from session variables.",
290
+ render: (ctx) => ctx.variables.toMacroText(ctx.variables.get("ticket.id")),
291
+ });
292
+
293
+ api.registerSlot({
294
+ name: "ticket-context",
295
+ description: "Render ticket context for the current task.",
296
+ options: {
297
+ heading: { type: "string", default: "Ticket context" },
298
+ },
299
+ render: (ctx) => [
300
+ String(ctx.options.heading ?? "Ticket context") + ":",
301
+ "- Ticket: " + ctx.variables.toMacroText(ctx.variables.get("ticket.id")),
302
+ "- Project: " + ctx.helpers.normalizePath(ctx.runtime.options.cwd),
303
+ ].join("\n"),
304
+ });
305
+ }
306
+ ```
307
+
308
+ The stack remains declarative:
309
+
310
+ ```json
311
+ {
312
+ "kind": "slot",
313
+ "id": "ticket-context",
314
+ "enabled": true,
315
+ "role": "system",
316
+ "slot": "ticket-context",
317
+ "options": {
318
+ "heading": "Current ticket"
319
+ }
320
+ }
321
+ ```
322
+
323
+ Supported module files are `.ts`, `.js`, `.mjs`, `.cjs`, and `index.*` inside a subdirectory. TypeScript modules should stick to syntax Node can strip at runtime, or you can use `.js` / `.mjs` instead. A module can export either `default function register(api)` or `export function register(api)`. Registered macro and slot names must be unique across built-ins, global extensions, and project extensions; duplicate names show as extension load warnings.
324
+
325
+ The API includes `cwd`, `forgeDir`, `extensionPath`, `helpers`, `registerMacro`, `registerSlot`, `getRegisteredMacros`, and `getRegisteredSlots`. For global modules, `forgeDir` is `~/.pi/forge`; for project modules, it is `<project>/.pi/forge`.
326
+
327
+ Missing custom slots are validation warnings until the registering module is loaded. Built-in macros and slots use the same registry internally, so `getRegisteredMacros()` and `getRegisteredSlots()` can be used as implementation references. `/preset diagnostics` shows loaded pi-forge extension files and load failures.
328
+
329
+ For a complete copyable extension and stack, see [examples/custom-system-status-extension](examples/custom-system-status-extension). It registers a `{{cpuLoad}}` macro and a `machine-status` slot from `.pi/forge/extensions/system-status.ts`.
330
+
331
+ Reusable Pi packages can still import `registerMacro` and `registerSlot` from `@zihanw/pi-forge`. The `.pi/forge/extensions` and `~/.pi/forge/extensions` loaders are intended for small trusted customizations without package boilerplate.
332
+
260
333
  ## Stack reference
261
334
 
262
335
  ### Full item types
@@ -312,6 +385,10 @@ Set `stripAssistantThinking` to `true` to remove prior assistant thinking blocks
312
385
 
313
386
  Use `includeSummaries: false` to omit Pi branch/compaction summary messages, `roles` to keep only specific message roles, `toolMode: "drop"` to remove prior tool-call/tool-result history, and `maxMessages` / `maxChars` to keep only recent history. When filters or limits can break tool-call pairs, pi-forge removes dangling tool calls/results instead of sending inconsistent tool history.
314
387
 
388
+ ### Date slot options
389
+
390
+ Set `"includeTime": true` on a `date` or `date-cwd` slot to include the current time in `HH:MM:SS` after the current date.
391
+
315
392
  ### Structured slot format options
316
393
 
317
394
  Structured runtime slots default to XML-style wrappers. Add `"format": "plain"` to `tools`, `tool-guidelines`, `skills`, `project-context`, or `variables` slots for compact newline-separated output.
@@ -434,6 +511,8 @@ SillyTavern imports convert deterministic prompt-only `{{match}}` / `$0` full-ma
434
511
  ```bash
435
512
  git clone <repo>
436
513
  cd pi-forge
514
+ npm install
515
+ npm run build
437
516
  # .pi/settings.json already points at the package root
438
517
  pi # start Pi, trust the project, /reload if needed
439
518
  ```
@@ -450,6 +529,12 @@ Typecheck:
450
529
  npm run typecheck
451
530
  ```
452
531
 
532
+ Build package output:
533
+
534
+ ```bash
535
+ npm run build
536
+ ```
537
+
453
538
  ## License
454
539
 
455
540
  MIT
package/README.zh-CN.md CHANGED
@@ -50,7 +50,7 @@ $EDITOR .pi/forge/prompt-stacks/default.json
50
50
  /preset ui
51
51
  ```
52
52
 
53
- 拖拽、编辑、校验、查看完整预览和捕获的 payload、用 tabs 管理变量/context/regex 规则、切换深色模式、通过原始 stack JSON 修复高级字段、导入、导出、fork、删除栈 —— 全在浏览器里完成。Stack metadata 可以折叠,方便把当前编辑区留在屏幕内。
53
+ 拖拽、新建、编辑、校验、查看完整预览和捕获的 payload、用 tabs 管理变量/context/regex 规则、切换深色模式、通过原始 stack JSON 修复高级字段、导入、导出、fork、删除栈 —— 全在浏览器里完成。新栈会从默认 Pi prompt mirror 布局开始。Stack metadata 可以折叠,方便把当前编辑区留在屏幕内。Policy tab 会显示已注册工具和已加载 skills,并提供已选 pattern chips 和过滤输入,方便用精确名称编写 allow/deny 规则,同时保留通配符写法。
54
54
 
55
55
  导入支持原生 pi-forge stack JSON,也支持 SillyTavern 预设 JSON。SillyTavern 预设会自动转换成 prompt stack;如果一个预设里有多个 `character_id` 配置,编辑器会询问要使用哪一个。
56
56
 
@@ -190,7 +190,7 @@ pi-forge 会把预设转换为 prompt stack,并生成迁移报告,标明哪
190
190
  | `skills` | 已加载的 Pi 技能 |
191
191
  | `project-context` | 项目指令和上下文文件 |
192
192
  | `variables` | 静态/会话/轮次模板变量 |
193
- | `date` / `cwd` / `date-cwd` | 当前日期和工作目录 |
193
+ | `date` / `cwd` / `date-cwd` | 当前日期、可选当前时间和工作目录 |
194
194
  | `active-model` | 当前使用的模型 |
195
195
  | `append-system-prompt` | 用户追加的系统提示词 |
196
196
  | `pi-docs` | Pi 文档指导 |
@@ -255,6 +255,64 @@ pi-forge 会把预设转换为 prompt stack,并生成迁移报告,标明哪
255
255
  {{clearsessionvar::name}} 清除会话变量
256
256
  ```
257
257
 
258
+ ### 过滤和条件宏
259
+
260
+ 宏支持嵌套,`::` 分隔符只会在当前宏深度拆分。
261
+
262
+ | 宏 | 展开为 |
263
+ |----|--------|
264
+ | `{{trim::value}}` | 去掉首尾空白后的 `value` |
265
+ | `{{upper::value}}` | 大写 `value` |
266
+ | `{{lower::value}}` | 小写 `value` |
267
+ | `{{json::value}}` | `value` 的 JSON 字符串字面量 |
268
+ | `{{xml::value}}` | XML 转义后的 `value` |
269
+ | `{{ifvar::name::then::else}}` | 变量存在时输出 `then`,否则输出 `else` |
270
+ | `{{ifeq::name::expected::then::else}}` | 变量等于 `expected` 时输出 `then`,否则输出 `else` |
271
+ | `{{iftools::tool::then::else}}` | 当前工具列表包含 `tool` 时输出 `then`,否则输出 `else` |
272
+ | `{{ifslot::slot::then::else}}` | 启用的 stack 条目包含 `slot` 时输出 `then`,否则输出 `else` |
273
+
274
+ 条件宏是 lazy 的:只有选中的分支会展开,所以被跳过的分支不会设置或清除变量。最后的 `else` 参数可省略,默认输出空文本。
275
+
276
+ ### 可信自定义宏和 slot
277
+
278
+ 自定义宏和 slot 由可信扩展代码注册,不把可执行代码写进 prompt-stack JSON。项目本地自定义代码放在 `.pi/forge/extensions/`。机器级个人自定义代码放在 `~/.pi/forge/extensions/`。pi-forge 会在项目受信任后、stack 校验前先加载全局模块,再加载项目本地模块;两个位置都会在 `/preset reload` 时重新加载。
279
+
280
+ 这些模块会从 pi-forge 接收注册 API,所以不需要 import `@zihanw/pi-forge`,也不需要知道 pi-forge 安装在哪里。
281
+
282
+ ```ts
283
+ // .pi/forge/extensions/ticket-context.ts
284
+ export default function register(api) {
285
+ api.registerMacro({
286
+ name: "ticketId",
287
+ description: "从会话变量读取当前 ticket id。",
288
+ render: (ctx) => ctx.variables.toMacroText(ctx.variables.get("ticket.id")),
289
+ });
290
+
291
+ api.registerSlot({
292
+ name: "ticket-context",
293
+ description: "渲染当前任务的 ticket 上下文。",
294
+ options: {
295
+ heading: { type: "string", default: "Ticket context" },
296
+ },
297
+ render: (ctx) => [
298
+ String(ctx.options.heading ?? "Ticket context") + ":",
299
+ "- Ticket: " + ctx.variables.toMacroText(ctx.variables.get("ticket.id")),
300
+ "- Project: " + ctx.helpers.normalizePath(ctx.runtime.options.cwd),
301
+ ].join("\n"),
302
+ });
303
+ }
304
+ ```
305
+
306
+ 支持 `.ts`、`.js`、`.mjs`、`.cjs` 文件,也支持子目录里的 `index.*`。TypeScript 模块应使用 Node 运行时可直接 strip 的语法;如果需要更复杂的构建,使用 `.js` / `.mjs`。模块可以导出 `default function register(api)`,也可以导出具名 `register(api)`。注册的宏和 slot 名称必须在内置项、全局扩展、项目扩展之间唯一;重复名称会显示为扩展加载 warning。
307
+
308
+ API 包含 `cwd`、`forgeDir`、`extensionPath`、`helpers`、`registerMacro`、`registerSlot`、`getRegisteredMacros`、`getRegisteredSlots`。对全局模块来说,`forgeDir` 是 `~/.pi/forge`;对项目模块来说,它是 `<project>/.pi/forge`。
309
+
310
+ 缺失的自定义 slot 会产生校验 warning,直到对应注册模块加载。内置宏和 slot 也使用同一个 registry,可用 `getRegisteredMacros()` 和 `getRegisteredSlots()` 作为实现参考。`/preset diagnostics` 会显示已加载的 pi-forge extension 文件和加载失败信息。
311
+
312
+ 完整可复制的扩展和 stack 示例见 [examples/custom-system-status-extension](examples/custom-system-status-extension)。它通过 `.pi/forge/extensions/system-status.ts` 注册 `{{cpuLoad}}` 宏和 `machine-status` slot。
313
+
314
+ 可复用的 Pi package 仍然可以从 `@zihanw/pi-forge` import `registerMacro` 和 `registerSlot`。`.pi/forge/extensions` 和 `~/.pi/forge/extensions` loader 主要用于不需要 package 样板的小型可信自定义逻辑。
315
+
258
316
  ## Stack 参考
259
317
 
260
318
  ### 完整条目类型
@@ -310,6 +368,10 @@ pi-forge 会把预设转换为 prompt stack,并生成迁移报告,标明哪
310
368
 
311
369
  使用 `includeSummaries: false` 可以排除 Pi 的 branch/compaction summary 消息;`roles` 可以只保留指定消息角色;`toolMode: "drop"` 可以移除之前的 tool call/tool result history;`maxMessages` / `maxChars` 可以只保留最近 history。当过滤或截断可能拆散 tool-call pair 时,pi-forge 会移除悬空的 tool call/result,避免发送不一致的 tool history。
312
370
 
371
+ ### Date slot 选项
372
+
373
+ 在 `date` 或 `date-cwd` slot 上设置 `"includeTime": true`,会在当前日期后加入 `HH:MM:SS` 格式的当前时间。
374
+
313
375
  ### 结构化 slot 格式选项
314
376
 
315
377
  结构化运行时 slot 默认使用 XML 风格包装。给 `tools`、`tool-guidelines`、`skills`、`project-context` 或 `variables` slot 添加 `"format": "plain"`,可输出更紧凑的换行分隔文本。
@@ -432,6 +494,8 @@ SillyTavern 导入会把确定性的 prompt-only `{{match}}` / `$0` full-match r
432
494
  ```bash
433
495
  git clone <repo>
434
496
  cd pi-forge
497
+ npm install
498
+ npm run build
435
499
  # .pi/settings.json 已指向包根目录
436
500
  pi # 启动 Pi,信任项目,必要时 /reload
437
501
  ```
@@ -448,6 +512,12 @@ npm test
448
512
  npm run typecheck
449
513
  ```
450
514
 
515
+ 构建 package 输出:
516
+
517
+ ```bash
518
+ npm run build
519
+ ```
520
+
451
521
  ## License
452
522
 
453
523
  MIT
@@ -0,0 +1,10 @@
1
+ import type { AgentMessage } from "@earendil-works/pi-agent-core";
2
+ import type { CompileMessagesResult, CompileSystemPromptResult, PromptRuntime, PromptStack, PromptVariableValue, PromptVariableStore } from "./types.ts";
3
+ export declare function createPromptVariableStore(sessionVariables?: Record<string, PromptVariableValue>): PromptVariableStore;
4
+ export declare function resetTurnVariables(store: PromptVariableStore): void;
5
+ export declare function markSessionVariablesClean(store: PromptVariableStore): void;
6
+ export declare function compileSystemPrompt(stack: PromptStack, runtime: PromptRuntime, baseSystemPrompt: string): CompileSystemPromptResult;
7
+ export declare function compileMessages(stack: PromptStack, runtime: PromptRuntime, originalMessages: AgentMessage[]): CompileMessagesResult;
8
+ export declare function getLatestUserMessage(messages: AgentMessage[]): string | undefined;
9
+ export declare function agentMessageToPreviewText(message: AgentMessage): string;
10
+ //# sourceMappingURL=compiler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../src/compiler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,KAAK,EAEX,qBAAqB,EACrB,yBAAyB,EACzB,aAAa,EACb,WAAW,EAKX,mBAAmB,EACnB,mBAAmB,EACnB,MAAM,YAAY,CAAC;AAgBpB,wBAAgB,yBAAyB,CAAC,gBAAgB,GAAE,MAAM,CAAC,MAAM,EAAE,mBAAmB,CAAM,GAAG,mBAAmB,CAEzH;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI,CAGnE;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,mBAAmB,GAAG,IAAI,CAE1E;AAED,wBAAgB,mBAAmB,CAClC,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,aAAa,EACtB,gBAAgB,EAAE,MAAM,GACtB,yBAAyB,CAuC3B;AAED,wBAAgB,eAAe,CAC9B,KAAK,EAAE,WAAW,EAClB,OAAO,EAAE,aAAa,EACtB,gBAAgB,EAAE,YAAY,EAAE,GAC9B,qBAAqB,CA2CvB;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,YAAY,EAAE,GAAG,MAAM,GAAG,SAAS,CASjF;AAED,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAWvE"}