@productbrain/cli 0.1.0-beta.1440 → 0.1.0-beta.1463
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 +1 -0
- package/dist/commands/scoreboard.d.ts +28 -0
- package/dist/commands/scoreboard.d.ts.map +1 -0
- package/dist/commands/scoreboard.js +40 -0
- package/dist/commands/scoreboard.js.map +1 -0
- package/dist/formatters/scoreboard.d.ts +11 -0
- package/dist/formatters/scoreboard.d.ts.map +1 -0
- package/dist/formatters/scoreboard.js +48 -0
- package/dist/formatters/scoreboard.js.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/scoreboard/diagnose.d.ts +182 -0
- package/dist/scoreboard/diagnose.d.ts.map +1 -0
- package/dist/scoreboard/diagnose.js +250 -0
- package/dist/scoreboard/diagnose.js.map +1 -0
- package/dist/scoreboard/diagnose.test.d.ts +12 -0
- package/dist/scoreboard/diagnose.test.d.ts.map +1 -0
- package/dist/scoreboard/diagnose.test.js +192 -0
- package/dist/scoreboard/diagnose.test.js.map +1 -0
- package/dist/scoreboard/localDrift.d.ts +23 -0
- package/dist/scoreboard/localDrift.d.ts.map +1 -0
- package/dist/scoreboard/localDrift.js +111 -0
- package/dist/scoreboard/localDrift.js.map +1 -0
- package/dist/scoreboard/localDrift.test.d.ts +9 -0
- package/dist/scoreboard/localDrift.test.d.ts.map +1 -0
- package/dist/scoreboard/localDrift.test.js +82 -0
- package/dist/scoreboard/localDrift.test.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* M5 local-pull drift unit tests (A5, DEC-1284).
|
|
3
|
+
*
|
|
4
|
+
* Exercises computeLocalDrift over a real temp `.productbrain/` so the stat path is genuinely
|
|
5
|
+
* driven (not mocked): a config-bearing root (so findProjectRoot resolves) + a projection file
|
|
6
|
+
* whose mtime is the local pull. Asserts the lag/age math, the clamp, and the fail-soft branches.
|
|
7
|
+
*/
|
|
8
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
9
|
+
import { mkdtempSync, mkdirSync, writeFileSync, utimesSync, rmSync } from 'fs';
|
|
10
|
+
import { tmpdir } from 'os';
|
|
11
|
+
import { resolve } from 'path';
|
|
12
|
+
import { computeLocalDrift } from './localDrift.js';
|
|
13
|
+
let root;
|
|
14
|
+
function setMtime(path, ms) {
|
|
15
|
+
const secs = ms / 1000;
|
|
16
|
+
utimesSync(path, secs, secs);
|
|
17
|
+
}
|
|
18
|
+
beforeEach(() => {
|
|
19
|
+
root = mkdtempSync(resolve(tmpdir(), 'pb-m5-'));
|
|
20
|
+
const pb = resolve(root, '.productbrain');
|
|
21
|
+
mkdirSync(pb, { recursive: true });
|
|
22
|
+
// config.json makes this a CLI project root (findProjectRoot requires it).
|
|
23
|
+
writeFileSync(resolve(pb, 'config.json'), JSON.stringify({ siteUrl: 'https://example.test' }));
|
|
24
|
+
});
|
|
25
|
+
afterEach(() => {
|
|
26
|
+
rmSync(root, { recursive: true, force: true });
|
|
27
|
+
});
|
|
28
|
+
describe('computeLocalDrift', () => {
|
|
29
|
+
it('fails soft to unavailable when no projection files exist', () => {
|
|
30
|
+
const d = computeLocalDrift(5_000, 10_000, root);
|
|
31
|
+
expect(d.localProjectionMtime).toBeNull();
|
|
32
|
+
expect(d.localLagMs).toBeNull();
|
|
33
|
+
expect(d.localAgeMs).toBeNull();
|
|
34
|
+
expect(d.unavailableReason).toMatch(/projection files/);
|
|
35
|
+
});
|
|
36
|
+
it('computes lag (server − local) and age (now − local) from the newest projection mtime', () => {
|
|
37
|
+
const pb = resolve(root, '.productbrain');
|
|
38
|
+
const ctx = resolve(pb, 'context.md');
|
|
39
|
+
writeFileSync(ctx, '# context');
|
|
40
|
+
setMtime(ctx, 1_000);
|
|
41
|
+
// Also write a newer briefing — newest mtime should win.
|
|
42
|
+
const brief = resolve(pb, 'briefing.md');
|
|
43
|
+
writeFileSync(brief, '# briefing');
|
|
44
|
+
setMtime(brief, 3_000);
|
|
45
|
+
const d = computeLocalDrift(5_000 /* server */, 10_000 /* now */, root);
|
|
46
|
+
expect(d.localProjectionMtime).toBe(3_000);
|
|
47
|
+
expect(d.serverMaterializedAt).toBe(5_000);
|
|
48
|
+
expect(d.localLagMs).toBe(2_000); // 5000 − 3000
|
|
49
|
+
expect(d.localAgeMs).toBe(7_000); // 10000 − 3000
|
|
50
|
+
expect(d.unavailableReason).toBeUndefined();
|
|
51
|
+
});
|
|
52
|
+
it('clamps lag at 0 when the local pull is newer than the server materialization', () => {
|
|
53
|
+
const pb = resolve(root, '.productbrain');
|
|
54
|
+
const ctx = resolve(pb, 'context.md');
|
|
55
|
+
writeFileSync(ctx, '# context');
|
|
56
|
+
setMtime(ctx, 9_000);
|
|
57
|
+
const d = computeLocalDrift(5_000, 10_000, root);
|
|
58
|
+
expect(d.localLagMs).toBe(0); // max(0, 5000 − 9000)
|
|
59
|
+
expect(d.localAgeMs).toBe(1_000);
|
|
60
|
+
});
|
|
61
|
+
it('returns null lag when the server never materialized', () => {
|
|
62
|
+
const pb = resolve(root, '.productbrain');
|
|
63
|
+
const ctx = resolve(pb, 'context.md');
|
|
64
|
+
writeFileSync(ctx, '# context');
|
|
65
|
+
setMtime(ctx, 2_000);
|
|
66
|
+
const d = computeLocalDrift(null, 10_000, root);
|
|
67
|
+
expect(d.localLagMs).toBeNull();
|
|
68
|
+
expect(d.localAgeMs).toBe(8_000);
|
|
69
|
+
});
|
|
70
|
+
it('reports unavailable when no project root is found', () => {
|
|
71
|
+
const bare = mkdtempSync(resolve(tmpdir(), 'pb-noroot-'));
|
|
72
|
+
try {
|
|
73
|
+
const d = computeLocalDrift(5_000, 10_000, bare);
|
|
74
|
+
expect(d.localProjectionMtime).toBeNull();
|
|
75
|
+
expect(d.unavailableReason).toMatch(/project root|missing/i);
|
|
76
|
+
}
|
|
77
|
+
finally {
|
|
78
|
+
rmSync(bare, { recursive: true, force: true });
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
//# sourceMappingURL=localDrift.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"localDrift.test.js","sourceRoot":"","sources":["../../src/scoreboard/localDrift.test.ts"],"names":[],"mappings":"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"}
|