@brainervirus/workit-pi 8.24.0 → 8.26.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/dist/worker.js +526 -153
- package/dist/workit.js +2016 -1635
- package/package.json +1 -1
- package/skills/workit-fanout/SKILL.md +4 -4
- package/skills/workit-fanout/references/brief.md +4 -4
- package/skills/workit-fanout/references/orchestration.md +26 -17
- package/skills/workit-implement/SKILL.md +1 -1
- package/skills/workit-review/SKILL.md +4 -1
- package/skills/workit-ship/SKILL.md +1 -1
package/dist/worker.js
CHANGED
|
@@ -6669,6 +6669,41 @@ var ENVELOPE = new Set([
|
|
|
6669
6669
|
"judgment"
|
|
6670
6670
|
]);
|
|
6671
6671
|
// packages/workit-core/src/core/config.ts
|
|
6672
|
+
import {
|
|
6673
|
+
copyFileSync,
|
|
6674
|
+
cpSync,
|
|
6675
|
+
existsSync,
|
|
6676
|
+
mkdirSync,
|
|
6677
|
+
readFileSync,
|
|
6678
|
+
readdirSync,
|
|
6679
|
+
writeFileSync
|
|
6680
|
+
} from "node:fs";
|
|
6681
|
+
import os from "node:os";
|
|
6682
|
+
import path from "node:path";
|
|
6683
|
+
|
|
6684
|
+
// packages/workit-core/src/core/boundary.ts
|
|
6685
|
+
var EVENT = {
|
|
6686
|
+
initialization: "initialization",
|
|
6687
|
+
provenance: "provenance",
|
|
6688
|
+
assets: "assets",
|
|
6689
|
+
configurationSource: "configuration_source",
|
|
6690
|
+
hooks: "hooks",
|
|
6691
|
+
mcpConnection: "mcp_connection",
|
|
6692
|
+
migration: "migration",
|
|
6693
|
+
installSteps: "install_steps",
|
|
6694
|
+
uncaughtFailure: "uncaught_failure",
|
|
6695
|
+
toolsFailed: "tools_failed",
|
|
6696
|
+
doctor: "doctor"
|
|
6697
|
+
};
|
|
6698
|
+
var errorDetail = (err) => {
|
|
6699
|
+
if (err instanceof Error) {
|
|
6700
|
+
return { error_name: err.name, error: err.message };
|
|
6701
|
+
}
|
|
6702
|
+
return { error_name: "unknown", error: String(err) };
|
|
6703
|
+
};
|
|
6704
|
+
|
|
6705
|
+
// packages/workit-core/src/core/config.ts
|
|
6706
|
+
var diagnosticLogger;
|
|
6672
6707
|
var PRESETS = {
|
|
6673
6708
|
gitflow: {
|
|
6674
6709
|
allowed: ["feature/*", "bugfix/*", "hotfix/*", "release/*"],
|
|
@@ -6678,6 +6713,49 @@ var PRESETS = {
|
|
|
6678
6713
|
"trunk-based": { allowed: ["*"], protected: ["main"] },
|
|
6679
6714
|
custom: { allowed: [], protected: [] }
|
|
6680
6715
|
};
|
|
6716
|
+
var resolveConfigDir = () => process.env.WORKFLOW_TOOLKIT_CONFIG ?? process.env.WORKFLOW_TOOLKIT_CONFIG_DIR ?? path.join(process.env.XDG_CONFIG_HOME || path.join(os.homedir(), ".config"), "workit");
|
|
6717
|
+
var migratedDir = null;
|
|
6718
|
+
var migrationFailed = false;
|
|
6719
|
+
var ensureConfigDir = (dir = resolveConfigDir()) => {
|
|
6720
|
+
if (migratedDir === dir)
|
|
6721
|
+
return dir;
|
|
6722
|
+
if (process.env.WORKFLOW_TOOLKIT_CONFIG || process.env.WORKFLOW_TOOLKIT_CONFIG_DIR) {
|
|
6723
|
+
migratedDir = dir;
|
|
6724
|
+
return dir;
|
|
6725
|
+
}
|
|
6726
|
+
const legacy = path.join(process.env.XDG_CONFIG_HOME || path.join(os.homedir(), ".config"), "workflow-toolkit");
|
|
6727
|
+
if (!existsSync(legacy)) {
|
|
6728
|
+
migratedDir = dir;
|
|
6729
|
+
return dir;
|
|
6730
|
+
}
|
|
6731
|
+
if (!migrationFailed && existsSync(dir)) {
|
|
6732
|
+
migratedDir = dir;
|
|
6733
|
+
return dir;
|
|
6734
|
+
}
|
|
6735
|
+
migrationFailed = false;
|
|
6736
|
+
mkdirSync(dir, { recursive: true });
|
|
6737
|
+
diagnosticLogger?.info(EVENT.migration, { from: legacy, to: dir });
|
|
6738
|
+
for (const entry of readdirSync(legacy, { withFileTypes: true })) {
|
|
6739
|
+
const src = path.join(legacy, entry.name);
|
|
6740
|
+
const dest = path.join(dir, entry.name);
|
|
6741
|
+
if (existsSync(dest))
|
|
6742
|
+
continue;
|
|
6743
|
+
try {
|
|
6744
|
+
if (entry.isDirectory())
|
|
6745
|
+
cpSync(src, dest, { recursive: true });
|
|
6746
|
+
else if (entry.isFile())
|
|
6747
|
+
copyFileSync(src, dest);
|
|
6748
|
+
} catch (err) {
|
|
6749
|
+
migrationFailed = true;
|
|
6750
|
+
diagnosticLogger?.warn(EVENT.migration, { from: src, ok: false, ...errorDetail(err) });
|
|
6751
|
+
console.warn(`[workit] config migration: a file could not be copied to ${dir}; it will be retried on the next run`);
|
|
6752
|
+
}
|
|
6753
|
+
}
|
|
6754
|
+
if (!migrationFailed)
|
|
6755
|
+
migratedDir = dir;
|
|
6756
|
+
return dir;
|
|
6757
|
+
};
|
|
6758
|
+
var configDir = () => ensureConfigDir();
|
|
6681
6759
|
var DEFAULTS = {
|
|
6682
6760
|
locale: "en",
|
|
6683
6761
|
localeOptions: ["en", "es-CL", "es-MX", "es-AR", "pt-BR"],
|
|
@@ -6699,7 +6777,9 @@ var COMMIT_PRESETS = [
|
|
|
6699
6777
|
];
|
|
6700
6778
|
|
|
6701
6779
|
// packages/workit-core/src/core/workspaces.ts
|
|
6702
|
-
import
|
|
6780
|
+
import { spawnSync } from "node:child_process";
|
|
6781
|
+
import { readFileSync as readFileSync2, realpathSync } from "node:fs";
|
|
6782
|
+
import path2 from "node:path";
|
|
6703
6783
|
var nonBlank = string2().refine((value) => value.trim().length > 0, "must not be blank");
|
|
6704
6784
|
var branchPreset = custom((value) => typeof value === "string" && Object.hasOwn(PRESETS, value), "unsupported branch preset");
|
|
6705
6785
|
var commitPreset = custom((value) => typeof value === "string" && COMMIT_PRESETS.includes(value), "unsupported commit preset");
|
|
@@ -6757,7 +6837,7 @@ var releaseTrackSchema = object({
|
|
|
6757
6837
|
context.addIssue({ code: "custom", path: [field], message: "entries must be unique" });
|
|
6758
6838
|
}
|
|
6759
6839
|
}
|
|
6760
|
-
if (track.versionSource?.kind === "package-json" && (
|
|
6840
|
+
if (track.versionSource?.kind === "package-json" && (path2.posix.isAbsolute(track.versionSource.path.replaceAll("\\", "/")) || /^[A-Za-z]:\//u.test(track.versionSource.path.replaceAll("\\", "/")) || track.versionSource.path.replaceAll("\\", "/").split("/").includes(".."))) {
|
|
6761
6841
|
context.addIssue({
|
|
6762
6842
|
code: "custom",
|
|
6763
6843
|
path: ["versionSource", "path"],
|
|
@@ -6781,6 +6861,7 @@ var workspaceConfigSchema = object({
|
|
|
6781
6861
|
trailers: boolean2().optional(),
|
|
6782
6862
|
liveSessionGuard: boolean2().optional(),
|
|
6783
6863
|
fanout: object({ tierModels: unknown().optional() }).passthrough().optional(),
|
|
6864
|
+
models: object({ roles: unknown().optional() }).passthrough().optional(),
|
|
6784
6865
|
autonomy: object(Object.fromEntries(["push", "pr", "merge", "release", "rerun"].map((kind) => [
|
|
6785
6866
|
kind,
|
|
6786
6867
|
union([boolean2(), literal("verified")]).optional()
|
|
@@ -6807,7 +6888,10 @@ var workspaceConfigSchema = object({
|
|
|
6807
6888
|
});
|
|
6808
6889
|
}
|
|
6809
6890
|
});
|
|
6810
|
-
var workspacesFileSchema = object({
|
|
6891
|
+
var workspacesFileSchema = object({
|
|
6892
|
+
workspaces: array(workspaceConfigSchema).optional(),
|
|
6893
|
+
models: object({ roles: unknown().optional() }).passthrough().optional()
|
|
6894
|
+
}).passthrough().superRefine((file, context) => {
|
|
6811
6895
|
const names = new Set;
|
|
6812
6896
|
for (const [index, workspace] of (file.workspaces ?? []).entries()) {
|
|
6813
6897
|
if (names.has(workspace.name)) {
|
|
@@ -6820,10 +6904,213 @@ var workspacesFileSchema = object({ workspaces: array(workspaceConfigSchema).opt
|
|
|
6820
6904
|
names.add(workspace.name);
|
|
6821
6905
|
}
|
|
6822
6906
|
});
|
|
6907
|
+
var globToRegExp = (glob) => {
|
|
6908
|
+
let out = "";
|
|
6909
|
+
for (let i = 0;i < glob.length; i++) {
|
|
6910
|
+
const c = glob[i];
|
|
6911
|
+
if (c === "*") {
|
|
6912
|
+
if (glob[i + 1] === "*") {
|
|
6913
|
+
if (glob[i + 2] === "/") {
|
|
6914
|
+
if (out === "")
|
|
6915
|
+
out += "/?";
|
|
6916
|
+
out += "(?:[^/]+/)*";
|
|
6917
|
+
i += 2;
|
|
6918
|
+
} else {
|
|
6919
|
+
if (i + 2 >= glob.length) {
|
|
6920
|
+
if (out.endsWith("/")) {
|
|
6921
|
+
out = out.slice(0, -1);
|
|
6922
|
+
out += "(?:/.*)?";
|
|
6923
|
+
} else {
|
|
6924
|
+
out += ".*";
|
|
6925
|
+
}
|
|
6926
|
+
} else {
|
|
6927
|
+
out += ".*";
|
|
6928
|
+
}
|
|
6929
|
+
i++;
|
|
6930
|
+
}
|
|
6931
|
+
} else {
|
|
6932
|
+
out += "[^/]*";
|
|
6933
|
+
}
|
|
6934
|
+
} else {
|
|
6935
|
+
out += c.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
|
|
6936
|
+
}
|
|
6937
|
+
}
|
|
6938
|
+
return new RegExp(`^${out}$`);
|
|
6939
|
+
};
|
|
6940
|
+
var matchWorkspace = (glob, target) => globToRegExp(glob.replaceAll("\\", "/")).test(target.replaceAll("\\", "/"));
|
|
6941
|
+
var UNSUPPORTED_GLOB = /[?[\]{}]/;
|
|
6942
|
+
var UNSUPPORTED_EXTGLOB = /[@+*]\(|!/;
|
|
6943
|
+
var validateWorkspaceGlob = (glob) => {
|
|
6944
|
+
const trimmed = glob.trim();
|
|
6945
|
+
if (!trimmed)
|
|
6946
|
+
return { ok: false, error: "workspace pattern is required" };
|
|
6947
|
+
const m = UNSUPPORTED_GLOB.exec(trimmed);
|
|
6948
|
+
if (m) {
|
|
6949
|
+
return {
|
|
6950
|
+
ok: false,
|
|
6951
|
+
error: `unsupported glob character ${JSON.stringify(m[0])} in workspace pattern ${JSON.stringify(glob)} — the matcher supports * and ** only (e.g. /work/**)`
|
|
6952
|
+
};
|
|
6953
|
+
}
|
|
6954
|
+
const ext = UNSUPPORTED_EXTGLOB.exec(trimmed);
|
|
6955
|
+
if (ext) {
|
|
6956
|
+
const token = ext[0];
|
|
6957
|
+
const kind = token === "!" ? "negation (!)" : `extglob (${token})`;
|
|
6958
|
+
return {
|
|
6959
|
+
ok: false,
|
|
6960
|
+
error: `unsupported glob ${kind} in workspace pattern ${JSON.stringify(glob)} — the matcher supports * and ** only (e.g. /work/**)`
|
|
6961
|
+
};
|
|
6962
|
+
}
|
|
6963
|
+
return { ok: true };
|
|
6964
|
+
};
|
|
6965
|
+
|
|
6966
|
+
class WorkspaceConfigError extends Error {
|
|
6967
|
+
name = "WorkspaceConfigError";
|
|
6968
|
+
}
|
|
6823
6969
|
var mainCheckouts = new Map;
|
|
6970
|
+
var mainCheckoutOf = (cwd) => {
|
|
6971
|
+
const cached = mainCheckouts.get(cwd);
|
|
6972
|
+
if (cached !== undefined)
|
|
6973
|
+
return cached;
|
|
6974
|
+
const env = { ...process.env };
|
|
6975
|
+
for (const name of ["GIT_DIR", "GIT_WORK_TREE", "GIT_COMMON_DIR", "GIT_INDEX_FILE"])
|
|
6976
|
+
delete env[name];
|
|
6977
|
+
const git = (args) => {
|
|
6978
|
+
const run = spawnSync("git", args, {
|
|
6979
|
+
cwd,
|
|
6980
|
+
env,
|
|
6981
|
+
encoding: "utf8",
|
|
6982
|
+
timeout: 5000,
|
|
6983
|
+
windowsHide: true
|
|
6984
|
+
});
|
|
6985
|
+
return run.status === 0 ? run.stdout : null;
|
|
6986
|
+
};
|
|
6987
|
+
let main = null;
|
|
6988
|
+
const dirs = git(["rev-parse", "--path-format=absolute", "--git-dir", "--git-common-dir"]);
|
|
6989
|
+
const [gitDir, common] = (dirs ?? "").trim().split(/\r?\n/u);
|
|
6990
|
+
if (gitDir && common && path2.resolve(gitDir) !== path2.resolve(common)) {
|
|
6991
|
+
const listed = /^worktree (.+)$/mu.exec(git(["worktree", "list", "--porcelain"]) ?? "")?.[1];
|
|
6992
|
+
main = listed?.trim() || (path2.basename(common) === ".git" ? path2.dirname(common) : common);
|
|
6993
|
+
}
|
|
6994
|
+
mainCheckouts.set(cwd, main);
|
|
6995
|
+
return main;
|
|
6996
|
+
};
|
|
6997
|
+
var matchingEntries = (cwd, entries) => {
|
|
6998
|
+
const match = (where) => {
|
|
6999
|
+
const targets = [where, realpathOf(where)].map((value) => value.replaceAll("\\", "/"));
|
|
7000
|
+
return entries.filter((entry) => {
|
|
7001
|
+
const glob = entry.glob.replaceAll("\\", "/");
|
|
7002
|
+
const canonical = canonicalGlob(glob);
|
|
7003
|
+
return targets.some((target) => matchWorkspace(glob, target) || canonical !== glob && matchWorkspace(canonical, target));
|
|
7004
|
+
});
|
|
7005
|
+
};
|
|
7006
|
+
const direct = match(cwd);
|
|
7007
|
+
if (direct.length)
|
|
7008
|
+
return direct;
|
|
7009
|
+
const main = mainCheckoutOf(cwd);
|
|
7010
|
+
return main ? match(main) : direct;
|
|
7011
|
+
};
|
|
7012
|
+
var realpathOf = (p) => {
|
|
7013
|
+
const real = realpathSync.native ?? realpathSync;
|
|
7014
|
+
try {
|
|
7015
|
+
return real(p);
|
|
7016
|
+
} catch {
|
|
7017
|
+
return p;
|
|
7018
|
+
}
|
|
7019
|
+
};
|
|
7020
|
+
var canonicalGlob = (glob) => {
|
|
7021
|
+
const m = /[*?[\]{]/.exec(glob);
|
|
7022
|
+
const prefix = m ? glob.slice(0, m.index) : glob;
|
|
7023
|
+
const rest = m ? glob.slice(m.index) : "";
|
|
7024
|
+
if (!prefix)
|
|
7025
|
+
return glob;
|
|
7026
|
+
const real = realpathOf(prefix.replace(/\/+$/, "") || "/");
|
|
7027
|
+
return real + (prefix.endsWith("/") ? "/" : "") + rest;
|
|
7028
|
+
};
|
|
7029
|
+
var globSpecificity = (glob) => glob.replaceAll("\\", "/").split("/").filter((segment) => segment.length > 0 && !/[*?[\]{]/.test(segment)).length;
|
|
7030
|
+
var selectWorkspaceMatch = (matches, cwd, workspaceName) => {
|
|
7031
|
+
if (workspaceName !== undefined) {
|
|
7032
|
+
const named = matches.filter((entry) => entry.name === workspaceName);
|
|
7033
|
+
if (named.length === 1)
|
|
7034
|
+
return named[0];
|
|
7035
|
+
if (named.length > 1)
|
|
7036
|
+
throw new WorkspaceConfigError(`ambiguous workspace ${JSON.stringify(workspaceName)} for ${cwd}`);
|
|
7037
|
+
if (matches.length > 0) {
|
|
7038
|
+
throw new WorkspaceConfigError(`workspace ${JSON.stringify(workspaceName)} does not match ${cwd}; matching choices: ${matches.map((entry) => entry.name).join(", ")}`);
|
|
7039
|
+
}
|
|
7040
|
+
throw new WorkspaceConfigError(`workspace ${JSON.stringify(workspaceName)} does not match ${cwd}`);
|
|
7041
|
+
}
|
|
7042
|
+
if (matches.length < 2)
|
|
7043
|
+
return matches[0];
|
|
7044
|
+
const highestSpecificity = Math.max(...matches.map((entry) => globSpecificity(entry.glob)));
|
|
7045
|
+
const mostSpecific = matches.filter((entry) => globSpecificity(entry.glob) === highestSpecificity);
|
|
7046
|
+
if (mostSpecific.length > 1) {
|
|
7047
|
+
throw new WorkspaceConfigError(`ambiguous workspace for ${cwd}; choose one of: ${mostSpecific.map((entry) => entry.name).join(", ")}`);
|
|
7048
|
+
}
|
|
7049
|
+
return mostSpecific[0];
|
|
7050
|
+
};
|
|
6824
7051
|
var runtimeWorkspaceIndexSchema = object({
|
|
6825
7052
|
workspaces: array(object({ name: nonBlank, glob: nonBlank }).passthrough()).optional()
|
|
6826
7053
|
}).passthrough();
|
|
7054
|
+
var matchRuntimeWorkspace = (cwd, dir = configDir()) => {
|
|
7055
|
+
const file = path2.join(dir, "workspaces.json");
|
|
7056
|
+
let raw;
|
|
7057
|
+
try {
|
|
7058
|
+
raw = readFileSync2(file, "utf8");
|
|
7059
|
+
} catch (error) {
|
|
7060
|
+
if (error.code === "ENOENT")
|
|
7061
|
+
return null;
|
|
7062
|
+
throw new WorkspaceConfigError(`${file} could not be read: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
7063
|
+
}
|
|
7064
|
+
let parsed;
|
|
7065
|
+
try {
|
|
7066
|
+
parsed = JSON.parse(raw);
|
|
7067
|
+
} catch {
|
|
7068
|
+
throw new WorkspaceConfigError(`${file} is not valid JSON`);
|
|
7069
|
+
}
|
|
7070
|
+
const validated = runtimeWorkspaceIndexSchema.safeParse(parsed);
|
|
7071
|
+
if (!validated.success) {
|
|
7072
|
+
const detail = validated.error.issues.map((issue) => `${issue.path.map(String).join(".") || "workspaces"}: ${issue.message}`).join("; ");
|
|
7073
|
+
throw new WorkspaceConfigError(`${file} has invalid workspace matching data: ${detail}`);
|
|
7074
|
+
}
|
|
7075
|
+
const entries = validated.data.workspaces;
|
|
7076
|
+
for (const entry of entries ?? []) {
|
|
7077
|
+
const glob = validateWorkspaceGlob(entry.glob);
|
|
7078
|
+
if (!glob.ok)
|
|
7079
|
+
throw new WorkspaceConfigError(`${file} workspace ${entry.name}: ${glob.error}`);
|
|
7080
|
+
}
|
|
7081
|
+
const matches = matchingEntries(cwd, entries ?? []);
|
|
7082
|
+
const workspaceName = process.env.WORKFLOW_WORKSPACE_NAME?.trim() || undefined;
|
|
7083
|
+
const selected = selectWorkspaceMatch(matches, cwd, workspaceName);
|
|
7084
|
+
return selected ? { file, selected, matches } : null;
|
|
7085
|
+
};
|
|
7086
|
+
var modelSources = (cwd, dir) => {
|
|
7087
|
+
const out = [];
|
|
7088
|
+
try {
|
|
7089
|
+
const matched = matchRuntimeWorkspace(cwd, dir);
|
|
7090
|
+
if (matched) {
|
|
7091
|
+
const enclosing = matched.matches.filter((entry) => entry !== matched.selected).toSorted((a, b) => globSpecificity(b.glob) - globSpecificity(a.glob));
|
|
7092
|
+
for (const entry of [matched.selected, ...enclosing])
|
|
7093
|
+
out.push({
|
|
7094
|
+
name: entry.name,
|
|
7095
|
+
global: false,
|
|
7096
|
+
models: entry.models,
|
|
7097
|
+
tierModels: entry.fanout?.tierModels
|
|
7098
|
+
});
|
|
7099
|
+
}
|
|
7100
|
+
} catch {}
|
|
7101
|
+
try {
|
|
7102
|
+
const document = JSON.parse(readFileSync2(path2.join(dir ?? configDir(), "workspaces.json"), "utf8"));
|
|
7103
|
+
if (document && typeof document === "object" && !Array.isArray(document))
|
|
7104
|
+
out.push({
|
|
7105
|
+
name: "global",
|
|
7106
|
+
global: true,
|
|
7107
|
+
models: document.models,
|
|
7108
|
+
tierModels: undefined
|
|
7109
|
+
});
|
|
7110
|
+
} catch {}
|
|
7111
|
+
return out;
|
|
7112
|
+
};
|
|
7113
|
+
var hostFamily = (host) => host.replace(/_(?:cli|desktop)$/u, "");
|
|
6827
7114
|
var TIER_KEYS = new Set(["mundane", "standard", "hard"]);
|
|
6828
7115
|
var TIER_HOSTS = new Set([
|
|
6829
7116
|
"claude_code",
|
|
@@ -6837,11 +7124,11 @@ var TIER_HOSTS = new Set([
|
|
|
6837
7124
|
]);
|
|
6838
7125
|
|
|
6839
7126
|
// packages/workit-core/src/git/rev.ts
|
|
6840
|
-
import { spawnSync } from "node:child_process";
|
|
7127
|
+
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
6841
7128
|
var MAX_BUFFER = 256 * 1024 * 1024;
|
|
6842
7129
|
var GIT_TIMEOUTS = { local: 20000, worktree: 120000, network: 15000 };
|
|
6843
7130
|
var git = (cwd, args, options = {}) => {
|
|
6844
|
-
const result =
|
|
7131
|
+
const result = spawnSync2("git", args, {
|
|
6845
7132
|
cwd,
|
|
6846
7133
|
encoding: "utf8",
|
|
6847
7134
|
env: options.env ?? process.env,
|
|
@@ -6890,7 +7177,7 @@ var memo2 = new Map;
|
|
|
6890
7177
|
var TRACKERS = new Set(["github", "gitlab", "youtrack"]);
|
|
6891
7178
|
|
|
6892
7179
|
// packages/workit-core/src/core/logger.ts
|
|
6893
|
-
import
|
|
7180
|
+
import os2 from "node:os";
|
|
6894
7181
|
var SENSITIVE_WORDS = new Set([
|
|
6895
7182
|
"token",
|
|
6896
7183
|
"secret",
|
|
@@ -6929,15 +7216,15 @@ var SENSITIVE_WORDS = new Set([
|
|
|
6929
7216
|
]);
|
|
6930
7217
|
var STACK_WORDS = new Set(["stack", "stacktrace", "trace"]);
|
|
6931
7218
|
var escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
6932
|
-
var homePattern = new RegExp(`${escapeRegExp(
|
|
7219
|
+
var homePattern = new RegExp(`${escapeRegExp(os2.homedir())}(?=[/\\\\]|$)|\\$HOME(?=[/\\\\]|$)`, "g");
|
|
6933
7220
|
|
|
6934
7221
|
// packages/workit-core/src/store/paths.ts
|
|
6935
|
-
import { spawnSync as
|
|
7222
|
+
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
6936
7223
|
import fs from "node:fs";
|
|
6937
|
-
import
|
|
7224
|
+
import path3 from "node:path";
|
|
6938
7225
|
var NOT_A_REPO = /not a git repository \(or any (of the parent directories|parent up to)/u;
|
|
6939
7226
|
var gitRun = (cwd, args) => {
|
|
6940
|
-
const run =
|
|
7227
|
+
const run = spawnSync3("git", args, {
|
|
6941
7228
|
cwd,
|
|
6942
7229
|
encoding: "utf8",
|
|
6943
7230
|
timeout: 20000,
|
|
@@ -6975,14 +7262,14 @@ var DISCOVERY_ENV = [
|
|
|
6975
7262
|
];
|
|
6976
7263
|
var isGitDir = (dir) => {
|
|
6977
7264
|
try {
|
|
6978
|
-
return fs.statSync(
|
|
7265
|
+
return fs.statSync(path3.join(dir, "HEAD")).isFile() && fs.statSync(path3.join(dir, "objects")).isDirectory() && fs.statSync(path3.join(dir, "refs")).isDirectory();
|
|
6979
7266
|
} catch {
|
|
6980
7267
|
return false;
|
|
6981
7268
|
}
|
|
6982
7269
|
};
|
|
6983
7270
|
var reftableRefs = (common) => {
|
|
6984
7271
|
try {
|
|
6985
|
-
return /^\s*refstorage\s*=\s*reftable\s*$/imu.test(fs.readFileSync(
|
|
7272
|
+
return /^\s*refstorage\s*=\s*reftable\s*$/imu.test(fs.readFileSync(path3.join(common, "config"), "utf8"));
|
|
6986
7273
|
} catch {
|
|
6987
7274
|
return false;
|
|
6988
7275
|
}
|
|
@@ -7002,7 +7289,7 @@ function fastGit(root) {
|
|
|
7002
7289
|
if (device !== null && stat.dev !== device)
|
|
7003
7290
|
return { kind: "none" };
|
|
7004
7291
|
device = stat.dev;
|
|
7005
|
-
const dotGit =
|
|
7292
|
+
const dotGit = path3.join(dir, ".git");
|
|
7006
7293
|
let entry = null;
|
|
7007
7294
|
try {
|
|
7008
7295
|
entry = fs.statSync(dotGit);
|
|
@@ -7023,19 +7310,19 @@ function fastGit(root) {
|
|
|
7023
7310
|
const match = /^gitdir: (.+)$/mu.exec(text);
|
|
7024
7311
|
if (!match)
|
|
7025
7312
|
return null;
|
|
7026
|
-
gitDir =
|
|
7313
|
+
gitDir = path3.resolve(dir, match[1].trim());
|
|
7027
7314
|
} else
|
|
7028
7315
|
return null;
|
|
7029
|
-
if (!fs.existsSync(
|
|
7316
|
+
if (!fs.existsSync(path3.join(gitDir, "HEAD")))
|
|
7030
7317
|
return null;
|
|
7031
7318
|
} else if (isGitDir(dir))
|
|
7032
7319
|
gitDir = dir;
|
|
7033
7320
|
if (gitDir) {
|
|
7034
7321
|
let common = gitDir;
|
|
7035
7322
|
try {
|
|
7036
|
-
common =
|
|
7323
|
+
common = path3.resolve(gitDir, fs.readFileSync(path3.join(gitDir, "commondir"), "utf8").trim());
|
|
7037
7324
|
} catch {}
|
|
7038
|
-
if (!fs.existsSync(
|
|
7325
|
+
if (!fs.existsSync(path3.join(common, "objects")))
|
|
7039
7326
|
return null;
|
|
7040
7327
|
return {
|
|
7041
7328
|
kind: "repo",
|
|
@@ -7045,26 +7332,26 @@ function fastGit(root) {
|
|
|
7045
7332
|
reftable: reftableRefs(common)
|
|
7046
7333
|
};
|
|
7047
7334
|
}
|
|
7048
|
-
const parent =
|
|
7335
|
+
const parent = path3.dirname(dir);
|
|
7049
7336
|
if (parent === dir)
|
|
7050
7337
|
return { kind: "none" };
|
|
7051
7338
|
dir = parent;
|
|
7052
7339
|
}
|
|
7053
7340
|
}
|
|
7054
7341
|
function resolveStore(root) {
|
|
7055
|
-
root =
|
|
7342
|
+
root = path3.resolve(root);
|
|
7056
7343
|
let directory = false;
|
|
7057
7344
|
try {
|
|
7058
7345
|
directory = fs.statSync(root).isDirectory();
|
|
7059
7346
|
} catch {}
|
|
7060
7347
|
if (!directory)
|
|
7061
|
-
return { dir:
|
|
7348
|
+
return { dir: path3.join(root, ".workit"), shared: false, top: null };
|
|
7062
7349
|
const fast = fastGit(root);
|
|
7063
7350
|
if (fast?.kind === "none")
|
|
7064
|
-
return { dir:
|
|
7351
|
+
return { dir: path3.join(root, ".workit"), shared: false, top: null };
|
|
7065
7352
|
if (fast?.kind === "repo")
|
|
7066
7353
|
return {
|
|
7067
|
-
dir:
|
|
7354
|
+
dir: path3.join(fast.common, "workit"),
|
|
7068
7355
|
shared: true,
|
|
7069
7356
|
top: fast.top,
|
|
7070
7357
|
git: { gitDir: fast.gitDir, top: fast.top, reftable: fast.reftable }
|
|
@@ -7074,13 +7361,13 @@ function resolveStore(root) {
|
|
|
7074
7361
|
if (run.ok && common) {
|
|
7075
7362
|
const top = gitRun(root, ["rev-parse", "--path-format=absolute", "--show-toplevel"]);
|
|
7076
7363
|
return {
|
|
7077
|
-
dir:
|
|
7364
|
+
dir: path3.join(real(path3.resolve(root, common)), "workit"),
|
|
7078
7365
|
shared: true,
|
|
7079
7366
|
top: top.ok && top.stdout.trim() ? real(top.stdout.trim()) : null
|
|
7080
7367
|
};
|
|
7081
7368
|
}
|
|
7082
7369
|
if (run.missing || !run.ok && NOT_A_REPO.test(run.stderr))
|
|
7083
|
-
return { dir:
|
|
7370
|
+
return { dir: path3.join(root, ".workit"), shared: false, top: null };
|
|
7084
7371
|
return new Error(`cannot locate the workit store: git rev-parse failed (${run.stderr.trim().split(`
|
|
7085
7372
|
`)[0] || "no output"}); fix the repository (git status should work here)`);
|
|
7086
7373
|
}
|
|
@@ -7095,22 +7382,22 @@ function childSessionId(lead, child) {
|
|
|
7095
7382
|
}
|
|
7096
7383
|
|
|
7097
7384
|
// packages/workit-core/src/core/package-root.ts
|
|
7098
|
-
import { existsSync } from "node:fs";
|
|
7099
|
-
import
|
|
7385
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
7386
|
+
import path4 from "node:path";
|
|
7100
7387
|
import { fileURLToPath } from "node:url";
|
|
7101
7388
|
var packageRoot = () => {
|
|
7102
|
-
let dir =
|
|
7389
|
+
let dir = path4.dirname(fileURLToPath(import.meta.url));
|
|
7103
7390
|
while (true) {
|
|
7104
|
-
const parent =
|
|
7105
|
-
if (
|
|
7391
|
+
const parent = path4.dirname(dir);
|
|
7392
|
+
if (existsSync2(path4.join(dir, "package.json")) || parent === dir)
|
|
7106
7393
|
return dir;
|
|
7107
7394
|
dir = parent;
|
|
7108
7395
|
}
|
|
7109
7396
|
};
|
|
7110
7397
|
var assetRoot = () => {
|
|
7111
7398
|
const root = packageRoot();
|
|
7112
|
-
const assets =
|
|
7113
|
-
return
|
|
7399
|
+
const assets = path4.join(root, "assets");
|
|
7400
|
+
return existsSync2(assets) ? assets : root;
|
|
7114
7401
|
};
|
|
7115
7402
|
|
|
7116
7403
|
// packages/workit-core/src/core/store-lock.ts
|
|
@@ -7162,41 +7449,139 @@ var STALE_TEMPORARY_MS = 60 * 60000;
|
|
|
7162
7449
|
var origins = new Map;
|
|
7163
7450
|
var heldInProcess = new Map;
|
|
7164
7451
|
// packages/workit-core/src/ledger.ts
|
|
7165
|
-
import { spawnSync as
|
|
7452
|
+
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
7166
7453
|
import { createHash as createHash3, randomBytes } from "node:crypto";
|
|
7167
7454
|
import fs3 from "node:fs";
|
|
7168
|
-
import
|
|
7455
|
+
import path6 from "node:path";
|
|
7456
|
+
|
|
7457
|
+
// packages/workit-core/src/core/policy/substance.ts
|
|
7458
|
+
var SLASH_BLOCK = [["/*", "*/"]];
|
|
7459
|
+
var C_LIKE = { line: ["//"], block: SLASH_BLOCK, quotes: `"'` };
|
|
7460
|
+
var SYNTAXES = Object.fromEntries([
|
|
7461
|
+
...["ts", "mts", "cts", "js", "mjs", "cjs"].map((ext) => [ext, { ...C_LIKE, js: true }]),
|
|
7462
|
+
...["java", "kt", "kts", "scala", "swift", "dart", "groovy"].map((ext) => [
|
|
7463
|
+
ext,
|
|
7464
|
+
{ ...C_LIKE, triple: true }
|
|
7465
|
+
]),
|
|
7466
|
+
["go", { ...C_LIKE, rawBacktick: true }],
|
|
7467
|
+
...["css", "scss", "less"].map((ext) => [
|
|
7468
|
+
ext,
|
|
7469
|
+
{ line: [], block: SLASH_BLOCK, quotes: `"'`, cssUrl: true }
|
|
7470
|
+
]),
|
|
7471
|
+
...["py", "pyi"].map((ext) => [
|
|
7472
|
+
ext,
|
|
7473
|
+
{ line: ["#"], block: [], quotes: `"'`, triple: true, indented: true, fstring: true }
|
|
7474
|
+
]),
|
|
7475
|
+
["toml", { line: ["#"], block: [], quotes: `"`, literal: "'", triple: true }],
|
|
7476
|
+
...["html", "htm", "xml", "svg", "xhtml"].map((ext) => [
|
|
7477
|
+
ext,
|
|
7478
|
+
{ line: [], block: [["<!--", "-->"]], quotes: "", indented: true }
|
|
7479
|
+
])
|
|
7480
|
+
]);
|
|
7481
|
+
var REGEX_KEYWORDS = new Set([
|
|
7482
|
+
"return",
|
|
7483
|
+
"typeof",
|
|
7484
|
+
"instanceof",
|
|
7485
|
+
"case",
|
|
7486
|
+
"do",
|
|
7487
|
+
"else",
|
|
7488
|
+
"in",
|
|
7489
|
+
"of",
|
|
7490
|
+
"new",
|
|
7491
|
+
"delete",
|
|
7492
|
+
"void",
|
|
7493
|
+
"throw",
|
|
7494
|
+
"yield",
|
|
7495
|
+
"await"
|
|
7496
|
+
]);
|
|
7497
|
+
var decoder = new TextDecoder("utf-8", { fatal: true });
|
|
7498
|
+
|
|
7499
|
+
// packages/workit-core/src/core/policy/lane.ts
|
|
7500
|
+
var RISK_TOKENS = new Set([
|
|
7501
|
+
"auth",
|
|
7502
|
+
"authn",
|
|
7503
|
+
"authz",
|
|
7504
|
+
"oauth",
|
|
7505
|
+
"security",
|
|
7506
|
+
"permission",
|
|
7507
|
+
"permissions",
|
|
7508
|
+
"secret",
|
|
7509
|
+
"secrets",
|
|
7510
|
+
"crypto",
|
|
7511
|
+
"gate",
|
|
7512
|
+
"gates",
|
|
7513
|
+
"policy",
|
|
7514
|
+
"policies",
|
|
7515
|
+
"hook",
|
|
7516
|
+
"hooks",
|
|
7517
|
+
"husky",
|
|
7518
|
+
"lefthook",
|
|
7519
|
+
"release",
|
|
7520
|
+
"releases",
|
|
7521
|
+
"migration",
|
|
7522
|
+
"migrations",
|
|
7523
|
+
"migrate",
|
|
7524
|
+
"workflows"
|
|
7525
|
+
]);
|
|
7526
|
+
var RISK_FILES = new Set([
|
|
7527
|
+
".gitlab-ci.yml",
|
|
7528
|
+
"Jenkinsfile",
|
|
7529
|
+
"azure-pipelines.yml",
|
|
7530
|
+
".pre-commit-config.yaml",
|
|
7531
|
+
".workit/risk-paths"
|
|
7532
|
+
]);
|
|
7533
|
+
var RISK_NAMES = new Set([".gitattributes"]);
|
|
7534
|
+
var LOCKFILES = new Set([
|
|
7535
|
+
"bun.lock",
|
|
7536
|
+
"bun.lockb",
|
|
7537
|
+
"package-lock.json",
|
|
7538
|
+
"npm-shrinkwrap.json",
|
|
7539
|
+
"yarn.lock",
|
|
7540
|
+
"pnpm-lock.yaml",
|
|
7541
|
+
"Cargo.lock",
|
|
7542
|
+
"go.sum",
|
|
7543
|
+
"poetry.lock",
|
|
7544
|
+
"uv.lock",
|
|
7545
|
+
"Pipfile.lock",
|
|
7546
|
+
"Gemfile.lock",
|
|
7547
|
+
"composer.lock"
|
|
7548
|
+
]);
|
|
7549
|
+
var globCache = new Map;
|
|
7550
|
+
var REGULAR = new Set(["100644", "100755"]);
|
|
7551
|
+
|
|
7552
|
+
// packages/workit-core/src/core/policy/carry.ts
|
|
7553
|
+
var TEST_ONLY_KINDS = new Set(["doc", "cosmetic", "generated", "test"]);
|
|
7169
7554
|
|
|
7170
7555
|
// packages/workit-core/src/hooks/standing-signal.ts
|
|
7171
7556
|
import { createHash as createHash2 } from "node:crypto";
|
|
7172
7557
|
import fs2 from "node:fs";
|
|
7173
|
-
import
|
|
7558
|
+
import path5 from "node:path";
|
|
7174
7559
|
var gitStoreDir = (cwd) => {
|
|
7175
7560
|
try {
|
|
7176
|
-
for (let dir =
|
|
7177
|
-
const dotGit =
|
|
7561
|
+
for (let dir = path5.resolve(cwd);; dir = path5.dirname(dir)) {
|
|
7562
|
+
const dotGit = path5.join(dir, ".git");
|
|
7178
7563
|
if (fs2.existsSync(dotGit)) {
|
|
7179
7564
|
let gitDir = dotGit;
|
|
7180
7565
|
if (fs2.statSync(dotGit).isFile()) {
|
|
7181
7566
|
const target = /^gitdir:\s*(.+)$/mu.exec(fs2.readFileSync(dotGit, "utf8"))?.[1]?.trim();
|
|
7182
7567
|
if (!target)
|
|
7183
7568
|
return null;
|
|
7184
|
-
gitDir =
|
|
7185
|
-
const common =
|
|
7569
|
+
gitDir = path5.resolve(dir, target);
|
|
7570
|
+
const common = path5.join(gitDir, "commondir");
|
|
7186
7571
|
if (fs2.existsSync(common))
|
|
7187
|
-
gitDir =
|
|
7572
|
+
gitDir = path5.resolve(gitDir, fs2.readFileSync(common, "utf8").trim());
|
|
7188
7573
|
}
|
|
7189
|
-
return
|
|
7574
|
+
return path5.join(gitDir, "workit");
|
|
7190
7575
|
}
|
|
7191
|
-
if (
|
|
7576
|
+
if (path5.dirname(dir) === dir)
|
|
7192
7577
|
return null;
|
|
7193
7578
|
}
|
|
7194
7579
|
} catch {
|
|
7195
7580
|
return null;
|
|
7196
7581
|
}
|
|
7197
7582
|
};
|
|
7198
|
-
var standingRevFile = (store) =>
|
|
7199
|
-
var standingSeenFile = (store, session, agentId) =>
|
|
7583
|
+
var standingRevFile = (store) => path5.join(store, "standing", "rev");
|
|
7584
|
+
var standingSeenFile = (store, session, agentId) => path5.join(store, "standing", "seen", `${createHash2("sha256").update(`${session}\x00${agentId ?? ""}`).digest("hex").slice(0, 32)}.json`);
|
|
7200
7585
|
var readStandingRev = (store) => {
|
|
7201
7586
|
try {
|
|
7202
7587
|
return fs2.readFileSync(standingRevFile(store), "utf8").trim() || null;
|
|
@@ -7206,7 +7591,7 @@ var readStandingRev = (store) => {
|
|
|
7206
7591
|
};
|
|
7207
7592
|
var writeStandingSeen = (file, seen) => {
|
|
7208
7593
|
try {
|
|
7209
|
-
fs2.mkdirSync(
|
|
7594
|
+
fs2.mkdirSync(path5.dirname(file), { recursive: true });
|
|
7210
7595
|
fs2.writeFileSync(file, JSON.stringify(seen));
|
|
7211
7596
|
} catch {}
|
|
7212
7597
|
};
|
|
@@ -7229,7 +7614,7 @@ var err = (code, error, unblock) => ({
|
|
|
7229
7614
|
...unblock ? { unblock } : {}
|
|
7230
7615
|
});
|
|
7231
7616
|
var gitRun2 = (cwd, args, timeoutMs = GIT_TIMEOUTS.local) => {
|
|
7232
|
-
const run =
|
|
7617
|
+
const run = spawnSync4("git", args, {
|
|
7233
7618
|
cwd,
|
|
7234
7619
|
encoding: "utf8",
|
|
7235
7620
|
timeout: timeoutMs,
|
|
@@ -7257,14 +7642,14 @@ var git2 = (cwd, args) => {
|
|
|
7257
7642
|
};
|
|
7258
7643
|
var safeRef = (value) => value.length > 0 && !value.startsWith("-");
|
|
7259
7644
|
function storeRoot(cwd) {
|
|
7260
|
-
const location = resolveStore(
|
|
7645
|
+
const location = resolveStore(path6.resolve(cwd));
|
|
7261
7646
|
if (location instanceof Error)
|
|
7262
7647
|
return err("unavailable", location.message.replace(/; fix the repository.*$/u, ""), "fix the repository (git status should work here) or run from a non-git directory");
|
|
7263
7648
|
return { ok: true, value: { root: location.dir, shared: location.shared } };
|
|
7264
7649
|
}
|
|
7265
7650
|
function ledgerPath(cwd) {
|
|
7266
7651
|
const root = storeRoot(cwd);
|
|
7267
|
-
return root.ok ? { ok: true, value:
|
|
7652
|
+
return root.ok ? { ok: true, value: path6.join(root.value.root, "ledger", "ledger.jsonl") } : root;
|
|
7268
7653
|
}
|
|
7269
7654
|
var NETWORK_FS_TYPES = new Set([
|
|
7270
7655
|
26985,
|
|
@@ -7506,6 +7891,7 @@ var SHELL_VOUCHED_HOSTS = new Set([
|
|
|
7506
7891
|
"codex_cli",
|
|
7507
7892
|
"codex_desktop"
|
|
7508
7893
|
]);
|
|
7894
|
+
var restackExact = new WeakMap;
|
|
7509
7895
|
var fromLead = (row, leads) => leads === null || row.actor.session !== null && leads.includes(row.actor.session);
|
|
7510
7896
|
function activeStanding(rows, fanout, leads = null) {
|
|
7511
7897
|
const active = [];
|
|
@@ -7534,109 +7920,6 @@ var OBSERVED_ONLY = new Set([
|
|
|
7534
7920
|
"policy.judged",
|
|
7535
7921
|
...PR_ROW_TYPES
|
|
7536
7922
|
]);
|
|
7537
|
-
// packages/workit-core/src/forge/redact.ts
|
|
7538
|
-
var KEY = String.raw`[A-Za-z0-9_.-]*?(?:token|secret|password|passwd|pwd|api[_-]?key|access[_-]?key|account[_-]?key|private[_-]?key|client[_-]?secret|credentials?|authorization|cookie|signature)[A-Za-z0-9_.-]*`;
|
|
7539
|
-
var ASSIGNMENT = new RegExp(String.raw`(?<![A-Za-z0-9])(["']?${KEY}["']?\s*[:=]\s*["']?)((?:bearer|basic|token|digest)\s+)?([^\s"',;&]+)`, "giu");
|
|
7540
|
-
var QUOTED_ASSIGNMENT = new RegExp(String.raw`(?<![A-Za-z0-9])(["']?${KEY}["']?\s*[:=]\s*)(["'])([^"'\n]*[^\s"'][^"'\n]*)\2`, "giu");
|
|
7541
|
-
var ANSI = new RegExp(String.raw`\u001b\[[0-9;?]*[ -/]*[@-~]|\u001b\][^\u0007]*\u0007`, "gu");
|
|
7542
|
-
|
|
7543
|
-
// packages/workit-core/src/git/ops.ts
|
|
7544
|
-
var COMMIT_TIMEOUT_MS = 10 * 60000;
|
|
7545
|
-
|
|
7546
|
-
// packages/workit-core/src/core/policy/substance.ts
|
|
7547
|
-
var SLASH_BLOCK = [["/*", "*/"]];
|
|
7548
|
-
var C_LIKE = { line: ["//"], block: SLASH_BLOCK, quotes: `"'` };
|
|
7549
|
-
var SYNTAXES = Object.fromEntries([
|
|
7550
|
-
...["ts", "mts", "cts", "js", "mjs", "cjs"].map((ext) => [ext, { ...C_LIKE, js: true }]),
|
|
7551
|
-
...["java", "kt", "kts", "scala", "swift", "dart", "groovy"].map((ext) => [
|
|
7552
|
-
ext,
|
|
7553
|
-
{ ...C_LIKE, triple: true }
|
|
7554
|
-
]),
|
|
7555
|
-
["go", { ...C_LIKE, rawBacktick: true }],
|
|
7556
|
-
...["css", "scss", "less"].map((ext) => [
|
|
7557
|
-
ext,
|
|
7558
|
-
{ line: [], block: SLASH_BLOCK, quotes: `"'`, cssUrl: true }
|
|
7559
|
-
]),
|
|
7560
|
-
...["py", "pyi"].map((ext) => [
|
|
7561
|
-
ext,
|
|
7562
|
-
{ line: ["#"], block: [], quotes: `"'`, triple: true, indented: true, fstring: true }
|
|
7563
|
-
]),
|
|
7564
|
-
["toml", { line: ["#"], block: [], quotes: `"`, literal: "'", triple: true }],
|
|
7565
|
-
...["html", "htm", "xml", "svg", "xhtml"].map((ext) => [
|
|
7566
|
-
ext,
|
|
7567
|
-
{ line: [], block: [["<!--", "-->"]], quotes: "", indented: true }
|
|
7568
|
-
])
|
|
7569
|
-
]);
|
|
7570
|
-
var REGEX_KEYWORDS = new Set([
|
|
7571
|
-
"return",
|
|
7572
|
-
"typeof",
|
|
7573
|
-
"instanceof",
|
|
7574
|
-
"case",
|
|
7575
|
-
"do",
|
|
7576
|
-
"else",
|
|
7577
|
-
"in",
|
|
7578
|
-
"of",
|
|
7579
|
-
"new",
|
|
7580
|
-
"delete",
|
|
7581
|
-
"void",
|
|
7582
|
-
"throw",
|
|
7583
|
-
"yield",
|
|
7584
|
-
"await"
|
|
7585
|
-
]);
|
|
7586
|
-
var decoder = new TextDecoder("utf-8", { fatal: true });
|
|
7587
|
-
|
|
7588
|
-
// packages/workit-core/src/core/policy/lane.ts
|
|
7589
|
-
var RISK_TOKENS = new Set([
|
|
7590
|
-
"auth",
|
|
7591
|
-
"authn",
|
|
7592
|
-
"authz",
|
|
7593
|
-
"oauth",
|
|
7594
|
-
"security",
|
|
7595
|
-
"permission",
|
|
7596
|
-
"permissions",
|
|
7597
|
-
"secret",
|
|
7598
|
-
"secrets",
|
|
7599
|
-
"crypto",
|
|
7600
|
-
"gate",
|
|
7601
|
-
"gates",
|
|
7602
|
-
"policy",
|
|
7603
|
-
"policies",
|
|
7604
|
-
"hook",
|
|
7605
|
-
"hooks",
|
|
7606
|
-
"husky",
|
|
7607
|
-
"lefthook",
|
|
7608
|
-
"release",
|
|
7609
|
-
"releases",
|
|
7610
|
-
"migration",
|
|
7611
|
-
"migrations",
|
|
7612
|
-
"migrate",
|
|
7613
|
-
"workflows"
|
|
7614
|
-
]);
|
|
7615
|
-
var RISK_FILES = new Set([
|
|
7616
|
-
".gitlab-ci.yml",
|
|
7617
|
-
"Jenkinsfile",
|
|
7618
|
-
"azure-pipelines.yml",
|
|
7619
|
-
".pre-commit-config.yaml",
|
|
7620
|
-
".workit/risk-paths"
|
|
7621
|
-
]);
|
|
7622
|
-
var RISK_NAMES = new Set([".gitattributes"]);
|
|
7623
|
-
var LOCKFILES = new Set([
|
|
7624
|
-
"bun.lock",
|
|
7625
|
-
"bun.lockb",
|
|
7626
|
-
"package-lock.json",
|
|
7627
|
-
"npm-shrinkwrap.json",
|
|
7628
|
-
"yarn.lock",
|
|
7629
|
-
"pnpm-lock.yaml",
|
|
7630
|
-
"Cargo.lock",
|
|
7631
|
-
"go.sum",
|
|
7632
|
-
"poetry.lock",
|
|
7633
|
-
"uv.lock",
|
|
7634
|
-
"Pipfile.lock",
|
|
7635
|
-
"Gemfile.lock",
|
|
7636
|
-
"composer.lock"
|
|
7637
|
-
]);
|
|
7638
|
-
var globCache = new Map;
|
|
7639
|
-
var REGULAR = new Set(["100644", "100755"]);
|
|
7640
7923
|
// packages/workit-core/src/hooks/raw-git.ts
|
|
7641
7924
|
var SHELLS = new Set(["sh", "bash", "zsh", "dash", "ksh", "ash", "mksh", "yash", "fish"]);
|
|
7642
7925
|
var POWERSHELLS = new Set(["pwsh", "powershell"]);
|
|
@@ -7825,11 +8108,97 @@ var contextReadSchema = object({
|
|
|
7825
8108
|
planPath: string2().optional(),
|
|
7826
8109
|
cwd: string2().min(1).optional()
|
|
7827
8110
|
}).strict();
|
|
8111
|
+
// packages/workit-core/src/core/role-models.ts
|
|
8112
|
+
var MODEL_ROLES = [
|
|
8113
|
+
"decider",
|
|
8114
|
+
"implementer",
|
|
8115
|
+
"verifier",
|
|
8116
|
+
"reviewer",
|
|
8117
|
+
"explore",
|
|
8118
|
+
"babysit"
|
|
8119
|
+
];
|
|
8120
|
+
var MODEL_TIERS = ["mundane", "standard", "hard"];
|
|
8121
|
+
var HOST_KEYS = new Set([
|
|
8122
|
+
"claude_code",
|
|
8123
|
+
"opencode",
|
|
8124
|
+
"codex",
|
|
8125
|
+
"codex_cli",
|
|
8126
|
+
"codex_desktop",
|
|
8127
|
+
"cursor",
|
|
8128
|
+
"pi",
|
|
8129
|
+
"default"
|
|
8130
|
+
]);
|
|
8131
|
+
var BUILT_IN_CLAUDE_CODE = {
|
|
8132
|
+
decider: { model: "fable", effort: "high" },
|
|
8133
|
+
"implementer.hard": { model: "opus" },
|
|
8134
|
+
"implementer.standard": { model: "sonnet" },
|
|
8135
|
+
"implementer.mundane": { model: "haiku" },
|
|
8136
|
+
verifier: { model: "sonnet" },
|
|
8137
|
+
reviewer: { model: "opus" },
|
|
8138
|
+
explore: { model: "haiku" },
|
|
8139
|
+
babysit: { model: "haiku" }
|
|
8140
|
+
};
|
|
8141
|
+
var isObject2 = (value) => !!value && typeof value === "object" && !Array.isArray(value);
|
|
8142
|
+
var name = (value) => typeof value === "string" && value.trim() ? value.trim() : null;
|
|
8143
|
+
var leaf = (value) => {
|
|
8144
|
+
const text = name(value);
|
|
8145
|
+
if (text)
|
|
8146
|
+
return { model: text, effort: null };
|
|
8147
|
+
if (!isObject2(value))
|
|
8148
|
+
return null;
|
|
8149
|
+
const model = name(value.model);
|
|
8150
|
+
return model ? { model, effort: name(value.effort) } : null;
|
|
8151
|
+
};
|
|
8152
|
+
var isFlat = (value) => typeof value === "string" || isObject2(value) && Object.hasOwn(value, "model");
|
|
8153
|
+
var forHost = (value, host) => {
|
|
8154
|
+
if (isFlat(value))
|
|
8155
|
+
return leaf(value);
|
|
8156
|
+
if (!isObject2(value))
|
|
8157
|
+
return null;
|
|
8158
|
+
const family = host ? hostFamily(host) : null;
|
|
8159
|
+
for (const key of [family, host, "default"])
|
|
8160
|
+
if (key && Object.hasOwn(value, key)) {
|
|
8161
|
+
const found = leaf(value[key]);
|
|
8162
|
+
if (found)
|
|
8163
|
+
return found;
|
|
8164
|
+
}
|
|
8165
|
+
return null;
|
|
8166
|
+
};
|
|
8167
|
+
var rolesOf = (models) => isObject2(models) && isObject2(models.roles) ? models.roles : null;
|
|
8168
|
+
var resolveRoleModel = (cwd, selector, host, dir) => {
|
|
8169
|
+
const { role, tier } = selector;
|
|
8170
|
+
for (const source of modelSources(cwd, dir)) {
|
|
8171
|
+
const where = source.global ? "the global default" : `workspace ${source.name}`;
|
|
8172
|
+
const roles = rolesOf(source.models);
|
|
8173
|
+
const configured = roles && Object.hasOwn(roles, role) ? roles[role] : undefined;
|
|
8174
|
+
const fromRoles = role === "implementer" ? tier && isObject2(configured) && Object.hasOwn(configured, tier) ? forHost(configured[tier], host) : null : forHost(configured, host);
|
|
8175
|
+
if (fromRoles)
|
|
8176
|
+
return { ...fromRoles, source: `models.roles in ${where}` };
|
|
8177
|
+
if (role === "implementer" && tier && isObject2(source.tierModels)) {
|
|
8178
|
+
const fromTiers = Object.hasOwn(source.tierModels, tier) ? forHost(source.tierModels[tier], host) : null;
|
|
8179
|
+
if (fromTiers)
|
|
8180
|
+
return { model: fromTiers.model, effort: null, source: `fanout.tierModels in ${where}` };
|
|
8181
|
+
}
|
|
8182
|
+
}
|
|
8183
|
+
if (host && hostFamily(host) === "claude_code") {
|
|
8184
|
+
const builtIn = BUILT_IN_CLAUDE_CODE[tier ? `${role}.${tier}` : role];
|
|
8185
|
+
if (builtIn)
|
|
8186
|
+
return { model: builtIn.model, effort: builtIn.effort ?? null, source: "built-in" };
|
|
8187
|
+
}
|
|
8188
|
+
return null;
|
|
8189
|
+
};
|
|
8190
|
+
var uniformImplementerModel = (cwd, host, dir) => {
|
|
8191
|
+
const tiers = MODEL_TIERS.map((tier) => resolveRoleModel(cwd, { role: "implementer", tier }, host, dir));
|
|
8192
|
+
const [first] = tiers;
|
|
8193
|
+
return first && tiers.every((t) => t?.model === first.model && t.effort === first.effort) ? first : null;
|
|
8194
|
+
};
|
|
8195
|
+
var ROLE_SELECTORS = MODEL_ROLES.flatMap((role) => role === "implementer" ? MODEL_TIERS.map((tier) => ({ role, tier })) : [{ role }]);
|
|
8196
|
+
|
|
7828
8197
|
// packages/workit-core/src/hooks/standing.ts
|
|
7829
8198
|
import fs4 from "node:fs";
|
|
7830
|
-
import
|
|
8199
|
+
import path7 from "node:path";
|
|
7831
8200
|
var readPlans = (store) => {
|
|
7832
|
-
const dir =
|
|
8201
|
+
const dir = path7.join(store, "fanouts");
|
|
7833
8202
|
let names;
|
|
7834
8203
|
try {
|
|
7835
8204
|
names = fs4.readdirSync(dir).filter((name) => name.endsWith(".json"));
|
|
@@ -7839,7 +8208,7 @@ var readPlans = (store) => {
|
|
|
7839
8208
|
const plans = [];
|
|
7840
8209
|
for (const name of names) {
|
|
7841
8210
|
try {
|
|
7842
|
-
const raw = JSON.parse(fs4.readFileSync(
|
|
8211
|
+
const raw = JSON.parse(fs4.readFileSync(path7.join(dir, name), "utf8"));
|
|
7843
8212
|
if (typeof raw.name !== "string" || !Array.isArray(raw.slices))
|
|
7844
8213
|
continue;
|
|
7845
8214
|
const texts = (value) => Array.isArray(value) ? value.filter((item) => typeof item === "string" && item !== "") : [];
|
|
@@ -7966,7 +8335,9 @@ var roleTools = (role) => {
|
|
|
7966
8335
|
return [...readOnly, "write", "edit", ...familyTools];
|
|
7967
8336
|
return [...readOnly, ...familyTools];
|
|
7968
8337
|
};
|
|
8338
|
+
var roleModel = (cwd, role) => role === "implementer" ? uniformImplementerModel(cwd, "pi") : resolveRoleModel(cwd, { role: role === "investigator" ? "explore" : "reviewer" }, "pi");
|
|
7969
8339
|
function workerCommand(runtime, assignment) {
|
|
8340
|
+
const configured = roleModel(runtime.root, assignment.role);
|
|
7970
8341
|
return {
|
|
7971
8342
|
command: runtime.node,
|
|
7972
8343
|
args: [
|
|
@@ -7977,6 +8348,8 @@ function workerCommand(runtime, assignment) {
|
|
|
7977
8348
|
...runtime.sessionId ? ["--session-id", runtime.sessionId] : [],
|
|
7978
8349
|
"--approve",
|
|
7979
8350
|
"--offline",
|
|
8351
|
+
...configured ? ["--model", configured.model] : [],
|
|
8352
|
+
...configured?.effort ? ["--thinking", configured.effort] : [],
|
|
7980
8353
|
"--no-context-files",
|
|
7981
8354
|
"--tools",
|
|
7982
8355
|
roleTools(assignment.role).join(","),
|