@minimalcorp/tsunagi 0.3.3 → 0.4.2
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/page_client-reference-manifest.js +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 +2 -2
- package/.next/standalone/apps/web/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- 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 +2 -2
- 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 +2 -2
- package/.next/standalone/apps/web/.next/server/app/index.html +1 -1
- package/.next/standalone/apps/web/.next/server/app/index.rsc +3 -3
- package/.next/standalone/apps/web/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/apps/web/.next/server/app/index.segments/_full.segment.rsc +3 -3
- 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 +2 -2
- package/.next/standalone/apps/web/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/apps/web/.next/server/app/page.js.nft.json +1 -1
- package/.next/standalone/apps/web/.next/server/app/page_client-reference-manifest.js +1 -1
- package/.next/standalone/apps/web/.next/server/app/settings/page.js.nft.json +1 -1
- package/.next/standalone/apps/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/.next/standalone/apps/web/.next/server/app/settings.html +1 -1
- package/.next/standalone/apps/web/.next/server/app/settings.rsc +3 -3
- package/.next/standalone/apps/web/.next/server/app/settings.segments/_full.segment.rsc +3 -3
- 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 +2 -2
- package/.next/standalone/apps/web/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
- package/.next/standalone/apps/web/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +2 -2
- package/.next/standalone/apps/web/.next/server/app/settings.segments/settings.segment.rsc +1 -1
- package/.next/standalone/apps/web/.next/server/app/tasks/[id]/page.js.nft.json +1 -1
- package/.next/standalone/apps/web/.next/server/app/tasks/[id]/page_client-reference-manifest.js +1 -1
- package/.next/standalone/apps/web/.next/server/chunks/ssr/[root-of-the-server]__0qjafjt._.js +1 -1
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{_13w5ytx._.js → _01~tp-i._.js} +2 -2
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{_0kflgfj._.js → _03lm.~7._.js} +3 -3
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{_0g79jqo._.js → _09br4yx._.js} +3 -3
- package/.next/standalone/apps/web/.next/server/chunks/ssr/_0g.cd6a._.js +2 -2
- package/.next/standalone/apps/web/.next/server/chunks/ssr/_0h-u~an._.js +7 -0
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{_139_l.u._.js → _0kkt7a_._.js} +2 -2
- package/.next/standalone/apps/web/.next/server/chunks/ssr/_0ts4rpp._.js +3 -0
- package/.next/standalone/apps/web/.next/server/chunks/ssr/_13ne7ej._.js +3 -0
- package/.next/standalone/apps/web/.next/server/chunks/ssr/apps_web_src_app_settings_page_tsx_0i6itlb._.js +1 -3
- package/.next/standalone/apps/web/.next/server/chunks/ssr/apps_web_src_app_tasks_[id]_page_tsx_0jshsm2._.js +3 -3
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0cv326~._.js → node_modules_06jdmu~._.js} +1 -1
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0h.vgyn._.js → node_modules_0ac2-~z._.js} +1 -1
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0sn0lqb._.js → node_modules_0gglkx9._.js} +1 -1
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0tod6y8._.js → node_modules_0h4h_aw._.js} +1 -1
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0q_5qo~._.js → node_modules_0i5v48e._.js} +1 -1
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_09d2oqj._.js → node_modules_0k3x6_w._.js} +1 -1
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0oip5a1._.js → node_modules_0q8yuvq._.js} +1 -1
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0npujym._.js → node_modules_0rnsluy._.js} +1 -1
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0krwgny._.js → node_modules_0t-jssg._.js} +1 -1
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0l23gkf._.js → node_modules_0t6ysh_._.js} +1 -1
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_11-z65a._.js → node_modules_0ut2-yw._.js} +1 -1
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0_huoqd._.js → node_modules_0vq~hzy._.js} +1 -1
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0a57phw._.js → node_modules_0w6fm3f._.js} +2 -2
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0xp9nhx._.js → node_modules_0yb2sh9._.js} +1 -1
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0q_xfyl._.js → node_modules_0yc~s8p._.js} +1 -1
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0ak_3rk._.js → node_modules_0zi0w9_._.js} +1 -1
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_04pfam-._.js → node_modules_0zzdoud._.js} +1 -1
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{_0w2dm3r._.js → node_modules_lucide-react_dist_esm_icons_0zerlct._.js} +2 -2
- 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/.next/standalone/apps/web/.next/static/chunks/{0l83q95s~tih4.js → 08s3o7outb~0z.js} +1 -1
- package/.next/standalone/apps/web/.next/static/chunks/0a2u28f44p7t..js +1 -0
- package/.next/standalone/apps/web/.next/static/chunks/{0oricprxoxb_d.js → 0ae7zmpe8063z.js} +10 -10
- package/.next/standalone/apps/web/.next/static/chunks/0dgu~u-1e5b7-.js +5 -0
- package/.next/standalone/apps/web/.next/static/chunks/{0whl1y16cvn5q.js → 0e8u7rqrqfiiy.js} +1 -1
- package/.next/standalone/apps/web/.next/static/chunks/{0z60ewb40i2ce.js → 0gxhy80~c0gvp.js} +1 -1
- package/.next/standalone/apps/web/.next/static/chunks/0n72w4sxrwoj4.js +5 -0
- package/.next/standalone/apps/web/.next/static/chunks/0o1bh_qwdvmid.css +4 -0
- package/.next/standalone/apps/web/.next/static/chunks/{17~93fal1fw_d.js → 0uugzgqr-ug3_.js} +1 -1
- package/.next/standalone/apps/web/.next/static/chunks/{149sia28cskw9.js → 0yp~t_.pozr-d.js} +6 -6
- package/.next/standalone/apps/web/.next/static/chunks/0ysgl4vmer~v5.js +6 -0
- package/.next/standalone/apps/web/.next/static/chunks/{053h220fng_68.js → 11u7x4ic4~mp3.js} +10 -10
- package/.next/standalone/apps/web/.next/static/chunks/13_9zaka0bif_.js +1 -0
- package/.next/standalone/apps/web/package.json +1 -3
- package/README.md +1 -1
- package/dist/app.js +3 -4
- package/dist/plugin-lifecycle.d.ts +5 -3
- package/dist/plugin-lifecycle.js +40 -16
- package/dist/prisma/migrations/20261011000000_add_codex_support/migration.sql +20 -0
- package/dist/prisma/schema.prisma +9 -5
- package/dist/server/generated/prisma/browser.d.ts +2 -2
- package/dist/server/generated/prisma/client.d.ts +2 -2
- package/dist/server/generated/prisma/internal/class.d.ts +4 -4
- package/dist/server/generated/prisma/internal/class.js +4 -4
- package/dist/server/generated/prisma/internal/prismaNamespace.d.ts +41 -39
- package/dist/server/generated/prisma/internal/prismaNamespace.js +4 -2
- package/dist/server/generated/prisma/internal/prismaNamespaceBrowser.d.ts +5 -3
- package/dist/server/generated/prisma/internal/prismaNamespaceBrowser.js +4 -2
- package/dist/server/generated/prisma/models/AgentProfile.d.ts +972 -0
- package/dist/server/generated/prisma/models/Tab.d.ts +36 -1
- package/dist/server/generated/prisma/models.d.ts +1 -1
- package/dist/server/index.js +2 -7
- package/dist/server/lib/agent-profiles.d.ts +44 -0
- package/dist/server/lib/agent-profiles.js +130 -0
- package/dist/server/lib/agents/claude.d.ts +2 -0
- package/dist/server/lib/agents/claude.js +130 -0
- package/dist/server/lib/agents/cli.d.ts +14 -0
- package/dist/server/lib/agents/cli.js +57 -0
- package/dist/server/lib/agents/codex.d.ts +2 -0
- package/dist/server/lib/agents/codex.js +285 -0
- package/dist/server/lib/agents/index.d.ts +11 -0
- package/dist/server/lib/agents/index.js +19 -0
- package/dist/server/lib/agents/login-callback.d.ts +11 -0
- package/dist/server/lib/agents/login-callback.js +47 -0
- package/dist/server/lib/agents/types.d.ts +77 -0
- package/dist/server/lib/agents/types.js +8 -0
- package/dist/server/lib/pty-env-sync.js +1 -1
- package/dist/server/lib/pty-launch.d.ts +8 -10
- package/dist/server/lib/pty-launch.js +20 -58
- package/dist/server/lib/repositories/task.js +1 -0
- package/dist/server/lib/tab-todos.d.ts +5 -0
- package/dist/server/lib/tab-todos.js +13 -0
- package/dist/server/pty-manager.d.ts +7 -2
- package/dist/server/pty-manager.js +13 -0
- package/dist/server/routes/agent-profiles.d.ts +2 -0
- package/dist/server/routes/agent-profiles.js +193 -0
- package/dist/server/routes/env.js +2 -2
- package/dist/server/routes/hooks.d.ts +4 -19
- package/dist/server/routes/hooks.js +83 -73
- package/dist/server/routes/mcp.js +2 -2
- package/dist/server/routes/onboarding.js +19 -10
- package/dist/server/routes/tasks.js +4 -4
- package/dist/server/routes/terminal.js +47 -34
- package/dist/with-plugin.js +3 -3
- package/npm-shrinkwrap.json +37 -24
- package/package.json +1 -1
- package/tsunagi-marketplace/codex/tsunagi-task.md +120 -0
- package/.next/standalone/apps/web/.next/server/chunks/ssr/[root-of-the-server]__11y.qj~._.js +0 -3
- package/.next/standalone/apps/web/.next/server/chunks/ssr/_03vftq7._.js +0 -7
- package/.next/standalone/apps/web/.next/server/chunks/ssr/_0hnxatt._.js +0 -3
- package/.next/standalone/apps/web/.next/server/chunks/ssr/_10gk93.._.js +0 -3
- package/.next/standalone/apps/web/.next/static/chunks/0.gcmzq82~36i.js +0 -1
- package/.next/standalone/apps/web/.next/static/chunks/06gfh91..uydi.js +0 -5
- package/.next/standalone/apps/web/.next/static/chunks/0b90ys7wq-p.4.css +0 -4
- package/.next/standalone/apps/web/.next/static/chunks/0crn03y2tj0lu.js +0 -6
- package/.next/standalone/apps/web/.next/static/chunks/0lvl3ec93cab_.js +0 -7
- package/.next/standalone/apps/web/.next/static/chunks/0makl-d3f0_qh.js +0 -2878
- package/.next/standalone/apps/web/.next/static/chunks/0o6ggm7jrim25.js +0 -1
- package/.next/standalone/apps/web/public/vad/ort-wasm-simd-threaded.mjs +0 -59
- package/.next/standalone/apps/web/public/vad/ort-wasm-simd-threaded.wasm +0 -0
- package/.next/standalone/apps/web/public/vad/silero_vad_v5.onnx +0 -0
- package/.next/standalone/apps/web/public/vad/vad.worklet.bundle.min.js +0 -1
- package/dist/server/generated/prisma/models/ClaudeProfile.d.ts +0 -939
- package/dist/server/lib/asr-models.d.ts +0 -7
- package/dist/server/lib/asr-models.js +0 -51
- package/dist/server/lib/claude-profiles.d.ts +0 -49
- package/dist/server/lib/claude-profiles.js +0 -168
- package/dist/server/lib/process-port.d.ts +0 -1
- package/dist/server/lib/process-port.js +0 -28
- package/dist/server/lib/python-venv.d.ts +0 -4
- package/dist/server/lib/python-venv.js +0 -66
- package/dist/server/lib/voice-debug-log.d.ts +0 -9
- package/dist/server/lib/voice-debug-log.js +0 -28
- package/dist/server/lib/whisper-process.d.ts +0 -40
- package/dist/server/lib/whisper-process.js +0 -333
- package/dist/server/routes/claude-profiles.d.ts +0 -2
- package/dist/server/routes/claude-profiles.js +0 -138
- package/dist/server/routes/whisper.d.ts +0 -2
- package/dist/server/routes/whisper.js +0 -103
- package/dist/whisper-server/README.md +0 -31
- package/dist/whisper-server/download_model.py +0 -19
- package/dist/whisper-server/requirements.txt +0 -8
- package/dist/whisper-server/run.sh +0 -62
- package/dist/whisper-server/server.py +0 -147
- /package/.next/standalone/apps/web/.next/static/{7x81GlNKt9yqIkeI7U1BX → vdAs-hr87-L7y2bUSdX3i}/_buildManifest.js +0 -0
- /package/.next/standalone/apps/web/.next/static/{7x81GlNKt9yqIkeI7U1BX → vdAs-hr87-L7y2bUSdX3i}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/apps/web/.next/static/{7x81GlNKt9yqIkeI7U1BX → vdAs-hr87-L7y2bUSdX3i}/_ssgManifest.js +0 -0
- /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 {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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
|
|
8
|
-
const statuses = await Promise.all(profiles.map((p) =>
|
|
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 [
|
|
16
|
-
|
|
17
|
-
// 実験的機能のローカルLLM(Ollama / LM Studio
|
|
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: {
|
|
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
|
|
269
|
-
if (
|
|
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
|
-
?
|
|
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 {
|
|
4
|
-
import {
|
|
5
|
-
import { PtyLaunchError,
|
|
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が強制終了した場合に
|
|
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
|
-
|
|
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/
|
|
294
|
-
// コマンドはタブの mode に応じてサーバーで組み立てる(ローカルLLM
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
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);
|
package/dist/with-plugin.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { spawn } from 'node:child_process';
|
|
3
|
-
import {
|
|
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
|
-
|
|
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'
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@minimalcorp/tsunagi",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@minimalcorp/tsunagi",
|
|
9
|
-
"version": "0.
|
|
9
|
+
"version": "0.4.2",
|
|
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.
|
|
239
|
-
"resolved": "https://registry.npmjs.org/@fastify/multipart/-/multipart-10.1.
|
|
240
|
-
"integrity": "sha512-
|
|
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.
|
|
282
|
-
"resolved": "https://registry.npmjs.org/@fastify/reply-from/-/reply-from-12.
|
|
283
|
-
"integrity": "sha512
|
|
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": "^
|
|
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",
|
|
@@ -1608,9 +1608,9 @@
|
|
|
1608
1608
|
"license": "MIT"
|
|
1609
1609
|
},
|
|
1610
1610
|
"node_modules/content-disposition": {
|
|
1611
|
-
"version": "
|
|
1612
|
-
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-
|
|
1613
|
-
"integrity": "sha512-
|
|
1611
|
+
"version": "2.0.1",
|
|
1612
|
+
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-2.0.1.tgz",
|
|
1613
|
+
"integrity": "sha512-e+H0ZXHSWYrENhQzw1LPuP4oF5MzVKmDU6d3hxlvaPEYLLg62MxtQNPRx4SYSuYJSBUgnQIG4HIN2tEtNv7Dog==",
|
|
1614
1614
|
"license": "MIT",
|
|
1615
1615
|
"engines": {
|
|
1616
1616
|
"node": ">=18"
|
|
@@ -2190,15 +2190,15 @@
|
|
|
2190
2190
|
}
|
|
2191
2191
|
},
|
|
2192
2192
|
"node_modules/express": {
|
|
2193
|
-
"version": "5.
|
|
2194
|
-
"resolved": "https://registry.npmjs.org/express/-/express-5.
|
|
2195
|
-
"integrity": "sha512-
|
|
2193
|
+
"version": "5.3.0",
|
|
2194
|
+
"resolved": "https://registry.npmjs.org/express/-/express-5.3.0.tgz",
|
|
2195
|
+
"integrity": "sha512-qCqy1xSoaugxOD4IVHb1ZWdkvCF2W3aE2okKouWj8VwJ+ztskSiXoBnCSJqfKT+cVPJhuJqe9YLbY425+Zh00g==",
|
|
2196
2196
|
"license": "MIT",
|
|
2197
2197
|
"dependencies": {
|
|
2198
2198
|
"accepts": "^2.0.0",
|
|
2199
|
-
"body-parser": "^2.
|
|
2200
|
-
"content-disposition": "^
|
|
2201
|
-
"content-type": "^
|
|
2199
|
+
"body-parser": "^2.3.0",
|
|
2200
|
+
"content-disposition": "^2.0.1",
|
|
2201
|
+
"content-type": "^2.0.0",
|
|
2202
2202
|
"cookie": "^0.7.1",
|
|
2203
2203
|
"cookie-signature": "^1.2.1",
|
|
2204
2204
|
"debug": "^4.4.0",
|
|
@@ -2214,14 +2214,14 @@
|
|
|
2214
2214
|
"on-finished": "^2.4.1",
|
|
2215
2215
|
"once": "^1.4.0",
|
|
2216
2216
|
"parseurl": "^1.3.3",
|
|
2217
|
-
"proxy-addr": "^2.0.
|
|
2218
|
-
"qs": "^6.
|
|
2217
|
+
"proxy-addr": "^2.0.8",
|
|
2218
|
+
"qs": "^6.16.0",
|
|
2219
2219
|
"range-parser": "^1.2.1",
|
|
2220
2220
|
"router": "^2.2.0",
|
|
2221
2221
|
"send": "^1.1.0",
|
|
2222
2222
|
"serve-static": "^2.2.0",
|
|
2223
2223
|
"statuses": "^2.0.1",
|
|
2224
|
-
"type-is": "^2.0
|
|
2224
|
+
"type-is": "^2.1.0",
|
|
2225
2225
|
"vary": "^1.1.2"
|
|
2226
2226
|
},
|
|
2227
2227
|
"engines": {
|
|
@@ -2251,6 +2251,19 @@
|
|
|
2251
2251
|
"express": ">= 4.11"
|
|
2252
2252
|
}
|
|
2253
2253
|
},
|
|
2254
|
+
"node_modules/express/node_modules/content-type": {
|
|
2255
|
+
"version": "2.1.0",
|
|
2256
|
+
"resolved": "https://registry.npmjs.org/content-type/-/content-type-2.1.0.tgz",
|
|
2257
|
+
"integrity": "sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==",
|
|
2258
|
+
"license": "MIT",
|
|
2259
|
+
"engines": {
|
|
2260
|
+
"node": ">=18"
|
|
2261
|
+
},
|
|
2262
|
+
"funding": {
|
|
2263
|
+
"type": "opencollective",
|
|
2264
|
+
"url": "https://opencollective.com/express"
|
|
2265
|
+
}
|
|
2266
|
+
},
|
|
2254
2267
|
"node_modules/exsolve": {
|
|
2255
2268
|
"version": "1.1.3",
|
|
2256
2269
|
"resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.1.3.tgz",
|
|
@@ -2280,9 +2293,9 @@
|
|
|
2280
2293
|
}
|
|
2281
2294
|
},
|
|
2282
2295
|
"node_modules/fast-content-type-parse": {
|
|
2283
|
-
"version": "
|
|
2284
|
-
"resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-
|
|
2285
|
-
"integrity": "sha512-
|
|
2296
|
+
"version": "4.0.0",
|
|
2297
|
+
"resolved": "https://registry.npmjs.org/fast-content-type-parse/-/fast-content-type-parse-4.0.0.tgz",
|
|
2298
|
+
"integrity": "sha512-rvu3AY9s3EsDXSDUWzFU5M9/fDpjAUwyIkDR9VrwZA3H9J5f4ymkT0J4iWw9iLaMvFVwsYTGFClUgy9VIvnabA==",
|
|
2286
2299
|
"funding": [
|
|
2287
2300
|
{
|
|
2288
2301
|
"type": "github",
|
package/package.json
CHANGED
|
@@ -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` が失敗した場合、エラー内容をユーザーに報告するだけでよい(原因の深掘り不要)
|