@bubblebrain-ai/bubble 0.0.49 → 0.0.51

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 (64) hide show
  1. package/dist/agent/abort-errors.d.ts +4 -0
  2. package/dist/agent/abort-errors.js +30 -0
  3. package/dist/agent/profiles.js +3 -4
  4. package/dist/agent/provider-fingerprint.d.ts +6 -0
  5. package/dist/agent/provider-fingerprint.js +89 -0
  6. package/dist/agent/resident-history.d.ts +7 -0
  7. package/dist/agent/resident-history.js +61 -0
  8. package/dist/agent/subtask-policy.js +4 -4
  9. package/dist/agent/transcript-helpers.d.ts +20 -0
  10. package/dist/agent/transcript-helpers.js +62 -0
  11. package/dist/agent/update-queue.d.ts +13 -0
  12. package/dist/agent/update-queue.js +69 -0
  13. package/dist/agent.d.ts +33 -26
  14. package/dist/agent.js +80 -334
  15. package/dist/debug-trace.js +0 -2
  16. package/dist/external-runtime/grok-runtime.js +1 -1
  17. package/dist/feishu/agent-host/run-driver.js +1 -8
  18. package/dist/feishu/card/run-state.js +0 -3
  19. package/dist/lsp/service.js +2 -2
  20. package/dist/main.js +0 -15
  21. package/dist/memory/phase1.js +0 -2
  22. package/dist/model-catalog.js +8 -6
  23. package/dist/permissions/settings.d.ts +0 -1
  24. package/dist/permissions/settings.js +0 -2
  25. package/dist/prompt/compose.js +0 -3
  26. package/dist/prompt/environment.js +0 -2
  27. package/dist/prompt/reminders.js +1 -1
  28. package/dist/provider-registry.js +13 -1
  29. package/dist/provider-transform.js +7 -8
  30. package/dist/sdk/index.d.ts +17 -2
  31. package/dist/sdk/index.js +37 -6
  32. package/dist/session-log.d.ts +2 -4
  33. package/dist/session-log.js +0 -23
  34. package/dist/session-types.d.ts +2 -6
  35. package/dist/session.d.ts +1 -3
  36. package/dist/session.js +0 -8
  37. package/dist/slash-commands/commands.js +13 -13
  38. package/dist/tools/child-tools.d.ts +1 -1
  39. package/dist/tools/child-tools.js +1 -1
  40. package/dist/tools/grep.js +1 -1
  41. package/dist/tools/index.d.ts +0 -3
  42. package/dist/tools/index.js +0 -3
  43. package/dist/tui-ink/app-helpers.d.ts +43 -0
  44. package/dist/tui-ink/app-helpers.js +150 -0
  45. package/dist/tui-ink/app.d.ts +4 -11
  46. package/dist/tui-ink/app.js +57 -657
  47. package/dist/tui-ink/command-palette.d.ts +32 -0
  48. package/dist/tui-ink/command-palette.js +158 -0
  49. package/dist/tui-ink/display-reconstruct.d.ts +3 -0
  50. package/dist/tui-ink/display-reconstruct.js +82 -0
  51. package/dist/tui-ink/message-list.js +0 -1
  52. package/dist/tui-ink/rewind-picker.d.ts +8 -0
  53. package/dist/tui-ink/rewind-picker.js +102 -0
  54. package/dist/tui-ink/session-picker.js +1 -1
  55. package/dist/tui-ink/stats-panel.d.ts +11 -0
  56. package/dist/tui-ink/stats-panel.js +65 -0
  57. package/dist/tui-ink/waiting-indicator.d.ts +12 -0
  58. package/dist/tui-ink/waiting-indicator.js +129 -0
  59. package/dist/types.d.ts +0 -9
  60. package/package.json +1 -1
  61. package/dist/tools/todo.d.ts +0 -12
  62. package/dist/tools/todo.js +0 -136
  63. package/dist/tui-ink/todos.d.ts +0 -7
  64. package/dist/tui-ink/todos.js +0 -46
@@ -1,12 +0,0 @@
1
- /**
2
- * Todo tool - manage an agent-visible task list for multi-step work.
3
- *
4
- * The tool overwrites the entire list on each call. The model should re-send the full
5
- * array with updated statuses rather than trying to patch individual items.
6
- */
7
- import type { Todo, ToolRegistryEntry } from "../types.js";
8
- export interface TodoStore {
9
- getTodos: () => Todo[];
10
- setTodos: (todos: Todo[]) => void;
11
- }
12
- export declare function createTodoTool(store: TodoStore): ToolRegistryEntry;
@@ -1,136 +0,0 @@
1
- /**
2
- * Todo tool - manage an agent-visible task list for multi-step work.
3
- *
4
- * The tool overwrites the entire list on each call. The model should re-send the full
5
- * array with updated statuses rather than trying to patch individual items.
6
- */
7
- export function createTodoTool(store) {
8
- return {
9
- name: "todo_write",
10
- readOnly: true,
11
- effect: "read",
12
- description: `Create or update the task list for the current work. Send the COMPLETE list each call; this overwrites the prior list entirely.
13
-
14
- ## When to use
15
-
16
- Default to just doing the work. Reach for a list only when actively tracking progress would genuinely help you or the user follow it — never to pad simple work with filler steps or to state the obvious. When in doubt, skip the list and do the task; a list you never meaningfully update is just noise.
17
-
18
- A list earns its place when:
19
- - The task is non-trivial and spans many actions across several areas of the codebase
20
- - There are non-obvious phases or dependencies you must hold in mind to avoid losing track (a plain read → edit → test sequence does not count)
21
- - The work is ambiguous and benefits from outlining the goals up front
22
- - The user asked for several distinct things in one prompt, or gave a numbered/bulleted list
23
- - The user explicitly asked for a todo list (aka TODOs)
24
- - You discover extra steps mid-task and intend to finish them before yielding
25
-
26
- ## Quality bar
27
-
28
- If you do make a list, make a good one: meaningful, logically ordered steps that are easy to verify as you go.
29
-
30
- Good — distinct, verifiable steps for genuinely multi-part work:
31
- 1. Add CSS variables for the color palette
32
- 2. Add the toggle with localStorage state
33
- 3. Refactor components to use the variables
34
- 4. Verify every view for readability
35
-
36
- Good — scope a search uncovers makes the list worth it:
37
- "Rename getCwd across the project" → grep finds 15 call sites in 8 files → one item per file so none are missed.
38
-
39
- Bad — padding a task you could just do; do NOT create a list for this:
40
- "Fix the typo in the README title" → 1. Find typo 2. Open file 3. Fix it 4. Save. That is one edit — just make it.
41
-
42
- Bad — vague, unverifiable filler: "Make it work", "Improve the styling", "Clean things up".
43
-
44
- ## Task states
45
-
46
- - pending: not yet started
47
- - in_progress: currently working on — exactly ONE at a time
48
- - completed: finished successfully
49
-
50
- Each item needs:
51
- - content: imperative form (e.g. "Run tests")
52
- - activeForm: present continuous, shown while in progress (e.g. "Running tests")
53
-
54
- ## Rules
55
-
56
- - Update status in real time; mark completed IMMEDIATELY on finishing.
57
- - Never mark completed if tests are failing, implementation is partial, errors are unresolved, or needed files are missing — keep as in_progress.
58
- - When blocked, add a new task describing what must be resolved.
59
- - Remove items that are no longer relevant; don't leave stale entries.
60
- - Do not re-send the list when nothing meaningful has changed since the last call; update only after real progress.`,
61
- parameters: {
62
- type: "object",
63
- properties: {
64
- todos: {
65
- type: "array",
66
- description: "The complete list of todos. Replaces any existing list.",
67
- items: {
68
- type: "object",
69
- properties: {
70
- content: {
71
- type: "string",
72
- description: "Imperative form describing the task (e.g., 'Add unit tests for foo')",
73
- },
74
- activeForm: {
75
- type: "string",
76
- description: "Present continuous form shown while in progress (e.g., 'Adding unit tests for foo')",
77
- },
78
- status: {
79
- type: "string",
80
- enum: ["pending", "in_progress", "completed"],
81
- description: "Current status of the task",
82
- },
83
- },
84
- required: ["content", "activeForm", "status"],
85
- },
86
- },
87
- },
88
- required: ["todos"],
89
- },
90
- async execute(args) {
91
- if (!Array.isArray(args.todos)) {
92
- return { content: "Error: 'todos' must be an array", isError: true };
93
- }
94
- const normalized = [];
95
- for (let i = 0; i < args.todos.length; i++) {
96
- const raw = args.todos[i];
97
- if (!raw || typeof raw !== "object") {
98
- return { content: `Error: todo at index ${i} is not an object`, isError: true };
99
- }
100
- const content = typeof raw.content === "string" ? raw.content.trim() : "";
101
- const activeForm = typeof raw.activeForm === "string" ? raw.activeForm.trim() : "";
102
- const status = raw.status;
103
- if (!content) {
104
- return { content: `Error: todo at index ${i} has empty content`, isError: true };
105
- }
106
- if (!activeForm) {
107
- return { content: `Error: todo at index ${i} has empty activeForm`, isError: true };
108
- }
109
- if (status !== "pending" && status !== "in_progress" && status !== "completed") {
110
- return {
111
- content: `Error: todo at index ${i} has invalid status "${status}". Must be pending|in_progress|completed`,
112
- isError: true,
113
- };
114
- }
115
- normalized.push({ content, activeForm, status });
116
- }
117
- const inProgressCount = normalized.filter((t) => t.status === "in_progress").length;
118
- if (inProgressCount > 1) {
119
- return {
120
- content: `Error: at most one todo may be in_progress at a time, found ${inProgressCount}`,
121
- isError: true,
122
- };
123
- }
124
- store.setTodos(normalized);
125
- const counts = {
126
- pending: normalized.filter((t) => t.status === "pending").length,
127
- in_progress: inProgressCount,
128
- completed: normalized.filter((t) => t.status === "completed").length,
129
- };
130
- return {
131
- content: `Todo list updated: ${normalized.length} item${normalized.length === 1 ? "" : "s"} ` +
132
- `(${counts.completed} completed, ${counts.in_progress} in progress, ${counts.pending} pending).`,
133
- };
134
- },
135
- };
136
- }
@@ -1,7 +0,0 @@
1
- import type { Todo } from "../types.js";
2
- interface TodosPanelProps {
3
- todos: Todo[];
4
- terminalColumns: number;
5
- }
6
- export declare function TodosPanel({ todos, terminalColumns }: TodosPanelProps): import("react/jsx-runtime").JSX.Element | null;
7
- export {};
@@ -1,46 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Box, Text } from "ink";
3
- import { useTheme } from "./theme.js";
4
- const MAX_ROWS = 8;
5
- export function TodosPanel({ todos, terminalColumns }) {
6
- const theme = useTheme();
7
- if (todos.length === 0) {
8
- return null;
9
- }
10
- const rows = selectVisibleRows(todos);
11
- const hiddenCount = todos.length - rows.length;
12
- const contentWidth = Math.max(20, terminalColumns - 4);
13
- return (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsx(Text, { color: theme.accent, bold: true, children: "\u25CF Todos" }), rows.map((todo, index) => (_jsx(TodoRow, { todo: todo, maxWidth: contentWidth }, index))), hiddenCount > 0 && (_jsxs(Text, { color: theme.muted, children: ["... ", hiddenCount, " more item", hiddenCount === 1 ? "" : "s", " hidden"] }))] }));
14
- }
15
- function selectVisibleRows(todos) {
16
- if (todos.length <= MAX_ROWS) {
17
- return todos;
18
- }
19
- // Prefer to show: all in_progress, the last N completed just before current, and upcoming pending.
20
- const inProgressIdx = todos.findIndex((t) => t.status === "in_progress");
21
- const anchor = inProgressIdx >= 0 ? inProgressIdx : todos.findIndex((t) => t.status === "pending");
22
- const pivot = anchor >= 0 ? anchor : 0;
23
- const half = Math.floor(MAX_ROWS / 2);
24
- let start = Math.max(0, pivot - half);
25
- let end = Math.min(todos.length, start + MAX_ROWS);
26
- if (end - start < MAX_ROWS) {
27
- start = Math.max(0, end - MAX_ROWS);
28
- }
29
- return todos.slice(start, end);
30
- }
31
- function TodoRow({ todo, maxWidth }) {
32
- const theme = useTheme();
33
- const { glyph, color, dim, label } = statusStyle(todo, theme);
34
- const text = label || todo.content;
35
- const trimmed = text.length > maxWidth - 4 ? text.slice(0, maxWidth - 5) + "…" : text;
36
- return (_jsx(Box, { height: 1, children: _jsxs(Text, { color: color, dimColor: dim, children: [glyph, " ", trimmed] }) }));
37
- }
38
- function statusStyle(todo, theme) {
39
- if (todo.status === "completed") {
40
- return { glyph: "✔", color: theme.muted, dim: true, label: todo.content };
41
- }
42
- if (todo.status === "in_progress") {
43
- return { glyph: "▶", color: theme.accent, dim: false, label: todo.activeForm || todo.content };
44
- }
45
- return { glyph: "○", color: theme.muted, dim: false, label: todo.content };
46
- }