@imdeadpool/guardex 7.0.41 → 7.1.0

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 (118) hide show
  1. package/README.md +94 -13
  2. package/package.json +3 -1
  3. package/skills/gitguardex/SKILL.md +13 -0
  4. package/skills/guardex-merge-skills-to-dev/SKILL.md +59 -0
  5. package/skills/gx-act/SKILL.md +82 -0
  6. package/src/agents/cleanup-sessions.js +126 -0
  7. package/src/agents/finish.js +172 -0
  8. package/src/agents/inspect.js +202 -0
  9. package/src/agents/launch.js +249 -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 +146 -0
  15. package/src/agents/terminal.js +152 -0
  16. package/src/budget/index.js +344 -0
  17. package/src/ci-init/index.js +265 -0
  18. package/src/cli/args.js +357 -3
  19. package/src/cli/commands/agents.js +364 -0
  20. package/src/cli/commands/bootstrap.js +92 -0
  21. package/src/cli/commands/branch.js +127 -0
  22. package/src/cli/commands/claude.js +674 -0
  23. package/src/cli/commands/doctor.js +268 -0
  24. package/src/cli/commands/finish.js +26 -0
  25. package/src/cli/commands/mcp.js +122 -0
  26. package/src/cli/commands/misc.js +304 -0
  27. package/src/cli/commands/pr.js +439 -0
  28. package/src/cli/commands/prompt.js +92 -0
  29. package/src/cli/commands/release.js +305 -0
  30. package/src/cli/commands/report.js +244 -0
  31. package/src/cli/commands/review.js +32 -0
  32. package/src/cli/commands/setup.js +242 -0
  33. package/src/cli/commands/status.js +338 -0
  34. package/src/cli/commands/watch.js +234 -0
  35. package/src/cli/main.js +85 -3613
  36. package/src/cli/shared/repo-env.js +161 -0
  37. package/src/cli/shared/sandbox.js +417 -0
  38. package/src/cli/shared/scaffolding.js +535 -0
  39. package/src/cli/shared/toolchain-shims.js +420 -0
  40. package/src/cockpit/action-runner.js +3 -0
  41. package/src/cockpit/actions.js +80 -0
  42. package/src/cockpit/control.js +1121 -0
  43. package/src/cockpit/index.js +426 -0
  44. package/src/cockpit/kitty-layout.js +549 -0
  45. package/src/cockpit/kitty-tree.js +144 -0
  46. package/src/cockpit/logs-reader.js +182 -0
  47. package/src/cockpit/menu.js +204 -0
  48. package/src/cockpit/pane-actions.js +597 -0
  49. package/src/cockpit/pane-menu.js +387 -0
  50. package/src/cockpit/projects-finder.js +178 -0
  51. package/src/cockpit/render.js +215 -0
  52. package/src/cockpit/settings-render.js +128 -0
  53. package/src/cockpit/settings.js +124 -0
  54. package/src/cockpit/shortcuts.js +24 -0
  55. package/src/cockpit/sidebar.js +311 -0
  56. package/src/cockpit/state.js +72 -0
  57. package/src/cockpit/theme.js +128 -0
  58. package/src/cockpit/welcome.js +266 -0
  59. package/src/context.js +304 -43
  60. package/src/core/runtime.js +6 -1
  61. package/src/doctor/index.js +45 -15
  62. package/src/finish/index.js +186 -7
  63. package/src/finish/preflight.js +177 -0
  64. package/src/finish/review-gate.js +182 -0
  65. package/src/git/index.js +511 -4
  66. package/src/hooks/index.js +0 -64
  67. package/src/kitty/command.js +101 -0
  68. package/src/kitty/runtime.js +250 -0
  69. package/src/mcp/collect.js +370 -0
  70. package/src/mcp/server.js +157 -0
  71. package/src/output/index.js +68 -2
  72. package/src/pr-review.js +264 -0
  73. package/src/pr.js +381 -0
  74. package/src/sandbox/index.js +13 -2
  75. package/src/scaffold/agent-worktree-prep.js +213 -0
  76. package/src/scaffold/index.js +127 -10
  77. package/src/speckit/index.js +226 -0
  78. package/src/submodule/index.js +288 -0
  79. package/src/terminal/index.js +45 -0
  80. package/src/terminal/kitty.js +622 -0
  81. package/src/terminal/tmux.js +125 -0
  82. package/src/tmux/command.js +27 -0
  83. package/src/tmux/session.js +89 -0
  84. package/src/toolchain/index.js +20 -0
  85. package/templates/AGENTS.monorepo-apps.md +26 -0
  86. package/templates/AGENTS.multiagent-safety.md +63 -323
  87. package/templates/AGENTS.multiagent-safety.min.md +11 -0
  88. package/templates/codex/skills/gitguardex/SKILL.md +2 -0
  89. package/templates/codex/skills/gx-act/SKILL.md +82 -0
  90. package/templates/githooks/pre-commit +44 -20
  91. package/templates/github/workflows/README.md +87 -0
  92. package/templates/github/workflows/ci-full.yml +55 -0
  93. package/templates/github/workflows/ci.yml +56 -0
  94. package/templates/github/workflows/cr.yml +20 -1
  95. package/templates/scripts/agent-branch-finish.sh +519 -23
  96. package/templates/scripts/agent-branch-merge.sh +4 -1
  97. package/templates/scripts/agent-branch-start.sh +176 -24
  98. package/templates/scripts/agent-preflight.sh +115 -0
  99. package/templates/scripts/agent-worktree-prune.sh +96 -5
  100. package/templates/scripts/codex-agent.sh +41 -97
  101. package/templates/scripts/openspec/init-plan-workspace.sh +43 -0
  102. package/templates/scripts/review-bot-watch.sh +31 -2
  103. package/templates/scripts/agent-session-state.js +0 -171
  104. package/templates/scripts/install-vscode-active-agents-extension.js +0 -135
  105. package/templates/vscode/guardex-active-agents/README.md +0 -34
  106. package/templates/vscode/guardex-active-agents/extension.js +0 -3782
  107. package/templates/vscode/guardex-active-agents/fileicons/gitguardex-fileicons.json +0 -54
  108. package/templates/vscode/guardex-active-agents/fileicons/icons/agent.svg +0 -5
  109. package/templates/vscode/guardex-active-agents/fileicons/icons/branch.svg +0 -7
  110. package/templates/vscode/guardex-active-agents/fileicons/icons/config.svg +0 -4
  111. package/templates/vscode/guardex-active-agents/fileicons/icons/hook.svg +0 -4
  112. package/templates/vscode/guardex-active-agents/fileicons/icons/openspec.svg +0 -5
  113. package/templates/vscode/guardex-active-agents/fileicons/icons/plan.svg +0 -4
  114. package/templates/vscode/guardex-active-agents/fileicons/icons/spec.svg +0 -5
  115. package/templates/vscode/guardex-active-agents/icon.png +0 -0
  116. package/templates/vscode/guardex-active-agents/media/active-agents-hivemind.svg +0 -14
  117. package/templates/vscode/guardex-active-agents/package.json +0 -169
  118. package/templates/vscode/guardex-active-agents/session-schema.js +0 -1348
@@ -0,0 +1,266 @@
1
+ 'use strict';
2
+
3
+ const path = require('node:path');
4
+ const { WELCOME_SHORTCUTS } = require('./shortcuts');
5
+ const { colorize, getCockpitTheme } = require('./theme');
6
+
7
+ const DEFAULT_WIDTH = 76;
8
+ const MIN_WIDTH = 48;
9
+ const MAX_WIDTH = 88;
10
+
11
+ const DEFAULT_AGENTS = ['codex', 'claude', 'opencode', 'cursor', 'gemini'];
12
+ const GITGUARDEX_BRAND = [
13
+ ' ____ _ _ _ ___ ___ _____ __',
14
+ ' / ___|| | | | / \\ | _ \\ | _ \\ | ____|\\ \\/ /',
15
+ '| | _ | | | |/ _ \\| |_) || | | || _| \\ /',
16
+ '| |_| || |_| / ___ \\ _ < | |_| || |___ / \\',
17
+ ' \\____| \\___/_/ \\_\\_| \\_\\____/ |_____|/_/\\_\\',
18
+ ];
19
+ const GITGUARDEX_STRAPLINE = 'guarded multi-agent cockpit';
20
+
21
+ function stringValue(value, fallback = '') {
22
+ if (typeof value === 'string') {
23
+ return value.trim() || fallback;
24
+ }
25
+ if (value === null || value === undefined) {
26
+ return fallback;
27
+ }
28
+ return String(value).trim() || fallback;
29
+ }
30
+
31
+ function firstString(...values) {
32
+ for (const value of values) {
33
+ const text = stringValue(value);
34
+ if (text) {
35
+ return text;
36
+ }
37
+ }
38
+ return '';
39
+ }
40
+
41
+ function boundedWidth(settings = {}) {
42
+ const width = Number(settings.width || settings.welcomeWidth || settings.cockpitWidth);
43
+ if (!Number.isFinite(width)) {
44
+ return DEFAULT_WIDTH;
45
+ }
46
+ return Math.min(MAX_WIDTH, Math.max(MIN_WIDTH, Math.floor(width)));
47
+ }
48
+
49
+ function truncate(value, width) {
50
+ const text = stringValue(value);
51
+ if (width <= 0) {
52
+ return '';
53
+ }
54
+ if (text.length <= width) {
55
+ return text;
56
+ }
57
+ if (width <= 3) {
58
+ return text.slice(0, width);
59
+ }
60
+ return `${text.slice(0, width - 3)}...`;
61
+ }
62
+
63
+ function repoName(state = {}, settings = {}) {
64
+ const explicit = firstString(
65
+ settings.repoName,
66
+ state.repoName,
67
+ state.projectName,
68
+ state.repo,
69
+ state.name,
70
+ );
71
+ if (explicit) {
72
+ return explicit;
73
+ }
74
+
75
+ const repoPath = firstString(state.repoPath, state.repoRoot, state.agentsStatus && state.agentsStatus.repoRoot);
76
+ if (!repoPath) {
77
+ return '-';
78
+ }
79
+ return path.basename(repoPath) || repoPath;
80
+ }
81
+
82
+ function currentBranch(state = {}) {
83
+ return firstString(
84
+ state.currentBranch,
85
+ state.branch,
86
+ state.git && state.git.currentBranch,
87
+ state.agentsStatus && state.agentsStatus.currentBranch,
88
+ ) || '-';
89
+ }
90
+
91
+ function baseBranch(state = {}, settings = {}) {
92
+ return firstString(
93
+ state.baseBranch,
94
+ state.base,
95
+ settings.baseBranch,
96
+ settings.defaultBase,
97
+ state.git && state.git.baseBranch,
98
+ state.agentsStatus && state.agentsStatus.baseBranch,
99
+ ) || '-';
100
+ }
101
+
102
+ function hooksStatus(state = {}) {
103
+ const hooks = state.hooks || state.gitHooks || state.safetyHooks;
104
+ const direct = firstString(
105
+ state.hooksStatus,
106
+ state.hookStatus,
107
+ state.coreHooksPath,
108
+ state.safety && state.safety.hooksStatus,
109
+ );
110
+ if (direct) {
111
+ return direct;
112
+ }
113
+ if (typeof hooks === 'boolean') {
114
+ return hooks ? 'enabled' : 'disabled';
115
+ }
116
+ if (typeof hooks === 'string') {
117
+ return hooks.trim();
118
+ }
119
+ if (hooks && typeof hooks === 'object') {
120
+ return firstString(hooks.status, hooks.state, hooks.coreHooksPath, hooks.path, hooks.value);
121
+ }
122
+ return '';
123
+ }
124
+
125
+ function safetyStatus(state = {}) {
126
+ return firstString(
127
+ state.safetyStatus,
128
+ state.guardStatus,
129
+ state.guardexStatus,
130
+ state.safety && state.safety.status,
131
+ state.agentsStatus && state.agentsStatus.safetyStatus,
132
+ ) || 'unknown';
133
+ }
134
+
135
+ function normalizeAgentList(value) {
136
+ if (typeof value === 'string') {
137
+ return value.split(',').map((item) => item.trim()).filter(Boolean);
138
+ }
139
+ if (!Array.isArray(value)) {
140
+ return [];
141
+ }
142
+ return value
143
+ .map((agent) => {
144
+ if (typeof agent === 'string') {
145
+ return agent.trim();
146
+ }
147
+ if (agent && typeof agent === 'object') {
148
+ return firstString(agent.name, agent.agent, agent.id, agent.label);
149
+ }
150
+ return '';
151
+ })
152
+ .filter(Boolean);
153
+ }
154
+
155
+ function availableAgents(state = {}, settings = {}) {
156
+ const agents = [
157
+ ...normalizeAgentList(settings.availableAgents),
158
+ ...normalizeAgentList(settings.agents),
159
+ ...normalizeAgentList(state.availableAgents),
160
+ ...normalizeAgentList(state.agents),
161
+ ];
162
+
163
+ const source = agents.length > 0 ? agents : DEFAULT_AGENTS;
164
+ return Array.from(new Set(source)).join(', ');
165
+ }
166
+
167
+ function totalLockCount(state = {}) {
168
+ if (Number.isFinite(state.lockCount)) {
169
+ return Math.max(0, Math.floor(state.lockCount));
170
+ }
171
+ if (Array.isArray(state.locks)) {
172
+ return state.locks.length;
173
+ }
174
+ if (state.lockSummary && Number.isFinite(state.lockSummary.count)) {
175
+ return Math.max(0, Math.floor(state.lockSummary.count));
176
+ }
177
+ if (state.agentsStatus && Number.isFinite(state.agentsStatus.lockCount)) {
178
+ return Math.max(0, Math.floor(state.agentsStatus.lockCount));
179
+ }
180
+
181
+ const sessions = Array.isArray(state.sessions) ? state.sessions : [];
182
+ return sessions.reduce((count, session) => {
183
+ if (Array.isArray(session.locks)) {
184
+ return count + session.locks.length;
185
+ }
186
+ if (Number.isFinite(session.lockCount)) {
187
+ return count + Math.max(0, Math.floor(session.lockCount));
188
+ }
189
+ return count;
190
+ }, 0);
191
+ }
192
+
193
+ function row(label, value) {
194
+ return `${label.padEnd(12)} ${value}`;
195
+ }
196
+
197
+ function boxedLine(value, width) {
198
+ const innerWidth = width - 4;
199
+ const text = truncate(value, innerWidth);
200
+ return `| ${text.padEnd(innerWidth)} |`;
201
+ }
202
+
203
+ function divider(width) {
204
+ return `+${'-'.repeat(width - 2)}+`;
205
+ }
206
+
207
+ function emptyLine(width) {
208
+ return boxedLine('', width);
209
+ }
210
+
211
+ function themedBoxedLine(value, width, token, theme) {
212
+ return colorize(boxedLine(value, width), token, theme);
213
+ }
214
+
215
+ function renderWelcomePage(state = {}, settings = {}) {
216
+ const width = boundedWidth(settings);
217
+ const theme = getCockpitTheme(settings.theme || state.theme, settings);
218
+ const hooks = hooksStatus(state);
219
+ const lines = [
220
+ colorize(divider(width), 'border', theme),
221
+ themedBoxedLine('gitguardex | gx cockpit', width, 'title', theme),
222
+ themedBoxedLine('Guardian cockpit ready. No active agent lanes.', width, 'secondary', theme),
223
+ emptyLine(width),
224
+ ];
225
+
226
+ GITGUARDEX_BRAND.forEach((brandLine) => {
227
+ lines.push(themedBoxedLine(brandLine, width, 'accent', theme));
228
+ });
229
+ lines.push(
230
+ emptyLine(width),
231
+ themedBoxedLine(GITGUARDEX_STRAPLINE, width, 'heading', theme),
232
+ );
233
+
234
+ lines.push(
235
+ emptyLine(width),
236
+ themedBoxedLine(row('Repo:', repoName(state, settings)), width, 'secondary', theme),
237
+ themedBoxedLine(row('Branch:', `${currentBranch(state)} (base ${baseBranch(state, settings)})`), width, 'secondary', theme),
238
+ themedBoxedLine(row('Safety:', safetyStatus(state)), width, 'success', theme),
239
+ );
240
+
241
+ if (hooks) {
242
+ lines.push(themedBoxedLine(row('Hooks:', hooks), width, 'secondary', theme));
243
+ }
244
+
245
+ lines.push(
246
+ themedBoxedLine(row('Locks:', String(totalLockCount(state))), width, 'accent', theme),
247
+ themedBoxedLine(row('Agents:', availableAgents(state, settings)), width, 'secondary', theme),
248
+ emptyLine(width),
249
+ themedBoxedLine('Shortcuts', width, 'heading', theme),
250
+ ...WELCOME_SHORTCUTS.map(([key, label]) => themedBoxedLine(` ${key} ${label}`, width, 'secondary', theme)),
251
+ emptyLine(width),
252
+ themedBoxedLine('Next actions', width, 'heading', theme),
253
+ themedBoxedLine(' n new agent - start a guarded agent lane', width, 'secondary', theme),
254
+ themedBoxedLine(' t terminal - open a repo terminal', width, 'secondary', theme),
255
+ themedBoxedLine(' l logs - tail apps/logs/*.log and lane events', width, 'secondary', theme),
256
+ themedBoxedLine(' p projects - switch repo (no lane selected)', width, 'secondary', theme),
257
+ themedBoxedLine(' s settings - tune cockpit defaults', width, 'secondary', theme),
258
+ colorize(divider(width), 'border', theme),
259
+ );
260
+
261
+ return `${lines.join('\n')}\n`;
262
+ }
263
+
264
+ module.exports = {
265
+ renderWelcomePage,
266
+ };