kimaki 0.4.65 → 0.4.67
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/bin.js +16 -1
- package/dist/cli-parsing.test.js +16 -0
- package/dist/cli.js +187 -9
- package/dist/commands/abort.js +1 -1
- package/dist/commands/agent.js +1 -1
- package/dist/commands/ask-question.js +10 -8
- package/dist/commands/compact.js +5 -5
- package/dist/commands/context-usage.js +4 -4
- package/dist/commands/file-upload.js +3 -3
- package/dist/commands/fork.js +4 -4
- package/dist/commands/login.js +14 -15
- package/dist/commands/merge-worktree.js +1 -1
- package/dist/commands/model.js +6 -3
- package/dist/commands/permissions.js +9 -8
- package/dist/commands/restart-opencode-server.js +1 -1
- package/dist/commands/resume.js +2 -2
- package/dist/commands/session-id.js +78 -0
- package/dist/commands/session.js +2 -4
- package/dist/commands/share.js +1 -1
- package/dist/commands/undo-redo.js +5 -5
- package/dist/commands/upgrade.js +4 -0
- package/dist/config.js +9 -0
- package/dist/discord-bot.js +17 -11
- package/dist/discord-utils.js +6 -13
- package/dist/heap-monitor.js +3 -0
- package/dist/interaction-handler.js +4 -0
- package/dist/markdown.js +3 -3
- package/dist/markdown.test.js +2 -2
- package/dist/message-formatting.js +2 -1
- package/dist/opencode-plugin.js +225 -34
- package/dist/opencode.js +48 -13
- package/dist/session-handler.js +121 -102
- package/dist/session-search.js +100 -0
- package/dist/session-search.test.js +40 -0
- package/dist/system-message.js +25 -5
- package/dist/tools.js +18 -26
- package/dist/voice-handler.js +1 -1
- package/dist/wait-session.js +1 -1
- package/package.json +6 -4
- package/skills/errore/SKILL.md +1159 -0
- package/skills/jitter/EDITOR.md +210 -0
- package/skills/jitter/SKILL.md +158 -0
- package/skills/jitter/dist/jitter-utils.js +620 -0
- package/skills/jitter/jitter-clipboard.json +1042 -0
- package/skills/jitter/node_modules/.bin/esbuild +21 -0
- package/skills/jitter/node_modules/.bin/tsc +21 -0
- package/skills/jitter/node_modules/.bin/tsserver +21 -0
- package/skills/jitter/node_modules/typescript/LICENSE.txt +55 -0
- package/skills/jitter/node_modules/typescript/README.md +50 -0
- package/skills/jitter/node_modules/typescript/SECURITY.md +41 -0
- package/skills/jitter/node_modules/typescript/ThirdPartyNoticeText.txt +193 -0
- package/skills/jitter/node_modules/typescript/bin/tsc +2 -0
- package/skills/jitter/node_modules/typescript/bin/tsserver +2 -0
- package/skills/jitter/node_modules/typescript/lib/_tsc.js +133792 -0
- package/skills/jitter/node_modules/typescript/lib/_tsserver.js +659 -0
- package/skills/jitter/node_modules/typescript/lib/_typingsInstaller.js +222 -0
- package/skills/jitter/node_modules/typescript/lib/cs/diagnosticMessages.generated.json +2122 -0
- package/skills/jitter/node_modules/typescript/lib/de/diagnosticMessages.generated.json +2122 -0
- package/skills/jitter/node_modules/typescript/lib/es/diagnosticMessages.generated.json +2122 -0
- package/skills/jitter/node_modules/typescript/lib/fr/diagnosticMessages.generated.json +2122 -0
- package/skills/jitter/node_modules/typescript/lib/it/diagnosticMessages.generated.json +2122 -0
- package/skills/jitter/node_modules/typescript/lib/ja/diagnosticMessages.generated.json +2122 -0
- package/skills/jitter/node_modules/typescript/lib/ko/diagnosticMessages.generated.json +2122 -0
- package/skills/jitter/node_modules/typescript/lib/lib.d.ts +22 -0
- package/skills/jitter/node_modules/typescript/lib/lib.decorators.d.ts +384 -0
- package/skills/jitter/node_modules/typescript/lib/lib.decorators.legacy.d.ts +22 -0
- package/skills/jitter/node_modules/typescript/lib/lib.dom.asynciterable.d.ts +41 -0
- package/skills/jitter/node_modules/typescript/lib/lib.dom.d.ts +39429 -0
- package/skills/jitter/node_modules/typescript/lib/lib.dom.iterable.d.ts +571 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2015.collection.d.ts +147 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2015.core.d.ts +597 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2015.d.ts +28 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2015.generator.d.ts +77 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2015.iterable.d.ts +605 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2015.promise.d.ts +81 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2015.proxy.d.ts +128 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2015.reflect.d.ts +144 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2015.symbol.d.ts +46 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts +326 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2016.array.include.d.ts +116 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2016.d.ts +21 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2016.full.d.ts +23 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2016.intl.d.ts +31 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2017.arraybuffer.d.ts +21 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2017.d.ts +26 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2017.date.d.ts +31 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2017.full.d.ts +23 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2017.intl.d.ts +44 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2017.object.d.ts +49 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts +135 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2017.string.d.ts +45 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2017.typedarrays.d.ts +53 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2018.asyncgenerator.d.ts +77 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2018.asynciterable.d.ts +53 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2018.d.ts +24 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2018.full.d.ts +24 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2018.intl.d.ts +83 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2018.promise.d.ts +30 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2018.regexp.d.ts +37 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2019.array.d.ts +79 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2019.d.ts +24 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2019.full.d.ts +24 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2019.intl.d.ts +23 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2019.object.d.ts +33 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2019.string.d.ts +37 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2019.symbol.d.ts +24 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2020.bigint.d.ts +765 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2020.d.ts +27 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2020.date.d.ts +42 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2020.full.d.ts +24 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2020.intl.d.ts +474 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2020.number.d.ts +28 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2020.promise.d.ts +47 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2020.sharedmemory.d.ts +99 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2020.string.d.ts +44 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2020.symbol.wellknown.d.ts +41 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2021.d.ts +23 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2021.full.d.ts +24 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2021.intl.d.ts +166 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2021.promise.d.ts +48 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2021.string.d.ts +33 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2021.weakref.d.ts +78 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2022.array.d.ts +121 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2022.d.ts +25 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2022.error.d.ts +75 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2022.full.d.ts +24 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2022.intl.d.ts +145 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2022.object.d.ts +26 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2022.regexp.d.ts +39 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2022.string.d.ts +25 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2023.array.d.ts +924 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2023.collection.d.ts +21 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2023.d.ts +22 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2023.full.d.ts +24 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2023.intl.d.ts +56 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2024.arraybuffer.d.ts +65 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2024.collection.d.ts +29 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2024.d.ts +26 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2024.full.d.ts +24 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2024.object.d.ts +29 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2024.promise.d.ts +35 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2024.regexp.d.ts +25 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2024.sharedmemory.d.ts +68 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es2024.string.d.ts +29 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es5.d.ts +4601 -0
- package/skills/jitter/node_modules/typescript/lib/lib.es6.d.ts +23 -0
- package/skills/jitter/node_modules/typescript/lib/lib.esnext.array.d.ts +35 -0
- package/skills/jitter/node_modules/typescript/lib/lib.esnext.collection.d.ts +96 -0
- package/skills/jitter/node_modules/typescript/lib/lib.esnext.d.ts +29 -0
- package/skills/jitter/node_modules/typescript/lib/lib.esnext.decorators.d.ts +28 -0
- package/skills/jitter/node_modules/typescript/lib/lib.esnext.disposable.d.ts +193 -0
- package/skills/jitter/node_modules/typescript/lib/lib.esnext.error.d.ts +24 -0
- package/skills/jitter/node_modules/typescript/lib/lib.esnext.float16.d.ts +443 -0
- package/skills/jitter/node_modules/typescript/lib/lib.esnext.full.d.ts +24 -0
- package/skills/jitter/node_modules/typescript/lib/lib.esnext.intl.d.ts +21 -0
- package/skills/jitter/node_modules/typescript/lib/lib.esnext.iterator.d.ts +148 -0
- package/skills/jitter/node_modules/typescript/lib/lib.esnext.promise.d.ts +34 -0
- package/skills/jitter/node_modules/typescript/lib/lib.esnext.sharedmemory.d.ts +25 -0
- package/skills/jitter/node_modules/typescript/lib/lib.scripthost.d.ts +322 -0
- package/skills/jitter/node_modules/typescript/lib/lib.webworker.asynciterable.d.ts +41 -0
- package/skills/jitter/node_modules/typescript/lib/lib.webworker.d.ts +13150 -0
- package/skills/jitter/node_modules/typescript/lib/lib.webworker.importscripts.d.ts +23 -0
- package/skills/jitter/node_modules/typescript/lib/lib.webworker.iterable.d.ts +340 -0
- package/skills/jitter/node_modules/typescript/lib/pl/diagnosticMessages.generated.json +2122 -0
- package/skills/jitter/node_modules/typescript/lib/pt-br/diagnosticMessages.generated.json +2122 -0
- package/skills/jitter/node_modules/typescript/lib/ru/diagnosticMessages.generated.json +2122 -0
- package/skills/jitter/node_modules/typescript/lib/tr/diagnosticMessages.generated.json +2122 -0
- package/skills/jitter/node_modules/typescript/lib/tsc.js +8 -0
- package/skills/jitter/node_modules/typescript/lib/tsserver.js +8 -0
- package/skills/jitter/node_modules/typescript/lib/tsserverlibrary.d.ts +17 -0
- package/skills/jitter/node_modules/typescript/lib/tsserverlibrary.js +21 -0
- package/skills/jitter/node_modules/typescript/lib/typesMap.json +497 -0
- package/skills/jitter/node_modules/typescript/lib/typescript.d.ts +11438 -0
- package/skills/jitter/node_modules/typescript/lib/typescript.js +200253 -0
- package/skills/jitter/node_modules/typescript/lib/typingsInstaller.js +8 -0
- package/skills/jitter/node_modules/typescript/lib/watchGuard.js +53 -0
- package/skills/jitter/node_modules/typescript/lib/zh-cn/diagnosticMessages.generated.json +2122 -0
- package/skills/jitter/node_modules/typescript/lib/zh-tw/diagnosticMessages.generated.json +2122 -0
- package/skills/jitter/node_modules/typescript/node_modules/.bin/tsc +21 -0
- package/skills/jitter/node_modules/typescript/node_modules/.bin/tsserver +21 -0
- package/skills/jitter/node_modules/typescript/package.json +120 -0
- package/skills/jitter/package.json +14 -0
- package/skills/jitter/tsconfig.json +15 -0
- package/skills/jitter/utils/actions.ts +208 -0
- package/skills/jitter/utils/export.ts +109 -0
- package/skills/jitter/utils/index.ts +140 -0
- package/skills/jitter/utils/snapshot.ts +140 -0
- package/skills/jitter/utils/traverse.ts +228 -0
- package/skills/jitter/utils/types.ts +279 -0
- package/skills/jitter/utils/wait.ts +131 -0
- package/skills/playwriter/SKILL.md +30 -0
- package/skills/tuistory/SKILL.md +250 -0
- package/src/bin.ts +26 -4
- package/src/cli-parsing.test.ts +22 -0
- package/src/cli.ts +264 -23
- package/src/commands/abort.ts +1 -1
- package/src/commands/agent.ts +1 -1
- package/src/commands/ask-question.ts +10 -8
- package/src/commands/compact.ts +5 -5
- package/src/commands/context-usage.ts +4 -4
- package/src/commands/file-upload.ts +3 -3
- package/src/commands/fork.ts +4 -4
- package/src/commands/login.ts +14 -15
- package/src/commands/merge-worktree.ts +1 -1
- package/src/commands/model.ts +6 -3
- package/src/commands/permissions.ts +10 -9
- package/src/commands/restart-opencode-server.ts +1 -1
- package/src/commands/resume.ts +2 -2
- package/src/commands/session-id.ts +95 -0
- package/src/commands/session.ts +2 -4
- package/src/commands/share.ts +1 -1
- package/src/commands/undo-redo.ts +5 -5
- package/src/commands/upgrade.ts +4 -0
- package/src/config.ts +12 -0
- package/src/discord-bot.ts +17 -11
- package/src/discord-utils.ts +7 -15
- package/src/heap-monitor.ts +4 -0
- package/src/interaction-handler.ts +5 -0
- package/src/markdown.test.ts +2 -2
- package/src/markdown.ts +4 -4
- package/src/message-formatting.test.ts +1 -1
- package/src/message-formatting.ts +4 -3
- package/src/opencode-plugin.ts +260 -33
- package/src/opencode.ts +49 -18
- package/src/session-handler.ts +125 -89
- package/src/session-search.test.ts +50 -0
- package/src/session-search.ts +146 -0
- package/src/system-message.ts +25 -5
- package/src/tools.ts +18 -27
- package/src/voice-handler.ts +1 -1
- package/src/wait-session.ts +1 -1
- package/LICENSE +0 -21
package/dist/bin.js
CHANGED
|
@@ -8,7 +8,18 @@
|
|
|
8
8
|
// since they are short-lived and don't need crash recovery.
|
|
9
9
|
//
|
|
10
10
|
// When __KIMAKI_CHILD is set, we're the child process -- just run cli.js directly.
|
|
11
|
+
//
|
|
12
|
+
// V8 heap snapshot flags:
|
|
13
|
+
// Injects --heapsnapshot-near-heap-limit=3 and --diagnostic-dir so V8 writes
|
|
14
|
+
// heap snapshots internally as it approaches the heap limit. This catches OOM
|
|
15
|
+
// situations where SIGKILL (exit 137) would kill the process before our
|
|
16
|
+
// heap-monitor.ts polling can react. The polling monitor is kept as an early
|
|
17
|
+
// warning system at 85% usage; the V8 flag is the last-resort safety net.
|
|
11
18
|
import { spawn } from 'node:child_process';
|
|
19
|
+
import fs from 'node:fs';
|
|
20
|
+
import os from 'node:os';
|
|
21
|
+
import path from 'node:path';
|
|
22
|
+
const HEAP_SNAPSHOT_DIR = path.join(os.homedir(), '.kimaki', 'heap-snapshots');
|
|
12
23
|
// First arg after node + script is either a subcommand or a flag.
|
|
13
24
|
// If it doesn't start with '-', it's a subcommand (e.g. "send", "tunnel", "project").
|
|
14
25
|
const firstArg = process.argv[2];
|
|
@@ -27,7 +38,11 @@ else {
|
|
|
27
38
|
// Track when we forwarded a termination signal so we don't restart after graceful shutdown
|
|
28
39
|
let shutdownRequested = false;
|
|
29
40
|
function start() {
|
|
30
|
-
|
|
41
|
+
if (!fs.existsSync(HEAP_SNAPSHOT_DIR)) {
|
|
42
|
+
fs.mkdirSync(HEAP_SNAPSHOT_DIR, { recursive: true });
|
|
43
|
+
}
|
|
44
|
+
const heapArgs = [`--heapsnapshot-near-heap-limit=3`, `--diagnostic-dir=${HEAP_SNAPSHOT_DIR}`];
|
|
45
|
+
child = spawn(process.argv[0], [...heapArgs, ...process.execArgv, ...process.argv.slice(1)], {
|
|
31
46
|
stdio: 'inherit',
|
|
32
47
|
env: { ...process.env, __KIMAKI_CHILD: '1' },
|
|
33
48
|
});
|
package/dist/cli-parsing.test.js
CHANGED
|
@@ -9,6 +9,10 @@ function createCliForIdParsing() {
|
|
|
9
9
|
.option('--thread <threadId>', 'Thread ID')
|
|
10
10
|
.option('--session <sessionId>', 'Session ID');
|
|
11
11
|
cli.command('session archive <threadId>', 'Archive a thread');
|
|
12
|
+
cli
|
|
13
|
+
.command('session search <query>', 'Search sessions')
|
|
14
|
+
.option('--channel <channelId>', 'Discord channel ID')
|
|
15
|
+
.option('--project <path>', 'Project path');
|
|
12
16
|
cli
|
|
13
17
|
.command('add-project', 'Add a project')
|
|
14
18
|
.option('-g, --guild <guildId>', 'Discord guild/server ID');
|
|
@@ -50,4 +54,16 @@ describe('goke CLI ID parsing', () => {
|
|
|
50
54
|
expect(result.args[0]).toBe(threadId);
|
|
51
55
|
expect(typeof result.args[0]).toBe('string');
|
|
52
56
|
});
|
|
57
|
+
test('keeps session search regex and channel ID as strings', () => {
|
|
58
|
+
const cli = createCliForIdParsing();
|
|
59
|
+
const channelId = '0012345678901234567';
|
|
60
|
+
const query = '/error\\s+42/i';
|
|
61
|
+
const result = cli.parse(['node', 'kimaki', 'session', 'search', query, '--channel', channelId], {
|
|
62
|
+
run: false,
|
|
63
|
+
});
|
|
64
|
+
expect(result.args[0]).toBe(query);
|
|
65
|
+
expect(typeof result.args[0]).toBe('string');
|
|
66
|
+
expect(result.options.channel).toBe(channelId);
|
|
67
|
+
expect(typeof result.options.channel).toBe('string');
|
|
68
|
+
});
|
|
53
69
|
});
|
package/dist/cli.js
CHANGED
|
@@ -8,6 +8,7 @@ import { deduplicateByKey, generateBotInstallUrl, abbreviatePath } from './utils
|
|
|
8
8
|
import { getChannelsWithDescriptions, createDiscordClient, initDatabase, getChannelDirectory, startDiscordBot, initializeOpencodeForDirectory, ensureKimakiCategory, createProjectChannels, } from './discord-bot.js';
|
|
9
9
|
import { getBotToken, setBotToken, setChannelDirectory, findChannelsByDirectory, findChannelByAppId, getThreadSession, getThreadIdBySessionId, getPrisma, } from './database.js';
|
|
10
10
|
import { ShareMarkdown } from './markdown.js';
|
|
11
|
+
import { parseSessionSearchPattern, findFirstSessionSearchHit, buildSessionSearchSnippet, getPartSearchTexts, } from './session-search.js';
|
|
11
12
|
import { formatWorktreeName } from './commands/worktree.js';
|
|
12
13
|
import { WORKTREE_PREFIX } from './commands/merge-worktree.js';
|
|
13
14
|
import yaml from 'js-yaml';
|
|
@@ -19,7 +20,7 @@ import { createLogger, formatErrorWithStack, LogPrefix } from './logger.js';
|
|
|
19
20
|
import { archiveThread, uploadFilesToDiscord, stripMentions } from './discord-utils.js';
|
|
20
21
|
import { spawn, spawnSync, execSync } from 'node:child_process';
|
|
21
22
|
import http from 'node:http';
|
|
22
|
-
import { setDataDir, getDataDir, getLockPort, setDefaultVerbosity, setDefaultMentionMode, setCritiqueEnabled, getProjectsDir, } from './config.js';
|
|
23
|
+
import { setDataDir, getDataDir, getLockPort, setDefaultVerbosity, setDefaultMentionMode, setCritiqueEnabled, setVerboseOpencodeServer, getProjectsDir, } from './config.js';
|
|
23
24
|
import { sanitizeAgentName } from './commands/agent.js';
|
|
24
25
|
import { showFileUploadButton } from './commands/file-upload.js';
|
|
25
26
|
import { execAsync } from './worktree-utils.js';
|
|
@@ -611,6 +612,11 @@ async function registerCommands({ token, appId, userCommands = [], agents = [],
|
|
|
611
612
|
.setDescription('Show token usage and context window percentage for this session')
|
|
612
613
|
.setDMPermission(false)
|
|
613
614
|
.toJSON(),
|
|
615
|
+
new SlashCommandBuilder()
|
|
616
|
+
.setName('session-id')
|
|
617
|
+
.setDescription('Show current session ID and opencode attach command for this thread')
|
|
618
|
+
.setDMPermission(false)
|
|
619
|
+
.toJSON(),
|
|
614
620
|
new SlashCommandBuilder()
|
|
615
621
|
.setName('upgrade-and-restart')
|
|
616
622
|
.setDescription('Upgrade kimaki to the latest version and restart the bot')
|
|
@@ -738,14 +744,14 @@ async function backgroundInit({ currentDir, token, appId, }) {
|
|
|
738
744
|
const getClient = opencodeResult;
|
|
739
745
|
const [userCommands, agents] = await Promise.all([
|
|
740
746
|
getClient()
|
|
741
|
-
.command.list({
|
|
747
|
+
.command.list({ directory: currentDir })
|
|
742
748
|
.then((r) => r.data || [])
|
|
743
749
|
.catch((error) => {
|
|
744
750
|
cliLogger.warn('Failed to load user commands during background init:', error instanceof Error ? error.message : String(error));
|
|
745
751
|
return [];
|
|
746
752
|
}),
|
|
747
753
|
getClient()
|
|
748
|
-
.app.agents({
|
|
754
|
+
.app.agents({ directory: currentDir })
|
|
749
755
|
.then((r) => r.data || [])
|
|
750
756
|
.catch((error) => {
|
|
751
757
|
cliLogger.warn('Failed to load agents during background init:', error instanceof Error ? error.message : String(error));
|
|
@@ -978,7 +984,7 @@ async function run({ restart, addChannels, useWorktrees, enableVoiceChannels })
|
|
|
978
984
|
// Fetch projects, commands, and agents in parallel
|
|
979
985
|
const [projects, allUserCommands, allAgents] = await Promise.all([
|
|
980
986
|
getClient()
|
|
981
|
-
.project.list(
|
|
987
|
+
.project.list()
|
|
982
988
|
.then((r) => r.data || [])
|
|
983
989
|
.catch((error) => {
|
|
984
990
|
cliLogger.log('Failed to fetch projects');
|
|
@@ -987,14 +993,14 @@ async function run({ restart, addChannels, useWorktrees, enableVoiceChannels })
|
|
|
987
993
|
process.exit(EXIT_NO_RESTART);
|
|
988
994
|
}),
|
|
989
995
|
getClient()
|
|
990
|
-
.command.list({
|
|
996
|
+
.command.list({ directory: currentDir })
|
|
991
997
|
.then((r) => r.data || [])
|
|
992
998
|
.catch((error) => {
|
|
993
999
|
cliLogger.warn('Failed to load user commands during setup:', error instanceof Error ? error.message : String(error));
|
|
994
1000
|
return [];
|
|
995
1001
|
}),
|
|
996
1002
|
getClient()
|
|
997
|
-
.app.agents({
|
|
1003
|
+
.app.agents({ directory: currentDir })
|
|
998
1004
|
.then((r) => r.data || [])
|
|
999
1005
|
.catch((error) => {
|
|
1000
1006
|
cliLogger.warn('Failed to load agents during setup:', error instanceof Error ? error.message : String(error));
|
|
@@ -1116,6 +1122,7 @@ cli
|
|
|
1116
1122
|
.option('--mention-mode', 'Bot only responds when @mentioned (default for all channels)')
|
|
1117
1123
|
.option('--no-critique', 'Disable automatic diff upload to critique.work in system prompts')
|
|
1118
1124
|
.option('--auto-restart', 'Automatically restart the bot on crash or OOM kill')
|
|
1125
|
+
.option('--verbose-opencode-server', 'Forward OpenCode server stdout/stderr to kimaki.log')
|
|
1119
1126
|
.action(async (options) => {
|
|
1120
1127
|
try {
|
|
1121
1128
|
// Set data directory early, before any database access
|
|
@@ -1140,6 +1147,10 @@ cli
|
|
|
1140
1147
|
setCritiqueEnabled(false);
|
|
1141
1148
|
cliLogger.log('Critique disabled: diffs will not be auto-uploaded to critique.work');
|
|
1142
1149
|
}
|
|
1150
|
+
if (options.verboseOpencodeServer) {
|
|
1151
|
+
setVerboseOpencodeServer(true);
|
|
1152
|
+
cliLogger.log('Verbose OpenCode server: stdout/stderr will be forwarded to kimaki.log');
|
|
1153
|
+
}
|
|
1143
1154
|
if (options.installUrl) {
|
|
1144
1155
|
await initDatabase();
|
|
1145
1156
|
const existingBot = await getBotToken();
|
|
@@ -1916,7 +1927,7 @@ cli
|
|
|
1916
1927
|
cli
|
|
1917
1928
|
.command('tunnel', 'Expose a local port via tunnel')
|
|
1918
1929
|
.option('-p, --port <port>', 'Local port to expose (required)')
|
|
1919
|
-
.option('-t, --tunnel-id [id]', '
|
|
1930
|
+
.option('-t, --tunnel-id [id]', 'Custom tunnel ID (only for services safe to expose publicly; prefer random default)')
|
|
1920
1931
|
.option('-h, --host [host]', 'Local host (default: localhost)')
|
|
1921
1932
|
.option('-s, --server [url]', 'Tunnel server URL')
|
|
1922
1933
|
.action(async (options) => {
|
|
@@ -2025,7 +2036,7 @@ cli
|
|
|
2025
2036
|
// project.list() returns all known projects globally from any OpenCode server,
|
|
2026
2037
|
// but session.list/get are scoped to the server's own project. So we try each.
|
|
2027
2038
|
cliLogger.log('Session not in current project, searching all projects...');
|
|
2028
|
-
const projectsResponse = await getClient().project.list(
|
|
2039
|
+
const projectsResponse = await getClient().project.list();
|
|
2029
2040
|
const projects = projectsResponse.data || [];
|
|
2030
2041
|
const otherProjects = projects
|
|
2031
2042
|
.filter((p) => path.resolve(p.worktree) !== projectDirectory)
|
|
@@ -2062,6 +2073,157 @@ cli
|
|
|
2062
2073
|
process.exit(EXIT_NO_RESTART);
|
|
2063
2074
|
}
|
|
2064
2075
|
});
|
|
2076
|
+
cli
|
|
2077
|
+
.command('session search <query>', 'Search past sessions for text or /regex/flags in the selected project')
|
|
2078
|
+
.option('--project <path>', 'Project directory (defaults to cwd)')
|
|
2079
|
+
.option('--channel <channelId>', 'Resolve project from a Discord channel ID')
|
|
2080
|
+
.option('--limit <n>', 'Maximum matched sessions to return (default: 20)')
|
|
2081
|
+
.option('--json', 'Output as JSON')
|
|
2082
|
+
.action(async (query, options) => {
|
|
2083
|
+
try {
|
|
2084
|
+
await initDatabase();
|
|
2085
|
+
if (options.project && options.channel) {
|
|
2086
|
+
cliLogger.error('Use either --project or --channel, not both');
|
|
2087
|
+
process.exit(EXIT_NO_RESTART);
|
|
2088
|
+
}
|
|
2089
|
+
const limit = (() => {
|
|
2090
|
+
const rawLimit = typeof options.limit === 'string' ? options.limit : '20';
|
|
2091
|
+
const parsed = Number.parseInt(rawLimit, 10);
|
|
2092
|
+
if (Number.isNaN(parsed) || parsed < 1) {
|
|
2093
|
+
return new Error(`Invalid --limit value: ${rawLimit}`);
|
|
2094
|
+
}
|
|
2095
|
+
return parsed;
|
|
2096
|
+
})();
|
|
2097
|
+
if (limit instanceof Error) {
|
|
2098
|
+
cliLogger.error(limit.message);
|
|
2099
|
+
process.exit(EXIT_NO_RESTART);
|
|
2100
|
+
}
|
|
2101
|
+
const projectDirectoryResult = await (async () => {
|
|
2102
|
+
if (options.channel) {
|
|
2103
|
+
const channelConfig = await getChannelDirectory(options.channel);
|
|
2104
|
+
if (!channelConfig) {
|
|
2105
|
+
return new Error(`No project mapping found for channel: ${options.channel}`);
|
|
2106
|
+
}
|
|
2107
|
+
return path.resolve(channelConfig.directory);
|
|
2108
|
+
}
|
|
2109
|
+
return path.resolve(options.project || '.');
|
|
2110
|
+
})();
|
|
2111
|
+
if (projectDirectoryResult instanceof Error) {
|
|
2112
|
+
cliLogger.error(projectDirectoryResult.message);
|
|
2113
|
+
process.exit(EXIT_NO_RESTART);
|
|
2114
|
+
}
|
|
2115
|
+
const projectDirectory = projectDirectoryResult;
|
|
2116
|
+
if (!fs.existsSync(projectDirectory)) {
|
|
2117
|
+
cliLogger.error(`Directory does not exist: ${projectDirectory}`);
|
|
2118
|
+
process.exit(EXIT_NO_RESTART);
|
|
2119
|
+
}
|
|
2120
|
+
const searchPattern = parseSessionSearchPattern(query);
|
|
2121
|
+
if (searchPattern instanceof Error) {
|
|
2122
|
+
cliLogger.error(searchPattern.message);
|
|
2123
|
+
process.exit(EXIT_NO_RESTART);
|
|
2124
|
+
}
|
|
2125
|
+
cliLogger.log('Connecting to OpenCode server...');
|
|
2126
|
+
const getClient = await initializeOpencodeForDirectory(projectDirectory);
|
|
2127
|
+
if (getClient instanceof Error) {
|
|
2128
|
+
cliLogger.error('Failed to connect to OpenCode:', getClient.message);
|
|
2129
|
+
process.exit(EXIT_NO_RESTART);
|
|
2130
|
+
}
|
|
2131
|
+
const sessionsResponse = await getClient().session.list();
|
|
2132
|
+
const sessions = sessionsResponse.data || [];
|
|
2133
|
+
if (sessions.length === 0) {
|
|
2134
|
+
cliLogger.log('No sessions found');
|
|
2135
|
+
process.exit(0);
|
|
2136
|
+
}
|
|
2137
|
+
const prisma = await getPrisma();
|
|
2138
|
+
const threadSessions = await prisma.thread_sessions.findMany({
|
|
2139
|
+
select: { thread_id: true, session_id: true },
|
|
2140
|
+
});
|
|
2141
|
+
const sessionToThread = new Map(threadSessions
|
|
2142
|
+
.filter((row) => row.session_id !== '')
|
|
2143
|
+
.map((row) => [row.session_id, row.thread_id]));
|
|
2144
|
+
const sortedSessions = [...sessions].sort((a, b) => {
|
|
2145
|
+
return b.time.updated - a.time.updated;
|
|
2146
|
+
});
|
|
2147
|
+
const matchedSessions = [];
|
|
2148
|
+
let scannedSessions = 0;
|
|
2149
|
+
for (const session of sortedSessions) {
|
|
2150
|
+
scannedSessions++;
|
|
2151
|
+
const messagesResponse = await getClient().session.messages({
|
|
2152
|
+
sessionID: session.id,
|
|
2153
|
+
});
|
|
2154
|
+
const messages = messagesResponse.data || [];
|
|
2155
|
+
const snippets = messages
|
|
2156
|
+
.flatMap((message) => {
|
|
2157
|
+
const rolePrefix = message.info.role === 'assistant'
|
|
2158
|
+
? 'assistant'
|
|
2159
|
+
: message.info.role === 'user'
|
|
2160
|
+
? 'user'
|
|
2161
|
+
: 'message';
|
|
2162
|
+
return message.parts.flatMap((part) => {
|
|
2163
|
+
return getPartSearchTexts(part).flatMap((text) => {
|
|
2164
|
+
const hit = findFirstSessionSearchHit({
|
|
2165
|
+
text,
|
|
2166
|
+
searchPattern,
|
|
2167
|
+
});
|
|
2168
|
+
if (!hit) {
|
|
2169
|
+
return [];
|
|
2170
|
+
}
|
|
2171
|
+
const snippet = buildSessionSearchSnippet({ text, hit });
|
|
2172
|
+
if (!snippet) {
|
|
2173
|
+
return [];
|
|
2174
|
+
}
|
|
2175
|
+
return [`${rolePrefix}: ${snippet}`];
|
|
2176
|
+
});
|
|
2177
|
+
});
|
|
2178
|
+
})
|
|
2179
|
+
.slice(0, 3);
|
|
2180
|
+
if (snippets.length === 0) {
|
|
2181
|
+
continue;
|
|
2182
|
+
}
|
|
2183
|
+
const threadId = sessionToThread.get(session.id);
|
|
2184
|
+
matchedSessions.push({
|
|
2185
|
+
id: session.id,
|
|
2186
|
+
title: session.title || 'Untitled Session',
|
|
2187
|
+
directory: session.directory,
|
|
2188
|
+
updated: new Date(session.time.updated).toISOString(),
|
|
2189
|
+
source: threadId ? 'kimaki' : 'opencode',
|
|
2190
|
+
threadId: threadId || null,
|
|
2191
|
+
snippets,
|
|
2192
|
+
});
|
|
2193
|
+
if (matchedSessions.length >= limit) {
|
|
2194
|
+
break;
|
|
2195
|
+
}
|
|
2196
|
+
}
|
|
2197
|
+
if (options.json) {
|
|
2198
|
+
console.log(JSON.stringify({
|
|
2199
|
+
query: searchPattern.raw,
|
|
2200
|
+
mode: searchPattern.mode,
|
|
2201
|
+
projectDirectory,
|
|
2202
|
+
scannedSessions,
|
|
2203
|
+
matches: matchedSessions,
|
|
2204
|
+
}, null, 2));
|
|
2205
|
+
process.exit(0);
|
|
2206
|
+
}
|
|
2207
|
+
if (matchedSessions.length === 0) {
|
|
2208
|
+
cliLogger.log(`No matches found for ${searchPattern.raw} in ${projectDirectory} (${scannedSessions} sessions scanned)`);
|
|
2209
|
+
process.exit(0);
|
|
2210
|
+
}
|
|
2211
|
+
cliLogger.log(`Found ${matchedSessions.length} matching session(s) for ${searchPattern.raw} in ${projectDirectory}`);
|
|
2212
|
+
for (const match of matchedSessions) {
|
|
2213
|
+
const threadInfo = match.threadId ? ` | thread: ${match.threadId}` : '';
|
|
2214
|
+
console.log(`${match.id} | ${match.title} | ${match.updated} | ${match.source}${threadInfo}`);
|
|
2215
|
+
console.log(` Directory: ${match.directory}`);
|
|
2216
|
+
match.snippets.forEach((snippet) => {
|
|
2217
|
+
console.log(` - ${snippet}`);
|
|
2218
|
+
});
|
|
2219
|
+
}
|
|
2220
|
+
process.exit(0);
|
|
2221
|
+
}
|
|
2222
|
+
catch (error) {
|
|
2223
|
+
cliLogger.error('Error:', error instanceof Error ? error.message : String(error));
|
|
2224
|
+
process.exit(EXIT_NO_RESTART);
|
|
2225
|
+
}
|
|
2226
|
+
});
|
|
2065
2227
|
cli
|
|
2066
2228
|
.command('session archive <threadId>', 'Archive a Discord thread and stop its mapped OpenCode session')
|
|
2067
2229
|
.action(async (threadId) => {
|
|
@@ -2115,7 +2277,10 @@ cli
|
|
|
2115
2277
|
process.exit(EXIT_NO_RESTART);
|
|
2116
2278
|
}
|
|
2117
2279
|
});
|
|
2118
|
-
cli
|
|
2280
|
+
cli
|
|
2281
|
+
.command('upgrade', 'Upgrade kimaki to the latest version and restart the running bot')
|
|
2282
|
+
.option('--skip-restart', 'Only upgrade, do not restart the running bot')
|
|
2283
|
+
.action(async (options) => {
|
|
2119
2284
|
try {
|
|
2120
2285
|
const current = getCurrentVersion();
|
|
2121
2286
|
cliLogger.log(`Current version: v${current}`);
|
|
@@ -2125,6 +2290,19 @@ cli.command('upgrade', 'Upgrade kimaki to the latest version').action(async () =
|
|
|
2125
2290
|
process.exit(0);
|
|
2126
2291
|
}
|
|
2127
2292
|
cliLogger.log(`Upgraded to v${newVersion}`);
|
|
2293
|
+
if (options.skipRestart) {
|
|
2294
|
+
process.exit(0);
|
|
2295
|
+
}
|
|
2296
|
+
// Spawn a new kimaki process without args (starts the bot with default command).
|
|
2297
|
+
// The new process kills the old one via the single-instance lock.
|
|
2298
|
+
// No args passed to avoid recursively running `upgrade` again.
|
|
2299
|
+
const child = spawn('kimaki', [], {
|
|
2300
|
+
shell: true,
|
|
2301
|
+
stdio: 'ignore',
|
|
2302
|
+
detached: true,
|
|
2303
|
+
});
|
|
2304
|
+
child.unref();
|
|
2305
|
+
cliLogger.log('Restarting bot with new version...');
|
|
2128
2306
|
process.exit(0);
|
|
2129
2307
|
}
|
|
2130
2308
|
catch (error) {
|
package/dist/commands/abort.js
CHANGED
|
@@ -63,7 +63,7 @@ export async function handleAbortCommand({ command }) {
|
|
|
63
63
|
try {
|
|
64
64
|
logger.log(`[ABORT-API] reason=user-requested sessionId=${sessionId} channelId=${channel.id} - sending API abort from /abort command`);
|
|
65
65
|
await getClient().session.abort({
|
|
66
|
-
|
|
66
|
+
sessionID: sessionId,
|
|
67
67
|
});
|
|
68
68
|
await command.reply({
|
|
69
69
|
content: `🛑 Request **aborted**`,
|
package/dist/commands/agent.js
CHANGED
|
@@ -126,7 +126,7 @@ export async function handleAgentCommand({ interaction, appId, }) {
|
|
|
126
126
|
return;
|
|
127
127
|
}
|
|
128
128
|
const agentsResponse = await getClient().app.agents({
|
|
129
|
-
|
|
129
|
+
directory: context.dir,
|
|
130
130
|
});
|
|
131
131
|
if (!agentsResponse.data || agentsResponse.data.length === 0) {
|
|
132
132
|
await interaction.editReply({ content: 'No agents available' });
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { StringSelectMenuBuilder, StringSelectMenuInteraction, ActionRowBuilder, MessageFlags, } from 'discord.js';
|
|
5
5
|
import crypto from 'node:crypto';
|
|
6
6
|
import { sendThreadMessage, NOTIFY_MESSAGE_FLAGS } from '../discord-utils.js';
|
|
7
|
-
import {
|
|
7
|
+
import { getOpencodeClient } from '../opencode.js';
|
|
8
8
|
import { createLogger, LogPrefix } from '../logger.js';
|
|
9
9
|
const logger = createLogger(LogPrefix.ASK_QUESTION);
|
|
10
10
|
// Store pending question contexts by hash
|
|
@@ -56,7 +56,7 @@ export async function showAskUserQuestionDropdowns({ thread, sessionId, director
|
|
|
56
56
|
}
|
|
57
57
|
const actionRow = new ActionRowBuilder().addComponents(selectMenu);
|
|
58
58
|
await thread.send({
|
|
59
|
-
content: `**${q.header}**\n${q.question}`,
|
|
59
|
+
content: `**${(q.header || '').slice(0, 200)}**\n${q.question.slice(0, 1700)}`,
|
|
60
60
|
components: [actionRow],
|
|
61
61
|
flags: NOTIFY_MESSAGE_FLAGS,
|
|
62
62
|
});
|
|
@@ -129,16 +129,17 @@ export async function handleAskQuestionSelectMenu(interaction) {
|
|
|
129
129
|
*/
|
|
130
130
|
async function submitQuestionAnswers(context) {
|
|
131
131
|
try {
|
|
132
|
-
const
|
|
133
|
-
if (!
|
|
132
|
+
const client = getOpencodeClient(context.directory);
|
|
133
|
+
if (!client) {
|
|
134
134
|
throw new Error('OpenCode server not found for directory');
|
|
135
135
|
}
|
|
136
136
|
// Build answers array: each element is an array of selected labels for that question
|
|
137
137
|
const answers = context.questions.map((_, i) => {
|
|
138
138
|
return context.answers[i] || [];
|
|
139
139
|
});
|
|
140
|
-
await
|
|
140
|
+
await client.question.reply({
|
|
141
141
|
requestID: context.requestId,
|
|
142
|
+
directory: context.directory,
|
|
142
143
|
answers,
|
|
143
144
|
});
|
|
144
145
|
logger.log(`Submitted answers for question ${context.requestId} in session ${context.sessionId}`);
|
|
@@ -195,8 +196,8 @@ export async function cancelPendingQuestion(threadId, userMessage) {
|
|
|
195
196
|
return false;
|
|
196
197
|
}
|
|
197
198
|
try {
|
|
198
|
-
const
|
|
199
|
-
if (!
|
|
199
|
+
const client = getOpencodeClient(context.directory);
|
|
200
|
+
if (!client) {
|
|
200
201
|
throw new Error('OpenCode server not found for directory');
|
|
201
202
|
}
|
|
202
203
|
// Use user's message as answer if provided, otherwise mark as "Other"
|
|
@@ -204,8 +205,9 @@ export async function cancelPendingQuestion(threadId, userMessage) {
|
|
|
204
205
|
const answers = context.questions.map((_, i) => {
|
|
205
206
|
return context.answers[i] || [customAnswer];
|
|
206
207
|
});
|
|
207
|
-
await
|
|
208
|
+
await client.question.reply({
|
|
208
209
|
requestID: context.requestId,
|
|
210
|
+
directory: context.directory,
|
|
209
211
|
answers,
|
|
210
212
|
});
|
|
211
213
|
logger.log(`Answered question ${context.requestId} with user message`);
|
package/dist/commands/compact.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// /compact command - Trigger context compaction (summarization) for the current session.
|
|
2
2
|
import { ChannelType, MessageFlags } from 'discord.js';
|
|
3
3
|
import { getThreadSession } from '../database.js';
|
|
4
|
-
import { initializeOpencodeForDirectory,
|
|
4
|
+
import { initializeOpencodeForDirectory, getOpencodeClient } from '../opencode.js';
|
|
5
5
|
import { resolveWorkingDirectory, SILENT_MESSAGE_FLAGS } from '../discord-utils.js';
|
|
6
6
|
import { createLogger, LogPrefix } from '../logger.js';
|
|
7
7
|
const logger = createLogger(LogPrefix.COMPACT);
|
|
@@ -54,8 +54,8 @@ export async function handleCompactCommand({ command }) {
|
|
|
54
54
|
});
|
|
55
55
|
return;
|
|
56
56
|
}
|
|
57
|
-
const
|
|
58
|
-
if (!
|
|
57
|
+
const client = getOpencodeClient(projectDirectory);
|
|
58
|
+
if (!client) {
|
|
59
59
|
await command.reply({
|
|
60
60
|
content: 'Failed to get OpenCode client',
|
|
61
61
|
flags: MessageFlags.Ephemeral | SILENT_MESSAGE_FLAGS,
|
|
@@ -66,7 +66,7 @@ export async function handleCompactCommand({ command }) {
|
|
|
66
66
|
await command.deferReply({ flags: SILENT_MESSAGE_FLAGS });
|
|
67
67
|
try {
|
|
68
68
|
// Get session messages to find the model from the last user message
|
|
69
|
-
const messagesResult = await
|
|
69
|
+
const messagesResult = await client.session.messages({
|
|
70
70
|
sessionID: sessionId,
|
|
71
71
|
directory: workingDirectory,
|
|
72
72
|
});
|
|
@@ -88,7 +88,7 @@ export async function handleCompactCommand({ command }) {
|
|
|
88
88
|
return;
|
|
89
89
|
}
|
|
90
90
|
const { providerID, modelID } = lastUserMessage.info.model;
|
|
91
|
-
const result = await
|
|
91
|
+
const result = await client.session.summarize({
|
|
92
92
|
sessionID: sessionId,
|
|
93
93
|
directory: workingDirectory,
|
|
94
94
|
providerID,
|
|
@@ -60,8 +60,8 @@ export async function handleContextUsageCommand({ command }) {
|
|
|
60
60
|
await command.deferReply({ flags: SILENT_MESSAGE_FLAGS });
|
|
61
61
|
try {
|
|
62
62
|
const messagesResponse = await getClient().session.messages({
|
|
63
|
-
|
|
64
|
-
|
|
63
|
+
sessionID: sessionId,
|
|
64
|
+
directory: workingDirectory,
|
|
65
65
|
});
|
|
66
66
|
const messages = messagesResponse.data || [];
|
|
67
67
|
const assistantMessages = messages.filter((m) => m.info.role === 'assistant');
|
|
@@ -99,7 +99,7 @@ export async function handleContextUsageCommand({ command }) {
|
|
|
99
99
|
// Fetch model context limit from provider API
|
|
100
100
|
let contextLimit;
|
|
101
101
|
const providersResult = await errore.tryAsync(() => {
|
|
102
|
-
return getClient().provider.list({
|
|
102
|
+
return getClient().provider.list({ directory: workingDirectory });
|
|
103
103
|
});
|
|
104
104
|
if (providersResult instanceof Error) {
|
|
105
105
|
logger.error('[CONTEXT-USAGE] Failed to fetch provider info:', providersResult);
|
|
@@ -117,7 +117,7 @@ export async function handleContextUsageCommand({ command }) {
|
|
|
117
117
|
if (contextLimit) {
|
|
118
118
|
const percentage = Math.round((totalTokens / contextLimit) * 100);
|
|
119
119
|
const formattedLimit = contextLimit.toLocaleString('en-US');
|
|
120
|
-
lines.push(`**Context usage:** ${formattedTokens} / ${formattedLimit} tokens
|
|
120
|
+
lines.push(`**Context usage:** ${percentage}%, ${formattedTokens} / ${formattedLimit} tokens`);
|
|
121
121
|
}
|
|
122
122
|
else {
|
|
123
123
|
lines.push(`**Context usage:** ${formattedTokens} tokens (context limit unavailable)`);
|
|
@@ -70,7 +70,7 @@ export function showFileUploadButton({ thread, sessionId, directory, prompt, max
|
|
|
70
70
|
.fetch(ctx.messageId)
|
|
71
71
|
.then((msg) => {
|
|
72
72
|
return msg.edit({
|
|
73
|
-
content: `**File Upload Requested**\n${prompt}\n_Timed out_`,
|
|
73
|
+
content: `**File Upload Requested**\n${prompt.slice(0, 1900)}\n_Timed out_`,
|
|
74
74
|
components: [],
|
|
75
75
|
});
|
|
76
76
|
})
|
|
@@ -98,7 +98,7 @@ export function showFileUploadButton({ thread, sessionId, directory, prompt, max
|
|
|
98
98
|
const actionRow = new ActionRowBuilder().addComponents(uploadButton);
|
|
99
99
|
thread
|
|
100
100
|
.send({
|
|
101
|
-
content: `**File Upload Requested**\n${prompt}`,
|
|
101
|
+
content: `**File Upload Requested**\n${prompt.slice(0, 1900)}`,
|
|
102
102
|
components: [actionRow],
|
|
103
103
|
flags: NOTIFY_MESSAGE_FLAGS,
|
|
104
104
|
})
|
|
@@ -240,7 +240,7 @@ function updateButtonMessage(context, status) {
|
|
|
240
240
|
.fetch(context.messageId)
|
|
241
241
|
.then((msg) => {
|
|
242
242
|
return msg.edit({
|
|
243
|
-
content: `**File Upload Requested**\n${context.prompt}\n${status}`,
|
|
243
|
+
content: `**File Upload Requested**\n${context.prompt.slice(0, 1900)}\n${status}`,
|
|
244
244
|
components: [],
|
|
245
245
|
});
|
|
246
246
|
})
|
package/dist/commands/fork.js
CHANGED
|
@@ -57,7 +57,7 @@ export async function handleForkCommand(interaction) {
|
|
|
57
57
|
}
|
|
58
58
|
try {
|
|
59
59
|
const messagesResponse = await getClient().session.messages({
|
|
60
|
-
|
|
60
|
+
sessionID: sessionId,
|
|
61
61
|
});
|
|
62
62
|
if (!messagesResponse.data) {
|
|
63
63
|
await interaction.editReply({
|
|
@@ -143,8 +143,8 @@ export async function handleForkSelectMenu(interaction) {
|
|
|
143
143
|
}
|
|
144
144
|
try {
|
|
145
145
|
const forkResponse = await getClient().session.fork({
|
|
146
|
-
|
|
147
|
-
|
|
146
|
+
sessionID: sessionId,
|
|
147
|
+
messageID: selectedMessageId,
|
|
148
148
|
});
|
|
149
149
|
if (!forkResponse.data) {
|
|
150
150
|
await interaction.editReply('Failed to fork session');
|
|
@@ -178,7 +178,7 @@ export async function handleForkSelectMenu(interaction) {
|
|
|
178
178
|
await sendThreadMessage(thread, `**Forked session created!**\nFrom: \`${sessionId}\`\nNew session: \`${forkedSession.id}\``);
|
|
179
179
|
// Fetch and display the last assistant messages from the forked session
|
|
180
180
|
const messagesResponse = await getClient().session.messages({
|
|
181
|
-
|
|
181
|
+
sessionID: forkedSession.id,
|
|
182
182
|
});
|
|
183
183
|
if (messagesResponse.data) {
|
|
184
184
|
const { partIds, content } = collectLastAssistantParts({
|
package/dist/commands/login.js
CHANGED
|
@@ -73,7 +73,7 @@ export async function handleLoginCommand({ interaction, appId, }) {
|
|
|
73
73
|
return;
|
|
74
74
|
}
|
|
75
75
|
const providersResponse = await getClient().provider.list({
|
|
76
|
-
|
|
76
|
+
directory: projectDirectory,
|
|
77
77
|
});
|
|
78
78
|
if (!providersResponse.data) {
|
|
79
79
|
await interaction.editReply({
|
|
@@ -160,13 +160,13 @@ export async function handleLoginProviderSelectMenu(interaction) {
|
|
|
160
160
|
}
|
|
161
161
|
// Get provider info for display
|
|
162
162
|
const providersResponse = await getClient().provider.list({
|
|
163
|
-
|
|
163
|
+
directory: context.dir,
|
|
164
164
|
});
|
|
165
165
|
const provider = providersResponse.data?.all.find((p) => p.id === selectedProviderId);
|
|
166
166
|
const providerName = provider?.name || selectedProviderId;
|
|
167
167
|
// Get auth methods for all providers
|
|
168
168
|
const authMethodsResponse = await getClient().provider.auth({
|
|
169
|
-
|
|
169
|
+
directory: context.dir,
|
|
170
170
|
});
|
|
171
171
|
if (!authMethodsResponse.data) {
|
|
172
172
|
await interaction.deferUpdate();
|
|
@@ -273,7 +273,7 @@ export async function handleLoginMethodSelectMenu(interaction) {
|
|
|
273
273
|
}
|
|
274
274
|
// Get auth methods again to get the selected one
|
|
275
275
|
const authMethodsResponse = await getClient().provider.auth({
|
|
276
|
-
|
|
276
|
+
directory: context.dir,
|
|
277
277
|
});
|
|
278
278
|
const methods = authMethodsResponse.data?.[context.providerId] || [
|
|
279
279
|
{ type: 'api', label: 'API Key' },
|
|
@@ -361,9 +361,9 @@ async function startOAuthFlow(interaction, context, contextHash) {
|
|
|
361
361
|
});
|
|
362
362
|
// Start OAuth authorization
|
|
363
363
|
const authorizeResponse = await getClient().provider.oauth.authorize({
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
364
|
+
providerID: context.providerId,
|
|
365
|
+
method: context.methodIndex,
|
|
366
|
+
directory: context.dir,
|
|
367
367
|
});
|
|
368
368
|
if (!authorizeResponse.data) {
|
|
369
369
|
const errorData = authorizeResponse.error;
|
|
@@ -397,9 +397,9 @@ async function startOAuthFlow(interaction, context, contextHash) {
|
|
|
397
397
|
if (method === 'auto') {
|
|
398
398
|
// Poll for completion (device flow)
|
|
399
399
|
const callbackResponse = await getClient().provider.oauth.callback({
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
400
|
+
providerID: context.providerId,
|
|
401
|
+
method: context.methodIndex,
|
|
402
|
+
directory: context.dir,
|
|
403
403
|
});
|
|
404
404
|
if (callbackResponse.error) {
|
|
405
405
|
const errorData = callbackResponse.error;
|
|
@@ -410,7 +410,7 @@ async function startOAuthFlow(interaction, context, contextHash) {
|
|
|
410
410
|
return;
|
|
411
411
|
}
|
|
412
412
|
// Dispose to refresh provider state so new credentials are recognized
|
|
413
|
-
await getClient().instance.dispose({
|
|
413
|
+
await getClient().instance.dispose({ directory: context.dir });
|
|
414
414
|
await interaction.editReply({
|
|
415
415
|
content: `✅ **Successfully authenticated with ${context.providerName}!**\n\nYou can now use models from this provider.`,
|
|
416
416
|
components: [],
|
|
@@ -464,15 +464,14 @@ export async function handleApiKeyModalSubmit(interaction) {
|
|
|
464
464
|
}
|
|
465
465
|
// Set the API key
|
|
466
466
|
await getClient().auth.set({
|
|
467
|
-
|
|
468
|
-
|
|
467
|
+
providerID: context.providerId,
|
|
468
|
+
auth: {
|
|
469
469
|
type: 'api',
|
|
470
470
|
key: apiKey.trim(),
|
|
471
471
|
},
|
|
472
|
-
query: { directory: context.dir },
|
|
473
472
|
});
|
|
474
473
|
// Dispose to refresh provider state so new credentials are recognized
|
|
475
|
-
await getClient().instance.dispose({
|
|
474
|
+
await getClient().instance.dispose({ directory: context.dir });
|
|
476
475
|
await interaction.editReply({
|
|
477
476
|
content: `✅ **Successfully authenticated with ${context.providerName}!**\n\nYou can now use models from this provider.`,
|
|
478
477
|
});
|
|
@@ -62,7 +62,7 @@ async function sendPromptToModel({ prompt, thread, projectDirectory, command, ap
|
|
|
62
62
|
appId,
|
|
63
63
|
}).catch((e) => {
|
|
64
64
|
logger.error(`[merge] Failed to send prompt to model:`, e);
|
|
65
|
-
sendThreadMessage(thread, `Failed to send prompt: ${e instanceof Error ? e.message : String(e)}`).catch(() => { });
|
|
65
|
+
sendThreadMessage(thread, `Failed to send prompt: ${(e instanceof Error ? e.message : String(e)).slice(0, 1900)}`).catch(() => { });
|
|
66
66
|
});
|
|
67
67
|
}
|
|
68
68
|
export async function handleMergeWorktreeCommand({ command, appId, }) {
|