@codeworksh/plugin 0.0.1-dev.20260925150557 → 0.1.0-canary.16.1.gfa1c6c4c

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/README.md CHANGED
@@ -52,20 +52,28 @@ for a capability such as `SandboxIO.Shell`.
52
52
  ## A prompt plugin
53
53
 
54
54
  ```ts
55
- import { Plugin } from "@codeworksh/plugin";
55
+ import { Plugin, Section } from "@codeworksh/plugin";
56
+
57
+ const GithubPrRules = Section.define("github_pr_rules", { format: "list" });
56
58
 
57
59
  export default Plugin.define({
58
60
  id: "acme.prompt.house-style",
59
61
  kind: "prompt",
60
62
  setup(ctx) {
61
- // `set` replaces the whole prompt, so compose on what earlier plugins rendered.
62
- const existing = ctx.plugin.prompt.get();
63
- const section = "## House style\n\n- No `any`.";
64
- ctx.plugin.prompt.set(existing === undefined ? section : `${existing}\n\n${section}`);
63
+ // Merges into the one <rules> every plugin writes to.
64
+ ctx.plugin.prompt.sections.append(Section.Rules, "No `any`.");
65
+ // Opens <github_pr_rules> on first use; later appends, from any plugin, land in it.
66
+ ctx.plugin.prompt.sections.append(GithubPrRules, "Link the issue in every PR description.");
65
67
  },
66
68
  });
67
69
  ```
68
70
 
71
+ The harness renders the system prompt from what plugins wrote: the foundation first and untagged
72
+ (`ctx.plugin.prompt.foundation.set`), then `<tools>`, `<rules>`, `<addendum>`, `<project_context>`,
73
+ `<skills>`, `<cwd>`, and custom sections in the order they were first written. `tools` and `cwd`
74
+ belong to the harness. A `list` section renders its entries as deduplicated `- ` bullets; a `text`
75
+ section (the default) keeps them verbatim, separated by a blank line.
76
+
69
77
  ## `kind` decides when a plugin runs
70
78
 
71
79
  Every `tool` plugin runs before any `prompt` plugin, whichever settings layer each came from, so a
@@ -147,13 +147,26 @@ declare const AikitAssistantMessage: Schema.decodeTo<Schema.declare<{
147
147
  completed: number;
148
148
  };
149
149
  parts: ({
150
+ type: "text";
151
+ text: string;
152
+ textSignature?: string;
153
+ } | {
154
+ type: "image";
155
+ data: string;
156
+ mimeType: string;
157
+ } | {
158
+ type: "thinking";
159
+ thinking: string;
160
+ thinkingSignature?: string;
161
+ redacted?: boolean;
162
+ } | {
150
163
  addedToolNames?: string[];
151
164
  arguments: Record<string, any>;
152
165
  callID: string;
153
166
  name: string;
154
167
  namespace?: string;
155
- result: {
156
- content: ({
168
+ partial?: {
169
+ content?: ({
157
170
  type: "text";
158
171
  text: string;
159
172
  textSignature?: string;
@@ -163,9 +176,8 @@ declare const AikitAssistantMessage: Schema.decodeTo<Schema.declare<{
163
176
  mimeType: string;
164
177
  })[];
165
178
  details?: any;
166
- isError: false;
167
179
  };
168
- status: "completed";
180
+ status: "running";
169
181
  thoughtSignature?: string;
170
182
  time: {
171
183
  start: number;
@@ -189,9 +201,9 @@ declare const AikitAssistantMessage: Schema.decodeTo<Schema.declare<{
189
201
  mimeType: string;
190
202
  })[];
191
203
  details?: any;
192
- isError: true;
204
+ isError: false;
193
205
  };
194
- status: "error";
206
+ status: "completed";
195
207
  thoughtSignature?: string;
196
208
  time: {
197
209
  start: number;
@@ -217,7 +229,7 @@ declare const AikitAssistantMessage: Schema.decodeTo<Schema.declare<{
217
229
  details?: any;
218
230
  isError: true;
219
231
  };
220
- status: "skipped";
232
+ status: "error";
221
233
  thoughtSignature?: string;
222
234
  time: {
223
235
  start: number;
@@ -243,34 +255,21 @@ declare const AikitAssistantMessage: Schema.decodeTo<Schema.declare<{
243
255
  details?: any;
244
256
  isError: true;
245
257
  };
246
- status: "aborted";
258
+ status: "skipped";
247
259
  thoughtSignature?: string;
248
260
  time: {
249
261
  start: number;
250
262
  end: number;
251
263
  };
252
264
  type: "toolCall";
253
- } | {
254
- type: "text";
255
- text: string;
256
- textSignature?: string;
257
- } | {
258
- type: "image";
259
- data: string;
260
- mimeType: string;
261
- } | {
262
- type: "thinking";
263
- thinking: string;
264
- thinkingSignature?: string;
265
- redacted?: boolean;
266
265
  } | {
267
266
  addedToolNames?: string[];
268
267
  arguments: Record<string, any>;
269
268
  callID: string;
270
269
  name: string;
271
270
  namespace?: string;
272
- partial?: {
273
- content?: ({
271
+ result: {
272
+ content: ({
274
273
  type: "text";
275
274
  text: string;
276
275
  textSignature?: string;
@@ -280,8 +279,9 @@ declare const AikitAssistantMessage: Schema.decodeTo<Schema.declare<{
280
279
  mimeType: string;
281
280
  })[];
282
281
  details?: any;
282
+ isError: true;
283
283
  };
284
- status: "running";
284
+ status: "aborted";
285
285
  thoughtSignature?: string;
286
286
  time: {
287
287
  start: number;
@@ -447,13 +447,26 @@ declare const AikitAssistantMessage: Schema.decodeTo<Schema.declare<{
447
447
  completed: number;
448
448
  };
449
449
  parts: ({
450
+ type: "text";
451
+ text: string;
452
+ textSignature?: string;
453
+ } | {
454
+ type: "image";
455
+ data: string;
456
+ mimeType: string;
457
+ } | {
458
+ type: "thinking";
459
+ thinking: string;
460
+ thinkingSignature?: string;
461
+ redacted?: boolean;
462
+ } | {
450
463
  addedToolNames?: string[];
451
464
  arguments: Record<string, any>;
452
465
  callID: string;
453
466
  name: string;
454
467
  namespace?: string;
455
- result: {
456
- content: ({
468
+ partial?: {
469
+ content?: ({
457
470
  type: "text";
458
471
  text: string;
459
472
  textSignature?: string;
@@ -463,9 +476,8 @@ declare const AikitAssistantMessage: Schema.decodeTo<Schema.declare<{
463
476
  mimeType: string;
464
477
  })[];
465
478
  details?: any;
466
- isError: false;
467
479
  };
468
- status: "completed";
480
+ status: "running";
469
481
  thoughtSignature?: string;
470
482
  time: {
471
483
  start: number;
@@ -489,9 +501,9 @@ declare const AikitAssistantMessage: Schema.decodeTo<Schema.declare<{
489
501
  mimeType: string;
490
502
  })[];
491
503
  details?: any;
492
- isError: true;
504
+ isError: false;
493
505
  };
494
- status: "error";
506
+ status: "completed";
495
507
  thoughtSignature?: string;
496
508
  time: {
497
509
  start: number;
@@ -517,7 +529,7 @@ declare const AikitAssistantMessage: Schema.decodeTo<Schema.declare<{
517
529
  details?: any;
518
530
  isError: true;
519
531
  };
520
- status: "skipped";
532
+ status: "error";
521
533
  thoughtSignature?: string;
522
534
  time: {
523
535
  start: number;
@@ -543,34 +555,21 @@ declare const AikitAssistantMessage: Schema.decodeTo<Schema.declare<{
543
555
  details?: any;
544
556
  isError: true;
545
557
  };
546
- status: "aborted";
558
+ status: "skipped";
547
559
  thoughtSignature?: string;
548
560
  time: {
549
561
  start: number;
550
562
  end: number;
551
563
  };
552
564
  type: "toolCall";
553
- } | {
554
- type: "text";
555
- text: string;
556
- textSignature?: string;
557
- } | {
558
- type: "image";
559
- data: string;
560
- mimeType: string;
561
- } | {
562
- type: "thinking";
563
- thinking: string;
564
- thinkingSignature?: string;
565
- redacted?: boolean;
566
565
  } | {
567
566
  addedToolNames?: string[];
568
567
  arguments: Record<string, any>;
569
568
  callID: string;
570
569
  name: string;
571
570
  namespace?: string;
572
- partial?: {
573
- content?: ({
571
+ result: {
572
+ content: ({
574
573
  type: "text";
575
574
  text: string;
576
575
  textSignature?: string;
@@ -580,8 +579,9 @@ declare const AikitAssistantMessage: Schema.decodeTo<Schema.declare<{
580
579
  mimeType: string;
581
580
  })[];
582
581
  details?: any;
582
+ isError: true;
583
583
  };
584
- status: "running";
584
+ status: "aborted";
585
585
  thoughtSignature?: string;
586
586
  time: {
587
587
  start: number;
@@ -892,4 +892,4 @@ declare function durable<const Definitions extends ReadonlyArray<Definition>>(de
892
892
  declare function latest(definitions: ReadonlyArray<Definition>): ReadonlyMap<string, Definition<string, Schema.Codec<unknown, unknown, never, never>>>;
893
893
  //#endregion
894
894
  export { ID as a, define as c, inventory as d, latest as f, Definition as i, durable as l, AikitToolCallTerminalPart as n, Payload as o, versionedType as p, Data as r, PublishOptions as s, AikitAssistantMessage as t, event_d_exports as u };
895
- //# sourceMappingURL=event-BnLveFBB.d.mts.map
895
+ //# sourceMappingURL=event-9PbbjnHJ.d.mts.map
package/event.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as ID, c as define, d as inventory, f as latest, i as Definition, l as durable, n as AikitToolCallTerminalPart, o as Payload, p as versionedType, r as Data, s as PublishOptions, t as AikitAssistantMessage, u as event_d_exports } from "./event-BnLveFBB.mjs";
1
+ import { a as ID, c as define, d as inventory, f as latest, i as Definition, l as durable, n as AikitToolCallTerminalPart, o as Payload, p as versionedType, r as Data, s as PublishOptions, t as AikitAssistantMessage, u as event_d_exports } from "./event-9PbbjnHJ.mjs";
2
2
  export { AikitAssistantMessage, AikitToolCallTerminalPart, Data, Definition, event_d_exports as EventSchema, ID, Payload, PublishOptions, define, durable, inventory, latest, versionedType };
package/ids.mjs CHANGED
@@ -10,7 +10,7 @@ import { uuidv7 } from "uuidv7";
10
10
  * twice is two types, and a plugin would have to cast to hand either back. They live here, in the
11
11
  * package both sides depend on, rather than being re-declared on each side.
12
12
  */
13
- const SessionID = Schema.String.check(Schema.isStartsWith("ses")).pipe(Schema.brand("Session.ID"), withStatics((schema) => ({
13
+ const SessionID = Schema.String.check(Schema.isStartingWith("ses")).pipe(Schema.brand("Session.ID"), withStatics((schema) => ({
14
14
  ascending: (id) => {
15
15
  if (!id) return schema.make("ses_" + uuidv7());
16
16
  if (!id.startsWith("ses")) throw new Error(`ID ${id} does not start with ses`);
package/ids.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ids.mjs","names":[],"sources":["../../src/ids.ts"],"sourcesContent":["import { Schema } from \"effect\";\nimport { uuidv7 } from \"uuidv7\";\nimport { withStatics } from \"./schema.ts\";\n\n/**\n * The identifiers that cross the plugin boundary.\n *\n * A plugin reads a session id off its context and a message id off every tool call, so both\n * brands have to be the ones the harness itself mints -- a structurally identical brand declared\n * twice is two types, and a plugin would have to cast to hand either back. They live here, in the\n * package both sides depend on, rather than being re-declared on each side.\n */\n\n// Session identity. Branded so a session ID is not interchangeable with an\n// entry, part, or workspace ID at the type level — service signatures take\n// `SessionID`, never a bare `string`.\n//\n// `create` mints a new one; `ascending` adopts an ID that came from outside\n// (a persisted row, a request payload) and rejects a foreign prefix rather\n// than branding it silently. uuidv7 keeps IDs lexicographically sortable by\n// creation time, so `ORDER BY id` is `ORDER BY created`.\nexport const SessionID = Schema.String.check(Schema.isStartsWith(\"ses\")).pipe(\n\tSchema.brand(\"Session.ID\"),\n\twithStatics((schema) => ({\n\t\tascending: (id?: string) => {\n\t\t\tif (!id) return schema.make(\"ses_\" + uuidv7());\n\t\t\tif (!id.startsWith(\"ses\")) throw new Error(`ID ${id} does not start with ses`);\n\t\t\treturn schema.make(id);\n\t\t},\n\t\tcreate: () => schema.make(\"ses_\" + uuidv7()),\n\t})),\n);\nexport type SessionID = typeof SessionID.Type;\n\n/**\n * A conversation message id.\n *\n * Deliberately unprefixed. aikit mints assistant message ids itself, as bare\n * uuidv7, and `stream()` accepts no id -- so any naming rule of ours would have\n * to be imposed on messages aikit hands us, by rewriting a field of the value we\n * were given. Sharing aikit's format instead means an id means the same thing on\n * both sides of the boundary and never needs translating.\n *\n * The brand carries the meaning; uuidv7 keeps ids time-ordered, so they sort by\n * creation.\n */\nexport const MessageID = Schema.String.pipe(\n\tSchema.brand(\"Message.ID\"),\n\twithStatics((schema) => ({\n\t\tcreate: () => schema.make(uuidv7()),\n\t\t/**\n\t\t * Adopt an id minted elsewhere -- in practice aikit's, which arrives as a\n\t\t * plain string on every stream event and inside every assistant message.\n\t\t *\n\t\t * `make` does the same thing. This exists so the boundary where a foreign\n\t\t * id enters the domain is named and greppable, and so the pairing with\n\t\t * `create` says which side chose the id.\n\t\t */\n\t\tfrom: (id: string) => schema.make(id),\n\t})),\n);\nexport type MessageID = typeof MessageID.Type;\n"],"mappings":";;;;;;;;;;;;AAqBA,MAAa,YAAY,OAAO,OAAO,MAAM,OAAO,aAAa,KAAK,CAAC,CAAC,CAAC,KACxE,OAAO,MAAM,YAAY,GACzB,aAAa,YAAY;CACxB,YAAY,OAAgB;EAC3B,IAAI,CAAC,IAAI,OAAO,OAAO,KAAK,SAAS,OAAO,CAAC;EAC7C,IAAI,CAAC,GAAG,WAAW,KAAK,GAAG,MAAM,IAAI,MAAM,MAAM,GAAG,yBAAyB;EAC7E,OAAO,OAAO,KAAK,EAAE;CACtB;CACA,cAAc,OAAO,KAAK,SAAS,OAAO,CAAC;AAC5C,EAAE,CACH;;;;;;;;;;;;;AAeA,MAAa,YAAY,OAAO,OAAO,KACtC,OAAO,MAAM,YAAY,GACzB,aAAa,YAAY;CACxB,cAAc,OAAO,KAAK,OAAO,CAAC;;;;;;;;;CASlC,OAAO,OAAe,OAAO,KAAK,EAAE;AACrC,EAAE,CACH"}
1
+ {"version":3,"file":"ids.mjs","names":[],"sources":["../../src/ids.ts"],"sourcesContent":["import { Schema } from \"effect\";\nimport { uuidv7 } from \"uuidv7\";\nimport { withStatics } from \"./schema.ts\";\n\n/**\n * The identifiers that cross the plugin boundary.\n *\n * A plugin reads a session id off its context and a message id off every tool call, so both\n * brands have to be the ones the harness itself mints -- a structurally identical brand declared\n * twice is two types, and a plugin would have to cast to hand either back. They live here, in the\n * package both sides depend on, rather than being re-declared on each side.\n */\n\n// Session identity. Branded so a session ID is not interchangeable with an\n// entry, part, or workspace ID at the type level — service signatures take\n// `SessionID`, never a bare `string`.\n//\n// `create` mints a new one; `ascending` adopts an ID that came from outside\n// (a persisted row, a request payload) and rejects a foreign prefix rather\n// than branding it silently. uuidv7 keeps IDs lexicographically sortable by\n// creation time, so `ORDER BY id` is `ORDER BY created`.\nexport const SessionID = Schema.String.check(Schema.isStartingWith(\"ses\")).pipe(\n\tSchema.brand(\"Session.ID\"),\n\twithStatics((schema) => ({\n\t\tascending: (id?: string) => {\n\t\t\tif (!id) return schema.make(\"ses_\" + uuidv7());\n\t\t\tif (!id.startsWith(\"ses\")) throw new Error(`ID ${id} does not start with ses`);\n\t\t\treturn schema.make(id);\n\t\t},\n\t\tcreate: () => schema.make(\"ses_\" + uuidv7()),\n\t})),\n);\nexport type SessionID = typeof SessionID.Type;\n\n/**\n * A conversation message id.\n *\n * Deliberately unprefixed. aikit mints assistant message ids itself, as bare\n * uuidv7, and `stream()` accepts no id -- so any naming rule of ours would have\n * to be imposed on messages aikit hands us, by rewriting a field of the value we\n * were given. Sharing aikit's format instead means an id means the same thing on\n * both sides of the boundary and never needs translating.\n *\n * The brand carries the meaning; uuidv7 keeps ids time-ordered, so they sort by\n * creation.\n */\nexport const MessageID = Schema.String.pipe(\n\tSchema.brand(\"Message.ID\"),\n\twithStatics((schema) => ({\n\t\tcreate: () => schema.make(uuidv7()),\n\t\t/**\n\t\t * Adopt an id minted elsewhere -- in practice aikit's, which arrives as a\n\t\t * plain string on every stream event and inside every assistant message.\n\t\t *\n\t\t * `make` does the same thing. This exists so the boundary where a foreign\n\t\t * id enters the domain is named and greppable, and so the pairing with\n\t\t * `create` says which side chose the id.\n\t\t */\n\t\tfrom: (id: string) => schema.make(id),\n\t})),\n);\nexport type MessageID = typeof MessageID.Type;\n"],"mappings":";;;;;;;;;;;;AAqBA,MAAa,YAAY,OAAO,OAAO,MAAM,OAAO,eAAe,KAAK,CAAC,CAAC,CAAC,KAC1E,OAAO,MAAM,YAAY,GACzB,aAAa,YAAY;CACxB,YAAY,OAAgB;EAC3B,IAAI,CAAC,IAAI,OAAO,OAAO,KAAK,SAAS,OAAO,CAAC;EAC7C,IAAI,CAAC,GAAG,WAAW,KAAK,GAAG,MAAM,IAAI,MAAM,MAAM,GAAG,yBAAyB;EAC7E,OAAO,OAAO,KAAK,EAAE;CACtB;CACA,cAAc,OAAO,KAAK,SAAS,OAAO,CAAC;AAC5C,EAAE,CACH;;;;;;;;;;;;;AAeA,MAAa,YAAY,OAAO,OAAO,KACtC,OAAO,MAAM,YAAY,GACzB,aAAa,YAAY;CACxB,cAAc,OAAO,KAAK,OAAO,CAAC;;;;;;;;;CASlC,OAAO,OAAe,OAAO,KAAK,EAAE;AACrC,EAAE,CACH"}
package/index.d.mts CHANGED
@@ -1,3 +1,4 @@
1
+ import { t as section_d_exports } from "./plugin/section.mjs";
1
2
  import { g as tool_d_exports } from "./tool-DuYBgiJf.mjs";
2
- import { t as plugin_d_exports } from "./plugin-B1M3SjEb.mjs";
3
- export { plugin_d_exports as Plugin, tool_d_exports as Tool };
3
+ import { t as plugin_d_exports } from "./plugin-CaG6IlD-.mjs";
4
+ export { plugin_d_exports as Plugin, section_d_exports as Section, tool_d_exports as Tool };
package/index.mjs CHANGED
@@ -1,3 +1,4 @@
1
- import { t as plugin_exports } from "./plugin-lorpq7Oi.mjs";
1
+ import { t as plugin_exports } from "./plugin-XaYYRsX-.mjs";
2
+ import { t as section_exports } from "./plugin/section.mjs";
2
3
  import { t as tool_exports } from "./tool.mjs";
3
- export { plugin_exports as Plugin, tool_exports as Tool };
4
+ export { plugin_exports as Plugin, section_exports as Section, tool_exports as Tool };
@@ -2,6 +2,12 @@ import { i as project_d_exports, n as Info$1 } from "./project-CLGsIFD-.mjs";
2
2
  import { a as space_d_exports, n as Info$2 } from "./space-CR-9UxdT.mjs";
3
3
  import { Context, Schema } from "effect";
4
4
  //#region src/location.d.ts
5
+ declare const Info_base: Schema.Class<Info, Schema.Struct<{
6
+ /** The absolute cwd tools run in; `space.location` is the root it lives under. */
7
+ readonly directory: Schema.brand<Schema.String, "AbsolutePath">;
8
+ readonly space: typeof Info$2;
9
+ readonly project: typeof Info$1;
10
+ }>, {}>;
5
11
  /**
6
12
  * Where work happens: a directory inside a space.
7
13
  *
@@ -12,7 +18,7 @@ import { Context, Schema } from "effect";
12
18
  * equal to or beneath that root. Sessions sharing a space share the project;
13
19
  * worktree relationships stay a Project concern beneath it.
14
20
  *
15
- * **Both halves come from the mount, so `Ref` is overrides and nothing else.**
21
+ * **Both halves come from the mount, and nothing overrides them.**
16
22
  * A Location is a directory *within* a mounted namespace — the mount has to be
17
23
  * resolved first, the way a volume is mounted before any path on it means
18
24
  * anything — and once it is, the namespace and the working directory are already
@@ -24,17 +30,6 @@ import { Context, Schema } from "effect";
24
30
  * which belong to the harness; a plugin receives a resolved `Info` on its context and asks for
25
31
  * {@link Service} when it needs the live one.
26
32
  */
27
- declare const Ref: Schema.Struct<{
28
- /** Defaults to the mount's cwd. Set it to work in a subdirectory of the mount. */
29
- readonly directory: Schema.optional<Schema.brand<Schema.String, "AbsolutePath">>;
30
- }>;
31
- type Ref = typeof Ref.Type;
32
- declare const Info_base: Schema.Class<Info, Schema.Struct<{
33
- /** The absolute cwd tools run in; `space.location` is the root it lives under. */
34
- readonly directory: Schema.brand<Schema.String, "AbsolutePath">;
35
- readonly space: typeof Info$2;
36
- readonly project: typeof Info$1;
37
- }>, {}>;
38
33
  declare class Info extends Info_base {}
39
34
  interface Interface extends Info {}
40
35
  declare const Service_base: Context.ServiceClass<Service, "@codeworksh/plugin/location/Service", Interface>;
@@ -57,5 +52,5 @@ declare const NotDirectoryError_base: Schema.Class<NotDirectoryError, Schema.Tag
57
52
  declare class NotDirectoryError extends NotDirectoryError_base {}
58
53
  type Error = DirectoryNotFoundError | NotDirectoryError;
59
54
  //#endregion
60
- export { NotDirectoryError as a, Interface as i, Error as n, Ref as o, Info as r, Service as s, DirectoryNotFoundError as t };
61
- //# sourceMappingURL=location-D4hAfuXF.d.mts.map
55
+ export { NotDirectoryError as a, Interface as i, Error as n, Service as o, Info as r, DirectoryNotFoundError as t };
56
+ //# sourceMappingURL=location-Q39els63.d.mts.map
package/location.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as NotDirectoryError, i as Interface, n as Error, o as Ref, r as Info, s as Service, t as DirectoryNotFoundError } from "./location-D4hAfuXF.mjs";
2
- export { DirectoryNotFoundError, Error, Info, Interface, NotDirectoryError, Ref, Service };
1
+ import { a as NotDirectoryError, i as Interface, n as Error, o as Service, r as Info, t as DirectoryNotFoundError } from "./location-Q39els63.mjs";
2
+ export { DirectoryNotFoundError, Error, Info, Interface, NotDirectoryError, Service };
package/location.mjs CHANGED
@@ -14,7 +14,7 @@ import { Context, Schema } from "effect";
14
14
  * equal to or beneath that root. Sessions sharing a space share the project;
15
15
  * worktree relationships stay a Project concern beneath it.
16
16
  *
17
- * **Both halves come from the mount, so `Ref` is overrides and nothing else.**
17
+ * **Both halves come from the mount, and nothing overrides them.**
18
18
  * A Location is a directory *within* a mounted namespace — the mount has to be
19
19
  * resolved first, the way a volume is mounted before any path on it means
20
20
  * anything — and once it is, the namespace and the working directory are already
@@ -26,9 +26,6 @@ import { Context, Schema } from "effect";
26
26
  * which belong to the harness; a plugin receives a resolved `Info` on its context and asks for
27
27
  * {@link Service} when it needs the live one.
28
28
  */
29
- const Ref = Schema.Struct({
30
- /** Defaults to the mount's cwd. Set it to work in a subdirectory of the mount. */
31
- directory: Schema.optional(AbsolutePath) }).annotate({ identifier: "Location.Ref" });
32
29
  var Info = class extends Schema.Class("Location.Info")({
33
30
  /** The absolute cwd tools run in; `space.location` is the root it lives under. */
34
31
  directory: AbsolutePath,
@@ -43,6 +40,6 @@ const Fields = {
43
40
  var DirectoryNotFoundError = class extends Schema.TaggedError()("Location.DirectoryNotFoundError", Fields) {};
44
41
  var NotDirectoryError = class extends Schema.TaggedError()("Location.NotDirectoryError", Fields) {};
45
42
  //#endregion
46
- export { DirectoryNotFoundError, Info, NotDirectoryError, Ref, Service };
43
+ export { DirectoryNotFoundError, Info, NotDirectoryError, Service };
47
44
 
48
45
  //# sourceMappingURL=location.mjs.map
package/location.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"location.mjs","names":["SpaceSchema.Info","ProjectSchema.Info","SandboxInstance.ID"],"sources":["../../src/location.ts"],"sourcesContent":["import { Context, Schema } from \"effect\";\nimport { ProjectSchema } from \"./project.ts\";\nimport { AbsolutePath } from \"./schema.ts\";\nimport { SandboxInstance } from \"./sandbox/instance.ts\";\nimport { SpaceSchema } from \"./space.ts\";\n\n/**\n * Where work happens: a directory inside a space.\n *\n * The pair (space, directory) is the key. A path alone does not name a place —\n * `/app/repo` on the host and `/app/repo` inside a remote sandbox are different\n * trees wearing the same spelling — so the space carries the env and the\n * root it lives under (`space.location`), and `directory` is the absolute cwd\n * equal to or beneath that root. Sessions sharing a space share the project;\n * worktree relationships stay a Project concern beneath it.\n *\n * **Both halves come from the mount, so `Ref` is overrides and nothing else.**\n * A Location is a directory *within* a mounted namespace — the mount has to be\n * resolved first, the way a volume is mounted before any path on it means\n * anything — and once it is, the namespace and the working directory are already\n * in scope. Re-declaring them would be two spellings of one value, free to drift;\n * a Location pointing somewhere its own shell is not becomes unrepresentable\n * rather than merely avoided by discipline.\n *\n * Only the shape and the service tag live here. Building one needs Project, Space, Repo and Git,\n * which belong to the harness; a plugin receives a resolved `Info` on its context and asks for\n * {@link Service} when it needs the live one.\n */\nexport const Ref = Schema.Struct({\n\t/** Defaults to the mount's cwd. Set it to work in a subdirectory of the mount. */\n\tdirectory: Schema.optional(AbsolutePath),\n}).annotate({ identifier: \"Location.Ref\" });\nexport type Ref = typeof Ref.Type;\n\nexport class Info extends Schema.Class<Info>(\"Location.Info\")({\n\t/** The absolute cwd tools run in; `space.location` is the root it lives under. */\n\tdirectory: AbsolutePath,\n\tspace: SpaceSchema.Info,\n\tproject: ProjectSchema.Info,\n}) {}\n\nexport interface Interface extends Info {}\n\nexport class Service extends Context.Service<Service, Interface>()(\"@codeworksh/plugin/location/Service\") {}\n\nconst Fields = {\n\tdirectory: AbsolutePath,\n\tsandboxInstanceId: SandboxInstance.ID,\n};\n\nexport class DirectoryNotFoundError extends Schema.TaggedError<DirectoryNotFoundError>()(\n\t\"Location.DirectoryNotFoundError\",\n\tFields,\n) {}\n\nexport class NotDirectoryError extends Schema.TaggedError<NotDirectoryError>()(\"Location.NotDirectoryError\", Fields) {}\n\nexport type Error = DirectoryNotFoundError | NotDirectoryError;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,MAAa,MAAM,OAAO,OAAO;;AAEhC,WAAW,OAAO,SAAS,YAAY,EACxC,CAAC,CAAC,CAAC,SAAS,EAAE,YAAY,eAAe,CAAC;AAG1C,IAAa,OAAb,cAA0B,OAAO,MAAY,eAAe,CAAC,CAAC;;CAE7D,WAAW;CACX,OAAOA;CACP,SAASC;AACV,CAAC,CAAC,CAAC,CAAC;AAIJ,IAAa,UAAb,cAA6B,QAAQ,QAA4B,CAAC,CAAC,qCAAqC,CAAC,CAAC,CAAC;AAE3G,MAAM,SAAS;CACd,WAAW;CACX,mBAAmBC;AACpB;AAEA,IAAa,yBAAb,cAA4C,OAAO,YAAoC,CAAC,CACvF,mCACA,MACD,CAAC,CAAC,CAAC;AAEH,IAAa,oBAAb,cAAuC,OAAO,YAA+B,CAAC,CAAC,8BAA8B,MAAM,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"location.mjs","names":["SpaceSchema.Info","ProjectSchema.Info","SandboxInstance.ID"],"sources":["../../src/location.ts"],"sourcesContent":["import { Context, Schema } from \"effect\";\nimport { ProjectSchema } from \"./project.ts\";\nimport { AbsolutePath } from \"./schema.ts\";\nimport { SandboxInstance } from \"./sandbox/instance.ts\";\nimport { SpaceSchema } from \"./space.ts\";\n\n/**\n * Where work happens: a directory inside a space.\n *\n * The pair (space, directory) is the key. A path alone does not name a place —\n * `/app/repo` on the host and `/app/repo` inside a remote sandbox are different\n * trees wearing the same spelling — so the space carries the env and the\n * root it lives under (`space.location`), and `directory` is the absolute cwd\n * equal to or beneath that root. Sessions sharing a space share the project;\n * worktree relationships stay a Project concern beneath it.\n *\n * **Both halves come from the mount, and nothing overrides them.**\n * A Location is a directory *within* a mounted namespace — the mount has to be\n * resolved first, the way a volume is mounted before any path on it means\n * anything — and once it is, the namespace and the working directory are already\n * in scope. Re-declaring them would be two spellings of one value, free to drift;\n * a Location pointing somewhere its own shell is not becomes unrepresentable\n * rather than merely avoided by discipline.\n *\n * Only the shape and the service tag live here. Building one needs Project, Space, Repo and Git,\n * which belong to the harness; a plugin receives a resolved `Info` on its context and asks for\n * {@link Service} when it needs the live one.\n */\nexport class Info extends Schema.Class<Info>(\"Location.Info\")({\n\t/** The absolute cwd tools run in; `space.location` is the root it lives under. */\n\tdirectory: AbsolutePath,\n\tspace: SpaceSchema.Info,\n\tproject: ProjectSchema.Info,\n}) {}\n\nexport interface Interface extends Info {}\n\nexport class Service extends Context.Service<Service, Interface>()(\"@codeworksh/plugin/location/Service\") {}\n\nconst Fields = {\n\tdirectory: AbsolutePath,\n\tsandboxInstanceId: SandboxInstance.ID,\n};\n\nexport class DirectoryNotFoundError extends Schema.TaggedError<DirectoryNotFoundError>()(\n\t\"Location.DirectoryNotFoundError\",\n\tFields,\n) {}\n\nexport class NotDirectoryError extends Schema.TaggedError<NotDirectoryError>()(\"Location.NotDirectoryError\", Fields) {}\n\nexport type Error = DirectoryNotFoundError | NotDirectoryError;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,IAAa,OAAb,cAA0B,OAAO,MAAY,eAAe,CAAC,CAAC;;CAE7D,WAAW;CACX,OAAOA;CACP,SAASC;AACV,CAAC,CAAC,CAAC,CAAC;AAIJ,IAAa,UAAb,cAA6B,QAAQ,QAA4B,CAAC,CAAC,qCAAqC,CAAC,CAAC,CAAC;AAE3G,MAAM,SAAS;CACd,WAAW;CACX,mBAAmBC;AACpB;AAEA,IAAa,yBAAb,cAA4C,OAAO,YAAoC,CAAC,CACvF,mCACA,MACD,CAAC,CAAC,CAAC;AAEH,IAAa,oBAAb,cAAuC,OAAO,YAA+B,CAAC,CAAC,8BAA8B,MAAM,CAAC,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codeworksh/plugin",
3
- "version": "0.0.1-dev.20260925150557",
3
+ "version": "0.1.0-canary.16.1.gfa1c6c4c",
4
4
  "description": "SDK for building CodeWork plugins — the plugin, tool, and sandbox contracts shared with @codeworksh/harness.",
5
5
  "keywords": [
6
6
  "agent",
@@ -45,6 +45,11 @@
45
45
  "import": "./plugin/prompt.mjs",
46
46
  "default": "./plugin/prompt.mjs"
47
47
  },
48
+ "./plugin/section": {
49
+ "types": "./plugin/section.d.mts",
50
+ "import": "./plugin/section.mjs",
51
+ "default": "./plugin/section.mjs"
52
+ },
48
53
  "./sandbox": {
49
54
  "types": "./sandbox.d.mts",
50
55
  "import": "./sandbox.mjs",
@@ -163,7 +168,7 @@
163
168
  "uuidv7": "^1.2.1"
164
169
  },
165
170
  "peerDependencies": {
166
- "@codeworksh/aikit": "^0.9.2",
167
- "effect": "4.0.0-rc.115"
171
+ "@codeworksh/aikit": "0.10.0-canary.16.1.gfa1c6c4c",
172
+ "effect": "4.0.1"
168
173
  }
169
174
  }
@@ -1,2 +1,2 @@
1
- import { t as PromptRegistry } from "../prompt-BcpagjGh.mjs";
1
+ import { t as PromptRegistry } from "../prompt-DWaA5ZXj.mjs";
2
2
  export { PromptRegistry };
@@ -1 +1 @@
1
- {"version":3,"file":"prompt.mjs","names":[],"sources":["../../../src/plugin/prompt.ts"],"sourcesContent":["export interface PromptRegistry {\n\treadonly set: (systemPrompt: string) => void;\n\treadonly get: () => string | undefined;\n}\n"],"mappings":""}
1
+ {"version":3,"file":"prompt.mjs","names":[],"sources":["../../../src/plugin/prompt.ts"],"sourcesContent":["import type { Section } from \"./section.ts\";\n\nexport interface PromptRegistry {\n\t/** The untagged head of the system prompt; the last `set` wins. */\n\treadonly foundation: {\n\t\treadonly set: (text: string) => void;\n\t\treadonly get: () => string | undefined;\n\t};\n\treadonly sections: {\n\t\treadonly append: (section: Section, entry: string) => void;\n\t\treadonly set: (section: Section, entries: ReadonlyArray<string>) => void;\n\t\t/** Writing a removed section again opens a new one, last in order. */\n\t\treadonly remove: (section: Section) => void;\n\t\treadonly get: (section: Section) => ReadonlyArray<string> | undefined;\n\t};\n}\n"],"mappings":""}
@@ -0,0 +1,27 @@
1
+ declare namespace section_d_exports {
2
+ export { Addendum, Format, ProjectContext, Rules, Section, Skills, builtins, define, invalid, isFormat, reserved };
3
+ }
4
+ /** `text`: entries verbatim, blank-line separated. `list`: deduplicated `- ` bullets. */
5
+ export type Format = "text" | "list";
6
+ export interface Section<Name extends string = string> {
7
+ readonly name: Name;
8
+ readonly format: Format;
9
+ }
10
+ export declare const Rules: Section<"rules">;
11
+ export declare const Addendum: Section<"addendum">;
12
+ export declare const ProjectContext: Section<"project_context">;
13
+ export declare const Skills: Section<"skills">;
14
+ /** Rendered in this order, before custom sections. */
15
+ export declare const builtins: ReadonlyArray<Section>;
16
+ /** Rendered by the harness, never by a plugin. */
17
+ export declare const reserved: ReadonlySet<string>;
18
+ /** Runtime check: a JavaScript plugin can pass anything. */
19
+ export declare const isFormat: (format: unknown) => format is Format;
20
+ export declare const invalid: (name: unknown) => string | undefined;
21
+ /** A custom section. Throws on a name that is malformed, reserved, or built in. */
22
+ export declare const define: <const Name extends string>(name: Name, options?: {
23
+ readonly format?: Format;
24
+ }) => Section<Name>;
25
+ //#endregion
26
+ export { section_d_exports as t };
27
+ //# sourceMappingURL=section.d.mts.map
@@ -0,0 +1,65 @@
1
+ import { t as __exportAll } from "../rolldown-runtime-D7D4PA-g.mjs";
2
+ //#region src/plugin/section.ts
3
+ var section_exports = /* @__PURE__ */ __exportAll({
4
+ Addendum: () => Addendum,
5
+ ProjectContext: () => ProjectContext,
6
+ Rules: () => Rules,
7
+ Skills: () => Skills,
8
+ builtins: () => builtins,
9
+ define: () => define,
10
+ invalid: () => invalid,
11
+ isFormat: () => isFormat,
12
+ reserved: () => reserved
13
+ });
14
+ const Rules = Object.freeze({
15
+ name: "rules",
16
+ format: "list"
17
+ });
18
+ const Addendum = Object.freeze({
19
+ name: "addendum",
20
+ format: "text"
21
+ });
22
+ const ProjectContext = Object.freeze({
23
+ name: "project_context",
24
+ format: "text"
25
+ });
26
+ const Skills = Object.freeze({
27
+ name: "skills",
28
+ format: "text"
29
+ });
30
+ /** Rendered in this order, before custom sections. */
31
+ const builtins = Object.freeze([
32
+ Rules,
33
+ Addendum,
34
+ ProjectContext,
35
+ Skills
36
+ ]);
37
+ /** Rendered by the harness, never by a plugin. */
38
+ const reserved = /* @__PURE__ */ new Set([
39
+ "tools",
40
+ "cwd",
41
+ "foundation"
42
+ ]);
43
+ const pattern = /^[a-z][a-z0-9_-]*$/;
44
+ const formats = /* @__PURE__ */ new Set(["text", "list"]);
45
+ /** Runtime check: a JavaScript plugin can pass anything. */
46
+ const isFormat = (format) => formats.has(format);
47
+ const invalid = (name) => {
48
+ if (typeof name !== "string" || !pattern.test(name)) return `prompt section name must be lowercase letters, digits, "_" or "-": ${JSON.stringify(name)}`;
49
+ if (reserved.has(name)) return `prompt section name is reserved: ${name}`;
50
+ };
51
+ /** A custom section. Throws on a name that is malformed, reserved, or built in. */
52
+ const define = (name, options) => {
53
+ const reason = invalid(name) ?? (builtins.some((section) => section.name === name) ? `prompt section name is built in: ${name}` : void 0);
54
+ if (reason !== void 0) throw new Error(reason);
55
+ const format = options?.format ?? "text";
56
+ if (!isFormat(format)) throw new Error(`prompt section format must be "text" or "list": ${JSON.stringify(format)}`);
57
+ return Object.freeze({
58
+ name,
59
+ format
60
+ });
61
+ };
62
+ //#endregion
63
+ export { Addendum, ProjectContext, Rules, Skills, builtins, define, invalid, isFormat, reserved, section_exports as t };
64
+
65
+ //# sourceMappingURL=section.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"section.mjs","names":[],"sources":["../../../src/plugin/section.ts"],"sourcesContent":["// Sections are passed by value, never by name string, so a typo fails to compile instead of\n// quietly opening a new section.\n\n/** `text`: entries verbatim, blank-line separated. `list`: deduplicated `- ` bullets. */\nexport type Format = \"text\" | \"list\";\n\nexport interface Section<Name extends string = string> {\n\treadonly name: Name;\n\treadonly format: Format;\n}\n\nexport const Rules: Section<\"rules\"> = Object.freeze({ name: \"rules\", format: \"list\" });\nexport const Addendum: Section<\"addendum\"> = Object.freeze({ name: \"addendum\", format: \"text\" });\nexport const ProjectContext: Section<\"project_context\"> = Object.freeze({ name: \"project_context\", format: \"text\" });\nexport const Skills: Section<\"skills\"> = Object.freeze({ name: \"skills\", format: \"text\" });\n\n/** Rendered in this order, before custom sections. */\nexport const builtins: ReadonlyArray<Section> = Object.freeze([Rules, Addendum, ProjectContext, Skills]);\n\n/** Rendered by the harness, never by a plugin. */\nexport const reserved: ReadonlySet<string> = new Set([\"tools\", \"cwd\", \"foundation\"]);\n\nconst pattern = /^[a-z][a-z0-9_-]*$/;\n\nconst formats: ReadonlySet<unknown> = new Set<Format>([\"text\", \"list\"]);\n\n/** Runtime check: a JavaScript plugin can pass anything. */\nexport const isFormat = (format: unknown): format is Format => formats.has(format);\n\nexport const invalid = (name: unknown): string | undefined => {\n\tif (typeof name !== \"string\" || !pattern.test(name))\n\t\treturn `prompt section name must be lowercase letters, digits, \"_\" or \"-\": ${JSON.stringify(name)}`;\n\tif (reserved.has(name)) return `prompt section name is reserved: ${name}`;\n\treturn undefined;\n};\n\n/** A custom section. Throws on a name that is malformed, reserved, or built in. */\nexport const define = <const Name extends string>(\n\tname: Name,\n\toptions?: { readonly format?: Format },\n): Section<Name> => {\n\tconst reason =\n\t\tinvalid(name) ??\n\t\t(builtins.some((section) => section.name === name) ? `prompt section name is built in: ${name}` : undefined);\n\tif (reason !== undefined) throw new Error(reason);\n\tconst format = options?.format ?? \"text\";\n\tif (!isFormat(format)) throw new Error(`prompt section format must be \"text\" or \"list\": ${JSON.stringify(format)}`);\n\treturn Object.freeze({ name, format });\n};\n"],"mappings":";;;;;;;;;;;;;AAWA,MAAa,QAA0B,OAAO,OAAO;CAAE,MAAM;CAAS,QAAQ;AAAO,CAAC;AACtF,MAAa,WAAgC,OAAO,OAAO;CAAE,MAAM;CAAY,QAAQ;AAAO,CAAC;AAC/F,MAAa,iBAA6C,OAAO,OAAO;CAAE,MAAM;CAAmB,QAAQ;AAAO,CAAC;AACnH,MAAa,SAA4B,OAAO,OAAO;CAAE,MAAM;CAAU,QAAQ;AAAO,CAAC;;AAGzF,MAAa,WAAmC,OAAO,OAAO;CAAC;CAAO;CAAU;CAAgB;AAAM,CAAC;;AAGvG,MAAa,2BAAgC,IAAI,IAAI;CAAC;CAAS;CAAO;AAAY,CAAC;AAEnF,MAAM,UAAU;AAEhB,MAAM,0BAAgC,IAAI,IAAY,CAAC,QAAQ,MAAM,CAAC;;AAGtE,MAAa,YAAY,WAAsC,QAAQ,IAAI,MAAM;AAEjF,MAAa,WAAW,SAAsC;CAC7D,IAAI,OAAO,SAAS,YAAY,CAAC,QAAQ,KAAK,IAAI,GACjD,OAAO,sEAAsE,KAAK,UAAU,IAAI;CACjG,IAAI,SAAS,IAAI,IAAI,GAAG,OAAO,oCAAoC;AAEpE;;AAGA,MAAa,UACZ,MACA,YACmB;CACnB,MAAM,SACL,QAAQ,IAAI,MACX,SAAS,MAAM,YAAY,QAAQ,SAAS,IAAI,IAAI,oCAAoC,SAAS,KAAA;CACnG,IAAI,WAAW,KAAA,GAAW,MAAM,IAAI,MAAM,MAAM;CAChD,MAAM,SAAS,SAAS,UAAU;CAClC,IAAI,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI,MAAM,mDAAmD,KAAK,UAAU,MAAM,GAAG;CAClH,OAAO,OAAO,OAAO;EAAE;EAAM;CAAO,CAAC;AACtC"}
@@ -1,9 +1,10 @@
1
- import { i as Definition, o as Payload, r as Data, s as PublishOptions } from "./event-BnLveFBB.mjs";
1
+ import { i as Definition, o as Payload, r as Data, s as PublishOptions } from "./event-9PbbjnHJ.mjs";
2
2
  import { n as SessionID } from "./ids-CHjmAdTc.mjs";
3
- import { r as Info, s as Service } from "./location-D4hAfuXF.mjs";
3
+ import { o as Service, r as Info } from "./location-Q39els63.mjs";
4
4
  import { a as Provides, r as Identity, u as io_d_exports } from "./io-BYs7hbiY.mjs";
5
- import { r as Info$1 } from "./settings-bbJi7FiQ.mjs";
6
- import { n as prompt_d_exports, t as PromptRegistry } from "./prompt-BcpagjGh.mjs";
5
+ import { i as Info$1 } from "./settings-B6-grSTA.mjs";
6
+ import { t as section_d_exports } from "./plugin/section.mjs";
7
+ import { n as prompt_d_exports, t as PromptRegistry } from "./prompt-DWaA5ZXj.mjs";
7
8
  import { d as ToolRegistry, p as tool_d_exports } from "./tool-BoVqkYvL.mjs";
8
9
  import { Model } from "@codeworksh/aikit";
9
10
  import { Effect } from "effect";
@@ -133,8 +134,8 @@ interface Plugin {
133
134
  }
134
135
  declare const define: (plugin: Plugin) => Plugin;
135
136
  declare namespace plugin_d_exports {
136
- export { Config, Events, Mount, Plugin, PluginKind, PluginOptions, PluginPatch, PluginRef, PluginRegistry, PluginSpec, prompt_d_exports as Prompt, PromptResolver, SharedPluginContext, tool_d_exports as Tool, define, domains, rank };
137
+ export { Config, Events, Mount, Plugin, PluginKind, PluginOptions, PluginPatch, PluginRef, PluginRegistry, PluginSpec, prompt_d_exports as Prompt, PromptResolver, section_d_exports as Section, SharedPluginContext, tool_d_exports as Tool, define, domains, rank };
137
138
  }
138
139
  //#endregion
139
140
  export { define as a, PluginOptions as c, PluginSpec as d, Config as f, PluginRegistry as g, SharedPluginContext as h, PluginKind as i, PluginPatch as l, PromptResolver as m, Mount as n, domains as o, Events as p, Plugin as r, rank as s, plugin_d_exports as t, PluginRef as u };
140
- //# sourceMappingURL=plugin-B1M3SjEb.d.mts.map
141
+ //# sourceMappingURL=plugin-CaG6IlD-.d.mts.map
@@ -1,5 +1,6 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
2
  import { t as prompt_exports } from "./plugin/prompt.mjs";
3
+ import { t as section_exports } from "./plugin/section.mjs";
3
4
  import { t as tool_exports } from "./plugin/tool.mjs";
4
5
  //#region src/plugin/plugin.ts
5
6
  /**
@@ -30,6 +31,7 @@ const define = (plugin) => plugin;
30
31
  //#region src/plugin.ts
31
32
  var plugin_exports = /* @__PURE__ */ __exportAll({
32
33
  Prompt: () => prompt_exports,
34
+ Section: () => section_exports,
33
35
  Tool: () => tool_exports,
34
36
  define: () => define,
35
37
  domains: () => domains,
@@ -38,4 +40,4 @@ var plugin_exports = /* @__PURE__ */ __exportAll({
38
40
  //#endregion
39
41
  export { rank as i, define as n, domains as r, plugin_exports as t };
40
42
 
41
- //# sourceMappingURL=plugin-lorpq7Oi.mjs.map
43
+ //# sourceMappingURL=plugin-XaYYRsX-.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin-lorpq7Oi.mjs","names":[],"sources":["../../src/plugin/plugin.ts","../../src/plugin.ts"],"sourcesContent":["import type { Effect } from \"effect\";\nimport type { Definition } from \"../event.ts\";\nimport type { Service as LocationService } from \"../location.ts\";\nimport type { SandboxIO } from \"../sandbox/io.ts\";\nimport type { PluginOptions } from \"./ref.ts\";\nimport type { SharedPluginContext } from \"./context.ts\";\n\n/**\n * The domains a plugin can extend, and the order the harness runs them in.\n *\n * Order is declared, not positional. A plugin's place used to come from where its entry sat in\n * the `plugins` array, which is unknowable when the entry is written: a user's settings file and\n * a project's are edited by different people at different times, and neither can see the other's\n * order. Since a prompt plugin indexes the tools registered before it, that made a tool added\n * from settings invisible in the system prompt, with no way to fix it from a settings file.\n *\n * A plugin instead says which domain it extends, and the harness runs the domains in this order.\n * Entries within one domain keep the order they were written in, because that is where\n * composition actually happens -- a plugin patching another's tool, or appending to the prompt a\n * previous one rendered, is written next to it and deliberately after it.\n *\n * Kept as data so a later release can add a domain, or make the order configurable, without\n * touching the loader: `{ tool: 1, skill: 2, prompt: 3 }` needs no code change here.\n */\nexport const domains = { tool: 1, prompt: 2 } as const;\n\nexport type PluginKind = keyof typeof domains;\n\n/** Sort key for a plugin: its domain first, then where it was written. */\nexport const rank = (kind: PluginKind) => domains[kind];\n\nexport type Mount = SandboxIO.Provides | LocationService;\nexport interface Plugin {\n\treadonly id: string;\n\t/**\n\t * The domain this plugin extends, which decides when it runs: every `tool` plugin is set up\n\t * before any `prompt` plugin, whichever settings layer each came from, so a prompt plugin\n\t * always sees the complete tool set. Plugins within one domain run in the order they were\n\t * written.\n\t */\n\treadonly kind: PluginKind;\n\t/**\n\t * Event definitions this plugin publishes. Declared rather than registered at\n\t * runtime so they are known before the event system builds, and so a bad type\n\t * fails the boot instead of the first publish. Types must be namespaced\n\t * `plugin.<id>.*`.\n\t */\n\treadonly events?: ReadonlyArray<Definition>;\n\t/**\n\t * `options` is this plugin's own configuration block, `{}` when its entry carried none.\n\t * Unvalidated: the harness never looks inside it, so a plugin checks whatever shape it\n\t * documents. It is a second argument rather than a context field so `ctx` stays one object\n\t * shared by every plugin in the exchange.\n\t */\n\treadonly setup: (\n\t\tctx: SharedPluginContext,\n\t\toptions: PluginOptions,\n\t) => void | Promise<void> | Effect.Effect<void, unknown, Mount>;\n}\n\nexport const define = (plugin: Plugin): Plugin => plugin;\n","/**\n * The plugin authoring surface.\n *\n * Everything a third-party plugin needs to describe itself and to write into the harness during\n * `setup`, and nothing about how the harness finds, installs or runs it. Loading, the store and\n * the `.npmrc` anchoring stay in `@codeworksh/harness`, which imports this same module — so a\n * plugin and its host agree on one set of types rather than two that happen to match.\n */\nexport type { Config, Events, PromptResolver, SharedPluginContext } from \"./plugin/context.ts\";\nexport { define, domains, type Mount, type Plugin, type PluginKind, rank } from \"./plugin/plugin.ts\";\nexport * as Prompt from \"./plugin/prompt.ts\";\nexport type { PluginOptions, PluginPatch, PluginRef, PluginSpec } from \"./plugin/ref.ts\";\nexport type { PluginRegistry } from \"./plugin/registry.ts\";\nexport * as Tool from \"./plugin/tool.ts\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAwBA,MAAa,UAAU;CAAE,MAAM;CAAG,QAAQ;AAAE;;AAK5C,MAAa,QAAQ,SAAqB,QAAQ;AA+BlD,MAAa,UAAU,WAA2B"}
1
+ {"version":3,"file":"plugin-XaYYRsX-.mjs","names":[],"sources":["../../src/plugin/plugin.ts","../../src/plugin.ts"],"sourcesContent":["import type { Effect } from \"effect\";\nimport type { Definition } from \"../event.ts\";\nimport type { Service as LocationService } from \"../location.ts\";\nimport type { SandboxIO } from \"../sandbox/io.ts\";\nimport type { PluginOptions } from \"./ref.ts\";\nimport type { SharedPluginContext } from \"./context.ts\";\n\n/**\n * The domains a plugin can extend, and the order the harness runs them in.\n *\n * Order is declared, not positional. A plugin's place used to come from where its entry sat in\n * the `plugins` array, which is unknowable when the entry is written: a user's settings file and\n * a project's are edited by different people at different times, and neither can see the other's\n * order. Since a prompt plugin indexes the tools registered before it, that made a tool added\n * from settings invisible in the system prompt, with no way to fix it from a settings file.\n *\n * A plugin instead says which domain it extends, and the harness runs the domains in this order.\n * Entries within one domain keep the order they were written in, because that is where\n * composition actually happens -- a plugin patching another's tool, or appending to the prompt a\n * previous one rendered, is written next to it and deliberately after it.\n *\n * Kept as data so a later release can add a domain, or make the order configurable, without\n * touching the loader: `{ tool: 1, skill: 2, prompt: 3 }` needs no code change here.\n */\nexport const domains = { tool: 1, prompt: 2 } as const;\n\nexport type PluginKind = keyof typeof domains;\n\n/** Sort key for a plugin: its domain first, then where it was written. */\nexport const rank = (kind: PluginKind) => domains[kind];\n\nexport type Mount = SandboxIO.Provides | LocationService;\nexport interface Plugin {\n\treadonly id: string;\n\t/**\n\t * The domain this plugin extends, which decides when it runs: every `tool` plugin is set up\n\t * before any `prompt` plugin, whichever settings layer each came from, so a prompt plugin\n\t * always sees the complete tool set. Plugins within one domain run in the order they were\n\t * written.\n\t */\n\treadonly kind: PluginKind;\n\t/**\n\t * Event definitions this plugin publishes. Declared rather than registered at\n\t * runtime so they are known before the event system builds, and so a bad type\n\t * fails the boot instead of the first publish. Types must be namespaced\n\t * `plugin.<id>.*`.\n\t */\n\treadonly events?: ReadonlyArray<Definition>;\n\t/**\n\t * `options` is this plugin's own configuration block, `{}` when its entry carried none.\n\t * Unvalidated: the harness never looks inside it, so a plugin checks whatever shape it\n\t * documents. It is a second argument rather than a context field so `ctx` stays one object\n\t * shared by every plugin in the exchange.\n\t */\n\treadonly setup: (\n\t\tctx: SharedPluginContext,\n\t\toptions: PluginOptions,\n\t) => void | Promise<void> | Effect.Effect<void, unknown, Mount>;\n}\n\nexport const define = (plugin: Plugin): Plugin => plugin;\n","/**\n * The plugin authoring surface.\n *\n * Everything a third-party plugin needs to describe itself and to write into the harness during\n * `setup`, and nothing about how the harness finds, installs or runs it. Loading, the store and\n * the `.npmrc` anchoring stay in `@codeworksh/harness`, which imports this same module — so a\n * plugin and its host agree on one set of types rather than two that happen to match.\n */\nexport type { Config, Events, PromptResolver, SharedPluginContext } from \"./plugin/context.ts\";\nexport { define, domains, type Mount, type Plugin, type PluginKind, rank } from \"./plugin/plugin.ts\";\nexport * as Prompt from \"./plugin/prompt.ts\";\nexport * as Section from \"./plugin/section.ts\";\nexport type { PluginOptions, PluginPatch, PluginRef, PluginSpec } from \"./plugin/ref.ts\";\nexport type { PluginRegistry } from \"./plugin/registry.ts\";\nexport * as Tool from \"./plugin/tool.ts\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAwBA,MAAa,UAAU;CAAE,MAAM;CAAG,QAAQ;AAAE;;AAK5C,MAAa,QAAQ,SAAqB,QAAQ;AA+BlD,MAAa,UAAU,WAA2B"}
package/plugin.d.mts CHANGED
@@ -1,4 +1,5 @@
1
- import { n as prompt_d_exports } from "./prompt-BcpagjGh.mjs";
1
+ import { t as section_d_exports } from "./plugin/section.mjs";
2
+ import { n as prompt_d_exports } from "./prompt-DWaA5ZXj.mjs";
2
3
  import { p as tool_d_exports } from "./tool-BoVqkYvL.mjs";
3
- import { a as define, c as PluginOptions, d as PluginSpec, f as Config, g as PluginRegistry, h as SharedPluginContext, i as PluginKind, l as PluginPatch, m as PromptResolver, n as Mount, o as domains, p as Events, r as Plugin, s as rank, u as PluginRef } from "./plugin-B1M3SjEb.mjs";
4
- export { type Config, type Events, type Mount, type Plugin, type PluginKind, type PluginOptions, type PluginPatch, type PluginRef, type PluginRegistry, type PluginSpec, prompt_d_exports as Prompt, type PromptResolver, type SharedPluginContext, tool_d_exports as Tool, define, domains, rank };
4
+ import { a as define, c as PluginOptions, d as PluginSpec, f as Config, g as PluginRegistry, h as SharedPluginContext, i as PluginKind, l as PluginPatch, m as PromptResolver, n as Mount, o as domains, p as Events, r as Plugin, s as rank, u as PluginRef } from "./plugin-CaG6IlD-.mjs";
5
+ export { type Config, type Events, type Mount, type Plugin, type PluginKind, type PluginOptions, type PluginPatch, type PluginRef, type PluginRegistry, type PluginSpec, prompt_d_exports as Prompt, type PromptResolver, section_d_exports as Section, type SharedPluginContext, tool_d_exports as Tool, define, domains, rank };