clay-server 2.19.0 → 2.20.0-beta.2
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 +51 -91
- package/bin/cli.js +49 -14
- package/lib/builtin-mates.js +360 -0
- package/lib/cli-sessions.js +3 -3
- package/lib/config.js +30 -4
- package/lib/daemon.js +28 -5
- package/lib/mates.js +169 -7
- package/lib/notes.js +20 -0
- package/lib/os-users.js +71 -2
- package/lib/project.js +903 -228
- package/lib/public/app.js +249 -69
- package/lib/public/css/icon-strip.css +55 -2
- package/lib/public/css/input.css +50 -30
- package/lib/public/css/mates.css +316 -2
- package/lib/public/css/mention.css +23 -0
- package/lib/public/css/mobile-nav.css +198 -0
- package/lib/public/css/overlays.css +23 -0
- package/lib/public/css/rewind.css +32 -0
- package/lib/public/css/title-bar.css +3 -0
- package/lib/public/css/user-settings.css +2 -2
- package/lib/public/index.html +65 -14
- package/lib/public/mates/ally.png +0 -0
- package/lib/public/mates/sage.jpg +0 -0
- package/lib/public/mates/scout.png +0 -0
- package/lib/public/modules/command-palette.js +44 -4
- package/lib/public/modules/filebrowser.js +2 -0
- package/lib/public/modules/input.js +158 -16
- package/lib/public/modules/mate-knowledge.js +2 -0
- package/lib/public/modules/mate-memory.js +353 -0
- package/lib/public/modules/mention.js +77 -2
- package/lib/public/modules/notifications.js +0 -8
- package/lib/public/modules/server-settings.js +11 -4
- package/lib/public/modules/sidebar.js +507 -21
- package/lib/public/modules/theme.js +10 -12
- package/lib/public/modules/tools.js +84 -12
- package/lib/public/modules/user-settings.js +45 -12
- package/lib/sdk-bridge.js +122 -61
- package/lib/server.js +209 -13
- package/lib/sessions.js +4 -4
- package/lib/users.js +89 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="media/logo/icon-full-banded-256-transparent.png" alt="Clay" />
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
|
-
<h3 align="center">
|
|
5
|
+
<h3 align="center">Your AI dev team. Not another coding agent.</h3>
|
|
4
6
|
|
|
5
7
|
[](https://www.npmjs.com/package/clay-server) [](https://www.npmjs.com/package/clay-server) [](https://github.com/chadbyte/clay) [](https://github.com/chadbyte/clay/blob/main/LICENSE)
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
AI teammates who remember your decisions, challenge your thinking, and grow with your codebase. Runs on your machine.
|
|
8
10
|
|
|
9
11
|
```bash
|
|
10
12
|
npx clay-server
|
|
@@ -15,78 +17,64 @@ npx clay-server
|
|
|
15
17
|
|
|
16
18
|
## What you get
|
|
17
19
|
|
|
18
|
-
###
|
|
19
|
-
|
|
20
|
-
Your CLI sessions, your CLAUDE.md rules, your MCP servers. **All of it works in Clay as-is.** Pick up a CLI session in the browser, or continue a browser session in the CLI. Same SDK, same tools, same results.
|
|
21
|
-
|
|
22
|
-
<p align="center">
|
|
23
|
-
<img src="media/split.gif" alt="split-screen workflow" width="700">
|
|
24
|
-
</p>
|
|
25
|
-
|
|
26
|
-
### Everything the CLI doesn't
|
|
20
|
+
### Debate before you decide
|
|
27
21
|
|
|
28
|
-
|
|
22
|
+
<!-- TODO: debate.gif -->
|
|
29
23
|
|
|
30
|
-
|
|
24
|
+
Let your Mates challenge each other. Set up a debate. Pick a moderator and panelists, give them a topic, and let them go. You can raise your hand to interject.
|
|
31
25
|
|
|
32
|
-
|
|
33
|
-
<img src="media/phone.gif" alt="Clay on phone" width="280">
|
|
34
|
-
</p>
|
|
26
|
+
"REST vs GraphQL for the new API?" "Monorepo or separate repos?" "This architecture won't scale past 10k users. Here's why." Get opposing perspectives before you commit.
|
|
35
27
|
|
|
36
|
-
###
|
|
28
|
+
### Build your team with Mates
|
|
37
29
|
|
|
38
|
-
|
|
30
|
+
<!-- TODO: mates.gif -->
|
|
39
31
|
|
|
40
|
-
|
|
32
|
+
Mates are AI teammates shaped through real conversation, built to hold their own perspective. Give them a name, avatar, expertise, and working style. **They don't flatter you. They push back.**
|
|
41
33
|
|
|
42
|
-
|
|
34
|
+
@mention them in any project session, DM them directly, or bring multiple into the same conversation. Each Mate builds persistent knowledge over time, remembering past decisions, project context, and how you work together.
|
|
43
35
|
|
|
44
|
-
|
|
36
|
+
### Drop-in replacement
|
|
45
37
|
|
|
46
|
-
|
|
38
|
+
Your existing agent setup works as-is. CLI sessions, CLAUDE.md rules, MCP servers. **No migration needed.** Pick up a CLI session in the browser, or continue a browser session in the CLI.
|
|
47
39
|
|
|
48
|
-
|
|
40
|
+
### Your machine, your server
|
|
49
41
|
|
|
50
|
-
|
|
42
|
+
Clay runs as a daemon on your machine. **No cloud relay, no intermediary service.** Schedule agents with cron, get push notifications on your phone, close your laptop. Sessions keep running.
|
|
51
43
|
|
|
52
|
-
|
|
44
|
+
### Bring your whole team
|
|
53
45
|
|
|
54
|
-
|
|
46
|
+
**One API key runs the whole workspace.** Invite teammates, set permissions per person, per project, per session. If someone gets stuck, **jump into their session** to help in real time.
|
|
55
47
|
|
|
56
|
-
|
|
48
|
+
### Before vs Clay
|
|
57
49
|
|
|
58
|
-
|
|
50
|
+
| Before | With Clay |
|
|
51
|
+
|---|---|
|
|
52
|
+
| One CLI session at a time | Multiple agents across projects, persistent |
|
|
53
|
+
| No shared context across teammates | Shared workspace with roles and permissions |
|
|
54
|
+
| No memory between decisions | AI that remembers past decisions and challenges new ones |
|
|
55
|
+
| No teammates, just prompts | Mates with names, knowledge, and opinions |
|
|
59
56
|
|
|
60
|
-
|
|
57
|
+
### Why not just use Claude Code directly?
|
|
61
58
|
|
|
62
|
-
|
|
59
|
+
Claude Code is excellent for solo coding. Clay is for when you need more than a single agent session. A team that debates your architecture decisions. AI colleagues who remember what you decided last month. A workspace where your human teammates and AI teammates sit side by side.
|
|
63
60
|
|
|
64
|
-
|
|
65
|
-
Designer finds a bug → writes up a ticket on Asana → dev asks clarifying questions → PM prioritizes → dev opens terminal, fixes it → shares a preview → QA checks → deploy
|
|
66
|
-
<br>*7 steps. 3 people. 2 days.*
|
|
61
|
+
If Claude Code is a solo instrument, Clay is the band.
|
|
67
62
|
|
|
68
|
-
|
|
69
|
-
Designer opens Clay in the browser, describes the bug in plain language → senior joins the same session, reviews the fix together → merge
|
|
70
|
-
<br>*2 steps. 2 people. Minutes. The designer never touched a terminal.*
|
|
63
|
+
## Who is Clay for
|
|
71
64
|
|
|
72
|
-
|
|
65
|
+
- **Solo dev juggling multiple roles.** You need a code reviewer, a marketing lead, a writing partner, but it's just you. Build them as Mates.
|
|
66
|
+
- **Small team sharing one AI workflow.** One API key, everyone in the browser, no terminal knowledge required.
|
|
67
|
+
- **Founder doing dev + product + ops.** Run agents overnight, get notified on your phone, review in the morning.
|
|
73
68
|
|
|
74
|
-
##
|
|
69
|
+
## Why I built Clay
|
|
75
70
|
|
|
76
|
-
|
|
71
|
+
I wanted AI teammates, not just a coding agent. The underlying agent is the best foundation for a personal AI I've found. I wanted to turn it into my own AI assistant, one that knows my context, remembers my decisions, and works the way I work.
|
|
77
72
|
|
|
78
|
-
|
|
79
|
-
|---|---|---|---|---|
|
|
80
|
-
| Multi-user with roles | – | – | Platform-dependent | **Accounts + RBAC** |
|
|
81
|
-
| AI teammates (Mates + Debates) | – | – | – | **Yes** |
|
|
82
|
-
| Join teammate's session | – | – | – | **Yes** |
|
|
83
|
-
| Persistent daemon | – | Session-based | – | **Yes** |
|
|
84
|
-
| Native mobile app | – | **Yes** | **Platform app** | PWA |
|
|
85
|
-
| Official support | **Anthropic** | **Anthropic** | **Anthropic** | Community |
|
|
73
|
+
That started as a browser interface so I could access it from anywhere. Then I added multi-user so my team could use it too. Then I started building the AI teammates themselves.
|
|
86
74
|
|
|
87
|
-
|
|
75
|
+
Most AI agent projects go for full autonomy. Let the AI loose, give it all the permissions, let it run. I wanted the opposite: **AI that works as part of a team.** Visible, controllable, accountable. Your teammates can see what the agent is doing, jump in when it needs help, and set the rules it operates under.
|
|
88
76
|
|
|
89
|
-
|
|
77
|
+
That's Clay now. A workspace where AI teammates have names, persistent memory, and their own perspective. Not "act like an expert" prompting. Actual teammates that push back, remember last week, and sit in your sidebar next to your human colleagues.
|
|
90
78
|
|
|
91
79
|
## Getting Started
|
|
92
80
|
|
|
@@ -96,21 +84,25 @@ Clay is a community project, not affiliated with Anthropic. Official tools recei
|
|
|
96
84
|
npx clay-server
|
|
97
85
|
```
|
|
98
86
|
|
|
99
|
-
On first run, it
|
|
87
|
+
On first run, it asks for a port number and whether you're using it solo or with a team.
|
|
100
88
|
Scan the QR code to connect from your phone instantly.
|
|
101
89
|
|
|
102
90
|
For remote access, use a VPN like Tailscale.
|
|
103
91
|
|
|
104
|
-
|
|
105
|
-
<img src="media/start.gif" alt="Clay starting from CLI" width="600">
|
|
106
|
-
</p>
|
|
92
|
+
## Philosophy
|
|
107
93
|
|
|
108
|
-
|
|
94
|
+
**AI is a teammate, not a tool.** A tool gets used once and forgotten. A teammate accumulates your history, your decisions, your working style. Give them a specialty, let them build context over time, and bring them into any project as a colleague.
|
|
95
|
+
|
|
96
|
+
**AI should understand you first.** When you create a Mate, set up a scheduled task, or start a Ralph Loop, Clay interviews you. Not to save time, but to use AI's capability to understand what you actually want. "Just do it for me" is a trap. The better AI understands you, the better the output.
|
|
97
|
+
|
|
98
|
+
**Your data is yours.** Sessions are JSONL files. Settings are JSON. Knowledge is Markdown. Everything lives on your machine in formats you can read, move, and back up. No proprietary database, no cloud lock-in. If you stop using Clay tomorrow, your data doesn't disappear.
|
|
99
|
+
|
|
100
|
+
**Friction is a feature.** The goal of AI is not to remove all friction. It's to free you to focus on the friction that matters. Reviewing a critical decision, shaping the direction, catching what the agent missed. Clay keeps those moments in, on purpose.
|
|
109
101
|
|
|
110
102
|
## FAQ
|
|
111
103
|
|
|
112
104
|
**"Is this just a terminal wrapper?"**
|
|
113
|
-
No. Clay
|
|
105
|
+
No. Clay is a team workspace that happens to use Claude as its engine. It manages AI teammates, persistent knowledge, and structured debates. The agent runtime is an implementation detail.
|
|
114
106
|
|
|
115
107
|
**"Does my code leave my machine?"**
|
|
116
108
|
The Clay server runs locally. Files stay local. Only Claude API calls go out, which is the same as using the CLI.
|
|
@@ -127,36 +119,8 @@ No. Teammates share the Claude Code session logged in on the server. You can als
|
|
|
127
119
|
**"Does it work with MCP servers?"**
|
|
128
120
|
Yes. MCP configurations from the CLI carry over as-is.
|
|
129
121
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
## HTTPS
|
|
133
|
-
|
|
134
|
-
HTTPS is enabled by default using a builtin wildcard certificate for `*.d.clay.studio`. No setup required. Available from `v2.17.0-beta.2`. Your browser connects to a URL like:
|
|
135
|
-
|
|
136
|
-
```
|
|
137
|
-
https://192-168-1-50.d.clay.studio:2633
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
The domain resolves to your local IP. All traffic stays on your network. See [clay-dns](clay-dns/) for details on how this works.
|
|
141
|
-
|
|
142
|
-
Push notifications require HTTPS, so they work out of the box with this setup. Install Clay as a PWA on your device to receive them.
|
|
143
|
-
|
|
144
|
-
<details>
|
|
145
|
-
<summary><strong>Alternative: local certificate with mkcert</strong></summary>
|
|
146
|
-
|
|
147
|
-
If you prefer to use a locally generated certificate (e.g. air-gapped environments where DNS is unavailable):
|
|
148
|
-
|
|
149
|
-
```bash
|
|
150
|
-
brew install mkcert
|
|
151
|
-
mkcert -install
|
|
152
|
-
npx clay-server --local-cert
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
This generates a self-signed certificate trusted by your machine. The setup wizard will guide you through installing the CA on other devices.
|
|
156
|
-
|
|
157
|
-
</details>
|
|
158
|
-
|
|
159
|
-
---
|
|
122
|
+
**"What is d.clay.studio in my browser URL?"**
|
|
123
|
+
It's a DNS-only service that resolves to your local IP for HTTPS certificate validation. No data passes through it. All traffic stays between your browser and your machine. See [clay-dns](clay-dns/) for details.
|
|
160
124
|
|
|
161
125
|
## CLI Options
|
|
162
126
|
|
|
@@ -180,11 +144,9 @@ npx clay-server --dangerously-skip-permissions
|
|
|
180
144
|
npx clay-server --dev # Dev mode (foreground, auto-restart on lib/ changes, port 2635)
|
|
181
145
|
```
|
|
182
146
|
|
|
183
|
-
---
|
|
184
|
-
|
|
185
147
|
## Architecture
|
|
186
148
|
|
|
187
|
-
Clay drives
|
|
149
|
+
Clay drives agent execution through the [Claude Agent SDK](https://www.npmjs.com/package/@anthropic-ai/claude-agent-sdk) and streams it to the browser over WebSocket.
|
|
188
150
|
|
|
189
151
|
```mermaid
|
|
190
152
|
graph LR
|
|
@@ -207,8 +169,6 @@ graph LR
|
|
|
207
169
|
|
|
208
170
|
For detailed sequence diagrams, daemon architecture, and design decisions, see [docs/architecture.md](docs/architecture.md).
|
|
209
171
|
|
|
210
|
-
---
|
|
211
|
-
|
|
212
172
|
## Contributors
|
|
213
173
|
|
|
214
174
|
<a href="https://github.com/chadbyte/clay/graphs/contributors">
|
package/bin/cli.js
CHANGED
|
@@ -33,7 +33,7 @@ if (_isDev || process.argv.includes("--debug")) {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
var crypto = require("crypto");
|
|
36
|
-
var { loadConfig, saveConfig, configPath, socketPath, logPath, ensureConfigDir, isDaemonAlive, isDaemonAliveAsync, generateSlug, clearStaleConfig, loadClayrc, saveClayrc, readCrashInfo } = require("../lib/config");
|
|
36
|
+
var { loadConfig, saveConfig, configPath, socketPath, logPath, ensureConfigDir, isDaemonAlive, isDaemonAliveAsync, generateSlug, clearStaleConfig, loadClayrc, saveClayrc, readCrashInfo, REAL_HOME } = require("../lib/config");
|
|
37
37
|
var { sendIPCCommand } = require("../lib/ipc");
|
|
38
38
|
var { generateAuthToken } = require("../lib/server");
|
|
39
39
|
var { enableMultiUser, disableMultiUser, hasAdmin, isMultiUser } = require("../lib/users");
|
|
@@ -610,8 +610,7 @@ function ensureCerts(ip) {
|
|
|
610
610
|
return null;
|
|
611
611
|
}
|
|
612
612
|
|
|
613
|
-
var
|
|
614
|
-
var certDir = path.join(process.env.CLAY_HOME || path.join(homeDir, ".clay"), "certs");
|
|
613
|
+
var certDir = path.join(process.env.CLAY_HOME || path.join(REAL_HOME, ".clay"), "certs");
|
|
615
614
|
var keyPath = path.join(certDir, "key.pem");
|
|
616
615
|
var certPath = path.join(certDir, "cert.pem");
|
|
617
616
|
|
|
@@ -891,7 +890,7 @@ function promptText(title, placeholder, callback, opts) {
|
|
|
891
890
|
|
|
892
891
|
// Resolve ~ to home
|
|
893
892
|
if (current.charAt(0) === "~") {
|
|
894
|
-
current =
|
|
893
|
+
current = REAL_HOME + current.substring(1);
|
|
895
894
|
}
|
|
896
895
|
|
|
897
896
|
var resolved = path.resolve(current);
|
|
@@ -1605,14 +1604,11 @@ async function forkDaemon(mode, keepAwake, extraProjects, addCwd, wantOsUsers) {
|
|
|
1605
1604
|
}
|
|
1606
1605
|
|
|
1607
1606
|
// Enable/disable multi-user mode based on startup config
|
|
1607
|
+
var _pendingSetupCode = null;
|
|
1608
1608
|
if (config.mode === "multi") {
|
|
1609
1609
|
var muResult = enableMultiUser();
|
|
1610
1610
|
if (muResult.setupCode) {
|
|
1611
|
-
|
|
1612
|
-
log(sym.done + " " + a.green + "Multi-user mode enabled." + a.reset);
|
|
1613
|
-
log(sym.bar + " Setup code: " + a.bold + muResult.setupCode + a.reset);
|
|
1614
|
-
log(sym.bar + " Open Clay in your browser and enter this code to create the admin account.");
|
|
1615
|
-
log("");
|
|
1611
|
+
_pendingSetupCode = muResult.setupCode;
|
|
1616
1612
|
}
|
|
1617
1613
|
} else if (isMultiUser()) {
|
|
1618
1614
|
disableMultiUser();
|
|
@@ -1628,13 +1624,19 @@ async function forkDaemon(mode, keepAwake, extraProjects, addCwd, wantOsUsers) {
|
|
|
1628
1624
|
console.log(" " + sym.done + " " + url);
|
|
1629
1625
|
if (config.builtinCert) console.log(" " + sym.done + " d.clay.studio provides HTTPS certificates only. Your traffic never leaves your network.");
|
|
1630
1626
|
if (config.mkcertDetected) console.log(" " + sym.warn + " Clay now ships with a builtin HTTPS certificate. To use it, pass --builtin-cert or uninstall mkcert.");
|
|
1627
|
+
if (_pendingSetupCode) {
|
|
1628
|
+
console.log("");
|
|
1629
|
+
console.log(" " + sym.done + " " + a.green + "Multi-user mode enabled." + a.reset);
|
|
1630
|
+
console.log(" " + sym.bar + " Setup code: " + a.bold + _pendingSetupCode + a.reset);
|
|
1631
|
+
console.log(" " + sym.bar + " Open Clay in your browser and enter this code to create the admin account.");
|
|
1632
|
+
}
|
|
1631
1633
|
console.log(" " + sym.done + " Headless mode — exiting CLI");
|
|
1632
1634
|
process.exit(0);
|
|
1633
1635
|
return;
|
|
1634
1636
|
}
|
|
1635
1637
|
|
|
1636
1638
|
// Show success + QR
|
|
1637
|
-
showServerStarted(config, ip);
|
|
1639
|
+
showServerStarted(config, ip, _pendingSetupCode);
|
|
1638
1640
|
}
|
|
1639
1641
|
|
|
1640
1642
|
// ==============================
|
|
@@ -1959,14 +1961,14 @@ async function restartDaemonWithTLS(config, callback) {
|
|
|
1959
1961
|
// ==============================
|
|
1960
1962
|
// Show server started info
|
|
1961
1963
|
// ==============================
|
|
1962
|
-
function showServerStarted(config, ip) {
|
|
1963
|
-
showMainMenu(config, ip);
|
|
1964
|
+
function showServerStarted(config, ip, setupCode) {
|
|
1965
|
+
showMainMenu(config, ip, setupCode);
|
|
1964
1966
|
}
|
|
1965
1967
|
|
|
1966
1968
|
// ==============================
|
|
1967
1969
|
// Main management menu
|
|
1968
1970
|
// ==============================
|
|
1969
|
-
function showMainMenu(config, ip) {
|
|
1971
|
+
function showMainMenu(config, ip, setupCode) {
|
|
1970
1972
|
startDaemonWatcher();
|
|
1971
1973
|
var protocol = config.tls ? "https" : "http";
|
|
1972
1974
|
var url = config.builtinCert
|
|
@@ -2007,6 +2009,12 @@ function showMainMenu(config, ip) {
|
|
|
2007
2009
|
log("");
|
|
2008
2010
|
}
|
|
2009
2011
|
|
|
2012
|
+
if (setupCode) {
|
|
2013
|
+
log(" " + a.yellow + sym.warn + " Setup code: " + a.bold + setupCode + a.reset);
|
|
2014
|
+
log(" " + a.dim + "Open Clay in your browser and enter this code to create the admin account." + a.reset);
|
|
2015
|
+
log("");
|
|
2016
|
+
}
|
|
2017
|
+
|
|
2010
2018
|
showMenuItems();
|
|
2011
2019
|
}
|
|
2012
2020
|
|
|
@@ -2507,7 +2515,19 @@ function showSettingsMenu(config, ip) {
|
|
|
2507
2515
|
], function (confirmChoice) {
|
|
2508
2516
|
if (confirmChoice === "confirm") {
|
|
2509
2517
|
sendIPCCommand(socketPath(), { cmd: "set_os_users", value: true }).then(function (res) {
|
|
2510
|
-
if (res.
|
|
2518
|
+
if (res.error === "acl_not_installed") {
|
|
2519
|
+
log(sym.bar);
|
|
2520
|
+
log(sym.bar + " " + a.red + sym.warn + " setfacl is not installed." + a.reset);
|
|
2521
|
+
log(sym.bar);
|
|
2522
|
+
log(sym.bar + " OS user isolation requires the ACL (Access Control List) package");
|
|
2523
|
+
log(sym.bar + " to manage per-user file permissions on shared projects.");
|
|
2524
|
+
log(sym.bar);
|
|
2525
|
+
log(sym.bar + " " + a.bold + "Install it:" + a.reset);
|
|
2526
|
+
log(sym.bar + " " + a.cyan + res.installCmd + a.reset);
|
|
2527
|
+
log(sym.bar);
|
|
2528
|
+
log(sym.bar + " " + a.dim + "Then try enabling OS user isolation again." + a.reset);
|
|
2529
|
+
log(sym.bar);
|
|
2530
|
+
} else if (res.ok) {
|
|
2511
2531
|
config.osUsers = true;
|
|
2512
2532
|
log(sym.bar);
|
|
2513
2533
|
log(sym.done + " " + a.green + "OS-level user isolation enabled." + a.reset);
|
|
@@ -2858,6 +2878,21 @@ var currentVersion = require("../package.json").version;
|
|
|
2858
2878
|
return;
|
|
2859
2879
|
}
|
|
2860
2880
|
|
|
2881
|
+
// os-users requires setfacl (ACL package)
|
|
2882
|
+
if (savedOsUsers && process.platform === "linux") {
|
|
2883
|
+
var { checkAclSupport } = require("../lib/os-users");
|
|
2884
|
+
var aclCheck = checkAclSupport();
|
|
2885
|
+
if (!aclCheck.available) {
|
|
2886
|
+
console.error(a.red + "OS user isolation requires the 'acl' package (setfacl)." + a.reset);
|
|
2887
|
+
console.error("");
|
|
2888
|
+
console.error("Install it: " + a.bold + aclCheck.installCmd + a.reset);
|
|
2889
|
+
console.error("");
|
|
2890
|
+
console.error("Then restart Clay.");
|
|
2891
|
+
process.exit(1);
|
|
2892
|
+
return;
|
|
2893
|
+
}
|
|
2894
|
+
}
|
|
2895
|
+
|
|
2861
2896
|
if (savedConfig && savedConfig.port) port = savedConfig.port;
|
|
2862
2897
|
if (savedConfig && savedConfig.host) host = savedConfig.host;
|
|
2863
2898
|
if (savedConfig && savedConfig.dangerouslySkipPermissions) dangerouslySkipPermissions = true;
|