sqlew 4.1.2 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (197) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +25 -165
  3. package/assets/claude-md-snippets/plan-mode-integration.md +48 -24
  4. package/assets/sample-skills/sqlew-decision-format/SKILL.md +73 -0
  5. package/dist/cli/hooks/check-completion.d.ts.map +1 -1
  6. package/dist/cli/hooks/check-completion.js +90 -2
  7. package/dist/cli/hooks/check-completion.js.map +1 -1
  8. package/dist/cli/hooks/init-hooks.d.ts.map +1 -1
  9. package/dist/cli/hooks/init-hooks.js +97 -5
  10. package/dist/cli/hooks/init-hooks.js.map +1 -1
  11. package/dist/cli/hooks/on-enter-plan.d.ts +22 -0
  12. package/dist/cli/hooks/on-enter-plan.d.ts.map +1 -0
  13. package/dist/cli/hooks/on-enter-plan.js +51 -0
  14. package/dist/cli/hooks/on-enter-plan.js.map +1 -0
  15. package/dist/cli/hooks/on-exit-plan.d.ts +20 -0
  16. package/dist/cli/hooks/on-exit-plan.d.ts.map +1 -0
  17. package/dist/cli/hooks/on-exit-plan.js +66 -0
  18. package/dist/cli/hooks/on-exit-plan.js.map +1 -0
  19. package/dist/cli/hooks/on-stop.d.ts +19 -0
  20. package/dist/cli/hooks/on-stop.d.ts.map +1 -0
  21. package/dist/cli/hooks/on-stop.js +152 -0
  22. package/dist/cli/hooks/on-stop.js.map +1 -0
  23. package/dist/cli/hooks/on-subagent-stop.d.ts +20 -0
  24. package/dist/cli/hooks/on-subagent-stop.d.ts.map +1 -0
  25. package/dist/cli/hooks/on-subagent-stop.js +94 -0
  26. package/dist/cli/hooks/on-subagent-stop.js.map +1 -0
  27. package/dist/cli/hooks/plan-pattern-extractor.d.ts +87 -0
  28. package/dist/cli/hooks/plan-pattern-extractor.d.ts.map +1 -0
  29. package/dist/cli/hooks/plan-pattern-extractor.js +218 -0
  30. package/dist/cli/hooks/plan-pattern-extractor.js.map +1 -0
  31. package/dist/cli/hooks/plan-processor.d.ts +43 -0
  32. package/dist/cli/hooks/plan-processor.d.ts.map +1 -0
  33. package/dist/cli/hooks/plan-processor.js +115 -0
  34. package/dist/cli/hooks/plan-processor.js.map +1 -0
  35. package/dist/cli/hooks/plan-toml-parser.d.ts +42 -0
  36. package/dist/cli/hooks/plan-toml-parser.d.ts.map +1 -0
  37. package/dist/cli/hooks/plan-toml-parser.js +178 -0
  38. package/dist/cli/hooks/plan-toml-parser.js.map +1 -0
  39. package/dist/cli/hooks/save.d.ts +7 -9
  40. package/dist/cli/hooks/save.d.ts.map +1 -1
  41. package/dist/cli/hooks/save.js +50 -25
  42. package/dist/cli/hooks/save.js.map +1 -1
  43. package/dist/cli/hooks/stdin-parser.d.ts +66 -2
  44. package/dist/cli/hooks/stdin-parser.d.ts.map +1 -1
  45. package/dist/cli/hooks/stdin-parser.js +57 -2
  46. package/dist/cli/hooks/stdin-parser.js.map +1 -1
  47. package/dist/cli/hooks/suggest.d.ts +8 -4
  48. package/dist/cli/hooks/suggest.d.ts.map +1 -1
  49. package/dist/cli/hooks/suggest.js +21 -123
  50. package/dist/cli/hooks/suggest.js.map +1 -1
  51. package/dist/cli/hooks/track-plan.d.ts +8 -1
  52. package/dist/cli/hooks/track-plan.d.ts.map +1 -1
  53. package/dist/cli/hooks/track-plan.js +64 -66
  54. package/dist/cli/hooks/track-plan.js.map +1 -1
  55. package/dist/cli.d.ts.map +1 -1
  56. package/dist/cli.js +139 -38
  57. package/dist/cli.js.map +1 -1
  58. package/dist/config/global-config.d.ts +90 -0
  59. package/dist/config/global-config.d.ts.map +1 -1
  60. package/dist/config/global-config.js +86 -1
  61. package/dist/config/global-config.js.map +1 -1
  62. package/dist/database/initialization/init.js +3 -3
  63. package/dist/database/initialization/init.js.map +1 -1
  64. package/dist/database/migrations/v4/20260102204000_v4_fix_decision_set_example.d.ts +15 -0
  65. package/dist/database/migrations/v4/20260102204000_v4_fix_decision_set_example.d.ts.map +1 -0
  66. package/dist/database/migrations/v4/20260102204000_v4_fix_decision_set_example.js +74 -0
  67. package/dist/database/migrations/v4/20260102204000_v4_fix_decision_set_example.js.map +1 -0
  68. package/dist/index.js +8 -4
  69. package/dist/index.js.map +1 -1
  70. package/dist/init-skills.d.ts +6 -1
  71. package/dist/init-skills.d.ts.map +1 -1
  72. package/dist/init-skills.js +50 -1
  73. package/dist/init-skills.js.map +1 -1
  74. package/dist/knexfile.d.ts.map +1 -1
  75. package/dist/knexfile.js +16 -12
  76. package/dist/knexfile.js.map +1 -1
  77. package/dist/server/setup.js +5 -5
  78. package/dist/server/setup.js.map +1 -1
  79. package/dist/server/tool-handlers.d.ts.map +1 -1
  80. package/dist/server/tool-handlers.js +7 -1
  81. package/dist/server/tool-handlers.js.map +1 -1
  82. package/dist/server/tool-registry.js +1 -1
  83. package/dist/server/tool-registry.js.map +1 -1
  84. package/dist/tests/feature/decision/truncate.test.d.ts +8 -0
  85. package/dist/tests/feature/decision/truncate.test.d.ts.map +1 -0
  86. package/dist/tests/feature/decision/truncate.test.js +192 -0
  87. package/dist/tests/feature/decision/truncate.test.js.map +1 -0
  88. package/dist/tests/unit/config/plan-toml-cache.test.d.ts +9 -0
  89. package/dist/tests/unit/config/plan-toml-cache.test.d.ts.map +1 -0
  90. package/dist/tests/unit/config/plan-toml-cache.test.js +230 -0
  91. package/dist/tests/unit/config/plan-toml-cache.test.js.map +1 -0
  92. package/dist/tests/unit/hooks/plan-toml-parser.test.d.ts +10 -0
  93. package/dist/tests/unit/hooks/plan-toml-parser.test.d.ts.map +1 -0
  94. package/dist/tests/unit/hooks/plan-toml-parser.test.js +316 -0
  95. package/dist/tests/unit/hooks/plan-toml-parser.test.js.map +1 -0
  96. package/dist/tools/constraints/actions/activate.d.ts +46 -0
  97. package/dist/tools/constraints/actions/activate.d.ts.map +1 -0
  98. package/dist/tools/constraints/actions/activate.js +105 -0
  99. package/dist/tools/constraints/actions/activate.js.map +1 -0
  100. package/dist/tools/constraints/actions/add.d.ts.map +1 -1
  101. package/dist/tools/constraints/actions/add.js +30 -13
  102. package/dist/tools/constraints/actions/add.js.map +1 -1
  103. package/dist/tools/constraints/actions/deactivate.d.ts.map +1 -1
  104. package/dist/tools/constraints/actions/deactivate.js +7 -4
  105. package/dist/tools/constraints/actions/deactivate.js.map +1 -1
  106. package/dist/tools/constraints/actions/get.d.ts.map +1 -1
  107. package/dist/tools/constraints/actions/get.js +10 -7
  108. package/dist/tools/constraints/actions/get.js.map +1 -1
  109. package/dist/tools/constraints/actions/suggest-pending.d.ts +41 -0
  110. package/dist/tools/constraints/actions/suggest-pending.d.ts.map +1 -0
  111. package/dist/tools/constraints/actions/suggest-pending.js +71 -0
  112. package/dist/tools/constraints/actions/suggest-pending.js.map +1 -0
  113. package/dist/tools/constraints/help/example.d.ts.map +1 -1
  114. package/dist/tools/constraints/help/example.js +65 -1
  115. package/dist/tools/constraints/help/example.js.map +1 -1
  116. package/dist/tools/constraints/help/help.d.ts.map +1 -1
  117. package/dist/tools/constraints/help/help.js +10 -5
  118. package/dist/tools/constraints/help/help.js.map +1 -1
  119. package/dist/tools/constraints/index.d.ts +2 -0
  120. package/dist/tools/constraints/index.d.ts.map +1 -1
  121. package/dist/tools/constraints/index.js +2 -0
  122. package/dist/tools/constraints/index.js.map +1 -1
  123. package/dist/tools/context/actions/add-context.d.ts.map +1 -1
  124. package/dist/tools/context/actions/add-context.js +13 -6
  125. package/dist/tools/context/actions/add-context.js.map +1 -1
  126. package/dist/tools/context/actions/list-contexts.d.ts.map +1 -1
  127. package/dist/tools/context/actions/list-contexts.js +12 -7
  128. package/dist/tools/context/actions/list-contexts.js.map +1 -1
  129. package/dist/tools/context/actions/list.d.ts.map +1 -1
  130. package/dist/tools/context/actions/list.js +8 -0
  131. package/dist/tools/context/actions/list.js.map +1 -1
  132. package/dist/tools/context/actions/search-advanced.d.ts.map +1 -1
  133. package/dist/tools/context/actions/search-advanced.js +41 -27
  134. package/dist/tools/context/actions/search-advanced.js.map +1 -1
  135. package/dist/tools/context/actions/search-layer.d.ts.map +1 -1
  136. package/dist/tools/context/actions/search-layer.js +8 -0
  137. package/dist/tools/context/actions/search-layer.js.map +1 -1
  138. package/dist/tools/context/actions/search-tags.d.ts.map +1 -1
  139. package/dist/tools/context/actions/search-tags.js +8 -0
  140. package/dist/tools/context/actions/search-tags.js.map +1 -1
  141. package/dist/tools/files/actions/check-lock.d.ts.map +1 -1
  142. package/dist/tools/files/actions/check-lock.js +9 -3
  143. package/dist/tools/files/actions/check-lock.js.map +1 -1
  144. package/dist/tools/files/actions/get.d.ts.map +1 -1
  145. package/dist/tools/files/actions/get.js +18 -13
  146. package/dist/tools/files/actions/get.js.map +1 -1
  147. package/dist/tools/files/actions/record-batch.d.ts.map +1 -1
  148. package/dist/tools/files/actions/record-batch.js +11 -6
  149. package/dist/tools/files/actions/record-batch.js.map +1 -1
  150. package/dist/tools/files/actions/record.d.ts.map +1 -1
  151. package/dist/tools/files/actions/record.js +8 -2
  152. package/dist/tools/files/actions/record.js.map +1 -1
  153. package/dist/types/actions.d.ts +1 -1
  154. package/dist/types/actions.d.ts.map +1 -1
  155. package/dist/types.d.ts +9 -2
  156. package/dist/types.d.ts.map +1 -1
  157. package/dist/utils/action-specs/constraint-specs.d.ts +1 -1
  158. package/dist/utils/action-specs/constraint-specs.d.ts.map +1 -1
  159. package/dist/utils/action-specs/constraint-specs.js +22 -5
  160. package/dist/utils/action-specs/constraint-specs.js.map +1 -1
  161. package/dist/utils/action-specs/decision-specs.d.ts.map +1 -1
  162. package/dist/utils/action-specs/decision-specs.js +11 -10
  163. package/dist/utils/action-specs/decision-specs.js.map +1 -1
  164. package/dist/utils/action-specs/file-specs.js +4 -4
  165. package/dist/utils/action-specs/file-specs.js.map +1 -1
  166. package/dist/utils/hook-queue.d.ts +43 -3
  167. package/dist/utils/hook-queue.d.ts.map +1 -1
  168. package/dist/utils/hook-queue.js +326 -32
  169. package/dist/utils/hook-queue.js.map +1 -1
  170. package/dist/utils/param-normalizer.d.ts +52 -0
  171. package/dist/utils/param-normalizer.d.ts.map +1 -0
  172. package/dist/utils/param-normalizer.js +70 -0
  173. package/dist/utils/param-normalizer.js.map +1 -0
  174. package/dist/utils/parameter-validator.d.ts.map +1 -1
  175. package/dist/utils/parameter-validator.js +2 -0
  176. package/dist/utils/parameter-validator.js.map +1 -1
  177. package/dist/utils/text-truncate.d.ts +13 -0
  178. package/dist/utils/text-truncate.d.ts.map +1 -0
  179. package/dist/utils/text-truncate.js +18 -0
  180. package/dist/utils/text-truncate.js.map +1 -0
  181. package/dist/utils/validators.d.ts +1 -1
  182. package/dist/utils/validators.d.ts.map +1 -1
  183. package/dist/utils/validators.js +1 -1
  184. package/dist/utils/validators.js.map +1 -1
  185. package/dist/watcher/base-watcher.d.ts.map +1 -1
  186. package/dist/watcher/base-watcher.js +4 -3
  187. package/dist/watcher/base-watcher.js.map +1 -1
  188. package/dist/watcher/file-watcher.d.ts.map +1 -1
  189. package/dist/watcher/file-watcher.js +5 -1
  190. package/dist/watcher/file-watcher.js.map +1 -1
  191. package/dist/watcher/queue-watcher.d.ts +12 -1
  192. package/dist/watcher/queue-watcher.d.ts.map +1 -1
  193. package/dist/watcher/queue-watcher.js +92 -12
  194. package/dist/watcher/queue-watcher.js.map +1 -1
  195. package/docs/ADR_CONCEPTS.md +4 -0
  196. package/docs/HOOKS_GUIDE.md +1 -1
  197. package/package.json +1 -1
@@ -0,0 +1,192 @@
1
+ /**
2
+ * Value Truncation Feature Tests
3
+ *
4
+ * Tests for the value truncation feature in decision list/search actions.
5
+ * Default behavior: 30 chars with ellipsis; full_value=true returns complete text.
6
+ */
7
+ import { describe, it, before, after } from 'node:test';
8
+ import assert from 'node:assert';
9
+ import { mkdirSync } from 'node:fs';
10
+ import { getAdapter, initializeDatabase, closeDatabase } from '../../../database.js';
11
+ import { ProjectContext } from '../../../utils/project-context.js';
12
+ import { truncateValue } from '../../../utils/text-truncate.js';
13
+ // Action imports
14
+ import { setDecision } from '../../../tools/context/index.js';
15
+ import { getContext } from '../../../tools/context/actions/list.js';
16
+ import { searchByTags } from '../../../tools/context/actions/search-tags.js';
17
+ import { searchByLayer } from '../../../tools/context/actions/search-layer.js';
18
+ import { searchAdvanced } from '../../../tools/context/actions/search-advanced.js';
19
+ const TEST_DB_PATH = '.tmp-test/decision-truncate.db';
20
+ describe('Value Truncation', () => {
21
+ before(async () => {
22
+ // Ensure test directory exists
23
+ mkdirSync('.tmp-test', { recursive: true });
24
+ // Initialize database with SQLite using test-specific database
25
+ const adapter = await initializeDatabase({
26
+ databaseType: 'sqlite',
27
+ connection: { filename: TEST_DB_PATH }
28
+ });
29
+ // Set up project context (required after v3.7.0)
30
+ const knex = adapter.getKnex();
31
+ const projectContext = ProjectContext.getInstance();
32
+ await projectContext.ensureProject(knex, 'test-truncate', 'config', {
33
+ projectRootPath: process.cwd(),
34
+ });
35
+ });
36
+ after(async () => {
37
+ await closeDatabase();
38
+ });
39
+ describe('truncateValue utility', () => {
40
+ it('should return original value if shorter than maxLength', () => {
41
+ const result = truncateValue('short text', 30);
42
+ assert.strictEqual(result, 'short text');
43
+ });
44
+ it('should truncate and add ellipsis if longer than maxLength', () => {
45
+ const longText = 'This is a very long text that exceeds thirty characters';
46
+ const result = truncateValue(longText, 30);
47
+ // 30 chars: 'This is a very long text that ' (with trailing space)
48
+ assert.strictEqual(result, 'This is a very long text that …');
49
+ assert.strictEqual(result.length, 31); // 30 + 1 ellipsis
50
+ });
51
+ it('should handle empty string', () => {
52
+ const result = truncateValue('', 30);
53
+ assert.strictEqual(result, '');
54
+ });
55
+ it('should handle exactly maxLength chars', () => {
56
+ const exactText = 'a'.repeat(30);
57
+ const result = truncateValue(exactText, 30);
58
+ assert.strictEqual(result, exactText);
59
+ assert.strictEqual(result.length, 30);
60
+ });
61
+ });
62
+ describe('list action', () => {
63
+ it('should truncate values by default', async () => {
64
+ const longValue = 'This is a very long decision value that should be truncated to 30 characters';
65
+ const adapter = getAdapter();
66
+ await setDecision({
67
+ key: 'truncate/list-default',
68
+ value: longValue,
69
+ layer: 'business'
70
+ });
71
+ const result = await getContext({}, adapter);
72
+ const decision = result.decisions.find(d => d.key === 'truncate/list-default');
73
+ assert.ok(decision, 'Decision should exist');
74
+ assert.strictEqual(decision.value, 'This is a very long decision v…');
75
+ });
76
+ it('should return full value when full_value=true', async () => {
77
+ const longValue = 'This is a very long decision value that should NOT be truncated when full_value is true';
78
+ const adapter = getAdapter();
79
+ await setDecision({
80
+ key: 'truncate/list-full',
81
+ value: longValue,
82
+ layer: 'business'
83
+ });
84
+ const result = await getContext({ full_value: true }, adapter);
85
+ const decision = result.decisions.find(d => d.key === 'truncate/list-full');
86
+ assert.ok(decision, 'Decision should exist');
87
+ assert.strictEqual(decision.value, longValue);
88
+ });
89
+ it('should not add ellipsis for short values', async () => {
90
+ const shortValue = 'Short value';
91
+ const adapter = getAdapter();
92
+ await setDecision({
93
+ key: 'truncate/list-short',
94
+ value: shortValue,
95
+ layer: 'business'
96
+ });
97
+ const result = await getContext({}, adapter);
98
+ const decision = result.decisions.find(d => d.key === 'truncate/list-short');
99
+ assert.ok(decision, 'Decision should exist');
100
+ assert.strictEqual(decision.value, shortValue);
101
+ });
102
+ });
103
+ describe('search_tags action', () => {
104
+ it('should truncate values by default', async () => {
105
+ const longValue = 'This is another very long decision value for tag search testing purpose';
106
+ const adapter = getAdapter();
107
+ await setDecision({
108
+ key: 'truncate/tags-default',
109
+ value: longValue,
110
+ layer: 'business',
111
+ tags: ['truncate-test']
112
+ });
113
+ const result = await searchByTags({ tags: ['truncate-test'] }, adapter);
114
+ const decision = result.decisions.find(d => d.key === 'truncate/tags-default');
115
+ assert.ok(decision, 'Decision should exist');
116
+ assert.strictEqual(decision.value, 'This is another very long deci…');
117
+ });
118
+ it('should return full value when full_value=true', async () => {
119
+ const longValue = 'This is another very long decision value for tag search testing purpose';
120
+ const adapter = getAdapter();
121
+ await setDecision({
122
+ key: 'truncate/tags-full',
123
+ value: longValue,
124
+ layer: 'business',
125
+ tags: ['truncate-full-test']
126
+ });
127
+ const result = await searchByTags({ tags: ['truncate-full-test'], full_value: true }, adapter);
128
+ const decision = result.decisions.find(d => d.key === 'truncate/tags-full');
129
+ assert.ok(decision, 'Decision should exist');
130
+ assert.strictEqual(decision.value, longValue);
131
+ });
132
+ });
133
+ describe('search_layer action', () => {
134
+ it('should truncate values by default', async () => {
135
+ const longValue = 'Layer search test with a very long value that exceeds thirty characters limit';
136
+ const adapter = getAdapter();
137
+ await setDecision({
138
+ key: 'truncate/layer-default',
139
+ value: longValue,
140
+ layer: 'data'
141
+ });
142
+ const result = await searchByLayer({ layer: 'data' }, adapter);
143
+ const decision = result.decisions.find(d => d.key === 'truncate/layer-default');
144
+ assert.ok(decision, 'Decision should exist');
145
+ assert.strictEqual(decision.value, 'Layer search test with a very …');
146
+ });
147
+ it('should return full value when full_value=true', async () => {
148
+ const longValue = 'Layer search test with a very long value that exceeds thirty characters limit';
149
+ const adapter = getAdapter();
150
+ await setDecision({
151
+ key: 'truncate/layer-full',
152
+ value: longValue,
153
+ layer: 'infrastructure'
154
+ });
155
+ const result = await searchByLayer({ layer: 'infrastructure', full_value: true }, adapter);
156
+ const decision = result.decisions.find(d => d.key === 'truncate/layer-full');
157
+ assert.ok(decision, 'Decision should exist');
158
+ assert.strictEqual(decision.value, longValue);
159
+ });
160
+ });
161
+ describe('search_advanced action', () => {
162
+ it('should truncate values by default', async () => {
163
+ const longValue = 'Advanced search test with a very long value exceeding thirty characters limit here';
164
+ const adapter = getAdapter();
165
+ await setDecision({
166
+ key: 'truncate/advanced-default',
167
+ value: longValue,
168
+ layer: 'cross-cutting',
169
+ tags: ['advanced-truncate']
170
+ });
171
+ const result = await searchAdvanced({ tags_any: ['advanced-truncate'] }, adapter);
172
+ const decision = result.decisions.find(d => d.key === 'truncate/advanced-default');
173
+ assert.ok(decision, 'Decision should exist');
174
+ assert.strictEqual(decision.value, 'Advanced search test with a ve…');
175
+ });
176
+ it('should return full value when full_value=true', async () => {
177
+ const longValue = 'Advanced search test with a very long value exceeding thirty characters limit here';
178
+ const adapter = getAdapter();
179
+ await setDecision({
180
+ key: 'truncate/advanced-full',
181
+ value: longValue,
182
+ layer: 'presentation',
183
+ tags: ['advanced-full-truncate']
184
+ });
185
+ const result = await searchAdvanced({ tags_any: ['advanced-full-truncate'], full_value: true }, adapter);
186
+ const decision = result.decisions.find(d => d.key === 'truncate/advanced-full');
187
+ assert.ok(decision, 'Decision should exist');
188
+ assert.strictEqual(decision.value, longValue);
189
+ });
190
+ });
191
+ });
192
+ //# sourceMappingURL=truncate.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"truncate.test.js","sourceRoot":"","sources":["../../../../src/tests/feature/decision/truncate.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Plan TOML Cache Unit Tests
3
+ *
4
+ * Tests for cache CRUD operations for plan TOML data.
5
+ *
6
+ * @since v4.2.0
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=plan-toml-cache.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-toml-cache.test.d.ts","sourceRoot":"","sources":["../../../../src/tests/unit/config/plan-toml-cache.test.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,230 @@
1
+ /**
2
+ * Plan TOML Cache Unit Tests
3
+ *
4
+ * Tests for cache CRUD operations for plan TOML data.
5
+ *
6
+ * @since v4.2.0
7
+ */
8
+ import { describe, it, beforeEach, afterEach } from 'node:test';
9
+ import assert from 'node:assert';
10
+ import { existsSync, mkdirSync, rmSync, readFileSync } from 'fs';
11
+ import { join } from 'path';
12
+ import { tmpdir } from 'os';
13
+ import { getPlanTomlCachePath, loadPlanTomlCache, savePlanTomlCache, clearPlanTomlCache, } from '../../../config/global-config.js';
14
+ describe('plan-toml-cache', () => {
15
+ // Use a unique temp directory for each test
16
+ let testProjectPath;
17
+ beforeEach(() => {
18
+ // Create unique test directory
19
+ testProjectPath = join(tmpdir(), `sqlew-test-${Date.now()}-${Math.random().toString(36).slice(2)}`);
20
+ mkdirSync(testProjectPath, { recursive: true });
21
+ });
22
+ afterEach(() => {
23
+ // Cleanup test directory
24
+ if (existsSync(testProjectPath)) {
25
+ rmSync(testProjectPath, { recursive: true, force: true });
26
+ }
27
+ });
28
+ describe('getPlanTomlCachePath', () => {
29
+ it('should return path ending with _plan-toml.json', () => {
30
+ const cachePath = getPlanTomlCachePath(testProjectPath);
31
+ assert.ok(cachePath.endsWith('_plan-toml.json'));
32
+ });
33
+ it('should return consistent path for same project', () => {
34
+ const path1 = getPlanTomlCachePath(testProjectPath);
35
+ const path2 = getPlanTomlCachePath(testProjectPath);
36
+ assert.strictEqual(path1, path2);
37
+ });
38
+ it('should return different paths for different projects', () => {
39
+ const path1 = getPlanTomlCachePath(testProjectPath);
40
+ const path2 = getPlanTomlCachePath(join(testProjectPath, 'subdir'));
41
+ assert.notStrictEqual(path1, path2);
42
+ });
43
+ });
44
+ describe('savePlanTomlCache / loadPlanTomlCache', () => {
45
+ it('should save and load cache correctly', () => {
46
+ const decisions = [
47
+ {
48
+ key: 'test/decision',
49
+ value: 'Test value',
50
+ status: 'active',
51
+ layer: 'business',
52
+ tags: ['test'],
53
+ },
54
+ ];
55
+ const constraints = [
56
+ {
57
+ text: 'Test constraint',
58
+ category: 'security',
59
+ priority: 'high',
60
+ },
61
+ ];
62
+ const cache = {
63
+ plan_id: 'test-plan-123',
64
+ decisions,
65
+ constraints,
66
+ updated_at: new Date().toISOString(),
67
+ decisions_registered: false,
68
+ constraints_prompted: false,
69
+ };
70
+ savePlanTomlCache(testProjectPath, cache);
71
+ const loaded = loadPlanTomlCache(testProjectPath);
72
+ assert.ok(loaded);
73
+ assert.strictEqual(loaded.plan_id, 'test-plan-123');
74
+ assert.strictEqual(loaded.decisions.length, 1);
75
+ assert.strictEqual(loaded.constraints.length, 1);
76
+ assert.strictEqual(loaded.decisions[0].key, 'test/decision');
77
+ assert.strictEqual(loaded.constraints[0].text, 'Test constraint');
78
+ });
79
+ it('should return null for non-existent cache', () => {
80
+ const loaded = loadPlanTomlCache(testProjectPath);
81
+ assert.strictEqual(loaded, null);
82
+ });
83
+ it('should preserve all decision fields', () => {
84
+ const decision = {
85
+ key: 'full/decision',
86
+ value: 'Complete decision',
87
+ status: 'draft',
88
+ layer: 'data',
89
+ tags: ['tag1', 'tag2'],
90
+ rationale: 'Because reasons',
91
+ alternatives: ['Alt 1', 'Alt 2'],
92
+ tradeoffs: 'Speed vs safety',
93
+ };
94
+ const cache = {
95
+ plan_id: 'full-test',
96
+ decisions: [decision],
97
+ constraints: [],
98
+ updated_at: new Date().toISOString(),
99
+ decisions_registered: true,
100
+ constraints_prompted: true,
101
+ };
102
+ savePlanTomlCache(testProjectPath, cache);
103
+ const loaded = loadPlanTomlCache(testProjectPath);
104
+ assert.ok(loaded);
105
+ const d = loaded.decisions[0];
106
+ assert.strictEqual(d.key, 'full/decision');
107
+ assert.strictEqual(d.value, 'Complete decision');
108
+ assert.strictEqual(d.status, 'draft');
109
+ assert.strictEqual(d.layer, 'data');
110
+ assert.deepStrictEqual(d.tags, ['tag1', 'tag2']);
111
+ assert.strictEqual(d.rationale, 'Because reasons');
112
+ assert.deepStrictEqual(d.alternatives, ['Alt 1', 'Alt 2']);
113
+ assert.strictEqual(d.tradeoffs, 'Speed vs safety');
114
+ });
115
+ it('should preserve all constraint fields', () => {
116
+ const constraint = {
117
+ text: 'Full constraint',
118
+ category: 'performance',
119
+ priority: 'critical',
120
+ layer: 'infrastructure',
121
+ tags: ['perf', 'critical'],
122
+ rationale: 'Performance matters',
123
+ };
124
+ const cache = {
125
+ plan_id: 'constraint-test',
126
+ decisions: [],
127
+ constraints: [constraint],
128
+ updated_at: new Date().toISOString(),
129
+ decisions_registered: false,
130
+ constraints_prompted: false,
131
+ };
132
+ savePlanTomlCache(testProjectPath, cache);
133
+ const loaded = loadPlanTomlCache(testProjectPath);
134
+ assert.ok(loaded);
135
+ const c = loaded.constraints[0];
136
+ assert.strictEqual(c.text, 'Full constraint');
137
+ assert.strictEqual(c.category, 'performance');
138
+ assert.strictEqual(c.priority, 'critical');
139
+ assert.strictEqual(c.layer, 'infrastructure');
140
+ assert.deepStrictEqual(c.tags, ['perf', 'critical']);
141
+ assert.strictEqual(c.rationale, 'Performance matters');
142
+ });
143
+ it('should update existing cache on save', () => {
144
+ const cache1 = {
145
+ plan_id: 'plan-1',
146
+ decisions: [{ key: 'first', value: 'First' }],
147
+ constraints: [],
148
+ updated_at: new Date().toISOString(),
149
+ decisions_registered: false,
150
+ constraints_prompted: false,
151
+ };
152
+ const cache2 = {
153
+ plan_id: 'plan-2',
154
+ decisions: [{ key: 'second', value: 'Second' }],
155
+ constraints: [],
156
+ updated_at: new Date().toISOString(),
157
+ decisions_registered: true,
158
+ constraints_prompted: true,
159
+ };
160
+ savePlanTomlCache(testProjectPath, cache1);
161
+ savePlanTomlCache(testProjectPath, cache2);
162
+ const loaded = loadPlanTomlCache(testProjectPath);
163
+ assert.ok(loaded);
164
+ assert.strictEqual(loaded.plan_id, 'plan-2');
165
+ assert.strictEqual(loaded.decisions[0].key, 'second');
166
+ assert.strictEqual(loaded.decisions_registered, true);
167
+ });
168
+ });
169
+ describe('clearPlanTomlCache', () => {
170
+ it('should clear cache by writing empty arrays', () => {
171
+ const cache = {
172
+ plan_id: 'to-clear',
173
+ decisions: [{ key: 'test', value: 'value' }],
174
+ constraints: [{ text: 'rule', category: 'security' }],
175
+ updated_at: new Date().toISOString(),
176
+ decisions_registered: true,
177
+ constraints_prompted: true,
178
+ };
179
+ savePlanTomlCache(testProjectPath, cache);
180
+ clearPlanTomlCache(testProjectPath);
181
+ const cachePath = getPlanTomlCachePath(testProjectPath);
182
+ const content = JSON.parse(readFileSync(cachePath, 'utf-8'));
183
+ assert.deepStrictEqual(content.decisions, []);
184
+ assert.deepStrictEqual(content.constraints, []);
185
+ });
186
+ it('should not throw for non-existent cache', () => {
187
+ // Should not throw
188
+ clearPlanTomlCache(testProjectPath);
189
+ });
190
+ });
191
+ describe('flag management', () => {
192
+ it('should track decisions_registered flag', () => {
193
+ const cache = {
194
+ plan_id: 'flag-test',
195
+ decisions: [{ key: 'test', value: 'value' }],
196
+ constraints: [],
197
+ updated_at: new Date().toISOString(),
198
+ decisions_registered: false,
199
+ constraints_prompted: false,
200
+ };
201
+ savePlanTomlCache(testProjectPath, cache);
202
+ let loaded = loadPlanTomlCache(testProjectPath);
203
+ assert.strictEqual(loaded?.decisions_registered, false);
204
+ // Update flag
205
+ cache.decisions_registered = true;
206
+ savePlanTomlCache(testProjectPath, cache);
207
+ loaded = loadPlanTomlCache(testProjectPath);
208
+ assert.strictEqual(loaded?.decisions_registered, true);
209
+ });
210
+ it('should track constraints_prompted flag', () => {
211
+ const cache = {
212
+ plan_id: 'flag-test',
213
+ decisions: [],
214
+ constraints: [{ text: 'rule', category: 'security' }],
215
+ updated_at: new Date().toISOString(),
216
+ decisions_registered: false,
217
+ constraints_prompted: false,
218
+ };
219
+ savePlanTomlCache(testProjectPath, cache);
220
+ let loaded = loadPlanTomlCache(testProjectPath);
221
+ assert.strictEqual(loaded?.constraints_prompted, false);
222
+ // Update flag
223
+ cache.constraints_prompted = true;
224
+ savePlanTomlCache(testProjectPath, cache);
225
+ loaded = loadPlanTomlCache(testProjectPath);
226
+ assert.strictEqual(loaded?.constraints_prompted, true);
227
+ });
228
+ });
229
+ });
230
+ //# sourceMappingURL=plan-toml-cache.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-toml-cache.test.js","sourceRoot":"","sources":["../../../../src/tests/unit/config/plan-toml-cache.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Plan TOML Parser Unit Tests
3
+ *
4
+ * Tests for extracting and parsing [[decision]] and [[constraint]]
5
+ * from ```toml blocks in plan markdown files.
6
+ *
7
+ * @since v4.2.0
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=plan-toml-parser.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan-toml-parser.test.d.ts","sourceRoot":"","sources":["../../../../src/tests/unit/hooks/plan-toml-parser.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}