@brainervirus/workit-opencode 1.3.0 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/plugin.js +157 -98
  2. package/package.json +2 -2
package/dist/plugin.js CHANGED
@@ -8318,7 +8318,47 @@ function operationJsonSchema(family) {
8318
8318
  return toJSONSchema(operationSchemas[family], { target: "draft-2020-12" });
8319
8319
  }
8320
8320
  var OPERATION_SCHEMA_DEPTH = 1;
8321
- var canonicalFieldsDescription = (fields) => `Canonical object fields: ${fields.join(", ")}. Workit validates the complete nested value.`;
8321
+ var schemaShapeDescription = (value, depth = 0) => {
8322
+ if (!value || typeof value !== "object")
8323
+ return "value";
8324
+ const schema = value;
8325
+ if (Array.isArray(schema.oneOf) || Array.isArray(schema.anyOf)) {
8326
+ const options = Array.isArray(schema.oneOf) ? schema.oneOf : schema.anyOf;
8327
+ return `(${options.map((option) => schemaShapeDescription(option, depth)).join("|")})`;
8328
+ }
8329
+ if (schema.const !== undefined)
8330
+ return `=${JSON.stringify(schema.const)}`;
8331
+ if (Array.isArray(schema.enum))
8332
+ return `[${schema.enum.map(String).join("|")}]`;
8333
+ const type = Array.isArray(schema.type) ? schema.type.join("/") : schema.type;
8334
+ if (type === "array")
8335
+ return `arr<${schemaShapeDescription(schema.items, depth)}>`;
8336
+ if (type === "object" && schema.properties && typeof schema.properties === "object") {
8337
+ if (depth >= 2)
8338
+ return "obj";
8339
+ const required = new Set(Array.isArray(schema.required) ? schema.required : []);
8340
+ const properties = schema.properties;
8341
+ const fields = Object.entries(properties).map(([name, child]) => `${name}${required.has(name) ? "!" : ""}:${schemaShapeDescription(child, depth + 1)}`);
8342
+ return `obj{${fields.join(",")}}`;
8343
+ }
8344
+ if (typeof type !== "string")
8345
+ return "?";
8346
+ return type.split("/").map((part) => ({ string: "str", boolean: "bool", number: "num", null: "null" })[part] ?? part).join("|");
8347
+ };
8348
+ var canonicalFieldsDescription = (value) => {
8349
+ if (Array.isArray(value))
8350
+ return `Canonical object fields: ${value.join(", ")}. Workit validates the complete nested value.`;
8351
+ const isZodType = (schema) => ("_zod" in schema) && typeof schema._zod === "object";
8352
+ const schema = isZodType(value) ? toJSONSchema(value, { target: "draft-2020-12" }) : value;
8353
+ if (!schema.properties || typeof schema.properties !== "object") {
8354
+ const variants = Array.isArray(schema.oneOf) ? schema.oneOf : Array.isArray(schema.anyOf) ? schema.anyOf : null;
8355
+ return variants ? `Canonical shapes: ${variants.map((variant) => schemaShapeDescription(variant)).join(" | ")}. Full nested value is validated.` : "Canonical nested value; Workit validates the complete value.";
8356
+ }
8357
+ const properties = schema.properties;
8358
+ const required = new Set(Array.isArray(schema.required) ? schema.required : []);
8359
+ const fields = Object.entries(properties).map(([name, child]) => `${name}${required.has(name) ? "!" : ""}:${schemaShapeDescription(child)}`);
8360
+ return `Fields (! required): ${fields.join(", ")}. Full nested value is validated.`;
8361
+ };
8322
8362
  function boundedOperationJsonSchema(family, maxDepth = OPERATION_SCHEMA_DEPTH, stringifiedObjects = false) {
8323
8363
  const tolerate = (projected) => {
8324
8364
  if (!stringifiedObjects)
@@ -8342,9 +8382,10 @@ function boundedOperationJsonSchema(family, maxDepth = OPERATION_SCHEMA_DEPTH, s
8342
8382
  return node;
8343
8383
  const record = node;
8344
8384
  if (record.properties && typeof record.properties === "object") {
8345
- const fields = Object.keys(record.properties);
8385
+ const properties = record.properties;
8386
+ const fields = Object.keys(properties);
8346
8387
  if (currentDepth >= maxDepth || fields.length === 0) {
8347
- const description = stringifiedObjects ? `${canonicalFieldsDescription(fields)} A JSON-encoded string is also accepted.` : canonicalFieldsDescription(fields);
8388
+ const description = stringifiedObjects ? `${canonicalFieldsDescription(record)} A JSON-encoded string is also accepted.` : canonicalFieldsDescription(record);
8348
8389
  return tolerate({ type: "object", description });
8349
8390
  }
8350
8391
  return tolerate({
@@ -10650,6 +10691,28 @@ var canonicalGlob = (glob) => {
10650
10691
  const real = realpathOf(prefix.replace(/\/+$/, "") || "/");
10651
10692
  return real + (prefix.endsWith("/") ? "/" : "") + rest;
10652
10693
  };
10694
+ var globSpecificity = (glob) => glob.replaceAll("\\", "/").split("/").filter((segment) => segment.length > 0 && !/[*?[\]{]/.test(segment)).length;
10695
+ var selectWorkspaceMatch = (matches, cwd, workspaceName) => {
10696
+ if (workspaceName !== undefined) {
10697
+ const named = matches.filter((entry) => entry.name === workspaceName);
10698
+ if (named.length === 1)
10699
+ return named[0];
10700
+ if (named.length > 1)
10701
+ throw new Error(`ambiguous workspace ${JSON.stringify(workspaceName)} for ${cwd}`);
10702
+ if (matches.length > 0) {
10703
+ throw new Error(`workspace ${JSON.stringify(workspaceName)} does not match ${cwd}; matching choices: ${matches.map((entry) => entry.name).join(", ")}`);
10704
+ }
10705
+ throw new Error(`workspace ${JSON.stringify(workspaceName)} does not match ${cwd}`);
10706
+ }
10707
+ if (matches.length < 2)
10708
+ return matches[0];
10709
+ const highestSpecificity = Math.max(...matches.map((entry) => globSpecificity(entry.glob)));
10710
+ const mostSpecific = matches.filter((entry) => globSpecificity(entry.glob) === highestSpecificity);
10711
+ if (mostSpecific.length > 1) {
10712
+ throw new Error(`ambiguous workspace for ${cwd}; choose one of: ${mostSpecific.map((entry) => entry.name).join(", ")}`);
10713
+ }
10714
+ return mostSpecific[0];
10715
+ };
10653
10716
  var resolveWorkspaceFrom = (cwd, dir, workspaceName) => {
10654
10717
  const result = readWorkspacesResult(dir);
10655
10718
  if (result.status === "malformed" || result.status === "invalid")
@@ -10669,20 +10732,7 @@ var resolveWorkspaceFrom = (cwd, dir, workspaceName) => {
10669
10732
  if (matched)
10670
10733
  matches.push(ws);
10671
10734
  }
10672
- if (workspaceName !== undefined) {
10673
- const selected = matches.find((ws) => ws.name === workspaceName);
10674
- if (!selected && matches.length > 0) {
10675
- const matchingNames = matches.map((ws) => ws.name);
10676
- throw new Error(`workspace ${JSON.stringify(workspaceName)} does not match ${cwd}; matching choices: ${matchingNames.join(", ")}`);
10677
- }
10678
- if (selected)
10679
- return selected;
10680
- throw new Error(`workspace ${JSON.stringify(workspaceName)} does not match ${cwd}`);
10681
- }
10682
- if (matches.length > 1) {
10683
- throw new Error(`ambiguous workspace for ${cwd}; choose one of: ${matches.map((ws) => ws.name).join(", ")}`);
10684
- }
10685
- return matches[0] ?? null;
10735
+ return selectWorkspaceMatch(matches, cwd, workspaceName) ?? null;
10686
10736
  };
10687
10737
  var runtimeWorkspacePolicySchema = (kind) => {
10688
10738
  const key = kind === "branch" ? "branchPolicy" : kind === "commit" ? "commitPolicy" : "vcs";
@@ -10739,21 +10789,7 @@ var resolveRuntimeWorkspaceCandidate = (cwd, kind) => {
10739
10789
  return targets.some((target) => matchWorkspace(glob, target) || canonical !== glob && matchWorkspace(canonical, target));
10740
10790
  });
10741
10791
  const workspaceName = process.env.WORKFLOW_WORKSPACE_NAME?.trim() || undefined;
10742
- let selected;
10743
- if (workspaceName) {
10744
- const named = matches.filter((entry) => entry.name === workspaceName);
10745
- if (named.length === 1)
10746
- selected = named[0];
10747
- else if (named.length > 1)
10748
- throw new Error(`ambiguous workspace ${JSON.stringify(workspaceName)} for ${cwd}`);
10749
- else if (matches.length)
10750
- throw new Error(`workspace ${JSON.stringify(workspaceName)} does not match ${cwd}; matching choices: ${matches.map((entry) => entry.name).join(", ")}`);
10751
- else
10752
- throw new Error(`workspace ${JSON.stringify(workspaceName)} does not match ${cwd}`);
10753
- } else if (matches.length > 1)
10754
- throw new Error(`ambiguous workspace for ${cwd}; choose one of: ${matches.map((entry) => entry.name).join(", ")}`);
10755
- else
10756
- selected = matches[0];
10792
+ const selected = selectWorkspaceMatch(matches, cwd, workspaceName);
10757
10793
  if (!selected)
10758
10794
  return null;
10759
10795
  const policy = runtimeWorkspacePolicySchema(kind).safeParse(selected);
@@ -12941,6 +12977,15 @@ need zero Workit task, assessment, or writer calls. Use one compact tracked
12941
12977
  record only when handoff, dependent steps, concurrent actors, or meaningful
12942
12978
  decisions make continuity useful; similar titles alone never merge tasks.
12943
12979
 
12980
+ For a routine user-authorized branch or commit, prefer native host Git/shell
12981
+ tools from the outset when managed coordination or outcome reconciliation is
12982
+ not needed. Inspect the actual target checkout and its configured conventions;
12983
+ use Workit's read-only context/policy tools when needed. Do not start a task,
12984
+ acquire a writer, or mint a decision receipt solely for a native Git action.
12985
+ Native permissions still apply. Never switch execution paths to evade a denial
12986
+ or repeat an uncertain managed effect. A local-commit endpoint does not imply
12987
+ PR readiness, a fresh review, or post-commit assessment/closure paperwork.
12988
+
12944
12989
  For tracked work, inspect its current state and use the shared operations for
12945
12990
  task, policy, evidence, finding, decision, worker, writer, and state changes.
12946
12991
  Start a record once for an explicit tracked objective; assess or reassess only
@@ -13222,6 +13267,10 @@ var externalActionSchema = discriminatedUnion("operation", [
13222
13267
  }).strict()
13223
13268
  }).strict()
13224
13269
  ]);
13270
+ var externalActionJsonSchema = () => ({
13271
+ type: "object",
13272
+ ...toJSONSchema(externalActionSchema, { target: "draft-2020-12" })
13273
+ });
13225
13274
  var externalActionRequest = (value) => {
13226
13275
  const parsed = externalActionSchema.safeParse(value);
13227
13276
  return parsed.success ? success(null, null, parsed.data) : failure("invalid_input", "external action payload is invalid", {
@@ -13977,6 +14026,7 @@ function resolveRequirements(input) {
13977
14026
  dependentAction: null,
13978
14027
  acceptanceAllowed: false
13979
14028
  }));
14029
+ const independentBehaviorReview = input.preferences?.thorough === true || input.assessment.consequences.some((consequence) => ["security", "data", "public_contract", "operations"].includes(consequence.area));
13980
14030
  if (signals.behaviorChange.value === true)
13981
14031
  requirements.push(requirement({
13982
14032
  ruleId: "behavioral-verification",
@@ -13988,14 +14038,14 @@ function resolveRequirements(input) {
13988
14038
  dependentAction: null,
13989
14039
  acceptanceAllowed: false
13990
14040
  }), requirement({
13991
- ruleId: "fresh-context-review",
14041
+ ruleId: independentBehaviorReview ? "fresh-context-review" : "self-review",
13992
14042
  dimension: "review",
13993
14043
  scope,
13994
- reason: "A non-mechanical behavior change requires fresh-context review.",
13995
- satisfaction: "A separate review context examines the current candidate and records its result.",
14044
+ 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.",
14045
+ 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.",
13996
14046
  before: "close",
13997
14047
  dependentAction: null,
13998
- acceptanceAllowed: false
14048
+ acceptanceAllowed: !independentBehaviorReview
13999
14049
  }));
14000
14050
  else if (signals.mechanicalLowRisk.value === true)
14001
14051
  requirements.push(requirement({
@@ -34040,14 +34090,33 @@ class NativeReceiptStore {
34040
34090
  #observations = new WeakSet;
34041
34091
  #reservations = new WeakMap;
34042
34092
  #pending = new Map;
34093
+ #callSequences = new Map;
34094
+ #seenCalls = new Set;
34043
34095
  #now;
34096
+ #sequence = 0;
34044
34097
  constructor(options = {}) {
34045
34098
  this.#now = options.now ?? Date.now;
34046
34099
  }
34100
+ get sequence() {
34101
+ return this.#sequence;
34102
+ }
34103
+ callKey(sessionID, callID) {
34104
+ return `${sessionID.length}:${sessionID}${callID}`;
34105
+ }
34106
+ rememberSequence(key, sequence) {
34107
+ if (!this.#callSequences.has(key))
34108
+ this.#callSequences.set(key, sequence);
34109
+ }
34047
34110
  recordRequest(requestID, sessionID, callID, questions) {
34048
34111
  if (typeof requestID !== "string" || !requestID)
34049
34112
  return;
34050
- this.#pending.set(requestID, { sessionID, callID, questions });
34113
+ const key = this.callKey(sessionID, callID);
34114
+ let sequence = this.#callSequences.get(key);
34115
+ if (sequence === undefined) {
34116
+ sequence = ++this.#sequence;
34117
+ this.rememberSequence(key, sequence);
34118
+ }
34119
+ this.#pending.set(requestID, { sessionID, callID, questions, sequence });
34051
34120
  if (this.#pending.size > 16) {
34052
34121
  const oldest = this.#pending.keys().next();
34053
34122
  if (!oldest.done)
@@ -34064,9 +34133,9 @@ class NativeReceiptStore {
34064
34133
  return false;
34065
34134
  if (!Array.isArray(answers) || answers.length !== 1)
34066
34135
  return false;
34067
- return this.mint(pending.sessionID, pending.callID, pending.questions, answers);
34136
+ return this.mint(pending.sessionID, pending.callID, pending.questions, answers, pending.sequence);
34068
34137
  }
34069
- mint(sessionID, callID, questions, answers) {
34138
+ mint(sessionID, callID, questions, answers, sequence) {
34070
34139
  const answer = Array.isArray(answers) && answers.length === 1 && Array.isArray(answers[0]) && answers[0].length === 1 && typeof answers[0][0] === "string" ? answers[0][0] : undefined;
34071
34140
  if (typeof answer !== "string" || !answer.trim())
34072
34141
  return false;
@@ -34087,6 +34156,12 @@ class NativeReceiptStore {
34087
34156
  const decisionPurpose = typeof question.header === "string" ? question.header.match(/^Workit decision: (design|action|limitation|preference)$/)?.[1] : undefined;
34088
34157
  if (!decisionPurpose)
34089
34158
  return false;
34159
+ const key = this.callKey(sessionID, callID);
34160
+ if (this.#seenCalls.has(key))
34161
+ return true;
34162
+ const receiptSequence = sequence ?? this.#callSequences.get(key) ?? ++this.#sequence;
34163
+ this.rememberSequence(key, receiptSequence);
34164
+ this.#seenCalls.add(key);
34090
34165
  const content = decisionContent(decisionPurpose, typeof question.question === "string" ? question.question : "", options[0].description);
34091
34166
  const receipt = {
34092
34167
  sessionID,
@@ -34097,7 +34172,8 @@ class NativeReceiptStore {
34097
34172
  question: content.question,
34098
34173
  purpose,
34099
34174
  contentDigest: sha256(canonicalJson(content)),
34100
- recordedAt: this.#now()
34175
+ recordedAt: this.#now(),
34176
+ sequence: receiptSequence
34101
34177
  };
34102
34178
  const queue = this.#receipts.get(sessionID) ?? [];
34103
34179
  queue.push(receipt);
@@ -34201,7 +34277,7 @@ var boundedSchema = (schema, depth, field) => {
34201
34277
  key,
34202
34278
  depth >= MAX_OPERATION_OBJECT_DEPTH ? shallowSchema(child, `${field}.${key}`) : boundedSchema(child, depth + 1, `${field}.${key}`)
34203
34279
  ]));
34204
- const description = depth >= MAX_OPERATION_OBJECT_DEPTH ? canonicalFieldsDescription(Object.keys(canonicalShape)) : undefined;
34280
+ const description = depth >= MAX_OPERATION_OBJECT_DEPTH ? canonicalFieldsDescription(schema) : undefined;
34205
34281
  const object = tool.schema.object(shape).strict();
34206
34282
  return description ? object.describe(description) : object;
34207
34283
  }
@@ -34493,27 +34569,39 @@ var createWorkitTools = ({
34493
34569
  if (decision.purpose === "action" && decision.response === "approved") {
34494
34570
  const queue = actionProposals.get(context.sessionID) ?? [];
34495
34571
  const textMatches = queue.filter((pending) => pending.presented === decision.binding.presented && pending.approvedText === decision.binding.approvedContent);
34496
- if (textMatches.length > 1 && new Set(textMatches.map((pending) => pending.descriptor)).size > 1)
34497
- return output2(failure("invalid_input", "multiple action proposals match this approval; resolve the action again"));
34498
34572
  let bound = false;
34499
- const pending = textMatches[0];
34500
- if (pending) {
34573
+ const valid = [];
34574
+ const stale = new Set;
34575
+ let unresolved = false;
34576
+ for (const pending of textMatches) {
34501
34577
  const fresh = resolveExternalActionRequest(context.directory, pending.request);
34502
34578
  const freshDescriptor = fresh.ok ? externalActionDescriptor(pending.request.operation, fresh.data.descriptorPayload) : null;
34503
34579
  if (freshDescriptor === pending.descriptor) {
34504
- proposalToCommit = pending;
34505
- recordInput = {
34506
- ...recordInput,
34507
- binding: {
34508
- ...recordInput.binding,
34509
- approvedContent: pending.descriptor,
34510
- displayed: pending.approvedText
34511
- }
34512
- };
34513
- bound = true;
34580
+ valid.push(pending);
34581
+ if (observed.receipt.sequence <= pending.receiptSequence)
34582
+ unresolved = true;
34514
34583
  } else if (fresh.ok) {
34515
- actionProposals.set(context.sessionID, queue.filter((candidate) => candidate !== pending));
34516
- }
34584
+ stale.add(pending);
34585
+ } else
34586
+ unresolved = true;
34587
+ }
34588
+ if (stale.size)
34589
+ actionProposals.set(context.sessionID, queue.filter((candidate) => !stale.has(candidate)));
34590
+ const validDescriptors = new Set(valid.map((pending) => pending.descriptor));
34591
+ if (unresolved || validDescriptors.size > 1)
34592
+ return output2(failure("invalid_input", "matching action proposals are ambiguous or this receipt predates a matching proposal; resolve and ask again"));
34593
+ if (validDescriptors.size === 1) {
34594
+ const pending = valid[0];
34595
+ proposalToCommit = pending;
34596
+ recordInput = {
34597
+ ...recordInput,
34598
+ binding: {
34599
+ ...recordInput.binding,
34600
+ approvedContent: pending.descriptor,
34601
+ displayed: pending.approvedText
34602
+ }
34603
+ };
34604
+ bound = true;
34517
34605
  }
34518
34606
  if (!bound && !isSelfAuthorizingActionContent(decision.binding.approvedContent)) {
34519
34607
  return output2(failure("invalid_input", textMatches.length > 0 ? "repository state changed since the proposal; resolve the action again for a fresh proposal" : "no matching action proposal; resolve the action through the action tool first"));
@@ -34540,20 +34628,8 @@ var createWorkitTools = ({
34540
34628
  workit_external_action: tool({
34541
34629
  description: `Run one fixed optional action. ${externalActionHelp}`,
34542
34630
  args: {
34543
- operation: tool.schema.enum([
34544
- "git.branch_setup",
34545
- "git.commit",
34546
- "git.push",
34547
- "hosting.pull_request",
34548
- "hosting.merge",
34549
- "hosting.delete_branch",
34550
- "youtrack.update",
34551
- "youtrack.time",
34552
- "youtrack.meeting",
34553
- "changelog.apply",
34554
- "context.read"
34555
- ]),
34556
- payload: tool.schema.record(tool.schema.string(), tool.schema.any())
34631
+ operation: tool.schema.enum(externalActionSchema.options.map((variant) => variant.shape.operation.value)),
34632
+ payload: tool.schema.union(externalActionSchema.options.map((variant) => variant.shape.payload)).describe("Use the payload variant for the selected operation; Workit validates their exact pairing.")
34557
34633
  },
34558
34634
  execute: async (args, context) => {
34559
34635
  const parsed = externalActionRequest(args);
@@ -34687,7 +34763,8 @@ var createWorkitTools = ({
34687
34763
  descriptor,
34688
34764
  presented: proposal.presented,
34689
34765
  approvedText: proposal.approvedText,
34690
- request: resolved.data.request
34766
+ request: resolved.data.request,
34767
+ receiptSequence: receipts.sequence
34691
34768
  };
34692
34769
  if (!existing) {
34693
34770
  pending.push(open);
@@ -35259,19 +35336,6 @@ var objectSchema = (properties, required) => ({
35259
35336
  required,
35260
35337
  additionalProperties: false
35261
35338
  });
35262
- var WORKIT_EXTERNAL_ACTION_OPERATIONS = [
35263
- "git.branch_setup",
35264
- "git.commit",
35265
- "git.push",
35266
- "hosting.pull_request",
35267
- "hosting.merge",
35268
- "hosting.delete_branch",
35269
- "youtrack.update",
35270
- "youtrack.time",
35271
- "youtrack.meeting",
35272
- "changelog.apply",
35273
- "context.read"
35274
- ];
35275
35339
  var familyTools = OPERATION_FAMILIES.map((family) => ({
35276
35340
  name: `workit_${family}`,
35277
35341
  description: `Workit ${family} operations backed by the shared task contract.`,
@@ -35281,19 +35345,8 @@ var WORKIT_TOOL_CATALOG = [
35281
35345
  ...familyTools,
35282
35346
  {
35283
35347
  name: "workit_external_action",
35284
- description: `Run one fixed optional action. ${externalActionHelp}`,
35285
- input: objectSchema({
35286
- operation: {
35287
- type: "string",
35288
- enum: [...WORKIT_EXTERNAL_ACTION_OPERATIONS],
35289
- description: "Fixed optional action to run."
35290
- },
35291
- payload: {
35292
- type: "object",
35293
- description: "Operation-specific payload; Workit validates it.",
35294
- additionalProperties: true
35295
- }
35296
- }, ["operation", "payload"])
35348
+ description: "Run a Workit-managed external action. context.read is read-only. Mutations require an active coordinator task, checkout writer ownership, and host-native authorization. Routine Git work already permitted by the host can use native tools without a Workit task; never use another route to bypass a host denial or uncertain result.",
35349
+ input: externalActionJsonSchema()
35297
35350
  },
35298
35351
  {
35299
35352
  name: "workit_init_apply",
@@ -36028,6 +36081,12 @@ var setup = async (ctx) => {
36028
36081
  }
36029
36082
  });
36030
36083
  await ctx.tool.hook("execute.before", async (event) => {
36084
+ if (event.tool === "question") {
36085
+ const sessionID = String(event.sessionID);
36086
+ const callID = String(event.id);
36087
+ receipts.recordRequest(callID, sessionID, callID, event.input?.questions);
36088
+ return;
36089
+ }
36031
36090
  if (event.tool !== "subagent")
36032
36091
  return;
36033
36092
  await lifecycle.executeBefore({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brainervirus/workit-opencode",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "private": false,
5
5
  "description": "Workit OpenCode plugin — native tools, adaptive policy, and fourteen method skills",
6
6
  "keywords": [
@@ -39,7 +39,7 @@
39
39
  "typecheck": "tsc --noEmit"
40
40
  },
41
41
  "dependencies": {
42
- "@brainervirus/workit-core": "^1.3.0"
42
+ "@brainervirus/workit-core": "^1.3.1"
43
43
  },
44
44
  "devDependencies": {
45
45
  "@opencode-ai/plugin": "1.18.30",