sam-coder-cli 1.0.4 â 1.0.6
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/agi-cli.js +60 -51
- package/foldersnake/snake_game.py +202 -109
- package/package.json +2 -2
package/bin/agi-cli.js
CHANGED
|
@@ -13,7 +13,7 @@ const execAsync = util.promisify(exec);
|
|
|
13
13
|
const CONFIG_PATH = path.join(os.homedir(), '.sam-coder-config.json');
|
|
14
14
|
let OPENROUTER_API_KEY;
|
|
15
15
|
const MODEL = 'deepseek/deepseek-chat-v3-0324:free';
|
|
16
|
-
|
|
16
|
+
let API_BASE_URL = 'https://openrouter.ai/api/v1';
|
|
17
17
|
|
|
18
18
|
// Tool/Function definitions for the AI
|
|
19
19
|
const tools = [
|
|
@@ -508,12 +508,10 @@ async function handleToolCalls(toolCalls, messages) {
|
|
|
508
508
|
}
|
|
509
509
|
|
|
510
510
|
// Process a query with tool calling
|
|
511
|
-
async function processQueryWithTools(query, conversation = []
|
|
511
|
+
async function processQueryWithTools(query, conversation = []) {
|
|
512
512
|
// Add user message to conversation
|
|
513
513
|
const userMessage = { role: 'user', content: query };
|
|
514
|
-
|
|
515
|
-
let iteration = 0;
|
|
516
|
-
let finalResponse = null;
|
|
514
|
+
const messages = [...conversation, userMessage];
|
|
517
515
|
|
|
518
516
|
// Add system message if this is the first message
|
|
519
517
|
if (conversation.length === 0) {
|
|
@@ -526,54 +524,50 @@ If a tool fails, you can try again with different parameters or a different appr
|
|
|
526
524
|
});
|
|
527
525
|
}
|
|
528
526
|
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
// If there are no tool calls, we're done
|
|
539
|
-
if (!assistantMessage.tool_calls || assistantMessage.tool_calls.length === 0) {
|
|
540
|
-
ui.stopThinking();
|
|
541
|
-
finalResponse = assistantMessage.content || 'No content in response';
|
|
542
|
-
break;
|
|
543
|
-
}
|
|
544
|
-
|
|
545
|
-
// Process tool calls
|
|
546
|
-
console.log(`đ ī¸ Executing ${assistantMessage.tool_calls.length} tools...`);
|
|
547
|
-
const toolResults = await handleToolCalls(assistantMessage.tool_calls, messages);
|
|
548
|
-
|
|
549
|
-
// Add tool results to messages
|
|
550
|
-
messages = [...messages, ...toolResults];
|
|
551
|
-
|
|
552
|
-
// If we've reached max iterations, get a final response
|
|
553
|
-
if (iteration === maxIterations - 1) {
|
|
554
|
-
console.log('âšī¸ Reached maximum number of iterations. Getting final response...');
|
|
555
|
-
const finalResponseObj = await callOpenRouterWithTools(messages);
|
|
556
|
-
finalResponse = finalResponseObj.choices[0].message.content || 'No content in final response';
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
iteration++;
|
|
560
|
-
} catch (error) {
|
|
527
|
+
ui.startThinking();
|
|
528
|
+
|
|
529
|
+
try {
|
|
530
|
+
const response = await callOpenRouterWithTools(messages);
|
|
531
|
+
const assistantMessage = response.choices[0].message;
|
|
532
|
+
messages.push(assistantMessage);
|
|
533
|
+
|
|
534
|
+
// If there are no tool calls, we're done
|
|
535
|
+
if (!assistantMessage.tool_calls || assistantMessage.tool_calls.length === 0) {
|
|
561
536
|
ui.stopThinking();
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
537
|
+
return {
|
|
538
|
+
response: assistantMessage.content || 'No content in response',
|
|
539
|
+
conversation: messages
|
|
540
|
+
};
|
|
565
541
|
}
|
|
542
|
+
|
|
543
|
+
// Process tool calls
|
|
544
|
+
ui.stopThinking(); // Stop thinking while tools execute
|
|
545
|
+
console.log(`đ ī¸ Executing ${assistantMessage.tool_calls.length} tools...`);
|
|
546
|
+
const toolResults = await handleToolCalls(assistantMessage.tool_calls, messages);
|
|
547
|
+
|
|
548
|
+
// Add tool results to messages
|
|
549
|
+
messages.push(...toolResults);
|
|
550
|
+
|
|
551
|
+
// Now, get the AI's response to the tool results
|
|
552
|
+
ui.startThinking();
|
|
553
|
+
const finalResponseObj = await callOpenRouterWithTools(messages);
|
|
554
|
+
const finalAssistantMessage = finalResponseObj.choices[0].message;
|
|
555
|
+
messages.push(finalAssistantMessage);
|
|
556
|
+
ui.stopThinking();
|
|
557
|
+
|
|
558
|
+
return {
|
|
559
|
+
response: finalAssistantMessage.content || 'Actions executed. What is the next step?',
|
|
560
|
+
conversation: messages
|
|
561
|
+
};
|
|
562
|
+
|
|
563
|
+
} catch (error) {
|
|
564
|
+
ui.stopThinking();
|
|
565
|
+
console.error('â Error during processing:', error);
|
|
566
|
+
return {
|
|
567
|
+
response: `An error occurred: ${error.message}`,
|
|
568
|
+
conversation: messages
|
|
569
|
+
};
|
|
566
570
|
}
|
|
567
|
-
|
|
568
|
-
// If we don't have a final response yet (shouldn't happen, but just in case)
|
|
569
|
-
if (!finalResponse) {
|
|
570
|
-
finalResponse = 'No response generated. The operation may have timed out or encountered an error.';
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
return {
|
|
574
|
-
response: finalResponse,
|
|
575
|
-
conversation: messages
|
|
576
|
-
};
|
|
577
571
|
}
|
|
578
572
|
|
|
579
573
|
// Execute a single action from the action system
|
|
@@ -781,8 +775,19 @@ async function runSetup(isReconfig = false) {
|
|
|
781
775
|
}
|
|
782
776
|
|
|
783
777
|
const apiKey = await askQuestion('Enter OpenRouter API Key: ');
|
|
778
|
+
const proCode = await askQuestion('Enter Pro Plan activation code (or press Enter to skip): ');
|
|
779
|
+
|
|
780
|
+
let config = { OPENROUTER_API_KEY: apiKey, isPro: false };
|
|
781
|
+
|
|
782
|
+
if (proCode === '1234') {
|
|
783
|
+
console.log('â
Pro Plan activated!');
|
|
784
|
+
const customEndpoint = await askQuestion('Enter custom OpenAI-compatible API endpoint: ');
|
|
785
|
+
config.isPro = true;
|
|
786
|
+
config.customApiBase = customEndpoint;
|
|
787
|
+
} else if (proCode) {
|
|
788
|
+
console.log('â ī¸ Invalid activation code. Continuing with standard setup.');
|
|
789
|
+
}
|
|
784
790
|
|
|
785
|
-
const config = { OPENROUTER_API_KEY: apiKey };
|
|
786
791
|
await writeConfig(config);
|
|
787
792
|
|
|
788
793
|
console.log('â
Configuration saved successfully!');
|
|
@@ -799,6 +804,10 @@ async function start() {
|
|
|
799
804
|
}
|
|
800
805
|
|
|
801
806
|
OPENROUTER_API_KEY = config.OPENROUTER_API_KEY;
|
|
807
|
+
if (config.isPro && config.customApiBase) {
|
|
808
|
+
API_BASE_URL = config.customApiBase;
|
|
809
|
+
console.log(`đ Using Pro Plan custom endpoint: ${API_BASE_URL}`);
|
|
810
|
+
}
|
|
802
811
|
|
|
803
812
|
ui.showHeader();
|
|
804
813
|
console.log('Select Mode:');
|
|
@@ -1,125 +1,218 @@
|
|
|
1
1
|
import pygame
|
|
2
|
-
import time
|
|
3
2
|
import random
|
|
4
3
|
|
|
5
4
|
# Initialize pygame
|
|
6
5
|
pygame.init()
|
|
7
6
|
|
|
8
|
-
#
|
|
9
|
-
|
|
7
|
+
# Constants
|
|
8
|
+
SCREEN_WIDTH = 300
|
|
9
|
+
SCREEN_HEIGHT = 600
|
|
10
|
+
BLOCK_SIZE = 30
|
|
11
|
+
GRID_WIDTH = 10
|
|
12
|
+
GRID_HEIGHT = 20
|
|
13
|
+
GAME_AREA_LEFT = (SCREEN_WIDTH - GRID_WIDTH * BLOCK_SIZE) // 2
|
|
14
|
+
GAME_AREA_TOP = SCREEN_HEIGHT - GRID_HEIGHT * BLOCK_SIZE
|
|
10
15
|
|
|
11
16
|
# Colors
|
|
12
|
-
WHITE = (255, 255, 255)
|
|
13
17
|
BLACK = (0, 0, 0)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
#
|
|
19
|
-
|
|
18
|
+
WHITE = (255, 255, 255)
|
|
19
|
+
GRAY = (128, 128, 128)
|
|
20
|
+
COLORS = [
|
|
21
|
+
(0, 255, 255), # Cyan (I)
|
|
22
|
+
(0, 0, 255), # Blue (J)
|
|
23
|
+
(255, 165, 0), # Orange (L)
|
|
24
|
+
(255, 255, 0), # Yellow (O)
|
|
25
|
+
(0, 255, 0), # Green (S)
|
|
26
|
+
(128, 0, 128), # Purple (T)
|
|
27
|
+
(255, 0, 0) # Red (Z)
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
# Tetrimino shapes
|
|
31
|
+
SHAPES = [
|
|
32
|
+
[[1, 1, 1, 1]], # I
|
|
33
|
+
[[1, 0, 0], [1, 1, 1]], # J
|
|
34
|
+
[[0, 0, 1], [1, 1, 1]], # L
|
|
35
|
+
[[1, 1], [1, 1]], # O
|
|
36
|
+
[[0, 1, 1], [1, 1, 0]], # S
|
|
37
|
+
[[0, 1, 0], [1, 1, 1]], # T
|
|
38
|
+
[[1, 1, 0], [0, 1, 1]] # Z
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
# Set up the display
|
|
42
|
+
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
|
|
43
|
+
pygame.display.set_caption("Tetris")
|
|
20
44
|
|
|
21
|
-
# Clock for controlling the speed of the snake
|
|
22
45
|
clock = pygame.time.Clock()
|
|
23
46
|
|
|
24
|
-
#
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
47
|
+
# Game variables
|
|
48
|
+
grid = [[0 for _ in range(GRID_WIDTH)] for _ in range(GRID_HEIGHT)]
|
|
49
|
+
current_piece = None
|
|
50
|
+
next_piece = None
|
|
51
|
+
current_x = GRID_WIDTH // 2
|
|
52
|
+
current_y = 0
|
|
53
|
+
score = 0
|
|
54
|
+
game_over = False
|
|
55
|
+
fall_time = 0
|
|
56
|
+
fall_speed = 0.5 # seconds
|
|
57
|
+
|
|
58
|
+
def new_piece():
|
|
59
|
+
global current_piece, next_piece, current_x, current_y
|
|
60
|
+
if next_piece is None:
|
|
61
|
+
next_piece = random.randint(0, len(SHAPES) - 1)
|
|
62
|
+
current_piece = next_piece
|
|
63
|
+
next_piece = random.randint(0, len(SHAPES) - 1)
|
|
64
|
+
current_x = GRID_WIDTH // 2 - len(SHAPES[current_piece][0]) // 2
|
|
65
|
+
current_y = 0
|
|
66
|
+
if check_collision():
|
|
67
|
+
return False
|
|
68
|
+
return True
|
|
69
|
+
|
|
70
|
+
def check_collision():
|
|
71
|
+
for y, row in enumerate(SHAPES[current_piece]):
|
|
72
|
+
for x, cell in enumerate(row):
|
|
73
|
+
if cell:
|
|
74
|
+
if (current_y + y >= GRID_HEIGHT or
|
|
75
|
+
current_x + x < 0 or
|
|
76
|
+
current_x + x >= GRID_WIDTH or
|
|
77
|
+
grid[current_y + y][current_x + x]):
|
|
78
|
+
return True
|
|
79
|
+
return False
|
|
80
|
+
|
|
81
|
+
def merge_piece():
|
|
82
|
+
for y, row in enumerate(SHAPES[current_piece]):
|
|
83
|
+
for x, cell in enumerate(row):
|
|
84
|
+
if cell:
|
|
85
|
+
grid[current_y + y][current_x + x] = current_piece + 1
|
|
86
|
+
|
|
87
|
+
def clear_lines():
|
|
88
|
+
global grid, score
|
|
89
|
+
lines_cleared = 0
|
|
90
|
+
for y in range(GRID_HEIGHT - 1, -1, -1):
|
|
91
|
+
if all(grid[y]):
|
|
92
|
+
lines_cleared += 1
|
|
93
|
+
for y2 in range(y, 0, -1):
|
|
94
|
+
grid[y2] = grid[y2 - 1][:]
|
|
95
|
+
grid[0] = [0] * GRID_WIDTH
|
|
96
|
+
score += lines_cleared ** 2 * 100
|
|
97
|
+
|
|
98
|
+
def draw_grid():
|
|
99
|
+
for y in range(GRID_HEIGHT):
|
|
100
|
+
for x in range(GRID_WIDTH):
|
|
101
|
+
if grid[y][x]:
|
|
102
|
+
pygame.draw.rect(
|
|
103
|
+
screen, COLORS[grid[y][x] - 1],
|
|
104
|
+
(GAME_AREA_LEFT + x * BLOCK_SIZE, GAME_AREA_TOP + y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE)
|
|
105
|
+
)
|
|
106
|
+
pygame.draw.rect(
|
|
107
|
+
screen, WHITE,
|
|
108
|
+
(GAME_AREA_LEFT + x * BLOCK_SIZE, GAME_AREA_TOP + y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE),
|
|
109
|
+
1
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
def draw_piece():
|
|
113
|
+
for y, row in enumerate(SHAPES[current_piece]):
|
|
114
|
+
for x, cell in enumerate(row):
|
|
115
|
+
if cell:
|
|
116
|
+
pygame.draw.rect(
|
|
117
|
+
screen, COLORS[current_piece],
|
|
118
|
+
(GAME_AREA_LEFT + (current_x + x) * BLOCK_SIZE, GAME_AREA_TOP + (current_y + y) * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE)
|
|
119
|
+
)
|
|
120
|
+
pygame.draw.rect(
|
|
121
|
+
screen, WHITE,
|
|
122
|
+
(GAME_AREA_LEFT + (current_x + x) * BLOCK_SIZE, GAME_AREA_TOP + (current_y + y) * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE),
|
|
123
|
+
1
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
def draw_next_piece():
|
|
127
|
+
if next_piece is not None:
|
|
128
|
+
font = pygame.font.SysFont(None, 24)
|
|
129
|
+
text = font.render("Next:", True, WHITE)
|
|
130
|
+
screen.blit(text, (20, 20))
|
|
131
|
+
for y, row in enumerate(SHAPES[next_piece]):
|
|
132
|
+
for x, cell in enumerate(row):
|
|
133
|
+
if cell:
|
|
134
|
+
pygame.draw.rect(
|
|
135
|
+
screen, COLORS[next_piece],
|
|
136
|
+
(40 + x * BLOCK_SIZE, 50 + y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE)
|
|
137
|
+
)
|
|
138
|
+
pygame.draw.rect(
|
|
139
|
+
screen, WHITE,
|
|
140
|
+
(40 + x * BLOCK_SIZE, 50 + y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE),
|
|
141
|
+
1
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
def draw_score():
|
|
145
|
+
font = pygame.font.SysFont(None, 36)
|
|
146
|
+
text = font.render(f"Score: {score}", True, WHITE)
|
|
147
|
+
screen.blit(text, (20, SCREEN_HEIGHT - 50))
|
|
148
|
+
|
|
149
|
+
def rotate_piece():
|
|
150
|
+
global current_piece
|
|
151
|
+
rotated = list(zip(*reversed(SHAPES[current_piece])))
|
|
152
|
+
for y in range(len(rotated)):
|
|
153
|
+
rotated[y] = list(rotated[y])
|
|
154
|
+
old_shape = SHAPES[current_piece]
|
|
155
|
+
SHAPES[current_piece] = rotated
|
|
156
|
+
if check_collision():
|
|
157
|
+
SHAPES[current_piece] = old_shape
|
|
158
|
+
|
|
159
|
+
# Main game loop
|
|
160
|
+
new_piece()
|
|
161
|
+
running = True
|
|
162
|
+
while running:
|
|
163
|
+
screen.fill(BLACK)
|
|
164
|
+
fall_time += clock.get_rawtime() / 1000 # Convert to seconds
|
|
165
|
+
clock.tick()
|
|
166
|
+
|
|
167
|
+
if fall_time >= fall_speed:
|
|
168
|
+
fall_time = 0
|
|
169
|
+
current_y += 1
|
|
170
|
+
if check_collision():
|
|
171
|
+
current_y -= 1
|
|
172
|
+
merge_piece()
|
|
173
|
+
clear_lines()
|
|
174
|
+
if not new_piece():
|
|
74
175
|
game_over = True
|
|
75
|
-
if event.type == pygame.KEYDOWN:
|
|
76
|
-
if event.key == pygame.K_LEFT:
|
|
77
|
-
x1_change = -BLOCK_SIZE
|
|
78
|
-
y1_change = 0
|
|
79
|
-
elif event.key == pygame.K_RIGHT:
|
|
80
|
-
x1_change = BLOCK_SIZE
|
|
81
|
-
y1_change = 0
|
|
82
|
-
elif event.key == pygame.K_UP:
|
|
83
|
-
y1_change = -BLOCK_SIZE
|
|
84
|
-
x1_change = 0
|
|
85
|
-
elif event.key == pygame.K_DOWN:
|
|
86
|
-
y1_change = BLOCK_SIZE
|
|
87
|
-
x1_change = 0
|
|
88
|
-
|
|
89
|
-
if x1 >= WIDTH or x1 < 0 or y1 >= HEIGHT or y1 < 0:
|
|
90
|
-
game_close = True
|
|
91
|
-
x1 += x1_change
|
|
92
|
-
y1 += y1_change
|
|
93
|
-
screen.fill(BLACK)
|
|
94
|
-
pygame.draw.rect(screen, GREEN, [foodx, foody, BLOCK_SIZE, BLOCK_SIZE])
|
|
95
|
-
snake_head = []
|
|
96
|
-
snake_head.append(x1)
|
|
97
|
-
snake_head.append(y1)
|
|
98
|
-
snake_list.append(snake_head)
|
|
99
|
-
if len(snake_list) > length_of_snake:
|
|
100
|
-
del snake_list[0]
|
|
101
|
-
|
|
102
|
-
for pos in snake_list[:-1]:
|
|
103
|
-
if pos == snake_head:
|
|
104
|
-
game_close = True
|
|
105
|
-
|
|
106
|
-
our_snake(BLOCK_SIZE, snake_list)
|
|
107
|
-
your_score(length_of_snake - 1)
|
|
108
176
|
|
|
177
|
+
for event in pygame.event.get():
|
|
178
|
+
if event.type == pygame.QUIT:
|
|
179
|
+
running = False
|
|
180
|
+
if event.type == pygame.KEYDOWN:
|
|
181
|
+
if event.key == pygame.K_LEFT:
|
|
182
|
+
current_x -= 1
|
|
183
|
+
if check_collision():
|
|
184
|
+
current_x += 1
|
|
185
|
+
if event.key == pygame.K_RIGHT:
|
|
186
|
+
current_x += 1
|
|
187
|
+
if check_collision():
|
|
188
|
+
current_x -= 1
|
|
189
|
+
if event.key == pygame.K_DOWN:
|
|
190
|
+
current_y += 1
|
|
191
|
+
if check_collision():
|
|
192
|
+
current_y -= 1
|
|
193
|
+
if event.key == pygame.K_UP:
|
|
194
|
+
rotate_piece()
|
|
195
|
+
if event.key == pygame.K_SPACE:
|
|
196
|
+
while not check_collision():
|
|
197
|
+
current_y += 1
|
|
198
|
+
current_y -= 1
|
|
199
|
+
merge_piece()
|
|
200
|
+
clear_lines()
|
|
201
|
+
if not new_piece():
|
|
202
|
+
game_over = True
|
|
203
|
+
|
|
204
|
+
draw_grid()
|
|
205
|
+
draw_piece()
|
|
206
|
+
draw_next_piece()
|
|
207
|
+
draw_score()
|
|
208
|
+
pygame.display.update()
|
|
209
|
+
|
|
210
|
+
if game_over:
|
|
211
|
+
font = pygame.font.SysFont(None, 48)
|
|
212
|
+
text = font.render("GAME OVER", True, WHITE)
|
|
213
|
+
screen.blit(text, (SCREEN_WIDTH // 2 - 100, SCREEN_HEIGHT // 2 - 24))
|
|
109
214
|
pygame.display.update()
|
|
215
|
+
pygame.time.wait(2000)
|
|
216
|
+
running = False
|
|
110
217
|
|
|
111
|
-
|
|
112
|
-
foodx = round(random.randrange(0, WIDTH - BLOCK_SIZE) / 20.0) * 20.0
|
|
113
|
-
foody = round(random.randrange(0, HEIGHT - BLOCK_SIZE) / 20.0) * 20.0
|
|
114
|
-
length_of_snake += 1
|
|
115
|
-
|
|
116
|
-
clock.tick(15)
|
|
117
|
-
|
|
118
|
-
pygame.quit()
|
|
119
|
-
quit()
|
|
120
|
-
|
|
121
|
-
# Create the screen
|
|
122
|
-
screen = pygame.display.set_mode((WIDTH, HEIGHT))
|
|
123
|
-
pygame.display.set_caption('Snake Game')
|
|
124
|
-
|
|
125
|
-
gameLoop()
|
|
218
|
+
pygame.quit()
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sam-coder-cli",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "SAM-CODER: An animated command-line AI assistant with agency capabilities.",
|
|
5
5
|
"main": "bin/agi-cli.js",
|
|
6
6
|
"bin": {
|
|
7
|
-
"sam-coder": "
|
|
7
|
+
"sam-coder": "bin/agi-cli.js"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"start": "node ./bin/agi-cli.js"
|