@treeseed/agent 0.8.5
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/Dockerfile +7 -0
- package/README.md +198 -0
- package/dist/agent-runtime.d.ts +17 -0
- package/dist/agent-runtime.js +117 -0
- package/dist/agents/adapters/execution.d.ts +41 -0
- package/dist/agents/adapters/execution.js +73 -0
- package/dist/agents/adapters/mutations.d.ts +22 -0
- package/dist/agents/adapters/mutations.js +30 -0
- package/dist/agents/adapters/notification.d.ts +26 -0
- package/dist/agents/adapters/notification.js +46 -0
- package/dist/agents/adapters/repository.d.ts +28 -0
- package/dist/agents/adapters/repository.js +61 -0
- package/dist/agents/adapters/research.d.ts +26 -0
- package/dist/agents/adapters/research.js +59 -0
- package/dist/agents/adapters/verification.d.ts +36 -0
- package/dist/agents/adapters/verification.js +62 -0
- package/dist/agents/cli-tools.d.ts +1 -0
- package/dist/agents/cli-tools.js +5 -0
- package/dist/agents/cli.d.ts +15 -0
- package/dist/agents/cli.js +109 -0
- package/dist/agents/contracts/messages.d.ts +88 -0
- package/dist/agents/contracts/messages.js +138 -0
- package/dist/agents/contracts/run.d.ts +21 -0
- package/dist/agents/contracts/run.js +0 -0
- package/dist/agents/index.d.ts +1 -0
- package/dist/agents/index.js +5 -0
- package/dist/agents/kernel/agent-kernel.d.ts +63 -0
- package/dist/agents/kernel/agent-kernel.js +291 -0
- package/dist/agents/kernel/trigger-resolver.d.ts +19 -0
- package/dist/agents/kernel/trigger-resolver.js +157 -0
- package/dist/agents/registry-helper.d.ts +4 -0
- package/dist/agents/registry-helper.js +14 -0
- package/dist/agents/registry.d.ts +6 -0
- package/dist/agents/registry.js +98 -0
- package/dist/agents/runtime-types.d.ts +118 -0
- package/dist/agents/runtime-types.js +0 -0
- package/dist/agents/spec-loader.d.ts +18 -0
- package/dist/agents/spec-loader.js +54 -0
- package/dist/agents/spec-normalizer.d.ts +2 -0
- package/dist/agents/spec-normalizer.js +327 -0
- package/dist/agents/spec-types.d.ts +64 -0
- package/dist/agents/spec-types.js +0 -0
- package/dist/agents/testing/agents-smoke.d.ts +1 -0
- package/dist/agents/testing/agents-smoke.js +32 -0
- package/dist/agents/testing/e2e-harness.d.ts +44 -0
- package/dist/agents/testing/e2e-harness.js +503 -0
- package/dist/api/agent-routes.d.ts +13 -0
- package/dist/api/agent-routes.js +327 -0
- package/dist/api/app.d.ts +8 -0
- package/dist/api/app.js +444 -0
- package/dist/api/auth/d1-database.d.ts +3 -0
- package/dist/api/auth/d1-database.js +20 -0
- package/dist/api/auth/d1-provider.d.ts +79 -0
- package/dist/api/auth/d1-provider.js +92 -0
- package/dist/api/auth/d1-store.d.ts +114 -0
- package/dist/api/auth/d1-store.js +895 -0
- package/dist/api/auth/memory-provider.d.ts +77 -0
- package/dist/api/auth/memory-provider.js +249 -0
- package/dist/api/auth/rbac.d.ts +22 -0
- package/dist/api/auth/rbac.js +162 -0
- package/dist/api/auth/tokens.d.ts +18 -0
- package/dist/api/auth/tokens.js +56 -0
- package/dist/api/capabilities.d.ts +9 -0
- package/dist/api/capabilities.js +33 -0
- package/dist/api/config.d.ts +2 -0
- package/dist/api/config.js +77 -0
- package/dist/api/http.d.ts +28 -0
- package/dist/api/http.js +51 -0
- package/dist/api/index.d.ts +9 -0
- package/dist/api/index.js +20 -0
- package/dist/api/operations-routes.d.ts +11 -0
- package/dist/api/operations-routes.js +87 -0
- package/dist/api/operations.d.ts +3 -0
- package/dist/api/operations.js +26 -0
- package/dist/api/project-routes.d.ts +8 -0
- package/dist/api/project-routes.js +585 -0
- package/dist/api/providers.d.ts +2 -0
- package/dist/api/providers.js +62 -0
- package/dist/api/railway.d.ts +51 -0
- package/dist/api/railway.js +71 -0
- package/dist/api/sdk-dispatch.d.ts +5 -0
- package/dist/api/sdk-dispatch.js +13 -0
- package/dist/api/sdk-routes.d.ts +11 -0
- package/dist/api/sdk-routes.js +29 -0
- package/dist/api/server.d.ts +2 -0
- package/dist/api/server.js +10 -0
- package/dist/api/templates.d.ts +3 -0
- package/dist/api/templates.js +31 -0
- package/dist/api/types.d.ts +237 -0
- package/dist/api/types.js +0 -0
- package/dist/env.yaml +957 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +41 -0
- package/dist/scripts/assert-release-tag-version.d.ts +1 -0
- package/dist/scripts/assert-release-tag-version.js +20 -0
- package/dist/scripts/build-dist.d.ts +1 -0
- package/dist/scripts/build-dist.js +106 -0
- package/dist/scripts/package-tools.d.ts +1 -0
- package/dist/scripts/package-tools.js +7 -0
- package/dist/scripts/publish-package.d.ts +1 -0
- package/dist/scripts/publish-package.js +24 -0
- package/dist/scripts/release-verify.d.ts +1 -0
- package/dist/scripts/release-verify.js +152 -0
- package/dist/scripts/test-smoke.d.ts +1 -0
- package/dist/scripts/test-smoke.js +23 -0
- package/dist/scripts/treeseed-agent-api.d.ts +2 -0
- package/dist/scripts/treeseed-agent-api.js +25 -0
- package/dist/scripts/treeseed-agent-service.d.ts +2 -0
- package/dist/scripts/treeseed-agent-service.js +36 -0
- package/dist/scripts/treeseed-agents.d.ts +2 -0
- package/dist/scripts/treeseed-agents.js +13 -0
- package/dist/services/agents.d.ts +17 -0
- package/dist/services/agents.js +48 -0
- package/dist/services/common.d.ts +66 -0
- package/dist/services/common.js +212 -0
- package/dist/services/index.d.ts +6 -0
- package/dist/services/index.js +19 -0
- package/dist/services/manager.d.ts +333 -0
- package/dist/services/manager.js +1368 -0
- package/dist/services/remote-runner.d.ts +30 -0
- package/dist/services/remote-runner.js +230 -0
- package/dist/services/workday-content.d.ts +53 -0
- package/dist/services/workday-content.js +190 -0
- package/dist/services/workday-manager.d.ts +391 -0
- package/dist/services/workday-manager.js +163 -0
- package/dist/services/workday-report.d.ts +238 -0
- package/dist/services/workday-report.js +17 -0
- package/dist/services/workday-start.d.ts +238 -0
- package/dist/services/workday-start.js +17 -0
- package/dist/services/worker-capacity.d.ts +58 -0
- package/dist/services/worker-capacity.js +208 -0
- package/dist/services/worker-pool-scaler.d.ts +27 -0
- package/dist/services/worker-pool-scaler.js +127 -0
- package/dist/services/worker.d.ts +19 -0
- package/dist/services/worker.js +436 -0
- package/dist/templates/github/deploy-processing.workflow.yml +119 -0
- package/package.json +136 -0
- package/templates/github/deploy-processing.workflow.yml +119 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { AgentKernel } from './agents/kernel/agent-kernel.ts';
|
|
2
|
+
export { listTreeseedAgentCommands, renderTreeseedAgentHelp, runTreeseedAgentCli } from './agents/cli.ts';
|
|
3
|
+
export { resolveAgentHandler, listRegisteredAgentHandlers } from './agents/registry.ts';
|
|
4
|
+
export { resolveAgentRuntimeProviders } from './agent-runtime.ts';
|
|
5
|
+
export { createTreeseedApiApp, createTreeseedApiRouter, createTreeseedNodeServer, createRailwayTreeseedApiServer, resolveApiConfig, resolveApiRuntimeProviders, } from './api/index.ts';
|
|
6
|
+
export { createManagerApp } from './services/manager.ts';
|
|
7
|
+
export { runScheduledWorkdayManager } from './services/workday-manager.ts';
|
|
8
|
+
export { runWorkerCycle, startWorkerLoop } from './services/worker.ts';
|
|
9
|
+
export { runWorkdayStart } from './services/workday-start.ts';
|
|
10
|
+
export { runWorkdayReport } from './services/workday-report.ts';
|
|
11
|
+
export { parseAgentMessagePayload, AGENT_MESSAGE_TYPES } from './agents/contracts/messages.ts';
|
|
12
|
+
export type * from './agents/runtime-types.ts';
|
|
13
|
+
export type * from './agents/contracts/run.ts';
|
|
14
|
+
export type * from './api/types.ts';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { AgentKernel } from "./agents/kernel/agent-kernel.js";
|
|
2
|
+
import { listTreeseedAgentCommands, renderTreeseedAgentHelp, runTreeseedAgentCli } from "./agents/cli.js";
|
|
3
|
+
import { resolveAgentHandler, listRegisteredAgentHandlers } from "./agents/registry.js";
|
|
4
|
+
import { resolveAgentRuntimeProviders } from "./agent-runtime.js";
|
|
5
|
+
import {
|
|
6
|
+
createTreeseedApiApp,
|
|
7
|
+
createTreeseedApiRouter,
|
|
8
|
+
createTreeseedNodeServer,
|
|
9
|
+
createRailwayTreeseedApiServer,
|
|
10
|
+
resolveApiConfig,
|
|
11
|
+
resolveApiRuntimeProviders
|
|
12
|
+
} from "./api/index.js";
|
|
13
|
+
import { createManagerApp } from "./services/manager.js";
|
|
14
|
+
import { runScheduledWorkdayManager } from "./services/workday-manager.js";
|
|
15
|
+
import { runWorkerCycle, startWorkerLoop } from "./services/worker.js";
|
|
16
|
+
import { runWorkdayStart } from "./services/workday-start.js";
|
|
17
|
+
import { runWorkdayReport } from "./services/workday-report.js";
|
|
18
|
+
import { parseAgentMessagePayload, AGENT_MESSAGE_TYPES } from "./agents/contracts/messages.js";
|
|
19
|
+
export {
|
|
20
|
+
AGENT_MESSAGE_TYPES,
|
|
21
|
+
AgentKernel,
|
|
22
|
+
createManagerApp,
|
|
23
|
+
createRailwayTreeseedApiServer,
|
|
24
|
+
createTreeseedApiApp,
|
|
25
|
+
createTreeseedApiRouter,
|
|
26
|
+
createTreeseedNodeServer,
|
|
27
|
+
listRegisteredAgentHandlers,
|
|
28
|
+
listTreeseedAgentCommands,
|
|
29
|
+
parseAgentMessagePayload,
|
|
30
|
+
renderTreeseedAgentHelp,
|
|
31
|
+
resolveAgentHandler,
|
|
32
|
+
resolveAgentRuntimeProviders,
|
|
33
|
+
resolveApiConfig,
|
|
34
|
+
resolveApiRuntimeProviders,
|
|
35
|
+
runScheduledWorkdayManager,
|
|
36
|
+
runTreeseedAgentCli,
|
|
37
|
+
runWorkdayReport,
|
|
38
|
+
runWorkdayStart,
|
|
39
|
+
runWorkerCycle,
|
|
40
|
+
startWorkerLoop
|
|
41
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
const packageRoot = resolve(fileURLToPath(new URL('..', import.meta.url)));
|
|
5
|
+
const packageJson = JSON.parse(readFileSync(resolve(packageRoot, 'package.json'), 'utf8'));
|
|
6
|
+
const packageVersion = packageJson.version;
|
|
7
|
+
const tagName = process.argv[2] || process.env.GITHUB_REF_NAME;
|
|
8
|
+
if (!tagName) {
|
|
9
|
+
console.error('Release tag validation requires a tag name argument or GITHUB_REF_NAME.');
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
if (!/^\d+\.\d+\.\d+$/.test(tagName)) {
|
|
13
|
+
console.error(`Release tag "${tagName}" must be a plain semver tag like "${packageVersion}".`);
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
if (tagName !== packageVersion) {
|
|
17
|
+
console.error(`Release tag "${tagName}" does not match @treeseed/agent version "${packageVersion}".`);
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
console.log(`Release tag "${tagName}" matches @treeseed/agent version "${packageVersion}".`);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { copyFileSync, cpSync, existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync, chmodSync } from 'node:fs';
|
|
2
|
+
import { dirname, extname, join, relative, resolve } from 'node:path';
|
|
3
|
+
import { build } from 'esbuild';
|
|
4
|
+
import ts from 'typescript';
|
|
5
|
+
import { packageRoot } from './package-tools.js';
|
|
6
|
+
const srcRoot = resolve(packageRoot, 'src');
|
|
7
|
+
const scriptsRoot = resolve(packageRoot, 'scripts');
|
|
8
|
+
const templatesRoot = resolve(packageRoot, 'templates');
|
|
9
|
+
const distRoot = resolve(packageRoot, 'dist');
|
|
10
|
+
const COPY_EXTENSIONS = new Set(['.d.js', '.json', '.md', '.yaml', '.yml']);
|
|
11
|
+
function walkFiles(root) {
|
|
12
|
+
const files = [];
|
|
13
|
+
for (const entry of readdirSync(root, { withFileTypes: true })) {
|
|
14
|
+
const fullPath = join(root, entry.name);
|
|
15
|
+
if (entry.isDirectory())
|
|
16
|
+
files.push(...walkFiles(fullPath));
|
|
17
|
+
else
|
|
18
|
+
files.push(fullPath);
|
|
19
|
+
}
|
|
20
|
+
return files;
|
|
21
|
+
}
|
|
22
|
+
function ensureDir(filePath) {
|
|
23
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
24
|
+
}
|
|
25
|
+
function rewriteRuntimeSpecifiers(contents) {
|
|
26
|
+
return contents
|
|
27
|
+
.replace(/(['"`])(\.[^'"`\n]+)\.(mjs|ts)\1/g, '$1$2.js$1')
|
|
28
|
+
.replace(/(['"`])\.\.\/src\//g, '$1../');
|
|
29
|
+
}
|
|
30
|
+
async function compileModule(filePath, sourceRoot, outputRoot) {
|
|
31
|
+
const relativePath = relative(sourceRoot, filePath);
|
|
32
|
+
const outputFile = resolve(outputRoot, relativePath.replace(/\.(mjs|ts)$/u, '.js'));
|
|
33
|
+
ensureDir(outputFile);
|
|
34
|
+
await build({
|
|
35
|
+
entryPoints: [filePath],
|
|
36
|
+
outfile: outputFile,
|
|
37
|
+
platform: 'node',
|
|
38
|
+
format: 'esm',
|
|
39
|
+
bundle: false,
|
|
40
|
+
logLevel: 'silent',
|
|
41
|
+
});
|
|
42
|
+
const builtSource = readFileSync(outputFile, 'utf8');
|
|
43
|
+
writeFileSync(outputFile, rewriteRuntimeSpecifiers(builtSource), 'utf8');
|
|
44
|
+
}
|
|
45
|
+
function copyAsset(filePath, sourceRoot, outputRoot) {
|
|
46
|
+
const outputFile = resolve(outputRoot, relative(sourceRoot, filePath));
|
|
47
|
+
ensureDir(outputFile);
|
|
48
|
+
copyFileSync(filePath, outputFile);
|
|
49
|
+
if (outputFile.endsWith('.d.js')) {
|
|
50
|
+
writeFileSync(outputFile, rewriteRuntimeSpecifiers(readFileSync(outputFile, 'utf8')), 'utf8');
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
function transpileScript(filePath) {
|
|
54
|
+
const source = readFileSync(filePath, 'utf8');
|
|
55
|
+
const relativePath = relative(scriptsRoot, filePath);
|
|
56
|
+
const outputFile = resolve(distRoot, 'scripts', relativePath.replace(/\.(mjs|ts)$/u, '.js'));
|
|
57
|
+
const transformed = extname(filePath) === '.ts'
|
|
58
|
+
? ts.transpileModule(source, {
|
|
59
|
+
compilerOptions: { module: ts.ModuleKind.ESNext, target: ts.ScriptTarget.ES2022 },
|
|
60
|
+
}).outputText
|
|
61
|
+
: source;
|
|
62
|
+
ensureDir(outputFile);
|
|
63
|
+
writeFileSync(outputFile, rewriteRuntimeSpecifiers(transformed), 'utf8');
|
|
64
|
+
chmodSync(outputFile, 0o755);
|
|
65
|
+
}
|
|
66
|
+
function emitDeclarations() {
|
|
67
|
+
const configPath = ts.findConfigFile(packageRoot, ts.sys.fileExists, 'tsconfig.json');
|
|
68
|
+
if (!configPath)
|
|
69
|
+
throw new Error('Unable to locate tsconfig.json for declaration build.');
|
|
70
|
+
const configFile = ts.readConfigFile(configPath, ts.sys.readFile);
|
|
71
|
+
const parsed = ts.parseJsonConfigFileContent(configFile.config, ts.sys, packageRoot);
|
|
72
|
+
const program = ts.createProgram({
|
|
73
|
+
rootNames: parsed.fileNames,
|
|
74
|
+
options: { ...parsed.options, declaration: true, emitDeclarationOnly: true, declarationDir: distRoot, noEmit: false },
|
|
75
|
+
});
|
|
76
|
+
const result = program.emit();
|
|
77
|
+
if (result.emitSkipped)
|
|
78
|
+
throw new Error('Declaration build failed.');
|
|
79
|
+
}
|
|
80
|
+
rmSync(distRoot, { recursive: true, force: true });
|
|
81
|
+
for (const filePath of walkFiles(srcRoot)) {
|
|
82
|
+
const extension = extname(filePath);
|
|
83
|
+
if (extension === '.ts')
|
|
84
|
+
await compileModule(filePath, srcRoot, distRoot);
|
|
85
|
+
else if (COPY_EXTENSIONS.has(extension))
|
|
86
|
+
copyAsset(filePath, srcRoot, distRoot);
|
|
87
|
+
}
|
|
88
|
+
for (const filePath of walkFiles(scriptsRoot)) {
|
|
89
|
+
const extension = extname(filePath);
|
|
90
|
+
if (extension === '.ts' || extension === '.ts')
|
|
91
|
+
transpileScript(filePath);
|
|
92
|
+
}
|
|
93
|
+
emitDeclarations();
|
|
94
|
+
if (existsSync(resolve(distRoot, 'src'))) {
|
|
95
|
+
cpSync(resolve(distRoot, 'src'), distRoot, { recursive: true });
|
|
96
|
+
rmSync(resolve(distRoot, 'src'), { recursive: true, force: true });
|
|
97
|
+
}
|
|
98
|
+
if (existsSync(resolve(packageRoot, 'README.md'))) {
|
|
99
|
+
copyFileSync(resolve(packageRoot, 'README.md'), resolve(distRoot, '..', 'README.md'));
|
|
100
|
+
}
|
|
101
|
+
if (existsSync(resolve(packageRoot, 'Dockerfile'))) {
|
|
102
|
+
copyFileSync(resolve(packageRoot, 'Dockerfile'), resolve(distRoot, '..', 'Dockerfile'));
|
|
103
|
+
}
|
|
104
|
+
if (existsSync(templatesRoot)) {
|
|
105
|
+
cpSync(templatesRoot, resolve(distRoot, 'templates'), { recursive: true });
|
|
106
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const packageRoot: string;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { dirname, resolve } from 'node:path';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
const scriptRoot = dirname(fileURLToPath(import.meta.url));
|
|
4
|
+
const packageCandidate = resolve(scriptRoot, '..');
|
|
5
|
+
export const packageRoot = packageCandidate.endsWith('/dist')
|
|
6
|
+
? resolve(packageCandidate, '..')
|
|
7
|
+
: packageCandidate;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { resolve } from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
const packageRoot = resolve(fileURLToPath(new URL('..', import.meta.url)));
|
|
5
|
+
const extraArgs = process.argv.slice(2);
|
|
6
|
+
const tagName = process.env.GITHUB_REF_NAME;
|
|
7
|
+
if (tagName && !/^\d+\.\d+\.\d+$/.test(tagName)) {
|
|
8
|
+
console.error(`Refusing to publish @treeseed/agent from non-stable tag "${tagName}".`);
|
|
9
|
+
process.exit(1);
|
|
10
|
+
}
|
|
11
|
+
const npmArgs = ['publish', '.', '--access', 'public'];
|
|
12
|
+
if (process.env.GITHUB_ACTIONS === 'true')
|
|
13
|
+
npmArgs.push('--provenance');
|
|
14
|
+
npmArgs.push(...extraArgs);
|
|
15
|
+
const result = spawnSync('npm', npmArgs, {
|
|
16
|
+
cwd: packageRoot,
|
|
17
|
+
stdio: 'inherit',
|
|
18
|
+
env: process.env,
|
|
19
|
+
});
|
|
20
|
+
if (result.error) {
|
|
21
|
+
console.error(result.error.message);
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
process.exit(result.status ?? 1);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { cpSync, mkdirSync, readFileSync, readdirSync, rmSync, symlinkSync, writeFileSync, existsSync } from 'node:fs';
|
|
2
|
+
import { mkdtempSync } from 'node:fs';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
4
|
+
import { dirname, extname, join, resolve } from 'node:path';
|
|
5
|
+
import { spawnSync } from 'node:child_process';
|
|
6
|
+
import { createRequire } from 'node:module';
|
|
7
|
+
import { packageRoot } from './package-tools.js';
|
|
8
|
+
const require = createRequire(import.meta.url);
|
|
9
|
+
const sdkPackageRoot = resolve(dirname(require.resolve('@treeseed/sdk')), '..');
|
|
10
|
+
const npmCacheDir = resolve(tmpdir(), 'treeseed-npm-cache');
|
|
11
|
+
const textExtensions = new Set(['.js', '.ts', '.mjs', '.cjs', '.d.js', '.json', '.md']);
|
|
12
|
+
const forbiddenPatterns = [
|
|
13
|
+
/['"`]file:[^'"`\n]+['"`]/,
|
|
14
|
+
/['"`]workspace:[^'"`\n]+['"`]/,
|
|
15
|
+
/['"`](?:\.\.\/|\.\/)[^'"`\n]*src\/[^'"`\n]*\.(?:[cm]?js|ts|tsx|json|astro|css)['"`]/,
|
|
16
|
+
/['"`][^'"`\n]*\/packages\/[^'"`\n]*\/src\/[^'"`\n]*['"`]/,
|
|
17
|
+
];
|
|
18
|
+
function run(command, args, cwd = packageRoot, capture = false) {
|
|
19
|
+
const result = spawnSync(command, args, {
|
|
20
|
+
cwd,
|
|
21
|
+
stdio: capture ? 'pipe' : 'inherit',
|
|
22
|
+
encoding: 'utf8',
|
|
23
|
+
env: {
|
|
24
|
+
...process.env,
|
|
25
|
+
npm_config_cache: npmCacheDir,
|
|
26
|
+
NPM_CONFIG_CACHE: npmCacheDir,
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
if (result.status !== 0) {
|
|
30
|
+
throw new Error(result.stderr?.trim() || result.stdout?.trim() || `${command} ${args.join(' ')} failed`);
|
|
31
|
+
}
|
|
32
|
+
return (result.stdout ?? '').trim();
|
|
33
|
+
}
|
|
34
|
+
function walkFiles(root) {
|
|
35
|
+
const files = [];
|
|
36
|
+
for (const entry of readdirSync(root, { withFileTypes: true })) {
|
|
37
|
+
const fullPath = join(root, entry.name);
|
|
38
|
+
if (entry.isDirectory()) {
|
|
39
|
+
files.push(...walkFiles(fullPath));
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
files.push(fullPath);
|
|
43
|
+
}
|
|
44
|
+
return files;
|
|
45
|
+
}
|
|
46
|
+
function scanDirectory(root) {
|
|
47
|
+
for (const filePath of walkFiles(root)) {
|
|
48
|
+
if (!textExtensions.has(extname(filePath)))
|
|
49
|
+
continue;
|
|
50
|
+
const source = readFileSync(filePath, 'utf8');
|
|
51
|
+
for (const pattern of forbiddenPatterns) {
|
|
52
|
+
if (pattern.test(source)) {
|
|
53
|
+
throw new Error(`${filePath} contains forbidden publish reference matching ${pattern}.`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function resolveNodeModulesRoot() {
|
|
59
|
+
let lastCandidate = null;
|
|
60
|
+
let current = packageRoot;
|
|
61
|
+
while (true) {
|
|
62
|
+
const candidate = resolve(current, 'node_modules');
|
|
63
|
+
try {
|
|
64
|
+
readdirSync(candidate);
|
|
65
|
+
lastCandidate = candidate;
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
}
|
|
69
|
+
const parent = resolve(current, '..');
|
|
70
|
+
if (parent === current)
|
|
71
|
+
break;
|
|
72
|
+
current = parent;
|
|
73
|
+
}
|
|
74
|
+
if (lastCandidate) {
|
|
75
|
+
return lastCandidate;
|
|
76
|
+
}
|
|
77
|
+
throw new Error(`Unable to locate node_modules for ${packageRoot}.`);
|
|
78
|
+
}
|
|
79
|
+
function mirrorDependencies(tempRoot) {
|
|
80
|
+
const sharedNodeModules = resolveNodeModulesRoot();
|
|
81
|
+
for (const entry of readdirSync(sharedNodeModules, { withFileTypes: true })) {
|
|
82
|
+
if (entry.name === '.bin' || entry.name === '@treeseed') {
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
const targetPath = resolve(tempRoot, 'node_modules', entry.name);
|
|
86
|
+
mkdirSync(dirname(targetPath), { recursive: true });
|
|
87
|
+
symlinkSync(resolve(sharedNodeModules, entry.name), targetPath, 'dir');
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function pack(root, fallbackName) {
|
|
91
|
+
const output = run('npm', ['pack', '--ignore-scripts', '--cache', npmCacheDir], root, true);
|
|
92
|
+
const filename = output
|
|
93
|
+
.split('\n')
|
|
94
|
+
.map((line) => line.trim())
|
|
95
|
+
.filter(Boolean)
|
|
96
|
+
.at(-1)
|
|
97
|
+
?? readdirSync(root, { withFileTypes: true })
|
|
98
|
+
.filter((entry) => entry.isFile() && entry.name.endsWith('.tgz'))
|
|
99
|
+
.map((entry) => entry.name)
|
|
100
|
+
.sort((left, right) => left.localeCompare(right, undefined, { numeric: true, sensitivity: 'base' }))
|
|
101
|
+
.at(-1)
|
|
102
|
+
?? fallbackName;
|
|
103
|
+
return resolve(root, filename);
|
|
104
|
+
}
|
|
105
|
+
function installPackagedPackage(extractRoot, tempRoot, tarballPath, folderName) {
|
|
106
|
+
mkdirSync(resolve(tempRoot, 'node_modules', '@treeseed'), { recursive: true });
|
|
107
|
+
run('tar', ['-xzf', tarballPath, '-C', extractRoot]);
|
|
108
|
+
run('cp', ['-R', resolve(extractRoot, 'package'), resolve(tempRoot, 'node_modules', '@treeseed', folderName)]);
|
|
109
|
+
rmSync(resolve(extractRoot, 'package'), { recursive: true, force: true });
|
|
110
|
+
}
|
|
111
|
+
function isInstalledDependencyPackage(root) {
|
|
112
|
+
return root.includes(`${process.platform === 'win32' ? '\\' : '/'}node_modules${process.platform === 'win32' ? '\\' : '/'}`);
|
|
113
|
+
}
|
|
114
|
+
function installDependencyPackage(root, extractRoot, tempRoot, folderName, fallbackName) {
|
|
115
|
+
if (isInstalledDependencyPackage(root) && existsSync(resolve(root, 'dist')) && existsSync(resolve(root, 'package.json'))) {
|
|
116
|
+
const targetRoot = resolve(tempRoot, 'node_modules', '@treeseed', folderName);
|
|
117
|
+
mkdirSync(resolve(tempRoot, 'node_modules', '@treeseed'), { recursive: true });
|
|
118
|
+
cpSync(root, targetRoot, {
|
|
119
|
+
recursive: true,
|
|
120
|
+
filter(source) {
|
|
121
|
+
const relativePath = source.slice(root.length).replace(/^[/\\]/, '');
|
|
122
|
+
if (!relativePath) {
|
|
123
|
+
return true;
|
|
124
|
+
}
|
|
125
|
+
return !(relativePath === 'node_modules'
|
|
126
|
+
|| relativePath.startsWith(`node_modules${process.platform === 'win32' ? '\\' : '/'}`));
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const tarballPath = pack(root, fallbackName);
|
|
132
|
+
installPackagedPackage(extractRoot, tempRoot, tarballPath, folderName);
|
|
133
|
+
}
|
|
134
|
+
run('npm', ['run', 'lint']);
|
|
135
|
+
scanDirectory(resolve(packageRoot, 'dist'));
|
|
136
|
+
run('npm', ['run', 'test:smoke']);
|
|
137
|
+
const stageRoot = mkdtempSync(join(tmpdir(), 'treeseed-agent-release-'));
|
|
138
|
+
const extractRoot = resolve(stageRoot, 'extract');
|
|
139
|
+
const installRoot = resolve(stageRoot, 'install');
|
|
140
|
+
try {
|
|
141
|
+
mkdirSync(extractRoot, { recursive: true });
|
|
142
|
+
const agentTarball = pack(packageRoot, 'treeseed-agent.tgz');
|
|
143
|
+
installDependencyPackage(sdkPackageRoot, extractRoot, installRoot, 'sdk', 'treeseed-sdk.tgz');
|
|
144
|
+
installPackagedPackage(extractRoot, installRoot, agentTarball, 'agent');
|
|
145
|
+
mirrorDependencies(installRoot);
|
|
146
|
+
writeFileSync(resolve(installRoot, 'package.json'), `${JSON.stringify({ name: 'treeseed-agent-smoke', private: true, type: 'module' }, null, 2)}\n`, 'utf8');
|
|
147
|
+
run(process.execPath, ['node_modules/@treeseed/agent/dist/scripts/treeseed-agents.js', '--help'], installRoot);
|
|
148
|
+
console.log('Agent packed-install bin smoke passed.');
|
|
149
|
+
}
|
|
150
|
+
finally {
|
|
151
|
+
rmSync(stageRoot, { recursive: true, force: true });
|
|
152
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { createAgentTestRuntime } from '../agents/testing/e2e-harness.js';
|
|
2
|
+
const runtime = await createAgentTestRuntime({
|
|
3
|
+
executionMode: 'stub',
|
|
4
|
+
databaseMode: 'memory',
|
|
5
|
+
});
|
|
6
|
+
try {
|
|
7
|
+
await runtime.seedObjectives([{ slug: 'release-smoke-objective' }]);
|
|
8
|
+
await runtime.seedQuestions([
|
|
9
|
+
{
|
|
10
|
+
slug: 'release-smoke-question',
|
|
11
|
+
relatedObjectives: ['release-smoke-objective'],
|
|
12
|
+
},
|
|
13
|
+
]);
|
|
14
|
+
await runtime.runAgent('planner-agent');
|
|
15
|
+
const runs = await runtime.readRunLogs();
|
|
16
|
+
if (runs.length === 0) {
|
|
17
|
+
throw new Error('Agent smoke did not produce any run logs.');
|
|
18
|
+
}
|
|
19
|
+
console.log(`Agent smoke passed with ${runs.length} run log(s).`);
|
|
20
|
+
}
|
|
21
|
+
finally {
|
|
22
|
+
await runtime.cleanup();
|
|
23
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawn } from 'node:child_process';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
const apiServerPath = fileURLToPath(new URL('../api/server.js', import.meta.url));
|
|
5
|
+
const command = process.argv[2] ?? 'start';
|
|
6
|
+
const forwardedArgs = command === 'start' || command === 'dev' ? process.argv.slice(3) : process.argv.slice(2);
|
|
7
|
+
if (command === '--help' || command === '-h' || command === 'help') {
|
|
8
|
+
process.stdout.write([
|
|
9
|
+
'treeseed-agent-api <command>',
|
|
10
|
+
'',
|
|
11
|
+
'Commands:',
|
|
12
|
+
' start Start the Treeseed agent API server',
|
|
13
|
+
' dev Start the Treeseed agent API server for local development',
|
|
14
|
+
'',
|
|
15
|
+
].join('\n'));
|
|
16
|
+
process.exit(0);
|
|
17
|
+
}
|
|
18
|
+
const child = spawn(process.execPath, [apiServerPath, ...forwardedArgs], {
|
|
19
|
+
cwd: process.cwd(),
|
|
20
|
+
stdio: 'inherit',
|
|
21
|
+
env: process.env,
|
|
22
|
+
});
|
|
23
|
+
child.on('exit', (code) => {
|
|
24
|
+
process.exit(code ?? 1);
|
|
25
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawn } from 'node:child_process';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
const services = new Map([
|
|
5
|
+
['manager', '../services/manager.js'],
|
|
6
|
+
['worker', '../services/worker.js'],
|
|
7
|
+
['workday-manager', '../services/workday-manager.js'],
|
|
8
|
+
['workday-start', '../services/workday-start.js'],
|
|
9
|
+
['workday-report', '../services/workday-report.js'],
|
|
10
|
+
['remote-runner', '../services/remote-runner.js'],
|
|
11
|
+
['agents', '../services/agents.js'],
|
|
12
|
+
]);
|
|
13
|
+
const command = process.argv[2] ?? 'help';
|
|
14
|
+
if (command === '--help' || command === '-h' || command === 'help') {
|
|
15
|
+
process.stdout.write([
|
|
16
|
+
'treeseed-agent-service <service>',
|
|
17
|
+
'',
|
|
18
|
+
'Services:',
|
|
19
|
+
...services.keys(),
|
|
20
|
+
'',
|
|
21
|
+
].join('\n'));
|
|
22
|
+
process.exit(0);
|
|
23
|
+
}
|
|
24
|
+
const servicePath = services.get(command);
|
|
25
|
+
if (!servicePath) {
|
|
26
|
+
process.stderr.write(`Unknown Treeseed agent service "${command}".\n`);
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
const child = spawn(process.execPath, [fileURLToPath(new URL(servicePath, import.meta.url)), ...process.argv.slice(3)], {
|
|
30
|
+
cwd: process.cwd(),
|
|
31
|
+
stdio: 'inherit',
|
|
32
|
+
env: process.env,
|
|
33
|
+
});
|
|
34
|
+
child.on('exit', (code) => {
|
|
35
|
+
process.exit(code ?? 1);
|
|
36
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawn } from 'node:child_process';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
const packageRoot = fileURLToPath(new URL('..', import.meta.url));
|
|
5
|
+
const cliScriptPath = fileURLToPath(new URL('../agents/cli.js', import.meta.url));
|
|
6
|
+
const child = spawn(process.execPath, [cliScriptPath, ...process.argv.slice(2)], {
|
|
7
|
+
cwd: packageRoot,
|
|
8
|
+
stdio: 'inherit',
|
|
9
|
+
env: process.env,
|
|
10
|
+
});
|
|
11
|
+
child.on('exit', (code) => {
|
|
12
|
+
process.exit(code ?? 1);
|
|
13
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
export declare function resolveAgentsServiceConfig(): {
|
|
3
|
+
serviceName: string;
|
|
4
|
+
pollIntervalMs: number;
|
|
5
|
+
};
|
|
6
|
+
export declare function runAgentsCycle(): Promise<{
|
|
7
|
+
ok: boolean;
|
|
8
|
+
processed: number;
|
|
9
|
+
results: {
|
|
10
|
+
slug: string;
|
|
11
|
+
result: import("../index.ts").AgentExecutionResult | {
|
|
12
|
+
status: string;
|
|
13
|
+
summary: string;
|
|
14
|
+
};
|
|
15
|
+
}[];
|
|
16
|
+
}>;
|
|
17
|
+
export declare function startAgentsLoop(): Promise<void>;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { AgentKernel } from "../agents/kernel/agent-kernel.js";
|
|
4
|
+
import { createServiceSdk, resolveServiceRepoRoot } from "./common.js";
|
|
5
|
+
function integerFromEnv(name, fallback) {
|
|
6
|
+
const value = process.env[name];
|
|
7
|
+
if (!value) return fallback;
|
|
8
|
+
const parsed = Number.parseInt(value, 10);
|
|
9
|
+
return Number.isFinite(parsed) ? parsed : fallback;
|
|
10
|
+
}
|
|
11
|
+
function resolveAgentsServiceConfig() {
|
|
12
|
+
return {
|
|
13
|
+
serviceName: process.env.TREESEED_AGENTS_SERVICE_NAME?.trim() || "agents",
|
|
14
|
+
pollIntervalMs: integerFromEnv("TREESEED_AGENTS_POLL_INTERVAL_MS", 3e4)
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
async function runAgentsCycle() {
|
|
18
|
+
const sdk = createServiceSdk();
|
|
19
|
+
const kernel = new AgentKernel(sdk, resolveServiceRepoRoot());
|
|
20
|
+
const results = await kernel.runCycle();
|
|
21
|
+
return {
|
|
22
|
+
ok: true,
|
|
23
|
+
processed: results.length,
|
|
24
|
+
results
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
async function startAgentsLoop() {
|
|
28
|
+
const config = resolveAgentsServiceConfig();
|
|
29
|
+
for (; ; ) {
|
|
30
|
+
try {
|
|
31
|
+
await runAgentsCycle();
|
|
32
|
+
} catch (error) {
|
|
33
|
+
process.stderr.write(`${error instanceof Error ? error.message : String(error)}
|
|
34
|
+
`);
|
|
35
|
+
}
|
|
36
|
+
await new Promise((resolve) => setTimeout(resolve, config.pollIntervalMs));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const currentFile = fileURLToPath(import.meta.url);
|
|
40
|
+
const entryFile = process.argv[1] ?? "";
|
|
41
|
+
if (entryFile === currentFile) {
|
|
42
|
+
await startAgentsLoop();
|
|
43
|
+
}
|
|
44
|
+
export {
|
|
45
|
+
resolveAgentsServiceConfig,
|
|
46
|
+
runAgentsCycle,
|
|
47
|
+
startAgentsLoop
|
|
48
|
+
};
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { AgentSdk } from '@treeseed/sdk';
|
|
2
|
+
import { CloudflareQueuePullClient } from '@treeseed/sdk/remote';
|
|
3
|
+
import type { SdkQueueMessageEnvelope } from '@treeseed/sdk';
|
|
4
|
+
export declare function resolveServiceRepoRoot(): string;
|
|
5
|
+
export declare function createServiceSdk(): AgentSdk;
|
|
6
|
+
export declare function createQueueClient(): CloudflareQueuePullClient | null;
|
|
7
|
+
export declare function createQueuePushClient(): {
|
|
8
|
+
enqueue(request: {
|
|
9
|
+
message: SdkQueueMessageEnvelope;
|
|
10
|
+
delaySeconds?: number;
|
|
11
|
+
}): Promise<void>;
|
|
12
|
+
} | null;
|
|
13
|
+
export declare function queueEnvelopeForTask(task: Record<string, unknown>): SdkQueueMessageEnvelope;
|
|
14
|
+
export declare function enqueueTaskFromSdk(sdk: AgentSdk, request: {
|
|
15
|
+
taskId: string;
|
|
16
|
+
queueName?: string;
|
|
17
|
+
deliveryDelaySeconds?: number;
|
|
18
|
+
actor?: string;
|
|
19
|
+
}): Promise<{
|
|
20
|
+
ok: boolean;
|
|
21
|
+
taskId: string;
|
|
22
|
+
queued: boolean;
|
|
23
|
+
}>;
|
|
24
|
+
export declare function buildTaskContext(sdk: AgentSdk, taskId: string): Promise<{
|
|
25
|
+
agent: Record<string, unknown> | import("@treeseed/sdk").SdkContentEntry | null;
|
|
26
|
+
task: import("@treeseed/sdk").SdkTaskEntity | null;
|
|
27
|
+
workDay: import("@treeseed/sdk").SdkWorkDayEntity | null;
|
|
28
|
+
graph: Record<string, unknown> | null;
|
|
29
|
+
}>;
|
|
30
|
+
export declare function seedRootTasks(sdk: AgentSdk, workDayId: string): Promise<import("@treeseed/sdk").SdkJsonEnvelope<import("@treeseed/sdk").SdkTaskEntity | null>[]>;
|
|
31
|
+
export declare function seedGraphRefreshTask(sdk: AgentSdk, request: {
|
|
32
|
+
workDayId: string;
|
|
33
|
+
projectId: string;
|
|
34
|
+
repositoryId?: string | null;
|
|
35
|
+
actor?: string;
|
|
36
|
+
}): Promise<import("@treeseed/sdk").SdkTaskEntity | null>;
|
|
37
|
+
export declare function startAndSeedWorkday(sdk: AgentSdk, request: {
|
|
38
|
+
id?: string;
|
|
39
|
+
projectId: string;
|
|
40
|
+
capacityBudget: number;
|
|
41
|
+
actor?: string;
|
|
42
|
+
}): Promise<{
|
|
43
|
+
ok: boolean;
|
|
44
|
+
workDay: import("@treeseed/sdk").SdkWorkDayEntity | null;
|
|
45
|
+
seededTasks: (import("@treeseed/sdk").SdkTaskEntity | null)[];
|
|
46
|
+
}>;
|
|
47
|
+
export declare function resolveManagerConfig(): {
|
|
48
|
+
host: string;
|
|
49
|
+
port: number;
|
|
50
|
+
projectId: string;
|
|
51
|
+
defaultCapacityBudget: number;
|
|
52
|
+
};
|
|
53
|
+
export declare function resolveWorkerConfig(): {
|
|
54
|
+
workerId: string;
|
|
55
|
+
batchSize: number;
|
|
56
|
+
maxLocalWorkers: number;
|
|
57
|
+
runnerServiceName: string;
|
|
58
|
+
volumeRoot: string;
|
|
59
|
+
volumeIdentity: string;
|
|
60
|
+
projectId: string;
|
|
61
|
+
environment: string;
|
|
62
|
+
visibilityTimeoutMs: number;
|
|
63
|
+
pollIntervalMs: number;
|
|
64
|
+
idleExitMs: number;
|
|
65
|
+
leaseSeconds: number;
|
|
66
|
+
};
|