sinapse-ai 1.11.3 → 1.12.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 (77) hide show
  1. package/.claude/hooks/enforce-architecture-first.cjs +2 -2
  2. package/.claude/hooks/enforce-delegation.cjs +2 -2
  3. package/.claude/hooks/enforce-permission-mode.cjs +12 -12
  4. package/.claude/hooks/enforce-story-gate.cjs +5 -5
  5. package/.claude/hooks/precompact-session-digest.cjs +2 -2
  6. package/.claude/hooks/secret-scanning.cjs +6 -6
  7. package/.claude/hooks/telemetry-post-tool.cjs +0 -1
  8. package/.claude/hooks/write-path-validation.cjs +2 -2
  9. package/.sinapse-ai/core/code-intel/helpers/dev-helper.js +1 -1
  10. package/.sinapse-ai/core/code-intel/helpers/devops-helper.js +0 -1
  11. package/.sinapse-ai/core/code-intel/helpers/planning-helper.js +1 -1
  12. package/.sinapse-ai/core/code-intel/helpers/qa-helper.js +2 -2
  13. package/.sinapse-ai/core/config/template-overrides.js +1 -1
  14. package/.sinapse-ai/core/doctor/checks/git-hooks.js +6 -3
  15. package/.sinapse-ai/core/doctor/checks/npm-packages.js +1 -1
  16. package/.sinapse-ai/core/doctor/checks/rules-files.js +0 -1
  17. package/.sinapse-ai/core/doctor/index.js +0 -1
  18. package/.sinapse-ai/core/graph-dashboard/cli.js +1 -1
  19. package/.sinapse-ai/core/graph-dashboard/data-sources/code-intel-source.js +1 -1
  20. package/.sinapse-ai/core/health-check/checks/project/constitution-consistency.js +0 -1
  21. package/.sinapse-ai/core/ideation/ideation-engine.js +0 -2
  22. package/.sinapse-ai/core/ids/layer-classifier.js +1 -1
  23. package/.sinapse-ai/core/registry/build-registry.js +12 -2
  24. package/.sinapse-ai/core/registry/service-registry.json +178 -55
  25. package/.sinapse-ai/core/registry/squad-agent-resolver.js +6 -0
  26. package/.sinapse-ai/core/synapse/layers/layer-processor.js +1 -1
  27. package/.sinapse-ai/data/capability-detection.js +15 -15
  28. package/.sinapse-ai/data/tok3-token-comparison.js +0 -3
  29. package/.sinapse-ai/data/tool-search-validation.js +1 -1
  30. package/.sinapse-ai/development/agents/snps-orqx.md +109 -0
  31. package/.sinapse-ai/development/scripts/agent-config-loader.js +8 -2
  32. package/.sinapse-ai/development/templates/sinapse-doc-template.md +6 -6
  33. package/.sinapse-ai/git-hooks/lib/framework-guard.js +1 -0
  34. package/.sinapse-ai/git-hooks/lib/staged-protected-files-guard.js +63 -0
  35. package/.sinapse-ai/git-hooks/pre-commit +3 -1
  36. package/.sinapse-ai/index.d.ts +19 -0
  37. package/.sinapse-ai/install-manifest.yaml +59 -55
  38. package/.sinapse-ai/package.json +0 -1
  39. package/.sinapse-ai/utils/filters/index.js +2 -1
  40. package/CHANGELOG.md +31 -2
  41. package/bin/commands/doctor.js +1 -1
  42. package/bin/commands/help.js +3 -4
  43. package/bin/commands/install.js +7 -7
  44. package/bin/commands/status.js +3 -3
  45. package/bin/modules/chrome-brain-installer.js +3 -3
  46. package/bin/postinstall.js +1 -1
  47. package/bin/sinapse-init.js +11 -9
  48. package/bin/sinapse.js +1 -1
  49. package/bin/utils/framework-guard.js +1 -0
  50. package/bin/utils/staged-protected-files-guard.js +63 -0
  51. package/package.json +19 -2
  52. package/packages/installer/src/index.js +1 -1
  53. package/packages/installer/src/installer/brownfield-upgrader.js +1 -1
  54. package/packages/installer/src/installer/git-hooks-installer.js +10 -3
  55. package/packages/installer/src/pro/pro-scaffolder.js +3 -3
  56. package/packages/installer/src/wizard/ide-config-generator.js +1 -1
  57. package/packages/installer/src/wizard/index.js +4 -41
  58. package/scripts/audit-tasks.cjs +1 -1
  59. package/scripts/package-synapse.js +1 -1
  60. package/scripts/sinapse-patch.js +31 -31
  61. package/scripts/sync-squad-yaml-components.js +3 -3
  62. package/scripts/validate-agents-md.js +1 -1
  63. package/scripts/validate-no-personal-leaks.js +1 -1
  64. package/scripts/validate-orqx-discipline.js +0 -2
  65. package/scripts/validate-package-completeness.js +7 -7
  66. package/scripts/validate-squad-yaml.js +6 -6
  67. package/sinapse/agents/sinapse-orqx.md +1 -1
  68. package/sinapse/agents/snps-orqx.md +110 -1
  69. package/squads/claude-code-mastery/agents/swarm-orqx.md +12 -11
  70. package/squads/claude-code-mastery/scripts/validate-setup.js +2 -2
  71. package/squads/squad-brand/agents/brand-orqx.md +16 -1
  72. package/squads/squad-cloning/agents/cloning-orqx.md +2 -0
  73. package/squads/squad-commercial/agents/commercial-orqx.md +7 -4
  74. package/squads/squad-council/squad.yaml +67 -11
  75. package/squads/squad-design/agents/design-orqx.md +20 -0
  76. package/squads/squad-finance/agents/finance-orqx.md +6 -0
  77. package/squads/squad-paidmedia/agents/paidmedia-orqx.md +3 -1
@@ -133,10 +133,10 @@ function main() {
133
133
  const accepted = protection.docPatterns.map((d) => ` - ${d.replace('{name}', name)}`).join('\n');
134
134
 
135
135
  process.stderr.write(
136
- `\nARCHITECTURE-FIRST BLOCK: Documentation required before code.\n` +
136
+ '\nARCHITECTURE-FIRST BLOCK: Documentation required before code.\n' +
137
137
  `File: ${rel}\n` +
138
138
  `Create one of:\n${accepted}\n` +
139
- `Then retry the operation.\n`,
139
+ 'Then retry the operation.\n',
140
140
  );
141
141
  process.exit(2);
142
142
  }
@@ -158,10 +158,10 @@ function main() {
158
158
  const delegate = delegationMap[toolName] || '@developer';
159
159
 
160
160
  process.stderr.write(
161
- `\nMANDATORY DELEGATION BLOCK (Constitution Article VIII)\n` +
161
+ '\nMANDATORY DELEGATION BLOCK (Constitution Article VIII)\n' +
162
162
  `Agent: ${agentId} (orchestrator)\n` +
163
163
  `Tool: ${toolName}\n` +
164
- `Orchestrators NEVER execute domain work directly.\n` +
164
+ 'Orchestrators NEVER execute domain work directly.\n' +
165
165
  `Delegate to ${delegate} for this operation.\n`,
166
166
  );
167
167
  process.exit(2);
@@ -229,19 +229,19 @@ function main() {
229
229
 
230
230
  // BLOCK — exit 2
231
231
  process.stderr.write(
232
- `\nPERMISSION-MODE BLOCK [Explore / Read-Only]\n` +
232
+ '\nPERMISSION-MODE BLOCK [Explore / Read-Only]\n' +
233
233
  `Tool: ${toolName} Operation: ${operation}${detail}\n` +
234
- `\n` +
235
- `The project is in Explore (read-only) mode. Write, Edit, and destructive\n` +
236
- `Bash commands are not allowed in this mode.\n` +
237
- `\n` +
238
- `To enable writes, change the permission mode:\n` +
239
- ` *mode ask — confirm before each change\n` +
240
- ` *mode auto — full autonomy (no prompts)\n` +
241
- `\n` +
242
- `Or update .sinapse/config.yaml:\n` +
243
- ` permissions:\n` +
244
- ` mode: ask\n`,
234
+ '\n' +
235
+ 'The project is in Explore (read-only) mode. Write, Edit, and destructive\n' +
236
+ 'Bash commands are not allowed in this mode.\n' +
237
+ '\n' +
238
+ 'To enable writes, change the permission mode:\n' +
239
+ ' *mode ask — confirm before each change\n' +
240
+ ' *mode auto — full autonomy (no prompts)\n' +
241
+ '\n' +
242
+ 'Or update .sinapse/config.yaml:\n' +
243
+ ' permissions:\n' +
244
+ ' mode: ask\n',
245
245
  );
246
246
  process.exit(2);
247
247
  }
@@ -181,12 +181,12 @@ function main() {
181
181
 
182
182
  // BLOCK
183
183
  process.stderr.write(
184
- `\nDOCUMENTATION-FIRST BLOCK (Constitution Article III)\n` +
184
+ '\nDOCUMENTATION-FIRST BLOCK (Constitution Article III)\n' +
185
185
  `File: ${rel}\n` +
186
- `No active story found with status >= Ready in docs/stories/.\n` +
187
- `Create a story first: @sprint-lead *draft\n` +
188
- `Then validate it: @product-lead *validate\n` +
189
- `Only then can implementation proceed.\n`,
186
+ 'No active story found with status >= Ready in docs/stories/.\n' +
187
+ 'Create a story first: @sprint-lead *draft\n' +
188
+ 'Then validate it: @product-lead *validate\n' +
189
+ 'Only then can implementation proceed.\n',
190
190
  );
191
191
  process.exit(2);
192
192
  }
@@ -99,9 +99,9 @@ async function main() {
99
99
  contextJson = '{}';
100
100
  }
101
101
  const inlineScript = [
102
- `const ctx = JSON.parse(process.env.SINAPSE_HOOK_CONTEXT || '{}');`,
102
+ 'const ctx = JSON.parse(process.env.SINAPSE_HOOK_CONTEXT || \'{}\');',
103
103
  `const { onPreCompact } = require(${JSON.stringify(runnerPath)});`,
104
- `onPreCompact(ctx).catch(() => {});`,
104
+ 'onPreCompact(ctx).catch(() => {});',
105
105
  ].join('\n');
106
106
  const child = spawn(process.execPath, ['-e', inlineScript], {
107
107
  detached: true,
@@ -131,14 +131,14 @@ function main() {
131
131
  return ` - ${f.name}: ${f.redacted}${ent}`;
132
132
  });
133
133
  process.stderr.write(
134
- `\nSECRET SCANNING BLOCK: Potential secrets detected!\n` +
134
+ '\nSECRET SCANNING BLOCK: Potential secrets detected!\n' +
135
135
  `File: ${rel}\n` +
136
136
  `Found:\n${lines.join('\n')}\n` +
137
- `\n` +
138
- `DO NOT commit secrets to code. Instead:\n` +
139
- ` - Use environment variables (.env) for local dev\n` +
140
- ` - Use .env.example with placeholder values for templates\n` +
141
- ` - Use secret managers for production (Supabase Vault, etc.)\n`,
137
+ '\n' +
138
+ 'DO NOT commit secrets to code. Instead:\n' +
139
+ ' - Use environment variables (.env) for local dev\n' +
140
+ ' - Use .env.example with placeholder values for templates\n' +
141
+ ' - Use secret managers for production (Supabase Vault, etc.)\n',
142
142
  );
143
143
  process.exit(2);
144
144
  }
@@ -17,7 +17,6 @@
17
17
 
18
18
  const fs = require('fs');
19
19
  const path = require('path');
20
- const os = require('os');
21
20
 
22
21
  // ─── constants ───────────────────────────────────────────────────────────────
23
22
 
@@ -120,11 +120,11 @@ function main() {
120
120
 
121
121
  // WARN only — never block
122
122
  process.stderr.write(
123
- `\nPATH WARNING: Document may be in the wrong location.\n` +
123
+ '\nPATH WARNING: Document may be in the wrong location.\n' +
124
124
  ` File: ${violation.currentPath}\n` +
125
125
  ` Expected: ${violation.expectedPath}\n` +
126
126
  ` Rule: ${violation.description}\n` +
127
- ` NOTE: This is a WARNING only — the operation will proceed.\n`,
127
+ ' NOTE: This is a WARNING only — the operation will proceed.\n',
128
128
  );
129
129
  process.exit(0);
130
130
  }
@@ -6,7 +6,7 @@ const { getEnricher, getClient, isCodeIntelAvailable } = require('../index');
6
6
  const RISK_THRESHOLDS = {
7
7
  LOW_MAX: 4, // 0-4 refs = LOW
8
8
  MEDIUM_MAX: 15, // 5-15 refs = MEDIUM
9
- // >15 refs = HIGH
9
+ // >15 refs = HIGH
10
10
  };
11
11
 
12
12
  // Minimum references to suggest REUSE (>threshold = REUSE, <=threshold = ADAPT)
@@ -78,7 +78,6 @@ async function generateImpactSummary(files) {
78
78
  } catch { /* skip — partial result ok */ }
79
79
 
80
80
  const riskLevel = classifyRiskLevel(impact.blastRadius);
81
- const fileCount = impact.references ? impact.references.length : 0;
82
81
  const topFiles = (impact.references || [])
83
82
  .map((r) => r.file || r.path || 'unknown')
84
83
  .slice(0, 10);
@@ -7,7 +7,7 @@ const { getEnricher, getClient, isCodeIntelAvailable } = require('../index');
7
7
  const RISK_THRESHOLDS = {
8
8
  LOW_MAX: 4, // 0-4 refs = LOW
9
9
  MEDIUM_MAX: 15, // 5-15 refs = MEDIUM
10
- // >15 refs = HIGH
10
+ // >15 refs = HIGH
11
11
  };
12
12
 
13
13
  /**
@@ -7,14 +7,14 @@ const { getEnricher, getClient, isCodeIntelAvailable } = require('../index');
7
7
  const RISK_THRESHOLDS = {
8
8
  LOW_MAX: 4, // 0-4 refs = LOW
9
9
  MEDIUM_MAX: 15, // 5-15 refs = MEDIUM
10
- // >15 refs = HIGH
10
+ // >15 refs = HIGH
11
11
  };
12
12
 
13
13
  // Coverage status thresholds based on test reference count
14
14
  const COVERAGE_THRESHOLDS = {
15
15
  INDIRECT_MAX: 2, // 1-2 test refs = INDIRECT
16
16
  MINIMAL_MAX: 5, // 3-5 test refs = MINIMAL
17
- // >5 test refs = GOOD
17
+ // >5 test refs = GOOD
18
18
  };
19
19
 
20
20
  /**
@@ -53,7 +53,7 @@ function getTemplateOverrides(resolvedConfig) {
53
53
  if (unknown.length > 0) {
54
54
  throw new Error(
55
55
  `Unknown story section ID(s) in template_overrides: ${unknown.join(', ')}. ` +
56
- `Valid IDs: ${KNOWN_STORY_SECTIONS.join(', ')}`
56
+ `Valid IDs: ${KNOWN_STORY_SECTIONS.join(', ')}`,
57
57
  );
58
58
  }
59
59
 
@@ -108,11 +108,14 @@ async function run(context) {
108
108
  // hooksPath points at a real dir, but does it point at OUR managed dir? If it
109
109
  // resolves elsewhere, the framework backstop is not the active hook system.
110
110
  if (!resolvesToManaged(projectRoot, hooksPath)) {
111
+ // The user runs their OWN hook system (husky/lefthook/custom). This is a
112
+ // legitimate brownfield setup, NOT a broken install — so WARN, not FAIL.
113
+ // The framework's secret-scan/SQL/boundary guards just aren't layered in.
111
114
  return {
112
115
  check: name,
113
- status: 'FAIL',
114
- message: `core.hooksPath -> "${hooksPath}" resolves OUTSIDE the managed dir (${MANAGED_HOOKS_DIR}). The framework's secret-scan/SQL/boundary guards are not the active hook system. Re-wire core.hooksPath to the managed dir.`,
115
- fixCommand: 'sinapse init # re-wires core.hooksPath to .sinapse-ai/git-hooks',
116
+ status: 'WARN',
117
+ message: `core.hooksPath -> "${hooksPath}" points at your own hook system (outside ${MANAGED_HOOKS_DIR}). That's fine — but the framework's secret-scan/SQL/boundary guards are not active. To layer them in, source ${MANAGED_HOOKS_DIR}/pre-commit from your own pre-commit, or re-wire core.hooksPath to ${MANAGED_HOOKS_DIR}.`,
118
+ fixCommand: null,
116
119
  };
117
120
  }
118
121
 
@@ -46,7 +46,7 @@ async function run(context) {
46
46
  const sinapseCorePackageJson = path.join(sinapseCoreDir, 'package.json');
47
47
  const sinapseCoreNodeModules = path.join(sinapseCoreDir, 'node_modules');
48
48
 
49
- let unresolved = [];
49
+ const unresolved = [];
50
50
  let totalDeps = 0;
51
51
  let hasSinapseCorePkg = false;
52
52
 
@@ -47,7 +47,6 @@ async function run(context) {
47
47
  };
48
48
  }
49
49
 
50
- const present = EXPECTED_RULES.length - missing.length;
51
50
  const severity = missing.length > 3 ? 'FAIL' : 'WARN';
52
51
 
53
52
  return {
@@ -21,7 +21,6 @@
21
21
  */
22
22
 
23
23
  const fs = require('fs');
24
- const os = require('os');
25
24
  const path = require('path');
26
25
  const { loadChecks } = require('./checks');
27
26
  const { formatText } = require('./formatters/text');
@@ -280,7 +280,7 @@ Examples:
280
280
  * Handle default summary view: dependency tree (compact) + stats + provider status.
281
281
  * @param {Object} args - Parsed CLI args
282
282
  */
283
- async function handleSummary(args) {
283
+ async function handleSummary(_args) {
284
284
  const codeIntelSource = new CodeIntelSource();
285
285
  const registrySource = new RegistrySource();
286
286
  const metricsSource = new MetricsSource();
@@ -161,7 +161,7 @@ class CodeIntelSource {
161
161
  Object.entries(deps.dependencies).map(([key, val]) => ({
162
162
  id: key,
163
163
  ...((typeof val === 'object' && val) || {}),
164
- }))
164
+ })),
165
165
  );
166
166
  }
167
167
 
@@ -121,7 +121,6 @@ class ConstitutionConsistencyCheck extends BaseCheck {
121
121
  const generatedContent = fs.readFileSync(generatedPath, 'utf8');
122
122
 
123
123
  for (const article of EXPECTED_ARTICLES) {
124
- const key = `CONSTITUTION_RULE_ART${EXPECTED_ARTICLES.indexOf(article) + 1}_0`;
125
124
  if (!generatedContent.includes(article.title)) {
126
125
  issues.push(`Generated constitution missing Article "${article.title}". Run generate-constitution.js`);
127
126
  }
@@ -13,10 +13,8 @@ const { spawnSync } = require('child_process');
13
13
  // Import dependencies with fallbacks
14
14
  const GOTCHAS_MEMORY_MODULE = '../memory/gotchas-memory';
15
15
  let GotchasMemory;
16
- let gotchasMemoryLoadError = null;
17
16
 
18
17
  function recordGotchasMemoryLoadError(error) {
19
- gotchasMemoryLoadError = error;
20
18
  if (process.env.SINAPSE_DEBUG) {
21
19
  console.warn(
22
20
  `[ideation-engine] Optional dependency '${GOTCHAS_MEMORY_MODULE}' failed to load: ${error.stack || error.message}`,
@@ -44,7 +44,7 @@ const LAYER_RULES = [
44
44
  * @returns {'L1' | 'L2' | 'L3' | 'L4'} The boundary layer
45
45
  */
46
46
  function classifyLayer(entityPath) {
47
- if (typeof entityPath !== "string") return "L4";
47
+ if (typeof entityPath !== 'string') return 'L4';
48
48
 
49
49
  // Normalize: forward slashes, no leading ./ or /
50
50
  const normalized = entityPath
@@ -372,9 +372,19 @@ async function buildRegistry(baseDir = process.cwd()) {
372
372
  for (const file of files) {
373
373
  const worker = await buildWorkerEntry(file, source, baseDir);
374
374
 
375
- // Ensure unique IDs
375
+ // Ensure unique IDs. First collision keeps the legacy `-{category}`
376
+ // suffix; further collisions (3+ files with the same basename in the
377
+ // same category, e.g. multiple `index.js`) append a numeric counter so
378
+ // every id is guaranteed unique — the previous code suffixed only once
379
+ // and never re-checked, so N>2 collisions all produced the same id.
376
380
  if (seenIds.has(worker.id)) {
377
- worker.id = `${worker.id}-${source.category}`;
381
+ let candidate = `${worker.id}-${source.category}`;
382
+ let n = 2;
383
+ while (seenIds.has(candidate)) {
384
+ candidate = `${worker.id}-${source.category}-${n}`;
385
+ n++;
386
+ }
387
+ worker.id = candidate;
378
388
  }
379
389
  seenIds.add(worker.id);
380
390