@brad-frost-web/eddie-brain 0.32.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 +109 -0
- package/dist/analyze/drift-detector.d.ts +30 -0
- package/dist/analyze/drift-detector.d.ts.map +1 -0
- package/dist/analyze/drift-detector.js +310 -0
- package/dist/analyze/drift-detector.js.map +1 -0
- package/dist/analyze/health-scorer.d.ts +71 -0
- package/dist/analyze/health-scorer.d.ts.map +1 -0
- package/dist/analyze/health-scorer.js +420 -0
- package/dist/analyze/health-scorer.js.map +1 -0
- package/dist/analyze/index.d.ts +11 -0
- package/dist/analyze/index.d.ts.map +1 -0
- package/dist/analyze/index.js +11 -0
- package/dist/analyze/index.js.map +1 -0
- package/dist/analyze/naming-validator.d.ts +99 -0
- package/dist/analyze/naming-validator.d.ts.map +1 -0
- package/dist/analyze/naming-validator.js +430 -0
- package/dist/analyze/naming-validator.js.map +1 -0
- package/dist/analyze/slot-contract-validator.d.ts +68 -0
- package/dist/analyze/slot-contract-validator.d.ts.map +1 -0
- package/dist/analyze/slot-contract-validator.js +232 -0
- package/dist/analyze/slot-contract-validator.js.map +1 -0
- package/dist/analyze/token-validator.d.ts +62 -0
- package/dist/analyze/token-validator.d.ts.map +1 -0
- package/dist/analyze/token-validator.js +348 -0
- package/dist/analyze/token-validator.js.map +1 -0
- package/dist/cli/brain.d.ts +12 -0
- package/dist/cli/brain.d.ts.map +1 -0
- package/dist/cli/brain.js +641 -0
- package/dist/cli/brain.js.map +1 -0
- package/dist/cli/formatters/json.d.ts +15 -0
- package/dist/cli/formatters/json.d.ts.map +1 -0
- package/dist/cli/formatters/json.js +18 -0
- package/dist/cli/formatters/json.js.map +1 -0
- package/dist/cli/formatters/terminal.d.ts +19 -0
- package/dist/cli/formatters/terminal.d.ts.map +1 -0
- package/dist/cli/formatters/terminal.js +125 -0
- package/dist/cli/formatters/terminal.js.map +1 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +7 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/data/governance-rules.json +94 -0
- package/dist/governance/audit-log.d.ts +17 -0
- package/dist/governance/audit-log.d.ts.map +1 -0
- package/dist/governance/audit-log.js +44 -0
- package/dist/governance/audit-log.js.map +1 -0
- package/dist/governance/index.d.ts +8 -0
- package/dist/governance/index.d.ts.map +1 -0
- package/dist/governance/index.js +8 -0
- package/dist/governance/index.js.map +1 -0
- package/dist/governance/permissions.d.ts +26 -0
- package/dist/governance/permissions.d.ts.map +1 -0
- package/dist/governance/permissions.js +75 -0
- package/dist/governance/permissions.js.map +1 -0
- package/dist/governance/rules-engine.d.ts +24 -0
- package/dist/governance/rules-engine.d.ts.map +1 -0
- package/dist/governance/rules-engine.js +111 -0
- package/dist/governance/rules-engine.js.map +1 -0
- package/dist/governance/trust-manager.d.ts +34 -0
- package/dist/governance/trust-manager.d.ts.map +1 -0
- package/dist/governance/trust-manager.js +148 -0
- package/dist/governance/trust-manager.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/knowledge-graph/component-index.d.ts +320 -0
- package/dist/knowledge-graph/component-index.d.ts.map +1 -0
- package/dist/knowledge-graph/component-index.js +1033 -0
- package/dist/knowledge-graph/component-index.js.map +1 -0
- package/dist/knowledge-graph/index.d.ts +134 -0
- package/dist/knowledge-graph/index.d.ts.map +1 -0
- package/dist/knowledge-graph/index.js +249 -0
- package/dist/knowledge-graph/index.js.map +1 -0
- package/dist/knowledge-graph/learning-history.d.ts +77 -0
- package/dist/knowledge-graph/learning-history.d.ts.map +1 -0
- package/dist/knowledge-graph/learning-history.js +187 -0
- package/dist/knowledge-graph/learning-history.js.map +1 -0
- package/dist/knowledge-graph/relationship-map.d.ts +55 -0
- package/dist/knowledge-graph/relationship-map.d.ts.map +1 -0
- package/dist/knowledge-graph/relationship-map.js +238 -0
- package/dist/knowledge-graph/relationship-map.js.map +1 -0
- package/dist/knowledge-graph/token-taxonomy.d.ts +127 -0
- package/dist/knowledge-graph/token-taxonomy.d.ts.map +1 -0
- package/dist/knowledge-graph/token-taxonomy.js +357 -0
- package/dist/knowledge-graph/token-taxonomy.js.map +1 -0
- package/dist/loop/fix-agent.d.ts +55 -0
- package/dist/loop/fix-agent.d.ts.map +1 -0
- package/dist/loop/fix-agent.js +344 -0
- package/dist/loop/fix-agent.js.map +1 -0
- package/dist/loop/index.d.ts +8 -0
- package/dist/loop/index.d.ts.map +1 -0
- package/dist/loop/index.js +8 -0
- package/dist/loop/index.js.map +1 -0
- package/dist/loop/issue-fetcher.d.ts +51 -0
- package/dist/loop/issue-fetcher.d.ts.map +1 -0
- package/dist/loop/issue-fetcher.js +188 -0
- package/dist/loop/issue-fetcher.js.map +1 -0
- package/dist/loop/observer.d.ts +42 -0
- package/dist/loop/observer.d.ts.map +1 -0
- package/dist/loop/observer.js +220 -0
- package/dist/loop/observer.js.map +1 -0
- package/dist/loop/pacer.d.ts +44 -0
- package/dist/loop/pacer.d.ts.map +1 -0
- package/dist/loop/pacer.js +90 -0
- package/dist/loop/pacer.js.map +1 -0
- package/dist/loop/reporter.d.ts +9 -0
- package/dist/loop/reporter.d.ts.map +1 -0
- package/dist/loop/reporter.js +119 -0
- package/dist/loop/reporter.js.map +1 -0
- package/dist/loop/runner.d.ts +57 -0
- package/dist/loop/runner.d.ts.map +1 -0
- package/dist/loop/runner.js +390 -0
- package/dist/loop/runner.js.map +1 -0
- package/dist/loop/types.d.ts +151 -0
- package/dist/loop/types.d.ts.map +1 -0
- package/dist/loop/types.js +22 -0
- package/dist/loop/types.js.map +1 -0
- package/dist/mcp/index.d.ts +7 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +7 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/server.d.ts +12 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +618 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/pipeline/agent-runner.d.ts +34 -0
- package/dist/pipeline/agent-runner.d.ts.map +1 -0
- package/dist/pipeline/agent-runner.js +323 -0
- package/dist/pipeline/agent-runner.js.map +1 -0
- package/dist/pipeline/agents/accessibility-auditor.d.ts +10 -0
- package/dist/pipeline/agents/accessibility-auditor.d.ts.map +1 -0
- package/dist/pipeline/agents/accessibility-auditor.js +69 -0
- package/dist/pipeline/agents/accessibility-auditor.js.map +1 -0
- package/dist/pipeline/agents/code-reviewer.d.ts +10 -0
- package/dist/pipeline/agents/code-reviewer.d.ts.map +1 -0
- package/dist/pipeline/agents/code-reviewer.js +75 -0
- package/dist/pipeline/agents/code-reviewer.js.map +1 -0
- package/dist/pipeline/agents/code-writer.d.ts +10 -0
- package/dist/pipeline/agents/code-writer.d.ts.map +1 -0
- package/dist/pipeline/agents/code-writer.js +103 -0
- package/dist/pipeline/agents/code-writer.js.map +1 -0
- package/dist/pipeline/agents/component-architect.d.ts +13 -0
- package/dist/pipeline/agents/component-architect.d.ts.map +1 -0
- package/dist/pipeline/agents/component-architect.js +81 -0
- package/dist/pipeline/agents/component-architect.js.map +1 -0
- package/dist/pipeline/agents/index.d.ts +16 -0
- package/dist/pipeline/agents/index.d.ts.map +1 -0
- package/dist/pipeline/agents/index.js +24 -0
- package/dist/pipeline/agents/index.js.map +1 -0
- package/dist/pipeline/agents/library-researcher.d.ts +12 -0
- package/dist/pipeline/agents/library-researcher.d.ts.map +1 -0
- package/dist/pipeline/agents/library-researcher.js +85 -0
- package/dist/pipeline/agents/library-researcher.js.map +1 -0
- package/dist/pipeline/agents/quality-gate.d.ts +9 -0
- package/dist/pipeline/agents/quality-gate.d.ts.map +1 -0
- package/dist/pipeline/agents/quality-gate.js +71 -0
- package/dist/pipeline/agents/quality-gate.js.map +1 -0
- package/dist/pipeline/agents/spec-analyst.d.ts +10 -0
- package/dist/pipeline/agents/spec-analyst.d.ts.map +1 -0
- package/dist/pipeline/agents/spec-analyst.js +72 -0
- package/dist/pipeline/agents/spec-analyst.js.map +1 -0
- package/dist/pipeline/agents/story-author.d.ts +9 -0
- package/dist/pipeline/agents/story-author.d.ts.map +1 -0
- package/dist/pipeline/agents/story-author.js +65 -0
- package/dist/pipeline/agents/story-author.js.map +1 -0
- package/dist/pipeline/artifact-store.d.ts +27 -0
- package/dist/pipeline/artifact-store.d.ts.map +1 -0
- package/dist/pipeline/artifact-store.js +77 -0
- package/dist/pipeline/artifact-store.js.map +1 -0
- package/dist/pipeline/conversational-gate.d.ts +26 -0
- package/dist/pipeline/conversational-gate.d.ts.map +1 -0
- package/dist/pipeline/conversational-gate.js +122 -0
- package/dist/pipeline/conversational-gate.js.map +1 -0
- package/dist/pipeline/index.d.ts +14 -0
- package/dist/pipeline/index.d.ts.map +1 -0
- package/dist/pipeline/index.js +17 -0
- package/dist/pipeline/index.js.map +1 -0
- package/dist/pipeline/iteration-tracker.d.ts +29 -0
- package/dist/pipeline/iteration-tracker.d.ts.map +1 -0
- package/dist/pipeline/iteration-tracker.js +102 -0
- package/dist/pipeline/iteration-tracker.js.map +1 -0
- package/dist/pipeline/learning-bridge.d.ts +37 -0
- package/dist/pipeline/learning-bridge.d.ts.map +1 -0
- package/dist/pipeline/learning-bridge.js +118 -0
- package/dist/pipeline/learning-bridge.js.map +1 -0
- package/dist/pipeline/orchestrator.d.ts +45 -0
- package/dist/pipeline/orchestrator.d.ts.map +1 -0
- package/dist/pipeline/orchestrator.js +473 -0
- package/dist/pipeline/orchestrator.js.map +1 -0
- package/dist/pipeline/templates/architecture.d.ts +27 -0
- package/dist/pipeline/templates/architecture.d.ts.map +1 -0
- package/dist/pipeline/templates/architecture.js +111 -0
- package/dist/pipeline/templates/architecture.js.map +1 -0
- package/dist/pipeline/templates/brief.d.ts +22 -0
- package/dist/pipeline/templates/brief.d.ts.map +1 -0
- package/dist/pipeline/templates/brief.js +121 -0
- package/dist/pipeline/templates/brief.js.map +1 -0
- package/dist/pipeline/templates/component-rules.d.ts +25 -0
- package/dist/pipeline/templates/component-rules.d.ts.map +1 -0
- package/dist/pipeline/templates/component-rules.js +93 -0
- package/dist/pipeline/templates/component-rules.js.map +1 -0
- package/dist/pipeline/templates/index.d.ts +9 -0
- package/dist/pipeline/templates/index.d.ts.map +1 -0
- package/dist/pipeline/templates/index.js +7 -0
- package/dist/pipeline/templates/index.js.map +1 -0
- package/dist/pipeline/tool-handler.d.ts +25 -0
- package/dist/pipeline/tool-handler.d.ts.map +1 -0
- package/dist/pipeline/tool-handler.js +392 -0
- package/dist/pipeline/tool-handler.js.map +1 -0
- package/dist/pipeline/types.d.ts +146 -0
- package/dist/pipeline/types.d.ts.map +1 -0
- package/dist/pipeline/types.js +27 -0
- package/dist/pipeline/types.js.map +1 -0
- package/dist/plan/action-types.d.ts +31 -0
- package/dist/plan/action-types.d.ts.map +1 -0
- package/dist/plan/action-types.js +83 -0
- package/dist/plan/action-types.js.map +1 -0
- package/dist/plan/decision-engine.d.ts +57 -0
- package/dist/plan/decision-engine.d.ts.map +1 -0
- package/dist/plan/decision-engine.js +162 -0
- package/dist/plan/decision-engine.js.map +1 -0
- package/dist/plan/index.d.ts +6 -0
- package/dist/plan/index.d.ts.map +1 -0
- package/dist/plan/index.js +6 -0
- package/dist/plan/index.js.map +1 -0
- package/dist/types.d.ts +351 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +26 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/anthropic.d.ts +15 -0
- package/dist/utils/anthropic.d.ts.map +1 -0
- package/dist/utils/anthropic.js +40 -0
- package/dist/utils/anthropic.js.map +1 -0
- package/dist/utils/id.d.ts +8 -0
- package/dist/utils/id.d.ts.map +1 -0
- package/dist/utils/id.js +14 -0
- package/dist/utils/id.js.map +1 -0
- package/package.json +80 -0
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Observer — Spots areas for improvement in files touched during a lap.
|
|
3
|
+
*
|
|
4
|
+
* After each lap, reviews the files that were fixed and identifies
|
|
5
|
+
* patterns, inconsistencies, missing features, or architectural
|
|
6
|
+
* improvements. Files observations as GitHub issues.
|
|
7
|
+
*/
|
|
8
|
+
import type { Observation, FixAttempt } from './types.js';
|
|
9
|
+
import type { Pacer } from './pacer.js';
|
|
10
|
+
export declare class Observer {
|
|
11
|
+
private apiKey;
|
|
12
|
+
private model;
|
|
13
|
+
private rootDir;
|
|
14
|
+
private pacer;
|
|
15
|
+
private client;
|
|
16
|
+
constructor(apiKey: string, model: string, rootDir: string, pacer: Pacer);
|
|
17
|
+
/**
|
|
18
|
+
* Review files from a completed lap and identify improvement opportunities.
|
|
19
|
+
*/
|
|
20
|
+
observe(fixes: FixAttempt[]): Promise<Observation[]>;
|
|
21
|
+
/**
|
|
22
|
+
* File observations as GitHub issues, with deduplication.
|
|
23
|
+
*
|
|
24
|
+
* Before creating any issue, fetches all open issue titles in one batch
|
|
25
|
+
* and checks for:
|
|
26
|
+
* 1. Exact title match (case-insensitive)
|
|
27
|
+
* 2. Filename-based similarity — if the observation references a file
|
|
28
|
+
* and an existing open issue mentions the same filename in its title
|
|
29
|
+
*
|
|
30
|
+
* Skipped observations are logged but not filed, preventing the historic
|
|
31
|
+
* duplicate-issue bug (#217) where each pipeline run filed new issues for
|
|
32
|
+
* the same file+violation across multiple runs. With ~200 duplicate issues
|
|
33
|
+
* accumulated before this fix, the dedup is critical for keeping the
|
|
34
|
+
* issue board usable.
|
|
35
|
+
*/
|
|
36
|
+
fileIssues(observations: Observation[]): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Parse the observer's response into structured observations.
|
|
39
|
+
*/
|
|
40
|
+
private parseObservations;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=observer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observer.d.ts","sourceRoot":"","sources":["../../src/loop/observer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAExC,qBAAa,QAAQ;IAIjB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,KAAK;IANf,OAAO,CAAC,MAAM,CAAY;gBAGhB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,KAAK;IAKtB;;OAEG;IACG,OAAO,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IA0C1D;;;;;;;;;;;;;;OAcG;IACG,UAAU,CAAC,YAAY,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IA4E5D;;OAEG;IACH,OAAO,CAAC,iBAAiB;CAiD1B"}
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Observer — Spots areas for improvement in files touched during a lap.
|
|
3
|
+
*
|
|
4
|
+
* After each lap, reviews the files that were fixed and identifies
|
|
5
|
+
* patterns, inconsistencies, missing features, or architectural
|
|
6
|
+
* improvements. Files observations as GitHub issues.
|
|
7
|
+
*/
|
|
8
|
+
import Anthropic from '@anthropic-ai/sdk';
|
|
9
|
+
import { execSync } from 'child_process';
|
|
10
|
+
import { readFileSync } from 'fs';
|
|
11
|
+
import { resolve } from 'path';
|
|
12
|
+
import chalk from 'chalk';
|
|
13
|
+
import { createWithRetry } from '../utils/anthropic.js';
|
|
14
|
+
export class Observer {
|
|
15
|
+
apiKey;
|
|
16
|
+
model;
|
|
17
|
+
rootDir;
|
|
18
|
+
pacer;
|
|
19
|
+
client;
|
|
20
|
+
constructor(apiKey, model, rootDir, pacer) {
|
|
21
|
+
this.apiKey = apiKey;
|
|
22
|
+
this.model = model;
|
|
23
|
+
this.rootDir = rootDir;
|
|
24
|
+
this.pacer = pacer;
|
|
25
|
+
this.client = new Anthropic({ apiKey });
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Review files from a completed lap and identify improvement opportunities.
|
|
29
|
+
*/
|
|
30
|
+
async observe(fixes) {
|
|
31
|
+
const successfulFixes = fixes.filter(f => f.success);
|
|
32
|
+
if (successfulFixes.length === 0)
|
|
33
|
+
return [];
|
|
34
|
+
// Read the fixed files to give the observer context
|
|
35
|
+
const fileContents = [];
|
|
36
|
+
for (const fix of successfulFixes) {
|
|
37
|
+
try {
|
|
38
|
+
const content = readFileSync(resolve(this.rootDir, fix.filePath), 'utf-8');
|
|
39
|
+
fileContents.push(`## ${fix.filePath}\n\`\`\`\n${content}\n\`\`\``);
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
// Skip unreadable files
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (fileContents.length === 0)
|
|
46
|
+
return [];
|
|
47
|
+
console.log(chalk.cyan(` Observing ${fileContents.length} file(s) for improvement opportunities...`));
|
|
48
|
+
try {
|
|
49
|
+
this.pacer.recordApiCall();
|
|
50
|
+
const response = await createWithRetry(this.client, {
|
|
51
|
+
model: this.model,
|
|
52
|
+
max_tokens: 4096,
|
|
53
|
+
system: OBSERVER_SYSTEM_PROMPT,
|
|
54
|
+
messages: [{
|
|
55
|
+
role: 'user',
|
|
56
|
+
content: `Review these Eddie Design System files that were just fixed for violations. Identify any improvement opportunities beyond what was already fixed.\n\n${fileContents.join('\n\n')}`,
|
|
57
|
+
}],
|
|
58
|
+
}, 'observer');
|
|
59
|
+
this.pacer.recordSuccess();
|
|
60
|
+
return this.parseObservations(response);
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
if (err instanceof Error && err.message.includes('rate_limit')) {
|
|
64
|
+
this.pacer.record429();
|
|
65
|
+
}
|
|
66
|
+
console.log(chalk.yellow(` Observer failed: ${err instanceof Error ? err.message : String(err)}`));
|
|
67
|
+
return [];
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* File observations as GitHub issues, with deduplication.
|
|
72
|
+
*
|
|
73
|
+
* Before creating any issue, fetches all open issue titles in one batch
|
|
74
|
+
* and checks for:
|
|
75
|
+
* 1. Exact title match (case-insensitive)
|
|
76
|
+
* 2. Filename-based similarity — if the observation references a file
|
|
77
|
+
* and an existing open issue mentions the same filename in its title
|
|
78
|
+
*
|
|
79
|
+
* Skipped observations are logged but not filed, preventing the historic
|
|
80
|
+
* duplicate-issue bug (#217) where each pipeline run filed new issues for
|
|
81
|
+
* the same file+violation across multiple runs. With ~200 duplicate issues
|
|
82
|
+
* accumulated before this fix, the dedup is critical for keeping the
|
|
83
|
+
* issue board usable.
|
|
84
|
+
*/
|
|
85
|
+
async fileIssues(observations) {
|
|
86
|
+
// Fetch all open issue titles in one batch for dedup
|
|
87
|
+
let existingTitles;
|
|
88
|
+
try {
|
|
89
|
+
const existing = execSync('gh issue list --state open --limit 500 --json title', { cwd: this.rootDir, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] });
|
|
90
|
+
const parsed = JSON.parse(existing);
|
|
91
|
+
existingTitles = new Set(parsed.map((i) => i.title.toLowerCase()));
|
|
92
|
+
console.log(chalk.dim(` Dedup: loaded ${existingTitles.size} open issue titles`));
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
// If we can't fetch existing issues (no gh CLI, no auth, offline),
|
|
96
|
+
// fall through and file everything — better to have a duplicate than
|
|
97
|
+
// to silently swallow a real finding.
|
|
98
|
+
existingTitles = new Set();
|
|
99
|
+
console.log(chalk.yellow(' Dedup: could not fetch existing issues — filing all'));
|
|
100
|
+
}
|
|
101
|
+
let filed = 0;
|
|
102
|
+
let skipped = 0;
|
|
103
|
+
for (const obs of observations) {
|
|
104
|
+
// Check 1: exact title match (case-insensitive)
|
|
105
|
+
if (existingTitles.has(obs.title.toLowerCase())) {
|
|
106
|
+
console.log(chalk.yellow(` Skipped (duplicate title): "${obs.title}"`));
|
|
107
|
+
skipped++;
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
// Check 2: filename-based similarity — if the observation's file path
|
|
111
|
+
// basename appears in any existing issue title, skip it. This catches
|
|
112
|
+
// the common case where the title format changes slightly between runs
|
|
113
|
+
// but the underlying file is the same.
|
|
114
|
+
if (obs.filePath) {
|
|
115
|
+
const fileBasename = obs.filePath.split('/').pop() || '';
|
|
116
|
+
if (fileBasename.length > 3) {
|
|
117
|
+
const hasSimilar = [...existingTitles].some((t) => t.includes(fileBasename));
|
|
118
|
+
if (hasSimilar) {
|
|
119
|
+
console.log(chalk.yellow(` Skipped (existing issue for ${fileBasename}): "${obs.title}"`));
|
|
120
|
+
skipped++;
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// No duplicate found — file it
|
|
126
|
+
try {
|
|
127
|
+
const labels = obs.labels.length > 0 ? `--label "${obs.labels.join(',')}"` : '';
|
|
128
|
+
const result = execSync(`gh issue create --title "${obs.title.replace(/"/g, '\\"')}" ${labels} --body "${obs.body.replace(/"/g, '\\"')}"`, { cwd: this.rootDir, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] }).trim();
|
|
129
|
+
obs.issueFiled = parseInt(result.match(/\/(\d+)$/)?.[1] || '0', 10);
|
|
130
|
+
// Add the newly-filed title to the dedup set so subsequent
|
|
131
|
+
// observations in the same batch don't duplicate each other
|
|
132
|
+
existingTitles.add(obs.title.toLowerCase());
|
|
133
|
+
console.log(chalk.green(` Filed: ${result}`));
|
|
134
|
+
filed++;
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
console.log(chalk.yellow(` Failed to file issue "${obs.title}": ${err instanceof Error ? err.message : String(err)}`));
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
console.log(chalk.dim(` Summary: ${filed} filed, ${skipped} skipped (duplicates)`));
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Parse the observer's response into structured observations.
|
|
144
|
+
*/
|
|
145
|
+
parseObservations(response) {
|
|
146
|
+
const text = response.content
|
|
147
|
+
.filter((b) => b.type === 'text')
|
|
148
|
+
.map(b => b.text)
|
|
149
|
+
.join('\n');
|
|
150
|
+
// Parse observations from the structured format
|
|
151
|
+
const observations = [];
|
|
152
|
+
const obsRegex = /### (.+?)\n([\s\S]*?)(?=###|\[END\]|$)/g;
|
|
153
|
+
let match;
|
|
154
|
+
while ((match = obsRegex.exec(text)) !== null) {
|
|
155
|
+
const title = match[1].trim();
|
|
156
|
+
const body = match[2].trim();
|
|
157
|
+
// Skip if it looks like "no observations"
|
|
158
|
+
if (title.toLowerCase().includes('no observation') || title.toLowerCase().includes('none')) {
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
// Extract file path if mentioned
|
|
162
|
+
const fileMatch = body.match(/`(packages\/[^`]+)`/);
|
|
163
|
+
// Determine labels
|
|
164
|
+
const labels = [];
|
|
165
|
+
const bodyLower = body.toLowerCase();
|
|
166
|
+
if (bodyLower.includes('token') || bodyLower.includes('color') || bodyLower.includes('spacing')) {
|
|
167
|
+
labels.push('tokens');
|
|
168
|
+
}
|
|
169
|
+
if (bodyLower.includes('slot') || bodyLower.includes('component') || bodyLower.includes('property')) {
|
|
170
|
+
labels.push('component');
|
|
171
|
+
}
|
|
172
|
+
if (bodyLower.includes('accessibility') || bodyLower.includes('aria') || bodyLower.includes('a11y')) {
|
|
173
|
+
labels.push('accessibility');
|
|
174
|
+
}
|
|
175
|
+
if (bodyLower.includes('inconsisten') || bodyLower.includes('pattern')) {
|
|
176
|
+
labels.push('eddie-brain');
|
|
177
|
+
}
|
|
178
|
+
observations.push({
|
|
179
|
+
title,
|
|
180
|
+
body: `${body}\n\n---\n*Filed automatically by Eddie's Brain autonomous loop*`,
|
|
181
|
+
labels: labels.length > 0 ? labels : ['eddie-brain'],
|
|
182
|
+
filePath: fileMatch?.[1],
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
return observations;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
const OBSERVER_SYSTEM_PROMPT = `You are an Eddie Design System architectural observer. You review component source code and identify improvement opportunities — things like:
|
|
189
|
+
|
|
190
|
+
- Missing slots that JSDoc promises but the template doesn't implement
|
|
191
|
+
- Inconsistent patterns across similar components (e.g., one uses classnames library, others use componentClassNames())
|
|
192
|
+
- Raw values that should use design tokens
|
|
193
|
+
- Missing accessibility attributes
|
|
194
|
+
- Components that could compose with other Eddie components but don't
|
|
195
|
+
- Opportunities to use existing Eddie patterns (EdFormElement, slotNotEmpty, etc.)
|
|
196
|
+
- Dead code or unused properties
|
|
197
|
+
|
|
198
|
+
RULES:
|
|
199
|
+
- Only report genuinely useful observations, not cosmetic nitpicks
|
|
200
|
+
- Each observation should be actionable — someone should be able to fix it
|
|
201
|
+
- Do NOT repeat violations that were already fixed
|
|
202
|
+
- Limit to 2-3 observations max per review (quality over quantity)
|
|
203
|
+
- If the files look clean and well-structured, say so and output [END]
|
|
204
|
+
|
|
205
|
+
FORMAT your response as:
|
|
206
|
+
|
|
207
|
+
### Observation Title
|
|
208
|
+
Description of the issue, why it matters, and suggested fix.
|
|
209
|
+
Reference the specific file and line if applicable.
|
|
210
|
+
|
|
211
|
+
### Another Observation
|
|
212
|
+
...
|
|
213
|
+
|
|
214
|
+
[END]
|
|
215
|
+
|
|
216
|
+
If there are no observations worth filing, just output:
|
|
217
|
+
### No observations
|
|
218
|
+
The reviewed files follow Eddie conventions correctly.
|
|
219
|
+
[END]`;
|
|
220
|
+
//# sourceMappingURL=observer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observer.js","sourceRoot":"","sources":["../../src/loop/observer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pacer — Rate-limit-aware scheduling for the autonomous loop.
|
|
3
|
+
*
|
|
4
|
+
* Manages cooldowns between laps and API calls to stay within
|
|
5
|
+
* the Anthropic API rate limits (450K input tokens/min).
|
|
6
|
+
*/
|
|
7
|
+
export declare class Pacer {
|
|
8
|
+
private apiCallTimestamps;
|
|
9
|
+
private backoffLevel;
|
|
10
|
+
private maxBackoffLevel;
|
|
11
|
+
/**
|
|
12
|
+
* Wait between laps.
|
|
13
|
+
*/
|
|
14
|
+
waitBetweenLaps(): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Wait between individual API calls within a lap.
|
|
17
|
+
*/
|
|
18
|
+
waitBetweenApiCalls(): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Wait between full pipeline runs (Type B laps).
|
|
21
|
+
*/
|
|
22
|
+
waitBetweenPipelineRuns(): Promise<void>;
|
|
23
|
+
/**
|
|
24
|
+
* Record an API call for rate tracking.
|
|
25
|
+
*/
|
|
26
|
+
recordApiCall(): void;
|
|
27
|
+
/**
|
|
28
|
+
* Record a rate limit hit — increases all cooldowns.
|
|
29
|
+
*/
|
|
30
|
+
record429(): void;
|
|
31
|
+
/**
|
|
32
|
+
* Record a successful API call — may decrease backoff over time.
|
|
33
|
+
*/
|
|
34
|
+
recordSuccess(): void;
|
|
35
|
+
/**
|
|
36
|
+
* Check if the loop should stop based on time budget.
|
|
37
|
+
*/
|
|
38
|
+
shouldStop(startTime: number, maxHours: number): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Get the number of API calls in the last 60 seconds.
|
|
41
|
+
*/
|
|
42
|
+
getRecentCallCount(): number;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=pacer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pacer.d.ts","sourceRoot":"","sources":["../../src/loop/pacer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAiBH,qBAAa,KAAK;IAChB,OAAO,CAAC,iBAAiB,CAAgB;IACzC,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,eAAe,CAAK;IAE5B;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAOtC;;OAEG;IACG,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC;IAK1C;;OAEG;IACG,uBAAuB,IAAI,OAAO,CAAC,IAAI,CAAC;IAO9C;;OAEG;IACH,aAAa,IAAI,IAAI;IAOrB;;OAEG;IACH,SAAS,IAAI,IAAI;IAOjB;;OAEG;IACH,aAAa,IAAI,IAAI;IAQrB;;OAEG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO;IAMxD;;OAEG;IACH,kBAAkB,IAAI,MAAM;CAI7B"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pacer — Rate-limit-aware scheduling for the autonomous loop.
|
|
3
|
+
*
|
|
4
|
+
* Manages cooldowns between laps and API calls to stay within
|
|
5
|
+
* the Anthropic API rate limits (450K input tokens/min).
|
|
6
|
+
*/
|
|
7
|
+
import chalk from 'chalk';
|
|
8
|
+
import { sleep } from '../utils/anthropic.js';
|
|
9
|
+
/** Default cooldown between laps in ms */
|
|
10
|
+
const LAP_COOLDOWN_MS = 60_000;
|
|
11
|
+
/** Default cooldown between API calls in ms */
|
|
12
|
+
const API_CALL_COOLDOWN_MS = 5_000;
|
|
13
|
+
/** Cooldown between full pipeline runs in ms */
|
|
14
|
+
const PIPELINE_COOLDOWN_MS = 120_000;
|
|
15
|
+
/** Multiplier applied to cooldowns after a 429 error */
|
|
16
|
+
const BACKOFF_MULTIPLIER = 2;
|
|
17
|
+
export class Pacer {
|
|
18
|
+
apiCallTimestamps = [];
|
|
19
|
+
backoffLevel = 0;
|
|
20
|
+
maxBackoffLevel = 3;
|
|
21
|
+
/**
|
|
22
|
+
* Wait between laps.
|
|
23
|
+
*/
|
|
24
|
+
async waitBetweenLaps() {
|
|
25
|
+
const delay = LAP_COOLDOWN_MS * Math.pow(BACKOFF_MULTIPLIER, this.backoffLevel);
|
|
26
|
+
const delaySec = Math.round(delay / 1000);
|
|
27
|
+
console.log(chalk.gray(` Cooling down ${delaySec}s before next lap...`));
|
|
28
|
+
await sleep(delay);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Wait between individual API calls within a lap.
|
|
32
|
+
*/
|
|
33
|
+
async waitBetweenApiCalls() {
|
|
34
|
+
const delay = API_CALL_COOLDOWN_MS * Math.pow(BACKOFF_MULTIPLIER, this.backoffLevel);
|
|
35
|
+
await sleep(delay);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Wait between full pipeline runs (Type B laps).
|
|
39
|
+
*/
|
|
40
|
+
async waitBetweenPipelineRuns() {
|
|
41
|
+
const delay = PIPELINE_COOLDOWN_MS * Math.pow(BACKOFF_MULTIPLIER, this.backoffLevel);
|
|
42
|
+
const delaySec = Math.round(delay / 1000);
|
|
43
|
+
console.log(chalk.gray(` Pipeline cooldown ${delaySec}s...`));
|
|
44
|
+
await sleep(delay);
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Record an API call for rate tracking.
|
|
48
|
+
*/
|
|
49
|
+
recordApiCall() {
|
|
50
|
+
this.apiCallTimestamps.push(Date.now());
|
|
51
|
+
// Keep only last 60 seconds of timestamps
|
|
52
|
+
const cutoff = Date.now() - 60_000;
|
|
53
|
+
this.apiCallTimestamps = this.apiCallTimestamps.filter(t => t > cutoff);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Record a rate limit hit — increases all cooldowns.
|
|
57
|
+
*/
|
|
58
|
+
record429() {
|
|
59
|
+
if (this.backoffLevel < this.maxBackoffLevel) {
|
|
60
|
+
this.backoffLevel++;
|
|
61
|
+
console.log(chalk.yellow(` Rate limit hit. Backoff level increased to ${this.backoffLevel}.`));
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Record a successful API call — may decrease backoff over time.
|
|
66
|
+
*/
|
|
67
|
+
recordSuccess() {
|
|
68
|
+
// After 10 consecutive successful calls, reduce backoff
|
|
69
|
+
const recentCalls = this.apiCallTimestamps.length;
|
|
70
|
+
if (recentCalls >= 10 && this.backoffLevel > 0) {
|
|
71
|
+
this.backoffLevel--;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Check if the loop should stop based on time budget.
|
|
76
|
+
*/
|
|
77
|
+
shouldStop(startTime, maxHours) {
|
|
78
|
+
const elapsedMs = Date.now() - startTime;
|
|
79
|
+
const maxMs = maxHours * 60 * 60 * 1000;
|
|
80
|
+
return elapsedMs >= maxMs;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Get the number of API calls in the last 60 seconds.
|
|
84
|
+
*/
|
|
85
|
+
getRecentCallCount() {
|
|
86
|
+
const cutoff = Date.now() - 60_000;
|
|
87
|
+
return this.apiCallTimestamps.filter(t => t > cutoff).length;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=pacer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pacer.js","sourceRoot":"","sources":["../../src/loop/pacer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reporter — Generates markdown reports from loop state.
|
|
3
|
+
*/
|
|
4
|
+
import type { LoopConfig, LoopState } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Generate a markdown report from the loop state.
|
|
7
|
+
*/
|
|
8
|
+
export declare function generateReport(state: LoopState, config: LoopConfig): string;
|
|
9
|
+
//# sourceMappingURL=reporter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../../src/loop/reporter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAuB,MAAM,YAAY,CAAC;AAG7E;;GAEG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CA+F3E"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reporter — Generates markdown reports from loop state.
|
|
3
|
+
*/
|
|
4
|
+
import { LAP_TYPE_LABELS } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Generate a markdown report from the loop state.
|
|
7
|
+
*/
|
|
8
|
+
export function generateReport(state, config) {
|
|
9
|
+
const report = buildReport(state);
|
|
10
|
+
const lines = [];
|
|
11
|
+
const durationMin = Math.round(report.durationMs / 60_000);
|
|
12
|
+
const startDate = new Date(state.startedAt).toISOString().slice(0, 16).replace('T', ' ');
|
|
13
|
+
lines.push('# Eddie\'s Brain — Autonomous Loop Report');
|
|
14
|
+
lines.push('');
|
|
15
|
+
lines.push(`**Date:** ${startDate}`);
|
|
16
|
+
lines.push(`**Branch:** \`${state.branch}\``);
|
|
17
|
+
lines.push(`**Duration:** ${durationMin} minutes`);
|
|
18
|
+
lines.push(`**Model:** ${config.model}`);
|
|
19
|
+
lines.push('');
|
|
20
|
+
// Summary
|
|
21
|
+
lines.push('## Summary');
|
|
22
|
+
lines.push('');
|
|
23
|
+
lines.push(`| Metric | Value |`);
|
|
24
|
+
lines.push(`|--------|-------|`);
|
|
25
|
+
lines.push(`| Total laps | ${report.totalLaps} |`);
|
|
26
|
+
lines.push(`| Violations fixed | ${report.totalFixed} |`);
|
|
27
|
+
lines.push(`| False positives | ${report.totalFalsePositives} |`);
|
|
28
|
+
lines.push(`| Errors | ${report.totalErrors} |`);
|
|
29
|
+
lines.push(`| Issues remaining | ${report.remainingIssueCount} |`);
|
|
30
|
+
lines.push('');
|
|
31
|
+
// Laps by type
|
|
32
|
+
if (Object.keys(report.lapsByType).length > 0) {
|
|
33
|
+
lines.push('## Laps by Type');
|
|
34
|
+
lines.push('');
|
|
35
|
+
lines.push('| Type | Count |');
|
|
36
|
+
lines.push('|------|-------|');
|
|
37
|
+
for (const [type, count] of Object.entries(report.lapsByType)) {
|
|
38
|
+
if (count > 0) {
|
|
39
|
+
lines.push(`| ${type} — ${LAP_TYPE_LABELS[type]} | ${count} |`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
lines.push('');
|
|
43
|
+
}
|
|
44
|
+
// Violation fixes
|
|
45
|
+
const allFixes = report.laps.flatMap(l => l.fixes ?? []);
|
|
46
|
+
if (allFixes.length > 0) {
|
|
47
|
+
lines.push('## Violation Fixes');
|
|
48
|
+
lines.push('');
|
|
49
|
+
lines.push('| Issue | File | Violations | Status |');
|
|
50
|
+
lines.push('|-------|------|------------|--------|');
|
|
51
|
+
for (const fix of allFixes) {
|
|
52
|
+
const status = fix.success
|
|
53
|
+
? (fix.remainingViolations === 0 ? 'Fixed' : `Partial (${fix.remainingViolations} remain)`)
|
|
54
|
+
: fix.falsePositive
|
|
55
|
+
? 'False positive'
|
|
56
|
+
: `Failed: ${fix.error ?? 'unknown'}`;
|
|
57
|
+
lines.push(`| #${fix.issueNumber} | \`${fix.filePath}\` | ${fix.violationCount} | ${status} |`);
|
|
58
|
+
}
|
|
59
|
+
lines.push('');
|
|
60
|
+
}
|
|
61
|
+
// Fidelity scores
|
|
62
|
+
if (report.fidelityScores.length > 0) {
|
|
63
|
+
lines.push('## Fidelity Scores');
|
|
64
|
+
lines.push('');
|
|
65
|
+
lines.push('| Component | Score | Imports | Class | Props | Render | SCSS | Registration |');
|
|
66
|
+
lines.push('|-----------|-------|---------|-------|-------|--------|------|-------------|');
|
|
67
|
+
for (const f of report.fidelityScores) {
|
|
68
|
+
lines.push(`| ${f.componentName} | **${f.score}/5** | ${f.dimensions.imports} | ${f.dimensions.classStructure} | ${f.dimensions.propertyApi} | ${f.dimensions.renderMethod} | ${f.dimensions.scss} | ${f.dimensions.registration} |`);
|
|
69
|
+
}
|
|
70
|
+
lines.push('');
|
|
71
|
+
}
|
|
72
|
+
// Observations filed as issues
|
|
73
|
+
const allObservations = report.laps.flatMap(l => l.observations ?? []);
|
|
74
|
+
if (allObservations.length > 0) {
|
|
75
|
+
lines.push('## Observations Filed');
|
|
76
|
+
lines.push('');
|
|
77
|
+
for (const obs of allObservations) {
|
|
78
|
+
const issueRef = obs.issueFiled ? ` (#${obs.issueFiled})` : '';
|
|
79
|
+
lines.push(`- **${obs.title}**${issueRef}`);
|
|
80
|
+
}
|
|
81
|
+
lines.push('');
|
|
82
|
+
}
|
|
83
|
+
// Errors
|
|
84
|
+
const errors = report.laps.filter(l => l.error);
|
|
85
|
+
if (errors.length > 0) {
|
|
86
|
+
lines.push('## Errors');
|
|
87
|
+
lines.push('');
|
|
88
|
+
for (const lap of errors) {
|
|
89
|
+
lines.push(`- **Lap ${lap.lapNumber}** (${LAP_TYPE_LABELS[lap.type]}): ${lap.error}`);
|
|
90
|
+
}
|
|
91
|
+
lines.push('');
|
|
92
|
+
}
|
|
93
|
+
return lines.join('\n');
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Build a LoopReport from the state.
|
|
97
|
+
*/
|
|
98
|
+
function buildReport(state) {
|
|
99
|
+
const allFixes = state.completedLaps.flatMap(l => l.fixes ?? []);
|
|
100
|
+
const allFidelity = state.completedLaps
|
|
101
|
+
.map(l => l.fidelity)
|
|
102
|
+
.filter((f) => f !== undefined);
|
|
103
|
+
const lapsByType = { A: 0, B: 0, C: 0, D: 0 };
|
|
104
|
+
for (const lap of state.completedLaps) {
|
|
105
|
+
lapsByType[lap.type]++;
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
durationMs: Date.now() - new Date(state.startedAt).getTime(),
|
|
109
|
+
totalLaps: state.completedLaps.length,
|
|
110
|
+
lapsByType,
|
|
111
|
+
totalFixed: allFixes.filter(f => f.success).length,
|
|
112
|
+
totalFalsePositives: allFixes.filter(f => f.falsePositive).length,
|
|
113
|
+
totalErrors: state.completedLaps.filter(l => l.error).length,
|
|
114
|
+
fidelityScores: allFidelity,
|
|
115
|
+
remainingIssueCount: 0, // Would need to re-fetch to know
|
|
116
|
+
laps: state.completedLaps,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=reporter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reporter.js","sourceRoot":"","sources":["../../src/loop/reporter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LoopRunner — Main orchestrator for the autonomous loop.
|
|
3
|
+
*
|
|
4
|
+
* Cycles through lap types (A: violation fixes, B: fidelity tests),
|
|
5
|
+
* manages git branches, persists state for resumability, and
|
|
6
|
+
* generates reports at the end.
|
|
7
|
+
*/
|
|
8
|
+
import type { KnowledgeGraph } from '../knowledge-graph/index.js';
|
|
9
|
+
import type { LoopConfig } from './types.js';
|
|
10
|
+
export declare class LoopRunner {
|
|
11
|
+
private config;
|
|
12
|
+
private knowledgeGraph;
|
|
13
|
+
private pacer;
|
|
14
|
+
private issueFetcher;
|
|
15
|
+
private fixAgent;
|
|
16
|
+
private observer;
|
|
17
|
+
private state;
|
|
18
|
+
private brainDir;
|
|
19
|
+
constructor(config: LoopConfig, knowledgeGraph: KnowledgeGraph);
|
|
20
|
+
/**
|
|
21
|
+
* Run the autonomous loop.
|
|
22
|
+
*/
|
|
23
|
+
/** Track fixes since last PR for chunking */
|
|
24
|
+
private fixesSinceLastPr;
|
|
25
|
+
private prCount;
|
|
26
|
+
run(): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Execute a single lap.
|
|
29
|
+
*/
|
|
30
|
+
private executeLap;
|
|
31
|
+
/**
|
|
32
|
+
* Type A: Fix violation issues.
|
|
33
|
+
*/
|
|
34
|
+
private executeViolationFixLap;
|
|
35
|
+
/**
|
|
36
|
+
* Type B: Pipeline fidelity test.
|
|
37
|
+
*/
|
|
38
|
+
private executeFidelityLap;
|
|
39
|
+
/**
|
|
40
|
+
* Select the next lap type using round-robin.
|
|
41
|
+
*/
|
|
42
|
+
private selectNextLapType;
|
|
43
|
+
private setupGitBranch;
|
|
44
|
+
private commitFixes;
|
|
45
|
+
private hasCommits;
|
|
46
|
+
/**
|
|
47
|
+
* Create a chunked PR: push current branch, create PR to dev, then start a new branch.
|
|
48
|
+
*/
|
|
49
|
+
private createChunkedPr;
|
|
50
|
+
private createInitialState;
|
|
51
|
+
private saveState;
|
|
52
|
+
private loadState;
|
|
53
|
+
private saveReport;
|
|
54
|
+
private printHeader;
|
|
55
|
+
private dryRun;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/loop/runner.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,KAAK,EACV,UAAU,EAKX,MAAM,YAAY,CAAC;AAWpB,qBAAa,UAAU;IASnB,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,cAAc;IATxB,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,KAAK,CAAY;IACzB,OAAO,CAAC,QAAQ,CAAS;gBAGf,MAAM,EAAE,UAAU,EAClB,cAAc,EAAE,cAAc;IAqBxC;;OAEG;IACH,6CAA6C;IAC7C,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,OAAO,CAAK;IAEd,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAkH1B;;OAEG;YACW,UAAU;IAkBxB;;OAEG;YACW,sBAAsB;IA+CpC;;OAEG;YACW,kBAAkB;IAWhC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAczB,OAAO,CAAC,cAAc;IAgCtB,OAAO,CAAC,WAAW;IAoBnB,OAAO,CAAC,UAAU;IAYlB;;OAEG;YACW,eAAe;IAgD7B,OAAO,CAAC,kBAAkB;IAa1B,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,SAAS;IAWjB,OAAO,CAAC,UAAU;IAgBlB,OAAO,CAAC,WAAW;YAUL,MAAM;CAiBrB"}
|