@brainervirus/workit-opencode 8.9.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/plugin.js +174 -41
- package/package.json +2 -2
package/dist/plugin.js
CHANGED
|
@@ -10564,6 +10564,38 @@ var isNewerVersion = (candidate, current) => {
|
|
|
10564
10564
|
return false;
|
|
10565
10565
|
};
|
|
10566
10566
|
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);
|
|
10567
|
+
var readText = (file) => {
|
|
10568
|
+
try {
|
|
10569
|
+
return fs7.readFileSync(file, "utf8");
|
|
10570
|
+
} catch {
|
|
10571
|
+
return "";
|
|
10572
|
+
}
|
|
10573
|
+
};
|
|
10574
|
+
var REFLOG_LINE = /^[0-9a-f]+ ([0-9a-f]+) .* (\d+) [+-]\d{4}\t(.*)$/u;
|
|
10575
|
+
var branchStart = (location, branch, aliases) => {
|
|
10576
|
+
const first = readText(path6.join(path6.dirname(location.dir), "logs", "refs", "heads", branch)).split(`
|
|
10577
|
+
`, 1)[0];
|
|
10578
|
+
const created = REFLOG_LINE.exec(first);
|
|
10579
|
+
const start = created && /^branch: Created from (\S+)$/u.exec(created[3])?.[1];
|
|
10580
|
+
if (!created || !start)
|
|
10581
|
+
return null;
|
|
10582
|
+
if (start !== "HEAD")
|
|
10583
|
+
return start;
|
|
10584
|
+
if (!location.git)
|
|
10585
|
+
return null;
|
|
10586
|
+
for (const line of readText(path6.join(location.git.gitDir, "logs", "HEAD")).split(`
|
|
10587
|
+
`)) {
|
|
10588
|
+
const entry = REFLOG_LINE.exec(line);
|
|
10589
|
+
const moved = entry && /^checkout: moving from (\S+) to (\S+)$/u.exec(entry[3]);
|
|
10590
|
+
const seconds = entry ? Number(entry[2]) - Number(created[2]) : -1;
|
|
10591
|
+
if (moved && entry[1] === created[1] && seconds >= 0 && seconds <= 1 && aliases.includes(moved[2]))
|
|
10592
|
+
return moved[1];
|
|
10593
|
+
}
|
|
10594
|
+
return null;
|
|
10595
|
+
};
|
|
10596
|
+
var refExists = (common, ref) => fs7.existsSync(path6.join(common, ref)) || readText(path6.join(common, "packed-refs")).includes(` ${ref}
|
|
10597
|
+
`);
|
|
10598
|
+
var origins = new Map;
|
|
10567
10599
|
var sameDirectoryIdentity = (left, right) => {
|
|
10568
10600
|
if (!path6.isAbsolute(left) || !path6.isAbsolute(right))
|
|
10569
10601
|
return false;
|
|
@@ -10816,6 +10848,66 @@ class TaskStore {
|
|
|
10816
10848
|
return bound;
|
|
10817
10849
|
return success(null, null, { key: key.data, bound: bound.data });
|
|
10818
10850
|
}
|
|
10851
|
+
taskForWorker(workerId) {
|
|
10852
|
+
if (typeof workerId !== "string" || !validId(workerId))
|
|
10853
|
+
return failure2("invalid_input", "needs a worker id: `workit worker cancel|report <workerId>`");
|
|
10854
|
+
const listed = this.listTaskIndex();
|
|
10855
|
+
if (!listed.ok)
|
|
10856
|
+
return listed;
|
|
10857
|
+
for (const entry of listed.data) {
|
|
10858
|
+
if (entry.status === "closed")
|
|
10859
|
+
continue;
|
|
10860
|
+
const loaded = this.load(entry.id);
|
|
10861
|
+
if (!loaded.ok)
|
|
10862
|
+
return loaded;
|
|
10863
|
+
if (loaded.data?.record.workers.some((worker) => worker.id === workerId))
|
|
10864
|
+
return success(null, null, entry.id);
|
|
10865
|
+
}
|
|
10866
|
+
return success(null, null, null);
|
|
10867
|
+
}
|
|
10868
|
+
originTaskEntry() {
|
|
10869
|
+
const key = this.currentKey();
|
|
10870
|
+
const location = this.location();
|
|
10871
|
+
const branch = key.ok ? key.data.branch : null;
|
|
10872
|
+
if (!branch || !location.ok)
|
|
10873
|
+
return success(null, null, null);
|
|
10874
|
+
const common = path6.dirname(location.data.dir);
|
|
10875
|
+
const heads = path6.join(common, "logs", "refs", "heads");
|
|
10876
|
+
const headLog = location.data.git ? path6.join(location.data.git.gitDir, "logs", "HEAD") : "";
|
|
10877
|
+
const signatures = [
|
|
10878
|
+
path6.join(heads, branch),
|
|
10879
|
+
headLog,
|
|
10880
|
+
heads,
|
|
10881
|
+
path6.join(common, "packed-refs")
|
|
10882
|
+
].map((file) => fileSignature(file) ?? "-");
|
|
10883
|
+
const slot = `${location.data.dir}\x00${headLog}\x00${branch}`;
|
|
10884
|
+
let resolved = origins.get(slot);
|
|
10885
|
+
if (resolved?.signature !== signatures.join("|")) {
|
|
10886
|
+
const renames = branchRenames(location.data);
|
|
10887
|
+
const aliases = [branch];
|
|
10888
|
+
for (const rename of renames.toReversed())
|
|
10889
|
+
if (rename.to === aliases.at(-1))
|
|
10890
|
+
aliases.push(rename.from);
|
|
10891
|
+
const start = branchStart(location.data, branch, aliases);
|
|
10892
|
+
const slash = start?.indexOf("/") ?? -1;
|
|
10893
|
+
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)}"]`));
|
|
10894
|
+
const name = start && (remote ? start.slice(slash + 1) : start);
|
|
10895
|
+
resolved = {
|
|
10896
|
+
signature: signatures.join("|"),
|
|
10897
|
+
name: name && !aliases.includes(name) ? name : null,
|
|
10898
|
+
renames
|
|
10899
|
+
};
|
|
10900
|
+
origins.set(slot, resolved);
|
|
10901
|
+
}
|
|
10902
|
+
const entry = resolved.name ? this.openTasksForKey(resolved.name, resolved.renames) : null;
|
|
10903
|
+
if (entry && !entry.ok)
|
|
10904
|
+
return entry;
|
|
10905
|
+
return success(null, null, entry?.data[0] ? { origin: `branch ${resolved.name}`, entry: entry.data[0] } : null);
|
|
10906
|
+
}
|
|
10907
|
+
readStoreTask(taskId) {
|
|
10908
|
+
const loaded = this.load(taskId);
|
|
10909
|
+
return loaded.ok ? success(null, null, loaded.data?.record ?? null) : loaded;
|
|
10910
|
+
}
|
|
10819
10911
|
create(input, provenance, expectedWorkspaceRevision) {
|
|
10820
10912
|
const value = "intent" in input ? input : {
|
|
10821
10913
|
intent: input,
|
|
@@ -11485,12 +11577,12 @@ class TaskStore {
|
|
|
11485
11577
|
return 0;
|
|
11486
11578
|
}
|
|
11487
11579
|
}
|
|
11488
|
-
openTasksForKey(key) {
|
|
11580
|
+
openTasksForKey(key, known) {
|
|
11489
11581
|
const all = this.listStoreIndex();
|
|
11490
11582
|
if (!all.ok)
|
|
11491
11583
|
return all;
|
|
11492
|
-
const location = this.location();
|
|
11493
|
-
const renames = location
|
|
11584
|
+
const location = known ? null : this.location();
|
|
11585
|
+
const renames = known ?? (location?.ok ? branchRenames(location.data) : []);
|
|
11494
11586
|
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));
|
|
11495
11587
|
}
|
|
11496
11588
|
openTaskForKey(key) {
|
|
@@ -15687,38 +15779,45 @@ var compactReference = (ref) => {
|
|
|
15687
15779
|
};
|
|
15688
15780
|
return { kind: ref.kind };
|
|
15689
15781
|
};
|
|
15690
|
-
|
|
15691
|
-
const
|
|
15692
|
-
|
|
15693
|
-
|
|
15694
|
-
|
|
15695
|
-
|
|
15696
|
-
|
|
15697
|
-
|
|
15698
|
-
|
|
15699
|
-
|
|
15700
|
-
|
|
15701
|
-
|
|
15702
|
-
|
|
15703
|
-
|
|
15704
|
-
|
|
15705
|
-
|
|
15782
|
+
var newestDecisionFirst = (left, right) => {
|
|
15783
|
+
const leftAt = compactTimestamp(left.recordedAt);
|
|
15784
|
+
const rightAt = compactTimestamp(right.recordedAt);
|
|
15785
|
+
if (leftAt !== rightAt)
|
|
15786
|
+
return leftAt > rightAt ? -1 : 1;
|
|
15787
|
+
return left.id < right.id ? -1 : left.id > right.id ? 1 : 0;
|
|
15788
|
+
};
|
|
15789
|
+
var compactDecisions = (sources) => sources.flatMap((source) => source ? source.decisions.toSorted(newestDecisionFirst).map((entry) => ({
|
|
15790
|
+
id: entry.id,
|
|
15791
|
+
purpose: entry.data.purpose,
|
|
15792
|
+
status: entry.data.response,
|
|
15793
|
+
digest: entry.data.digest,
|
|
15794
|
+
choice: compactDecisionChoice(entry) || `task.inspect taskId=${source.taskId} view=full; decision=${entry.id}`,
|
|
15795
|
+
references: entry.data.binding.contentRefs.slice(0, 1).map(compactReference),
|
|
15796
|
+
origin: source.origin ?? undefined
|
|
15797
|
+
})) : []).slice(0, COMPACT_MAX_ITEMS);
|
|
15798
|
+
function compactTaskContext(view, inherited = null) {
|
|
15799
|
+
const decisions = compactDecisions([
|
|
15800
|
+
view && { origin: null, taskId: view.task.id, decisions: view.task.decisions },
|
|
15801
|
+
inherited
|
|
15802
|
+
]);
|
|
15803
|
+
const methods = view?.task.policy ? selectMethods(view.task.policy, view.capabilities).map((method) => ({
|
|
15706
15804
|
id: method.id,
|
|
15707
15805
|
assurance: method.assurance,
|
|
15708
15806
|
reason: compactText(method.reason, COMPACT_TEXT_BYTES) ?? ""
|
|
15709
15807
|
})) : [];
|
|
15808
|
+
const stale = view?.evidence.filter((entry) => entry.status === "stale").length;
|
|
15710
15809
|
const gaps = Array.from(new Set([
|
|
15711
|
-
...
|
|
15712
|
-
...view
|
|
15713
|
-
...view
|
|
15810
|
+
...stale ? [`stale evidence: ${stale}; workit task inspect --task ${view.task.id} --view full`] : [],
|
|
15811
|
+
...(view?.requirements ?? []).filter((entry) => entry.status !== "satisfied").map((entry) => entry.reason),
|
|
15812
|
+
...(view?.task.progress.blockers ?? []).map((entry) => entry.reason)
|
|
15714
15813
|
])).toSorted().slice(0, COMPACT_MAX_ITEMS).map((gap) => compactText(gap, COMPACT_TEXT_BYTES));
|
|
15715
15814
|
const context = {
|
|
15716
|
-
objective: compactText(view.task.intent.data.objective, COMPACT_TEXT_BYTES) ?? "",
|
|
15717
|
-
status: view
|
|
15815
|
+
objective: view ? compactText(view.task.intent.data.objective, COMPACT_TEXT_BYTES) ?? "" : "no task on this branch yet",
|
|
15816
|
+
status: view?.task.status ?? null,
|
|
15718
15817
|
decisions,
|
|
15719
15818
|
methods,
|
|
15720
15819
|
gaps,
|
|
15721
|
-
nextAction: compactText(view
|
|
15820
|
+
nextAction: compactText(view?.task.progress.nextAction ?? null, COMPACT_TEXT_BYTES)
|
|
15722
15821
|
};
|
|
15723
15822
|
let encoded = JSON.stringify(context);
|
|
15724
15823
|
while (compactBytes(encoded) > COMPACT_MAX_BYTES && (context.decisions.length || context.methods.length || context.gaps.length)) {
|
|
@@ -16461,6 +16560,13 @@ var TASK_SCOPED_ACTIONS = new Set([
|
|
|
16461
16560
|
"worker.cancel",
|
|
16462
16561
|
"state.export"
|
|
16463
16562
|
]);
|
|
16563
|
+
var WORKER_ADDRESSED_ACTIONS = new Set(["worker.cancel", "worker.report"]);
|
|
16564
|
+
var workerCommand = (taskId, request) => {
|
|
16565
|
+
const { action, workerId, reason, report } = request;
|
|
16566
|
+
const rest = JSON.stringify({ reason, report });
|
|
16567
|
+
const payload = rest === "{}" ? "" : ` --payload '${rest.replace(/'/gu, "'\\''")}'`;
|
|
16568
|
+
return `workit worker ${String(action)} ${String(workerId)} --task ${taskId}${payload}`;
|
|
16569
|
+
};
|
|
16464
16570
|
var CREATING_ACTIONS = new Set([
|
|
16465
16571
|
"task.revise",
|
|
16466
16572
|
"task.progress",
|
|
@@ -16711,6 +16817,17 @@ class WorkitCore {
|
|
|
16711
16817
|
const root = this.contextRootError();
|
|
16712
16818
|
if (!root.ok)
|
|
16713
16819
|
return root;
|
|
16820
|
+
const addressed = WORKER_ADDRESSED_ACTIONS.has(action);
|
|
16821
|
+
const workerId = addressed ? value.workerId : this.context.workerId ?? null;
|
|
16822
|
+
if (workerId !== null) {
|
|
16823
|
+
const owner = this.store.taskForWorker(workerId);
|
|
16824
|
+
if (!owner.ok)
|
|
16825
|
+
return owner;
|
|
16826
|
+
if (owner.data)
|
|
16827
|
+
return success(null, null, { ...request, taskId: owner.data });
|
|
16828
|
+
if (addressed)
|
|
16829
|
+
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)}\``);
|
|
16830
|
+
}
|
|
16714
16831
|
const create = CREATING_ACTIONS.has(action) && (this.context.workerId ?? null) === null;
|
|
16715
16832
|
const found = this.store.implicitTask({
|
|
16716
16833
|
provenance: provenance(this.context),
|
|
@@ -17417,7 +17534,9 @@ class WorkitCore {
|
|
|
17417
17534
|
if (!resolved.ok)
|
|
17418
17535
|
return resolved;
|
|
17419
17536
|
const value = resolved.data;
|
|
17420
|
-
|
|
17537
|
+
const result = this.retryOmittedRevisions(value, () => this.workerOnce(value));
|
|
17538
|
+
const { action, taskId } = value ?? {};
|
|
17539
|
+
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)}\`` };
|
|
17421
17540
|
}
|
|
17422
17541
|
workerOnce(request) {
|
|
17423
17542
|
const root = this.contextRootError();
|
|
@@ -17622,10 +17741,18 @@ class WorkitCore {
|
|
|
17622
17741
|
requirements
|
|
17623
17742
|
});
|
|
17624
17743
|
}
|
|
17625
|
-
compactContext(taskId, freshness) {
|
|
17744
|
+
compactContext(taskId, freshness, origin = null) {
|
|
17626
17745
|
const root = this.contextRootError();
|
|
17627
17746
|
if (!root.ok)
|
|
17628
17747
|
return root;
|
|
17748
|
+
const base = origin && this.store.readStoreTask(origin.taskId);
|
|
17749
|
+
const inherited = base?.ok && base.data ? {
|
|
17750
|
+
origin: origin.origin,
|
|
17751
|
+
taskId: base.data.id,
|
|
17752
|
+
decisions: base.data.decisions.filter((entry) => entry.data.revoked === null)
|
|
17753
|
+
} : null;
|
|
17754
|
+
if (taskId === null)
|
|
17755
|
+
return success(null, null, inherited?.decisions.length ? compactTaskContext(null, inherited) : "");
|
|
17629
17756
|
const task = this.store.readTask(taskId);
|
|
17630
17757
|
if (!task.ok)
|
|
17631
17758
|
return task;
|
|
@@ -17635,7 +17762,7 @@ class WorkitCore {
|
|
|
17635
17762
|
const view = this.view(task.data, false, freshness ?? signalFreshness(this.store.root));
|
|
17636
17763
|
if (!view.ok)
|
|
17637
17764
|
return view;
|
|
17638
|
-
return success(view.revision, view.workspaceRevision, compactTaskContext(view.data));
|
|
17765
|
+
return success(view.revision, view.workspaceRevision, compactTaskContext(view.data, inherited));
|
|
17639
17766
|
}
|
|
17640
17767
|
view(task, capture = true, freshness = treeFreshness(this.store.root)) {
|
|
17641
17768
|
const workspace = this.store.readWorkspace();
|
|
@@ -19074,8 +19201,9 @@ var currentTaskEntry = (entries, session, selection) => {
|
|
|
19074
19201
|
const active = entries.filter((entry) => entry.status === "active");
|
|
19075
19202
|
return active.length === 1 ? active[0] : null;
|
|
19076
19203
|
};
|
|
19204
|
+
var otherConversation = (entry, session) => entry.sessions.some((item) => item.host !== "workit_cli" && !(item.host === session.host && item.handle === session.handle));
|
|
19077
19205
|
var implicitTaskEntry = (store, entries, session) => {
|
|
19078
|
-
const open = entries.filter((entry) => entry.key !== null && entry.status !== "closed" && !entry
|
|
19206
|
+
const open = entries.filter((entry) => entry.key !== null && entry.status !== "closed" && !otherConversation(entry, session));
|
|
19079
19207
|
if (open.length === 0)
|
|
19080
19208
|
return null;
|
|
19081
19209
|
const key = store.currentKey();
|
|
@@ -19116,18 +19244,23 @@ function sessionCompactContext(store, session, context, selection = "session-bou
|
|
|
19116
19244
|
if (!listed.ok)
|
|
19117
19245
|
return migrationPending(listed) ? MIGRATION_PENDING_NOTE : null;
|
|
19118
19246
|
const entry = currentTaskEntry(listed.data, session, selection) ?? implicitTaskEntry(store, listed.data, session);
|
|
19119
|
-
return
|
|
19247
|
+
return entryCompactContext(store, entry, session, context);
|
|
19120
19248
|
}
|
|
19121
19249
|
function entryCompactContext(store, entry, session, context) {
|
|
19250
|
+
const found = store.originTaskEntry();
|
|
19251
|
+
const origin = found.ok && found.data && found.data.entry.id !== entry?.id && !otherConversation(found.data.entry, session) ? found.data : null;
|
|
19252
|
+
if (!entry && !origin)
|
|
19253
|
+
return null;
|
|
19122
19254
|
const workspace = store.readWorkspace();
|
|
19123
|
-
if (!workspace.ok || !workspace.data)
|
|
19255
|
+
if (!workspace.ok || entry && !workspace.data)
|
|
19124
19256
|
return null;
|
|
19125
19257
|
const slot = `${store.root}\x00${session.host}\x00${session.handle}`;
|
|
19126
19258
|
const key = canonicalJson({
|
|
19127
|
-
task: entry
|
|
19128
|
-
revision: entry
|
|
19129
|
-
file: entry
|
|
19130
|
-
|
|
19259
|
+
task: entry?.id ?? null,
|
|
19260
|
+
revision: entry?.revision ?? null,
|
|
19261
|
+
file: entry?.file ?? null,
|
|
19262
|
+
origin: origin && origin.entry.file,
|
|
19263
|
+
workspace: workspace.data?.revision ?? null,
|
|
19131
19264
|
caller: context.caller,
|
|
19132
19265
|
workerId: context.workerId ?? null,
|
|
19133
19266
|
capabilities: context.capabilities
|
|
@@ -19135,15 +19268,15 @@ function entryCompactContext(store, entry, session, context) {
|
|
|
19135
19268
|
const hit = cache.get(slot);
|
|
19136
19269
|
if (hit && hit.key === key && hit.filesKey !== null && hit.filesKey === filesKey(hit.files) && (hit.signal === null || hit.signal === recentSignal(store.root)))
|
|
19137
19270
|
return hit.value;
|
|
19138
|
-
const task = store.readTask(entry.id);
|
|
19139
|
-
if (!task.ok)
|
|
19271
|
+
const task = entry ? store.readTask(entry.id) : null;
|
|
19272
|
+
if (task && !task.ok)
|
|
19140
19273
|
return null;
|
|
19141
19274
|
const freshness = { mode: "signal", current: () => recentSignal(store.root) };
|
|
19142
|
-
const observed = task
|
|
19143
|
-
const files = task
|
|
19275
|
+
const observed = task?.data.evidence.some(isObservedCheck) ?? false;
|
|
19276
|
+
const files = (task?.data.decisions ?? []).flatMap((decision) => decision.data.binding.contentRefs.flatMap((ref) => ref.kind === "file" ? [path20.resolve(store.root, ref.path)] : []));
|
|
19144
19277
|
const observedFiles = filesKey(files);
|
|
19145
|
-
const compact = new WorkitCore(store, context).compactContext(entry
|
|
19146
|
-
if (!compact.ok)
|
|
19278
|
+
const compact = new WorkitCore(store, context).compactContext(entry?.id ?? null, freshness, origin && { origin: origin.origin, taskId: origin.entry.id });
|
|
19279
|
+
if (!compact.ok || !compact.data)
|
|
19147
19280
|
return null;
|
|
19148
19281
|
cache.delete(slot);
|
|
19149
19282
|
cache.set(slot, {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brainervirus/workit-opencode",
|
|
3
|
-
"version": "8.9.
|
|
3
|
+
"version": "8.9.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Workit OpenCode plugin — native tools, adaptive policy, and sixteen method skills",
|
|
6
6
|
"keywords": [
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"typecheck": "tsc --noEmit"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@brainervirus/workit-core": "^8.9.
|
|
42
|
+
"@brainervirus/workit-core": "^8.9.1"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@opencode/plugin": "2.0.18"
|