@evandu/super-pi 0.1.83 → 0.1.85

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 (33) hide show
  1. package/agents/super-pi-knowledge/index.ts +40 -0
  2. package/assets/knowledge-model/README.md +37 -0
  3. package/assets/knowledge-model/Xenova/bge-small-zh-v1.5/config.json +31 -0
  4. package/assets/knowledge-model/Xenova/bge-small-zh-v1.5/onnx/model_quantized.onnx +0 -0
  5. package/assets/knowledge-model/Xenova/bge-small-zh-v1.5/special_tokens_map.json +7 -0
  6. package/assets/knowledge-model/Xenova/bge-small-zh-v1.5/tokenizer.json +21278 -0
  7. package/assets/knowledge-model/Xenova/bge-small-zh-v1.5/tokenizer_config.json +15 -0
  8. package/assets/knowledge-model/Xenova/bge-small-zh-v1.5/vocab.txt +21128 -0
  9. package/dist/.super-pi-check-inputs.json +4 -0
  10. package/dist/client/.super-pi-client-sources.json +8 -7
  11. package/dist/client/assets/index-B_jOwjyp.js +72 -0
  12. package/dist/client/assets/index-CNNGl4eF.css +1 -0
  13. package/dist/client/index.html +2 -2
  14. package/dist/server/application/run-service.d.ts +50 -11
  15. package/dist/server/application/run-service.js +206 -77
  16. package/dist/server/command-handler.js +16 -4
  17. package/dist/server/http-server.js +59 -1
  18. package/dist/server/index.js +7 -0
  19. package/dist/server/knowledge-vectors.d.ts +133 -0
  20. package/dist/server/knowledge-vectors.js +302 -0
  21. package/dist/server/knowledge.d.ts +263 -0
  22. package/dist/server/knowledge.js +743 -0
  23. package/dist/server/persistence/app-state-repository.d.ts +25 -1
  24. package/dist/server/persistence/sqlite-state-repository.js +47 -4
  25. package/dist/server/runtime.d.ts +48 -1
  26. package/dist/server/runtime.js +83 -7
  27. package/dist/server/server-context.d.ts +1 -0
  28. package/dist/server/store.d.ts +153 -68
  29. package/dist/server/store.js +405 -187
  30. package/dist/server/types.d.ts +97 -65
  31. package/package.json +163 -154
  32. package/dist/client/assets/index-DhOfFh0G.js +0 -72
  33. package/dist/client/assets/index-v2n_FYv_.css +0 -1
@@ -105,7 +105,39 @@ export type Message = {
105
105
  id?: string;
106
106
  name: string;
107
107
  };
108
+ delivery?: MessageDelivery;
108
109
  };
110
+ /**
111
+ * WHERE A USER MESSAGE IS IN ITS OWN DELIVERY, or `undefined` for every message that is not waiting.
112
+ *
113
+ * A user message is written into the transcript the instant it is sent, BEFORE any turn has started,
114
+ * and it stays in that exact position until the agent has answered it. What changes meanwhile is this
115
+ * field and nothing else - see `docs/QUEUE-UX.md` for why the message must never move.
116
+ *
117
+ * ABSENT means "not waiting": a message the agent is answering right now, one it already answered, one
118
+ * withdrawn, and every `assistant` / `tool` message. Only `role: "user"` ever carries it.
119
+ *
120
+ * - `waiting` - said, not yet handed to the agent. CANCELLED freely, EDITED freely, and REORDERED
121
+ * freely. This is where essentially every waiting message lives, because a message is only given to
122
+ * Pi at the moment it is about to be delivered.
123
+ * - `sending` - written to a live Pi child's stdin as a `steer` and not yet confirmed delivered. NOT
124
+ * cancellable and NOT editable: Pi has no single-item retract (its only queue command is
125
+ * `clear_queue`, which clears everything), so a UI offering either would be a promise the transport
126
+ * cannot keep. It returns to `waiting` exactly when we can prove Pi never delivered it - the turn
127
+ * ended - and stays here when Pi simply has not answered yet.
128
+ *
129
+ * WHY A FIELD AND NOT A SEPARATE LIST. The waiting list used to be its own array of content copies
130
+ * (`QueuedMessage`), and that is what made two bugs structural rather than accidental: a queued entry
131
+ * was not a message, so promoting one to a turn had to CREATE a message - which is why a steered
132
+ * message reached Pi and the model and never reached the transcript at all - and "delivered" could only
133
+ * be expressed by DELETING a row, so every delivery was an opportunity to lose the user's words. A
134
+ * message with a state has an identity to transition and nothing to delete.
135
+ *
136
+ * ORDER IS THE QUEUE. There is no `priority` flag and no second source of truth: the waiting messages
137
+ * are the trailing `role: "user"` messages of the array, and "put this one first" is a move within
138
+ * that block.
139
+ */
140
+ export type MessageDelivery = "waiting" | "sending";
109
141
  /**
110
142
  * A piece of context attached to a user message that is shown as its OWN block under the bubble, rather
111
143
  * than flattened into the prompt. Today: a skill the person picked from the slash menu - the model gets
@@ -691,7 +723,6 @@ export type AppState = {
691
723
  workspaces: Workspace[];
692
724
  conversations: Conversation[];
693
725
  subagentRuns: SubagentRun[];
694
- queuedMessages: QueuedMessage[];
695
726
  backgroundTasks: BackgroundTaskSummary[];
696
727
  todosByConversation?: Record<string, TodoItem[]>;
697
728
  workflows?: WorkflowRun[];
@@ -703,63 +734,21 @@ export type TodoItem = {
703
734
  status: "pending" | "in_progress" | "completed";
704
735
  priority?: "high" | "medium" | "low";
705
736
  };
706
- /**
707
- * One message the user sent WHILE THE AGENT WAS WORKING, held by Super Pi until a turn boundary can
708
- * carry it.
709
- *
710
- * WHY THE SERVER OWNS THIS LIST AT ALL. Pi's own queues live in the Pi process's memory
711
- * (`agent-session.ts:394/396`) and Super Pi kills that process unconditionally at the end of every
712
- * turn (`runtime.ts:539-545`), while Pi never writes a queued message to the session JSONL. A list kept
713
- * in Pi is therefore guaranteed to be destroyed, with no trace, on every turn boundary. So Pi is used
714
- * only as a delivery pipe - one steer per turn, handed over at the moment it is allowed to be
715
- * delivered - and the waiting list is this one.
716
- *
717
- * THE ID IS OURS AND IT IS THE POINT. Pi matches a queued message back to its queue entry by
718
- * `indexOf` on the message TEXT (`agent-session.ts:1123/1129`), so two queued messages with identical
719
- * text are indistinguishable to it and one of them is left behind in its queue forever. Every entry
720
- * here therefore carries a Super Pi id that Pi never sees, and cancel/steer address THAT.
721
- *
722
- * `state` is the whole lifecycle, and `sending` is the only irreversible step:
723
- *
724
- * - `queued` - in the list, not yet given to Pi. CANCELLED freely; this is where essentially every
725
- * message lives, because a message is only handed to Pi when it is about to be delivered.
726
- * - `sending` - written to Pi's stdin as a `steer` and not yet confirmed delivered. NOT cancellable:
727
- * Pi has no single-item retract (its only queue command is `clear_queue`, which clears
728
- * everything), so claiming otherwise in the UI would be a lie. It goes back to `queued`
729
- * exactly when we can prove Pi never delivered it - the turn ended - and stays here when
730
- * Pi simply has not answered yet.
731
- *
732
- * A delivered or cancelled message is REMOVED rather than kept with a terminal state: a queue that
733
- * retains sent messages needs a pruning policy and a way to read it, and a stale row in this list is
734
- * worse than no row.
735
- */
736
- export type QueuedMessage = {
737
- /** `q_<uuid>`. Super Pi's own identity for this message, and the only thing cancel/steer name. */
738
- id: string;
739
- /**
740
- * The conversation whose next turn will carry this. Deliberately a CONVERSATION id and never a
741
- * `sub_*` run id: sub-agent children run in their own Pi processes under their own supervisor
742
- * (`subagents.ts`), they have their own stop and their own lifecycle, and a queue entry keyed by one
743
- * would be claimed and delivered by the wrong owner.
744
- */
745
- conversationId: string;
746
- content: string;
747
- state: "queued" | "sending";
748
- /** Chosen for priority delivery. Survives a Pi turn boundary and a server restart. */
749
- priority?: boolean;
750
- createdAt: string;
751
- images?: MessageImage[];
752
- attachments?: MessageAttachments;
753
- };
754
737
  /**
755
738
  * What Pi reports about ITS OWN queue, forwarded to the browser as it arrives.
756
739
  *
757
740
  * `steering` and `followUp` are Pi's in-memory arrays as of this event (`agent-session.ts:204-208`).
758
- * They are NOT the queue the user sees: the authoritative list is `AppState.queuedMessages`, and this
759
- * is Pi's own view of the at most one steer that is currently in flight inside the child process. It
760
- * is forwarded because it is the only signal that proves a steer was really picked up, and because a
761
- * `followUp` array that is ever non-empty means something outside this server sent a `follow_up` -
762
- * worth being able to see rather than infer.
741
+ * They are NOT what the user sees: the authoritative list is the trailing `delivery`-bearing messages
742
+ * of the conversation itself (`MessageDelivery`), and this is Pi's own view of the at most one steer
743
+ * that is currently in flight inside the child process. It is forwarded because it is the only signal
744
+ * that proves a steer was really picked up, and because a `followUp` array that is ever non-empty means
745
+ * something outside this server sent a `follow_up` - worth being able to see rather than infer.
746
+ *
747
+ * It no longer decides anything. A delivery used to be inferred from a DROP in `steering.length` and
748
+ * applied by DELETING the oldest `sending` row, which is how a steered message could reach the model
749
+ * and never reach the transcript. Delivery is now announced directly, by the `message_start` Pi emits
750
+ * when it hands the text to the agent loop, and applied by moving a state on a message that was already
751
+ * on screen the whole time.
763
752
  */
764
753
  export type PiQueueSnapshot = {
765
754
  steering: string[];
@@ -989,6 +978,14 @@ export type ClientCommandBody =
989
978
  * one gets a turn. The browser never picks, which is what makes the guard un-bypassable - the old
990
979
  * arrangement had the browser decide by disabling itself, and a second WebSocket client (or a stale
991
980
  * tab) walked straight past it into two Pi processes writing one session.
981
+ *
982
+ * `clientId` is how the browser's copy and the server's copy become THE SAME MESSAGE instead of two
983
+ * that have to be matched up afterwards. The browser mints the id, renders the message with it in the
984
+ * same frame it pressed send, and sends it here; the store uses it as the message id when it is well
985
+ * formed and not already taken. So when the broadcast arrives there is nothing to reconcile - no
986
+ * content matching, no `knownIds` set, no window in which the same sentence exists twice. It used to
987
+ * be matched by `content === content.trim()`, which cannot tell two identical messages apart and made
988
+ * the tests assert ordinals instead of messages. Omitted means "server, mint one".
992
989
  */
993
990
  | {
994
991
  type: "message.send";
@@ -996,6 +993,7 @@ export type ClientCommandBody =
996
993
  content: string;
997
994
  images?: MessageImage[];
998
995
  attachments?: MessageAttachments;
996
+ clientId?: string;
999
997
  }
1000
998
  /**
1001
999
  * Revert the conversation to the state right AFTER one message: every message after it is removed from
@@ -1018,21 +1016,49 @@ export type ClientCommandBody =
1018
1016
  withdraw?: boolean;
1019
1017
  }
1020
1018
  /**
1021
- * Drops ONE queued message, by Super Pi's id.
1019
+ * Withdraws ONE waiting message, by its message id.
1022
1020
  *
1023
- * Addressed by `queueId` rather than by text or by index for the reason `QueuedMessage.id` exists at
1024
- * all: two queued messages can be the same string, and a cancel that matched on text would drop
1025
- * whichever one sorted first. Refused for an entry already in `sending` - Pi holds that text now and
1026
- * cannot be told to forget one item - and an unknown or already-removed id is a no-op rather than an
1027
- * error, exactly as `subagent.stop` treats a run that has already settled.
1021
+ * Addressed by `messageId` rather than by text or by index because two waiting messages can be the
1022
+ * same string. Refused for a message already in `sending` - Pi holds that text now and cannot be told
1023
+ * to forget one item - and an unknown or already-removed id is a no-op rather than an error, exactly
1024
+ * as `subagent.stop` treats a run that has already settled.
1028
1025
  */
1029
1026
  | {
1030
1027
  type: "message.cancel";
1031
1028
  conversationId: string;
1032
- queueId: string;
1029
+ messageId: string;
1033
1030
  }
1034
1031
  /**
1035
- * Promotes one queued message to a `steer`: Pi takes it at the next turn boundary instead of waiting
1032
+ * Rewrites the text of ONE waiting message that has not been given to Pi yet.
1033
+ *
1034
+ * The one mutation the old waiting list could not express: a row there was a content copy in an array
1035
+ * with no way to say "the user changed their mind about these words", so changing your mind meant
1036
+ * cancelling and retyping. Now the message itself is edited, in place, and it stays exactly where it
1037
+ * is. Refused for `sending`, for the same reason `cancel` is.
1038
+ */
1039
+ | {
1040
+ type: "message.edit";
1041
+ conversationId: string;
1042
+ messageId: string;
1043
+ content: string;
1044
+ }
1045
+ /**
1046
+ * Moves ONE waiting message to a new position among the waiting messages.
1047
+ *
1048
+ * This is the whole of what the old `priority` boolean meant, expressed as a position instead of a
1049
+ * flag. `toIndex` is counted over the WAITING messages only (`0` is the next one the agent will
1050
+ * start), so moving something to the front does not depend on how many answered messages sit above
1051
+ * it, and moving it back is the same command rather than a separate "un-prioritise" that would be a
1052
+ * second source of truth for one idea.
1053
+ */
1054
+ | {
1055
+ type: "message.reorder";
1056
+ conversationId: string;
1057
+ messageId: string;
1058
+ toIndex: number;
1059
+ }
1060
+ /**
1061
+ * Promotes one waiting message to a `steer`: Pi takes it at the next turn boundary instead of waiting
1036
1062
  * for the whole task to finish.
1037
1063
  *
1038
1064
  * The timing is Pi's and cannot be finer: `agent-loop.ts:295` polls steering after `turn_end`, which
@@ -1040,17 +1066,23 @@ export type ClientCommandBody =
1040
1066
  * this means "after the tools currently running finish", and during a long single tool call there is
1041
1067
  * nothing to interrupt - Pi offers no preemption. The UI says so in words rather than implying
1042
1068
  * instant delivery.
1069
+ *
1070
+ * What this USED TO DO that it no longer does: it also set a `priority` flag, and on failure it fell
1071
+ * back to setting that flag, so "make this the next one" and "hand this to Pi right now" were one
1072
+ * button and one code path. They are still one button - both move the message to the front of the
1073
+ * waiting block - but the flag is gone, so the fallback is now the same move rather than a second
1074
+ * mechanism that had to be kept in agreement with the first.
1043
1075
  */
1044
1076
  | {
1045
1077
  type: "message.steer";
1046
1078
  conversationId: string;
1047
- queueId: string;
1079
+ messageId: string;
1048
1080
  }
1049
- /** Starts this saved queued message as the next turn, only after the current turn has ended. */
1081
+ /** Starts this waiting message as the next turn, only after the current turn has ended. */
1050
1082
  | {
1051
1083
  type: "message.sendQueued";
1052
1084
  conversationId: string;
1053
- queueId: string;
1085
+ messageId: string;
1054
1086
  } | {
1055
1087
  type: "run.stop";
1056
1088
  conversationId: string;
package/package.json CHANGED
@@ -1,154 +1,163 @@
1
- {
2
- "name": "@evandu/super-pi",
3
- "version": "0.1.83",
4
- "description": "Web control plane and companion for Pi",
5
- "license": "MIT",
6
- "type": "module",
7
- "bin": {
8
- "super-pi": "bin/super-pi.js",
9
- "super_pi": "bin/super-pi.js"
10
- },
11
- "pi": {
12
- "extensions": [
13
- "./dist/extension.js"
14
- ]
15
- },
16
- "files": [
17
- "dist",
18
- "agents",
19
- "bin",
20
- "scripts/restart-server.mjs",
21
- "README.md"
22
- ],
23
- "engines": {
24
- "node": ">=22.19.0"
25
- },
26
- "scripts": {
27
- "prepack": "npm run build",
28
- "prepublishOnly": "npm run build && cross-env SUPER_PI_REQUIRE_REAL_PI=1 node scripts/extension-load.test.mjs",
29
- "dev": "concurrently --kill-others-on-fail \"npm:dev:server\" \"npm:dev:client\"",
30
- "dev:client": "vite --host 0.0.0.0",
31
- "dev:server": "cross-env SUPER_PI_PORT=3081 tsx watch src/server/index.ts",
32
- "dev:installed": "npm run build && cross-env SUPER_PI_PORT=3080 node bin/super-pi.js",
33
- "build": "tsc -b && vite build && node scripts/fresh-build.mjs",
34
- "start": "node dist/server/index.js",
35
- "restart:server": "node scripts/restart-server.mjs",
36
- "smoke": "npm run build && node scripts/smoke.mjs",
37
- "check": "node scripts/run-check.mjs"
38
- },
39
- "check:logic": [
40
- "scripts/stream-checkpoint.test.mjs",
41
- "scripts/stream-transport.test.mjs",
42
- "scripts/lan-access.test.mjs",
43
- "scripts/terminal-pty.test.mjs",
44
- "scripts/persistence-repository.test.mjs",
45
- "scripts/sqlite-repository.test.mjs",
46
- "scripts/dispatch-ancestry.test.mjs",
47
- "scripts/dispatch-endpoint.test.mjs",
48
- "scripts/dispatched-by.test.mjs",
49
- "scripts/verify-source-text.test.mjs",
50
- "scripts/runtime-extension-ui.test.mjs",
51
- "scripts/agent-mechanism.test.mjs",
52
- "scripts/agent-wiring.test.mjs",
53
- "scripts/message-timestamps.test.mjs",
54
- "scripts/pi-resolution.test.mjs",
55
- "scripts/agent-real-pi.test.mjs",
56
- "scripts/image-input-real-pi.test.mjs",
57
- "scripts/image-upload.test.mjs",
58
- "scripts/extension-ui-e2e.test.mjs",
59
- "scripts/session-picker.test.mjs",
60
- "scripts/workspace-cwd.test.mjs",
61
- "scripts/subagents.test.mjs",
62
- "scripts/subagent-noise.test.mjs",
63
- "scripts/subagent-runs.test.mjs",
64
- "scripts/conversation-reconcile.test.mjs",
65
- "scripts/subagent-dispatch.test.mjs",
66
- "scripts/workflow-plan.test.mjs",
67
- "scripts/workflow-engine.test.mjs",
68
- "scripts/workflow-endpoint.test.mjs",
69
- "scripts/workflow-ui.test.mjs",
70
- "scripts/agent-vis-records.test.mjs",
71
- "scripts/queue-store.test.mjs",
72
- "scripts/followup.test.mjs",
73
- "scripts/md-render.test.mjs",
74
- "scripts/revert-session-format.test.mjs",
75
- "scripts/revert-session-file.test.mjs",
76
- "scripts/revert-real-pi.test.mjs",
77
- "scripts/bg-task.test.mjs",
78
- "scripts/todo-tool.test.mjs",
79
- "scripts/tool-calls.test.mjs",
80
- "scripts/files-api.test.mjs",
81
- "scripts/files-missing-path.test.mjs",
82
- "scripts/task-tool.test.mjs",
83
- "scripts/fork-server.test.mjs",
84
- "scripts/styles-no-dangling.test.mjs",
85
- "scripts/theme-no-hardcoded-colours.test.mjs",
86
- "scripts/agent-config-regression.test.mjs",
87
- "scripts/model-filter.test.mjs",
88
- "scripts/active-memory.test.mjs",
89
- "scripts/tool-runner.test.mjs",
90
- "scripts/tool-runtime-api.test.mjs",
91
- "scripts/extension-load.test.mjs",
92
- "scripts/static-client-assets.test.mjs",
93
- "scripts/cli.test.mjs"
94
- ],
95
- "check:browser": [
96
- "scripts/revert-browser.test.mjs",
97
- "scripts/extension-ui-browser.test.mjs",
98
- "scripts/inline-rename-blur.test.mjs",
99
- "scripts/message-timestamps-browser.test.mjs",
100
- "scripts/session-picker-browser.test.mjs",
101
- "scripts/workspace-settings-browser.test.mjs",
102
- "scripts/subagent-card-browser.test.mjs",
103
- "scripts/workflow-browser.test.mjs",
104
- "scripts/conversation-reconcile-browser.test.mjs",
105
- "scripts/visual-defects-browser.test.mjs",
106
- "scripts/session-state-animation-browser.test.mjs",
107
- "scripts/agent-vis-card-browser.test.mjs",
108
- "scripts/queue-dock.test.mjs",
109
- "scripts/md-render-browser.test.mjs",
110
- "scripts/right-sidebar-browser.test.mjs",
111
- "scripts/sidebar-tools-browser.test.mjs",
112
- "scripts/tool-runtime-browser.test.mjs",
113
- "scripts/session-context-menu-browser.test.mjs",
114
- "scripts/tool-call-blocks-browser.test.mjs",
115
- "scripts/files-tab-browser.test.mjs",
116
- "scripts/msg-tabs-browser.test.mjs",
117
- "scripts/tabs-on-top-browser.test.mjs",
118
- "scripts/subagent-source.test.mjs",
119
- "scripts/fork-resize-browser.test.mjs",
120
- "scripts/msg-bubbles.test.mjs",
121
- "scripts/narrow-layout.test.mjs",
122
- "scripts/scrollbar-style.test.mjs",
123
- "scripts/stream-tail-browser.test.mjs",
124
- "scripts/theme-contrast.test.mjs",
125
- "scripts/theme-switch-state.test.mjs",
126
- "scripts/settings-window-structure.test.mjs",
127
- "scripts/file-tab-selected-contrast.test.mjs",
128
- "scripts/help-window.test.mjs",
129
- "scripts/composer-regression-browser.test.mjs",
130
- "scripts/workspace-picker-browser.test.mjs",
131
- "scripts/optimistic-browser.test.mjs",
132
- "scripts/active-memory-browser.test.mjs"
133
- ],
134
- "dependencies": {
135
- "@xterm/addon-fit": "^0.11.0",
136
- "@xterm/xterm": "^6.0.0",
137
- "node-pty": "^1.2.0-beta.15",
138
- "ws": "latest"
139
- },
140
- "devDependencies": {
141
- "@types/node": "latest",
142
- "@types/react": "latest",
143
- "@types/react-dom": "latest",
144
- "@types/ws": "latest",
145
- "@vitejs/plugin-react": "latest",
146
- "concurrently": "latest",
147
- "cross-env": "latest",
148
- "react": "latest",
149
- "react-dom": "latest",
150
- "tsx": "latest",
151
- "typescript": "latest",
152
- "vite": "latest"
153
- }
154
- }
1
+ {
2
+ "name": "@evandu/super-pi",
3
+ "version": "0.1.85",
4
+ "description": "Web control plane and companion for Pi",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "bin": {
8
+ "super-pi": "bin/super-pi.js",
9
+ "super_pi": "bin/super-pi.js"
10
+ },
11
+ "pi": {
12
+ "extensions": [
13
+ "./dist/extension.js"
14
+ ]
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "agents",
19
+ "bin",
20
+ "scripts/restart-server.mjs",
21
+ "README.md",
22
+ "assets/knowledge-model"
23
+ ],
24
+ "engines": {
25
+ "node": ">=22.19.0"
26
+ },
27
+ "scripts": {
28
+ "prepack": "npm run build",
29
+ "prepublishOnly": "npm run build && cross-env SUPER_PI_REQUIRE_REAL_PI=1 node scripts/extension-load.test.mjs",
30
+ "dev": "concurrently --kill-others-on-fail \"npm:dev:server\" \"npm:dev:client\"",
31
+ "dev:client": "vite --host 0.0.0.0",
32
+ "dev:server": "cross-env SUPER_PI_PORT=3081 tsx watch src/server/index.ts",
33
+ "dev:installed": "npm run build && cross-env SUPER_PI_PORT=3080 node bin/super-pi.js",
34
+ "build": "tsc -b && vite build && node scripts/fresh-build.mjs",
35
+ "start": "node dist/server/index.js",
36
+ "restart:server": "node scripts/restart-server.mjs",
37
+ "smoke": "npm run build && node scripts/smoke.mjs",
38
+ "check": "node scripts/run-check.mjs"
39
+ },
40
+ "check:logic": [
41
+ "scripts/stream-checkpoint.test.mjs",
42
+ "scripts/stream-transport.test.mjs",
43
+ "scripts/lan-access.test.mjs",
44
+ "scripts/terminal-pty.test.mjs",
45
+ "scripts/persistence-repository.test.mjs",
46
+ "scripts/sqlite-repository.test.mjs",
47
+ "scripts/dispatch-ancestry.test.mjs",
48
+ "scripts/dispatch-endpoint.test.mjs",
49
+ "scripts/dispatched-by.test.mjs",
50
+ "scripts/verify-source-text.test.mjs",
51
+ "scripts/runtime-extension-ui.test.mjs",
52
+ "scripts/agent-mechanism.test.mjs",
53
+ "scripts/agent-wiring.test.mjs",
54
+ "scripts/message-timestamps.test.mjs",
55
+ "scripts/pi-resolution.test.mjs",
56
+ "scripts/agent-real-pi.test.mjs",
57
+ "scripts/image-input-real-pi.test.mjs",
58
+ "scripts/image-upload.test.mjs",
59
+ "scripts/extension-ui-e2e.test.mjs",
60
+ "scripts/session-picker.test.mjs",
61
+ "scripts/workspace-cwd.test.mjs",
62
+ "scripts/subagents.test.mjs",
63
+ "scripts/subagent-noise.test.mjs",
64
+ "scripts/subagent-runs.test.mjs",
65
+ "scripts/conversation-reconcile.test.mjs",
66
+ "scripts/subagent-dispatch.test.mjs",
67
+ "scripts/workflow-plan.test.mjs",
68
+ "scripts/workflow-engine.test.mjs",
69
+ "scripts/workflow-endpoint.test.mjs",
70
+ "scripts/workflow-ui.test.mjs",
71
+ "scripts/agent-vis-records.test.mjs",
72
+ "scripts/queue-store.test.mjs",
73
+ "scripts/followup.test.mjs",
74
+ "scripts/md-render.test.mjs",
75
+ "scripts/revert-session-format.test.mjs",
76
+ "scripts/revert-session-file.test.mjs",
77
+ "scripts/revert-real-pi.test.mjs",
78
+ "scripts/bg-task.test.mjs",
79
+ "scripts/todo-tool.test.mjs",
80
+ "scripts/tool-calls.test.mjs",
81
+ "scripts/files-api.test.mjs",
82
+ "scripts/files-missing-path.test.mjs",
83
+ "scripts/task-tool.test.mjs",
84
+ "scripts/fork-server.test.mjs",
85
+ "scripts/styles-no-dangling.test.mjs",
86
+ "scripts/theme-no-hardcoded-colours.test.mjs",
87
+ "scripts/agent-config-regression.test.mjs",
88
+ "scripts/model-filter.test.mjs",
89
+ "scripts/active-memory.test.mjs",
90
+ "scripts/knowledge-base.test.mjs",
91
+ "scripts/tool-runner.test.mjs",
92
+ "scripts/tool-runtime-api.test.mjs",
93
+ "scripts/extension-load.test.mjs",
94
+ "scripts/static-client-assets.test.mjs",
95
+ "scripts/cli.test.mjs",
96
+ "scripts/check-runner.test.mjs",
97
+ "scripts/shared-chrome.test.mjs"
98
+ ],
99
+ "check:browser": [
100
+ "scripts/revert-browser.test.mjs",
101
+ "scripts/extension-ui-browser.test.mjs",
102
+ "scripts/inline-rename-blur.test.mjs",
103
+ "scripts/message-timestamps-browser.test.mjs",
104
+ "scripts/session-picker-browser.test.mjs",
105
+ "scripts/workspace-settings-browser.test.mjs",
106
+ "scripts/subagent-card-browser.test.mjs",
107
+ "scripts/workflow-browser.test.mjs",
108
+ "scripts/conversation-reconcile-browser.test.mjs",
109
+ "scripts/visual-defects-browser.test.mjs",
110
+ "scripts/session-state-animation-browser.test.mjs",
111
+ "scripts/agent-vis-card-browser.test.mjs",
112
+ "scripts/queue-dock.test.mjs",
113
+ "scripts/md-render-browser.test.mjs",
114
+ "scripts/right-sidebar-browser.test.mjs",
115
+ "scripts/sidebar-tools-browser.test.mjs",
116
+ "scripts/tool-runtime-browser.test.mjs",
117
+ "scripts/session-context-menu-browser.test.mjs",
118
+ "scripts/tool-call-blocks-browser.test.mjs",
119
+ "scripts/files-tab-browser.test.mjs",
120
+ "scripts/msg-tabs-browser.test.mjs",
121
+ "scripts/tabs-on-top-browser.test.mjs",
122
+ "scripts/subagent-source.test.mjs",
123
+ "scripts/fork-resize-browser.test.mjs",
124
+ "scripts/msg-bubbles.test.mjs",
125
+ "scripts/narrow-layout.test.mjs",
126
+ "scripts/scrollbar-style.test.mjs",
127
+ "scripts/stream-tail-browser.test.mjs",
128
+ "scripts/theme-contrast.test.mjs",
129
+ "scripts/theme-switch-state.test.mjs",
130
+ "scripts/settings-window-structure.test.mjs",
131
+ "scripts/file-tab-selected-contrast.test.mjs",
132
+ "scripts/help-window.test.mjs",
133
+ "scripts/composer-regression-browser.test.mjs",
134
+ "scripts/composer-resize-browser.test.mjs",
135
+ "scripts/workspace-picker-browser.test.mjs",
136
+ "scripts/optimistic-browser.test.mjs",
137
+ "scripts/active-memory-browser.test.mjs",
138
+ "scripts/knowledge-base-browser.test.mjs"
139
+ ],
140
+ "dependencies": {
141
+ "@xterm/addon-fit": "^0.11.0",
142
+ "@xterm/xterm": "^6.0.0",
143
+ "node-pty": "^1.2.0-beta.15",
144
+ "ws": "latest"
145
+ },
146
+ "devDependencies": {
147
+ "@types/node": "latest",
148
+ "@types/react": "latest",
149
+ "@types/react-dom": "latest",
150
+ "@types/ws": "latest",
151
+ "@vitejs/plugin-react": "latest",
152
+ "concurrently": "latest",
153
+ "cross-env": "latest",
154
+ "react": "latest",
155
+ "react-dom": "latest",
156
+ "tsx": "latest",
157
+ "typescript": "latest",
158
+ "vite": "latest"
159
+ },
160
+ "optionalDependencies": {
161
+ "@huggingface/transformers": "^4.3.1"
162
+ }
163
+ }