@offworld/sdk 0.1.2 → 0.1.5
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 +29 -25
- package/dist/index.d.mts +1 -66
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +194 -83
- package/dist/index.mjs.map +1 -1
- package/package.json +38 -8
package/README.md
CHANGED
|
@@ -12,24 +12,24 @@ bun add @offworld/sdk
|
|
|
12
12
|
|
|
13
13
|
## Modules
|
|
14
14
|
|
|
15
|
-
| Module
|
|
16
|
-
|
|
|
17
|
-
| `config.ts`
|
|
18
|
-
| `paths.ts`
|
|
19
|
-
| `clone.ts`
|
|
20
|
-
| `index-manager.ts`
|
|
21
|
-
| `generate.ts`
|
|
22
|
-
| `sync.ts`
|
|
23
|
-
| `auth.ts`
|
|
24
|
-
| `agents.ts`
|
|
25
|
-
| `agents-md.ts`
|
|
26
|
-
| `repo-source.ts`
|
|
27
|
-
| `manifest.ts`
|
|
28
|
-
| `dep-mappings.ts`
|
|
29
|
-
| `reference-matcher.ts` | Match deps to installed references
|
|
30
|
-
| `repo-manager.ts`
|
|
31
|
-
| `models.ts`
|
|
32
|
-
| `installation.ts`
|
|
15
|
+
| Module | Description |
|
|
16
|
+
| ---------------------- | ----------------------------------------- |
|
|
17
|
+
| `config.ts` | Config load/save, path utilities |
|
|
18
|
+
| `paths.ts` | XDG-compliant path resolution |
|
|
19
|
+
| `clone.ts` | Git clone/update/remove |
|
|
20
|
+
| `index-manager.ts` | Global + project map management |
|
|
21
|
+
| `generate.ts` | AI reference generation |
|
|
22
|
+
| `sync.ts` | Convex client for push/pull |
|
|
23
|
+
| `auth.ts` | WorkOS token management |
|
|
24
|
+
| `agents.ts` | Agent registry |
|
|
25
|
+
| `agents-md.ts` | AGENTS.md reference table generation |
|
|
26
|
+
| `repo-source.ts` | Parse repo input (URL, owner/repo, local) |
|
|
27
|
+
| `manifest.ts` | Dependency parsing (package.json, etc.) |
|
|
28
|
+
| `dep-mappings.ts` | npm package to GitHub repo resolution |
|
|
29
|
+
| `reference-matcher.ts` | Match deps to installed references |
|
|
30
|
+
| `repo-manager.ts` | Bulk repo operations (update, prune, gc) |
|
|
31
|
+
| `models.ts` | AI provider/model registry |
|
|
32
|
+
| `installation.ts` | Upgrade/uninstall utilities |
|
|
33
33
|
|
|
34
34
|
## Usage
|
|
35
35
|
|
|
@@ -84,7 +84,11 @@ await pushReference("owner/repo", referenceData);
|
|
|
84
84
|
### Dependency Resolution
|
|
85
85
|
|
|
86
86
|
```typescript
|
|
87
|
-
import {
|
|
87
|
+
import {
|
|
88
|
+
parseDependencies,
|
|
89
|
+
resolveDependencyRepo,
|
|
90
|
+
matchDependenciesToReferences,
|
|
91
|
+
} from "@offworld/sdk";
|
|
88
92
|
|
|
89
93
|
const deps = parseDependencies("package.json");
|
|
90
94
|
const repo = await resolveDependencyRepo("zod");
|
|
@@ -93,12 +97,12 @@ const matches = matchDependenciesToReferences(deps);
|
|
|
93
97
|
|
|
94
98
|
## Data Paths
|
|
95
99
|
|
|
96
|
-
| Purpose
|
|
97
|
-
|
|
|
98
|
-
| Config
|
|
99
|
-
| Data root
|
|
100
|
-
| Skill dir
|
|
101
|
-
| Global map | `Paths.globalMap`
|
|
100
|
+
| Purpose | Getter |
|
|
101
|
+
| ---------- | --------------------- |
|
|
102
|
+
| Config | `Paths.config` |
|
|
103
|
+
| Data root | `Paths.data` |
|
|
104
|
+
| Skill dir | `Paths.offworldDir` |
|
|
105
|
+
| Global map | `Paths.globalMap` |
|
|
102
106
|
| References | `Paths.referencesDir` |
|
|
103
107
|
|
|
104
108
|
## Commands
|
package/dist/index.d.mts
CHANGED
|
@@ -5,7 +5,7 @@ import { Agent, Config, Config as Config$1, FileIndex, FileIndexEntry, FileRole,
|
|
|
5
5
|
* SDK Constants
|
|
6
6
|
*/
|
|
7
7
|
/** SDK version - must match package.json */
|
|
8
|
-
declare const VERSION = "0.1.
|
|
8
|
+
declare const VERSION = "0.1.5";
|
|
9
9
|
/**
|
|
10
10
|
* Default patterns to ignore when scanning repositories.
|
|
11
11
|
* Includes directories, binary files, IDE configs, and build outputs.
|
|
@@ -269,19 +269,7 @@ interface CloneOptions {
|
|
|
269
269
|
/** Use sparse checkout for large repos (only src/, lib/, packages/, docs/) */
|
|
270
270
|
sparse?: boolean;
|
|
271
271
|
}
|
|
272
|
-
/**
|
|
273
|
-
* Get the current commit SHA for a repository
|
|
274
|
-
*/
|
|
275
272
|
declare function getCommitSha(repoPath: string): string;
|
|
276
|
-
/**
|
|
277
|
-
* Get the number of commits between two SHAs.
|
|
278
|
-
* Returns the number of commits from `olderSha` to `newerSha`.
|
|
279
|
-
* Returns null if the distance cannot be determined (e.g., shallow clone without the commit).
|
|
280
|
-
*
|
|
281
|
-
* @param repoPath - Path to the git repository
|
|
282
|
-
* @param olderSha - The older commit SHA (e.g., remote skill's commit)
|
|
283
|
-
* @param newerSha - The newer commit SHA (e.g., current HEAD), defaults to HEAD
|
|
284
|
-
*/
|
|
285
273
|
declare function getCommitDistance(repoPath: string, olderSha: string, newerSha?: string): number | null;
|
|
286
274
|
/**
|
|
287
275
|
* Clone a remote repository to the local repo root.
|
|
@@ -293,15 +281,7 @@ declare function getCommitDistance(repoPath: string, olderSha: string, newerSha?
|
|
|
293
281
|
* @throws GitError if clone fails
|
|
294
282
|
*/
|
|
295
283
|
declare function cloneRepo(source: RemoteRepoSource, options?: CloneOptions): Promise<string>;
|
|
296
|
-
/**
|
|
297
|
-
* Check if a repository is a shallow clone.
|
|
298
|
-
*/
|
|
299
284
|
declare function isShallowClone(repoPath: string): boolean;
|
|
300
|
-
/**
|
|
301
|
-
* Convert a shallow clone to a full clone by fetching all history.
|
|
302
|
-
* Returns true if the repo was shallow and is now unshallowed.
|
|
303
|
-
* Returns false if the repo was already a full clone.
|
|
304
|
-
*/
|
|
305
285
|
declare function unshallowRepo(repoPath: string): Promise<boolean>;
|
|
306
286
|
interface UpdateResult {
|
|
307
287
|
/** Whether any updates were fetched */
|
|
@@ -328,31 +308,11 @@ interface UpdateOptions {
|
|
|
328
308
|
*/
|
|
329
309
|
declare function updateRepo(qualifiedName: string, options?: UpdateOptions): Promise<UpdateResult>;
|
|
330
310
|
interface RemoveOptions {
|
|
331
|
-
/** Only remove reference files (keep cloned repo) */
|
|
332
311
|
referenceOnly?: boolean;
|
|
333
|
-
/** Only remove cloned repo (keep reference files) */
|
|
334
312
|
repoOnly?: boolean;
|
|
335
313
|
}
|
|
336
|
-
/**
|
|
337
|
-
* Remove a cloned repository and its reference data.
|
|
338
|
-
*
|
|
339
|
-
* @param qualifiedName - The qualified name of the repo
|
|
340
|
-
* @param options - Remove options
|
|
341
|
-
* @returns true if removed, false if not found
|
|
342
|
-
*/
|
|
343
314
|
declare function removeRepo(qualifiedName: string, options?: RemoveOptions): Promise<boolean>;
|
|
344
|
-
/**
|
|
345
|
-
* List all cloned repositories from the global map.
|
|
346
|
-
*
|
|
347
|
-
* @returns Array of qualified names
|
|
348
|
-
*/
|
|
349
315
|
declare function listRepos(): string[];
|
|
350
|
-
/**
|
|
351
|
-
* Check if a repository is cloned and in the map.
|
|
352
|
-
*
|
|
353
|
-
* @param qualifiedName - The qualified name of the repo
|
|
354
|
-
* @returns true if repo exists in map and on disk
|
|
355
|
-
*/
|
|
356
316
|
declare function isRepoCloned(qualifiedName: string): boolean;
|
|
357
317
|
/**
|
|
358
318
|
* Get the local path for a cloned repository.
|
|
@@ -567,7 +527,6 @@ declare function validatePushAllowed(source: RepoSource$1): void;
|
|
|
567
527
|
/**
|
|
568
528
|
* Authentication utilities for offworld CLI
|
|
569
529
|
*/
|
|
570
|
-
/** Stored authentication data */
|
|
571
530
|
interface AuthData {
|
|
572
531
|
token: string;
|
|
573
532
|
expiresAt?: string;
|
|
@@ -591,15 +550,7 @@ declare class NotLoggedInError extends AuthError {
|
|
|
591
550
|
declare class TokenExpiredError extends AuthError {
|
|
592
551
|
constructor(message?: string);
|
|
593
552
|
}
|
|
594
|
-
/**
|
|
595
|
-
* Returns the auth file path using XDG Base Directory spec
|
|
596
|
-
* Location: ~/.local/share/offworld/auth.json
|
|
597
|
-
*/
|
|
598
553
|
declare function getAuthPath(): string;
|
|
599
|
-
/**
|
|
600
|
-
* Saves authentication data to ~/.local/share/offworld/auth.json
|
|
601
|
-
* Creates directory if it doesn't exist
|
|
602
|
-
*/
|
|
603
554
|
declare function saveAuthData(data: AuthData): void;
|
|
604
555
|
/**
|
|
605
556
|
* Loads authentication data from ~/.local/share/offworld/auth.json
|
|
@@ -611,34 +562,18 @@ declare function loadAuthData(): AuthData | null;
|
|
|
611
562
|
* @returns true if auth file was deleted, false if it didn't exist
|
|
612
563
|
*/
|
|
613
564
|
declare function clearAuthData(): boolean;
|
|
614
|
-
/**
|
|
615
|
-
* Gets the current authentication token
|
|
616
|
-
* Auto-refreshes if token expires within 1 minute
|
|
617
|
-
* @throws NotLoggedInError if not logged in
|
|
618
|
-
* @throws TokenExpiredError if token is expired and refresh fails
|
|
619
|
-
*/
|
|
620
565
|
declare function getToken(): Promise<string>;
|
|
621
566
|
/**
|
|
622
567
|
* Gets the current authentication token, or null if not logged in
|
|
623
568
|
* Does not throw errors
|
|
624
569
|
*/
|
|
625
570
|
declare function getTokenOrNull(): Promise<string | null>;
|
|
626
|
-
/**
|
|
627
|
-
* Checks if user is logged in with valid token
|
|
628
|
-
*/
|
|
629
571
|
declare function isLoggedIn(): Promise<boolean>;
|
|
630
572
|
declare function getAuthStatus(): Promise<AuthStatus>;
|
|
631
|
-
/**
|
|
632
|
-
* Refreshes the access token using the stored refresh token
|
|
633
|
-
* @returns New auth data with refreshed token
|
|
634
|
-
* @throws AuthError if refresh fails
|
|
635
|
-
*/
|
|
636
573
|
declare function refreshAccessToken(): Promise<AuthData>;
|
|
637
574
|
//#endregion
|
|
638
575
|
//#region src/generate.d.ts
|
|
639
576
|
/**
|
|
640
|
-
* Simplified AI-only reference generation
|
|
641
|
-
*
|
|
642
577
|
* This module provides a streamlined approach to generating reference files
|
|
643
578
|
* by delegating all codebase exploration to the AI agent via OpenCode.
|
|
644
579
|
*/
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/constants.ts","../src/config.ts","../src/paths.ts","../src/repo-source.ts","../src/index-manager.ts","../src/map.ts","../src/clone.ts","../src/ai/opencode.ts","../src/ai/errors.ts","../src/sync.ts","../src/auth.ts","../src/generate.ts","../src/agents.ts","../src/manifest.ts","../src/dep-mappings.ts","../src/reference-matcher.ts","../src/agents-md.ts","../src/repo-manager.ts","../src/models.ts","../src/installation.ts"],"mappings":";;;;;;AAKA;AAAA,cAAa,OAAA;;;;AAMb;cAAa,uBAAA;;;;;;;iBCGG,WAAA,CAAA;AAAA,iBAIA,WAAA,CAAY,MAAA,GAAS,QAAA;;;;;;;AAJrC;;iBAiBgB,WAAA,CACf,QAAA,UACA,QAAA,sCACA,MAAA,GAAS,QAAA;;;AAhBV;;iBA8BgB,aAAA,CAAc,QAAA;;;AAjB9B;;;;;iBAwCgB,mBAAA,CAAoB,QAAA;AAAA,
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/constants.ts","../src/config.ts","../src/paths.ts","../src/repo-source.ts","../src/index-manager.ts","../src/map.ts","../src/clone.ts","../src/ai/opencode.ts","../src/ai/errors.ts","../src/sync.ts","../src/auth.ts","../src/generate.ts","../src/agents.ts","../src/manifest.ts","../src/dep-mappings.ts","../src/reference-matcher.ts","../src/agents-md.ts","../src/repo-manager.ts","../src/models.ts","../src/installation.ts"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -15,7 +15,7 @@ import { api } from "@offworld/backend-api/api";
|
|
|
15
15
|
* SDK Constants
|
|
16
16
|
*/
|
|
17
17
|
/** SDK version - must match package.json */
|
|
18
|
-
const VERSION = "0.1.
|
|
18
|
+
const VERSION = "0.1.5";
|
|
19
19
|
/**
|
|
20
20
|
* Default patterns to ignore when scanning repositories.
|
|
21
21
|
* Includes directories, binary files, IDE configs, and build outputs.
|
|
@@ -764,21 +764,9 @@ function execGitAsync(args, cwd) {
|
|
|
764
764
|
});
|
|
765
765
|
});
|
|
766
766
|
}
|
|
767
|
-
/**
|
|
768
|
-
* Get the current commit SHA for a repository
|
|
769
|
-
*/
|
|
770
767
|
function getCommitSha(repoPath) {
|
|
771
768
|
return execGit(["rev-parse", "HEAD"], repoPath);
|
|
772
769
|
}
|
|
773
|
-
/**
|
|
774
|
-
* Get the number of commits between two SHAs.
|
|
775
|
-
* Returns the number of commits from `olderSha` to `newerSha`.
|
|
776
|
-
* Returns null if the distance cannot be determined (e.g., shallow clone without the commit).
|
|
777
|
-
*
|
|
778
|
-
* @param repoPath - Path to the git repository
|
|
779
|
-
* @param olderSha - The older commit SHA (e.g., remote skill's commit)
|
|
780
|
-
* @param newerSha - The newer commit SHA (e.g., current HEAD), defaults to HEAD
|
|
781
|
-
*/
|
|
782
770
|
function getCommitDistance(repoPath, olderSha, newerSha = "HEAD") {
|
|
783
771
|
try {
|
|
784
772
|
try {
|
|
@@ -875,9 +863,6 @@ async function cloneSparse(cloneUrl, repoPath, options) {
|
|
|
875
863
|
], repoPath);
|
|
876
864
|
await execGitAsync(["checkout"], repoPath);
|
|
877
865
|
}
|
|
878
|
-
/**
|
|
879
|
-
* Check if a repository is a shallow clone.
|
|
880
|
-
*/
|
|
881
866
|
function isShallowClone(repoPath) {
|
|
882
867
|
try {
|
|
883
868
|
return execGit(["rev-parse", "--is-shallow-repository"], repoPath) === "true";
|
|
@@ -885,11 +870,6 @@ function isShallowClone(repoPath) {
|
|
|
885
870
|
return false;
|
|
886
871
|
}
|
|
887
872
|
}
|
|
888
|
-
/**
|
|
889
|
-
* Convert a shallow clone to a full clone by fetching all history.
|
|
890
|
-
* Returns true if the repo was shallow and is now unshallowed.
|
|
891
|
-
* Returns false if the repo was already a full clone.
|
|
892
|
-
*/
|
|
893
873
|
async function unshallowRepo(repoPath) {
|
|
894
874
|
if (!isShallowClone(repoPath)) return false;
|
|
895
875
|
await execGitAsync(["fetch", "--unshallow"], repoPath);
|
|
@@ -926,13 +906,6 @@ async function updateRepo(qualifiedName, options = {}) {
|
|
|
926
906
|
unshallowed
|
|
927
907
|
};
|
|
928
908
|
}
|
|
929
|
-
/**
|
|
930
|
-
* Remove a cloned repository and its reference data.
|
|
931
|
-
*
|
|
932
|
-
* @param qualifiedName - The qualified name of the repo
|
|
933
|
-
* @param options - Remove options
|
|
934
|
-
* @returns true if removed, false if not found
|
|
935
|
-
*/
|
|
936
909
|
async function removeRepo(qualifiedName, options = {}) {
|
|
937
910
|
const entry = readGlobalMap().repos[qualifiedName];
|
|
938
911
|
if (!entry) return false;
|
|
@@ -968,21 +941,10 @@ async function removeRepo(qualifiedName, options = {}) {
|
|
|
968
941
|
});
|
|
969
942
|
return true;
|
|
970
943
|
}
|
|
971
|
-
/**
|
|
972
|
-
* List all cloned repositories from the global map.
|
|
973
|
-
*
|
|
974
|
-
* @returns Array of qualified names
|
|
975
|
-
*/
|
|
976
944
|
function listRepos() {
|
|
977
945
|
const map = readGlobalMap();
|
|
978
946
|
return Object.keys(map.repos);
|
|
979
947
|
}
|
|
980
|
-
/**
|
|
981
|
-
* Check if a repository is cloned and in the map.
|
|
982
|
-
*
|
|
983
|
-
* @param qualifiedName - The qualified name of the repo
|
|
984
|
-
* @returns true if repo exists in map and on disk
|
|
985
|
-
*/
|
|
986
948
|
function isRepoCloned(qualifiedName) {
|
|
987
949
|
const entry = readGlobalMap().repos[qualifiedName];
|
|
988
950
|
if (!entry) return false;
|
|
@@ -1619,7 +1581,7 @@ async function streamPrompt(options) {
|
|
|
1619
1581
|
* Uses ConvexHttpClient for direct type-safe API calls
|
|
1620
1582
|
*/
|
|
1621
1583
|
function getConvexUrl() {
|
|
1622
|
-
return
|
|
1584
|
+
return "";
|
|
1623
1585
|
}
|
|
1624
1586
|
const GITHUB_API_BASE = "https://api.github.com";
|
|
1625
1587
|
var SyncError = class extends Error {
|
|
@@ -1976,11 +1938,6 @@ var TokenExpiredError = class extends AuthError {
|
|
|
1976
1938
|
this.name = "TokenExpiredError";
|
|
1977
1939
|
}
|
|
1978
1940
|
};
|
|
1979
|
-
/**
|
|
1980
|
-
* Extracts expiration timestamp from JWT access token
|
|
1981
|
-
* @param token - JWT access token
|
|
1982
|
-
* @returns ISO string of expiration date, or undefined if extraction fails
|
|
1983
|
-
*/
|
|
1984
1941
|
function extractJwtExpiration(token) {
|
|
1985
1942
|
try {
|
|
1986
1943
|
const parts = token.split(".");
|
|
@@ -1994,17 +1951,9 @@ function extractJwtExpiration(token) {
|
|
|
1994
1951
|
return;
|
|
1995
1952
|
}
|
|
1996
1953
|
}
|
|
1997
|
-
/**
|
|
1998
|
-
* Returns the auth file path using XDG Base Directory spec
|
|
1999
|
-
* Location: ~/.local/share/offworld/auth.json
|
|
2000
|
-
*/
|
|
2001
1954
|
function getAuthPath() {
|
|
2002
1955
|
return Paths.authFile;
|
|
2003
1956
|
}
|
|
2004
|
-
/**
|
|
2005
|
-
* Saves authentication data to ~/.local/share/offworld/auth.json
|
|
2006
|
-
* Creates directory if it doesn't exist
|
|
2007
|
-
*/
|
|
2008
1957
|
function saveAuthData(data) {
|
|
2009
1958
|
const authPath = getAuthPath();
|
|
2010
1959
|
const authDir = dirname(authPath);
|
|
@@ -2043,12 +1992,6 @@ function clearAuthData() {
|
|
|
2043
1992
|
return false;
|
|
2044
1993
|
}
|
|
2045
1994
|
}
|
|
2046
|
-
/**
|
|
2047
|
-
* Gets the current authentication token
|
|
2048
|
-
* Auto-refreshes if token expires within 1 minute
|
|
2049
|
-
* @throws NotLoggedInError if not logged in
|
|
2050
|
-
* @throws TokenExpiredError if token is expired and refresh fails
|
|
2051
|
-
*/
|
|
2052
1995
|
async function getToken() {
|
|
2053
1996
|
const data = loadAuthData();
|
|
2054
1997
|
if (!data) throw new NotLoggedInError();
|
|
@@ -2093,9 +2036,6 @@ async function getTokenOrNull() {
|
|
|
2093
2036
|
return null;
|
|
2094
2037
|
}
|
|
2095
2038
|
}
|
|
2096
|
-
/**
|
|
2097
|
-
* Checks if user is logged in with valid token
|
|
2098
|
-
*/
|
|
2099
2039
|
async function isLoggedIn() {
|
|
2100
2040
|
return await getTokenOrNull() !== null;
|
|
2101
2041
|
}
|
|
@@ -2127,13 +2067,8 @@ async function getAuthStatus() {
|
|
|
2127
2067
|
}
|
|
2128
2068
|
const WORKOS_API = "https://api.workos.com";
|
|
2129
2069
|
function getWorkosClientId() {
|
|
2130
|
-
return
|
|
2070
|
+
return "";
|
|
2131
2071
|
}
|
|
2132
|
-
/**
|
|
2133
|
-
* Refreshes the access token using the stored refresh token
|
|
2134
|
-
* @returns New auth data with refreshed token
|
|
2135
|
-
* @throws AuthError if refresh fails
|
|
2136
|
-
*/
|
|
2137
2072
|
async function refreshAccessToken() {
|
|
2138
2073
|
const data = loadAuthData();
|
|
2139
2074
|
if (!data?.refreshToken) throw new AuthError("No refresh token available. Please log in again.");
|
|
@@ -2251,8 +2186,6 @@ function getAllAgentConfigs() {
|
|
|
2251
2186
|
//#endregion
|
|
2252
2187
|
//#region src/generate.ts
|
|
2253
2188
|
/**
|
|
2254
|
-
* Simplified AI-only reference generation
|
|
2255
|
-
*
|
|
2256
2189
|
* This module provides a streamlined approach to generating reference files
|
|
2257
2190
|
* by delegating all codebase exploration to the AI agent via OpenCode.
|
|
2258
2191
|
*/
|
|
@@ -2533,7 +2466,47 @@ allowed-tools: Bash(ow:*) Read
|
|
|
2533
2466
|
|
|
2534
2467
|
# Offworld Reference Router
|
|
2535
2468
|
|
|
2536
|
-
|
|
2469
|
+
Use \`ow\` to locate and read Offworld reference files for dependencies.
|
|
2470
|
+
|
|
2471
|
+
## What This Does
|
|
2472
|
+
|
|
2473
|
+
- Finds references for libraries and repos
|
|
2474
|
+
- Returns paths for reference files and local clones
|
|
2475
|
+
- Helps you read the right context fast
|
|
2476
|
+
|
|
2477
|
+
## When to Use
|
|
2478
|
+
|
|
2479
|
+
- You need docs or patterns for a dependency
|
|
2480
|
+
- You want the verified reference instead of web search
|
|
2481
|
+
- You are about to work inside a repo clone
|
|
2482
|
+
|
|
2483
|
+
## Prerequisites
|
|
2484
|
+
|
|
2485
|
+
Check that the CLI is available:
|
|
2486
|
+
|
|
2487
|
+
\`\`\`bash
|
|
2488
|
+
ow --version
|
|
2489
|
+
\`\`\`
|
|
2490
|
+
|
|
2491
|
+
If \`ow\` is not available, install it:
|
|
2492
|
+
|
|
2493
|
+
\`\`\`bash
|
|
2494
|
+
curl -fsSL https://offworld.sh/install | bash
|
|
2495
|
+
\`\`\`
|
|
2496
|
+
|
|
2497
|
+
## Setup
|
|
2498
|
+
|
|
2499
|
+
Initialize Offworld once per machine:
|
|
2500
|
+
|
|
2501
|
+
\`\`\`bash
|
|
2502
|
+
ow init
|
|
2503
|
+
\`\`\`
|
|
2504
|
+
|
|
2505
|
+
For a specific project, build a project map:
|
|
2506
|
+
|
|
2507
|
+
\`\`\`bash
|
|
2508
|
+
ow project init
|
|
2509
|
+
\`\`\`
|
|
2537
2510
|
|
|
2538
2511
|
## Usage
|
|
2539
2512
|
|
|
@@ -2568,22 +2541,15 @@ ow pull <owner/repo> # clone + generate reference
|
|
|
2568
2541
|
ow project init # scan project deps, install references
|
|
2569
2542
|
\`\`\`
|
|
2570
2543
|
|
|
2571
|
-
## All Commands
|
|
2572
|
-
|
|
2573
|
-
| Command | Description |
|
|
2574
|
-
|---------|-------------|
|
|
2575
|
-
| \`ow map search <term>\` | Find repos by name/keyword |
|
|
2576
|
-
| \`ow map show <repo>\` | Show repo info |
|
|
2577
|
-
| \`ow map show <repo> --ref\` | Print reference file path |
|
|
2578
|
-
| \`ow map show <repo> --path\` | Print clone directory path |
|
|
2579
|
-
| \`ow list\` | List all installed repos |
|
|
2580
|
-
| \`ow pull <repo>\` | Clone + generate reference |
|
|
2581
|
-
|
|
2582
2544
|
## Notes
|
|
2583
2545
|
|
|
2584
2546
|
- Project map (\`.offworld/map.json\`) takes precedence over global map when present
|
|
2585
2547
|
- Reference files are markdown with API docs, patterns, best practices
|
|
2586
2548
|
- Clone paths useful for exploring source code after reading reference
|
|
2549
|
+
|
|
2550
|
+
## Additional Resources
|
|
2551
|
+
|
|
2552
|
+
- Docs: https://offworld.sh/cli
|
|
2587
2553
|
`;
|
|
2588
2554
|
/**
|
|
2589
2555
|
* Ensures the global SKILL.md exists and symlinks the offworld/ directory to all agent skill directories.
|
|
@@ -2671,6 +2637,15 @@ function installReference(qualifiedName, fullName, localPath, referenceContent,
|
|
|
2671
2637
|
/**
|
|
2672
2638
|
* Dependency manifest parsing for multiple package ecosystems
|
|
2673
2639
|
*/
|
|
2640
|
+
const DEFAULT_IGNORED_DIRS = new Set([
|
|
2641
|
+
".git",
|
|
2642
|
+
".offworld",
|
|
2643
|
+
".turbo",
|
|
2644
|
+
"build",
|
|
2645
|
+
"dist",
|
|
2646
|
+
"node_modules",
|
|
2647
|
+
"out"
|
|
2648
|
+
]);
|
|
2674
2649
|
/**
|
|
2675
2650
|
* Detects the manifest type in a directory
|
|
2676
2651
|
*/
|
|
@@ -2687,13 +2662,139 @@ function detectManifestType(dir) {
|
|
|
2687
2662
|
*/
|
|
2688
2663
|
function parseDependencies(dir) {
|
|
2689
2664
|
switch (detectManifestType(dir)) {
|
|
2690
|
-
case "npm": return
|
|
2665
|
+
case "npm": return parseNpmDependencies(dir);
|
|
2691
2666
|
case "python": return existsSync(join(dir, "pyproject.toml")) ? parsePyprojectToml(join(dir, "pyproject.toml")) : parseRequirementsTxt(join(dir, "requirements.txt"));
|
|
2692
2667
|
case "rust": return parseCargoToml(join(dir, "Cargo.toml"));
|
|
2693
2668
|
case "go": return parseGoMod(join(dir, "go.mod"));
|
|
2694
2669
|
default: return [];
|
|
2695
2670
|
}
|
|
2696
2671
|
}
|
|
2672
|
+
function parseNpmDependencies(dir) {
|
|
2673
|
+
return mergeDependencies(parsePackageJson(join(dir, "package.json")), parseWorkspaceDependencies(dir)).sort((a, b) => a.name.localeCompare(b.name));
|
|
2674
|
+
}
|
|
2675
|
+
function parseWorkspaceDependencies(dir) {
|
|
2676
|
+
const workspacePatterns = getWorkspacePatterns(dir);
|
|
2677
|
+
if (workspacePatterns.length === 0) return [];
|
|
2678
|
+
const packageJsonPaths = resolveWorkspacePackageJsonPaths(dir, workspacePatterns);
|
|
2679
|
+
const deps = [];
|
|
2680
|
+
for (const path of packageJsonPaths) deps.push(...parsePackageJson(path));
|
|
2681
|
+
return mergeDependencies([], deps);
|
|
2682
|
+
}
|
|
2683
|
+
function getWorkspacePatterns(dir) {
|
|
2684
|
+
const patterns = /* @__PURE__ */ new Set();
|
|
2685
|
+
const packageJsonPath = join(dir, "package.json");
|
|
2686
|
+
if (existsSync(packageJsonPath)) {
|
|
2687
|
+
const workspaces = readJson(packageJsonPath)?.workspaces;
|
|
2688
|
+
if (Array.isArray(workspaces)) {
|
|
2689
|
+
for (const pattern of workspaces) if (typeof pattern === "string") patterns.add(pattern);
|
|
2690
|
+
} else if (workspaces && typeof workspaces === "object") {
|
|
2691
|
+
const packagesField = workspaces.packages;
|
|
2692
|
+
if (Array.isArray(packagesField)) {
|
|
2693
|
+
for (const pattern of packagesField) if (typeof pattern === "string") patterns.add(pattern);
|
|
2694
|
+
}
|
|
2695
|
+
}
|
|
2696
|
+
}
|
|
2697
|
+
const pnpmWorkspacePath = existsSync(join(dir, "pnpm-workspace.yaml")) ? join(dir, "pnpm-workspace.yaml") : existsSync(join(dir, "pnpm-workspace.yml")) ? join(dir, "pnpm-workspace.yml") : null;
|
|
2698
|
+
if (pnpmWorkspacePath) for (const pattern of parsePnpmWorkspacePackages(pnpmWorkspacePath)) patterns.add(pattern);
|
|
2699
|
+
return Array.from(patterns);
|
|
2700
|
+
}
|
|
2701
|
+
function resolveWorkspacePackageJsonPaths(dir, patterns) {
|
|
2702
|
+
const includePatterns = patterns.filter((pattern) => !pattern.startsWith("!"));
|
|
2703
|
+
const excludePatterns = patterns.filter((pattern) => pattern.startsWith("!")).map((pattern) => pattern.slice(1));
|
|
2704
|
+
if (includePatterns.length === 0) return [];
|
|
2705
|
+
const includeRegexes = includePatterns.map(patternToRegex);
|
|
2706
|
+
const excludeRegexes = excludePatterns.map(patternToRegex);
|
|
2707
|
+
const matches = [];
|
|
2708
|
+
const directories = walkDirectories(dir);
|
|
2709
|
+
for (const relativePath of directories) {
|
|
2710
|
+
if (!includeRegexes.some((regex) => regex.test(relativePath))) continue;
|
|
2711
|
+
if (excludeRegexes.some((regex) => regex.test(relativePath))) continue;
|
|
2712
|
+
const packageJsonPath = join(dir, relativePath, "package.json");
|
|
2713
|
+
if (existsSync(packageJsonPath)) matches.push(packageJsonPath);
|
|
2714
|
+
}
|
|
2715
|
+
return Array.from(new Set(matches));
|
|
2716
|
+
}
|
|
2717
|
+
function walkDirectories(root) {
|
|
2718
|
+
const results = [];
|
|
2719
|
+
const stack = [""];
|
|
2720
|
+
while (stack.length > 0) {
|
|
2721
|
+
const relativePath = stack.pop();
|
|
2722
|
+
const currentPath = relativePath ? join(root, relativePath) : root;
|
|
2723
|
+
let entries;
|
|
2724
|
+
try {
|
|
2725
|
+
entries = readdirSync(currentPath, { withFileTypes: true });
|
|
2726
|
+
} catch {
|
|
2727
|
+
continue;
|
|
2728
|
+
}
|
|
2729
|
+
for (const entry of entries) {
|
|
2730
|
+
if (!entry.isDirectory()) continue;
|
|
2731
|
+
if (DEFAULT_IGNORED_DIRS.has(entry.name)) continue;
|
|
2732
|
+
const nextRelative = relativePath ? `${relativePath}/${entry.name}` : entry.name;
|
|
2733
|
+
results.push(nextRelative);
|
|
2734
|
+
stack.push(nextRelative);
|
|
2735
|
+
}
|
|
2736
|
+
}
|
|
2737
|
+
return results;
|
|
2738
|
+
}
|
|
2739
|
+
function patternToRegex(pattern) {
|
|
2740
|
+
let normalized = pattern.trim().replace(/\\/g, "/");
|
|
2741
|
+
if (normalized.startsWith("./")) normalized = normalized.slice(2);
|
|
2742
|
+
if (normalized.endsWith("/")) normalized = normalized.slice(0, -1);
|
|
2743
|
+
const withGlob = normalized.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\\\*\\\*/g, ".*").replace(/\\\*/g, "[^/]+");
|
|
2744
|
+
return new RegExp(`^${withGlob}$`);
|
|
2745
|
+
}
|
|
2746
|
+
function parsePnpmWorkspacePackages(path) {
|
|
2747
|
+
try {
|
|
2748
|
+
const lines = readFileSync(path, "utf-8").split("\n");
|
|
2749
|
+
const patterns = [];
|
|
2750
|
+
let inPackages = false;
|
|
2751
|
+
for (const line of lines) {
|
|
2752
|
+
const trimmed = line.trim();
|
|
2753
|
+
if (!trimmed || trimmed.startsWith("#")) continue;
|
|
2754
|
+
if (/^packages\s*:/.test(trimmed)) {
|
|
2755
|
+
inPackages = true;
|
|
2756
|
+
continue;
|
|
2757
|
+
}
|
|
2758
|
+
if (!inPackages) continue;
|
|
2759
|
+
const entryMatch = trimmed.match(/^-\s*(.+)$/);
|
|
2760
|
+
if (entryMatch?.[1]) {
|
|
2761
|
+
const value = entryMatch[1].trim().replace(/^['"]|['"]$/g, "");
|
|
2762
|
+
if (value) patterns.push(value);
|
|
2763
|
+
continue;
|
|
2764
|
+
}
|
|
2765
|
+
if (!line.startsWith(" ") && !line.startsWith(" ")) break;
|
|
2766
|
+
}
|
|
2767
|
+
return patterns;
|
|
2768
|
+
} catch {
|
|
2769
|
+
return [];
|
|
2770
|
+
}
|
|
2771
|
+
}
|
|
2772
|
+
function readJson(path) {
|
|
2773
|
+
try {
|
|
2774
|
+
const content = readFileSync(path, "utf-8");
|
|
2775
|
+
return JSON.parse(content);
|
|
2776
|
+
} catch {
|
|
2777
|
+
return null;
|
|
2778
|
+
}
|
|
2779
|
+
}
|
|
2780
|
+
function mergeDependencies(base, incoming) {
|
|
2781
|
+
const map = /* @__PURE__ */ new Map();
|
|
2782
|
+
for (const dep of [...base, ...incoming]) {
|
|
2783
|
+
const existing = map.get(dep.name);
|
|
2784
|
+
if (!existing) {
|
|
2785
|
+
map.set(dep.name, { ...dep });
|
|
2786
|
+
continue;
|
|
2787
|
+
}
|
|
2788
|
+
const dev = existing.dev && dep.dev;
|
|
2789
|
+
const version = existing.version ?? dep.version;
|
|
2790
|
+
map.set(dep.name, {
|
|
2791
|
+
name: dep.name,
|
|
2792
|
+
version,
|
|
2793
|
+
dev
|
|
2794
|
+
});
|
|
2795
|
+
}
|
|
2796
|
+
return Array.from(map.values());
|
|
2797
|
+
}
|
|
2697
2798
|
/**
|
|
2698
2799
|
* Parse package.json dependencies
|
|
2699
2800
|
*/
|
|
@@ -2712,6 +2813,16 @@ function parsePackageJson(path) {
|
|
|
2712
2813
|
version,
|
|
2713
2814
|
dev: true
|
|
2714
2815
|
});
|
|
2816
|
+
if (pkg.peerDependencies && typeof pkg.peerDependencies === "object") for (const [name, version] of Object.entries(pkg.peerDependencies)) deps.push({
|
|
2817
|
+
name,
|
|
2818
|
+
version,
|
|
2819
|
+
dev: false
|
|
2820
|
+
});
|
|
2821
|
+
if (pkg.optionalDependencies && typeof pkg.optionalDependencies === "object") for (const [name, version] of Object.entries(pkg.optionalDependencies)) deps.push({
|
|
2822
|
+
name,
|
|
2823
|
+
version,
|
|
2824
|
+
dev: false
|
|
2825
|
+
});
|
|
2715
2826
|
return deps;
|
|
2716
2827
|
} catch {
|
|
2717
2828
|
return [];
|