codeloop-mcp-server 0.1.14 → 0.1.15
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/dist/auth/local_mode.d.ts +32 -0
- package/dist/auth/local_mode.d.ts.map +1 -0
- package/dist/auth/local_mode.js +56 -0
- package/dist/auth/local_mode.js.map +1 -0
- package/dist/auth/usage_tracker.d.ts +11 -1
- package/dist/auth/usage_tracker.d.ts.map +1 -1
- package/dist/auth/usage_tracker.js +51 -4
- package/dist/auth/usage_tracker.js.map +1 -1
- package/dist/environment/presets.d.ts +46 -0
- package/dist/environment/presets.d.ts.map +1 -0
- package/dist/environment/presets.js +109 -0
- package/dist/environment/presets.js.map +1 -0
- package/dist/evidence/baseline_governance.d.ts +62 -0
- package/dist/evidence/baseline_governance.d.ts.map +1 -0
- package/dist/evidence/baseline_governance.js +113 -0
- package/dist/evidence/baseline_governance.js.map +1 -0
- package/dist/evidence/run_lineage.d.ts +66 -0
- package/dist/evidence/run_lineage.d.ts.map +1 -0
- package/dist/evidence/run_lineage.js +138 -0
- package/dist/evidence/run_lineage.js.map +1 -0
- package/dist/evidence/screenshot_diff.d.ts +6 -2
- package/dist/evidence/screenshot_diff.d.ts.map +1 -1
- package/dist/evidence/screenshot_diff.js +40 -3
- package/dist/evidence/screenshot_diff.js.map +1 -1
- package/dist/evidence/visual_attribution.d.ts +32 -0
- package/dist/evidence/visual_attribution.d.ts.map +1 -0
- package/dist/evidence/visual_attribution.js +88 -0
- package/dist/evidence/visual_attribution.js.map +1 -0
- package/dist/index.js +150 -0
- package/dist/index.js.map +1 -1
- package/dist/prompt_manager/index.d.ts +27 -0
- package/dist/prompt_manager/index.d.ts.map +1 -0
- package/dist/prompt_manager/index.js +28 -0
- package/dist/prompt_manager/index.js.map +1 -0
- package/dist/prompt_manager/state_machine.d.ts +55 -0
- package/dist/prompt_manager/state_machine.d.ts.map +1 -0
- package/dist/prompt_manager/state_machine.js +60 -0
- package/dist/prompt_manager/state_machine.js.map +1 -0
- package/dist/prompt_manager/templates.d.ts +43 -0
- package/dist/prompt_manager/templates.d.ts.map +1 -0
- package/dist/prompt_manager/templates.js +177 -0
- package/dist/prompt_manager/templates.js.map +1 -0
- package/dist/runners/base.d.ts +1 -1
- package/dist/runners/base.d.ts.map +1 -1
- package/dist/runners/base.js +2 -2
- package/dist/runners/base.js.map +1 -1
- package/dist/runners/figma_spec_generator.d.ts +54 -0
- package/dist/runners/figma_spec_generator.d.ts.map +1 -0
- package/dist/runners/figma_spec_generator.js +227 -0
- package/dist/runners/figma_spec_generator.js.map +1 -0
- package/dist/runners/playwright.d.ts +9 -1
- package/dist/runners/playwright.d.ts.map +1 -1
- package/dist/runners/playwright.js +18 -3
- package/dist/runners/playwright.js.map +1 -1
- package/dist/runners/plugin_sdk.d.ts +25 -0
- package/dist/runners/plugin_sdk.d.ts.map +1 -0
- package/dist/runners/plugin_sdk.js +86 -0
- package/dist/runners/plugin_sdk.js.map +1 -0
- package/dist/state/dependency_graph.d.ts +23 -0
- package/dist/state/dependency_graph.d.ts.map +1 -0
- package/dist/state/dependency_graph.js +127 -0
- package/dist/state/dependency_graph.js.map +1 -0
- package/dist/state/section_registry.d.ts.map +1 -1
- package/dist/state/section_registry.js +11 -5
- package/dist/state/section_registry.js.map +1 -1
- package/dist/tools/design_compare.js +2 -2
- package/dist/tools/design_compare.js.map +1 -1
- package/dist/tools/update_baseline.d.ts +3 -0
- package/dist/tools/update_baseline.d.ts.map +1 -1
- package/dist/tools/update_baseline.js +18 -2
- package/dist/tools/update_baseline.js.map +1 -1
- package/dist/tools/verify.d.ts.map +1 -1
- package/dist/tools/verify.js +66 -4
- package/dist/tools/verify.js.map +1 -1
- package/dist/tools/visual_review.js +1 -1
- package/dist/tools/visual_review.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local mode — skip all cloud API calls.
|
|
3
|
+
*
|
|
4
|
+
* When `CODELOOP_MODE=local` or `config.mode = "local"`, the server:
|
|
5
|
+
* - Skips API key validation (all keys accepted)
|
|
6
|
+
* - Queues usage events to disk instead of POSTing them
|
|
7
|
+
* - Operates entirely offline (no network calls)
|
|
8
|
+
*
|
|
9
|
+
* This is intended for enterprise self-hosted deployments and air-gapped
|
|
10
|
+
* environments. Usage events are stored in `.codeloop/offline_queue.json`
|
|
11
|
+
* and can be flushed manually via `codeloop_flush_usage` or when the
|
|
12
|
+
* server re-connects.
|
|
13
|
+
*/
|
|
14
|
+
export type CodeLoopMode = "cloud" | "local";
|
|
15
|
+
export declare function detectMode(): CodeLoopMode;
|
|
16
|
+
export declare function isLocalMode(): boolean;
|
|
17
|
+
export interface PersistedQueueEntry {
|
|
18
|
+
apiKey: string;
|
|
19
|
+
event: string;
|
|
20
|
+
count: number;
|
|
21
|
+
idempotencyKey: string;
|
|
22
|
+
timestamp: number;
|
|
23
|
+
}
|
|
24
|
+
export interface PersistedQueue {
|
|
25
|
+
entries: PersistedQueueEntry[];
|
|
26
|
+
updated_at: string;
|
|
27
|
+
}
|
|
28
|
+
export declare function loadPersistedQueue(cwd: string): PersistedQueue;
|
|
29
|
+
export declare function savePersistedQueue(cwd: string, queue: PersistedQueue): void;
|
|
30
|
+
export declare function enqueueOffline(cwd: string, entry: Omit<PersistedQueueEntry, "timestamp">): void;
|
|
31
|
+
export declare function drainPersistedQueue(cwd: string): PersistedQueueEntry[];
|
|
32
|
+
//# sourceMappingURL=local_mode.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local_mode.d.ts","sourceRoot":"","sources":["../../src/auth/local_mode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAKH,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,OAAO,CAAC;AAE7C,wBAAgB,UAAU,IAAI,YAAY,CAIzC;AAED,wBAAgB,WAAW,IAAI,OAAO,CAErC;AAID,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,mBAAmB,EAAE,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;CACpB;AAID,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,cAAc,CAS9D;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,IAAI,CAK3E;AAED,wBAAgB,cAAc,CAC5B,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,IAAI,CAAC,mBAAmB,EAAE,WAAW,CAAC,GAC5C,IAAI,CAIN;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB,EAAE,CAMtE"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local mode — skip all cloud API calls.
|
|
3
|
+
*
|
|
4
|
+
* When `CODELOOP_MODE=local` or `config.mode = "local"`, the server:
|
|
5
|
+
* - Skips API key validation (all keys accepted)
|
|
6
|
+
* - Queues usage events to disk instead of POSTing them
|
|
7
|
+
* - Operates entirely offline (no network calls)
|
|
8
|
+
*
|
|
9
|
+
* This is intended for enterprise self-hosted deployments and air-gapped
|
|
10
|
+
* environments. Usage events are stored in `.codeloop/offline_queue.json`
|
|
11
|
+
* and can be flushed manually via `codeloop_flush_usage` or when the
|
|
12
|
+
* server re-connects.
|
|
13
|
+
*/
|
|
14
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
|
|
15
|
+
import { join } from "path";
|
|
16
|
+
export function detectMode() {
|
|
17
|
+
const envMode = process.env.CODELOOP_MODE;
|
|
18
|
+
if (envMode === "local" || envMode === "offline")
|
|
19
|
+
return "local";
|
|
20
|
+
return "cloud";
|
|
21
|
+
}
|
|
22
|
+
export function isLocalMode() {
|
|
23
|
+
return detectMode() === "local";
|
|
24
|
+
}
|
|
25
|
+
const QUEUE_FILE = ".codeloop/offline_queue.json";
|
|
26
|
+
export function loadPersistedQueue(cwd) {
|
|
27
|
+
const p = join(cwd, QUEUE_FILE);
|
|
28
|
+
if (!existsSync(p))
|
|
29
|
+
return { entries: [], updated_at: new Date().toISOString() };
|
|
30
|
+
try {
|
|
31
|
+
const raw = JSON.parse(readFileSync(p, "utf-8"));
|
|
32
|
+
return Array.isArray(raw.entries) ? raw : { entries: [], updated_at: new Date().toISOString() };
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return { entries: [], updated_at: new Date().toISOString() };
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export function savePersistedQueue(cwd, queue) {
|
|
39
|
+
const dir = join(cwd, ".codeloop");
|
|
40
|
+
mkdirSync(dir, { recursive: true });
|
|
41
|
+
queue.updated_at = new Date().toISOString();
|
|
42
|
+
writeFileSync(join(cwd, QUEUE_FILE), JSON.stringify(queue, null, 2));
|
|
43
|
+
}
|
|
44
|
+
export function enqueueOffline(cwd, entry) {
|
|
45
|
+
const queue = loadPersistedQueue(cwd);
|
|
46
|
+
queue.entries.push({ ...entry, timestamp: Date.now() });
|
|
47
|
+
savePersistedQueue(cwd, queue);
|
|
48
|
+
}
|
|
49
|
+
export function drainPersistedQueue(cwd) {
|
|
50
|
+
const queue = loadPersistedQueue(cwd);
|
|
51
|
+
const entries = [...queue.entries];
|
|
52
|
+
queue.entries = [];
|
|
53
|
+
savePersistedQueue(cwd, queue);
|
|
54
|
+
return entries;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=local_mode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local_mode.js","sourceRoot":"","sources":["../../src/auth/local_mode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AACxE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAI5B,MAAM,UAAU,UAAU;IACxB,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;IAC1C,IAAI,OAAO,KAAK,OAAO,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,OAAO,CAAC;IACjE,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,OAAO,UAAU,EAAE,KAAK,OAAO,CAAC;AAClC,CAAC;AAiBD,MAAM,UAAU,GAAG,8BAA8B,CAAC;AAElD,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IAChC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;QAAE,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;IACjF,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAmB,CAAC;QACnE,OAAO,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;IAClG,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;IAC/D,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,GAAW,EAAE,KAAqB;IACnE,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;IACnC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpC,KAAK,CAAC,UAAU,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC5C,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,GAAW,EACX,KAA6C;IAE7C,MAAM,KAAK,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;IACtC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IACxD,kBAAkB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,GAAW;IAC7C,MAAM,KAAK,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;IACnC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC;IACnB,kBAAkB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC/B,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
export type UsageEvent = "verification_run" | "visual_review" | "design_comparison" | "recommendation" | "release_readiness" | "interaction";
|
|
2
|
-
export declare function trackUsage(apiKey: string, event: UsageEvent, count?: number): Promise<void>;
|
|
2
|
+
export declare function trackUsage(apiKey: string, event: UsageEvent, count?: number, cwd?: string): Promise<void>;
|
|
3
|
+
/**
|
|
4
|
+
* Drain the on-disk offline queue (`.codeloop/offline_queue.json`) and
|
|
5
|
+
* POST each entry to the backend. Used by `codeloop_flush_usage` once the
|
|
6
|
+
* server detects it is back online.
|
|
7
|
+
*/
|
|
8
|
+
export declare function flushPersistedUsage(cwd?: string): Promise<{
|
|
9
|
+
attempted: number;
|
|
10
|
+
succeeded: number;
|
|
11
|
+
requeued: number;
|
|
12
|
+
}>;
|
|
3
13
|
export declare function flushOfflineQueue(): Promise<number>;
|
|
4
14
|
export declare function getOfflineQueueSize(): number;
|
|
5
15
|
/** Clears the offline queue (for testing). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usage_tracker.d.ts","sourceRoot":"","sources":["../../src/auth/usage_tracker.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"usage_tracker.d.ts","sourceRoot":"","sources":["../../src/auth/usage_tracker.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,UAAU,GAClB,kBAAkB,GAClB,eAAe,GACf,mBAAmB,GACnB,gBAAgB,GAChB,mBAAmB,GACnB,aAAa,CAAC;AAYlB,wBAAsB,UAAU,CAC9B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,UAAU,EACjB,KAAK,GAAE,MAAU,EACjB,GAAG,GAAE,MAAsB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAqCf;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CAAC,GAAG,GAAE,MAAsB,GAAG,OAAO,CAAC;IAC9E,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,CAoCD;AAED,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC,CA6BzD;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED,8CAA8C;AAC9C,wBAAgB,iBAAiB,IAAI,IAAI,CAExC"}
|
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
import { BACKEND_URL, API_KEY_PREFIX_TEST } from "@codelooptech/shared";
|
|
2
|
+
import { isLocalMode, enqueueOffline, drainPersistedQueue, } from "./local_mode.js";
|
|
2
3
|
const offlineQueue = [];
|
|
3
|
-
export async function trackUsage(apiKey, event, count = 1) {
|
|
4
|
-
// Test keys skip tracking entirely
|
|
4
|
+
export async function trackUsage(apiKey, event, count = 1, cwd = process.cwd()) {
|
|
5
5
|
if (apiKey.startsWith(API_KEY_PREFIX_TEST)) {
|
|
6
6
|
return;
|
|
7
7
|
}
|
|
8
8
|
const idempotencyKey = `${apiKey}_${event}_${Date.now()}_${Math.random().toString(36).slice(2)}`;
|
|
9
|
+
// Local / self-hosted mode: never POST to the cloud. Persist to disk so
|
|
10
|
+
// the queue survives process restarts. flushPersistedUsage() drains it
|
|
11
|
+
// when the server reconnects.
|
|
12
|
+
if (isLocalMode()) {
|
|
13
|
+
enqueueOffline(cwd, { apiKey, event, count, idempotencyKey });
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
9
16
|
try {
|
|
10
17
|
await fetch(`${BACKEND_URL}/v1/usage/track`, {
|
|
11
18
|
method: "POST",
|
|
@@ -21,8 +28,6 @@ export async function trackUsage(apiKey, event, count = 1) {
|
|
|
21
28
|
});
|
|
22
29
|
}
|
|
23
30
|
catch {
|
|
24
|
-
// Usage tracking failure must not block tool execution.
|
|
25
|
-
// Queue event locally for retry on next successful connection.
|
|
26
31
|
offlineQueue.push({
|
|
27
32
|
apiKey,
|
|
28
33
|
event,
|
|
@@ -32,6 +37,48 @@ export async function trackUsage(apiKey, event, count = 1) {
|
|
|
32
37
|
});
|
|
33
38
|
}
|
|
34
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* Drain the on-disk offline queue (`.codeloop/offline_queue.json`) and
|
|
42
|
+
* POST each entry to the backend. Used by `codeloop_flush_usage` once the
|
|
43
|
+
* server detects it is back online.
|
|
44
|
+
*/
|
|
45
|
+
export async function flushPersistedUsage(cwd = process.cwd()) {
|
|
46
|
+
const entries = drainPersistedQueue(cwd);
|
|
47
|
+
let succeeded = 0;
|
|
48
|
+
const requeue = [];
|
|
49
|
+
for (const entry of entries) {
|
|
50
|
+
try {
|
|
51
|
+
const resp = await fetch(`${BACKEND_URL}/v1/usage/track`, {
|
|
52
|
+
method: "POST",
|
|
53
|
+
headers: {
|
|
54
|
+
"Content-Type": "application/json",
|
|
55
|
+
Authorization: `Bearer ${entry.apiKey}`,
|
|
56
|
+
},
|
|
57
|
+
body: JSON.stringify({
|
|
58
|
+
event: entry.event,
|
|
59
|
+
count: entry.count,
|
|
60
|
+
idempotency_key: entry.idempotencyKey,
|
|
61
|
+
}),
|
|
62
|
+
});
|
|
63
|
+
if (resp.ok)
|
|
64
|
+
succeeded++;
|
|
65
|
+
else
|
|
66
|
+
requeue.push(entry);
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
requeue.push(entry);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
for (const r of requeue) {
|
|
73
|
+
enqueueOffline(cwd, {
|
|
74
|
+
apiKey: r.apiKey,
|
|
75
|
+
event: r.event,
|
|
76
|
+
count: r.count,
|
|
77
|
+
idempotencyKey: r.idempotencyKey,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
return { attempted: entries.length, succeeded, requeued: requeue.length };
|
|
81
|
+
}
|
|
35
82
|
export async function flushOfflineQueue() {
|
|
36
83
|
if (offlineQueue.length === 0)
|
|
37
84
|
return 0;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usage_tracker.js","sourceRoot":"","sources":["../../src/auth/usage_tracker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"usage_tracker.js","sourceRoot":"","sources":["../../src/auth/usage_tracker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment normalization presets.
|
|
3
|
+
*
|
|
4
|
+
* Pre-defined configurations for viewports, network throttle, locale/timezone,
|
|
5
|
+
* seed data, API modes, and simulator targets. Agents reference presets by
|
|
6
|
+
* name (e.g. `viewport: "mobile_se"`) and this module resolves them to
|
|
7
|
+
* concrete settings that downstream runners (Playwright, Puppeteer, Xcode,
|
|
8
|
+
* Android Emulator) can consume.
|
|
9
|
+
*/
|
|
10
|
+
import type { ViewportPreset, NetworkThrottlePreset, EnvironmentPreset } from "@codelooptech/shared";
|
|
11
|
+
export declare const VIEWPORT_PRESETS: Record<string, ViewportPreset>;
|
|
12
|
+
export declare function resolveViewport(v: string | ViewportPreset | undefined): ViewportPreset | undefined;
|
|
13
|
+
export declare const NETWORK_PRESETS: Record<string, NetworkThrottlePreset>;
|
|
14
|
+
export declare function resolveNetwork(n: string | NetworkThrottlePreset | undefined): NetworkThrottlePreset | undefined;
|
|
15
|
+
export declare const LOCALE_PRESETS: Record<string, {
|
|
16
|
+
locale: string;
|
|
17
|
+
timezone: string;
|
|
18
|
+
}>;
|
|
19
|
+
export declare const SIMULATOR_PRESETS: Record<string, {
|
|
20
|
+
platform: string;
|
|
21
|
+
device: string;
|
|
22
|
+
os_version?: string;
|
|
23
|
+
}>;
|
|
24
|
+
export declare const SEED_DATA_PRESETS: Record<string, {
|
|
25
|
+
description: string;
|
|
26
|
+
fixture_path: string;
|
|
27
|
+
}>;
|
|
28
|
+
export interface ResolvedEnvironment {
|
|
29
|
+
viewport?: ViewportPreset;
|
|
30
|
+
seed_data?: string;
|
|
31
|
+
api_mode: "mock" | "real" | "record";
|
|
32
|
+
network?: NetworkThrottlePreset;
|
|
33
|
+
locale: string;
|
|
34
|
+
timezone: string;
|
|
35
|
+
simulator?: string;
|
|
36
|
+
}
|
|
37
|
+
export declare function resolveEnvironment(preset?: EnvironmentPreset): ResolvedEnvironment;
|
|
38
|
+
export declare function listPresets(): {
|
|
39
|
+
viewports: string[];
|
|
40
|
+
networks: string[];
|
|
41
|
+
locales: string[];
|
|
42
|
+
simulators: string[];
|
|
43
|
+
seed_data: string[];
|
|
44
|
+
api_modes: string[];
|
|
45
|
+
};
|
|
46
|
+
//# sourceMappingURL=presets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../src/environment/presets.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EACV,cAAc,EACd,qBAAqB,EACrB,iBAAiB,EAClB,MAAM,sBAAsB,CAAC;AAI9B,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAS3D,CAAC;AAEF,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,GAAG,cAAc,GAAG,SAAS,CAIlG;AAID,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAQjE,CAAC;AAEF,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,qBAAqB,GAAG,SAAS,GAAG,qBAAqB,GAAG,SAAS,CAI/G;AAID,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAQ/E,CAAC;AAIF,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAOA,CAAC;AAIF,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE;IAC7C,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB,CAKA,CAAC;AAIF,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAC;IACrC,OAAO,CAAC,EAAE,qBAAqB,CAAC;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,kBAAkB,CAAC,MAAM,CAAC,EAAE,iBAAiB,GAAG,mBAAmB,CA8BlF;AAED,wBAAgB,WAAW,IAAI;IAC7B,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB,CASA"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment normalization presets.
|
|
3
|
+
*
|
|
4
|
+
* Pre-defined configurations for viewports, network throttle, locale/timezone,
|
|
5
|
+
* seed data, API modes, and simulator targets. Agents reference presets by
|
|
6
|
+
* name (e.g. `viewport: "mobile_se"`) and this module resolves them to
|
|
7
|
+
* concrete settings that downstream runners (Playwright, Puppeteer, Xcode,
|
|
8
|
+
* Android Emulator) can consume.
|
|
9
|
+
*/
|
|
10
|
+
// ── Viewport presets ──
|
|
11
|
+
export const VIEWPORT_PRESETS = {
|
|
12
|
+
mobile_se: { name: "mobile_se", width: 375, height: 667, device_scale_factor: 2, is_mobile: true },
|
|
13
|
+
mobile_pro: { name: "mobile_pro", width: 390, height: 844, device_scale_factor: 3, is_mobile: true },
|
|
14
|
+
mobile_pro_max: { name: "mobile_pro_max", width: 428, height: 926, device_scale_factor: 3, is_mobile: true },
|
|
15
|
+
tablet_portrait: { name: "tablet_portrait", width: 768, height: 1024, device_scale_factor: 2, is_mobile: false },
|
|
16
|
+
tablet_landscape: { name: "tablet_landscape", width: 1024, height: 768, device_scale_factor: 2, is_mobile: false },
|
|
17
|
+
desktop_1280: { name: "desktop_1280", width: 1280, height: 720, device_scale_factor: 1, is_mobile: false },
|
|
18
|
+
desktop_1920: { name: "desktop_1920", width: 1920, height: 1080, device_scale_factor: 1, is_mobile: false },
|
|
19
|
+
desktop_4k: { name: "desktop_4k", width: 3840, height: 2160, device_scale_factor: 1, is_mobile: false },
|
|
20
|
+
};
|
|
21
|
+
export function resolveViewport(v) {
|
|
22
|
+
if (!v)
|
|
23
|
+
return undefined;
|
|
24
|
+
if (typeof v === "object")
|
|
25
|
+
return v;
|
|
26
|
+
return VIEWPORT_PRESETS[v];
|
|
27
|
+
}
|
|
28
|
+
// ── Network throttle presets ──
|
|
29
|
+
export const NETWORK_PRESETS = {
|
|
30
|
+
offline: { name: "offline", download_kbps: 0, upload_kbps: 0, latency_ms: 0 },
|
|
31
|
+
slow_2g: { name: "slow_2g", download_kbps: 50, upload_kbps: 25, latency_ms: 2000 },
|
|
32
|
+
"2g": { name: "2g", download_kbps: 250, upload_kbps: 50, latency_ms: 300 },
|
|
33
|
+
"3g": { name: "3g", download_kbps: 750, upload_kbps: 250, latency_ms: 100 },
|
|
34
|
+
"4g": { name: "4g", download_kbps: 4000, upload_kbps: 3000, latency_ms: 20 },
|
|
35
|
+
wifi: { name: "wifi", download_kbps: 30000, upload_kbps: 15000, latency_ms: 2 },
|
|
36
|
+
cable: { name: "cable", download_kbps: 50000, upload_kbps: 25000, latency_ms: 1 },
|
|
37
|
+
};
|
|
38
|
+
export function resolveNetwork(n) {
|
|
39
|
+
if (!n)
|
|
40
|
+
return undefined;
|
|
41
|
+
if (typeof n === "object")
|
|
42
|
+
return n;
|
|
43
|
+
return NETWORK_PRESETS[n];
|
|
44
|
+
}
|
|
45
|
+
// ── Locale presets ──
|
|
46
|
+
export const LOCALE_PRESETS = {
|
|
47
|
+
en_us: { locale: "en-US", timezone: "America/New_York" },
|
|
48
|
+
en_gb: { locale: "en-GB", timezone: "Europe/London" },
|
|
49
|
+
ja_jp: { locale: "ja-JP", timezone: "Asia/Tokyo" },
|
|
50
|
+
de_de: { locale: "de-DE", timezone: "Europe/Berlin" },
|
|
51
|
+
zh_cn: { locale: "zh-CN", timezone: "Asia/Shanghai" },
|
|
52
|
+
ar_sa: { locale: "ar-SA", timezone: "Asia/Riyadh" },
|
|
53
|
+
pt_br: { locale: "pt-BR", timezone: "America/Sao_Paulo" },
|
|
54
|
+
};
|
|
55
|
+
// ── Simulator presets ──
|
|
56
|
+
export const SIMULATOR_PRESETS = {
|
|
57
|
+
iphone_se: { platform: "ios", device: "iPhone SE (3rd generation)" },
|
|
58
|
+
iphone_15: { platform: "ios", device: "iPhone 15" },
|
|
59
|
+
iphone_15_pro_max: { platform: "ios", device: "iPhone 15 Pro Max" },
|
|
60
|
+
ipad_air: { platform: "ios", device: "iPad Air (5th generation)" },
|
|
61
|
+
pixel_7: { platform: "android", device: "Pixel 7" },
|
|
62
|
+
pixel_tablet: { platform: "android", device: "Pixel Tablet" },
|
|
63
|
+
};
|
|
64
|
+
// ── Seed data presets ──
|
|
65
|
+
export const SEED_DATA_PRESETS = {
|
|
66
|
+
empty: { description: "Empty database — fresh install", fixture_path: "fixtures/seed_empty.json" },
|
|
67
|
+
minimal: { description: "Minimal data — 1 user, 1 item", fixture_path: "fixtures/seed_minimal.json" },
|
|
68
|
+
realistic: { description: "Realistic sample — 50 users, varied data", fixture_path: "fixtures/seed_realistic.json" },
|
|
69
|
+
stress: { description: "Stress test — 10k records", fixture_path: "fixtures/seed_stress.json" },
|
|
70
|
+
};
|
|
71
|
+
export function resolveEnvironment(preset) {
|
|
72
|
+
if (!preset) {
|
|
73
|
+
return {
|
|
74
|
+
api_mode: "real",
|
|
75
|
+
locale: "en-US",
|
|
76
|
+
timezone: "UTC",
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
const viewport = resolveViewport(preset.viewport);
|
|
80
|
+
const network = resolveNetwork(preset.network);
|
|
81
|
+
let locale = preset.locale ?? "en-US";
|
|
82
|
+
let timezone = preset.timezone ?? "UTC";
|
|
83
|
+
const localePreset = preset.locale ? LOCALE_PRESETS[preset.locale] : undefined;
|
|
84
|
+
if (localePreset) {
|
|
85
|
+
locale = localePreset.locale;
|
|
86
|
+
if (!preset.timezone)
|
|
87
|
+
timezone = localePreset.timezone;
|
|
88
|
+
}
|
|
89
|
+
return {
|
|
90
|
+
viewport,
|
|
91
|
+
seed_data: preset.seed_data,
|
|
92
|
+
api_mode: preset.api_mode ?? "real",
|
|
93
|
+
network,
|
|
94
|
+
locale,
|
|
95
|
+
timezone,
|
|
96
|
+
simulator: preset.simulator,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
export function listPresets() {
|
|
100
|
+
return {
|
|
101
|
+
viewports: Object.keys(VIEWPORT_PRESETS),
|
|
102
|
+
networks: Object.keys(NETWORK_PRESETS),
|
|
103
|
+
locales: Object.keys(LOCALE_PRESETS),
|
|
104
|
+
simulators: Object.keys(SIMULATOR_PRESETS),
|
|
105
|
+
seed_data: Object.keys(SEED_DATA_PRESETS),
|
|
106
|
+
api_modes: ["mock", "real", "record"],
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=presets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presets.js","sourceRoot":"","sources":["../../src/environment/presets.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Baseline governance — region masks, change logs, and approval tracking.
|
|
3
|
+
*
|
|
4
|
+
* Region masks let you exclude dynamic UI regions (timestamps, avatars,
|
|
5
|
+
* ads) from visual comparison by zeroing them out in both baseline and
|
|
6
|
+
* actual screenshots before pixelmatch runs.
|
|
7
|
+
*
|
|
8
|
+
* Change logs record every baseline update with the commit, timestamp,
|
|
9
|
+
* approval status, and which screens changed — enabling audit trails.
|
|
10
|
+
*/
|
|
11
|
+
export interface MaskRegion {
|
|
12
|
+
x: number;
|
|
13
|
+
y: number;
|
|
14
|
+
width: number;
|
|
15
|
+
height: number;
|
|
16
|
+
}
|
|
17
|
+
export interface ScreenMask {
|
|
18
|
+
screen: string;
|
|
19
|
+
regions: MaskRegion[];
|
|
20
|
+
}
|
|
21
|
+
export interface MaskConfig {
|
|
22
|
+
masks: ScreenMask[];
|
|
23
|
+
}
|
|
24
|
+
export declare function loadMasks(cwd: string): MaskConfig;
|
|
25
|
+
export declare function saveMasks(cwd: string, config: MaskConfig): void;
|
|
26
|
+
export declare function getMaskForScreen(config: MaskConfig, screen: string): MaskRegion[];
|
|
27
|
+
/**
|
|
28
|
+
* Zero out masked regions in an RGBA buffer. Modifies the buffer in-place.
|
|
29
|
+
* Used to neutralize dynamic regions before pixelmatch comparison.
|
|
30
|
+
*
|
|
31
|
+
* Coordinates are clamped to [0, width) x [0, height); negative origins and
|
|
32
|
+
* regions extending past the image bounds are silently truncated rather
|
|
33
|
+
* than corrupting buffer memory.
|
|
34
|
+
*/
|
|
35
|
+
export declare function applyMaskToBuffer(data: Buffer, width: number, height: number, regions: MaskRegion[]): void;
|
|
36
|
+
export interface BaselineChangeEntry {
|
|
37
|
+
timestamp: string;
|
|
38
|
+
screens: string[];
|
|
39
|
+
commit_sha?: string;
|
|
40
|
+
branch?: string;
|
|
41
|
+
approved: boolean;
|
|
42
|
+
approved_by?: string;
|
|
43
|
+
approved_at?: string;
|
|
44
|
+
notes?: string;
|
|
45
|
+
}
|
|
46
|
+
export interface BaselineChangeLog {
|
|
47
|
+
version: 1;
|
|
48
|
+
entries: BaselineChangeEntry[];
|
|
49
|
+
}
|
|
50
|
+
export declare function loadChangeLog(cwd: string): BaselineChangeLog;
|
|
51
|
+
export declare function saveChangeLog(cwd: string, log: BaselineChangeLog): void;
|
|
52
|
+
export declare function recordBaselineChange(cwd: string, entry: Omit<BaselineChangeEntry, "timestamp">): BaselineChangeEntry;
|
|
53
|
+
/**
|
|
54
|
+
* Mark the most recent unapproved change as approved.
|
|
55
|
+
* Returns the approved entry or null if nothing to approve.
|
|
56
|
+
*/
|
|
57
|
+
export declare function approveLatest(cwd: string, approver?: string): BaselineChangeEntry | null;
|
|
58
|
+
/**
|
|
59
|
+
* List pending (unapproved) baseline changes.
|
|
60
|
+
*/
|
|
61
|
+
export declare function listPending(cwd: string): BaselineChangeEntry[];
|
|
62
|
+
//# sourceMappingURL=baseline_governance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseline_governance.d.ts","sourceRoot":"","sources":["../../src/evidence/baseline_governance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAaH,MAAM,WAAW,UAAU;IACzB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,UAAU,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,UAAU,EAAE,CAAC;CACrB;AAID,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CASjD;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CAI/D;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,EAAE,CAKjF;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,UAAU,EAAE,GACpB,IAAI,CAiBN;AAID,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,CAAC,CAAC;IACX,OAAO,EAAE,mBAAmB,EAAE,CAAC;CAChC;AAID,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB,CAS5D;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,iBAAiB,GAAG,IAAI,CAIvE;AAED,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,IAAI,CAAC,mBAAmB,EAAE,WAAW,CAAC,GAC5C,mBAAmB,CASrB;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,MAAM,EACX,QAAQ,GAAE,MAAc,GACvB,mBAAmB,GAAG,IAAI,CAW5B;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,mBAAmB,EAAE,CAG9D"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Baseline governance — region masks, change logs, and approval tracking.
|
|
3
|
+
*
|
|
4
|
+
* Region masks let you exclude dynamic UI regions (timestamps, avatars,
|
|
5
|
+
* ads) from visual comparison by zeroing them out in both baseline and
|
|
6
|
+
* actual screenshots before pixelmatch runs.
|
|
7
|
+
*
|
|
8
|
+
* Change logs record every baseline update with the commit, timestamp,
|
|
9
|
+
* approval status, and which screens changed — enabling audit trails.
|
|
10
|
+
*/
|
|
11
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync, } from "fs";
|
|
12
|
+
import { join } from "path";
|
|
13
|
+
const MASK_FILE = ".codeloop/baseline_masks.json";
|
|
14
|
+
export function loadMasks(cwd) {
|
|
15
|
+
const p = join(cwd, MASK_FILE);
|
|
16
|
+
if (!existsSync(p))
|
|
17
|
+
return { masks: [] };
|
|
18
|
+
try {
|
|
19
|
+
const raw = JSON.parse(readFileSync(p, "utf-8"));
|
|
20
|
+
return Array.isArray(raw.masks) ? raw : { masks: [] };
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return { masks: [] };
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export function saveMasks(cwd, config) {
|
|
27
|
+
const p = join(cwd, MASK_FILE);
|
|
28
|
+
mkdirSync(join(cwd, ".codeloop"), { recursive: true });
|
|
29
|
+
writeFileSync(p, JSON.stringify(config, null, 2));
|
|
30
|
+
}
|
|
31
|
+
export function getMaskForScreen(config, screen) {
|
|
32
|
+
const entry = config.masks.find((m) => m.screen === screen || m.screen === screen.replace(/\.png$/i, ""));
|
|
33
|
+
return entry?.regions ?? [];
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Zero out masked regions in an RGBA buffer. Modifies the buffer in-place.
|
|
37
|
+
* Used to neutralize dynamic regions before pixelmatch comparison.
|
|
38
|
+
*
|
|
39
|
+
* Coordinates are clamped to [0, width) x [0, height); negative origins and
|
|
40
|
+
* regions extending past the image bounds are silently truncated rather
|
|
41
|
+
* than corrupting buffer memory.
|
|
42
|
+
*/
|
|
43
|
+
export function applyMaskToBuffer(data, width, height, regions) {
|
|
44
|
+
for (const r of regions) {
|
|
45
|
+
const minX = Math.max(0, Math.trunc(r.x));
|
|
46
|
+
const minY = Math.max(0, Math.trunc(r.y));
|
|
47
|
+
const maxX = Math.min(Math.trunc(r.x + r.width), width);
|
|
48
|
+
const maxY = Math.min(Math.trunc(r.y + r.height), height);
|
|
49
|
+
if (maxX <= minX || maxY <= minY)
|
|
50
|
+
continue;
|
|
51
|
+
for (let y = minY; y < maxY; y++) {
|
|
52
|
+
for (let x = minX; x < maxX; x++) {
|
|
53
|
+
const i = (y * width + x) * 4;
|
|
54
|
+
data[i] = 0;
|
|
55
|
+
data[i + 1] = 0;
|
|
56
|
+
data[i + 2] = 0;
|
|
57
|
+
data[i + 3] = 0;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const CHANGELOG_FILE = ".codeloop/baseline_changelog.json";
|
|
63
|
+
export function loadChangeLog(cwd) {
|
|
64
|
+
const p = join(cwd, CHANGELOG_FILE);
|
|
65
|
+
if (!existsSync(p))
|
|
66
|
+
return { version: 1, entries: [] };
|
|
67
|
+
try {
|
|
68
|
+
const raw = JSON.parse(readFileSync(p, "utf-8"));
|
|
69
|
+
return Array.isArray(raw.entries) ? raw : { version: 1, entries: [] };
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return { version: 1, entries: [] };
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
export function saveChangeLog(cwd, log) {
|
|
76
|
+
const p = join(cwd, CHANGELOG_FILE);
|
|
77
|
+
mkdirSync(join(cwd, ".codeloop"), { recursive: true });
|
|
78
|
+
writeFileSync(p, JSON.stringify(log, null, 2));
|
|
79
|
+
}
|
|
80
|
+
export function recordBaselineChange(cwd, entry) {
|
|
81
|
+
const log = loadChangeLog(cwd);
|
|
82
|
+
const full = {
|
|
83
|
+
...entry,
|
|
84
|
+
timestamp: new Date().toISOString(),
|
|
85
|
+
};
|
|
86
|
+
log.entries.push(full);
|
|
87
|
+
saveChangeLog(cwd, log);
|
|
88
|
+
return full;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Mark the most recent unapproved change as approved.
|
|
92
|
+
* Returns the approved entry or null if nothing to approve.
|
|
93
|
+
*/
|
|
94
|
+
export function approveLatest(cwd, approver = "cli") {
|
|
95
|
+
const log = loadChangeLog(cwd);
|
|
96
|
+
const unapproved = log.entries.filter((e) => !e.approved);
|
|
97
|
+
if (unapproved.length === 0)
|
|
98
|
+
return null;
|
|
99
|
+
const target = unapproved[unapproved.length - 1];
|
|
100
|
+
target.approved = true;
|
|
101
|
+
target.approved_by = approver;
|
|
102
|
+
target.approved_at = new Date().toISOString();
|
|
103
|
+
saveChangeLog(cwd, log);
|
|
104
|
+
return target;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* List pending (unapproved) baseline changes.
|
|
108
|
+
*/
|
|
109
|
+
export function listPending(cwd) {
|
|
110
|
+
const log = loadChangeLog(cwd);
|
|
111
|
+
return log.entries.filter((e) => !e.approved);
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=baseline_governance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseline_governance.js","sourceRoot":"","sources":["../../src/evidence/baseline_governance.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run lineage — enriches every run with ancestry and Git context so that
|
|
3
|
+
* artifacts can be traced back to the commit, branch, and section that
|
|
4
|
+
* produced them.
|
|
5
|
+
*
|
|
6
|
+
* Also maintains `run_index.json` at the artifacts root for fast lookups
|
|
7
|
+
* without scanning every `meta.json` file.
|
|
8
|
+
*/
|
|
9
|
+
export interface LineageFields {
|
|
10
|
+
parent_run_id?: string;
|
|
11
|
+
section_id?: string;
|
|
12
|
+
commit_sha?: string;
|
|
13
|
+
branch?: string;
|
|
14
|
+
trigger: "manual" | "verify" | "gate_check" | "integration_check" | "replan";
|
|
15
|
+
run_index: number;
|
|
16
|
+
}
|
|
17
|
+
export interface RunIndexEntry {
|
|
18
|
+
run_id: string;
|
|
19
|
+
started_at: string;
|
|
20
|
+
finished_at?: string;
|
|
21
|
+
trigger: string;
|
|
22
|
+
section_id?: string;
|
|
23
|
+
parent_run_id?: string;
|
|
24
|
+
commit_sha?: string;
|
|
25
|
+
branch?: string;
|
|
26
|
+
confidence?: number;
|
|
27
|
+
pass_count?: number;
|
|
28
|
+
fail_count?: number;
|
|
29
|
+
platform?: string;
|
|
30
|
+
}
|
|
31
|
+
export interface RunIndex {
|
|
32
|
+
version: 1;
|
|
33
|
+
entries: RunIndexEntry[];
|
|
34
|
+
updated_at: string;
|
|
35
|
+
}
|
|
36
|
+
export declare function captureGitContext(cwd: string): {
|
|
37
|
+
commit_sha?: string;
|
|
38
|
+
branch?: string;
|
|
39
|
+
};
|
|
40
|
+
export declare function loadRunIndex(artifactsBase: string): RunIndex;
|
|
41
|
+
export declare function saveRunIndex(artifactsBase: string, index: RunIndex): void;
|
|
42
|
+
export declare function appendToIndex(artifactsBase: string, entry: RunIndexEntry): RunIndex;
|
|
43
|
+
export declare function buildLineage(artifactsBase: string, opts: {
|
|
44
|
+
trigger: LineageFields["trigger"];
|
|
45
|
+
section_id?: string;
|
|
46
|
+
parent_run_id?: string;
|
|
47
|
+
cwd?: string;
|
|
48
|
+
}): LineageFields;
|
|
49
|
+
/**
|
|
50
|
+
* Rebuild `run_index.json` by scanning every `meta.json` in the artifacts base.
|
|
51
|
+
* Useful for migrating existing runs that pre-date the lineage feature.
|
|
52
|
+
*/
|
|
53
|
+
export declare function rebuildIndex(artifactsBase: string): RunIndex;
|
|
54
|
+
export interface RunHistoryQuery {
|
|
55
|
+
section_id?: string;
|
|
56
|
+
branch?: string;
|
|
57
|
+
limit?: number;
|
|
58
|
+
since?: string;
|
|
59
|
+
}
|
|
60
|
+
export interface RunHistoryResult {
|
|
61
|
+
total: number;
|
|
62
|
+
returned: number;
|
|
63
|
+
entries: RunIndexEntry[];
|
|
64
|
+
}
|
|
65
|
+
export declare function queryRunHistory(artifactsBase: string, query?: RunHistoryQuery): RunHistoryResult;
|
|
66
|
+
//# sourceMappingURL=run_lineage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run_lineage.d.ts","sourceRoot":"","sources":["../../src/evidence/run_lineage.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,MAAM,WAAW,aAAa;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,QAAQ,GAAG,QAAQ,GAAG,YAAY,GAAG,mBAAmB,GAAG,QAAQ,CAAC;IAC7E,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,CAAC,CAAC;IACX,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;CACpB;AAYD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAKvF;AAED,wBAAgB,YAAY,CAAC,aAAa,EAAE,MAAM,GAAG,QAAQ,CAc5D;AAED,wBAAgB,YAAY,CAAC,aAAa,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,IAAI,CAIzE;AAED,wBAAgB,aAAa,CAC3B,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,aAAa,GACnB,QAAQ,CAUV;AAED,wBAAgB,YAAY,CAC1B,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE;IACJ,OAAO,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GACA,aAAa,CAWf;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,aAAa,EAAE,MAAM,GAAG,QAAQ,CAmC5D;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,aAAa,EAAE,CAAC;CAC1B;AAED,wBAAgB,eAAe,CAC7B,aAAa,EAAE,MAAM,EACrB,KAAK,GAAE,eAAoB,GAC1B,gBAAgB,CA6BlB"}
|