sinapse-ai 1.9.0 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/rules/mandatory-delegation.md +1 -1
- package/.codex/delegation-matrix.json +4 -3
- package/.codex/delegation-parity.json +4 -3
- package/.codex/instructions.md +2 -2
- package/.sinapse-ai/constitution.md +2 -2
- package/.sinapse-ai/core/doctor/checks/git-hooks.js +76 -10
- package/.sinapse-ai/core/execution/subagent-dispatcher.js +1 -1
- package/.sinapse-ai/core/synapse/engine.js +15 -0
- package/.sinapse-ai/data/entity-registry.yaml +13 -13
- package/.sinapse-ai/development/agents/snps-orqx.md +4 -4
- package/.sinapse-ai/git-hooks/lib/secret-scanner-core.js +76 -4
- package/.sinapse-ai/git-hooks/pre-push +7 -1
- package/.sinapse-ai/install-manifest.yaml +9 -9
- package/AGENTS.md +4 -4
- package/CHANGELOG.md +1257 -0
- package/README.en.md +4 -3
- package/README.md +5 -6
- package/bin/commands/install.js +6 -3
- package/bin/commands/uninstall.js +2 -2
- package/bin/sinapse.js +20 -0
- package/bin/utils/secret-scanner-core.js +76 -4
- package/docs/agent-reference-guide.md +1 -1
- package/docs/framework/architecture-overview.md +4 -4
- package/docs/framework/guiding-principles.md +9 -9
- package/docs/getting-started.md +1 -1
- package/docs/guides/agent-reference.md +1 -1
- package/docs/guides/codex-config.md +4 -5
- package/docs/pt/architecture/sub-orqx-pattern.md +20 -18
- package/package.json +8 -2
- package/packages/installer/src/installer/git-hooks-installer.js +3 -1
- package/packages/installer/src/installer/sinapse-ai-installer.js +32 -7
- package/packages/installer/src/wizard/ide-config-generator.js +9 -1
- package/packages/installer/src/wizard/index.js +3 -4
- package/scripts/regenerate-orqx-stubs.ps1 +0 -1
- package/scripts/sync-counts.js +10 -2
- package/scripts/sync-squad-yaml-components.js +108 -6
- package/scripts/validate-article-vii.js +68 -7
- package/scripts/validate-squad-orqx.js +19 -9
- package/sinapse/agents/sinapse-orqx.md +4 -4
- package/sinapse/agents/snps-orqx.md +4 -4
- package/sinapse/knowledge-base/routing-catalog.md +1 -1
- package/sinapse/tasks/diagnose-and-route.md +1 -1
- package/sinapse/tasks/squad-status-report.md +1 -1
- package/squads/claude-code-mastery/agents/claude-mastery-chief.md +1 -1
- package/squads/claude-code-mastery/agents/hooks-architect.md +60 -68
- package/squads/claude-code-mastery/knowledge-base/swarm-orchestration-patterns.md +1 -1
- package/squads/claude-code-mastery/tasks/audit-setup.md +1 -1
- package/squads/claude-code-mastery/workflows/optimization-cycle.yaml +4 -4
- package/squads/claude-code-mastery/workflows/project-setup-cycle.yaml +4 -4
- package/squads/squad-animations/README.md +1 -1
- package/squads/squad-cloning/README.md +1 -1
- package/squads/squad-commercial/README.md +1 -1
- package/squads/squad-content/README.md +1 -1
- package/squads/squad-copy/README.md +1 -1
- package/squads/squad-council/README.md +1 -1
- package/squads/squad-courses/README.md +1 -1
- package/squads/squad-cybersecurity/README.md +1 -1
- package/squads/squad-design/README.md +1 -1
- package/squads/squad-finance/README.md +1 -1
- package/squads/squad-growth/README.md +1 -1
- package/squads/squad-paidmedia/README.md +1 -1
- package/squads/squad-product/README.md +1 -1
- package/squads/squad-research/README.md +1 -1
- package/squads/squad-storytelling/README.md +1 -1
- package/.sinapse-ai/core/memory/__tests__/active-modules.verify.js +0 -265
- package/.sinapse-ai/core/permissions/__tests__/permission-mode.test.js +0 -293
- package/.sinapse-ai/infrastructure/tests/project-status-loader.test.js +0 -569
- package/.sinapse-ai/infrastructure/tests/regression-suite-v2.md +0 -622
- package/.sinapse-ai/infrastructure/tests/validate-module.js +0 -98
- package/.sinapse-ai/infrastructure/tests/worktree-manager.test.js +0 -620
- package/.sinapse-ai/workflow-intelligence/__tests__/confidence-scorer.test.js +0 -335
- package/.sinapse-ai/workflow-intelligence/__tests__/integration.test.js +0 -340
- package/.sinapse-ai/workflow-intelligence/__tests__/suggestion-engine.test.js +0 -438
- package/.sinapse-ai/workflow-intelligence/__tests__/wave-analyzer.test.js +0 -448
- package/.sinapse-ai/workflow-intelligence/__tests__/workflow-registry.test.js +0 -303
- package/packages/installer/src/__tests__/performance-benchmark.js +0 -383
- package/packages/installer/tests/integration/environment-configuration.test.js +0 -332
- package/packages/installer/tests/integration/wizard-detection.test.js +0 -352
- package/packages/installer/tests/unit/artifact-copy-pipeline/artifact-copy-pipeline.test.js +0 -402
- package/packages/installer/tests/unit/claude-md-template-v5/claude-md-template-v5.test.js +0 -193
- package/packages/installer/tests/unit/config-validator.test.js +0 -315
- package/packages/installer/tests/unit/detection/detect-project-type.test.js +0 -539
- package/packages/installer/tests/unit/doctor/doctor-checks.test.js +0 -675
- package/packages/installer/tests/unit/doctor/doctor-orchestrator.test.js +0 -192
- package/packages/installer/tests/unit/entity-registry-bootstrap.test.js +0 -192
- package/packages/installer/tests/unit/env-template.test.js +0 -187
- package/packages/installer/tests/unit/generate-settings-json/generate-settings-json.test.js +0 -310
- package/packages/installer/tests/unit/git-hooks-installer.test.js +0 -262
- package/packages/installer/tests/unit/ide-sync-integration/ide-sync-integration.test.js +0 -231
- package/packages/installer/tests/unit/merger/env-merger.test.js +0 -191
- package/packages/installer/tests/unit/merger/markdown-merger.test.js +0 -262
- package/packages/installer/tests/unit/merger/strategies.test.js +0 -154
- package/packages/installer/tests/unit/merger/yaml-merger.test.js +0 -328
- package/packages/sinapse-install/tests/unit/chrome-brain.smoke.test.js +0 -66
|
@@ -1,315 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Unit Tests: Configuration Validator
|
|
3
|
-
* Story 1.6: Environment Configuration
|
|
4
|
-
*
|
|
5
|
-
* Tests for config-validator.js
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
const {
|
|
9
|
-
validateEnvFormat,
|
|
10
|
-
validateApiKeyFormat,
|
|
11
|
-
validateYamlSyntax,
|
|
12
|
-
validateCoreConfigStructure,
|
|
13
|
-
validatePath,
|
|
14
|
-
sanitizeInput,
|
|
15
|
-
} = require('../../src/config/validation/config-validator');
|
|
16
|
-
|
|
17
|
-
describe('Configuration Validator', () => {
|
|
18
|
-
describe('validateEnvFormat', () => {
|
|
19
|
-
it('should validate correct .env format', () => {
|
|
20
|
-
const content = `# Comment
|
|
21
|
-
NODE_ENV=development
|
|
22
|
-
API_KEY=sk-12345
|
|
23
|
-
DATABASE_URL=postgresql://localhost`;
|
|
24
|
-
|
|
25
|
-
const result = validateEnvFormat(content);
|
|
26
|
-
expect(result.valid).toBe(true);
|
|
27
|
-
expect(result.errors).toHaveLength(0);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it('should reject spaces around =', () => {
|
|
31
|
-
const content = 'NODE_ENV = development';
|
|
32
|
-
const result = validateEnvFormat(content);
|
|
33
|
-
|
|
34
|
-
expect(result.valid).toBe(false);
|
|
35
|
-
expect(result.errors.length).toBeGreaterThan(0);
|
|
36
|
-
expect(result.errors[0]).toContain('spaces around =');
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it('should reject invalid key names', () => {
|
|
40
|
-
const content = 'invalid-key=value';
|
|
41
|
-
const result = validateEnvFormat(content);
|
|
42
|
-
|
|
43
|
-
expect(result.valid).toBe(false);
|
|
44
|
-
expect(result.errors.length).toBeGreaterThan(0);
|
|
45
|
-
expect(result.errors[0]).toContain('Invalid format');
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it('should allow empty values', () => {
|
|
49
|
-
const content = 'API_KEY=';
|
|
50
|
-
const result = validateEnvFormat(content);
|
|
51
|
-
|
|
52
|
-
expect(result.valid).toBe(true);
|
|
53
|
-
expect(result.errors).toHaveLength(0);
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
it('should skip comments and empty lines', () => {
|
|
57
|
-
const content = `# Comment
|
|
58
|
-
|
|
59
|
-
NODE_ENV=development
|
|
60
|
-
# Another comment
|
|
61
|
-
`;
|
|
62
|
-
|
|
63
|
-
const result = validateEnvFormat(content);
|
|
64
|
-
expect(result.valid).toBe(true);
|
|
65
|
-
expect(result.errors).toHaveLength(0);
|
|
66
|
-
});
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
describe('validateApiKeyFormat', () => {
|
|
70
|
-
it('should allow empty keys (skip logic)', () => {
|
|
71
|
-
const result = validateApiKeyFormat('');
|
|
72
|
-
expect(result.valid).toBe(true);
|
|
73
|
-
expect(result.error).toBeNull();
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it('should reject whitespace-only keys', () => {
|
|
77
|
-
const result = validateApiKeyFormat(' ');
|
|
78
|
-
expect(result.valid).toBe(false);
|
|
79
|
-
expect(result.error).toContain('whitespace');
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
it('should validate OpenAI key format', () => {
|
|
83
|
-
const validKey = 'sk-1234567890abcdefghij';
|
|
84
|
-
const result = validateApiKeyFormat(validKey, 'openai');
|
|
85
|
-
|
|
86
|
-
expect(result.valid).toBe(true);
|
|
87
|
-
expect(result.error).toBeNull();
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
it('should reject invalid OpenAI key format', () => {
|
|
91
|
-
const invalidKey = 'invalid-key';
|
|
92
|
-
const result = validateApiKeyFormat(invalidKey, 'openai');
|
|
93
|
-
|
|
94
|
-
expect(result.valid).toBe(false);
|
|
95
|
-
expect(result.error).toContain('sk-');
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
it('should validate Anthropic key format', () => {
|
|
99
|
-
const validKey = 'sk-ant-1234567890abcdefghijklmnopqrstuv';
|
|
100
|
-
const result = validateApiKeyFormat(validKey, 'anthropic');
|
|
101
|
-
|
|
102
|
-
expect(result.valid).toBe(true);
|
|
103
|
-
expect(result.error).toBeNull();
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
it('should reject invalid Anthropic key format', () => {
|
|
107
|
-
const invalidKey = 'sk-1234';
|
|
108
|
-
const result = validateApiKeyFormat(invalidKey, 'anthropic');
|
|
109
|
-
|
|
110
|
-
expect(result.valid).toBe(false);
|
|
111
|
-
expect(result.error).toContain('sk-ant-');
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it('should validate GitHub token format', () => {
|
|
115
|
-
const validToken = 'ghp_1234567890abcdefghij';
|
|
116
|
-
const result = validateApiKeyFormat(validToken, 'github');
|
|
117
|
-
|
|
118
|
-
expect(result.valid).toBe(true);
|
|
119
|
-
expect(result.error).toBeNull();
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
it('should reject keys with spaces', () => {
|
|
123
|
-
const keyWithSpace = 'sk-12345 67890';
|
|
124
|
-
const result = validateApiKeyFormat(keyWithSpace);
|
|
125
|
-
|
|
126
|
-
expect(result.valid).toBe(false);
|
|
127
|
-
expect(result.error).toContain('spaces');
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
it('should reject too short keys', () => {
|
|
131
|
-
const shortKey = 'sk-123';
|
|
132
|
-
const result = validateApiKeyFormat(shortKey);
|
|
133
|
-
|
|
134
|
-
expect(result.valid).toBe(false);
|
|
135
|
-
expect(result.error).toContain('too short');
|
|
136
|
-
});
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
describe('validateYamlSyntax', () => {
|
|
140
|
-
it('should validate correct YAML', () => {
|
|
141
|
-
const content = `
|
|
142
|
-
project:
|
|
143
|
-
type: GREENFIELD
|
|
144
|
-
version: 2.1.0
|
|
145
|
-
qa:
|
|
146
|
-
qaLocation: docs/qa
|
|
147
|
-
`;
|
|
148
|
-
|
|
149
|
-
const result = validateYamlSyntax(content);
|
|
150
|
-
expect(result.valid).toBe(true);
|
|
151
|
-
expect(result.error).toBeNull();
|
|
152
|
-
expect(result.parsed).toBeDefined();
|
|
153
|
-
expect(result.parsed.project.type).toBe('GREENFIELD');
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
it('should reject invalid YAML', () => {
|
|
157
|
-
// Use truly invalid YAML syntax that js-yaml will reject
|
|
158
|
-
const content = `
|
|
159
|
-
project:
|
|
160
|
-
type: GREENFIELD
|
|
161
|
-
!!invalid %%% syntax
|
|
162
|
-
`;
|
|
163
|
-
|
|
164
|
-
const result = validateYamlSyntax(content);
|
|
165
|
-
expect(result.valid).toBe(false);
|
|
166
|
-
expect(result.error).toContain('YAML syntax error');
|
|
167
|
-
expect(result.parsed).toBeNull();
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
it('should handle empty YAML', () => {
|
|
171
|
-
const content = '';
|
|
172
|
-
const result = validateYamlSyntax(content);
|
|
173
|
-
|
|
174
|
-
expect(result.valid).toBe(true);
|
|
175
|
-
expect(result.parsed).toBeUndefined();
|
|
176
|
-
});
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
describe('validateCoreConfigStructure', () => {
|
|
180
|
-
it('should validate correct core config structure', () => {
|
|
181
|
-
const config = {
|
|
182
|
-
project: { type: 'GREENFIELD' },
|
|
183
|
-
qa: { qaLocation: 'docs/qa' },
|
|
184
|
-
prd: { prdFile: 'docs/prd.md' },
|
|
185
|
-
architecture: { architectureFile: 'docs/architecture.md' },
|
|
186
|
-
};
|
|
187
|
-
|
|
188
|
-
const result = validateCoreConfigStructure(config);
|
|
189
|
-
expect(result.valid).toBe(true);
|
|
190
|
-
expect(result.errors).toHaveLength(0);
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
it('should reject missing required fields', () => {
|
|
194
|
-
const config = {
|
|
195
|
-
project: { type: 'GREENFIELD' },
|
|
196
|
-
// Missing qa, prd, architecture
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
const result = validateCoreConfigStructure(config);
|
|
200
|
-
expect(result.valid).toBe(false);
|
|
201
|
-
expect(result.errors.length).toBeGreaterThan(0);
|
|
202
|
-
expect(result.errors).toContain('Missing required field: qa');
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
it('should reject invalid project type', () => {
|
|
206
|
-
const config = {
|
|
207
|
-
project: { type: 'INVALID_TYPE' },
|
|
208
|
-
qa: {},
|
|
209
|
-
prd: {},
|
|
210
|
-
architecture: {},
|
|
211
|
-
};
|
|
212
|
-
|
|
213
|
-
const result = validateCoreConfigStructure(config);
|
|
214
|
-
expect(result.valid).toBe(false);
|
|
215
|
-
expect(result.errors).toContain('Invalid project.type: INVALID_TYPE. Expected greenfield, brownfield, or existing_sinapse');
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
it('should validate IDE section if present', () => {
|
|
219
|
-
const config = {
|
|
220
|
-
project: { type: 'GREENFIELD' },
|
|
221
|
-
qa: {},
|
|
222
|
-
prd: {},
|
|
223
|
-
architecture: {},
|
|
224
|
-
ide: { selected: 'not-an-array' }, // Should be array
|
|
225
|
-
};
|
|
226
|
-
|
|
227
|
-
const result = validateCoreConfigStructure(config);
|
|
228
|
-
expect(result.valid).toBe(false);
|
|
229
|
-
expect(result.errors).toContain('ide.selected must be an array');
|
|
230
|
-
});
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
describe('validatePath', () => {
|
|
234
|
-
it('should validate correct paths', () => {
|
|
235
|
-
const paths = [
|
|
236
|
-
'/absolute/path/to/file',
|
|
237
|
-
'relative/path/to/file',
|
|
238
|
-
'C:\\Windows\\Path\\File.txt',
|
|
239
|
-
'./current/directory',
|
|
240
|
-
];
|
|
241
|
-
|
|
242
|
-
paths.forEach(p => {
|
|
243
|
-
const result = validatePath(p);
|
|
244
|
-
expect(result.valid).toBe(true);
|
|
245
|
-
expect(result.error).toBeNull();
|
|
246
|
-
});
|
|
247
|
-
});
|
|
248
|
-
|
|
249
|
-
it('should reject empty paths', () => {
|
|
250
|
-
const result = validatePath('');
|
|
251
|
-
expect(result.valid).toBe(false);
|
|
252
|
-
expect(result.error).toContain('empty');
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
it('should reject path traversal', () => {
|
|
256
|
-
const result = validatePath('../../../etc/passwd');
|
|
257
|
-
expect(result.valid).toBe(false);
|
|
258
|
-
expect(result.error).toContain('Path traversal');
|
|
259
|
-
});
|
|
260
|
-
|
|
261
|
-
it('should reject invalid characters', () => {
|
|
262
|
-
const invalidPaths = [
|
|
263
|
-
'path/with<angle>brackets',
|
|
264
|
-
'path/with|pipe',
|
|
265
|
-
'path/with"quote',
|
|
266
|
-
'path/with?question',
|
|
267
|
-
];
|
|
268
|
-
|
|
269
|
-
invalidPaths.forEach(p => {
|
|
270
|
-
const result = validatePath(p);
|
|
271
|
-
expect(result.valid).toBe(false);
|
|
272
|
-
expect(result.error).toContain('invalid characters');
|
|
273
|
-
});
|
|
274
|
-
});
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
describe('sanitizeInput', () => {
|
|
278
|
-
it('should remove null bytes', () => {
|
|
279
|
-
const input = 'text\0with\0nulls';
|
|
280
|
-
const result = sanitizeInput(input);
|
|
281
|
-
|
|
282
|
-
expect(result).toBe('textwithnulls');
|
|
283
|
-
});
|
|
284
|
-
|
|
285
|
-
it('should trim whitespace', () => {
|
|
286
|
-
const input = ' whitespace around ';
|
|
287
|
-
const result = sanitizeInput(input);
|
|
288
|
-
|
|
289
|
-
expect(result).toBe('whitespace around');
|
|
290
|
-
});
|
|
291
|
-
|
|
292
|
-
it('should limit length', () => {
|
|
293
|
-
const input = 'a'.repeat(20000); // Exceeds max length
|
|
294
|
-
const result = sanitizeInput(input);
|
|
295
|
-
|
|
296
|
-
expect(result.length).toBeLessThanOrEqual(10000);
|
|
297
|
-
});
|
|
298
|
-
|
|
299
|
-
it('should handle non-string input', () => {
|
|
300
|
-
const inputs = [null, undefined, 123, {}, []];
|
|
301
|
-
|
|
302
|
-
inputs.forEach(input => {
|
|
303
|
-
const result = sanitizeInput(input);
|
|
304
|
-
expect(result).toBe('');
|
|
305
|
-
});
|
|
306
|
-
});
|
|
307
|
-
|
|
308
|
-
it('should preserve valid input', () => {
|
|
309
|
-
const input = 'Valid API Key sk-1234567890';
|
|
310
|
-
const result = sanitizeInput(input);
|
|
311
|
-
|
|
312
|
-
expect(result).toBe(input);
|
|
313
|
-
});
|
|
314
|
-
});
|
|
315
|
-
});
|