workbite 0.1.4 → 0.1.6

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.
package/README.md CHANGED
@@ -3,15 +3,26 @@
3
3
  WorkBite installs and opens **Work Stack** (organizes the work) and
4
4
  **StackBite** (gets it moving) as one native suite.
5
5
 
6
- Version 0.1.4 opens the unified Rust UI: select a Task, start its agent, and
7
- use `9 Execution` to see and control its native terminal in the same window.
8
- The existing 1–8 menus remain available. Task completion stays an explicit action.
6
+ Launcher 0.1.6 (native bundle 0.1.6) opens the familiar TypeScript
7
+ Work Stack UI by default. The unified Rust UI, where you select a Task, start
8
+ its agent and use `9 Execution` to see and control its native terminal in the
9
+ same window, is opt-in per open: `workbite open --frontend rust` (or bare
10
+ `workbite --frontend rust`). The TypeScript UI does not yet embed `9 Execution`.
11
+ Either frontend reuses the same owner and StackBite backend; the choice is not
12
+ saved. Task completion stays an explicit action.
13
+
14
+ 0.1.6 rebuilds the Windows terminal core for baseline x64 CPUs, removing the
15
+ previous build machine's AVX-512 requirement, and adds bounded native startup
16
+ failure diagnostics. Linux still supports glibc 2.28+. Updating from the 0.1.4
17
+ native bundle requires an operator handover of existing backend processes;
18
+ the launcher does not stop them or clear startup records automatically.
9
19
 
10
20
  ```sh
11
21
  npm install -g workbite
12
22
  workbite install
13
23
  workbite open --workspace /abs/path/new-folder --init # first time, once
14
- workbite # afterwards
24
+ workbite # afterwards (TypeScript UI)
25
+ workbite --frontend rust # unified Rust UI with 9 Execution
15
26
  ```
16
27
 
17
28
  Node.js 20+ on Windows x64 or Linux x64 (glibc 2.28+).
@@ -21,9 +32,11 @@ Node.js 20+ on Windows x64 or Linux x64 (glibc 2.28+).
21
32
  every file listed in its `bundle.json`, and installs it into an immutable
22
33
  per-user version folder. No auto-update, no install scripts, no dependencies.
23
34
  - `workbite check` re-verifies the installed bundle without downloading.
24
- - `workbite open --workspace ABS [--init] [--no-ui]` starts or reuses the
25
- workspace's Work Stack owner and a StackBite backend (only processes it can
26
- prove it started), then runs the unified WorkBite terminal UI. Backends keep
35
+ - `workbite open --workspace ABS [--init] [--no-ui] [--frontend typescript|rust]`
36
+ starts or reuses the workspace's Work Stack owner and a StackBite backend
37
+ (only processes it can prove it started), then runs the TypeScript Work Stack
38
+ UI, or the unified Rust UI with `--frontend rust` (0.1.4+ execution bundle
39
+ only; an older bundle refuses it before starting anything). Backends keep
27
40
  running after the UI exits.
28
41
  - `workbite` (or `workbite open` without `--workspace`) reopens the last
29
42
  workspace that opened successfully; an explicit `--workspace` always wins.
package/lib/cli.js CHANGED
@@ -2,7 +2,7 @@
2
2
  const path = require('node:path');
3
3
  const { fail, readSmall } = require('./common');
4
4
  const { locations, releaseSpec, ensureInstalled, stageReporter, packageVersion } = require('./install');
5
- const { openSuite } = require('./runtime');
5
+ const { openSuite, FRONTENDS } = require('./runtime');
6
6
  const { bindAgent, executeAgent, agentCapabilities, WRITE_COMMANDS, MAX_PACKET_BYTES } = require('./agent');
7
7
 
8
8
  const HELP = `WorkBite ${packageVersion} - Work Stack organizes the work. StackBite gets it moving.
@@ -10,10 +10,11 @@ const HELP = `WorkBite ${packageVersion} - Work Stack organizes the work. StackB
10
10
  Usage:
11
11
  workbite install download, verify and install the pinned native suite
12
12
  workbite check verify the installed suite (no download, no processes)
13
- workbite open --workspace ABS [--init] [--no-ui]
13
+ workbite open --workspace ABS [--init] [--no-ui] [--frontend typescript|rust]
14
14
  start or reuse this workspace's Work Stack owner and the
15
15
  StackBite backend, then run the Work Stack terminal UI
16
- workbite [open] [--no-ui] reopen the last workspace WorkBite opened successfully
16
+ workbite [open] [--no-ui] [--frontend typescript|rust]
17
+ reopen the last workspace WorkBite opened successfully
17
18
  workbite agent [--workspace ABS --workspace-uid UUID] COMMAND [--input-file FILE | --stdin] [flags]
18
19
  curated Work Stack agent commands against the running,
19
20
  WorkBite-owned owner (never starts one): capabilities, status,
@@ -32,6 +33,8 @@ open:
32
33
  --workspace ABS absolute workspace folder; always wins over the remembered one
33
34
  --init create a new Work Stack workspace in a new or empty folder (needs --workspace)
34
35
  --no-ui start or reuse the backends, print one JSON summary and exit
36
+ --frontend NAME typescript (default): the familiar Work Stack UI; rust: the unified UI with
37
+ 9 Execution (execution bundles only). Chosen per open, never saved.
35
38
 
36
39
  First time, name the workspace once:
37
40
  workbite open --workspace /abs/path/new-folder --init
@@ -148,6 +151,11 @@ function parseArguments(argv) {
148
151
  else if (argument === '--no-ui' && options.ui) options.ui = false;
149
152
  else if (argument === '--workspace' && options.workspace === undefined && rest[index + 1] !== undefined
150
153
  && !rest[index + 1].startsWith('--')) options.workspace = rest[++index];
154
+ else if (argument === '--frontend' && options.frontend === undefined) {
155
+ const name = rest[++index];
156
+ if (!FRONTENDS.includes(name)) fail(`--frontend must be one of: ${FRONTENDS.join(', ')}`);
157
+ options.frontend = name;
158
+ }
151
159
  else fail(`Unknown or repeated open option: ${String(argument).slice(0, 64)}. See workbite --help.`);
152
160
  }
153
161
  // Without --workspace the remembered workspace is reopened; --init never picks a folder by itself.
@@ -237,7 +245,7 @@ async function main(argv = process.argv.slice(2), options = {}) {
237
245
  return { code: 0, signal: null };
238
246
  }
239
247
  return openSuite({ installed, commands: options.commands, workspace: parsed.workspace, init: parsed.init, ui: parsed.ui,
240
- stateRoot, environment, spawnImpl: options.spawnImpl, execImpl: options.execImpl, stdout, timeouts: options.timeouts });
248
+ frontend: parsed.frontend, stateRoot, environment, spawnImpl: options.spawnImpl, execImpl: options.execImpl, stdout, timeouts: options.timeouts });
241
249
  }
242
250
 
243
251
  module.exports = { main, parseArguments, HELP };
package/lib/runtime.js CHANGED
@@ -20,6 +20,8 @@ const CONNECTION_SCHEMA = 'workstack.helm-connection.v1';
20
20
  const OWNER_SCHEMA = 'workbite.owner.v2';
21
21
  const STACKBITE_SCHEMA = 'workbite.stackbite-backend.v2';
22
22
  const SELECTION_SCHEMA = 'workbite.workspace-selection.v1';
23
+ // Foreground UI per open: the familiar TypeScript Work Stack UI by default, the unified Rust UI on request.
24
+ const FRONTENDS = Object.freeze(['typescript', 'rust']);
23
25
  const LOOPBACK = /^http:\/\/127\.0\.0\.1:([1-9][0-9]{0,4})$/;
24
26
  // Ports of the existing official StackBite and its previews are never chosen.
25
27
  const RESERVED_PORTS = new Set([8089, 8090, 8091, 54036, 54039, 54236, 54239]);
@@ -540,14 +542,22 @@ function runForeground(command, args, environment, { spawnImpl = spawn, signalSo
540
542
 
541
543
  // commands maps each bundle executable to its argv prefix; tests substitute fixtures.
542
544
  async function openSuite({ installed, commands, workspace, init = false, stateRoot, environment = process.env,
543
- ui = true, spawnImpl = spawn, execImpl = execFile, platform = process.platform, stdout = process.stdout, timeouts = {} }) {
545
+ ui = true, frontend = 'typescript', spawnImpl = spawn, execImpl = execFile, platform = process.platform,
546
+ stdout = process.stdout, timeouts = {} }) {
547
+ if (!FRONTENDS.includes(frontend)) fail(`--frontend must be one of: ${FRONTENDS.join(', ')}`);
544
548
  if (workspace !== undefined) workspace = checkedWorkspace(workspace);
545
549
  else if (init) fail('--init needs --workspace ABS naming the new or empty folder');
546
550
  commands = commands || Object.fromEntries(Object.entries(installed.executables).map(([name, file]) => [name, [file]]));
547
- // A v2 bundle always runs its execution UI; a v1 bundle keeps the legacy UI. There is no fallback between them.
551
+ // A v2 bundle keeps its owner/backend markers and native init whichever frontend runs; only the
552
+ // foreground UI differs. TypeScript is the default; rust needs a v2 bundle. There is no fallback between them.
548
553
  const execution = installed.bundle?.schema === BUNDLE_V2 ? { bundleVersion: installed.bundle.version } : null;
549
- if (execution && !(Array.isArray(commands.workbite_tui) && commands.workbite_tui.length)) {
550
- fail('This WorkBite bundle has no verified execution UI executable; nothing was started.');
554
+ if (frontend === 'rust' && !execution) {
555
+ fail('--frontend rust needs a WorkBite execution (v2) bundle; this installed bundle has only the TypeScript UI. Nothing was started.');
556
+ }
557
+ const uiCommand = frontend === 'rust' ? 'workbite_tui' : 'workstack_tui';
558
+ if (!(Array.isArray(commands[uiCommand]) && commands[uiCommand].length)) {
559
+ fail(frontend === 'rust' ? 'This WorkBite bundle has no verified execution UI executable; nothing was started.'
560
+ : 'This WorkBite bundle has no verified TypeScript UI executable; nothing was started.');
551
561
  }
552
562
  const layout = stateLayout(path.resolve(stateRoot));
553
563
  await prepareState(layout);
@@ -584,20 +594,21 @@ async function openSuite({ installed, commands, workspace, init = false, stateRo
584
594
  });
585
595
  const summary = { schema: 'workbite.open.v1', workspace, workspace_uid: session.uid, endpoint: session.engine.endpoint,
586
596
  owner_reused: session.engine.reused, stackbite_url: session.stackbite.url, stackbite_reused: session.stackbite.reused,
587
- backend_id: session.backendId, state: layout.root,
597
+ backend_id: session.backendId, state: layout.root, frontend,
588
598
  ...(execution ? { execution_ui: session.executionUi, execution_bundle_version: execution.bundleVersion } : {}) };
589
599
  if (!ui) {
590
600
  stdout.write(JSON.stringify(summary) + '\n');
591
601
  return { code: 0, signal: null, summary };
592
602
  }
593
603
  const environmentForUi = uiEnvironment(base, { executables: installed.executables, layout, endpoint: session.engine.endpoint,
594
- uid: session.uid, backendId: session.backendId, execution });
604
+ uid: session.uid, backendId: session.backendId, execution: frontend === 'rust' ? execution : null });
595
605
  // Exactly one foreground child in this terminal (inherited stdio, never detached or a new console).
596
- const result = await runForeground(execution ? commands.workbite_tui : commands.workstack_tui, [], environmentForUi, { spawnImpl });
606
+ // The TypeScript UI gets the same environment as on a v1 bundle, so it keeps its own familiar settings file.
607
+ const result = await runForeground(commands[uiCommand], [], environmentForUi, { spawnImpl });
597
608
  return { ...result, summary };
598
609
  }
599
610
 
600
611
  module.exports = { cleanEnvironment, stateLayout, prepareState, ensureBackendId, workspaceKey, readWorkspaceUid,
601
612
  initializeWorkspace, engineIdentity, stackbiteIdentity, freePort, ensureEngine, ensureStackbite, writeDockConfig,
602
613
  withLock, uiEnvironment, openSuite, rememberedWorkspace, ensureExecutionSettings, initializeNativeRuntime, RESERVED_PORTS,
603
- SELECTION_SCHEMA, EXECUTION_UI_DEFAULT, NATIVE_INIT_SCHEMA };
614
+ SELECTION_SCHEMA, EXECUTION_UI_DEFAULT, NATIVE_INIT_SCHEMA, FRONTENDS };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "workbite",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "WorkBite (Work Stack + StackBite) verified native suite installer and launcher",
5
5
  "license": "UNLICENSED",
6
6
  "engines": {
package/release.json CHANGED
@@ -1,24 +1,24 @@
1
1
  {
2
2
  "schema": "workbite.release.v1",
3
3
  "product": "WorkBite",
4
- "version": "0.1.4",
5
- "launcherVersion": "0.1.4",
4
+ "version": "0.1.6",
5
+ "launcherVersion": "0.1.6",
6
6
  "repository": "Shinick-Han/WorkBite-releases",
7
- "tag": "v0.1.4",
7
+ "tag": "v0.1.6",
8
8
  "platforms": {
9
9
  "windows-x64": {
10
- "asset": "workbite-0.1.4-windows-x64.zip",
11
- "sha256": "82150e6731bbe2cc00b08265ea5f97f12dc92e6213d32fc53ba4cd3bb1f98c50",
12
- "size": 97936126,
13
- "bundleSha256": "77efe214a312c14f4565075574541777a96e541ce3d0065d3e85184b0c4a2568",
14
- "url": "https://github.com/Shinick-Han/WorkBite-releases/releases/download/v0.1.4/workbite-0.1.4-windows-x64.zip"
10
+ "asset": "workbite-0.1.6-windows-x64.zip",
11
+ "sha256": "7a639475361111a5afb8c04ac5d8532a125f57c1de00f9b1a6587356357bbe65",
12
+ "size": 97763242,
13
+ "bundleSha256": "aadb8ab699423879b6ce56a987ad3e1f2d242764f057fa249d8537f3e3841630",
14
+ "url": "https://github.com/Shinick-Han/WorkBite-releases/releases/download/v0.1.6/workbite-0.1.6-windows-x64.zip"
15
15
  },
16
16
  "linux-x64": {
17
- "asset": "workbite-0.1.4-linux-x64.tar.gz",
18
- "sha256": "f349f8c0eebbcf171a488bd1108d74b123cb57633ec6fc54c55c79532b47ae12",
19
- "size": 81647804,
20
- "bundleSha256": "aa37923f4dd74e8a12ceac09d26cea956a960ea6d34939be1bef303c79042222",
21
- "url": "https://github.com/Shinick-Han/WorkBite-releases/releases/download/v0.1.4/workbite-0.1.4-linux-x64.tar.gz"
17
+ "asset": "workbite-0.1.6-linux-x64.tar.gz",
18
+ "sha256": "028f237823078d2adfb96d074b62ed1c8538879a46dd55252a49f43a0f2092b7",
19
+ "size": 81660896,
20
+ "bundleSha256": "3fb3d0b42341df58ee00664342407d00b3251795686300f1000261eb8dffe725",
21
+ "url": "https://github.com/Shinick-Han/WorkBite-releases/releases/download/v0.1.6/workbite-0.1.6-linux-x64.tar.gz"
22
22
  }
23
23
  }
24
24
  }