sinapse-ai 1.11.3 → 1.12.1
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/hooks/enforce-architecture-first.cjs +2 -2
- package/.claude/hooks/enforce-delegation.cjs +2 -2
- package/.claude/hooks/enforce-permission-mode.cjs +12 -12
- package/.claude/hooks/enforce-story-gate.cjs +5 -5
- package/.claude/hooks/precompact-session-digest.cjs +2 -2
- package/.claude/hooks/secret-scanning.cjs +6 -6
- package/.claude/hooks/telemetry-post-tool.cjs +0 -1
- package/.claude/hooks/write-path-validation.cjs +2 -2
- package/.sinapse-ai/core/code-intel/helpers/dev-helper.js +1 -1
- package/.sinapse-ai/core/code-intel/helpers/devops-helper.js +0 -1
- package/.sinapse-ai/core/code-intel/helpers/planning-helper.js +1 -1
- package/.sinapse-ai/core/code-intel/helpers/qa-helper.js +2 -2
- package/.sinapse-ai/core/config/template-overrides.js +1 -1
- package/.sinapse-ai/core/doctor/checks/git-hooks.js +6 -3
- package/.sinapse-ai/core/doctor/checks/npm-packages.js +1 -1
- package/.sinapse-ai/core/doctor/checks/rules-files.js +0 -1
- package/.sinapse-ai/core/doctor/index.js +0 -1
- package/.sinapse-ai/core/graph-dashboard/cli.js +1 -1
- package/.sinapse-ai/core/graph-dashboard/data-sources/code-intel-source.js +1 -1
- package/.sinapse-ai/core/health-check/checks/project/constitution-consistency.js +0 -1
- package/.sinapse-ai/core/ideation/ideation-engine.js +0 -2
- package/.sinapse-ai/core/ids/layer-classifier.js +1 -1
- package/.sinapse-ai/core/registry/build-registry.js +12 -2
- package/.sinapse-ai/core/registry/service-registry.json +178 -55
- package/.sinapse-ai/core/registry/squad-agent-resolver.js +6 -0
- package/.sinapse-ai/core/synapse/layers/layer-processor.js +1 -1
- package/.sinapse-ai/data/capability-detection.js +15 -15
- package/.sinapse-ai/data/tok3-token-comparison.js +0 -3
- package/.sinapse-ai/data/tool-search-validation.js +1 -1
- package/.sinapse-ai/development/agents/snps-orqx.md +109 -0
- package/.sinapse-ai/development/scripts/agent-config-loader.js +8 -2
- package/.sinapse-ai/development/templates/sinapse-doc-template.md +6 -6
- package/.sinapse-ai/git-hooks/lib/framework-guard.js +1 -0
- package/.sinapse-ai/git-hooks/lib/staged-protected-files-guard.js +63 -0
- package/.sinapse-ai/git-hooks/pre-commit +3 -1
- package/.sinapse-ai/index.d.ts +19 -0
- package/.sinapse-ai/infrastructure/scripts/validate-agents.js +46 -16
- package/.sinapse-ai/install-manifest.yaml +61 -57
- package/.sinapse-ai/package.json +0 -1
- package/.sinapse-ai/utils/filters/index.js +2 -1
- package/CHANGELOG.md +38 -2
- package/README.md +132 -132
- package/bin/commands/doctor.js +1 -1
- package/bin/commands/help.js +3 -4
- package/bin/commands/install.js +7 -7
- package/bin/commands/status.js +3 -3
- package/bin/modules/chrome-brain-installer.js +3 -3
- package/bin/postinstall.js +1 -1
- package/bin/sinapse-init.js +11 -9
- package/bin/sinapse.js +1 -1
- package/bin/utils/framework-guard.js +1 -0
- package/bin/utils/staged-protected-files-guard.js +63 -0
- package/package.json +19 -2
- package/packages/installer/src/index.js +1 -1
- package/packages/installer/src/installer/brownfield-upgrader.js +1 -1
- package/packages/installer/src/installer/git-hooks-installer.js +10 -3
- package/packages/installer/src/pro/pro-scaffolder.js +3 -3
- package/packages/installer/src/wizard/ide-config-generator.js +1 -1
- package/packages/installer/src/wizard/index.js +4 -41
- package/scripts/audit-tasks.cjs +1 -1
- package/scripts/package-synapse.js +1 -1
- package/scripts/sinapse-patch.js +31 -31
- package/scripts/sync-squad-yaml-components.js +3 -3
- package/scripts/validate-agents-md.js +1 -1
- package/scripts/validate-no-external-refs.js +2 -2
- package/scripts/validate-no-personal-leaks.js +1 -1
- package/scripts/validate-orqx-discipline.js +0 -2
- package/scripts/validate-package-completeness.js +7 -7
- package/scripts/validate-squad-yaml.js +6 -6
- package/sinapse/agents/sinapse-orqx.md +1 -1
- package/sinapse/agents/snps-orqx.md +110 -1
- package/squads/claude-code-mastery/agents/swarm-orqx.md +12 -11
- package/squads/claude-code-mastery/scripts/validate-setup.js +2 -2
- package/squads/squad-brand/agents/brand-orqx.md +16 -1
- package/squads/squad-cloning/agents/cloning-orqx.md +2 -0
- package/squads/squad-commercial/agents/commercial-orqx.md +7 -4
- package/squads/squad-council/squad.yaml +67 -11
- package/squads/squad-design/agents/design-orqx.md +20 -0
- package/squads/squad-finance/agents/finance-orqx.md +6 -0
- package/squads/squad-paidmedia/agents/paidmedia-orqx.md +3 -1
|
@@ -44,9 +44,102 @@ After the greeting, check if the user already provided briefing/context with the
|
|
|
44
44
|
|
|
45
45
|
If the user asks about SINAPSE, how it works, or how to use it, execute the `*onboard` task from `tasks/onboard-user.md` to provide a guided walkthrough of the ecosystem, available squads, commands, and workflows.
|
|
46
46
|
|
|
47
|
+
## NON-NEGOTIABLE: INITIAL STATE AUDIT (RUNS FIRST OF ALL)
|
|
48
|
+
|
|
49
|
+
> **This step runs BEFORE bootstrap classification, BEFORE routing, BEFORE anything.**
|
|
50
|
+
> Without it, Imperator treats every directory as greenfield and ignores existing partial work (brand assets, half-written PRD, components, abandoned epics, brownfield code without `package.json`).
|
|
51
|
+
|
|
52
|
+
On every briefing that mentions creating, building, or working on a project, run the **Initial State Audit** (full spec in `~/.claude/rules/project-intelligence.md` § Initial State Audit):
|
|
53
|
+
|
|
54
|
+
1. Silently check the 8 dimensions (Docs, Brand, Design system, Components, Code, Tests, Infra, Git history)
|
|
55
|
+
2. Compute maturity level: `EMPTY` / `BOOTSTRAPPED` / `PARTIAL` / `MATURE` / `SINAPSE_MANAGED`
|
|
56
|
+
3. **Present a structured report to the user (PT-BR) BEFORE proposing any plan:**
|
|
57
|
+
```
|
|
58
|
+
Estado detectado: {maturity_level}
|
|
59
|
+
Já existe: {list of artifacts found}
|
|
60
|
+
Faltando: {list of gaps relative to user's goal}
|
|
61
|
+
Recomendação: {workflow + first step}
|
|
62
|
+
```
|
|
63
|
+
4. Only after this report (and any user correction) proceed to bootstrap classification
|
|
64
|
+
|
|
65
|
+
### Why this exists
|
|
66
|
+
|
|
67
|
+
Caio's runtime test (2026-05-07) showed the framework treating fresh installs as "create from scratch" without ever checking what already lived in the directory. A user often has brand assets, an old PRD, half-finished components, or an abandoned epic — and the framework was overwriting / duplicating that work instead of continuing from it.
|
|
68
|
+
|
|
69
|
+
### Anti-patterns (FORBIDDEN)
|
|
70
|
+
|
|
71
|
+
- Skipping the audit "because it looks empty"
|
|
72
|
+
- Routing to greenfield workflows without first reporting what already exists
|
|
73
|
+
- Overwriting partial work (brand assets, components, docs) without listing it to the user
|
|
74
|
+
- Ignoring `docs/epics/` or `docs/stories/` from a previous session
|
|
75
|
+
- Treating a directory with brand assets but no code as `EMPTY`
|
|
76
|
+
- Treating a directory with `package.json` as `MATURE` when it's actually just bootstrapped infra
|
|
77
|
+
|
|
78
|
+
## NON-NEGOTIABLE: PROJECT BOOTSTRAP CLASSIFICATION (RUNS AFTER AUDIT, BEFORE ROUTING)
|
|
79
|
+
|
|
80
|
+
> **This step runs AFTER the Initial State Audit, BEFORE the routing decision. No exceptions.**
|
|
81
|
+
> Without it, Imperator routes large-project requests directly to a domain orchestrator and skips the doc-first pipeline (Article III violation).
|
|
82
|
+
|
|
83
|
+
After the audit reports the maturity level, classify the request **before** consulting the routing table:
|
|
84
|
+
|
|
85
|
+
### Step 1 — Detect intent
|
|
86
|
+
|
|
87
|
+
| Intent | Trigger keywords (PT/EN) |
|
|
88
|
+
|---|---|
|
|
89
|
+
| `new_project_bootstrap` | criar / novo / build / montar / fazer um(a) [site, plataforma, app, API, ...] |
|
|
90
|
+
| `feature_in_existing_project` | implementa / adiciona / add (with `docs/epics/` already present) |
|
|
91
|
+
| `fix` | corrige / conserta / ajusta / fix / bug |
|
|
92
|
+
| `tweak` | troca / muda / altera (small surface, single file) |
|
|
93
|
+
| `domain_consult` | qualquer pergunta de branding, copy, growth, etc. (no code change implied) |
|
|
94
|
+
|
|
95
|
+
### Step 2 — If `new_project_bootstrap`, sub-classify project_type
|
|
96
|
+
|
|
97
|
+
| project_type | Triggers | Required workflow |
|
|
98
|
+
|---|---|---|
|
|
99
|
+
| `site` | site, website, institutional, página | `greenfield-ui.yaml` |
|
|
100
|
+
| `lp` | landing page, LP, captura, sales page | `greenfield-ui.yaml` |
|
|
101
|
+
| `app` | app mobile, app nativo, ios, android, react native | `greenfield-ui.yaml` |
|
|
102
|
+
| `platform` | plataforma, dashboard, admin, portal interno | `greenfield-fullstack.yaml` |
|
|
103
|
+
| `saas` | SaaS, software as a service, app web com login | `greenfield-fullstack.yaml` |
|
|
104
|
+
| `api` | API, backend, microservice, serviço REST/GraphQL | `greenfield-service.yaml` |
|
|
105
|
+
| `service` | worker, integration, automation, ETL, cron job | `greenfield-service.yaml` |
|
|
106
|
+
|
|
107
|
+
### Step 3 — Apply the gate (NON-NEGOTIABLE)
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
IF intent == new_project_bootstrap
|
|
111
|
+
AND project_type ∈ [site, lp, app, platform, saas, api, service]
|
|
112
|
+
AND no epic exists in docs/epics/
|
|
113
|
+
THEN
|
|
114
|
+
BLOCK any direct routing to domain orchestrators
|
|
115
|
+
INVOKE the required greenfield workflow (see table)
|
|
116
|
+
PRODUCE upstream artifacts FIRST: project-brief.md → prd.md → architecture.md (and front-end-spec.md for UI)
|
|
117
|
+
ONLY AFTER artifacts validated → shard → stories → route to domain orqx for execution
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Step 4 — Complexity gate
|
|
121
|
+
|
|
122
|
+
If the briefing scores ≥ 16 on the 5 complexity dimensions (scope, integration, infrastructure, knowledge, risk), run the **Spec Pipeline** (`spec-pipeline.yaml`) BEFORE the greenfield workflow:
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
@project-lead gather → @architect assess → @analyst research →
|
|
126
|
+
@project-lead spec → @quality-gate critique → @architect plan
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Only after spec is APPROVED, the greenfield workflow runs.
|
|
130
|
+
|
|
131
|
+
### Anti-patterns (FORBIDDEN — these violate Article III)
|
|
132
|
+
|
|
133
|
+
- Routing "criar um site" directly to `@design-orqx` / `@brand-orqx` without first running greenfield-ui.yaml
|
|
134
|
+
- Routing "monta uma plataforma SaaS" to a domain orqx without Spec Pipeline + greenfield-fullstack.yaml
|
|
135
|
+
- Skipping Phase 1 Discovery (5-agent: analyst → project-lead → ux-design-expert → architect → product-lead) on a new UI project
|
|
136
|
+
- Treating "rapidinho" / "simples" as a license to skip doc-first when the project type requires it
|
|
137
|
+
- Generating UI without DS grounding (see `~/.claude/rules/design-system-grounding.md`)
|
|
138
|
+
|
|
47
139
|
## NON-NEGOTIABLE: ORCHESTRATION PLAN ON EVERY BRIEFING
|
|
48
140
|
|
|
49
141
|
> **This is an absolute, non-negotiable rule. No exceptions. No waiting to be asked.**
|
|
142
|
+
> **It runs AFTER the bootstrap classification above.** If the gate routed to a greenfield workflow, the orchestration plan describes that workflow (its phases, agents, handoffs) — not a domain-orqx routing.
|
|
50
143
|
|
|
51
144
|
When the user provides ANY briefing, request, or initiative (regardless of complexity), Imperator MUST **immediately and autonomously**:
|
|
52
145
|
|
|
@@ -610,6 +703,22 @@ framework_compatibility:
|
|
|
610
703
|
|
|
611
704
|
## How Imperator Operates
|
|
612
705
|
|
|
706
|
+
### -1. Initial State Audit (ABSOLUTE FIRST)
|
|
707
|
+
Before anything else, Imperator runs the Initial State Audit described above:
|
|
708
|
+
- Silently checks 8 dimensions (Docs, Brand, DS, Components, Code, Tests, Infra, Git)
|
|
709
|
+
- Computes maturity level: `EMPTY` / `BOOTSTRAPPED` / `PARTIAL` / `MATURE` / `SINAPSE_MANAGED`
|
|
710
|
+
- Presents structured PT-BR report to user listing what exists, what's missing, what's recommended
|
|
711
|
+
- Only proceeds when the user has seen what's already there
|
|
712
|
+
|
|
713
|
+
### 0. Bootstrap Classification (after audit)
|
|
714
|
+
Imperator runs the Project Bootstrap Classification described above:
|
|
715
|
+
- Detects intent: `new_project_bootstrap` / `feature` / `fix` / `tweak` / `domain_consult`
|
|
716
|
+
- Sub-classifies project_type if bootstrap: `site` / `lp` / `app` / `platform` / `saas` / `api` / `service`
|
|
717
|
+
- Applies the gate: large-project bootstrap with no epic → invokes the required greenfield workflow
|
|
718
|
+
- Triggers the Spec Pipeline if complexity score ≥ 16
|
|
719
|
+
- Routes to Continuation Behavior when audit detected `PARTIAL` maturity (never overwrite existing work)
|
|
720
|
+
- Only proceeds to step 1 (routing) when this gate is satisfied
|
|
721
|
+
|
|
613
722
|
### 1. Diagnose First
|
|
614
723
|
Every request gets classified before routing. Imperator identifies:
|
|
615
724
|
- **Domain(s):** Which squad(s) own this work?
|
|
@@ -12,6 +12,10 @@ const path = require('path');
|
|
|
12
12
|
const yaml = require('js-yaml');
|
|
13
13
|
const { globalConfigCache } = require('../../core/config/config-cache');
|
|
14
14
|
const { trackConfigLoad } = require('../../infrastructure/scripts/performance-tracker');
|
|
15
|
+
// Canonical short-form → file-id alias map (single source of truth). Without this,
|
|
16
|
+
// short ids like 'dev'/'qa'/'sinapse-orqx' resolve to '<id>.md' which does not exist
|
|
17
|
+
// (files are developer.md / quality-gate.md / snps-orqx.md), degrading the greeting.
|
|
18
|
+
const { ALIASES: AGENT_ID_ALIASES } = require('../../core/registry/squad-agent-resolver');
|
|
15
19
|
|
|
16
20
|
/**
|
|
17
21
|
* Agent configuration requirements cache
|
|
@@ -317,8 +321,10 @@ class AgentConfigLoader {
|
|
|
317
321
|
}
|
|
318
322
|
}
|
|
319
323
|
|
|
320
|
-
// Load from file
|
|
321
|
-
|
|
324
|
+
// Load from file. Resolve short-form aliases (dev→developer, qa→quality-gate,
|
|
325
|
+
// sinapse-orqx→snps-orqx, ...) to the canonical file id before building the path.
|
|
326
|
+
const fileId = AGENT_ID_ALIASES[this.agentId] || this.agentId;
|
|
327
|
+
const agentPath = path.join(process.cwd(), '.sinapse-ai', 'development', 'agents', `${fileId}.md`);
|
|
322
328
|
|
|
323
329
|
try {
|
|
324
330
|
const content = await fs.readFile(agentPath, 'utf8');
|
|
@@ -65,7 +65,7 @@ _Last Updated: {{DATE}} | SINAPSE Framework Team_
|
|
|
65
65
|
```markdown
|
|
66
66
|
# {{TITLE}}
|
|
67
67
|
|
|
68
|
-
> **EN** | [PT](../pt/path/{{FILENAME}})
|
|
68
|
+
> **EN** | [PT](../pt/path/{{FILENAME}})
|
|
69
69
|
|
|
70
70
|
---
|
|
71
71
|
|
|
@@ -169,7 +169,7 @@ _Last Updated: {{DATE}} | SINAPSE Framework Team_
|
|
|
169
169
|
```markdown
|
|
170
170
|
# ADR-{{NUMBER}}: {{TITLE}}
|
|
171
171
|
|
|
172
|
-
> **EN** | [PT](../../pt/architecture/adr/{{FILENAME}})
|
|
172
|
+
> **EN** | [PT](../../pt/architecture/adr/{{FILENAME}})
|
|
173
173
|
|
|
174
174
|
---
|
|
175
175
|
|
|
@@ -224,7 +224,7 @@ _Decision made as part of {{STORY_ID}}._
|
|
|
224
224
|
```markdown
|
|
225
225
|
# {{TITLE}} Guide
|
|
226
226
|
|
|
227
|
-
> **EN** | [PT](../pt/guides/{{FILENAME}})
|
|
227
|
+
> **EN** | [PT](../pt/guides/{{FILENAME}})
|
|
228
228
|
|
|
229
229
|
---
|
|
230
230
|
|
|
@@ -311,7 +311,7 @@ _Last Updated: {{DATE}} | SINAPSE Framework Team_
|
|
|
311
311
|
```markdown
|
|
312
312
|
# {{COMPONENT}} Reference
|
|
313
313
|
|
|
314
|
-
> **EN** | [PT](../pt/reference/{{FILENAME}})
|
|
314
|
+
> **EN** | [PT](../pt/reference/{{FILENAME}})
|
|
315
315
|
|
|
316
316
|
---
|
|
317
317
|
|
|
@@ -396,7 +396,7 @@ docs/
|
|
|
396
396
|
Always include the language navigation header:
|
|
397
397
|
|
|
398
398
|
```markdown
|
|
399
|
-
> **EN** | [PT](../pt/path/file.md)
|
|
399
|
+
> **EN** | [PT](../pt/path/file.md)
|
|
400
400
|
```
|
|
401
401
|
|
|
402
402
|
### Translation Notes
|
|
@@ -445,7 +445,7 @@ Always include the language navigation header:
|
|
|
445
445
|
```markdown
|
|
446
446
|
# Creating Custom Agents
|
|
447
447
|
|
|
448
|
-
> **EN** | [PT](../pt/guides/creating-agents.md)
|
|
448
|
+
> **EN** | [PT](../pt/guides/creating-agents.md)
|
|
449
449
|
|
|
450
450
|
---
|
|
451
451
|
|
|
@@ -54,6 +54,7 @@ function globToRegex(glob) {
|
|
|
54
54
|
pattern = pattern.replace(/\*/g, '[^/]+');
|
|
55
55
|
|
|
56
56
|
// 4. Restore ** placeholder to any-depth matcher
|
|
57
|
+
// eslint-disable-next-line no-control-regex -- internal placeholder char (set above), never user input
|
|
57
58
|
pattern = pattern.replace(/\u0000/g, '.+');
|
|
58
59
|
|
|
59
60
|
// If pattern ends with .+ (was **), match prefix
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* staged-protected-files-guard — blocks a commit that DELETES (or untracks) a
|
|
6
|
+
* protected, committed-but-critical framework file.
|
|
7
|
+
*
|
|
8
|
+
* Why: on 2026-06-20 a "snapshot migracao notebook" sweep (`git add -A`) untracked
|
|
9
|
+
* `.sinapse-ai/core/registry/service-registry.json` (the committed registry drift
|
|
10
|
+
* detector, ~12k lines), bundled it with unrelated work, and pushed it. The
|
|
11
|
+
* framework-boundary guard is a no-op in contributor mode
|
|
12
|
+
* (boundary.frameworkProtection=false), so nothing stopped the deletion. This guard
|
|
13
|
+
* is ALWAYS on and narrowly targets that class of damage — it never touches normal
|
|
14
|
+
* edits, only the removal of a curated set of protected paths.
|
|
15
|
+
*
|
|
16
|
+
* Intentional removal (done in a story) bypasses with: git commit --no-verify
|
|
17
|
+
*
|
|
18
|
+
* Self-contained: Node built-ins + `git` only (matches the other lib guards so it
|
|
19
|
+
* bundles into <hooksDir>/lib/ with no extra deps).
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
const { spawnSync } = require('child_process');
|
|
23
|
+
|
|
24
|
+
// Curated, high-signal list. Keep small to guarantee zero false positives on
|
|
25
|
+
// normal work. These files are committed on purpose and must never be removed by
|
|
26
|
+
// an automated sweep without an explicit story.
|
|
27
|
+
const PROTECTED = ['.sinapse-ai/core/registry/service-registry.json'];
|
|
28
|
+
|
|
29
|
+
function stagedDeletions() {
|
|
30
|
+
// --no-renames forces a rename-away of a protected file to surface as a real
|
|
31
|
+
// deletion (D) of the old path, so moving the file out also trips the guard.
|
|
32
|
+
const res = spawnSync('git', ['diff', '--cached', '--name-status', '--no-renames'], {
|
|
33
|
+
encoding: 'utf8',
|
|
34
|
+
});
|
|
35
|
+
if (!res || res.status !== 0 || typeof res.stdout !== 'string') return [];
|
|
36
|
+
const deleted = [];
|
|
37
|
+
for (const line of res.stdout.split('\n')) {
|
|
38
|
+
if (!line) continue;
|
|
39
|
+
const parts = line.split('\t');
|
|
40
|
+
const status = parts[0];
|
|
41
|
+
const file = (parts[parts.length - 1] || '').replace(/\\/g, '/');
|
|
42
|
+
if (status === 'D') deleted.push(file);
|
|
43
|
+
}
|
|
44
|
+
return deleted;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const offenders = stagedDeletions().filter((f) => PROTECTED.includes(f));
|
|
48
|
+
|
|
49
|
+
if (offenders.length > 0) {
|
|
50
|
+
process.stderr.write(
|
|
51
|
+
'SINAPSE Protected Files: blocking commit — it deletes/untracks a protected file:\n',
|
|
52
|
+
);
|
|
53
|
+
for (const f of offenders) process.stderr.write(' - ' + f + '\n');
|
|
54
|
+
process.stderr.write(
|
|
55
|
+
'\nThese files are committed on purpose (e.g. service-registry.json is the registry\n' +
|
|
56
|
+
'drift detector). They must not be removed by an automated sweep (git add -A) or a\n' +
|
|
57
|
+
'machine-migration snapshot. If this removal is intentional, do it in a story and\n' +
|
|
58
|
+
'bypass once with: git commit --no-verify\n',
|
|
59
|
+
);
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
process.exit(0);
|
|
@@ -11,12 +11,14 @@ const projectRoot = process.cwd();
|
|
|
11
11
|
const libDir = path.join(__dirname, 'lib');
|
|
12
12
|
|
|
13
13
|
// --- 1-3. SINAPSE staged guards (each fail-CLOSED) ---------------------------
|
|
14
|
-
// Order: secret scan,
|
|
14
|
+
// Order: secret scan, destructive-SQL guard, framework-boundary guard, then
|
|
15
|
+
// protected-files guard (always-on anti-sweep; does NOT respect frameworkProtection).
|
|
15
16
|
// framework-guard self-disables when boundary.frameworkProtection is false.
|
|
16
17
|
const GUARDS = [
|
|
17
18
|
{ file: 'staged-secret-scan.js', label: 'Secret Scan' },
|
|
18
19
|
{ file: 'staged-sql-guard.js', label: 'SQL Guard' },
|
|
19
20
|
{ file: 'framework-guard.js', label: 'Framework Boundary' },
|
|
21
|
+
{ file: 'staged-protected-files-guard.js', label: 'Protected Files' },
|
|
20
22
|
];
|
|
21
23
|
|
|
22
24
|
for (const guard of GUARDS) {
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type declarations for the SINAPSE programmatic API (CommonJS + ESM entry points).
|
|
3
|
+
*
|
|
4
|
+
* The underlying modules are authored in JavaScript, so these declarations expose
|
|
5
|
+
* the public constructors only — enough for `import { MetaAgent } from 'sinapse-ai'`
|
|
6
|
+
* to resolve. Member signatures are intentionally permissive (the JS implementation
|
|
7
|
+
* is the source of truth); this file does NOT fabricate detailed types it cannot
|
|
8
|
+
* guarantee. The framework is CLI-first; the programmatic API is a secondary surface.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/** A JS class/constructor exposed by the framework, with an unconstrained surface. */
|
|
12
|
+
type FrameworkConstructor = new (...args: unknown[]) => unknown;
|
|
13
|
+
|
|
14
|
+
export const MetaAgent: FrameworkConstructor;
|
|
15
|
+
export const TaskManager: FrameworkConstructor;
|
|
16
|
+
export const ElicitationEngine: FrameworkConstructor;
|
|
17
|
+
export const TemplateEngine: FrameworkConstructor;
|
|
18
|
+
export const ComponentSearch: FrameworkConstructor;
|
|
19
|
+
export const DependencyAnalyzer: FrameworkConstructor;
|
|
@@ -35,6 +35,18 @@ const DATA_DIR = path.join(ROOT_DIR, 'development', 'data');
|
|
|
35
35
|
const UTILS_DIR = path.join(ROOT_DIR, 'development', 'utils');
|
|
36
36
|
const WORKFLOWS_DIR = path.join(ROOT_DIR, 'development', 'workflows');
|
|
37
37
|
const SCRIPTS_DIR = path.join(ROOT_DIR, 'development', 'scripts');
|
|
38
|
+
// Additional canonical homes — the framework stores agent artifacts across
|
|
39
|
+
// development/, product/, data/ and infrastructure/, not only development/.
|
|
40
|
+
const KNOWLEDGE_BASE_DIR = path.join(ROOT_DIR, 'development', 'knowledge-base');
|
|
41
|
+
const PRODUCT_TEMPLATES_DIR = path.join(ROOT_DIR, 'product', 'templates');
|
|
42
|
+
const PRODUCT_CHECKLISTS_DIR = path.join(ROOT_DIR, 'product', 'checklists');
|
|
43
|
+
const PRODUCT_DATA_DIR = path.join(ROOT_DIR, 'product', 'data');
|
|
44
|
+
const ROOT_DATA_DIR = path.join(ROOT_DIR, 'data');
|
|
45
|
+
const INFRA_SCRIPTS_DIR = path.join(ROOT_DIR, 'infrastructure', 'scripts');
|
|
46
|
+
const INFRA_SCHEMAS_DIR = path.join(ROOT_DIR, 'infrastructure', 'schemas');
|
|
47
|
+
const SCHEMAS_DIR = path.join(ROOT_DIR, 'schemas');
|
|
48
|
+
const CORE_EXECUTION_DIR = path.join(ROOT_DIR, 'core', 'execution');
|
|
49
|
+
const CORE_MEMORY_DIR = path.join(ROOT_DIR, 'core', 'memory');
|
|
38
50
|
|
|
39
51
|
// Commands that are allowed to be shared by multiple agents
|
|
40
52
|
// These are utility/infrastructure commands, not domain-specific
|
|
@@ -187,14 +199,18 @@ async function validateDependencies(agents) {
|
|
|
187
199
|
const errors = [];
|
|
188
200
|
const warnings = [];
|
|
189
201
|
|
|
202
|
+
// Each dependency type resolves against one or more candidate directories —
|
|
203
|
+
// an artifact is considered present if it exists in ANY of them.
|
|
190
204
|
const depDirs = {
|
|
191
|
-
tasks: TASKS_DIR,
|
|
192
|
-
templates: TEMPLATES_DIR,
|
|
193
|
-
checklists: CHECKLISTS_DIR,
|
|
194
|
-
data: DATA_DIR,
|
|
195
|
-
utils: UTILS_DIR,
|
|
196
|
-
workflows: WORKFLOWS_DIR,
|
|
197
|
-
scripts: SCRIPTS_DIR,
|
|
205
|
+
tasks: [TASKS_DIR],
|
|
206
|
+
templates: [TEMPLATES_DIR, PRODUCT_TEMPLATES_DIR],
|
|
207
|
+
checklists: [CHECKLISTS_DIR, PRODUCT_CHECKLISTS_DIR],
|
|
208
|
+
data: [DATA_DIR, ROOT_DATA_DIR, PRODUCT_DATA_DIR],
|
|
209
|
+
utils: [UTILS_DIR, SCRIPTS_DIR, INFRA_SCRIPTS_DIR, CORE_EXECUTION_DIR, CORE_MEMORY_DIR],
|
|
210
|
+
workflows: [WORKFLOWS_DIR],
|
|
211
|
+
scripts: [SCRIPTS_DIR, INFRA_SCRIPTS_DIR, CORE_EXECUTION_DIR, CORE_MEMORY_DIR],
|
|
212
|
+
knowledge_bases: [KNOWLEDGE_BASE_DIR],
|
|
213
|
+
schemas: [SCHEMAS_DIR, INFRA_SCHEMAS_DIR],
|
|
198
214
|
};
|
|
199
215
|
|
|
200
216
|
// Dependency types that are not file-based (external tools, integrations)
|
|
@@ -208,8 +224,8 @@ async function validateDependencies(agents) {
|
|
|
208
224
|
if (skipDepTypes.has(depType)) continue;
|
|
209
225
|
if (!Array.isArray(depList)) continue;
|
|
210
226
|
|
|
211
|
-
const
|
|
212
|
-
if (!
|
|
227
|
+
const candidateDirs = depDirs[depType];
|
|
228
|
+
if (!candidateDirs) {
|
|
213
229
|
warnings.push({
|
|
214
230
|
type: 'UNKNOWN_DEP_TYPE',
|
|
215
231
|
agent: agent.id,
|
|
@@ -219,9 +235,23 @@ async function validateDependencies(agents) {
|
|
|
219
235
|
continue;
|
|
220
236
|
}
|
|
221
237
|
|
|
222
|
-
for (const
|
|
223
|
-
|
|
224
|
-
|
|
238
|
+
for (const depFile2 of depList) {
|
|
239
|
+
// Bare references (no extension) may be listed without their suffix —
|
|
240
|
+
// try the common framework extensions before declaring them missing.
|
|
241
|
+
const extCandidates = path.extname(depFile2)
|
|
242
|
+
? ['']
|
|
243
|
+
: ['', '.js', '.cjs', '.md', '.yaml', '.yml'];
|
|
244
|
+
|
|
245
|
+
let exists = false;
|
|
246
|
+
for (const dir of candidateDirs) {
|
|
247
|
+
for (const ext of extCandidates) {
|
|
248
|
+
if (await fileExists(path.join(dir, depFile2 + ext))) {
|
|
249
|
+
exists = true;
|
|
250
|
+
break;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
if (exists) break;
|
|
254
|
+
}
|
|
225
255
|
|
|
226
256
|
if (!exists) {
|
|
227
257
|
// Missing dependencies are warnings, not errors (pre-existing technical debt)
|
|
@@ -229,10 +259,10 @@ async function validateDependencies(agents) {
|
|
|
229
259
|
type: 'MISSING_DEPENDENCY',
|
|
230
260
|
agent: agent.id,
|
|
231
261
|
depType,
|
|
232
|
-
depFile,
|
|
233
|
-
expectedPath:
|
|
234
|
-
message: `Missing dependency: @${agent.id} → ${depType}/${
|
|
235
|
-
suggestion: `Create the file
|
|
262
|
+
depFile: depFile2,
|
|
263
|
+
expectedPath: path.join(candidateDirs[0], depFile2),
|
|
264
|
+
message: `Missing dependency: @${agent.id} → ${depType}/${depFile2}`,
|
|
265
|
+
suggestion: `Create the file under one of [${candidateDirs.join(', ')}] or remove from agent dependencies.`,
|
|
236
266
|
});
|
|
237
267
|
}
|
|
238
268
|
}
|