kiosapi 0.1.2 → 0.1.4

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.
@@ -17,19 +17,20 @@ const ROLES = {
17
17
  brief: 'Peranmu: PENINJAU. Baca file yang relevan dan tinjau hasil implementasi: sebutkan masalah/risiko & saran perbaikan singkat.',
18
18
  },
19
19
  };
20
- /** Run one role as a sub-agent and return its final text. */
21
- async function runRole(role, task, opts) {
22
- console.log(`\n${bold(role.title)}`);
23
- const s = newSession(opts.model, role.mode, opts.otomatis);
20
+ /** Run one role as a sub-agent (with its own model) and return its final text. */
21
+ async function runRole(name, task, opts) {
22
+ const role = ROLES[name];
23
+ const model = opts.models[name];
24
+ console.log(`\n${bold(role.title)} ${dim(`(${model})`)}`);
25
+ const s = newSession(model, role.mode, opts.otomatis);
24
26
  s.messages.push({ role: 'system', content: role.brief });
25
27
  return runTurn(s, task);
26
28
  }
27
29
  /** Orchestrate the perencana → pengkode → peninjau pipeline for a task. */
28
30
  export async function runTeam(task, opts) {
29
31
  console.log(bold('👥 Tim agen: perencana → pengkode → peninjau'));
30
- console.log(dim(`Model: ${opts.model}`));
31
- const plan = await runRole(ROLES.perencana, task, opts);
32
- await runRole(ROLES.pengkode, `Tugas: ${task}\n\nRencana:\n${plan || '(tidak ada rencana eksplisit)'}`, opts);
33
- await runRole(ROLES.peninjau, `Tinjau hasil implementasi untuk tugas: ${task}`, opts);
32
+ const plan = await runRole('perencana', task, opts);
33
+ await runRole('pengkode', `Tugas: ${task}\n\nRencana:\n${plan || '(tidak ada rencana eksplisit)'}`, opts);
34
+ await runRole('peninjau', `Tinjau hasil implementasi untuk tugas: ${task}`, opts);
34
35
  console.log(green('\n✓ Tim selesai.'));
35
36
  }
package/dist/commands.js CHANGED
@@ -404,19 +404,34 @@ export async function cmdLihat(args) {
404
404
  stop();
405
405
  process.stdout.write('\n');
406
406
  }
407
- /** tim — multi-agent pipeline (perencana → pengkode → peninjau). */
407
+ /**
408
+ * tim — multi-agent pipeline (perencana → pengkode → peninjau). Each role can use a different model
409
+ * via --perencana/--pengkode/--peninjau; roles without an override fall back to -m / the default.
410
+ */
408
411
  export async function cmdTim(args) {
409
412
  const { values, positionals } = parseArgs({
410
413
  args,
411
- options: { model: { type: 'string', short: 'm' }, otomatis: { type: 'boolean' } },
414
+ options: {
415
+ model: { type: 'string', short: 'm' },
416
+ otomatis: { type: 'boolean' },
417
+ perencana: { type: 'string' },
418
+ pengkode: { type: 'string' },
419
+ peninjau: { type: 'string' },
420
+ },
412
421
  allowPositionals: true,
413
422
  });
414
423
  const task = positionals.join(' ').trim();
415
424
  if (!task)
416
425
  throw new Error('Beri tugas. Contoh: kiosapi tim "bikin endpoint /health + tes"');
417
- const model = await resolveModel(values.model);
418
- await warnIfNoTools(model);
419
- await runTeam(task, { model, otomatis: Boolean(values.otomatis) });
426
+ const base = await resolveModel(values.model);
427
+ const models = {
428
+ perencana: values.perencana ?? base,
429
+ pengkode: values.pengkode ?? base,
430
+ peninjau: values.peninjau ?? base,
431
+ };
432
+ for (const m of new Set(Object.values(models)))
433
+ await warnIfNoTools(m);
434
+ await runTeam(task, { models, otomatis: Boolean(values.otomatis) });
420
435
  }
421
436
  /** saldo — show own balance, bonus tokens, and month-to-date spend. */
422
437
  export async function cmdSaldo() {
package/dist/help.js CHANGED
@@ -1,5 +1,20 @@
1
+ import { readFileSync } from 'node:fs';
1
2
  import { bold, dim } from './ui.js';
2
- export const VERSION = '0.1.2';
3
+ /**
4
+ * Version — single source of truth is package.json (always shipped in the npm tarball, sitting next
5
+ * to dist/). Read at runtime so a bump only needs editing package.json (e.g. `npm version patch`).
6
+ * dist/help.js → ../package.json resolves to the package root in both dev and the published package.
7
+ */
8
+ function readVersion() {
9
+ try {
10
+ const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
11
+ return pkg.version ?? '0.0.0';
12
+ }
13
+ catch {
14
+ return '0.0.0';
15
+ }
16
+ }
17
+ export const VERSION = readVersion();
3
18
  export function printVersion() {
4
19
  console.log(`kiosapi ${VERSION}`);
5
20
  }
package/dist/session.js CHANGED
@@ -1,10 +1,9 @@
1
- import { createInterface } from 'node:readline/promises';
2
1
  import { newSession, resetSession, runTurn } from './agent/run.js';
3
2
  import { runTeam } from './agent/team.js';
4
3
  import { resolveModel } from './api.js';
5
4
  import { cmdGambar, cmdIsi, cmdLihat, cmdMasuk, cmdPakai, cmdSaldo, cmdVideo, maybeNotifyUpdate, pickModel, warnIfNoTools, } from './commands.js';
6
5
  import { loadConfig } from './config.js';
7
- import { bold, cyan, dim, green, red } from './ui.js';
6
+ import { bold, cyan, dim, green, prompt, red } from './ui.js';
8
7
  const MODES = ['rencana', 'edit', 'buat'];
9
8
  /** The prompt indicator shows the active mode (and ⚡ when auto-approve is on). */
10
9
  function label(s) {
@@ -100,7 +99,10 @@ async function runSlash(line, s) {
100
99
  if (!task)
101
100
  console.log(red('Beri tugas. Contoh: /tim bikin endpoint /health + tes'));
102
101
  else
103
- await runTeam(task, { model: s.model, otomatis: s.otomatis });
102
+ await runTeam(task, {
103
+ models: { perencana: s.model, pengkode: s.model, peninjau: s.model },
104
+ otomatis: s.otomatis,
105
+ });
104
106
  return false;
105
107
  }
106
108
  case 'gambar':
@@ -139,33 +141,30 @@ export async function startSession() {
139
141
  const s = newSession(model, 'buat', false);
140
142
  banner(s);
141
143
  await warnIfNoTools(model);
142
- const rl = createInterface({ input: process.stdin, output: process.stdout });
143
- try {
144
- while (true) {
145
- let line;
146
- try {
147
- line = (await rl.question(label(s))).trim();
148
- }
149
- catch {
150
- break; // stdin closed (Ctrl+D / EOF)
151
- }
152
- if (!line)
153
- continue;
154
- if (line.startsWith('/')) {
155
- if (await runSlash(line, s))
156
- break;
157
- continue;
158
- }
159
- try {
160
- await runTurn(s, line);
161
- }
162
- catch (err) {
163
- console.error(red(err instanceof Error ? err.message : String(err)));
164
- }
144
+ // One readline at a time: each turn uses prompt() (create+close), and slash commands that need
145
+ // their own input (e.g. /model picker, masuk) also use prompt(). A persistent interface here would
146
+ // collide with those → double-echoed input and a stray close that exits the session.
147
+ while (true) {
148
+ let line;
149
+ try {
150
+ line = (await prompt(label(s))).trim();
151
+ }
152
+ catch {
153
+ break; // stdin closed (Ctrl+D / EOF)
154
+ }
155
+ if (!line)
156
+ continue;
157
+ if (line.startsWith('/')) {
158
+ if (await runSlash(line, s))
159
+ break;
160
+ continue;
161
+ }
162
+ try {
163
+ await runTurn(s, line);
164
+ }
165
+ catch (err) {
166
+ console.error(red(err instanceof Error ? err.message : String(err)));
165
167
  }
166
- }
167
- finally {
168
- rl.close();
169
168
  }
170
169
  console.log(green('Sampai jumpa.'));
171
170
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kiosapi",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "type": "module",
5
5
  "description": "CLI Kiosapi.id berbahasa Indonesia — bangun aplikasimu pakai API key Kiosapi (agen + multimodal).",
6
6
  "keywords": [
@@ -28,7 +28,10 @@
28
28
  "bin": {
29
29
  "kiosapi": "./dist/index.js"
30
30
  },
31
- "files": ["dist", "README.md"],
31
+ "files": [
32
+ "dist",
33
+ "README.md"
34
+ ],
32
35
  "engines": {
33
36
  "node": ">=20"
34
37
  },