@imdeadpool/guardex 5.0.13 → 5.0.16
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.
- package/README.md +24 -0
- package/bin/multiagent-safety.js +112 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -111,6 +111,11 @@ gx doctor
|
|
|
111
111
|
# setup + repair another repo without switching your current repo checkout
|
|
112
112
|
gx setup --target /path/to/repo
|
|
113
113
|
gx doctor --target /path/to/repo
|
|
114
|
+
# optional: from parent folder, generate VS Code workspace view for repo + agent worktrees
|
|
115
|
+
cd /path/to
|
|
116
|
+
gx setup --target ./repo --parent-workspace-view
|
|
117
|
+
# open this in VS Code to manage both base repo and .omx/agent-worktrees
|
|
118
|
+
code ./repo-branches.code-workspace
|
|
114
119
|
|
|
115
120
|
# protected branch management
|
|
116
121
|
gx protect list
|
|
@@ -198,6 +203,7 @@ gx agents stop
|
|
|
198
203
|
- `gx init` is alias of `gx setup`.
|
|
199
204
|
- Setup/doctor can install missing global OMX/OpenSpec/codex-auth with explicit Y/N confirmation.
|
|
200
205
|
- `gx setup` checks GitHub CLI (`gh`) and prints install guidance if missing.
|
|
206
|
+
- Optional parent-folder VS Code Source Control view: `gx setup --target /path/to/repo --parent-workspace-view` creates `../<repo>-branches.code-workspace`.
|
|
201
207
|
- Interactive self-update prompt defaults to **No** (`[y/N]`).
|
|
202
208
|
- In initialized repos, `setup`/`install`/`fix` block protected-base writes unless explicitly overridden.
|
|
203
209
|
- Direct commits/pushes to protected branches are blocked by default.
|
|
@@ -366,6 +372,24 @@ npm pack --dry-run
|
|
|
366
372
|
|
|
367
373
|
## Release notes
|
|
368
374
|
|
|
375
|
+
### v5.0.16
|
|
376
|
+
|
|
377
|
+
- Fixed `gx doctor` runtime crash (`parseDoctorArgs is not defined`) by restoring the doctor argument parser for `--target` and `--strict`.
|
|
378
|
+
- Added regression coverage that asserts the doctor parser function exists in `bin/multiagent-safety.js`.
|
|
379
|
+
- Bumped package version from `5.0.15` to `5.0.16`.
|
|
380
|
+
|
|
381
|
+
### v5.0.15
|
|
382
|
+
|
|
383
|
+
- Added `gx setup --parent-workspace-view` to generate a parent-folder VS Code workspace (`../<repo>-branches.code-workspace`) that shows both the base repo and `.omx/agent-worktrees` in Source Control.
|
|
384
|
+
- Added dry-run-safe parent workspace operations (`would-create` / `would-update`) and setup output that prints the created workspace path.
|
|
385
|
+
- Added regression coverage for parent workspace generation and dry-run behavior.
|
|
386
|
+
- Bumped package version from `5.0.14` to `5.0.15`.
|
|
387
|
+
|
|
388
|
+
### v5.0.14
|
|
389
|
+
|
|
390
|
+
- Changed release metadata for the next npm publish by bumping package version from `5.0.13` to `5.0.14`.
|
|
391
|
+
- Kept Guardex release notes synchronized with the published package version.
|
|
392
|
+
|
|
369
393
|
### v5.0.13
|
|
370
394
|
|
|
371
395
|
- Bumped package version from `5.0.12` to `5.0.13` for the next npm publish.
|
package/bin/multiagent-safety.js
CHANGED
|
@@ -184,7 +184,7 @@ const SUGGESTIBLE_COMMANDS = [
|
|
|
184
184
|
];
|
|
185
185
|
const CLI_COMMAND_DESCRIPTIONS = [
|
|
186
186
|
['status', 'Show GuardeX CLI + service health without modifying files'],
|
|
187
|
-
['setup', 'Install + repair guardrails in a git repo (supports --no-gitignore)'],
|
|
187
|
+
['setup', 'Install + repair guardrails in a git repo (supports --no-gitignore, --parent-workspace-view)'],
|
|
188
188
|
['init', 'Alias of setup (bootstrap + repair guardrails in a git repo)'],
|
|
189
189
|
['doctor', 'Repair safety setup drift, then verify repo safety'],
|
|
190
190
|
['report', 'Generate security/safety reports (for example: OpenSSF scorecard)'],
|
|
@@ -445,6 +445,7 @@ NOTES
|
|
|
445
445
|
- ${TOOL_NAME} setup asks for Y/N approval before global installs
|
|
446
446
|
- ${TOOL_NAME} setup checks GitHub CLI (gh) and prints install guidance if missing
|
|
447
447
|
- For other repos: ${SHORT_TOOL_NAME} setup --target <repo-path> then ${SHORT_TOOL_NAME} doctor --target <repo-path>
|
|
448
|
+
- Optional parent-folder Source Control view: ${SHORT_TOOL_NAME} setup --target <repo-path> --parent-workspace-view
|
|
448
449
|
- In initialized repos, setup/install/fix block in-place writes on protected main by default
|
|
449
450
|
- setup/doctor auto-finish clean pending agent/* branches via PR flow into the current local base branch
|
|
450
451
|
- doctor auto-runs in a sandbox agent branch/worktree on protected main and tries auto-finish PR flow
|
|
@@ -838,6 +839,14 @@ function configureHooks(repoRoot, dryRun) {
|
|
|
838
839
|
return { status: 'set', key: 'core.hooksPath', value: '.githooks' };
|
|
839
840
|
}
|
|
840
841
|
|
|
842
|
+
function requireValue(rawArgs, index, flagName) {
|
|
843
|
+
const value = rawArgs[index + 1];
|
|
844
|
+
if (!value || value.startsWith('-')) {
|
|
845
|
+
throw new Error(`${flagName} requires a value`);
|
|
846
|
+
}
|
|
847
|
+
return value;
|
|
848
|
+
}
|
|
849
|
+
|
|
841
850
|
function parseCommonArgs(rawArgs, defaults) {
|
|
842
851
|
const options = { ...defaults };
|
|
843
852
|
|
|
@@ -899,6 +908,99 @@ function parseCommonArgs(rawArgs, defaults) {
|
|
|
899
908
|
return options;
|
|
900
909
|
}
|
|
901
910
|
|
|
911
|
+
function parseSetupArgs(rawArgs, defaults) {
|
|
912
|
+
const setupDefaults = { ...defaults, parentWorkspaceView: false };
|
|
913
|
+
const forwardedArgs = [];
|
|
914
|
+
|
|
915
|
+
for (const arg of rawArgs) {
|
|
916
|
+
if (arg === '--parent-workspace-view') {
|
|
917
|
+
setupDefaults.parentWorkspaceView = true;
|
|
918
|
+
continue;
|
|
919
|
+
}
|
|
920
|
+
if (arg === '--no-parent-workspace-view') {
|
|
921
|
+
setupDefaults.parentWorkspaceView = false;
|
|
922
|
+
continue;
|
|
923
|
+
}
|
|
924
|
+
forwardedArgs.push(arg);
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
return parseCommonArgs(forwardedArgs, setupDefaults);
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
function parseDoctorArgs(rawArgs) {
|
|
931
|
+
const options = {
|
|
932
|
+
target: process.cwd(),
|
|
933
|
+
strict: false,
|
|
934
|
+
};
|
|
935
|
+
|
|
936
|
+
for (let index = 0; index < rawArgs.length; index += 1) {
|
|
937
|
+
const arg = rawArgs[index];
|
|
938
|
+
if (arg === '--target' || arg === '-t') {
|
|
939
|
+
options.target = requireValue(rawArgs, index, '--target');
|
|
940
|
+
index += 1;
|
|
941
|
+
continue;
|
|
942
|
+
}
|
|
943
|
+
if (arg === '--strict') {
|
|
944
|
+
options.strict = true;
|
|
945
|
+
continue;
|
|
946
|
+
}
|
|
947
|
+
throw new Error(`Unknown option: ${arg}`);
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
return options;
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
function normalizeWorkspacePath(relativePath) {
|
|
954
|
+
return String(relativePath || '.').replace(/\\/g, '/');
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
function buildParentWorkspaceView(repoRoot) {
|
|
958
|
+
const parentDir = path.dirname(repoRoot);
|
|
959
|
+
const workspaceFileName = `${path.basename(repoRoot)}-branches.code-workspace`;
|
|
960
|
+
const workspacePath = path.join(parentDir, workspaceFileName);
|
|
961
|
+
const repoRelativePath = normalizeWorkspacePath(path.relative(parentDir, repoRoot) || '.');
|
|
962
|
+
const worktreesRelativePath = normalizeWorkspacePath(
|
|
963
|
+
path.join(repoRelativePath === '.' ? '' : repoRelativePath, '.omx', 'agent-worktrees'),
|
|
964
|
+
);
|
|
965
|
+
|
|
966
|
+
return {
|
|
967
|
+
workspacePath,
|
|
968
|
+
payload: {
|
|
969
|
+
folders: [
|
|
970
|
+
{ path: repoRelativePath },
|
|
971
|
+
{ path: worktreesRelativePath },
|
|
972
|
+
],
|
|
973
|
+
settings: {
|
|
974
|
+
'scm.alwaysShowRepositories': true,
|
|
975
|
+
},
|
|
976
|
+
},
|
|
977
|
+
};
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
function ensureParentWorkspaceView(repoRoot, dryRun) {
|
|
981
|
+
const { workspacePath, payload } = buildParentWorkspaceView(repoRoot);
|
|
982
|
+
const operationFile = path.relative(repoRoot, workspacePath) || path.basename(workspacePath);
|
|
983
|
+
const nextContent = `${JSON.stringify(payload, null, 2)}\n`;
|
|
984
|
+
const note = 'parent VS Code workspace view';
|
|
985
|
+
|
|
986
|
+
if (!fs.existsSync(workspacePath)) {
|
|
987
|
+
if (!dryRun) {
|
|
988
|
+
fs.writeFileSync(workspacePath, nextContent, 'utf8');
|
|
989
|
+
}
|
|
990
|
+
return { status: dryRun ? 'would-create' : 'created', file: operationFile, note };
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
const currentContent = fs.readFileSync(workspacePath, 'utf8');
|
|
994
|
+
if (currentContent === nextContent) {
|
|
995
|
+
return { status: 'unchanged', file: operationFile, note };
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
if (!dryRun) {
|
|
999
|
+
fs.writeFileSync(workspacePath, nextContent, 'utf8');
|
|
1000
|
+
}
|
|
1001
|
+
return { status: dryRun ? 'would-update' : 'updated', file: operationFile, note };
|
|
1002
|
+
}
|
|
1003
|
+
|
|
902
1004
|
function hasGuardexBootstrapFiles(repoRoot) {
|
|
903
1005
|
const required = [
|
|
904
1006
|
'AGENTS.md',
|
|
@@ -4284,7 +4386,7 @@ function report(rawArgs) {
|
|
|
4284
4386
|
}
|
|
4285
4387
|
|
|
4286
4388
|
function setup(rawArgs) {
|
|
4287
|
-
const options =
|
|
4389
|
+
const options = parseSetupArgs(rawArgs, {
|
|
4288
4390
|
target: process.cwd(),
|
|
4289
4391
|
force: false,
|
|
4290
4392
|
skipAgents: false,
|
|
@@ -4331,6 +4433,9 @@ function setup(rawArgs) {
|
|
|
4331
4433
|
assertProtectedMainWriteAllowed(options, 'setup');
|
|
4332
4434
|
const installPayload = runInstallInternal(options);
|
|
4333
4435
|
installPayload.operations.push(ensureSetupProtectedBranches(installPayload.repoRoot, Boolean(options.dryRun)));
|
|
4436
|
+
if (options.parentWorkspaceView) {
|
|
4437
|
+
installPayload.operations.push(ensureParentWorkspaceView(installPayload.repoRoot, Boolean(options.dryRun)));
|
|
4438
|
+
}
|
|
4334
4439
|
printOperations('Setup/install', installPayload, options.dryRun);
|
|
4335
4440
|
|
|
4336
4441
|
const fixPayload = runFixInternal({
|
|
@@ -4349,6 +4454,11 @@ function setup(rawArgs) {
|
|
|
4349
4454
|
return;
|
|
4350
4455
|
}
|
|
4351
4456
|
|
|
4457
|
+
if (options.parentWorkspaceView) {
|
|
4458
|
+
const parentWorkspace = buildParentWorkspaceView(installPayload.repoRoot);
|
|
4459
|
+
console.log(`[${TOOL_NAME}] Parent workspace view: ${parentWorkspace.workspacePath}`);
|
|
4460
|
+
}
|
|
4461
|
+
|
|
4352
4462
|
const scanResult = runScanInternal({ target: options.target, json: false });
|
|
4353
4463
|
const currentBaseBranch = currentBranchName(scanResult.repoRoot);
|
|
4354
4464
|
const autoFinishSummary = autoFinishReadyAgentBranches(scanResult.repoRoot, {
|