monora-ai 2.1.0 → 2.1.4
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 +339 -158
- package/dist/aims_governance.d.ts +238 -0
- package/dist/aims_governance.d.ts.map +1 -0
- package/dist/aims_governance.js +922 -0
- package/dist/alerts.d.ts +16 -0
- package/dist/alerts.d.ts.map +1 -1
- package/dist/alerts.js +16 -0
- package/dist/api.d.ts +6 -0
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +6 -0
- package/dist/assessment.d.ts +85 -0
- package/dist/assessment.d.ts.map +1 -1
- package/dist/assessment.js +525 -13
- package/dist/attribution.d.ts +44 -3
- package/dist/attribution.d.ts.map +1 -1
- package/dist/attribution.js +197 -10
- package/dist/autodetect.d.ts +68 -0
- package/dist/autodetect.d.ts.map +1 -1
- package/dist/autodetect.js +639 -0
- package/dist/bias.d.ts +130 -0
- package/dist/bias.d.ts.map +1 -0
- package/dist/bias.js +223 -0
- package/dist/cli/diagnostics.d.ts +5 -1
- package/dist/cli/diagnostics.d.ts.map +1 -1
- package/dist/cli/diagnostics.js +23 -6
- package/dist/cli/doctor.d.ts +25 -0
- package/dist/cli/doctor.d.ts.map +1 -0
- package/dist/cli/doctor.js +381 -0
- package/dist/cli/fix.d.ts +16 -0
- package/dist/cli/fix.d.ts.map +1 -0
- package/dist/cli/fix.js +284 -0
- package/dist/cli/init.d.ts +57 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +205 -0
- package/dist/cli.js +1564 -177
- package/dist/complianceConsolidation.d.ts +17 -0
- package/dist/complianceConsolidation.d.ts.map +1 -0
- package/dist/complianceConsolidation.js +68 -0
- package/dist/complianceTargets.d.ts +111 -0
- package/dist/complianceTargets.d.ts.map +1 -0
- package/dist/complianceTargets.js +521 -0
- package/dist/config.d.ts +261 -16
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +381 -32
- package/dist/config_migrations.d.ts.map +1 -1
- package/dist/config_migrations.js +38 -1
- package/dist/config_schema.d.ts +2490 -1035
- package/dist/config_schema.d.ts.map +1 -1
- package/dist/config_schema.js +233 -64
- package/dist/context.d.ts +34 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +118 -7
- package/dist/control_backbone.d.ts +128 -0
- package/dist/control_backbone.d.ts.map +1 -0
- package/dist/control_backbone.js +826 -0
- package/dist/data-governance.d.ts +187 -0
- package/dist/data-governance.d.ts.map +1 -0
- package/dist/data-governance.js +424 -0
- package/dist/dataResidency.d.ts +44 -0
- package/dist/dataResidency.d.ts.map +1 -0
- package/dist/dataResidency.js +203 -0
- package/dist/dispatcher.d.ts.map +1 -1
- package/dist/dispatcher.js +17 -5
- package/dist/evidence_store.d.ts +103 -0
- package/dist/evidence_store.d.ts.map +1 -0
- package/dist/evidence_store.js +459 -0
- package/dist/executiveSummary.d.ts +15 -0
- package/dist/executiveSummary.d.ts.map +1 -1
- package/dist/executiveSummary.js +135 -22
- package/dist/identity.d.ts +143 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +231 -0
- package/dist/impact-assessment.d.ts +350 -0
- package/dist/impact-assessment.d.ts.map +1 -0
- package/dist/impact-assessment.js +580 -0
- package/dist/index.d.ts +21 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +254 -5
- package/dist/instrumentation.d.ts +1 -1
- package/dist/instrumentation.d.ts.map +1 -1
- package/dist/instrumentation.js +123 -22
- package/dist/integrations/anthropic.d.ts +3 -0
- package/dist/integrations/anthropic.d.ts.map +1 -1
- package/dist/integrations/anthropic.js +282 -80
- package/dist/integrations/governance.d.ts +33 -0
- package/dist/integrations/governance.d.ts.map +1 -0
- package/dist/integrations/governance.js +208 -0
- package/dist/integrations/langchain.d.ts +4 -0
- package/dist/integrations/langchain.d.ts.map +1 -1
- package/dist/integrations/langchain.js +362 -142
- package/dist/integrations/openai.d.ts +9 -0
- package/dist/integrations/openai.d.ts.map +1 -1
- package/dist/integrations/openai.js +673 -73
- package/dist/iso42001_consolidation.d.ts +16 -0
- package/dist/iso42001_consolidation.d.ts.map +1 -0
- package/dist/iso42001_consolidation.js +413 -0
- package/dist/iso42001_workflows.d.ts +263 -0
- package/dist/iso42001_workflows.d.ts.map +1 -0
- package/dist/iso42001_workflows.js +781 -0
- package/dist/lifecycle.d.ts +299 -0
- package/dist/lifecycle.d.ts.map +1 -0
- package/dist/lifecycle.js +624 -0
- package/dist/lineage.d.ts +2 -2
- package/dist/lineage.d.ts.map +1 -1
- package/dist/lineage.js +9 -16
- package/dist/middleware/express.d.ts.map +1 -1
- package/dist/middleware/express.js +18 -3
- package/dist/middleware/nextjs.js +2 -2
- package/dist/model.d.ts +143 -0
- package/dist/model.d.ts.map +1 -0
- package/dist/model.js +371 -0
- package/dist/onboarding.d.ts +42 -0
- package/dist/onboarding.d.ts.map +1 -0
- package/dist/onboarding.js +1075 -0
- package/dist/oversight.d.ts +264 -0
- package/dist/oversight.d.ts.map +1 -0
- package/dist/oversight.js +497 -0
- package/dist/presets.js +7 -7
- package/dist/quotas.d.ts +171 -0
- package/dist/quotas.d.ts.map +1 -0
- package/dist/quotas.js +259 -0
- package/dist/register.d.ts +13 -0
- package/dist/register.d.ts.map +1 -0
- package/dist/register.js +99 -0
- package/dist/registry.d.ts +1 -0
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +7 -0
- package/dist/registryData.json +43 -6
- package/dist/report.d.ts +2 -1
- package/dist/report.d.ts.map +1 -1
- package/dist/report.js +189 -2
- package/dist/reporting.d.ts +125 -0
- package/dist/reporting.d.ts.map +1 -1
- package/dist/reporting.js +192 -2
- package/dist/resources.d.ts +285 -0
- package/dist/resources.d.ts.map +1 -0
- package/dist/resources.js +643 -0
- package/dist/risk.d.ts +120 -0
- package/dist/risk.d.ts.map +1 -0
- package/dist/risk.js +220 -0
- package/dist/runtime.d.ts +74 -0
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +416 -18
- package/dist/schemaInference.d.ts +92 -0
- package/dist/schemaInference.d.ts.map +1 -0
- package/dist/schemaInference.js +466 -0
- package/dist/schema_validation.js +2 -2
- package/dist/schemas/config.schema.json +118 -4
- package/dist/security_report.js +4 -4
- package/dist/signing.d.ts +1 -1
- package/dist/signing.d.ts.map +1 -1
- package/dist/signing.js +4 -0
- package/dist/sinks/file.d.ts +19 -1
- package/dist/sinks/file.d.ts.map +1 -1
- package/dist/sinks/file.js +82 -13
- package/dist/sinks/https.d.ts +10 -0
- package/dist/sinks/https.d.ts.map +1 -1
- package/dist/sinks/https.js +76 -16
- package/dist/sinks/stdout.d.ts +1 -0
- package/dist/sinks/stdout.d.ts.map +1 -1
- package/dist/sinks/stdout.js +12 -1
- package/dist/spec.d.ts +159 -0
- package/dist/spec.d.ts.map +1 -0
- package/dist/spec.js +391 -0
- package/dist/stakeholders.d.ts +199 -0
- package/dist/stakeholders.d.ts.map +1 -0
- package/dist/stakeholders.js +398 -0
- package/dist/standards.d.ts.map +1 -1
- package/dist/standards.js +160 -2
- package/dist/standards_ingest.d.ts.map +1 -1
- package/dist/standards_ingest.js +1 -4
- package/dist/telemetry.d.ts +16 -2
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/telemetry.js +77 -14
- package/dist/templates/controls/gdpr_control_catalog.json +261 -0
- package/dist/templates/controls/iso42001_control_catalog.json +1443 -0
- package/dist/templates/controls/soc2_control_catalog.json +163 -0
- package/dist/templates/standards/iso42001_claims.json +72 -0
- package/dist/traced_emitter.d.ts.map +1 -1
- package/dist/traced_emitter.js +19 -9
- package/dist/trust_package.d.ts +20 -1
- package/dist/trust_package.d.ts.map +1 -1
- package/dist/trust_package.js +90 -2
- package/dist/verify.d.ts.map +1 -1
- package/dist/verify.js +9 -2
- package/dist/wal.d.ts.map +1 -1
- package/dist/wal.js +2 -1
- package/package.json +14 -1
- package/scripts/postinstall.js +105 -210
- package/templates/controls/gdpr_control_catalog.json +261 -0
- package/templates/controls/iso42001_control_catalog.json +1443 -0
- package/templates/controls/soc2_control_catalog.json +163 -0
- package/templates/standards/iso42001_claims.json +72 -0
package/scripts/postinstall.js
CHANGED
|
@@ -1,17 +1,29 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
3
|
* Postinstall script for Monora SDK
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
*
|
|
5
|
+
* Shows a non-blocking welcome message with setup instructions.
|
|
6
|
+
* Opt-in only - no interactive prompts or data collection during install.
|
|
7
|
+
*
|
|
8
|
+
* Users can register later via: npx monora-ai init
|
|
6
9
|
*/
|
|
7
10
|
|
|
8
|
-
const { spawn } = require('child_process');
|
|
9
11
|
const fs = require('fs');
|
|
10
12
|
const path = require('path');
|
|
11
|
-
const readline = require('readline');
|
|
12
13
|
const crypto = require('crypto');
|
|
13
14
|
|
|
14
|
-
//
|
|
15
|
+
// ANSI color codes for terminal output
|
|
16
|
+
const colors = {
|
|
17
|
+
reset: '\x1b[0m',
|
|
18
|
+
bold: '\x1b[1m',
|
|
19
|
+
dim: '\x1b[2m',
|
|
20
|
+
cyan: '\x1b[36m',
|
|
21
|
+
green: '\x1b[32m',
|
|
22
|
+
yellow: '\x1b[33m',
|
|
23
|
+
blue: '\x1b[34m',
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
// Check if we're in a CI environment
|
|
15
27
|
function isCI() {
|
|
16
28
|
return !!(
|
|
17
29
|
process.env.CI ||
|
|
@@ -22,61 +34,29 @@ function isCI() {
|
|
|
22
34
|
process.env.CIRCLECI ||
|
|
23
35
|
process.env.TRAVIS ||
|
|
24
36
|
process.env.JENKINS_URL ||
|
|
37
|
+
process.env.BUILDKITE ||
|
|
38
|
+
process.env.TF_BUILD ||
|
|
25
39
|
process.env.MONORA_SKIP_POSTINSTALL
|
|
26
40
|
);
|
|
27
41
|
}
|
|
28
42
|
|
|
29
|
-
//
|
|
30
|
-
function
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function isTTY() {
|
|
36
|
-
return process.stdout.isTTY && process.stdin.isTTY;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function findProjectRoot() {
|
|
40
|
-
// Walk up from current directory to find package.json (the user's project)
|
|
41
|
-
let dir = process.cwd();
|
|
42
|
-
const maxLevels = 10;
|
|
43
|
-
|
|
44
|
-
for (let i = 0; i < maxLevels; i++) {
|
|
45
|
-
const pkgPath = path.join(dir, 'package.json');
|
|
46
|
-
if (fs.existsSync(pkgPath)) {
|
|
47
|
-
try {
|
|
48
|
-
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
49
|
-
// Skip if this is the monora-ai package itself
|
|
50
|
-
if (pkg.name !== 'monora-ai') {
|
|
51
|
-
return dir;
|
|
52
|
-
}
|
|
53
|
-
} catch (e) {
|
|
54
|
-
// Continue searching
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
const parent = path.dirname(dir);
|
|
58
|
-
if (parent === dir) break;
|
|
59
|
-
dir = parent;
|
|
43
|
+
// Check if terminal supports colors
|
|
44
|
+
function supportsColor() {
|
|
45
|
+
if (process.env.NO_COLOR || process.env.TERM === 'dumb') {
|
|
46
|
+
return false;
|
|
60
47
|
}
|
|
61
|
-
return process.
|
|
48
|
+
return process.stdout.isTTY;
|
|
62
49
|
}
|
|
63
50
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
'.monora.yaml',
|
|
71
|
-
'.monora.json',
|
|
72
|
-
];
|
|
73
|
-
|
|
74
|
-
return configFiles.some(file =>
|
|
75
|
-
fs.existsSync(path.join(projectRoot, file))
|
|
76
|
-
);
|
|
51
|
+
// Colorize text if supported
|
|
52
|
+
function colorize(text, color) {
|
|
53
|
+
if (!supportsColor()) {
|
|
54
|
+
return text;
|
|
55
|
+
}
|
|
56
|
+
return `${color}${text}${colors.reset}`;
|
|
77
57
|
}
|
|
78
58
|
|
|
79
|
-
// Get the Monora data directory
|
|
59
|
+
// Get the Monora data directory
|
|
80
60
|
function getMonoraDataDir() {
|
|
81
61
|
const home = process.env.HOME || process.env.USERPROFILE;
|
|
82
62
|
if (!home) {
|
|
@@ -85,189 +65,104 @@ function getMonoraDataDir() {
|
|
|
85
65
|
return path.join(home, '.monora');
|
|
86
66
|
}
|
|
87
67
|
|
|
88
|
-
//
|
|
89
|
-
function
|
|
68
|
+
// Record install timestamp for analytics (local only)
|
|
69
|
+
function recordInstallTimestamp() {
|
|
90
70
|
const dataDir = getMonoraDataDir();
|
|
91
71
|
if (!dataDir) {
|
|
92
|
-
|
|
93
|
-
return null;
|
|
94
|
-
}
|
|
95
|
-
const regPath = path.join(dataDir, 'registration.json');
|
|
96
|
-
try {
|
|
97
|
-
if (fs.existsSync(regPath)) {
|
|
98
|
-
return JSON.parse(fs.readFileSync(regPath, 'utf8'));
|
|
99
|
-
}
|
|
100
|
-
} catch (e) {
|
|
101
|
-
// Ignore errors
|
|
72
|
+
return;
|
|
102
73
|
}
|
|
103
|
-
return null;
|
|
104
|
-
}
|
|
105
74
|
|
|
106
|
-
// Save registration data
|
|
107
|
-
function saveRegistration(data) {
|
|
108
|
-
const dataDir = getMonoraDataDir();
|
|
109
|
-
if (!dataDir) {
|
|
110
|
-
console.warn('Monora: HOME/USERPROFILE not set; skipping registration save');
|
|
111
|
-
return false;
|
|
112
|
-
}
|
|
113
75
|
try {
|
|
114
76
|
if (!fs.existsSync(dataDir)) {
|
|
115
77
|
fs.mkdirSync(dataDir, { recursive: true });
|
|
116
78
|
}
|
|
117
|
-
const regPath = path.join(dataDir, 'registration.json');
|
|
118
|
-
fs.writeFileSync(regPath, JSON.stringify(data, null, 2));
|
|
119
|
-
return true;
|
|
120
|
-
} catch (e) {
|
|
121
|
-
return false;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
79
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
80
|
+
const installPath = path.join(dataDir, 'install_info.json');
|
|
81
|
+
const existingData = fs.existsSync(installPath)
|
|
82
|
+
? JSON.parse(fs.readFileSync(installPath, 'utf8'))
|
|
83
|
+
: {};
|
|
84
|
+
|
|
85
|
+
const installInfo = {
|
|
86
|
+
...existingData,
|
|
87
|
+
install_id: existingData.install_id || crypto.randomUUID().replace(/-/g, '').slice(0, 32),
|
|
88
|
+
sdk: 'node',
|
|
89
|
+
first_installed_at: existingData.first_installed_at || new Date().toISOString(),
|
|
90
|
+
last_installed_at: new Date().toISOString(),
|
|
91
|
+
install_count: (existingData.install_count || 0) + 1,
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
fs.writeFileSync(installPath, JSON.stringify(installInfo, null, 2));
|
|
95
|
+
} catch {
|
|
96
|
+
// Silent fail - never break install
|
|
141
97
|
}
|
|
98
|
+
}
|
|
142
99
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
const company = await prompt(rl, ' Company/Organization');
|
|
154
|
-
const role = await prompt(rl, ' Your role (e.g., Developer, ML Engineer)');
|
|
155
|
-
const email = await prompt(rl, ' Email (for product updates, optional)');
|
|
156
|
-
|
|
157
|
-
rl.close();
|
|
100
|
+
// Check if config already exists in project
|
|
101
|
+
function configExists() {
|
|
102
|
+
const configFiles = [
|
|
103
|
+
'monora.yml',
|
|
104
|
+
'monora.yaml',
|
|
105
|
+
'monora.json',
|
|
106
|
+
'.monora.yml',
|
|
107
|
+
'.monora.yaml',
|
|
108
|
+
'.monora.json',
|
|
109
|
+
];
|
|
158
110
|
|
|
159
|
-
|
|
160
|
-
if (company || role || email) {
|
|
161
|
-
const registration = {
|
|
162
|
-
install_id: generateInstallId(),
|
|
163
|
-
company: company || undefined,
|
|
164
|
-
role: role || undefined,
|
|
165
|
-
email: email || undefined,
|
|
166
|
-
sdk_type: 'node',
|
|
167
|
-
source: 'npm',
|
|
168
|
-
registered_at: new Date().toISOString(),
|
|
169
|
-
};
|
|
170
|
-
if (saveRegistration(registration)) {
|
|
171
|
-
console.log('\n ✓ Thanks! Your info has been saved locally.\n');
|
|
172
|
-
}
|
|
173
|
-
return registration;
|
|
174
|
-
} else {
|
|
175
|
-
// Create minimal registration with just install_id
|
|
176
|
-
const registration = {
|
|
177
|
-
install_id: generateInstallId(),
|
|
178
|
-
sdk_type: 'node',
|
|
179
|
-
source: 'npm',
|
|
180
|
-
registered_at: new Date().toISOString(),
|
|
181
|
-
};
|
|
182
|
-
saveRegistration(registration);
|
|
183
|
-
return registration;
|
|
184
|
-
}
|
|
185
|
-
} catch (e) {
|
|
186
|
-
rl.close();
|
|
187
|
-
return null;
|
|
188
|
-
}
|
|
111
|
+
return configFiles.some(file => fs.existsSync(path.join(process.cwd(), file)));
|
|
189
112
|
}
|
|
190
113
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
console.log('\n📦 Monora SDK installed successfully.');
|
|
195
|
-
console.log(' Run "npx monora init" to configure.\n');
|
|
196
|
-
return;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
const projectRoot = findProjectRoot();
|
|
114
|
+
// Display welcome message
|
|
115
|
+
function showWelcomeMessage() {
|
|
116
|
+
const hasConfig = configExists();
|
|
200
117
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
return;
|
|
205
|
-
}
|
|
118
|
+
console.log('');
|
|
119
|
+
console.log(colorize(' Monora AI Governance SDK', colors.bold + colors.cyan));
|
|
120
|
+
console.log('');
|
|
206
121
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
console.log('\n📦 Monora SDK installed successfully!');
|
|
122
|
+
if (hasConfig) {
|
|
123
|
+
console.log(colorize(' ✓ Existing configuration detected', colors.green));
|
|
210
124
|
console.log('');
|
|
211
|
-
|
|
212
|
-
console.log('
|
|
213
|
-
console.log('
|
|
214
|
-
console.log('
|
|
215
|
-
console.log('
|
|
125
|
+
} else {
|
|
126
|
+
console.log(colorize(' Quick Start:', colors.bold));
|
|
127
|
+
console.log('');
|
|
128
|
+
console.log(' ' + colorize('Option 1:', colors.yellow) + ' Zero-config (recommended)');
|
|
129
|
+
console.log(colorize(' import { init } from "monora-ai";', colors.dim));
|
|
130
|
+
console.log(colorize(' init();', colors.dim));
|
|
131
|
+
console.log('');
|
|
132
|
+
console.log(' ' + colorize('Option 2:', colors.yellow) + ' Run setup wizard');
|
|
133
|
+
console.log(colorize(' npx monora-ai init', colors.dim));
|
|
216
134
|
console.log('');
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
// Interactive terminal - run setup wizard
|
|
221
|
-
console.log('\n🚀 Monora SDK installed!');
|
|
222
|
-
|
|
223
|
-
// Collect optional registration data
|
|
224
|
-
try {
|
|
225
|
-
await collectRegistration();
|
|
226
|
-
} catch {
|
|
227
|
-
// Intentionally ignore - registration is optional and should never break install
|
|
228
135
|
}
|
|
229
136
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
137
|
+
console.log(colorize(' Documentation:', colors.bold) + ' https://docs.monora.ai');
|
|
138
|
+
console.log(colorize(' GitHub:', colors.bold) + ' https://github.com/monora-ai/monora');
|
|
139
|
+
console.log('');
|
|
140
|
+
}
|
|
234
141
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
shell: process.platform === 'win32',
|
|
242
|
-
});
|
|
142
|
+
// Display minimal CI message
|
|
143
|
+
function showCIMessage() {
|
|
144
|
+
console.log('');
|
|
145
|
+
console.log('Monora SDK installed. Use init() for zero-config or run "npx monora-ai init".');
|
|
146
|
+
console.log('');
|
|
147
|
+
}
|
|
243
148
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
149
|
+
// Main function
|
|
150
|
+
function main() {
|
|
151
|
+
// Record install timestamp (local only, non-blocking)
|
|
152
|
+
recordInstallTimestamp();
|
|
248
153
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
} else {
|
|
255
|
-
// CLI not built yet (fresh install), show manual instructions
|
|
256
|
-
console.log('Quick Start:');
|
|
257
|
-
console.log(' Option 1: Run "npx monora init" to configure');
|
|
258
|
-
console.log(' Option 2: Use zero-config in your code:');
|
|
259
|
-
console.log(' import { init } from "monora-ai";');
|
|
260
|
-
console.log(' init();');
|
|
261
|
-
console.log('');
|
|
262
|
-
}
|
|
263
|
-
} catch (err) {
|
|
264
|
-
// Silent fail - don't break npm install
|
|
265
|
-
console.log('\n📦 Monora SDK installed.');
|
|
266
|
-
console.log(' Run "npx monora init" to configure.\n');
|
|
154
|
+
// Show appropriate message based on environment
|
|
155
|
+
if (isCI()) {
|
|
156
|
+
showCIMessage();
|
|
157
|
+
} else {
|
|
158
|
+
showWelcomeMessage();
|
|
267
159
|
}
|
|
268
160
|
}
|
|
269
161
|
|
|
270
|
-
|
|
162
|
+
// Execute
|
|
163
|
+
try {
|
|
164
|
+
main();
|
|
165
|
+
} catch {
|
|
271
166
|
// Never fail the install
|
|
272
|
-
console.log('\
|
|
273
|
-
}
|
|
167
|
+
console.log('\nMonora SDK installed.\n');
|
|
168
|
+
}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
{
|
|
2
|
+
"catalog_id": "gdpr_gap_catalog_monora",
|
|
3
|
+
"standard": "GDPR",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"generated_at": "2026-02-16T00:00:00+00:00",
|
|
6
|
+
"notes": "Default GDPR article coverage catalog for workflow gap analysis.",
|
|
7
|
+
"controls": [
|
|
8
|
+
{
|
|
9
|
+
"control_id": "art5",
|
|
10
|
+
"clause": "Art.5",
|
|
11
|
+
"title": "Principles Relating to Processing",
|
|
12
|
+
"requirement": "Apply lawfulness, fairness, transparency, minimization, and integrity principles.",
|
|
13
|
+
"guidance": "Maintain data handling policies and minimization controls.",
|
|
14
|
+
"evidence_types": ["data_handling_policy", "data_minimization_review"],
|
|
15
|
+
"frequency": "quarterly",
|
|
16
|
+
"owner": "Privacy Officer",
|
|
17
|
+
"system": "privacy_governance",
|
|
18
|
+
"collection_method": "manual",
|
|
19
|
+
"status": "gap",
|
|
20
|
+
"priority": "high"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"control_id": "art6",
|
|
24
|
+
"clause": "Art.6",
|
|
25
|
+
"title": "Lawfulness of Processing",
|
|
26
|
+
"requirement": "Document lawful basis for processing.",
|
|
27
|
+
"guidance": "Track legal basis per data processing purpose.",
|
|
28
|
+
"evidence_types": ["lawful_basis_register"],
|
|
29
|
+
"frequency": "quarterly",
|
|
30
|
+
"owner": "Privacy Officer",
|
|
31
|
+
"system": "privacy_governance",
|
|
32
|
+
"collection_method": "manual",
|
|
33
|
+
"status": "gap",
|
|
34
|
+
"priority": "high"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"control_id": "art7",
|
|
38
|
+
"clause": "Art.7",
|
|
39
|
+
"title": "Conditions for Consent",
|
|
40
|
+
"requirement": "Collect and manage valid consent where required.",
|
|
41
|
+
"guidance": "Track consent status and revocation.",
|
|
42
|
+
"evidence_types": ["consent_log", "consent_revocation_log"],
|
|
43
|
+
"frequency": "monthly",
|
|
44
|
+
"owner": "Privacy Officer",
|
|
45
|
+
"system": "consent_management",
|
|
46
|
+
"collection_method": "manual",
|
|
47
|
+
"status": "gap",
|
|
48
|
+
"priority": "high"
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"control_id": "art12",
|
|
52
|
+
"clause": "Art.12",
|
|
53
|
+
"title": "Transparent Information and Communication",
|
|
54
|
+
"requirement": "Provide transparent communications to data subjects.",
|
|
55
|
+
"guidance": "Maintain clear rights and request channels.",
|
|
56
|
+
"evidence_types": ["privacy_notice", "communication_record"],
|
|
57
|
+
"frequency": "quarterly",
|
|
58
|
+
"owner": "Privacy Officer",
|
|
59
|
+
"system": "transparency",
|
|
60
|
+
"collection_method": "manual",
|
|
61
|
+
"status": "gap",
|
|
62
|
+
"priority": "medium"
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"control_id": "art13",
|
|
66
|
+
"clause": "Art.13",
|
|
67
|
+
"title": "Information to Be Provided (Direct Collection)",
|
|
68
|
+
"requirement": "Provide required information when collecting data directly.",
|
|
69
|
+
"guidance": "Maintain direct collection notices and acknowledgments.",
|
|
70
|
+
"evidence_types": ["privacy_notice", "notice_acknowledgement"],
|
|
71
|
+
"frequency": "quarterly",
|
|
72
|
+
"owner": "Privacy Officer",
|
|
73
|
+
"system": "transparency",
|
|
74
|
+
"collection_method": "manual",
|
|
75
|
+
"status": "gap",
|
|
76
|
+
"priority": "medium"
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
"control_id": "art14",
|
|
80
|
+
"clause": "Art.14",
|
|
81
|
+
"title": "Information to Be Provided (Indirect Collection)",
|
|
82
|
+
"requirement": "Provide required information when data is not collected directly.",
|
|
83
|
+
"guidance": "Maintain indirect collection notice process.",
|
|
84
|
+
"evidence_types": ["privacy_notice", "indirect_collection_log"],
|
|
85
|
+
"frequency": "quarterly",
|
|
86
|
+
"owner": "Privacy Officer",
|
|
87
|
+
"system": "transparency",
|
|
88
|
+
"collection_method": "manual",
|
|
89
|
+
"status": "gap",
|
|
90
|
+
"priority": "medium"
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
"control_id": "art15",
|
|
94
|
+
"clause": "Art.15",
|
|
95
|
+
"title": "Right of Access",
|
|
96
|
+
"requirement": "Respond to access requests within legal timelines.",
|
|
97
|
+
"guidance": "Track request intake and fulfillment.",
|
|
98
|
+
"evidence_types": ["data_subject_request_log"],
|
|
99
|
+
"frequency": "monthly",
|
|
100
|
+
"owner": "Privacy Officer",
|
|
101
|
+
"system": "rights_management",
|
|
102
|
+
"collection_method": "manual",
|
|
103
|
+
"status": "gap",
|
|
104
|
+
"priority": "high"
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"control_id": "art16",
|
|
108
|
+
"clause": "Art.16",
|
|
109
|
+
"title": "Right to Rectification",
|
|
110
|
+
"requirement": "Correct inaccurate personal data.",
|
|
111
|
+
"guidance": "Track rectification workflow and completion.",
|
|
112
|
+
"evidence_types": ["rectification_log"],
|
|
113
|
+
"frequency": "monthly",
|
|
114
|
+
"owner": "Privacy Officer",
|
|
115
|
+
"system": "rights_management",
|
|
116
|
+
"collection_method": "manual",
|
|
117
|
+
"status": "gap",
|
|
118
|
+
"priority": "medium"
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
"control_id": "art17",
|
|
122
|
+
"clause": "Art.17",
|
|
123
|
+
"title": "Right to Erasure",
|
|
124
|
+
"requirement": "Erase data when erasure conditions are met.",
|
|
125
|
+
"guidance": "Track erasure requests and outcomes.",
|
|
126
|
+
"evidence_types": ["erasure_log"],
|
|
127
|
+
"frequency": "monthly",
|
|
128
|
+
"owner": "Privacy Officer",
|
|
129
|
+
"system": "rights_management",
|
|
130
|
+
"collection_method": "manual",
|
|
131
|
+
"status": "gap",
|
|
132
|
+
"priority": "high"
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"control_id": "art18",
|
|
136
|
+
"clause": "Art.18",
|
|
137
|
+
"title": "Right to Restriction",
|
|
138
|
+
"requirement": "Restrict processing when requested and applicable.",
|
|
139
|
+
"guidance": "Track restriction states and enforcement.",
|
|
140
|
+
"evidence_types": ["restriction_log"],
|
|
141
|
+
"frequency": "monthly",
|
|
142
|
+
"owner": "Privacy Officer",
|
|
143
|
+
"system": "rights_management",
|
|
144
|
+
"collection_method": "manual",
|
|
145
|
+
"status": "gap",
|
|
146
|
+
"priority": "medium"
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"control_id": "art20",
|
|
150
|
+
"clause": "Art.20",
|
|
151
|
+
"title": "Right to Data Portability",
|
|
152
|
+
"requirement": "Provide portable personal data where applicable.",
|
|
153
|
+
"guidance": "Track portability requests and delivery.",
|
|
154
|
+
"evidence_types": ["portability_log"],
|
|
155
|
+
"frequency": "monthly",
|
|
156
|
+
"owner": "Privacy Officer",
|
|
157
|
+
"system": "rights_management",
|
|
158
|
+
"collection_method": "manual",
|
|
159
|
+
"status": "gap",
|
|
160
|
+
"priority": "medium"
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
"control_id": "art21",
|
|
164
|
+
"clause": "Art.21",
|
|
165
|
+
"title": "Right to Object",
|
|
166
|
+
"requirement": "Honor objections to processing.",
|
|
167
|
+
"guidance": "Track objections and resulting actions.",
|
|
168
|
+
"evidence_types": ["objection_log"],
|
|
169
|
+
"frequency": "monthly",
|
|
170
|
+
"owner": "Privacy Officer",
|
|
171
|
+
"system": "rights_management",
|
|
172
|
+
"collection_method": "manual",
|
|
173
|
+
"status": "gap",
|
|
174
|
+
"priority": "medium"
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
"control_id": "art22",
|
|
178
|
+
"clause": "Art.22",
|
|
179
|
+
"title": "Automated Decision-Making and Profiling",
|
|
180
|
+
"requirement": "Provide safeguards for automated decisions.",
|
|
181
|
+
"guidance": "Maintain human oversight and challenge workflow.",
|
|
182
|
+
"evidence_types": ["human_oversight_record", "automated_decision_review"],
|
|
183
|
+
"frequency": "monthly",
|
|
184
|
+
"owner": "Responsible AI Lead",
|
|
185
|
+
"system": "automated_decisioning",
|
|
186
|
+
"collection_method": "hybrid",
|
|
187
|
+
"status": "gap",
|
|
188
|
+
"priority": "high"
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
"control_id": "art25",
|
|
192
|
+
"clause": "Art.25",
|
|
193
|
+
"title": "Data Protection by Design and by Default",
|
|
194
|
+
"requirement": "Implement privacy by design/default safeguards.",
|
|
195
|
+
"guidance": "Document privacy design reviews.",
|
|
196
|
+
"evidence_types": ["privacy_design_review", "data_minimization_review"],
|
|
197
|
+
"frequency": "quarterly",
|
|
198
|
+
"owner": "Privacy Officer",
|
|
199
|
+
"system": "privacy_engineering",
|
|
200
|
+
"collection_method": "manual",
|
|
201
|
+
"status": "gap",
|
|
202
|
+
"priority": "high"
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
"control_id": "art30",
|
|
206
|
+
"clause": "Art.30",
|
|
207
|
+
"title": "Records of Processing Activities",
|
|
208
|
+
"requirement": "Maintain records of processing activities.",
|
|
209
|
+
"guidance": "Track purposes, categories, recipients, and safeguards.",
|
|
210
|
+
"evidence_types": ["processing_activity_register"],
|
|
211
|
+
"frequency": "quarterly",
|
|
212
|
+
"owner": "Privacy Officer",
|
|
213
|
+
"system": "records_management",
|
|
214
|
+
"collection_method": "manual",
|
|
215
|
+
"status": "gap",
|
|
216
|
+
"priority": "high"
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
"control_id": "art32",
|
|
220
|
+
"clause": "Art.32",
|
|
221
|
+
"title": "Security of Processing",
|
|
222
|
+
"requirement": "Implement appropriate technical and organizational security.",
|
|
223
|
+
"guidance": "Demonstrate confidentiality, integrity, and resilience controls.",
|
|
224
|
+
"evidence_types": ["security_control_report", "incident_response_record"],
|
|
225
|
+
"frequency": "monthly",
|
|
226
|
+
"owner": "Security Lead",
|
|
227
|
+
"system": "security",
|
|
228
|
+
"collection_method": "hybrid",
|
|
229
|
+
"status": "gap",
|
|
230
|
+
"priority": "critical"
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
"control_id": "art33",
|
|
234
|
+
"clause": "Art.33",
|
|
235
|
+
"title": "Breach Notification to Supervisory Authority",
|
|
236
|
+
"requirement": "Notify authority within required timeframe for qualifying breaches.",
|
|
237
|
+
"guidance": "Track breach timeline and authority notifications.",
|
|
238
|
+
"evidence_types": ["breach_notification_log"],
|
|
239
|
+
"frequency": "on_incident",
|
|
240
|
+
"owner": "Security Lead",
|
|
241
|
+
"system": "incident_management",
|
|
242
|
+
"collection_method": "manual",
|
|
243
|
+
"status": "gap",
|
|
244
|
+
"priority": "critical"
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
"control_id": "art35",
|
|
248
|
+
"clause": "Art.35",
|
|
249
|
+
"title": "Data Protection Impact Assessment",
|
|
250
|
+
"requirement": "Perform DPIA for high-risk processing.",
|
|
251
|
+
"guidance": "Maintain DPIA methodology, outcomes, and approvals.",
|
|
252
|
+
"evidence_types": ["dpia_report", "risk_register"],
|
|
253
|
+
"frequency": "per_release",
|
|
254
|
+
"owner": "Responsible AI Lead",
|
|
255
|
+
"system": "risk_management",
|
|
256
|
+
"collection_method": "manual",
|
|
257
|
+
"status": "gap",
|
|
258
|
+
"priority": "high"
|
|
259
|
+
}
|
|
260
|
+
]
|
|
261
|
+
}
|