kimiflare 0.84.0 → 0.84.1
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/index.js +399 -353
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -13999,6 +13999,301 @@ var init_deploy_commute = __esm({
|
|
|
13999
13999
|
}
|
|
14000
14000
|
});
|
|
14001
14001
|
|
|
14002
|
+
// src/util/image.ts
|
|
14003
|
+
import { readFile as readFile15 } from "fs/promises";
|
|
14004
|
+
import { basename as basename3 } from "path";
|
|
14005
|
+
async function encodeImageFile(filePath) {
|
|
14006
|
+
const buf = await readFile15(filePath);
|
|
14007
|
+
if (buf.byteLength > MAX_IMAGE_BYTES) {
|
|
14008
|
+
throw new Error(
|
|
14009
|
+
`image too large (${(buf.byteLength / 1024 / 1024).toFixed(1)} MB); max is ${MAX_IMAGE_BYTES / 1024 / 1024} MB`
|
|
14010
|
+
);
|
|
14011
|
+
}
|
|
14012
|
+
const ext = filePath.slice(filePath.lastIndexOf(".")).toLowerCase();
|
|
14013
|
+
const mime = EXT_TO_MIME[ext] ?? "image/jpeg";
|
|
14014
|
+
const b64 = buf.toString("base64");
|
|
14015
|
+
return {
|
|
14016
|
+
filename: basename3(filePath),
|
|
14017
|
+
mime,
|
|
14018
|
+
dataUrl: `data:${mime};base64,${b64}`
|
|
14019
|
+
};
|
|
14020
|
+
}
|
|
14021
|
+
function isImagePath(path) {
|
|
14022
|
+
const ext = path.slice(path.lastIndexOf(".")).toLowerCase();
|
|
14023
|
+
return ext in EXT_TO_MIME;
|
|
14024
|
+
}
|
|
14025
|
+
var MAX_IMAGE_BYTES, EXT_TO_MIME;
|
|
14026
|
+
var init_image = __esm({
|
|
14027
|
+
"src/util/image.ts"() {
|
|
14028
|
+
"use strict";
|
|
14029
|
+
MAX_IMAGE_BYTES = 5 * 1024 * 1024;
|
|
14030
|
+
EXT_TO_MIME = {
|
|
14031
|
+
".png": "image/png",
|
|
14032
|
+
".jpg": "image/jpeg",
|
|
14033
|
+
".jpeg": "image/jpeg",
|
|
14034
|
+
".gif": "image/gif",
|
|
14035
|
+
".webp": "image/webp",
|
|
14036
|
+
".bmp": "image/bmp"
|
|
14037
|
+
};
|
|
14038
|
+
}
|
|
14039
|
+
});
|
|
14040
|
+
|
|
14041
|
+
// src/ui/app-helpers.ts
|
|
14042
|
+
import { execSync as execSync3, spawn as spawn5 } from "child_process";
|
|
14043
|
+
import { existsSync as existsSync4, readFileSync as readFileSync4, statSync as statSync4 } from "fs";
|
|
14044
|
+
import { join as join24 } from "path";
|
|
14045
|
+
import { platform as platform3 } from "os";
|
|
14046
|
+
function buildFilePickerIgnoreList(cwd) {
|
|
14047
|
+
const hardcoded = [
|
|
14048
|
+
// Dependencies
|
|
14049
|
+
"**/node_modules/**",
|
|
14050
|
+
"**/vendor/**",
|
|
14051
|
+
"**/.bundle/**",
|
|
14052
|
+
"**/bower_components/**",
|
|
14053
|
+
// Version control
|
|
14054
|
+
"**/.git/**",
|
|
14055
|
+
"**/.svn/**",
|
|
14056
|
+
"**/.hg/**",
|
|
14057
|
+
// Build / output directories
|
|
14058
|
+
"**/dist/**",
|
|
14059
|
+
"**/build/**",
|
|
14060
|
+
"**/out/**",
|
|
14061
|
+
"**/public/**",
|
|
14062
|
+
"**/.next/**",
|
|
14063
|
+
"**/.nuxt/**",
|
|
14064
|
+
"**/.svelte-kit/**",
|
|
14065
|
+
"**/.vercel/**",
|
|
14066
|
+
"**/.netlify/**",
|
|
14067
|
+
"**/target/**",
|
|
14068
|
+
"**/bin/**",
|
|
14069
|
+
"**/obj/**",
|
|
14070
|
+
"**/Debug/**",
|
|
14071
|
+
"**/Release/**",
|
|
14072
|
+
"**/.gradle/**",
|
|
14073
|
+
// Caches
|
|
14074
|
+
"**/.cache/**",
|
|
14075
|
+
"**/.parcel-cache/**",
|
|
14076
|
+
"**/.turbo/**",
|
|
14077
|
+
"**/.eslintcache",
|
|
14078
|
+
"**/.stylelintcache",
|
|
14079
|
+
"**/.rpt2_cache/**",
|
|
14080
|
+
"**/.rts2_cache/**",
|
|
14081
|
+
// Temporary
|
|
14082
|
+
"**/tmp/**",
|
|
14083
|
+
"**/temp/**",
|
|
14084
|
+
"**/*.tmp",
|
|
14085
|
+
// Coverage
|
|
14086
|
+
"**/coverage/**",
|
|
14087
|
+
"**/.nyc_output/**",
|
|
14088
|
+
// OS files
|
|
14089
|
+
"**/.DS_Store",
|
|
14090
|
+
"**/Thumbs.db",
|
|
14091
|
+
// Logs
|
|
14092
|
+
"**/*.log",
|
|
14093
|
+
"**/logs/**",
|
|
14094
|
+
// Lock files (auto-generated, usually huge)
|
|
14095
|
+
"**/package-lock.json",
|
|
14096
|
+
"**/yarn.lock",
|
|
14097
|
+
"**/pnpm-lock.yaml",
|
|
14098
|
+
"**/bun.lockb",
|
|
14099
|
+
"**/Cargo.lock",
|
|
14100
|
+
"**/Gemfile.lock",
|
|
14101
|
+
"**/composer.lock",
|
|
14102
|
+
"**/Pipfile.lock",
|
|
14103
|
+
"**/poetry.lock",
|
|
14104
|
+
"**/go.sum",
|
|
14105
|
+
// Minified / source maps
|
|
14106
|
+
"**/*.min.js",
|
|
14107
|
+
"**/*.min.css",
|
|
14108
|
+
"**/*.map",
|
|
14109
|
+
// kimiflare internal
|
|
14110
|
+
"**/.kimiflare/**",
|
|
14111
|
+
// IDE (usually not relevant to mention)
|
|
14112
|
+
"**/.idea/**"
|
|
14113
|
+
];
|
|
14114
|
+
const gitignorePatterns = [];
|
|
14115
|
+
try {
|
|
14116
|
+
const gitignorePath = join24(cwd, ".gitignore");
|
|
14117
|
+
const stats = statSync4(gitignorePath);
|
|
14118
|
+
if (stats.size > MAX_GITIGNORE_SIZE) {
|
|
14119
|
+
return hardcoded;
|
|
14120
|
+
}
|
|
14121
|
+
const content = readFileSync4(gitignorePath, "utf-8");
|
|
14122
|
+
for (const line of content.split(/\r?\n/)) {
|
|
14123
|
+
const trimmed = line.trim();
|
|
14124
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
14125
|
+
if (trimmed.startsWith("!")) continue;
|
|
14126
|
+
let pattern = trimmed;
|
|
14127
|
+
const isAnchored = pattern.startsWith("/");
|
|
14128
|
+
const isDir = pattern.endsWith("/");
|
|
14129
|
+
if (isAnchored) pattern = pattern.slice(1);
|
|
14130
|
+
if (isDir) pattern = pattern.slice(0, -1);
|
|
14131
|
+
if (!pattern) continue;
|
|
14132
|
+
if (isAnchored) {
|
|
14133
|
+
gitignorePatterns.push(isDir ? pattern + "/**" : pattern);
|
|
14134
|
+
} else {
|
|
14135
|
+
gitignorePatterns.push(isDir ? "**/" + pattern + "/**" : "**/" + pattern);
|
|
14136
|
+
}
|
|
14137
|
+
}
|
|
14138
|
+
} catch {
|
|
14139
|
+
}
|
|
14140
|
+
return [...hardcoded, ...gitignorePatterns];
|
|
14141
|
+
}
|
|
14142
|
+
function gatewayFromConfig(cfg) {
|
|
14143
|
+
if (process.env.KIMIFLARE_DISABLE_AI_GATEWAY === "1") return void 0;
|
|
14144
|
+
if (!cfg.aiGatewayId) return void 0;
|
|
14145
|
+
return {
|
|
14146
|
+
id: cfg.aiGatewayId,
|
|
14147
|
+
cacheTtl: cfg.aiGatewayCacheTtl,
|
|
14148
|
+
skipCache: cfg.aiGatewaySkipCache,
|
|
14149
|
+
collectLogPayload: cfg.aiGatewayCollectLogPayload,
|
|
14150
|
+
metadata: cfg.aiGatewayMetadata
|
|
14151
|
+
};
|
|
14152
|
+
}
|
|
14153
|
+
function gatewayUsageLookupFromConfig(cfg, meta) {
|
|
14154
|
+
if (process.env.KIMIFLARE_DISABLE_AI_GATEWAY === "1") return void 0;
|
|
14155
|
+
if (!cfg.aiGatewayId || !meta) return void 0;
|
|
14156
|
+
return {
|
|
14157
|
+
accountId: cfg.accountId,
|
|
14158
|
+
apiToken: cfg.apiToken,
|
|
14159
|
+
gatewayId: cfg.aiGatewayId,
|
|
14160
|
+
meta
|
|
14161
|
+
};
|
|
14162
|
+
}
|
|
14163
|
+
function openBrowser(url) {
|
|
14164
|
+
const cmd = platform3() === "darwin" ? "open" : platform3() === "win32" ? "start" : "xdg-open";
|
|
14165
|
+
const child = spawn5(cmd, [url], { detached: true, stdio: "ignore" });
|
|
14166
|
+
child.unref();
|
|
14167
|
+
}
|
|
14168
|
+
function detectGitHubRepo(cachedRepo) {
|
|
14169
|
+
if (cachedRepo) {
|
|
14170
|
+
const parts = cachedRepo.split("/");
|
|
14171
|
+
if (parts.length === 2) return { owner: parts[0], name: parts[1] };
|
|
14172
|
+
}
|
|
14173
|
+
try {
|
|
14174
|
+
const remoteUrl = execSync3("git remote get-url origin", { cwd: process.cwd(), encoding: "utf8" }).trim();
|
|
14175
|
+
const httpsMatch = remoteUrl.match(/github\.com\/([^\/]+)\/([^\/]+?)(?:\.git)?$/);
|
|
14176
|
+
if (httpsMatch) return { owner: httpsMatch[1], name: httpsMatch[2] };
|
|
14177
|
+
const sshMatch = remoteUrl.match(/github\.com:([^\/]+)\/([^\/]+?)(?:\.git)?$/);
|
|
14178
|
+
if (sshMatch) return { owner: sshMatch[1], name: sshMatch[2] };
|
|
14179
|
+
} catch {
|
|
14180
|
+
}
|
|
14181
|
+
return null;
|
|
14182
|
+
}
|
|
14183
|
+
function detectGitBranch() {
|
|
14184
|
+
try {
|
|
14185
|
+
return execSync3("git branch --show-current", { cwd: process.cwd(), encoding: "utf8" }).trim() || null;
|
|
14186
|
+
} catch {
|
|
14187
|
+
return null;
|
|
14188
|
+
}
|
|
14189
|
+
}
|
|
14190
|
+
function formatTokens(n) {
|
|
14191
|
+
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
14192
|
+
if (n >= 1e3) return `${(n / 1e3).toFixed(1)}K`;
|
|
14193
|
+
return String(n);
|
|
14194
|
+
}
|
|
14195
|
+
function trackRecentFile(ref, path, max = 10) {
|
|
14196
|
+
ref.current.set(path, Date.now());
|
|
14197
|
+
if (ref.current.size > max) {
|
|
14198
|
+
let oldest = null;
|
|
14199
|
+
let oldestTime = Infinity;
|
|
14200
|
+
for (const [p, t] of ref.current) {
|
|
14201
|
+
if (t < oldestTime) {
|
|
14202
|
+
oldestTime = t;
|
|
14203
|
+
oldest = p;
|
|
14204
|
+
}
|
|
14205
|
+
}
|
|
14206
|
+
if (oldest) ref.current.delete(oldest);
|
|
14207
|
+
}
|
|
14208
|
+
}
|
|
14209
|
+
function capEvents(prev) {
|
|
14210
|
+
if (prev.length <= MAX_EVENTS) return prev;
|
|
14211
|
+
return prev.slice(prev.length - MAX_EVENTS);
|
|
14212
|
+
}
|
|
14213
|
+
function compactEventsVisual(prev, keepLastTurns) {
|
|
14214
|
+
let seen = 0;
|
|
14215
|
+
let cutoff = -1;
|
|
14216
|
+
for (let i = prev.length - 1; i >= 0; i--) {
|
|
14217
|
+
if (prev[i].kind === "user") {
|
|
14218
|
+
seen++;
|
|
14219
|
+
if (seen === keepLastTurns + 1) {
|
|
14220
|
+
cutoff = i;
|
|
14221
|
+
break;
|
|
14222
|
+
}
|
|
14223
|
+
}
|
|
14224
|
+
}
|
|
14225
|
+
if (cutoff <= 0) return prev;
|
|
14226
|
+
const kept = prev.slice(cutoff);
|
|
14227
|
+
return [
|
|
14228
|
+
{ kind: "info", key: mkKey(), text: `\xB7\xB7\xB7 ${cutoff} earlier messages compacted \xB7\xB7\xB7` },
|
|
14229
|
+
...kept
|
|
14230
|
+
];
|
|
14231
|
+
}
|
|
14232
|
+
function makePrefixMessages(cacheStable, model, mode, tools) {
|
|
14233
|
+
if (cacheStable) {
|
|
14234
|
+
return buildSystemMessages({ cwd: process.cwd(), tools, model, mode });
|
|
14235
|
+
}
|
|
14236
|
+
return [
|
|
14237
|
+
{
|
|
14238
|
+
role: "system",
|
|
14239
|
+
content: buildSystemPrompt({ cwd: process.cwd(), tools, model, mode })
|
|
14240
|
+
}
|
|
14241
|
+
];
|
|
14242
|
+
}
|
|
14243
|
+
function rebuildSystemPromptForMode(messages, cacheStable, model, mode, tools) {
|
|
14244
|
+
if (cacheStable) {
|
|
14245
|
+
const rebuilt = buildSystemMessages({ cwd: process.cwd(), tools, model, mode });
|
|
14246
|
+
messages[0] = rebuilt[0];
|
|
14247
|
+
if (rebuilt[1]) {
|
|
14248
|
+
messages[1] = rebuilt[1];
|
|
14249
|
+
}
|
|
14250
|
+
} else {
|
|
14251
|
+
messages[0] = {
|
|
14252
|
+
role: "system",
|
|
14253
|
+
content: buildSystemPrompt({ cwd: process.cwd(), tools, model, mode })
|
|
14254
|
+
};
|
|
14255
|
+
}
|
|
14256
|
+
}
|
|
14257
|
+
function findImagePaths(text) {
|
|
14258
|
+
const paths = [];
|
|
14259
|
+
const quotedRegex = /"([^"]+)"|'([^']+)'/g;
|
|
14260
|
+
let match;
|
|
14261
|
+
while ((match = quotedRegex.exec(text)) !== null) {
|
|
14262
|
+
const path = match[1] ?? match[2];
|
|
14263
|
+
if (path && isImagePath(path) && existsSync4(path)) {
|
|
14264
|
+
paths.push(path);
|
|
14265
|
+
}
|
|
14266
|
+
}
|
|
14267
|
+
const remaining = text.replace(/"[^"]+"|'[^']+'/g, "");
|
|
14268
|
+
const ESCAPED_SPACE = "\0";
|
|
14269
|
+
const processed = remaining.replace(/\\ /g, ESCAPED_SPACE);
|
|
14270
|
+
for (const token of processed.split(/\s+/)) {
|
|
14271
|
+
const clean = token.replace(new RegExp(ESCAPED_SPACE, "g"), " ").replace(/^["']|["',;:!?]$/g, "").replace(/[.,;:!?]$/, "");
|
|
14272
|
+
if (clean && isImagePath(clean) && existsSync4(clean) && !paths.includes(clean)) {
|
|
14273
|
+
paths.push(clean);
|
|
14274
|
+
}
|
|
14275
|
+
}
|
|
14276
|
+
return paths;
|
|
14277
|
+
}
|
|
14278
|
+
var MAX_GITIGNORE_SIZE, CONTEXT_LIMIT, AUTO_COMPACT_THRESHOLD, MAX_EVENTS, MAX_IMAGES_PER_MESSAGE, FEEDBACK_WORKER_URL, nextKey, mkKey, nextAssistantId, mkAssistantId;
|
|
14279
|
+
var init_app_helpers = __esm({
|
|
14280
|
+
"src/ui/app-helpers.ts"() {
|
|
14281
|
+
"use strict";
|
|
14282
|
+
init_system_prompt();
|
|
14283
|
+
init_image();
|
|
14284
|
+
MAX_GITIGNORE_SIZE = 1 * 1024 * 1024;
|
|
14285
|
+
CONTEXT_LIMIT = 262e3;
|
|
14286
|
+
AUTO_COMPACT_THRESHOLD = 0.8;
|
|
14287
|
+
MAX_EVENTS = 500;
|
|
14288
|
+
MAX_IMAGES_PER_MESSAGE = 10;
|
|
14289
|
+
FEEDBACK_WORKER_URL = "https://hello.kimiflare.com";
|
|
14290
|
+
nextKey = 1;
|
|
14291
|
+
mkKey = () => `evt_${nextKey++}`;
|
|
14292
|
+
nextAssistantId = 1;
|
|
14293
|
+
mkAssistantId = () => nextAssistantId++;
|
|
14294
|
+
}
|
|
14295
|
+
});
|
|
14296
|
+
|
|
14002
14297
|
// src/commands/builtins.ts
|
|
14003
14298
|
var BUILTIN_COMMANDS, BUILTIN_COMMAND_NAMES;
|
|
14004
14299
|
var init_builtins = __esm({
|
|
@@ -15021,24 +15316,24 @@ var init_theme = __esm({
|
|
|
15021
15316
|
});
|
|
15022
15317
|
|
|
15023
15318
|
// src/util/clipboard.ts
|
|
15024
|
-
import { execSync as
|
|
15025
|
-
import { platform as
|
|
15319
|
+
import { execSync as execSync4 } from "child_process";
|
|
15320
|
+
import { platform as platform4 } from "os";
|
|
15026
15321
|
function writeToClipboard(text) {
|
|
15027
|
-
const os2 =
|
|
15322
|
+
const os2 = platform4();
|
|
15028
15323
|
try {
|
|
15029
15324
|
if (os2 === "darwin") {
|
|
15030
|
-
|
|
15325
|
+
execSync4("pbcopy", { input: text, timeout: 5e3 });
|
|
15031
15326
|
return { success: true, message: "Copied to clipboard" };
|
|
15032
15327
|
}
|
|
15033
15328
|
if (os2 === "win32") {
|
|
15034
|
-
|
|
15329
|
+
execSync4("clip", { input: text, timeout: 5e3 });
|
|
15035
15330
|
return { success: true, message: "Copied to clipboard" };
|
|
15036
15331
|
}
|
|
15037
15332
|
try {
|
|
15038
|
-
|
|
15333
|
+
execSync4("xclip -selection clipboard", { input: text, timeout: 5e3 });
|
|
15039
15334
|
return { success: true, message: "Copied to clipboard" };
|
|
15040
15335
|
} catch {
|
|
15041
|
-
|
|
15336
|
+
execSync4("xsel --clipboard --input", { input: text, timeout: 5e3 });
|
|
15042
15337
|
return { success: true, message: "Copied to clipboard" };
|
|
15043
15338
|
}
|
|
15044
15339
|
} catch {
|
|
@@ -15359,8 +15654,8 @@ var init_frontmatter = __esm({
|
|
|
15359
15654
|
});
|
|
15360
15655
|
|
|
15361
15656
|
// src/skills/loader.ts
|
|
15362
|
-
import { readFile as
|
|
15363
|
-
import { join as
|
|
15657
|
+
import { readFile as readFile16, readdir as readdir6, stat as stat6 } from "fs/promises";
|
|
15658
|
+
import { join as join25, extname } from "path";
|
|
15364
15659
|
function normalizeManifest(raw, filePath) {
|
|
15365
15660
|
const name = typeof raw.name === "string" ? raw.name : "";
|
|
15366
15661
|
const description = typeof raw.description === "string" ? raw.description : "";
|
|
@@ -15374,7 +15669,7 @@ function normalizeManifest(raw, filePath) {
|
|
|
15374
15669
|
return { name, description, match, scope, priority, enabled };
|
|
15375
15670
|
}
|
|
15376
15671
|
async function loadSkillFile(filePath) {
|
|
15377
|
-
const raw = await
|
|
15672
|
+
const raw = await readFile16(filePath, "utf-8");
|
|
15378
15673
|
const parsed = parseFrontmatter(raw);
|
|
15379
15674
|
const manifest = normalizeManifest(parsed.data, filePath);
|
|
15380
15675
|
const body = parsed.content.trim();
|
|
@@ -15396,7 +15691,7 @@ async function loadSkillsFromDir(dirPath) {
|
|
|
15396
15691
|
const entries = await readdir6(dirPath);
|
|
15397
15692
|
const files = [];
|
|
15398
15693
|
for (const entry of entries) {
|
|
15399
|
-
const full =
|
|
15694
|
+
const full = join25(dirPath, entry);
|
|
15400
15695
|
const s = await stat6(full);
|
|
15401
15696
|
if (s.isFile() && extname(entry) === ".md") {
|
|
15402
15697
|
files.push(full);
|
|
@@ -15424,12 +15719,12 @@ var init_loader = __esm({
|
|
|
15424
15719
|
});
|
|
15425
15720
|
|
|
15426
15721
|
// src/skills/manager.ts
|
|
15427
|
-
import { mkdir as mkdir10, writeFile as writeFile11, unlink as unlink2, readFile as
|
|
15428
|
-
import { join as
|
|
15722
|
+
import { mkdir as mkdir10, writeFile as writeFile11, unlink as unlink2, readFile as readFile17 } from "fs/promises";
|
|
15723
|
+
import { join as join26 } from "path";
|
|
15429
15724
|
function getSkillDirs(cwd) {
|
|
15430
15725
|
return {
|
|
15431
|
-
projectDir:
|
|
15432
|
-
globalDir:
|
|
15726
|
+
projectDir: join26(cwd, ".kimiflare", "skills"),
|
|
15727
|
+
globalDir: join26(process.env.HOME ?? "", ".config", "kimiflare", "skills")
|
|
15433
15728
|
};
|
|
15434
15729
|
}
|
|
15435
15730
|
async function listAllSkills(cwd) {
|
|
@@ -15443,7 +15738,7 @@ async function listAllSkills(cwd) {
|
|
|
15443
15738
|
async function createSkill(opts2) {
|
|
15444
15739
|
const dirs = getSkillDirs(opts2.cwd);
|
|
15445
15740
|
const dir = opts2.scope === "project" ? dirs.projectDir : dirs.globalDir;
|
|
15446
|
-
const filepath =
|
|
15741
|
+
const filepath = join26(dir, `${opts2.name}.md`);
|
|
15447
15742
|
const frontmatter = {
|
|
15448
15743
|
name: opts2.name,
|
|
15449
15744
|
enabled: true,
|
|
@@ -15479,7 +15774,7 @@ async function setSkillEnabled(name, enabled, cwd) {
|
|
|
15479
15774
|
const all = await listAllSkills(cwd);
|
|
15480
15775
|
const skill = all.project.find((s) => s.name === name) ?? all.global.find((s) => s.name === name);
|
|
15481
15776
|
if (!skill) throw new Error(`skill "${name}" not found`);
|
|
15482
|
-
const raw = await
|
|
15777
|
+
const raw = await readFile17(skill.filePath, "utf-8");
|
|
15483
15778
|
const parsed = parseFrontmatter(raw);
|
|
15484
15779
|
parsed.data.enabled = enabled;
|
|
15485
15780
|
const yaml = Object.entries(parsed.data).map(([k, v]) => {
|
|
@@ -15564,13 +15859,13 @@ var init_frontmatter2 = __esm({
|
|
|
15564
15859
|
// src/commands/loader.ts
|
|
15565
15860
|
import { open, realpath as realpath2 } from "fs/promises";
|
|
15566
15861
|
import { homedir as homedir14 } from "os";
|
|
15567
|
-
import { join as
|
|
15862
|
+
import { join as join27, relative as relative5, sep as sep2 } from "path";
|
|
15568
15863
|
function projectCommandsDir(cwd = process.cwd()) {
|
|
15569
|
-
return
|
|
15864
|
+
return join27(cwd, ".kimiflare", "commands");
|
|
15570
15865
|
}
|
|
15571
15866
|
function globalCommandsDir() {
|
|
15572
|
-
const xdg = process.env.XDG_CONFIG_HOME ||
|
|
15573
|
-
return
|
|
15867
|
+
const xdg = process.env.XDG_CONFIG_HOME || join27(homedir14(), ".config");
|
|
15868
|
+
return join27(xdg, "kimiflare", "commands");
|
|
15574
15869
|
}
|
|
15575
15870
|
async function loadCustomCommands(cwd = process.cwd()) {
|
|
15576
15871
|
const warnings = [];
|
|
@@ -15844,13 +16139,13 @@ var init_worker_client = __esm({
|
|
|
15844
16139
|
});
|
|
15845
16140
|
|
|
15846
16141
|
// src/init/context-generator.ts
|
|
15847
|
-
import { existsSync as
|
|
15848
|
-
import { join as
|
|
16142
|
+
import { existsSync as existsSync5, statSync as statSync5 } from "fs";
|
|
16143
|
+
import { join as join28 } from "path";
|
|
15849
16144
|
function detectFlavor(cwd) {
|
|
15850
16145
|
for (const [flavor, signatures] of Object.entries(FLAVOR_SIGNATURES)) {
|
|
15851
16146
|
if (flavor === "generic") continue;
|
|
15852
16147
|
for (const sig of signatures) {
|
|
15853
|
-
const path =
|
|
16148
|
+
const path = join28(cwd, sig);
|
|
15854
16149
|
if (sig.includes("*")) {
|
|
15855
16150
|
try {
|
|
15856
16151
|
const parts = sig.split("*");
|
|
@@ -15862,7 +16157,7 @@ function detectFlavor(cwd) {
|
|
|
15862
16157
|
}
|
|
15863
16158
|
} catch {
|
|
15864
16159
|
}
|
|
15865
|
-
} else if (
|
|
16160
|
+
} else if (existsSync5(path)) {
|
|
15866
16161
|
return flavor;
|
|
15867
16162
|
}
|
|
15868
16163
|
}
|
|
@@ -15871,16 +16166,16 @@ function detectFlavor(cwd) {
|
|
|
15871
16166
|
}
|
|
15872
16167
|
function findFile(cwd, candidates) {
|
|
15873
16168
|
for (const c of candidates) {
|
|
15874
|
-
if (
|
|
16169
|
+
if (existsSync5(join28(cwd, c))) return c;
|
|
15875
16170
|
}
|
|
15876
16171
|
return null;
|
|
15877
16172
|
}
|
|
15878
16173
|
function findSourceRoots(cwd) {
|
|
15879
16174
|
const roots = [];
|
|
15880
16175
|
for (const r of SOURCE_ROOT_CANDIDATES) {
|
|
15881
|
-
const p =
|
|
16176
|
+
const p = join28(cwd, r);
|
|
15882
16177
|
try {
|
|
15883
|
-
const s =
|
|
16178
|
+
const s = statSync5(p);
|
|
15884
16179
|
if (s.isDirectory()) roots.push(r);
|
|
15885
16180
|
} catch {
|
|
15886
16181
|
}
|
|
@@ -15889,9 +16184,9 @@ function findSourceRoots(cwd) {
|
|
|
15889
16184
|
}
|
|
15890
16185
|
function findCiConfig(cwd) {
|
|
15891
16186
|
for (const c of CI_PATHS) {
|
|
15892
|
-
if (
|
|
16187
|
+
if (existsSync5(join28(cwd, c))) {
|
|
15893
16188
|
try {
|
|
15894
|
-
const s =
|
|
16189
|
+
const s = statSync5(join28(cwd, c));
|
|
15895
16190
|
return s.isDirectory() ? c : c;
|
|
15896
16191
|
} catch {
|
|
15897
16192
|
}
|
|
@@ -16028,7 +16323,7 @@ function analyzeProject(cwd) {
|
|
|
16028
16323
|
ciConfig: findCiConfig(cwd),
|
|
16029
16324
|
readme: findFile(cwd, ["README.md", "README.rst", "README.txt", "Readme.md"]),
|
|
16030
16325
|
sourceRoots: findSourceRoots(cwd),
|
|
16031
|
-
hasGit:
|
|
16326
|
+
hasGit: existsSync5(join28(cwd, ".git"))
|
|
16032
16327
|
};
|
|
16033
16328
|
}
|
|
16034
16329
|
function bashDiscoveryCommands(profile) {
|
|
@@ -16193,7 +16488,7 @@ Aim for 100\u2013200 lines total. Use markdown tables where they save space.
|
|
|
16193
16488
|
}
|
|
16194
16489
|
function buildInitPrompt(cwd) {
|
|
16195
16490
|
const existingName = ["KIMI.md", "KIMIFLARE.md", "AGENT.md"].find(
|
|
16196
|
-
(n) =>
|
|
16491
|
+
(n) => existsSync5(join28(cwd, n))
|
|
16197
16492
|
);
|
|
16198
16493
|
const isRefresh = existingName !== void 0;
|
|
16199
16494
|
const targetFilename = existingName ?? "KIMI.md";
|
|
@@ -16281,11 +16576,11 @@ __export(ui_mode_exports, {
|
|
|
16281
16576
|
runCamouflageOnboarding: () => runCamouflageOnboarding,
|
|
16282
16577
|
runUiMode: () => runUiMode
|
|
16283
16578
|
});
|
|
16284
|
-
import { execSync as
|
|
16579
|
+
import { execSync as execSync5, spawn as spawn6 } from "child_process";
|
|
16285
16580
|
import { appendFileSync, openSync } from "fs";
|
|
16286
16581
|
import { readdir as readdir7, unlink as unlink4 } from "fs/promises";
|
|
16287
|
-
import { join as
|
|
16288
|
-
import { platform as
|
|
16582
|
+
import { join as join29, relative as relative6 } from "path";
|
|
16583
|
+
import { platform as platform5 } from "os";
|
|
16289
16584
|
function kimiLog(payload) {
|
|
16290
16585
|
if (!KIMI_LOG_PATH) return;
|
|
16291
16586
|
try {
|
|
@@ -17067,6 +17362,14 @@ Executor opened PR: ${prUrl}` : plan });
|
|
|
17067
17362
|
cam.send("StatusUpdate", {
|
|
17068
17363
|
segments: { tokens: "in 0", cost: "$0.00", elapsed: "" }
|
|
17069
17364
|
});
|
|
17365
|
+
rebuildSystemPromptForMode(
|
|
17366
|
+
messages,
|
|
17367
|
+
false,
|
|
17368
|
+
// Camouflage UI always uses single system message
|
|
17369
|
+
opts2.model,
|
|
17370
|
+
currentMode,
|
|
17371
|
+
ALL_TOOLS
|
|
17372
|
+
);
|
|
17070
17373
|
messages.push({ role: "user", content: selected.plan });
|
|
17071
17374
|
cam.send("UserMessageCreated", { text: selected.plan });
|
|
17072
17375
|
cam.send("ShowToast", {
|
|
@@ -17129,7 +17432,7 @@ Executor opened PR: ${prUrl}` : plan });
|
|
|
17129
17432
|
allow_cancel: true
|
|
17130
17433
|
});
|
|
17131
17434
|
if (pick3.cancelled || !pick3.value) return;
|
|
17132
|
-
|
|
17435
|
+
openBrowser2(
|
|
17133
17436
|
`${URL2}/inbox?u=${encodeURIComponent(handle)}&s=${encodeURIComponent(secret)}&m=${encodeURIComponent(pick3.value)}`
|
|
17134
17437
|
);
|
|
17135
17438
|
cam.send("ShowToast", { text: "opened in browser", kind: "success", ttl_ms: 1500 });
|
|
@@ -18246,7 +18549,7 @@ Executor opened PR: ${prUrl}` : plan });
|
|
|
18246
18549
|
return true;
|
|
18247
18550
|
}
|
|
18248
18551
|
case "hello":
|
|
18249
|
-
|
|
18552
|
+
openBrowser2("https://hello.kimiflare.com");
|
|
18250
18553
|
cam.send("ShowToast", { text: "opened hello.kimiflare.com \u2014 leave the creator a voice note", kind: "info", ttl_ms: 3500 });
|
|
18251
18554
|
return true;
|
|
18252
18555
|
case "inbox":
|
|
@@ -18282,6 +18585,14 @@ Executor opened PR: ${prUrl}` : plan });
|
|
|
18282
18585
|
cam.send("StatusUpdate", {
|
|
18283
18586
|
segments: { tokens: "in 0", cost: "$0.00", elapsed: "" }
|
|
18284
18587
|
});
|
|
18588
|
+
rebuildSystemPromptForMode(
|
|
18589
|
+
messages,
|
|
18590
|
+
false,
|
|
18591
|
+
// Camouflage UI always uses single system message
|
|
18592
|
+
opts2.model,
|
|
18593
|
+
currentMode,
|
|
18594
|
+
ALL_TOOLS
|
|
18595
|
+
);
|
|
18285
18596
|
messages.push({ role: "user", content: plan });
|
|
18286
18597
|
cam.send("ShowToast", {
|
|
18287
18598
|
text: clipResult.success ? "Plan copied to clipboard. Starting fresh session with plan only\u2026" : "Clipboard unavailable. Starting fresh session with plan only\u2026",
|
|
@@ -18355,7 +18666,7 @@ async function registerMentions(cam, recents) {
|
|
|
18355
18666
|
for (const e of entries) {
|
|
18356
18667
|
if (collected.length >= 200) return;
|
|
18357
18668
|
if (e.name.startsWith(".") || SKIP.has(e.name)) continue;
|
|
18358
|
-
const full =
|
|
18669
|
+
const full = join29(dir, e.name);
|
|
18359
18670
|
if (e.isDirectory()) {
|
|
18360
18671
|
await walk2(full, depth + 1);
|
|
18361
18672
|
} else if (e.isFile()) {
|
|
@@ -18404,9 +18715,9 @@ function formatShortDate(iso) {
|
|
|
18404
18715
|
return iso;
|
|
18405
18716
|
}
|
|
18406
18717
|
}
|
|
18407
|
-
function
|
|
18408
|
-
const cmd =
|
|
18409
|
-
const child =
|
|
18718
|
+
function openBrowser2(url) {
|
|
18719
|
+
const cmd = platform5() === "darwin" ? "open" : platform5() === "win32" ? "start" : "xdg-open";
|
|
18720
|
+
const child = spawn6(cmd, [url], { detached: true, stdio: "ignore" });
|
|
18410
18721
|
child.unref();
|
|
18411
18722
|
}
|
|
18412
18723
|
function formatUsd(n) {
|
|
@@ -18425,7 +18736,7 @@ function formatElapsed2(secs) {
|
|
|
18425
18736
|
}
|
|
18426
18737
|
function tryGitBranch2() {
|
|
18427
18738
|
try {
|
|
18428
|
-
const out =
|
|
18739
|
+
const out = execSync5("git rev-parse --abbrev-ref HEAD 2>/dev/null", {
|
|
18429
18740
|
encoding: "utf8",
|
|
18430
18741
|
timeout: 200
|
|
18431
18742
|
}).trim();
|
|
@@ -18530,6 +18841,7 @@ var init_ui_mode = __esm({
|
|
|
18530
18841
|
init_classify();
|
|
18531
18842
|
init_deploy_commute();
|
|
18532
18843
|
init_system_prompt();
|
|
18844
|
+
init_app_helpers();
|
|
18533
18845
|
init_executor();
|
|
18534
18846
|
init_errors();
|
|
18535
18847
|
init_builtins();
|
|
@@ -21017,7 +21329,7 @@ var init_text_input = __esm({
|
|
|
21017
21329
|
// src/ui/permission.tsx
|
|
21018
21330
|
import { useState as useState4, useCallback } from "react";
|
|
21019
21331
|
import { Box as Box7, Text as Text8, useInput as useInput2 } from "ink";
|
|
21020
|
-
import { platform as
|
|
21332
|
+
import { platform as platform6 } from "os";
|
|
21021
21333
|
import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
21022
21334
|
function formatSelection(label, shortcut) {
|
|
21023
21335
|
return `${label} [${MOD_KEY}+${shortcut}]`;
|
|
@@ -21181,7 +21493,7 @@ var init_permission = __esm({
|
|
|
21181
21493
|
{ value: { decision: "deny", scope: "once" }, label: "Something else", key: 3 }
|
|
21182
21494
|
];
|
|
21183
21495
|
DENY = { decision: "deny", scope: "once" };
|
|
21184
|
-
MOD_KEY =
|
|
21496
|
+
MOD_KEY = platform6() === "darwin" ? "\u2325" : "Alt";
|
|
21185
21497
|
}
|
|
21186
21498
|
});
|
|
21187
21499
|
|
|
@@ -21619,7 +21931,7 @@ function TaskList({ tasks, startedAt, tokensDelta }) {
|
|
|
21619
21931
|
const allDone = done === total;
|
|
21620
21932
|
const header = active ? active.title : allDone ? `${total} tasks done` : `${done}/${total}`;
|
|
21621
21933
|
const elapsed = startedAt ? formatElapsed5(now2 - startedAt) : null;
|
|
21622
|
-
const headerStats = [elapsed, tokensDelta > 0 ? `\u2191 ${
|
|
21934
|
+
const headerStats = [elapsed, tokensDelta > 0 ? `\u2191 ${formatTokens2(tokensDelta)} tokens` : null].filter(Boolean).join(" \xB7 ");
|
|
21623
21935
|
const visibleTasks = tasks.slice(0, MAX_VISIBLE);
|
|
21624
21936
|
const hiddenPending = Math.max(0, tasks.length - visibleTasks.length);
|
|
21625
21937
|
return /* @__PURE__ */ jsxs11(Box11, { flexDirection: "column", marginBottom: 1, children: [
|
|
@@ -21671,7 +21983,7 @@ function formatElapsed5(ms) {
|
|
|
21671
21983
|
if (m === 0) return `${s}s`;
|
|
21672
21984
|
return `${m}m ${s}s`;
|
|
21673
21985
|
}
|
|
21674
|
-
function
|
|
21986
|
+
function formatTokens2(n) {
|
|
21675
21987
|
if (n < 1e3) return String(n);
|
|
21676
21988
|
return `${(n / 1e3).toFixed(1)}k`;
|
|
21677
21989
|
}
|
|
@@ -23210,54 +23522,15 @@ function Welcome() {
|
|
|
23210
23522
|
day: now2.getDay()
|
|
23211
23523
|
});
|
|
23212
23524
|
return /* @__PURE__ */ jsxs18(Box18, { flexDirection: "column", marginBottom: 1, children: [
|
|
23213
|
-
/* @__PURE__ */ jsx20(Box18, { marginBottom: 1, children: /* @__PURE__ */ jsx20(Text19, { bold: true, color: theme.accent, children: headline }) }),
|
|
23214
|
-
/* @__PURE__ */ jsx20(Box18, { flexDirection: "column", children: /* @__PURE__ */ jsx20(Text19, { color: theme.info.color, dimColor: true, children: "Type / for commands" }) })
|
|
23215
|
-
] });
|
|
23216
|
-
}
|
|
23217
|
-
var init_welcome = __esm({
|
|
23218
|
-
"src/ui/welcome.tsx"() {
|
|
23219
|
-
"use strict";
|
|
23220
|
-
init_theme_context();
|
|
23221
|
-
init_greetings();
|
|
23222
|
-
}
|
|
23223
|
-
});
|
|
23224
|
-
|
|
23225
|
-
// src/util/image.ts
|
|
23226
|
-
import { readFile as readFile17 } from "fs/promises";
|
|
23227
|
-
import { basename as basename4 } from "path";
|
|
23228
|
-
async function encodeImageFile(filePath) {
|
|
23229
|
-
const buf = await readFile17(filePath);
|
|
23230
|
-
if (buf.byteLength > MAX_IMAGE_BYTES) {
|
|
23231
|
-
throw new Error(
|
|
23232
|
-
`image too large (${(buf.byteLength / 1024 / 1024).toFixed(1)} MB); max is ${MAX_IMAGE_BYTES / 1024 / 1024} MB`
|
|
23233
|
-
);
|
|
23234
|
-
}
|
|
23235
|
-
const ext = filePath.slice(filePath.lastIndexOf(".")).toLowerCase();
|
|
23236
|
-
const mime = EXT_TO_MIME[ext] ?? "image/jpeg";
|
|
23237
|
-
const b64 = buf.toString("base64");
|
|
23238
|
-
return {
|
|
23239
|
-
filename: basename4(filePath),
|
|
23240
|
-
mime,
|
|
23241
|
-
dataUrl: `data:${mime};base64,${b64}`
|
|
23242
|
-
};
|
|
23243
|
-
}
|
|
23244
|
-
function isImagePath(path) {
|
|
23245
|
-
const ext = path.slice(path.lastIndexOf(".")).toLowerCase();
|
|
23246
|
-
return ext in EXT_TO_MIME;
|
|
23525
|
+
/* @__PURE__ */ jsx20(Box18, { marginBottom: 1, children: /* @__PURE__ */ jsx20(Text19, { bold: true, color: theme.accent, children: headline }) }),
|
|
23526
|
+
/* @__PURE__ */ jsx20(Box18, { flexDirection: "column", children: /* @__PURE__ */ jsx20(Text19, { color: theme.info.color, dimColor: true, children: "Type / for commands" }) })
|
|
23527
|
+
] });
|
|
23247
23528
|
}
|
|
23248
|
-
var
|
|
23249
|
-
|
|
23250
|
-
"src/util/image.ts"() {
|
|
23529
|
+
var init_welcome = __esm({
|
|
23530
|
+
"src/ui/welcome.tsx"() {
|
|
23251
23531
|
"use strict";
|
|
23252
|
-
|
|
23253
|
-
|
|
23254
|
-
".png": "image/png",
|
|
23255
|
-
".jpg": "image/jpeg",
|
|
23256
|
-
".jpeg": "image/jpeg",
|
|
23257
|
-
".gif": "image/gif",
|
|
23258
|
-
".webp": "image/webp",
|
|
23259
|
-
".bmp": "image/bmp"
|
|
23260
|
-
};
|
|
23532
|
+
init_theme_context();
|
|
23533
|
+
init_greetings();
|
|
23261
23534
|
}
|
|
23262
23535
|
});
|
|
23263
23536
|
|
|
@@ -23494,10 +23767,10 @@ var init_wcag = __esm({
|
|
|
23494
23767
|
|
|
23495
23768
|
// src/ui/theme-loader.ts
|
|
23496
23769
|
import { readFile as readFile18, readdir as readdir8 } from "fs/promises";
|
|
23497
|
-
import { join as
|
|
23770
|
+
import { join as join30 } from "path";
|
|
23498
23771
|
import { homedir as homedir15 } from "os";
|
|
23499
23772
|
function projectThemesDir(cwd = process.cwd()) {
|
|
23500
|
-
return
|
|
23773
|
+
return join30(cwd, ".kimiflare", "themes");
|
|
23501
23774
|
}
|
|
23502
23775
|
function isHexColor(c) {
|
|
23503
23776
|
return /^#[0-9a-fA-F]{6}$/.test(c);
|
|
@@ -23586,7 +23859,7 @@ async function loadThemesFromDir(dir, source) {
|
|
|
23586
23859
|
return { themes, errors };
|
|
23587
23860
|
}
|
|
23588
23861
|
for (const file of files.filter((f) => f.endsWith(".json"))) {
|
|
23589
|
-
const path =
|
|
23862
|
+
const path = join30(dir, file);
|
|
23590
23863
|
let raw;
|
|
23591
23864
|
try {
|
|
23592
23865
|
raw = await readFile18(path, "utf-8");
|
|
@@ -23735,8 +24008,8 @@ var init_theme_loader = __esm({
|
|
|
23735
24008
|
"use strict";
|
|
23736
24009
|
init_wcag();
|
|
23737
24010
|
init_theme();
|
|
23738
|
-
USER_THEMES_DIR =
|
|
23739
|
-
process.env.XDG_CONFIG_HOME ||
|
|
24011
|
+
USER_THEMES_DIR = join30(
|
|
24012
|
+
process.env.XDG_CONFIG_HOME || join30(homedir15(), ".config"),
|
|
23740
24013
|
"kimiflare",
|
|
23741
24014
|
"themes"
|
|
23742
24015
|
);
|
|
@@ -24823,7 +25096,7 @@ var init_command_list = __esm({
|
|
|
24823
25096
|
import { useState as useState18 } from "react";
|
|
24824
25097
|
import { Box as Box25, Text as Text26 } from "ink";
|
|
24825
25098
|
import SelectInput10 from "ink-select-input";
|
|
24826
|
-
import { spawn as
|
|
25099
|
+
import { spawn as spawn7 } from "child_process";
|
|
24827
25100
|
import { jsx as jsx27, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
24828
25101
|
function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
24829
25102
|
const theme = useTheme();
|
|
@@ -24837,7 +25110,7 @@ function LspWizard({ servers, currentScope, hasProjectDir, onDone, onSave }) {
|
|
|
24837
25110
|
const runInstall = (command) => {
|
|
24838
25111
|
setInstallState({ status: "running", output: "Installing..." });
|
|
24839
25112
|
const { shell, args } = getShellCommand();
|
|
24840
|
-
const child =
|
|
25113
|
+
const child = spawn7(shell, [...args, command], {
|
|
24841
25114
|
env: process.env
|
|
24842
25115
|
});
|
|
24843
25116
|
let stdout = "";
|
|
@@ -25863,7 +26136,7 @@ function formatSessionLine(s) {
|
|
|
25863
26136
|
const ago = formatAgo(new Date(s.updatedAt));
|
|
25864
26137
|
const prompt = s.prompt.slice(0, 30) + (s.prompt.length > 30 ? "\u2026" : "");
|
|
25865
26138
|
const outcome = s.prUrl ? `PR ${s.prUrl.split("/").pop()}` : s.status;
|
|
25866
|
-
const cost = s.tokensUsed && s.tokensBudget ? ` (${
|
|
26139
|
+
const cost = s.tokensUsed && s.tokensBudget ? ` (${formatTokens3(s.tokensUsed)}/${formatTokens3(s.tokensBudget)})` : s.tokensUsed ? ` (${formatTokens3(s.tokensUsed)})` : "";
|
|
25867
26140
|
return `${icon} ${prompt} \u2192 ${outcome} ${ago}${cost}`;
|
|
25868
26141
|
}
|
|
25869
26142
|
function formatAgo(date) {
|
|
@@ -25876,7 +26149,7 @@ function formatAgo(date) {
|
|
|
25876
26149
|
if (minutes > 0) return `${minutes}m ago`;
|
|
25877
26150
|
return "just now";
|
|
25878
26151
|
}
|
|
25879
|
-
function
|
|
26152
|
+
function formatTokens3(n) {
|
|
25880
26153
|
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
25881
26154
|
if (n >= 1e3) return `${(n / 1e3).toFixed(1)}K`;
|
|
25882
26155
|
return String(n);
|
|
@@ -25937,8 +26210,8 @@ function RemoteSessionDetail({
|
|
|
25937
26210
|
] }),
|
|
25938
26211
|
session.tokensUsed !== void 0 && /* @__PURE__ */ jsxs33(Text34, { children: [
|
|
25939
26212
|
"Tokens: ",
|
|
25940
|
-
|
|
25941
|
-
session.tokensBudget ? ` / ${
|
|
26213
|
+
formatTokens3(session.tokensUsed),
|
|
26214
|
+
session.tokensBudget ? ` / ${formatTokens3(session.tokensBudget)}` : ""
|
|
25942
26215
|
] }),
|
|
25943
26216
|
/* @__PURE__ */ jsxs33(Text34, { children: [
|
|
25944
26217
|
"Created: ",
|
|
@@ -25982,7 +26255,7 @@ function InboxModal({ onDone, onOpen }) {
|
|
|
25982
26255
|
setError(null);
|
|
25983
26256
|
try {
|
|
25984
26257
|
const res = await fetch(
|
|
25985
|
-
`${
|
|
26258
|
+
`${FEEDBACK_WORKER_URL2}/inbox/check?u=${encodeURIComponent(u)}&s=${encodeURIComponent(s)}`
|
|
25986
26259
|
);
|
|
25987
26260
|
if (!res.ok) {
|
|
25988
26261
|
throw new Error(`Server returned ${res.status}`);
|
|
@@ -26028,7 +26301,7 @@ function InboxModal({ onDone, onOpen }) {
|
|
|
26028
26301
|
if (messages.length === 0) return;
|
|
26029
26302
|
const msg = messages[selectedIndex];
|
|
26030
26303
|
if (!msg) return;
|
|
26031
|
-
const url = `${
|
|
26304
|
+
const url = `${FEEDBACK_WORKER_URL2}/inbox?u=${encodeURIComponent(twitter)}&s=${encodeURIComponent(secret)}&m=${encodeURIComponent(msg.id)}`;
|
|
26032
26305
|
onOpen(url);
|
|
26033
26306
|
onDone();
|
|
26034
26307
|
}, [messages, selectedIndex, twitter, secret, onOpen, onDone]);
|
|
@@ -26127,255 +26400,13 @@ function InboxModal({ onDone, onOpen }) {
|
|
|
26127
26400
|
] })
|
|
26128
26401
|
] });
|
|
26129
26402
|
}
|
|
26130
|
-
var
|
|
26403
|
+
var FEEDBACK_WORKER_URL2;
|
|
26131
26404
|
var init_inbox_modal = __esm({
|
|
26132
26405
|
"src/ui/inbox-modal.tsx"() {
|
|
26133
26406
|
"use strict";
|
|
26134
26407
|
init_text_input();
|
|
26135
26408
|
init_theme_context();
|
|
26136
|
-
FEEDBACK_WORKER_URL = "https://hello.kimiflare.com";
|
|
26137
|
-
}
|
|
26138
|
-
});
|
|
26139
|
-
|
|
26140
|
-
// src/ui/app-helpers.ts
|
|
26141
|
-
import { execSync as execSync5, spawn as spawn7 } from "child_process";
|
|
26142
|
-
import { existsSync as existsSync5, readFileSync as readFileSync4, statSync as statSync5 } from "fs";
|
|
26143
|
-
import { join as join30 } from "path";
|
|
26144
|
-
import { platform as platform6 } from "os";
|
|
26145
|
-
function buildFilePickerIgnoreList(cwd) {
|
|
26146
|
-
const hardcoded = [
|
|
26147
|
-
// Dependencies
|
|
26148
|
-
"**/node_modules/**",
|
|
26149
|
-
"**/vendor/**",
|
|
26150
|
-
"**/.bundle/**",
|
|
26151
|
-
"**/bower_components/**",
|
|
26152
|
-
// Version control
|
|
26153
|
-
"**/.git/**",
|
|
26154
|
-
"**/.svn/**",
|
|
26155
|
-
"**/.hg/**",
|
|
26156
|
-
// Build / output directories
|
|
26157
|
-
"**/dist/**",
|
|
26158
|
-
"**/build/**",
|
|
26159
|
-
"**/out/**",
|
|
26160
|
-
"**/public/**",
|
|
26161
|
-
"**/.next/**",
|
|
26162
|
-
"**/.nuxt/**",
|
|
26163
|
-
"**/.svelte-kit/**",
|
|
26164
|
-
"**/.vercel/**",
|
|
26165
|
-
"**/.netlify/**",
|
|
26166
|
-
"**/target/**",
|
|
26167
|
-
"**/bin/**",
|
|
26168
|
-
"**/obj/**",
|
|
26169
|
-
"**/Debug/**",
|
|
26170
|
-
"**/Release/**",
|
|
26171
|
-
"**/.gradle/**",
|
|
26172
|
-
// Caches
|
|
26173
|
-
"**/.cache/**",
|
|
26174
|
-
"**/.parcel-cache/**",
|
|
26175
|
-
"**/.turbo/**",
|
|
26176
|
-
"**/.eslintcache",
|
|
26177
|
-
"**/.stylelintcache",
|
|
26178
|
-
"**/.rpt2_cache/**",
|
|
26179
|
-
"**/.rts2_cache/**",
|
|
26180
|
-
// Temporary
|
|
26181
|
-
"**/tmp/**",
|
|
26182
|
-
"**/temp/**",
|
|
26183
|
-
"**/*.tmp",
|
|
26184
|
-
// Coverage
|
|
26185
|
-
"**/coverage/**",
|
|
26186
|
-
"**/.nyc_output/**",
|
|
26187
|
-
// OS files
|
|
26188
|
-
"**/.DS_Store",
|
|
26189
|
-
"**/Thumbs.db",
|
|
26190
|
-
// Logs
|
|
26191
|
-
"**/*.log",
|
|
26192
|
-
"**/logs/**",
|
|
26193
|
-
// Lock files (auto-generated, usually huge)
|
|
26194
|
-
"**/package-lock.json",
|
|
26195
|
-
"**/yarn.lock",
|
|
26196
|
-
"**/pnpm-lock.yaml",
|
|
26197
|
-
"**/bun.lockb",
|
|
26198
|
-
"**/Cargo.lock",
|
|
26199
|
-
"**/Gemfile.lock",
|
|
26200
|
-
"**/composer.lock",
|
|
26201
|
-
"**/Pipfile.lock",
|
|
26202
|
-
"**/poetry.lock",
|
|
26203
|
-
"**/go.sum",
|
|
26204
|
-
// Minified / source maps
|
|
26205
|
-
"**/*.min.js",
|
|
26206
|
-
"**/*.min.css",
|
|
26207
|
-
"**/*.map",
|
|
26208
|
-
// kimiflare internal
|
|
26209
|
-
"**/.kimiflare/**",
|
|
26210
|
-
// IDE (usually not relevant to mention)
|
|
26211
|
-
"**/.idea/**"
|
|
26212
|
-
];
|
|
26213
|
-
const gitignorePatterns = [];
|
|
26214
|
-
try {
|
|
26215
|
-
const gitignorePath = join30(cwd, ".gitignore");
|
|
26216
|
-
const stats = statSync5(gitignorePath);
|
|
26217
|
-
if (stats.size > MAX_GITIGNORE_SIZE) {
|
|
26218
|
-
return hardcoded;
|
|
26219
|
-
}
|
|
26220
|
-
const content = readFileSync4(gitignorePath, "utf-8");
|
|
26221
|
-
for (const line of content.split(/\r?\n/)) {
|
|
26222
|
-
const trimmed = line.trim();
|
|
26223
|
-
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
26224
|
-
if (trimmed.startsWith("!")) continue;
|
|
26225
|
-
let pattern = trimmed;
|
|
26226
|
-
const isAnchored = pattern.startsWith("/");
|
|
26227
|
-
const isDir = pattern.endsWith("/");
|
|
26228
|
-
if (isAnchored) pattern = pattern.slice(1);
|
|
26229
|
-
if (isDir) pattern = pattern.slice(0, -1);
|
|
26230
|
-
if (!pattern) continue;
|
|
26231
|
-
if (isAnchored) {
|
|
26232
|
-
gitignorePatterns.push(isDir ? pattern + "/**" : pattern);
|
|
26233
|
-
} else {
|
|
26234
|
-
gitignorePatterns.push(isDir ? "**/" + pattern + "/**" : "**/" + pattern);
|
|
26235
|
-
}
|
|
26236
|
-
}
|
|
26237
|
-
} catch {
|
|
26238
|
-
}
|
|
26239
|
-
return [...hardcoded, ...gitignorePatterns];
|
|
26240
|
-
}
|
|
26241
|
-
function gatewayFromConfig(cfg) {
|
|
26242
|
-
if (process.env.KIMIFLARE_DISABLE_AI_GATEWAY === "1") return void 0;
|
|
26243
|
-
if (!cfg.aiGatewayId) return void 0;
|
|
26244
|
-
return {
|
|
26245
|
-
id: cfg.aiGatewayId,
|
|
26246
|
-
cacheTtl: cfg.aiGatewayCacheTtl,
|
|
26247
|
-
skipCache: cfg.aiGatewaySkipCache,
|
|
26248
|
-
collectLogPayload: cfg.aiGatewayCollectLogPayload,
|
|
26249
|
-
metadata: cfg.aiGatewayMetadata
|
|
26250
|
-
};
|
|
26251
|
-
}
|
|
26252
|
-
function gatewayUsageLookupFromConfig(cfg, meta) {
|
|
26253
|
-
if (process.env.KIMIFLARE_DISABLE_AI_GATEWAY === "1") return void 0;
|
|
26254
|
-
if (!cfg.aiGatewayId || !meta) return void 0;
|
|
26255
|
-
return {
|
|
26256
|
-
accountId: cfg.accountId,
|
|
26257
|
-
apiToken: cfg.apiToken,
|
|
26258
|
-
gatewayId: cfg.aiGatewayId,
|
|
26259
|
-
meta
|
|
26260
|
-
};
|
|
26261
|
-
}
|
|
26262
|
-
function openBrowser2(url) {
|
|
26263
|
-
const cmd = platform6() === "darwin" ? "open" : platform6() === "win32" ? "start" : "xdg-open";
|
|
26264
|
-
const child = spawn7(cmd, [url], { detached: true, stdio: "ignore" });
|
|
26265
|
-
child.unref();
|
|
26266
|
-
}
|
|
26267
|
-
function detectGitHubRepo(cachedRepo) {
|
|
26268
|
-
if (cachedRepo) {
|
|
26269
|
-
const parts = cachedRepo.split("/");
|
|
26270
|
-
if (parts.length === 2) return { owner: parts[0], name: parts[1] };
|
|
26271
|
-
}
|
|
26272
|
-
try {
|
|
26273
|
-
const remoteUrl = execSync5("git remote get-url origin", { cwd: process.cwd(), encoding: "utf8" }).trim();
|
|
26274
|
-
const httpsMatch = remoteUrl.match(/github\.com\/([^\/]+)\/([^\/]+?)(?:\.git)?$/);
|
|
26275
|
-
if (httpsMatch) return { owner: httpsMatch[1], name: httpsMatch[2] };
|
|
26276
|
-
const sshMatch = remoteUrl.match(/github\.com:([^\/]+)\/([^\/]+?)(?:\.git)?$/);
|
|
26277
|
-
if (sshMatch) return { owner: sshMatch[1], name: sshMatch[2] };
|
|
26278
|
-
} catch {
|
|
26279
|
-
}
|
|
26280
|
-
return null;
|
|
26281
|
-
}
|
|
26282
|
-
function detectGitBranch() {
|
|
26283
|
-
try {
|
|
26284
|
-
return execSync5("git branch --show-current", { cwd: process.cwd(), encoding: "utf8" }).trim() || null;
|
|
26285
|
-
} catch {
|
|
26286
|
-
return null;
|
|
26287
|
-
}
|
|
26288
|
-
}
|
|
26289
|
-
function formatTokens3(n) {
|
|
26290
|
-
if (n >= 1e6) return `${(n / 1e6).toFixed(1)}M`;
|
|
26291
|
-
if (n >= 1e3) return `${(n / 1e3).toFixed(1)}K`;
|
|
26292
|
-
return String(n);
|
|
26293
|
-
}
|
|
26294
|
-
function trackRecentFile(ref, path, max = 10) {
|
|
26295
|
-
ref.current.set(path, Date.now());
|
|
26296
|
-
if (ref.current.size > max) {
|
|
26297
|
-
let oldest = null;
|
|
26298
|
-
let oldestTime = Infinity;
|
|
26299
|
-
for (const [p, t] of ref.current) {
|
|
26300
|
-
if (t < oldestTime) {
|
|
26301
|
-
oldestTime = t;
|
|
26302
|
-
oldest = p;
|
|
26303
|
-
}
|
|
26304
|
-
}
|
|
26305
|
-
if (oldest) ref.current.delete(oldest);
|
|
26306
|
-
}
|
|
26307
|
-
}
|
|
26308
|
-
function capEvents(prev) {
|
|
26309
|
-
if (prev.length <= MAX_EVENTS) return prev;
|
|
26310
|
-
return prev.slice(prev.length - MAX_EVENTS);
|
|
26311
|
-
}
|
|
26312
|
-
function compactEventsVisual(prev, keepLastTurns) {
|
|
26313
|
-
let seen = 0;
|
|
26314
|
-
let cutoff = -1;
|
|
26315
|
-
for (let i = prev.length - 1; i >= 0; i--) {
|
|
26316
|
-
if (prev[i].kind === "user") {
|
|
26317
|
-
seen++;
|
|
26318
|
-
if (seen === keepLastTurns + 1) {
|
|
26319
|
-
cutoff = i;
|
|
26320
|
-
break;
|
|
26321
|
-
}
|
|
26322
|
-
}
|
|
26323
|
-
}
|
|
26324
|
-
if (cutoff <= 0) return prev;
|
|
26325
|
-
const kept = prev.slice(cutoff);
|
|
26326
|
-
return [
|
|
26327
|
-
{ kind: "info", key: mkKey(), text: `\xB7\xB7\xB7 ${cutoff} earlier messages compacted \xB7\xB7\xB7` },
|
|
26328
|
-
...kept
|
|
26329
|
-
];
|
|
26330
|
-
}
|
|
26331
|
-
function makePrefixMessages(cacheStable, model, mode, tools) {
|
|
26332
|
-
if (cacheStable) {
|
|
26333
|
-
return buildSystemMessages({ cwd: process.cwd(), tools, model, mode });
|
|
26334
|
-
}
|
|
26335
|
-
return [
|
|
26336
|
-
{
|
|
26337
|
-
role: "system",
|
|
26338
|
-
content: buildSystemPrompt({ cwd: process.cwd(), tools, model, mode })
|
|
26339
|
-
}
|
|
26340
|
-
];
|
|
26341
|
-
}
|
|
26342
|
-
function findImagePaths(text) {
|
|
26343
|
-
const paths = [];
|
|
26344
|
-
const quotedRegex = /"([^"]+)"|'([^']+)'/g;
|
|
26345
|
-
let match;
|
|
26346
|
-
while ((match = quotedRegex.exec(text)) !== null) {
|
|
26347
|
-
const path = match[1] ?? match[2];
|
|
26348
|
-
if (path && isImagePath(path) && existsSync5(path)) {
|
|
26349
|
-
paths.push(path);
|
|
26350
|
-
}
|
|
26351
|
-
}
|
|
26352
|
-
const remaining = text.replace(/"[^"]+"|'[^']+'/g, "");
|
|
26353
|
-
const ESCAPED_SPACE = "\0";
|
|
26354
|
-
const processed = remaining.replace(/\\ /g, ESCAPED_SPACE);
|
|
26355
|
-
for (const token of processed.split(/\s+/)) {
|
|
26356
|
-
const clean = token.replace(new RegExp(ESCAPED_SPACE, "g"), " ").replace(/^["']|["',;:!?]$/g, "").replace(/[.,;:!?]$/, "");
|
|
26357
|
-
if (clean && isImagePath(clean) && existsSync5(clean) && !paths.includes(clean)) {
|
|
26358
|
-
paths.push(clean);
|
|
26359
|
-
}
|
|
26360
|
-
}
|
|
26361
|
-
return paths;
|
|
26362
|
-
}
|
|
26363
|
-
var MAX_GITIGNORE_SIZE, CONTEXT_LIMIT, AUTO_COMPACT_THRESHOLD, MAX_EVENTS, MAX_IMAGES_PER_MESSAGE, FEEDBACK_WORKER_URL2, nextKey, mkKey, nextAssistantId, mkAssistantId;
|
|
26364
|
-
var init_app_helpers = __esm({
|
|
26365
|
-
"src/ui/app-helpers.ts"() {
|
|
26366
|
-
"use strict";
|
|
26367
|
-
init_system_prompt();
|
|
26368
|
-
init_image();
|
|
26369
|
-
MAX_GITIGNORE_SIZE = 1 * 1024 * 1024;
|
|
26370
|
-
CONTEXT_LIMIT = 262e3;
|
|
26371
|
-
AUTO_COMPACT_THRESHOLD = 0.8;
|
|
26372
|
-
MAX_EVENTS = 500;
|
|
26373
|
-
MAX_IMAGES_PER_MESSAGE = 10;
|
|
26374
26409
|
FEEDBACK_WORKER_URL2 = "https://hello.kimiflare.com";
|
|
26375
|
-
nextKey = 1;
|
|
26376
|
-
mkKey = () => `evt_${nextKey++}`;
|
|
26377
|
-
nextAssistantId = 1;
|
|
26378
|
-
mkAssistantId = () => nextAssistantId++;
|
|
26379
26410
|
}
|
|
26380
26411
|
});
|
|
26381
26412
|
|
|
@@ -26556,7 +26587,7 @@ function MultiAgentModal({ initial, onSave, onDone, remoteWorkerUrl, remoteAuthS
|
|
|
26556
26587
|
if (deployFailed) {
|
|
26557
26588
|
if (input === "o" || input === "O") {
|
|
26558
26589
|
const url = deployLog.map((l) => l.match(/https:\/\/dash\.cloudflare\.com\/[^\s)]+/)?.[0]).find((u) => !!u) ?? "https://dash.cloudflare.com/profile/api-tokens";
|
|
26559
|
-
|
|
26590
|
+
openBrowser(url);
|
|
26560
26591
|
return;
|
|
26561
26592
|
}
|
|
26562
26593
|
if (input === "r" || input === "R") {
|
|
@@ -28465,6 +28496,13 @@ function executeFreshStart(ctx, planText) {
|
|
|
28465
28496
|
ctx.compactSuggestedRef.current = false;
|
|
28466
28497
|
ctx.updateNudgedRef.current = false;
|
|
28467
28498
|
ctx.sessionPlanRef.current = null;
|
|
28499
|
+
rebuildSystemPromptForMode(
|
|
28500
|
+
ctx.messagesRef.current,
|
|
28501
|
+
ctx.cacheStableRef.current,
|
|
28502
|
+
ctx.cfg?.model ?? "@cf/moonshotai/kimi-k2.6",
|
|
28503
|
+
ctx.mode,
|
|
28504
|
+
[...ALL_TOOLS, ...ctx.mcpToolsRef.current, ...ctx.lspToolsRef.current]
|
|
28505
|
+
);
|
|
28468
28506
|
ctx.messagesRef.current.push({ role: "user", content: planText });
|
|
28469
28507
|
const newSessionId = ctx.ensureSessionId();
|
|
28470
28508
|
if (oldSessionId) {
|
|
@@ -28497,6 +28535,7 @@ var init_slash_commands = __esm({
|
|
|
28497
28535
|
init_manager4();
|
|
28498
28536
|
init_sessions();
|
|
28499
28537
|
init_session_state();
|
|
28538
|
+
init_executor();
|
|
28500
28539
|
init_recommended();
|
|
28501
28540
|
init_settings();
|
|
28502
28541
|
init_types2();
|
|
@@ -29555,8 +29594,8 @@ project: ${projectSettingsPath(cwd)}`
|
|
|
29555
29594
|
handleHello = (ctx) => {
|
|
29556
29595
|
const { setEvents, mkKey: mkKey2 } = ctx;
|
|
29557
29596
|
const session = crypto.randomUUID();
|
|
29558
|
-
const url = `${
|
|
29559
|
-
|
|
29597
|
+
const url = `${FEEDBACK_WORKER_URL}/?s=${session}&v=${getAppVersion()}`;
|
|
29598
|
+
openBrowser(url);
|
|
29560
29599
|
void (async () => {
|
|
29561
29600
|
try {
|
|
29562
29601
|
const qr = await QRCode.toString(url, { type: "terminal", small: true });
|
|
@@ -29709,7 +29748,7 @@ project: ${projectSettingsPath(cwd)}`
|
|
|
29709
29748
|
setEvents((e) => [
|
|
29710
29749
|
...e,
|
|
29711
29750
|
{ kind: "info", key: mkKey2(), text: `Starting remote session for ${repo.owner}/${repo.name}...` },
|
|
29712
|
-
{ kind: "info", key: mkKey2(), text: `Budget: ${
|
|
29751
|
+
{ kind: "info", key: mkKey2(), text: `Budget: ${formatTokens(budget)} tokens. TTL: ${ttl} min.` }
|
|
29713
29752
|
]);
|
|
29714
29753
|
try {
|
|
29715
29754
|
const data = await startRemoteSession({
|
|
@@ -31946,6 +31985,13 @@ ${wcagWarnings.join("\n")}` }
|
|
|
31946
31985
|
}
|
|
31947
31986
|
setMode(picked);
|
|
31948
31987
|
modeRef.current = picked;
|
|
31988
|
+
rebuildSystemPromptForMode(
|
|
31989
|
+
messagesRef.current,
|
|
31990
|
+
cacheStableRef.current,
|
|
31991
|
+
cfg?.model ?? DEFAULT_MODEL,
|
|
31992
|
+
picked,
|
|
31993
|
+
[...ALL_TOOLS, ...mcpToolsRef.current, ...lspToolsRef.current]
|
|
31994
|
+
);
|
|
31949
31995
|
submitRef.current(plan);
|
|
31950
31996
|
},
|
|
31951
31997
|
[mkKey, setShowPlanCompletePicker, setMode, setEvents, setUsage, setSessionUsage, setGatewayMeta, clearTaskTracking, resetSession, submitRef]
|
|
@@ -33018,7 +33064,7 @@ ${conflicts.join("\n")}` }
|
|
|
33018
33064
|
selectedRemoteSession,
|
|
33019
33065
|
onSelectRemoteSession: setSelectedRemoteSession,
|
|
33020
33066
|
onCancelRemoteSession: handleRemoteCancel2,
|
|
33021
|
-
onInboxOpen:
|
|
33067
|
+
onInboxOpen: openBrowser,
|
|
33022
33068
|
multiAgentSettings: cfg ? {
|
|
33023
33069
|
multiAgentEnabled: cfg.multiAgentEnabled,
|
|
33024
33070
|
workerEndpoint: cfg.workerEndpoint,
|