datagrok-tools 6.7.6 → 6.7.8
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/.devcontainer/PACKAGES_DEV.md +14 -13
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +6 -1
- package/CLAUDE.md +1 -1
- package/GROK_S.md +14 -1
- package/README.md +2 -1
- package/bin/commands/server.js +19 -0
- package/bin/grok.js +8 -4
- package/bin/utils/node-dapi.js +14 -0
- package/package.json +2 -2
|
@@ -66,7 +66,7 @@ Host machine
|
|
|
66
66
|
│ │ │ └── <folder>/ ← bind mount of user's repo │ │
|
|
67
67
|
│ │ ├── /var/run/docker.sock ← host Docker for stand mgmt │ │
|
|
68
68
|
│ │ ├── entrypoint.sh ← bind-mounted from tools/ │ │
|
|
69
|
-
│ │ ├── Claude Code + MCP plugins (
|
|
69
|
+
│ │ ├── Claude Code + MCP plugins (GitHub, Jira) │ │
|
|
70
70
|
│ │ ├── Playwright + Chrome for testing │ │
|
|
71
71
|
│ │ └── grok CLI for build/publish/test │ │
|
|
72
72
|
│ └────────────────────────────────────────────────────────────┘ │
|
|
@@ -197,15 +197,25 @@ Based on `node:22-bookworm-slim`. Pre-installed:
|
|
|
197
197
|
|
|
198
198
|
Runs as **root** in compose (entrypoint drops to `node` user for the main process).
|
|
199
199
|
|
|
200
|
-
## MCP plugins:
|
|
200
|
+
## MCP plugins: GitHub and Jira
|
|
201
201
|
|
|
202
202
|
The agent uses MCP plugins to search for similar issues, read context, and update
|
|
203
|
-
status.
|
|
203
|
+
status. Tickets are GitHub issues (`datagrok-ai/public`); Jira holds only read-only
|
|
204
|
+
`GROK-NNNNN` history. Set tokens in `.env` or the agent will ask interactively on first use.
|
|
204
205
|
|
|
205
|
-
###
|
|
206
|
+
### GitHub
|
|
206
207
|
|
|
207
208
|
```bash
|
|
208
209
|
# Inside tools-dev, register the MCP server:
|
|
210
|
+
claude mcp add github -s user -- \
|
|
211
|
+
npx -y @modelcontextprotocol/server-github
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Requires `GITHUB_TOKEN` in the environment (already passed from `.env`).
|
|
215
|
+
|
|
216
|
+
### Jira (optional, read-only history)
|
|
217
|
+
|
|
218
|
+
```bash
|
|
209
219
|
claude mcp add mcp-atlassian -s user -- \
|
|
210
220
|
npx -y mcp-atlassian \
|
|
211
221
|
--jira-url "$JIRA_URL" \
|
|
@@ -213,15 +223,6 @@ claude mcp add mcp-atlassian -s user -- \
|
|
|
213
223
|
--jira-token "$JIRA_TOKEN"
|
|
214
224
|
```
|
|
215
225
|
|
|
216
|
-
### GitHub
|
|
217
|
-
|
|
218
|
-
```bash
|
|
219
|
-
claude mcp add github -s user -- \
|
|
220
|
-
npx -y @modelcontextprotocol/server-github
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
Requires `GITHUB_TOKEN` in the environment (already passed from `.env`).
|
|
224
|
-
|
|
225
226
|
## Testing
|
|
226
227
|
|
|
227
228
|
### grok test (Puppeteer-based)
|
package/.turbo/turbo-build.log
CHANGED
package/CHANGELOG.md
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
# Datagrok-tools changelog
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## 6.7.8 (2026-10-13)
|
|
4
4
|
|
|
5
|
+
* Fixed `grok api` (and every command other than `grok s`) exiting with code 1 and its usage text in 6.7.7: the new `--send-email` flag reached every command as `send-email: false`, which `grok api` rejected as an unknown option
|
|
6
|
+
|
|
7
|
+
## 6.7.7 (2026-10-09)
|
|
8
|
+
|
|
9
|
+
* GROK-21156: `grok s users invite [<email>] [--prefix <P>] [--send-email]`: invites a user and prints a link that logs them in (no email sent; the email may be omitted); `--prefix` starts the code with `<P>`; `--send-email` mails the invitation instead
|
|
5
10
|
* `grok test --skip-gc` launches the browser without `--expose-gc`, so the test runner skips its garbage collection after every test; a suite of small unit tests runs several times faster (ComputeUtils driver tests: 92 s to 19 s)
|
|
6
11
|
* `grok setup` installs corepack when it is missing instead of asking for it by hand: Node 25 no longer bundles corepack, so every fresh checkout on current Node stopped at that step
|
|
7
12
|
* `grok setup` also removes the `.js`/`.d.ts` files the npm-era tsc emitted beside js-api and library sources: the workspace emits into `dist/`, and a leftover `js-api/grok.js` shadowed the `grok` command in cmd.exe
|
package/CLAUDE.md
CHANGED
|
@@ -220,7 +220,7 @@ Based on `node:22-bookworm-slim`. Pre-installed:
|
|
|
220
220
|
| `demo` | + world, test_db, northwind |
|
|
221
221
|
| `full` | + grok_spawner, JKG, demo DBs |
|
|
222
222
|
|
|
223
|
-
See `.devcontainer/PACKAGES_DEV.md` for detailed usage docs, architecture diagram, MCP plugin setup (Jira
|
|
223
|
+
See `.devcontainer/PACKAGES_DEV.md` for detailed usage docs, architecture diagram, MCP plugin setup (GitHub/Jira), and troubleshooting.
|
|
224
224
|
|
|
225
225
|
### `grok server` / `grok s` Command
|
|
226
226
|
|
package/GROK_S.md
CHANGED
|
@@ -16,6 +16,7 @@ browser or a logged-in session.
|
|
|
16
16
|
|-------------------------------------------------------------|--------------------------------------------------------|
|
|
17
17
|
| Create / update a user | `grok s users save --json user.json` |
|
|
18
18
|
| Block / unblock a user | `grok s users block <login>` / `users unblock <login>` |
|
|
19
|
+
| Invite a user, get a login link | `grok s users invite [<email>] [--prefix <P>]` |
|
|
19
20
|
| Create / update a group | `grok s groups save --json group.json` |
|
|
20
21
|
| Add or remove users in a group | `grok s groups add-members <group> <user>...` |
|
|
21
22
|
| List members of a group | `grok s groups list-members <group>` |
|
|
@@ -165,8 +166,17 @@ personal groups.
|
|
|
165
166
|
```bash
|
|
166
167
|
grok s users block alice.mendel # accept login, UUID, or namespace:name
|
|
167
168
|
grok s users unblock alice.mendel
|
|
169
|
+
grok s users invite alice@corp.com # prints a login link; no email is sent
|
|
170
|
+
grok s users invite # same, for an account with no email
|
|
171
|
+
grok s users invite --prefix ALEX- # code starts with ALEX- (letters, digits, - and _, up to 32)
|
|
172
|
+
grok s users invite alice@corp.com --send-email # mail the invitation instead
|
|
168
173
|
```
|
|
169
174
|
|
|
175
|
+
`users invite` creates the user in state `new` and prints `<server>?inviteCode=<code>`. The
|
|
176
|
+
link logs straight in as that user, every time, for a year. Inviting the same email again
|
|
177
|
+
prints a new link, and the earlier ones keep working. An account that has already been used
|
|
178
|
+
cannot be sent a link.
|
|
179
|
+
|
|
170
180
|
Both commands resolve the argument to a full user record first, so the server receives
|
|
171
181
|
the entire object (matching the Python client's `grok.users.block(user)`). Blocking
|
|
172
182
|
flips `status` to `Blocked` and terminates active sessions; unblocking restores `Active`.
|
|
@@ -616,9 +626,12 @@ entities shared with that account, and the target's own users never get their co
|
|
|
616
626
|
|
|
617
627
|
```bash
|
|
618
628
|
grok s pull --since 10y --type project,connection,query,script,group,layout --out ./bundle --host dev --admin
|
|
619
|
-
grok s push ./bundle --host prod --admin --on-conflict
|
|
629
|
+
grok s push ./bundle --host prod --admin --on-conflict adopt
|
|
620
630
|
```
|
|
621
631
|
|
|
632
|
+
`adopt` keeps one copy of what both instances already have, such as shared groups and spaces;
|
|
633
|
+
`skip` would leave them alone and fail everything in the bundle that points at them.
|
|
634
|
+
|
|
622
635
|
**Move a whole instance one space at a time.** Placement is exclusive on the server — one project
|
|
623
636
|
holding an entity takes it from every other — so a single bundle carrying every space has its
|
|
624
637
|
projects competing, and a stand-sized push spends its time taking rows back off each other. Scoped
|
package/README.md
CHANGED
|
@@ -106,7 +106,8 @@ For more information on configuring connections, refer to the [Connections](http
|
|
|
106
106
|
`config.yaml`): `grok report fetch <instance> <number>` downloads the report zip, `grok report read
|
|
107
107
|
<zip|json|instance number>` prints one normalized JSON object (flags `--extract-screenshot`,
|
|
108
108
|
`--extract-d42`, `--extract-client-log`), `grok report resolve <instance> <number>` marks it resolved.
|
|
109
|
-
`ticket`, `comment`, `label`, `attach` talk to JIRA with `JIRA_TOKEN
|
|
109
|
+
`ticket`, `comment`, `label`, `attach` talk to JIRA with `JIRA_TOKEN`; porting them to GitHub Issues
|
|
110
|
+
is pending. See `grok report --help`.
|
|
110
111
|
- `check` checks package content (function signatures, import statements of external modules,
|
|
111
112
|
etc.). The check is also run during package publication.
|
|
112
113
|
- `init` modifies a package template by adding config files for linters, IDE, and so on
|
package/bin/commands/server.js
CHANGED
|
@@ -111,6 +111,7 @@ async function server(argv) {
|
|
|
111
111
|
if (entity === 'groups' && (verb === 'list-members' || verb === 'list-memberships')) return await handleGroupListMembers(dapi, verb, rest, argv, output);
|
|
112
112
|
if (entity === 'users' && verb === 'block') return await handleUserBlock(dapi, rest, output);
|
|
113
113
|
if (entity === 'users' && verb === 'unblock') return await handleUserUnblock(dapi, rest, output);
|
|
114
|
+
if (entity === 'users' && verb === 'invite') return await handleUserInvite(dapi, rest, argv, output);
|
|
114
115
|
if (entity === 'tables' && verb === 'download') return await handleTablesDownload(dapi, rest, argv, output);
|
|
115
116
|
if (entity === 'tables' && verb === 'upload') return await handleTablesUpload(dapi, rest, output);
|
|
116
117
|
if (entity === 'packages' && verb === 'install') return await handlePackagesInstall(dapi, rest, argv, output);
|
|
@@ -214,6 +215,20 @@ async function handleUserUnblock(dapi, rest, output) {
|
|
|
214
215
|
if (output !== 'quiet') console.log(`Unblocked ${user?.login ?? rest[0]}`);
|
|
215
216
|
return true;
|
|
216
217
|
}
|
|
218
|
+
async function handleUserInvite(dapi, rest, argv, output) {
|
|
219
|
+
const email = rest[0] !== undefined ? String(rest[0]) : undefined;
|
|
220
|
+
const prefix = argv.prefix !== undefined ? String(argv.prefix) : undefined;
|
|
221
|
+
if (argv['send-email'] && (!email || prefix !== undefined)) {
|
|
222
|
+
(0, _serverOutput.printError)(new Error('Usage: grok s users invite <email> --send-email (no --prefix: only a link has a code)'));
|
|
223
|
+
return false;
|
|
224
|
+
}
|
|
225
|
+
const link = await dapi.users.invite(email, !!argv['send-email'], prefix);
|
|
226
|
+
if (output === 'json') (0, _serverOutput.printOutput)({
|
|
227
|
+
email: email ?? null,
|
|
228
|
+
link: link || null
|
|
229
|
+
}, output);else if (link) console.log(link);else if (output !== 'quiet') console.log(`Invitation sent to ${email}`);
|
|
230
|
+
return true;
|
|
231
|
+
}
|
|
217
232
|
async function handleTablesDownload(dapi, rest, argv, output) {
|
|
218
233
|
const name = rest[0];
|
|
219
234
|
if (!name) {
|
|
@@ -949,6 +964,10 @@ Special commands:
|
|
|
949
964
|
List parent groups
|
|
950
965
|
grok s users block <id-or-login> Block a user from the platform
|
|
951
966
|
grok s users unblock <id-or-login> Unblock a previously blocked user
|
|
967
|
+
grok s users invite [<email>] [--prefix <P>] [--send-email]
|
|
968
|
+
Invite a user; prints a login link (no email sent).
|
|
969
|
+
--prefix starts the code with <P> (e.g. ALEX-);
|
|
970
|
+
--send-email mails the invitation instead
|
|
952
971
|
grok s tables upload <name> <file.csv|file.d42> Upload a CSV or d42 binary as a Datagrok table
|
|
953
972
|
grok s tables download <name|Project:Table|id> [-O <file>]
|
|
954
973
|
Download a table as CSV (stdout by default)
|
package/bin/grok.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
// minimist sets every boolean option to false when it is absent, and commands such as `grok api`
|
|
3
|
+
// reject any key they do not expect — so each boolean reaches only the commands that read it.
|
|
4
|
+
const commandBooleans = {dartium: ['test', 'stresstest'], 'send-email': ['server', 's']};
|
|
2
5
|
const argv = require('minimist')(process.argv.slice(2), {
|
|
3
6
|
alias: {k: 'key', h: 'help', r: 'recursive'},
|
|
4
|
-
boolean:
|
|
7
|
+
boolean: Object.keys(commandBooleans),
|
|
5
8
|
// keep versions verbatim — minimist would coerce '1.10' to the number 1.1
|
|
6
|
-
string: ['version'],
|
|
9
|
+
string: ['version', 'prefix'],
|
|
7
10
|
});
|
|
8
11
|
// minimist maps `--no-retry` to `{retry: false}`, so the `args['no-retry']` checks in
|
|
9
12
|
// test.ts / playwright-runner.ts never fired and `--no-retry` was silently ignored
|
|
@@ -59,8 +62,9 @@ function printUsage(command) {
|
|
|
59
62
|
}
|
|
60
63
|
|
|
61
64
|
const command = argv['_'][0];
|
|
62
|
-
|
|
63
|
-
|
|
65
|
+
for (const [flag, owners] of Object.entries(commandBooleans))
|
|
66
|
+
if (!owners.includes(command))
|
|
67
|
+
delete argv[flag];
|
|
64
68
|
if (command in commands) {
|
|
65
69
|
try {
|
|
66
70
|
if (argv['help']) {
|
package/bin/utils/node-dapi.js
CHANGED
|
@@ -595,6 +595,20 @@ class NodeUsersDataSource extends NodeHttpDataSource {
|
|
|
595
595
|
async unblock(user) {
|
|
596
596
|
await this.client.post('/public/v1/users/unblock', user);
|
|
597
597
|
}
|
|
598
|
+
|
|
599
|
+
/**
|
|
600
|
+
* Creates the invitee (status `new`) and returns a link that logs them in, sending no email; the
|
|
601
|
+
* email may be omitted, and [prefix] goes in front of the link's code. With [sendEmail] the
|
|
602
|
+
* server mails the invitation and returns '' instead.
|
|
603
|
+
*/
|
|
604
|
+
async invite(email, sendEmail = false, prefix) {
|
|
605
|
+
return this.client.post(`/users/invite${buildQuery({
|
|
606
|
+
email: email ?? '',
|
|
607
|
+
target: 'Datagrok',
|
|
608
|
+
link: sendEmail ? undefined : true,
|
|
609
|
+
prefix
|
|
610
|
+
})}`);
|
|
611
|
+
}
|
|
598
612
|
}
|
|
599
613
|
exports.NodeUsersDataSource = NodeUsersDataSource;
|
|
600
614
|
class NodeConnectionsDataSource extends NodeHttpDataSource {
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"type": "git",
|
|
5
5
|
"url": "https://github.com/datagrok-ai/public.git"
|
|
6
6
|
},
|
|
7
|
-
"version": "6.7.
|
|
7
|
+
"version": "6.7.8",
|
|
8
8
|
"description": "Utility to upload and publish packages to Datagrok",
|
|
9
9
|
"homepage": "https://github.com/datagrok-ai/public/tree/master/tools#readme",
|
|
10
10
|
"dependencies": {
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
"update:ivp-parser": "esbuild plugins/ivp-parser.entry.mjs --bundle --format=cjs --platform=node --alias:diff-grok=../libraries/compute-utils/node_modules/diff-grok --outfile=plugins/ivp-parser.bundle.cjs",
|
|
91
91
|
"debug-source-map": "node build.js --source-maps",
|
|
92
92
|
"test": "vitest run --project unit",
|
|
93
|
-
"test:server": "vitest run --project unit bin/__tests__/node-dapi bin/__tests__/server bin/__tests__/migrate bin/__tests__/keypair",
|
|
93
|
+
"test:server": "vitest run --project unit bin/__tests__/node-dapi bin/__tests__/server bin/__tests__/migrate bin/__tests__/keypair bin/__tests__/grok-cli",
|
|
94
94
|
"test:watch": "vitest --project unit",
|
|
95
95
|
"test:integration": "vitest run --project integration",
|
|
96
96
|
"test:all": "vitest run"
|