@yhong91/vibetime 0.1.44 → 0.1.45
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 +321 -229
- package/package.json +1 -1
package/bin/vibetime.mjs
CHANGED
|
@@ -1719,6 +1719,69 @@ import { promisify } from "node:util";
|
|
|
1719
1719
|
// src/lib/activity.ts
|
|
1720
1720
|
import path2 from "node:path";
|
|
1721
1721
|
|
|
1722
|
+
// src/lib/fields.ts
|
|
1723
|
+
function stringField(object, key) {
|
|
1724
|
+
if (!isPlainObject(object)) {
|
|
1725
|
+
return void 0;
|
|
1726
|
+
}
|
|
1727
|
+
const value = object[key];
|
|
1728
|
+
return typeof value === "string" ? value : void 0;
|
|
1729
|
+
}
|
|
1730
|
+
function numberField(object, key) {
|
|
1731
|
+
const value = object[key];
|
|
1732
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
1733
|
+
}
|
|
1734
|
+
function objectField(object, key) {
|
|
1735
|
+
if (!isPlainObject(object) || !isPlainObject(object[key])) {
|
|
1736
|
+
return {};
|
|
1737
|
+
}
|
|
1738
|
+
return object[key];
|
|
1739
|
+
}
|
|
1740
|
+
function arrayField(object, key) {
|
|
1741
|
+
if (!isPlainObject(object) || !Array.isArray(object[key])) {
|
|
1742
|
+
return [];
|
|
1743
|
+
}
|
|
1744
|
+
return object[key];
|
|
1745
|
+
}
|
|
1746
|
+
function isPlainObject(value) {
|
|
1747
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1748
|
+
}
|
|
1749
|
+
function stringRefs(value) {
|
|
1750
|
+
const refs2 = {};
|
|
1751
|
+
for (const [key, item] of Object.entries(value || {})) {
|
|
1752
|
+
if (typeof item === "string" && item.length > 0) {
|
|
1753
|
+
refs2[key] = item;
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
return refs2;
|
|
1757
|
+
}
|
|
1758
|
+
function stringOption(value) {
|
|
1759
|
+
if (Array.isArray(value)) {
|
|
1760
|
+
return value.at(-1);
|
|
1761
|
+
}
|
|
1762
|
+
return typeof value === "string" ? value : void 0;
|
|
1763
|
+
}
|
|
1764
|
+
function valuesOption(value) {
|
|
1765
|
+
if (Array.isArray(value)) {
|
|
1766
|
+
return value;
|
|
1767
|
+
}
|
|
1768
|
+
return typeof value === "string" ? [value] : [];
|
|
1769
|
+
}
|
|
1770
|
+
function numberOption(value) {
|
|
1771
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
1772
|
+
return value;
|
|
1773
|
+
}
|
|
1774
|
+
if (Array.isArray(value)) {
|
|
1775
|
+
return numberOption(value.at(-1));
|
|
1776
|
+
}
|
|
1777
|
+
const text = stringOption(value);
|
|
1778
|
+
if (!text) {
|
|
1779
|
+
return void 0;
|
|
1780
|
+
}
|
|
1781
|
+
const parsed = Number(text);
|
|
1782
|
+
return Number.isFinite(parsed) ? parsed : void 0;
|
|
1783
|
+
}
|
|
1784
|
+
|
|
1722
1785
|
// src/lib/shell.ts
|
|
1723
1786
|
import path from "node:path";
|
|
1724
1787
|
function fileActivitiesFromShellCommand(command, ts, rootCwd, initialCwd) {
|
|
@@ -1926,78 +1989,71 @@ function countTextLines(text) {
|
|
|
1926
1989
|
}
|
|
1927
1990
|
return text.split(/\r\n|\r|\n/).length;
|
|
1928
1991
|
}
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
// src/lib/fields.ts
|
|
1939
|
-
function stringField(object, key) {
|
|
1940
|
-
if (!isPlainObject(object)) {
|
|
1941
|
-
return void 0;
|
|
1942
|
-
}
|
|
1943
|
-
const value = object[key];
|
|
1944
|
-
return typeof value === "string" ? value : void 0;
|
|
1945
|
-
}
|
|
1946
|
-
function numberField(object, key) {
|
|
1947
|
-
const value = object[key];
|
|
1948
|
-
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
1949
|
-
}
|
|
1950
|
-
function objectField(object, key) {
|
|
1951
|
-
if (!isPlainObject(object) || !isPlainObject(object[key])) {
|
|
1952
|
-
return {};
|
|
1953
|
-
}
|
|
1954
|
-
return object[key];
|
|
1955
|
-
}
|
|
1956
|
-
function arrayField(object, key) {
|
|
1957
|
-
if (!isPlainObject(object) || !Array.isArray(object[key])) {
|
|
1958
|
-
return [];
|
|
1959
|
-
}
|
|
1960
|
-
return object[key];
|
|
1961
|
-
}
|
|
1962
|
-
function isPlainObject(value) {
|
|
1963
|
-
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
1964
|
-
}
|
|
1965
|
-
function stringRefs(value) {
|
|
1966
|
-
const refs2 = {};
|
|
1967
|
-
for (const [key, item] of Object.entries(value || {})) {
|
|
1968
|
-
if (typeof item === "string" && item.length > 0) {
|
|
1969
|
-
refs2[key] = item;
|
|
1992
|
+
function claudeStyleToolFileActivities(tool, input, ts, cwd) {
|
|
1993
|
+
const changes = /* @__PURE__ */ new Map();
|
|
1994
|
+
const operation = operationForTool(tool);
|
|
1995
|
+
const workdir = stringField(input, "cwd") || cwd;
|
|
1996
|
+
for (const key of ["file_path", "path", "notebook_path"]) {
|
|
1997
|
+
const filePath = stringField(input, key);
|
|
1998
|
+
if (!filePath) {
|
|
1999
|
+
continue;
|
|
1970
2000
|
}
|
|
2001
|
+
const metrics = claudeStyleFileMetrics(tool, input);
|
|
2002
|
+
addResolvedPathActivity(changes, filePath, operation, ts, cwd, workdir, metrics);
|
|
1971
2003
|
}
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
2004
|
+
for (const edit of [...arrayField(input, "edits"), ...arrayField(input, "replacements")]) {
|
|
2005
|
+
if (!isPlainObject(edit)) {
|
|
2006
|
+
continue;
|
|
2007
|
+
}
|
|
2008
|
+
const filePath = stringField(input, "file_path") || stringField(input, "path");
|
|
2009
|
+
if (!filePath) {
|
|
2010
|
+
continue;
|
|
2011
|
+
}
|
|
2012
|
+
addResolvedPathActivity(changes, filePath, "edit", ts, cwd, workdir, {
|
|
2013
|
+
linesAdded: countTextLines(stringField(edit, "new_string") || stringField(edit, "new_text")),
|
|
2014
|
+
linesRemoved: countTextLines(stringField(edit, "old_string") || stringField(edit, "original_text"))
|
|
2015
|
+
});
|
|
1977
2016
|
}
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
2017
|
+
const command = stringField(input, "command");
|
|
2018
|
+
if (command) {
|
|
2019
|
+
for (const item of fileActivitiesFromShellCommand(command, ts, cwd, workdir)) {
|
|
2020
|
+
changes.set(item.path, mergeFileActivity(changes.get(item.path), item));
|
|
2021
|
+
}
|
|
1983
2022
|
}
|
|
1984
|
-
return
|
|
2023
|
+
return [...changes.values()];
|
|
1985
2024
|
}
|
|
1986
|
-
function
|
|
1987
|
-
|
|
1988
|
-
|
|
2025
|
+
function claudeStyleFileMetrics(tool, input) {
|
|
2026
|
+
const normalized = tool.toLowerCase();
|
|
2027
|
+
if (normalized === "read") {
|
|
2028
|
+
return { linesRead: numberField(input, "limit") };
|
|
1989
2029
|
}
|
|
1990
|
-
if (
|
|
1991
|
-
|
|
2030
|
+
if (normalized === "write") {
|
|
2031
|
+
const content = stringField(input, "content") || stringField(input, "file_content");
|
|
2032
|
+
return {
|
|
2033
|
+
linesAdded: countTextLines(content),
|
|
2034
|
+
charsWritten: content?.length
|
|
2035
|
+
};
|
|
1992
2036
|
}
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
2037
|
+
if (normalized === "edit" || normalized === "multiedit" || normalized === "searchreplace") {
|
|
2038
|
+
const oldString = stringField(input, "old_string");
|
|
2039
|
+
const newString = stringField(input, "new_string");
|
|
2040
|
+
return {
|
|
2041
|
+
linesAdded: countTextLines(newString),
|
|
2042
|
+
linesRemoved: countTextLines(oldString),
|
|
2043
|
+
charsWritten: newString?.length
|
|
2044
|
+
};
|
|
1996
2045
|
}
|
|
1997
|
-
|
|
1998
|
-
return Number.isFinite(parsed) ? parsed : void 0;
|
|
2046
|
+
return {};
|
|
1999
2047
|
}
|
|
2000
2048
|
|
|
2049
|
+
// src/lib/constants.ts
|
|
2050
|
+
var PACKAGE_VERSION = true ? "0.1.45" : "0.1.1";
|
|
2051
|
+
var DEFAULT_API_URL = "http://121.196.224.82:3001";
|
|
2052
|
+
var DEFAULT_BACKFILL_BATCH_SIZE = 50;
|
|
2053
|
+
var DEFAULT_BACKFILL_BATCH_BYTES = 800 * 1024;
|
|
2054
|
+
var ROLLUP_BUCKET_MS = 15 * 60 * 1e3;
|
|
2055
|
+
var DEFAULT_HOOK_SYNC_MIN_INTERVAL_SECONDS = 60;
|
|
2056
|
+
|
|
2001
2057
|
// src/lib/jsonl.ts
|
|
2002
2058
|
function parseJsonLine(line) {
|
|
2003
2059
|
try {
|
|
@@ -3868,14 +3924,14 @@ function claudeProjectRootFromCwds(projectDir, cwds) {
|
|
|
3868
3924
|
return void 0;
|
|
3869
3925
|
}
|
|
3870
3926
|
function encodeClaudeProjectPath(value) {
|
|
3871
|
-
return path7.resolve(value).split(path7.sep).join("-").
|
|
3927
|
+
return path7.resolve(value).split(path7.sep).join("-").replaceAll("_", "-");
|
|
3872
3928
|
}
|
|
3873
3929
|
function rawClaudeProjectPath(value) {
|
|
3874
3930
|
return path7.resolve(value).split(path7.sep).join("-");
|
|
3875
3931
|
}
|
|
3876
3932
|
function claudeEncodedVariants(value) {
|
|
3877
3933
|
const raw = rawClaudeProjectPath(value);
|
|
3878
|
-
const normalized = raw.
|
|
3934
|
+
const normalized = raw.replaceAll("_", "-");
|
|
3879
3935
|
return raw === normalized ? [raw] : [raw, normalized];
|
|
3880
3936
|
}
|
|
3881
3937
|
function claudeEncodedProjectSuffix(projectDir, home) {
|
|
@@ -4129,7 +4185,7 @@ async function discoverCoworkTranscripts(root) {
|
|
|
4129
4185
|
function coworkMetaPathForTranscript(transcriptPath) {
|
|
4130
4186
|
const marker = `${path8.sep}.claude${path8.sep}projects${path8.sep}`;
|
|
4131
4187
|
const index = transcriptPath.indexOf(marker);
|
|
4132
|
-
if (index
|
|
4188
|
+
if (index === -1) {
|
|
4133
4189
|
return void 0;
|
|
4134
4190
|
}
|
|
4135
4191
|
return `${transcriptPath.slice(0, index)}.json`;
|
|
@@ -4144,7 +4200,7 @@ function projectFromMeta(meta) {
|
|
|
4144
4200
|
}
|
|
4145
4201
|
const resolved = path8.resolve(folder);
|
|
4146
4202
|
return {
|
|
4147
|
-
project: path8.basename(resolved).
|
|
4203
|
+
project: path8.basename(resolved).replaceAll("-", "_") || "cowork",
|
|
4148
4204
|
cwd: resolved
|
|
4149
4205
|
};
|
|
4150
4206
|
}
|
|
@@ -4269,7 +4325,7 @@ function createClaudeCoworkAdapter() {
|
|
|
4269
4325
|
}
|
|
4270
4326
|
|
|
4271
4327
|
// src/adapters/codebuddy.ts
|
|
4272
|
-
import {
|
|
4328
|
+
import { readdir as readdir4, readFile as readFile5 } from "node:fs/promises";
|
|
4273
4329
|
import path9 from "node:path";
|
|
4274
4330
|
var ENDPOINT_MODEL_ID_RE = /^(?:ep|endpoint)-/i;
|
|
4275
4331
|
async function parseCodebuddyTraceFile(filePath, options) {
|
|
@@ -4504,6 +4560,28 @@ async function parseCodebuddyTraceFile(filePath, options) {
|
|
|
4504
4560
|
sourceId: span.spanId
|
|
4505
4561
|
})
|
|
4506
4562
|
}), index, "function");
|
|
4563
|
+
const toolInput = parseEmbeddedJson(span.toolInput);
|
|
4564
|
+
if (isPlainObject(toolInput)) {
|
|
4565
|
+
const fileActivities = claudeStyleToolFileActivities(tool, toolInput, ts, cwd);
|
|
4566
|
+
if (fileActivities.length > 0) {
|
|
4567
|
+
push(baseEvent({
|
|
4568
|
+
ts,
|
|
4569
|
+
type: eventTypeFromFileActivities(fileActivities),
|
|
4570
|
+
operation: `${tool} file activity`,
|
|
4571
|
+
sessionId,
|
|
4572
|
+
cwd,
|
|
4573
|
+
project,
|
|
4574
|
+
model,
|
|
4575
|
+
tool,
|
|
4576
|
+
confidence: "derived",
|
|
4577
|
+
fileActivities,
|
|
4578
|
+
metrics: summarizeFileActivities(fileActivities),
|
|
4579
|
+
refs: stringRefs({
|
|
4580
|
+
sourceId: span.spanId
|
|
4581
|
+
})
|
|
4582
|
+
}), index, "function");
|
|
4583
|
+
}
|
|
4584
|
+
}
|
|
4507
4585
|
if (span.endedAt) {
|
|
4508
4586
|
const durationMs = span.duration ?? void 0;
|
|
4509
4587
|
push(baseEvent({
|
|
@@ -4527,30 +4605,28 @@ async function parseCodebuddyTraceFile(filePath, options) {
|
|
|
4527
4605
|
})
|
|
4528
4606
|
}), index, "function");
|
|
4529
4607
|
}
|
|
4530
|
-
if (tool === "Bash") {
|
|
4531
|
-
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
|
|
4540
|
-
|
|
4541
|
-
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
}), index, "function");
|
|
4553
|
-
}
|
|
4608
|
+
if (tool === "Bash" && span.endedAt) {
|
|
4609
|
+
const durationMs = span.duration ?? void 0;
|
|
4610
|
+
push(baseEvent({
|
|
4611
|
+
ts: span.endedAt,
|
|
4612
|
+
type: toolSuccess ? "command.completed" : "command.failed",
|
|
4613
|
+
operation: "Bash completed",
|
|
4614
|
+
sessionId,
|
|
4615
|
+
cwd,
|
|
4616
|
+
project,
|
|
4617
|
+
model,
|
|
4618
|
+
tool,
|
|
4619
|
+
success: toolSuccess,
|
|
4620
|
+
confidence: "derived",
|
|
4621
|
+
metrics: {
|
|
4622
|
+
commandCalls: 1,
|
|
4623
|
+
commandDurationMs: durationMs,
|
|
4624
|
+
durationMs
|
|
4625
|
+
},
|
|
4626
|
+
refs: stringRefs({
|
|
4627
|
+
sourceId: span.spanId
|
|
4628
|
+
})
|
|
4629
|
+
}), index, "function");
|
|
4554
4630
|
}
|
|
4555
4631
|
continue;
|
|
4556
4632
|
}
|
|
@@ -4755,7 +4831,6 @@ async function resolveSessionIdFromSiblingTraces(filePath) {
|
|
|
4755
4831
|
}
|
|
4756
4832
|
} catch {
|
|
4757
4833
|
}
|
|
4758
|
-
return void 0;
|
|
4759
4834
|
})();
|
|
4760
4835
|
siblingSessionIdByDir.set(dir, cached);
|
|
4761
4836
|
}
|
|
@@ -4949,6 +5024,33 @@ import { readFile as readFile6 } from "node:fs/promises";
|
|
|
4949
5024
|
import path11 from "node:path";
|
|
4950
5025
|
|
|
4951
5026
|
// src/lib/diff.ts
|
|
5027
|
+
function parseApplyPatch(patch, ts) {
|
|
5028
|
+
const changes = [];
|
|
5029
|
+
let current;
|
|
5030
|
+
for (const line of patch.split("\n")) {
|
|
5031
|
+
const fileMatch = line.match(/^\*\*\* (Add|Update|Delete) File: (.+)$/);
|
|
5032
|
+
if (fileMatch) {
|
|
5033
|
+
current = {
|
|
5034
|
+
ts,
|
|
5035
|
+
path: fileMatch[2].trim(),
|
|
5036
|
+
operation: fileMatch[1] === "Add" ? "create" : fileMatch[1] === "Delete" ? "delete" : "edit",
|
|
5037
|
+
linesAdded: 0,
|
|
5038
|
+
linesRemoved: 0
|
|
5039
|
+
};
|
|
5040
|
+
changes.push(current);
|
|
5041
|
+
continue;
|
|
5042
|
+
}
|
|
5043
|
+
if (!current) {
|
|
5044
|
+
continue;
|
|
5045
|
+
}
|
|
5046
|
+
if (line.startsWith("+") && !line.startsWith("+++")) {
|
|
5047
|
+
current.linesAdded = (current.linesAdded || 0) + 1;
|
|
5048
|
+
} else if (line.startsWith("-") && !line.startsWith("---")) {
|
|
5049
|
+
current.linesRemoved = (current.linesRemoved || 0) + 1;
|
|
5050
|
+
}
|
|
5051
|
+
}
|
|
5052
|
+
return changes;
|
|
5053
|
+
}
|
|
4952
5054
|
function diffStats(diff) {
|
|
4953
5055
|
let linesAdded = 0;
|
|
4954
5056
|
let linesRemoved = 0;
|
|
@@ -4992,10 +5094,10 @@ function fileActivitiesFromPatchChanges(changes, ts, cwd, displayFilePath3) {
|
|
|
4992
5094
|
}
|
|
4993
5095
|
|
|
4994
5096
|
// src/lib/session-context.ts
|
|
4995
|
-
init_fs();
|
|
4996
5097
|
import { mkdir as mkdir3, writeFile as writeFile3 } from "node:fs/promises";
|
|
4997
5098
|
import os4 from "node:os";
|
|
4998
5099
|
import path10 from "node:path";
|
|
5100
|
+
init_fs();
|
|
4999
5101
|
var SESSION_CONTEXT_VERSION = 1;
|
|
5000
5102
|
function sessionContextDir(home) {
|
|
5001
5103
|
return path10.join(home, ".vibetime", "session-context");
|
|
@@ -5814,7 +5916,7 @@ async function parseCopilotSessionFile(filePath, options) {
|
|
|
5814
5916
|
model = msgModel;
|
|
5815
5917
|
}
|
|
5816
5918
|
const msgTurnId = stringField(data, "turnId");
|
|
5817
|
-
const turnId = msgTurnId
|
|
5919
|
+
const turnId = msgTurnId === void 0 ? currentTurnId : `turn_${createStableHash([sessionId, msgTurnId]).slice(0, 24)}`;
|
|
5818
5920
|
events.push(baseCopilotEvent({
|
|
5819
5921
|
ts,
|
|
5820
5922
|
type: "agent.operation",
|
|
@@ -5841,7 +5943,7 @@ async function parseCopilotSessionFile(filePath, options) {
|
|
|
5841
5943
|
const toolCallId = stringField(data, "toolCallId");
|
|
5842
5944
|
const toolName = stringField(data, "toolName") || "tool";
|
|
5843
5945
|
const toolTurnId = stringField(data, "turnId");
|
|
5844
|
-
const turnId = toolTurnId
|
|
5946
|
+
const turnId = toolTurnId === void 0 ? currentTurnId : `turn_${createStableHash([sessionId, toolTurnId]).slice(0, 24)}`;
|
|
5845
5947
|
if (toolCallId) {
|
|
5846
5948
|
pendingTools.set(toolCallId, { tool: toolName, startedAt: ts, turnId });
|
|
5847
5949
|
}
|
|
@@ -5859,6 +5961,24 @@ async function parseCopilotSessionFile(filePath, options) {
|
|
|
5859
5961
|
metrics: { toolCalls: 1 },
|
|
5860
5962
|
refs: stringRefs({ sourceId: toolCallId })
|
|
5861
5963
|
}));
|
|
5964
|
+
const fileActivities = copilotFileActivities(toolName, data.arguments, ts, cwd);
|
|
5965
|
+
if (fileActivities.length > 0) {
|
|
5966
|
+
events.push(baseCopilotEvent({
|
|
5967
|
+
ts,
|
|
5968
|
+
type: eventTypeFromFileActivities(fileActivities),
|
|
5969
|
+
operation: `${toolName} file activity`,
|
|
5970
|
+
sessionId,
|
|
5971
|
+
turnId,
|
|
5972
|
+
cwd,
|
|
5973
|
+
project,
|
|
5974
|
+
model,
|
|
5975
|
+
tool: toolName,
|
|
5976
|
+
confidence: "derived",
|
|
5977
|
+
fileActivities,
|
|
5978
|
+
metrics: summarizeFileActivities(fileActivities),
|
|
5979
|
+
refs: stringRefs({ sourceId: toolCallId })
|
|
5980
|
+
}));
|
|
5981
|
+
}
|
|
5862
5982
|
break;
|
|
5863
5983
|
}
|
|
5864
5984
|
case "tool.execution_complete": {
|
|
@@ -5881,7 +6001,7 @@ async function parseCopilotSessionFile(filePath, options) {
|
|
|
5881
6001
|
tool: pending?.tool,
|
|
5882
6002
|
success,
|
|
5883
6003
|
confidence: "exact",
|
|
5884
|
-
metrics: durationMs
|
|
6004
|
+
metrics: durationMs === void 0 ? void 0 : { toolDurationMs: durationMs, durationMs },
|
|
5885
6005
|
refs: stringRefs({ sourceId: toolCallId })
|
|
5886
6006
|
}));
|
|
5887
6007
|
const toolLower = (pending?.tool || "").toLowerCase();
|
|
@@ -5910,7 +6030,7 @@ async function parseCopilotSessionFile(filePath, options) {
|
|
|
5910
6030
|
}
|
|
5911
6031
|
case "assistant.turn_end": {
|
|
5912
6032
|
const endTurnId = stringField(data, "turnId");
|
|
5913
|
-
const turnId = endTurnId
|
|
6033
|
+
const turnId = endTurnId === void 0 ? currentTurnId : `turn_${createStableHash([sessionId, endTurnId]).slice(0, 24)}`;
|
|
5914
6034
|
const accum = turnId ? turnTokenAccum.get(turnId) : void 0;
|
|
5915
6035
|
if (accum && accum.tokensOutput && accum.tokensOutput > 0) {
|
|
5916
6036
|
accum.reasoningEffort = reasoningEffort;
|
|
@@ -5997,6 +6117,29 @@ async function parseCopilotSessionFile(filePath, options) {
|
|
|
5997
6117
|
}
|
|
5998
6118
|
return events.filter((event) => validateCanonicalEvent(event).valid);
|
|
5999
6119
|
}
|
|
6120
|
+
function copilotFileActivities(tool, args, ts, cwd) {
|
|
6121
|
+
const normalized = tool.toLowerCase();
|
|
6122
|
+
if (normalized === "apply_patch" && typeof args === "string") {
|
|
6123
|
+
return parseApplyPatch(args, ts);
|
|
6124
|
+
}
|
|
6125
|
+
if (!isPlainObject(args)) {
|
|
6126
|
+
return [];
|
|
6127
|
+
}
|
|
6128
|
+
const changes = /* @__PURE__ */ new Map();
|
|
6129
|
+
const filePath = stringField(args, "path") || stringField(args, "file_path");
|
|
6130
|
+
if (filePath) {
|
|
6131
|
+
const metrics = {};
|
|
6132
|
+
if (normalized === "edit") {
|
|
6133
|
+
const oldStr = stringField(args, "old_str");
|
|
6134
|
+
const newStr = stringField(args, "new_str");
|
|
6135
|
+
metrics.linesAdded = countTextLines(newStr);
|
|
6136
|
+
metrics.linesRemoved = countTextLines(oldStr);
|
|
6137
|
+
metrics.charsWritten = newStr?.length;
|
|
6138
|
+
}
|
|
6139
|
+
addResolvedPathActivity(changes, filePath, operationForTool(normalized === "view" ? "read" : tool), ts, cwd, cwd, metrics);
|
|
6140
|
+
}
|
|
6141
|
+
return [...changes.values()];
|
|
6142
|
+
}
|
|
6000
6143
|
function baseCopilotEvent(event) {
|
|
6001
6144
|
return {
|
|
6002
6145
|
schemaVersion: AGENT_TIME_SCHEMA_VERSION,
|
|
@@ -6205,7 +6348,7 @@ async function parseGrokSessionFile(filePath, options) {
|
|
|
6205
6348
|
}
|
|
6206
6349
|
if (type === "turn_started") {
|
|
6207
6350
|
const turnNumber = numberField(raw, "turn_number");
|
|
6208
|
-
currentTurnId = turnNumber
|
|
6351
|
+
currentTurnId = turnNumber === void 0 ? `turn_${createStableHash([sessionId, lineNumber]).slice(0, 24)}` : `turn_${turnNumber}`;
|
|
6209
6352
|
currentTurnStartedAt = ts;
|
|
6210
6353
|
const turnModel = stringField(raw, "model_id") || model;
|
|
6211
6354
|
push(base({
|
|
@@ -6229,7 +6372,7 @@ async function parseGrokSessionFile(filePath, options) {
|
|
|
6229
6372
|
turnId,
|
|
6230
6373
|
success,
|
|
6231
6374
|
confidence: "exact",
|
|
6232
|
-
metrics: durationMs
|
|
6375
|
+
metrics: durationMs === void 0 ? void 0 : { durationMs },
|
|
6233
6376
|
refs: stringRefs({
|
|
6234
6377
|
sourceId: `${sessionId}:${turnId || "turn"}:ended`,
|
|
6235
6378
|
outcome
|
|
@@ -6374,7 +6517,7 @@ function resolveSessionDir(filePath) {
|
|
|
6374
6517
|
if (base === "summary.json" || base === "events.jsonl" || base === "signals.json") {
|
|
6375
6518
|
return path13.dirname(filePath);
|
|
6376
6519
|
}
|
|
6377
|
-
if (
|
|
6520
|
+
if (/^[0-9a-f]{8}-[0-9a-f-]{27,}$/i.test(base)) {
|
|
6378
6521
|
return filePath;
|
|
6379
6522
|
}
|
|
6380
6523
|
return void 0;
|
|
@@ -7381,6 +7524,18 @@ function piFileActivitiesFromToolCall(tool, input, ts, cwd) {
|
|
|
7381
7524
|
addResolvedPathActivity(changes, filePath, operation, ts, cwd, cwd, piToolFileMetrics(normalized, input));
|
|
7382
7525
|
}
|
|
7383
7526
|
}
|
|
7527
|
+
if (normalized === "edit") {
|
|
7528
|
+
const filePath = stringField(input, "path") || stringField(input, "file_path") || stringField(input, "filePath");
|
|
7529
|
+
for (const edit of Array.isArray(input.edits) ? input.edits : []) {
|
|
7530
|
+
if (!isPlainObject(edit) || !filePath) {
|
|
7531
|
+
continue;
|
|
7532
|
+
}
|
|
7533
|
+
addResolvedPathActivity(changes, filePath, "edit", ts, cwd, cwd, {
|
|
7534
|
+
linesAdded: countTextLines(stringField(edit, "newText") || stringField(edit, "new_text")),
|
|
7535
|
+
linesRemoved: countTextLines(stringField(edit, "oldText") || stringField(edit, "old_text"))
|
|
7536
|
+
});
|
|
7537
|
+
}
|
|
7538
|
+
}
|
|
7384
7539
|
if (normalized === "bash" || normalized === "run") {
|
|
7385
7540
|
const command = stringField(input, "command");
|
|
7386
7541
|
if (command) {
|
|
@@ -8069,7 +8224,7 @@ async function parseQoderCnSessionFile(filePath, options) {
|
|
|
8069
8224
|
const toolUseId = stringField(toolUse, "id") || `tool_${createStableHash([filePath, lineNumber, tool]).slice(0, 24)}`;
|
|
8070
8225
|
const input = objectField(toolUse, "input");
|
|
8071
8226
|
const command = stringField(input, "command");
|
|
8072
|
-
const fileActivities =
|
|
8227
|
+
const fileActivities = claudeStyleToolFileActivities(tool, input, ts, cwd);
|
|
8073
8228
|
const agentInstanceId = tool === "Agent" ? `agent_${createStableHash([sessionId, toolUseId]).slice(0, 24)}` : void 0;
|
|
8074
8229
|
pendingTools.set(toolUseId, {
|
|
8075
8230
|
id: toolUseId,
|
|
@@ -8206,62 +8361,6 @@ function qoderCnSubagentMetrics(toolResult, fallbackDurationMs) {
|
|
|
8206
8361
|
tokensTotal: numberField(toolResult, "totalTokens") || totalInputTokens + outputTokens || void 0
|
|
8207
8362
|
};
|
|
8208
8363
|
}
|
|
8209
|
-
function fileActivitiesFromQoderCnToolUse(tool, input, ts, cwd) {
|
|
8210
|
-
const changes = /* @__PURE__ */ new Map();
|
|
8211
|
-
const operation = operationForTool(tool);
|
|
8212
|
-
const workdir = stringField(input, "cwd") || cwd;
|
|
8213
|
-
for (const key of ["file_path", "path", "notebook_path"]) {
|
|
8214
|
-
const filePath = stringField(input, key);
|
|
8215
|
-
if (!filePath) {
|
|
8216
|
-
continue;
|
|
8217
|
-
}
|
|
8218
|
-
const metrics = fileMetricsFromQoderCnToolInput(tool, input);
|
|
8219
|
-
addResolvedPathActivity(changes, filePath, operation, ts, cwd, workdir, metrics);
|
|
8220
|
-
}
|
|
8221
|
-
for (const edit of [...arrayField4(input, "edits"), ...arrayField4(input, "replacements")]) {
|
|
8222
|
-
if (!isPlainObject(edit)) {
|
|
8223
|
-
continue;
|
|
8224
|
-
}
|
|
8225
|
-
const filePath = stringField(input, "file_path") || stringField(input, "path");
|
|
8226
|
-
if (!filePath) {
|
|
8227
|
-
continue;
|
|
8228
|
-
}
|
|
8229
|
-
addResolvedPathActivity(changes, filePath, "edit", ts, cwd, workdir, {
|
|
8230
|
-
linesAdded: countTextLines(stringField(edit, "new_string") || stringField(edit, "new_text")),
|
|
8231
|
-
linesRemoved: countTextLines(stringField(edit, "old_string") || stringField(edit, "original_text"))
|
|
8232
|
-
});
|
|
8233
|
-
}
|
|
8234
|
-
const command = stringField(input, "command");
|
|
8235
|
-
if (command) {
|
|
8236
|
-
for (const item of fileActivitiesFromShellCommand(command, ts, cwd, workdir)) {
|
|
8237
|
-
changes.set(item.path, mergeFileActivity(changes.get(item.path), item));
|
|
8238
|
-
}
|
|
8239
|
-
}
|
|
8240
|
-
return [...changes.values()];
|
|
8241
|
-
}
|
|
8242
|
-
function fileMetricsFromQoderCnToolInput(tool, input) {
|
|
8243
|
-
const normalized = tool.toLowerCase();
|
|
8244
|
-
if (normalized === "read") {
|
|
8245
|
-
return { linesRead: numberField(input, "limit") };
|
|
8246
|
-
}
|
|
8247
|
-
if (normalized === "write") {
|
|
8248
|
-
const content = stringField(input, "content") || stringField(input, "file_content");
|
|
8249
|
-
return {
|
|
8250
|
-
linesAdded: countTextLines(content),
|
|
8251
|
-
charsWritten: content?.length
|
|
8252
|
-
};
|
|
8253
|
-
}
|
|
8254
|
-
if (normalized === "edit" || normalized === "multiedit" || normalized === "searchreplace") {
|
|
8255
|
-
const oldString = stringField(input, "old_string");
|
|
8256
|
-
const newString = stringField(input, "new_string");
|
|
8257
|
-
return {
|
|
8258
|
-
linesAdded: countTextLines(newString),
|
|
8259
|
-
linesRemoved: countTextLines(oldString),
|
|
8260
|
-
charsWritten: newString?.length
|
|
8261
|
-
};
|
|
8262
|
-
}
|
|
8263
|
-
return {};
|
|
8264
|
-
}
|
|
8265
8364
|
function arrayField4(object, key) {
|
|
8266
8365
|
if (!isPlainObject(object) || !Array.isArray(object[key])) {
|
|
8267
8366
|
return [];
|
|
@@ -8422,7 +8521,7 @@ function qoderCnProjectRootFromCwds(projectDir, cwds) {
|
|
|
8422
8521
|
return void 0;
|
|
8423
8522
|
}
|
|
8424
8523
|
function encodeQoderCnProjectPath(value) {
|
|
8425
|
-
return path17.resolve(value).split(path17.sep).join("-").
|
|
8524
|
+
return path17.resolve(value).split(path17.sep).join("-").replaceAll("_", "-");
|
|
8426
8525
|
}
|
|
8427
8526
|
async function qoderCnProjectFromFilePath(filePath, options) {
|
|
8428
8527
|
const projectDir = path17.basename(path17.dirname(filePath));
|
|
@@ -8903,7 +9002,7 @@ async function parseQoderSessionFile(filePath, options) {
|
|
|
8903
9002
|
const toolUseId = stringField(toolUse, "id") || `tool_${createStableHash([filePath, lineNumber, tool]).slice(0, 24)}`;
|
|
8904
9003
|
const input = objectField(toolUse, "input");
|
|
8905
9004
|
const command = stringField(input, "command");
|
|
8906
|
-
const fileActivities =
|
|
9005
|
+
const fileActivities = claudeStyleToolFileActivities(tool, input, ts, cwd);
|
|
8907
9006
|
const agentInstanceId = tool === "Agent" ? `agent_${createStableHash([sessionId, toolUseId]).slice(0, 24)}` : void 0;
|
|
8908
9007
|
pendingTools.set(toolUseId, {
|
|
8909
9008
|
id: toolUseId,
|
|
@@ -9040,62 +9139,6 @@ function qoderSubagentMetrics(toolResult, fallbackDurationMs) {
|
|
|
9040
9139
|
tokensTotal: numberField(toolResult, "totalTokens") || totalInputTokens + outputTokens || void 0
|
|
9041
9140
|
};
|
|
9042
9141
|
}
|
|
9043
|
-
function fileActivitiesFromQoderToolUse(tool, input, ts, cwd) {
|
|
9044
|
-
const changes = /* @__PURE__ */ new Map();
|
|
9045
|
-
const operation = operationForTool(tool);
|
|
9046
|
-
const workdir = stringField(input, "cwd") || cwd;
|
|
9047
|
-
for (const key of ["file_path", "path", "notebook_path"]) {
|
|
9048
|
-
const filePath = stringField(input, key);
|
|
9049
|
-
if (!filePath) {
|
|
9050
|
-
continue;
|
|
9051
|
-
}
|
|
9052
|
-
const metrics = fileMetricsFromQoderToolInput(tool, input);
|
|
9053
|
-
addResolvedPathActivity(changes, filePath, operation, ts, cwd, workdir, metrics);
|
|
9054
|
-
}
|
|
9055
|
-
for (const edit of [...arrayField5(input, "edits"), ...arrayField5(input, "replacements")]) {
|
|
9056
|
-
if (!isPlainObject(edit)) {
|
|
9057
|
-
continue;
|
|
9058
|
-
}
|
|
9059
|
-
const filePath = stringField(input, "file_path") || stringField(input, "path");
|
|
9060
|
-
if (!filePath) {
|
|
9061
|
-
continue;
|
|
9062
|
-
}
|
|
9063
|
-
addResolvedPathActivity(changes, filePath, "edit", ts, cwd, workdir, {
|
|
9064
|
-
linesAdded: countTextLines(stringField(edit, "new_string") || stringField(edit, "new_text")),
|
|
9065
|
-
linesRemoved: countTextLines(stringField(edit, "old_string") || stringField(edit, "original_text"))
|
|
9066
|
-
});
|
|
9067
|
-
}
|
|
9068
|
-
const command = stringField(input, "command");
|
|
9069
|
-
if (command) {
|
|
9070
|
-
for (const item of fileActivitiesFromShellCommand(command, ts, cwd, workdir)) {
|
|
9071
|
-
changes.set(item.path, mergeFileActivity(changes.get(item.path), item));
|
|
9072
|
-
}
|
|
9073
|
-
}
|
|
9074
|
-
return [...changes.values()];
|
|
9075
|
-
}
|
|
9076
|
-
function fileMetricsFromQoderToolInput(tool, input) {
|
|
9077
|
-
const normalized = tool.toLowerCase();
|
|
9078
|
-
if (normalized === "read") {
|
|
9079
|
-
return { linesRead: numberField(input, "limit") };
|
|
9080
|
-
}
|
|
9081
|
-
if (normalized === "write") {
|
|
9082
|
-
const content = stringField(input, "content") || stringField(input, "file_content");
|
|
9083
|
-
return {
|
|
9084
|
-
linesAdded: countTextLines(content),
|
|
9085
|
-
charsWritten: content?.length
|
|
9086
|
-
};
|
|
9087
|
-
}
|
|
9088
|
-
if (normalized === "edit" || normalized === "multiedit" || normalized === "searchreplace") {
|
|
9089
|
-
const oldString = stringField(input, "old_string");
|
|
9090
|
-
const newString = stringField(input, "new_string");
|
|
9091
|
-
return {
|
|
9092
|
-
linesAdded: countTextLines(newString),
|
|
9093
|
-
linesRemoved: countTextLines(oldString),
|
|
9094
|
-
charsWritten: newString?.length
|
|
9095
|
-
};
|
|
9096
|
-
}
|
|
9097
|
-
return {};
|
|
9098
|
-
}
|
|
9099
9142
|
function arrayField5(object, key) {
|
|
9100
9143
|
if (!isPlainObject(object) || !Array.isArray(object[key])) {
|
|
9101
9144
|
return [];
|
|
@@ -9222,14 +9265,14 @@ function qoderProjectRootFromCwds(projectDir, cwds) {
|
|
|
9222
9265
|
return void 0;
|
|
9223
9266
|
}
|
|
9224
9267
|
function encodeQoderProjectPath(value) {
|
|
9225
|
-
return path18.resolve(value).split(path18.sep).join("-").
|
|
9268
|
+
return path18.resolve(value).split(path18.sep).join("-").replaceAll("_", "-");
|
|
9226
9269
|
}
|
|
9227
9270
|
function rawQoderProjectPath(value) {
|
|
9228
9271
|
return path18.resolve(value).split(path18.sep).join("-");
|
|
9229
9272
|
}
|
|
9230
9273
|
function qoderEncodedVariants(value) {
|
|
9231
9274
|
const raw = rawQoderProjectPath(value);
|
|
9232
|
-
const normalized = raw.
|
|
9275
|
+
const normalized = raw.replaceAll("_", "-");
|
|
9233
9276
|
return raw === normalized ? [raw] : [raw, normalized];
|
|
9234
9277
|
}
|
|
9235
9278
|
function qoderEncodedProjectSuffix(projectDir, home) {
|
|
@@ -9385,7 +9428,7 @@ function normalizeId(id) {
|
|
|
9385
9428
|
}
|
|
9386
9429
|
|
|
9387
9430
|
// src/adapters/workbuddy.ts
|
|
9388
|
-
import {
|
|
9431
|
+
import { readdir as readdir9, readFile as readFile12, stat as stat10 } from "node:fs/promises";
|
|
9389
9432
|
import path19 from "node:path";
|
|
9390
9433
|
function workbuddyProjectsDir(home, env) {
|
|
9391
9434
|
const override = env?.WORKBUDDY_PROJECTS_DIR || env?.WORKBUDDY_HOME;
|
|
@@ -9591,7 +9634,9 @@ async function parseWorkbuddySessionFile(filePath, options) {
|
|
|
9591
9634
|
confidence: "derived",
|
|
9592
9635
|
refs: { sourceId: `${sessionPrefix}:session`, ...subagentRefs }
|
|
9593
9636
|
}, lines[0], filePath, options);
|
|
9594
|
-
if (event)
|
|
9637
|
+
if (event) {
|
|
9638
|
+
events.push(event);
|
|
9639
|
+
}
|
|
9595
9640
|
}
|
|
9596
9641
|
for (const line of lines) {
|
|
9597
9642
|
const record = line.record;
|
|
@@ -9606,7 +9651,9 @@ async function parseWorkbuddySessionFile(filePath, options) {
|
|
|
9606
9651
|
continue;
|
|
9607
9652
|
}
|
|
9608
9653
|
const ended = closeTurn(line);
|
|
9609
|
-
if (ended)
|
|
9654
|
+
if (ended) {
|
|
9655
|
+
events.push(ended);
|
|
9656
|
+
}
|
|
9610
9657
|
turnIndex += 1;
|
|
9611
9658
|
currentTurnId = `${sessionPrefix}:turn:${turnIndex}`;
|
|
9612
9659
|
turnLastTs = ts;
|
|
@@ -9644,7 +9691,9 @@ async function parseWorkbuddySessionFile(filePath, options) {
|
|
|
9644
9691
|
refs: { sourceId: `${sourceId}:prompt` }
|
|
9645
9692
|
}, line, filePath, options)
|
|
9646
9693
|
]) {
|
|
9647
|
-
if (event)
|
|
9694
|
+
if (event) {
|
|
9695
|
+
events.push(event);
|
|
9696
|
+
}
|
|
9648
9697
|
}
|
|
9649
9698
|
continue;
|
|
9650
9699
|
}
|
|
@@ -9671,7 +9720,9 @@ async function parseWorkbuddySessionFile(filePath, options) {
|
|
|
9671
9720
|
confidence: "partial",
|
|
9672
9721
|
refs: { sourceId: `${sourceId}:usage` }
|
|
9673
9722
|
}, line, filePath, options);
|
|
9674
|
-
if (usage)
|
|
9723
|
+
if (usage) {
|
|
9724
|
+
events.push(usage);
|
|
9725
|
+
}
|
|
9675
9726
|
}
|
|
9676
9727
|
continue;
|
|
9677
9728
|
}
|
|
@@ -9698,7 +9749,40 @@ async function parseWorkbuddySessionFile(filePath, options) {
|
|
|
9698
9749
|
confidence: "exact",
|
|
9699
9750
|
refs: { sourceId: `${callId}:start` }
|
|
9700
9751
|
}, line, filePath, options);
|
|
9701
|
-
if (started)
|
|
9752
|
+
if (started) {
|
|
9753
|
+
events.push(started);
|
|
9754
|
+
}
|
|
9755
|
+
let toolInput;
|
|
9756
|
+
try {
|
|
9757
|
+
toolInput = JSON.parse(stringField(record, "arguments") || "");
|
|
9758
|
+
} catch {
|
|
9759
|
+
toolInput = void 0;
|
|
9760
|
+
}
|
|
9761
|
+
if (isPlainObject(toolInput)) {
|
|
9762
|
+
const fileActivities = claudeStyleToolFileActivities(tool, toolInput, ts, cwd);
|
|
9763
|
+
if (fileActivities.length > 0) {
|
|
9764
|
+
const fileEvent = makeEvent({
|
|
9765
|
+
schemaVersion: AGENT_TIME_SCHEMA_VERSION,
|
|
9766
|
+
ts,
|
|
9767
|
+
type: eventTypeFromFileActivities(fileActivities),
|
|
9768
|
+
source: "workbuddy",
|
|
9769
|
+
workspaceId,
|
|
9770
|
+
project,
|
|
9771
|
+
cwd,
|
|
9772
|
+
sessionId: sessionPrefix,
|
|
9773
|
+
turnId: currentTurnId,
|
|
9774
|
+
agent: "workbuddy",
|
|
9775
|
+
tool,
|
|
9776
|
+
confidence: "derived",
|
|
9777
|
+
fileActivities,
|
|
9778
|
+
metrics: summarizeFileActivities(fileActivities),
|
|
9779
|
+
refs: { sourceId: `${callId}:files` }
|
|
9780
|
+
}, line, filePath, options);
|
|
9781
|
+
if (fileEvent) {
|
|
9782
|
+
events.push(fileEvent);
|
|
9783
|
+
}
|
|
9784
|
+
}
|
|
9785
|
+
}
|
|
9702
9786
|
}
|
|
9703
9787
|
const metrics = workbuddyUsageMetrics(record);
|
|
9704
9788
|
const model = stringField(objectField(record, "providerData"), "model");
|
|
@@ -9719,7 +9803,9 @@ async function parseWorkbuddySessionFile(filePath, options) {
|
|
|
9719
9803
|
confidence: metrics ? "partial" : "derived",
|
|
9720
9804
|
refs: { sourceId: `${sourceId}:usage:${callId || line.lineNumber}` }
|
|
9721
9805
|
}, line, filePath, options);
|
|
9722
|
-
if (usage)
|
|
9806
|
+
if (usage) {
|
|
9807
|
+
events.push(usage);
|
|
9808
|
+
}
|
|
9723
9809
|
}
|
|
9724
9810
|
continue;
|
|
9725
9811
|
}
|
|
@@ -9748,13 +9834,17 @@ async function parseWorkbuddySessionFile(filePath, options) {
|
|
|
9748
9834
|
confidence: start ? "derived" : "partial",
|
|
9749
9835
|
refs: { sourceId: `${callId}:result` }
|
|
9750
9836
|
}, line, filePath, options);
|
|
9751
|
-
if (completed)
|
|
9837
|
+
if (completed) {
|
|
9838
|
+
events.push(completed);
|
|
9839
|
+
}
|
|
9752
9840
|
}
|
|
9753
9841
|
}
|
|
9754
9842
|
const lastLine = lines.at(-1);
|
|
9755
9843
|
if (lastLine) {
|
|
9756
9844
|
const ended = closeTurn(lastLine);
|
|
9757
|
-
if (ended)
|
|
9845
|
+
if (ended) {
|
|
9846
|
+
events.push(ended);
|
|
9847
|
+
}
|
|
9758
9848
|
}
|
|
9759
9849
|
const lastTs = lastLine ? timestampFrom(numberField(lastLine.record, "timestamp")) : void 0;
|
|
9760
9850
|
if (lastLine && lastTs) {
|
|
@@ -9771,7 +9861,9 @@ async function parseWorkbuddySessionFile(filePath, options) {
|
|
|
9771
9861
|
confidence: "derived",
|
|
9772
9862
|
refs: { sourceId: `${sessionPrefix}:ended` }
|
|
9773
9863
|
}, lastLine, filePath, options);
|
|
9774
|
-
if (event)
|
|
9864
|
+
if (event) {
|
|
9865
|
+
events.push(event);
|
|
9866
|
+
}
|
|
9775
9867
|
}
|
|
9776
9868
|
return events;
|
|
9777
9869
|
}
|
|
@@ -12425,8 +12517,8 @@ function selectBackfillFilesForImport(files, watermarkTs) {
|
|
|
12425
12517
|
}
|
|
12426
12518
|
}
|
|
12427
12519
|
const order = /* @__PURE__ */ new Map();
|
|
12428
|
-
for (
|
|
12429
|
-
order.set(
|
|
12520
|
+
for (const [i, file] of files.entries()) {
|
|
12521
|
+
order.set(file.path, i);
|
|
12430
12522
|
}
|
|
12431
12523
|
picked.sort((a, b) => (order.get(a.path) ?? 0) - (order.get(b.path) ?? 0));
|
|
12432
12524
|
return picked;
|
package/package.json
CHANGED