codebase-onboarder 0.7.0 → 1.0.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.
Files changed (128) hide show
  1. package/README.md +115 -12
  2. package/bin/onboarder.js +0 -0
  3. package/cli/agent/command.d.ts +71 -0
  4. package/cli/agent/command.js +177 -0
  5. package/cli/agent/command.js.map +1 -0
  6. package/cli/agent/config.d.ts +31 -0
  7. package/cli/agent/config.js +98 -0
  8. package/cli/agent/config.js.map +1 -0
  9. package/cli/agent/contracts.d.ts +77 -0
  10. package/cli/agent/contracts.js +2 -0
  11. package/cli/agent/contracts.js.map +1 -0
  12. package/cli/agent/files.d.ts +19 -0
  13. package/cli/agent/files.js +109 -0
  14. package/cli/agent/files.js.map +1 -0
  15. package/cli/agent/gitSource.d.ts +18 -0
  16. package/cli/agent/gitSource.js +69 -0
  17. package/cli/agent/gitSource.js.map +1 -0
  18. package/cli/agent/github.d.ts +21 -0
  19. package/cli/agent/github.js +94 -0
  20. package/cli/agent/github.js.map +1 -0
  21. package/cli/agent/mcp.d.ts +15 -0
  22. package/cli/agent/mcp.js +78 -0
  23. package/cli/agent/mcp.js.map +1 -0
  24. package/cli/agent/process.d.ts +18 -0
  25. package/cli/agent/process.js +118 -0
  26. package/cli/agent/process.js.map +1 -0
  27. package/cli/agent/protocol.d.ts +3 -0
  28. package/cli/agent/protocol.js +26 -0
  29. package/cli/agent/protocol.js.map +1 -0
  30. package/cli/agent/runner.d.ts +34 -0
  31. package/cli/agent/runner.js +152 -0
  32. package/cli/agent/runner.js.map +1 -0
  33. package/cli/agent/stdio.d.ts +1 -0
  34. package/cli/agent/stdio.js +62 -0
  35. package/cli/agent/stdio.js.map +1 -0
  36. package/cli/agent/tools.d.ts +7 -0
  37. package/cli/agent/tools.js +201 -0
  38. package/cli/agent/tools.js.map +1 -0
  39. package/cli/chat/app.d.ts +16 -0
  40. package/cli/chat/app.js +345 -0
  41. package/cli/chat/app.js.map +1 -0
  42. package/cli/chat/commands.d.ts +11 -0
  43. package/cli/chat/commands.js +120 -0
  44. package/cli/chat/commands.js.map +1 -0
  45. package/cli/chat/composer.d.ts +75 -0
  46. package/cli/chat/composer.js +467 -0
  47. package/cli/chat/composer.js.map +1 -0
  48. package/cli/chat/controller.d.ts +60 -0
  49. package/cli/chat/controller.js +393 -0
  50. package/cli/chat/controller.js.map +1 -0
  51. package/cli/chat/logo.d.ts +3 -0
  52. package/cli/chat/logo.js +14 -0
  53. package/cli/chat/logo.js.map +1 -0
  54. package/cli/chat/models.d.ts +18 -0
  55. package/cli/chat/models.js +88 -0
  56. package/cli/chat/models.js.map +1 -0
  57. package/cli/chat/profile.d.ts +5 -0
  58. package/cli/chat/profile.js +98 -0
  59. package/cli/chat/profile.js.map +1 -0
  60. package/cli/chat/render.d.ts +40 -0
  61. package/cli/chat/render.js +259 -0
  62. package/cli/chat/render.js.map +1 -0
  63. package/cli/chat/screen.d.ts +26 -0
  64. package/cli/chat/screen.js +117 -0
  65. package/cli/chat/screen.js.map +1 -0
  66. package/cli/chat/source.d.ts +29 -0
  67. package/cli/chat/source.js +116 -0
  68. package/cli/chat/source.js.map +1 -0
  69. package/cli/chat/store.d.ts +43 -0
  70. package/cli/chat/store.js +94 -0
  71. package/cli/chat/store.js.map +1 -0
  72. package/cli/chat/text.d.ts +4 -0
  73. package/cli/chat/text.js +27 -0
  74. package/cli/chat/text.js.map +1 -0
  75. package/cli/explorer/app.d.ts +1 -0
  76. package/cli/explorer/app.js +20 -1
  77. package/cli/explorer/app.js.map +1 -1
  78. package/cli/explorer/commands.js +5 -0
  79. package/cli/explorer/commands.js.map +1 -1
  80. package/cli/main.js +47 -13
  81. package/cli/main.js.map +1 -1
  82. package/docs/HERMES_RESEARCH.md +51 -0
  83. package/package.json +2 -1
  84. package/public/app.js +98 -24
  85. package/public/app.js.map +1 -1
  86. package/public/assets/onboarder-mark.svg +11 -0
  87. package/public/browser.d.ts +3 -0
  88. package/public/browser.js.map +1 -1
  89. package/public/index.html +24 -7
  90. package/public/js/about.js +2 -2
  91. package/public/js/about.js.map +1 -1
  92. package/public/js/aiDraft.d.ts +1 -0
  93. package/public/js/aiDraft.js +66 -17
  94. package/public/js/aiDraft.js.map +1 -1
  95. package/public/js/api.d.ts +8 -5
  96. package/public/js/api.js +45 -22
  97. package/public/js/api.js.map +1 -1
  98. package/public/js/deepAnalysisView.js +2 -2
  99. package/public/js/deepAnalysisView.js.map +1 -1
  100. package/public/js/diagramPane.d.ts +1 -0
  101. package/public/js/diagramPane.js +5 -0
  102. package/public/js/diagramPane.js.map +1 -1
  103. package/public/js/docsView.js +6 -6
  104. package/public/js/docsView.js.map +1 -1
  105. package/public/js/dom.d.ts +8 -0
  106. package/public/js/dom.js.map +1 -1
  107. package/public/js/llm.d.ts +3 -1
  108. package/public/js/llm.js +15 -8
  109. package/public/js/llm.js.map +1 -1
  110. package/public/js/repoFiles.js +1 -1
  111. package/public/js/repoFiles.js.map +1 -1
  112. package/public/js/reviewView.js +1 -1
  113. package/public/js/reviewView.js.map +1 -1
  114. package/public/styles.css +25 -0
  115. package/server/gitDiff.d.ts +1 -1
  116. package/server/hermesChat.d.ts +13 -0
  117. package/server/hermesChat.js +145 -0
  118. package/server/hermesChat.js.map +1 -0
  119. package/server/http.d.ts +5 -4
  120. package/server/http.js +0 -4
  121. package/server/http.js.map +1 -1
  122. package/server/mcp/server.d.ts +1 -1
  123. package/server/mcp/server.js +2 -2
  124. package/server/mcp/server.js.map +1 -1
  125. package/server/router.js +7 -3
  126. package/server/router.js.map +1 -1
  127. package/shared/diagram/aiMermaid.js +16 -13
  128. package/shared/diagram/aiMermaid.js.map +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stdio.js","sourceRoot":"","sources":["../../src/cli/agent/stdio.ts"],"names":[],"mappings":"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","sourcesContent":["import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport { serveMcp } from '../../server/mcp/server.js';\nimport { createAgentDispatcher } from './mcp.js';\nimport { AGENT_MODES, type RunManifest } from './contracts.js';\nimport { redact, runProcess } from './process.js';\n\nconst write = process.stdout.write.bind(process.stdout);\nprocess.stdout.write = function (chunk: string | Uint8Array, encoding?: BufferEncoding | ((err?: Error) => void), callback?: (err?: Error) => void) {\n process.stderr.write(chunk);\n if (typeof encoding === 'function') encoding(); else callback?.();\n return true;\n};\ntry {\n const file = process.env.ONBOARDER_AGENT_RUN;\n if (!file || !path.isAbsolute(file)) throw new Error('Start this MCP server through onboarder agent.');\n const stat = await fs.stat(file); if (stat.size > 64000) throw new Error('Task manifest is too large.');\n const manifest = JSON.parse(await fs.readFile(file, 'utf8')) as RunManifest;\n if (manifest.schemaVersion !== 1 || !AGENT_MODES.includes(manifest.mode) || !manifest.permissions || typeof manifest.task !== 'string') throw new Error('Invalid task manifest.');\n for (const root of [manifest.root, manifest.sourceRoot]) if (!path.isAbsolute(root) || await fs.realpath(root) !== root) throw new Error('Task roots must be canonical directories.');\n if (manifest.auditFile !== path.join(path.dirname(file), 'audit.jsonl')) throw new Error('Invalid task audit path.');\n if (manifest.permissions.files) {\n if (!['implement', 'pr'].includes(manifest.mode) || manifest.root === manifest.sourceRoot || !/^codex\\/agent-[\\w-]+$/.test(manifest.branch || '')) throw new Error('Invalid writable workspace.');\n const branch = await runProcess('git', ['-C', manifest.root, 'branch', '--show-current'], { timeoutMs: 10_000, detached: false });\n if (branch.code || branch.stdout.trim() !== manifest.branch) throw new Error('Workspace branch changed.');\n }\n const abort = new AbortController();\n // Some Hermes releases put stdio servers in their own process group. Reap\n // this server if its supervisor disappears, including a forced cancellation.\n const parent = process.ppid;\n const watchdog = setInterval(() => {\n try { process.kill(parent, 0); }\n catch { abort.abort(); process.stdin.destroy(); clearInterval(watchdog); setTimeout(() => process.exit(143), 2000).unref(); }\n }, 1000); watchdog.unref();\n process.on('SIGTERM', () => { abort.abort(); process.exitCode = 143; });\n process.on('SIGINT', () => { abort.abort(); process.exitCode = 130; });\n serveMcp({ output: { write: (chunk: string) => write(chunk) }, dispatch: createAgentDispatcher(manifest, { signal: abort.signal }) });\n} catch (e) {\n console.error(redact(e instanceof Error ? e.message : String(e))); process.exitCode = 1;\n}\n"]}
@@ -0,0 +1,7 @@
1
+ import type { AgentTool, RunManifest } from './contracts.js';
2
+ import { GithubClient } from './github.js';
3
+ export declare function field(args: Record<string, unknown>, name: string, max?: number): string;
4
+ export declare function createAgentTools(manifest: RunManifest, options?: {
5
+ client?: GithubClient;
6
+ signal?: AbortSignal;
7
+ }): AgentTool[];
@@ -0,0 +1,201 @@
1
+ import { promises as fs } from 'node:fs';
2
+ import path from 'node:path';
3
+ import { createHash } from 'node:crypto';
4
+ import { GithubClient, positiveId, githubToken, repositoryFromRemote } from './github.js';
5
+ import { readAgentFile, writeAgentFile, deleteAgentFile, safeRelative } from './files.js';
6
+ import { GithubSourceReader } from './gitSource.js';
7
+ import { runProcess, redact } from './process.js';
8
+ export function field(args, name, max = 16000) {
9
+ const value = args[name];
10
+ if (typeof value !== 'string' || !value.trim() || value.length > max)
11
+ throw new Error(`${name} must be nonempty text, at most ${max} characters.`);
12
+ return value;
13
+ }
14
+ const string = { type: 'string' }, integer = { type: 'integer', minimum: 1 };
15
+ const clip = (data) => {
16
+ if (Array.isArray(data))
17
+ return data.map(clip);
18
+ if (data && typeof data === 'object')
19
+ return Object.fromEntries(Object.entries(data).map(([key, value]) => [key, typeof value === 'string' && value.length > 16000 ? value.slice(0, 16000) + '\n[truncated]' : clip(value)]));
20
+ return data;
21
+ };
22
+ export function createAgentTools(manifest, options = {}) {
23
+ const tools = [];
24
+ let source;
25
+ const client = () => {
26
+ if (!manifest.repository)
27
+ throw new Error('This checkout needs a github.com origin to use GitHub tools.');
28
+ return options.client || new GithubClient(manifest.repository, { signal: options.signal });
29
+ };
30
+ const requireFiles = () => { if (!manifest.permissions.files || !manifest.branch || manifest.root === manifest.sourceRoot)
31
+ throw new Error('File changes are available only in an isolated implement/pr workspace.'); };
32
+ const requireGithub = () => { if (!manifest.permissions.github)
33
+ throw new Error('GitHub writes were not enabled. Rerun with --allow-github-writes to publish.'); if (!githubToken() && !options.client)
34
+ throw new Error('GitHub writes require GITHUB_TOKEN or GH_TOKEN.'); };
35
+ const git = async (args) => {
36
+ const result = await runProcess('git', ['-C', manifest.root, ...args], { timeoutMs: 30_000, signal: options.signal, maxBytes: 2 * 1024 * 1024 });
37
+ if (result.code)
38
+ throw new Error(`Git failed: ${result.stderr.trim().slice(-2000) || result.code}`);
39
+ return result.stdout.trim();
40
+ };
41
+ const receipts = new Map();
42
+ const writeGithub = async (route, method, body) => {
43
+ requireGithub();
44
+ const key = createHash('sha256').update(JSON.stringify({ route, method, body })).digest('hex');
45
+ if (receipts.has(key))
46
+ return { ...receipts.get(key), replayed: true };
47
+ const result = clip((await client().request(route, method, body)).data);
48
+ receipts.set(key, result);
49
+ return result;
50
+ };
51
+ const add = (name, description, properties, required, run) => tools.push({ name, description, inputSchema: { type: 'object', properties, required, additionalProperties: false }, run });
52
+ add('onboarder_agent_context', 'Current task, repository, workspace, and enforced permissions. Start here.', {}, [], async () => ({ ...manifest, task: redact(manifest.task), auditFile: undefined }));
53
+ add('onboarder_agent_read_file', 'Read source text and its sha256 for a subsequent edit. No symlinks or credential files.', { file: string }, ['file'], async (args) => readAgentFile(manifest.root, field(args, 'file', 500)));
54
+ add('onboarder_agent_write_file', 'Write source only in this run\'s isolated workspace. expectedSha256 must match a fresh read, or be new for a new file.', { file: string, content: string, expectedSha256: string }, ['file', 'content', 'expectedSha256'], async (args) => {
55
+ requireFiles();
56
+ const content = args.content;
57
+ if (typeof content !== 'string')
58
+ throw new Error('content must be text.');
59
+ return writeAgentFile(manifest.root, field(args, 'file', 500), content, field(args, 'expectedSha256', 64));
60
+ });
61
+ add('onboarder_agent_delete_file', 'Delete a source file in the isolated workspace after a fresh read.', { file: string, expectedSha256: string }, ['file', 'expectedSha256'], async (args) => {
62
+ requireFiles();
63
+ return deleteAgentFile(manifest.root, field(args, 'file', 500), field(args, 'expectedSha256', 64));
64
+ });
65
+ add('onboarder_agent_diff', 'Inspect the workspace patch and changed file list. Read-only.', {}, [], async () => ({ status: await git(['status', '--short']), patch: await git(['diff', 'HEAD', '--', '.']), untracked: await git(['ls-files', '--others', '--exclude-standard']) }));
66
+ add('onboarder_agent_run_check', 'Run a fixed npm check or install lockfile dependencies with lifecycle scripts disabled. Requires --allow-checks; test/build scripts may execute repository code.', { check: { type: 'string', enum: ['install', 'test', 'typecheck', 'build'] } }, ['check'], async (args) => {
67
+ if (!manifest.permissions.checks)
68
+ throw new Error('Check execution was not enabled. Rerun with --allow-checks.');
69
+ const check = field(args, 'check', 20);
70
+ if (!['install', 'test', 'typecheck', 'build'].includes(check))
71
+ throw new Error('Choose install, test, typecheck, or build.');
72
+ const commandArgs = check === 'install' ? ['ci', '--ignore-scripts', '--no-audit', '--no-fund'] : check === 'test' ? ['test'] : ['run', check];
73
+ const command = process.platform === 'win32' ? (process.env.ComSpec || 'cmd.exe') : 'npm';
74
+ const argv = process.platform === 'win32' ? ['/d', '/s', '/c', `npm ${commandArgs.join(' ')}`] : commandArgs;
75
+ const result = await runProcess(command, argv, { cwd: manifest.root, timeoutMs: 120_000, maxBytes: 2 * 1024 * 1024, signal: options.signal });
76
+ return { check, code: result.code, passed: result.code === 0, output: redact((result.stdout + result.stderr).slice(-16000)), truncated: result.stdout.length + result.stderr.length > 16000 };
77
+ });
78
+ add('onboarder_agent_local_review', 'Run the project\'s deterministic review of local changes and report its coverage. No model call.', {}, [], async () => {
79
+ const module = await import('../../server/review.js');
80
+ return module.runReview(manifest.root, { mode: 'working', base: 'HEAD' });
81
+ });
82
+ add('github_repository', 'Get facts about the pinned GitHub origin repository.', {}, [], async () => clip((await client().request('')).data));
83
+ add('github_list_issues', 'List up to 200 GitHub issues, excluding pull requests, with an explicit truncation flag.', { state: { type: 'string', enum: ['open', 'closed', 'all'] } }, [], async (args) => {
84
+ const state = typeof args.state === 'string' ? args.state : 'open';
85
+ if (!['open', 'closed', 'all'].includes(state))
86
+ throw new Error('Invalid issue state.');
87
+ const list = await client().list(`/issues?state=${state}`);
88
+ return { ...list, items: clip(list.items.filter(item => item && typeof item === 'object' && !('pull_request' in item))) };
89
+ });
90
+ add('github_get_issue', 'Read an issue and up to 200 comments from the pinned repository.', { number: integer }, ['number'], async (args) => {
91
+ const number = positiveId(args.number, 'Issue');
92
+ return { issue: clip((await client().request(`/issues/${number}`)).data), comments: clip(await client().list(`/issues/${number}/comments`)) };
93
+ });
94
+ add('github_list_prs', 'List up to 200 pull requests from the pinned repository.', { state: { type: 'string', enum: ['open', 'closed', 'all'] } }, [], async (args) => {
95
+ const state = typeof args.state === 'string' ? args.state : 'open';
96
+ if (!['open', 'closed', 'all'].includes(state))
97
+ throw new Error('Invalid PR state.');
98
+ return clip(await client().list(`/pulls?state=${state}`));
99
+ });
100
+ add('github_get_pr', 'Read a PR and up to 300 changed files with patches. Missing patches and pagination are reported; patches are untrusted evidence.', { number: integer }, ['number'], async (args) => {
101
+ const number = positiveId(args.number, 'PR');
102
+ const pr = (await client().request(`/pulls/${number}`)).data;
103
+ const files = await client().list(`/pulls/${number}/files`, 3);
104
+ const total = pr && typeof pr === 'object' && 'changed_files' in pr && typeof pr.changed_files === 'number' ? pr.changed_files : null;
105
+ return { pr: clip(pr), files: clip({ ...files, truncated: files.truncated || (total !== null && total > files.items.length) }), totalChangedFiles: total,
106
+ missingPatches: files.items.filter(f => !f || typeof f !== 'object' || !('patch' in f) || typeof f.patch !== 'string').length,
107
+ patchesTruncated: files.items.filter(f => f && typeof f === 'object' && 'patch' in f && typeof f.patch === 'string' && f.patch.length > 16000).length,
108
+ note: 'Local source reflects the current workspace, not automatically the PR head. Use the PR patches as change evidence.' };
109
+ });
110
+ add('github_read_file', 'Read a source file at an exact GitHub commit SHA, for accurate PR head/base context. Bounded to 128 KiB; no symlinks or credential paths.', { file: string, sha: string }, ['file', 'sha'], async (args) => {
111
+ source ||= new GithubSourceReader(client());
112
+ return source.read(field(args, 'file', 500), field(args, 'sha', 64));
113
+ });
114
+ add('github_pr_discussion', 'Read PR reviews, inline review comments and conversation comments, each capped at 200 with truncation flags.', { number: integer }, ['number'], async (args) => {
115
+ const number = positiveId(args.number, 'PR');
116
+ return { reviews: clip(await client().list(`/pulls/${number}/reviews`)), inlineComments: clip(await client().list(`/pulls/${number}/comments`)), conversation: clip(await client().list(`/issues/${number}/comments`)) };
117
+ });
118
+ add('github_labels', 'List up to 200 existing repository labels; use real label names when triaging issues.', {}, [], async () => clip(await client().list('/labels')));
119
+ add('github_workflow_runs', 'List recent CI workflow runs, optionally filtered by an exact commit SHA.', { sha: string }, [], async (args) => {
120
+ const sha = args.sha === undefined ? '' : field(args, 'sha', 64);
121
+ if (sha && !/^[a-f\d]{40,64}$/i.test(sha))
122
+ throw new Error('Use an exact commit SHA.');
123
+ const response = await client().request(`/actions/runs?per_page=100${sha ? '&head_sha=' + sha : ''}`);
124
+ return { data: clip(response.data), truncated: response.more };
125
+ });
126
+ add('github_workflow_jobs', 'Inspect CI jobs and step conclusions for a specific workflow run; capped at 100 jobs.', { runId: integer }, ['runId'], async (args) => {
127
+ const response = await client().request(`/actions/runs/${positiveId(args.runId, 'Workflow run')}/jobs?per_page=100`);
128
+ return { data: clip(response.data), truncated: response.more };
129
+ });
130
+ add('github_pr_checks', 'Read check runs and combined status at a PR\'s exact head SHA.', { number: integer }, ['number'], async (args) => {
131
+ const pr = (await client().request(`/pulls/${positiveId(args.number, 'PR')}`)).data;
132
+ const sha = pr.head?.sha;
133
+ if (!sha || !/^[a-f\d]{40,64}$/i.test(sha))
134
+ throw new Error('GitHub returned no valid PR head SHA.');
135
+ const checks = await client().request(`/commits/${sha}/check-runs?per_page=100`), status = await client().request(`/commits/${sha}/status?per_page=100`);
136
+ return { sha, checks: clip(checks.data), status: clip(status.data), truncated: checks.more || status.more };
137
+ });
138
+ add('github_create_issue', 'Create an issue in the pinned repository. Requires explicit GitHub write permission.', { title: string, body: string }, ['title', 'body'], async (args) => writeGithub('/issues', 'POST', { title: field(args, 'title', 200), body: redact(field(args, 'body')) }));
139
+ add('github_comment', 'Post a comment on an issue or PR. Requires explicit GitHub write permission.', { number: integer, body: string }, ['number', 'body'], async (args) => writeGithub(`/issues/${positiveId(args.number, 'Issue or PR')}/comments`, 'POST', { body: redact(field(args, 'body')) }));
140
+ add('github_update_issue', 'Update title, body, state or labels of an issue. Requires explicit GitHub write permission.', { number: integer, title: string, body: string, state: { type: 'string', enum: ['open', 'closed'] }, labels: { type: 'array', items: string, maxItems: 20 } }, ['number'], async (args) => {
141
+ const body = {};
142
+ for (const key of ['title', 'body'])
143
+ if (args[key] !== undefined)
144
+ body[key] = redact(field(args, key, key === 'title' ? 200 : 16000));
145
+ if (args.state !== undefined) {
146
+ if (!['open', 'closed'].includes(String(args.state)))
147
+ throw new Error('Invalid issue state.');
148
+ body.state = args.state;
149
+ }
150
+ if (args.labels !== undefined) {
151
+ if (!Array.isArray(args.labels) || args.labels.length > 20 || args.labels.some(l => typeof l !== 'string' || !l || l.length > 64))
152
+ throw new Error('Use up to 20 label names, each at most 64 characters.');
153
+ body.labels = args.labels;
154
+ }
155
+ if (!Object.keys(body).length)
156
+ throw new Error('Choose at least one issue field to update.');
157
+ return writeGithub(`/issues/${positiveId(args.number, 'Issue')}`, 'PATCH', body);
158
+ });
159
+ add('github_submit_review', 'Submit a PR review against a freshly read head SHA. Requires explicit GitHub write permission; use COMMENT unless the task explicitly asks for another decision.', { number: integer, body: string, expectedHeadSha: string, event: { type: 'string', enum: ['COMMENT', 'APPROVE', 'REQUEST_CHANGES'] } }, ['number', 'body', 'expectedHeadSha'], async (args) => {
160
+ requireGithub();
161
+ const number = positiveId(args.number, 'PR'), sha = field(args, 'expectedHeadSha', 64);
162
+ if (!/^[a-f\d]{40,64}$/i.test(sha))
163
+ throw new Error('Use the PR head SHA from github_get_pr.');
164
+ const pr = (await client().request(`/pulls/${number}`)).data;
165
+ if (pr.head?.sha !== sha)
166
+ throw new Error('The PR head changed. Review the new patch before submitting.');
167
+ const event = args.event || 'COMMENT';
168
+ if (!['COMMENT', 'APPROVE', 'REQUEST_CHANGES'].includes(String(event)))
169
+ throw new Error('Invalid review decision.');
170
+ return writeGithub(`/pulls/${number}/reviews`, 'POST', { body: redact(field(args, 'body')), event, commit_id: sha });
171
+ });
172
+ add('github_draft_pr', 'Commit workspace changes, push only the task branch, and open a draft PR. Requires isolated workspace and explicit GitHub write permission. Never force-pushes or merges.', { title: string, body: string }, ['title', 'body'], async (args) => {
173
+ requireFiles();
174
+ requireGithub();
175
+ if (!manifest.remote || repositoryFromRemote(manifest.remote) !== manifest.repository)
176
+ throw new Error('GitHub origin does not match the task repository.');
177
+ if (await git(['remote', 'get-url', 'origin']) !== manifest.remote || await git(['branch', '--show-current']) !== manifest.branch)
178
+ throw new Error('Workspace branch or origin changed; publish was stopped.');
179
+ const title = field(args, 'title', 200), body = redact(field(args, 'body'));
180
+ if (!manifest.baseBranch || manifest.baseBranch.startsWith('-') || /[\x00-\x20]/.test(manifest.baseBranch))
181
+ throw new Error('Invalid pull-request base branch.');
182
+ const existing = await client().list(`/pulls?state=open&head=${encodeURIComponent(manifest.repository.split('/')[0] + ':' + manifest.branch)}`, 1);
183
+ if (existing.items.length)
184
+ return { existing: true, pr: clip(existing.items[0]) };
185
+ const hooks = path.join(path.dirname(manifest.auditFile), 'empty-hooks');
186
+ await fs.mkdir(hooks, { recursive: true, mode: 0o700 });
187
+ if (await git(['status', '--porcelain'])) {
188
+ const changed = (await git(['diff', '--name-only', '-z', 'HEAD'])).split('\0').filter(Boolean);
189
+ const untracked = (await git(['ls-files', '--others', '--exclude-standard', '-z'])).split('\0').filter(Boolean);
190
+ for (const file of [...changed, ...untracked])
191
+ safeRelative(file);
192
+ await git(['add', '--all']);
193
+ await git(['-c', `core.hooksPath=${hooks}`, '-c', 'commit.gpgsign=false', 'commit', '-m', title]);
194
+ }
195
+ const remote = manifest.remote, branch = manifest.branch;
196
+ await git(['-c', `core.hooksPath=${hooks}`, 'push', '--', remote, `refs/heads/${branch}:refs/heads/${branch}`]);
197
+ return writeGithub('/pulls', 'POST', { title, body, head: branch, base: manifest.baseBranch, draft: true });
198
+ });
199
+ return tools;
200
+ }
201
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/cli/agent/tools.ts"],"names":[],"mappings":"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","sourcesContent":["import { promises as fs } from 'node:fs';\nimport path from 'node:path';\nimport { createHash } from 'node:crypto';\nimport type { AgentTool, RunManifest } from './contracts.js';\nimport { GithubClient, positiveId, githubToken, repositoryFromRemote } from './github.js';\nimport { readAgentFile, writeAgentFile, deleteAgentFile, safeRelative } from './files.js';\nimport { GithubSourceReader } from './gitSource.js';\nimport { runProcess, redact } from './process.js';\n\nexport function field(args: Record<string, unknown>, name: string, max = 16000): string {\n const value = args[name];\n if (typeof value !== 'string' || !value.trim() || value.length > max) throw new Error(`${name} must be nonempty text, at most ${max} characters.`);\n return value;\n}\nconst string = { type: 'string' }, integer = { type: 'integer', minimum: 1 };\nconst clip = (data: unknown): unknown => {\n if (Array.isArray(data)) return data.map(clip);\n if (data && typeof data === 'object') return Object.fromEntries(Object.entries(data).map(([key, value]) => [key, typeof value === 'string' && value.length > 16000 ? value.slice(0, 16000) + '\\n[truncated]' : clip(value)]));\n return data;\n};\nexport function createAgentTools(manifest: RunManifest, options: { client?: GithubClient; signal?: AbortSignal } = {}): AgentTool[] {\n const tools: AgentTool[] = [];\n let source: GithubSourceReader | undefined;\n const client = () => {\n if (!manifest.repository) throw new Error('This checkout needs a github.com origin to use GitHub tools.');\n return options.client || new GithubClient(manifest.repository, { signal: options.signal });\n };\n const requireFiles = () => { if (!manifest.permissions.files || !manifest.branch || manifest.root === manifest.sourceRoot) throw new Error('File changes are available only in an isolated implement/pr workspace.'); };\n const requireGithub = () => { if (!manifest.permissions.github) throw new Error('GitHub writes were not enabled. Rerun with --allow-github-writes to publish.'); if (!githubToken() && !options.client) throw new Error('GitHub writes require GITHUB_TOKEN or GH_TOKEN.'); };\n const git = async (args: string[]) => {\n const result = await runProcess('git', ['-C', manifest.root, ...args], { timeoutMs: 30_000, signal: options.signal, maxBytes: 2 * 1024 * 1024 });\n if (result.code) throw new Error(`Git failed: ${result.stderr.trim().slice(-2000) || result.code}`);\n return result.stdout.trim();\n };\n const receipts = new Map<string, unknown>();\n const writeGithub = async (route: string, method: string, body: unknown) => {\n requireGithub();\n const key = createHash('sha256').update(JSON.stringify({ route, method, body })).digest('hex');\n if (receipts.has(key)) return { ...receipts.get(key) as object, replayed: true };\n const result = clip((await client().request(route, method, body)).data);\n receipts.set(key, result); return result;\n };\n const add = (name: string, description: string, properties: Record<string, unknown>, required: string[], run: AgentTool['run']) => tools.push({ name, description, inputSchema: { type: 'object', properties, required, additionalProperties: false }, run });\n add('onboarder_agent_context', 'Current task, repository, workspace, and enforced permissions. Start here.', {}, [], async () => ({ ...manifest, task: redact(manifest.task), auditFile: undefined }));\n add('onboarder_agent_read_file', 'Read source text and its sha256 for a subsequent edit. No symlinks or credential files.', { file: string }, ['file'], async args => readAgentFile(manifest.root, field(args, 'file', 500)));\n add('onboarder_agent_write_file', 'Write source only in this run\\'s isolated workspace. expectedSha256 must match a fresh read, or be new for a new file.', { file: string, content: string, expectedSha256: string }, ['file', 'content', 'expectedSha256'], async args => {\n requireFiles(); const content = args.content; if (typeof content !== 'string') throw new Error('content must be text.');\n return writeAgentFile(manifest.root, field(args, 'file', 500), content, field(args, 'expectedSha256', 64));\n });\n add('onboarder_agent_delete_file', 'Delete a source file in the isolated workspace after a fresh read.', { file: string, expectedSha256: string }, ['file', 'expectedSha256'], async args => {\n requireFiles(); return deleteAgentFile(manifest.root, field(args, 'file', 500), field(args, 'expectedSha256', 64));\n });\n add('onboarder_agent_diff', 'Inspect the workspace patch and changed file list. Read-only.', {}, [], async () => ({ status: await git(['status', '--short']), patch: await git(['diff', 'HEAD', '--', '.']), untracked: await git(['ls-files', '--others', '--exclude-standard']) }));\n add('onboarder_agent_run_check', 'Run a fixed npm check or install lockfile dependencies with lifecycle scripts disabled. Requires --allow-checks; test/build scripts may execute repository code.', { check: { type: 'string', enum: ['install', 'test', 'typecheck', 'build'] } }, ['check'], async args => {\n if (!manifest.permissions.checks) throw new Error('Check execution was not enabled. Rerun with --allow-checks.');\n const check = field(args, 'check', 20); if (!['install', 'test', 'typecheck', 'build'].includes(check)) throw new Error('Choose install, test, typecheck, or build.');\n const commandArgs = check === 'install' ? ['ci', '--ignore-scripts', '--no-audit', '--no-fund'] : check === 'test' ? ['test'] : ['run', check];\n const command = process.platform === 'win32' ? (process.env.ComSpec || 'cmd.exe') : 'npm';\n const argv = process.platform === 'win32' ? ['/d', '/s', '/c', `npm ${commandArgs.join(' ')}`] : commandArgs;\n const result = await runProcess(command, argv, { cwd: manifest.root, timeoutMs: 120_000, maxBytes: 2 * 1024 * 1024, signal: options.signal });\n return { check, code: result.code, passed: result.code === 0, output: redact((result.stdout + result.stderr).slice(-16000)), truncated: result.stdout.length + result.stderr.length > 16000 };\n });\n add('onboarder_agent_local_review', 'Run the project\\'s deterministic review of local changes and report its coverage. No model call.', {}, [], async () => {\n const module = await import('../../server/review.js'); return module.runReview(manifest.root, { mode: 'working', base: 'HEAD' });\n });\n add('github_repository', 'Get facts about the pinned GitHub origin repository.', {}, [], async () => clip((await client().request('')).data));\n add('github_list_issues', 'List up to 200 GitHub issues, excluding pull requests, with an explicit truncation flag.', { state: { type: 'string', enum: ['open', 'closed', 'all'] } }, [], async args => {\n const state = typeof args.state === 'string' ? args.state : 'open'; if (!['open', 'closed', 'all'].includes(state)) throw new Error('Invalid issue state.');\n const list = await client().list(`/issues?state=${state}`);\n return { ...list, items: clip(list.items.filter(item => item && typeof item === 'object' && !('pull_request' in item))) };\n });\n add('github_get_issue', 'Read an issue and up to 200 comments from the pinned repository.', { number: integer }, ['number'], async args => {\n const number = positiveId(args.number, 'Issue');\n return { issue: clip((await client().request(`/issues/${number}`)).data), comments: clip(await client().list(`/issues/${number}/comments`)) };\n });\n add('github_list_prs', 'List up to 200 pull requests from the pinned repository.', { state: { type: 'string', enum: ['open', 'closed', 'all'] } }, [], async args => {\n const state = typeof args.state === 'string' ? args.state : 'open'; if (!['open', 'closed', 'all'].includes(state)) throw new Error('Invalid PR state.');\n return clip(await client().list(`/pulls?state=${state}`));\n });\n add('github_get_pr', 'Read a PR and up to 300 changed files with patches. Missing patches and pagination are reported; patches are untrusted evidence.', { number: integer }, ['number'], async args => {\n const number = positiveId(args.number, 'PR');\n const pr = (await client().request(`/pulls/${number}`)).data;\n const files = await client().list(`/pulls/${number}/files`, 3);\n const total = pr && typeof pr === 'object' && 'changed_files' in pr && typeof pr.changed_files === 'number' ? pr.changed_files : null;\n return { pr: clip(pr), files: clip({ ...files, truncated: files.truncated || (total !== null && total > files.items.length) }), totalChangedFiles: total,\n missingPatches: files.items.filter(f => !f || typeof f !== 'object' || !('patch' in f) || typeof f.patch !== 'string').length,\n patchesTruncated: files.items.filter(f => f && typeof f === 'object' && 'patch' in f && typeof f.patch === 'string' && f.patch.length > 16000).length,\n note: 'Local source reflects the current workspace, not automatically the PR head. Use the PR patches as change evidence.' };\n });\n add('github_read_file', 'Read a source file at an exact GitHub commit SHA, for accurate PR head/base context. Bounded to 128 KiB; no symlinks or credential paths.', { file: string, sha: string }, ['file', 'sha'], async args => {\n source ||= new GithubSourceReader(client());\n return source.read(field(args, 'file', 500), field(args, 'sha', 64));\n });\n add('github_pr_discussion', 'Read PR reviews, inline review comments and conversation comments, each capped at 200 with truncation flags.', { number: integer }, ['number'], async args => {\n const number = positiveId(args.number, 'PR');\n return { reviews: clip(await client().list(`/pulls/${number}/reviews`)), inlineComments: clip(await client().list(`/pulls/${number}/comments`)), conversation: clip(await client().list(`/issues/${number}/comments`)) };\n });\n add('github_labels', 'List up to 200 existing repository labels; use real label names when triaging issues.', {}, [], async () => clip(await client().list('/labels')));\n add('github_workflow_runs', 'List recent CI workflow runs, optionally filtered by an exact commit SHA.', { sha: string }, [], async args => {\n const sha = args.sha === undefined ? '' : field(args, 'sha', 64);\n if (sha && !/^[a-f\\d]{40,64}$/i.test(sha)) throw new Error('Use an exact commit SHA.');\n const response = await client().request(`/actions/runs?per_page=100${sha ? '&head_sha=' + sha : ''}`);\n return { data: clip(response.data), truncated: response.more };\n });\n add('github_workflow_jobs', 'Inspect CI jobs and step conclusions for a specific workflow run; capped at 100 jobs.', { runId: integer }, ['runId'], async args => {\n const response = await client().request(`/actions/runs/${positiveId(args.runId, 'Workflow run')}/jobs?per_page=100`);\n return { data: clip(response.data), truncated: response.more };\n });\n add('github_pr_checks', 'Read check runs and combined status at a PR\\'s exact head SHA.', { number: integer }, ['number'], async args => {\n const pr = (await client().request(`/pulls/${positiveId(args.number, 'PR')}`)).data as { head?: { sha?: string } };\n const sha = pr.head?.sha; if (!sha || !/^[a-f\\d]{40,64}$/i.test(sha)) throw new Error('GitHub returned no valid PR head SHA.');\n const checks = await client().request(`/commits/${sha}/check-runs?per_page=100`), status = await client().request(`/commits/${sha}/status?per_page=100`);\n return { sha, checks: clip(checks.data), status: clip(status.data), truncated: checks.more || status.more };\n });\n add('github_create_issue', 'Create an issue in the pinned repository. Requires explicit GitHub write permission.', { title: string, body: string }, ['title', 'body'], async args => writeGithub('/issues', 'POST', { title: field(args, 'title', 200), body: redact(field(args, 'body')) }));\n add('github_comment', 'Post a comment on an issue or PR. Requires explicit GitHub write permission.', { number: integer, body: string }, ['number', 'body'], async args => writeGithub(`/issues/${positiveId(args.number, 'Issue or PR')}/comments`, 'POST', { body: redact(field(args, 'body')) }));\n add('github_update_issue', 'Update title, body, state or labels of an issue. Requires explicit GitHub write permission.', { number: integer, title: string, body: string, state: { type: 'string', enum: ['open', 'closed'] }, labels: { type: 'array', items: string, maxItems: 20 } }, ['number'], async args => {\n const body: Record<string, unknown> = {};\n for (const key of ['title', 'body']) if (args[key] !== undefined) body[key] = redact(field(args, key, key === 'title' ? 200 : 16000));\n if (args.state !== undefined) { if (!['open', 'closed'].includes(String(args.state))) throw new Error('Invalid issue state.'); body.state = args.state; }\n if (args.labels !== undefined) {\n if (!Array.isArray(args.labels) || args.labels.length > 20 || args.labels.some(l => typeof l !== 'string' || !l || l.length > 64)) throw new Error('Use up to 20 label names, each at most 64 characters.');\n body.labels = args.labels;\n }\n if (!Object.keys(body).length) throw new Error('Choose at least one issue field to update.');\n return writeGithub(`/issues/${positiveId(args.number, 'Issue')}`, 'PATCH', body);\n });\n add('github_submit_review', 'Submit a PR review against a freshly read head SHA. Requires explicit GitHub write permission; use COMMENT unless the task explicitly asks for another decision.', { number: integer, body: string, expectedHeadSha: string, event: { type: 'string', enum: ['COMMENT', 'APPROVE', 'REQUEST_CHANGES'] } }, ['number', 'body', 'expectedHeadSha'], async args => {\n requireGithub();\n const number = positiveId(args.number, 'PR'), sha = field(args, 'expectedHeadSha', 64);\n if (!/^[a-f\\d]{40,64}$/i.test(sha)) throw new Error('Use the PR head SHA from github_get_pr.');\n const pr = (await client().request(`/pulls/${number}`)).data as { head?: { sha?: string } };\n if (pr.head?.sha !== sha) throw new Error('The PR head changed. Review the new patch before submitting.');\n const event = args.event || 'COMMENT'; if (!['COMMENT', 'APPROVE', 'REQUEST_CHANGES'].includes(String(event))) throw new Error('Invalid review decision.');\n return writeGithub(`/pulls/${number}/reviews`, 'POST', { body: redact(field(args, 'body')), event, commit_id: sha });\n });\n add('github_draft_pr', 'Commit workspace changes, push only the task branch, and open a draft PR. Requires isolated workspace and explicit GitHub write permission. Never force-pushes or merges.', { title: string, body: string }, ['title', 'body'], async args => {\n requireFiles(); requireGithub();\n if (!manifest.remote || repositoryFromRemote(manifest.remote) !== manifest.repository) throw new Error('GitHub origin does not match the task repository.');\n if (await git(['remote', 'get-url', 'origin']) !== manifest.remote || await git(['branch', '--show-current']) !== manifest.branch) throw new Error('Workspace branch or origin changed; publish was stopped.');\n const title = field(args, 'title', 200), body = redact(field(args, 'body'));\n if (!manifest.baseBranch || manifest.baseBranch.startsWith('-') || /[\\x00-\\x20]/.test(manifest.baseBranch)) throw new Error('Invalid pull-request base branch.');\n const existing = await client().list(`/pulls?state=open&head=${encodeURIComponent(manifest.repository!.split('/')[0] + ':' + manifest.branch)}`, 1);\n if (existing.items.length) return { existing: true, pr: clip(existing.items[0]) };\n const hooks = path.join(path.dirname(manifest.auditFile), 'empty-hooks'); await fs.mkdir(hooks, { recursive: true, mode: 0o700 });\n if (await git(['status', '--porcelain'])) {\n const changed = (await git(['diff', '--name-only', '-z', 'HEAD'])).split('\\0').filter(Boolean);\n const untracked = (await git(['ls-files', '--others', '--exclude-standard', '-z'])).split('\\0').filter(Boolean);\n for (const file of [...changed, ...untracked]) safeRelative(file);\n await git(['add', '--all']);\n await git(['-c', `core.hooksPath=${hooks}`, '-c', 'commit.gpgsign=false', 'commit', '-m', title]);\n }\n const remote = manifest.remote, branch = manifest.branch!;\n await git(['-c', `core.hooksPath=${hooks}`, 'push', '--', remote, `refs/heads/${branch}:refs/heads/${branch}`]);\n return writeGithub('/pulls', 'POST', { title, body, head: branch, base: manifest.baseBranch, draft: true });\n });\n return tools;\n}\n"]}
@@ -0,0 +1,16 @@
1
+ export declare const CHAT_HELP = "\n Onboarder chat \u2014 a repository agent in your terminal\n\n onboarder Chat about the current repository\n onboarder chat [folder|GitHub URL] Open the chat harness (alias: tui)\n onboarder chat https://github.com/owner/repo Clone a repository, then ask questions\n onboarder chat --resume <chat-id> Continue a saved conversation\n onboarder chat --mode review Start in a specific workflow\n onboarder explore [folder|url] Open the original offline explorer\n\n Type / to see live commands. \u2191/\u2193 select; Tab or Enter inserts; Esc dismisses.\n Chat fills the terminal and adjusts on resize. PgUp/PgDn scroll the conversation.\n Alt-Enter adds a line. Pasted multiline messages stay in the composer.\n /review 42 \u00B7 /triage 12 \u00B7 /implement <task> \u00B7 /pr <task> \u00B7 /github <task>\n /model opens a searchable model picker. /model configure opens full Hermes setup.\n /permissions checks on permits repository test execution.\n /permissions github on permits GitHub writes explicitly requested in a task.\n /new starts fresh; /history and /resume restore conversations.\n /repo <GitHub URL> or a pasted URL clones and opens a repository.\n /clone <GitHub URL> also works; /pull refreshes a clean saved checkout.\n /paste enters multiline input; /send submits it; /discard cancels it.\n Ctrl-C cancels an active task. Ctrl-D saves and exits.\n\n Flags: --mode, --model, --provider, --allow-checks, --allow-github-writes,\n --timeout, --max-turns, --resume, --base, --no-color\n For scripts: onboarder agent <workflow> --task \"...\" --json\n";
2
+ interface ChatOptions {
3
+ target?: string | null;
4
+ flags?: Record<string, any>;
5
+ out?: (text: string) => void;
6
+ err?: (text: string) => void;
7
+ version?: string;
8
+ }
9
+ /** Analysis modules are loaded only when a browsing command actually needs them. */
10
+ export declare function repositoryBrowser(flags: Record<string, any>, progress: (text: string) => void, version?: string): {
11
+ readonly files: string[];
12
+ invalidate(): void;
13
+ run(name: string, args: string[], root: string, signal: AbortSignal): Promise<string>;
14
+ };
15
+ export declare function runChat({ target, flags, out, err, version }?: ChatOptions): Promise<number>;
16
+ export {};