sinapse-ai 1.12.2 → 1.14.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/CLAUDE.md +2 -2
- package/.claude/rules/agent-memory-imports.md +4 -0
- package/.sinapse-ai/cli/commands/pro/index.js +8 -48
- package/.sinapse-ai/constitution.md +6 -2
- package/.sinapse-ai/data/entity-registry.yaml +63 -429
- package/.sinapse-ai/development/agents/analyst/MEMORY.md +19 -0
- package/.sinapse-ai/development/agents/architect/MEMORY.md +52 -0
- package/.sinapse-ai/development/agents/data-engineer/MEMORY.md +55 -0
- package/.sinapse-ai/development/agents/developer/MEMORY.md +53 -0
- package/.sinapse-ai/development/agents/devops/MEMORY.md +56 -0
- package/.sinapse-ai/development/agents/product-lead/MEMORY.md +53 -0
- package/.sinapse-ai/development/agents/project-lead/MEMORY.md +53 -0
- package/.sinapse-ai/development/agents/quality-gate/MEMORY.md +52 -0
- package/.sinapse-ai/development/agents/snps-orqx.md +15 -0
- package/.sinapse-ai/development/agents/sprint-lead/MEMORY.md +53 -0
- package/.sinapse-ai/development/agents/squad-creator.md +15 -0
- package/.sinapse-ai/development/agents/ux/MEMORY.md +21 -0
- package/.sinapse-ai/development/templates/chrome-brain/knowledge-base/chrome-brain.md +2 -2
- package/.sinapse-ai/infrastructure/scripts/ide-sync/index.js +15 -0
- package/.sinapse-ai/infrastructure/scripts/validate-agents.js +159 -8
- package/.sinapse-ai/install-manifest.yaml +16 -152
- package/AGENTS.md +13 -2
- package/CHANGELOG.md +135 -3
- package/README.en.md +1 -1
- package/README.md +6 -26
- package/bin/cli.js +2 -7
- package/bin/commands/install.js +19 -257
- package/bin/commands/update.js +18 -78
- package/bin/lib/command-generator.js +261 -0
- package/bin/lib/prompts.js +2 -65
- package/bin/modules/chrome-brain-installer.js +2 -1
- package/bin/postinstall.js +6 -6
- package/docs/getting-started.md +0 -1
- package/docs/pt/getting-started.md +1 -1
- package/docs/security/dependabot-triage.md +17 -17
- package/package.json +6 -3
- package/packages/installer/src/wizard/i18n.js +3 -204
- package/packages/installer/src/wizard/index.js +1 -1
- package/packages/installer/src/wizard/questions.js +5 -368
- package/packages/installer/src/wizard/wizard.js +0 -9
- package/scripts/generate-install-manifest.js +6 -0
- package/scripts/validate-changelog-tags.js +97 -0
- package/scripts/validate-no-personal-leaks.js +184 -28
- package/scripts/validate-schemas.js +55 -10
- package/scripts/validate-story-meta.js +25 -12
- package/squads/claude-code-mastery/agents/claude-mastery-chief.md +15 -1
- package/squads/claude-code-mastery/agents/config-engineer.md +15 -0
- package/squads/claude-code-mastery/agents/hooks-architect.md +27 -20
- package/squads/claude-code-mastery/agents/mcp-integrator.md +15 -0
- package/squads/claude-code-mastery/agents/project-integrator.md +15 -0
- package/squads/claude-code-mastery/agents/roadmap-sentinel.md +15 -0
- package/squads/claude-code-mastery/agents/skill-craftsman.md +15 -0
- package/squads/claude-code-mastery/agents/swarm-orqx.md +15 -0
- package/squads/claude-code-mastery/tasks/audit-setup.md +1 -1
- package/squads/squad-animations/agents/animation-interpreter.md +15 -0
- package/squads/squad-animations/agents/animation-performance-engineer.md +15 -0
- package/squads/squad-animations/agents/animations-orqx.md +13 -0
- package/squads/squad-animations/agents/css-motion-artist.md +15 -0
- package/squads/squad-animations/agents/generative-particle-engineer.md +15 -0
- package/squads/squad-animations/agents/motion-choreographer.md +15 -0
- package/squads/squad-animations/agents/scroll-narrative-engineer.md +15 -0
- package/squads/squad-animations/agents/shader-artist.md +15 -0
- package/squads/squad-animations/agents/threejs-architect.md +15 -0
- package/squads/squad-brand/agents/brand-archetype-strategist.md +13 -0
- package/squads/squad-brand/agents/brand-auditor.md +15 -0
- package/squads/squad-brand/agents/brand-collateral-designer.md +15 -0
- package/squads/squad-brand/agents/brand-compiler.md +13 -0
- package/squads/squad-brand/agents/brand-creative-engineer.md +15 -0
- package/squads/squad-brand/agents/brand-culture-architect.md +15 -0
- package/squads/squad-brand/agents/brand-growth-strategist.md +15 -0
- package/squads/squad-brand/agents/brand-identity-designer.md +15 -0
- package/squads/squad-brand/agents/brand-motion-vfx.md +15 -0
- package/squads/squad-brand/agents/brand-naming-specialist.md +15 -0
- package/squads/squad-brand/agents/brand-orqx.md +13 -0
- package/squads/squad-brand/agents/brand-positioning-strategist.md +15 -0
- package/squads/squad-brand/agents/brand-sonic-designer.md +15 -0
- package/squads/squad-brand/agents/brand-strategist.md +15 -0
- package/squads/squad-brand/agents/brand-system-architect.md +15 -0
- package/squads/squad-cloning/agents/agent-forger.md +15 -0
- package/squads/squad-cloning/agents/cloning-orqx.md +15 -0
- package/squads/squad-cloning/agents/cognitive-extractor.md +15 -0
- package/squads/squad-cloning/agents/content-capturer.md +15 -0
- package/squads/squad-cloning/agents/kb-architect.md +15 -0
- package/squads/squad-cloning/agents/mind-synthesizer.md +15 -0
- package/squads/squad-cloning/agents/sop-extractor.md +15 -0
- package/squads/squad-cloning/agents/source-hunter.md +13 -0
- package/squads/squad-cloning/agents/squad-assembler.md +15 -0
- package/squads/squad-commercial/agents/commercial-orqx.md +13 -0
- package/squads/squad-commercial/agents/cs-business-auditor.md +15 -0
- package/squads/squad-commercial/agents/cs-client-success.md +15 -0
- package/squads/squad-commercial/agents/cs-crm-specialist.md +15 -0
- package/squads/squad-commercial/agents/cs-funnel-architect.md +15 -0
- package/squads/squad-commercial/agents/cs-lead-generation-strategist.md +15 -0
- package/squads/squad-commercial/agents/cs-offer-designer.md +15 -0
- package/squads/squad-commercial/agents/cs-revops-analyst.md +15 -0
- package/squads/squad-commercial/agents/cs-sales-closer.md +13 -0
- package/squads/squad-commercial/agents/cs-sales-enablement.md +15 -0
- package/squads/squad-content/agents/content-analyst.md +13 -0
- package/squads/squad-content/agents/content-engineer.md +15 -0
- package/squads/squad-content/agents/content-governor.md +13 -0
- package/squads/squad-content/agents/content-orqx.md +13 -0
- package/squads/squad-content/agents/editorial-strategist.md +15 -0
- package/squads/squad-content/agents/platform-specialist.md +15 -0
- package/squads/squad-content/agents/signal-intelligence.md +13 -0
- package/squads/squad-copy/agents/ad-copywriter.md +13 -0
- package/squads/squad-copy/agents/brand-voice-writer.md +15 -0
- package/squads/squad-copy/agents/conversion-writer.md +13 -0
- package/squads/squad-copy/agents/copy-editor.md +15 -0
- package/squads/squad-copy/agents/copy-orqx.md +13 -0
- package/squads/squad-copy/agents/copy-strategist.md +15 -0
- package/squads/squad-copy/agents/direct-response-writer.md +15 -0
- package/squads/squad-copy/agents/email-sequence-strategist.md +15 -0
- package/squads/squad-copy/agents/funnel-copywriter.md +15 -0
- package/squads/squad-copy/agents/headline-specialist.md +13 -0
- package/squads/squad-copy/agents/long-form-writer.md +15 -0
- package/squads/squad-copy/agents/persuasion-psychologist.md +15 -0
- package/squads/squad-copy/agents/proof-architect.md +15 -0
- package/squads/squad-council/agents/brene-brown.md +13 -0
- package/squads/squad-council/agents/charlie-munger.md +13 -0
- package/squads/squad-council/agents/council-orqx.md +13 -0
- package/squads/squad-council/agents/derek-sivers.md +13 -0
- package/squads/squad-council/agents/naval-ravikant.md +13 -0
- package/squads/squad-council/agents/patrick-lencioni.md +15 -0
- package/squads/squad-council/agents/peter-thiel.md +13 -0
- package/squads/squad-council/agents/ray-dalio.md +13 -0
- package/squads/squad-council/agents/reid-hoffman.md +13 -0
- package/squads/squad-council/agents/simon-sinek.md +15 -0
- package/squads/squad-council/agents/yvon-chouinard.md +13 -0
- package/squads/squad-courses/agents/assessment-creator.md +15 -0
- package/squads/squad-courses/agents/content-writer.md +15 -0
- package/squads/squad-courses/agents/courses-orqx.md +15 -0
- package/squads/squad-courses/agents/curriculum-designer.md +15 -0
- package/squads/squad-courses/agents/launch-strategist.md +15 -0
- package/squads/squad-courses/agents/lesson-architect.md +15 -0
- package/squads/squad-courses/agents/production-director.md +13 -0
- package/squads/squad-courses/agents/slide-designer.md +15 -0
- package/squads/squad-cybersecurity/agents/cloud-security-engineer.md +15 -0
- package/squads/squad-cybersecurity/agents/compliance-officer.md +15 -0
- package/squads/squad-cybersecurity/agents/cyber-orqx.md +15 -0
- package/squads/squad-cybersecurity/agents/incident-responder.md +15 -0
- package/squads/squad-cybersecurity/agents/network-security-engineer.md +15 -0
- package/squads/squad-cybersecurity/agents/penetration-tester.md +15 -0
- package/squads/squad-cybersecurity/agents/soc-analyst.md +15 -0
- package/squads/squad-cybersecurity/agents/threat-analyst.md +15 -0
- package/squads/squad-design/agents/cro-persuasion.md +15 -0
- package/squads/squad-design/agents/design-orqx.md +13 -0
- package/squads/squad-design/agents/design-system.md +15 -0
- package/squads/squad-design/agents/dx-accessibility-specialist.md +15 -0
- package/squads/squad-design/agents/dx-design-system-architect.md +15 -0
- package/squads/squad-design/agents/dx-frontend-engineer.md +15 -0
- package/squads/squad-design/agents/dx-interaction-designer.md +15 -0
- package/squads/squad-design/agents/dx-performance-engineer.md +15 -0
- package/squads/squad-design/agents/dx-ui-designer.md +15 -0
- package/squads/squad-design/agents/dx-ux-strategist.md +15 -0
- package/squads/squad-design/agents/platform-aesthetic-director.md +15 -0
- package/squads/squad-design/agents/premium-packaging-strategist.md +15 -0
- package/squads/squad-design/agents/product-surface-director.md +15 -0
- package/squads/squad-design/agents/ux-designer.md +15 -0
- package/squads/squad-finance/agents/budget-controller.md +15 -0
- package/squads/squad-finance/agents/cost-optimizer.md +15 -0
- package/squads/squad-finance/agents/finance-orqx.md +15 -0
- package/squads/squad-finance/agents/fiscal-compliance-br.md +15 -0
- package/squads/squad-finance/agents/forecast-strategist.md +15 -0
- package/squads/squad-finance/agents/pricing-strategist.md +15 -0
- package/squads/squad-finance/agents/profitability-analyst.md +15 -0
- package/squads/squad-finance/agents/revenue-analyst.md +15 -0
- package/squads/squad-growth/agents/ga-analytics-engineer.md +15 -0
- package/squads/squad-growth/agents/ga-campaign-analyst.md +15 -0
- package/squads/squad-growth/agents/ga-cro-specialist.md +15 -0
- package/squads/squad-growth/agents/ga-data-analyst.md +13 -0
- package/squads/squad-growth/agents/ga-growth-hacker.md +15 -0
- package/squads/squad-growth/agents/ga-seo-strategist.md +15 -0
- package/squads/squad-growth/agents/growth-orqx.md +15 -0
- package/squads/squad-paidmedia/agents/campaign-analyst.md +15 -0
- package/squads/squad-paidmedia/agents/creative-strategist.md +15 -0
- package/squads/squad-paidmedia/agents/cro-specialist.md +15 -0
- package/squads/squad-paidmedia/agents/google-ads-specialist.md +15 -0
- package/squads/squad-paidmedia/agents/meta-ads-specialist.md +15 -0
- package/squads/squad-paidmedia/agents/paidmedia-orqx.md +15 -0
- package/squads/squad-paidmedia/agents/performance-engineer.md +15 -0
- package/squads/squad-paidmedia/agents/pm-creative-performance-analyst.md +15 -0
- package/squads/squad-paidmedia/agents/pm-youtube-ads-specialist.md +15 -0
- package/squads/squad-product/agents/product-orqx.md +13 -1
- package/squads/squad-product/agents/ps-client-product-manager.md +13 -1
- package/squads/squad-product/agents/ps-delivery-manager.md +13 -1
- package/squads/squad-product/agents/ps-discovery-lead.md +15 -1
- package/squads/squad-product/agents/ps-product-analyst.md +15 -1
- package/squads/squad-product/agents/ps-product-ops-specialist.md +15 -1
- package/squads/squad-product/agents/ps-product-strategist.md +15 -1
- package/squads/squad-research/agents/audience-intelligence.md +15 -0
- package/squads/squad-research/agents/competitive-intelligence.md +15 -0
- package/squads/squad-research/agents/data-synthesizer.md +15 -0
- package/squads/squad-research/agents/deep-researcher.md +15 -0
- package/squads/squad-research/agents/market-analyst.md +15 -0
- package/squads/squad-research/agents/research-orqx.md +15 -0
- package/squads/squad-research/agents/trend-forecaster.md +15 -0
- package/squads/squad-storytelling/agents/blake-snyder.md +13 -0
- package/squads/squad-storytelling/agents/dan-harmon.md +13 -0
- package/squads/squad-storytelling/agents/joseph-campbell.md +13 -0
- package/squads/squad-storytelling/agents/keith-johnstone.md +13 -0
- package/squads/squad-storytelling/agents/kindra-hall.md +15 -0
- package/squads/squad-storytelling/agents/marshall-ganz.md +15 -0
- package/squads/squad-storytelling/agents/nancy-duarte.md +15 -0
- package/squads/squad-storytelling/agents/oren-klaff.md +15 -0
- package/squads/squad-storytelling/agents/park-howell.md +13 -0
- package/squads/squad-storytelling/agents/storytelling-orqx.md +13 -0
- package/.sinapse-ai/core/grounding/README.md +0 -83
- package/.sinapse-ai/core/grounding/brand.cjs +0 -29
- package/.sinapse-ai/core/grounding/config-loader.cjs +0 -52
- package/.sinapse-ai/core/grounding/design-system.cjs +0 -29
- package/.sinapse-ai/core/grounding/vault.cjs +0 -36
- package/.sinapse-ai/development/scripts/approval-workflow.js +0 -643
- package/.sinapse-ai/development/scripts/backup-manager.js +0 -607
- package/.sinapse-ai/development/scripts/branch-manager.js +0 -390
- package/.sinapse-ai/development/scripts/code-quality-improver.js +0 -1329
- package/.sinapse-ai/development/scripts/commit-message-generator.js +0 -850
- package/.sinapse-ai/development/scripts/conflict-resolver.js +0 -675
- package/.sinapse-ai/development/scripts/dependency-analyzer.js +0 -638
- package/.sinapse-ai/development/scripts/diff-generator.js +0 -352
- package/.sinapse-ai/development/scripts/git-wrapper.js +0 -462
- package/.sinapse-ai/development/scripts/modification-validator.js +0 -555
- package/.sinapse-ai/development/scripts/performance-analyzer.js +0 -758
- package/.sinapse-ai/development/scripts/refactoring-suggester.js +0 -1148
- package/.sinapse-ai/development/scripts/rollback-handler.js +0 -531
- package/.sinapse-ai/development/scripts/security-checker.js +0 -359
- package/.sinapse-ai/development/scripts/template-engine.js +0 -240
- package/.sinapse-ai/development/scripts/template-validator.js +0 -279
- package/.sinapse-ai/development/scripts/test-generator.js +0 -844
- package/.sinapse-ai/development/scripts/transaction-manager.js +0 -590
- package/.sinapse-ai/development/scripts/yaml-validator.js +0 -397
- package/.sinapse-ai/hooks/sinapse-brand-grounding.cjs +0 -162
- package/.sinapse-ai/hooks/sinapse-ds-grounding.cjs +0 -211
- package/.sinapse-ai/hooks/sinapse-vault-grounding.cjs +0 -194
- package/bin/lib/register-grounding-hooks.js +0 -145
- package/docs/guides/agents/traces/execution-traces.zip +0 -0
- package/docs/guides/grounding-setup.md +0 -154
- package/docs/guides/workflows/SINAPSE-WORKFLOWS.zip +0 -0
- package/packages/installer/src/pro/pro-scaffolder.js +0 -449
- package/packages/installer/src/wizard/grounding-config.js +0 -131
- package/packages/installer/src/wizard/pro-setup.js +0 -1439
- package/packages/installer/templates/README.md +0 -16
- package/packages/installer/templates/brand-routing.example.json +0 -12
- package/packages/installer/templates/ds-routing.example.json +0 -12
- package/packages/installer/templates/vault-routing.example.json +0 -12
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
# Grounding Setup Guide
|
|
2
|
-
|
|
3
|
-
> Story 10.47 — opt-in BYO (Bring Your Own) vault, design system, brand.
|
|
4
|
-
|
|
5
|
-
## What is grounding?
|
|
6
|
-
|
|
7
|
-
Most agent frameworks assume the LLM already knows everything about your
|
|
8
|
-
business. SINAPSE-AI assumes the opposite: it ships three optional
|
|
9
|
-
**grounding** channels that connect agents to your real context.
|
|
10
|
-
|
|
11
|
-
| Channel | Purpose | Disabled = |
|
|
12
|
-
|---------|---------|------------|
|
|
13
|
-
| **Vault** | Inject context from your markdown notes vault into agent prompts | Hook is a no-op |
|
|
14
|
-
| **Design System** | Resolve tokens / components / layouts from your DS source-of-truth so agents stop generating generic `max-w-7xl shadcn-default` UIs | Hook is a no-op (high-quality fallback principles still apply at the framework level) |
|
|
15
|
-
| **Brand** | Read your brandbook (positioning, MVV, tone-of-voice) so copy and UX nasce aligned to your brand | Hook is a no-op |
|
|
16
|
-
|
|
17
|
-
All three are independent. Configure the ones that matter, skip the rest.
|
|
18
|
-
|
|
19
|
-
## When does each one make sense?
|
|
20
|
-
|
|
21
|
-
- **Enable vault grounding** if you keep a structured markdown knowledge base with notes about your projects, clients, decisions, or domain. Agents reference these instead of inventing.
|
|
22
|
-
- **Enable design system grounding** if your project has a defined visual identity (tokens, components, layout primitives). Without it, design agents fall back to generic principles — still good, but not yours.
|
|
23
|
-
- **Enable brand grounding** if you have a brandbook with positioning, MVV, tone-of-voice. Especially valuable for copy + storytelling squads.
|
|
24
|
-
- **Skip all three** if you're prototyping or evaluating. The framework defaults are high-quality enough to ship; you can come back later via `--reconfigure`.
|
|
25
|
-
|
|
26
|
-
## How to configure
|
|
27
|
-
|
|
28
|
-
### Option A — interactive wizard (recommended)
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
npx sinapse-ai install # first run, prompts every section
|
|
32
|
-
npx sinapse-ai install --reconfigure # re-run prompts on an existing install
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
The wizard asks one question per section. Each accepts a path or empty
|
|
36
|
-
(skip). Empty answers leave the section disabled and the corresponding
|
|
37
|
-
shipped hook stays a complete no-op.
|
|
38
|
-
|
|
39
|
-
### Option B — manual edit
|
|
40
|
-
|
|
41
|
-
The wizard writes to `~/.claude/sinapse-ai-config.yaml`. You can create or
|
|
42
|
-
edit this file directly using the schema below.
|
|
43
|
-
|
|
44
|
-
```yaml
|
|
45
|
-
version: "1"
|
|
46
|
-
grounding:
|
|
47
|
-
vault:
|
|
48
|
-
enabled: true
|
|
49
|
-
path: "/absolute/path/to/your/vault"
|
|
50
|
-
domains: [] # optional: list of domain tags to filter on
|
|
51
|
-
designSystem:
|
|
52
|
-
enabled: true
|
|
53
|
-
profileName: "my-product-ds"
|
|
54
|
-
rootPath: "/absolute/path/to/your/design-system"
|
|
55
|
-
brand:
|
|
56
|
-
enabled: false
|
|
57
|
-
profileName: ""
|
|
58
|
-
brandbookPath: ""
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
Generic JSON examples for copy-paste reference live in
|
|
62
|
-
`packages/installer/templates/`:
|
|
63
|
-
|
|
64
|
-
- `vault-routing.example.json`
|
|
65
|
-
- `ds-routing.example.json`
|
|
66
|
-
- `brand-routing.example.json`
|
|
67
|
-
|
|
68
|
-
## How fallback works
|
|
69
|
-
|
|
70
|
-
When a section is disabled (or the YAML file is absent altogether), the
|
|
71
|
-
shipped grounding hook for that section returns `null`. Agents proceed
|
|
72
|
-
without that channel of context. There are **no warnings, no errors, no
|
|
73
|
-
log noise** — only silence.
|
|
74
|
-
|
|
75
|
-
Design system grounding has an additional safety net: even with the hook
|
|
76
|
-
disabled, the framework's design-system rules still apply
|
|
77
|
-
high-quality fallback principles (no hardcoded `max-w-7xl`, fluid
|
|
78
|
-
typography, semantic tokens) so generated UIs do not collapse into
|
|
79
|
-
generic SaaS templates.
|
|
80
|
-
|
|
81
|
-
## Schema versioning
|
|
82
|
-
|
|
83
|
-
The top-level `version` field allows future migrations. Always check
|
|
84
|
-
`~/.claude/sinapse-ai-config.yaml` after a major SINAPSE-AI upgrade. If
|
|
85
|
-
the schema bumps, the installer will migrate it on the next run; manual
|
|
86
|
-
edits should preserve unknown keys.
|
|
87
|
-
|
|
88
|
-
## Privacy
|
|
89
|
-
|
|
90
|
-
Paths configured here stay local on your machine. SINAPSE-AI does not
|
|
91
|
-
ship vault contents anywhere. The grounding hooks read locally and
|
|
92
|
-
inject only what the agent's working context requires for the task at
|
|
93
|
-
hand.
|
|
94
|
-
|
|
95
|
-
## How the hooks work (Story GA-1.6)
|
|
96
|
-
|
|
97
|
-
After running `sinapse-ai install` (or `update`), three executable hooks
|
|
98
|
-
are placed in `~/.sinapse/hooks/` and registered in
|
|
99
|
-
`~/.claude/settings.json` under `UserPromptSubmit`:
|
|
100
|
-
|
|
101
|
-
| Hook | Reads from config | Activates when | Injects |
|
|
102
|
-
|------|-------------------|---------------|---------|
|
|
103
|
-
| `sinapse-vault-grounding.cjs` | `grounding.vault` | Any prompt ≥ 10 chars | `<vault-grounding>` with up to 5 most-recent vault notes (500 chars each, 6000 total cap) |
|
|
104
|
-
| `sinapse-ds-grounding.cjs` | `grounding.designSystem` | Prompt contains UI keywords (PT + EN: `pagina`, `componente`, `layout`, `react`, `tailwind`, etc.) | `<ds-grounding>` with the first 3000 chars of the DS law file (`0.0-guidelines.md`, `principles.md`, `README.md`, …) |
|
|
105
|
-
| `sinapse-brand-grounding.cjs` | `grounding.brand` | Any prompt ≥ 10 chars | `<brand-grounding>` with the first 2000 chars of the brandbook |
|
|
106
|
-
|
|
107
|
-
All three follow the same contract:
|
|
108
|
-
|
|
109
|
-
- **Fail-open** — any error (missing config, malformed YAML, unreadable
|
|
110
|
-
file, timeout) exits 0 silently. Claude Code never sees a broken
|
|
111
|
-
prompt because grounding misfired.
|
|
112
|
-
- **Anti-double-injection** — if the prompt already contains the
|
|
113
|
-
matching tag (e.g. another tool or a previous hook ran), the hook is
|
|
114
|
-
a no-op.
|
|
115
|
-
- **Timeout 3500 ms** — each hook short-circuits on its own timer so a
|
|
116
|
-
slow filesystem can't stall agent activation.
|
|
117
|
-
- **Size caps** — vault 6000 / DS 3000 / brand 2000 chars. Truncated
|
|
118
|
-
with a `[...truncated...]` marker.
|
|
119
|
-
|
|
120
|
-
### Coexistence with personal hooks
|
|
121
|
-
|
|
122
|
-
If you also maintain personal global hooks (e.g.
|
|
123
|
-
`~/.claude/hooks/vault-grounding.cjs` reading from
|
|
124
|
-
`~/.claude/vault-routing.json`), the framework hooks are
|
|
125
|
-
**file-name-prefixed** with `sinapse-` and **read a different config
|
|
126
|
-
file** (`~/.claude/sinapse-ai-config.yaml`). Both can run side-by-side
|
|
127
|
-
without conflict — the fail-open guarantee makes any duplication
|
|
128
|
-
harmless.
|
|
129
|
-
|
|
130
|
-
### Disabling temporarily
|
|
131
|
-
|
|
132
|
-
Open `~/.claude/sinapse-ai-config.yaml` and set the section's
|
|
133
|
-
`enabled: false`. Re-running `sinapse-ai install --reconfigure` lets you
|
|
134
|
-
update paths interactively.
|
|
135
|
-
|
|
136
|
-
## What grounding does NOT do (today)
|
|
137
|
-
|
|
138
|
-
Story `10.47` shipped the **foundation** (schema, wizard, no-op library
|
|
139
|
-
hooks). Story `GA-1.6` (this entry) ships **executable hooks** that
|
|
140
|
-
inject real context. The concrete domain integration logic — parsing
|
|
141
|
-
note frontmatter, walking a deep DS token tree, reading a
|
|
142
|
-
brandbook PDF — still lands in follow-up stories per channel.
|
|
143
|
-
|
|
144
|
-
## Troubleshooting
|
|
145
|
-
|
|
146
|
-
| Symptom | Cause | Fix |
|
|
147
|
-
|---------|-------|-----|
|
|
148
|
-
| "Vault grounding configured" message but no notes injected | Concrete parser not yet shipped (out-of-scope for 10.47) | Wait for follow-up story, or open an issue if blocking |
|
|
149
|
-
| Hook errors during agent run | Should not happen — hooks short-circuit on any error | Check `~/.claude/sinapse-ai-config.yaml` is valid YAML; report issue if persistent |
|
|
150
|
-
| Wizard does not re-ask grounding questions | Upsert mode — already configured | Run with `--reconfigure` to re-prompt |
|
|
151
|
-
|
|
152
|
-
---
|
|
153
|
-
|
|
154
|
-
*See also:* [`README.md`](../../README.md), [`packages/installer/templates/README.md`](../../packages/installer/templates/README.md).
|
|
Binary file
|
|
@@ -1,449 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pro Content Scaffolder
|
|
3
|
-
*
|
|
4
|
-
* Copies premium content (squads, configs, feature registry) from
|
|
5
|
-
* node_modules/@sinapse-fullstack/pro/ into the user's project after
|
|
6
|
-
* license activation.
|
|
7
|
-
*
|
|
8
|
-
* @module packages/installer/src/pro/pro-scaffolder
|
|
9
|
-
* @story INS-3.1 — Implement Pro Content Scaffolder
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
'use strict';
|
|
13
|
-
|
|
14
|
-
const fs = require('fs-extra');
|
|
15
|
-
const path = require('path');
|
|
16
|
-
const yaml = require('js-yaml');
|
|
17
|
-
const { hashFileAsync, hashFilesMatchAsync } = require('../installer/file-hasher');
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Directories excluded from scaffolding (private/internal squads).
|
|
21
|
-
*/
|
|
22
|
-
const SCAFFOLD_EXCLUDES = [
|
|
23
|
-
'mmos-squad',
|
|
24
|
-
];
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Items to scaffold from pro package into user project.
|
|
28
|
-
* Each entry defines source (relative to proSourceDir) and dest (relative to targetDir).
|
|
29
|
-
*/
|
|
30
|
-
const SCAFFOLD_ITEMS = [
|
|
31
|
-
{
|
|
32
|
-
type: 'directory',
|
|
33
|
-
source: 'squads',
|
|
34
|
-
dest: 'squads',
|
|
35
|
-
description: 'Pro squads',
|
|
36
|
-
required: true,
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
type: 'file',
|
|
40
|
-
source: 'pro-config.yaml',
|
|
41
|
-
dest: path.join('.sinapse-ai', 'pro-config.yaml'),
|
|
42
|
-
description: 'Pro configuration',
|
|
43
|
-
required: true,
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
type: 'file',
|
|
47
|
-
source: 'feature-registry.yaml',
|
|
48
|
-
dest: path.join('.sinapse-ai', 'feature-registry.yaml'),
|
|
49
|
-
description: 'Feature registry',
|
|
50
|
-
required: false,
|
|
51
|
-
},
|
|
52
|
-
];
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Scaffold pro content into user project.
|
|
56
|
-
*
|
|
57
|
-
* @param {string} targetDir - Project root directory
|
|
58
|
-
* @param {string} proSourceDir - Path to pro package content (node_modules/@sinapse-fullstack/pro)
|
|
59
|
-
* @param {Object} [options={}] - Scaffold options
|
|
60
|
-
* @param {Function} [options.onProgress] - Progress callback ({item, status, message})
|
|
61
|
-
* @param {boolean} [options.force=false] - Force overwrite even if content exists
|
|
62
|
-
* @returns {Promise<Object>} Scaffold result with copiedFiles, warnings, manifest
|
|
63
|
-
*/
|
|
64
|
-
async function scaffoldProContent(targetDir, proSourceDir, options = {}) {
|
|
65
|
-
const { onProgress = null, force = false } = options;
|
|
66
|
-
|
|
67
|
-
const result = {
|
|
68
|
-
success: false,
|
|
69
|
-
copiedFiles: [],
|
|
70
|
-
skippedFiles: [],
|
|
71
|
-
warnings: [],
|
|
72
|
-
errors: [],
|
|
73
|
-
manifest: null,
|
|
74
|
-
versionInfo: null,
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
// Track files for rollback on partial failure
|
|
78
|
-
const rollbackFiles = [];
|
|
79
|
-
|
|
80
|
-
// Validate pro source exists
|
|
81
|
-
if (!await fs.pathExists(proSourceDir)) {
|
|
82
|
-
result.errors.push(
|
|
83
|
-
`Pro package not found at ${proSourceDir}. Run "npm install @sinapse-fullstack/pro" first.`,
|
|
84
|
-
);
|
|
85
|
-
return result;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
try {
|
|
89
|
-
for (const item of SCAFFOLD_ITEMS) {
|
|
90
|
-
const sourcePath = path.join(proSourceDir, item.source);
|
|
91
|
-
const destPath = path.join(targetDir, item.dest);
|
|
92
|
-
|
|
93
|
-
// Check source exists
|
|
94
|
-
if (!await fs.pathExists(sourcePath)) {
|
|
95
|
-
if (item.required) {
|
|
96
|
-
throw new Error(`Required pro content not found: ${item.source}`);
|
|
97
|
-
}
|
|
98
|
-
const warning = `${item.description} (${item.source}) not found in pro package — skipping`;
|
|
99
|
-
result.warnings.push(warning);
|
|
100
|
-
if (onProgress) {
|
|
101
|
-
onProgress({ item: item.source, status: 'warning', message: warning });
|
|
102
|
-
}
|
|
103
|
-
continue;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
if (item.type === 'directory') {
|
|
107
|
-
const copied = await scaffoldDirectory(sourcePath, destPath, { force, rollbackFiles, baseDir: targetDir });
|
|
108
|
-
result.copiedFiles.push(...copied.copiedFiles);
|
|
109
|
-
result.skippedFiles.push(...copied.skippedFiles);
|
|
110
|
-
} else {
|
|
111
|
-
const copied = await scaffoldFile(sourcePath, destPath, { force, rollbackFiles, baseDir: targetDir });
|
|
112
|
-
if (copied.skipped) {
|
|
113
|
-
result.skippedFiles.push(copied.relativePath);
|
|
114
|
-
} else {
|
|
115
|
-
result.copiedFiles.push(copied.relativePath);
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
if (onProgress) {
|
|
120
|
-
onProgress({ item: item.source, status: 'done', message: `${item.description} scaffolded` });
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// Merge pro-config into core-config
|
|
125
|
-
const merged = await mergeProConfig(targetDir);
|
|
126
|
-
if (merged && onProgress) {
|
|
127
|
-
onProgress({ item: 'pro-config', status: 'done', message: 'Pro config merged into core-config.yaml' });
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// Install squad agent commands to IDEs
|
|
131
|
-
const commandsResult = await installSquadCommands(targetDir);
|
|
132
|
-
if (commandsResult.installed > 0) {
|
|
133
|
-
result.copiedFiles.push(...commandsResult.files);
|
|
134
|
-
if (onProgress) {
|
|
135
|
-
onProgress({ item: 'squad-setup', status: 'done',
|
|
136
|
-
message: `${commandsResult.installed} squad agent commands installed` });
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// Generate pro-version.json (AC4)
|
|
141
|
-
const versionInfo = await generateProVersionJson(targetDir, proSourceDir, result.copiedFiles);
|
|
142
|
-
result.versionInfo = versionInfo;
|
|
143
|
-
result.copiedFiles.push('pro-version.json');
|
|
144
|
-
rollbackFiles.push(path.join(targetDir, 'pro-version.json'));
|
|
145
|
-
|
|
146
|
-
// Generate pro-installed-manifest.yaml (AC8)
|
|
147
|
-
const manifest = await generateInstalledManifest(targetDir, result.copiedFiles);
|
|
148
|
-
result.manifest = manifest;
|
|
149
|
-
result.copiedFiles.push('pro-installed-manifest.yaml');
|
|
150
|
-
rollbackFiles.push(path.join(targetDir, 'pro-installed-manifest.yaml'));
|
|
151
|
-
|
|
152
|
-
result.success = true;
|
|
153
|
-
|
|
154
|
-
} catch (error) {
|
|
155
|
-
result.errors.push(error.message);
|
|
156
|
-
|
|
157
|
-
// Rollback partially copied files (AC6)
|
|
158
|
-
const rollbackResult = await rollbackScaffold(rollbackFiles);
|
|
159
|
-
if (rollbackResult.errors.length > 0) {
|
|
160
|
-
result.errors.push(`Rollback errors: ${rollbackResult.errors.join(', ')}`);
|
|
161
|
-
}
|
|
162
|
-
result.warnings.push(
|
|
163
|
-
`Scaffolding failed: ${error.message}. ${rollbackResult.removed} files cleaned up.`,
|
|
164
|
-
);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
return result;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Scaffold a directory recursively with idempotency checks.
|
|
172
|
-
*
|
|
173
|
-
* @param {string} sourceDir - Source directory
|
|
174
|
-
* @param {string} destDir - Destination directory
|
|
175
|
-
* @param {Object} options - Options
|
|
176
|
-
* @returns {Promise<Object>} Result with copiedFiles and skippedFiles
|
|
177
|
-
*/
|
|
178
|
-
async function scaffoldDirectory(sourceDir, destDir, options = {}) {
|
|
179
|
-
const { force = false, rollbackFiles = [], baseDir } = options;
|
|
180
|
-
const copiedFiles = [];
|
|
181
|
-
const skippedFiles = [];
|
|
182
|
-
|
|
183
|
-
await fs.ensureDir(destDir);
|
|
184
|
-
|
|
185
|
-
const items = await fs.readdir(sourceDir, { withFileTypes: true });
|
|
186
|
-
|
|
187
|
-
for (const item of items) {
|
|
188
|
-
// Skip excluded directories (e.g. private squads)
|
|
189
|
-
if (SCAFFOLD_EXCLUDES.includes(item.name)) {
|
|
190
|
-
continue;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
const sourcePath = path.join(sourceDir, item.name);
|
|
194
|
-
const destPath = path.join(destDir, item.name);
|
|
195
|
-
|
|
196
|
-
if (item.isDirectory()) {
|
|
197
|
-
const sub = await scaffoldDirectory(sourcePath, destPath, options);
|
|
198
|
-
copiedFiles.push(...sub.copiedFiles);
|
|
199
|
-
skippedFiles.push(...sub.skippedFiles);
|
|
200
|
-
} else {
|
|
201
|
-
const result = await scaffoldFile(sourcePath, destPath, { force, rollbackFiles, baseDir });
|
|
202
|
-
if (result.skipped) {
|
|
203
|
-
skippedFiles.push(result.relativePath);
|
|
204
|
-
} else {
|
|
205
|
-
copiedFiles.push(result.relativePath);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
return { copiedFiles, skippedFiles };
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* Scaffold a single file with idempotency (AC5).
|
|
215
|
-
* If dest exists and has identical hash, skip. If user modified, skip (preserve).
|
|
216
|
-
*
|
|
217
|
-
* @param {string} sourcePath - Source file path
|
|
218
|
-
* @param {string} destPath - Destination file path
|
|
219
|
-
* @param {Object} options - Options
|
|
220
|
-
* @returns {Promise<Object>} Result with relativePath and skipped flag
|
|
221
|
-
*/
|
|
222
|
-
async function scaffoldFile(sourcePath, destPath, options = {}) {
|
|
223
|
-
const { force = false, rollbackFiles = [], baseDir } = options;
|
|
224
|
-
const base = baseDir || path.resolve(destPath, '..', '..');
|
|
225
|
-
const relativePath = path.relative(base, destPath).replace(/\\/g, '/');
|
|
226
|
-
|
|
227
|
-
// Idempotency check (AC5) — async to avoid blocking event loop
|
|
228
|
-
if (!force && await fs.pathExists(destPath)) {
|
|
229
|
-
try {
|
|
230
|
-
if (await hashFilesMatchAsync(sourcePath, destPath)) {
|
|
231
|
-
// Identical — skip
|
|
232
|
-
return { relativePath, skipped: true };
|
|
233
|
-
}
|
|
234
|
-
} catch {
|
|
235
|
-
// Hash comparison failed — overwrite to be safe
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
await fs.ensureDir(path.dirname(destPath));
|
|
240
|
-
await fs.copy(sourcePath, destPath);
|
|
241
|
-
rollbackFiles.push(destPath);
|
|
242
|
-
|
|
243
|
-
return { relativePath, skipped: false };
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* Generate pro-version.json with SHA256 hashes for version tracking (AC4).
|
|
248
|
-
*
|
|
249
|
-
* @param {string} targetDir - Project root
|
|
250
|
-
* @param {string} proSourceDir - Pro package directory
|
|
251
|
-
* @param {string[]} copiedFiles - List of copied file relative paths
|
|
252
|
-
* @returns {Promise<Object>} Version info object
|
|
253
|
-
*/
|
|
254
|
-
async function generateProVersionJson(targetDir, proSourceDir, copiedFiles) {
|
|
255
|
-
// Read pro package version
|
|
256
|
-
let proVersion = 'unknown';
|
|
257
|
-
const proPkgPath = path.join(proSourceDir, 'package.json');
|
|
258
|
-
if (await fs.pathExists(proPkgPath)) {
|
|
259
|
-
try {
|
|
260
|
-
const proPkg = await fs.readJson(proPkgPath);
|
|
261
|
-
proVersion = proPkg.version || 'unknown';
|
|
262
|
-
} catch {
|
|
263
|
-
// Keep 'unknown'
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
// Generate hashes for all copied files
|
|
268
|
-
const fileHashes = {};
|
|
269
|
-
for (const relativePath of copiedFiles) {
|
|
270
|
-
const absolutePath = path.join(targetDir, relativePath);
|
|
271
|
-
try {
|
|
272
|
-
if (await fs.pathExists(absolutePath)) {
|
|
273
|
-
const stats = await fs.stat(absolutePath);
|
|
274
|
-
if (stats.isFile()) {
|
|
275
|
-
fileHashes[relativePath] = `sha256:${await hashFileAsync(absolutePath)}`;
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
} catch {
|
|
279
|
-
// Skip unhashable files
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
const versionInfo = {
|
|
284
|
-
proVersion,
|
|
285
|
-
installedAt: new Date().toISOString(),
|
|
286
|
-
fileCount: copiedFiles.length,
|
|
287
|
-
fileHashes,
|
|
288
|
-
};
|
|
289
|
-
|
|
290
|
-
const versionPath = path.join(targetDir, 'pro-version.json');
|
|
291
|
-
await fs.writeJson(versionPath, versionInfo, { spaces: 2 });
|
|
292
|
-
|
|
293
|
-
return versionInfo;
|
|
294
|
-
}
|
|
295
|
-
|
|
296
|
-
/**
|
|
297
|
-
* Generate pro-installed-manifest.yaml listing all scaffolded files (AC8).
|
|
298
|
-
*
|
|
299
|
-
* @param {string} targetDir - Project root
|
|
300
|
-
* @param {string[]} copiedFiles - List of copied file relative paths
|
|
301
|
-
* @returns {Promise<Object>} Manifest object
|
|
302
|
-
*/
|
|
303
|
-
async function generateInstalledManifest(targetDir, copiedFiles) {
|
|
304
|
-
const files = [];
|
|
305
|
-
for (const relativePath of copiedFiles) {
|
|
306
|
-
const absolutePath = path.join(targetDir, relativePath);
|
|
307
|
-
let timestamp = new Date().toISOString();
|
|
308
|
-
try {
|
|
309
|
-
if (await fs.pathExists(absolutePath)) {
|
|
310
|
-
const stats = await fs.stat(absolutePath);
|
|
311
|
-
timestamp = stats.mtime.toISOString();
|
|
312
|
-
}
|
|
313
|
-
} catch {
|
|
314
|
-
// Use current time
|
|
315
|
-
}
|
|
316
|
-
files.push({ path: relativePath, timestamp });
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
const manifest = {
|
|
320
|
-
generatedAt: new Date().toISOString(),
|
|
321
|
-
totalFiles: files.length,
|
|
322
|
-
files,
|
|
323
|
-
};
|
|
324
|
-
|
|
325
|
-
const manifestPath = path.join(targetDir, 'pro-installed-manifest.yaml');
|
|
326
|
-
await fs.writeFile(manifestPath, yaml.dump(manifest), 'utf8');
|
|
327
|
-
|
|
328
|
-
return manifest;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
/**
|
|
332
|
-
* Rollback partially scaffolded files on error (AC6).
|
|
333
|
-
*
|
|
334
|
-
* @param {string[]} rollbackFiles - Absolute paths to remove
|
|
335
|
-
* @returns {Promise<Object>} Rollback result with removed count and errors
|
|
336
|
-
*/
|
|
337
|
-
async function rollbackScaffold(rollbackFiles) {
|
|
338
|
-
let removed = 0;
|
|
339
|
-
const errors = [];
|
|
340
|
-
|
|
341
|
-
for (const filePath of rollbackFiles) {
|
|
342
|
-
try {
|
|
343
|
-
if (await fs.pathExists(filePath)) {
|
|
344
|
-
await fs.remove(filePath);
|
|
345
|
-
removed++;
|
|
346
|
-
}
|
|
347
|
-
} catch (error) {
|
|
348
|
-
errors.push(`Failed to remove ${filePath}: ${error.message}`);
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
return { removed, errors };
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
/**
|
|
356
|
-
* Merge pro-config.yaml sections into core-config.yaml.
|
|
357
|
-
* Deep merges top-level keys (pro, memory, metrics, integrations, squads).
|
|
358
|
-
*
|
|
359
|
-
* @param {string} targetDir - Project root directory
|
|
360
|
-
* @returns {Promise<boolean>} True if merge was performed
|
|
361
|
-
*/
|
|
362
|
-
async function mergeProConfig(targetDir) {
|
|
363
|
-
const coreConfigPath = path.join(targetDir, '.sinapse-ai', 'core-config.yaml');
|
|
364
|
-
const proConfigPath = path.join(targetDir, '.sinapse-ai', 'pro-config.yaml');
|
|
365
|
-
|
|
366
|
-
if (!await fs.pathExists(proConfigPath) || !await fs.pathExists(coreConfigPath)) {
|
|
367
|
-
return false;
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
const coreConfig = yaml.load(await fs.readFile(coreConfigPath, 'utf8')) || {};
|
|
371
|
-
const proConfig = yaml.load(await fs.readFile(proConfigPath, 'utf8')) || {};
|
|
372
|
-
|
|
373
|
-
for (const [key, value] of Object.entries(proConfig)) {
|
|
374
|
-
if (coreConfig[key] && typeof coreConfig[key] === 'object' && typeof value === 'object' && !Array.isArray(value)) {
|
|
375
|
-
coreConfig[key] = { ...coreConfig[key], ...value };
|
|
376
|
-
} else {
|
|
377
|
-
coreConfig[key] = value;
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
await fs.writeFile(coreConfigPath, yaml.dump(coreConfig, { lineWidth: -1 }), 'utf8');
|
|
382
|
-
return true;
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
/**
|
|
386
|
-
* Install squad agent commands into active IDE directories.
|
|
387
|
-
* Detects which IDEs are configured and copies agent .md files accordingly.
|
|
388
|
-
*
|
|
389
|
-
* @param {string} targetDir - Project root directory
|
|
390
|
-
* @returns {Promise<Object>} Result with installed count and file list
|
|
391
|
-
*/
|
|
392
|
-
async function installSquadCommands(targetDir) {
|
|
393
|
-
const squadsDir = path.join(targetDir, 'squads');
|
|
394
|
-
if (!await fs.pathExists(squadsDir)) return { installed: 0, files: [] };
|
|
395
|
-
|
|
396
|
-
const ideTargets = [
|
|
397
|
-
{ check: path.join('.claude', 'commands'), dest: (squad) => path.join('.claude', 'commands', squad) },
|
|
398
|
-
{ check: path.join('.codex', 'agents'), dest: () => path.join('.codex', 'agents') },
|
|
399
|
-
{ check: path.join('.gemini', 'rules'), dest: (squad) => path.join('.gemini', 'rules', squad) },
|
|
400
|
-
{ check: path.join('.cursor', 'rules'), dest: () => path.join('.cursor', 'rules') },
|
|
401
|
-
];
|
|
402
|
-
|
|
403
|
-
const activeIDEs = [];
|
|
404
|
-
for (const ide of ideTargets) {
|
|
405
|
-
if (await fs.pathExists(path.join(targetDir, ide.check))) {
|
|
406
|
-
activeIDEs.push(ide);
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
if (activeIDEs.length === 0) return { installed: 0, files: [] };
|
|
410
|
-
|
|
411
|
-
const files = [];
|
|
412
|
-
const items = await fs.readdir(squadsDir, { withFileTypes: true });
|
|
413
|
-
|
|
414
|
-
for (const item of items) {
|
|
415
|
-
if (!item.isDirectory()) continue;
|
|
416
|
-
const agentsDir = path.join(squadsDir, item.name, 'agents');
|
|
417
|
-
if (!await fs.pathExists(agentsDir)) continue;
|
|
418
|
-
|
|
419
|
-
const agentFiles = (await fs.readdir(agentsDir))
|
|
420
|
-
.filter(f => f.endsWith('.md') && !f.startsWith('test-'));
|
|
421
|
-
|
|
422
|
-
for (const ide of activeIDEs) {
|
|
423
|
-
const destDir = path.join(targetDir, ide.dest(item.name));
|
|
424
|
-
await fs.ensureDir(destDir);
|
|
425
|
-
for (const agentFile of agentFiles) {
|
|
426
|
-
await fs.copy(
|
|
427
|
-
path.join(agentsDir, agentFile),
|
|
428
|
-
path.join(destDir, agentFile),
|
|
429
|
-
);
|
|
430
|
-
files.push(path.relative(targetDir, path.join(destDir, agentFile)).replace(/\\/g, '/'));
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
return { installed: files.length, files };
|
|
436
|
-
}
|
|
437
|
-
|
|
438
|
-
module.exports = {
|
|
439
|
-
scaffoldProContent,
|
|
440
|
-
scaffoldDirectory,
|
|
441
|
-
scaffoldFile,
|
|
442
|
-
generateProVersionJson,
|
|
443
|
-
generateInstalledManifest,
|
|
444
|
-
rollbackScaffold,
|
|
445
|
-
mergeProConfig,
|
|
446
|
-
installSquadCommands,
|
|
447
|
-
SCAFFOLD_ITEMS,
|
|
448
|
-
SCAFFOLD_EXCLUDES,
|
|
449
|
-
};
|