bantou 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,3 +1,61 @@
1
- # Temporary Holding Version
1
+ # bantou-server
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ **雛形のみ(業務ロジック未実装)。** 起動・設定読込・workspace 準備・終了処理だけを持つ常駐プロセス。
4
+
5
+ ## 役割
6
+
7
+ - linux / mac で動く npm package(`bantou`)。`npx` で起動する。
8
+ - bantou-desktop(`../desktop/`、mac / windows のネイティブアプリ)からの指示を受ける。
9
+ - 担当は 2 つ。remote session の起動(`src/session.ts`)と、remote cap(オーケストレーター)の起動(`src/cap.ts`)。
10
+ - desktop が指示を出す側。server は受ける側で、自律的に方針を決めない。
11
+
12
+ ## 起動方法
13
+
14
+ ```
15
+ npx bantou --config <path>
16
+ ```
17
+
18
+ - `--config` 省略時は `~/.config/bantou-server/config.json`。
19
+ - それ以外の引数は exit 2。実行時エラーは exit 1。
20
+ - SIGTERM / SIGINT で後始末して exit 0。
21
+
22
+ 開発時は `server/` で実行する。
23
+
24
+ ```
25
+ npm install
26
+ npm run typecheck
27
+ npm run build
28
+ npm test
29
+ npm run dev -- --config <path>
30
+ ```
31
+
32
+ dev / test は `node --import tsx` を使う。Node >=22 のみで動き、bun を要しない。
33
+
34
+ ## config.json
35
+
36
+ ```json
37
+ { "workspace": "/path/to/workspace" }
38
+ ```
39
+
40
+ - `workspace`(必須): workspace フォルダの絶対パス。
41
+
42
+ ## workspace レイアウト
43
+
44
+ ```
45
+ <workspace>/
46
+ repos/ repo の展開先
47
+ ```
48
+
49
+ 起動時に `<workspace>/` と `<workspace>/repos/` が無ければ作る。
50
+
51
+ ## 未決定事項
52
+
53
+ - desktop と server の通信方式
54
+ - remote session と remote cap の起動手順の詳細
55
+ - 配置先ホスト
56
+
57
+ ## 関連資料
58
+
59
+ - [`../docs/protocol.md`](../docs/protocol.md)
60
+ - [`../docs/guardrail.md`](../docs/guardrail.md)
61
+ - [`../desktop/README.md`](../desktop/README.md)
package/dist/cap.js ADDED
@@ -0,0 +1,7 @@
1
+ /**
2
+ * remote cap(オーケストレーター)の起動を担う予定のモジュール。
3
+ * 業務ロジックは未実装。
4
+ */
5
+ export async function startCap(_spec) {
6
+ throw new Error("未実装");
7
+ }
package/dist/cli.js ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env node
2
+ import { homedir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { runDaemon } from "./daemon.js";
5
+ const DEFAULT_CONFIG = join(homedir(), ".config", "bantou-server", "config.json");
6
+ /** 引数を解釈する。不正な引数は null を返す。 */
7
+ function parseArgs(argv) {
8
+ let config = DEFAULT_CONFIG;
9
+ for (let i = 0; i < argv.length; i++) {
10
+ if (argv[i] === "--config" && i + 1 < argv.length) {
11
+ config = argv[++i];
12
+ }
13
+ else {
14
+ return null;
15
+ }
16
+ }
17
+ return { config };
18
+ }
19
+ const args = parseArgs(process.argv.slice(2));
20
+ if (!args) {
21
+ console.error("usage: bantou-server [--config <path>]");
22
+ process.exit(2);
23
+ }
24
+ runDaemon(args.config).catch((e) => {
25
+ console.error(`bantou-server: ${e instanceof Error ? e.message : String(e)}`);
26
+ process.exit(1);
27
+ });
package/dist/config.js ADDED
@@ -0,0 +1,23 @@
1
+ import { readFile } from "node:fs/promises";
2
+ /** config.json を読み込んで検証する。 */
3
+ export async function loadConfig(path) {
4
+ let raw;
5
+ try {
6
+ raw = await readFile(path, "utf8");
7
+ }
8
+ catch (e) {
9
+ throw new Error(`config を読めない: ${path} (${e.message})`);
10
+ }
11
+ let data;
12
+ try {
13
+ data = JSON.parse(raw);
14
+ }
15
+ catch (e) {
16
+ throw new Error(`config が JSON として不正: ${path} (${e.message})`);
17
+ }
18
+ const ws = data?.workspace;
19
+ if (typeof ws !== "string" || ws.length === 0) {
20
+ throw new Error(`config の workspace は必須の文字列: ${path}`);
21
+ }
22
+ return { workspace: ws };
23
+ }
package/dist/daemon.js ADDED
@@ -0,0 +1,23 @@
1
+ import { loadConfig } from "./config.js";
2
+ import { prepareWorkspace } from "./workspace.js";
3
+ const log = (msg) => {
4
+ console.log(`${new Date().toISOString()} bantou-server: ${msg}`);
5
+ };
6
+ /** 起動して常駐する。SIGTERM / SIGINT で後始末して exit 0。 */
7
+ export async function runDaemon(configPath) {
8
+ log("起動");
9
+ const config = await loadConfig(configPath);
10
+ log(`設定読込: ${configPath} (workspace=${config.workspace})`);
11
+ const repos = await prepareWorkspace(config.workspace);
12
+ log(`workspace 準備完了: ${repos}`);
13
+ const keepAlive = setInterval(() => { }, 1 << 30);
14
+ const shutdown = (signal) => {
15
+ log(`${signal} 受信、終了処理`);
16
+ clearInterval(keepAlive);
17
+ log("終了");
18
+ process.exit(0);
19
+ };
20
+ process.on("SIGTERM", () => shutdown("SIGTERM"));
21
+ process.on("SIGINT", () => shutdown("SIGINT"));
22
+ log("常駐開始");
23
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * remote session の起動を担う予定のモジュール。
3
+ * 業務ロジックは未実装。
4
+ */
5
+ export async function startSession(_spec) {
6
+ throw new Error("未実装");
7
+ }
@@ -0,0 +1,8 @@
1
+ import { mkdir } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ /** `<workspace>/` と `<workspace>/repos/` を無ければ作る。repos のパスを返す。 */
4
+ export async function prepareWorkspace(workspace) {
5
+ const repos = join(workspace, "repos");
6
+ await mkdir(repos, { recursive: true });
7
+ return repos;
8
+ }
package/package.json CHANGED
@@ -1,6 +1,32 @@
1
1
  {
2
2
  "name": "bantou",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.0",
4
+ "description": "Remote session and remote cap launcher server for bantou-desktop",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/unagents/bantou.git",
9
+ "directory": "server"
10
+ },
11
+ "type": "module",
12
+ "bin": {
13
+ "bantou": "dist/cli.js"
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsc",
20
+ "dev": "node --import tsx src/cli.ts",
21
+ "test": "node --import tsx --test test/*.test.ts",
22
+ "typecheck": "tsc --noEmit -p tsconfig.json"
23
+ },
24
+ "engines": {
25
+ "node": ">=22"
26
+ },
27
+ "devDependencies": {
28
+ "@types/node": "^22.0.0",
29
+ "tsx": "^4.19.0",
30
+ "typescript": "^5.6.0"
31
+ }
32
+ }