traits 0.5.1 → 0.5.3

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 (112) hide show
  1. package/Source.ts +1 -1
  2. package/Trait.ts +109 -4
  3. package/TraitConflict.ts +43 -4
  4. package/TraitDerivation.ts +104 -32
  5. package/TraitEvaluation.ts +104 -49
  6. package/TraitStore.ts +123 -44
  7. package/TraitsConfig.ts +16 -9
  8. package/TraitsContext.ts +3 -1
  9. package/_util/Frontmatter.ts +78 -0
  10. package/_util/Git.ts +6 -5
  11. package/bin.ts +3 -1
  12. package/dist/Source.js +1 -1
  13. package/dist/Source.js.map +1 -1
  14. package/dist/Trait.d.ts +39 -5
  15. package/dist/Trait.d.ts.map +1 -1
  16. package/dist/Trait.js +66 -3
  17. package/dist/Trait.js.map +1 -1
  18. package/dist/TraitConflict.d.ts +47 -15
  19. package/dist/TraitConflict.d.ts.map +1 -1
  20. package/dist/TraitConflict.js +38 -4
  21. package/dist/TraitConflict.js.map +1 -1
  22. package/dist/TraitDerivation.d.ts +85 -28
  23. package/dist/TraitDerivation.d.ts.map +1 -1
  24. package/dist/TraitDerivation.js +85 -23
  25. package/dist/TraitDerivation.js.map +1 -1
  26. package/dist/TraitEvaluation.d.ts +38 -8
  27. package/dist/TraitEvaluation.d.ts.map +1 -1
  28. package/dist/TraitEvaluation.js +84 -47
  29. package/dist/TraitEvaluation.js.map +1 -1
  30. package/dist/TraitStore.d.ts +54 -10
  31. package/dist/TraitStore.d.ts.map +1 -1
  32. package/dist/TraitStore.js +61 -37
  33. package/dist/TraitStore.js.map +1 -1
  34. package/dist/TraitsConfig.d.ts +4 -3
  35. package/dist/TraitsConfig.d.ts.map +1 -1
  36. package/dist/TraitsConfig.js +12 -5
  37. package/dist/TraitsConfig.js.map +1 -1
  38. package/dist/TraitsContext.d.ts +2 -1
  39. package/dist/TraitsContext.d.ts.map +1 -1
  40. package/dist/TraitsContext.js.map +1 -1
  41. package/dist/_util/Frontmatter.d.ts +37 -0
  42. package/dist/_util/Frontmatter.d.ts.map +1 -0
  43. package/dist/_util/Frontmatter.js +52 -0
  44. package/dist/_util/Frontmatter.js.map +1 -0
  45. package/dist/_util/Git.d.ts +2 -3
  46. package/dist/_util/Git.d.ts.map +1 -1
  47. package/dist/_util/Git.js +4 -1
  48. package/dist/_util/Git.js.map +1 -1
  49. package/dist/bin.js +3 -1
  50. package/dist/bin.js.map +1 -1
  51. package/dist/getIncludedFiles.d.ts +13 -0
  52. package/dist/getIncludedFiles.d.ts.map +1 -0
  53. package/dist/getIncludedFiles.js +26 -0
  54. package/dist/getIncludedFiles.js.map +1 -0
  55. package/dist/main.js +16 -12
  56. package/dist/main.js.map +1 -1
  57. package/dist/package.json +7 -2
  58. package/dist/test/Frontmatter.test.d.ts +2 -0
  59. package/dist/test/Frontmatter.test.d.ts.map +1 -0
  60. package/dist/test/Frontmatter.test.js +29 -0
  61. package/dist/test/Frontmatter.test.js.map +1 -0
  62. package/dist/test/Trait.test.d.ts +2 -0
  63. package/dist/test/Trait.test.d.ts.map +1 -0
  64. package/dist/test/Trait.test.js +144 -0
  65. package/dist/test/Trait.test.js.map +1 -0
  66. package/dist/test/TraitDerivation.test.d.ts +2 -0
  67. package/dist/test/TraitDerivation.test.d.ts.map +1 -0
  68. package/dist/test/TraitDerivation.test.js +173 -0
  69. package/dist/test/TraitDerivation.test.js.map +1 -0
  70. package/dist/test/TraitEvaluation.test.d.ts +2 -0
  71. package/dist/test/TraitEvaluation.test.d.ts.map +1 -0
  72. package/dist/test/TraitEvaluation.test.js +116 -0
  73. package/dist/test/TraitEvaluation.test.js.map +1 -0
  74. package/dist/test/TraitIgnores.test.js +29 -5
  75. package/dist/test/TraitIgnores.test.js.map +1 -1
  76. package/dist/test/TraitStore.test.d.ts +2 -0
  77. package/dist/test/TraitStore.test.d.ts.map +1 -0
  78. package/dist/test/TraitStore.test.js +120 -0
  79. package/dist/test/TraitStore.test.js.map +1 -0
  80. package/dist/test/TraitsInitialization.test.d.ts +2 -0
  81. package/dist/test/TraitsInitialization.test.d.ts.map +1 -0
  82. package/dist/test/TraitsInitialization.test.js +130 -0
  83. package/dist/test/TraitsInitialization.test.js.map +1 -0
  84. package/dist/toolkit/CheckTraits.d.ts +97 -13
  85. package/dist/toolkit/CheckTraits.d.ts.map +1 -1
  86. package/dist/toolkit/CheckTraits.js +28 -40
  87. package/dist/toolkit/CheckTraits.js.map +1 -1
  88. package/dist/toolkit/ConfigurationError.d.ts +3 -0
  89. package/dist/toolkit/ConfigurationError.d.ts.map +1 -0
  90. package/dist/toolkit/ConfigurationError.js +15 -0
  91. package/dist/toolkit/ConfigurationError.js.map +1 -0
  92. package/dist/toolkit/DeriveTrait.d.ts +137 -45
  93. package/dist/toolkit/DeriveTrait.d.ts.map +1 -1
  94. package/dist/toolkit/DeriveTrait.js +26 -14
  95. package/dist/toolkit/DeriveTrait.js.map +1 -1
  96. package/dist/traitIgnores.d.ts +18 -0
  97. package/dist/traitIgnores.d.ts.map +1 -1
  98. package/dist/traitIgnores.js +10 -7
  99. package/dist/traitIgnores.js.map +1 -1
  100. package/getIncludedFiles.ts +42 -0
  101. package/main.ts +17 -12
  102. package/package.json +7 -2
  103. package/skills/traits/SKILL.md +107 -51
  104. package/toolkit/CheckTraits.ts +34 -55
  105. package/toolkit/ConfigurationError.ts +27 -0
  106. package/toolkit/DeriveTrait.ts +27 -14
  107. package/traitIgnores.ts +14 -6
  108. package/_util/words.ts +0 -555
  109. package/dist/_util/words.d.ts +0 -2
  110. package/dist/_util/words.d.ts.map +0 -1
  111. package/dist/_util/words.js +0 -556
  112. package/dist/_util/words.js.map +0 -1
@@ -0,0 +1,173 @@
1
+ import { expect, it } from "@effect/vitest";
2
+ import { Array, Effect, Layer, pipe, Predicate, Record, Semaphore, Stream } from "effect";
3
+ import { DecisionModel, LanguageModel } from "effect/ai";
4
+ import { toCodecOpenAI } from "effect/ai/OpenAiStructuredOutput";
5
+ import * as Trait from "../Trait.js";
6
+ import { derive } from "../TraitDerivation.js";
7
+ import { TraitsContext } from "../TraitsContext.js";
8
+ import * as TraitStore from "../TraitStore.js";
9
+ const name = Trait.TraitName.make("indentation");
10
+ const original = Trait.Trait.make({
11
+ name,
12
+ body: "Use tabs for indentation."
13
+ });
14
+ const proposedTrait = "Use two spaces for indentation.";
15
+ const harness = Effect.fn("test.harness")(function* (options) {
16
+ const stored = new Map([[original.name, original]]);
17
+ if (options.unaffected !== undefined)
18
+ stored.set(options.unaffected.name, options.unaffected);
19
+ const mutations = [];
20
+ const requests = [];
21
+ const decisionModel = yield* DecisionModel.make({
22
+ decide: (request) => {
23
+ const relationship = Predicate.hasProperty(request.state, "trait");
24
+ const label = relationship
25
+ ? Predicate.hasProperty(request.state.trait, "name") && request.state.trait.name === original.name
26
+ ? "conflict"
27
+ : "distinct"
28
+ : options.decomposable === true
29
+ ? "decomposable"
30
+ : "atomic";
31
+ const labels = relationship
32
+ ? ["distinct", "covered", "clarification", "conflict", "inconclusive"]
33
+ : ["atomic", "decomposable"];
34
+ return Effect.succeed({
35
+ answers: {
36
+ assessment: {
37
+ _tag: "Classify",
38
+ label,
39
+ probabilities: pipe(labels, Array.map((key) => [key, key === label ? 1 : 0]), Record.fromEntries)
40
+ }
41
+ },
42
+ usage: { inputTokens: 0, outputTokens: 0 }
43
+ });
44
+ }
45
+ });
46
+ const languageModel = yield* LanguageModel.make({
47
+ generateText: (request) => {
48
+ requests.push(request);
49
+ return Effect.succeed([
50
+ {
51
+ type: "text",
52
+ text: options.responseText ?? JSON.stringify({ traits: [{ name, body: proposedTrait, extensionMetadata: "{}" }] })
53
+ }
54
+ ]);
55
+ },
56
+ streamText: () => Stream.empty,
57
+ codecTransformer: toCodecOpenAI
58
+ });
59
+ const store = TraitStore.TraitStore.of({
60
+ ls: Effect.sync(() => [...stored.values()]),
61
+ add: (trait) => Effect.suspend(() => {
62
+ if (stored.has(trait.name))
63
+ return TraitStore.TraitAlreadyExistsError.make({ name: trait.name });
64
+ mutations.push("add");
65
+ stored.set(trait.name, trait);
66
+ return Effect.succeed(trait);
67
+ }),
68
+ update: (trait) => Effect.sync(() => {
69
+ mutations.push("update");
70
+ stored.set(trait.name, trait);
71
+ }),
72
+ get: (name) => Effect.suspend(() => {
73
+ const trait = stored.get(name);
74
+ return trait === undefined ? TraitStore.TraitNotFoundError.make({ name }) : Effect.succeed(trait);
75
+ }),
76
+ rm: (names) => Effect.sync(() => {
77
+ mutations.push("rm");
78
+ for (const name of names)
79
+ stored.delete(name);
80
+ })
81
+ });
82
+ const semaphore = yield* Semaphore.make(4);
83
+ const layer = Layer.mergeAll(Layer.succeed(DecisionModel.DecisionModel, decisionModel), Layer.succeed(LanguageModel.LanguageModel, languageModel), Layer.succeed(TraitStore.TraitStore, store), Layer.succeed(TraitsContext, {
84
+ configRoot: "/test",
85
+ excludes: [],
86
+ semaphore,
87
+ config: {
88
+ decisionConcurrency: 4,
89
+ excludeGitignored: true,
90
+ excludes: [],
91
+ layerDecisionModel: Layer.succeed(DecisionModel.DecisionModel, decisionModel),
92
+ layerLanguageModel: Layer.succeed(LanguageModel.LanguageModel, languageModel)
93
+ }
94
+ }));
95
+ return { stored, mutations, requests, layer };
96
+ });
97
+ it.effect("does not generate replacements or mutate traits before approval", Effect.fnUntraced(function* () {
98
+ const test = yield* harness({});
99
+ const result = yield* derive({ name, proposedTrait }).pipe(Effect.provide(test.layer));
100
+ expect(result._tag).toBe("ApprovalRequired");
101
+ expect(test.requests).toEqual([]);
102
+ expect(test.mutations).toEqual([]);
103
+ }));
104
+ it.effect("requests explicit JSON and updates reused names without deleting replacements", Effect.fnUntraced(function* () {
105
+ const test = yield* harness({});
106
+ const result = yield* derive({ name, proposedTrait, approved: true }).pipe(Effect.provide(test.layer));
107
+ expect(result._tag).toBe("Resolved");
108
+ expect(test.mutations).toEqual(["update", "rm"]);
109
+ expect(pipe(test.stored.values(), Array.fromIterable, Array.map((trait) => trait.body))).toEqual([proposedTrait]);
110
+ expect(test.requests).toHaveLength(1);
111
+ expect(test.requests[0]?.prompt.content[0]).toMatchObject({
112
+ role: "system",
113
+ content: expect.stringContaining('Return only a JSON object with this shape: {"traits":[{"name":')
114
+ });
115
+ }));
116
+ it.effect("leaves originals untouched when generation returns invalid output", Effect.fnUntraced(function* () {
117
+ for (const responseText of ["Use two spaces for indentation.", '{"traits":[]}']) {
118
+ const test = yield* harness({ responseText });
119
+ const error = yield* derive({ name, proposedTrait, approved: true }).pipe(Effect.provide(test.layer), Effect.flip);
120
+ expect(error).toMatchObject({
121
+ module: "LanguageModel",
122
+ method: "generateObject",
123
+ reason: { _tag: "StructuredOutputError" }
124
+ });
125
+ expect(test.mutations).toEqual([]);
126
+ expect([...test.stored.values()]).toEqual([original]);
127
+ }
128
+ }));
129
+ it.effect("rejects duplicate replacement names and unaffected-name collisions before any writes", Effect.fnUntraced(function* () {
130
+ const unaffected = Trait.Trait.make({
131
+ name: Trait.TraitName.make("unrelated"),
132
+ body: "Keep unrelated requirements."
133
+ });
134
+ for (const names of [
135
+ ["replacement", "replacement"],
136
+ ["replacement", unaffected.name]
137
+ ]) {
138
+ const test = yield* harness({
139
+ unaffected,
140
+ responseText: JSON.stringify({
141
+ traits: Array.map(names, (name) => ({ name, body: proposedTrait, extensionMetadata: "{}" }))
142
+ })
143
+ });
144
+ const error = yield* derive({ name, proposedTrait, approved: true }).pipe(Effect.provide(test.layer), Effect.flip);
145
+ expect(error).toBeInstanceOf(TraitStore.TraitAlreadyExistsError);
146
+ expect(test.mutations).toEqual([]);
147
+ expect([...test.stored.values()]).toEqual([original, unaffected]);
148
+ }
149
+ }));
150
+ it.effect("saves a new replacement name before removing the original", Effect.fnUntraced(function* () {
151
+ const replacementName = Trait.TraitName.make("two-space-indentation");
152
+ const test = yield* harness({
153
+ responseText: JSON.stringify({
154
+ traits: [{ name: replacementName, body: proposedTrait, extensionMetadata: "{}" }]
155
+ })
156
+ });
157
+ const result = yield* derive({ name, proposedTrait, approved: true }).pipe(Effect.provide(test.layer));
158
+ expect(result._tag).toBe("Resolved");
159
+ expect(test.mutations).toEqual(["add", "rm"]);
160
+ expect([...test.stored.keys()]).toEqual([replacementName]);
161
+ }));
162
+ it.effect("requests the distinct JSON shape required for decomposition", Effect.fnUntraced(function* () {
163
+ const bodies = ["Use two spaces for indentation.", "Use single quotes."];
164
+ const test = yield* harness({ decomposable: true, responseText: JSON.stringify({ traits: bodies }) });
165
+ const result = yield* Trait.checkDecomposability(Array.join(bodies, " ")).pipe(Effect.provide(test.layer));
166
+ expect(result).toEqual(bodies);
167
+ expect(test.requests[0]?.prompt.content[0]).toMatchObject({
168
+ role: "system",
169
+ content: expect.stringContaining('Return only a JSON object with this shape: {"traits":["')
170
+ });
171
+ expect(test.mutations).toEqual([]);
172
+ }));
173
+ //# sourceMappingURL=TraitDerivation.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TraitDerivation.test.js","sourceRoot":"","sources":["../../test/TraitDerivation.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAA;AAC3C,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AACzF,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,WAAW,CAAA;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAA;AAEhE,OAAO,KAAK,KAAK,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,KAAK,UAAU,MAAM,kBAAkB,CAAA;AAE9C,MAAM,IAAI,GAAG,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,CAAA;AAChD,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC;IAChC,IAAI;IACJ,IAAI,EAAE,2BAA2B;CAClC,CAAC,CAAA;AACF,MAAM,aAAa,GAAG,iCAAiC,CAAA;AAEvD,MAAM,OAAO,GAAG,MAAM,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,QAAQ,CAAC,EAAE,OAIpD;IACC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAA;IACnD,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS;QAAE,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,OAAO,CAAC,UAAU,CAAC,CAAA;IAC7F,MAAM,SAAS,GAAkB,EAAE,CAAA;IACnC,MAAM,QAAQ,GAAyC,EAAE,CAAA;IACzD,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC;QAC9C,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE;YAClB,MAAM,YAAY,GAAG,SAAS,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAA;YAClE,MAAM,KAAK,GAAG,YAAY;gBACxB,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,IAAI;oBAChG,CAAC,CAAC,UAAU;oBACZ,CAAC,CAAC,UAAU;gBACd,CAAC,CAAC,OAAO,CAAC,YAAY,KAAK,IAAI;oBAC7B,CAAC,CAAC,cAAc;oBAChB,CAAC,CAAC,QAAQ,CAAA;YACd,MAAM,MAAM,GAAG,YAAY;gBACzB,CAAC,CAAC,CAAC,UAAU,EAAE,SAAS,EAAE,eAAe,EAAE,UAAU,EAAE,cAAc,CAAC;gBACtE,CAAC,CAAC,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAA;YAC9B,OAAO,MAAM,CAAC,OAAO,CAAC;gBACpB,OAAO,EAAE;oBACP,UAAU,EAAE;wBACV,IAAI,EAAE,UAAU;wBAChB,KAAK;wBACL,aAAa,EAAE,IAAI,CACjB,MAAM,EACN,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,GAAG,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAU,CAAC,EACzD,MAAM,CAAC,WAAW,CACnB;qBACF;iBACF;gBACD,KAAK,EAAE,EAAE,WAAW,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE;aAC3C,CAAC,CAAA;QACJ,CAAC;KACF,CAAC,CAAA;IACF,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC;QAC9C,YAAY,EAAE,CAAC,OAAO,EAAE,EAAE;YACxB,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YACtB,OAAO,MAAM,CAAC,OAAO,CAAC;gBACpB;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EACF,OAAO,CAAC,YAAY,IAAI,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,aAAa,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;iBAC/G;aACF,CAAC,CAAA;QACJ,CAAC;QACD,UAAU,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK;QAC9B,gBAAgB,EAAE,aAAa;KAChC,CAAC,CAAA;IACF,MAAM,KAAK,GAAG,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QACrC,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QAC3C,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE,CACb,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE;YAClB,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;gBAAE,OAAO,UAAU,CAAC,uBAAuB,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC,CAAA;YAChG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;YACrB,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;YAC7B,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;QAC9B,CAAC,CAAC;QACJ,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAChB,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;YACf,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;YACxB,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;QAC/B,CAAC,CAAC;QACJ,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,CACZ,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE;YAClB,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;YAC9B,OAAO,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;QACnG,CAAC,CAAC;QACJ,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CACZ,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;YACf,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YACpB,KAAK,MAAM,IAAI,IAAI,KAAK;gBAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAC/C,CAAC,CAAC;KACL,CAAC,CAAA;IACF,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC1C,MAAM,KAAK,GAAG,KAAK,CAAC,QAAQ,CAC1B,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,aAAa,EAAE,aAAa,CAAC,EACzD,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,aAAa,EAAE,aAAa,CAAC,EACzD,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,EAAE,KAAK,CAAC,EAC3C,KAAK,CAAC,OAAO,CAAC,aAAa,EAAE;QAC3B,UAAU,EAAE,OAAO;QACnB,QAAQ,EAAE,EAAE;QACZ,SAAS;QACT,MAAM,EAAE;YACN,mBAAmB,EAAE,CAAC;YACtB,iBAAiB,EAAE,IAAI;YACvB,QAAQ,EAAE,EAAE;YACZ,kBAAkB,EAAE,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,aAAa,EAAE,aAAa,CAAC;YAC7E,kBAAkB,EAAE,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC,aAAa,EAAE,aAAa,CAAC;SAC9E;KACF,CAAC,CACH,CAAA;IACD,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAA;AAC/C,CAAC,CAAC,CAAA;AAEF,EAAE,CAAC,MAAM,CACP,iEAAiE,EACjE,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC;IACzB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;IAC/B,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;IACtF,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAA;IAC5C,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;IACjC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;AACpC,CAAC,CAAC,CACH,CAAA;AAED,EAAE,CAAC,MAAM,CACP,+EAA+E,EAC/E,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC;IACzB,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;IAC/B,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;IACtG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IACpC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAA;IAChD,MAAM,CACJ,IAAI,CACF,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,EACpB,KAAK,CAAC,YAAY,EAClB,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CACjC,CACF,CAAC,OAAO,CAAC,CAAC,aAAa,CAAC,CAAC,CAAA;IAC1B,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAA;IACrC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;QACxD,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,MAAM,CAAC,gBAAgB,CAAC,gEAAgE,CAAC;KACnG,CAAC,CAAA;AACJ,CAAC,CAAC,CACH,CAAA;AAED,EAAE,CAAC,MAAM,CACP,mEAAmE,EACnE,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC;IACzB,KAAK,MAAM,YAAY,IAAI,CAAC,iCAAiC,EAAE,eAAe,CAAC,EAAE,CAAC;QAChF,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC,CAAA;QAC7C,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;QAClH,MAAM,CAAC,KAAK,CAAC,CAAC,aAAa,CAAC;YAC1B,MAAM,EAAE,eAAe;YACvB,MAAM,EAAE,gBAAgB;YACxB,MAAM,EAAE,EAAE,IAAI,EAAE,uBAAuB,EAAE;SAC1C,CAAC,CAAA;QACF,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QAClC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAA;IACvD,CAAC;AACH,CAAC,CAAC,CACH,CAAA;AAED,EAAE,CAAC,MAAM,CACP,sFAAsF,EACtF,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC;IACzB,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC;QAClC,IAAI,EAAE,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC;QACvC,IAAI,EAAE,8BAA8B;KACrC,CAAC,CAAA;IACF,KAAK,MAAM,KAAK,IAAI;QAClB,CAAC,aAAa,EAAE,aAAa,CAAC;QAC9B,CAAC,aAAa,EAAE,UAAU,CAAC,IAAI,CAAC;KACjC,EAAE,CAAC;QACF,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC;YAC1B,UAAU;YACV,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC;gBAC3B,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,aAAa,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC;aAC7F,CAAC;SACH,CAAC,CAAA;QACF,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAA;QAClH,MAAM,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,UAAU,CAAC,uBAAuB,CAAC,CAAA;QAChE,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QAClC,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAA;IACnE,CAAC;AACH,CAAC,CAAC,CACH,CAAA;AAED,EAAE,CAAC,MAAM,CACP,2DAA2D,EAC3D,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC;IACzB,MAAM,eAAe,GAAG,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAA;IACrE,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC;QAC1B,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC;YAC3B,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,aAAa,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC;SAClF,CAAC;KACH,CAAC,CAAA;IACF,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;IACtG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAA;IACpC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAA;IAC7C,MAAM,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,eAAe,CAAC,CAAC,CAAA;AAC5D,CAAC,CAAC,CACH,CAAA;AAED,EAAE,CAAC,MAAM,CACP,6DAA6D,EAC7D,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC;IACzB,MAAM,MAAM,GAAG,CAAC,iCAAiC,EAAE,oBAAoB,CAAC,CAAA;IACxE,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,CAAA;IACrG,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,oBAAoB,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;IAC1G,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IAC9B,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;QACxD,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,MAAM,CAAC,gBAAgB,CAAC,yDAAyD,CAAC;KAC5F,CAAC,CAAA;IACF,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;AACpC,CAAC,CAAC,CACH,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=TraitEvaluation.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TraitEvaluation.test.d.ts","sourceRoot":"","sources":["../../test/TraitEvaluation.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,116 @@
1
+ import { expect, it } from "@effect/vitest";
2
+ import { Array, Effect, Layer, pipe, Record, Result, Semaphore, String } from "effect";
3
+ import { DecisionModel, LanguageModel } from "effect/ai";
4
+ import * as Source from "../Source.js";
5
+ import * as Trait from "../Trait.js";
6
+ import * as Evaluation from "../TraitEvaluation.js";
7
+ import { TraitsContext } from "../TraitsContext.js";
8
+ const source = Source.Source.make({ text: "const value = 1", location: Source.SourceLocation.cases.Generated.make({}) });
9
+ const traits = Array.makeBy(20, (index) => Trait.Trait.make({
10
+ name: Trait.TraitName.make(`example-trait-${index}`),
11
+ body: "Prefer const declarations.",
12
+ when: "declaring bindings.",
13
+ mime: "text/typescript",
14
+ skip: "When mutation is required."
15
+ }));
16
+ const run = Effect.fnUntraced(function* (selected, input = source, omitAnswers = false) {
17
+ const calls = [];
18
+ const model = yield* DecisionModel.make({
19
+ decide: (options) => Effect.sync(() => {
20
+ calls.push(options);
21
+ return {
22
+ answers: omitAnswers
23
+ ? {}
24
+ : Record.fromEntries(Array.map(Array.reverse(Record.keys(options.decisions)), (name) => [
25
+ name,
26
+ {
27
+ _tag: "Classify",
28
+ label: name === selected[0]?.name ? "violation" : "compliant",
29
+ probabilities: {
30
+ compliant: name === selected[0]?.name ? 0 : 1,
31
+ violation: name === selected[0]?.name ? 1 : 0,
32
+ "not-applicable": 0,
33
+ inconclusive: 0
34
+ }
35
+ }
36
+ ])),
37
+ usage: { inputTokens: undefined, outputTokens: undefined }
38
+ };
39
+ })
40
+ });
41
+ const semaphore = yield* Semaphore.make(1);
42
+ const result = yield* Evaluation.evaluateAll(selected, input).pipe(Effect.provideService(DecisionModel.DecisionModel, model), Effect.provideService(TraitsContext, {
43
+ configRoot: ".",
44
+ excludes: [],
45
+ semaphore,
46
+ config: {
47
+ decisionConcurrency: 1,
48
+ excludeGitignored: true,
49
+ excludes: [],
50
+ layerDecisionModel: Layer.succeed(DecisionModel.DecisionModel, model),
51
+ layerLanguageModel: Layer.effect(LanguageModel.LanguageModel, Effect.die("Generation is not used in evaluation tests"))
52
+ }
53
+ }), Effect.result);
54
+ return { calls, result };
55
+ });
56
+ it.effect("shares source once and maps name-keyed answers back to each trait in order", Effect.fnUntraced(function* () {
57
+ const selected = Array.take(traits, 3);
58
+ const { calls, result } = yield* run(selected);
59
+ expect(calls).toHaveLength(1);
60
+ expect(calls[0]?.state).toEqual({ source });
61
+ expect(Record.keys(calls[0].decisions)).toEqual(Array.map(selected, (trait) => trait.name));
62
+ expect(calls[0].decisions[selected[0].name]?.instructions).toContain(JSON.stringify(selected[0]));
63
+ expect(Result.isSuccess(result)).toBe(true);
64
+ if (Result.isSuccess(result)) {
65
+ expect(Array.map(result.success, (entry) => entry.trait)).toEqual(selected);
66
+ expect(Array.map(result.success, (entry) => entry.source)).toEqual([source, source, source]);
67
+ expect(Array.map(result.success, (entry) => entry.assessment.classification)).toEqual([
68
+ "violation",
69
+ "compliant",
70
+ "compliant"
71
+ ]);
72
+ expect(Array.filter(result.success, Evaluation.requiresReview)).toHaveLength(1);
73
+ }
74
+ }));
75
+ it.effect("splits question counts and preserves all results", Effect.fnUntraced(function* () {
76
+ const { calls, result } = yield* run(traits);
77
+ expect(calls).toHaveLength(2);
78
+ expect(Record.keys(calls[0].decisions).length).toBeLessThanOrEqual(16);
79
+ expect(Record.keys(calls[1].decisions).length).toBeLessThanOrEqual(16);
80
+ expect(Result.isSuccess(result)).toBe(true);
81
+ if (Result.isSuccess(result))
82
+ expect(Array.map(result.success, (entry) => entry.trait)).toEqual(traits);
83
+ }));
84
+ it.effect("splits UTF-8 request sizes without truncating trait text", Effect.fnUntraced(function* () {
85
+ const selected = Array.map(Array.take(traits, 6), (trait) => Trait.Trait.make({ ...trait, body: pipe("語", String.repeat(2000)) }));
86
+ const { calls, result } = yield* run(selected);
87
+ expect(calls.length).toBeGreaterThan(1);
88
+ expect(Result.isSuccess(result)).toBe(true);
89
+ for (const call of calls) {
90
+ expect(new TextEncoder().encode(JSON.stringify(call)).length).toBeLessThan(25_000);
91
+ }
92
+ if (Result.isSuccess(result))
93
+ expect(Array.map(result.success, (entry) => entry.trait)).toEqual(selected);
94
+ }));
95
+ it.effect("does not call the provider for empty selections", Effect.fnUntraced(function* () {
96
+ const { calls, result } = yield* run([]);
97
+ expect(calls).toEqual([]);
98
+ expect(result).toEqual(Result.succeed([]));
99
+ }));
100
+ it.effect("fails oversized inputs before sending any batch", Effect.fnUntraced(function* () {
101
+ const { calls, result } = yield* run(traits, Source.Source.make({ ...source, text: pipe("x", String.repeat(24_000)) }));
102
+ expect(calls).toEqual([]);
103
+ expect(Result.isFailure(result)).toBe(true);
104
+ if (Result.isFailure(result)) {
105
+ expect(result.failure).toBeInstanceOf(Evaluation.TraitAssessmentTooLargeError);
106
+ expect(result.failure).toMatchObject({ traitName: traits[0].name, maxBytes: 24_000, location: source.location });
107
+ if (result.failure._tag === "TraitAssessmentTooLargeError") {
108
+ expect(result.failure.bytes).toBeGreaterThan(result.failure.maxBytes);
109
+ }
110
+ }
111
+ }));
112
+ it.effect("fails incomplete provider answers instead of silently skipping traits", Effect.fnUntraced(function* () {
113
+ const { result } = yield* run(Array.take(traits, 2), source, true);
114
+ expect(Result.isFailure(result)).toBe(true);
115
+ }));
116
+ //# sourceMappingURL=TraitEvaluation.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TraitEvaluation.test.js","sourceRoot":"","sources":["../../test/TraitEvaluation.test.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,14 @@
1
+ import { pipe } from "effect";
1
2
  import { expect, it } from "vite-plus/test";
2
- import { traitIgnores } from "../traitIgnores.js";
3
+ import * as Trait from "../Trait.js";
4
+ import { excludeIgnored, traitIgnores } from "../traitIgnores.js";
5
+ const first = Trait.Trait.make({ name: Trait.TraitName.make("direct-callbacks"), body: "Pass callbacks directly." });
6
+ const second = Trait.Trait.make({ name: Trait.TraitName.make("use-arrow-functions"), body: "Use arrow functions." });
3
7
  it("reads repeated directives from the leading header", () => {
4
- const ids = traitIgnores("#!/usr/bin/env node\n\n// header\n// traits-ignore-file first: reason\n// traits-ignore-file second: another reason\nimport 'module'");
5
- expect([...ids]).toEqual(["first", "second"]);
8
+ const references = traitIgnores("#!/usr/bin/env node\n\n// header\n// traits-ignore-file first: reason\n// traits-ignore-file second: another reason\nimport 'module'");
9
+ expect([...references]).toEqual(["first", "second"]);
6
10
  });
7
- it("requires a reason and exactly one ID", () => {
11
+ it("requires a reason and exactly one reference", () => {
8
12
  expect([
9
13
  ...traitIgnores("// traits-ignore-file first\n// traits-ignore-file second: \n// traits-ignore-file first second: reason")
10
14
  ]).toEqual([]);
@@ -14,7 +18,27 @@ it("does not interpret strings or comments after code", () => {
14
18
  ...traitIgnores("const text = `\n// traits-ignore-file first: reason\n`\n// traits-ignore-file second: reason")
15
19
  ]).toEqual([]);
16
20
  });
17
- it("handles CRLF and deduplicates IDs", () => {
21
+ it("handles CRLF and deduplicates references", () => {
18
22
  expect([...traitIgnores("// traits-ignore-file first: reason\r\n// traits-ignore-file first: repeated\r\n")]).toEqual(["first"]);
19
23
  });
24
+ it("selects exact unique names and supports multiple exceptions", () => {
25
+ expect(pipe([first, second], excludeIgnored(`// traits-ignore-file ${first.name}: exception`))).toEqual([second]);
26
+ const header = `// traits-ignore-file ${first.name}: first exception\n// traits-ignore-file ${second.name}: second exception\nconst value = 1`;
27
+ expect(pipe([first, second], excludeIgnored(header))).toEqual([]);
28
+ });
29
+ it("does not match partial names, different casing, filenames, or unknown references", () => {
30
+ const header = `// traits-ignore-file direct: partial\n// traits-ignore-file Direct-callbacks: wrong casing\n// traits-ignore-file ${first.name}.md: filename\n// traits-ignore-file unknown-trait: unknown`;
31
+ expect(pipe([first, second], excludeIgnored(header))).toEqual([first, second]);
32
+ });
33
+ it("requires references to be updated after renaming", () => {
34
+ const renamed = Trait.Trait.make({ ...first, name: Trait.TraitName.make("renamed-callbacks") });
35
+ expect(pipe([renamed], excludeIgnored(`// traits-ignore-file ${first.name}: old name`))).toEqual([renamed]);
36
+ expect(pipe([renamed], excludeIgnored(`// traits-ignore-file ${renamed.name}: new name`))).toEqual([]);
37
+ });
38
+ it("does not apply directives without reasons or after code", () => {
39
+ expect(pipe([first], excludeIgnored(`// traits-ignore-file ${first.name}: `))).toEqual([first]);
40
+ expect(pipe([first], excludeIgnored(`const value = 1\n// traits-ignore-file ${first.name}: too late`))).toEqual([
41
+ first
42
+ ]);
43
+ });
20
44
  //# sourceMappingURL=TraitIgnores.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TraitIgnores.test.js","sourceRoot":"","sources":["../../test/TraitIgnores.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,gBAAgB,CAAA;AAE3C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEjD,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;IAC3D,MAAM,GAAG,GAAG,YAAY,CACtB,sIAAsI,CACvI,CAAA;IACD,MAAM,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAA;AAC/C,CAAC,CAAC,CAAA;AAEF,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;IAC9C,MAAM,CAAC;QACL,GAAG,YAAY,CACb,2GAA2G,CAC5G;KACF,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;AAChB,CAAC,CAAC,CAAA;AAEF,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;IAC3D,MAAM,CAAC;QACL,GAAG,YAAY,CAAC,8FAA8F,CAAC;KAChH,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;AAChB,CAAC,CAAC,CAAA;AAEF,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;IAC3C,MAAM,CAAC,CAAC,GAAG,YAAY,CAAC,kFAAkF,CAAC,CAAC,CAAC,CAAC,OAAO,CACnH,CAAC,OAAO,CAAC,CACV,CAAA;AACH,CAAC,CAAC,CAAA"}
1
+ {"version":3,"file":"TraitIgnores.test.js","sourceRoot":"","sources":["../../test/TraitIgnores.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=TraitStore.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TraitStore.test.d.ts","sourceRoot":"","sources":["../../test/TraitStore.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,120 @@
1
+ import { NodeServices } from "@effect/platform-node";
2
+ import { expect, it } from "@effect/vitest";
3
+ import { Effect, FileSystem, Path, Result } from "effect";
4
+ import * as Trait from "../Trait.js";
5
+ import * as TraitStore from "../TraitStore.js";
6
+ it.effect("reports migration guidance without changing an unparseable stored trait", Effect.fn("test.TraitStore.parseError")(function* () {
7
+ const fs = yield* FileSystem.FileSystem;
8
+ const path = yield* Path.Path;
9
+ const dir = yield* fs.makeTempDirectoryScoped({ prefix: "traits-parse-" });
10
+ const trait = Trait.Trait.make({ name: Trait.TraitName.make("old-format"), body: "Preserve this rule." });
11
+ const file = path.join(dir, "old-format.md");
12
+ const original = "---\nname: [\n---\nPreserve this rule.";
13
+ yield* fs.writeFileString(file, original);
14
+ yield* Effect.gen(function* () {
15
+ const store = yield* TraitStore.TraitStore;
16
+ for (const operation of [store.get(trait.name), store.update(trait), store.rm([trait.name])]) {
17
+ const result = yield* operation.pipe(Effect.result);
18
+ expect(Result.isFailure(result)).toBe(true);
19
+ if (Result.isFailure(result)) {
20
+ expect(result.failure).toMatchObject({
21
+ _tag: "TraitParseError",
22
+ path: file,
23
+ cause: { _tag: "InvalidYamlError" },
24
+ message: expect.stringContaining("Update all stored traits")
25
+ });
26
+ }
27
+ }
28
+ const text = yield* fs.readFileString(file);
29
+ expect(text).toBe(original);
30
+ }).pipe(Effect.provide(TraitStore.layerFileSystem(dir)));
31
+ }, Effect.provide(NodeServices.layer)));
32
+ it.effect("stores complete traits by unique name without overwriting duplicates", Effect.fn("test.TraitStore")(function* () {
33
+ const fs = yield* FileSystem.FileSystem;
34
+ const path = yield* Path.Path;
35
+ const dir = yield* fs.makeTempDirectoryScoped({ prefix: "traits-names-" });
36
+ const initial = Trait.Trait.make({
37
+ name: Trait.TraitName.make("test-trait"),
38
+ body: "Original",
39
+ when: "testing asynchronous operations.",
40
+ mime: ["text/typescript", "text/tsx"],
41
+ skip: "When a synchronous framework contract must be preserved.",
42
+ priority: 2
43
+ });
44
+ yield* Effect.gen(function* () {
45
+ const store = yield* TraitStore.TraitStore;
46
+ const added = yield* store.add(initial);
47
+ expect(added).toEqual(initial);
48
+ const loaded = yield* store.get(initial.name);
49
+ expect(loaded).toEqual(initial);
50
+ const updated = Trait.Trait.make({ ...initial, body: "Replacement", priority: 3 });
51
+ yield* store.update(updated);
52
+ const reloaded = yield* store.get(initial.name);
53
+ expect(reloaded).toEqual(updated);
54
+ const listed = yield* store.ls;
55
+ expect(listed).toEqual([updated]);
56
+ const file = path.join(dir, `${initial.name}.md`);
57
+ const text = yield* fs.readFileString(file);
58
+ expect(text).toContain(`name: ${initial.name}`);
59
+ expect(text).not.toContain("id:");
60
+ const files = yield* fs.readDirectory(dir);
61
+ expect(files).toEqual([`${initial.name}.md`]);
62
+ const collision = yield* store.add(initial).pipe(Effect.result);
63
+ expect(Result.isFailure(collision)).toBe(true);
64
+ if (Result.isFailure(collision)) {
65
+ expect(collision.failure).toBeInstanceOf(TraitStore.TraitAlreadyExistsError);
66
+ expect(collision.failure).toMatchObject({ name: initial.name });
67
+ }
68
+ const afterCollision = yield* store.get(initial.name);
69
+ expect(afterCollision).toEqual(updated);
70
+ const renamed = Trait.Trait.make({ ...updated, name: Trait.TraitName.make("renamed-trait") });
71
+ const missingUpdate = yield* store.update(renamed).pipe(Effect.result);
72
+ expect(Result.isFailure(missingUpdate)).toBe(true);
73
+ if (Result.isFailure(missingUpdate))
74
+ expect(missingUpdate.failure).toBeInstanceOf(TraitStore.TraitNotFoundError);
75
+ yield* store.add(renamed);
76
+ yield* store.rm([initial.name]);
77
+ const afterRename = yield* store.ls;
78
+ expect(afterRename).toEqual([renamed]);
79
+ const missing = yield* store.get(initial.name).pipe(Effect.result);
80
+ expect(Result.isFailure(missing)).toBe(true);
81
+ if (Result.isFailure(missing))
82
+ expect(missing.failure).toMatchObject({ _tag: "TraitNotFoundError", name: initial.name });
83
+ yield* store.rm([renamed.name]);
84
+ const remaining = yield* store.ls;
85
+ expect(remaining).toEqual([]);
86
+ }).pipe(Effect.provide(TraitStore.layerFileSystem(dir)));
87
+ }, Effect.provide(NodeServices.layer)));
88
+ it.effect("rejects mismatched filenames on reads, updates, removals, and listing", Effect.fn("test.TraitStore.nameMismatch")(function* () {
89
+ const fs = yield* FileSystem.FileSystem;
90
+ const path = yield* Path.Path;
91
+ const dir = yield* fs.makeTempDirectoryScoped({ prefix: "traits-mismatch-" });
92
+ const actual = Trait.Trait.make({ name: Trait.TraitName.make("actual-name"), body: "Body" });
93
+ const wrongName = Trait.TraitName.make("wrong-name");
94
+ const file = path.join(dir, `${wrongName}.md`);
95
+ yield* fs.writeFileString(file, Trait.serialize(actual));
96
+ yield* Effect.gen(function* () {
97
+ const store = yield* TraitStore.TraitStore;
98
+ for (const operation of [
99
+ store.get(wrongName),
100
+ store.update(Trait.Trait.make({ ...actual, name: wrongName })),
101
+ store.rm([wrongName]),
102
+ store.ls
103
+ ]) {
104
+ const result = yield* operation.pipe(Effect.result);
105
+ expect(Result.isFailure(result)).toBe(true);
106
+ if (Result.isFailure(result))
107
+ expect(result.failure).toMatchObject({
108
+ _tag: "TraitFilenameMismatchError",
109
+ path: file,
110
+ expectedFilename: `${actual.name}.md`
111
+ });
112
+ }
113
+ const text = yield* fs.readFileString(file);
114
+ expect(text).toBe(Trait.serialize(actual));
115
+ yield* store.add(actual);
116
+ const loaded = yield* store.get(actual.name);
117
+ expect(loaded).toEqual(actual);
118
+ }).pipe(Effect.provide(TraitStore.layerFileSystem(dir)));
119
+ }, Effect.provide(NodeServices.layer)));
120
+ //# sourceMappingURL=TraitStore.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TraitStore.test.js","sourceRoot":"","sources":["../../test/TraitStore.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=TraitsInitialization.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TraitsInitialization.test.d.ts","sourceRoot":"","sources":["../../test/TraitsInitialization.test.ts"],"names":[],"mappings":""}