@treeseed/agent 0.1.2

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.
Files changed (93) hide show
  1. package/Dockerfile +7 -0
  2. package/README.md +62 -0
  3. package/dist/agent-runtime.js +111 -0
  4. package/dist/agents/adapters/execution.js +90 -0
  5. package/dist/agents/adapters/mutations.js +30 -0
  6. package/dist/agents/adapters/notification.js +16 -0
  7. package/dist/agents/adapters/repository.js +61 -0
  8. package/dist/agents/adapters/research.js +25 -0
  9. package/dist/agents/adapters/verification.js +62 -0
  10. package/dist/agents/cli-tools.js +5 -0
  11. package/dist/agents/cli.js +77 -0
  12. package/dist/agents/content-store.js +1 -0
  13. package/dist/agents/contracts/messages.js +138 -0
  14. package/dist/agents/contracts/run.js +0 -0
  15. package/dist/agents/d1-store.js +1 -0
  16. package/dist/agents/frontmatter.js +1 -0
  17. package/dist/agents/git-runtime.js +1 -0
  18. package/dist/agents/index.js +5 -0
  19. package/dist/agents/kernel/agent-kernel.js +284 -0
  20. package/dist/agents/kernel/trigger-resolver.js +153 -0
  21. package/dist/agents/model-registry.js +1 -0
  22. package/dist/agents/registry-helper.js +14 -0
  23. package/dist/agents/registry.js +91 -0
  24. package/dist/agents/runtime-types.js +0 -0
  25. package/dist/agents/sdk-filters.js +1 -0
  26. package/dist/agents/sdk-types.js +1 -0
  27. package/dist/agents/sdk.js +1 -0
  28. package/dist/agents/spec-loader.js +53 -0
  29. package/dist/agents/spec-normalizer.js +257 -0
  30. package/dist/agents/spec-types.js +0 -0
  31. package/dist/agents/stores/cursor-store.js +1 -0
  32. package/dist/agents/stores/helpers.js +1 -0
  33. package/dist/agents/stores/lease-store.js +1 -0
  34. package/dist/agents/stores/message-store.js +1 -0
  35. package/dist/agents/stores/run-store.js +1 -0
  36. package/dist/agents/stores/subscription-store.js +1 -0
  37. package/dist/agents/testing/agents-smoke.js +32 -0
  38. package/dist/agents/testing/e2e-harness.js +435 -0
  39. package/dist/agents/wrangler-d1.js +1 -0
  40. package/dist/index.js +9 -0
  41. package/dist/scripts/assert-release-tag-version.d.ts +1 -0
  42. package/dist/scripts/assert-release-tag-version.js +20 -0
  43. package/dist/scripts/build-dist.d.ts +1 -0
  44. package/dist/scripts/build-dist.js +98 -0
  45. package/dist/scripts/package-tools.d.ts +1 -0
  46. package/dist/scripts/package-tools.js +7 -0
  47. package/dist/scripts/publish-package.d.ts +1 -0
  48. package/dist/scripts/publish-package.js +19 -0
  49. package/dist/scripts/release-verify.d.ts +1 -0
  50. package/dist/scripts/release-verify.js +143 -0
  51. package/dist/scripts/test-smoke.d.ts +1 -0
  52. package/dist/scripts/test-smoke.js +23 -0
  53. package/dist/scripts/treeseed-agents.d.ts +2 -0
  54. package/dist/scripts/treeseed-agents.js +13 -0
  55. package/dist/src/agent-runtime.d.ts +17 -0
  56. package/dist/src/agents/adapters/execution.d.ts +46 -0
  57. package/dist/src/agents/adapters/mutations.d.ts +22 -0
  58. package/dist/src/agents/adapters/notification.d.ts +11 -0
  59. package/dist/src/agents/adapters/repository.d.ts +28 -0
  60. package/dist/src/agents/adapters/research.d.ts +14 -0
  61. package/dist/src/agents/adapters/verification.d.ts +36 -0
  62. package/dist/src/agents/cli-tools.d.ts +1 -0
  63. package/dist/src/agents/cli.d.ts +6 -0
  64. package/dist/src/agents/content-store.d.ts +1 -0
  65. package/dist/src/agents/contracts/messages.d.ts +88 -0
  66. package/dist/src/agents/contracts/run.d.ts +20 -0
  67. package/dist/src/agents/d1-store.d.ts +1 -0
  68. package/dist/src/agents/frontmatter.d.ts +1 -0
  69. package/dist/src/agents/git-runtime.d.ts +1 -0
  70. package/dist/src/agents/index.d.ts +1 -0
  71. package/dist/src/agents/kernel/agent-kernel.d.ts +52 -0
  72. package/dist/src/agents/kernel/trigger-resolver.d.ts +18 -0
  73. package/dist/src/agents/model-registry.d.ts +1 -0
  74. package/dist/src/agents/registry-helper.d.ts +4 -0
  75. package/dist/src/agents/registry.d.ts +7 -0
  76. package/dist/src/agents/runtime-types.d.ts +117 -0
  77. package/dist/src/agents/sdk-filters.d.ts +1 -0
  78. package/dist/src/agents/sdk-types.d.ts +1 -0
  79. package/dist/src/agents/sdk.d.ts +1 -0
  80. package/dist/src/agents/spec-loader.d.ts +18 -0
  81. package/dist/src/agents/spec-normalizer.d.ts +2 -0
  82. package/dist/src/agents/spec-types.d.ts +64 -0
  83. package/dist/src/agents/stores/cursor-store.d.ts +1 -0
  84. package/dist/src/agents/stores/helpers.d.ts +1 -0
  85. package/dist/src/agents/stores/lease-store.d.ts +1 -0
  86. package/dist/src/agents/stores/message-store.d.ts +1 -0
  87. package/dist/src/agents/stores/run-store.d.ts +1 -0
  88. package/dist/src/agents/stores/subscription-store.d.ts +1 -0
  89. package/dist/src/agents/testing/agents-smoke.d.ts +1 -0
  90. package/dist/src/agents/testing/e2e-harness.d.ts +44 -0
  91. package/dist/src/agents/wrangler-d1.d.ts +1 -0
  92. package/dist/src/index.d.ts +3 -0
  93. package/package.json +54 -0
package/Dockerfile ADDED
@@ -0,0 +1,7 @@
1
+ FROM node:20-bookworm-slim
2
+
3
+ WORKDIR /app
4
+
5
+ COPY . .
6
+
7
+ ENTRYPOINT ["node", "./dist/scripts/treeseed-agents.js", "start"]
package/README.md ADDED
@@ -0,0 +1,62 @@
1
+ # `@treeseed/agent`
2
+
3
+ Treeseed agent service runtime package.
4
+
5
+ This package publishes the `treeseed-agents` CLI and the runtime exports needed to load, inspect, and execute TreeSeed agents in a Treeseed tenant repository.
6
+
7
+ ## Requirements
8
+
9
+ - Node `>=20`
10
+ - npm
11
+ - a Treeseed tenant repository for runtime commands such as `doctor` and `start`
12
+
13
+ ## Install
14
+
15
+ ```bash
16
+ npm install @treeseed/agent @treeseed/core @treeseed/sdk
17
+ ```
18
+
19
+ ## Build And Test
20
+
21
+ ```bash
22
+ npm install
23
+ npm run build
24
+ npm test
25
+ npm run release:verify
26
+ ```
27
+
28
+ `npm test` runs the package smoke test. `npm run release:verify` rebuilds the package, runs the smoke test, and verifies that the packed tarball installs cleanly with the published `treeseed-agents` binary.
29
+
30
+ ## CLI
31
+
32
+ Run the CLI from a Treeseed tenant repository root, or set `TREESEED_TENANT_ROOT` to point at one.
33
+
34
+ ```bash
35
+ treeseed-agents doctor
36
+ treeseed-agents run-agent planner-agent
37
+ treeseed-agents start
38
+ ```
39
+
40
+ Available commands:
41
+
42
+ - `doctor`
43
+ - `run-agent <slug>`
44
+ - `drain-messages`
45
+ - `release-leases`
46
+ - `replay-message <id>`
47
+ - `start`
48
+
49
+ ## Package Scripts
50
+
51
+ - `npm run setup`: install dependencies with `npm install`
52
+ - `npm run setup:ci`: install dependencies with `npm ci`
53
+ - `npm run build`: build the distributable package
54
+ - `npm test`: run the smoke test
55
+ - `npm run release:verify`: verify build, smoke test, and packed-install behavior
56
+ - `npm run release:check-tag -- <tag>`: validate plain semver tags like `0.1.1` against `package.json`
57
+ - `npm run release:publish`: publish to npm
58
+
59
+ ## GitHub Actions
60
+
61
+ - `.github/workflows/ci.yml` runs `npm ci`, `npm run build`, `npm test`, and `npm run release:verify` on pushes and pull requests.
62
+ - `.github/workflows/publish.yml` runs the same verification steps before publishing on `*.*.*` version tags or manual dispatch.
@@ -0,0 +1,111 @@
1
+ import { loadTreeseedPluginRuntime } from "@treeseed/core/plugins/runtime";
2
+ import {
3
+ CopilotExecutionAdapter,
4
+ ManualExecutionAdapter,
5
+ StubExecutionAdapter
6
+ } from "./agents/adapters/execution.js";
7
+ import { LocalBranchMutationAdapter } from "./agents/adapters/mutations.js";
8
+ import { StubNotificationAdapter } from "./agents/adapters/notification.js";
9
+ import { GitRepositoryInspectionAdapter, StubRepositoryInspectionAdapter } from "./agents/adapters/repository.js";
10
+ import { StubResearchAdapter } from "./agents/adapters/research.js";
11
+ import { LocalVerificationAdapter, StubVerificationAdapter } from "./agents/adapters/verification.js";
12
+ let cachedAgentRuntime = null;
13
+ function readPluginRecord(pluginEntry, key) {
14
+ const value = pluginEntry.plugin[key];
15
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
16
+ }
17
+ function assertUniqueProvider(registry, id, owner) {
18
+ if (registry.has(id)) {
19
+ throw new Error(`Treeseed plugin runtime found duplicate provider "${id}" from ${owner}.`);
20
+ }
21
+ }
22
+ function collectAgentHandlersFromPlugin(pluginEntry, registry) {
23
+ const contributedHandlers = readPluginRecord(pluginEntry, "agentHandlers");
24
+ for (const [id, handler] of Object.entries(contributedHandlers)) {
25
+ assertUniqueProvider(registry, id, pluginEntry.package);
26
+ registry.set(id, handler);
27
+ }
28
+ }
29
+ function buildAgentRuntime() {
30
+ const runtime = loadTreeseedPluginRuntime();
31
+ const execution = /* @__PURE__ */ new Map([
32
+ ["stub", () => new StubExecutionAdapter()],
33
+ ["manual", () => new ManualExecutionAdapter()],
34
+ ["copilot", () => new CopilotExecutionAdapter()]
35
+ ]);
36
+ const mutation = /* @__PURE__ */ new Map([
37
+ ["local_branch", (repoRoot) => new LocalBranchMutationAdapter(repoRoot)]
38
+ ]);
39
+ const repository = /* @__PURE__ */ new Map([
40
+ ["stub", () => new StubRepositoryInspectionAdapter()],
41
+ ["git", () => new GitRepositoryInspectionAdapter()]
42
+ ]);
43
+ const verification = /* @__PURE__ */ new Map([
44
+ ["stub", () => new StubVerificationAdapter()],
45
+ ["local", () => new LocalVerificationAdapter()]
46
+ ]);
47
+ const notification = /* @__PURE__ */ new Map([["stub", () => new StubNotificationAdapter()]]);
48
+ const research = /* @__PURE__ */ new Map([["stub", () => new StubResearchAdapter()]]);
49
+ const handlers = /* @__PURE__ */ new Map();
50
+ for (const pluginEntry of runtime.plugins) {
51
+ const agentProviders = readPluginRecord(pluginEntry, "agentProviders");
52
+ for (const [id, factory] of Object.entries(agentProviders.execution ?? {})) {
53
+ assertUniqueProvider(execution, id, pluginEntry.package);
54
+ execution.set(id, factory);
55
+ }
56
+ for (const [id, factory] of Object.entries(agentProviders.mutation ?? {})) {
57
+ assertUniqueProvider(mutation, id, pluginEntry.package);
58
+ mutation.set(id, factory);
59
+ }
60
+ for (const [id, factory] of Object.entries(agentProviders.repository ?? {})) {
61
+ assertUniqueProvider(repository, id, pluginEntry.package);
62
+ repository.set(id, factory);
63
+ }
64
+ for (const [id, factory] of Object.entries(agentProviders.verification ?? {})) {
65
+ assertUniqueProvider(verification, id, pluginEntry.package);
66
+ verification.set(id, factory);
67
+ }
68
+ for (const [id, factory] of Object.entries(agentProviders.notification ?? {})) {
69
+ assertUniqueProvider(notification, id, pluginEntry.package);
70
+ notification.set(id, factory);
71
+ }
72
+ for (const [id, factory] of Object.entries(agentProviders.research ?? {})) {
73
+ assertUniqueProvider(research, id, pluginEntry.package);
74
+ research.set(id, factory);
75
+ }
76
+ collectAgentHandlersFromPlugin(pluginEntry, handlers);
77
+ }
78
+ return {
79
+ providers: { execution, mutation, repository, verification, notification, research },
80
+ handlers
81
+ };
82
+ }
83
+ function resolveAgentRuntimeProviders(repoRoot, selections) {
84
+ if (!cachedAgentRuntime) {
85
+ cachedAgentRuntime = buildAgentRuntime();
86
+ }
87
+ const executionFactory = cachedAgentRuntime.providers.execution.get(selections.execution);
88
+ const mutationFactory = cachedAgentRuntime.providers.mutation.get(selections.mutation);
89
+ const repositoryFactory = cachedAgentRuntime.providers.repository.get(selections.repository);
90
+ const verificationFactory = cachedAgentRuntime.providers.verification.get(selections.verification);
91
+ const notificationFactory = cachedAgentRuntime.providers.notification.get(selections.notification);
92
+ const researchFactory = cachedAgentRuntime.providers.research.get(selections.research);
93
+ if (!executionFactory) throw new Error(`Treeseed agent execution provider "${selections.execution}" is not registered.`);
94
+ if (!mutationFactory) throw new Error(`Treeseed agent mutation provider "${selections.mutation}" is not registered.`);
95
+ if (!repositoryFactory) throw new Error(`Treeseed agent repository provider "${selections.repository}" is not registered.`);
96
+ if (!verificationFactory) throw new Error(`Treeseed agent verification provider "${selections.verification}" is not registered.`);
97
+ if (!notificationFactory) throw new Error(`Treeseed agent notification provider "${selections.notification}" is not registered.`);
98
+ if (!researchFactory) throw new Error(`Treeseed agent research provider "${selections.research}" is not registered.`);
99
+ return {
100
+ execution: executionFactory(),
101
+ mutations: mutationFactory(repoRoot),
102
+ repository: repositoryFactory(),
103
+ verification: verificationFactory(),
104
+ notifications: notificationFactory(),
105
+ research: researchFactory(),
106
+ handlers: cachedAgentRuntime.handlers
107
+ };
108
+ }
109
+ export {
110
+ resolveAgentRuntimeProviders
111
+ };
@@ -0,0 +1,90 @@
1
+ import { execFile } from "node:child_process";
2
+ import { promisify } from "node:util";
3
+ import { normalizeAgentCliOptions, buildCopilotAllowToolArgs } from "../cli-tools.js";
4
+ import { getTreeseedAgentProviderSelections } from "@treeseed/core/deploy/runtime";
5
+ const execFileAsync = promisify(execFile);
6
+ class StubExecutionAdapter {
7
+ async runTask(input) {
8
+ return {
9
+ status: "completed",
10
+ summary: `Stubbed Copilot execution for ${input.runId}.`,
11
+ stdout: [
12
+ "# Planned Task",
13
+ "",
14
+ "1. Inspect the requested architecture context.",
15
+ "2. Produce a safe local change artifact.",
16
+ "3. Summarize the implementation intent.",
17
+ "",
18
+ `Prompt digest: ${input.prompt.slice(0, 240)}`
19
+ ].join("\n"),
20
+ stderr: ""
21
+ };
22
+ }
23
+ }
24
+ class CopilotExecutionAdapter {
25
+ async runTask(input) {
26
+ const cli = normalizeAgentCliOptions(input.agent.cli);
27
+ const args = ["copilot", "-p", input.prompt];
28
+ if (cli.model) {
29
+ args.push("--model", cli.model);
30
+ }
31
+ args.push(...buildCopilotAllowToolArgs(cli.allowTools));
32
+ args.push(...cli.additionalArgs ?? []);
33
+ try {
34
+ const { stdout, stderr } = await execFileAsync("gh", args, {
35
+ cwd: process.cwd(),
36
+ env: process.env,
37
+ maxBuffer: 10 * 1024 * 1024
38
+ });
39
+ return {
40
+ status: "completed",
41
+ summary: "Copilot task completed.",
42
+ stdout,
43
+ stderr
44
+ };
45
+ } catch (error) {
46
+ const stderr = error && typeof error === "object" && "stderr" in error ? String(error.stderr ?? "") : error instanceof Error ? error.message : String(error);
47
+ return {
48
+ status: "failed",
49
+ summary: "Copilot task failed.",
50
+ stdout: "",
51
+ stderr
52
+ };
53
+ }
54
+ }
55
+ }
56
+ class ManualExecutionAdapter {
57
+ async runTask(input) {
58
+ return {
59
+ status: "completed",
60
+ summary: `Manual execution mode is enabled for ${input.runId}.`,
61
+ stdout: [
62
+ "# Manual Execution Required",
63
+ "",
64
+ "This agent run is configured for manual execution.",
65
+ "Review the prompt below and complete the work outside the automated adapter.",
66
+ "",
67
+ input.prompt
68
+ ].join("\n"),
69
+ stderr: ""
70
+ };
71
+ }
72
+ }
73
+ function createExecutionAdapter() {
74
+ const configuredMode = String(
75
+ process.env.TREESEED_AGENT_EXECUTION_PROVIDER ?? getTreeseedAgentProviderSelections().execution
76
+ ).toLowerCase();
77
+ if (configuredMode === "manual") {
78
+ return new ManualExecutionAdapter();
79
+ }
80
+ if (configuredMode !== "copilot") {
81
+ return new StubExecutionAdapter();
82
+ }
83
+ return new CopilotExecutionAdapter();
84
+ }
85
+ export {
86
+ CopilotExecutionAdapter,
87
+ ManualExecutionAdapter,
88
+ StubExecutionAdapter,
89
+ createExecutionAdapter
90
+ };
@@ -0,0 +1,30 @@
1
+ import { mkdir, writeFile } from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { GitRuntime } from "../git-runtime.js";
4
+ class LocalBranchMutationAdapter {
5
+ git;
6
+ constructor(repoRoot) {
7
+ this.git = new GitRuntime(
8
+ repoRoot,
9
+ process.env.TREESEED_AGENT_DISABLE_GIT === "true"
10
+ );
11
+ }
12
+ async writeArtifact(input) {
13
+ const branchName = `${input.agent.execution.branchPrefix}/${input.runId}`;
14
+ const worktreePath = await this.git.ensureWorktree(branchName);
15
+ const filePath = path.join(worktreePath, input.relativePath);
16
+ await mkdir(path.dirname(filePath), { recursive: true });
17
+ await writeFile(filePath, input.content, "utf8");
18
+ const git = await this.git.commitFileChange(filePath, branchName, input.commitMessage);
19
+ return {
20
+ branchName: git.branchName,
21
+ commitMessage: git.commitMessage,
22
+ worktreePath: git.worktreePath,
23
+ commitSha: git.commitSha,
24
+ changedPaths: git.changedPaths
25
+ };
26
+ }
27
+ }
28
+ export {
29
+ LocalBranchMutationAdapter
30
+ };
@@ -0,0 +1,16 @@
1
+ class StubNotificationAdapter {
2
+ async deliver(input) {
3
+ return {
4
+ status: input.recipients.length ? "completed" : "waiting",
5
+ summary: input.recipients.length ? `Prepared ${input.recipients.length} notification(s).` : "No recipients available for notification.",
6
+ deliveredCount: input.recipients.length
7
+ };
8
+ }
9
+ }
10
+ function createNotificationAdapter() {
11
+ return new StubNotificationAdapter();
12
+ }
13
+ export {
14
+ StubNotificationAdapter,
15
+ createNotificationAdapter
16
+ };
@@ -0,0 +1,61 @@
1
+ import { execFile } from "node:child_process";
2
+ import { promisify } from "node:util";
3
+ import { getTreeseedAgentProviderSelections } from "@treeseed/core/deploy/runtime";
4
+ const execFileAsync = promisify(execFile);
5
+ class StubRepositoryInspectionAdapter {
6
+ async inspectBranch(input) {
7
+ return {
8
+ branchName: input.branchName,
9
+ changedPaths: [],
10
+ commitSha: null,
11
+ summary: input.branchName ? `Stub repository inspection for ${input.branchName}.` : "No branch to inspect."
12
+ };
13
+ }
14
+ }
15
+ class GitRepositoryInspectionAdapter {
16
+ async inspectBranch(input) {
17
+ if (!input.branchName) {
18
+ return {
19
+ branchName: null,
20
+ changedPaths: [],
21
+ commitSha: null,
22
+ summary: "No branch to inspect."
23
+ };
24
+ }
25
+ try {
26
+ const { stdout: changedStdout } = await execFileAsync(
27
+ "git",
28
+ ["diff", "--name-only", "HEAD~1..HEAD"],
29
+ { cwd: input.repoRoot, env: process.env }
30
+ );
31
+ const { stdout: shaStdout } = await execFileAsync("git", ["rev-parse", "HEAD"], {
32
+ cwd: input.repoRoot,
33
+ env: process.env
34
+ });
35
+ const changedPaths = changedStdout.split("\n").map((entry) => entry.trim()).filter(Boolean);
36
+ return {
37
+ branchName: input.branchName,
38
+ changedPaths,
39
+ commitSha: shaStdout.trim() || null,
40
+ summary: `Inspected ${changedPaths.length} changed path(s) on ${input.branchName}.`
41
+ };
42
+ } catch {
43
+ return {
44
+ branchName: input.branchName,
45
+ changedPaths: [],
46
+ commitSha: null,
47
+ summary: `Unable to inspect branch ${input.branchName}.`
48
+ };
49
+ }
50
+ }
51
+ }
52
+ function createRepositoryInspectionAdapter() {
53
+ return String(
54
+ process.env.TREESEED_AGENT_REPOSITORY_PROVIDER ?? getTreeseedAgentProviderSelections().repository
55
+ ).toLowerCase() !== "git" ? new StubRepositoryInspectionAdapter() : new GitRepositoryInspectionAdapter();
56
+ }
57
+ export {
58
+ GitRepositoryInspectionAdapter,
59
+ StubRepositoryInspectionAdapter,
60
+ createRepositoryInspectionAdapter
61
+ };
@@ -0,0 +1,25 @@
1
+ class StubResearchAdapter {
2
+ async research(input) {
3
+ return {
4
+ status: "completed",
5
+ summary: `Research prepared for ${input.questionId}.`,
6
+ markdown: [
7
+ "# Research Summary",
8
+ "",
9
+ `Question: ${input.questionId}`,
10
+ `Reason: ${input.reason ?? "not provided"}`,
11
+ `Run: ${input.runId}`,
12
+ "",
13
+ "This is a stub research summary produced by the runtime adapter."
14
+ ].join("\n"),
15
+ sources: []
16
+ };
17
+ }
18
+ }
19
+ function createResearchAdapter() {
20
+ return new StubResearchAdapter();
21
+ }
22
+ export {
23
+ StubResearchAdapter,
24
+ createResearchAdapter
25
+ };
@@ -0,0 +1,62 @@
1
+ import { execFile } from "node:child_process";
2
+ import { promisify } from "node:util";
3
+ import { getTreeseedAgentProviderSelections } from "@treeseed/core/deploy/runtime";
4
+ const execFileAsync = promisify(execFile);
5
+ class StubVerificationAdapter {
6
+ async runChecks(input) {
7
+ return {
8
+ status: "completed",
9
+ summary: input.commands.length ? `Stub verification completed for ${input.runId}.` : "No verification commands configured.",
10
+ stdout: input.commands.join("\n"),
11
+ stderr: ""
12
+ };
13
+ }
14
+ }
15
+ class LocalVerificationAdapter {
16
+ async runChecks(input) {
17
+ if (!input.commands.length) {
18
+ return {
19
+ status: "waiting",
20
+ summary: "No verification commands configured.",
21
+ stdout: "",
22
+ stderr: ""
23
+ };
24
+ }
25
+ const stdoutChunks = [];
26
+ const stderrChunks = [];
27
+ for (const command of input.commands) {
28
+ try {
29
+ const { stdout, stderr } = await execFileAsync("/bin/bash", ["-lc", command], {
30
+ env: process.env,
31
+ maxBuffer: 10 * 1024 * 1024
32
+ });
33
+ stdoutChunks.push(stdout);
34
+ stderrChunks.push(stderr);
35
+ } catch (error) {
36
+ return {
37
+ status: "failed",
38
+ summary: `Verification command failed: ${command}`,
39
+ stdout: stdoutChunks.join("\n"),
40
+ stderr: error && typeof error === "object" && "stderr" in error ? String(error.stderr ?? "") : String(error),
41
+ errorCategory: "execution_error"
42
+ };
43
+ }
44
+ }
45
+ return {
46
+ status: "completed",
47
+ summary: `Verification completed for ${input.commands.length} command(s).`,
48
+ stdout: stdoutChunks.join("\n"),
49
+ stderr: stderrChunks.join("\n")
50
+ };
51
+ }
52
+ }
53
+ function createVerificationAdapter() {
54
+ return String(
55
+ process.env.TREESEED_AGENT_VERIFICATION_PROVIDER ?? getTreeseedAgentProviderSelections().verification
56
+ ).toLowerCase() !== "local" ? new StubVerificationAdapter() : new LocalVerificationAdapter();
57
+ }
58
+ export {
59
+ LocalVerificationAdapter,
60
+ StubVerificationAdapter,
61
+ createVerificationAdapter
62
+ };
@@ -0,0 +1,5 @@
1
+ import { normalizeAgentCliOptions, buildCopilotAllowToolArgs } from "@treeseed/sdk/cli-tools";
2
+ export {
3
+ buildCopilotAllowToolArgs,
4
+ normalizeAgentCliOptions
5
+ };
@@ -0,0 +1,77 @@
1
+ function parseArgs(argv) {
2
+ const [, , command = "doctor", ...rest] = argv;
3
+ return {
4
+ command,
5
+ args: rest
6
+ };
7
+ }
8
+ function renderHelp() {
9
+ return [
10
+ "treeseed-agents <command>",
11
+ "",
12
+ "Commands:",
13
+ " doctor",
14
+ " run-agent <slug>",
15
+ " drain-messages",
16
+ " release-leases",
17
+ " replay-message <id>",
18
+ " start"
19
+ ].join("\n");
20
+ }
21
+ async function main() {
22
+ const { command, args } = parseArgs(process.argv);
23
+ if (command === "--help" || command === "-h" || command === "help") {
24
+ console.log(renderHelp());
25
+ return;
26
+ }
27
+ const [{ AgentKernel }, { AgentSdk }] = await Promise.all([
28
+ import("./kernel/agent-kernel.js"),
29
+ import("./sdk.js")
30
+ ]);
31
+ const repoRoot = process.cwd();
32
+ const sdk = AgentSdk.createLocal({
33
+ repoRoot,
34
+ databaseName: process.env.TREESEED_AGENT_D1_DATABASE ?? "karyon-docs-site-data",
35
+ persistTo: process.env.TREESEED_AGENT_D1_PERSIST_TO ?? void 0
36
+ });
37
+ const kernel = new AgentKernel(sdk, repoRoot);
38
+ if (command === "doctor") {
39
+ console.log(JSON.stringify({ ok: true, command, ...await kernel.doctor() }, null, 2));
40
+ return;
41
+ }
42
+ if (command === "run-agent") {
43
+ console.log(JSON.stringify({ ok: true, command, slug: args[0], result: await kernel.runAgent(args[0]) }, null, 2));
44
+ return;
45
+ }
46
+ if (command === "drain-messages") {
47
+ console.log(JSON.stringify({ ok: true, command, results: await kernel.drainMessages() }, null, 2));
48
+ return;
49
+ }
50
+ if (command === "release-leases") {
51
+ console.log(JSON.stringify({ ok: true, command, result: await kernel.releaseLeases() }, null, 2));
52
+ return;
53
+ }
54
+ if (command === "replay-message") {
55
+ console.log(JSON.stringify({ ok: true, command, result: await kernel.replayMessage(Number(args[0])) }, null, 2));
56
+ return;
57
+ }
58
+ if (command === "start") {
59
+ console.log(JSON.stringify({ ok: true, command, status: "starting" }, null, 2));
60
+ await kernel.start();
61
+ return;
62
+ }
63
+ throw new Error(`Unknown Treeseed command "${command}".`);
64
+ }
65
+ main().catch((error) => {
66
+ console.error(
67
+ JSON.stringify(
68
+ {
69
+ ok: false,
70
+ error: error instanceof Error ? error.message : String(error)
71
+ },
72
+ null,
73
+ 2
74
+ )
75
+ );
76
+ process.exit(1);
77
+ });
@@ -0,0 +1 @@
1
+ export * from "@treeseed/sdk/content-store";