@minimalcorp/tsunagi 0.3.2 → 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.
- 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/_05n88to._.js +3 -0
- package/.next/standalone/apps/web/.next/server/chunks/ssr/_0g.cd6a._.js +2 -2
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{_0kflgfj._.js → _0pw3_r_._.js} +3 -3
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{_0g79jqo._.js → _0rb6-mo._.js} +3 -3
- package/.next/standalone/apps/web/.next/server/chunks/ssr/_0ts4rpp._.js +3 -0
- package/.next/standalone/apps/web/.next/server/chunks/ssr/apps_web_src_app_settings_page_tsx_0i6itlb._.js +2 -2
- 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_04pfam-._.js → node_modules_03-rvdo._.js} +1 -1
- 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_0a57phw._.js → node_modules_0925te2._.js} +2 -2
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0_huoqd._.js → node_modules_0e8uni7._.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_0h.vgyn._.js → node_modules_0nzbb9~._.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_11-z65a._.js → node_modules_0r6t2tu._.js} +1 -1
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_09d2oqj._.js → node_modules_0t6ysh_._.js} +1 -1
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0krwgny._.js → node_modules_0vj~e_v._.js} +1 -1
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0sn0lqb._.js → node_modules_0vq~hzy._.js} +1 -1
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0l23gkf._.js → node_modules_0xzmx-x._.js} +1 -1
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0npujym._.js → node_modules_0yb2sh9._.js} +1 -1
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0q_5qo~._.js → node_modules_0yc~s8p._.js} +1 -1
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0q_xfyl._.js → node_modules_0zi-gfw._.js} +1 -1
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0ak_3rk._.js → node_modules_0zzdoud._.js} +1 -1
- package/.next/standalone/apps/web/.next/server/chunks/ssr/{node_modules_0xp9nhx._.js → node_modules_0~aiu12._.js} +1 -1
- package/.next/standalone/apps/web/.next/server/middleware-build-manifest.js +3 -3
- package/.next/standalone/apps/web/.next/server/pages/404.html +1 -1
- package/.next/standalone/apps/web/.next/server/pages/500.html +1 -1
- package/.next/standalone/apps/web/.next/server/server-reference-manifest.js +1 -1
- package/.next/standalone/apps/web/.next/server/server-reference-manifest.json +1 -1
- package/.next/standalone/apps/web/.next/static/chunks/09b_3duxnyfto.js +7 -0
- package/.next/standalone/apps/web/.next/static/chunks/{0z60ewb40i2ce.js → 0gxhy80~c0gvp.js} +1 -1
- package/.next/standalone/apps/web/.next/static/chunks/0i9h-39w91ybd.js +6 -0
- package/.next/standalone/apps/web/.next/static/chunks/{0b90ys7wq-p.4.css → 0pm0knaijueoc.css} +1 -1
- package/.next/standalone/apps/web/.next/static/chunks/{16cbfrtkn0.kw.js → 0smdykrt42e.5.js} +10 -10
- 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/{0o6ggm7jrim25.js → 14zh2vf8ljbxo.js} +1 -1
- package/.next/standalone/apps/web/.next/static/chunks/{06yhoqamnoyq-.js → 1624992q-gpj2.js} +10 -10
- package/.next/standalone/apps/web/package.json +1 -0
- package/README.md +1 -1
- package/dist/app.js +3 -3
- 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 -2
- package/dist/server/lib/agent-profiles.d.ts +43 -0
- package/dist/server/lib/agent-profiles.js +127 -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 +19 -2
- package/dist/server/pty-manager.js +38 -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 +84 -37
- package/dist/with-plugin.js +3 -3
- package/npm-shrinkwrap.json +31 -31
- package/package.json +1 -1
- package/tsunagi-marketplace/codex/tsunagi-task.md +120 -0
- 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/0crn03y2tj0lu.js +0 -6
- package/.next/standalone/apps/web/.next/static/chunks/0lvl3ec93cab_.js +0 -7
- package/dist/server/generated/prisma/models/ClaudeProfile.d.ts +0 -939
- package/dist/server/lib/claude-profiles.d.ts +0 -49
- package/dist/server/lib/claude-profiles.js +0 -168
- package/dist/server/routes/claude-profiles.d.ts +0 -2
- package/dist/server/routes/claude-profiles.js +0 -138
- /package/.next/standalone/apps/web/.next/static/{kCD_Mhp9UYT63vnxJPuK4 → ZcOuTrikuO_ZLaERk7FsW}/_buildManifest.js +0 -0
- /package/.next/standalone/apps/web/.next/static/{kCD_Mhp9UYT63vnxJPuK4 → ZcOuTrikuO_ZLaERk7FsW}/_clientMiddlewareManifest.js +0 -0
- /package/.next/standalone/apps/web/.next/static/{kCD_Mhp9UYT63vnxJPuK4 → ZcOuTrikuO_ZLaERk7FsW}/_ssgManifest.js +0 -0
- /package/dist/server/generated/prisma/models/{ClaudeProfile.js → AgentProfile.js} +0 -0
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { prisma } from '../lib/db.js';
|
|
2
|
-
import {
|
|
2
|
+
import { parseTodos } from '../lib/tab-todos.js';
|
|
3
|
+
import { getAgent } from '../lib/agents/index.js';
|
|
3
4
|
export const hookEvents = [];
|
|
4
5
|
/**
|
|
5
6
|
* status から未読フラグを導出する。
|
|
6
7
|
* 完了(success/error)で未読を立て、再実行・セッション終了で落とす。
|
|
7
|
-
* web 側 (apps/web/src/lib/
|
|
8
|
+
* web 側 (apps/web/src/lib/agent-status.ts の unreadForStatus) と同じルール。
|
|
8
9
|
*/
|
|
9
10
|
function unreadForStatus(status) {
|
|
10
11
|
switch (status) {
|
|
@@ -68,88 +69,97 @@ async function updateTabStatus(sessionId, status, todos) {
|
|
|
68
69
|
return { count: 0 };
|
|
69
70
|
}
|
|
70
71
|
}
|
|
72
|
+
/** 正規化した hook イベントでタブの状態を更新し、購読中のクライアントに通知する */
|
|
73
|
+
async function applyHookEvent(fastify, io, event) {
|
|
74
|
+
const { tabId } = event;
|
|
75
|
+
const room = `tab:${tabId}`;
|
|
76
|
+
const setStatus = async (status, emitted = status) => {
|
|
77
|
+
await updateTabStatus(tabId, status);
|
|
78
|
+
io.to(room).emit('status-changed', { sessionId: tabId, status: emitted });
|
|
79
|
+
};
|
|
80
|
+
switch (event.kind) {
|
|
81
|
+
case 'session-start':
|
|
82
|
+
// エージェントが起動しただけ(まだプロンプト処理していない)→ idleのまま通知のみ。
|
|
83
|
+
// タブIDと別のセッションIDを振るエージェント(Codex)は、次回の resume 用に保存する
|
|
84
|
+
if (event.agentSessionId) {
|
|
85
|
+
await prisma.tab
|
|
86
|
+
.updateMany({ where: { tabId }, data: { agentSessionId: event.agentSessionId } })
|
|
87
|
+
.catch((err) => fastify.log.warn(err, '[hooks] Failed to save agent session id'));
|
|
88
|
+
}
|
|
89
|
+
io.to(room).emit('status-changed', { sessionId: tabId, status: 'idle' });
|
|
90
|
+
break;
|
|
91
|
+
case 'prompt':
|
|
92
|
+
// プロンプト送信開始 → running
|
|
93
|
+
await setStatus('running');
|
|
94
|
+
break;
|
|
95
|
+
case 'permission':
|
|
96
|
+
// ツール実行許可待ち → waiting
|
|
97
|
+
await setStatus('waiting');
|
|
98
|
+
break;
|
|
99
|
+
case 'tool-post': {
|
|
100
|
+
// ツール実行完了(許可待ち後のAllow含む)→ runningに戻す。todos を更新するツールなら todos も更新する
|
|
101
|
+
const { applyTodos } = event;
|
|
102
|
+
const todosUpdated = applyTodos !== undefined &&
|
|
103
|
+
(await withTodosLock(tabId, async () => {
|
|
104
|
+
const todos = applyTodos(await loadTabTodos(tabId));
|
|
105
|
+
if (!todos) {
|
|
106
|
+
fastify.log.debug({ tabId, tool: event.toolName }, '[hooks] todo tool ignored (unknown task or unexpected payload)');
|
|
107
|
+
return false;
|
|
108
|
+
}
|
|
109
|
+
const { count } = await updateTabStatus(tabId, 'running', todos);
|
|
110
|
+
fastify.log.info({ tabId, tool: event.toolName, todosCount: todos.length, updatedTabCount: count }, '[hooks] todos updated');
|
|
111
|
+
io.to(room).emit('todos-updated', { sessionId: tabId, todos });
|
|
112
|
+
return true;
|
|
113
|
+
}));
|
|
114
|
+
if (!todosUpdated) {
|
|
115
|
+
await updateTabStatus(tabId, 'running');
|
|
116
|
+
}
|
|
117
|
+
io.to(room).emit('status-changed', { sessionId: tabId, status: 'running' });
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
case 'stop':
|
|
121
|
+
// 正常完了 → success
|
|
122
|
+
await setStatus('success');
|
|
123
|
+
break;
|
|
124
|
+
case 'stop-failure':
|
|
125
|
+
// APIエラーでターン終了 → error
|
|
126
|
+
// todos は残す(エージェント側の進捗はセッションに永続化され、resume 後も続きから使われる)
|
|
127
|
+
await setStatus('error', 'failure');
|
|
128
|
+
break;
|
|
129
|
+
case 'interrupt':
|
|
130
|
+
case 'session-end':
|
|
131
|
+
// 中断・セッション終了 → idle(todos は stop-failure と同じ理由で残す)
|
|
132
|
+
await setStatus('idle');
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
71
136
|
export async function hooksRoutes(fastify) {
|
|
72
137
|
const io = fastify.io;
|
|
73
|
-
// POST /hooks
|
|
74
|
-
fastify.post('/hooks
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
138
|
+
// POST /hooks/:agent - エージェント CLI からの hook 受信
|
|
139
|
+
fastify.post('/hooks/:agent', async (request, reply) => {
|
|
140
|
+
const adapter = getAgent(request.params.agent);
|
|
141
|
+
if (!adapter)
|
|
142
|
+
return reply.status(404).send({ error: 'Unknown agent' });
|
|
143
|
+
const body = request.body ?? {};
|
|
144
|
+
const event = adapter.normalizeHook({ body, headers: request.headers });
|
|
145
|
+
const eventName = typeof body.hook_event_name === 'string' ? body.hook_event_name : undefined;
|
|
146
|
+
fastify.log.info({ agent: adapter.id, eventName, tabId: event?.tabId }, 'Agent hook received');
|
|
79
147
|
// メモリに記録(確認用)
|
|
80
148
|
hookEvents.push({
|
|
81
149
|
receivedAt: new Date().toISOString(),
|
|
150
|
+
agent: adapter.id,
|
|
82
151
|
event: eventName,
|
|
83
|
-
|
|
152
|
+
tabId: event?.tabId,
|
|
84
153
|
raw: body,
|
|
85
154
|
});
|
|
86
155
|
// 最新100件のみ保持
|
|
87
156
|
if (hookEvents.length > 100)
|
|
88
157
|
hookEvents.splice(0, hookEvents.length - 100);
|
|
89
|
-
if (
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
io.to(room).emit('status-changed', { sessionId, status: 'idle' });
|
|
95
|
-
break;
|
|
96
|
-
case 'UserPromptSubmit':
|
|
97
|
-
// プロンプト送信開始 → running状態に更新
|
|
98
|
-
await updateTabStatus(sessionId, 'running');
|
|
99
|
-
io.to(room).emit('status-changed', { sessionId, status: 'running' });
|
|
100
|
-
break;
|
|
101
|
-
case 'PermissionRequest':
|
|
102
|
-
// ツール実行許可待ち → waiting状態に更新
|
|
103
|
-
await updateTabStatus(sessionId, 'waiting');
|
|
104
|
-
io.to(room).emit('status-changed', { sessionId, status: 'waiting' });
|
|
105
|
-
break;
|
|
106
|
-
case 'PostToolUse': {
|
|
107
|
-
// ツール実行完了(PermissionRequest後のAllow含む)→ runningに戻す
|
|
108
|
-
// TodoWrite / Task 系ツールなら todos も更新する
|
|
109
|
-
const toolName = body.tool_name;
|
|
110
|
-
const todosUpdated = toolName !== undefined &&
|
|
111
|
-
TODO_TOOL_NAMES.has(toolName) &&
|
|
112
|
-
(await withTodosLock(sessionId, async () => {
|
|
113
|
-
const todos = applyToolToTodos(await loadTabTodos(sessionId), toolName, body.tool_input, body.tool_response);
|
|
114
|
-
if (!todos) {
|
|
115
|
-
fastify.log.debug({ sessionId, tool: toolName, input: body.tool_input }, '[hooks] todo tool ignored (unknown task or unexpected payload)');
|
|
116
|
-
return false;
|
|
117
|
-
}
|
|
118
|
-
const { count } = await updateTabStatus(sessionId, 'running', todos);
|
|
119
|
-
fastify.log.info({ sessionId, tool: toolName, todosCount: todos.length, updatedTabCount: count }, '[hooks] todos updated');
|
|
120
|
-
io.to(room).emit('todos-updated', { sessionId, todos });
|
|
121
|
-
return true;
|
|
122
|
-
}));
|
|
123
|
-
if (!todosUpdated) {
|
|
124
|
-
await updateTabStatus(sessionId, 'running');
|
|
125
|
-
}
|
|
126
|
-
io.to(room).emit('status-changed', { sessionId, status: 'running' });
|
|
127
|
-
break;
|
|
128
|
-
}
|
|
129
|
-
case 'PreToolUse':
|
|
130
|
-
// ログ記録のみ
|
|
131
|
-
break;
|
|
132
|
-
case 'Stop':
|
|
133
|
-
// 正常完了 → success状態に更新
|
|
134
|
-
await updateTabStatus(sessionId, 'success');
|
|
135
|
-
io.to(room).emit('status-changed', { sessionId, status: 'success' });
|
|
136
|
-
break;
|
|
137
|
-
case 'StopFailure':
|
|
138
|
-
// APIエラーでターン終了 → failure状態に更新
|
|
139
|
-
// todos は残す(Claude 側の Task はセッションに永続化され、--resume 後も続きから使われる)
|
|
140
|
-
await updateTabStatus(sessionId, 'error');
|
|
141
|
-
io.to(room).emit('status-changed', { sessionId, status: 'failure' });
|
|
142
|
-
break;
|
|
143
|
-
case 'SessionEnd':
|
|
144
|
-
// セッション終了(Escキー中断・Ctrl+C・/exit等)→ idle状態に更新(todos は StopFailure と同じ理由で残す)
|
|
145
|
-
// reason: "prompt_input_exit" = ユーザー中断、"other" = プロセスkill等
|
|
146
|
-
fastify.log.info({ sessionId, reason: body.reason }, 'SessionEnd received');
|
|
147
|
-
await updateTabStatus(sessionId, 'idle');
|
|
148
|
-
io.to(room).emit('status-changed', { sessionId, status: 'idle' });
|
|
149
|
-
break;
|
|
150
|
-
default:
|
|
151
|
-
fastify.log.debug({ eventName }, 'Unhandled hook event');
|
|
152
|
-
}
|
|
158
|
+
if (event) {
|
|
159
|
+
await applyHookEvent(fastify, io, event);
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
fastify.log.debug({ agent: adapter.id, eventName }, 'Unhandled hook event');
|
|
153
163
|
}
|
|
154
164
|
return reply.status(200).send({ ok: true });
|
|
155
165
|
});
|
|
@@ -22,7 +22,7 @@ const taskIdentifierProperties = {
|
|
|
22
22
|
const STATUS_ENUM = ['backlog', 'planning', 'coding', 'reviewing', 'done'];
|
|
23
23
|
/** status description(LLMバイアス対策の警告文言付き) */
|
|
24
24
|
const STATUS_DESCRIPTION = 'ステータス。backlog → planning → coding → reviewing → done の順で遷移。' +
|
|
25
|
-
'注意: `in_progress` / `completed` / `todo`
|
|
25
|
+
'注意: `in_progress` / `completed` / `todo` は使用不可(エージェント組み込みの TODO 管理ツール(Claude Code の TaskUpdate、Codex の update_plan)の語彙と混同しないこと)。' +
|
|
26
26
|
'実装中 = `coding`、完了 = `done`。';
|
|
27
27
|
/** typo 検出ヒント(schema validation が skip された場合のフォールバック) */
|
|
28
28
|
const TYPO_HINTS = {
|
|
@@ -74,7 +74,7 @@ function createMcpServer(io) {
|
|
|
74
74
|
],
|
|
75
75
|
description: 'ステータスフィルタ。単一値(例: "backlog")または配列(例: ["backlog", "planning"])で指定。' +
|
|
76
76
|
'有効値: backlog / planning / coding / reviewing / done。' +
|
|
77
|
-
'注意: `in_progress` / `completed` / `todo`
|
|
77
|
+
'注意: `in_progress` / `completed` / `todo` は使用不可(エージェント組み込みの TODO 管理ツールの語彙)。',
|
|
78
78
|
},
|
|
79
79
|
},
|
|
80
80
|
additionalProperties: false,
|
|
@@ -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 から「端末への問い合わせ(クエリ)」シーケンスを除去する。
|
|
@@ -78,6 +78,10 @@ export async function terminalRoutes(fastify) {
|
|
|
78
78
|
socket.join(room);
|
|
79
79
|
return;
|
|
80
80
|
}
|
|
81
|
+
// 別セッションへ join し直した場合は、前のセッションのサイズ登録を外す
|
|
82
|
+
if (boundSessionId && boundSessionId !== sessionId) {
|
|
83
|
+
ptyManager.removeTerminalSocket(boundSessionId, socket.id);
|
|
84
|
+
}
|
|
81
85
|
boundSessionId = sessionId;
|
|
82
86
|
const session = ptyManager.getSession(sessionId);
|
|
83
87
|
if (!session) {
|
|
@@ -92,6 +96,7 @@ export async function terminalRoutes(fastify) {
|
|
|
92
96
|
dataHandlerDispose = null;
|
|
93
97
|
exitHandlerDispose = null;
|
|
94
98
|
socket.removeAllListeners('resize');
|
|
99
|
+
socket.removeAllListeners('claim');
|
|
95
100
|
socket.removeAllListeners('input');
|
|
96
101
|
socket.join(room);
|
|
97
102
|
// 環境変数の変更が未反映ならクライアントに伝える(反映待ちバッジ)
|
|
@@ -140,7 +145,7 @@ export async function terminalRoutes(fastify) {
|
|
|
140
145
|
if (session.respawning)
|
|
141
146
|
return;
|
|
142
147
|
io.to(room).emit('exit', { exitCode });
|
|
143
|
-
// Ctrl+C等でClaudeが強制終了した場合に
|
|
148
|
+
// Ctrl+C等でClaudeが強制終了した場合にagentStatusをidleにリセット
|
|
144
149
|
// todos は残す(Claude 側の Task はセッションに永続化され、--resume 後も続きから使われる)
|
|
145
150
|
io.to(room).emit('status-changed', { sessionId, status: 'idle' });
|
|
146
151
|
prisma.tab
|
|
@@ -154,11 +159,16 @@ export async function terminalRoutes(fastify) {
|
|
|
154
159
|
ptyManager.deleteSession(sessionId);
|
|
155
160
|
});
|
|
156
161
|
exitHandlerDispose = () => exitHandler.dispose();
|
|
157
|
-
// resize イベント: PTY
|
|
162
|
+
// resize イベント: この socket のサイズを記録し、所有者 socket の場合のみ PTY へ反映する。
|
|
163
|
+
// 同一タスクを複数ウィンドウで開いた場合に、フォアグラウンドでない側のサイズで
|
|
164
|
+
// PTY が変わり Claude の表示幅がずれるのを防ぐ(所有者の切り替えは claim で行う)。
|
|
158
165
|
socket.on('resize', ({ sessionId: sid, cols, rows }) => {
|
|
159
166
|
if (sid !== sessionId)
|
|
160
167
|
return;
|
|
161
|
-
|
|
168
|
+
ptyManager.setTerminalSize(sessionId, socket.id, { cols, rows });
|
|
169
|
+
if (ptyManager.getActiveSocket(sessionId) === socket.id) {
|
|
170
|
+
ptyProcess.resize(cols, rows);
|
|
171
|
+
}
|
|
162
172
|
// reused時: 初回 resize 後にバッファリングしていた出力をフラッシュ
|
|
163
173
|
if (!initialResizeHandled) {
|
|
164
174
|
initialResizeHandled = true;
|
|
@@ -169,6 +179,17 @@ export async function terminalRoutes(fastify) {
|
|
|
169
179
|
}
|
|
170
180
|
}
|
|
171
181
|
});
|
|
182
|
+
// claim イベント: フォアグラウンドになった socket が所有者になり、PTY を自分のサイズに合わせる。
|
|
183
|
+
// サイズが変われば SIGWINCH で Claude が描き直す。
|
|
184
|
+
socket.on('claim', ({ sessionId: sid, cols, rows }) => {
|
|
185
|
+
if (sid !== sessionId)
|
|
186
|
+
return;
|
|
187
|
+
ptyManager.setTerminalSize(sessionId, socket.id, { cols, rows });
|
|
188
|
+
ptyManager.setActiveSocket(sessionId, socket.id);
|
|
189
|
+
if (ptyProcess.cols !== cols || ptyProcess.rows !== rows) {
|
|
190
|
+
ptyProcess.resize(cols, rows);
|
|
191
|
+
}
|
|
192
|
+
});
|
|
172
193
|
// input イベント: 所有者 socket からの入力のみ PTY へ書き込む。
|
|
173
194
|
// ゾンビ/非所有 socket(再接続前の旧 socket・誤バインド socket 等)からの重複 input は
|
|
174
195
|
// 破棄し、1 キーストロークの多重書き込み(例: /clear が連続入力される)を防ぐ。
|
|
@@ -199,7 +220,20 @@ export async function terminalRoutes(fastify) {
|
|
|
199
220
|
// 遅延切断では GC を張らない(現役セッションが誤って GC 対象になるのを防ぐ)。
|
|
200
221
|
const wasOwner = ptyManager.getActiveSocket(boundSessionId) === socket.id;
|
|
201
222
|
ptyManager.clearActiveSocket(boundSessionId, socket.id);
|
|
202
|
-
|
|
223
|
+
const next = ptyManager.removeTerminalSocket(boundSessionId, socket.id);
|
|
224
|
+
if (wasOwner && next) {
|
|
225
|
+
// 同じ PTY を表示している socket が残っている → 最後に使われた socket に所有権と
|
|
226
|
+
// サイズを引き継ぐ(表示中なので GC も cols の縮小も行わない)
|
|
227
|
+
ptyManager.setActiveSocket(boundSessionId, next.socketId);
|
|
228
|
+
const session = ptyManager.getSession(boundSessionId);
|
|
229
|
+
try {
|
|
230
|
+
session?.pty.resize(next.size.cols, next.size.rows);
|
|
231
|
+
}
|
|
232
|
+
catch {
|
|
233
|
+
// 終了済みの PTY は無視する
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
else if (wasOwner) {
|
|
203
237
|
ptyManager.scheduleGc(boundSessionId);
|
|
204
238
|
// 次に表示されたとき Claude に描き直させるため、表示中のクライアントがいない間に
|
|
205
239
|
// cols を縮めておく(REDRAW_BUMP_COLS 参照)
|
|
@@ -216,7 +250,7 @@ export async function terminalRoutes(fastify) {
|
|
|
216
250
|
});
|
|
217
251
|
// POST /terminal/sessions - セッション作成(または既存セッション再利用)
|
|
218
252
|
fastify.post('/terminal/sessions', async (request, reply) => {
|
|
219
|
-
const { cwd, env, sessionId: requestedSessionId, claude, command } = request.body ?? {};
|
|
253
|
+
const { cwd, env, sessionId: requestedSessionId, agent, claude, command } = request.body ?? {};
|
|
220
254
|
const sessionId = requestedSessionId ?? crypto.randomUUID();
|
|
221
255
|
// 既存セッションが生きていれば再利用
|
|
222
256
|
const existing = ptyManager.getSession(sessionId);
|
|
@@ -224,6 +258,10 @@ export async function terminalRoutes(fastify) {
|
|
|
224
258
|
fastify.log.info({ sessionId }, 'Reusing existing PTY session');
|
|
225
259
|
return reply.status(200).send({ sessionId, reused: true });
|
|
226
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
|
+
}
|
|
227
265
|
const pending = pendingCreations.get(sessionId);
|
|
228
266
|
const creation = pending ??
|
|
229
267
|
(async () => {
|
|
@@ -231,7 +269,7 @@ export async function terminalRoutes(fastify) {
|
|
|
231
269
|
const launch = await resolvePtyLaunch(sessionId, launchRequest);
|
|
232
270
|
await startPtySession(sessionId, launch, {
|
|
233
271
|
request: launchRequest,
|
|
234
|
-
|
|
272
|
+
launchAgent: Boolean(agent ?? claude),
|
|
235
273
|
command,
|
|
236
274
|
});
|
|
237
275
|
})();
|
|
@@ -256,33 +294,42 @@ export async function terminalRoutes(fastify) {
|
|
|
256
294
|
return reply.status(500).send({ error: message });
|
|
257
295
|
}
|
|
258
296
|
});
|
|
259
|
-
// POST /terminal/sessions/:sessionId/
|
|
260
|
-
// コマンドはタブの mode に応じてサーバーで組み立てる(ローカルLLM
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
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
|
+
}
|
|
286
333
|
// POST /terminal/sessions/:sessionId/respawn - 環境変数の変更を今すぐ反映する(PTY を作り直す)
|
|
287
334
|
fastify.post('/terminal/sessions/:sessionId/respawn', async (request, reply) => {
|
|
288
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.0",
|
|
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.0",
|
|
10
10
|
"license": "SEE LICENSE IN LICENSE",
|
|
11
11
|
"os": [
|
|
12
12
|
"darwin",
|
|
@@ -107,9 +107,9 @@
|
|
|
107
107
|
"license": "MIT"
|
|
108
108
|
},
|
|
109
109
|
"node_modules/@fastify/cors": {
|
|
110
|
-
"version": "11.3.
|
|
111
|
-
"resolved": "https://registry.npmjs.org/@fastify/cors/-/cors-11.3.
|
|
112
|
-
"integrity": "sha512-
|
|
110
|
+
"version": "11.3.1",
|
|
111
|
+
"resolved": "https://registry.npmjs.org/@fastify/cors/-/cors-11.3.1.tgz",
|
|
112
|
+
"integrity": "sha512-gZXNzd6FLHzOIfvoK4+Az3Wko2V6Y0MIsLxpyo4AEYl7a9q1JBPwPaxLea4nkr++8FCiJiPpYYo6E02uZW0dqw==",
|
|
113
113
|
"funding": [
|
|
114
114
|
{
|
|
115
115
|
"type": "github",
|
|
@@ -127,9 +127,9 @@
|
|
|
127
127
|
}
|
|
128
128
|
},
|
|
129
129
|
"node_modules/@fastify/deepmerge": {
|
|
130
|
-
"version": "3.2.
|
|
131
|
-
"resolved": "https://registry.npmjs.org/@fastify/deepmerge/-/deepmerge-3.2.
|
|
132
|
-
"integrity": "sha512-
|
|
130
|
+
"version": "3.2.2",
|
|
131
|
+
"resolved": "https://registry.npmjs.org/@fastify/deepmerge/-/deepmerge-3.2.2.tgz",
|
|
132
|
+
"integrity": "sha512-155eqA/WMQdN6gUD4RrhS2K0Pcz2Ou9pQ86L0sipOpP9ONbTA6oYw/hW4VdBjR4egcDHqmWUK9x80oUX7S1mDQ==",
|
|
133
133
|
"funding": [
|
|
134
134
|
{
|
|
135
135
|
"type": "github",
|
|
@@ -194,9 +194,9 @@
|
|
|
194
194
|
"license": "MIT"
|
|
195
195
|
},
|
|
196
196
|
"node_modules/@fastify/http-proxy": {
|
|
197
|
-
"version": "11.6.
|
|
198
|
-
"resolved": "https://registry.npmjs.org/@fastify/http-proxy/-/http-proxy-11.6.
|
|
199
|
-
"integrity": "sha512-
|
|
197
|
+
"version": "11.6.4",
|
|
198
|
+
"resolved": "https://registry.npmjs.org/@fastify/http-proxy/-/http-proxy-11.6.4.tgz",
|
|
199
|
+
"integrity": "sha512-JPsbLX9D5X5yES1A6M2yx1i2PGf8eNyKT48j+6pgLIwxfRYpj1MEzR1CwASRvqdZOWhcPmdsZiIKehSgioW6ww==",
|
|
200
200
|
"funding": [
|
|
201
201
|
{
|
|
202
202
|
"type": "github",
|
|
@@ -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",
|
|
@@ -303,15 +303,15 @@
|
|
|
303
303
|
}
|
|
304
304
|
},
|
|
305
305
|
"node_modules/@hono/node-server": {
|
|
306
|
-
"version": "2.1.
|
|
307
|
-
"resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-2.1.
|
|
308
|
-
"integrity": "sha512-
|
|
306
|
+
"version": "2.1.4",
|
|
307
|
+
"resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-2.1.4.tgz",
|
|
308
|
+
"integrity": "sha512-2g1qeHl4BduwDn6L8nkAvDrPUWPMlkQ//a5NhP/zIyaXKMjZNRV+cG9Csu+BiJFf6+68pqzjf4Hi5sJGKHuS1g==",
|
|
309
309
|
"license": "MIT",
|
|
310
310
|
"engines": {
|
|
311
311
|
"node": ">=20"
|
|
312
312
|
},
|
|
313
313
|
"peerDependencies": {
|
|
314
|
-
"hono": "^4"
|
|
314
|
+
"hono": "^4 || ^5.0.0-0"
|
|
315
315
|
}
|
|
316
316
|
},
|
|
317
317
|
"node_modules/@kwsites/file-exists": {
|
|
@@ -500,9 +500,9 @@
|
|
|
500
500
|
]
|
|
501
501
|
},
|
|
502
502
|
"node_modules/@modelcontextprotocol/sdk": {
|
|
503
|
-
"version": "1.32.
|
|
504
|
-
"resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.32.
|
|
505
|
-
"integrity": "sha512-
|
|
503
|
+
"version": "1.32.1",
|
|
504
|
+
"resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.32.1.tgz",
|
|
505
|
+
"integrity": "sha512-2DdE+SJDtzLEEWzY1ZjY7Q+VcPhcV1KisD3zI4u0XZyktsjHum1mwbMI+JaulUBi2OZk+KJAi2uPXzxichPkdw==",
|
|
506
506
|
"license": "MIT",
|
|
507
507
|
"dependencies": {
|
|
508
508
|
"@hono/node-server": "^1.19.9 || ^2.0.5",
|
|
@@ -2233,9 +2233,9 @@
|
|
|
2233
2233
|
}
|
|
2234
2234
|
},
|
|
2235
2235
|
"node_modules/express-rate-limit": {
|
|
2236
|
-
"version": "8.7.
|
|
2237
|
-
"resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.7.
|
|
2238
|
-
"integrity": "sha512-
|
|
2236
|
+
"version": "8.7.1",
|
|
2237
|
+
"resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.7.1.tgz",
|
|
2238
|
+
"integrity": "sha512-2FXbqkygil3mZiXzEtM0IjE/UBmBNot0J1GEVrJT4JbrvwOSoEtqtO+wHbiMQELWe1eNvHoYRg2dkjOid+6JkA==",
|
|
2239
2239
|
"license": "MIT",
|
|
2240
2240
|
"dependencies": {
|
|
2241
2241
|
"debug": "^4.4.3",
|
|
@@ -2280,9 +2280,9 @@
|
|
|
2280
2280
|
}
|
|
2281
2281
|
},
|
|
2282
2282
|
"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-
|
|
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",
|