@digi4care/omo-slim-decision-layer 0.2.3 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -27,6 +27,16 @@ Built as a companion plugin for
27
27
  - **Traceability** — typed links (`refines`, `depends_on`, `constrains`,
28
28
  `relates_to`) between records, with queries for orphans and reverse lookup.
29
29
 
30
+ ## Compatibility
31
+
32
+ One package, two registration paths, sharing the same register and tool logic:
33
+
34
+ - **v1** (`@opencode-ai/plugin` 1.x): the default export provides a v1 `server`
35
+ that registers the nine tools and the `command.execute.before` hook.
36
+ - **v2** (`@opencode/plugin` 2.x): the same default export also provides a v2
37
+ `setup` that registers the tools via `ctx.tool.transform` and injects the
38
+ prompt via `ctx.session.hook('prompt')`.
39
+
30
40
  ## Agent tools
31
41
 
32
42
  | Tool | Purpose |
package/dist/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import type { Plugin } from '@opencode-ai/plugin';
2
- declare const _default: {
2
+ declare const pluginModule: {
3
3
  id: string;
4
4
  server: Plugin;
5
+ setup: (ctx: import("./v2/setup").V2Context) => Promise<void>;
5
6
  };
6
- export default _default;
7
+ export default pluginModule;
package/dist/index.js CHANGED
@@ -3569,7 +3569,16 @@ import { z as z4 } from "zod";
3569
3569
  import { z } from "zod";
3570
3570
  var RecordTypes = ["REQ", "CONSTRAINT", "ASSUMPTION", "DEC"];
3571
3571
  var RecordStatuses = ["proposed", "accepted", "rejected", "superseded"];
3572
- var LinkRelations = ["refines", "depends_on", "constrains", "relates_to"];
3572
+ var LinkRelations = [
3573
+ "refines",
3574
+ "depends_on",
3575
+ "constrains",
3576
+ "relates_to",
3577
+ "decides",
3578
+ "implements",
3579
+ "satisfies",
3580
+ "external"
3581
+ ];
3573
3582
  var TypeOrder = {
3574
3583
  REQ: 0,
3575
3584
  CONSTRAINT: 1,
@@ -3597,8 +3606,19 @@ var RecordId = z.string().superRefine((val, ctx) => {
3597
3606
  });
3598
3607
  var LinkSchema = z.object({
3599
3608
  type: z.enum(LinkRelations),
3600
- target: RecordId,
3609
+ target: z.string().min(1, "Link target is required"),
3601
3610
  rationale: z.string().min(1, "Link rationale is required")
3611
+ }).superRefine((link, ctx) => {
3612
+ if (link.type === "external")
3613
+ return;
3614
+ const parsed = RecordId.safeParse(link.target);
3615
+ if (!parsed.success) {
3616
+ ctx.addIssue({
3617
+ code: "custom",
3618
+ message: parsed.error.issues.map((issue) => issue.message).join("; "),
3619
+ path: ["target"]
3620
+ });
3621
+ }
3602
3622
  });
3603
3623
  var BaseRecordFields = {
3604
3624
  schema_version: z.literal("1.0"),
@@ -3608,7 +3628,9 @@ var BaseRecordFields = {
3608
3628
  change_authority: z.string().min(1, "Change authority is required"),
3609
3629
  supersedes: z.array(RecordId).default([]),
3610
3630
  status_reason: z.string().optional(),
3611
- links: z.array(LinkSchema).default([])
3631
+ links: z.array(LinkSchema).default([]),
3632
+ context: z.string().optional(),
3633
+ meta: z.record(z.string(), z.unknown()).optional()
3612
3634
  };
3613
3635
  function createRecordSchema(type) {
3614
3636
  return z.object({
@@ -3622,13 +3644,13 @@ function createRecordSchema(type) {
3622
3644
  });
3623
3645
  }
3624
3646
  })
3625
- });
3647
+ }).strict();
3626
3648
  }
3627
3649
  var ReqRecordSchema = createRecordSchema("REQ");
3628
3650
  var ConstraintRecordSchema = createRecordSchema("CONSTRAINT");
3629
3651
  var AssumptionRecordSchema = createRecordSchema("ASSUMPTION").extend({
3630
3652
  needed_to_close: z.string().min(1, "needed_to_close is required")
3631
- });
3653
+ }).strict();
3632
3654
  var DecRecordSchema = createRecordSchema("DEC").extend({
3633
3655
  decision: z.string().min(1, "Decision is required"),
3634
3656
  alternatives_rejected: z.array(z.object({
@@ -3636,7 +3658,7 @@ var DecRecordSchema = createRecordSchema("DEC").extend({
3636
3658
  rejected_because: z.string().min(1, "Rejection reason is required")
3637
3659
  })).default([]),
3638
3660
  consequences: z.string().min(1, "Consequences are required")
3639
- });
3661
+ }).strict();
3640
3662
  var RecordSchema = z.discriminatedUnion("type", [
3641
3663
  ReqRecordSchema,
3642
3664
  ConstraintRecordSchema,
@@ -3648,16 +3670,18 @@ var BaseAddInputFields = {
3648
3670
  owner: z.string().optional(),
3649
3671
  change_authority: z.string().optional(),
3650
3672
  supersedes: z.array(RecordId).optional(),
3651
- links: z.array(LinkSchema).optional()
3673
+ links: z.array(LinkSchema).optional(),
3674
+ context: z.string().optional(),
3675
+ meta: z.record(z.string(), z.unknown()).optional()
3652
3676
  };
3653
3677
  var AddRecordInputSchema = z.discriminatedUnion("type", [
3654
- z.object({ ...BaseAddInputFields, type: z.literal("REQ") }),
3655
- z.object({ ...BaseAddInputFields, type: z.literal("CONSTRAINT") }),
3678
+ z.object({ ...BaseAddInputFields, type: z.literal("REQ") }).strict(),
3679
+ z.object({ ...BaseAddInputFields, type: z.literal("CONSTRAINT") }).strict(),
3656
3680
  z.object({
3657
3681
  ...BaseAddInputFields,
3658
3682
  type: z.literal("ASSUMPTION"),
3659
3683
  needed_to_close: z.string().min(1, "needed_to_close is required")
3660
- }),
3684
+ }).strict(),
3661
3685
  z.object({
3662
3686
  ...BaseAddInputFields,
3663
3687
  type: z.literal("DEC"),
@@ -3667,7 +3691,7 @@ var AddRecordInputSchema = z.discriminatedUnion("type", [
3667
3691
  rejected_because: z.string().min(1, "Rejection reason is required")
3668
3692
  })).optional(),
3669
3693
  consequences: z.string().min(1, "Consequences are required")
3670
- })
3694
+ }).strict()
3671
3695
  ]);
3672
3696
  function sortRecords(records) {
3673
3697
  return [...records].sort((a, b) => {
@@ -3723,7 +3747,9 @@ var RecordKeyOrder = {
3723
3747
  needed_to_close: 10,
3724
3748
  decision: 11,
3725
3749
  alternatives_rejected: 12,
3726
- consequences: 13
3750
+ consequences: 13,
3751
+ context: 14,
3752
+ meta: 15
3727
3753
  };
3728
3754
  var LinkKeyOrder = {
3729
3755
  type: 0,
@@ -3745,6 +3771,8 @@ function validateLinkIntegrity(register) {
3745
3771
  const ids = new Set(register.records.map((r) => r.id));
3746
3772
  for (const record of register.records) {
3747
3773
  for (const link of record.links) {
3774
+ if (link.type === "external")
3775
+ continue;
3748
3776
  if (!ids.has(link.target)) {
3749
3777
  return `Record ${record.id} links to non-existent target ${link.target}`;
3750
3778
  }
@@ -3775,6 +3803,12 @@ function normalizeRecord(record) {
3775
3803
  if (base.status_reason === undefined) {
3776
3804
  delete base.status_reason;
3777
3805
  }
3806
+ if (base.context === undefined) {
3807
+ delete base.context;
3808
+ }
3809
+ if (base.meta === undefined) {
3810
+ delete base.meta;
3811
+ }
3778
3812
  if (Array.isArray(base.links)) {
3779
3813
  base.links = base.links.map((link) => sortObjectKeys(link, LinkKeyOrder));
3780
3814
  }
@@ -3858,6 +3892,14 @@ function initRegister(filePath, workspace) {
3858
3892
  };
3859
3893
  writeRegister(filePath, register);
3860
3894
  }
3895
+ function withExtras(base, input) {
3896
+ const extras = base;
3897
+ if (input.context !== undefined)
3898
+ extras.context = input.context;
3899
+ if (input.meta !== undefined)
3900
+ extras.meta = input.meta;
3901
+ return base;
3902
+ }
3861
3903
  function addRecord(filePath, input) {
3862
3904
  if (!fs.existsSync(filePath)) {
3863
3905
  throw new Error(`Register not found at ${filePath}. Run the decision-init tool first to create a new register.`);
@@ -3866,7 +3908,7 @@ function addRecord(filePath, input) {
3866
3908
  const id = allocateId(register.records, input.type);
3867
3909
  const owner = input.owner ?? register.workspace.owner;
3868
3910
  const change_authority = input.change_authority ?? register.workspace.change_authority;
3869
- const base = {
3911
+ const base = withExtras({
3870
3912
  schema_version: "1.0",
3871
3913
  id,
3872
3914
  type: input.type,
@@ -3876,7 +3918,7 @@ function addRecord(filePath, input) {
3876
3918
  change_authority,
3877
3919
  supersedes: input.supersedes ?? [],
3878
3920
  links: input.links ?? []
3879
- };
3921
+ }, input);
3880
3922
  let record;
3881
3923
  switch (input.type) {
3882
3924
  case "REQ":
@@ -3938,7 +3980,7 @@ function supersedeRecord(filePath, oldId, newRecordInput, reason) {
3938
3980
  const newId = allocateId(register.records, newRecordInput.type);
3939
3981
  const owner = newRecordInput.owner ?? register.workspace.owner;
3940
3982
  const change_authority = newRecordInput.change_authority ?? register.workspace.change_authority;
3941
- const base = {
3983
+ const base = withExtras({
3942
3984
  schema_version: "1.0",
3943
3985
  id: newId,
3944
3986
  type: newRecordInput.type,
@@ -3948,7 +3990,7 @@ function supersedeRecord(filePath, oldId, newRecordInput, reason) {
3948
3990
  change_authority,
3949
3991
  supersedes: [oldId],
3950
3992
  links: newRecordInput.links ?? []
3951
- };
3993
+ }, newRecordInput);
3952
3994
  let newRecord;
3953
3995
  switch (newRecordInput.type) {
3954
3996
  case "REQ":
@@ -4113,6 +4155,9 @@ function generateMarkdownView(register) {
4113
4155
  if (record.status_reason !== undefined) {
4114
4156
  lines.push(`- Status reason: ${record.status_reason}`);
4115
4157
  }
4158
+ if (record.context !== undefined) {
4159
+ lines.push(`- Context: ${record.context}`);
4160
+ }
4116
4161
  if (record.links.length > 0) {
4117
4162
  lines.push("- Links:");
4118
4163
  for (const link of record.links) {
@@ -4307,6 +4352,55 @@ function createDecisionTools() {
4307
4352
  };
4308
4353
  }
4309
4354
 
4355
+ // src/v2/setup.ts
4356
+ import { z as z5 } from "zod";
4357
+ var INTERVIEW_MARKER = "You are running an interview q&a session for the user inside their repository";
4358
+ var SENTINEL2 = "<!-- decision-layer:inject v1 -->";
4359
+ function isRecord(value) {
4360
+ return typeof value === "object" && value !== null && !Array.isArray(value);
4361
+ }
4362
+ function createV2Setup() {
4363
+ return async (ctx) => {
4364
+ const projectDir = ctx.location.directory;
4365
+ const tools = createDecisionTools();
4366
+ await ctx.tool.transform((editor) => {
4367
+ for (const [name, definition] of Object.entries(tools)) {
4368
+ editor.add({
4369
+ name,
4370
+ description: definition.description,
4371
+ input: z5.object(definition.args),
4372
+ execute: async (input, toolContext) => {
4373
+ const v1Context = {
4374
+ ...isRecord(toolContext) ? toolContext : {},
4375
+ worktree: projectDir,
4376
+ directory: projectDir
4377
+ };
4378
+ const result = await definition.execute(input, v1Context);
4379
+ return { content: result };
4380
+ }
4381
+ });
4382
+ }
4383
+ });
4384
+ await ctx.session.hook("prompt", async (event) => {
4385
+ try {
4386
+ if (!isRecord(event))
4387
+ return;
4388
+ const prompt = event.prompt;
4389
+ if (!isRecord(prompt) || typeof prompt.text !== "string")
4390
+ return;
4391
+ if (!prompt.text.includes(INTERVIEW_MARKER))
4392
+ return;
4393
+ if (prompt.text.includes(SENTINEL2))
4394
+ return;
4395
+ prompt.text = `${prompt.text}
4396
+
4397
+ ${SENTINEL2}
4398
+ ${DECISION_DISCIPLINE_PROMPT}`;
4399
+ } catch {}
4400
+ });
4401
+ };
4402
+ }
4403
+
4310
4404
  // src/index.ts
4311
4405
  var DecisionLayer = async () => {
4312
4406
  const hooks = {
@@ -4315,10 +4409,12 @@ var DecisionLayer = async () => {
4315
4409
  };
4316
4410
  return hooks;
4317
4411
  };
4318
- var src_default = {
4412
+ var pluginModule = {
4319
4413
  id: "omo-slim-decision-layer",
4320
- server: DecisionLayer
4414
+ server: DecisionLayer,
4415
+ setup: createV2Setup()
4321
4416
  };
4417
+ var src_default = pluginModule;
4322
4418
  export {
4323
4419
  src_default as default
4324
4420
  };
@@ -3,7 +3,7 @@ export declare const RecordTypes: readonly ['REQ', 'CONSTRAINT', 'ASSUMPTION', '
3
3
  export type RecordType = (typeof RecordTypes)[number];
4
4
  export declare const RecordStatuses: readonly ['proposed', 'accepted', 'rejected', 'superseded'];
5
5
  export type RecordStatus = (typeof RecordStatuses)[number];
6
- export declare const LinkRelations: readonly ['refines', 'depends_on', 'constrains', 'relates_to'];
6
+ export declare const LinkRelations: readonly ['refines', 'depends_on', 'constrains', 'relates_to', 'decides', 'implements', 'satisfies', 'external'];
7
7
  export type LinkRelation = (typeof LinkRelations)[number];
8
8
  export declare function recordIdPattern(type: RecordType): RegExp;
9
9
  export declare const RecordId: z.ZodString;
@@ -11,9 +11,13 @@ export type RecordId = z.infer<typeof RecordId>;
11
11
  export declare const LinkSchema: z.ZodObject<{
12
12
  type: z.ZodEnum<{
13
13
  constrains: "constrains";
14
+ decides: "decides";
14
15
  depends_on: "depends_on";
16
+ external: "external";
17
+ implements: "implements";
15
18
  refines: "refines";
16
19
  relates_to: "relates_to";
20
+ satisfies: "satisfies";
17
21
  }>;
18
22
  target: z.ZodString;
19
23
  rationale: z.ZodString;
@@ -35,16 +39,22 @@ export declare const ReqRecordSchema: z.ZodObject<{
35
39
  links: z.ZodDefault<z.ZodArray<z.ZodObject<{
36
40
  type: z.ZodEnum<{
37
41
  constrains: "constrains";
42
+ decides: "decides";
38
43
  depends_on: "depends_on";
44
+ external: "external";
45
+ implements: "implements";
39
46
  refines: "refines";
40
47
  relates_to: "relates_to";
48
+ satisfies: "satisfies";
41
49
  }>;
42
50
  target: z.ZodString;
43
51
  rationale: z.ZodString;
44
52
  }, z.core.$strip>>>;
53
+ context: z.ZodOptional<z.ZodString>;
54
+ meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
45
55
  type: z.ZodLiteral<"REQ">;
46
56
  id: z.ZodString;
47
- }, z.core.$strip>;
57
+ }, z.core.$strict>;
48
58
  export declare const ConstraintRecordSchema: z.ZodObject<{
49
59
  schema_version: z.ZodLiteral<"1.0">;
50
60
  title: z.ZodString;
@@ -61,16 +71,22 @@ export declare const ConstraintRecordSchema: z.ZodObject<{
61
71
  links: z.ZodDefault<z.ZodArray<z.ZodObject<{
62
72
  type: z.ZodEnum<{
63
73
  constrains: "constrains";
74
+ decides: "decides";
64
75
  depends_on: "depends_on";
76
+ external: "external";
77
+ implements: "implements";
65
78
  refines: "refines";
66
79
  relates_to: "relates_to";
80
+ satisfies: "satisfies";
67
81
  }>;
68
82
  target: z.ZodString;
69
83
  rationale: z.ZodString;
70
84
  }, z.core.$strip>>>;
85
+ context: z.ZodOptional<z.ZodString>;
86
+ meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
71
87
  type: z.ZodLiteral<"CONSTRAINT">;
72
88
  id: z.ZodString;
73
- }, z.core.$strip>;
89
+ }, z.core.$strict>;
74
90
  export declare const AssumptionRecordSchema: z.ZodObject<{
75
91
  schema_version: z.ZodLiteral<"1.0">;
76
92
  title: z.ZodString;
@@ -87,17 +103,23 @@ export declare const AssumptionRecordSchema: z.ZodObject<{
87
103
  links: z.ZodDefault<z.ZodArray<z.ZodObject<{
88
104
  type: z.ZodEnum<{
89
105
  constrains: "constrains";
106
+ decides: "decides";
90
107
  depends_on: "depends_on";
108
+ external: "external";
109
+ implements: "implements";
91
110
  refines: "refines";
92
111
  relates_to: "relates_to";
112
+ satisfies: "satisfies";
93
113
  }>;
94
114
  target: z.ZodString;
95
115
  rationale: z.ZodString;
96
116
  }, z.core.$strip>>>;
117
+ context: z.ZodOptional<z.ZodString>;
118
+ meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
97
119
  type: z.ZodLiteral<"ASSUMPTION">;
98
120
  id: z.ZodString;
99
121
  needed_to_close: z.ZodString;
100
- }, z.core.$strip>;
122
+ }, z.core.$strict>;
101
123
  export declare const DecRecordSchema: z.ZodObject<{
102
124
  schema_version: z.ZodLiteral<"1.0">;
103
125
  title: z.ZodString;
@@ -114,13 +136,19 @@ export declare const DecRecordSchema: z.ZodObject<{
114
136
  links: z.ZodDefault<z.ZodArray<z.ZodObject<{
115
137
  type: z.ZodEnum<{
116
138
  constrains: "constrains";
139
+ decides: "decides";
117
140
  depends_on: "depends_on";
141
+ external: "external";
142
+ implements: "implements";
118
143
  refines: "refines";
119
144
  relates_to: "relates_to";
145
+ satisfies: "satisfies";
120
146
  }>;
121
147
  target: z.ZodString;
122
148
  rationale: z.ZodString;
123
149
  }, z.core.$strip>>>;
150
+ context: z.ZodOptional<z.ZodString>;
151
+ meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
124
152
  type: z.ZodLiteral<"DEC">;
125
153
  id: z.ZodString;
126
154
  decision: z.ZodString;
@@ -129,7 +157,7 @@ export declare const DecRecordSchema: z.ZodObject<{
129
157
  rejected_because: z.ZodString;
130
158
  }, z.core.$strip>>>;
131
159
  consequences: z.ZodString;
132
- }, z.core.$strip>;
160
+ }, z.core.$strict>;
133
161
  export declare const RecordSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
134
162
  schema_version: z.ZodLiteral<"1.0">;
135
163
  title: z.ZodString;
@@ -146,16 +174,22 @@ export declare const RecordSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
146
174
  links: z.ZodDefault<z.ZodArray<z.ZodObject<{
147
175
  type: z.ZodEnum<{
148
176
  constrains: "constrains";
177
+ decides: "decides";
149
178
  depends_on: "depends_on";
179
+ external: "external";
180
+ implements: "implements";
150
181
  refines: "refines";
151
182
  relates_to: "relates_to";
183
+ satisfies: "satisfies";
152
184
  }>;
153
185
  target: z.ZodString;
154
186
  rationale: z.ZodString;
155
187
  }, z.core.$strip>>>;
188
+ context: z.ZodOptional<z.ZodString>;
189
+ meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
156
190
  type: z.ZodLiteral<"REQ">;
157
191
  id: z.ZodString;
158
- }, z.core.$strip>, z.ZodObject<{
192
+ }, z.core.$strict>, z.ZodObject<{
159
193
  schema_version: z.ZodLiteral<"1.0">;
160
194
  title: z.ZodString;
161
195
  status: z.ZodEnum<{
@@ -171,16 +205,22 @@ export declare const RecordSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
171
205
  links: z.ZodDefault<z.ZodArray<z.ZodObject<{
172
206
  type: z.ZodEnum<{
173
207
  constrains: "constrains";
208
+ decides: "decides";
174
209
  depends_on: "depends_on";
210
+ external: "external";
211
+ implements: "implements";
175
212
  refines: "refines";
176
213
  relates_to: "relates_to";
214
+ satisfies: "satisfies";
177
215
  }>;
178
216
  target: z.ZodString;
179
217
  rationale: z.ZodString;
180
218
  }, z.core.$strip>>>;
219
+ context: z.ZodOptional<z.ZodString>;
220
+ meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
181
221
  type: z.ZodLiteral<"CONSTRAINT">;
182
222
  id: z.ZodString;
183
- }, z.core.$strip>, z.ZodObject<{
223
+ }, z.core.$strict>, z.ZodObject<{
184
224
  schema_version: z.ZodLiteral<"1.0">;
185
225
  title: z.ZodString;
186
226
  status: z.ZodEnum<{
@@ -196,17 +236,23 @@ export declare const RecordSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
196
236
  links: z.ZodDefault<z.ZodArray<z.ZodObject<{
197
237
  type: z.ZodEnum<{
198
238
  constrains: "constrains";
239
+ decides: "decides";
199
240
  depends_on: "depends_on";
241
+ external: "external";
242
+ implements: "implements";
200
243
  refines: "refines";
201
244
  relates_to: "relates_to";
245
+ satisfies: "satisfies";
202
246
  }>;
203
247
  target: z.ZodString;
204
248
  rationale: z.ZodString;
205
249
  }, z.core.$strip>>>;
250
+ context: z.ZodOptional<z.ZodString>;
251
+ meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
206
252
  type: z.ZodLiteral<"ASSUMPTION">;
207
253
  id: z.ZodString;
208
254
  needed_to_close: z.ZodString;
209
- }, z.core.$strip>, z.ZodObject<{
255
+ }, z.core.$strict>, z.ZodObject<{
210
256
  schema_version: z.ZodLiteral<"1.0">;
211
257
  title: z.ZodString;
212
258
  status: z.ZodEnum<{
@@ -222,13 +268,19 @@ export declare const RecordSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
222
268
  links: z.ZodDefault<z.ZodArray<z.ZodObject<{
223
269
  type: z.ZodEnum<{
224
270
  constrains: "constrains";
271
+ decides: "decides";
225
272
  depends_on: "depends_on";
273
+ external: "external";
274
+ implements: "implements";
226
275
  refines: "refines";
227
276
  relates_to: "relates_to";
277
+ satisfies: "satisfies";
228
278
  }>;
229
279
  target: z.ZodString;
230
280
  rationale: z.ZodString;
231
281
  }, z.core.$strip>>>;
282
+ context: z.ZodOptional<z.ZodString>;
283
+ meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
232
284
  type: z.ZodLiteral<"DEC">;
233
285
  id: z.ZodString;
234
286
  decision: z.ZodString;
@@ -237,7 +289,7 @@ export declare const RecordSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
237
289
  rejected_because: z.ZodString;
238
290
  }, z.core.$strip>>>;
239
291
  consequences: z.ZodString;
240
- }, z.core.$strip>], "type">;
292
+ }, z.core.$strict>], "type">;
241
293
  export type ReqRecord = z.infer<typeof ReqRecordSchema>;
242
294
  export type ConstraintRecord = z.infer<typeof ConstraintRecordSchema>;
243
295
  export type AssumptionRecord = z.infer<typeof AssumptionRecordSchema>;
@@ -251,15 +303,21 @@ export declare const AddRecordInputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<
251
303
  links: z.ZodOptional<z.ZodArray<z.ZodObject<{
252
304
  type: z.ZodEnum<{
253
305
  constrains: "constrains";
306
+ decides: "decides";
254
307
  depends_on: "depends_on";
308
+ external: "external";
309
+ implements: "implements";
255
310
  refines: "refines";
256
311
  relates_to: "relates_to";
312
+ satisfies: "satisfies";
257
313
  }>;
258
314
  target: z.ZodString;
259
315
  rationale: z.ZodString;
260
316
  }, z.core.$strip>>>;
317
+ context: z.ZodOptional<z.ZodString>;
318
+ meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
261
319
  type: z.ZodLiteral<"REQ">;
262
- }, z.core.$strip>, z.ZodObject<{
320
+ }, z.core.$strict>, z.ZodObject<{
263
321
  title: z.ZodString;
264
322
  owner: z.ZodOptional<z.ZodString>;
265
323
  change_authority: z.ZodOptional<z.ZodString>;
@@ -267,15 +325,21 @@ export declare const AddRecordInputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<
267
325
  links: z.ZodOptional<z.ZodArray<z.ZodObject<{
268
326
  type: z.ZodEnum<{
269
327
  constrains: "constrains";
328
+ decides: "decides";
270
329
  depends_on: "depends_on";
330
+ external: "external";
331
+ implements: "implements";
271
332
  refines: "refines";
272
333
  relates_to: "relates_to";
334
+ satisfies: "satisfies";
273
335
  }>;
274
336
  target: z.ZodString;
275
337
  rationale: z.ZodString;
276
338
  }, z.core.$strip>>>;
339
+ context: z.ZodOptional<z.ZodString>;
340
+ meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
277
341
  type: z.ZodLiteral<"CONSTRAINT">;
278
- }, z.core.$strip>, z.ZodObject<{
342
+ }, z.core.$strict>, z.ZodObject<{
279
343
  title: z.ZodString;
280
344
  owner: z.ZodOptional<z.ZodString>;
281
345
  change_authority: z.ZodOptional<z.ZodString>;
@@ -283,16 +347,22 @@ export declare const AddRecordInputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<
283
347
  links: z.ZodOptional<z.ZodArray<z.ZodObject<{
284
348
  type: z.ZodEnum<{
285
349
  constrains: "constrains";
350
+ decides: "decides";
286
351
  depends_on: "depends_on";
352
+ external: "external";
353
+ implements: "implements";
287
354
  refines: "refines";
288
355
  relates_to: "relates_to";
356
+ satisfies: "satisfies";
289
357
  }>;
290
358
  target: z.ZodString;
291
359
  rationale: z.ZodString;
292
360
  }, z.core.$strip>>>;
361
+ context: z.ZodOptional<z.ZodString>;
362
+ meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
293
363
  type: z.ZodLiteral<"ASSUMPTION">;
294
364
  needed_to_close: z.ZodString;
295
- }, z.core.$strip>, z.ZodObject<{
365
+ }, z.core.$strict>, z.ZodObject<{
296
366
  title: z.ZodString;
297
367
  owner: z.ZodOptional<z.ZodString>;
298
368
  change_authority: z.ZodOptional<z.ZodString>;
@@ -300,13 +370,19 @@ export declare const AddRecordInputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<
300
370
  links: z.ZodOptional<z.ZodArray<z.ZodObject<{
301
371
  type: z.ZodEnum<{
302
372
  constrains: "constrains";
373
+ decides: "decides";
303
374
  depends_on: "depends_on";
375
+ external: "external";
376
+ implements: "implements";
304
377
  refines: "refines";
305
378
  relates_to: "relates_to";
379
+ satisfies: "satisfies";
306
380
  }>;
307
381
  target: z.ZodString;
308
382
  rationale: z.ZodString;
309
383
  }, z.core.$strip>>>;
384
+ context: z.ZodOptional<z.ZodString>;
385
+ meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
310
386
  type: z.ZodLiteral<"DEC">;
311
387
  decision: z.ZodString;
312
388
  alternatives_rejected: z.ZodOptional<z.ZodArray<z.ZodObject<{
@@ -314,7 +390,7 @@ export declare const AddRecordInputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<
314
390
  rejected_because: z.ZodString;
315
391
  }, z.core.$strip>>>;
316
392
  consequences: z.ZodString;
317
- }, z.core.$strip>], "type">;
393
+ }, z.core.$strict>], "type">;
318
394
  export type AddRecordInput = z.infer<typeof AddRecordInputSchema>;
319
395
  export declare function sortRecords(records: DecisionRecord[]): DecisionRecord[];
320
396
  export declare function recordType(id: string): RecordType | undefined;
@@ -41,16 +41,22 @@ export declare const RegisterSchema: z.ZodObject<{
41
41
  links: z.ZodDefault<z.ZodArray<z.ZodObject<{
42
42
  type: z.ZodEnum<{
43
43
  constrains: "constrains";
44
+ decides: "decides";
44
45
  depends_on: "depends_on";
46
+ external: "external";
47
+ implements: "implements";
45
48
  refines: "refines";
46
49
  relates_to: "relates_to";
50
+ satisfies: "satisfies";
47
51
  }>;
48
52
  target: z.ZodString;
49
53
  rationale: z.ZodString;
50
54
  }, z.core.$strip>>>;
55
+ context: z.ZodOptional<z.ZodString>;
56
+ meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
51
57
  type: z.ZodLiteral<"REQ">;
52
58
  id: z.ZodString;
53
- }, z.core.$strip>, z.ZodObject<{
59
+ }, z.core.$strict>, z.ZodObject<{
54
60
  schema_version: z.ZodLiteral<"1.0">;
55
61
  title: z.ZodString;
56
62
  status: z.ZodEnum<{
@@ -66,16 +72,22 @@ export declare const RegisterSchema: z.ZodObject<{
66
72
  links: z.ZodDefault<z.ZodArray<z.ZodObject<{
67
73
  type: z.ZodEnum<{
68
74
  constrains: "constrains";
75
+ decides: "decides";
69
76
  depends_on: "depends_on";
77
+ external: "external";
78
+ implements: "implements";
70
79
  refines: "refines";
71
80
  relates_to: "relates_to";
81
+ satisfies: "satisfies";
72
82
  }>;
73
83
  target: z.ZodString;
74
84
  rationale: z.ZodString;
75
85
  }, z.core.$strip>>>;
86
+ context: z.ZodOptional<z.ZodString>;
87
+ meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
76
88
  type: z.ZodLiteral<"CONSTRAINT">;
77
89
  id: z.ZodString;
78
- }, z.core.$strip>, z.ZodObject<{
90
+ }, z.core.$strict>, z.ZodObject<{
79
91
  schema_version: z.ZodLiteral<"1.0">;
80
92
  title: z.ZodString;
81
93
  status: z.ZodEnum<{
@@ -91,17 +103,23 @@ export declare const RegisterSchema: z.ZodObject<{
91
103
  links: z.ZodDefault<z.ZodArray<z.ZodObject<{
92
104
  type: z.ZodEnum<{
93
105
  constrains: "constrains";
106
+ decides: "decides";
94
107
  depends_on: "depends_on";
108
+ external: "external";
109
+ implements: "implements";
95
110
  refines: "refines";
96
111
  relates_to: "relates_to";
112
+ satisfies: "satisfies";
97
113
  }>;
98
114
  target: z.ZodString;
99
115
  rationale: z.ZodString;
100
116
  }, z.core.$strip>>>;
117
+ context: z.ZodOptional<z.ZodString>;
118
+ meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
101
119
  type: z.ZodLiteral<"ASSUMPTION">;
102
120
  id: z.ZodString;
103
121
  needed_to_close: z.ZodString;
104
- }, z.core.$strip>, z.ZodObject<{
122
+ }, z.core.$strict>, z.ZodObject<{
105
123
  schema_version: z.ZodLiteral<"1.0">;
106
124
  title: z.ZodString;
107
125
  status: z.ZodEnum<{
@@ -117,13 +135,19 @@ export declare const RegisterSchema: z.ZodObject<{
117
135
  links: z.ZodDefault<z.ZodArray<z.ZodObject<{
118
136
  type: z.ZodEnum<{
119
137
  constrains: "constrains";
138
+ decides: "decides";
120
139
  depends_on: "depends_on";
140
+ external: "external";
141
+ implements: "implements";
121
142
  refines: "refines";
122
143
  relates_to: "relates_to";
144
+ satisfies: "satisfies";
123
145
  }>;
124
146
  target: z.ZodString;
125
147
  rationale: z.ZodString;
126
148
  }, z.core.$strip>>>;
149
+ context: z.ZodOptional<z.ZodString>;
150
+ meta: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
127
151
  type: z.ZodLiteral<"DEC">;
128
152
  id: z.ZodString;
129
153
  decision: z.ZodString;
@@ -132,7 +156,7 @@ export declare const RegisterSchema: z.ZodObject<{
132
156
  rejected_because: z.ZodString;
133
157
  }, z.core.$strip>>>;
134
158
  consequences: z.ZodString;
135
- }, z.core.$strip>], "type">>;
159
+ }, z.core.$strict>], "type">>;
136
160
  }, z.core.$strip>;
137
161
  export declare function readRegister(filePath: string): Register;
138
162
  export declare function validateRegisterFile(filePath: string): void;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * v2 registration path, next to the v1 `server` export.
3
+ *
4
+ * Differences that matter for v2 (verified against @opencode/plugin 2.0.29):
5
+ * - tools are registered via `ctx.tool.transform` with a full input schema
6
+ * (zod object) instead of a raw args shape;
7
+ * - the tool context has no `worktree`/`directory`, so the project root is
8
+ * captured from `ctx.location.directory` at setup time and closed over;
9
+ * - the interview injection uses `ctx.session.hook('prompt')` and mutates the
10
+ * outgoing prompt instead of appending to `command.execute.before` parts.
11
+ */
12
+ interface V2TransformEditor {
13
+ add: (tool: unknown) => void;
14
+ }
15
+ export interface V2Context {
16
+ location: {
17
+ directory: string;
18
+ };
19
+ tool: {
20
+ transform: (callback: (editor: V2TransformEditor) => void) => Promise<unknown>;
21
+ };
22
+ session: {
23
+ hook: (name: string, callback: (event: unknown) => Promise<void> | void) => Promise<unknown>;
24
+ };
25
+ }
26
+ export declare function createV2Setup(): (ctx: V2Context) => Promise<void>;
27
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digi4care/omo-slim-decision-layer",
3
- "version": "0.2.3",
3
+ "version": "0.4.0",
4
4
  "description": "Git-native decision register for OpenCode: typed records (REQ/CONSTRAINT/ASSUMPTION/DEC), owner ratification and traceability, as a companion plugin for oh-my-opencode-slim",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -64,6 +64,7 @@
64
64
  "devDependencies": {
65
65
  "@biomejs/biome": "2.5.15",
66
66
  "@opencode-ai/plugin": "1.18.35",
67
+ "@opencode/plugin": "^2.0.29",
67
68
  "bun-types": "^1.4.2",
68
69
  "typescript": "^7.0.2"
69
70
  },
@@ -74,10 +74,20 @@
74
74
  "properties": {
75
75
  "type": {
76
76
  "type": "string",
77
- "enum": ["refines", "depends_on", "constrains", "relates_to"]
77
+ "enum": [
78
+ "refines",
79
+ "depends_on",
80
+ "constrains",
81
+ "relates_to",
82
+ "decides",
83
+ "implements",
84
+ "satisfies",
85
+ "external"
86
+ ]
78
87
  },
79
88
  "target": {
80
- "type": "string"
89
+ "type": "string",
90
+ "minLength": 1
81
91
  },
82
92
  "rationale": {
83
93
  "type": "string",
@@ -88,6 +98,16 @@
88
98
  "additionalProperties": false
89
99
  }
90
100
  },
101
+ "context": {
102
+ "type": "string"
103
+ },
104
+ "meta": {
105
+ "type": "object",
106
+ "propertyNames": {
107
+ "type": "string"
108
+ },
109
+ "additionalProperties": {}
110
+ },
91
111
  "type": {
92
112
  "type": "string",
93
113
  "const": "REQ"
@@ -150,10 +170,20 @@
150
170
  "properties": {
151
171
  "type": {
152
172
  "type": "string",
153
- "enum": ["refines", "depends_on", "constrains", "relates_to"]
173
+ "enum": [
174
+ "refines",
175
+ "depends_on",
176
+ "constrains",
177
+ "relates_to",
178
+ "decides",
179
+ "implements",
180
+ "satisfies",
181
+ "external"
182
+ ]
154
183
  },
155
184
  "target": {
156
- "type": "string"
185
+ "type": "string",
186
+ "minLength": 1
157
187
  },
158
188
  "rationale": {
159
189
  "type": "string",
@@ -164,6 +194,16 @@
164
194
  "additionalProperties": false
165
195
  }
166
196
  },
197
+ "context": {
198
+ "type": "string"
199
+ },
200
+ "meta": {
201
+ "type": "object",
202
+ "propertyNames": {
203
+ "type": "string"
204
+ },
205
+ "additionalProperties": {}
206
+ },
167
207
  "type": {
168
208
  "type": "string",
169
209
  "const": "CONSTRAINT"
@@ -226,10 +266,20 @@
226
266
  "properties": {
227
267
  "type": {
228
268
  "type": "string",
229
- "enum": ["refines", "depends_on", "constrains", "relates_to"]
269
+ "enum": [
270
+ "refines",
271
+ "depends_on",
272
+ "constrains",
273
+ "relates_to",
274
+ "decides",
275
+ "implements",
276
+ "satisfies",
277
+ "external"
278
+ ]
230
279
  },
231
280
  "target": {
232
- "type": "string"
281
+ "type": "string",
282
+ "minLength": 1
233
283
  },
234
284
  "rationale": {
235
285
  "type": "string",
@@ -240,6 +290,16 @@
240
290
  "additionalProperties": false
241
291
  }
242
292
  },
293
+ "context": {
294
+ "type": "string"
295
+ },
296
+ "meta": {
297
+ "type": "object",
298
+ "propertyNames": {
299
+ "type": "string"
300
+ },
301
+ "additionalProperties": {}
302
+ },
243
303
  "type": {
244
304
  "type": "string",
245
305
  "const": "ASSUMPTION"
@@ -307,10 +367,20 @@
307
367
  "properties": {
308
368
  "type": {
309
369
  "type": "string",
310
- "enum": ["refines", "depends_on", "constrains", "relates_to"]
370
+ "enum": [
371
+ "refines",
372
+ "depends_on",
373
+ "constrains",
374
+ "relates_to",
375
+ "decides",
376
+ "implements",
377
+ "satisfies",
378
+ "external"
379
+ ]
311
380
  },
312
381
  "target": {
313
- "type": "string"
382
+ "type": "string",
383
+ "minLength": 1
314
384
  },
315
385
  "rationale": {
316
386
  "type": "string",
@@ -321,6 +391,16 @@
321
391
  "additionalProperties": false
322
392
  }
323
393
  },
394
+ "context": {
395
+ "type": "string"
396
+ },
397
+ "meta": {
398
+ "type": "object",
399
+ "propertyNames": {
400
+ "type": "string"
401
+ },
402
+ "additionalProperties": {}
403
+ },
324
404
  "type": {
325
405
  "type": "string",
326
406
  "const": "DEC"