@minimalcorp/tsunagi 0.3.3 → 0.4.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 (144) 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/page_client-reference-manifest.js +1 -1
  12. package/.next/standalone/apps/web/.next/server/app/_not-found.html +1 -1
  13. package/.next/standalone/apps/web/.next/server/app/_not-found.rsc +2 -2
  14. package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  15. package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  16. package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  17. package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  18. package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  19. package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  20. package/.next/standalone/apps/web/.next/server/app/index.html +1 -1
  21. package/.next/standalone/apps/web/.next/server/app/index.rsc +3 -3
  22. package/.next/standalone/apps/web/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  23. package/.next/standalone/apps/web/.next/server/app/index.segments/_full.segment.rsc +3 -3
  24. package/.next/standalone/apps/web/.next/server/app/index.segments/_head.segment.rsc +1 -1
  25. package/.next/standalone/apps/web/.next/server/app/index.segments/_index.segment.rsc +2 -2
  26. package/.next/standalone/apps/web/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  27. package/.next/standalone/apps/web/.next/server/app/page.js.nft.json +1 -1
  28. package/.next/standalone/apps/web/.next/server/app/page_client-reference-manifest.js +1 -1
  29. package/.next/standalone/apps/web/.next/server/app/settings/page.js.nft.json +1 -1
  30. package/.next/standalone/apps/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  31. package/.next/standalone/apps/web/.next/server/app/settings.html +1 -1
  32. package/.next/standalone/apps/web/.next/server/app/settings.rsc +3 -3
  33. package/.next/standalone/apps/web/.next/server/app/settings.segments/_full.segment.rsc +3 -3
  34. package/.next/standalone/apps/web/.next/server/app/settings.segments/_head.segment.rsc +1 -1
  35. package/.next/standalone/apps/web/.next/server/app/settings.segments/_index.segment.rsc +2 -2
  36. package/.next/standalone/apps/web/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
  37. package/.next/standalone/apps/web/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +2 -2
  38. package/.next/standalone/apps/web/.next/server/app/settings.segments/settings.segment.rsc +1 -1
  39. package/.next/standalone/apps/web/.next/server/app/tasks/[id]/page.js.nft.json +1 -1
  40. package/.next/standalone/apps/web/.next/server/app/tasks/[id]/page_client-reference-manifest.js +1 -1
  41. package/.next/standalone/apps/web/.next/server/chunks/ssr/_05n88to._.js +3 -0
  42. package/.next/standalone/apps/web/.next/server/chunks/ssr/_0g.cd6a._.js +2 -2
  43. package/.next/standalone/apps/web/.next/server/chunks/ssr/{_0kflgfj._.js → _0pw3_r_._.js} +3 -3
  44. package/.next/standalone/apps/web/.next/server/chunks/ssr/{_0g79jqo._.js → _0rb6-mo._.js} +3 -3
  45. package/.next/standalone/apps/web/.next/server/chunks/ssr/_0ts4rpp._.js +3 -0
  46. package/.next/standalone/apps/web/.next/server/chunks/ssr/apps_web_src_app_settings_page_tsx_0i6itlb._.js +2 -2
  47. package/.next/standalone/apps/web/.next/server/chunks/ssr/apps_web_src_app_tasks_[id]_page_tsx_0jshsm2._.js +3 -3
  48. package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_04pfam-._.js → node_modules_03-rvdo._.js} +1 -1
  49. package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0cv326~._.js → node_modules_06jdmu~._.js} +1 -1
  50. package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0a57phw._.js → node_modules_0925te2._.js} +2 -2
  51. package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0_huoqd._.js → node_modules_0e8uni7._.js} +1 -1
  52. package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0tod6y8._.js → node_modules_0h4h_aw._.js} +1 -1
  53. package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0h.vgyn._.js → node_modules_0nzbb9~._.js} +1 -1
  54. package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0oip5a1._.js → node_modules_0q8yuvq._.js} +1 -1
  55. package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_11-z65a._.js → node_modules_0r6t2tu._.js} +1 -1
  56. package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_09d2oqj._.js → node_modules_0t6ysh_._.js} +1 -1
  57. package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0krwgny._.js → node_modules_0vj~e_v._.js} +1 -1
  58. package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0sn0lqb._.js → node_modules_0vq~hzy._.js} +1 -1
  59. package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0l23gkf._.js → node_modules_0xzmx-x._.js} +1 -1
  60. package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0npujym._.js → node_modules_0yb2sh9._.js} +1 -1
  61. package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0q_5qo~._.js → node_modules_0yc~s8p._.js} +1 -1
  62. package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0q_xfyl._.js → node_modules_0zi-gfw._.js} +1 -1
  63. package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0ak_3rk._.js → node_modules_0zzdoud._.js} +1 -1
  64. package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0xp9nhx._.js → node_modules_0~aiu12._.js} +1 -1
  65. package/.next/standalone/apps/web/.next/server/middleware-build-manifest.js +3 -3
  66. package/.next/standalone/apps/web/.next/server/pages/404.html +1 -1
  67. package/.next/standalone/apps/web/.next/server/pages/500.html +1 -1
  68. package/.next/standalone/apps/web/.next/server/server-reference-manifest.js +1 -1
  69. package/.next/standalone/apps/web/.next/server/server-reference-manifest.json +1 -1
  70. package/.next/standalone/apps/web/.next/static/chunks/09b_3duxnyfto.js +7 -0
  71. package/.next/standalone/apps/web/.next/static/chunks/{0z60ewb40i2ce.js → 0gxhy80~c0gvp.js} +1 -1
  72. package/.next/standalone/apps/web/.next/static/chunks/0i9h-39w91ybd.js +6 -0
  73. package/.next/standalone/apps/web/.next/static/chunks/{0b90ys7wq-p.4.css → 0pm0knaijueoc.css} +1 -1
  74. package/.next/standalone/apps/web/.next/static/chunks/{0oricprxoxb_d.js → 0smdykrt42e.5.js} +10 -10
  75. package/.next/standalone/apps/web/.next/static/chunks/{149sia28cskw9.js → 0yp~t_.pozr-d.js} +6 -6
  76. package/.next/standalone/apps/web/.next/static/chunks/{0o6ggm7jrim25.js → 14zh2vf8ljbxo.js} +1 -1
  77. package/.next/standalone/apps/web/.next/static/chunks/{053h220fng_68.js → 1624992q-gpj2.js} +10 -10
  78. package/.next/standalone/apps/web/package.json +1 -0
  79. package/README.md +1 -1
  80. package/dist/app.js +3 -3
  81. package/dist/plugin-lifecycle.d.ts +5 -3
  82. package/dist/plugin-lifecycle.js +40 -16
  83. package/dist/prisma/migrations/20261011000000_add_codex_support/migration.sql +20 -0
  84. package/dist/prisma/schema.prisma +9 -5
  85. package/dist/server/generated/prisma/browser.d.ts +2 -2
  86. package/dist/server/generated/prisma/client.d.ts +2 -2
  87. package/dist/server/generated/prisma/internal/class.d.ts +4 -4
  88. package/dist/server/generated/prisma/internal/class.js +4 -4
  89. package/dist/server/generated/prisma/internal/prismaNamespace.d.ts +41 -39
  90. package/dist/server/generated/prisma/internal/prismaNamespace.js +4 -2
  91. package/dist/server/generated/prisma/internal/prismaNamespaceBrowser.d.ts +5 -3
  92. package/dist/server/generated/prisma/internal/prismaNamespaceBrowser.js +4 -2
  93. package/dist/server/generated/prisma/models/AgentProfile.d.ts +972 -0
  94. package/dist/server/generated/prisma/models/Tab.d.ts +36 -1
  95. package/dist/server/generated/prisma/models.d.ts +1 -1
  96. package/dist/server/index.js +2 -2
  97. package/dist/server/lib/agent-profiles.d.ts +43 -0
  98. package/dist/server/lib/agent-profiles.js +127 -0
  99. package/dist/server/lib/agents/claude.d.ts +2 -0
  100. package/dist/server/lib/agents/claude.js +130 -0
  101. package/dist/server/lib/agents/cli.d.ts +14 -0
  102. package/dist/server/lib/agents/cli.js +57 -0
  103. package/dist/server/lib/agents/codex.d.ts +2 -0
  104. package/dist/server/lib/agents/codex.js +285 -0
  105. package/dist/server/lib/agents/index.d.ts +11 -0
  106. package/dist/server/lib/agents/index.js +19 -0
  107. package/dist/server/lib/agents/login-callback.d.ts +11 -0
  108. package/dist/server/lib/agents/login-callback.js +47 -0
  109. package/dist/server/lib/agents/types.d.ts +77 -0
  110. package/dist/server/lib/agents/types.js +8 -0
  111. package/dist/server/lib/pty-env-sync.js +1 -1
  112. package/dist/server/lib/pty-launch.d.ts +8 -10
  113. package/dist/server/lib/pty-launch.js +20 -58
  114. package/dist/server/lib/repositories/task.js +1 -0
  115. package/dist/server/lib/tab-todos.d.ts +5 -0
  116. package/dist/server/lib/tab-todos.js +13 -0
  117. package/dist/server/pty-manager.d.ts +7 -2
  118. package/dist/server/pty-manager.js +13 -0
  119. package/dist/server/routes/agent-profiles.d.ts +2 -0
  120. package/dist/server/routes/agent-profiles.js +193 -0
  121. package/dist/server/routes/env.js +2 -2
  122. package/dist/server/routes/hooks.d.ts +4 -19
  123. package/dist/server/routes/hooks.js +83 -73
  124. package/dist/server/routes/mcp.js +2 -2
  125. package/dist/server/routes/onboarding.js +19 -10
  126. package/dist/server/routes/tasks.js +4 -4
  127. package/dist/server/routes/terminal.js +47 -34
  128. package/dist/with-plugin.js +3 -3
  129. package/npm-shrinkwrap.json +12 -12
  130. package/package.json +1 -1
  131. package/tsunagi-marketplace/codex/tsunagi-task.md +120 -0
  132. package/.next/standalone/apps/web/.next/server/chunks/ssr/_0hnxatt._.js +0 -3
  133. package/.next/standalone/apps/web/.next/server/chunks/ssr/_10gk93.._.js +0 -3
  134. package/.next/standalone/apps/web/.next/static/chunks/0crn03y2tj0lu.js +0 -6
  135. package/.next/standalone/apps/web/.next/static/chunks/0lvl3ec93cab_.js +0 -7
  136. package/dist/server/generated/prisma/models/ClaudeProfile.d.ts +0 -939
  137. package/dist/server/lib/claude-profiles.d.ts +0 -49
  138. package/dist/server/lib/claude-profiles.js +0 -168
  139. package/dist/server/routes/claude-profiles.d.ts +0 -2
  140. package/dist/server/routes/claude-profiles.js +0 -138
  141. /package/.next/standalone/apps/web/.next/static/{7x81GlNKt9yqIkeI7U1BX → ZcOuTrikuO_ZLaERk7FsW}/_buildManifest.js +0 -0
  142. /package/.next/standalone/apps/web/.next/static/{7x81GlNKt9yqIkeI7U1BX → ZcOuTrikuO_ZLaERk7FsW}/_clientMiddlewareManifest.js +0 -0
  143. /package/.next/standalone/apps/web/.next/static/{7x81GlNKt9yqIkeI7U1BX → ZcOuTrikuO_ZLaERk7FsW}/_ssgManifest.js +0 -0
  144. /package/dist/server/generated/prisma/models/{ClaudeProfile.js → AgentProfile.js} +0 -0
@@ -1,24 +1,33 @@
1
1
  import { isLocalLlmReady } from '../lib/local-llm.js';
2
- import { DEFAULT_CLAUDE_PROFILE, getClaudeAuthStatus, listClaudeProfiles, } from '../lib/claude-profiles.js';
3
- /** システム既定かいずれかの Claude プロファイルがログイン済みか */
4
- async function isClaudeLoggedIn() {
5
- if ((await getClaudeAuthStatus(DEFAULT_CLAUDE_PROFILE)).loggedIn)
2
+ import { AGENTS, getAgentAvailability } from '../lib/agents/index.js';
3
+ import { DEFAULT_PROFILE, getProfileAuthStatus, listProfiles } from '../lib/agent-profiles.js';
4
+ /** 導入済みのエージェントで、システム既定かいずれかのプロファイルがログイン済みか */
5
+ async function isAgentLoggedIn(agent) {
6
+ if (!(await getAgentAvailability(agent)).installed)
7
+ return false;
8
+ if ((await getProfileAuthStatus(agent, DEFAULT_PROFILE)).loggedIn)
6
9
  return true;
7
- const profiles = await listClaudeProfiles();
8
- const statuses = await Promise.all(profiles.map((p) => getClaudeAuthStatus(p.slug)));
10
+ const profiles = await listProfiles(agent);
11
+ const statuses = await Promise.all(profiles.map((p) => getProfileAuthStatus(agent, p.slug)));
9
12
  return statuses.some((status) => status.loggedIn);
10
13
  }
11
14
  export async function onboardingRoutes(fastify) {
12
15
  // GET /onboarding/status
13
16
  fastify.get('/onboarding/status', async (_request, reply) => {
14
17
  try {
15
- const [claudeLoggedIn, localLlmReady] = await Promise.all([
16
- isClaudeLoggedIn(),
17
- // 実験的機能のローカルLLM(Ollama / LM Studio)を設定済みなら、Claude にログインしていなくても claude を起動できる
18
+ const [loggedIn, localLlmReady] = await Promise.all([
19
+ Promise.all(AGENTS.map(async (agent) => [agent.id, await isAgentLoggedIn(agent)])),
20
+ // 実験的機能のローカルLLM(Ollama / LM Studio)を設定済みなら、ログインしていなくても claude を起動できる
18
21
  isLocalLlmReady(),
19
22
  ]);
23
+ const agentLoggedIn = Object.fromEntries(loggedIn);
24
+ const anyLoggedIn = loggedIn.some(([, value]) => value);
20
25
  return reply.status(200).send({
21
- data: { completed: claudeLoggedIn || localLlmReady, claudeLoggedIn, localLlmReady },
26
+ data: {
27
+ completed: anyLoggedIn || localLlmReady,
28
+ agentLoggedIn,
29
+ localLlmReady,
30
+ },
22
31
  });
23
32
  }
24
33
  catch (error) {
@@ -265,8 +265,8 @@ export async function tasksRoutes(fastify) {
265
265
  if (!(await worktreeManager.worktreeExists(task.owner, task.repo, task.branch))) {
266
266
  return reply.status(400).send({ error: 'Worktree not found' });
267
267
  }
268
- const isClaudeRunning = task.tabs.some((tab) => tab.status === 'running');
269
- if (isClaudeRunning) {
268
+ const isAgentRunning = task.tabs.some((tab) => tab.status === 'running');
269
+ if (isAgentRunning) {
270
270
  return reply.status(400).send({ error: 'Cannot rebase while Claude is running' });
271
271
  }
272
272
  const result = await worktreeManager.rebaseWorktree(task.owner, task.repo, task.branch, baseBranch);
@@ -335,8 +335,8 @@ export async function tasksRoutes(fastify) {
335
335
  try {
336
336
  const { id: taskId } = request.params;
337
337
  const requested = request.body?.mode;
338
- const mode = requested === 'terminal'
339
- ? 'terminal'
338
+ const mode = requested === 'terminal' || requested === 'codex'
339
+ ? requested
340
340
  : requested === 'local' || requested === 'ollama' || requested === 'lmstudio'
341
341
  ? 'local'
342
342
  : 'claude';
@@ -1,8 +1,8 @@
1
- import { ptyManager } from '../pty-manager.js';
1
+ import { isShellForeground, ptyManager } from '../pty-manager.js';
2
2
  import { prisma } from '../lib/db.js';
3
- import { ensureActiveLoaded } from '../lib/local-llm.js';
4
- import { buildClaudeCommand, isLocalLlmMode } from '../lib/claude-command.js';
5
- import { PtyLaunchError, prepareClaudeConfigForSession, resolvePtyLaunch, startPtySession, } from '../lib/pty-launch.js';
3
+ import { getAgentForMode } from '../lib/agents/index.js';
4
+ import { LOGIN_SESSION_PREFIX } from '../lib/agent-profiles.js';
5
+ import { PtyLaunchError, prepareAgentLaunchForSession, resolvePtyLaunch, startPtySession, } from '../lib/pty-launch.js';
6
6
  import { getEnvPending, initPtyEnvSync, respawnSessionNow } from '../lib/pty-env-sync.js';
7
7
  /**
8
8
  * 再接続時の画面復元用 scrollback から「端末への問い合わせ(クエリ)」シーケンスを除去する。
@@ -145,7 +145,7 @@ export async function terminalRoutes(fastify) {
145
145
  if (session.respawning)
146
146
  return;
147
147
  io.to(room).emit('exit', { exitCode });
148
- // Ctrl+C等でClaudeが強制終了した場合にclaudeStatusをidleにリセット
148
+ // Ctrl+C等でClaudeが強制終了した場合にagentStatusをidleにリセット
149
149
  // todos は残す(Claude 側の Task はセッションに永続化され、--resume 後も続きから使われる)
150
150
  io.to(room).emit('status-changed', { sessionId, status: 'idle' });
151
151
  prisma.tab
@@ -250,7 +250,7 @@ export async function terminalRoutes(fastify) {
250
250
  });
251
251
  // POST /terminal/sessions - セッション作成(または既存セッション再利用)
252
252
  fastify.post('/terminal/sessions', async (request, reply) => {
253
- const { cwd, env, sessionId: requestedSessionId, claude, command } = request.body ?? {};
253
+ const { cwd, env, sessionId: requestedSessionId, agent, claude, command } = request.body ?? {};
254
254
  const sessionId = requestedSessionId ?? crypto.randomUUID();
255
255
  // 既存セッションが生きていれば再利用
256
256
  const existing = ptyManager.getSession(sessionId);
@@ -258,6 +258,10 @@ export async function terminalRoutes(fastify) {
258
258
  fastify.log.info({ sessionId }, 'Reusing existing PTY session');
259
259
  return reply.status(200).send({ sessionId, reused: true });
260
260
  }
261
+ // ログイン用 PTY は作り直さない(無ければ終わっている。ログインコマンドの無いシェルを出さない)
262
+ if (sessionId.startsWith(LOGIN_SESSION_PREFIX)) {
263
+ return reply.status(404).send({ error: 'Login session has ended. Close and try again.' });
264
+ }
261
265
  const pending = pendingCreations.get(sessionId);
262
266
  const creation = pending ??
263
267
  (async () => {
@@ -265,7 +269,7 @@ export async function terminalRoutes(fastify) {
265
269
  const launch = await resolvePtyLaunch(sessionId, launchRequest);
266
270
  await startPtySession(sessionId, launch, {
267
271
  request: launchRequest,
268
- launchClaude: Boolean(claude),
272
+ launchAgent: Boolean(agent ?? claude),
269
273
  command,
270
274
  });
271
275
  })();
@@ -290,33 +294,42 @@ export async function terminalRoutes(fastify) {
290
294
  return reply.status(500).send({ error: message });
291
295
  }
292
296
  });
293
- // POST /terminal/sessions/:sessionId/claude - 既存 PTY で claude を(再)起動する
294
- // コマンドはタブの mode に応じてサーバーで組み立てる(ローカルLLMタブは引数が付くため)
295
- fastify.post('/terminal/sessions/:sessionId/claude', async (request, reply) => {
296
- const { sessionId } = request.params;
297
- const session = ptyManager.getSession(sessionId);
298
- if (!session) {
299
- return reply.status(404).send({ error: 'Session not found' });
300
- }
301
- const tab = await prisma.tab.findUnique({ where: { tabId: sessionId } }).catch(() => null);
302
- const mode = (tab?.mode ?? 'claude');
303
- if (isLocalLlmMode(mode)) {
304
- // 最初の発言を待たせないよう読み込みを始めておく(未設定等のエラーは中継口がタブに返す)
305
- ensureActiveLoaded().catch(() => undefined);
306
- }
307
- let command;
308
- try {
309
- command = await buildClaudeCommand(sessionId, mode);
310
- }
311
- catch (err) {
312
- return reply.status(400).send({ error: err instanceof Error ? err.message : String(err) });
313
- }
314
- // 環境変数の反映で PTY を作り直したときも claude を起動し直す
315
- session.options.launchClaude = true;
316
- await prepareClaudeConfigForSession(session);
317
- session.pty.write(`${command}\n`);
318
- return reply.status(204).send();
319
- });
297
+ // POST /terminal/sessions/:sessionId/agent - 既存 PTY でエージェントを(再)起動する
298
+ // コマンドはタブの mode に応じてサーバーで組み立てる(ローカルLLMタブは引数が付くため)。
299
+ // /claude は旧パス(互換のため残す)
300
+ for (const route of [
301
+ '/terminal/sessions/:sessionId/agent',
302
+ '/terminal/sessions/:sessionId/claude',
303
+ ]) {
304
+ fastify.post(route, async (request, reply) => {
305
+ const { sessionId } = request.params;
306
+ const session = ptyManager.getSession(sessionId);
307
+ if (!session) {
308
+ return reply.status(404).send({ error: 'Session not found' });
309
+ }
310
+ // エージェントなどが動いている間に書き込むと、そのコマンドの入力欄に入ってしまう
311
+ if (!isShellForeground(session)) {
312
+ return reply.status(409).send({
313
+ error: 'ターミナルで実行中のコマンド(エージェント等)を終了してから実行してください',
314
+ });
315
+ }
316
+ const tab = await prisma.tab.findUnique({ where: { tabId: sessionId } }).catch(() => null);
317
+ const mode = (tab?.mode ?? 'claude');
318
+ const agent = getAgentForMode(mode);
319
+ let command;
320
+ try {
321
+ command = await agent.buildCommand(sessionId, mode);
322
+ }
323
+ catch (err) {
324
+ return reply.status(400).send({ error: err instanceof Error ? err.message : String(err) });
325
+ }
326
+ // 環境変数の反映で PTY を作り直したときもエージェントを起動し直す
327
+ session.options.launchAgent = true;
328
+ await prepareAgentLaunchForSession(session, mode);
329
+ session.pty.write(`${command}\n`);
330
+ return reply.status(204).send();
331
+ });
332
+ }
320
333
  // POST /terminal/sessions/:sessionId/respawn - 環境変数の変更を今すぐ反映する(PTY を作り直す)
321
334
  fastify.post('/terminal/sessions/:sessionId/respawn', async (request, reply) => {
322
335
  const ok = await respawnSessionNow(request.params.sessionId);
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { spawn } from 'node:child_process';
3
- import { assertClaudeSupportsPluginDirs, getPluginDir, removeLegacyPluginInstall, } from './plugin-lifecycle.js';
3
+ import { assertAgentCliAvailable, getPluginDir, removeLegacyPluginInstall, } from './plugin-lifecycle.js';
4
4
  /**
5
5
  * Development wrapper:
6
6
  * 1. Pass the Claude Code plugin dir to the server via TSUNAGI_PLUGIN_DIR
@@ -15,8 +15,8 @@ if (mode !== 'dev' && mode !== 'start') {
15
15
  console.error('Usage: tsx src/with-plugin.ts <dev|start>');
16
16
  process.exit(1);
17
17
  }
18
- assertClaudeSupportsPluginDirs();
19
- removeLegacyPluginInstall();
18
+ if (assertAgentCliAvailable().claude)
19
+ removeLegacyPluginInstall();
20
20
  // 子プロセス(concurrently → server)に継承させる
21
21
  process.env.TSUNAGI_PLUGIN_DIR = getPluginDir();
22
22
  const webCmd = mode === 'dev'
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@minimalcorp/tsunagi",
3
- "version": "0.3.3",
3
+ "version": "0.4.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@minimalcorp/tsunagi",
9
- "version": "0.3.3",
9
+ "version": "0.4.0",
10
10
  "license": "SEE LICENSE IN LICENSE",
11
11
  "os": [
12
12
  "darwin",
@@ -235,9 +235,9 @@
235
235
  }
236
236
  },
237
237
  "node_modules/@fastify/multipart": {
238
- "version": "10.1.2",
239
- "resolved": "https://registry.npmjs.org/@fastify/multipart/-/multipart-10.1.2.tgz",
240
- "integrity": "sha512-WHsqW5ffDXCbXXtdBQDryxu58fQvFPVGh4E4MlCO6hwCLNm0lYTCS6GKXUw2P64REDoECUNpMVvtMMstdIyBjQ==",
238
+ "version": "10.1.3",
239
+ "resolved": "https://registry.npmjs.org/@fastify/multipart/-/multipart-10.1.3.tgz",
240
+ "integrity": "sha512-nLZopLYgAj+0BhcSm6upfT5x4fwKDfGlJ51U4Bkg1HknFaO6LjfCc2prqbXMNjRdM0cCVzp3L4bjkvfuuTLxJg==",
241
241
  "funding": [
242
242
  {
243
243
  "type": "github",
@@ -278,9 +278,9 @@
278
278
  }
279
279
  },
280
280
  "node_modules/@fastify/reply-from": {
281
- "version": "12.6.5",
282
- "resolved": "https://registry.npmjs.org/@fastify/reply-from/-/reply-from-12.6.5.tgz",
283
- "integrity": "sha512-/4MP+iF6T2+UBEmVYveMU2Tbx3lR1Q7xsDo8GAGjNeQrLF/JqNRlOMhOksh8fXBA47KI8ifsIlUXYdMOUXGZNQ==",
281
+ "version": "12.7.1",
282
+ "resolved": "https://registry.npmjs.org/@fastify/reply-from/-/reply-from-12.7.1.tgz",
283
+ "integrity": "sha512-F26CIcy6PKqyhsTwQI7p5UwH5vrv2yz7BOqAnkHTmNVSU9J+vmRh8CNfOk/ZD8AjcKbiyRkNl6Lb3AuJdxIADQ==",
284
284
  "funding": [
285
285
  {
286
286
  "type": "github",
@@ -295,7 +295,7 @@
295
295
  "dependencies": {
296
296
  "@fastify/error": "^4.0.0",
297
297
  "end-of-stream": "^1.4.4",
298
- "fast-content-type-parse": "^3.0.0",
298
+ "fast-content-type-parse": "^4.0.0",
299
299
  "fast-querystring": "^1.1.2",
300
300
  "fastify-plugin": "^6.0.0",
301
301
  "toad-cache": "^3.7.0",
@@ -2280,9 +2280,9 @@
2280
2280
  }
2281
2281
  },
2282
2282
  "node_modules/fast-content-type-parse": {
2283
- "version": "3.0.0",
2284
- "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-3.0.0.tgz",
2285
- "integrity": "sha512-ZvLdcY8P+N8mGQJahJV5G4U88CSvT1rP8ApL6uETe88MBXrBHAkZlSEySdUlyztF7ccb+Znos3TFqaepHxdhBg==",
2283
+ "version": "4.0.0",
2284
+ "resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-4.0.0.tgz",
2285
+ "integrity": "sha512-rvu3AY9s3EsDXSDUWzFU5M9/fDpjAUwyIkDR9VrwZA3H9J5f4ymkT0J4iWw9iLaMvFVwsYTGFClUgy9VIvnabA==",
2286
2286
  "funding": [
2287
2287
  {
2288
2288
  "type": "github",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@minimalcorp/tsunagi",
3
- "version": "0.3.3",
3
+ "version": "0.4.0",
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",
@@ -0,0 +1,120 @@
1
+ # tsunagi タスク管理
2
+
3
+ このセッションは tsunagi(タスク管理ツール)のタスクに紐づいている。タスクの検索・詳細取得・作成・更新・削除、現在担当タスクの特定、実装計画の description への記録には tsunagi MCP の `tsunagi_*` ツールを使う。計画の対話を開始した時、実装を開始した時、実装・検証が完了した時、PR がマージされた時に、必ずこの手順でステータスを更新すること。
4
+
5
+ ## ステータスの自動更新(必須)
6
+
7
+ 作業フェーズが変わったら、**即座に** `tsunagi_update_task` でステータスを更新する。
8
+
9
+ | ステータス | 遷移タイミング |
10
+ | ----------- | ---------------------------------------------- |
11
+ | `backlog` | タスク作成時のデフォルト |
12
+ | `planning` | ユーザーと計画の対話を開始した時点 |
13
+ | `coding` | ユーザーが実装を指示、または実装を開始した時点 |
14
+ | `reviewing` | 全ての実装・検証が完了した時点 |
15
+ | `done` | PRがマージされた時点 |
16
+
17
+ 遷移は必ず順方向: backlog → planning → coding → reviewing → done
18
+
19
+ ## 実装開始時の計画作成(必須)
20
+
21
+ `coding` に遷移したら、**即座に** 組み込みの `update_plan` ツールで実装ステップを登録する。これにより tsunagi UI にプログレスバーが表示される。
22
+
23
+ ### 手順
24
+
25
+ 1. `tsunagi_update_task(status: "coding")` の直後に、`update_plan` で全ステップを登録する(各ステップの `status` は `pending`)
26
+ 2. 各ステップは完了判断が明確な作業単位にする
27
+ - 例: 「○○ファイルを修正」「マイグレーション作成・適用」「lint/type-check を通す」「動作確認」
28
+ 3. 着手時・完了時に `update_plan` で該当ステップの status を `in_progress` → `completed` に更新する(`update_plan` は毎回計画全体を渡す)
29
+ 4. 作業中に追加ステップが判明した場合は計画に追加し、不要になったステップは計画から外す
30
+
31
+ ### 語彙の使い分け(混同注意)
32
+
33
+ | 対象 | 使うツール | status 語彙 |
34
+ | -------------- | ------------------------ | -------------------------------------- |
35
+ | tsunagi タスク | `tsunagi_update_task` | backlog/planning/coding/reviewing/done |
36
+ | 計画 (進捗) | `update_plan` (組み込み) | pending/in_progress/completed |
37
+
38
+ tsunagi タスクの status に `in_progress` を渡してはいけない(「よくある間違い」表参照)。逆に計画の進捗管理は組み込み `update_plan` で行う。
39
+
40
+ ## 現在のタスクを特定する
41
+
42
+ タスク操作には `id`, `session_id`, `cwd` のいずれかでタスクを指定する。
43
+ 優先順位: id > session_id > cwd
44
+
45
+ - **推奨**: 環境変数 `TSUNAGI_SESSION_ID`(シェルで `echo $TSUNAGI_SESSION_ID`)を `session_id` パラメータとして渡す
46
+ - **フォールバック**: `TSUNAGI_SESSION_ID` が未設定の場合、CWDを `cwd` パラメータとして渡す
47
+
48
+ ## タスク操作
49
+
50
+ | 操作 | ツール | タスク指定 | その他パラメータ |
51
+ | -------- | ------------------- | ----------------------- | ---------------------------------------------------------------------------- |
52
+ | 一覧取得 | tsunagi_list_tasks | 不要 | owner?, repo?, status?(string \| string[]) |
53
+ | 詳細取得 | tsunagi_get_task | id or session_id or cwd | - |
54
+ | 作成 | tsunagi_create_task | 不要 | owner, repo, title, branch?, description?, effort?, order?, status? |
55
+ | 更新 | tsunagi_update_task | id or session_id or cwd | title?, description?, status?, effort?, order?, baseBranch?, pullRequestUrl? |
56
+ | 削除 | tsunagi_delete_task | id or session_id or cwd | - |
57
+
58
+ ## タスク一覧取得のガイドライン
59
+
60
+ `tsunagi_list_tasks` の `status` は単一値または配列で指定可能。ユースケースに応じて適切なステータスセットを指定すること。
61
+
62
+ ### 並び替え・棚卸しは `tsunagi-task-curator` subagent に委譲する
63
+
64
+ ユーザーから以下のような依頼があった場合、**メインセッションで直接 `tsunagi_list_tasks` を呼ばず**、`spawn_agent` で `agent_type: "tsunagi-task-curator"` の subagent を起動すること:
65
+
66
+ - 「優先度を並び替えて」「順序を見直して」「priorityを変更して」
67
+ - 「棚卸しして」「backlogを整理して」「不要なタスクを削除して」「重複を確認して」
68
+
69
+ 重いdescription(PRD)読み込みはsubagent内に閉じ込められ、メインセッションには圧縮された判断結果(提案 + 根拠1行 + confidence)のみが返却される。
70
+
71
+ subagentの返却を受けた後、メインセッションの役割:
72
+
73
+ 1. `confidence: "high"` の提案は **自動的に実行**(`tsunagi_update_task` で order 更新、`tsunagi_delete_task` で削除 等)
74
+ 2. `needs_user_input` に含まれる項目のみユーザーに確認
75
+ 3. 実行結果をユーザーに簡潔に報告
76
+
77
+ ### subagent を使わず直接 `tsunagi_list_tasks` を呼んでよいケース
78
+
79
+ 以下のような軽い参照用途では直接呼び出してよい:
80
+
81
+ - 特定ステータスの件数確認(例: 現在 coding 中のタスクを確認)
82
+ - 特定リポジトリのタスク一覧表示(`owner` + `repo` 指定)
83
+ - ユーザーが明示的に全件リストを要求した場合
84
+
85
+ これらのケースでも、必要なければ `status` を指定して対象を絞ること。
86
+
87
+ ## ブランチ命名規則
88
+
89
+ `branch`を省略するとtitleから自動生成されるが、短縮された意味不明な名前になりがちなため、**必ず`branch`を明示的に指定する**。
90
+
91
+ - タスク内容が一目でわかる具体的な名前にする
92
+ - `feat/`、`fix/`等のprefixを使用する
93
+ - 例: `feat/task-update-socket-notification`、`fix/duplicate-toast-on-create`
94
+
95
+ ## 実装計画の管理
96
+
97
+ 実装計画はタスクの `description` にPRD(Product Requirements Document)形式のmarkdownで記載・管理する。
98
+ ファイルシステム上に計画ファイルを作成しない。
99
+ `planning` 完了時点で `description` は完成していること。`coding` 中に計画変更があれば随時更新する。
100
+
101
+ ## よくある間違い
102
+
103
+ | ❌ 誤り | ✅ 正しい | 備考 |
104
+ | ----------------------------------------- | ------------------------------------------------------- | ------------------------------------------- |
105
+ | `taskId: "..."` | `id: "..."` | パラメータ名は `id`(camelCase ではない) |
106
+ | `sessionId: "..."` | `session_id: "..."` | snake_case |
107
+ | `status: "in_progress"` | `status: "coding"` | 組み込み update_plan とは別語彙 |
108
+ | `status: "completed"` | `status: "done"` | |
109
+ | `status: "todo"` | `status: "backlog"` | |
110
+ | 識別子なしで update / get / delete を呼ぶ | `id` / `session_id` / `cwd` のいずれか1つ以上を必ず指定 | 全て省略すると `Identifier required` エラー |
111
+
112
+ ### ステータス語彙の混同に注意
113
+
114
+ 組み込みの `update_plan` ツール(`pending` / `in_progress` / `completed`)と、tsunagi の `tsunagi_update_task`(`backlog` / `planning` / `coding` / `reviewing` / `done`)は**完全に別物**。
115
+
116
+ ## 注意事項
117
+
118
+ - `id`, `session_id`, `cwd` は優先順位に従い最初にマッチしたものでタスクを解決する
119
+ - 削除は論理削除(UIから復元する手段は提供されていない)
120
+ - `tsunagi_create_task` が失敗した場合、エラー内容をユーザーに報告するだけでよい(原因の深掘り不要)
@@ -1,3 +0,0 @@
1
- module.exports=[68177,a=>{"use strict";var b=a.i(84991),c=a.i(2840),d=a.i(187),e=a.i(760);let f=(0,d.cva)("group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-full border border-transparent px-2 py-0.5 text-[0.625rem] font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-2.5!",{variants:{variant:{default:"bg-primary text-primary-foreground [a]:hover:bg-primary/80",secondary:"bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80",destructive:"bg-destructive/10 text-destructive focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:bg-destructive/20",outline:"border-border bg-input/20 text-foreground dark:bg-input/30 [a]:hover:bg-muted [a]:hover:text-muted-foreground",ghost:"hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50",link:"text-primary underline-offset-4 hover:underline"}},defaultVariants:{variant:"default"}});a.s(["Badge",0,function({className:a,variant:d="default",render:g,...h}){var i;return i={defaultTagName:"span",props:(0,b.mergeProps)({className:(0,e.cn)(f({variant:d}),a)},h),render:g,state:{slot:"badge",variant:d}},(0,c.useRenderElement)(i.defaultTagName??"div",i,i)}],68177)},63588,a=>{"use strict";let b=(0,a.i(60137).default)("message-square",[["path",{d:"M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z",key:"18887p"}]]);a.s(["MessageSquare",0,b],63588)},62722,a=>{"use strict";let b=(0,a.i(60137).default)("circle-x",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m15 9-6 6",key:"1uzhvr"}],["path",{d:"m9 9 6 6",key:"z0biqf"}]]);a.s(["XCircle",0,b],62722)},88381,a=>{"use strict";var b=a.i(72131),c=a.i(83915),d=a.i(91399);a.s(["useTaskEvents",0,function(a){let e=(0,b.useRef)(null),f=(0,b.useRef)(a);(0,b.useLayoutEffect)(()=>{f.current=a}),(0,b.useEffect)(()=>{let a=(0,c.io)((0,d.getServerUrl)(),{transports:["polling","websocket"]});return e.current=a,a.on("task:created",({task:a,warnings:b})=>{f.current.onTaskCreated(a,b??[])}),a.on("task:updated",({task:a})=>{f.current.onTaskUpdated(a)}),a.on("task:deleted",({taskId:a})=>{f.current.onTaskDeleted(a)}),a.on("task:tabs-changed",({task:a})=>{f.current.onTaskTabsChanged?.(a)}),()=>{a.disconnect(),e.current=null}},[])}])},13425,a=>{"use strict";var b=a.i(72131),c=a.i(83915),d=a.i(91399);a.s(["useTabStatusEvents",0,function(a,e){let f=(0,b.useRef)(null),g=(0,b.useRef)(new Set),h=(0,b.useRef)(e);(0,b.useEffect)(()=>{h.current=e});let i=(0,b.useCallback)(()=>{if(!f.current){let a=(0,c.io)((0,d.getServerUrl)(),{transports:["polling","websocket"]});f.current=a,a.on("status-changed",({sessionId:a,status:b})=>{let c=function(a){switch(a){case"running":return"running";case"waiting":return"waiting";case"success":return"success";case"failure":case"error":return"error";case"idle":return"idle";default:return null}}(b);null!==c&&h.current(a,c)}),a.on("connect",()=>{for(let b of g.current)a.emit("join",{room:b,mode:"subscribe"})})}return f.current},[]);(0,b.useEffect)(()=>{if(0===a.length)return;let b=i();for(let c of a){let a=`tab:${c}`;g.current.has(a)||(b.emit("join",{room:a,mode:"subscribe"}),g.current.add(a))}let c=new Set(a);for(let a of g.current){let d=a.replace("tab:","");c.has(d)||(b.emit("leave",{room:a}),g.current.delete(a))}},[a,i]),(0,b.useEffect)(()=>{let a=g.current;return()=>{f.current?.disconnect(),f.current=null,a.clear()}},[])}])},11081,93886,a=>{"use strict";function b(a){return"success"===a||"error"===a||"running"!==a&&"idle"!==a&&void 0}function c(a){let b=a.tabs??[];if(0===b.length||b.some(a=>"running"===a.status))return null;if(b.some(a=>"waiting"===a.status))return"waiting";let c=b.filter(a=>a.unread);return c.some(a=>"error"===a.status)?"error":c.some(a=>"success"===a.status)?"success":null}a.s(["activityKind",0,function(a){return(a.tabs??[]).some(a=>"running"===a.status)?"running":c(a)},"hasUnreadResult",0,function(a){return null!==c(a)},"unreadForStatus",0,b,"unreadKind",0,c],11081);var d=a.i(72131),e=a.i(91399),f=a.i(88381),g=a.i(13425);a.s(["useLiveTasks",0,function(a={}){let[c,h]=(0,d.useState)([]),[i,j]=(0,d.useState)(!0),k=(0,d.useRef)(a),l=(0,d.useRef)(c);(0,d.useEffect)(()=>{k.current=a,l.current=c});let m=(0,d.useCallback)(async()=>{j(!0);try{let a=await fetch((0,e.apiUrl)("/api/tasks"));if(!a.ok)throw Error("Failed to fetch tasks");let b=await a.json();h(b.data.tasks)}catch(a){console.error("Failed to load tasks:",a)}finally{j(!1)}},[]);(0,d.useEffect)(()=>{m()},[m]);let n=(0,d.useMemo)(()=>c.flatMap(a=>(a.tabs??[]).map(a=>a.tab_id)),[c]);return(0,g.useTabStatusEvents)(n,(a,c)=>{let d=b(c);h(b=>b.map(b=>({...b,tabs:(b.tabs??[]).map(b=>b.tab_id===a?{...b,status:c,...void 0!==d&&{unread:d}}:b)})))}),(0,f.useTaskEvents)({onTaskCreated:(a,b)=>{h(b=>b.some(b=>b.id===a.id)?b:[...b,a]),k.current.onTaskCreated?.(a,b)},onTaskUpdated:a=>{h(b=>b.map(b=>b.id===a.id?a:b)),k.current.onTaskUpdated?.(a)},onTaskDeleted:a=>{let b=l.current.find(b=>b.id===a);h(b=>b.filter(b=>b.id!==a)),k.current.onTaskDeleted?.(a,b)},onTaskTabsChanged:a=>{h(b=>b.map(b=>b.id===a.id?a:b))}}),{tasks:c,setTasks:h,isLoading:i,reload:m}}],93886)},27006,a=>{"use strict";var b=a.i(87924),c=a.i(50944),d=a.i(72131),e=a.i(67453),f=a.i(96221),g=a.i(63588),h=a.i(62722),i=a.i(11081),j=a.i(93886),k=a.i(68177),l=a.i(760);let m={waiting:{order:0,icon:g.MessageSquare,className:"text-warning",label:"Waiting for your input"},error:{order:1,icon:h.XCircle,className:"text-destructive",label:"Failed, not opened yet"},success:{order:2,icon:e.CheckCircle2,className:"text-success",label:"Finished, not opened yet"},running:{order:3,icon:f.Loader2,className:"text-primary animate-spin",label:"Running"}};function n({currentTaskId:a}){let e=(0,c.useRouter)(),{tasks:f}=(0,j.useLiveTasks)(),g=(0,d.useMemo)(()=>{let b=[];for(let c of f){let d=(0,i.activityKind)(c);d&&(c.id!==a||"success"!==d&&"error"!==d)&&b.push({task:c,kind:d})}return b.sort((a,b)=>m[a.kind].order-m[b.kind].order||a.task.order-b.task.order||a.task.createdAt.localeCompare(b.task.createdAt))},[f,a]);return(0,b.jsxs)("aside",{className:"hidden md:flex w-64 shrink-0 flex-col border-r border-border bg-card",children:[(0,b.jsxs)("div",{className:"flex h-8 shrink-0 box-content items-center gap-2 border-b border-border p-4",children:[(0,b.jsx)("span",{className:"text-sm font-medium text-foreground",children:"Active"}),(0,b.jsx)(k.Badge,{variant:"secondary",children:g.length})]}),0===g.length?(0,b.jsx)("p",{className:"p-4 text-center text-xs text-muted-foreground",children:"No active tasks"}):(0,b.jsx)("ul",{className:"flex-1 space-y-0.5 overflow-y-auto p-2",children:g.map(({task:c,kind:d})=>{let{icon:f,className:g,label:h}=m[d],i=c.id===a;return(0,b.jsx)("li",{children:(0,b.jsxs)("button",{type:"button",onClick:()=>e.replace(`/tasks/${c.id}`),"aria-current":i?"page":void 0,className:(0,l.cn)("flex w-full items-start gap-2 rounded-md px-2 py-1.5 text-left transition-colors hover:bg-accent",i&&"bg-accent"),children:[(0,b.jsx)("span",{role:"img","aria-label":h,title:h,className:"mt-0.5 shrink-0",children:(0,b.jsx)(f,{className:(0,l.cn)("size-3.5",g)})}),(0,b.jsxs)("span",{className:"min-w-0 flex-1",children:[(0,b.jsx)("span",{className:"block truncate text-sm text-foreground",title:c.title,children:c.title}),(0,b.jsxs)("span",{className:"block truncate text-xs text-muted-foreground",children:[c.owner,"/",c.repo]})]})]})},c.id)})})]})}a.s(["default",0,function({children:a}){let{id:d}=(0,c.useParams)();return(0,b.jsxs)("div",{className:"h-screen flex bg-background",children:[(0,b.jsx)(n,{currentTaskId:d}),(0,b.jsx)("div",{className:"flex-1 min-w-0",children:a})]})}],27006)}];
2
-
3
- //# sourceMappingURL=_0hnxatt._.js.map
@@ -1,3 +0,0 @@
1
- module.exports=[84454,65486,80056,43715,a=>{"use strict";var b=a.i(30685),c=(0,a.i(17508).default)(Object.keys,Object),d=Object.prototype.hasOwnProperty;let e=function(a){if(!(0,b.default)(a))return c(a);var e=[];for(var f in Object(a))d.call(a,f)&&"constructor"!=f&&e.push(f);return e};a.s(["default",0,e],65486);var f=a.i(37991),g=a.i(11253),h=(0,f.default)(g.default,"DataView"),i=a.i(38141),j=(0,f.default)(g.default,"Promise"),k=(0,f.default)(g.default,"Set");a.s(["default",0,k],80056);var l=(0,f.default)(g.default,"WeakMap"),m=a.i(35102),n=a.i(12098),o="[object Map]",p="[object Promise]",q="[object Set]",r="[object WeakMap]",s="[object DataView]",t=(0,n.default)(h),u=(0,n.default)(i.default),v=(0,n.default)(j),w=(0,n.default)(k),x=(0,n.default)(l),y=m.default;(h&&y(new h(new ArrayBuffer(1)))!=s||i.default&&y(new i.default)!=o||j&&y(j.resolve())!=p||k&&y(new k)!=q||l&&y(new l)!=r)&&(y=function(a){var b=(0,m.default)(a),c="[object Object]"==b?a.constructor:void 0,d=c?(0,n.default)(c):"";if(d)switch(d){case t:return s;case u:return o;case v:return p;case w:return q;case x:return r}return b});let z=y;a.s(["default",0,z],43715);var A=a.i(62244),B=a.i(66723),C=a.i(68378),D=a.i(12999),E=a.i(56814),F=Object.prototype.hasOwnProperty;a.s(["default",0,function(a){if(null==a)return!0;if((0,C.default)(a)&&((0,B.default)(a)||"string"==typeof a||"function"==typeof a.splice||(0,D.default)(a)||(0,E.default)(a)||(0,A.default)(a)))return!a.length;var c=z(a);if("[object Map]"==c||"[object Set]"==c)return!a.size;if((0,b.default)(a))return!e(a).length;for(var d in a)if(F.call(a,d))return!1;return!0}],84454)},73160,a=>{"use strict";var b=a.i(14562),c=a.i(34603);a.i(75930);var d=a.i(71731),e=(0,c.__name)(a=>{let{securityLevel:c}=(0,b.getConfig2)(),e=(0,d.select)("body");if("sandbox"===c){let b=(0,d.select)(`#i${a}`),c=b.node()?.contentDocument??document;e=(0,d.select)(c.body)}return e.select(`#${a}`)},"selectSvgElement");a.s(["selectSvgElement",0,e])},50160,a=>{a.v("/_next/static/media/icon.0fkix7.hkmsz4.png"+(globalThis.NEXT_CLIENT_ASSET_SUFFIX||""))},33354,(a,b,c)=>{"use strict";c._=function(a){return a&&a.__esModule?a:{default:a}}},15618,49594,a=>{"use strict";let b=(0,a.i(60137).default)("plus",[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"M12 5v14",key:"s699le"}]]);a.s(["Plus",0,b],15618);let c=[{bg:"bg-blue-100 dark:bg-blue-900/30",text:"text-blue-700 dark:text-blue-300"},{bg:"bg-emerald-100 dark:bg-emerald-900/30",text:"text-emerald-700 dark:text-emerald-300"},{bg:"bg-violet-100 dark:bg-violet-900/30",text:"text-violet-700 dark:text-violet-300"},{bg:"bg-amber-100 dark:bg-amber-900/30",text:"text-amber-700 dark:text-amber-300"},{bg:"bg-rose-100 dark:bg-rose-900/30",text:"text-rose-700 dark:text-rose-300"},{bg:"bg-cyan-100 dark:bg-cyan-900/30",text:"text-cyan-700 dark:text-cyan-300"},{bg:"bg-orange-100 dark:bg-orange-900/30",text:"text-orange-700 dark:text-orange-300"},{bg:"bg-teal-100 dark:bg-teal-900/30",text:"text-teal-700 dark:text-teal-300"},{bg:"bg-indigo-100 dark:bg-indigo-900/30",text:"text-indigo-700 dark:text-indigo-300"},{bg:"bg-pink-100 dark:bg-pink-900/30",text:"text-pink-700 dark:text-pink-300"},{bg:"bg-lime-100 dark:bg-lime-900/30",text:"text-lime-700 dark:text-lime-300"},{bg:"bg-fuchsia-100 dark:bg-fuchsia-900/30",text:"text-fuchsia-700 dark:text-fuchsia-300"}];a.s(["getRepoColor",0,function(a,b){let d=function(a){let b=5381;for(let c=0;c<a.length;c++)b=33*b^a.charCodeAt(c);return b>>>0}(`${a}/${b}`)%c.length;return c[d]}],49594)},10948,a=>{"use strict";let b=(0,a.i(60137).default)("git-branch",[["line",{x1:"6",x2:"6",y1:"3",y2:"15",key:"17qcm7"}],["circle",{cx:"18",cy:"6",r:"3",key:"1h7g24"}],["circle",{cx:"6",cy:"18",r:"3",key:"fqmcym"}],["path",{d:"M18 9a9 9 0 0 1-9 9",key:"n2h4wq"}]]);a.s(["GitBranch",0,b],10948)},63588,a=>{"use strict";let b=(0,a.i(60137).default)("message-square",[["path",{d:"M22 17a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 21.286V5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2z",key:"18887p"}]]);a.s(["MessageSquare",0,b],63588)},62722,a=>{"use strict";let b=(0,a.i(60137).default)("circle-x",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"m15 9-6 6",key:"1uzhvr"}],["path",{d:"m9 9 6 6",key:"z0biqf"}]]);a.s(["XCircle",0,b],62722)},88381,a=>{"use strict";var b=a.i(72131),c=a.i(83915),d=a.i(91399);a.s(["useTaskEvents",0,function(a){let e=(0,b.useRef)(null),f=(0,b.useRef)(a);(0,b.useLayoutEffect)(()=>{f.current=a}),(0,b.useEffect)(()=>{let a=(0,c.io)((0,d.getServerUrl)(),{transports:["polling","websocket"]});return e.current=a,a.on("task:created",({task:a,warnings:b})=>{f.current.onTaskCreated(a,b??[])}),a.on("task:updated",({task:a})=>{f.current.onTaskUpdated(a)}),a.on("task:deleted",({taskId:a})=>{f.current.onTaskDeleted(a)}),a.on("task:tabs-changed",({task:a})=>{f.current.onTaskTabsChanged?.(a)}),()=>{a.disconnect(),e.current=null}},[])}])},13425,a=>{"use strict";var b=a.i(72131),c=a.i(83915),d=a.i(91399);a.s(["useTabStatusEvents",0,function(a,e){let f=(0,b.useRef)(null),g=(0,b.useRef)(new Set),h=(0,b.useRef)(e);(0,b.useEffect)(()=>{h.current=e});let i=(0,b.useCallback)(()=>{if(!f.current){let a=(0,c.io)((0,d.getServerUrl)(),{transports:["polling","websocket"]});f.current=a,a.on("status-changed",({sessionId:a,status:b})=>{let c=function(a){switch(a){case"running":return"running";case"waiting":return"waiting";case"success":return"success";case"failure":case"error":return"error";case"idle":return"idle";default:return null}}(b);null!==c&&h.current(a,c)}),a.on("connect",()=>{for(let b of g.current)a.emit("join",{room:b,mode:"subscribe"})})}return f.current},[]);(0,b.useEffect)(()=>{if(0===a.length)return;let b=i();for(let c of a){let a=`tab:${c}`;g.current.has(a)||(b.emit("join",{room:a,mode:"subscribe"}),g.current.add(a))}let c=new Set(a);for(let a of g.current){let d=a.replace("tab:","");c.has(d)||(b.emit("leave",{room:a}),g.current.delete(a))}},[a,i]),(0,b.useEffect)(()=>{let a=g.current;return()=>{f.current?.disconnect(),f.current=null,a.clear()}},[])}])},11081,93886,a=>{"use strict";function b(a){return"success"===a||"error"===a||"running"!==a&&"idle"!==a&&void 0}function c(a){let b=a.tabs??[];if(0===b.length||b.some(a=>"running"===a.status))return null;if(b.some(a=>"waiting"===a.status))return"waiting";let c=b.filter(a=>a.unread);return c.some(a=>"error"===a.status)?"error":c.some(a=>"success"===a.status)?"success":null}a.s(["activityKind",0,function(a){return(a.tabs??[]).some(a=>"running"===a.status)?"running":c(a)},"hasUnreadResult",0,function(a){return null!==c(a)},"unreadForStatus",0,b,"unreadKind",0,c],11081);var d=a.i(72131),e=a.i(91399),f=a.i(88381),g=a.i(13425);a.s(["useLiveTasks",0,function(a={}){let[c,h]=(0,d.useState)([]),[i,j]=(0,d.useState)(!0),k=(0,d.useRef)(a),l=(0,d.useRef)(c);(0,d.useEffect)(()=>{k.current=a,l.current=c});let m=(0,d.useCallback)(async()=>{j(!0);try{let a=await fetch((0,e.apiUrl)("/api/tasks"));if(!a.ok)throw Error("Failed to fetch tasks");let b=await a.json();h(b.data.tasks)}catch(a){console.error("Failed to load tasks:",a)}finally{j(!1)}},[]);(0,d.useEffect)(()=>{m()},[m]);let n=(0,d.useMemo)(()=>c.flatMap(a=>(a.tabs??[]).map(a=>a.tab_id)),[c]);return(0,g.useTabStatusEvents)(n,(a,c)=>{let d=b(c);h(b=>b.map(b=>({...b,tabs:(b.tabs??[]).map(b=>b.tab_id===a?{...b,status:c,...void 0!==d&&{unread:d}}:b)})))}),(0,f.useTaskEvents)({onTaskCreated:(a,b)=>{h(b=>b.some(b=>b.id===a.id)?b:[...b,a]),k.current.onTaskCreated?.(a,b)},onTaskUpdated:a=>{h(b=>b.map(b=>b.id===a.id?a:b)),k.current.onTaskUpdated?.(a)},onTaskDeleted:a=>{let b=l.current.find(b=>b.id===a);h(b=>b.filter(b=>b.id!==a)),k.current.onTaskDeleted?.(a,b)},onTaskTabsChanged:a=>{h(b=>b.map(b=>b.id===a.id?a:b))}}),{tasks:c,setTasks:h,isLoading:i,reload:m}}],93886)},92025,a=>{a.v(b=>Promise.all(["server/chunks/ssr/node_modules_katex_dist_katex_mjs_0zuygmo._.js"].map(b=>a.l(b))).then(()=>b(48986)))},69e3,a=>{a.v(b=>Promise.all(["server/chunks/ssr/node_modules_lodash-es_0yap81y._.js","server/chunks/ssr/node_modules_mermaid_dist_chunks_mermaid_core_dagre-KV5264BT_mjs_0aqvo3i._.js","server/chunks/ssr/node_modules_lodash-es_091xgk5._.js","server/chunks/ssr/node_modules_dagre-d3-es_src_dagre_index_097t5l0.js","server/chunks/ssr/node_modules_103v9xp._.js"].map(b=>a.l(b))).then(()=>b(55868)))},71331,a=>{a.v(b=>Promise.all(["server/chunks/ssr/node_modules_0hsalo_._.js","server/chunks/ssr/node_modules_cytoscape_dist_cytoscape_esm_mjs_0642y5z._.js"].map(b=>a.l(b))).then(()=>b(3671)))},99987,a=>{a.v(b=>Promise.all(["server/chunks/ssr/node_modules_mermaid_dist_chunks_mermaid_core_chunk-YZCP3GAM_mjs_04sswi2._.js","server/chunks/ssr/node_modules_mermaid_dist_chunks_mermaid_core_c4Diagram-AHTNJAMY_mjs_0mw4ioe._.js"].map(b=>a.l(b))).then(()=>b(42357)))},48308,a=>{a.v(b=>Promise.all(["server/chunks/ssr/node_modules_08av5m5._.js","server/chunks/ssr/node_modules_mermaid_dist_chunks_mermaid_core_flowDiagram-DWJPFMVM_mjs_11yfm2v._.js"].map(b=>a.l(b))).then(()=>b(26594)))},74667,a=>{a.v(b=>Promise.all(["server/chunks/ssr/node_modules_07xyphe._.js","server/chunks/ssr/node_modules_mermaid_dist_chunks_mermaid_core_erDiagram-SMLLAGMA_mjs_0ti8x~s._.js"].map(b=>a.l(b))).then(()=>b(35543)))},15498,a=>{a.v(b=>Promise.all(["server/chunks/ssr/node_modules_0_huoqd._.js","server/chunks/ssr/[root-of-the-server]__0qtqq5d._.js","server/chunks/ssr/node_modules_0gvdioh._.js","server/chunks/ssr/node_modules_lodash-es_01jun1r._.js","server/chunks/ssr/0_lp_modules_mermaid_dist_chunks_mermaid_core_gitGraphDiagram-UUTBAWPF_mjs_0dvv8~.._.js"].map(b=>a.l(b))).then(()=>b(2421)))},24500,a=>{a.v(b=>Promise.all(["server/chunks/ssr/node_modules_0q8gl61._.js","server/chunks/ssr/node_modules_0t03q3z._.js"].map(b=>a.l(b))).then(()=>b(37521)))},78102,a=>{a.v(b=>Promise.all(["server/chunks/ssr/node_modules_0tod6y8._.js","server/chunks/ssr/[root-of-the-server]__0ff1foz._.js","server/chunks/ssr/node_modules_lodash-es_01jun1r._.js","server/chunks/ssr/node_modules_0gvdioh._.js"].map(b=>a.l(b))).then(()=>b(86618)))},94433,a=>{a.v(b=>Promise.all(["server/chunks/ssr/node_modules_0xp9nhx._.js","server/chunks/ssr/[root-of-the-server]__0n2qong._.js","server/chunks/ssr/node_modules_lodash-es_01jun1r._.js","server/chunks/ssr/node_modules_0gvdioh._.js"].map(b=>a.l(b))).then(()=>b(28018)))},65122,a=>{a.v(b=>Promise.all(["server/chunks/ssr/node_modules_0m8d9.a._.js","server/chunks/ssr/0_lp_modules_mermaid_dist_chunks_mermaid_core_quadrantDiagram-34T5L4WZ_mjs_05wge~v._.js"].map(b=>a.l(b))).then(()=>b(40628)))},6687,a=>{a.v(b=>Promise.all(["server/chunks/ssr/node_modules_0j1i92p._.js","server/chunks/ssr/0_lp_modules_mermaid_dist_chunks_mermaid_core_xychartDiagram-5P7HB3ND_mjs_0wwuvw2._.js"].map(b=>a.l(b))).then(()=>b(7451)))},18402,a=>{a.v(b=>Promise.all(["server/chunks/ssr/node_modules_mermaid_dist_chunks_mermaid_core_04x.vut._.js","server/chunks/ssr/0t6k_mermaid_dist_chunks_mermaid_core_requirementDiagram-MS252O5E_mjs_048lezu._.js"].map(b=>a.l(b))).then(()=>b(90431)))},92739,a=>{a.v(b=>Promise.all(["server/chunks/ssr/node_modules_mermaid_dist_chunks_mermaid_core_0w_54yy._.js","server/chunks/ssr/0_lp_modules_mermaid_dist_chunks_mermaid_core_sequenceDiagram-FGHM5R23_mjs_12c7k-5._.js"].map(b=>a.l(b))).then(()=>b(67397)))},32256,a=>{a.v(b=>Promise.all(["server/chunks/ssr/node_modules_mermaid_dist_chunks_mermaid_core_0o900rn._.js","server/chunks/ssr/node_modules_mermaid_dist_chunks_mermaid_core_chunk-4TB4RGXK_mjs_0ie15wz._.js"].map(b=>a.l(b))).then(()=>b(55252)))},51050,a=>{a.v(b=>Promise.all(["server/chunks/ssr/node_modules_mermaid_dist_chunks_mermaid_core_03f~che._.js","server/chunks/ssr/node_modules_mermaid_dist_chunks_mermaid_core_chunk-4TB4RGXK_mjs_0ie15wz._.js"].map(b=>a.l(b))).then(()=>b(12084)))},33430,a=>{a.v(b=>Promise.all(["server/chunks/ssr/node_modules_0mwl~df._.js","server/chunks/ssr/node_modules_lodash-es_091xgk5._.js","server/chunks/ssr/node_modules_mermaid_dist_chunks_mermaid_core_stateDiagram-FHFEXIEX_mjs_0mg2~ri._.js","server/chunks/ssr/node_modules_dagre-d3-es_src_dagre_index_097t5l0.js","server/chunks/ssr/node_modules_mermaid_dist_chunks_mermaid_core_chunk-OYMX7WX6_mjs_087i3.l._.js","server/chunks/ssr/node_modules_103v9xp._.js"].map(b=>a.l(b))).then(()=>b(55905)))},43021,a=>{a.v(b=>Promise.all(["server/chunks/ssr/node_modules_mermaid_dist_chunks_mermaid_core_0cje6no._.js","server/chunks/ssr/node_modules_mermaid_dist_chunks_mermaid_core_chunk-OYMX7WX6_mjs_087i3.l._.js"].map(b=>a.l(b))).then(()=>b(79891)))},21261,a=>{a.v(b=>Promise.all(["server/chunks/ssr/node_modules_0_09.d-._.js","server/chunks/ssr/0_lp_modules_mermaid_dist_chunks_mermaid_core_journeyDiagram-VCZTEJTY_mjs_0q7b_tk._.js"].map(b=>a.l(b))).then(()=>b(47598)))},50244,a=>{a.v(b=>Promise.all(["server/chunks/ssr/node_modules_d3-shape_src_arc_135n374.js","server/chunks/ssr/0t6k_mermaid_dist_chunks_mermaid_core_timeline-definition-GMOUNBTQ_mjs_0y7flug._.js"].map(b=>a.l(b))).then(()=>b(98138)))},54532,a=>{a.v(b=>Promise.all(["server/chunks/ssr/node_modules_mermaid_dist_chunks_mermaid_core_04x.vut._.js","server/chunks/ssr/0t6k_mermaid_dist_chunks_mermaid_core_mindmap-definition-QFDTVHPH_mjs_0ie03qp._.js"].map(b=>a.l(b))).then(()=>b(73348)))},42598,a=>{a.v(b=>Promise.all(["server/chunks/ssr/node_modules_mermaid_dist_chunks_mermaid_core_chunk-FMBD7UC4_mjs_0dox0y0._.js","server/chunks/ssr/0_lp_modules_mermaid_dist_chunks_mermaid_core_kanban-definition-6JOO6SKY_mjs_0b8_92c._.js"].map(b=>a.l(b))).then(()=>b(78776)))},18652,a=>{a.v(b=>Promise.all(["server/chunks/ssr/node_modules_d3-scale_src_0~kn3a6._.js","server/chunks/ssr/node_modules_mermaid_dist_chunks_mermaid_core_sankeyDiagram-XADWPNL6_mjs_0akor_o._.js"].map(b=>a.l(b))).then(()=>b(88909)))},9099,a=>{a.v(b=>Promise.all(["server/chunks/ssr/node_modules_0l23gkf._.js","server/chunks/ssr/[root-of-the-server]__0hhfi7s._.js","server/chunks/ssr/node_modules_lodash-es_01jun1r._.js","server/chunks/ssr/node_modules_0gvdioh._.js"].map(b=>a.l(b))).then(()=>b(20145)))},35140,a=>{a.v(b=>Promise.all(["server/chunks/ssr/node_modules_04pfam-._.js","server/chunks/ssr/[root-of-the-server]__0hhfi7s._.js","server/chunks/ssr/node_modules_lodash-es_01jun1r._.js","server/chunks/ssr/node_modules_0gvdioh._.js"].map(b=>a.l(b))).then(()=>b(42910)))},56125,a=>{a.v(b=>Promise.all(["server/chunks/ssr/node_modules_0omx0o-._.js","server/chunks/ssr/node_modules_0heie6p._.js","server/chunks/ssr/node_modules_mermaid_dist_chunks_mermaid_core_blockDiagram-DXYQGD6D_mjs_13mbtfc._.js","server/chunks/ssr/node_modules_lodash-es_0egjqeu._.js"].map(b=>a.l(b))).then(()=>b(68669)))},54269,a=>{a.v(b=>Promise.all(["server/chunks/ssr/node_modules_0q_xfyl._.js","server/chunks/ssr/[root-of-the-server]__0cl-0al._.js","server/chunks/ssr/node_modules_lodash-es_01jun1r._.js","server/chunks/ssr/node_modules_0gvdioh._.js"].map(b=>a.l(b))).then(()=>b(58204)))},97375,a=>{a.v(b=>Promise.all(["server/chunks/ssr/node_modules_0krwgny._.js","server/chunks/ssr/node_modules_lodash-es_01jun1r._.js","server/chunks/ssr/[root-of-the-server]__0e2_bho._.js","server/chunks/ssr/node_modules_0gvdioh._.js","server/chunks/ssr/node_modules_0sqcrg2._.js","server/chunks/ssr/node_modules_cytoscape_dist_cytoscape_esm_mjs_0642y5z._.js"].map(b=>a.l(b))).then(()=>b(29821)))},70868,a=>{a.v(b=>Promise.all(["server/chunks/ssr/0_lp_modules_mermaid_dist_chunks_mermaid_core_ishikawaDiagram-UXIWVN3A_mjs_0gpauwj._.js"].map(b=>a.l(b))).then(()=>b(5822)))},5494,a=>{a.v(b=>Promise.all(["server/chunks/ssr/node_modules_mermaid_dist_chunks_mermaid_core_vennDiagram-DHZGUBPP_mjs_013wte~._.js"].map(b=>a.l(b))).then(()=>b(65580)))},41872,a=>{a.v(b=>Promise.all(["server/chunks/ssr/node_modules_0oip5a1._.js","server/chunks/ssr/[root-of-the-server]__0sha5xx._.js","server/chunks/ssr/node_modules_lodash-es_01jun1r._.js","server/chunks/ssr/node_modules_0gvdioh._.js","server/chunks/ssr/node_modules_mermaid_dist_chunks_mermaid_core_diagram-G4DWMVQ6_mjs_108p.po._.js"].map(b=>a.l(b))).then(()=>b(52172)))},40744,a=>{a.v(b=>Promise.all(["server/chunks/ssr/node_modules_0krwgny._.js","server/chunks/ssr/[root-of-the-server]__0e2_bho._.js","server/chunks/ssr/node_modules_0gvdioh._.js","server/chunks/ssr/node_modules_lodash-es_01jun1r._.js","server/chunks/ssr/0_lp_modules_mermaid_dist_chunks_mermaid_core_wardleyDiagram-NUSXRM2D_mjs_0579rrr._.js"].map(b=>a.l(b))).then(()=>b(2410)))}];
2
-
3
- //# sourceMappingURL=_10gk93.._.js.map