@brainervirus/workit-cursor 7.0.0 → 7.2.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 +267 -41
- package/dist/mcp-server.js +555 -67
- package/dist/workit-hook.js +270 -37
- package/package.json +3 -3
- package/skills/workit-implement/SKILL.md +3 -2
- package/skills/workit-ship/SKILL.md +31 -13
|
@@ -10081,14 +10081,14 @@ var diagnosticLogger, PRESETS, mergePreset = (preset, input = {}, current = {
|
|
|
10081
10081
|
if (result.status === "malformed")
|
|
10082
10082
|
throw new Error(result.error);
|
|
10083
10083
|
return result.config ?? DEFAULTS;
|
|
10084
|
-
}, resolveBranchPolicy = (config, workspace) => {
|
|
10084
|
+
}, branchGlobPattern = (glob) => new RegExp(`^${glob.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*")}$`, "i"), resolveBranchPolicy = (config, workspace) => {
|
|
10085
10085
|
const wp = workspace?.branchPolicy ?? {};
|
|
10086
10086
|
const preset = Object.hasOwn(PRESETS, wp.preset) ? wp.preset : config.branchPolicy?.preset ?? "gitflow";
|
|
10087
10087
|
const merged = mergePreset(preset, {
|
|
10088
10088
|
allowed: wp.allowed,
|
|
10089
10089
|
protectedNames: wp.protected
|
|
10090
10090
|
}, config);
|
|
10091
|
-
const allowed = merged.allowed.map(
|
|
10091
|
+
const allowed = merged.allowed.map(branchGlobPattern);
|
|
10092
10092
|
return {
|
|
10093
10093
|
preset,
|
|
10094
10094
|
allowed,
|
|
@@ -10334,7 +10334,7 @@ var nonBlank, branchPreset, commitPreset, workspaceBranchPolicySchema, workspace
|
|
|
10334
10334
|
profiles: record(nonBlank, profileSchema).optional()
|
|
10335
10335
|
}).passthrough();
|
|
10336
10336
|
return entrySchema;
|
|
10337
|
-
}, runtimeWorkspaceIndexSchema,
|
|
10337
|
+
}, runtimeWorkspaceIndexSchema, matchRuntimeWorkspace = (cwd) => {
|
|
10338
10338
|
const file = path6.join(configDir(), "workspaces.json");
|
|
10339
10339
|
let raw;
|
|
10340
10340
|
try {
|
|
@@ -10369,8 +10369,15 @@ var nonBlank, branchPreset, commitPreset, workspaceBranchPolicySchema, workspace
|
|
|
10369
10369
|
});
|
|
10370
10370
|
const workspaceName = process.env.WORKFLOW_WORKSPACE_NAME?.trim() || undefined;
|
|
10371
10371
|
const selected = selectWorkspaceMatch(matches, cwd, workspaceName);
|
|
10372
|
-
|
|
10372
|
+
return selected ? { file, selected } : null;
|
|
10373
|
+
}, resolveRuntimeReleaseTracks = (cwd) => {
|
|
10374
|
+
const matched = matchRuntimeWorkspace(cwd);
|
|
10375
|
+
return matched ? { workspace: matched.selected.name, releaseTracks: matched.selected.releaseTracks } : null;
|
|
10376
|
+
}, resolveRuntimeWorkspaceCandidate = (cwd, kind) => {
|
|
10377
|
+
const matched = matchRuntimeWorkspace(cwd);
|
|
10378
|
+
if (!matched)
|
|
10373
10379
|
return null;
|
|
10380
|
+
const { file, selected } = matched;
|
|
10374
10381
|
const policy = runtimeWorkspacePolicySchema(kind).safeParse(selected);
|
|
10375
10382
|
if (!policy.success) {
|
|
10376
10383
|
const detail = policy.error.issues.map((issue) => `${issue.path.map(String).join(".") || "workspace"}: ${issue.message}`).join("; ");
|
|
@@ -10431,26 +10438,31 @@ var init_workspaces = __esm(() => {
|
|
|
10431
10438
|
object({ kind: literal("manual") }).strict()
|
|
10432
10439
|
]);
|
|
10433
10440
|
releaseTrackSchema = object({
|
|
10434
|
-
strategy: branchPreset,
|
|
10441
|
+
strategy: branchPreset.optional(),
|
|
10435
10442
|
productionBranch: nonBlank,
|
|
10436
10443
|
integrationBranch: nonBlank,
|
|
10437
|
-
naming: object({
|
|
10438
|
-
|
|
10439
|
-
|
|
10440
|
-
|
|
10441
|
-
|
|
10442
|
-
|
|
10443
|
-
|
|
10444
|
-
|
|
10444
|
+
naming: object({
|
|
10445
|
+
feature: nonBlank.optional(),
|
|
10446
|
+
release: nonBlank.optional(),
|
|
10447
|
+
hotfix: nonBlank.optional()
|
|
10448
|
+
}).passthrough().optional(),
|
|
10449
|
+
baseBranch: nonBlank.optional(),
|
|
10450
|
+
mergeBackBranches: array(nonBlank).optional(),
|
|
10451
|
+
pullRequestTarget: nonBlank.optional(),
|
|
10452
|
+
tagNamespace: string2().optional(),
|
|
10453
|
+
versionSource: versionSourceSchema.optional(),
|
|
10454
|
+
requiredChecks: array(nonBlank).optional(),
|
|
10455
|
+
critical: array(nonBlank).optional()
|
|
10456
|
+
}).passthrough().superRefine((track, context) => {
|
|
10445
10457
|
for (const [field, values] of [
|
|
10446
|
-
["mergeBackBranches", track.mergeBackBranches],
|
|
10447
|
-
["requiredChecks", track.requiredChecks]
|
|
10458
|
+
["mergeBackBranches", track.mergeBackBranches ?? []],
|
|
10459
|
+
["requiredChecks", track.requiredChecks ?? []]
|
|
10448
10460
|
]) {
|
|
10449
10461
|
if (new Set(values).size !== values.length) {
|
|
10450
10462
|
context.addIssue({ code: "custom", path: [field], message: "entries must be unique" });
|
|
10451
10463
|
}
|
|
10452
10464
|
}
|
|
10453
|
-
if (track.versionSource
|
|
10465
|
+
if (track.versionSource?.kind === "package-json" && (path6.posix.isAbsolute(track.versionSource.path.replaceAll("\\", "/")) || /^[A-Za-z]:\//u.test(track.versionSource.path.replaceAll("\\", "/")) || track.versionSource.path.replaceAll("\\", "/").split("/").includes(".."))) {
|
|
10454
10466
|
context.addIssue({
|
|
10455
10467
|
code: "custom",
|
|
10456
10468
|
path: ["versionSource", "path"],
|
|
@@ -10468,7 +10480,7 @@ var init_workspaces = __esm(() => {
|
|
|
10468
10480
|
account: nonBlank.optional()
|
|
10469
10481
|
}).passthrough().optional(),
|
|
10470
10482
|
autoApprove: union([boolean2(), array(nonBlank)]).optional(),
|
|
10471
|
-
defaultEndpoint:
|
|
10483
|
+
defaultEndpoint: unknown().optional(),
|
|
10472
10484
|
verification: _enum(["self", "independent"]).optional(),
|
|
10473
10485
|
autonomy: object(Object.fromEntries(["push", "pr", "merge", "release", "rerun"].map((kind) => [
|
|
10474
10486
|
kind,
|
|
@@ -10520,6 +10532,46 @@ var init_workspaces = __esm(() => {
|
|
|
10520
10532
|
// packages/workit-core/src/autonomy.ts
|
|
10521
10533
|
import os3 from "node:os";
|
|
10522
10534
|
import path7 from "node:path";
|
|
10535
|
+
function endpointOf(entry) {
|
|
10536
|
+
const raw = entry?.defaultEndpoint;
|
|
10537
|
+
if (raw === undefined)
|
|
10538
|
+
return { raw, endpoint: DEFAULT_ENDPOINT };
|
|
10539
|
+
if (isDefaultEndpoint(raw))
|
|
10540
|
+
return { raw, endpoint: raw };
|
|
10541
|
+
return {
|
|
10542
|
+
raw,
|
|
10543
|
+
endpoint: DEFAULT_ENDPOINT,
|
|
10544
|
+
issue: `defaultEndpoint ${JSON.stringify(raw)} is not one of ${DEFAULT_ENDPOINTS.join(", ")}; using ${DEFAULT_ENDPOINT}`
|
|
10545
|
+
};
|
|
10546
|
+
}
|
|
10547
|
+
function effectiveEndpoint(endpoint, context) {
|
|
10548
|
+
if (endpoint === "commit")
|
|
10549
|
+
return { endpoint };
|
|
10550
|
+
const missing = (kind) => `${kind} grant missing; ${grantHint(context.workspace, kind)}`;
|
|
10551
|
+
if (context.grants.push === false)
|
|
10552
|
+
return { endpoint: "commit", reason: missing("push") };
|
|
10553
|
+
if (context.grants.pr === false)
|
|
10554
|
+
return { endpoint: "commit", reason: missing("pr") };
|
|
10555
|
+
if (context.configured.length > 0 && !context.accountConfigured)
|
|
10556
|
+
return {
|
|
10557
|
+
endpoint: "commit",
|
|
10558
|
+
reason: `vcs.account missing; set vcs.account for workspace "${context.workspace ?? "?"}" in ~/.config/workit/workspaces.json`
|
|
10559
|
+
};
|
|
10560
|
+
if (endpoint === "merged" && context.grants.merge === false)
|
|
10561
|
+
return { endpoint: "green", reason: missing("merge") };
|
|
10562
|
+
return { endpoint };
|
|
10563
|
+
}
|
|
10564
|
+
function endpointView(entry, context) {
|
|
10565
|
+
const { raw, endpoint, issue } = endpointOf(entry);
|
|
10566
|
+
const effective = effectiveEndpoint(endpoint, context);
|
|
10567
|
+
return {
|
|
10568
|
+
defaultEndpoint: endpoint,
|
|
10569
|
+
configuredEndpoint: raw ?? null,
|
|
10570
|
+
effectiveEndpoint: effective.endpoint,
|
|
10571
|
+
...effective.reason ? { endpointReason: effective.reason } : {},
|
|
10572
|
+
...issue ? { endpointIssue: issue } : {}
|
|
10573
|
+
};
|
|
10574
|
+
}
|
|
10523
10575
|
function configuredGrants(entry) {
|
|
10524
10576
|
const record = entry ?? {};
|
|
10525
10577
|
const raw = record.autonomy;
|
|
@@ -10545,18 +10597,28 @@ function resolveAutonomy(cwd) {
|
|
|
10545
10597
|
source: "default",
|
|
10546
10598
|
accountConfigured: false,
|
|
10547
10599
|
defaultEndpoint: DEFAULT_ENDPOINT,
|
|
10600
|
+
configuredEndpoint: null,
|
|
10601
|
+
effectiveEndpoint: DEFAULT_ENDPOINT,
|
|
10548
10602
|
verification: DEFAULT_VERIFICATION,
|
|
10549
10603
|
note: override
|
|
10550
10604
|
};
|
|
10551
10605
|
const workspace = resolveWorkspaceFrom(cwd, grantsDir(), process.env.WORKFLOW_WORKSPACE_NAME?.trim() || undefined);
|
|
10552
10606
|
const { grants, source } = configuredGrants(workspace);
|
|
10607
|
+
const full = { ...DEFAULT_GRANTS, ...grants };
|
|
10608
|
+
const configured = GRANT_KINDS.filter((kind) => grants[kind] !== undefined);
|
|
10609
|
+
const accountConfigured = Boolean(workspace?.vcs?.account);
|
|
10553
10610
|
return {
|
|
10554
10611
|
workspace: workspace?.name ?? null,
|
|
10555
|
-
grants:
|
|
10556
|
-
configured
|
|
10612
|
+
grants: full,
|
|
10613
|
+
configured,
|
|
10557
10614
|
source,
|
|
10558
|
-
accountConfigured
|
|
10559
|
-
|
|
10615
|
+
accountConfigured,
|
|
10616
|
+
...endpointView(workspace, {
|
|
10617
|
+
workspace: workspace?.name ?? null,
|
|
10618
|
+
grants: full,
|
|
10619
|
+
configured,
|
|
10620
|
+
accountConfigured
|
|
10621
|
+
}),
|
|
10560
10622
|
verification: verificationOf(workspace)
|
|
10561
10623
|
};
|
|
10562
10624
|
}
|
|
@@ -10569,7 +10631,7 @@ var accountHome = () => {
|
|
|
10569
10631
|
}, grantsHome, grantsDir = () => path7.join(grantsHome.resolve(), ".config", "workit"), grantsOverride = () => {
|
|
10570
10632
|
const configured = path7.resolve(resolveConfigDir());
|
|
10571
10633
|
return configured === path7.resolve(grantsDir()) ? null : `the config directory is redirected to ${configured} (WORKFLOW_TOOLKIT_CONFIG, WORKFLOW_TOOLKIT_CONFIG_DIR or XDG_CONFIG_HOME); grants are read only from ${path7.join(grantsDir(), "workspaces.json")}, so the D4 defaults apply`;
|
|
10572
|
-
}, GRANT_KINDS, DEFAULT_GRANTS, DEFAULT_ENDPOINT = "commit",
|
|
10634
|
+
}, GRANT_KINDS, DEFAULT_GRANTS, DEFAULT_ENDPOINTS, DEFAULT_ENDPOINT = "commit", isDefaultEndpoint = (value) => typeof value === "string" && DEFAULT_ENDPOINTS.includes(value), DEFAULT_VERIFICATION = "self", verificationOf = (entry) => entry?.verification === "independent" ? "independent" : "self", isGrantValue = (value) => value === true || value === false || value === "verified", normalized = (kind, value) => value === "verified" && kind !== "merge" ? true : value, fromAutoApprove = (value) => {
|
|
10573
10635
|
if (value === true)
|
|
10574
10636
|
return { push: true, pr: true, merge: "verified" };
|
|
10575
10637
|
if (!Array.isArray(value))
|
|
@@ -10581,7 +10643,7 @@ var accountHome = () => {
|
|
|
10581
10643
|
else if (item === "merge")
|
|
10582
10644
|
grants.merge = "verified";
|
|
10583
10645
|
return Object.keys(grants).length > 0 ? grants : null;
|
|
10584
|
-
}
|
|
10646
|
+
}, suggested = (kind) => kind === "merge" ? "verified" : "true", grantHint = (workspace, kind) => `ask the user to run, in their own terminal: workit grant set ${workspace ?? "<workspace>"} ${kind}=${suggested(kind)}`;
|
|
10585
10647
|
var init_autonomy = __esm(() => {
|
|
10586
10648
|
init_config();
|
|
10587
10649
|
init_safe_write();
|
|
@@ -10595,6 +10657,7 @@ var init_autonomy = __esm(() => {
|
|
|
10595
10657
|
release: false,
|
|
10596
10658
|
rerun: true
|
|
10597
10659
|
});
|
|
10660
|
+
DEFAULT_ENDPOINTS = ["commit", "pr", "green", "merged"];
|
|
10598
10661
|
});
|
|
10599
10662
|
|
|
10600
10663
|
// node_modules/@openclaw/fs-safe/dist/errors.js
|
|
@@ -14291,10 +14354,10 @@ Autonomy contract:
|
|
|
14291
14354
|
Stop only for a new consequential choice, a host denial, a conflicting edit
|
|
14292
14355
|
or an unresolved blocker; report open gaps and uncertain workers.
|
|
14293
14356
|
- No endpoint named: stop at a local commit on a policy-compliant branch and
|
|
14294
|
-
state the next command.
|
|
14295
|
-
|
|
14296
|
-
\`
|
|
14297
|
-
|
|
14357
|
+
state the next command. If the request implies delivery (fix, implement,
|
|
14358
|
+
ship), go to the effective endpoint in \`workit grant show\`: \`pr\` opens
|
|
14359
|
+
the PR; \`green\` babysits it without asking (workit-ship) to merge-ready,
|
|
14360
|
+
never merging; \`merged\` also lands it with \`workit pr merge\`.
|
|
14298
14361
|
Merge and release need a workspace grant; a blocked verb names its unblock.
|
|
14299
14362
|
Only the user raises a grant, from their own terminal (\`workit grant set\`);
|
|
14300
14363
|
never edit workspaces.json or route around a grant_required.
|
|
@@ -16225,11 +16288,150 @@ var init_commit_flavors = () => {};
|
|
|
16225
16288
|
// packages/workit-core/src/core/git.ts
|
|
16226
16289
|
var init_git = () => {};
|
|
16227
16290
|
|
|
16291
|
+
// packages/workit-core/src/core/release-tracks.ts
|
|
16292
|
+
function readReleaseTracks(raw) {
|
|
16293
|
+
const out = { tracks: [], issues: [], error: null, protectedBranches: [] };
|
|
16294
|
+
if (raw === undefined || raw === null)
|
|
16295
|
+
return out;
|
|
16296
|
+
if (!isRecord3(raw)) {
|
|
16297
|
+
out.issues.push("releaseTracks is not an object; ignored");
|
|
16298
|
+
return out;
|
|
16299
|
+
}
|
|
16300
|
+
const fatal = [];
|
|
16301
|
+
const protectedNames = new Set;
|
|
16302
|
+
for (const [name, entry] of Object.entries(raw).toSorted(([a], [b]) => a < b ? -1 : 1)) {
|
|
16303
|
+
const label = `release track ${JSON.stringify(name)}`;
|
|
16304
|
+
if (!isRecord3(entry)) {
|
|
16305
|
+
out.issues.push(`${label} is not an object; ignored`);
|
|
16306
|
+
continue;
|
|
16307
|
+
}
|
|
16308
|
+
for (const branch of namedBranches(entry))
|
|
16309
|
+
protectedNames.add(branch);
|
|
16310
|
+
if (!name.trim()) {
|
|
16311
|
+
out.issues.push("a release track with a blank name was ignored");
|
|
16312
|
+
continue;
|
|
16313
|
+
}
|
|
16314
|
+
let critical = [];
|
|
16315
|
+
if (Array.isArray(entry.critical))
|
|
16316
|
+
critical = entry.critical.filter((item) => typeof item === "string");
|
|
16317
|
+
else if (entry.critical !== undefined)
|
|
16318
|
+
out.issues.push(`${label} critical: must be a list of field names; ignored`);
|
|
16319
|
+
const isCritical = (field) => critical.some((item) => field === item || field.startsWith(`${item}.`));
|
|
16320
|
+
const problem = (field, message) => {
|
|
16321
|
+
if (isCritical(field))
|
|
16322
|
+
fatal.push(`${label} ${field}: ${message}`);
|
|
16323
|
+
else
|
|
16324
|
+
out.issues.push(`${label} ${field}: ${message}`);
|
|
16325
|
+
};
|
|
16326
|
+
for (const key of Object.keys(entry))
|
|
16327
|
+
if (!KNOWN_FIELDS.has(key))
|
|
16328
|
+
problem(key, "unknown field, ignored");
|
|
16329
|
+
const productionBranch = branchName(entry.productionBranch);
|
|
16330
|
+
const integrationBranch = branchName(entry.integrationBranch);
|
|
16331
|
+
if (!productionBranch)
|
|
16332
|
+
problem("productionBranch", "missing or not a branch name");
|
|
16333
|
+
if (!integrationBranch)
|
|
16334
|
+
problem("integrationBranch", "missing or not a branch name");
|
|
16335
|
+
const optionalBranch = (field) => {
|
|
16336
|
+
if (entry[field] === undefined)
|
|
16337
|
+
return null;
|
|
16338
|
+
const value = branchName(entry[field]);
|
|
16339
|
+
if (!value)
|
|
16340
|
+
problem(field, "not a branch name; using the integration branch");
|
|
16341
|
+
return value;
|
|
16342
|
+
};
|
|
16343
|
+
const baseBranch = optionalBranch("baseBranch");
|
|
16344
|
+
const pullRequestTarget = optionalBranch("pullRequestTarget");
|
|
16345
|
+
let mergeBackBranches = [];
|
|
16346
|
+
if (entry.mergeBackBranches !== undefined) {
|
|
16347
|
+
const list = Array.isArray(entry.mergeBackBranches) ? entry.mergeBackBranches.map(branchName) : [null];
|
|
16348
|
+
if (list.some((item) => item === null))
|
|
16349
|
+
problem("mergeBackBranches", "must be a list of branch names; ignored");
|
|
16350
|
+
else
|
|
16351
|
+
mergeBackBranches = [...new Set(list)];
|
|
16352
|
+
}
|
|
16353
|
+
const naming = {};
|
|
16354
|
+
if (entry.naming !== undefined) {
|
|
16355
|
+
if (!isRecord3(entry.naming))
|
|
16356
|
+
problem("naming", "not an object; ignored");
|
|
16357
|
+
else
|
|
16358
|
+
for (const kind of ["feature", "release", "hotfix"]) {
|
|
16359
|
+
const template = entry.naming[kind];
|
|
16360
|
+
if (template === undefined)
|
|
16361
|
+
continue;
|
|
16362
|
+
if (typeof template !== "string" || !template.trim())
|
|
16363
|
+
problem(`naming.${kind}`, "not a template string; ignored");
|
|
16364
|
+
else if (!literalOf(template))
|
|
16365
|
+
problem(`naming.${kind}`, "needs literal text besides placeholders; ignored");
|
|
16366
|
+
else
|
|
16367
|
+
naming[kind] = template.trim();
|
|
16368
|
+
}
|
|
16369
|
+
}
|
|
16370
|
+
if (!productionBranch || !integrationBranch) {
|
|
16371
|
+
out.issues.push(`${label} was skipped: it needs a productionBranch and integrationBranch`);
|
|
16372
|
+
continue;
|
|
16373
|
+
}
|
|
16374
|
+
out.tracks.push({
|
|
16375
|
+
name,
|
|
16376
|
+
productionBranch,
|
|
16377
|
+
integrationBranch,
|
|
16378
|
+
baseBranch: baseBranch ?? integrationBranch,
|
|
16379
|
+
pullRequestTarget: pullRequestTarget ?? integrationBranch,
|
|
16380
|
+
mergeBackBranches,
|
|
16381
|
+
naming
|
|
16382
|
+
});
|
|
16383
|
+
}
|
|
16384
|
+
out.protectedBranches = [...protectedNames];
|
|
16385
|
+
if (fatal.length)
|
|
16386
|
+
out.error = `workspace releaseTracks cannot be read by this Workit (${fatal.join("; ")}); upgrade Workit or fix the track`;
|
|
16387
|
+
return out;
|
|
16388
|
+
}
|
|
16389
|
+
function workspaceReleaseTracks(cwd) {
|
|
16390
|
+
const raw = resolveRuntimeReleaseTracks(cwd);
|
|
16391
|
+
return { workspace: raw?.workspace ?? null, ...readReleaseTracks(raw?.releaseTracks) };
|
|
16392
|
+
}
|
|
16393
|
+
var ReleaseTrackError, KNOWN_FIELDS, BRANCH_FIELDS, PLACEHOLDER, HAS_PLACEHOLDER, isRecord3 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), branchName = (value) => typeof value === "string" && value.trim() && !value.trim().startsWith("-") ? value.trim() : null, namedBranches = (entry) => [
|
|
16394
|
+
...BRANCH_FIELDS.map((field) => branchName(entry[field])),
|
|
16395
|
+
...Array.isArray(entry.mergeBackBranches) ? entry.mergeBackBranches.map(branchName) : []
|
|
16396
|
+
].filter((name) => name !== null), literalOf = (template) => template.replace(PLACEHOLDER, "").replace(/[*/]/gu, "").trim(), trackBranches = (tracks) => [
|
|
16397
|
+
...new Set(tracks.flatMap((track) => [
|
|
16398
|
+
track.productionBranch,
|
|
16399
|
+
track.integrationBranch,
|
|
16400
|
+
track.baseBranch,
|
|
16401
|
+
track.pullRequestTarget,
|
|
16402
|
+
...track.mergeBackBranches
|
|
16403
|
+
]))
|
|
16404
|
+
], namingGlob = (template) => HAS_PLACEHOLDER.test(template) ? template.replace(PLACEHOLDER, "*") : `${template.replace(/\/?\*?$/u, "")}/*`, memo3;
|
|
16405
|
+
var init_release_tracks = __esm(() => {
|
|
16406
|
+
init_rev();
|
|
16407
|
+
init_config();
|
|
16408
|
+
init_workspaces();
|
|
16409
|
+
ReleaseTrackError = class ReleaseTrackError extends Error {
|
|
16410
|
+
};
|
|
16411
|
+
KNOWN_FIELDS = new Set([
|
|
16412
|
+
"strategy",
|
|
16413
|
+
"productionBranch",
|
|
16414
|
+
"integrationBranch",
|
|
16415
|
+
"naming",
|
|
16416
|
+
"baseBranch",
|
|
16417
|
+
"mergeBackBranches",
|
|
16418
|
+
"pullRequestTarget",
|
|
16419
|
+
"tagNamespace",
|
|
16420
|
+
"versionSource",
|
|
16421
|
+
"requiredChecks",
|
|
16422
|
+
"critical"
|
|
16423
|
+
]);
|
|
16424
|
+
BRANCH_FIELDS = ["productionBranch", "integrationBranch", "baseBranch", "pullRequestTarget"];
|
|
16425
|
+
PLACEHOLDER = /\{[^}]*\}/gu;
|
|
16426
|
+
HAS_PLACEHOLDER = /\{[^}]*\}/u;
|
|
16427
|
+
memo3 = new Map;
|
|
16428
|
+
});
|
|
16429
|
+
|
|
16228
16430
|
// packages/workit-core/src/core/vcs-config.ts
|
|
16229
16431
|
var init_vcs_config = __esm(() => {
|
|
16230
16432
|
init_config();
|
|
16231
16433
|
init_workspaces();
|
|
16232
|
-
|
|
16434
|
+
init_release_tracks();
|
|
16233
16435
|
});
|
|
16234
16436
|
|
|
16235
16437
|
// packages/workit-core/src/core/branch.ts
|
|
@@ -16238,14 +16440,37 @@ function effectiveWorkspacePolicy(workspaceRoot, kind, profileName) {
|
|
|
16238
16440
|
const selected = resolveRuntimeWorkspacePolicy(workspaceRoot, kind, profileName?.trim() || process.env.WORKFLOW_PROFILE?.trim() || undefined);
|
|
16239
16441
|
const config = readConfig();
|
|
16240
16442
|
return kind === "branch" ? {
|
|
16241
|
-
branchPolicy: resolveBranchPolicy(config, selected.policy ? { branchPolicy: selected.policy } : null),
|
|
16443
|
+
branchPolicy: withReleaseTracks(workspaceRoot, resolveBranchPolicy(config, selected.policy ? { branchPolicy: selected.policy } : null)),
|
|
16242
16444
|
provenance: { branchPolicy: selected.source }
|
|
16243
16445
|
} : {
|
|
16244
16446
|
commitPolicy: resolveCommitPolicy(config, selected.policy ? { commitPolicy: selected.policy } : null),
|
|
16245
16447
|
provenance: { commitPolicy: selected.source }
|
|
16246
16448
|
};
|
|
16247
16449
|
}
|
|
16248
|
-
var
|
|
16450
|
+
var withReleaseTracks = (workspaceRoot, policy) => {
|
|
16451
|
+
const read = workspaceReleaseTracks(workspaceRoot);
|
|
16452
|
+
if (read.error)
|
|
16453
|
+
throw new ReleaseTrackError(read.error);
|
|
16454
|
+
if (read.tracks.length === 0 && read.protectedBranches.length === 0)
|
|
16455
|
+
return policy;
|
|
16456
|
+
const known = new Set(policy.allowed.map((pattern) => pattern.source));
|
|
16457
|
+
const allowed = [...policy.allowed];
|
|
16458
|
+
for (const glob of read.tracks.flatMap((track) => Object.values(track.naming).map(namingGlob))) {
|
|
16459
|
+
const pattern = branchGlobPattern(glob);
|
|
16460
|
+
if (!known.has(pattern.source)) {
|
|
16461
|
+
known.add(pattern.source);
|
|
16462
|
+
allowed.push(pattern);
|
|
16463
|
+
}
|
|
16464
|
+
}
|
|
16465
|
+
return {
|
|
16466
|
+
...policy,
|
|
16467
|
+
allowed,
|
|
16468
|
+
protected: new Set([
|
|
16469
|
+
...policy.protected,
|
|
16470
|
+
...[...trackBranches(read.tracks), ...read.protectedBranches].map((name) => name.toLowerCase())
|
|
16471
|
+
])
|
|
16472
|
+
};
|
|
16473
|
+
}, validateBranchNamePolicy = (name, policy, source) => {
|
|
16249
16474
|
const allowed = policy.allowed.map((pattern) => `/${pattern.source}/${pattern.flags}`);
|
|
16250
16475
|
if (policy.protected.has(name.toLowerCase())) {
|
|
16251
16476
|
const correction = `choose a non-protected branch matching one of: ${allowed.join(", ")}`;
|
|
@@ -16305,6 +16530,7 @@ var init_branch = __esm(() => {
|
|
|
16305
16530
|
init_config();
|
|
16306
16531
|
init_workspaces();
|
|
16307
16532
|
init_vcs_config();
|
|
16533
|
+
init_release_tracks();
|
|
16308
16534
|
});
|
|
16309
16535
|
|
|
16310
16536
|
// packages/workit-core/src/core/route-intent.ts
|
|
@@ -16598,7 +16824,7 @@ var init_write_gate = __esm(() => {
|
|
|
16598
16824
|
// packages/workit-core/src/hooks/hosts/fields.ts
|
|
16599
16825
|
import { existsSync as existsSync6, realpathSync as realpathSync6, statSync as statSync2 } from "node:fs";
|
|
16600
16826
|
import path17 from "node:path";
|
|
16601
|
-
var
|
|
16827
|
+
var isRecord4 = (value) => value !== null && typeof value === "object" && !Array.isArray(value), nonEmpty2 = (value) => typeof value === "string" && value.trim() !== "", optionalText = (value) => typeof value === "string" ? value : null, existingDirectory = (value) => {
|
|
16602
16828
|
if (!nonEmpty2(value) || !path17.isAbsolute(value) || !existsSync6(value))
|
|
16603
16829
|
return null;
|
|
16604
16830
|
try {
|
|
@@ -16625,7 +16851,7 @@ var isRecord3 = (value) => value !== null && typeof value === "object" && !Array
|
|
|
16625
16851
|
const joined = argv.map(quoteArg).join(" ");
|
|
16626
16852
|
return nonEmpty2(joined) ? joined : null;
|
|
16627
16853
|
}, WRITE_TOOLS, isWriteTool = (name) => typeof name === "string" && WRITE_TOOLS.has(name.toLowerCase().replace(/[_-]/g, "")), PATH_KEYS, writePaths = (input) => {
|
|
16628
|
-
if (!
|
|
16854
|
+
if (!isRecord4(input))
|
|
16629
16855
|
return [];
|
|
16630
16856
|
const paths = PATH_KEYS.map((key) => input[key]).filter(nonEmpty2);
|
|
16631
16857
|
for (const value of Object.values(input))
|
|
@@ -16757,7 +16983,7 @@ var init_handle = __esm(() => {
|
|
|
16757
16983
|
});
|
|
16758
16984
|
|
|
16759
16985
|
// packages/workit-core/src/hooks/hosts/claude-code.ts
|
|
16760
|
-
var CLAUDE_CODE_DESCRIPTOR, EVENTS, SOURCES, SHELL_TOOLS, toolCommand = (value) =>
|
|
16986
|
+
var CLAUDE_CODE_DESCRIPTOR, EVENTS, SOURCES, SHELL_TOOLS, toolCommand = (value) => isRecord4(value.tool_input) ? commandText(value.tool_input.command) : null, eventOf = (name, value) => {
|
|
16761
16987
|
const toolUseId = optionalText(value.tool_use_id);
|
|
16762
16988
|
switch (name) {
|
|
16763
16989
|
case "SessionStart":
|
|
@@ -16786,7 +17012,7 @@ var CLAUDE_CODE_DESCRIPTOR, EVENTS, SOURCES, SHELL_TOOLS, toolCommand = (value)
|
|
|
16786
17012
|
const command = toolCommand(value);
|
|
16787
17013
|
if (!SHELL_TOOLS.has(String(value.tool_name)) || !command)
|
|
16788
17014
|
return { ok: false, error: "only shell PostToolUse is mapped" };
|
|
16789
|
-
const response =
|
|
17015
|
+
const response = isRecord4(value.tool_response) ? value.tool_response : {};
|
|
16790
17016
|
return {
|
|
16791
17017
|
ok: true,
|
|
16792
17018
|
event: {
|
|
@@ -16961,14 +17187,14 @@ var init_claude_code = __esm(() => {
|
|
|
16961
17187
|
claudeCodeAdapter = {
|
|
16962
17188
|
descriptor: CLAUDE_CODE_DESCRIPTOR,
|
|
16963
17189
|
parse(raw) {
|
|
16964
|
-
const native =
|
|
17190
|
+
const native = isRecord4(raw) && Object.hasOwn(EVENTS, String(raw.hook_event_name)) ? raw.hook_event_name : null;
|
|
16965
17191
|
const fail = (error) => ({
|
|
16966
17192
|
ok: false,
|
|
16967
17193
|
error,
|
|
16968
17194
|
native,
|
|
16969
17195
|
event: native ? EVENTS[native] : null
|
|
16970
17196
|
});
|
|
16971
|
-
if (!
|
|
17197
|
+
if (!isRecord4(raw) || !native)
|
|
16972
17198
|
return fail("hook_event_name is required");
|
|
16973
17199
|
if (!nonEmpty2(raw.session_id))
|
|
16974
17200
|
return fail("session_id is required");
|
|
@@ -17005,7 +17231,7 @@ function detectCodexSurface(env) {
|
|
|
17005
17231
|
return env.CODEX_INTERNAL_ORIGINATOR_OVERRIDE === "Codex Desktop" || Boolean(env.CODEX_ELECTRON_RESOURCES_PATH) ? "codex_desktop" : "codex_cli";
|
|
17006
17232
|
}
|
|
17007
17233
|
var undocumented, CODEX_DESCRIPTOR, EVENTS2, SHELL_TOOLS2, isShellTool = (name) => SHELL_TOOLS2.has(String(name).toLowerCase()), SOURCES2, parseCodexHookInput = (value) => {
|
|
17008
|
-
if (!
|
|
17234
|
+
if (!isRecord4(value) || !Object.hasOwn(EVENTS2, String(value.hook_event_name)))
|
|
17009
17235
|
return { ok: false, error: "hook_event_name is required" };
|
|
17010
17236
|
const event = value.hook_event_name;
|
|
17011
17237
|
const cwd = existingDirectory(value.cwd);
|
|
@@ -17013,7 +17239,7 @@ var undocumented, CODEX_DESCRIPTOR, EVENTS2, SHELL_TOOLS2, isShellTool = (name)
|
|
|
17013
17239
|
return { ok: false, error: "cwd must be an existing absolute directory" };
|
|
17014
17240
|
if (event === "PreToolUse" && !nonEmpty2(value.tool_name))
|
|
17015
17241
|
return { ok: false, error: "tool_name is required" };
|
|
17016
|
-
const command =
|
|
17242
|
+
const command = isRecord4(value.tool_input) ? commandText(value.tool_input.command) : null;
|
|
17017
17243
|
if (event === "PreToolUse" && isShellTool(value.tool_name) && !command)
|
|
17018
17244
|
return { ok: false, error: "tool_input.command is required for shell tools" };
|
|
17019
17245
|
if (event === "SubagentStart" && !nonEmpty2(value.agent_id))
|
|
@@ -17200,7 +17426,7 @@ var init_codex = __esm(() => {
|
|
|
17200
17426
|
const host = detectCodexSurface(env);
|
|
17201
17427
|
const parsed = parseCodexHookInput(raw);
|
|
17202
17428
|
if (!parsed.ok) {
|
|
17203
|
-
const native =
|
|
17429
|
+
const native = isRecord4(raw) && Object.hasOwn(EVENTS2, String(raw.hook_event_name)) ? raw.hook_event_name : null;
|
|
17204
17430
|
return { ok: false, error: parsed.error, native, event: native ? EVENTS2[native] : null };
|
|
17205
17431
|
}
|
|
17206
17432
|
const input = parsed.data;
|
|
@@ -17230,7 +17456,7 @@ var init_codex = __esm(() => {
|
|
|
17230
17456
|
// packages/workit-core/src/hooks/hosts/cursor.ts
|
|
17231
17457
|
import path18 from "node:path";
|
|
17232
17458
|
var undocumented2, none, CURSOR_DESCRIPTOR, EVENTS3, parseCursorHookInput = (value) => {
|
|
17233
|
-
if (!
|
|
17459
|
+
if (!isRecord4(value) || !Object.hasOwn(EVENTS3, String(value.hook_event_name)))
|
|
17234
17460
|
return { ok: false, error: "hook_event_name is required" };
|
|
17235
17461
|
const roots = value.workspace_roots;
|
|
17236
17462
|
if (!Array.isArray(roots) || roots.length === 0 || !roots.every(nonEmpty2))
|
|
@@ -17442,7 +17668,7 @@ var init_cursor = __esm(() => {
|
|
|
17442
17668
|
parse(raw) {
|
|
17443
17669
|
const parsed = parseCursorHookInput(raw);
|
|
17444
17670
|
if (!parsed.ok) {
|
|
17445
|
-
const native =
|
|
17671
|
+
const native = isRecord4(raw) && Object.hasOwn(EVENTS3, String(raw.hook_event_name)) ? raw.hook_event_name : null;
|
|
17446
17672
|
return { ok: false, error: parsed.error, native, event: native ? EVENTS3[native] : null };
|
|
17447
17673
|
}
|
|
17448
17674
|
const input = parsed.data;
|