@praveencs/agent 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1007 -0
- package/bin/agent.ts +6 -0
- package/dist/bin/agent.d.ts +3 -0
- package/dist/bin/agent.d.ts.map +1 -0
- package/dist/bin/agent.js +5 -0
- package/dist/bin/agent.js.map +1 -0
- package/dist/src/cli/commands/config.d.ts +3 -0
- package/dist/src/cli/commands/config.d.ts.map +1 -0
- package/dist/src/cli/commands/config.js +54 -0
- package/dist/src/cli/commands/config.js.map +1 -0
- package/dist/src/cli/commands/daemon.d.ts +3 -0
- package/dist/src/cli/commands/daemon.d.ts.map +1 -0
- package/dist/src/cli/commands/daemon.js +43 -0
- package/dist/src/cli/commands/daemon.js.map +1 -0
- package/dist/src/cli/commands/doctor.d.ts +3 -0
- package/dist/src/cli/commands/doctor.d.ts.map +1 -0
- package/dist/src/cli/commands/doctor.js +84 -0
- package/dist/src/cli/commands/doctor.js.map +1 -0
- package/dist/src/cli/commands/init.d.ts +8 -0
- package/dist/src/cli/commands/init.d.ts.map +1 -0
- package/dist/src/cli/commands/init.js +112 -0
- package/dist/src/cli/commands/init.js.map +1 -0
- package/dist/src/cli/commands/mcp.d.ts +3 -0
- package/dist/src/cli/commands/mcp.d.ts.map +1 -0
- package/dist/src/cli/commands/mcp.js +26 -0
- package/dist/src/cli/commands/mcp.js.map +1 -0
- package/dist/src/cli/commands/plan.d.ts +3 -0
- package/dist/src/cli/commands/plan.d.ts.map +1 -0
- package/dist/src/cli/commands/plan.js +220 -0
- package/dist/src/cli/commands/plan.js.map +1 -0
- package/dist/src/cli/commands/run.d.ts +3 -0
- package/dist/src/cli/commands/run.d.ts.map +1 -0
- package/dist/src/cli/commands/run.js +192 -0
- package/dist/src/cli/commands/run.js.map +1 -0
- package/dist/src/cli/commands/skills.d.ts +3 -0
- package/dist/src/cli/commands/skills.d.ts.map +1 -0
- package/dist/src/cli/commands/skills.js +143 -0
- package/dist/src/cli/commands/skills.js.map +1 -0
- package/dist/src/cli/index.d.ts +6 -0
- package/dist/src/cli/index.d.ts.map +1 -0
- package/dist/src/cli/index.js +33 -0
- package/dist/src/cli/index.js.map +1 -0
- package/dist/src/cli/ui/progress.d.ts +17 -0
- package/dist/src/cli/ui/progress.d.ts.map +1 -0
- package/dist/src/cli/ui/progress.js +43 -0
- package/dist/src/cli/ui/progress.js.map +1 -0
- package/dist/src/cli/ui/prompt.d.ts +10 -0
- package/dist/src/cli/ui/prompt.d.ts.map +1 -0
- package/dist/src/cli/ui/prompt.js +53 -0
- package/dist/src/cli/ui/prompt.js.map +1 -0
- package/dist/src/cli/ui/report.d.ts +6 -0
- package/dist/src/cli/ui/report.d.ts.map +1 -0
- package/dist/src/cli/ui/report.js +81 -0
- package/dist/src/cli/ui/report.js.map +1 -0
- package/dist/src/config/defaults.d.ts +3 -0
- package/dist/src/config/defaults.d.ts.map +1 -0
- package/dist/src/config/defaults.js +82 -0
- package/dist/src/config/defaults.js.map +1 -0
- package/dist/src/config/loader.d.ts +33 -0
- package/dist/src/config/loader.d.ts.map +1 -0
- package/dist/src/config/loader.js +161 -0
- package/dist/src/config/loader.js.map +1 -0
- package/dist/src/config/schema.d.ts +530 -0
- package/dist/src/config/schema.d.ts.map +1 -0
- package/dist/src/config/schema.js +97 -0
- package/dist/src/config/schema.js.map +1 -0
- package/dist/src/config/secrets.d.ts +31 -0
- package/dist/src/config/secrets.d.ts.map +1 -0
- package/dist/src/config/secrets.js +98 -0
- package/dist/src/config/secrets.js.map +1 -0
- package/dist/src/daemon/manager.d.ts +28 -0
- package/dist/src/daemon/manager.d.ts.map +1 -0
- package/dist/src/daemon/manager.js +77 -0
- package/dist/src/daemon/manager.js.map +1 -0
- package/dist/src/daemon/scheduler.d.ts +6 -0
- package/dist/src/daemon/scheduler.d.ts.map +1 -0
- package/dist/src/daemon/scheduler.js +82 -0
- package/dist/src/daemon/scheduler.js.map +1 -0
- package/dist/src/daemon/watcher.d.ts +16 -0
- package/dist/src/daemon/watcher.d.ts.map +1 -0
- package/dist/src/daemon/watcher.js +59 -0
- package/dist/src/daemon/watcher.js.map +1 -0
- package/dist/src/engine/executor.d.ts +51 -0
- package/dist/src/engine/executor.d.ts.map +1 -0
- package/dist/src/engine/executor.js +189 -0
- package/dist/src/engine/executor.js.map +1 -0
- package/dist/src/engine/rollback.d.ts +37 -0
- package/dist/src/engine/rollback.d.ts.map +1 -0
- package/dist/src/engine/rollback.js +95 -0
- package/dist/src/engine/rollback.js.map +1 -0
- package/dist/src/engine/types.d.ts +31 -0
- package/dist/src/engine/types.d.ts.map +1 -0
- package/dist/src/engine/types.js +2 -0
- package/dist/src/engine/types.js.map +1 -0
- package/dist/src/engine/verification.d.ts +27 -0
- package/dist/src/engine/verification.d.ts.map +1 -0
- package/dist/src/engine/verification.js +75 -0
- package/dist/src/engine/verification.js.map +1 -0
- package/dist/src/index.d.ts +17 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +13 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/llm/cache.d.ts +20 -0
- package/dist/src/llm/cache.d.ts.map +1 -0
- package/dist/src/llm/cache.js +45 -0
- package/dist/src/llm/cache.js.map +1 -0
- package/dist/src/llm/providers/anthropic.d.ts +13 -0
- package/dist/src/llm/providers/anthropic.d.ts.map +1 -0
- package/dist/src/llm/providers/anthropic.js +69 -0
- package/dist/src/llm/providers/anthropic.js.map +1 -0
- package/dist/src/llm/providers/azure.d.ts +14 -0
- package/dist/src/llm/providers/azure.d.ts.map +1 -0
- package/dist/src/llm/providers/azure.js +98 -0
- package/dist/src/llm/providers/azure.js.map +1 -0
- package/dist/src/llm/providers/ollama.d.ts +13 -0
- package/dist/src/llm/providers/ollama.d.ts.map +1 -0
- package/dist/src/llm/providers/ollama.js +80 -0
- package/dist/src/llm/providers/ollama.js.map +1 -0
- package/dist/src/llm/providers/openai.d.ts +13 -0
- package/dist/src/llm/providers/openai.d.ts.map +1 -0
- package/dist/src/llm/providers/openai.js +74 -0
- package/dist/src/llm/providers/openai.js.map +1 -0
- package/dist/src/llm/router.d.ts +26 -0
- package/dist/src/llm/router.d.ts.map +1 -0
- package/dist/src/llm/router.js +104 -0
- package/dist/src/llm/router.js.map +1 -0
- package/dist/src/llm/types.d.ts +44 -0
- package/dist/src/llm/types.d.ts.map +1 -0
- package/dist/src/llm/types.js +2 -0
- package/dist/src/llm/types.js.map +1 -0
- package/dist/src/logging/audit-log.d.ts +89 -0
- package/dist/src/logging/audit-log.d.ts.map +1 -0
- package/dist/src/logging/audit-log.js +132 -0
- package/dist/src/logging/audit-log.js.map +1 -0
- package/dist/src/logging/logger.d.ts +13 -0
- package/dist/src/logging/logger.d.ts.map +1 -0
- package/dist/src/logging/logger.js +57 -0
- package/dist/src/logging/logger.js.map +1 -0
- package/dist/src/logging/redactor.d.ts +14 -0
- package/dist/src/logging/redactor.d.ts.map +1 -0
- package/dist/src/logging/redactor.js +48 -0
- package/dist/src/logging/redactor.js.map +1 -0
- package/dist/src/mcp/handlers.d.ts +21 -0
- package/dist/src/mcp/handlers.d.ts.map +1 -0
- package/dist/src/mcp/handlers.js +156 -0
- package/dist/src/mcp/handlers.js.map +1 -0
- package/dist/src/mcp/server.d.ts +8 -0
- package/dist/src/mcp/server.d.ts.map +1 -0
- package/dist/src/mcp/server.js +40 -0
- package/dist/src/mcp/server.js.map +1 -0
- package/dist/src/mcp/types.d.ts +20 -0
- package/dist/src/mcp/types.d.ts.map +1 -0
- package/dist/src/mcp/types.js +2 -0
- package/dist/src/mcp/types.js.map +1 -0
- package/dist/src/plans/parser.d.ts +33 -0
- package/dist/src/plans/parser.d.ts.map +1 -0
- package/dist/src/plans/parser.js +93 -0
- package/dist/src/plans/parser.js.map +1 -0
- package/dist/src/plans/propose.d.ts +26 -0
- package/dist/src/plans/propose.d.ts.map +1 -0
- package/dist/src/plans/propose.js +85 -0
- package/dist/src/plans/propose.js.map +1 -0
- package/dist/src/plans/runner.d.ts +19 -0
- package/dist/src/plans/runner.d.ts.map +1 -0
- package/dist/src/plans/runner.js +159 -0
- package/dist/src/plans/runner.js.map +1 -0
- package/dist/src/plans/triggers.d.ts +12 -0
- package/dist/src/plans/triggers.d.ts.map +1 -0
- package/dist/src/plans/triggers.js +43 -0
- package/dist/src/plans/triggers.js.map +1 -0
- package/dist/src/plans/types.d.ts +454 -0
- package/dist/src/plans/types.d.ts.map +1 -0
- package/dist/src/plans/types.js +56 -0
- package/dist/src/plans/types.js.map +1 -0
- package/dist/src/policy/audit.d.ts +35 -0
- package/dist/src/policy/audit.d.ts.map +1 -0
- package/dist/src/policy/audit.js +39 -0
- package/dist/src/policy/audit.js.map +1 -0
- package/dist/src/policy/engine.d.ts +35 -0
- package/dist/src/policy/engine.d.ts.map +1 -0
- package/dist/src/policy/engine.js +134 -0
- package/dist/src/policy/engine.js.map +1 -0
- package/dist/src/policy/scope.d.ts +27 -0
- package/dist/src/policy/scope.d.ts.map +1 -0
- package/dist/src/policy/scope.js +89 -0
- package/dist/src/policy/scope.js.map +1 -0
- package/dist/src/policy/types.d.ts +15 -0
- package/dist/src/policy/types.d.ts.map +1 -0
- package/dist/src/policy/types.js +2 -0
- package/dist/src/policy/types.js.map +1 -0
- package/dist/src/self-extend/generator.d.ts +27 -0
- package/dist/src/self-extend/generator.d.ts.map +1 -0
- package/dist/src/self-extend/generator.js +107 -0
- package/dist/src/self-extend/generator.js.map +1 -0
- package/dist/src/self-extend/publisher.d.ts +5 -0
- package/dist/src/self-extend/publisher.d.ts.map +1 -0
- package/dist/src/self-extend/publisher.js +40 -0
- package/dist/src/self-extend/publisher.js.map +1 -0
- package/dist/src/self-extend/sandbox.d.ts +10 -0
- package/dist/src/self-extend/sandbox.d.ts.map +1 -0
- package/dist/src/self-extend/sandbox.js +22 -0
- package/dist/src/self-extend/sandbox.js.map +1 -0
- package/dist/src/skills/hub/lockfile.d.ts +15 -0
- package/dist/src/skills/hub/lockfile.d.ts.map +1 -0
- package/dist/src/skills/hub/lockfile.js +13 -0
- package/dist/src/skills/hub/lockfile.js.map +1 -0
- package/dist/src/skills/hub/publisher.d.ts +7 -0
- package/dist/src/skills/hub/publisher.d.ts.map +1 -0
- package/dist/src/skills/hub/publisher.js +10 -0
- package/dist/src/skills/hub/publisher.js.map +1 -0
- package/dist/src/skills/hub/registry.d.ts +16 -0
- package/dist/src/skills/hub/registry.d.ts.map +1 -0
- package/dist/src/skills/hub/registry.js +24 -0
- package/dist/src/skills/hub/registry.js.map +1 -0
- package/dist/src/skills/index.d.ts +12 -0
- package/dist/src/skills/index.d.ts.map +1 -0
- package/dist/src/skills/index.js +82 -0
- package/dist/src/skills/index.js.map +1 -0
- package/dist/src/skills/lifecycle.d.ts +19 -0
- package/dist/src/skills/lifecycle.d.ts.map +1 -0
- package/dist/src/skills/lifecycle.js +48 -0
- package/dist/src/skills/lifecycle.js.map +1 -0
- package/dist/src/skills/loader.d.ts +43 -0
- package/dist/src/skills/loader.d.ts.map +1 -0
- package/dist/src/skills/loader.js +142 -0
- package/dist/src/skills/loader.js.map +1 -0
- package/dist/src/skills/runner.d.ts +43 -0
- package/dist/src/skills/runner.d.ts.map +1 -0
- package/dist/src/skills/runner.js +198 -0
- package/dist/src/skills/runner.js.map +1 -0
- package/dist/src/skills/types.d.ts +150 -0
- package/dist/src/skills/types.d.ts.map +1 -0
- package/dist/src/skills/types.js +31 -0
- package/dist/src/skills/types.js.map +1 -0
- package/dist/src/skills/validator.d.ts +19 -0
- package/dist/src/skills/validator.d.ts.map +1 -0
- package/dist/src/skills/validator.js +92 -0
- package/dist/src/skills/validator.js.map +1 -0
- package/dist/src/tools/core/cmd.d.ts +24 -0
- package/dist/src/tools/core/cmd.d.ts.map +1 -0
- package/dist/src/tools/core/cmd.js +55 -0
- package/dist/src/tools/core/cmd.js.map +1 -0
- package/dist/src/tools/core/fs.d.ts +76 -0
- package/dist/src/tools/core/fs.d.ts.map +1 -0
- package/dist/src/tools/core/fs.js +173 -0
- package/dist/src/tools/core/fs.js.map +1 -0
- package/dist/src/tools/core/git.d.ts +62 -0
- package/dist/src/tools/core/git.d.ts.map +1 -0
- package/dist/src/tools/core/git.js +138 -0
- package/dist/src/tools/core/git.js.map +1 -0
- package/dist/src/tools/core/project.d.ts +17 -0
- package/dist/src/tools/core/project.d.ts.map +1 -0
- package/dist/src/tools/core/project.js +104 -0
- package/dist/src/tools/core/project.js.map +1 -0
- package/dist/src/tools/plugins/loader.d.ts +13 -0
- package/dist/src/tools/plugins/loader.d.ts.map +1 -0
- package/dist/src/tools/plugins/loader.js +36 -0
- package/dist/src/tools/plugins/loader.js.map +1 -0
- package/dist/src/tools/registry.d.ts +38 -0
- package/dist/src/tools/registry.d.ts.map +1 -0
- package/dist/src/tools/registry.js +118 -0
- package/dist/src/tools/registry.js.map +1 -0
- package/dist/src/tools/types.d.ts +46 -0
- package/dist/src/tools/types.d.ts.map +1 -0
- package/dist/src/tools/types.js +10 -0
- package/dist/src/tools/types.js.map +1 -0
- package/dist/src/utils/hash.d.ts +13 -0
- package/dist/src/utils/hash.d.ts.map +1 -0
- package/dist/src/utils/hash.js +22 -0
- package/dist/src/utils/hash.js.map +1 -0
- package/dist/src/utils/paths.d.ts +45 -0
- package/dist/src/utils/paths.d.ts.map +1 -0
- package/dist/src/utils/paths.js +71 -0
- package/dist/src/utils/paths.js.map +1 -0
- package/dist/src/utils/schema.d.ts +16 -0
- package/dist/src/utils/schema.d.ts.map +1 -0
- package/dist/src/utils/schema.js +66 -0
- package/dist/src/utils/schema.js.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secrets management: OS keychain integration with fallback
|
|
3
|
+
* Handles API key storage, retrieval, and redaction
|
|
4
|
+
*/
|
|
5
|
+
// List of well-known secret patterns for auto-redaction
|
|
6
|
+
const SECRET_PATTERNS = [
|
|
7
|
+
/sk-[a-zA-Z0-9_-]{20,}/g, // OpenAI
|
|
8
|
+
/sk-ant-[a-zA-Z0-9_-]{20,}/g, // Anthropic
|
|
9
|
+
/ghp_[a-zA-Z0-9]{36}/g, // GitHub PAT
|
|
10
|
+
/gho_[a-zA-Z0-9]{36}/g, // GitHub OAuth
|
|
11
|
+
/glpat-[a-zA-Z0-9_-]{20,}/g, // GitLab PAT
|
|
12
|
+
/xoxb-[a-zA-Z0-9-]+/g, // Slack Bot
|
|
13
|
+
/xoxp-[a-zA-Z0-9-]+/g, // Slack User
|
|
14
|
+
/AKIA[0-9A-Z]{16}/g, // AWS Access Key
|
|
15
|
+
/[a-f0-9]{32,}/g, // Generic hex tokens (>32 chars)
|
|
16
|
+
];
|
|
17
|
+
/**
|
|
18
|
+
* Redact secrets from a string
|
|
19
|
+
*/
|
|
20
|
+
export function redactSecrets(text) {
|
|
21
|
+
let result = text;
|
|
22
|
+
for (const pattern of SECRET_PATTERNS) {
|
|
23
|
+
result = result.replace(pattern, (match) => {
|
|
24
|
+
if (match.length < 8)
|
|
25
|
+
return match;
|
|
26
|
+
return match.substring(0, 4) + '***' + match.substring(match.length - 4);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
return result;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* In-memory secrets store (fallback when OS keychain is unavailable)
|
|
33
|
+
*/
|
|
34
|
+
class SecretsStore {
|
|
35
|
+
secrets = new Map();
|
|
36
|
+
keytarAvailable = null;
|
|
37
|
+
/**
|
|
38
|
+
* Store a secret
|
|
39
|
+
*/
|
|
40
|
+
async set(key, value) {
|
|
41
|
+
if (await this.useKeytar()) {
|
|
42
|
+
try {
|
|
43
|
+
const keytar = await import('keytar');
|
|
44
|
+
await keytar.default.setPassword('agent-runtime', key, value);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// Fallback to in-memory
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
this.secrets.set(key, value);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Retrieve a secret
|
|
55
|
+
*/
|
|
56
|
+
async get(key) {
|
|
57
|
+
if (await this.useKeytar()) {
|
|
58
|
+
try {
|
|
59
|
+
const keytar = await import('keytar');
|
|
60
|
+
return await keytar.default.getPassword('agent-runtime', key);
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// Fallback to in-memory
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return this.secrets.get(key) ?? null;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Delete a secret
|
|
70
|
+
*/
|
|
71
|
+
async delete(key) {
|
|
72
|
+
if (await this.useKeytar()) {
|
|
73
|
+
try {
|
|
74
|
+
const keytar = await import('keytar');
|
|
75
|
+
await keytar.default.deletePassword('agent-runtime', key);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
// Fallback to in-memory
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
this.secrets.delete(key);
|
|
83
|
+
}
|
|
84
|
+
async useKeytar() {
|
|
85
|
+
if (this.keytarAvailable !== null)
|
|
86
|
+
return this.keytarAvailable;
|
|
87
|
+
try {
|
|
88
|
+
await import('keytar');
|
|
89
|
+
this.keytarAvailable = true;
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
this.keytarAvailable = false;
|
|
93
|
+
}
|
|
94
|
+
return this.keytarAvailable;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
export const secretsStore = new SecretsStore();
|
|
98
|
+
//# sourceMappingURL=secrets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"secrets.js","sourceRoot":"","sources":["../../../src/config/secrets.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,wDAAwD;AACxD,MAAM,eAAe,GAAG;IACpB,wBAAwB,EAAiB,SAAS;IAClD,4BAA4B,EAAa,YAAY;IACrD,sBAAsB,EAAmB,aAAa;IACtD,sBAAsB,EAAmB,eAAe;IACxD,2BAA2B,EAAc,aAAa;IACtD,qBAAqB,EAAoB,YAAY;IACrD,qBAAqB,EAAoB,aAAa;IACtD,mBAAmB,EAAsB,iBAAiB;IAC1D,gBAAgB,EAAyB,iCAAiC;CAC7E,CAAC;AAEF;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACtC,IAAI,MAAM,GAAG,IAAI,CAAC;IAClB,KAAK,MAAM,OAAO,IAAI,eAAe,EAAE,CAAC;QACpC,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YACvC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;gBAAE,OAAO,KAAK,CAAC;YACnC,OAAO,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC7E,CAAC,CAAC,CAAC;IACP,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,MAAM,YAAY;IACN,OAAO,GAAwB,IAAI,GAAG,EAAE,CAAC;IACzC,eAAe,GAAmB,IAAI,CAAC;IAE/C;;OAEG;IACH,KAAK,CAAC,GAAG,CAAC,GAAW,EAAE,KAAa;QAChC,IAAI,MAAM,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;YACzB,IAAI,CAAC;gBACD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;gBACtC,MAAM,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,eAAe,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;gBAC9D,OAAO;YACX,CAAC;YAAC,MAAM,CAAC;gBACL,wBAAwB;YAC5B,CAAC;QACL,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACjC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,GAAG,CAAC,GAAW;QACjB,IAAI,MAAM,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;YACzB,IAAI,CAAC;gBACD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;gBACtC,OAAO,MAAM,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;YAClE,CAAC;YAAC,MAAM,CAAC;gBACL,wBAAwB;YAC5B,CAAC;QACL,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;IACzC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,MAAM,CAAC,GAAW;QACpB,IAAI,MAAM,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;YACzB,IAAI,CAAC;gBACD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;gBACtC,MAAM,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC;gBAC1D,OAAO;YACX,CAAC;YAAC,MAAM,CAAC;gBACL,wBAAwB;YAC5B,CAAC;QACL,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAEO,KAAK,CAAC,SAAS;QACnB,IAAI,IAAI,CAAC,eAAe,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC,eAAe,CAAC;QAC/D,IAAI,CAAC;YACD,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;YACvB,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAChC,CAAC;QAAC,MAAM,CAAC;YACL,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;QACjC,CAAC;QACD,OAAO,IAAI,CAAC,eAAe,CAAC;IAChC,CAAC;CACJ;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Daemon manager — start/stop/status for the agent daemon process
|
|
3
|
+
*/
|
|
4
|
+
export declare class DaemonManager {
|
|
5
|
+
private pidFile;
|
|
6
|
+
constructor(pidFile?: string);
|
|
7
|
+
/**
|
|
8
|
+
* Start the daemon
|
|
9
|
+
*/
|
|
10
|
+
start(): Promise<{
|
|
11
|
+
pid: number;
|
|
12
|
+
message: string;
|
|
13
|
+
}>;
|
|
14
|
+
/**
|
|
15
|
+
* Stop the daemon
|
|
16
|
+
*/
|
|
17
|
+
stop(): Promise<{
|
|
18
|
+
message: string;
|
|
19
|
+
}>;
|
|
20
|
+
/**
|
|
21
|
+
* Get daemon status
|
|
22
|
+
*/
|
|
23
|
+
status(): Promise<{
|
|
24
|
+
running: boolean;
|
|
25
|
+
pid?: number;
|
|
26
|
+
}>;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../src/daemon/manager.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,qBAAa,aAAa;IACtB,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,CAAC,EAAE,MAAM;IAI5B;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IA0BxD;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAiB1C;;OAEG;IACG,MAAM,IAAI,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAoB9D"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { readFile, writeFile, access } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fork } from 'node:child_process';
|
|
4
|
+
import { getAgentDir } from '../utils/paths.js';
|
|
5
|
+
/**
|
|
6
|
+
* Daemon manager — start/stop/status for the agent daemon process
|
|
7
|
+
*/
|
|
8
|
+
export class DaemonManager {
|
|
9
|
+
pidFile;
|
|
10
|
+
constructor(pidFile) {
|
|
11
|
+
this.pidFile = pidFile ?? path.join(getAgentDir(), 'daemon.pid');
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Start the daemon
|
|
15
|
+
*/
|
|
16
|
+
async start() {
|
|
17
|
+
// Check if already running
|
|
18
|
+
const existing = await this.status();
|
|
19
|
+
if (existing.running) {
|
|
20
|
+
return { pid: existing.pid, message: `Daemon already running (PID: ${existing.pid})` };
|
|
21
|
+
}
|
|
22
|
+
// Fork the daemon process
|
|
23
|
+
const daemonScript = path.resolve(path.dirname(new URL(import.meta.url).pathname), 'scheduler.js');
|
|
24
|
+
const child = fork(daemonScript, [], {
|
|
25
|
+
detached: true,
|
|
26
|
+
stdio: 'ignore',
|
|
27
|
+
});
|
|
28
|
+
child.unref();
|
|
29
|
+
const pid = child.pid;
|
|
30
|
+
await writeFile(this.pidFile, String(pid), 'utf-8');
|
|
31
|
+
return { pid, message: `Daemon started (PID: ${pid})` };
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Stop the daemon
|
|
35
|
+
*/
|
|
36
|
+
async stop() {
|
|
37
|
+
const status = await this.status();
|
|
38
|
+
if (!status.running || !status.pid) {
|
|
39
|
+
return { message: 'Daemon is not running' };
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
process.kill(status.pid, 'SIGTERM');
|
|
43
|
+
// Clean up PID file
|
|
44
|
+
const { unlink } = await import('node:fs/promises');
|
|
45
|
+
await unlink(this.pidFile).catch(() => { });
|
|
46
|
+
return { message: `Daemon stopped (PID: ${status.pid})` };
|
|
47
|
+
}
|
|
48
|
+
catch (err) {
|
|
49
|
+
return { message: `Failed to stop daemon: ${err.message}` };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Get daemon status
|
|
54
|
+
*/
|
|
55
|
+
async status() {
|
|
56
|
+
try {
|
|
57
|
+
await access(this.pidFile);
|
|
58
|
+
const pidStr = await readFile(this.pidFile, 'utf-8');
|
|
59
|
+
const pid = parseInt(pidStr.trim(), 10);
|
|
60
|
+
// Check if process is alive
|
|
61
|
+
try {
|
|
62
|
+
process.kill(pid, 0);
|
|
63
|
+
return { running: true, pid };
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
// PID file exists but process is dead
|
|
67
|
+
const { unlink } = await import('node:fs/promises');
|
|
68
|
+
await unlink(this.pidFile).catch(() => { });
|
|
69
|
+
return { running: false };
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return { running: false };
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../../src/daemon/manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../../src/daemon/scheduler.ts"],"names":[],"mappings":"AAaA;;;GAGG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAiEpD"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { Cron } from 'croner';
|
|
2
|
+
import { ConfigLoader } from '../config/loader.js';
|
|
3
|
+
import { PlanParser } from '../plans/parser.js';
|
|
4
|
+
import { PlanRunner } from '../plans/runner.js';
|
|
5
|
+
import { ExecutionEngine } from '../engine/executor.js';
|
|
6
|
+
import { ToolRegistry } from '../tools/registry.js';
|
|
7
|
+
import { PolicyEngine } from '../policy/engine.js';
|
|
8
|
+
import { SkillLoader } from '../skills/loader.js';
|
|
9
|
+
import { SkillRunner } from '../skills/runner.js';
|
|
10
|
+
import { LLMRouter } from '../llm/router.js';
|
|
11
|
+
import { generateRunId } from '../utils/paths.js';
|
|
12
|
+
/**
|
|
13
|
+
* Daemon scheduler — runs plans on cron schedules
|
|
14
|
+
* This is the daemon's main loop, started by DaemonManager
|
|
15
|
+
*/
|
|
16
|
+
export async function startScheduler() {
|
|
17
|
+
const configLoader = new ConfigLoader();
|
|
18
|
+
const config = await configLoader.load();
|
|
19
|
+
const registry = ToolRegistry.getInstance();
|
|
20
|
+
const policy = new PolicyEngine(config, process.cwd());
|
|
21
|
+
const skillLoader = new SkillLoader(config);
|
|
22
|
+
const llmRouter = new LLMRouter(config);
|
|
23
|
+
const skillRunner = new SkillRunner(registry, policy, llmRouter);
|
|
24
|
+
const engine = new ExecutionEngine(registry, policy, skillLoader, skillRunner);
|
|
25
|
+
const planParser = new PlanParser();
|
|
26
|
+
const planRunner = new PlanRunner(engine);
|
|
27
|
+
await skillLoader.loadAll();
|
|
28
|
+
// Discover plans with cron triggers
|
|
29
|
+
const plans = await planParser.listPlans();
|
|
30
|
+
const cronJobs = [];
|
|
31
|
+
for (const planInfo of plans) {
|
|
32
|
+
try {
|
|
33
|
+
const plan = await planParser.parseFile(planInfo.path);
|
|
34
|
+
if (plan.trigger.type === 'cron' && plan.trigger.cron) {
|
|
35
|
+
const job = new Cron(plan.trigger.cron, {
|
|
36
|
+
timezone: config.daemon.timezone,
|
|
37
|
+
}, async () => {
|
|
38
|
+
const ctx = {
|
|
39
|
+
runId: generateRunId(),
|
|
40
|
+
cwd: process.cwd(),
|
|
41
|
+
config,
|
|
42
|
+
autonomous: plan.policy.approvals === 'auto',
|
|
43
|
+
approvedPermissions: new Set(),
|
|
44
|
+
};
|
|
45
|
+
console.log(`[scheduler] Running plan: ${plan.name}`);
|
|
46
|
+
try {
|
|
47
|
+
if (plan.mode === 'propose') {
|
|
48
|
+
await planRunner.propose(plan, ctx);
|
|
49
|
+
console.log(`[scheduler] Proposed run for plan: ${plan.name}`);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
const run = await planRunner.run(plan, ctx);
|
|
53
|
+
console.log(`[scheduler] Plan ${plan.name} completed: ${run.status}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
console.error(`[scheduler] Plan ${plan.name} failed: ${err.message}`);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
cronJobs.push(job);
|
|
61
|
+
console.log(`[scheduler] Registered cron for ${plan.name}: ${plan.trigger.cron}`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch (err) {
|
|
65
|
+
console.error(`[scheduler] Failed to load plan ${planInfo.name}: ${err.message}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
console.log(`[scheduler] Started with ${cronJobs.length} cron jobs`);
|
|
69
|
+
// Keep the process alive
|
|
70
|
+
process.on('SIGTERM', () => {
|
|
71
|
+
console.log('[scheduler] Shutting down...');
|
|
72
|
+
for (const job of cronJobs) {
|
|
73
|
+
job.stop();
|
|
74
|
+
}
|
|
75
|
+
process.exit(0);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
// Auto-start if run directly
|
|
79
|
+
if (process.argv[1] === new URL(import.meta.url).pathname) {
|
|
80
|
+
startScheduler().catch(console.error);
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=scheduler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../../src/daemon/scheduler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type TriggerEvent } from '../plans/triggers.js';
|
|
2
|
+
/**
|
|
3
|
+
* File system & git event watcher
|
|
4
|
+
*/
|
|
5
|
+
export declare class EventWatcher {
|
|
6
|
+
private watchers;
|
|
7
|
+
/**
|
|
8
|
+
* Start watching for file system events
|
|
9
|
+
*/
|
|
10
|
+
start(onTrigger: (planName: string, event: TriggerEvent) => void): Promise<void>;
|
|
11
|
+
/**
|
|
12
|
+
* Stop all watchers
|
|
13
|
+
*/
|
|
14
|
+
stop(): Promise<void>;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=watcher.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher.d.ts","sourceRoot":"","sources":["../../../src/daemon/watcher.ts"],"names":[],"mappings":"AAGA,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAE1E;;GAEG;AACH,qBAAa,YAAY;IACrB,OAAO,CAAC,QAAQ,CAAkC;IAElD;;OAEG;IACG,KAAK,CAAC,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IA0CtF;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAM9B"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { watch } from 'chokidar';
|
|
2
|
+
import { ConfigLoader } from '../config/loader.js';
|
|
3
|
+
import { PlanParser } from '../plans/parser.js';
|
|
4
|
+
import { evaluateTrigger } from '../plans/triggers.js';
|
|
5
|
+
/**
|
|
6
|
+
* File system & git event watcher
|
|
7
|
+
*/
|
|
8
|
+
export class EventWatcher {
|
|
9
|
+
watchers = [];
|
|
10
|
+
/**
|
|
11
|
+
* Start watching for file system events
|
|
12
|
+
*/
|
|
13
|
+
async start(onTrigger) {
|
|
14
|
+
const configLoader = new ConfigLoader();
|
|
15
|
+
const config = await configLoader.load();
|
|
16
|
+
const planParser = new PlanParser();
|
|
17
|
+
const plans = await planParser.listPlans();
|
|
18
|
+
for (const planInfo of plans) {
|
|
19
|
+
try {
|
|
20
|
+
const plan = await planParser.parseFile(planInfo.path);
|
|
21
|
+
if (plan.trigger.type === 'fs_change' && plan.trigger.paths) {
|
|
22
|
+
const watcher = watch(plan.trigger.paths, {
|
|
23
|
+
cwd: process.cwd(),
|
|
24
|
+
ignoreInitial: true,
|
|
25
|
+
awaitWriteFinish: {
|
|
26
|
+
stabilityThreshold: config.daemon.watcherDebounceMs,
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
watcher.on('change', (path) => {
|
|
30
|
+
const event = { type: 'fs_change', path };
|
|
31
|
+
if (evaluateTrigger(plan.trigger, event)) {
|
|
32
|
+
onTrigger(plan.name, event);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
watcher.on('add', (path) => {
|
|
36
|
+
const event = { type: 'fs_change', path };
|
|
37
|
+
if (evaluateTrigger(plan.trigger, event)) {
|
|
38
|
+
onTrigger(plan.name, event);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
this.watchers.push(watcher);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
// Skip invalid plans
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Stop all watchers
|
|
51
|
+
*/
|
|
52
|
+
async stop() {
|
|
53
|
+
for (const watcher of this.watchers) {
|
|
54
|
+
await watcher.close();
|
|
55
|
+
}
|
|
56
|
+
this.watchers = [];
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher.js","sourceRoot":"","sources":["../../../src/daemon/watcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,eAAe,EAAqB,MAAM,sBAAsB,CAAC;AAE1E;;GAEG;AACH,MAAM,OAAO,YAAY;IACb,QAAQ,GAA+B,EAAE,CAAC;IAElD;;OAEG;IACH,KAAK,CAAC,KAAK,CAAC,SAA0D;QAClE,MAAM,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC;QACxC,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,IAAI,EAAE,CAAC;QACzC,MAAM,UAAU,GAAG,IAAI,UAAU,EAAE,CAAC;QAEpC,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,SAAS,EAAE,CAAC;QAE3C,KAAK,MAAM,QAAQ,IAAI,KAAK,EAAE,CAAC;YAC3B,IAAI,CAAC;gBACD,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBAEvD,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,WAAW,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;oBAC1D,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE;wBACtC,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;wBAClB,aAAa,EAAE,IAAI;wBACnB,gBAAgB,EAAE;4BACd,kBAAkB,EAAE,MAAM,CAAC,MAAM,CAAC,iBAAiB;yBACtD;qBACJ,CAAC,CAAC;oBAEH,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,EAAE;wBAC1B,MAAM,KAAK,GAAiB,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;wBACxD,IAAI,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC;4BACvC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;wBAChC,CAAC;oBACL,CAAC,CAAC,CAAC;oBAEH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE;wBACvB,MAAM,KAAK,GAAiB,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;wBACxD,IAAI,eAAe,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC;4BACvC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;wBAChC,CAAC;oBACL,CAAC,CAAC,CAAC;oBAEH,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBAChC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACL,qBAAqB;YACzB,CAAC;QACL,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI;QACN,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClC,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QAC1B,CAAC;QACD,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;IACvB,CAAC;CACJ"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { PlanStep, VerifyConfig } from '../plans/types.js';
|
|
2
|
+
import type { ExecutionContext } from '../tools/types.js';
|
|
3
|
+
import type { StepResult } from './types.js';
|
|
4
|
+
import { ToolRegistry } from '../tools/registry.js';
|
|
5
|
+
import { PolicyEngine } from '../policy/engine.js';
|
|
6
|
+
import { SkillLoader } from '../skills/loader.js';
|
|
7
|
+
import { SkillRunner } from '../skills/runner.js';
|
|
8
|
+
import { RollbackTracker } from './rollback.js';
|
|
9
|
+
/**
|
|
10
|
+
* Execution engine — state machine loop for step execution
|
|
11
|
+
*
|
|
12
|
+
* Each step follows:
|
|
13
|
+
* 1. Plan step selection (resolved by caller)
|
|
14
|
+
* 2. Preconditions check
|
|
15
|
+
* 3. Action execution (skill or tool)
|
|
16
|
+
* 4. Verification
|
|
17
|
+
* 5. Retry or fallback
|
|
18
|
+
* 6. Mark complete and proceed
|
|
19
|
+
*/
|
|
20
|
+
export declare class ExecutionEngine {
|
|
21
|
+
private registry;
|
|
22
|
+
private policy;
|
|
23
|
+
private skillLoader;
|
|
24
|
+
private skillRunner;
|
|
25
|
+
private rollback;
|
|
26
|
+
constructor(registry: ToolRegistry, policy: PolicyEngine, skillLoader: SkillLoader, skillRunner: SkillRunner);
|
|
27
|
+
/**
|
|
28
|
+
* Execute a single plan step
|
|
29
|
+
*/
|
|
30
|
+
executeStep(step: PlanStep, ctx: ExecutionContext): Promise<StepResult>;
|
|
31
|
+
/**
|
|
32
|
+
* Execute a step via a skill
|
|
33
|
+
*/
|
|
34
|
+
private executeSkillStep;
|
|
35
|
+
/**
|
|
36
|
+
* Execute a step via a direct tool call
|
|
37
|
+
*/
|
|
38
|
+
private executeToolStep;
|
|
39
|
+
/**
|
|
40
|
+
* Run verification for a step
|
|
41
|
+
*/
|
|
42
|
+
verify(verifyConfig: VerifyConfig, ctx: ExecutionContext): Promise<{
|
|
43
|
+
passed: boolean;
|
|
44
|
+
details: string;
|
|
45
|
+
}>;
|
|
46
|
+
/**
|
|
47
|
+
* Get the rollback tracker
|
|
48
|
+
*/
|
|
49
|
+
getRollbackTracker(): RollbackTracker;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../../src/engine/executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAQhD;;;;;;;;;;GAUG;AACH,qBAAa,eAAe;IACxB,OAAO,CAAC,QAAQ,CAAe;IAC/B,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,QAAQ,CAAkB;gBAG9B,QAAQ,EAAE,YAAY,EACtB,MAAM,EAAE,YAAY,EACpB,WAAW,EAAE,WAAW,EACxB,WAAW,EAAE,WAAW;IAS5B;;OAEG;IACG,WAAW,CAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC,UAAU,CAAC;IAmC7E;;OAEG;YACW,gBAAgB;IAiB9B;;OAEG;YACW,eAAe;IAyE7B;;OAEG;IACG,MAAM,CAAC,YAAY,EAAE,YAAY,EAAE,GAAG,EAAE,gBAAgB,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAgD9G;;OAEG;IACH,kBAAkB,IAAI,eAAe;CAGxC"}
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { RollbackTracker } from './rollback.js';
|
|
2
|
+
import { auditEmitter, AuditEventType } from '../policy/audit.js';
|
|
3
|
+
import { execFile } from 'node:child_process';
|
|
4
|
+
import { promisify } from 'node:util';
|
|
5
|
+
import { access } from 'node:fs/promises';
|
|
6
|
+
const execFileAsync = promisify(execFile);
|
|
7
|
+
/**
|
|
8
|
+
* Execution engine — state machine loop for step execution
|
|
9
|
+
*
|
|
10
|
+
* Each step follows:
|
|
11
|
+
* 1. Plan step selection (resolved by caller)
|
|
12
|
+
* 2. Preconditions check
|
|
13
|
+
* 3. Action execution (skill or tool)
|
|
14
|
+
* 4. Verification
|
|
15
|
+
* 5. Retry or fallback
|
|
16
|
+
* 6. Mark complete and proceed
|
|
17
|
+
*/
|
|
18
|
+
export class ExecutionEngine {
|
|
19
|
+
registry;
|
|
20
|
+
policy;
|
|
21
|
+
skillLoader;
|
|
22
|
+
skillRunner;
|
|
23
|
+
rollback;
|
|
24
|
+
constructor(registry, policy, skillLoader, skillRunner) {
|
|
25
|
+
this.registry = registry;
|
|
26
|
+
this.policy = policy;
|
|
27
|
+
this.skillLoader = skillLoader;
|
|
28
|
+
this.skillRunner = skillRunner;
|
|
29
|
+
this.rollback = new RollbackTracker();
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Execute a single plan step
|
|
33
|
+
*/
|
|
34
|
+
async executeStep(step, ctx) {
|
|
35
|
+
const start = Date.now();
|
|
36
|
+
try {
|
|
37
|
+
// Phase 1: Preconditions check
|
|
38
|
+
if (step.dependsOn && step.dependsOn.length > 0) {
|
|
39
|
+
// Dependencies are checked by PlanRunner before calling this
|
|
40
|
+
}
|
|
41
|
+
let result;
|
|
42
|
+
if (step.skill) {
|
|
43
|
+
// Execute via skill
|
|
44
|
+
result = await this.executeSkillStep(step, ctx);
|
|
45
|
+
}
|
|
46
|
+
else if (step.tool) {
|
|
47
|
+
// Execute via direct tool call
|
|
48
|
+
result = await this.executeToolStep(step, ctx);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
result = {
|
|
52
|
+
success: false,
|
|
53
|
+
error: `Step "${step.id}" has neither skill nor tool defined`,
|
|
54
|
+
durationMs: Date.now() - start,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
return { ...result, durationMs: Date.now() - start };
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
return {
|
|
61
|
+
success: false,
|
|
62
|
+
error: err.message,
|
|
63
|
+
durationMs: Date.now() - start,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Execute a step via a skill
|
|
69
|
+
*/
|
|
70
|
+
async executeSkillStep(step, ctx) {
|
|
71
|
+
const skill = this.skillLoader.get(step.skill);
|
|
72
|
+
if (!skill) {
|
|
73
|
+
return { success: false, error: `Skill "${step.skill}" not found`, durationMs: 0 };
|
|
74
|
+
}
|
|
75
|
+
const result = await this.skillRunner.run(skill, step.args ?? {}, ctx);
|
|
76
|
+
return {
|
|
77
|
+
success: result.success,
|
|
78
|
+
output: result.output,
|
|
79
|
+
error: result.error,
|
|
80
|
+
toolCalls: result.toolCalls,
|
|
81
|
+
durationMs: result.durationMs,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Execute a step via a direct tool call
|
|
86
|
+
*/
|
|
87
|
+
async executeToolStep(step, ctx) {
|
|
88
|
+
const tool = this.registry.get(step.tool);
|
|
89
|
+
if (!tool) {
|
|
90
|
+
return { success: false, error: `Tool "${step.tool}" not found`, durationMs: 0 };
|
|
91
|
+
}
|
|
92
|
+
// Check permissions
|
|
93
|
+
const permResult = await this.policy.checkPermission({
|
|
94
|
+
tool: step.tool,
|
|
95
|
+
operation: step.tool,
|
|
96
|
+
description: `Plan step "${step.name}" calling ${step.tool}`,
|
|
97
|
+
permissions: tool.permissions,
|
|
98
|
+
args: step.args,
|
|
99
|
+
riskLevel: 'medium',
|
|
100
|
+
}, ctx);
|
|
101
|
+
if (!permResult.allowed && permResult.requiresApproval) {
|
|
102
|
+
const approved = await this.policy.requestApproval({
|
|
103
|
+
tool: step.tool,
|
|
104
|
+
operation: step.tool,
|
|
105
|
+
description: `Plan step "${step.name}" calling ${step.tool}`,
|
|
106
|
+
permissions: tool.permissions,
|
|
107
|
+
args: step.args,
|
|
108
|
+
riskLevel: 'medium',
|
|
109
|
+
}, ctx);
|
|
110
|
+
if (!approved) {
|
|
111
|
+
return { success: false, error: 'Permission denied by user', durationMs: 0 };
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
else if (!permResult.allowed) {
|
|
115
|
+
return { success: false, error: permResult.reason, durationMs: 0 };
|
|
116
|
+
}
|
|
117
|
+
// Track file state for rollback (if filesystem write)
|
|
118
|
+
if (step.tool.startsWith('fs.') && step.args?.['path']) {
|
|
119
|
+
await this.rollback.captureBeforeState(step.id, step.args['path'], ctx.cwd);
|
|
120
|
+
}
|
|
121
|
+
const result = await this.registry.execute(step.tool, step.args, ctx);
|
|
122
|
+
auditEmitter.emit(AuditEventType.TOOL_CALL, {
|
|
123
|
+
stepId: step.id,
|
|
124
|
+
tool: step.tool,
|
|
125
|
+
input: step.args,
|
|
126
|
+
success: result.success,
|
|
127
|
+
});
|
|
128
|
+
// Capture after state for rollback
|
|
129
|
+
if (step.tool.startsWith('fs.') && step.args?.['path'] && result.success) {
|
|
130
|
+
await this.rollback.captureAfterState(step.id, step.args['path'], ctx.cwd);
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
success: result.success,
|
|
134
|
+
output: result.data,
|
|
135
|
+
error: result.error,
|
|
136
|
+
durationMs: result.durationMs,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Run verification for a step
|
|
141
|
+
*/
|
|
142
|
+
async verify(verifyConfig, ctx) {
|
|
143
|
+
const results = [];
|
|
144
|
+
let passed = true;
|
|
145
|
+
// Check command exit code
|
|
146
|
+
if (verifyConfig.command) {
|
|
147
|
+
try {
|
|
148
|
+
const { stdout } = await execFileAsync(verifyConfig.command.split(' ')[0], verifyConfig.command.split(' ').slice(1), { cwd: ctx.cwd, timeout: 30000, shell: true });
|
|
149
|
+
const output = stdout.toString();
|
|
150
|
+
if (verifyConfig.exitCode !== undefined) {
|
|
151
|
+
// Exit code check is implicit (execFile throws on non-zero)
|
|
152
|
+
results.push(`Command exited with code 0 (expected: ${verifyConfig.exitCode})`);
|
|
153
|
+
}
|
|
154
|
+
if (verifyConfig.contains && !output.includes(verifyConfig.contains)) {
|
|
155
|
+
passed = false;
|
|
156
|
+
results.push(`Output does not contain "${verifyConfig.contains}"`);
|
|
157
|
+
}
|
|
158
|
+
else if (verifyConfig.contains) {
|
|
159
|
+
results.push(`Output contains "${verifyConfig.contains}"`);
|
|
160
|
+
}
|
|
161
|
+
results.push('Command executed successfully');
|
|
162
|
+
}
|
|
163
|
+
catch (err) {
|
|
164
|
+
passed = false;
|
|
165
|
+
results.push(`Command failed: ${err.message}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
// Check file existence
|
|
169
|
+
if (verifyConfig.fileExists) {
|
|
170
|
+
try {
|
|
171
|
+
const filePath = require('node:path').resolve(ctx.cwd, verifyConfig.fileExists);
|
|
172
|
+
await access(filePath);
|
|
173
|
+
results.push(`File exists: ${verifyConfig.fileExists}`);
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
passed = false;
|
|
177
|
+
results.push(`File not found: ${verifyConfig.fileExists}`);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return { passed, details: results.join('\n') };
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Get the rollback tracker
|
|
184
|
+
*/
|
|
185
|
+
getRollbackTracker() {
|
|
186
|
+
return this.rollback;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
//# sourceMappingURL=executor.js.map
|