@ycodium-ai/plugin-team 0.2.3598 → 0.2.3608

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.
Files changed (2) hide show
  1. package/dist/index.js +92 -41
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -9056,6 +9056,67 @@ function createRosterService(ctx, options = {}) {
9056
9056
 
9057
9057
  // src/runtime/deliver.ts
9058
9058
  import * as NodeCrypto from "node:crypto";
9059
+
9060
+ // ../../packages/ycodium-system-text/src/systemText.ts
9061
+ var SYSTEM_NOTIFICATION_OPEN_TAG = "<ycodium-system>";
9062
+ var SYSTEM_NOTIFICATION_CLOSE_TAG = "</ycodium-system>";
9063
+ var isSystemNotificationText = (text) => text.startsWith(SYSTEM_NOTIFICATION_OPEN_TAG);
9064
+ var rendersAsSystemMessage = (text) => isSystemNotificationText(text) && !(isPresetPrefixMessage(text) && text.includes(PRESET_PREFIX_CLOSE) && parsePresetPrefixText(text) === null);
9065
+ var FIRST_BLOCK_START = `^(?:${SYSTEM_NOTIFICATION_OPEN_TAG}\\n)?`;
9066
+ var PRESET_PREFIX_MESSAGE_START = `${SYSTEM_NOTIFICATION_OPEN_TAG}
9067
+ <preset-prefix `;
9068
+ var isPresetPrefixMessage = (text) => text.startsWith(PRESET_PREFIX_MESSAGE_START);
9069
+ var SYSTEM_TEXT_ESCAPED_ATTRIBUTE = 'esc="1"';
9070
+ var escapeSystemText = (text) => text.replace(/&/g, "&amp;").replace(/</g, "&lt;");
9071
+ var SYSTEM_TEXT_MAX_ESCAPE_GROWTH = "&amp;".length;
9072
+ var escapeSystemAttribute = (text) => escapeSystemText(text).replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/\r/g, "&#13;").replace(/\n/g, "&#10;");
9073
+ var ESCAPED_BLOCK_NAMES = [
9074
+ "thread-response",
9075
+ "thread-handover",
9076
+ "scheduled-wake",
9077
+ "plugin-wake"
9078
+ ];
9079
+ var escapedBlockOpenTag = (name, attributes) => `<${name} ${[
9080
+ ...attributes.map(([key, value]) => `${key}="${escapeSystemAttribute(value)}"`),
9081
+ SYSTEM_TEXT_ESCAPED_ATTRIBUTE
9082
+ ].join(" ")}>`;
9083
+ var ESCAPED_OPEN_LINE_PATTERN = new RegExp(
9084
+ `^<(?:${ESCAPED_BLOCK_NAMES.join("|")})(?:\\s[^>]*)? ${SYSTEM_TEXT_ESCAPED_ATTRIBUTE}>$`
9085
+ );
9086
+ var PRESET_PREFIX_CLOSE = `
9087
+ </preset-prefix>
9088
+ ${SYSTEM_NOTIFICATION_CLOSE_TAG}`;
9089
+ var PRESET_PREFIX_PATTERN = new RegExp(
9090
+ `^${SYSTEM_NOTIFICATION_OPEN_TAG}\\n<preset-prefix id="([^"]*)">\\n([\\s\\S]*?)\\n</preset-prefix>\\n${SYSTEM_NOTIFICATION_CLOSE_TAG}(?:\\n\\n([\\s\\S]*))?$`
9091
+ );
9092
+ var parsePresetPrefixText = (text) => {
9093
+ if (text.split(PRESET_PREFIX_CLOSE).length !== 2) return null;
9094
+ const match7 = PRESET_PREFIX_PATTERN.exec(text);
9095
+ if (match7 === null) return null;
9096
+ const [, presetId, prefix, body] = match7;
9097
+ if (!presetId) return null;
9098
+ return { presetId, prefix: prefix ?? "", body: body ?? "" };
9099
+ };
9100
+ var userSpokenText = (text) => {
9101
+ if (!rendersAsSystemMessage(text)) return text;
9102
+ return parsePresetPrefixText(text)?.body || null;
9103
+ };
9104
+ var formatPluginWakeText = (input) => [
9105
+ SYSTEM_NOTIFICATION_OPEN_TAG,
9106
+ escapedBlockOpenTag("plugin-wake", [
9107
+ ["plugin", input.pluginId],
9108
+ ["reason", input.reason],
9109
+ ...input.item ? [["item", input.item]] : []
9110
+ ]),
9111
+ escapeSystemText(input.text),
9112
+ "</plugin-wake>",
9113
+ SYSTEM_NOTIFICATION_CLOSE_TAG
9114
+ ].join("\n");
9115
+ var PLUGIN_WAKE_PATTERN = new RegExp(
9116
+ `${FIRST_BLOCK_START}<plugin-wake plugin="([^"]+)" reason="([^"]+)"(?: item="([^"]+)")? ${SYSTEM_TEXT_ESCAPED_ATTRIBUTE}>\\n[\\s\\S]*?\\n</plugin-wake>`
9117
+ );
9118
+
9119
+ // src/runtime/deliver.ts
9059
9120
  var worktreeSetupSentence = async (ctx, projectId, branch) => {
9060
9121
  const intro = `You are in your own newly created worktree on branch ${branch}.`;
9061
9122
  const project2 = await ctx.projects.get({ projectId }).catch(() => null);
@@ -9064,6 +9125,12 @@ var worktreeSetupSentence = async (ctx, projectId, branch) => {
9064
9125
  return `${intro} Install dependencies according to the project's instructions before starting work.`;
9065
9126
  return `${intro} If dependencies are missing, install them before starting work. This project defines a setup command for that: ${setup.command}; run it from the worktree root with the environment variables YCODIUM_PROJECT_ROOT set to "${project2.workspaceRoot}" and YCODIUM_WORKTREE_PATH set to this worktree's path. If it fails with "could not lock config file", wait a moment and run it again.`;
9066
9127
  };
9128
+ var teamWakeText = (display, text) => formatPluginWakeText({
9129
+ pluginId: "team",
9130
+ reason: display.reason,
9131
+ item: display.sequenceId === void 0 ? void 0 : `W${display.sequenceId}`,
9132
+ text
9133
+ });
9067
9134
  var stableHash = (key) => NodeCrypto.createHash("sha256").update(key).digest("hex").slice(0, 32);
9068
9135
  var memberWorktreeBranch = (name, threadId) => {
9069
9136
  const slug = Array.from(
@@ -9115,7 +9182,7 @@ async function deliverWake(ctx, input) {
9115
9182
  message: {
9116
9183
  messageId: input.messageId,
9117
9184
  role: "user",
9118
- text,
9185
+ text: teamWakeText(input.wake, text),
9119
9186
  attachments: []
9120
9187
  },
9121
9188
  modelSelection: execution.modelSelection,
@@ -9152,9 +9219,12 @@ async function deliverWake(ctx, input) {
9152
9219
  requestId: input.requestId,
9153
9220
  message: {
9154
9221
  ...turn.message,
9155
- text: `${text}
9222
+ text: teamWakeText(
9223
+ input.wake,
9224
+ `${text}
9156
9225
 
9157
9226
  ${await worktreeSetupSentence(ctx, input.projectId, branch)}`
9227
+ )
9158
9228
  },
9159
9229
  bootstrap: {
9160
9230
  prepareWorktree: {
@@ -9190,7 +9260,8 @@ ${await worktreeSetupSentence(ctx, input.projectId, branch)}`
9190
9260
  recipient: { threadId: worktree.leadThreadId },
9191
9261
  requestId: `team-worktree-report:${threadId}`,
9192
9262
  messageId: `team-worktree-report-msg:${threadId}`,
9193
- text: `Could not create a worktree for member ${await worktree.name()} (threadId ${threadId}): ${failure.reason}. They will work in the project folder for now.`
9263
+ text: `Could not create a worktree for member ${await worktree.name()} (threadId ${threadId}): ${failure.reason}. They will work in the project folder for now.`,
9264
+ wake: { reason: "notice" }
9194
9265
  });
9195
9266
  if (!reported) throw new Error("Member worktree failure could not be reported to the lead");
9196
9267
  const receipt = await worktree.lane.events.append({
@@ -10051,7 +10122,10 @@ function createGoalService(ctx, rosterService, options = {}) {
10051
10122
  message: {
10052
10123
  messageId: `team-lead-message:${goal.projectId}:${goal.goalId}`,
10053
10124
  role: "user",
10054
- text: leadBrief(goal, roster, { engineMembers: view.stored?.version === 2 }),
10125
+ text: teamWakeText(
10126
+ { reason: "instructions" },
10127
+ leadBrief(goal, roster, { engineMembers: view.stored?.version === 2 })
10128
+ ),
10055
10129
  attachments: []
10056
10130
  },
10057
10131
  modelSelection: selections.get(goal.leadMemberId).modelSelection,
@@ -11902,6 +11976,7 @@ function startMemberBindingRuntime(ctx, goals, rosters, wakes, trials2) {
11902
11976
  recipient: { threadId: leadThreadId },
11903
11977
  requestId: `team-member-unbound-notice:${key}`,
11904
11978
  messageId: `team-member-unbound-notice-message:${key}`,
11979
+ wake: { reason: "notice" },
11905
11980
  text: rebinding ? `Member ${member.name} (memberId ${member.memberId}) passed its trial run with the new setup but could not be moved onto it: ${failure.detail}. Work not yet handed to them waits until it is. Fix the cause, for example change their model with team_update_member; they are set up again within a couple of minutes.` : `Member ${member.name} (memberId ${member.memberId}) could not join this goal: ${failure.detail}. Work assigned to them waits until they join. Fix the cause, for example change their model with team_update_member; they are set up again within a couple of minutes.`
11906
11981
  });
11907
11982
  if (delivered) told.add(key);
@@ -12080,6 +12155,7 @@ function startMemberRemovalRuntime(ctx, goals, wakes) {
12080
12155
  recipient: { threadId: lead },
12081
12156
  requestId: `team-member-removed-notice:${key}`,
12082
12157
  messageId: `team-member-removed-notice-message:${key}`,
12158
+ wake: { reason: "notice" },
12083
12159
  text: [
12084
12160
  `Member ${member.name} (memberId ${memberId}) was removed from this project's team.`,
12085
12161
  `Work that had not reached them yet was taken off them and now has no assignee: ${list(mine(taken))}. Assign it to another member with work_update_item.`,
@@ -13371,6 +13447,7 @@ function startWakeRuntime(ctx, goals, options = {}) {
13371
13447
  recipient: wake,
13372
13448
  requestId: wakeRequestId(id),
13373
13449
  messageId: `team-wake-msg:${id}`,
13450
+ wake: { reason: "work", sequenceId: wake.sequenceId },
13374
13451
  memberWorktree: worktree === void 0 ? void 0 : { ...worktree, lane: worktrees },
13375
13452
  // 评论在收件人正在跑时插进当前这一轮,不排到这一轮结束(试跑 3:一轮 97 分钟,检查点落空)。
13376
13453
  ...wake.kind === "comment" ? { steer: true } : {},
@@ -13574,6 +13651,10 @@ function startRecoveryRuntime(ctx, goals, state, worktrees) {
13574
13651
  requestId: `team-recovery:${id}:${plan.action}`,
13575
13652
  messageId: `team-recovery-msg:${id}:${plan.action}`,
13576
13653
  text: plan.text,
13654
+ // 续做与提醒是叫成员接着干活;告诉负责人谁停了是通知。
13655
+ wake: {
13656
+ reason: plan.action === "resume" || plan.action === "remind" ? "work" : "notice"
13657
+ },
13577
13658
  memberWorktree: worktree === void 0 ? void 0 : { ...worktree, lane: worktrees }
13578
13659
  });
13579
13660
  if (!delivered) continue;
@@ -13665,7 +13746,8 @@ fired:${fired.wakes.length}`);
13665
13746
  recipient: { threadId },
13666
13747
  requestId: `team-lead-checkin:${threadId}:${key}`,
13667
13748
  messageId: `team-lead-checkin-message:${threadId}:${key}`,
13668
- text: LEAD_CHECKIN_REMINDER
13749
+ text: LEAD_CHECKIN_REMINDER,
13750
+ wake: { reason: "check-in" }
13669
13751
  });
13670
13752
  }
13671
13753
  };
@@ -14372,6 +14454,7 @@ function startHandbookRuntime(ctx, worktrees) {
14372
14454
  messageId: `team-handbook-msg:${id}`,
14373
14455
  // 成员闲着时被换版提醒叫醒,不能借机自己挑活:成员的提醒写死只确认、确认完就结束这一轮。
14374
14456
  text: handbookReminder(release, seat.goal.leadMemberId === member.memberId),
14457
+ wake: { reason: "instructions" },
14375
14458
  memberWorktree: worktree === void 0 ? void 0 : { ...worktree, lane: worktrees.lane }
14376
14459
  });
14377
14460
  if (!delivered) continue;
@@ -15931,39 +16014,6 @@ async function teamWaitingList(ctx, memberThreads, nameOf2) {
15931
16014
  return waiting.length === 0 ? null : `${count(waiting.length, "member is", "members are")} waiting on the person: ${waiting.join("; ")}. These appear in this conversation for the person to answer; you cannot answer them and should not wait for them. Hand out work to members who are not blocked.`;
15932
16015
  }
15933
16016
 
15934
- // ../../packages/ycodium-system-text/src/systemText.ts
15935
- var SYSTEM_NOTIFICATION_OPEN_TAG = "<ycodium-system>";
15936
- var SYSTEM_NOTIFICATION_CLOSE_TAG = "</ycodium-system>";
15937
- var isSystemNotificationText = (text) => text.startsWith(SYSTEM_NOTIFICATION_OPEN_TAG);
15938
- var rendersAsSystemMessage = (text) => isSystemNotificationText(text) && !(isPresetPrefixMessage(text) && text.includes(PRESET_PREFIX_CLOSE) && parsePresetPrefixText(text) === null);
15939
- var FIRST_BLOCK_START = `^(?:${SYSTEM_NOTIFICATION_OPEN_TAG}\\n)?`;
15940
- var PRESET_PREFIX_MESSAGE_START = `${SYSTEM_NOTIFICATION_OPEN_TAG}
15941
- <preset-prefix `;
15942
- var isPresetPrefixMessage = (text) => text.startsWith(PRESET_PREFIX_MESSAGE_START);
15943
- var SYSTEM_TEXT_ESCAPED_ATTRIBUTE = 'esc="1"';
15944
- var ESCAPED_BLOCK_NAMES = ["thread-response", "thread-handover", "scheduled-wake"];
15945
- var ESCAPED_OPEN_LINE_PATTERN = new RegExp(
15946
- `^<(?:${ESCAPED_BLOCK_NAMES.join("|")})(?:\\s[^>]*)? ${SYSTEM_TEXT_ESCAPED_ATTRIBUTE}>$`
15947
- );
15948
- var PRESET_PREFIX_CLOSE = `
15949
- </preset-prefix>
15950
- ${SYSTEM_NOTIFICATION_CLOSE_TAG}`;
15951
- var PRESET_PREFIX_PATTERN = new RegExp(
15952
- `^${SYSTEM_NOTIFICATION_OPEN_TAG}\\n<preset-prefix id="([^"]*)">\\n([\\s\\S]*?)\\n</preset-prefix>\\n${SYSTEM_NOTIFICATION_CLOSE_TAG}(?:\\n\\n([\\s\\S]*))?$`
15953
- );
15954
- var parsePresetPrefixText = (text) => {
15955
- if (text.split(PRESET_PREFIX_CLOSE).length !== 2) return null;
15956
- const match7 = PRESET_PREFIX_PATTERN.exec(text);
15957
- if (match7 === null) return null;
15958
- const [, presetId, prefix, body] = match7;
15959
- if (!presetId) return null;
15960
- return { presetId, prefix: prefix ?? "", body: body ?? "" };
15961
- };
15962
- var userSpokenText = (text) => {
15963
- if (!rendersAsSystemMessage(text)) return text;
15964
- return parsePresetPrefixText(text)?.body || null;
15965
- };
15966
-
15967
16017
  // src/team/groupDigest.ts
15968
16018
  var DIGEST_LIMIT = 30;
15969
16019
  var SCAN_PAGES = 5;
@@ -16917,7 +16967,7 @@ async function ensureSession(env, record2, ensured, prepared) {
16917
16967
  message: {
16918
16968
  messageId: `team-trial-message:${key}`,
16919
16969
  role: "user",
16920
- text: trialMessage("localPrompt", { trialId }),
16970
+ text: teamWakeText({ reason: "instructions" }, trialMessage("localPrompt", { trialId })),
16921
16971
  attachments: []
16922
16972
  },
16923
16973
  modelSelection: selection.modelSelection,
@@ -16987,7 +17037,8 @@ async function tellLeads(env, leadThreads, projectId, key, text) {
16987
17037
  recipient: { threadId: leadThreadId },
16988
17038
  requestId,
16989
17039
  messageId: `${requestId}:message`,
16990
- text
17040
+ text,
17041
+ wake: { reason: "notice" }
16991
17042
  });
16992
17043
  delivered ||= sent;
16993
17044
  }
@@ -17413,7 +17464,7 @@ function startTrialRuntime(ctx, deps, options = {}) {
17413
17464
  // src/index.ts
17414
17465
  var index_default = definePlugin({
17415
17466
  id: "team",
17416
- apiVersion: 48,
17467
+ apiVersion: 49,
17417
17468
  activate(ctx) {
17418
17469
  const trialState = ctx.derivedState(trialStateDefinition);
17419
17470
  const rosters = createRosterService(ctx);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ycodium-ai/plugin-team",
3
- "version": "0.2.3598",
3
+ "version": "0.2.3608",
4
4
  "description": "A project team roster with members, a lead, and goals.",
5
5
  "keywords": [
6
6
  "teams",
@@ -34,8 +34,8 @@
34
34
  "tailwindcss": "^4.0.0",
35
35
  "typescript": "~6.0.3",
36
36
  "vite-plus": "0.2.2",
37
- "ycodium-system-text": "0.0.0",
38
- "@ycodium-ai/plugin-api": "0.2.3598"
37
+ "@ycodium-ai/plugin-api": "0.2.3608",
38
+ "ycodium-system-text": "0.0.0"
39
39
  },
40
40
  "ycodium": {
41
41
  "plugin": "./dist/index.js",