Skip to content

Commit 70dc46f

Browse files
authored
Merge pull request #179 from maystudios/worktree-agent-af4b4b21
fix: core, install & config audit compliance
2 parents 16fc6fd + 35479fb commit 70dc46f

File tree

9 files changed

+122
-9
lines changed

9 files changed

+122
-9
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,4 @@ analysis/
4747
gaps.md
4848
/improve.md
4949
philosophy.md
50-
autoresearch-results.tsv
50+
/autoresearch-results.tsv

package-lock.json

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"packages/website"
88
],
99
"description": "A meta-prompting, context engineering and spec-driven development system for Claude Code by MayStudios.",
10+
"license": "MIT",
1011
"engines": {
1112
"node": ">=22.0.0"
1213
},

packages/cli/scripts/inject-version.cjs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,41 @@ const versionTsPath = path.join(pkgCliRoot, 'src', 'core', 'version.ts');
2121
const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf8'));
2222
const version = pkg.version;
2323

24-
const content = `/** MaxsimCLI version — auto-injected from package.json at build time. */\nexport const VERSION = '${version}';\n`;
24+
const versionLine = `export const VERSION = '${version}';`;
2525

2626
const existing = fs.existsSync(versionTsPath)
2727
? fs.readFileSync(versionTsPath, 'utf8')
2828
: '';
2929

30-
if (existing === content) {
30+
if (existing.includes(versionLine)) {
3131
console.log(` [version] version.ts already up-to-date (${version})`);
32+
} else if (existing && /export const VERSION = '.*';/.test(existing)) {
33+
// Replace the VERSION line in-place, preserving utility functions
34+
const updated = existing.replace(/export const VERSION = '.*';/, versionLine);
35+
fs.writeFileSync(versionTsPath, updated, 'utf8');
36+
console.log(` [version] Injected version ${version} -> src/core/version.ts`);
3237
} else {
38+
// File missing or doesn't contain VERSION — write the full template
39+
const content = `/** MaxsimCLI version — auto-injected from package.json at build time. */\n${versionLine}\n`;
3340
fs.writeFileSync(versionTsPath, content, 'utf8');
3441
console.log(` [version] Injected version ${version} -> src/core/version.ts`);
3542
}
43+
44+
// Also update templates/templates/config.json version
45+
const configJsonPath = path.join(pkgCliRoot, '..', '..', 'templates', 'templates', 'config.json');
46+
if (fs.existsSync(configJsonPath)) {
47+
try {
48+
const config = JSON.parse(fs.readFileSync(configJsonPath, 'utf8'));
49+
if (config.version !== version) {
50+
config.version = version;
51+
fs.writeFileSync(configJsonPath, JSON.stringify(config, null, 2) + '\n', 'utf8');
52+
console.log(` [version] Injected version ${version} -> templates/templates/config.json`);
53+
} else {
54+
console.log(` [version] config.json already up-to-date (${version})`);
55+
}
56+
} catch (err) {
57+
console.warn(` [version] Warning: Could not update config.json: ${err.message}`);
58+
}
59+
} else {
60+
console.warn(' [version] Warning: templates/templates/config.json not found');
61+
}

packages/cli/src/core/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export {
2323
export { loadConfig, saveConfig, resolveModel, resolveMaxAgents, getConfigPath } from './config.js';
2424

2525
// Version
26-
export { VERSION } from './version.js';
26+
export { VERSION, parseVersion, isVersionAtLeast, getVersion } from './version.js';
2727

2828
// Utils
2929
export { claudeDir, maxsimDir, agentMemoryDir, configPath, parseFrontmatter } from './utils.js';

packages/cli/src/core/version.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,33 @@
11
/** MaxsimCLI version — auto-injected from package.json at build time. */
2-
export const VERSION = '5.10.0';
2+
export const VERSION = '5.12.0';
3+
4+
/**
5+
* Parse a semantic version string into components.
6+
* Returns null if the string is not a valid semver.
7+
*/
8+
export function parseVersion(versionStr: string): { major: number; minor: number; patch: number } | null {
9+
const match = versionStr.match(/^(\d+)\.(\d+)\.(\d+)/);
10+
if (!match) return null;
11+
return {
12+
major: Number.parseInt(match[1], 10),
13+
minor: Number.parseInt(match[2], 10),
14+
patch: Number.parseInt(match[3], 10),
15+
};
16+
}
17+
18+
/**
19+
* Check if the current VERSION is at least the given minimum version.
20+
*/
21+
export function isVersionAtLeast(minimum: string): boolean {
22+
const current = parseVersion(VERSION);
23+
const target = parseVersion(minimum);
24+
if (!current || !target) return false;
25+
if (current.major !== target.major) return current.major > target.major;
26+
if (current.minor !== target.minor) return current.minor > target.minor;
27+
return current.patch >= target.patch;
28+
}
29+
30+
/** Get the current version string. */
31+
export function getVersion(): string {
32+
return VERSION;
33+
}

packages/cli/src/install/hooks.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ export function installHooks(projectDir: string): { installed: string[] } {
3434
const installed: string[] = [];
3535

3636
if (copied === 0) {
37+
// Guarantee settings.json exists even if no hooks were copied
38+
if (!fs.existsSync(settingsPath)) {
39+
fs.mkdirSync(path.dirname(settingsPath), { recursive: true });
40+
fs.writeFileSync(settingsPath, `${JSON.stringify({ hooks: {} }, null, 2)}\n`, 'utf8');
41+
}
3742
return { installed };
3843
}
3944

packages/cli/tests/unit/types.test.ts

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import {
1717
PARALLELISM_LIMITS,
1818
DEFAULT_CONFIG,
1919
} from '../../src/core/types.js';
20-
import { VERSION } from '../../src/core/version.js';
20+
import { VERSION, parseVersion, isVersionAtLeast, getVersion } from '../../src/core/version.js';
2121

2222
describe('CmdResult', () => {
2323
it('cmdOk creates a successful result with data', () => {
@@ -148,6 +148,49 @@ describe('VERSION', () => {
148148
});
149149
});
150150

151+
describe('parseVersion', () => {
152+
it('parses a valid semver string', () => {
153+
expect(parseVersion('1.2.3')).toEqual({ major: 1, minor: 2, patch: 3 });
154+
});
155+
156+
it('parses semver with pre-release suffix', () => {
157+
expect(parseVersion('2.0.1-beta.1')).toEqual({ major: 2, minor: 0, patch: 1 });
158+
});
159+
160+
it('returns null for invalid strings', () => {
161+
expect(parseVersion('invalid')).toBeNull();
162+
expect(parseVersion('')).toBeNull();
163+
});
164+
});
165+
166+
describe('getVersion', () => {
167+
it('returns a non-empty string matching VERSION', () => {
168+
const v = getVersion();
169+
expect(typeof v).toBe('string');
170+
expect(v.length).toBeGreaterThan(0);
171+
expect(v).toBe(VERSION);
172+
});
173+
});
174+
175+
describe('isVersionAtLeast', () => {
176+
it('returns true when current version meets the minimum', () => {
177+
// Current VERSION should be at least 1.0.0
178+
expect(isVersionAtLeast('1.0.0')).toBe(true);
179+
});
180+
181+
it('returns true when current version equals the minimum', () => {
182+
expect(isVersionAtLeast(VERSION)).toBe(true);
183+
});
184+
185+
it('returns false when minimum is higher than current', () => {
186+
expect(isVersionAtLeast('999.0.0')).toBe(false);
187+
});
188+
189+
it('returns false for invalid version strings', () => {
190+
expect(isVersionAtLeast('invalid')).toBe(false);
191+
});
192+
});
193+
151194
describe('PARALLELISM_LIMITS', () => {
152195
it('has entries for all 3 profiles', () => {
153196
expect(Object.keys(PARALLELISM_LIMITS)).toHaveLength(3);

templates/templates/config.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"version": "6.0.0",
2+
"version": "5.12.0",
33
"execution": {
44
"model_profile": "balanced",
55
"parallelism": {
@@ -9,7 +9,13 @@
99
},
1010
"verification": {
1111
"strict_mode": true,
12-
"gates": ["tests", "build", "lint", "spec", "review"],
12+
"gates": [
13+
"tests",
14+
"build",
15+
"lint",
16+
"spec",
17+
"review"
18+
],
1319
"require_code_review": true,
1420
"auto_resolve_conflicts": true
1521
}

0 commit comments

Comments
 (0)