@brainervirus/workit-pi 1.3.0 → 1.3.2
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/workit.js +93 -42
- package/package.json +1 -1
package/dist/workit.js
CHANGED
|
@@ -8302,7 +8302,47 @@ function operationJsonSchema(family) {
|
|
|
8302
8302
|
return toJSONSchema(operationSchemas[family], { target: "draft-2020-12" });
|
|
8303
8303
|
}
|
|
8304
8304
|
var OPERATION_SCHEMA_DEPTH = 1;
|
|
8305
|
-
var
|
|
8305
|
+
var schemaShapeDescription = (value, depth = 0) => {
|
|
8306
|
+
if (!value || typeof value !== "object")
|
|
8307
|
+
return "value";
|
|
8308
|
+
const schema = value;
|
|
8309
|
+
if (Array.isArray(schema.oneOf) || Array.isArray(schema.anyOf)) {
|
|
8310
|
+
const options = Array.isArray(schema.oneOf) ? schema.oneOf : schema.anyOf;
|
|
8311
|
+
return `(${options.map((option) => schemaShapeDescription(option, depth)).join("|")})`;
|
|
8312
|
+
}
|
|
8313
|
+
if (schema.const !== undefined)
|
|
8314
|
+
return `=${JSON.stringify(schema.const)}`;
|
|
8315
|
+
if (Array.isArray(schema.enum))
|
|
8316
|
+
return `[${schema.enum.map(String).join("|")}]`;
|
|
8317
|
+
const type = Array.isArray(schema.type) ? schema.type.join("/") : schema.type;
|
|
8318
|
+
if (type === "array")
|
|
8319
|
+
return `arr<${schemaShapeDescription(schema.items, depth)}>`;
|
|
8320
|
+
if (type === "object" && schema.properties && typeof schema.properties === "object") {
|
|
8321
|
+
if (depth >= 2)
|
|
8322
|
+
return "obj";
|
|
8323
|
+
const required = new Set(Array.isArray(schema.required) ? schema.required : []);
|
|
8324
|
+
const properties = schema.properties;
|
|
8325
|
+
const fields = Object.entries(properties).map(([name, child]) => `${name}${required.has(name) ? "!" : ""}:${schemaShapeDescription(child, depth + 1)}`);
|
|
8326
|
+
return `obj{${fields.join(",")}}`;
|
|
8327
|
+
}
|
|
8328
|
+
if (typeof type !== "string")
|
|
8329
|
+
return "?";
|
|
8330
|
+
return type.split("/").map((part) => ({ string: "str", boolean: "bool", number: "num", null: "null" })[part] ?? part).join("|");
|
|
8331
|
+
};
|
|
8332
|
+
var canonicalFieldsDescription = (value) => {
|
|
8333
|
+
if (Array.isArray(value))
|
|
8334
|
+
return `Canonical object fields: ${value.join(", ")}. Workit validates the complete nested value.`;
|
|
8335
|
+
const isZodType = (schema) => ("_zod" in schema) && typeof schema._zod === "object";
|
|
8336
|
+
const schema = isZodType(value) ? toJSONSchema(value, { target: "draft-2020-12" }) : value;
|
|
8337
|
+
if (!schema.properties || typeof schema.properties !== "object") {
|
|
8338
|
+
const variants = Array.isArray(schema.oneOf) ? schema.oneOf : Array.isArray(schema.anyOf) ? schema.anyOf : null;
|
|
8339
|
+
return variants ? `Canonical shapes: ${variants.map((variant) => schemaShapeDescription(variant)).join(" | ")}. Full nested value is validated.` : "Canonical nested value; Workit validates the complete value.";
|
|
8340
|
+
}
|
|
8341
|
+
const properties = schema.properties;
|
|
8342
|
+
const required = new Set(Array.isArray(schema.required) ? schema.required : []);
|
|
8343
|
+
const fields = Object.entries(properties).map(([name, child]) => `${name}${required.has(name) ? "!" : ""}:${schemaShapeDescription(child)}`);
|
|
8344
|
+
return `Fields (! required): ${fields.join(", ")}. Full nested value is validated.`;
|
|
8345
|
+
};
|
|
8306
8346
|
function boundedOperationJsonSchema(family, maxDepth = OPERATION_SCHEMA_DEPTH, stringifiedObjects = false) {
|
|
8307
8347
|
const tolerate = (projected) => {
|
|
8308
8348
|
if (!stringifiedObjects)
|
|
@@ -8326,9 +8366,10 @@ function boundedOperationJsonSchema(family, maxDepth = OPERATION_SCHEMA_DEPTH, s
|
|
|
8326
8366
|
return node;
|
|
8327
8367
|
const record = node;
|
|
8328
8368
|
if (record.properties && typeof record.properties === "object") {
|
|
8329
|
-
const
|
|
8369
|
+
const properties = record.properties;
|
|
8370
|
+
const fields = Object.keys(properties);
|
|
8330
8371
|
if (currentDepth >= maxDepth || fields.length === 0) {
|
|
8331
|
-
const description = stringifiedObjects ? `${canonicalFieldsDescription(
|
|
8372
|
+
const description = stringifiedObjects ? `${canonicalFieldsDescription(record)} A JSON-encoded string is also accepted.` : canonicalFieldsDescription(record);
|
|
8332
8373
|
return tolerate({ type: "object", description });
|
|
8333
8374
|
}
|
|
8334
8375
|
return tolerate({
|
|
@@ -10605,6 +10646,28 @@ var canonicalGlob = (glob) => {
|
|
|
10605
10646
|
const real = realpathOf(prefix.replace(/\/+$/, "") || "/");
|
|
10606
10647
|
return real + (prefix.endsWith("/") ? "/" : "") + rest;
|
|
10607
10648
|
};
|
|
10649
|
+
var globSpecificity = (glob) => glob.replaceAll("\\", "/").split("/").filter((segment) => segment.length > 0 && !/[*?[\]{]/.test(segment)).length;
|
|
10650
|
+
var selectWorkspaceMatch = (matches, cwd, workspaceName) => {
|
|
10651
|
+
if (workspaceName !== undefined) {
|
|
10652
|
+
const named = matches.filter((entry) => entry.name === workspaceName);
|
|
10653
|
+
if (named.length === 1)
|
|
10654
|
+
return named[0];
|
|
10655
|
+
if (named.length > 1)
|
|
10656
|
+
throw new Error(`ambiguous workspace ${JSON.stringify(workspaceName)} for ${cwd}`);
|
|
10657
|
+
if (matches.length > 0) {
|
|
10658
|
+
throw new Error(`workspace ${JSON.stringify(workspaceName)} does not match ${cwd}; matching choices: ${matches.map((entry) => entry.name).join(", ")}`);
|
|
10659
|
+
}
|
|
10660
|
+
throw new Error(`workspace ${JSON.stringify(workspaceName)} does not match ${cwd}`);
|
|
10661
|
+
}
|
|
10662
|
+
if (matches.length < 2)
|
|
10663
|
+
return matches[0];
|
|
10664
|
+
const highestSpecificity = Math.max(...matches.map((entry) => globSpecificity(entry.glob)));
|
|
10665
|
+
const mostSpecific = matches.filter((entry) => globSpecificity(entry.glob) === highestSpecificity);
|
|
10666
|
+
if (mostSpecific.length > 1) {
|
|
10667
|
+
throw new Error(`ambiguous workspace for ${cwd}; choose one of: ${mostSpecific.map((entry) => entry.name).join(", ")}`);
|
|
10668
|
+
}
|
|
10669
|
+
return mostSpecific[0];
|
|
10670
|
+
};
|
|
10608
10671
|
var resolveWorkspaceFrom = (cwd, dir, workspaceName) => {
|
|
10609
10672
|
const result = readWorkspacesResult(dir);
|
|
10610
10673
|
if (result.status === "malformed" || result.status === "invalid")
|
|
@@ -10624,20 +10687,7 @@ var resolveWorkspaceFrom = (cwd, dir, workspaceName) => {
|
|
|
10624
10687
|
if (matched)
|
|
10625
10688
|
matches.push(ws);
|
|
10626
10689
|
}
|
|
10627
|
-
|
|
10628
|
-
const selected = matches.find((ws) => ws.name === workspaceName);
|
|
10629
|
-
if (!selected && matches.length > 0) {
|
|
10630
|
-
const matchingNames = matches.map((ws) => ws.name);
|
|
10631
|
-
throw new Error(`workspace ${JSON.stringify(workspaceName)} does not match ${cwd}; matching choices: ${matchingNames.join(", ")}`);
|
|
10632
|
-
}
|
|
10633
|
-
if (selected)
|
|
10634
|
-
return selected;
|
|
10635
|
-
throw new Error(`workspace ${JSON.stringify(workspaceName)} does not match ${cwd}`);
|
|
10636
|
-
}
|
|
10637
|
-
if (matches.length > 1) {
|
|
10638
|
-
throw new Error(`ambiguous workspace for ${cwd}; choose one of: ${matches.map((ws) => ws.name).join(", ")}`);
|
|
10639
|
-
}
|
|
10640
|
-
return matches[0] ?? null;
|
|
10690
|
+
return selectWorkspaceMatch(matches, cwd, workspaceName) ?? null;
|
|
10641
10691
|
};
|
|
10642
10692
|
var runtimeWorkspacePolicySchema = (kind) => {
|
|
10643
10693
|
const key = kind === "branch" ? "branchPolicy" : kind === "commit" ? "commitPolicy" : "vcs";
|
|
@@ -10694,21 +10744,7 @@ var resolveRuntimeWorkspaceCandidate = (cwd, kind) => {
|
|
|
10694
10744
|
return targets.some((target) => matchWorkspace(glob, target) || canonical !== glob && matchWorkspace(canonical, target));
|
|
10695
10745
|
});
|
|
10696
10746
|
const workspaceName = process.env.WORKFLOW_WORKSPACE_NAME?.trim() || undefined;
|
|
10697
|
-
|
|
10698
|
-
if (workspaceName) {
|
|
10699
|
-
const named = matches.filter((entry) => entry.name === workspaceName);
|
|
10700
|
-
if (named.length === 1)
|
|
10701
|
-
selected = named[0];
|
|
10702
|
-
else if (named.length > 1)
|
|
10703
|
-
throw new Error(`ambiguous workspace ${JSON.stringify(workspaceName)} for ${cwd}`);
|
|
10704
|
-
else if (matches.length)
|
|
10705
|
-
throw new Error(`workspace ${JSON.stringify(workspaceName)} does not match ${cwd}; matching choices: ${matches.map((entry) => entry.name).join(", ")}`);
|
|
10706
|
-
else
|
|
10707
|
-
throw new Error(`workspace ${JSON.stringify(workspaceName)} does not match ${cwd}`);
|
|
10708
|
-
} else if (matches.length > 1)
|
|
10709
|
-
throw new Error(`ambiguous workspace for ${cwd}; choose one of: ${matches.map((entry) => entry.name).join(", ")}`);
|
|
10710
|
-
else
|
|
10711
|
-
selected = matches[0];
|
|
10747
|
+
const selected = selectWorkspaceMatch(matches, cwd, workspaceName);
|
|
10712
10748
|
if (!selected)
|
|
10713
10749
|
return null;
|
|
10714
10750
|
const policy = runtimeWorkspacePolicySchema(kind).safeParse(selected);
|
|
@@ -11470,7 +11506,7 @@ var branchSetup = ({
|
|
|
11470
11506
|
const dirty = Boolean(gitContext(cwd).status_short.trim());
|
|
11471
11507
|
if (classifyBranchDirt(cwd) === "stash-required" && stash !== "yes") {
|
|
11472
11508
|
return {
|
|
11473
|
-
error: "dirty working tree —
|
|
11509
|
+
error: "dirty working tree — obtain native host approval before stashing and setting up the branch",
|
|
11474
11510
|
phase: "preflight"
|
|
11475
11511
|
};
|
|
11476
11512
|
}
|
|
@@ -12893,6 +12929,15 @@ need zero Workit task, assessment, or writer calls. Use one compact tracked
|
|
|
12893
12929
|
record only when handoff, dependent steps, concurrent actors, or meaningful
|
|
12894
12930
|
decisions make continuity useful; similar titles alone never merge tasks.
|
|
12895
12931
|
|
|
12932
|
+
For a routine user-authorized branch or commit, prefer native host Git/shell
|
|
12933
|
+
tools from the outset when managed coordination or outcome reconciliation is
|
|
12934
|
+
not needed. Inspect the actual target checkout and its configured conventions;
|
|
12935
|
+
use Workit's read-only context/policy tools when needed. Do not start a task,
|
|
12936
|
+
acquire a writer, or mint a decision receipt solely for a native Git action.
|
|
12937
|
+
Native permissions still apply. Never switch execution paths to evade a denial
|
|
12938
|
+
or repeat an uncertain managed effect. A local-commit endpoint does not imply
|
|
12939
|
+
PR readiness, a fresh review, or post-commit assessment/closure paperwork.
|
|
12940
|
+
|
|
12896
12941
|
For tracked work, inspect its current state and use the shared operations for
|
|
12897
12942
|
task, policy, evidence, finding, decision, worker, writer, and state changes.
|
|
12898
12943
|
Start a record once for an explicit tracked objective; assess or reassess only
|
|
@@ -12914,6 +12959,11 @@ Preserve uncertain external outcomes and reconcile repository/provider state
|
|
|
12914
12959
|
before retrying. Internal reservations prevent duplicate or ambiguous effects;
|
|
12915
12960
|
they are not permission tickets for every edit.
|
|
12916
12961
|
|
|
12962
|
+
On OpenCode V1 and V2, use native host tools for external mutations. Workit
|
|
12963
|
+
provides read-only workit_context; it has no managed external-action executor.
|
|
12964
|
+
Do not create proposals or request Workit approvals merely to invoke native
|
|
12965
|
+
tools. Old uncertain managed effects still require evidence before any retry.
|
|
12966
|
+
|
|
12917
12967
|
Use host-native authorization through the host's supported path. A native
|
|
12918
12968
|
question receipt records an actual question interaction; it is not automatic
|
|
12919
12969
|
host permission. Record a meaningful user choice once with provenance when
|
|
@@ -13929,6 +13979,7 @@ function resolveRequirements(input) {
|
|
|
13929
13979
|
dependentAction: null,
|
|
13930
13980
|
acceptanceAllowed: false
|
|
13931
13981
|
}));
|
|
13982
|
+
const independentBehaviorReview = input.preferences?.thorough === true || input.assessment.consequences.some((consequence) => ["security", "data", "public_contract", "operations"].includes(consequence.area));
|
|
13932
13983
|
if (signals.behaviorChange.value === true)
|
|
13933
13984
|
requirements.push(requirement({
|
|
13934
13985
|
ruleId: "behavioral-verification",
|
|
@@ -13940,14 +13991,14 @@ function resolveRequirements(input) {
|
|
|
13940
13991
|
dependentAction: null,
|
|
13941
13992
|
acceptanceAllowed: false
|
|
13942
13993
|
}), requirement({
|
|
13943
|
-
ruleId: "fresh-context-review",
|
|
13994
|
+
ruleId: independentBehaviorReview ? "fresh-context-review" : "self-review",
|
|
13944
13995
|
dimension: "review",
|
|
13945
13996
|
scope,
|
|
13946
|
-
reason: "
|
|
13947
|
-
satisfaction: "A separate review context examines the current candidate and records its result.",
|
|
13997
|
+
reason: independentBehaviorReview ? "Consequential behavior or the thorough preference requires fresh-context review." : "Bounded behavior changes use self-review unless consequential risks or trusted rules require more.",
|
|
13998
|
+
satisfaction: independentBehaviorReview ? "A separate review context examines the current candidate and records its result." : "The lead reviews the resulting diff and records the relevant scope and checks.",
|
|
13948
13999
|
before: "close",
|
|
13949
14000
|
dependentAction: null,
|
|
13950
|
-
acceptanceAllowed:
|
|
14001
|
+
acceptanceAllowed: !independentBehaviorReview
|
|
13951
14002
|
}));
|
|
13952
14003
|
else if (signals.mechanicalLowRisk.value === true)
|
|
13953
14004
|
requirements.push(requirement({
|
|
@@ -17083,7 +17134,7 @@ var CHANGELOG_RULES = `- Use an [Unreleased] section.
|
|
|
17083
17134
|
- Entries should be human-readable and user-facing.
|
|
17084
17135
|
- Do not use raw commit messages as changelog bullets.
|
|
17085
17136
|
- MERGE into existing ### Category under [Unreleased] — never append a second ### Added / ### Fixed block.
|
|
17086
|
-
- Apply with the native
|
|
17137
|
+
- Apply with the host-native editor, preserving the repository changelog conventions.
|
|
17087
17138
|
- If Unreleased already has duplicate category headings, normalize_only first.`;
|
|
17088
17139
|
function changelogContext(root, range) {
|
|
17089
17140
|
const cwd = path15.resolve(repoRoot2(root));
|
|
@@ -17874,7 +17925,7 @@ async function postUpdate({
|
|
|
17874
17925
|
postedComment: true,
|
|
17875
17926
|
loggedMinutes: 0,
|
|
17876
17927
|
error: time.error,
|
|
17877
|
-
retry: "
|
|
17928
|
+
retry: "youtrack.time"
|
|
17878
17929
|
};
|
|
17879
17930
|
}
|
|
17880
17931
|
return { ok: true, issueId, postedComment: true, loggedMinutes: minutes };
|
|
@@ -17924,7 +17975,7 @@ async function postUpdate2(input, operations = defaultOperations) {
|
|
|
17924
17975
|
postedComment: false,
|
|
17925
17976
|
loggedMinutes: 0,
|
|
17926
17977
|
outcome: "not_applied",
|
|
17927
|
-
retry: "
|
|
17978
|
+
retry: "youtrack.update"
|
|
17928
17979
|
});
|
|
17929
17980
|
unwrap(comment);
|
|
17930
17981
|
} catch (error) {
|
|
@@ -17951,7 +18002,7 @@ async function postUpdate2(input, operations = defaultOperations) {
|
|
|
17951
18002
|
postedComment: true,
|
|
17952
18003
|
loggedMinutes: 0,
|
|
17953
18004
|
outcome: "not_applied",
|
|
17954
|
-
retry: "
|
|
18005
|
+
retry: "youtrack.time"
|
|
17955
18006
|
});
|
|
17956
18007
|
unwrap(time);
|
|
17957
18008
|
} catch (error) {
|
|
@@ -17978,7 +18029,7 @@ async function logTimeUpdate(input, operation = defaultOperations) {
|
|
|
17978
18029
|
issueId: input.issueId,
|
|
17979
18030
|
loggedMinutes: 0,
|
|
17980
18031
|
outcome: "not_applied",
|
|
17981
|
-
retry: "
|
|
18032
|
+
retry: "youtrack.time"
|
|
17982
18033
|
});
|
|
17983
18034
|
return ok(unwrap(value));
|
|
17984
18035
|
} catch (error) {
|