@brainervirus/workit-pi 8.14.0 → 8.15.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/worker.js +22 -13
- package/dist/workit.js +114 -26
- package/package.json +1 -1
- package/skills/workit-ship/SKILL.md +2 -2
package/dist/worker.js
CHANGED
|
@@ -7546,6 +7546,8 @@ var text = string2().check((ctx) => {
|
|
|
7546
7546
|
ctx.issues.push({ code: "custom", input: ctx.value, message: "invalid Unicode", path: [] });
|
|
7547
7547
|
});
|
|
7548
7548
|
var id = text.regex(uuidPattern, "expected lowercase UUID");
|
|
7549
|
+
var idRefPattern = /^[0-9a-f][0-9a-f-]{7,35}$/;
|
|
7550
|
+
var idRef = text.regex(idRefPattern, "expected a UUID or an id prefix of 8+ characters");
|
|
7549
7551
|
var digest = text.regex(digestPattern, "expected lowercase SHA-256 digest");
|
|
7550
7552
|
var revision = text.regex(uuidPattern, "expected UUID revision");
|
|
7551
7553
|
var validUtc = (value) => {
|
|
@@ -7825,7 +7827,7 @@ var workerReportSchema = object({
|
|
|
7825
7827
|
outcome: _enum(["completed", "failed", "cancelled"]),
|
|
7826
7828
|
summary: text,
|
|
7827
7829
|
evidenceIds: array(id),
|
|
7828
|
-
findingIds: array(
|
|
7830
|
+
findingIds: array(idRef)
|
|
7829
7831
|
}).strict();
|
|
7830
7832
|
var workerSchema = object({
|
|
7831
7833
|
assignment: assignmentSchema,
|
|
@@ -8018,7 +8020,7 @@ var findingOperations = {
|
|
|
8018
8020
|
action: literal("resolve"),
|
|
8019
8021
|
...taskId,
|
|
8020
8022
|
expectedRevision: revision.optional(),
|
|
8021
|
-
findingId:
|
|
8023
|
+
findingId: idRef,
|
|
8022
8024
|
disposition: _enum(["open", "fixed", "dismissed", "deferred"]),
|
|
8023
8025
|
reason: text,
|
|
8024
8026
|
evidenceIds: array(id),
|
|
@@ -8059,7 +8061,7 @@ var workerOperations = {
|
|
|
8059
8061
|
...taskId,
|
|
8060
8062
|
expectedRevision: revision.optional(),
|
|
8061
8063
|
expectedWorkspaceRevision: revision.optional(),
|
|
8062
|
-
workerId:
|
|
8064
|
+
workerId: idRef,
|
|
8063
8065
|
report: workerReportSchema
|
|
8064
8066
|
}),
|
|
8065
8067
|
cancel: operation({
|
|
@@ -8067,7 +8069,7 @@ var workerOperations = {
|
|
|
8067
8069
|
...taskId,
|
|
8068
8070
|
...revisions,
|
|
8069
8071
|
expectedWorkspaceRevision: revision.optional(),
|
|
8070
|
-
workerId:
|
|
8072
|
+
workerId: idRef,
|
|
8071
8073
|
reason: text
|
|
8072
8074
|
})
|
|
8073
8075
|
};
|
|
@@ -8544,20 +8546,19 @@ var workspaceConfigSchema = object({
|
|
|
8544
8546
|
union([boolean2(), literal("verified")]).optional()
|
|
8545
8547
|
]))).passthrough().optional(),
|
|
8546
8548
|
youtrack: object({ baseUrl: nonBlank.optional(), link_issues: boolean2().optional() }).passthrough().optional(),
|
|
8547
|
-
issues: object({
|
|
8549
|
+
issues: object({
|
|
8550
|
+
provider: _enum(["github", "gitlab", "youtrack"]).optional(),
|
|
8551
|
+
link: boolean2().optional(),
|
|
8552
|
+
relation: unknown().optional(),
|
|
8553
|
+
backlink: boolean2().optional(),
|
|
8554
|
+
link_on_pr: boolean2().optional()
|
|
8555
|
+
}).passthrough().optional(),
|
|
8548
8556
|
branchPolicy: workspaceBranchPolicySchema.optional(),
|
|
8549
8557
|
commitPolicy: workspaceCommitPolicySchema.optional(),
|
|
8550
8558
|
defaultProfile: nonBlank.optional(),
|
|
8551
8559
|
profiles: record(nonBlank, workspaceProfileSchema).optional(),
|
|
8552
8560
|
releaseTracks: record(nonBlank, releaseTrackSchema).optional()
|
|
8553
8561
|
}).passthrough().superRefine((workspace, context) => {
|
|
8554
|
-
if (workspace.issues && workspace.vcs?.provider !== "github") {
|
|
8555
|
-
context.addIssue({
|
|
8556
|
-
code: "custom",
|
|
8557
|
-
path: ["issues"],
|
|
8558
|
-
message: `GitHub issue linking requires the github provider, got ${workspace.vcs?.provider ?? "unset"}`
|
|
8559
|
-
});
|
|
8560
|
-
}
|
|
8561
8562
|
if (workspace.defaultProfile !== undefined && !Object.hasOwn(workspace.profiles ?? {}, workspace.defaultProfile)) {
|
|
8562
8563
|
context.addIssue({
|
|
8563
8564
|
code: "custom",
|
|
@@ -8611,11 +8612,19 @@ var KNOWN_FIELDS = new Set([
|
|
|
8611
8612
|
]);
|
|
8612
8613
|
var memo2 = new Map;
|
|
8613
8614
|
|
|
8615
|
+
// packages/workit-core/src/core/vcs-config.ts
|
|
8616
|
+
var TRACKERS = new Set(["github", "gitlab", "youtrack"]);
|
|
8617
|
+
|
|
8614
8618
|
// packages/workit-core/src/ledger.ts
|
|
8615
8619
|
var PASSING = new Set(["verified", "tests-verified", "type-check-only"]);
|
|
8616
8620
|
var FAILING = new Set(["failed", "blocked"]);
|
|
8617
8621
|
var STRONG_RESULTS = new Set(["verified", "tests-verified"]);
|
|
8618
|
-
var PR_ROW_TYPES = new Set([
|
|
8622
|
+
var PR_ROW_TYPES = new Set([
|
|
8623
|
+
"pr.created",
|
|
8624
|
+
"pr.status",
|
|
8625
|
+
"pr.merged",
|
|
8626
|
+
"pr.linked"
|
|
8627
|
+
]);
|
|
8619
8628
|
var NETWORK_FS_TYPES = new Set([
|
|
8620
8629
|
26985,
|
|
8621
8630
|
20859,
|
package/dist/workit.js
CHANGED
|
@@ -7771,6 +7771,8 @@ var text = string2().check((ctx) => {
|
|
|
7771
7771
|
ctx.issues.push({ code: "custom", input: ctx.value, message: "invalid Unicode", path: [] });
|
|
7772
7772
|
});
|
|
7773
7773
|
var id = text.regex(uuidPattern, "expected lowercase UUID");
|
|
7774
|
+
var idRefPattern = /^[0-9a-f][0-9a-f-]{7,35}$/;
|
|
7775
|
+
var idRef = text.regex(idRefPattern, "expected a UUID or an id prefix of 8+ characters");
|
|
7774
7776
|
var digest = text.regex(digestPattern, "expected lowercase SHA-256 digest");
|
|
7775
7777
|
var revision = text.regex(uuidPattern, "expected UUID revision");
|
|
7776
7778
|
var validUtc = (value) => {
|
|
@@ -8148,7 +8150,7 @@ var workerReportSchema = object({
|
|
|
8148
8150
|
outcome: _enum(["completed", "failed", "cancelled"]),
|
|
8149
8151
|
summary: text,
|
|
8150
8152
|
evidenceIds: array(id),
|
|
8151
|
-
findingIds: array(
|
|
8153
|
+
findingIds: array(idRef)
|
|
8152
8154
|
}).strict();
|
|
8153
8155
|
var workerSchema = object({
|
|
8154
8156
|
assignment: assignmentSchema,
|
|
@@ -8394,7 +8396,7 @@ var findingOperations = {
|
|
|
8394
8396
|
action: literal("resolve"),
|
|
8395
8397
|
...taskId,
|
|
8396
8398
|
expectedRevision: revision.optional(),
|
|
8397
|
-
findingId:
|
|
8399
|
+
findingId: idRef,
|
|
8398
8400
|
disposition: _enum(["open", "fixed", "dismissed", "deferred"]),
|
|
8399
8401
|
reason: text,
|
|
8400
8402
|
evidenceIds: array(id),
|
|
@@ -8435,7 +8437,7 @@ var workerOperations = {
|
|
|
8435
8437
|
...taskId,
|
|
8436
8438
|
expectedRevision: revision.optional(),
|
|
8437
8439
|
expectedWorkspaceRevision: revision.optional(),
|
|
8438
|
-
workerId:
|
|
8440
|
+
workerId: idRef,
|
|
8439
8441
|
report: workerReportSchema
|
|
8440
8442
|
}),
|
|
8441
8443
|
cancel: operation({
|
|
@@ -8443,7 +8445,7 @@ var workerOperations = {
|
|
|
8443
8445
|
...taskId,
|
|
8444
8446
|
...revisions,
|
|
8445
8447
|
expectedWorkspaceRevision: revision.optional(),
|
|
8446
|
-
workerId:
|
|
8448
|
+
workerId: idRef,
|
|
8447
8449
|
reason: text
|
|
8448
8450
|
})
|
|
8449
8451
|
};
|
|
@@ -8493,6 +8495,16 @@ var success = (revisionValue, workspaceRevisionValue, data) => ({
|
|
|
8493
8495
|
data
|
|
8494
8496
|
});
|
|
8495
8497
|
var failure2 = (code, error, details = {}) => ({ ok: false, schemaVersion: 1, code, error, details });
|
|
8498
|
+
function resolveIdRef(kind, ref, ids) {
|
|
8499
|
+
if (ids.includes(ref))
|
|
8500
|
+
return success(null, null, ref);
|
|
8501
|
+
const matches = ids.filter((candidate) => candidate.startsWith(ref));
|
|
8502
|
+
if (matches.length === 1)
|
|
8503
|
+
return success(null, null, matches[0]);
|
|
8504
|
+
if (matches.length === 0)
|
|
8505
|
+
return failure2("not_found", `${kind} not found`);
|
|
8506
|
+
return failure2("invalid_input", `${kind} prefix ${ref} is ambiguous; candidates: ${matches.join(", ")}`);
|
|
8507
|
+
}
|
|
8496
8508
|
function parseOperation(family, input) {
|
|
8497
8509
|
if (typeof input === "object" && input !== null && "schemaVersion" in input && input.schemaVersion !== SCHEMA_VERSION)
|
|
8498
8510
|
return failure2("unsupported_version", "unsupported schema version", { operation: family });
|
|
@@ -10022,7 +10034,7 @@ var removeIfEmpty = (dir) => {
|
|
|
10022
10034
|
};
|
|
10023
10035
|
var tokenHash = (token) => createHash3("sha256").update(token).digest("hex");
|
|
10024
10036
|
function recordIssuedSession(cwd, lead, issued) {
|
|
10025
|
-
const token = randomBytes2(18).toString("
|
|
10037
|
+
const token = randomBytes2(18).toString("hex");
|
|
10026
10038
|
try {
|
|
10027
10039
|
migrateRepoIssued(cwd);
|
|
10028
10040
|
const own = hash(issued);
|
|
@@ -11036,20 +11048,26 @@ class TaskStore {
|
|
|
11036
11048
|
return success(null, null, { key: key.data, bound: bound.data });
|
|
11037
11049
|
}
|
|
11038
11050
|
taskForWorker(workerId) {
|
|
11039
|
-
if (typeof workerId !== "string" || !
|
|
11051
|
+
if (typeof workerId !== "string" || !idRefPattern.test(workerId))
|
|
11040
11052
|
return failure2("invalid_input", "needs a worker id: `workit worker cancel|report <workerId>`");
|
|
11041
11053
|
const listed = this.listTaskIndex();
|
|
11042
11054
|
if (!listed.ok)
|
|
11043
11055
|
return listed;
|
|
11056
|
+
const owners = new Map;
|
|
11044
11057
|
for (const entry of listed.data) {
|
|
11045
11058
|
if (entry.status === "closed")
|
|
11046
11059
|
continue;
|
|
11047
11060
|
const loaded = this.load(entry.id);
|
|
11048
11061
|
if (!loaded.ok)
|
|
11049
11062
|
return loaded;
|
|
11050
|
-
|
|
11051
|
-
|
|
11063
|
+
for (const worker of loaded.data?.record.workers ?? [])
|
|
11064
|
+
owners.set(worker.id, entry.id);
|
|
11052
11065
|
}
|
|
11066
|
+
const resolved = resolveIdRef("worker", workerId, [...owners.keys()]);
|
|
11067
|
+
if (resolved.ok)
|
|
11068
|
+
return success(null, null, owners.get(resolved.data) ?? null);
|
|
11069
|
+
if (resolved.code !== "not_found")
|
|
11070
|
+
return resolved;
|
|
11053
11071
|
return success(null, null, null);
|
|
11054
11072
|
}
|
|
11055
11073
|
originTaskEntry() {
|
|
@@ -13174,20 +13192,19 @@ var workspaceConfigSchema = object({
|
|
|
13174
13192
|
union([boolean2(), literal("verified")]).optional()
|
|
13175
13193
|
]))).passthrough().optional(),
|
|
13176
13194
|
youtrack: object({ baseUrl: nonBlank.optional(), link_issues: boolean2().optional() }).passthrough().optional(),
|
|
13177
|
-
issues: object({
|
|
13195
|
+
issues: object({
|
|
13196
|
+
provider: _enum(["github", "gitlab", "youtrack"]).optional(),
|
|
13197
|
+
link: boolean2().optional(),
|
|
13198
|
+
relation: unknown().optional(),
|
|
13199
|
+
backlink: boolean2().optional(),
|
|
13200
|
+
link_on_pr: boolean2().optional()
|
|
13201
|
+
}).passthrough().optional(),
|
|
13178
13202
|
branchPolicy: workspaceBranchPolicySchema.optional(),
|
|
13179
13203
|
commitPolicy: workspaceCommitPolicySchema.optional(),
|
|
13180
13204
|
defaultProfile: nonBlank.optional(),
|
|
13181
13205
|
profiles: record(nonBlank, workspaceProfileSchema).optional(),
|
|
13182
13206
|
releaseTracks: record(nonBlank, releaseTrackSchema).optional()
|
|
13183
13207
|
}).passthrough().superRefine((workspace, context) => {
|
|
13184
|
-
if (workspace.issues && workspace.vcs?.provider !== "github") {
|
|
13185
|
-
context.addIssue({
|
|
13186
|
-
code: "custom",
|
|
13187
|
-
path: ["issues"],
|
|
13188
|
-
message: `GitHub issue linking requires the github provider, got ${workspace.vcs?.provider ?? "unset"}`
|
|
13189
|
-
});
|
|
13190
|
-
}
|
|
13191
13208
|
if (workspace.defaultProfile !== undefined && !Object.hasOwn(workspace.profiles ?? {}, workspace.defaultProfile)) {
|
|
13192
13209
|
context.addIssue({
|
|
13193
13210
|
code: "custom",
|
|
@@ -14062,6 +14079,44 @@ var readVcsConfig = () => {
|
|
|
14062
14079
|
}
|
|
14063
14080
|
return { status: "malformed", path: file, config: {}, error: `${file} is not a JSON object` };
|
|
14064
14081
|
};
|
|
14082
|
+
var TRACKERS = new Set(["github", "gitlab", "youtrack"]);
|
|
14083
|
+
var asRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
14084
|
+
var flag = (value) => typeof value === "boolean" ? value : null;
|
|
14085
|
+
var text2 = (value) => typeof value === "string" && value.trim() ? value.trim() : null;
|
|
14086
|
+
function issueTrackerOf(issues, youtrack) {
|
|
14087
|
+
const iss = asRecord(issues);
|
|
14088
|
+
const yt = asRecord(youtrack);
|
|
14089
|
+
const warnings = [];
|
|
14090
|
+
const named = typeof iss.provider === "string" && TRACKERS.has(iss.provider.toLowerCase()) ? iss.provider.toLowerCase() : null;
|
|
14091
|
+
if (iss.relation !== undefined && iss.relation !== "closes" && iss.relation !== "refs")
|
|
14092
|
+
warnings.push(`issues.relation ${JSON.stringify(iss.relation)} is not closes or refs; read as closes`);
|
|
14093
|
+
for (const key of ["repo", "host"])
|
|
14094
|
+
if (iss[key] !== undefined && text2(iss[key]) === null)
|
|
14095
|
+
warnings.push(`issues.${key} is not a non-empty string; ignored`);
|
|
14096
|
+
const common = {
|
|
14097
|
+
relation: iss.relation === "refs" ? "refs" : "closes",
|
|
14098
|
+
backlink: iss.backlink === true,
|
|
14099
|
+
baseUrl: text2(yt.baseUrl),
|
|
14100
|
+
repo: text2(iss.repo)?.replace(/^\/+|\/+$/gu, "") ?? null,
|
|
14101
|
+
host: text2(iss.host)?.toLowerCase() ?? null,
|
|
14102
|
+
warnings
|
|
14103
|
+
};
|
|
14104
|
+
const legacyGithub = named === "github" && flag(iss.link) === null;
|
|
14105
|
+
if (flag(yt.link_issues) === true && (named === null || legacyGithub))
|
|
14106
|
+
return { provider: "youtrack", link: true, ...common, source: "youtrack.link_issues" };
|
|
14107
|
+
if (named) {
|
|
14108
|
+
const link = flag(iss.link) ?? flag(iss.link_on_pr) ?? (named === "youtrack" ? flag(yt.link_issues) : null) ?? false;
|
|
14109
|
+
return {
|
|
14110
|
+
provider: named,
|
|
14111
|
+
link,
|
|
14112
|
+
...common,
|
|
14113
|
+
source: flag(iss.link) === null && flag(iss.link_on_pr) !== null ? "issues.link_on_pr" : "issues"
|
|
14114
|
+
};
|
|
14115
|
+
}
|
|
14116
|
+
if (common.baseUrl)
|
|
14117
|
+
return { provider: "youtrack", link: false, ...common, source: "youtrack.baseUrl" };
|
|
14118
|
+
return null;
|
|
14119
|
+
}
|
|
14065
14120
|
var trackSummary = (resolution) => resolution.status === "resolved" ? {
|
|
14066
14121
|
name: resolution.track?.name ?? null,
|
|
14067
14122
|
source: resolution.source,
|
|
@@ -14082,6 +14137,7 @@ function vcsConfig(mode, cwd, options = {}) {
|
|
|
14082
14137
|
const rawProvider = wsVcs.provider ?? (determinateRoot ? remoteProvider(root) : null) ?? cfg.provider ?? null;
|
|
14083
14138
|
const provider = rawProvider === null || rawProvider === undefined ? null : String(rawProvider).toLowerCase() || null;
|
|
14084
14139
|
const workspaceDefault = workspaceDefaultTarget(root, cfg.defaultTargetBranch);
|
|
14140
|
+
const issueTracker = issueTrackerOf(wsIssues, wsYt);
|
|
14085
14141
|
const linkIssues = typeof wsYt.link_issues === "boolean" ? wsYt.link_issues : null;
|
|
14086
14142
|
const youtrackBaseUrl = typeof wsYt.baseUrl === "string" ? wsYt.baseUrl : null;
|
|
14087
14143
|
let issuesProvider = null;
|
|
@@ -14114,7 +14170,8 @@ function vcsConfig(mode, cwd, options = {}) {
|
|
|
14114
14170
|
link_issues: linkIssues,
|
|
14115
14171
|
youtrack_base_url: youtrackBaseUrl,
|
|
14116
14172
|
issues_provider: issuesProvider,
|
|
14117
|
-
link_on_pr: linkOnPr
|
|
14173
|
+
link_on_pr: linkOnPr,
|
|
14174
|
+
issue_tracker: issueTracker
|
|
14118
14175
|
};
|
|
14119
14176
|
}
|
|
14120
14177
|
if (cfgStatus === "malformed") {
|
|
@@ -14140,7 +14197,8 @@ function vcsConfig(mode, cwd, options = {}) {
|
|
|
14140
14197
|
link_issues: linkIssues,
|
|
14141
14198
|
youtrack_base_url: youtrackBaseUrl,
|
|
14142
14199
|
issues_provider: issuesProvider,
|
|
14143
|
-
link_on_pr: linkOnPr
|
|
14200
|
+
link_on_pr: linkOnPr,
|
|
14201
|
+
issue_tracker: issueTracker
|
|
14144
14202
|
};
|
|
14145
14203
|
if (provider === "gitlab") {
|
|
14146
14204
|
out.gitlab = {
|
|
@@ -14244,7 +14302,12 @@ var MAX_LINE_BYTES = 4096;
|
|
|
14244
14302
|
var PASSING = new Set(["verified", "tests-verified", "type-check-only"]);
|
|
14245
14303
|
var FAILING = new Set(["failed", "blocked"]);
|
|
14246
14304
|
var STRONG_RESULTS = new Set(["verified", "tests-verified"]);
|
|
14247
|
-
var PR_ROW_TYPES = new Set([
|
|
14305
|
+
var PR_ROW_TYPES = new Set([
|
|
14306
|
+
"pr.created",
|
|
14307
|
+
"pr.status",
|
|
14308
|
+
"pr.merged",
|
|
14309
|
+
"pr.linked"
|
|
14310
|
+
]);
|
|
14248
14311
|
var err = (code, error, unblock) => ({
|
|
14249
14312
|
ok: false,
|
|
14250
14313
|
code,
|
|
@@ -18572,7 +18635,7 @@ var RISK = {
|
|
|
18572
18635
|
};
|
|
18573
18636
|
var YES = new Set(["true", "yes", "y", "1", "on"]);
|
|
18574
18637
|
var NO = new Set(["false", "no", "n", "0", "off", "none"]);
|
|
18575
|
-
var
|
|
18638
|
+
var flag2 = (value, unknownAs) => {
|
|
18576
18639
|
if (typeof value === "boolean")
|
|
18577
18640
|
return { ok: true, value };
|
|
18578
18641
|
if (typeof value === "number" && (value === 0 || value === 1))
|
|
@@ -18638,12 +18701,12 @@ function normalizeJudgment(raw, previous) {
|
|
|
18638
18701
|
const items = Array.isArray(value) ? value : [value];
|
|
18639
18702
|
judgment.refs.push(...items.filter((item) => item !== null && item !== "").map(refOf));
|
|
18640
18703
|
} else {
|
|
18641
|
-
if (name === "needsPlan" && typeof value === "string" && !
|
|
18704
|
+
if (name === "needsPlan" && typeof value === "string" && !flag2(value, false).ok && value.trim()) {
|
|
18642
18705
|
judgment.needsPlan = true;
|
|
18643
18706
|
judgment.refs.push(refOf(value.trim()));
|
|
18644
18707
|
continue;
|
|
18645
18708
|
}
|
|
18646
|
-
const parsed =
|
|
18709
|
+
const parsed = flag2(value, name === "behaviorChange");
|
|
18647
18710
|
if (parsed.ok)
|
|
18648
18711
|
judgment[name] = parsed.value;
|
|
18649
18712
|
else
|
|
@@ -18998,6 +19061,8 @@ var TASK_SCOPED_ACTIONS = new Set([
|
|
|
18998
19061
|
"worker.cancel",
|
|
18999
19062
|
"state.export"
|
|
19000
19063
|
]);
|
|
19064
|
+
var ONLY_OWN_REPORT = "workers can submit only their own report";
|
|
19065
|
+
var NO_HELPER_CONTROL = "helpers cannot cancel or control workers";
|
|
19001
19066
|
var WORKER_ADDRESSED_ACTIONS = new Set(["worker.cancel", "worker.report"]);
|
|
19002
19067
|
var workerCommand = (taskId, request) => {
|
|
19003
19068
|
const { action, workerId, reason, report } = request;
|
|
@@ -19895,6 +19960,10 @@ class WorkitCore {
|
|
|
19895
19960
|
}
|
|
19896
19961
|
if (helper?.ok)
|
|
19897
19962
|
return failure2("permission_denied", "helpers cannot resolve findings");
|
|
19963
|
+
const findingRef = resolveIdRef("finding", input.findingId, task.data.findings.map((entry) => entry.id));
|
|
19964
|
+
if (!findingRef.ok)
|
|
19965
|
+
return findingRef;
|
|
19966
|
+
input.findingId = findingRef.data;
|
|
19898
19967
|
const finding = task.data.findings.find((entry) => entry.id === input.findingId);
|
|
19899
19968
|
if (!finding)
|
|
19900
19969
|
return failure2("not_found", "finding not found");
|
|
@@ -20046,15 +20115,31 @@ class WorkitCore {
|
|
|
20046
20115
|
return changed;
|
|
20047
20116
|
return success(changed.data.task.revision, changed.data.workspace.revision, changed.data.task.workers.at(-1));
|
|
20048
20117
|
}
|
|
20118
|
+
const workerRef = resolveIdRef("worker", input.workerId, helperId === null ? task.data.workers.map((candidate) => candidate.id) : [helperId]);
|
|
20119
|
+
if (!workerRef.ok)
|
|
20120
|
+
return helperId === null ? workerRef : failure2("permission_denied", input.action === "report" ? ONLY_OWN_REPORT : NO_HELPER_CONTROL);
|
|
20121
|
+
input.workerId = workerRef.data;
|
|
20049
20122
|
const entry = task.data.workers.find((candidate) => candidate.id === input.workerId);
|
|
20050
20123
|
if (!entry)
|
|
20051
20124
|
return failure2("not_found", "worker not found");
|
|
20052
20125
|
if (input.action === "report") {
|
|
20053
20126
|
if (helperId === null || helperId !== input.workerId)
|
|
20054
|
-
return failure2("permission_denied",
|
|
20127
|
+
return failure2("permission_denied", ONLY_OWN_REPORT);
|
|
20055
20128
|
const helper = this.helperEntry(task.data, true, true);
|
|
20056
20129
|
if (!helper.ok)
|
|
20057
20130
|
return helper;
|
|
20131
|
+
const ownFindings = task.data.findings.filter((candidate) => candidate.provenance.workerId === helperId).map((candidate) => candidate.id);
|
|
20132
|
+
const reported = [];
|
|
20133
|
+
for (const findingRef of input.report.findingIds) {
|
|
20134
|
+
const found = resolveIdRef("finding", findingRef, ownFindings);
|
|
20135
|
+
if (found.ok)
|
|
20136
|
+
reported.push(found.data);
|
|
20137
|
+
else if (found.code === "not_found")
|
|
20138
|
+
reported.push(findingRef);
|
|
20139
|
+
else
|
|
20140
|
+
return found;
|
|
20141
|
+
}
|
|
20142
|
+
input.report.findingIds = reported;
|
|
20058
20143
|
const evidence = task.data.evidence.filter((candidate) => input.report.evidenceIds.includes(candidate.id));
|
|
20059
20144
|
const findings = task.data.findings.filter((candidate) => input.report.findingIds.includes(candidate.id));
|
|
20060
20145
|
if (evidence.length !== input.report.evidenceIds.length || findings.length !== input.report.findingIds.length)
|
|
@@ -20082,7 +20167,7 @@ class WorkitCore {
|
|
|
20082
20167
|
return updated ? success(changed.data.task.revision, changed.data.workspace.revision, updated) : failure2("recovery_required", "worker disappeared during report");
|
|
20083
20168
|
}
|
|
20084
20169
|
if (helperId !== null)
|
|
20085
|
-
return failure2("permission_denied",
|
|
20170
|
+
return failure2("permission_denied", NO_HELPER_CONTROL);
|
|
20086
20171
|
if (task.data.status === "closed")
|
|
20087
20172
|
return failure2("invalid_transition", "closed task cannot cancel workers");
|
|
20088
20173
|
if (entry.data.state === "stopped") {
|
|
@@ -23779,7 +23864,10 @@ var readAssignment = (ctx, request) => {
|
|
|
23779
23864
|
return failure2("permission_denied", "worker assignment is not bound to this workspace");
|
|
23780
23865
|
if (task.data.status !== "active")
|
|
23781
23866
|
return failure2("invalid_transition", "paused or closed tasks cannot supervise workers");
|
|
23782
|
-
const
|
|
23867
|
+
const workerId = resolveIdRef("worker", request.workerId, task.data.workers.map((candidate) => candidate.id));
|
|
23868
|
+
if (!workerId.ok)
|
|
23869
|
+
return workerId;
|
|
23870
|
+
const worker = task.data.workers.find((candidate) => candidate.id === workerId.data);
|
|
23783
23871
|
if (!worker)
|
|
23784
23872
|
return failure2("not_found", "worker assignment not found");
|
|
23785
23873
|
return success(null, workspace.data.revision, {
|
|
@@ -23926,7 +24014,7 @@ function extension(pi) {
|
|
|
23926
24014
|
if (!validated.ok)
|
|
23927
24015
|
return validated;
|
|
23928
24016
|
const { store, task, workspace, worker } = validated.data;
|
|
23929
|
-
const current = [...workers.values()].find((handle) => handle.workerId ===
|
|
24017
|
+
const current = [...workers.values()].find((handle) => handle.workerId === worker.id);
|
|
23930
24018
|
if (request.action === "cancel") {
|
|
23931
24019
|
if (!current)
|
|
23932
24020
|
return failure2("recovery_required", "worker process is not live in this session");
|
package/package.json
CHANGED
|
@@ -33,8 +33,8 @@ that repeats because the base keeps moving, or after 3 failed fix attempts on
|
|
|
33
33
|
the same check.
|
|
34
34
|
|
|
35
35
|
1. **Open.** `workit git push`, then `workit pr create --title "<title>"
|
|
36
|
-
--body-file <f|->` (
|
|
37
|
-
`workit pr edit`). A stack: `workit stack plan <bottom> ... <top>`, one
|
|
36
|
+
--body-file <f|->` plus `--issue <#n|ID>` per issue (`--refs`: no close; idempotent;
|
|
37
|
+
body: `references/pr-body.md`; edits: `workit pr edit`). A stack: `workit stack plan <bottom> ... <top>`, one
|
|
38
38
|
`workit pr create --base <parent> --fill` per branch, then
|
|
39
39
|
`workit stack sync`. Finish the whole stack before babysitting any PR.
|
|
40
40
|
2. **Read state** with `workit pr status --json`. `REVIEW` alone is a pending
|