sam-coder-cli 2.0.4 → 2.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/ui.js CHANGED
@@ -1,7 +1,14 @@
1
1
  const chalk = require('chalk');
2
2
  const ora = require('ora');
3
3
 
4
- const spinner = ora({ text: 'Thinking...', color: 'yellow', spinner: 'pipe' });
4
+ // IMPORTANT: discardStdin must be false to prevent ora from closing stdin
5
+ // which would cause readline to close and the program to exit
6
+ const spinner = ora({
7
+ text: 'Thinking...',
8
+ color: 'yellow',
9
+ spinner: 'pipe',
10
+ discardStdin: false // Critical: prevents stdin interference
11
+ });
5
12
 
6
13
  // ASCII Art for AGI header
7
14
  const AGI_HEADER = `
package/package.json CHANGED
@@ -1,12 +1,16 @@
1
1
  {
2
2
  "name": "sam-coder-cli",
3
- "version": "2.0.4",
4
- "description": "SAM-CODER: An animated command-line AI assistant with agency capabilities, brainstorm framework, and engineer mode.",
3
+ "version": "2.0.7",
4
+ "description": "SAM-CODER: An animated command-line AI assistant with agency capabilities.",
5
5
  "main": "bin/agi-cli.js",
6
6
  "bin": {
7
7
  "sam-coder": "bin/agi-cli.js",
8
8
  "agi-cli": "bin/agi-cli.js"
9
9
  },
10
+ "files": [
11
+ "bin",
12
+ "README.md"
13
+ ],
10
14
  "scripts": {
11
15
  "start": "node ./bin/agi-cli.js"
12
16
  },
@@ -16,29 +20,16 @@
16
20
  "cli",
17
21
  "terminal",
18
22
  "agent",
19
- "brainstorm",
20
- "engineer",
21
- "code-generation"
23
+ "agi",
24
+ "deepseek"
22
25
  ],
23
- "author": "",
26
+ "author": "Guilherme Keller",
24
27
  "license": "MIT",
25
28
  "dependencies": {
26
29
  "chalk": "^4.1.2",
27
- "ora": "^5.4.1",
28
- "ws": "^8.18.3"
29
- },
30
- "devDependencies": {
31
- "@types/vscode": "^1.102.0",
32
- "eslint": "^7.27.0"
30
+ "ora": "^5.4.1"
33
31
  },
34
32
  "engines": {
35
33
  "node": ">=18.12.1"
36
- },
37
- "files": [
38
- "bin/**/*"
39
- ],
40
- "repository": {
41
- "type": "git",
42
- "url": ""
43
34
  }
44
- }
35
+ }
@@ -1,198 +0,0 @@
1
- /**
2
- * Brainstorm Module - Start a New Brainstorm Session
3
- *
4
- * Initializes a new brainstorm session and generates all project coordination files.
5
- * Ported from Python to JavaScript.
6
- */
7
-
8
- const fs = require('fs').promises;
9
- const path = require('path');
10
- const { ProjectConfig, BrainstormSession } = require('./models');
11
- const templates = require('./templates');
12
-
13
- /**
14
- * File templates mapping
15
- */
16
- const FILE_TEMPLATES = {
17
- 'CLAUDE.md': templates.generateClaudeMd,
18
- 'PROJECT_STATUS.md': templates.generateProjectStatusMd,
19
- 'PROGRESS_REPORT.md': templates.generateProgressReportMd,
20
- 'GETTING_STARTED.md': templates.generateGettingStartedMd,
21
- 'SELF_IMPROVEMENT.md': templates.generateSelfImprovementMd,
22
- 'CEO-UPDATES-TODAY.md': templates.generateCeoUpdatesMd,
23
- 'CODE_OF_CONDUCT_OF_AI_WORKERS.md': templates.generateCodeOfConductMd
24
- };
25
-
26
- const MULTI_AGENT_TEMPLATES = {
27
- 'SECONDARY-AI-CHAT.md': templates.generateSecondaryAiChatMd
28
- };
29
-
30
- /**
31
- * Start a new brainstorm session
32
- *
33
- * @param {Object} options
34
- * @param {ProjectConfig|Object} options.config - Project configuration
35
- * @param {string} options.outputDir - Directory where files will be generated
36
- * @param {string[]} options.agents - List of agent identities (e.g., ["CLAUDE-1", "CLAUDE-2"])
37
- * @returns {Promise<BrainstormSession>}
38
- */
39
- async function startBrainstorm({ config, outputDir, agents = ['CLAUDE-1'] }) {
40
- // Convert to ProjectConfig if needed
41
- const project = config instanceof ProjectConfig ? config : new ProjectConfig(config);
42
-
43
- // Create output directory
44
- await fs.mkdir(outputDir, { recursive: true });
45
-
46
- // Create new session
47
- const session = BrainstormSession.create({
48
- project,
49
- outputDirectory: outputDir,
50
- agents
51
- });
52
-
53
- const generatedFiles = [];
54
-
55
- // Generate standard files
56
- for (const [fileName, templateFn] of Object.entries(FILE_TEMPLATES)) {
57
- const content = templateFn({ project, agents, session });
58
- const filePath = path.join(outputDir, fileName);
59
- await fs.writeFile(filePath, content, 'utf-8');
60
- generatedFiles.push(fileName);
61
- session.fileVersions[fileName] = 1;
62
- }
63
-
64
- // Generate multi-agent files if more than one agent
65
- if (agents.length > 1) {
66
- for (const [fileName, templateFn] of Object.entries(MULTI_AGENT_TEMPLATES)) {
67
- const content = templateFn({ project, agents, session });
68
- const filePath = path.join(outputDir, fileName);
69
- await fs.writeFile(filePath, content, 'utf-8');
70
- generatedFiles.push(fileName);
71
- session.fileVersions[fileName] = 1;
72
- }
73
- }
74
-
75
- // Create directory structure if defined
76
- if (project.directoryStructure && Object.keys(project.directoryStructure).length > 0) {
77
- await createDirectoryStructure(outputDir, project.directoryStructure);
78
- }
79
-
80
- // Add event for file generation
81
- session.addEvent({
82
- eventType: 'UPDATED',
83
- actor: 'BRAINSTORM',
84
- description: `Generated ${generatedFiles.length} project files`,
85
- affectedFiles: generatedFiles
86
- });
87
-
88
- // Save session state
89
- await session.save();
90
-
91
- return session;
92
- }
93
-
94
- /**
95
- * Create directory structure recursively
96
- */
97
- async function createDirectoryStructure(baseDir, structure, currentPath = null) {
98
- const current = currentPath || baseDir;
99
-
100
- for (const [name, children] of Object.entries(structure)) {
101
- const itemPath = path.join(current, name);
102
-
103
- if (typeof children === 'object' && children !== null && Object.keys(children).length > 0) {
104
- // Directory with children
105
- await fs.mkdir(itemPath, { recursive: true });
106
- await createDirectoryStructure(baseDir, children, itemPath);
107
- } else if (children === null || (typeof children === 'object' && Object.keys(children).length === 0)) {
108
- // Empty directory
109
- await fs.mkdir(itemPath, { recursive: true });
110
- } else {
111
- // File placeholder
112
- await fs.mkdir(path.dirname(itemPath), { recursive: true });
113
- try {
114
- await fs.access(itemPath);
115
- } catch {
116
- await fs.writeFile(itemPath, '', 'utf-8');
117
- }
118
- }
119
- }
120
- }
121
-
122
- /**
123
- * Load an existing session from a directory
124
- *
125
- * @param {string} sessionDir - Directory containing SESSION.json
126
- * @returns {Promise<BrainstormSession|null>}
127
- */
128
- async function getSession(sessionDir) {
129
- const sessionFile = path.join(sessionDir, 'SESSION.json');
130
-
131
- try {
132
- await fs.access(sessionFile);
133
- return await BrainstormSession.load(sessionFile);
134
- } catch {
135
- return null;
136
- }
137
- }
138
-
139
- /**
140
- * List all files in a brainstorm session with their versions
141
- *
142
- * @param {BrainstormSession} session
143
- * @returns {Array<Object>}
144
- */
145
- async function listFiles(session) {
146
- const files = [];
147
-
148
- for (const [fileName, version] of Object.entries(session.fileVersions)) {
149
- const filePath = path.join(session.outputDirectory, fileName);
150
- let exists = false;
151
-
152
- try {
153
- await fs.access(filePath);
154
- exists = true;
155
- } catch { }
156
-
157
- files.push({
158
- name: fileName,
159
- path: filePath,
160
- version,
161
- exists
162
- });
163
- }
164
-
165
- return files;
166
- }
167
-
168
- /**
169
- * Quick start function for creating a brainstorm session
170
- *
171
- * @param {string} name - Project name
172
- * @param {string} description - Project description
173
- * @param {string} outputDir - Output directory
174
- * @param {string[]} agents - List of agent identities
175
- * @param {Object} options - Additional ProjectConfig fields
176
- * @returns {Promise<BrainstormSession>}
177
- */
178
- async function quickStart(name, description, outputDir, agents = ['CLAUDE-1'], options = {}) {
179
- const config = new ProjectConfig({
180
- name,
181
- description,
182
- ...options
183
- });
184
-
185
- return startBrainstorm({
186
- config,
187
- outputDir,
188
- agents
189
- });
190
- }
191
-
192
- module.exports = {
193
- startBrainstorm,
194
- getSession,
195
- listFiles,
196
- quickStart,
197
- createDirectoryStructure
198
- };
@@ -1,294 +0,0 @@
1
- /**
2
- * Edit Finished Brainstorm Module - Version-Tracked Edits
3
- *
4
- * Allows editing of completed brainstorm files with full version tracking and audit trail.
5
- * Ported from Python to JavaScript.
6
- */
7
-
8
- const fs = require('fs').promises;
9
- const path = require('path');
10
- const { BrainstormSession, EditInfo } = require('./models');
11
-
12
- /**
13
- * Result of an edit operation
14
- */
15
- class EditResult {
16
- constructor({
17
- success,
18
- fileName,
19
- versionBefore,
20
- versionAfter,
21
- backupPath = null,
22
- error = null
23
- }) {
24
- this.success = success;
25
- this.fileName = fileName;
26
- this.versionBefore = versionBefore;
27
- this.versionAfter = versionAfter;
28
- this.backupPath = backupPath;
29
- this.error = error;
30
- }
31
- }
32
-
33
- /**
34
- * Edit a file in a completed brainstorm session
35
- *
36
- * @param {Object} options
37
- * @param {string} options.sessionDir - Directory containing the session
38
- * @param {string} options.fileName - Name of the file to edit
39
- * @param {string} options.newContent - New content for the file
40
- * @param {string} options.description - Description of what was changed
41
- * @param {string} options.editor - Who is making the edit
42
- * @returns {Promise<EditResult>}
43
- */
44
- async function editBrainstormFile({ sessionDir, fileName, newContent, description, editor = 'HUMAN' }) {
45
- const sessionFile = path.join(sessionDir, 'SESSION.json');
46
-
47
- // Check if session exists
48
- try {
49
- await fs.access(sessionFile);
50
- } catch {
51
- return new EditResult({
52
- success: false,
53
- fileName,
54
- versionBefore: 0,
55
- versionAfter: 0,
56
- error: 'SESSION.json not found'
57
- });
58
- }
59
-
60
- // Load session
61
- const session = await BrainstormSession.load(sessionFile);
62
- const filePath = path.join(session.outputDirectory, fileName);
63
-
64
- // Check if file exists
65
- try {
66
- await fs.access(filePath);
67
- } catch {
68
- return new EditResult({
69
- success: false,
70
- fileName,
71
- versionBefore: 0,
72
- versionAfter: 0,
73
- error: `File ${fileName} does not exist in session`
74
- });
75
- }
76
-
77
- // Get current version
78
- const versionBefore = session.getFileVersion(fileName);
79
-
80
- // Create backup
81
- const backupPath = await createBackup(session, filePath, versionBefore);
82
-
83
- // Write new content
84
- await fs.writeFile(filePath, newContent, 'utf-8');
85
-
86
- // Increment version
87
- const versionAfter = session.incrementFileVersion(fileName);
88
-
89
- // Add event to session history
90
- session.addEvent({
91
- eventType: 'EDITED',
92
- actor: editor,
93
- description: `Edited ${fileName}: ${description}`,
94
- affectedFiles: [fileName]
95
- });
96
-
97
- // Save updated session
98
- await session.save();
99
-
100
- return new EditResult({
101
- success: true,
102
- fileName,
103
- versionBefore,
104
- versionAfter,
105
- backupPath
106
- });
107
- }
108
-
109
- /**
110
- * Create a versioned backup of a file
111
- *
112
- * @param {BrainstormSession} session
113
- * @param {string} filePath - Path to the file
114
- * @param {number} version - Current version number
115
- * @returns {Promise<string|null>}
116
- */
117
- async function createBackup(session, filePath, version) {
118
- const backupsDir = path.join(session.outputDirectory, '.backups');
119
-
120
- try {
121
- await fs.mkdir(backupsDir, { recursive: true });
122
- } catch { }
123
-
124
- const fileName = path.basename(filePath);
125
- const backupName = `${fileName}.v${version}`;
126
- const backupPath = path.join(backupsDir, backupName);
127
-
128
- try {
129
- await fs.copyFile(filePath, backupPath);
130
- return backupPath;
131
- } catch (error) {
132
- console.error(`Failed to create backup: ${error.message}`);
133
- return null;
134
- }
135
- }
136
-
137
- /**
138
- * Get edit history for a session or specific file
139
- *
140
- * @param {string} sessionDir - Directory containing the session
141
- * @param {string|null} fileName - Optional file name to filter by
142
- * @returns {Promise<Array>}
143
- */
144
- async function getHistory(sessionDir, fileName = null) {
145
- const sessionFile = path.join(sessionDir, 'SESSION.json');
146
-
147
- try {
148
- await fs.access(sessionFile);
149
- } catch {
150
- return [];
151
- }
152
-
153
- const session = await BrainstormSession.load(sessionFile);
154
-
155
- // Filter for EDITED events
156
- let edits = session.history
157
- .filter(e => e.eventType === 'EDITED')
158
- .map(e => e.toJSON ? e.toJSON() : e);
159
-
160
- // Filter by file name if specified
161
- if (fileName) {
162
- edits = edits.filter(e =>
163
- (e.affectedFiles || []).includes(fileName)
164
- );
165
- }
166
-
167
- return edits;
168
- }
169
-
170
- /**
171
- * Get current versions of all files in a session
172
- *
173
- * @param {string} sessionDir - Directory containing the session
174
- * @returns {Promise<Object>}
175
- */
176
- async function getVersions(sessionDir) {
177
- const sessionFile = path.join(sessionDir, 'SESSION.json');
178
-
179
- try {
180
- await fs.access(sessionFile);
181
- } catch {
182
- return {};
183
- }
184
-
185
- const session = await BrainstormSession.load(sessionFile);
186
- return { ...session.fileVersions };
187
- }
188
-
189
- /**
190
- * Restore a file to a previous version
191
- *
192
- * @param {Object} options
193
- * @param {string} options.sessionDir - Directory containing the session
194
- * @param {string} options.fileName - Name of the file to restore
195
- * @param {number} options.version - Version number to restore to
196
- * @param {string} options.editor - Who is making the restore
197
- * @returns {Promise<EditResult>}
198
- */
199
- async function restoreVersion({ sessionDir, fileName, version, editor = 'HUMAN' }) {
200
- const sessionFile = path.join(sessionDir, 'SESSION.json');
201
-
202
- try {
203
- await fs.access(sessionFile);
204
- } catch {
205
- return new EditResult({
206
- success: false,
207
- fileName,
208
- versionBefore: 0,
209
- versionAfter: 0,
210
- error: 'SESSION.json not found'
211
- });
212
- }
213
-
214
- const session = await BrainstormSession.load(sessionFile);
215
-
216
- // Find backup file
217
- const backupsDir = path.join(session.outputDirectory, '.backups');
218
- const backupPath = path.join(backupsDir, `${fileName}.v${version}`);
219
-
220
- try {
221
- await fs.access(backupPath);
222
- } catch {
223
- return new EditResult({
224
- success: false,
225
- fileName,
226
- versionBefore: session.getFileVersion(fileName),
227
- versionAfter: session.getFileVersion(fileName),
228
- error: `Backup version ${version} not found for ${fileName}`
229
- });
230
- }
231
-
232
- // Read backup content
233
- const content = await fs.readFile(backupPath, 'utf-8');
234
-
235
- // Use edit to restore (this creates a new version)
236
- return editBrainstormFile({
237
- sessionDir,
238
- fileName,
239
- newContent: content,
240
- description: `Restored to version ${version}`,
241
- editor
242
- });
243
- }
244
-
245
- /**
246
- * List all backup files in a session
247
- *
248
- * @param {string} sessionDir - Directory containing the session
249
- * @returns {Promise<Array>}
250
- */
251
- async function listBackups(sessionDir) {
252
- const backupsDir = path.join(sessionDir, '.backups');
253
-
254
- try {
255
- await fs.access(backupsDir);
256
- } catch {
257
- return [];
258
- }
259
-
260
- const entries = await fs.readdir(backupsDir, { withFileTypes: true });
261
- const backups = [];
262
-
263
- for (const entry of entries) {
264
- if (entry.isFile()) {
265
- const match = entry.name.match(/^(.+)\.v(\d+)$/);
266
- if (match) {
267
- const filePath = path.join(backupsDir, entry.name);
268
- const stats = await fs.stat(filePath);
269
-
270
- backups.push({
271
- fileName: match[1],
272
- version: parseInt(match[2], 10),
273
- backupPath: filePath,
274
- size: stats.size,
275
- modified: stats.mtime.toISOString()
276
- });
277
- }
278
- }
279
- }
280
-
281
- return backups.sort((a, b) => {
282
- if (a.fileName !== b.fileName) return a.fileName.localeCompare(b.fileName);
283
- return a.version - b.version;
284
- });
285
- }
286
-
287
- module.exports = {
288
- EditResult,
289
- editBrainstormFile,
290
- getHistory,
291
- getVersions,
292
- restoreVersion,
293
- listBackups
294
- };