opencode-swarm 7.123.0 → 7.125.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/.opencode/skills/critic-gate/SKILL.md +8 -0
- package/.opencode/skills/swarm/SKILL.md +12 -8
- package/.opencode/skills/swarm-pr-feedback/SKILL.md +252 -62
- package/.opencode/skills/swarm-pr-review/SKILL.md +242 -76
- package/README.md +6 -1
- package/dist/background/lane-output-store.d.ts +10 -0
- package/dist/background/pending-delegations.d.ts +3 -0
- package/dist/background/workspace-snapshot.d.ts +59 -0
- package/dist/cli/{config-doctor-3ksh1534.js → config-doctor-be9sxqx8.js} +6 -6
- package/dist/cli/{core-cwgb7ev8.js → core-d38hc85b.js} +4 -4
- package/dist/cli/{curation-policy-4j4qce5a.js → curation-policy-52kt6d7t.js} +2 -2
- package/dist/cli/{curator-drift-6b2fjsgr.js → curator-drift-h9a2sjvf.js} +7 -7
- package/dist/cli/{curator-tkyn9bzz.js → curator-hbst8nbc.js} +32 -30
- package/dist/cli/curator-llm-factory-frde1955.js +54 -0
- package/dist/cli/{dispatch-07jgc3hn.js → dispatch-f4hj1cj7.js} +3 -3
- package/dist/cli/{evidence-summary-service-96ndczbk.js → evidence-summary-service-9hq7n9k9.js} +12 -12
- package/dist/cli/{gate-evidence-xqks3kk2.js → gate-evidence-cy2te3x8.js} +2 -2
- package/dist/cli/guardrail-explain-112kqmbc.js +55 -0
- package/dist/cli/guardrail-log-c8zcab91.js +16 -0
- package/dist/cli/hive-promoter-448xs2tp.js +69 -0
- package/dist/cli/{index-hns7xjm7.js → index-09vd53pz.js} +4 -2
- package/dist/cli/{pending-delegations-68cbaqv2.js → index-0cz1ws47.js} +9 -21
- package/dist/cli/{index-det5jwfk.js → index-0y6tmm9v.js} +5 -1
- package/dist/cli/index-134d35c1.js +116 -0
- package/dist/cli/{index-m1abzg93.js → index-1kz6da87.js} +4 -2
- package/dist/cli/{index-22e127jw.js → index-23zsx7dm.js} +5 -3
- package/dist/cli/{index-kzj3fp7c.js → index-2445sx3d.js} +1 -1
- package/dist/cli/{index-ctpgsj84.js → index-2tn5h2zp.js} +1 -1
- package/dist/cli/{index-6xnxz6z0.js → index-3x761jqv.js} +4 -2
- package/dist/cli/{index-7cspygmb.js → index-4rzzzjtg.js} +11 -8
- package/dist/cli/{index-cqsak7bf.js → index-67hqr2zv.js} +1 -1
- package/dist/cli/{index-nprawcc0.js → index-6n2jpz7x.js} +1 -1
- package/dist/cli/{index-19zn67q6.js → index-6vfvc36k.js} +5 -1
- package/dist/cli/{index-6sgqnvpw.js → index-7j3sm7h8.js} +2 -2
- package/dist/cli/{index-2j25br0p.js → index-958hf0yr.js} +9 -9
- package/dist/cli/{index-j9kxwshw.js → index-99ed0h32.js} +8 -6
- package/dist/cli/{index-7g91saha.js → index-9hbwa5x1.js} +40 -32
- package/dist/cli/{index-jyrhy4ww.js → index-amspa811.js} +3179 -1557
- package/dist/cli/index-bk5tah7q.js +19 -0
- package/dist/cli/{index-293f68mj.js → index-bpmtbmy9.js} +4680 -4342
- package/dist/cli/{index-m0bmh3w0.js → index-dx2c2wjt.js} +2 -2
- package/dist/cli/{index-ye3fndsw.js → index-gacm5s2n.js} +9 -5
- package/dist/cli/{index-d6h5hq91.js → index-gnvg72y1.js} +2 -2
- package/dist/cli/{index-17eybc3z.js → index-jh6s75f6.js} +1 -1
- package/dist/cli/{index-vcgfqd8f.js → index-k5jrywpr.js} +4 -2
- package/dist/cli/{index-3rr0ese8.js → index-kt0awv1n.js} +41 -9
- package/dist/cli/index-mg54y5gc.js +564 -0
- package/dist/cli/{index-dywekeen.js → index-n6chz2g8.js} +1 -1
- package/dist/cli/{index-gnp9x6se.js → index-n832052r.js} +4 -2
- package/dist/cli/{index-816rkp4y.js → index-s9mj4rb9.js} +5 -3
- package/dist/cli/{index-gw3m5fw0.js → index-v2rdhwx8.js} +5 -3
- package/dist/cli/{index-q00e4s1s.js → index-vtwqjr4z.js} +11 -7
- package/dist/cli/index-xattnmyb.js +2502 -0
- package/dist/cli/{index-n2712byd.js → index-yt1v62pv.js} +8 -5
- package/dist/cli/{index-5e4e2hvv.js → index-z6xqpmqg.js} +4 -0
- package/dist/cli/{index-p0arc26j.js → index-zjygnfay.js} +7 -2
- package/dist/cli/index.js +35 -31
- package/dist/cli/{knowledge-escalator-dyxsm78k.js → knowledge-escalator-htafbhxg.js} +4 -4
- package/dist/cli/{knowledge-events-36q6nvae.js → knowledge-events-havw8c4t.js} +1 -1
- package/dist/cli/{knowledge-store-e07b4s54.js → knowledge-store-hqngpt2v.js} +2 -2
- package/dist/cli/{knowledge-validator-sfyf7wn2.js → knowledge-validator-g7mpnazh.js} +5 -5
- package/dist/cli/pending-delegations-7j8xqg5f.js +34 -0
- package/dist/cli/{pr-subscriptions-x653151h.js → pr-subscriptions-bxpqde8w.js} +5 -5
- package/dist/cli/{scan-cursor-hm0aqqae.js → scan-cursor-sx7cvh8v.js} +3 -3
- package/dist/cli/{schema-13bnng2n.js → schema-2418eqy3.js} +7 -4
- package/dist/cli/{scope-persistence-d9erwnvb.js → scope-persistence-habn4q8a.js} +4 -4
- package/dist/cli/{skill-generator-63r20a9k.js → skill-generator-zggy797r.js} +7 -7
- package/dist/cli/sqlite-loader-r1kgt2pq.js +12 -0
- package/dist/cli/workspace-snapshot-c9pxxt9a.js +48 -0
- package/dist/commands/memory-link.d.ts +28 -0
- package/dist/commands/registry.d.ts +26 -1
- package/dist/config/schema.d.ts +6 -0
- package/dist/hooks/pr-workflow-gate.d.ts +211 -0
- package/dist/hooks/pr-workflow-response-gate.d.ts +23 -0
- package/dist/hooks/pr-workflow-session-resolver.d.ts +14 -0
- package/dist/index.js +496 -451
- package/dist/knowledge/family-migration-shared.d.ts +24 -0
- package/dist/knowledge/family-migration.d.ts +5 -0
- package/dist/memory/config.d.ts +11 -0
- package/dist/memory/consolidation-log.d.ts +8 -2
- package/dist/memory/finalize-reward-sweep.d.ts +2 -1
- package/dist/memory/gateway.d.ts +13 -0
- package/dist/memory/index.d.ts +4 -2
- package/dist/memory/local-jsonl-provider.d.ts +25 -1
- package/dist/memory/memory-family-manifest.d.ts +52 -0
- package/dist/memory/memory-family-migration.d.ts +94 -0
- package/dist/memory/memory-link.d.ts +103 -0
- package/dist/memory/provider-pool.d.ts +35 -0
- package/dist/memory/redaction.d.ts +31 -0
- package/dist/memory/schema.d.ts +21 -0
- package/dist/memory/sqlite-provider.d.ts +58 -1
- package/dist/memory/storage-root.d.ts +93 -0
- package/dist/memory/types.d.ts +20 -1
- package/dist/services/knowledge-diagnostics.d.ts +25 -0
- package/dist/services/status-service.d.ts +16 -0
- package/dist/tools/complete-pr-workflow.d.ts +5 -0
- package/dist/tools/dispatch-lanes.d.ts +44 -0
- package/dist/tools/index.d.ts +2 -0
- package/dist/tools/manifest.d.ts +2 -0
- package/dist/tools/run-pr-feedback-stage-a.d.ts +69 -0
- package/dist/tools/tool-metadata.d.ts +8 -0
- package/dist/tools/write-pr-review-trigger-eval.d.ts +56 -46
- package/package.json +1 -1
- package/dist/cli/curator-llm-factory-mfvd4sqx.js +0 -52
- package/dist/cli/guardrail-explain-4vytbchb.js +0 -53
- package/dist/cli/guardrail-log-z291m4gw.js +0 -16
- package/dist/cli/hive-promoter-y5wsztkc.js +0 -67
- package/dist/cli/index-4rhcth7a.js +0 -14
- package/dist/cli/index-dqh3zhhc.js +0 -133
- package/dist/cli/index-wr8qgpz5.js +0 -2463
- package/dist/cli/workspace-snapshot-eyf6gd0d.js +0 -22
|
@@ -0,0 +1,564 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// src/background/workspace-snapshot.ts
|
|
3
|
+
import * as child_process from "child_process";
|
|
4
|
+
import { createHash } from "crypto";
|
|
5
|
+
import * as fs from "fs";
|
|
6
|
+
import * as path from "path";
|
|
7
|
+
var GIT_SNAPSHOT_TIMEOUT_MS = 3000;
|
|
8
|
+
var GIT_SNAPSHOT_MAX_BUFFER = 512 * 1024;
|
|
9
|
+
var REVISION_MAX_FILES = 5000;
|
|
10
|
+
var REVISION_MAX_TOTAL_BYTES = 64 * 1024 * 1024;
|
|
11
|
+
var REVISION_READ_CHUNK_BYTES = 64 * 1024;
|
|
12
|
+
var REVISION_YIELD_EVERY_CHUNKS = 16;
|
|
13
|
+
function runGit(directory, args, timeoutMs = GIT_SNAPSHOT_TIMEOUT_MS) {
|
|
14
|
+
const result = _internals.spawnSync("git", ["-C", directory, ...args], {
|
|
15
|
+
cwd: directory,
|
|
16
|
+
encoding: "utf-8",
|
|
17
|
+
timeout: timeoutMs,
|
|
18
|
+
maxBuffer: GIT_SNAPSHOT_MAX_BUFFER,
|
|
19
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
20
|
+
});
|
|
21
|
+
if (result.error || result.status !== 0)
|
|
22
|
+
return null;
|
|
23
|
+
return typeof result.stdout === "string" ? result.stdout.trimEnd() : null;
|
|
24
|
+
}
|
|
25
|
+
async function runGitAsync(directory, args, timeoutMs = GIT_SNAPSHOT_TIMEOUT_MS) {
|
|
26
|
+
return await new Promise((resolve2) => {
|
|
27
|
+
let settled = false;
|
|
28
|
+
let stdout = "";
|
|
29
|
+
let stderrBytes = 0;
|
|
30
|
+
let timeout;
|
|
31
|
+
let child;
|
|
32
|
+
const finish = (value) => {
|
|
33
|
+
if (settled)
|
|
34
|
+
return;
|
|
35
|
+
settled = true;
|
|
36
|
+
if (timeout)
|
|
37
|
+
clearTimeout(timeout);
|
|
38
|
+
try {
|
|
39
|
+
child?.kill();
|
|
40
|
+
} catch {}
|
|
41
|
+
resolve2(value);
|
|
42
|
+
};
|
|
43
|
+
try {
|
|
44
|
+
child = child_process.spawn("git", ["-C", directory, ...args], {
|
|
45
|
+
cwd: directory,
|
|
46
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
47
|
+
windowsHide: true
|
|
48
|
+
});
|
|
49
|
+
} catch {
|
|
50
|
+
finish(null);
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
timeout = setTimeout(() => finish(null), timeoutMs);
|
|
54
|
+
child.stdout?.setEncoding("utf-8");
|
|
55
|
+
child.stdout?.on("data", (chunk) => {
|
|
56
|
+
stdout += chunk;
|
|
57
|
+
if (Buffer.byteLength(stdout, "utf-8") > GIT_SNAPSHOT_MAX_BUFFER) {
|
|
58
|
+
finish(null);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
child.stderr?.on("data", (chunk) => {
|
|
62
|
+
stderrBytes += chunk.length;
|
|
63
|
+
if (stderrBytes > GIT_SNAPSHOT_MAX_BUFFER) {
|
|
64
|
+
finish(null);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
child.once("error", () => finish(null));
|
|
68
|
+
child.once("close", (code) => finish(code === 0 ? stdout.trimEnd() : null));
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
function readGitTextAtRevision(directory, revision, relativePath) {
|
|
72
|
+
if (!isSafeGitRevisionToken(revision) || !/^\.?(?:[A-Za-z0-9][A-Za-z0-9._-]*\/)*[A-Za-z0-9][A-Za-z0-9._-]*$/.test(relativePath) || relativePath.split("/").includes("..")) {
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
const result = _internals.spawnSync("git", ["-C", directory, "show", `${revision}:${relativePath}`], {
|
|
76
|
+
cwd: directory,
|
|
77
|
+
encoding: "utf-8",
|
|
78
|
+
timeout: GIT_SNAPSHOT_TIMEOUT_MS,
|
|
79
|
+
maxBuffer: GIT_SNAPSHOT_MAX_BUFFER,
|
|
80
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
81
|
+
});
|
|
82
|
+
if (result.error || result.status !== 0 || typeof result.stdout !== "string")
|
|
83
|
+
return null;
|
|
84
|
+
return result.stdout;
|
|
85
|
+
}
|
|
86
|
+
function resolveCurrentGitHead(directory) {
|
|
87
|
+
return runGit(directory, ["rev-parse", "--verify", "HEAD^{commit}"]);
|
|
88
|
+
}
|
|
89
|
+
function resolveExactMergeBase(directory, baseRef, prHeadSha) {
|
|
90
|
+
if (!isSafeGitRevisionToken(baseRef) || !isSafeGitRevisionToken(prHeadSha))
|
|
91
|
+
return null;
|
|
92
|
+
const mergeBase = runGit(directory, ["merge-base", "--", baseRef, prHeadSha]);
|
|
93
|
+
return mergeBase && /^[0-9a-f]{6,64}$/i.test(mergeBase) ? mergeBase : null;
|
|
94
|
+
}
|
|
95
|
+
function isSafeGitRevisionToken(value) {
|
|
96
|
+
return /^(?!-)[A-Za-z0-9][A-Za-z0-9._/-]{0,255}$/.test(value) && !value.includes("..") && !value.includes("//") && !value.includes("@{");
|
|
97
|
+
}
|
|
98
|
+
function resolveCurrentUpstreamRemoteRef(directory) {
|
|
99
|
+
const upstream = runGit(directory, [
|
|
100
|
+
"rev-parse",
|
|
101
|
+
"--symbolic-full-name",
|
|
102
|
+
"@{upstream}"
|
|
103
|
+
]);
|
|
104
|
+
if (!upstream?.startsWith("refs/remotes/") || upstream.endsWith("/HEAD")) {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
return upstream;
|
|
108
|
+
}
|
|
109
|
+
function resolveCurrentUpstreamPushTarget(directory) {
|
|
110
|
+
const localBranchRef = runGit(directory, ["symbolic-ref", "--quiet", "HEAD"]);
|
|
111
|
+
if (!localBranchRef?.startsWith("refs/heads/"))
|
|
112
|
+
return null;
|
|
113
|
+
const encoded = runGit(directory, [
|
|
114
|
+
"for-each-ref",
|
|
115
|
+
"--format=%(upstream:remotename)%00%(upstream:remoteref)%00%(upstream)",
|
|
116
|
+
localBranchRef
|
|
117
|
+
]);
|
|
118
|
+
if (!encoded)
|
|
119
|
+
return null;
|
|
120
|
+
const [remoteName, remoteBranchRef, remoteTrackingRef, ...extras] = encoded.split("\x00");
|
|
121
|
+
if (extras.length > 0 || !remoteName || remoteName.startsWith("-") || /[\s;&|<>`]/.test(remoteName) || !remoteBranchRef?.startsWith("refs/heads/") || remoteBranchRef === "refs/heads/" || /[\s;&|<>`]/.test(remoteBranchRef) || !remoteTrackingRef?.startsWith("refs/remotes/") || remoteTrackingRef.endsWith("/HEAD")) {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
return { remoteName, remoteBranchRef, remoteTrackingRef };
|
|
125
|
+
}
|
|
126
|
+
function resolveExactRemoteBranchHead(directory, remoteName, remoteBranchRef) {
|
|
127
|
+
if (!remoteName || remoteName.startsWith("-") || /[\s;&|<>`]/.test(remoteName) || !remoteBranchRef.startsWith("refs/heads/") || remoteBranchRef === "refs/heads/" || /[\s;&|<>`]/.test(remoteBranchRef)) {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
const output = runGit(directory, ["ls-remote", "--exit-code", "--heads", remoteName, remoteBranchRef], 20000);
|
|
131
|
+
if (!output)
|
|
132
|
+
return null;
|
|
133
|
+
const rows = output.split(/\r?\n/).filter(Boolean);
|
|
134
|
+
if (rows.length !== 1)
|
|
135
|
+
return null;
|
|
136
|
+
const [objectName, refName, ...extras] = rows[0].split(/\s+/);
|
|
137
|
+
if (extras.length > 0 || refName !== remoteBranchRef || !objectName || !(/^[0-9a-f]{40}$/i.test(objectName) || /^[0-9a-f]{64}$/i.test(objectName))) {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
return objectName;
|
|
141
|
+
}
|
|
142
|
+
function resolveGitControlStateDigest(directory) {
|
|
143
|
+
const head = runGit(directory, ["rev-parse", "--verify", "HEAD^{commit}"]);
|
|
144
|
+
const symbolicHead = runGit(directory, ["symbolic-ref", "--quiet", "HEAD"]);
|
|
145
|
+
const upstream = resolveCurrentUpstreamPushTarget(directory);
|
|
146
|
+
const refs = runGit(directory, [
|
|
147
|
+
"for-each-ref",
|
|
148
|
+
"--format=%(refname)%00%(objectname)",
|
|
149
|
+
"refs/heads",
|
|
150
|
+
"refs/remotes",
|
|
151
|
+
"refs/tags"
|
|
152
|
+
]);
|
|
153
|
+
const config = runGit(directory, [
|
|
154
|
+
"config",
|
|
155
|
+
"--null",
|
|
156
|
+
"--show-origin",
|
|
157
|
+
"--show-scope",
|
|
158
|
+
"--list"
|
|
159
|
+
]);
|
|
160
|
+
const index = runGit(directory, ["ls-files", "--stage", "-z"]);
|
|
161
|
+
if (head === null || symbolicHead === null || !upstream || refs === null || config === null || index === null) {
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
return digest(`head\x00${head}\x00symbolic\x00${symbolicHead}\x00upstream\x00${upstream.remoteName}\x00${upstream.remoteBranchRef}\x00${upstream.remoteTrackingRef}\x00refs\x00${refs}\x00config\x00${config}\x00index\x00${index}`);
|
|
165
|
+
}
|
|
166
|
+
function resolveIsWorkingTreeClean(directory) {
|
|
167
|
+
const status = runGit(directory, [
|
|
168
|
+
"status",
|
|
169
|
+
"--porcelain=v1",
|
|
170
|
+
"--untracked-files=all"
|
|
171
|
+
]);
|
|
172
|
+
return status === null ? null : status.length === 0;
|
|
173
|
+
}
|
|
174
|
+
function resolveCommitCountSince(directory, baseHeadSha, currentHeadSha) {
|
|
175
|
+
const output = runGit(directory, [
|
|
176
|
+
"rev-list",
|
|
177
|
+
"--count",
|
|
178
|
+
"--ancestry-path",
|
|
179
|
+
`${baseHeadSha}..${currentHeadSha}`
|
|
180
|
+
]);
|
|
181
|
+
if (!output || !/^\d+$/.test(output))
|
|
182
|
+
return null;
|
|
183
|
+
const count = Number(output);
|
|
184
|
+
return Number.isSafeInteger(count) ? count : null;
|
|
185
|
+
}
|
|
186
|
+
function resolveIsExactSingleChildCommit(directory, baseHeadSha, currentHeadSha) {
|
|
187
|
+
const base = runGit(directory, [
|
|
188
|
+
"rev-parse",
|
|
189
|
+
"--verify",
|
|
190
|
+
`${baseHeadSha}^{commit}`
|
|
191
|
+
]);
|
|
192
|
+
const current = runGit(directory, [
|
|
193
|
+
"rev-parse",
|
|
194
|
+
"--verify",
|
|
195
|
+
`${currentHeadSha}^{commit}`
|
|
196
|
+
]);
|
|
197
|
+
if (!base || !current)
|
|
198
|
+
return null;
|
|
199
|
+
const commitAndParents = runGit(directory, [
|
|
200
|
+
"rev-list",
|
|
201
|
+
"--parents",
|
|
202
|
+
"-n",
|
|
203
|
+
"1",
|
|
204
|
+
current
|
|
205
|
+
]);
|
|
206
|
+
if (commitAndParents === null)
|
|
207
|
+
return null;
|
|
208
|
+
const fields = commitAndParents.trim().split(/\s+/);
|
|
209
|
+
return fields.length === 2 && fields[0]?.toLowerCase() === current.toLowerCase() && fields[1]?.toLowerCase() === base.toLowerCase();
|
|
210
|
+
}
|
|
211
|
+
function resolveRemoteRefsContainingHead(directory, headSha) {
|
|
212
|
+
const output = runGit(directory, [
|
|
213
|
+
"for-each-ref",
|
|
214
|
+
"--format=%(refname)%09%(objectname)",
|
|
215
|
+
"refs/remotes"
|
|
216
|
+
]);
|
|
217
|
+
if (output === null)
|
|
218
|
+
return null;
|
|
219
|
+
return output.split(/\r?\n/).map((line) => line.trim().split("\t")).filter(([ref, objectName]) => ref?.startsWith("refs/remotes/") && !ref.endsWith("/HEAD") && objectName?.toLowerCase() === headSha.toLowerCase()).map(([ref]) => ref);
|
|
220
|
+
}
|
|
221
|
+
function resolvePrWorkflowRevisionDigest(directory, baseHeadSha) {
|
|
222
|
+
const projectRoot = path.resolve(directory);
|
|
223
|
+
const baseHead = runGit(projectRoot, [
|
|
224
|
+
"rev-parse",
|
|
225
|
+
"--verify",
|
|
226
|
+
`${baseHeadSha}^{commit}`
|
|
227
|
+
]);
|
|
228
|
+
const diffNames = runGit(projectRoot, [
|
|
229
|
+
"diff",
|
|
230
|
+
"--no-ext-diff",
|
|
231
|
+
"--name-only",
|
|
232
|
+
"-z",
|
|
233
|
+
baseHeadSha
|
|
234
|
+
]);
|
|
235
|
+
const porcelain = runGit(projectRoot, [
|
|
236
|
+
"status",
|
|
237
|
+
"--porcelain=v1",
|
|
238
|
+
"-z",
|
|
239
|
+
"--untracked-files=all"
|
|
240
|
+
]);
|
|
241
|
+
if (!baseHead || diffNames === null || porcelain === null)
|
|
242
|
+
return null;
|
|
243
|
+
const porcelainPaths = parsePorcelainPaths(porcelain);
|
|
244
|
+
if (!porcelainPaths)
|
|
245
|
+
return null;
|
|
246
|
+
const changedPaths = [
|
|
247
|
+
...new Set([...parseNulPaths(diffNames), ...porcelainPaths])
|
|
248
|
+
].sort((left, right) => left.localeCompare(right));
|
|
249
|
+
if (changedPaths.length > REVISION_MAX_FILES)
|
|
250
|
+
return null;
|
|
251
|
+
const hash = createHash("sha256");
|
|
252
|
+
hash.update(`base\x00${baseHead}\x00`);
|
|
253
|
+
let totalBytes = 0;
|
|
254
|
+
for (const relativePath of changedPaths) {
|
|
255
|
+
const resolvedPath = path.resolve(projectRoot, relativePath);
|
|
256
|
+
const relativeToRoot = path.relative(projectRoot, resolvedPath);
|
|
257
|
+
if (!relativeToRoot || relativeToRoot.startsWith("..") || path.isAbsolute(relativeToRoot))
|
|
258
|
+
return null;
|
|
259
|
+
hash.update(`path\x00${relativePath}\x00`);
|
|
260
|
+
let stats;
|
|
261
|
+
try {
|
|
262
|
+
stats = fs.lstatSync(resolvedPath);
|
|
263
|
+
} catch (error) {
|
|
264
|
+
if (error.code === "ENOENT") {
|
|
265
|
+
hash.update("deleted\x00");
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
268
|
+
return null;
|
|
269
|
+
}
|
|
270
|
+
if (stats.isSymbolicLink()) {
|
|
271
|
+
try {
|
|
272
|
+
hash.update(`symlink\x00${fs.readlinkSync(resolvedPath)}\x00`);
|
|
273
|
+
continue;
|
|
274
|
+
} catch {
|
|
275
|
+
return null;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
if (!stats.isFile()) {
|
|
279
|
+
hash.update(`node\x00${stats.mode}\x00`);
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
282
|
+
totalBytes += stats.size;
|
|
283
|
+
if (totalBytes > REVISION_MAX_TOTAL_BYTES)
|
|
284
|
+
return null;
|
|
285
|
+
try {
|
|
286
|
+
hash.update(`file\x00${stats.mode}\x00`);
|
|
287
|
+
hash.update(fs.readFileSync(resolvedPath));
|
|
288
|
+
hash.update("\x00");
|
|
289
|
+
} catch {
|
|
290
|
+
return null;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return hash.digest("hex");
|
|
294
|
+
}
|
|
295
|
+
async function resolvePrWorkflowRevisionDigestAsync(directory, baseHeadSha) {
|
|
296
|
+
const projectRoot = path.resolve(directory);
|
|
297
|
+
const [baseHead, diffNames, porcelain] = await Promise.all([
|
|
298
|
+
runGitAsync(projectRoot, [
|
|
299
|
+
"rev-parse",
|
|
300
|
+
"--verify",
|
|
301
|
+
`${baseHeadSha}^{commit}`
|
|
302
|
+
]),
|
|
303
|
+
runGitAsync(projectRoot, [
|
|
304
|
+
"diff",
|
|
305
|
+
"--no-ext-diff",
|
|
306
|
+
"--name-only",
|
|
307
|
+
"-z",
|
|
308
|
+
baseHeadSha
|
|
309
|
+
]),
|
|
310
|
+
runGitAsync(projectRoot, [
|
|
311
|
+
"status",
|
|
312
|
+
"--porcelain=v1",
|
|
313
|
+
"-z",
|
|
314
|
+
"--untracked-files=all"
|
|
315
|
+
])
|
|
316
|
+
]);
|
|
317
|
+
if (!baseHead || diffNames === null || porcelain === null)
|
|
318
|
+
return null;
|
|
319
|
+
const porcelainPaths = parsePorcelainPaths(porcelain);
|
|
320
|
+
if (!porcelainPaths)
|
|
321
|
+
return null;
|
|
322
|
+
const changedPaths = [
|
|
323
|
+
...new Set([...parseNulPaths(diffNames), ...porcelainPaths])
|
|
324
|
+
].sort((left, right) => left.localeCompare(right));
|
|
325
|
+
if (changedPaths.length > REVISION_MAX_FILES)
|
|
326
|
+
return null;
|
|
327
|
+
const hash = createHash("sha256");
|
|
328
|
+
hash.update(`base\x00${baseHead}\x00`);
|
|
329
|
+
let totalBytes = 0;
|
|
330
|
+
let chunksSinceYield = 0;
|
|
331
|
+
for (const relativePath of changedPaths) {
|
|
332
|
+
const resolvedPath = path.resolve(projectRoot, relativePath);
|
|
333
|
+
const relativeToRoot = path.relative(projectRoot, resolvedPath);
|
|
334
|
+
if (!relativeToRoot || relativeToRoot.startsWith("..") || path.isAbsolute(relativeToRoot))
|
|
335
|
+
return null;
|
|
336
|
+
hash.update(`path\x00${relativePath}\x00`);
|
|
337
|
+
let stats;
|
|
338
|
+
try {
|
|
339
|
+
stats = await fs.promises.lstat(resolvedPath);
|
|
340
|
+
} catch (error) {
|
|
341
|
+
if (error.code === "ENOENT") {
|
|
342
|
+
hash.update("deleted\x00");
|
|
343
|
+
continue;
|
|
344
|
+
}
|
|
345
|
+
return null;
|
|
346
|
+
}
|
|
347
|
+
if (stats.isSymbolicLink()) {
|
|
348
|
+
try {
|
|
349
|
+
hash.update(`symlink\x00${await fs.promises.readlink(resolvedPath)}\x00`);
|
|
350
|
+
continue;
|
|
351
|
+
} catch {
|
|
352
|
+
return null;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
if (!stats.isFile()) {
|
|
356
|
+
hash.update(`node\x00${stats.mode}\x00`);
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
359
|
+
totalBytes += stats.size;
|
|
360
|
+
if (totalBytes > REVISION_MAX_TOTAL_BYTES)
|
|
361
|
+
return null;
|
|
362
|
+
hash.update(`file\x00${stats.mode}\x00`);
|
|
363
|
+
let handle;
|
|
364
|
+
try {
|
|
365
|
+
handle = await fs.promises.open(resolvedPath, "r");
|
|
366
|
+
const buffer = Buffer.allocUnsafe(REVISION_READ_CHUNK_BYTES);
|
|
367
|
+
for (let position = 0;position < stats.size; ) {
|
|
368
|
+
const length = Math.min(REVISION_READ_CHUNK_BYTES, stats.size - position);
|
|
369
|
+
const { bytesRead } = await handle.read(buffer, 0, length, position);
|
|
370
|
+
if (bytesRead <= 0)
|
|
371
|
+
return null;
|
|
372
|
+
hash.update(buffer.subarray(0, bytesRead));
|
|
373
|
+
position += bytesRead;
|
|
374
|
+
chunksSinceYield++;
|
|
375
|
+
if (chunksSinceYield >= REVISION_YIELD_EVERY_CHUNKS) {
|
|
376
|
+
chunksSinceYield = 0;
|
|
377
|
+
await _internals.yieldControl();
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
hash.update("\x00");
|
|
381
|
+
} catch {
|
|
382
|
+
return null;
|
|
383
|
+
} finally {
|
|
384
|
+
await handle?.close().catch(() => {
|
|
385
|
+
return;
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
return hash.digest("hex");
|
|
390
|
+
}
|
|
391
|
+
function parseNulPaths(output) {
|
|
392
|
+
return output.split("\x00").filter((entry) => entry.length > 0);
|
|
393
|
+
}
|
|
394
|
+
function parsePorcelainPaths(output) {
|
|
395
|
+
const entries = parseNulPaths(output);
|
|
396
|
+
const paths = [];
|
|
397
|
+
for (let index = 0;index < entries.length; index++) {
|
|
398
|
+
const entry = entries[index];
|
|
399
|
+
if (entry.length < 4 || entry[2] !== " ")
|
|
400
|
+
return null;
|
|
401
|
+
const status = entry.slice(0, 2);
|
|
402
|
+
const changedPath = entry.slice(3);
|
|
403
|
+
if (!changedPath)
|
|
404
|
+
return null;
|
|
405
|
+
paths.push(changedPath);
|
|
406
|
+
if (status.includes("R") || status.includes("C")) {
|
|
407
|
+
const originalPath = entries[++index];
|
|
408
|
+
if (!originalPath)
|
|
409
|
+
return null;
|
|
410
|
+
paths.push(originalPath);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
return [...new Set(paths)];
|
|
414
|
+
}
|
|
415
|
+
function parsePorcelainV2Snapshot(output) {
|
|
416
|
+
const records = output.split("\x00");
|
|
417
|
+
const headers = [];
|
|
418
|
+
while (records[0]?.startsWith("# ")) {
|
|
419
|
+
headers.push(records.shift());
|
|
420
|
+
}
|
|
421
|
+
const oidMatch = headers.join(`
|
|
422
|
+
`).match(/^# branch\.oid (.+)$/m);
|
|
423
|
+
if (!oidMatch)
|
|
424
|
+
return null;
|
|
425
|
+
const gitHead = /^[0-9a-f]{6,64}$/i.test(oidMatch[1]) ? oidMatch[1] : oidMatch[1] === "(initial)" ? null : null;
|
|
426
|
+
const paths = [];
|
|
427
|
+
for (let index = 0;index < records.length; index++) {
|
|
428
|
+
const record = records[index];
|
|
429
|
+
if (!record)
|
|
430
|
+
continue;
|
|
431
|
+
if (record.startsWith("? ")) {
|
|
432
|
+
paths.push(record.slice(2));
|
|
433
|
+
continue;
|
|
434
|
+
}
|
|
435
|
+
if (record.startsWith("1 ")) {
|
|
436
|
+
const changedPath = porcelainV2PathAfterFields(record, 8);
|
|
437
|
+
if (!changedPath)
|
|
438
|
+
return null;
|
|
439
|
+
paths.push(changedPath);
|
|
440
|
+
continue;
|
|
441
|
+
}
|
|
442
|
+
if (record.startsWith("2 ")) {
|
|
443
|
+
const changedPath = porcelainV2PathAfterFields(record, 9);
|
|
444
|
+
const originalPath = records[++index];
|
|
445
|
+
if (!changedPath || !originalPath)
|
|
446
|
+
return null;
|
|
447
|
+
paths.push(changedPath, originalPath);
|
|
448
|
+
continue;
|
|
449
|
+
}
|
|
450
|
+
if (record.startsWith("u ")) {
|
|
451
|
+
const changedPath = porcelainV2PathAfterFields(record, 10);
|
|
452
|
+
if (!changedPath)
|
|
453
|
+
return null;
|
|
454
|
+
paths.push(changedPath);
|
|
455
|
+
continue;
|
|
456
|
+
}
|
|
457
|
+
return null;
|
|
458
|
+
}
|
|
459
|
+
return { gitHead, changedFiles: [...new Set(paths)] };
|
|
460
|
+
}
|
|
461
|
+
function porcelainV2PathAfterFields(record, fields) {
|
|
462
|
+
let offset = 0;
|
|
463
|
+
for (let index = 0;index < fields; index++) {
|
|
464
|
+
const delimiter = record.indexOf(" ", offset);
|
|
465
|
+
if (delimiter < 0)
|
|
466
|
+
return null;
|
|
467
|
+
offset = delimiter + 1;
|
|
468
|
+
}
|
|
469
|
+
const pathValue = record.slice(offset);
|
|
470
|
+
return pathValue || null;
|
|
471
|
+
}
|
|
472
|
+
function captureWorkspaceSnapshot(directory, optionsOrScope = null, prHeadShaArg = null) {
|
|
473
|
+
const scope = typeof optionsOrScope === "object" && optionsOrScope !== null ? optionsOrScope.scope ?? null : optionsOrScope;
|
|
474
|
+
const configuredPrHeadSha = (() => {
|
|
475
|
+
if (typeof optionsOrScope !== "object" || optionsOrScope === null) {
|
|
476
|
+
return prHeadShaArg;
|
|
477
|
+
}
|
|
478
|
+
return optionsOrScope.prHeadSha ?? null;
|
|
479
|
+
})();
|
|
480
|
+
const resolveCurrentPrHeadSha = typeof optionsOrScope === "object" && optionsOrScope !== null && optionsOrScope.resolveCurrentPrHeadSha === true;
|
|
481
|
+
const upstreamBefore = resolveCurrentPrHeadSha ? runGit(directory, ["rev-parse", "@{upstream}"]) : null;
|
|
482
|
+
const porcelain = runGit(directory, [
|
|
483
|
+
"status",
|
|
484
|
+
"--porcelain=v2",
|
|
485
|
+
"--branch",
|
|
486
|
+
"-z",
|
|
487
|
+
"--untracked-files=all"
|
|
488
|
+
]);
|
|
489
|
+
const snapshot = porcelain === null ? null : parsePorcelainV2Snapshot(porcelain);
|
|
490
|
+
const upstreamAfter = resolveCurrentPrHeadSha ? runGit(directory, ["rev-parse", "@{upstream}"]) : null;
|
|
491
|
+
const prHeadSha = resolveCurrentPrHeadSha ? upstreamBefore && upstreamBefore === upstreamAfter ? upstreamBefore : null : configuredPrHeadSha;
|
|
492
|
+
return {
|
|
493
|
+
directory: path.resolve(directory),
|
|
494
|
+
gitHead: snapshot?.gitHead ?? null,
|
|
495
|
+
dirtyHash: porcelain === null ? null : digest(porcelain),
|
|
496
|
+
changedFiles: snapshot?.changedFiles ?? null,
|
|
497
|
+
prHeadSha,
|
|
498
|
+
scope
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
function changedFilesSinceSnapshot(directory, baseline) {
|
|
502
|
+
if (!baseline?.gitHead || baseline.changedFiles == null)
|
|
503
|
+
return null;
|
|
504
|
+
if (baseline.changedFiles.length > 0)
|
|
505
|
+
return null;
|
|
506
|
+
const current = captureWorkspaceSnapshot(directory);
|
|
507
|
+
if (!current.gitHead || current.changedFiles == null)
|
|
508
|
+
return null;
|
|
509
|
+
const changed = new Set(current.changedFiles);
|
|
510
|
+
if (baseline.gitHead !== current.gitHead) {
|
|
511
|
+
const committed = runGit(directory, [
|
|
512
|
+
"diff",
|
|
513
|
+
"--name-only",
|
|
514
|
+
"-z",
|
|
515
|
+
baseline.gitHead,
|
|
516
|
+
current.gitHead
|
|
517
|
+
]);
|
|
518
|
+
if (committed === null)
|
|
519
|
+
return null;
|
|
520
|
+
for (const changedPath of parseNulPaths(committed))
|
|
521
|
+
changed.add(changedPath);
|
|
522
|
+
}
|
|
523
|
+
return [...changed];
|
|
524
|
+
}
|
|
525
|
+
function workspaceSnapshotMatches(expected, current) {
|
|
526
|
+
if (!expected)
|
|
527
|
+
return { ok: true };
|
|
528
|
+
if (path.resolve(expected.directory) !== path.resolve(current.directory)) {
|
|
529
|
+
return {
|
|
530
|
+
ok: false,
|
|
531
|
+
reason: `directory changed: expected ${expected.directory}, got ${current.directory}`
|
|
532
|
+
};
|
|
533
|
+
}
|
|
534
|
+
const checks = ["gitHead", "dirtyHash", "prHeadSha"];
|
|
535
|
+
for (const key of checks) {
|
|
536
|
+
const expectedValue = expected[key];
|
|
537
|
+
if (expectedValue === null)
|
|
538
|
+
continue;
|
|
539
|
+
if (current[key] !== expectedValue) {
|
|
540
|
+
return {
|
|
541
|
+
ok: false,
|
|
542
|
+
reason: `${key} changed: expected ${expectedValue}, got ${current[key] ?? "unknown"}`
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
return { ok: true };
|
|
547
|
+
}
|
|
548
|
+
var compareWorkspaceSnapshot = workspaceSnapshotMatches;
|
|
549
|
+
function compareWorkspaceSnapshots(expected, current) {
|
|
550
|
+
const result = workspaceSnapshotMatches(expected, current);
|
|
551
|
+
if (result.ok)
|
|
552
|
+
return { stale: false };
|
|
553
|
+
return { stale: true, reason: result.reason };
|
|
554
|
+
}
|
|
555
|
+
function digest(text) {
|
|
556
|
+
return createHash("sha256").update(text).digest("hex");
|
|
557
|
+
}
|
|
558
|
+
var _internals = {
|
|
559
|
+
spawnSync: child_process.spawnSync,
|
|
560
|
+
yieldControl: () => new Promise((resolve2) => setImmediate(resolve2)),
|
|
561
|
+
parsePorcelainV2Snapshot
|
|
562
|
+
};
|
|
563
|
+
|
|
564
|
+
export { readGitTextAtRevision, resolveCurrentGitHead, resolveExactMergeBase, resolveCurrentUpstreamRemoteRef, resolveCurrentUpstreamPushTarget, resolveExactRemoteBranchHead, resolveGitControlStateDigest, resolveIsWorkingTreeClean, resolveCommitCountSince, resolveIsExactSingleChildCommit, resolveRemoteRefsContainingHead, resolvePrWorkflowRevisionDigest, resolvePrWorkflowRevisionDigestAsync, parsePorcelainPaths, captureWorkspaceSnapshot, changedFilesSinceSnapshot, workspaceSnapshotMatches, compareWorkspaceSnapshot, compareWorkspaceSnapshots, digest, _internals };
|
|
@@ -608,7 +608,7 @@ async function applyKnowledgeVerdictFeedback(directory, options) {
|
|
|
608
608
|
deltas.push({ id, delta });
|
|
609
609
|
}
|
|
610
610
|
if (deltas.length > 0) {
|
|
611
|
-
const { bumpKnowledgeConfidenceBatch } = await import("./knowledge-store-
|
|
611
|
+
const { bumpKnowledgeConfidenceBatch } = await import("./knowledge-store-hqngpt2v.js");
|
|
612
612
|
await bumpKnowledgeConfidenceBatch(directory, deltas, options?.floorOptions);
|
|
613
613
|
}
|
|
614
614
|
return {
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
|
-
exports_external
|
|
4
|
-
|
|
3
|
+
exports_external,
|
|
4
|
+
init_zod
|
|
5
|
+
} from "./index-bpmtbmy9.js";
|
|
5
6
|
|
|
6
7
|
// src/config/spec-schema.ts
|
|
8
|
+
init_zod();
|
|
7
9
|
var ObligationSchema = exports_external.enum(["MUST", "SHALL", "SHOULD", "MAY"]);
|
|
8
10
|
var SpecRequirementSchema = exports_external.object({
|
|
9
11
|
id: exports_external.string().regex(/^FR-(?!000)\d{3}$/, "Requirement ID must match FR-### pattern (e.g., FR-001)"),
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
validateSpecContent
|
|
4
|
-
} from "./index-
|
|
4
|
+
} from "./index-n832052r.js";
|
|
5
5
|
import {
|
|
6
|
-
advisoryWarn
|
|
7
|
-
|
|
6
|
+
advisoryWarn,
|
|
7
|
+
init_warning_buffer
|
|
8
|
+
} from "./index-gacm5s2n.js";
|
|
8
9
|
|
|
9
10
|
// src/sdd/effective-spec.ts
|
|
10
11
|
import { createHash } from "crypto";
|
|
11
12
|
import * as fs from "fs";
|
|
12
13
|
import * as path from "path";
|
|
14
|
+
init_warning_buffer();
|
|
13
15
|
var SWARM_SPEC_REL = path.join(".swarm", "spec.md");
|
|
14
16
|
var OPENSPEC_ROOT = "openspec";
|
|
15
17
|
var SPECKIT_MARKER = ".specify";
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
|
-
advisoryWarn
|
|
4
|
-
|
|
3
|
+
advisoryWarn,
|
|
4
|
+
init_warning_buffer
|
|
5
|
+
} from "./index-gacm5s2n.js";
|
|
5
6
|
import {
|
|
6
7
|
log
|
|
7
8
|
} from "./index-zgwm4ryv.js";
|
|
@@ -13,6 +14,7 @@ import {
|
|
|
13
14
|
} from "./index-a76rekgs.js";
|
|
14
15
|
|
|
15
16
|
// src/worktree/core.ts
|
|
17
|
+
init_warning_buffer();
|
|
16
18
|
import * as fs from "fs";
|
|
17
19
|
import * as fsPromises from "fs/promises";
|
|
18
20
|
import * as os from "os";
|
|
@@ -37,7 +39,7 @@ var _internals = {
|
|
|
37
39
|
symlinkSync: fs.symlinkSync
|
|
38
40
|
},
|
|
39
41
|
writeScopeToDisk: async (directory, taskId, files) => {
|
|
40
|
-
const { writeScopeToDisk: realWrite } = await import("./scope-persistence-
|
|
42
|
+
const { writeScopeToDisk: realWrite } = await import("./scope-persistence-habn4q8a.js");
|
|
41
43
|
return realWrite(directory, taskId, files);
|
|
42
44
|
},
|
|
43
45
|
writeLaneProfileToDisk: async (_worktreePath, _laneIndex, _envOverrides) => {
|
|
@@ -2,24 +2,26 @@
|
|
|
2
2
|
import {
|
|
3
3
|
ALLOWED_SKILL_PATH_PREFIXES,
|
|
4
4
|
validateSkillPath
|
|
5
|
-
} from "./index-
|
|
5
|
+
} from "./index-dx2c2wjt.js";
|
|
6
6
|
import {
|
|
7
7
|
computeOutcomeSignal,
|
|
8
8
|
readKnowledge,
|
|
9
9
|
resolveHiveKnowledgePath,
|
|
10
10
|
resolveSwarmKnowledgePath,
|
|
11
11
|
transactKnowledge
|
|
12
|
-
} from "./index-
|
|
12
|
+
} from "./index-yt1v62pv.js";
|
|
13
13
|
import {
|
|
14
14
|
effectiveRetrievalOutcomes,
|
|
15
15
|
readKnowledgeCounterRollups
|
|
16
|
-
} from "./index-
|
|
16
|
+
} from "./index-n6chz2g8.js";
|
|
17
17
|
import {
|
|
18
|
+
init_knowledge_types,
|
|
18
19
|
isActiveStatus
|
|
19
|
-
} from "./index-
|
|
20
|
+
} from "./index-bk5tah7q.js";
|
|
20
21
|
import {
|
|
21
|
-
advisoryWarn
|
|
22
|
-
|
|
22
|
+
advisoryWarn,
|
|
23
|
+
init_warning_buffer
|
|
24
|
+
} from "./index-gacm5s2n.js";
|
|
23
25
|
import {
|
|
24
26
|
init_logger,
|
|
25
27
|
log,
|
|
@@ -35,10 +37,11 @@ import { mkdir as mkdir4, readFile as readFile4, rename as rename3, unlink, writ
|
|
|
35
37
|
import * as path4 from "path";
|
|
36
38
|
|
|
37
39
|
// src/config/bundled-skills.ts
|
|
40
|
+
init_warning_buffer();
|
|
41
|
+
init_logger();
|
|
38
42
|
import { randomUUID } from "crypto";
|
|
39
43
|
import * as fsp from "fs/promises";
|
|
40
44
|
import * as path from "path";
|
|
41
|
-
init_logger();
|
|
42
45
|
var BUNDLED_PROJECT_SKILLS = [
|
|
43
46
|
"brainstorm",
|
|
44
47
|
"specify",
|
|
@@ -326,6 +329,7 @@ async function syncBundledProjectSkillsIfMissingAsync(projectDirectory, packageR
|
|
|
326
329
|
}
|
|
327
330
|
|
|
328
331
|
// src/services/skill-generator.ts
|
|
332
|
+
init_knowledge_types();
|
|
329
333
|
init_logger();
|
|
330
334
|
|
|
331
335
|
// src/services/skill-changelog.ts
|