@staff0rd/assist 0.461.3 → 0.463.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/sessions/web/bundle.js +418 -418
- package/dist/index.js +637 -254
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { Command } from "commander";
|
|
|
6
6
|
// package.json
|
|
7
7
|
var package_default = {
|
|
8
8
|
name: "@staff0rd/assist",
|
|
9
|
-
version: "0.
|
|
9
|
+
version: "0.463.0",
|
|
10
10
|
type: "module",
|
|
11
11
|
main: "dist/index.js",
|
|
12
12
|
bin: {
|
|
@@ -3365,7 +3365,7 @@ function collectHashComments(content, options2) {
|
|
|
3365
3365
|
function collectComments(sourceFile) {
|
|
3366
3366
|
const seen = /* @__PURE__ */ new Set();
|
|
3367
3367
|
const comments3 = [];
|
|
3368
|
-
const
|
|
3368
|
+
const collect5 = (node) => {
|
|
3369
3369
|
for (const range of [
|
|
3370
3370
|
...node.getLeadingCommentRanges(),
|
|
3371
3371
|
...node.getTrailingCommentRanges()
|
|
@@ -3376,8 +3376,8 @@ function collectComments(sourceFile) {
|
|
|
3376
3376
|
comments3.push({ pos, text: range.getText() });
|
|
3377
3377
|
}
|
|
3378
3378
|
};
|
|
3379
|
-
|
|
3380
|
-
sourceFile.forEachDescendant(
|
|
3379
|
+
collect5(sourceFile);
|
|
3380
|
+
sourceFile.forEachDescendant(collect5);
|
|
3381
3381
|
return comments3;
|
|
3382
3382
|
}
|
|
3383
3383
|
|
|
@@ -3596,16 +3596,19 @@ var WRAPPER_TYPES = /* @__PURE__ */ new Set([
|
|
|
3596
3596
|
"readonly",
|
|
3597
3597
|
"catch"
|
|
3598
3598
|
]);
|
|
3599
|
+
var OPTIONAL_TYPES = /* @__PURE__ */ new Set(["optional", "nullish"]);
|
|
3599
3600
|
function unwrapSchemaNode(node) {
|
|
3600
3601
|
let current = node;
|
|
3601
3602
|
let defaultValue;
|
|
3603
|
+
let optional = false;
|
|
3602
3604
|
while (current.def && WRAPPER_TYPES.has(current.def.type ?? "") && current.def.innerType) {
|
|
3603
3605
|
if (current.def.type === "default" && defaultValue === void 0) {
|
|
3604
3606
|
defaultValue = current.def.defaultValue;
|
|
3605
3607
|
}
|
|
3608
|
+
if (OPTIONAL_TYPES.has(current.def.type ?? "")) optional = true;
|
|
3606
3609
|
current = current.def.innerType;
|
|
3607
3610
|
}
|
|
3608
|
-
return { inner: current, defaultValue };
|
|
3611
|
+
return { inner: current, defaultValue, optional };
|
|
3609
3612
|
}
|
|
3610
3613
|
|
|
3611
3614
|
// src/shared/scalarUnionMembers.ts
|
|
@@ -3649,7 +3652,67 @@ function scalarArrayItemType(node) {
|
|
|
3649
3652
|
return isScalarLeafType(type) ? type : void 0;
|
|
3650
3653
|
}
|
|
3651
3654
|
|
|
3652
|
-
// src/shared/
|
|
3655
|
+
// src/shared/listConfigNode.ts
|
|
3656
|
+
function scalarListNode(inner, base, item) {
|
|
3657
|
+
const itemType = scalarArrayItemType(inner);
|
|
3658
|
+
if (!itemType || item.kind !== "scalar") return void 0;
|
|
3659
|
+
return { ...base, kind: "scalarList", itemType, item };
|
|
3660
|
+
}
|
|
3661
|
+
function objectListNode(base, item) {
|
|
3662
|
+
if (item.kind !== "object" && item.kind !== "unionOfObjects")
|
|
3663
|
+
return void 0;
|
|
3664
|
+
return { ...base, kind: "objectList", item };
|
|
3665
|
+
}
|
|
3666
|
+
function listConfigNode(inner, base, build2) {
|
|
3667
|
+
const element = inner.def?.element;
|
|
3668
|
+
if (inner.def?.type !== "array" || !element) return void 0;
|
|
3669
|
+
const item = build2(element, [...base.path, { kind: "item" }]);
|
|
3670
|
+
return scalarListNode(inner, base, item) ?? objectListNode(base, item);
|
|
3671
|
+
}
|
|
3672
|
+
|
|
3673
|
+
// src/shared/objectConfigNode.ts
|
|
3674
|
+
function objectConfigNode(inner, base, build2) {
|
|
3675
|
+
const shape = inner.def?.shape;
|
|
3676
|
+
if (inner.def?.type !== "object" || !shape) return void 0;
|
|
3677
|
+
const fields = Object.entries(shape).map(
|
|
3678
|
+
([name, child]) => build2(child, [...base.path, { kind: "key", name }])
|
|
3679
|
+
);
|
|
3680
|
+
return { ...base, kind: "object", fields };
|
|
3681
|
+
}
|
|
3682
|
+
function unionOfObjectsConfigNode(inner, base, build2) {
|
|
3683
|
+
const options2 = inner.def?.options;
|
|
3684
|
+
if (inner.def?.type !== "union" || !options2?.length) return void 0;
|
|
3685
|
+
const variants = [];
|
|
3686
|
+
for (const option of options2) {
|
|
3687
|
+
const variant = build2(option, base.path);
|
|
3688
|
+
if (variant.kind !== "object") return void 0;
|
|
3689
|
+
variants.push(variant);
|
|
3690
|
+
}
|
|
3691
|
+
return { ...base, kind: "unionOfObjects", variants };
|
|
3692
|
+
}
|
|
3693
|
+
|
|
3694
|
+
// src/shared/recordConfigNode.ts
|
|
3695
|
+
function recordConfigNode(inner, base, build2) {
|
|
3696
|
+
const valueType = inner.def?.valueType;
|
|
3697
|
+
if (inner.def?.type !== "record" || !valueType) return void 0;
|
|
3698
|
+
const value = build2(valueType, [...base.path, { kind: "entry" }]);
|
|
3699
|
+
return { ...base, kind: "record", value };
|
|
3700
|
+
}
|
|
3701
|
+
|
|
3702
|
+
// src/shared/scalarConfigNode.ts
|
|
3703
|
+
function scalarConfigNode(inner, base) {
|
|
3704
|
+
const unionTypes = scalarUnionMembers(inner);
|
|
3705
|
+
if (unionTypes) return { ...base, kind: "scalar", type: "union", unionTypes };
|
|
3706
|
+
const type = leafTypeOf(inner);
|
|
3707
|
+
if (!isScalarLeafType(type)) return void 0;
|
|
3708
|
+
const values = type === "enum" ? enumValues(inner) : void 0;
|
|
3709
|
+
return {
|
|
3710
|
+
...base,
|
|
3711
|
+
kind: "scalar",
|
|
3712
|
+
type,
|
|
3713
|
+
...values ? { enumValues: values } : {}
|
|
3714
|
+
};
|
|
3715
|
+
}
|
|
3653
3716
|
function enumValues(node) {
|
|
3654
3717
|
const entries = node.def?.entries;
|
|
3655
3718
|
if (!entries) return void 0;
|
|
@@ -3657,31 +3720,81 @@ function enumValues(node) {
|
|
|
3657
3720
|
(value) => typeof value === "string"
|
|
3658
3721
|
);
|
|
3659
3722
|
}
|
|
3660
|
-
|
|
3661
|
-
|
|
3662
|
-
|
|
3663
|
-
|
|
3664
|
-
|
|
3665
|
-
|
|
3666
|
-
const
|
|
3667
|
-
|
|
3668
|
-
|
|
3723
|
+
|
|
3724
|
+
// src/shared/describeConfigNode.ts
|
|
3725
|
+
function opaqueConfigNode(inner, base) {
|
|
3726
|
+
return { ...base, kind: "other", type: leafTypeOf(inner) };
|
|
3727
|
+
}
|
|
3728
|
+
function build(node, path71) {
|
|
3729
|
+
const { inner, defaultValue, optional } = unwrapSchemaNode(node);
|
|
3730
|
+
const base = {
|
|
3731
|
+
path: path71,
|
|
3732
|
+
...optional ? { optional: true } : {},
|
|
3733
|
+
...defaultValue === void 0 ? {} : { defaultValue }
|
|
3734
|
+
};
|
|
3735
|
+
return scalarConfigNode(inner, base) ?? objectConfigNode(inner, base, build) ?? listConfigNode(inner, base, build) ?? recordConfigNode(inner, base, build) ?? unionOfObjectsConfigNode(inner, base, build) ?? opaqueConfigNode(inner, base);
|
|
3736
|
+
}
|
|
3737
|
+
function describeConfigNode(schema2) {
|
|
3738
|
+
return build(schema2, []);
|
|
3739
|
+
}
|
|
3740
|
+
|
|
3741
|
+
// src/shared/formatConfigPath.ts
|
|
3742
|
+
var RECORD_ENTRY_TOKEN = "*";
|
|
3743
|
+
function segmentText(segment) {
|
|
3744
|
+
if (segment.kind === "key") return segment.name;
|
|
3745
|
+
if (segment.kind === "entry") return RECORD_ENTRY_TOKEN;
|
|
3746
|
+
if (segment.kind === "index") return `[${segment.index}]`;
|
|
3747
|
+
return "[]";
|
|
3748
|
+
}
|
|
3749
|
+
function formatConfigPath(path71) {
|
|
3750
|
+
let text17 = "";
|
|
3751
|
+
for (const segment of path71) {
|
|
3752
|
+
const dotted = segment.kind === "key" || segment.kind === "entry";
|
|
3753
|
+
const rendered = segmentText(segment);
|
|
3754
|
+
text17 += dotted && text17 ? `.${rendered}` : rendered;
|
|
3755
|
+
}
|
|
3756
|
+
return text17;
|
|
3757
|
+
}
|
|
3758
|
+
|
|
3759
|
+
// src/shared/describeConfigLeaves.ts
|
|
3760
|
+
function leafType(node) {
|
|
3761
|
+
switch (node.kind) {
|
|
3762
|
+
case "scalar":
|
|
3763
|
+
return node.type;
|
|
3764
|
+
case "scalarList":
|
|
3765
|
+
case "objectList":
|
|
3766
|
+
return "array";
|
|
3767
|
+
case "record":
|
|
3768
|
+
return "record";
|
|
3769
|
+
case "other":
|
|
3770
|
+
return node.type;
|
|
3771
|
+
default:
|
|
3772
|
+
return "other";
|
|
3773
|
+
}
|
|
3774
|
+
}
|
|
3775
|
+
function toLeaf(node) {
|
|
3776
|
+
const leaf = {
|
|
3777
|
+
key: formatConfigPath(node.path),
|
|
3778
|
+
type: leafType(node)
|
|
3779
|
+
};
|
|
3780
|
+
if (node.kind === "scalar") {
|
|
3781
|
+
if (node.enumValues) leaf.enumValues = node.enumValues;
|
|
3782
|
+
if (node.unionTypes) leaf.unionTypes = node.unionTypes;
|
|
3783
|
+
}
|
|
3784
|
+
if (node.kind === "scalarList") leaf.itemType = node.itemType;
|
|
3785
|
+
if (node.defaultValue !== void 0) leaf.defaultValue = node.defaultValue;
|
|
3669
3786
|
return leaf;
|
|
3670
3787
|
}
|
|
3671
|
-
function
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
if (inner.def?.type === "object" && shape) {
|
|
3675
|
-
for (const [key, child] of Object.entries(shape)) {
|
|
3676
|
-
collect(child, prefix2 ? `${prefix2}.${key}` : key, out);
|
|
3677
|
-
}
|
|
3788
|
+
function flatten(node, out) {
|
|
3789
|
+
if (node.kind === "object") {
|
|
3790
|
+
for (const field of node.fields) flatten(field, out);
|
|
3678
3791
|
return;
|
|
3679
3792
|
}
|
|
3680
|
-
out.push(toLeaf(
|
|
3793
|
+
out.push(toLeaf(node));
|
|
3681
3794
|
}
|
|
3682
3795
|
function describeConfigLeaves(schema2) {
|
|
3683
3796
|
const out = [];
|
|
3684
|
-
|
|
3797
|
+
flatten(describeConfigNode(schema2), out);
|
|
3685
3798
|
return out.sort((a, b) => a.key < b.key ? -1 : a.key > b.key ? 1 : 0);
|
|
3686
3799
|
}
|
|
3687
3800
|
|
|
@@ -3773,9 +3886,9 @@ function forbiddenStrings() {
|
|
|
3773
3886
|
console.log("No forbidden-strings rules configured.");
|
|
3774
3887
|
process.exit(0);
|
|
3775
3888
|
}
|
|
3776
|
-
const
|
|
3889
|
+
const cache5 = /* @__PURE__ */ new Map();
|
|
3777
3890
|
const readJson = (file) => {
|
|
3778
|
-
if (
|
|
3891
|
+
if (cache5.has(file)) return cache5.get(file);
|
|
3779
3892
|
if (!existsSync12(file)) {
|
|
3780
3893
|
console.log(`Forbidden-strings file not found: ${file}`);
|
|
3781
3894
|
process.exit(1);
|
|
@@ -3787,7 +3900,7 @@ function forbiddenStrings() {
|
|
|
3787
3900
|
console.log(`Could not parse ${file}: ${error.message}`);
|
|
3788
3901
|
process.exit(1);
|
|
3789
3902
|
}
|
|
3790
|
-
|
|
3903
|
+
cache5.set(file, parsed);
|
|
3791
3904
|
return parsed;
|
|
3792
3905
|
};
|
|
3793
3906
|
const violations = findForbiddenStrings(rules, readJson);
|
|
@@ -8456,19 +8569,19 @@ import { dirname as dirname19, join as join23 } from "path";
|
|
|
8456
8569
|
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
8457
8570
|
function createBundleHandler(importMetaUrl, bundlePath, contentType = "application/javascript") {
|
|
8458
8571
|
const file = join23(dirname19(fileURLToPath4(importMetaUrl)), bundlePath);
|
|
8459
|
-
let
|
|
8572
|
+
let cache5;
|
|
8460
8573
|
return (req, res) => {
|
|
8461
8574
|
const mtimeMs = statSync2(file).mtimeMs;
|
|
8462
|
-
if (
|
|
8575
|
+
if (cache5?.mtimeMs !== mtimeMs) {
|
|
8463
8576
|
const body = readFileSync19(file, "utf8");
|
|
8464
8577
|
const etag = `"${createHash("sha256").update(body).digest("hex").slice(0, 16)}"`;
|
|
8465
|
-
|
|
8578
|
+
cache5 = { body, etag, mtimeMs };
|
|
8466
8579
|
}
|
|
8467
8580
|
const headers = {
|
|
8468
|
-
ETag:
|
|
8581
|
+
ETag: cache5.etag,
|
|
8469
8582
|
"Cache-Control": "no-cache"
|
|
8470
8583
|
};
|
|
8471
|
-
if (req.headers["if-none-match"] ===
|
|
8584
|
+
if (req.headers["if-none-match"] === cache5.etag) {
|
|
8472
8585
|
res.writeHead(304, headers);
|
|
8473
8586
|
res.end();
|
|
8474
8587
|
return;
|
|
@@ -8477,7 +8590,7 @@ function createBundleHandler(importMetaUrl, bundlePath, contentType = "applicati
|
|
|
8477
8590
|
"Content-Type": contentType,
|
|
8478
8591
|
...headers
|
|
8479
8592
|
});
|
|
8480
|
-
res.end(
|
|
8593
|
+
res.end(cache5.body);
|
|
8481
8594
|
};
|
|
8482
8595
|
}
|
|
8483
8596
|
|
|
@@ -8971,67 +9084,119 @@ function getSessionParam(req) {
|
|
|
8971
9084
|
return url.searchParams.get("session") ?? void 0;
|
|
8972
9085
|
}
|
|
8973
9086
|
|
|
8974
|
-
// src/shared/db/findCommitAnchor.ts
|
|
8975
|
-
import { and as and7, asc as asc6, eq as eq16, inArray as inArray3 } from "drizzle-orm";
|
|
8976
|
-
async function findCommitAnchor(db, itemId2) {
|
|
8977
|
-
const rows = await db.select({ kind: itemGitRefs.kind, ref: itemGitRefs.ref }).from(itemGitRefs).where(
|
|
8978
|
-
and7(
|
|
8979
|
-
eq16(itemGitRefs.itemId, itemId2),
|
|
8980
|
-
inArray3(itemGitRefs.kind, ["commit", "commit-parent"])
|
|
8981
|
-
)
|
|
8982
|
-
).orderBy(asc6(itemGitRefs.createdAt));
|
|
8983
|
-
const anchor = {};
|
|
8984
|
-
for (const row of rows) {
|
|
8985
|
-
if (row.kind === "commit") anchor.commit ??= row.ref;
|
|
8986
|
-
else anchor.parent ??= row.ref;
|
|
8987
|
-
}
|
|
8988
|
-
return anchor;
|
|
8989
|
-
}
|
|
8990
|
-
|
|
8991
9087
|
// src/shared/db/findItemBySessionId.ts
|
|
8992
|
-
import { asc as
|
|
9088
|
+
import { asc as asc6, eq as eq16 } from "drizzle-orm";
|
|
8993
9089
|
async function findItemBySessionId(db, claudeSessionId) {
|
|
8994
|
-
const rows = await db.select({ itemId: phaseUsage.itemId }).from(phaseUsage).where(
|
|
9090
|
+
const rows = await db.select({ itemId: phaseUsage.itemId }).from(phaseUsage).where(eq16(phaseUsage.claudeSessionId, claudeSessionId)).orderBy(asc6(phaseUsage.itemId), asc6(phaseUsage.phaseIdx)).limit(1);
|
|
8995
9091
|
return rows[0]?.itemId;
|
|
8996
9092
|
}
|
|
8997
9093
|
|
|
8998
|
-
// src/
|
|
8999
|
-
|
|
9000
|
-
|
|
9001
|
-
|
|
9002
|
-
|
|
9003
|
-
|
|
9004
|
-
|
|
9005
|
-
|
|
9006
|
-
|
|
9007
|
-
|
|
9008
|
-
|
|
9009
|
-
|
|
9010
|
-
|
|
9011
|
-
return lookup;
|
|
9012
|
-
}
|
|
9013
|
-
async function loadAnchor(sessionId) {
|
|
9014
|
-
const anchor = await queryAnchor(sessionId);
|
|
9015
|
-
const found = Boolean(anchor.commit || anchor.parent);
|
|
9016
|
-
cache3.set(sessionId, {
|
|
9017
|
-
anchor,
|
|
9018
|
-
expiresAt: found ? Number.POSITIVE_INFINITY : Date.now() + EMPTY_TTL_MS
|
|
9019
|
-
});
|
|
9020
|
-
return anchor;
|
|
9094
|
+
// src/shared/db/listCommitRefs.ts
|
|
9095
|
+
import { and as and7, asc as asc7, eq as eq17 } from "drizzle-orm";
|
|
9096
|
+
async function listCommitRefs(db, itemId2) {
|
|
9097
|
+
const rows = await db.select({
|
|
9098
|
+
ref: itemGitRefs.ref,
|
|
9099
|
+
title: itemGitRefs.title,
|
|
9100
|
+
url: itemGitRefs.url
|
|
9101
|
+
}).from(itemGitRefs).where(and7(eq17(itemGitRefs.itemId, itemId2), eq17(itemGitRefs.kind, "commit"))).orderBy(asc7(itemGitRefs.createdAt), asc7(itemGitRefs.ref));
|
|
9102
|
+
return rows.map((row) => ({
|
|
9103
|
+
sha: row.ref,
|
|
9104
|
+
...row.title ? { title: row.title } : {},
|
|
9105
|
+
...row.url ? { url: row.url } : {}
|
|
9106
|
+
}));
|
|
9021
9107
|
}
|
|
9022
|
-
|
|
9108
|
+
|
|
9109
|
+
// src/commands/sessions/web/itemCommits.ts
|
|
9110
|
+
async function itemCommits(sessionId) {
|
|
9023
9111
|
try {
|
|
9024
9112
|
if (!process.env.ASSIST_DATABASE_URL && !loadConfig().database.url)
|
|
9025
|
-
return
|
|
9113
|
+
return [];
|
|
9026
9114
|
const db = await getDb();
|
|
9027
9115
|
const itemId2 = await findItemBySessionId(db, sessionId);
|
|
9028
|
-
if (itemId2 === void 0) return
|
|
9029
|
-
return await
|
|
9116
|
+
if (itemId2 === void 0) return [];
|
|
9117
|
+
return await listCommitRefs(db, itemId2);
|
|
9030
9118
|
} catch {
|
|
9031
|
-
return
|
|
9119
|
+
return [];
|
|
9032
9120
|
}
|
|
9033
9121
|
}
|
|
9034
9122
|
|
|
9123
|
+
// src/commands/sessions/web/resolveCommit.ts
|
|
9124
|
+
var GIT_EMPTY_TREE_HASH = "4b825dc642cb6eb9a060e54bf8d69288fbee4904";
|
|
9125
|
+
async function resolveCommit(cwd, sha) {
|
|
9126
|
+
if (!await commitExists(cwd, sha)) return void 0;
|
|
9127
|
+
const parent = await parentOf(cwd, sha);
|
|
9128
|
+
return {
|
|
9129
|
+
base: parent ?? GIT_EMPTY_TREE_HASH,
|
|
9130
|
+
paths: await commitPaths(cwd, sha)
|
|
9131
|
+
};
|
|
9132
|
+
}
|
|
9133
|
+
async function commitExists(cwd, sha) {
|
|
9134
|
+
try {
|
|
9135
|
+
await execGit(cwd, ["cat-file", "-e", `${sha}^{commit}`]);
|
|
9136
|
+
return true;
|
|
9137
|
+
} catch {
|
|
9138
|
+
return false;
|
|
9139
|
+
}
|
|
9140
|
+
}
|
|
9141
|
+
async function parentOf(cwd, sha) {
|
|
9142
|
+
try {
|
|
9143
|
+
const parent = await execGit(cwd, [
|
|
9144
|
+
"rev-parse",
|
|
9145
|
+
"--verify",
|
|
9146
|
+
"--quiet",
|
|
9147
|
+
`${sha}^`
|
|
9148
|
+
]);
|
|
9149
|
+
return parent.trim() || void 0;
|
|
9150
|
+
} catch {
|
|
9151
|
+
return void 0;
|
|
9152
|
+
}
|
|
9153
|
+
}
|
|
9154
|
+
async function commitPaths(cwd, sha) {
|
|
9155
|
+
try {
|
|
9156
|
+
const output = await execGit(cwd, [
|
|
9157
|
+
"diff-tree",
|
|
9158
|
+
"--no-commit-id",
|
|
9159
|
+
"--name-only",
|
|
9160
|
+
"-r",
|
|
9161
|
+
"--root",
|
|
9162
|
+
sha
|
|
9163
|
+
]);
|
|
9164
|
+
return output.split("\n").filter(Boolean);
|
|
9165
|
+
} catch {
|
|
9166
|
+
return [];
|
|
9167
|
+
}
|
|
9168
|
+
}
|
|
9169
|
+
|
|
9170
|
+
// src/commands/sessions/web/committedPaths.ts
|
|
9171
|
+
var cache3 = /* @__PURE__ */ new Map();
|
|
9172
|
+
var inFlight = /* @__PURE__ */ new Map();
|
|
9173
|
+
var CACHE_TTL_MS = 1e4;
|
|
9174
|
+
async function committedPaths(cwd, sessionId) {
|
|
9175
|
+
const key = `${cwd} ${sessionId}`;
|
|
9176
|
+
const cached = cache3.get(key);
|
|
9177
|
+
if (cached && cached.expiresAt > Date.now()) return cached.value;
|
|
9178
|
+
const pending = inFlight.get(key);
|
|
9179
|
+
if (pending) return pending;
|
|
9180
|
+
const lookup = loadCommittedPaths(cwd, sessionId).then((value) => {
|
|
9181
|
+
cache3.set(key, { value, expiresAt: Date.now() + CACHE_TTL_MS });
|
|
9182
|
+
return value;
|
|
9183
|
+
}).finally(() => inFlight.delete(key));
|
|
9184
|
+
inFlight.set(key, lookup);
|
|
9185
|
+
return lookup;
|
|
9186
|
+
}
|
|
9187
|
+
async function loadCommittedPaths(cwd, sessionId) {
|
|
9188
|
+
const commits2 = await itemCommits(sessionId);
|
|
9189
|
+
const bases = /* @__PURE__ */ new Map();
|
|
9190
|
+
for (const commit2 of commits2) {
|
|
9191
|
+
const resolved = await resolveCommit(cwd, commit2.sha);
|
|
9192
|
+
if (!resolved) continue;
|
|
9193
|
+
for (const path71 of resolved.paths) {
|
|
9194
|
+
if (!bases.has(path71)) bases.set(path71, resolved.base);
|
|
9195
|
+
}
|
|
9196
|
+
}
|
|
9197
|
+
return { commits: commits2, bases };
|
|
9198
|
+
}
|
|
9199
|
+
|
|
9035
9200
|
// src/commands/sessions/web/windowsCwdToWslPath.ts
|
|
9036
9201
|
function windowsCwdToWslPath(cwd) {
|
|
9037
9202
|
const match = /^([A-Za-z]):[\\/](.*)$/.exec(cwd);
|
|
@@ -9046,55 +9211,37 @@ function toGitCwd(cwd) {
|
|
|
9046
9211
|
return detectPlatform() === "wsl" ? windowsCwdToWslPath(cwd) : cwd;
|
|
9047
9212
|
}
|
|
9048
9213
|
|
|
9049
|
-
// src/commands/sessions/web/
|
|
9050
|
-
function
|
|
9051
|
-
return
|
|
9052
|
-
|
|
9053
|
-
|
|
9054
|
-
|
|
9055
|
-
|
|
9056
|
-
|
|
9057
|
-
|
|
9058
|
-
].filter((candidate) => Boolean(candidate));
|
|
9214
|
+
// src/commands/sessions/web/itemChangeSet.ts
|
|
9215
|
+
async function itemChangeSet(cwd, sessionId) {
|
|
9216
|
+
if (!sessionId || !includesCommittedChanges(cwd)) return void 0;
|
|
9217
|
+
const { commits: commits2, bases } = await committedPaths(cwd, sessionId);
|
|
9218
|
+
if (bases.size === 0) return void 0;
|
|
9219
|
+
const groups = groupByBase(bases);
|
|
9220
|
+
const dirty = await dirtyPaths(cwd, bases);
|
|
9221
|
+
if (dirty.length > 0) groups.push({ base: "HEAD", paths: dirty });
|
|
9222
|
+
return { commits: commits2, groups };
|
|
9059
9223
|
}
|
|
9060
|
-
|
|
9224
|
+
function includesCommittedChanges(cwd) {
|
|
9061
9225
|
try {
|
|
9062
|
-
|
|
9063
|
-
|
|
9226
|
+
return Boolean(
|
|
9227
|
+
loadConfigFrom(toGitCwd(cwd)).sessions?.includeCommittedChanges
|
|
9228
|
+
);
|
|
9064
9229
|
} catch {
|
|
9065
9230
|
return false;
|
|
9066
9231
|
}
|
|
9067
9232
|
}
|
|
9068
|
-
|
|
9069
|
-
const
|
|
9070
|
-
|
|
9071
|
-
|
|
9072
|
-
|
|
9073
|
-
|
|
9074
|
-
async function resolveDiffBase(cwd, sessionId) {
|
|
9075
|
-
let defaultBranch;
|
|
9076
|
-
try {
|
|
9077
|
-
const config = loadConfigFrom(toGitCwd(cwd));
|
|
9078
|
-
if (!config.sessions?.includeCommittedChanges) return "HEAD";
|
|
9079
|
-
defaultBranch = config.branch?.defaultBranch;
|
|
9080
|
-
} catch {
|
|
9081
|
-
return "HEAD";
|
|
9082
|
-
}
|
|
9083
|
-
if (sessionId) {
|
|
9084
|
-
const anchored = await anchoredBase(cwd, sessionId);
|
|
9085
|
-
if (anchored) return anchored;
|
|
9086
|
-
}
|
|
9087
|
-
for (const candidate of baseCandidates(defaultBranch)) {
|
|
9088
|
-
if (!await refExists2(cwd, candidate)) continue;
|
|
9089
|
-
try {
|
|
9090
|
-
const base = await execGit(cwd, ["merge-base", "HEAD", candidate]);
|
|
9091
|
-
const sha = base.trim();
|
|
9092
|
-
if (sha) return sha;
|
|
9093
|
-
} catch {
|
|
9094
|
-
}
|
|
9095
|
-
return "HEAD";
|
|
9233
|
+
function groupByBase(bases) {
|
|
9234
|
+
const groups = /* @__PURE__ */ new Map();
|
|
9235
|
+
for (const [path71, base] of bases) {
|
|
9236
|
+
const paths = groups.get(base);
|
|
9237
|
+
if (paths) paths.push(path71);
|
|
9238
|
+
else groups.set(base, [path71]);
|
|
9096
9239
|
}
|
|
9097
|
-
return
|
|
9240
|
+
return [...groups].map(([base, paths]) => ({ base, paths: paths.sort() }));
|
|
9241
|
+
}
|
|
9242
|
+
async function dirtyPaths(cwd, bases) {
|
|
9243
|
+
const output = await execGit(cwd, ["diff", "--name-only", "HEAD"]);
|
|
9244
|
+
return output.split("\n").filter((path71) => path71 && !bases.has(path71)).sort();
|
|
9098
9245
|
}
|
|
9099
9246
|
|
|
9100
9247
|
// src/commands/sessions/web/diff.ts
|
|
@@ -9117,14 +9264,26 @@ async function untrackedDiff(cwd) {
|
|
|
9117
9264
|
);
|
|
9118
9265
|
return diffs.join("");
|
|
9119
9266
|
}
|
|
9267
|
+
async function groupedDiff(cwd, groups) {
|
|
9268
|
+
const diffs = await Promise.all(
|
|
9269
|
+
groups.map(
|
|
9270
|
+
(group) => execGit(cwd, ["diff", group.base, "--", ...group.paths], {
|
|
9271
|
+
maxBuffer: MAX_DIFF_BYTES
|
|
9272
|
+
})
|
|
9273
|
+
)
|
|
9274
|
+
);
|
|
9275
|
+
return diffs.join("");
|
|
9276
|
+
}
|
|
9277
|
+
async function trackedDiff(cwd, session) {
|
|
9278
|
+
const changeSet = await itemChangeSet(cwd, session);
|
|
9279
|
+
if (changeSet) return groupedDiff(cwd, changeSet.groups);
|
|
9280
|
+
return execGit(cwd, ["diff", "HEAD"], { maxBuffer: MAX_DIFF_BYTES });
|
|
9281
|
+
}
|
|
9120
9282
|
async function diff2(req, res) {
|
|
9121
9283
|
const cwd = getCwdParam(req, res);
|
|
9122
9284
|
if (!cwd) return;
|
|
9123
9285
|
try {
|
|
9124
|
-
const
|
|
9125
|
-
const tracked = await execGit(cwd, ["diff", base], {
|
|
9126
|
-
maxBuffer: MAX_DIFF_BYTES
|
|
9127
|
-
});
|
|
9286
|
+
const tracked = await trackedDiff(cwd, getSessionParam(req));
|
|
9128
9287
|
const untracked = await untrackedDiff(cwd);
|
|
9129
9288
|
res.writeHead(200, { "Content-Type": "text/plain; charset=utf-8" });
|
|
9130
9289
|
res.end(tracked + untracked);
|
|
@@ -9224,16 +9383,104 @@ function resolveConfigSource(key, layers) {
|
|
|
9224
9383
|
return "default";
|
|
9225
9384
|
}
|
|
9226
9385
|
|
|
9386
|
+
// src/shared/configNodeFieldName.ts
|
|
9387
|
+
function configNodeFieldName(node) {
|
|
9388
|
+
const last = node.path.at(-1);
|
|
9389
|
+
return last?.kind === "key" ? last.name : void 0;
|
|
9390
|
+
}
|
|
9391
|
+
|
|
9392
|
+
// src/shared/findConfigNode.ts
|
|
9393
|
+
function objectField(node, segment) {
|
|
9394
|
+
if (segment.kind !== "key") return void 0;
|
|
9395
|
+
return node.fields.find(
|
|
9396
|
+
(field) => configNodeFieldName(field) === segment.name
|
|
9397
|
+
);
|
|
9398
|
+
}
|
|
9399
|
+
function variantField(node, segment) {
|
|
9400
|
+
for (const variant of node.variants) {
|
|
9401
|
+
const found = objectField(variant, segment);
|
|
9402
|
+
if (found) return found;
|
|
9403
|
+
}
|
|
9404
|
+
return void 0;
|
|
9405
|
+
}
|
|
9406
|
+
function step(node, segment) {
|
|
9407
|
+
const intoItem = segment.kind === "item" || segment.kind === "index";
|
|
9408
|
+
const intoEntry = segment.kind === "entry" || segment.kind === "key";
|
|
9409
|
+
switch (node.kind) {
|
|
9410
|
+
case "object":
|
|
9411
|
+
return objectField(node, segment);
|
|
9412
|
+
case "unionOfObjects":
|
|
9413
|
+
return variantField(node, segment);
|
|
9414
|
+
case "objectList":
|
|
9415
|
+
case "scalarList":
|
|
9416
|
+
return intoItem ? node.item : void 0;
|
|
9417
|
+
case "record":
|
|
9418
|
+
return intoEntry ? node.value : void 0;
|
|
9419
|
+
default:
|
|
9420
|
+
return void 0;
|
|
9421
|
+
}
|
|
9422
|
+
}
|
|
9423
|
+
function findConfigNode(root, path71) {
|
|
9424
|
+
let current = root;
|
|
9425
|
+
for (const segment of path71) {
|
|
9426
|
+
if (!current) return void 0;
|
|
9427
|
+
current = step(current, segment);
|
|
9428
|
+
}
|
|
9429
|
+
return current;
|
|
9430
|
+
}
|
|
9431
|
+
|
|
9432
|
+
// src/shared/parseConfigPath.ts
|
|
9433
|
+
var INDEX = /^\d+$/;
|
|
9434
|
+
function bracketSegment(inner) {
|
|
9435
|
+
if (inner === "") return { kind: "item" };
|
|
9436
|
+
return INDEX.test(inner) ? { kind: "index", index: Number(inner) } : void 0;
|
|
9437
|
+
}
|
|
9438
|
+
function nameSegment(name) {
|
|
9439
|
+
return name === RECORD_ENTRY_TOKEN ? { kind: "entry" } : { kind: "key", name };
|
|
9440
|
+
}
|
|
9441
|
+
function parseConfigPath(text17) {
|
|
9442
|
+
const path71 = [];
|
|
9443
|
+
let at2 = 0;
|
|
9444
|
+
while (at2 < text17.length) {
|
|
9445
|
+
if (text17[at2] === "[") {
|
|
9446
|
+
const close = text17.indexOf("]", at2);
|
|
9447
|
+
const segment = close === -1 ? void 0 : bracketSegment(text17.slice(at2 + 1, close));
|
|
9448
|
+
if (!segment) return void 0;
|
|
9449
|
+
path71.push(segment);
|
|
9450
|
+
at2 = close + 1;
|
|
9451
|
+
continue;
|
|
9452
|
+
}
|
|
9453
|
+
if (text17[at2] === ".") {
|
|
9454
|
+
if (path71.length === 0) return void 0;
|
|
9455
|
+
at2 += 1;
|
|
9456
|
+
}
|
|
9457
|
+
const start3 = at2;
|
|
9458
|
+
while (at2 < text17.length && text17[at2] !== "." && text17[at2] !== "[") at2 += 1;
|
|
9459
|
+
const name = text17.slice(start3, at2);
|
|
9460
|
+
if (!name) return void 0;
|
|
9461
|
+
path71.push(nameSegment(name));
|
|
9462
|
+
}
|
|
9463
|
+
return path71;
|
|
9464
|
+
}
|
|
9465
|
+
|
|
9466
|
+
// src/commands/config/configEntryNode.ts
|
|
9467
|
+
function configEntryNode(root, key) {
|
|
9468
|
+
const path71 = parseConfigPath(key);
|
|
9469
|
+
return path71 ? findConfigNode(root, path71) : void 0;
|
|
9470
|
+
}
|
|
9471
|
+
|
|
9227
9472
|
// src/commands/config/readConfigEntries.ts
|
|
9228
9473
|
var KEYS_STRIPPED_FROM_MERGED_CONFIG = /* @__PURE__ */ new Set(["repos"]);
|
|
9229
9474
|
function readConfigEntries(cwd) {
|
|
9230
9475
|
const config = loadConfigFrom(cwd);
|
|
9231
9476
|
const layers = readRawConfigLayers(cwd);
|
|
9477
|
+
const schema2 = describeConfigNode(assistConfigSchema);
|
|
9232
9478
|
return describeConfigLeaves(assistConfigSchema).filter((leaf) => !KEYS_STRIPPED_FROM_MERGED_CONFIG.has(leaf.key)).map((leaf) => ({
|
|
9233
9479
|
...leaf,
|
|
9234
9480
|
value: getNestedValue(config, leaf.key),
|
|
9235
9481
|
source: resolveConfigSource(leaf.key, layers),
|
|
9236
|
-
globalOnly: isGlobalOnlyConfigKey(leaf.key)
|
|
9482
|
+
globalOnly: isGlobalOnlyConfigKey(leaf.key),
|
|
9483
|
+
node: configEntryNode(schema2, leaf.key)
|
|
9237
9484
|
}));
|
|
9238
9485
|
}
|
|
9239
9486
|
|
|
@@ -9421,6 +9668,111 @@ function parseGitStatus(output) {
|
|
|
9421
9668
|
return result;
|
|
9422
9669
|
}
|
|
9423
9670
|
|
|
9671
|
+
// src/shared/db/findCommitAnchor.ts
|
|
9672
|
+
import { and as and8, asc as asc8, eq as eq18, inArray as inArray3 } from "drizzle-orm";
|
|
9673
|
+
async function findCommitAnchor(db, itemId2) {
|
|
9674
|
+
const rows = await db.select({ kind: itemGitRefs.kind, ref: itemGitRefs.ref }).from(itemGitRefs).where(
|
|
9675
|
+
and8(
|
|
9676
|
+
eq18(itemGitRefs.itemId, itemId2),
|
|
9677
|
+
inArray3(itemGitRefs.kind, ["commit", "commit-parent"])
|
|
9678
|
+
)
|
|
9679
|
+
).orderBy(asc8(itemGitRefs.createdAt));
|
|
9680
|
+
const anchor = {};
|
|
9681
|
+
for (const row of rows) {
|
|
9682
|
+
if (row.kind === "commit") anchor.commit ??= row.ref;
|
|
9683
|
+
else anchor.parent ??= row.ref;
|
|
9684
|
+
}
|
|
9685
|
+
return anchor;
|
|
9686
|
+
}
|
|
9687
|
+
|
|
9688
|
+
// src/commands/sessions/web/sessionCommitAnchor.ts
|
|
9689
|
+
var EMPTY_TTL_MS = 3e4;
|
|
9690
|
+
var cache4 = /* @__PURE__ */ new Map();
|
|
9691
|
+
var inFlight2 = /* @__PURE__ */ new Map();
|
|
9692
|
+
async function sessionCommitAnchor(sessionId) {
|
|
9693
|
+
const cached = cache4.get(sessionId);
|
|
9694
|
+
if (cached && cached.expiresAt > Date.now()) return cached.anchor;
|
|
9695
|
+
const pending = inFlight2.get(sessionId);
|
|
9696
|
+
if (pending) return pending;
|
|
9697
|
+
const lookup = loadAnchor(sessionId).finally(
|
|
9698
|
+
() => inFlight2.delete(sessionId)
|
|
9699
|
+
);
|
|
9700
|
+
inFlight2.set(sessionId, lookup);
|
|
9701
|
+
return lookup;
|
|
9702
|
+
}
|
|
9703
|
+
async function loadAnchor(sessionId) {
|
|
9704
|
+
const anchor = await queryAnchor(sessionId);
|
|
9705
|
+
const found = Boolean(anchor.commit || anchor.parent);
|
|
9706
|
+
cache4.set(sessionId, {
|
|
9707
|
+
anchor,
|
|
9708
|
+
expiresAt: found ? Number.POSITIVE_INFINITY : Date.now() + EMPTY_TTL_MS
|
|
9709
|
+
});
|
|
9710
|
+
return anchor;
|
|
9711
|
+
}
|
|
9712
|
+
async function queryAnchor(sessionId) {
|
|
9713
|
+
try {
|
|
9714
|
+
if (!process.env.ASSIST_DATABASE_URL && !loadConfig().database.url)
|
|
9715
|
+
return {};
|
|
9716
|
+
const db = await getDb();
|
|
9717
|
+
const itemId2 = await findItemBySessionId(db, sessionId);
|
|
9718
|
+
if (itemId2 === void 0) return {};
|
|
9719
|
+
return await findCommitAnchor(db, itemId2);
|
|
9720
|
+
} catch {
|
|
9721
|
+
return {};
|
|
9722
|
+
}
|
|
9723
|
+
}
|
|
9724
|
+
|
|
9725
|
+
// src/commands/sessions/web/resolveDiffBase.ts
|
|
9726
|
+
function baseCandidates(defaultBranch) {
|
|
9727
|
+
return [
|
|
9728
|
+
defaultBranch && `origin/${defaultBranch}`,
|
|
9729
|
+
defaultBranch,
|
|
9730
|
+
"origin/main",
|
|
9731
|
+
"origin/master",
|
|
9732
|
+
"main",
|
|
9733
|
+
"master"
|
|
9734
|
+
].filter((candidate) => Boolean(candidate));
|
|
9735
|
+
}
|
|
9736
|
+
async function refExists2(cwd, ref) {
|
|
9737
|
+
try {
|
|
9738
|
+
await execGit(cwd, ["rev-parse", "--verify", "--quiet", `${ref}^{commit}`]);
|
|
9739
|
+
return true;
|
|
9740
|
+
} catch {
|
|
9741
|
+
return false;
|
|
9742
|
+
}
|
|
9743
|
+
}
|
|
9744
|
+
async function anchoredBase(cwd, sessionId) {
|
|
9745
|
+
const { commit: commit2, parent } = await sessionCommitAnchor(sessionId);
|
|
9746
|
+
if (parent && await refExists2(cwd, parent)) return parent;
|
|
9747
|
+
if (commit2 && await refExists2(cwd, `${commit2}^`)) return `${commit2}^`;
|
|
9748
|
+
return void 0;
|
|
9749
|
+
}
|
|
9750
|
+
async function resolveDiffBase(cwd, sessionId) {
|
|
9751
|
+
let defaultBranch;
|
|
9752
|
+
try {
|
|
9753
|
+
const config = loadConfigFrom(toGitCwd(cwd));
|
|
9754
|
+
if (!config.sessions?.includeCommittedChanges) return "HEAD";
|
|
9755
|
+
defaultBranch = config.branch?.defaultBranch;
|
|
9756
|
+
} catch {
|
|
9757
|
+
return "HEAD";
|
|
9758
|
+
}
|
|
9759
|
+
if (sessionId) {
|
|
9760
|
+
const anchored = await anchoredBase(cwd, sessionId);
|
|
9761
|
+
if (anchored) return anchored;
|
|
9762
|
+
}
|
|
9763
|
+
for (const candidate of baseCandidates(defaultBranch)) {
|
|
9764
|
+
if (!await refExists2(cwd, candidate)) continue;
|
|
9765
|
+
try {
|
|
9766
|
+
const base = await execGit(cwd, ["merge-base", "HEAD", candidate]);
|
|
9767
|
+
const sha = base.trim();
|
|
9768
|
+
if (sha) return sha;
|
|
9769
|
+
} catch {
|
|
9770
|
+
}
|
|
9771
|
+
return "HEAD";
|
|
9772
|
+
}
|
|
9773
|
+
return "HEAD";
|
|
9774
|
+
}
|
|
9775
|
+
|
|
9424
9776
|
// src/commands/sessions/web/gitStatus.ts
|
|
9425
9777
|
async function untrackedPaths(cwd) {
|
|
9426
9778
|
const list5 = await execGit(cwd, [
|
|
@@ -9586,7 +9938,7 @@ function rankFilePaths(paths, query, limit) {
|
|
|
9586
9938
|
|
|
9587
9939
|
// src/commands/sessions/web/listFiles.ts
|
|
9588
9940
|
var MAX_RESULTS = 20;
|
|
9589
|
-
var
|
|
9941
|
+
var CACHE_TTL_MS2 = 5e3;
|
|
9590
9942
|
var LS_FILES_MAX_BUFFER = 32 * 1024 * 1024;
|
|
9591
9943
|
var fileListCache = /* @__PURE__ */ new Map();
|
|
9592
9944
|
async function repoFiles(cwd) {
|
|
@@ -9598,7 +9950,7 @@ async function repoFiles(cwd) {
|
|
|
9598
9950
|
{ maxBuffer: LS_FILES_MAX_BUFFER }
|
|
9599
9951
|
);
|
|
9600
9952
|
const files = [...new Set(output.split(/\r?\n/).filter(Boolean))];
|
|
9601
|
-
fileListCache.set(cwd, { files, expires: Date.now() +
|
|
9953
|
+
fileListCache.set(cwd, { files, expires: Date.now() + CACHE_TTL_MS2 });
|
|
9602
9954
|
return files;
|
|
9603
9955
|
}
|
|
9604
9956
|
async function listFiles(req, res) {
|
|
@@ -9737,14 +10089,14 @@ async function listNewsItems(_req, res) {
|
|
|
9737
10089
|
}
|
|
9738
10090
|
|
|
9739
10091
|
// src/shared/db/countUsagePeaks.ts
|
|
9740
|
-
import { count, eq as
|
|
10092
|
+
import { count, eq as eq19 } from "drizzle-orm";
|
|
9741
10093
|
async function countUsagePeaks(db, window) {
|
|
9742
|
-
const [row] = await db.select({ value: count() }).from(usagePeaks).where(window ?
|
|
10094
|
+
const [row] = await db.select({ value: count() }).from(usagePeaks).where(window ? eq19(usagePeaks.window, window) : void 0);
|
|
9743
10095
|
return row?.value ?? 0;
|
|
9744
10096
|
}
|
|
9745
10097
|
|
|
9746
10098
|
// src/shared/db/listUsagePeaks.ts
|
|
9747
|
-
import { and as
|
|
10099
|
+
import { and as and9, desc as desc2, eq as eq20, getTableColumns } from "drizzle-orm";
|
|
9748
10100
|
|
|
9749
10101
|
// src/shared/db/avgContextPerCycle.ts
|
|
9750
10102
|
import { count as count2, sql as sql16 } from "drizzle-orm";
|
|
@@ -9768,11 +10120,11 @@ async function listUsagePeaks(db, options2) {
|
|
|
9768
10120
|
phaseCount: avgContext.phaseCount
|
|
9769
10121
|
}).from(usagePeaks).leftJoin(
|
|
9770
10122
|
avgContext,
|
|
9771
|
-
|
|
9772
|
-
|
|
9773
|
-
|
|
10123
|
+
and9(
|
|
10124
|
+
eq20(usagePeaks.window, avgContext.window),
|
|
10125
|
+
eq20(usagePeaks.resetsAt, avgContext.resetsAt)
|
|
9774
10126
|
)
|
|
9775
|
-
).where(options2?.window ?
|
|
10127
|
+
).where(options2?.window ? eq20(usagePeaks.window, options2.window) : void 0).orderBy(
|
|
9776
10128
|
desc2(usagePeaks.resetsAt),
|
|
9777
10129
|
usagePeaks.window,
|
|
9778
10130
|
desc2(usagePeaks.createdAt),
|
|
@@ -9824,14 +10176,14 @@ async function openInCode(req, res) {
|
|
|
9824
10176
|
import { execFile as execFile5 } from "child_process";
|
|
9825
10177
|
import { promisify as promisify5 } from "util";
|
|
9826
10178
|
var execFileAsync4 = promisify5(execFile5);
|
|
9827
|
-
var
|
|
10179
|
+
var CACHE_TTL_MS3 = 3e4;
|
|
9828
10180
|
function createCachedGhJson(args, parse3, fallback, options2 = {}) {
|
|
9829
10181
|
const { cacheFallback = true } = options2;
|
|
9830
|
-
const
|
|
10182
|
+
const cache5 = /* @__PURE__ */ new Map();
|
|
9831
10183
|
return async (cwd, extraArgs = []) => {
|
|
9832
10184
|
const key = extraArgs.length ? `${cwd}\0${extraArgs.join("\0")}` : cwd;
|
|
9833
10185
|
const now = Date.now();
|
|
9834
|
-
const cached =
|
|
10186
|
+
const cached = cache5.get(key);
|
|
9835
10187
|
if (cached && cached.expires > now) return cached.value;
|
|
9836
10188
|
let value = fallback;
|
|
9837
10189
|
try {
|
|
@@ -9844,7 +10196,7 @@ function createCachedGhJson(args, parse3, fallback, options2 = {}) {
|
|
|
9844
10196
|
value = fallback;
|
|
9845
10197
|
}
|
|
9846
10198
|
if (cacheFallback || value !== fallback)
|
|
9847
|
-
|
|
10199
|
+
cache5.set(key, { value, expires: now + CACHE_TTL_MS3 });
|
|
9848
10200
|
return value;
|
|
9849
10201
|
};
|
|
9850
10202
|
}
|
|
@@ -10155,6 +10507,41 @@ function coerceString(key, raw) {
|
|
|
10155
10507
|
return { ok: false, error: `${key}: expected a string` };
|
|
10156
10508
|
}
|
|
10157
10509
|
|
|
10510
|
+
// src/shared/configLeafSchema.ts
|
|
10511
|
+
function configLeafSchema(schema2, key) {
|
|
10512
|
+
let current = schema2;
|
|
10513
|
+
for (const name of key.split(".")) {
|
|
10514
|
+
const { inner } = unwrapSchemaNode(current);
|
|
10515
|
+
const child = inner.def?.type === "object" ? inner.def.shape?.[name] : void 0;
|
|
10516
|
+
if (!child) return void 0;
|
|
10517
|
+
current = child;
|
|
10518
|
+
}
|
|
10519
|
+
return current;
|
|
10520
|
+
}
|
|
10521
|
+
|
|
10522
|
+
// src/commands/config/coerceStructuredConfigValue.ts
|
|
10523
|
+
function coerceStructuredConfigValue(key, raw) {
|
|
10524
|
+
const schema2 = configLeafSchema(assistConfigSchema, key);
|
|
10525
|
+
if (!schema2) return { ok: false, error: `Unknown config key "${key}"` };
|
|
10526
|
+
const parsed = schema2.safeParse(raw);
|
|
10527
|
+
if (parsed.success)
|
|
10528
|
+
return { ok: true, value: parsed.data };
|
|
10529
|
+
return {
|
|
10530
|
+
ok: false,
|
|
10531
|
+
error: parsed.error.issues.map((issue) => formatIssue2(key, issue)).join("\n")
|
|
10532
|
+
};
|
|
10533
|
+
}
|
|
10534
|
+
function formatIssue2(key, issue) {
|
|
10535
|
+
const path71 = formatConfigPath([
|
|
10536
|
+
{ kind: "key", name: key },
|
|
10537
|
+
...issue.path.map(toSegment)
|
|
10538
|
+
]);
|
|
10539
|
+
return `${path71}: ${issue.message}`;
|
|
10540
|
+
}
|
|
10541
|
+
function toSegment(part) {
|
|
10542
|
+
return typeof part === "number" ? { kind: "index", index: part } : { kind: "key", name: String(part) };
|
|
10543
|
+
}
|
|
10544
|
+
|
|
10158
10545
|
// src/commands/config/coerceConfigValue.ts
|
|
10159
10546
|
var EDITABLE_TYPES = /* @__PURE__ */ new Set([
|
|
10160
10547
|
"string",
|
|
@@ -10169,12 +10556,8 @@ function coerceConfigValue(key, raw) {
|
|
|
10169
10556
|
);
|
|
10170
10557
|
if (!leaf) return { ok: false, error: `Unknown config key "${key}"` };
|
|
10171
10558
|
if (leaf.itemType) return coerceScalarList(key, raw, leaf.itemType);
|
|
10172
|
-
if (!EDITABLE_TYPES.has(leaf.type))
|
|
10173
|
-
return
|
|
10174
|
-
ok: false,
|
|
10175
|
-
error: `"${key}" is a ${leaf.type} value and is read-only here`
|
|
10176
|
-
};
|
|
10177
|
-
}
|
|
10559
|
+
if (!EDITABLE_TYPES.has(leaf.type))
|
|
10560
|
+
return coerceStructuredConfigValue(key, raw);
|
|
10178
10561
|
if (leaf.type === "union")
|
|
10179
10562
|
return coerceUnion(key, raw, leaf.unionTypes ?? []);
|
|
10180
10563
|
return coerceConfigScalar(key, raw, leaf.type);
|
|
@@ -10393,22 +10776,22 @@ import { readFileSync as readFileSync21 } from "fs";
|
|
|
10393
10776
|
import { createRequire as createRequire2 } from "module";
|
|
10394
10777
|
var require3 = createRequire2(import.meta.url);
|
|
10395
10778
|
function createCssHandler(packageEntry) {
|
|
10396
|
-
let
|
|
10779
|
+
let cache5;
|
|
10397
10780
|
return (req, res) => {
|
|
10398
|
-
if (!
|
|
10781
|
+
if (!cache5) {
|
|
10399
10782
|
const resolved = require3.resolve(packageEntry);
|
|
10400
10783
|
const body = readFileSync21(resolved, "utf8");
|
|
10401
10784
|
const etag = `"${createHash2("sha256").update(body).digest("hex").slice(0, 16)}"`;
|
|
10402
|
-
|
|
10785
|
+
cache5 = { body, etag };
|
|
10403
10786
|
}
|
|
10404
|
-
const headers = { ETag:
|
|
10405
|
-
if (req.headers["if-none-match"] ===
|
|
10787
|
+
const headers = { ETag: cache5.etag, "Cache-Control": "no-cache" };
|
|
10788
|
+
if (req.headers["if-none-match"] === cache5.etag) {
|
|
10406
10789
|
res.writeHead(304, headers);
|
|
10407
10790
|
res.end();
|
|
10408
10791
|
return;
|
|
10409
10792
|
}
|
|
10410
10793
|
res.writeHead(200, { "Content-Type": "text/css", ...headers });
|
|
10411
|
-
res.end(
|
|
10794
|
+
res.end(cache5.body);
|
|
10412
10795
|
};
|
|
10413
10796
|
}
|
|
10414
10797
|
|
|
@@ -10907,11 +11290,11 @@ function registerActivityCommands(cmd) {
|
|
|
10907
11290
|
|
|
10908
11291
|
// src/commands/backlog/associate-github/index.ts
|
|
10909
11292
|
import chalk64 from "chalk";
|
|
10910
|
-
import { eq as
|
|
11293
|
+
import { eq as eq22 } from "drizzle-orm";
|
|
10911
11294
|
|
|
10912
11295
|
// src/commands/backlog/beginAssociation.ts
|
|
10913
11296
|
import chalk63 from "chalk";
|
|
10914
|
-
import { eq as
|
|
11297
|
+
import { eq as eq21 } from "drizzle-orm";
|
|
10915
11298
|
async function beginAssociation(id, options2, clearPatch, label2) {
|
|
10916
11299
|
const found = await findOneItem(id);
|
|
10917
11300
|
if (!found) {
|
|
@@ -10921,7 +11304,7 @@ async function beginAssociation(id, options2, clearPatch, label2) {
|
|
|
10921
11304
|
const { orm } = found;
|
|
10922
11305
|
const itemId2 = found.item.id;
|
|
10923
11306
|
if (options2.clear) {
|
|
10924
|
-
await orm.update(items).set(clearPatch).where(
|
|
11307
|
+
await orm.update(items).set(clearPatch).where(eq21(items.id, itemId2));
|
|
10925
11308
|
console.log(
|
|
10926
11309
|
chalk63.green(
|
|
10927
11310
|
`Cleared ${label2} association on item ${formatItemId(itemId2)}.`
|
|
@@ -10989,7 +11372,7 @@ async function associateGithub(id, issue, options2) {
|
|
|
10989
11372
|
return;
|
|
10990
11373
|
}
|
|
10991
11374
|
const title = fetchGithubIssueTitle(normalized);
|
|
10992
|
-
await orm.update(items).set({ githubIssue: normalized, jiraKey: null }).where(
|
|
11375
|
+
await orm.update(items).set({ githubIssue: normalized, jiraKey: null }).where(eq22(items.id, itemId2));
|
|
10993
11376
|
console.log(
|
|
10994
11377
|
chalk64.green(`Associated ${normalized} with item ${formatItemId(itemId2)}.`),
|
|
10995
11378
|
title ? chalk64.dim(`(${title})`) : ""
|
|
@@ -11003,7 +11386,7 @@ function registerAssociateGithubCommand(cmd) {
|
|
|
11003
11386
|
|
|
11004
11387
|
// src/commands/backlog/associate-jira/index.ts
|
|
11005
11388
|
import chalk66 from "chalk";
|
|
11006
|
-
import { eq as
|
|
11389
|
+
import { eq as eq23 } from "drizzle-orm";
|
|
11007
11390
|
|
|
11008
11391
|
// src/commands/jira/fetchIssue.ts
|
|
11009
11392
|
import { execSync as execSync33 } from "child_process";
|
|
@@ -11068,7 +11451,7 @@ async function associateJira(id, key, options2) {
|
|
|
11068
11451
|
const parsed = fetchIssue(normalized, "summary");
|
|
11069
11452
|
const fields = parsed?.fields;
|
|
11070
11453
|
const summary = fields?.summary;
|
|
11071
|
-
await orm.update(items).set({ jiraKey: normalized, githubIssue: null }).where(
|
|
11454
|
+
await orm.update(items).set({ jiraKey: normalized, githubIssue: null }).where(eq23(items.id, itemId2));
|
|
11072
11455
|
console.log(
|
|
11073
11456
|
chalk66.green(`Associated ${normalized} with item ${formatItemId(itemId2)}.`),
|
|
11074
11457
|
summary ? chalk66.dim(`(${summary})`) : ""
|
|
@@ -11446,15 +11829,15 @@ function isClaudeCode() {
|
|
|
11446
11829
|
}
|
|
11447
11830
|
|
|
11448
11831
|
// src/commands/backlog/insertPhaseAt.ts
|
|
11449
|
-
import { eq as
|
|
11832
|
+
import { eq as eq25 } from "drizzle-orm";
|
|
11450
11833
|
|
|
11451
11834
|
// src/commands/backlog/shiftPhasesUp.ts
|
|
11452
|
-
import { and as
|
|
11835
|
+
import { and as and10, desc as desc3, eq as eq24, gte } from "drizzle-orm";
|
|
11453
11836
|
async function shiftPhasesUp(db, itemId2, fromIdx) {
|
|
11454
|
-
const toShift = await db.select({ idx: planPhases.idx }).from(planPhases).where(
|
|
11837
|
+
const toShift = await db.select({ idx: planPhases.idx }).from(planPhases).where(and10(eq24(planPhases.itemId, itemId2), gte(planPhases.idx, fromIdx))).orderBy(desc3(planPhases.idx));
|
|
11455
11838
|
for (const p of toShift) {
|
|
11456
|
-
await db.update(planTasks).set({ phaseIdx: p.idx + 1 }).where(
|
|
11457
|
-
await db.update(planPhases).set({ idx: p.idx + 1 }).where(
|
|
11839
|
+
await db.update(planTasks).set({ phaseIdx: p.idx + 1 }).where(and10(eq24(planTasks.itemId, itemId2), eq24(planTasks.phaseIdx, p.idx)));
|
|
11840
|
+
await db.update(planPhases).set({ idx: p.idx + 1 }).where(and10(eq24(planPhases.itemId, itemId2), eq24(planPhases.idx, p.idx)));
|
|
11458
11841
|
}
|
|
11459
11842
|
}
|
|
11460
11843
|
|
|
@@ -11467,7 +11850,7 @@ async function insertPhaseAt(orm, itemId2, phaseIdx, name, tasks, manualChecks,
|
|
|
11467
11850
|
await tx.insert(planTasks).values(tasks.map((task, i) => ({ itemId: itemId2, phaseIdx, idx: i, task })));
|
|
11468
11851
|
}
|
|
11469
11852
|
if (currentPhase !== void 0 && currentPhase - 1 >= phaseIdx) {
|
|
11470
|
-
await tx.update(items).set({ currentPhase: phaseIdx + 1 }).where(
|
|
11853
|
+
await tx.update(items).set({ currentPhase: phaseIdx + 1 }).where(eq25(items.id, itemId2));
|
|
11471
11854
|
}
|
|
11472
11855
|
});
|
|
11473
11856
|
}
|
|
@@ -11639,9 +12022,9 @@ import chalk76 from "chalk";
|
|
|
11639
12022
|
|
|
11640
12023
|
// src/commands/backlog/resolveInsertPosition.ts
|
|
11641
12024
|
import chalk75 from "chalk";
|
|
11642
|
-
import { count as count3, eq as
|
|
12025
|
+
import { count as count3, eq as eq26 } from "drizzle-orm";
|
|
11643
12026
|
async function resolveInsertPosition(orm, itemId2, position) {
|
|
11644
|
-
const [row] = await orm.select({ cnt: count3() }).from(planPhases).where(
|
|
12027
|
+
const [row] = await orm.select({ cnt: count3() }).from(planPhases).where(eq26(planPhases.itemId, itemId2));
|
|
11645
12028
|
const phaseCount = row?.cnt ?? 0;
|
|
11646
12029
|
if (position === void 0) return phaseCount;
|
|
11647
12030
|
const pos = Number.parseInt(position, 10);
|
|
@@ -11997,9 +12380,9 @@ function hasCycle(adjacency, fromId, toId) {
|
|
|
11997
12380
|
}
|
|
11998
12381
|
|
|
11999
12382
|
// src/commands/backlog/loadDependencyGraph.ts
|
|
12000
|
-
import { eq as
|
|
12383
|
+
import { eq as eq27 } from "drizzle-orm";
|
|
12001
12384
|
async function loadDependencyGraph(orm) {
|
|
12002
|
-
const rows = await orm.select({ itemId: links.itemId, targetId: links.targetId }).from(links).where(
|
|
12385
|
+
const rows = await orm.select({ itemId: links.itemId, targetId: links.targetId }).from(links).where(eq27(links.type, "depends-on"));
|
|
12003
12386
|
const graph = /* @__PURE__ */ new Map();
|
|
12004
12387
|
for (const { itemId: itemId2, targetId } of rows) {
|
|
12005
12388
|
const bucket = graph.get(itemId2);
|
|
@@ -12066,7 +12449,7 @@ async function link(fromId, toId, opts) {
|
|
|
12066
12449
|
|
|
12067
12450
|
// src/commands/backlog/unlink.ts
|
|
12068
12451
|
import chalk82 from "chalk";
|
|
12069
|
-
import { and as
|
|
12452
|
+
import { and as and11, eq as eq28 } from "drizzle-orm";
|
|
12070
12453
|
async function unlink(fromId, toId) {
|
|
12071
12454
|
const fromNum = parseItemId(fromId);
|
|
12072
12455
|
const toNum = parseItemId(toId);
|
|
@@ -12090,7 +12473,7 @@ async function unlink(fromId, toId) {
|
|
|
12090
12473
|
);
|
|
12091
12474
|
return;
|
|
12092
12475
|
}
|
|
12093
|
-
await orm.delete(links).where(
|
|
12476
|
+
await orm.delete(links).where(and11(eq28(links.itemId, fromNum), eq28(links.targetId, toNum)));
|
|
12094
12477
|
console.log(
|
|
12095
12478
|
chalk82.green(
|
|
12096
12479
|
`Removed link from ${formatItemId(fromNum)} to ${formatItemId(toNum)}.`
|
|
@@ -12110,7 +12493,7 @@ function registerLinkCommands(cmd) {
|
|
|
12110
12493
|
|
|
12111
12494
|
// src/commands/backlog/move-repo/index.ts
|
|
12112
12495
|
import chalk84 from "chalk";
|
|
12113
|
-
import { eq as
|
|
12496
|
+
import { eq as eq30 } from "drizzle-orm";
|
|
12114
12497
|
|
|
12115
12498
|
// src/commands/backlog/move-repo/confirmMove.ts
|
|
12116
12499
|
import chalk83 from "chalk";
|
|
@@ -12125,9 +12508,9 @@ async function confirmMove(cnt, oldOrigin, newOrigin) {
|
|
|
12125
12508
|
}
|
|
12126
12509
|
|
|
12127
12510
|
// src/commands/backlog/move-repo/countByOrigin.ts
|
|
12128
|
-
import { count as count4, eq as
|
|
12511
|
+
import { count as count4, eq as eq29 } from "drizzle-orm";
|
|
12129
12512
|
async function countByOrigin(orm, origin) {
|
|
12130
|
-
const [{ cnt }] = await orm.select({ cnt: count4() }).from(items).where(
|
|
12513
|
+
const [{ cnt }] = await orm.select({ cnt: count4() }).from(items).where(eq29(items.origin, origin));
|
|
12131
12514
|
return cnt;
|
|
12132
12515
|
}
|
|
12133
12516
|
|
|
@@ -12170,7 +12553,7 @@ async function moveRepo(oldOriginRaw, newOriginRaw, options2 = {}) {
|
|
|
12170
12553
|
console.log(chalk84.yellow("Move cancelled; no changes made."));
|
|
12171
12554
|
return;
|
|
12172
12555
|
}
|
|
12173
|
-
await orm.update(items).set({ origin: newOrigin }).where(
|
|
12556
|
+
await orm.update(items).set({ origin: newOrigin }).where(eq30(items.origin, oldOrigin));
|
|
12174
12557
|
console.log(
|
|
12175
12558
|
chalk84.green(
|
|
12176
12559
|
`Moved ${pluralItems(cnt)} from "${oldOrigin}" to "${newOrigin}".`
|
|
@@ -12587,10 +12970,10 @@ async function start(id) {
|
|
|
12587
12970
|
|
|
12588
12971
|
// src/commands/backlog/stop/index.ts
|
|
12589
12972
|
import chalk96 from "chalk";
|
|
12590
|
-
import { and as
|
|
12973
|
+
import { and as and12, eq as eq31 } from "drizzle-orm";
|
|
12591
12974
|
async function stop() {
|
|
12592
12975
|
const { orm } = await getReady();
|
|
12593
|
-
const stopped = await orm.update(items).set({ status: "todo", currentPhase: 1 }).where(
|
|
12976
|
+
const stopped = await orm.update(items).set({ status: "todo", currentPhase: 1 }).where(and12(eq31(items.status, "in-progress"), eq31(items.origin, getOrigin()))).returning({ id: items.id, name: items.name });
|
|
12594
12977
|
if (stopped.length === 0) {
|
|
12595
12978
|
console.log(chalk96.yellow("No in-progress items to stop."));
|
|
12596
12979
|
return;
|
|
@@ -12707,13 +13090,13 @@ async function findSubtask(id, index3) {
|
|
|
12707
13090
|
}
|
|
12708
13091
|
|
|
12709
13092
|
// src/commands/backlog/updateSubtask.ts
|
|
12710
|
-
import { and as
|
|
13093
|
+
import { and as and13, eq as eq32 } from "drizzle-orm";
|
|
12711
13094
|
async function updateSubtask(orm, itemId2, idx, fields) {
|
|
12712
13095
|
const set = {};
|
|
12713
13096
|
if (fields.title !== void 0) set.title = fields.title;
|
|
12714
13097
|
if (fields.description !== void 0) set.description = fields.description;
|
|
12715
13098
|
if (fields.status !== void 0) set.status = fields.status;
|
|
12716
|
-
const [row] = await orm.update(itemSubtasks).set(set).where(
|
|
13099
|
+
const [row] = await orm.update(itemSubtasks).set(set).where(and13(eq32(itemSubtasks.itemId, itemId2), eq32(itemSubtasks.idx, idx))).returning({ title: itemSubtasks.title });
|
|
12717
13100
|
return row?.title;
|
|
12718
13101
|
}
|
|
12719
13102
|
|
|
@@ -12768,16 +13151,16 @@ async function editSubtask(id, index3, options2) {
|
|
|
12768
13151
|
import chalk102 from "chalk";
|
|
12769
13152
|
|
|
12770
13153
|
// src/commands/backlog/deleteSubtask.ts
|
|
12771
|
-
import { and as
|
|
13154
|
+
import { and as and14, asc as asc9, eq as eq33 } from "drizzle-orm";
|
|
12772
13155
|
async function deleteSubtask(orm, itemId2, idx) {
|
|
12773
|
-
const [row] = await orm.delete(itemSubtasks).where(
|
|
13156
|
+
const [row] = await orm.delete(itemSubtasks).where(and14(eq33(itemSubtasks.itemId, itemId2), eq33(itemSubtasks.idx, idx))).returning({ title: itemSubtasks.title });
|
|
12774
13157
|
if (!row) return void 0;
|
|
12775
|
-
const remaining = await orm.select({ idx: itemSubtasks.idx }).from(itemSubtasks).where(
|
|
13158
|
+
const remaining = await orm.select({ idx: itemSubtasks.idx }).from(itemSubtasks).where(eq33(itemSubtasks.itemId, itemId2)).orderBy(asc9(itemSubtasks.idx));
|
|
12776
13159
|
for (let i = 0; i < remaining.length; i++) {
|
|
12777
13160
|
const oldIdx = remaining[i].idx;
|
|
12778
13161
|
if (oldIdx === i) continue;
|
|
12779
13162
|
await orm.update(itemSubtasks).set({ idx: i }).where(
|
|
12780
|
-
|
|
13163
|
+
and14(eq33(itemSubtasks.itemId, itemId2), eq33(itemSubtasks.idx, oldIdx))
|
|
12781
13164
|
);
|
|
12782
13165
|
}
|
|
12783
13166
|
return row.title;
|
|
@@ -12846,20 +13229,20 @@ function registerSubtaskCommands(cmd) {
|
|
|
12846
13229
|
|
|
12847
13230
|
// src/commands/backlog/movePhase.ts
|
|
12848
13231
|
import chalk104 from "chalk";
|
|
12849
|
-
import { count as count6, eq as
|
|
13232
|
+
import { count as count6, eq as eq36 } from "drizzle-orm";
|
|
12850
13233
|
|
|
12851
13234
|
// src/commands/backlog/reorderPhaseRows.ts
|
|
12852
|
-
import { and as
|
|
13235
|
+
import { and as and16, asc as asc11, eq as eq35 } from "drizzle-orm";
|
|
12853
13236
|
|
|
12854
13237
|
// src/commands/backlog/reindexPhases.ts
|
|
12855
|
-
import { and as
|
|
13238
|
+
import { and as and15, asc as asc10, count as count5, eq as eq34 } from "drizzle-orm";
|
|
12856
13239
|
async function reindexPhases(db, itemId2) {
|
|
12857
|
-
const remaining = await db.select({ idx: planPhases.idx }).from(planPhases).where(
|
|
13240
|
+
const remaining = await db.select({ idx: planPhases.idx }).from(planPhases).where(eq34(planPhases.itemId, itemId2)).orderBy(asc10(planPhases.idx));
|
|
12858
13241
|
for (let i = 0; i < remaining.length; i++) {
|
|
12859
13242
|
const oldIdx = remaining[i].idx;
|
|
12860
13243
|
if (oldIdx === i) continue;
|
|
12861
|
-
await db.update(planTasks).set({ phaseIdx: i }).where(
|
|
12862
|
-
await db.update(planPhases).set({ idx: i }).where(
|
|
13244
|
+
await db.update(planTasks).set({ phaseIdx: i }).where(and15(eq34(planTasks.itemId, itemId2), eq34(planTasks.phaseIdx, oldIdx)));
|
|
13245
|
+
await db.update(planPhases).set({ idx: i }).where(and15(eq34(planPhases.itemId, itemId2), eq34(planPhases.idx, oldIdx)));
|
|
12863
13246
|
}
|
|
12864
13247
|
}
|
|
12865
13248
|
async function adjustCurrentPhase(db, item, removedIdx) {
|
|
@@ -12867,24 +13250,24 @@ async function adjustCurrentPhase(db, item, removedIdx) {
|
|
|
12867
13250
|
if (currentPhase === void 0) return;
|
|
12868
13251
|
const currentIdx = currentPhase - 1;
|
|
12869
13252
|
if (removedIdx < currentIdx) {
|
|
12870
|
-
await db.update(items).set({ currentPhase: currentPhase - 1 }).where(
|
|
13253
|
+
await db.update(items).set({ currentPhase: currentPhase - 1 }).where(eq34(items.id, item.id));
|
|
12871
13254
|
return;
|
|
12872
13255
|
}
|
|
12873
13256
|
if (removedIdx !== currentIdx) return;
|
|
12874
|
-
const [row] = await db.select({ cnt: count5() }).from(planPhases).where(
|
|
13257
|
+
const [row] = await db.select({ cnt: count5() }).from(planPhases).where(eq34(planPhases.itemId, item.id));
|
|
12875
13258
|
const cnt = row?.cnt ?? 0;
|
|
12876
|
-
await db.update(items).set({ currentPhase: cnt === 0 ? null : Math.min(currentPhase, cnt) }).where(
|
|
13259
|
+
await db.update(items).set({ currentPhase: cnt === 0 ? null : Math.min(currentPhase, cnt) }).where(eq34(items.id, item.id));
|
|
12877
13260
|
}
|
|
12878
13261
|
|
|
12879
13262
|
// src/commands/backlog/reorderPhaseRows.ts
|
|
12880
13263
|
async function reorderPhaseRows(orm, itemId2, fromIdx, toIdx) {
|
|
12881
13264
|
await orm.transaction(async (tx) => {
|
|
12882
|
-
const [phaseRow] = await tx.select({ name: planPhases.name, manualChecks: planPhases.manualChecks }).from(planPhases).where(
|
|
12883
|
-
const tasks = await tx.select({ idx: planTasks.idx, task: planTasks.task }).from(planTasks).where(
|
|
13265
|
+
const [phaseRow] = await tx.select({ name: planPhases.name, manualChecks: planPhases.manualChecks }).from(planPhases).where(and16(eq35(planPhases.itemId, itemId2), eq35(planPhases.idx, fromIdx)));
|
|
13266
|
+
const tasks = await tx.select({ idx: planTasks.idx, task: planTasks.task }).from(planTasks).where(and16(eq35(planTasks.itemId, itemId2), eq35(planTasks.phaseIdx, fromIdx))).orderBy(asc11(planTasks.idx));
|
|
12884
13267
|
await tx.delete(planTasks).where(
|
|
12885
|
-
|
|
13268
|
+
and16(eq35(planTasks.itemId, itemId2), eq35(planTasks.phaseIdx, fromIdx))
|
|
12886
13269
|
);
|
|
12887
|
-
await tx.delete(planPhases).where(
|
|
13270
|
+
await tx.delete(planPhases).where(and16(eq35(planPhases.itemId, itemId2), eq35(planPhases.idx, fromIdx)));
|
|
12888
13271
|
await reindexPhases(tx, itemId2);
|
|
12889
13272
|
await shiftPhasesUp(tx, itemId2, toIdx);
|
|
12890
13273
|
await tx.insert(planPhases).values({
|
|
@@ -12925,7 +13308,7 @@ async function movePhase(id, from, to) {
|
|
|
12925
13308
|
if (!found) return;
|
|
12926
13309
|
const { orm, item } = found;
|
|
12927
13310
|
const itemId2 = item.id;
|
|
12928
|
-
const [row] = await orm.select({ cnt: count6() }).from(planPhases).where(
|
|
13311
|
+
const [row] = await orm.select({ cnt: count6() }).from(planPhases).where(eq36(planPhases.itemId, itemId2));
|
|
12929
13312
|
const phaseCount = row?.cnt ?? 0;
|
|
12930
13313
|
const fromIdx = toIndex(from, phaseCount);
|
|
12931
13314
|
if (fromIdx === void 0) return;
|
|
@@ -12941,22 +13324,22 @@ async function movePhase(id, from, to) {
|
|
|
12941
13324
|
import chalk106 from "chalk";
|
|
12942
13325
|
|
|
12943
13326
|
// src/commands/backlog/applyPhaseUpdate.ts
|
|
12944
|
-
import { and as
|
|
13327
|
+
import { and as and17, eq as eq37 } from "drizzle-orm";
|
|
12945
13328
|
async function applyPhaseUpdate(orm, itemId2, phaseIdx, fields) {
|
|
12946
13329
|
await orm.transaction(async (tx) => {
|
|
12947
13330
|
if (fields.name) {
|
|
12948
13331
|
await tx.update(planPhases).set({ name: fields.name }).where(
|
|
12949
|
-
|
|
13332
|
+
and17(eq37(planPhases.itemId, itemId2), eq37(planPhases.idx, phaseIdx))
|
|
12950
13333
|
);
|
|
12951
13334
|
}
|
|
12952
13335
|
if (fields.manualCheck) {
|
|
12953
13336
|
await tx.update(planPhases).set({ manualChecks: JSON.stringify(fields.manualCheck) }).where(
|
|
12954
|
-
|
|
13337
|
+
and17(eq37(planPhases.itemId, itemId2), eq37(planPhases.idx, phaseIdx))
|
|
12955
13338
|
);
|
|
12956
13339
|
}
|
|
12957
13340
|
if (fields.task) {
|
|
12958
13341
|
await tx.delete(planTasks).where(
|
|
12959
|
-
|
|
13342
|
+
and17(eq37(planTasks.itemId, itemId2), eq37(planTasks.phaseIdx, phaseIdx))
|
|
12960
13343
|
);
|
|
12961
13344
|
if (fields.task.length) {
|
|
12962
13345
|
await tx.insert(planTasks).values(
|
|
@@ -12974,14 +13357,14 @@ async function applyPhaseUpdate(orm, itemId2, phaseIdx, fields) {
|
|
|
12974
13357
|
|
|
12975
13358
|
// src/commands/backlog/findPhase.ts
|
|
12976
13359
|
import chalk105 from "chalk";
|
|
12977
|
-
import { and as
|
|
13360
|
+
import { and as and18, count as count7, eq as eq38 } from "drizzle-orm";
|
|
12978
13361
|
async function findPhase(id, phase) {
|
|
12979
13362
|
const found = await findOneItem(id);
|
|
12980
13363
|
if (!found) return void 0;
|
|
12981
13364
|
const { orm, item } = found;
|
|
12982
13365
|
const itemId2 = item.id;
|
|
12983
13366
|
const phaseIdx = Number.parseInt(phase, 10) - 1;
|
|
12984
|
-
const [row] = await orm.select({ cnt: count7() }).from(planPhases).where(
|
|
13367
|
+
const [row] = await orm.select({ cnt: count7() }).from(planPhases).where(and18(eq38(planPhases.itemId, itemId2), eq38(planPhases.idx, phaseIdx)));
|
|
12985
13368
|
if (!row || row.cnt === 0) {
|
|
12986
13369
|
console.log(
|
|
12987
13370
|
chalk105.red(
|
|
@@ -13137,14 +13520,14 @@ async function updatePhase(id, phase, options2) {
|
|
|
13137
13520
|
}
|
|
13138
13521
|
|
|
13139
13522
|
// src/commands/backlog/registerUpdatePhaseCommand.ts
|
|
13140
|
-
function
|
|
13523
|
+
function collect(value, previous) {
|
|
13141
13524
|
return [...previous, value];
|
|
13142
13525
|
}
|
|
13143
13526
|
function registerUpdatePhaseCommand(cmd) {
|
|
13144
|
-
cmd.command("update-phase <id> <phase>").alias("edit-phase").description("Modify a plan phase on a backlog item").option("--name <name>", "New phase name").option("--task <task...>", "Replace tasks (repeatable)").option("--manual-check <check...>", "Replace manual checks (repeatable)").option("--add-task <text>", "Append one task (repeatable)",
|
|
13527
|
+
cmd.command("update-phase <id> <phase>").alias("edit-phase").description("Modify a plan phase on a backlog item").option("--name <name>", "New phase name").option("--task <task...>", "Replace tasks (repeatable)").option("--manual-check <check...>", "Replace manual checks (repeatable)").option("--add-task <text>", "Append one task (repeatable)", collect, []).option("--edit-task <n> <text...>", "Replace task n (1-based) in place").option("--remove-task <n>", "Remove task n (1-based)").option(
|
|
13145
13528
|
"--add-check <text>",
|
|
13146
13529
|
"Append one manual check (repeatable)",
|
|
13147
|
-
|
|
13530
|
+
collect,
|
|
13148
13531
|
[]
|
|
13149
13532
|
).option(
|
|
13150
13533
|
"--edit-check <n> <text...>",
|
|
@@ -13154,16 +13537,16 @@ function registerUpdatePhaseCommand(cmd) {
|
|
|
13154
13537
|
|
|
13155
13538
|
// src/commands/backlog/removePhase.ts
|
|
13156
13539
|
import chalk107 from "chalk";
|
|
13157
|
-
import { and as
|
|
13540
|
+
import { and as and19, eq as eq39 } from "drizzle-orm";
|
|
13158
13541
|
async function removePhase(id, phase) {
|
|
13159
13542
|
const found = await findPhase(id, phase);
|
|
13160
13543
|
if (!found) return;
|
|
13161
13544
|
const { item, orm, itemId: itemId2, phaseIdx } = found;
|
|
13162
13545
|
await orm.transaction(async (tx) => {
|
|
13163
13546
|
await tx.delete(planTasks).where(
|
|
13164
|
-
|
|
13547
|
+
and19(eq39(planTasks.itemId, itemId2), eq39(planTasks.phaseIdx, phaseIdx))
|
|
13165
13548
|
);
|
|
13166
|
-
await tx.delete(planPhases).where(
|
|
13549
|
+
await tx.delete(planPhases).where(and19(eq39(planPhases.itemId, itemId2), eq39(planPhases.idx, phaseIdx)));
|
|
13167
13550
|
await reindexPhases(tx, itemId2);
|
|
13168
13551
|
await adjustCurrentPhase(tx, item, phaseIdx);
|
|
13169
13552
|
});
|
|
@@ -13176,7 +13559,7 @@ async function removePhase(id, phase) {
|
|
|
13176
13559
|
|
|
13177
13560
|
// src/commands/backlog/update/update.ts
|
|
13178
13561
|
import chalk111 from "chalk";
|
|
13179
|
-
import { eq as
|
|
13562
|
+
import { eq as eq40 } from "drizzle-orm";
|
|
13180
13563
|
|
|
13181
13564
|
// src/commands/backlog/update/buildUpdateValues.ts
|
|
13182
13565
|
import chalk108 from "chalk";
|
|
@@ -13287,14 +13670,14 @@ async function update(id, options2) {
|
|
|
13287
13670
|
if (!built) return;
|
|
13288
13671
|
const { orm } = found;
|
|
13289
13672
|
const itemId2 = found.item.id;
|
|
13290
|
-
await orm.update(items).set(built.set).where(
|
|
13673
|
+
await orm.update(items).set(built.set).where(eq40(items.id, itemId2));
|
|
13291
13674
|
console.log(
|
|
13292
13675
|
chalk111.green(`Updated ${built.fields} on item ${formatItemId(itemId2)}.`)
|
|
13293
13676
|
);
|
|
13294
13677
|
}
|
|
13295
13678
|
|
|
13296
13679
|
// src/commands/backlog/registerUpdateCommands.ts
|
|
13297
|
-
function
|
|
13680
|
+
function collect2(value, previous) {
|
|
13298
13681
|
return [...previous, value];
|
|
13299
13682
|
}
|
|
13300
13683
|
function registerUpdateCommands(cmd) {
|
|
@@ -13304,7 +13687,7 @@ function registerUpdateCommands(cmd) {
|
|
|
13304
13687
|
).option("--type <type>", "New type (story or bug)").option("--ac <criterion...>", "Replace acceptance criteria (repeatable)").option(
|
|
13305
13688
|
"--add-ac <text>",
|
|
13306
13689
|
"Append one acceptance criterion (repeatable)",
|
|
13307
|
-
|
|
13690
|
+
collect2,
|
|
13308
13691
|
[]
|
|
13309
13692
|
).option(
|
|
13310
13693
|
"--edit-ac <n> <text...>",
|
|
@@ -13489,9 +13872,9 @@ var UNPARSEABLE = { ok: false, error: "unable to parse" };
|
|
|
13489
13872
|
function groupByOperator(tokens) {
|
|
13490
13873
|
const groups = [[]];
|
|
13491
13874
|
for (let i = 0; i < tokens.length; i++) {
|
|
13492
|
-
const
|
|
13493
|
-
if (!
|
|
13494
|
-
i =
|
|
13875
|
+
const step2 = handleToken(tokens, i, groups);
|
|
13876
|
+
if (!step2.ok) return step2;
|
|
13877
|
+
i = step2.nextIndex;
|
|
13495
13878
|
}
|
|
13496
13879
|
return { ok: true, groups };
|
|
13497
13880
|
}
|
|
@@ -17365,9 +17748,9 @@ function registerGithub(program2) {
|
|
|
17365
17748
|
}
|
|
17366
17749
|
|
|
17367
17750
|
// src/commands/handover/countPendingHandovers.ts
|
|
17368
|
-
import { and as
|
|
17751
|
+
import { and as and20, eq as eq41, isNull, sql as sql18 } from "drizzle-orm";
|
|
17369
17752
|
async function countPendingHandovers(orm, origin) {
|
|
17370
|
-
const [row] = await orm.select({ count: sql18`count(*)::int` }).from(handovers).where(
|
|
17753
|
+
const [row] = await orm.select({ count: sql18`count(*)::int` }).from(handovers).where(and20(eq41(handovers.origin, origin), isNull(handovers.recalledAt)));
|
|
17371
17754
|
return row?.count ?? 0;
|
|
17372
17755
|
}
|
|
17373
17756
|
|
|
@@ -17507,13 +17890,13 @@ async function load2(options2 = {}) {
|
|
|
17507
17890
|
}
|
|
17508
17891
|
|
|
17509
17892
|
// src/commands/handover/listPendingHandovers.ts
|
|
17510
|
-
import { and as
|
|
17893
|
+
import { and as and21, desc as desc4, eq as eq42, isNull as isNull2 } from "drizzle-orm";
|
|
17511
17894
|
async function listPendingHandovers(orm, origin) {
|
|
17512
17895
|
return orm.select({
|
|
17513
17896
|
id: handovers.id,
|
|
17514
17897
|
summary: handovers.summary,
|
|
17515
17898
|
createdAt: handovers.createdAt
|
|
17516
|
-
}).from(handovers).where(
|
|
17899
|
+
}).from(handovers).where(and21(eq42(handovers.origin, origin), isNull2(handovers.recalledAt))).orderBy(desc4(handovers.createdAt), desc4(handovers.id));
|
|
17517
17900
|
}
|
|
17518
17901
|
|
|
17519
17902
|
// src/commands/handover/printPendingHandovers.ts
|
|
@@ -17526,17 +17909,17 @@ async function printPendingHandovers() {
|
|
|
17526
17909
|
}
|
|
17527
17910
|
|
|
17528
17911
|
// src/commands/handover/recallHandover.ts
|
|
17529
|
-
import { and as
|
|
17912
|
+
import { and as and22, desc as desc5, eq as eq43, isNull as isNull3 } from "drizzle-orm";
|
|
17530
17913
|
async function recallHandover(orm, origin, id) {
|
|
17531
17914
|
const [row] = await orm.select().from(handovers).where(
|
|
17532
|
-
|
|
17533
|
-
|
|
17915
|
+
and22(
|
|
17916
|
+
eq43(handovers.origin, origin),
|
|
17534
17917
|
isNull3(handovers.recalledAt),
|
|
17535
|
-
...id === void 0 ? [] : [
|
|
17918
|
+
...id === void 0 ? [] : [eq43(handovers.id, id)]
|
|
17536
17919
|
)
|
|
17537
17920
|
).orderBy(desc5(handovers.createdAt), desc5(handovers.id)).limit(1);
|
|
17538
17921
|
if (!row) return void 0;
|
|
17539
|
-
await orm.update(handovers).set({ recalledAt: /* @__PURE__ */ new Date() }).where(
|
|
17922
|
+
await orm.update(handovers).set({ recalledAt: /* @__PURE__ */ new Date() }).where(eq43(handovers.id, row.id));
|
|
17540
17923
|
return row.content;
|
|
17541
17924
|
}
|
|
17542
17925
|
|
|
@@ -17924,16 +18307,16 @@ function* durabilityProbes() {
|
|
|
17924
18307
|
async function checkDurability(cwd) {
|
|
17925
18308
|
if (!existsSync44(cwd)) return { durable: true };
|
|
17926
18309
|
const probes = durabilityProbes();
|
|
17927
|
-
let
|
|
17928
|
-
while (!
|
|
17929
|
-
return
|
|
18310
|
+
let step2 = probes.next();
|
|
18311
|
+
while (!step2.done) step2 = probes.next(await gitResult(cwd, step2.value));
|
|
18312
|
+
return step2.value;
|
|
17930
18313
|
}
|
|
17931
18314
|
function checkDurabilitySync(cwd) {
|
|
17932
18315
|
if (!existsSync44(cwd)) return { durable: true };
|
|
17933
18316
|
const probes = durabilityProbes();
|
|
17934
|
-
let
|
|
17935
|
-
while (!
|
|
17936
|
-
return
|
|
18317
|
+
let step2 = probes.next();
|
|
18318
|
+
while (!step2.done) step2 = probes.next(gitSyncResult(cwd, step2.value));
|
|
18319
|
+
return step2.value;
|
|
17937
18320
|
}
|
|
17938
18321
|
|
|
17939
18322
|
// src/commands/sessions/daemon/worktree/worktreeConfigFor.ts
|
|
@@ -19552,20 +19935,20 @@ function resolveThread(threadId) {
|
|
|
19552
19935
|
}
|
|
19553
19936
|
}
|
|
19554
19937
|
function requireCache(prNumber) {
|
|
19555
|
-
const
|
|
19556
|
-
if (!
|
|
19938
|
+
const cache5 = loadCommentsCache(prNumber);
|
|
19939
|
+
if (!cache5) {
|
|
19557
19940
|
console.error(
|
|
19558
19941
|
`Error: No cached comments found for PR #${prNumber}. Run "assist prs list-comments" first.`
|
|
19559
19942
|
);
|
|
19560
19943
|
process.exit(1);
|
|
19561
19944
|
}
|
|
19562
|
-
return
|
|
19945
|
+
return cache5;
|
|
19563
19946
|
}
|
|
19564
19947
|
function findLineComment(comments3, commentId) {
|
|
19565
19948
|
return comments3.find((c) => c.type === "line" && c.id === commentId);
|
|
19566
19949
|
}
|
|
19567
|
-
function requireLineComment(
|
|
19568
|
-
const comment3 = findLineComment(
|
|
19950
|
+
function requireLineComment(cache5, commentId) {
|
|
19951
|
+
const comment3 = findLineComment(cache5.comments, commentId);
|
|
19569
19952
|
if (!comment3 || comment3.type !== "line" || !comment3.threadId) {
|
|
19570
19953
|
console.error(
|
|
19571
19954
|
`Error: Comment #${commentId} not found or has no thread ID.`
|
|
@@ -19574,8 +19957,8 @@ function requireLineComment(cache4, commentId) {
|
|
|
19574
19957
|
}
|
|
19575
19958
|
return comment3;
|
|
19576
19959
|
}
|
|
19577
|
-
function cleanupCacheIfDone(
|
|
19578
|
-
const hasRemaining =
|
|
19960
|
+
function cleanupCacheIfDone(cache5, prNumber, commentId) {
|
|
19961
|
+
const hasRemaining = cache5.comments.some(
|
|
19579
19962
|
(c) => c.type === "line" && c.id !== commentId
|
|
19580
19963
|
);
|
|
19581
19964
|
if (!hasRemaining) deleteCommentsCache(prNumber);
|
|
@@ -19583,13 +19966,13 @@ function cleanupCacheIfDone(cache4, prNumber, commentId) {
|
|
|
19583
19966
|
function resolveCommentWithReply(commentId, message2) {
|
|
19584
19967
|
const prNumber = getCurrentPrNumber();
|
|
19585
19968
|
const { org, repo } = getRepoInfo();
|
|
19586
|
-
const
|
|
19587
|
-
const comment3 = requireLineComment(
|
|
19969
|
+
const cache5 = requireCache(prNumber);
|
|
19970
|
+
const comment3 = requireLineComment(cache5, commentId);
|
|
19588
19971
|
replyToComment(org, repo, prNumber, commentId, message2);
|
|
19589
19972
|
console.log("Reply posted successfully.");
|
|
19590
19973
|
resolveThread(comment3.threadId);
|
|
19591
19974
|
console.log("Thread resolved successfully.");
|
|
19592
|
-
cleanupCacheIfDone(
|
|
19975
|
+
cleanupCacheIfDone(cache5, prNumber, commentId);
|
|
19593
19976
|
}
|
|
19594
19977
|
|
|
19595
19978
|
// src/commands/prs/fixed.ts
|
|
@@ -20178,7 +20561,7 @@ var prsConfigHelp = [
|
|
|
20178
20561
|
];
|
|
20179
20562
|
|
|
20180
20563
|
// src/commands/registerPrsEdit.ts
|
|
20181
|
-
function
|
|
20564
|
+
function collect3(value, previous) {
|
|
20182
20565
|
return previous.concat([value]);
|
|
20183
20566
|
}
|
|
20184
20567
|
function registerPrsEdit(prsCommand) {
|
|
@@ -20187,7 +20570,7 @@ function registerPrsEdit(prsCommand) {
|
|
|
20187
20570
|
).option("-t, --title <title>", "New title for the pull request").option("--what <what>", "Replace the ## What section").option("--why <why>", "Replace the ## Why section").option("--how <how>", "Replace the ## How section").option(
|
|
20188
20571
|
"--resolves <key>",
|
|
20189
20572
|
"Jira issue key resolved by this PR, appended to ## Why (repeatable)",
|
|
20190
|
-
|
|
20573
|
+
collect3,
|
|
20191
20574
|
[]
|
|
20192
20575
|
).action(edit);
|
|
20193
20576
|
}
|
|
@@ -20288,7 +20671,7 @@ ${confirm}
|
|
|
20288
20671
|
}
|
|
20289
20672
|
|
|
20290
20673
|
// src/commands/registerPrsRaise.ts
|
|
20291
|
-
function
|
|
20674
|
+
function collect4(value, previous) {
|
|
20292
20675
|
return previous.concat([value]);
|
|
20293
20676
|
}
|
|
20294
20677
|
function registerPrsRaise(prsCommand) {
|
|
@@ -20297,20 +20680,20 @@ function registerPrsRaise(prsCommand) {
|
|
|
20297
20680
|
).option("-t, --title <title>", "Title for the pull request").option("--what <what>", "What the change does (## What section)").option("--why <why>", "Why the change is needed (## Why section)").option("--how <how>", "How the change works (optional ## How section)").option(
|
|
20298
20681
|
"--resolves <key>",
|
|
20299
20682
|
"Jira issue key resolved by this PR, appended to ## Why (repeatable)",
|
|
20300
|
-
|
|
20683
|
+
collect4,
|
|
20301
20684
|
[]
|
|
20302
20685
|
).option(
|
|
20303
20686
|
"--force",
|
|
20304
20687
|
"Overwrite the title and body of an existing pull request"
|
|
20305
|
-
).option("-B, --base <branch>", "Branch into which the pull request merges").option("-H, --head <branch>", "Branch that contains the commits").option("-d, --draft", "Mark the pull request as a draft").option("-w, --web", "Open the browser to create the pull request").option("-l, --label <label>", "Add a label (repeatable)",
|
|
20688
|
+
).option("-B, --base <branch>", "Branch into which the pull request merges").option("-H, --head <branch>", "Branch that contains the commits").option("-d, --draft", "Mark the pull request as a draft").option("-w, --web", "Open the browser to create the pull request").option("-l, --label <label>", "Add a label (repeatable)", collect4, []).option(
|
|
20306
20689
|
"-a, --assignee <login>",
|
|
20307
20690
|
"Assign a person by login (repeatable)",
|
|
20308
|
-
|
|
20691
|
+
collect4,
|
|
20309
20692
|
[]
|
|
20310
20693
|
).option(
|
|
20311
20694
|
"-r, --reviewer <handle>",
|
|
20312
20695
|
"Request a review (repeatable)",
|
|
20313
|
-
|
|
20696
|
+
collect4,
|
|
20314
20697
|
[]
|
|
20315
20698
|
).option("-m, --milestone <name>", "Add the pull request to a milestone").addHelpText("after", () => raiseHelpText()).action(raise);
|
|
20316
20699
|
}
|
|
@@ -27822,10 +28205,10 @@ function applyReviewPause(session, activity2) {
|
|
|
27822
28205
|
}
|
|
27823
28206
|
|
|
27824
28207
|
// src/shared/db/getPhaseActiveMs.ts
|
|
27825
|
-
import { and as
|
|
28208
|
+
import { and as and23, eq as eq44 } from "drizzle-orm";
|
|
27826
28209
|
async function getPhaseActiveMs(db, itemId2, phaseIdx) {
|
|
27827
28210
|
const [row] = await db.select({ activeMs: phaseUsage.activeMs }).from(phaseUsage).where(
|
|
27828
|
-
|
|
28211
|
+
and23(eq44(phaseUsage.itemId, itemId2), eq44(phaseUsage.phaseIdx, phaseIdx))
|
|
27829
28212
|
);
|
|
27830
28213
|
return row?.activeMs ?? 0;
|
|
27831
28214
|
}
|
|
@@ -28336,17 +28719,17 @@ async function recordPhaseTranscriptUsage(db, itemId2, phaseIdx, responses) {
|
|
|
28336
28719
|
}
|
|
28337
28720
|
|
|
28338
28721
|
// src/shared/db/recordWindowTokens.ts
|
|
28339
|
-
import { and as
|
|
28722
|
+
import { and as and24, eq as eq45, sql as sql24 } from "drizzle-orm";
|
|
28340
28723
|
async function recordWindowTokens(db, window, resetsAt, tokensUp, tokensDown) {
|
|
28341
28724
|
if (tokensUp <= 0 && tokensDown <= 0) return;
|
|
28342
28725
|
await db.update(usagePeaks).set({
|
|
28343
28726
|
tokensUp: sql24`${usagePeaks.tokensUp} + ${tokensUp}`,
|
|
28344
28727
|
tokensDown: sql24`${usagePeaks.tokensDown} + ${tokensDown}`
|
|
28345
28728
|
}).where(
|
|
28346
|
-
|
|
28347
|
-
|
|
28348
|
-
|
|
28349
|
-
|
|
28729
|
+
and24(
|
|
28730
|
+
eq45(usagePeaks.window, window),
|
|
28731
|
+
eq45(usagePeaks.resetsAt, resetsAt),
|
|
28732
|
+
eq45(usagePeaks.segment, 0)
|
|
28350
28733
|
)
|
|
28351
28734
|
);
|
|
28352
28735
|
}
|