@yhong91/vibetime 0.1.51 → 0.1.52
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/bin/vibetime.mjs +660 -192
- package/package.json +1 -1
package/bin/vibetime.mjs
CHANGED
|
@@ -886,7 +886,7 @@ var init_esm = __esm({
|
|
|
886
886
|
import { spawn as spawn2, spawnSync } from "node:child_process";
|
|
887
887
|
import { mkdir as mkdir5, open, rm, stat as stat13, writeFile as writeFile4 } from "node:fs/promises";
|
|
888
888
|
import os11 from "node:os";
|
|
889
|
-
import
|
|
889
|
+
import path25 from "node:path";
|
|
890
890
|
import { fileURLToPath } from "node:url";
|
|
891
891
|
|
|
892
892
|
// ../shared/src/index.ts
|
|
@@ -924,7 +924,7 @@ var TELEMETRY_EVENT_TYPES = [
|
|
|
924
924
|
"agent.operation"
|
|
925
925
|
];
|
|
926
926
|
var FILE_ACTIVITY_OPERATIONS = ["read", "search", "create", "write", "edit", "delete"];
|
|
927
|
-
var BACKFILL_SOURCE_IDS = ["codex", "claude-code", "claude-cowork", "copilot", "opencode", "pi", "agy", "codebuddy", "qoder", "qoder-cn", "workbuddy", "zcode", "grok-build", "zed"];
|
|
927
|
+
var BACKFILL_SOURCE_IDS = ["codex", "claude-code", "claude-cowork", "copilot", "opencode", "pi", "agy", "codebuddy", "qoder", "qoder-cn", "workbuddy", "zcode", "grok-build", "zed", "kimi-code"];
|
|
928
928
|
function createWorkspaceId(input) {
|
|
929
929
|
const basis = input.repoUrl || input.repoRoot || input.projectName || "unknown";
|
|
930
930
|
return `workspace_${fnv1a(basis)}`;
|
|
@@ -2047,7 +2047,7 @@ function claudeStyleFileMetrics(tool, input) {
|
|
|
2047
2047
|
}
|
|
2048
2048
|
|
|
2049
2049
|
// src/lib/constants.ts
|
|
2050
|
-
var PACKAGE_VERSION = true ? "0.1.
|
|
2050
|
+
var PACKAGE_VERSION = true ? "0.1.52" : "0.1.1";
|
|
2051
2051
|
var DEFAULT_API_URL = "http://121.196.224.82:3001";
|
|
2052
2052
|
var DEFAULT_BACKFILL_BATCH_SIZE = 50;
|
|
2053
2053
|
var DEFAULT_BACKFILL_BATCH_BYTES = 800 * 1024;
|
|
@@ -6935,9 +6935,476 @@ function createGrokBuildAdapter() {
|
|
|
6935
6935
|
};
|
|
6936
6936
|
}
|
|
6937
6937
|
|
|
6938
|
+
// src/adapters/kimi-code.ts
|
|
6939
|
+
import { readFile as readFile9 } from "node:fs/promises";
|
|
6940
|
+
import path14 from "node:path";
|
|
6941
|
+
function kimiCodeHome(home, env) {
|
|
6942
|
+
const override = env?.KIMI_CODE_HOME || env?.KIMI_HOME;
|
|
6943
|
+
if (override && override.trim()) {
|
|
6944
|
+
return path14.resolve(override);
|
|
6945
|
+
}
|
|
6946
|
+
return path14.join(home, ".kimi-code");
|
|
6947
|
+
}
|
|
6948
|
+
function kimiCodeSessionsDir(home, env) {
|
|
6949
|
+
return path14.join(kimiCodeHome(home, env), "sessions");
|
|
6950
|
+
}
|
|
6951
|
+
function baseKimiEvent(event) {
|
|
6952
|
+
return {
|
|
6953
|
+
schemaVersion: AGENT_TIME_SCHEMA_VERSION,
|
|
6954
|
+
source: "kimi-code",
|
|
6955
|
+
agent: "kimi-code",
|
|
6956
|
+
workspaceId: createWorkspaceId({ projectName: event.project, repoRoot: event.cwd }),
|
|
6957
|
+
...event
|
|
6958
|
+
};
|
|
6959
|
+
}
|
|
6960
|
+
function extractTextParts(input) {
|
|
6961
|
+
if (typeof input === "string") {
|
|
6962
|
+
return input;
|
|
6963
|
+
}
|
|
6964
|
+
if (!Array.isArray(input)) {
|
|
6965
|
+
return "";
|
|
6966
|
+
}
|
|
6967
|
+
return input.filter((item) => isPlainObject(item) && item.type === "text").map((item) => stringField(item, "text") || "").join("");
|
|
6968
|
+
}
|
|
6969
|
+
function kimiUsageFromRecord(usage) {
|
|
6970
|
+
const inputOther = numberField(usage, "inputOther") || 0;
|
|
6971
|
+
const output = numberField(usage, "output") || 0;
|
|
6972
|
+
const cacheRead = numberField(usage, "inputCacheRead") || 0;
|
|
6973
|
+
const cacheWrite = numberField(usage, "inputCacheCreation") || 0;
|
|
6974
|
+
const inputTokens = numberField(usage, "input_tokens") || numberField(usage, "input") || 0;
|
|
6975
|
+
const outputTokens = numberField(usage, "output_tokens") || 0;
|
|
6976
|
+
const nonCached = inputOther || inputTokens;
|
|
6977
|
+
const out = output || outputTokens;
|
|
6978
|
+
const total = nonCached + out + cacheRead + cacheWrite;
|
|
6979
|
+
if (total <= 0) {
|
|
6980
|
+
return void 0;
|
|
6981
|
+
}
|
|
6982
|
+
return {
|
|
6983
|
+
tokensInput: nonCached + cacheRead + cacheWrite || void 0,
|
|
6984
|
+
tokensOutput: out || void 0,
|
|
6985
|
+
tokensCacheReadInput: cacheRead || void 0,
|
|
6986
|
+
tokensCacheCreationInput: cacheWrite || void 0,
|
|
6987
|
+
tokensCachedInput: cacheRead + cacheWrite || void 0,
|
|
6988
|
+
tokensTotal: total,
|
|
6989
|
+
modelCalls: 1
|
|
6990
|
+
};
|
|
6991
|
+
}
|
|
6992
|
+
function normalizeTurnId(raw) {
|
|
6993
|
+
if (typeof raw === "number" && Number.isFinite(raw)) {
|
|
6994
|
+
return `turn_${raw}`;
|
|
6995
|
+
}
|
|
6996
|
+
if (typeof raw === "string" && raw.trim()) {
|
|
6997
|
+
return raw.startsWith("turn_") ? raw : `turn_${raw}`;
|
|
6998
|
+
}
|
|
6999
|
+
return void 0;
|
|
7000
|
+
}
|
|
7001
|
+
function sessionIdFromWirePath(filePath) {
|
|
7002
|
+
const normalized = filePath.replaceAll("\\", "/");
|
|
7003
|
+
const match = normalized.match(/\/(session_[^/]+)\/agents\/[^/]+\/wire\.jsonl$/);
|
|
7004
|
+
return match?.[1];
|
|
7005
|
+
}
|
|
7006
|
+
async function readSessionState(filePath) {
|
|
7007
|
+
const sessionDir = path14.dirname(path14.dirname(path14.dirname(filePath)));
|
|
7008
|
+
const statePath = path14.join(sessionDir, "state.json");
|
|
7009
|
+
try {
|
|
7010
|
+
const text = await readFile9(statePath, "utf8");
|
|
7011
|
+
const raw = JSON.parse(text);
|
|
7012
|
+
if (!isPlainObject(raw)) {
|
|
7013
|
+
return {};
|
|
7014
|
+
}
|
|
7015
|
+
return {
|
|
7016
|
+
sessionId: stringField(raw, "id"),
|
|
7017
|
+
cwd: stringField(raw, "cwd"),
|
|
7018
|
+
title: stringField(raw, "title")
|
|
7019
|
+
};
|
|
7020
|
+
} catch {
|
|
7021
|
+
return {};
|
|
7022
|
+
}
|
|
7023
|
+
}
|
|
7024
|
+
async function parseKimiCodeSessionFile(filePath, options) {
|
|
7025
|
+
if (path14.basename(filePath) !== "wire.jsonl") {
|
|
7026
|
+
return [];
|
|
7027
|
+
}
|
|
7028
|
+
const text = await readFile9(filePath, "utf8");
|
|
7029
|
+
const lines = text.split("\n").filter(Boolean);
|
|
7030
|
+
const stateMeta = await readSessionState(filePath);
|
|
7031
|
+
let sessionId = stateMeta.sessionId || sessionIdFromWirePath(filePath);
|
|
7032
|
+
let cwd = stateMeta.cwd;
|
|
7033
|
+
let project = cwd ? path14.basename(cwd) : void 0;
|
|
7034
|
+
let model;
|
|
7035
|
+
let provider;
|
|
7036
|
+
let reasoningEffort;
|
|
7037
|
+
const pendingToolCalls = /* @__PURE__ */ new Map();
|
|
7038
|
+
const pendingPermissions = /* @__PURE__ */ new Map();
|
|
7039
|
+
let sawUsageRecord = false;
|
|
7040
|
+
const state = new SessionParserState(filePath, options, (event) => baseKimiEvent({ ...event, cwd, project, model, provider }));
|
|
7041
|
+
if (sessionId) {
|
|
7042
|
+
state.sessionId = sessionId;
|
|
7043
|
+
}
|
|
7044
|
+
const push = (event, ln, topType) => {
|
|
7045
|
+
state.push(
|
|
7046
|
+
{
|
|
7047
|
+
...event,
|
|
7048
|
+
sessionId: event.sessionId || sessionId,
|
|
7049
|
+
workspaceId: event.workspaceId || createWorkspaceId({ projectName: project, repoRoot: cwd })
|
|
7050
|
+
},
|
|
7051
|
+
ln,
|
|
7052
|
+
topType || event.type,
|
|
7053
|
+
event.type
|
|
7054
|
+
);
|
|
7055
|
+
};
|
|
7056
|
+
for (const [index, line] of lines.entries()) {
|
|
7057
|
+
const lineNumber = index + 1;
|
|
7058
|
+
const raw = parseJsonLine(line);
|
|
7059
|
+
if (!raw) {
|
|
7060
|
+
continue;
|
|
7061
|
+
}
|
|
7062
|
+
const entryType = stringField(raw, "type");
|
|
7063
|
+
const ts = timestampFrom(raw.time) || timestampFrom(raw.created_at) || timestampFrom(raw.timestamp);
|
|
7064
|
+
if (!ts || !entryType) {
|
|
7065
|
+
continue;
|
|
7066
|
+
}
|
|
7067
|
+
if (entryType === "metadata") {
|
|
7068
|
+
state.ensureSessionStarted(ts, lineNumber, entryType);
|
|
7069
|
+
continue;
|
|
7070
|
+
}
|
|
7071
|
+
if (entryType === "profile.bind") {
|
|
7072
|
+
state.ensureSessionStarted(ts, lineNumber, entryType);
|
|
7073
|
+
model = stringField(raw, "modelAlias") || stringField(raw, "model") || model;
|
|
7074
|
+
reasoningEffort = stringField(raw, "thinkingEffort") || reasoningEffort;
|
|
7075
|
+
const disclosure = objectField(raw, "environmentDisclosure");
|
|
7076
|
+
const disclosedCwd = stringField(disclosure, "cwd");
|
|
7077
|
+
if (disclosedCwd) {
|
|
7078
|
+
cwd = disclosedCwd;
|
|
7079
|
+
project = path14.basename(disclosedCwd);
|
|
7080
|
+
}
|
|
7081
|
+
continue;
|
|
7082
|
+
}
|
|
7083
|
+
if (entryType === "turn.prompt") {
|
|
7084
|
+
state.ensureSessionStarted(ts, lineNumber, entryType);
|
|
7085
|
+
if (isTurnIdle(state.currentTurnLastEventAt) || state.currentTurnId) {
|
|
7086
|
+
state.closeTurn(ts, lineNumber, entryType);
|
|
7087
|
+
}
|
|
7088
|
+
const nextOrdinal = state.currentTurnId ? Number.parseInt(state.currentTurnId.replace(/^turn_/, ""), 10) : Number.NaN;
|
|
7089
|
+
const turnOrdinal = Number.isFinite(nextOrdinal) ? nextOrdinal + 1 : 0;
|
|
7090
|
+
const turnId = `turn_${turnOrdinal}`;
|
|
7091
|
+
state.startTurn(turnId, ts);
|
|
7092
|
+
push(baseKimiEvent({
|
|
7093
|
+
ts,
|
|
7094
|
+
type: "turn.started",
|
|
7095
|
+
sessionId,
|
|
7096
|
+
turnId,
|
|
7097
|
+
cwd,
|
|
7098
|
+
project,
|
|
7099
|
+
model,
|
|
7100
|
+
provider,
|
|
7101
|
+
confidence: "exact"
|
|
7102
|
+
}), lineNumber, entryType);
|
|
7103
|
+
const promptText = extractTextParts(raw.input);
|
|
7104
|
+
push(baseKimiEvent({
|
|
7105
|
+
ts,
|
|
7106
|
+
type: "prompt.submitted",
|
|
7107
|
+
sessionId,
|
|
7108
|
+
turnId,
|
|
7109
|
+
cwd,
|
|
7110
|
+
project,
|
|
7111
|
+
model,
|
|
7112
|
+
provider,
|
|
7113
|
+
confidence: "exact",
|
|
7114
|
+
metrics: {
|
|
7115
|
+
prompts: 1,
|
|
7116
|
+
promptChars: promptText.length || void 0
|
|
7117
|
+
},
|
|
7118
|
+
refs: stringRefs({
|
|
7119
|
+
promptHash: promptText ? `sha256:${createStableHash(promptText)}` : void 0
|
|
7120
|
+
})
|
|
7121
|
+
}), lineNumber, entryType);
|
|
7122
|
+
continue;
|
|
7123
|
+
}
|
|
7124
|
+
if (entryType === "llm.request") {
|
|
7125
|
+
state.ensureSessionStarted(ts, lineNumber, entryType);
|
|
7126
|
+
model = stringField(raw, "modelAlias") || stringField(raw, "model") || model;
|
|
7127
|
+
provider = stringField(raw, "provider") || provider;
|
|
7128
|
+
reasoningEffort = stringField(raw, "thinkingEffort") || reasoningEffort;
|
|
7129
|
+
const turnStep = stringField(raw, "turnStep");
|
|
7130
|
+
if (turnStep && !state.currentTurnId) {
|
|
7131
|
+
const turnPart = turnStep.split(".")[0];
|
|
7132
|
+
const turnId = normalizeTurnId(turnPart);
|
|
7133
|
+
if (turnId) {
|
|
7134
|
+
state.startTurn(turnId, ts);
|
|
7135
|
+
}
|
|
7136
|
+
}
|
|
7137
|
+
continue;
|
|
7138
|
+
}
|
|
7139
|
+
if (entryType === "usage.record") {
|
|
7140
|
+
state.ensureSessionStarted(ts, lineNumber, entryType);
|
|
7141
|
+
sawUsageRecord = true;
|
|
7142
|
+
model = stringField(raw, "model") || model;
|
|
7143
|
+
const usage = objectField(raw, "usage");
|
|
7144
|
+
const metrics = kimiUsageFromRecord(usage);
|
|
7145
|
+
if (metrics) {
|
|
7146
|
+
if (reasoningEffort) {
|
|
7147
|
+
metrics.reasoningEffort = reasoningEffort;
|
|
7148
|
+
}
|
|
7149
|
+
push(baseKimiEvent({
|
|
7150
|
+
ts,
|
|
7151
|
+
type: "model.usage",
|
|
7152
|
+
sessionId,
|
|
7153
|
+
turnId: state.currentTurnId,
|
|
7154
|
+
cwd,
|
|
7155
|
+
project,
|
|
7156
|
+
model,
|
|
7157
|
+
provider,
|
|
7158
|
+
confidence: "exact",
|
|
7159
|
+
metrics
|
|
7160
|
+
}), lineNumber, entryType);
|
|
7161
|
+
}
|
|
7162
|
+
continue;
|
|
7163
|
+
}
|
|
7164
|
+
if (entryType === "context.append_loop_event") {
|
|
7165
|
+
state.ensureSessionStarted(ts, lineNumber, entryType);
|
|
7166
|
+
const loopEvent = objectField(raw, "event");
|
|
7167
|
+
const loopType = stringField(loopEvent, "type");
|
|
7168
|
+
const turnId = normalizeTurnId(loopEvent.turnId) || state.currentTurnId;
|
|
7169
|
+
if (turnId && turnId !== state.currentTurnId) {
|
|
7170
|
+
if (state.currentTurnId) {
|
|
7171
|
+
state.closeTurn(ts, lineNumber, entryType);
|
|
7172
|
+
}
|
|
7173
|
+
state.startTurn(turnId, ts);
|
|
7174
|
+
}
|
|
7175
|
+
if (loopType === "tool.call") {
|
|
7176
|
+
const toolCallId = stringField(loopEvent, "toolCallId") || stringField(loopEvent, "uuid");
|
|
7177
|
+
const toolName = stringField(loopEvent, "name") || "tool";
|
|
7178
|
+
const toolInput = isPlainObject(loopEvent.args) ? loopEvent.args : {};
|
|
7179
|
+
if (toolCallId) {
|
|
7180
|
+
pendingToolCalls.set(toolCallId, {
|
|
7181
|
+
toolName,
|
|
7182
|
+
startedAt: ts,
|
|
7183
|
+
turnId: turnId || state.currentTurnId,
|
|
7184
|
+
input: toolInput
|
|
7185
|
+
});
|
|
7186
|
+
}
|
|
7187
|
+
push(baseKimiEvent({
|
|
7188
|
+
ts,
|
|
7189
|
+
type: "tool.started",
|
|
7190
|
+
operation: `${toolName} started`,
|
|
7191
|
+
sessionId,
|
|
7192
|
+
turnId: turnId || state.currentTurnId,
|
|
7193
|
+
cwd,
|
|
7194
|
+
project,
|
|
7195
|
+
model,
|
|
7196
|
+
provider,
|
|
7197
|
+
tool: toolName,
|
|
7198
|
+
confidence: "exact",
|
|
7199
|
+
metrics: { toolCalls: 1 },
|
|
7200
|
+
refs: stringRefs({
|
|
7201
|
+
sourceId: toolCallId,
|
|
7202
|
+
commandHash: toolName.toLowerCase() === "bash" && stringField(toolInput, "command") ? createStableHash(stringField(toolInput, "command")) : void 0
|
|
7203
|
+
})
|
|
7204
|
+
}), lineNumber, entryType);
|
|
7205
|
+
const fileActivities = claudeStyleToolFileActivities(
|
|
7206
|
+
toolName,
|
|
7207
|
+
toolInput,
|
|
7208
|
+
ts,
|
|
7209
|
+
cwd
|
|
7210
|
+
);
|
|
7211
|
+
if (fileActivities.length > 0) {
|
|
7212
|
+
push(baseKimiEvent({
|
|
7213
|
+
ts,
|
|
7214
|
+
type: eventTypeFromFileActivities(fileActivities),
|
|
7215
|
+
operation: `${toolName} file activity`,
|
|
7216
|
+
sessionId,
|
|
7217
|
+
turnId: turnId || state.currentTurnId,
|
|
7218
|
+
cwd,
|
|
7219
|
+
project,
|
|
7220
|
+
model,
|
|
7221
|
+
provider,
|
|
7222
|
+
tool: toolName,
|
|
7223
|
+
confidence: "derived",
|
|
7224
|
+
fileActivities,
|
|
7225
|
+
metrics: summarizeFileActivities(fileActivities),
|
|
7226
|
+
refs: stringRefs({ sourceId: toolCallId })
|
|
7227
|
+
}), lineNumber, entryType);
|
|
7228
|
+
}
|
|
7229
|
+
continue;
|
|
7230
|
+
}
|
|
7231
|
+
if (loopType === "tool.result") {
|
|
7232
|
+
const toolCallId = stringField(loopEvent, "toolCallId");
|
|
7233
|
+
const pending = toolCallId ? pendingToolCalls.get(toolCallId) : void 0;
|
|
7234
|
+
if (toolCallId) {
|
|
7235
|
+
pendingToolCalls.delete(toolCallId);
|
|
7236
|
+
}
|
|
7237
|
+
const result = objectField(loopEvent, "result");
|
|
7238
|
+
const isError = Boolean(result.isError);
|
|
7239
|
+
const toolName = pending?.toolName || "tool";
|
|
7240
|
+
const durationMs = pending ? durationMsBetween(pending.startedAt, ts) : void 0;
|
|
7241
|
+
push(baseKimiEvent({
|
|
7242
|
+
ts,
|
|
7243
|
+
type: isError ? "tool.failed" : "tool.completed",
|
|
7244
|
+
operation: isError ? `${toolName} failed` : `${toolName} completed`,
|
|
7245
|
+
sessionId,
|
|
7246
|
+
turnId: pending?.turnId || turnId || state.currentTurnId,
|
|
7247
|
+
cwd,
|
|
7248
|
+
project,
|
|
7249
|
+
model,
|
|
7250
|
+
provider,
|
|
7251
|
+
tool: toolName,
|
|
7252
|
+
success: !isError,
|
|
7253
|
+
confidence: "exact",
|
|
7254
|
+
metrics: {
|
|
7255
|
+
toolDurationMs: durationMs,
|
|
7256
|
+
durationMs
|
|
7257
|
+
},
|
|
7258
|
+
refs: stringRefs({ sourceId: toolCallId })
|
|
7259
|
+
}), lineNumber, entryType);
|
|
7260
|
+
if (toolName.toLowerCase() === "bash") {
|
|
7261
|
+
push(baseKimiEvent({
|
|
7262
|
+
ts,
|
|
7263
|
+
type: isError ? "command.failed" : "command.completed",
|
|
7264
|
+
operation: "command completed",
|
|
7265
|
+
sessionId,
|
|
7266
|
+
turnId: pending?.turnId || turnId || state.currentTurnId,
|
|
7267
|
+
cwd,
|
|
7268
|
+
project,
|
|
7269
|
+
model,
|
|
7270
|
+
provider,
|
|
7271
|
+
tool: "Bash",
|
|
7272
|
+
success: !isError,
|
|
7273
|
+
confidence: "derived",
|
|
7274
|
+
metrics: {
|
|
7275
|
+
commandCalls: 1,
|
|
7276
|
+
commandDurationMs: durationMs,
|
|
7277
|
+
durationMs
|
|
7278
|
+
},
|
|
7279
|
+
refs: stringRefs({
|
|
7280
|
+
sourceId: toolCallId,
|
|
7281
|
+
commandHash: pending?.input.command ? `sha256:${createStableHash(String(pending.input.command))}` : void 0
|
|
7282
|
+
})
|
|
7283
|
+
}), lineNumber, entryType);
|
|
7284
|
+
}
|
|
7285
|
+
continue;
|
|
7286
|
+
}
|
|
7287
|
+
if (loopType === "step.end") {
|
|
7288
|
+
if (!sawUsageRecord) {
|
|
7289
|
+
const streamMs = numberField(loopEvent, "llmStreamDurationMs") || numberField(loopEvent, "llmServerDecodeMs");
|
|
7290
|
+
const usage = objectField(loopEvent, "usage");
|
|
7291
|
+
const metrics = kimiUsageFromRecord(usage);
|
|
7292
|
+
if (metrics) {
|
|
7293
|
+
if (streamMs) {
|
|
7294
|
+
metrics.modelDurationMs = streamMs;
|
|
7295
|
+
}
|
|
7296
|
+
if (reasoningEffort) {
|
|
7297
|
+
metrics.reasoningEffort = reasoningEffort;
|
|
7298
|
+
}
|
|
7299
|
+
push(baseKimiEvent({
|
|
7300
|
+
ts,
|
|
7301
|
+
type: "model.usage",
|
|
7302
|
+
sessionId,
|
|
7303
|
+
turnId: turnId || state.currentTurnId,
|
|
7304
|
+
cwd,
|
|
7305
|
+
project,
|
|
7306
|
+
model,
|
|
7307
|
+
provider,
|
|
7308
|
+
confidence: "exact",
|
|
7309
|
+
metrics
|
|
7310
|
+
}), lineNumber, entryType);
|
|
7311
|
+
}
|
|
7312
|
+
}
|
|
7313
|
+
continue;
|
|
7314
|
+
}
|
|
7315
|
+
continue;
|
|
7316
|
+
}
|
|
7317
|
+
if (entryType === "interaction.request") {
|
|
7318
|
+
state.ensureSessionStarted(ts, lineNumber, entryType);
|
|
7319
|
+
const requestId = stringField(raw, "id") || stringField(raw, "toolCallId");
|
|
7320
|
+
const request2 = objectField(raw, "request");
|
|
7321
|
+
const toolName = stringField(request2, "toolName") || stringField(raw, "toolName");
|
|
7322
|
+
const turnId = normalizeTurnId(request2.turnId) || state.currentTurnId;
|
|
7323
|
+
if (requestId) {
|
|
7324
|
+
pendingPermissions.set(requestId, { toolName, startedAt: ts, turnId });
|
|
7325
|
+
}
|
|
7326
|
+
push(baseKimiEvent({
|
|
7327
|
+
ts,
|
|
7328
|
+
type: "permission.requested",
|
|
7329
|
+
operation: toolName ? `${toolName} permission` : "permission requested",
|
|
7330
|
+
sessionId,
|
|
7331
|
+
turnId,
|
|
7332
|
+
cwd,
|
|
7333
|
+
project,
|
|
7334
|
+
model,
|
|
7335
|
+
provider,
|
|
7336
|
+
tool: toolName,
|
|
7337
|
+
confidence: "exact",
|
|
7338
|
+
refs: stringRefs({ sourceId: requestId })
|
|
7339
|
+
}), lineNumber, entryType);
|
|
7340
|
+
continue;
|
|
7341
|
+
}
|
|
7342
|
+
if (entryType === "interaction.resolved") {
|
|
7343
|
+
state.ensureSessionStarted(ts, lineNumber, entryType);
|
|
7344
|
+
const requestId = stringField(raw, "id");
|
|
7345
|
+
const pending = requestId ? pendingPermissions.get(requestId) : void 0;
|
|
7346
|
+
if (requestId) {
|
|
7347
|
+
pendingPermissions.delete(requestId);
|
|
7348
|
+
}
|
|
7349
|
+
const response = objectField(raw, "response");
|
|
7350
|
+
const decision = stringField(response, "decision") || stringField(raw, "decision");
|
|
7351
|
+
const granted = decision === "approved" || decision === "allow" || decision === "granted";
|
|
7352
|
+
const denied = decision === "denied" || decision === "reject" || decision === "rejected";
|
|
7353
|
+
push(baseKimiEvent({
|
|
7354
|
+
ts,
|
|
7355
|
+
type: granted ? "permission.granted" : denied ? "permission.denied" : "permission.resolved",
|
|
7356
|
+
operation: decision ? `permission ${decision}` : "permission resolved",
|
|
7357
|
+
sessionId,
|
|
7358
|
+
turnId: pending?.turnId || state.currentTurnId,
|
|
7359
|
+
cwd,
|
|
7360
|
+
project,
|
|
7361
|
+
model,
|
|
7362
|
+
provider,
|
|
7363
|
+
tool: pending?.toolName,
|
|
7364
|
+
success: granted ? true : denied ? false : void 0,
|
|
7365
|
+
confidence: "exact",
|
|
7366
|
+
metrics: {
|
|
7367
|
+
durationMs: pending ? durationMsBetween(pending.startedAt, ts) : void 0,
|
|
7368
|
+
approvalWaitMs: pending ? durationMsBetween(pending.startedAt, ts) : void 0
|
|
7369
|
+
},
|
|
7370
|
+
refs: stringRefs({ sourceId: requestId })
|
|
7371
|
+
}), lineNumber, entryType);
|
|
7372
|
+
continue;
|
|
7373
|
+
}
|
|
7374
|
+
}
|
|
7375
|
+
if (isTurnIdle(state.currentTurnLastEventAt)) {
|
|
7376
|
+
state.closeTurn(state.currentTurnLastEventAt, lines.length);
|
|
7377
|
+
}
|
|
7378
|
+
return state.events.filter((event) => matchesBackfillFilters(event, options));
|
|
7379
|
+
}
|
|
7380
|
+
function createKimiCodeAdapter() {
|
|
7381
|
+
return {
|
|
7382
|
+
id: "kimi-code",
|
|
7383
|
+
label: "Kimi Code",
|
|
7384
|
+
agentName: "kimi-code",
|
|
7385
|
+
kind: "agent",
|
|
7386
|
+
detectPath(home, env) {
|
|
7387
|
+
return kimiCodeHome(home, env);
|
|
7388
|
+
},
|
|
7389
|
+
installedPath(home, env) {
|
|
7390
|
+
return path14.join(kimiCodeHome(home, env), "vibetime-marker");
|
|
7391
|
+
},
|
|
7392
|
+
async isInstalled() {
|
|
7393
|
+
return false;
|
|
7394
|
+
},
|
|
7395
|
+
installEntries(_home, _env) {
|
|
7396
|
+
return [];
|
|
7397
|
+
},
|
|
7398
|
+
sourcePaths(home, env) {
|
|
7399
|
+
return [kimiCodeSessionsDir(home, env)];
|
|
7400
|
+
},
|
|
7401
|
+
parseSessionFile: parseKimiCodeSessionFile
|
|
7402
|
+
};
|
|
7403
|
+
}
|
|
7404
|
+
|
|
6938
7405
|
// src/adapters/opencode.ts
|
|
6939
7406
|
import os6 from "node:os";
|
|
6940
|
-
import
|
|
7407
|
+
import path15 from "node:path";
|
|
6941
7408
|
async function parseOpenCodeSessionFile(dbPath, options) {
|
|
6942
7409
|
const { DatabaseSync } = await import("node:sqlite");
|
|
6943
7410
|
if (!dbPath.endsWith(".db")) {
|
|
@@ -6994,7 +7461,7 @@ async function parseOpenCodeSessionFile(dbPath, options) {
|
|
|
6994
7461
|
const rawSessionId = session.id;
|
|
6995
7462
|
const sessionId = rootIdByRawId.get(rawSessionId) || rawSessionId;
|
|
6996
7463
|
const cwd = session.directory || session.path || void 0;
|
|
6997
|
-
const project = cwd ?
|
|
7464
|
+
const project = cwd ? path15.basename(cwd) : void 0;
|
|
6998
7465
|
const sessionTs = msToIso(session.time_created);
|
|
6999
7466
|
events.push(baseOpenCodeEvent({
|
|
7000
7467
|
ts: sessionTs,
|
|
@@ -7102,7 +7569,7 @@ async function parseOpenCodeSessionFile(dbPath, options) {
|
|
|
7102
7569
|
const provider = currentProvider;
|
|
7103
7570
|
const pathObj = objectField(info, "path");
|
|
7104
7571
|
const assistantCwd = stringField(pathObj, "cwd") || cwd;
|
|
7105
|
-
const assistantProject = assistantCwd ?
|
|
7572
|
+
const assistantProject = assistantCwd ? path15.basename(assistantCwd) : project;
|
|
7106
7573
|
const completedTs = numberField(objectField(info, "time"), "completed");
|
|
7107
7574
|
const createdTs = timeCreated;
|
|
7108
7575
|
const tokens = opencodeUsageFromInfo(info);
|
|
@@ -7373,18 +7840,18 @@ function opencodeUsageFromInfo(info) {
|
|
|
7373
7840
|
function opencodeConfigDir(home, env) {
|
|
7374
7841
|
const override = env?.OPENCODE_CONFIG_DIR;
|
|
7375
7842
|
if (override && override.trim()) {
|
|
7376
|
-
return
|
|
7843
|
+
return path15.resolve(override);
|
|
7377
7844
|
}
|
|
7378
7845
|
const xdgConfig = env?.XDG_CONFIG_HOME;
|
|
7379
7846
|
if (xdgConfig && xdgConfig.trim()) {
|
|
7380
|
-
return
|
|
7847
|
+
return path15.join(path15.resolve(xdgConfig), "opencode");
|
|
7381
7848
|
}
|
|
7382
|
-
return
|
|
7849
|
+
return path15.join(home, ".config", "opencode");
|
|
7383
7850
|
}
|
|
7384
7851
|
function opencodeDataCandidates(home, env) {
|
|
7385
7852
|
const xdgData = env?.XDG_DATA_HOME;
|
|
7386
|
-
const primary = xdgData && xdgData.trim() ?
|
|
7387
|
-
return [primary,
|
|
7853
|
+
const primary = xdgData && xdgData.trim() ? path15.join(path15.resolve(xdgData), "opencode", "opencode.db") : path15.join(home, ".local", "share", "opencode", "opencode.db");
|
|
7854
|
+
return [primary, path15.join(home, ".opencode", "opencode.db")];
|
|
7388
7855
|
}
|
|
7389
7856
|
async function opencodeBackfillFiles(sourceRoot, home = os6.homedir(), env) {
|
|
7390
7857
|
const { stat: stat14 } = await import("node:fs/promises");
|
|
@@ -7474,12 +7941,12 @@ function createOpenCodeAdapter() {
|
|
|
7474
7941
|
return opencodeConfigDir(home, env);
|
|
7475
7942
|
},
|
|
7476
7943
|
installedPath(home, env) {
|
|
7477
|
-
return
|
|
7944
|
+
return path15.join(opencodeConfigDir(home, env), PLUGIN_PATH);
|
|
7478
7945
|
},
|
|
7479
7946
|
async isInstalled(home, env) {
|
|
7480
7947
|
try {
|
|
7481
7948
|
const { pathExists: pathExists2 } = await Promise.resolve().then(() => (init_fs(), fs_exports));
|
|
7482
|
-
return await pathExists2(
|
|
7949
|
+
return await pathExists2(path15.join(opencodeConfigDir(home, env), PLUGIN_PATH)) || await pathExists2(path15.join(".opencode", PLUGIN_PATH));
|
|
7483
7950
|
} catch {
|
|
7484
7951
|
return false;
|
|
7485
7952
|
}
|
|
@@ -7487,7 +7954,7 @@ function createOpenCodeAdapter() {
|
|
|
7487
7954
|
installEntries(home, env) {
|
|
7488
7955
|
return [{
|
|
7489
7956
|
kind: "file",
|
|
7490
|
-
path:
|
|
7957
|
+
path: path15.join(opencodeConfigDir(home, env), PLUGIN_PATH),
|
|
7491
7958
|
content: opencodePluginContent()
|
|
7492
7959
|
}];
|
|
7493
7960
|
},
|
|
@@ -7499,12 +7966,12 @@ function createOpenCodeAdapter() {
|
|
|
7499
7966
|
}
|
|
7500
7967
|
|
|
7501
7968
|
// src/adapters/pi.ts
|
|
7502
|
-
import { readFile as
|
|
7503
|
-
import
|
|
7969
|
+
import { readFile as readFile10 } from "node:fs/promises";
|
|
7970
|
+
import path16 from "node:path";
|
|
7504
7971
|
function parsePiSubagentLink(filePath, headerParentSession) {
|
|
7505
7972
|
if (headerParentSession) {
|
|
7506
|
-
const parentFile =
|
|
7507
|
-
const parentSessionId2 = parentFile ?
|
|
7973
|
+
const parentFile = path16.isAbsolute(headerParentSession) ? headerParentSession : void 0;
|
|
7974
|
+
const parentSessionId2 = parentFile ? path16.basename(parentFile, ".jsonl") : headerParentSession;
|
|
7508
7975
|
return { parentSessionId: parentSessionId2, parentSessionFile: parentFile, explicit: true };
|
|
7509
7976
|
}
|
|
7510
7977
|
const normalized = filePath.replaceAll("\\", "/");
|
|
@@ -7517,20 +7984,20 @@ function parsePiSubagentLink(filePath, headerParentSession) {
|
|
|
7517
7984
|
return void 0;
|
|
7518
7985
|
}
|
|
7519
7986
|
const parentSessionId = parentBasename.endsWith(".jsonl") ? parentBasename.slice(0, -".jsonl".length) : parentBasename;
|
|
7520
|
-
const parentDir =
|
|
7521
|
-
const parentSessionFile =
|
|
7987
|
+
const parentDir = path16.dirname(path16.dirname(path16.dirname(filePath)));
|
|
7988
|
+
const parentSessionFile = path16.join(path16.dirname(parentDir), `${parentBasename}.jsonl`);
|
|
7522
7989
|
return { parentSessionId, parentSessionFile, explicit: false };
|
|
7523
7990
|
}
|
|
7524
7991
|
async function resolveParentContext(link, options) {
|
|
7525
7992
|
if (link.parentSessionFile) {
|
|
7526
7993
|
try {
|
|
7527
|
-
const text = await
|
|
7994
|
+
const text = await readFile10(link.parentSessionFile, "utf8");
|
|
7528
7995
|
const firstLine = text.split("\n").find((line) => line.trim().length > 0);
|
|
7529
7996
|
const raw = firstLine ? parseJsonLine(firstLine) : void 0;
|
|
7530
7997
|
if (raw) {
|
|
7531
7998
|
const id = stringField(raw, "id");
|
|
7532
7999
|
const cwd = stringField(raw, "cwd");
|
|
7533
|
-
const project = cwd ?
|
|
8000
|
+
const project = cwd ? path16.basename(cwd) : void 0;
|
|
7534
8001
|
if (id || cwd || project) {
|
|
7535
8002
|
return { sessionId: id, cwd, project };
|
|
7536
8003
|
}
|
|
@@ -7575,7 +8042,7 @@ function rebuildEventIdentity2(event) {
|
|
|
7575
8042
|
};
|
|
7576
8043
|
}
|
|
7577
8044
|
async function parsePiSessionFile(filePath, options) {
|
|
7578
|
-
const text = await
|
|
8045
|
+
const text = await readFile10(filePath, "utf8");
|
|
7579
8046
|
const lines = text.split("\n").filter(Boolean);
|
|
7580
8047
|
let sessionId;
|
|
7581
8048
|
let cwd;
|
|
@@ -7607,7 +8074,7 @@ async function parsePiSessionFile(filePath, options) {
|
|
|
7607
8074
|
sessionId = stringField(raw, "id") || state.sessionId;
|
|
7608
8075
|
state.sessionId = sessionId || state.sessionId;
|
|
7609
8076
|
cwd = stringField(raw, "cwd") || cwd;
|
|
7610
|
-
project = cwd ?
|
|
8077
|
+
project = cwd ? path16.basename(cwd) : project;
|
|
7611
8078
|
headerParentSession = stringField(raw, "parentSession") || headerParentSession;
|
|
7612
8079
|
continue;
|
|
7613
8080
|
}
|
|
@@ -8040,16 +8507,16 @@ export default function (pi: ExtensionAPI) {
|
|
|
8040
8507
|
function piAgentDir(home, env) {
|
|
8041
8508
|
const override = env?.PI_CODING_AGENT_DIR;
|
|
8042
8509
|
if (override && override.trim()) {
|
|
8043
|
-
return
|
|
8510
|
+
return path16.resolve(override);
|
|
8044
8511
|
}
|
|
8045
|
-
return
|
|
8512
|
+
return path16.join(home, ".pi", "agent");
|
|
8046
8513
|
}
|
|
8047
8514
|
function piSessionDir(home, env) {
|
|
8048
8515
|
const override = env?.PI_CODING_AGENT_SESSION_DIR;
|
|
8049
8516
|
if (override && override.trim()) {
|
|
8050
|
-
return
|
|
8517
|
+
return path16.resolve(override);
|
|
8051
8518
|
}
|
|
8052
|
-
return
|
|
8519
|
+
return path16.join(piAgentDir(home, env), "sessions");
|
|
8053
8520
|
}
|
|
8054
8521
|
function createPiAdapter() {
|
|
8055
8522
|
return {
|
|
@@ -8061,12 +8528,12 @@ function createPiAdapter() {
|
|
|
8061
8528
|
return piAgentDir(home, env);
|
|
8062
8529
|
},
|
|
8063
8530
|
installedPath(home, env) {
|
|
8064
|
-
return
|
|
8531
|
+
return path16.join(piAgentDir(home, env), "extensions", "vibetime.ts");
|
|
8065
8532
|
},
|
|
8066
8533
|
async isInstalled(home, env) {
|
|
8067
8534
|
try {
|
|
8068
8535
|
const { pathExists: pathExists2 } = await Promise.resolve().then(() => (init_fs(), fs_exports));
|
|
8069
|
-
return await pathExists2(
|
|
8536
|
+
return await pathExists2(path16.join(piAgentDir(home, env), "extensions", "vibetime.ts"));
|
|
8070
8537
|
} catch {
|
|
8071
8538
|
return false;
|
|
8072
8539
|
}
|
|
@@ -8074,7 +8541,7 @@ function createPiAdapter() {
|
|
|
8074
8541
|
installEntries(home, env) {
|
|
8075
8542
|
return [{
|
|
8076
8543
|
kind: "file",
|
|
8077
|
-
path:
|
|
8544
|
+
path: path16.join(piAgentDir(home, env), "extensions", "vibetime.ts"),
|
|
8078
8545
|
content: piExtensionContent()
|
|
8079
8546
|
}];
|
|
8080
8547
|
},
|
|
@@ -8086,14 +8553,14 @@ function createPiAdapter() {
|
|
|
8086
8553
|
}
|
|
8087
8554
|
|
|
8088
8555
|
// src/adapters/qoder-cn.ts
|
|
8089
|
-
import { readdir as readdir7, readFile as
|
|
8556
|
+
import { readdir as readdir7, readFile as readFile11, stat as stat8 } from "node:fs/promises";
|
|
8090
8557
|
import os8 from "node:os";
|
|
8091
|
-
import
|
|
8558
|
+
import path18 from "node:path";
|
|
8092
8559
|
|
|
8093
8560
|
// src/adapters/qoder-local-db.ts
|
|
8094
8561
|
import { access } from "node:fs/promises";
|
|
8095
8562
|
import os7 from "node:os";
|
|
8096
|
-
import
|
|
8563
|
+
import path17 from "node:path";
|
|
8097
8564
|
function takeQoderDbModelCall(calls, requestId, blockStart) {
|
|
8098
8565
|
if (requestId) {
|
|
8099
8566
|
const call = calls.byRequestId.get(requestId)?.shift();
|
|
@@ -8112,12 +8579,12 @@ function takeQoderDbModelCall(calls, requestId, blockStart) {
|
|
|
8112
8579
|
}
|
|
8113
8580
|
function appDataRoot(appDirName, home = os7.homedir()) {
|
|
8114
8581
|
if (process.platform === "darwin") {
|
|
8115
|
-
return
|
|
8582
|
+
return path17.join(home, "Library", "Application Support", appDirName);
|
|
8116
8583
|
}
|
|
8117
8584
|
if (process.platform === "win32") {
|
|
8118
|
-
return
|
|
8585
|
+
return path17.join(process.env.APPDATA || path17.join(home, "AppData", "Roaming"), appDirName);
|
|
8119
8586
|
}
|
|
8120
|
-
return
|
|
8587
|
+
return path17.join(home, ".config", appDirName);
|
|
8121
8588
|
}
|
|
8122
8589
|
function qoderLocalDbCandidates(appDirName) {
|
|
8123
8590
|
const candidates = [];
|
|
@@ -8127,8 +8594,8 @@ function qoderLocalDbCandidates(appDirName) {
|
|
|
8127
8594
|
}
|
|
8128
8595
|
const configRoot = appDataRoot(appDirName);
|
|
8129
8596
|
candidates.push(
|
|
8130
|
-
|
|
8131
|
-
|
|
8597
|
+
path17.join(configRoot, "SharedClientCache", "cache", "db", "local.db"),
|
|
8598
|
+
path17.join(configRoot, "SharedClientCache", "db", "local.db")
|
|
8132
8599
|
);
|
|
8133
8600
|
return candidates;
|
|
8134
8601
|
}
|
|
@@ -8137,7 +8604,7 @@ async function loadQoderIdeModelCatalog(appDirName, home) {
|
|
|
8137
8604
|
try {
|
|
8138
8605
|
const { DatabaseSync } = await import("node:sqlite");
|
|
8139
8606
|
const db = new DatabaseSync(
|
|
8140
|
-
|
|
8607
|
+
path17.join(appDataRoot(appDirName, home), "User", "globalStorage", "state.vscdb"),
|
|
8141
8608
|
{ readOnly: true }
|
|
8142
8609
|
);
|
|
8143
8610
|
try {
|
|
@@ -8279,7 +8746,7 @@ function resolveSessionPreferredModel(db, sessionId, modelMap) {
|
|
|
8279
8746
|
|
|
8280
8747
|
// src/adapters/qoder-cn.ts
|
|
8281
8748
|
function parseQoderCnPaths(filePath) {
|
|
8282
|
-
const parts = filePath.split(
|
|
8749
|
+
const parts = filePath.split(path18.sep);
|
|
8283
8750
|
const subagentsIdx = parts.lastIndexOf("subagents");
|
|
8284
8751
|
let sessionId = "";
|
|
8285
8752
|
let projectName = "";
|
|
@@ -8289,17 +8756,17 @@ function parseQoderCnPaths(filePath) {
|
|
|
8289
8756
|
sessionId = parts[subagentsIdx - 1];
|
|
8290
8757
|
projectName = parts[subagentsIdx - 2];
|
|
8291
8758
|
const projectsIdx = parts.lastIndexOf("projects");
|
|
8292
|
-
configDir2 = parts.slice(0, projectsIdx).join(
|
|
8293
|
-
mainTranscriptPath = [...parts.slice(0, subagentsIdx - 1), `${sessionId}.jsonl`].join(
|
|
8759
|
+
configDir2 = parts.slice(0, projectsIdx).join(path18.sep);
|
|
8760
|
+
mainTranscriptPath = [...parts.slice(0, subagentsIdx - 1), `${sessionId}.jsonl`].join(path18.sep);
|
|
8294
8761
|
} else {
|
|
8295
8762
|
const filename = parts.at(-1) || "";
|
|
8296
|
-
sessionId =
|
|
8763
|
+
sessionId = path18.basename(filename, ".jsonl");
|
|
8297
8764
|
projectName = parts.at(-2) || "";
|
|
8298
8765
|
if (projectName === "transcript") {
|
|
8299
8766
|
projectName = parts.at(-3) || "";
|
|
8300
8767
|
}
|
|
8301
8768
|
const projectsIdx = parts.lastIndexOf("projects");
|
|
8302
|
-
configDir2 = parts.slice(0, projectsIdx).join(
|
|
8769
|
+
configDir2 = parts.slice(0, projectsIdx).join(path18.sep);
|
|
8303
8770
|
}
|
|
8304
8771
|
return { configDir: configDir2, projectName, sessionId, mainTranscriptPath };
|
|
8305
8772
|
}
|
|
@@ -8322,7 +8789,7 @@ function rebuildEventIdentity3(event) {
|
|
|
8322
8789
|
}
|
|
8323
8790
|
async function parseModelNamesFromDynamicTexts(dynamicTextsPath) {
|
|
8324
8791
|
try {
|
|
8325
|
-
const content = await
|
|
8792
|
+
const content = await readFile11(dynamicTextsPath, "utf8");
|
|
8326
8793
|
const json = JSON.parse(content);
|
|
8327
8794
|
const texts = json.texts || {};
|
|
8328
8795
|
const map = {};
|
|
@@ -8338,10 +8805,10 @@ async function parseModelNamesFromDynamicTexts(dynamicTextsPath) {
|
|
|
8338
8805
|
}
|
|
8339
8806
|
}
|
|
8340
8807
|
async function loadQoderCnModelNames(configDir2, home) {
|
|
8341
|
-
const map = await parseModelNamesFromDynamicTexts(
|
|
8808
|
+
const map = await parseModelNamesFromDynamicTexts(path18.join(configDir2, ".auth", "dynamic-texts.json"));
|
|
8342
8809
|
const siblingConfigDir = configDir2.replace(/\.qoder-cn$/, ".qoder");
|
|
8343
8810
|
if (siblingConfigDir !== configDir2) {
|
|
8344
|
-
const siblingMap = await parseModelNamesFromDynamicTexts(
|
|
8811
|
+
const siblingMap = await parseModelNamesFromDynamicTexts(path18.join(siblingConfigDir, ".auth", "dynamic-texts.json"));
|
|
8345
8812
|
for (const [key, val] of Object.entries(siblingMap)) {
|
|
8346
8813
|
if (!(key in map)) {
|
|
8347
8814
|
map[key] = val;
|
|
@@ -8360,7 +8827,7 @@ async function loadQoderCnModelNames(configDir2, home) {
|
|
|
8360
8827
|
}
|
|
8361
8828
|
async function loadQoderCnSegmentModelCalls(filePath, isSubagentSession, modelMap) {
|
|
8362
8829
|
const { configDir: configDir2, projectName, sessionId } = parseQoderCnPaths(filePath);
|
|
8363
|
-
const segmentsPath =
|
|
8830
|
+
const segmentsPath = path18.join(configDir2, "logs", "sessions", projectName, sessionId, "segments");
|
|
8364
8831
|
const modelCalls = [];
|
|
8365
8832
|
try {
|
|
8366
8833
|
const files = await readdir7(segmentsPath);
|
|
@@ -8368,7 +8835,7 @@ async function loadQoderCnSegmentModelCalls(filePath, isSubagentSession, modelMa
|
|
|
8368
8835
|
if (!file.endsWith(".jsonl")) {
|
|
8369
8836
|
continue;
|
|
8370
8837
|
}
|
|
8371
|
-
const content = await
|
|
8838
|
+
const content = await readFile11(path18.join(segmentsPath, file), "utf8");
|
|
8372
8839
|
let currentTurnIsSubagent = false;
|
|
8373
8840
|
for (const line of content.split("\n").filter(Boolean)) {
|
|
8374
8841
|
const raw = parseJsonLine(line);
|
|
@@ -8402,7 +8869,7 @@ async function loadQoderCnSegmentModelCalls(filePath, isSubagentSession, modelMa
|
|
|
8402
8869
|
return modelCalls.filter((call) => call.isSubagent === isSubagentSession);
|
|
8403
8870
|
}
|
|
8404
8871
|
async function parseQoderCnSessionFile(filePath, options) {
|
|
8405
|
-
const text = await
|
|
8872
|
+
const text = await readFile11(filePath, "utf8");
|
|
8406
8873
|
const lines = text.split("\n").filter(Boolean);
|
|
8407
8874
|
const parsedPaths = parseQoderCnPaths(filePath);
|
|
8408
8875
|
const { configDir: configDir2 } = parsedPaths;
|
|
@@ -8413,7 +8880,7 @@ async function parseQoderCnSessionFile(filePath, options) {
|
|
|
8413
8880
|
let cwd;
|
|
8414
8881
|
let project = projectContext.project;
|
|
8415
8882
|
let model;
|
|
8416
|
-
const home =
|
|
8883
|
+
const home = path18.resolve(stringOption(options.home) || os8.homedir());
|
|
8417
8884
|
const modelMap = await loadQoderCnModelNames(configDir2, home);
|
|
8418
8885
|
const isSubagentSession = filePath.includes("subagents");
|
|
8419
8886
|
const segmentModelCalls = await loadQoderCnSegmentModelCalls(filePath, isSubagentSession, modelMap);
|
|
@@ -8448,7 +8915,7 @@ async function parseQoderCnSessionFile(filePath, options) {
|
|
|
8448
8915
|
sessionId = stringField(raw, "sessionId") || sessionId;
|
|
8449
8916
|
state.sessionId = sessionId;
|
|
8450
8917
|
cwd = stringField(raw, "cwd") || cwd;
|
|
8451
|
-
project = projectContext.project || (cwd ?
|
|
8918
|
+
project = projectContext.project || (cwd ? path18.basename(cwd) : project || await qoderCnProjectFromFilePath(filePath, options));
|
|
8452
8919
|
if (!ts) {
|
|
8453
8920
|
continue;
|
|
8454
8921
|
}
|
|
@@ -8783,7 +9250,7 @@ async function parseQoderCnSessionFile(filePath, options) {
|
|
|
8783
9250
|
}
|
|
8784
9251
|
dbModelCalls ??= await loadQoderDbModelCalls("QoderCN", parsedPaths.sessionId, modelMap);
|
|
8785
9252
|
if (dbModelCalls.rootSessionId) {
|
|
8786
|
-
const parentPath =
|
|
9253
|
+
const parentPath = path18.join(path18.dirname(filePath), `${dbModelCalls.rootSessionId}.jsonl`);
|
|
8787
9254
|
const parentSourcePathHash = `sha256:${createStableHash(parentPath)}`;
|
|
8788
9255
|
return validEvents.map((event) => rebuildEventIdentity3({
|
|
8789
9256
|
...event,
|
|
@@ -8935,28 +9402,28 @@ function extractQoderAttachedPrompt(content) {
|
|
|
8935
9402
|
}
|
|
8936
9403
|
async function qoderCnProjectContextFromLines(filePath, lines, options, configDir2) {
|
|
8937
9404
|
const { projectName: projectDir, sessionId } = parseQoderCnPaths(filePath);
|
|
8938
|
-
const isSubagent = filePath.includes(`${
|
|
9405
|
+
const isSubagent = filePath.includes(`${path18.sep}subagents${path18.sep}`);
|
|
8939
9406
|
const inherited = isSubagent ? await readPersistedSessionContextFromOptions(options, sessionId) : void 0;
|
|
8940
9407
|
let cwds = [];
|
|
8941
9408
|
for (const line of lines) {
|
|
8942
9409
|
const raw = parseJsonLine(line);
|
|
8943
9410
|
const cwd = raw ? stringField(raw, "cwd") : void 0;
|
|
8944
|
-
if (cwd &&
|
|
9411
|
+
if (cwd && path18.isAbsolute(cwd)) {
|
|
8945
9412
|
cwds.push(cwd);
|
|
8946
9413
|
}
|
|
8947
9414
|
}
|
|
8948
9415
|
if (isSubagent) {
|
|
8949
|
-
if (inherited?.cwd &&
|
|
9416
|
+
if (inherited?.cwd && path18.isAbsolute(inherited.cwd)) {
|
|
8950
9417
|
cwds = [inherited.cwd];
|
|
8951
9418
|
} else {
|
|
8952
|
-
const parentSessionPath =
|
|
9419
|
+
const parentSessionPath = path18.join(configDir2, "projects", projectDir, `${sessionId}.jsonl`);
|
|
8953
9420
|
try {
|
|
8954
|
-
const parentText = await
|
|
9421
|
+
const parentText = await readFile11(parentSessionPath, "utf8");
|
|
8955
9422
|
const parentCwds = [];
|
|
8956
9423
|
for (const line of parentText.split("\n").filter(Boolean)) {
|
|
8957
9424
|
const raw = parseJsonLine(line);
|
|
8958
9425
|
const cwd = raw ? stringField(raw, "cwd") : void 0;
|
|
8959
|
-
if (cwd &&
|
|
9426
|
+
if (cwd && path18.isAbsolute(cwd)) {
|
|
8960
9427
|
parentCwds.push(cwd);
|
|
8961
9428
|
}
|
|
8962
9429
|
}
|
|
@@ -8968,7 +9435,7 @@ async function qoderCnProjectContextFromLines(filePath, lines, options, configDi
|
|
|
8968
9435
|
}
|
|
8969
9436
|
}
|
|
8970
9437
|
const root = await gitRootFromCwds2(cwds) || qoderCnProjectRootFromCwds(projectDir, cwds);
|
|
8971
|
-
const project = inherited?.project || (cwds.length > 0 ?
|
|
9438
|
+
const project = inherited?.project || (cwds.length > 0 ? path18.basename(cwds[0]) : root ? path18.basename(root) : await qoderCnProjectFromFilePath(filePath, options));
|
|
8972
9439
|
return {
|
|
8973
9440
|
project,
|
|
8974
9441
|
workspaceId: createWorkspaceId({ projectName: project, repoRoot: root })
|
|
@@ -8977,15 +9444,15 @@ async function qoderCnProjectContextFromLines(filePath, lines, options, configDi
|
|
|
8977
9444
|
async function gitRootFromCwds2(cwds) {
|
|
8978
9445
|
const seen = /* @__PURE__ */ new Set();
|
|
8979
9446
|
for (const cwd of cwds) {
|
|
8980
|
-
let current =
|
|
9447
|
+
let current = path18.resolve(cwd);
|
|
8981
9448
|
while (!seen.has(current)) {
|
|
8982
9449
|
seen.add(current);
|
|
8983
9450
|
try {
|
|
8984
|
-
await stat8(
|
|
9451
|
+
await stat8(path18.join(current, ".git"));
|
|
8985
9452
|
return current;
|
|
8986
9453
|
} catch {
|
|
8987
9454
|
}
|
|
8988
|
-
const parent =
|
|
9455
|
+
const parent = path18.dirname(current);
|
|
8989
9456
|
if (parent === current) {
|
|
8990
9457
|
break;
|
|
8991
9458
|
}
|
|
@@ -8996,12 +9463,12 @@ async function gitRootFromCwds2(cwds) {
|
|
|
8996
9463
|
}
|
|
8997
9464
|
function qoderCnProjectRootFromCwds(projectDir, cwds) {
|
|
8998
9465
|
for (const cwd of cwds) {
|
|
8999
|
-
let current =
|
|
9466
|
+
let current = path18.resolve(cwd);
|
|
9000
9467
|
while (true) {
|
|
9001
9468
|
if (encodeQoderCnProjectPath(current) === projectDir) {
|
|
9002
9469
|
return current;
|
|
9003
9470
|
}
|
|
9004
|
-
const parent =
|
|
9471
|
+
const parent = path18.dirname(current);
|
|
9005
9472
|
if (parent === current) {
|
|
9006
9473
|
break;
|
|
9007
9474
|
}
|
|
@@ -9011,14 +9478,14 @@ function qoderCnProjectRootFromCwds(projectDir, cwds) {
|
|
|
9011
9478
|
return void 0;
|
|
9012
9479
|
}
|
|
9013
9480
|
function encodeQoderCnProjectPath(value) {
|
|
9014
|
-
return
|
|
9481
|
+
return path18.resolve(value).split(path18.sep).join("-").replaceAll("_", "-");
|
|
9015
9482
|
}
|
|
9016
9483
|
async function qoderCnProjectFromFilePath(filePath, options) {
|
|
9017
|
-
const projectDir =
|
|
9018
|
-
const home = options ?
|
|
9484
|
+
const projectDir = path18.basename(path18.dirname(filePath));
|
|
9485
|
+
const home = options ? path18.resolve(stringOption(options.home) || os8.homedir()) : os8.homedir();
|
|
9019
9486
|
const resolved = await resolveQoderCnProjectPath(projectDir, home);
|
|
9020
9487
|
if (resolved) {
|
|
9021
|
-
return
|
|
9488
|
+
return path18.basename(resolved);
|
|
9022
9489
|
}
|
|
9023
9490
|
const homePrefix = `${encodeQoderCnProjectPath(home)}-`;
|
|
9024
9491
|
if (projectDir.startsWith(homePrefix)) {
|
|
@@ -9043,7 +9510,7 @@ async function resolveQoderCnProjectPath(projectDir, home) {
|
|
|
9043
9510
|
if (!entry.isDirectory()) {
|
|
9044
9511
|
continue;
|
|
9045
9512
|
}
|
|
9046
|
-
const candidate =
|
|
9513
|
+
const candidate = path18.join(current, entry.name);
|
|
9047
9514
|
const encoded = encodeQoderCnProjectPath(candidate);
|
|
9048
9515
|
if (encoded === projectDir) {
|
|
9049
9516
|
return candidate;
|
|
@@ -9088,9 +9555,9 @@ function hookConfig6() {
|
|
|
9088
9555
|
function qoderCnConfigDir(home, env) {
|
|
9089
9556
|
const override = env?.QODER_CN_CONFIG_DIR;
|
|
9090
9557
|
if (override && override.trim()) {
|
|
9091
|
-
return
|
|
9558
|
+
return path18.resolve(override);
|
|
9092
9559
|
}
|
|
9093
|
-
return
|
|
9560
|
+
return path18.join(home, ".qoder-cn");
|
|
9094
9561
|
}
|
|
9095
9562
|
function createQoderCnAdapter() {
|
|
9096
9563
|
return {
|
|
@@ -9102,27 +9569,27 @@ function createQoderCnAdapter() {
|
|
|
9102
9569
|
return qoderCnConfigDir(home, env);
|
|
9103
9570
|
},
|
|
9104
9571
|
installedPath(home, env) {
|
|
9105
|
-
return
|
|
9572
|
+
return path18.join(qoderCnConfigDir(home, env), "settings.json");
|
|
9106
9573
|
},
|
|
9107
9574
|
async isInstalled(home, env) {
|
|
9108
9575
|
return isHooksJsonInstalled(
|
|
9109
|
-
|
|
9576
|
+
path18.join(qoderCnConfigDir(home, env), "settings.json"),
|
|
9110
9577
|
"vibetime hook --agent qoder-cn"
|
|
9111
9578
|
);
|
|
9112
9579
|
},
|
|
9113
9580
|
installEntries(home, env) {
|
|
9114
9581
|
return [{
|
|
9115
9582
|
kind: "hooks-json",
|
|
9116
|
-
path:
|
|
9583
|
+
path: path18.join(qoderCnConfigDir(home, env), "settings.json"),
|
|
9117
9584
|
content: hookConfig6()
|
|
9118
9585
|
}];
|
|
9119
9586
|
},
|
|
9120
9587
|
sourcePaths(home, env) {
|
|
9121
9588
|
const base = qoderCnConfigDir(home, env);
|
|
9122
9589
|
return [
|
|
9123
|
-
|
|
9124
|
-
|
|
9125
|
-
|
|
9590
|
+
path18.join(base, "projects"),
|
|
9591
|
+
path18.join(base, ".qoder.json"),
|
|
9592
|
+
path18.join(home, ".qoder.json")
|
|
9126
9593
|
];
|
|
9127
9594
|
},
|
|
9128
9595
|
parseSessionFile: parseQoderCnSessionFile
|
|
@@ -9131,11 +9598,11 @@ function createQoderCnAdapter() {
|
|
|
9131
9598
|
|
|
9132
9599
|
// src/adapters/qoder.ts
|
|
9133
9600
|
import { existsSync } from "node:fs";
|
|
9134
|
-
import { readdir as readdir8, readFile as
|
|
9601
|
+
import { readdir as readdir8, readFile as readFile12, stat as stat9 } from "node:fs/promises";
|
|
9135
9602
|
import os9 from "node:os";
|
|
9136
|
-
import
|
|
9603
|
+
import path19 from "node:path";
|
|
9137
9604
|
function parseQoderPaths(filePath) {
|
|
9138
|
-
const parts = filePath.split(
|
|
9605
|
+
const parts = filePath.split(path19.sep);
|
|
9139
9606
|
const subagentsIdx = parts.lastIndexOf("subagents");
|
|
9140
9607
|
let sessionId = "";
|
|
9141
9608
|
let projectName = "";
|
|
@@ -9145,17 +9612,17 @@ function parseQoderPaths(filePath) {
|
|
|
9145
9612
|
sessionId = parts[subagentsIdx - 1];
|
|
9146
9613
|
projectName = parts[subagentsIdx - 2];
|
|
9147
9614
|
const projectsIdx = parts.lastIndexOf("projects");
|
|
9148
|
-
configDir2 = parts.slice(0, projectsIdx).join(
|
|
9149
|
-
mainTranscriptPath = [...parts.slice(0, subagentsIdx - 1), `${sessionId}.jsonl`].join(
|
|
9615
|
+
configDir2 = parts.slice(0, projectsIdx).join(path19.sep);
|
|
9616
|
+
mainTranscriptPath = [...parts.slice(0, subagentsIdx - 1), `${sessionId}.jsonl`].join(path19.sep);
|
|
9150
9617
|
} else {
|
|
9151
9618
|
const filename = parts.at(-1) || "";
|
|
9152
|
-
sessionId =
|
|
9619
|
+
sessionId = path19.basename(filename, ".jsonl");
|
|
9153
9620
|
projectName = parts.at(-2) || "";
|
|
9154
9621
|
if (projectName === "transcript") {
|
|
9155
9622
|
projectName = parts.at(-3) || "";
|
|
9156
9623
|
}
|
|
9157
9624
|
const projectsIdx = parts.lastIndexOf("projects");
|
|
9158
|
-
configDir2 = parts.slice(0, projectsIdx).join(
|
|
9625
|
+
configDir2 = parts.slice(0, projectsIdx).join(path19.sep);
|
|
9159
9626
|
}
|
|
9160
9627
|
return { configDir: configDir2, projectName, sessionId, mainTranscriptPath };
|
|
9161
9628
|
}
|
|
@@ -9178,7 +9645,7 @@ function rebuildEventIdentity4(event) {
|
|
|
9178
9645
|
}
|
|
9179
9646
|
async function parseModelNamesFromDynamicTexts2(dynamicTextsPath) {
|
|
9180
9647
|
try {
|
|
9181
|
-
const content = await
|
|
9648
|
+
const content = await readFile12(dynamicTextsPath, "utf8");
|
|
9182
9649
|
const json = JSON.parse(content);
|
|
9183
9650
|
const texts = json.texts || {};
|
|
9184
9651
|
const map = {};
|
|
@@ -9194,10 +9661,10 @@ async function parseModelNamesFromDynamicTexts2(dynamicTextsPath) {
|
|
|
9194
9661
|
}
|
|
9195
9662
|
}
|
|
9196
9663
|
async function loadQoderModelNames(configDir2, home) {
|
|
9197
|
-
const map = await parseModelNamesFromDynamicTexts2(
|
|
9664
|
+
const map = await parseModelNamesFromDynamicTexts2(path19.join(configDir2, ".auth", "dynamic-texts.json"));
|
|
9198
9665
|
const siblingConfigDir = configDir2.replace(/\.qoder$/, ".qoder-cn");
|
|
9199
9666
|
if (siblingConfigDir !== configDir2) {
|
|
9200
|
-
const siblingMap = await parseModelNamesFromDynamicTexts2(
|
|
9667
|
+
const siblingMap = await parseModelNamesFromDynamicTexts2(path19.join(siblingConfigDir, ".auth", "dynamic-texts.json"));
|
|
9201
9668
|
for (const [key, val] of Object.entries(siblingMap)) {
|
|
9202
9669
|
if (!(key in map)) {
|
|
9203
9670
|
map[key] = val;
|
|
@@ -9205,11 +9672,11 @@ async function loadQoderModelNames(configDir2, home) {
|
|
|
9205
9672
|
}
|
|
9206
9673
|
}
|
|
9207
9674
|
if (isQwenworkConfigRoot(configDir2)) {
|
|
9208
|
-
for (const dir of [
|
|
9209
|
-
if (
|
|
9675
|
+
for (const dir of [path19.join(home, ".qoder"), path19.join(home, ".qoder-cn")]) {
|
|
9676
|
+
if (path19.resolve(dir) === path19.resolve(configDir2)) {
|
|
9210
9677
|
continue;
|
|
9211
9678
|
}
|
|
9212
|
-
const fallbackMap = await parseModelNamesFromDynamicTexts2(
|
|
9679
|
+
const fallbackMap = await parseModelNamesFromDynamicTexts2(path19.join(dir, ".auth", "dynamic-texts.json"));
|
|
9213
9680
|
for (const [key, val] of Object.entries(fallbackMap)) {
|
|
9214
9681
|
if (!(key in map)) {
|
|
9215
9682
|
map[key] = val;
|
|
@@ -9228,17 +9695,17 @@ async function loadQoderModelNames(configDir2, home) {
|
|
|
9228
9695
|
return map;
|
|
9229
9696
|
}
|
|
9230
9697
|
function isQwenworkConfigRoot(configDir2) {
|
|
9231
|
-
const name =
|
|
9698
|
+
const name = path19.basename(path19.resolve(configDir2));
|
|
9232
9699
|
if (name === ".qwenworkcn" || name === ".qwenwork") {
|
|
9233
9700
|
return true;
|
|
9234
9701
|
}
|
|
9235
9702
|
const override = process.env.QWENWORK_CONFIG_DIR;
|
|
9236
|
-
return Boolean(override && override.trim() &&
|
|
9703
|
+
return Boolean(override && override.trim() && path19.basename(path19.resolve(override)) === name);
|
|
9237
9704
|
}
|
|
9238
9705
|
var FAILED_SEGMENT_STOP_REASONS = /* @__PURE__ */ new Set(["cancelled", "canceled", "error", "failed", "refusal"]);
|
|
9239
9706
|
async function loadQoderSegmentModelCalls(filePath, isSubagentSession, modelMap) {
|
|
9240
9707
|
const { configDir: configDir2, projectName, sessionId } = parseQoderPaths(filePath);
|
|
9241
|
-
const segmentsPath =
|
|
9708
|
+
const segmentsPath = path19.join(configDir2, "logs", "sessions", projectName, sessionId, "segments");
|
|
9242
9709
|
const modelCalls = [];
|
|
9243
9710
|
try {
|
|
9244
9711
|
const files = await readdir8(segmentsPath);
|
|
@@ -9246,7 +9713,7 @@ async function loadQoderSegmentModelCalls(filePath, isSubagentSession, modelMap)
|
|
|
9246
9713
|
if (!file.endsWith(".jsonl")) {
|
|
9247
9714
|
continue;
|
|
9248
9715
|
}
|
|
9249
|
-
const content = await
|
|
9716
|
+
const content = await readFile12(path19.join(segmentsPath, file), "utf8");
|
|
9250
9717
|
let currentTurnIsSubagent = false;
|
|
9251
9718
|
for (const line of content.split("\n").filter(Boolean)) {
|
|
9252
9719
|
const raw = parseJsonLine(line);
|
|
@@ -9280,7 +9747,7 @@ async function loadQoderSegmentModelCalls(filePath, isSubagentSession, modelMap)
|
|
|
9280
9747
|
return modelCalls.filter((call) => call.isSubagent === isSubagentSession);
|
|
9281
9748
|
}
|
|
9282
9749
|
async function parseQoderSessionFile(filePath, options) {
|
|
9283
|
-
const text = await
|
|
9750
|
+
const text = await readFile12(filePath, "utf8");
|
|
9284
9751
|
const lines = text.split("\n").filter(Boolean);
|
|
9285
9752
|
const parsedPaths = parseQoderPaths(filePath);
|
|
9286
9753
|
const { configDir: configDir2 } = parsedPaths;
|
|
@@ -9291,7 +9758,7 @@ async function parseQoderSessionFile(filePath, options) {
|
|
|
9291
9758
|
let cwd;
|
|
9292
9759
|
let project = projectContext.project;
|
|
9293
9760
|
let model;
|
|
9294
|
-
const home =
|
|
9761
|
+
const home = path19.resolve(stringOption(options.home) || os9.homedir());
|
|
9295
9762
|
const modelMap = await loadQoderModelNames(configDir2, home);
|
|
9296
9763
|
const qwenworkRoot = isQwenworkConfigRoot(configDir2);
|
|
9297
9764
|
const isSubagentSession = filePath.includes("subagents");
|
|
@@ -9327,7 +9794,7 @@ async function parseQoderSessionFile(filePath, options) {
|
|
|
9327
9794
|
sessionId = stringField(raw, "sessionId") || sessionId;
|
|
9328
9795
|
state.sessionId = sessionId;
|
|
9329
9796
|
cwd = stringField(raw, "cwd") || cwd;
|
|
9330
|
-
project = projectContext.project || (cwd ?
|
|
9797
|
+
project = projectContext.project || (cwd ? path19.basename(cwd) : project || await qoderProjectFromFilePath(filePath, options));
|
|
9331
9798
|
if (!ts) {
|
|
9332
9799
|
continue;
|
|
9333
9800
|
}
|
|
@@ -9637,7 +10104,7 @@ async function parseQoderSessionFile(filePath, options) {
|
|
|
9637
10104
|
}
|
|
9638
10105
|
dbModelCalls ??= await loadQoderDbModelCalls("Qoder", parsedPaths.sessionId, modelMap);
|
|
9639
10106
|
if (dbModelCalls.rootSessionId) {
|
|
9640
|
-
const parentPath =
|
|
10107
|
+
const parentPath = path19.join(path19.dirname(filePath), `${dbModelCalls.rootSessionId}.jsonl`);
|
|
9641
10108
|
const parentSourcePathHash = `sha256:${createStableHash(parentPath)}`;
|
|
9642
10109
|
return validEvents.map((event) => rebuildEventIdentity4({
|
|
9643
10110
|
...event,
|
|
@@ -9753,41 +10220,41 @@ function qoderExtractText(value) {
|
|
|
9753
10220
|
}
|
|
9754
10221
|
async function qoderProjectContextFromLines(filePath, lines, options, configDir2) {
|
|
9755
10222
|
const { projectName: projectDir, sessionId } = parseQoderPaths(filePath);
|
|
9756
|
-
const isSubagent = filePath.includes(`${
|
|
10223
|
+
const isSubagent = filePath.includes(`${path19.sep}subagents${path19.sep}`);
|
|
9757
10224
|
const inherited = isSubagent ? await readPersistedSessionContextFromOptions(options, sessionId) : void 0;
|
|
9758
10225
|
let cwds = [];
|
|
9759
10226
|
const workspaceDirs = [];
|
|
9760
10227
|
for (const line of lines) {
|
|
9761
10228
|
const raw = parseJsonLine(line);
|
|
9762
10229
|
const cwd = raw ? stringField(raw, "cwd") : void 0;
|
|
9763
|
-
if (cwd &&
|
|
10230
|
+
if (cwd && path19.isAbsolute(cwd)) {
|
|
9764
10231
|
cwds.push(cwd);
|
|
9765
10232
|
}
|
|
9766
10233
|
if (raw && stringField(raw, "type") === "workspace-directories") {
|
|
9767
10234
|
for (const dir of arrayField5(raw, "directories")) {
|
|
9768
|
-
if (typeof dir === "string" &&
|
|
10235
|
+
if (typeof dir === "string" && path19.isAbsolute(dir)) {
|
|
9769
10236
|
workspaceDirs.push(dir);
|
|
9770
10237
|
}
|
|
9771
10238
|
}
|
|
9772
10239
|
}
|
|
9773
10240
|
}
|
|
9774
10241
|
if (isSubagent) {
|
|
9775
|
-
if (inherited?.cwd &&
|
|
10242
|
+
if (inherited?.cwd && path19.isAbsolute(inherited.cwd)) {
|
|
9776
10243
|
cwds = [inherited.cwd];
|
|
9777
10244
|
} else {
|
|
9778
|
-
const parentSessionPath =
|
|
10245
|
+
const parentSessionPath = path19.join(configDir2, "projects", projectDir, `${sessionId}.jsonl`);
|
|
9779
10246
|
try {
|
|
9780
|
-
const parentText = await
|
|
10247
|
+
const parentText = await readFile12(parentSessionPath, "utf8");
|
|
9781
10248
|
const parentCwds = [];
|
|
9782
10249
|
for (const line of parentText.split("\n").filter(Boolean)) {
|
|
9783
10250
|
const raw = parseJsonLine(line);
|
|
9784
10251
|
const cwd = raw ? stringField(raw, "cwd") : void 0;
|
|
9785
|
-
if (cwd &&
|
|
10252
|
+
if (cwd && path19.isAbsolute(cwd)) {
|
|
9786
10253
|
parentCwds.push(cwd);
|
|
9787
10254
|
}
|
|
9788
10255
|
if (workspaceDirs.length === 0 && raw && stringField(raw, "type") === "workspace-directories") {
|
|
9789
10256
|
for (const dir of arrayField5(raw, "directories")) {
|
|
9790
|
-
if (typeof dir === "string" &&
|
|
10257
|
+
if (typeof dir === "string" && path19.isAbsolute(dir)) {
|
|
9791
10258
|
workspaceDirs.push(dir);
|
|
9792
10259
|
}
|
|
9793
10260
|
}
|
|
@@ -9807,29 +10274,29 @@ async function qoderProjectContextFromLines(filePath, lines, options, configDir2
|
|
|
9807
10274
|
}
|
|
9808
10275
|
}
|
|
9809
10276
|
const root = await gitRootFromCwds3(cwds) || qoderProjectRootFromCwds(projectDir, cwds);
|
|
9810
|
-
const project = inherited?.project || (cwds.length > 0 ?
|
|
10277
|
+
const project = inherited?.project || (cwds.length > 0 ? path19.basename(cwds[0]) : root ? path19.basename(root) : await qoderProjectFromFilePath(filePath, options));
|
|
9811
10278
|
return {
|
|
9812
10279
|
project,
|
|
9813
10280
|
workspaceId: createWorkspaceId({ projectName: project, repoRoot: root })
|
|
9814
10281
|
};
|
|
9815
10282
|
}
|
|
9816
10283
|
function pathInsideDir(candidate, dir) {
|
|
9817
|
-
const resolvedDir =
|
|
9818
|
-
const resolved =
|
|
9819
|
-
return resolved === resolvedDir || resolved.startsWith(`${resolvedDir}${
|
|
10284
|
+
const resolvedDir = path19.resolve(dir);
|
|
10285
|
+
const resolved = path19.resolve(candidate);
|
|
10286
|
+
return resolved === resolvedDir || resolved.startsWith(`${resolvedDir}${path19.sep}`);
|
|
9820
10287
|
}
|
|
9821
10288
|
async function gitRootFromCwds3(cwds) {
|
|
9822
10289
|
const seen = /* @__PURE__ */ new Set();
|
|
9823
10290
|
for (const cwd of cwds) {
|
|
9824
|
-
let current =
|
|
10291
|
+
let current = path19.resolve(cwd);
|
|
9825
10292
|
while (!seen.has(current)) {
|
|
9826
10293
|
seen.add(current);
|
|
9827
10294
|
try {
|
|
9828
|
-
await stat9(
|
|
10295
|
+
await stat9(path19.join(current, ".git"));
|
|
9829
10296
|
return current;
|
|
9830
10297
|
} catch {
|
|
9831
10298
|
}
|
|
9832
|
-
const parent =
|
|
10299
|
+
const parent = path19.dirname(current);
|
|
9833
10300
|
if (parent === current) {
|
|
9834
10301
|
break;
|
|
9835
10302
|
}
|
|
@@ -9840,12 +10307,12 @@ async function gitRootFromCwds3(cwds) {
|
|
|
9840
10307
|
}
|
|
9841
10308
|
function qoderProjectRootFromCwds(projectDir, cwds) {
|
|
9842
10309
|
for (const cwd of cwds) {
|
|
9843
|
-
let current =
|
|
10310
|
+
let current = path19.resolve(cwd);
|
|
9844
10311
|
while (true) {
|
|
9845
10312
|
if (qoderEncodedVariants(current).includes(projectDir)) {
|
|
9846
10313
|
return current;
|
|
9847
10314
|
}
|
|
9848
|
-
const parent =
|
|
10315
|
+
const parent = path19.dirname(current);
|
|
9849
10316
|
if (parent === current) {
|
|
9850
10317
|
break;
|
|
9851
10318
|
}
|
|
@@ -9855,7 +10322,7 @@ function qoderProjectRootFromCwds(projectDir, cwds) {
|
|
|
9855
10322
|
return void 0;
|
|
9856
10323
|
}
|
|
9857
10324
|
function rawQoderProjectPath(value) {
|
|
9858
|
-
return
|
|
10325
|
+
return path19.resolve(value).split(path19.sep).join("-");
|
|
9859
10326
|
}
|
|
9860
10327
|
function qoderEncodedVariants(value) {
|
|
9861
10328
|
const raw = rawQoderProjectPath(value);
|
|
@@ -9876,11 +10343,11 @@ function qoderEncodedProjectSuffix(projectDir, home) {
|
|
|
9876
10343
|
return void 0;
|
|
9877
10344
|
}
|
|
9878
10345
|
async function qoderProjectFromFilePath(filePath, options) {
|
|
9879
|
-
const projectDir =
|
|
9880
|
-
const home = options ?
|
|
10346
|
+
const projectDir = path19.basename(path19.dirname(filePath));
|
|
10347
|
+
const home = options ? path19.resolve(stringOption(options.home) || os9.homedir()) : os9.homedir();
|
|
9881
10348
|
const resolved = await resolveQoderProjectPath(projectDir, home);
|
|
9882
10349
|
if (resolved) {
|
|
9883
|
-
return
|
|
10350
|
+
return path19.basename(resolved);
|
|
9884
10351
|
}
|
|
9885
10352
|
const suffix = qoderEncodedProjectSuffix(projectDir, home);
|
|
9886
10353
|
if (suffix) {
|
|
@@ -9906,7 +10373,7 @@ async function resolveQoderProjectPath(projectDir, home) {
|
|
|
9906
10373
|
if (!entry.isDirectory()) {
|
|
9907
10374
|
continue;
|
|
9908
10375
|
}
|
|
9909
|
-
const candidate =
|
|
10376
|
+
const candidate = path19.join(current, entry.name);
|
|
9910
10377
|
const candidateVariants = qoderEncodedVariants(candidate);
|
|
9911
10378
|
if (candidateVariants.includes(projectDir)) {
|
|
9912
10379
|
return candidate;
|
|
@@ -9951,19 +10418,19 @@ function hookConfig7() {
|
|
|
9951
10418
|
function qoderConfigDir(home, env) {
|
|
9952
10419
|
const override = env?.QODER_CONFIG_DIR;
|
|
9953
10420
|
if (override && override.trim()) {
|
|
9954
|
-
return
|
|
10421
|
+
return path19.resolve(override);
|
|
9955
10422
|
}
|
|
9956
|
-
return
|
|
10423
|
+
return path19.join(home, ".qoder");
|
|
9957
10424
|
}
|
|
9958
10425
|
function qwenworkConfigDir(home, env) {
|
|
9959
10426
|
const override = env?.QWENWORK_CONFIG_DIR;
|
|
9960
10427
|
if (override && override.trim()) {
|
|
9961
|
-
return
|
|
10428
|
+
return path19.resolve(override);
|
|
9962
10429
|
}
|
|
9963
|
-
return
|
|
10430
|
+
return path19.join(home, ".qwenworkcn");
|
|
9964
10431
|
}
|
|
9965
10432
|
function qoderConfigDirs(home, env) {
|
|
9966
|
-
return [...new Set([qoderConfigDir(home, env), qwenworkConfigDir(home, env)].map((dir) =>
|
|
10433
|
+
return [...new Set([qoderConfigDir(home, env), qwenworkConfigDir(home, env)].map((dir) => path19.resolve(dir)))];
|
|
9967
10434
|
}
|
|
9968
10435
|
function createQoderAdapter() {
|
|
9969
10436
|
return {
|
|
@@ -9975,11 +10442,11 @@ function createQoderAdapter() {
|
|
|
9975
10442
|
return qoderConfigDir(home, env);
|
|
9976
10443
|
},
|
|
9977
10444
|
installedPath(home, env) {
|
|
9978
|
-
return
|
|
10445
|
+
return path19.join(qoderConfigDir(home, env), "settings.json");
|
|
9979
10446
|
},
|
|
9980
10447
|
async isInstalled(home, env) {
|
|
9981
10448
|
return isHooksJsonInstalled(
|
|
9982
|
-
|
|
10449
|
+
path19.join(qoderConfigDir(home, env), "settings.json"),
|
|
9983
10450
|
"vibetime hook --agent qoder"
|
|
9984
10451
|
);
|
|
9985
10452
|
},
|
|
@@ -9988,16 +10455,16 @@ function createQoderAdapter() {
|
|
|
9988
10455
|
const targets = [primary, ...variants.filter((dir) => existsSync(dir))];
|
|
9989
10456
|
return targets.map((base) => ({
|
|
9990
10457
|
kind: "hooks-json",
|
|
9991
|
-
path:
|
|
10458
|
+
path: path19.join(base, "settings.json"),
|
|
9992
10459
|
content: hookConfig7()
|
|
9993
10460
|
}));
|
|
9994
10461
|
},
|
|
9995
10462
|
sourcePaths(home, env) {
|
|
9996
|
-
const paths = qoderConfigDirs(home, env).map((base2) =>
|
|
10463
|
+
const paths = qoderConfigDirs(home, env).map((base2) => path19.join(base2, "projects"));
|
|
9997
10464
|
const base = qoderConfigDir(home, env);
|
|
9998
10465
|
paths.push(
|
|
9999
|
-
|
|
10000
|
-
|
|
10466
|
+
path19.join(base, ".qoder.json"),
|
|
10467
|
+
path19.join(home, ".qoder.json")
|
|
10001
10468
|
);
|
|
10002
10469
|
return paths;
|
|
10003
10470
|
},
|
|
@@ -10033,27 +10500,27 @@ function normalizeId(id) {
|
|
|
10033
10500
|
}
|
|
10034
10501
|
|
|
10035
10502
|
// src/adapters/workbuddy.ts
|
|
10036
|
-
import { readdir as readdir9, readFile as
|
|
10037
|
-
import
|
|
10503
|
+
import { readdir as readdir9, readFile as readFile13, stat as stat10 } from "node:fs/promises";
|
|
10504
|
+
import path20 from "node:path";
|
|
10038
10505
|
function workbuddyProjectsDir(home, env) {
|
|
10039
10506
|
const override = env?.WORKBUDDY_PROJECTS_DIR || env?.WORKBUDDY_HOME;
|
|
10040
10507
|
if (override && override.trim()) {
|
|
10041
|
-
return
|
|
10508
|
+
return path20.resolve(override, override.endsWith("projects") ? "" : "projects");
|
|
10042
10509
|
}
|
|
10043
|
-
return
|
|
10510
|
+
return path20.join(home, ".workbuddy", "projects");
|
|
10044
10511
|
}
|
|
10045
10512
|
function workbuddyBaseDir(home, env) {
|
|
10046
10513
|
const override = env?.WORKBUDDY_HOME;
|
|
10047
10514
|
if (override && override.trim()) {
|
|
10048
|
-
return
|
|
10515
|
+
return path20.resolve(override);
|
|
10049
10516
|
}
|
|
10050
|
-
return
|
|
10517
|
+
return path20.join(home, ".workbuddy");
|
|
10051
10518
|
}
|
|
10052
10519
|
function projectFromCwd(cwd, fallback) {
|
|
10053
10520
|
if (!cwd) {
|
|
10054
10521
|
return fallback;
|
|
10055
10522
|
}
|
|
10056
|
-
return
|
|
10523
|
+
return path20.basename(cwd) || fallback;
|
|
10057
10524
|
}
|
|
10058
10525
|
function sourceHash(filePath) {
|
|
10059
10526
|
return `sha256:${createStableHash(filePath)}`;
|
|
@@ -10171,7 +10638,7 @@ function toolCallFailed(record) {
|
|
|
10171
10638
|
return status === "failed" || status === "incomplete" || record.is_error === true || providerData.error != null || providerData.isError === true;
|
|
10172
10639
|
}
|
|
10173
10640
|
async function readWorkbuddyLines(filePath) {
|
|
10174
|
-
const text = await
|
|
10641
|
+
const text = await readFile13(filePath, "utf8");
|
|
10175
10642
|
return text.split(/\r?\n/).map((line, index) => {
|
|
10176
10643
|
if (!line.trim()) {
|
|
10177
10644
|
return void 0;
|
|
@@ -10191,8 +10658,8 @@ async function parseWorkbuddySessionFile(filePath, options) {
|
|
|
10191
10658
|
}
|
|
10192
10659
|
const events = [];
|
|
10193
10660
|
const first = lines[0].record;
|
|
10194
|
-
const sessionId = stringField(first, "sessionId") ||
|
|
10195
|
-
const fallbackProject =
|
|
10661
|
+
const sessionId = stringField(first, "sessionId") || path20.basename(filePath, ".jsonl");
|
|
10662
|
+
const fallbackProject = path20.basename(path20.dirname(filePath));
|
|
10196
10663
|
const cwd = lines.map((line) => stringField(line.record, "cwd")).find(Boolean);
|
|
10197
10664
|
const project = projectFromCwd(cwd, fallbackProject);
|
|
10198
10665
|
const workspaceId = createWorkspaceId({ projectName: project, repoRoot: cwd });
|
|
@@ -10481,11 +10948,11 @@ async function workbuddyBackfillFiles(sourceRoot, home, env) {
|
|
|
10481
10948
|
if (!project.isDirectory()) {
|
|
10482
10949
|
continue;
|
|
10483
10950
|
}
|
|
10484
|
-
const projectDir =
|
|
10951
|
+
const projectDir = path20.join(base, project.name);
|
|
10485
10952
|
const entries = await readdir9(projectDir, { withFileTypes: true });
|
|
10486
10953
|
for (const entry of entries) {
|
|
10487
10954
|
if (entry.isFile() && entry.name.endsWith(".jsonl")) {
|
|
10488
|
-
const filePath =
|
|
10955
|
+
const filePath = path20.join(projectDir, entry.name);
|
|
10489
10956
|
const info = await stat10(filePath);
|
|
10490
10957
|
files.push({ path: filePath, modifiedAt: info.mtime.toISOString() });
|
|
10491
10958
|
}
|
|
@@ -10523,18 +10990,18 @@ function createWorkbuddyAdapter() {
|
|
|
10523
10990
|
return workbuddyProjectsDir(home, env);
|
|
10524
10991
|
},
|
|
10525
10992
|
installedPath(home, env) {
|
|
10526
|
-
return
|
|
10993
|
+
return path20.join(workbuddyBaseDir(home, env), "settings.json");
|
|
10527
10994
|
},
|
|
10528
10995
|
async isInstalled(home, env) {
|
|
10529
10996
|
return isHooksJsonInstalled(
|
|
10530
|
-
|
|
10997
|
+
path20.join(workbuddyBaseDir(home, env), "settings.json"),
|
|
10531
10998
|
"vibetime hook --agent workbuddy"
|
|
10532
10999
|
);
|
|
10533
11000
|
},
|
|
10534
11001
|
installEntries(home, env) {
|
|
10535
11002
|
return [{
|
|
10536
11003
|
kind: "hooks-json",
|
|
10537
|
-
path:
|
|
11004
|
+
path: path20.join(workbuddyBaseDir(home, env), "settings.json"),
|
|
10538
11005
|
content: hookConfig8()
|
|
10539
11006
|
}];
|
|
10540
11007
|
},
|
|
@@ -10547,20 +11014,20 @@ function createWorkbuddyAdapter() {
|
|
|
10547
11014
|
|
|
10548
11015
|
// src/adapters/zcode.ts
|
|
10549
11016
|
import { execFile } from "node:child_process";
|
|
10550
|
-
import { readFile as
|
|
10551
|
-
import
|
|
11017
|
+
import { readFile as readFile14, stat as stat11 } from "node:fs/promises";
|
|
11018
|
+
import path21 from "node:path";
|
|
10552
11019
|
import { promisify as promisify2 } from "node:util";
|
|
10553
11020
|
init_fs();
|
|
10554
11021
|
var execFileAsync = promisify2(execFile);
|
|
10555
11022
|
function zcodeCliDir(home, env) {
|
|
10556
11023
|
const override = env?.ZCODE_CLI_DIR || env?.ZCODE_HOME;
|
|
10557
11024
|
if (override && override.trim()) {
|
|
10558
|
-
return
|
|
11025
|
+
return path21.resolve(override, override.endsWith("cli") ? "" : "cli");
|
|
10559
11026
|
}
|
|
10560
|
-
return
|
|
11027
|
+
return path21.join(home, ".zcode", "cli");
|
|
10561
11028
|
}
|
|
10562
11029
|
function zcodeDbPath(home, env) {
|
|
10563
|
-
return
|
|
11030
|
+
return path21.join(zcodeCliDir(home, env), "db", "db.sqlite");
|
|
10564
11031
|
}
|
|
10565
11032
|
var providerNameCache = null;
|
|
10566
11033
|
async function loadProviderNames(configPath2) {
|
|
@@ -10576,7 +11043,7 @@ async function loadProviderNames(configPath2) {
|
|
|
10576
11043
|
}
|
|
10577
11044
|
const map = /* @__PURE__ */ new Map();
|
|
10578
11045
|
try {
|
|
10579
|
-
const raw = await
|
|
11046
|
+
const raw = await readFile14(configPath2, "utf-8");
|
|
10580
11047
|
const config = JSON.parse(raw);
|
|
10581
11048
|
const providers = config?.provider;
|
|
10582
11049
|
if (isPlainObject(providers)) {
|
|
@@ -10594,7 +11061,7 @@ function sourceHash2(filePath) {
|
|
|
10594
11061
|
return `sha256:${createStableHash(filePath)}`;
|
|
10595
11062
|
}
|
|
10596
11063
|
function projectFromDirectory(directory) {
|
|
10597
|
-
return directory ?
|
|
11064
|
+
return directory ? path21.basename(directory) || "zcode" : "zcode";
|
|
10598
11065
|
}
|
|
10599
11066
|
function isoFromMs(value) {
|
|
10600
11067
|
return timestampFrom(typeof value === "number" ? value : Number(value));
|
|
@@ -10777,16 +11244,16 @@ async function parseZCodeDb(filePath, options) {
|
|
|
10777
11244
|
if (rows.length === 0) {
|
|
10778
11245
|
return [];
|
|
10779
11246
|
}
|
|
10780
|
-
let candidate =
|
|
11247
|
+
let candidate = path21.resolve(filePath);
|
|
10781
11248
|
let configPath2 = "";
|
|
10782
11249
|
for (let i = 0; i < 12; i++) {
|
|
10783
|
-
const probe =
|
|
11250
|
+
const probe = path21.join(candidate, ".zcode", "v2", "config.json");
|
|
10784
11251
|
try {
|
|
10785
11252
|
await stat11(probe);
|
|
10786
11253
|
configPath2 = probe;
|
|
10787
11254
|
break;
|
|
10788
11255
|
} catch {
|
|
10789
|
-
const parent =
|
|
11256
|
+
const parent = path21.dirname(candidate);
|
|
10790
11257
|
if (parent === candidate) break;
|
|
10791
11258
|
candidate = parent;
|
|
10792
11259
|
}
|
|
@@ -11002,7 +11469,7 @@ async function parseZCodeDb(filePath, options) {
|
|
|
11002
11469
|
}
|
|
11003
11470
|
async function zcodeBackfillFiles(sourceRoot, home, env) {
|
|
11004
11471
|
const candidate = sourceRoot || zcodeDbPath(home, env);
|
|
11005
|
-
const filePath = candidate.endsWith(".sqlite") ? candidate :
|
|
11472
|
+
const filePath = candidate.endsWith(".sqlite") ? candidate : path21.join(candidate, "db", "db.sqlite");
|
|
11006
11473
|
try {
|
|
11007
11474
|
const info = await stat11(filePath);
|
|
11008
11475
|
return [{ path: filePath, modifiedAt: info.mtime.toISOString() }];
|
|
@@ -11037,49 +11504,49 @@ function createZCodeAdapter() {
|
|
|
11037
11504
|
|
|
11038
11505
|
// src/adapters/zed.ts
|
|
11039
11506
|
import os10 from "node:os";
|
|
11040
|
-
import
|
|
11507
|
+
import path22 from "node:path";
|
|
11041
11508
|
function zedThreadsCandidates(home, env) {
|
|
11042
11509
|
const candidates = [];
|
|
11043
11510
|
const platform2 = process.platform;
|
|
11044
11511
|
if (platform2 === "darwin") {
|
|
11045
|
-
candidates.push(
|
|
11512
|
+
candidates.push(path22.join(home, "Library", "Application Support", "Zed", "threads", "threads.db"));
|
|
11046
11513
|
} else if (platform2 === "win32") {
|
|
11047
11514
|
const appdata = env?.APPDATA;
|
|
11048
11515
|
if (appdata && appdata.trim()) {
|
|
11049
|
-
candidates.push(
|
|
11516
|
+
candidates.push(path22.join(path22.resolve(appdata), "Zed", "threads", "threads.db"));
|
|
11050
11517
|
}
|
|
11051
|
-
candidates.push(
|
|
11518
|
+
candidates.push(path22.join(home, "AppData", "Roaming", "Zed", "threads", "threads.db"));
|
|
11052
11519
|
} else {
|
|
11053
11520
|
const xdgData = env?.XDG_DATA_HOME;
|
|
11054
11521
|
if (xdgData && xdgData.trim()) {
|
|
11055
|
-
candidates.push(
|
|
11522
|
+
candidates.push(path22.join(path22.resolve(xdgData), "zed", "threads", "threads.db"));
|
|
11056
11523
|
}
|
|
11057
|
-
candidates.push(
|
|
11524
|
+
candidates.push(path22.join(home, ".local", "share", "zed", "threads", "threads.db"));
|
|
11058
11525
|
const xdgConfig = env?.XDG_CONFIG_HOME;
|
|
11059
11526
|
if (xdgConfig && xdgConfig.trim()) {
|
|
11060
|
-
candidates.push(
|
|
11527
|
+
candidates.push(path22.join(path22.resolve(xdgConfig), "zed", "threads", "threads.db"));
|
|
11061
11528
|
}
|
|
11062
|
-
candidates.push(
|
|
11529
|
+
candidates.push(path22.join(home, ".config", "zed", "threads", "threads.db"));
|
|
11063
11530
|
}
|
|
11064
11531
|
return candidates;
|
|
11065
11532
|
}
|
|
11066
11533
|
function zedConfigDir(home, env) {
|
|
11067
11534
|
const platform2 = process.platform;
|
|
11068
11535
|
if (platform2 === "darwin") {
|
|
11069
|
-
return
|
|
11536
|
+
return path22.join(home, "Library", "Application Support", "Zed");
|
|
11070
11537
|
}
|
|
11071
11538
|
if (platform2 === "win32") {
|
|
11072
11539
|
const appdata = env?.APPDATA;
|
|
11073
11540
|
if (appdata && appdata.trim()) {
|
|
11074
|
-
return
|
|
11541
|
+
return path22.join(path22.resolve(appdata), "Zed");
|
|
11075
11542
|
}
|
|
11076
|
-
return
|
|
11543
|
+
return path22.join(home, "AppData", "Roaming", "Zed");
|
|
11077
11544
|
}
|
|
11078
11545
|
const xdgConfig = env?.XDG_CONFIG_HOME;
|
|
11079
11546
|
if (xdgConfig && xdgConfig.trim()) {
|
|
11080
|
-
return
|
|
11547
|
+
return path22.join(path22.resolve(xdgConfig), "zed");
|
|
11081
11548
|
}
|
|
11082
|
-
return
|
|
11549
|
+
return path22.join(home, ".config", "zed");
|
|
11083
11550
|
}
|
|
11084
11551
|
function baseZedEvent(event) {
|
|
11085
11552
|
return {
|
|
@@ -11143,7 +11610,7 @@ async function parseZedSessionFile(dbPath, options) {
|
|
|
11143
11610
|
const folderRaw = row.folder_paths || "";
|
|
11144
11611
|
const folder = folderRaw.split(/[\n,]/).map((s) => s.trim()).find(Boolean);
|
|
11145
11612
|
const cwd = folder || void 0;
|
|
11146
|
-
const project = cwd ?
|
|
11613
|
+
const project = cwd ? path22.basename(cwd) : row.summary ? row.summary.slice(0, 40) : void 0;
|
|
11147
11614
|
let json;
|
|
11148
11615
|
try {
|
|
11149
11616
|
const bytes = row.data_type === "zstd" ? decompress2(new Uint8Array(row.data)) : new Uint8Array(row.data);
|
|
@@ -11418,7 +11885,7 @@ function createZedAdapter() {
|
|
|
11418
11885
|
return zedConfigDir(home, env);
|
|
11419
11886
|
},
|
|
11420
11887
|
installedPath(home, env) {
|
|
11421
|
-
return
|
|
11888
|
+
return path22.join(zedConfigDir(home, env), "vibetime-marker");
|
|
11422
11889
|
},
|
|
11423
11890
|
async isInstalled() {
|
|
11424
11891
|
return false;
|
|
@@ -11899,15 +12366,15 @@ function hookCommandFromGroup(group) {
|
|
|
11899
12366
|
import { randomUUID } from "node:crypto";
|
|
11900
12367
|
import { existsSync as existsSync2, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
11901
12368
|
import { homedir, hostname } from "node:os";
|
|
11902
|
-
import
|
|
12369
|
+
import path23 from "node:path";
|
|
11903
12370
|
function configDir(home = homedir()) {
|
|
11904
|
-
return
|
|
12371
|
+
return path23.join(home, ".vibetime");
|
|
11905
12372
|
}
|
|
11906
12373
|
function configPath(home = homedir()) {
|
|
11907
|
-
return
|
|
12374
|
+
return path23.join(configDir(home), "config.json");
|
|
11908
12375
|
}
|
|
11909
12376
|
function machineIdPath(home = homedir()) {
|
|
11910
|
-
return
|
|
12377
|
+
return path23.join(configDir(home), "machine-id");
|
|
11911
12378
|
}
|
|
11912
12379
|
function readConfig(home = homedir()) {
|
|
11913
12380
|
const file = configPath(home);
|
|
@@ -11956,13 +12423,13 @@ init_fs();
|
|
|
11956
12423
|
// src/lib/logger.ts
|
|
11957
12424
|
import { appendFile, mkdir as mkdir4, rename, stat as stat12 } from "node:fs/promises";
|
|
11958
12425
|
import { homedir as homedir2 } from "node:os";
|
|
11959
|
-
import
|
|
12426
|
+
import path24 from "node:path";
|
|
11960
12427
|
var MAX_BYTES = 1 * 1024 * 1024;
|
|
11961
12428
|
function logDir(home = homedir2()) {
|
|
11962
|
-
return
|
|
12429
|
+
return path24.join(home, ".vibetime", "logs");
|
|
11963
12430
|
}
|
|
11964
12431
|
function logPath(home = homedir2(), name = "cli.log") {
|
|
11965
|
-
return
|
|
12432
|
+
return path24.join(logDir(home), name);
|
|
11966
12433
|
}
|
|
11967
12434
|
function serializeError(error) {
|
|
11968
12435
|
if (error instanceof Error) {
|
|
@@ -12137,8 +12604,8 @@ function buildHeaders(token, machine) {
|
|
|
12137
12604
|
...machine?.platform ? { "x-machine-platform": machine.platform } : {}
|
|
12138
12605
|
};
|
|
12139
12606
|
}
|
|
12140
|
-
function joinUrl(base,
|
|
12141
|
-
return new URL(
|
|
12607
|
+
function joinUrl(base, path26) {
|
|
12608
|
+
return new URL(path26, base.endsWith("/") ? base : `${base}/`).toString();
|
|
12142
12609
|
}
|
|
12143
12610
|
async function postRollupBatch(remote, rollups, options = {}) {
|
|
12144
12611
|
const response = await remote.fetchImpl(joinUrl(remote.baseUrl, "/v3/agent/ingest"), {
|
|
@@ -12228,6 +12695,7 @@ function createRegistry() {
|
|
|
12228
12695
|
registry.register(createZCodeAdapter());
|
|
12229
12696
|
registry.register(createGrokBuildAdapter());
|
|
12230
12697
|
registry.register(createZedAdapter());
|
|
12698
|
+
registry.register(createKimiCodeAdapter());
|
|
12231
12699
|
return registry;
|
|
12232
12700
|
}
|
|
12233
12701
|
var defaultContext = {
|
|
@@ -13123,13 +13591,13 @@ function selectBackfillFilesForImport(files, watermarkTs) {
|
|
|
13123
13591
|
return picked;
|
|
13124
13592
|
}
|
|
13125
13593
|
function backfillIncrementalStatePath(home) {
|
|
13126
|
-
return
|
|
13594
|
+
return path25.join(home, ".vibetime", "backfill-state.json");
|
|
13127
13595
|
}
|
|
13128
13596
|
function syncLocalTriggerStatePath(home) {
|
|
13129
|
-
return
|
|
13597
|
+
return path25.join(home, ".vibetime", "sync-local-trigger.json");
|
|
13130
13598
|
}
|
|
13131
13599
|
function syncLocalTriggerLockPath(home) {
|
|
13132
|
-
return
|
|
13600
|
+
return path25.join(home, ".vibetime", "sync-local-trigger.lock");
|
|
13133
13601
|
}
|
|
13134
13602
|
function backfillRemoteKey(baseUrl) {
|
|
13135
13603
|
try {
|
|
@@ -13191,7 +13659,7 @@ async function readBackfillIncrementalStateFile(home, ctx) {
|
|
|
13191
13659
|
}
|
|
13192
13660
|
async function writeBackfillIncrementalStateFile(home, file) {
|
|
13193
13661
|
const statePath = backfillIncrementalStatePath(home);
|
|
13194
|
-
await mkdir5(
|
|
13662
|
+
await mkdir5(path25.dirname(statePath), { recursive: true });
|
|
13195
13663
|
await writeFile4(statePath, `${JSON.stringify(file, null, 2)}
|
|
13196
13664
|
`, "utf8");
|
|
13197
13665
|
}
|
|
@@ -13240,7 +13708,7 @@ async function readSyncLocalTriggerState(statePath) {
|
|
|
13240
13708
|
return nextState;
|
|
13241
13709
|
}
|
|
13242
13710
|
async function writeSyncLocalTriggerState(statePath, state) {
|
|
13243
|
-
await mkdir5(
|
|
13711
|
+
await mkdir5(path25.dirname(statePath), { recursive: true });
|
|
13244
13712
|
await writeFile4(statePath, `${JSON.stringify(state, null, 2)}
|
|
13245
13713
|
`, "utf8");
|
|
13246
13714
|
}
|
|
@@ -13255,12 +13723,12 @@ async function readSyncLocalLock(lockPath) {
|
|
|
13255
13723
|
return { pid: lock.pid, startedAt: lock.startedAt };
|
|
13256
13724
|
}
|
|
13257
13725
|
async function writeSyncLocalLock(lockPath, lock) {
|
|
13258
|
-
await mkdir5(
|
|
13726
|
+
await mkdir5(path25.dirname(lockPath), { recursive: true });
|
|
13259
13727
|
await writeFile4(lockPath, `${JSON.stringify(lock, null, 2)}
|
|
13260
13728
|
`, "utf8");
|
|
13261
13729
|
}
|
|
13262
13730
|
async function acquireSyncLocalLock(lockPath, lock) {
|
|
13263
|
-
await mkdir5(
|
|
13731
|
+
await mkdir5(path25.dirname(lockPath), { recursive: true });
|
|
13264
13732
|
try {
|
|
13265
13733
|
const handle = await open(lockPath, "wx");
|
|
13266
13734
|
try {
|
|
@@ -13340,10 +13808,10 @@ function syncLocalRunnerEntryArgs(cliPath) {
|
|
|
13340
13808
|
if (cliPath.endsWith(".ts")) {
|
|
13341
13809
|
return ["--import", "tsx", cliPath];
|
|
13342
13810
|
}
|
|
13343
|
-
return [
|
|
13811
|
+
return [path25.resolve(path25.dirname(cliPath), "../bin/vibetime.mjs")];
|
|
13344
13812
|
}
|
|
13345
13813
|
function resolveHome3(options, ctx) {
|
|
13346
|
-
return
|
|
13814
|
+
return path25.resolve(stringOption(options.home) || ctx.env.HOME || os11.homedir());
|
|
13347
13815
|
}
|
|
13348
13816
|
function requestedTargets(options) {
|
|
13349
13817
|
const value = options.target || options.targets;
|