@ycodium-ai/plugin-team 0.2.3252 → 0.2.3254
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/dist/index.js +201 -39
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -7211,6 +7211,7 @@ function leadBrief(goal, roster) {
|
|
|
7211
7211
|
"A comment that mentions a remote member, or replies to one of their comments, wakes them on their machine, so you can ask or answer them in work item comments. Once they mark an item done they stop working on it, so to send work back to a remote member you still reopen the item as described above."
|
|
7212
7212
|
],
|
|
7213
7213
|
"Use work_list_items to check progress. When all work is complete, summarize the results here in one or two sentences.",
|
|
7214
|
+
"Members' worktrees and branches remain after the goal ends. After their work is merged into the main line, they can be deleted from the source control panel.",
|
|
7214
7215
|
PERSON_MESSAGE_RULE,
|
|
7215
7216
|
"If the work item tools are unavailable, tell the user directly that this project needs the board and project memory switches turned on first."
|
|
7216
7217
|
].join("\n\n");
|
|
@@ -8190,9 +8191,74 @@ function createRosterService(ctx, options = {}) {
|
|
|
8190
8191
|
};
|
|
8191
8192
|
}
|
|
8192
8193
|
|
|
8194
|
+
// src/runtime/wakeQueries.ts
|
|
8195
|
+
function memberWorktreeFor(goals, project2, projectId, recipient) {
|
|
8196
|
+
if (!("threadId" in recipient) || project2 === void 0 || !project2.threads.includes(recipient.threadId) || project2.leadThreads?.includes(recipient.threadId))
|
|
8197
|
+
return;
|
|
8198
|
+
const { threadId } = recipient;
|
|
8199
|
+
const leadThreadId = project2.leadThreads?.[0];
|
|
8200
|
+
if (leadThreadId === void 0) return;
|
|
8201
|
+
return {
|
|
8202
|
+
leadThreadId,
|
|
8203
|
+
failure: project2.worktreeFailures?.[threadId],
|
|
8204
|
+
// 只在要建树或报失败时读目标取名字,叫醒的热路径不多读。
|
|
8205
|
+
name: async () => (await goals.read(projectId))?.members.find((member) => member.threadId === threadId)?.name ?? project2.memberIds?.[threadId] ?? threadId
|
|
8206
|
+
};
|
|
8207
|
+
}
|
|
8208
|
+
var compare = (a, b) => a < b ? -1 : a > b ? 1 : 0;
|
|
8209
|
+
var compareWakeItems = (a, b) => a.sequenceId - b.sequenceId || compare(a.workItemId, b.workItemId);
|
|
8210
|
+
var isClosed = (item) => item?.stateGroup === "completed" || item?.stateGroup === "cancelled";
|
|
8211
|
+
var hasOpenBlocker = (project2, workItemId) => (readFact(project2.blockers, workItemId) ?? []).some(
|
|
8212
|
+
(blocker) => !isClosed(readFact(project2.items, blocker))
|
|
8213
|
+
);
|
|
8214
|
+
var isAssignedOpen = (project2, workItemId, threadId) => {
|
|
8215
|
+
const item = readFact(project2.items, workItemId);
|
|
8216
|
+
return item !== null && item !== void 0 && !isClosed(item) && item.assigneeThreads.includes(threadId);
|
|
8217
|
+
};
|
|
8218
|
+
var isWorkable = (project2, workItemId) => !isClosed(readFact(project2.items, workItemId)) && !hasOpenBlocker(project2, workItemId);
|
|
8219
|
+
var isOpenWorkFor = (project2, workItemId, threadId) => isAssignedOpen(project2, workItemId, threadId) && !hasOpenBlocker(project2, workItemId);
|
|
8220
|
+
var isMember = (project2, recipient) => "threadId" in recipient ? project2.threads.includes(recipient.threadId) : project2.remoteMembers.includes(recipient.principalId);
|
|
8221
|
+
var isQueuedUnclaimed = (item, threadId) => item.wakeStatus?.[threadId] === "pending" && !item.claimedBy.includes(threadId);
|
|
8222
|
+
var isDeferredWake = (project2, item, threadId) => project2.threads.includes(threadId) && !project2.leadThreads?.includes(threadId) && item.assigneeThreads.includes(threadId) && isQueuedUnclaimed(item, threadId) && !isClosed(item);
|
|
8223
|
+
function countDeferredWakes(project2, threadId) {
|
|
8224
|
+
let count = 0;
|
|
8225
|
+
for (const workItemId in project2.items) {
|
|
8226
|
+
const item = readFact(project2.items, workItemId);
|
|
8227
|
+
if (item !== null && isDeferredWake(project2, item, threadId)) count++;
|
|
8228
|
+
}
|
|
8229
|
+
return count;
|
|
8230
|
+
}
|
|
8231
|
+
|
|
8193
8232
|
// src/runtime/deliver.ts
|
|
8194
8233
|
import * as NodeCrypto from "node:crypto";
|
|
8195
8234
|
var stableHash = (key) => NodeCrypto.createHash("sha256").update(key).digest("hex").slice(0, 32);
|
|
8235
|
+
var memberWorktreeBranch = (name, threadId) => {
|
|
8236
|
+
const slug = Array.from(
|
|
8237
|
+
name.normalize("NFKC").toLowerCase().replace(/[^\p{L}\p{N}]+/gu, "-")
|
|
8238
|
+
).slice(0, 32).join("").replace(/^-+|-+$/g, "") || "member";
|
|
8239
|
+
return `team/${slug}-${stableHash(threadId).slice(0, 16)}`;
|
|
8240
|
+
};
|
|
8241
|
+
var createMemberWorktreeLane = (state, events) => {
|
|
8242
|
+
const tails = /* @__PURE__ */ new Map();
|
|
8243
|
+
return {
|
|
8244
|
+
state,
|
|
8245
|
+
events,
|
|
8246
|
+
serialize: (threadId, run3) => {
|
|
8247
|
+
const next = (tails.get(threadId) ?? Promise.resolve()).then(run3);
|
|
8248
|
+
const tail = next.then(
|
|
8249
|
+
() => void 0,
|
|
8250
|
+
() => void 0
|
|
8251
|
+
);
|
|
8252
|
+
tails.set(threadId, tail);
|
|
8253
|
+
void tail.then(() => {
|
|
8254
|
+
if (tails.get(threadId) === tail) tails.delete(threadId);
|
|
8255
|
+
});
|
|
8256
|
+
return next;
|
|
8257
|
+
}
|
|
8258
|
+
};
|
|
8259
|
+
};
|
|
8260
|
+
var shortReason = (error) => (error instanceof Error ? error.message : String(error)).replace(/\s+/g, " ").trim().slice(0, 240) || "Worktree preparation failed";
|
|
8261
|
+
var FALLBACK_SUFFIX = ":worktree-fallback";
|
|
8196
8262
|
async function deliverWake(ctx, input) {
|
|
8197
8263
|
const { recipient } = input;
|
|
8198
8264
|
if ("principalId" in recipient) {
|
|
@@ -8206,46 +8272,93 @@ async function deliverWake(ctx, input) {
|
|
|
8206
8272
|
} else {
|
|
8207
8273
|
const execution = await ctx.projections.getThreadExecution(recipient.threadId);
|
|
8208
8274
|
if (execution === null || execution.archivedAt !== null) return false;
|
|
8209
|
-
|
|
8210
|
-
|
|
8211
|
-
|
|
8275
|
+
const { threadId } = recipient;
|
|
8276
|
+
const text = typeof input.text === "string" ? input.text : await input.text();
|
|
8277
|
+
const worktree = input.memberWorktree;
|
|
8278
|
+
const turn = {
|
|
8279
|
+
threadId,
|
|
8212
8280
|
message: {
|
|
8213
8281
|
messageId: input.messageId,
|
|
8214
8282
|
role: "user",
|
|
8215
|
-
text
|
|
8283
|
+
text,
|
|
8216
8284
|
attachments: []
|
|
8217
8285
|
},
|
|
8218
8286
|
modelSelection: execution.modelSelection,
|
|
8219
8287
|
runtimeMode: execution.runtimeMode,
|
|
8220
8288
|
interactionMode: execution.interactionMode
|
|
8289
|
+
};
|
|
8290
|
+
const startTurn = (suffix) => ctx.threads.turns.start({
|
|
8291
|
+
...turn,
|
|
8292
|
+
requestId: `${input.requestId}${suffix}`,
|
|
8293
|
+
message: { ...turn.message, messageId: `${input.messageId}${suffix}` }
|
|
8221
8294
|
});
|
|
8222
|
-
|
|
8223
|
-
|
|
8224
|
-
|
|
8295
|
+
let failure = worktree?.failure;
|
|
8296
|
+
let delivered = false;
|
|
8297
|
+
if (worktree !== void 0 && failure === void 0 && !execution.worktreePath) {
|
|
8298
|
+
const { lane } = worktree;
|
|
8299
|
+
const first = await lane.serialize(threadId, async () => {
|
|
8300
|
+
const current = await ctx.projections.getThreadExecution(threadId);
|
|
8301
|
+
if (current?.worktreePath) return { kind: "registered" };
|
|
8302
|
+
const recorded = (await lane.state.get())[input.projectId]?.worktreeFailures?.[threadId];
|
|
8303
|
+
if (recorded !== void 0) return { kind: "failed", failure: recorded };
|
|
8304
|
+
const branch = memberWorktreeBranch(await worktree.name(), threadId);
|
|
8305
|
+
try {
|
|
8306
|
+
await ctx.threads.turns.start({
|
|
8307
|
+
...turn,
|
|
8308
|
+
requestId: input.requestId,
|
|
8309
|
+
message: {
|
|
8310
|
+
...turn.message,
|
|
8311
|
+
text: `${text}
|
|
8225
8312
|
|
|
8226
|
-
|
|
8227
|
-
|
|
8228
|
-
|
|
8229
|
-
|
|
8230
|
-
|
|
8231
|
-
|
|
8232
|
-
|
|
8233
|
-
|
|
8234
|
-
|
|
8235
|
-
|
|
8236
|
-
};
|
|
8237
|
-
|
|
8238
|
-
|
|
8239
|
-
|
|
8240
|
-
|
|
8241
|
-
|
|
8242
|
-
|
|
8243
|
-
|
|
8244
|
-
|
|
8245
|
-
|
|
8246
|
-
|
|
8313
|
+
You are in your own newly created worktree on branch ${branch}. Install dependencies according to the project's instructions before starting work.`
|
|
8314
|
+
},
|
|
8315
|
+
bootstrap: {
|
|
8316
|
+
prepareWorktree: {
|
|
8317
|
+
// bootstrapTurnStart 将它传作 refName;gitDriver/worktrees 用 cwd 下的 HEAD 执行 git worktree add -b。
|
|
8318
|
+
baseBranch: "HEAD",
|
|
8319
|
+
branch,
|
|
8320
|
+
startFromOrigin: false
|
|
8321
|
+
}
|
|
8322
|
+
}
|
|
8323
|
+
});
|
|
8324
|
+
} catch (error) {
|
|
8325
|
+
await startTurn(FALLBACK_SUFFIX);
|
|
8326
|
+
const reason = shortReason(error);
|
|
8327
|
+
const receipt = await lane.events.append({
|
|
8328
|
+
commandId: `team-worktree-failed:${threadId}`,
|
|
8329
|
+
name: "member-worktree-failed",
|
|
8330
|
+
aggregate: { kind: "project", id: input.projectId },
|
|
8331
|
+
data: { version: 1, projectId: input.projectId, threadId, reason }
|
|
8332
|
+
});
|
|
8333
|
+
const persisted = (await lane.state.get({ throughSequence: receipt.sequence }))[input.projectId]?.worktreeFailures?.[threadId];
|
|
8334
|
+
return { kind: "fallback", failure: persisted ?? { reason } };
|
|
8335
|
+
}
|
|
8336
|
+
return { kind: "worktree" };
|
|
8337
|
+
});
|
|
8338
|
+
if (first.kind === "worktree") return true;
|
|
8339
|
+
if (first.kind !== "registered") failure = first.failure;
|
|
8340
|
+
delivered = first.kind === "fallback";
|
|
8341
|
+
}
|
|
8342
|
+
if (!delivered) await startTurn(failure === void 0 ? "" : FALLBACK_SUFFIX);
|
|
8343
|
+
if (worktree !== void 0 && failure !== void 0 && failure.reported !== true) {
|
|
8344
|
+
const reported = await deliverWake(ctx, {
|
|
8345
|
+
projectId: input.projectId,
|
|
8346
|
+
recipient: { threadId: worktree.leadThreadId },
|
|
8347
|
+
requestId: `team-worktree-report:${threadId}`,
|
|
8348
|
+
messageId: `team-worktree-report-msg:${threadId}`,
|
|
8349
|
+
text: `Could not create a worktree for member ${await worktree.name()} (threadId ${threadId}): ${failure.reason}. They will work in the project folder for now.`
|
|
8350
|
+
});
|
|
8351
|
+
if (!reported) throw new Error("Member worktree failure could not be reported to the lead");
|
|
8352
|
+
const receipt = await worktree.lane.events.append({
|
|
8353
|
+
commandId: `team-worktree-reported:${threadId}`,
|
|
8354
|
+
name: "member-worktree-reported",
|
|
8355
|
+
aggregate: { kind: "project", id: input.projectId },
|
|
8356
|
+
data: { version: 1, projectId: input.projectId, threadId }
|
|
8357
|
+
});
|
|
8358
|
+
await worktree.lane.state.get({ throughSequence: receipt.sequence });
|
|
8359
|
+
}
|
|
8247
8360
|
}
|
|
8248
|
-
return
|
|
8361
|
+
return true;
|
|
8249
8362
|
}
|
|
8250
8363
|
|
|
8251
8364
|
// src/runtime/recoveryState.ts
|
|
@@ -8576,6 +8689,12 @@ var MemberWokenFact = Struct({
|
|
|
8576
8689
|
threadId: optionalKey2(String4),
|
|
8577
8690
|
principalId: optionalKey2(String4)
|
|
8578
8691
|
});
|
|
8692
|
+
var MemberWorktreeFailedFact = Struct({
|
|
8693
|
+
version: Literal2(1),
|
|
8694
|
+
projectId: String4,
|
|
8695
|
+
threadId: String4,
|
|
8696
|
+
reason: String4
|
|
8697
|
+
});
|
|
8579
8698
|
var emptyProject = () => ({
|
|
8580
8699
|
threads: [],
|
|
8581
8700
|
leadThreads: [],
|
|
@@ -8607,6 +8726,20 @@ var decodeEnvelope2 = decodeUnknownOption2(
|
|
|
8607
8726
|
pluginId: Literal2("team"),
|
|
8608
8727
|
name: Literal2("team/member-woken"),
|
|
8609
8728
|
data: MemberWokenFact
|
|
8729
|
+
}),
|
|
8730
|
+
Struct({
|
|
8731
|
+
pluginId: Literal2("team"),
|
|
8732
|
+
name: Literal2("team/member-worktree-failed"),
|
|
8733
|
+
data: MemberWorktreeFailedFact
|
|
8734
|
+
}),
|
|
8735
|
+
Struct({
|
|
8736
|
+
pluginId: Literal2("team"),
|
|
8737
|
+
name: Literal2("team/member-worktree-reported"),
|
|
8738
|
+
data: Struct({
|
|
8739
|
+
version: Literal2(1),
|
|
8740
|
+
projectId: String4,
|
|
8741
|
+
threadId: String4
|
|
8742
|
+
})
|
|
8610
8743
|
})
|
|
8611
8744
|
])
|
|
8612
8745
|
);
|
|
@@ -8727,6 +8860,20 @@ function foldWorkWakes(state, event) {
|
|
|
8727
8860
|
}
|
|
8728
8861
|
};
|
|
8729
8862
|
}
|
|
8863
|
+
if (fact.name === "team/member-worktree-failed" || fact.name === "team/member-worktree-reported") {
|
|
8864
|
+
const { projectId: projectId3, threadId } = fact.data;
|
|
8865
|
+
const project4 = readFact(state, projectId3) ?? emptyProject();
|
|
8866
|
+
const previous = project4.worktreeFailures?.[threadId];
|
|
8867
|
+
const failure = fact.name === "team/member-worktree-failed" ? previous ?? { reason: fact.data.reason } : previous === void 0 ? void 0 : { ...previous, reported: true };
|
|
8868
|
+
if (failure === void 0 || failure === previous) return state;
|
|
8869
|
+
return {
|
|
8870
|
+
...state,
|
|
8871
|
+
[projectId3]: {
|
|
8872
|
+
...project4,
|
|
8873
|
+
worktreeFailures: { ...project4.worktreeFailures, [threadId]: failure }
|
|
8874
|
+
}
|
|
8875
|
+
};
|
|
8876
|
+
}
|
|
8730
8877
|
const { projectId: projectId2, key } = fact.data;
|
|
8731
8878
|
const project3 = readFact(state, projectId2) ?? emptyProject();
|
|
8732
8879
|
if (project3.pendingComments.some((comment) => comment.key === key)) {
|
|
@@ -9009,7 +9156,7 @@ var leadItemText = (workItemId, sequenceId, title) => `You have ${titled(workIte
|
|
|
9009
9156
|
var leadUnblockedText = (workItemId, sequenceId, title) => `Everything blocking ${titled(workItemId, sequenceId, title)} is done now. Read those items with work_read_items and check the results. ${LEAD_SEND_BACK_RULE} When all of them are acceptable, mark this item done with work_update_item. ${LEAD_NO_MEMBER_TASKS}`;
|
|
9010
9157
|
var unblockedText = (workItemId, sequenceId, title) => `Everything blocking ${titled(workItemId, sequenceId, title)} is done now. Read those items with work_read_items, finish this one, and mark it done with work_update_item.`;
|
|
9011
9158
|
var commentText2 = (workItemId, sequenceId) => `There is a new comment for you on ${workLabel(workItemId, sequenceId)}. Read it with work_list_comments, passing workItemId: "${workItemId}", and reply there if needed.`;
|
|
9012
|
-
function startWakeRuntime(ctx, options = {}) {
|
|
9159
|
+
function startWakeRuntime(ctx, goals, options = {}) {
|
|
9013
9160
|
const wakes = ctx.derivedState({
|
|
9014
9161
|
key: WAKE_STATE_KEY,
|
|
9015
9162
|
version: WAKE_STATE_VERSION,
|
|
@@ -9017,6 +9164,7 @@ function startWakeRuntime(ctx, options = {}) {
|
|
|
9017
9164
|
init: () => ({}),
|
|
9018
9165
|
apply: foldWakes
|
|
9019
9166
|
});
|
|
9167
|
+
const worktrees = createMemberWorktreeLane(wakes, ctx.events);
|
|
9020
9168
|
const hash2 = options.hash ?? stableHash;
|
|
9021
9169
|
let pending = Promise.resolve();
|
|
9022
9170
|
const readItem = async (projectId, workItemId) => {
|
|
@@ -9029,11 +9177,13 @@ function startWakeRuntime(ctx, options = {}) {
|
|
|
9029
9177
|
if (!isWakeDue(state, wake)) continue;
|
|
9030
9178
|
try {
|
|
9031
9179
|
const id = hash2(wake.key);
|
|
9180
|
+
const worktree = memberWorktreeFor(goals, state[wake.projectId], wake.projectId, wake);
|
|
9032
9181
|
const delivered = await deliverWake(ctx, {
|
|
9033
9182
|
projectId: wake.projectId,
|
|
9034
9183
|
recipient: wake,
|
|
9035
9184
|
requestId: `team-wake:${id}`,
|
|
9036
9185
|
messageId: `team-wake-msg:${id}`,
|
|
9186
|
+
memberWorktree: worktree === void 0 ? void 0 : { ...worktree, lane: worktrees },
|
|
9037
9187
|
text: async () => {
|
|
9038
9188
|
if ("principalId" in wake || wake.kind === "comment")
|
|
9039
9189
|
return commentText2(wake.workItemId, wake.sequenceId);
|
|
@@ -9081,7 +9231,7 @@ function startWakeRuntime(ctx, options = {}) {
|
|
|
9081
9231
|
});
|
|
9082
9232
|
const ready = flush();
|
|
9083
9233
|
void ready.catch((error) => ctx.log?.warn("team wake catch-up failed", { error }));
|
|
9084
|
-
return { flush, ready, state: wakes };
|
|
9234
|
+
return { flush, ready, state: wakes, worktrees };
|
|
9085
9235
|
}
|
|
9086
9236
|
|
|
9087
9237
|
// src/runtime/recovery.ts
|
|
@@ -9104,7 +9254,7 @@ ${commentInstructions(recovery)}`;
|
|
|
9104
9254
|
var stallLeadText = (recovery, name) => `Member ${name} (threadId ${recovery.threadId}) ended this turn normally, but ${recovery.items.map(itemLabel).join(", ")} ${recovery.items.length === 1 ? "is" : "are"} still open. ${deferredText(recovery)}${recovery.alreadyRetried ? "They have already been reminded once to continue this work, with no progress since. " : ""}${recovery.items.filter((item) => item.waitingForReply).map(
|
|
9105
9255
|
(item) => `Their last action on ${itemLabel(item)} was their own comment (commentId ${item.lastCommentId}); reply to it or arrange another member to help. `
|
|
9106
9256
|
).join("")}${leadInstructions()}`;
|
|
9107
|
-
function startRecoveryRuntime(ctx, goals, state) {
|
|
9257
|
+
function startRecoveryRuntime(ctx, goals, state, worktrees) {
|
|
9108
9258
|
let pending = Promise.resolve();
|
|
9109
9259
|
let disposed = false;
|
|
9110
9260
|
const execute = async (scope2) => {
|
|
@@ -9222,12 +9372,16 @@ function startRecoveryRuntime(ctx, goals, state) {
|
|
|
9222
9372
|
await requestPlan(plan);
|
|
9223
9373
|
}
|
|
9224
9374
|
}
|
|
9375
|
+
const worktree = memberWorktreeFor(goals, current[recovery.projectId], recovery.projectId, {
|
|
9376
|
+
threadId: plan.recipientThreadId
|
|
9377
|
+
});
|
|
9225
9378
|
const delivered = await deliverWake(ctx, {
|
|
9226
9379
|
projectId: recovery.projectId,
|
|
9227
9380
|
recipient: { threadId: plan.recipientThreadId },
|
|
9228
9381
|
requestId: `team-recovery:${id}:${plan.action}`,
|
|
9229
9382
|
messageId: `team-recovery-msg:${id}:${plan.action}`,
|
|
9230
|
-
text: plan.text
|
|
9383
|
+
text: plan.text,
|
|
9384
|
+
memberWorktree: worktree === void 0 ? void 0 : { ...worktree, lane: worktrees }
|
|
9231
9385
|
});
|
|
9232
9386
|
if (!delivered) continue;
|
|
9233
9387
|
const receipt = await ctx.events.append({
|
|
@@ -9572,7 +9726,7 @@ var terminalFailure = (error) => {
|
|
|
9572
9726
|
if (!rejected && !invalid2) return null;
|
|
9573
9727
|
return error instanceof Error ? error.message : "detail" in error ? String(error.detail) : String(reason);
|
|
9574
9728
|
};
|
|
9575
|
-
function startHandbookRuntime(ctx) {
|
|
9729
|
+
function startHandbookRuntime(ctx, worktrees) {
|
|
9576
9730
|
const state = ctx.derivedState({
|
|
9577
9731
|
key: "handbook",
|
|
9578
9732
|
version: 5,
|
|
@@ -9651,16 +9805,24 @@ function startHandbookRuntime(ctx) {
|
|
|
9651
9805
|
};
|
|
9652
9806
|
const remind = async () => {
|
|
9653
9807
|
const snapshot = await state.get();
|
|
9808
|
+
const wakeState = Object.keys(snapshot.pendingReminders).length === 0 ? void 0 : await worktrees.lane.state.get();
|
|
9654
9809
|
for (const [key, reminder] of Object.entries(snapshot.pendingReminders)) {
|
|
9655
9810
|
const { projectId, release, member } = reminder;
|
|
9656
9811
|
try {
|
|
9657
9812
|
const id = stableHash(key);
|
|
9813
|
+
const worktree = memberWorktreeFor(
|
|
9814
|
+
worktrees.goals,
|
|
9815
|
+
wakeState?.[projectId],
|
|
9816
|
+
projectId,
|
|
9817
|
+
member.recipient
|
|
9818
|
+
);
|
|
9658
9819
|
const delivered = await deliverWake(ctx, {
|
|
9659
9820
|
projectId,
|
|
9660
9821
|
recipient: member.recipient,
|
|
9661
9822
|
requestId: `team-handbook:${id}`,
|
|
9662
9823
|
messageId: `team-handbook-msg:${id}`,
|
|
9663
|
-
text: handbookMessage("reminder", release)
|
|
9824
|
+
text: handbookMessage("reminder", release),
|
|
9825
|
+
memberWorktree: worktree === void 0 ? void 0 : { ...worktree, lane: worktrees.lane }
|
|
9664
9826
|
});
|
|
9665
9827
|
if (!delivered) continue;
|
|
9666
9828
|
const previousKey = JSON.stringify([release, member.memberId]);
|
|
@@ -9985,7 +10147,7 @@ function registerHandbookPanel(ctx, runtime) {
|
|
|
9985
10147
|
// src/index.ts
|
|
9986
10148
|
var index_default = definePlugin({
|
|
9987
10149
|
id: "team",
|
|
9988
|
-
apiVersion:
|
|
10150
|
+
apiVersion: 30,
|
|
9989
10151
|
activate(ctx) {
|
|
9990
10152
|
const rosters = createRosterService(ctx);
|
|
9991
10153
|
registerRosterCommands(ctx, rosters);
|
|
@@ -9993,9 +10155,9 @@ var index_default = definePlugin({
|
|
|
9993
10155
|
registerGoalCommands(ctx, goals);
|
|
9994
10156
|
registerBoardCommands(ctx, goals, rosters);
|
|
9995
10157
|
registerDetailCommands(ctx, goals);
|
|
9996
|
-
const wakes = startWakeRuntime(ctx);
|
|
9997
|
-
startRecoveryRuntime(ctx, goals, wakes.state);
|
|
9998
|
-
const handbook = startHandbookRuntime(ctx);
|
|
10158
|
+
const wakes = startWakeRuntime(ctx, goals);
|
|
10159
|
+
startRecoveryRuntime(ctx, goals, wakes.state, wakes.worktrees);
|
|
10160
|
+
const handbook = startHandbookRuntime(ctx, { lane: wakes.worktrees, goals });
|
|
9999
10161
|
registerHandbook(ctx, handbook);
|
|
10000
10162
|
registerHandbookPanel(ctx, handbook);
|
|
10001
10163
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ycodium-ai/plugin-team",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3254",
|
|
4
4
|
"description": "A project team roster with members, a lead, and goals.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"teams",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"tailwindcss": "^4.0.0",
|
|
35
35
|
"typescript": "~6.0.3",
|
|
36
36
|
"vite-plus": "0.2.2",
|
|
37
|
-
"@ycodium-ai/plugin-api": "0.2.
|
|
37
|
+
"@ycodium-ai/plugin-api": "0.2.3254"
|
|
38
38
|
},
|
|
39
39
|
"ycodium": {
|
|
40
40
|
"plugin": "./dist/index.js",
|
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
"commands": [
|
|
47
47
|
"thread.create",
|
|
48
48
|
"thread.turn.start",
|
|
49
|
+
"thread.worktree.prepare",
|
|
49
50
|
"thread.turn-queue.resume",
|
|
50
51
|
"work.item.create",
|
|
51
52
|
"work.item.update",
|