@brainervirus/workit-codex 8.8.0 → 8.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/launch-mcp.js
CHANGED
|
@@ -17028,6 +17028,38 @@ var isNewerVersion = (candidate, current) => {
|
|
|
17028
17028
|
return false;
|
|
17029
17029
|
};
|
|
17030
17030
|
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);
|
|
17031
|
+
var readText = (file) => {
|
|
17032
|
+
try {
|
|
17033
|
+
return fs7.readFileSync(file, "utf8");
|
|
17034
|
+
} catch {
|
|
17035
|
+
return "";
|
|
17036
|
+
}
|
|
17037
|
+
};
|
|
17038
|
+
var REFLOG_LINE = /^[0-9a-f]+ ([0-9a-f]+) .* (\d+) [+-]\d{4}\t(.*)$/u;
|
|
17039
|
+
var branchStart = (location, branch, aliases) => {
|
|
17040
|
+
const first = readText(path6.join(path6.dirname(location.dir), "logs", "refs", "heads", branch)).split(`
|
|
17041
|
+
`, 1)[0];
|
|
17042
|
+
const created = REFLOG_LINE.exec(first);
|
|
17043
|
+
const start = created && /^branch: Created from (\S+)$/u.exec(created[3])?.[1];
|
|
17044
|
+
if (!created || !start)
|
|
17045
|
+
return null;
|
|
17046
|
+
if (start !== "HEAD")
|
|
17047
|
+
return start;
|
|
17048
|
+
if (!location.git)
|
|
17049
|
+
return null;
|
|
17050
|
+
for (const line of readText(path6.join(location.git.gitDir, "logs", "HEAD")).split(`
|
|
17051
|
+
`)) {
|
|
17052
|
+
const entry = REFLOG_LINE.exec(line);
|
|
17053
|
+
const moved = entry && /^checkout: moving from (\S+) to (\S+)$/u.exec(entry[3]);
|
|
17054
|
+
const seconds = entry ? Number(entry[2]) - Number(created[2]) : -1;
|
|
17055
|
+
if (moved && entry[1] === created[1] && seconds >= 0 && seconds <= 1 && aliases.includes(moved[2]))
|
|
17056
|
+
return moved[1];
|
|
17057
|
+
}
|
|
17058
|
+
return null;
|
|
17059
|
+
};
|
|
17060
|
+
var refExists = (common, ref) => fs7.existsSync(path6.join(common, ref)) || readText(path6.join(common, "packed-refs")).includes(` ${ref}
|
|
17061
|
+
`);
|
|
17062
|
+
var origins = new Map;
|
|
17031
17063
|
var sameDirectoryIdentity = (left, right) => {
|
|
17032
17064
|
if (!path6.isAbsolute(left) || !path6.isAbsolute(right))
|
|
17033
17065
|
return false;
|
|
@@ -17280,6 +17312,66 @@ class TaskStore {
|
|
|
17280
17312
|
return bound;
|
|
17281
17313
|
return success(null, null, { key: key.data, bound: bound.data });
|
|
17282
17314
|
}
|
|
17315
|
+
taskForWorker(workerId) {
|
|
17316
|
+
if (typeof workerId !== "string" || !validId(workerId))
|
|
17317
|
+
return failure2("invalid_input", "needs a worker id: `workit worker cancel|report <workerId>`");
|
|
17318
|
+
const listed = this.listTaskIndex();
|
|
17319
|
+
if (!listed.ok)
|
|
17320
|
+
return listed;
|
|
17321
|
+
for (const entry of listed.data) {
|
|
17322
|
+
if (entry.status === "closed")
|
|
17323
|
+
continue;
|
|
17324
|
+
const loaded = this.load(entry.id);
|
|
17325
|
+
if (!loaded.ok)
|
|
17326
|
+
return loaded;
|
|
17327
|
+
if (loaded.data?.record.workers.some((worker) => worker.id === workerId))
|
|
17328
|
+
return success(null, null, entry.id);
|
|
17329
|
+
}
|
|
17330
|
+
return success(null, null, null);
|
|
17331
|
+
}
|
|
17332
|
+
originTaskEntry() {
|
|
17333
|
+
const key = this.currentKey();
|
|
17334
|
+
const location = this.location();
|
|
17335
|
+
const branch = key.ok ? key.data.branch : null;
|
|
17336
|
+
if (!branch || !location.ok)
|
|
17337
|
+
return success(null, null, null);
|
|
17338
|
+
const common = path6.dirname(location.data.dir);
|
|
17339
|
+
const heads = path6.join(common, "logs", "refs", "heads");
|
|
17340
|
+
const headLog = location.data.git ? path6.join(location.data.git.gitDir, "logs", "HEAD") : "";
|
|
17341
|
+
const signatures = [
|
|
17342
|
+
path6.join(heads, branch),
|
|
17343
|
+
headLog,
|
|
17344
|
+
heads,
|
|
17345
|
+
path6.join(common, "packed-refs")
|
|
17346
|
+
].map((file) => fileSignature(file) ?? "-");
|
|
17347
|
+
const slot = `${location.data.dir}\x00${headLog}\x00${branch}`;
|
|
17348
|
+
let resolved = origins.get(slot);
|
|
17349
|
+
if (resolved?.signature !== signatures.join("|")) {
|
|
17350
|
+
const renames = branchRenames(location.data);
|
|
17351
|
+
const aliases = [branch];
|
|
17352
|
+
for (const rename of renames.toReversed())
|
|
17353
|
+
if (rename.to === aliases.at(-1))
|
|
17354
|
+
aliases.push(rename.from);
|
|
17355
|
+
const start = branchStart(location.data, branch, aliases);
|
|
17356
|
+
const slash = start?.indexOf("/") ?? -1;
|
|
17357
|
+
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)}"]`));
|
|
17358
|
+
const name = start && (remote ? start.slice(slash + 1) : start);
|
|
17359
|
+
resolved = {
|
|
17360
|
+
signature: signatures.join("|"),
|
|
17361
|
+
name: name && !aliases.includes(name) ? name : null,
|
|
17362
|
+
renames
|
|
17363
|
+
};
|
|
17364
|
+
origins.set(slot, resolved);
|
|
17365
|
+
}
|
|
17366
|
+
const entry = resolved.name ? this.openTasksForKey(resolved.name, resolved.renames) : null;
|
|
17367
|
+
if (entry && !entry.ok)
|
|
17368
|
+
return entry;
|
|
17369
|
+
return success(null, null, entry?.data[0] ? { origin: `branch ${resolved.name}`, entry: entry.data[0] } : null);
|
|
17370
|
+
}
|
|
17371
|
+
readStoreTask(taskId) {
|
|
17372
|
+
const loaded = this.load(taskId);
|
|
17373
|
+
return loaded.ok ? success(null, null, loaded.data?.record ?? null) : loaded;
|
|
17374
|
+
}
|
|
17283
17375
|
create(input, provenance, expectedWorkspaceRevision) {
|
|
17284
17376
|
const value = "intent" in input ? input : {
|
|
17285
17377
|
intent: input,
|
|
@@ -17949,12 +18041,12 @@ class TaskStore {
|
|
|
17949
18041
|
return 0;
|
|
17950
18042
|
}
|
|
17951
18043
|
}
|
|
17952
|
-
openTasksForKey(key) {
|
|
18044
|
+
openTasksForKey(key, known) {
|
|
17953
18045
|
const all = this.listStoreIndex();
|
|
17954
18046
|
if (!all.ok)
|
|
17955
18047
|
return all;
|
|
17956
|
-
const location = this.location();
|
|
17957
|
-
const renames = location
|
|
18048
|
+
const location = known ? null : this.location();
|
|
18049
|
+
const renames = known ?? (location?.ok ? branchRenames(location.data) : []);
|
|
17958
18050
|
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
18051
|
}
|
|
17960
18052
|
openTaskForKey(key) {
|
|
@@ -22040,38 +22132,45 @@ var compactReference = (ref) => {
|
|
|
22040
22132
|
};
|
|
22041
22133
|
return { kind: ref.kind };
|
|
22042
22134
|
};
|
|
22043
|
-
|
|
22044
|
-
const
|
|
22045
|
-
|
|
22046
|
-
|
|
22047
|
-
|
|
22048
|
-
|
|
22049
|
-
|
|
22050
|
-
|
|
22051
|
-
|
|
22052
|
-
|
|
22053
|
-
|
|
22054
|
-
|
|
22055
|
-
|
|
22056
|
-
|
|
22057
|
-
|
|
22058
|
-
|
|
22135
|
+
var newestDecisionFirst = (left, right) => {
|
|
22136
|
+
const leftAt = compactTimestamp(left.recordedAt);
|
|
22137
|
+
const rightAt = compactTimestamp(right.recordedAt);
|
|
22138
|
+
if (leftAt !== rightAt)
|
|
22139
|
+
return leftAt > rightAt ? -1 : 1;
|
|
22140
|
+
return left.id < right.id ? -1 : left.id > right.id ? 1 : 0;
|
|
22141
|
+
};
|
|
22142
|
+
var compactDecisions = (sources) => sources.flatMap((source) => source ? source.decisions.toSorted(newestDecisionFirst).map((entry) => ({
|
|
22143
|
+
id: entry.id,
|
|
22144
|
+
purpose: entry.data.purpose,
|
|
22145
|
+
status: entry.data.response,
|
|
22146
|
+
digest: entry.data.digest,
|
|
22147
|
+
choice: compactDecisionChoice(entry) || `task.inspect taskId=${source.taskId} view=full; decision=${entry.id}`,
|
|
22148
|
+
references: entry.data.binding.contentRefs.slice(0, 1).map(compactReference),
|
|
22149
|
+
origin: source.origin ?? undefined
|
|
22150
|
+
})) : []).slice(0, COMPACT_MAX_ITEMS);
|
|
22151
|
+
function compactTaskContext(view, inherited = null) {
|
|
22152
|
+
const decisions = compactDecisions([
|
|
22153
|
+
view && { origin: null, taskId: view.task.id, decisions: view.task.decisions },
|
|
22154
|
+
inherited
|
|
22155
|
+
]);
|
|
22156
|
+
const methods = view?.task.policy ? selectMethods(view.task.policy, view.capabilities).map((method) => ({
|
|
22059
22157
|
id: method.id,
|
|
22060
22158
|
assurance: method.assurance,
|
|
22061
22159
|
reason: compactText(method.reason, COMPACT_TEXT_BYTES) ?? ""
|
|
22062
22160
|
})) : [];
|
|
22161
|
+
const stale = view?.evidence.filter((entry) => entry.status === "stale").length;
|
|
22063
22162
|
const gaps = Array.from(new Set([
|
|
22064
|
-
...
|
|
22065
|
-
...view
|
|
22066
|
-
...view
|
|
22163
|
+
...stale ? [`stale evidence: ${stale}; workit task inspect --task ${view.task.id} --view full`] : [],
|
|
22164
|
+
...(view?.requirements ?? []).filter((entry) => entry.status !== "satisfied").map((entry) => entry.reason),
|
|
22165
|
+
...(view?.task.progress.blockers ?? []).map((entry) => entry.reason)
|
|
22067
22166
|
])).toSorted().slice(0, COMPACT_MAX_ITEMS).map((gap) => compactText(gap, COMPACT_TEXT_BYTES));
|
|
22068
22167
|
const context = {
|
|
22069
|
-
objective: compactText(view.task.intent.data.objective, COMPACT_TEXT_BYTES) ?? "",
|
|
22070
|
-
status: view
|
|
22168
|
+
objective: view ? compactText(view.task.intent.data.objective, COMPACT_TEXT_BYTES) ?? "" : "no task on this branch yet",
|
|
22169
|
+
status: view?.task.status ?? null,
|
|
22071
22170
|
decisions,
|
|
22072
22171
|
methods,
|
|
22073
22172
|
gaps,
|
|
22074
|
-
nextAction: compactText(view
|
|
22173
|
+
nextAction: compactText(view?.task.progress.nextAction ?? null, COMPACT_TEXT_BYTES)
|
|
22075
22174
|
};
|
|
22076
22175
|
let encoded = JSON.stringify(context);
|
|
22077
22176
|
while (compactBytes(encoded) > COMPACT_MAX_BYTES && (context.decisions.length || context.methods.length || context.gaps.length)) {
|
|
@@ -22676,6 +22775,13 @@ var TASK_SCOPED_ACTIONS = new Set([
|
|
|
22676
22775
|
"worker.cancel",
|
|
22677
22776
|
"state.export"
|
|
22678
22777
|
]);
|
|
22778
|
+
var WORKER_ADDRESSED_ACTIONS = new Set(["worker.cancel", "worker.report"]);
|
|
22779
|
+
var workerCommand = (taskId, request) => {
|
|
22780
|
+
const { action, workerId, reason, report } = request;
|
|
22781
|
+
const rest = JSON.stringify({ reason, report });
|
|
22782
|
+
const payload = rest === "{}" ? "" : ` --payload '${rest.replace(/'/gu, "'\\''")}'`;
|
|
22783
|
+
return `workit worker ${String(action)} ${String(workerId)} --task ${taskId}${payload}`;
|
|
22784
|
+
};
|
|
22679
22785
|
var CREATING_ACTIONS = new Set([
|
|
22680
22786
|
"task.revise",
|
|
22681
22787
|
"task.progress",
|
|
@@ -22926,6 +23032,17 @@ class WorkitCore {
|
|
|
22926
23032
|
const root = this.contextRootError();
|
|
22927
23033
|
if (!root.ok)
|
|
22928
23034
|
return root;
|
|
23035
|
+
const addressed = WORKER_ADDRESSED_ACTIONS.has(action);
|
|
23036
|
+
const workerId = addressed ? value.workerId : this.context.workerId ?? null;
|
|
23037
|
+
if (workerId !== null) {
|
|
23038
|
+
const owner = this.store.taskForWorker(workerId);
|
|
23039
|
+
if (!owner.ok)
|
|
23040
|
+
return owner;
|
|
23041
|
+
if (owner.data)
|
|
23042
|
+
return success(null, null, { ...request, taskId: owner.data });
|
|
23043
|
+
if (addressed)
|
|
23044
|
+
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)}\``);
|
|
23045
|
+
}
|
|
22929
23046
|
const create = CREATING_ACTIONS.has(action) && (this.context.workerId ?? null) === null;
|
|
22930
23047
|
const found = this.store.implicitTask({
|
|
22931
23048
|
provenance: provenance(this.context),
|
|
@@ -23632,7 +23749,9 @@ class WorkitCore {
|
|
|
23632
23749
|
if (!resolved.ok)
|
|
23633
23750
|
return resolved;
|
|
23634
23751
|
const value = resolved.data;
|
|
23635
|
-
|
|
23752
|
+
const result = this.retryOmittedRevisions(value, () => this.workerOnce(value));
|
|
23753
|
+
const { action, taskId } = value ?? {};
|
|
23754
|
+
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
23755
|
}
|
|
23637
23756
|
workerOnce(request) {
|
|
23638
23757
|
const root = this.contextRootError();
|
|
@@ -23837,10 +23956,18 @@ class WorkitCore {
|
|
|
23837
23956
|
requirements
|
|
23838
23957
|
});
|
|
23839
23958
|
}
|
|
23840
|
-
compactContext(taskId, freshness) {
|
|
23959
|
+
compactContext(taskId, freshness, origin = null) {
|
|
23841
23960
|
const root = this.contextRootError();
|
|
23842
23961
|
if (!root.ok)
|
|
23843
23962
|
return root;
|
|
23963
|
+
const base = origin && this.store.readStoreTask(origin.taskId);
|
|
23964
|
+
const inherited = base?.ok && base.data ? {
|
|
23965
|
+
origin: origin.origin,
|
|
23966
|
+
taskId: base.data.id,
|
|
23967
|
+
decisions: base.data.decisions.filter((entry) => entry.data.revoked === null)
|
|
23968
|
+
} : null;
|
|
23969
|
+
if (taskId === null)
|
|
23970
|
+
return success(null, null, inherited?.decisions.length ? compactTaskContext(null, inherited) : "");
|
|
23844
23971
|
const task = this.store.readTask(taskId);
|
|
23845
23972
|
if (!task.ok)
|
|
23846
23973
|
return task;
|
|
@@ -23850,7 +23977,7 @@ class WorkitCore {
|
|
|
23850
23977
|
const view = this.view(task.data, false, freshness ?? signalFreshness(this.store.root));
|
|
23851
23978
|
if (!view.ok)
|
|
23852
23979
|
return view;
|
|
23853
|
-
return success(view.revision, view.workspaceRevision, compactTaskContext(view.data));
|
|
23980
|
+
return success(view.revision, view.workspaceRevision, compactTaskContext(view.data, inherited));
|
|
23854
23981
|
}
|
|
23855
23982
|
view(task, capture = true, freshness = treeFreshness(this.store.root)) {
|
|
23856
23983
|
const workspace = this.store.readWorkspace();
|
|
@@ -10464,6 +10464,38 @@ var isNewerVersion = (candidate, current) => {
|
|
|
10464
10464
|
return false;
|
|
10465
10465
|
};
|
|
10466
10466
|
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);
|
|
10467
|
+
var readText = (file) => {
|
|
10468
|
+
try {
|
|
10469
|
+
return fs9.readFileSync(file, "utf8");
|
|
10470
|
+
} catch {
|
|
10471
|
+
return "";
|
|
10472
|
+
}
|
|
10473
|
+
};
|
|
10474
|
+
var REFLOG_LINE = /^[0-9a-f]+ ([0-9a-f]+) .* (\d+) [+-]\d{4}\t(.*)$/u;
|
|
10475
|
+
var branchStart = (location, branch, aliases) => {
|
|
10476
|
+
const first = readText(path8.join(path8.dirname(location.dir), "logs", "refs", "heads", branch)).split(`
|
|
10477
|
+
`, 1)[0];
|
|
10478
|
+
const created = REFLOG_LINE.exec(first);
|
|
10479
|
+
const start = created && /^branch: Created from (\S+)$/u.exec(created[3])?.[1];
|
|
10480
|
+
if (!created || !start)
|
|
10481
|
+
return null;
|
|
10482
|
+
if (start !== "HEAD")
|
|
10483
|
+
return start;
|
|
10484
|
+
if (!location.git)
|
|
10485
|
+
return null;
|
|
10486
|
+
for (const line of readText(path8.join(location.git.gitDir, "logs", "HEAD")).split(`
|
|
10487
|
+
`)) {
|
|
10488
|
+
const entry = REFLOG_LINE.exec(line);
|
|
10489
|
+
const moved = entry && /^checkout: moving from (\S+) to (\S+)$/u.exec(entry[3]);
|
|
10490
|
+
const seconds = entry ? Number(entry[2]) - Number(created[2]) : -1;
|
|
10491
|
+
if (moved && entry[1] === created[1] && seconds >= 0 && seconds <= 1 && aliases.includes(moved[2]))
|
|
10492
|
+
return moved[1];
|
|
10493
|
+
}
|
|
10494
|
+
return null;
|
|
10495
|
+
};
|
|
10496
|
+
var refExists = (common, ref) => fs9.existsSync(path8.join(common, ref)) || readText(path8.join(common, "packed-refs")).includes(` ${ref}
|
|
10497
|
+
`);
|
|
10498
|
+
var origins = new Map;
|
|
10467
10499
|
var sameDirectoryIdentity = (left, right) => {
|
|
10468
10500
|
if (!path8.isAbsolute(left) || !path8.isAbsolute(right))
|
|
10469
10501
|
return false;
|
|
@@ -10716,6 +10748,66 @@ class TaskStore {
|
|
|
10716
10748
|
return bound;
|
|
10717
10749
|
return success(null, null, { key: key.data, bound: bound.data });
|
|
10718
10750
|
}
|
|
10751
|
+
taskForWorker(workerId) {
|
|
10752
|
+
if (typeof workerId !== "string" || !validId(workerId))
|
|
10753
|
+
return failure2("invalid_input", "needs a worker id: `workit worker cancel|report <workerId>`");
|
|
10754
|
+
const listed = this.listTaskIndex();
|
|
10755
|
+
if (!listed.ok)
|
|
10756
|
+
return listed;
|
|
10757
|
+
for (const entry of listed.data) {
|
|
10758
|
+
if (entry.status === "closed")
|
|
10759
|
+
continue;
|
|
10760
|
+
const loaded = this.load(entry.id);
|
|
10761
|
+
if (!loaded.ok)
|
|
10762
|
+
return loaded;
|
|
10763
|
+
if (loaded.data?.record.workers.some((worker) => worker.id === workerId))
|
|
10764
|
+
return success(null, null, entry.id);
|
|
10765
|
+
}
|
|
10766
|
+
return success(null, null, null);
|
|
10767
|
+
}
|
|
10768
|
+
originTaskEntry() {
|
|
10769
|
+
const key = this.currentKey();
|
|
10770
|
+
const location = this.location();
|
|
10771
|
+
const branch = key.ok ? key.data.branch : null;
|
|
10772
|
+
if (!branch || !location.ok)
|
|
10773
|
+
return success(null, null, null);
|
|
10774
|
+
const common = path8.dirname(location.data.dir);
|
|
10775
|
+
const heads = path8.join(common, "logs", "refs", "heads");
|
|
10776
|
+
const headLog = location.data.git ? path8.join(location.data.git.gitDir, "logs", "HEAD") : "";
|
|
10777
|
+
const signatures = [
|
|
10778
|
+
path8.join(heads, branch),
|
|
10779
|
+
headLog,
|
|
10780
|
+
heads,
|
|
10781
|
+
path8.join(common, "packed-refs")
|
|
10782
|
+
].map((file) => fileSignature(file) ?? "-");
|
|
10783
|
+
const slot = `${location.data.dir}\x00${headLog}\x00${branch}`;
|
|
10784
|
+
let resolved = origins.get(slot);
|
|
10785
|
+
if (resolved?.signature !== signatures.join("|")) {
|
|
10786
|
+
const renames = branchRenames(location.data);
|
|
10787
|
+
const aliases = [branch];
|
|
10788
|
+
for (const rename of renames.toReversed())
|
|
10789
|
+
if (rename.to === aliases.at(-1))
|
|
10790
|
+
aliases.push(rename.from);
|
|
10791
|
+
const start = branchStart(location.data, branch, aliases);
|
|
10792
|
+
const slash = start?.indexOf("/") ?? -1;
|
|
10793
|
+
const remote = slash > 0 && !refExists(common, `refs/heads/${start}`) && (refExists(common, `refs/remotes/${start}`) || readText(path8.join(common, "config")).includes(`[remote "${start.slice(0, slash)}"]`));
|
|
10794
|
+
const name = start && (remote ? start.slice(slash + 1) : start);
|
|
10795
|
+
resolved = {
|
|
10796
|
+
signature: signatures.join("|"),
|
|
10797
|
+
name: name && !aliases.includes(name) ? name : null,
|
|
10798
|
+
renames
|
|
10799
|
+
};
|
|
10800
|
+
origins.set(slot, resolved);
|
|
10801
|
+
}
|
|
10802
|
+
const entry = resolved.name ? this.openTasksForKey(resolved.name, resolved.renames) : null;
|
|
10803
|
+
if (entry && !entry.ok)
|
|
10804
|
+
return entry;
|
|
10805
|
+
return success(null, null, entry?.data[0] ? { origin: `branch ${resolved.name}`, entry: entry.data[0] } : null);
|
|
10806
|
+
}
|
|
10807
|
+
readStoreTask(taskId) {
|
|
10808
|
+
const loaded = this.load(taskId);
|
|
10809
|
+
return loaded.ok ? success(null, null, loaded.data?.record ?? null) : loaded;
|
|
10810
|
+
}
|
|
10719
10811
|
create(input, provenance, expectedWorkspaceRevision) {
|
|
10720
10812
|
const value = "intent" in input ? input : {
|
|
10721
10813
|
intent: input,
|
|
@@ -11385,12 +11477,12 @@ class TaskStore {
|
|
|
11385
11477
|
return 0;
|
|
11386
11478
|
}
|
|
11387
11479
|
}
|
|
11388
|
-
openTasksForKey(key) {
|
|
11480
|
+
openTasksForKey(key, known) {
|
|
11389
11481
|
const all = this.listStoreIndex();
|
|
11390
11482
|
if (!all.ok)
|
|
11391
11483
|
return all;
|
|
11392
|
-
const location = this.location();
|
|
11393
|
-
const renames = location
|
|
11484
|
+
const location = known ? null : this.location();
|
|
11485
|
+
const renames = known ?? (location?.ok ? branchRenames(location.data) : []);
|
|
11394
11486
|
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));
|
|
11395
11487
|
}
|
|
11396
11488
|
openTaskForKey(key) {
|
|
@@ -15599,38 +15691,45 @@ var compactReference = (ref) => {
|
|
|
15599
15691
|
};
|
|
15600
15692
|
return { kind: ref.kind };
|
|
15601
15693
|
};
|
|
15602
|
-
|
|
15603
|
-
const
|
|
15604
|
-
|
|
15605
|
-
|
|
15606
|
-
|
|
15607
|
-
|
|
15608
|
-
|
|
15609
|
-
|
|
15610
|
-
|
|
15611
|
-
|
|
15612
|
-
|
|
15613
|
-
|
|
15614
|
-
|
|
15615
|
-
|
|
15616
|
-
|
|
15617
|
-
|
|
15694
|
+
var newestDecisionFirst = (left, right) => {
|
|
15695
|
+
const leftAt = compactTimestamp(left.recordedAt);
|
|
15696
|
+
const rightAt = compactTimestamp(right.recordedAt);
|
|
15697
|
+
if (leftAt !== rightAt)
|
|
15698
|
+
return leftAt > rightAt ? -1 : 1;
|
|
15699
|
+
return left.id < right.id ? -1 : left.id > right.id ? 1 : 0;
|
|
15700
|
+
};
|
|
15701
|
+
var compactDecisions = (sources) => sources.flatMap((source) => source ? source.decisions.toSorted(newestDecisionFirst).map((entry) => ({
|
|
15702
|
+
id: entry.id,
|
|
15703
|
+
purpose: entry.data.purpose,
|
|
15704
|
+
status: entry.data.response,
|
|
15705
|
+
digest: entry.data.digest,
|
|
15706
|
+
choice: compactDecisionChoice(entry) || `task.inspect taskId=${source.taskId} view=full; decision=${entry.id}`,
|
|
15707
|
+
references: entry.data.binding.contentRefs.slice(0, 1).map(compactReference),
|
|
15708
|
+
origin: source.origin ?? undefined
|
|
15709
|
+
})) : []).slice(0, COMPACT_MAX_ITEMS);
|
|
15710
|
+
function compactTaskContext(view, inherited = null) {
|
|
15711
|
+
const decisions = compactDecisions([
|
|
15712
|
+
view && { origin: null, taskId: view.task.id, decisions: view.task.decisions },
|
|
15713
|
+
inherited
|
|
15714
|
+
]);
|
|
15715
|
+
const methods = view?.task.policy ? selectMethods(view.task.policy, view.capabilities).map((method) => ({
|
|
15618
15716
|
id: method.id,
|
|
15619
15717
|
assurance: method.assurance,
|
|
15620
15718
|
reason: compactText(method.reason, COMPACT_TEXT_BYTES) ?? ""
|
|
15621
15719
|
})) : [];
|
|
15720
|
+
const stale = view?.evidence.filter((entry) => entry.status === "stale").length;
|
|
15622
15721
|
const gaps = Array.from(new Set([
|
|
15623
|
-
...
|
|
15624
|
-
...view
|
|
15625
|
-
...view
|
|
15722
|
+
...stale ? [`stale evidence: ${stale}; workit task inspect --task ${view.task.id} --view full`] : [],
|
|
15723
|
+
...(view?.requirements ?? []).filter((entry) => entry.status !== "satisfied").map((entry) => entry.reason),
|
|
15724
|
+
...(view?.task.progress.blockers ?? []).map((entry) => entry.reason)
|
|
15626
15725
|
])).toSorted().slice(0, COMPACT_MAX_ITEMS).map((gap) => compactText(gap, COMPACT_TEXT_BYTES));
|
|
15627
15726
|
const context = {
|
|
15628
|
-
objective: compactText(view.task.intent.data.objective, COMPACT_TEXT_BYTES) ?? "",
|
|
15629
|
-
status: view
|
|
15727
|
+
objective: view ? compactText(view.task.intent.data.objective, COMPACT_TEXT_BYTES) ?? "" : "no task on this branch yet",
|
|
15728
|
+
status: view?.task.status ?? null,
|
|
15630
15729
|
decisions,
|
|
15631
15730
|
methods,
|
|
15632
15731
|
gaps,
|
|
15633
|
-
nextAction: compactText(view
|
|
15732
|
+
nextAction: compactText(view?.task.progress.nextAction ?? null, COMPACT_TEXT_BYTES)
|
|
15634
15733
|
};
|
|
15635
15734
|
let encoded = JSON.stringify(context);
|
|
15636
15735
|
while (compactBytes(encoded) > COMPACT_MAX_BYTES && (context.decisions.length || context.methods.length || context.gaps.length)) {
|
|
@@ -15819,6 +15918,13 @@ var TASK_SCOPED_ACTIONS = new Set([
|
|
|
15819
15918
|
"worker.cancel",
|
|
15820
15919
|
"state.export"
|
|
15821
15920
|
]);
|
|
15921
|
+
var WORKER_ADDRESSED_ACTIONS = new Set(["worker.cancel", "worker.report"]);
|
|
15922
|
+
var workerCommand = (taskId, request) => {
|
|
15923
|
+
const { action, workerId, reason, report } = request;
|
|
15924
|
+
const rest = JSON.stringify({ reason, report });
|
|
15925
|
+
const payload = rest === "{}" ? "" : ` --payload '${rest.replace(/'/gu, "'\\''")}'`;
|
|
15926
|
+
return `workit worker ${String(action)} ${String(workerId)} --task ${taskId}${payload}`;
|
|
15927
|
+
};
|
|
15822
15928
|
var CREATING_ACTIONS = new Set([
|
|
15823
15929
|
"task.revise",
|
|
15824
15930
|
"task.progress",
|
|
@@ -16069,6 +16175,17 @@ class WorkitCore {
|
|
|
16069
16175
|
const root = this.contextRootError();
|
|
16070
16176
|
if (!root.ok)
|
|
16071
16177
|
return root;
|
|
16178
|
+
const addressed = WORKER_ADDRESSED_ACTIONS.has(action);
|
|
16179
|
+
const workerId = addressed ? value.workerId : this.context.workerId ?? null;
|
|
16180
|
+
if (workerId !== null) {
|
|
16181
|
+
const owner = this.store.taskForWorker(workerId);
|
|
16182
|
+
if (!owner.ok)
|
|
16183
|
+
return owner;
|
|
16184
|
+
if (owner.data)
|
|
16185
|
+
return success(null, null, { ...request, taskId: owner.data });
|
|
16186
|
+
if (addressed)
|
|
16187
|
+
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)}\``);
|
|
16188
|
+
}
|
|
16072
16189
|
const create = CREATING_ACTIONS.has(action) && (this.context.workerId ?? null) === null;
|
|
16073
16190
|
const found = this.store.implicitTask({
|
|
16074
16191
|
provenance: provenance(this.context),
|
|
@@ -16775,7 +16892,9 @@ class WorkitCore {
|
|
|
16775
16892
|
if (!resolved.ok)
|
|
16776
16893
|
return resolved;
|
|
16777
16894
|
const value = resolved.data;
|
|
16778
|
-
|
|
16895
|
+
const result = this.retryOmittedRevisions(value, () => this.workerOnce(value));
|
|
16896
|
+
const { action, taskId } = value ?? {};
|
|
16897
|
+
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)}\`` };
|
|
16779
16898
|
}
|
|
16780
16899
|
workerOnce(request) {
|
|
16781
16900
|
const root = this.contextRootError();
|
|
@@ -16980,10 +17099,18 @@ class WorkitCore {
|
|
|
16980
17099
|
requirements
|
|
16981
17100
|
});
|
|
16982
17101
|
}
|
|
16983
|
-
compactContext(taskId, freshness) {
|
|
17102
|
+
compactContext(taskId, freshness, origin = null) {
|
|
16984
17103
|
const root = this.contextRootError();
|
|
16985
17104
|
if (!root.ok)
|
|
16986
17105
|
return root;
|
|
17106
|
+
const base = origin && this.store.readStoreTask(origin.taskId);
|
|
17107
|
+
const inherited = base?.ok && base.data ? {
|
|
17108
|
+
origin: origin.origin,
|
|
17109
|
+
taskId: base.data.id,
|
|
17110
|
+
decisions: base.data.decisions.filter((entry) => entry.data.revoked === null)
|
|
17111
|
+
} : null;
|
|
17112
|
+
if (taskId === null)
|
|
17113
|
+
return success(null, null, inherited?.decisions.length ? compactTaskContext(null, inherited) : "");
|
|
16987
17114
|
const task = this.store.readTask(taskId);
|
|
16988
17115
|
if (!task.ok)
|
|
16989
17116
|
return task;
|
|
@@ -16993,7 +17120,7 @@ class WorkitCore {
|
|
|
16993
17120
|
const view = this.view(task.data, false, freshness ?? signalFreshness(this.store.root));
|
|
16994
17121
|
if (!view.ok)
|
|
16995
17122
|
return view;
|
|
16996
|
-
return success(view.revision, view.workspaceRevision, compactTaskContext(view.data));
|
|
17123
|
+
return success(view.revision, view.workspaceRevision, compactTaskContext(view.data, inherited));
|
|
16997
17124
|
}
|
|
16998
17125
|
view(task, capture = true, freshness = treeFreshness(this.store.root)) {
|
|
16999
17126
|
const workspace = this.store.readWorkspace();
|
|
@@ -17288,8 +17415,9 @@ var currentTaskEntry = (entries, session, selection) => {
|
|
|
17288
17415
|
const active = entries.filter((entry) => entry.status === "active");
|
|
17289
17416
|
return active.length === 1 ? active[0] : null;
|
|
17290
17417
|
};
|
|
17418
|
+
var otherConversation = (entry, session) => entry.sessions.some((item) => item.host !== "workit_cli" && !(item.host === session.host && item.handle === session.handle));
|
|
17291
17419
|
var implicitTaskEntry = (store, entries, session) => {
|
|
17292
|
-
const open = entries.filter((entry) => entry.key !== null && entry.status !== "closed" && !entry
|
|
17420
|
+
const open = entries.filter((entry) => entry.key !== null && entry.status !== "closed" && !otherConversation(entry, session));
|
|
17293
17421
|
if (open.length === 0)
|
|
17294
17422
|
return null;
|
|
17295
17423
|
const key = store.currentKey();
|
|
@@ -17330,18 +17458,23 @@ function sessionCompactContext(store, session, context, selection = "session-bou
|
|
|
17330
17458
|
if (!listed.ok)
|
|
17331
17459
|
return migrationPending(listed) ? MIGRATION_PENDING_NOTE : null;
|
|
17332
17460
|
const entry = currentTaskEntry(listed.data, session, selection) ?? implicitTaskEntry(store, listed.data, session);
|
|
17333
|
-
return
|
|
17461
|
+
return entryCompactContext(store, entry, session, context);
|
|
17334
17462
|
}
|
|
17335
17463
|
function entryCompactContext(store, entry, session, context) {
|
|
17464
|
+
const found = store.originTaskEntry();
|
|
17465
|
+
const origin = found.ok && found.data && found.data.entry.id !== entry?.id && !otherConversation(found.data.entry, session) ? found.data : null;
|
|
17466
|
+
if (!entry && !origin)
|
|
17467
|
+
return null;
|
|
17336
17468
|
const workspace = store.readWorkspace();
|
|
17337
|
-
if (!workspace.ok || !workspace.data)
|
|
17469
|
+
if (!workspace.ok || entry && !workspace.data)
|
|
17338
17470
|
return null;
|
|
17339
17471
|
const slot = `${store.root}\x00${session.host}\x00${session.handle}`;
|
|
17340
17472
|
const key = canonicalJson({
|
|
17341
|
-
task: entry
|
|
17342
|
-
revision: entry
|
|
17343
|
-
file: entry
|
|
17344
|
-
|
|
17473
|
+
task: entry?.id ?? null,
|
|
17474
|
+
revision: entry?.revision ?? null,
|
|
17475
|
+
file: entry?.file ?? null,
|
|
17476
|
+
origin: origin && origin.entry.file,
|
|
17477
|
+
workspace: workspace.data?.revision ?? null,
|
|
17345
17478
|
caller: context.caller,
|
|
17346
17479
|
workerId: context.workerId ?? null,
|
|
17347
17480
|
capabilities: context.capabilities
|
|
@@ -17349,15 +17482,15 @@ function entryCompactContext(store, entry, session, context) {
|
|
|
17349
17482
|
const hit = cache.get(slot);
|
|
17350
17483
|
if (hit && hit.key === key && hit.filesKey !== null && hit.filesKey === filesKey(hit.files) && (hit.signal === null || hit.signal === recentSignal(store.root)))
|
|
17351
17484
|
return hit.value;
|
|
17352
|
-
const task = store.readTask(entry.id);
|
|
17353
|
-
if (!task.ok)
|
|
17485
|
+
const task = entry ? store.readTask(entry.id) : null;
|
|
17486
|
+
if (task && !task.ok)
|
|
17354
17487
|
return null;
|
|
17355
17488
|
const freshness = { mode: "signal", current: () => recentSignal(store.root) };
|
|
17356
|
-
const observed = task
|
|
17357
|
-
const files = task
|
|
17489
|
+
const observed = task?.data.evidence.some(isObservedCheck) ?? false;
|
|
17490
|
+
const files = (task?.data.decisions ?? []).flatMap((decision) => decision.data.binding.contentRefs.flatMap((ref) => ref.kind === "file" ? [path16.resolve(store.root, ref.path)] : []));
|
|
17358
17491
|
const observedFiles = filesKey(files);
|
|
17359
|
-
const compact = new WorkitCore(store, context).compactContext(entry
|
|
17360
|
-
if (!compact.ok)
|
|
17492
|
+
const compact = new WorkitCore(store, context).compactContext(entry?.id ?? null, freshness, origin && { origin: origin.origin, taskId: origin.entry.id });
|
|
17493
|
+
if (!compact.ok || !compact.data)
|
|
17361
17494
|
return null;
|
|
17362
17495
|
cache.delete(slot);
|
|
17363
17496
|
cache.set(slot, {
|
|
@@ -17396,7 +17529,7 @@ ${options.addendum}` : ""}
|
|
|
17396
17529
|
if (!listed.ok)
|
|
17397
17530
|
throw new Error(listed.error);
|
|
17398
17531
|
const entry = currentTaskEntry(listed.data, session, descriptor.context.task) ?? implicitTaskEntry(store, listed.data, session);
|
|
17399
|
-
const text =
|
|
17532
|
+
const text = entryCompactContext(store, entry, session, hookOperationContext(input, descriptor));
|
|
17400
17533
|
if (text)
|
|
17401
17534
|
compact = `
|
|
17402
17535
|
<workit-task-context>${text}</workit-task-context>`;
|
package/dist/workit-hook.js
CHANGED
|
@@ -37,6 +37,6 @@ if (quiet)
|
|
|
37
37
|
process.stdout.write(`${JSON.stringify({ hookSpecificOutput: { hookEventName: quiet } })}
|
|
38
38
|
`);
|
|
39
39
|
else {
|
|
40
|
-
const { runCodexHook } = await import("./workit-hook-
|
|
40
|
+
const { runCodexHook } = await import("./workit-hook-vjkepg0b.js");
|
|
41
41
|
await runCodexHook([payload]);
|
|
42
42
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brainervirus/workit-codex",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.9.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Workit Codex CLI/desktop plugin — shared MCP transport, hooks, method skills, and verifier/reviewer/implementer agents",
|
|
6
6
|
"keywords": [
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
"build": "bun scripts/build.ts"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@brainervirus/workit-core": "^8.
|
|
43
|
-
"@brainervirus/workit-mcp": "^8.
|
|
42
|
+
"@brainervirus/workit-core": "^8.9.1",
|
|
43
|
+
"@brainervirus/workit-mcp": "^8.9.1"
|
|
44
44
|
},
|
|
45
45
|
"engines": {
|
|
46
46
|
"node": ">=24"
|