aios-core 4.0.2 → 4.1.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/.aios-core/cli/commands/migrate/analyze.js +6 -6
- package/.aios-core/cli/commands/migrate/backup.js +2 -2
- package/.aios-core/cli/commands/migrate/execute.js +4 -4
- package/.aios-core/cli/commands/migrate/index.js +5 -5
- package/.aios-core/cli/commands/migrate/rollback.js +6 -6
- package/.aios-core/cli/commands/migrate/update-imports.js +2 -2
- package/.aios-core/cli/commands/migrate/validate.js +2 -2
- package/.aios-core/cli/commands/pro/index.js +52 -0
- package/.aios-core/cli/index.js +1 -1
- package/.aios-core/core/ids/registry-updater.js +29 -3
- package/.aios-core/core/migration/migration-config.yaml +2 -2
- package/.aios-core/core/migration/module-mapping.yaml +2 -2
- package/.aios-core/core/registry/README.md +2 -2
- package/.aios-core/core/synapse/context/context-builder.js +34 -0
- package/.aios-core/core/synapse/diagnostics/collectors/consistency-collector.js +168 -0
- package/.aios-core/core/synapse/diagnostics/collectors/hook-collector.js +129 -0
- package/.aios-core/core/synapse/diagnostics/collectors/manifest-collector.js +82 -0
- package/.aios-core/core/synapse/diagnostics/collectors/output-analyzer.js +134 -0
- package/.aios-core/core/synapse/diagnostics/collectors/pipeline-collector.js +75 -0
- package/.aios-core/core/synapse/diagnostics/collectors/quality-collector.js +252 -0
- package/.aios-core/core/synapse/diagnostics/collectors/relevance-matrix.js +174 -0
- package/.aios-core/core/synapse/diagnostics/collectors/safe-read-json.js +31 -0
- package/.aios-core/core/synapse/diagnostics/collectors/session-collector.js +102 -0
- package/.aios-core/core/synapse/diagnostics/collectors/timing-collector.js +126 -0
- package/.aios-core/core/synapse/diagnostics/collectors/uap-collector.js +83 -0
- package/.aios-core/core/synapse/diagnostics/report-formatter.js +484 -0
- package/.aios-core/core/synapse/diagnostics/synapse-diagnostics.js +95 -0
- package/.aios-core/core/synapse/engine.js +73 -20
- package/.aios-core/core/synapse/runtime/hook-runtime.js +60 -0
- package/.aios-core/core-config.yaml +6 -0
- package/.aios-core/data/agent-config-requirements.yaml +2 -2
- package/.aios-core/data/aios-kb.md +4 -4
- package/.aios-core/data/entity-registry.yaml +5 -5
- package/.aios-core/development/agents/architect.md +10 -10
- package/.aios-core/development/agents/devops.md +93 -50
- package/.aios-core/development/agents/qa.md +94 -40
- package/.aios-core/development/agents/ux-design-expert.md +25 -25
- package/.aios-core/development/scripts/activation-runtime.js +63 -0
- package/.aios-core/development/scripts/generate-greeting.js +9 -8
- package/.aios-core/development/scripts/unified-activation-pipeline.js +102 -2
- package/.aios-core/development/tasks/{db-expansion-pack-integration.md → db-squad-integration.md} +5 -5
- package/.aios-core/development/tasks/{integrate-expansion-pack.md → integrate-squad.md} +2 -2
- package/.aios-core/development/tasks/next.md +3 -3
- package/.aios-core/development/tasks/pr-automation.md +2 -2
- package/.aios-core/development/tasks/publish-npm.md +257 -0
- package/.aios-core/development/tasks/release-management.md +4 -4
- package/.aios-core/development/tasks/setup-github.md +1 -1
- package/.aios-core/development/tasks/squad-creator-migrate.md +1 -1
- package/.aios-core/development/tasks/squad-creator-sync-ide-command.md +14 -14
- package/.aios-core/development/tasks/update-aios.md +1 -1
- package/.aios-core/docs/standards/AIOS-COLOR-PALETTE-QUICK-REFERENCE.md +1 -1
- package/.aios-core/docs/standards/AIOS-COLOR-PALETTE-V2.1.md +5 -5
- package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO-V2.1-COMPLETE.md +21 -21
- package/.aios-core/docs/standards/AIOS-LIVRO-DE-OURO-V2.2-SUMMARY.md +25 -25
- package/.aios-core/docs/standards/OPEN-SOURCE-VS-SERVICE-DIFFERENCES.md +4 -4
- package/.aios-core/docs/standards/QUALITY-GATES-SPECIFICATION.md +3 -3
- package/.aios-core/docs/standards/STANDARDS-INDEX.md +13 -13
- package/.aios-core/docs/standards/STORY-TEMPLATE-V2-SPECIFICATION.md +1 -1
- package/.aios-core/framework-config.yaml +4 -0
- package/.aios-core/infrastructure/scripts/codex-skills-sync/index.js +182 -0
- package/.aios-core/infrastructure/scripts/codex-skills-sync/validate.js +172 -0
- package/.aios-core/infrastructure/scripts/ide-sync/README.md +14 -0
- package/.aios-core/infrastructure/scripts/ide-sync/index.js +6 -0
- package/.aios-core/infrastructure/scripts/tool-resolver.js +4 -4
- package/.aios-core/infrastructure/scripts/validate-paths.js +142 -0
- package/.aios-core/infrastructure/templates/aios-sync.yaml.template +11 -11
- package/.aios-core/infrastructure/templates/github-workflows/README.md +1 -1
- package/.aios-core/install-manifest.yaml +190 -106
- package/.aios-core/local-config.yaml.template +2 -0
- package/.aios-core/product/README.md +2 -2
- package/.aios-core/product/data/integration-patterns.md +1 -1
- package/.aios-core/product/templates/ide-rules/cline-rules.md +1 -1
- package/.aios-core/product/templates/ide-rules/codex-rules.md +65 -0
- package/.aios-core/product/templates/ide-rules/copilot-rules.md +1 -1
- package/.aios-core/product/templates/ide-rules/roo-rules.md +1 -1
- package/.aios-core/user-guide.md +15 -14
- package/.aios-core/workflow-intelligence/engine/output-formatter.js +1 -1
- package/.claude/hooks/enforce-architecture-first.py +196 -0
- package/.claude/hooks/install-hooks.sh +41 -0
- package/.claude/hooks/mind-clone-governance.py +192 -0
- package/.claude/hooks/pre-commit-mmos-guard.sh +99 -0
- package/.claude/hooks/pre-commit-version-check.sh +156 -0
- package/.claude/hooks/read-protection.py +151 -0
- package/.claude/hooks/slug-validation.py +176 -0
- package/.claude/hooks/sql-governance.py +182 -0
- package/.claude/hooks/synapse-engine.js +9 -20
- package/.claude/hooks/write-path-validation.py +194 -0
- package/README.md +44 -14
- package/bin/aios-init.js +255 -184
- package/bin/aios-minimal.js +2 -2
- package/bin/aios.js +19 -19
- package/package.json +7 -4
- package/packages/aios-pro-cli/bin/aios-pro.js +75 -2
- package/packages/aios-pro-cli/package.json +5 -1
- package/packages/aios-pro-cli/src/recover.js +100 -0
- package/packages/installer/src/__tests__/performance-benchmark.js +382 -0
- package/packages/installer/src/config/ide-configs.js +12 -1
- package/packages/installer/src/config/templates/core-config-template.js +2 -2
- package/packages/installer/src/installer/aios-core-installer.js +2 -2
- package/packages/installer/src/installer/file-hasher.js +97 -0
- package/packages/installer/src/installer/post-install-validator.js +41 -1
- package/packages/installer/src/pro/pro-scaffolder.js +335 -0
- package/packages/installer/src/utils/aios-colors.js +2 -2
- package/packages/installer/src/wizard/feedback.js +1 -1
- package/packages/installer/src/wizard/ide-config-generator.js +2 -2
- package/packages/installer/src/wizard/index.js +58 -19
- package/packages/installer/src/wizard/pro-setup.js +547 -0
- package/packages/installer/src/wizard/questions.js +20 -14
- package/packages/installer/src/wizard/validators.js +1 -1
- package/scripts/package-synapse.js +323 -0
- package/scripts/validate-package-completeness.js +317 -0
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* SYNAPSE Package Builder — Creates a distributable ZIP for collaborators.
|
|
5
|
+
*
|
|
6
|
+
* Usage: node scripts/package-synapse.js
|
|
7
|
+
* Output: synapse-package.zip in project root
|
|
8
|
+
*
|
|
9
|
+
* The ZIP contains all SYNAPSE files organized by category with a
|
|
10
|
+
* README-INSTALL.md tutorial for setting up SYNAPSE in a new project.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
'use strict';
|
|
14
|
+
|
|
15
|
+
const fs = require('fs');
|
|
16
|
+
const path = require('path');
|
|
17
|
+
const { execSync } = require('child_process');
|
|
18
|
+
|
|
19
|
+
const ROOT = path.resolve(__dirname, '..');
|
|
20
|
+
const OUT_DIR = path.join(ROOT, '.synapse-package');
|
|
21
|
+
const ZIP_NAME = 'synapse-package.zip';
|
|
22
|
+
|
|
23
|
+
// ── File manifest ──────────────────────────────────────────────────────────
|
|
24
|
+
|
|
25
|
+
const FILES = {
|
|
26
|
+
// Core Engine
|
|
27
|
+
'core/engine.js': '.aios-core/core/synapse/engine.js',
|
|
28
|
+
'core/context/context-tracker.js': '.aios-core/core/synapse/context/context-tracker.js',
|
|
29
|
+
'core/domain/domain-loader.js': '.aios-core/core/synapse/domain/domain-loader.js',
|
|
30
|
+
'core/layers/layer-processor.js': '.aios-core/core/synapse/layers/layer-processor.js',
|
|
31
|
+
'core/layers/l0-constitution.js': '.aios-core/core/synapse/layers/l0-constitution.js',
|
|
32
|
+
'core/layers/l1-global.js': '.aios-core/core/synapse/layers/l1-global.js',
|
|
33
|
+
'core/layers/l2-agent.js': '.aios-core/core/synapse/layers/l2-agent.js',
|
|
34
|
+
'core/layers/l3-workflow.js': '.aios-core/core/synapse/layers/l3-workflow.js',
|
|
35
|
+
'core/layers/l4-task.js': '.aios-core/core/synapse/layers/l4-task.js',
|
|
36
|
+
'core/layers/l5-squad.js': '.aios-core/core/synapse/layers/l5-squad.js',
|
|
37
|
+
'core/layers/l6-keyword.js': '.aios-core/core/synapse/layers/l6-keyword.js',
|
|
38
|
+
'core/layers/l7-star-command.js': '.aios-core/core/synapse/layers/l7-star-command.js',
|
|
39
|
+
'core/memory/memory-bridge.js': '.aios-core/core/synapse/memory/memory-bridge.js',
|
|
40
|
+
'core/output/formatter.js': '.aios-core/core/synapse/output/formatter.js',
|
|
41
|
+
'core/session/session-manager.js': '.aios-core/core/synapse/session/session-manager.js',
|
|
42
|
+
'core/scripts/generate-constitution.js': '.aios-core/core/synapse/scripts/generate-constitution.js',
|
|
43
|
+
'core/utils/paths.js': '.aios-core/core/synapse/utils/paths.js',
|
|
44
|
+
'core/utils/tokens.js': '.aios-core/core/synapse/utils/tokens.js',
|
|
45
|
+
|
|
46
|
+
// Diagnostics
|
|
47
|
+
'core/diagnostics/synapse-diagnostics.js': '.aios-core/core/synapse/diagnostics/synapse-diagnostics.js',
|
|
48
|
+
'core/diagnostics/report-formatter.js': '.aios-core/core/synapse/diagnostics/report-formatter.js',
|
|
49
|
+
'core/diagnostics/collectors/safe-read-json.js': '.aios-core/core/synapse/diagnostics/collectors/safe-read-json.js',
|
|
50
|
+
'core/diagnostics/collectors/hook-collector.js': '.aios-core/core/synapse/diagnostics/collectors/hook-collector.js',
|
|
51
|
+
'core/diagnostics/collectors/session-collector.js': '.aios-core/core/synapse/diagnostics/collectors/session-collector.js',
|
|
52
|
+
'core/diagnostics/collectors/manifest-collector.js': '.aios-core/core/synapse/diagnostics/collectors/manifest-collector.js',
|
|
53
|
+
'core/diagnostics/collectors/pipeline-collector.js': '.aios-core/core/synapse/diagnostics/collectors/pipeline-collector.js',
|
|
54
|
+
'core/diagnostics/collectors/uap-collector.js': '.aios-core/core/synapse/diagnostics/collectors/uap-collector.js',
|
|
55
|
+
'core/diagnostics/collectors/timing-collector.js': '.aios-core/core/synapse/diagnostics/collectors/timing-collector.js',
|
|
56
|
+
'core/diagnostics/collectors/quality-collector.js': '.aios-core/core/synapse/diagnostics/collectors/quality-collector.js',
|
|
57
|
+
'core/diagnostics/collectors/consistency-collector.js': '.aios-core/core/synapse/diagnostics/collectors/consistency-collector.js',
|
|
58
|
+
'core/diagnostics/collectors/output-analyzer.js': '.aios-core/core/synapse/diagnostics/collectors/output-analyzer.js',
|
|
59
|
+
'core/diagnostics/collectors/relevance-matrix.js': '.aios-core/core/synapse/diagnostics/collectors/relevance-matrix.js',
|
|
60
|
+
|
|
61
|
+
// Hook Entry Point
|
|
62
|
+
'hook/synapse-engine.js': '.claude/hooks/synapse-engine.js',
|
|
63
|
+
|
|
64
|
+
// Commands
|
|
65
|
+
'commands/manager.md': '.claude/commands/synapse/manager.md',
|
|
66
|
+
'commands/tasks/add-rule.md': '.claude/commands/synapse/tasks/add-rule.md',
|
|
67
|
+
'commands/tasks/create-command.md': '.claude/commands/synapse/tasks/create-command.md',
|
|
68
|
+
'commands/tasks/create-domain.md': '.claude/commands/synapse/tasks/create-domain.md',
|
|
69
|
+
'commands/tasks/diagnose-synapse.md': '.claude/commands/synapse/tasks/diagnose-synapse.md',
|
|
70
|
+
'commands/tasks/edit-rule.md': '.claude/commands/synapse/tasks/edit-rule.md',
|
|
71
|
+
'commands/tasks/suggest-domain.md': '.claude/commands/synapse/tasks/suggest-domain.md',
|
|
72
|
+
'commands/tasks/toggle-domain.md': '.claude/commands/synapse/tasks/toggle-domain.md',
|
|
73
|
+
'commands/templates/domain-template': '.claude/commands/synapse/templates/domain-template',
|
|
74
|
+
'commands/templates/manifest-entry-template': '.claude/commands/synapse/templates/manifest-entry-template',
|
|
75
|
+
'commands/utils/manifest-parser-reference.md': '.claude/commands/synapse/utils/manifest-parser-reference.md',
|
|
76
|
+
|
|
77
|
+
// Skills
|
|
78
|
+
'skills/SKILL.md': '.claude/skills/synapse/SKILL.md',
|
|
79
|
+
'skills/references/brackets.md': '.claude/skills/synapse/references/brackets.md',
|
|
80
|
+
'skills/references/commands.md': '.claude/skills/synapse/references/commands.md',
|
|
81
|
+
'skills/references/domains.md': '.claude/skills/synapse/references/domains.md',
|
|
82
|
+
'skills/references/layers.md': '.claude/skills/synapse/references/layers.md',
|
|
83
|
+
'skills/references/manifest.md': '.claude/skills/synapse/references/manifest.md',
|
|
84
|
+
'skills/assets/README.md': '.claude/skills/synapse/assets/README.md',
|
|
85
|
+
|
|
86
|
+
// Documentation
|
|
87
|
+
'docs/SYNAPSE-FLOWCHARTS.md': 'docs/architecture/SYNAPSE/SYNAPSE-FLOWCHARTS.md',
|
|
88
|
+
'docs/DESIGN-SYNAPSE-ENGINE.md': 'docs/architecture/SYNAPSE/docs/DESIGN-SYNAPSE-ENGINE.md',
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
// Runtime domain files to copy from .synapse/
|
|
92
|
+
const RUNTIME_DOMAINS = [
|
|
93
|
+
'manifest', 'constitution', 'global', 'context', 'commands',
|
|
94
|
+
'agent-dev', 'agent-qa', 'agent-architect', 'agent-pm', 'agent-po',
|
|
95
|
+
'agent-sm', 'agent-devops', 'agent-analyst', 'agent-data-engineer',
|
|
96
|
+
'agent-ux', 'agent-aios-master', 'agent-squad-creator',
|
|
97
|
+
'workflow-story-dev', 'workflow-epic-create', 'workflow-arch-review',
|
|
98
|
+
];
|
|
99
|
+
|
|
100
|
+
// ── Build ──────────────────────────────────────────────────────────────────
|
|
101
|
+
|
|
102
|
+
function main() {
|
|
103
|
+
console.log('Building SYNAPSE package...\n');
|
|
104
|
+
|
|
105
|
+
// Clean
|
|
106
|
+
if (fs.existsSync(OUT_DIR)) fs.rmSync(OUT_DIR, { recursive: true });
|
|
107
|
+
fs.mkdirSync(OUT_DIR, { recursive: true });
|
|
108
|
+
|
|
109
|
+
// Copy files
|
|
110
|
+
let copied = 0;
|
|
111
|
+
let missing = 0;
|
|
112
|
+
for (const [dest, src] of Object.entries(FILES)) {
|
|
113
|
+
const srcPath = path.join(ROOT, src);
|
|
114
|
+
const destPath = path.join(OUT_DIR, dest);
|
|
115
|
+
if (!fs.existsSync(srcPath)) {
|
|
116
|
+
console.warn(` SKIP (missing): ${src}`);
|
|
117
|
+
missing++;
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
fs.mkdirSync(path.dirname(destPath), { recursive: true });
|
|
121
|
+
fs.copyFileSync(srcPath, destPath);
|
|
122
|
+
copied++;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Copy runtime domains
|
|
126
|
+
const runtimeDir = path.join(OUT_DIR, 'runtime');
|
|
127
|
+
fs.mkdirSync(runtimeDir, { recursive: true });
|
|
128
|
+
for (const domain of RUNTIME_DOMAINS) {
|
|
129
|
+
const srcPath = path.join(ROOT, '.synapse', domain);
|
|
130
|
+
if (fs.existsSync(srcPath)) {
|
|
131
|
+
fs.copyFileSync(srcPath, path.join(runtimeDir, domain));
|
|
132
|
+
copied++;
|
|
133
|
+
} else {
|
|
134
|
+
console.warn(` SKIP (runtime): .synapse/${domain}`);
|
|
135
|
+
missing++;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Copy tests
|
|
140
|
+
const testsDir = path.join(OUT_DIR, 'tests');
|
|
141
|
+
copyDirRecursive(path.join(ROOT, 'tests', 'synapse'), testsDir);
|
|
142
|
+
|
|
143
|
+
// Generate README-INSTALL.md
|
|
144
|
+
generateReadme(OUT_DIR);
|
|
145
|
+
|
|
146
|
+
console.log(`\nCopied: ${copied} files | Missing: ${missing} files`);
|
|
147
|
+
|
|
148
|
+
// Create ZIP
|
|
149
|
+
const zipPath = path.join(ROOT, ZIP_NAME);
|
|
150
|
+
if (fs.existsSync(zipPath)) fs.unlinkSync(zipPath);
|
|
151
|
+
|
|
152
|
+
try {
|
|
153
|
+
// Use PowerShell Compress-Archive on Windows
|
|
154
|
+
execSync(
|
|
155
|
+
`powershell -Command "Compress-Archive -Path '${OUT_DIR}\\*' -DestinationPath '${zipPath}' -Force"`,
|
|
156
|
+
{ stdio: 'inherit' },
|
|
157
|
+
);
|
|
158
|
+
console.log(`\nZIP created: ${ZIP_NAME}`);
|
|
159
|
+
console.log(`Size: ${(fs.statSync(zipPath).size / 1024).toFixed(1)} KB`);
|
|
160
|
+
} catch (err) {
|
|
161
|
+
console.error('Failed to create ZIP:', err.message);
|
|
162
|
+
console.log(`Package directory still available at: ${OUT_DIR}`);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Cleanup temp dir
|
|
166
|
+
if (fs.existsSync(zipPath) && fs.existsSync(OUT_DIR)) {
|
|
167
|
+
fs.rmSync(OUT_DIR, { recursive: true });
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function copyDirRecursive(src, dest) {
|
|
172
|
+
if (!fs.existsSync(src)) return;
|
|
173
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
174
|
+
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
175
|
+
const srcPath = path.join(src, entry.name);
|
|
176
|
+
const destPath = path.join(dest, entry.name);
|
|
177
|
+
if (entry.isDirectory()) {
|
|
178
|
+
copyDirRecursive(srcPath, destPath);
|
|
179
|
+
} else {
|
|
180
|
+
fs.copyFileSync(srcPath, destPath);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function generateReadme(outDir) {
|
|
186
|
+
const content = `# SYNAPSE Context Engine — Installation Guide
|
|
187
|
+
|
|
188
|
+
## What is SYNAPSE?
|
|
189
|
+
|
|
190
|
+
SYNAPSE (Synkra Adaptive Processing & State Engine) is the JIT context injection
|
|
191
|
+
engine for AIOS. On every user prompt, it injects \`<synapse-rules>\` with adaptive
|
|
192
|
+
contextual rules through an 8-layer pipeline.
|
|
193
|
+
|
|
194
|
+
## Prerequisites
|
|
195
|
+
|
|
196
|
+
- **Node.js** 18+
|
|
197
|
+
- **Claude Code** CLI with hook support
|
|
198
|
+
- **AIOS Core** installed (\`npx aios-core install\`)
|
|
199
|
+
|
|
200
|
+
## Quick Install
|
|
201
|
+
|
|
202
|
+
### 1. Copy Core Engine
|
|
203
|
+
|
|
204
|
+
Copy the \`core/\` directory to your project:
|
|
205
|
+
|
|
206
|
+
\`\`\`
|
|
207
|
+
cp -r core/ <your-project>/.aios-core/core/synapse/
|
|
208
|
+
\`\`\`
|
|
209
|
+
|
|
210
|
+
### 2. Copy Hook Entry Point
|
|
211
|
+
|
|
212
|
+
\`\`\`
|
|
213
|
+
cp hook/synapse-engine.js <your-project>/.claude/hooks/
|
|
214
|
+
\`\`\`
|
|
215
|
+
|
|
216
|
+
### 3. Register the Hook
|
|
217
|
+
|
|
218
|
+
Add to \`.claude/settings.local.json\`:
|
|
219
|
+
|
|
220
|
+
\`\`\`json
|
|
221
|
+
{
|
|
222
|
+
"hooks": {
|
|
223
|
+
"UserPromptSubmit": [
|
|
224
|
+
{
|
|
225
|
+
"type": "command",
|
|
226
|
+
"command": "node .claude/hooks/synapse-engine.js"
|
|
227
|
+
}
|
|
228
|
+
]
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
\`\`\`
|
|
232
|
+
|
|
233
|
+
### 4. Copy Runtime Domains
|
|
234
|
+
|
|
235
|
+
\`\`\`
|
|
236
|
+
cp -r runtime/ <your-project>/.synapse/
|
|
237
|
+
mkdir -p <your-project>/.synapse/sessions
|
|
238
|
+
mkdir -p <your-project>/.synapse/metrics
|
|
239
|
+
mkdir -p <your-project>/.synapse/cache
|
|
240
|
+
\`\`\`
|
|
241
|
+
|
|
242
|
+
### 5. Copy Commands & Skills (Optional)
|
|
243
|
+
|
|
244
|
+
\`\`\`
|
|
245
|
+
cp -r commands/ <your-project>/.claude/commands/synapse/
|
|
246
|
+
cp -r skills/ <your-project>/.claude/skills/synapse/
|
|
247
|
+
\`\`\`
|
|
248
|
+
|
|
249
|
+
### 6. Update .gitignore
|
|
250
|
+
|
|
251
|
+
Add these lines:
|
|
252
|
+
|
|
253
|
+
\`\`\`
|
|
254
|
+
.synapse/sessions/
|
|
255
|
+
.synapse/metrics/
|
|
256
|
+
.synapse/cache/
|
|
257
|
+
!.claude/hooks/synapse-engine.js
|
|
258
|
+
\`\`\`
|
|
259
|
+
|
|
260
|
+
## Verification
|
|
261
|
+
|
|
262
|
+
After installation, activate any agent and run:
|
|
263
|
+
|
|
264
|
+
\`\`\`
|
|
265
|
+
/synapse:tasks:diagnose-synapse
|
|
266
|
+
\`\`\`
|
|
267
|
+
|
|
268
|
+
Expected: All checks PASS, Context Quality grade B or higher.
|
|
269
|
+
|
|
270
|
+
## Architecture
|
|
271
|
+
|
|
272
|
+
See \`docs/SYNAPSE-FLOWCHARTS.md\` for complete visual architecture including:
|
|
273
|
+
- 8-layer pipeline flow
|
|
274
|
+
- Context brackets (FRESH/MODERATE/DEPLETED/CRITICAL)
|
|
275
|
+
- Domain system
|
|
276
|
+
- Session management
|
|
277
|
+
- Diagnostics pipeline (10 collectors)
|
|
278
|
+
- Metrics persistence
|
|
279
|
+
|
|
280
|
+
## Tests
|
|
281
|
+
|
|
282
|
+
Copy \`tests/\` to your project and run:
|
|
283
|
+
|
|
284
|
+
\`\`\`bash
|
|
285
|
+
npx jest synapse
|
|
286
|
+
\`\`\`
|
|
287
|
+
|
|
288
|
+
Expected: 749+ tests passing.
|
|
289
|
+
|
|
290
|
+
## File Structure
|
|
291
|
+
|
|
292
|
+
\`\`\`
|
|
293
|
+
synapse-package/
|
|
294
|
+
├── README-INSTALL.md # This file
|
|
295
|
+
├── core/ # Engine source (.aios-core/core/synapse/)
|
|
296
|
+
│ ├── engine.js # Main orchestrator
|
|
297
|
+
│ ├── context/ # Bracket tracker
|
|
298
|
+
│ ├── domain/ # Manifest + domain loader
|
|
299
|
+
│ ├── layers/ # L0-L7 layer processors
|
|
300
|
+
│ ├── memory/ # MIS bridge (Pro)
|
|
301
|
+
│ ├── output/ # XML formatter
|
|
302
|
+
│ ├── session/ # Session manager
|
|
303
|
+
│ ├── diagnostics/ # Observability (10 collectors)
|
|
304
|
+
│ ├── scripts/ # Constitution generator
|
|
305
|
+
│ └── utils/ # Path + token helpers
|
|
306
|
+
├── hook/ # .claude/hooks/synapse-engine.js
|
|
307
|
+
├── commands/ # .claude/commands/synapse/
|
|
308
|
+
├── skills/ # .claude/skills/synapse/
|
|
309
|
+
├── runtime/ # .synapse/ domain files (manifest, domains)
|
|
310
|
+
├── docs/ # Architecture documentation
|
|
311
|
+
└── tests/ # Full test suite (749+ tests)
|
|
312
|
+
\`\`\`
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
*SYNAPSE Context Engine v2.0 — Synkra AIOS*
|
|
317
|
+
*Generated: ${new Date().toISOString().split('T')[0]}*
|
|
318
|
+
`;
|
|
319
|
+
|
|
320
|
+
fs.writeFileSync(path.join(outDir, 'README-INSTALL.md'), content, 'utf8');
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
main();
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Validate Package Completeness for npm Publishing
|
|
4
|
+
*
|
|
5
|
+
* Ensures the npm tarball contains all critical files and excludes
|
|
6
|
+
* private content before publishing. Runs as prepublishOnly hook.
|
|
7
|
+
*
|
|
8
|
+
* @script scripts/validate-package-completeness.js
|
|
9
|
+
* @story INS-2 - Release Pipeline: Preview to Latest
|
|
10
|
+
*
|
|
11
|
+
* Usage:
|
|
12
|
+
* node scripts/validate-package-completeness.js
|
|
13
|
+
* node scripts/validate-package-completeness.js --verbose
|
|
14
|
+
*
|
|
15
|
+
* Exit codes:
|
|
16
|
+
* 0 - Package is complete and safe to publish
|
|
17
|
+
* 1 - Validation failed (missing files, leaked content, or config issues)
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
const { execSync } = require('child_process');
|
|
21
|
+
const fs = require('fs');
|
|
22
|
+
const path = require('path');
|
|
23
|
+
|
|
24
|
+
const ROOT = path.resolve(__dirname, '..');
|
|
25
|
+
const VERBOSE = process.argv.includes('--verbose') || process.env.VERBOSE === 'true';
|
|
26
|
+
|
|
27
|
+
// ─── Configuration ──────────────────────────────────────────────────────────
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Files/directories that MUST be present in the tarball.
|
|
31
|
+
* Paths are relative to package root, checked as prefixes against tarball entries.
|
|
32
|
+
*/
|
|
33
|
+
const REQUIRED_PATHS = [
|
|
34
|
+
// Hooks (critical - these were missing in v4.0.0)
|
|
35
|
+
'.claude/hooks/synapse-engine.js',
|
|
36
|
+
'.claude/hooks/precompact-session-digest.js',
|
|
37
|
+
// Rules
|
|
38
|
+
'.claude/rules/',
|
|
39
|
+
// CLI binaries
|
|
40
|
+
'bin/aios.js',
|
|
41
|
+
'bin/aios-minimal.js',
|
|
42
|
+
// Core framework
|
|
43
|
+
'.aios-core/core-config.yaml',
|
|
44
|
+
'.aios-core/constitution.md',
|
|
45
|
+
'.aios-core/development/agents/',
|
|
46
|
+
'.aios-core/development/tasks/',
|
|
47
|
+
];
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Paths that MUST NOT appear in the tarball (leak prevention).
|
|
51
|
+
*/
|
|
52
|
+
const EXCLUDED_PATHS = [
|
|
53
|
+
'pro/',
|
|
54
|
+
'.env',
|
|
55
|
+
'.git/',
|
|
56
|
+
'node_modules/',
|
|
57
|
+
'.aios/',
|
|
58
|
+
'tests/',
|
|
59
|
+
];
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Entries required in package.json "files" array.
|
|
63
|
+
*/
|
|
64
|
+
const REQUIRED_FILES_ENTRIES = [
|
|
65
|
+
'.claude/hooks/',
|
|
66
|
+
'.claude/rules/',
|
|
67
|
+
'.aios-core/',
|
|
68
|
+
'bin/',
|
|
69
|
+
];
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Bin entries that must point to existing files.
|
|
73
|
+
*/
|
|
74
|
+
const REQUIRED_BIN_ENTRIES = ['aios', 'aios-core'];
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Runtime dependencies that must be present.
|
|
78
|
+
*/
|
|
79
|
+
const REQUIRED_DEPENDENCIES = ['js-yaml', 'execa', 'chalk', 'commander', 'fs-extra'];
|
|
80
|
+
|
|
81
|
+
// ─── Helpers ────────────────────────────────────────────────────────────────
|
|
82
|
+
|
|
83
|
+
let totalChecks = 0;
|
|
84
|
+
let passedChecks = 0;
|
|
85
|
+
let failedChecks = 0;
|
|
86
|
+
const failures = [];
|
|
87
|
+
|
|
88
|
+
function log(msg) {
|
|
89
|
+
console.log(msg);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function verbose(msg) {
|
|
93
|
+
if (VERBOSE) {
|
|
94
|
+
console.log(` [verbose] ${msg}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
function check(description, passed, detail) {
|
|
99
|
+
totalChecks++;
|
|
100
|
+
if (passed) {
|
|
101
|
+
passedChecks++;
|
|
102
|
+
log(` PASS ${description}`);
|
|
103
|
+
} else {
|
|
104
|
+
failedChecks++;
|
|
105
|
+
const msg = detail ? `${description} -- ${detail}` : description;
|
|
106
|
+
failures.push(msg);
|
|
107
|
+
log(` FAIL ${description}`);
|
|
108
|
+
if (detail) {
|
|
109
|
+
log(` ${detail}`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function getTarballContents() {
|
|
115
|
+
try {
|
|
116
|
+
const output = execSync('npm pack --dry-run --json 2>&1', {
|
|
117
|
+
cwd: ROOT,
|
|
118
|
+
encoding: 'utf8',
|
|
119
|
+
timeout: 30000,
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// npm pack --json outputs a JSON array
|
|
123
|
+
const parsed = JSON.parse(output);
|
|
124
|
+
if (!Array.isArray(parsed) || parsed.length === 0) {
|
|
125
|
+
throw new Error('npm pack --json returned empty result');
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const files = parsed[0].files || [];
|
|
129
|
+
return files.map((f) => f.path);
|
|
130
|
+
} catch (parseError) {
|
|
131
|
+
// Fallback: parse text output from npm pack --dry-run
|
|
132
|
+
verbose(`JSON parse failed, falling back to text output: ${parseError.message}`);
|
|
133
|
+
try {
|
|
134
|
+
const output = execSync('npm pack --dry-run 2>&1', {
|
|
135
|
+
cwd: ROOT,
|
|
136
|
+
encoding: 'utf8',
|
|
137
|
+
timeout: 30000,
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
// Text output has lines like "npm notice 1.2kB .claude/hooks/synapse-engine.js"
|
|
141
|
+
const lines = output.split('\n');
|
|
142
|
+
return lines
|
|
143
|
+
.filter((line) => line.includes('npm notice') && !line.includes('=== Tarball'))
|
|
144
|
+
.map((line) => {
|
|
145
|
+
// Extract file path (last token after size)
|
|
146
|
+
const match = line.match(/npm notice\s+[\d.]+[kMG]?B?\s+(.+)/);
|
|
147
|
+
return match ? match[1].trim() : null;
|
|
148
|
+
})
|
|
149
|
+
.filter(Boolean);
|
|
150
|
+
} catch (fallbackError) {
|
|
151
|
+
log(` FAIL Could not run npm pack: ${fallbackError.message}`);
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
function loadPackageJson() {
|
|
158
|
+
const pkgPath = path.join(ROOT, 'package.json');
|
|
159
|
+
return JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// ─── Validation Phases ──────────────────────────────────────────────────────
|
|
163
|
+
|
|
164
|
+
function validateTarballContents(tarballFiles) {
|
|
165
|
+
log('\n--- Phase 1: Tarball Contents ---\n');
|
|
166
|
+
|
|
167
|
+
if (!tarballFiles) {
|
|
168
|
+
check('npm pack --dry-run executed', false, 'Failed to get tarball contents');
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
verbose(`Tarball contains ${tarballFiles.length} files`);
|
|
173
|
+
|
|
174
|
+
// Check required paths exist
|
|
175
|
+
for (const required of REQUIRED_PATHS) {
|
|
176
|
+
const isDir = required.endsWith('/');
|
|
177
|
+
let found;
|
|
178
|
+
|
|
179
|
+
if (isDir) {
|
|
180
|
+
found = tarballFiles.some((f) => f.startsWith(required) || f.startsWith(`package/${required}`));
|
|
181
|
+
} else {
|
|
182
|
+
found = tarballFiles.some((f) => f === required || f === `package/${required}`);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
check(
|
|
186
|
+
`Required: ${required}`,
|
|
187
|
+
found,
|
|
188
|
+
found ? undefined : `Not found in tarball (${tarballFiles.length} files scanned)`
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Check excluded paths do NOT exist
|
|
193
|
+
for (const excluded of EXCLUDED_PATHS) {
|
|
194
|
+
const leaked = tarballFiles.filter(
|
|
195
|
+
(f) => f.startsWith(excluded) || f.startsWith(`package/${excluded}`)
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
check(
|
|
199
|
+
`Excluded: ${excluded} not in tarball`,
|
|
200
|
+
leaked.length === 0,
|
|
201
|
+
leaked.length > 0 ? `LEAK DETECTED: ${leaked.slice(0, 3).join(', ')}` : undefined
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function validatePackageJson(pkg) {
|
|
207
|
+
log('\n--- Phase 2: package.json Validation ---\n');
|
|
208
|
+
|
|
209
|
+
// Check "files" array includes required entries
|
|
210
|
+
const filesArray = pkg.files || [];
|
|
211
|
+
|
|
212
|
+
for (const entry of REQUIRED_FILES_ENTRIES) {
|
|
213
|
+
const found = filesArray.some((f) => f === entry || f.startsWith(entry));
|
|
214
|
+
check(
|
|
215
|
+
`files[] includes "${entry}"`,
|
|
216
|
+
found,
|
|
217
|
+
found ? undefined : `Add "${entry}" to package.json "files" array`
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Check bin entries point to existing files
|
|
222
|
+
const binEntries = pkg.bin || {};
|
|
223
|
+
for (const name of REQUIRED_BIN_ENTRIES) {
|
|
224
|
+
const binPath = binEntries[name];
|
|
225
|
+
if (!binPath) {
|
|
226
|
+
check(`bin.${name} defined`, false, `Missing bin entry for "${name}"`);
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const fullPath = path.join(ROOT, binPath);
|
|
231
|
+
const exists = fs.existsSync(fullPath);
|
|
232
|
+
check(
|
|
233
|
+
`bin.${name} -> ${binPath} exists`,
|
|
234
|
+
exists,
|
|
235
|
+
exists ? undefined : `File not found: ${fullPath}`
|
|
236
|
+
);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Check runtime dependencies
|
|
240
|
+
const deps = pkg.dependencies || {};
|
|
241
|
+
for (const dep of REQUIRED_DEPENDENCIES) {
|
|
242
|
+
check(
|
|
243
|
+
`dependency: ${dep}`,
|
|
244
|
+
dep in deps,
|
|
245
|
+
dep in deps ? undefined : `Missing runtime dependency "${dep}"`
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
function validateBinScripts() {
|
|
251
|
+
log('\n--- Phase 3: Bin Script Validation ---\n');
|
|
252
|
+
|
|
253
|
+
const pkg = loadPackageJson();
|
|
254
|
+
const binEntries = pkg.bin || {};
|
|
255
|
+
|
|
256
|
+
for (const [name, binPath] of Object.entries(binEntries)) {
|
|
257
|
+
const fullPath = path.join(ROOT, binPath);
|
|
258
|
+
if (!fs.existsSync(fullPath)) {
|
|
259
|
+
verbose(`Skipping shebang check for missing file: ${binPath}`);
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
const content = fs.readFileSync(fullPath, 'utf8');
|
|
264
|
+
const firstLine = content.split('\n')[0];
|
|
265
|
+
const hasShebang = firstLine.startsWith('#!/usr/bin/env node');
|
|
266
|
+
|
|
267
|
+
check(
|
|
268
|
+
`${name} (${binPath}) has correct shebang`,
|
|
269
|
+
hasShebang,
|
|
270
|
+
hasShebang ? undefined : `Expected "#!/usr/bin/env node", got "${firstLine.substring(0, 40)}"`
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// ─── Main ───────────────────────────────────────────────────────────────────
|
|
276
|
+
|
|
277
|
+
function main() {
|
|
278
|
+
log('='.repeat(60));
|
|
279
|
+
log('AIOS-Core Package Completeness Validation');
|
|
280
|
+
log('='.repeat(60));
|
|
281
|
+
|
|
282
|
+
const pkg = loadPackageJson();
|
|
283
|
+
log(`\nPackage: ${pkg.name}@${pkg.version}`);
|
|
284
|
+
|
|
285
|
+
// Phase 1: Tarball contents
|
|
286
|
+
const tarballFiles = getTarballContents();
|
|
287
|
+
validateTarballContents(tarballFiles);
|
|
288
|
+
|
|
289
|
+
// Phase 2: package.json
|
|
290
|
+
validatePackageJson(pkg);
|
|
291
|
+
|
|
292
|
+
// Phase 3: Bin scripts
|
|
293
|
+
validateBinScripts();
|
|
294
|
+
|
|
295
|
+
// Summary
|
|
296
|
+
log('\n' + '='.repeat(60));
|
|
297
|
+
log(`Results: ${passedChecks}/${totalChecks} passed, ${failedChecks} failed`);
|
|
298
|
+
|
|
299
|
+
if (failures.length > 0) {
|
|
300
|
+
log('\nFailures:');
|
|
301
|
+
for (const f of failures) {
|
|
302
|
+
log(` - ${f}`);
|
|
303
|
+
}
|
|
304
|
+
log('\n' + '='.repeat(60));
|
|
305
|
+
log('BLOCKED: Package is NOT safe to publish.');
|
|
306
|
+
log('Fix the issues above before running npm publish.');
|
|
307
|
+
log('='.repeat(60));
|
|
308
|
+
process.exit(1);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
log('\n' + '='.repeat(60));
|
|
312
|
+
log('PASSED: Package is complete and safe to publish.');
|
|
313
|
+
log('='.repeat(60));
|
|
314
|
+
process.exit(0);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
main();
|