mirror of
https://github.com/abhigyanpatwari/GitNexus.git
synced 2026-10-26 06:02:22 +00:00
fix(opencode): skip plugin write on literal drift, glob token extraction, segment-anchored mutation check
This commit is contained in:
parent
111e045f50
commit
20cb030ec9
3 changed files with 35 additions and 12 deletions
|
|
@ -184,8 +184,13 @@ export function extractOpenCodePattern(tool, args) {
|
|||
}
|
||||
if (tool === 'glob') {
|
||||
const raw = typeof input.pattern === 'string' ? input.pattern : '';
|
||||
const match = raw.match(/[*\/]([a-zA-Z][a-zA-Z0-9_-]{2,})/);
|
||||
return match ? match[1] : null;
|
||||
// Longest literal run (>=3 chars) in the glob, with glob metachars as
|
||||
// delimiters: '**/UserService*' → UserService, 'src/**/*.ts' → src,
|
||||
// '**/*.service.ts' → service. The older [*/]letter regex missed every
|
||||
// recursive glob whose segments start with '*', '.', or another metachar.
|
||||
const runs = raw.match(/[a-zA-Z0-9_-]{3,}/g);
|
||||
if (!runs) return null;
|
||||
return runs.reduce((best, run) => (run.length > best.length ? run : best));
|
||||
}
|
||||
if (tool === 'bash') {
|
||||
return extractBashSearchPattern(input.command);
|
||||
|
|
@ -193,12 +198,17 @@ export function extractOpenCodePattern(tool, args) {
|
|||
return null;
|
||||
}
|
||||
|
||||
/** True for the git commands that move HEAD (same set as the Claude adapter). */
|
||||
/**
|
||||
* True for the git commands that move HEAD (same set as the Claude adapter).
|
||||
* Segments are checked after splitting on shell separators and each must
|
||||
* START with `git`, so `echo 'git commit'` or `grep 'git commit' file` don't
|
||||
* count as mutations while `cd x && git commit` still does.
|
||||
*/
|
||||
export function isGitMutationCommand(command) {
|
||||
return (
|
||||
typeof command === 'string' &&
|
||||
/\bgit\s+(commit|merge|rebase|cherry-pick|pull)(\s|$)/.test(command)
|
||||
);
|
||||
if (typeof command !== 'string') return false;
|
||||
return command
|
||||
.split(/&&|\|\||;|\|/)
|
||||
.some((seg) => /^\s*git\s+(commit|merge|rebase|cherry-pick|pull)(\s|$)/.test(seg));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1351,8 +1351,9 @@ async function installOpenCodePlugin(result: SetupResult): Promise<void> {
|
|||
const jsonCli = JSON.stringify(normalizedCli);
|
||||
if (!content.includes(OPENCODE_CLI_PATH_SOURCE_LITERAL)) {
|
||||
result.errors.push(
|
||||
'OpenCode hooks: gitnexus-plugin.js no longer contains the cliPath literal to patch — the installed plugin may fail to resolve the CLI. Update OPENCODE_CLI_PATH_SOURCE_LITERAL in setup.ts.',
|
||||
'OpenCode hooks: gitnexus-plugin.js no longer contains the cliPath literal to patch — skipping plugin install (the unpatched relative cliPath would resolve under the OpenCode config dir). Update OPENCODE_CLI_PATH_SOURCE_LITERAL in setup.ts.',
|
||||
);
|
||||
return;
|
||||
}
|
||||
content = content.replace(OPENCODE_CLI_PATH_SOURCE_LITERAL, `let cliPath = ${jsonCli};`);
|
||||
// Sanity: the installed copy must export the plugin initializer OpenCode calls.
|
||||
|
|
|
|||
|
|
@ -48,7 +48,9 @@ describe('extractOpenCodePattern', () => {
|
|||
|
||||
it('derives a token from glob patterns', () => {
|
||||
expect(extractOpenCodePattern('glob', { pattern: '**/UserService*' })).toBe('UserService');
|
||||
expect(extractOpenCodePattern('glob', { pattern: 'src/**/*.ts' })).toBeNull();
|
||||
expect(extractOpenCodePattern('glob', { pattern: 'src/**/*.ts' })).toBe('src');
|
||||
expect(extractOpenCodePattern('glob', { pattern: '**/*.service.ts' })).toBe('service');
|
||||
expect(extractOpenCodePattern('glob', { pattern: '**/*.{a,b}' })).toBeNull();
|
||||
expect(extractOpenCodePattern('glob', {})).toBeNull();
|
||||
});
|
||||
|
||||
|
|
@ -102,11 +104,21 @@ describe('isGitMutationCommand', () => {
|
|||
'git rebase main',
|
||||
'git cherry-pick abc',
|
||||
'git pull',
|
||||
'cd src && git commit -m x',
|
||||
'npm test || git pull',
|
||||
])('detects %s', (cmd) => expect(isGitMutationCommand(cmd)).toBe(true));
|
||||
|
||||
it.each(['git status', 'git diff', 'git stash push', 'npm test', ''])('ignores %s', (cmd) =>
|
||||
expect(isGitMutationCommand(cmd)).toBe(false),
|
||||
);
|
||||
it.each([
|
||||
'git status',
|
||||
'git diff',
|
||||
'git stash push',
|
||||
'npm test',
|
||||
'',
|
||||
// Text that merely mentions a mutation must not count.
|
||||
"echo 'git commit'",
|
||||
"grep 'git commit' file.txt",
|
||||
'cat notes.md | grep git-pull',
|
||||
])('ignores %s', (cmd) => expect(isGitMutationCommand(cmd)).toBe(false));
|
||||
|
||||
it('rejects non-strings', () => {
|
||||
expect(isGitMutationCommand(null)).toBe(false);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue