Mechanical rename produced by scripts/msd-rename.cjs: gsd/Gsd/GSD -> msd/Msd/MSD across contents and paths, upstream package/repo coordinates -> @golem15/msd-core and golem15com/msd-core. Deep links into upstream history, sibling upstream packages, the GSD-2 import feature, CHANGELOG.md and .changeset/ are kept as-is. Hand edits on top: MSD block-letter banner and logos, LICENSE copyright line, package/plugin identity, regenerated lockfile, install-tree fixtures, derived registries and benchmark baseline; migration checksum baseline re-locked (MSD keeps its own install state, so no install had applied the old sums); sort-order and regex-escaped expectations in tests adjusted.
91 lines
4.0 KiB
JavaScript
91 lines
4.0 KiB
JavaScript
'use strict';
|
|
|
|
/**
|
|
* SDK CLI integration tests for `msd-tools validate context`.
|
|
*
|
|
* The pure classifier's behavior is covered by
|
|
* tests/context-utilization.test.cjs — these tests focus on what the CLI
|
|
* adds on top: argument parsing, JSON vs human-readable rendering,
|
|
* recommendation-string formatting, and exit-code semantics.
|
|
*/
|
|
|
|
const { describe, test } = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const { runMsdTools } = require('./helpers.cjs');
|
|
|
|
describe('msd-tools validate context — CLI argument errors', () => {
|
|
test('missing --tokens-used fails with named flag in stderr', () => {
|
|
const r = runMsdTools(['validate', 'context', '--context-window', '200000']);
|
|
assert.strictEqual(r.success, false);
|
|
assert.match(r.error, /tokens-used/i);
|
|
});
|
|
|
|
test('missing --context-window fails with named flag in stderr', () => {
|
|
const r = runMsdTools(['validate', 'context', '--tokens-used', '100000']);
|
|
assert.strictEqual(r.success, false);
|
|
assert.match(r.error, /context-window/i);
|
|
});
|
|
|
|
test('non-numeric --tokens-used reports the offending flag', () => {
|
|
const r = runMsdTools(['validate', 'context', '--tokens-used', 'abc', '--context-window', '200000']);
|
|
assert.strictEqual(r.success, false);
|
|
assert.match(r.error, /tokens-used/i);
|
|
});
|
|
|
|
test('negative --tokens-used reports the offending flag', () => {
|
|
const r = runMsdTools(['validate', 'context', '--tokens-used', '-1', '--context-window', '200000']);
|
|
assert.strictEqual(r.success, false);
|
|
assert.match(r.error, /tokens-used/i);
|
|
});
|
|
});
|
|
|
|
describe('msd-tools validate context — JSON vs human rendering', () => {
|
|
test('--json emits the classifier result plus a recommendation field', () => {
|
|
// Single round-trip test confirms (a) classifier integration,
|
|
// (b) JSON serialization, and (c) recommendation lookup. Per-state
|
|
// classifier behavior is covered by context-utilization.test.cjs.
|
|
const r = runMsdTools(['validate', 'context', '--tokens-used', '50000', '--context-window', '200000', '--json']);
|
|
assert.strictEqual(r.success, true, `expected success, got: ${r.error}`);
|
|
const obj = JSON.parse(r.output);
|
|
assert.deepStrictEqual(Object.keys(obj).sort(), ['percent', 'recommendation', 'state']);
|
|
assert.strictEqual(obj.percent, 25);
|
|
assert.strictEqual(obj.state, 'healthy');
|
|
assert.strictEqual(obj.recommendation, null);
|
|
});
|
|
|
|
test('human mode (default) prints percent, state, and recommendation', () => {
|
|
const r = runMsdTools(['validate', 'context', '--tokens-used', '140000', '--context-window', '200000']);
|
|
assert.strictEqual(r.success, true);
|
|
assert.match(r.output, /70%/);
|
|
assert.match(r.output, /critical/);
|
|
assert.match(r.output, /\/msd-thread/);
|
|
});
|
|
|
|
test('human mode omits the recommendation line for healthy state', () => {
|
|
const r = runMsdTools(['validate', 'context', '--tokens-used', '40000', '--context-window', '200000']);
|
|
assert.strictEqual(r.success, true);
|
|
assert.match(r.output, /20%/);
|
|
assert.match(r.output, /healthy/);
|
|
assert.doesNotMatch(r.output, /\/msd-thread/, 'healthy output must not nag the user');
|
|
});
|
|
});
|
|
|
|
describe('msd-tools validate context — recommendation copy per state', () => {
|
|
// The CLI owns the recommendation strings (the classifier does not).
|
|
// These tests pin the wording so a regression to the prose is caught.
|
|
test('warning state recommends /msd-thread', () => {
|
|
const r = runMsdTools(['validate', 'context', '--tokens-used', '130000', '--context-window', '200000', '--json']);
|
|
const obj = JSON.parse(r.output);
|
|
assert.strictEqual(obj.state, 'warning');
|
|
assert.match(obj.recommendation, /\/msd-thread/);
|
|
});
|
|
|
|
test('critical state names the fracture-point reasoning risk', () => {
|
|
const r = runMsdTools(['validate', 'context', '--tokens-used', '160000', '--context-window', '200000', '--json']);
|
|
const obj = JSON.parse(r.output);
|
|
assert.strictEqual(obj.state, 'critical');
|
|
assert.match(obj.recommendation, /\/msd-thread/);
|
|
assert.match(obj.recommendation, /reasoning|degrade|fracture/i);
|
|
});
|
|
});
|