genesis-ai-cli 7.4.5

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 (227) hide show
  1. package/.env.example +78 -0
  2. package/README.md +282 -0
  3. package/dist/src/active-inference/actions.d.ts +75 -0
  4. package/dist/src/active-inference/actions.js +250 -0
  5. package/dist/src/active-inference/autonomous-loop.d.ts +103 -0
  6. package/dist/src/active-inference/autonomous-loop.js +289 -0
  7. package/dist/src/active-inference/core.d.ts +85 -0
  8. package/dist/src/active-inference/core.js +555 -0
  9. package/dist/src/active-inference/demo-autonomous-loop.d.ts +8 -0
  10. package/dist/src/active-inference/demo-autonomous-loop.js +338 -0
  11. package/dist/src/active-inference/demo-value-integration.d.ts +8 -0
  12. package/dist/src/active-inference/demo-value-integration.js +174 -0
  13. package/dist/src/active-inference/index.d.ts +32 -0
  14. package/dist/src/active-inference/index.js +88 -0
  15. package/dist/src/active-inference/integration.d.ts +114 -0
  16. package/dist/src/active-inference/integration.js +698 -0
  17. package/dist/src/active-inference/memory-integration.d.ts +51 -0
  18. package/dist/src/active-inference/memory-integration.js +232 -0
  19. package/dist/src/active-inference/observations.d.ts +67 -0
  20. package/dist/src/active-inference/observations.js +147 -0
  21. package/dist/src/active-inference/test-active-inference.d.ts +8 -0
  22. package/dist/src/active-inference/test-active-inference.js +320 -0
  23. package/dist/src/active-inference/test-value-integration.d.ts +6 -0
  24. package/dist/src/active-inference/test-value-integration.js +168 -0
  25. package/dist/src/active-inference/types.d.ts +150 -0
  26. package/dist/src/active-inference/types.js +59 -0
  27. package/dist/src/active-inference/value-integration.d.ts +164 -0
  28. package/dist/src/active-inference/value-integration.js +459 -0
  29. package/dist/src/agents/base-agent.d.ts +53 -0
  30. package/dist/src/agents/base-agent.js +178 -0
  31. package/dist/src/agents/builder.d.ts +67 -0
  32. package/dist/src/agents/builder.js +537 -0
  33. package/dist/src/agents/critic.d.ts +35 -0
  34. package/dist/src/agents/critic.js +322 -0
  35. package/dist/src/agents/ethicist.d.ts +54 -0
  36. package/dist/src/agents/ethicist.js +393 -0
  37. package/dist/src/agents/explorer.d.ts +26 -0
  38. package/dist/src/agents/explorer.js +216 -0
  39. package/dist/src/agents/feeling.d.ts +41 -0
  40. package/dist/src/agents/feeling.js +320 -0
  41. package/dist/src/agents/index.d.ts +111 -0
  42. package/dist/src/agents/index.js +222 -0
  43. package/dist/src/agents/memory.d.ts +69 -0
  44. package/dist/src/agents/memory.js +404 -0
  45. package/dist/src/agents/message-bus.d.ts +88 -0
  46. package/dist/src/agents/message-bus.js +267 -0
  47. package/dist/src/agents/narrator.d.ts +90 -0
  48. package/dist/src/agents/narrator.js +473 -0
  49. package/dist/src/agents/planner.d.ts +38 -0
  50. package/dist/src/agents/planner.js +341 -0
  51. package/dist/src/agents/predictor.d.ts +73 -0
  52. package/dist/src/agents/predictor.js +506 -0
  53. package/dist/src/agents/sensor.d.ts +88 -0
  54. package/dist/src/agents/sensor.js +377 -0
  55. package/dist/src/agents/test-agents.d.ts +6 -0
  56. package/dist/src/agents/test-agents.js +73 -0
  57. package/dist/src/agents/types.d.ts +194 -0
  58. package/dist/src/agents/types.js +7 -0
  59. package/dist/src/brain/index.d.ts +185 -0
  60. package/dist/src/brain/index.js +843 -0
  61. package/dist/src/brain/trace.d.ts +91 -0
  62. package/dist/src/brain/trace.js +327 -0
  63. package/dist/src/brain/types.d.ts +165 -0
  64. package/dist/src/brain/types.js +51 -0
  65. package/dist/src/cli/chat.d.ts +237 -0
  66. package/dist/src/cli/chat.js +1959 -0
  67. package/dist/src/cli/dispatcher.d.ts +182 -0
  68. package/dist/src/cli/dispatcher.js +718 -0
  69. package/dist/src/cli/human-loop.d.ts +170 -0
  70. package/dist/src/cli/human-loop.js +543 -0
  71. package/dist/src/cli/index.d.ts +12 -0
  72. package/dist/src/cli/index.js +28 -0
  73. package/dist/src/cli/interactive.d.ts +141 -0
  74. package/dist/src/cli/interactive.js +757 -0
  75. package/dist/src/cli/ui.d.ts +205 -0
  76. package/dist/src/cli/ui.js +632 -0
  77. package/dist/src/consciousness/attention-schema.d.ts +154 -0
  78. package/dist/src/consciousness/attention-schema.js +432 -0
  79. package/dist/src/consciousness/global-workspace.d.ts +149 -0
  80. package/dist/src/consciousness/global-workspace.js +422 -0
  81. package/dist/src/consciousness/index.d.ts +186 -0
  82. package/dist/src/consciousness/index.js +476 -0
  83. package/dist/src/consciousness/phi-calculator.d.ts +119 -0
  84. package/dist/src/consciousness/phi-calculator.js +445 -0
  85. package/dist/src/consciousness/phi-decisions.d.ts +169 -0
  86. package/dist/src/consciousness/phi-decisions.js +383 -0
  87. package/dist/src/consciousness/phi-monitor.d.ts +153 -0
  88. package/dist/src/consciousness/phi-monitor.js +465 -0
  89. package/dist/src/consciousness/types.d.ts +260 -0
  90. package/dist/src/consciousness/types.js +44 -0
  91. package/dist/src/daemon/dream-mode.d.ts +115 -0
  92. package/dist/src/daemon/dream-mode.js +470 -0
  93. package/dist/src/daemon/index.d.ts +162 -0
  94. package/dist/src/daemon/index.js +542 -0
  95. package/dist/src/daemon/maintenance.d.ts +139 -0
  96. package/dist/src/daemon/maintenance.js +549 -0
  97. package/dist/src/daemon/process.d.ts +82 -0
  98. package/dist/src/daemon/process.js +442 -0
  99. package/dist/src/daemon/scheduler.d.ts +90 -0
  100. package/dist/src/daemon/scheduler.js +494 -0
  101. package/dist/src/daemon/types.d.ts +213 -0
  102. package/dist/src/daemon/types.js +50 -0
  103. package/dist/src/epistemic/index.d.ts +74 -0
  104. package/dist/src/epistemic/index.js +225 -0
  105. package/dist/src/grounding/epistemic-stack.d.ts +100 -0
  106. package/dist/src/grounding/epistemic-stack.js +408 -0
  107. package/dist/src/grounding/feedback.d.ts +98 -0
  108. package/dist/src/grounding/feedback.js +276 -0
  109. package/dist/src/grounding/index.d.ts +123 -0
  110. package/dist/src/grounding/index.js +224 -0
  111. package/dist/src/grounding/verifier.d.ts +149 -0
  112. package/dist/src/grounding/verifier.js +484 -0
  113. package/dist/src/healing/detector.d.ts +110 -0
  114. package/dist/src/healing/detector.js +436 -0
  115. package/dist/src/healing/fixer.d.ts +138 -0
  116. package/dist/src/healing/fixer.js +572 -0
  117. package/dist/src/healing/index.d.ts +23 -0
  118. package/dist/src/healing/index.js +43 -0
  119. package/dist/src/hooks/index.d.ts +135 -0
  120. package/dist/src/hooks/index.js +317 -0
  121. package/dist/src/index.d.ts +23 -0
  122. package/dist/src/index.js +1266 -0
  123. package/dist/src/kernel/index.d.ts +155 -0
  124. package/dist/src/kernel/index.js +795 -0
  125. package/dist/src/kernel/invariants.d.ts +153 -0
  126. package/dist/src/kernel/invariants.js +355 -0
  127. package/dist/src/kernel/test-kernel.d.ts +6 -0
  128. package/dist/src/kernel/test-kernel.js +108 -0
  129. package/dist/src/kernel/test-real-mcp.d.ts +10 -0
  130. package/dist/src/kernel/test-real-mcp.js +295 -0
  131. package/dist/src/llm/index.d.ts +146 -0
  132. package/dist/src/llm/index.js +428 -0
  133. package/dist/src/llm/router.d.ts +136 -0
  134. package/dist/src/llm/router.js +510 -0
  135. package/dist/src/mcp/index.d.ts +85 -0
  136. package/dist/src/mcp/index.js +657 -0
  137. package/dist/src/mcp/resilient.d.ts +139 -0
  138. package/dist/src/mcp/resilient.js +417 -0
  139. package/dist/src/memory/cache.d.ts +118 -0
  140. package/dist/src/memory/cache.js +356 -0
  141. package/dist/src/memory/cognitive-workspace.d.ts +231 -0
  142. package/dist/src/memory/cognitive-workspace.js +521 -0
  143. package/dist/src/memory/consolidation.d.ts +99 -0
  144. package/dist/src/memory/consolidation.js +443 -0
  145. package/dist/src/memory/episodic.d.ts +114 -0
  146. package/dist/src/memory/episodic.js +394 -0
  147. package/dist/src/memory/forgetting.d.ts +134 -0
  148. package/dist/src/memory/forgetting.js +324 -0
  149. package/dist/src/memory/index.d.ts +211 -0
  150. package/dist/src/memory/index.js +367 -0
  151. package/dist/src/memory/indexer.d.ts +123 -0
  152. package/dist/src/memory/indexer.js +479 -0
  153. package/dist/src/memory/procedural.d.ts +136 -0
  154. package/dist/src/memory/procedural.js +479 -0
  155. package/dist/src/memory/semantic.d.ts +132 -0
  156. package/dist/src/memory/semantic.js +497 -0
  157. package/dist/src/memory/types.d.ts +193 -0
  158. package/dist/src/memory/types.js +15 -0
  159. package/dist/src/orchestrator.d.ts +65 -0
  160. package/dist/src/orchestrator.js +317 -0
  161. package/dist/src/persistence/index.d.ts +257 -0
  162. package/dist/src/persistence/index.js +763 -0
  163. package/dist/src/pipeline/executor.d.ts +51 -0
  164. package/dist/src/pipeline/executor.js +695 -0
  165. package/dist/src/pipeline/index.d.ts +7 -0
  166. package/dist/src/pipeline/index.js +11 -0
  167. package/dist/src/self-production.d.ts +67 -0
  168. package/dist/src/self-production.js +205 -0
  169. package/dist/src/subagents/executor.d.ts +58 -0
  170. package/dist/src/subagents/executor.js +283 -0
  171. package/dist/src/subagents/index.d.ts +37 -0
  172. package/dist/src/subagents/index.js +53 -0
  173. package/dist/src/subagents/registry.d.ts +23 -0
  174. package/dist/src/subagents/registry.js +167 -0
  175. package/dist/src/subagents/types.d.ts +79 -0
  176. package/dist/src/subagents/types.js +14 -0
  177. package/dist/src/tools/bash.d.ts +139 -0
  178. package/dist/src/tools/bash.js +583 -0
  179. package/dist/src/tools/edit.d.ts +125 -0
  180. package/dist/src/tools/edit.js +424 -0
  181. package/dist/src/tools/git.d.ts +179 -0
  182. package/dist/src/tools/git.js +504 -0
  183. package/dist/src/tools/index.d.ts +21 -0
  184. package/dist/src/tools/index.js +163 -0
  185. package/dist/src/types.d.ts +145 -0
  186. package/dist/src/types.js +7 -0
  187. package/dist/src/world-model/decoder.d.ts +163 -0
  188. package/dist/src/world-model/decoder.js +517 -0
  189. package/dist/src/world-model/digital-twin.d.ts +219 -0
  190. package/dist/src/world-model/digital-twin.js +695 -0
  191. package/dist/src/world-model/encoder.d.ts +141 -0
  192. package/dist/src/world-model/encoder.js +564 -0
  193. package/dist/src/world-model/index.d.ts +221 -0
  194. package/dist/src/world-model/index.js +772 -0
  195. package/dist/src/world-model/predictor.d.ts +161 -0
  196. package/dist/src/world-model/predictor.js +681 -0
  197. package/dist/src/world-model/test-value-jepa.d.ts +8 -0
  198. package/dist/src/world-model/test-value-jepa.js +430 -0
  199. package/dist/src/world-model/types.d.ts +341 -0
  200. package/dist/src/world-model/types.js +69 -0
  201. package/dist/src/world-model/value-jepa.d.ts +247 -0
  202. package/dist/src/world-model/value-jepa.js +622 -0
  203. package/dist/test/brain.test.d.ts +11 -0
  204. package/dist/test/brain.test.js +358 -0
  205. package/dist/test/cli/dispatcher.test.d.ts +4 -0
  206. package/dist/test/cli/dispatcher.test.js +332 -0
  207. package/dist/test/cli/human-loop.test.d.ts +4 -0
  208. package/dist/test/cli/human-loop.test.js +270 -0
  209. package/dist/test/grounding/feedback.test.d.ts +4 -0
  210. package/dist/test/grounding/feedback.test.js +462 -0
  211. package/dist/test/grounding/verifier.test.d.ts +4 -0
  212. package/dist/test/grounding/verifier.test.js +442 -0
  213. package/dist/test/grounding.test.d.ts +6 -0
  214. package/dist/test/grounding.test.js +246 -0
  215. package/dist/test/healing/detector.test.d.ts +4 -0
  216. package/dist/test/healing/detector.test.js +266 -0
  217. package/dist/test/healing/fixer.test.d.ts +4 -0
  218. package/dist/test/healing/fixer.test.js +369 -0
  219. package/dist/test/integration.test.d.ts +5 -0
  220. package/dist/test/integration.test.js +290 -0
  221. package/dist/test/tools/bash.test.d.ts +4 -0
  222. package/dist/test/tools/bash.test.js +348 -0
  223. package/dist/test/tools/edit.test.d.ts +4 -0
  224. package/dist/test/tools/edit.test.js +350 -0
  225. package/dist/test/tools/git.test.d.ts +4 -0
  226. package/dist/test/tools/git.test.js +350 -0
  227. package/package.json +60 -0
@@ -0,0 +1,179 @@
1
+ /**
2
+ * Genesis Native Git Operations
3
+ *
4
+ * Git operations:
5
+ * - status, diff, log (read-only, always safe)
6
+ * - add, commit (with message templates)
7
+ * - push (only with explicit confirmation)
8
+ * - branch operations
9
+ * - Safety guards for destructive operations
10
+ */
11
+ export interface GitConfig {
12
+ /** Default working directory */
13
+ workingDirectory: string;
14
+ /** Default commit signature */
15
+ signature: string;
16
+ /** Max timeout for git operations */
17
+ maxTimeout: number;
18
+ /** Block force push */
19
+ blockForcePush: boolean;
20
+ /** Block hard reset */
21
+ blockHardReset: boolean;
22
+ /** Require confirmation for push */
23
+ requirePushConfirmation: boolean;
24
+ }
25
+ export interface GitStatus {
26
+ branch: string;
27
+ ahead: number;
28
+ behind: number;
29
+ staged: string[];
30
+ unstaged: string[];
31
+ untracked: string[];
32
+ conflicted: string[];
33
+ isClean: boolean;
34
+ }
35
+ export interface GitDiff {
36
+ files: DiffFile[];
37
+ stats: {
38
+ insertions: number;
39
+ deletions: number;
40
+ filesChanged: number;
41
+ };
42
+ raw: string;
43
+ }
44
+ export interface DiffFile {
45
+ path: string;
46
+ status: 'added' | 'modified' | 'deleted' | 'renamed';
47
+ insertions: number;
48
+ deletions: number;
49
+ }
50
+ export interface GitCommit {
51
+ hash: string;
52
+ shortHash: string;
53
+ author: string;
54
+ email: string;
55
+ date: Date;
56
+ message: string;
57
+ }
58
+ export interface GitResult<T> {
59
+ success: boolean;
60
+ data?: T;
61
+ error?: string;
62
+ }
63
+ export interface CommitOptions {
64
+ message: string;
65
+ /** Add signature to commit message */
66
+ addSignature?: boolean;
67
+ /** Files to stage before commit (default: all staged) */
68
+ files?: string[];
69
+ }
70
+ export interface PushOptions {
71
+ /** Remote name (default: origin) */
72
+ remote?: string;
73
+ /** Branch name (default: current) */
74
+ branch?: string;
75
+ /** Set upstream */
76
+ setUpstream?: boolean;
77
+ /** Force push (blocked by default) */
78
+ force?: boolean;
79
+ /** User confirmed push */
80
+ confirmed?: boolean;
81
+ }
82
+ export declare const DEFAULT_GIT_CONFIG: GitConfig;
83
+ export declare class GitTool {
84
+ private config;
85
+ constructor(config?: Partial<GitConfig>);
86
+ /**
87
+ * Execute a git command
88
+ */
89
+ private exec;
90
+ /**
91
+ * Get repository status
92
+ */
93
+ status(cwd?: string): Promise<GitResult<GitStatus>>;
94
+ /**
95
+ * Get diff of changes
96
+ */
97
+ diff(options?: {
98
+ staged?: boolean;
99
+ file?: string;
100
+ }, cwd?: string): Promise<GitResult<GitDiff>>;
101
+ /**
102
+ * Get commit log
103
+ */
104
+ log(options?: {
105
+ count?: number;
106
+ oneline?: boolean;
107
+ }, cwd?: string): Promise<GitResult<GitCommit[]>>;
108
+ /**
109
+ * Get current branch name
110
+ */
111
+ branch(cwd?: string): Promise<GitResult<string>>;
112
+ /**
113
+ * List all branches
114
+ */
115
+ listBranches(cwd?: string): Promise<GitResult<{
116
+ current: string;
117
+ branches: string[];
118
+ }>>;
119
+ /**
120
+ * Stage files for commit
121
+ */
122
+ add(files: string[], cwd?: string): Promise<GitResult<void>>;
123
+ /**
124
+ * Unstage files
125
+ */
126
+ unstage(files: string[], cwd?: string): Promise<GitResult<void>>;
127
+ /**
128
+ * Create a commit
129
+ */
130
+ commit(options: CommitOptions, cwd?: string): Promise<GitResult<GitCommit>>;
131
+ /**
132
+ * Push to remote
133
+ */
134
+ push(options?: PushOptions, cwd?: string): Promise<GitResult<string>>;
135
+ /**
136
+ * Create a new branch
137
+ */
138
+ createBranch(name: string, options?: {
139
+ checkout?: boolean;
140
+ }, cwd?: string): Promise<GitResult<void>>;
141
+ /**
142
+ * Checkout a branch
143
+ */
144
+ checkout(branch: string, cwd?: string): Promise<GitResult<void>>;
145
+ /**
146
+ * Stash changes
147
+ */
148
+ stash(options?: {
149
+ message?: string;
150
+ pop?: boolean;
151
+ }, cwd?: string): Promise<GitResult<void>>;
152
+ /**
153
+ * Check if directory is a git repository
154
+ */
155
+ isRepo(cwd?: string): Promise<boolean>;
156
+ /**
157
+ * Get remote URL
158
+ */
159
+ getRemoteUrl(remote?: string, cwd?: string): Promise<GitResult<string>>;
160
+ /**
161
+ * Generate a commit message from staged changes
162
+ */
163
+ generateCommitMessage(cwd?: string): Promise<GitResult<string>>;
164
+ getConfig(): GitConfig;
165
+ updateConfig(config: Partial<GitConfig>): void;
166
+ }
167
+ export declare function getGitTool(config?: Partial<GitConfig>): GitTool;
168
+ export declare function resetGitTool(): void;
169
+ export declare function gitStatus(cwd?: string): Promise<GitResult<GitStatus>>;
170
+ export declare function gitDiff(options?: {
171
+ staged?: boolean;
172
+ file?: string;
173
+ }, cwd?: string): Promise<GitResult<GitDiff>>;
174
+ export declare function gitLog(options?: {
175
+ count?: number;
176
+ }, cwd?: string): Promise<GitResult<GitCommit[]>>;
177
+ export declare function gitAdd(files: string[], cwd?: string): Promise<GitResult<void>>;
178
+ export declare function gitCommit(options: CommitOptions, cwd?: string): Promise<GitResult<GitCommit>>;
179
+ export declare function gitPush(options?: PushOptions, cwd?: string): Promise<GitResult<string>>;
@@ -0,0 +1,504 @@
1
+ "use strict";
2
+ /**
3
+ * Genesis Native Git Operations
4
+ *
5
+ * Git operations:
6
+ * - status, diff, log (read-only, always safe)
7
+ * - add, commit (with message templates)
8
+ * - push (only with explicit confirmation)
9
+ * - branch operations
10
+ * - Safety guards for destructive operations
11
+ */
12
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ var desc = Object.getOwnPropertyDescriptor(m, k);
15
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
16
+ desc = { enumerable: true, get: function() { return m[k]; } };
17
+ }
18
+ Object.defineProperty(o, k2, desc);
19
+ }) : (function(o, m, k, k2) {
20
+ if (k2 === undefined) k2 = k;
21
+ o[k2] = m[k];
22
+ }));
23
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
24
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
25
+ }) : function(o, v) {
26
+ o["default"] = v;
27
+ });
28
+ var __importStar = (this && this.__importStar) || (function () {
29
+ var ownKeys = function(o) {
30
+ ownKeys = Object.getOwnPropertyNames || function (o) {
31
+ var ar = [];
32
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
33
+ return ar;
34
+ };
35
+ return ownKeys(o);
36
+ };
37
+ return function (mod) {
38
+ if (mod && mod.__esModule) return mod;
39
+ var result = {};
40
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
41
+ __setModuleDefault(result, mod);
42
+ return result;
43
+ };
44
+ })();
45
+ Object.defineProperty(exports, "__esModule", { value: true });
46
+ exports.GitTool = exports.DEFAULT_GIT_CONFIG = void 0;
47
+ exports.getGitTool = getGitTool;
48
+ exports.resetGitTool = resetGitTool;
49
+ exports.gitStatus = gitStatus;
50
+ exports.gitDiff = gitDiff;
51
+ exports.gitLog = gitLog;
52
+ exports.gitAdd = gitAdd;
53
+ exports.gitCommit = gitCommit;
54
+ exports.gitPush = gitPush;
55
+ const child_process_1 = require("child_process");
56
+ const path = __importStar(require("path"));
57
+ // ============================================================================
58
+ // Default Configuration
59
+ // ============================================================================
60
+ exports.DEFAULT_GIT_CONFIG = {
61
+ workingDirectory: process.cwd(),
62
+ signature: '\n\n🤖 Generated with Genesis\n\nCo-Authored-By: Genesis <noreply@genesis.ai>',
63
+ maxTimeout: 30000,
64
+ blockForcePush: true,
65
+ blockHardReset: true,
66
+ requirePushConfirmation: true,
67
+ };
68
+ // ============================================================================
69
+ // Git Tool Class
70
+ // ============================================================================
71
+ class GitTool {
72
+ config;
73
+ constructor(config) {
74
+ this.config = { ...exports.DEFAULT_GIT_CONFIG, ...config };
75
+ }
76
+ // --------------------------------------------------------------------------
77
+ // Core Git Execution
78
+ // --------------------------------------------------------------------------
79
+ /**
80
+ * Execute a git command
81
+ */
82
+ async exec(args, cwd) {
83
+ return new Promise((resolve) => {
84
+ const child = (0, child_process_1.spawn)('git', args, {
85
+ cwd: cwd || this.config.workingDirectory,
86
+ stdio: ['pipe', 'pipe', 'pipe'],
87
+ });
88
+ let stdout = '';
89
+ let stderr = '';
90
+ const timeout = setTimeout(() => {
91
+ child.kill('SIGTERM');
92
+ resolve({ stdout, stderr: 'Git command timed out', exitCode: -1 });
93
+ }, this.config.maxTimeout);
94
+ child.stdout.on('data', (data) => { stdout += data.toString(); });
95
+ child.stderr.on('data', (data) => { stderr += data.toString(); });
96
+ child.on('close', (code) => {
97
+ clearTimeout(timeout);
98
+ resolve({ stdout: stdout.trim(), stderr: stderr.trim(), exitCode: code ?? 0 });
99
+ });
100
+ child.on('error', (err) => {
101
+ clearTimeout(timeout);
102
+ resolve({ stdout: '', stderr: err.message, exitCode: -1 });
103
+ });
104
+ });
105
+ }
106
+ // --------------------------------------------------------------------------
107
+ // Read-Only Operations (Always Safe)
108
+ // --------------------------------------------------------------------------
109
+ /**
110
+ * Get repository status
111
+ */
112
+ async status(cwd) {
113
+ const { stdout, stderr, exitCode } = await this.exec(['status', '--porcelain', '-b'], cwd);
114
+ if (exitCode !== 0) {
115
+ return { success: false, error: stderr || 'Not a git repository' };
116
+ }
117
+ const lines = stdout.split('\n').filter(l => l);
118
+ const branchLine = lines.find(l => l.startsWith('##')) || '';
119
+ // Parse branch info
120
+ const branchMatch = branchLine.match(/^## (\S+?)(?:\.\.\.(\S+))?(?:\s+\[ahead (\d+)(?:, behind (\d+))?\])?$/);
121
+ const branch = branchMatch?.[1] || 'unknown';
122
+ const ahead = parseInt(branchMatch?.[3] || '0', 10);
123
+ const behind = parseInt(branchMatch?.[4] || '0', 10);
124
+ // Parse file status
125
+ const staged = [];
126
+ const unstaged = [];
127
+ const untracked = [];
128
+ const conflicted = [];
129
+ for (const line of lines) {
130
+ if (line.startsWith('##'))
131
+ continue;
132
+ const indexStatus = line[0];
133
+ const workStatus = line[1];
134
+ const file = line.slice(3);
135
+ if (indexStatus === 'U' || workStatus === 'U' || (indexStatus === 'A' && workStatus === 'A') || (indexStatus === 'D' && workStatus === 'D')) {
136
+ conflicted.push(file);
137
+ }
138
+ else if (indexStatus === '?') {
139
+ untracked.push(file);
140
+ }
141
+ else {
142
+ if (indexStatus !== ' ' && indexStatus !== '?') {
143
+ staged.push(file);
144
+ }
145
+ if (workStatus !== ' ' && workStatus !== '?') {
146
+ unstaged.push(file);
147
+ }
148
+ }
149
+ }
150
+ return {
151
+ success: true,
152
+ data: {
153
+ branch,
154
+ ahead,
155
+ behind,
156
+ staged,
157
+ unstaged,
158
+ untracked,
159
+ conflicted,
160
+ isClean: staged.length === 0 && unstaged.length === 0 && untracked.length === 0,
161
+ },
162
+ };
163
+ }
164
+ /**
165
+ * Get diff of changes
166
+ */
167
+ async diff(options, cwd) {
168
+ const args = ['diff', '--stat'];
169
+ if (options?.staged)
170
+ args.push('--staged');
171
+ if (options?.file)
172
+ args.push('--', options.file);
173
+ const { stdout: statOutput, exitCode } = await this.exec(args, cwd);
174
+ if (exitCode !== 0) {
175
+ return { success: false, error: 'Failed to get diff' };
176
+ }
177
+ // Get raw diff
178
+ const rawArgs = ['diff'];
179
+ if (options?.staged)
180
+ rawArgs.push('--staged');
181
+ if (options?.file)
182
+ rawArgs.push('--', options.file);
183
+ const { stdout: rawDiff } = await this.exec(rawArgs, cwd);
184
+ // Parse stats
185
+ const lines = statOutput.split('\n').filter(l => l);
186
+ const files = [];
187
+ let insertions = 0;
188
+ let deletions = 0;
189
+ for (const line of lines) {
190
+ // File line: "path/to/file.ts | 10 ++++----"
191
+ const match = line.match(/^\s*(.+?)\s+\|\s+(\d+)\s*([+-]*)/);
192
+ if (match) {
193
+ const [, filePath, changes, symbols] = match;
194
+ const ins = (symbols.match(/\+/g) || []).length;
195
+ const del = (symbols.match(/-/g) || []).length;
196
+ files.push({
197
+ path: filePath.trim(),
198
+ status: 'modified',
199
+ insertions: ins,
200
+ deletions: del,
201
+ });
202
+ insertions += ins;
203
+ deletions += del;
204
+ }
205
+ }
206
+ return {
207
+ success: true,
208
+ data: {
209
+ files,
210
+ stats: { insertions, deletions, filesChanged: files.length },
211
+ raw: rawDiff,
212
+ },
213
+ };
214
+ }
215
+ /**
216
+ * Get commit log
217
+ */
218
+ async log(options, cwd) {
219
+ const count = options?.count || 10;
220
+ const format = options?.oneline
221
+ ? '%H|%h|%an|%ae|%ai|%s'
222
+ : '%H|%h|%an|%ae|%ai|%B---END---';
223
+ const { stdout, stderr, exitCode } = await this.exec([
224
+ 'log',
225
+ `-${count}`,
226
+ `--format=${format}`,
227
+ ], cwd);
228
+ if (exitCode !== 0) {
229
+ return { success: false, error: stderr || 'Failed to get log' };
230
+ }
231
+ const commits = [];
232
+ const entries = options?.oneline
233
+ ? stdout.split('\n').filter(l => l)
234
+ : stdout.split('---END---').filter(l => l.trim());
235
+ for (const entry of entries) {
236
+ const parts = entry.trim().split('|');
237
+ if (parts.length >= 6) {
238
+ commits.push({
239
+ hash: parts[0],
240
+ shortHash: parts[1],
241
+ author: parts[2],
242
+ email: parts[3],
243
+ date: new Date(parts[4]),
244
+ message: parts.slice(5).join('|').trim(),
245
+ });
246
+ }
247
+ }
248
+ return { success: true, data: commits };
249
+ }
250
+ /**
251
+ * Get current branch name
252
+ */
253
+ async branch(cwd) {
254
+ const { stdout, exitCode } = await this.exec(['rev-parse', '--abbrev-ref', 'HEAD'], cwd);
255
+ if (exitCode !== 0) {
256
+ return { success: false, error: 'Not a git repository or no commits' };
257
+ }
258
+ return { success: true, data: stdout };
259
+ }
260
+ /**
261
+ * List all branches
262
+ */
263
+ async listBranches(cwd) {
264
+ const { stdout, exitCode } = await this.exec(['branch', '-a'], cwd);
265
+ if (exitCode !== 0) {
266
+ return { success: false, error: 'Failed to list branches' };
267
+ }
268
+ const branches = [];
269
+ let current = '';
270
+ for (const line of stdout.split('\n')) {
271
+ if (line.startsWith('*')) {
272
+ current = line.slice(2).trim();
273
+ branches.push(current);
274
+ }
275
+ else if (line.trim()) {
276
+ branches.push(line.trim());
277
+ }
278
+ }
279
+ return { success: true, data: { current, branches } };
280
+ }
281
+ // --------------------------------------------------------------------------
282
+ // Write Operations (With Safety)
283
+ // --------------------------------------------------------------------------
284
+ /**
285
+ * Stage files for commit
286
+ */
287
+ async add(files, cwd) {
288
+ if (files.length === 0) {
289
+ return { success: false, error: 'No files specified' };
290
+ }
291
+ const { stderr, exitCode } = await this.exec(['add', ...files], cwd);
292
+ if (exitCode !== 0) {
293
+ return { success: false, error: stderr || 'Failed to stage files' };
294
+ }
295
+ return { success: true };
296
+ }
297
+ /**
298
+ * Unstage files
299
+ */
300
+ async unstage(files, cwd) {
301
+ const { stderr, exitCode } = await this.exec(['reset', 'HEAD', ...files], cwd);
302
+ if (exitCode !== 0) {
303
+ return { success: false, error: stderr || 'Failed to unstage files' };
304
+ }
305
+ return { success: true };
306
+ }
307
+ /**
308
+ * Create a commit
309
+ */
310
+ async commit(options, cwd) {
311
+ // Stage files if specified
312
+ if (options.files && options.files.length > 0) {
313
+ const addResult = await this.add(options.files, cwd);
314
+ if (!addResult.success) {
315
+ return { success: false, error: addResult.error };
316
+ }
317
+ }
318
+ // Build commit message
319
+ let message = options.message;
320
+ if (options.addSignature !== false) {
321
+ message += this.config.signature;
322
+ }
323
+ const { stdout, stderr, exitCode } = await this.exec([
324
+ 'commit',
325
+ '-m',
326
+ message,
327
+ ], cwd);
328
+ if (exitCode !== 0) {
329
+ return { success: false, error: stderr || 'Failed to create commit' };
330
+ }
331
+ // Get the new commit info
332
+ const logResult = await this.log({ count: 1 }, cwd);
333
+ if (logResult.success && logResult.data && logResult.data.length > 0) {
334
+ return { success: true, data: logResult.data[0] };
335
+ }
336
+ return { success: true, data: undefined };
337
+ }
338
+ /**
339
+ * Push to remote
340
+ */
341
+ async push(options, cwd) {
342
+ // Safety checks
343
+ if (this.config.requirePushConfirmation && !options?.confirmed) {
344
+ return { success: false, error: 'Push requires explicit confirmation. Set confirmed: true' };
345
+ }
346
+ if (options?.force && this.config.blockForcePush) {
347
+ return { success: false, error: 'Force push is blocked for safety' };
348
+ }
349
+ const args = ['push'];
350
+ if (options?.setUpstream) {
351
+ args.push('-u');
352
+ }
353
+ if (options?.force && !this.config.blockForcePush) {
354
+ args.push('--force-with-lease'); // Safer than --force
355
+ }
356
+ if (options?.remote) {
357
+ args.push(options.remote);
358
+ }
359
+ if (options?.branch) {
360
+ args.push(options.branch);
361
+ }
362
+ const { stdout, stderr, exitCode } = await this.exec(args, cwd);
363
+ if (exitCode !== 0) {
364
+ return { success: false, error: stderr || 'Failed to push' };
365
+ }
366
+ return { success: true, data: stdout || stderr || 'Push successful' };
367
+ }
368
+ /**
369
+ * Create a new branch
370
+ */
371
+ async createBranch(name, options, cwd) {
372
+ const { stderr, exitCode } = await this.exec(['branch', name], cwd);
373
+ if (exitCode !== 0) {
374
+ return { success: false, error: stderr || 'Failed to create branch' };
375
+ }
376
+ if (options?.checkout) {
377
+ return this.checkout(name, cwd);
378
+ }
379
+ return { success: true };
380
+ }
381
+ /**
382
+ * Checkout a branch
383
+ */
384
+ async checkout(branch, cwd) {
385
+ const { stderr, exitCode } = await this.exec(['checkout', branch], cwd);
386
+ if (exitCode !== 0) {
387
+ return { success: false, error: stderr || 'Failed to checkout branch' };
388
+ }
389
+ return { success: true };
390
+ }
391
+ /**
392
+ * Stash changes
393
+ */
394
+ async stash(options, cwd) {
395
+ const args = ['stash'];
396
+ if (options?.pop) {
397
+ args.push('pop');
398
+ }
399
+ else if (options?.message) {
400
+ args.push('push', '-m', options.message);
401
+ }
402
+ const { stderr, exitCode } = await this.exec(args, cwd);
403
+ if (exitCode !== 0) {
404
+ return { success: false, error: stderr || 'Failed to stash' };
405
+ }
406
+ return { success: true };
407
+ }
408
+ // --------------------------------------------------------------------------
409
+ // Utility Methods
410
+ // --------------------------------------------------------------------------
411
+ /**
412
+ * Check if directory is a git repository
413
+ */
414
+ async isRepo(cwd) {
415
+ const { exitCode } = await this.exec(['rev-parse', '--git-dir'], cwd);
416
+ return exitCode === 0;
417
+ }
418
+ /**
419
+ * Get remote URL
420
+ */
421
+ async getRemoteUrl(remote = 'origin', cwd) {
422
+ const { stdout, exitCode } = await this.exec(['remote', 'get-url', remote], cwd);
423
+ if (exitCode !== 0) {
424
+ return { success: false, error: 'Remote not found' };
425
+ }
426
+ return { success: true, data: stdout };
427
+ }
428
+ /**
429
+ * Generate a commit message from staged changes
430
+ */
431
+ async generateCommitMessage(cwd) {
432
+ const diffResult = await this.diff({ staged: true }, cwd);
433
+ if (!diffResult.success || !diffResult.data) {
434
+ return { success: false, error: 'No staged changes' };
435
+ }
436
+ const { files, stats } = diffResult.data;
437
+ if (files.length === 0) {
438
+ return { success: false, error: 'No staged changes' };
439
+ }
440
+ // Simple heuristic-based message generation
441
+ const fileTypes = new Set(files.map(f => path.extname(f.path)));
442
+ const directories = new Set(files.map(f => path.dirname(f.path).split('/')[0]));
443
+ let type = 'update';
444
+ if (files.every(f => f.status === 'added'))
445
+ type = 'add';
446
+ if (files.some(f => f.path.includes('test')))
447
+ type = 'test';
448
+ if (files.some(f => f.path.includes('fix')))
449
+ type = 'fix';
450
+ if (files.length === 1 && files[0].path.includes('README'))
451
+ type = 'docs';
452
+ const scope = directories.size === 1 ? Array.from(directories)[0] : undefined;
453
+ const scopePart = scope ? `(${scope})` : '';
454
+ const message = `${type}${scopePart}: ${files.length} file(s) changed (+${stats.insertions}/-${stats.deletions})`;
455
+ return { success: true, data: message };
456
+ }
457
+ // --------------------------------------------------------------------------
458
+ // Configuration
459
+ // --------------------------------------------------------------------------
460
+ getConfig() {
461
+ return { ...this.config };
462
+ }
463
+ updateConfig(config) {
464
+ this.config = { ...this.config, ...config };
465
+ }
466
+ }
467
+ exports.GitTool = GitTool;
468
+ // ============================================================================
469
+ // Singleton Instance
470
+ // ============================================================================
471
+ let gitToolInstance = null;
472
+ function getGitTool(config) {
473
+ if (!gitToolInstance) {
474
+ gitToolInstance = new GitTool(config);
475
+ }
476
+ else if (config) {
477
+ gitToolInstance.updateConfig(config);
478
+ }
479
+ return gitToolInstance;
480
+ }
481
+ function resetGitTool() {
482
+ gitToolInstance = null;
483
+ }
484
+ // ============================================================================
485
+ // Convenience Functions
486
+ // ============================================================================
487
+ async function gitStatus(cwd) {
488
+ return getGitTool().status(cwd);
489
+ }
490
+ async function gitDiff(options, cwd) {
491
+ return getGitTool().diff(options, cwd);
492
+ }
493
+ async function gitLog(options, cwd) {
494
+ return getGitTool().log(options, cwd);
495
+ }
496
+ async function gitAdd(files, cwd) {
497
+ return getGitTool().add(files, cwd);
498
+ }
499
+ async function gitCommit(options, cwd) {
500
+ return getGitTool().commit(options, cwd);
501
+ }
502
+ async function gitPush(options, cwd) {
503
+ return getGitTool().push(options, cwd);
504
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Genesis Tools Module
3
+ *
4
+ * Local tool capabilities:
5
+ * - Bash: Secure command execution
6
+ * - Edit: Diff-based file editing
7
+ * - Git: Native git operations
8
+ */
9
+ export * from './bash.js';
10
+ export * from './edit.js';
11
+ export * from './git.js';
12
+ export interface Tool {
13
+ name: string;
14
+ description: string;
15
+ execute: (params: Record<string, unknown>) => Promise<unknown>;
16
+ validate?: (params: Record<string, unknown>) => {
17
+ valid: boolean;
18
+ reason?: string;
19
+ };
20
+ }
21
+ export declare const toolRegistry: Map<string, Tool>;