@minimalcorp/tsunagi 0.1.37 → 0.1.38

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 (49) hide show
  1. package/.next/standalone/apps/web/.next/BUILD_ID +1 -1
  2. package/.next/standalone/apps/web/.next/build-manifest.json +3 -3
  3. package/.next/standalone/apps/web/.next/prerender-manifest.json +3 -3
  4. package/.next/standalone/apps/web/.next/server/app/_global-error.html +1 -1
  5. package/.next/standalone/apps/web/.next/server/app/_global-error.rsc +1 -1
  6. package/.next/standalone/apps/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  7. package/.next/standalone/apps/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  8. package/.next/standalone/apps/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  9. package/.next/standalone/apps/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  10. package/.next/standalone/apps/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  11. package/.next/standalone/apps/web/.next/server/app/_not-found.html +1 -1
  12. package/.next/standalone/apps/web/.next/server/app/_not-found.rsc +1 -1
  13. package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  14. package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  15. package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  16. package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  17. package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  18. package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  19. package/.next/standalone/apps/web/.next/server/app/index.html +1 -1
  20. package/.next/standalone/apps/web/.next/server/app/index.rsc +1 -1
  21. package/.next/standalone/apps/web/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  22. package/.next/standalone/apps/web/.next/server/app/index.segments/_full.segment.rsc +1 -1
  23. package/.next/standalone/apps/web/.next/server/app/index.segments/_head.segment.rsc +1 -1
  24. package/.next/standalone/apps/web/.next/server/app/index.segments/_index.segment.rsc +1 -1
  25. package/.next/standalone/apps/web/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  26. package/.next/standalone/apps/web/.next/server/app/settings.html +1 -1
  27. package/.next/standalone/apps/web/.next/server/app/settings.rsc +1 -1
  28. package/.next/standalone/apps/web/.next/server/app/settings.segments/_full.segment.rsc +1 -1
  29. package/.next/standalone/apps/web/.next/server/app/settings.segments/_head.segment.rsc +1 -1
  30. package/.next/standalone/apps/web/.next/server/app/settings.segments/_index.segment.rsc +1 -1
  31. package/.next/standalone/apps/web/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
  32. package/.next/standalone/apps/web/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +1 -1
  33. package/.next/standalone/apps/web/.next/server/app/settings.segments/settings.segment.rsc +1 -1
  34. package/.next/standalone/apps/web/.next/server/app/tasks/[id]/page_client-reference-manifest.js +1 -1
  35. package/.next/standalone/apps/web/.next/server/chunks/ssr/apps_web_src_app_tasks_[id]_page_tsx_0jshsm2._.js +2 -2
  36. package/.next/standalone/apps/web/.next/server/middleware-build-manifest.js +3 -3
  37. package/.next/standalone/apps/web/.next/server/pages/404.html +1 -1
  38. package/.next/standalone/apps/web/.next/server/pages/500.html +1 -1
  39. package/.next/standalone/apps/web/.next/server/server-reference-manifest.js +1 -1
  40. package/.next/standalone/apps/web/.next/server/server-reference-manifest.json +1 -1
  41. package/.next/standalone/apps/web/.next/static/chunks/{094hkpbli0k9s.js → 0p.4ej_8gk7m7.js} +2 -2
  42. package/dist/server/lib/repositories/task.js +3 -0
  43. package/dist/server/lib/services/task-service.js +1 -3
  44. package/dist/server/routes/terminal.js +24 -17
  45. package/npm-shrinkwrap.json +2 -2
  46. package/package.json +1 -1
  47. /package/.next/standalone/apps/web/.next/static/{otC3BXpS9D6HI8k0EQ2ZH → TJDp2MIqJ14hotMmE5sIo}/_buildManifest.js +0 -0
  48. /package/.next/standalone/apps/web/.next/static/{otC3BXpS9D6HI8k0EQ2ZH → TJDp2MIqJ14hotMmE5sIo}/_clientMiddlewareManifest.js +0 -0
  49. /package/.next/standalone/apps/web/.next/static/{otC3BXpS9D6HI8k0EQ2ZH → TJDp2MIqJ14hotMmE5sIo}/_ssgManifest.js +0 -0
@@ -1,4 +1,5 @@
1
1
  import { prisma } from '../db.js';
2
+ import { getWorktreePath } from '../worktree-manager.js';
2
3
  // タスク一覧取得(deleted: false のみデフォルト)
3
4
  export async function getTasks(filter) {
4
5
  const tasks = await prisma.task.findMany({
@@ -226,6 +227,8 @@ function mapTask(task) {
226
227
  baseBranch: task.baseBranch,
227
228
  repoId: task.repoId,
228
229
  worktreeStatus: task.worktreeStatus,
230
+ // 派生値。REST / Socket.IO の全経路で必ず含める(欠けるとタブの cwd が既定ディレクトリに化ける)
231
+ worktreePath: getWorktreePath(task.owner, task.repo, task.branch),
229
232
  pullRequestUrl: task.pullRequestUrl ?? undefined,
230
233
  effort: task.effort ?? undefined,
231
234
  order: task.order,
@@ -88,9 +88,7 @@ export async function getTask(identifier) {
88
88
  if (!task) {
89
89
  throw new TaskServiceError('Task not found', 'TASK_NOT_FOUND');
90
90
  }
91
- // worktreePathを付与
92
- const worktreePath = worktreeManager.getWorktreePath(task.owner, task.repo, task.branch);
93
- return { ...task, worktreePath };
91
+ return task;
94
92
  }
95
93
  /**
96
94
  * タスクを作成
@@ -3,6 +3,7 @@ import * as os from 'os';
3
3
  import * as path from 'path';
4
4
  import { ptyManager } from '../pty-manager.js';
5
5
  import { prisma } from '../lib/db.js';
6
+ import { getWorktreePath } from '../lib/worktree-manager.js';
6
7
  import { getEnv } from '../lib/repositories/environment.js';
7
8
  import { ensureClaudeOnboardingCompleted } from '../lib/claude-config-guard.js';
8
9
  import { OLLAMA_UNSET_ENV_KEYS, buildOllamaEnv, getOllamaSettings, } from '../lib/ollama-settings.js';
@@ -183,36 +184,42 @@ export async function terminalRoutes(fastify) {
183
184
  fastify.post('/terminal/sessions', async (request, reply) => {
184
185
  const { cwd, env, sessionId: requestedSessionId, command } = request.body ?? {};
185
186
  const sessionId = requestedSessionId ?? crypto.randomUUID();
187
+ // 既存セッションが生きていれば再利用
188
+ const existing = ptyManager.getSession(sessionId);
189
+ if (existing) {
190
+ fastify.log.info({ sessionId }, 'Reusing existing PTY session');
191
+ return reply.status(200).send({ sessionId, reused: true });
192
+ }
193
+ // sessionId(=tab_id) から Task を解決する。cwd / env の決定に使う。
194
+ // Taskに紐づかないタブは Tab レコードが存在しないため null になる。
195
+ const tab = await prisma.tab
196
+ .findUnique({ where: { tabId: sessionId }, include: { task: true } })
197
+ .catch((err) => {
198
+ fastify.log.warn({ err, sessionId }, 'Failed to load tab');
199
+ return null;
200
+ });
201
+ // cwd は Task があればサーバー側で worktree パスを導出する(クライアントの state に依存しない)。
202
+ // クライアント指定の cwd は Task に紐づかないタブのフォールバックとしてのみ使う。
186
203
  const defaultDir = path.join(os.homedir(), '.tsunagi', 'workspaces');
187
- let workingDir = cwd ?? defaultDir;
204
+ let workingDir = tab
205
+ ? getWorktreePath(tab.task.owner, tab.task.repo, tab.task.branch)
206
+ : (cwd ?? defaultDir);
188
207
  // cwd が存在するか確認、なければデフォルトにフォールバック
189
208
  try {
190
209
  await fs.access(workingDir);
191
210
  }
192
211
  catch {
193
- fastify.log.warn({ workingDir }, 'cwd does not exist, falling back to default');
212
+ fastify.log.warn({ sessionId, workingDir }, 'cwd does not exist, falling back to default');
194
213
  workingDir = defaultDir;
195
214
  }
196
215
  // デフォルトディレクトリが存在しない場合も作成する
197
216
  await fs.mkdir(workingDir, { recursive: true });
198
- // 既存セッションが生きていれば再利用
199
- const existing = ptyManager.getSession(sessionId);
200
- if (existing) {
201
- fastify.log.info({ sessionId }, 'Reusing existing PTY session');
202
- return reply.status(200).send({ sessionId, reused: true });
203
- }
204
217
  try {
205
- // sessionId(=tab_id) から Task(owner/repo) を解決し、repo スコープまで階層マージした
206
- // 環境変数を取得する(global → owner → repo、後勝ちで上書き)。
207
- // Plannerタブ等、Taskに紐づかないタブは Tab レコードが存在しないため global のみになる。
218
+ // repo スコープまで階層マージした環境変数を取得する(global → owner → repo、後勝ちで上書き)。
219
+ // Taskに紐づかないタブは global のみになる。
208
220
  let dbEnv = {};
209
- let tabMode;
221
+ const tabMode = tab?.mode;
210
222
  try {
211
- const tab = await prisma.tab.findUnique({
212
- where: { tabId: sessionId },
213
- include: { task: true },
214
- });
215
- tabMode = tab?.mode;
216
223
  dbEnv = tab ? await getEnv('repo', tab.task.owner, tab.task.repo) : await getEnv('global');
217
224
  fastify.log.info({ count: Object.keys(dbEnv).length, owner: tab?.task.owner, repo: tab?.task.repo }, 'Loaded env vars');
218
225
  }
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@minimalcorp/tsunagi",
3
- "version": "0.1.37",
3
+ "version": "0.1.38",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@minimalcorp/tsunagi",
9
- "version": "0.1.37",
9
+ "version": "0.1.38",
10
10
  "license": "SEE LICENSE IN LICENSE",
11
11
  "os": [
12
12
  "darwin",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@minimalcorp/tsunagi",
3
- "version": "0.1.37",
3
+ "version": "0.1.38",
4
4
  "description": "Multi-repo GitHub project management with Claude AI integration, designed for visualizing and controlling AI-driven development locally.",
5
5
  "keywords": [
6
6
  "tsunagi",