@plurnk/plurnk-service 0.8.0 → 0.10.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.
Files changed (109) hide show
  1. package/SPEC.md +44 -56
  2. package/dist/content/line-marker.d.ts +2 -17
  3. package/dist/content/line-marker.d.ts.map +1 -1
  4. package/dist/content/line-marker.js +11 -319
  5. package/dist/content/line-marker.js.map +1 -1
  6. package/dist/content/matcher.d.ts.map +1 -1
  7. package/dist/content/matcher.js +9 -33
  8. package/dist/content/matcher.js.map +1 -1
  9. package/dist/content/mimetype-binary.d.ts +0 -1
  10. package/dist/content/mimetype-binary.d.ts.map +1 -1
  11. package/dist/content/mimetype-binary.js +13 -82
  12. package/dist/content/mimetype-binary.js.map +1 -1
  13. package/dist/content/path-mimetype.d.ts +0 -1
  14. package/dist/content/path-mimetype.d.ts.map +1 -1
  15. package/dist/content/path-mimetype.js +10 -44
  16. package/dist/content/path-mimetype.js.map +1 -1
  17. package/dist/core/ChannelWrite.d.ts +2 -0
  18. package/dist/core/ChannelWrite.d.ts.map +1 -1
  19. package/dist/core/ChannelWrite.js +8 -2
  20. package/dist/core/ChannelWrite.js.map +1 -1
  21. package/dist/core/Engine.d.ts +2 -0
  22. package/dist/core/Engine.d.ts.map +1 -1
  23. package/dist/core/Engine.js +72 -109
  24. package/dist/core/Engine.js.map +1 -1
  25. package/dist/core/ExecutorRegistry.d.ts +26 -0
  26. package/dist/core/ExecutorRegistry.d.ts.map +1 -0
  27. package/dist/core/ExecutorRegistry.js +99 -0
  28. package/dist/core/ExecutorRegistry.js.map +1 -0
  29. package/dist/core/ProviderInstantiate.d.ts.map +1 -1
  30. package/dist/core/ProviderInstantiate.js +15 -1
  31. package/dist/core/ProviderInstantiate.js.map +1 -1
  32. package/dist/core/git-membership.js +7 -7
  33. package/dist/core/git-membership.js.map +1 -1
  34. package/dist/core/packet-wire.d.ts +0 -5
  35. package/dist/core/packet-wire.d.ts.map +1 -1
  36. package/dist/core/packet-wire.js +2 -54
  37. package/dist/core/packet-wire.js.map +1 -1
  38. package/dist/core/resolveForLoop.d.ts +0 -9
  39. package/dist/core/resolveForLoop.d.ts.map +1 -1
  40. package/dist/core/resolveForLoop.js +7 -29
  41. package/dist/core/resolveForLoop.js.map +1 -1
  42. package/dist/core/results.d.ts +6 -34
  43. package/dist/core/results.d.ts.map +1 -1
  44. package/dist/core/results.js +19 -44
  45. package/dist/core/results.js.map +1 -1
  46. package/dist/core/scheme-types.d.ts +2 -0
  47. package/dist/core/scheme-types.d.ts.map +1 -1
  48. package/dist/core/scheme-types.js.map +1 -1
  49. package/dist/core/types.d.ts +2 -26
  50. package/dist/core/types.d.ts.map +1 -1
  51. package/dist/core/types.js +1 -16
  52. package/dist/core/types.js.map +1 -1
  53. package/dist/schemes/EffectPolicy.d.ts +6 -0
  54. package/dist/schemes/EffectPolicy.d.ts.map +1 -0
  55. package/dist/schemes/EffectPolicy.js +18 -0
  56. package/dist/schemes/EffectPolicy.js.map +1 -0
  57. package/dist/schemes/Exec.d.ts +2 -4
  58. package/dist/schemes/Exec.d.ts.map +1 -1
  59. package/dist/schemes/Exec.js +54 -36
  60. package/dist/schemes/Exec.js.map +1 -1
  61. package/dist/schemes/File.d.ts.map +1 -1
  62. package/dist/schemes/File.js +9 -13
  63. package/dist/schemes/File.js.map +1 -1
  64. package/dist/schemes/Known.d.ts +2 -4
  65. package/dist/schemes/Known.d.ts.map +1 -1
  66. package/dist/schemes/Known.js +0 -6
  67. package/dist/schemes/Known.js.map +1 -1
  68. package/dist/schemes/Plurnk.d.ts +2 -4
  69. package/dist/schemes/Plurnk.d.ts.map +1 -1
  70. package/dist/schemes/Plurnk.js +0 -6
  71. package/dist/schemes/Plurnk.js.map +1 -1
  72. package/dist/schemes/Skill.d.ts +2 -4
  73. package/dist/schemes/Skill.d.ts.map +1 -1
  74. package/dist/schemes/Skill.js +0 -6
  75. package/dist/schemes/Skill.js.map +1 -1
  76. package/dist/schemes/Unknown.d.ts +2 -4
  77. package/dist/schemes/Unknown.d.ts.map +1 -1
  78. package/dist/schemes/Unknown.js +0 -6
  79. package/dist/schemes/Unknown.js.map +1 -1
  80. package/dist/schemes/_entry-crud.d.ts.map +1 -1
  81. package/dist/schemes/_entry-crud.js +2 -3
  82. package/dist/schemes/_entry-crud.js.map +1 -1
  83. package/dist/schemes/_entry-find.d.ts.map +1 -1
  84. package/dist/schemes/_entry-find.js +6 -7
  85. package/dist/schemes/_entry-find.js.map +1 -1
  86. package/dist/schemes/_entry-manifest.d.ts.map +1 -1
  87. package/dist/schemes/_entry-manifest.js +12 -14
  88. package/dist/schemes/_entry-manifest.js.map +1 -1
  89. package/dist/schemes/_entry-ops.d.ts +1 -3
  90. package/dist/schemes/_entry-ops.d.ts.map +1 -1
  91. package/dist/schemes/_entry-ops.js +1 -59
  92. package/dist/schemes/_entry-ops.js.map +1 -1
  93. package/dist/server/Daemon.d.ts.map +1 -1
  94. package/dist/server/Daemon.js +13 -0
  95. package/dist/server/Daemon.js.map +1 -1
  96. package/dist/server/clientTurn.js +1 -1
  97. package/dist/server/clientTurn.js.map +1 -1
  98. package/dist/server/methods/loop_run.d.ts.map +1 -1
  99. package/dist/server/methods/loop_run.js.map +1 -1
  100. package/dist/server/methods/op_hide.js +1 -1
  101. package/dist/server/methods/op_hide.js.map +1 -1
  102. package/dist/server/methods/op_show.js +1 -1
  103. package/dist/server/methods/op_show.js.map +1 -1
  104. package/dist/server/noProposals.d.ts +6 -0
  105. package/dist/server/noProposals.d.ts.map +1 -0
  106. package/dist/server/noProposals.js +37 -0
  107. package/dist/server/noProposals.js.map +1 -0
  108. package/migrations/0000-00-00.01_schema.sql +0 -13
  109. package/package.json +27 -34
@@ -1,49 +1,15 @@
1
- // Path-extension mimetype resolver for entry schemes per plurnk-grammar
2
- // 0.14.0 §Paths: "Path suffix (`.json`, `.md`, `.txt`, etc.) declares
3
- // mimetype; absent suffix defers to scheme default."
1
+ // Path-extension mimetype resolver for entry schemes single source of truth
2
+ // is @plurnk/plurnk-schemes (keystone PR-1). Local OO facade over the
3
+ // daughter's function; call sites stay `PathMimetype.resolveEntryMimetype(...)`.
4
4
  //
5
- // Plurnk-service implements this uniformly across entry schemes: a
6
- // pathname's extension drives the effective mimetype (via the sibling
7
- // Mimetypes detect service), and the scheme manifest's channel default
8
- // is the fallback when no extension is present.
9
- //
10
- // This makes structural ops (`<L>` item-index, matcher dialect dispatch)
11
- // fire correctly without content-sniffing: a model writing JSON to
12
- // `known://users.json` opts into JSON treatment via the `.json` suffix,
13
- // while `known://notes` (no suffix) stays at Known's default of
14
- // `text/markdown`.
15
- //
16
- // Consistent across:
17
- // - known://users.json → application/json
18
- // - known://notes.md → text/markdown
19
- // - known://config.yaml → application/yaml
20
- // - known://users → scheme default (text/markdown for Known)
21
- import MimetypeBinary from "./mimetype-binary.js";
5
+ // A pathname's extension drives the effective mimetype (via the sibling
6
+ // Mimetypes detect service); the scheme manifest's channel default is the
7
+ // fallback when no extension is present. `known://users.json`
8
+ // application/json; `known://notes` scheme default.
9
+ import { resolveEntryMimetype as _resolveEntryMimetype } from "@plurnk/plurnk-schemes";
22
10
  export default class PathMimetype {
23
- // Extract the suffix (everything after the last dot in the last segment)
24
- // from a pathname. Empty if no dot in the last segment.
25
- static #extractExtension(pathname) {
26
- const lastSlash = pathname.lastIndexOf("/");
27
- const lastSegment = lastSlash === -1 ? pathname : pathname.slice(lastSlash + 1);
28
- const lastDot = lastSegment.lastIndexOf(".");
29
- if (lastDot <= 0)
30
- return ""; // leading-dot files (".env") aren't an extension
31
- return lastSegment.slice(lastDot); // includes the leading "."
32
- }
33
- // Resolve a pathname → effective mimetype.
34
- // 1. If the pathname has an extension, query Mimetypes.detect({ ext })
35
- // and use what comes back (normalized via the text-primitive rule —
36
- // text/plain → text/markdown).
37
- // 2. Otherwise (no extension or no Mimetypes service), fall back to
38
- // `schemeDefault` (typically the scheme manifest's channel default).
39
- static async resolveEntryMimetype(pathname, schemeDefault, mimetypes) {
40
- const ext = PathMimetype.#extractExtension(pathname);
41
- if (ext.length > 0 && mimetypes !== undefined) {
42
- const detected = await mimetypes.detect({ ext });
43
- if (detected !== null)
44
- return MimetypeBinary.normalizeAutoTextMimetype(detected);
45
- }
46
- return schemeDefault;
11
+ static resolveEntryMimetype(pathname, schemeDefault, mimetypes) {
12
+ return _resolveEntryMimetype(pathname, schemeDefault, mimetypes);
47
13
  }
48
14
  }
49
15
  //# sourceMappingURL=path-mimetype.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"path-mimetype.js","sourceRoot":"","sources":["../../src/content/path-mimetype.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,sEAAsE;AACtE,qDAAqD;AACrD,EAAE;AACF,mEAAmE;AACnE,sEAAsE;AACtE,uEAAuE;AACvE,gDAAgD;AAChD,EAAE;AACF,yEAAyE;AACzE,mEAAmE;AACnE,wEAAwE;AACxE,gEAAgE;AAChE,mBAAmB;AACnB,EAAE;AACF,qBAAqB;AACrB,gDAAgD;AAChD,6CAA6C;AAC7C,gDAAgD;AAChD,wEAAwE;AAGxE,OAAO,cAAc,MAAM,sBAAsB,CAAC;AAElD,MAAM,CAAC,OAAO,OAAO,YAAY;IAC7B,yEAAyE;IACzE,wDAAwD;IACxD,MAAM,CAAC,iBAAiB,CAAC,QAAgB;QACrC,MAAM,SAAS,GAAG,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAC5C,MAAM,WAAW,GAAG,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;QAChF,MAAM,OAAO,GAAG,WAAW,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAC7C,IAAI,OAAO,IAAI,CAAC;YAAE,OAAO,EAAE,CAAC,CAAE,iDAAiD;QAC/E,OAAO,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAE,2BAA2B;IACnE,CAAC;IAED,2CAA2C;IAC3C,uEAAuE;IACvE,uEAAuE;IACvE,kCAAkC;IAClC,oEAAoE;IACpE,wEAAwE;IACxE,MAAM,CAAC,KAAK,CAAC,oBAAoB,CAC7B,QAAgB,EAChB,aAAqB,EACrB,SAAgC;QAEhC,MAAM,GAAG,GAAG,YAAY,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;QACrD,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;YAC5C,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;YACjD,IAAI,QAAQ,KAAK,IAAI;gBAAE,OAAO,cAAc,CAAC,yBAAyB,CAAC,QAAQ,CAAC,CAAC;QACrF,CAAC;QACD,OAAO,aAAa,CAAC;IACzB,CAAC;CACJ"}
1
+ {"version":3,"file":"path-mimetype.js","sourceRoot":"","sources":["../../src/content/path-mimetype.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,sEAAsE;AACtE,iFAAiF;AACjF,EAAE;AACF,wEAAwE;AACxE,0EAA0E;AAC1E,gEAAgE;AAChE,sDAAsD;AACtD,OAAO,EAAE,oBAAoB,IAAI,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAGvF,MAAM,CAAC,OAAO,OAAO,YAAY;IAC7B,MAAM,CAAC,oBAAoB,CAAC,QAAgB,EAAE,aAAqB,EAAE,SAAgC;QACjG,OAAO,qBAAqB,CAAC,QAAQ,EAAE,aAAa,EAAE,SAAS,CAAC,CAAC;IACrE,CAAC;CACJ"}
@@ -2,6 +2,7 @@ import type { Db } from "./Db.ts";
2
2
  export type ChannelState = "static" | "active" | "closed" | "errored";
3
3
  export interface StreamEventPayload {
4
4
  entryId: number;
5
+ target: string;
5
6
  channel: string;
6
7
  state: ChannelState;
7
8
  contentLength: number;
@@ -11,6 +12,7 @@ export interface WakeRunPayload {
11
12
  sessionId: number;
12
13
  runId: number;
13
14
  entryId: number;
15
+ target: string;
14
16
  subscriptionId: number;
15
17
  closeStatus: number;
16
18
  scheme: string;
@@ -1 +1 @@
1
- {"version":3,"file":"ChannelWrite.d.ts","sourceRoot":"","sources":["../../src/core/ChannelWrite.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,EAAE,EAAc,MAAM,SAAS,CAAC;AAE9C,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEtE,MAAM,WAAW,kBAAkB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,YAAY,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,iBAAiB,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;AAQvF,MAAM,WAAW,cAAc;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;AAQ9D,MAAM,WAAW,qBAAqB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,oBAAoB,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB,KAAK,IAAI,CAAC;AAQ/F,MAAM,CAAC,OAAO,OAAO,YAAY;;WAQhB,eAAe,CACxB,EAAE,EAAE,EAAE,EACN,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,iBAAiB,CAAA;KAAE,GACrH,OAAO,CAAC,IAAI,CAAC;WASH,eAAe,CACxB,EAAE,EAAE,EAAE,EACN,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,YAAY,CAAC;QAAC,MAAM,CAAC,EAAE,iBAAiB,CAAA;KAAE,GAC3H,OAAO,CAAC,IAAI,CAAC;WASH,gBAAgB,CACzB,EAAE,EAAE,EAAE,EACN,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GACvG,OAAO,CAAC,MAAM,CAAC;WAML,iBAAiB,CAC1B,EAAE,EAAE,EAAE,EACN,EAAE,cAAc,EAAE,MAAM,EAAE,EAAE;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GACvE,OAAO,CAAC,IAAI,CAAC;WAIH,sBAAsB,CAC/B,EAAE,EAAE,EAAE,EACN,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GACvD,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAIpE"}
1
+ {"version":3,"file":"ChannelWrite.d.ts","sourceRoot":"","sources":["../../src/core/ChannelWrite.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,EAAE,EAAc,MAAM,SAAS,CAAC;AAE9C,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEtE,MAAM,WAAW,kBAAkB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,YAAY,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,iBAAiB,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB,KAAK,IAAI,CAAC;AAQvF,MAAM,WAAW,cAAc;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,CAAC;AAQ9D,MAAM,WAAW,qBAAqB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,MAAM,oBAAoB,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,qBAAqB,KAAK,IAAI,CAAC;AAU/F,MAAM,CAAC,OAAO,OAAO,YAAY;;WAehB,eAAe,CACxB,EAAE,EAAE,EAAE,EACN,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,iBAAiB,CAAA;KAAE,GACrH,OAAO,CAAC,IAAI,CAAC;WASH,eAAe,CACxB,EAAE,EAAE,EAAE,EACN,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,YAAY,CAAC;QAAC,MAAM,CAAC,EAAE,iBAAiB,CAAA;KAAE,GAC3H,OAAO,CAAC,IAAI,CAAC;WASH,gBAAgB,CACzB,EAAE,EAAE,EAAE,EACN,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GACvG,OAAO,CAAC,MAAM,CAAC;WAML,iBAAiB,CAC1B,EAAE,EAAE,EAAE,EACN,EAAE,cAAc,EAAE,MAAM,EAAE,EAAE;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GACvE,OAAO,CAAC,IAAI,CAAC;WAIH,sBAAsB,CAC/B,EAAE,EAAE,EAAE,EACN,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GACvD,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAIpE"}
@@ -12,6 +12,12 @@ export default class ChannelWrite {
12
12
  static #openSubStmt(db) { return db.open_subscription; }
13
13
  static #closeSubStmt(db) { return db.close_subscription; }
14
14
  static #findActiveStmt(db) { return db.find_active_subscription; }
15
+ // The entry's target URI for stream notifications (#179). A NULL scheme is
16
+ // a filesystem entry (the file scheme stores scheme=NULL), so it decodes to
17
+ // file://.
18
+ static #targetUri(scheme, pathname) {
19
+ return `${scheme === null ? "file" : scheme}://${pathname}`;
20
+ }
15
21
  static async appendToChannel(db, { entryId, channel, chunk, notify }) {
16
22
  const result = await ChannelWrite.#appendStmt(db).run({ chunk, entry_id: entryId, channel });
17
23
  if (result.changes === 0)
@@ -21,7 +27,7 @@ export default class ChannelWrite {
21
27
  const meta = await ChannelWrite.#channelMeta(db).get({ entry_id: entryId, channel });
22
28
  if (meta === undefined)
23
29
  return;
24
- notify(meta.session_id, { entryId, channel, state: meta.state, contentLength: meta.contentLength });
30
+ notify(meta.session_id, { entryId, target: ChannelWrite.#targetUri(meta.scheme, meta.pathname), channel, state: meta.state, contentLength: meta.contentLength });
25
31
  }
26
32
  static async setChannelState(db, { entryId, channel, state, notify }) {
27
33
  const result = await ChannelWrite.#stateStmt(db).run({ state, entry_id: entryId, channel });
@@ -32,7 +38,7 @@ export default class ChannelWrite {
32
38
  const meta = await ChannelWrite.#channelMeta(db).get({ entry_id: entryId, channel });
33
39
  if (meta === undefined)
34
40
  return;
35
- notify(meta.session_id, { entryId, channel, state: meta.state, contentLength: meta.contentLength });
41
+ notify(meta.session_id, { entryId, target: ChannelWrite.#targetUri(meta.scheme, meta.pathname), channel, state: meta.state, contentLength: meta.contentLength });
36
42
  }
37
43
  static async openSubscription(db, { runId, entryId, scheme, handle }) {
38
44
  const row = await ChannelWrite.#openSubStmt(db).get({ run_id: runId, entry_id: entryId, scheme, handle });
@@ -1 +1 @@
1
- {"version":3,"file":"ChannelWrite.js","sourceRoot":"","sources":["../../src/core/ChannelWrite.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ChannelWrite.js","sourceRoot":"","sources":["../../src/core/ChannelWrite.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,7 @@ import type SchemeRegistry from "./SchemeRegistry.ts";
3
3
  import { Mimetypes } from "@plurnk/plurnk-mimetypes";
4
4
  import type { Db } from "./Db.ts";
5
5
  import type { LoopFlags } from "./scheme-types.ts";
6
+ import type ExecutorRegistry from "./ExecutorRegistry.ts";
6
7
  import type { StreamEventNotify, TelemetryEventNotify, WakeRunNotify } from "./ChannelWrite.ts";
7
8
  type Origin = "model" | "client" | "system" | "plugin";
8
9
  type ChatMessage = {
@@ -66,6 +67,7 @@ export default class Engine {
66
67
  telemetryEventNotify?: TelemetryEventNotify;
67
68
  tokenize?: (text: string) => number;
68
69
  });
70
+ setExecutors(executors: ExecutorRegistry): void;
69
71
  runLoop({ provider, messages, persona, requirements, sessionId, runId, loopId, maxTurns, maxStrikes, minCycles, maxCyclePeriod, origin, signal, onDispatch, }: {
70
72
  provider: Provider;
71
73
  messages: ChatMessage[];
@@ -1 +1 @@
1
- {"version":3,"file":"Engine.d.ts","sourceRoot":"","sources":["../../src/core/Engine.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAA4D,MAAM,wBAAwB,CAAC;AAMxH,OAAO,KAAK,cAAc,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAiB,MAAM,0BAA0B,CAAC;AACpE,OAAO,KAAK,EAAE,EAAE,EAAc,MAAM,SAAS,CAAC;AAK9C,OAAO,KAAK,EAAmD,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEpG,OAAO,KAAK,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AA4EhG,KAAK,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAEvD,KAAK,WAAW,GAAG;IAAE,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAG9E,OAAO,KAAK,EAAE,QAAQ,EAAsD,MAAM,0BAA0B,CAAC;AA6C7G,KAAK,eAAe,GAAG;IACnB,SAAS,EAAE,eAAe,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7C,CAAC;AAEF,KAAK,cAAc,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAAC;AAOjF,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;AAC9D,MAAM,WAAW,kBAAkB;IAC/B,QAAQ,EAAE,gBAAgB,CAAC;IAK3B,IAAI,CAAC,EAAE,MAAM,CAAC;IAKd,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAYD,MAAM,WAAW,oBAAoB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,CAAC;CACpB;AAuGD,MAAM,CAAC,OAAO,OAAO,MAAM;;IACvB,MAAM,CAAC,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAUhF,MAAM,CAAC,eAAe,CAAC,GAAG,EAAE,aAAa,CAAC,eAAe,CAAC,GAAG,MAAM;IAQnE,MAAM,CAAC,WAAW,CACd,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,EAC9B,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,GACvB;QAAE,QAAQ,EAAE,KAAK,CAAA;KAAE,GAAG;QAAE,QAAQ,EAAE,IAAI,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;gBAiE/D,EAAE,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,aAAa,EAAE,oBAAoB,EAAE,QAAQ,EAAE,EAAE;QACtG,EAAE,EAAE,EAAE,CAAC;QACP,OAAO,EAAE,cAAc,CAAC;QACxB,SAAS,CAAC,EAAE,SAAS,CAAC;QACtB,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;QACtC,aAAa,CAAC,EAAE,aAAa,CAAC;QAC9B,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;QAC5C,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;KACvC;IA2DK,OAAO,CAAC,EACV,QAAQ,EAAE,QAAQ,EAAE,OAAY,EAAE,YAAiB,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAC7E,QAAa,EAAE,UAA6B,EAC5C,SAAoE,EACpE,cAAqF,EACrF,MAAgB,EAAE,MAAM,EAAE,UAAU,GACvC,EAAE;QACC,QAAQ,EAAE,QAAQ,CAAC;QACnB,QAAQ,EAAE,WAAW,EAAE,CAAC;QAIxB,OAAO,CAAC,EAAE,MAAM,CAAC;QAIjB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QACjD,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,WAAW,CAAC;QACrB,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;KAC7C,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,WAAW,GAAG,kBAAkB,GAAG,iBAAiB,GAAG,UAAU,GAAG,IAAI,CAAA;KAAE,CAAC;IAqHzJ,OAAO,CAAC,EACV,QAAQ,EAAE,QAAQ,EAAE,OAAY,EAAE,YAAiB,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,MAAgB,EAAE,MAAM,EAAE,UAAU,EACnH,UAAc,EAAE,QAAa,GAChC,EAAE;QACC,QAAQ,EAAE,QAAQ,CAAC;QACnB,QAAQ,EAAE,WAAW,EAAE,CAAC;QACxB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QACjD,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,WAAW,CAAC;QACrB,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;QAK1C,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACrB,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,OAAO,CAAC;QAAC,cAAc,EAAE,OAAO,CAAA;KAAE,CAAC;IAslBlI,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IA6JjE,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,kBAAkB,GAAG,IAAI;IAYzE,kBAAkB,IAAI,MAAM,EAAE;IAQxB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAiBpD,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAChD;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAC7C;IAgCD,iBAAiB,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,oBAAoB,KAAK,IAAI,GAAG,IAAI;CA0Y3E"}
1
+ {"version":3,"file":"Engine.d.ts","sourceRoot":"","sources":["../../src/core/Engine.ts"],"names":[],"mappings":"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"}
@@ -6,12 +6,12 @@ import EntryManifest from "../schemes/_entry-manifest.js";
6
6
  import GitMembership from "./git-membership.js";
7
7
  import { DEFAULT_LOOP_FLAGS } from "./scheme-types.js";
8
8
  import { LineMarkerOps, MimetypeBinary } from "../content/index.js";
9
- // Plain JS module shared with bin/digest.js so wire projection and
10
- // digest projection are structurally one function. tsconfig.build.json
11
- // has allowJs:true so this gets copied through to dist/.
9
+ // Shared module imported by both Engine and bin/digest.ts, so wire
10
+ // projection and digest projection are structurally one function — no
11
+ // drift between wire and digest possible.
12
12
  import PacketWire from "./packet-wire.js";
13
13
  // SPEC §3.6: writer must be in target scheme's manifest.writableBy.
14
- // SHOW/HIDE/READ/FIND are not gated — they touch visibility metadata or read.
14
+ // SHOW/HIDE/READ/FIND are not gated — they curate the log or read, never mutating an entry.
15
15
  const MUTATING_OPS = new Set(["EDIT", "SEND", "COPY", "MOVE", "EXEC"]);
16
16
  const DEFAULT_PREVIEW_BUDGET = 256;
17
17
  const DEFAULT_MAX_STRIKES = 3;
@@ -202,6 +202,9 @@ class Engine {
202
202
  // construction before a provider is wired (same boot affordance as
203
203
  // Mimetypes, §4.5). Real counts come from provider.countTokens.
204
204
  #tokenize;
205
+ // Boot-discovered runtime executors. Daemon builds + sets via
206
+ // setExecutors at start(); undefined until then (and in bare tests).
207
+ #executors;
205
208
  // Per-loop transient buffer of actionless failures pending surface in the
206
209
  // NEXT packet's user.telemetry.errors[]. Drained by #buildTelemetryErrors.
207
210
  // Map<loopId, TelemetryError[]>. SPEC §15.1.
@@ -256,6 +259,11 @@ class Engine {
256
259
  // wired by the Daemon. Real counts come from provider.countTokens.
257
260
  this.#tokenize = tokenize ?? ((text) => Math.ceil(text.length / 4));
258
261
  }
262
+ // Late injection: the executor registry is async-built at daemon start()
263
+ // (discover + probe), after Engine construction.
264
+ setExecutors(executors) {
265
+ this.#executors = executors;
266
+ }
259
267
  #pushTelemetry(sessionId, loopId, event) {
260
268
  const existing = this.#telemetryBuffer.get(loopId);
261
269
  if (existing === undefined)
@@ -479,9 +487,9 @@ class Engine {
479
487
  // prompt-composition (EMI is eager + relevance-bounded). When the
480
488
  // session's project_root is a git working tree, tracked files are
481
489
  // members without a client `add`; active members are materialized
482
- // (disk → body channel + visibility) so they surface in the index
483
- // below. No-ops on headless / non-git sessions. Runs BEFORE the
484
- // manifest + index build so this turn's packet reflects them.
490
+ // (disk → body channel) so they appear in the manifest below. No-ops
491
+ // on headless / non-git sessions. Runs BEFORE the manifest write so
492
+ // this turn's packet reflects them.
485
493
  await GitMembership.indexGitMembership(systemCtx);
486
494
  await EntryCrud.writeEntry("manifest.json", {
487
495
  channels: { body: { content: await EntryManifest.buildManifestBody(systemCtx, this.#previewBudget), mimetype: "application/json" } },
@@ -651,6 +659,16 @@ class Engine {
651
659
  }
652
660
  }
653
661
  }
662
+ // The grammar also reports an `unparsedTail` when input ends
663
+ // mid-statement (a body opened but never closed): its `reason`
664
+ // names the op AND the fix ("…never closed — add `:READ`"), where
665
+ // the item-level error only says "expected close tag" for a tag the
666
+ // model thinks it already wrote. Surface it — phenomenal messages
667
+ // the model can self-correct from are the whole point of the DSL.
668
+ const tail = parsed.unparsedTail;
669
+ if (tail !== undefined) {
670
+ parseErrors.push({ message: tail.reason, line: tail.from.line, column: tail.from.column, source: "grammar" });
671
+ }
654
672
  }
655
673
  const wireReasoning = assistant.reasoning ?? "";
656
674
  const scrapedReasoning = textFragments.join("\n");
@@ -683,7 +701,6 @@ class Engine {
683
701
  // query; null result means no DB override exists, use the default.
684
702
  const row = await this.#db.engine_resolve_persona.get({ loop_id: loopId });
685
703
  const persona = (row?.persona !== undefined && row?.persona !== null) ? row.persona : defaultPersona;
686
- const index = await this.#buildIndex(runId, loopId);
687
704
  const log = await this.#buildLog(runId);
688
705
  const telemetryErrors = presetTelemetry ?? await this.#buildTelemetryErrors(loopId, currentTurnSeq);
689
706
  // Per-section render-cost subtotals via provider's tokenizer.
@@ -701,7 +718,7 @@ class Engine {
701
718
  // headline omitted, section lines still shown).
702
719
  const ceiling = _a.computeCeiling(provider.contextSize, this.#budgetCeiling);
703
720
  const scratch = {
704
- system: { system_definition, persona, index, log },
721
+ system: { system_definition, persona, log },
705
722
  user: { prompt, telemetry: { budget: "", errors: telemetryErrors }, system_requirements: requirements },
706
723
  };
707
724
  const sections = PacketWire.measureBudgetSections(scratch, countTokens);
@@ -715,7 +732,7 @@ class Engine {
715
732
  .replace(TOKEN_USAGE_PLACEHOLDER, String(total))
716
733
  .replace(TOKEN_PERCENT_PLACEHOLDER, String(percent))
717
734
  .replace(TOKENS_FREE_PLACEHOLDER, String(tokensFree));
718
- const system = { tokens: 0, system_definition, persona, index, log };
735
+ const system = { tokens: 0, system_definition, persona, log };
719
736
  const user = { tokens: 0, prompt, telemetry: { budget, errors: telemetryErrors }, system_requirements: requirements };
720
737
  system.tokens = countTokens(PacketWire.renderSystemContent(system));
721
738
  user.tokens = countTokens(PacketWire.renderUserContent(user));
@@ -729,8 +746,6 @@ class Engine {
729
746
  const lines = [];
730
747
  if (ceiling !== null)
731
748
  lines.push(`ceiling ${ceiling} · usage ${TOKEN_USAGE_PLACEHOLDER} (${TOKEN_PERCENT_PLACEHOLDER}%) · free ${TOKENS_FREE_PLACEHOLDER}`);
732
- if (sections.index.channels > 0)
733
- lines.push(`Index previews: ${sections.index.channels} channels, ${sections.index.tokens} tokens`);
734
749
  if (sections.log.entries > 0) {
735
750
  lines.push(`Log entries: ${sections.log.entries} entries, ${sections.log.tokens} tokens`);
736
751
  if (sections.log.byScheme.length > 0) {
@@ -766,15 +781,9 @@ class Engine {
766
781
  this.#emitBudgetOverflow(sessionId, loopId, hidden);
767
782
  return { packet: current, fit: true, struck: turnNumber > 1 };
768
783
  }
769
- // Pass 2 index collapse: hide every catalog entry except the manifest.
770
- const catalog = await this.#db.engine_grinder_catalog.all({ run_id: runId, session_id: sessionId });
771
- for (const c of catalog)
772
- note(c.scheme);
773
- if (catalog.length > 0) {
774
- const pairs = JSON.stringify(catalog.map((c) => ({ entry_id: c.entry_id, channel: c.channel })));
775
- await this.#db.engine_grinder_hide_catalog.run({ run_id: runId, pairs });
776
- }
777
- current = catalog.length > 0 ? await rebuild(errors) : current;
784
+ // Prior-turn rollback is the only budget lever now: entries don't render
785
+ // (no index), so there is no catalog to collapse. If pass 1 didn't fit,
786
+ // the packet is over and the caller hard-413s.
778
787
  this.#emitBudgetOverflow(sessionId, loopId, hidden);
779
788
  return { packet: current, fit: measure(current) <= ceiling, struck: turnNumber > 1 };
780
789
  }
@@ -790,8 +799,8 @@ class Engine {
790
799
  hidden: [...hidden.entries()].map(([scheme, count]) => ({ scheme, count })),
791
800
  });
792
801
  }
793
- // Wire projection lives in ./packet-wire.js (plain JS) so Engine and
794
- // bin/digest.js import the exact same function — structurally one
802
+ // Wire projection lives in ./packet-wire.ts so Engine and
803
+ // bin/digest.ts import the exact same function — structurally one
795
804
  // implementation, no drift between wire and digest possible.
796
805
  // Format: markdown (user pick over rummy's XML alternative, 2026-05-22).
797
806
  #packetToWireMessages(packet) {
@@ -874,66 +883,6 @@ class Engine {
874
883
  mimetype_tx: r.mimetype_tx,
875
884
  }));
876
885
  }
877
- async #buildIndex(runId, currentLoopId) {
878
- const rows = await this.#db.engine_render_index.all({ run_id: runId });
879
- const tagsStmt = this.#db.engine_entry_tags;
880
- // Foist the CURRENT loop's prompt entries out of the index render —
881
- // their bodies are materialized in packet.user.prompt instead. With
882
- // multi-turn injection, a loop can have multiple prompt entries at
883
- // plurnk://prompt/<loop_id>/<N>; all of them get foisted, leaving
884
- // only previous loops' prompts (still addressable for HIDE).
885
- const foistedPrefix = `prompt/${currentLoopId}/`;
886
- // Backward compat: legacy single-slot path. Tests / older runs may
887
- // still have a `prompt/<loop_id>` entry (no trailing /N); foist it too.
888
- const foistedExact = `prompt/${currentLoopId}`;
889
- const entries = new Map();
890
- for (const row of rows) {
891
- if (row.scheme === "plurnk"
892
- && (row.pathname === foistedExact || row.pathname.startsWith(foistedPrefix)))
893
- continue;
894
- let entry = entries.get(row.entry_id);
895
- if (entry === undefined) {
896
- const tagRows = await tagsStmt.all({ entry_id: row.entry_id });
897
- // defaultChannel pulled from the row's scheme manifest. The
898
- // wire renderer uses it to omit `#channel` on fences whose
899
- // channel is the scheme's default — that absence is the
900
- // addressing of the default channel.
901
- const handler = this.#schemes.get(row.scheme ?? "");
902
- const manifest = handler?.constructor?.manifest;
903
- entry = {
904
- id: row.entry_id,
905
- version: row.version,
906
- scope: row.scope,
907
- session_id: row.session_id,
908
- scheme: row.scheme,
909
- username: row.username,
910
- password: row.password,
911
- hostname: row.hostname,
912
- port: row.port,
913
- pathname: row.pathname,
914
- params: row.params === null ? null : JSON.parse(row.params),
915
- channels: {},
916
- defaultChannel: manifest?.defaultChannel ?? "",
917
- attributes: JSON.parse(row.attributes),
918
- tags: tagRows.map((r) => r.tag),
919
- };
920
- entries.set(row.entry_id, entry);
921
- }
922
- // Mimetypes.process owns the full preview pipeline: detect (or
923
- // honor the hint), resolve handler, validate, extract → symbols,
924
- // budget-truncate via the framework's fit/fitContent. Passing
925
- // `hint: row.mimetype` short-circuits detection — service already
926
- // knows what each channel is.
927
- const result = await this.#mimetypes.process({ content: row.content, hint: row.mimetype }, { budget: this.#previewBudget });
928
- entry.channels[row.channel] = {
929
- content: result.preview,
930
- mimetype: row.mimetype,
931
- tokens: row.tokens,
932
- lines: result.totalLines,
933
- };
934
- }
935
- return [...entries.values()];
936
- }
937
886
  async dispatch(context) {
938
887
  const { statement, sessionId, runId, loopId, turnId, sequence, origin, onDispatch } = context;
939
888
  const schemeCtx = {
@@ -946,6 +895,7 @@ class Engine {
946
895
  mimetypes: this.#mimetypes,
947
896
  tokenize: this.#tokenize,
948
897
  pushTelemetry: (event) => this.#pushTelemetry(sessionId, loopId, event),
898
+ executors: this.#executors,
949
899
  };
950
900
  let result;
951
901
  let denial = this.#checkWritable(statement, origin);
@@ -998,6 +948,13 @@ class Engine {
998
948
  // 202 in the result the caller sees, so runTurn never branches on
999
949
  // a pending state.
1000
950
  if (result.status === 202) {
951
+ // Effect-gated auto-run (read/pure runtimes, plurnk-service#182):
952
+ // no human gate, no loop/proposal notification. Accept + apply
953
+ // in-process; the model sees the outcome directly, never a review.
954
+ if (result.attrs?.inline === true) {
955
+ const effective = await this.#runApplyResolution(statement, result, { decision: "accept" }, { sessionId, runId, loopId, turnId });
956
+ return this.#applyResolution(logEntryId, effective);
957
+ }
1001
958
  // Register the resolution waiter SYNCHRONOUSLY before any await
1002
959
  // yields. A same-tick resolveProposal() (e.g. from a test that
1003
960
  // awaits the onDispatch callback and immediately resolves) must
@@ -1060,6 +1017,7 @@ class Engine {
1060
1017
  wakeRunNotify: this.#wakeRunNotify,
1061
1018
  tokenize: this.#tokenize,
1062
1019
  pushTelemetry: (event) => this.#pushTelemetry(sessionId, loopId, event),
1020
+ executors: this.#executors,
1063
1021
  };
1064
1022
  const applyResult = await handler.applyResolution({
1065
1023
  attrs: (originalResult.attrs ?? {}),
@@ -1073,14 +1031,14 @@ class Engine {
1073
1031
  };
1074
1032
  }
1075
1033
  // Propagate applyResolution.outcome onto the accepted resolution
1076
- // so the log entry's outcome column reflects operational metadata
1077
- // (e.g. exec's "exit_N"). Without this, only failures get an
1078
- // outcome on the durable record, and "ran cleanly but with a
1079
- // notable detail" has nowhere to land.
1080
- if (applyResult.outcome !== undefined && resolution.outcome === undefined) {
1081
- return { ...resolution, outcome: applyResult.outcome };
1082
- }
1083
- return resolution;
1034
+ // (operational metadata, e.g. exec's "exit_N") AND its body — an
1035
+ // inline (read/pure) run returns its output as the body, which has
1036
+ // to reach the model-facing result this turn, not just stream to
1037
+ // the entry. Host accepts carry no body (fire-and-forget).
1038
+ const withOutcome = applyResult.outcome !== undefined && resolution.outcome === undefined
1039
+ ? { ...resolution, outcome: applyResult.outcome }
1040
+ : resolution;
1041
+ return applyResult.body === undefined ? withOutcome : { ...withOutcome, body: applyResult.body };
1084
1042
  }
1085
1043
  catch (err) {
1086
1044
  return {
@@ -1216,13 +1174,15 @@ class Engine {
1216
1174
  : decision === "reject" ? "rejected"
1217
1175
  : "loop_aborted";
1218
1176
  const outcome = resolution.outcome ?? defaultOutcome;
1219
- // rx is the model-facing operation result. ONLY status outcome
1220
- // is operational (security/admin) and stays on the log_entries
1221
- // column for forensics; body was an input echo with no value to
1222
- // the model; target/path lives in log_entries metadata and
1223
- // surfaces via the log section's `target` field uniformly.
1177
+ // rx is the model-facing operation result. Status always; outcome is
1178
+ // operational (stays on log_entries for forensics, never model-facing).
1179
+ // Body is normally dropped — the propose preview was an input echo
1180
+ // EXCEPT an inline auto-run (read/pure) carries its run output AS the
1181
+ // body, which is exactly the "what happened" the model needs this turn.
1224
1182
  // Per AGENTS.md "Operational hygiene on what the model sees."
1225
- const rx = JSON.stringify({ status });
1183
+ const rx = (decision === "accept" && resolution.body !== undefined)
1184
+ ? JSON.stringify({ status, body: resolution.body })
1185
+ : JSON.stringify({ status });
1226
1186
  await this.#db.engine_resolve_log_entry.run({
1227
1187
  id: logEntryId, state, outcome, status_rx: status, rx,
1228
1188
  });
@@ -1277,7 +1237,7 @@ class Engine {
1277
1237
  return { status: 403, error: `writer '${origin}' is not in writableBy for scheme '${schemeName}'` };
1278
1238
  }
1279
1239
  // Per-loop flag gating. Schemes self-declare their flag affinity in
1280
- // their manifest (proposes / excludedInAsk / requiresWeb /
1240
+ // their manifest (excludedInAsk / requiresWeb /
1281
1241
  // requiresInteraction); SchemeRegistry.resolveForLoop returns the
1282
1242
  // active set under the loop's persisted flags. Anything outside the
1283
1243
  // set returns 403 — action-entry-as-outcome carries the rejection.
@@ -1287,7 +1247,7 @@ class Engine {
1287
1247
  return null;
1288
1248
  const flags = await this.#loadLoopFlags(loopId);
1289
1249
  // Fast path: default flags gate nothing. (yolo never gates.)
1290
- if (!flags.noProposals && !flags.noWeb && !flags.noInteraction && flags.mode === "act")
1250
+ if (!flags.noWeb && !flags.noInteraction && flags.mode === "act")
1291
1251
  return null;
1292
1252
  const active = this.#schemes.resolveForLoop(flags);
1293
1253
  const check = (target) => {
@@ -1409,7 +1369,7 @@ class Engine {
1409
1369
  const dstNames = Object.keys(dstChannels).sort();
1410
1370
  const sameContent = writeNames.length === dstNames.length
1411
1371
  && writeNames.every((n, i) => n === dstNames[i] && (channels[n]?.content ?? "") === (dstChannels[n]?.content ?? ""));
1412
- const sameTags = [...tags].sort().join("") === [...dstExisting.entry.tags].sort().join("");
1372
+ const sameTags = [...tags].sort().join("") === [...dstExisting.entry.tags].sort().join("");
1413
1373
  if (sameContent && sameTags)
1414
1374
  return { status: 304 };
1415
1375
  return { status: 409, error: `COPY/MOVE destination exists: ${dstSchemeName}://${dstPathname}` };
@@ -1465,19 +1425,23 @@ class Engine {
1465
1425
  let attrsObj = (result.attrs !== undefined && result.attrs !== null)
1466
1426
  ? { ...result.attrs }
1467
1427
  : {};
1468
- // EXEC pathname is coordinate-based the stream entry lives at
1469
- // exec://<loop_seq>/<turn_seq>/<sequence>/EXEC, mirroring the log
1470
- // row's own URI at log://<...>/EXEC. The model can correlate the
1471
- // log meta to its stream output by structural parallelism no
1472
- // random slug injection. Coordinate is resolved here because both
1473
- // log row write and applyResolution need it.
1428
+ // EXEC pathname is executor-domain + coordinate: the stream entry
1429
+ // lives at exec://<runtime>/<loop_seq>/<turn_seq>/<sequence> (e.g.
1430
+ // exec://sh/1/1/2). The runtime leads domain-aware, the executor
1431
+ // as authority and the coordinate that follows is already unique
1432
+ // per statement, so no slug is injected. The log row's target points
1433
+ // at this same address; its log:// coordinate shares the trailing
1434
+ // <loop>/<turn>/<seq>, so the model correlates op to stream output.
1435
+ // Runtime comes from statement.signal (EXEC's runtime slot) so it's
1436
+ // resolvable for failed execs too; empty/absent = the default shell.
1474
1437
  if (statement.op === "EXEC") {
1475
1438
  const seqs = await this.#db.engine_loop_turn_seqs.get({
1476
1439
  loop_id: loopId, turn_id: turnId,
1477
1440
  });
1478
1441
  if (seqs === undefined)
1479
1442
  throw new Error(`Engine.#writeLog: loop_turn_seqs returned no row for loop=${loopId} turn=${turnId}`);
1480
- const coordPathname = `${seqs.loop_seq}/${seqs.turn_seq}/${sequence}/EXEC`;
1443
+ const runtime = (typeof statement.signal === "string" && statement.signal.length > 0) ? statement.signal : "sh";
1444
+ const coordPathname = `${runtime}/${seqs.loop_seq}/${seqs.turn_seq}/${sequence}`;
1481
1445
  target.scheme = "exec";
1482
1446
  target.pathname = coordPathname;
1483
1447
  attrsObj.pathname = coordPathname;
@@ -1485,8 +1449,7 @@ class Engine {
1485
1449
  // hands originalResult.attrs to handler.applyResolution after
1486
1450
  // proposal accept (see #acceptResolution). Both views — the
1487
1451
  // stored row AND the in-memory proposal — need the same
1488
- // coordinate-based pathname so applyResolution writes the
1489
- // entry at exec://<coord>/EXEC.
1452
+ // pathname so applyResolution writes the entry at the same URI.
1490
1453
  if (result.attrs !== undefined && result.attrs !== null) {
1491
1454
  result.attrs.pathname = coordPathname;
1492
1455
  }