@antistud/handrails-cli 0.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 (92) hide show
  1. package/dist/bin/handrails-rig.d.ts +9 -0
  2. package/dist/bin/handrails-rig.js +19 -0
  3. package/dist/bin/handrails-rig.js.map +1 -0
  4. package/dist/bin/handrails.d.ts +2 -0
  5. package/dist/bin/handrails.js +10 -0
  6. package/dist/bin/handrails.js.map +1 -0
  7. package/dist/src/bridge/daemon.d.ts +50 -0
  8. package/dist/src/bridge/daemon.js +319 -0
  9. package/dist/src/bridge/daemon.js.map +1 -0
  10. package/dist/src/claude/context-manager.d.ts +41 -0
  11. package/dist/src/claude/context-manager.js +184 -0
  12. package/dist/src/claude/context-manager.js.map +1 -0
  13. package/dist/src/claude/reader.d.ts +17 -0
  14. package/dist/src/claude/reader.js +186 -0
  15. package/dist/src/claude/reader.js.map +1 -0
  16. package/dist/src/cli/commands/config.d.ts +2 -0
  17. package/dist/src/cli/commands/config.js +59 -0
  18. package/dist/src/cli/commands/config.js.map +1 -0
  19. package/dist/src/cli/commands/context.d.ts +2 -0
  20. package/dist/src/cli/commands/context.js +158 -0
  21. package/dist/src/cli/commands/context.js.map +1 -0
  22. package/dist/src/cli/commands/daemon.d.ts +2 -0
  23. package/dist/src/cli/commands/daemon.js +29 -0
  24. package/dist/src/cli/commands/daemon.js.map +1 -0
  25. package/dist/src/cli/commands/init.d.ts +2 -0
  26. package/dist/src/cli/commands/init.js +197 -0
  27. package/dist/src/cli/commands/init.js.map +1 -0
  28. package/dist/src/cli/commands/login.d.ts +2 -0
  29. package/dist/src/cli/commands/login.js +87 -0
  30. package/dist/src/cli/commands/login.js.map +1 -0
  31. package/dist/src/cli/commands/rig.d.ts +2 -0
  32. package/dist/src/cli/commands/rig.js +49 -0
  33. package/dist/src/cli/commands/rig.js.map +1 -0
  34. package/dist/src/cli/commands/status.d.ts +2 -0
  35. package/dist/src/cli/commands/status.js +119 -0
  36. package/dist/src/cli/commands/status.js.map +1 -0
  37. package/dist/src/cli/commands/sync.d.ts +2 -0
  38. package/dist/src/cli/commands/sync.js +149 -0
  39. package/dist/src/cli/commands/sync.js.map +1 -0
  40. package/dist/src/cli/index.d.ts +2 -0
  41. package/dist/src/cli/index.js +62 -0
  42. package/dist/src/cli/index.js.map +1 -0
  43. package/dist/src/config/index.d.ts +20 -0
  44. package/dist/src/config/index.js +131 -0
  45. package/dist/src/config/index.js.map +1 -0
  46. package/dist/src/config/schema.d.ts +59 -0
  47. package/dist/src/config/schema.js +14 -0
  48. package/dist/src/config/schema.js.map +1 -0
  49. package/dist/src/handrails/auth.d.ts +15 -0
  50. package/dist/src/handrails/auth.js +80 -0
  51. package/dist/src/handrails/auth.js.map +1 -0
  52. package/dist/src/handrails/client.d.ts +100 -0
  53. package/dist/src/handrails/client.js +135 -0
  54. package/dist/src/handrails/client.js.map +1 -0
  55. package/dist/src/index.d.ts +5 -0
  56. package/dist/src/index.js +34 -0
  57. package/dist/src/index.js.map +1 -0
  58. package/dist/src/mcp/server.d.ts +10 -0
  59. package/dist/src/mcp/server.js +167 -0
  60. package/dist/src/mcp/server.js.map +1 -0
  61. package/dist/src/mcp/tools/context-tools.d.ts +8 -0
  62. package/dist/src/mcp/tools/context-tools.js +111 -0
  63. package/dist/src/mcp/tools/context-tools.js.map +1 -0
  64. package/dist/src/mcp/tools/sync-tools.d.ts +9 -0
  65. package/dist/src/mcp/tools/sync-tools.js +170 -0
  66. package/dist/src/mcp/tools/sync-tools.js.map +1 -0
  67. package/dist/src/runner/executor.d.ts +8 -0
  68. package/dist/src/runner/executor.js +39 -0
  69. package/dist/src/runner/executor.js.map +1 -0
  70. package/dist/src/runner/executors/claude-code.d.ts +7 -0
  71. package/dist/src/runner/executors/claude-code.js +247 -0
  72. package/dist/src/runner/executors/claude-code.js.map +1 -0
  73. package/dist/src/runner/executors/codex.d.ts +9 -0
  74. package/dist/src/runner/executors/codex.js +72 -0
  75. package/dist/src/runner/executors/codex.js.map +1 -0
  76. package/dist/src/runner/executors/opencode.d.ts +9 -0
  77. package/dist/src/runner/executors/opencode.js +71 -0
  78. package/dist/src/runner/executors/opencode.js.map +1 -0
  79. package/dist/src/runner/executors/types.d.ts +24 -0
  80. package/dist/src/runner/executors/types.js +27 -0
  81. package/dist/src/runner/executors/types.js.map +1 -0
  82. package/dist/src/runner/index.d.ts +34 -0
  83. package/dist/src/runner/index.js +234 -0
  84. package/dist/src/runner/index.js.map +1 -0
  85. package/dist/src/runner/logger.d.ts +14 -0
  86. package/dist/src/runner/logger.js +35 -0
  87. package/dist/src/runner/logger.js.map +1 -0
  88. package/dist/src/workflow/engine.d.ts +44 -0
  89. package/dist/src/workflow/engine.js +383 -0
  90. package/dist/src/workflow/engine.js.map +1 -0
  91. package/dist/tsconfig.tsbuildinfo +1 -0
  92. package/package.json +46 -0
@@ -0,0 +1,197 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.registerInitCommand = registerInitCommand;
40
+ const chalk_1 = __importDefault(require("chalk"));
41
+ const ora_1 = __importDefault(require("ora"));
42
+ const path = __importStar(require("path"));
43
+ const fs = __importStar(require("fs"));
44
+ const config_1 = require("../../config");
45
+ const reader_1 = require("../../claude/reader");
46
+ const context_manager_1 = require("../../claude/context-manager");
47
+ const readline = __importStar(require("readline"));
48
+ function prompt(question) {
49
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
50
+ return new Promise(resolve => {
51
+ rl.question(question, answer => {
52
+ rl.close();
53
+ resolve(answer.trim());
54
+ });
55
+ });
56
+ }
57
+ function registerInitCommand(program) {
58
+ program
59
+ .command('init')
60
+ .description('Set up Handrails for the current project')
61
+ .option('--project-tag <tag>', 'Tag to associate this project with in Handrails')
62
+ .option('--team <teamId>', 'Team ID to associate with this project')
63
+ .option('--skip-hooks', 'Skip installing Claude Code hooks')
64
+ .option('--skip-context', 'Skip pulling team context')
65
+ .action(async (options) => {
66
+ const projectPath = process.cwd();
67
+ const projectName = path.basename(projectPath);
68
+ console.log(chalk_1.default.bold(`\nInitializing Handrails for ${chalk_1.default.cyan(projectName)}\n`));
69
+ // Step 1: Check authentication
70
+ if (!(0, config_1.isAuthenticated)()) {
71
+ console.log(chalk_1.default.red('Not authenticated. Run "handrails login" first.'));
72
+ process.exit(1);
73
+ }
74
+ // Step 2: Select team
75
+ const teams = (0, config_1.getAuthenticatedTeams)();
76
+ let selectedTeam;
77
+ if (options.team) {
78
+ const match = teams.find(t => t.teamId === options.team);
79
+ if (!match) {
80
+ console.log(chalk_1.default.red(`Team "${options.team}" not found. Authenticated teams:`));
81
+ teams.forEach(t => console.log(chalk_1.default.dim(` ${t.teamName} (${t.teamId})`)));
82
+ process.exit(1);
83
+ }
84
+ selectedTeam = match;
85
+ }
86
+ else if (teams.length === 1) {
87
+ selectedTeam = teams[0];
88
+ }
89
+ else if (teams.length > 1) {
90
+ // Multiple teams — prompt the user to pick one
91
+ console.log(chalk_1.default.bold('Select a team for this project:\n'));
92
+ teams.forEach((t, i) => {
93
+ console.log(` ${chalk_1.default.cyan(`${i + 1})`)} ${t.teamName} ${chalk_1.default.dim(`(${t.teamId})`)}`);
94
+ });
95
+ console.log('');
96
+ const choice = await prompt(`Team number [1]: `);
97
+ const idx = (parseInt(choice) || 1) - 1;
98
+ if (idx < 0 || idx >= teams.length) {
99
+ console.log(chalk_1.default.red('Invalid selection.'));
100
+ process.exit(1);
101
+ }
102
+ selectedTeam = teams[idx];
103
+ }
104
+ else {
105
+ console.log(chalk_1.default.red('No authenticated teams found. Run "handrails login" first.'));
106
+ process.exit(1);
107
+ }
108
+ console.log(chalk_1.default.green(` Team: ${selectedTeam.teamName} (${selectedTeam.teamId})`));
109
+ // Step 3: Set project tag
110
+ const projectTag = options.projectTag || await prompt(`Project tag [${projectName}]: `) || projectName;
111
+ (0, config_1.setProjectConfig)(projectPath, {
112
+ projectTag,
113
+ teamId: selectedTeam.teamId,
114
+ lastSync: null,
115
+ });
116
+ console.log(chalk_1.default.green(` Project tag: ${projectTag}`));
117
+ // Step 4: Configure MCP server
118
+ const spinner = (0, ora_1.default)('Configuring MCP server...').start();
119
+ const mcpConfigPath = path.join(projectPath, '.mcp.json');
120
+ let mcpConfig = {};
121
+ if (fs.existsSync(mcpConfigPath)) {
122
+ try {
123
+ mcpConfig = JSON.parse(fs.readFileSync(mcpConfigPath, 'utf-8'));
124
+ }
125
+ catch { /* start fresh */ }
126
+ }
127
+ if (!mcpConfig.mcpServers)
128
+ mcpConfig.mcpServers = {};
129
+ mcpConfig.mcpServers['handrails-local'] = {
130
+ command: 'handrails',
131
+ args: ['serve'],
132
+ env: {
133
+ HANDRAILS_PROJECT_PATH: projectPath,
134
+ },
135
+ };
136
+ fs.writeFileSync(mcpConfigPath, JSON.stringify(mcpConfig, null, 2), 'utf-8');
137
+ spinner.succeed('MCP server configured in .mcp.json');
138
+ // Step 5: Install hooks (optional)
139
+ if (!options.skipHooks) {
140
+ const installHooks = await prompt('Install Claude Code hooks for automatic session tracking? (Y/n): ');
141
+ if (installHooks.toLowerCase() !== 'n') {
142
+ const hookSpinner = (0, ora_1.default)('Installing hooks...').start();
143
+ if ((0, reader_1.claudeDirExists)()) {
144
+ const settings = (0, reader_1.getClaudeSettings)() || {};
145
+ if (!settings.hooks)
146
+ settings.hooks = {};
147
+ const stopHooks = settings.hooks.Stop || [];
148
+ const hasHandrailsHook = stopHooks.some((h) => typeof h === 'object' && h.command?.includes('handrails'));
149
+ if (!hasHandrailsHook) {
150
+ stopHooks.push({ command: 'handrails hook-stop' });
151
+ settings.hooks.Stop = stopHooks;
152
+ (0, reader_1.saveClaudeSettings)(settings);
153
+ }
154
+ hookSpinner.succeed('Claude Code hooks installed');
155
+ const config = (0, config_1.loadConfig)();
156
+ config.hooksInstalled = true;
157
+ (0, config_1.saveConfig)(config);
158
+ }
159
+ else {
160
+ hookSpinner.warn('~/.claude/ not found — hooks will be installed when Claude Code runs');
161
+ }
162
+ }
163
+ }
164
+ // Step 6: Pull team context (optional)
165
+ if (!options.skipContext) {
166
+ const contextSpinner = (0, ora_1.default)('Pulling team context...').start();
167
+ try {
168
+ const result = await (0, context_manager_1.pullContext)(projectPath);
169
+ if (result.templateFound) {
170
+ contextSpinner.succeed(`Team CLAUDE.md template applied to ${result.path}`);
171
+ }
172
+ else {
173
+ contextSpinner.info('No team CLAUDE.md template found (you can push one with "handrails context push")');
174
+ }
175
+ const cmdSpinner = (0, ora_1.default)('Syncing slash commands...').start();
176
+ const cmdResult = await (0, context_manager_1.syncSlashCommands)('pull');
177
+ if (cmdResult.pulled > 0) {
178
+ cmdSpinner.succeed(`Synced ${cmdResult.pulled} team slash commands`);
179
+ }
180
+ else {
181
+ cmdSpinner.info('No team slash commands to sync');
182
+ }
183
+ }
184
+ catch (err) {
185
+ contextSpinner.warn(`Could not pull team context: ${err.message}`);
186
+ }
187
+ }
188
+ // Done
189
+ console.log(chalk_1.default.bold.green('\nHandrails initialized!\n'));
190
+ console.log(chalk_1.default.dim('Next steps:'));
191
+ console.log(chalk_1.default.dim(' - Claude Code will now use the handrails-local MCP server'));
192
+ console.log(chalk_1.default.dim(' - Run "handrails context push" to share your CLAUDE.md with the team'));
193
+ console.log(chalk_1.default.dim(' - Run "handrails status" to check your setup'));
194
+ console.log('');
195
+ });
196
+ }
197
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../../../src/cli/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerLoginCommand(program: Command): void;
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.registerLoginCommand = registerLoginCommand;
40
+ const chalk_1 = __importDefault(require("chalk"));
41
+ const ora_1 = __importDefault(require("ora"));
42
+ const auth_1 = require("../../handrails/auth");
43
+ const readline = __importStar(require("readline"));
44
+ function prompt(question) {
45
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
46
+ return new Promise(resolve => {
47
+ rl.question(question, answer => {
48
+ rl.close();
49
+ resolve(answer.trim());
50
+ });
51
+ });
52
+ }
53
+ function registerLoginCommand(program) {
54
+ program
55
+ .command('login')
56
+ .description('Authenticate with your Handrails API key')
57
+ .option('--api-key <key>', 'API key (or enter interactively)')
58
+ .option('--api-url <url>', 'Handrails API URL (default: https://mcp.handrails.dev)')
59
+ .action(async (options) => {
60
+ const status = (0, auth_1.getAuthStatus)();
61
+ if (status.authenticated) {
62
+ console.log(chalk_1.default.yellow(`Already authenticated as team "${status.teamName}" (${status.teamId})`));
63
+ const answer = await prompt('Re-authenticate? (y/N): ');
64
+ if (answer.toLowerCase() !== 'y')
65
+ return;
66
+ }
67
+ let apiKey = options.apiKey;
68
+ if (!apiKey) {
69
+ console.log(chalk_1.default.dim('Get your API key at: https://handrails.dev/api-keys'));
70
+ apiKey = await prompt('Enter your Handrails API key: ');
71
+ }
72
+ if (!apiKey) {
73
+ console.log(chalk_1.default.red('No API key provided.'));
74
+ process.exit(1);
75
+ }
76
+ const spinner = (0, ora_1.default)('Validating API key...').start();
77
+ const result = await (0, auth_1.login)(apiKey, options.apiUrl);
78
+ if (result.success) {
79
+ spinner.succeed(chalk_1.default.green(`Authenticated! Team: ${result.teamName} (${result.teamId})`));
80
+ }
81
+ else {
82
+ spinner.fail(chalk_1.default.red(`Authentication failed: ${result.error}`));
83
+ process.exit(1);
84
+ }
85
+ });
86
+ }
87
+ //# sourceMappingURL=login.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login.js","sourceRoot":"","sources":["../../../../src/cli/commands/login.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiBA,oDAoCC;AApDD,kDAA0B;AAC1B,8CAAsB;AACtB,+CAA4D;AAE5D,mDAAqC;AAErC,SAAS,MAAM,CAAC,QAAgB;IAC9B,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACtF,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;QAC3B,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,EAAE;YAC7B,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAgB,oBAAoB,CAAC,OAAgB;IACnD,OAAO;SACJ,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,0CAA0C,CAAC;SACvD,MAAM,CAAC,iBAAiB,EAAE,kCAAkC,CAAC;SAC7D,MAAM,CAAC,iBAAiB,EAAE,wDAAwD,CAAC;SACnF,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QACxB,MAAM,MAAM,GAAG,IAAA,oBAAa,GAAE,CAAC;QAC/B,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,MAAM,CAAC,kCAAkC,MAAM,CAAC,QAAQ,MAAM,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;YACnG,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,0BAA0B,CAAC,CAAC;YACxD,IAAI,MAAM,CAAC,WAAW,EAAE,KAAK,GAAG;gBAAE,OAAO;QAC3C,CAAC;QAED,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC5B,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC,CAAC;YAC9E,MAAM,GAAG,MAAM,MAAM,CAAC,gCAAgC,CAAC,CAAC;QAC1D,CAAC;QAED,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,CAAC,GAAG,CAAC,eAAK,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC,CAAC;YAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,OAAO,GAAG,IAAA,aAAG,EAAC,uBAAuB,CAAC,CAAC,KAAK,EAAE,CAAC;QAErD,MAAM,MAAM,GAAG,MAAM,IAAA,YAAK,EAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QAEnD,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO,CAAC,OAAO,CAAC,eAAK,CAAC,KAAK,CAAC,wBAAwB,MAAM,CAAC,QAAQ,KAAK,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC7F,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,IAAI,CAAC,eAAK,CAAC,GAAG,CAAC,0BAA0B,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YAClE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerRigCommand(program: Command): void;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerRigCommand = registerRigCommand;
4
+ const config_1 = require("../../config");
5
+ const runner_1 = require("../../runner");
6
+ const VALID_RIG_TYPES = ['claude-code', 'opencode', 'codex'];
7
+ function registerRigCommand(program) {
8
+ program
9
+ .command('rig')
10
+ .description('Start a rig — a stateless executor that mounts agents and runs tasks')
11
+ .option('--api-url <url>', 'Override Handrails API URL')
12
+ .option('--rig-key <key>', 'Rig key (from dashboard)')
13
+ .option('--rig-type <type>', `CLI executor to use (${VALID_RIG_TYPES.join(', ')})`)
14
+ .option('--project <path>', 'Project directory (default: current directory)', '.')
15
+ .option('--interval <ms>', 'Heartbeat interval in milliseconds', '10000')
16
+ .action(async (options) => {
17
+ const rigKey = options.rigKey || process.env.HANDRAILS_RIG_KEY;
18
+ if (!rigKey && !(0, config_1.isAuthenticated)()) {
19
+ console.error('Provide a rig key via --rig-key, HANDRAILS_RIG_KEY env var, or run "handrails login" first.');
20
+ process.exit(1);
21
+ }
22
+ const rigType = options.rigType;
23
+ if (rigType && !VALID_RIG_TYPES.includes(rigType)) {
24
+ console.error(`Invalid --rig-type "${rigType}". Must be one of: ${VALID_RIG_TYPES.join(', ')}`);
25
+ process.exit(1);
26
+ }
27
+ const config = (0, config_1.loadConfig)();
28
+ const apiUrl = options.apiUrl || process.env.HANDRAILS_API_URL || config.apiUrl;
29
+ const key = rigKey || config.apiKey;
30
+ console.log('');
31
+ console.log(' Handrails Rig');
32
+ console.log(' ============');
33
+ console.log(' "Agents think. Rigs act. Harness keeps everything on track."');
34
+ console.log('');
35
+ console.log(` Server: ${apiUrl}`);
36
+ console.log(` Type: ${rigType || '(from server config)'}`);
37
+ console.log(` Project: ${options.project}`);
38
+ console.log('');
39
+ const rig = new runner_1.AgentRig({
40
+ apiUrl,
41
+ rigKey: key,
42
+ projectPath: options.project,
43
+ heartbeatInterval: parseInt(options.interval),
44
+ rigType,
45
+ });
46
+ await rig.start();
47
+ });
48
+ }
49
+ //# sourceMappingURL=rig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rig.js","sourceRoot":"","sources":["../../../../src/cli/commands/rig.ts"],"names":[],"mappings":";;AAOA,gDA8CC;AApDD,yCAA2D;AAC3D,yCAAwC;AAGxC,MAAM,eAAe,GAAc,CAAC,aAAa,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;AAExE,SAAgB,kBAAkB,CAAC,OAAgB;IACjD,OAAO;SACJ,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,sEAAsE,CAAC;SACnF,MAAM,CAAC,iBAAiB,EAAE,4BAA4B,CAAC;SACvD,MAAM,CAAC,iBAAiB,EAAE,0BAA0B,CAAC;SACrD,MAAM,CAAC,mBAAmB,EAAE,wBAAwB,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;SAClF,MAAM,CAAC,kBAAkB,EAAE,gDAAgD,EAAE,GAAG,CAAC;SACjF,MAAM,CAAC,iBAAiB,EAAE,oCAAoC,EAAE,OAAO,CAAC;SACxE,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;QACxB,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;QAC/D,IAAI,CAAC,MAAM,IAAI,CAAC,IAAA,wBAAe,GAAE,EAAE,CAAC;YAClC,OAAO,CAAC,KAAK,CAAC,6FAA6F,CAAC,CAAC;YAC7G,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,OAAO,GAAwB,OAAO,CAAC,OAAO,CAAC;QACrD,IAAI,OAAO,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAClD,OAAO,CAAC,KAAK,CAAC,uBAAuB,OAAO,sBAAsB,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAChG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,MAAM,GAAG,IAAA,mBAAU,GAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,MAAM,CAAC,MAAM,CAAC;QAChF,MAAM,GAAG,GAAG,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC;QAEpC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,gEAAgE,CAAC,CAAC;QAC9E,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,cAAc,MAAM,EAAE,CAAC,CAAC;QACpC,OAAO,CAAC,GAAG,CAAC,cAAc,OAAO,IAAI,sBAAsB,EAAE,CAAC,CAAC;QAC/D,OAAO,CAAC,GAAG,CAAC,cAAc,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;QAC7C,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEhB,MAAM,GAAG,GAAG,IAAI,iBAAQ,CAAC;YACvB,MAAM;YACN,MAAM,EAAE,GAAG;YACX,WAAW,EAAE,OAAO,CAAC,OAAO;YAC5B,iBAAiB,EAAE,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC;YAC7C,OAAO;SACR,CAAC,CAAC;QAEH,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC;IACpB,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerStatusCommand(program: Command): void;
@@ -0,0 +1,119 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.registerStatusCommand = registerStatusCommand;
40
+ const chalk_1 = __importDefault(require("chalk"));
41
+ const path = __importStar(require("path"));
42
+ const config_1 = require("../../config");
43
+ const auth_1 = require("../../handrails/auth");
44
+ const reader_1 = require("../../claude/reader");
45
+ function registerStatusCommand(program) {
46
+ program
47
+ .command('status')
48
+ .description('Show Handrails configuration and connection status')
49
+ .action(async () => {
50
+ const config = (0, config_1.loadConfig)();
51
+ const auth = (0, auth_1.getAuthStatus)();
52
+ const teams = (0, config_1.getAuthenticatedTeams)();
53
+ const projectPath = process.cwd();
54
+ const projectName = path.basename(projectPath);
55
+ const projectConfig = (0, config_1.getProjectConfig)(projectPath);
56
+ console.log(chalk_1.default.bold('\nHandrails Status\n'));
57
+ // Auth
58
+ console.log(chalk_1.default.bold('Authentication'));
59
+ if (auth.authenticated) {
60
+ console.log(chalk_1.default.green(` Authenticated: Yes`));
61
+ console.log(` Default Team: ${auth.teamName} (${auth.teamId})`);
62
+ if (teams.length > 1) {
63
+ console.log(` Teams: ${teams.length} authenticated`);
64
+ teams.forEach(t => {
65
+ const isDefault = t.teamId === auth.teamId ? chalk_1.default.dim(' (default)') : '';
66
+ console.log(` - ${t.teamName} (${t.teamId})${isDefault}`);
67
+ });
68
+ }
69
+ console.log(` API URL: ${auth.apiUrl}`);
70
+ }
71
+ else {
72
+ console.log(chalk_1.default.red(' Authenticated: No'));
73
+ console.log(chalk_1.default.dim(' Run "handrails login" to authenticate'));
74
+ }
75
+ console.log('');
76
+ // Project
77
+ console.log(chalk_1.default.bold(`Project: ${projectName}`));
78
+ if (projectConfig) {
79
+ console.log(` Tag: ${projectConfig.projectTag}`);
80
+ if (projectConfig.teamId) {
81
+ const team = teams.find(t => t.teamId === projectConfig.teamId);
82
+ console.log(` Team: ${team?.teamName || projectConfig.teamId}`);
83
+ }
84
+ else {
85
+ console.log(` Team: ${chalk_1.default.dim('using default')}`);
86
+ }
87
+ console.log(` Last Sync: ${projectConfig.lastSync || 'Never'}`);
88
+ }
89
+ else {
90
+ console.log(chalk_1.default.dim(' Not initialized. Run "handrails init"'));
91
+ }
92
+ console.log('');
93
+ // Claude Code
94
+ console.log(chalk_1.default.bold('Claude Code'));
95
+ console.log(` ~/.claude/ exists: ${(0, reader_1.claudeDirExists)() ? chalk_1.default.green('Yes') : chalk_1.default.red('No')}`);
96
+ const claudeMd = (0, reader_1.getProjectClaudeMd)(projectPath);
97
+ console.log(` CLAUDE.md: ${claudeMd ? chalk_1.default.green('Found') : chalk_1.default.dim('Not found')}`);
98
+ const commands = (0, reader_1.getSlashCommands)();
99
+ console.log(` Slash commands: ${commands.length} local`);
100
+ const sessions = (0, reader_1.getRecentSessions)(projectPath, 5);
101
+ console.log(` Recent sessions: ${sessions.length}`);
102
+ if (sessions.length > 0) {
103
+ const latest = sessions[0];
104
+ console.log(chalk_1.default.dim(` Latest: "${latest.firstPrompt?.substring(0, 60)}..." (${latest.modified})`));
105
+ }
106
+ console.log('');
107
+ // Hooks
108
+ console.log(chalk_1.default.bold('Hooks'));
109
+ console.log(` Installed: ${config.hooksInstalled ? chalk_1.default.green('Yes') : chalk_1.default.dim('No')}`);
110
+ console.log('');
111
+ // MCP Server
112
+ const mcpConfigPath = path.join(projectPath, '.mcp.json');
113
+ const hasMcpConfig = require('fs').existsSync(mcpConfigPath);
114
+ console.log(chalk_1.default.bold('MCP Server'));
115
+ console.log(` .mcp.json: ${hasMcpConfig ? chalk_1.default.green('Configured') : chalk_1.default.dim('Not configured')}`);
116
+ console.log('');
117
+ });
118
+ }
119
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../../../src/cli/commands/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerSyncCommand(program: Command): void;
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.registerSyncCommand = registerSyncCommand;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const config_1 = require("../../config");
40
+ const client_1 = require("../../handrails/client");
41
+ function registerSyncCommand(program) {
42
+ program
43
+ .command('sync')
44
+ .description('Sync team MCP server configs to your local environment')
45
+ .option('--project-dir <dir>', 'Project directory (defaults to cwd)')
46
+ .option('--dry-run', 'Show what would change without writing files')
47
+ .action(async (options) => {
48
+ if (!(0, config_1.isAuthenticated)()) {
49
+ console.error('Not authenticated. Run "handrails login" first.');
50
+ process.exit(1);
51
+ }
52
+ const config = (0, config_1.loadConfig)();
53
+ const client = new client_1.HandrailsClient(config.apiUrl, config.apiKey);
54
+ const projectDir = options.projectDir || process.cwd();
55
+ const mcpJsonPath = path.join(projectDir, '.mcp.json');
56
+ console.log('Syncing team MCP servers...');
57
+ console.log(`Team: ${config.teamName || 'unknown'}`);
58
+ console.log('');
59
+ // Fetch team MCP configs
60
+ let servers;
61
+ try {
62
+ servers = await client.getTeamMcpServers();
63
+ }
64
+ catch (error) {
65
+ console.error('Failed to fetch team MCP servers:', error.message);
66
+ process.exit(1);
67
+ }
68
+ if (servers.length === 0) {
69
+ console.log('No MCP servers configured for your team.');
70
+ console.log('Team admins can add MCP servers at https://handrails.dev');
71
+ return;
72
+ }
73
+ console.log(`Found ${servers.length} team MCP server(s):`);
74
+ for (const server of servers) {
75
+ console.log(` - ${server.name} (${server.package_name})`);
76
+ }
77
+ console.log('');
78
+ // Load existing .mcp.json or start fresh
79
+ let mcpJson = { mcpServers: {} };
80
+ if (fs.existsSync(mcpJsonPath)) {
81
+ try {
82
+ mcpJson = JSON.parse(fs.readFileSync(mcpJsonPath, 'utf-8'));
83
+ if (!mcpJson.mcpServers)
84
+ mcpJson.mcpServers = {};
85
+ }
86
+ catch {
87
+ console.warn('Warning: existing .mcp.json is invalid, starting fresh');
88
+ }
89
+ }
90
+ // Check required env vars
91
+ const missingEnv = [];
92
+ for (const server of servers) {
93
+ // Build the MCP server entry
94
+ const args = [...server.args];
95
+ // If command is npx, prepend the package name
96
+ if (server.command === 'npx' && !args.includes(server.package_name)) {
97
+ args.unshift('-y', server.package_name + (server.version ? `@${server.version}` : ''));
98
+ }
99
+ const entry = {
100
+ command: server.command,
101
+ args,
102
+ _managed: 'handrails',
103
+ };
104
+ // Check required env vars
105
+ if (server.required_env?.length) {
106
+ const env = {};
107
+ for (const envVar of server.required_env) {
108
+ const value = process.env[envVar.name] || envVar.default || '';
109
+ if (envVar.required && !value) {
110
+ missingEnv.push({
111
+ server: server.name,
112
+ envVar: envVar.name,
113
+ description: envVar.description,
114
+ });
115
+ }
116
+ if (value) {
117
+ env[envVar.name] = value;
118
+ }
119
+ else {
120
+ // Use placeholder so user knows to fill it in
121
+ env[envVar.name] = `<set ${envVar.name}>`;
122
+ }
123
+ }
124
+ entry.env = env;
125
+ }
126
+ mcpJson.mcpServers[server.name] = entry;
127
+ }
128
+ if (options.dryRun) {
129
+ console.log('Dry run - would write the following .mcp.json:');
130
+ console.log(JSON.stringify(mcpJson, null, 2));
131
+ }
132
+ else {
133
+ fs.writeFileSync(mcpJsonPath, JSON.stringify(mcpJson, null, 2) + '\n', 'utf-8');
134
+ console.log(`Written to ${mcpJsonPath}`);
135
+ }
136
+ if (missingEnv.length > 0) {
137
+ console.log('');
138
+ console.log('Missing required environment variables:');
139
+ for (const missing of missingEnv) {
140
+ console.log(` ${missing.server}: ${missing.envVar}${missing.description ? ` - ${missing.description}` : ''}`);
141
+ }
142
+ console.log('');
143
+ console.log('Set these in your environment or update the env values in .mcp.json');
144
+ }
145
+ console.log('');
146
+ console.log('Sync complete.');
147
+ });
148
+ }
149
+ //# sourceMappingURL=sync.js.map