@imdeadpool/guardex 5.0.13 → 5.0.15

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 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,18 @@ npm pack --dry-run
366
372
 
367
373
  ## Release notes
368
374
 
375
+ ### v5.0.15
376
+
377
+ - 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.
378
+ - Added dry-run-safe parent workspace operations (`would-create` / `would-update`) and setup output that prints the created workspace path.
379
+ - Added regression coverage for parent workspace generation and dry-run behavior.
380
+ - Bumped package version from `5.0.14` to `5.0.15`.
381
+
382
+ ### v5.0.14
383
+
384
+ - Changed release metadata for the next npm publish by bumping package version from `5.0.13` to `5.0.14`.
385
+ - Kept Guardex release notes synchronized with the published package version.
386
+
369
387
  ### v5.0.13
370
388
 
371
389
  - Bumped package version from `5.0.12` to `5.0.13` for the next npm publish.
@@ -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,76 @@ 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 normalizeWorkspacePath(relativePath) {
931
+ return String(relativePath || '.').replace(/\\/g, '/');
932
+ }
933
+
934
+ function buildParentWorkspaceView(repoRoot) {
935
+ const parentDir = path.dirname(repoRoot);
936
+ const workspaceFileName = `${path.basename(repoRoot)}-branches.code-workspace`;
937
+ const workspacePath = path.join(parentDir, workspaceFileName);
938
+ const repoRelativePath = normalizeWorkspacePath(path.relative(parentDir, repoRoot) || '.');
939
+ const worktreesRelativePath = normalizeWorkspacePath(
940
+ path.join(repoRelativePath === '.' ? '' : repoRelativePath, '.omx', 'agent-worktrees'),
941
+ );
942
+
943
+ return {
944
+ workspacePath,
945
+ payload: {
946
+ folders: [
947
+ { path: repoRelativePath },
948
+ { path: worktreesRelativePath },
949
+ ],
950
+ settings: {
951
+ 'scm.alwaysShowRepositories': true,
952
+ },
953
+ },
954
+ };
955
+ }
956
+
957
+ function ensureParentWorkspaceView(repoRoot, dryRun) {
958
+ const { workspacePath, payload } = buildParentWorkspaceView(repoRoot);
959
+ const operationFile = path.relative(repoRoot, workspacePath) || path.basename(workspacePath);
960
+ const nextContent = `${JSON.stringify(payload, null, 2)}\n`;
961
+ const note = 'parent VS Code workspace view';
962
+
963
+ if (!fs.existsSync(workspacePath)) {
964
+ if (!dryRun) {
965
+ fs.writeFileSync(workspacePath, nextContent, 'utf8');
966
+ }
967
+ return { status: dryRun ? 'would-create' : 'created', file: operationFile, note };
968
+ }
969
+
970
+ const currentContent = fs.readFileSync(workspacePath, 'utf8');
971
+ if (currentContent === nextContent) {
972
+ return { status: 'unchanged', file: operationFile, note };
973
+ }
974
+
975
+ if (!dryRun) {
976
+ fs.writeFileSync(workspacePath, nextContent, 'utf8');
977
+ }
978
+ return { status: dryRun ? 'would-update' : 'updated', file: operationFile, note };
979
+ }
980
+
902
981
  function hasGuardexBootstrapFiles(repoRoot) {
903
982
  const required = [
904
983
  'AGENTS.md',
@@ -4284,7 +4363,7 @@ function report(rawArgs) {
4284
4363
  }
4285
4364
 
4286
4365
  function setup(rawArgs) {
4287
- const options = parseCommonArgs(rawArgs, {
4366
+ const options = parseSetupArgs(rawArgs, {
4288
4367
  target: process.cwd(),
4289
4368
  force: false,
4290
4369
  skipAgents: false,
@@ -4331,6 +4410,9 @@ function setup(rawArgs) {
4331
4410
  assertProtectedMainWriteAllowed(options, 'setup');
4332
4411
  const installPayload = runInstallInternal(options);
4333
4412
  installPayload.operations.push(ensureSetupProtectedBranches(installPayload.repoRoot, Boolean(options.dryRun)));
4413
+ if (options.parentWorkspaceView) {
4414
+ installPayload.operations.push(ensureParentWorkspaceView(installPayload.repoRoot, Boolean(options.dryRun)));
4415
+ }
4334
4416
  printOperations('Setup/install', installPayload, options.dryRun);
4335
4417
 
4336
4418
  const fixPayload = runFixInternal({
@@ -4349,6 +4431,11 @@ function setup(rawArgs) {
4349
4431
  return;
4350
4432
  }
4351
4433
 
4434
+ if (options.parentWorkspaceView) {
4435
+ const parentWorkspace = buildParentWorkspaceView(installPayload.repoRoot);
4436
+ console.log(`[${TOOL_NAME}] Parent workspace view: ${parentWorkspace.workspacePath}`);
4437
+ }
4438
+
4352
4439
  const scanResult = runScanInternal({ target: options.target, json: false });
4353
4440
  const currentBaseBranch = currentBranchName(scanResult.repoRoot);
4354
4441
  const autoFinishSummary = autoFinishReadyAgentBranches(scanResult.repoRoot, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@imdeadpool/guardex",
3
- "version": "5.0.13",
3
+ "version": "5.0.15",
4
4
  "description": "GuardeX: the Guardian T-Rex for your repo, with hardened multi-agent git guardrails.",
5
5
  "license": "MIT",
6
6
  "preferGlobal": true,