@imdeadpool/guardex 7.0.41 → 7.0.43

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.
Files changed (85) hide show
  1. package/README.md +68 -13
  2. package/package.json +2 -1
  3. package/skills/gitguardex/SKILL.md +13 -0
  4. package/skills/guardex-merge-skills-to-dev/SKILL.md +59 -0
  5. package/src/agents/cleanup-sessions.js +126 -0
  6. package/src/agents/detect.js +160 -0
  7. package/src/agents/finish.js +172 -0
  8. package/src/agents/inspect.js +189 -0
  9. package/src/agents/launch.js +240 -0
  10. package/src/agents/registry.js +133 -0
  11. package/src/agents/selection-panel.js +571 -0
  12. package/src/agents/sessions.js +151 -0
  13. package/src/agents/start.js +591 -0
  14. package/src/agents/status.js +143 -0
  15. package/src/agents/terminal.js +152 -0
  16. package/src/budget/index.js +343 -0
  17. package/src/ci-init/index.js +265 -0
  18. package/src/cli/args.js +305 -1
  19. package/src/cli/main.js +262 -132
  20. package/src/cockpit/action-runner.js +3 -0
  21. package/src/cockpit/actions.js +80 -0
  22. package/src/cockpit/control.js +1121 -0
  23. package/src/cockpit/index.js +426 -0
  24. package/src/cockpit/keybindings.js +224 -0
  25. package/src/cockpit/kitty-layout.js +549 -0
  26. package/src/cockpit/kitty-tree.js +144 -0
  27. package/src/cockpit/layout.js +224 -0
  28. package/src/cockpit/logs-reader.js +182 -0
  29. package/src/cockpit/menu.js +204 -0
  30. package/src/cockpit/pane-actions.js +597 -0
  31. package/src/cockpit/pane-menu.js +387 -0
  32. package/src/cockpit/projects-finder.js +178 -0
  33. package/src/cockpit/render.js +215 -0
  34. package/src/cockpit/settings-render.js +128 -0
  35. package/src/cockpit/settings.js +124 -0
  36. package/src/cockpit/shortcuts.js +24 -0
  37. package/src/cockpit/sidebar.js +311 -0
  38. package/src/cockpit/state.js +72 -0
  39. package/src/cockpit/theme.js +128 -0
  40. package/src/cockpit/welcome.js +266 -0
  41. package/src/context.js +76 -33
  42. package/src/doctor/index.js +3 -2
  43. package/src/finish/index.js +39 -2
  44. package/src/git/index.js +65 -0
  45. package/src/kitty/command.js +101 -0
  46. package/src/kitty/runtime.js +250 -0
  47. package/src/output/index.js +1 -1
  48. package/src/pr-review.js +241 -0
  49. package/src/scaffold/index.js +19 -0
  50. package/src/submodule/index.js +288 -0
  51. package/src/terminal/index.js +120 -0
  52. package/src/terminal/kitty.js +622 -0
  53. package/src/terminal/tmux.js +126 -0
  54. package/src/tmux/command.js +27 -0
  55. package/src/tmux/session.js +89 -0
  56. package/templates/AGENTS.multiagent-safety.md +27 -1
  57. package/templates/codex/skills/gitguardex/SKILL.md +2 -0
  58. package/templates/githooks/pre-commit +22 -1
  59. package/templates/github/workflows/README.md +87 -0
  60. package/templates/github/workflows/ci-full.yml +55 -0
  61. package/templates/github/workflows/ci.yml +56 -0
  62. package/templates/github/workflows/cr.yml +20 -1
  63. package/templates/scripts/agent-branch-finish.sh +544 -26
  64. package/templates/scripts/agent-branch-start.sh +89 -22
  65. package/templates/scripts/agent-preflight.sh +89 -0
  66. package/templates/scripts/agent-worktree-prune.sh +96 -5
  67. package/templates/scripts/codex-agent.sh +41 -6
  68. package/templates/scripts/openspec/init-plan-workspace.sh +43 -0
  69. package/templates/scripts/review-bot-watch.sh +31 -2
  70. package/templates/scripts/agent-session-state.js +0 -171
  71. package/templates/scripts/install-vscode-active-agents-extension.js +0 -135
  72. package/templates/vscode/guardex-active-agents/README.md +0 -34
  73. package/templates/vscode/guardex-active-agents/extension.js +0 -3782
  74. package/templates/vscode/guardex-active-agents/fileicons/gitguardex-fileicons.json +0 -54
  75. package/templates/vscode/guardex-active-agents/fileicons/icons/agent.svg +0 -5
  76. package/templates/vscode/guardex-active-agents/fileicons/icons/branch.svg +0 -7
  77. package/templates/vscode/guardex-active-agents/fileicons/icons/config.svg +0 -4
  78. package/templates/vscode/guardex-active-agents/fileicons/icons/hook.svg +0 -4
  79. package/templates/vscode/guardex-active-agents/fileicons/icons/openspec.svg +0 -5
  80. package/templates/vscode/guardex-active-agents/fileicons/icons/plan.svg +0 -4
  81. package/templates/vscode/guardex-active-agents/fileicons/icons/spec.svg +0 -5
  82. package/templates/vscode/guardex-active-agents/icon.png +0 -0
  83. package/templates/vscode/guardex-active-agents/media/active-agents-hivemind.svg +0 -14
  84. package/templates/vscode/guardex-active-agents/package.json +0 -169
  85. package/templates/vscode/guardex-active-agents/session-schema.js +0 -1348
@@ -1,171 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const fs = require('node:fs');
4
- const path = require('node:path');
5
-
6
- function resolveSessionSchemaModule() {
7
- const candidates = [
8
- path.resolve(__dirname, '..', 'vscode', 'guardex-active-agents', 'session-schema.js'),
9
- path.resolve(__dirname, '..', 'templates', 'vscode', 'guardex-active-agents', 'session-schema.js'),
10
- ];
11
-
12
- for (const candidate of candidates) {
13
- if (fs.existsSync(candidate)) {
14
- return require(candidate);
15
- }
16
- }
17
-
18
- throw new Error('Could not resolve Guardex active-agent session schema module.');
19
- }
20
-
21
- const sessionSchema = resolveSessionSchemaModule();
22
-
23
- function usage() {
24
- return (
25
- 'Usage:\n' +
26
- ' node scripts/agent-session-state.js start --repo <path> --branch <name> --task <task> --agent <agent> --worktree <path> --pid <pid> --cli <name> [--task-mode <caveman|omx>] [--openspec-tier <T0|T1|T2|T3>] [--routing-reason <text>] [--state <working|thinking|idle>]\n' +
27
- ' node scripts/agent-session-state.js heartbeat --repo <path> --branch <name> [--state <working|thinking|idle>]\n' +
28
- ' node scripts/agent-session-state.js terminate --repo <path> --branch <name>\n' +
29
- ' node scripts/agent-session-state.js stop --repo <path> --branch <name>\n'
30
- );
31
- }
32
-
33
- function parseOptions(argv) {
34
- const options = {};
35
- for (let index = 0; index < argv.length; index += 1) {
36
- const token = argv[index];
37
- if (!token.startsWith('--')) {
38
- throw new Error(`Unexpected argument: ${token}`);
39
- }
40
- const key = token.slice(2);
41
- const value = argv[index + 1];
42
- if (!value || value.startsWith('--')) {
43
- throw new Error(`Missing value for --${key}`);
44
- }
45
- options[key] = value;
46
- index += 1;
47
- }
48
- return options;
49
- }
50
-
51
- function requireOption(options, key) {
52
- const value = options[key];
53
- if (!value) {
54
- throw new Error(`Missing required option --${key}`);
55
- }
56
- return value;
57
- }
58
-
59
- function writeSessionRecord(options) {
60
- const repoRoot = requireOption(options, 'repo');
61
- const branch = requireOption(options, 'branch');
62
- const record = sessionSchema.buildSessionRecord({
63
- repoRoot,
64
- branch,
65
- taskName: requireOption(options, 'task'),
66
- agentName: requireOption(options, 'agent'),
67
- worktreePath: requireOption(options, 'worktree'),
68
- pid: requireOption(options, 'pid'),
69
- cliName: requireOption(options, 'cli'),
70
- taskMode: options['task-mode'],
71
- openspecTier: options['openspec-tier'],
72
- taskRoutingReason: options['routing-reason'],
73
- state: options.state,
74
- });
75
-
76
- const targetPath = sessionSchema.sessionFilePathForBranch(repoRoot, branch);
77
- fs.mkdirSync(path.dirname(targetPath), { recursive: true });
78
- fs.writeFileSync(targetPath, `${JSON.stringify(record, null, 2)}\n`, 'utf8');
79
- }
80
-
81
- function refreshSessionRecord(options) {
82
- const repoRoot = requireOption(options, 'repo');
83
- const branch = requireOption(options, 'branch');
84
- const targetPath = sessionSchema.sessionFilePathForBranch(repoRoot, branch);
85
- if (!fs.existsSync(targetPath)) {
86
- return;
87
- }
88
-
89
- const parsed = JSON.parse(fs.readFileSync(targetPath, 'utf8'));
90
- const nextRecord = {
91
- ...parsed,
92
- lastHeartbeatAt: new Date().toISOString(),
93
- };
94
- if (options.state) {
95
- nextRecord.state = options.state;
96
- }
97
-
98
- fs.writeFileSync(targetPath, `${JSON.stringify(nextRecord, null, 2)}\n`, 'utf8');
99
- }
100
-
101
- function readSessionRecord(options) {
102
- const repoRoot = requireOption(options, 'repo');
103
- const branch = requireOption(options, 'branch');
104
- const targetPath = sessionSchema.sessionFilePathForBranch(repoRoot, branch);
105
- if (!fs.existsSync(targetPath)) {
106
- return null;
107
- }
108
- return JSON.parse(fs.readFileSync(targetPath, 'utf8'));
109
- }
110
-
111
- function terminateSessionProcess(options) {
112
- const record = readSessionRecord(options);
113
- const pid = Number(record?.pid);
114
- if (!Number.isInteger(pid) || pid <= 0) {
115
- throw new Error('No live pid recorded for branch.');
116
- }
117
-
118
- try {
119
- process.kill(pid, 'SIGTERM');
120
- } catch (error) {
121
- if (error?.code === 'ESRCH') {
122
- return;
123
- }
124
- throw error;
125
- }
126
- }
127
-
128
- function removeSessionRecord(options) {
129
- const repoRoot = requireOption(options, 'repo');
130
- const branch = requireOption(options, 'branch');
131
- const targetPath = sessionSchema.sessionFilePathForBranch(repoRoot, branch);
132
- if (fs.existsSync(targetPath)) {
133
- fs.unlinkSync(targetPath);
134
- }
135
- }
136
-
137
- function main() {
138
- const [command, ...rest] = process.argv.slice(2);
139
- if (!command || ['-h', '--help', 'help'].includes(command)) {
140
- process.stdout.write(usage());
141
- return;
142
- }
143
-
144
- const options = parseOptions(rest);
145
- if (command === 'start') {
146
- writeSessionRecord(options);
147
- return;
148
- }
149
- if (command === 'heartbeat') {
150
- refreshSessionRecord(options);
151
- return;
152
- }
153
- if (command === 'terminate') {
154
- terminateSessionProcess(options);
155
- return;
156
- }
157
- if (command === 'stop') {
158
- removeSessionRecord(options);
159
- return;
160
- }
161
-
162
- throw new Error(`Unknown subcommand: ${command}`);
163
- }
164
-
165
- try {
166
- main();
167
- } catch (error) {
168
- process.stderr.write(`[guardex-active-session] ${error.message}\n`);
169
- process.stderr.write(usage());
170
- process.exitCode = 1;
171
- }
@@ -1,135 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- const fs = require('node:fs');
4
- const os = require('node:os');
5
- const path = require('node:path');
6
-
7
- const PATCH_COMPATIBILITY_WINDOW = 20;
8
- const RETIRED_EXTENSION_IDS = [
9
- 'recodeee.gitguardex-active-agents',
10
- ];
11
-
12
- function parseOptions(argv) {
13
- const options = {};
14
- for (let index = 0; index < argv.length; index += 1) {
15
- const token = argv[index];
16
- if (!token.startsWith('--')) {
17
- throw new Error(`Unexpected argument: ${token}`);
18
- }
19
- const key = token.slice(2);
20
- const value = argv[index + 1];
21
- if (!value || value.startsWith('--')) {
22
- throw new Error(`Missing value for --${key}`);
23
- }
24
- options[key] = value;
25
- index += 1;
26
- }
27
- return options;
28
- }
29
-
30
- function resolveExtensionSource(repoRoot) {
31
- const candidates = [
32
- path.join(repoRoot, 'vscode', 'guardex-active-agents'),
33
- path.join(repoRoot, 'templates', 'vscode', 'guardex-active-agents'),
34
- ];
35
-
36
- for (const candidate of candidates) {
37
- if (fs.existsSync(path.join(candidate, 'package.json'))) {
38
- return candidate;
39
- }
40
- }
41
-
42
- throw new Error('Could not find the Guardex VS Code companion sources.');
43
- }
44
-
45
- function removeIfExists(targetPath) {
46
- if (fs.existsSync(targetPath)) {
47
- fs.rmSync(targetPath, { recursive: true, force: true });
48
- }
49
- }
50
-
51
- function parseSimpleSemver(version) {
52
- const parts = String(version || '').trim().split('.').map((part) => Number.parseInt(part, 10));
53
- if (parts.length !== 3 || parts.some((part) => Number.isNaN(part))) {
54
- throw new Error(`Expected simple semver for the Active Agents companion, received "${version}".`);
55
- }
56
- return parts;
57
- }
58
-
59
- function buildInstallTargets(extensionId, version, extensionsDir) {
60
- const [major, minor, patch] = parseSimpleSemver(version);
61
- const firstCompatiblePatch = Math.max(0, patch - PATCH_COMPATIBILITY_WINDOW);
62
- const targets = [path.join(extensionsDir, extensionId)];
63
-
64
- for (let compatiblePatch = firstCompatiblePatch; compatiblePatch <= patch; compatiblePatch += 1) {
65
- targets.push(path.join(extensionsDir, `${extensionId}-${major}.${minor}.${compatiblePatch}`));
66
- }
67
-
68
- return targets;
69
- }
70
-
71
- function isRetiredExtensionInstall(entryName, currentExtensionId) {
72
- return RETIRED_EXTENSION_IDS
73
- .filter((extensionId) => extensionId !== currentExtensionId)
74
- .some((extensionId) => entryName === extensionId || entryName.startsWith(`${extensionId}-`));
75
- }
76
-
77
- function main() {
78
- const repoRoot = path.resolve(__dirname, '..');
79
- const options = parseOptions(process.argv.slice(2));
80
- const sourceDir = resolveExtensionSource(repoRoot);
81
- const manifest = JSON.parse(fs.readFileSync(path.join(sourceDir, 'package.json'), 'utf8'));
82
- const extensionId = `${manifest.publisher}.${manifest.name}`;
83
- const extensionsDir = path.resolve(
84
- options['extensions-dir'] ||
85
- process.env.GUARDEX_VSCODE_EXTENSIONS_DIR ||
86
- process.env.VSCODE_EXTENSIONS_DIR ||
87
- path.join(os.homedir(), '.vscode', 'extensions'),
88
- );
89
-
90
- fs.mkdirSync(extensionsDir, { recursive: true });
91
- const targetDirs = buildInstallTargets(extensionId, manifest.version, extensionsDir);
92
- const canonicalTargetDir = targetDirs[0];
93
- const keepDirNames = new Set(targetDirs.map((targetDir) => path.basename(targetDir)));
94
- let retiredInstallCount = 0;
95
-
96
- for (const entry of fs.readdirSync(extensionsDir, { withFileTypes: true })) {
97
- if (!entry.isDirectory()) {
98
- continue;
99
- }
100
- if (isRetiredExtensionInstall(entry.name, extensionId)) {
101
- removeIfExists(path.join(extensionsDir, entry.name));
102
- retiredInstallCount += 1;
103
- continue;
104
- }
105
- if (keepDirNames.has(entry.name)) {
106
- continue;
107
- }
108
- if (entry.name === extensionId || entry.name.startsWith(`${extensionId}-`)) {
109
- removeIfExists(path.join(extensionsDir, entry.name));
110
- }
111
- }
112
-
113
- for (const targetDir of targetDirs) {
114
- removeIfExists(targetDir);
115
- fs.cpSync(sourceDir, targetDir, {
116
- recursive: true,
117
- force: true,
118
- preserveTimestamps: true,
119
- });
120
- }
121
-
122
- process.stdout.write(
123
- `[guardex-active-agents] Installed ${extensionId}@${manifest.version} to ${canonicalTargetDir}\n` +
124
- `[guardex-active-agents] Refreshed ${targetDirs.length - 1} recent patch compatibility path(s) for already-open windows.\n` +
125
- `[guardex-active-agents] Removed ${retiredInstallCount} retired extension install path(s).\n` +
126
- '[guardex-active-agents] Reload each already-open VS Code window to activate the newest Source Control companion.\n',
127
- );
128
- }
129
-
130
- try {
131
- main();
132
- } catch (error) {
133
- process.stderr.write(`[guardex-active-agents] ${error.message}\n`);
134
- process.exitCode = 1;
135
- }
@@ -1,34 +0,0 @@
1
- # GitGuardex Active Agents
2
-
3
- Local VS Code companion for Guardex-managed repos.
4
-
5
- ## Quick Start
6
-
7
- Use the dedicated Active Agents sidebar icon to create or inspect Guardex sandboxes quickly.
8
-
9
- 1. Install from a Guardex-wired repo:
10
-
11
- ```sh
12
- node scripts/install-vscode-active-agents-extension.js
13
- ```
14
-
15
- 2. Reload the VS Code window.
16
- 3. In the Activity Bar, open the dedicated `Active Agents` hive icon. Use `Start agent` to enter a task + agent name and launch the repo Guardex agent runner. The companion prefers `bash scripts/codex-agent.sh` when present, falls back to `npm run agent:codex --`, and only uses `gx branch start` as a last resort.
17
-
18
- What it does:
19
-
20
- - Bundles a local GitGuardex icon so repo installs show branded extension metadata inside VS Code.
21
- - Bundles the optional `GitGuardex File Icons` theme for OpenSpec, agent worktree, and hook files in Explorer.
22
- - Adds a dedicated `Active Agents` Activity Bar container with a hive icon and live badge count for active sessions.
23
- - Renders one repo node per live Guardex workspace with grouped `ACTIVE AGENTS` and `CHANGES` sections.
24
- - Splits live sessions inside `ACTIVE AGENTS` into `BLOCKED`, `WORKING NOW`, `THINKING`, `STALLED`, and `DEAD` groups so stuck, active, and inactive lanes stand out immediately.
25
- - Mirrors the same live state in the VS Code status bar so the selected session or active-agent count stays visible outside the tree.
26
- - Keeps the built-in Source Control view focused on real Git repositories; the Active Agents commit command prompts for a message from its own toolbar action.
27
- - Shows one row per live Guardex sandbox session inside those activity groups, with changed-file rows nested under sessions that are touching files.
28
- - Labels session rows with provider identity and snapshot context; snapshot-backed rows use a one-letter snapshot badge such as `N` for `nagyviktor@edixa.com`.
29
- - Shows raw agent branch groups with the `git-branch` icon instead of the generic folder icon.
30
- - Shows repo-root git changes in a sibling `CHANGES` section when the guarded repo itself is dirty.
31
- - Derives session state from dirty worktree status, git conflict markers, heartbeat freshness, PID liveness, and recent file mtimes, surfaces working/dead/conflict counts in the repo/header summary, and shows changed-file counts for active edits.
32
- - Uses distinct VS Code codicons for each session state, including animated `loading~spin` for `WORKING NOW`.
33
- - Reads repo-local presence files from `.omx/state/active-sessions/`, expects `lastHeartbeatAt` freshness, and falls back to managed worktree-root `AGENT.lock` telemetry when the launcher session file is absent.
34
- - Publishes `guardex.hasAgents` and `guardex.hasConflicts` context keys for other VS Code contributions.