pi-roundtable 0.4.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +39 -11
  3. package/README.zh-TW.md +36 -15
  4. package/docs/plugins.md +259 -168
  5. package/examples/migrations.test.ts +1 -1
  6. package/examples/migrations.ts +2 -2
  7. package/package.json +8 -4
  8. package/src/cli/cli.ts +2 -0
  9. package/src/cli/main.ts +1 -0
  10. package/src/cli/project.ts +2 -0
  11. package/src/cli/runtime.ts +2 -2
  12. package/src/cli/templates.ts +10 -9
  13. package/src/core/agents/agent-prompt.ts +1 -2
  14. package/src/core/agents/agent-store.ts +1 -2
  15. package/src/core/agents/agent-team-fixture.ts +5 -3
  16. package/src/core/agents/fallback-avatar.ts +1 -0
  17. package/src/core/agents/group-messages.ts +1 -1
  18. package/src/core/agents/group-round.ts +10 -9
  19. package/src/core/agents/group-turns.ts +13 -8
  20. package/src/core/agents/team-layout.ts +13 -14
  21. package/src/core/agents/team-status.ts +8 -8
  22. package/src/core/agents/team-turns.ts +8 -9
  23. package/src/core/builtin/skills.ts +6 -1
  24. package/src/core/config/config.ts +4 -1
  25. package/src/core/define-roundtable.ts +19 -19
  26. package/src/core/define.ts +10 -10
  27. package/src/core/discord/channel-executor.ts +20 -18
  28. package/src/core/discord/channel-operations.ts +7 -3
  29. package/src/core/discord/inbound-message.ts +13 -11
  30. package/src/core/discord/owner-cards.ts +3 -3
  31. package/src/core/discord/owner-discord-threads.ts +16 -12
  32. package/src/core/discord/owner-discord.ts +5 -4
  33. package/src/core/host.ts +1 -0
  34. package/src/core/log.ts +1 -0
  35. package/src/core/modules/schedules/scheduler.ts +3 -0
  36. package/src/core/modules/skills/skill-link.ts +13 -8
  37. package/src/core/modules/skills/skill-listing.ts +2 -4
  38. package/src/core/modules/skills/skill-registry.ts +3 -2
  39. package/src/core/modules/skills/skill-store.ts +3 -2
  40. package/src/core/registry/contributions.ts +1 -1
  41. package/src/core/routing/conversation-turns.ts +2 -2
  42. package/src/core/routing/settle-turn.ts +8 -0
  43. package/src/core/runtime/compaction-tiers.ts +9 -10
  44. package/src/core/runtime/turn-answer.ts +10 -12
  45. package/src/core/shared/session-messages.ts +4 -4
  46. package/src/core/speakers.ts +4 -1
  47. package/src/core/tool-set.snapshot.json +5 -0
  48. package/templates/official/codex-images/plugin.ts +65 -57
  49. package/templates/official/dice/plugin.ts +70 -41
@@ -41,6 +41,8 @@ function removed(
41
41
  return ascending.slice(0, n);
42
42
  case "dh":
43
43
  return ascending.slice(rolls.length - n);
44
+ default:
45
+ return rule satisfies never;
44
46
  }
45
47
  }
46
48
 
@@ -51,49 +53,53 @@ interface Rolled {
51
53
  dice: number;
52
54
  }
53
55
 
54
- function rollTerm(term: string, random: Random): Rolled {
55
- if (/^\d+$/.test(term)) {
56
- if (term.length > 7 || Number(term) > MAX_MODIFIER)
57
- return refuse(`The number ${term} is over ${MAX_MODIFIER}.`);
58
- return { shown: String(Number(term)), value: Number(term), dice: 0 };
59
- }
60
- const match = TERM.exec(term);
61
- if (!match) return refuse(`"${term}" is not a dice term.`);
62
- const [, countText, fate, sidesText, rule, nText] = match;
63
- const count = countText ? Number(countText) : fate ? FATE_DEFAULT : 1;
64
- if (count < 1) return refuse(`"${term}" rolls no dice.`);
65
- if (count > MAX_DICE)
66
- return refuse(`"${term}" rolls more than ${MAX_DICE} dice.`);
67
- if (fate) {
68
- const faces = Array.from(
69
- { length: count },
70
- () => Math.floor(random() * 3) - 1,
71
- );
72
- const symbols = faces.map((face) =>
73
- face > 0 ? "+" : face < 0 ? "-" : "0",
74
- );
75
- return {
76
- shown: `[${symbols.join(", ")}]`,
77
- value: faces.reduce((sum, face) => sum + face, 0),
78
- dice: count,
79
- };
80
- }
81
- const sides = Number(sidesText);
56
+ /** A plain number term. */
57
+ function rollNumber(term: string): Rolled {
58
+ if (term.length > 7 || Number(term) > MAX_MODIFIER)
59
+ return refuse(`The number ${term} is over ${MAX_MODIFIER}.`);
60
+ return { shown: String(Number(term)), value: Number(term), dice: 0 };
61
+ }
62
+
63
+ /** How a fate die shows: + for 1, - for -1, and 0. */
64
+ function fateSymbol(face: number): string {
65
+ if (face > 0) return "+";
66
+ if (face < 0) return "-";
67
+ return "0";
68
+ }
69
+
70
+ /** `count` fate dice, each one of -1, 0, or +1. */
71
+ function rollFate(count: number, random: Random): Rolled {
72
+ const faces = Array.from(
73
+ { length: count },
74
+ () => Math.floor(random() * 3) - 1,
75
+ );
76
+ const symbols = faces.map(fateSymbol);
77
+ return {
78
+ shown: `[${symbols.join(", ")}]`,
79
+ value: faces.reduce((sum, face) => sum + face, 0),
80
+ dice: count,
81
+ };
82
+ }
83
+
84
+ /** `count` dice of `sides` sides, with an optional keep or drop rule that removes some of them. */
85
+ function rollPool(
86
+ term: string,
87
+ count: number,
88
+ sides: number,
89
+ rule: { kind: KeepDrop; n: number } | undefined,
90
+ random: Random,
91
+ ): Rolled {
82
92
  if (sides < 2 || sides > MAX_SIDES)
83
93
  return refuse(`"${term}" needs between 2 and ${MAX_SIDES} sides.`);
84
94
  const rolls = Array.from(
85
95
  { length: count },
86
96
  () => Math.floor(random() * sides) + 1,
87
97
  );
88
- const dropped = new Set<number>();
89
- if (rule) {
90
- const n = Number(nText);
91
- if (n < 1 || n >= count)
92
- return refuse(
93
- `"${term}" must keep or drop at least 1 and fewer than ${count} dice.`,
94
- );
95
- for (const index of removed(rolls, rule as KeepDrop, n)) dropped.add(index);
96
- }
98
+ if (rule && (rule.n < 1 || rule.n >= count))
99
+ return refuse(
100
+ `"${term}" must keep or drop at least 1 and fewer than ${count} dice.`,
101
+ );
102
+ const dropped = new Set(rule ? removed(rolls, rule.kind, rule.n) : []);
97
103
  const shown = rolls.map((value, index) =>
98
104
  dropped.has(index) ? `(${value})` : String(value),
99
105
  );
@@ -107,6 +113,31 @@ function rollTerm(term: string, random: Random): Rolled {
107
113
  };
108
114
  }
109
115
 
116
+ /** How many dice a term rolls: the count it writes, else 4 for fate dice and 1 for the rest. */
117
+ function diceCount(countText: string | undefined, fate: string | undefined) {
118
+ if (countText) return Number(countText);
119
+ return fate ? FATE_DEFAULT : 1;
120
+ }
121
+
122
+ function rollTerm(term: string, random: Random): Rolled {
123
+ if (/^\d+$/.test(term)) return rollNumber(term);
124
+ const match = TERM.exec(term);
125
+ if (!match) return refuse(`"${term}" is not a dice term.`);
126
+ const [, countText, fate, sidesText, rule, nText] = match;
127
+ const count = diceCount(countText, fate);
128
+ if (count < 1) return refuse(`"${term}" rolls no dice.`);
129
+ if (count > MAX_DICE)
130
+ return refuse(`"${term}" rolls more than ${MAX_DICE} dice.`);
131
+ if (fate) return rollFate(count, random);
132
+ return rollPool(
133
+ term,
134
+ count,
135
+ Number(sidesText),
136
+ rule ? { kind: rule as KeepDrop, n: Number(nText) } : undefined,
137
+ random,
138
+ );
139
+ }
140
+
110
141
  /**
111
142
  * Rolls an expression of dice terms and numbers joined by `+` and `-`, and writes the result as
112
143
  * text such as `2d6+3: [3, 5] + 3 = 11`. A term is `NdS`, an optional keep or drop rule
@@ -133,10 +164,8 @@ export function roll(expression: string, random: Random = Math.random): string {
133
164
  if (dice > MAX_DICE)
134
165
  return refuse(`The expression rolls more than ${MAX_DICE} dice in all.`);
135
166
  total += sign === "-" ? -rolled.value : rolled.value;
136
- line +=
137
- index === 0
138
- ? `${sign === "-" ? "-" : ""}${rolled.shown}`
139
- : ` ${sign} ${rolled.shown}`;
167
+ const lead = sign === "-" ? "-" : "";
168
+ line += index === 0 ? `${lead}${rolled.shown}` : ` ${sign} ${rolled.shown}`;
140
169
  }
141
170
  return `${compact}: ${line} = ${total}`;
142
171
  }