@brainervirus/workit-codex 8.9.0 → 8.10.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/.codex-plugin/plugin.json +1 -1
- package/dist/launch-mcp.js +240 -105
- package/dist/{workit-hook-aw8j630z.js → workit-hook-xhqhe7h0.js} +545 -369
- package/dist/workit-hook.js +1 -1
- package/package.json +3 -3
- package/skills/workit-fanout/references/brief.md +1 -1
- package/skills/workit-fanout/references/orchestration.md +16 -6
- package/skills/workit-implement/SKILL.md +3 -2
- package/skills/workit-review/SKILL.md +4 -2
package/dist/launch-mcp.js
CHANGED
|
@@ -16061,64 +16061,11 @@ function acquireFileLockSync(targetPath, options) {
|
|
|
16061
16061
|
}
|
|
16062
16062
|
}
|
|
16063
16063
|
}
|
|
16064
|
-
// packages/workit-core/src/host-session.ts
|
|
16065
|
-
var HOST_SESSION_VARS = [
|
|
16066
|
-
["OPENCODE_SESSION_ID", () => "opencode"],
|
|
16067
|
-
["PI_SESSION_ID", () => "pi"],
|
|
16068
|
-
[
|
|
16069
|
-
"CODEX_THREAD_ID",
|
|
16070
|
-
(env) => env.CODEX_INTERNAL_ORIGINATOR_OVERRIDE === "Codex Desktop" || env.CODEX_ELECTRON_RESOURCES_PATH ? "codex_desktop" : "codex_cli"
|
|
16071
|
-
]
|
|
16072
|
-
];
|
|
16073
|
-
var family = (host) => host?.replace(/_(?:cli|desktop)$/, "") ?? null;
|
|
16074
|
-
function hostSessionFromEnv(env) {
|
|
16075
|
-
const value = (key) => env[key]?.trim() || null;
|
|
16076
|
-
let inner = null;
|
|
16077
|
-
for (const [key, host] of HOST_SESSION_VARS) {
|
|
16078
|
-
const session = value(key);
|
|
16079
|
-
if (session) {
|
|
16080
|
-
inner = { host: host(env), session };
|
|
16081
|
-
break;
|
|
16082
|
-
}
|
|
16083
|
-
}
|
|
16084
|
-
const declared = value("WORKIT_HOST");
|
|
16085
|
-
if (env.WORKIT_SESSION_ID !== undefined) {
|
|
16086
|
-
const inherited = inner !== null && declared !== null && family(declared) !== family(inner.host);
|
|
16087
|
-
if (!inherited)
|
|
16088
|
-
return { host: declared, session: value("WORKIT_SESSION_ID") };
|
|
16089
|
-
}
|
|
16090
|
-
return inner ? { host: inner.host, session: inner.session } : { host: declared, session: null };
|
|
16091
|
-
}
|
|
16092
|
-
|
|
16093
|
-
// packages/workit-core/src/core/package-root.ts
|
|
16094
|
-
import { existsSync } from "node:fs";
|
|
16095
|
-
import path3 from "node:path";
|
|
16096
|
-
import { fileURLToPath } from "node:url";
|
|
16097
|
-
var packageRoot = () => {
|
|
16098
|
-
let dir = path3.dirname(fileURLToPath(import.meta.url));
|
|
16099
|
-
while (true) {
|
|
16100
|
-
const parent = path3.dirname(dir);
|
|
16101
|
-
if (existsSync(path3.join(dir, "package.json")) || parent === dir)
|
|
16102
|
-
return dir;
|
|
16103
|
-
dir = parent;
|
|
16104
|
-
}
|
|
16105
|
-
};
|
|
16106
|
-
var assetRoot = () => {
|
|
16107
|
-
const root = packageRoot();
|
|
16108
|
-
const assets = path3.join(root, "assets");
|
|
16109
|
-
return existsSync(assets) ? assets : root;
|
|
16110
|
-
};
|
|
16111
|
-
|
|
16112
|
-
// packages/workit-core/src/core/store-lock.ts
|
|
16113
|
-
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
16114
|
-
import fs5 from "node:fs";
|
|
16115
|
-
import { hostname } from "node:os";
|
|
16116
|
-
|
|
16117
16064
|
// packages/workit-core/src/store/paths.ts
|
|
16118
16065
|
import { spawnSync } from "node:child_process";
|
|
16119
16066
|
import { createHash as createHash2 } from "node:crypto";
|
|
16120
16067
|
import fs4 from "node:fs";
|
|
16121
|
-
import
|
|
16068
|
+
import path3 from "node:path";
|
|
16122
16069
|
var NOT_A_REPO = /not a git repository \(or any (of the parent directories|parent up to)/u;
|
|
16123
16070
|
var gitRun = (cwd, args) => {
|
|
16124
16071
|
const run = spawnSync("git", args, {
|
|
@@ -16160,14 +16107,14 @@ var DISCOVERY_ENV = [
|
|
|
16160
16107
|
];
|
|
16161
16108
|
var isGitDir = (dir) => {
|
|
16162
16109
|
try {
|
|
16163
|
-
return fs4.statSync(
|
|
16110
|
+
return fs4.statSync(path3.join(dir, "HEAD")).isFile() && fs4.statSync(path3.join(dir, "objects")).isDirectory() && fs4.statSync(path3.join(dir, "refs")).isDirectory();
|
|
16164
16111
|
} catch {
|
|
16165
16112
|
return false;
|
|
16166
16113
|
}
|
|
16167
16114
|
};
|
|
16168
16115
|
var reftableRefs = (common) => {
|
|
16169
16116
|
try {
|
|
16170
|
-
return /^\s*refstorage\s*=\s*reftable\s*$/imu.test(fs4.readFileSync(
|
|
16117
|
+
return /^\s*refstorage\s*=\s*reftable\s*$/imu.test(fs4.readFileSync(path3.join(common, "config"), "utf8"));
|
|
16171
16118
|
} catch {
|
|
16172
16119
|
return false;
|
|
16173
16120
|
}
|
|
@@ -16187,7 +16134,7 @@ function fastGit(root) {
|
|
|
16187
16134
|
if (device !== null && stat.dev !== device)
|
|
16188
16135
|
return { kind: "none" };
|
|
16189
16136
|
device = stat.dev;
|
|
16190
|
-
const dotGit =
|
|
16137
|
+
const dotGit = path3.join(dir, ".git");
|
|
16191
16138
|
let entry = null;
|
|
16192
16139
|
try {
|
|
16193
16140
|
entry = fs4.statSync(dotGit);
|
|
@@ -16208,19 +16155,19 @@ function fastGit(root) {
|
|
|
16208
16155
|
const match = /^gitdir: (.+)$/mu.exec(text);
|
|
16209
16156
|
if (!match)
|
|
16210
16157
|
return null;
|
|
16211
|
-
gitDir =
|
|
16158
|
+
gitDir = path3.resolve(dir, match[1].trim());
|
|
16212
16159
|
} else
|
|
16213
16160
|
return null;
|
|
16214
|
-
if (!fs4.existsSync(
|
|
16161
|
+
if (!fs4.existsSync(path3.join(gitDir, "HEAD")))
|
|
16215
16162
|
return null;
|
|
16216
16163
|
} else if (isGitDir(dir))
|
|
16217
16164
|
gitDir = dir;
|
|
16218
16165
|
if (gitDir) {
|
|
16219
16166
|
let common = gitDir;
|
|
16220
16167
|
try {
|
|
16221
|
-
common =
|
|
16168
|
+
common = path3.resolve(gitDir, fs4.readFileSync(path3.join(gitDir, "commondir"), "utf8").trim());
|
|
16222
16169
|
} catch {}
|
|
16223
|
-
if (!fs4.existsSync(
|
|
16170
|
+
if (!fs4.existsSync(path3.join(common, "objects")))
|
|
16224
16171
|
return null;
|
|
16225
16172
|
return {
|
|
16226
16173
|
kind: "repo",
|
|
@@ -16230,26 +16177,26 @@ function fastGit(root) {
|
|
|
16230
16177
|
reftable: reftableRefs(common)
|
|
16231
16178
|
};
|
|
16232
16179
|
}
|
|
16233
|
-
const parent =
|
|
16180
|
+
const parent = path3.dirname(dir);
|
|
16234
16181
|
if (parent === dir)
|
|
16235
16182
|
return { kind: "none" };
|
|
16236
16183
|
dir = parent;
|
|
16237
16184
|
}
|
|
16238
16185
|
}
|
|
16239
16186
|
function resolveStore(root) {
|
|
16240
|
-
root =
|
|
16187
|
+
root = path3.resolve(root);
|
|
16241
16188
|
let directory = false;
|
|
16242
16189
|
try {
|
|
16243
16190
|
directory = fs4.statSync(root).isDirectory();
|
|
16244
16191
|
} catch {}
|
|
16245
16192
|
if (!directory)
|
|
16246
|
-
return { dir:
|
|
16193
|
+
return { dir: path3.join(root, ".workit"), shared: false, top: null };
|
|
16247
16194
|
const fast = fastGit(root);
|
|
16248
16195
|
if (fast?.kind === "none")
|
|
16249
|
-
return { dir:
|
|
16196
|
+
return { dir: path3.join(root, ".workit"), shared: false, top: null };
|
|
16250
16197
|
if (fast?.kind === "repo")
|
|
16251
16198
|
return {
|
|
16252
|
-
dir:
|
|
16199
|
+
dir: path3.join(fast.common, "workit"),
|
|
16253
16200
|
shared: true,
|
|
16254
16201
|
top: fast.top,
|
|
16255
16202
|
git: { gitDir: fast.gitDir, top: fast.top, reftable: fast.reftable }
|
|
@@ -16259,20 +16206,20 @@ function resolveStore(root) {
|
|
|
16259
16206
|
if (run.ok && common) {
|
|
16260
16207
|
const top = gitRun(root, ["rev-parse", "--path-format=absolute", "--show-toplevel"]);
|
|
16261
16208
|
return {
|
|
16262
|
-
dir:
|
|
16209
|
+
dir: path3.join(real(path3.resolve(root, common)), "workit"),
|
|
16263
16210
|
shared: true,
|
|
16264
16211
|
top: top.ok && top.stdout.trim() ? real(top.stdout.trim()) : null
|
|
16265
16212
|
};
|
|
16266
16213
|
}
|
|
16267
16214
|
if (run.missing || !run.ok && NOT_A_REPO.test(run.stderr))
|
|
16268
|
-
return { dir:
|
|
16215
|
+
return { dir: path3.join(root, ".workit"), shared: false, top: null };
|
|
16269
16216
|
return new Error(`cannot locate the workit store: git rev-parse failed (${run.stderr.trim().split(`
|
|
16270
16217
|
`)[0] || "no output"}); fix the repository (git status should work here)`);
|
|
16271
16218
|
}
|
|
16272
16219
|
var rebasingBranch = (gitDir) => {
|
|
16273
16220
|
for (const state of ["rebase-merge", "rebase-apply"]) {
|
|
16274
16221
|
try {
|
|
16275
|
-
const ref = fs4.readFileSync(
|
|
16222
|
+
const ref = fs4.readFileSync(path3.join(gitDir, state, "head-name"), "utf8").trim();
|
|
16276
16223
|
const match = /^refs\/heads\/(.+)$/u.exec(ref);
|
|
16277
16224
|
if (match)
|
|
16278
16225
|
return match[1];
|
|
@@ -16287,7 +16234,7 @@ function resolveTaskKey(root, location) {
|
|
|
16287
16234
|
if (location.git && !location.git.reftable) {
|
|
16288
16235
|
let head = "";
|
|
16289
16236
|
try {
|
|
16290
|
-
head = fs4.readFileSync(
|
|
16237
|
+
head = fs4.readFileSync(path3.join(location.git.gitDir, "HEAD"), "utf8").trim();
|
|
16291
16238
|
} catch {}
|
|
16292
16239
|
const ref = /^ref: refs\/heads\/(.+)$/u.exec(head);
|
|
16293
16240
|
if (ref && ref[1] !== ".invalid")
|
|
@@ -16318,7 +16265,7 @@ function resolveTaskKey(root, location) {
|
|
|
16318
16265
|
return { key: `detached-${shortHash(real(worktree))}`, kind: "detached", branch: null };
|
|
16319
16266
|
}
|
|
16320
16267
|
function checkoutRootOf(root, location) {
|
|
16321
|
-
const resolved =
|
|
16268
|
+
const resolved = path3.resolve(root);
|
|
16322
16269
|
let canonical = resolved;
|
|
16323
16270
|
try {
|
|
16324
16271
|
canonical = fs4.realpathSync(resolved);
|
|
@@ -16349,13 +16296,13 @@ function branchRenames(location) {
|
|
|
16349
16296
|
}
|
|
16350
16297
|
for (const entry of entries)
|
|
16351
16298
|
if (entry.isDirectory())
|
|
16352
|
-
walk(
|
|
16299
|
+
walk(path3.join(dir, entry.name));
|
|
16353
16300
|
else
|
|
16354
|
-
files.push(
|
|
16301
|
+
files.push(path3.join(dir, entry.name));
|
|
16355
16302
|
};
|
|
16356
|
-
walk(
|
|
16303
|
+
walk(path3.join(path3.dirname(location.dir), "logs", "refs", "heads"));
|
|
16357
16304
|
if (location.git)
|
|
16358
|
-
files.push(
|
|
16305
|
+
files.push(path3.join(location.git.gitDir, "logs", "HEAD"));
|
|
16359
16306
|
const seen = new Set;
|
|
16360
16307
|
const renames = [];
|
|
16361
16308
|
for (const file of files) {
|
|
@@ -16390,11 +16337,63 @@ var checkoutSlug = (root) => {
|
|
|
16390
16337
|
let canonical = real(root);
|
|
16391
16338
|
if (process.platform === "win32")
|
|
16392
16339
|
canonical = canonical.toLowerCase();
|
|
16393
|
-
const base =
|
|
16340
|
+
const base = path3.basename(canonical).replace(/[^A-Za-z0-9._-]/g, "_").slice(0, 40) || "root";
|
|
16394
16341
|
return `${base}-${shortHash(canonical)}`;
|
|
16395
16342
|
};
|
|
16396
16343
|
|
|
16344
|
+
// packages/workit-core/src/host-session.ts
|
|
16345
|
+
var HOST_SESSION_VARS = [
|
|
16346
|
+
["OPENCODE_SESSION_ID", () => "opencode"],
|
|
16347
|
+
["PI_SESSION_ID", () => "pi"],
|
|
16348
|
+
[
|
|
16349
|
+
"CODEX_THREAD_ID",
|
|
16350
|
+
(env) => env.CODEX_INTERNAL_ORIGINATOR_OVERRIDE === "Codex Desktop" || env.CODEX_ELECTRON_RESOURCES_PATH ? "codex_desktop" : "codex_cli"
|
|
16351
|
+
]
|
|
16352
|
+
];
|
|
16353
|
+
var family = (host) => host?.replace(/_(?:cli|desktop)$/, "") ?? null;
|
|
16354
|
+
function hostSessionFromEnv(env) {
|
|
16355
|
+
const value = (key) => env[key]?.trim() || null;
|
|
16356
|
+
let inner = null;
|
|
16357
|
+
for (const [key, host] of HOST_SESSION_VARS) {
|
|
16358
|
+
const session = value(key);
|
|
16359
|
+
if (session) {
|
|
16360
|
+
inner = { host: host(env), session };
|
|
16361
|
+
break;
|
|
16362
|
+
}
|
|
16363
|
+
}
|
|
16364
|
+
const declared = value("WORKIT_HOST");
|
|
16365
|
+
if (env.WORKIT_SESSION_ID !== undefined) {
|
|
16366
|
+
const inherited = inner !== null && declared !== null && family(declared) !== family(inner.host);
|
|
16367
|
+
if (!inherited)
|
|
16368
|
+
return { host: declared, session: value("WORKIT_SESSION_ID") };
|
|
16369
|
+
}
|
|
16370
|
+
return inner ? { host: inner.host, session: inner.session } : { host: declared, session: null };
|
|
16371
|
+
}
|
|
16372
|
+
var OWN_CHILD_SHELL = new Set(["opencode", "pi"]);
|
|
16373
|
+
|
|
16374
|
+
// packages/workit-core/src/core/package-root.ts
|
|
16375
|
+
import { existsSync } from "node:fs";
|
|
16376
|
+
import path4 from "node:path";
|
|
16377
|
+
import { fileURLToPath } from "node:url";
|
|
16378
|
+
var packageRoot = () => {
|
|
16379
|
+
let dir = path4.dirname(fileURLToPath(import.meta.url));
|
|
16380
|
+
while (true) {
|
|
16381
|
+
const parent = path4.dirname(dir);
|
|
16382
|
+
if (existsSync(path4.join(dir, "package.json")) || parent === dir)
|
|
16383
|
+
return dir;
|
|
16384
|
+
dir = parent;
|
|
16385
|
+
}
|
|
16386
|
+
};
|
|
16387
|
+
var assetRoot = () => {
|
|
16388
|
+
const root = packageRoot();
|
|
16389
|
+
const assets = path4.join(root, "assets");
|
|
16390
|
+
return existsSync(assets) ? assets : root;
|
|
16391
|
+
};
|
|
16392
|
+
|
|
16397
16393
|
// packages/workit-core/src/core/store-lock.ts
|
|
16394
|
+
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
16395
|
+
import fs5 from "node:fs";
|
|
16396
|
+
import { hostname } from "node:os";
|
|
16398
16397
|
var metadataLockSchema = object({
|
|
16399
16398
|
pid: number2().int().nonnegative().safe(),
|
|
16400
16399
|
processStart: string2().nullable(),
|
|
@@ -17028,6 +17027,38 @@ var isNewerVersion = (candidate, current) => {
|
|
|
17028
17027
|
return false;
|
|
17029
17028
|
};
|
|
17030
17029
|
var validId = (value) => /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/.test(value);
|
|
17030
|
+
var readText = (file) => {
|
|
17031
|
+
try {
|
|
17032
|
+
return fs7.readFileSync(file, "utf8");
|
|
17033
|
+
} catch {
|
|
17034
|
+
return "";
|
|
17035
|
+
}
|
|
17036
|
+
};
|
|
17037
|
+
var REFLOG_LINE = /^[0-9a-f]+ ([0-9a-f]+) .* (\d+) [+-]\d{4}\t(.*)$/u;
|
|
17038
|
+
var branchStart = (location, branch, aliases) => {
|
|
17039
|
+
const first = readText(path6.join(path6.dirname(location.dir), "logs", "refs", "heads", branch)).split(`
|
|
17040
|
+
`, 1)[0];
|
|
17041
|
+
const created = REFLOG_LINE.exec(first);
|
|
17042
|
+
const start = created && /^branch: Created from (\S+)$/u.exec(created[3])?.[1];
|
|
17043
|
+
if (!created || !start)
|
|
17044
|
+
return null;
|
|
17045
|
+
if (start !== "HEAD")
|
|
17046
|
+
return start;
|
|
17047
|
+
if (!location.git)
|
|
17048
|
+
return null;
|
|
17049
|
+
for (const line of readText(path6.join(location.git.gitDir, "logs", "HEAD")).split(`
|
|
17050
|
+
`)) {
|
|
17051
|
+
const entry = REFLOG_LINE.exec(line);
|
|
17052
|
+
const moved = entry && /^checkout: moving from (\S+) to (\S+)$/u.exec(entry[3]);
|
|
17053
|
+
const seconds = entry ? Number(entry[2]) - Number(created[2]) : -1;
|
|
17054
|
+
if (moved && entry[1] === created[1] && seconds >= 0 && seconds <= 1 && aliases.includes(moved[2]))
|
|
17055
|
+
return moved[1];
|
|
17056
|
+
}
|
|
17057
|
+
return null;
|
|
17058
|
+
};
|
|
17059
|
+
var refExists = (common, ref) => fs7.existsSync(path6.join(common, ref)) || readText(path6.join(common, "packed-refs")).includes(` ${ref}
|
|
17060
|
+
`);
|
|
17061
|
+
var origins = new Map;
|
|
17031
17062
|
var sameDirectoryIdentity = (left, right) => {
|
|
17032
17063
|
if (!path6.isAbsolute(left) || !path6.isAbsolute(right))
|
|
17033
17064
|
return false;
|
|
@@ -17280,6 +17311,66 @@ class TaskStore {
|
|
|
17280
17311
|
return bound;
|
|
17281
17312
|
return success(null, null, { key: key.data, bound: bound.data });
|
|
17282
17313
|
}
|
|
17314
|
+
taskForWorker(workerId) {
|
|
17315
|
+
if (typeof workerId !== "string" || !validId(workerId))
|
|
17316
|
+
return failure2("invalid_input", "needs a worker id: `workit worker cancel|report <workerId>`");
|
|
17317
|
+
const listed = this.listTaskIndex();
|
|
17318
|
+
if (!listed.ok)
|
|
17319
|
+
return listed;
|
|
17320
|
+
for (const entry of listed.data) {
|
|
17321
|
+
if (entry.status === "closed")
|
|
17322
|
+
continue;
|
|
17323
|
+
const loaded = this.load(entry.id);
|
|
17324
|
+
if (!loaded.ok)
|
|
17325
|
+
return loaded;
|
|
17326
|
+
if (loaded.data?.record.workers.some((worker) => worker.id === workerId))
|
|
17327
|
+
return success(null, null, entry.id);
|
|
17328
|
+
}
|
|
17329
|
+
return success(null, null, null);
|
|
17330
|
+
}
|
|
17331
|
+
originTaskEntry() {
|
|
17332
|
+
const key = this.currentKey();
|
|
17333
|
+
const location = this.location();
|
|
17334
|
+
const branch = key.ok ? key.data.branch : null;
|
|
17335
|
+
if (!branch || !location.ok)
|
|
17336
|
+
return success(null, null, null);
|
|
17337
|
+
const common = path6.dirname(location.data.dir);
|
|
17338
|
+
const heads = path6.join(common, "logs", "refs", "heads");
|
|
17339
|
+
const headLog = location.data.git ? path6.join(location.data.git.gitDir, "logs", "HEAD") : "";
|
|
17340
|
+
const signatures = [
|
|
17341
|
+
path6.join(heads, branch),
|
|
17342
|
+
headLog,
|
|
17343
|
+
heads,
|
|
17344
|
+
path6.join(common, "packed-refs")
|
|
17345
|
+
].map((file) => fileSignature(file) ?? "-");
|
|
17346
|
+
const slot = `${location.data.dir}\x00${headLog}\x00${branch}`;
|
|
17347
|
+
let resolved = origins.get(slot);
|
|
17348
|
+
if (resolved?.signature !== signatures.join("|")) {
|
|
17349
|
+
const renames = branchRenames(location.data);
|
|
17350
|
+
const aliases = [branch];
|
|
17351
|
+
for (const rename of renames.toReversed())
|
|
17352
|
+
if (rename.to === aliases.at(-1))
|
|
17353
|
+
aliases.push(rename.from);
|
|
17354
|
+
const start = branchStart(location.data, branch, aliases);
|
|
17355
|
+
const slash = start?.indexOf("/") ?? -1;
|
|
17356
|
+
const remote = slash > 0 && !refExists(common, `refs/heads/${start}`) && (refExists(common, `refs/remotes/${start}`) || readText(path6.join(common, "config")).includes(`[remote "${start.slice(0, slash)}"]`));
|
|
17357
|
+
const name = start && (remote ? start.slice(slash + 1) : start);
|
|
17358
|
+
resolved = {
|
|
17359
|
+
signature: signatures.join("|"),
|
|
17360
|
+
name: name && !aliases.includes(name) ? name : null,
|
|
17361
|
+
renames
|
|
17362
|
+
};
|
|
17363
|
+
origins.set(slot, resolved);
|
|
17364
|
+
}
|
|
17365
|
+
const entry = resolved.name ? this.openTasksForKey(resolved.name, resolved.renames) : null;
|
|
17366
|
+
if (entry && !entry.ok)
|
|
17367
|
+
return entry;
|
|
17368
|
+
return success(null, null, entry?.data[0] ? { origin: `branch ${resolved.name}`, entry: entry.data[0] } : null);
|
|
17369
|
+
}
|
|
17370
|
+
readStoreTask(taskId) {
|
|
17371
|
+
const loaded = this.load(taskId);
|
|
17372
|
+
return loaded.ok ? success(null, null, loaded.data?.record ?? null) : loaded;
|
|
17373
|
+
}
|
|
17283
17374
|
create(input, provenance, expectedWorkspaceRevision) {
|
|
17284
17375
|
const value = "intent" in input ? input : {
|
|
17285
17376
|
intent: input,
|
|
@@ -17949,12 +18040,12 @@ class TaskStore {
|
|
|
17949
18040
|
return 0;
|
|
17950
18041
|
}
|
|
17951
18042
|
}
|
|
17952
|
-
openTasksForKey(key) {
|
|
18043
|
+
openTasksForKey(key, known) {
|
|
17953
18044
|
const all = this.listStoreIndex();
|
|
17954
18045
|
if (!all.ok)
|
|
17955
18046
|
return all;
|
|
17956
|
-
const location = this.location();
|
|
17957
|
-
const renames = location
|
|
18047
|
+
const location = known ? null : this.location();
|
|
18048
|
+
const renames = known ?? (location?.ok ? branchRenames(location.data) : []);
|
|
17958
18049
|
return success(null, null, all.data.filter((entry) => entry.key !== null && entry.status !== "closed").filter((entry) => (renames.length ? followRenames(entry.key, entry.boundAt ?? entry.createdAt, renames) : entry.key) === key).toSorted(oldestFirst));
|
|
17959
18050
|
}
|
|
17960
18051
|
openTaskForKey(key) {
|
|
@@ -20935,11 +21026,20 @@ function authorSessions(cwd, rows, branch, range = { base: null, head: null }, s
|
|
|
20935
21026
|
sessions.add(session);
|
|
20936
21027
|
return sessions;
|
|
20937
21028
|
}
|
|
21029
|
+
var derivesFrom = (derived, bare) => !bare.includes(":") && derived.endsWith(`:${bare}`);
|
|
21030
|
+
var authoredBy = (authors, session) => {
|
|
21031
|
+
if (authors.has(session))
|
|
21032
|
+
return true;
|
|
21033
|
+
for (const author of authors)
|
|
21034
|
+
if (derivesFrom(author, session) || derivesFrom(session, author))
|
|
21035
|
+
return true;
|
|
21036
|
+
return false;
|
|
21037
|
+
};
|
|
20938
21038
|
var independenceReasons = (row, authors) => {
|
|
20939
21039
|
const reasons = [];
|
|
20940
21040
|
if (!row.actor.session)
|
|
20941
21041
|
reasons.push("no_session");
|
|
20942
|
-
else if (authors
|
|
21042
|
+
else if (authoredBy(authors, row.actor.session))
|
|
20943
21043
|
reasons.push("author_session");
|
|
20944
21044
|
if (row.self === true && !reasons.includes("no_session"))
|
|
20945
21045
|
reasons.push("self");
|
|
@@ -22040,38 +22140,45 @@ var compactReference = (ref) => {
|
|
|
22040
22140
|
};
|
|
22041
22141
|
return { kind: ref.kind };
|
|
22042
22142
|
};
|
|
22043
|
-
|
|
22044
|
-
const
|
|
22045
|
-
|
|
22046
|
-
|
|
22047
|
-
|
|
22048
|
-
|
|
22049
|
-
|
|
22050
|
-
|
|
22051
|
-
|
|
22052
|
-
|
|
22053
|
-
|
|
22054
|
-
|
|
22055
|
-
|
|
22056
|
-
|
|
22057
|
-
|
|
22058
|
-
|
|
22143
|
+
var newestDecisionFirst = (left, right) => {
|
|
22144
|
+
const leftAt = compactTimestamp(left.recordedAt);
|
|
22145
|
+
const rightAt = compactTimestamp(right.recordedAt);
|
|
22146
|
+
if (leftAt !== rightAt)
|
|
22147
|
+
return leftAt > rightAt ? -1 : 1;
|
|
22148
|
+
return left.id < right.id ? -1 : left.id > right.id ? 1 : 0;
|
|
22149
|
+
};
|
|
22150
|
+
var compactDecisions = (sources) => sources.flatMap((source) => source ? source.decisions.toSorted(newestDecisionFirst).map((entry) => ({
|
|
22151
|
+
id: entry.id,
|
|
22152
|
+
purpose: entry.data.purpose,
|
|
22153
|
+
status: entry.data.response,
|
|
22154
|
+
digest: entry.data.digest,
|
|
22155
|
+
choice: compactDecisionChoice(entry) || `task.inspect taskId=${source.taskId} view=full; decision=${entry.id}`,
|
|
22156
|
+
references: entry.data.binding.contentRefs.slice(0, 1).map(compactReference),
|
|
22157
|
+
origin: source.origin ?? undefined
|
|
22158
|
+
})) : []).slice(0, COMPACT_MAX_ITEMS);
|
|
22159
|
+
function compactTaskContext(view, inherited = null) {
|
|
22160
|
+
const decisions = compactDecisions([
|
|
22161
|
+
view && { origin: null, taskId: view.task.id, decisions: view.task.decisions },
|
|
22162
|
+
inherited
|
|
22163
|
+
]);
|
|
22164
|
+
const methods = view?.task.policy ? selectMethods(view.task.policy, view.capabilities).map((method) => ({
|
|
22059
22165
|
id: method.id,
|
|
22060
22166
|
assurance: method.assurance,
|
|
22061
22167
|
reason: compactText(method.reason, COMPACT_TEXT_BYTES) ?? ""
|
|
22062
22168
|
})) : [];
|
|
22169
|
+
const stale = view?.evidence.filter((entry) => entry.status === "stale").length;
|
|
22063
22170
|
const gaps = Array.from(new Set([
|
|
22064
|
-
...
|
|
22065
|
-
...view
|
|
22066
|
-
...view
|
|
22171
|
+
...stale ? [`stale evidence: ${stale}; workit task inspect --task ${view.task.id} --view full`] : [],
|
|
22172
|
+
...(view?.requirements ?? []).filter((entry) => entry.status !== "satisfied").map((entry) => entry.reason),
|
|
22173
|
+
...(view?.task.progress.blockers ?? []).map((entry) => entry.reason)
|
|
22067
22174
|
])).toSorted().slice(0, COMPACT_MAX_ITEMS).map((gap) => compactText(gap, COMPACT_TEXT_BYTES));
|
|
22068
22175
|
const context = {
|
|
22069
|
-
objective: compactText(view.task.intent.data.objective, COMPACT_TEXT_BYTES) ?? "",
|
|
22070
|
-
status: view
|
|
22176
|
+
objective: view ? compactText(view.task.intent.data.objective, COMPACT_TEXT_BYTES) ?? "" : "no task on this branch yet",
|
|
22177
|
+
status: view?.task.status ?? null,
|
|
22071
22178
|
decisions,
|
|
22072
22179
|
methods,
|
|
22073
22180
|
gaps,
|
|
22074
|
-
nextAction: compactText(view
|
|
22181
|
+
nextAction: compactText(view?.task.progress.nextAction ?? null, COMPACT_TEXT_BYTES)
|
|
22075
22182
|
};
|
|
22076
22183
|
let encoded = JSON.stringify(context);
|
|
22077
22184
|
while (compactBytes(encoded) > COMPACT_MAX_BYTES && (context.decisions.length || context.methods.length || context.gaps.length)) {
|
|
@@ -22676,6 +22783,13 @@ var TASK_SCOPED_ACTIONS = new Set([
|
|
|
22676
22783
|
"worker.cancel",
|
|
22677
22784
|
"state.export"
|
|
22678
22785
|
]);
|
|
22786
|
+
var WORKER_ADDRESSED_ACTIONS = new Set(["worker.cancel", "worker.report"]);
|
|
22787
|
+
var workerCommand = (taskId, request) => {
|
|
22788
|
+
const { action, workerId, reason, report } = request;
|
|
22789
|
+
const rest = JSON.stringify({ reason, report });
|
|
22790
|
+
const payload = rest === "{}" ? "" : ` --payload '${rest.replace(/'/gu, "'\\''")}'`;
|
|
22791
|
+
return `workit worker ${String(action)} ${String(workerId)} --task ${taskId}${payload}`;
|
|
22792
|
+
};
|
|
22679
22793
|
var CREATING_ACTIONS = new Set([
|
|
22680
22794
|
"task.revise",
|
|
22681
22795
|
"task.progress",
|
|
@@ -22926,6 +23040,17 @@ class WorkitCore {
|
|
|
22926
23040
|
const root = this.contextRootError();
|
|
22927
23041
|
if (!root.ok)
|
|
22928
23042
|
return root;
|
|
23043
|
+
const addressed = WORKER_ADDRESSED_ACTIONS.has(action);
|
|
23044
|
+
const workerId = addressed ? value.workerId : this.context.workerId ?? null;
|
|
23045
|
+
if (workerId !== null) {
|
|
23046
|
+
const owner = this.store.taskForWorker(workerId);
|
|
23047
|
+
if (!owner.ok)
|
|
23048
|
+
return owner;
|
|
23049
|
+
if (owner.data)
|
|
23050
|
+
return success(null, null, { ...request, taskId: owner.data });
|
|
23051
|
+
if (addressed)
|
|
23052
|
+
return failure2("not_found", `worker ${workerId} is on no open task; find its task with \`workit task status --all\`, then run \`${workerCommand("<task-id>", request)}\``);
|
|
23053
|
+
}
|
|
22929
23054
|
const create = CREATING_ACTIONS.has(action) && (this.context.workerId ?? null) === null;
|
|
22930
23055
|
const found = this.store.implicitTask({
|
|
22931
23056
|
provenance: provenance(this.context),
|
|
@@ -23632,7 +23757,9 @@ class WorkitCore {
|
|
|
23632
23757
|
if (!resolved.ok)
|
|
23633
23758
|
return resolved;
|
|
23634
23759
|
const value = resolved.data;
|
|
23635
|
-
|
|
23760
|
+
const result = this.retryOmittedRevisions(value, () => this.workerOnce(value));
|
|
23761
|
+
const { action, taskId } = value ?? {};
|
|
23762
|
+
return result.ok || request?.taskId !== undefined || typeof taskId !== "string" || !WORKER_ADDRESSED_ACTIONS.has(`worker.${String(action)}`) ? result : { ...result, error: `${result.error}; run \`${workerCommand(taskId, value)}\`` };
|
|
23636
23763
|
}
|
|
23637
23764
|
workerOnce(request) {
|
|
23638
23765
|
const root = this.contextRootError();
|
|
@@ -23837,10 +23964,18 @@ class WorkitCore {
|
|
|
23837
23964
|
requirements
|
|
23838
23965
|
});
|
|
23839
23966
|
}
|
|
23840
|
-
compactContext(taskId, freshness) {
|
|
23967
|
+
compactContext(taskId, freshness, origin = null) {
|
|
23841
23968
|
const root = this.contextRootError();
|
|
23842
23969
|
if (!root.ok)
|
|
23843
23970
|
return root;
|
|
23971
|
+
const base = origin && this.store.readStoreTask(origin.taskId);
|
|
23972
|
+
const inherited = base?.ok && base.data ? {
|
|
23973
|
+
origin: origin.origin,
|
|
23974
|
+
taskId: base.data.id,
|
|
23975
|
+
decisions: base.data.decisions.filter((entry) => entry.data.revoked === null)
|
|
23976
|
+
} : null;
|
|
23977
|
+
if (taskId === null)
|
|
23978
|
+
return success(null, null, inherited?.decisions.length ? compactTaskContext(null, inherited) : "");
|
|
23844
23979
|
const task = this.store.readTask(taskId);
|
|
23845
23980
|
if (!task.ok)
|
|
23846
23981
|
return task;
|
|
@@ -23850,7 +23985,7 @@ class WorkitCore {
|
|
|
23850
23985
|
const view = this.view(task.data, false, freshness ?? signalFreshness(this.store.root));
|
|
23851
23986
|
if (!view.ok)
|
|
23852
23987
|
return view;
|
|
23853
|
-
return success(view.revision, view.workspaceRevision, compactTaskContext(view.data));
|
|
23988
|
+
return success(view.revision, view.workspaceRevision, compactTaskContext(view.data, inherited));
|
|
23854
23989
|
}
|
|
23855
23990
|
view(task, capture = true, freshness = treeFreshness(this.store.root)) {
|
|
23856
23991
|
const workspace = this.store.readWorkspace();
|