@unlimitechcloud/devlink 1.0.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.
Files changed (186) hide show
  1. package/AGENTS.md +880 -0
  2. package/LICENSE +21 -0
  3. package/README.md +335 -0
  4. package/dist/__tests__/e2e.spec.d.ts +8 -0
  5. package/dist/__tests__/e2e.spec.d.ts.map +1 -0
  6. package/dist/__tests__/e2e.spec.js +253 -0
  7. package/dist/__tests__/e2e.spec.js.map +1 -0
  8. package/dist/__tests__/integration.spec.d.ts +8 -0
  9. package/dist/__tests__/integration.spec.d.ts.map +1 -0
  10. package/dist/__tests__/integration.spec.js +274 -0
  11. package/dist/__tests__/integration.spec.js.map +1 -0
  12. package/dist/cli.d.ts +6 -0
  13. package/dist/cli.d.ts.map +1 -0
  14. package/dist/cli.js +610 -0
  15. package/dist/cli.js.map +1 -0
  16. package/dist/commands/consumers.d.ts +37 -0
  17. package/dist/commands/consumers.d.ts.map +1 -0
  18. package/dist/commands/consumers.js +107 -0
  19. package/dist/commands/consumers.js.map +1 -0
  20. package/dist/commands/docs.d.ts +59 -0
  21. package/dist/commands/docs.d.ts.map +1 -0
  22. package/dist/commands/docs.js +262 -0
  23. package/dist/commands/docs.js.map +1 -0
  24. package/dist/commands/docs.spec.d.ts +5 -0
  25. package/dist/commands/docs.spec.d.ts.map +1 -0
  26. package/dist/commands/docs.spec.js +213 -0
  27. package/dist/commands/docs.spec.js.map +1 -0
  28. package/dist/commands/index.d.ts +13 -0
  29. package/dist/commands/index.d.ts.map +1 -0
  30. package/dist/commands/index.js +13 -0
  31. package/dist/commands/index.js.map +1 -0
  32. package/dist/commands/install.d.ts +31 -0
  33. package/dist/commands/install.d.ts.map +1 -0
  34. package/dist/commands/install.js +234 -0
  35. package/dist/commands/install.js.map +1 -0
  36. package/dist/commands/list.d.ts +22 -0
  37. package/dist/commands/list.d.ts.map +1 -0
  38. package/dist/commands/list.js +45 -0
  39. package/dist/commands/list.js.map +1 -0
  40. package/dist/commands/list.spec.d.ts +5 -0
  41. package/dist/commands/list.spec.d.ts.map +1 -0
  42. package/dist/commands/list.spec.js +95 -0
  43. package/dist/commands/list.spec.js.map +1 -0
  44. package/dist/commands/prune.d.ts +27 -0
  45. package/dist/commands/prune.d.ts.map +1 -0
  46. package/dist/commands/prune.js +74 -0
  47. package/dist/commands/prune.js.map +1 -0
  48. package/dist/commands/publish.d.ts +16 -0
  49. package/dist/commands/publish.d.ts.map +1 -0
  50. package/dist/commands/publish.js +225 -0
  51. package/dist/commands/publish.js.map +1 -0
  52. package/dist/commands/publish.spec.d.ts +5 -0
  53. package/dist/commands/publish.spec.d.ts.map +1 -0
  54. package/dist/commands/publish.spec.js +98 -0
  55. package/dist/commands/publish.spec.js.map +1 -0
  56. package/dist/commands/push.d.ts +16 -0
  57. package/dist/commands/push.d.ts.map +1 -0
  58. package/dist/commands/push.js +164 -0
  59. package/dist/commands/push.js.map +1 -0
  60. package/dist/commands/remove.d.ts +24 -0
  61. package/dist/commands/remove.d.ts.map +1 -0
  62. package/dist/commands/remove.js +80 -0
  63. package/dist/commands/remove.js.map +1 -0
  64. package/dist/commands/remove.spec.d.ts +5 -0
  65. package/dist/commands/remove.spec.d.ts.map +1 -0
  66. package/dist/commands/remove.spec.js +87 -0
  67. package/dist/commands/remove.spec.js.map +1 -0
  68. package/dist/commands/resolve.d.ts +20 -0
  69. package/dist/commands/resolve.d.ts.map +1 -0
  70. package/dist/commands/resolve.js +52 -0
  71. package/dist/commands/resolve.js.map +1 -0
  72. package/dist/commands/resolve.spec.d.ts +5 -0
  73. package/dist/commands/resolve.spec.d.ts.map +1 -0
  74. package/dist/commands/resolve.spec.js +87 -0
  75. package/dist/commands/resolve.spec.js.map +1 -0
  76. package/dist/commands/verify.d.ts +32 -0
  77. package/dist/commands/verify.d.ts.map +1 -0
  78. package/dist/commands/verify.js +127 -0
  79. package/dist/commands/verify.js.map +1 -0
  80. package/dist/config.d.ts +22 -0
  81. package/dist/config.d.ts.map +1 -0
  82. package/dist/config.js +70 -0
  83. package/dist/config.js.map +1 -0
  84. package/dist/constants.d.ts +65 -0
  85. package/dist/constants.d.ts.map +1 -0
  86. package/dist/constants.js +116 -0
  87. package/dist/constants.js.map +1 -0
  88. package/dist/constants.spec.d.ts +5 -0
  89. package/dist/constants.spec.d.ts.map +1 -0
  90. package/dist/constants.spec.js +72 -0
  91. package/dist/constants.spec.js.map +1 -0
  92. package/dist/core/index.d.ts +9 -0
  93. package/dist/core/index.d.ts.map +1 -0
  94. package/dist/core/index.js +9 -0
  95. package/dist/core/index.js.map +1 -0
  96. package/dist/core/installations.d.ts +79 -0
  97. package/dist/core/installations.d.ts.map +1 -0
  98. package/dist/core/installations.js +207 -0
  99. package/dist/core/installations.js.map +1 -0
  100. package/dist/core/installations.spec.d.ts +5 -0
  101. package/dist/core/installations.spec.d.ts.map +1 -0
  102. package/dist/core/installations.spec.js +261 -0
  103. package/dist/core/installations.spec.js.map +1 -0
  104. package/dist/core/lock.d.ts +37 -0
  105. package/dist/core/lock.d.ts.map +1 -0
  106. package/dist/core/lock.js +198 -0
  107. package/dist/core/lock.js.map +1 -0
  108. package/dist/core/lock.spec.d.ts +5 -0
  109. package/dist/core/lock.spec.d.ts.map +1 -0
  110. package/dist/core/lock.spec.js +161 -0
  111. package/dist/core/lock.spec.js.map +1 -0
  112. package/dist/core/registry.d.ts +80 -0
  113. package/dist/core/registry.d.ts.map +1 -0
  114. package/dist/core/registry.js +231 -0
  115. package/dist/core/registry.js.map +1 -0
  116. package/dist/core/registry.spec.d.ts +5 -0
  117. package/dist/core/registry.spec.d.ts.map +1 -0
  118. package/dist/core/registry.spec.js +281 -0
  119. package/dist/core/registry.spec.js.map +1 -0
  120. package/dist/core/resolver.d.ts +55 -0
  121. package/dist/core/resolver.d.ts.map +1 -0
  122. package/dist/core/resolver.js +127 -0
  123. package/dist/core/resolver.js.map +1 -0
  124. package/dist/core/resolver.spec.d.ts +5 -0
  125. package/dist/core/resolver.spec.d.ts.map +1 -0
  126. package/dist/core/resolver.spec.js +202 -0
  127. package/dist/core/resolver.spec.js.map +1 -0
  128. package/dist/core/store.d.ts +65 -0
  129. package/dist/core/store.d.ts.map +1 -0
  130. package/dist/core/store.js +245 -0
  131. package/dist/core/store.js.map +1 -0
  132. package/dist/core/store.spec.d.ts +5 -0
  133. package/dist/core/store.spec.d.ts.map +1 -0
  134. package/dist/core/store.spec.js +195 -0
  135. package/dist/core/store.spec.js.map +1 -0
  136. package/dist/formatters/flat.d.ts +41 -0
  137. package/dist/formatters/flat.d.ts.map +1 -0
  138. package/dist/formatters/flat.js +131 -0
  139. package/dist/formatters/flat.js.map +1 -0
  140. package/dist/formatters/flat.spec.d.ts +5 -0
  141. package/dist/formatters/flat.spec.d.ts.map +1 -0
  142. package/dist/formatters/flat.spec.js +130 -0
  143. package/dist/formatters/flat.spec.js.map +1 -0
  144. package/dist/formatters/index.d.ts +6 -0
  145. package/dist/formatters/index.d.ts.map +1 -0
  146. package/dist/formatters/index.js +6 -0
  147. package/dist/formatters/index.js.map +1 -0
  148. package/dist/formatters/tree.d.ts +29 -0
  149. package/dist/formatters/tree.d.ts.map +1 -0
  150. package/dist/formatters/tree.js +256 -0
  151. package/dist/formatters/tree.js.map +1 -0
  152. package/dist/formatters/tree.spec.d.ts +5 -0
  153. package/dist/formatters/tree.spec.d.ts.map +1 -0
  154. package/dist/formatters/tree.spec.js +127 -0
  155. package/dist/formatters/tree.spec.js.map +1 -0
  156. package/dist/index.d.ts +11 -0
  157. package/dist/index.d.ts.map +1 -0
  158. package/dist/index.js +13 -0
  159. package/dist/index.js.map +1 -0
  160. package/dist/installer.d.ts +13 -0
  161. package/dist/installer.d.ts.map +1 -0
  162. package/dist/installer.js +171 -0
  163. package/dist/installer.js.map +1 -0
  164. package/dist/store.d.ts +78 -0
  165. package/dist/store.d.ts.map +1 -0
  166. package/dist/store.js +344 -0
  167. package/dist/store.js.map +1 -0
  168. package/dist/types.d.ts +235 -0
  169. package/dist/types.d.ts.map +1 -0
  170. package/dist/types.js +5 -0
  171. package/dist/types.js.map +1 -0
  172. package/docs/README.md +68 -0
  173. package/docs/inspection/consumers.md +178 -0
  174. package/docs/inspection/list.md +182 -0
  175. package/docs/inspection/resolve.md +172 -0
  176. package/docs/installation/configuration.md +238 -0
  177. package/docs/installation/install.md +184 -0
  178. package/docs/maintenance/prune.md +159 -0
  179. package/docs/maintenance/remove.md +174 -0
  180. package/docs/maintenance/verify.md +174 -0
  181. package/docs/publishing/publish.md +146 -0
  182. package/docs/publishing/push.md +146 -0
  183. package/docs/store/locking.md +118 -0
  184. package/docs/store/namespaces.md +141 -0
  185. package/docs/store/structure.md +163 -0
  186. package/package.json +58 -0
@@ -0,0 +1,146 @@
1
+ # Push Command
2
+
3
+ Publishes a package and automatically updates all consumer projects.
4
+
5
+ ## Usage
6
+
7
+ ```bash
8
+ devlink push [options]
9
+ ```
10
+
11
+ ## Options
12
+
13
+ | Option | Description |
14
+ |--------|-------------|
15
+ | `-n, --namespace <name>` | Target namespace (default: `global`) |
16
+ | `--repo <path>` | Use custom repo path |
17
+
18
+ ## Description
19
+
20
+ The `push` command combines publishing with automatic consumer updates:
21
+
22
+ 1. Publishes the package (same as `devlink publish`)
23
+ 2. Finds all projects that have installed this package
24
+ 3. Re-links the package in each consumer project
25
+ 4. Updates signatures in `installations.json`
26
+ 5. Updates `devlink.lock` files in consumer projects
27
+
28
+ This is the recommended command during active development.
29
+
30
+ ## Example
31
+
32
+ ```bash
33
+ cd my-sdk/packages/core
34
+ devlink push
35
+ ```
36
+
37
+ Output:
38
+ ```
39
+ 📦 @scope/core@1.0.0 published to global
40
+ Signature: abc123new
41
+
42
+ 🔄 Pushing to 2 project(s):
43
+ ✓ /home/user/project-a
44
+ ✓ /home/user/project-b
45
+ ```
46
+
47
+ ## How It Works
48
+
49
+ ### 1. Publish Phase
50
+
51
+ Same as `devlink publish`:
52
+ - Copies files to store
53
+ - Updates registry
54
+ - Generates new signature
55
+
56
+ ### 2. Find Consumers
57
+
58
+ Searches `installations.json` for projects that:
59
+ - Have installed this package
60
+ - From the same namespace
61
+ - With the same version
62
+
63
+ ### 3. Update Consumers
64
+
65
+ For each consumer project:
66
+ - Verifies project still exists
67
+ - Re-creates symlink in `node_modules`
68
+ - Updates signature in `installations.json`
69
+ - Updates `devlink.lock` file
70
+
71
+ ## Consumer Tracking
72
+
73
+ Projects become "consumers" when they run `devlink install`. The installation is recorded in `installations.json`:
74
+
75
+ ```json
76
+ {
77
+ "projects": {
78
+ "/home/user/project-a": {
79
+ "packages": {
80
+ "@scope/core": {
81
+ "version": "1.0.0",
82
+ "namespace": "global",
83
+ "signature": "old-signature"
84
+ }
85
+ }
86
+ }
87
+ }
88
+ }
89
+ ```
90
+
91
+ After `push`, the signature is updated to match the new content.
92
+
93
+ ## Use Cases
94
+
95
+ ### Active Development
96
+
97
+ When developing a library used by multiple projects:
98
+
99
+ ```bash
100
+ # Make changes to library
101
+ vim src/index.ts
102
+
103
+ # Build
104
+ npm run build
105
+
106
+ # Push to all consumers
107
+ devlink push
108
+ ```
109
+
110
+ All consumer projects immediately get the updated code.
111
+
112
+ ### Feature Branch Development
113
+
114
+ ```bash
115
+ # Publish to feature namespace
116
+ devlink push -n feature-v2
117
+
118
+ # Only consumers using feature-v2 namespace are updated
119
+ ```
120
+
121
+ ## Dead Projects
122
+
123
+ If a consumer project no longer exists (deleted), `push` will:
124
+ - Skip that project
125
+ - Show a warning
126
+ - Continue with other projects
127
+
128
+ To clean up dead projects:
129
+
130
+ ```bash
131
+ devlink consumers --prune
132
+ ```
133
+
134
+ ## Comparison with Publish
135
+
136
+ | Aspect | `publish` | `push` |
137
+ |--------|-----------|--------|
138
+ | Publishes package | ✓ | ✓ |
139
+ | Updates consumers | ✗ | ✓ |
140
+ | Use case | Initial publish | Active development |
141
+
142
+ ## See Also
143
+
144
+ - [Publish Command](publish.md) - Publishing without consumer updates
145
+ - [Consumers Command](../inspection/consumers.md) - Managing consumer projects
146
+ - [Install Command](../installation/install.md) - How projects become consumers
@@ -0,0 +1,118 @@
1
+ # File Locking
2
+
3
+ DevLink uses file locking to serialize write operations and prevent store corruption when multiple processes access the store simultaneously.
4
+
5
+ ## How It Works
6
+
7
+ When a command needs to modify the store, it:
8
+
9
+ 1. Attempts to acquire an exclusive lock
10
+ 2. If lock is held by another process, waits and retries
11
+ 3. Executes the operation
12
+ 4. Releases the lock
13
+
14
+ ## Lock File
15
+
16
+ The lock is implemented as a file at `{store}/.lock`:
17
+
18
+ ```json
19
+ {
20
+ "pid": 12345,
21
+ "acquired": "2026-02-12T10:00:00Z",
22
+ "command": "devlink publish"
23
+ }
24
+ ```
25
+
26
+ ## Operations Requiring Lock
27
+
28
+ | Command | Requires Lock | Reason |
29
+ |---------|---------------|--------|
30
+ | `publish` | ✓ | Modifies registry.json, writes files |
31
+ | `push` | ✓ | Modifies registry.json, installations.json |
32
+ | `install` | ✓ | Modifies installations.json |
33
+ | `remove` | ✓ | Modifies registry.json, deletes files |
34
+ | `verify --fix` | ✓ | Modifies registry.json |
35
+ | `prune` | ✓ | Modifies registry.json, deletes files |
36
+ | `consumers --prune` | ✓ | Modifies installations.json |
37
+ | `list` | ✗ | Read-only |
38
+ | `resolve` | ✗ | Read-only |
39
+ | `verify` | ✗ | Read-only |
40
+ | `consumers` | ✗ | Read-only |
41
+
42
+ ## Lock Parameters
43
+
44
+ | Parameter | Value | Description |
45
+ |-----------|-------|-------------|
46
+ | Timeout | 30 seconds | Maximum wait time for lock |
47
+ | Retry interval | 100ms | Time between retry attempts |
48
+ | Stale detection | 10 seconds | Lock considered stale if process is dead |
49
+
50
+ ## Stale Lock Detection
51
+
52
+ If a process crashes while holding the lock, DevLink detects this by:
53
+
54
+ 1. Reading the PID from the lock file
55
+ 2. Checking if that process is still running
56
+ 3. If process is dead, removing the stale lock
57
+
58
+ This prevents deadlocks from crashed processes.
59
+
60
+ ## Concurrent Access Example
61
+
62
+ ```
63
+ Terminal A: devlink publish Terminal B: devlink push
64
+ ───────────────────────────── ─────────────────────────
65
+
66
+ 1. Acquire lock ✓ 1. Acquire lock
67
+ ⏳ Store locked by PID 1234
68
+ 2. Read registry.json
69
+ 3. Copy files 2. Retry (100ms)
70
+ 4. Update registry.json ⏳ Still locked
71
+ 5. Release lock ✓
72
+ 3. Acquire lock ✓
73
+ 4. Continue operation...
74
+ 5. Release lock ✓
75
+ ```
76
+
77
+ ## Troubleshooting
78
+
79
+ ### Lock Timeout
80
+
81
+ If you see "Lock timeout" errors:
82
+
83
+ 1. Check if another DevLink process is running
84
+ 2. Check for stale lock files (process crashed)
85
+ 3. Manually remove `.lock` file if necessary
86
+
87
+ ```bash
88
+ # Check lock file
89
+ cat ~/.devlink/.lock
90
+
91
+ # Remove stale lock (use with caution)
92
+ rm ~/.devlink/.lock
93
+ ```
94
+
95
+ ### Multiple Repos
96
+
97
+ Each repo has its own lock file, so operations on different repos don't block each other:
98
+
99
+ ```bash
100
+ # These can run simultaneously
101
+ devlink --repo /repo-a publish &
102
+ devlink --repo /repo-b publish &
103
+ ```
104
+
105
+ ## Implementation Details
106
+
107
+ The lock uses atomic file operations:
108
+
109
+ 1. Create lock file with `O_EXCL` flag (fails if exists)
110
+ 2. Write lock info (PID, timestamp, command)
111
+ 3. On release, delete lock file
112
+
113
+ This ensures only one process can hold the lock at a time.
114
+
115
+ ## See Also
116
+
117
+ - [Store Structure](structure.md) - Lock file location
118
+ - [Verify Command](../maintenance/verify.md) - Check store integrity
@@ -0,0 +1,141 @@
1
+ # Namespaces
2
+
3
+ Namespaces provide isolated contexts for packages, allowing multiple versions or variants of the same package to coexist.
4
+
5
+ ## Concept
6
+
7
+ A namespace is a logical container for packages. Each namespace is independent, meaning:
8
+
9
+ - The same package@version can exist in multiple namespaces with different content
10
+ - Projects can choose which namespaces to search when resolving packages
11
+ - Feature branches can have their own namespace without affecting stable packages
12
+
13
+ ## The Global Namespace
14
+
15
+ The `global` namespace is special:
16
+
17
+ - **Reserved**: Cannot be deleted
18
+ - **Default**: Used when no namespace is specified
19
+ - **Fallback**: Typically the last namespace in precedence order
20
+
21
+ ```bash
22
+ # These are equivalent
23
+ devlink publish
24
+ devlink publish -n global
25
+ ```
26
+
27
+ ## Creating Namespaces
28
+
29
+ Namespaces are created automatically when you publish to them:
30
+
31
+ ```bash
32
+ # Creates 'feature-v2' namespace if it doesn't exist
33
+ devlink publish -n feature-v2
34
+ ```
35
+
36
+ ## Use Cases
37
+
38
+ ### Feature Branch Development
39
+
40
+ Isolate experimental changes without affecting stable packages:
41
+
42
+ ```bash
43
+ # Developer working on v2 API
44
+ cd my-sdk
45
+ devlink publish -n sdk-v2
46
+
47
+ # Consumer project uses sdk-v2 first, falls back to global
48
+ # devlink.config.mjs:
49
+ # namespaces: ["sdk-v2", "global"]
50
+ ```
51
+
52
+ ### Team Isolation
53
+
54
+ Different teams can have their own namespaces:
55
+
56
+ ```bash
57
+ devlink publish -n team-frontend
58
+ devlink publish -n team-backend
59
+ ```
60
+
61
+ ### Version Testing
62
+
63
+ Test new versions before promoting to global:
64
+
65
+ ```bash
66
+ # Publish beta to testing namespace
67
+ devlink publish -n testing
68
+
69
+ # After validation, publish to global
70
+ devlink publish -n global
71
+ ```
72
+
73
+ ## Namespace Precedence
74
+
75
+ When resolving packages, namespaces are searched in order:
76
+
77
+ ```javascript
78
+ // devlink.config.mjs
79
+ export default {
80
+ dev: () => ({
81
+ manager: "store",
82
+ namespaces: ["feature-v2", "global"],
83
+ }),
84
+ };
85
+ ```
86
+
87
+ Resolution order:
88
+ 1. Search in `feature-v2`
89
+ 2. If not found, search in `global`
90
+ 3. If not found anywhere, error
91
+
92
+ ### Example
93
+
94
+ ```
95
+ Store contents:
96
+ global/@scope/core@1.0.0
97
+ global/@scope/utils@1.0.0
98
+ feature-v2/@scope/core@1.0.0 (different code)
99
+
100
+ With namespaces: ["feature-v2", "global"]
101
+
102
+ Resolving @scope/core@1.0.0:
103
+ → Found in feature-v2 ✓
104
+
105
+ Resolving @scope/utils@1.0.0:
106
+ → Not in feature-v2
107
+ → Found in global ✓
108
+ ```
109
+
110
+ ## Listing Namespaces
111
+
112
+ ```bash
113
+ # List all packages grouped by namespace
114
+ devlink list
115
+
116
+ # List specific namespaces
117
+ devlink list -n global,feature-v2
118
+ ```
119
+
120
+ ## Removing Namespaces
121
+
122
+ ```bash
123
+ # Remove entire namespace (and all packages within)
124
+ devlink remove feature-v2
125
+
126
+ # Note: Cannot remove 'global' namespace
127
+ devlink remove global # Error!
128
+ ```
129
+
130
+ ## Best Practices
131
+
132
+ 1. **Use descriptive names**: `feature-auth-v2`, `team-mobile`, `release-candidate`
133
+ 2. **Clean up old namespaces**: Remove namespaces when feature branches are merged
134
+ 3. **Keep global stable**: Only publish tested packages to global
135
+ 4. **Document namespace usage**: Let team members know which namespaces to use
136
+
137
+ ## See Also
138
+
139
+ - [Store Structure](structure.md) - How namespaces are stored on disk
140
+ - [Resolve Command](../inspection/resolve.md) - Debug namespace resolution
141
+ - [Configuration](../installation/configuration.md) - Configure namespace precedence
@@ -0,0 +1,163 @@
1
+ # Store Structure
2
+
3
+ The DevLink store is a centralized repository for locally published packages.
4
+
5
+ ## Default Location
6
+
7
+ By default, the store is located at:
8
+
9
+ - **Linux/macOS**: `~/.devlink/`
10
+ - **Windows**: `%LOCALAPPDATA%\DevLink\`
11
+
12
+ ## Custom Location
13
+
14
+ You can use a custom location via:
15
+
16
+ ```bash
17
+ # Command line flag
18
+ devlink --repo /path/to/repo list
19
+
20
+ # Environment variable
21
+ export DEVLINK_REPO=/path/to/repo
22
+ devlink list
23
+ ```
24
+
25
+ This allows maintaining multiple independent stores for different projects or teams.
26
+
27
+ ## Directory Structure
28
+
29
+ ```
30
+ ~/.devlink/ # Store root
31
+ ├── .lock # Lock file for write serialization
32
+ ├── registry.json # Package index (metadata)
33
+ ├── installations.json # Consumer project tracking
34
+ └── namespaces/ # Package storage
35
+ ├── global/ # Default namespace (reserved)
36
+ │ ├── @scope/ # Scoped packages
37
+ │ │ └── package-name/
38
+ │ │ ├── 1.0.0/ # Version directory
39
+ │ │ │ ├── package.json
40
+ │ │ │ ├── devlink.sig # Content signature
41
+ │ │ │ └── dist/ # Package files
42
+ │ │ └── 2.0.0/
43
+ │ └── simple-package/ # Non-scoped packages
44
+ │ └── 1.0.0/
45
+ └── feature-branch/ # Custom namespace
46
+ └── @scope/
47
+ └── package-name/
48
+ └── 1.0.0/
49
+ ```
50
+
51
+ ## Files
52
+
53
+ ### registry.json
54
+
55
+ The registry is an index of all published packages. It contains metadata but not the actual package files.
56
+
57
+ ```json
58
+ {
59
+ "version": "1.0.0",
60
+ "namespaces": {
61
+ "global": {
62
+ "created": "2026-02-12T10:00:00Z",
63
+ "packages": {
64
+ "@scope/package": {
65
+ "versions": {
66
+ "1.0.0": {
67
+ "signature": "6761ca1fefdde1b6e9ea372e7d6931e4",
68
+ "published": "2026-02-12T10:00:00Z",
69
+ "files": 15
70
+ }
71
+ }
72
+ }
73
+ }
74
+ }
75
+ }
76
+ }
77
+ ```
78
+
79
+ ### installations.json
80
+
81
+ Tracks which projects have installed packages from the store. Used by the `push` command to update consumers.
82
+
83
+ ```json
84
+ {
85
+ "version": "1.0.0",
86
+ "projects": {
87
+ "/home/user/my-project": {
88
+ "registered": "2026-02-12T10:00:00Z",
89
+ "packages": {
90
+ "@scope/package": {
91
+ "version": "1.0.0",
92
+ "namespace": "global",
93
+ "signature": "6761ca1f...",
94
+ "installedAt": "2026-02-12T10:05:00Z"
95
+ }
96
+ }
97
+ }
98
+ }
99
+ }
100
+ ```
101
+
102
+ ### .lock
103
+
104
+ A lock file used to serialize write operations. Contains information about the process holding the lock.
105
+
106
+ ```json
107
+ {
108
+ "pid": 12345,
109
+ "acquired": "2026-02-12T10:00:00Z",
110
+ "command": "devlink publish"
111
+ }
112
+ ```
113
+
114
+ ### devlink.sig
115
+
116
+ Each published package version contains a signature file with an MD5 hash of the package contents. Used for integrity verification.
117
+
118
+ ## Package Storage
119
+
120
+ Packages are stored in a hierarchical structure:
121
+
122
+ ```
123
+ namespaces/{namespace}/{package-name}/{version}/
124
+ ```
125
+
126
+ For scoped packages:
127
+ ```
128
+ namespaces/{namespace}/@{scope}/{package-name}/{version}/
129
+ ```
130
+
131
+ Each version directory contains:
132
+ - `package.json` - Package manifest
133
+ - `devlink.sig` - Content signature
134
+ - All files specified in the package's `files` field
135
+
136
+ ## Multiple Versions
137
+
138
+ Multiple versions of the same package can coexist:
139
+
140
+ ```
141
+ namespaces/global/@scope/core/
142
+ ├── 1.0.0/
143
+ ├── 1.1.0/
144
+ └── 2.0.0/
145
+ ```
146
+
147
+ ## Multiple Namespaces
148
+
149
+ The same package can exist in different namespaces with different content:
150
+
151
+ ```
152
+ namespaces/
153
+ ├── global/
154
+ │ └── @scope/core/1.0.0/ # Stable version
155
+ └── feature-v2/
156
+ └── @scope/core/1.0.0/ # Development version (different code)
157
+ ```
158
+
159
+ ## See Also
160
+
161
+ - [Namespaces](namespaces.md) - Understanding namespace isolation
162
+ - [File Locking](locking.md) - Concurrency control
163
+ - [Publish Command](../publishing/publish.md) - Publishing packages
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@unlimitechcloud/devlink",
3
+ "version": "1.0.2",
4
+ "description": "Local package development and linking tool with namespace support",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "bin": {
9
+ "devlink": "dist/cli.js"
10
+ },
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "docs",
20
+ "AGENTS.md"
21
+ ],
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "git+https://github.com/unlimitechcloud/devlink.git"
25
+ },
26
+ "scripts": {
27
+ "build": "tsc",
28
+ "clean": "rm -rf dist",
29
+ "test": "vitest run",
30
+ "test:watch": "vitest",
31
+ "test:coverage": "vitest run --coverage",
32
+ "prepublishOnly": "npm run build",
33
+ "publish:local": "node dist/cli.js publish"
34
+ },
35
+ "keywords": [
36
+ "npm",
37
+ "link",
38
+ "local",
39
+ "development",
40
+ "monorepo",
41
+ "packages",
42
+ "dependencies"
43
+ ],
44
+ "author": "UnlimitechCloud",
45
+ "license": "MIT",
46
+ "devDependencies": {
47
+ "@types/node": "^22.0.0",
48
+ "@vitest/coverage-v8": "^2.0.0",
49
+ "typescript": "^5.5.0",
50
+ "vitest": "^2.0.0"
51
+ },
52
+ "dependencies": {
53
+ "cli-color": "^2.0.0"
54
+ },
55
+ "engines": {
56
+ "node": ">=18.0.0"
57
+ }
58
+ }