@brainervirus/workit-opencode 8.4.1 → 8.5.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/assets/skills/workit-retro/SKILL.md +2 -2
- package/dist/plugin.js +385 -114
- package/package.json +2 -2
|
@@ -15,8 +15,8 @@ proposes and stops. Nothing changes until the user approves.
|
|
|
15
15
|
`retro:` row in `workit ledger list --type decision`), else the last ~10
|
|
16
16
|
sessions. State the window in one line.
|
|
17
17
|
2. **Read through workit, cheapest first.** Every finding cites these:
|
|
18
|
-
- `workit ledger list --last 200`: rulings
|
|
19
|
-
|
|
18
|
+
- `workit ledger list --last 200`: rulings, failed/self verdicts, handoffs,
|
|
19
|
+
check runs, CI reruns, `skill.loaded` rows (skipped skills: routing).
|
|
20
20
|
- `workit pr status --pr <n>` for each recent PR: threads, failing checks.
|
|
21
21
|
- `git log --oneline -50`, plus reverts and fixups after review.
|
|
22
22
|
- `workit knowledge lint`: today's AGENTS.md and need-based files.
|
package/dist/plugin.js
CHANGED
|
@@ -19157,6 +19157,7 @@ function entryCompactContext(store, entry, session, context) {
|
|
|
19157
19157
|
cache.delete(cache.keys().next().value);
|
|
19158
19158
|
return compact.data;
|
|
19159
19159
|
}
|
|
19160
|
+
var TURN_TTL_MS = 7 * 24 * 60 * 60 * 1000;
|
|
19160
19161
|
// packages/workit-core/src/hooks/policy.ts
|
|
19161
19162
|
var shellPolicy = (cwd, command) => {
|
|
19162
19163
|
const policy = shellBranchPolicyViolation(cwd, command);
|
|
@@ -19450,7 +19451,7 @@ function writeGate(cwd, paths) {
|
|
|
19450
19451
|
const gate = gateFor(cwd);
|
|
19451
19452
|
if (!gate || gate.blockers.length === 0)
|
|
19452
19453
|
return NONE2;
|
|
19453
|
-
if (paths && paths.every((file) => exempt(cwd, gate.root, file, gate.plans)))
|
|
19454
|
+
if (paths?.length && paths.every((file) => exempt(cwd, gate.root, file, gate.plans)))
|
|
19454
19455
|
return NONE2;
|
|
19455
19456
|
const reasons = gate.blockers.map((item) => `${item.ruleId}: ${item.reason}`).join("; ");
|
|
19456
19457
|
return {
|
|
@@ -19800,6 +19801,11 @@ var actionsIn = (cwd, command, dialect) => {
|
|
|
19800
19801
|
}
|
|
19801
19802
|
return out;
|
|
19802
19803
|
};
|
|
19804
|
+
var inWorkitWorkspace = (dir) => {
|
|
19805
|
+
const repo = repoAt(dir);
|
|
19806
|
+
return repo !== null && isWorkitWorkspace(repo);
|
|
19807
|
+
};
|
|
19808
|
+
var rawDelivery = (cwd, command, dialect) => mentionsRawTool(command) && actionsIn(cwd, command, dialect).some(({ action }) => action.kind !== "commit" && action.kind !== "pr-read");
|
|
19803
19809
|
var mentionsRawTool = (command) => /\b(?:git|gh|glab)\b/i.test(command);
|
|
19804
19810
|
var dialectOf = (input) => (input.event.kind === "shell.pre" || input.event.kind === "shell.post" ? input.event.dialect : undefined) ?? "posix";
|
|
19805
19811
|
function rawGitPre(input, command) {
|
|
@@ -19908,8 +19914,274 @@ function rawGitPost(input, command, key) {
|
|
|
19908
19914
|
settle2(input, repo, markerFile(repo, input.session.id, key));
|
|
19909
19915
|
} catch {}
|
|
19910
19916
|
}
|
|
19917
|
+
// packages/workit-core/src/hooks/skill-nudge.ts
|
|
19918
|
+
import { createHash as createHash12 } from "node:crypto";
|
|
19919
|
+
import fs16 from "node:fs";
|
|
19920
|
+
import path23 from "node:path";
|
|
19921
|
+
|
|
19922
|
+
// packages/workit-core/src/core/skill-manifests.ts
|
|
19923
|
+
var WORKIT_METHOD_SKILLS = [
|
|
19924
|
+
"workit-shape",
|
|
19925
|
+
"workit-implement",
|
|
19926
|
+
"workit-review",
|
|
19927
|
+
"workit-debug",
|
|
19928
|
+
"workit-ship",
|
|
19929
|
+
"workit-continue",
|
|
19930
|
+
"workit-bdd",
|
|
19931
|
+
"workit-test-audit",
|
|
19932
|
+
"workit-deslop",
|
|
19933
|
+
"workit-fanout",
|
|
19934
|
+
"workit-verify-app",
|
|
19935
|
+
"workit-retro",
|
|
19936
|
+
"workit-architecture"
|
|
19937
|
+
];
|
|
19938
|
+
var WORKIT_SKILL_ALIASES = {
|
|
19939
|
+
"wk-shape": "workit-shape",
|
|
19940
|
+
"wk-implement": "workit-implement",
|
|
19941
|
+
"wk-review": "workit-review",
|
|
19942
|
+
"wk-debug": "workit-debug",
|
|
19943
|
+
"wk-ship": "workit-ship",
|
|
19944
|
+
"wk-continue": "workit-continue",
|
|
19945
|
+
"wk-bdd": "workit-bdd",
|
|
19946
|
+
"wk-test-audit": "workit-test-audit",
|
|
19947
|
+
"wk-deslop": "workit-deslop",
|
|
19948
|
+
"wk-fanout": "workit-fanout",
|
|
19949
|
+
"wk-verify-app": "workit-verify-app",
|
|
19950
|
+
"wk-retro": "workit-retro",
|
|
19951
|
+
"wk-architecture": "workit-architecture"
|
|
19952
|
+
};
|
|
19953
|
+
var skillLoadWording = (host, skill) => {
|
|
19954
|
+
switch (host) {
|
|
19955
|
+
case "claude-code":
|
|
19956
|
+
return `call the Skill tool with \`workit:${skill.replace(/^workit-/, "")}\``;
|
|
19957
|
+
case "opencode":
|
|
19958
|
+
return `call the skill tool with \`${skill}\``;
|
|
19959
|
+
default:
|
|
19960
|
+
return `read the \`${skill}\` skill's SKILL.md and follow it`;
|
|
19961
|
+
}
|
|
19962
|
+
};
|
|
19963
|
+
var SKILL_REFERENCE = /\((workit-[a-z-]+)\)/g;
|
|
19964
|
+
var renderSkillText = (text, host) => text.replace(SKILL_REFERENCE, (match, name) => WORKIT_METHOD_SKILLS.includes(name) ? `(${skillLoadWording(host, name)})` : match);
|
|
19965
|
+
if (false) {}
|
|
19966
|
+
|
|
19967
|
+
// packages/workit-core/src/hooks/skill-nudge.ts
|
|
19968
|
+
var USER_INVOKED = new Set(["workit-retro", "workit-architecture"]);
|
|
19969
|
+
var SKILL_HOST = {
|
|
19970
|
+
claude_code: "claude-code",
|
|
19971
|
+
opencode: "opencode",
|
|
19972
|
+
codex_cli: "codex",
|
|
19973
|
+
codex_desktop: "codex",
|
|
19974
|
+
cursor: "cursor",
|
|
19975
|
+
pi: "pi"
|
|
19976
|
+
};
|
|
19977
|
+
var PROMPT_INTENTS = [
|
|
19978
|
+
[
|
|
19979
|
+
"workit-debug",
|
|
19980
|
+
/\b(flaky|regressed|(?:is|introduced) a regression|regression (?:in|after|since|from)|(?:is|are|got|looks) broken|debug (?:this|it|the|why)|fix (?:the|this|a) bug)\b/i
|
|
19981
|
+
],
|
|
19982
|
+
[
|
|
19983
|
+
"workit-continue",
|
|
19984
|
+
/\b(pick up where|where (?:were|did) we|resume (?:the|this|my|our|work|where)|hand ?off)\b/i
|
|
19985
|
+
],
|
|
19986
|
+
[
|
|
19987
|
+
"workit-review",
|
|
19988
|
+
/\b(blast radius|code review|review (?:the|this|my|PR|pr|#\d+|branch|diff|changes))\b/i
|
|
19989
|
+
],
|
|
19990
|
+
[
|
|
19991
|
+
"workit-ship",
|
|
19992
|
+
/\b(ship (?:it|this|the)|babysit|open (?:a|the) (?:PR|pr|MR|mr)(?=\s*$|\s+(?:for|to|on|with|and|against|into|from|after|once)\b|[.!,;])|merge (?:the|this|my) (?:PR|pr|MR|mr|branch)|(?:get|until|make) CI (?:is )?green)\b/i
|
|
19993
|
+
],
|
|
19994
|
+
["workit-bdd", /\b(BDD|TDD|acceptance criteria|Given\/When\/Then)(?![\w/])/],
|
|
19995
|
+
["workit-test-audit", /\b(test audit|audit the tests|tautolog\w*|weak tests)\b/i],
|
|
19996
|
+
["workit-deslop", /\b(deslop|slop|dead code)\b/i],
|
|
19997
|
+
[
|
|
19998
|
+
"workit-fanout",
|
|
19999
|
+
/\b(fan(?: |-)?out|parallelize|parallel agents|agent swarm|swarm of agents)\b/i
|
|
20000
|
+
],
|
|
20001
|
+
["workit-verify-app", /\b(verify the app|smoke test|prove it works)\b/i],
|
|
20002
|
+
["workit-retro", /\b((?:a|the) retro(?![-\w]|\.\w)|retrospective)/i],
|
|
20003
|
+
["workit-architecture", /\b(deepen (?:the )?modules|architecture (?:review|pass|audit))\b/i],
|
|
20004
|
+
[
|
|
20005
|
+
"workit-shape",
|
|
20006
|
+
/\b(brainstorm\w*|grill me|should we|let'?s plan|plan (?:out|how|the|a|for)|(?:write|draft) (?:a|the) spec)\b/i
|
|
20007
|
+
],
|
|
20008
|
+
[
|
|
20009
|
+
"workit-implement",
|
|
20010
|
+
/\b(implement (?:the|this|a|it)|add (?:a|the) feature|build (?:a|an|the) (?:new )?(?:feature|command|verb|page|endpoint|component|cli|tool))\b/i
|
|
20011
|
+
]
|
|
20012
|
+
];
|
|
20013
|
+
var workitSkillOf = (name) => {
|
|
20014
|
+
const bare = name.trim().replace(/^\//, "").toLowerCase();
|
|
20015
|
+
const alias = WORKIT_SKILL_ALIASES[bare];
|
|
20016
|
+
if (alias)
|
|
20017
|
+
return alias;
|
|
20018
|
+
const skill = bare.replace(/^workit:/, "workit-");
|
|
20019
|
+
return WORKIT_METHOD_SKILLS.includes(skill) ? skill : null;
|
|
20020
|
+
};
|
|
20021
|
+
var promptTrigger = (prompt) => {
|
|
20022
|
+
const text = prompt.replace(/```[\s\S]*?```/g, " ").slice(0, 4000);
|
|
20023
|
+
for (const [skill, pattern] of PROMPT_INTENTS) {
|
|
20024
|
+
const match = pattern.exec(text);
|
|
20025
|
+
if (match)
|
|
20026
|
+
return { skill, trigger: match[1] ?? match[0] };
|
|
20027
|
+
}
|
|
20028
|
+
return null;
|
|
20029
|
+
};
|
|
20030
|
+
var markerFile2 = (input, session) => {
|
|
20031
|
+
const location = resolveStore(input.cwd);
|
|
20032
|
+
if (location instanceof Error || !location.shared)
|
|
20033
|
+
return null;
|
|
20034
|
+
const name = createHash12("sha256").update(`${input.host}\x00${session}`).digest("hex").slice(0, 32);
|
|
20035
|
+
return path23.join(location.dir, "hooks", `skills-${name}.json`);
|
|
20036
|
+
};
|
|
20037
|
+
var readMarker = (file) => {
|
|
20038
|
+
try {
|
|
20039
|
+
const value = JSON.parse(fs16.readFileSync(file, "utf8"));
|
|
20040
|
+
return { nudged: value.nudged ?? [], loaded: value.loaded ?? [] };
|
|
20041
|
+
} catch {
|
|
20042
|
+
return { nudged: [], loaded: [] };
|
|
20043
|
+
}
|
|
20044
|
+
};
|
|
20045
|
+
var writeMarker = (file, marker) => {
|
|
20046
|
+
try {
|
|
20047
|
+
fs16.mkdirSync(path23.dirname(file), { recursive: true });
|
|
20048
|
+
fs16.writeFileSync(file, JSON.stringify(marker));
|
|
20049
|
+
} catch {}
|
|
20050
|
+
};
|
|
20051
|
+
var loadedSkills = (cwd, session) => {
|
|
20052
|
+
const ledger = readLedger(cwd);
|
|
20053
|
+
const loaded = new Set;
|
|
20054
|
+
if (!ledger.ok)
|
|
20055
|
+
return loaded;
|
|
20056
|
+
for (const row of ledger.value.rows)
|
|
20057
|
+
if (row.type === "skill.loaded" && row.actor.session === session && typeof row.skill === "string")
|
|
20058
|
+
loaded.add(row.skill);
|
|
20059
|
+
return loaded;
|
|
20060
|
+
};
|
|
20061
|
+
var READERS = new Set([
|
|
20062
|
+
"cat",
|
|
20063
|
+
"sed",
|
|
20064
|
+
"head",
|
|
20065
|
+
"tail",
|
|
20066
|
+
"less",
|
|
20067
|
+
"more",
|
|
20068
|
+
"bat",
|
|
20069
|
+
"nl",
|
|
20070
|
+
"get-content",
|
|
20071
|
+
"gc",
|
|
20072
|
+
"type"
|
|
20073
|
+
]);
|
|
20074
|
+
function recordSkillLoad(input, name, via) {
|
|
20075
|
+
try {
|
|
20076
|
+
const skill = workitSkillOf(name);
|
|
20077
|
+
const session = input.session.id;
|
|
20078
|
+
if (!skill || !session)
|
|
20079
|
+
return;
|
|
20080
|
+
if (!inWorkitWorkspace(input.cwd))
|
|
20081
|
+
return;
|
|
20082
|
+
const file = markerFile2(input, session);
|
|
20083
|
+
if (!file)
|
|
20084
|
+
return;
|
|
20085
|
+
const marker = readMarker(file);
|
|
20086
|
+
if (marker.loaded.includes(skill))
|
|
20087
|
+
return;
|
|
20088
|
+
writeMarker(file, { ...marker, loaded: [...marker.loaded, skill] });
|
|
20089
|
+
if (loadedSkills(input.cwd, session).has(skill))
|
|
20090
|
+
return;
|
|
20091
|
+
appendHookObserved(input.cwd, {
|
|
20092
|
+
type: "skill.loaded",
|
|
20093
|
+
actor: { host: input.host, session, agentId: input.session.agentId },
|
|
20094
|
+
skill,
|
|
20095
|
+
via
|
|
20096
|
+
});
|
|
20097
|
+
} catch {}
|
|
20098
|
+
}
|
|
20099
|
+
var nudgeOnce = (input, session, skill, line) => {
|
|
20100
|
+
const file = markerFile2(input, session);
|
|
20101
|
+
if (!file)
|
|
20102
|
+
return null;
|
|
20103
|
+
const marker = readMarker(file);
|
|
20104
|
+
if (marker.nudged.includes(skill) || marker.loaded.includes(skill))
|
|
20105
|
+
return null;
|
|
20106
|
+
if (loadedSkills(input.cwd, session).has(skill))
|
|
20107
|
+
return null;
|
|
20108
|
+
writeMarker(file, { ...marker, nudged: [...marker.nudged, skill] });
|
|
20109
|
+
return line;
|
|
20110
|
+
};
|
|
20111
|
+
var nudgeText = (input, skill, why) => USER_INVOKED.has(skill) ? `Workit: ${why} looks like ${skill} work, which the user starts; offer it (/${skill.replace(/^workit-/, "wk-")}) rather than loading it.` : `Workit: ${why} looks like ${skill} work; if it is, ${skillLoadWording(SKILL_HOST[input.host], skill)} first.`;
|
|
20112
|
+
var promptLoads = (prompt) => /^\s*\/(?:skill:)?([\w:-]+)/.exec(prompt)?.[1] ?? /^\s*<skill name="([\w:-]+)"/.exec(prompt)?.[1] ?? /^\s*Load the (workit-[a-z-]+) skill with the skill tool\b/.exec(prompt)?.[1] ?? null;
|
|
20113
|
+
function promptNudge(input, prompt) {
|
|
20114
|
+
try {
|
|
20115
|
+
const session = input.session.id;
|
|
20116
|
+
if (!prompt || !session || input.session.agentId)
|
|
20117
|
+
return null;
|
|
20118
|
+
const loads = promptLoads(prompt);
|
|
20119
|
+
if (loads) {
|
|
20120
|
+
recordSkillLoad(input, loads, "slash");
|
|
20121
|
+
return null;
|
|
20122
|
+
}
|
|
20123
|
+
const hit = promptTrigger(prompt);
|
|
20124
|
+
if (!hit || !inWorkitWorkspace(input.cwd))
|
|
20125
|
+
return null;
|
|
20126
|
+
return nudgeOnce(input, session, hit.skill, nudgeText(input, hit.skill, `this request ("${hit.trigger}")`));
|
|
20127
|
+
} catch {
|
|
20128
|
+
return null;
|
|
20129
|
+
}
|
|
20130
|
+
}
|
|
20131
|
+
var WORKIT_DELIVERY = /^(?:pr (?:create|merge)|ci wait|git push)\b/;
|
|
20132
|
+
var SHELLS2 = new Set(["sh", "bash", "zsh", "dash", "ksh"]);
|
|
20133
|
+
var LAUNCHERS = new Set([
|
|
20134
|
+
"npx",
|
|
20135
|
+
"bunx",
|
|
20136
|
+
"pnpx",
|
|
20137
|
+
"-y",
|
|
20138
|
+
"--yes",
|
|
20139
|
+
"pnpm",
|
|
20140
|
+
"dlx",
|
|
20141
|
+
"exec",
|
|
20142
|
+
"env",
|
|
20143
|
+
"sudo",
|
|
20144
|
+
"command"
|
|
20145
|
+
]);
|
|
20146
|
+
var runsWorkitDelivery = (command, dialect, depth = 0) => segmentsOf(command, dialect).some(({ words }) => {
|
|
20147
|
+
const at = words.findIndex((word) => !/^\w+=/.test(word) && !LAUNCHERS.has(word));
|
|
20148
|
+
if (at >= 0 && /(?:^|[\\/])workit(?:\.exe)?$|^@brainervirus\/workit-cli$/.test(words[at])) {
|
|
20149
|
+
const args = words.slice(at + 1);
|
|
20150
|
+
if (args.some((arg) => arg === "--help" || arg === "-h" || arg === "--dry-run"))
|
|
20151
|
+
return false;
|
|
20152
|
+
return WORKIT_DELIVERY.test(args.join(" "));
|
|
20153
|
+
}
|
|
20154
|
+
const shell = SHELLS2.has(words[at]?.split(/[\\/]/).at(-1) ?? "");
|
|
20155
|
+
const script = shell && words[at + 1] === "-c" ? words[at + 2] : undefined;
|
|
20156
|
+
return depth < 3 && script !== undefined && runsWorkitDelivery(script, "posix", depth + 1);
|
|
20157
|
+
});
|
|
20158
|
+
var isDeliveryCommand = (cwd, command, dialect = "posix") => rawDelivery(cwd, command, dialect) || runsWorkitDelivery(command, dialect) && inWorkitWorkspace(cwd);
|
|
20159
|
+
function shipNudge(input, command) {
|
|
20160
|
+
try {
|
|
20161
|
+
const session = input.session.id;
|
|
20162
|
+
if (!session || input.session.agentId)
|
|
20163
|
+
return null;
|
|
20164
|
+
const dialect = input.event.kind === "shell.pre" ? input.event.dialect ?? "posix" : "posix";
|
|
20165
|
+
if (!isDeliveryCommand(input.cwd, command, dialect))
|
|
20166
|
+
return null;
|
|
20167
|
+
return nudgeOnce(input, session, "workit-ship", nudgeText(input, "workit-ship", "this delivery step"));
|
|
20168
|
+
} catch {
|
|
20169
|
+
return null;
|
|
20170
|
+
}
|
|
20171
|
+
}
|
|
20172
|
+
var withContextLine = (decision, line) => {
|
|
20173
|
+
if (!line)
|
|
20174
|
+
return decision;
|
|
20175
|
+
if (decision.kind === "none")
|
|
20176
|
+
return { kind: "context", text: line };
|
|
20177
|
+
if (decision.kind === "context")
|
|
20178
|
+
return { kind: "context", text: `${decision.text}
|
|
20179
|
+
${line}` };
|
|
20180
|
+
return decision;
|
|
20181
|
+
};
|
|
20182
|
+
var shellNudge = (input, command) => withContextLine(rawGitPre(input, command), shipNudge(input, command));
|
|
19911
20183
|
// packages/workit-core/src/hooks/hosts/fields.ts
|
|
19912
|
-
var
|
|
20184
|
+
var SHELLS3 = new Set(["sh", "bash", "zsh", "dash", "pwsh", "powershell", "cmd"]);
|
|
19913
20185
|
var WRITE_TOOLS = new Set([
|
|
19914
20186
|
"write",
|
|
19915
20187
|
"edit",
|
|
@@ -19931,7 +20203,6 @@ var WRITE_TOOLS = new Set([
|
|
|
19931
20203
|
]);
|
|
19932
20204
|
// packages/workit-core/src/hooks/handle.ts
|
|
19933
20205
|
var offered = new Set;
|
|
19934
|
-
var CLAUDE_JUDGES = new Set(["workit:verifier", "workit:reviewer"]);
|
|
19935
20206
|
// packages/workit-core/src/hooks/hosts/claude-code.ts
|
|
19936
20207
|
var SOURCES = new Set(["startup", "resume", "clear", "compact", "fork"]);
|
|
19937
20208
|
var SHELL_TOOLS = new Set(["Bash", "PowerShell"]);
|
|
@@ -19945,7 +20216,7 @@ var CONTEXT_EVENTS = new Set([
|
|
|
19945
20216
|
|
|
19946
20217
|
// packages/workit-core/src/hooks/hosts/codex.ts
|
|
19947
20218
|
var SHELL_TOOLS2 = new Set(["bash", "unified-exec"]);
|
|
19948
|
-
var SOURCES2 = new Set(["startup", "resume", "clear", "compact"]);
|
|
20219
|
+
var SOURCES2 = new Set(["startup", "resume", "clear", "compact", "fork"]);
|
|
19949
20220
|
|
|
19950
20221
|
// packages/workit-core/src/hooks/hosts/cursor.ts
|
|
19951
20222
|
var BLOCKING2 = new Set(["preToolUse", "beforeShellExecution", "subagentStart"]);
|
|
@@ -19970,21 +20241,23 @@ var OPENCODE_DESCRIPTOR = {
|
|
|
19970
20241
|
"subagent.stop": { support: "native", native: 'tool.hook("execute.after") subagent' },
|
|
19971
20242
|
"prompt.submit": { support: "undocumented", native: null },
|
|
19972
20243
|
"compact.pre": { support: "native", native: 'session.hook("compaction")' },
|
|
19973
|
-
stop: { support: "
|
|
20244
|
+
stop: { support: "none", native: null }
|
|
19974
20245
|
},
|
|
19975
20246
|
shellPolicy: { deny: "native", channel: "effect", failClosed: false },
|
|
19976
20247
|
context: {
|
|
19977
20248
|
sessionStart: "none",
|
|
19978
20249
|
perTurn: "native",
|
|
19979
20250
|
afterCompact: "native",
|
|
19980
|
-
task: "session-bound"
|
|
20251
|
+
task: "session-bound",
|
|
20252
|
+
turnResend: "every-turn"
|
|
19981
20253
|
},
|
|
19982
20254
|
subagents: {
|
|
19983
20255
|
identity: "native",
|
|
19984
20256
|
parentBinding: "native",
|
|
19985
20257
|
blockStart: "native",
|
|
19986
20258
|
worktreeIsolation: "undocumented",
|
|
19987
|
-
maxConcurrency: "undocumented"
|
|
20259
|
+
maxConcurrency: "undocumented",
|
|
20260
|
+
agentPrefix: "workit-"
|
|
19988
20261
|
},
|
|
19989
20262
|
provenance: { sessionId: "native", agentIdOnTool: "native", postToolObserve: "native" },
|
|
19990
20263
|
interaction: { questions: "native", writeBoundary: "partial" },
|
|
@@ -20019,11 +20292,11 @@ var OPENCODE_DESCRIPTOR = {
|
|
|
20019
20292
|
]
|
|
20020
20293
|
};
|
|
20021
20294
|
// packages/workit-opencode/src/shared/init-apply.ts
|
|
20022
|
-
import
|
|
20295
|
+
import path28 from "node:path";
|
|
20023
20296
|
|
|
20024
20297
|
// packages/workit-core/src/core/gitignore.ts
|
|
20025
20298
|
import { existsSync as existsSync8, readFileSync as readFileSync6, writeFileSync as writeFileSync4 } from "node:fs";
|
|
20026
|
-
import
|
|
20299
|
+
import path24 from "node:path";
|
|
20027
20300
|
var GITIGNORE_ENTRIES = [
|
|
20028
20301
|
"# workit: SDD working state (never commit)",
|
|
20029
20302
|
"docs/*/sdd/",
|
|
@@ -20043,7 +20316,7 @@ var GITIGNORE_ENTRIES = [
|
|
|
20043
20316
|
var ensureProjectGitignore = (workspaceRoot, confirmed) => {
|
|
20044
20317
|
if (!confirmed)
|
|
20045
20318
|
return { ok: false, error: "confirmed: true required" };
|
|
20046
|
-
const file =
|
|
20319
|
+
const file = path24.join(workspaceRoot, ".gitignore");
|
|
20047
20320
|
const existing = existsSync8(file) ? readFileSync6(file, "utf8") : "";
|
|
20048
20321
|
const existingLines = new Set(existing.split(`
|
|
20049
20322
|
`).map((l) => l.trim()).filter(Boolean));
|
|
@@ -20071,25 +20344,25 @@ var ensureProjectGitignore = (workspaceRoot, confirmed) => {
|
|
|
20071
20344
|
|
|
20072
20345
|
// packages/workit-core/src/core/hygiene.ts
|
|
20073
20346
|
import { existsSync as existsSync9, readFileSync as readFileSync7, writeFileSync as writeFileSync5 } from "node:fs";
|
|
20074
|
-
import
|
|
20347
|
+
import path25 from "node:path";
|
|
20075
20348
|
var repoRoot3 = assetRoot();
|
|
20076
|
-
var templatesDir = () =>
|
|
20349
|
+
var templatesDir = () => path25.join(repoRoot3, "templates", "hygiene");
|
|
20077
20350
|
var packageJson = (root) => {
|
|
20078
|
-
if (!existsSync9(
|
|
20351
|
+
if (!existsSync9(path25.join(root, "package.json")))
|
|
20079
20352
|
return null;
|
|
20080
20353
|
try {
|
|
20081
|
-
return JSON.parse(readFileSync7(
|
|
20354
|
+
return JSON.parse(readFileSync7(path25.join(root, "package.json"), "utf8"));
|
|
20082
20355
|
} catch {
|
|
20083
20356
|
return null;
|
|
20084
20357
|
}
|
|
20085
20358
|
};
|
|
20086
20359
|
var isOpenSource = (root) => {
|
|
20087
|
-
if (existsSync9(
|
|
20360
|
+
if (existsSync9(path25.join(root, "LICENSE")))
|
|
20088
20361
|
return true;
|
|
20089
20362
|
const pkg = packageJson(root);
|
|
20090
20363
|
if (pkg && !pkg.private)
|
|
20091
20364
|
return true;
|
|
20092
|
-
return
|
|
20365
|
+
return path25.basename(root) === "workflow-toolkit";
|
|
20093
20366
|
};
|
|
20094
20367
|
var licenseHolder = (root) => {
|
|
20095
20368
|
const pkg = packageJson(root);
|
|
@@ -20112,13 +20385,13 @@ var planHygieneFiles = (root, opts = {}) => {
|
|
|
20112
20385
|
files.push("LICENSE", "CONTRIBUTING.md");
|
|
20113
20386
|
const planned = [];
|
|
20114
20387
|
for (const file of files) {
|
|
20115
|
-
if (existsSync9(
|
|
20388
|
+
if (existsSync9(path25.join(root, file)))
|
|
20116
20389
|
continue;
|
|
20117
|
-
const tpl =
|
|
20390
|
+
const tpl = path25.join(templatesDir(), file);
|
|
20118
20391
|
if (!existsSync9(tpl))
|
|
20119
20392
|
continue;
|
|
20120
|
-
const content = readFileSync7(tpl, "utf8").replace(/<PROJECT>/g,
|
|
20121
|
-
planned.push({ path:
|
|
20393
|
+
const content = readFileSync7(tpl, "utf8").replace(/<PROJECT>/g, path25.basename(root)).replace(/<YEAR>/g, String(new Date().getFullYear())).replace(/<HOLDER>\s*/g, licenseHolder(root));
|
|
20394
|
+
planned.push({ path: path25.join(root, file), content });
|
|
20122
20395
|
}
|
|
20123
20396
|
return planned;
|
|
20124
20397
|
};
|
|
@@ -20128,19 +20401,19 @@ var ensureHygieneFiles = (root, opts) => {
|
|
|
20128
20401
|
const created = [];
|
|
20129
20402
|
for (const planned of planHygieneFiles(root, opts)) {
|
|
20130
20403
|
writeFileSync5(planned.path, planned.content, "utf8");
|
|
20131
|
-
created.push(
|
|
20404
|
+
created.push(path25.basename(planned.path));
|
|
20132
20405
|
}
|
|
20133
20406
|
return { ok: true, created };
|
|
20134
20407
|
};
|
|
20135
20408
|
|
|
20136
20409
|
// packages/workit-core/src/core/init.ts
|
|
20137
|
-
import
|
|
20138
|
-
import
|
|
20410
|
+
import fs17 from "node:fs";
|
|
20411
|
+
import path27 from "node:path";
|
|
20139
20412
|
import { spawnSync as spawnSync16 } from "node:child_process";
|
|
20140
20413
|
|
|
20141
20414
|
// packages/workit-core/src/core/workspace-branch-policy.ts
|
|
20142
20415
|
import { mkdirSync as mkdirSync4, readFileSync as readFileSync8, renameSync as renameSync3, rmSync as rmSync2, writeFileSync as writeFileSync6 } from "node:fs";
|
|
20143
|
-
import
|
|
20416
|
+
import path26 from "node:path";
|
|
20144
20417
|
import { isDeepStrictEqual } from "node:util";
|
|
20145
20418
|
var readFileSafe = (p) => {
|
|
20146
20419
|
try {
|
|
@@ -20151,7 +20424,7 @@ var readFileSafe = (p) => {
|
|
|
20151
20424
|
};
|
|
20152
20425
|
function applyWorkspaceBranchPolicy(opts) {
|
|
20153
20426
|
const { workspace_root, env = process.env } = opts;
|
|
20154
|
-
const dir =
|
|
20427
|
+
const dir = path26.join(env.WORKFLOW_TOOLKIT_CONFIG ?? configDir());
|
|
20155
20428
|
const {
|
|
20156
20429
|
status,
|
|
20157
20430
|
path: wsPath,
|
|
@@ -20163,7 +20436,7 @@ function applyWorkspaceBranchPolicy(opts) {
|
|
|
20163
20436
|
if (status === "malformed" || status === "invalid")
|
|
20164
20437
|
return { ok: false, error: workspacesError ?? `invalid workspaces.json: ${wsPath}` };
|
|
20165
20438
|
const detection = detectBranchPolicy(workspace_root);
|
|
20166
|
-
const name = String(env.WORKFLOW_BP_NAME ??
|
|
20439
|
+
const name = String(env.WORKFLOW_BP_NAME ?? path26.basename(workspace_root));
|
|
20167
20440
|
const integration = env.WORKFLOW_BP_INTEGRATION ?? detection.integration;
|
|
20168
20441
|
const policy = {
|
|
20169
20442
|
preset: detection.preset,
|
|
@@ -20212,7 +20485,7 @@ function applyWorkspaceBranchPolicy(opts) {
|
|
|
20212
20485
|
ok: false,
|
|
20213
20486
|
error: `workspaces.json changed while applying the branch policy: ${wsPath}`
|
|
20214
20487
|
};
|
|
20215
|
-
mkdirSync4(
|
|
20488
|
+
mkdirSync4(path26.dirname(wsPath), { recursive: true });
|
|
20216
20489
|
const tmp = `${wsPath}.${process.pid}.tmp`;
|
|
20217
20490
|
try {
|
|
20218
20491
|
writeFileSync6(tmp, JSON.stringify({ ...document, workspaces: next }, null, 2) + `
|
|
@@ -20247,7 +20520,7 @@ function applyWorkspaceBranchPolicy(opts) {
|
|
|
20247
20520
|
var TOKEN_PLACEHOLDER2 = "YOUR_TOKEN_HERE";
|
|
20248
20521
|
var readJson = (p) => {
|
|
20249
20522
|
try {
|
|
20250
|
-
const parsed = JSON.parse(
|
|
20523
|
+
const parsed = JSON.parse(fs17.readFileSync(p, "utf8"));
|
|
20251
20524
|
return isConfigObject(parsed) ? parsed : null;
|
|
20252
20525
|
} catch {
|
|
20253
20526
|
return null;
|
|
@@ -20277,7 +20550,7 @@ var youtrackJsonContent = (dir) => {
|
|
|
20277
20550
|
const meetingIssue = process.env.WORKFLOW_YT_MEETING_ISSUE;
|
|
20278
20551
|
return {
|
|
20279
20552
|
baseUrl: process.env.WORKFLOW_YT_BASE_URL ?? "https://youtrack.example.com",
|
|
20280
|
-
tokenFile: process.env.WORKFLOW_YT_TOKEN_FILE ??
|
|
20553
|
+
tokenFile: process.env.WORKFLOW_YT_TOKEN_FILE ?? path27.join(dir, "youtrack.token"),
|
|
20281
20554
|
...meetingIssue ? {
|
|
20282
20555
|
meetingIssue,
|
|
20283
20556
|
meetingIssues: { general: { issue: meetingIssue, label: "General meetings" } }
|
|
@@ -20307,19 +20580,19 @@ var vcsJsonContent = () => {
|
|
|
20307
20580
|
};
|
|
20308
20581
|
function initApplyData(action, env = process.env) {
|
|
20309
20582
|
const dir = String(env.WORKFLOW_TOOLKIT_CONFIG ?? configDir());
|
|
20310
|
-
|
|
20583
|
+
fs17.mkdirSync(dir, { recursive: true });
|
|
20311
20584
|
switch (action) {
|
|
20312
20585
|
case "youtrack_json": {
|
|
20313
|
-
const out =
|
|
20314
|
-
|
|
20586
|
+
const out = path27.join(dir, "youtrack.json");
|
|
20587
|
+
fs17.writeFileSync(out, JSON.stringify(youtrackJsonContent(dir), null, 2) + `
|
|
20315
20588
|
`, "utf8");
|
|
20316
20589
|
return { action, ok: true, path: out };
|
|
20317
20590
|
}
|
|
20318
20591
|
case "youtrack_token_placeholder": {
|
|
20319
|
-
const p =
|
|
20592
|
+
const p = path27.join(dir, "youtrack.token");
|
|
20320
20593
|
const preserved = writeFileExclusive(p, TOKEN_PLACEHOLDER2 + `
|
|
20321
20594
|
`, 384) === "preserved";
|
|
20322
|
-
const abs =
|
|
20595
|
+
const abs = path27.resolve(p);
|
|
20323
20596
|
return {
|
|
20324
20597
|
action,
|
|
20325
20598
|
ok: true,
|
|
@@ -20331,14 +20604,14 @@ function initApplyData(action, env = process.env) {
|
|
|
20331
20604
|
};
|
|
20332
20605
|
}
|
|
20333
20606
|
case "youtrack_scaffold": {
|
|
20334
|
-
const jsonOut =
|
|
20335
|
-
const tokenOut =
|
|
20336
|
-
|
|
20607
|
+
const jsonOut = path27.join(dir, "youtrack.json");
|
|
20608
|
+
const tokenOut = path27.join(dir, "youtrack.token");
|
|
20609
|
+
fs17.writeFileSync(jsonOut, JSON.stringify(youtrackJsonContent(dir), null, 2) + `
|
|
20337
20610
|
`, "utf8");
|
|
20338
20611
|
const preserved = writeFileExclusive(tokenOut, TOKEN_PLACEHOLDER2 + `
|
|
20339
20612
|
`, 384) === "preserved";
|
|
20340
|
-
const configPath =
|
|
20341
|
-
const tokenPath =
|
|
20613
|
+
const configPath = path27.resolve(jsonOut);
|
|
20614
|
+
const tokenPath = path27.resolve(tokenOut);
|
|
20342
20615
|
const prev = process.env.WORKFLOW_YOUTRACK_CONFIG;
|
|
20343
20616
|
process.env.WORKFLOW_YOUTRACK_CONFIG = configPath;
|
|
20344
20617
|
let tokenCreate = {};
|
|
@@ -20390,10 +20663,10 @@ function initApplyData(action, env = process.env) {
|
|
|
20390
20663
|
}
|
|
20391
20664
|
}
|
|
20392
20665
|
case "vcs_scaffold": {
|
|
20393
|
-
const jsonOut =
|
|
20394
|
-
|
|
20666
|
+
const jsonOut = path27.join(dir, "vcs.json");
|
|
20667
|
+
fs17.writeFileSync(jsonOut, JSON.stringify(vcsJsonContent(), null, 2) + `
|
|
20395
20668
|
`, "utf8");
|
|
20396
|
-
const configPath =
|
|
20669
|
+
const configPath = path27.resolve(jsonOut);
|
|
20397
20670
|
const prev = process.env.WORKFLOW_VCS_CONFIG;
|
|
20398
20671
|
process.env.WORKFLOW_VCS_CONFIG = configPath;
|
|
20399
20672
|
try {
|
|
@@ -20512,7 +20785,7 @@ var executeInitApply = (args, directory, runtime) => {
|
|
|
20512
20785
|
protectedNames: args.branch_policy_protected
|
|
20513
20786
|
}, current);
|
|
20514
20787
|
writeConfig(next);
|
|
20515
|
-
return output(ok({ action: "config", path:
|
|
20788
|
+
return output(ok({ action: "config", path: path28.join(configDir(), "config.json"), ...next }));
|
|
20516
20789
|
}
|
|
20517
20790
|
const env = Object.fromEntries(Object.entries({
|
|
20518
20791
|
WORKFLOW_YT_BASE_URL: args.base_url,
|
|
@@ -20529,14 +20802,14 @@ var executeInitApply = (args, directory, runtime) => {
|
|
|
20529
20802
|
|
|
20530
20803
|
// packages/workit-opencode/src/shared/session.ts
|
|
20531
20804
|
import { realpathSync as realpathSync7 } from "node:fs";
|
|
20532
|
-
import
|
|
20805
|
+
import path29 from "node:path";
|
|
20533
20806
|
var sameWorkspace = (expected, observed) => {
|
|
20534
20807
|
if (typeof observed !== "string" || !observed)
|
|
20535
20808
|
return false;
|
|
20536
20809
|
try {
|
|
20537
20810
|
return realpathSync7(expected) === realpathSync7(observed);
|
|
20538
20811
|
} catch {
|
|
20539
|
-
return
|
|
20812
|
+
return path29.resolve(expected) === path29.resolve(observed);
|
|
20540
20813
|
}
|
|
20541
20814
|
};
|
|
20542
20815
|
|
|
@@ -20608,7 +20881,7 @@ var workitFamilyOf = (toolName) => {
|
|
|
20608
20881
|
|
|
20609
20882
|
// packages/workit-opencode/src/tools/context.ts
|
|
20610
20883
|
import { realpathSync as realpathSync8 } from "node:fs";
|
|
20611
|
-
import
|
|
20884
|
+
import path30 from "node:path";
|
|
20612
20885
|
var createContextTool = () => ({
|
|
20613
20886
|
description: "Read Git, pull request, YouTrack, issue, changelog, release, or affected-file context.",
|
|
20614
20887
|
execute: async (args, context) => {
|
|
@@ -20618,7 +20891,7 @@ var createContextTool = () => ({
|
|
|
20618
20891
|
let root;
|
|
20619
20892
|
try {
|
|
20620
20893
|
const cwd = parsed.data.cwd;
|
|
20621
|
-
root = realpathSync8(cwd ?
|
|
20894
|
+
root = realpathSync8(cwd ? path30.resolve(context.directory, cwd) : context.directory);
|
|
20622
20895
|
} catch {
|
|
20623
20896
|
return JSON.stringify(failure2("invalid_input", "context target directory cannot be resolved"), null, 2);
|
|
20624
20897
|
}
|
|
@@ -21180,7 +21453,7 @@ var evaluateShellPermission = (root, event, workdirs = new Map) => {
|
|
|
21180
21453
|
};
|
|
21181
21454
|
|
|
21182
21455
|
// packages/workit-opencode/src/v2/shell.ts
|
|
21183
|
-
import
|
|
21456
|
+
import path31 from "node:path";
|
|
21184
21457
|
var commandOf = (input) => {
|
|
21185
21458
|
if (input === null || typeof input !== "object")
|
|
21186
21459
|
return null;
|
|
@@ -21189,7 +21462,7 @@ var commandOf = (input) => {
|
|
|
21189
21462
|
};
|
|
21190
21463
|
var hookInput = (root, sessionID, id, shell) => ({
|
|
21191
21464
|
host: "opencode",
|
|
21192
|
-
cwd: shell.workdir ?
|
|
21465
|
+
cwd: shell.workdir ? path31.resolve(root, shell.workdir) : root,
|
|
21193
21466
|
session: { id: sessionID, agentId: null, agentType: null, parentId: null },
|
|
21194
21467
|
permissionMode: null,
|
|
21195
21468
|
transcriptPath: null,
|
|
@@ -21219,7 +21492,7 @@ var observeShellResult = (root, event) => {
|
|
|
21219
21492
|
return;
|
|
21220
21493
|
const input = hookInput(root, String(event.sessionID), String(event.id), shell);
|
|
21221
21494
|
rawGitPost(input, shell.command, callKey(String(event.id), shell.command));
|
|
21222
|
-
const nudge =
|
|
21495
|
+
const nudge = shellNudge(input, shell.command);
|
|
21223
21496
|
const result = event.result;
|
|
21224
21497
|
if (nudge.kind !== "context" || !result)
|
|
21225
21498
|
return;
|
|
@@ -21235,84 +21508,78 @@ ${nudge.text}` };
|
|
|
21235
21508
|
} catch {}
|
|
21236
21509
|
};
|
|
21237
21510
|
|
|
21238
|
-
// packages/workit-opencode/src/v2/
|
|
21239
|
-
|
|
21240
|
-
|
|
21241
|
-
|
|
21242
|
-
|
|
21243
|
-
|
|
21244
|
-
|
|
21245
|
-
|
|
21246
|
-
|
|
21247
|
-
|
|
21248
|
-
|
|
21249
|
-
|
|
21250
|
-
"
|
|
21251
|
-
|
|
21252
|
-
|
|
21253
|
-
|
|
21254
|
-
"
|
|
21255
|
-
|
|
21256
|
-
|
|
21257
|
-
|
|
21258
|
-
|
|
21259
|
-
|
|
21260
|
-
|
|
21261
|
-
|
|
21262
|
-
|
|
21263
|
-
|
|
21264
|
-
|
|
21265
|
-
"
|
|
21266
|
-
|
|
21267
|
-
|
|
21268
|
-
"wk-fanout": "workit-fanout",
|
|
21269
|
-
"wk-verify-app": "workit-verify-app",
|
|
21270
|
-
"wk-retro": "workit-retro",
|
|
21271
|
-
"wk-architecture": "workit-architecture"
|
|
21511
|
+
// packages/workit-opencode/src/v2/skills.ts
|
|
21512
|
+
var hookInput2 = (root, sessionID, subagent) => ({
|
|
21513
|
+
host: "opencode",
|
|
21514
|
+
cwd: root,
|
|
21515
|
+
session: {
|
|
21516
|
+
id: sessionID,
|
|
21517
|
+
agentId: subagent ? sessionID : null,
|
|
21518
|
+
agentType: null,
|
|
21519
|
+
parentId: null
|
|
21520
|
+
},
|
|
21521
|
+
permissionMode: null,
|
|
21522
|
+
transcriptPath: null,
|
|
21523
|
+
event: { kind: "context.turn" }
|
|
21524
|
+
});
|
|
21525
|
+
var observeSkillLoad = (root, event) => {
|
|
21526
|
+
const input = event.input;
|
|
21527
|
+
if (typeof input?.name === "string")
|
|
21528
|
+
recordSkillLoad(hookInput2(root, String(event.sessionID), false), input.name, "tool");
|
|
21529
|
+
};
|
|
21530
|
+
var newUserPrompt = (messages) => {
|
|
21531
|
+
const last = messages.at(-1);
|
|
21532
|
+
if (last?.role !== "user")
|
|
21533
|
+
return null;
|
|
21534
|
+
if (typeof last.content === "string")
|
|
21535
|
+
return last.content;
|
|
21536
|
+
if (!Array.isArray(last.content))
|
|
21537
|
+
return null;
|
|
21538
|
+
const text = last.content.filter((part) => part.type === "text" && typeof part.text === "string").map((part) => part.text).join(`
|
|
21539
|
+
`);
|
|
21540
|
+
return text || null;
|
|
21272
21541
|
};
|
|
21273
|
-
var
|
|
21274
|
-
|
|
21275
|
-
|
|
21276
|
-
|
|
21277
|
-
|
|
21278
|
-
|
|
21279
|
-
default:
|
|
21280
|
-
return `read the \`${skill}\` skill's SKILL.md and follow it`;
|
|
21281
|
-
}
|
|
21542
|
+
var injectSkillNudge = (root, session, messages, system) => {
|
|
21543
|
+
try {
|
|
21544
|
+
const nudge = promptNudge(hookInput2(root, session.id, session.parentID !== undefined), newUserPrompt(messages));
|
|
21545
|
+
if (nudge)
|
|
21546
|
+
system.push({ type: "text", text: nudge });
|
|
21547
|
+
} catch {}
|
|
21282
21548
|
};
|
|
21283
|
-
|
|
21284
|
-
|
|
21285
|
-
|
|
21549
|
+
|
|
21550
|
+
// packages/workit-opencode/src/v2/registry.ts
|
|
21551
|
+
import { existsSync as existsSync11, readFileSync as readFileSync9 } from "node:fs";
|
|
21552
|
+
import path33 from "node:path";
|
|
21286
21553
|
|
|
21287
21554
|
// packages/workit-opencode/src/shared/assets.ts
|
|
21288
21555
|
import { existsSync as existsSync10, realpathSync as realpathSync9 } from "node:fs";
|
|
21289
|
-
import
|
|
21556
|
+
import path32 from "node:path";
|
|
21290
21557
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
21291
21558
|
var moduleDir = () => {
|
|
21292
21559
|
try {
|
|
21293
|
-
return realpathSync9(
|
|
21560
|
+
return realpathSync9(path32.dirname(fileURLToPath2(import.meta.url)));
|
|
21294
21561
|
} catch {
|
|
21295
|
-
return
|
|
21562
|
+
return path32.dirname(fileURLToPath2(import.meta.url));
|
|
21296
21563
|
}
|
|
21297
21564
|
};
|
|
21298
21565
|
var packageRoot2 = () => {
|
|
21299
21566
|
const dir = moduleDir();
|
|
21300
21567
|
for (const candidate of [
|
|
21301
|
-
|
|
21302
|
-
|
|
21303
|
-
|
|
21568
|
+
path32.resolve(dir, ".."),
|
|
21569
|
+
path32.resolve(dir, "..", ".."),
|
|
21570
|
+
path32.resolve(dir, "..", "..", "..")
|
|
21304
21571
|
]) {
|
|
21305
|
-
if (existsSync10(
|
|
21572
|
+
if (existsSync10(path32.join(candidate, "package.json")))
|
|
21306
21573
|
return candidate;
|
|
21307
21574
|
}
|
|
21308
|
-
return
|
|
21575
|
+
return path32.resolve(dir, "..");
|
|
21309
21576
|
};
|
|
21310
21577
|
var skillsRoot = () => {
|
|
21311
21578
|
const root = packageRoot2();
|
|
21312
|
-
const canonical =
|
|
21313
|
-
if (existsSync10(
|
|
21579
|
+
const canonical = path32.resolve(root, "..", "workit-core", "skills");
|
|
21580
|
+
if (existsSync10(path32.join(root, "src")) && existsSync10(canonical))
|
|
21314
21581
|
return canonical;
|
|
21315
|
-
return
|
|
21582
|
+
return path32.join(root, "assets", "skills");
|
|
21316
21583
|
};
|
|
21317
21584
|
|
|
21318
21585
|
// packages/workit-opencode/src/v2/registry.ts
|
|
@@ -21339,11 +21606,11 @@ var registerSkills = async (ctx) => {
|
|
|
21339
21606
|
if (!existsSync11(skillsDir))
|
|
21340
21607
|
return new Set;
|
|
21341
21608
|
const listed = await ctx.skill.list().catch(() => ({ data: [] }));
|
|
21342
|
-
const own = (skill) => typeof skill.path === "string" &&
|
|
21609
|
+
const own = (skill) => typeof skill.path === "string" && path33.resolve(skill.path).startsWith(skillsDir + path33.sep);
|
|
21343
21610
|
const userSkills = new Set((listed?.data ?? []).filter((skill) => !own(skill)).map((skill) => skill.id));
|
|
21344
21611
|
const packaged = new Map;
|
|
21345
21612
|
for (const id of WORKIT_METHOD_SKILLS) {
|
|
21346
|
-
const file =
|
|
21613
|
+
const file = path33.join(skillsDir, id, "SKILL.md");
|
|
21347
21614
|
if (!userSkills.has(id) && existsSync11(file))
|
|
21348
21615
|
packaged.set(id, file);
|
|
21349
21616
|
}
|
|
@@ -21391,22 +21658,22 @@ var registerCommands = async (ctx, registeredSkills) => {
|
|
|
21391
21658
|
|
|
21392
21659
|
// packages/workit-opencode/src/stale-sources.ts
|
|
21393
21660
|
import { existsSync as existsSync12, readdirSync as readdirSync5 } from "node:fs";
|
|
21394
|
-
import
|
|
21661
|
+
import path34 from "node:path";
|
|
21395
21662
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
21396
21663
|
var typescriptFiles = (directory) => {
|
|
21397
21664
|
if (!existsSync12(directory))
|
|
21398
21665
|
return [];
|
|
21399
21666
|
return readdirSync5(directory, { withFileTypes: true }).flatMap((entry) => {
|
|
21400
|
-
const file =
|
|
21667
|
+
const file = path34.join(directory, entry.name);
|
|
21401
21668
|
return entry.isDirectory() ? typescriptFiles(file) : entry.isFile() && file.endsWith(".ts") ? [file] : [];
|
|
21402
21669
|
});
|
|
21403
21670
|
};
|
|
21404
21671
|
var pluginSourceFiles = [
|
|
21405
21672
|
...new Set([
|
|
21406
21673
|
fileURLToPath3(import.meta.url),
|
|
21407
|
-
...typescriptFiles(
|
|
21408
|
-
|
|
21409
|
-
...typescriptFiles(
|
|
21674
|
+
...typescriptFiles(path34.join(packageRoot2(), "src")),
|
|
21675
|
+
path34.join(packageRoot2(), "..", "workit-core", "src", "core.ts"),
|
|
21676
|
+
...typescriptFiles(path34.join(packageRoot2(), "..", "workit-core", "src", "core"))
|
|
21410
21677
|
])
|
|
21411
21678
|
].filter((file) => existsSync12(file)).toSorted();
|
|
21412
21679
|
|
|
@@ -21511,6 +21778,8 @@ var setup = async (ctx) => {
|
|
|
21511
21778
|
await ctx.tool.hook("execute.before", async (event) => {
|
|
21512
21779
|
if (event.tool === "shell")
|
|
21513
21780
|
return observeShellBefore(root, event, shellWorkdirs);
|
|
21781
|
+
if (event.tool === "skill")
|
|
21782
|
+
return observeSkillLoad(root, event);
|
|
21514
21783
|
if (event.tool !== "subagent")
|
|
21515
21784
|
return;
|
|
21516
21785
|
await lifecycle.executeBefore({
|
|
@@ -21540,6 +21809,8 @@ var setup = async (ctx) => {
|
|
|
21540
21809
|
const session = await sessionFacts(ctx, String(event.sessionID));
|
|
21541
21810
|
injectAgentContext(root, session, lifecycle.directChildren, event.system);
|
|
21542
21811
|
injectHistoryOffer(root, session, historyOfferSessions, event.system);
|
|
21812
|
+
if (session)
|
|
21813
|
+
injectSkillNudge(root, session, event.messages, event.system);
|
|
21543
21814
|
if (!staleSourcesWarned) {
|
|
21544
21815
|
const changed = changedSourcesSinceLoad(sourceMarker);
|
|
21545
21816
|
if (changed.length > 0) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brainervirus/workit-opencode",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.5.2",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Workit OpenCode plugin — native tools, adaptive policy, and sixteen method skills",
|
|
6
6
|
"keywords": [
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"typecheck": "tsc --noEmit"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@brainervirus/workit-core": "^8.
|
|
42
|
+
"@brainervirus/workit-core": "^8.5.2"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@opencode/plugin": "2.0.18"
|