@devicelink/dlink 0.3.1 → 0.3.3

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,59 @@ 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
+
17
+ Sign in at [devicelink.ai](https://devicelink.ai) with Google. We create a workspace for you automatically. No setup needed.
16
18
 
17
- # Pick a folder to share
18
- dlink share /path/to/project
19
+ ### 2. Install the agent
19
20
 
20
- # You're set: your AI can use that folder when you connect it through DeviceLink
21
+ Go to the folder you want to share, open a terminal there, install the CLI, and run it. Sign in with the same Google account to link your device.
22
+
23
+ ```bash
24
+ npm install -g @devicelink/dlink
25
+ dlink
21
26
  ```
22
27
 
28
+ ### 3. Use with ChatGPT
29
+
30
+ Add DeviceLink as a connected app in ChatGPT and sign in with the same Google account. Then just ask "list my files using DeviceLink".
31
+
23
32
  ## Commands
24
33
 
34
+ Run `dlink` to start the interactive agent. Once running, you can type these in the console:
35
+
25
36
  | 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 |
37
+ |---------|-------------|
38
+ | `signin` | Sign in to DeviceLink |
39
+ | `signout` | Sign out on this device |
40
+ | `status` | Show connection status |
41
+ | `stop` | Disconnect and exit |
31
42
 
32
43
  ## How it works
33
44
 
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.
45
+ 1. **Run the agent** from the folder you want to share.
46
+ 2. **Sign in** with Google when the browser opens.
47
+ 3. **Approve your device** when prompted in the terminal.
48
+ 4. **Stay connected** so tool calls from ChatGPT can reach your machine.
49
+ 5. **Stop anytime** by closing the agent. All access stops instantly.
39
50
 
40
- ## Security & privacy
51
+ ## Security and privacy
41
52
 
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.
53
+ - Files are streamed in real-time. Nothing is stored on our servers.
54
+ - Each device is verified with Ed25519 cryptographic signatures.
55
+ - Shared folders are sandboxed. The AI cannot access anything outside the shared directory.
56
+ - Path traversal and symlink escapes are blocked.
57
+ - Credentials are stored encrypted on your machine.
58
+ - Access tokens are short-lived and refreshed automatically.
47
59
 
48
- ## Requirements
60
+ ## Links
49
61
 
50
- - [Node.js](https://nodejs.org/) version 20 or newer
51
- - Internet access to sign in and stay connected
62
+ - Website: [devicelink.ai](https://devicelink.ai)
63
+ - Support: [devicelink.ai/support](https://devicelink.ai/support)
52
64
 
53
65
  ## License
54
66
 
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,