@cloudstreamsoftware/claude-tools 1.0.0 → 1.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/README.md +152 -37
- package/agents/INDEX.md +183 -0
- package/agents/architect.md +247 -0
- package/agents/build-error-resolver.md +555 -0
- package/agents/catalyst-deployer.md +132 -0
- package/agents/code-reviewer.md +121 -0
- package/agents/compliance-auditor.md +148 -0
- package/agents/creator-architect.md +395 -0
- package/agents/deluge-reviewer.md +98 -0
- package/agents/doc-updater.md +471 -0
- package/agents/e2e-runner.md +711 -0
- package/agents/planner.md +122 -0
- package/agents/refactor-cleaner.md +309 -0
- package/agents/security-reviewer.md +582 -0
- package/agents/tdd-guide.md +302 -0
- package/config/versions.json +63 -0
- package/dist/hooks/hooks.json +209 -0
- package/dist/index.js +47 -0
- package/dist/lib/asset-value.js +609 -0
- package/dist/lib/client-manager.js +300 -0
- package/dist/lib/command-matcher.js +242 -0
- package/dist/lib/cross-session-patterns.js +754 -0
- package/dist/lib/intent-classifier.js +1075 -0
- package/dist/lib/package-manager.js +374 -0
- package/dist/lib/recommendation-engine.js +597 -0
- package/dist/lib/session-memory.js +489 -0
- package/dist/lib/skill-effectiveness.js +486 -0
- package/dist/lib/skill-matcher.js +595 -0
- package/dist/lib/tutorial-metrics.js +242 -0
- package/dist/lib/tutorial-progress.js +209 -0
- package/dist/lib/tutorial-renderer.js +431 -0
- package/dist/lib/utils.js +380 -0
- package/dist/lib/verify-formatter.js +143 -0
- package/dist/lib/workflow-state.js +249 -0
- package/hooks/hooks.json +209 -0
- package/package.json +5 -1
- package/scripts/aggregate-sessions.js +290 -0
- package/scripts/branch-name-validator.js +291 -0
- package/scripts/build.js +101 -0
- package/scripts/commands/client-switch.js +231 -0
- package/scripts/deprecate-skill.js +610 -0
- package/scripts/diagnose.js +324 -0
- package/scripts/doc-freshness.js +168 -0
- package/scripts/generate-weekly-digest.js +393 -0
- package/scripts/health-check.js +270 -0
- package/scripts/hooks/credential-check.js +101 -0
- package/scripts/hooks/evaluate-session.js +81 -0
- package/scripts/hooks/pre-compact.js +66 -0
- package/scripts/hooks/prompt-analyzer.js +276 -0
- package/scripts/hooks/prompt-router.js +422 -0
- package/scripts/hooks/quality-gate-enforcer.js +371 -0
- package/scripts/hooks/session-end.js +156 -0
- package/scripts/hooks/session-start.js +195 -0
- package/scripts/hooks/skill-injector.js +333 -0
- package/scripts/hooks/suggest-compact.js +58 -0
- package/scripts/lib/asset-value.js +609 -0
- package/scripts/lib/client-manager.js +300 -0
- package/scripts/lib/command-matcher.js +242 -0
- package/scripts/lib/cross-session-patterns.js +754 -0
- package/scripts/lib/intent-classifier.js +1075 -0
- package/scripts/lib/package-manager.js +374 -0
- package/scripts/lib/recommendation-engine.js +597 -0
- package/scripts/lib/session-memory.js +489 -0
- package/scripts/lib/skill-effectiveness.js +486 -0
- package/scripts/lib/skill-matcher.js +595 -0
- package/scripts/lib/tutorial-metrics.js +242 -0
- package/scripts/lib/tutorial-progress.js +209 -0
- package/scripts/lib/tutorial-renderer.js +431 -0
- package/scripts/lib/utils.js +380 -0
- package/scripts/lib/verify-formatter.js +143 -0
- package/scripts/lib/workflow-state.js +249 -0
- package/scripts/onboard.js +363 -0
- package/scripts/quarterly-report.js +692 -0
- package/scripts/setup-package-manager.js +204 -0
- package/scripts/sync-upstream.js +391 -0
- package/scripts/test.js +108 -0
- package/scripts/tutorial-runner.js +351 -0
- package/scripts/validate-all.js +201 -0
- package/scripts/verifiers/agents.js +245 -0
- package/scripts/verifiers/config.js +186 -0
- package/scripts/verifiers/environment.js +123 -0
- package/scripts/verifiers/hooks.js +188 -0
- package/scripts/verifiers/index.js +38 -0
- package/scripts/verifiers/persistence.js +140 -0
- package/scripts/verifiers/plugin.js +215 -0
- package/scripts/verifiers/skills.js +209 -0
- package/scripts/verify-setup.js +164 -0
- package/skills/INDEX.md +157 -0
- package/skills/backend-patterns/SKILL.md +586 -0
- package/skills/backend-patterns/catalyst-patterns.md +128 -0
- package/skills/bigquery-patterns/SKILL.md +27 -0
- package/skills/bigquery-patterns/performance-optimization.md +518 -0
- package/skills/bigquery-patterns/query-patterns.md +372 -0
- package/skills/bigquery-patterns/schema-design.md +78 -0
- package/skills/cloudstream-project-template/SKILL.md +20 -0
- package/skills/cloudstream-project-template/structure.md +65 -0
- package/skills/coding-standards/SKILL.md +524 -0
- package/skills/coding-standards/deluge-standards.md +83 -0
- package/skills/compliance-patterns/SKILL.md +28 -0
- package/skills/compliance-patterns/hipaa/audit-requirements.md +251 -0
- package/skills/compliance-patterns/hipaa/baa-process.md +298 -0
- package/skills/compliance-patterns/hipaa/data-archival-strategy.md +387 -0
- package/skills/compliance-patterns/hipaa/phi-handling.md +52 -0
- package/skills/compliance-patterns/pci-dss/saq-a-requirements.md +307 -0
- package/skills/compliance-patterns/pci-dss/tokenization-patterns.md +382 -0
- package/skills/compliance-patterns/pci-dss/zoho-checkout-patterns.md +56 -0
- package/skills/compliance-patterns/soc2/access-controls.md +344 -0
- package/skills/compliance-patterns/soc2/audit-logging.md +458 -0
- package/skills/compliance-patterns/soc2/change-management.md +403 -0
- package/skills/compliance-patterns/soc2/deluge-execution-logging.md +407 -0
- package/skills/consultancy-workflows/SKILL.md +19 -0
- package/skills/consultancy-workflows/client-isolation.md +21 -0
- package/skills/consultancy-workflows/documentation-automation.md +454 -0
- package/skills/consultancy-workflows/handoff-procedures.md +257 -0
- package/skills/consultancy-workflows/knowledge-capture.md +513 -0
- package/skills/consultancy-workflows/time-tracking.md +26 -0
- package/skills/continuous-learning/SKILL.md +84 -0
- package/skills/continuous-learning/config.json +18 -0
- package/skills/continuous-learning/evaluate-session.sh +60 -0
- package/skills/continuous-learning-v2/SKILL.md +126 -0
- package/skills/continuous-learning-v2/config.json +61 -0
- package/skills/frontend-patterns/SKILL.md +635 -0
- package/skills/frontend-patterns/zoho-widget-patterns.md +103 -0
- package/skills/gcp-data-engineering/SKILL.md +36 -0
- package/skills/gcp-data-engineering/bigquery/performance-optimization.md +337 -0
- package/skills/gcp-data-engineering/dataflow/error-handling.md +496 -0
- package/skills/gcp-data-engineering/dataflow/pipeline-patterns.md +444 -0
- package/skills/gcp-data-engineering/dbt/model-organization.md +63 -0
- package/skills/gcp-data-engineering/dbt/testing-patterns.md +503 -0
- package/skills/gcp-data-engineering/medallion-architecture/bronze-layer.md +60 -0
- package/skills/gcp-data-engineering/medallion-architecture/gold-layer.md +311 -0
- package/skills/gcp-data-engineering/medallion-architecture/layer-transitions.md +517 -0
- package/skills/gcp-data-engineering/medallion-architecture/silver-layer.md +305 -0
- package/skills/gcp-data-engineering/zoho-to-gcp/data-extraction.md +543 -0
- package/skills/gcp-data-engineering/zoho-to-gcp/real-time-vs-batch.md +337 -0
- package/skills/security-review/SKILL.md +498 -0
- package/skills/security-review/compliance-checklist.md +53 -0
- package/skills/strategic-compact/SKILL.md +67 -0
- package/skills/tdd-workflow/SKILL.md +413 -0
- package/skills/tdd-workflow/zoho-testing.md +124 -0
- package/skills/tutorial/SKILL.md +249 -0
- package/skills/tutorial/docs/ACCESSIBILITY.md +169 -0
- package/skills/tutorial/lessons/00-philosophy-and-workflow.md +198 -0
- package/skills/tutorial/lessons/01-basics.md +81 -0
- package/skills/tutorial/lessons/02-training.md +86 -0
- package/skills/tutorial/lessons/03-commands.md +109 -0
- package/skills/tutorial/lessons/04-workflows.md +115 -0
- package/skills/tutorial/lessons/05-compliance.md +116 -0
- package/skills/tutorial/lessons/06-zoho.md +121 -0
- package/skills/tutorial/lessons/07-hooks-system.md +277 -0
- package/skills/tutorial/lessons/08-mcp-servers.md +316 -0
- package/skills/tutorial/lessons/09-client-management.md +215 -0
- package/skills/tutorial/lessons/10-testing-e2e.md +260 -0
- package/skills/tutorial/lessons/11-skills-deep-dive.md +272 -0
- package/skills/tutorial/lessons/12-rules-system.md +326 -0
- package/skills/tutorial/lessons/13-golden-standard-graduation.md +213 -0
- package/skills/tutorial/lessons/14-fork-setup-and-sync.md +312 -0
- package/skills/tutorial/lessons/15-living-examples-system.md +221 -0
- package/skills/tutorial/tracks/accelerated/README.md +134 -0
- package/skills/tutorial/tracks/accelerated/assessment/checkpoint-1.md +161 -0
- package/skills/tutorial/tracks/accelerated/assessment/checkpoint-2.md +175 -0
- package/skills/tutorial/tracks/accelerated/day-1-core-concepts.md +234 -0
- package/skills/tutorial/tracks/accelerated/day-2-essential-commands.md +270 -0
- package/skills/tutorial/tracks/accelerated/day-3-workflow-mastery.md +305 -0
- package/skills/tutorial/tracks/accelerated/day-4-compliance-zoho.md +304 -0
- package/skills/tutorial/tracks/accelerated/day-5-hooks-skills.md +344 -0
- package/skills/tutorial/tracks/accelerated/day-6-client-testing.md +386 -0
- package/skills/tutorial/tracks/accelerated/day-7-graduation.md +369 -0
- package/skills/zoho-patterns/CHANGELOG.md +108 -0
- package/skills/zoho-patterns/SKILL.md +446 -0
- package/skills/zoho-patterns/analytics/dashboard-patterns.md +352 -0
- package/skills/zoho-patterns/analytics/zoho-to-bigquery-pipeline.md +427 -0
- package/skills/zoho-patterns/catalyst/appsail-deployment.md +349 -0
- package/skills/zoho-patterns/catalyst/context-close-patterns.md +354 -0
- package/skills/zoho-patterns/catalyst/cron-batch-processing.md +374 -0
- package/skills/zoho-patterns/catalyst/function-patterns.md +439 -0
- package/skills/zoho-patterns/creator/form-design.md +304 -0
- package/skills/zoho-patterns/creator/publish-api-patterns.md +313 -0
- package/skills/zoho-patterns/creator/widget-integration.md +306 -0
- package/skills/zoho-patterns/creator/workflow-automation.md +253 -0
- package/skills/zoho-patterns/deluge/api-patterns.md +468 -0
- package/skills/zoho-patterns/deluge/batch-processing.md +403 -0
- package/skills/zoho-patterns/deluge/cross-app-integration.md +356 -0
- package/skills/zoho-patterns/deluge/error-handling.md +423 -0
- package/skills/zoho-patterns/deluge/syntax-reference.md +65 -0
- package/skills/zoho-patterns/integration/cors-proxy-architecture.md +426 -0
- package/skills/zoho-patterns/integration/crm-books-native-sync.md +277 -0
- package/skills/zoho-patterns/integration/oauth-token-management.md +461 -0
- package/skills/zoho-patterns/integration/zoho-flow-patterns.md +334 -0
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client Manager - Client Discovery and Context Loading
|
|
3
|
+
*
|
|
4
|
+
* Provides utilities for:
|
|
5
|
+
* - Discovering client directories in clients/
|
|
6
|
+
* - Loading client configuration from CLAUDE.md
|
|
7
|
+
* - Parsing .env.client files
|
|
8
|
+
* - Fetching client-specific git activity
|
|
9
|
+
*
|
|
10
|
+
* @module client-manager
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const fs = require('fs');
|
|
14
|
+
const path = require('path');
|
|
15
|
+
const { runCommand, readFile, log } = require('./utils');
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Get the clients directory path
|
|
19
|
+
* Clients are stored in clients/ at the repo root
|
|
20
|
+
*/
|
|
21
|
+
function getClientsDir() {
|
|
22
|
+
// Look for clients/ relative to the repo root
|
|
23
|
+
// Start from current working directory and search upward
|
|
24
|
+
let currentDir = process.cwd();
|
|
25
|
+
const maxDepth = 10;
|
|
26
|
+
let depth = 0;
|
|
27
|
+
|
|
28
|
+
while (depth < maxDepth) {
|
|
29
|
+
const clientsPath = path.join(currentDir, 'clients');
|
|
30
|
+
if (fs.existsSync(clientsPath) && fs.statSync(clientsPath).isDirectory()) {
|
|
31
|
+
return clientsPath;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Also check if we're in a Claude Code plugin directory
|
|
35
|
+
const pluginClientsPath = path.join(currentDir, '..', 'clients');
|
|
36
|
+
if (fs.existsSync(pluginClientsPath) && fs.statSync(pluginClientsPath).isDirectory()) {
|
|
37
|
+
return pluginClientsPath;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const parentDir = path.dirname(currentDir);
|
|
41
|
+
if (parentDir === currentDir) break; // Reached root
|
|
42
|
+
currentDir = parentDir;
|
|
43
|
+
depth++;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Default to cwd/clients if not found (will be created)
|
|
47
|
+
return path.join(process.cwd(), 'clients');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Discover all client directories
|
|
52
|
+
* @returns {Array<{id: string, path: string, hasConfig: boolean}>}
|
|
53
|
+
*/
|
|
54
|
+
function discoverClients() {
|
|
55
|
+
const clientsDir = getClientsDir();
|
|
56
|
+
const clients = [];
|
|
57
|
+
|
|
58
|
+
if (!fs.existsSync(clientsDir)) {
|
|
59
|
+
return clients;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
const entries = fs.readdirSync(clientsDir, { withFileTypes: true });
|
|
64
|
+
|
|
65
|
+
for (const entry of entries) {
|
|
66
|
+
if (entry.isDirectory() && !entry.name.startsWith('.')) {
|
|
67
|
+
const clientPath = path.join(clientsDir, entry.name);
|
|
68
|
+
const configPath = path.join(clientPath, '.claude', 'CLAUDE.md');
|
|
69
|
+
const hasConfig = fs.existsSync(configPath);
|
|
70
|
+
|
|
71
|
+
clients.push({
|
|
72
|
+
id: entry.name,
|
|
73
|
+
path: clientPath,
|
|
74
|
+
hasConfig,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
} catch (err) {
|
|
79
|
+
log(`[ClientManager] Error discovering clients: ${err.message}`);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return clients;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Parse a client CLAUDE.md file to extract configuration
|
|
87
|
+
* @param {string} configPath - Path to CLAUDE.md
|
|
88
|
+
* @returns {object|null} Parsed configuration
|
|
89
|
+
*/
|
|
90
|
+
function parseClientConfig(configPath) {
|
|
91
|
+
const content = readFile(configPath);
|
|
92
|
+
if (!content) return null;
|
|
93
|
+
|
|
94
|
+
const config = {
|
|
95
|
+
name: null,
|
|
96
|
+
complianceMode: 'standard',
|
|
97
|
+
zohoOrg: null,
|
|
98
|
+
clientId: null,
|
|
99
|
+
industry: null,
|
|
100
|
+
applications: [],
|
|
101
|
+
raw: content,
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
// Parse header - first line is usually "# [Client Name] - Configuration"
|
|
105
|
+
const headerMatch = content.match(/^#\s+(.+?)\s*[-–—]\s*Configuration/m);
|
|
106
|
+
if (headerMatch) {
|
|
107
|
+
config.name = headerMatch[1].trim();
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Parse structured fields
|
|
111
|
+
const patterns = {
|
|
112
|
+
complianceMode: /##\s*Compliance\s*Mode:\s*(\S+)/i,
|
|
113
|
+
zohoOrg: /##\s*Zoho\s*Organization:\s*(\S+)/i,
|
|
114
|
+
clientId: /##\s*Client\s*ID:\s*(\S+)/i,
|
|
115
|
+
industry: /##\s*Industry:\s*(\S+)/i,
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
for (const [key, pattern] of Object.entries(patterns)) {
|
|
119
|
+
const match = content.match(pattern);
|
|
120
|
+
if (match) {
|
|
121
|
+
config[key] = match[1].replace(/[[\]]/g, '').trim();
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Parse applications section
|
|
126
|
+
const appsMatch = content.match(/##\s*Applications\s*\n([\s\S]*?)(?=\n##|\n$|$)/i);
|
|
127
|
+
if (appsMatch) {
|
|
128
|
+
const lines = appsMatch[1].split('\n').filter((l) => l.trim().startsWith('-'));
|
|
129
|
+
config.applications = lines.map((l) => l.replace(/^-\s*/, '').trim());
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return config;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Load a client's .env.client file
|
|
137
|
+
* @param {string} clientPath - Path to client directory
|
|
138
|
+
* @returns {object} Parsed environment variables
|
|
139
|
+
*/
|
|
140
|
+
function loadClientEnv(clientPath) {
|
|
141
|
+
const envPath = path.join(clientPath, '.env.client');
|
|
142
|
+
const env = {};
|
|
143
|
+
|
|
144
|
+
if (!fs.existsSync(envPath)) {
|
|
145
|
+
return env;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const content = readFile(envPath);
|
|
149
|
+
if (!content) return env;
|
|
150
|
+
|
|
151
|
+
const lines = content.split('\n');
|
|
152
|
+
for (const line of lines) {
|
|
153
|
+
const trimmed = line.trim();
|
|
154
|
+
// Skip comments and empty lines
|
|
155
|
+
if (!trimmed || trimmed.startsWith('#')) continue;
|
|
156
|
+
|
|
157
|
+
const eqIndex = trimmed.indexOf('=');
|
|
158
|
+
if (eqIndex > 0) {
|
|
159
|
+
const key = trimmed.substring(0, eqIndex).trim();
|
|
160
|
+
const value = trimmed.substring(eqIndex + 1).trim();
|
|
161
|
+
env[key] = value;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
return env;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Get recent git commits for a client
|
|
170
|
+
* @param {string} clientId - Client ID to filter commits
|
|
171
|
+
* @param {number} count - Number of commits to fetch
|
|
172
|
+
* @returns {Array<{hash: string, message: string}>}
|
|
173
|
+
*/
|
|
174
|
+
function getClientCommits(clientId, count = 5) {
|
|
175
|
+
const commits = [];
|
|
176
|
+
|
|
177
|
+
const result = runCommand(`git log --oneline -${count} --grep="[${clientId}]"`);
|
|
178
|
+
if (!result.success || !result.output) {
|
|
179
|
+
return commits;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const lines = result.output.split('\n').filter(Boolean);
|
|
183
|
+
for (const line of lines) {
|
|
184
|
+
const match = line.match(/^([a-f0-9]+)\s+(.+)$/);
|
|
185
|
+
if (match) {
|
|
186
|
+
commits.push({
|
|
187
|
+
hash: match[1],
|
|
188
|
+
message: match[2],
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return commits;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Load full client context
|
|
198
|
+
* @param {string} clientId - Client identifier
|
|
199
|
+
* @returns {object|null} Full client context or null if not found
|
|
200
|
+
*/
|
|
201
|
+
function loadClient(clientId) {
|
|
202
|
+
const clientsDir = getClientsDir();
|
|
203
|
+
const clientPath = path.join(clientsDir, clientId);
|
|
204
|
+
|
|
205
|
+
if (!fs.existsSync(clientPath)) {
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const configPath = path.join(clientPath, '.claude', 'CLAUDE.md');
|
|
210
|
+
const config = parseClientConfig(configPath);
|
|
211
|
+
|
|
212
|
+
if (!config) {
|
|
213
|
+
// Client directory exists but no config
|
|
214
|
+
return {
|
|
215
|
+
id: clientId,
|
|
216
|
+
path: clientPath,
|
|
217
|
+
name: clientId,
|
|
218
|
+
complianceMode: 'standard',
|
|
219
|
+
zohoOrg: null,
|
|
220
|
+
env: loadClientEnv(clientPath),
|
|
221
|
+
commits: getClientCommits(clientId),
|
|
222
|
+
hasConfig: false,
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
return {
|
|
227
|
+
id: clientId,
|
|
228
|
+
path: clientPath,
|
|
229
|
+
name: config.name || clientId,
|
|
230
|
+
complianceMode: config.complianceMode,
|
|
231
|
+
zohoOrg: config.zohoOrg,
|
|
232
|
+
clientId: config.clientId || clientId,
|
|
233
|
+
industry: config.industry,
|
|
234
|
+
applications: config.applications,
|
|
235
|
+
env: loadClientEnv(clientPath),
|
|
236
|
+
commits: getClientCommits(config.clientId || clientId),
|
|
237
|
+
hasConfig: true,
|
|
238
|
+
config,
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Get compliance requirements for a mode
|
|
244
|
+
* @param {string} mode - Compliance mode
|
|
245
|
+
* @returns {Array<string>} List of requirements
|
|
246
|
+
*/
|
|
247
|
+
function getComplianceRequirements(mode) {
|
|
248
|
+
const requirements = {
|
|
249
|
+
hipaa: [
|
|
250
|
+
'ePHI field handling enabled',
|
|
251
|
+
'BAA documentation required',
|
|
252
|
+
'Audit log archival: 7 years',
|
|
253
|
+
'Session timeout: 15 minutes',
|
|
254
|
+
'All PHI fields must use [PHI] prefix',
|
|
255
|
+
],
|
|
256
|
+
soc2: [
|
|
257
|
+
'Audit logging enabled',
|
|
258
|
+
'Change management required',
|
|
259
|
+
'Access controls documented',
|
|
260
|
+
'Annual compliance review',
|
|
261
|
+
],
|
|
262
|
+
'pci-dss': [
|
|
263
|
+
'Use Zoho Checkout only for payments',
|
|
264
|
+
'Tokenization required for card data',
|
|
265
|
+
'SAQ-A compliance level',
|
|
266
|
+
'No PAN storage allowed',
|
|
267
|
+
],
|
|
268
|
+
standard: ['Standard development practices', 'Code review required'],
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
return requirements[mode] || requirements.standard;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Set environment variables for a client context
|
|
276
|
+
* @param {object} client - Client context from loadClient
|
|
277
|
+
*/
|
|
278
|
+
function setClientEnvironment(client) {
|
|
279
|
+
// Set CloudStream-specific env vars
|
|
280
|
+
process.env.CLOUDSTREAM_CLIENT_ID = client.clientId || client.id;
|
|
281
|
+
process.env.CLOUDSTREAM_COMPLIANCE_MODE = client.complianceMode;
|
|
282
|
+
|
|
283
|
+
// Set env vars from .env.client
|
|
284
|
+
for (const [key, value] of Object.entries(client.env)) {
|
|
285
|
+
if (value) {
|
|
286
|
+
process.env[key] = value;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
module.exports = {
|
|
292
|
+
getClientsDir,
|
|
293
|
+
discoverClients,
|
|
294
|
+
parseClientConfig,
|
|
295
|
+
loadClientEnv,
|
|
296
|
+
getClientCommits,
|
|
297
|
+
loadClient,
|
|
298
|
+
getComplianceRequirements,
|
|
299
|
+
setClientEnvironment,
|
|
300
|
+
};
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command Matcher - Maps Detected Intents to Optimal Commands/Agents
|
|
3
|
+
*
|
|
4
|
+
* Takes classified intents from intent-classifier and maps them to
|
|
5
|
+
* the appropriate CloudStream Claude Code commands and agents.
|
|
6
|
+
*
|
|
7
|
+
* @module command-matcher
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Intent to command/agent mapping
|
|
12
|
+
*
|
|
13
|
+
* Structure:
|
|
14
|
+
* - command: The slash command to invoke
|
|
15
|
+
* - agent: Primary agent that handles this intent
|
|
16
|
+
* - agents: Array of agents (if multiple are needed)
|
|
17
|
+
* - model: Preferred model (opus for complex, sonnet for execution)
|
|
18
|
+
* - description: Human-readable description
|
|
19
|
+
*/
|
|
20
|
+
const INTENT_TO_COMMAND = {
|
|
21
|
+
PLANNING: {
|
|
22
|
+
command: '/plan',
|
|
23
|
+
agent: 'planner',
|
|
24
|
+
model: 'opus',
|
|
25
|
+
description: 'Strategic planner for feature design and architecture decisions',
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
TESTING: {
|
|
29
|
+
command: '/tdd',
|
|
30
|
+
agent: 'tdd-guide',
|
|
31
|
+
model: 'sonnet',
|
|
32
|
+
description: 'Test-driven development specialist enforcing 80%+ coverage',
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
REVIEW: {
|
|
36
|
+
command: '/code-review',
|
|
37
|
+
agent: 'code-reviewer',
|
|
38
|
+
agents: ['code-reviewer', 'security-reviewer'],
|
|
39
|
+
model: 'sonnet',
|
|
40
|
+
description: 'Comprehensive code and security review',
|
|
41
|
+
},
|
|
42
|
+
|
|
43
|
+
SECURITY: {
|
|
44
|
+
command: '/code-review', // Uses code-review with security focus
|
|
45
|
+
agent: 'security-reviewer',
|
|
46
|
+
model: 'opus',
|
|
47
|
+
description: 'Security vulnerability detection and remediation',
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
COMPLIANCE: {
|
|
51
|
+
command: '/compliance-check',
|
|
52
|
+
agent: 'compliance-auditor',
|
|
53
|
+
model: 'opus',
|
|
54
|
+
description: 'HIPAA/SOC2/PCI-DSS compliance audit',
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
ZOHO: {
|
|
58
|
+
command: '/zoho-scaffold',
|
|
59
|
+
agent: 'creator-architect',
|
|
60
|
+
agents: ['creator-architect', 'deluge-reviewer'],
|
|
61
|
+
model: 'opus',
|
|
62
|
+
description: 'Zoho Creator/Catalyst architecture and Deluge development',
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
DEPLOY: {
|
|
66
|
+
command: '/verify',
|
|
67
|
+
agent: 'catalyst-deployer',
|
|
68
|
+
model: 'sonnet',
|
|
69
|
+
description: 'Deployment verification and execution',
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
REFACTOR: {
|
|
73
|
+
command: '/refactor-clean',
|
|
74
|
+
agent: 'refactor-cleaner',
|
|
75
|
+
model: 'sonnet',
|
|
76
|
+
description: 'Dead code cleanup and consolidation',
|
|
77
|
+
},
|
|
78
|
+
|
|
79
|
+
DEBUG: {
|
|
80
|
+
command: '/build-fix',
|
|
81
|
+
agent: 'build-error-resolver',
|
|
82
|
+
model: 'sonnet',
|
|
83
|
+
description: 'Build and TypeScript error resolution',
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
// New intent mappings for full documentation alignment
|
|
87
|
+
|
|
88
|
+
LEARNING: {
|
|
89
|
+
command: '/learn',
|
|
90
|
+
agent: null,
|
|
91
|
+
model: 'sonnet',
|
|
92
|
+
description: 'Extract reusable patterns from current session',
|
|
93
|
+
},
|
|
94
|
+
|
|
95
|
+
SETUP: {
|
|
96
|
+
command: '/onboard',
|
|
97
|
+
agent: null,
|
|
98
|
+
model: 'sonnet',
|
|
99
|
+
description: 'Project setup and initialization wizard',
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
HANDOFF: {
|
|
103
|
+
command: '/handoff',
|
|
104
|
+
agent: 'doc-updater',
|
|
105
|
+
model: 'sonnet',
|
|
106
|
+
description: 'Client handoff documentation generation',
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
E2E: {
|
|
110
|
+
command: '/e2e',
|
|
111
|
+
agent: 'e2e-runner',
|
|
112
|
+
model: 'sonnet',
|
|
113
|
+
description: 'End-to-end test generation with Playwright',
|
|
114
|
+
},
|
|
115
|
+
|
|
116
|
+
DOCUMENTATION: {
|
|
117
|
+
command: '/update-docs',
|
|
118
|
+
agent: 'doc-updater',
|
|
119
|
+
model: 'sonnet',
|
|
120
|
+
description: 'Documentation generation and synchronization',
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Match an intent to its optimal command/agent configuration
|
|
126
|
+
*
|
|
127
|
+
* @param {string} intent - The classified intent (e.g., 'PLANNING', 'TESTING')
|
|
128
|
+
* @returns {object|null} Command configuration or null if no match
|
|
129
|
+
*/
|
|
130
|
+
function matchCommand(intent) {
|
|
131
|
+
// Handle null/undefined/empty input
|
|
132
|
+
if (!intent || typeof intent !== 'string') {
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Normalize intent to uppercase
|
|
137
|
+
const normalizedIntent = intent.toUpperCase();
|
|
138
|
+
|
|
139
|
+
// UNKNOWN intent returns null
|
|
140
|
+
if (normalizedIntent === 'UNKNOWN') {
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Look up the mapping
|
|
145
|
+
const mapping = INTENT_TO_COMMAND[normalizedIntent];
|
|
146
|
+
|
|
147
|
+
if (!mapping) {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// Return a copy to prevent mutation
|
|
152
|
+
return {
|
|
153
|
+
command: mapping.command,
|
|
154
|
+
agent: mapping.agent,
|
|
155
|
+
agents: mapping.agents || [mapping.agent],
|
|
156
|
+
model: mapping.model,
|
|
157
|
+
description: mapping.description,
|
|
158
|
+
intent: normalizedIntent,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Format a complete command string with the user's task
|
|
164
|
+
*
|
|
165
|
+
* @param {string} intent - The classified intent
|
|
166
|
+
* @param {string} task - The user's task description
|
|
167
|
+
* @returns {string|null} Formatted command string or null if no match
|
|
168
|
+
*/
|
|
169
|
+
function formatCommand(intent, task = '') {
|
|
170
|
+
const mapping = matchCommand(intent);
|
|
171
|
+
|
|
172
|
+
if (!mapping) {
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// Clean the task - remove any leading/trailing whitespace
|
|
177
|
+
const cleanTask = task.trim();
|
|
178
|
+
|
|
179
|
+
// Some commands don't need arguments
|
|
180
|
+
const commandsWithoutArgs = ['/verify', '/code-review', '/compliance-check'];
|
|
181
|
+
|
|
182
|
+
if (commandsWithoutArgs.includes(mapping.command) || !cleanTask) {
|
|
183
|
+
return mapping.command;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Format the command with the task
|
|
187
|
+
return `${mapping.command} ${cleanTask}`;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Get all available command mappings
|
|
192
|
+
*
|
|
193
|
+
* @returns {object} All intent-to-command mappings
|
|
194
|
+
*/
|
|
195
|
+
function getAllMappings() {
|
|
196
|
+
return { ...INTENT_TO_COMMAND };
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Check if an intent has a valid mapping
|
|
201
|
+
*
|
|
202
|
+
* @param {string} intent - The intent to check
|
|
203
|
+
* @returns {boolean} True if intent has a mapping
|
|
204
|
+
*/
|
|
205
|
+
function hasMapping(intent) {
|
|
206
|
+
if (!intent || typeof intent !== 'string') {
|
|
207
|
+
return false;
|
|
208
|
+
}
|
|
209
|
+
return intent.toUpperCase() in INTENT_TO_COMMAND;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Get commands that use Opus model (complex tasks)
|
|
214
|
+
*
|
|
215
|
+
* @returns {string[]} Array of intent names that use Opus
|
|
216
|
+
*/
|
|
217
|
+
function getOpusIntents() {
|
|
218
|
+
return Object.entries(INTENT_TO_COMMAND)
|
|
219
|
+
.filter(([_, config]) => config.model === 'opus')
|
|
220
|
+
.map(([intent]) => intent);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Get commands that use Sonnet model (execution tasks)
|
|
225
|
+
*
|
|
226
|
+
* @returns {string[]} Array of intent names that use Sonnet
|
|
227
|
+
*/
|
|
228
|
+
function getSonnetIntents() {
|
|
229
|
+
return Object.entries(INTENT_TO_COMMAND)
|
|
230
|
+
.filter(([_, config]) => config.model === 'sonnet')
|
|
231
|
+
.map(([intent]) => intent);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
module.exports = {
|
|
235
|
+
matchCommand,
|
|
236
|
+
formatCommand,
|
|
237
|
+
getAllMappings,
|
|
238
|
+
hasMapping,
|
|
239
|
+
getOpusIntents,
|
|
240
|
+
getSonnetIntents,
|
|
241
|
+
INTENT_TO_COMMAND,
|
|
242
|
+
};
|