@agntk/agent-harness 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/NOTICE +41 -0
- package/README.md +445 -0
- package/defaults/agents/summarizer.md +49 -0
- package/defaults/instincts/lead-with-answer.md +24 -0
- package/defaults/instincts/qualify-before-recommending.md +40 -0
- package/defaults/instincts/read-before-edit.md +23 -0
- package/defaults/instincts/search-before-create.md +23 -0
- package/defaults/playbooks/ship-feature.md +31 -0
- package/defaults/rules/ask-before-assuming.md +35 -0
- package/defaults/rules/operations.md +35 -0
- package/defaults/rules/respect-the-user.md +39 -0
- package/defaults/skills/business-analyst.md +181 -0
- package/defaults/skills/content-marketer.md +184 -0
- package/defaults/skills/research.md +34 -0
- package/defaults/tools/example-web-search.md +60 -0
- package/defaults/workflows/daily-reflection.md +54 -0
- package/dist/agent-framework-K4GUIICH.js +344 -0
- package/dist/agent-framework-K4GUIICH.js.map +1 -0
- package/dist/analytics-RPT73WNM.js +12 -0
- package/dist/analytics-RPT73WNM.js.map +1 -0
- package/dist/auto-processor-OLE45UI3.js +13 -0
- package/dist/auto-processor-OLE45UI3.js.map +1 -0
- package/dist/chunk-274RV3YO.js +162 -0
- package/dist/chunk-274RV3YO.js.map +1 -0
- package/dist/chunk-4CWAGBNS.js +168 -0
- package/dist/chunk-4CWAGBNS.js.map +1 -0
- package/dist/chunk-4FDUOGSZ.js +69 -0
- package/dist/chunk-4FDUOGSZ.js.map +1 -0
- package/dist/chunk-5H34JPMB.js +199 -0
- package/dist/chunk-5H34JPMB.js.map +1 -0
- package/dist/chunk-6EMOEYGU.js +102 -0
- package/dist/chunk-6EMOEYGU.js.map +1 -0
- package/dist/chunk-A7BJPQQ6.js +236 -0
- package/dist/chunk-A7BJPQQ6.js.map +1 -0
- package/dist/chunk-AGAAFJEO.js +76 -0
- package/dist/chunk-AGAAFJEO.js.map +1 -0
- package/dist/chunk-BSKDOFRT.js +65 -0
- package/dist/chunk-BSKDOFRT.js.map +1 -0
- package/dist/chunk-CHJ5GNZC.js +100 -0
- package/dist/chunk-CHJ5GNZC.js.map +1 -0
- package/dist/chunk-CSL3ERUI.js +307 -0
- package/dist/chunk-CSL3ERUI.js.map +1 -0
- package/dist/chunk-DA7IKHC4.js +229 -0
- package/dist/chunk-DA7IKHC4.js.map +1 -0
- package/dist/chunk-DGUM43GV.js +11 -0
- package/dist/chunk-DGUM43GV.js.map +1 -0
- package/dist/chunk-DTTXPHFW.js +211 -0
- package/dist/chunk-DTTXPHFW.js.map +1 -0
- package/dist/chunk-FD55B3IO.js +204 -0
- package/dist/chunk-FD55B3IO.js.map +1 -0
- package/dist/chunk-FLZU44SV.js +230 -0
- package/dist/chunk-FLZU44SV.js.map +1 -0
- package/dist/chunk-GJNNR2RA.js +200 -0
- package/dist/chunk-GJNNR2RA.js.map +1 -0
- package/dist/chunk-GNUSHD2Y.js +111 -0
- package/dist/chunk-GNUSHD2Y.js.map +1 -0
- package/dist/chunk-GUJTBGVS.js +2212 -0
- package/dist/chunk-GUJTBGVS.js.map +1 -0
- package/dist/chunk-IZ6UZ3ZL.js +207 -0
- package/dist/chunk-IZ6UZ3ZL.js.map +1 -0
- package/dist/chunk-JKMGYWXB.js +197 -0
- package/dist/chunk-JKMGYWXB.js.map +1 -0
- package/dist/chunk-KFX54TQM.js +165 -0
- package/dist/chunk-KFX54TQM.js.map +1 -0
- package/dist/chunk-M7NXUK55.js +199 -0
- package/dist/chunk-M7NXUK55.js.map +1 -0
- package/dist/chunk-MPZ3BPUI.js +374 -0
- package/dist/chunk-MPZ3BPUI.js.map +1 -0
- package/dist/chunk-OC6YSTDX.js +119 -0
- package/dist/chunk-OC6YSTDX.js.map +1 -0
- package/dist/chunk-RC6MEZB6.js +469 -0
- package/dist/chunk-RC6MEZB6.js.map +1 -0
- package/dist/chunk-RY3ZFII7.js +3440 -0
- package/dist/chunk-RY3ZFII7.js.map +1 -0
- package/dist/chunk-TAT6JU3X.js +167 -0
- package/dist/chunk-TAT6JU3X.js.map +1 -0
- package/dist/chunk-UDZIS2AQ.js +79 -0
- package/dist/chunk-UDZIS2AQ.js.map +1 -0
- package/dist/chunk-UPLBF4RZ.js +115 -0
- package/dist/chunk-UPLBF4RZ.js.map +1 -0
- package/dist/chunk-UWQTZMNI.js +154 -0
- package/dist/chunk-UWQTZMNI.js.map +1 -0
- package/dist/chunk-W4T7PGI2.js +346 -0
- package/dist/chunk-W4T7PGI2.js.map +1 -0
- package/dist/chunk-XTBKL5BI.js +111 -0
- package/dist/chunk-XTBKL5BI.js.map +1 -0
- package/dist/chunk-YIJY5DBV.js +399 -0
- package/dist/chunk-YIJY5DBV.js.map +1 -0
- package/dist/chunk-YUFNYN2H.js +242 -0
- package/dist/chunk-YUFNYN2H.js.map +1 -0
- package/dist/chunk-Z2PUCXTZ.js +94 -0
- package/dist/chunk-Z2PUCXTZ.js.map +1 -0
- package/dist/chunk-ZZJOFKAT.js +13 -0
- package/dist/chunk-ZZJOFKAT.js.map +1 -0
- package/dist/cli/index.js +3661 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/config-WVMRUOCA.js +13 -0
- package/dist/config-WVMRUOCA.js.map +1 -0
- package/dist/context-loader-3ORBPMHJ.js +13 -0
- package/dist/context-loader-3ORBPMHJ.js.map +1 -0
- package/dist/conversation-QDEIDQPH.js +22 -0
- package/dist/conversation-QDEIDQPH.js.map +1 -0
- package/dist/cost-tracker-RS3W7SVY.js +24 -0
- package/dist/cost-tracker-RS3W7SVY.js.map +1 -0
- package/dist/delegate-VJCJLYEK.js +29 -0
- package/dist/delegate-VJCJLYEK.js.map +1 -0
- package/dist/emotional-state-VQVRA6ED.js +206 -0
- package/dist/emotional-state-VQVRA6ED.js.map +1 -0
- package/dist/env-discovery-2BLVMAIM.js +251 -0
- package/dist/env-discovery-2BLVMAIM.js.map +1 -0
- package/dist/export-6GCYHEHQ.js +165 -0
- package/dist/export-6GCYHEHQ.js.map +1 -0
- package/dist/graph-YUIPOSOO.js +14 -0
- package/dist/graph-YUIPOSOO.js.map +1 -0
- package/dist/harness-LCHA3DWP.js +10 -0
- package/dist/harness-LCHA3DWP.js.map +1 -0
- package/dist/harness-WE4SLCML.js +26 -0
- package/dist/harness-WE4SLCML.js.map +1 -0
- package/dist/health-NZ6WNIMV.js +23 -0
- package/dist/health-NZ6WNIMV.js.map +1 -0
- package/dist/index.d.ts +3612 -0
- package/dist/index.js +13501 -0
- package/dist/index.js.map +1 -0
- package/dist/indexer-LONANRRM.js +16 -0
- package/dist/indexer-LONANRRM.js.map +1 -0
- package/dist/instinct-learner-SRM72DHF.js +20 -0
- package/dist/instinct-learner-SRM72DHF.js.map +1 -0
- package/dist/intake-4M3HNU43.js +21 -0
- package/dist/intake-4M3HNU43.js.map +1 -0
- package/dist/intelligence-HJOCA4SJ.js +1081 -0
- package/dist/intelligence-HJOCA4SJ.js.map +1 -0
- package/dist/journal-WANJL3MI.js +24 -0
- package/dist/journal-WANJL3MI.js.map +1 -0
- package/dist/loader-C3TKIKZR.js +23 -0
- package/dist/loader-C3TKIKZR.js.map +1 -0
- package/dist/mcp-WTQJJZAO.js +15 -0
- package/dist/mcp-WTQJJZAO.js.map +1 -0
- package/dist/mcp-discovery-WPAQFL6S.js +377 -0
- package/dist/mcp-discovery-WPAQFL6S.js.map +1 -0
- package/dist/mcp-installer-6O2XXD3V.js +394 -0
- package/dist/mcp-installer-6O2XXD3V.js.map +1 -0
- package/dist/metrics-KXGNFAAB.js +20 -0
- package/dist/metrics-KXGNFAAB.js.map +1 -0
- package/dist/primitive-registry-I6VTIR4W.js +512 -0
- package/dist/primitive-registry-I6VTIR4W.js.map +1 -0
- package/dist/project-discovery-C4UMD7JI.js +246 -0
- package/dist/project-discovery-C4UMD7JI.js.map +1 -0
- package/dist/provider-LQHQX7Z7.js +26 -0
- package/dist/provider-LQHQX7Z7.js.map +1 -0
- package/dist/provider-SXPQZ74H.js +28 -0
- package/dist/provider-SXPQZ74H.js.map +1 -0
- package/dist/rate-limiter-RLRVM325.js +22 -0
- package/dist/rate-limiter-RLRVM325.js.map +1 -0
- package/dist/rule-engine-YGQ3RYZM.js +182 -0
- package/dist/rule-engine-YGQ3RYZM.js.map +1 -0
- package/dist/scaffold-A3VRRCBV.js +347 -0
- package/dist/scaffold-A3VRRCBV.js.map +1 -0
- package/dist/scheduler-XHHIVHRI.js +397 -0
- package/dist/scheduler-XHHIVHRI.js.map +1 -0
- package/dist/search-V3W5JMJG.js +75 -0
- package/dist/search-V3W5JMJG.js.map +1 -0
- package/dist/semantic-search-2DTOO5UX.js +241 -0
- package/dist/semantic-search-2DTOO5UX.js.map +1 -0
- package/dist/serve-DTQ3HENY.js +291 -0
- package/dist/serve-DTQ3HENY.js.map +1 -0
- package/dist/sessions-CZGVXKQE.js +21 -0
- package/dist/sessions-CZGVXKQE.js.map +1 -0
- package/dist/sources-RW5DT56F.js +32 -0
- package/dist/sources-RW5DT56F.js.map +1 -0
- package/dist/starter-packs-76YUVHEU.js +893 -0
- package/dist/starter-packs-76YUVHEU.js.map +1 -0
- package/dist/state-GMXILIHW.js +13 -0
- package/dist/state-GMXILIHW.js.map +1 -0
- package/dist/state-merge-NKO5FRBA.js +174 -0
- package/dist/state-merge-NKO5FRBA.js.map +1 -0
- package/dist/telemetry-UC6PBXC7.js +22 -0
- package/dist/telemetry-UC6PBXC7.js.map +1 -0
- package/dist/tool-executor-MJ7IG7PQ.js +28 -0
- package/dist/tool-executor-MJ7IG7PQ.js.map +1 -0
- package/dist/tools-DZ4KETET.js +20 -0
- package/dist/tools-DZ4KETET.js.map +1 -0
- package/dist/types-EW7AIB3R.js +18 -0
- package/dist/types-EW7AIB3R.js.map +1 -0
- package/dist/types-WGDLSPO6.js +16 -0
- package/dist/types-WGDLSPO6.js.map +1 -0
- package/dist/universal-installer-QGS4SJGX.js +578 -0
- package/dist/universal-installer-QGS4SJGX.js.map +1 -0
- package/dist/validator-7WXMDIHH.js +22 -0
- package/dist/validator-7WXMDIHH.js.map +1 -0
- package/dist/verification-gate-FYXUX6LH.js +246 -0
- package/dist/verification-gate-FYXUX6LH.js.map +1 -0
- package/dist/versioning-Z3XNE2Q2.js +271 -0
- package/dist/versioning-Z3XNE2Q2.js.map +1 -0
- package/dist/watcher-ISJC7YKL.js +109 -0
- package/dist/watcher-ISJC7YKL.js.map +1 -0
- package/dist/web-server-DD7ZOP46.js +28 -0
- package/dist/web-server-DD7ZOP46.js.map +1 -0
- package/package.json +76 -0
- package/sources.yaml +121 -0
- package/templates/assistant/CORE.md +24 -0
- package/templates/assistant/SYSTEM.md +24 -0
- package/templates/assistant/config.yaml +51 -0
- package/templates/base/CORE.md +17 -0
- package/templates/base/SYSTEM.md +24 -0
- package/templates/base/config.yaml +51 -0
- package/templates/claude-opus/config.yaml +51 -0
- package/templates/code-reviewer/CORE.md +25 -0
- package/templates/code-reviewer/SYSTEM.md +30 -0
- package/templates/code-reviewer/config.yaml +51 -0
- package/templates/gpt4/config.yaml +51 -0
- package/templates/local/config.yaml +51 -0
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
log
|
|
5
|
+
} from "./chunk-BSKDOFRT.js";
|
|
6
|
+
import "./chunk-ZZJOFKAT.js";
|
|
7
|
+
|
|
8
|
+
// src/runtime/versioning.ts
|
|
9
|
+
import { existsSync, writeFileSync } from "fs";
|
|
10
|
+
import { join, relative } from "path";
|
|
11
|
+
import { execSync } from "child_process";
|
|
12
|
+
var HARNESS_GIT_AUTHOR_NAME = "agent-harness";
|
|
13
|
+
var HARNESS_GIT_AUTHOR_EMAIL = "versioning@agent-harness.local";
|
|
14
|
+
function gitExec(harnessDir, args) {
|
|
15
|
+
try {
|
|
16
|
+
const result = execSync(
|
|
17
|
+
`git -c user.name="${HARNESS_GIT_AUTHOR_NAME}" -c user.email="${HARNESS_GIT_AUTHOR_EMAIL}" ${args}`,
|
|
18
|
+
{
|
|
19
|
+
cwd: harnessDir,
|
|
20
|
+
encoding: "utf-8",
|
|
21
|
+
timeout: 1e4,
|
|
22
|
+
stdio: ["pipe", "pipe", "pipe"]
|
|
23
|
+
}
|
|
24
|
+
);
|
|
25
|
+
return result.trim();
|
|
26
|
+
} catch {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function isGitRepo(harnessDir) {
|
|
31
|
+
return gitExec(harnessDir, "rev-parse --is-inside-work-tree") === "true";
|
|
32
|
+
}
|
|
33
|
+
function initVersioning(harnessDir) {
|
|
34
|
+
if (isGitRepo(harnessDir)) return true;
|
|
35
|
+
const result = gitExec(harnessDir, "init");
|
|
36
|
+
if (result === null) {
|
|
37
|
+
log.warn("Failed to initialize git repository for versioning");
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
const gitignorePath = join(harnessDir, ".gitignore");
|
|
41
|
+
if (!existsSync(gitignorePath)) {
|
|
42
|
+
const gitignoreContent = [
|
|
43
|
+
"# Agent harness versioning",
|
|
44
|
+
"memory/sessions/",
|
|
45
|
+
"memory/metrics.json",
|
|
46
|
+
"memory/health.json",
|
|
47
|
+
"memory/costs.json",
|
|
48
|
+
"memory/rate-limits.json",
|
|
49
|
+
"memory/emotional-history.jsonl",
|
|
50
|
+
"memory/locks/",
|
|
51
|
+
".installed/",
|
|
52
|
+
"archive/",
|
|
53
|
+
"node_modules/"
|
|
54
|
+
].join("\n") + "\n";
|
|
55
|
+
writeFileSync(gitignorePath, gitignoreContent, "utf-8");
|
|
56
|
+
}
|
|
57
|
+
gitExec(harnessDir, "add -A");
|
|
58
|
+
gitExec(harnessDir, 'commit -m "Initial harness version" --allow-empty');
|
|
59
|
+
return true;
|
|
60
|
+
}
|
|
61
|
+
function snapshot(harnessDir, message, options) {
|
|
62
|
+
if (!isGitRepo(harnessDir)) {
|
|
63
|
+
if (!initVersioning(harnessDir)) {
|
|
64
|
+
return { success: false, hash: "", files: [], error: "Failed to initialize git repository" };
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const dirsToTrack = [
|
|
68
|
+
"rules",
|
|
69
|
+
"instincts",
|
|
70
|
+
"skills",
|
|
71
|
+
"playbooks",
|
|
72
|
+
"workflows",
|
|
73
|
+
"tools",
|
|
74
|
+
"agents",
|
|
75
|
+
"memory/journal",
|
|
76
|
+
"memory/state.md",
|
|
77
|
+
"memory/scratch.md",
|
|
78
|
+
"memory/state-ownership.json",
|
|
79
|
+
"memory/emotional-state.json",
|
|
80
|
+
"CORE.md",
|
|
81
|
+
"SYSTEM.md",
|
|
82
|
+
"config.yaml"
|
|
83
|
+
];
|
|
84
|
+
const stagedFiles = [];
|
|
85
|
+
for (const dir of dirsToTrack) {
|
|
86
|
+
const fullPath = join(harnessDir, dir);
|
|
87
|
+
if (existsSync(fullPath)) {
|
|
88
|
+
gitExec(harnessDir, `add "${dir}"`);
|
|
89
|
+
stagedFiles.push(dir);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
const status = gitExec(harnessDir, "diff --cached --name-only");
|
|
93
|
+
if (!status || status.length === 0) {
|
|
94
|
+
return { success: true, hash: getHeadHash(harnessDir) ?? "", files: [], error: "No changes to commit" };
|
|
95
|
+
}
|
|
96
|
+
const changedFiles = status.split("\n").filter(Boolean);
|
|
97
|
+
const commitResult = gitExec(harnessDir, `commit -m "${escapeMessage(message)}"`);
|
|
98
|
+
if (commitResult === null) {
|
|
99
|
+
return { success: false, hash: "", files: changedFiles, error: "Git commit failed" };
|
|
100
|
+
}
|
|
101
|
+
const hash = getHeadHash(harnessDir) ?? "";
|
|
102
|
+
if (options?.tag) {
|
|
103
|
+
gitExec(harnessDir, `tag "${escapeMessage(options.tag)}"`);
|
|
104
|
+
}
|
|
105
|
+
return { success: true, hash, files: changedFiles };
|
|
106
|
+
}
|
|
107
|
+
function getVersionLog(harnessDir, options) {
|
|
108
|
+
if (!isGitRepo(harnessDir)) {
|
|
109
|
+
return { entries: [], currentHash: "" };
|
|
110
|
+
}
|
|
111
|
+
const limit = options?.limit ?? 50;
|
|
112
|
+
const fileFilter = options?.file ? ` -- "${options.file}"` : "";
|
|
113
|
+
const format = "%H|%h|%s|%aI|%an";
|
|
114
|
+
const logOutput = gitExec(harnessDir, `log --format="${format}" -n ${limit}${fileFilter}`);
|
|
115
|
+
if (!logOutput) {
|
|
116
|
+
return { entries: [], currentHash: getHeadHash(harnessDir) ?? "" };
|
|
117
|
+
}
|
|
118
|
+
const entries = [];
|
|
119
|
+
for (const line of logOutput.split("\n")) {
|
|
120
|
+
if (!line.trim()) continue;
|
|
121
|
+
const parts = line.split("|");
|
|
122
|
+
if (parts.length < 5) continue;
|
|
123
|
+
const fullHash = parts[0];
|
|
124
|
+
const hash = parts[1];
|
|
125
|
+
const filesOutput = gitExec(harnessDir, `diff-tree --no-commit-id --name-only -r ${fullHash}`);
|
|
126
|
+
const filesChanged = filesOutput ? filesOutput.split("\n").filter(Boolean) : [];
|
|
127
|
+
const tagOutput = gitExec(harnessDir, `tag --points-at ${fullHash}`);
|
|
128
|
+
const tag = tagOutput && tagOutput.length > 0 ? tagOutput.split("\n")[0] : void 0;
|
|
129
|
+
entries.push({
|
|
130
|
+
hash,
|
|
131
|
+
fullHash,
|
|
132
|
+
message: parts[2],
|
|
133
|
+
timestamp: parts[3],
|
|
134
|
+
author: parts.slice(4).join("|"),
|
|
135
|
+
filesChanged,
|
|
136
|
+
tag
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
const currentHash = getHeadHash(harnessDir) ?? "";
|
|
140
|
+
const currentTag = entries.length > 0 && entries[0].tag ? entries[0].tag : void 0;
|
|
141
|
+
return { entries, currentHash, currentTag };
|
|
142
|
+
}
|
|
143
|
+
function getVersionDiff(harnessDir, from, to) {
|
|
144
|
+
if (!isGitRepo(harnessDir)) {
|
|
145
|
+
return { from, to: to ?? "HEAD", entries: [], summary: "Not a git repository" };
|
|
146
|
+
}
|
|
147
|
+
const target = to ?? "HEAD";
|
|
148
|
+
const diffOutput = gitExec(harnessDir, `diff --numstat ${from} ${target}`);
|
|
149
|
+
const nameOutput = gitExec(harnessDir, `diff --name-status ${from} ${target}`);
|
|
150
|
+
const entries = [];
|
|
151
|
+
if (nameOutput) {
|
|
152
|
+
const nameLines = nameOutput.split("\n").filter(Boolean);
|
|
153
|
+
const statLines = (diffOutput ?? "").split("\n").filter(Boolean);
|
|
154
|
+
for (let i = 0; i < nameLines.length; i++) {
|
|
155
|
+
const nameParts = nameLines[i].split(" ");
|
|
156
|
+
const statusChar = nameParts[0];
|
|
157
|
+
const file = nameParts[nameParts.length - 1];
|
|
158
|
+
let status = "modified";
|
|
159
|
+
if (statusChar === "A") status = "added";
|
|
160
|
+
else if (statusChar === "D") status = "deleted";
|
|
161
|
+
else if (statusChar.startsWith("R")) status = "renamed";
|
|
162
|
+
const entry = { file, status };
|
|
163
|
+
if (i < statLines.length) {
|
|
164
|
+
const statParts = statLines[i].split(" ");
|
|
165
|
+
if (statParts.length >= 2) {
|
|
166
|
+
const adds = parseInt(statParts[0], 10);
|
|
167
|
+
const dels = parseInt(statParts[1], 10);
|
|
168
|
+
if (!isNaN(adds)) entry.additions = adds;
|
|
169
|
+
if (!isNaN(dels)) entry.deletions = dels;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
entries.push(entry);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
const added = entries.filter((e) => e.status === "added").length;
|
|
176
|
+
const modified = entries.filter((e) => e.status === "modified").length;
|
|
177
|
+
const deleted = entries.filter((e) => e.status === "deleted").length;
|
|
178
|
+
const summary = `${entries.length} file(s) changed: ${added} added, ${modified} modified, ${deleted} deleted`;
|
|
179
|
+
return { from, to: target, entries, summary };
|
|
180
|
+
}
|
|
181
|
+
function rollback(harnessDir, targetHash) {
|
|
182
|
+
if (!isGitRepo(harnessDir)) {
|
|
183
|
+
return { success: false, targetHash, restoredFiles: [], error: "Not a git repository" };
|
|
184
|
+
}
|
|
185
|
+
const resolvedHash = gitExec(harnessDir, `rev-parse --verify ${targetHash}`);
|
|
186
|
+
if (!resolvedHash) {
|
|
187
|
+
return { success: false, targetHash, restoredFiles: [], error: `Invalid version: ${targetHash}` };
|
|
188
|
+
}
|
|
189
|
+
const diff = getVersionDiff(harnessDir, "HEAD", resolvedHash);
|
|
190
|
+
const restoredFiles = diff.entries.map((e) => e.file);
|
|
191
|
+
const restoreResult = gitExec(harnessDir, `checkout ${resolvedHash} -- .`);
|
|
192
|
+
if (restoreResult === null) {
|
|
193
|
+
return { success: false, targetHash: resolvedHash, restoredFiles: [], error: "Failed to restore files" };
|
|
194
|
+
}
|
|
195
|
+
gitExec(harnessDir, "add -A");
|
|
196
|
+
const shortHash = resolvedHash.slice(0, 7);
|
|
197
|
+
const commitResult = gitExec(harnessDir, `commit -m "Rollback to ${shortHash}" --allow-empty`);
|
|
198
|
+
if (commitResult === null) {
|
|
199
|
+
return { success: false, targetHash: resolvedHash, restoredFiles, error: "Failed to commit rollback" };
|
|
200
|
+
}
|
|
201
|
+
return { success: true, targetHash: resolvedHash, restoredFiles };
|
|
202
|
+
}
|
|
203
|
+
function listTags(harnessDir) {
|
|
204
|
+
if (!isGitRepo(harnessDir)) return [];
|
|
205
|
+
const output = gitExec(harnessDir, "tag -l");
|
|
206
|
+
if (!output) return [];
|
|
207
|
+
const tags = [];
|
|
208
|
+
for (const tag of output.split("\n").filter(Boolean)) {
|
|
209
|
+
const hash = gitExec(harnessDir, `rev-parse ${tag}`);
|
|
210
|
+
const message = gitExec(harnessDir, `log -1 --format=%s ${tag}`);
|
|
211
|
+
tags.push({
|
|
212
|
+
tag,
|
|
213
|
+
hash: hash ? hash.slice(0, 7) : "",
|
|
214
|
+
message: message ?? ""
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
return tags;
|
|
218
|
+
}
|
|
219
|
+
function tagVersion(harnessDir, tag, message) {
|
|
220
|
+
if (!isGitRepo(harnessDir)) return false;
|
|
221
|
+
if (message) {
|
|
222
|
+
return gitExec(harnessDir, `tag -a "${escapeMessage(tag)}" -m "${escapeMessage(message)}"`) !== null;
|
|
223
|
+
}
|
|
224
|
+
return gitExec(harnessDir, `tag "${escapeMessage(tag)}"`) !== null;
|
|
225
|
+
}
|
|
226
|
+
function getPendingChanges(harnessDir) {
|
|
227
|
+
if (!isGitRepo(harnessDir)) return [];
|
|
228
|
+
const output = gitExec(harnessDir, "status --porcelain");
|
|
229
|
+
if (!output) return [];
|
|
230
|
+
const entries = [];
|
|
231
|
+
for (const line of output.split("\n").filter(Boolean)) {
|
|
232
|
+
const statusChar = line.substring(0, 2).trim();
|
|
233
|
+
const file = line.substring(3);
|
|
234
|
+
let status = "modified";
|
|
235
|
+
if (statusChar === "??" || statusChar === "A") status = "added";
|
|
236
|
+
else if (statusChar === "D") status = "deleted";
|
|
237
|
+
else if (statusChar.startsWith("R")) status = "renamed";
|
|
238
|
+
entries.push({ file, status });
|
|
239
|
+
}
|
|
240
|
+
return entries;
|
|
241
|
+
}
|
|
242
|
+
function getFileHistory(harnessDir, filePath, options) {
|
|
243
|
+
const relPath = relative(harnessDir, join(harnessDir, filePath));
|
|
244
|
+
const log2 = getVersionLog(harnessDir, { limit: options?.limit ?? 20, file: relPath });
|
|
245
|
+
return log2.entries;
|
|
246
|
+
}
|
|
247
|
+
function getFileAtVersion(harnessDir, filePath, hash) {
|
|
248
|
+
if (!isGitRepo(harnessDir)) return null;
|
|
249
|
+
const relPath = relative(harnessDir, join(harnessDir, filePath));
|
|
250
|
+
return gitExec(harnessDir, `show ${hash}:"${relPath}"`);
|
|
251
|
+
}
|
|
252
|
+
function getHeadHash(harnessDir) {
|
|
253
|
+
return gitExec(harnessDir, "rev-parse HEAD");
|
|
254
|
+
}
|
|
255
|
+
function escapeMessage(msg) {
|
|
256
|
+
return msg.replace(/"/g, '\\"').replace(/\n/g, " ");
|
|
257
|
+
}
|
|
258
|
+
export {
|
|
259
|
+
getFileAtVersion,
|
|
260
|
+
getFileHistory,
|
|
261
|
+
getPendingChanges,
|
|
262
|
+
getVersionDiff,
|
|
263
|
+
getVersionLog,
|
|
264
|
+
initVersioning,
|
|
265
|
+
isGitRepo,
|
|
266
|
+
listTags,
|
|
267
|
+
rollback,
|
|
268
|
+
snapshot,
|
|
269
|
+
tagVersion
|
|
270
|
+
};
|
|
271
|
+
//# sourceMappingURL=versioning-Z3XNE2Q2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/runtime/versioning.ts"],"sourcesContent":["import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';\nimport { join, relative } from 'path';\nimport { execSync } from 'child_process';\nimport { log } from '../core/logger.js';\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\nexport interface VersionEntry {\n /** Git commit hash (short) */\n hash: string;\n /** Full commit hash */\n fullHash: string;\n /** Commit message */\n message: string;\n /** Timestamp (ISO string) */\n timestamp: string;\n /** Files changed in this version */\n filesChanged: string[];\n /** Author name */\n author: string;\n /** Tag if one was applied */\n tag?: string;\n}\n\nexport interface VersionLog {\n /** Ordered list of versions (newest first) */\n entries: VersionEntry[];\n /** Current HEAD hash */\n currentHash: string;\n /** Current tag if any */\n currentTag?: string;\n}\n\nexport interface RollbackResult {\n success: boolean;\n /** Hash we rolled back to */\n targetHash: string;\n /** Files that were restored */\n restoredFiles: string[];\n /** Error message if failed */\n error?: string;\n}\n\nexport interface SnapshotResult {\n success: boolean;\n /** New commit hash */\n hash: string;\n /** Files included in snapshot */\n files: string[];\n /** Error if failed */\n error?: string;\n}\n\nexport interface DiffEntry {\n file: string;\n status: 'added' | 'modified' | 'deleted' | 'renamed';\n /** Lines added */\n additions?: number;\n /** Lines deleted */\n deletions?: number;\n}\n\nexport interface VersionDiff {\n from: string;\n to: string;\n entries: DiffEntry[];\n summary: string;\n}\n\n// ─── Git Helpers ─────────────────────────────────────────────────────────────\n\n/**\n * Identity used for internal harness versioning commits. This keeps harness\n * snapshots functional on machines (and CI runners) where the user has no\n * global `user.name` / `user.email` configured. Harness versioning is an\n * internal bookkeeping feature; the commits never leave the user's disk,\n * so a synthetic identity is appropriate and doesn't pollute user git history.\n */\nconst HARNESS_GIT_AUTHOR_NAME = 'agent-harness';\nconst HARNESS_GIT_AUTHOR_EMAIL = 'versioning@agent-harness.local';\n\n/**\n * Execute a git command in the harness directory.\n * Returns stdout as a string, or null if the command failed.\n *\n * All invocations automatically inject a synthetic author identity so commits\n * succeed on machines without global git user config (e.g. CI runners, Docker\n * containers, fresh VMs).\n */\nfunction gitExec(harnessDir: string, args: string): string | null {\n try {\n const result = execSync(\n `git -c user.name=\"${HARNESS_GIT_AUTHOR_NAME}\" -c user.email=\"${HARNESS_GIT_AUTHOR_EMAIL}\" ${args}`,\n {\n cwd: harnessDir,\n encoding: 'utf-8',\n timeout: 10000,\n stdio: ['pipe', 'pipe', 'pipe'],\n },\n );\n return result.trim();\n } catch {\n return null;\n }\n}\n\n/**\n * Check if the harness directory is a git repository.\n */\nexport function isGitRepo(harnessDir: string): boolean {\n return gitExec(harnessDir, 'rev-parse --is-inside-work-tree') === 'true';\n}\n\n/**\n * Initialize a git repository in the harness directory.\n * If already initialized, this is a no-op.\n */\nexport function initVersioning(harnessDir: string): boolean {\n if (isGitRepo(harnessDir)) return true;\n\n const result = gitExec(harnessDir, 'init');\n if (result === null) {\n log.warn('Failed to initialize git repository for versioning');\n return false;\n }\n\n // Create .gitignore for non-versioned files\n const gitignorePath = join(harnessDir, '.gitignore');\n if (!existsSync(gitignorePath)) {\n const gitignoreContent = [\n '# Agent harness versioning',\n 'memory/sessions/',\n 'memory/metrics.json',\n 'memory/health.json',\n 'memory/costs.json',\n 'memory/rate-limits.json',\n 'memory/emotional-history.jsonl',\n 'memory/locks/',\n '.installed/',\n 'archive/',\n 'node_modules/',\n ].join('\\n') + '\\n';\n writeFileSync(gitignorePath, gitignoreContent, 'utf-8');\n }\n\n // Initial commit\n gitExec(harnessDir, 'add -A');\n gitExec(harnessDir, 'commit -m \"Initial harness version\" --allow-empty');\n\n return true;\n}\n\n// ─── Snapshot (Commit) ──────────────────────────────────────────────────────\n\n/**\n * Take a versioned snapshot of the current harness state.\n * Stages all changes and creates a git commit.\n *\n * @param harnessDir - Harness directory path\n * @param message - Commit message describing the change\n * @param options.tag - Optional tag to apply to this version\n */\nexport function snapshot(\n harnessDir: string,\n message: string,\n options?: { tag?: string },\n): SnapshotResult {\n if (!isGitRepo(harnessDir)) {\n if (!initVersioning(harnessDir)) {\n return { success: false, hash: '', files: [], error: 'Failed to initialize git repository' };\n }\n }\n\n // Stage all tracked primitive directories\n const dirsToTrack = [\n 'rules', 'instincts', 'skills', 'playbooks', 'workflows',\n 'tools', 'agents', 'memory/journal', 'memory/state.md',\n 'memory/scratch.md', 'memory/state-ownership.json',\n 'memory/emotional-state.json',\n 'CORE.md', 'SYSTEM.md', 'config.yaml',\n ];\n\n const stagedFiles: string[] = [];\n for (const dir of dirsToTrack) {\n const fullPath = join(harnessDir, dir);\n if (existsSync(fullPath)) {\n gitExec(harnessDir, `add \"${dir}\"`);\n stagedFiles.push(dir);\n }\n }\n\n // Check if there are staged changes\n const status = gitExec(harnessDir, 'diff --cached --name-only');\n if (!status || status.length === 0) {\n return { success: true, hash: getHeadHash(harnessDir) ?? '', files: [], error: 'No changes to commit' };\n }\n\n const changedFiles = status.split('\\n').filter(Boolean);\n\n // Commit\n const commitResult = gitExec(harnessDir, `commit -m \"${escapeMessage(message)}\"`);\n if (commitResult === null) {\n return { success: false, hash: '', files: changedFiles, error: 'Git commit failed' };\n }\n\n const hash = getHeadHash(harnessDir) ?? '';\n\n // Tag if requested\n if (options?.tag) {\n gitExec(harnessDir, `tag \"${escapeMessage(options.tag)}\"`);\n }\n\n return { success: true, hash, files: changedFiles };\n}\n\n// ─── Version Log ────────────────────────────────────────────────────────────\n\n/**\n * Get the version history of the harness.\n *\n * @param harnessDir - Harness directory path\n * @param options.limit - Maximum entries to return (default: 50)\n * @param options.file - Filter to a specific file path\n */\nexport function getVersionLog(\n harnessDir: string,\n options?: { limit?: number; file?: string },\n): VersionLog {\n if (!isGitRepo(harnessDir)) {\n return { entries: [], currentHash: '' };\n }\n\n const limit = options?.limit ?? 50;\n const fileFilter = options?.file ? ` -- \"${options.file}\"` : '';\n const format = '%H|%h|%s|%aI|%an';\n\n const logOutput = gitExec(harnessDir, `log --format=\"${format}\" -n ${limit}${fileFilter}`);\n if (!logOutput) {\n return { entries: [], currentHash: getHeadHash(harnessDir) ?? '' };\n }\n\n const entries: VersionEntry[] = [];\n\n for (const line of logOutput.split('\\n')) {\n if (!line.trim()) continue;\n const parts = line.split('|');\n if (parts.length < 5) continue;\n\n const fullHash = parts[0];\n const hash = parts[1];\n\n // Get files changed in this commit\n const filesOutput = gitExec(harnessDir, `diff-tree --no-commit-id --name-only -r ${fullHash}`);\n const filesChanged = filesOutput ? filesOutput.split('\\n').filter(Boolean) : [];\n\n // Check for tags\n const tagOutput = gitExec(harnessDir, `tag --points-at ${fullHash}`);\n const tag = tagOutput && tagOutput.length > 0 ? tagOutput.split('\\n')[0] : undefined;\n\n entries.push({\n hash,\n fullHash,\n message: parts[2],\n timestamp: parts[3],\n author: parts.slice(4).join('|'),\n filesChanged,\n tag,\n });\n }\n\n const currentHash = getHeadHash(harnessDir) ?? '';\n const currentTag = entries.length > 0 && entries[0].tag ? entries[0].tag : undefined;\n\n return { entries, currentHash, currentTag };\n}\n\n// ─── Diff ───────────────────────────────────────────────────────────────────\n\n/**\n * Get the diff between two versions (or between a version and HEAD).\n */\nexport function getVersionDiff(\n harnessDir: string,\n from: string,\n to?: string,\n): VersionDiff {\n if (!isGitRepo(harnessDir)) {\n return { from, to: to ?? 'HEAD', entries: [], summary: 'Not a git repository' };\n }\n\n const target = to ?? 'HEAD';\n const diffOutput = gitExec(harnessDir, `diff --numstat ${from} ${target}`);\n const nameOutput = gitExec(harnessDir, `diff --name-status ${from} ${target}`);\n\n const entries: DiffEntry[] = [];\n\n if (nameOutput) {\n const nameLines = nameOutput.split('\\n').filter(Boolean);\n const statLines = (diffOutput ?? '').split('\\n').filter(Boolean);\n\n for (let i = 0; i < nameLines.length; i++) {\n const nameParts = nameLines[i].split('\\t');\n const statusChar = nameParts[0];\n const file = nameParts[nameParts.length - 1];\n\n let status: DiffEntry['status'] = 'modified';\n if (statusChar === 'A') status = 'added';\n else if (statusChar === 'D') status = 'deleted';\n else if (statusChar.startsWith('R')) status = 'renamed';\n\n const entry: DiffEntry = { file, status };\n\n // Parse numstat for additions/deletions\n if (i < statLines.length) {\n const statParts = statLines[i].split('\\t');\n if (statParts.length >= 2) {\n const adds = parseInt(statParts[0], 10);\n const dels = parseInt(statParts[1], 10);\n if (!isNaN(adds)) entry.additions = adds;\n if (!isNaN(dels)) entry.deletions = dels;\n }\n }\n\n entries.push(entry);\n }\n }\n\n const added = entries.filter((e) => e.status === 'added').length;\n const modified = entries.filter((e) => e.status === 'modified').length;\n const deleted = entries.filter((e) => e.status === 'deleted').length;\n const summary = `${entries.length} file(s) changed: ${added} added, ${modified} modified, ${deleted} deleted`;\n\n return { from, to: target, entries, summary };\n}\n\n// ─── Rollback ───────────────────────────────────────────────────────────────\n\n/**\n * Roll back the harness to a previous version.\n *\n * Creates a new commit that restores files to the state at `targetHash`,\n * preserving full history (no destructive rewrite).\n *\n * @param harnessDir - Harness directory path\n * @param targetHash - Commit hash or tag to roll back to\n */\nexport function rollback(\n harnessDir: string,\n targetHash: string,\n): RollbackResult {\n if (!isGitRepo(harnessDir)) {\n return { success: false, targetHash, restoredFiles: [], error: 'Not a git repository' };\n }\n\n // Verify the target exists\n const resolvedHash = gitExec(harnessDir, `rev-parse --verify ${targetHash}`);\n if (!resolvedHash) {\n return { success: false, targetHash, restoredFiles: [], error: `Invalid version: ${targetHash}` };\n }\n\n // Get files that will change\n const diff = getVersionDiff(harnessDir, 'HEAD', resolvedHash);\n const restoredFiles = diff.entries.map((e) => e.file);\n\n // Restore all tracked files from the target commit\n const restoreResult = gitExec(harnessDir, `checkout ${resolvedHash} -- .`);\n if (restoreResult === null) {\n return { success: false, targetHash: resolvedHash, restoredFiles: [], error: 'Failed to restore files' };\n }\n\n // Stage and commit the rollback\n gitExec(harnessDir, 'add -A');\n const shortHash = resolvedHash.slice(0, 7);\n const commitResult = gitExec(harnessDir, `commit -m \"Rollback to ${shortHash}\" --allow-empty`);\n if (commitResult === null) {\n return { success: false, targetHash: resolvedHash, restoredFiles, error: 'Failed to commit rollback' };\n }\n\n return { success: true, targetHash: resolvedHash, restoredFiles };\n}\n\n// ─── Tag Management ─────────────────────────────────────────────────────────\n\n/**\n * List all version tags.\n */\nexport function listTags(harnessDir: string): Array<{ tag: string; hash: string; message: string }> {\n if (!isGitRepo(harnessDir)) return [];\n\n const output = gitExec(harnessDir, 'tag -l');\n if (!output) return [];\n\n const tags: Array<{ tag: string; hash: string; message: string }> = [];\n\n for (const tag of output.split('\\n').filter(Boolean)) {\n const hash = gitExec(harnessDir, `rev-parse ${tag}`);\n const message = gitExec(harnessDir, `log -1 --format=%s ${tag}`);\n tags.push({\n tag,\n hash: hash ? hash.slice(0, 7) : '',\n message: message ?? '',\n });\n }\n\n return tags;\n}\n\n/**\n * Tag the current version.\n */\nexport function tagVersion(harnessDir: string, tag: string, message?: string): boolean {\n if (!isGitRepo(harnessDir)) return false;\n\n if (message) {\n return gitExec(harnessDir, `tag -a \"${escapeMessage(tag)}\" -m \"${escapeMessage(message)}\"`) !== null;\n }\n return gitExec(harnessDir, `tag \"${escapeMessage(tag)}\"`) !== null;\n}\n\n// ─── Pending Changes ────────────────────────────────────────────────────────\n\n/**\n * Get uncommitted changes in the harness.\n */\nexport function getPendingChanges(harnessDir: string): DiffEntry[] {\n if (!isGitRepo(harnessDir)) return [];\n\n const output = gitExec(harnessDir, 'status --porcelain');\n if (!output) return [];\n\n const entries: DiffEntry[] = [];\n\n for (const line of output.split('\\n').filter(Boolean)) {\n const statusChar = line.substring(0, 2).trim();\n const file = line.substring(3);\n\n let status: DiffEntry['status'] = 'modified';\n if (statusChar === '??' || statusChar === 'A') status = 'added';\n else if (statusChar === 'D') status = 'deleted';\n else if (statusChar.startsWith('R')) status = 'renamed';\n\n entries.push({ file, status });\n }\n\n return entries;\n}\n\n// ─── File History ───────────────────────────────────────────────────────────\n\n/**\n * Get the version history for a specific file.\n */\nexport function getFileHistory(\n harnessDir: string,\n filePath: string,\n options?: { limit?: number },\n): VersionEntry[] {\n const relPath = relative(harnessDir, join(harnessDir, filePath));\n const log = getVersionLog(harnessDir, { limit: options?.limit ?? 20, file: relPath });\n return log.entries;\n}\n\n/**\n * Get the content of a file at a specific version.\n */\nexport function getFileAtVersion(\n harnessDir: string,\n filePath: string,\n hash: string,\n): string | null {\n if (!isGitRepo(harnessDir)) return null;\n\n const relPath = relative(harnessDir, join(harnessDir, filePath));\n return gitExec(harnessDir, `show ${hash}:\"${relPath}\"`);\n}\n\n// ─── Helpers ────────────────────────────────────────────────────────────────\n\nfunction getHeadHash(harnessDir: string): string | null {\n return gitExec(harnessDir, 'rev-parse HEAD');\n}\n\nfunction escapeMessage(msg: string): string {\n return msg.replace(/\"/g, '\\\\\"').replace(/\\n/g, ' ');\n}\n"],"mappings":"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","names":["log"]}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
writeIndexFile
|
|
5
|
+
} from "./chunk-4FDUOGSZ.js";
|
|
6
|
+
import {
|
|
7
|
+
autoProcessFile
|
|
8
|
+
} from "./chunk-M7NXUK55.js";
|
|
9
|
+
import "./chunk-UPLBF4RZ.js";
|
|
10
|
+
import {
|
|
11
|
+
log
|
|
12
|
+
} from "./chunk-BSKDOFRT.js";
|
|
13
|
+
import {
|
|
14
|
+
CORE_PRIMITIVE_DIRS
|
|
15
|
+
} from "./chunk-4CWAGBNS.js";
|
|
16
|
+
import "./chunk-ZZJOFKAT.js";
|
|
17
|
+
|
|
18
|
+
// src/runtime/watcher.ts
|
|
19
|
+
import { watch } from "chokidar";
|
|
20
|
+
import { relative } from "path";
|
|
21
|
+
function createWatcher(options) {
|
|
22
|
+
const { harnessDir, extraDirs, onChange, onIndexRebuild, onError, watchConfig, onConfigChange, autoProcess, onAutoProcess } = options;
|
|
23
|
+
const watchedDirs = [...CORE_PRIMITIVE_DIRS];
|
|
24
|
+
if (extraDirs) {
|
|
25
|
+
for (const dir of extraDirs) {
|
|
26
|
+
if (!watchedDirs.includes(dir)) watchedDirs.push(dir);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const patterns = watchedDirs.map((dir) => `${harnessDir}/${dir}/**/*.md`);
|
|
30
|
+
if (watchConfig) {
|
|
31
|
+
patterns.push(`${harnessDir}/config.yaml`);
|
|
32
|
+
}
|
|
33
|
+
const watcher = watch(patterns, {
|
|
34
|
+
ignoreInitial: true,
|
|
35
|
+
awaitWriteFinish: {
|
|
36
|
+
stabilityThreshold: 500,
|
|
37
|
+
pollInterval: 100
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
const handleChange = (filePath, event) => {
|
|
41
|
+
if (filePath.includes("_index.md")) return;
|
|
42
|
+
if (filePath.endsWith("config.yaml")) {
|
|
43
|
+
log.info("Config file changed");
|
|
44
|
+
try {
|
|
45
|
+
onConfigChange?.();
|
|
46
|
+
} catch (e) {
|
|
47
|
+
log.warn(`onConfigChange callback failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
48
|
+
}
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
const rel = relative(harnessDir, filePath);
|
|
52
|
+
const dir = rel.split("/")[0];
|
|
53
|
+
if (autoProcess && event !== "unlink" && filePath.endsWith(".md") && watchedDirs.includes(dir)) {
|
|
54
|
+
try {
|
|
55
|
+
const processResult = autoProcessFile(filePath, { harnessDir });
|
|
56
|
+
if (processResult.modified) {
|
|
57
|
+
log.info(`Auto-processed ${rel}: ${processResult.fixes.join(", ")}`);
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
onAutoProcess?.(processResult);
|
|
61
|
+
} catch (e) {
|
|
62
|
+
log.warn(`onAutoProcess callback failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
63
|
+
}
|
|
64
|
+
} catch (err) {
|
|
65
|
+
log.warn(`Auto-process failed for ${rel}: ${err instanceof Error ? err.message : String(err)}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (watchedDirs.includes(dir)) {
|
|
69
|
+
try {
|
|
70
|
+
writeIndexFile(harnessDir, dir);
|
|
71
|
+
try {
|
|
72
|
+
onIndexRebuild?.(dir);
|
|
73
|
+
} catch (e) {
|
|
74
|
+
log.warn(`onIndexRebuild callback failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
75
|
+
}
|
|
76
|
+
} catch (err) {
|
|
77
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
78
|
+
log.warn(`Failed to rebuild index for ${dir}: ${error.message}`);
|
|
79
|
+
try {
|
|
80
|
+
onError?.(error);
|
|
81
|
+
} catch (e) {
|
|
82
|
+
log.warn(`Watcher onError callback failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
try {
|
|
87
|
+
onChange?.(filePath, event);
|
|
88
|
+
} catch (e) {
|
|
89
|
+
log.warn(`onChange callback failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
watcher.on("add", (path) => handleChange(path, "add"));
|
|
93
|
+
watcher.on("change", (path) => handleChange(path, "change"));
|
|
94
|
+
watcher.on("unlink", (path) => handleChange(path, "unlink"));
|
|
95
|
+
watcher.on("error", (err) => {
|
|
96
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
97
|
+
log.warn(`File watcher error: ${error.message}`);
|
|
98
|
+
try {
|
|
99
|
+
onError?.(error);
|
|
100
|
+
} catch (e) {
|
|
101
|
+
log.warn(`Watcher onError callback failed: ${e instanceof Error ? e.message : String(e)}`);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
return watcher;
|
|
105
|
+
}
|
|
106
|
+
export {
|
|
107
|
+
createWatcher
|
|
108
|
+
};
|
|
109
|
+
//# sourceMappingURL=watcher-ISJC7YKL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/runtime/watcher.ts"],"sourcesContent":["import { watch, type FSWatcher } from 'chokidar';\nimport { relative } from 'path';\nimport { writeIndexFile } from './indexer.js';\nimport { log } from '../core/logger.js';\nimport { CORE_PRIMITIVE_DIRS } from '../core/types.js';\nimport { autoProcessFile, type AutoProcessResult } from './auto-processor.js';\n\nexport interface WatcherOptions {\n harnessDir: string;\n extraDirs?: string[];\n onChange?: (path: string, event: string) => void;\n onIndexRebuild?: (directory: string) => void;\n onError?: (error: Error) => void;\n /** Also watch config.yaml for changes */\n watchConfig?: boolean;\n onConfigChange?: () => void;\n /** Enable auto-processing of primitives on save (default: false) */\n autoProcess?: boolean;\n /** Called after auto-processing a file */\n onAutoProcess?: (result: AutoProcessResult) => void;\n}\n\nexport function createWatcher(options: WatcherOptions): FSWatcher {\n const { harnessDir, extraDirs, onChange, onIndexRebuild, onError, watchConfig, onConfigChange, autoProcess, onAutoProcess } = options;\n\n const watchedDirs: string[] = [...CORE_PRIMITIVE_DIRS];\n if (extraDirs) {\n for (const dir of extraDirs) {\n if (!watchedDirs.includes(dir)) watchedDirs.push(dir);\n }\n }\n\n const patterns: string[] = watchedDirs.map((dir) => `${harnessDir}/${dir}/**/*.md`);\n\n // Optionally watch config.yaml for live reload\n if (watchConfig) {\n patterns.push(`${harnessDir}/config.yaml`);\n }\n\n const watcher = watch(patterns, {\n ignoreInitial: true,\n awaitWriteFinish: {\n stabilityThreshold: 500,\n pollInterval: 100,\n },\n });\n\n const handleChange = (filePath: string, event: string) => {\n // Skip index files\n if (filePath.includes('_index.md')) return;\n\n // Config change handler\n if (filePath.endsWith('config.yaml')) {\n log.info('Config file changed');\n try { onConfigChange?.(); } catch (e) {\n log.warn(`onConfigChange callback failed: ${e instanceof Error ? e.message : String(e)}`);\n }\n return;\n }\n\n const rel = relative(harnessDir, filePath);\n const dir = rel.split('/')[0];\n\n // Auto-process primitives on add/change (before index rebuild so index sees fixes)\n if (autoProcess && event !== 'unlink' && filePath.endsWith('.md') && watchedDirs.includes(dir)) {\n try {\n const processResult = autoProcessFile(filePath, { harnessDir });\n if (processResult.modified) {\n log.info(`Auto-processed ${rel}: ${processResult.fixes.join(', ')}`);\n }\n try { onAutoProcess?.(processResult); } catch (e) {\n log.warn(`onAutoProcess callback failed: ${e instanceof Error ? e.message : String(e)}`);\n }\n } catch (err) {\n log.warn(`Auto-process failed for ${rel}: ${err instanceof Error ? err.message : String(err)}`);\n }\n }\n\n if (watchedDirs.includes(dir)) {\n // Rebuild index for this directory — wrapped for resilience\n try {\n writeIndexFile(harnessDir, dir);\n try { onIndexRebuild?.(dir); } catch (e) {\n log.warn(`onIndexRebuild callback failed: ${e instanceof Error ? e.message : String(e)}`);\n }\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n log.warn(`Failed to rebuild index for ${dir}: ${error.message}`);\n try { onError?.(error); } catch (e) {\n log.warn(`Watcher onError callback failed: ${e instanceof Error ? e.message : String(e)}`);\n }\n }\n }\n\n try { onChange?.(filePath, event); } catch (e) {\n log.warn(`onChange callback failed: ${e instanceof Error ? e.message : String(e)}`);\n }\n };\n\n watcher.on('add', (path) => handleChange(path, 'add'));\n watcher.on('change', (path) => handleChange(path, 'change'));\n watcher.on('unlink', (path) => handleChange(path, 'unlink'));\n\n // Handle file system errors gracefully\n watcher.on('error', (err) => {\n const error = err instanceof Error ? err : new Error(String(err));\n log.warn(`File watcher error: ${error.message}`);\n try { onError?.(error); } catch (e) {\n log.warn(`Watcher onError callback failed: ${e instanceof Error ? e.message : String(e)}`);\n }\n });\n\n return watcher;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
createWebApp,
|
|
5
|
+
startWebServer
|
|
6
|
+
} from "./chunk-RY3ZFII7.js";
|
|
7
|
+
import "./chunk-A7BJPQQ6.js";
|
|
8
|
+
import "./chunk-6EMOEYGU.js";
|
|
9
|
+
import "./chunk-GNUSHD2Y.js";
|
|
10
|
+
import "./chunk-5H34JPMB.js";
|
|
11
|
+
import "./chunk-MPZ3BPUI.js";
|
|
12
|
+
import "./chunk-UWQTZMNI.js";
|
|
13
|
+
import "./chunk-UDZIS2AQ.js";
|
|
14
|
+
import "./chunk-DTTXPHFW.js";
|
|
15
|
+
import "./chunk-Z2PUCXTZ.js";
|
|
16
|
+
import "./chunk-TAT6JU3X.js";
|
|
17
|
+
import "./chunk-JKMGYWXB.js";
|
|
18
|
+
import "./chunk-UPLBF4RZ.js";
|
|
19
|
+
import "./chunk-BSKDOFRT.js";
|
|
20
|
+
import "./chunk-IZ6UZ3ZL.js";
|
|
21
|
+
import "./chunk-CHJ5GNZC.js";
|
|
22
|
+
import "./chunk-4CWAGBNS.js";
|
|
23
|
+
import "./chunk-ZZJOFKAT.js";
|
|
24
|
+
export {
|
|
25
|
+
createWebApp,
|
|
26
|
+
startWebServer
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=web-server-DD7ZOP46.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@agntk/agent-harness",
|
|
3
|
+
"version": "0.1.1",
|
|
4
|
+
"description": "A file-first agent operating system. Build AI agents by editing markdown files, not writing code.",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "git+https://github.com/Phoenixrr2113/agent-harness.git"
|
|
8
|
+
},
|
|
9
|
+
"homepage": "https://github.com/Phoenixrr2113/agent-harness#readme",
|
|
10
|
+
"bugs": {
|
|
11
|
+
"url": "https://github.com/Phoenixrr2113/agent-harness/issues"
|
|
12
|
+
},
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "./dist/index.js",
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"bin": {
|
|
17
|
+
"harness": "./dist/cli/index.js"
|
|
18
|
+
},
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"import": "./dist/index.js",
|
|
22
|
+
"types": "./dist/index.d.ts"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsup",
|
|
27
|
+
"dev": "tsup --watch",
|
|
28
|
+
"test": "vitest run",
|
|
29
|
+
"test:watch": "vitest",
|
|
30
|
+
"lint": "tsc --noEmit",
|
|
31
|
+
"clean": "rm -rf dist"
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"dist",
|
|
35
|
+
"defaults",
|
|
36
|
+
"templates",
|
|
37
|
+
"sources.yaml",
|
|
38
|
+
"NOTICE"
|
|
39
|
+
],
|
|
40
|
+
"keywords": [
|
|
41
|
+
"ai",
|
|
42
|
+
"agent",
|
|
43
|
+
"harness",
|
|
44
|
+
"autonomous",
|
|
45
|
+
"llm",
|
|
46
|
+
"openrouter",
|
|
47
|
+
"framework"
|
|
48
|
+
],
|
|
49
|
+
"license": "MIT",
|
|
50
|
+
"engines": {
|
|
51
|
+
"node": ">=20"
|
|
52
|
+
},
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"@ai-sdk/anthropic": "^3.0.66",
|
|
55
|
+
"@ai-sdk/mcp": "^1.0.32",
|
|
56
|
+
"@ai-sdk/openai": "^3.0.50",
|
|
57
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
58
|
+
"@openrouter/ai-sdk-provider": "^2.3.3",
|
|
59
|
+
"ai": "^6.0.146",
|
|
60
|
+
"chalk": "^5.6.2",
|
|
61
|
+
"chokidar": "^5.0.0",
|
|
62
|
+
"commander": "^14.0.3",
|
|
63
|
+
"dotenv": "^17.4.1",
|
|
64
|
+
"gray-matter": "^4.0.3",
|
|
65
|
+
"node-cron": "^4.2.1",
|
|
66
|
+
"yaml": "^2.8.3",
|
|
67
|
+
"zod": "^4.3.6"
|
|
68
|
+
},
|
|
69
|
+
"devDependencies": {
|
|
70
|
+
"@types/node": "^25.5.2",
|
|
71
|
+
"@types/node-cron": "^3.0.11",
|
|
72
|
+
"tsup": "^8.5.1",
|
|
73
|
+
"typescript": "^6.0.2",
|
|
74
|
+
"vitest": "^4.1.2"
|
|
75
|
+
}
|
|
76
|
+
}
|