@ycodium-ai/plugin-team 0.2.4160 → 0.2.4162
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/README.md +3 -2
- package/dist/index.js +35 -8
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -50,8 +50,9 @@ on a remote seat; the release check was not exercised, and the other providers h
|
|
|
50
50
|
provider-by-provider table is in the [team plugin](../../docs/internals/team-plugin.md#trial-run) page.
|
|
51
51
|
|
|
52
52
|
Starting a goal also puts the goal on the board as a work item assigned to the lead, recorded
|
|
53
|
-
with this plugin as its author. The lead does no item itself, merging and pushing included
|
|
54
|
-
|
|
53
|
+
with this plugin as its author. The lead does no item itself, merging and pushing included. While the
|
|
54
|
+
goal is open, a member's completed item wakes the lead for review without requiring a dependency on
|
|
55
|
+
the goal item. When all work is finished, it checks the results and marks the goal item done,
|
|
55
56
|
and the team's Board view shows that item's state.
|
|
56
57
|
|
|
57
58
|
Member conversations start without messages; each gets its first one when work is assigned to its member.
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ var __export = (target, all3) => {
|
|
|
8
8
|
import { definePlugin } from "@ycodium-ai/plugin-api";
|
|
9
9
|
|
|
10
10
|
// ../../packages/plugin-api/src/version.ts
|
|
11
|
-
var PLUGIN_API_VERSION =
|
|
11
|
+
var PLUGIN_API_VERSION = 99;
|
|
12
12
|
|
|
13
13
|
// ../../node_modules/.pnpm/effect@4.0.0-beta.103_patch_hash=78523ded7c3dfc3efd3cec0247f4960d00eaa3d3c96a2077457694a4d8b453c6/node_modules/effect/dist/Pipeable.js
|
|
14
14
|
var pipeArguments = (self, args2) => {
|
|
@@ -10932,6 +10932,12 @@ var decodeCompletion = decodeUnknownOption2(
|
|
|
10932
10932
|
var openLeadItemsBlockedBy = (project2, workItemId, lead) => lead === void 0 ? [] : Object.entries(project2.items).filter(
|
|
10933
10933
|
([id]) => isAssignedOpen(project2, id, lead) && readFact(project2.blockers, id)?.includes(workItemId) === true
|
|
10934
10934
|
);
|
|
10935
|
+
var hasOpenTeamGoal = (project2, review) => {
|
|
10936
|
+
const item = readFact(project2.items, review.workItemId);
|
|
10937
|
+
if (item === null) return false;
|
|
10938
|
+
const scope2 = scopeOfRecipient(project2, review.by, item.workLineId);
|
|
10939
|
+
return scope2 !== void 0 && scope2 === scopeForLine(project2, item.workLineId) && scope2.goalId !== void 0 && scope2.leadThreads?.includes(review.threadId) === true && isAssignedOpen(project2, teamGoalItemId(review.projectId, scope2.goalId), review.threadId);
|
|
10940
|
+
};
|
|
10935
10941
|
function reviewOnUpdate(previous, next, event) {
|
|
10936
10942
|
const decoded = decodeCompletion(event.payload);
|
|
10937
10943
|
if (isNone2(decoded) || decoded.value.state.group !== "completed") return null;
|
|
@@ -10942,16 +10948,18 @@ function reviewOnUpdate(previous, next, event) {
|
|
|
10942
10948
|
if (lead === void 0) return null;
|
|
10943
10949
|
if (!isMember(next, by) || "threadId" in by && isLeadThread(next, by.threadId)) return null;
|
|
10944
10950
|
const goals = openLeadItemsBlockedBy(next, workItemId, lead);
|
|
10945
|
-
|
|
10946
|
-
return {
|
|
10951
|
+
const review = {
|
|
10947
10952
|
key: `review:${workItemId}:${lead}#${event.sequence}`,
|
|
10948
10953
|
projectId,
|
|
10949
10954
|
workItemId,
|
|
10950
10955
|
threadId: lead,
|
|
10951
10956
|
by
|
|
10952
10957
|
};
|
|
10958
|
+
if (goals.some(([id]) => isWorkable(next, id)) || goals.length === 0 && !hasOpenTeamGoal(next, review))
|
|
10959
|
+
return null;
|
|
10960
|
+
return review;
|
|
10953
10961
|
}
|
|
10954
|
-
var isLiveReview = (project2, review) => isLeadThread(project2, review.threadId) && readFact(project2.items, review.workItemId)?.stateGroup === "completed" && openLeadItemsBlockedBy(project2, review.workItemId, review.threadId).length > 0;
|
|
10962
|
+
var isLiveReview = (project2, review) => isLeadThread(project2, review.threadId) && readFact(project2.items, review.workItemId)?.stateGroup === "completed" && (openLeadItemsBlockedBy(project2, review.workItemId, review.threadId).length > 0 || hasOpenTeamGoal(project2, review));
|
|
10955
10963
|
var isReviewDue = (project2, key) => project2.pendingReviews?.some((review) => review.key === key && isLiveReview(project2, review)) === true;
|
|
10956
10964
|
var dueReviews = (project2) => (project2.pendingReviews ?? []).filter((review) => isLiveReview(project2, review)).map((review) => {
|
|
10957
10965
|
const item = readFact(project2.items, review.workItemId);
|
|
@@ -12114,7 +12122,7 @@ function withPause(project2, change, legacyEventId) {
|
|
|
12114
12122
|
|
|
12115
12123
|
// src/runtime/wakeState.ts
|
|
12116
12124
|
var WAKE_STATE_KEY = "wakes";
|
|
12117
|
-
var WAKE_STATE_VERSION =
|
|
12125
|
+
var WAKE_STATE_VERSION = 10;
|
|
12118
12126
|
var WAKE_EVENTS = [
|
|
12119
12127
|
"work.item-created",
|
|
12120
12128
|
"work.item-updated",
|
|
@@ -12126,6 +12134,8 @@ var WAKE_EVENTS = [
|
|
|
12126
12134
|
"work.item-dispatched",
|
|
12127
12135
|
"plugin.event-appended",
|
|
12128
12136
|
"thread.session-set",
|
|
12137
|
+
"thread.turn-start-requested",
|
|
12138
|
+
"thread.unarchived",
|
|
12129
12139
|
// 线与线上成员的暂停:引擎的看板事实,派发闸读它(见 `linePauses` / `pausedMembers`)。
|
|
12130
12140
|
"work.line-paused",
|
|
12131
12141
|
"work.line-resumed",
|
|
@@ -12541,6 +12551,7 @@ function foldWakes(state, event) {
|
|
|
12541
12551
|
}
|
|
12542
12552
|
|
|
12543
12553
|
// src/runtime/wake.ts
|
|
12554
|
+
var decodeThread = decodeUnknownOption2(Struct({ threadId: String4 }));
|
|
12544
12555
|
function startWakeRuntime(ctx, goals, options = {}) {
|
|
12545
12556
|
const wakes = ctx.derivedState({
|
|
12546
12557
|
key: WAKE_STATE_KEY,
|
|
@@ -12552,6 +12563,7 @@ function startWakeRuntime(ctx, goals, options = {}) {
|
|
|
12552
12563
|
const worktrees = createMemberWorktreeLane(wakes, ctx.events);
|
|
12553
12564
|
const hash2 = options.hash ?? stableHash;
|
|
12554
12565
|
let pending = Promise.resolve();
|
|
12566
|
+
let queued;
|
|
12555
12567
|
const readItem = async (projectId, workItemId) => {
|
|
12556
12568
|
const result2 = await ctx.work.items.get({ projectId, workItemIds: [workItemId] });
|
|
12557
12569
|
return result2.items.find((item) => item.workItemId === workItemId);
|
|
@@ -12586,7 +12598,7 @@ function startWakeRuntime(ctx, goals, options = {}) {
|
|
|
12586
12598
|
{
|
|
12587
12599
|
idle: facts.idle.map((threadId) => name({ threadId })),
|
|
12588
12600
|
queued: facts.queued.map(
|
|
12589
|
-
(
|
|
12601
|
+
(queued2) => `${workLabel(queued2.workItemId, queued2.sequenceId)}, assigned to ${name({ threadId: queued2.threadId })}`
|
|
12590
12602
|
)
|
|
12591
12603
|
}
|
|
12592
12604
|
);
|
|
@@ -12690,7 +12702,12 @@ function startWakeRuntime(ctx, goals, options = {}) {
|
|
|
12690
12702
|
}
|
|
12691
12703
|
};
|
|
12692
12704
|
const flush = () => {
|
|
12693
|
-
|
|
12705
|
+
if (queued !== void 0) return queued;
|
|
12706
|
+
const result2 = pending.then(() => {
|
|
12707
|
+
queued = void 0;
|
|
12708
|
+
return execute();
|
|
12709
|
+
});
|
|
12710
|
+
queued = result2;
|
|
12694
12711
|
pending = result2.then(
|
|
12695
12712
|
() => void 0,
|
|
12696
12713
|
() => void 0
|
|
@@ -12700,7 +12717,17 @@ function startWakeRuntime(ctx, goals, options = {}) {
|
|
|
12700
12717
|
ctx.reactor({
|
|
12701
12718
|
name: "team-wake",
|
|
12702
12719
|
events: WAKE_EVENTS,
|
|
12703
|
-
handle: (event) =>
|
|
12720
|
+
handle: async (event) => {
|
|
12721
|
+
if (event.type === "thread.session-set" || isRecoveryFact(event)) return;
|
|
12722
|
+
if (event.type === "thread.turn-start-requested" || event.type === "thread.unarchived") {
|
|
12723
|
+
const thread = decodeThread(event.payload);
|
|
12724
|
+
if (isNone2(thread) || !dueWakes(await wakes.get()).some(
|
|
12725
|
+
(wake) => "threadId" in wake && wake.threadId === thread.value.threadId
|
|
12726
|
+
))
|
|
12727
|
+
return;
|
|
12728
|
+
}
|
|
12729
|
+
await flush();
|
|
12730
|
+
}
|
|
12704
12731
|
});
|
|
12705
12732
|
const ready = flush();
|
|
12706
12733
|
void ready.catch((error) => ctx.log?.warn("team wake catch-up failed", { error }));
|
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.4162",
|
|
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.4162",
|
|
38
38
|
"ycodium-system-text": "0.0.0"
|
|
39
39
|
},
|
|
40
40
|
"ycodium": {
|