@ordewell/core 0.12.1 → 0.12.2

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.
@@ -5,6 +5,28 @@ import 'child_process';
5
5
  import 'zod/v4';
6
6
  import './ModeResolver-CA2fUU9h.mjs';
7
7
 
8
+ /**
9
+ * The tips an empty planner chat composer shows (#137), one table for every
10
+ * surface so the TUI and the webview agree on the wording and how often each
11
+ * comes round. A surface offers only the tips for the commands it answers.
12
+ */
13
+ interface ComposerTip {
14
+ /** The built-in planner chat command the tip names, without its slash. */
15
+ command: string;
16
+ /** How many times per cycle the tip comes round. */
17
+ weight: number;
18
+ /** Short enough to fit after the prompt and caret on an 80-column terminal. */
19
+ text: string;
20
+ }
21
+ declare const COMPOSER_TIPS: readonly ComposerTip[];
22
+ /**
23
+ * The tip for the `seq`-th time the composer has been empty, among those for
24
+ * the commands the surface answers, or null when it answers none of them. The
25
+ * same `seq` always gives the same tip, so the surface decides when a new one
26
+ * shows by when it moves `seq` on, and its rendering stays a function of state.
27
+ */
28
+ declare function composerTip(seq: number, answers: ReadonlySet<string>): string | null;
29
+
8
30
  /** A name or a path on a line of Ordewell's: as it stands, or quoted where it would break that line. */
9
31
  declare function onOneLine(text: string): string;
10
32
 
@@ -22,4 +44,4 @@ declare function clampThinkingEffort(effort: string | undefined, variants: {
22
44
  id: string;
23
45
  }[]): string | undefined;
24
46
 
25
- export { clampThinkingEffort, onOneLine };
47
+ export { COMPOSER_TIPS, type ComposerTip, clampThinkingEffort, composerTip, onOneLine };
@@ -5,6 +5,28 @@ import 'child_process';
5
5
  import 'zod/v4';
6
6
  import './ModeResolver-B64aUZXJ.js';
7
7
 
8
+ /**
9
+ * The tips an empty planner chat composer shows (#137), one table for every
10
+ * surface so the TUI and the webview agree on the wording and how often each
11
+ * comes round. A surface offers only the tips for the commands it answers.
12
+ */
13
+ interface ComposerTip {
14
+ /** The built-in planner chat command the tip names, without its slash. */
15
+ command: string;
16
+ /** How many times per cycle the tip comes round. */
17
+ weight: number;
18
+ /** Short enough to fit after the prompt and caret on an 80-column terminal. */
19
+ text: string;
20
+ }
21
+ declare const COMPOSER_TIPS: readonly ComposerTip[];
22
+ /**
23
+ * The tip for the `seq`-th time the composer has been empty, among those for
24
+ * the commands the surface answers, or null when it answers none of them. The
25
+ * same `seq` always gives the same tip, so the surface decides when a new one
26
+ * shows by when it moves `seq` on, and its rendering stays a function of state.
27
+ */
28
+ declare function composerTip(seq: number, answers: ReadonlySet<string>): string | null;
29
+
8
30
  /** A name or a path on a line of Ordewell's: as it stands, or quoted where it would break that line. */
9
31
  declare function onOneLine(text: string): string;
10
32
 
@@ -22,4 +44,4 @@ declare function clampThinkingEffort(effort: string | undefined, variants: {
22
44
  id: string;
23
45
  }[]): string | undefined;
24
46
 
25
- export { clampThinkingEffort, onOneLine };
47
+ export { COMPOSER_TIPS, type ComposerTip, clampThinkingEffort, composerTip, onOneLine };
@@ -31,6 +31,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var plan_utils_exports = {};
32
32
  __export(plan_utils_exports, {
33
33
  CHECKPOINT_TRUNCATE_LENGTH: () => CHECKPOINT_TRUNCATE_LENGTH,
34
+ COMPOSER_TIPS: () => COMPOSER_TIPS,
34
35
  DEFAULT_RUNNERS: () => DEFAULT_RUNNERS,
35
36
  DELEGATION_OFFERED: () => DELEGATION_OFFERED,
36
37
  EMPTY_CONVERSATION: () => EMPTY_CONVERSATION,
@@ -83,6 +84,7 @@ __export(plan_utils_exports, {
83
84
  clampThinkingEffort: () => clampThinkingEffort,
84
85
  closeTurn: () => closeTurn,
85
86
  compactionText: () => compactionText,
87
+ composerTip: () => composerTip,
86
88
  confirmedOverride: () => confirmedOverride,
87
89
  contextMeterText: () => contextMeterText,
88
90
  contextMeterTitle: () => contextMeterTitle,
@@ -1248,6 +1250,36 @@ function parseCount(arg, min) {
1248
1250
  return n >= min ? n : null;
1249
1251
  }
1250
1252
 
1253
+ // src/services/composerTips.ts
1254
+ var COMPOSER_TIPS = [
1255
+ // The per-runner model allowlist (ADR-0003) is the easiest command to miss.
1256
+ { command: "allowlist", weight: 3, text: "Tip: Use /allowlist to limit which models the planner assigns per runner." },
1257
+ { command: "planner", weight: 1, text: "Tip: Use /planner to pick the planner's harness, model and effort." },
1258
+ { command: "runners", weight: 1, text: "Tip: Use /runners to turn runners on or off." },
1259
+ { command: "settings", weight: 1, text: "Tip: Use /settings for autonomy, supervisor, merging, autorun and more." },
1260
+ { command: "help", weight: 1, text: "Tip: Use /help to list every command." }
1261
+ ];
1262
+ function tipCycle(tips) {
1263
+ const total = tips.reduce((sum, tip) => sum + Math.max(0, tip.weight), 0);
1264
+ if (total === 0) return [];
1265
+ const slots = new Array(total).fill(void 0);
1266
+ const order = tips.map((tip, index) => ({ tip, index })).filter(({ tip }) => tip.weight > 0).sort((a, b) => b.tip.weight - a.tip.weight || a.index - b.index);
1267
+ for (const { tip } of order) {
1268
+ const free = slots.flatMap((slot, at) => slot === void 0 ? [at] : []);
1269
+ for (let k = 0; k < tip.weight; k++) {
1270
+ slots[free[Math.floor((k + 0.5) * free.length / tip.weight)]] = tip;
1271
+ }
1272
+ }
1273
+ const cycle = slots.filter((tip) => tip !== void 0);
1274
+ const start = cycle.indexOf(order[0].tip);
1275
+ return [...cycle.slice(start), ...cycle.slice(0, start)];
1276
+ }
1277
+ function composerTip(seq, answers) {
1278
+ const cycle = tipCycle(COMPOSER_TIPS.filter((tip) => answers.has(tip.command)));
1279
+ if (cycle.length === 0) return null;
1280
+ return cycle[(seq % cycle.length + cycle.length) % cycle.length].text;
1281
+ }
1282
+
1251
1283
  // src/models/Usage.ts
1252
1284
  function partedPromptUsage(parts) {
1253
1285
  const reported2 = [parts.uncached, parts.cacheRead, parts.cacheWrite].filter((n) => n !== void 0);
@@ -3379,6 +3411,7 @@ function accountLimitsTitle(snapshot, time) {
3379
3411
  // Annotate the CommonJS export names for ESM import in node:
3380
3412
  0 && (module.exports = {
3381
3413
  CHECKPOINT_TRUNCATE_LENGTH,
3414
+ COMPOSER_TIPS,
3382
3415
  DEFAULT_RUNNERS,
3383
3416
  DELEGATION_OFFERED,
3384
3417
  EMPTY_CONVERSATION,
@@ -3431,6 +3464,7 @@ function accountLimitsTitle(snapshot, time) {
3431
3464
  clampThinkingEffort,
3432
3465
  closeTurn,
3433
3466
  compactionText,
3467
+ composerTip,
3434
3468
  confirmedOverride,
3435
3469
  contextMeterText,
3436
3470
  contextMeterTitle,