@hongmaple0820/scale-engine 0.29.0 → 0.33.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.en.md +2 -0
- package/README.md +2 -0
- package/dist/api/cli.js +4 -0
- package/dist/api/cli.js.map +1 -1
- package/dist/evolution/SessionLearnings.d.ts +70 -0
- package/dist/evolution/SessionLearnings.js +217 -0
- package/dist/evolution/SessionLearnings.js.map +1 -0
- package/dist/runtime/AiOsRuntime.d.ts +99 -1
- package/dist/runtime/AiOsRuntime.js +462 -14
- package/dist/runtime/AiOsRuntime.js.map +1 -1
- package/dist/skills/RoleSkills.d.ts +20 -0
- package/dist/skills/RoleSkills.js +154 -0
- package/dist/skills/RoleSkills.js.map +1 -0
- package/dist/skills/SkillDiscovery.d.ts +5 -0
- package/dist/skills/SkillDiscovery.js +15 -0
- package/dist/skills/SkillDiscovery.js.map +1 -1
- package/dist/skills/SkillFrontmatter.d.ts +28 -0
- package/dist/skills/SkillFrontmatter.js +152 -0
- package/dist/skills/SkillFrontmatter.js.map +1 -0
- package/dist/skills/SkillRegistry.d.ts +11 -0
- package/dist/skills/SkillRegistry.js +12 -0
- package/dist/skills/SkillRegistry.js.map +1 -1
- package/dist/skills/index.d.ts +1 -0
- package/dist/skills/index.js +1 -0
- package/dist/skills/index.js.map +1 -1
- package/dist/testing/DiffTestSelector.d.ts +22 -0
- package/dist/testing/DiffTestSelector.js +114 -0
- package/dist/testing/DiffTestSelector.js.map +1 -0
- package/dist/testing/index.d.ts +1 -0
- package/dist/testing/index.js +3 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/workflow/AdaptiveWorkflowRouter.d.ts +37 -0
- package/dist/workflow/AdaptiveWorkflowRouter.js +211 -0
- package/dist/workflow/AdaptiveWorkflowRouter.js.map +1 -0
- package/dist/workflow/EvolutionShadowPromoter.d.ts +46 -0
- package/dist/workflow/EvolutionShadowPromoter.js +73 -0
- package/dist/workflow/EvolutionShadowPromoter.js.map +1 -0
- package/dist/workflow/ReviewAnalyzer.d.ts +15 -0
- package/dist/workflow/ReviewAnalyzer.js +82 -0
- package/dist/workflow/ReviewAnalyzer.js.map +1 -1
- package/dist/workflow/SecurityAudit.d.ts +27 -0
- package/dist/workflow/SecurityAudit.js +294 -0
- package/dist/workflow/SecurityAudit.js.map +1 -0
- package/dist/workflow/SessionPreamble.d.ts +19 -0
- package/dist/workflow/SessionPreamble.js +125 -0
- package/dist/workflow/SessionPreamble.js.map +1 -0
- package/dist/workflow/ShipPipeline.d.ts +30 -0
- package/dist/workflow/ShipPipeline.js +366 -0
- package/dist/workflow/ShipPipeline.js.map +1 -0
- package/dist/workflow/WorkflowGuidance.d.ts +5 -1
- package/dist/workflow/WorkflowGuidance.js +31 -0
- package/dist/workflow/WorkflowGuidance.js.map +1 -1
- package/dist/workflow/index.d.ts +5 -0
- package/dist/workflow/index.js +5 -0
- package/dist/workflow/index.js.map +1 -1
- package/docs/AI_ENGINEERING_OS_POSITIONING.md +9 -0
- package/docs/CONTEXT_BUDGET.md +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
// SCALE Engine — Security Audit Engine (v0.33.0)
|
|
2
|
+
// OWASP Top 10 + STRIDE security audit for code review.
|
|
3
|
+
// Inspired by gstack's /cso security audit skill.
|
|
4
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
const SECURITY_PATTERNS = [
|
|
7
|
+
// Injection
|
|
8
|
+
{
|
|
9
|
+
id: 'sql-concat',
|
|
10
|
+
category: 'injection',
|
|
11
|
+
severity: 'critical',
|
|
12
|
+
title: 'SQL string concatenation detected',
|
|
13
|
+
pattern: /(?:query|execute|raw)\s*\(\s*[`'"].*\$\{|(?:query|execute|raw)\s*\(\s*['"].*\+\s*(?:req\.|params\.|input|user)/i,
|
|
14
|
+
description: 'SQL query built with string concatenation or template literals using user input.',
|
|
15
|
+
recommendation: 'Use parameterized queries or an ORM with built-in escaping.',
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
id: 'eval-usage',
|
|
19
|
+
category: 'injection',
|
|
20
|
+
severity: 'critical',
|
|
21
|
+
title: 'Dynamic code execution detected',
|
|
22
|
+
pattern: /\b(?:eval|Function|setTimeout|setInterval)\s*\(\s*(?:req\.|params\.|input|user|req\[)/i,
|
|
23
|
+
description: 'Dynamic code execution with user-controlled input.',
|
|
24
|
+
recommendation: 'Never pass user input to eval/Function. Use safe alternatives like JSON.parse or a sandboxed VM.',
|
|
25
|
+
},
|
|
26
|
+
// Auth
|
|
27
|
+
{
|
|
28
|
+
id: 'hardcoded-password',
|
|
29
|
+
category: 'auth',
|
|
30
|
+
severity: 'critical',
|
|
31
|
+
title: 'Hardcoded password or secret',
|
|
32
|
+
pattern: /(?:password|passwd|secret|api[_-]?key|token|auth[_-]?key)\s*[:=]\s*['"][^'"]{8,}['"]/i,
|
|
33
|
+
description: 'Hardcoded credential found in source code.',
|
|
34
|
+
recommendation: 'Move secrets to environment variables or a secret manager.',
|
|
35
|
+
testFileExempt: true,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
id: 'weak-crypto',
|
|
39
|
+
category: 'auth',
|
|
40
|
+
severity: 'high',
|
|
41
|
+
title: 'Weak cryptographic algorithm',
|
|
42
|
+
pattern: /\b(?:md5|sha1)\b.*(?:hash|digest|createHash)/i,
|
|
43
|
+
description: 'Weak hash algorithm (MD5/SHA1) used for security-sensitive operation.',
|
|
44
|
+
recommendation: 'Use SHA-256 or stronger. For passwords, use bcrypt, argon2, or scrypt.',
|
|
45
|
+
},
|
|
46
|
+
// XSS
|
|
47
|
+
{
|
|
48
|
+
id: 'innerhtml',
|
|
49
|
+
category: 'xss',
|
|
50
|
+
severity: 'high',
|
|
51
|
+
title: 'innerHTML assignment detected',
|
|
52
|
+
pattern: /\.innerHTML\s*=\s*(?!['"]\s*['"])/,
|
|
53
|
+
description: 'Direct innerHTML assignment may allow XSS if input is not sanitized.',
|
|
54
|
+
recommendation: 'Use textContent, or sanitize with DOMPurify before assigning to innerHTML.',
|
|
55
|
+
testFileExempt: true,
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
id: 'dangerously-set-html',
|
|
59
|
+
category: 'xss',
|
|
60
|
+
severity: 'high',
|
|
61
|
+
title: 'dangerouslySetInnerHTML usage',
|
|
62
|
+
pattern: /dangerouslySetInnerHTML\s*:/,
|
|
63
|
+
description: 'React dangerouslySetInnerHTML bypasses XSS protection.',
|
|
64
|
+
recommendation: 'Sanitize HTML with DOMPurify before passing to dangerouslySetInnerHTML.',
|
|
65
|
+
testFileExempt: true,
|
|
66
|
+
},
|
|
67
|
+
// Exposure
|
|
68
|
+
{
|
|
69
|
+
id: 'stack-trace-exposure',
|
|
70
|
+
category: 'exposure',
|
|
71
|
+
severity: 'medium',
|
|
72
|
+
title: 'Stack trace exposure in response',
|
|
73
|
+
pattern: /(?:res\.|response\.)\s*(?:send|json|write)\s*\(\s*(?:err|error)\s*(?:\.stack)?\s*\)/i,
|
|
74
|
+
description: 'Error stack trace sent to client, leaking internal implementation details.',
|
|
75
|
+
recommendation: 'Return generic error messages to clients. Log detailed errors server-side only.',
|
|
76
|
+
},
|
|
77
|
+
// Access Control
|
|
78
|
+
{
|
|
79
|
+
id: 'path-traversal',
|
|
80
|
+
category: 'access-control',
|
|
81
|
+
severity: 'critical',
|
|
82
|
+
title: 'Potential path traversal vulnerability',
|
|
83
|
+
pattern: /(?:readFile|readFileSync|createReadStream|access)\s*\(\s*(?:req\.|params\.|query\.|input|user)/i,
|
|
84
|
+
description: 'File system operation with user-controlled path.',
|
|
85
|
+
recommendation: 'Validate and normalize paths. Use path.resolve with a base directory check.',
|
|
86
|
+
},
|
|
87
|
+
// Logging
|
|
88
|
+
{
|
|
89
|
+
id: 'sensitive-logging',
|
|
90
|
+
category: 'logging',
|
|
91
|
+
severity: 'medium',
|
|
92
|
+
title: 'Sensitive data in log output',
|
|
93
|
+
pattern: /console\.\w+\s*\(.*(?:password|secret|token|key|credential)/i,
|
|
94
|
+
description: 'Sensitive data may be written to logs.',
|
|
95
|
+
recommendation: 'Redact sensitive fields before logging.',
|
|
96
|
+
},
|
|
97
|
+
// Deserialization
|
|
98
|
+
{
|
|
99
|
+
id: 'unsafe-deserialize',
|
|
100
|
+
category: 'deserialization',
|
|
101
|
+
severity: 'high',
|
|
102
|
+
title: 'Unsafe deserialization',
|
|
103
|
+
pattern: /JSON\.parse\s*\(\s*(?:req\.|params\.|body|input|user)/i,
|
|
104
|
+
description: 'JSON.parse with untrusted input without validation.',
|
|
105
|
+
recommendation: 'Validate JSON schema after parsing. Consider using a schema validator like zod or ajv.',
|
|
106
|
+
testFileExempt: true,
|
|
107
|
+
},
|
|
108
|
+
];
|
|
109
|
+
// ============================================================================
|
|
110
|
+
// Core Audit
|
|
111
|
+
// ============================================================================
|
|
112
|
+
export async function runSecurityAudit(opts) {
|
|
113
|
+
const projectDir = opts?.projectDir ?? process.cwd();
|
|
114
|
+
const files = opts?.files ?? [];
|
|
115
|
+
const findings = [];
|
|
116
|
+
let findingCounter = 0;
|
|
117
|
+
// Scan each file
|
|
118
|
+
for (const filePath of files) {
|
|
119
|
+
const fullPath = join(projectDir, filePath);
|
|
120
|
+
if (!existsSync(fullPath))
|
|
121
|
+
continue;
|
|
122
|
+
let content;
|
|
123
|
+
try {
|
|
124
|
+
content = readFileSync(fullPath, 'utf-8');
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
const lines = content.split('\n');
|
|
130
|
+
const isTestFile = isTestPath(filePath);
|
|
131
|
+
for (const patternDef of SECURITY_PATTERNS) {
|
|
132
|
+
if (patternDef.testFileExempt && isTestFile)
|
|
133
|
+
continue;
|
|
134
|
+
for (let i = 0; i < lines.length; i++) {
|
|
135
|
+
if (patternDef.pattern.test(lines[i])) {
|
|
136
|
+
findingCounter++;
|
|
137
|
+
findings.push({
|
|
138
|
+
id: `SEC-${String(findingCounter).padStart(3, '0')}`,
|
|
139
|
+
category: patternDef.category,
|
|
140
|
+
severity: patternDef.severity,
|
|
141
|
+
title: patternDef.title,
|
|
142
|
+
description: patternDef.description,
|
|
143
|
+
file: filePath,
|
|
144
|
+
line: i + 1,
|
|
145
|
+
evidence: lines[i].trim().slice(0, 200),
|
|
146
|
+
recommendation: patternDef.recommendation,
|
|
147
|
+
});
|
|
148
|
+
break; // One finding per pattern per file
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
// Build coverage maps
|
|
154
|
+
const owaspCoverage = buildOwaspCoverage(findings);
|
|
155
|
+
const strideCoverage = buildStrideCoverage(findings);
|
|
156
|
+
const riskScore = calculateRiskScore(findings);
|
|
157
|
+
const summary = buildSummary(findings, riskScore);
|
|
158
|
+
return { findings, owaspCoverage, strideCoverage, riskScore, summary };
|
|
159
|
+
}
|
|
160
|
+
// ============================================================================
|
|
161
|
+
// Coverage
|
|
162
|
+
// ============================================================================
|
|
163
|
+
function buildOwaspCoverage(findings) {
|
|
164
|
+
const categories = [
|
|
165
|
+
'injection', 'auth', 'exposure', 'xxe', 'access-control',
|
|
166
|
+
'misconfig', 'xss', 'deserialization', 'components', 'logging',
|
|
167
|
+
];
|
|
168
|
+
const foundCategories = new Set(findings.map(f => f.category));
|
|
169
|
+
const result = {};
|
|
170
|
+
for (const cat of categories) {
|
|
171
|
+
if (foundCategories.has(cat)) {
|
|
172
|
+
result[cat] = 'checked';
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
result[cat] = 'not-applicable';
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return result;
|
|
179
|
+
}
|
|
180
|
+
function buildStrideCoverage(findings) {
|
|
181
|
+
const categories = [
|
|
182
|
+
'spoofing', 'tampering', 'repudiation', 'info-disclosure', 'denial-of-service', 'elevation-of-privilege',
|
|
183
|
+
];
|
|
184
|
+
// Map OWASP categories to STRIDE
|
|
185
|
+
const owaspToStride = {
|
|
186
|
+
'auth': 'spoofing',
|
|
187
|
+
'injection': 'tampering',
|
|
188
|
+
'xss': 'tampering',
|
|
189
|
+
'deserialization': 'tampering',
|
|
190
|
+
'logging': 'repudiation',
|
|
191
|
+
'exposure': 'info-disclosure',
|
|
192
|
+
'xxe': 'info-disclosure',
|
|
193
|
+
'access-control': 'elevation-of-privilege',
|
|
194
|
+
'components': 'elevation-of-privilege',
|
|
195
|
+
'misconfig': 'denial-of-service',
|
|
196
|
+
};
|
|
197
|
+
const foundStride = new Set();
|
|
198
|
+
for (const f of findings) {
|
|
199
|
+
const stride = owaspToStride[f.category];
|
|
200
|
+
if (stride)
|
|
201
|
+
foundStride.add(stride);
|
|
202
|
+
}
|
|
203
|
+
const result = {};
|
|
204
|
+
for (const cat of categories) {
|
|
205
|
+
result[cat] = foundStride.has(cat) ? 'checked' : 'not-applicable';
|
|
206
|
+
}
|
|
207
|
+
return result;
|
|
208
|
+
}
|
|
209
|
+
// ============================================================================
|
|
210
|
+
// Risk Score
|
|
211
|
+
// ============================================================================
|
|
212
|
+
function calculateRiskScore(findings) {
|
|
213
|
+
if (findings.length === 0)
|
|
214
|
+
return 0;
|
|
215
|
+
const weights = {
|
|
216
|
+
critical: 25,
|
|
217
|
+
high: 15,
|
|
218
|
+
medium: 8,
|
|
219
|
+
low: 3,
|
|
220
|
+
};
|
|
221
|
+
let score = 0;
|
|
222
|
+
for (const f of findings) {
|
|
223
|
+
score += weights[f.severity];
|
|
224
|
+
}
|
|
225
|
+
return Math.min(100, score);
|
|
226
|
+
}
|
|
227
|
+
// ============================================================================
|
|
228
|
+
// Summary
|
|
229
|
+
// ============================================================================
|
|
230
|
+
function buildSummary(findings, riskScore) {
|
|
231
|
+
if (findings.length === 0) {
|
|
232
|
+
return 'No security findings detected.';
|
|
233
|
+
}
|
|
234
|
+
const critical = findings.filter(f => f.severity === 'critical').length;
|
|
235
|
+
const high = findings.filter(f => f.severity === 'high').length;
|
|
236
|
+
const medium = findings.filter(f => f.severity === 'medium').length;
|
|
237
|
+
const low = findings.filter(f => f.severity === 'low').length;
|
|
238
|
+
const lines = [
|
|
239
|
+
`Security audit found ${findings.length} finding(s):`,
|
|
240
|
+
` Critical: ${critical}, High: ${high}, Medium: ${medium}, Low: ${low}`,
|
|
241
|
+
` Risk Score: ${riskScore}/100`,
|
|
242
|
+
];
|
|
243
|
+
if (critical > 0) {
|
|
244
|
+
lines.push(' ⚠️ CRITICAL findings require immediate remediation before merge.');
|
|
245
|
+
}
|
|
246
|
+
return lines.join('\n');
|
|
247
|
+
}
|
|
248
|
+
// ============================================================================
|
|
249
|
+
// Formatter
|
|
250
|
+
// ============================================================================
|
|
251
|
+
export function summarizeSecurityAudit(result) {
|
|
252
|
+
const lines = ['## Security Audit Result\n'];
|
|
253
|
+
if (result.findings.length === 0) {
|
|
254
|
+
lines.push('No security findings detected.');
|
|
255
|
+
return lines.join('\n');
|
|
256
|
+
}
|
|
257
|
+
lines.push(`**Risk Score:** ${result.riskScore}/100\n`);
|
|
258
|
+
const bySeverity = {
|
|
259
|
+
critical: result.findings.filter(f => f.severity === 'critical'),
|
|
260
|
+
high: result.findings.filter(f => f.severity === 'high'),
|
|
261
|
+
medium: result.findings.filter(f => f.severity === 'medium'),
|
|
262
|
+
low: result.findings.filter(f => f.severity === 'low'),
|
|
263
|
+
};
|
|
264
|
+
for (const [severity, items] of Object.entries(bySeverity)) {
|
|
265
|
+
if (items.length === 0)
|
|
266
|
+
continue;
|
|
267
|
+
const icon = severity === 'critical' ? '🔴' : severity === 'high' ? '🟠' : severity === 'medium' ? '🟡' : '🔵';
|
|
268
|
+
lines.push(`### ${icon} ${severity.toUpperCase()} (${items.length})\n`);
|
|
269
|
+
for (const f of items) {
|
|
270
|
+
lines.push(`**${f.id}: ${f.title}**`);
|
|
271
|
+
if (f.file)
|
|
272
|
+
lines.push(` File: \`${f.file}${f.line ? `:${f.line}` : ''}\``);
|
|
273
|
+
lines.push(` ${f.description}`);
|
|
274
|
+
lines.push(` Recommendation: ${f.recommendation}`);
|
|
275
|
+
lines.push('');
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
// OWASP coverage
|
|
279
|
+
lines.push('### OWASP Top 10 Coverage\n');
|
|
280
|
+
for (const [cat, status] of Object.entries(result.owaspCoverage)) {
|
|
281
|
+
const icon = status === 'checked' ? '✅' : '⬜';
|
|
282
|
+
lines.push(`${icon} ${cat}`);
|
|
283
|
+
}
|
|
284
|
+
return lines.join('\n');
|
|
285
|
+
}
|
|
286
|
+
// ============================================================================
|
|
287
|
+
// Helpers
|
|
288
|
+
// ============================================================================
|
|
289
|
+
function isTestPath(path) {
|
|
290
|
+
const normalized = path.replace(/\\/g, '/');
|
|
291
|
+
return /(^|\/)(tests?|__tests__)\//i.test(normalized) ||
|
|
292
|
+
/\.(test|spec)\.(ts|tsx|js|jsx|mjs|cjs)$/i.test(normalized);
|
|
293
|
+
}
|
|
294
|
+
//# sourceMappingURL=SecurityAudit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SecurityAudit.js","sourceRoot":"","sources":["../../src/workflow/SecurityAudit.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface SessionPreamble {
|
|
2
|
+
sessionId: string;
|
|
3
|
+
timestamp: string;
|
|
4
|
+
gitBranch: string;
|
|
5
|
+
gitRoot: string;
|
|
6
|
+
projectSlug: string;
|
|
7
|
+
scaleVersion: string;
|
|
8
|
+
activeRunCount: number;
|
|
9
|
+
learningCount: number;
|
|
10
|
+
verificationProfile: string;
|
|
11
|
+
governanceMode: string;
|
|
12
|
+
warnings: string[];
|
|
13
|
+
}
|
|
14
|
+
export interface PreambleOptions {
|
|
15
|
+
projectDir?: string;
|
|
16
|
+
scaleDir?: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function collectSessionPreamble(opts?: PreambleOptions): SessionPreamble;
|
|
19
|
+
export declare function formatPreambleForAgent(preamble: SessionPreamble): string;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
// SCALE Engine — Session Preamble (v0.31.0)
|
|
2
|
+
// Automatic environment context collection before workflow execution.
|
|
3
|
+
// Inspired by gstack's preamble pattern: collect branch, sessions, learnings, etc.
|
|
4
|
+
import { existsSync, readdirSync, readFileSync } from 'node:fs';
|
|
5
|
+
import { join, basename } from 'node:path';
|
|
6
|
+
import { randomUUID } from 'node:crypto';
|
|
7
|
+
import { execSync } from 'node:child_process';
|
|
8
|
+
import { SCALE_ENGINE_VERSION } from '../version.js';
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Collector
|
|
11
|
+
// ============================================================================
|
|
12
|
+
export function collectSessionPreamble(opts) {
|
|
13
|
+
const projectDir = opts?.projectDir ?? process.cwd();
|
|
14
|
+
const scaleDir = opts?.scaleDir ?? '.scale';
|
|
15
|
+
const warnings = [];
|
|
16
|
+
// Git branch
|
|
17
|
+
let gitBranch = 'unknown';
|
|
18
|
+
try {
|
|
19
|
+
gitBranch = execSync('git branch --show-current', { cwd: projectDir, encoding: 'utf-8', timeout: 5000 }).trim();
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
warnings.push('Not in a git repository or git not available');
|
|
23
|
+
}
|
|
24
|
+
// Git root
|
|
25
|
+
let gitRoot = projectDir;
|
|
26
|
+
try {
|
|
27
|
+
gitRoot = execSync('git rev-parse --show-toplevel', { cwd: projectDir, encoding: 'utf-8', timeout: 5000 }).trim();
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
// Use projectDir as fallback
|
|
31
|
+
}
|
|
32
|
+
// Project slug
|
|
33
|
+
const projectSlug = deriveProjectSlug(projectDir);
|
|
34
|
+
// Active run count
|
|
35
|
+
const activeRunCount = countActiveRuns(scaleDir);
|
|
36
|
+
// Learning count
|
|
37
|
+
const learningCount = countLearnings(scaleDir, projectSlug);
|
|
38
|
+
// Verification profile
|
|
39
|
+
const verificationProfile = resolveCurrentProfile(scaleDir, projectDir);
|
|
40
|
+
// Governance mode (default)
|
|
41
|
+
const governanceMode = 'standard';
|
|
42
|
+
return {
|
|
43
|
+
sessionId: randomUUID().slice(0, 8),
|
|
44
|
+
timestamp: new Date().toISOString(),
|
|
45
|
+
gitBranch,
|
|
46
|
+
gitRoot,
|
|
47
|
+
projectSlug,
|
|
48
|
+
scaleVersion: SCALE_ENGINE_VERSION,
|
|
49
|
+
activeRunCount,
|
|
50
|
+
learningCount,
|
|
51
|
+
verificationProfile,
|
|
52
|
+
governanceMode,
|
|
53
|
+
warnings,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
// ============================================================================
|
|
57
|
+
// Formatter
|
|
58
|
+
// ============================================================================
|
|
59
|
+
export function formatPreambleForAgent(preamble) {
|
|
60
|
+
const lines = [
|
|
61
|
+
`SESSION: ${preamble.sessionId}`,
|
|
62
|
+
`BRANCH: ${preamble.gitBranch}`,
|
|
63
|
+
`PROJECT: ${preamble.projectSlug}`,
|
|
64
|
+
`SCALE_VERSION: ${preamble.scaleVersion}`,
|
|
65
|
+
`ACTIVE_RUNS: ${preamble.activeRunCount}`,
|
|
66
|
+
`LEARNINGS: ${preamble.learningCount}`,
|
|
67
|
+
`VERIFICATION_PROFILE: ${preamble.verificationProfile}`,
|
|
68
|
+
`GOVERNANCE_MODE: ${preamble.governanceMode}`,
|
|
69
|
+
];
|
|
70
|
+
if (preamble.warnings.length > 0) {
|
|
71
|
+
lines.push(`WARNINGS: ${preamble.warnings.join('; ')}`);
|
|
72
|
+
}
|
|
73
|
+
return lines.join('\n');
|
|
74
|
+
}
|
|
75
|
+
// ============================================================================
|
|
76
|
+
// Helpers
|
|
77
|
+
// ============================================================================
|
|
78
|
+
function deriveProjectSlug(projectDir) {
|
|
79
|
+
try {
|
|
80
|
+
return basename(projectDir).replace(/[^a-zA-Z0-9-]/g, '-').toLowerCase();
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
return 'unknown';
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
function countActiveRuns(scaleDir) {
|
|
87
|
+
const runsDir = join(scaleDir, 'ai-os', 'runs');
|
|
88
|
+
if (!existsSync(runsDir))
|
|
89
|
+
return 0;
|
|
90
|
+
try {
|
|
91
|
+
return readdirSync(runsDir).filter(f => f.endsWith('.json')).length;
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
return 0;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
function countLearnings(scaleDir, projectSlug) {
|
|
98
|
+
const learningsDir = join(scaleDir, 'learnings');
|
|
99
|
+
if (!existsSync(learningsDir))
|
|
100
|
+
return 0;
|
|
101
|
+
try {
|
|
102
|
+
const jsonlPath = join(learningsDir, `${projectSlug}.jsonl`);
|
|
103
|
+
if (!existsSync(jsonlPath))
|
|
104
|
+
return 0;
|
|
105
|
+
const content = readFileSync(jsonlPath, 'utf-8');
|
|
106
|
+
return content.split('\n').filter(line => line.trim()).length;
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
return 0;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function resolveCurrentProfile(scaleDir, projectDir) {
|
|
113
|
+
try {
|
|
114
|
+
const matrixPath = join(projectDir, scaleDir, 'verification-matrix.json');
|
|
115
|
+
if (existsSync(matrixPath)) {
|
|
116
|
+
const matrix = JSON.parse(readFileSync(matrixPath, 'utf-8'));
|
|
117
|
+
return matrix.defaultProfile ?? 'default';
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
// Ignore
|
|
122
|
+
}
|
|
123
|
+
return 'default';
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=SessionPreamble.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SessionPreamble.js","sourceRoot":"","sources":["../../src/workflow/SessionPreamble.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export type ShipStep = 'sync-base' | 'test' | 'review-diff' | 'bump-version' | 'changelog' | 'commit' | 'push' | 'create-pr';
|
|
2
|
+
export interface ShipPipelineInput {
|
|
3
|
+
projectDir?: string;
|
|
4
|
+
scaleDir?: string;
|
|
5
|
+
baseBranch?: string;
|
|
6
|
+
remote?: string;
|
|
7
|
+
prTitle?: string;
|
|
8
|
+
prBody?: string;
|
|
9
|
+
skipSteps?: ShipStep[];
|
|
10
|
+
dryRun?: boolean;
|
|
11
|
+
versionBump?: 'patch' | 'minor' | 'major';
|
|
12
|
+
}
|
|
13
|
+
export interface ShipStepResult {
|
|
14
|
+
step: ShipStep;
|
|
15
|
+
status: 'passed' | 'skipped' | 'failed' | 'blocked';
|
|
16
|
+
duration: number;
|
|
17
|
+
evidence?: string;
|
|
18
|
+
error?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface ShipPipelineResult {
|
|
21
|
+
success: boolean;
|
|
22
|
+
steps: ShipStepResult[];
|
|
23
|
+
prUrl?: string;
|
|
24
|
+
commitSha?: string;
|
|
25
|
+
totalDuration: number;
|
|
26
|
+
changedFiles: string[];
|
|
27
|
+
warnings: string[];
|
|
28
|
+
}
|
|
29
|
+
export declare function runShipPipeline(input: ShipPipelineInput): Promise<ShipPipelineResult>;
|
|
30
|
+
export declare function summarizeShipPipeline(result: ShipPipelineResult): string;
|