@agntk/agent-harness 0.1.4 → 0.1.6
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/README.md +104 -43
- package/dist/{analytics-RPT73WNM.js → analytics-L24W3B7U.js} +1 -2
- package/dist/auto-processor-QIRUOGEI.js +12 -0
- package/dist/{chunk-UPLBF4RZ.js → chunk-2UVWCTAY.js} +2 -2
- package/dist/{chunk-CSL3ERUI.js → chunk-4P6TRFPZ.js} +3 -3
- package/dist/chunk-4P6TRFPZ.js.map +1 -0
- package/dist/{chunk-4CWAGBNS.js → chunk-4TQQZILG.js} +73 -3
- package/dist/chunk-4TQQZILG.js.map +1 -0
- package/dist/{chunk-DA7IKHC4.js → chunk-5CO5JTYT.js} +2 -2
- package/dist/chunk-5CO5JTYT.js.map +1 -0
- package/dist/{chunk-A7BJPQQ6.js → chunk-5O5OGOOQ.js} +2 -2
- package/dist/{chunk-UWQTZMNI.js → chunk-7GZ4D6V6.js} +2 -2
- package/dist/{chunk-FLZU44SV.js → chunk-AN6Y4MDD.js} +6 -6
- package/dist/{chunk-4FDUOGSZ.js → chunk-D7AWV24Z.js} +3 -3
- package/dist/{chunk-CHJ5GNZC.js → chunk-EC42HQQH.js} +2 -2
- package/dist/{chunk-YIJY5DBV.js → chunk-KLYMGWQJ.js} +4 -4
- package/dist/chunk-KLYMGWQJ.js.map +1 -0
- package/dist/{chunk-YUFNYN2H.js → chunk-M62KLIEK.js} +4 -4
- package/dist/chunk-M62KLIEK.js.map +1 -0
- package/dist/{chunk-GJNNR2RA.js → chunk-M6PDMK2O.js} +3 -3
- package/dist/{chunk-M7NXUK55.js → chunk-NVC2WY4K.js} +2 -2
- package/dist/{chunk-XTBKL5BI.js → chunk-PMFAYKBD.js} +2 -2
- package/dist/chunk-PMFAYKBD.js.map +1 -0
- package/dist/{chunk-274RV3YO.js → chunk-QMOIVORH.js} +3 -3
- package/dist/chunk-QMOIVORH.js.map +1 -0
- package/dist/{chunk-RY3ZFII7.js → chunk-SEHAQTBO.js} +6 -6
- package/dist/{chunk-MPZ3BPUI.js → chunk-UMXPOYZR.js} +4 -4
- package/dist/{chunk-W4T7PGI2.js → chunk-UXCHAS3Z.js} +4 -4
- package/dist/cli/index.js +153 -167
- package/dist/cli/index.js.map +1 -1
- package/dist/config-PYSS3QY6.js +12 -0
- package/dist/context-loader-RSXXFW5R.js +12 -0
- package/dist/{conversation-QDEIDQPH.js → conversation-TBTFIJVU.js} +6 -7
- package/dist/{cost-tracker-RS3W7SVY.js → cost-tracker-NZRZEHVA.js} +1 -2
- package/dist/{delegate-VJCJLYEK.js → delegate-3KJAL4NZ.js} +7 -8
- package/dist/{emotional-state-VQVRA6ED.js → emotional-state-IN4ZUL2Q.js} +1 -2
- package/dist/{emotional-state-VQVRA6ED.js.map → emotional-state-IN4ZUL2Q.js.map} +1 -1
- package/dist/{env-discovery-2BLVMAIM.js → env-discovery-PXBRE5FX.js} +1 -2
- package/dist/{env-discovery-2BLVMAIM.js.map → env-discovery-PXBRE5FX.js.map} +1 -1
- package/dist/{export-6GCYHEHQ.js → export-GYLWROMB.js} +3 -4
- package/dist/{export-6GCYHEHQ.js.map → export-GYLWROMB.js.map} +1 -1
- package/dist/graph-LEEO37L3.js +13 -0
- package/dist/{harness-WE4SLCML.js → harness-R5FKRICG.js} +8 -9
- package/dist/{health-NZ6WNIMV.js → health-HL2JYHIY.js} +1 -2
- package/dist/indexer-L5UC6J2V.js +15 -0
- package/dist/{instinct-learner-SRM72DHF.js → instinct-learner-QGAMIS3X.js} +5 -6
- package/dist/{intake-4M3HNU43.js → intake-SVJKFHTL.js} +5 -6
- package/dist/{intelligence-HJOCA4SJ.js → intelligence-XPV3MC5U.js} +10 -13
- package/dist/intelligence-XPV3MC5U.js.map +1 -0
- package/dist/{journal-WANJL3MI.js → journal-ITUMKT6U.js} +5 -6
- package/dist/{loader-C3TKIKZR.js → loader-27PLDCOJ.js} +3 -4
- package/dist/{mcp-WTQJJZAO.js → mcp-JSIUJJZV.js} +1 -2
- package/dist/{mcp-discovery-WPAQFL6S.js → mcp-discovery-DG3RQYLM.js} +1 -2
- package/dist/{mcp-discovery-WPAQFL6S.js.map → mcp-discovery-DG3RQYLM.js.map} +1 -1
- package/dist/{mcp-installer-6O2XXD3V.js → mcp-installer-X2TJ2S2G.js} +3 -4
- package/dist/{mcp-installer-6O2XXD3V.js.map → mcp-installer-X2TJ2S2G.js.map} +1 -1
- package/dist/{metrics-KXGNFAAB.js → metrics-2MNINXNQ.js} +1 -2
- package/dist/{primitive-registry-I6VTIR4W.js → primitive-registry-ZMGGXSO5.js} +3 -4
- package/dist/{primitive-registry-I6VTIR4W.js.map → primitive-registry-ZMGGXSO5.js.map} +1 -1
- package/dist/{project-discovery-C4UMD7JI.js → project-discovery-FQLAZKEM.js} +1 -2
- package/dist/project-discovery-FQLAZKEM.js.map +1 -0
- package/dist/{provider-SXPQZ74H.js → provider-HQY6SPZI.js} +1 -2
- package/dist/{rate-limiter-RLRVM325.js → rate-limiter-PH5DCVU4.js} +1 -2
- package/dist/{rule-engine-YGQ3RYZM.js → rule-engine-DM26S77N.js} +3 -4
- package/dist/{rule-engine-YGQ3RYZM.js.map → rule-engine-DM26S77N.js.map} +1 -1
- package/dist/{scaffold-A3VRRCBV.js → scaffold-2F36YVW6.js} +5 -6
- package/dist/{scaffold-A3VRRCBV.js.map → scaffold-2F36YVW6.js.map} +1 -1
- package/dist/{scheduler-XHHIVHRI.js → scheduler-Q7GB2KCW.js} +11 -12
- package/dist/{scheduler-XHHIVHRI.js.map → scheduler-Q7GB2KCW.js.map} +1 -1
- package/dist/{search-V3W5JMJG.js → search-6Y6NCOLQ.js} +3 -4
- package/dist/search-6Y6NCOLQ.js.map +1 -0
- package/dist/{semantic-search-2DTOO5UX.js → semantic-search-FN6FZIXI.js} +3 -4
- package/dist/semantic-search-FN6FZIXI.js.map +1 -0
- package/dist/{serve-DTQ3HENY.js → serve-MXRTP2HE.js} +10 -11
- package/dist/serve-MXRTP2HE.js.map +1 -0
- package/dist/{sessions-CZGVXKQE.js → sessions-G6SZZXWS.js} +1 -2
- package/dist/{sources-RW5DT56F.js → sources-7LDYO5GK.js} +1 -2
- package/dist/{starter-packs-76YUVHEU.js → starter-packs-OR7NI5NA.js} +1 -2
- package/dist/{starter-packs-76YUVHEU.js.map → starter-packs-OR7NI5NA.js.map} +1 -1
- package/dist/{state-GMXILIHW.js → state-25IQEC5C.js} +1 -2
- package/dist/{state-merge-NKO5FRBA.js → state-merge-E333OEIQ.js} +1 -2
- package/dist/{state-merge-NKO5FRBA.js.map → state-merge-E333OEIQ.js.map} +1 -1
- package/dist/{telemetry-UC6PBXC7.js → telemetry-RS2JZUZP.js} +4 -5
- package/dist/{tool-executor-MJ7IG7PQ.js → tool-executor-6I5PHQDY.js} +5 -6
- package/dist/{tools-DZ4KETET.js → tools-NDFJNVHK.js} +4 -5
- package/dist/{types-EW7AIB3R.js → types-NPJZAI72.js} +2 -3
- package/dist/{universal-installer-AAXXYM5A.js → universal-installer-LCAZHFZR.js} +91 -7
- package/dist/universal-installer-LCAZHFZR.js.map +1 -0
- package/dist/validator-LM7RZWSH.js +21 -0
- package/dist/{verification-gate-FYXUX6LH.js → verification-gate-2O6DF2B7.js} +3 -4
- package/dist/verification-gate-2O6DF2B7.js.map +1 -0
- package/dist/{versioning-Z3XNE2Q2.js → versioning-WEGF6KJG.js} +1 -2
- package/dist/versioning-WEGF6KJG.js.map +1 -0
- package/dist/{watcher-ISJC7YKL.js → watcher-GZWQSWZ6.js} +5 -6
- package/dist/{watcher-ISJC7YKL.js.map → watcher-GZWQSWZ6.js.map} +1 -1
- package/dist/{web-server-DD7ZOP46.js → web-server-2Y4CHD2W.js} +8 -9
- package/package.json +1 -9
- package/dist/agent-framework-K4GUIICH.js +0 -344
- package/dist/agent-framework-K4GUIICH.js.map +0 -1
- package/dist/auto-processor-OLE45UI3.js +0 -13
- package/dist/chunk-274RV3YO.js.map +0 -1
- package/dist/chunk-4CWAGBNS.js.map +0 -1
- package/dist/chunk-CSL3ERUI.js.map +0 -1
- package/dist/chunk-DA7IKHC4.js.map +0 -1
- package/dist/chunk-DGUM43GV.js +0 -11
- package/dist/chunk-FD55B3IO.js +0 -204
- package/dist/chunk-FD55B3IO.js.map +0 -1
- package/dist/chunk-GUJTBGVS.js +0 -2212
- package/dist/chunk-GUJTBGVS.js.map +0 -1
- package/dist/chunk-KFX54TQM.js +0 -165
- package/dist/chunk-KFX54TQM.js.map +0 -1
- package/dist/chunk-XTBKL5BI.js.map +0 -1
- package/dist/chunk-YIJY5DBV.js.map +0 -1
- package/dist/chunk-YUFNYN2H.js.map +0 -1
- package/dist/chunk-ZZJOFKAT.js +0 -13
- package/dist/config-WVMRUOCA.js +0 -13
- package/dist/context-loader-3ORBPMHJ.js +0 -13
- package/dist/graph-YUIPOSOO.js +0 -14
- package/dist/harness-LCHA3DWP.js +0 -10
- package/dist/index.d.ts +0 -3612
- package/dist/index.js +0 -13713
- package/dist/index.js.map +0 -1
- package/dist/indexer-LONANRRM.js +0 -16
- package/dist/intelligence-HJOCA4SJ.js.map +0 -1
- package/dist/project-discovery-C4UMD7JI.js.map +0 -1
- package/dist/provider-LQHQX7Z7.js +0 -26
- package/dist/search-V3W5JMJG.js.map +0 -1
- package/dist/semantic-search-2DTOO5UX.js.map +0 -1
- package/dist/serve-DTQ3HENY.js.map +0 -1
- package/dist/tools-DZ4KETET.js.map +0 -1
- package/dist/types-EW7AIB3R.js.map +0 -1
- package/dist/types-WGDLSPO6.js +0 -16
- package/dist/types-WGDLSPO6.js.map +0 -1
- package/dist/universal-installer-AAXXYM5A.js.map +0 -1
- package/dist/validator-7WXMDIHH.js +0 -22
- package/dist/validator-7WXMDIHH.js.map +0 -1
- package/dist/verification-gate-FYXUX6LH.js.map +0 -1
- package/dist/versioning-Z3XNE2Q2.js.map +0 -1
- package/dist/web-server-DD7ZOP46.js.map +0 -1
- /package/dist/{analytics-RPT73WNM.js.map → analytics-L24W3B7U.js.map} +0 -0
- /package/dist/{auto-processor-OLE45UI3.js.map → auto-processor-QIRUOGEI.js.map} +0 -0
- /package/dist/{chunk-UPLBF4RZ.js.map → chunk-2UVWCTAY.js.map} +0 -0
- /package/dist/{chunk-A7BJPQQ6.js.map → chunk-5O5OGOOQ.js.map} +0 -0
- /package/dist/{chunk-UWQTZMNI.js.map → chunk-7GZ4D6V6.js.map} +0 -0
- /package/dist/{chunk-FLZU44SV.js.map → chunk-AN6Y4MDD.js.map} +0 -0
- /package/dist/{chunk-4FDUOGSZ.js.map → chunk-D7AWV24Z.js.map} +0 -0
- /package/dist/{chunk-CHJ5GNZC.js.map → chunk-EC42HQQH.js.map} +0 -0
- /package/dist/{chunk-GJNNR2RA.js.map → chunk-M6PDMK2O.js.map} +0 -0
- /package/dist/{chunk-M7NXUK55.js.map → chunk-NVC2WY4K.js.map} +0 -0
- /package/dist/{chunk-RY3ZFII7.js.map → chunk-SEHAQTBO.js.map} +0 -0
- /package/dist/{chunk-MPZ3BPUI.js.map → chunk-UMXPOYZR.js.map} +0 -0
- /package/dist/{chunk-W4T7PGI2.js.map → chunk-UXCHAS3Z.js.map} +0 -0
- /package/dist/{chunk-DGUM43GV.js.map → config-PYSS3QY6.js.map} +0 -0
- /package/dist/{chunk-ZZJOFKAT.js.map → context-loader-RSXXFW5R.js.map} +0 -0
- /package/dist/{config-WVMRUOCA.js.map → conversation-TBTFIJVU.js.map} +0 -0
- /package/dist/{context-loader-3ORBPMHJ.js.map → cost-tracker-NZRZEHVA.js.map} +0 -0
- /package/dist/{conversation-QDEIDQPH.js.map → delegate-3KJAL4NZ.js.map} +0 -0
- /package/dist/{cost-tracker-RS3W7SVY.js.map → graph-LEEO37L3.js.map} +0 -0
- /package/dist/{delegate-VJCJLYEK.js.map → harness-R5FKRICG.js.map} +0 -0
- /package/dist/{graph-YUIPOSOO.js.map → health-HL2JYHIY.js.map} +0 -0
- /package/dist/{harness-LCHA3DWP.js.map → indexer-L5UC6J2V.js.map} +0 -0
- /package/dist/{harness-WE4SLCML.js.map → instinct-learner-QGAMIS3X.js.map} +0 -0
- /package/dist/{health-NZ6WNIMV.js.map → intake-SVJKFHTL.js.map} +0 -0
- /package/dist/{indexer-LONANRRM.js.map → journal-ITUMKT6U.js.map} +0 -0
- /package/dist/{instinct-learner-SRM72DHF.js.map → loader-27PLDCOJ.js.map} +0 -0
- /package/dist/{intake-4M3HNU43.js.map → mcp-JSIUJJZV.js.map} +0 -0
- /package/dist/{journal-WANJL3MI.js.map → metrics-2MNINXNQ.js.map} +0 -0
- /package/dist/{loader-C3TKIKZR.js.map → provider-HQY6SPZI.js.map} +0 -0
- /package/dist/{mcp-WTQJJZAO.js.map → rate-limiter-PH5DCVU4.js.map} +0 -0
- /package/dist/{metrics-KXGNFAAB.js.map → sessions-G6SZZXWS.js.map} +0 -0
- /package/dist/{provider-LQHQX7Z7.js.map → sources-7LDYO5GK.js.map} +0 -0
- /package/dist/{provider-SXPQZ74H.js.map → state-25IQEC5C.js.map} +0 -0
- /package/dist/{rate-limiter-RLRVM325.js.map → telemetry-RS2JZUZP.js.map} +0 -0
- /package/dist/{sessions-CZGVXKQE.js.map → tool-executor-6I5PHQDY.js.map} +0 -0
- /package/dist/{sources-RW5DT56F.js.map → tools-NDFJNVHK.js.map} +0 -0
- /package/dist/{state-GMXILIHW.js.map → types-NPJZAI72.js.map} +0 -0
- /package/dist/{telemetry-UC6PBXC7.js.map → validator-LM7RZWSH.js.map} +0 -0
- /package/dist/{tool-executor-MJ7IG7PQ.js.map → web-server-2Y4CHD2W.js.map} +0 -0
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
doctorHarness,
|
|
5
|
-
validateHarness
|
|
6
|
-
} from "./chunk-FLZU44SV.js";
|
|
7
|
-
import "./chunk-W4T7PGI2.js";
|
|
8
|
-
import "./chunk-5H34JPMB.js";
|
|
9
|
-
import "./chunk-4FDUOGSZ.js";
|
|
10
|
-
import "./chunk-UWQTZMNI.js";
|
|
11
|
-
import "./chunk-UDZIS2AQ.js";
|
|
12
|
-
import "./chunk-Z2PUCXTZ.js";
|
|
13
|
-
import "./chunk-UPLBF4RZ.js";
|
|
14
|
-
import "./chunk-BSKDOFRT.js";
|
|
15
|
-
import "./chunk-CHJ5GNZC.js";
|
|
16
|
-
import "./chunk-4CWAGBNS.js";
|
|
17
|
-
import "./chunk-ZZJOFKAT.js";
|
|
18
|
-
export {
|
|
19
|
-
doctorHarness,
|
|
20
|
-
validateHarness
|
|
21
|
-
};
|
|
22
|
-
//# sourceMappingURL=validator-7WXMDIHH.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/runtime/verification-gate.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'fs';\nimport { join } from 'path';\nimport { loadDirectory } from '../primitives/loader.js';\nimport type { HarnessDocument, HarnessConfig } from '../core/types.js';\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\nexport interface VerificationCriterion {\n /** Human-readable criterion description */\n description: string;\n /** Whether this criterion must be manually checked (vs auto-checkable) */\n manual: boolean;\n /** Optional command to run for automated verification */\n command?: string;\n /** Optional expected output pattern (regex) for automated verification */\n expectedPattern?: string;\n}\n\nexport interface VerificationGate {\n /** Gate ID derived from playbook/workflow stage */\n id: string;\n /** Stage name this gate guards (e.g., \"Build\", \"Verify\") */\n stage: string;\n /** Source playbook/workflow ID */\n sourceId: string;\n /** Acceptance criteria that must pass before proceeding */\n criteria: VerificationCriterion[];\n}\n\nexport interface GateCheckResult {\n gateId: string;\n stage: string;\n passed: boolean;\n /** Individual criterion results */\n results: Array<{\n criterion: string;\n passed: boolean;\n detail?: string;\n }>;\n /** Criteria that need manual verification */\n pendingManual: string[];\n}\n\nexport interface GateExtractResult {\n gates: VerificationGate[];\n /** Source playbook/workflow IDs that had gates */\n sources: string[];\n}\n\n// ─── Gate Extraction ─────────────────────────────────────────────────────────\n\n/**\n * Extract verification gates from a playbook or workflow document.\n *\n * Gates are detected from:\n * 1. `## Gate:` or `## Verification:` sections in the document body\n * 2. Acceptance criteria blocks (`### Acceptance Criteria` or `### Gate`)\n * 3. Inline gate markers: `<!-- gate: description -->` in the markdown\n * 4. Numbered steps with `[x]` checkbox markers (treated as manual criteria)\n */\nexport function extractGates(doc: HarnessDocument): VerificationGate[] {\n const gates: VerificationGate[] = [];\n const body = doc.body;\n\n // Strategy 1: Named gate sections\n const gateSectionRegex = /##\\s+(?:Gate|Verification):\\s*(.+)\\n([\\s\\S]*?)(?=\\n##\\s|\\n*$)/gi;\n let match: RegExpExecArray | null;\n\n while ((match = gateSectionRegex.exec(body)) !== null) {\n const stageName = match[1].trim();\n const sectionBody = match[2];\n const criteria = extractCriteriaFromSection(sectionBody);\n\n if (criteria.length > 0) {\n gates.push({\n id: `${doc.frontmatter.id}:${slugify(stageName)}`,\n stage: stageName,\n sourceId: doc.frontmatter.id,\n criteria,\n });\n }\n }\n\n // Strategy 2: Acceptance criteria subsections\n const acRegex = /###\\s+(?:Acceptance Criteria|Gate)\\s*(?::\\s*(.+))?\\n([\\s\\S]*?)(?=\\n###?\\s|\\n*$)/gi;\n\n while ((match = acRegex.exec(body)) !== null) {\n const stageName = match[1]?.trim() ?? 'default';\n const sectionBody = match[2];\n const criteria = extractCriteriaFromSection(sectionBody);\n\n if (criteria.length > 0) {\n const gateId = `${doc.frontmatter.id}:ac-${slugify(stageName)}`;\n // Avoid duplicates from strategy 1\n if (!gates.some((g) => g.id === gateId)) {\n gates.push({\n id: gateId,\n stage: stageName,\n sourceId: doc.frontmatter.id,\n criteria,\n });\n }\n }\n }\n\n // Strategy 3: Inline gate markers\n const inlineRegex = /<!--\\s*gate:\\s*(.+?)\\s*-->/gi;\n\n while ((match = inlineRegex.exec(body)) !== null) {\n const desc = match[1].trim();\n const gateId = `${doc.frontmatter.id}:inline-${slugify(desc.slice(0, 40))}`;\n\n if (!gates.some((g) => g.id === gateId)) {\n gates.push({\n id: gateId,\n stage: 'inline',\n sourceId: doc.frontmatter.id,\n criteria: [{\n description: desc,\n manual: !desc.includes('`'),\n command: extractInlineCommand(desc),\n }],\n });\n }\n }\n\n // Strategy 4: Steps with checkboxes between stages\n const stepGates = extractStepGates(doc);\n for (const gate of stepGates) {\n if (!gates.some((g) => g.id === gate.id)) {\n gates.push(gate);\n }\n }\n\n return gates;\n}\n\n/**\n * Extract criteria from a section body (bullet list parsing).\n */\nfunction extractCriteriaFromSection(section: string): VerificationCriterion[] {\n const criteria: VerificationCriterion[] = [];\n\n for (const line of section.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n\n // Bullet or numbered list items\n const listMatch = trimmed.match(/^[-*]\\s+(?:\\[[ x]]\\s+)?(.+)/);\n if (!listMatch) continue;\n\n const desc = listMatch[1].trim();\n if (!desc) continue;\n\n // Check if it's an automated criterion (contains backtick command)\n const cmdMatch = desc.match(/`(.+?)`/);\n const isManual = !cmdMatch;\n\n // Check for expected pattern: \"should output X\" or \"expected: X\"\n const patternMatch = desc.match(/(?:should\\s+(?:output|return|show)|expected:\\s*)(.+?)(?:\\)|$)/i);\n\n criteria.push({\n description: desc,\n manual: isManual,\n command: cmdMatch ? cmdMatch[1] : undefined,\n expectedPattern: patternMatch ? patternMatch[1].trim() : undefined,\n });\n }\n\n return criteria;\n}\n\n/**\n * Extract verification gates from step transitions.\n * Looks for numbered steps where intermediate verification steps exist.\n */\nfunction extractStepGates(doc: HarnessDocument): VerificationGate[] {\n const gates: VerificationGate[] = [];\n const lines = doc.body.split('\\n');\n let currentStep = '';\n let criteriaBuffer: VerificationCriterion[] = [];\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n // Detect numbered step headers (e.g., \"1. **Understand**\" or \"## Step 1:\")\n const stepMatch = trimmed.match(/^(?:\\d+\\.\\s+\\*\\*(.+?)\\*\\*|##\\s+Step\\s+\\d+:\\s*(.+))/);\n if (stepMatch) {\n // Flush previous gate if criteria were collected\n if (currentStep && criteriaBuffer.length > 0) {\n gates.push({\n id: `${doc.frontmatter.id}:step-${slugify(currentStep)}`,\n stage: currentStep,\n sourceId: doc.frontmatter.id,\n criteria: [...criteriaBuffer],\n });\n criteriaBuffer = [];\n }\n currentStep = (stepMatch[1] ?? stepMatch[2]).trim();\n continue;\n }\n\n // Collect checkbox items within steps as criteria\n const checkboxMatch = trimmed.match(/^[-*]\\s+\\[[ x]]\\s+(.+)/);\n if (checkboxMatch && currentStep) {\n const desc = checkboxMatch[1].trim();\n const cmdMatch = desc.match(/`(.+?)`/);\n criteriaBuffer.push({\n description: desc,\n manual: !cmdMatch,\n command: cmdMatch ? cmdMatch[1] : undefined,\n });\n }\n }\n\n // Flush last step\n if (currentStep && criteriaBuffer.length > 0) {\n gates.push({\n id: `${doc.frontmatter.id}:step-${slugify(currentStep)}`,\n stage: currentStep,\n sourceId: doc.frontmatter.id,\n criteria: [...criteriaBuffer],\n });\n }\n\n return gates;\n}\n\n/**\n * Extract a command from an inline gate description (text between backticks).\n */\nfunction extractInlineCommand(desc: string): string | undefined {\n const match = desc.match(/`(.+?)`/);\n return match ? match[1] : undefined;\n}\n\n/**\n * Convert text to a URL-safe slug.\n */\nfunction slugify(text: string): string {\n return text\n .toLowerCase()\n .replace(/[^a-z0-9\\s-]/g, '')\n .replace(/\\s+/g, '-')\n .slice(0, 50)\n .replace(/-+$/, '');\n}\n\n// ─── Gate Loading ────────────────────────────────────────────────────────────\n\n/**\n * Load all verification gates from playbooks and workflows in the harness.\n */\nexport function loadGates(harnessDir: string): GateExtractResult {\n const gates: VerificationGate[] = [];\n const sources: string[] = [];\n\n for (const dir of ['playbooks', 'workflows']) {\n const fullPath = join(harnessDir, dir);\n if (!existsSync(fullPath)) continue;\n\n const docs = loadDirectory(fullPath);\n for (const doc of docs) {\n if (doc.frontmatter.status !== 'active') continue;\n const docGates = extractGates(doc);\n if (docGates.length > 0) {\n gates.push(...docGates);\n if (!sources.includes(doc.frontmatter.id)) {\n sources.push(doc.frontmatter.id);\n }\n }\n }\n }\n\n return { gates, sources };\n}\n\n/**\n * Find gates for a specific playbook/workflow by ID.\n */\nexport function getGatesForPlaybook(harnessDir: string, playbookId: string): VerificationGate[] {\n const { gates } = loadGates(harnessDir);\n return gates.filter((g) => g.sourceId === playbookId);\n}\n\n// ─── Gate Checking ───────────────────────────────────────────────────────────\n\n/**\n * Check a verification gate against provided results.\n * For manual criteria, checks against the `manualResults` map.\n * For automated criteria, checks if the command output matches the expected pattern.\n *\n * @param gate - The gate to check\n * @param manualResults - Map of criterion description → pass/fail\n * @param commandOutputs - Map of command → actual output (for automated checks)\n */\nexport function checkGate(\n gate: VerificationGate,\n manualResults?: Map<string, boolean>,\n commandOutputs?: Map<string, string>,\n): GateCheckResult {\n const results: Array<{ criterion: string; passed: boolean; detail?: string }> = [];\n const pendingManual: string[] = [];\n\n for (const criterion of gate.criteria) {\n if (criterion.manual) {\n // Manual criterion — check if result was provided\n if (manualResults && manualResults.has(criterion.description)) {\n const passed = manualResults.get(criterion.description)!;\n results.push({\n criterion: criterion.description,\n passed,\n detail: passed ? 'Manually verified' : 'Manual verification failed',\n });\n } else {\n pendingManual.push(criterion.description);\n results.push({\n criterion: criterion.description,\n passed: false,\n detail: 'Awaiting manual verification',\n });\n }\n } else if (criterion.command && commandOutputs) {\n // Automated criterion — check command output\n const output = commandOutputs.get(criterion.command);\n if (output === undefined) {\n results.push({\n criterion: criterion.description,\n passed: false,\n detail: `Command not executed: ${criterion.command}`,\n });\n } else if (criterion.expectedPattern) {\n try {\n const regex = new RegExp(criterion.expectedPattern, 'i');\n const passed = regex.test(output);\n results.push({\n criterion: criterion.description,\n passed,\n detail: passed\n ? `Output matches expected pattern`\n : `Output does not match expected pattern: ${criterion.expectedPattern}`,\n });\n } catch {\n // Invalid regex — treat as string match\n const passed = output.includes(criterion.expectedPattern);\n results.push({\n criterion: criterion.description,\n passed,\n detail: passed ? 'Output contains expected text' : 'Output missing expected text',\n });\n }\n } else {\n // No expected pattern — command succeeded if output exists\n results.push({\n criterion: criterion.description,\n passed: true,\n detail: 'Command produced output',\n });\n }\n } else {\n // Automated criterion but no output available\n results.push({\n criterion: criterion.description,\n passed: false,\n detail: criterion.command ? `Command not executed: ${criterion.command}` : 'No verification method',\n });\n }\n }\n\n const passed = results.every((r) => r.passed) && pendingManual.length === 0;\n\n return {\n gateId: gate.id,\n stage: gate.stage,\n passed,\n results,\n pendingManual,\n };\n}\n\n/**\n * Check all gates for a playbook/workflow. Returns individual gate results.\n */\nexport function checkAllGates(\n harnessDir: string,\n playbookId: string,\n manualResults?: Map<string, boolean>,\n commandOutputs?: Map<string, string>,\n): GateCheckResult[] {\n const gates = getGatesForPlaybook(harnessDir, playbookId);\n return gates.map((gate) => checkGate(gate, manualResults, commandOutputs));\n}\n"],"mappings":"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","names":["passed"]}
|
|
@@ -1 +0,0 @@
|
|
|
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"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|