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 +20 -7
- package/lib/cli.js +12 -4
- package/lib/runtime.js +19 -8
- package/package.json +1 -1
- package/release.json +13 -13
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
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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]
|
|
25
|
-
workspace's Work Stack owner and a StackBite backend
|
|
26
|
-
prove it started), then runs the
|
|
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]
|
|
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,
|
|
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
|
|
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 (
|
|
550
|
-
fail('
|
|
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
|
-
|
|
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
package/release.json
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schema": "workbite.release.v1",
|
|
3
3
|
"product": "WorkBite",
|
|
4
|
-
"version": "0.1.
|
|
5
|
-
"launcherVersion": "0.1.
|
|
4
|
+
"version": "0.1.6",
|
|
5
|
+
"launcherVersion": "0.1.6",
|
|
6
6
|
"repository": "Shinick-Han/WorkBite-releases",
|
|
7
|
-
"tag": "v0.1.
|
|
7
|
+
"tag": "v0.1.6",
|
|
8
8
|
"platforms": {
|
|
9
9
|
"windows-x64": {
|
|
10
|
-
"asset": "workbite-0.1.
|
|
11
|
-
"sha256": "
|
|
12
|
-
"size":
|
|
13
|
-
"bundleSha256": "
|
|
14
|
-
"url": "https://github.com/Shinick-Han/WorkBite-releases/releases/download/v0.1.
|
|
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.
|
|
18
|
-
"sha256": "
|
|
19
|
-
"size":
|
|
20
|
-
"bundleSha256": "
|
|
21
|
-
"url": "https://github.com/Shinick-Han/WorkBite-releases/releases/download/v0.1.
|
|
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
|
}
|