sinapse-ai 1.25.2 → 1.26.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/.agents/skills/react-bits-frontend/SKILL.md +13 -4
- package/.claude/skill-manifest.json +1 -0
- package/.claude/skills/react-bits-frontend/SKILL.md +75 -0
- package/.codex/scripts/sync-codex-native.js +12 -0
- package/.sinapse-ai/data/entity-registry.yaml +39 -14
- package/.sinapse-ai/install-manifest.yaml +3 -3
- package/CHANGELOG.md +8 -7
- package/README.en.md +1 -1
- package/README.md +1 -1
- package/bin/commands/install.js +25 -4
- package/bin/commands/uninstall.js +1 -1
- package/bin/commands/update.js +19 -3
- package/bin/lib/command-generator.js +60 -36
- package/bin/lib/global-provider-adapters.js +257 -50
- package/bin/lib/provider-contract.js +25 -0
- package/bin/lib/provider-parity.js +67 -10
- package/docs/guides/ide-integration.md +1 -1
- package/package.json +1 -1
- package/packages/installer/src/installer/react-bits-corpus.js +90 -0
- package/packages/installer/src/installer/sinapse-ai-installer.js +9 -0
- package/scripts/sync-provider-adapters.js +7 -2
- package/scripts/validate-provider-adapters.js +21 -1
- package/squads/squad-animations/agents/animations-orqx.md +7 -0
- package/squads/squad-animations/squad.yaml +1 -1
|
@@ -10,8 +10,16 @@ not as a black-box library.
|
|
|
10
10
|
|
|
11
11
|
## Locate the corpus
|
|
12
12
|
|
|
13
|
-
Resolve the
|
|
14
|
-
|
|
13
|
+
Resolve the corpus in this exact order, then read `index.md` from the first
|
|
14
|
+
location that contains the complete corpus:
|
|
15
|
+
|
|
16
|
+
1. `<project>/docs/framework/react-bits/`
|
|
17
|
+
2. `<installed-package>/docs/framework/react-bits/`
|
|
18
|
+
3. `~/.sinapse/docs/framework/react-bits/`
|
|
19
|
+
|
|
20
|
+
The project location wins so a project can pin or extend its installed research.
|
|
21
|
+
The package location supports package-managed runs, and the global SINAPSE home
|
|
22
|
+
supports `--global-only` installs. Read only the category needed:
|
|
15
23
|
|
|
16
24
|
- `animations.md` for wrappers, cursors, trails, transitions and interactive effects.
|
|
17
25
|
- `text-animations.md` for headline, counter, scramble, marquee and reveal work.
|
|
@@ -21,8 +29,9 @@ Resolve the SINAPSE package/repository root, then read
|
|
|
21
29
|
- `audit-findings.md` when dependency, prop, variant or upstream accuracy matters.
|
|
22
30
|
- `inventory.json` for exact machine-readable props, dependencies and variant state.
|
|
23
31
|
|
|
24
|
-
If
|
|
25
|
-
|
|
32
|
+
If none of those locations has all nine files, state which locations were checked,
|
|
33
|
+
ask the user to run the relevant SINAPSE install/update, then verify current facts
|
|
34
|
+
against the official registry and source before implementation.
|
|
26
35
|
|
|
27
36
|
## Workflow
|
|
28
37
|
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: react-bits-frontend
|
|
3
|
+
description: Select, install, adapt, combine, optimize, and audit official React Bits components for React, Next.js, Vite, Astro islands, and SINAPSE frontend projects. Use for animated text, cursors, reveals, cards, navigation, galleries, WebGL backgrounds, shaders, particles, motion systems, React Bits CLI/MCP commands, component props/dependencies, or when improving an existing page with React Bits while preserving accessibility, mobile performance, lifecycle cleanup, design-system fit, and license compliance.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# React Bits Frontend
|
|
7
|
+
|
|
8
|
+
Use the source-grounded SINAPSE corpus to implement React Bits as application code,
|
|
9
|
+
not as a black-box library.
|
|
10
|
+
|
|
11
|
+
## Locate the corpus
|
|
12
|
+
|
|
13
|
+
Resolve the corpus in this exact order, then read `index.md` from the first
|
|
14
|
+
location that contains the complete corpus:
|
|
15
|
+
|
|
16
|
+
1. `<project>/docs/framework/react-bits/`
|
|
17
|
+
2. `<installed-package>/docs/framework/react-bits/`
|
|
18
|
+
3. `~/.sinapse/docs/framework/react-bits/`
|
|
19
|
+
|
|
20
|
+
The project location wins so a project can pin or extend its installed research.
|
|
21
|
+
The package location supports package-managed runs, and the global SINAPSE home
|
|
22
|
+
supports `--global-only` installs. Read only the category needed:
|
|
23
|
+
|
|
24
|
+
- `animations.md` for wrappers, cursors, trails, transitions and interactive effects.
|
|
25
|
+
- `text-animations.md` for headline, counter, scramble, marquee and reveal work.
|
|
26
|
+
- `components.md` for cards, navigation, galleries, inputs and compound UI.
|
|
27
|
+
- `backgrounds.md` for Canvas/WebGL/shader/particle backgrounds.
|
|
28
|
+
- `implementation-playbook.md` for integration, composition, accessibility and tuning.
|
|
29
|
+
- `audit-findings.md` when dependency, prop, variant or upstream accuracy matters.
|
|
30
|
+
- `inventory.json` for exact machine-readable props, dependencies and variant state.
|
|
31
|
+
|
|
32
|
+
If none of those locations has all nine files, state which locations were checked,
|
|
33
|
+
ask the user to run the relevant SINAPSE install/update, then verify current facts
|
|
34
|
+
against the official registry and source before implementation.
|
|
35
|
+
|
|
36
|
+
## Workflow
|
|
37
|
+
|
|
38
|
+
1. Inspect the target stack, component architecture, design tokens, performance budget
|
|
39
|
+
and existing animation/scroll ownership.
|
|
40
|
+
2. Translate the visual request into a user-experience function.
|
|
41
|
+
3. Search the relevant catalog and shortlist at most three candidates.
|
|
42
|
+
4. Compare visual fit, dependencies, runtime engine, props, interaction model,
|
|
43
|
+
accessibility, mobile cost and compatibility with existing effects.
|
|
44
|
+
5. Open the official source for the selected variant. Treat source and registry as
|
|
45
|
+
authoritative when docs conflict.
|
|
46
|
+
6. Run `npm view <package>` for every declared dependency before installing it.
|
|
47
|
+
7. Prefer TS-TW or TS-CSS in TypeScript projects. Never use the three empty CurvedInput
|
|
48
|
+
variants recorded in the snapshot; use JS-CSS or verify that upstream fixed them.
|
|
49
|
+
8. Install through shadcn/jsrepo or copy manually. Keep upstream provenance and the
|
|
50
|
+
required license notice for substantial copies.
|
|
51
|
+
9. Wrap the imported component behind a local application component. Map design
|
|
52
|
+
tokens, content, breakpoints and quality presets at that boundary.
|
|
53
|
+
10. Implement reduced-motion behavior, semantic fallback, keyboard/focus behavior,
|
|
54
|
+
cleanup and static/mobile fallback.
|
|
55
|
+
11. Test load, resize, route unmount/remount, long scroll, coarse pointer, reduced
|
|
56
|
+
motion and low-power mobile. Measure frame time and memory.
|
|
57
|
+
12. Report component, variant, source SHA/URL, dependencies, adaptations, fallbacks and
|
|
58
|
+
remaining risks.
|
|
59
|
+
|
|
60
|
+
## Composition rules
|
|
61
|
+
|
|
62
|
+
- Use one dominant motion effect per viewport and no more than two support effects.
|
|
63
|
+
- Prefer the lowest-cost engine that satisfies the visual objective.
|
|
64
|
+
- Allow only one owner for smooth scroll, custom cursor and each render loop.
|
|
65
|
+
- Do not stack multiple heavy WebGL/physics backgrounds without an explicit budget.
|
|
66
|
+
- Pause offscreen/hidden loops and dispose GPU resources on unmount.
|
|
67
|
+
- Preserve content and interaction when animation is disabled or fails.
|
|
68
|
+
|
|
69
|
+
## Accuracy rules
|
|
70
|
+
|
|
71
|
+
- Do not repeat the promotional “140+” as an exact count. The pinned snapshot has 139.
|
|
72
|
+
- Do not infer functional variants from registry names alone; inspect source bytes/code.
|
|
73
|
+
- Use registry JSON for install dependencies and source for actual API/behavior.
|
|
74
|
+
- Note documentation typos and per-variant divergences from `audit-findings.md`.
|
|
75
|
+
- Do not redistribute React Bits components as a standalone library, bundle, or port.
|
|
@@ -34,6 +34,10 @@ function isPathInside(parentPath, candidatePath) {
|
|
|
34
34
|
return relative === '' || (!relative.startsWith('..') && !path.isAbsolute(relative));
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
function isSafeSkillId(skillId) {
|
|
38
|
+
return typeof skillId === 'string' && /^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(skillId);
|
|
39
|
+
}
|
|
40
|
+
|
|
37
41
|
function readCanonicalSource(projectRoot, sourcePath) {
|
|
38
42
|
if (!sourcePath) {
|
|
39
43
|
throw new Error('Codex agent pointer does not declare a canonical source');
|
|
@@ -329,6 +333,14 @@ function readCodexCatalog(projectRoot = PROJECT_ROOT) {
|
|
|
329
333
|
if (typeof catalog.genericAgentSkillId !== 'string' || !catalog.genericAgentSkillId.trim()) {
|
|
330
334
|
throw new Error('Codex catalog does not declare genericAgentSkillId');
|
|
331
335
|
}
|
|
336
|
+
const catalogSkillIds = [
|
|
337
|
+
...catalog.expectedSkillIds,
|
|
338
|
+
...catalog.publicAliasSkillIds,
|
|
339
|
+
catalog.genericAgentSkillId,
|
|
340
|
+
];
|
|
341
|
+
if (catalogSkillIds.some((skillId) => !isSafeSkillId(skillId))) {
|
|
342
|
+
throw new Error('Codex catalog contains an unsafe skill ID');
|
|
343
|
+
}
|
|
332
344
|
return catalog;
|
|
333
345
|
}
|
|
334
346
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
metadata:
|
|
2
2
|
version: 1.0.0
|
|
3
|
-
lastUpdated: '2026-07-
|
|
4
|
-
entityCount:
|
|
3
|
+
lastUpdated: '2026-07-15T14:30:07.448Z'
|
|
4
|
+
entityCount: 818
|
|
5
5
|
checksumAlgorithm: sha256
|
|
6
6
|
resolutionRate: 100
|
|
7
7
|
entities:
|
|
@@ -166,8 +166,8 @@ entities:
|
|
|
166
166
|
score: 0.7
|
|
167
167
|
constraints: []
|
|
168
168
|
extensionPoints: []
|
|
169
|
-
checksum: sha256:
|
|
170
|
-
lastVerified: '2026-07-
|
|
169
|
+
checksum: sha256:86db5a2578b6a0b4849fde4e0f4a197a41560a3a213b247f0edd8522d857ffea
|
|
170
|
+
lastVerified: '2026-07-15T13:41:11.702Z'
|
|
171
171
|
local:
|
|
172
172
|
path: bin/commands/local.js
|
|
173
173
|
layer: L1
|
|
@@ -276,8 +276,8 @@ entities:
|
|
|
276
276
|
score: 0.7
|
|
277
277
|
constraints: []
|
|
278
278
|
extensionPoints: []
|
|
279
|
-
checksum: sha256:
|
|
280
|
-
lastVerified: '2026-07-
|
|
279
|
+
checksum: sha256:05056e197ecb29e6f63a1d86d9d77d944e3083021bf632b48a76eb4cb2223b95
|
|
280
|
+
lastVerified: '2026-07-15T13:41:11.703Z'
|
|
281
281
|
command-generator:
|
|
282
282
|
path: bin/lib/command-generator.js
|
|
283
283
|
layer: L1
|
|
@@ -299,6 +299,7 @@ entities:
|
|
|
299
299
|
- constants
|
|
300
300
|
- squads
|
|
301
301
|
- fs-utils
|
|
302
|
+
- provider-contract
|
|
302
303
|
externalDeps: []
|
|
303
304
|
plannedDeps: []
|
|
304
305
|
lifecycle: production
|
|
@@ -306,8 +307,8 @@ entities:
|
|
|
306
307
|
score: 0.7
|
|
307
308
|
constraints: []
|
|
308
309
|
extensionPoints: []
|
|
309
|
-
checksum: sha256:
|
|
310
|
-
lastVerified: '2026-07-
|
|
310
|
+
checksum: sha256:837f10f3ce227b1f3ff9b3d4c9e824e8928cd67ec07b0dcebd78e85468eed003
|
|
311
|
+
lastVerified: '2026-07-15T13:41:11.703Z'
|
|
311
312
|
constants:
|
|
312
313
|
path: bin/lib/constants.js
|
|
313
314
|
layer: L1
|
|
@@ -413,7 +414,8 @@ entities:
|
|
|
413
414
|
usedBy:
|
|
414
415
|
- install
|
|
415
416
|
- update
|
|
416
|
-
dependencies:
|
|
417
|
+
dependencies:
|
|
418
|
+
- provider-contract
|
|
417
419
|
externalDeps: []
|
|
418
420
|
plannedDeps: []
|
|
419
421
|
lifecycle: production
|
|
@@ -421,8 +423,8 @@ entities:
|
|
|
421
423
|
score: 0.7
|
|
422
424
|
constraints: []
|
|
423
425
|
extensionPoints: []
|
|
424
|
-
checksum: sha256:
|
|
425
|
-
lastVerified: '2026-07-
|
|
426
|
+
checksum: sha256:898fbe5a00cf1bb77bc8e8a34ee40337145912374a2e809789a02d5345fdd679
|
|
427
|
+
lastVerified: '2026-07-15T14:30:07.273Z'
|
|
426
428
|
header:
|
|
427
429
|
path: bin/lib/header.js
|
|
428
430
|
layer: L1
|
|
@@ -475,6 +477,28 @@ entities:
|
|
|
475
477
|
extensionPoints: []
|
|
476
478
|
checksum: sha256:dc7cc1109f2bbdb7b3c5927df0de2418925842bdacdc0ba82815bfa2783d0b42
|
|
477
479
|
lastVerified: '2026-06-22T02:41:18.152Z'
|
|
480
|
+
provider-contract:
|
|
481
|
+
path: bin/lib/provider-contract.js
|
|
482
|
+
layer: L1
|
|
483
|
+
type: script
|
|
484
|
+
purpose: Entity at bin\lib\provider-contract.js
|
|
485
|
+
keywords:
|
|
486
|
+
- provider
|
|
487
|
+
- contract
|
|
488
|
+
usedBy:
|
|
489
|
+
- command-generator
|
|
490
|
+
- global-provider-adapters
|
|
491
|
+
- provider-parity
|
|
492
|
+
dependencies: []
|
|
493
|
+
externalDeps: []
|
|
494
|
+
plannedDeps: []
|
|
495
|
+
lifecycle: production
|
|
496
|
+
adaptability:
|
|
497
|
+
score: 0.7
|
|
498
|
+
constraints: []
|
|
499
|
+
extensionPoints: []
|
|
500
|
+
checksum: sha256:a18d271a73b2f371213af4d9503e302e9237920057afd521b723c96efd28fda0
|
|
501
|
+
lastVerified: '2026-07-15T13:41:11.704Z'
|
|
478
502
|
provider-parity:
|
|
479
503
|
path: bin/lib/provider-parity.js
|
|
480
504
|
layer: L1
|
|
@@ -486,7 +510,8 @@ entities:
|
|
|
486
510
|
usedBy:
|
|
487
511
|
- install
|
|
488
512
|
- update
|
|
489
|
-
dependencies:
|
|
513
|
+
dependencies:
|
|
514
|
+
- provider-contract
|
|
490
515
|
externalDeps: []
|
|
491
516
|
plannedDeps: []
|
|
492
517
|
lifecycle: production
|
|
@@ -494,8 +519,8 @@ entities:
|
|
|
494
519
|
score: 0.7
|
|
495
520
|
constraints: []
|
|
496
521
|
extensionPoints: []
|
|
497
|
-
checksum: sha256:
|
|
498
|
-
lastVerified: '2026-07-
|
|
522
|
+
checksum: sha256:5f0ff4517425fef01683f035afef1d139aede2fe47956773a398e7c761ace42d
|
|
523
|
+
lastVerified: '2026-07-15T13:41:11.704Z'
|
|
499
524
|
setup-statusline:
|
|
500
525
|
path: bin/lib/setup-statusline.js
|
|
501
526
|
layer: L1
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
# - SHA256 hashes for change detection
|
|
8
8
|
# - File types for categorization
|
|
9
9
|
#
|
|
10
|
-
version: 1.
|
|
10
|
+
version: 1.26.0
|
|
11
11
|
generator: scripts/generate-install-manifest.js
|
|
12
12
|
file_count: 1156
|
|
13
13
|
files:
|
|
@@ -1368,9 +1368,9 @@ files:
|
|
|
1368
1368
|
type: data
|
|
1369
1369
|
size: 9671
|
|
1370
1370
|
- path: data/entity-registry.yaml
|
|
1371
|
-
hash: sha256:
|
|
1371
|
+
hash: sha256:08edc9d3cde1bf956cce462004670a3d2924a691a16c27bdfd2bf1ce4de037f8
|
|
1372
1372
|
type: data
|
|
1373
|
-
size:
|
|
1373
|
+
size: 560701
|
|
1374
1374
|
- path: data/learned-patterns.yaml
|
|
1375
1375
|
hash: sha256:1a4cd045c087b9dfd7046ff1464a9d2edb85fba77cf0b6fba14f4bb9004c741e
|
|
1376
1376
|
type: data
|
package/CHANGELOG.md
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
## [1.
|
|
1
|
+
## [1.26.0](https://github.com/caioimori/sinapse-ai/compare/1.25.3...1.26.0) (2026-07-15)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
|
|
5
|
+
* deliver React Bits across providers [Story react-bits-distribution-parity] ([aa191f1](https://github.com/caioimori/sinapse-ai/commit/aa191f102dc417e3a0182c02661907e474226abb))
|
|
2
6
|
|
|
3
7
|
### Bug Fixes
|
|
4
8
|
|
|
5
|
-
* **docs:** align
|
|
6
|
-
* **
|
|
9
|
+
* **docs:** align provider skill metrics [Story react-bits-distribution-parity] ([729d120](https://github.com/caioimori/sinapse-ai/commit/729d120ee1735473d01971efdb746be59d2d19d8))
|
|
10
|
+
* **react-bits:** harden corpus delivery and orchestration [Story react-bits-distribution-parity] ([6456062](https://github.com/caioimori/sinapse-ai/commit/6456062cd756826e6bc14c698ebde07298d8a5eb))
|
|
7
11
|
|
|
8
12
|
### Documentation
|
|
9
13
|
|
|
10
|
-
*
|
|
11
|
-
* **story:** normalize validation terminology [Story sinapse-only-catalog-cleanup] ([7e0ecb9](https://github.com/caioimori/sinapse-ai/commit/7e0ecb9fb01a6626ccc7c665d262c38c61196120))
|
|
12
|
-
* **story:** reconcile post-release evidence [Story sinapse-only-catalog-cleanup] ([3c10c65](https://github.com/caioimori/sinapse-ai/commit/3c10c65fcfdca77ec0d1c1af6a2831af39b0adf0))
|
|
13
|
-
* **story:** record SINAPSE 1.25.1 release [Story sinapse-only-catalog-cleanup] ([ba9f776](https://github.com/caioimori/sinapse-ai/commit/ba9f77607879c6efe8511e38cfeab6c71d2335c4))
|
|
14
|
+
* close installer parity release evidence [Story hotfix-installer-provider-adapter-parity-1.25.3] ([#386](https://github.com/caioimori/sinapse-ai/issues/386)) ([ceafcb8](https://github.com/caioimori/sinapse-ai/commit/ceafcb8ac522835c264115e9ee16cba6e49e173c))
|
|
14
15
|
|
|
15
16
|
# Changelog
|
|
16
17
|
|
package/README.en.md
CHANGED
|
@@ -309,7 +309,7 @@ Both IDEs have access to all 17 squads, 172 agents, workflows, and knowledge bas
|
|
|
309
309
|
| Native agents | 172 | 172 |
|
|
310
310
|
| Direct activation | `@agent-name` | `$sinapse-agent agent-id` |
|
|
311
311
|
| Primary routing | `@sinapse-orqx` | `$snps` |
|
|
312
|
-
| Installed skills |
|
|
312
|
+
| Installed skills | 37 | 37 |
|
|
313
313
|
| Registered hooks | 20 native registrations | 9 lifecycle events through the bridge |
|
|
314
314
|
| Validation source | `npm run validate:providers` | `npm run validate:codex-native` |
|
|
315
315
|
|
package/README.md
CHANGED
|
@@ -331,7 +331,7 @@ Ambas as IDEs têm acesso a todos os 17 squads, 172 agentes, workflows e knowled
|
|
|
331
331
|
| Agentes nativos | 172 | 172 |
|
|
332
332
|
| Ativação direta | `@agent-name` | `$sinapse-agent agent-id` |
|
|
333
333
|
| Roteamento principal | `@sinapse-orqx` | `$snps` |
|
|
334
|
-
| Skills instaladas |
|
|
334
|
+
| Skills instaladas | 37 | 37 |
|
|
335
335
|
| Hooks registrados | 20 registros nativos | 9 eventos de lifecycle via bridge |
|
|
336
336
|
| Fonte de validação | `npm run validate:providers` | `npm run validate:codex-native` |
|
|
337
337
|
|
package/bin/commands/install.js
CHANGED
|
@@ -50,6 +50,10 @@ const {
|
|
|
50
50
|
} = require('../lib/command-generator');
|
|
51
51
|
const { deliverGlobalProviderAdapters, getGlobalCommandStagingDir } = require('../lib/global-provider-adapters');
|
|
52
52
|
const { assertProviderAdapterParity } = require('../lib/provider-parity');
|
|
53
|
+
const {
|
|
54
|
+
copyReactBitsCapabilitySync,
|
|
55
|
+
REACT_BITS_SKILL_RELATIVE_PATH,
|
|
56
|
+
} = require('../../packages/installer/src/installer/react-bits-corpus');
|
|
53
57
|
// Follow-up #13 — wire the transactional backup/rollback engine into the
|
|
54
58
|
// installer so an in-place UPGRADE (upsert) that fails mid-flight is restored
|
|
55
59
|
// to its previous state instead of leaving ~/.sinapse half-updated.
|
|
@@ -317,7 +321,12 @@ async function cmdInstallGlobal(opts = {}) {
|
|
|
317
321
|
// rich, frontmatter'd stubs are always the final word. Idempotent.
|
|
318
322
|
try {
|
|
319
323
|
const commandsDir = getGlobalCommandStagingDir({ llmChoice, sinapseHome: SINAPSE_HOME, claudeCommandsDir: CLAUDE_COMMANDS_DIR });
|
|
320
|
-
const reconciled = deliverGlobalProviderAdapters({
|
|
324
|
+
const reconciled = deliverGlobalProviderAdapters({
|
|
325
|
+
llmChoice,
|
|
326
|
+
home: HOME,
|
|
327
|
+
commandsDir,
|
|
328
|
+
reactBitsSkillPath: path.join(SINAPSE_HOME, REACT_BITS_SKILL_RELATIVE_PATH),
|
|
329
|
+
});
|
|
321
330
|
const total = reconciled.claude.length + reconciled.codex.length + reconciled.skills.length;
|
|
322
331
|
if (total) logger.always(` ${GREEN}OK${NC} Global provider adapters reconciled (${total} artifacts)`);
|
|
323
332
|
} catch (e) {
|
|
@@ -557,10 +566,13 @@ function installFatalPhases({ squads, squadsDir, isUpsert, llmChoice, existing,
|
|
|
557
566
|
logger.always(` ${GREEN}OK${NC} core development (${coreAgents} agents)`);
|
|
558
567
|
}
|
|
559
568
|
|
|
569
|
+
const reactBits = copyReactBitsCapabilitySync(ROOT, SINAPSE_HOME);
|
|
570
|
+
if (reactBits.files.length) logger.always(` ${GREEN}OK${NC} React Bits corpus (${reactBits.files.length} files)`);
|
|
571
|
+
|
|
560
572
|
// Phase 2: Generate agent commands (shared with `update` via command-generator).
|
|
561
573
|
logger.always(`\n${CYAN}Phase 2:${NC} Generating agent commands`);
|
|
562
574
|
const commandStagingDir = getGlobalCommandStagingDir({ llmChoice, sinapseHome: SINAPSE_HOME, claudeCommandsDir: CLAUDE_COMMANDS_DIR });
|
|
563
|
-
const { writtenAgents,
|
|
575
|
+
const { writtenAgents, canonicalAgents } = regenerateAgentCommands({
|
|
564
576
|
sinapseHome: SINAPSE_HOME,
|
|
565
577
|
commandsDir: commandStagingDir,
|
|
566
578
|
squads,
|
|
@@ -570,8 +582,17 @@ function installFatalPhases({ squads, squadsDir, isUpsert, llmChoice, existing,
|
|
|
570
582
|
logger.always(` ${GREEN}OK${NC} ${writtenAgents.size} total command files`);
|
|
571
583
|
|
|
572
584
|
// Phase 2b: Install global agents based on LLM choice
|
|
573
|
-
const globalAdapters = deliverGlobalProviderAdapters({
|
|
574
|
-
|
|
585
|
+
const globalAdapters = deliverGlobalProviderAdapters({
|
|
586
|
+
llmChoice,
|
|
587
|
+
home: HOME,
|
|
588
|
+
commandsDir: commandStagingDir,
|
|
589
|
+
reactBitsSkillPath: path.join(SINAPSE_HOME, REACT_BITS_SKILL_RELATIVE_PATH),
|
|
590
|
+
});
|
|
591
|
+
const activeAgentCount = assertProviderAdapterParity(
|
|
592
|
+
llmChoice,
|
|
593
|
+
globalAdapters,
|
|
594
|
+
canonicalAgents,
|
|
595
|
+
);
|
|
575
596
|
const installedAgentFilenames = new Set([...globalAdapters.claude, ...globalAdapters.codex]);
|
|
576
597
|
const installedIdes = [];
|
|
577
598
|
if (globalAdapters.claude.length) installedIdes.push('claude-code');
|
|
@@ -170,7 +170,7 @@ function removeOrqxAgentsFrom(dir) {
|
|
|
170
170
|
return removeInstalledAgentsFrom(dir);
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
-
const MANAGED_GLOBAL_SKILL_IDS = ['snps', 'sinapse', 'snps-orqx', 'sinapse-orqx', 'sinapse-agent'];
|
|
173
|
+
const MANAGED_GLOBAL_SKILL_IDS = ['snps', 'sinapse', 'snps-orqx', 'sinapse-orqx', 'sinapse-agent', 'react-bits-frontend'];
|
|
174
174
|
const MANAGED_GLOBAL_SKILL_MARKER = 'SINAPSE-MANAGED:global-skill';
|
|
175
175
|
|
|
176
176
|
function removeManagedGlobalSkills(home = HOME, options = {}) {
|
package/bin/commands/update.js
CHANGED
|
@@ -36,6 +36,10 @@ const {
|
|
|
36
36
|
} = require('./uninstall');
|
|
37
37
|
const { regenerateAgentCommands } = require('../lib/command-generator');
|
|
38
38
|
const { deliverGlobalProviderAdapters, getGlobalCommandStagingDir } = require('../lib/global-provider-adapters');
|
|
39
|
+
const {
|
|
40
|
+
copyReactBitsCapabilitySync,
|
|
41
|
+
REACT_BITS_SKILL_RELATIVE_PATH,
|
|
42
|
+
} = require('../../packages/installer/src/installer/react-bits-corpus');
|
|
39
43
|
const { assertProviderAdapterParity } = require('../lib/provider-parity');
|
|
40
44
|
const { execSync } = require('child_process');
|
|
41
45
|
|
|
@@ -164,13 +168,16 @@ async function cmdUpdateGlobal() {
|
|
|
164
168
|
logger.always(` ${GREEN}OK${NC} core development`);
|
|
165
169
|
}
|
|
166
170
|
|
|
171
|
+
const reactBits = copyReactBitsCapabilitySync(ROOT, SINAPSE_HOME);
|
|
172
|
+
if (reactBits.files.length) logger.always(` ${GREEN}OK${NC} React Bits corpus (${reactBits.files.length} files)`);
|
|
173
|
+
|
|
167
174
|
// Phase 2: Regenerate commands — shared with `install` so `update` produces the
|
|
168
175
|
// SAME complete set (every specialist command + the rich master Imperator stubs),
|
|
169
176
|
// not just the `-orqx` subset it used to write.
|
|
170
177
|
logger.always(`\n${CYAN}Phase 2:${NC} Regenerating commands`);
|
|
171
178
|
const commandStagingDir = getGlobalCommandStagingDir({ llmChoice, sinapseHome: SINAPSE_HOME, claudeCommandsDir: CLAUDE_COMMANDS_DIR });
|
|
172
179
|
rmDirSync(commandStagingDir);
|
|
173
|
-
const { writtenAgents, totalAgents } = regenerateAgentCommands({
|
|
180
|
+
const { writtenAgents, canonicalAgents, totalAgents } = regenerateAgentCommands({
|
|
174
181
|
sinapseHome: SINAPSE_HOME,
|
|
175
182
|
commandsDir: commandStagingDir,
|
|
176
183
|
squads,
|
|
@@ -180,8 +187,17 @@ async function cmdUpdateGlobal() {
|
|
|
180
187
|
logger.always(` ${GREEN}OK${NC} ${writtenAgents.size} command files (${totalAgents} agents total)`);
|
|
181
188
|
|
|
182
189
|
// Phase 2b: Install global agents based on LLM choice
|
|
183
|
-
const globalAdapters = deliverGlobalProviderAdapters({
|
|
184
|
-
|
|
190
|
+
const globalAdapters = deliverGlobalProviderAdapters({
|
|
191
|
+
llmChoice,
|
|
192
|
+
home: HOME,
|
|
193
|
+
commandsDir: commandStagingDir,
|
|
194
|
+
reactBitsSkillPath: path.join(SINAPSE_HOME, REACT_BITS_SKILL_RELATIVE_PATH),
|
|
195
|
+
});
|
|
196
|
+
const activeAgentCount = assertProviderAdapterParity(
|
|
197
|
+
llmChoice,
|
|
198
|
+
globalAdapters,
|
|
199
|
+
canonicalAgents,
|
|
200
|
+
);
|
|
185
201
|
if (globalAdapters.claude.length) logger.always(` ${GREEN}OK${NC} Claude Code global agents (${globalAdapters.claude.length})`);
|
|
186
202
|
if (globalAdapters.codex.length) logger.always(` ${GREEN}OK${NC} Codex global agents (${globalAdapters.codex.length} TOML, ${globalAdapters.skills.length} skills)`);
|
|
187
203
|
|
|
@@ -20,6 +20,7 @@ const { toForwardSlash, atomicWriteFileSync } = require('./fs-utils');
|
|
|
20
20
|
// sync-counts uses so the master-stub headline can never drift from README/persona
|
|
21
21
|
// (Constitution Article VII). Fails open to 0 if the dir is unavailable.
|
|
22
22
|
const CORE_AGENTS_DIR = path.join(ROOT, '.sinapse-ai', 'development', 'agents');
|
|
23
|
+
const { MASTER_ALIAS_ENTRY_POINTS } = require('./provider-contract');
|
|
23
24
|
|
|
24
25
|
function countCoreAgents(dir = CORE_AGENTS_DIR) {
|
|
25
26
|
try {
|
|
@@ -207,7 +208,7 @@ If the task requires expertise outside this squad:
|
|
|
207
208
|
* @param {string} [deps.commandsDir] - Target commands dir.
|
|
208
209
|
* @param {Array} deps.squads - Squad descriptors ({ name, agents, ... }).
|
|
209
210
|
* @param {string} [deps.sinapseMasterDest] - Path to the installed sinapse/ master squad.
|
|
210
|
-
* @returns {{ writtenAgents: Set<string>, totalAgents: number }}
|
|
211
|
+
* @returns {{ writtenAgents: Set<string>, canonicalAgents: Array<{ id: string, file: string, origin: string }>, aliasEntryPoints: string[], totalAgents: number }}
|
|
211
212
|
*/
|
|
212
213
|
function regenerateAgentCommands(deps = {}) {
|
|
213
214
|
const {
|
|
@@ -222,20 +223,21 @@ function regenerateAgentCommands(deps = {}) {
|
|
|
222
223
|
throw new Error('regenerateAgentCommands: `squads` array is required');
|
|
223
224
|
}
|
|
224
225
|
|
|
225
|
-
fs.mkdirSync(commandsDir, { recursive: true });
|
|
226
|
-
|
|
227
|
-
// Clear old commands (dir may not exist on a fresh install — guarded).
|
|
228
|
-
try {
|
|
229
|
-
for (const f of fs.readdirSync(commandsDir)) {
|
|
230
|
-
fs.unlinkSync(path.join(commandsDir, f));
|
|
231
|
-
}
|
|
232
|
-
} catch { /* dir may not exist yet */ }
|
|
233
|
-
|
|
234
226
|
const sinapseBase = toForwardSlash(sinapseHome);
|
|
235
227
|
const writtenAgents = new Set();
|
|
228
|
+
const catalogById = new Map();
|
|
229
|
+
const definitions = [];
|
|
230
|
+
|
|
231
|
+
function registerDefinition(definition) {
|
|
232
|
+
const previous = catalogById.get(definition.id);
|
|
233
|
+
if (previous) {
|
|
234
|
+
throw new Error(`Duplicate canonical agent ID "${definition.id}" from ${previous.origin} and ${definition.origin}`);
|
|
235
|
+
}
|
|
236
|
+
catalogById.set(definition.id, definition);
|
|
237
|
+
definitions.push(definition);
|
|
238
|
+
}
|
|
236
239
|
|
|
237
|
-
//
|
|
238
|
-
// is invokable via @agent and /SINAPSE:agents:agent.
|
|
240
|
+
// Inventory every canonical definition before clearing or writing commands.
|
|
239
241
|
for (const squad of squads) {
|
|
240
242
|
const squadPath = `${sinapseBase}/${squad.name}`;
|
|
241
243
|
const agentsDir = path.join(sinapseHome, squad.name, 'agents');
|
|
@@ -244,10 +246,14 @@ function regenerateAgentCommands(deps = {}) {
|
|
|
244
246
|
const squadAgents = fs.readdirSync(agentsDir).filter(f => f.endsWith('.md'));
|
|
245
247
|
for (const file of squadAgents) {
|
|
246
248
|
const agentId = file.replace('.md', '');
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
249
|
+
registerDefinition({
|
|
250
|
+
id: agentId,
|
|
251
|
+
file,
|
|
252
|
+
origin: path.join(agentsDir, file),
|
|
253
|
+
squadName: squad.name,
|
|
254
|
+
squadPath,
|
|
255
|
+
hasManifest: true,
|
|
256
|
+
});
|
|
251
257
|
}
|
|
252
258
|
}
|
|
253
259
|
|
|
@@ -257,29 +263,37 @@ function regenerateAgentCommands(deps = {}) {
|
|
|
257
263
|
if (fs.existsSync(coreAgentsDir)) {
|
|
258
264
|
const coreBase = toForwardSlash(coreDevelopmentDest);
|
|
259
265
|
for (const file of fs.readdirSync(coreAgentsDir).filter(f => f.endsWith('.md'))) {
|
|
260
|
-
if (file === 'README.md' || file === 'MEMORY.md' || file.startsWith('_')
|
|
266
|
+
if (file === 'README.md' || file === 'MEMORY.md' || file.startsWith('_')) continue;
|
|
261
267
|
const agentId = file.replace('.md', '');
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
268
|
+
registerDefinition({
|
|
269
|
+
id: agentId,
|
|
270
|
+
file,
|
|
271
|
+
origin: path.join(coreAgentsDir, file),
|
|
272
|
+
squadName: 'core',
|
|
273
|
+
squadPath: coreBase,
|
|
274
|
+
hasManifest: false,
|
|
275
|
+
});
|
|
266
276
|
}
|
|
267
277
|
}
|
|
268
278
|
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
279
|
+
fs.mkdirSync(commandsDir, { recursive: true });
|
|
280
|
+
for (const file of fs.readdirSync(commandsDir)) {
|
|
281
|
+
fs.unlinkSync(path.join(commandsDir, file));
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
for (const definition of definitions) {
|
|
285
|
+
const meta = extractAgentMeta(definition.origin);
|
|
286
|
+
const cmdContent = generateCommandMd(
|
|
287
|
+
definition.id,
|
|
288
|
+
meta.name,
|
|
289
|
+
meta.icon,
|
|
290
|
+
definition.squadName,
|
|
291
|
+
definition.squadPath,
|
|
292
|
+
definition.file,
|
|
293
|
+
{ hasManifest: definition.hasManifest },
|
|
294
|
+
);
|
|
295
|
+
atomicWriteFileSync(path.join(commandsDir, definition.file), cmdContent);
|
|
296
|
+
writtenAgents.add(definition.file);
|
|
283
297
|
}
|
|
284
298
|
|
|
285
299
|
// 3. Master entry points (@sinapse, @snps, @sinapse-orqx, @snps-orqx) → rich
|
|
@@ -301,7 +315,16 @@ function regenerateAgentCommands(deps = {}) {
|
|
|
301
315
|
}
|
|
302
316
|
}
|
|
303
317
|
|
|
304
|
-
|
|
318
|
+
const aliasEntryPoints = [...MASTER_ALIAS_ENTRY_POINTS]
|
|
319
|
+
.filter((id) => writtenAgents.has(`${id}.md`));
|
|
320
|
+
const canonicalAgents = definitions.map(({ id, file, origin }) => ({ id, file, origin }));
|
|
321
|
+
|
|
322
|
+
return {
|
|
323
|
+
writtenAgents,
|
|
324
|
+
canonicalAgents,
|
|
325
|
+
aliasEntryPoints,
|
|
326
|
+
totalAgents: canonicalAgents.length,
|
|
327
|
+
};
|
|
305
328
|
}
|
|
306
329
|
|
|
307
330
|
module.exports = {
|
|
@@ -309,4 +332,5 @@ module.exports = {
|
|
|
309
332
|
generateMasterStub,
|
|
310
333
|
regenerateAgentCommands,
|
|
311
334
|
countCoreAgents,
|
|
335
|
+
MASTER_ALIAS_ENTRY_POINTS,
|
|
312
336
|
};
|