@devicelink/dlink 0.3.1 → 0.3.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # @devicelink/dlink
2
2
 
3
- DeviceLink lets you share folders from your computer with AI assistants (like ChatGPT) safely. Nothing is uploaded to the cloud to sit on a server: files stay on your machine until you allow access, and you stay in control.
3
+ DeviceLink lets you share folders from your computer with AI assistants (like ChatGPT) safely. Nothing is uploaded - files stay on your machine and are streamed in real-time with your explicit permission.
4
4
 
5
5
  ## Install
6
6
 
@@ -8,47 +8,58 @@ DeviceLink lets you share folders from your computer with AI assistants (like Ch
8
8
  npm install -g @devicelink/dlink
9
9
  ```
10
10
 
11
+ Requires Node.js 20+.
12
+
11
13
  ## Quick start
12
14
 
13
- ```bash
14
- # Sign in with your DeviceLink account
15
- dlink signin
15
+ ### 1. Create your account
16
16
 
17
- # Pick a folder to share
18
- dlink share /path/to/project
17
+ Sign in at [devicelink.ai](https://devicelink.ai) with Google. A workspace is created for you automatically.
19
18
 
20
- # You're set: your AI can use that folder when you connect it through DeviceLink
19
+ ### 2. Run the agent
20
+
21
+ ```bash
22
+ dlink
21
23
  ```
22
24
 
25
+ The agent will open your browser to sign in with the same Google account. Once authenticated, your device is linked to your workspace. Choose a folder to share when prompted.
26
+
27
+ ### 3. Connect ChatGPT
28
+
29
+ Add DeviceLink as an MCP integration in ChatGPT (chatgpt.com → Settings → Connected apps). Sign in with the same Google account. Ask ChatGPT to list your files using DeviceLink - you're all set.
30
+
23
31
  ## Commands
24
32
 
33
+ Run `dlink` to start the interactive agent. Once running, you can use these commands in the console:
34
+
25
35
  | Command | What it does |
26
- |---------|----------------|
27
- | `dlink signin` | Sign in to DeviceLink |
28
- | `dlink signout` | Sign out on this computer |
29
- | `dlink share <path>` | Share a folder with your AI |
30
- | `dlink status` | See whether you're connected |
36
+ |---------|-------------|
37
+ | `signin` | Sign in to DeviceLink |
38
+ | `signout` | Sign out on this device |
39
+ | `stop` | Disconnect and exit |
31
40
 
32
41
  ## How it works
33
42
 
34
- 1. **Sign in** with your account (you'll use your browser when asked).
35
- 2. **Pick folders** you want the AI to be able to read.
36
- 3. **Stay connected** so requests can reach your computer securely.
37
- 4. **Use your AI** as usual: it can list and read files in the folders you shared.
38
- 5. **Stop anytime**: sign out or disconnect if you want access to end.
43
+ 1. **Sign in** - the agent opens your browser for Google sign-in.
44
+ 2. **Approve your device** - confirm on the web UI that this device can connect.
45
+ 3. **Share folders** - choose which directories the AI can access.
46
+ 4. **Stay connected** - the agent maintains a secure WebSocket connection so tool calls reach your machine.
47
+ 5. **Use your AI** - ChatGPT can list, read, search, and grep files in your shared folders.
48
+ 6. **Stop anytime** - close the agent and all access stops instantly.
39
49
 
40
50
  ## Security & privacy
41
51
 
42
- - Your files are not kept on our servers for browsing; access happens when you're connected and allow it.
43
- - Your device is checked so only your account can use your shared folders.
44
- - Sign-in details are stored encrypted on this computer.
45
- - Shared folders are limited to what you picked, so the AI can't wander the rest of your disk.
46
- - Access is short-lived and refreshed automatically so old keys don't stick around.
52
+ - Files are streamed in real-time - nothing is stored on our servers.
53
+ - Each device is verified with Ed25519 cryptographic signatures.
54
+ - Shared folders are sandboxed - the AI cannot access anything outside what you shared.
55
+ - Path traversal and symlink escapes are blocked.
56
+ - Credentials are stored encrypted on your machine.
57
+ - Access tokens are short-lived and refreshed automatically.
47
58
 
48
- ## Requirements
59
+ ## Links
49
60
 
50
- - [Node.js](https://nodejs.org/) version 20 or newer
51
- - Internet access to sign in and stay connected
61
+ - Website: [devicelink.ai](https://devicelink.ai)
62
+ - Support: [devicelink.ai/support](https://devicelink.ai/support)
52
63
 
53
64
  ## License
54
65
 
package/index.js CHANGED
@@ -575,8 +575,16 @@ function sleep(ms) {
575
575
  return new Promise((resolve3) => setTimeout(resolve3, ms));
576
576
  }
577
577
 
578
- // common/src/lib/utils/path-display.utils.ts
578
+ // common/src/lib/utils/path.utils.ts
579
579
  import * as path2 from "node:path";
580
+ var isCaseInsensitiveFS = process.platform === "win32";
581
+ function pathDedupeKey(p) {
582
+ const resolved = path2.resolve(p);
583
+ return isCaseInsensitiveFS ? resolved.toLowerCase() : resolved;
584
+ }
585
+
586
+ // common/src/lib/utils/path-display.utils.ts
587
+ import * as path3 from "node:path";
580
588
  import * as os2 from "node:os";
581
589
  function normalizeSlashes(s) {
582
590
  return s.replace(/\\/g, "/");
@@ -600,10 +608,10 @@ function toTildeHomePath(absolutePath) {
600
608
  }
601
609
  if (!looksLikeWindowsDrivePath(raw)) {
602
610
  try {
603
- const abs = path2.resolve(raw);
604
- const home = path2.resolve(os2.homedir());
605
- const rel = path2.relative(home, abs);
606
- if (!rel.startsWith("..") && !path2.isAbsolute(rel)) {
611
+ const abs = path3.resolve(raw);
612
+ const home = path3.resolve(os2.homedir());
613
+ const rel = path3.relative(home, abs);
614
+ if (!rel.startsWith("..") && !path3.isAbsolute(rel)) {
607
615
  if (rel === "")
608
616
  return "~";
609
617
  return "~/" + normalizeSlashes(rel);
@@ -643,20 +651,12 @@ function toTildeHomePath(absolutePath) {
643
651
  return rest ? "~" + normalizeSlashes(rest) : "~";
644
652
  }
645
653
  try {
646
- return path2.basename(path2.resolve(raw));
654
+ return path3.basename(path3.resolve(raw));
647
655
  } catch {
648
656
  return raw.split(/[/\\]/).pop() ?? raw;
649
657
  }
650
658
  }
651
659
 
652
- // common/src/lib/utils/path.utils.ts
653
- import * as path3 from "node:path";
654
- var isCaseInsensitiveFS = process.platform === "win32";
655
- function pathDedupeKey(p) {
656
- const resolved = path3.resolve(p);
657
- return isCaseInsensitiveFS ? resolved.toLowerCase() : resolved;
658
- }
659
-
660
660
  // agent/src/cli/utils/config.builder.ts
661
661
  var DEFAULT_CONFIG = {
662
662
  version: 1,