clinkx 1.1.0 → 1.1.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/CHANGELOG.md +10 -1
- package/README.md +171 -171
- package/dist/context-builder/secrets.js +6 -1
- package/dist/context-builder/secrets.js.map +1 -1
- package/docs/configuration.md +426 -0
- package/docs/security.md +293 -0
- package/package.json +4 -5
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## 1.1.1 — 2026-10-05
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- The npm package now ships `docs/configuration.md` and `docs/security.md`, and the README is rewritten as a self-contained, install-facing page in Simplified Technical English. `package.json` `homepage` points at the npm package page and `bugs` is removed, because the source repository is private.
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- `context_builder` secret scanning (`allow_secrets:false`) on large bodies is 6-8x faster on Node 24: comment masking now returns the input string when nothing is masked, so memo lookups no longer compare a distinct but equal copy of the whole body. Output is unchanged.
|
|
12
|
+
- npm publish confirmation now waits up to about eight minutes for npm to expose the new version instead of failing after a few seconds; 1.1.0's automated publish succeeded but failed confirmation and needed a manual re-run to go green.
|
|
4
13
|
|
|
5
14
|
## 1.1.0 — 2026-10-03
|
|
6
15
|
|
package/README.md
CHANGED
|
@@ -1,146 +1,171 @@
|
|
|
1
1
|
# ClinkX
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
ClinkX is an MCP server that connects your AI coding assistant to other command-line AI agents. It runs Codex, Claude Code, agy, GLM, or Grok as child processes and returns their output as MCP tool results. You can send one task to one agent. You can run a council of many agents on one question. You can also build a context bundle for a later task.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
- `context_builder` writes a persisted context bundle from allowed local roots. Selection is deterministic by default. You can also run explicit curator and finalizer adapters, then the server validates and materializes locally.
|
|
7
|
-
- `list_workflows`, `resume_workflow`, and `run_workflow` run multi-stage workflows.
|
|
5
|
+
ClinkX uses MCP over STDIO. It works with any MCP client that can start a local command.
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
## Requirements
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
- Node.js 24.0.0 or later.
|
|
10
|
+
- At least one of these command-line tools on your `PATH`: `codex`, `claude`, `agy`, or `grok`. The `glm` adapter also uses the `claude` command.
|
|
11
|
+
- The `codex` command, if you run workflows. Workflows use Codex to select repository context before the first stage. See [Workflows](#workflows) for the opt-out switch.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
## Installation
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
npm install
|
|
17
|
-
npm run build:all
|
|
18
|
-
node dist/index.js
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
stdout is MCP JSON-RPC only (one JSON object per line). Logs go to stderr.
|
|
15
|
+
Add ClinkX to the MCP server list of your client. The exact file and format depend on the client. This is the common JSON shape:
|
|
22
16
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"mcpServers": {
|
|
20
|
+
"clinkx": {
|
|
21
|
+
"command": "npx",
|
|
22
|
+
"args": ["-y", "clinkx@latest"],
|
|
23
|
+
"env": {
|
|
24
|
+
"CLINKX_ALLOWED_ROOTS": "/path/to/your/workspace",
|
|
25
|
+
"CLINKX_WORKFLOWS_WORKSPACE_ROOT": "/path/to/your/workspace"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
```
|
|
34
31
|
|
|
35
|
-
|
|
32
|
+
Set the two paths to the directory that tool calls can reference. Use absolute paths.
|
|
36
33
|
|
|
37
|
-
|
|
34
|
+
To install ClinkX globally, run this command. Then set `"command": "clinkx"` with no `args`:
|
|
38
35
|
|
|
39
36
|
```bash
|
|
40
|
-
|
|
37
|
+
npm install -g clinkx
|
|
41
38
|
```
|
|
42
39
|
|
|
43
|
-
|
|
40
|
+
Restart your MCP client after you change its configuration. To control when upgrades happen, replace `clinkx@latest` with a fixed version.
|
|
44
41
|
|
|
45
|
-
|
|
42
|
+
## First call
|
|
46
43
|
|
|
47
|
-
|
|
44
|
+
Ask your assistant to use the `clink` tool. This is the smallest valid request:
|
|
48
45
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
Workflow and activity session logs follow retention of that exact parent generation. Context session logs follow the parent context-run/manual lifecycle. There is no separate context-run pruner yet.
|
|
58
|
-
|
|
59
|
-
Persisted inputs, outputs, errors, and artifact bytes can be sensitive. Access is loopback-only and passkey-gated. That is a shared-account boundary, not isolation from other processes as the same OS user. Redaction strips high-confidence credentials and user-home paths before write. Prompts, outputs, tool summaries, and reasoning can still be sensitive after that. Per-run state admission defaults to 16 MiB (configurable 1–64 MiB via `CLINKX_WORKFLOWS_DASHBOARD_MAX_STATE_BYTES`). Raw result/call reads use smaller fixed caps.
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"cli_name": "codex",
|
|
49
|
+
"prompt": "Summarize the module boundaries in this project. Do not edit files.",
|
|
50
|
+
"absolute_file_paths": ["/path/to/your/workspace/src/server.ts"]
|
|
51
|
+
}
|
|
52
|
+
```
|
|
60
53
|
|
|
61
|
-
|
|
54
|
+
ClinkX starts the Codex CLI, sends the prompt and the file references, and returns the final answer. You can run many `clink` calls at the same time, up to the concurrency limit.
|
|
62
55
|
|
|
63
|
-
|
|
56
|
+
## Tools
|
|
64
57
|
|
|
65
|
-
|
|
58
|
+
| Tool | Function |
|
|
59
|
+
|---|---|
|
|
60
|
+
| `clink` | Runs one task on one configured CLI and returns the result. |
|
|
61
|
+
| `context_builder` | Selects a bounded set of files from permitted roots and writes a reusable context bundle to disk. |
|
|
62
|
+
| `refine_context_run` | Makes a new bundle from an earlier one. You can add, remove, promote, or demote files, or set their slices. |
|
|
63
|
+
| `list_workflows` | Lists the available workflows, CLIs, and roster presets. |
|
|
64
|
+
| `run_workflow` | Starts a multi-stage workflow. Runs in blocking mode by default, or in the background with `async: true`. |
|
|
65
|
+
| `workflow_run_status` | Reports the progress and result of a workflow run. |
|
|
66
|
+
| `resume_workflow` | Continues a workflow run that stopped before completion. |
|
|
67
|
+
| `cancel_workflow` | Cancels a workflow run. |
|
|
68
|
+
| `progress_report_start`, `progress_report_update`, `progress_report_get`, `progress_report_list` | Keep a live progress report that the dashboard shows. |
|
|
66
69
|
|
|
67
|
-
|
|
68
|
-
npm run build:dashboard:standalone -- \
|
|
69
|
-
--node-executable /absolute/path/to/official-node \
|
|
70
|
-
--output ./artifacts/clinkx-dashboard
|
|
71
|
-
```
|
|
70
|
+
Two more tool groups are off by default:
|
|
72
71
|
|
|
73
|
-
|
|
72
|
+
- `clink_agent_run` and `clink_agent_manage` control a stateful Codex app-server session with approvals. Set `CLINKX_APP_SERVER_ENABLED=true` to publish them.
|
|
73
|
+
- `clink_elaris_run` and `clink_elaris_manage` start remote Elaris agent sessions over HTTPS. Set `CLINKX_ELARIS_ENABLED=true` and the Elaris connection variables to publish them.
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
Each tool publishes its full input schema through MCP. MCP clients can show the schema with the tool description.
|
|
76
76
|
|
|
77
|
-
|
|
77
|
+
## Supported CLIs
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
2. `${XDG_CONFIG_HOME:-~/.config}/clinkx/adapters/*.json`. First-wins on `name`.
|
|
81
|
-
3. Packaged `conf/adapters/*.json` next to the installed package (`import.meta.url`). Not `process.cwd()`.
|
|
79
|
+
An adapter file tells ClinkX how to start one CLI, how to pass the prompt, and how to read the output. These adapters are included:
|
|
82
80
|
|
|
83
|
-
|
|
81
|
+
| `cli_name` | Command (short form) | Notes |
|
|
82
|
+
|---|---|---|
|
|
83
|
+
| `codex` | `codex exec --json` | Default curator and finalizer for workflow context. |
|
|
84
|
+
| `claude` | `claude -p --output-format stream-json` | |
|
|
85
|
+
| `agy` | `agy --output-format stream-json` | Use an agy build that emits stream-json (1.1.8 or later). |
|
|
86
|
+
| `glm` | `claude -p ... --model glm-5.3[1m]` | Runs GLM through the Claude Code CLI. |
|
|
87
|
+
| `grok` | `grok --output-format streaming-messages-json` | |
|
|
84
88
|
|
|
85
|
-
|
|
89
|
+
All included adapters accept the optional `model` and `effort` fields on each call:
|
|
86
90
|
|
|
87
91
|
```json
|
|
88
|
-
{"cli_name":"codex","prompt":
|
|
92
|
+
{ "cli_name": "codex", "prompt": "...", "model": "gpt-5.4", "effort": "low" }
|
|
89
93
|
```
|
|
90
94
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
Dashboard deployment controls:
|
|
94
|
-
|
|
95
|
-
| Setting | Contract |
|
|
96
|
-
|---|---|
|
|
97
|
-
| `CLINKX_WORKFLOWS_DASHBOARD_CREDENTIAL_DIR` | Optional absolute, non-root credential directory. Host default: `${CLINKX_WORKFLOWS_STATE_DIR}/dashboard/webauthn`. Compose pins the writable `/data/dashboard-credentials` volume. |
|
|
98
|
-
| `DASHBOARD_DEPLOYMENT_SLUG` | Required Compose identity, `^[a-z][a-z0-9-]{0,31}$`. Local and cloud names keep distinct stack-kind prefixes. |
|
|
99
|
-
| `DASHBOARD_CREDENTIAL_BOOTSTRAP_MODE` | Required Compose state assertion. First start is `bootstrap`. Flip to `existing-enrolled` right after enrollment, before restart. |
|
|
100
|
-
|
|
101
|
-
Passkey challenge capacity is 96 login slots and 32 registration/add-passkey slots, with 8 concurrent verifications. Saturation returns 503 `auth_busy` and `Retry-After: 1`. Live challenges are not evicted. Local session and challenge cookie names are port-scoped. WebAuthn still uses the shared bare `localhost` RP ID.
|
|
95
|
+
If you omit a field, ClinkX uses the adapter setting or the CLI default. If the adapter does not declare the field or the value, ClinkX returns MCP error `-32602` and does not start the process.
|
|
102
96
|
|
|
103
|
-
|
|
97
|
+
The `conf/adapters/hapi/` directory in the package holds optional templates that start each CLI through a `hapi` gateway. These templates are not ready to use. You must set the gateway URL and credentials in your copy.
|
|
104
98
|
|
|
105
|
-
|
|
99
|
+
## Configuration
|
|
106
100
|
|
|
107
|
-
|
|
101
|
+
### Adapter files
|
|
108
102
|
|
|
109
|
-
|
|
103
|
+
ClinkX reads adapter JSON files from these locations, in this order. ClinkX uses the first file with a given `name`.
|
|
110
104
|
|
|
111
|
-
|
|
105
|
+
1. `CLINKX_CONFIG_PATH`, a file or a directory. When you set it, ClinkX reads only this location and does not load the included adapters. The location must also contain a `codex` adapter with a `json` role, or you must set `CLINKX_WORKFLOWS_CONTEXT_PREFLIGHT_ENABLED=false`.
|
|
106
|
+
2. `${XDG_CONFIG_HOME:-~/.config}/clinkx/adapters/*.json`.
|
|
107
|
+
3. The `conf/adapters/` directory inside the installed package.
|
|
112
108
|
|
|
113
|
-
|
|
114
|
-
2. `${XDG_CONFIG_HOME:-~/.config}/clinkx/rosters/*.json`
|
|
115
|
-
3. Packaged `conf/rosters/*.json` on the root server only. Standalone `createWorkflowServer` loads env/user only.
|
|
109
|
+
To change an included adapter, copy its file to `~/.config/clinkx/adapters/` and edit the copy. The copy replaces the included file completely. ClinkX does not merge the two files. After you upgrade ClinkX, compare your copy with the new included file. Copy the new file again if necessary.
|
|
116
110
|
|
|
117
|
-
|
|
111
|
+
To add a CLI that is not included, write a new file in the same directory. This example adapter returns the prompt unchanged:
|
|
118
112
|
|
|
119
113
|
```json
|
|
120
114
|
{
|
|
121
|
-
"
|
|
122
|
-
"
|
|
123
|
-
"
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
],
|
|
128
|
-
"chairman": { "cli_name": "codex" },
|
|
129
|
-
"delegate": {
|
|
130
|
-
"enabled": true,
|
|
131
|
-
"curator": { "cli_name": "codex", "role": "json" },
|
|
132
|
-
"finalizer": {
|
|
133
|
-
"cli_name": "codex",
|
|
134
|
-
"role": "json-codereviewer",
|
|
135
|
-
"enabled": true,
|
|
136
|
-
"min_score": 8.5
|
|
137
|
-
},
|
|
138
|
-
"failure_policy": "fail"
|
|
139
|
-
}
|
|
115
|
+
"name": "echo",
|
|
116
|
+
"command": "node",
|
|
117
|
+
"args": ["-e", "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>process.stdout.write(d));"],
|
|
118
|
+
"parser": "text",
|
|
119
|
+
"prompt_mode": "stdin",
|
|
120
|
+
"timeout_seconds": 60
|
|
140
121
|
}
|
|
141
122
|
```
|
|
142
123
|
|
|
143
|
-
|
|
124
|
+
### Environment variables
|
|
125
|
+
|
|
126
|
+
These are the variables that most installations set. Every variable has a default.
|
|
127
|
+
|
|
128
|
+
| Variable | Default | Function |
|
|
129
|
+
|---|---|---|
|
|
130
|
+
| `CLINKX_ALLOWED_ROOTS` | Current directory of the server process | Comma-separated list of directories that tool calls can reference. Set it so path checks do not depend on the directory in which the client starts ClinkX. |
|
|
131
|
+
| `CLINKX_WORKFLOWS_WORKSPACE_ROOT` | Current directory of the server process | Workspace for workflows. Set it to the same directory as the allowed root. |
|
|
132
|
+
| `CLINKX_WORKFLOWS_STATE_DIR` | `${XDG_STATE_HOME:-~/.local/state}/clinkx-workflows` | Directory for workflow runs, progress reports, and dashboard state. |
|
|
133
|
+
| `CLINKX_CONTEXT_BUILDER_RUNS_DIR` | `${XDG_STATE_HOME:-~/.local/state}/clinkx/context-builder/runs` | Directory for `context_builder` runs and bundles. |
|
|
134
|
+
| `CLINKX_CONFIG_PATH` | not set | Replaces the adapter search path. See [Adapter files](#adapter-files). |
|
|
135
|
+
| `CLINKX_ROSTERS_PATH` | not set | Replaces the roster-preset search path. See [Workflows](#workflows). |
|
|
136
|
+
| `CLINKX_MAX_CONCURRENT` | `5` | Maximum number of `clink` processes at one time. ClinkX returns an error when the limit is reached. It does not queue requests. |
|
|
137
|
+
| `CLINKX_TIMEOUT_SECONDS` | `600` | Default time limit for one child process. |
|
|
138
|
+
| `CLINKX_MAX_RESPONSE_CHARS` | `20000` | Maximum number of characters in one tool result. |
|
|
139
|
+
| `CLINKX_LOG_LEVEL` | `info` | Log level. Logs go to stderr. |
|
|
140
|
+
| `CLINKX_CONTEXT_ALLOW_SECRETS` | `true` | When `true`, `context_builder` copies secret material into bundles as written. See [Safety](#safety). |
|
|
141
|
+
| `CLINKX_WORKFLOWS_CONTEXT_PREFLIGHT_ENABLED` | `true` | Set to `false` to run workflows without the Codex context step. |
|
|
142
|
+
| `CLINKX_WORKFLOWS_RETAIN_SUCCEEDED_DAYS` | `1` | Days to keep completed blocking workflow runs on disk. `0` keeps them without limit. |
|
|
143
|
+
| `CLINKX_WORKFLOWS_RETAIN_ASYNC_DAYS` | `1` | Days to keep completed background workflow runs on disk. `0` keeps them without limit. |
|
|
144
|
+
| `CLINKX_SERVER_IDLE_TIMEOUT_SECONDS` | `0` | Seconds of inactivity after which the server exits. `0` disables the timer. Active tool calls, workflows, and Codex turns reset it. |
|
|
145
|
+
| `CLINKX_APP_SERVER_ENABLED` | `false` | Set to `true` to publish the Codex app-server tools. |
|
|
146
|
+
| `CLINKX_ELARIS_ENABLED` | `false` | Set to `true` to publish the Elaris tools. |
|
|
147
|
+
|
|
148
|
+
ClinkX writes only MCP JSON-RPC to stdout. All logs go to stderr. The server detects the exit of its parent process and stops.
|
|
149
|
+
|
|
150
|
+
## Workflows
|
|
151
|
+
|
|
152
|
+
A workflow runs many CLI calls in stages and returns one result. A council workflow asks each member for an independent answer. The members then review each other. A chairman writes the final answer. These workflows are included:
|
|
153
|
+
|
|
154
|
+
| Workflow | Purpose |
|
|
155
|
+
|---|---|
|
|
156
|
+
| `council-answer` | Answer one hard question. |
|
|
157
|
+
| `council-code-review` | Review a change set. |
|
|
158
|
+
| `council-debug` | Find the cause of a defect. |
|
|
159
|
+
| `council-discover` | Inspect a codebase or a design space. |
|
|
160
|
+
| `council-plan-review` | Review a plan document. |
|
|
161
|
+
| `council-default` | General-purpose council. |
|
|
162
|
+
| `plan-review-receipts` | Typed plan review that returns receipt candidates for an external approval process. |
|
|
163
|
+
|
|
164
|
+
Before the first stage, the workflow runs `context_builder` with Codex as curator and finalizer. This step selects the repository files that the members receive. The `codex` command must be on your `PATH`. To skip this step, set `CLINKX_WORKFLOWS_CONTEXT_PREFLIGHT_ENABLED=false`.
|
|
165
|
+
|
|
166
|
+
### Roster presets
|
|
167
|
+
|
|
168
|
+
A roster preset names the members, the chairman, and the context delegate of a council in one file. Pass the preset name as `roster` in place of `members`, `chairman`, and `cb_delegate`:
|
|
144
169
|
|
|
145
170
|
```json
|
|
146
171
|
{
|
|
@@ -150,106 +175,81 @@ Call `run_workflow` with the preset name:
|
|
|
150
175
|
}
|
|
151
176
|
```
|
|
152
177
|
|
|
153
|
-
|
|
178
|
+
The included `default-council` preset uses Codex, Claude, and GLM as members and Codex as chairman. ClinkX reads these locations in this order and uses the first file with a given name:
|
|
154
179
|
|
|
155
|
-
|
|
180
|
+
1. `CLINKX_ROSTERS_PATH`, a file or a directory. When you set it, ClinkX reads only this location.
|
|
181
|
+
2. `${XDG_CONFIG_HOME:-~/.config}/clinkx/rosters/*.json`.
|
|
182
|
+
3. The `conf/rosters/` directory inside the installed package.
|
|
156
183
|
|
|
157
|
-
|
|
184
|
+
To write your own preset, copy `conf/rosters/default-council.json` to `~/.config/clinkx/rosters/<name>.json` and edit the copy. The file name is the preset name. The preset name must match `^[a-z0-9][a-z0-9_-]{0,63}$`. A request that gives `roster` together with `members`, `chairman`, `chairman_model`, `chairman_effort`, or a non-empty `cb_delegate` returns error `-32602` and starts no run.
|
|
158
185
|
|
|
159
|
-
|
|
186
|
+
### Background runs
|
|
160
187
|
|
|
161
|
-
|
|
188
|
+
Pass `async: true` to `run_workflow` to get a `run_id` immediately. Call `workflow_run_status` with that `run_id` to see the stage progress. Pass `include_result: true` to get the final result. Use `cancel_workflow` to stop a run. Completed runs stay on disk for the retention period given above.
|
|
189
|
+
|
|
190
|
+
## Context bundles
|
|
191
|
+
|
|
192
|
+
Use `context_builder` when a later call needs a selected part of the repository. Then the first tool result does not contain that content. You must give at least one anchor: a `focus_paths` entry or a non-blank `search_terms` entry.
|
|
162
193
|
|
|
163
194
|
```json
|
|
164
195
|
{
|
|
165
196
|
"task": "Collect context for the server tool registration",
|
|
166
|
-
"roots": ["/path/to/workspace"],
|
|
197
|
+
"roots": ["/path/to/your/workspace"],
|
|
167
198
|
"focus_paths": ["src/server.ts"],
|
|
168
|
-
"
|
|
169
|
-
"enabled": true,
|
|
170
|
-
"curator": {
|
|
171
|
-
"cli_name": "<curator-cli>",
|
|
172
|
-
"role": "<curator-role>"
|
|
173
|
-
},
|
|
174
|
-
"finalizer": {
|
|
175
|
-
"cli_name": "<finalizer-cli>",
|
|
176
|
-
"role": "<finalizer-role>",
|
|
177
|
-
"min_score": 8.5
|
|
178
|
-
},
|
|
179
|
-
"failure_policy": "fallback",
|
|
180
|
-
"timeout_seconds": 120,
|
|
181
|
-
"max_response_chars": 20000
|
|
182
|
-
}
|
|
199
|
+
"search_terms": ["ListToolsRequestSchema"]
|
|
183
200
|
}
|
|
184
201
|
```
|
|
185
202
|
|
|
186
|
-
|
|
203
|
+
The tool writes the bundle to the context-runs directory and returns a short JSON receipt. The receipt contains `recommended_clink.absolute_file_paths`. Pass that list as `absolute_file_paths` on the next `clink` call.
|
|
187
204
|
|
|
188
|
-
|
|
205
|
+
By default the selection is deterministic. You can also set `delegate.enabled: true` and name a curator and a finalizer CLI. The curator makes a selection and the finalizer scores it. ClinkX checks the selection and rebuilds the bundle from local files. It applies the budgets again and writes only content that it checked itself. Provider output is an input that ClinkX checks, not a result.
|
|
189
206
|
|
|
190
|
-
|
|
207
|
+
## Dashboard
|
|
191
208
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
"args": ["-e", "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>process.stdout.write(d));"],
|
|
197
|
-
"parser": "text",
|
|
198
|
-
"prompt_mode": "stdin",
|
|
199
|
-
"timeout_seconds": 60
|
|
200
|
-
}
|
|
209
|
+
The package includes a local, read-only web dashboard. It shows workflow runs, single calls, context runs, progress reports, the workflow catalog, the adapter catalog, and the saved artifacts. Start it with the second command that the package installs:
|
|
210
|
+
|
|
211
|
+
```bash
|
|
212
|
+
npx -p clinkx clinkx-workflows-dashboard --port 4180
|
|
201
213
|
```
|
|
202
214
|
|
|
203
|
-
|
|
215
|
+
The dashboard listens on `127.0.0.1` and `::1` and prints `http://localhost:<port>`. Passkey sign-in is the default. On the first start, the dashboard prints one enrollment code. Register a passkey with that code, then sign in. For local tests only, `CLINKX_WORKFLOWS_DASHBOARD_AUTH_MODE=none` disables sign-in.
|
|
204
216
|
|
|
205
|
-
|
|
217
|
+
Point the dashboard at the same `CLINKX_WORKFLOWS_STATE_DIR` as the ClinkX server. If the two directories differ, the dashboard shows a different run set, often an empty one. If you set `CLINKX_CONTEXT_BUILDER_RUNS_DIR` for the server, set the same value for the dashboard.
|
|
206
218
|
|
|
207
|
-
|
|
219
|
+
The dashboard does not start, cancel, or approve anything. The data that it shows can contain prompts, outputs, and file contents from your workspace. Access is local and needs a passkey, but any process that runs as the same OS user can read the state directory.
|
|
208
220
|
|
|
209
|
-
|
|
210
|
-
{
|
|
211
|
-
"mcpServers": {
|
|
212
|
-
"clinkx": {
|
|
213
|
-
"command": "npx",
|
|
214
|
-
"args": ["-y", "clinkx@latest"],
|
|
215
|
-
"env": {
|
|
216
|
-
"CLINKX_ALLOWED_ROOTS": "/path/to/your/workspace",
|
|
217
|
-
"CLINKX_WORKFLOWS_WORKSPACE_ROOT": "/path/to/your/workspace"
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
```
|
|
221
|
+
## Safety
|
|
223
222
|
|
|
224
|
-
|
|
223
|
+
ClinkX checks request paths and passes only a small set of environment variables to the child process. It does not sandbox the child process.
|
|
225
224
|
|
|
226
|
-
|
|
227
|
-
{
|
|
228
|
-
"mcpServers": {
|
|
229
|
-
"clinkx": {
|
|
230
|
-
"command": "node",
|
|
231
|
-
"args": ["/path/to/clink-mcp/dist/index.js"],
|
|
232
|
-
"env": {
|
|
233
|
-
"CLINKX_ALLOWED_ROOTS": "/path/to/your/workspace",
|
|
234
|
-
"CLINKX_WORKFLOWS_WORKSPACE_ROOT": "/path/to/your/workspace"
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
```
|
|
225
|
+
**WARNING: A child process has the same permissions as the user who started ClinkX.** The included adapters start each CLI with no sandbox and with approval prompts turned off or set to accept file edits. The child process can edit and delete files in your workspace and can run commands. Give each prompt clear limits. Do not run ClinkX as root or as an administrator.
|
|
240
226
|
|
|
241
|
-
|
|
227
|
+
**WARNING: `context_builder` copies secrets by default.** The default is `allow_secrets: true`. With this default, ClinkX copies API keys, private keys, tokens, and files such as `.env` and `id_rsa` into bundles. The CLIs that receive the bundle also receive the secrets. To make ClinkX omit or redact common secret forms, set one of these:
|
|
228
|
+
|
|
229
|
+
- `allow_secrets: false` on the `context_builder` call.
|
|
230
|
+
- `cb_allow_secrets: false` on the `run_workflow` call.
|
|
231
|
+
- `CLINKX_CONTEXT_ALLOW_SECRETS=false` in the server environment.
|
|
232
|
+
|
|
233
|
+
This filter is a best-effort check, not a security boundary.
|
|
242
234
|
|
|
243
|
-
|
|
235
|
+
`CLINKX_ALLOWED_ROOTS` limits the paths that tool calls can reference. It does not limit the child process. Set it in all installations so that the limit does not depend on the start directory of the client.
|
|
244
236
|
|
|
245
|
-
`
|
|
237
|
+
Only the `council-plan-review` and `plan-review-receipts` prompts tell the members not to edit files. This is an instruction to the model, not a mechanical control. The other workflows give no such instruction.
|
|
246
238
|
|
|
247
|
-
|
|
239
|
+
## Documentation
|
|
248
240
|
|
|
249
|
-
|
|
241
|
+
The installed package contains these files. After `npm install clinkx`, find them in `node_modules/clinkx/`.
|
|
250
242
|
|
|
251
|
-
|
|
243
|
+
| File | Content |
|
|
244
|
+
|---|---|
|
|
245
|
+
| `docs/configuration.md` | Reference for adapter files, invocation overrides, and environment variables. |
|
|
246
|
+
| `docs/security.md` | Trust boundaries, redaction scope, and the limits of each safety control. |
|
|
247
|
+
| `CHANGELOG.md` | Changes, upgrade notes, and new flags for each release. |
|
|
248
|
+
|
|
249
|
+
Read the upgrade notes before you upgrade a server that has unfinished workflow runs.
|
|
252
250
|
|
|
253
251
|
## License
|
|
254
252
|
|
|
255
|
-
Copyright (c) 2026 jim380. All rights reserved.
|
|
253
|
+
Copyright (c) 2026 jim380. All rights reserved.
|
|
254
|
+
|
|
255
|
+
ClinkX is free to use but not open source. You may install and run the published npm package for your own use. You may not copy, change, redistribute, or sell it. The `package.json` license field is `UNLICENSED`. See the `LICENSE` file in the package for the full text.
|
|
@@ -2359,8 +2359,11 @@ function residualJsValueSpan(text, commentMasked, valueStart) {
|
|
|
2359
2359
|
(cursor - valueStart >= 32_768 || lineCount >= 64),
|
|
2360
2360
|
};
|
|
2361
2361
|
}
|
|
2362
|
+
// Returns `text` itself when nothing is masked: callers key memo Maps by the
|
|
2363
|
+
// result, and Node 24's V8 compares a distinct-but-equal string per lookup.
|
|
2362
2364
|
function maskJsCommentTrivia(text) {
|
|
2363
2365
|
const output = text.split("");
|
|
2366
|
+
let changed = false;
|
|
2364
2367
|
let quote;
|
|
2365
2368
|
let escaped = false;
|
|
2366
2369
|
for (let index = 0; index < text.length; index++) {
|
|
@@ -2377,6 +2380,7 @@ function maskJsCommentTrivia(text) {
|
|
|
2377
2380
|
continue;
|
|
2378
2381
|
}
|
|
2379
2382
|
if (character === "/" && text[index + 1] === "*") {
|
|
2383
|
+
changed = true;
|
|
2380
2384
|
output[index] = " ";
|
|
2381
2385
|
output[index + 1] = " ";
|
|
2382
2386
|
index += 2;
|
|
@@ -2395,6 +2399,7 @@ function maskJsCommentTrivia(text) {
|
|
|
2395
2399
|
continue;
|
|
2396
2400
|
}
|
|
2397
2401
|
if (character === "/" && text[index + 1] === "/") {
|
|
2402
|
+
changed = true;
|
|
2398
2403
|
output[index] = " ";
|
|
2399
2404
|
output[index + 1] = " ";
|
|
2400
2405
|
index += 2;
|
|
@@ -2405,7 +2410,7 @@ function maskJsCommentTrivia(text) {
|
|
|
2405
2410
|
index--;
|
|
2406
2411
|
}
|
|
2407
2412
|
}
|
|
2408
|
-
return output.join("");
|
|
2413
|
+
return changed ? output.join("") : text;
|
|
2409
2414
|
}
|
|
2410
2415
|
function shannonEntropy(value) {
|
|
2411
2416
|
const counts = new Map();
|