@brainervirus/workit-cursor 8.14.1 → 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/.cursor-plugin/plugin.json +1 -1
- package/dist/cursor-session-start.js +58 -16
- package/dist/mcp-server.js +59 -14
- package/dist/workit-hook.js +60 -15
- package/package.json +3 -3
- package/skills/workit-ship/SKILL.md +2 -2
|
@@ -9719,20 +9719,19 @@ var init_workspaces = __esm(() => {
|
|
|
9719
9719
|
union([boolean2(), literal("verified")]).optional()
|
|
9720
9720
|
]))).passthrough().optional(),
|
|
9721
9721
|
youtrack: object({ baseUrl: nonBlank.optional(), link_issues: boolean2().optional() }).passthrough().optional(),
|
|
9722
|
-
issues: object({
|
|
9722
|
+
issues: object({
|
|
9723
|
+
provider: _enum(["github", "gitlab", "youtrack"]).optional(),
|
|
9724
|
+
link: boolean2().optional(),
|
|
9725
|
+
relation: unknown().optional(),
|
|
9726
|
+
backlink: boolean2().optional(),
|
|
9727
|
+
link_on_pr: boolean2().optional()
|
|
9728
|
+
}).passthrough().optional(),
|
|
9723
9729
|
branchPolicy: workspaceBranchPolicySchema.optional(),
|
|
9724
9730
|
commitPolicy: workspaceCommitPolicySchema.optional(),
|
|
9725
9731
|
defaultProfile: nonBlank.optional(),
|
|
9726
9732
|
profiles: record(nonBlank, workspaceProfileSchema).optional(),
|
|
9727
9733
|
releaseTracks: record(nonBlank, releaseTrackSchema).optional()
|
|
9728
9734
|
}).passthrough().superRefine((workspace, context) => {
|
|
9729
|
-
if (workspace.issues && workspace.vcs?.provider !== "github") {
|
|
9730
|
-
context.addIssue({
|
|
9731
|
-
code: "custom",
|
|
9732
|
-
path: ["issues"],
|
|
9733
|
-
message: `GitHub issue linking requires the github provider, got ${workspace.vcs?.provider ?? "unset"}`
|
|
9734
|
-
});
|
|
9735
|
-
}
|
|
9736
9735
|
if (workspace.defaultProfile !== undefined && !Object.hasOwn(workspace.profiles ?? {}, workspace.defaultProfile)) {
|
|
9737
9736
|
context.addIssue({
|
|
9738
9737
|
code: "custom",
|
|
@@ -10169,6 +10168,40 @@ var init_release_tracks = __esm(() => {
|
|
|
10169
10168
|
import fs4 from "node:fs";
|
|
10170
10169
|
import path5 from "node:path";
|
|
10171
10170
|
import { spawnSync as spawnSync7 } from "node:child_process";
|
|
10171
|
+
function issueTrackerOf(issues, youtrack) {
|
|
10172
|
+
const iss = asRecord(issues);
|
|
10173
|
+
const yt = asRecord(youtrack);
|
|
10174
|
+
const warnings = [];
|
|
10175
|
+
const named = typeof iss.provider === "string" && TRACKERS.has(iss.provider.toLowerCase()) ? iss.provider.toLowerCase() : null;
|
|
10176
|
+
if (iss.relation !== undefined && iss.relation !== "closes" && iss.relation !== "refs")
|
|
10177
|
+
warnings.push(`issues.relation ${JSON.stringify(iss.relation)} is not closes or refs; read as closes`);
|
|
10178
|
+
for (const key of ["repo", "host"])
|
|
10179
|
+
if (iss[key] !== undefined && text2(iss[key]) === null)
|
|
10180
|
+
warnings.push(`issues.${key} is not a non-empty string; ignored`);
|
|
10181
|
+
const common = {
|
|
10182
|
+
relation: iss.relation === "refs" ? "refs" : "closes",
|
|
10183
|
+
backlink: iss.backlink === true,
|
|
10184
|
+
baseUrl: text2(yt.baseUrl),
|
|
10185
|
+
repo: text2(iss.repo)?.replace(/^\/+|\/+$/gu, "") ?? null,
|
|
10186
|
+
host: text2(iss.host)?.toLowerCase() ?? null,
|
|
10187
|
+
warnings
|
|
10188
|
+
};
|
|
10189
|
+
const legacyGithub = named === "github" && flag(iss.link) === null;
|
|
10190
|
+
if (flag(yt.link_issues) === true && (named === null || legacyGithub))
|
|
10191
|
+
return { provider: "youtrack", link: true, ...common, source: "youtrack.link_issues" };
|
|
10192
|
+
if (named) {
|
|
10193
|
+
const link = flag(iss.link) ?? flag(iss.link_on_pr) ?? (named === "youtrack" ? flag(yt.link_issues) : null) ?? false;
|
|
10194
|
+
return {
|
|
10195
|
+
provider: named,
|
|
10196
|
+
link,
|
|
10197
|
+
...common,
|
|
10198
|
+
source: flag(iss.link) === null && flag(iss.link_on_pr) !== null ? "issues.link_on_pr" : "issues"
|
|
10199
|
+
};
|
|
10200
|
+
}
|
|
10201
|
+
if (common.baseUrl)
|
|
10202
|
+
return { provider: "youtrack", link: false, ...common, source: "youtrack.baseUrl" };
|
|
10203
|
+
return null;
|
|
10204
|
+
}
|
|
10172
10205
|
function vcsConfig(mode, cwd, options = {}) {
|
|
10173
10206
|
const ws = resolveRuntimeWorkspaceVcs(vcsCwd(cwd));
|
|
10174
10207
|
const wsVcs = ws?.vcs ?? {};
|
|
@@ -10180,6 +10213,7 @@ function vcsConfig(mode, cwd, options = {}) {
|
|
|
10180
10213
|
const rawProvider = wsVcs.provider ?? (determinateRoot ? remoteProvider(root) : null) ?? cfg.provider ?? null;
|
|
10181
10214
|
const provider = rawProvider === null || rawProvider === undefined ? null : String(rawProvider).toLowerCase() || null;
|
|
10182
10215
|
const workspaceDefault = workspaceDefaultTarget(root, cfg.defaultTargetBranch);
|
|
10216
|
+
const issueTracker = issueTrackerOf(wsIssues, wsYt);
|
|
10183
10217
|
const linkIssues = typeof wsYt.link_issues === "boolean" ? wsYt.link_issues : null;
|
|
10184
10218
|
const youtrackBaseUrl = typeof wsYt.baseUrl === "string" ? wsYt.baseUrl : null;
|
|
10185
10219
|
let issuesProvider = null;
|
|
@@ -10212,7 +10246,8 @@ function vcsConfig(mode, cwd, options = {}) {
|
|
|
10212
10246
|
link_issues: linkIssues,
|
|
10213
10247
|
youtrack_base_url: youtrackBaseUrl,
|
|
10214
10248
|
issues_provider: issuesProvider,
|
|
10215
|
-
link_on_pr: linkOnPr
|
|
10249
|
+
link_on_pr: linkOnPr,
|
|
10250
|
+
issue_tracker: issueTracker
|
|
10216
10251
|
};
|
|
10217
10252
|
}
|
|
10218
10253
|
if (cfgStatus === "malformed") {
|
|
@@ -10238,7 +10273,8 @@ function vcsConfig(mode, cwd, options = {}) {
|
|
|
10238
10273
|
link_issues: linkIssues,
|
|
10239
10274
|
youtrack_base_url: youtrackBaseUrl,
|
|
10240
10275
|
issues_provider: issuesProvider,
|
|
10241
|
-
link_on_pr: linkOnPr
|
|
10276
|
+
link_on_pr: linkOnPr,
|
|
10277
|
+
issue_tracker: issueTracker
|
|
10242
10278
|
};
|
|
10243
10279
|
if (provider === "gitlab") {
|
|
10244
10280
|
out.gitlab = {
|
|
@@ -10278,7 +10314,7 @@ var workspacesPath = () => path5.join(configDir(), "workspaces.json"), vcsCwd =
|
|
|
10278
10314
|
return { status: "valid", path: file, config: parsed };
|
|
10279
10315
|
}
|
|
10280
10316
|
return { status: "malformed", path: file, config: {}, error: `${file} is not a JSON object` };
|
|
10281
|
-
}, trackSummary = (resolution) => resolution.status === "resolved" ? {
|
|
10317
|
+
}, TRACKERS, asRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {}, flag = (value) => typeof value === "boolean" ? value : null, text2 = (value) => typeof value === "string" && value.trim() ? value.trim() : null, trackSummary = (resolution) => resolution.status === "resolved" ? {
|
|
10282
10318
|
name: resolution.track?.name ?? null,
|
|
10283
10319
|
source: resolution.source,
|
|
10284
10320
|
detail: resolution.detail,
|
|
@@ -10291,6 +10327,7 @@ var init_vcs_config = __esm(() => {
|
|
|
10291
10327
|
init_config();
|
|
10292
10328
|
init_workspaces();
|
|
10293
10329
|
init_release_tracks();
|
|
10330
|
+
TRACKERS = new Set(["github", "gitlab", "youtrack"]);
|
|
10294
10331
|
});
|
|
10295
10332
|
|
|
10296
10333
|
// packages/workit-core/src/core/logger.ts
|
|
@@ -10411,7 +10448,7 @@ function migrateRepoIssued(cwd) {
|
|
|
10411
10448
|
removeIfEmpty(old);
|
|
10412
10449
|
}
|
|
10413
10450
|
function recordIssuedSession(cwd, lead, issued) {
|
|
10414
|
-
const token = randomBytes(18).toString("
|
|
10451
|
+
const token = randomBytes(18).toString("hex");
|
|
10415
10452
|
try {
|
|
10416
10453
|
migrateRepoIssued(cwd);
|
|
10417
10454
|
const own = hash(issued);
|
|
@@ -11245,7 +11282,12 @@ var init_ledger = __esm(() => {
|
|
|
11245
11282
|
PASSING = new Set(["verified", "tests-verified", "type-check-only"]);
|
|
11246
11283
|
FAILING = new Set(["failed", "blocked"]);
|
|
11247
11284
|
STRONG_RESULTS = new Set(["verified", "tests-verified"]);
|
|
11248
|
-
PR_ROW_TYPES = new Set([
|
|
11285
|
+
PR_ROW_TYPES = new Set([
|
|
11286
|
+
"pr.created",
|
|
11287
|
+
"pr.status",
|
|
11288
|
+
"pr.merged",
|
|
11289
|
+
"pr.linked"
|
|
11290
|
+
]);
|
|
11249
11291
|
NETWORK_FS_TYPES = new Set([
|
|
11250
11292
|
26985,
|
|
11251
11293
|
20859,
|
|
@@ -11960,12 +12002,12 @@ function normalizeJudgment(raw, previous) {
|
|
|
11960
12002
|
const items = Array.isArray(value) ? value : [value];
|
|
11961
12003
|
judgment.refs.push(...items.filter((item) => item !== null && item !== "").map(refOf));
|
|
11962
12004
|
} else {
|
|
11963
|
-
if (name === "needsPlan" && typeof value === "string" && !
|
|
12005
|
+
if (name === "needsPlan" && typeof value === "string" && !flag2(value, false).ok && value.trim()) {
|
|
11964
12006
|
judgment.needsPlan = true;
|
|
11965
12007
|
judgment.refs.push(refOf(value.trim()));
|
|
11966
12008
|
continue;
|
|
11967
12009
|
}
|
|
11968
|
-
const parsed =
|
|
12010
|
+
const parsed = flag2(value, name === "behaviorChange");
|
|
11969
12011
|
if (parsed.ok)
|
|
11970
12012
|
judgment[name] = parsed.value;
|
|
11971
12013
|
else
|
|
@@ -11989,7 +12031,7 @@ function normalizeJudgment(raw, previous) {
|
|
|
11989
12031
|
});
|
|
11990
12032
|
return success(null, null, { judgment: parsed.data, ignored, legacy });
|
|
11991
12033
|
}
|
|
11992
|
-
var isObject3 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), squash = (key) => key.toLowerCase().replace(/[_-]/g, ""), ALIASES, LEGACY_KEYS, RISK, YES, NO,
|
|
12034
|
+
var isObject3 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), squash = (key) => key.toLowerCase().replace(/[_-]/g, ""), ALIASES, LEGACY_KEYS, RISK, YES, NO, flag2 = (value, unknownAs) => {
|
|
11993
12035
|
if (typeof value === "boolean")
|
|
11994
12036
|
return { ok: true, value };
|
|
11995
12037
|
if (typeof value === "number" && (value === 0 || value === 1))
|
package/dist/mcp-server.js
CHANGED
|
@@ -22008,20 +22008,19 @@ var workspaceConfigSchema = object2({
|
|
|
22008
22008
|
union([boolean2(), literal("verified")]).optional()
|
|
22009
22009
|
]))).passthrough().optional(),
|
|
22010
22010
|
youtrack: object2({ baseUrl: nonBlank.optional(), link_issues: boolean2().optional() }).passthrough().optional(),
|
|
22011
|
-
issues: object2({
|
|
22011
|
+
issues: object2({
|
|
22012
|
+
provider: _enum(["github", "gitlab", "youtrack"]).optional(),
|
|
22013
|
+
link: boolean2().optional(),
|
|
22014
|
+
relation: unknown().optional(),
|
|
22015
|
+
backlink: boolean2().optional(),
|
|
22016
|
+
link_on_pr: boolean2().optional()
|
|
22017
|
+
}).passthrough().optional(),
|
|
22012
22018
|
branchPolicy: workspaceBranchPolicySchema.optional(),
|
|
22013
22019
|
commitPolicy: workspaceCommitPolicySchema.optional(),
|
|
22014
22020
|
defaultProfile: nonBlank.optional(),
|
|
22015
22021
|
profiles: record(nonBlank, workspaceProfileSchema).optional(),
|
|
22016
22022
|
releaseTracks: record(nonBlank, releaseTrackSchema).optional()
|
|
22017
22023
|
}).passthrough().superRefine((workspace, context) => {
|
|
22018
|
-
if (workspace.issues && workspace.vcs?.provider !== "github") {
|
|
22019
|
-
context.addIssue({
|
|
22020
|
-
code: "custom",
|
|
22021
|
-
path: ["issues"],
|
|
22022
|
-
message: `GitHub issue linking requires the github provider, got ${workspace.vcs?.provider ?? "unset"}`
|
|
22023
|
-
});
|
|
22024
|
-
}
|
|
22025
22024
|
if (workspace.defaultProfile !== undefined && !Object.hasOwn(workspace.profiles ?? {}, workspace.defaultProfile)) {
|
|
22026
22025
|
context.addIssue({
|
|
22027
22026
|
code: "custom",
|
|
@@ -22861,6 +22860,44 @@ var readVcsConfig = () => {
|
|
|
22861
22860
|
}
|
|
22862
22861
|
return { status: "malformed", path: file, config: {}, error: `${file} is not a JSON object` };
|
|
22863
22862
|
};
|
|
22863
|
+
var TRACKERS = new Set(["github", "gitlab", "youtrack"]);
|
|
22864
|
+
var asRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
22865
|
+
var flag = (value) => typeof value === "boolean" ? value : null;
|
|
22866
|
+
var text2 = (value) => typeof value === "string" && value.trim() ? value.trim() : null;
|
|
22867
|
+
function issueTrackerOf(issues, youtrack) {
|
|
22868
|
+
const iss = asRecord(issues);
|
|
22869
|
+
const yt = asRecord(youtrack);
|
|
22870
|
+
const warnings = [];
|
|
22871
|
+
const named = typeof iss.provider === "string" && TRACKERS.has(iss.provider.toLowerCase()) ? iss.provider.toLowerCase() : null;
|
|
22872
|
+
if (iss.relation !== undefined && iss.relation !== "closes" && iss.relation !== "refs")
|
|
22873
|
+
warnings.push(`issues.relation ${JSON.stringify(iss.relation)} is not closes or refs; read as closes`);
|
|
22874
|
+
for (const key of ["repo", "host"])
|
|
22875
|
+
if (iss[key] !== undefined && text2(iss[key]) === null)
|
|
22876
|
+
warnings.push(`issues.${key} is not a non-empty string; ignored`);
|
|
22877
|
+
const common = {
|
|
22878
|
+
relation: iss.relation === "refs" ? "refs" : "closes",
|
|
22879
|
+
backlink: iss.backlink === true,
|
|
22880
|
+
baseUrl: text2(yt.baseUrl),
|
|
22881
|
+
repo: text2(iss.repo)?.replace(/^\/+|\/+$/gu, "") ?? null,
|
|
22882
|
+
host: text2(iss.host)?.toLowerCase() ?? null,
|
|
22883
|
+
warnings
|
|
22884
|
+
};
|
|
22885
|
+
const legacyGithub = named === "github" && flag(iss.link) === null;
|
|
22886
|
+
if (flag(yt.link_issues) === true && (named === null || legacyGithub))
|
|
22887
|
+
return { provider: "youtrack", link: true, ...common, source: "youtrack.link_issues" };
|
|
22888
|
+
if (named) {
|
|
22889
|
+
const link = flag(iss.link) ?? flag(iss.link_on_pr) ?? (named === "youtrack" ? flag(yt.link_issues) : null) ?? false;
|
|
22890
|
+
return {
|
|
22891
|
+
provider: named,
|
|
22892
|
+
link,
|
|
22893
|
+
...common,
|
|
22894
|
+
source: flag(iss.link) === null && flag(iss.link_on_pr) !== null ? "issues.link_on_pr" : "issues"
|
|
22895
|
+
};
|
|
22896
|
+
}
|
|
22897
|
+
if (common.baseUrl)
|
|
22898
|
+
return { provider: "youtrack", link: false, ...common, source: "youtrack.baseUrl" };
|
|
22899
|
+
return null;
|
|
22900
|
+
}
|
|
22864
22901
|
var trackSummary = (resolution) => resolution.status === "resolved" ? {
|
|
22865
22902
|
name: resolution.track?.name ?? null,
|
|
22866
22903
|
source: resolution.source,
|
|
@@ -22881,6 +22918,7 @@ function vcsConfig(mode, cwd, options = {}) {
|
|
|
22881
22918
|
const rawProvider = wsVcs.provider ?? (determinateRoot ? remoteProvider(root) : null) ?? cfg.provider ?? null;
|
|
22882
22919
|
const provider = rawProvider === null || rawProvider === undefined ? null : String(rawProvider).toLowerCase() || null;
|
|
22883
22920
|
const workspaceDefault = workspaceDefaultTarget(root, cfg.defaultTargetBranch);
|
|
22921
|
+
const issueTracker = issueTrackerOf(wsIssues, wsYt);
|
|
22884
22922
|
const linkIssues = typeof wsYt.link_issues === "boolean" ? wsYt.link_issues : null;
|
|
22885
22923
|
const youtrackBaseUrl = typeof wsYt.baseUrl === "string" ? wsYt.baseUrl : null;
|
|
22886
22924
|
let issuesProvider = null;
|
|
@@ -22913,7 +22951,8 @@ function vcsConfig(mode, cwd, options = {}) {
|
|
|
22913
22951
|
link_issues: linkIssues,
|
|
22914
22952
|
youtrack_base_url: youtrackBaseUrl,
|
|
22915
22953
|
issues_provider: issuesProvider,
|
|
22916
|
-
link_on_pr: linkOnPr
|
|
22954
|
+
link_on_pr: linkOnPr,
|
|
22955
|
+
issue_tracker: issueTracker
|
|
22917
22956
|
};
|
|
22918
22957
|
}
|
|
22919
22958
|
if (cfgStatus === "malformed") {
|
|
@@ -22939,7 +22978,8 @@ function vcsConfig(mode, cwd, options = {}) {
|
|
|
22939
22978
|
link_issues: linkIssues,
|
|
22940
22979
|
youtrack_base_url: youtrackBaseUrl,
|
|
22941
22980
|
issues_provider: issuesProvider,
|
|
22942
|
-
link_on_pr: linkOnPr
|
|
22981
|
+
link_on_pr: linkOnPr,
|
|
22982
|
+
issue_tracker: issueTracker
|
|
22943
22983
|
};
|
|
22944
22984
|
if (provider === "gitlab") {
|
|
22945
22985
|
out.gitlab = {
|
|
@@ -23043,7 +23083,12 @@ var MAX_LINE_BYTES = 4096;
|
|
|
23043
23083
|
var PASSING = new Set(["verified", "tests-verified", "type-check-only"]);
|
|
23044
23084
|
var FAILING = new Set(["failed", "blocked"]);
|
|
23045
23085
|
var STRONG_RESULTS = new Set(["verified", "tests-verified"]);
|
|
23046
|
-
var PR_ROW_TYPES = new Set([
|
|
23086
|
+
var PR_ROW_TYPES = new Set([
|
|
23087
|
+
"pr.created",
|
|
23088
|
+
"pr.status",
|
|
23089
|
+
"pr.merged",
|
|
23090
|
+
"pr.linked"
|
|
23091
|
+
]);
|
|
23047
23092
|
var err = (code, error, unblock) => ({
|
|
23048
23093
|
ok: false,
|
|
23049
23094
|
code,
|
|
@@ -25180,7 +25225,7 @@ var RISK = {
|
|
|
25180
25225
|
};
|
|
25181
25226
|
var YES = new Set(["true", "yes", "y", "1", "on"]);
|
|
25182
25227
|
var NO = new Set(["false", "no", "n", "0", "off", "none"]);
|
|
25183
|
-
var
|
|
25228
|
+
var flag2 = (value, unknownAs) => {
|
|
25184
25229
|
if (typeof value === "boolean")
|
|
25185
25230
|
return { ok: true, value };
|
|
25186
25231
|
if (typeof value === "number" && (value === 0 || value === 1))
|
|
@@ -25246,12 +25291,12 @@ function normalizeJudgment(raw, previous) {
|
|
|
25246
25291
|
const items = Array.isArray(value) ? value : [value];
|
|
25247
25292
|
judgment.refs.push(...items.filter((item) => item !== null && item !== "").map(refOf));
|
|
25248
25293
|
} else {
|
|
25249
|
-
if (name === "needsPlan" && typeof value === "string" && !
|
|
25294
|
+
if (name === "needsPlan" && typeof value === "string" && !flag2(value, false).ok && value.trim()) {
|
|
25250
25295
|
judgment.needsPlan = true;
|
|
25251
25296
|
judgment.refs.push(refOf(value.trim()));
|
|
25252
25297
|
continue;
|
|
25253
25298
|
}
|
|
25254
|
-
const parsed =
|
|
25299
|
+
const parsed = flag2(value, name === "behaviorChange");
|
|
25255
25300
|
if (parsed.ok)
|
|
25256
25301
|
judgment[name] = parsed.value;
|
|
25257
25302
|
else
|
package/dist/workit-hook.js
CHANGED
|
@@ -9374,20 +9374,19 @@ var workspaceConfigSchema = object({
|
|
|
9374
9374
|
union([boolean2(), literal("verified")]).optional()
|
|
9375
9375
|
]))).passthrough().optional(),
|
|
9376
9376
|
youtrack: object({ baseUrl: nonBlank.optional(), link_issues: boolean2().optional() }).passthrough().optional(),
|
|
9377
|
-
issues: object({
|
|
9377
|
+
issues: object({
|
|
9378
|
+
provider: _enum(["github", "gitlab", "youtrack"]).optional(),
|
|
9379
|
+
link: boolean2().optional(),
|
|
9380
|
+
relation: unknown().optional(),
|
|
9381
|
+
backlink: boolean2().optional(),
|
|
9382
|
+
link_on_pr: boolean2().optional()
|
|
9383
|
+
}).passthrough().optional(),
|
|
9378
9384
|
branchPolicy: workspaceBranchPolicySchema.optional(),
|
|
9379
9385
|
commitPolicy: workspaceCommitPolicySchema.optional(),
|
|
9380
9386
|
defaultProfile: nonBlank.optional(),
|
|
9381
9387
|
profiles: record(nonBlank, workspaceProfileSchema).optional(),
|
|
9382
9388
|
releaseTracks: record(nonBlank, releaseTrackSchema).optional()
|
|
9383
9389
|
}).passthrough().superRefine((workspace, context) => {
|
|
9384
|
-
if (workspace.issues && workspace.vcs?.provider !== "github") {
|
|
9385
|
-
context.addIssue({
|
|
9386
|
-
code: "custom",
|
|
9387
|
-
path: ["issues"],
|
|
9388
|
-
message: `GitHub issue linking requires the github provider, got ${workspace.vcs?.provider ?? "unset"}`
|
|
9389
|
-
});
|
|
9390
|
-
}
|
|
9391
9390
|
if (workspace.defaultProfile !== undefined && !Object.hasOwn(workspace.profiles ?? {}, workspace.defaultProfile)) {
|
|
9392
9391
|
context.addIssue({
|
|
9393
9392
|
code: "custom",
|
|
@@ -10189,6 +10188,44 @@ var readVcsConfig = () => {
|
|
|
10189
10188
|
}
|
|
10190
10189
|
return { status: "malformed", path: file, config: {}, error: `${file} is not a JSON object` };
|
|
10191
10190
|
};
|
|
10191
|
+
var TRACKERS = new Set(["github", "gitlab", "youtrack"]);
|
|
10192
|
+
var asRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
10193
|
+
var flag = (value) => typeof value === "boolean" ? value : null;
|
|
10194
|
+
var text2 = (value) => typeof value === "string" && value.trim() ? value.trim() : null;
|
|
10195
|
+
function issueTrackerOf(issues, youtrack) {
|
|
10196
|
+
const iss = asRecord(issues);
|
|
10197
|
+
const yt = asRecord(youtrack);
|
|
10198
|
+
const warnings = [];
|
|
10199
|
+
const named = typeof iss.provider === "string" && TRACKERS.has(iss.provider.toLowerCase()) ? iss.provider.toLowerCase() : null;
|
|
10200
|
+
if (iss.relation !== undefined && iss.relation !== "closes" && iss.relation !== "refs")
|
|
10201
|
+
warnings.push(`issues.relation ${JSON.stringify(iss.relation)} is not closes or refs; read as closes`);
|
|
10202
|
+
for (const key of ["repo", "host"])
|
|
10203
|
+
if (iss[key] !== undefined && text2(iss[key]) === null)
|
|
10204
|
+
warnings.push(`issues.${key} is not a non-empty string; ignored`);
|
|
10205
|
+
const common = {
|
|
10206
|
+
relation: iss.relation === "refs" ? "refs" : "closes",
|
|
10207
|
+
backlink: iss.backlink === true,
|
|
10208
|
+
baseUrl: text2(yt.baseUrl),
|
|
10209
|
+
repo: text2(iss.repo)?.replace(/^\/+|\/+$/gu, "") ?? null,
|
|
10210
|
+
host: text2(iss.host)?.toLowerCase() ?? null,
|
|
10211
|
+
warnings
|
|
10212
|
+
};
|
|
10213
|
+
const legacyGithub = named === "github" && flag(iss.link) === null;
|
|
10214
|
+
if (flag(yt.link_issues) === true && (named === null || legacyGithub))
|
|
10215
|
+
return { provider: "youtrack", link: true, ...common, source: "youtrack.link_issues" };
|
|
10216
|
+
if (named) {
|
|
10217
|
+
const link = flag(iss.link) ?? flag(iss.link_on_pr) ?? (named === "youtrack" ? flag(yt.link_issues) : null) ?? false;
|
|
10218
|
+
return {
|
|
10219
|
+
provider: named,
|
|
10220
|
+
link,
|
|
10221
|
+
...common,
|
|
10222
|
+
source: flag(iss.link) === null && flag(iss.link_on_pr) !== null ? "issues.link_on_pr" : "issues"
|
|
10223
|
+
};
|
|
10224
|
+
}
|
|
10225
|
+
if (common.baseUrl)
|
|
10226
|
+
return { provider: "youtrack", link: false, ...common, source: "youtrack.baseUrl" };
|
|
10227
|
+
return null;
|
|
10228
|
+
}
|
|
10192
10229
|
var trackSummary = (resolution) => resolution.status === "resolved" ? {
|
|
10193
10230
|
name: resolution.track?.name ?? null,
|
|
10194
10231
|
source: resolution.source,
|
|
@@ -10209,6 +10246,7 @@ function vcsConfig(mode, cwd, options = {}) {
|
|
|
10209
10246
|
const rawProvider = wsVcs.provider ?? (determinateRoot ? remoteProvider(root) : null) ?? cfg.provider ?? null;
|
|
10210
10247
|
const provider = rawProvider === null || rawProvider === undefined ? null : String(rawProvider).toLowerCase() || null;
|
|
10211
10248
|
const workspaceDefault = workspaceDefaultTarget(root, cfg.defaultTargetBranch);
|
|
10249
|
+
const issueTracker = issueTrackerOf(wsIssues, wsYt);
|
|
10212
10250
|
const linkIssues = typeof wsYt.link_issues === "boolean" ? wsYt.link_issues : null;
|
|
10213
10251
|
const youtrackBaseUrl = typeof wsYt.baseUrl === "string" ? wsYt.baseUrl : null;
|
|
10214
10252
|
let issuesProvider = null;
|
|
@@ -10241,7 +10279,8 @@ function vcsConfig(mode, cwd, options = {}) {
|
|
|
10241
10279
|
link_issues: linkIssues,
|
|
10242
10280
|
youtrack_base_url: youtrackBaseUrl,
|
|
10243
10281
|
issues_provider: issuesProvider,
|
|
10244
|
-
link_on_pr: linkOnPr
|
|
10282
|
+
link_on_pr: linkOnPr,
|
|
10283
|
+
issue_tracker: issueTracker
|
|
10245
10284
|
};
|
|
10246
10285
|
}
|
|
10247
10286
|
if (cfgStatus === "malformed") {
|
|
@@ -10267,7 +10306,8 @@ function vcsConfig(mode, cwd, options = {}) {
|
|
|
10267
10306
|
link_issues: linkIssues,
|
|
10268
10307
|
youtrack_base_url: youtrackBaseUrl,
|
|
10269
10308
|
issues_provider: issuesProvider,
|
|
10270
|
-
link_on_pr: linkOnPr
|
|
10309
|
+
link_on_pr: linkOnPr,
|
|
10310
|
+
issue_tracker: issueTracker
|
|
10271
10311
|
};
|
|
10272
10312
|
if (provider === "gitlab") {
|
|
10273
10313
|
out.gitlab = {
|
|
@@ -10426,7 +10466,7 @@ var removeIfEmpty = (dir) => {
|
|
|
10426
10466
|
};
|
|
10427
10467
|
var tokenHash = (token) => createHash6("sha256").update(token).digest("hex");
|
|
10428
10468
|
function recordIssuedSession(cwd, lead, issued) {
|
|
10429
|
-
const token = randomBytes(18).toString("
|
|
10469
|
+
const token = randomBytes(18).toString("hex");
|
|
10430
10470
|
try {
|
|
10431
10471
|
migrateRepoIssued(cwd);
|
|
10432
10472
|
const own = hash(issued);
|
|
@@ -10497,7 +10537,12 @@ var MAX_LINE_BYTES = 4096;
|
|
|
10497
10537
|
var PASSING = new Set(["verified", "tests-verified", "type-check-only"]);
|
|
10498
10538
|
var FAILING = new Set(["failed", "blocked"]);
|
|
10499
10539
|
var STRONG_RESULTS = new Set(["verified", "tests-verified"]);
|
|
10500
|
-
var PR_ROW_TYPES = new Set([
|
|
10540
|
+
var PR_ROW_TYPES = new Set([
|
|
10541
|
+
"pr.created",
|
|
10542
|
+
"pr.status",
|
|
10543
|
+
"pr.merged",
|
|
10544
|
+
"pr.linked"
|
|
10545
|
+
]);
|
|
10501
10546
|
var err = (code, error, unblock) => ({
|
|
10502
10547
|
ok: false,
|
|
10503
10548
|
code,
|
|
@@ -11978,7 +12023,7 @@ var RISK = {
|
|
|
11978
12023
|
};
|
|
11979
12024
|
var YES = new Set(["true", "yes", "y", "1", "on"]);
|
|
11980
12025
|
var NO = new Set(["false", "no", "n", "0", "off", "none"]);
|
|
11981
|
-
var
|
|
12026
|
+
var flag2 = (value, unknownAs) => {
|
|
11982
12027
|
if (typeof value === "boolean")
|
|
11983
12028
|
return { ok: true, value };
|
|
11984
12029
|
if (typeof value === "number" && (value === 0 || value === 1))
|
|
@@ -12044,12 +12089,12 @@ function normalizeJudgment(raw, previous) {
|
|
|
12044
12089
|
const items = Array.isArray(value) ? value : [value];
|
|
12045
12090
|
judgment.refs.push(...items.filter((item) => item !== null && item !== "").map(refOf));
|
|
12046
12091
|
} else {
|
|
12047
|
-
if (name === "needsPlan" && typeof value === "string" && !
|
|
12092
|
+
if (name === "needsPlan" && typeof value === "string" && !flag2(value, false).ok && value.trim()) {
|
|
12048
12093
|
judgment.needsPlan = true;
|
|
12049
12094
|
judgment.refs.push(refOf(value.trim()));
|
|
12050
12095
|
continue;
|
|
12051
12096
|
}
|
|
12052
|
-
const parsed =
|
|
12097
|
+
const parsed = flag2(value, name === "behaviorChange");
|
|
12053
12098
|
if (parsed.ok)
|
|
12054
12099
|
judgment[name] = parsed.value;
|
|
12055
12100
|
else
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brainervirus/workit-cursor",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.15.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Workit Cursor plugin — shared MCP transport, native hooks, and sixteen method skills",
|
|
6
6
|
"keywords": [
|
|
@@ -46,8 +46,8 @@
|
|
|
46
46
|
"build": "bun scripts/build.ts"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@brainervirus/workit-core": "^8.
|
|
50
|
-
"@brainervirus/workit-mcp": "^8.
|
|
49
|
+
"@brainervirus/workit-core": "^8.15.0",
|
|
50
|
+
"@brainervirus/workit-mcp": "^8.15.0"
|
|
51
51
|
},
|
|
52
52
|
"engines": {
|
|
53
53
|
"node": ">=24"
|
|
@@ -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
|