@dassi_ai/cli 0.7.0 → 0.7.1
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 +3 -3
- package/daemon-client.mjs +3 -1
- package/dassi-daemon.mjs +5 -2
- package/dassi-shared.mjs +6 -1
- package/dassi.mjs +2 -3
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -138,20 +138,20 @@ dassi launch --stop dev
|
|
|
138
138
|
|
|
139
139
|
Launch supports `--dist`, `--chrome`, `--profile-dir`, `--load-mode auto|pipe|flag`, and Chrome arguments after `--`. Branded Chrome uses a detached helper holding a CDP pipe for the unpacked extension; Chromium/Chrome for Testing can use `--load-extension` directly.
|
|
140
140
|
|
|
141
|
-
CLI 0.7 requires the current extension with live tool discovery, and CLI protocol 3 for task submission. Incompatible clients, daemons, and extensions fail before a task is submitted, in either upgrade order. After upgrading the CLI, finish any old CLI calls and restart an older daemon if prompted (its PID is in `~/.dassi/default.pid`). Browser conversations survive a daemon restart.
|
|
141
|
+
CLI 0.7 requires the current extension with live tool discovery, and CLI protocol 3 for task submission. Incompatible clients, daemons, and extensions fail before a task is submitted, in either upgrade order. After upgrading the CLI, finish any old CLI calls and restart an older daemon if prompted (its PID is in `~/.dassi/default.pid`). Browser conversations survive a daemon restart. Merging a `cli/package.json` version bump to `main` publishes this package (`.github/workflows/publish-cli.yml`, npm trusted publishing); an extension release is blocked until the CLI on npm speaks the protocol it requires.
|
|
142
142
|
|
|
143
143
|
`run --timeout` is rejected with migration instructions. Use `--wait` to observe and `stop` to cancel. Scripts must check task status and explicitly stop a task if they impose an execution budget. `--session`/`DASSI_SESSION` are retained for development compatibility; they select a daemon socket, not a browser or conversation. Normal use needs neither. `DASSI_BRIDGE_PORT` configures an isolated development bridge.
|
|
144
144
|
|
|
145
145
|
The daemon routes short requests. Native runtime admission controls each conversation; the daemon does not serialize unrelated profiles or hold a connection for a task's lifetime. Startup requires no sign-in. The native conversation owns admission, cancellation, recovery, and transcript. Status reads its transcript and state in one storage transaction; a single last-run summary survives later compaction. There is no per-prompt task ledger.
|
|
146
146
|
|
|
147
|
-
|
|
147
|
+
A protocol bump ships CLI first: the CLI publishes on merge, and the extension release refuses to tag until npm `latest` declares that protocol (`scripts/check-cli-on-npm.sh` reads `dassi.protocol` from `cli/package.json` via `npm view`). While the matching extension is still in Chrome Web Store review, a freshly installed CLI reports that the extension is older and must be updated; CLIs already installed keep working against the store build. Check the packed npm artifact in a fresh global prefix, then verify setup against that store installation: extension confirmation, signed-out browser access, profile choice, agent discovery, an initial tab listing, and resume after interruption. Local builds and injected browser responses do not establish that store-to-npm release path.
|
|
148
148
|
|
|
149
149
|
## Output for scripts
|
|
150
150
|
|
|
151
151
|
Browser and task commands with `--json` write their response to stdout, including argument, setup, and connection failures:
|
|
152
152
|
|
|
153
153
|
```json
|
|
154
|
-
{"success": false, "error": "An older Dassi daemon is running. Finish active tasks,
|
|
154
|
+
{"success": false, "error": "An older Dassi daemon is running. Finish active tasks, stop it (kill the PID in ~/.dassi/default.pid), then retry with this CLI."}
|
|
155
155
|
```
|
|
156
156
|
|
|
157
157
|
Parse stdout even on a nonzero exit. Successful responses contain `data`; failures contain `error`. Direct group tools return an array of `{tabId, response}`. Task status, rather than exit zero alone, tells you whether delegated work finished. `--help`, `--version`, and `skill` also support JSON, with a string in `data`. Development `launch` commands use terminal output.
|
package/daemon-client.mjs
CHANGED
|
@@ -9,6 +9,7 @@ import {
|
|
|
9
9
|
getSocketPath,
|
|
10
10
|
CLI_PROTOCOL_VERSION,
|
|
11
11
|
getReadyFile,
|
|
12
|
+
getPidFile,
|
|
12
13
|
isDaemonRunning,
|
|
13
14
|
parseReadyPayload,
|
|
14
15
|
CHROME_WEB_STORE_URL,
|
|
@@ -156,7 +157,8 @@ export async function ensureDaemonReady(session) {
|
|
|
156
157
|
}
|
|
157
158
|
|
|
158
159
|
if (ready.status === 'error') throw new Error(ready.error);
|
|
159
|
-
if (ready.protocolVersion
|
|
160
|
+
if (ready.protocolVersion > CLI_PROTOCOL_VERSION) throw new Error(`A newer Dassi daemon is running (protocol ${ready.protocolVersion}, this CLI speaks ${CLI_PROTOCOL_VERSION}). Run \`npm install -g @dassi_ai/cli@latest\` and retry.`);
|
|
161
|
+
if (ready.protocolVersion !== CLI_PROTOCOL_VERSION) throw new Error(`An older Dassi daemon is running. Finish active tasks, stop it (kill the PID in ${getPidFile(session)}), then retry with this CLI.`);
|
|
160
162
|
|
|
161
163
|
return socketPath;
|
|
162
164
|
}
|
package/dassi-daemon.mjs
CHANGED
|
@@ -182,11 +182,15 @@ export async function dispatchToExtension(cmd, reg = registry) {
|
|
|
182
182
|
}
|
|
183
183
|
|
|
184
184
|
/** Discovery is independent of authentication and in-flight agent work. */
|
|
185
|
+
const session = validateSession(process.env.DASSI_SESSION ?? 'default');
|
|
186
|
+
|
|
185
187
|
export async function routeCommand(cmd, reg = registry, dispatch = dispatchToExtension) {
|
|
186
188
|
let resolvedProfile;
|
|
187
189
|
const call = (command) => dispatch(command, reg);
|
|
188
190
|
try {
|
|
189
|
-
if (['run', 'task_status', 'task_stop'].includes(cmd.action) && cmd.protocolVersion !== CLI_PROTOCOL_VERSION) throw new Error(
|
|
191
|
+
if (['run', 'task_status', 'task_stop'].includes(cmd.action) && cmd.protocolVersion !== CLI_PROTOCOL_VERSION) throw new Error(cmd.protocolVersion > CLI_PROTOCOL_VERSION
|
|
192
|
+
? `This Dassi daemon is older than the CLI (daemon protocol ${CLI_PROTOCOL_VERSION}, CLI ${cmd.protocolVersion}). Stop it (kill the PID in ${getPidFile(session)}) and retry.`
|
|
193
|
+
: `Incompatible CLI (protocol ${cmd.protocolVersion ?? 'none'}, this daemon speaks ${CLI_PROTOCOL_VERSION}). Run \`npm install -g @dassi_ai/cli@latest\` and retry.`);
|
|
190
194
|
let target = cmd.target ?? null;
|
|
191
195
|
let localTaskId = cmd.taskId;
|
|
192
196
|
if (cmd.action === 'task_status' || cmd.action === 'task_stop' || (cmd.action === 'run' && cmd.taskId)) {
|
|
@@ -347,7 +351,6 @@ function startIdleShutdown(server, session, getLastCommandAt) {
|
|
|
347
351
|
* @returns {Promise<void>}
|
|
348
352
|
*/
|
|
349
353
|
export async function startDaemon() {
|
|
350
|
-
const session = validateSession(process.env.DASSI_SESSION ?? 'default');
|
|
351
354
|
const { socketPath, readyFile } = initDaemonProcess(session);
|
|
352
355
|
|
|
353
356
|
try {
|
package/dassi-shared.mjs
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export const CLI_PROTOCOL_VERSION = 3;
|
|
2
1
|
/**
|
|
3
2
|
* Dassi CLI Shared Utilities
|
|
4
3
|
*
|
|
@@ -10,6 +9,12 @@ export const CLI_PROTOCOL_VERSION = 3;
|
|
|
10
9
|
import * as fs from 'fs';
|
|
11
10
|
import * as path from 'path';
|
|
12
11
|
import * as os from 'os';
|
|
12
|
+
import { fileURLToPath } from 'url';
|
|
13
|
+
|
|
14
|
+
const PACKAGE = JSON.parse(fs.readFileSync(path.join(path.dirname(fileURLToPath(import.meta.url)), 'package.json'), 'utf8'));
|
|
15
|
+
export const CLI_VERSION = PACKAGE.version;
|
|
16
|
+
/** Lives in package.json so the extension release gate can read it from npm (`npm view … dassi.protocol`) without downloading the tarball. */
|
|
17
|
+
export const CLI_PROTOCOL_VERSION = PACKAGE.dassi.protocol;
|
|
13
18
|
|
|
14
19
|
// ─── Extension identity ───────────────────────────────────────────────────────
|
|
15
20
|
|
package/dassi.mjs
CHANGED
|
@@ -9,7 +9,7 @@ import * as path from 'path';
|
|
|
9
9
|
import * as child_process from 'child_process';
|
|
10
10
|
import { randomUUID } from 'node:crypto';
|
|
11
11
|
import { fileURLToPath, pathToFileURL } from 'url';
|
|
12
|
-
import { getSocketPath, validateSession, getAppDir, getLaunchesFile } from './dassi-shared.mjs';
|
|
12
|
+
import { getSocketPath, validateSession, getAppDir, getLaunchesFile, CLI_VERSION } from './dassi-shared.mjs';
|
|
13
13
|
import { ensureDaemonRunning, sendCommand, sendAndWait, ensureDaemonReady } from './daemon-client.mjs';
|
|
14
14
|
import { dispatchLaunch } from './launch.mjs';
|
|
15
15
|
import { parseToolCommand, requireTarget, parseStrictInt, parseTarget, parseWait } from './tool-commands.mjs';
|
|
@@ -18,7 +18,6 @@ import { formatResponse } from './format-response.mjs';
|
|
|
18
18
|
import { HELP_TEXT } from './help-text.mjs';
|
|
19
19
|
|
|
20
20
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
21
|
-
const VERSION = JSON.parse(fs.readFileSync(path.join(__dirname, 'package.json'), 'utf8')).version;
|
|
22
21
|
|
|
23
22
|
// ─── Arg parsing ──────────────────────────────────────────────────────────────
|
|
24
23
|
|
|
@@ -243,7 +242,7 @@ function consumeFlag(args, flag) {
|
|
|
243
242
|
|
|
244
243
|
function handleImmediateAction({ action, params, json }) {
|
|
245
244
|
let text;
|
|
246
|
-
if (action === 'version') text =
|
|
245
|
+
if (action === 'version') text = CLI_VERSION;
|
|
247
246
|
else if (action === 'help') text = HELP_TEXT;
|
|
248
247
|
else if (action === 'skill') {
|
|
249
248
|
const skillDir = path.join(__dirname, 'skills', 'dassi');
|
package/package.json
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dassi_ai/cli",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.1",
|
|
4
4
|
"description": "CLI for the Dassi Chrome extension \u2014 run browser automation from the terminal",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"dassi": {
|
|
7
|
+
"protocol": 3
|
|
8
|
+
},
|
|
6
9
|
"bin": {
|
|
7
10
|
"dassi": "./dassi.mjs"
|
|
8
11
|
},
|