agentic-workflow-manager 9.18.0 → 9.20.0

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 (69) hide show
  1. package/dist/src/commands/change/index.js +492 -0
  2. package/dist/src/commands/changes/index.js +84 -0
  3. package/dist/src/commands/plan/index.js +1 -1
  4. package/dist/src/commands/sensors/index.js +9 -0
  5. package/dist/src/commands/sensors/read-only-observation.js +305 -0
  6. package/dist/src/commands/sensors/run.js +24 -60
  7. package/dist/src/core/admission/index.js +11 -1
  8. package/dist/src/core/changes/command.js +38 -0
  9. package/dist/src/core/changes/derive.js +120 -0
  10. package/dist/src/core/changes/fs-safe.js +47 -0
  11. package/dist/src/core/changes/git-env.js +68 -0
  12. package/dist/src/core/changes/git.js +216 -0
  13. package/dist/src/core/changes/list-parse.js +67 -0
  14. package/dist/src/core/changes/list.js +408 -0
  15. package/dist/src/core/changes/parse.js +72 -0
  16. package/dist/src/core/changes/range.js +53 -0
  17. package/dist/src/core/changes/receipt.js +274 -0
  18. package/dist/src/core/changes/record-io.js +149 -0
  19. package/dist/src/core/changes/render-list.js +109 -0
  20. package/dist/src/core/changes/render.js +178 -0
  21. package/dist/src/core/changes/text-safety.js +116 -0
  22. package/dist/src/core/changes/trailers.js +76 -0
  23. package/dist/src/core/changes/types.js +26 -0
  24. package/dist/src/core/changes/validate-shape.js +219 -0
  25. package/dist/src/core/changes/worktree.js +53 -0
  26. package/dist/src/core/currentness/check.js +5 -2
  27. package/dist/src/index.js +4 -0
  28. package/dist/src/release/orchestrator.js +3 -1
  29. package/dist/tests/commands/change/new.test.js +1126 -0
  30. package/dist/tests/commands/change/validate.test.js +1145 -0
  31. package/dist/tests/commands/changes/list.test.js +423 -0
  32. package/dist/tests/commands/sensors/index.test.js +1 -1
  33. package/dist/tests/commands/sensors/read-only-observation.test.js +537 -0
  34. package/dist/tests/commands/sensors/run-read-only.test.js +151 -0
  35. package/dist/tests/core/admission/index.test.js +60 -0
  36. package/dist/tests/core/changes/derive.test.js +455 -0
  37. package/dist/tests/core/changes/fs-safe.test.js +82 -0
  38. package/dist/tests/core/changes/git-env.test.js +143 -0
  39. package/dist/tests/core/changes/git.test.js +442 -0
  40. package/dist/tests/core/changes/helpers.js +269 -0
  41. package/dist/tests/core/changes/list-fixtures.js +122 -0
  42. package/dist/tests/core/changes/list-long-history.test.js +52 -0
  43. package/dist/tests/core/changes/list-paging.test.js +511 -0
  44. package/dist/tests/core/changes/list-parse.test.js +120 -0
  45. package/dist/tests/core/changes/list-tree.test.js +44 -0
  46. package/dist/tests/core/changes/list.test.js +821 -0
  47. package/dist/tests/core/changes/parse.test.js +142 -0
  48. package/dist/tests/core/changes/predicates.test.js +83 -0
  49. package/dist/tests/core/changes/range.test.js +92 -0
  50. package/dist/tests/core/changes/receipt.test.js +947 -0
  51. package/dist/tests/core/changes/record-io.test.js +307 -0
  52. package/dist/tests/core/changes/record.test.js +549 -0
  53. package/dist/tests/core/changes/render-list.test.js +212 -0
  54. package/dist/tests/core/changes/render.test.js +202 -0
  55. package/dist/tests/core/changes/text-safety.test.js +226 -0
  56. package/dist/tests/core/changes/trailers.test.js +181 -0
  57. package/dist/tests/core/changes/worktree.test.js +259 -0
  58. package/dist/tests/core/currentness/check-insteadof.test.js +120 -0
  59. package/dist/tests/core/currentness/check.test.js +75 -14
  60. package/dist/tests/release/orchestrator-trailer.test.js +72 -0
  61. package/dist/tests/release/orchestrator.test.js +1 -0
  62. package/dist/tests/structural/change-commands-are-registered.test.js +29 -0
  63. package/dist/tests/structural/change-record-git-and-platform-conventions.test.js +77 -0
  64. package/dist/tests/structural/cloud-admission-docs-contract.test.js +54 -0
  65. package/package.json +1 -1
  66. package/prebuilds/darwin-arm64/secure_fs.node +0 -0
  67. package/prebuilds/darwin-x64/secure_fs.node +0 -0
  68. package/prebuilds/win32-arm64/secure_fs.node +0 -0
  69. package/prebuilds/win32-x64/secure_fs.node +0 -0
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ // The Change Record commands are reachable from the real program: `awm change new|validate` and `awm changes list`. Every command
4
+ // module is tested by registering it on a fresh Commander program, which would stay green if src/index.ts forgot the register call.
5
+ const index_1 = require("../../src/index");
6
+ const find = (parent, name) => parent.commands.find((c) => c.name() === name);
7
+ const flags = (command) => (command?.options ?? []).map((o) => o.long ?? o.flags).sort();
8
+ describe('the real awm program registers the Change Record commands', () => {
9
+ test('`awm change` has `new <slug>` and `validate [path]` with their options', () => {
10
+ const change = find(index_1.program, 'change');
11
+ expect(change).toBeDefined();
12
+ const created = find(change, 'new');
13
+ const validated = find(change, 'validate');
14
+ expect(created?.usage()).toContain('<slug>');
15
+ expect(flags(created)).toEqual(['--base', '--issue', '--model', '--plan', '--refresh', '--session']);
16
+ expect(validated?.usage()).toContain('[path]');
17
+ expect(flags(validated)).toEqual(['--base', '--json', '--strict']);
18
+ });
19
+ test('`awm changes` has `list` with --since, --base and --format', () => {
20
+ const changes = find(index_1.program, 'changes');
21
+ expect(changes).toBeDefined();
22
+ expect(flags(find(changes, 'list'))).toEqual(['--base', '--format', '--since']);
23
+ });
24
+ test('both are in the top-level help', () => {
25
+ const help = index_1.program.helpInformation();
26
+ expect(help).toMatch(/^\s+change\b/m);
27
+ expect(help).toMatch(/^\s+changes\b/m);
28
+ });
29
+ });
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ // Structural guards for two defect classes that recurred through the Change Record cycle (#217,
3
+ // harness-retro 2026-10-17; see the branch ledger signatures `s3-cq-dirty-duplicates-gitstate`,
4
+ // `git-dir-env-not-scrubbed` and `silent-return-instead-of-skip`):
5
+ //
6
+ // 1. Every git child of the change-record code runs through `execGit`/`runGit`/`gitState`
7
+ // (core/changes/git-env.ts), which scrubs inherited GIT_* location/pathspec variables, closes
8
+ // stdin, bounds time and output and sets GIT_NO_LAZY_FETCH. A bare `execFileSync('git', ...)`
9
+ // in these directories silently loses all of that, and reviewers found such leaks four times.
10
+ // 2. A test that returns early on Windows is reported as PASSED by the 3-platform release gate.
11
+ // These suites use `posixOnly` (test.skip with a visible reason) instead.
12
+ //
13
+ // The detectors are exercised on inline samples below, so each guard demonstrably fires.
14
+ var __importDefault = (this && this.__importDefault) || function (mod) {
15
+ return (mod && mod.__esModule) ? mod : { "default": mod };
16
+ };
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.bareGitSpawns = bareGitSpawns;
19
+ exports.silentWin32Returns = silentWin32Returns;
20
+ const fs_1 = __importDefault(require("fs"));
21
+ const path_1 = __importDefault(require("path"));
22
+ const CLI_ROOT = path_1.default.join(__dirname, '../..');
23
+ function tsFiles(dir) {
24
+ if (!fs_1.default.existsSync(dir))
25
+ return [];
26
+ const out = [];
27
+ for (const entry of fs_1.default.readdirSync(dir, { withFileTypes: true })) {
28
+ const full = path_1.default.join(dir, entry.name);
29
+ if (entry.isDirectory())
30
+ out.push(...tsFiles(full));
31
+ else if (entry.isFile() && entry.name.endsWith('.ts'))
32
+ out.push(full);
33
+ }
34
+ return out;
35
+ }
36
+ // Naive comment stripping, as in exec-invocation-explicit-stdio.test.ts: a false positive fails loud.
37
+ function stripComments(source) {
38
+ return source.replace(/\/\*[\s\S]*?\*\//g, '').replace(/(^|[^:])\/\/.*$/gm, '$1');
39
+ }
40
+ const BARE_GIT_SPAWN = /\b(?:execFileSync|execFile|spawnSync|spawn)\(\s*['"`]git['"`]/;
41
+ const SILENT_WIN32_RETURN = /\bif\s*\(\s*(?:process\.platform\s*===\s*['"]win32['"]|win32|isWindows)\s*\)\s*(?:\{\s*)?return\b/;
42
+ function bareGitSpawns(source) {
43
+ return BARE_GIT_SPAWN.test(stripComments(source));
44
+ }
45
+ function silentWin32Returns(source) {
46
+ return SILENT_WIN32_RETURN.test(stripComments(source));
47
+ }
48
+ describe('change-record conventions (structural)', () => {
49
+ test('the detectors fire on the offending shapes and not on the sanctioned ones', () => {
50
+ expect(bareGitSpawns("execFileSync('git', ['status'])")).toBe(true);
51
+ expect(bareGitSpawns('spawnSync("git", args, opts)')).toBe(true);
52
+ expect(bareGitSpawns("runGit(root, ['status'])")).toBe(false);
53
+ expect(bareGitSpawns("// execFileSync('git', [])\nexecGit(root, [])")).toBe(false);
54
+ expect(silentWin32Returns("if (process.platform === 'win32') return;")).toBe(true);
55
+ expect(silentWin32Returns('if (win32) { return; }')).toBe(true);
56
+ expect(silentWin32Returns('posixOnly(() => { /* body */ });')).toBe(false);
57
+ expect(silentWin32Returns("// if (process.platform === 'win32') return;")).toBe(false);
58
+ });
59
+ test('git is spawned only by git-env.ts under core/changes and the change commands', () => {
60
+ const dirs = ['src/core/changes', 'src/commands/change', 'src/commands/changes'].map(d => path_1.default.join(CLI_ROOT, d));
61
+ const allowed = path_1.default.join(CLI_ROOT, 'src/core/changes/git-env.ts');
62
+ const offenders = dirs
63
+ .flatMap(tsFiles)
64
+ .filter(file => file !== allowed)
65
+ .filter(file => bareGitSpawns(fs_1.default.readFileSync(file, 'utf8')))
66
+ .map(file => path_1.default.relative(CLI_ROOT, file));
67
+ expect(offenders).toEqual([]);
68
+ });
69
+ test('change-record tests skip with posixOnly instead of returning early on Windows', () => {
70
+ const dirs = ['tests/core/changes', 'tests/commands/change', 'tests/commands/changes'].map(d => path_1.default.join(CLI_ROOT, d));
71
+ const offenders = dirs
72
+ .flatMap(tsFiles)
73
+ .filter(file => silentWin32Returns(fs_1.default.readFileSync(file, 'utf8')))
74
+ .map(file => path_1.default.relative(CLI_ROOT, file));
75
+ expect(offenders).toEqual([]);
76
+ });
77
+ });
@@ -0,0 +1,54 @@
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 fs_1 = __importDefault(require("fs"));
7
+ const path_1 = __importDefault(require("path"));
8
+ /** CMD-DOCS — V-R4 (issue #215 documentation). */
9
+ const repoRoot = path_1.default.resolve(__dirname, '../../..');
10
+ /** Whitespace-normalized so re-wrapping the prose never breaks a pinned phrase. */
11
+ const read = (relative) => fs_1.default.readFileSync(path_1.default.join(repoRoot, ...relative.split('/')), 'utf8').replace(/\s+/g, ' ');
12
+ describe('issue #215 documentation contract (V-R4)', () => {
13
+ const configuration = read('docs/configuration.md');
14
+ it('documents .awm/admission.json with defaults, the git rule and the accepted risk', () => {
15
+ expect(configuration).toContain('## Read-only admission observation (`.awm/admission.json`)');
16
+ for (const name of ['node_modules', '.next', '.turbo', 'dist', 'build', 'coverage', '.venv', 'target'])
17
+ expect(configuration).toContain(`\`${name}\``);
18
+ expect(configuration).toContain('git-ignored and contains no tracked file');
19
+ expect(configuration).toContain('**Accepted risk:**');
20
+ expect(configuration).toContain('`admission-config-invalid`');
21
+ expect(configuration).toContain('`readOnlyObservation`');
22
+ expect(configuration).toContain('`awm plan admit` does not print it');
23
+ });
24
+ it.each([
25
+ '250000',
26
+ '1 GiB',
27
+ '`read-only-mutation-detected`',
28
+ '`read-only-observation-unavailable`',
29
+ '`not-ignored`',
30
+ '`contains-tracked`',
31
+ '`git-unavailable`',
32
+ '`.git` or `.awm`',
33
+ 'never skipped',
34
+ 'including any `.awm` or `.git` nested',
35
+ 'regular file',
36
+ '65536 bytes',
37
+ ])('documents the observation limit, reason code or reserved-name rule %s', literal => {
38
+ expect(configuration).toContain(literal);
39
+ });
40
+ it('points --verify-sensors in the CLI reference at the observation rules', () => {
41
+ const doc = read('docs/cli-reference.md');
42
+ expect(doc).toContain('configuration.md#read-only-admission-observation-awmadmissionjson');
43
+ expect(doc).toContain('`ADMISSION_SENSORS_BLOCKED`');
44
+ });
45
+ it('states that the D-7 insteadOf recipe passes strict currentness', () => {
46
+ const doc = read('docs/operations/cloud-and-platforms.md');
47
+ expect(doc).toContain('`awm preflight --require-current`');
48
+ expect(doc).toContain('`remote.origin.url`');
49
+ expect(doc).toContain('--local');
50
+ });
51
+ it('describes the snapshot exclusions in the plan admit help', () => {
52
+ expect(read('cli/src/commands/plan/index.ts')).toContain("'require an empirical sensor pass; read-only observation skips git-ignored build output (see .awm/admission.json)'");
53
+ });
54
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentic-workflow-manager",
3
- "version": "9.18.0",
3
+ "version": "9.20.0",
4
4
  "main": "dist/src/index.js",
5
5
  "bin": {
6
6
  "awm": "./dist/src/index.js"
Binary file
Binary file