@minimalcorp/tsunagi 0.1.42 → 0.1.44
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/.next/standalone/apps/web/.next/BUILD_ID +1 -1
- package/.next/standalone/apps/web/.next/build-manifest.json +3 -3
- package/.next/standalone/apps/web/.next/prerender-manifest.json +3 -3
- package/.next/standalone/apps/web/.next/server/app/_global-error.html +1 -1
- package/.next/standalone/apps/web/.next/server/app/_global-error.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/_not-found.html +1 -1
- package/.next/standalone/apps/web/.next/server/app/_not-found.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/index.html +1 -1
- package/.next/standalone/apps/web/.next/server/app/index.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/settings.html +1 -1
- package/.next/standalone/apps/web/.next/server/app/settings.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/settings.segments/_full.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/settings.segments/_head.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/settings.segments/_index.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/settings.segments/settings.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/middleware-build-manifest.js +3 -3
- package/.next/standalone/apps/web/.next/server/pages/404.html +1 -1
- package/.next/standalone/apps/web/.next/server/pages/500.html +1 -1
- package/.next/standalone/apps/web/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/apps/web/.next/server/server-reference-manifest.json +1 -1
- package/LICENSE +126 -0
- package/README.md +154 -0
- package/dist/auto-migrate.js +5 -1
- package/dist/cli.js +12 -5
- package/dist/server/lib/llm-process.js +8 -7
- package/dist/server/lib/whisper-process.js +8 -7
- package/dist/server/routes/terminal.js +6 -2
- package/npm-shrinkwrap.json +199 -21
- package/package.json +3 -9
- /package/.next/standalone/apps/web/.next/static/{BNKOxgPR4vrQI79IAwnsk → b89JVAeQs5UYaMHr5WMOT}/_buildManifest.js +0 -0
- /package/.next/standalone/apps/web/.next/static/{BNKOxgPR4vrQI79IAwnsk → b89JVAeQs5UYaMHr5WMOT}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/apps/web/.next/static/{BNKOxgPR4vrQI79IAwnsk → b89JVAeQs5UYaMHr5WMOT}/_ssgManifest.js +0 -0
- /package/{llm-server → dist/llm-server}/README.md +0 -0
- /package/{llm-server → dist/llm-server}/download_model.py +0 -0
- /package/{llm-server → dist/llm-server}/requirements.txt +0 -0
- /package/{llm-server → dist/llm-server}/run.sh +0 -0
- /package/{prisma → dist/prisma}/migrations/20260129030443_init/migration.sql +0 -0
- /package/{prisma → dist/prisma}/migrations/20260130140855_add_task_planning_fields_and_base_branch/migration.sql +0 -0
- /package/{prisma → dist/prisma}/migrations/20260130163529_add_base_branch_commit/migration.sql +0 -0
- /package/{prisma → dist/prisma}/migrations/20260131171847_remove_completed_at/migration.sql +0 -0
- /package/{prisma → dist/prisma}/migrations/20260328000000_remove_sdk_dead_code/migration.sql +0 -0
- /package/{prisma → dist/prisma}/migrations/20260329000000_add_todos_and_planner_tabs/migration.sql +0 -0
- /package/{prisma → dist/prisma}/migrations/20260410000000_clear_stale_tab_todos/migration.sql +0 -0
- /package/{prisma → dist/prisma}/migrations/20260413000000_make_task_order_non_nullable/migration.sql +0 -0
- /package/{prisma → dist/prisma}/migrations/20260629000000_add_tab_mode/migration.sql +0 -0
- /package/{prisma → dist/prisma}/migrations/20260915000000_drop_planner_tabs/migration.sql +0 -0
- /package/{prisma → dist/prisma}/migrations/20260916000000_add_repository_order/migration.sql +0 -0
- /package/{prisma → dist/prisma}/migrations/20260918000000_add_tab_unread/migration.sql +0 -0
- /package/{prisma → dist/prisma}/migrations/20260924000000_add_app_settings/migration.sql +0 -0
- /package/{prisma → dist/prisma}/migrations/migration_lock.toml +0 -0
- /package/{prisma → dist/prisma}/schema.prisma +0 -0
- /package/{prisma.config.ts → dist/prisma.config.ts} +0 -0
- /package/{scripts → dist/scripts}/monaco-editor.sh +0 -0
- /package/{whisper-server → dist/whisper-server}/README.md +0 -0
- /package/{whisper-server → dist/whisper-server}/download_model.py +0 -0
- /package/{whisper-server → dist/whisper-server}/requirements.txt +0 -0
- /package/{whisper-server → dist/whisper-server}/run.sh +0 -0
- /package/{whisper-server → dist/whisper-server}/server.py +0 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# PolyForm Shield License 1.0.0
|
|
2
|
+
|
|
3
|
+
<https://polyformproject.org/licenses/shield/1.0.0>
|
|
4
|
+
|
|
5
|
+
## Acceptance
|
|
6
|
+
|
|
7
|
+
In order to get any license under these terms, you must agree
|
|
8
|
+
to them as both strict obligations and conditions to all
|
|
9
|
+
your licenses.
|
|
10
|
+
|
|
11
|
+
## Copyright License
|
|
12
|
+
|
|
13
|
+
The licensor grants you a copyright license for the
|
|
14
|
+
software to do everything you might do with the software
|
|
15
|
+
that would otherwise infringe the licensor's copyright
|
|
16
|
+
in it for any permitted purpose. However, you may
|
|
17
|
+
only distribute the software according to [Distribution
|
|
18
|
+
License](#distribution-license) and make changes or new works
|
|
19
|
+
based on the software according to [Changes and New Works
|
|
20
|
+
License](#changes-and-new-works-license).
|
|
21
|
+
|
|
22
|
+
## Distribution License
|
|
23
|
+
|
|
24
|
+
The licensor grants you an additional copyright license
|
|
25
|
+
to distribute copies of the software. Your license
|
|
26
|
+
to distribute covers distributing the software with
|
|
27
|
+
changes and new works permitted by [Changes and New Works
|
|
28
|
+
License](#changes-and-new-works-license).
|
|
29
|
+
|
|
30
|
+
## Notices
|
|
31
|
+
|
|
32
|
+
You must ensure that anyone who gets a copy of any part of
|
|
33
|
+
the software from you also gets a copy of these terms, as well
|
|
34
|
+
as the following copyright notice:
|
|
35
|
+
|
|
36
|
+
> Copyright 2026 minimalcorp
|
|
37
|
+
|
|
38
|
+
## Changes and New Works License
|
|
39
|
+
|
|
40
|
+
The licensor grants you the copyright licenses in
|
|
41
|
+
[Copyright License](#copyright-license) for changes and
|
|
42
|
+
new works based on the software subject to this license.
|
|
43
|
+
|
|
44
|
+
## Patent License
|
|
45
|
+
|
|
46
|
+
The licensor grants you a patent license for the software that
|
|
47
|
+
covers patent claims the licensor can license, or becomes able
|
|
48
|
+
to license, that you would infringe by using the software.
|
|
49
|
+
|
|
50
|
+
## Noncompete
|
|
51
|
+
|
|
52
|
+
Any purpose is a permitted purpose, except for providing to others
|
|
53
|
+
any product that competes with the software.
|
|
54
|
+
|
|
55
|
+
If you use this software to market a product as a substitute for
|
|
56
|
+
the functionality or value of the software, it competes with the
|
|
57
|
+
software. A product may use this software for testing, staging,
|
|
58
|
+
or deploying the product, without necessarily competing with the
|
|
59
|
+
software, even if the product provides some of the same features
|
|
60
|
+
as the software.
|
|
61
|
+
|
|
62
|
+
## Competition Conditions
|
|
63
|
+
|
|
64
|
+
If you use the software to provide a product that competes with
|
|
65
|
+
the software, that use is not allowed under the licenses granted
|
|
66
|
+
by these terms.
|
|
67
|
+
|
|
68
|
+
## Fair Use
|
|
69
|
+
|
|
70
|
+
You may have "fair use" rights for the software under the
|
|
71
|
+
law. These terms do not limit them.
|
|
72
|
+
|
|
73
|
+
## No Other Rights
|
|
74
|
+
|
|
75
|
+
These terms do not allow you to sublicense or transfer any of
|
|
76
|
+
your licenses to anyone else, or prevent the licensor from
|
|
77
|
+
granting licenses to anyone else. These terms do not imply
|
|
78
|
+
any other licenses.
|
|
79
|
+
|
|
80
|
+
## Patent Defense
|
|
81
|
+
|
|
82
|
+
If you make any written claim that the software infringes or
|
|
83
|
+
contributes to infringement of any patent, your patent license
|
|
84
|
+
for the software granted under these terms ends immediately. If
|
|
85
|
+
your company makes such a claim, your patent license ends
|
|
86
|
+
immediately for work on behalf of your company.
|
|
87
|
+
|
|
88
|
+
## Violations
|
|
89
|
+
|
|
90
|
+
The first time you are notified in writing that you have
|
|
91
|
+
violated any of these terms, or done anything with the software
|
|
92
|
+
not covered by your licenses, your licenses can nonetheless
|
|
93
|
+
continue if you come into full compliance with these terms,
|
|
94
|
+
and take practical steps to correct past violations, within
|
|
95
|
+
32 days of receiving notice. Otherwise, all your licenses
|
|
96
|
+
end immediately.
|
|
97
|
+
|
|
98
|
+
## No Liability
|
|
99
|
+
|
|
100
|
+
***As far as the law allows, the software comes as is, without
|
|
101
|
+
any warranty or condition, and the licensor will not be liable
|
|
102
|
+
to you for any damages arising out of these terms or the use
|
|
103
|
+
or nature of the software, under any kind of legal claim.***
|
|
104
|
+
|
|
105
|
+
## Definitions
|
|
106
|
+
|
|
107
|
+
The **licensor** is the individual or entity offering these
|
|
108
|
+
terms, and the **software** is the software the licensor makes
|
|
109
|
+
available under these terms.
|
|
110
|
+
|
|
111
|
+
**You** refers to the individual or entity agreeing to these
|
|
112
|
+
terms.
|
|
113
|
+
|
|
114
|
+
**Your company** is any legal entity, sole proprietorship,
|
|
115
|
+
or other kind of organization that you work for, plus all
|
|
116
|
+
organizations that have control over, are under the control of,
|
|
117
|
+
or are under common control with that organization. **Control**
|
|
118
|
+
means ownership of substantially all the assets of an entity,
|
|
119
|
+
or the power to direct its management and policies by vote,
|
|
120
|
+
contract, or otherwise. Control can be direct or indirect.
|
|
121
|
+
|
|
122
|
+
**Your licenses** are all the licenses granted to you for the
|
|
123
|
+
software under these terms.
|
|
124
|
+
|
|
125
|
+
**Use** means anything you do with the software requiring one
|
|
126
|
+
of your licenses.
|
package/README.md
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# Tsunagi Monorepo
|
|
2
|
+
|
|
3
|
+
**Tsunagi (繋ぎ)** — 複数 GitHub 組織のプロジェクトをローカルで統合管理し、
|
|
4
|
+
Claude AI による AI 駆動開発を可視化・制御する Web UI ツール。
|
|
5
|
+
|
|
6
|
+
このリポジトリは npm workspaces ベースの monorepo です。
|
|
7
|
+
|
|
8
|
+
## パッケージ
|
|
9
|
+
|
|
10
|
+
| パッケージ | 場所 | npm 公開 | 説明 |
|
|
11
|
+
| ------------------------------------ | ------------ | -------- | ---------------------------------------------------------------- |
|
|
12
|
+
| [`@minimalcorp/tsunagi`](./apps/web) | `apps/web/` | ✅ | Tsunagi 本体 (Next.js + Fastify + Prisma) |
|
|
13
|
+
| [`tsunagi-docs`](./apps/docs) | `apps/docs/` | ❌ | ユーザー向けドキュメントサイト (Nextra, GitHub Pages にデプロイ) |
|
|
14
|
+
|
|
15
|
+
## クイックスタート(エンドユーザー向け)
|
|
16
|
+
|
|
17
|
+
Tsunagi を使いたいだけの場合は、npm から直接起動できます:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npx @minimalcorp/tsunagi
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
詳細は [apps/web/README.md](./apps/web/README.md) または
|
|
24
|
+
[ドキュメントサイト](https://minimalcorp.github.io/tsunagi/) を参照してください。
|
|
25
|
+
|
|
26
|
+
## 開発セットアップ
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
# リポジトリをクローン
|
|
30
|
+
git clone https://github.com/minimalcorp/tsunagi.git
|
|
31
|
+
cd tsunagi
|
|
32
|
+
|
|
33
|
+
# 依存関係インストール(全ワークスペース)
|
|
34
|
+
npm install
|
|
35
|
+
|
|
36
|
+
# Tsunagi 本体を開発モードで起動
|
|
37
|
+
npm run dev
|
|
38
|
+
|
|
39
|
+
# ドキュメントサイトを開発モードで起動
|
|
40
|
+
npm run docs:dev
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## よく使うコマンド(ルートから実行)
|
|
44
|
+
|
|
45
|
+
| コマンド | 説明 |
|
|
46
|
+
| ---------------------- | ------------------------------------------ |
|
|
47
|
+
| `npm run dev` | web + docs を並列起動(Ctrl+C で両方停止) |
|
|
48
|
+
| `npm run web:dev` | Tsunagi 本体のみ開発モードで起動 |
|
|
49
|
+
| `npm run docs:dev` | ドキュメントサイトのみ開発モードで起動 |
|
|
50
|
+
| `npm run build` | 全ワークスペースをビルド |
|
|
51
|
+
| `npm run lint` | 全ワークスペースで ESLint を実行 |
|
|
52
|
+
| `npm run type-check` | 全ワークスペースで TypeScript 型チェック |
|
|
53
|
+
| `npm run format` | Prettier で全ファイルをフォーマット |
|
|
54
|
+
| `npm run format:check` | Prettier でフォーマット差分チェック |
|
|
55
|
+
|
|
56
|
+
## リリース
|
|
57
|
+
|
|
58
|
+
GitHub Actions の `Release` workflow を手動実行することで、`@minimalcorp/tsunagi`
|
|
59
|
+
の npm 公開、および docs の GitHub Pages デプロイを統合的に行えます:
|
|
60
|
+
|
|
61
|
+
1. GitHub の Actions タブから `Release` workflow を選択
|
|
62
|
+
2. 以下を入力して Run:
|
|
63
|
+
- **target**: `all` / `tsunagi` / `docs` のいずれか
|
|
64
|
+
- **version**: `patch` / `minor` / `major` (tsunagi にのみ適用)
|
|
65
|
+
|
|
66
|
+
詳細は [.github/workflows/release.yml](./.github/workflows/release.yml) を参照。
|
|
67
|
+
|
|
68
|
+
### 初回実行前の必須セットアップ
|
|
69
|
+
|
|
70
|
+
初めて `Release` workflow を実行する前に、以下を手動で設定しておく必要があります。
|
|
71
|
+
|
|
72
|
+
1. **npm Organization 準備**
|
|
73
|
+
- npmjs.com で `@minimalcorp` organization を作成(未作成の場合)
|
|
74
|
+
- `@minimalcorp/tsunagi` パッケージ名が未取得であることを確認
|
|
75
|
+
|
|
76
|
+
2. **npm Trusted Publisher を事前登録** (npm 側)
|
|
77
|
+
- 本 workflow は **npm Trusted Publishing (OIDC)** を使用するため `NPM_TOKEN` は不要
|
|
78
|
+
- npmjs.com で Trusted Publisher を追加: organization=`minimalcorp`, repository=`tsunagi`, workflow=`release.yml`, environment=`production-release`
|
|
79
|
+
- パッケージがまだ存在しない段階でも "Pending Trusted Publisher" として事前登録可能
|
|
80
|
+
|
|
81
|
+
3. **GitHub Pages を Actions ソースに設定**
|
|
82
|
+
- Settings → Pages → Source: `GitHub Actions` を選択(`Deploy from a branch` ではない)
|
|
83
|
+
|
|
84
|
+
4. **`production-release` Environment の作成と承認者設定**(必須)
|
|
85
|
+
- Settings → Environments → `New environment` → 名前を `production-release` として作成
|
|
86
|
+
- **Required reviewers** を有効化し、リリース承認権限を持つメンバー(自分自身でも可)を追加
|
|
87
|
+
- Release workflow の `approve` job はこの Environment 配下で実行されるため、
|
|
88
|
+
workflow 実行時に GitHub UI で明示的な承認操作が必要になる
|
|
89
|
+
- `publish-tsunagi` / `deploy-docs` 両方がこの approval を通過した後でのみ実行される
|
|
90
|
+
- 承認画面で main の最新状態(他 PR の merge 状況等)を目視確認してから承認する
|
|
91
|
+
ことで、意図しない内容のリリースを防ぐ
|
|
92
|
+
|
|
93
|
+
5. **`main` ブランチ保護の bypass 設定**(保護ルールを設定している場合)
|
|
94
|
+
- `Release` workflow は `npm version` で bump した commit と tag を `main` に直接 push する
|
|
95
|
+
- main に `Require a pull request before merging` 等の保護ルールがある場合、push がブロックされる
|
|
96
|
+
- `github-actions[bot]` は user role を持たないため、Bypass list に**明示的に**以下のいずれかを設定する必要がある:
|
|
97
|
+
- 独立した **Deploy key** を発行し Bypass に追加(推奨)
|
|
98
|
+
- 管理者ユーザーの **PAT** を `PAT_TOKEN` secret として登録し、workflow の `checkout` で使用
|
|
99
|
+
- 管理者ユーザー自身を Bypass に追加(workflow を本人が起動する運用)
|
|
100
|
+
- 保護ルールを main に設定していない場合は不要
|
|
101
|
+
|
|
102
|
+
これらを設定せずに workflow を実行すると、途中で失敗してバージョン番号だけが bump された中途半端な状態になる可能性があるので、**必ず事前に設定してください**。
|
|
103
|
+
|
|
104
|
+
### リリース中の concurrent push について
|
|
105
|
+
|
|
106
|
+
Release workflow には以下の保護機構が組み込まれています:
|
|
107
|
+
|
|
108
|
+
- **同時実行の排他制御**: `concurrency: release` group により、2つ目の Release workflow は1つ目の完了を待機します
|
|
109
|
+
- **Push retry with rebase**: workflow の checkout から push までの間に別の PR が main に merge された場合でも、自動で rebase してから retry します(最大3回)。rebase により merge 済みの内容を取り込んだ上で version bump commit を再適用するため、npm publish は最新の main 状態で行われます
|
|
110
|
+
- **Environment 承認ゲート**: 人間が承認するタイミングで main の状態を目視確認できるため、意図しない内容のリリースを事前に察知できます
|
|
111
|
+
|
|
112
|
+
## リポジトリ構成
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
tsunagi/
|
|
116
|
+
├── apps/
|
|
117
|
+
│ ├── web/ # @minimalcorp/tsunagi (Tsunagi 本体)
|
|
118
|
+
│ └── docs/ # tsunagi-docs (Nextra ドキュメントサイト)
|
|
119
|
+
├── .github/workflows/
|
|
120
|
+
│ ├── ci.yml # PR CI (format / lint / type-check / build)
|
|
121
|
+
│ ├── release.yml # 統合リリース (npm publish + Pages deploy)
|
|
122
|
+
│ └── cla.yml # CLA Assistant bot
|
|
123
|
+
├── .husky/ # Git hooks
|
|
124
|
+
├── package.json # monorepo root (workspaces)
|
|
125
|
+
├── .prettierrc.json # monorepo 共通 Prettier 設定
|
|
126
|
+
├── LICENSE # PolyForm Shield 1.0.0
|
|
127
|
+
├── CLA.md # Contributor License Agreement
|
|
128
|
+
├── CONTRIBUTING.md # コントリビューションガイド
|
|
129
|
+
└── CLAUDE.md # Claude AI 向け作業ルール
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## 対応 OS
|
|
133
|
+
|
|
134
|
+
- macOS
|
|
135
|
+
- Linux
|
|
136
|
+
- Windows は**非サポート**(WSL2 経由で動作する可能性はありますが保証されません)
|
|
137
|
+
|
|
138
|
+
## 必須ランタイム
|
|
139
|
+
|
|
140
|
+
- **Node.js ≥ 20**
|
|
141
|
+
- **Git ≥ 2.42**(空リポジトリを扱うため `git worktree add --orphan` を使用)
|
|
142
|
+
- **Claude Code CLI**(`claude` コマンドが PATH 上に必要)
|
|
143
|
+
|
|
144
|
+
## ライセンス
|
|
145
|
+
|
|
146
|
+
本リポジトリは [PolyForm Shield License 1.0.0](./LICENSE) のもとで公開されています。
|
|
147
|
+
これは source-available ライセンスであり、**競合製品化は禁止**されていますが、
|
|
148
|
+
個人利用・社内利用・通常の商用利用は自由です。詳細は [LICENSE](./LICENSE) を
|
|
149
|
+
参照してください。
|
|
150
|
+
|
|
151
|
+
## コントリビューション
|
|
152
|
+
|
|
153
|
+
Pull Request を送信する際は [CONTRIBUTING.md](./CONTRIBUTING.md) を参照し、
|
|
154
|
+
CLA Assistant bot の指示に従って [CLA](./CLA.md) への同意をお願いします。
|
package/dist/auto-migrate.js
CHANGED
|
@@ -3,7 +3,11 @@ import { promisify } from 'node:util';
|
|
|
3
3
|
import * as os from 'node:os';
|
|
4
4
|
import * as path from 'node:path';
|
|
5
5
|
import * as fs from 'node:fs/promises';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
6
7
|
const execAsync = promisify(exec);
|
|
8
|
+
// bundle.mjs が dist/ にコピーする。npx は npm workspace 内だと cwd を workspace
|
|
9
|
+
// ルートに変えるため、cwd 依存にせず --config で明示する(相対パスは config 基準で解決される)。
|
|
10
|
+
const PRISMA_CONFIG = path.join(path.dirname(fileURLToPath(import.meta.url)), 'prisma.config.ts');
|
|
7
11
|
function getTsunagiDataDir() {
|
|
8
12
|
return process.env.TSUNAGI_DATA_DIR || path.join(os.homedir(), '.tsunagi');
|
|
9
13
|
}
|
|
@@ -13,7 +17,7 @@ function getStateDir() {
|
|
|
13
17
|
async function autoMigrate() {
|
|
14
18
|
try {
|
|
15
19
|
await fs.mkdir(getStateDir(), { recursive: true });
|
|
16
|
-
const { stdout } = await execAsync(
|
|
20
|
+
const { stdout } = await execAsync(`npx prisma migrate deploy --config ${JSON.stringify(PRISMA_CONFIG)}`);
|
|
17
21
|
// Extract "N migration(s) applied." line from prisma output
|
|
18
22
|
const match = stdout.match(/(\d+)\s+migrations?\s+applied/i);
|
|
19
23
|
if (match) {
|
package/dist/cli.js
CHANGED
|
@@ -4,6 +4,7 @@ import * as fs from 'node:fs';
|
|
|
4
4
|
import * as http from 'node:http';
|
|
5
5
|
import * as path from 'node:path';
|
|
6
6
|
import { fileURLToPath } from 'node:url';
|
|
7
|
+
import openBrowser from 'open';
|
|
7
8
|
import { cleanupPluginState, ensureCleanPluginState } from './plugin-lifecycle.js';
|
|
8
9
|
import { acquireSingleInstanceLock } from './single-instance-lock.js';
|
|
9
10
|
/**
|
|
@@ -21,8 +22,13 @@ import { acquireSingleInstanceLock } from './single-instance-lock.js';
|
|
|
21
22
|
* <pkg>/.next/standalone/apps/web/server.js ← Next.js standalone entry (bundled from apps/web/.next/standalone)
|
|
22
23
|
* <pkg>/.next/standalone/apps/web/.next/static/
|
|
23
24
|
* <pkg>/.next/standalone/node_modules/
|
|
24
|
-
* <pkg>/prisma/schema.prisma
|
|
25
|
-
* <pkg>/prisma
|
|
25
|
+
* <pkg>/dist/prisma/schema.prisma ← bundled from apps/server/prisma
|
|
26
|
+
* <pkg>/dist/prisma/migrations/**
|
|
27
|
+
* <pkg>/dist/prisma.config.ts ← passed via --config by dist/auto-migrate.js
|
|
28
|
+
* <pkg>/dist/scripts/monaco-editor.sh ← $EDITOR for Ctrl+G (resolved by dist/server/routes/terminal.js)
|
|
29
|
+
* <pkg>/dist/docs/ ← bundled from apps/docs/out (served on DOCS_PORT)
|
|
30
|
+
* <pkg>/dist/whisper-server/ ← bundled from apps/whisper-server
|
|
31
|
+
* <pkg>/dist/llm-server/ ← bundled from apps/llm-server
|
|
26
32
|
* <pkg>/tsunagi-marketplace/plugins/tsunagi-plugin/.claude-plugin/plugin.json
|
|
27
33
|
*/
|
|
28
34
|
// ---------------------------------------------------------------------------
|
|
@@ -58,7 +64,7 @@ const PACKAGE_ROOT = path.resolve(DIST_DIR, '..');
|
|
|
58
64
|
const AUTO_MIGRATE_JS = path.join(DIST_DIR, 'auto-migrate.js');
|
|
59
65
|
const FASTIFY_ENTRY_JS = path.join(DIST_DIR, 'server', 'index.js');
|
|
60
66
|
const NEXT_STANDALONE_ENTRY = path.join(PACKAGE_ROOT, '.next', 'standalone', 'apps', 'web', 'server.js');
|
|
61
|
-
const DOCS_DIR = path.join(
|
|
67
|
+
const DOCS_DIR = path.join(DIST_DIR, 'docs');
|
|
62
68
|
const DOCS_PORT = 2793;
|
|
63
69
|
const isDebug = !!process.env.TSUNAGI_DEBUG;
|
|
64
70
|
const isDocker = fs.existsSync('/.dockerenv');
|
|
@@ -257,8 +263,9 @@ Promise.all([pollHealth(Number(PORT)), pollHealth(Number(NEXT_PORT))]).then(() =
|
|
|
257
263
|
console.log(TSUNAGI_AA);
|
|
258
264
|
const url = `http://localhost:${PORT}`;
|
|
259
265
|
if (!isDocker) {
|
|
260
|
-
|
|
261
|
-
|
|
266
|
+
// macOS / Linux / WSL(Windows 側ブラウザ)の差異は open パッケージが吸収する。
|
|
267
|
+
// ブラウザを開けなくてもサーバーは継続する(URL は下で案内する)
|
|
268
|
+
openBrowser(url).catch(() => { });
|
|
262
269
|
}
|
|
263
270
|
console.log(`Open ${url}`);
|
|
264
271
|
if (docsServer) {
|
|
@@ -28,15 +28,16 @@ const EXPECTED_MODEL_BYTES = 17_200_000_000;
|
|
|
28
28
|
const STARTUP_TIMEOUT_MS = 90_000;
|
|
29
29
|
// クラッシュ時にエラーメッセージへ含めるstderrの上限文字数。
|
|
30
30
|
const STDERR_TAIL_MAX_CHARS = 4000;
|
|
31
|
-
//
|
|
32
|
-
//
|
|
33
|
-
//
|
|
34
|
-
// (apps/server/dist/lib → apps/server → apps → apps/llm-server,
|
|
35
|
-
// apps/cli/dist/server/lib → apps/cli/dist → apps/cli → apps/cli/llm-server)。
|
|
31
|
+
// このファイルの位置から llm-server を探す:
|
|
32
|
+
// npm配布物: apps/cli/dist/server/lib → 2階層上 → apps/cli/dist/llm-server
|
|
33
|
+
// dev/build: apps/server/{src,dist}/lib → 3階層上 → apps/llm-server
|
|
36
34
|
export function findLlmServerDir() {
|
|
37
35
|
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
38
|
-
const
|
|
39
|
-
|
|
36
|
+
const candidates = [
|
|
37
|
+
path.join(here, '..', '..', 'llm-server'),
|
|
38
|
+
path.join(here, '..', '..', '..', 'llm-server'),
|
|
39
|
+
];
|
|
40
|
+
return candidates.find((c) => fs.existsSync(path.join(c, 'run.sh'))) ?? null;
|
|
40
41
|
}
|
|
41
42
|
function venvPython() {
|
|
42
43
|
return path.join(VENV_DIR, 'bin', 'python3');
|
|
@@ -22,15 +22,16 @@ const EXPECTED_MODEL_BYTES = 1_614_000_000;
|
|
|
22
22
|
const STARTUP_TIMEOUT_MS = 60_000;
|
|
23
23
|
// クラッシュ時にエラーメッセージへ含めるstderrの上限文字数。
|
|
24
24
|
const STDERR_TAIL_MAX_CHARS = 4000;
|
|
25
|
-
//
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
// (apps/server/dist/lib → apps/server → apps → apps/whisper-server,
|
|
29
|
-
// apps/cli/dist/server/lib → apps/cli/dist → apps/cli → apps/cli/whisper-server)。
|
|
25
|
+
// このファイルの位置から whisper-server を探す:
|
|
26
|
+
// npm配布物: apps/cli/dist/server/lib → 2階層上 → apps/cli/dist/whisper-server
|
|
27
|
+
// dev/build: apps/server/{src,dist}/lib → 3階層上 → apps/whisper-server
|
|
30
28
|
export function findWhisperServerDir() {
|
|
31
29
|
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
32
|
-
const
|
|
33
|
-
|
|
30
|
+
const candidates = [
|
|
31
|
+
path.join(here, '..', '..', 'whisper-server'),
|
|
32
|
+
path.join(here, '..', '..', '..', 'whisper-server'),
|
|
33
|
+
];
|
|
34
|
+
return candidates.find((c) => fs.existsSync(path.join(c, 'run.sh'))) ?? null;
|
|
34
35
|
}
|
|
35
36
|
function venvPython() {
|
|
36
37
|
return path.join(VENV_DIR, 'bin', 'python3');
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as fs from 'fs/promises';
|
|
2
2
|
import * as os from 'os';
|
|
3
3
|
import * as path from 'path';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
4
5
|
import { ptyManager } from '../pty-manager.js';
|
|
5
6
|
import { prisma } from '../lib/db.js';
|
|
6
7
|
import { getWorktreePath } from '../lib/worktree-manager.js';
|
|
@@ -9,8 +10,11 @@ import { ensureClaudeOnboardingCompleted, removeLocalModelFromUserSettings, } fr
|
|
|
9
10
|
import { LOCAL_LLM_UNSET_ENV_KEYS, LOCAL_MODEL_ALIAS, buildLocalLlmEnv, } from '../lib/local-llm-env.js';
|
|
10
11
|
import { ensureActiveLoaded, getLocalLlmSettings } from '../lib/local-llm.js';
|
|
11
12
|
import { LOCAL_LLM_PROXY_URL, buildClaudeCommand, isLocalLlmMode } from '../lib/claude-command.js';
|
|
12
|
-
//
|
|
13
|
-
|
|
13
|
+
// このファイル基準で解決する(cwd 非依存):
|
|
14
|
+
// dev: apps/server/src/routes → apps/server/scripts
|
|
15
|
+
// build: apps/server/dist/routes → apps/server/scripts
|
|
16
|
+
// npm bundle: <pkg>/dist/server/routes → <pkg>/dist/scripts
|
|
17
|
+
const TSUNAGI_EDITOR_PATH = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../scripts/monaco-editor.sh');
|
|
14
18
|
// Fastify(API) の公開ポート。index.ts と同じ既定値・同じ環境変数(TSUNAGI_SERVER_PORT)を見る。
|
|
15
19
|
// monaco-editor.sh など PTY 内のプロセスが API を叩く際の同一ホスト向けベース URL に使う。
|
|
16
20
|
const SERVER_PORT = Number(process.env.TSUNAGI_SERVER_PORT) || 2791;
|