agentic-workflow-manager 8.1.0 → 8.1.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.
@@ -3,7 +3,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.R3_PREPUBLICATION_FIXTURE_PURPOSE = exports.R3_PREPUBLICATION_FIXTURE_RELATIVE_PATH = exports.SENSOR_DOC_PATH = exports.SENSOR_PACKS = exports.SENSOR_END_MARKER = exports.SENSOR_BEGIN_MARKER = void 0;
6
+ exports.R3_PUBLISHED_REGISTRY_COMMIT = exports.R3_PUBLISHED_REGISTRY_TAG = exports.R3_PREPUBLICATION_FIXTURE_PURPOSE = exports.R3_PREPUBLICATION_FIXTURE_RELATIVE_PATH = exports.SENSOR_DOC_PATH = exports.SENSOR_PACKS = exports.SENSOR_END_MARKER = exports.SENSOR_BEGIN_MARKER = void 0;
7
+ exports.extractPublishedSupportMetadata = extractPublishedSupportMetadata;
8
+ exports.verifyPublishedRegistryIdentity = verifyPublishedRegistryIdentity;
7
9
  exports.parseRegistrySensorPacks = parseRegistrySensorPacks;
8
10
  exports.renderSensorSupportMatrix = renderSensorSupportMatrix;
9
11
  exports.spliceSensorSupportMatrix = spliceSensorSupportMatrix;
@@ -15,6 +17,7 @@ exports.registryRootFromArgs = registryRootFromArgs;
15
17
  */
16
18
  const fs_1 = __importDefault(require("fs"));
17
19
  const path_1 = __importDefault(require("path"));
20
+ const child_process_1 = require("child_process");
18
21
  const contract_1 = require("../src/commands/sensors/compatibility/contract");
19
22
  exports.SENSOR_BEGIN_MARKER = '<!-- BEGIN GENERATED: sensor-pack-support -->';
20
23
  exports.SENSOR_END_MARKER = '<!-- END GENERATED: sensor-pack-support -->';
@@ -27,6 +30,66 @@ exports.R3_PREPUBLICATION_FIXTURE_RELATIVE_PATH = 'tests/fixtures/sensor-support
27
30
  * never an invented description of an unpublished registry release.
28
31
  */
29
32
  exports.R3_PREPUBLICATION_FIXTURE_PURPOSE = 'R3 pre-publication contract fixture';
33
+ exports.R3_PUBLISHED_REGISTRY_TAG = 'v2.0.0';
34
+ exports.R3_PUBLISHED_REGISTRY_COMMIT = 'c35c087a0801c0b4e69e0a4ac3eafef9ecdf37cd';
35
+ /**
36
+ * Extract the registry-owned certification matrix without copying or rewording it.
37
+ * `SUPPORT.md` is generated by the registry from its manifests and frozen tool pins;
38
+ * this consumer must preserve that published evidence rather than infer certification
39
+ * from a compatibility range.
40
+ */
41
+ function extractPublishedSupportMetadata(source) {
42
+ if (typeof source !== 'string' || source.length === 0) {
43
+ throw new Error('published sensor support metadata must be non-empty text');
44
+ }
45
+ const begin = '<!-- BEGIN GENERATED: sensor-pack-support -->';
46
+ const end = '<!-- END GENERATED: sensor-pack-support -->';
47
+ const starts = source.split(begin).length - 1;
48
+ const ends = source.split(end).length - 1;
49
+ if (starts !== 1 || ends !== 1) {
50
+ throw new Error('published sensor support metadata requires exactly one generated marker pair');
51
+ }
52
+ const start = source.indexOf(begin) + begin.length;
53
+ const finish = source.indexOf(end);
54
+ if (finish <= start)
55
+ throw new Error('published sensor support metadata has invalid marker order');
56
+ const metadata = source.slice(start, finish).trim();
57
+ if (!metadata.includes('| Pack | Sensor | Variant | Tool | Certified range | Supported OS | OS certification evidence | Status | Evidence |')) {
58
+ throw new Error('published sensor support metadata lacks the certification table');
59
+ }
60
+ if (!metadata.includes('Status: `certified` has a matching frozen tool pin;')) {
61
+ throw new Error('published sensor support metadata lacks certification status semantics');
62
+ }
63
+ return metadata;
64
+ }
65
+ function exactArgument(argv, flag) {
66
+ const index = argv.indexOf(flag);
67
+ if (index === -1 || argv[index + 1] === undefined || argv[index + 1].startsWith('--') || index !== argv.lastIndexOf(flag)) {
68
+ throw new Error(`sensor support matrix requires exactly one ${flag} <value>`);
69
+ }
70
+ return argv[index + 1];
71
+ }
72
+ /** Refuse a mutable sibling checkout: published evidence is valid only for this immutable release. */
73
+ function verifyPublishedRegistryIdentity(registryRoot, tag, commit) {
74
+ const root = registryPath(registryRoot);
75
+ if (tag !== exports.R3_PUBLISHED_REGISTRY_TAG || commit !== exports.R3_PUBLISHED_REGISTRY_COMMIT) {
76
+ throw new Error(`sensor support matrix requires published registry ${exports.R3_PUBLISHED_REGISTRY_TAG}@${exports.R3_PUBLISHED_REGISTRY_COMMIT}`);
77
+ }
78
+ const resolve = (revision) => {
79
+ try {
80
+ return (0, child_process_1.execFileSync)('git', ['-C', root, 'rev-parse', revision], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'] }).trim();
81
+ }
82
+ catch {
83
+ throw new Error(`published registry root must be a git checkout at ${exports.R3_PUBLISHED_REGISTRY_TAG}`);
84
+ }
85
+ };
86
+ const head = resolve('HEAD');
87
+ const taggedCommit = resolve(`${tag}^{commit}`);
88
+ if (head !== commit)
89
+ throw new Error(`published registry HEAD ${head} does not match expected commit ${commit}`);
90
+ if (taggedCommit !== commit)
91
+ throw new Error(`published registry tag ${tag} resolves to ${taggedCommit}, expected commit ${commit}`);
92
+ }
30
93
  function registryPath(value) {
31
94
  if (typeof value !== 'string' || value.trim().length === 0 || value.includes('\0')) {
32
95
  throw new Error('sensor support matrix requires a non-empty --registry-root');
@@ -58,24 +121,47 @@ function parseRegistrySensorPacks(registryRoot) {
58
121
  function variants(pack) {
59
122
  return Object.entries(pack.sensors).flatMap(([sensor, definition]) => definition.variants.map((variant) => `\`${sensor}/${variant.id}\`: ${variant.requirements.tool} ${variant.requirements.toolRange}; ${variant.requirements.runtime} ${variant.requirements.runtimeRange}; certified ${variant.certifiedRange}`)).join('<br>');
60
123
  }
124
+ function publishedSupportMetadata(registryRoot) {
125
+ const file = path_1.default.join(registryRoot, 'sensor-packs', 'SUPPORT.md');
126
+ if (!fs_1.default.existsSync(file))
127
+ return null;
128
+ const stat = fs_1.default.lstatSync(file);
129
+ if (!stat.isFile() || stat.isSymbolicLink())
130
+ throw new Error(`published sensor support metadata must be a regular file: ${file}`);
131
+ return extractPublishedSupportMetadata(fs_1.default.readFileSync(file, 'utf8'));
132
+ }
61
133
  /** Pure renderer used by freshness tests and the documentation command. */
62
134
  function renderSensorSupportMatrix(registryRoot) {
135
+ const root = registryPath(registryRoot);
136
+ const publishedMetadata = publishedSupportMetadata(root);
63
137
  const lines = [
64
- `### Sensor-pack compatibility contract (${exports.R3_PREPUBLICATION_FIXTURE_PURPOSE})`,
138
+ publishedMetadata === null
139
+ ? `### Sensor-pack compatibility contract (${exports.R3_PREPUBLICATION_FIXTURE_PURPOSE})`
140
+ : '### Sensor-pack compatibility contract (published registry evidence)',
65
141
  '',
66
142
  '| Pack | Contract | Version-aware variants and certified ranges | Evidence status |',
67
143
  '|---|---|---|---|',
68
144
  ];
69
- for (const { name, parsed } of parseRegistrySensorPacks(registryRoot)) {
145
+ for (const { name, parsed } of parseRegistrySensorPacks(root)) {
70
146
  if (parsed.kind === 'legacy') {
71
147
  lines.push(`| \`${name}\` | legacy pack | No v2 variants declared | compatible-unverified — migrate the pack before claiming version certification |`);
72
148
  }
73
149
  else {
74
- lines.push(`| \`${name}\` | pack schema v2 | ${variants(parsed.pack)} | Fixture-declared ranges only; real-tool and OS certification awaits published registry release evidence |`);
150
+ lines.push(`| \`${name}\` | pack schema v2 | ${variants(parsed.pack)} | ${publishedMetadata === null ? 'Fixture-declared ranges only; real-tool and OS certification awaits published registry release evidence' : 'Published compatibility contract; certification evidence is reproduced below from the registry'} |`);
75
151
  }
76
152
  }
77
153
  lines.push('');
78
- lines.push('> Generated from the pinned R3 pre-publication contract fixture, not the published `awm-baseline-registry` manifests. **Do not edit by hand** — `npm run docs:matrix` regenerates this block. T13 verifies the actual registry tag and release evidence.');
154
+ if (publishedMetadata === null) {
155
+ lines.push('> Generated from the pinned R3 pre-publication contract fixture, not the published `awm-baseline-registry` manifests. **Do not edit by hand** — `npm run docs:matrix:prepublication` regenerates this fixture-only block. T13 verifies the actual registry tag and release evidence.');
156
+ }
157
+ else {
158
+ lines.push('');
159
+ lines.push('#### Published certification evidence');
160
+ lines.push('');
161
+ lines.push(publishedMetadata);
162
+ lines.push('');
163
+ lines.push('> Generated from the supplied published `awm-baseline-registry` root. Certification states, frozen pins, and OS evidence are registry-owned metadata reproduced verbatim; **do not edit by hand**.');
164
+ }
79
165
  return lines.join('\n');
80
166
  }
81
167
  function spliceSensorSupportMatrix(markdown, generated) {
@@ -83,20 +169,32 @@ function spliceSensorSupportMatrix(markdown, generated) {
83
169
  const end = markdown.indexOf(exports.SENSOR_END_MARKER);
84
170
  if (begin === -1 || end === -1 || end < begin)
85
171
  throw new Error(`support-matrix.md lacks ${exports.SENSOR_BEGIN_MARKER} / ${exports.SENSOR_END_MARKER}`);
86
- const eol = markdown.includes('\r\n') ? '\r\n' : '\n';
172
+ // Preserve the line ending of the block this renderer owns. Another generated
173
+ // block may legitimately have a different EOL during a Windows checkout.
174
+ const eol = markdown.slice(begin, end).includes('\r\n') ? '\r\n' : '\n';
87
175
  const block = generated.split('\n').join(eol);
88
176
  return markdown.slice(0, begin + exports.SENSOR_BEGIN_MARKER.length) + eol + eol + block + eol + eol + markdown.slice(end);
89
177
  }
90
178
  function registryRootFromArgs(argv) {
91
- const index = argv.indexOf('--registry-root');
92
- if (index === -1 || argv[index + 1] === undefined || argv[index + 1].startsWith('--') || index !== argv.lastIndexOf('--registry-root')) {
93
- throw new Error('sensor support matrix requires exactly one --registry-root <path>');
94
- }
95
- return registryPath(argv[index + 1]);
179
+ return registryPath(exactArgument(argv, '--registry-root'));
96
180
  }
97
181
  /* istanbul ignore next: command shell is covered through exported functions. */
98
182
  if (require.main === module) {
99
- const root = registryRootFromArgs(process.argv.slice(2));
183
+ const argv = process.argv.slice(2);
184
+ const root = registryRootFromArgs(argv);
185
+ const stdout = argv.includes('--stdout');
186
+ if (argv.includes('--prepublication-fixture')) {
187
+ if (argv.filter((value) => value === '--prepublication-fixture').length !== 1 || argv.filter((value) => value === '--stdout').length > 1 || (argv.length !== 3 && argv.length !== 4)) {
188
+ throw new Error('sensor support matrix fixture mode accepts only --registry-root <path> --prepublication-fixture [--stdout]');
189
+ }
190
+ }
191
+ else {
192
+ verifyPublishedRegistryIdentity(root, exactArgument(argv, '--registry-tag'), exactArgument(argv, '--registry-commit'));
193
+ }
194
+ if (stdout) {
195
+ process.stdout.write(`${renderSensorSupportMatrix(root)}\n`);
196
+ process.exit(0);
197
+ }
100
198
  const current = fs_1.default.readFileSync(exports.SENSOR_DOC_PATH, 'utf8');
101
199
  fs_1.default.writeFileSync(exports.SENSOR_DOC_PATH, spliceSensorSupportMatrix(current, renderSensorSupportMatrix(root)), 'utf8');
102
200
  process.stdout.write('support-matrix.md sensor-pack evidence regenerated from registry manifests\n');
@@ -144,7 +144,10 @@ function spliceGenerated(markdown, generated) {
144
144
  if (begin === -1 || end === -1 || end < begin) {
145
145
  throw new Error(`support-matrix.md no tiene los marcadores ${exports.BEGIN_MARKER} / ${exports.END_MARKER}`);
146
146
  }
147
- const eol = markdown.includes('\r\n') ? '\r\n' : '\n';
147
+ // Each renderer owns only its marked block. A document can temporarily contain
148
+ // another generated block with different line endings, so using the first CRLF
149
+ // anywhere in the file would rewrite this block and create CI-only drift.
150
+ const eol = markdown.slice(begin, end).includes('\r\n') ? '\r\n' : '\n';
148
151
  const block = generated.split('\n').join(eol);
149
152
  return markdown.slice(0, begin + exports.BEGIN_MARKER.length)
150
153
  + eol + eol + block + eol + eol
@@ -49,7 +49,10 @@ function registerPreflightCommand(program) {
49
49
  const report = await (0, checks_1.preflight)(opts.cwd ?? process.cwd());
50
50
  process.stdout.write(opts.json ? JSON.stringify(report, null, 2) + '\n' : formatReport(report));
51
51
  const code = exitCodeFor(report);
52
+ // `process.exit()` may truncate the JSON written immediately above when
53
+ // stdout is a pipe (CI, an API consumer, or a shell capture). Preserve
54
+ // the semantic exit code while allowing Node to flush the report.
52
55
  if (code !== 0)
53
- process.exit(code);
56
+ process.exitCode = code;
54
57
  });
55
58
  }
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const child_process_1 = require("child_process");
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const os_1 = __importDefault(require("os"));
9
+ const path_1 = __importDefault(require("path"));
10
+ const cliRoot = path_1.default.resolve(__dirname, '../..');
11
+ const bin = path_1.default.join(cliRoot, 'dist', 'src', 'index.js');
12
+ test('preserves degraded preflight JSON when stdout is piped', () => {
13
+ const project = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'awm-preflight-pipe-'));
14
+ try {
15
+ const result = (0, child_process_1.spawnSync)(process.execPath, [bin, 'preflight', '--json'], {
16
+ cwd: project,
17
+ encoding: 'utf8',
18
+ env: { ...process.env, AWM_HOME: path_1.default.join(project, 'awm-home'), AWM_NO_UPDATE_CHECK: '1' },
19
+ });
20
+ expect(result.status).toBe(1);
21
+ expect(JSON.parse(result.stdout)).toMatchObject({ status: 'not_configured' });
22
+ }
23
+ finally {
24
+ fs_1.default.rmSync(project, { recursive: true, force: true });
25
+ }
26
+ });
@@ -8,7 +8,7 @@ const path_1 = __importDefault(require("path"));
8
8
  const child_process_1 = require("child_process");
9
9
  const CLI_ROOT = path_1.default.resolve(__dirname, '../..');
10
10
  const DIST_ENTRYPOINT = path_1.default.join(CLI_ROOT, 'dist', 'src', 'index.js');
11
- const TARGET_VERSION = '8.0.0';
11
+ const R3_MAJOR_VERSION = 8;
12
12
  function readJson(file) {
13
13
  return JSON.parse(fs_1.default.readFileSync(path_1.default.join(CLI_ROOT, file), 'utf8'));
14
14
  }
@@ -22,16 +22,18 @@ function runCompiledCli(...args) {
22
22
  return `${result.stdout}${result.stderr}`;
23
23
  }
24
24
  describe('R3 public major CLI release contract', () => {
25
- it('declares 8.0.0 consistently in package metadata and the lockfile root', () => {
25
+ it('retains the R3 major version consistently in package metadata and the lockfile root', () => {
26
26
  const pkg = readJson('package.json');
27
27
  const lock = readJson('package-lock.json');
28
28
  const root = lock.packages[''];
29
- expect(pkg.version).toBe(TARGET_VERSION);
30
- expect(lock.version).toBe(TARGET_VERSION);
31
- expect(root.version).toBe(TARGET_VERSION);
29
+ const version = pkg.version;
30
+ expect(typeof version).toBe('string');
31
+ expect(version).toMatch(new RegExp(`^${R3_MAJOR_VERSION}\\.`));
32
+ expect(lock.version).toBe(version);
33
+ expect(root.version).toBe(version);
32
34
  });
33
- it('exposes 8.0.0 from the compiled CLI while retaining its help banner', () => {
34
- expect(runCompiledCli('--version').trim()).toBe(TARGET_VERSION);
35
+ it('exposes the package version from the compiled CLI while retaining its help banner', () => {
36
+ expect(runCompiledCli('--version').trim()).toBe(readJson('package.json').version);
35
37
  expect(runCompiledCli('--help')).toContain('Usage: awm');
36
38
  });
37
39
  });
@@ -16,10 +16,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
16
16
  // Este test hace que ese desvio sea imposible de mergear. No verifica que la tabla sea
17
17
  // "linda": verifica que sea LA MISMA que produce el codigo hoy.
18
18
  const fs_1 = __importDefault(require("fs"));
19
+ const os_1 = __importDefault(require("os"));
19
20
  const path_1 = __importDefault(require("path"));
21
+ const child_process_1 = require("child_process");
20
22
  const support_matrix_1 = require("../../scripts/support-matrix");
21
23
  const sensor_support_matrix_1 = require("../../scripts/sensor-support-matrix");
22
24
  const SENSOR_FIXTURE_REGISTRY = path_1.default.join(__dirname, '..', 'fixtures', 'sensor-support-matrix', 'registry');
25
+ const CI_WORKFLOW_PATH = path_1.default.resolve(__dirname, '../../..', '.github', 'workflows', 'ci.yml');
23
26
  describe('docs/support-matrix.md refleja el codigo', () => {
24
27
  it('el bloque generado esta al dia', () => {
25
28
  const doc = fs_1.default.readFileSync(support_matrix_1.DOC_PATH, 'utf-8');
@@ -33,17 +36,76 @@ describe('docs/support-matrix.md refleja el codigo', () => {
33
36
  expect(doc).toContain(support_matrix_1.BEGIN_MARKER);
34
37
  expect(doc).toContain(support_matrix_1.END_MARKER);
35
38
  });
36
- it('the generated pre-publication v2 sensor-pack contract fixture is current', () => {
39
+ it('keeps the generated pre-publication v2 fixture separately renderable', () => {
37
40
  const doc = fs_1.default.readFileSync(support_matrix_1.DOC_PATH, 'utf-8');
41
+ const fixture = (0, sensor_support_matrix_1.renderSensorSupportMatrix)(SENSOR_FIXTURE_REGISTRY);
42
+ expect(fixture).toContain(sensor_support_matrix_1.R3_PREPUBLICATION_FIXTURE_PURPOSE);
43
+ expect(fixture).toContain('not the published `awm-baseline-registry` manifests');
44
+ expect(fixture).not.toContain('Published certification evidence');
38
45
  expect(doc).toContain(sensor_support_matrix_1.SENSOR_BEGIN_MARKER);
39
46
  expect(doc).toContain(sensor_support_matrix_1.SENSOR_END_MARKER);
40
- expect(doc).toContain(sensor_support_matrix_1.R3_PREPUBLICATION_FIXTURE_PURPOSE);
41
- expect(doc).toContain('not the published `awm-baseline-registry` manifests');
42
- expect(doc).toBe((0, sensor_support_matrix_1.spliceSensorSupportMatrix)(doc, (0, sensor_support_matrix_1.renderSensorSupportMatrix)(SENSOR_FIXTURE_REGISTRY)));
47
+ expect(doc).toContain('published registry evidence');
48
+ expect(doc).toContain('Published certification evidence');
43
49
  });
44
- it('pins the documentation generator to the declared R3 pre-publication fixture', () => {
50
+ it('uses a published registry root for documentation and retains a fixture-only command', () => {
45
51
  const packageJson = JSON.parse(fs_1.default.readFileSync(path_1.default.join(__dirname, '..', '..', 'package.json'), 'utf8'));
46
- expect(packageJson.scripts?.['docs:matrix']).toContain(`--registry-root ${sensor_support_matrix_1.R3_PREPUBLICATION_FIXTURE_RELATIVE_PATH}`);
52
+ expect(packageJson.scripts?.['docs:matrix']).toContain('--registry-root ../../awm-baseline-registry');
53
+ expect(packageJson.scripts?.['docs:matrix:prepublication']).toContain(`--registry-root ${sensor_support_matrix_1.R3_PREPUBLICATION_FIXTURE_RELATIVE_PATH}`);
54
+ });
55
+ it('CI regenerates the published matrix from the immutable registry tag', () => {
56
+ const workflow = fs_1.default.readFileSync(CI_WORKFLOW_PATH, 'utf8');
57
+ expect(workflow).toContain('repository: Kodria/awm-baseline-registry');
58
+ expect(workflow).toContain('ref: v2.0.0');
59
+ expect(workflow).toContain('path: awm-baseline-registry');
60
+ expect(workflow).toContain('Verify published sensor support matrix');
61
+ expect(workflow).toContain('--registry-root ../awm-baseline-registry --registry-tag v2.0.0 --registry-commit c35c087a0801c0b4e69e0a4ac3eafef9ecdf37cd');
62
+ expect(workflow).toContain('git diff --exit-code -- docs/support-matrix.md');
63
+ });
64
+ it('retains the published registry certification rows verbatim instead of inventing fixture evidence', () => {
65
+ const publishedSupport = [
66
+ '# Sensor pack support',
67
+ '',
68
+ '<!-- BEGIN GENERATED: sensor-pack-support -->',
69
+ 'Generated from pack manifests and certification pins resolved at `2026-08-14T22:14:34.365Z`.',
70
+ '',
71
+ 'Status: `certified` has a matching frozen tool pin; `compatible-unverified` has no matching frozen pin; `not-applicable` is reserved for variants without a tool contract.',
72
+ '',
73
+ '| Pack | Sensor | Variant | Tool | Certified range | Supported OS | OS certification evidence | Status | Evidence |',
74
+ '| --- | --- | --- | --- | --- | --- | --- | --- | --- |',
75
+ '| `js-ts` | `lint` | `eslint-10-flat` | `eslint` | `=10.8.1` | Ubuntu, macOS, Windows | Ubuntu/macOS/Windows: contract | certified | pin: `eslint@10.8.1` |',
76
+ '| `js-ts` | `test` | `npm-script` | `npm` | `>=8.0.0` | Ubuntu, macOS, Windows | Ubuntu/macOS/Windows: contract | compatible-unverified | no matching pinned tool |',
77
+ '',
78
+ '| Certification status | Derived variant count | Meaning |',
79
+ '| --- | --- | --- |',
80
+ '| certified | 15 | Matching frozen tool pin |',
81
+ '| compatible-unverified | 6 | No matching frozen tool pin |',
82
+ '| not-applicable | 0 | Variant has no tool contract |',
83
+ '<!-- END GENERATED: sensor-pack-support -->',
84
+ '',
85
+ ].join('\n');
86
+ expect((0, sensor_support_matrix_1.extractPublishedSupportMetadata)(publishedSupport)).toContain('`eslint-10-flat`');
87
+ expect((0, sensor_support_matrix_1.extractPublishedSupportMetadata)(publishedSupport)).toContain('compatible-unverified');
88
+ expect((0, sensor_support_matrix_1.extractPublishedSupportMetadata)(publishedSupport)).not.toContain('Fixture-declared ranges only');
89
+ });
90
+ it('rejects a mutable checkout even when it contains the published v2.0.0 tag', () => {
91
+ const registryRoot = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'awm-published-registry-'));
92
+ const git = (...args) => (0, child_process_1.execFileSync)('git', ['-C', registryRoot, ...args], { stdio: 'pipe' });
93
+ try {
94
+ git('init');
95
+ git('config', 'user.email', 'test@example.com');
96
+ git('config', 'user.name', 'AWM test');
97
+ fs_1.default.writeFileSync(path_1.default.join(registryRoot, 'published.txt'), 'published\n');
98
+ git('add', '.');
99
+ git('commit', '-m', 'published registry');
100
+ git('tag', 'v2.0.0');
101
+ fs_1.default.writeFileSync(path_1.default.join(registryRoot, 'mutable.txt'), 'newer checkout\n');
102
+ git('add', '.');
103
+ git('commit', '-m', 'mutable checkout');
104
+ expect(() => (0, sensor_support_matrix_1.verifyPublishedRegistryIdentity)(registryRoot, 'v2.0.0', 'c35c087a0801c0b4e69e0a4ac3eafef9ecdf37cd')).toThrow(/HEAD .*expected commit/i);
105
+ }
106
+ finally {
107
+ fs_1.default.rmSync(registryRoot, { recursive: true, force: true });
108
+ }
47
109
  });
48
110
  it('la tabla nombra a los seis providers declarados', () => {
49
111
  // Que el bloque este "al dia" no sirve si el generador se olvidara de un provider:
@@ -156,6 +218,16 @@ describe('docs/support-matrix.md refleja el codigo', () => {
156
218
  expect(out).toContain('linea uno\r\nlinea dos');
157
219
  expect(out.split('\r\n').length - 1).toBe(out.split('\n').length - 1); // ni un LF suelto
158
220
  });
221
+ it('preserva el EOL del bloque de providers aunque otro bloque sea CRLF', () => {
222
+ const mixedDoc = `intro\r\n${support_matrix_1.BEGIN_MARKER}\nold\n${support_matrix_1.END_MARKER}\nfin\n`;
223
+ const out = (0, support_matrix_1.spliceGenerated)(mixedDoc, 'linea uno\nlinea dos');
224
+ expect(out).toContain(`${support_matrix_1.BEGIN_MARKER}\n\nlinea uno\nlinea dos\n\n${support_matrix_1.END_MARKER}`);
225
+ });
226
+ it('preserva el EOL del bloque de sensores aunque otro bloque sea CRLF', () => {
227
+ const mixedDoc = `intro\r\n${sensor_support_matrix_1.SENSOR_BEGIN_MARKER}\nold\n${sensor_support_matrix_1.SENSOR_END_MARKER}\nfin\n`;
228
+ const out = (0, sensor_support_matrix_1.spliceSensorSupportMatrix)(mixedDoc, 'linea uno\nlinea dos');
229
+ expect(out).toContain(`${sensor_support_matrix_1.SENSOR_BEGIN_MARKER}\n\nlinea uno\nlinea dos\n\n${sensor_support_matrix_1.SENSOR_END_MARKER}`);
230
+ });
159
231
  it('marks an unsupported scope rather than leaving it absent', () => {
160
232
  // La diferencia entre "no soportado" y una celda vacia es exactamente lo que el
161
233
  // documento existe para no dejar ambiguo: Copilot no tiene scope global por
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentic-workflow-manager",
3
- "version": "8.1.0",
3
+ "version": "8.1.1",
4
4
  "main": "dist/src/index.js",
5
5
  "bin": {
6
6
  "awm": "./dist/src/index.js"
@@ -27,7 +27,8 @@
27
27
  "release": "node dist/src/release/index.js",
28
28
  "prepack": "npm run build",
29
29
  "prepublishOnly": "npm run build",
30
- "docs:matrix": "ts-node scripts/support-matrix.ts && ts-node scripts/sensor-support-matrix.ts --registry-root tests/fixtures/sensor-support-matrix/registry"
30
+ "docs:matrix": "ts-node scripts/support-matrix.ts && ts-node scripts/sensor-support-matrix.ts --registry-root ../../awm-baseline-registry --registry-tag v2.0.0 --registry-commit c35c087a0801c0b4e69e0a4ac3eafef9ecdf37cd",
31
+ "docs:matrix:prepublication": "ts-node scripts/sensor-support-matrix.ts --registry-root tests/fixtures/sensor-support-matrix/registry --prepublication-fixture --stdout"
31
32
  },
32
33
  "keywords": [
33
34
  "agentic",