@xulthekl/team-flow 0.31.0 → 0.32.1

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.
Files changed (88) hide show
  1. package/.claude/always/phase-guard.md +1 -1
  2. package/.claude-plugin/marketplace.json +3 -3
  3. package/.claude-plugin/plugin.json +1 -1
  4. package/.codex-plugin/plugin.json +2 -2
  5. package/.cursor-plugin/marketplace.json +2 -2
  6. package/.cursor-plugin/plugin.json +2 -2
  7. package/.github/plugin/marketplace.json +2 -2
  8. package/AGENTS.md +3 -3
  9. package/CHANGELOG.md +47 -0
  10. package/GEMINI.md +1 -1
  11. package/HANDOFF.md +1 -1
  12. package/INSTALL.md +1 -1
  13. package/README.md +2 -2
  14. package/agents/contract-builder.md +6 -1
  15. package/docs/README_en.md +1 -1
  16. package/docs/solutions/INDEX.md +2 -0
  17. package/docs/solutions/cross-phase/2026-08-01-no-summary.md +17 -0
  18. package/docs/solutions/cross-phase/2026-08-03-no-summary.md +17 -0
  19. package/gemini-extension.json +2 -2
  20. package/hooks/session-start +2 -2
  21. package/llms.txt +1 -1
  22. package/package.json +6 -2
  23. package/plugin.json +1 -1
  24. package/scripts/guard/checks/test-gate-exemptions.mjs +53 -0
  25. package/scripts/guard/checks/test-matrix-complete.mjs +54 -30
  26. package/scripts/guard/checks/test-matrix-ready.mjs +60 -0
  27. package/scripts/guard/checks/tests-passing.mjs +112 -24
  28. package/scripts/guard/guard.mjs +5 -1
  29. package/scripts/lib/cmd-doctor.mjs +43 -1
  30. package/scripts/lib/cmd-execution.mjs +24 -1
  31. package/scripts/lib/cmd-state.mjs +28 -5
  32. package/scripts/lib/cmd-validate.mjs +42 -0
  33. package/scripts/lib/execution-plan.mjs +23 -0
  34. package/scripts/lib/state-loader.mjs +16 -2
  35. package/scripts/lib/test-record.mjs +212 -0
  36. package/scripts/team-flow.mjs +3 -0
  37. package/skills/contract-builder/SKILL.md +9 -10
  38. package/skills/release-archivist/SKILL.md +16 -9
  39. package/skills/session-handoff/SKILL.md +1 -0
  40. package/skills/workflow-start/SKILL.md +5 -3
  41. package/skills/workflow-start/references/routing-rules.md +10 -6
  42. package/tests/e2e.test.mjs +0 -266
  43. package/tests/lib/cmd-audit.test.mjs +0 -202
  44. package/tests/lib/cmd-checkpoint.test.mjs +0 -98
  45. package/tests/lib/cmd-config.test.mjs +0 -101
  46. package/tests/lib/cmd-doctor.test.mjs +0 -450
  47. package/tests/lib/cmd-execution.test.mjs +0 -647
  48. package/tests/lib/cmd-handoff.test.mjs +0 -137
  49. package/tests/lib/cmd-inject.test.mjs +0 -218
  50. package/tests/lib/cmd-install-workbuddy.test.mjs +0 -113
  51. package/tests/lib/cmd-install-zcode.test.mjs +0 -42
  52. package/tests/lib/cmd-isolate.test.mjs +0 -68
  53. package/tests/lib/cmd-list.test.mjs +0 -127
  54. package/tests/lib/cmd-runtime.test.mjs +0 -83
  55. package/tests/lib/cmd-state-missing.test.mjs +0 -65
  56. package/tests/lib/cmd-state.test.mjs +0 -365
  57. package/tests/lib/cmd-sync-paths.test.mjs +0 -84
  58. package/tests/lib/cmd-validate-paths.test.mjs +0 -90
  59. package/tests/lib/config-loader.test.mjs +0 -175
  60. package/tests/lib/ensure-branch.test.mjs +0 -110
  61. package/tests/lib/execution-control-plane.test.mjs +0 -168
  62. package/tests/lib/execution-plan.test.mjs +0 -474
  63. package/tests/lib/guard-compound-captured.test.mjs +0 -92
  64. package/tests/lib/guard-specs-merged.test.mjs +0 -110
  65. package/tests/lib/guard-tests-passing.test.mjs +0 -114
  66. package/tests/lib/guard-transitions.test.mjs +0 -262
  67. package/tests/lib/guard.test.mjs +0 -613
  68. package/tests/lib/hash.test.mjs +0 -138
  69. package/tests/lib/infer-workflow.test.mjs +0 -161
  70. package/tests/lib/install-git-hooks.test.mjs +0 -20
  71. package/tests/lib/marketplace-release-docs.test.mjs +0 -31
  72. package/tests/lib/minimality-discipline.test.mjs +0 -37
  73. package/tests/lib/model-profiles-docs.test.mjs +0 -33
  74. package/tests/lib/node20-compatibility.test.mjs +0 -73
  75. package/tests/lib/node20-test-entry.test.mjs +0 -17
  76. package/tests/lib/platform-runtime-distribution.test.mjs +0 -157
  77. package/tests/lib/raw-mode-smoke.test.mjs +0 -42
  78. package/tests/lib/sdd-overlay.test.mjs +0 -118
  79. package/tests/lib/solutions-capture.test.mjs +0 -108
  80. package/tests/lib/solutions-index-gen.test.mjs +0 -147
  81. package/tests/lib/solutions-inject.test.mjs +0 -115
  82. package/tests/lib/solutions-promote.test.mjs +0 -200
  83. package/tests/lib/spec-paths.test.mjs +0 -80
  84. package/tests/lib/state-loader.test.mjs +0 -251
  85. package/tests/lib/token-baseline.test.mjs +0 -72
  86. package/tests/lib/token-rules.test.mjs +0 -94
  87. package/tests/lib/verify-marketplace-release.test.mjs +0 -128
  88. package/tests/tsconfig.json +0 -12
@@ -1,72 +0,0 @@
1
- // tests/lib/token-baseline.test.mjs
2
- // Tests for scripts/token-baseline.mjs — measurement and comparison
3
-
4
- import { describe, it } from 'node:test';
5
- import assert from 'node:assert/strict';
6
- import { execSync } from 'node:child_process';
7
- import { writeFileSync, unlinkSync, readFileSync } from 'node:fs';
8
- import { join } from 'node:path';
9
- import { tmpdir } from 'node:os';
10
-
11
- const BASELINE_PATH = join(process.cwd(), 'scripts/token-baseline.mjs');
12
- const TMP = tmpdir();
13
-
14
- describe('token-baseline: measurement', () => {
15
- it('outputs valid JSON with components and totals', () => {
16
- const out = execSync(`node "${BASELINE_PATH}" --files hooks/session-start`, { encoding: 'utf-8' });
17
- const data = JSON.parse(out);
18
- assert.ok(Array.isArray(data.components), 'components should be an array');
19
- assert.ok(data.components.length > 0, 'should have at least one component');
20
- const c = data.components[0];
21
- assert.ok(typeof c.lines === 'number' && c.lines > 0, 'lines should be positive');
22
- assert.ok(typeof c.chars === 'number' && c.chars > 0, 'chars should be positive');
23
- assert.ok(typeof c.estimatedTokens === 'number' && c.estimatedTokens > 0, 'estimatedTokens should be positive');
24
- assert.ok(typeof data.totals === 'object', 'totals should be an object');
25
- assert.ok(data.totals.estimatedTokens > 0, 'total estimatedTokens should be positive');
26
- });
27
-
28
- it('--files filter limits output', () => {
29
- const out = execSync(`node "${BASELINE_PATH}" --files hooks/session-start`, { encoding: 'utf-8' });
30
- const data = JSON.parse(out);
31
- assert.equal(data.components.length, 1, 'should only have one component');
32
- assert.ok(data.components[0].path.includes('hooks/session-start'), 'should be the filtered file');
33
- });
34
-
35
- it('--output writes to file', () => {
36
- const outPath = join(TMP, 'token-baseline-test.json');
37
- execSync(`node "${BASELINE_PATH}" --files hooks/session-start --output "${outPath}"`, { encoding: 'utf-8' });
38
- const data = JSON.parse(readFileSync(outPath, 'utf-8'));
39
- assert.ok(data.totals.estimatedTokens > 0, 'file should contain valid data');
40
- unlinkSync(outPath);
41
- });
42
- });
43
-
44
- describe('token-baseline: comparison', () => {
45
- it('--compare produces change deltas', () => {
46
- const baselinePath = join(TMP, 'baseline-cmp-test.json');
47
- // Create a baseline with slightly different values
48
- const baseline = {
49
- timestamp: '2026-01-01T00:00:00Z',
50
- components: [
51
- { path: 'hooks/session-start', label: 'hooks/session-start', lines: 30, chars: 2000, estimatedTokens: 500 },
52
- ],
53
- totals: { lines: 30, chars: 2000, estimatedTokens: 500 },
54
- };
55
- writeFileSync(baselinePath, JSON.stringify(baseline));
56
-
57
- const out = execSync(`node "${BASELINE_PATH}" --files hooks/session-start --compare "${baselinePath}"`, { encoding: 'utf-8' });
58
- const data = JSON.parse(out);
59
- assert.ok(Array.isArray(data.changes), 'should have changes array');
60
- assert.ok(data.changes.length > 0, 'should have at least one change');
61
- assert.ok(typeof data.summary.totalDelta === 'number', 'should have totalDelta');
62
- assert.ok(typeof data.summary.totalPct === 'string', 'should have totalPct');
63
-
64
- unlinkSync(baselinePath);
65
- });
66
-
67
- it('missing file in baseline reports error', () => {
68
- const out = execSync(`node "${BASELINE_PATH}" --files hooks/session-start --compare /nonexistent/baseline.json 2>&1 || true`, { encoding: 'utf-8' });
69
- // Should fail gracefully — error message from file not found
70
- assert.ok(out.length > 0, 'should produce output even on error');
71
- });
72
- });
@@ -1,94 +0,0 @@
1
- // tests/lib/token-rules.test.mjs
2
- // Tests for scripts/lint/rules/token-rules.mjs — lint rule functions
3
-
4
- import { describe, it } from 'node:test';
5
- import assert from 'node:assert/strict';
6
- import { checkMaxLines, checkMaxChars, checkMaxEmphasisMarkers, checkMaxCodeBlockLength } from '../../scripts/lint/rules/token-rules.mjs';
7
-
8
- const CTX = { skillDirs: ['test-skill'], skillsDir: '/fake/skills' };
9
-
10
- describe('token-rules: checkMaxLines', () => {
11
- it('passes when under limit', async () => {
12
- const issues = await checkMaxLines('test', 'line1\nline2\nline3', CTX, 10);
13
- assert.equal(issues.length, 0);
14
- });
15
-
16
- it('fails when over limit', async () => {
17
- const content = Array(251).fill('line').join('\n');
18
- const issues = await checkMaxLines('test', content, CTX, 250);
19
- assert.equal(issues.length, 1);
20
- assert.equal(issues[0].severity, 'error');
21
- assert.ok(issues[0].message.includes('251'));
22
- });
23
- });
24
-
25
- describe('token-rules: checkMaxChars', () => {
26
- it('passes when under limit', async () => {
27
- const issues = await checkMaxChars('test', 'short', CTX, 100);
28
- assert.equal(issues.length, 0);
29
- });
30
-
31
- it('warns when over limit', async () => {
32
- const content = 'x'.repeat(10001);
33
- const issues = await checkMaxChars('test', content, CTX, 10000);
34
- assert.equal(issues.length, 1);
35
- assert.equal(issues[0].severity, 'warning');
36
- });
37
- });
38
-
39
- describe('token-rules: checkMaxEmphasisMarkers', () => {
40
- it('passes for content without banned markers', async () => {
41
- const issues = await checkMaxEmphasisMarkers('test', 'normal text with **some** emphasis', CTX, 30);
42
- assert.equal(issues.length, 0);
43
- });
44
-
45
- it('detects EXTREMELY_IMPORTANT', async () => {
46
- const issues = await checkMaxEmphasisMarkers('test', 'This is EXTREMELY_IMPORTANT content', CTX, 30);
47
- const eiIssue = issues.find(i => i.message.includes('EXTREMELY_IMPORTANT'));
48
- assert.ok(eiIssue, 'should flag EXTREMELY_IMPORTANT');
49
- assert.equal(eiIssue.severity, 'error');
50
- });
51
-
52
- it('detects CRITICAL', async () => {
53
- const issues = await checkMaxEmphasisMarkers('test', 'CRITICAL: do not skip', CTX, 30);
54
- const crIssue = issues.find(i => i.message.includes('CRITICAL'));
55
- assert.ok(crIssue, 'should flag CRITICAL');
56
- assert.equal(crIssue.severity, 'error');
57
- });
58
-
59
- it('warns on too many IMPORTANT occurrences', async () => {
60
- const content = 'IMPORTANT\n'.repeat(5) + 'text';
61
- const issues = await checkMaxEmphasisMarkers('test', content, CTX, 30);
62
- const impIssue = issues.find(i => i.message.includes('IMPORTANT'));
63
- assert.ok(impIssue, 'should flag excessive IMPORTANT');
64
- });
65
-
66
- it('warns on too many emphasis markers', async () => {
67
- const content = '**a** **b** '.repeat(31);
68
- const issues = await checkMaxEmphasisMarkers('test', content, CTX, 30);
69
- const empIssue = issues.find(i => i.message.includes('emphasis markers'));
70
- assert.ok(empIssue, 'should flag excessive emphasis');
71
- assert.equal(empIssue.severity, 'warning');
72
- });
73
- });
74
-
75
- describe('token-rules: checkMaxCodeBlockLength', () => {
76
- it('passes for short code blocks', async () => {
77
- const issues = await checkMaxCodeBlockLength('test', '```\nline1\nline2\n```', CTX, 5);
78
- assert.equal(issues.length, 0);
79
- });
80
-
81
- it('warns for long code blocks', async () => {
82
- const lines = Array(17).fill('code').join('\n');
83
- const content = '```\n' + lines + '\n```';
84
- const issues = await checkMaxCodeBlockLength('test', content, CTX, 15);
85
- assert.equal(issues.length, 1);
86
- assert.equal(issues[0].severity, 'warning');
87
- assert.ok(issues[0].message.includes('19'), `expected message to include '19', got: ${issues[0].message}`);
88
- });
89
-
90
- it('handles content with no code blocks', async () => {
91
- const issues = await checkMaxCodeBlockLength('test', 'just text, no code', CTX, 15);
92
- assert.equal(issues.length, 0);
93
- });
94
- });
@@ -1,128 +0,0 @@
1
- import { describe, it } from 'node:test';
2
- import assert from 'node:assert/strict';
3
- import { spawnSync } from 'node:child_process';
4
- import {
5
- main,
6
- parseReleaseCheckArgs,
7
- verifyMarketplaceRelease,
8
- } from '../../scripts/verify-marketplace-release.mjs';
9
-
10
- const response = ({ ok = true, status = 200, body = { version: '0.9.0' } } = {}) => ({
11
- ok,
12
- status,
13
- async json() { return body; },
14
- });
15
-
16
- describe('verify marketplace release', () => {
17
- it('accepts a matching HTTPS manifest version', async () => {
18
- const result = await verifyMarketplaceRelease({
19
- manifestUrl: 'https://example.test/plugin.json',
20
- expectedVersion: '0.9.0',
21
- fetchImpl: async () => response(),
22
- });
23
- assert.equal(result.actualVersion, '0.9.0');
24
- });
25
-
26
- it('rejects HTTP, malformed, network, and version-drift responses', async () => {
27
- await assert.rejects(
28
- () => verifyMarketplaceRelease({
29
- manifestUrl: 'https://example.test/plugin.json',
30
- expectedVersion: '0.9.0',
31
- fetchImpl: async () => response({ ok: false, status: 404 }),
32
- }),
33
- /HTTP 404/,
34
- );
35
- await assert.rejects(
36
- () => verifyMarketplaceRelease({
37
- manifestUrl: 'https://example.test/plugin.json',
38
- expectedVersion: '0.9.0',
39
- fetchImpl: async () => response({ body: { name: 'team-flow' } }),
40
- }),
41
- /missing a string version/,
42
- );
43
- await assert.rejects(
44
- () => verifyMarketplaceRelease({
45
- manifestUrl: 'https://example.test/plugin.json',
46
- expectedVersion: '0.9.0',
47
- fetchImpl: async () => ({
48
- ok: true,
49
- status: 200,
50
- async json() { throw new Error('unexpected token'); },
51
- }),
52
- }),
53
- /marketplace manifest is not valid JSON: unexpected token/,
54
- );
55
- await assert.rejects(
56
- () => verifyMarketplaceRelease({
57
- manifestUrl: 'https://example.test/plugin.json',
58
- expectedVersion: '0.9.0',
59
- fetchImpl: async () => { throw new Error('socket closed'); },
60
- }),
61
- /network request failed: socket closed/,
62
- );
63
- await assert.rejects(
64
- () => verifyMarketplaceRelease({
65
- manifestUrl: 'https://example.test/plugin.json',
66
- expectedVersion: '0.9.0',
67
- fetchImpl: async () => response({ body: { version: '0.8.17' } }),
68
- }),
69
- /expected 0.9.0, found 0.8.17/,
70
- );
71
- });
72
-
73
- it('requires one HTTPS URL and one complete semver argument', () => {
74
- assert.throws(() => parseReleaseCheckArgs([]), /Usage:/);
75
- assert.throws(
76
- () => parseReleaseCheckArgs([
77
- '--manifest-url', 'http://example.test/plugin.json',
78
- '--expected-version', '0.9.0',
79
- ]),
80
- /HTTPS/,
81
- );
82
- assert.throws(
83
- () => parseReleaseCheckArgs([
84
- '--manifest-url', 'https://example.test/plugin.json',
85
- '--expected-version', '0.9',
86
- ]),
87
- /x\.y\.z/,
88
- );
89
- });
90
-
91
- it('writes exact success and error messages through injected streams', async () => {
92
- const stdout = [];
93
- const stderr = [];
94
- const args = [
95
- '--manifest-url', 'https://example.test/plugin.json',
96
- '--expected-version', '0.9.0',
97
- ];
98
- const streams = {
99
- stdout: { write: (message) => stdout.push(message) },
100
- stderr: { write: (message) => stderr.push(message) },
101
- };
102
-
103
- assert.equal(await main(args, {
104
- ...streams,
105
- fetchImpl: async () => response(),
106
- }), 0);
107
- assert.deepEqual(stdout, ['Marketplace manifest verified: 0.9.0 (https://example.test/plugin.json)\n']);
108
- assert.deepEqual(stderr, []);
109
-
110
- assert.equal(await main(args, {
111
- ...streams,
112
- fetchImpl: async () => response({ body: { version: '0.8.17' } }),
113
- }), 1);
114
- assert.deepEqual(stderr, ['Error: marketplace version mismatch: expected 0.9.0, found 0.8.17\n']);
115
- });
116
-
117
- it('does not set process.exitCode when imported', () => {
118
- const scriptUrl = new URL('../../scripts/verify-marketplace-release.mjs', import.meta.url).href;
119
- const result = spawnSync(process.execPath, [
120
- '--input-type=module',
121
- '--eval',
122
- `await import(${JSON.stringify(scriptUrl)}); if (process.exitCode !== undefined) throw new Error('process.exitCode was set');`,
123
- ], { encoding: 'utf8' });
124
-
125
- assert.equal(result.status, 0, result.stderr);
126
- assert.equal(result.stderr, '');
127
- });
128
- });
@@ -1,12 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "NodeNext",
5
- "moduleResolution": "NodeNext",
6
- "strict": true,
7
- "esModuleInterop": true,
8
- "skipLibCheck": true,
9
- "noEmit": true
10
- },
11
- "include": ["./**/*.ts", "../src/**/*.ts"]
12
- }