@nonbot/mcp 0.2.4 → 0.3.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.
@@ -0,0 +1,3 @@
1
+ import { type GitCommit } from './core/config.js';
2
+ export declare function gitLog(repoPath: string, since: string): Promise<GitCommit[]>;
3
+ export declare function parseGitLog(out: string): GitCommit[];
package/dist/gitLog.js ADDED
@@ -0,0 +1,46 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { stat } from 'node:fs/promises';
3
+ import { resolve } from 'node:path';
4
+ import { checkRepoPath } from './core/config.js';
5
+ const MAX_COMMITS = 5000;
6
+ const BODY_MAX = 2000;
7
+ const FS = '\x1f';
8
+ const RS = '\x1e';
9
+ export async function gitLog(repoPath, since) {
10
+ const bad = checkRepoPath(repoPath);
11
+ if (bad)
12
+ throw new Error(bad);
13
+ if (!/^\d{4}-\d{2}-\d{2}$/.test(since))
14
+ throw new Error('since must be YYYY-MM-DD');
15
+ const dir = resolve(repoPath);
16
+ const st = await stat(dir).catch(() => null);
17
+ if (!st || !st.isDirectory())
18
+ throw new Error('repo_path is not a directory');
19
+ const args = [
20
+ '-c', 'core.fsmonitor=false', '-c', 'log.showSignature=false',
21
+ '-C', dir, 'log', `--since=${since}`, `--max-count=${MAX_COMMITS}`, '--no-color',
22
+ `--format=%H${FS}%cI${FS}%s${FS}%b${RS}`,
23
+ ];
24
+ const out = await new Promise((ok, fail) => {
25
+ execFile('git', args, { timeout: 20_000, maxBuffer: 32 * 1024 * 1024, env: { ...process.env, GIT_TERMINAL_PROMPT: '0' }, windowsHide: true }, (err, stdout) => {
26
+ if (err)
27
+ fail(new Error('git log failed — is repo_path a git repository?'));
28
+ else
29
+ ok(stdout);
30
+ });
31
+ });
32
+ return parseGitLog(out);
33
+ }
34
+ export function parseGitLog(out) {
35
+ const commits = [];
36
+ for (const rec of out.split(RS)) {
37
+ const r = rec.replace(/^\s+/, '');
38
+ if (!r)
39
+ continue;
40
+ const [hash = '', date = '', subject = '', body = ''] = r.split(FS);
41
+ if (!/^[0-9a-f]{7,64}$/.test(hash))
42
+ continue;
43
+ commits.push({ hash, date, subject, body: body.trim().slice(0, BODY_MAX) });
44
+ }
45
+ return commits;
46
+ }
package/dist/stdio.js CHANGED
@@ -5,6 +5,7 @@ import { dirname, join, resolve } from 'node:path';
5
5
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
6
6
  import { resolveApiBase } from './core/config.js';
7
7
  import { createNonbotMcpServer } from './core/server.js';
8
+ import { gitLog } from './gitLog.js';
8
9
  const BACKUP_DIR = join(homedir(), '.non.bot', 'backups');
9
10
  async function tokenFromCliAuth() {
10
11
  try {
@@ -61,6 +62,7 @@ async function main() {
61
62
  readonly: process.env.NON_BOT_MCP_READONLY === '1',
62
63
  backup: fileBackup,
63
64
  readLocalImage,
65
+ gitLog,
64
66
  };
65
67
  const server = createNonbotMcpServer(ctx);
66
68
  const transport = new StdioServerTransport();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nonbot/mcp",
3
- "version": "0.2.4",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
5
  "description": "The non.bot MCP server — one server for your portfolios, decision graph, and Runs. Runs over stdio (Claude Code, Cursor, VS Code) with a pat_ token. Built on MCP protocol 2025-11-25.",
6
6
  "keywords": [