@schoolai/shipyard-mcp 0.2.2-next.482 → 0.2.2-next.485
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/apps/hook/dist/index.js +4 -3
- package/apps/server/dist/{chunk-76JWRTPI.js → chunk-BBYZISY2.js} +27 -3
- package/apps/server/dist/{chunk-BWP37ADP.js → chunk-NH6GXGQO.js} +1 -1
- package/apps/server/dist/{chunk-E5DWX2WU.js → chunk-OLFHVNPI.js} +29 -0
- package/apps/server/dist/{dist-ORKL4P3L.js → dist-D4DG2R4R.js} +3 -1
- package/apps/server/dist/index.js +277 -59
- package/apps/server/dist/{input-request-manager-73GSTOIB.js → input-request-manager-3STPPPYU.js} +2 -2
- package/apps/server/dist/{server-identity-6PHKR2FY.js → server-identity-LSZ4CZRK.js} +5 -3
- package/package.json +1 -1
package/apps/hook/dist/index.js
CHANGED
|
@@ -28494,7 +28494,7 @@ init_cjs_shims();
|
|
|
28494
28494
|
// ../../packages/schema/dist/index.mjs
|
|
28495
28495
|
init_cjs_shims();
|
|
28496
28496
|
|
|
28497
|
-
// ../../packages/schema/dist/yjs-helpers-
|
|
28497
|
+
// ../../packages/schema/dist/yjs-helpers-A0hIPiRs.mjs
|
|
28498
28498
|
init_cjs_shims();
|
|
28499
28499
|
|
|
28500
28500
|
// ../../packages/schema/dist/plan.mjs
|
|
@@ -42552,7 +42552,8 @@ var PlanEventSchema = external_exports.discriminatedUnion("type", [
|
|
|
42552
42552
|
PlanEventBaseSchema.extend({
|
|
42553
42553
|
type: external_exports.literal("agent_activity"),
|
|
42554
42554
|
data: AgentActivityDataSchema
|
|
42555
|
-
})
|
|
42555
|
+
}),
|
|
42556
|
+
PlanEventBaseSchema.extend({ type: external_exports.literal("session_token_regenerated") })
|
|
42556
42557
|
]);
|
|
42557
42558
|
var PlanMetadataBaseSchema = external_exports.object({
|
|
42558
42559
|
id: external_exports.string(),
|
|
@@ -42665,7 +42666,7 @@ var PRReviewCommentSchema = external_exports.object({
|
|
|
42665
42666
|
resolved: external_exports.boolean().optional()
|
|
42666
42667
|
});
|
|
42667
42668
|
|
|
42668
|
-
// ../../packages/schema/dist/yjs-helpers-
|
|
42669
|
+
// ../../packages/schema/dist/yjs-helpers-A0hIPiRs.mjs
|
|
42669
42670
|
function assertNever2(value) {
|
|
42670
42671
|
throw new Error(`Unhandled discriminated union member: ${JSON.stringify(value)}`);
|
|
42671
42672
|
}
|
|
@@ -552,7 +552,8 @@ var PlanEventTypes = [
|
|
|
552
552
|
"input_request_created",
|
|
553
553
|
"input_request_answered",
|
|
554
554
|
"input_request_declined",
|
|
555
|
-
"agent_activity"
|
|
555
|
+
"agent_activity",
|
|
556
|
+
"session_token_regenerated"
|
|
556
557
|
];
|
|
557
558
|
var AgentActivityTypes = [
|
|
558
559
|
"help_request",
|
|
@@ -701,7 +702,8 @@ var PlanEventSchema = z.discriminatedUnion("type", [
|
|
|
701
702
|
PlanEventBaseSchema.extend({
|
|
702
703
|
type: z.literal("agent_activity"),
|
|
703
704
|
data: AgentActivityDataSchema
|
|
704
|
-
})
|
|
705
|
+
}),
|
|
706
|
+
PlanEventBaseSchema.extend({ type: z.literal("session_token_regenerated") })
|
|
705
707
|
]);
|
|
706
708
|
function isInboxWorthy(event, username, ownerId) {
|
|
707
709
|
if (!event.inboxWorthy) return false;
|
|
@@ -863,7 +865,7 @@ function createHandedOffConversationVersion(params) {
|
|
|
863
865
|
return ConversationVersionSchema.parse(version);
|
|
864
866
|
}
|
|
865
867
|
|
|
866
|
-
// ../../packages/schema/dist/yjs-helpers-
|
|
868
|
+
// ../../packages/schema/dist/yjs-helpers-A0hIPiRs.mjs
|
|
867
869
|
import { z as z2 } from "zod";
|
|
868
870
|
import { nanoid as nanoid2 } from "nanoid";
|
|
869
871
|
import * as Y from "yjs";
|
|
@@ -1753,6 +1755,27 @@ function declineInputRequest(ydoc, requestId) {
|
|
|
1753
1755
|
});
|
|
1754
1756
|
return { success: true };
|
|
1755
1757
|
}
|
|
1758
|
+
function atomicRegenerateTokenIfOwner(ydoc, expectedOwnerId, newTokenHash, actor) {
|
|
1759
|
+
let result = {
|
|
1760
|
+
success: false,
|
|
1761
|
+
actualOwner: void 0
|
|
1762
|
+
};
|
|
1763
|
+
ydoc.transact(() => {
|
|
1764
|
+
const map = ydoc.getMap(YDOC_KEYS.METADATA);
|
|
1765
|
+
const currentOwner = map.get("ownerId");
|
|
1766
|
+
if (currentOwner !== expectedOwnerId) {
|
|
1767
|
+
result = {
|
|
1768
|
+
success: false,
|
|
1769
|
+
actualOwner: currentOwner
|
|
1770
|
+
};
|
|
1771
|
+
return;
|
|
1772
|
+
}
|
|
1773
|
+
map.set("sessionTokenHash", newTokenHash);
|
|
1774
|
+
map.set("updatedAt", Date.now());
|
|
1775
|
+
result = { success: true };
|
|
1776
|
+
}, actor ? { actor } : void 0);
|
|
1777
|
+
return result;
|
|
1778
|
+
}
|
|
1756
1779
|
|
|
1757
1780
|
// ../../packages/schema/dist/url-encoding.mjs
|
|
1758
1781
|
var import_lz_string = __toESM(require_lz_string(), 1);
|
|
@@ -2896,6 +2919,7 @@ export {
|
|
|
2896
2919
|
answerInputRequest,
|
|
2897
2920
|
cancelInputRequest,
|
|
2898
2921
|
declineInputRequest,
|
|
2922
|
+
atomicRegenerateTokenIfOwner,
|
|
2899
2923
|
isUrlEncodedPlanV1,
|
|
2900
2924
|
isUrlEncodedPlanV2,
|
|
2901
2925
|
encodePlan,
|
|
@@ -152,6 +152,34 @@ function getUsernameFromGitConfig() {
|
|
|
152
152
|
return null;
|
|
153
153
|
}
|
|
154
154
|
}
|
|
155
|
+
async function getVerifiedGitHubUsername() {
|
|
156
|
+
if (githubConfig.GITHUB_USERNAME) {
|
|
157
|
+
logger.info({ username: githubConfig.GITHUB_USERNAME }, "Using GITHUB_USERNAME from env");
|
|
158
|
+
return githubConfig.GITHUB_USERNAME;
|
|
159
|
+
}
|
|
160
|
+
if (githubConfig.GITHUB_TOKEN) {
|
|
161
|
+
try {
|
|
162
|
+
const username = await getUsernameFromToken(githubConfig.GITHUB_TOKEN);
|
|
163
|
+
if (username) {
|
|
164
|
+
logger.info({ username }, "Got verified username from GITHUB_TOKEN");
|
|
165
|
+
return username;
|
|
166
|
+
}
|
|
167
|
+
} catch (error) {
|
|
168
|
+
logger.warn({ error }, "Failed to get username from GITHUB_TOKEN");
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
try {
|
|
172
|
+
const username = getUsernameFromCLI();
|
|
173
|
+
if (username) {
|
|
174
|
+
logger.info({ username }, "Got verified username from gh CLI");
|
|
175
|
+
return username;
|
|
176
|
+
}
|
|
177
|
+
} catch (error) {
|
|
178
|
+
logger.debug({ error }, "Failed to get username from gh CLI");
|
|
179
|
+
}
|
|
180
|
+
logger.warn("No verified GitHub authentication available");
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
155
183
|
function getGitBranch() {
|
|
156
184
|
try {
|
|
157
185
|
return execSync2("git branch --show-current", {
|
|
@@ -176,5 +204,6 @@ export {
|
|
|
176
204
|
githubConfig,
|
|
177
205
|
getRepositoryFullName,
|
|
178
206
|
getGitHubUsername,
|
|
207
|
+
getVerifiedGitHubUsername,
|
|
179
208
|
getEnvironmentContext
|
|
180
209
|
};
|
|
@@ -92,6 +92,7 @@ import {
|
|
|
92
92
|
asWebRTCPeerId,
|
|
93
93
|
assertNever,
|
|
94
94
|
assertNeverP2PMessage,
|
|
95
|
+
atomicRegenerateTokenIfOwner,
|
|
95
96
|
buildInviteUrl,
|
|
96
97
|
cancelInputRequest,
|
|
97
98
|
claudeCodeToA2A,
|
|
@@ -204,7 +205,7 @@ import {
|
|
|
204
205
|
updateLinkedPRStatus,
|
|
205
206
|
updatePlanIndexViewedBy,
|
|
206
207
|
validateA2AMessages
|
|
207
|
-
} from "./chunk-
|
|
208
|
+
} from "./chunk-BBYZISY2.js";
|
|
208
209
|
import "./chunk-JSBRDJBE.js";
|
|
209
210
|
export {
|
|
210
211
|
A2ADataPartSchema,
|
|
@@ -300,6 +301,7 @@ export {
|
|
|
300
301
|
asWebRTCPeerId,
|
|
301
302
|
assertNever,
|
|
302
303
|
assertNeverP2PMessage,
|
|
304
|
+
atomicRegenerateTokenIfOwner,
|
|
303
305
|
buildInviteUrl,
|
|
304
306
|
cancelInputRequest,
|
|
305
307
|
claudeCodeToA2A,
|
|
@@ -3,8 +3,9 @@ import {
|
|
|
3
3
|
getEnvironmentContext,
|
|
4
4
|
getGitHubUsername,
|
|
5
5
|
getRepositoryFullName,
|
|
6
|
+
getVerifiedGitHubUsername,
|
|
6
7
|
githubConfig
|
|
7
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-OLFHVNPI.js";
|
|
8
9
|
import {
|
|
9
10
|
assertNever,
|
|
10
11
|
getSessionIdByPlanId,
|
|
@@ -19,7 +20,7 @@ import {
|
|
|
19
20
|
} from "./chunk-EBNL5ZX7.js";
|
|
20
21
|
import {
|
|
21
22
|
InputRequestManager
|
|
22
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-NH6GXGQO.js";
|
|
23
24
|
import {
|
|
24
25
|
ArtifactSchema,
|
|
25
26
|
DeliverableSchema,
|
|
@@ -40,6 +41,7 @@ import {
|
|
|
40
41
|
addPRReviewComment,
|
|
41
42
|
addSnapshot,
|
|
42
43
|
appRouter,
|
|
44
|
+
atomicRegenerateTokenIfOwner,
|
|
43
45
|
createInitialConversationVersion,
|
|
44
46
|
createLinkedPR,
|
|
45
47
|
createPlanSnapshot,
|
|
@@ -69,7 +71,7 @@ import {
|
|
|
69
71
|
setPlanMetadata,
|
|
70
72
|
touchPlanIndexEntry,
|
|
71
73
|
transitionPlanStatus
|
|
72
|
-
} from "./chunk-
|
|
74
|
+
} from "./chunk-BBYZISY2.js";
|
|
73
75
|
import {
|
|
74
76
|
loadEnv,
|
|
75
77
|
logger
|
|
@@ -2472,7 +2474,7 @@ import * as os from "os";
|
|
|
2472
2474
|
import * as path from "path";
|
|
2473
2475
|
import * as vm from "vm";
|
|
2474
2476
|
import ffmpegInstaller from "@ffmpeg-installer/ffmpeg";
|
|
2475
|
-
import { z as
|
|
2477
|
+
import { z as z13 } from "zod";
|
|
2476
2478
|
|
|
2477
2479
|
// src/tools/add-artifact.ts
|
|
2478
2480
|
import { execSync } from "child_process";
|
|
@@ -2538,6 +2540,7 @@ var TOOL_NAMES = {
|
|
|
2538
2540
|
EXECUTE_CODE: "execute_code",
|
|
2539
2541
|
LINK_PR: "link_pr",
|
|
2540
2542
|
READ_PLAN: "read_plan",
|
|
2543
|
+
REGENERATE_SESSION_TOKEN: "regenerate_session_token",
|
|
2541
2544
|
REQUEST_USER_INPUT: "request_user_input",
|
|
2542
2545
|
SETUP_REVIEW_NOTIFICATION: "setup_review_notification",
|
|
2543
2546
|
UPDATE_BLOCK_CONTENT: "update_block_content",
|
|
@@ -4136,11 +4139,146 @@ OUTPUT INCLUDES:
|
|
|
4136
4139
|
}
|
|
4137
4140
|
};
|
|
4138
4141
|
|
|
4139
|
-
// src/tools/
|
|
4142
|
+
// src/tools/regenerate-session-token.ts
|
|
4140
4143
|
import { z as z9 } from "zod";
|
|
4141
|
-
var
|
|
4142
|
-
planId: z9.string().describe("
|
|
4143
|
-
|
|
4144
|
+
var RegenerateSessionTokenInput = z9.object({
|
|
4145
|
+
planId: z9.string().describe("The plan ID to regenerate token for")
|
|
4146
|
+
});
|
|
4147
|
+
var regenerateSessionTokenTool = {
|
|
4148
|
+
definition: {
|
|
4149
|
+
name: TOOL_NAMES.REGENERATE_SESSION_TOKEN,
|
|
4150
|
+
description: `Regenerate the session token for a plan.
|
|
4151
|
+
|
|
4152
|
+
USE WHEN:
|
|
4153
|
+
- Your Claude Code session ended and you lost the original token
|
|
4154
|
+
- You need to resume work on a plan you own
|
|
4155
|
+
- The old token may have been compromised
|
|
4156
|
+
|
|
4157
|
+
REQUIREMENTS:
|
|
4158
|
+
- You must be the plan owner (verified via GitHub identity)
|
|
4159
|
+
- The plan must exist and have an ownerId set
|
|
4160
|
+
|
|
4161
|
+
RETURNS:
|
|
4162
|
+
- New session token that can be used for add_artifact, read_plan, etc.
|
|
4163
|
+
|
|
4164
|
+
SECURITY:
|
|
4165
|
+
- Only the plan owner can regenerate tokens
|
|
4166
|
+
- Old token is immediately invalidated
|
|
4167
|
+
- New token is returned only once - store it securely`,
|
|
4168
|
+
inputSchema: {
|
|
4169
|
+
type: "object",
|
|
4170
|
+
properties: {
|
|
4171
|
+
planId: { type: "string", description: "The plan ID to regenerate token for" }
|
|
4172
|
+
},
|
|
4173
|
+
required: ["planId"]
|
|
4174
|
+
}
|
|
4175
|
+
},
|
|
4176
|
+
handler: async (args) => {
|
|
4177
|
+
const { planId } = RegenerateSessionTokenInput.parse(args);
|
|
4178
|
+
logger.info({ planId }, "Attempting to regenerate session token");
|
|
4179
|
+
const currentUser = await getVerifiedGitHubUsername();
|
|
4180
|
+
if (!currentUser) {
|
|
4181
|
+
return {
|
|
4182
|
+
content: [
|
|
4183
|
+
{
|
|
4184
|
+
type: "text",
|
|
4185
|
+
text: `Token regeneration requires verified GitHub authentication.
|
|
4186
|
+
|
|
4187
|
+
Please configure ONE of:
|
|
4188
|
+
1. GITHUB_USERNAME environment variable
|
|
4189
|
+
2. GITHUB_TOKEN environment variable (will verify via API)
|
|
4190
|
+
3. Run: gh auth login
|
|
4191
|
+
|
|
4192
|
+
Note: git config user.name is NOT accepted for security-critical operations.`
|
|
4193
|
+
}
|
|
4194
|
+
],
|
|
4195
|
+
isError: true
|
|
4196
|
+
};
|
|
4197
|
+
}
|
|
4198
|
+
const doc = await getOrCreateDoc3(planId);
|
|
4199
|
+
const metadata = getPlanMetadata(doc);
|
|
4200
|
+
if (!metadata) {
|
|
4201
|
+
return {
|
|
4202
|
+
content: [{ type: "text", text: `Plan "${planId}" not found.` }],
|
|
4203
|
+
isError: true
|
|
4204
|
+
};
|
|
4205
|
+
}
|
|
4206
|
+
if (!metadata.ownerId) {
|
|
4207
|
+
return {
|
|
4208
|
+
content: [
|
|
4209
|
+
{
|
|
4210
|
+
type: "text",
|
|
4211
|
+
text: `Plan "${planId}" has no owner set. Cannot regenerate token for ownerless plans.`
|
|
4212
|
+
}
|
|
4213
|
+
],
|
|
4214
|
+
isError: true
|
|
4215
|
+
};
|
|
4216
|
+
}
|
|
4217
|
+
const newToken = generateSessionToken();
|
|
4218
|
+
const newTokenHash = hashSessionToken(newToken);
|
|
4219
|
+
const updateResult = atomicRegenerateTokenIfOwner(
|
|
4220
|
+
doc,
|
|
4221
|
+
metadata.ownerId,
|
|
4222
|
+
newTokenHash,
|
|
4223
|
+
currentUser
|
|
4224
|
+
);
|
|
4225
|
+
if (!updateResult.success) {
|
|
4226
|
+
const actualOwner = updateResult.actualOwner;
|
|
4227
|
+
if (actualOwner !== currentUser) {
|
|
4228
|
+
logger.warn(
|
|
4229
|
+
{ planId, expectedOwner: metadata.ownerId, actualOwner, currentUser },
|
|
4230
|
+
"Token regeneration denied - ownership changed during operation"
|
|
4231
|
+
);
|
|
4232
|
+
return {
|
|
4233
|
+
content: [
|
|
4234
|
+
{
|
|
4235
|
+
type: "text",
|
|
4236
|
+
text: `Access denied. You do not have permission to regenerate the session token for plan "${planId}".`
|
|
4237
|
+
}
|
|
4238
|
+
],
|
|
4239
|
+
isError: true
|
|
4240
|
+
};
|
|
4241
|
+
}
|
|
4242
|
+
logger.error(
|
|
4243
|
+
{ planId, expectedOwner: metadata.ownerId, actualOwner, currentUser },
|
|
4244
|
+
"Unexpected failure in atomic token regeneration"
|
|
4245
|
+
);
|
|
4246
|
+
return {
|
|
4247
|
+
content: [
|
|
4248
|
+
{
|
|
4249
|
+
type: "text",
|
|
4250
|
+
text: "Token regeneration failed due to an unexpected error. Please try again."
|
|
4251
|
+
}
|
|
4252
|
+
],
|
|
4253
|
+
isError: true
|
|
4254
|
+
};
|
|
4255
|
+
}
|
|
4256
|
+
logPlanEvent(doc, "session_token_regenerated", currentUser);
|
|
4257
|
+
logger.info({ planId, ownerId: metadata.ownerId }, "Session token regenerated successfully");
|
|
4258
|
+
return {
|
|
4259
|
+
content: [
|
|
4260
|
+
{
|
|
4261
|
+
type: "text",
|
|
4262
|
+
text: `Session token regenerated successfully!
|
|
4263
|
+
|
|
4264
|
+
Plan: ${metadata.title}
|
|
4265
|
+
Plan ID: ${planId}
|
|
4266
|
+
|
|
4267
|
+
New Session Token: ${newToken}
|
|
4268
|
+
|
|
4269
|
+
IMPORTANT: Store this token securely. The old token has been invalidated.
|
|
4270
|
+
Use this token for add_artifact, read_plan, link_pr, and other plan operations.`
|
|
4271
|
+
}
|
|
4272
|
+
]
|
|
4273
|
+
};
|
|
4274
|
+
}
|
|
4275
|
+
};
|
|
4276
|
+
|
|
4277
|
+
// src/tools/setup-review-notification.ts
|
|
4278
|
+
import { z as z10 } from "zod";
|
|
4279
|
+
var SetupReviewNotificationInput = z10.object({
|
|
4280
|
+
planId: z10.string().describe("Plan ID to monitor"),
|
|
4281
|
+
pollIntervalSeconds: z10.number().optional().default(30).describe("Polling interval in seconds (default: 30)")
|
|
4144
4282
|
});
|
|
4145
4283
|
var setupReviewNotificationTool = {
|
|
4146
4284
|
definition: {
|
|
@@ -4258,31 +4396,31 @@ The script:
|
|
|
4258
4396
|
|
|
4259
4397
|
// src/tools/update-block-content.ts
|
|
4260
4398
|
import { ServerBlockNoteEditor as ServerBlockNoteEditor6 } from "@blocknote/server-util";
|
|
4261
|
-
import { z as
|
|
4262
|
-
var BlockOperationSchema =
|
|
4263
|
-
|
|
4264
|
-
type:
|
|
4265
|
-
blockId:
|
|
4266
|
-
content:
|
|
4399
|
+
import { z as z11 } from "zod";
|
|
4400
|
+
var BlockOperationSchema = z11.discriminatedUnion("type", [
|
|
4401
|
+
z11.object({
|
|
4402
|
+
type: z11.literal("update"),
|
|
4403
|
+
blockId: z11.string().describe("The block ID to update (from read_plan output)"),
|
|
4404
|
+
content: z11.string().describe("New markdown content for this block")
|
|
4267
4405
|
}),
|
|
4268
|
-
|
|
4269
|
-
type:
|
|
4270
|
-
afterBlockId:
|
|
4271
|
-
content:
|
|
4406
|
+
z11.object({
|
|
4407
|
+
type: z11.literal("insert"),
|
|
4408
|
+
afterBlockId: z11.string().nullable().describe("Insert after this block ID (null = insert at beginning)"),
|
|
4409
|
+
content: z11.string().describe("Markdown content to insert as new block(s)")
|
|
4272
4410
|
}),
|
|
4273
|
-
|
|
4274
|
-
type:
|
|
4275
|
-
blockId:
|
|
4411
|
+
z11.object({
|
|
4412
|
+
type: z11.literal("delete"),
|
|
4413
|
+
blockId: z11.string().describe("The block ID to delete")
|
|
4276
4414
|
}),
|
|
4277
|
-
|
|
4278
|
-
type:
|
|
4279
|
-
content:
|
|
4415
|
+
z11.object({
|
|
4416
|
+
type: z11.literal("replace_all"),
|
|
4417
|
+
content: z11.string().describe("Complete markdown content to replace the entire plan")
|
|
4280
4418
|
})
|
|
4281
4419
|
]);
|
|
4282
|
-
var UpdateBlockContentInput =
|
|
4283
|
-
planId:
|
|
4284
|
-
sessionToken:
|
|
4285
|
-
operations:
|
|
4420
|
+
var UpdateBlockContentInput = z11.object({
|
|
4421
|
+
planId: z11.string().describe("The plan ID to modify"),
|
|
4422
|
+
sessionToken: z11.string().describe("Session token from create_plan"),
|
|
4423
|
+
operations: z11.array(BlockOperationSchema).min(1).describe("Array of operations to perform atomically")
|
|
4286
4424
|
});
|
|
4287
4425
|
var updateBlockContentTool = {
|
|
4288
4426
|
definition: {
|
|
@@ -4544,7 +4682,7 @@ async function applyOperation(blocks, operation, editor) {
|
|
|
4544
4682
|
// src/tools/update-plan.ts
|
|
4545
4683
|
import { ServerBlockNoteEditor as ServerBlockNoteEditor7 } from "@blocknote/server-util";
|
|
4546
4684
|
import { nanoid as nanoid7 } from "nanoid";
|
|
4547
|
-
import { z as
|
|
4685
|
+
import { z as z12 } from "zod";
|
|
4548
4686
|
function buildStatusTransition(targetStatus, actorName) {
|
|
4549
4687
|
const now = Date.now();
|
|
4550
4688
|
switch (targetStatus) {
|
|
@@ -4577,12 +4715,12 @@ function buildStatusTransition(targetStatus, actorName) {
|
|
|
4577
4715
|
return null;
|
|
4578
4716
|
}
|
|
4579
4717
|
}
|
|
4580
|
-
var UpdatePlanInput =
|
|
4581
|
-
planId:
|
|
4582
|
-
sessionToken:
|
|
4583
|
-
title:
|
|
4584
|
-
status:
|
|
4585
|
-
tags:
|
|
4718
|
+
var UpdatePlanInput = z12.object({
|
|
4719
|
+
planId: z12.string().describe("The plan ID to update"),
|
|
4720
|
+
sessionToken: z12.string().describe("Session token from create_plan"),
|
|
4721
|
+
title: z12.string().optional().describe("New title"),
|
|
4722
|
+
status: z12.enum(["draft", "pending_review", "changes_requested", "in_progress", "completed"]).optional().describe("New status"),
|
|
4723
|
+
tags: z12.array(z12.string()).optional().describe("Updated tags (replaces existing tags)")
|
|
4586
4724
|
});
|
|
4587
4725
|
var updatePlanTool = {
|
|
4588
4726
|
definition: {
|
|
@@ -5035,6 +5173,46 @@ await resolveActivityRequest({
|
|
|
5035
5173
|
|
|
5036
5174
|
---
|
|
5037
5175
|
|
|
5176
|
+
### regenerateSessionToken(planId): Promise<{ sessionToken, planId }>
|
|
5177
|
+
Regenerate the session token for a plan you own.
|
|
5178
|
+
|
|
5179
|
+
USE WHEN:
|
|
5180
|
+
- Your Claude Code session ended and you lost the original token
|
|
5181
|
+
- You need to resume work on a plan from a previous session
|
|
5182
|
+
- The old token may have been compromised
|
|
5183
|
+
|
|
5184
|
+
REQUIREMENTS:
|
|
5185
|
+
- You must be the plan owner (verified via GitHub identity)
|
|
5186
|
+
- The plan must exist and have an ownerId set
|
|
5187
|
+
|
|
5188
|
+
Returns:
|
|
5189
|
+
- sessionToken: New token for API calls
|
|
5190
|
+
- planId: The plan ID
|
|
5191
|
+
|
|
5192
|
+
SECURITY:
|
|
5193
|
+
- Only the plan owner can regenerate tokens
|
|
5194
|
+
- Old token is immediately invalidated
|
|
5195
|
+
- GitHub identity verification happens on MCP server (via gh auth login)
|
|
5196
|
+
|
|
5197
|
+
Example:
|
|
5198
|
+
\`\`\`typescript
|
|
5199
|
+
// Lost your session token? Regenerate it:
|
|
5200
|
+
const { sessionToken, planId } = await regenerateSessionToken("abc123");
|
|
5201
|
+
|
|
5202
|
+
// Now use the new token for operations
|
|
5203
|
+
await addArtifact({
|
|
5204
|
+
planId,
|
|
5205
|
+
sessionToken,
|
|
5206
|
+
type: 'screenshot',
|
|
5207
|
+
filename: 'screenshot.png',
|
|
5208
|
+
source: 'file',
|
|
5209
|
+
filePath: '/tmp/screenshot.png',
|
|
5210
|
+
deliverableId: 'del_xxx'
|
|
5211
|
+
});
|
|
5212
|
+
\`\`\`
|
|
5213
|
+
|
|
5214
|
+
---
|
|
5215
|
+
|
|
5038
5216
|
## Common Pattern
|
|
5039
5217
|
|
|
5040
5218
|
\`\`\`typescript
|
|
@@ -5072,9 +5250,10 @@ const result = await addArtifact({
|
|
|
5072
5250
|
return { planId: plan.planId, snapshotUrl: result.snapshotUrl };
|
|
5073
5251
|
\`\`\`
|
|
5074
5252
|
`;
|
|
5075
|
-
var ExecuteCodeInput =
|
|
5076
|
-
code:
|
|
5253
|
+
var ExecuteCodeInput = z13.object({
|
|
5254
|
+
code: z13.string().describe("TypeScript code to execute")
|
|
5077
5255
|
});
|
|
5256
|
+
var scriptTracker = [];
|
|
5078
5257
|
async function createPlan(opts) {
|
|
5079
5258
|
const result = await createPlanTool.handler(opts);
|
|
5080
5259
|
const text = result.content[0]?.text || "";
|
|
@@ -5086,6 +5265,9 @@ async function createPlan(opts) {
|
|
|
5086
5265
|
deliverables = allDeliverables.map((d) => ({ id: d.id, text: d.text }));
|
|
5087
5266
|
}
|
|
5088
5267
|
const { script: monitoringScript } = await setupReviewNotification(planId, 30);
|
|
5268
|
+
scriptTracker.push(`Plan "${planId}" created.
|
|
5269
|
+
|
|
5270
|
+
${monitoringScript}`);
|
|
5089
5271
|
return {
|
|
5090
5272
|
planId,
|
|
5091
5273
|
sessionToken: text.match(/Session Token: (\S+)/)?.[1] || "",
|
|
@@ -5122,6 +5304,9 @@ async function readPlan(planId, sessionToken, opts) {
|
|
|
5122
5304
|
async function updatePlan(planId, sessionToken, updates) {
|
|
5123
5305
|
await updatePlanTool.handler({ planId, sessionToken, ...updates });
|
|
5124
5306
|
const { script: monitoringScript } = await setupReviewNotification(planId, 30);
|
|
5307
|
+
scriptTracker.push(`Plan "${planId}" updated.
|
|
5308
|
+
|
|
5309
|
+
${monitoringScript}`);
|
|
5125
5310
|
return {
|
|
5126
5311
|
success: true,
|
|
5127
5312
|
monitoringScript
|
|
@@ -5201,7 +5386,7 @@ async function setupReviewNotification(planId, pollIntervalSeconds) {
|
|
|
5201
5386
|
return { script, fullResponse: text };
|
|
5202
5387
|
}
|
|
5203
5388
|
async function requestUserInput(opts) {
|
|
5204
|
-
const { InputRequestManager: InputRequestManager2 } = await import("./input-request-manager-
|
|
5389
|
+
const { InputRequestManager: InputRequestManager2 } = await import("./input-request-manager-3STPPPYU.js");
|
|
5205
5390
|
const ydoc = await getOrCreateDoc3(PLAN_INDEX_DOC_NAME);
|
|
5206
5391
|
const manager = new InputRequestManager2();
|
|
5207
5392
|
const params = opts.type === "choice" ? {
|
|
@@ -5245,8 +5430,8 @@ async function requestUserInput(opts) {
|
|
|
5245
5430
|
};
|
|
5246
5431
|
}
|
|
5247
5432
|
async function postActivityUpdate(opts) {
|
|
5248
|
-
const { logPlanEvent: logPlanEvent2 } = await import("./dist-
|
|
5249
|
-
const { getGitHubUsername: getGitHubUsername2 } = await import("./server-identity-
|
|
5433
|
+
const { logPlanEvent: logPlanEvent2 } = await import("./dist-D4DG2R4R.js");
|
|
5434
|
+
const { getGitHubUsername: getGitHubUsername2 } = await import("./server-identity-LSZ4CZRK.js");
|
|
5250
5435
|
const { nanoid: nanoid8 } = await import("nanoid");
|
|
5251
5436
|
const doc = await getOrCreateDoc3(opts.planId);
|
|
5252
5437
|
const actorName = await getGitHubUsername2();
|
|
@@ -5268,8 +5453,8 @@ async function postActivityUpdate(opts) {
|
|
|
5268
5453
|
return { success: true, eventId, requestId };
|
|
5269
5454
|
}
|
|
5270
5455
|
async function resolveActivityRequest(opts) {
|
|
5271
|
-
const { logPlanEvent: logPlanEvent2, getPlanEvents } = await import("./dist-
|
|
5272
|
-
const { getGitHubUsername: getGitHubUsername2 } = await import("./server-identity-
|
|
5456
|
+
const { logPlanEvent: logPlanEvent2, getPlanEvents } = await import("./dist-D4DG2R4R.js");
|
|
5457
|
+
const { getGitHubUsername: getGitHubUsername2 } = await import("./server-identity-LSZ4CZRK.js");
|
|
5273
5458
|
const doc = await getOrCreateDoc3(opts.planId);
|
|
5274
5459
|
const actorName = await getGitHubUsername2();
|
|
5275
5460
|
const events = getPlanEvents(doc);
|
|
@@ -5294,6 +5479,18 @@ async function resolveActivityRequest(opts) {
|
|
|
5294
5479
|
});
|
|
5295
5480
|
return { success: true };
|
|
5296
5481
|
}
|
|
5482
|
+
async function regenerateSessionToken(planId) {
|
|
5483
|
+
const result = await regenerateSessionTokenTool.handler({ planId });
|
|
5484
|
+
const text = result.content[0]?.text || "";
|
|
5485
|
+
if (result.isError) {
|
|
5486
|
+
throw new Error(text);
|
|
5487
|
+
}
|
|
5488
|
+
const tokenMatch = text.match(/New Session Token: (\S+)/);
|
|
5489
|
+
return {
|
|
5490
|
+
sessionToken: tokenMatch?.[1] || "",
|
|
5491
|
+
planId
|
|
5492
|
+
};
|
|
5493
|
+
}
|
|
5297
5494
|
var executeCodeTool = {
|
|
5298
5495
|
definition: {
|
|
5299
5496
|
name: TOOL_NAMES.EXECUTE_CODE,
|
|
@@ -5312,6 +5509,7 @@ var executeCodeTool = {
|
|
|
5312
5509
|
handler: async (args) => {
|
|
5313
5510
|
const { code } = ExecuteCodeInput.parse(args);
|
|
5314
5511
|
logger.info({ codeLength: code.length }, "Executing code");
|
|
5512
|
+
scriptTracker.length = 0;
|
|
5315
5513
|
try {
|
|
5316
5514
|
async function encodeVideo(opts) {
|
|
5317
5515
|
const fps = opts.fps || 6;
|
|
@@ -5357,6 +5555,7 @@ var executeCodeTool = {
|
|
|
5357
5555
|
requestUserInput,
|
|
5358
5556
|
postActivityUpdate,
|
|
5359
5557
|
resolveActivityRequest,
|
|
5558
|
+
regenerateSessionToken,
|
|
5360
5559
|
// Video encoding helper (uses bundled FFmpeg)
|
|
5361
5560
|
encodeVideo,
|
|
5362
5561
|
// Node.js modules for advanced workflows (file ops, process spawning)
|
|
@@ -5376,14 +5575,33 @@ var executeCodeTool = {
|
|
|
5376
5575
|
const script = new vm.Script(wrappedCode);
|
|
5377
5576
|
const result = await script.runInContext(context, { timeout: 12e4 });
|
|
5378
5577
|
logger.info({ result }, "Code execution complete");
|
|
5379
|
-
|
|
5380
|
-
|
|
5381
|
-
|
|
5382
|
-
|
|
5383
|
-
|
|
5384
|
-
|
|
5385
|
-
|
|
5386
|
-
|
|
5578
|
+
const content = [
|
|
5579
|
+
{
|
|
5580
|
+
type: "text",
|
|
5581
|
+
text: typeof result === "object" ? JSON.stringify(result, null, 2) : String(result ?? "Done")
|
|
5582
|
+
}
|
|
5583
|
+
];
|
|
5584
|
+
const latestScript = scriptTracker[scriptTracker.length - 1];
|
|
5585
|
+
if (latestScript) {
|
|
5586
|
+
const [planAction, ...scriptParts] = latestScript.split("\n\n");
|
|
5587
|
+
content.push({
|
|
5588
|
+
type: "text",
|
|
5589
|
+
text: `
|
|
5590
|
+
|
|
5591
|
+
---
|
|
5592
|
+
**\u26A0\uFE0F IMPORTANT FOR NON-HOOK AGENTS (Cursor, Devin, Windsurf, etc.):**
|
|
5593
|
+
|
|
5594
|
+
${planAction} To wait for human approval before proceeding, run this monitoring script in background:
|
|
5595
|
+
|
|
5596
|
+
\`\`\`bash
|
|
5597
|
+
${scriptParts.join("\n\n")}
|
|
5598
|
+
\`\`\`
|
|
5599
|
+
|
|
5600
|
+
Save the script to a file and run: \`bash script.sh &\`
|
|
5601
|
+
The script will exit when the human approves or requests changes.`
|
|
5602
|
+
});
|
|
5603
|
+
}
|
|
5604
|
+
return { content };
|
|
5387
5605
|
} catch (error) {
|
|
5388
5606
|
logger.error({ error, code }, "Code execution failed");
|
|
5389
5607
|
const message = error instanceof Error ? error.message : "Unknown error";
|
|
@@ -5396,15 +5614,15 @@ var executeCodeTool = {
|
|
|
5396
5614
|
};
|
|
5397
5615
|
|
|
5398
5616
|
// src/tools/request-user-input.ts
|
|
5399
|
-
import { z as
|
|
5400
|
-
var RequestUserInputInput =
|
|
5401
|
-
message:
|
|
5402
|
-
type:
|
|
5403
|
-
options:
|
|
5404
|
-
multiSelect:
|
|
5405
|
-
defaultValue:
|
|
5406
|
-
timeout:
|
|
5407
|
-
planId:
|
|
5617
|
+
import { z as z14 } from "zod";
|
|
5618
|
+
var RequestUserInputInput = z14.object({
|
|
5619
|
+
message: z14.string().describe("The question to ask the user"),
|
|
5620
|
+
type: z14.enum(["text", "choice", "confirm", "multiline"]).describe("Type of input to request"),
|
|
5621
|
+
options: z14.array(z14.string()).optional().describe("For 'choice' type - available options (required for choice)"),
|
|
5622
|
+
multiSelect: z14.boolean().optional().describe("For 'choice' type - allow selecting multiple options"),
|
|
5623
|
+
defaultValue: z14.string().optional().describe("Pre-filled value for text/multiline inputs"),
|
|
5624
|
+
timeout: z14.number().optional().describe("Timeout in seconds (default: 1800, min: 10, max: 14400)"),
|
|
5625
|
+
planId: z14.string().optional().describe("Optional metadata to link request to plan (for activity log filtering)")
|
|
5408
5626
|
});
|
|
5409
5627
|
var requestUserInputTool = {
|
|
5410
5628
|
definition: {
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getEnvironmentContext,
|
|
3
3
|
getGitHubUsername,
|
|
4
|
-
getRepositoryFullName
|
|
5
|
-
|
|
4
|
+
getRepositoryFullName,
|
|
5
|
+
getVerifiedGitHubUsername
|
|
6
|
+
} from "./chunk-OLFHVNPI.js";
|
|
6
7
|
import "./chunk-GSGLHRWX.js";
|
|
7
8
|
import "./chunk-JSBRDJBE.js";
|
|
8
9
|
export {
|
|
9
10
|
getEnvironmentContext,
|
|
10
11
|
getGitHubUsername,
|
|
11
|
-
getRepositoryFullName
|
|
12
|
+
getRepositoryFullName,
|
|
13
|
+
getVerifiedGitHubUsername
|
|
12
14
|
};
|