crisp-tui 0.1.0 → 0.2.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.
- package/README.md +87 -15
- package/bin/crisp-tui.js +43 -4
- package/package.json +48 -10
- package/dist/cli.js +0 -1506
package/README.md
CHANGED
|
@@ -1,18 +1,41 @@
|
|
|
1
1
|
# crisp-tui
|
|
2
2
|
|
|
3
|
+
[](https://github.com/solcreek/crisp-tui/actions/workflows/ci.yml)
|
|
4
|
+
[](https://www.npmjs.com/package/crisp-tui)
|
|
5
|
+
[](LICENSE)
|
|
6
|
+
[](https://nodejs.org)
|
|
7
|
+
|
|
3
8
|
Crisp support inbox built with OpenTUI, SolidJS and Bun. People use the TUI;
|
|
4
9
|
agents use JSON commands and can prepare drafts in the same running screen.
|
|
5
|
-
[crispctl](https://github.com/solcreek/crisp-cli) v0.
|
|
10
|
+
[crispctl](https://github.com/solcreek/crisp-cli) v0.3.1 provides all REST and RTM
|
|
6
11
|
access. Both profile-based and 1Password sessions use its JSON interface;
|
|
7
12
|
this project has no separate HTTP or Socket.IO implementation.
|
|
8
13
|
|
|
14
|
+

|
|
15
|
+
|
|
16
|
+
Running on Omarchy with the Tokyo Night theme. The agent-prepared draft is ready
|
|
17
|
+
for human review; all contacts and messages shown are demo data.
|
|
18
|
+
|
|
9
19
|
## Install
|
|
10
20
|
|
|
11
|
-
Requires
|
|
12
|
-
|
|
21
|
+
Requires Node.js 20 or newer on macOS or Linux (glibc), on arm64 or x64.
|
|
22
|
+
**Bun is not required for npm/npx users.** npm installs the matching precompiled
|
|
23
|
+
executable, including the Bun runtime and OpenTUI renderer, automatically.
|
|
24
|
+
Windows and musl/Alpine are not currently supported.
|
|
25
|
+
|
|
26
|
+
This distribution targets v0.2.0. Until it is published, npm's v0.1.0 still
|
|
27
|
+
requires a separate Bun installation.
|
|
28
|
+
|
|
29
|
+
Try the demo without a global installation:
|
|
13
30
|
|
|
14
31
|
```sh
|
|
15
|
-
|
|
32
|
+
npx crisp-tui@0.2.0 --demo
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Or install the command:
|
|
36
|
+
|
|
37
|
+
```sh
|
|
38
|
+
npm install -g crisp-tui@0.2.0
|
|
16
39
|
crisp-tui --demo
|
|
17
40
|
```
|
|
18
41
|
|
|
@@ -22,6 +45,8 @@ with a crispctl profile configured, or `crisp-tui live --item 'Crisp development
|
|
|
22
45
|
connection check. Add `--rtm-timeout 60` to require RTM authentication and an
|
|
23
46
|
actual event within 60 seconds. The npm package includes crispctl as a dependency.
|
|
24
47
|
The following `bun run` examples are for a source checkout.
|
|
48
|
+
Keep npm optional dependencies enabled; they carry the platform executable.
|
|
49
|
+
Installation requires no lifecycle scripts or first-run download.
|
|
25
50
|
|
|
26
51
|
## Run from source
|
|
27
52
|
|
|
@@ -39,7 +64,7 @@ Demo mode is explicit, in-memory, and never contacts Crisp. In another terminal:
|
|
|
39
64
|
```sh
|
|
40
65
|
bun run src/index.ts ctl state
|
|
41
66
|
bun run src/index.ts ctl goto session_demo_2
|
|
42
|
-
bun run src/index.ts ctl draft session_demo_2 '
|
|
67
|
+
bun run src/index.ts ctl draft session_demo_2 'Let me help you check your settings.'
|
|
43
68
|
bun run src/index.ts ctl screen
|
|
44
69
|
```
|
|
45
70
|
|
|
@@ -94,10 +119,10 @@ requests use Basic auth with `identifier:key` and `X-Crisp-Tier: website`.
|
|
|
94
119
|
The token belongs to one workspace. `crispctl` supplies these headers; this
|
|
95
120
|
project never includes the secret in UI state or stores a second copy.
|
|
96
121
|
|
|
97
|
-
|
|
122
|
+
This source checkout uses crispctl v0.3.1. To configure it separately on PATH:
|
|
98
123
|
|
|
99
124
|
```sh
|
|
100
|
-
npm install -g crispctl@0.
|
|
125
|
+
npm install -g crispctl@0.3.1
|
|
101
126
|
```
|
|
102
127
|
|
|
103
128
|
Alternatively, build [crisp-cli from source](https://github.com/solcreek/crisp-cli#install)
|
|
@@ -125,7 +150,8 @@ All crispctl config and environment precedence still applies, including
|
|
|
125
150
|
to crispctl. Select the same `--profile` / `--website` when issuing `ctl` commands.
|
|
126
151
|
|
|
127
152
|
Executable lookup: `CRISPCTL_BIN` (one executable path, not a shell command),
|
|
128
|
-
then the
|
|
153
|
+
then the npm launcher's bundled crispctl dependency, then the dependency resolved
|
|
154
|
+
from a source checkout, then `crispctl` on PATH, then
|
|
129
155
|
`../crisp-cli/dist/index.js` relative to this source
|
|
130
156
|
checkout. The last option requires Node. A compiled TUI should use PATH or
|
|
131
157
|
`CRISPCTL_BIN`. Credentials stay in the subprocess environment/config; commands
|
|
@@ -158,6 +184,8 @@ mode are kept separately for each conversation during this process.
|
|
|
158
184
|
A failed send keeps the draft; writes are never retried automatically. A timeout
|
|
159
185
|
can leave the send outcome unknown, so refresh before resending. Once a send is
|
|
160
186
|
acknowledged, a failed follow-up refresh does not restore the draft.
|
|
187
|
+
One-shot crispctl calls have a 30-second deadline; 1Password reads have a
|
|
188
|
+
60-second deadline. Partial output from a timed-out process is discarded.
|
|
161
189
|
|
|
162
190
|
## Agent workflow
|
|
163
191
|
|
|
@@ -189,7 +217,8 @@ bun run src/index.ts ctl refresh
|
|
|
189
217
|
bun run src/index.ts ctl screen
|
|
190
218
|
```
|
|
191
219
|
|
|
192
|
-
`state` includes protocol version, source, current page/query,
|
|
220
|
+
`state` includes protocol version, source, current page/query, selected session,
|
|
221
|
+
conversation-loading state, active conversation,
|
|
193
222
|
loaded messages, per-session drafts and status. `messages` and `conversations`
|
|
194
223
|
return the currently loaded page, without an API call. `screen` is a semantic
|
|
195
224
|
text view of the loaded content, not an exact terminal screenshot. All other
|
|
@@ -217,8 +246,12 @@ One newline-delimited JSON request per connection:
|
|
|
217
246
|
```
|
|
218
247
|
|
|
219
248
|
Response: `{"id":1,"ok":true,"result":…}` or
|
|
220
|
-
`{"id":1,"ok":false,"error":"…"}`. Methods match `ctl` verbs.
|
|
221
|
-
|
|
249
|
+
`{"id":1,"ok":false,"error":"…"}`. Methods match `ctl` verbs. Unknown parameters
|
|
250
|
+
and invalid types are rejected. Screen-changing agent requests are serialized;
|
|
251
|
+
local snapshots (`state`, `screen`, `conversations`, `messages`) remain available
|
|
252
|
+
while a refresh or navigation waits on the API. CLI syntax, parameter validation
|
|
253
|
+
and command permissions are defined together in `src/commands.ts`.
|
|
254
|
+
No TCP server, daemon or MCP server is started.
|
|
222
255
|
|
|
223
256
|
## Refresh and current boundaries
|
|
224
257
|
|
|
@@ -240,24 +273,63 @@ and writes. Consider this alongside the website token's documented daily quota.
|
|
|
240
273
|
Conversation history is the latest page exposed by crispctl; there is no older
|
|
241
274
|
message pagination, background daemon, push notifications, attachment upload or
|
|
242
275
|
preview, persisted drafts, or MCP in this first version. Assignment and segments
|
|
243
|
-
are available via the CLI bridge. The default tests use demo data,
|
|
276
|
+
are available via the CLI bridge. The default tests use demo data, isolated
|
|
244
277
|
subprocesses and local sockets; they never read 1Password or contact Crisp.
|
|
278
|
+
Contract tests run the installed crispctl against an in-memory HTTP interceptor
|
|
279
|
+
with external network access disabled.
|
|
245
280
|
Real read-only checks are separate, explicitly invoked commands.
|
|
246
281
|
|
|
247
282
|
## Verification and binary
|
|
248
283
|
|
|
249
284
|
```sh
|
|
250
285
|
bun run typecheck
|
|
251
|
-
bun test
|
|
252
286
|
bun run build
|
|
287
|
+
bun run test:coverage
|
|
288
|
+
bun run test:package
|
|
253
289
|
./dist/crisp-tui-darwin-arm64 --demo # filename follows OS / architecture
|
|
254
290
|
```
|
|
255
291
|
|
|
256
292
|
The standalone binary embeds Bun and the TUI renderer and needs crispctl on PATH
|
|
257
|
-
or `CRISPCTL_BIN`. The npm package includes crispctl and
|
|
293
|
+
or `CRISPCTL_BIN`. The npm package includes crispctl and its platform executable;
|
|
294
|
+
only Node.js is needed on PATH. Bun 1.4.2 is a development/build requirement.
|
|
258
295
|
Tests exercise the UI with OpenTUI's
|
|
259
296
|
headless renderer, send failures, concurrent navigation, draft isolation,
|
|
260
|
-
subprocess argument handling and the Unix control protocol.
|
|
297
|
+
polling/RTM cleanup, subprocess argument handling and the Unix control protocol.
|
|
298
|
+
CI checks source and compiled PTY workflows, then packs and installs the npm
|
|
299
|
+
artifacts outside the checkout and runs their PTY workflows with Bun absent from
|
|
300
|
+
PATH. A local test registry lets real `npm exec`/`npx` install the root package
|
|
301
|
+
and choose the correct platform dependency automatically. Both installed and
|
|
302
|
+
npx workflows exercise TUI startup, agent drafts, human send, shutdown and the
|
|
303
|
+
crispctl bridge. The package check downloads dependencies from npm; Crisp API
|
|
304
|
+
access is not required. CI runs on macOS/Linux arm64/x64 with Node.js 20 or 24.
|
|
305
|
+
|
|
306
|
+
Coverage excludes test fixtures/helpers, checks for missing source files, and
|
|
307
|
+
enforces overall 90% line and function thresholds from LCOV counts. CI uploads
|
|
308
|
+
`coverage/lcov.info` for each platform. The report measures code executed within
|
|
309
|
+
the test process; PTY subprocess coverage
|
|
310
|
+
(including the thin `src/index.ts` entrypoint) is not merged into that percentage.
|
|
311
|
+
The subprocess tests independently verify the executable behavior.
|
|
312
|
+
|
|
313
|
+
### Publishing platform packages
|
|
314
|
+
|
|
315
|
+
All five package versions must match. `bun run build:package` compiles and stages
|
|
316
|
+
the host platform under `packages/<os>-<arch>/bin/`. `bun run test:package` produces
|
|
317
|
+
verified tarballs in `dist/npm/`. CI uploads them as `npm-<os>-<arch>` artifacts.
|
|
318
|
+
|
|
319
|
+
Use artifacts from one successful CI run for the release commit. Publish all four
|
|
320
|
+
platform packages first, then the main package, so new npx installs can always
|
|
321
|
+
find their binary. This requires npm publisher credentials; CI does not publish.
|
|
322
|
+
|
|
323
|
+
```sh
|
|
324
|
+
gh run download RUN_ID --pattern 'npm-*' --dir release-artifacts
|
|
325
|
+
for platform in darwin-arm64 darwin-x64 linux-arm64 linux-x64; do
|
|
326
|
+
npm publish "release-artifacts/npm-$platform/crisp-tui-$platform-0.2.0.tgz" --access public
|
|
327
|
+
done
|
|
328
|
+
npm publish release-artifacts/npm-darwin-arm64/crisp-tui-0.2.0.tgz --access public
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
Do not publish platform packages directly from an unbuilt workspace. The root
|
|
332
|
+
package's optional dependencies are pinned to the exact release version.
|
|
261
333
|
|
|
262
334
|
## Development data and license
|
|
263
335
|
|
package/bin/crisp-tui.js
CHANGED
|
@@ -1,4 +1,43 @@
|
|
|
1
|
-
#!/usr/bin/env
|
|
2
|
-
|
|
3
|
-
import "
|
|
4
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawn } from "node:child_process"
|
|
3
|
+
import { createRequire } from "node:module"
|
|
4
|
+
import { constants } from "node:os"
|
|
5
|
+
|
|
6
|
+
const require = createRequire(import.meta.url)
|
|
7
|
+
const pkg = require("../package.json")
|
|
8
|
+
const platformPackage = `crisp-tui-${process.platform}-${process.arch}`
|
|
9
|
+
try {
|
|
10
|
+
if (!Object.hasOwn(pkg.optionalDependencies, platformPackage)) {
|
|
11
|
+
throw new Error(`Unsupported platform: ${process.platform}/${process.arch}. crisp-tui supports macOS and Linux on x64 and arm64.`)
|
|
12
|
+
}
|
|
13
|
+
if (process.platform === "linux" && !process.report.getReport().header.glibcVersionRuntime) {
|
|
14
|
+
throw new Error("This crisp-tui package requires glibc on Linux; musl/Alpine is not supported yet.")
|
|
15
|
+
}
|
|
16
|
+
let executable
|
|
17
|
+
try {
|
|
18
|
+
const installed = require(`${platformPackage}/package.json`)
|
|
19
|
+
if (installed.version !== pkg.version) throw new Error("Version mismatch")
|
|
20
|
+
executable = require.resolve(`${platformPackage}/bin/crisp-tui`)
|
|
21
|
+
} catch {
|
|
22
|
+
throw new Error(`Missing ${platformPackage}@${pkg.version}. Reinstall crisp-tui with optional dependencies enabled (npm install --include=optional crisp-tui@${pkg.version}).`)
|
|
23
|
+
}
|
|
24
|
+
const child = spawn(executable, process.argv.slice(2), {
|
|
25
|
+
stdio: "inherit",
|
|
26
|
+
env: { ...process.env, CRISP_TUI_NODE: process.execPath, CRISP_TUI_CRISPCTL: require.resolve("crispctl/dist/index.js") },
|
|
27
|
+
})
|
|
28
|
+
const signals = ["SIGINT", "SIGTERM", "SIGHUP"]
|
|
29
|
+
const handlers = signals.map(signal => { const handler = () => child.kill(signal); process.on(signal, handler); return handler })
|
|
30
|
+
const cleanup = () => signals.forEach((signal, i) => process.off(signal, handlers[i]))
|
|
31
|
+
child.once("error", () => {
|
|
32
|
+
cleanup()
|
|
33
|
+
console.error(JSON.stringify({ ok: false, error: "Could not start the crisp-tui executable. Reinstall the package and check executable permissions." }))
|
|
34
|
+
process.exitCode = 1
|
|
35
|
+
})
|
|
36
|
+
child.once("exit", (code, signal) => {
|
|
37
|
+
cleanup()
|
|
38
|
+
process.exitCode = code ?? (128 + (constants.signals[signal] || 1))
|
|
39
|
+
})
|
|
40
|
+
} catch (error) {
|
|
41
|
+
console.error(JSON.stringify({ ok: false, error: error instanceof Error ? error.message : "Could not start crisp-tui" }))
|
|
42
|
+
process.exitCode = 1
|
|
43
|
+
}
|
package/package.json
CHANGED
|
@@ -1,15 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "crisp-tui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "A terminal inbox for Crisp, with JSON control commands for agents",
|
|
5
5
|
"license": "MIT",
|
|
6
|
-
"repository": {
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/solcreek/crisp-tui.git"
|
|
9
|
+
},
|
|
7
10
|
"homepage": "https://github.com/solcreek/crisp-tui#readme",
|
|
8
|
-
"bugs": {
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/solcreek/crisp-tui/issues"
|
|
13
|
+
},
|
|
9
14
|
"type": "module",
|
|
10
|
-
"bin": {
|
|
11
|
-
|
|
12
|
-
|
|
15
|
+
"bin": {
|
|
16
|
+
"crisp-tui": "bin/crisp-tui.js"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"bin/crisp-tui.js",
|
|
20
|
+
"README.md",
|
|
21
|
+
"LICENSE"
|
|
22
|
+
],
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public",
|
|
25
|
+
"registry": "https://registry.npmjs.org/"
|
|
26
|
+
},
|
|
13
27
|
"scripts": {
|
|
14
28
|
"dev": "bun run src/index.ts",
|
|
15
29
|
"demo": "bun run src/index.ts --demo",
|
|
@@ -17,16 +31,40 @@
|
|
|
17
31
|
"live:check": "bun run scripts/live-readonly.ts --check",
|
|
18
32
|
"typecheck": "tsc --noEmit",
|
|
19
33
|
"test": "bun test",
|
|
34
|
+
"test:coverage": "bun test --coverage && bun run scripts/check-coverage.ts",
|
|
35
|
+
"test:package": "bun run scripts/test-package.ts",
|
|
20
36
|
"build": "bun run scripts/build.ts",
|
|
21
37
|
"build:package": "bun run scripts/build-package.ts",
|
|
22
|
-
"prepack": "bun run
|
|
38
|
+
"prepack": "bun run scripts/check-package.ts"
|
|
23
39
|
},
|
|
24
40
|
"dependencies": {
|
|
41
|
+
"crispctl": "0.3.1"
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@types/bun": "1.3.14",
|
|
45
|
+
"typescript": "5.9.3",
|
|
25
46
|
"@opentui/core": "0.5.12",
|
|
26
47
|
"@opentui/solid": "0.5.12",
|
|
27
|
-
"crispctl": "0.2.0",
|
|
28
48
|
"solid-js": "1.9.12"
|
|
29
49
|
},
|
|
30
|
-
"
|
|
31
|
-
|
|
50
|
+
"engines": {
|
|
51
|
+
"node": ">=20"
|
|
52
|
+
},
|
|
53
|
+
"workspaces": [
|
|
54
|
+
"packages/*"
|
|
55
|
+
],
|
|
56
|
+
"os": [
|
|
57
|
+
"darwin",
|
|
58
|
+
"linux"
|
|
59
|
+
],
|
|
60
|
+
"cpu": [
|
|
61
|
+
"arm64",
|
|
62
|
+
"x64"
|
|
63
|
+
],
|
|
64
|
+
"optionalDependencies": {
|
|
65
|
+
"crisp-tui-darwin-arm64": "0.2.0",
|
|
66
|
+
"crisp-tui-darwin-x64": "0.2.0",
|
|
67
|
+
"crisp-tui-linux-arm64": "0.2.0",
|
|
68
|
+
"crisp-tui-linux-x64": "0.2.0"
|
|
69
|
+
}
|
|
32
70
|
}
|