kimaki 0.0.0 → 0.0.2

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/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,GAAG,mBAAgB,CAAA"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.tsx"],"names":[],"mappings":"AAcA,eAAO,MAAM,GAAG,mBAAgB,CAAA"}
package/package.json CHANGED
@@ -1,43 +1,75 @@
1
1
  {
2
2
  "name": "kimaki",
3
- "version": "0.0.0",
4
- "description": "",
3
+ "version": "0.0.2",
4
+ "description": "AI voice assistant for controlling coding agents",
5
5
  "type": "module",
6
6
  "repository": "https://github.com/remorses/kimaki",
7
+ "publishConfig": {
8
+ "access": "public"
9
+ },
10
+ "scripts": {
11
+ "build": "bun build ./src/bin.ts --outfile ./dist/bundle.js --target node --format esm --external @google/genai --external @opencode-ai/plugin --external @opencode-ai/sdk --external ai --external cac --external chalk --external chokidar --external cli-table3 --external date-fns --external globby --external ink --external js-yaml --external luxon --external mime-types --external node-web-audio-api --external picocolors --external prompts --external react --external sema4 --external sharp --external strip-ansi --external wavefile --external ws --external xdg-basedir --external zod --external eventemitter3 --external @ai-sdk/openai",
12
+ "typecheck": "tsc",
13
+ "prepublishOnly": "pnpm build",
14
+ "save-plugin": "bun build ./src/plugin.ts --outfile ~/.config/opencode/plugin/kimaki.js --target bun --format esm",
15
+ "kimaki": "tsx bin.js",
16
+ "play": "tsx src/bin.ts",
17
+ "play:prod": "node bin.js",
18
+ "watch": "tsc -w",
19
+ "test": "vitest",
20
+ "changeset": "changeset",
21
+ "version": "changeset version",
22
+ "release": "changeset publish"
23
+ },
7
24
  "bin": "./bin.js",
8
25
  "files": [
9
26
  "dist",
10
- "src",
11
27
  "bin.js"
12
28
  ],
13
- "keywords": [],
29
+ "keywords": [
30
+ "ai",
31
+ "voice",
32
+ "assistant",
33
+ "opencode",
34
+ "coding",
35
+ "agent"
36
+ ],
14
37
  "author": "Tommaso De Rossi, morse <beats.by.morse@gmail.com>",
15
- "license": "",
38
+ "license": "MIT",
16
39
  "dependencies": {
17
40
  "@google/genai": "^1.16.0",
41
+ "@opencode-ai/plugin": "^0.6.3",
42
+ "@opencode-ai/sdk": "^0.6.3",
43
+ "@types/js-yaml": "^4.0.9",
44
+ "ai": "^5.0.29",
18
45
  "cac": "^6.7.14",
46
+ "chalk": "^5.6.0",
19
47
  "chokidar": "^4.0.3",
20
48
  "cli-table3": "^0.6.5",
49
+ "date-fns": "^4.1.0",
21
50
  "globby": "^14.1.0",
22
- "mime-types": "^2.1.35",
51
+ "ink": "^6.2.3",
52
+ "js-yaml": "^4.1.0",
53
+ "@ai-sdk/openai": "^2.0.23",
54
+ "eventemitter3": "^5.0.1",
55
+ "luxon": "^3.7.1",
56
+ "mime-types": "^3.0.1",
23
57
  "node-web-audio-api": "^1.0.4",
24
58
  "picocolors": "^1.1.1",
25
59
  "prompts": "^2.4.2",
60
+ "react": "^19.1.1",
26
61
  "sema4": "^0.1.3",
27
- "tiny-jsonc": "^1.0.2",
28
- "ws": "^8.18.2"
62
+ "sharp": "^0.34.3",
63
+ "strip-ansi": "^7.1.0",
64
+ "wavefile": "^11.0.0",
65
+ "ws": "^8.18.3",
66
+ "xdg-basedir": "^5.1.0",
67
+ "zod": "^4.1.5"
29
68
  },
30
69
  "devDependencies": {
31
- "@types/mime-types": "^2.1.4",
70
+ "@types/mime-types": "^3.0.1",
32
71
  "@types/node": "^24.3.0",
33
72
  "@types/prompts": "^2.4.9",
34
73
  "@types/ws": "^8.18.1"
35
- },
36
- "scripts": {
37
- "build": "tsc ",
38
- "typecheck": "tsc",
39
- "_prepublishOnly": "tsc",
40
- "holocron": "node bin.js",
41
- "watch": "tsc -w"
42
74
  }
43
- }
75
+ }
package/dist/cli.d.ts DELETED
@@ -1,2 +0,0 @@
1
- export declare const cli: import("cac").CAC;
2
- //# sourceMappingURL=cli.d.ts.map
package/dist/cli.js DELETED
@@ -1,35 +0,0 @@
1
- import { cac } from 'cac';
2
- import pc from 'picocolors';
3
- export const cli = cac('kimaki');
4
- cli.help();
5
- // Check if running in TTY environment
6
- const isTTY = process.stdout.isTTY && process.stdin.isTTY;
7
- cli.command('', '')
8
- .action(async (options) => {
9
- try {
10
- import { Modality } from '@google/genai';
11
- import * as webAudioApi from 'node-web-audio-api';
12
- // @ts-expect-error still not typed https://github.com/ircam-ismm/node-web-audio-api/issues/73
13
- import { mediaDevices } from 'node-web-audio-api';
14
- const token = process.env.TOKEN;
15
- Object.assign(globalThis, webAudioApi);
16
- // @ts-expect-error still not typed https://github.com/ircam-ismm/node-web-audio-api/issues/73
17
- navigator.mediaDevices = mediaDevices;
18
- const { LiveAPIClient } = await import('liveapi');
19
- const newClient = new LiveAPIClient({
20
- apiKey: token,
21
- config: {
22
- responseModalities: [Modality.AUDIO],
23
- // tools: callableTools,
24
- },
25
- });
26
- // Connect to the API
27
- const connected = await newClient.connect();
28
- }
29
- catch (error) {
30
- console.error(pc.red('\nError initializing project:'));
31
- console.error(pc.red(error));
32
- process.exit(1);
33
- }
34
- });
35
- //# sourceMappingURL=cli.js.map
package/dist/cli.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,KAAK,CAAA;AACzB,OAAO,EAAE,MAAM,YAAY,CAAA;AAE3B,MAAM,CAAC,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC,CAAA;AAEhC,GAAG,CAAC,IAAI,EAAE,CAAA;AAEV,sCAAsC;AACtC,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,CAAA;AAEzD,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC;KAEd,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACtB,IAAI,CAAC;QACD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;QACxC,OAAO,KAAK,WAAW,MAAM,oBAAoB,CAAA;QACjD,8FAA8F;QAC9F,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;QAEjD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAA;QAE/B,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,CAAA;QACtC,8FAA8F;QAC9F,SAAS,CAAC,YAAY,GAAG,YAAY,CAAA;QAErC,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAA;QACjD,MAAM,SAAS,GAAG,IAAI,aAAa,CAAC;YAChC,MAAM,EAAE,KAAM;YACd,MAAM,EAAE;gBACJ,kBAAkB,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC;gBACpC,wBAAwB;aAC3B;SACJ,CAAC,CAAA;QAEF,qBAAqB;QACrB,MAAM,SAAS,GAAG,MAAM,SAAS,CAAC,OAAO,EAAE,CAAA;IAC/C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC,CAAA;QACtD,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAA;QAC5B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACnB,CAAC;AACL,CAAC,CAAC,CAAA"}
package/dist/utils.d.ts DELETED
@@ -1,16 +0,0 @@
1
- export declare function getCurrentGitBranch(): Promise<string | undefined>;
2
- export declare function openUrlInBrowser(url: string): void;
3
- export declare function safeParseJson<T = any>(str: string): T | undefined;
4
- export declare function getGitRepoRoot(): string | undefined;
5
- export declare function getGitRemoteUrl(): string | undefined;
6
- export declare function getGitHubInfo(): {
7
- githubOwner: string;
8
- githubRepo: string;
9
- name: string;
10
- } | undefined;
11
- export declare function checkGitStatus(): {
12
- hasUncommittedChanges: boolean;
13
- hasUnpushedCommits: boolean;
14
- error?: string;
15
- };
16
- //# sourceMappingURL=utils.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAOA,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAgCvE;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,QAqB3C;AAED,wBAAgB,aAAa,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAMjE;AAED,wBAAgB,cAAc,IAAI,MAAM,GAAG,SAAS,CASnD;AAED,wBAAgB,eAAe,IAAI,MAAM,GAAG,SAAS,CAQpD;AAED,wBAAgB,aAAa,IACvB;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACzD,SAAS,CAad;AAED,wBAAgB,cAAc,IAAI;IAC9B,qBAAqB,EAAE,OAAO,CAAA;IAC9B,kBAAkB,EAAE,OAAO,CAAA;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAA;CACjB,CAgDA"}
package/dist/utils.js DELETED
@@ -1,150 +0,0 @@
1
- import os from 'node:os';
2
- import path from 'node:path';
3
- import { execSync } from 'node:child_process';
4
- export async function getCurrentGitBranch() {
5
- try {
6
- // First check if we're in a git repository
7
- try {
8
- execSync('git rev-parse --git-dir', { stdio: 'ignore' });
9
- }
10
- catch {
11
- return undefined;
12
- }
13
- // Check if HEAD exists and has commits
14
- try {
15
- execSync('git rev-parse --verify HEAD', { stdio: 'ignore' });
16
- }
17
- catch {
18
- // No commits yet, check if we're on a branch
19
- try {
20
- const branch = execSync('git symbolic-ref --short HEAD', {
21
- encoding: 'utf-8',
22
- }).trim();
23
- return branch;
24
- }
25
- catch {
26
- return undefined;
27
- }
28
- }
29
- // Normal case: get current branch
30
- const branch = execSync('git rev-parse --abbrev-ref HEAD', {
31
- encoding: 'utf-8',
32
- }).trim();
33
- return branch === 'HEAD' ? undefined : branch;
34
- }
35
- catch (e) {
36
- return undefined;
37
- }
38
- }
39
- export function openUrlInBrowser(url) {
40
- let command;
41
- switch (os.platform()) {
42
- case 'darwin':
43
- command = `open "${url}"`;
44
- break;
45
- case 'win32':
46
- command = `start "" "${url}"`;
47
- break;
48
- default:
49
- // linux, unix, etc.
50
- command = `xdg-open "${url}"`;
51
- break;
52
- }
53
- try {
54
- execSync(command, { stdio: 'ignore' });
55
- }
56
- catch (error) {
57
- console.error('Failed to open URL in browser:', error);
58
- }
59
- }
60
- export function safeParseJson(str) {
61
- try {
62
- return JSON.parse(str);
63
- }
64
- catch (e) {
65
- return undefined;
66
- }
67
- }
68
- export function getGitRepoRoot() {
69
- try {
70
- const repoRoot = execSync('git rev-parse --show-toplevel', {
71
- encoding: 'utf-8',
72
- }).trim();
73
- return path.resolve(repoRoot);
74
- }
75
- catch {
76
- return undefined;
77
- }
78
- }
79
- export function getGitRemoteUrl() {
80
- try {
81
- return execSync('git remote get-url origin', {
82
- encoding: 'utf-8',
83
- }).trim();
84
- }
85
- catch {
86
- return undefined;
87
- }
88
- }
89
- export function getGitHubInfo() {
90
- const remoteUrl = getGitRemoteUrl();
91
- if (!remoteUrl)
92
- return undefined;
93
- const match = remoteUrl.match(/github\.com[\/:]([^\/]+)\/([^\/\.]+)/);
94
- if (match) {
95
- return {
96
- githubOwner: match[1],
97
- githubRepo: match[2],
98
- name: match[2],
99
- };
100
- }
101
- return undefined;
102
- }
103
- export function checkGitStatus() {
104
- try {
105
- // Check for uncommitted changes using porcelain format for machine readable output
106
- const gitStatus = execSync('git status --porcelain', {
107
- encoding: 'utf-8',
108
- }).trim();
109
- const hasUncommittedChanges = gitStatus.length > 0;
110
- // Check for unpushed commits
111
- let hasUnpushedCommits = false;
112
- try {
113
- const currentBranch = execSync('git rev-parse --abbrev-ref HEAD', {
114
- encoding: 'utf-8',
115
- }).trim();
116
- if (currentBranch && currentBranch !== 'HEAD') {
117
- // Check if remote branch exists
118
- try {
119
- execSync(`git rev-parse --verify origin/${currentBranch}`, {
120
- stdio: 'ignore',
121
- });
122
- // Remote branch exists, check for unpushed commits
123
- const unpushedCommits = execSync(`git log origin/${currentBranch}..${currentBranch} --oneline`, { encoding: 'utf-8' }).trim();
124
- hasUnpushedCommits = unpushedCommits.length > 0;
125
- }
126
- catch {
127
- // Remote branch doesn't exist, so we have unpushed commits
128
- hasUnpushedCommits = true;
129
- }
130
- }
131
- }
132
- catch (e) {
133
- // Could not determine branch or remote status
134
- return {
135
- hasUncommittedChanges,
136
- hasUnpushedCommits: false,
137
- error: 'Could not check remote branch status',
138
- };
139
- }
140
- return { hasUncommittedChanges, hasUnpushedCommits };
141
- }
142
- catch (e) {
143
- return {
144
- hasUncommittedChanges: false,
145
- hasUnpushedCommits: false,
146
- error: e.message,
147
- };
148
- }
149
- }
150
- //# sourceMappingURL=utils.js.map
package/dist/utils.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"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"}
package/src/cli.ts DELETED
@@ -1,42 +0,0 @@
1
- import { cac } from 'cac'
2
- import pc from 'picocolors'
3
-
4
- export const cli = cac('kimaki')
5
-
6
- cli.help()
7
-
8
- // Check if running in TTY environment
9
- const isTTY = process.stdout.isTTY && process.stdin.isTTY
10
-
11
- cli.command('', '')
12
-
13
- .action(async (options) => {
14
- try {
15
- import { Modality } from '@google/genai'
16
- import * as webAudioApi from 'node-web-audio-api'
17
- // @ts-expect-error still not typed https://github.com/ircam-ismm/node-web-audio-api/issues/73
18
- import { mediaDevices } from 'node-web-audio-api'
19
-
20
- const token = process.env.TOKEN
21
-
22
- Object.assign(globalThis, webAudioApi)
23
- // @ts-expect-error still not typed https://github.com/ircam-ismm/node-web-audio-api/issues/73
24
- navigator.mediaDevices = mediaDevices
25
-
26
- const { LiveAPIClient } = await import('liveapi')
27
- const newClient = new LiveAPIClient({
28
- apiKey: token!,
29
- config: {
30
- responseModalities: [Modality.AUDIO],
31
- // tools: callableTools,
32
- },
33
- })
34
-
35
- // Connect to the API
36
- const connected = await newClient.connect()
37
- } catch (error) {
38
- console.error(pc.red('\nError initializing project:'))
39
- console.error(pc.red(error))
40
- process.exit(1)
41
- }
42
- })
package/src/utils.ts DELETED
@@ -1,163 +0,0 @@
1
- import os from 'node:os'
2
- import JSONC from 'tiny-jsonc'
3
- import fs from 'node:fs'
4
- import path from 'node:path'
5
-
6
- import { execSync } from 'node:child_process'
7
-
8
- export async function getCurrentGitBranch(): Promise<string | undefined> {
9
- try {
10
- // First check if we're in a git repository
11
- try {
12
- execSync('git rev-parse --git-dir', { stdio: 'ignore' })
13
- } catch {
14
- return undefined
15
- }
16
-
17
- // Check if HEAD exists and has commits
18
- try {
19
- execSync('git rev-parse --verify HEAD', { stdio: 'ignore' })
20
- } catch {
21
- // No commits yet, check if we're on a branch
22
- try {
23
- const branch = execSync('git symbolic-ref --short HEAD', {
24
- encoding: 'utf-8',
25
- }).trim()
26
- return branch
27
- } catch {
28
- return undefined
29
- }
30
- }
31
-
32
- // Normal case: get current branch
33
- const branch = execSync('git rev-parse --abbrev-ref HEAD', {
34
- encoding: 'utf-8',
35
- }).trim()
36
- return branch === 'HEAD' ? undefined : branch
37
- } catch (e) {
38
- return undefined
39
- }
40
- }
41
-
42
- export function openUrlInBrowser(url: string) {
43
- let command: string
44
-
45
- switch (os.platform()) {
46
- case 'darwin':
47
- command = `open "${url}"`
48
- break
49
- case 'win32':
50
- command = `start "" "${url}"`
51
- break
52
- default:
53
- // linux, unix, etc.
54
- command = `xdg-open "${url}"`
55
- break
56
- }
57
-
58
- try {
59
- execSync(command, { stdio: 'ignore' })
60
- } catch (error) {
61
- console.error('Failed to open URL in browser:', error)
62
- }
63
- }
64
-
65
- export function safeParseJson<T = any>(str: string): T | undefined {
66
- try {
67
- return JSON.parse(str) as T
68
- } catch (e) {
69
- return undefined
70
- }
71
- }
72
-
73
- export function getGitRepoRoot(): string | undefined {
74
- try {
75
- const repoRoot = execSync('git rev-parse --show-toplevel', {
76
- encoding: 'utf-8',
77
- }).trim()
78
- return path.resolve(repoRoot)
79
- } catch {
80
- return undefined
81
- }
82
- }
83
-
84
- export function getGitRemoteUrl(): string | undefined {
85
- try {
86
- return execSync('git remote get-url origin', {
87
- encoding: 'utf-8',
88
- }).trim()
89
- } catch {
90
- return undefined
91
- }
92
- }
93
-
94
- export function getGitHubInfo():
95
- | { githubOwner: string; githubRepo: string; name: string }
96
- | undefined {
97
- const remoteUrl = getGitRemoteUrl()
98
- if (!remoteUrl) return undefined
99
-
100
- const match = remoteUrl.match(/github\.com[\/:]([^\/]+)\/([^\/\.]+)/)
101
- if (match) {
102
- return {
103
- githubOwner: match[1],
104
- githubRepo: match[2],
105
- name: match[2],
106
- }
107
- }
108
- return undefined
109
- }
110
-
111
- export function checkGitStatus(): {
112
- hasUncommittedChanges: boolean
113
- hasUnpushedCommits: boolean
114
- error?: string
115
- } {
116
- try {
117
- // Check for uncommitted changes using porcelain format for machine readable output
118
- const gitStatus = execSync('git status --porcelain', {
119
- encoding: 'utf-8',
120
- }).trim()
121
- const hasUncommittedChanges = gitStatus.length > 0
122
-
123
- // Check for unpushed commits
124
- let hasUnpushedCommits = false
125
- try {
126
- const currentBranch = execSync('git rev-parse --abbrev-ref HEAD', {
127
- encoding: 'utf-8',
128
- }).trim()
129
- if (currentBranch && currentBranch !== 'HEAD') {
130
- // Check if remote branch exists
131
- try {
132
- execSync(`git rev-parse --verify origin/${currentBranch}`, {
133
- stdio: 'ignore',
134
- })
135
- // Remote branch exists, check for unpushed commits
136
- const unpushedCommits = execSync(
137
- `git log origin/${currentBranch}..${currentBranch} --oneline`,
138
- { encoding: 'utf-8' },
139
- ).trim()
140
- hasUnpushedCommits = unpushedCommits.length > 0
141
- } catch {
142
- // Remote branch doesn't exist, so we have unpushed commits
143
- hasUnpushedCommits = true
144
- }
145
- }
146
- } catch (e) {
147
- // Could not determine branch or remote status
148
- return {
149
- hasUncommittedChanges,
150
- hasUnpushedCommits: false,
151
- error: 'Could not check remote branch status',
152
- }
153
- }
154
-
155
- return { hasUncommittedChanges, hasUnpushedCommits }
156
- } catch (e) {
157
- return {
158
- hasUncommittedChanges: false,
159
- hasUnpushedCommits: false,
160
- error: e.message,
161
- }
162
- }
163
- }