@contextgraph/agent 0.4.16 → 0.4.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { Command } from "commander";
|
|
5
5
|
import { readFileSync as readFileSync2 } from "fs";
|
|
6
6
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
7
|
-
import { dirname as dirname2, join as
|
|
7
|
+
import { dirname as dirname2, join as join5 } from "path";
|
|
8
8
|
|
|
9
9
|
// src/callback-server.ts
|
|
10
10
|
import http from "http";
|
|
@@ -975,7 +975,7 @@ var LogTransportService = class {
|
|
|
975
975
|
/**
|
|
976
976
|
* Create a new run for an action
|
|
977
977
|
* @param actionId - The action ID this run is executing
|
|
978
|
-
* @param purpose - The purpose of this run: 'execute' | 'prepare' | '
|
|
978
|
+
* @param purpose - The purpose of this run: 'execute' | 'prepare' | 'review'
|
|
979
979
|
* @param metadata - Optional metadata for the run (e.g., startingCommit)
|
|
980
980
|
* @returns The created run ID
|
|
981
981
|
*/
|
|
@@ -1050,7 +1050,7 @@ var LogTransportService = class {
|
|
|
1050
1050
|
if (!this.runId) {
|
|
1051
1051
|
throw new Error("No run ID set. Call createRun() first.");
|
|
1052
1052
|
}
|
|
1053
|
-
if (state === "executing" || state === "preparing" || state === "running"
|
|
1053
|
+
if (state === "executing" || state === "preparing" || state === "running") {
|
|
1054
1054
|
await this.startRun();
|
|
1055
1055
|
} else if (state === "completed" || state === "failed") {
|
|
1056
1056
|
const outcome = state === "completed" ? "success" : "error";
|
|
@@ -1500,114 +1500,18 @@ ${errorText}`);
|
|
|
1500
1500
|
}
|
|
1501
1501
|
}
|
|
1502
1502
|
|
|
1503
|
-
// src/workflows/learn.ts
|
|
1504
|
-
var API_BASE_URL3 = "https://www.contextgraph.dev";
|
|
1505
|
-
async function runLearn(actionId, options) {
|
|
1506
|
-
const credentials = await loadCredentials();
|
|
1507
|
-
if (!credentials) {
|
|
1508
|
-
console.error("\u274C Not authenticated. Run authentication first.");
|
|
1509
|
-
process.exit(1);
|
|
1510
|
-
}
|
|
1511
|
-
if (isExpired(credentials) || isTokenExpired(credentials.clerkToken)) {
|
|
1512
|
-
console.error("\u274C Token expired. Re-authenticate to continue.");
|
|
1513
|
-
process.exit(1);
|
|
1514
|
-
}
|
|
1515
|
-
const logTransport = new LogTransportService(API_BASE_URL3, credentials.clerkToken);
|
|
1516
|
-
let runId;
|
|
1517
|
-
let heartbeatManager;
|
|
1518
|
-
let logBuffer;
|
|
1519
|
-
try {
|
|
1520
|
-
console.log("[Log Streaming] Creating run for learn phase...");
|
|
1521
|
-
runId = await logTransport.createRun(actionId, "learn", {
|
|
1522
|
-
startingCommit: options?.startingCommit
|
|
1523
|
-
});
|
|
1524
|
-
console.log(`[Log Streaming] Run created: ${runId}`);
|
|
1525
|
-
console.log(`Fetching learning instructions for action ${actionId}...
|
|
1526
|
-
`);
|
|
1527
|
-
const response = await fetchWithRetry(
|
|
1528
|
-
`${API_BASE_URL3}/api/prompts/learn`,
|
|
1529
|
-
{
|
|
1530
|
-
method: "POST",
|
|
1531
|
-
headers: {
|
|
1532
|
-
"Authorization": `Bearer ${credentials.clerkToken}`,
|
|
1533
|
-
"Content-Type": "application/json"
|
|
1534
|
-
},
|
|
1535
|
-
body: JSON.stringify({ actionId, runId })
|
|
1536
|
-
}
|
|
1537
|
-
);
|
|
1538
|
-
if (!response.ok) {
|
|
1539
|
-
const errorText = await response.text();
|
|
1540
|
-
throw new Error(`Failed to fetch learn prompt: ${response.statusText}
|
|
1541
|
-
${errorText}`);
|
|
1542
|
-
}
|
|
1543
|
-
const { prompt } = await response.json();
|
|
1544
|
-
await logTransport.updateRunState("learning");
|
|
1545
|
-
heartbeatManager = new HeartbeatManager(API_BASE_URL3, credentials.clerkToken, runId);
|
|
1546
|
-
heartbeatManager.start();
|
|
1547
|
-
console.log("[Log Streaming] Heartbeat started");
|
|
1548
|
-
logBuffer = new LogBuffer(logTransport);
|
|
1549
|
-
logBuffer.start();
|
|
1550
|
-
console.log("Spawning Claude for learning extraction...\n");
|
|
1551
|
-
const claudeResult = await executeClaude({
|
|
1552
|
-
prompt,
|
|
1553
|
-
cwd: options?.cwd || process.cwd(),
|
|
1554
|
-
authToken: credentials.clerkToken,
|
|
1555
|
-
...options?.model ? { model: options.model } : {},
|
|
1556
|
-
onLogEvent: (event) => {
|
|
1557
|
-
logBuffer.push(event);
|
|
1558
|
-
}
|
|
1559
|
-
});
|
|
1560
|
-
if (claudeResult.exitCode === 0) {
|
|
1561
|
-
await logTransport.finishRun("success", {
|
|
1562
|
-
exitCode: claudeResult.exitCode,
|
|
1563
|
-
cost: claudeResult.cost,
|
|
1564
|
-
usage: claudeResult.usage
|
|
1565
|
-
});
|
|
1566
|
-
console.log("\n\u2705 Learning extraction complete");
|
|
1567
|
-
} else {
|
|
1568
|
-
await logTransport.finishRun("error", {
|
|
1569
|
-
exitCode: claudeResult.exitCode,
|
|
1570
|
-
errorMessage: `Claude learning extraction failed with exit code ${claudeResult.exitCode}`
|
|
1571
|
-
});
|
|
1572
|
-
console.error(`
|
|
1573
|
-
\u274C Claude learning extraction failed with exit code ${claudeResult.exitCode}`);
|
|
1574
|
-
process.exit(1);
|
|
1575
|
-
}
|
|
1576
|
-
} catch (error) {
|
|
1577
|
-
if (runId) {
|
|
1578
|
-
try {
|
|
1579
|
-
await logTransport.finishRun("error", {
|
|
1580
|
-
errorMessage: error instanceof Error ? error.message : String(error)
|
|
1581
|
-
});
|
|
1582
|
-
} catch (stateError) {
|
|
1583
|
-
console.error("[Log Streaming] Failed to update run state:", stateError);
|
|
1584
|
-
}
|
|
1585
|
-
}
|
|
1586
|
-
throw error;
|
|
1587
|
-
} finally {
|
|
1588
|
-
if (heartbeatManager) {
|
|
1589
|
-
heartbeatManager.stop();
|
|
1590
|
-
console.log("[Log Streaming] Heartbeat stopped");
|
|
1591
|
-
}
|
|
1592
|
-
if (logBuffer) {
|
|
1593
|
-
await logBuffer.stop();
|
|
1594
|
-
console.log("[Log Streaming] Logs flushed");
|
|
1595
|
-
}
|
|
1596
|
-
}
|
|
1597
|
-
}
|
|
1598
|
-
|
|
1599
1503
|
// src/workflows/agent.ts
|
|
1600
1504
|
import { randomUUID } from "crypto";
|
|
1601
1505
|
import { readFileSync } from "fs";
|
|
1602
1506
|
import { mkdtemp as mkdtemp2, rm as rm2 } from "fs/promises";
|
|
1603
1507
|
import { tmpdir as tmpdir2 } from "os";
|
|
1604
1508
|
import { fileURLToPath } from "url";
|
|
1605
|
-
import { dirname, join as
|
|
1509
|
+
import { dirname, join as join4 } from "path";
|
|
1606
1510
|
|
|
1607
1511
|
// package.json
|
|
1608
1512
|
var package_default = {
|
|
1609
1513
|
name: "@contextgraph/agent",
|
|
1610
|
-
version: "0.4.
|
|
1514
|
+
version: "0.4.18",
|
|
1611
1515
|
description: "Autonomous agent for contextgraph action execution",
|
|
1612
1516
|
type: "module",
|
|
1613
1517
|
bin: {
|
|
@@ -1766,7 +1670,125 @@ var ApiClient = class {
|
|
|
1766
1670
|
import { spawn as spawn2 } from "child_process";
|
|
1767
1671
|
import { mkdtemp, rm } from "fs/promises";
|
|
1768
1672
|
import { tmpdir } from "os";
|
|
1673
|
+
import { join as join3 } from "path";
|
|
1674
|
+
|
|
1675
|
+
// src/skill-injection.ts
|
|
1676
|
+
import { mkdir as mkdir2, writeFile } from "fs/promises";
|
|
1769
1677
|
import { join as join2 } from "path";
|
|
1678
|
+
async function injectSkills(workspacePath, skills) {
|
|
1679
|
+
if (skills.length === 0) {
|
|
1680
|
+
console.log("\u{1F4DA} No skills to inject");
|
|
1681
|
+
return;
|
|
1682
|
+
}
|
|
1683
|
+
console.log(`\u{1F4DA} Injecting ${skills.length} skill(s) into workspace...`);
|
|
1684
|
+
for (const skill of skills) {
|
|
1685
|
+
try {
|
|
1686
|
+
const skillDir = join2(workspacePath, ".claude", "skills", skill.name);
|
|
1687
|
+
await mkdir2(skillDir, { recursive: true });
|
|
1688
|
+
const skillContent = `---
|
|
1689
|
+
name: ${skill.name}
|
|
1690
|
+
description: ${skill.description}
|
|
1691
|
+
---
|
|
1692
|
+
|
|
1693
|
+
${skill.content}
|
|
1694
|
+
`;
|
|
1695
|
+
const skillFilePath = join2(skillDir, "SKILL.md");
|
|
1696
|
+
await writeFile(skillFilePath, skillContent, "utf-8");
|
|
1697
|
+
console.log(` \u2705 Injected skill: ${skill.name}`);
|
|
1698
|
+
} catch (error) {
|
|
1699
|
+
console.error(` \u274C Failed to inject skill "${skill.name}":`, error);
|
|
1700
|
+
throw error;
|
|
1701
|
+
}
|
|
1702
|
+
}
|
|
1703
|
+
console.log(`\u2705 Skills injected successfully`);
|
|
1704
|
+
}
|
|
1705
|
+
|
|
1706
|
+
// src/test-skills.ts
|
|
1707
|
+
var VALIDATION_SKILL = {
|
|
1708
|
+
name: "contextgraph-validation-marker",
|
|
1709
|
+
description: "Marks agent runs to validate skill injection is working",
|
|
1710
|
+
content: `# ContextGraph Skill Validation Marker
|
|
1711
|
+
|
|
1712
|
+
## Purpose
|
|
1713
|
+
This skill validates that the ContextGraph skill injection mechanism is working correctly.
|
|
1714
|
+
|
|
1715
|
+
## Instructions
|
|
1716
|
+
|
|
1717
|
+
**CRITICAL**: When you start execution, IMMEDIATELY include this exact marker in your first response:
|
|
1718
|
+
|
|
1719
|
+
\`\`\`
|
|
1720
|
+
\u{1F52C} SKILL_INJECTION_VALIDATED: contextgraph-validation-marker loaded
|
|
1721
|
+
\`\`\`
|
|
1722
|
+
|
|
1723
|
+
This marker proves that:
|
|
1724
|
+
1. The skill file was successfully written to the workspace
|
|
1725
|
+
2. Claude Code loaded the skill at startup
|
|
1726
|
+
3. The skill content is available during agent execution
|
|
1727
|
+
|
|
1728
|
+
## Usage
|
|
1729
|
+
|
|
1730
|
+
This skill should be invoked automatically at the start of EVERY agent run to validate the injection mechanism. The marker should appear in the agent's output logs.
|
|
1731
|
+
|
|
1732
|
+
## Context
|
|
1733
|
+
|
|
1734
|
+
This is a prototype validation skill for the ContextGraph learning and skills system. It's designed to have a high trigger frequency to reliably demonstrate skill loading mechanics.
|
|
1735
|
+
`
|
|
1736
|
+
};
|
|
1737
|
+
function getValidationSkills() {
|
|
1738
|
+
return [VALIDATION_SKILL];
|
|
1739
|
+
}
|
|
1740
|
+
|
|
1741
|
+
// src/skills-library-fetch.ts
|
|
1742
|
+
var API_BASE_URL3 = "https://www.contextgraph.dev";
|
|
1743
|
+
async function fetchSkillsLibrary(authToken) {
|
|
1744
|
+
try {
|
|
1745
|
+
const response = await fetchWithRetry(
|
|
1746
|
+
`${API_BASE_URL3}/api/skills/library`,
|
|
1747
|
+
{
|
|
1748
|
+
headers: {
|
|
1749
|
+
"x-authorization": `Bearer ${authToken}`,
|
|
1750
|
+
"Content-Type": "application/json"
|
|
1751
|
+
}
|
|
1752
|
+
},
|
|
1753
|
+
{
|
|
1754
|
+
maxRetries: 2,
|
|
1755
|
+
baseDelayMs: 500
|
|
1756
|
+
}
|
|
1757
|
+
);
|
|
1758
|
+
if (!response.ok) {
|
|
1759
|
+
console.warn(`\u26A0\uFE0F Skills library API returned ${response.status}: ${response.statusText}`);
|
|
1760
|
+
return [];
|
|
1761
|
+
}
|
|
1762
|
+
const data = await response.json();
|
|
1763
|
+
if (!data.success || !data.data?.skills) {
|
|
1764
|
+
console.warn("\u26A0\uFE0F Skills library API returned unexpected format");
|
|
1765
|
+
return [];
|
|
1766
|
+
}
|
|
1767
|
+
const skills = data.data.skills.map((skill) => {
|
|
1768
|
+
const name = skill.filename.replace(/\.md$/, "");
|
|
1769
|
+
let description = "Skill from ContextGraph library";
|
|
1770
|
+
const frontmatterMatch = skill.content.match(/^---\n([\s\S]*?)\n---/);
|
|
1771
|
+
if (frontmatterMatch) {
|
|
1772
|
+
const descMatch = frontmatterMatch[1].match(/description:\s*(.+)/);
|
|
1773
|
+
if (descMatch) {
|
|
1774
|
+
description = descMatch[1].trim();
|
|
1775
|
+
}
|
|
1776
|
+
}
|
|
1777
|
+
const contentWithoutFrontmatter = skill.content.replace(/^---\n[\s\S]*?\n---\n/, "");
|
|
1778
|
+
return {
|
|
1779
|
+
name,
|
|
1780
|
+
description,
|
|
1781
|
+
content: contentWithoutFrontmatter
|
|
1782
|
+
};
|
|
1783
|
+
});
|
|
1784
|
+
return skills;
|
|
1785
|
+
} catch (error) {
|
|
1786
|
+
console.warn("\u26A0\uFE0F Failed to fetch skills library:", error instanceof Error ? error.message : error);
|
|
1787
|
+
return [];
|
|
1788
|
+
}
|
|
1789
|
+
}
|
|
1790
|
+
|
|
1791
|
+
// src/workspace-prep.ts
|
|
1770
1792
|
var API_BASE_URL4 = "https://www.contextgraph.dev";
|
|
1771
1793
|
async function fetchGitHubCredentials(authToken) {
|
|
1772
1794
|
const response = await fetchWithRetry(`${API_BASE_URL4}/api/cli/credentials`, {
|
|
@@ -1825,7 +1847,7 @@ function buildAuthenticatedUrl(repoUrl, token) {
|
|
|
1825
1847
|
async function prepareWorkspace(repoUrl, options) {
|
|
1826
1848
|
const { branch, authToken } = options;
|
|
1827
1849
|
const credentials = await fetchGitHubCredentials(authToken);
|
|
1828
|
-
const workspacePath = await mkdtemp(
|
|
1850
|
+
const workspacePath = await mkdtemp(join3(tmpdir(), "cg-workspace-"));
|
|
1829
1851
|
const cleanup = async () => {
|
|
1830
1852
|
try {
|
|
1831
1853
|
await rm(workspacePath, { recursive: true, force: true });
|
|
@@ -1861,6 +1883,19 @@ async function prepareWorkspace(repoUrl, options) {
|
|
|
1861
1883
|
}
|
|
1862
1884
|
const { stdout: commitHash } = await runGitCommand(["rev-parse", "HEAD"], workspacePath);
|
|
1863
1885
|
const startingCommit = commitHash.trim();
|
|
1886
|
+
console.log("");
|
|
1887
|
+
try {
|
|
1888
|
+
const librarySkills = await fetchSkillsLibrary(authToken);
|
|
1889
|
+
const validationSkills = getValidationSkills();
|
|
1890
|
+
const allSkills = [...librarySkills, ...validationSkills];
|
|
1891
|
+
if (allSkills.length > 0) {
|
|
1892
|
+
await injectSkills(workspacePath, allSkills);
|
|
1893
|
+
} else {
|
|
1894
|
+
console.log("\u{1F4DA} No skills to inject (empty library)");
|
|
1895
|
+
}
|
|
1896
|
+
} catch (skillError) {
|
|
1897
|
+
console.warn("\u26A0\uFE0F Skill injection failed (agent will continue):", skillError);
|
|
1898
|
+
}
|
|
1864
1899
|
return { path: workspacePath, startingCommit, cleanup };
|
|
1865
1900
|
} catch (error) {
|
|
1866
1901
|
await cleanup();
|
|
@@ -1872,7 +1907,7 @@ async function prepareWorkspace(repoUrl, options) {
|
|
|
1872
1907
|
var __filename2 = fileURLToPath(import.meta.url);
|
|
1873
1908
|
var __dirname2 = dirname(__filename2);
|
|
1874
1909
|
var packageJson = JSON.parse(
|
|
1875
|
-
readFileSync(
|
|
1910
|
+
readFileSync(join4(__dirname2, "../package.json"), "utf-8")
|
|
1876
1911
|
);
|
|
1877
1912
|
var INITIAL_POLL_INTERVAL = parseInt(process.env.WORKER_INITIAL_POLL_INTERVAL || "2000", 10);
|
|
1878
1913
|
var MAX_POLL_INTERVAL = parseInt(process.env.WORKER_MAX_POLL_INTERVAL || "5000", 10);
|
|
@@ -1887,7 +1922,6 @@ var apiClient = null;
|
|
|
1887
1922
|
var stats = {
|
|
1888
1923
|
startTime: Date.now(),
|
|
1889
1924
|
prepared: 0,
|
|
1890
|
-
learned: 0,
|
|
1891
1925
|
executed: 0,
|
|
1892
1926
|
errors: 0
|
|
1893
1927
|
};
|
|
@@ -1904,8 +1938,8 @@ function formatDuration(ms) {
|
|
|
1904
1938
|
}
|
|
1905
1939
|
function printStatus() {
|
|
1906
1940
|
const uptime = formatDuration(Date.now() - stats.startTime);
|
|
1907
|
-
const total = stats.prepared + stats.
|
|
1908
|
-
console.log(`Status: ${total} actions (${stats.prepared} prepared, ${stats.
|
|
1941
|
+
const total = stats.prepared + stats.executed;
|
|
1942
|
+
console.log(`Status: ${total} actions (${stats.prepared} prepared, ${stats.executed} executed, ${stats.errors} errors) | Uptime: ${uptime}`);
|
|
1909
1943
|
}
|
|
1910
1944
|
async function cleanupAndExit() {
|
|
1911
1945
|
if (currentClaim && apiClient) {
|
|
@@ -1966,10 +2000,6 @@ async function runLocalAgent(options) {
|
|
|
1966
2000
|
console.log(`\u{1F477} Worker ID: ${workerId}`);
|
|
1967
2001
|
console.log(`\u{1F504} Starting continuous worker loop...
|
|
1968
2002
|
`);
|
|
1969
|
-
if (options?.skipLearning) {
|
|
1970
|
-
console.log(`\u23ED\uFE0F Skipping learning runs (--skip-learning)
|
|
1971
|
-
`);
|
|
1972
|
-
}
|
|
1973
2003
|
console.log(`\u{1F4A1} Press Ctrl+C to gracefully shutdown and release any claimed work
|
|
1974
2004
|
`);
|
|
1975
2005
|
let currentPollInterval = INITIAL_POLL_INTERVAL;
|
|
@@ -2026,17 +2056,12 @@ async function runLocalAgent(options) {
|
|
|
2026
2056
|
};
|
|
2027
2057
|
}
|
|
2028
2058
|
let phase;
|
|
2029
|
-
if (
|
|
2030
|
-
phase = "learn";
|
|
2031
|
-
} else if (!actionDetail.prepared) {
|
|
2059
|
+
if (!actionDetail.prepared) {
|
|
2032
2060
|
phase = "prepare";
|
|
2033
2061
|
} else if (!actionDetail.done) {
|
|
2034
2062
|
phase = "execute";
|
|
2035
2063
|
} else {
|
|
2036
|
-
|
|
2037
|
-
if (!isLearningOnlyAndSkipped) {
|
|
2038
|
-
console.log(`\u23ED\uFE0F Skipping action "${actionDetail.title}" - done but not yet reviewed`);
|
|
2039
|
-
}
|
|
2064
|
+
console.log(`\u23ED\uFE0F Skipping action "${actionDetail.title}" - already completed`);
|
|
2040
2065
|
if (currentClaim && apiClient) {
|
|
2041
2066
|
try {
|
|
2042
2067
|
await apiClient.releaseClaim({
|
|
@@ -2057,7 +2082,7 @@ async function runLocalAgent(options) {
|
|
|
2057
2082
|
let workspacePath;
|
|
2058
2083
|
let cleanup;
|
|
2059
2084
|
let startingCommit;
|
|
2060
|
-
const needsRepo =
|
|
2085
|
+
const needsRepo = repoUrl;
|
|
2061
2086
|
try {
|
|
2062
2087
|
if (needsRepo) {
|
|
2063
2088
|
const workspace = await prepareWorkspace(repoUrl, {
|
|
@@ -2068,12 +2093,8 @@ async function runLocalAgent(options) {
|
|
|
2068
2093
|
cleanup = workspace.cleanup;
|
|
2069
2094
|
startingCommit = workspace.startingCommit;
|
|
2070
2095
|
} else {
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
} else {
|
|
2074
|
-
console.log(`\u{1F4C2} No repository configured - creating blank workspace`);
|
|
2075
|
-
}
|
|
2076
|
-
workspacePath = await mkdtemp2(join3(tmpdir2(), "cg-workspace-"));
|
|
2096
|
+
console.log(`\u{1F4C2} No repository configured - creating blank workspace`);
|
|
2097
|
+
workspacePath = await mkdtemp2(join4(tmpdir2(), "cg-workspace-"));
|
|
2077
2098
|
console.log(` \u2192 ${workspacePath}`);
|
|
2078
2099
|
cleanup = async () => {
|
|
2079
2100
|
try {
|
|
@@ -2100,30 +2121,6 @@ async function runLocalAgent(options) {
|
|
|
2100
2121
|
currentClaim = null;
|
|
2101
2122
|
continue;
|
|
2102
2123
|
}
|
|
2103
|
-
if (phase === "learn") {
|
|
2104
|
-
try {
|
|
2105
|
-
await runLearn(actionDetail.id, { cwd: workspacePath, startingCommit, model: options?.forceModel });
|
|
2106
|
-
stats.learned++;
|
|
2107
|
-
console.log(`Learning extracted: ${actionDetail.title}`);
|
|
2108
|
-
} catch (learnError) {
|
|
2109
|
-
stats.errors++;
|
|
2110
|
-
console.error(`Error during learning: ${learnError.message}. Continuing...`);
|
|
2111
|
-
} finally {
|
|
2112
|
-
if (currentClaim && apiClient) {
|
|
2113
|
-
try {
|
|
2114
|
-
await apiClient.releaseClaim({
|
|
2115
|
-
action_id: currentClaim.actionId,
|
|
2116
|
-
worker_id: currentClaim.workerId,
|
|
2117
|
-
claim_id: currentClaim.claimId
|
|
2118
|
-
});
|
|
2119
|
-
} catch (releaseError) {
|
|
2120
|
-
console.error("\u26A0\uFE0F Failed to release claim:", releaseError.message);
|
|
2121
|
-
}
|
|
2122
|
-
}
|
|
2123
|
-
currentClaim = null;
|
|
2124
|
-
}
|
|
2125
|
-
continue;
|
|
2126
|
-
}
|
|
2127
2124
|
try {
|
|
2128
2125
|
await runExecute(actionDetail.id, { cwd: workspacePath, startingCommit, model: options?.forceModel });
|
|
2129
2126
|
stats.executed++;
|
|
@@ -2174,15 +2171,14 @@ async function runLocalAgent(options) {
|
|
|
2174
2171
|
var __filename3 = fileURLToPath2(import.meta.url);
|
|
2175
2172
|
var __dirname3 = dirname2(__filename3);
|
|
2176
2173
|
var packageJson2 = JSON.parse(
|
|
2177
|
-
readFileSync2(
|
|
2174
|
+
readFileSync2(join5(__dirname3, "../package.json"), "utf-8")
|
|
2178
2175
|
);
|
|
2179
2176
|
var program = new Command();
|
|
2180
2177
|
program.name("contextgraph-agent").description("Autonomous agent for contextgraph action execution").version(packageJson2.version);
|
|
2181
|
-
program.command("run").description("Run continuous worker loop (claims and executes actions until Ctrl+C)").option("--force-haiku", "Force all workflows to use claude-haiku-4-5 instead of default models").
|
|
2178
|
+
program.command("run").description("Run continuous worker loop (claims and executes actions until Ctrl+C)").option("--force-haiku", "Force all workflows to use claude-haiku-4-5 instead of default models").action(async (options) => {
|
|
2182
2179
|
try {
|
|
2183
2180
|
await runLocalAgent({
|
|
2184
|
-
forceModel: options.forceHaiku ? "claude-haiku-4-5-20251001" : void 0
|
|
2185
|
-
skipLearning: options.skipLearning || false
|
|
2181
|
+
forceModel: options.forceHaiku ? "claude-haiku-4-5-20251001" : void 0
|
|
2186
2182
|
});
|
|
2187
2183
|
} catch (error) {
|
|
2188
2184
|
if (error instanceof Error) {
|
|
@@ -2221,14 +2217,6 @@ program.command("execute").argument("<action-id>", "Action ID to execute").descr
|
|
|
2221
2217
|
process.exit(1);
|
|
2222
2218
|
}
|
|
2223
2219
|
});
|
|
2224
|
-
program.command("learn").argument("<action-id>", "Action ID to learn from").description("Extract learnings from a completed action").action(async (actionId) => {
|
|
2225
|
-
try {
|
|
2226
|
-
await runLearn(actionId);
|
|
2227
|
-
} catch (error) {
|
|
2228
|
-
console.error("Error learning from action:", error instanceof Error ? error.message : error);
|
|
2229
|
-
process.exit(1);
|
|
2230
|
-
}
|
|
2231
|
-
});
|
|
2232
2220
|
program.command("whoami").description("Show current authentication status").action(async () => {
|
|
2233
2221
|
try {
|
|
2234
2222
|
const credentials = await loadCredentials();
|