sharkcode 0.1.0 → 0.2.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 (2) hide show
  1. package/dist/cli.mjs +104 -39
  2. package/package.json +1 -1
package/dist/cli.mjs CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  // src/cli.ts
4
4
  import chalk3 from "chalk";
5
+ import * as readline2 from "readline";
5
6
 
6
7
  // src/config.ts
7
8
  import { parse } from "smol-toml";
@@ -235,12 +236,12 @@ Guidelines:
235
236
  - Keep changes minimal and focused on the user's request
236
237
  - When done, summarize what you changed`;
237
238
  }
238
- async function runAgent(prompt, config) {
239
+ async function runAgent(messages, config) {
239
240
  const model = createProvider(config);
240
241
  const result = streamText({
241
242
  model,
242
243
  system: buildSystemPrompt(),
243
- prompt,
244
+ messages,
244
245
  tools,
245
246
  stopWhen: stepCountIs(30)
246
247
  });
@@ -250,31 +251,33 @@ async function runAgent(prompt, config) {
250
251
  case "text-delta":
251
252
  process.stdout.write(event.text);
252
253
  break;
253
- case "tool-input-available":
254
+ case "tool-call":
254
255
  process.stdout.write(
255
256
  chalk2.cyan(`
256
257
  \u{1F527} ${event.toolName}`) + chalk2.gray(`(${formatArgs(event.input)})
257
258
  `)
258
259
  );
259
260
  break;
260
- case "tool-output-available":
261
+ case "tool-result":
261
262
  process.stdout.write(
262
- chalk2.green(`\u2705 tool`) + chalk2.gray(` \u2192 ${truncate(String(event.output), 120)}
263
+ chalk2.green(`\u2705 done`) + chalk2.gray(` \u2192 ${truncate(String(event.output), 120)}
263
264
 
264
265
  `)
265
266
  );
266
267
  break;
267
- case "tool-output-error":
268
- process.stderr.write(chalk2.red(`
269
- \u274C Tool error: ${event.errorText}
270
- `));
268
+ case "tool-error":
269
+ process.stderr.write(
270
+ chalk2.red(`
271
+ \u274C Tool error [${event.toolName}]: ${String(event.error)}
272
+ `)
273
+ );
271
274
  break;
272
275
  case "finish-step":
273
276
  currentStep++;
274
277
  break;
275
278
  case "error":
276
279
  process.stderr.write(chalk2.red(`
277
- \u274C Error: ${event.errorText}
280
+ \u274C Error: ${String(event.error)}
278
281
  `));
279
282
  break;
280
283
  }
@@ -290,6 +293,12 @@ async function runAgent(prompt, config) {
290
293
  )
291
294
  );
292
295
  }
296
+ try {
297
+ const { messages: responseMessages } = await result.response;
298
+ return [...messages, ...responseMessages];
299
+ } catch {
300
+ return messages;
301
+ }
293
302
  }
294
303
  function formatArgs(args) {
295
304
  if (typeof args !== "object" || args === null) return String(args);
@@ -305,47 +314,103 @@ function truncate(str, max) {
305
314
  }
306
315
 
307
316
  // src/cli.ts
308
- var BANNER = chalk3.bold.cyan(`
309
- \u{1F988} Shark Code v0.1
310
- AI Coding Agent \u2014 Local First, Open Source
311
- `);
312
- var HELP = `${BANNER}
313
- ${chalk3.white("Usage:")}
314
- ${chalk3.green("sharkcode")} ${chalk3.yellow('"your prompt here"')}
315
-
316
- ${chalk3.white("Examples:")}
317
- sharkcode "explain this codebase"
318
- sharkcode "fix the null pointer bug in auth.ts"
319
- sharkcode "add error handling to the API routes"
320
-
321
- ${chalk3.white("Config:")}
322
- Set ${chalk3.yellow("DEEPSEEK_API_KEY")} env var, or edit ${chalk3.gray("~/.sharkcode/config.toml")}
323
- Get your key at ${chalk3.underline("https://platform.deepseek.com")}
324
- `;
317
+ var PURPLE = chalk3.hex("#a855f7");
318
+ var GLYPHS = {
319
+ S: [[0, 1, 1, 1, 1], [1, 0, 0, 0, 0], [0, 1, 1, 1, 0], [0, 0, 0, 0, 1], [1, 1, 1, 1, 0]],
320
+ H: [[1, 0, 0, 0, 1], [1, 0, 0, 0, 1], [1, 1, 1, 1, 1], [1, 0, 0, 0, 1], [1, 0, 0, 0, 1]],
321
+ A: [[0, 1, 1, 1, 0], [1, 0, 0, 0, 1], [1, 1, 1, 1, 1], [1, 0, 0, 0, 1], [1, 0, 0, 0, 1]],
322
+ R: [[1, 1, 1, 1, 0], [1, 0, 0, 0, 1], [1, 1, 1, 1, 0], [1, 0, 1, 0, 0], [1, 0, 0, 1, 0]],
323
+ K: [[1, 0, 0, 1, 0], [1, 0, 1, 0, 0], [1, 1, 0, 0, 0], [1, 0, 1, 0, 0], [1, 0, 0, 1, 0]],
324
+ C: [[0, 1, 1, 1, 0], [1, 0, 0, 0, 1], [1, 0, 0, 0, 0], [1, 0, 0, 0, 1], [0, 1, 1, 1, 0]],
325
+ O: [[0, 1, 1, 1, 0], [1, 0, 0, 0, 1], [1, 0, 0, 0, 1], [1, 0, 0, 0, 1], [0, 1, 1, 1, 0]],
326
+ D: [[1, 1, 1, 1, 0], [1, 0, 0, 0, 1], [1, 0, 0, 0, 1], [1, 0, 0, 0, 1], [1, 1, 1, 1, 0]],
327
+ E: [[1, 1, 1, 1, 1], [1, 0, 0, 0, 0], [1, 1, 1, 1, 0], [1, 0, 0, 0, 0], [1, 1, 1, 1, 1]]
328
+ };
329
+ function renderWord(word, padLeft = 2) {
330
+ const letters = word.toUpperCase().split("").map((c) => GLYPHS[c]);
331
+ const rows = [];
332
+ for (let row = 0; row < 5; row++) {
333
+ let line = " ".repeat(padLeft);
334
+ for (let i = 0; i < letters.length; i++) {
335
+ const letter = letters[i];
336
+ for (let col = 0; col < letter[row].length; col++) {
337
+ line += letter[row][col] ? "\u2588\u2588" : " ";
338
+ }
339
+ if (i < letters.length - 1) line += " ";
340
+ }
341
+ rows.push(PURPLE(line));
342
+ }
343
+ return rows;
344
+ }
345
+ var BANNER = ["", ...renderWord("shark", 2), "", ...renderWord("code", 8), ""].join("\n");
346
+ async function readLine(prompt) {
347
+ return new Promise((resolve4) => {
348
+ const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
349
+ let answered = false;
350
+ rl.question(prompt, (answer) => {
351
+ answered = true;
352
+ rl.close();
353
+ resolve4(answer);
354
+ });
355
+ rl.on("close", () => {
356
+ if (!answered) resolve4(null);
357
+ });
358
+ });
359
+ }
325
360
  async function main() {
326
361
  const args = process.argv.slice(2);
327
- if (args.length === 0 || args[0] === "--help" || args[0] === "-h") {
328
- console.log(HELP);
362
+ if (args[0] === "--help" || args[0] === "-h") {
363
+ console.log(BANNER);
364
+ console.log(PURPLE(" Usage:"));
365
+ console.log(" " + PURPLE("sharkcode") + chalk3.gray(" \u2014 interactive mode"));
366
+ console.log(" " + PURPLE("sharkcode") + chalk3.yellow(' "prompt"') + chalk3.gray(" \u2014 single-shot mode\n"));
329
367
  return;
330
368
  }
331
369
  if (args[0] === "--version" || args[0] === "-v") {
332
- console.log("sharkcode v0.1.0");
370
+ console.log("sharkcode v0.2.0");
333
371
  return;
334
372
  }
335
- const prompt = args.join(" ");
336
373
  const config = loadConfig();
337
- process.stdout.write(
338
- chalk3.cyan("\u{1F988} Shark Code") + chalk3.gray(` | model: ${config.model}
339
-
340
- `)
374
+ if (args.length > 0) {
375
+ console.log(PURPLE("\n\u{1F988} SharkCode") + chalk3.gray(` | model: ${config.model}
376
+ `));
377
+ const messages2 = [{ role: "user", content: args.join(" ") }];
378
+ await runAgent(messages2, config);
379
+ return;
380
+ }
381
+ console.log(BANNER);
382
+ console.log(
383
+ PURPLE(" \u25C6") + chalk3.gray(` model: ${config.model}`) + chalk3.gray(' type "exit" to quit\n')
341
384
  );
342
- await runAgent(prompt, config);
385
+ let messages = [];
386
+ while (true) {
387
+ const input = await readLine(PURPLE("\n\u25C6 "));
388
+ if (input === null) {
389
+ console.log(chalk3.gray("\nBye! \u{1F988}"));
390
+ break;
391
+ }
392
+ const trimmed = input.trim();
393
+ if (!trimmed) continue;
394
+ if (trimmed === "exit" || trimmed === "quit" || trimmed === "/exit") {
395
+ console.log(chalk3.gray("Bye! \u{1F988}"));
396
+ break;
397
+ }
398
+ messages.push({ role: "user", content: trimmed });
399
+ try {
400
+ messages = await runAgent(messages, config);
401
+ } catch (err) {
402
+ const error = err;
403
+ console.error(chalk3.red(`
404
+ \u274C Error: ${error.message}`));
405
+ if (error.message?.includes("401") || error.message?.includes("Unauthorized")) {
406
+ console.error(chalk3.yellow(" Check your API key in ~/.sharkcode/config.toml"));
407
+ }
408
+ messages = messages.slice(0, -1);
409
+ }
410
+ }
343
411
  }
344
412
  main().catch((err) => {
345
413
  console.error(chalk3.red(`
346
414
  \u274C Fatal: ${err.message}`));
347
- if (err.message?.includes("401") || err.message?.includes("Unauthorized")) {
348
- console.error(chalk3.yellow(" Check your API key in ~/.sharkcode/config.toml"));
349
- }
350
415
  process.exit(1);
351
416
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sharkcode",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Local First, open-source AI Coding Agent",
5
5
  "type": "module",
6
6
  "bin": {