@ycodium-ai/plugin-team 0.2.3671 → 0.2.3681

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 CHANGED
@@ -7,78 +7,6 @@ var __export = (target, all3) => {
7
7
  // src/index.ts
8
8
  import { definePlugin } from "@ycodium-ai/plugin-api";
9
9
 
10
- // ../../node_modules/.pnpm/effect@4.0.0-beta.103_patch_hash=78523ded7c3dfc3efd3cec0247f4960d00eaa3d3c96a2077457694a4d8b453c6/node_modules/effect/dist/Option.js
11
- var Option_exports = {};
12
- __export(Option_exports, {
13
- Do: () => Do,
14
- all: () => all,
15
- andThen: () => andThen,
16
- as: () => as,
17
- asVoid: () => asVoid,
18
- bind: () => bind2,
19
- bindTo: () => bindTo2,
20
- composeK: () => composeK,
21
- contains: () => contains,
22
- containsWith: () => containsWith,
23
- exists: () => exists,
24
- filter: () => filter,
25
- filterMap: () => filterMap,
26
- firstSomeOf: () => firstSomeOf,
27
- flatMap: () => flatMap,
28
- flatMapNullishOr: () => flatMapNullishOr,
29
- flatten: () => flatten,
30
- fromIterable: () => fromIterable,
31
- fromNullOr: () => fromNullOr,
32
- fromNullishOr: () => fromNullishOr,
33
- fromUndefinedOr: () => fromUndefinedOr,
34
- gen: () => gen,
35
- getFailure: () => getFailure2,
36
- getOrElse: () => getOrElse,
37
- getOrNull: () => getOrNull,
38
- getOrThrow: () => getOrThrow,
39
- getOrThrowWith: () => getOrThrowWith,
40
- getOrUndefined: () => getOrUndefined,
41
- getSuccess: () => getSuccess2,
42
- isNone: () => isNone2,
43
- isOption: () => isOption2,
44
- isSome: () => isSome2,
45
- let: () => let_2,
46
- lift2: () => lift2,
47
- liftNullishOr: () => liftNullishOr,
48
- liftPredicate: () => liftPredicate,
49
- liftThrowable: () => liftThrowable,
50
- makeCombinerFailFast: () => makeCombinerFailFast,
51
- makeEquivalence: () => makeEquivalence,
52
- makeOrder: () => makeOrder,
53
- makeReducer: () => makeReducer,
54
- makeReducerFailFast: () => makeReducerFailFast,
55
- map: () => map,
56
- match: () => match,
57
- none: () => none2,
58
- orElse: () => orElse,
59
- orElseResult: () => orElseResult,
60
- orElseSome: () => orElseSome,
61
- partitionMap: () => partitionMap,
62
- product: () => product,
63
- productMany: () => productMany,
64
- reduceCompact: () => reduceCompact,
65
- some: () => some2,
66
- tap: () => tap,
67
- toArray: () => toArray,
68
- toRefinement: () => toRefinement,
69
- void: () => void_,
70
- zipLeft: () => zipLeft,
71
- zipRight: () => zipRight,
72
- zipWith: () => zipWith
73
- });
74
-
75
- // ../../node_modules/.pnpm/effect@4.0.0-beta.103_patch_hash=78523ded7c3dfc3efd3cec0247f4960d00eaa3d3c96a2077457694a4d8b453c6/node_modules/effect/dist/Combiner.js
76
- function make(combine2) {
77
- return {
78
- combine: combine2
79
- };
80
- }
81
-
82
10
  // ../../node_modules/.pnpm/effect@4.0.0-beta.103_patch_hash=78523ded7c3dfc3efd3cec0247f4960d00eaa3d3c96a2077457694a4d8b453c6/node_modules/effect/dist/Pipeable.js
83
11
  var pipeArguments = (self, args2) => {
84
12
  switch (args2.length) {
@@ -548,7 +476,7 @@ var isEqual = (u) => hasProperty(u, symbol2);
548
476
  var asEquivalence = () => equals;
549
477
 
550
478
  // ../../node_modules/.pnpm/effect@4.0.0-beta.103_patch_hash=78523ded7c3dfc3efd3cec0247f4960d00eaa3d3c96a2077457694a4d8b453c6/node_modules/effect/dist/Reducer.js
551
- function make2(combine2, initialValue, combineAll) {
479
+ function make(combine2, initialValue, combineAll) {
552
480
  return {
553
481
  combine: combine2,
554
482
  initialValue,
@@ -563,7 +491,10 @@ function make2(combine2, initialValue, combineAll) {
563
491
  }
564
492
 
565
493
  // ../../node_modules/.pnpm/effect@4.0.0-beta.103_patch_hash=78523ded7c3dfc3efd3cec0247f4960d00eaa3d3c96a2077457694a4d8b453c6/node_modules/effect/dist/Equivalence.js
566
- var make3 = (isEquivalent) => (self, that) => self === that || isEquivalent(self, that);
494
+ var make2 = (isEquivalent) => (self, that) => self === that || isEquivalent(self, that);
495
+
496
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.103_patch_hash=78523ded7c3dfc3efd3cec0247f4960d00eaa3d3c96a2077457694a4d8b453c6/node_modules/effect/dist/internal/array.js
497
+ var isArrayNonEmpty = (self) => self.length > 0;
567
498
 
568
499
  // ../../node_modules/.pnpm/effect@4.0.0-beta.103_patch_hash=78523ded7c3dfc3efd3cec0247f4960d00eaa3d3c96a2077457694a4d8b453c6/node_modules/effect/dist/internal/doNotation.js
569
500
  var let_ = (map7) => dual(3, (self, name, f) => map7(self, (a) => ({
@@ -578,6 +509,100 @@ var bind = (map7, flatMap4) => dual(3, (self, name, f) => flatMap4(self, (a) =>
578
509
  [name]: b
579
510
  }))));
580
511
 
512
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.103_patch_hash=78523ded7c3dfc3efd3cec0247f4960d00eaa3d3c96a2077457694a4d8b453c6/node_modules/effect/dist/internal/record.js
513
+ function assignProperty(self, key, value) {
514
+ if (key === "__proto__") {
515
+ Object.defineProperty(self, key, {
516
+ value,
517
+ writable: true,
518
+ enumerable: true,
519
+ configurable: true
520
+ });
521
+ } else {
522
+ ;
523
+ self[key] = value;
524
+ }
525
+ }
526
+ function assignProperties(self, source) {
527
+ for (const key of Reflect.ownKeys(source)) {
528
+ if (Object.prototype.propertyIsEnumerable.call(source, key)) {
529
+ assignProperty(self, key, source[key]);
530
+ }
531
+ }
532
+ }
533
+
534
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.103_patch_hash=78523ded7c3dfc3efd3cec0247f4960d00eaa3d3c96a2077457694a4d8b453c6/node_modules/effect/dist/Option.js
535
+ var Option_exports = {};
536
+ __export(Option_exports, {
537
+ Do: () => Do,
538
+ all: () => all,
539
+ andThen: () => andThen,
540
+ as: () => as,
541
+ asVoid: () => asVoid,
542
+ bind: () => bind2,
543
+ bindTo: () => bindTo2,
544
+ composeK: () => composeK,
545
+ contains: () => contains,
546
+ containsWith: () => containsWith,
547
+ exists: () => exists,
548
+ filter: () => filter,
549
+ filterMap: () => filterMap,
550
+ firstSomeOf: () => firstSomeOf,
551
+ flatMap: () => flatMap,
552
+ flatMapNullishOr: () => flatMapNullishOr,
553
+ flatten: () => flatten,
554
+ fromIterable: () => fromIterable,
555
+ fromNullOr: () => fromNullOr,
556
+ fromNullishOr: () => fromNullishOr,
557
+ fromUndefinedOr: () => fromUndefinedOr,
558
+ gen: () => gen,
559
+ getFailure: () => getFailure2,
560
+ getOrElse: () => getOrElse,
561
+ getOrNull: () => getOrNull,
562
+ getOrThrow: () => getOrThrow,
563
+ getOrThrowWith: () => getOrThrowWith,
564
+ getOrUndefined: () => getOrUndefined,
565
+ getSuccess: () => getSuccess2,
566
+ isNone: () => isNone2,
567
+ isOption: () => isOption2,
568
+ isSome: () => isSome2,
569
+ let: () => let_2,
570
+ lift2: () => lift2,
571
+ liftNullishOr: () => liftNullishOr,
572
+ liftPredicate: () => liftPredicate,
573
+ liftThrowable: () => liftThrowable,
574
+ makeCombinerFailFast: () => makeCombinerFailFast,
575
+ makeEquivalence: () => makeEquivalence,
576
+ makeOrder: () => makeOrder,
577
+ makeReducer: () => makeReducer,
578
+ makeReducerFailFast: () => makeReducerFailFast,
579
+ map: () => map,
580
+ match: () => match,
581
+ none: () => none2,
582
+ orElse: () => orElse,
583
+ orElseResult: () => orElseResult,
584
+ orElseSome: () => orElseSome,
585
+ partitionMap: () => partitionMap,
586
+ product: () => product,
587
+ productMany: () => productMany,
588
+ reduceCompact: () => reduceCompact,
589
+ some: () => some2,
590
+ tap: () => tap,
591
+ toArray: () => toArray,
592
+ toRefinement: () => toRefinement,
593
+ void: () => void_,
594
+ zipLeft: () => zipLeft,
595
+ zipRight: () => zipRight,
596
+ zipWith: () => zipWith
597
+ });
598
+
599
+ // ../../node_modules/.pnpm/effect@4.0.0-beta.103_patch_hash=78523ded7c3dfc3efd3cec0247f4960d00eaa3d3c96a2077457694a4d8b453c6/node_modules/effect/dist/Combiner.js
600
+ function make3(combine2) {
601
+ return {
602
+ combine: combine2
603
+ };
604
+ }
605
+
581
606
  // ../../node_modules/.pnpm/effect@4.0.0-beta.103_patch_hash=78523ded7c3dfc3efd3cec0247f4960d00eaa3d3c96a2077457694a4d8b453c6/node_modules/effect/dist/Redactable.js
582
607
  var symbolRedactable = /* @__PURE__ */ Symbol.for("~effect/Redactable");
583
608
  var isRedactable = (u) => hasProperty(u, symbolRedactable);
@@ -800,28 +825,6 @@ var pickInternalCall = () => {
800
825
  };
801
826
  var internalCall = /* @__PURE__ */ pickInternalCall();
802
827
 
803
- // ../../node_modules/.pnpm/effect@4.0.0-beta.103_patch_hash=78523ded7c3dfc3efd3cec0247f4960d00eaa3d3c96a2077457694a4d8b453c6/node_modules/effect/dist/internal/record.js
804
- function assignProperty(self, key, value) {
805
- if (key === "__proto__") {
806
- Object.defineProperty(self, key, {
807
- value,
808
- writable: true,
809
- enumerable: true,
810
- configurable: true
811
- });
812
- } else {
813
- ;
814
- self[key] = value;
815
- }
816
- }
817
- function assignProperties(self, source) {
818
- for (const key of Reflect.ownKeys(source)) {
819
- if (Object.prototype.propertyIsEnumerable.call(source, key)) {
820
- assignProperty(self, key, source[key]);
821
- }
822
- }
823
- }
824
-
825
828
  // ../../node_modules/.pnpm/effect@4.0.0-beta.103_patch_hash=78523ded7c3dfc3efd3cec0247f4960d00eaa3d3c96a2077457694a4d8b453c6/node_modules/effect/dist/internal/core.js
826
829
  var EffectTypeId = `~effect/Effect`;
827
830
  var ExitTypeId = `~effect/Exit`;
@@ -1440,7 +1443,7 @@ var filterMap = /* @__PURE__ */ dual(2, (self, f) => {
1440
1443
  return isSuccess(next) ? some2(next.success) : none2();
1441
1444
  });
1442
1445
  var filter = /* @__PURE__ */ dual(2, (self, predicate) => isNone2(self) ? none2() : predicate(self.value) ? some2(self.value) : none2());
1443
- var makeEquivalence = (isEquivalent) => make3((x, y) => isNone2(x) ? isNone2(y) : isNone2(y) ? false : isEquivalent(x.value, y.value));
1446
+ var makeEquivalence = (isEquivalent) => make2((x, y) => isNone2(x) ? isNone2(y) : isNone2(y) ? false : isEquivalent(x.value, y.value));
1444
1447
  var makeOrder = (O) => make4((self, that) => isSome2(self) ? isSome2(that) ? O(self.value, that.value) : 1 : -1);
1445
1448
  var lift2 = (f) => dual(2, (self, that) => zipWith(self, that, f));
1446
1449
  var liftPredicate = /* @__PURE__ */ dual(2, (b, predicate) => predicate(b) ? some2(b) : none2());
@@ -1465,14 +1468,14 @@ var gen = (...args2) => {
1465
1468
  return some2(state.value);
1466
1469
  };
1467
1470
  function makeReducer(combiner) {
1468
- return make2((self, that) => {
1471
+ return make((self, that) => {
1469
1472
  if (isNone2(self)) return that;
1470
1473
  if (isNone2(that)) return self;
1471
1474
  return some2(combiner.combine(self.value, that.value));
1472
1475
  }, none2());
1473
1476
  }
1474
1477
  function makeCombinerFailFast(combiner) {
1475
- return make((self, that) => {
1478
+ return make3((self, that) => {
1476
1479
  if (isNone2(self) || isNone2(that)) return none2();
1477
1480
  return some2(combiner.combine(self.value, that.value));
1478
1481
  });
@@ -1480,7 +1483,7 @@ function makeCombinerFailFast(combiner) {
1480
1483
  function makeReducerFailFast(reducer) {
1481
1484
  const combine2 = makeCombinerFailFast(reducer).combine;
1482
1485
  const initialValue = some2(reducer.initialValue);
1483
- return make2(combine2, initialValue, (collection) => {
1486
+ return make(combine2, initialValue, (collection) => {
1484
1487
  let out = initialValue;
1485
1488
  for (const value of collection) {
1486
1489
  out = combine2(out, value);
@@ -1490,9 +1493,6 @@ function makeReducerFailFast(reducer) {
1490
1493
  });
1491
1494
  }
1492
1495
 
1493
- // ../../node_modules/.pnpm/effect@4.0.0-beta.103_patch_hash=78523ded7c3dfc3efd3cec0247f4960d00eaa3d3c96a2077457694a4d8b453c6/node_modules/effect/dist/internal/array.js
1494
- var isArrayNonEmpty = (self) => self.length > 0;
1495
-
1496
1496
  // ../../node_modules/.pnpm/effect@4.0.0-beta.103_patch_hash=78523ded7c3dfc3efd3cec0247f4960d00eaa3d3c96a2077457694a4d8b453c6/node_modules/effect/dist/Result.js
1497
1497
  var succeed2 = succeed;
1498
1498
  var fail2 = fail;
@@ -7158,7 +7158,6 @@ var TrialSessionClosed = Struct({
7158
7158
  var AUTO_RETRY_CATEGORIES = /* @__PURE__ */ new Set(["rate-limit", "transport"]);
7159
7159
  var NEEDS_CHANGE_CATEGORIES = /* @__PURE__ */ new Set([
7160
7160
  "no-route",
7161
- "other-machine",
7162
7161
  "toolkit-off",
7163
7162
  "model-unavailable",
7164
7163
  "start-failed",
@@ -7431,8 +7430,10 @@ var TeamMember = Struct({
7431
7430
  name: String4,
7432
7431
  principal: optionalKey2(
7433
7432
  Struct({ kind: Literal2("remote-agent"), principalId: String4 })
7434
- )
7433
+ ),
7434
+ remote: optionalKey2(Literal2(true))
7435
7435
  });
7436
+ var isRemoteTeamMember = (member) => member.remote === true || member.principal !== void 0;
7436
7437
  var TeamRuleCode = Literals([
7437
7438
  "member-count",
7438
7439
  "lead-not-member",
@@ -7465,13 +7466,8 @@ function rosterRuleError(input) {
7465
7466
  }
7466
7467
  function teamRuleError(input) {
7467
7468
  if (input.members.length < 1) return "member-count";
7468
- const principals = /* @__PURE__ */ new Set();
7469
7469
  for (const member of input.members) {
7470
- if (member.principal === void 0) continue;
7471
- const { principalId } = member.principal;
7472
- if (principals.has(principalId)) return "duplicate-principal";
7473
- principals.add(principalId);
7474
- if (member.memberId === input.leadMemberId) return "lead-remote";
7470
+ if (isRemoteTeamMember(member) && member.memberId === input.leadMemberId) return "lead-remote";
7475
7471
  }
7476
7472
  return input.members.some((member) => member.memberId === input.leadMemberId) ? null : "lead-not-member";
7477
7473
  }
@@ -7556,14 +7552,15 @@ var workIdentity = (value) => ({
7556
7552
  ...value.principal === void 0 ? {} : { personKey: personKey(value.principal) }
7557
7553
  });
7558
7554
  var BoardPerson = Struct({ key: String4, displayName: String4 });
7559
- var BoardRemoteAgent = Struct({
7555
+ var BoardMachine = Struct({
7560
7556
  principalId: String4,
7561
- label: String4,
7562
- state: Literals(["active", "disabled", "revoked"]),
7563
- lastUsedAt: optionalKey2(String4)
7557
+ environmentId: String4,
7558
+ name: String4,
7559
+ online: Boolean3,
7560
+ lastSeenAt: optionalKey2(String4)
7564
7561
  });
7565
7562
  var BoardRemoteWork = Struct({
7566
- principalId: String4,
7563
+ memberId: String4,
7567
7564
  pending: NullOr(
7568
7565
  Struct({
7569
7566
  count: Number5,
@@ -7631,8 +7628,8 @@ var BoardSnapshot = Struct({
7631
7628
  // 指派菜单的选项:项目里还在队的成员(人和 agent)。引擎里的成员读不出来时省略并标 membersUnavailable。
7632
7629
  assignableMembers: optionalKey2(ArraySchema(AssignableMember)),
7633
7630
  membersUnavailable: optionalKey2(Literal2(true)),
7634
- remoteAgents: ArraySchema(BoardRemoteAgent),
7635
- remoteAgentsUnavailable: optionalKey2(Literal2(true)),
7631
+ machines: ArraySchema(BoardMachine),
7632
+ machinesUnavailable: optionalKey2(Literal2(true)),
7636
7633
  remoteWork: ArraySchema(BoardRemoteWork),
7637
7634
  viewerKey: optionalKey2(String4),
7638
7635
  // 负责人要用看板与项目记忆两组工具;开关由宿主控件拨,这里只读来提示。
@@ -7643,38 +7640,6 @@ var ReadBoardInput = Struct({
7643
7640
  projectId: String4,
7644
7641
  workLineId: optionalKey2(String4)
7645
7642
  });
7646
- var CreateItemInput = Struct({
7647
- projectId: String4,
7648
- title: String4,
7649
- description: optionalKey2(String4),
7650
- /** 指派给的项目成员(引擎成员号);成员存在、未移除由引擎核。 */
7651
- assigneeMemberId: optionalKey2(String4),
7652
- /** 件建在哪条线上;团队层的看板带它,项目层不带(没分线)。 */
7653
- workLineId: optionalKey2(String4),
7654
- requestId: String4
7655
- });
7656
- var UpdateItemInput = Struct({
7657
- projectId: String4,
7658
- workItemId: String4,
7659
- expectedVersion: Int.check(isGreaterThanOrEqualTo3(1)),
7660
- stateId: optionalKey2(String4),
7661
- assigneeMemberId: optionalKey2(String4),
7662
- unassign: optionalKey2(Boolean3)
7663
- });
7664
- var BoardRejection = Struct({
7665
- _tag: Literal2("TeamBoardRejection"),
7666
- commandType: Literals(["createItem", "updateItem", "postComment"]),
7667
- code: String4,
7668
- details: optionalKey2(Unknown2)
7669
- });
7670
- var CreateItemResult = Union2([
7671
- Struct({ workItemId: String4 }),
7672
- BoardRejection
7673
- ]);
7674
- var UpdateItemResult = Union2([
7675
- Struct({ workItemId: String4, version: Number5 }),
7676
- BoardRejection
7677
- ]);
7678
7643
 
7679
7644
  // src/watch.ts
7680
7645
  var emptyChanges = () => ({ cursor: 0, handbookCursor: 0, membersCursor: 0 });
@@ -7872,6 +7837,18 @@ function registerTeamWatch(ctx, hasMember, options) {
7872
7837
  });
7873
7838
  }
7874
7839
 
7840
+ // src/domain/machines.ts
7841
+ async function readMachines(ctx, projectId) {
7842
+ try {
7843
+ const { items } = await ctx.projects.machines.list({ projectId, includeModels: true });
7844
+ return new Map(items.map((machine) => [machine.environmentId, machine]));
7845
+ } catch {
7846
+ return null;
7847
+ }
7848
+ }
7849
+ var memberEnvironment = (member) => member.agent?.environmentId ?? null;
7850
+ var isRemoteMember = (member, localEnvironmentId) => member.kind === "agent" && memberEnvironment(member) !== localEnvironmentId;
7851
+
7875
7852
  // src/workReads.ts
7876
7853
  var PAGE_SIZE = 200;
7877
7854
  async function readPages(maximum, read, keep = "oldest") {
@@ -8052,7 +8029,7 @@ var lineScopeOfThread = (project2, threadId) => {
8052
8029
  var scopeOfPrincipal = (project2, principalId) => scopesOf(project2).find((scope2) => scope2.remoteMembers.includes(principalId));
8053
8030
  var isGoalThread = (project2, threadId) => scopeOfThread(project2, threadId) !== void 0;
8054
8031
  var isLeadThread = (project2, threadId) => scopesOf(project2).some((scope2) => scope2.leadThreads?.includes(threadId) === true);
8055
- var isRemoteMember = (project2, principalId) => scopeOfPrincipal(project2, principalId) !== void 0;
8032
+ var isRemoteMember2 = (project2, principalId) => scopeOfPrincipal(project2, principalId) !== void 0;
8056
8033
  var leadOfThread = (project2, threadId) => scopeOfThread(project2, threadId)?.leadThreads?.[0];
8057
8034
  var placeOfRecipient = (project2, who, workLineId) => {
8058
8035
  if ("threadId" in who) {
@@ -8140,7 +8117,7 @@ var memberLookup = (project2) => {
8140
8117
  let pinned;
8141
8118
  return (threadId) => isGoalThread(project2, threadId) || (pinned ??= pinnedOpenThreads(project2)).has(threadId);
8142
8119
  };
8143
- var isMember = (project2, recipient) => "threadId" in recipient ? isGoalThread(project2, recipient.threadId) || hasPinnedOpenItem(project2, recipient.threadId) : isRemoteMember(project2, recipient.principalId);
8120
+ var isMember = (project2, recipient) => "threadId" in recipient ? isGoalThread(project2, recipient.threadId) || hasPinnedOpenItem(project2, recipient.threadId) : isRemoteMember2(project2, recipient.principalId);
8144
8121
  var isQueuedUnclaimed = (item, threadId) => item.wakeStatus?.[threadId] === "pending" && !item.claimedBy.includes(threadId);
8145
8122
  var isDeferredWake = (project2, item, threadId) => isGoalThread(project2, threadId) && !isLeadThread(project2, threadId) && item.assigneeThreads.includes(threadId) && isQueuedUnclaimed(item, threadId) && !isClosed(item);
8146
8123
  function countDeferredWakes(project2, threadId) {
@@ -8327,34 +8304,6 @@ async function readPinnedSessions(ctx, rows, wakeProject, listed) {
8327
8304
  );
8328
8305
  }
8329
8306
 
8330
- // src/workWrites.ts
8331
- var decodeHostRefusal = decodeUnknownOption2(
8332
- Struct({
8333
- rejection: Struct({
8334
- code: String4,
8335
- details: optionalKey2(Unknown2)
8336
- })
8337
- })
8338
- );
8339
- var rejectWork = (commandType, code) => ({ _tag: "TeamBoardRejection", commandType, code });
8340
- async function writeWork(invocation, commandType, write) {
8341
- if (invocation.asPerson === void 0) return rejectWork(commandType, "needs-person");
8342
- try {
8343
- return await write(invocation.asPerson.work);
8344
- } catch (error) {
8345
- const refusal = decodeHostRefusal(error);
8346
- if (isNone2(refusal)) throw error;
8347
- const { code, details } = refusal.value.rejection;
8348
- return {
8349
- ...rejectWork(
8350
- commandType,
8351
- commandType !== "postComment" && code === "version-conflict" ? "stale-version" : code
8352
- ),
8353
- ...details === void 0 ? {} : { details }
8354
- };
8355
- }
8356
- }
8357
-
8358
8307
  // src/domain/goalItem.ts
8359
8308
  var teamGoalItemId = (projectId, goalId) => `team-goal:${projectId}:${goalId}`;
8360
8309
  var GOAL_ITEM_TITLE_MAX = 120;
@@ -8366,10 +8315,7 @@ var goalItemTitle = (goal) => {
8366
8315
  // src/board.ts
8367
8316
  var ITEM_LIMIT = 500;
8368
8317
  var PEOPLE_LIMIT = 200;
8369
- var REMOTE_AGENT_LIMIT = 1e3;
8370
8318
  var decodeRead2 = decodeUnknownSync(ReadBoardInput);
8371
- var decodeCreate = decodeUnknownOption2(CreateItemInput);
8372
- var decodeUpdate = decodeUnknownOption2(UpdateItemInput);
8373
8319
  function registerBoardCommands(ctx, goals, rosters, wakes, options = {}) {
8374
8320
  const hasMember = async (projectId, threadIds) => {
8375
8321
  const members = (await goals.allOf(projectId)).flatMap((goal) => goalExecution(goal).members);
@@ -8395,11 +8341,6 @@ function registerBoardCommands(ctx, goals, rosters, wakes, options = {}) {
8395
8341
  goal: read !== null && workLineId !== void 0 && read.workLineId !== workLineId ? null : read
8396
8342
  };
8397
8343
  };
8398
- const memberUnavailable = (result2) => {
8399
- const details = result2.details;
8400
- const field = (key) => typeof details === "object" && details !== null ? Reflect.get(details, key) : void 0;
8401
- return result2.code === "not-found" && field("entity") === "member" || result2.code === "not-permitted" && field("reason") === "invalid-state" ? { ...result2, code: "member-unavailable" } : result2;
8402
- };
8403
8344
  ctx.command({
8404
8345
  name: "board",
8405
8346
  scope: "read",
@@ -8411,7 +8352,7 @@ function registerBoardCommands(ctx, goals, rosters, wakes, options = {}) {
8411
8352
  { goal, roster, members, aliases },
8412
8353
  toolkitStates,
8413
8354
  people,
8414
- remoteAgents,
8355
+ machines,
8415
8356
  viewer,
8416
8357
  lines,
8417
8358
  everyGoal
@@ -8422,11 +8363,8 @@ function registerBoardCommands(ctx, goals, rosters, wakes, options = {}) {
8422
8363
  ctx.projects.toolkits.get({ projectId }),
8423
8364
  // 人名只用来显示作者;本机所有者排第一,后面是这个项目认识的账号。
8424
8365
  readPages(PEOPLE_LIMIT, (page) => ctx.communication.people.list({ projectId, ...page })),
8425
- // 主体目录只用于名字与选择器;任何一页读失败都退回空目录,不连累看板。
8426
- readPages(
8427
- REMOTE_AGENT_LIMIT,
8428
- (page) => ctx.auth.remoteAgents.list({ projectId, ...page })
8429
- ).catch(() => null),
8366
+ // 项目里的别的机器:远端作者(那台机器上的 agent)的名字与在线状态;读不出来退回空,不连累看板。
8367
+ readMachines(ctx, projectId),
8430
8368
  // 认出当前读者只为把作者显示成「你」:读不出来就当没有,不连累整张看板。
8431
8369
  invocation.viewer?.communication.people.current({}).catch(() => null),
8432
8370
  // 团队层只核这条线还在(读不到照抛,界面显示读取失败);项目层要全部线(含已归档)来分道,线不设上限。
@@ -8455,9 +8393,15 @@ function registerBoardCommands(ctx, goals, rosters, wakes, options = {}) {
8455
8393
  (roster?.members ?? []).flatMap(
8456
8394
  (member) => member.principal === void 0 ? [] : [
8457
8395
  ctx.work.remoteAgentPending.get({ projectId, principalId: member.principal.principalId }).then(
8458
- ({ work }) => ({ count: work.count, items: work.items }),
8396
+ // 一台机器上可能有好几个成员:只算派给这个成员的(与直接派给那台机器的)。
8397
+ ({ work }) => {
8398
+ const items2 = work.items.filter(
8399
+ (item) => item.memberId === void 0 || item.memberId === member.memberId
8400
+ ).map(({ workItemId, blocked }) => ({ workItemId, blocked }));
8401
+ return { count: items2.length, items: items2 };
8402
+ },
8459
8403
  () => null
8460
- ).then((pending) => ({ principalId: member.principal.principalId, pending }))
8404
+ ).then((pending) => ({ memberId: member.memberId, pending }))
8461
8405
  ]
8462
8406
  )
8463
8407
  ),
@@ -8560,14 +8504,14 @@ function registerBoardCommands(ctx, goals, rosters, wakes, options = {}) {
8560
8504
  }))
8561
8505
  },
8562
8506
  ...roster?.aliases === void 0 ? {} : { rosterAliases: roster.aliases },
8563
- // 读不出来时记一笔,添加菜单要说「读不出来」而不是「还没有」。
8564
- ...remoteAgents === null ? { remoteAgentsUnavailable: true } : {},
8565
- remoteAgents: (remoteAgents?.items ?? []).map(
8566
- ({ principalId, label: label2, state, lastUsedAt }) => ({
8507
+ ...machines === null ? { machinesUnavailable: true } : {},
8508
+ machines: [...machines?.values() ?? []].map(
8509
+ ({ principalId, environmentId, name, online, lastSeenAt }) => ({
8567
8510
  principalId,
8568
- label: label2,
8569
- state,
8570
- ...lastUsedAt === void 0 ? {} : { lastUsedAt }
8511
+ environmentId,
8512
+ name,
8513
+ online,
8514
+ ...lastSeenAt === void 0 ? {} : { lastSeenAt }
8571
8515
  })
8572
8516
  ),
8573
8517
  remoteWork,
@@ -8577,289 +8521,9 @@ function registerBoardCommands(ctx, goals, rosters, wakes, options = {}) {
8577
8521
  };
8578
8522
  }
8579
8523
  });
8580
- ctx.command({
8581
- name: "createItem",
8582
- scope: "operate",
8583
- payloadSchema: payloadSchemaOf(CreateItemInput),
8584
- handle: async (payload, invocation) => {
8585
- const decoded = decodeCreate(payload);
8586
- if (isNone2(decoded)) return rejectWork("createItem", "invalid-payload");
8587
- const input = decoded.value;
8588
- if (input.title.trim().length === 0) return rejectWork("createItem", "invalid-title");
8589
- const result2 = await writeWork(
8590
- invocation,
8591
- "createItem",
8592
- (work) => work.items.create({
8593
- projectId: input.projectId,
8594
- title: input.title.trim(),
8595
- requestId: input.requestId,
8596
- ...input.description === void 0 ? {} : { description: input.description },
8597
- ...input.workLineId === void 0 ? {} : { workLineId: input.workLineId },
8598
- ...input.assigneeMemberId === void 0 ? {} : { assignees: [{ kind: "member", memberId: input.assigneeMemberId }] }
8599
- })
8600
- );
8601
- return "code" in result2 ? memberUnavailable(result2) : { workItemId: result2.result.workItemId };
8602
- }
8603
- });
8604
- ctx.command({
8605
- name: "updateItem",
8606
- scope: "operate",
8607
- payloadSchema: payloadSchemaOf(UpdateItemInput),
8608
- handle: async (payload, invocation) => {
8609
- const decoded = decodeUpdate(payload);
8610
- if (isNone2(decoded)) return rejectWork("updateItem", "invalid-payload");
8611
- const input = decoded.value;
8612
- if (input.unassign === true && input.assigneeMemberId !== void 0) {
8613
- return rejectWork("updateItem", "invalid-payload");
8614
- }
8615
- const result2 = await writeWork(
8616
- invocation,
8617
- "updateItem",
8618
- (work) => work.items.update({
8619
- projectId: input.projectId,
8620
- workItemId: input.workItemId,
8621
- expectedVersion: input.expectedVersion,
8622
- ...input.stateId === void 0 ? {} : { stateId: input.stateId },
8623
- ...input.unassign === true ? { assignees: [] } : input.assigneeMemberId === void 0 ? {} : { assignees: [{ kind: "member", memberId: input.assigneeMemberId }] }
8624
- })
8625
- );
8626
- return "code" in result2 ? memberUnavailable(result2) : { workItemId: result2.result.workItemId, version: result2.result.version };
8627
- }
8628
- });
8629
8524
  registerTeamWatch(ctx, hasMember, options);
8630
8525
  }
8631
8526
 
8632
- // src/detailContracts.ts
8633
- var ReadItemDetailInput = Struct({
8634
- projectId: String4,
8635
- workItemId: String4
8636
- });
8637
- var commentText = (raw) => {
8638
- const text = raw.trim();
8639
- return text.length >= 1 && text.length <= 8e3 ? text : null;
8640
- };
8641
- var PostCommentInput = Struct({
8642
- projectId: String4,
8643
- workItemId: String4,
8644
- body: String4,
8645
- parentId: optionalKey2(String4),
8646
- mentions: optionalKey2(
8647
- ArraySchema(
8648
- Struct({
8649
- threadId: optionalKey2(String4),
8650
- principalId: optionalKey2(String4)
8651
- })
8652
- )
8653
- ),
8654
- requestId: String4
8655
- });
8656
- var mentionPrincipal = (mention) => mention.threadId !== void 0 ? mention.principalId === void 0 ? { kind: "agent", threadId: mention.threadId } : null : mention.principalId !== void 0 ? { kind: "remote-agent", principalId: mention.principalId } : null;
8657
- var PostCommentResult = Union2([
8658
- Struct({ commentId: String4 }),
8659
- BoardRejection
8660
- ]);
8661
- var DetailComment = Struct({
8662
- commentId: String4,
8663
- author: WorkIdentity,
8664
- mentions: optionalKey2(ArraySchema(WorkIdentity)),
8665
- body: NullOr(String4),
8666
- parentId: NullOr(String4),
8667
- createdAt: String4
8668
- });
8669
- var DetailActivity = Struct({
8670
- sequence: Number5,
8671
- actor: WorkIdentity,
8672
- /** 经哪个插件代人写的;作者仍是人,没有来源的活动省略。 */
8673
- viaPlugin: optionalKey2(String4),
8674
- at: String4,
8675
- verb: String4,
8676
- // old/new 随 field 变化;正文变化只映射修订号,指派对象仍用开放的 kind。
8677
- changes: ArraySchema(
8678
- Struct({ field: String4, old: Unknown2, new: Unknown2 })
8679
- )
8680
- });
8681
- var Dependency = Struct({
8682
- workItemId: String4,
8683
- sequenceId: Number5,
8684
- title: NullOr(String4),
8685
- stateId: String4,
8686
- stateName: String4
8687
- });
8688
- var ItemDetailSnapshot = Struct({
8689
- // 这件的指派和历史里出现过的项目成员的名字(含人和已移除的);没有成员、或读不出来就省略。
8690
- memberNames: optionalKey2(ArraySchema(MemberName)),
8691
- item: Struct({
8692
- workItemId: String4,
8693
- sequenceId: Number5,
8694
- title: NullOr(String4),
8695
- description: NullOr(String4),
8696
- state: Struct({ stateId: String4, name: String4 }),
8697
- assignees: ArraySchema(WorkIdentity),
8698
- version: Number5
8699
- }),
8700
- blockedBy: ArraySchema(Dependency),
8701
- blocking: ArraySchema(Dependency),
8702
- comments: ArraySchema(DetailComment),
8703
- commentsTruncated: Boolean3,
8704
- history: ArraySchema(DetailActivity),
8705
- historyTruncated: Boolean3
8706
- });
8707
- var ReadItemDetailResult = NullOr(ItemDetailSnapshot);
8708
-
8709
- // src/detail.ts
8710
- var RELATION_LIMIT = 100;
8711
- var COMMENT_LIMIT = 200;
8712
- var HISTORY_LIMIT = 200;
8713
- var GET_BATCH_SIZE = 50;
8714
- var decodeRead3 = decodeUnknownSync(ReadItemDetailInput);
8715
- var decodePost = decodeUnknownOption2(PostCommentInput);
8716
- function registerDetailCommands(ctx, goals, rosters) {
8717
- ctx.command({
8718
- name: "itemDetail",
8719
- scope: "read",
8720
- payloadSchema: payloadSchemaOf(ReadItemDetailInput),
8721
- handle: async (payload) => {
8722
- const { projectId, workItemId } = decodeRead3(payload);
8723
- const result2 = await ctx.work.items.get({ projectId, workItemIds: [workItemId] });
8724
- const item = result2.items.find((row) => row.workItemId === workItemId);
8725
- if (item === void 0) return null;
8726
- const base = { projectId, workItemId };
8727
- const relations = (type) => readPages(
8728
- RELATION_LIMIT,
8729
- (page) => ctx.work.relations.list({ ...base, types: [type], ...page })
8730
- );
8731
- const [blockedBy, blocking, comments, history] = await Promise.all([
8732
- relations("blocked_by"),
8733
- relations("blocking"),
8734
- // 评论与历史宿主按旧到新给;留最近的,刚发生的提问和动作不能被挤掉。
8735
- readPages(COMMENT_LIMIT, (page) => ctx.work.comments.list({ ...base, ...page }), "newest"),
8736
- readPages(HISTORY_LIMIT, (page) => ctx.work.history.list({ ...base, ...page }), "newest")
8737
- ]);
8738
- const relatedIds = [
8739
- ...new Set([...blockedBy.items, ...blocking.items].map((row) => row.workItemId))
8740
- ];
8741
- const related = /* @__PURE__ */ new Map();
8742
- for (let offset = 0; offset < relatedIds.length; offset += GET_BATCH_SIZE) {
8743
- const page = await ctx.work.items.get({
8744
- projectId,
8745
- workItemIds: relatedIds.slice(offset, offset + GET_BATCH_SIZE)
8746
- });
8747
- for (const row of page.items) {
8748
- related.set(row.workItemId, {
8749
- workItemId: row.workItemId,
8750
- sequenceId: row.sequenceId,
8751
- title: row.bodyState === "present" ? row.title : null,
8752
- stateId: row.state.stateId,
8753
- stateName: row.state.name
8754
- });
8755
- }
8756
- }
8757
- const assignedMembers = /* @__PURE__ */ new Set();
8758
- const collect = (people) => {
8759
- for (const who of people)
8760
- if (who.kind === "member" && who.memberId !== void 0)
8761
- assignedMembers.add(who.memberId);
8762
- };
8763
- collect(item.assignees);
8764
- for (const activity of history.items)
8765
- for (const change of activity.changes)
8766
- if (change.field === "assignees" || change.field === "mentions") {
8767
- collect(change.old);
8768
- collect(change.new);
8769
- }
8770
- const memberNames = assignedMembers.size === 0 ? [] : await rosters.memberNames(projectId, [...assignedMembers]).catch(() => []);
8771
- const dependencies = (rows) => rows.flatMap((row) => {
8772
- const other = related.get(row.workItemId);
8773
- return other === void 0 ? [] : [other];
8774
- });
8775
- return {
8776
- ...memberNames.length === 0 ? {} : { memberNames },
8777
- item: {
8778
- workItemId: item.workItemId,
8779
- sequenceId: item.sequenceId,
8780
- title: item.bodyState === "present" ? item.title : null,
8781
- description: item.bodyState === "present" ? item.description : null,
8782
- state: { stateId: item.state.stateId, name: item.state.name },
8783
- assignees: item.assignees.map(workIdentity),
8784
- version: item.version
8785
- },
8786
- blockedBy: dependencies(blockedBy.items),
8787
- blocking: dependencies(blocking.items),
8788
- comments: comments.items.map((comment) => ({
8789
- commentId: comment.commentId,
8790
- author: workIdentity(comment.author),
8791
- mentions: comment.mentions.map(workIdentity),
8792
- body: comment.bodyState === "present" ? comment.body : null,
8793
- parentId: comment.parentId,
8794
- createdAt: comment.createdAt
8795
- })).sort((a, b) => a.createdAt.localeCompare(b.createdAt)),
8796
- commentsTruncated: comments.truncated,
8797
- history: history.items.map((activity) => ({
8798
- sequence: activity.sequence,
8799
- actor: workIdentity(activity.actor),
8800
- ...activity.viaPlugin === void 0 ? {} : { viaPlugin: activity.viaPlugin },
8801
- at: activity.at,
8802
- verb: activity.verb,
8803
- // 工作线自己的成员组变化只有加、减两批,没有前后值,也不会出现在一件工作项的历史里:不转。
8804
- changes: activity.changes.filter((change) => change.field !== "members").map((change) => {
8805
- if ("oldRevision" in change) {
8806
- return { field: change.field, old: change.oldRevision, new: change.newRevision };
8807
- }
8808
- if (change.field === "assignees" || change.field === "mentions") {
8809
- return {
8810
- field: change.field,
8811
- old: change.old.map(workIdentity),
8812
- new: change.new.map(workIdentity)
8813
- };
8814
- }
8815
- if (change.field === "state") {
8816
- return {
8817
- field: change.field,
8818
- old: change.old === null ? null : { stateId: change.old.stateId },
8819
- new: change.new === null ? null : { stateId: change.new.stateId }
8820
- };
8821
- }
8822
- return { field: change.field, old: change.old, new: change.new };
8823
- })
8824
- })),
8825
- historyTruncated: history.truncated
8826
- };
8827
- }
8828
- });
8829
- ctx.command({
8830
- name: "postComment",
8831
- scope: "operate",
8832
- payloadSchema: payloadSchemaOf(PostCommentInput),
8833
- handle: async (payload, invocation) => {
8834
- const decoded = decodePost(payload);
8835
- if (isNone2(decoded)) return rejectWork("postComment", "invalid-payload");
8836
- const { mentions, ...input } = decoded.value;
8837
- const body = commentText(input.body);
8838
- if (body === null) return rejectWork("postComment", "invalid-body");
8839
- const principals = mentions?.flatMap((mention) => mentionPrincipal(mention) ?? []);
8840
- if (principals?.length !== mentions?.length)
8841
- return rejectWork("postComment", "invalid-payload");
8842
- if (principals !== void 0 && principals.length > 0) {
8843
- const members = (await goals.allOf(input.projectId)).flatMap(
8844
- (goal) => goalExecution(goal).members
8845
- );
8846
- if (principals.some((principal) => findGoalMember(members, principal) === void 0))
8847
- return rejectWork("postComment", "not-a-member");
8848
- }
8849
- const result2 = await writeWork(
8850
- invocation,
8851
- "postComment",
8852
- (work) => work.comments.post({
8853
- ...input,
8854
- body,
8855
- ...principals === void 0 ? {} : { mentions: principals }
8856
- })
8857
- );
8858
- return "code" in result2 ? result2 : { commentId: result2.result.commentId };
8859
- }
8860
- });
8861
- }
8862
-
8863
8527
  // src/runtime/serial.ts
8864
8528
  function createSerial(closedMessage = "team-serial-closed") {
8865
8529
  let pending = Promise.resolve();
@@ -8885,7 +8549,7 @@ function createSerial(closedMessage = "team-serial-closed") {
8885
8549
  }
8886
8550
 
8887
8551
  // src/domain/service.ts
8888
- var HISTORY_LIMIT2 = 500;
8552
+ var HISTORY_LIMIT = 500;
8889
8553
  var ACTIVE_LIMIT = 2e3;
8890
8554
  var MEMBER_NAMES_LIMIT = 50;
8891
8555
  var FactEnvelope = Struct({
@@ -8910,7 +8574,7 @@ async function listMembers(ctx, projectId) {
8910
8574
  }
8911
8575
  async function listMemberHistory(ctx, projectId) {
8912
8576
  const { items } = await readPages(
8913
- HISTORY_LIMIT2,
8577
+ HISTORY_LIMIT,
8914
8578
  (page) => ctx.members.list({ projectId, includeRemoved: true, ...page }),
8915
8579
  "newest"
8916
8580
  );
@@ -8927,18 +8591,23 @@ async function findMember(ctx, projectId, memberId, window) {
8927
8591
  }
8928
8592
  }
8929
8593
  var isActiveAgent = (member) => member.kind === "agent" && member.removedAt === null;
8930
- var toTeamMember = (member) => ({
8931
- memberId: member.memberId,
8932
- name: member.name,
8933
- ...member.identity?.kind === "remote-agent" ? { principal: { kind: "remote-agent", principalId: member.identity.principalId } } : {}
8934
- });
8935
- function resolveTeam(stored, members) {
8594
+ var toTeamMember = (member, where) => {
8595
+ if (!isRemoteMember(member, where.local)) return { memberId: member.memberId, name: member.name };
8596
+ const machine = member.agent === null ? void 0 : where.machines?.get(member.agent.environmentId);
8597
+ return {
8598
+ memberId: member.memberId,
8599
+ name: member.name,
8600
+ remote: true,
8601
+ ...machine === void 0 ? {} : { principal: { kind: "remote-agent", principalId: machine.principalId } }
8602
+ };
8603
+ };
8604
+ function resolveTeam(stored, members, where) {
8936
8605
  if (stored === null) return { team: null, problem: null };
8937
8606
  if (stored.version === 1) return { team: stored.roster, problem: null };
8938
8607
  const { roster: lead } = stored;
8939
8608
  const team = {
8940
8609
  projectId: lead.projectId,
8941
- members: members.filter(isActiveAgent).map(toTeamMember),
8610
+ members: members.filter(isActiveAgent).map((member) => toTeamMember(member, where)),
8942
8611
  leadMemberId: lead.leadMemberId,
8943
8612
  revision: lead.revision,
8944
8613
  updatedAt: lead.updatedAt,
@@ -8957,9 +8626,17 @@ function createRosterService(ctx, options = {}) {
8957
8626
  });
8958
8627
  const now3 = options.now ?? factTime;
8959
8628
  const storedOf = async (projectId) => readFact(await rosters.get(), projectId);
8629
+ const machinesOf = async (projectId) => ({
8630
+ local: ctx.environment.id,
8631
+ machines: await readMachines(ctx, projectId)
8632
+ });
8960
8633
  const activeView = async (projectId) => {
8961
- const [stored, active] = await Promise.all([storedOf(projectId), listMembers(ctx, projectId)]);
8962
- return { stored, active, ...resolveTeam(stored, active) };
8634
+ const [stored, active, where] = await Promise.all([
8635
+ storedOf(projectId),
8636
+ listMembers(ctx, projectId),
8637
+ machinesOf(projectId)
8638
+ ]);
8639
+ return { stored, active, machines: where.machines, ...resolveTeam(stored, active, where) };
8963
8640
  };
8964
8641
  const inspect = async (projectId) => {
8965
8642
  const [view, history] = await Promise.all([
@@ -8984,8 +8661,8 @@ function createRosterService(ctx, options = {}) {
8984
8661
  const stored = await storedOf(projectId);
8985
8662
  if (stored === null) return { team: null };
8986
8663
  if (stored.version === 1) return { team: stored.roster };
8987
- const active = await listMembers(ctx, projectId);
8988
- return { team: resolveTeam(stored, active).team, active };
8664
+ const [active, where] = await Promise.all([listMembers(ctx, projectId), machinesOf(projectId)]);
8665
+ return { team: resolveTeam(stored, active, where).team, active };
8989
8666
  };
8990
8667
  const read = async (projectId) => (await readTeam(projectId)).team;
8991
8668
  const append2 = async (projectId, expectedRevision, lead) => {
@@ -9018,7 +8695,7 @@ function createRosterService(ctx, options = {}) {
9018
8695
  if (expectedRevision !== (stored?.roster.revision ?? 0)) return rejectRoster("stale-revision");
9019
8696
  const lead = active.find((member) => member.memberId === leadMemberId);
9020
8697
  if (lead === void 0 || !isActiveAgent(lead)) return rejectRoster("lead-not-member");
9021
- if (lead.identity?.kind === "remote-agent") return rejectRoster("lead-remote");
8698
+ if (isRemoteMember(lead, ctx.environment.id)) return rejectRoster("lead-remote");
9022
8699
  return append2(projectId, expectedRevision, {
9023
8700
  leadMemberId,
9024
8701
  ...stored?.roster.aliases === void 0 ? {} : { aliases: stored.roster.aliases }
@@ -9288,16 +8965,15 @@ var specKeyOf = (spec) => stableHash(
9288
8965
  JSON.stringify([
9289
8966
  spec.environmentId ?? null,
9290
8967
  canonical(spec.modelSelection ?? null),
9291
- canonical(spec.identity ?? null)
8968
+ // 第三格原是主体(合一之前按远端主体记的成员才有),留着空位让本机成员的旧键不变。
8969
+ null
9292
8970
  ])
9293
8971
  );
9294
8972
  var specOfMember = (member) => ({
9295
8973
  environmentId: member.agent?.environmentId ?? null,
9296
- modelSelection: member.agent?.modelSelection ?? null,
9297
- identity: member.identity ?? null
8974
+ modelSelection: member.agent?.modelSelection ?? null
9298
8975
  });
9299
8976
  var trialIdOf = (projectId, memberId, specKey, attempt) => `team-trial:${stableHash(JSON.stringify([projectId, memberId, specKey, attempt]))}`;
9300
- var remotePrincipalOf = (identity2) => typeof identity2 === "object" && identity2 !== null && "kind" in identity2 && identity2.kind === "remote-agent" && "principalId" in identity2 && typeof identity2.principalId === "string" ? identity2.principalId : null;
9301
8977
 
9302
8978
  // src/domain/defaultModel.ts
9303
8979
  var isSelectionUnavailable = isTagged("ProviderSelectionError");
@@ -9354,7 +9030,7 @@ var en_default = {
9354
9030
  handbook: {
9355
9031
  requestConflict: "This requestId was already used for a different handbook request. Use a new requestId.",
9356
9032
  requestVoided: "This requestId was abandoned before the handbook received it. Use a new requestId.",
9357
- ackTool: "Acknowledge the currently required handbook release for your member seat in the current goal. Reading alone does not acknowledge it. Without a goal there are no team members, acknowledgement gates or reminders.",
9033
+ ackTool: "Acknowledge the currently required handbook release as a member of the current goal. Reading alone does not acknowledge it. Without a goal there are no team members, acknowledgement gates or reminders.",
9358
9034
  publishTool: "Publish handbook pages as the local team lead. Reuse requestId only for the same request. Rules changes require acknowledgement; for decisions changes choose requireAck (default false).",
9359
9035
  revertTool: "Restore a handbook release as the local team lead. Reuse requestId only for the same request. Rules changes require acknowledgement; for decisions changes choose requireAck (default false).",
9360
9036
  unknownMember: "Your verified caller identity is not mapped to a member of this project's current goal.",
@@ -9372,9 +9048,9 @@ var en_default = {
9372
9048
  leadBrief: "Read the handbook with wiki_read_handbook and explicitly acknowledge its currently required release with team_acknowledge_handbook before taking new work. Publish or revert it through team_publish_handbook or team_revert_handbook; publishing a release that requires acknowledgement also acknowledges it for you."
9373
9049
  },
9374
9050
  team: {
9375
- openTool: "Turn this conversation into a team. Call it only after the person has agreed, in this conversation, to the team you proposed: who joins (members already in the project, including agents on other machines you can see with work_list_remote_agents) and which new members you will create after the team is open. A member that does not exist yet comes after this call: create it with team_create_member, then add it with team_set_members. This conversation becomes the team's lead and its group chat and is renamed to the team's name: the members you list are added to it, and each local agent member gets its own conversation under yours. Pass a new requestId, and reuse it only to retry the same call. name is the team's name (at most 80 characters); goal is a summary of what was agreed (at most 4000 characters); memberIds are the memberIds of the project members to bring in (not yourself; you are added as the lead); leadName optionally names you as a project member (1-40 characters). The call returns the team's work line, the members and whether each one is ready, and your brief. A conversation that already is a team, or belongs to one, cannot open another.",
9051
+ openTool: "Turn this conversation into a team. Call it only after the person has agreed, in this conversation, to the team you proposed: who joins (members already in the project, including agents on the other machines that joined this project; work_list_machines lists those machines) and which new members you will create after the team is open. A member that does not exist yet comes after this call: create it with team_create_member, then add it with team_set_members. This conversation becomes the team's lead and its group chat and is renamed to the team's name: the members you list are added to it, and each local agent member gets its own conversation under yours. Pass a new requestId, and reuse it only to retry the same call. name is the team's name (at most 80 characters); goal is a summary of what was agreed (at most 4000 characters); memberIds are the memberIds of the project members to bring in (not yourself; you are added as the lead); leadName optionally names you as a project member (1-40 characters). The call returns the team's work line, the members and whether each one is ready, and your brief. A conversation that already is a team, or belongs to one, cannot open another.",
9376
9052
  setMembersTool: "Change who is on this team (only the team's lead conversation can). add: memberIds of project members to bring in; remove: memberIds to take out. Work assigned to a removed member that has not reached it yet is taken back and given to you; work already in their hands stays with them until you decide. You cannot remove yourself, and you cannot change members or leads of other teams. Pass a new requestId, and reuse it only to retry the same call.",
9377
- rosterOverviewTool: "Read everything you need to plan a team: every member of this project with their kind, machine, model, how their trial run stands (trial is none when no trial applies, such as a person; unverified for a remote agent whose machine you cannot test from here; pending until the trial passes; ready once it passed or was skipped; failed; invoked for the conversation that is itself the lead and needs no trial), and the teams they are in (with whether they lead it). Read it before you propose a team and before you create a member.",
9053
+ rosterOverviewTool: "Read everything you need to plan a team: every member of this project with their kind, machine, model, how their trial run stands (trial is none when no trial applies, such as a person; unverified for an agent on another machine with no trial record here; pending until the trial passes; ready once it passed or was skipped; failed; invoked for the conversation that is itself the lead and needs no trial), and the teams they are in (with whether they lead it). Read it before you propose a team and before you create a member.",
9378
9054
  noProject: "This call is not tied to a project, so there is no team to open or change.",
9379
9055
  notLocal: "Only a conversation on this machine can open a team.",
9380
9056
  invalidInput: "Check the arguments: requestId is 1-64 letters, digits, underscores or hyphens; name is 1-80 characters; goal is 1-4000 characters; leadName, if given, is 1-40 characters.",
@@ -9417,100 +9093,13 @@ var en_default = {
9417
9093
  cannotReplaceLead: "You cannot change your own provider or model."
9418
9094
  },
9419
9095
  board: {
9420
- title: "Project board",
9421
- newItem: "New work item",
9422
- itemTitle: "Title",
9423
- description: "Description (optional)",
9424
- assignee: "Assign to (optional)",
9425
- create: "Create work item",
9426
- retryCreate: "Retry creation",
9427
- saving: "Saving\u2026",
9428
- moveTo: "Move to\u2026",
9429
- goalItem: "Goal",
9430
- moveItem: "Move work item #{{number}}",
9431
- moveItemTo: "Move work item #{{number}} to {{state}}",
9432
- assignTo: "Assign to\u2026",
9433
- assignItem: "Assign work item #{{number}}",
9434
- assignItemTo: "Assign work item #{{number}} to {{name}}",
9435
- unassign: "Unassign",
9436
- unassignItem: "Unassign work item #{{number}}",
9437
- dragItem: "Drag work item #{{number}} to another state",
9438
- untitled: "(Untitled)",
9096
+ openTeam: "Open this team on the board",
9097
+ openProject: "Open board",
9439
9098
  other: "Other",
9440
- unassigned: "Unassigned",
9441
- sessionRunning: "Session running",
9442
- sessionFailed: "Failed",
9443
- sessionWaiting: "Needs input",
9444
- sessionStopped: "Stopped",
9445
- sessionStoppedAt: "Stopped at {{time}}",
9446
- queued: "Queued",
9447
- dateLocale: "en",
9448
- queuedTitle: "Assigned but not woken yet: waits until their current item is done",
9449
- blockedBy: "Blocked by {{count}} work items",
9450
- noMembers: "There are no members to assign to yet. Add one under Members.",
9451
- membersUnavailable: "Members could not be read, so work cannot be assigned right now. Try reloading the board.",
9452
- loading: "Loading board\u2026",
9453
- loadFailed: "The board could not be loaded. Try reloading it.",
9454
- watchFailed: "Live board updates are unavailable. Reload to reconnect.",
9455
- createFailed: "The work item could not be created. Retry with the same request.",
9456
- updateFailed: "The work item could not be changed. Reloading the board.",
9457
- staleVersion: "The work item was changed elsewhere. Your change was rolled back and the board is being reloaded.",
9458
- memberUnavailable: "That member was removed or no longer exists, so nothing was assigned. Choose another member.",
9459
- invalidTitle: "Enter a title for the work item.",
9460
- reload: "Reload board",
9461
- truncated: "Showing the first 500 work items in this project.",
9462
- teamTitle: "Team board",
9463
- lane: {
9464
- unlined: "No team",
9465
- archived: "Archived",
9466
- openTeam: "Open team",
9467
- openTeamFor: "Open team {{name}}"
9468
- },
9469
- noTeamHint: "To start a team, agree on the plan in a conversation; the agent opens the team from there."
9099
+ untitled: "(Untitled)"
9470
9100
  },
9471
9101
  detail: {
9472
- title: "Work item details",
9473
9102
  open: "Details",
9474
- openItem: "Open details for work item #{{number}}",
9475
- close: "Close",
9476
- via: "via {{source}}",
9477
- description: "Description",
9478
- noDescription: "(No description)",
9479
- blockedBy: "Blocked by these work items",
9480
- blocking: "Blocking these work items",
9481
- dependency: "#{{number}} {{title}}, {{state}}",
9482
- comments: "Comments",
9483
- noComments: "No comments yet.",
9484
- deletedComment: "(This comment has been deleted)",
9485
- commentsTruncated: "Showing the latest 200 comments, including replies.",
9486
- reply: "Reply",
9487
- replyTo: "Reply to comment {{number}}",
9488
- newComment: "Post a comment",
9489
- commentHint: "To wake a member, choose it under Mention\u2026 (or type @), or choose Reply under its comment. Commenting on an open work item assigned to a remote member also wakes it.",
9490
- mention: "Mention\u2026",
9491
- mentionLabel: "Mention a member \u2014 {{comment}}",
9492
- mentionMember: "Mention {{name}} \u2014 {{comment}}",
9493
- mentionMemberSelected: "{{name}} (mentioned) \u2014 {{comment}}",
9494
- mentionSelected: "{{name}} (mentioned)",
9495
- mentionRemove: "Remove mention of {{name}} \u2014 {{comment}}",
9496
- mentionNone: "Start a goal to mention members.",
9497
- mentionNoneLabel: "Start a goal to mention members \u2014 {{comment}}",
9498
- mentioned: "Mentioned: {{names}}",
9499
- mentionSeparator: ", ",
9500
- notAMember: "One of the mentioned members is not in the current goal. Remove it and try again.",
9501
- send: "Send",
9502
- sendComment: "Send comment",
9503
- sendReply: "Send reply to comment {{number}}",
9504
- sending: "Sending\u2026",
9505
- retry: "Retry",
9506
- retryComment: "Retry comment",
9507
- retryReply: "Retry reply to comment {{number}}",
9508
- invalidBody: "The comment must be 1\u20138000 characters after trimming spaces.",
9509
- commentFailed: "The comment couldn't be posted. Try again.",
9510
- loading: "Loading work item details\u2026",
9511
- loadFailed: "The work item details could not be loaded. Try reloading them.",
9512
- reload: "Reload details",
9513
- notFound: "This work item was not found in this project.",
9514
9103
  actor: {
9515
9104
  you: "You",
9516
9105
  human: "A person",
@@ -9519,24 +9108,7 @@ var en_default = {
9519
9108
  plugin: "Plugin {{pluginId}}",
9520
9109
  localCli: "Local command line",
9521
9110
  system: "System",
9522
- remoteAgentFallback: "Remote agent"
9523
- },
9524
- history: {
9525
- title: "Activity history",
9526
- empty: "No activity yet.",
9527
- truncated: "Showing the latest 200 activities.",
9528
- deletedState: "(Deleted state)",
9529
- created: "{{author}} created this work item",
9530
- createdAssigned: "{{author}} created this work item and assigned it to {{names}}",
9531
- stateChanged: "{{author}} changed the state from {{old}} to {{new}}",
9532
- assigned: "{{author}} assigned this work item to {{names}}",
9533
- unassigned: "{{author}} removed the assignment",
9534
- titleChanged: "{{author}} changed the title",
9535
- descriptionChanged: "{{author}} changed the description",
9536
- claimed: "{{author}} claimed this work item",
9537
- commented: "{{author}} posted a comment",
9538
- relationAdded: "{{author}} added a dependency",
9539
- relationRemoved: "{{author}} removed a dependency"
9111
+ remoteAgentFallback: "Another machine"
9540
9112
  }
9541
9113
  },
9542
9114
  goal: {
@@ -9544,7 +9116,7 @@ var en_default = {
9544
9116
  lead: "Lead: {{name}}",
9545
9117
  unknownLead: "This member is no longer on the team",
9546
9118
  openLead: "Open lead thread",
9547
- remoteMembers: "Remote members:",
9119
+ remoteMembers: "Members on other machines:",
9548
9120
  item: "Goal work item #{{number}}: {{state}}",
9549
9121
  openItem: "Open details for goal work item #{{number}}"
9550
9122
  },
@@ -9571,7 +9143,6 @@ var en_default = {
9571
9143
  makeLeadFor: "Make {{name}} the lead",
9572
9144
  person: "Person",
9573
9145
  agent: "Agent",
9574
- remote: "Remote agent",
9575
9146
  edit: "Edit",
9576
9147
  editFor: "Edit {{name}}",
9577
9148
  remove: "Remove",
@@ -9589,8 +9160,7 @@ var en_default = {
9589
9160
  restoredNotice: "Member restored.",
9590
9161
  leadChosen: "Lead chosen.",
9591
9162
  kind: "Type",
9592
- kindAgentHint: "Runs with the provider and model you pick when the machine is this one. A member set to another machine fails its trial run: set it back to this machine, or skip the trial run, and it runs on this machine with the project's default model.",
9593
- kindRemoteHint: "An agent that connects from another machine with its own credentials.",
9163
+ kindAgentHint: "Runs on the machine you pick, with that machine's provider and model. Other machines appear here after they join this project.",
9594
9164
  kindPersonHint: "People are listed as members but do not run sessions.",
9595
9165
  thisIsMe: "This is me",
9596
9166
  thisIsMeHint: "When someone @-mentions this member in a team group, the message goes to your Sent to me.",
@@ -9619,20 +9189,14 @@ var en_default = {
9619
9189
  providersFailed: "The providers on this machine could not be read.",
9620
9190
  noProviders: "This machine has no provider that is ready to use.",
9621
9191
  modelsFailed: "The models of this provider could not be read.",
9622
- remoteAgent: "Remote agent",
9623
- chooseRemote: "Choose a remote agent",
9624
- remoteBound: "Remote agent: {{label}}",
9625
- noRemoteAgents: "There are no available remote agents on this machine yet.",
9626
- allRemoteAgentsAdded: "All available remote agents are already members.",
9627
- remoteAgentsUnavailable: "Could not read the remote agents on this machine. Try again later.",
9628
9192
  save: "Save",
9629
9193
  saving: "Saving\u2026",
9630
9194
  adding: "Adding\u2026",
9631
9195
  problem: {
9632
9196
  memberCount: "A team needs at least one agent member.",
9633
9197
  leadNotMember: "Choose a lead from the agent members.",
9634
- leadRemote: "The lead must be a local member.",
9635
- duplicatePrincipal: "Each remote agent can be a member only once."
9198
+ leadRemote: "The lead must run on this machine.",
9199
+ duplicatePrincipal: "A machine can appear only once in this team list."
9636
9200
  },
9637
9201
  errors: {
9638
9202
  generic: "The change could not be saved. Try again.",
@@ -9643,7 +9207,7 @@ var en_default = {
9643
9207
  instanceNotFound: "The project's default model belongs to a provider instance that does not exist on this machine. Choose another model in the project settings under New threads \u2192 Model.",
9644
9208
  instanceUnavailable: "The provider instance of the project's default model is turned off or cannot run on this machine. Check the provider, or choose another model in the project settings under New threads \u2192 Model.",
9645
9209
  modelNotInCatalog: "The project's default model is not in its provider instance's model list. Choose another model in the project settings under New threads \u2192 Model.",
9646
- duplicateMember: "Another member already has this name or remote agent. Rename or remove that member first.",
9210
+ duplicateMember: "Another member already has this name or stands for this person. Rename or remove that member first.",
9647
9211
  alreadyYou: "You are already {{name}} on this roster. Clear \u201CThis is me\u201D on {{name}} first.",
9648
9212
  staleVersion: "This member was changed elsewhere and has been reloaded. Review it and save again.",
9649
9213
  notFound: "This member no longer exists.",
@@ -9656,9 +9220,9 @@ var en_default = {
9656
9220
  importDuplicate: "A member named {{name}} already exists, so the import stopped. Rename or remove it, then import again.",
9657
9221
  importResume: "Members already added are kept. Import again to continue.",
9658
9222
  nameRequired: "Enter a name.",
9659
- remoteRequired: "Choose a remote agent.",
9660
9223
  modelRequired: "Choose a provider and a model.",
9661
- instructionsTooLong: "The work instructions are too long."
9224
+ instructionsTooLong: "The work instructions are too long.",
9225
+ machineMissing: "The machine that {{memberName}} ran on has not joined this project. Add that machine to the project, then import again."
9662
9226
  },
9663
9227
  legacy: {
9664
9228
  title: "This project still uses an older roster",
@@ -9671,7 +9235,7 @@ var en_default = {
9671
9235
  trial: {
9672
9236
  passed: "Trial passed",
9673
9237
  skipped: "Trial skipped",
9674
- remoteVerified: "Remote connection verified",
9238
+ remoteVerified: "Verified on its machine",
9675
9239
  invoked: "Lead conversation, no trial needed",
9676
9240
  pending: "Trial run pending",
9677
9241
  running: "Trial run in progress",
@@ -9679,7 +9243,7 @@ var en_default = {
9679
9243
  failed: "Trial run failed",
9680
9244
  waiting: "Waiting for the other side to pick it up.",
9681
9245
  waitingSeen: "Waiting for the other side to pick it up (last seen {{time}}).",
9682
- remoteNote: "A remote agent runs with its own seat's settings; the trial run only checked the connection and the tool calls.",
9246
+ remoteNote: "The trial ran on its own machine with the model chosen for it: it checked the connection, the tool calls and the handbook.",
9683
9247
  failedDetail: "Reason: {{category}}",
9684
9248
  failedWithText: "Reason: {{category}} ({{detail}})",
9685
9249
  failedSummary: "Trial run failed: {{count}}",
@@ -9701,15 +9265,18 @@ var en_default = {
9701
9265
  transport: "the connection dropped",
9702
9266
  unknown: "an unclassified error",
9703
9267
  timeout: "it did not report back in time",
9704
- "no-route": "there is no usable machine or remote credential for it; reconnect the remote agent, or choose a machine for the member, then retry",
9705
- "other-machine": "it is set to another machine, which this machine cannot run a trial for; set it back to this machine, or skip the trial run to run it here with the project's default model",
9268
+ "no-route": "the machine it runs on has not joined this project; add that machine to the project, or choose another machine for the member, then retry",
9706
9269
  "start-failed": "the trial run could not be started",
9707
9270
  "toolkit-off": "the board and project memory switches are not both on; turn them on, then retry"
9708
9271
  }
9709
9272
  },
9710
9273
  teams: "Teams: {{names}}",
9711
9274
  remoteApprovals: "Approvals are handled on their machine",
9712
- teamsSeparator: ", "
9275
+ teamsSeparator: ", ",
9276
+ thisMachine: "This machine",
9277
+ machineOffline: "{{name}} (offline)",
9278
+ machineRemoved: "A machine that left this project",
9279
+ noMachine: "No machine chosen"
9713
9280
  },
9714
9281
  handbookPanel: {
9715
9282
  title: "Handbook",
@@ -9770,21 +9337,20 @@ var en_default = {
9770
9337
  discard: "Discard edits"
9771
9338
  },
9772
9339
  remoteStatus: {
9773
- title: "Remote members",
9340
+ title: "Members on other machines",
9774
9341
  lastSeen: "Last seen {{time}}",
9775
9342
  neverSeen: "Not seen yet",
9776
9343
  workUnavailable: "Could not read this member's work. Try again later.",
9777
9344
  noWork: "No work assigned.",
9778
9345
  item: "#{{number}} {{title}}",
9779
- disabled: "Disabled",
9780
- revoked: "No active credentials",
9781
9346
  lastSeenUnavailable: "Could not read when it was last seen",
9782
9347
  blocked: "Blocked",
9783
- more: "{{count}} more not listed here"
9348
+ more: "{{count}} more not listed here",
9349
+ machineMissing: "Its machine has not joined this project"
9784
9350
  },
9785
9351
  trial: {
9786
9352
  localPrompt: `This is a trial run for you as a member of this project's team. It only checks that you can reach the team's tools and read its handbook, so do not change any file and do not start other work. Do exactly this, then stop. 1. Call wiki_read_handbook with no arguments. If it returns a head, note head.current.release (a number); if head is null, the project has no handbook yet. 2. Call team_trial_done with trialId "{{trialId}}", and with release set to the number you read when there is one (leave release out when head is null). Report only what you really read: a release you did not read is refused.`,
9787
- remotePrompt: `Trial run for you as a member of this project's team. It only checks that your seat can reach the team's tools and read its handbook, so do not start any work item for it. Do exactly this, then stop. 1. Call team_trial_started with trialId "{{trialId}}". 2. Call wiki_read_handbook with no arguments. If it returns a head, note head.current.release (a number); if head is null, the project has no handbook yet. 3. Call team_trial_done with trialId "{{trialId}}", and with release set to the number you read when there is one (leave release out when head is null). Report only what you really read: a release you did not read is refused.`,
9353
+ remotePrompt: `Trial run for you as a member of this project's team. It only checks that you can reach the team's tools and read its handbook, so do not start any work item for it. Do exactly this, then stop. 1. Call team_trial_started with trialId "{{trialId}}". 2. Call wiki_read_handbook with no arguments. If it returns a head, note head.current.release (a number); if head is null, the project has no handbook yet. 3. Call team_trial_done with trialId "{{trialId}}", and with release set to the number you read when there is one (leave release out when head is null). Report only what you really read: a release you did not read is refused.`,
9788
9354
  startedTool: "Report that you picked up a trial run. Use the trialId from the trial message. A trial run only checks that you can reach the team's tools and read its handbook.",
9789
9355
  doneTool: "Finish a trial run: report the handbook release you read with wiki_read_handbook (leave release out when the project has no handbook). Use the trialId from the trial message. The host checks who is calling; a report for a trial run that was replaced, ended, or was not sent to you is refused.",
9790
9356
  retryTool: "Ask for another trial run of an agent member, as the lead of the current goal, for example when its last trial run failed or never finished. A trial run that is already queued or running is left alone and you are told so. Changing the member's provider or model with team_update_member also starts a new trial run by itself.",
@@ -9801,7 +9367,7 @@ var en_default = {
9801
9367
  retryReady: "This member is ready: its trial run passed or a person skipped it, so there is nothing to retry. A new trial run starts by itself when you change its provider or model with team_update_member.",
9802
9368
  retryFutile: "Another trial run will not help here: this member's trial run failed {{limit}} times in a row with the same setup, or it failed in a way that only changes when something is changed. Change its provider or model with team_update_member, or write to a person with send_message, explaining what is wrong and asking them to fix it or to skip the trial run on the Teams page.",
9803
9369
  failedForLeadNoRetry: "Trial run failed for {{name}} (memberId {{memberId}}): {{reason}}. {{name}} gets no work until a trial run passes, and asking again will not help until something changes. You can: change their provider or model with team_update_member (a new trial run starts by itself); or write to a person with send_message, explaining what is wrong and asking them to fix it or to skip the trial run on the Teams page.",
9804
- waitingForLead: "The trial run for {{name}} (memberId {{memberId}}) was sent {{minutes}} minutes ago and the remote agent has not picked it up. {{name}} may be offline or signed out. Until it picks the trial run up, work assigned to {{name}} will not start. You can: assign the work to another member for now; or write to a person with send_message, so they can check that the remote agent is running or skip the trial run on the Teams page.",
9370
+ waitingForLead: "The trial run for {{name}} (memberId {{memberId}}) was sent {{minutes}} minutes ago and the machine it runs on has not picked it up. That machine may be offline, or its provider may be signed out. Until the trial run is picked up, work assigned to {{name}} will not start. You can: assign the work to another member for now; or write to a person with send_message, so they can check that machine or skip the trial run on the Teams page.",
9805
9371
  failedHeadline: "Trial run failed: {{name}}.",
9806
9372
  failedHeadlineAgain: "Trial run failed again: {{name}}.",
9807
9373
  failedForPerson: "{{reason}}. {{name}} gets no work until a trial run passes. Fix the cause, then choose Retry trial run for that member on the Teams page, or choose Skip trial run.",
@@ -9815,8 +9381,7 @@ var en_default = {
9815
9381
  transport: "the connection to the provider dropped",
9816
9382
  unknown: "an unclassified error",
9817
9383
  timeout: "it did not report back in time",
9818
- "no-route": "there is no usable machine or remote credential for it (a person has to reconnect the remote agent, or choose a machine for the member)",
9819
- "other-machine": "it is set to another machine, which this machine cannot run a trial for (a person can set it back to this machine, or skip the trial run so that it runs here with the project's default model)",
9384
+ "no-route": "the machine it runs on has not joined this project (a person has to add that machine to the project, or choose another machine for the member)",
9820
9385
  "start-failed": "the trial run could not be started",
9821
9386
  "toolkit-off": "the project's board and project memory switches are not both on"
9822
9387
  },
@@ -9890,7 +9455,7 @@ function leadBrief(goal, roster, options = {}) {
9890
9455
  });
9891
9456
  const remoteMembers = (goal.remoteMembers ?? []).map((member) => {
9892
9457
  const name = rosterMemberName(roster, member.memberId) ?? member.memberId;
9893
- return byMember ? `| ${tableCell(name)} | ${tableCell(member.memberId)} | remote-agent: ${tableCell(member.principalId)} |` : `| ${tableCell(name)} | remote-agent: ${tableCell(member.principalId)} |`;
9458
+ return byMember ? `| ${tableCell(name)} | ${tableCell(member.memberId)} | another machine |` : `| ${tableCell(name)} | remote-agent: ${tableCell(member.principalId)} |`;
9894
9459
  });
9895
9460
  const assign2 = memberAssignRule(byMember);
9896
9461
  return [
@@ -9899,7 +9464,7 @@ function leadBrief(goal, roster, options = {}) {
9899
9464
  handbookMessage("leadBrief"),
9900
9465
  "Team members and their assignment identities (your own conversation is omitted):",
9901
9466
  [
9902
- byMember ? "| Member | memberId | threadId / remote principalId |" : "| Member | threadId / remote principalId |",
9467
+ byMember ? "| Member | memberId | threadId / machine |" : "| Member | threadId / remote principalId |",
9903
9468
  byMember ? "| --- | --- | --- |" : "| --- | --- |",
9904
9469
  ...localMembers,
9905
9470
  ...remoteMembers
@@ -10215,8 +9780,6 @@ var MemberRow = Struct({
10215
9780
  title: String4,
10216
9781
  responsibility: String4,
10217
9782
  avatar: NullOr(MemberAvatar),
10218
- /** 远端 agent 成员绑的主体;本机 agent 与人是 null。 */
10219
- remotePrincipalId: NullOr(String4),
10220
9783
  /** 人成员绑着的人是不是正在看这一页的人;没绑就没有这一项。 */
10221
9784
  person: optionalKey2(Literals(["me", "other"])),
10222
9785
  agent: NullOr(
@@ -10244,8 +9807,24 @@ var LegacyOffer = Struct({
10244
9807
  })
10245
9808
  )
10246
9809
  });
9810
+ var MachineRow = Struct({
9811
+ environmentId: String4,
9812
+ name: String4,
9813
+ online: Boolean3,
9814
+ lastSeenAt: optionalKey2(String4),
9815
+ providers: ArraySchema(
9816
+ Struct({
9817
+ instanceId: String4,
9818
+ displayName: String4,
9819
+ models: ArraySchema(Struct({ slug: String4, name: String4 })),
9820
+ defaultModel: optionalKey2(String4)
9821
+ })
9822
+ )
9823
+ });
10247
9824
  var MembersSnapshot = Struct({
10248
9825
  members: ArraySchema(MemberRow),
9826
+ /** 项目里的别的机器;读不出来是 null(表单只给这台机器)。 */
9827
+ machines: NullOr(ArraySchema(MachineRow)),
10249
9828
  /** 存着的带队记录;旧名单与还没设过时 memberId 是 null。 */
10250
9829
  lead: Struct({ memberId: NullOr(String4), revision: Int }),
10251
9830
  /** 开目标能用的团队;成不了队时是 null,原因在 `problem`。 */
@@ -10271,8 +9850,6 @@ var CreateMemberInput = Struct({
10271
9850
  name: String4,
10272
9851
  ...memberTextFields,
10273
9852
  avatar: optionalKey2(MemberAvatar),
10274
- /** 给了就是远端 agent:绑这个主体。 */
10275
- remotePrincipalId: optionalKey2(String4),
10276
9853
  agent: optionalKey2(AgentChoice),
10277
9854
  /** 人成员「这是我」:绑到发起这次调用的人。 */
10278
9855
  bindToMe: optionalKey2(Boolean3)
@@ -10382,8 +9959,8 @@ var MemberChangeCompleted = Struct({
10382
9959
  var coordinatorMessage = (key) => en_default.coordinator[key];
10383
9960
 
10384
9961
  // src/coordinator/entry.ts
10385
- var decodeCreate2 = decodeUnknownSync(CreateMemberToolInput);
10386
- var decodeUpdate2 = decodeUnknownSync(UpdateMemberToolInput);
9962
+ var decodeCreate = decodeUnknownSync(CreateMemberToolInput);
9963
+ var decodeUpdate = decodeUnknownSync(UpdateMemberToolInput);
10387
9964
  var decodeRef = decodeUnknownSync(MemberRefToolInput);
10388
9965
  function registerCoordinator(ctx, runtime) {
10389
9966
  ctx.toolkit({
@@ -10393,13 +9970,13 @@ function registerCoordinator(ctx, runtime) {
10393
9970
  name: "create_member",
10394
9971
  description: coordinatorMessage("createTool"),
10395
9972
  inputSchema: toolSchema(CreateMemberToolInput),
10396
- handle: (input, invocation) => runTool(() => runtime.create(decodeCreate2(input), invocation))
9973
+ handle: (input, invocation) => runTool(() => runtime.create(decodeCreate(input), invocation))
10397
9974
  },
10398
9975
  {
10399
9976
  name: "update_member",
10400
9977
  description: coordinatorMessage("updateTool"),
10401
9978
  inputSchema: toolSchema(UpdateMemberToolInput),
10402
- handle: (input, invocation) => runTool(() => runtime.update(decodeUpdate2(input), invocation))
9979
+ handle: (input, invocation) => runTool(() => runtime.update(decodeUpdate(input), invocation))
10403
9980
  },
10404
9981
  {
10405
9982
  name: "remove_member",
@@ -10431,6 +10008,16 @@ function dataCommandReason(error) {
10431
10008
  }
10432
10009
  var CONFLICT_REASONS = ["request-conflict", "command-id-conflict"];
10433
10010
 
10011
+ // src/workWrites.ts
10012
+ var decodeHostRefusal = decodeUnknownOption2(
10013
+ Struct({
10014
+ rejection: Struct({
10015
+ code: String4,
10016
+ details: optionalKey2(Unknown2)
10017
+ })
10018
+ })
10019
+ );
10020
+
10434
10021
  // src/members/refusal.ts
10435
10022
  function memberRefusal(error) {
10436
10023
  const refusal = decodeHostRefusal(error);
@@ -10776,7 +10363,6 @@ var toMemberRow = (member, trial, viewer) => {
10776
10363
  title: member.title,
10777
10364
  responsibility: member.responsibility,
10778
10365
  avatar: member.avatar === null ? null : { pattern: member.avatar.pattern, color: member.avatar.color },
10779
- remotePrincipalId: member.identity?.kind === "remote-agent" ? member.identity.principalId : null,
10780
10366
  ...person === null ? {} : {
10781
10367
  person: viewer !== null && samePerson(person, viewer) ? "me" : "other"
10782
10368
  },
@@ -10804,6 +10390,18 @@ function membersSnapshot(view, trialOf = () => null, viewer = null) {
10804
10390
  const { stored } = view;
10805
10391
  return {
10806
10392
  members: view.members.map((member) => toMemberRow(member, trialOf(member.memberId), viewer)),
10393
+ machines: view.machines === null ? null : [...view.machines.values()].map((machine) => ({
10394
+ environmentId: machine.environmentId,
10395
+ name: machine.name,
10396
+ online: machine.online,
10397
+ ...machine.lastSeenAt === void 0 ? {} : { lastSeenAt: machine.lastSeenAt },
10398
+ providers: machine.providers.map((provider) => ({
10399
+ instanceId: provider.instanceId,
10400
+ displayName: provider.displayName,
10401
+ models: provider.models.map(({ slug, name }) => ({ slug, name })),
10402
+ ...provider.defaultModel === void 0 ? {} : { defaultModel: provider.defaultModel }
10403
+ }))
10404
+ })),
10807
10405
  lead: {
10808
10406
  memberId: stored?.version === 2 ? stored.roster.leadMemberId : null,
10809
10407
  revision: stored?.roster.revision ?? 0
@@ -10895,8 +10493,8 @@ function foldMemberEvent(state, event) {
10895
10493
  if (event.type === "member.created") {
10896
10494
  const created = decodeCreated(event.payload);
10897
10495
  if (isNone2(created) || created.value.kind !== "agent") return state;
10898
- const { projectId: projectId2, memberId: memberId2, agent, identity: identity2, actor: actor2 } = created.value;
10899
- const spec = specOfMember({ agent, identity: identity2 });
10496
+ const { projectId: projectId2, memberId: memberId2, agent, actor: actor2 } = created.value;
10497
+ const spec = specOfMember({ agent });
10900
10498
  const previous = recordOf(state, projectId2, memberId2);
10901
10499
  const record3 = triggered(
10902
10500
  { projectId: projectId2, memberId: memberId2, removed: false, spec, specKey: specKeyOf(spec) },
@@ -10911,13 +10509,12 @@ function foldMemberEvent(state, event) {
10911
10509
  if (event.type === "member.updated") {
10912
10510
  const updated = decodeUpdated(event.payload);
10913
10511
  if (isNone2(updated)) return state;
10914
- const { projectId: projectId2, memberId: memberId2, agent, identity: identity2, actor: actor2 } = updated.value;
10512
+ const { projectId: projectId2, memberId: memberId2, agent, actor: actor2 } = updated.value;
10915
10513
  const record3 = recordOf(state, projectId2, memberId2);
10916
- if (record3 === null || agent === void 0 && identity2 === void 0) return state;
10514
+ if (record3 === null || agent === void 0) return state;
10917
10515
  const spec = {
10918
- environmentId: agent?.environmentId ?? record3.spec.environmentId,
10919
- modelSelection: agent?.modelSelection ?? record3.spec.modelSelection,
10920
- identity: identity2 === void 0 ? record3.spec.identity : identity2 ?? null
10516
+ environmentId: agent.environmentId,
10517
+ modelSelection: agent.modelSelection
10921
10518
  };
10922
10519
  const specKey = specKeyOf(spec);
10923
10520
  if (specKey === record3.specKey) return state;
@@ -11199,8 +10796,8 @@ function registerMemberCommands(ctx, rosters, writer, trials2) {
11199
10796
  }
11200
10797
 
11201
10798
  // src/members/writes.ts
11202
- var decodeCreate3 = decodeUnknownOption2(CreateMemberInput);
11203
- var decodeUpdate3 = decodeUnknownOption2(UpdateMemberInput);
10799
+ var decodeCreate2 = decodeUnknownOption2(CreateMemberInput);
10800
+ var decodeUpdate2 = decodeUnknownOption2(UpdateMemberInput);
11204
10801
  var decodeRef2 = decodeUnknownOption2(MemberRefInput);
11205
10802
  var decodeImport = decodeUnknownOption2(ImportRosterInput);
11206
10803
  var importedMemberId = (projectId, legacyMemberId) => `imp-${stableHash(JSON.stringify([projectId, legacyMemberId])).slice(0, 24)}`;
@@ -11235,10 +10832,10 @@ function createMemberWriter(ctx, rosters, queue = createSerial()) {
11235
10832
  });
11236
10833
  const meOf = async (commandType, invocation) => await currentPerson(invocation) ?? rejectMember(commandType, "needs-person");
11237
10834
  const create = asPerson("createMember", async (payload, members, invocation) => {
11238
- const decoded = decodeCreate3(payload);
10835
+ const decoded = decodeCreate2(payload);
11239
10836
  if (isNone2(decoded)) return rejectMember("createMember", "invalid-payload");
11240
10837
  const input = decoded.value;
11241
- if (input.kind === "human" ? input.agent !== void 0 || input.remotePrincipalId !== void 0 : input.bindToMe !== void 0)
10838
+ if (input.kind === "human" ? input.agent !== void 0 : input.bindToMe !== void 0)
11242
10839
  return rejectMember("createMember", "invalid-payload");
11243
10840
  let me;
11244
10841
  if (input.bindToMe === true) {
@@ -11249,14 +10846,12 @@ function createMemberWriter(ctx, rosters, queue = createSerial()) {
11249
10846
  const memberId = createdMemberId(input.projectId, input.requestId);
11250
10847
  let agent;
11251
10848
  if (input.kind === "agent") {
11252
- if (input.remotePrincipalId === void 0) {
11253
- if (input.agent !== void 0) {
11254
- agent = toEngineAgent(input.agent);
11255
- } else {
11256
- const fallback = await defaultAgent(ctx, input.projectId);
11257
- if ("code" in fallback) return rejectDefault("createMember", fallback);
11258
- agent = fallback.agent;
11259
- }
10849
+ if (input.agent !== void 0) {
10850
+ agent = toEngineAgent(input.agent);
10851
+ } else {
10852
+ const fallback = await defaultAgent(ctx, input.projectId);
10853
+ if ("code" in fallback) return rejectDefault("createMember", fallback);
10854
+ agent = fallback.agent;
11260
10855
  }
11261
10856
  }
11262
10857
  const result2 = await refused(
@@ -11271,7 +10866,6 @@ function createMemberWriter(ctx, rosters, queue = createSerial()) {
11271
10866
  ...input.responsibility === void 0 ? {} : { responsibility: input.responsibility },
11272
10867
  ...input.avatar === void 0 ? {} : { avatar: input.avatar },
11273
10868
  ...input.workInstructions === void 0 ? {} : { workInstructions: input.workInstructions },
11274
- ...input.remotePrincipalId === void 0 ? {} : { identity: { kind: "remote-agent", principalId: input.remotePrincipalId } },
11275
10869
  ...me === void 0 ? {} : { identity: { kind: "human", principal: me } },
11276
10870
  ...agent === void 0 ? {} : { agent }
11277
10871
  })
@@ -11279,7 +10873,7 @@ function createMemberWriter(ctx, rosters, queue = createSerial()) {
11279
10873
  return "code" in result2 ? result2 : written(result2);
11280
10874
  });
11281
10875
  const update = asPerson("updateMember", async (payload, members, invocation) => {
11282
- const decoded = decodeUpdate3(payload);
10876
+ const decoded = decodeUpdate2(payload);
11283
10877
  if (isNone2(decoded)) return rejectMember("updateMember", "invalid-payload");
11284
10878
  const input = decoded.value;
11285
10879
  if (input.avatar !== void 0 && input.clearAvatar === true)
@@ -11355,7 +10949,20 @@ function createMemberWriter(ctx, rosters, queue = createSerial()) {
11355
10949
  if ("code" in fallback) return rejectDefault("importRoster", fallback);
11356
10950
  local = fallback;
11357
10951
  }
10952
+ const machines = missing2.some(({ member }) => member.principal !== void 0) ? [...(await readMachines(ctx, projectId))?.values() ?? []] : [];
10953
+ const remoteAgentOf = (principalId) => {
10954
+ const machine = machines.find((entry) => entry.principalId === principalId);
10955
+ const provider = machine?.providers[0];
10956
+ const model = provider?.defaultModel ?? provider?.models[0]?.slug;
10957
+ return machine === void 0 || provider === void 0 || model === void 0 ? void 0 : {
10958
+ environmentId: machine.environmentId,
10959
+ modelSelection: { instanceId: provider.instanceId, model }
10960
+ };
10961
+ };
11358
10962
  for (const { member, memberId } of missing2) {
10963
+ const remote = member.principal === void 0 ? void 0 : remoteAgentOf(member.principal.principalId);
10964
+ if (member.principal !== void 0 && remote === void 0)
10965
+ return rejectMember("importRoster", "machine-missing", { memberName: member.name });
11359
10966
  const created = await refused(
11360
10967
  "importRoster",
11361
10968
  () => members.create({
@@ -11363,12 +10970,7 @@ function createMemberWriter(ctx, rosters, queue = createSerial()) {
11363
10970
  memberId,
11364
10971
  kind: "agent",
11365
10972
  name: member.name,
11366
- ...member.principal === void 0 ? local : {
11367
- identity: {
11368
- kind: "remote-agent",
11369
- principalId: member.principal.principalId
11370
- }
11371
- }
10973
+ ...remote === void 0 ? local : { agent: remote }
11372
10974
  })
11373
10975
  );
11374
10976
  if ("code" in created)
@@ -11441,6 +11043,7 @@ var isMentionStart = (text, index) => {
11441
11043
  };
11442
11044
 
11443
11045
  // src/runtime/mentionedMembers.ts
11046
+ var mentionPrincipal = (member) => member.threadId !== void 0 ? member.principalId === void 0 ? { kind: "agent", threadId: member.threadId } : null : member.principalId !== void 0 ? { kind: "remote-agent", principalId: member.principalId } : null;
11444
11047
  var ASCII_WORD = /[A-Za-z0-9_-]/;
11445
11048
  function mentionedMembers(body, members) {
11446
11049
  const aliases = members.flatMap((member) => {
@@ -11967,8 +11570,14 @@ function startMemberBindingRuntime(ctx, goals, rosters, wakes, trials2) {
11967
11570
  const { projectId } = goal;
11968
11571
  const base = baseOf(goal, member);
11969
11572
  let bound;
11970
- if (member.identity?.kind === "remote-agent") {
11971
- bound = { ...base, principalId: member.identity.principalId };
11573
+ if (isRemoteMember(member, ctx.environment.id)) {
11574
+ const machine = member.agent === null ? void 0 : (await readMachines(ctx, projectId))?.get(member.agent.environmentId);
11575
+ if (machine === void 0)
11576
+ return {
11577
+ code: "no-machine",
11578
+ detail: "the machine they run on has not joined this project, so there is nowhere to send their work"
11579
+ };
11580
+ bound = { ...base, principalId: machine.principalId };
11972
11581
  } else {
11973
11582
  const resolved = await resolveMemberSelection(ctx, projectId, member.agent, defaultSelection);
11974
11583
  if ("code" in resolved) {
@@ -13442,7 +13051,7 @@ var leadReviewText = (workItemId, sequenceId, title, by, facts) => [
13442
13051
  ...facts.idle.length > 0 && facts.queued.length > 0 ? [LEAD_REBALANCE_RULE] : [],
13443
13052
  LEAD_NO_MEMBER_TASKS
13444
13053
  ].join(" ");
13445
- 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.`;
13054
+ var commentText = (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.`;
13446
13055
  function startWakeRuntime(ctx, goals, options = {}) {
13447
13056
  const wakes = ctx.derivedState({
13448
13057
  key: WAKE_STATE_KEY,
@@ -13470,7 +13079,7 @@ function startWakeRuntime(ctx, goals, options = {}) {
13470
13079
  };
13471
13080
  const baseText = async (wake, state) => {
13472
13081
  if ("principalId" in wake || wake.kind === "comment")
13473
- return commentText2(wake.workItemId, wake.sequenceId);
13082
+ return commentText(wake.workItemId, wake.sequenceId);
13474
13083
  const item = await readItem(wake.projectId, wake.workItemId);
13475
13084
  const title = item?.title;
13476
13085
  if (wake.kind === "review") {
@@ -14780,7 +14389,7 @@ var currentSeat = (project2, memberId, wake) => {
14780
14389
  var decodeAcknowledgement = decodeUnknownSync(AcknowledgeInput);
14781
14390
  var decodePublish = decodeUnknownSync(PublishInput);
14782
14391
  var decodeRevert = decodeUnknownSync(RevertInput);
14783
- var decodeRead4 = decodeUnknownSync(ReadHandbookInput);
14392
+ var decodeRead3 = decodeUnknownSync(ReadHandbookInput);
14784
14393
  function registerHandbook(ctx, runtime) {
14785
14394
  ctx.toolkit({
14786
14395
  name: "handbook",
@@ -14814,7 +14423,7 @@ function registerHandbook(ctx, runtime) {
14814
14423
  name: "handbook",
14815
14424
  scope: "read",
14816
14425
  payloadSchema: payloadSchemaOf(ReadHandbookInput),
14817
- handle: (input) => runtime.read(decodeRead4(input).projectId)
14426
+ handle: (input) => runtime.read(decodeRead3(input).projectId)
14818
14427
  });
14819
14428
  ctx.operations.guard({ operations: ["work.start"], check: runtime.startCheck });
14820
14429
  }
@@ -15359,15 +14968,16 @@ function createLineChangeRunner(ctx, deps) {
15359
14968
  }
15360
14969
 
15361
14970
  // src/team/brief.ts
14971
+ var REMOTE_WHERE_PREFIX = "machine: ";
15362
14972
  function teamLeadBrief(team) {
15363
14973
  const table = [
15364
- "| Member | memberId | threadId / remote principalId | Ready |",
14974
+ "| Member | memberId | threadId / machine | Ready |",
15365
14975
  "| --- | --- | --- | --- |",
15366
14976
  ...team.members.map(
15367
14977
  (member) => `| ${tableCell(member.name)} | ${tableCell(member.memberId)} | ${tableCell(member.where)} | ${member.status} |`
15368
14978
  )
15369
14979
  ].join("\n");
15370
- const hasRemote = team.members.some((member) => member.where.startsWith("remote-agent"));
14980
+ const hasRemote = team.members.some((member) => member.where.startsWith(REMOTE_WHERE_PREFIX));
15371
14981
  return [
15372
14982
  `You are now the lead of the team "${team.name}". This conversation is the team: the person talks to you here, and your members are woken from here.`,
15373
14983
  "What was agreed:",
@@ -15381,7 +14991,7 @@ function teamLeadBrief(team) {
15381
14991
  'Then use work_add_relation with type "blocked_by" to record dependencies: the dependent workItemId is blocked by the prerequisite relatedWorkItemId.',
15382
14992
  LEAD_OWN_ITEM_RULE,
15383
14993
  memberAssignRule(true),
15384
- "Add or remove members of the team with team_set_members. To add someone who is not in the project yet, create them first with team_create_member (it starts their trial run), then add them. Use team_roster_overview to see everyone in the project and which teams they are in; work_list_remote_agents lists the agents from other machines that this project has authorized.",
14994
+ "Add or remove members of the team with team_set_members. To add someone who is not in the project yet, create them first with team_create_member (it starts their trial run), then add them. Use team_roster_overview to see everyone in the project and which teams they are in; work_list_machines lists the other machines that joined this project and the providers and models each one offers, for creating a member on one of them.",
15385
14995
  LEAD_SEND_BACK_RULE,
15386
14996
  LEAD_ACCEPT_RULE,
15387
14997
  LEAD_STUCK_RULE,
@@ -15390,7 +15000,7 @@ function teamLeadBrief(team) {
15390
15000
  LEAD_START_CHECK_RULE,
15391
15001
  LEAD_REBALANCE_RULE,
15392
15002
  ...hasRemote ? [
15393
- "Remote members are on another machine. Assign them work like the others; they pick it up from their own machine. Do not create conversations, start turns, or send wake-up signals for them on this machine. A comment that mentions a remote member wakes them on their machine; once they mark an item done they stop working on it, so to send work back you reopen the item as described above. Whatever a remote member needs a person for is handled on their machine, not in this conversation."
15003
+ "Members marked with a machine run on that other machine. Assign them work like the others; their machine picks it up and runs them with the model in their member record. Do not create conversations, start turns, or send wake-up signals for them on this machine; if their machine is offline, the work waits until it is back. A comment that mentions a remote member wakes them on their machine; once they mark an item done they stop working on it, so to send work back you reopen the item as described above. Whatever a remote member needs a person for is handled on their machine, not in this conversation."
15394
15004
  ] : [],
15395
15005
  "How the group works: when a member is woken it is shown what was said in this group since it last looked (the person's words and yours, plus group records, at most about 30 messages; never any tool call or thinking), so you do not have to repeat what was agreed. Older messages are read with list_thread_messages on this conversation, and older group records with message_list { groupThreadId: this conversation }. Members cannot see anything else you do, so put what a member needs into the work item description.",
15396
15006
  "To ask a member something in the group, use send_message with to: { group: { threadId: this conversation } } and mentions: [{ memberId }] for each member your text addresses with @name. Each mentioned member is woken; other group messages and members' replies reach you as a quiet copy in your inbox and never start a turn for you. Members answer in the group with replyTo to the record they are answering; a reply on its own wakes nobody, so a member who needs you mentions you in the text.",
@@ -15520,7 +15130,6 @@ function leadMemberName(leadName, title, tag2) {
15520
15130
  const tail = ` lead${tag2}`;
15521
15131
  return `${title.trim().slice(0, MAX_MEMBER_NAME_LENGTH - tail.length).trimEnd()}${tail}`.trim();
15522
15132
  }
15523
- var remotePrincipalOf2 = (member) => member.identity?.kind === "remote-agent" ? member.identity.principalId : null;
15524
15133
  function createTeamOpener(ctx, deps, runner = createLineChangeRunner(ctx, deps), now3 = factTime) {
15525
15134
  const lineIdOf = (projectId, threadId, requestId) => `wl-${mark(projectId, threadId, requestId).slice(0, 24)}`;
15526
15135
  const goalIdOf = (projectId, threadId, requestId) => `tg-${mark(projectId, threadId, requestId).slice(0, 24)}`;
@@ -15589,7 +15198,11 @@ function createTeamOpener(ctx, deps, runner = createLineChangeRunner(ctx, deps),
15589
15198
  );
15590
15199
  const members = await Promise.all(memberIds.map((id) => findMember(ctx, projectId, id)));
15591
15200
  const rows = members.flatMap((row) => row === null ? [] : [row]);
15592
- const local = rows.filter((row) => row.kind === "agent" && remotePrincipalOf2(row) === null);
15201
+ const local = rows.filter(
15202
+ (row) => row.kind === "agent" && !isRemoteMember(row, ctx.environment.id)
15203
+ );
15204
+ const machines = await readMachines(ctx, projectId);
15205
+ const machineOf = (row) => row.agent === null ? void 0 : machines?.get(row.agent.environmentId);
15593
15206
  const selections = await resolveLocalSelections(projectId, local);
15594
15207
  const leadMemberId = await ensureLeadMember(projectId, callerThreadId, input.leadName);
15595
15208
  const ownerMemberId = await ensureOwnerMember(
@@ -15620,8 +15233,8 @@ function createTeamOpener(ctx, deps, runner = createLineChangeRunner(ctx, deps),
15620
15233
  throw error;
15621
15234
  }
15622
15235
  const remote = rows.flatMap((row) => {
15623
- const principalId = remotePrincipalOf2(row);
15624
- return principalId === null ? [] : [{ memberId: row.memberId, principalId }];
15236
+ const machine = isRemoteMember(row, ctx.environment.id) ? machineOf(row) : void 0;
15237
+ return machine === void 0 ? [] : [{ memberId: row.memberId, principalId: machine.principalId }];
15625
15238
  });
15626
15239
  const lead = await findMember(ctx, projectId, leadMemberId);
15627
15240
  const specKeys = Object.fromEntries(
@@ -15675,11 +15288,10 @@ function createTeamOpener(ctx, deps, runner = createLineChangeRunner(ctx, deps),
15675
15288
  await syncLineTitle(ctx, projectId, workLineId);
15676
15289
  const trials2 = await deps.trials.get();
15677
15290
  const roster = team.map((row) => {
15678
- const principalId = remotePrincipalOf2(row);
15679
15291
  return {
15680
15292
  name: row.name,
15681
15293
  memberId: row.memberId,
15682
- where: principalId !== null ? `remote-agent: ${principalId}` : row.kind === "human" ? "person" : teamThreadId(projectId, goalId, row.memberId),
15294
+ where: isRemoteMember(row, ctx.environment.id) ? `${REMOTE_WHERE_PREFIX}${machineOf(row)?.name ?? "not joined"}` : row.kind === "human" ? "person" : teamThreadId(projectId, goalId, row.memberId),
15683
15295
  status: statusOf2(trials2, projectId, row)
15684
15296
  };
15685
15297
  });
@@ -15753,7 +15365,7 @@ function createTeamOpener(ctx, deps, runner = createLineChangeRunner(ctx, deps),
15753
15365
  }
15754
15366
  await resolveLocalSelections(
15755
15367
  projectId,
15756
- rows.filter((row) => row.kind === "agent" && remotePrincipalOf2(row) === null)
15368
+ rows.filter((row) => row.kind === "agent" && !isRemoteMember(row, ctx.environment.id))
15757
15369
  );
15758
15370
  return {
15759
15371
  ...input,
@@ -15788,7 +15400,7 @@ function createTeamOverview(ctx, deps) {
15788
15400
  projectId,
15789
15401
  members: members.items.filter((member) => member.removedAt === null).map((member) => {
15790
15402
  const trial = trialViewOf(recordOf(trials2, projectId, member.memberId));
15791
- const principalId = member.identity?.kind === "remote-agent" ? member.identity.principalId : null;
15403
+ const remote = isRemoteMember(member, ctx.environment.id);
15792
15404
  return {
15793
15405
  memberId: member.memberId,
15794
15406
  name: member.name,
@@ -15796,9 +15408,9 @@ function createTeamOverview(ctx, deps) {
15796
15408
  machine: member.agent?.environmentId ?? null,
15797
15409
  model: member.agent === null ? null : member.agent.modelSelection.model,
15798
15410
  provider: member.agent === null ? null : member.agent.modelSelection.instanceId,
15799
- remoteAgent: principalId,
15411
+ remote,
15800
15412
  // 人没有试跑;远端成员没有本机试跑记录时读不出对方机器的情况,标明。
15801
- trial: member.kind === "human" ? "none" : trial === null ? principalId === null ? "none" : "unverified" : trial.evidence === "invoked" ? "invoked" : trial.status === "failed" ? "failed" : trial.status === "passed" || trial.status === "overridden" ? "ready" : "pending",
15413
+ trial: member.kind === "human" ? "none" : trial === null ? remote ? "unverified" : "none" : trial.evidence === "invoked" ? "invoked" : trial.status === "failed" ? "failed" : trial.status === "passed" || trial.status === "overridden" ? "ready" : "pending",
15802
15414
  trialFailure: trial?.failure?.category ?? null,
15803
15415
  teams: teamsOf(member.memberId),
15804
15416
  // 这名成员被暂停的团队:整线暂停,或它在这条线上被单独暂停(ADR-0027:371);读线上的引擎事实。
@@ -16389,11 +16001,11 @@ var zh_CN_default = {
16389
16001
  handbook: {
16390
16002
  requestConflict: "\u8FD9\u4E2A requestId \u5DF2\u7528\u4E8E\u53E6\u4E00\u4EFD\u624B\u518C\u8BF7\u6C42\uFF0C\u8BF7\u6362\u4E00\u4E2A\u65B0\u7684 requestId\u3002",
16391
16003
  requestVoided: "\u8FD9\u4E2A requestId \u5728\u624B\u518C\u6536\u5230\u4E4B\u524D\u5C31\u4F5C\u5E9F\u4E86\uFF0C\u8BF7\u6362\u4E00\u4E2A\u65B0\u7684 requestId\u3002",
16392
- ackTool: "\u4EE5\u4F60\u5728\u5F53\u524D\u76EE\u6807\u4E2D\u7684\u6210\u5458\u5E2D\u4F4D\u786E\u8BA4\u5F53\u524D\u8981\u6C42\u786E\u8BA4\u7684\u624B\u518C\u7248\u672C\u3002\u53EA\u8BFB\u4E0D\u7B97\u786E\u8BA4\u3002\u6CA1\u6709\u76EE\u6807\u65F6\u6CA1\u6709\u56E2\u961F\u6210\u5458\uFF0C\u786E\u8BA4\u95E8\u69DB\u4E0E\u63D0\u9192\u5747\u4E0D\u4F5C\u7528\u3002",
16004
+ ackTool: "\u4EE5\u4F60\u5728\u5F53\u524D\u76EE\u6807\u4E2D\u7684\u6210\u5458\u8EAB\u4EFD\u786E\u8BA4\u5F53\u524D\u8981\u6C42\u786E\u8BA4\u7684\u624B\u518C\u7248\u672C\u3002\u53EA\u8BFB\u4E0D\u7B97\u786E\u8BA4\u3002\u6CA1\u6709\u76EE\u6807\u65F6\u6CA1\u6709\u56E2\u961F\u6210\u5458\uFF0C\u786E\u8BA4\u95E8\u69DB\u4E0E\u63D0\u9192\u5747\u4E0D\u4F5C\u7528\u3002",
16393
16005
  publishTool: "\u7531\u672C\u673A\u56E2\u961F\u8D1F\u8D23\u4EBA\u53D1\u5E03\u624B\u518C\u9875\u3002\u540C\u4E00 requestId \u53EA\u80FD\u91CD\u8BD5\u540C\u4E00\u8BF7\u6C42\u3002\u89C4\u77E9\u53D8\u5316\u5FC5\u987B\u786E\u8BA4\uFF1B\u5B9A\u8FC7\u4EC0\u4E48\u53D8\u5316\u65F6\u7528 requireAck \u9009\u62E9\uFF0C\u9ED8\u8BA4 false\u3002",
16394
16006
  revertTool: "\u7531\u672C\u673A\u56E2\u961F\u8D1F\u8D23\u4EBA\u6062\u590D\u6307\u5B9A\u624B\u518C\u7248\u672C\u3002\u540C\u4E00 requestId \u53EA\u80FD\u91CD\u8BD5\u540C\u4E00\u8BF7\u6C42\u3002\u89C4\u77E9\u53D8\u5316\u5FC5\u987B\u786E\u8BA4\uFF1B\u5B9A\u8FC7\u4EC0\u4E48\u53D8\u5316\u65F6\u7528 requireAck \u9009\u62E9\uFF0C\u9ED8\u8BA4 false\u3002",
16395
16007
  unknownMember: "\u5BBF\u4E3B\u6838\u5B9E\u7684\u8C03\u7528\u8005\u8EAB\u4EFD\u672A\u6620\u5C04\u5230\u672C\u9879\u76EE\u5F53\u524D\u76EE\u6807\u7684\u6210\u5458\u3002",
16396
- leadOnly: "\u53EA\u6709\u5F53\u524D\u76EE\u6807\u4E2D\u7684\u672C\u673A\u8D1F\u8D23\u4EBA\u5E2D\u4F4D\u53EF\u4EE5\u53D1\u5E03\u6216\u9000\u56DE\u624B\u518C\u3002",
16008
+ leadOnly: "\u53EA\u6709\u5F53\u524D\u76EE\u6807\u4E2D\u7684\u672C\u673A\u8D1F\u8D23\u4EBA\u53EF\u4EE5\u53D1\u5E03\u6216\u9000\u56DE\u624B\u518C\u3002",
16397
16009
  noGoal: "\u8BF7\u5148\u5F00\u59CB\u4E00\u4E2A\u76EE\u6807\uFF0C\u518D\u53D1\u5E03\u6216\u9000\u56DE\u624B\u518C\u3002\u6CA1\u6709\u76EE\u6807\u65F6\u6CA1\u6709\u56E2\u961F\u6210\u5458\uFF0C\u786E\u8BA4\u95E8\u69DB\u4E0E\u63D0\u9192\u5747\u4E0D\u4F5C\u7528\u3002",
16398
16010
  noRequirement: "\u76EE\u524D\u8FD8\u6CA1\u6709\u8981\u6C42\u786E\u8BA4\u7684\u624B\u518C\u7248\u672C\u3002",
16399
16011
  wrongRelease: "\u8BF7\u786E\u8BA4\u624B\u518C\u7B2C {{release}} \u7248\uFF0C\u8FD9\u662F\u5F53\u524D\u8981\u6C42\u786E\u8BA4\u7684\u7248\u672C\u3002",
@@ -16407,9 +16019,9 @@ var zh_CN_default = {
16407
16019
  leadBrief: "\u5148\u7528 wiki_read_handbook \u8BFB\u624B\u518C\uFF0C\u518D\u7528 team_acknowledge_handbook \u660E\u786E\u786E\u8BA4\u5F53\u524D\u8981\u6C42\u786E\u8BA4\u7684\u7248\u672C\uFF0C\u624D\u80FD\u9886\u65B0\u6D3B\u3002\u7528 team_publish_handbook \u6216 team_revert_handbook \u53D1\u5E03\u6216\u9000\u56DE\uFF1B\u53D1\u5E03\u8981\u6C42\u786E\u8BA4\u7684\u7248\u672C\u4E5F\u4F1A\u4E3A\u4F60\u8BB0\u4E0B\u786E\u8BA4\u3002"
16408
16020
  },
16409
16021
  team: {
16410
- openTool: "\u628A\u8FD9\u6761\u4F1A\u8BDD\u53D8\u6210\u4E00\u4E2A\u56E2\u961F\u3002\u53EA\u5728\u4EBA\u5DF2\u7ECF\u5728\u8FD9\u6761\u4F1A\u8BDD\u91CC\u540C\u610F\u4E86\u4F60\u63D0\u7684\u56E2\u961F\u65B9\u6848\u4E4B\u540E\u624D\u8C03\uFF1A\u8C01\u52A0\u5165\uFF08\u9879\u76EE\u91CC\u5DF2\u6709\u7684\u6210\u5458\uFF0C\u5305\u62EC\u7528 work_list_remote_agents \u770B\u5230\u7684\u522B\u7684\u673A\u5668\u4E0A\u7684 agent\uFF09\u3001\u56E2\u961F\u5F00\u597D\u4E4B\u540E\u8981\u65B0\u5EFA\u54EA\u4E9B\u6210\u5458\u3002\u8FD8\u4E0D\u5B58\u5728\u7684\u6210\u5458\u5728\u8FD9\u6B21\u8C03\u7528\u4E4B\u540E\u518D\u6765\uFF1A\u5148\u7528 team_create_member \u65B0\u5EFA\uFF0C\u518D\u7528 team_set_members \u62C9\u8FDB\u6765\u3002\u8FD9\u6761\u4F1A\u8BDD\u4ECE\u6B64\u662F\u56E2\u961F\u7684\u8D1F\u8D23\u4EBA\u548C\u7FA4\u804A\uFF0C\u5E76\u6539\u540D\u4E3A\u56E2\u961F\u540D\uFF1A\u4F60\u5217\u7684\u6210\u5458\u52A0\u8FDB\u6765\uFF0C\u6BCF\u4E2A\u672C\u673A agent \u6210\u5458\u5728\u4F60\u7684\u4F1A\u8BDD\u540D\u4E0B\u5F97\u5230\u81EA\u5DF1\u7684\u4F1A\u8BDD\u3002requestId \u8981\u7528\u65B0\u7684\uFF0C\u53EA\u6709\u91CD\u8BD5\u540C\u4E00\u6B21\u8C03\u7528\u65F6\u624D\u6CBF\u7528\u3002name \u662F\u56E2\u961F\u540D\uFF08\u6700\u591A 80 \u5B57\uFF09\uFF1Bgoal \u662F\u8C08\u59A5\u5185\u5BB9\u7684\u6458\u8981\uFF08\u6700\u591A 4000 \u5B57\uFF09\uFF1BmemberIds \u662F\u8981\u62C9\u8FDB\u6765\u7684\u9879\u76EE\u6210\u5458\u7684 memberId\uFF08\u4E0D\u542B\u4F60\u81EA\u5DF1\uFF0C\u4F60\u4F1A\u4F5C\u4E3A\u8D1F\u8D23\u4EBA\u52A0\u8FDB\u6765\uFF09\uFF1BleadName \u53EF\u9009\uFF0C\u662F\u4F60\u4F5C\u4E3A\u9879\u76EE\u6210\u5458\u7684\u540D\u5B57\uFF081-40 \u5B57\uFF09\u3002\u8FD4\u56DE\u56E2\u961F\u7684\u5DE5\u4F5C\u7EBF\u3001\u6210\u5458\u548C\u6BCF\u4E2A\u6210\u5458\u662F\u5426\u5C31\u7EEA\uFF0C\u4EE5\u53CA\u4F60\u7684\u5F00\u5DE5\u8BF4\u660E\u3002\u5DF2\u7ECF\u662F\u56E2\u961F\u3001\u6216\u5C5E\u4E8E\u67D0\u4E2A\u56E2\u961F\u7684\u4F1A\u8BDD\u4E0D\u80FD\u518D\u5F00\u56E2\u961F\u3002",
16022
+ openTool: "\u628A\u8FD9\u6761\u4F1A\u8BDD\u53D8\u6210\u4E00\u4E2A\u56E2\u961F\u3002\u53EA\u5728\u4EBA\u5DF2\u7ECF\u5728\u8FD9\u6761\u4F1A\u8BDD\u91CC\u540C\u610F\u4E86\u4F60\u63D0\u7684\u56E2\u961F\u65B9\u6848\u4E4B\u540E\u624D\u8C03\uFF1A\u8C01\u52A0\u5165\uFF08\u5DF2\u5728\u9879\u76EE\u91CC\u7684\u6210\u5458\uFF0C\u5305\u62EC\u52A0\u8FDB\u8FD9\u4E2A\u9879\u76EE\u7684\u5176\u4ED6\u673A\u5668\u4E0A\u7684 agent\uFF1Bwork_list_machines \u5217\u51FA\u8FD9\u4E9B\u673A\u5668\uFF09\u3001\u56E2\u961F\u5F00\u597D\u4E4B\u540E\u8981\u65B0\u5EFA\u54EA\u4E9B\u6210\u5458\u3002\u8FD8\u4E0D\u5B58\u5728\u7684\u6210\u5458\u5728\u8FD9\u6B21\u8C03\u7528\u4E4B\u540E\u518D\u6765\uFF1A\u5148\u7528 team_create_member \u65B0\u5EFA\uFF0C\u518D\u7528 team_set_members \u62C9\u8FDB\u6765\u3002\u8FD9\u6761\u4F1A\u8BDD\u4ECE\u6B64\u662F\u56E2\u961F\u7684\u8D1F\u8D23\u4EBA\u548C\u7FA4\u804A\uFF0C\u5E76\u6539\u540D\u4E3A\u56E2\u961F\u540D\uFF1A\u4F60\u5217\u7684\u6210\u5458\u52A0\u8FDB\u6765\uFF0C\u6BCF\u4E2A\u672C\u673A agent \u6210\u5458\u5728\u4F60\u7684\u4F1A\u8BDD\u540D\u4E0B\u5F97\u5230\u81EA\u5DF1\u7684\u4F1A\u8BDD\u3002requestId \u8981\u7528\u65B0\u7684\uFF0C\u53EA\u6709\u91CD\u8BD5\u540C\u4E00\u6B21\u8C03\u7528\u65F6\u624D\u6CBF\u7528\u3002name \u662F\u56E2\u961F\u540D\uFF08\u6700\u591A 80 \u5B57\uFF09\uFF1Bgoal \u662F\u8C08\u59A5\u5185\u5BB9\u7684\u6458\u8981\uFF08\u6700\u591A 4000 \u5B57\uFF09\uFF1BmemberIds \u662F\u8981\u62C9\u8FDB\u6765\u7684\u9879\u76EE\u6210\u5458\u7684 memberId\uFF08\u4E0D\u542B\u4F60\u81EA\u5DF1\uFF0C\u4F60\u4F1A\u4F5C\u4E3A\u8D1F\u8D23\u4EBA\u52A0\u8FDB\u6765\uFF09\uFF1BleadName \u53EF\u9009\uFF0C\u662F\u4F60\u4F5C\u4E3A\u9879\u76EE\u6210\u5458\u7684\u540D\u5B57\uFF081-40 \u5B57\uFF09\u3002\u8FD4\u56DE\u56E2\u961F\u7684\u5DE5\u4F5C\u7EBF\u3001\u6210\u5458\u548C\u6BCF\u4E2A\u6210\u5458\u662F\u5426\u5C31\u7EEA\uFF0C\u4EE5\u53CA\u4F60\u7684\u5F00\u5DE5\u8BF4\u660E\u3002\u5DF2\u7ECF\u662F\u56E2\u961F\u3001\u6216\u5C5E\u4E8E\u67D0\u4E2A\u56E2\u961F\u7684\u4F1A\u8BDD\u4E0D\u80FD\u518D\u5F00\u56E2\u961F\u3002",
16411
16023
  setMembersTool: "\u6539\u8FD9\u4E2A\u56E2\u961F\u91CC\u6709\u8C01\uFF08\u53EA\u6709\u56E2\u961F\u7684\u8D1F\u8D23\u4EBA\u4F1A\u8BDD\u80FD\u8C03\uFF09\u3002add\uFF1A\u8981\u62C9\u8FDB\u6765\u7684\u9879\u76EE\u6210\u5458\u7684 memberId\uFF1Bremove\uFF1A\u8981\u79FB\u51FA\u7684 memberId\u3002\u79FB\u51FA\u7684\u6210\u5458\u540D\u4E0B\u8FD8\u6CA1\u5230\u5B83\u624B\u4E0A\u7684\u6D3B\u4F1A\u6536\u56DE\u5E76\u4EA4\u7ED9\u4F60\uFF0C\u5DF2\u7ECF\u5728\u5B83\u624B\u4E0A\u7684\u6D3B\u7559\u7ED9\u5B83\uFF0C\u7531\u4F60\u51B3\u5B9A\u3002\u4F60\u4E0D\u80FD\u79FB\u51FA\u81EA\u5DF1\uFF0C\u4E5F\u4E0D\u80FD\u52A8\u522B\u7684\u56E2\u961F\u7684\u6210\u5458\u548C\u8D1F\u8D23\u4EBA\u3002requestId \u8981\u7528\u65B0\u7684\uFF0C\u53EA\u6709\u91CD\u8BD5\u540C\u4E00\u6B21\u8C03\u7528\u65F6\u624D\u6CBF\u7528\u3002",
16412
- rosterOverviewTool: "\u8BFB\u51FA\u89C4\u5212\u56E2\u961F\u9700\u8981\u7684\u5168\u90E8\u4FE1\u606F\uFF1A\u8FD9\u4E2A\u9879\u76EE\u7684\u6BCF\u4E2A\u6210\u5458\uFF0C\u542B\u79CD\u7C7B\u3001\u673A\u5668\u3001\u6A21\u578B\u3001\u8BD5\u8DD1\u8FDB\u5EA6\uFF08trial \u53D6\u503C\uFF1Anone \u8868\u793A\u4E0D\u9002\u7528\uFF0C\u6BD4\u5982\u4EBA\uFF1Bunverified \u662F\u522B\u7684\u673A\u5668\u4E0A\u7684 agent\uFF0C\u4ECE\u8FD9\u91CC\u6D4B\u4E0D\u5230\uFF1Bpending \u662F\u8FD8\u6CA1\u901A\u8FC7\uFF1Bready \u662F\u5DF2\u901A\u8FC7\u6216\u5DF2\u8DF3\u8FC7\uFF1Bfailed \u662F\u5931\u8D25\uFF1Binvoked \u662F\u8FD9\u6761\u4F1A\u8BDD\u672C\u8EAB\u5C31\u662F\u8D1F\u8D23\u4EBA\uFF0C\u65E0\u9700\u8BD5\u8DD1\uFF09\uFF0C\u4EE5\u53CA\u6240\u5728\u7684\u56E2\u961F\uFF08\u662F\u4E0D\u662F\u90A3\u4E2A\u56E2\u961F\u7684\u8D1F\u8D23\u4EBA\uFF09\u3002\u63D0\u56E2\u961F\u65B9\u6848\u4E4B\u524D\u3001\u65B0\u5EFA\u6210\u5458\u4E4B\u524D\u5148\u8BFB\u5B83\u3002",
16024
+ rosterOverviewTool: "\u8BFB\u51FA\u89C4\u5212\u56E2\u961F\u9700\u8981\u7684\u5168\u90E8\u4FE1\u606F\uFF1A\u8FD9\u4E2A\u9879\u76EE\u7684\u6BCF\u4E2A\u6210\u5458\uFF0C\u542B\u79CD\u7C7B\u3001\u673A\u5668\u3001\u6A21\u578B\u3001\u8BD5\u8DD1\u8FDB\u5EA6\uFF08trial \u53D6\u503C\uFF1Anone \u8868\u793A\u4E0D\u9002\u7528\uFF0C\u6BD4\u5982\u4EBA\uFF1Bunverified \u662F\u522B\u7684\u673A\u5668\u4E0A\u3001\u8FD9\u91CC\u8FD8\u6CA1\u6709\u8BD5\u8DD1\u8BB0\u5F55\u7684 agent\uFF1Bpending \u662F\u8FD8\u6CA1\u901A\u8FC7\uFF1Bready \u662F\u5DF2\u901A\u8FC7\u6216\u5DF2\u8DF3\u8FC7\uFF1Bfailed \u662F\u5931\u8D25\uFF1Binvoked \u662F\u8FD9\u6761\u4F1A\u8BDD\u672C\u8EAB\u5C31\u662F\u8D1F\u8D23\u4EBA\uFF0C\u65E0\u9700\u8BD5\u8DD1\uFF09\uFF0C\u4EE5\u53CA\u6240\u5728\u7684\u56E2\u961F\uFF08\u662F\u4E0D\u662F\u90A3\u4E2A\u56E2\u961F\u7684\u8D1F\u8D23\u4EBA\uFF09\u3002\u63D0\u56E2\u961F\u65B9\u6848\u4E4B\u524D\u3001\u65B0\u5EFA\u6210\u5458\u4E4B\u524D\u5148\u8BFB\u5B83\u3002",
16413
16025
  noProject: "\u8FD9\u6B21\u8C03\u7528\u4E0D\u5C5E\u4E8E\u4EFB\u4F55\u9879\u76EE\uFF0C\u6CA1\u6709\u53EF\u5F00\u6216\u53EF\u6539\u7684\u56E2\u961F\u3002",
16414
16026
  notLocal: "\u53EA\u6709\u8FD9\u53F0\u673A\u5668\u4E0A\u7684\u4F1A\u8BDD\u80FD\u5F00\u56E2\u961F\u3002",
16415
16027
  invalidInput: "\u8BF7\u68C0\u67E5\u53C2\u6570\uFF1ArequestId \u662F 1-64 \u4F4D\u5B57\u6BCD\u3001\u6570\u5B57\u3001\u4E0B\u5212\u7EBF\u6216\u8FDE\u5B57\u7B26\uFF1Bname 1-80 \u5B57\uFF1Bgoal 1-4000 \u5B57\uFF1BleadName \u82E5\u7ED9\u51FA\u4E3A 1-40 \u5B57\u3002",
@@ -16452,100 +16064,13 @@ var zh_CN_default = {
16452
16064
  cannotReplaceLead: "\u4E0D\u80FD\u6539\u81EA\u5DF1\u7684 provider \u548C\u6A21\u578B\u3002"
16453
16065
  },
16454
16066
  board: {
16455
- title: "\u9879\u76EE\u770B\u677F",
16456
- newItem: "\u65B0\u5EFA\u5DE5\u4F5C\u9879",
16457
- itemTitle: "\u6807\u9898",
16458
- description: "\u8BF4\u660E\uFF08\u53EF\u9009\uFF09",
16459
- assignee: "\u6307\u6D3E\u7ED9\uFF08\u53EF\u9009\uFF09",
16460
- create: "\u521B\u5EFA\u5DE5\u4F5C\u9879",
16461
- retryCreate: "\u91CD\u8BD5\u521B\u5EFA",
16462
- saving: "\u4FDD\u5B58\u4E2D\u2026",
16463
- moveTo: "\u79FB\u5230\u2026",
16464
- goalItem: "\u76EE\u6807",
16465
- moveItem: "\u79FB\u52A8\u5DE5\u4F5C\u9879 #{{number}}",
16466
- moveItemTo: "\u5C06\u5DE5\u4F5C\u9879 #{{number}} \u79FB\u5230 {{state}}",
16467
- assignTo: "\u6307\u6D3E\u7ED9\u2026",
16468
- assignItem: "\u6307\u6D3E\u5DE5\u4F5C\u9879 #{{number}}",
16469
- assignItemTo: "\u5C06\u5DE5\u4F5C\u9879 #{{number}} \u6307\u6D3E\u7ED9 {{name}}",
16470
- unassign: "\u53D6\u6D88\u6307\u6D3E",
16471
- unassignItem: "\u53D6\u6D88\u5DE5\u4F5C\u9879 #{{number}} \u7684\u6307\u6D3E",
16472
- dragItem: "\u5C06\u5DE5\u4F5C\u9879 #{{number}} \u62D6\u5230\u5176\u4ED6\u72B6\u6001",
16473
- untitled: "\uFF08\u65E0\u6807\u9898\uFF09",
16067
+ openTeam: "\u5728\u770B\u677F\u4E0A\u6253\u5F00\u8FD9\u4E2A\u56E2\u961F",
16068
+ openProject: "\u6253\u5F00\u770B\u677F",
16474
16069
  other: "\u5176\u4ED6",
16475
- unassigned: "\u672A\u6307\u6D3E",
16476
- sessionRunning: "\u4F1A\u8BDD\u5728\u8DD1",
16477
- sessionFailed: "\u51FA\u9519",
16478
- sessionWaiting: "\u7B49\u4EBA\u5904\u7406",
16479
- sessionStopped: "\u505C\u7740",
16480
- sessionStoppedAt: "\u505C\u4E8E {{time}}",
16481
- queued: "\u6392\u7740",
16482
- dateLocale: "zh-CN",
16483
- queuedTitle: "\u5DF2\u6D3E\u3001\u8FD8\u6CA1\u53EB\u9192\uFF1A\u7B49\u5BF9\u65B9\u624B\u4E0A\u90A3\u4EF6\u505A\u5B8C\u518D\u53EB",
16484
- blockedBy: "\u88AB {{count}} \u4EF6\u6321\u7740",
16485
- noMembers: "\u8FD8\u6CA1\u6709\u53EF\u4EE5\u6307\u6D3E\u7684\u6210\u5458\uFF0C\u8BF7\u5148\u5728\u300C\u6210\u5458\u300D\u91CC\u6DFB\u52A0\u3002",
16486
- membersUnavailable: "\u672A\u80FD\u8BFB\u53D6\u6210\u5458\uFF0C\u6682\u65F6\u4E0D\u80FD\u6307\u6D3E\u3002\u8BF7\u91CD\u65B0\u8F7D\u5165\u770B\u677F\u3002",
16487
- loading: "\u6B63\u5728\u8F7D\u5165\u770B\u677F\u2026",
16488
- loadFailed: "\u672A\u80FD\u8F7D\u5165\u770B\u677F\uFF0C\u8BF7\u91CD\u65B0\u8F7D\u5165\u3002",
16489
- watchFailed: "\u770B\u677F\u5B9E\u65F6\u66F4\u65B0\u6682\u4E0D\u53EF\u7528\uFF0C\u8BF7\u91CD\u65B0\u8F7D\u5165\u4EE5\u6062\u590D\u8BA2\u9605\u3002",
16490
- createFailed: "\u672A\u80FD\u521B\u5EFA\u5DE5\u4F5C\u9879\uFF0C\u8BF7\u7528\u540C\u4E00\u4E2A\u8BF7\u6C42\u91CD\u8BD5\u3002",
16491
- updateFailed: "\u672A\u80FD\u4FEE\u6539\u5DE5\u4F5C\u9879\uFF0C\u6B63\u5728\u91CD\u65B0\u8BFB\u53D6\u770B\u677F\u3002",
16492
- staleVersion: "\u5DE5\u4F5C\u9879\u5DF2\u88AB\u522B\u5904\u6539\u8FC7\uFF0C\u672C\u6B21\u4FEE\u6539\u5DF2\u9000\u56DE\uFF0C\u6B63\u5728\u91CD\u65B0\u8F7D\u5165\u770B\u677F\u3002",
16493
- memberUnavailable: "\u8FD9\u4E2A\u6210\u5458\u5DF2\u88AB\u79FB\u9664\u6216\u5DF2\u4E0D\u5B58\u5728\uFF0C\u6CA1\u6709\u6307\u6D3E\u6210\u529F\u3002\u8BF7\u9009\u62E9\u5176\u4ED6\u6210\u5458\u3002",
16494
- invalidTitle: "\u8BF7\u586B\u5199\u5DE5\u4F5C\u9879\u6807\u9898\u3002",
16495
- reload: "\u91CD\u65B0\u8F7D\u5165\u770B\u677F",
16496
- truncated: "\u5F53\u524D\u53EA\u663E\u793A\u8FD9\u4E2A\u9879\u76EE\u7684\u524D 500 \u4EF6\u5DE5\u4F5C\u9879\u3002",
16497
- teamTitle: "\u56E2\u961F\u770B\u677F",
16498
- lane: {
16499
- unlined: "\u6CA1\u5206\u7EBF",
16500
- archived: "\u5DF2\u5F52\u6863",
16501
- openTeam: "\u6253\u5F00\u56E2\u961F",
16502
- openTeamFor: "\u6253\u5F00\u56E2\u961F\u300C{{name}}\u300D"
16503
- },
16504
- noTeamHint: "\u8981\u5F00\u56E2\u961F\uFF0C\u5148\u5728\u4F1A\u8BDD\u91CC\u8C08\u59A5\uFF0C\u518D\u7531 agent \u5728\u4F1A\u8BDD\u91CC\u5F00\u56E2\u961F\u3002"
16070
+ untitled: "\uFF08\u65E0\u6807\u9898\uFF09"
16505
16071
  },
16506
16072
  detail: {
16507
- title: "\u5DE5\u4F5C\u9879\u8BE6\u60C5",
16508
16073
  open: "\u8BE6\u60C5",
16509
- openItem: "\u6253\u5F00\u5DE5\u4F5C\u9879 #{{number}} \u7684\u8BE6\u60C5",
16510
- close: "\u5173\u95ED",
16511
- via: "\u7ECF{{source}}",
16512
- description: "\u8BF4\u660E",
16513
- noDescription: "\uFF08\u6CA1\u6709\u8BF4\u660E\uFF09",
16514
- blockedBy: "\u88AB\u8FD9\u4E9B\u6321\u7740",
16515
- blocking: "\u6321\u7740\u8FD9\u4E9B",
16516
- dependency: "#{{number}} {{title}}\uFF0C{{state}}",
16517
- comments: "\u8BC4\u8BBA",
16518
- noComments: "\u8FD8\u6CA1\u6709\u8BC4\u8BBA",
16519
- deletedComment: "\uFF08\u8FD9\u6761\u8BC4\u8BBA\u5DF2\u5220\u9664\uFF09",
16520
- commentsTruncated: "\u53EA\u663E\u793A\u6700\u8FD1 200 \u6761\u8BC4\u8BBA\uFF08\u542B\u56DE\u590D\uFF09\u3002",
16521
- reply: "\u56DE\u590D",
16522
- replyTo: "\u56DE\u590D\u7B2C {{number}} \u6761\u8BC4\u8BBA",
16523
- newComment: "\u53D1\u8868\u8BC4\u8BBA",
16524
- commentHint: "\u8981\u53EB\u9192\u6210\u5458\uFF0C\u7528\u300C\u63D0\u53CA\u2026\u300D\u9009\u62E9\u5B83\uFF08\u6216\u8F93\u5165 @\uFF09\uFF0C\u6216\u5728\u5B83\u7684\u8BC4\u8BBA\u4E0B\u70B9\u300C\u56DE\u590D\u300D\uFF1B\u5728\u6307\u6D3E\u7ED9\u8FDC\u7AEF\u6210\u5458\u3001\u8FD8\u6CA1\u7ED3\u675F\u7684\u5DE5\u4F5C\u9879\u4E0A\u8BC4\u8BBA\u4E5F\u4F1A\u53EB\u9192\u5B83\u3002",
16525
- mention: "\u63D0\u53CA\u2026",
16526
- mentionLabel: "\u63D0\u53CA\u6210\u5458\uFF08{{comment}}\uFF09",
16527
- mentionMember: "\u63D0\u53CA {{name}}\uFF08{{comment}}\uFF09",
16528
- mentionMemberSelected: "{{name}}\uFF08\u5DF2\u63D0\u53CA\uFF09\uFF08{{comment}}\uFF09",
16529
- mentionSelected: "{{name}}\uFF08\u5DF2\u63D0\u53CA\uFF09",
16530
- mentionRemove: "\u79FB\u9664\u5BF9 {{name}} \u7684\u63D0\u53CA\uFF08{{comment}}\uFF09",
16531
- mentionNone: "\u5148\u5F00\u59CB\u4E00\u4E2A\u76EE\u6807\uFF0C\u624D\u80FD\u63D0\u53CA\u6210\u5458\u3002",
16532
- mentionNoneLabel: "\u5148\u5F00\u59CB\u4E00\u4E2A\u76EE\u6807\uFF0C\u624D\u80FD\u63D0\u53CA\u6210\u5458\uFF08{{comment}}\uFF09",
16533
- mentioned: "\u63D0\u53CA\uFF1A{{names}}",
16534
- mentionSeparator: "\u3001",
16535
- notAMember: "\u88AB\u63D0\u53CA\u7684\u6210\u5458\u91CC\u6709\u4EBA\u4E0D\u5728\u5F53\u524D\u76EE\u6807\u4E2D\uFF0C\u8BF7\u79FB\u9664\u540E\u91CD\u8BD5\u3002",
16536
- send: "\u53D1\u9001",
16537
- sendComment: "\u53D1\u9001\u8BC4\u8BBA",
16538
- sendReply: "\u53D1\u9001\u7B2C {{number}} \u6761\u8BC4\u8BBA\u7684\u56DE\u590D",
16539
- sending: "\u53D1\u9001\u4E2D\u2026",
16540
- retry: "\u91CD\u8BD5",
16541
- retryComment: "\u91CD\u8BD5\u8BC4\u8BBA",
16542
- retryReply: "\u91CD\u8BD5\u7B2C {{number}} \u6761\u8BC4\u8BBA\u7684\u56DE\u590D",
16543
- invalidBody: "\u8BC4\u8BBA\u53BB\u6389\u9996\u5C3E\u7A7A\u767D\u540E\u9700\u4E3A 1 \u5230 8000 \u4E2A\u5B57\u7B26\u3002",
16544
- commentFailed: "\u8BC4\u8BBA\u6CA1\u53D1\u51FA\u53BB\uFF0C\u53EF\u4EE5\u91CD\u8BD5\u3002",
16545
- loading: "\u6B63\u5728\u8F7D\u5165\u5DE5\u4F5C\u9879\u8BE6\u60C5\u2026",
16546
- loadFailed: "\u672A\u80FD\u8F7D\u5165\u5DE5\u4F5C\u9879\u8BE6\u60C5\uFF0C\u8BF7\u91CD\u65B0\u8F7D\u5165\u3002",
16547
- reload: "\u91CD\u65B0\u8F7D\u5165\u8BE6\u60C5",
16548
- notFound: "\u8FD9\u4E2A\u9879\u76EE\u4E2D\u627E\u4E0D\u5230\u8FD9\u4EF6\u5DE5\u4F5C\u9879\u3002",
16549
16074
  actor: {
16550
16075
  you: "\u4F60",
16551
16076
  human: "\u4EBA",
@@ -16554,24 +16079,7 @@ var zh_CN_default = {
16554
16079
  plugin: "\u63D2\u4EF6 {{pluginId}}",
16555
16080
  localCli: "\u672C\u673A\u547D\u4EE4\u884C",
16556
16081
  system: "\u7CFB\u7EDF",
16557
- remoteAgentFallback: "\u8FDC\u7AEF agent"
16558
- },
16559
- history: {
16560
- title: "\u6D3B\u52A8\u5386\u53F2",
16561
- empty: "\u8FD8\u6CA1\u6709\u6D3B\u52A8\u5386\u53F2",
16562
- truncated: "\u53EA\u663E\u793A\u6700\u8FD1 200 \u6761\u6D3B\u52A8\u3002",
16563
- deletedState: "\uFF08\u5DF2\u5220\u9664\u7684\u72B6\u6001\uFF09",
16564
- created: "{{author}} \u5EFA\u4E86\u8FD9\u4EF6\u6D3B",
16565
- createdAssigned: "{{author}} \u5EFA\u4E86\u8FD9\u4EF6\u6D3B\uFF0C\u6307\u6D3E\u7ED9 {{names}}",
16566
- stateChanged: "{{author}} \u628A\u72B6\u6001\u4ECE {{old}} \u6539\u6210 {{new}}",
16567
- assigned: "{{author}} \u6307\u6D3E\u7ED9 {{names}}",
16568
- unassigned: "{{author}} \u53D6\u6D88\u4E86\u6307\u6D3E",
16569
- titleChanged: "{{author}} \u6539\u4E86\u6807\u9898",
16570
- descriptionChanged: "{{author}} \u6539\u4E86\u8BF4\u660E",
16571
- claimed: "{{author}} \u9886\u4E86\u8FD9\u4EF6\u6D3B",
16572
- commented: "{{author}} \u53D1\u4E86\u4E00\u6761\u8BC4\u8BBA",
16573
- relationAdded: "{{author}} \u52A0\u4E86\u4E00\u6761\u4F9D\u8D56",
16574
- relationRemoved: "{{author}} \u53BB\u6389\u4E86\u4E00\u6761\u4F9D\u8D56"
16082
+ remoteAgentFallback: "\u53E6\u4E00\u53F0\u673A\u5668"
16575
16083
  }
16576
16084
  },
16577
16085
  goal: {
@@ -16579,7 +16087,7 @@ var zh_CN_default = {
16579
16087
  lead: "\u8D1F\u8D23\u4EBA\uFF1A{{name}}",
16580
16088
  unknownLead: "\u8FD9\u540D\u6210\u5458\u5DF2\u4E0D\u5728\u56E2\u961F\u91CC",
16581
16089
  openLead: "\u6253\u5F00\u8D1F\u8D23\u4EBA\u4F1A\u8BDD",
16582
- remoteMembers: "\u8FDC\u7AEF\u6210\u5458\uFF1A",
16090
+ remoteMembers: "\u522B\u7684\u673A\u5668\u4E0A\u7684\u6210\u5458\uFF1A",
16583
16091
  item: "\u76EE\u6807\u5DE5\u4F5C\u9879 #{{number}}\uFF1A{{state}}",
16584
16092
  openItem: "\u6253\u5F00\u76EE\u6807\u5DE5\u4F5C\u9879 #{{number}} \u7684\u8BE6\u60C5"
16585
16093
  },
@@ -16606,7 +16114,6 @@ var zh_CN_default = {
16606
16114
  makeLeadFor: "\u5C06 {{name}} \u8BBE\u4E3A\u8D1F\u8D23\u4EBA",
16607
16115
  person: "\u4EBA",
16608
16116
  agent: "agent",
16609
- remote: "\u8FDC\u7AEF agent",
16610
16117
  edit: "\u7F16\u8F91",
16611
16118
  editFor: "\u7F16\u8F91 {{name}}",
16612
16119
  remove: "\u79FB\u9664",
@@ -16624,8 +16131,7 @@ var zh_CN_default = {
16624
16131
  restoredNotice: "\u5DF2\u6062\u590D\u6210\u5458\u3002",
16625
16132
  leadChosen: "\u5DF2\u9009\u5B9A\u8D1F\u8D23\u4EBA\u3002",
16626
16133
  kind: "\u7C7B\u578B",
16627
- kindAgentHint: "\u673A\u5668\u9009\u8FD9\u4E00\u53F0\u65F6\uFF0C\u7528\u4F60\u9009\u7684 provider \u548C\u6A21\u578B\u8FD0\u884C\u3002\u9009\u4E86\u522B\u7684\u673A\u5668\u7684\u6210\u5458\u8BD5\u8DD1\u4F1A\u51FA\u9519\uFF1A\u6539\u56DE\u8FD9\u4E00\u53F0\uFF0C\u6216\u8005\u8DF3\u8FC7\u8BD5\u8DD1\uFF0C\u5B83\u5C31\u5728\u8FD9\u53F0\u673A\u5668\u4E0A\u7528\u9879\u76EE\u7684\u9ED8\u8BA4\u6A21\u578B\u8FD0\u884C\u3002",
16628
- kindRemoteHint: "\u4ECE\u53E6\u4E00\u53F0\u673A\u5668\u7528\u81EA\u5DF1\u7684\u51ED\u636E\u8FDE\u8FDB\u6765\u7684 agent\u3002",
16134
+ kindAgentHint: "\u5728\u4F60\u9009\u7684\u673A\u5668\u4E0A\uFF0C\u7528\u90A3\u53F0\u673A\u5668\u7684 provider \u548C\u6A21\u578B\u8FD0\u884C\u3002\u522B\u7684\u673A\u5668\u52A0\u8FDB\u8FD9\u4E2A\u9879\u76EE\u540E\u624D\u4F1A\u51FA\u73B0\u5728\u8FD9\u91CC\u3002",
16629
16135
  kindPersonHint: "\u4EBA\u4F1A\u5217\u5728\u6210\u5458\u91CC\uFF0C\u4F46\u4E0D\u4F1A\u8FD0\u884C\u4F1A\u8BDD\u3002",
16630
16136
  thisIsMe: "\u8FD9\u662F\u6211",
16631
16137
  thisIsMeHint: "\u6709\u4EBA\u5728\u56E2\u961F\u7FA4\u91CC @ \u8FD9\u4E2A\u6210\u5458\u65F6\uFF0C\u6D88\u606F\u4F1A\u8FDB\u4F60\u7684\u300C\u53D1\u7ED9\u6211\u7684\u300D\u3002",
@@ -16654,20 +16160,14 @@ var zh_CN_default = {
16654
16160
  providersFailed: "\u672A\u80FD\u8BFB\u53D6\u8FD9\u53F0\u673A\u5668\u4E0A\u7684 provider\u3002",
16655
16161
  noProviders: "\u8FD9\u53F0\u673A\u5668\u4E0A\u6CA1\u6709\u53EF\u7528\u7684 provider\u3002",
16656
16162
  modelsFailed: "\u672A\u80FD\u8BFB\u53D6\u8FD9\u4E2A provider \u7684\u6A21\u578B\u3002",
16657
- remoteAgent: "\u8FDC\u7AEF agent",
16658
- chooseRemote: "\u9009\u62E9\u8FDC\u7AEF agent",
16659
- remoteBound: "\u8FDC\u7AEF agent\uFF1A{{label}}",
16660
- noRemoteAgents: "\u8FD9\u53F0\u673A\u5668\u4E0A\u8FD8\u6CA1\u6709\u53EF\u7528\u7684\u8FDC\u7AEF agent\u3002",
16661
- allRemoteAgentsAdded: "\u53EF\u7528\u7684\u8FDC\u7AEF agent \u90FD\u5DF2\u662F\u6210\u5458\u3002",
16662
- remoteAgentsUnavailable: "\u6682\u65F6\u8BFB\u4E0D\u51FA\u8FD9\u53F0\u673A\u5668\u4E0A\u7684\u8FDC\u7AEF agent\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5\u3002",
16663
16163
  save: "\u4FDD\u5B58",
16664
16164
  saving: "\u4FDD\u5B58\u4E2D\u2026",
16665
16165
  adding: "\u6B63\u5728\u6DFB\u52A0\u2026",
16666
16166
  problem: {
16667
16167
  memberCount: "\u56E2\u961F\u81F3\u5C11\u9700\u8981\u4E00\u540D agent \u6210\u5458\u3002",
16668
16168
  leadNotMember: "\u8BF7\u4ECE agent \u6210\u5458\u91CC\u9009\u4E00\u540D\u8D1F\u8D23\u4EBA\u3002",
16669
- leadRemote: "\u8D1F\u8D23\u4EBA\u5FC5\u987B\u662F\u672C\u673A\u6210\u5458\u3002",
16670
- duplicatePrincipal: "\u540C\u4E00\u4E2A\u8FDC\u7AEF agent \u53EA\u80FD\u662F\u4E00\u540D\u6210\u5458\u3002"
16169
+ leadRemote: "\u8D1F\u8D23\u4EBA\u5FC5\u987B\u5728\u8FD9\u53F0\u673A\u5668\u4E0A\u8FD0\u884C\u3002",
16170
+ duplicatePrincipal: "\u540C\u4E00\u53F0\u673A\u5668\u5728\u8FD9\u4EFD\u56E2\u961F\u540D\u5355\u91CC\u53EA\u80FD\u51FA\u73B0\u4E00\u6B21\u3002"
16671
16171
  },
16672
16172
  errors: {
16673
16173
  generic: "\u672A\u80FD\u4FDD\u5B58\u6539\u52A8\uFF0C\u8BF7\u91CD\u8BD5\u3002",
@@ -16678,7 +16178,7 @@ var zh_CN_default = {
16678
16178
  instanceNotFound: "\u8FD9\u4E2A\u9879\u76EE\u7684\u9ED8\u8BA4\u6A21\u578B\u6240\u5C5E\u7684 provider \u5B9E\u4F8B\u5728\u8FD9\u53F0\u673A\u5668\u4E0A\u4E0D\u5B58\u5728\u3002\u5230\u9879\u76EE\u8BBE\u7F6E\u7684\u300C\u65B0\u4F1A\u8BDD \u2192 \u6A21\u578B\u300D\u6362\u4E00\u4E2A\u3002",
16679
16179
  instanceUnavailable: "\u8FD9\u4E2A\u9879\u76EE\u9ED8\u8BA4\u6A21\u578B\u6240\u5C5E\u7684 provider \u5B9E\u4F8B\u5DF2\u505C\u7528\u6216\u5728\u8FD9\u53F0\u673A\u5668\u4E0A\u8DD1\u4E0D\u4E86\u3002\u68C0\u67E5\u4E00\u4E0B provider\uFF0C\u6216\u5230\u9879\u76EE\u8BBE\u7F6E\u7684\u300C\u65B0\u4F1A\u8BDD \u2192 \u6A21\u578B\u300D\u6362\u4E00\u4E2A\u3002",
16680
16180
  modelNotInCatalog: "\u8FD9\u4E2A\u9879\u76EE\u7684\u9ED8\u8BA4\u6A21\u578B\u4E0D\u5728\u5176 provider \u5B9E\u4F8B\u7684\u6A21\u578B\u6E05\u5355\u91CC\u3002\u5230\u9879\u76EE\u8BBE\u7F6E\u7684\u300C\u65B0\u4F1A\u8BDD \u2192 \u6A21\u578B\u300D\u6362\u4E00\u4E2A\u3002",
16681
- duplicateMember: "\u5DF2\u6709\u6210\u5458\u7528\u4E86\u8FD9\u4E2A\u540D\u5B57\u6216\u8FD9\u4E2A\u8FDC\u7AEF agent\uFF0C\u8BF7\u5148\u6539\u540D\u6216\u79FB\u9664\u5B83\u3002",
16181
+ duplicateMember: "\u5DF2\u6709\u6210\u5458\u7528\u4E86\u8FD9\u4E2A\u540D\u5B57\u6216\u7ED1\u7740\u8FD9\u4E2A\u4EBA\uFF0C\u8BF7\u5148\u6539\u540D\u6216\u79FB\u9664\u5B83\u3002",
16682
16182
  alreadyYou: "\u4F60\u5728\u540D\u518C\u4E0A\u5DF2\u7ECF\u662F\u300C{{name}}\u300D\u4E86\uFF0C\u8BF7\u5148\u5728\u300C{{name}}\u300D\u90A3\u91CC\u53D6\u6D88\u300C\u8FD9\u662F\u6211\u300D\u3002",
16683
16183
  staleVersion: "\u8FD9\u540D\u6210\u5458\u5DF2\u88AB\u522B\u5904\u6539\u8FC7\uFF0C\u5DF2\u91CD\u65B0\u8F7D\u5165\u3002\u8BF7\u786E\u8BA4\u540E\u518D\u4FDD\u5B58\u3002",
16684
16184
  notFound: "\u8FD9\u540D\u6210\u5458\u5DF2\u4E0D\u5B58\u5728\u3002",
@@ -16691,9 +16191,9 @@ var zh_CN_default = {
16691
16191
  importDuplicate: "\u5DF2\u6709\u540D\u4E3A {{name}} \u7684\u6210\u5458\uFF0C\u5BFC\u5165\u5DF2\u505C\u4E0B\u3002\u8BF7\u5148\u6539\u540D\u6216\u79FB\u9664\u5B83\uFF0C\u518D\u91CD\u65B0\u5BFC\u5165\u3002",
16692
16192
  importResume: "\u5DF2\u6DFB\u52A0\u7684\u6210\u5458\u4F1A\u4FDD\u7559\uFF0C\u518D\u6B21\u5BFC\u5165\u5373\u53EF\u7EE7\u7EED\u3002",
16693
16193
  nameRequired: "\u8BF7\u586B\u5199\u540D\u5B57\u3002",
16694
- remoteRequired: "\u8BF7\u9009\u62E9\u8FDC\u7AEF agent\u3002",
16695
16194
  modelRequired: "\u8BF7\u9009\u62E9 provider \u548C\u6A21\u578B\u3002",
16696
- instructionsTooLong: "\u5DE5\u4F5C\u8BF4\u660E\u592A\u957F\u4E86\u3002"
16195
+ instructionsTooLong: "\u5DE5\u4F5C\u8BF4\u660E\u592A\u957F\u4E86\u3002",
16196
+ machineMissing: "{{memberName}} \u539F\u6765\u6240\u5728\u7684\u673A\u5668\u8FD8\u6CA1\u52A0\u8FDB\u8FD9\u4E2A\u9879\u76EE\u3002\u5148\u628A\u90A3\u53F0\u673A\u5668\u52A0\u8FDB\u9879\u76EE\uFF0C\u518D\u5BFC\u5165\u3002"
16697
16197
  },
16698
16198
  legacy: {
16699
16199
  title: "\u8FD9\u4E2A\u9879\u76EE\u8FD8\u5728\u7528\u65E7\u540D\u5355",
@@ -16706,7 +16206,7 @@ var zh_CN_default = {
16706
16206
  trial: {
16707
16207
  passed: "\u8BD5\u8DD1\u901A\u8FC7",
16708
16208
  skipped: "\u5DF2\u8DF3\u8FC7\u8BD5\u8DD1",
16709
- remoteVerified: "\u8FDC\u7AEF\u8FDE\u901A\u5DF2\u9A8C\u8BC1",
16209
+ remoteVerified: "\u5DF2\u5728\u5B83\u7684\u673A\u5668\u4E0A\u9A8C\u8BC1",
16710
16210
  invoked: "\u8D1F\u8D23\u4EBA\u4F1A\u8BDD\uFF0C\u65E0\u9700\u8BD5\u8DD1",
16711
16211
  pending: "\u7B49\u5F85\u8BD5\u8DD1",
16712
16212
  running: "\u8BD5\u8DD1\u4E2D",
@@ -16714,7 +16214,7 @@ var zh_CN_default = {
16714
16214
  failed: "\u8BD5\u8DD1\u51FA\u9519",
16715
16215
  waiting: "\u7B49\u5BF9\u65B9\u53D6\u8D70\u3002",
16716
16216
  waitingSeen: "\u7B49\u5BF9\u65B9\u53D6\u8D70\uFF08\u6700\u540E\u8054\u7CFB {{time}}\uFF09\u3002",
16717
- remoteNote: "\u8FDC\u7AEF agent \u7528\u5B83\u5E2D\u4F4D\u81EA\u5DF1\u7684\u8BBE\u7F6E\u8FD0\u884C\uFF0C\u8FD9\u6B21\u8BD5\u8DD1\u53EA\u9A8C\u8BC1\u4E86\u8FDE\u901A\u548C\u5DE5\u5177\u8C03\u7528\u3002",
16217
+ remoteNote: "\u8BD5\u8DD1\u5728\u5B83\u81EA\u5DF1\u7684\u673A\u5668\u4E0A\u3001\u7528\u4E3A\u5B83\u9009\u7684\u6A21\u578B\u8FD0\u884C\uFF0C\u9A8C\u8BC1\u4E86\u8FDE\u901A\u3001\u5DE5\u5177\u8C03\u7528\u548C\u624B\u518C\u3002",
16718
16218
  failedDetail: "\u539F\u56E0\uFF1A{{category}}",
16719
16219
  failedWithText: "\u539F\u56E0\uFF1A{{category}}\uFF08{{detail}}\uFF09",
16720
16220
  failedSummary: "\u8BD5\u8DD1\u51FA\u9519\uFF1A{{count}}",
@@ -16736,15 +16236,18 @@ var zh_CN_default = {
16736
16236
  transport: "\u8FDE\u63A5\u65AD\u4E86",
16737
16237
  unknown: "\u672A\u5F52\u7C7B\u7684\u9519\u8BEF",
16738
16238
  timeout: "\u6CA1\u6709\u53CA\u65F6\u62A5\u56DE",
16739
- "no-route": "\u6CA1\u6709\u53EF\u7528\u7684\u673A\u5668\u6216\u8FDC\u7AEF\u51ED\u636E\uFF1B\u91CD\u65B0\u63A5\u5165\u8FD9\u4E2A\u8FDC\u7AEF agent\uFF0C\u6216\u4E3A\u6210\u5458\u9009\u4E00\u53F0\u673A\u5668\uFF0C\u7136\u540E\u91CD\u8BD5",
16740
- "other-machine": "\u5B83\u9009\u7684\u662F\u53E6\u4E00\u53F0\u673A\u5668\uFF0C\u8FD9\u53F0\u673A\u5668\u6CA1\u6CD5\u4E3A\u5B83\u8BD5\u8DD1\uFF1B\u6539\u56DE\u8FD9\u4E00\u53F0\uFF0C\u6216\u8005\u8DF3\u8FC7\u8BD5\u8DD1\uFF0C\u8BA9\u5B83\u5728\u8FD9\u53F0\u673A\u5668\u4E0A\u7528\u9879\u76EE\u7684\u9ED8\u8BA4\u6A21\u578B\u8FD0\u884C",
16239
+ "no-route": "\u5B83\u6240\u5728\u7684\u673A\u5668\u8FD8\u6CA1\u52A0\u8FDB\u8FD9\u4E2A\u9879\u76EE\uFF1B\u628A\u90A3\u53F0\u673A\u5668\u52A0\u8FDB\u9879\u76EE\uFF0C\u6216\u4E3A\u6210\u5458\u6362\u4E00\u53F0\u673A\u5668\uFF0C\u7136\u540E\u91CD\u8BD5",
16741
16240
  "start-failed": "\u8BD5\u8DD1\u6CA1\u80FD\u5F00\u59CB",
16742
16241
  "toolkit-off": "\u9879\u76EE\u7684\u770B\u677F\u548C\u9879\u76EE\u8BB0\u5FC6\u5F00\u5173\u6CA1\u6709\u540C\u65F6\u6253\u5F00\uFF0C\u6253\u5F00\u540E\u518D\u91CD\u8BD5"
16743
16242
  }
16744
16243
  },
16745
16244
  teams: "\u6240\u5C5E\u56E2\u961F\uFF1A{{names}}",
16746
16245
  remoteApprovals: "\u5BA1\u6279\u5728\u5BF9\u65B9\u673A\u5668\u5904\u7406",
16747
- teamsSeparator: "\u3001"
16246
+ teamsSeparator: "\u3001",
16247
+ thisMachine: "\u8FD9\u53F0\u673A\u5668",
16248
+ machineOffline: "{{name}}\uFF08\u79BB\u7EBF\uFF09",
16249
+ machineRemoved: "\u5DF2\u79FB\u51FA\u9879\u76EE\u7684\u673A\u5668",
16250
+ noMachine: "\u8FD8\u6CA1\u9009\u673A\u5668"
16748
16251
  },
16749
16252
  handbookPanel: {
16750
16253
  title: "\u624B\u518C",
@@ -16772,7 +16275,7 @@ var zh_CN_default = {
16772
16275
  restoredFrom: "\u9000\u56DE\u81EA\u7B2C {{version}} \u7248",
16773
16276
  moreReleases: "\u52A0\u8F7D\u66F4\u65E9\u7248\u672C",
16774
16277
  members: "\u6210\u5458\u786E\u8BA4\u60C5\u51B5",
16775
- noMembers: "\u8FD8\u6CA1\u6709\u6267\u884C\u6210\u5458\uFF0C\u4ECE\u4F1A\u8BDD\u5F00\u56E2\u961F\u540E\u624D\u6709\u56E2\u961F\u5E2D\u4F4D",
16278
+ noMembers: "\u8FD8\u6CA1\u6709\u6267\u884C\u6210\u5458\uFF0C\u4ECE\u4F1A\u8BDD\u5F00\u56E2\u961F\u540E\u624D\u6709\u56E2\u961F\u6210\u5458",
16776
16279
  member: "\u6210\u5458 {{id}}",
16777
16280
  neverAck: "\u8FD8\u6CA1\u6709\u786E\u8BA4\u8FC7\u624B\u518C",
16778
16281
  acked: "\u5DF2\u786E\u8BA4\u5230\u7B2C {{version}} \u7248",
@@ -16805,21 +16308,20 @@ var zh_CN_default = {
16805
16308
  discard: "\u653E\u5F03\u4FEE\u6539"
16806
16309
  },
16807
16310
  remoteStatus: {
16808
- title: "\u8FDC\u7AEF\u6210\u5458",
16311
+ title: "\u5728\u522B\u7684\u673A\u5668\u4E0A\u7684\u6210\u5458",
16809
16312
  lastSeen: "\u6700\u8FD1\u6765\u8FC7\uFF1A{{time}}",
16810
16313
  neverSeen: "\u8FD8\u6CA1\u6765\u8FC7",
16811
16314
  workUnavailable: "\u6682\u65F6\u8BFB\u4E0D\u51FA\u5B83\u624B\u4E0A\u7684\u6D3B\uFF0C\u8BF7\u7A0D\u540E\u518D\u8BD5\u3002",
16812
16315
  noWork: "\u624B\u4E0A\u6CA1\u6709\u6D3B\u3002",
16813
16316
  item: "#{{number}} {{title}}",
16814
- disabled: "\u5DF2\u505C\u7528",
16815
- revoked: "\u6CA1\u6709\u53EF\u7528\u51ED\u636E",
16816
16317
  lastSeenUnavailable: "\u6682\u65F6\u8BFB\u4E0D\u51FA\u6700\u8FD1\u6765\u8FC7\u7684\u65F6\u95F4",
16817
16318
  blocked: "\u88AB\u6321\u7740",
16818
- more: "\u8FD8\u6709 {{count}} \u4EF6\u6CA1\u5728\u8FD9\u91CC\u5217\u51FA"
16319
+ more: "\u8FD8\u6709 {{count}} \u4EF6\u6CA1\u5728\u8FD9\u91CC\u5217\u51FA",
16320
+ machineMissing: "\u5B83\u6240\u5728\u7684\u673A\u5668\u8FD8\u6CA1\u52A0\u8FDB\u8FD9\u4E2A\u9879\u76EE"
16819
16321
  },
16820
16322
  trial: {
16821
16323
  localPrompt: '\u8FD9\u662F\u4F60\u4F5C\u4E3A\u8FD9\u4E2A\u9879\u76EE\u56E2\u961F\u6210\u5458\u7684\u8BD5\u8DD1\u3002\u5B83\u53EA\u68C0\u67E5\u4F60\u80FD\u4E0D\u80FD\u7528\u4E0A\u56E2\u961F\u7684\u5DE5\u5177\u3001\u8BFB\u5230\u56E2\u961F\u7684\u624B\u518C\uFF0C\u6240\u4EE5\u4E0D\u8981\u6539\u4EFB\u4F55\u6587\u4EF6\uFF0C\u4E5F\u4E0D\u8981\u5F00\u59CB\u522B\u7684\u5DE5\u4F5C\u3002\u7167\u4E0B\u9762\u505A\u5B8C\u5C31\u505C\u30021. \u4E0D\u5E26\u53C2\u6570\u8C03\u7528 wiki_read_handbook\u3002\u8FD4\u56DE\u91CC\u6709 head \u5C31\u8BB0\u4E0B head.current.release\uFF08\u4E00\u4E2A\u6570\u5B57\uFF09\uFF1Bhead \u662F null \u8BF4\u660E\u9879\u76EE\u8FD8\u6CA1\u6709\u624B\u518C\u30022. \u8C03\u7528 team_trial_done\uFF0CtrialId \u586B "{{trialId}}"\uFF1B\u8BFB\u5230\u4E86\u7248\u672C\u53F7\u5C31\u628A release \u8BBE\u6210\u8FD9\u4E2A\u6570\u5B57\uFF08head \u662F null \u65F6\u4E0D\u8981\u586B release\uFF09\u3002\u53EA\u62A5\u4F60\u771F\u8BFB\u5230\u7684\uFF1A\u6CA1\u8BFB\u8FC7\u7684\u7248\u672C\u53F7\u4F1A\u88AB\u62D2\u7EDD\u3002',
16822
- remotePrompt: '\u8FD9\u662F\u4F60\u4F5C\u4E3A\u8FD9\u4E2A\u9879\u76EE\u56E2\u961F\u6210\u5458\u7684\u8BD5\u8DD1\u3002\u5B83\u53EA\u68C0\u67E5\u4F60\u7684\u5E2D\u4F4D\u80FD\u4E0D\u80FD\u7528\u4E0A\u56E2\u961F\u7684\u5DE5\u5177\u3001\u8BFB\u5230\u56E2\u961F\u7684\u624B\u518C\uFF0C\u6240\u4EE5\u4E0D\u8981\u4E3A\u5B83\u5F00\u59CB\u4EFB\u4F55\u5DE5\u4F5C\u9879\u3002\u7167\u4E0B\u9762\u505A\u5B8C\u5C31\u505C\u30021. \u8C03\u7528 team_trial_started\uFF0CtrialId \u586B "{{trialId}}"\u30022. \u4E0D\u5E26\u53C2\u6570\u8C03\u7528 wiki_read_handbook\u3002\u8FD4\u56DE\u91CC\u6709 head \u5C31\u8BB0\u4E0B head.current.release\uFF08\u4E00\u4E2A\u6570\u5B57\uFF09\uFF1Bhead \u662F null \u8BF4\u660E\u9879\u76EE\u8FD8\u6CA1\u6709\u624B\u518C\u30023. \u8C03\u7528 team_trial_done\uFF0CtrialId \u586B "{{trialId}}"\uFF1B\u8BFB\u5230\u4E86\u7248\u672C\u53F7\u5C31\u628A release \u8BBE\u6210\u8FD9\u4E2A\u6570\u5B57\uFF08head \u662F null \u65F6\u4E0D\u8981\u586B release\uFF09\u3002\u53EA\u62A5\u4F60\u771F\u8BFB\u5230\u7684\uFF1A\u6CA1\u8BFB\u8FC7\u7684\u7248\u672C\u53F7\u4F1A\u88AB\u62D2\u7EDD\u3002',
16324
+ remotePrompt: '\u8FD9\u662F\u4F60\u4F5C\u4E3A\u8FD9\u4E2A\u9879\u76EE\u56E2\u961F\u6210\u5458\u7684\u8BD5\u8DD1\u3002\u5B83\u53EA\u68C0\u67E5\u4F60\u80FD\u4E0D\u80FD\u7528\u4E0A\u56E2\u961F\u7684\u5DE5\u5177\u3001\u8BFB\u5230\u56E2\u961F\u7684\u624B\u518C\uFF0C\u6240\u4EE5\u4E0D\u8981\u4E3A\u5B83\u5F00\u59CB\u4EFB\u4F55\u5DE5\u4F5C\u9879\u3002\u7167\u4E0B\u9762\u505A\u5B8C\u5C31\u505C\u30021. \u8C03\u7528 team_trial_started\uFF0CtrialId \u586B "{{trialId}}"\u30022. \u4E0D\u5E26\u53C2\u6570\u8C03\u7528 wiki_read_handbook\u3002\u8FD4\u56DE\u91CC\u6709 head \u5C31\u8BB0\u4E0B head.current.release\uFF08\u4E00\u4E2A\u6570\u5B57\uFF09\uFF1Bhead \u662F null \u8BF4\u660E\u9879\u76EE\u8FD8\u6CA1\u6709\u624B\u518C\u30023. \u8C03\u7528 team_trial_done\uFF0CtrialId \u586B "{{trialId}}"\uFF1B\u8BFB\u5230\u4E86\u7248\u672C\u53F7\u5C31\u628A release \u8BBE\u6210\u8FD9\u4E2A\u6570\u5B57\uFF08head \u662F null \u65F6\u4E0D\u8981\u586B release\uFF09\u3002\u53EA\u62A5\u4F60\u771F\u8BFB\u5230\u7684\uFF1A\u6CA1\u8BFB\u8FC7\u7684\u7248\u672C\u53F7\u4F1A\u88AB\u62D2\u7EDD\u3002',
16823
16325
  startedTool: "\u62A5\u544A\u4F60\u5DF2\u7ECF\u63A5\u4E0B\u4E00\u6B21\u8BD5\u8DD1\u3002trialId \u7528\u8BD5\u8DD1\u6D88\u606F\u91CC\u7ED9\u7684\u90A3\u4E2A\u3002\u8BD5\u8DD1\u53EA\u68C0\u67E5\u4F60\u80FD\u4E0D\u80FD\u7528\u4E0A\u56E2\u961F\u7684\u5DE5\u5177\u3001\u8BFB\u5230\u56E2\u961F\u7684\u624B\u518C\u3002",
16824
16326
  doneTool: "\u5B8C\u6210\u4E00\u6B21\u8BD5\u8DD1\uFF1A\u62A5\u56DE\u4F60\u7528 wiki_read_handbook \u8BFB\u5230\u7684\u624B\u518C\u7248\u672C\u53F7\uFF08\u9879\u76EE\u8FD8\u6CA1\u6709\u624B\u518C\u65F6\u4E0D\u586B release\uFF09\u3002trialId \u7528\u8BD5\u8DD1\u6D88\u606F\u91CC\u7ED9\u7684\u90A3\u4E2A\u3002\u5BBF\u4E3B\u4F1A\u6838\u5B9E\u8C01\u5728\u8C03\u7528\uFF1B\u5BF9\u5DF2\u88AB\u66FF\u6362\u3001\u5DF2\u7ED3\u675F\u6216\u4E0D\u662F\u53D1\u7ED9\u4F60\u7684\u8BD5\u8DD1\u7684\u62A5\u544A\u4F1A\u88AB\u62D2\u7EDD\u3002",
16825
16327
  retryTool: "\u4EE5\u5F53\u524D\u76EE\u6807\u8D1F\u8D23\u4EBA\u7684\u8EAB\u4EFD\uFF0C\u4E3A agent \u6210\u5458\u8981\u6C42\u518D\u8BD5\u8DD1\u4E00\u6B21\uFF0C\u4F8B\u5982\u4E0A\u4E00\u6B21\u8BD5\u8DD1\u5931\u8D25\u6216\u4E00\u76F4\u6CA1\u5B8C\u6210\u65F6\u3002\u5DF2\u7ECF\u5728\u6392\u961F\u6216\u6B63\u5728\u8DD1\u7684\u8BD5\u8DD1\u4E0D\u4F1A\u518D\u52A0\u4E00\u6B21\uFF0C\u4F1A\u5982\u5B9E\u544A\u8BC9\u4F60\u3002\u7528 team_update_member \u6539\u8FD9\u4E2A\u6210\u5458\u7684 provider \u6216\u6A21\u578B\uFF0C\u4E5F\u4F1A\u81EA\u52A8\u5F00\u59CB\u65B0\u7684\u8BD5\u8DD1\u3002",
@@ -16836,7 +16338,7 @@ var zh_CN_default = {
16836
16338
  retryReady: "\u8FD9\u4E2A\u6210\u5458\u5DF2\u5C31\u7EEA\uFF1A\u5B83\u7684\u8BD5\u8DD1\u901A\u8FC7\u4E86\uFF0C\u6216\u6709\u4EBA\u8DF3\u8FC7\u4E86\u5B83\uFF0C\u6240\u4EE5\u6CA1\u6709\u8981\u91CD\u8BD5\u7684\u3002\u7528 team_update_member \u6539\u5B83\u7684 provider \u6216\u6A21\u578B\uFF0C\u4F1A\u81EA\u52A8\u5F00\u59CB\u65B0\u7684\u8BD5\u8DD1\u3002",
16837
16339
  retryFutile: "\u8FD9\u91CC\u518D\u8BD5\u4E00\u6B21\u4E5F\u6CA1\u6709\u7528\uFF1A\u8FD9\u4E2A\u6210\u5458\u7684\u8BD5\u8DD1\u5728\u540C\u6837\u7684\u8BBE\u7F6E\u4E0B\u8FDE\u7740\u5931\u8D25\u4E86 {{limit}} \u6B21\uFF0C\u6216\u8005\u5931\u8D25\u7684\u539F\u56E0\u8981\u6539\u4E86\u4EC0\u4E48\u624D\u4F1A\u597D\u3002\u7528 team_update_member \u6539\u5B83\u7684 provider \u6216\u6A21\u578B\uFF0C\u6216\u8005\u7528 send_message \u5199\u7ED9\u4EBA\uFF0C\u8BF4\u660E\u51FA\u4E86\u4EC0\u4E48\u95EE\u9898\uFF0C\u8BF7\u4ED6\u4FEE\u597D\uFF0C\u6216\u8005\u5728\u56E2\u961F\u9875\u8DF3\u8FC7\u8FD9\u6B21\u8BD5\u8DD1\u3002",
16838
16340
  failedForLeadNoRetry: "{{name}}\uFF08memberId {{memberId}}\uFF09\u7684\u8BD5\u8DD1\u5931\u8D25\uFF1A{{reason}}\u3002\u8BD5\u8DD1\u901A\u8FC7\u4E4B\u524D\uFF0C{{name}} \u4E0D\u4F1A\u6536\u5230\u4EFB\u4F55\u6D3B\uFF0C\u800C\u4E14\u5728\u6709\u4E1C\u897F\u6539\u53D8\u4E4B\u524D\uFF0C\u518D\u8BD5\u4E00\u6B21\u4E5F\u4E0D\u4F1A\u597D\u3002\u4F60\u53EF\u4EE5\uFF1A\u7528 team_update_member \u6539\u5B83\u7684 provider \u6216\u6A21\u578B\uFF08\u4F1A\u81EA\u52A8\u5F00\u59CB\u65B0\u7684\u8BD5\u8DD1\uFF09\uFF1B\u6216\u8005\u7528 send_message \u5199\u7ED9\u4EBA\uFF0C\u8BF4\u660E\u51FA\u4E86\u4EC0\u4E48\u95EE\u9898\uFF0C\u8BF7\u4ED6\u4FEE\u597D\uFF0C\u6216\u8005\u5728\u56E2\u961F\u9875\u8DF3\u8FC7\u8FD9\u6B21\u8BD5\u8DD1\u3002",
16839
- waitingForLead: "{{name}}\uFF08memberId {{memberId}}\uFF09\u7684\u8BD5\u8DD1\u5DF2\u7ECF\u53D1\u51FA {{minutes}} \u5206\u949F\uFF0C\u8FDC\u7AEF agent \u8FD8\u6CA1\u6709\u53D6\u8D70\u3002{{name}} \u53EF\u80FD\u4E0D\u5728\u7EBF\u6216\u6CA1\u6709\u767B\u5F55\u3002\u5728\u5B83\u53D6\u8D70\u8BD5\u8DD1\u4E4B\u524D\uFF0C\u6D3E\u7ED9 {{name}} \u7684\u6D3B\u4E0D\u4F1A\u5F00\u59CB\u3002\u4F60\u53EF\u4EE5\uFF1A\u5148\u628A\u6D3B\u6D3E\u7ED9\u522B\u7684\u6210\u5458\uFF1B\u6216\u8005\u7528 send_message \u5199\u7ED9\u4EBA\uFF0C\u8BF7\u4ED6\u770B\u770B\u8FD9\u4E2A\u8FDC\u7AEF agent \u6709\u6CA1\u6709\u5728\u8FD0\u884C\uFF0C\u6216\u8005\u5728\u56E2\u961F\u9875\u8DF3\u8FC7\u8FD9\u6B21\u8BD5\u8DD1\u3002",
16341
+ waitingForLead: "{{name}}\uFF08memberId {{memberId}}\uFF09\u7684\u8BD5\u8DD1\u5DF2\u7ECF\u53D1\u51FA {{minutes}} \u5206\u949F\uFF0C\u5B83\u6240\u5728\u7684\u673A\u5668\u8FD8\u6CA1\u6709\u53D6\u8D70\u3002\u90A3\u53F0\u673A\u5668\u53EF\u80FD\u4E0D\u5728\u7EBF\uFF0C\u6216\u8005\u5B83\u7684 provider \u6CA1\u6709\u767B\u5F55\u3002\u5728\u8BD5\u8DD1\u88AB\u53D6\u8D70\u4E4B\u524D\uFF0C\u6D3E\u7ED9 {{name}} \u7684\u6D3B\u4E0D\u4F1A\u5F00\u59CB\u3002\u4F60\u53EF\u4EE5\uFF1A\u5148\u628A\u6D3B\u6D3E\u7ED9\u522B\u7684\u6210\u5458\uFF1B\u6216\u8005\u7528 send_message \u5199\u7ED9\u4EBA\uFF0C\u8BF7\u4ED6\u770B\u770B\u90A3\u53F0\u673A\u5668\uFF0C\u6216\u8005\u5728\u56E2\u961F\u9875\u8DF3\u8FC7\u8FD9\u6B21\u8BD5\u8DD1\u3002",
16840
16342
  failedHeadline: "\u8BD5\u8DD1\u51FA\u9519\uFF1A{{name}}\u3002",
16841
16343
  failedHeadlineAgain: "\u8BD5\u8DD1\u518D\u6B21\u51FA\u9519\uFF1A{{name}}\u3002",
16842
16344
  failedForPerson: "{{reason}}\u3002\u8BD5\u8DD1\u901A\u8FC7\u4E4B\u524D\uFF0C{{name}} \u4E0D\u4F1A\u6536\u5230\u4EFB\u4F55\u6D3B\u3002\u8BF7\u5148\u6392\u9664\u539F\u56E0\uFF0C\u7136\u540E\u5728\u56E2\u961F\u9875\u5BF9\u8FD9\u4E2A\u6210\u5458\u9009\u300C\u91CD\u65B0\u8BD5\u8DD1\u300D\uFF0C\u6216\u8005\u9009\u300C\u8DF3\u8FC7\u8BD5\u8DD1\u300D\u3002",
@@ -16850,8 +16352,7 @@ var zh_CN_default = {
16850
16352
  transport: "\u5230 provider \u7684\u8FDE\u63A5\u65AD\u4E86",
16851
16353
  unknown: "\u672A\u5F52\u7C7B\u7684\u9519\u8BEF",
16852
16354
  timeout: "\u6CA1\u6709\u53CA\u65F6\u62A5\u56DE",
16853
- "no-route": "\u6CA1\u6709\u53EF\u7528\u7684\u673A\u5668\u6216\u8FDC\u7AEF\u51ED\u636E\uFF08\u8981\u7531\u4EBA\u91CD\u65B0\u63A5\u5165\u8FD9\u4E2A\u8FDC\u7AEF agent\uFF0C\u6216\u4E3A\u6210\u5458\u9009\u4E00\u53F0\u673A\u5668\uFF09",
16854
- "other-machine": "\u5B83\u9009\u7684\u662F\u53E6\u4E00\u53F0\u673A\u5668\uFF0C\u8FD9\u53F0\u673A\u5668\u6CA1\u6CD5\u4E3A\u5B83\u8BD5\u8DD1\uFF08\u4EBA\u53EF\u4EE5\u628A\u5B83\u6539\u56DE\u8FD9\u4E00\u53F0\uFF0C\u6216\u8005\u8DF3\u8FC7\u8BD5\u8DD1\uFF0C\u8BA9\u5B83\u5728\u8FD9\u53F0\u673A\u5668\u4E0A\u7528\u9879\u76EE\u7684\u9ED8\u8BA4\u6A21\u578B\u8FD0\u884C\uFF09",
16355
+ "no-route": "\u5B83\u6240\u5728\u7684\u673A\u5668\u8FD8\u6CA1\u52A0\u8FDB\u8FD9\u4E2A\u9879\u76EE\uFF08\u8981\u7531\u4EBA\u628A\u90A3\u53F0\u673A\u5668\u52A0\u8FDB\u9879\u76EE\uFF0C\u6216\u4E3A\u6210\u5458\u6362\u4E00\u53F0\u673A\u5668\uFF09",
16855
16356
  "start-failed": "\u8BD5\u8DD1\u6CA1\u80FD\u5F00\u59CB",
16856
16357
  "toolkit-off": "\u9879\u76EE\u7684\u770B\u677F\u548C\u9879\u76EE\u8BB0\u5FC6\u5F00\u5173\u6CA1\u6709\u540C\u65F6\u6253\u5F00"
16857
16358
  },
@@ -17083,17 +16584,11 @@ var REJECTED_REASONS = /* @__PURE__ */ new Set(["rejected", ...CONFLICT_REASONS]
17083
16584
  var isRejection = (error) => REJECTED_REASONS.has(dataCommandReason(error) ?? "");
17084
16585
 
17085
16586
  // src/trial/dispatch.ts
17086
- async function remoteUsable(env, projectId, principalId) {
17087
- try {
17088
- const { items, truncated } = await readPages(
17089
- 500,
17090
- (page) => env.ctx.auth.remoteAgents.list({ projectId, ...page })
17091
- );
17092
- const found = items.find((row) => row.principalId === principalId);
17093
- return found === void 0 ? truncated ? null : false : found.state === "active";
17094
- } catch {
17095
- return null;
17096
- }
16587
+ async function remoteRoute(env, projectId, environmentId) {
16588
+ const machines = await readMachines(env.ctx, projectId);
16589
+ if (machines === null) return { kind: "unknown" };
16590
+ const machine = machines.get(environmentId);
16591
+ return machine === void 0 ? { kind: "missing" } : { kind: "found", principalId: machine.principalId };
17097
16592
  }
17098
16593
  async function toolkitsOn(env, projectId) {
17099
16594
  try {
@@ -17110,16 +16605,21 @@ async function dispatchTrial(env, record2, slots, ensured) {
17110
16605
  const { ctx } = env;
17111
16606
  const member = await findMember(ctx, record2.projectId, record2.memberId, { textLimit: 2 });
17112
16607
  if (!specMatches(member, record2)) return "stuck";
17113
- const principalId = member.identity?.kind === "remote-agent" ? member.identity.principalId : null;
17114
- const local = principalId === null && member.agent !== null && member.agent.environmentId === ctx.environment.id;
17115
- if (principalId === null && !local) {
17116
- await env.fail(record2, member.agent === null ? "no-route" : "other-machine", "");
16608
+ const local = member.agent !== null && !isRemoteMember(member, ctx.environment.id);
16609
+ if (member.agent === null) {
16610
+ await env.fail(record2, "no-route", "");
17117
16611
  return "done";
17118
16612
  }
17119
16613
  if (local && slots.local <= 0) return "wait";
17120
- if (principalId !== null && await remoteUsable(env, record2.projectId, principalId) === false) {
17121
- await env.fail(record2, "no-route", "");
17122
- return "done";
16614
+ let principalId = null;
16615
+ if (!local) {
16616
+ const route = await remoteRoute(env, record2.projectId, member.agent.environmentId);
16617
+ if (route.kind === "unknown") return "stuck";
16618
+ if (route.kind === "missing") {
16619
+ await env.fail(record2, "no-route", "");
16620
+ return "done";
16621
+ }
16622
+ principalId = route.principalId;
17123
16623
  }
17124
16624
  if (!await toolkitsOn(env, record2.projectId)) {
17125
16625
  await env.fail(record2, "toolkit-off", "");
@@ -17177,7 +16677,7 @@ async function ensureSession(env, record2, ensured, prepared) {
17177
16677
  await ctx.communication.records.send({
17178
16678
  projectId: record2.projectId,
17179
16679
  requestId: `team-trial-wake:${key}`,
17180
- to: { principalId: record2.principalId },
16680
+ to: { principalId: record2.principalId, memberId: record2.memberId },
17181
16681
  text: trialMessage("remotePrompt", { trialId }),
17182
16682
  delivery: "wake"
17183
16683
  });
@@ -17352,8 +16852,11 @@ async function tellWaiting(env, record2, told, minutes2) {
17352
16852
  if (await tellLeads(env, leadThreads, record2.projectId, key, text)) told.add(key);
17353
16853
  }
17354
16854
  async function tellReady(env, record2, told) {
17355
- const principalId = remotePrincipalOf(record2.spec.identity);
17356
- if (principalId === null) return;
16855
+ const environmentId = record2.spec.environmentId;
16856
+ if (environmentId === null || environmentId === env.ctx.environment.id) return;
16857
+ const machine = (await readMachines(env.ctx, record2.projectId))?.get(environmentId);
16858
+ if (machine === void 0) return;
16859
+ const { principalId } = machine;
17357
16860
  const key = `team-trial-ready:${stableHash(
17358
16861
  JSON.stringify([
17359
16862
  record2.projectId,
@@ -17366,11 +16869,13 @@ async function tellReady(env, record2, told) {
17366
16869
  if (told.has(key)) return;
17367
16870
  const pending = await env.ctx.work.remoteAgentPending.get({ projectId: record2.projectId, principalId }).catch(() => null);
17368
16871
  if (pending === null) return;
17369
- if (pending.work.items.some((item) => !item.blocked))
16872
+ if (pending.work.items.some(
16873
+ (item) => !item.blocked && (item.memberId === void 0 || item.memberId === record2.memberId)
16874
+ ))
17370
16875
  await env.ctx.communication.records.send({
17371
16876
  projectId: record2.projectId,
17372
16877
  requestId: key,
17373
- to: { principalId },
16878
+ to: { principalId, memberId: record2.memberId },
17374
16879
  text: trialMessage("readyForRemote"),
17375
16880
  delivery: "wake"
17376
16881
  });
@@ -17719,7 +17224,7 @@ function startTrialRuntime(ctx, deps, options = {}) {
17719
17224
  // src/index.ts
17720
17225
  var index_default = definePlugin({
17721
17226
  id: "team",
17722
- apiVersion: 51,
17227
+ apiVersion: 52,
17723
17228
  activate(ctx) {
17724
17229
  const trialState = ctx.derivedState(trialStateDefinition);
17725
17230
  const rosters = createRosterService(ctx);
@@ -17766,7 +17271,6 @@ var index_default = definePlugin({
17766
17271
  startCommentMentionRuntime(ctx, goals);
17767
17272
  startGroupDeliveryRuntime(ctx, wakes.state);
17768
17273
  registerBoardCommands(ctx, goals, rosters, wakes.state);
17769
- registerDetailCommands(ctx, goals, rosters);
17770
17274
  startRecoveryRuntime(ctx, goals, wakes.state, wakes.worktrees);
17771
17275
  startLeadCheckinRuntime(ctx, wakes.state, goals);
17772
17276
  startProgressCheckinRuntime(ctx, goals, wakes.state);