@memnexus-ai/mx-agent-cli 0.1.197 → 0.1.198

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.
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Guards for the CLI's agent-config bundler (scripts/bundle-config.mjs).
3
+ *
4
+ * Two regressions this locks down (security review of #4304 Phase 1):
5
+ *
6
+ * 1. The exclusion filter must test the path RELATIVE to the source root, not
7
+ * the absolute path cpSync hands it. Otherwise a checkout under a directory
8
+ * whose path contains a `local`/`node_modules`/`.git` segment (e.g.
9
+ * `/usr/local/src/...`, `~/.local/share/...`) matches the checkout-location
10
+ * PREFIX and excludes the ENTIRE agent-config tree — silently shipping an
11
+ * empty dist/agent-config/ (no settings.json, no git-mutation-guard hook,
12
+ * no agents).
13
+ *
14
+ * 2. A post-build assertion must FAIL the build if the copy produced an empty
15
+ * or partial bundle, rather than printing a success line unconditionally.
16
+ */
17
+ export {};
18
+ //# sourceMappingURL=bundle-config.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle-config.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/bundle-config.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Guards for the CLI's agent-config bundler (scripts/bundle-config.mjs).
3
+ *
4
+ * Two regressions this locks down (security review of #4304 Phase 1):
5
+ *
6
+ * 1. The exclusion filter must test the path RELATIVE to the source root, not
7
+ * the absolute path cpSync hands it. Otherwise a checkout under a directory
8
+ * whose path contains a `local`/`node_modules`/`.git` segment (e.g.
9
+ * `/usr/local/src/...`, `~/.local/share/...`) matches the checkout-location
10
+ * PREFIX and excludes the ENTIRE agent-config tree — silently shipping an
11
+ * empty dist/agent-config/ (no settings.json, no git-mutation-guard hook,
12
+ * no agents).
13
+ *
14
+ * 2. A post-build assertion must FAIL the build if the copy produced an empty
15
+ * or partial bundle, rather than printing a success line unconditionally.
16
+ */
17
+ import { describe, it, expect, afterEach } from 'vitest';
18
+ import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from 'fs';
19
+ import { tmpdir } from 'os';
20
+ import { join } from 'path';
21
+ // @ts-expect-error — plain ESM script, no type declarations.
22
+ import { makeConfigFilter, assertBundleNonEmpty } from '../../scripts/bundle-config.mjs';
23
+ describe('makeConfigFilter — relative-path exclusion', () => {
24
+ // Simulate a checkout whose location prefix contains excluded segments.
25
+ const SRC = '/usr/local/src/x/agent-config';
26
+ const filter = makeConfigFilter(SRC);
27
+ it('keeps the source root itself', () => {
28
+ expect(filter(SRC)).toBe(true);
29
+ });
30
+ it('keeps in-tree files despite a `local` segment in the prefix', () => {
31
+ // Regression: previously the `/usr/local/` prefix matched and excluded these.
32
+ expect(filter(`${SRC}/settings.json`)).toBe(true);
33
+ expect(filter(`${SRC}/hooks/git-mutation-guard.sh`)).toBe(true);
34
+ expect(filter(`${SRC}/agents/bar-raiser.md`)).toBe(true);
35
+ expect(filter(`${SRC}/skills/some-skill/SKILL.md`)).toBe(true);
36
+ });
37
+ it('still excludes the in-tree local/ overlay', () => {
38
+ expect(filter(`${SRC}/local`)).toBe(false);
39
+ expect(filter(`${SRC}/local/agents/internal.md`)).toBe(false);
40
+ });
41
+ it('still excludes in-tree node_modules and .git', () => {
42
+ expect(filter(`${SRC}/node_modules`)).toBe(false);
43
+ expect(filter(`${SRC}/node_modules/pkg/index.js`)).toBe(false);
44
+ expect(filter(`${SRC}/.git`)).toBe(false);
45
+ expect(filter(`${SRC}/.git/config`)).toBe(false);
46
+ });
47
+ it('still excludes co-located hook test suites (*.test.sh)', () => {
48
+ expect(filter(`${SRC}/hooks/git-mutation-guard.test.sh`)).toBe(false);
49
+ });
50
+ it('works when the source root has no excluded segment in its prefix', () => {
51
+ const cleanSrc = '/srv/build/agent-config';
52
+ const cleanFilter = makeConfigFilter(cleanSrc);
53
+ expect(cleanFilter(`${cleanSrc}/settings.json`)).toBe(true);
54
+ expect(cleanFilter(`${cleanSrc}/local/x.md`)).toBe(false);
55
+ });
56
+ });
57
+ describe('assertBundleNonEmpty — post-build guard', () => {
58
+ const dirs = [];
59
+ function tmp() {
60
+ const d = mkdtempSync(join(tmpdir(), 'bundle-assert-'));
61
+ dirs.push(d);
62
+ return d;
63
+ }
64
+ afterEach(() => {
65
+ while (dirs.length)
66
+ rmSync(dirs.pop(), { recursive: true, force: true });
67
+ });
68
+ it('throws on an empty output dir', () => {
69
+ expect(() => assertBundleNonEmpty(tmp())).toThrow(/missing or empty/);
70
+ });
71
+ it('throws when settings.json is empty', () => {
72
+ const d = tmp();
73
+ writeFileSync(join(d, 'settings.json'), '');
74
+ mkdirSync(join(d, 'hooks'));
75
+ writeFileSync(join(d, 'hooks', 'guard.sh'), '#!/bin/sh\n');
76
+ expect(() => assertBundleNonEmpty(d)).toThrow(/settings\.json is missing or empty/);
77
+ });
78
+ it('throws when hooks/ is missing', () => {
79
+ const d = tmp();
80
+ writeFileSync(join(d, 'settings.json'), '{}');
81
+ expect(() => assertBundleNonEmpty(d)).toThrow(/hooks.*missing or empty/);
82
+ });
83
+ it('throws when hooks/ is empty', () => {
84
+ const d = tmp();
85
+ writeFileSync(join(d, 'settings.json'), '{}');
86
+ mkdirSync(join(d, 'hooks'));
87
+ expect(() => assertBundleNonEmpty(d)).toThrow(/hooks.*missing or empty/);
88
+ });
89
+ it('passes for a populated bundle', () => {
90
+ const d = tmp();
91
+ writeFileSync(join(d, 'settings.json'), '{"ok":true}');
92
+ mkdirSync(join(d, 'hooks'));
93
+ writeFileSync(join(d, 'hooks', 'guard.sh'), '#!/bin/sh\n');
94
+ expect(() => assertBundleNonEmpty(d)).not.toThrow();
95
+ });
96
+ });
97
+ //# sourceMappingURL=bundle-config.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundle-config.test.js","sourceRoot":"","sources":["../../src/__tests__/bundle-config.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memnexus-ai/mx-agent-cli",
3
- "version": "0.1.197",
3
+ "version": "0.1.198",
4
4
  "description": "CLI for creating and managing AI agent teams",
5
5
  "type": "module",
6
6
  "bin": {