@bytetrue/byspace 0.15.0 → 0.16.0

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 (53) hide show
  1. package/node_modules/@bytetrue/client/package.json +3 -3
  2. package/node_modules/@bytetrue/highlight/package.json +1 -1
  3. package/node_modules/@bytetrue/protocol/package.json +1 -1
  4. package/node_modules/@bytetrue/relay/package.json +1 -1
  5. package/node_modules/@bytetrue/server/dist/server/server/byspace-env.d.ts +1 -0
  6. package/node_modules/@bytetrue/server/dist/server/server/byspace-env.js +9 -0
  7. package/node_modules/@bytetrue/server/dist/server/terminal/agent-hooks/pi/pi-extension.d.ts +1 -1
  8. package/node_modules/@bytetrue/server/dist/server/terminal/agent-hooks/pi/pi-extension.js +16 -1
  9. package/node_modules/@bytetrue/server/dist/server/terminal/terminal.js +6 -0
  10. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/{index-1e1ff7510a612ab12641e5e07e0a7208.js → index-eade2661e21bbc08a50d56f1c6b0917a.js} +526 -525
  11. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/index-eade2661e21bbc08a50d56f1c6b0917a.js.br +0 -0
  12. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/index-eade2661e21bbc08a50d56f1c6b0917a.js.gz +0 -0
  13. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/{indexeddb-attachment-store-1e67472b9640c869a55ff6915d1f7afb.js → indexeddb-attachment-store-a2e8491be0374dc2a52abfe002ecabe9.js} +1 -1
  14. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/{indexeddb-attachment-store-1e67472b9640c869a55ff6915d1f7afb.js.br → indexeddb-attachment-store-a2e8491be0374dc2a52abfe002ecabe9.js.br} +0 -0
  15. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-a2e8491be0374dc2a52abfe002ecabe9.js.gz +0 -0
  16. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/{native-file-attachment-store-63659fda781a1cc594f259795f1cc29f.js → native-file-attachment-store-6ba28513708667bbad7dd5434a0f8d5b.js} +3 -3
  17. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-6ba28513708667bbad7dd5434a0f8d5b.js.br +0 -0
  18. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-6ba28513708667bbad7dd5434a0f8d5b.js.gz +0 -0
  19. package/node_modules/@bytetrue/server/dist/server/web-ui/apple-touch-icon.png +0 -0
  20. package/node_modules/@bytetrue/server/dist/server/web-ui/assets/assets/images/favicon-dark-attention.9c2d51faf93468f68840811c0d9a8c6f.png +0 -0
  21. package/node_modules/@bytetrue/server/dist/server/web-ui/assets/assets/images/favicon-dark-running.a52155010955dca55546513b60bb2e2b.png +0 -0
  22. package/node_modules/@bytetrue/server/dist/server/web-ui/assets/assets/images/favicon-dark.ee7787d5c6bd1ad67c31b9949a832f7a.png +0 -0
  23. package/node_modules/@bytetrue/server/dist/server/web-ui/assets/assets/images/favicon-light-attention.9c2d51faf93468f68840811c0d9a8c6f.png +0 -0
  24. package/node_modules/@bytetrue/server/dist/server/web-ui/assets/assets/images/favicon-light-running.a52155010955dca55546513b60bb2e2b.png +0 -0
  25. package/node_modules/@bytetrue/server/dist/server/web-ui/assets/assets/images/favicon-light.ee7787d5c6bd1ad67c31b9949a832f7a.png +0 -0
  26. package/node_modules/@bytetrue/server/dist/server/web-ui/assets/assets/images/notification-icon.ba5a7dce236a7febe5d803b16f027b70.png +0 -0
  27. package/node_modules/@bytetrue/server/dist/server/web-ui/favicon.ico +0 -0
  28. package/node_modules/@bytetrue/server/dist/server/web-ui/index.html +1 -1
  29. package/node_modules/@bytetrue/server/dist/server/web-ui/index.html.br +0 -0
  30. package/node_modules/@bytetrue/server/dist/server/web-ui/index.html.gz +0 -0
  31. package/node_modules/@bytetrue/server/dist/server/web-ui/manifest.json +14 -2
  32. package/node_modules/@bytetrue/server/dist/server/web-ui/manifest.json.br +0 -0
  33. package/node_modules/@bytetrue/server/dist/server/web-ui/manifest.json.gz +0 -0
  34. package/node_modules/@bytetrue/server/dist/server/web-ui/pwa-icon-192.png +0 -0
  35. package/node_modules/@bytetrue/server/dist/server/web-ui/pwa-icon-512.png +0 -0
  36. package/node_modules/@bytetrue/server/dist/server/web-ui/pwa-maskable-192.png +0 -0
  37. package/node_modules/@bytetrue/server/dist/server/web-ui/pwa-maskable-512.png +0 -0
  38. package/node_modules/@bytetrue/server/dist/src/server/byspace-env.js +9 -0
  39. package/node_modules/@bytetrue/server/dist/src/terminal/terminal.js +6 -0
  40. package/node_modules/@bytetrue/server/package.json +5 -5
  41. package/package.json +7 -7
  42. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/index-1e1ff7510a612ab12641e5e07e0a7208.js.br +0 -0
  43. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/index-1e1ff7510a612ab12641e5e07e0a7208.js.gz +0 -0
  44. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-1e67472b9640c869a55ff6915d1f7afb.js.gz +0 -0
  45. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-63659fda781a1cc594f259795f1cc29f.js.br +0 -0
  46. package/node_modules/@bytetrue/server/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-63659fda781a1cc594f259795f1cc29f.js.gz +0 -0
  47. package/node_modules/@bytetrue/server/dist/server/web-ui/assets/assets/images/favicon-dark-attention.882b3a27dcb2073e9e31b334f9ed9728.png +0 -0
  48. package/node_modules/@bytetrue/server/dist/server/web-ui/assets/assets/images/favicon-dark-running.8112342ff0d39e047a7f8d4fad9402f3.png +0 -0
  49. package/node_modules/@bytetrue/server/dist/server/web-ui/assets/assets/images/favicon-dark.8005ed36ac07a5a7c60de25780897bd4.png +0 -0
  50. package/node_modules/@bytetrue/server/dist/server/web-ui/assets/assets/images/favicon-light-attention.882b3a27dcb2073e9e31b334f9ed9728.png +0 -0
  51. package/node_modules/@bytetrue/server/dist/server/web-ui/assets/assets/images/favicon-light-running.8112342ff0d39e047a7f8d4fad9402f3.png +0 -0
  52. package/node_modules/@bytetrue/server/dist/server/web-ui/assets/assets/images/favicon-light.8005ed36ac07a5a7c60de25780897bd4.png +0 -0
  53. package/node_modules/@bytetrue/server/dist/server/web-ui/assets/assets/images/notification-icon.3bf81d33ddbf380606bdd248ba83e158.png +0 -0
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bytetrue/client",
3
- "version": "0.15.0",
3
+ "version": "0.16.0",
4
4
  "description": "BySpace client SDK package",
5
5
  "files": [
6
6
  "dist",
@@ -39,8 +39,8 @@
39
39
  "test": "vitest run"
40
40
  },
41
41
  "dependencies": {
42
- "@bytetrue/protocol": "0.15.0",
43
- "@bytetrue/relay": "0.15.0"
42
+ "@bytetrue/protocol": "0.16.0",
43
+ "@bytetrue/relay": "0.16.0"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@types/node": "^20.9.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bytetrue/highlight",
3
- "version": "0.15.0",
3
+ "version": "0.16.0",
4
4
  "files": [
5
5
  "dist",
6
6
  "!dist/**/*.map",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bytetrue/protocol",
3
- "version": "0.15.0",
3
+ "version": "0.16.0",
4
4
  "description": "BySpace shared protocol schemas and wire types",
5
5
  "files": [
6
6
  "dist",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bytetrue/relay",
3
- "version": "0.15.0",
3
+ "version": "0.16.0",
4
4
  "description": "BySpace relay for bridging daemon and client connections",
5
5
  "files": [
6
6
  "dist",
@@ -1,3 +1,4 @@
1
+ export declare const PI_TERMINAL_HOOK_OWNER_PID_ENV_KEY = "BYSPACE_PI_TERMINAL_HOOK_OWNER_PID";
1
2
  export type BySpaceNodeEnv = "development" | "production" | "test";
2
3
  export type ProcessEnvRecord = Record<string, string | undefined>;
3
4
  export type ExternalProcessEnv = NodeJS.ProcessEnv & Record<string, string>;
@@ -1,5 +1,7 @@
1
1
  const BYSPACE_NODE_ENV = "BYSPACE_NODE_ENV";
2
2
  const ELECTRON_RUN_AS_NODE = "ELECTRON_RUN_AS_NODE";
3
+ // Shared with the installed Pi extension (which cannot import from here).
4
+ export const PI_TERMINAL_HOOK_OWNER_PID_ENV_KEY = "BYSPACE_PI_TERMINAL_HOOK_OWNER_PID";
3
5
  const RUNTIME_CONTROL_ENV_KEYS = [
4
6
  BYSPACE_NODE_ENV,
5
7
  "BYSPACE_DESKTOP_MANAGED",
@@ -7,6 +9,13 @@ const RUNTIME_CONTROL_ENV_KEYS = [
7
9
  ELECTRON_RUN_AS_NODE,
8
10
  "ELECTRON_NO_ATTACH_CONSOLE",
9
11
  "ESBUILD_BINARY_PATH",
12
+ // Written into `process.env` by the Pi terminal-activity extension so child Pi
13
+ // processes do not register a second reporter for the same terminal. If it
14
+ // survives into a fresh terminal or agent, that Pi process sees a marker whose
15
+ // value is a stale pid, concludes it is an inherited child, and registers no
16
+ // handlers at all — the terminal then never reports running/idle. It is
17
+ // per-process state, never inherited. See docs/terminal-activity.md.
18
+ PI_TERMINAL_HOOK_OWNER_PID_ENV_KEY,
10
19
  ];
11
20
  function buildInternalProcessEnv(baseEnv) {
12
21
  return { ...baseEnv };
@@ -1,2 +1,2 @@
1
- export declare const PI_TERMINAL_ACTIVITY_EXTENSION_SOURCE = "// byspace.pi-terminal-activity\nconst ownerPidKey = \"BYSPACE_PI_TERMINAL_HOOK_OWNER_PID\";\n\n// Keep one request in flight and only the latest state waiting behind it.\nexport function createReportQueue(sendReport) {\n let pendingReport;\n let reporting;\n\n async function flushReports() {\n while (pendingReport) {\n const next = pendingReport;\n pendingReport = undefined;\n try {\n await sendReport(next);\n } catch {}\n }\n reporting = undefined;\n }\n\n return {\n enqueue(next) {\n pendingReport = next;\n reporting ??= Promise.resolve().then(flushReports);\n return reporting;\n },\n wait() {\n return reporting ?? Promise.resolve();\n },\n };\n}\n\nasync function sendReport(next) {\n await fetch(next.url, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({\n terminalId: next.terminalId,\n token: next.token,\n state: next.state,\n }),\n signal: AbortSignal.timeout(1_000),\n });\n}\n\nconst reportQueue = createReportQueue(sendReport);\n\nfunction report(state) {\n const url =\n process.env.BYSPACE_TERMINAL_ACTIVITY_URL;\n const terminalId = process.env.BYSPACE_TERMINAL_ID;\n const token = process.env.BYSPACE_ACTIVITY_TOKEN;\n if (!url || !terminalId || !token) return reportQueue.wait();\n\n return reportQueue.enqueue({ url, terminalId, token, state });\n}\n\nexport default function byspaceTerminalActivity(pi) {\n const ownerPid = process.env[ownerPidKey];\n if (ownerPid && ownerPid !== String(process.pid)) return;\n process.env[ownerPidKey] = String(process.pid);\n\n pi.on(\"agent_start\", () => void report(\"running\"));\n pi.on(\"ui_prompt_start\", () => void report(\"needs-input\"));\n pi.on(\"ui_prompt_end\", () => void report(\"running\"));\n pi.on(\"agent_settled\", () => void report(\"idle\"));\n pi.on(\"session_shutdown\", () => report(\"idle\"));\n}\n";
1
+ export declare const PI_TERMINAL_ACTIVITY_EXTENSION_SOURCE = "// byspace.pi-terminal-activity\nconst ownerPidKey = \"BYSPACE_PI_TERMINAL_HOOK_OWNER_PID\";\n\n// Keep one request in flight and only the latest state waiting behind it.\nexport function createReportQueue(sendReport) {\n let pendingReport;\n let reporting;\n\n async function flushReports() {\n while (pendingReport) {\n const next = pendingReport;\n pendingReport = undefined;\n try {\n await sendReport(next);\n } catch {}\n }\n reporting = undefined;\n }\n\n return {\n enqueue(next) {\n pendingReport = next;\n reporting ??= Promise.resolve().then(flushReports);\n return reporting;\n },\n wait() {\n return reporting ?? Promise.resolve();\n },\n };\n}\n\nasync function sendReport(next) {\n await fetch(next.url, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({\n terminalId: next.terminalId,\n token: next.token,\n state: next.state,\n }),\n signal: AbortSignal.timeout(1_000),\n });\n}\n\nconst reportQueue = createReportQueue(sendReport);\n\n// The marker is inherited by Pi child processes so they do not register a second\n// reporter for the same terminal. A marker left by a process that is gone is\n// stale, not an owner: treating it as an owner makes this Pi report nothing at\n// all, which looks exactly like \"the terminal stopped showing running\".\nfunction ownerIsLive(ownerPid) {\n const pid = Number(ownerPid);\n if (!Number.isInteger(pid) || pid <= 0) return false;\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n return error?.code === \"EPERM\";\n }\n}\n\nfunction report(state) {\n const url =\n process.env.BYSPACE_TERMINAL_ACTIVITY_URL;\n const terminalId = process.env.BYSPACE_TERMINAL_ID;\n const token = process.env.BYSPACE_ACTIVITY_TOKEN;\n if (!url || !terminalId || !token) return reportQueue.wait();\n\n return reportQueue.enqueue({ url, terminalId, token, state });\n}\n\nexport default function byspaceTerminalActivity(pi) {\n const ownerPid = process.env[ownerPidKey];\n if (ownerPid && ownerPid !== String(process.pid) && ownerIsLive(ownerPid)) return;\n process.env[ownerPidKey] = String(process.pid);\n\n pi.on(\"agent_start\", () => void report(\"running\"));\n pi.on(\"ui_prompt_start\", () => void report(\"needs-input\"));\n pi.on(\"ui_prompt_end\", () => void report(\"running\"));\n pi.on(\"agent_settled\", () => void report(\"idle\"));\n pi.on(\"session_shutdown\", () => report(\"idle\"));\n}\n";
2
2
  //# sourceMappingURL=pi-extension.d.ts.map
@@ -44,6 +44,21 @@ async function sendReport(next) {
44
44
 
45
45
  const reportQueue = createReportQueue(sendReport);
46
46
 
47
+ // The marker is inherited by Pi child processes so they do not register a second
48
+ // reporter for the same terminal. A marker left by a process that is gone is
49
+ // stale, not an owner: treating it as an owner makes this Pi report nothing at
50
+ // all, which looks exactly like "the terminal stopped showing running".
51
+ function ownerIsLive(ownerPid) {
52
+ const pid = Number(ownerPid);
53
+ if (!Number.isInteger(pid) || pid <= 0) return false;
54
+ try {
55
+ process.kill(pid, 0);
56
+ return true;
57
+ } catch (error) {
58
+ return error?.code === "EPERM";
59
+ }
60
+ }
61
+
47
62
  function report(state) {
48
63
  const url =
49
64
  process.env.BYSPACE_TERMINAL_ACTIVITY_URL;
@@ -56,7 +71,7 @@ function report(state) {
56
71
 
57
72
  export default function byspaceTerminalActivity(pi) {
58
73
  const ownerPid = process.env[ownerPidKey];
59
- if (ownerPid && ownerPid !== String(process.pid)) return;
74
+ if (ownerPid && ownerPid !== String(process.pid) && ownerIsLive(ownerPid)) return;
60
75
  process.env[ownerPidKey] = String(process.pid);
61
76
 
62
77
  pi.on("agent_start", () => void report("running"));
@@ -786,6 +786,12 @@ export async function createTerminal(options) {
786
786
  if (!commandFinished) {
787
787
  return true;
788
788
  }
789
+ // The interactive shell only emits this when its foreground job ends. A
790
+ // terminal agent that exits without reporting idle (SIGKILL, crash, a
791
+ // suspend that never resumes) leaves `working` set forever, so treat the
792
+ // shell regaining the prompt as proof that the agent is gone. `interrupt`
793
+ // only clears `working`; a finished-attention idle state is untouched.
794
+ activityTracker.interrupt();
789
795
  for (const listener of Array.from(commandFinishedListeners)) {
790
796
  try {
791
797
  listener(commandFinished);