Skip to content

Commit 2c8503e

Browse files
committed
feat: add habitat-usage skill
1 parent 42310b9 commit 2c8503e

8 files changed

Lines changed: 310 additions & 0 deletions

File tree

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
---
3+
4+
Add habitat-usage skill package.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
"@lynx-js/ai-plugin-lynx-debug": "workspace:*",
3232
"@lynx-js/ai-plugin-reactlynx": "workspace:*",
3333
"@lynx-js/skill-debug-info-remapping": "workspace:*",
34+
"@lynx-js/skill-habitat-usage": "workspace:*",
3435
"@lynx-js/skill-reactlynx-best-practices": "workspace:*",
3536
"@lynx-js/skill-trace-analysis": "workspace:*"
3637
},
Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
---
2+
name: habitat-usage
3+
description: Guidance on using Habitat to manage multi-repo source and asset dependencies via .habitat/DEPS and hab sync, plus troubleshooting common sync failures.
4+
---
5+
6+
# Habitat Usage Guide
7+
8+
Habitat is a dependency-sync tool for mono-repo-like layouts built from multiple Git repos and asset downloads. This skill provides setup guidance, copy-pastable config snippets, and a troubleshooting checklist for common sync failures.
9+
10+
## When to Apply
11+
12+
- Setting up a “main repo + dependency repos/assets” workspace using `.habitat` + `DEPS`
13+
- Adding or changing dependency types: git repos, nested solutions, HTTP downloads, or custom actions
14+
- Debugging `hab sync` failures related to config, auth, network, or integrity checks
15+
16+
## Troubleshooting Inputs
17+
18+
When sync fails (fetch errors, permission issues, timeouts), collect:
19+
20+
- Habitat version and distribution (`./hab` wrapper in repo, `hab.pex`, etc.)
21+
- OS and architecture (darwin/windows/linux + arm64/x86_64)
22+
- The exact command and full error output (do not paste any secrets)
23+
- Relevant config snippets:
24+
- `.habitat`
25+
- `DEPS` (or the file pointed to by `deps_file` in `.habitat`)
26+
27+
## Installation and Versioning
28+
29+
Prefer committing the Habitat wrapper (`hab`) and config files (`.habitat`, `DEPS`) into the repository so developers and CI use the same version and configuration.
30+
31+
Avoid downloading `releases/latest` in automation, because it is not reproducible. Instead, pin to a specific release version (tag) and keep that pinned version consistent across developers and CI.
32+
33+
```bash
34+
HABITAT_VERSION="0.3.145"
35+
curl -L -o hab "https://github.com/lynx-family/habitat/releases/download/${HABITAT_VERSION}/hab"
36+
chmod +x hab
37+
```
38+
39+
If you just want to try Habitat locally (not recommended for CI), you can download the latest release:
40+
41+
```bash
42+
curl -L -o hab "https://github.com/lynx-family/habitat/releases/latest/download/hab"
43+
chmod +x hab
44+
```
45+
46+
If you need integrity verification, pin an expected SHA-256 for `hab` in your repo/CI and verify after download:
47+
48+
```bash
49+
EXPECTED_SHA256="<fill-me>"
50+
51+
if command -v shasum >/dev/null 2>&1; then
52+
echo "${EXPECTED_SHA256} hab" | shasum -a 256 -c -
53+
else
54+
echo "${EXPECTED_SHA256} hab" | sha256sum -c -
55+
fi
56+
```
57+
58+
## Multi-Repo Setup (solutions + deps)
59+
60+
### 1) Generate `.habitat` (solution config)
61+
62+
Generate the Habitat config at the main repo root:
63+
64+
```bash
65+
./hab config <repo remote uri>
66+
```
67+
68+
`.habitat` describes one or more solutions. Minimal example:
69+
70+
```python
71+
solutions = [
72+
{
73+
"name": ".",
74+
"deps_file": "DEPS",
75+
"url": "git@github.com:namespace/repo.git",
76+
}
77+
]
78+
```
79+
80+
Fields:
81+
82+
- `name`: solution name, typically `"."` for the main repo
83+
- `deps_file`: dependency manifest path (relative to the main repo root)
84+
- `url`: the main repo remote URL (used by the tool/CI)
85+
86+
### 2) Write `DEPS` (dependency manifest)
87+
88+
In `DEPS`, define `deps = { ... }`. The key is the destination path in the main repo, and the value describes the dependency type and parameters.
89+
90+
#### 2.1 git deps (source repositories)
91+
92+
```python
93+
deps = {
94+
"lib/example": {
95+
"type": "git",
96+
"url": "git@github.com:namespace/lib.git",
97+
"branch": "dev",
98+
}
99+
}
100+
```
101+
102+
Notes:
103+
104+
- Prefer stable refs (e.g., commit) for reproducibility; use branches when you want rolling updates.
105+
- If the destination directory already exists and contains local changes, decide whether overwriting is acceptable before syncing.
106+
107+
#### 2.2 solution deps (nested solutions)
108+
109+
If a dependency has its own dependency tree, you can bring it in as a solution and sync recursively:
110+
111+
```python
112+
deps = {
113+
"third_party/some_solution": {
114+
"type": "solution",
115+
"url": "git@github.com:namespace/solution_repo.git",
116+
"branch": "main",
117+
"deps_file": "DEPS",
118+
}
119+
}
120+
```
121+
122+
#### 2.3 http deps (assets/archives/binaries)
123+
124+
Use this to download archives, toolchains, model files, etc. Prefer providing integrity checks for verifiability and reproducibility:
125+
126+
```python
127+
deps = {
128+
"third_party/tooling": {
129+
"type": "http",
130+
"url": "https://example.com/tooling.zip",
131+
"sha256": "SHA256_HEX",
132+
}
133+
}
134+
```
135+
136+
#### 2.4 action deps (custom sync actions)
137+
138+
Use this to run extra steps during sync (generate files, copy assets, apply patches, etc.). Example:
139+
140+
```python
141+
def example_function():
142+
from pathlib import Path
143+
import shutil
144+
145+
dest_dir = Path("scripts/sync_something")
146+
dest_dir.mkdir(parents=True, exist_ok=True)
147+
src = dest_dir / "input.txt"
148+
dst = dest_dir / "output.txt"
149+
src.write_text("example\n", encoding="utf-8")
150+
shutil.copyfile(src, dst)
151+
152+
153+
deps = {
154+
"scripts/sync_something": {
155+
"type": "action",
156+
"function": example_function,
157+
}
158+
}
159+
```
160+
161+
## Sync Dependencies (hab sync)
162+
163+
Run at the main repo root:
164+
165+
```bash
166+
./hab sync .
167+
```
168+
169+
After sync, dependencies are materialized into the paths specified by the keys in `DEPS`.
170+
171+
## Track Config in Version Control
172+
173+
Commit the wrapper and config files to enable one-command bootstrapping for developers and CI:
174+
175+
```bash
176+
git add hab .habitat DEPS && git commit -m "Add habitat to manage dependencies."
177+
```
178+
179+
## FAQ / Common Failures
180+
181+
### 1) git permission/auth failures
182+
183+
Symptoms:
184+
185+
- Errors like `Permission denied`, `Authentication failed`, or `Could not read from remote repository`
186+
187+
Fix:
188+
189+
- Ensure the dependency `url` protocol matches your environment (SSH/HTTPS).
190+
- For SSH, confirm your SSH key is configured and has access to the target repo.
191+
- In CI, confirm the runner is provisioned with the right credentials.
192+
193+
### 2) http integrity check failures (sha256 mismatch)
194+
195+
Symptoms:
196+
197+
- Download succeeds but integrity verification fails
198+
199+
Fix:
200+
201+
- Check whether `url` content changed or redirects to different content.
202+
- Recompute sha256 for the actual artifact and update `sha256` in `DEPS`.
203+
- If the URL is rolling (e.g., “latest”), prefer an immutable, versioned URL.
204+
205+
### 3) Sync hangs/timeouts
206+
207+
Fix:
208+
209+
- Identify which dependency is slow (temporarily comment out others and bisect).
210+
- Check proxy settings, DNS, and network reachability.
211+
- For large git deps, consider pinning to a commit and reducing unnecessary history (if supported by your setup).
212+
213+
## Response Format (when assisting users)
214+
215+
When a user asks for help configuring deps, fixing errors, or speeding up sync, respond in this order:
216+
217+
1) Conclusion first (root cause + fix)
218+
2) Minimal copy-pastable commands/snippets (`.habitat` / `DEPS` / `./hab sync .`)
219+
3) Call out risky operations (overwriting local dirs, rolling deps harming reproducibility, etc.)
220+
4) If it can still fail, list the next required inputs (version, full error log, relevant config snippets)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{
2+
"name": "@lynx-js/skill-habitat-usage",
3+
"version": "0.0.1",
4+
"description": "Guidance on using Habitat to manage multi-repo source and asset dependencies via .habitat/DEPS and hab sync, plus troubleshooting common sync failures.",
5+
"type": "module",
6+
"files": [
7+
"SKILL.md",
8+
"scripts",
9+
"references",
10+
"examples",
11+
"reference.md",
12+
"examples.md"
13+
],
14+
"scripts": {
15+
"build": "rslib build"
16+
},
17+
"devDependencies": {
18+
"@rslib/core": "catalog:rstack",
19+
"@types/node": "^24.10.4",
20+
"typescript": "^5.9.3"
21+
},
22+
"engines": {
23+
"node": ">=18"
24+
}
25+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright 2026 The Lynx Authors. All rights reserved.
2+
// Licensed under the Apache License Version 2.0 that can be found in the
3+
// LICENSE file in the root directory of this source tree.
4+
import { defineConfig } from '@rslib/core';
5+
6+
export default defineConfig({
7+
lib: [
8+
{
9+
format: 'esm',
10+
syntax: ['node 18'],
11+
autoExtension: false,
12+
output: {
13+
filename: {
14+
js: '[name].mjs',
15+
},
16+
distPath: './scripts',
17+
},
18+
},
19+
],
20+
output: {
21+
target: 'node',
22+
},
23+
});
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// Copyright 2026 The Lynx Authors. All rights reserved.
2+
// Licensed under the Apache License Version 2.0 that can be found in the
3+
// LICENSE file in the root directory of this source tree.
4+
export {};
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"compilerOptions": {
3+
"lib": ["ES2022"],
4+
"target": "ES2022",
5+
"module": "NodeNext",
6+
"moduleResolution": "NodeNext",
7+
"types": ["node"],
8+
"rootDir": "src",
9+
"outDir": "scripts",
10+
"strict": true,
11+
"skipLibCheck": true,
12+
"isolatedModules": true,
13+
"resolveJsonModule": true,
14+
"esModuleInterop": true,
15+
"declaration": false
16+
},
17+
"include": ["src"]
18+
}

pnpm-lock.yaml

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)