@offworld/sdk 0.3.5 → 0.3.7

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/dist/index.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- import { $ as installGlobalSkill, $t as getMetaPath, A as pruneRepos, At as removeRepo, B as getNpmKeywords, Bt as readGlobalMap, C as RepoStatusOptions, Ct as UpdateResult, D as discoverRepos, Dt as getCommitSha, E as UpdateAllResult, Et as getCommitDistance, F as matchDependenciesToReferences, Ft as SearchResult, G as detectManifestType, Gt as NotGitRepoError, H as resolveFromNpm, Ht as upsertGlobalMapEntry, I as matchDependenciesToReferencesWithRemoteCheck, It as getMapEntry, J as agents, Jt as getReferenceFileNameForSource, K as parseDependencies, Kt as PathNotFoundError, L as FALLBACK_MAPPINGS, Lt as getProjectMapPath, M as ReferenceMatch, Mt as GetMapEntryOptions, N as ReferenceStatus, Nt as MapEntry, O as gcRepos, Ot as isRepoCloned, P as isReferenceInstalled, Pt as SearchMapOptions, Q as InstallReferenceMeta, Qt as getConfigPath, R as ResolveDependencyRepoOptions, Rt as resolveRepoKey, S as PruneResult, St as UpdateOptions, T as UpdateAllOptions, Tt as getClonedRepoPath, U as Dependency, Ut as writeGlobalMap, V as resolveDependencyRepo, Vt as removeGlobalMapEntry, W as ManifestType, Wt as writeProjectMap, X as getAgentConfig, Xt as Paths, Y as detectInstalledAgents, Yt as parseRepoInput, Z as getAllAgentConfigs, Zt as expandTilde, _ as DiscoverOptions, _t as CloneOptions, a as GlobalMap, an as saveConfig, at as NotLoggedInError, b as GcResult, bt as RepoExistsError, c as ProjectMapRepoEntry, cn as toReferenceName, ct as getAuthPath, d as ProviderInfo, dt as getTokenOrNull, en as getMetaRoot, et as installReference, f as ProviderWithModels, ft as isLoggedIn, g as validateProviderModel, gt as CloneError, h as listProvidersWithModels, ht as saveAuthData, i as FileRole, in as loadConfig, it as AuthStatus, j as updateAllRepos, jt as updateRepo, k as getRepoStatus, kt as listRepos, l as RepoSource, ln as DEFAULT_IGNORE_PATTERNS, lt as getAuthStatus, m as listProviders, mt as refreshAccessToken, n as FileIndex, nn as getRepoPath, nt as AuthData, o as GlobalMapRepoEntry, on as toMetaDirName, ot as TokenExpiredError, p as getProvider, pt as loadAuthData, q as AgentConfig, qt as RepoSourceError, r as FileIndexEntry, rn as getRepoRoot, rt as AuthError, s as ProjectMap, sn as toReferenceFileName, st as clearAuthData, t as Config, tn as getReferencePath, tt as resolveReferenceKeywords, u as ModelInfo, un as VERSION, ut as getToken, v as DiscoverResult, vt as GitError, w as RepoStatusSummary, wt as cloneRepo, x as PruneOptions, xt as RepoNotFoundError, y as GcOptions, yt as RemoveOptions, z as ResolvedDep, zt as searchMap } from "./public-DZZG1NQL.mjs";
1
+ import { $ as installGlobalSkill, $t as getMetaPath, A as pruneRepos, At as removeRepo, B as getNpmKeywords, Bt as readGlobalMap, C as RepoStatusOptions, Ct as UpdateResult, D as discoverRepos, Dt as getCommitSha, E as UpdateAllResult, Et as getCommitDistance, F as matchDependenciesToReferences, Ft as SearchResult, G as detectManifestType, Gt as NotGitRepoError, H as resolveFromNpm, Ht as upsertGlobalMapEntry, I as matchDependenciesToReferencesWithRemoteCheck, It as getMapEntry, J as agents, Jt as getReferenceFileNameForSource, K as parseDependencies, Kt as PathNotFoundError, L as FALLBACK_MAPPINGS, Lt as getProjectMapPath, M as ReferenceMatch, Mt as GetMapEntryOptions, N as ReferenceStatus, Nt as MapEntry, O as gcRepos, Ot as isRepoCloned, P as isReferenceInstalled, Pt as SearchMapOptions, Q as InstallReferenceMeta, Qt as getConfigPath, R as ResolveDependencyRepoOptions, Rt as resolveRepoKey, S as PruneResult, St as UpdateOptions, T as UpdateAllOptions, Tt as getClonedRepoPath, U as Dependency, Ut as writeGlobalMap, V as resolveDependencyRepo, Vt as removeGlobalMapEntry, W as ManifestType, Wt as writeProjectMap, X as getAgentConfig, Xt as Paths, Y as detectInstalledAgents, Yt as parseRepoInput, Z as getAllAgentConfigs, Zt as expandTilde, _ as DiscoverOptions, _t as CloneOptions, a as GlobalMap, an as saveConfig, at as NotLoggedInError, b as GcResult, bt as RepoExistsError, c as ProjectMapRepoEntry, cn as toReferenceName, ct as getAuthPath, d as ProviderInfo, dt as getTokenOrNull, en as getMetaRoot, et as installReference, f as ProviderWithModels, ft as isLoggedIn, g as validateProviderModel, gt as CloneError, h as listProvidersWithModels, ht as saveAuthData, i as FileRole, in as loadConfig, it as AuthStatus, j as updateAllRepos, jt as updateRepo, k as getRepoStatus, kt as listRepos, l as RepoSource, ln as DEFAULT_IGNORE_PATTERNS, lt as getAuthStatus, m as listProviders, mt as refreshAccessToken, n as FileIndex, nn as getRepoPath, nt as AuthData, o as GlobalMapRepoEntry, on as toMetaDirName, ot as TokenExpiredError, p as getProvider, pt as loadAuthData, q as AgentConfig, qt as RepoSourceError, r as FileIndexEntry, rn as getRepoRoot, rt as AuthError, s as ProjectMap, sn as toReferenceFileName, st as clearAuthData, t as Config, tn as getReferencePath, tt as resolveReferenceKeywords, u as ModelInfo, un as VERSION, ut as getToken, v as DiscoverResult, vt as GitError, w as RepoStatusSummary, wt as cloneRepo, x as PruneOptions, xt as RepoNotFoundError, y as GcOptions, yt as RemoveOptions, z as ResolvedDep, zt as searchMap } from "./public-DkkNYpNL.mjs";
2
2
  export { AgentConfig, AuthData, AuthError, AuthStatus, CloneError, CloneOptions, Config, DEFAULT_IGNORE_PATTERNS, Dependency, DiscoverOptions, DiscoverResult, FALLBACK_MAPPINGS, FileIndex, FileIndexEntry, FileRole, GcOptions, GcResult, GetMapEntryOptions, GitError, GlobalMap, GlobalMapRepoEntry, InstallReferenceMeta, ManifestType, MapEntry, ModelInfo, NotGitRepoError, NotLoggedInError, PathNotFoundError, Paths, ProjectMap, ProjectMapRepoEntry, ProviderInfo, ProviderWithModels, PruneOptions, PruneResult, ReferenceMatch, ReferenceStatus, RemoveOptions, RepoExistsError, RepoNotFoundError, RepoSource, RepoSourceError, RepoStatusOptions, RepoStatusSummary, ResolveDependencyRepoOptions, ResolvedDep, SearchMapOptions, SearchResult, TokenExpiredError, UpdateAllOptions, UpdateAllResult, UpdateOptions, UpdateResult, VERSION, agents, clearAuthData, cloneRepo, detectInstalledAgents, detectManifestType, discoverRepos, expandTilde, gcRepos, getAgentConfig, getAllAgentConfigs, getAuthPath, getAuthStatus, getClonedRepoPath, getCommitDistance, getCommitSha, getConfigPath, getMapEntry, getMetaPath, getMetaRoot, getNpmKeywords, getProjectMapPath, getProvider, getReferenceFileNameForSource, getReferencePath, getRepoPath, getRepoRoot, getRepoStatus, getToken, getTokenOrNull, installGlobalSkill, installReference, isLoggedIn, isReferenceInstalled, isRepoCloned, listProviders, listProvidersWithModels, listRepos, loadAuthData, loadConfig, matchDependenciesToReferences, matchDependenciesToReferencesWithRemoteCheck, parseDependencies, parseRepoInput, pruneRepos, readGlobalMap, refreshAccessToken, removeGlobalMapEntry, removeRepo, resolveDependencyRepo, resolveFromNpm, resolveReferenceKeywords, resolveRepoKey, saveAuthData, saveConfig, searchMap, toMetaDirName, toReferenceFileName, toReferenceName, updateAllRepos, updateRepo, upsertGlobalMapEntry, validateProviderModel, writeGlobalMap, writeProjectMap };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { A as getAuthPath, B as resolveRepoKey, C as detectInstalledAgents, D as NotLoggedInError, E as AuthError, F as loadAuthData, G as getReferenceFileNameForSource, H as NotGitRepoError, I as refreshAccessToken, J as VERSION, K as parseRepoInput, L as saveAuthData, M as getToken, N as getTokenOrNull, O as TokenExpiredError, P as isLoggedIn, R as getMapEntry, S as agents, T as getAllAgentConfigs, U as PathNotFoundError, V as searchMap, W as RepoSourceError, _ as resolveReferenceKeywords, a as discoverRepos, b as resolveDependencyRepo, c as pruneRepos, d as matchDependenciesToReferences, f as matchDependenciesToReferencesWithRemoteCheck, g as installReference, h as installGlobalSkill, i as validateProviderModel, j as getAuthStatus, k as clearAuthData, l as updateAllRepos, m as parseDependencies, n as listProviders, o as gcRepos, p as detectManifestType, q as DEFAULT_IGNORE_PATTERNS, r as listProvidersWithModels, s as getRepoStatus, t as getProvider, u as isReferenceInstalled, v as FALLBACK_MAPPINGS, w as getAgentConfig, x as resolveFromNpm, y as getNpmKeywords, z as getProjectMapPath } from "./public-CWnhJJ9J.mjs";
1
+ import { A as getAuthPath, B as resolveRepoKey, C as detectInstalledAgents, D as NotLoggedInError, E as AuthError, F as loadAuthData, G as getReferenceFileNameForSource, H as NotGitRepoError, I as refreshAccessToken, J as VERSION, K as parseRepoInput, L as saveAuthData, M as getToken, N as getTokenOrNull, O as TokenExpiredError, P as isLoggedIn, R as getMapEntry, S as agents, T as getAllAgentConfigs, U as PathNotFoundError, V as searchMap, W as RepoSourceError, _ as resolveReferenceKeywords, a as discoverRepos, b as resolveDependencyRepo, c as pruneRepos, d as matchDependenciesToReferences, f as matchDependenciesToReferencesWithRemoteCheck, g as installReference, h as installGlobalSkill, i as validateProviderModel, j as getAuthStatus, k as clearAuthData, l as updateAllRepos, m as parseDependencies, n as listProviders, o as gcRepos, p as detectManifestType, q as DEFAULT_IGNORE_PATTERNS, r as listProvidersWithModels, s as getRepoStatus, t as getProvider, u as isReferenceInstalled, v as FALLBACK_MAPPINGS, w as getAgentConfig, x as resolveFromNpm, y as getNpmKeywords, z as getProjectMapPath } from "./public-T9TZSuKw.mjs";
2
2
  import { a as getRepoPath, c as saveConfig, d as toReferenceName, f as Paths, i as getReferencePath, l as toMetaDirName, n as getMetaPath, o as getRepoRoot, p as expandTilde, r as getMetaRoot, s as loadConfig, t as getConfigPath, u as toReferenceFileName } from "./config-DW8J4gl5.mjs";
3
3
  import { _ as writeProjectMap, a as cloneRepo, c as getCommitSha, d as removeRepo, f as updateRepo, g as writeGlobalMap, h as upsertGlobalMapEntry, i as RepoNotFoundError, l as isRepoCloned, m as removeGlobalMapEntry, n as GitError, o as getClonedRepoPath, p as readGlobalMap, r as RepoExistsError, s as getCommitDistance, t as CloneError, u as listRepos } from "./clone-Z5ELU2fW.mjs";
4
4
 
@@ -1,4 +1,4 @@
1
- import { $ as installGlobalSkill, $t as getMetaPath, A as pruneRepos, At as removeRepo, B as getNpmKeywords, Bt as readGlobalMap, C as RepoStatusOptions, Ct as UpdateResult, D as discoverRepos, Dt as getCommitSha, E as UpdateAllResult, Et as getCommitDistance, F as matchDependenciesToReferences, Ft as SearchResult, G as detectManifestType, Gt as NotGitRepoError, H as resolveFromNpm, Ht as upsertGlobalMapEntry, I as matchDependenciesToReferencesWithRemoteCheck, It as getMapEntry, J as agents, Jt as getReferenceFileNameForSource, K as parseDependencies, Kt as PathNotFoundError, L as FALLBACK_MAPPINGS, Lt as getProjectMapPath, M as ReferenceMatch, Mt as GetMapEntryOptions, N as ReferenceStatus, Nt as MapEntry, O as gcRepos, Ot as isRepoCloned, P as isReferenceInstalled, Pt as SearchMapOptions, Q as InstallReferenceMeta, Qt as getConfigPath, R as ResolveDependencyRepoOptions, Rt as resolveRepoKey, S as PruneResult, St as UpdateOptions, T as UpdateAllOptions, Tt as getClonedRepoPath, U as Dependency, Ut as writeGlobalMap, V as resolveDependencyRepo, Vt as removeGlobalMapEntry, W as ManifestType, Wt as writeProjectMap, X as getAgentConfig, Xt as Paths, Y as detectInstalledAgents, Yt as parseRepoInput, Z as getAllAgentConfigs, Zt as expandTilde, _ as DiscoverOptions, _t as CloneOptions, a as GlobalMap, an as saveConfig, at as NotLoggedInError, b as GcResult, bt as RepoExistsError, c as ProjectMapRepoEntry, cn as toReferenceName, ct as getAuthPath, d as ProviderInfo, dt as getTokenOrNull, en as getMetaRoot, et as installReference, f as ProviderWithModels, ft as isLoggedIn, g as validateProviderModel, gt as CloneError, h as listProvidersWithModels, ht as saveAuthData, i as FileRole, in as loadConfig, it as AuthStatus, j as updateAllRepos, jt as updateRepo, k as getRepoStatus, kt as listRepos, l as RepoSource, ln as DEFAULT_IGNORE_PATTERNS, lt as getAuthStatus, m as listProviders, mt as refreshAccessToken, n as FileIndex, nn as getRepoPath, nt as AuthData, o as GlobalMapRepoEntry, on as toMetaDirName, ot as TokenExpiredError, p as getProvider, pt as loadAuthData, q as AgentConfig, qt as RepoSourceError, r as FileIndexEntry, rn as getRepoRoot, rt as AuthError, s as ProjectMap, sn as toReferenceFileName, st as clearAuthData, t as Config, tn as getReferencePath, tt as resolveReferenceKeywords, u as ModelInfo, un as VERSION, ut as getToken, v as DiscoverResult, vt as GitError, w as RepoStatusSummary, wt as cloneRepo, x as PruneOptions, xt as RepoNotFoundError, y as GcOptions, yt as RemoveOptions, z as ResolvedDep, zt as searchMap } from "./public-DZZG1NQL.mjs";
1
+ import { $ as installGlobalSkill, $t as getMetaPath, A as pruneRepos, At as removeRepo, B as getNpmKeywords, Bt as readGlobalMap, C as RepoStatusOptions, Ct as UpdateResult, D as discoverRepos, Dt as getCommitSha, E as UpdateAllResult, Et as getCommitDistance, F as matchDependenciesToReferences, Ft as SearchResult, G as detectManifestType, Gt as NotGitRepoError, H as resolveFromNpm, Ht as upsertGlobalMapEntry, I as matchDependenciesToReferencesWithRemoteCheck, It as getMapEntry, J as agents, Jt as getReferenceFileNameForSource, K as parseDependencies, Kt as PathNotFoundError, L as FALLBACK_MAPPINGS, Lt as getProjectMapPath, M as ReferenceMatch, Mt as GetMapEntryOptions, N as ReferenceStatus, Nt as MapEntry, O as gcRepos, Ot as isRepoCloned, P as isReferenceInstalled, Pt as SearchMapOptions, Q as InstallReferenceMeta, Qt as getConfigPath, R as ResolveDependencyRepoOptions, Rt as resolveRepoKey, S as PruneResult, St as UpdateOptions, T as UpdateAllOptions, Tt as getClonedRepoPath, U as Dependency, Ut as writeGlobalMap, V as resolveDependencyRepo, Vt as removeGlobalMapEntry, W as ManifestType, Wt as writeProjectMap, X as getAgentConfig, Xt as Paths, Y as detectInstalledAgents, Yt as parseRepoInput, Z as getAllAgentConfigs, Zt as expandTilde, _ as DiscoverOptions, _t as CloneOptions, a as GlobalMap, an as saveConfig, at as NotLoggedInError, b as GcResult, bt as RepoExistsError, c as ProjectMapRepoEntry, cn as toReferenceName, ct as getAuthPath, d as ProviderInfo, dt as getTokenOrNull, en as getMetaRoot, et as installReference, f as ProviderWithModels, ft as isLoggedIn, g as validateProviderModel, gt as CloneError, h as listProvidersWithModels, ht as saveAuthData, i as FileRole, in as loadConfig, it as AuthStatus, j as updateAllRepos, jt as updateRepo, k as getRepoStatus, kt as listRepos, l as RepoSource, ln as DEFAULT_IGNORE_PATTERNS, lt as getAuthStatus, m as listProviders, mt as refreshAccessToken, n as FileIndex, nn as getRepoPath, nt as AuthData, o as GlobalMapRepoEntry, on as toMetaDirName, ot as TokenExpiredError, p as getProvider, pt as loadAuthData, q as AgentConfig, qt as RepoSourceError, r as FileIndexEntry, rn as getRepoRoot, rt as AuthError, s as ProjectMap, sn as toReferenceFileName, st as clearAuthData, t as Config, tn as getReferencePath, tt as resolveReferenceKeywords, u as ModelInfo, un as VERSION, ut as getToken, v as DiscoverResult, vt as GitError, w as RepoStatusSummary, wt as cloneRepo, x as PruneOptions, xt as RepoNotFoundError, y as GcOptions, yt as RemoveOptions, z as ResolvedDep, zt as searchMap } from "./public-DkkNYpNL.mjs";
2
2
 
3
3
  //#region src/agents-md.d.ts
4
4
  /**
@@ -23,8 +23,7 @@ interface InstalledReference {
23
23
  */
24
24
  declare function appendReferencesSection(filePath: string, references: InstalledReference[]): void;
25
25
  /**
26
- * Update AGENTS.md and agent-specific files with project references.
27
- * Creates files if they don't exist.
26
+ * Update AGENTS.md with project references if the section is missing.
28
27
  *
29
28
  * @param projectRoot - Project root directory
30
29
  * @param references - Array of installed references to document
@@ -1 +1 @@
1
- {"version":3,"file":"internal.d.mts","names":[],"sources":["../src/agents-md.ts","../src/installation.ts"],"mappings":";;;;;;AASA;;UAAiB,kBAAA;EAAkB;EAElC,UAAA;EAEA;EAAA,SAAA;EAEI;EAAJ,IAAA;AAAA;;;;;;;;iBA2Be,uBAAA,CAAwB,QAAA,UAAkB,UAAA,EAAY,kBAAA;AAwBtE;;;;;;;AAAA,iBAAgB,gBAAA,CAAiB,WAAA,UAAqB,UAAA,EAAY,kBAAA;;;;;;KCpDtD,aAAA;;;;iBAKI,mBAAA,CAAA,GAAuB,aAAA;;;;iBAuFvB,iBAAA,CAAA;ADhEhB;;;AAAA,iBCuEsB,kBAAA,CAAmB,MAAA,GAAS,aAAA,GAAgB,OAAA;;;;iBAkClD,cAAA,CAAe,MAAA,EAAQ,aAAA,EAAe,OAAA,WAAkB,OAAA;;ADjFxE;;iBC4HgB,gBAAA,CAAiB,MAAA,EAAQ,aAAA,GAAgB,OAAA;;;;iBAkDzC,mBAAA,CAAA;;;;iBA0BA,gBAAA,CAAiB,QAAA"}
1
+ {"version":3,"file":"internal.d.mts","names":[],"sources":["../src/agents-md.ts","../src/installation.ts"],"mappings":";;;;;;AAWA;;UAAiB,kBAAA;EAAkB;EAElC,UAAA;EAEA;EAAA,SAAA;EAEI;EAAJ,IAAA;AAAA;;;;;;;;iBA2Be,uBAAA,CAAwB,QAAA,UAAkB,UAAA,EAAY,kBAAA;AAsBtE;;;;;;AAAA,iBAAgB,gBAAA,CAAiB,WAAA,UAAqB,UAAA,EAAY,kBAAA;;;;;;KCpDtD,aAAA;;;;iBAKI,mBAAA,CAAA,GAAuB,aAAA;;;;iBAuFvB,iBAAA,CAAA;AD9DhB;;;AAAA,iBCqEsB,kBAAA,CAAmB,MAAA,GAAS,aAAA,GAAgB,OAAA;;;;iBAkClD,cAAA,CAAe,MAAA,EAAQ,aAAA,EAAe,OAAA,WAAkB,OAAA;;ADjFxE;;iBC4HgB,gBAAA,CAAiB,MAAA,EAAQ,aAAA,GAAgB,OAAA;;;;iBAkDzC,mBAAA,CAAA;;;;iBA0BA,gBAAA,CAAiB,QAAA"}
package/dist/internal.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { A as getAuthPath, B as resolveRepoKey, C as detectInstalledAgents, D as NotLoggedInError, E as AuthError, F as loadAuthData, G as getReferenceFileNameForSource, H as NotGitRepoError, I as refreshAccessToken, J as VERSION, K as parseRepoInput, L as saveAuthData, M as getToken, N as getTokenOrNull, O as TokenExpiredError, P as isLoggedIn, R as getMapEntry, S as agents, T as getAllAgentConfigs, U as PathNotFoundError, V as searchMap, W as RepoSourceError, _ as resolveReferenceKeywords, a as discoverRepos, b as resolveDependencyRepo, c as pruneRepos, d as matchDependenciesToReferences, f as matchDependenciesToReferencesWithRemoteCheck, g as installReference, h as installGlobalSkill, i as validateProviderModel, j as getAuthStatus, k as clearAuthData, l as updateAllRepos, m as parseDependencies, n as listProviders, o as gcRepos, p as detectManifestType, q as DEFAULT_IGNORE_PATTERNS, r as listProvidersWithModels, s as getRepoStatus, t as getProvider, u as isReferenceInstalled, v as FALLBACK_MAPPINGS, w as getAgentConfig, x as resolveFromNpm, y as getNpmKeywords, z as getProjectMapPath } from "./public-CWnhJJ9J.mjs";
1
+ import { A as getAuthPath, B as resolveRepoKey, C as detectInstalledAgents, D as NotLoggedInError, E as AuthError, F as loadAuthData, G as getReferenceFileNameForSource, H as NotGitRepoError, I as refreshAccessToken, J as VERSION, K as parseRepoInput, L as saveAuthData, M as getToken, N as getTokenOrNull, O as TokenExpiredError, P as isLoggedIn, R as getMapEntry, S as agents, T as getAllAgentConfigs, U as PathNotFoundError, V as searchMap, W as RepoSourceError, _ as resolveReferenceKeywords, a as discoverRepos, b as resolveDependencyRepo, c as pruneRepos, d as matchDependenciesToReferences, f as matchDependenciesToReferencesWithRemoteCheck, g as installReference, h as installGlobalSkill, i as validateProviderModel, j as getAuthStatus, k as clearAuthData, l as updateAllRepos, m as parseDependencies, n as listProviders, o as gcRepos, p as detectManifestType, q as DEFAULT_IGNORE_PATTERNS, r as listProvidersWithModels, s as getRepoStatus, t as getProvider, u as isReferenceInstalled, v as FALLBACK_MAPPINGS, w as getAgentConfig, x as resolveFromNpm, y as getNpmKeywords, z as getProjectMapPath } from "./public-T9TZSuKw.mjs";
2
2
  import { a as getRepoPath, c as saveConfig, d as toReferenceName, f as Paths, i as getReferencePath, l as toMetaDirName, n as getMetaPath, o as getRepoRoot, p as expandTilde, r as getMetaRoot, s as loadConfig, t as getConfigPath, u as toReferenceFileName } from "./config-DW8J4gl5.mjs";
3
3
  import { _ as writeProjectMap, a as cloneRepo, c as getCommitSha, d as removeRepo, f as updateRepo, g as writeGlobalMap, h as upsertGlobalMapEntry, i as RepoNotFoundError, l as isRepoCloned, m as removeGlobalMapEntry, n as GitError, o as getClonedRepoPath, p as readGlobalMap, r as RepoExistsError, s as getCommitDistance, t as CloneError, u as listRepos } from "./clone-Z5ELU2fW.mjs";
4
4
  import { existsSync, readFileSync, writeFileSync } from "node:fs";
@@ -13,6 +13,7 @@ import { execSync, spawn } from "node:child_process";
13
13
  *
14
14
  * Manages updating project AGENTS.md and agent-specific files with reference information.
15
15
  */
16
+ const referencesSectionRegex = /^## Project References\n(?:.*\n)*?(?=^## |$)/m;
16
17
  /**
17
18
  * Generate single-line project reference guidance.
18
19
  *
@@ -37,25 +38,29 @@ function generateReferencesTable(_references) {
37
38
  function appendReferencesSection(filePath, references) {
38
39
  const content = existsSync(filePath) ? readFileSync(filePath, "utf-8") : "";
39
40
  const referencesMarkdown = generateReferencesTable(references);
40
- const sectionRegex = /^## Project References\n(?:.*\n)*?(?=^## |$)/m;
41
- const match = content.match(sectionRegex);
41
+ const match = content.match(referencesSectionRegex);
42
42
  let updatedContent;
43
- if (match) updatedContent = content.replace(sectionRegex, referencesMarkdown);
43
+ if (match) updatedContent = content.replace(referencesSectionRegex, referencesMarkdown);
44
44
  else updatedContent = content.trim() + "\n\n" + referencesMarkdown;
45
45
  writeFileSync(filePath, updatedContent, "utf-8");
46
46
  }
47
47
  /**
48
- * Update AGENTS.md and agent-specific files with project references.
49
- * Creates files if they don't exist.
48
+ * Update AGENTS.md with project references if the section is missing.
50
49
  *
51
50
  * @param projectRoot - Project root directory
52
51
  * @param references - Array of installed references to document
53
52
  */
54
53
  function updateAgentFiles(projectRoot, references) {
55
54
  const agentsMdPath = join(projectRoot, "AGENTS.md");
56
- const claudeMdPath = join(projectRoot, "CLAUDE.md");
57
- appendReferencesSection(agentsMdPath, references);
58
- if (existsSync(claudeMdPath)) appendReferencesSection(claudeMdPath, references);
55
+ const referencesMarkdown = generateReferencesTable(references);
56
+ if (!existsSync(agentsMdPath)) {
57
+ writeFileSync(agentsMdPath, referencesMarkdown, "utf-8");
58
+ return;
59
+ }
60
+ const content = readFileSync(agentsMdPath, "utf-8");
61
+ if (referencesSectionRegex.test(content)) return;
62
+ const separator = content.endsWith("\n\n") ? "" : content.endsWith("\n") ? "\n" : "\n\n";
63
+ writeFileSync(agentsMdPath, content.trim().length === 0 ? referencesMarkdown : `${content}${separator}${referencesMarkdown}`, "utf-8");
59
64
  }
60
65
 
61
66
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"internal.mjs","names":[],"sources":["../src/agents-md.ts","../src/installation.ts"],"sourcesContent":["/**\n * AGENTS.md manipulation utilities\n *\n * Manages updating project AGENTS.md and agent-specific files with reference information.\n */\n\nimport { readFileSync, writeFileSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nexport interface InstalledReference {\n\t/** Dependency name */\n\tdependency: string;\n\t/** Reference identifier (matches reference file name without .md) */\n\treference: string;\n\t/** Absolute path to reference file */\n\tpath: string;\n}\n\n/**\n * Generate single-line project reference guidance.\n *\n * @param _references - Installed references (unused; reserved for future context)\n * @returns Markdown string with one-line guidance\n */\nfunction generateReferencesTable(_references: InstalledReference[]): string {\n\tconst lines = [\n\t\t\"## Project References\",\n\t\t\"\",\n\t\t\"Use the Offworld CLI to find and read directly from local codebases for any repo in `.offworld/map.json` whenever the user asks about a specific open source project.\",\n\t\t\"\",\n\t];\n\n\treturn lines.join(\"\\n\");\n}\n\n/**\n * Update or append Project References section in a markdown file.\n * If the section exists, replaces its content. Otherwise, appends to end.\n *\n * @param filePath - Path to markdown file\n * @param references - Array of installed references\n */\nexport function appendReferencesSection(filePath: string, references: InstalledReference[]): void {\n\tconst content = existsSync(filePath) ? readFileSync(filePath, \"utf-8\") : \"\";\n\tconst referencesMarkdown = generateReferencesTable(references);\n\n\tconst sectionRegex = /^## Project References\\n(?:.*\\n)*?(?=^## |$)/m;\n\tconst match = content.match(sectionRegex);\n\n\tlet updatedContent: string;\n\tif (match) {\n\t\tupdatedContent = content.replace(sectionRegex, referencesMarkdown);\n\t} else {\n\t\tupdatedContent = content.trim() + \"\\n\\n\" + referencesMarkdown;\n\t}\n\n\twriteFileSync(filePath, updatedContent, \"utf-8\");\n}\n\n/**\n * Update AGENTS.md and agent-specific files with project references.\n * Creates files if they don't exist.\n *\n * @param projectRoot - Project root directory\n * @param references - Array of installed references to document\n */\nexport function updateAgentFiles(projectRoot: string, references: InstalledReference[]): void {\n\tconst agentsMdPath = join(projectRoot, \"AGENTS.md\");\n\tconst claudeMdPath = join(projectRoot, \"CLAUDE.md\");\n\n\tappendReferencesSection(agentsMdPath, references);\n\n\tif (existsSync(claudeMdPath)) {\n\t\tappendReferencesSection(claudeMdPath, references);\n\t}\n}\n","/**\n * Installation utilities for upgrade/uninstall commands\n */\n\nimport { execSync, spawn } from \"node:child_process\";\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { NpmPackageResponseSchema } from \"@offworld/types\";\nimport { VERSION } from \"./constants.js\";\n\nconst GITHUB_REPO = \"oscabriel/offworld\";\nconst NPM_PACKAGE = \"offworld\";\n\nexport type InstallMethod = \"curl\" | \"npm\" | \"pnpm\" | \"bun\" | \"brew\" | \"unknown\";\n\n/**\n * Detect how offworld was installed\n */\nexport function detectInstallMethod(): InstallMethod {\n\tconst execPath = process.execPath;\n\n\tif (execPath.includes(\".local/bin\")) return \"curl\";\n\n\tconst checks: Array<{ name: InstallMethod; test: () => boolean }> = [\n\t\t{\n\t\t\tname: \"npm\",\n\t\t\ttest: () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = execSync(\"npm list -g --depth=0 2>/dev/null\", {\n\t\t\t\t\t\tencoding: \"utf-8\",\n\t\t\t\t\t});\n\t\t\t\t\treturn result.includes(NPM_PACKAGE);\n\t\t\t\t} catch {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"pnpm\",\n\t\t\ttest: () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = execSync(\"pnpm list -g --depth=0 2>/dev/null\", {\n\t\t\t\t\t\tencoding: \"utf-8\",\n\t\t\t\t\t});\n\t\t\t\t\treturn result.includes(NPM_PACKAGE);\n\t\t\t\t} catch {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"bun\",\n\t\t\ttest: () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = execSync(\"bun pm ls -g 2>/dev/null\", {\n\t\t\t\t\t\tencoding: \"utf-8\",\n\t\t\t\t\t});\n\t\t\t\t\treturn result.includes(NPM_PACKAGE);\n\t\t\t\t} catch {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"brew\",\n\t\t\ttest: () => {\n\t\t\t\ttry {\n\t\t\t\t\texecSync(\"brew list --formula offworld 2>/dev/null\", {\n\t\t\t\t\t\tencoding: \"utf-8\",\n\t\t\t\t\t});\n\t\t\t\t\treturn true;\n\t\t\t\t} catch {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t];\n\n\tif (execPath.includes(\"npm\")) {\n\t\tconst check = checks.find((c) => c.name === \"npm\");\n\t\tif (check?.test()) return \"npm\";\n\t}\n\tif (execPath.includes(\"pnpm\")) {\n\t\tconst check = checks.find((c) => c.name === \"pnpm\");\n\t\tif (check?.test()) return \"pnpm\";\n\t}\n\tif (execPath.includes(\"bun\")) {\n\t\tconst check = checks.find((c) => c.name === \"bun\");\n\t\tif (check?.test()) return \"bun\";\n\t}\n\tif (execPath.includes(\"Cellar\") || execPath.includes(\"homebrew\")) {\n\t\tconst check = checks.find((c) => c.name === \"brew\");\n\t\tif (check?.test()) return \"brew\";\n\t}\n\n\tfor (const check of checks) {\n\t\tif (check.test()) return check.name;\n\t}\n\n\treturn \"unknown\";\n}\n\n/**\n * Get current installed version\n */\nexport function getCurrentVersion(): string {\n\treturn VERSION;\n}\n\n/**\n * Fetch latest version from appropriate source\n */\nexport async function fetchLatestVersion(method?: InstallMethod): Promise<string | null> {\n\tconst installMethod = method ?? detectInstallMethod();\n\n\ttry {\n\t\tif (installMethod === \"npm\" || installMethod === \"pnpm\" || installMethod === \"bun\") {\n\t\t\tconst response = await fetch(`https://registry.npmjs.org/${NPM_PACKAGE}/latest`);\n\t\t\tif (!response.ok) return null;\n\t\t\tconst json = await response.json();\n\t\t\tconst result = NpmPackageResponseSchema.safeParse(json);\n\t\t\tif (!result.success) return null;\n\t\t\treturn result.data.version ?? null;\n\t\t}\n\n\t\tconst response = await fetch(`https://api.github.com/repos/${GITHUB_REPO}/releases/latest`, {\n\t\t\theaders: {\n\t\t\t\tAccept: \"application/vnd.github.v3+json\",\n\t\t\t\t\"User-Agent\": \"offworld-cli\",\n\t\t\t},\n\t\t});\n\t\tif (!response.ok) return null;\n\t\tconst json = await response.json();\n\t\tconst tagName =\n\t\t\ttypeof json === \"object\" && json !== null && \"tag_name\" in json\n\t\t\t\t? String(json.tag_name)\n\t\t\t\t: null;\n\t\treturn tagName?.replace(/^v/, \"\") ?? null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Execute upgrade for given method\n */\nexport function executeUpgrade(method: InstallMethod, version: string): Promise<void> {\n\treturn new Promise((resolve, reject) => {\n\t\tlet cmd: string;\n\t\tlet args: string[];\n\n\t\tswitch (method) {\n\t\t\tcase \"curl\":\n\t\t\t\tcmd = \"bash\";\n\t\t\t\targs = [\"-c\", `curl -fsSL https://offworld.sh/install | VERSION=${version} bash`];\n\t\t\t\tbreak;\n\t\t\tcase \"npm\":\n\t\t\t\tcmd = \"npm\";\n\t\t\t\targs = [\"install\", \"-g\", `${NPM_PACKAGE}@${version}`];\n\t\t\t\tbreak;\n\t\t\tcase \"pnpm\":\n\t\t\t\tcmd = \"pnpm\";\n\t\t\t\targs = [\"install\", \"-g\", `${NPM_PACKAGE}@${version}`];\n\t\t\t\tbreak;\n\t\t\tcase \"bun\":\n\t\t\t\tcmd = \"bun\";\n\t\t\t\targs = [\"install\", \"-g\", `${NPM_PACKAGE}@${version}`];\n\t\t\t\tbreak;\n\t\t\tcase \"brew\":\n\t\t\t\tcmd = \"brew\";\n\t\t\t\targs = [\"upgrade\", \"offworld\"];\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\treject(new Error(`Cannot upgrade: unknown installation method`));\n\t\t\t\treturn;\n\t\t}\n\n\t\tconst proc = spawn(cmd, args, { stdio: \"inherit\" });\n\t\tproc.on(\"close\", (code) => {\n\t\t\tif (code === 0) resolve();\n\t\t\telse reject(new Error(`Upgrade failed with exit code ${code}`));\n\t\t});\n\t\tproc.on(\"error\", reject);\n\t});\n}\n\n/**\n * Execute uninstall for given method\n */\nexport function executeUninstall(method: InstallMethod): Promise<void> {\n\treturn new Promise((resolve, reject) => {\n\t\tlet cmd: string;\n\t\tlet args: string[];\n\n\t\tswitch (method) {\n\t\t\tcase \"curl\":\n\t\t\t\ttry {\n\t\t\t\t\tconst binPath = join(homedir(), \".local\", \"bin\", \"ow\");\n\t\t\t\t\tif (existsSync(binPath)) {\n\t\t\t\t\t\texecSync(`rm -f \"${binPath}\"`, { stdio: \"inherit\" });\n\t\t\t\t\t}\n\t\t\t\t\tresolve();\n\t\t\t\t} catch (err) {\n\t\t\t\t\treject(err);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\tcase \"npm\":\n\t\t\t\tcmd = \"npm\";\n\t\t\t\targs = [\"uninstall\", \"-g\", NPM_PACKAGE];\n\t\t\t\tbreak;\n\t\t\tcase \"pnpm\":\n\t\t\t\tcmd = \"pnpm\";\n\t\t\t\targs = [\"uninstall\", \"-g\", NPM_PACKAGE];\n\t\t\t\tbreak;\n\t\t\tcase \"bun\":\n\t\t\t\tcmd = \"bun\";\n\t\t\t\targs = [\"remove\", \"-g\", NPM_PACKAGE];\n\t\t\t\tbreak;\n\t\t\tcase \"brew\":\n\t\t\t\tcmd = \"brew\";\n\t\t\t\targs = [\"uninstall\", \"offworld\"];\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\treject(new Error(`Cannot uninstall: unknown installation method`));\n\t\t\t\treturn;\n\t\t}\n\n\t\tconst proc = spawn(cmd, args, { stdio: \"inherit\" });\n\t\tproc.on(\"close\", (code) => {\n\t\t\tif (code === 0) resolve();\n\t\t\telse reject(new Error(`Uninstall failed with exit code ${code}`));\n\t\t});\n\t\tproc.on(\"error\", reject);\n\t});\n}\n\n/**\n * Get shell config files to clean\n */\nexport function getShellConfigFiles(): string[] {\n\tconst home = homedir();\n\tconst configs: string[] = [];\n\n\tconst candidates = [\n\t\t\".bashrc\",\n\t\t\".bash_profile\",\n\t\t\".profile\",\n\t\t\".zshrc\",\n\t\t\".zshenv\",\n\t\t\".config/fish/config.fish\",\n\t];\n\n\tfor (const file of candidates) {\n\t\tconst path = join(home, file);\n\t\tif (existsSync(path)) {\n\t\t\tconfigs.push(path);\n\t\t}\n\t}\n\n\treturn configs;\n}\n\n/**\n * Clean PATH entries from shell config\n */\nexport function cleanShellConfig(filePath: string): boolean {\n\ttry {\n\t\tconst content = readFileSync(filePath, \"utf-8\");\n\t\tconst lines = content.split(\"\\n\");\n\t\tconst filtered: string[] = [];\n\t\tlet modified = false;\n\n\t\tfor (const line of lines) {\n\t\t\tconst trimmed = line.trim();\n\t\t\tif (\n\t\t\t\ttrimmed.includes(\".local/bin\") &&\n\t\t\t\t(trimmed.startsWith(\"export PATH=\") || trimmed.startsWith(\"fish_add_path\"))\n\t\t\t) {\n\t\t\t\tif (trimmed.includes(\"# offworld\") || trimmed === 'export PATH=\"$HOME/.local/bin:$PATH\"') {\n\t\t\t\t\tmodified = true;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfiltered.push(line);\n\t\t}\n\n\t\tif (modified) {\n\t\t\twriteFileSync(filePath, filtered.join(\"\\n\"), \"utf-8\");\n\t\t}\n\n\t\treturn modified;\n\t} catch {\n\t\treturn false;\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAwBA,SAAS,wBAAwB,aAA2C;AAQ3E,QAPc;EACb;EACA;EACA;EACA;EACA,CAEY,KAAK,KAAK;;;;;;;;;AAUxB,SAAgB,wBAAwB,UAAkB,YAAwC;CACjG,MAAM,UAAU,WAAW,SAAS,GAAG,aAAa,UAAU,QAAQ,GAAG;CACzE,MAAM,qBAAqB,wBAAwB,WAAW;CAE9D,MAAM,eAAe;CACrB,MAAM,QAAQ,QAAQ,MAAM,aAAa;CAEzC,IAAI;AACJ,KAAI,MACH,kBAAiB,QAAQ,QAAQ,cAAc,mBAAmB;KAElE,kBAAiB,QAAQ,MAAM,GAAG,SAAS;AAG5C,eAAc,UAAU,gBAAgB,QAAQ;;;;;;;;;AAUjD,SAAgB,iBAAiB,aAAqB,YAAwC;CAC7F,MAAM,eAAe,KAAK,aAAa,YAAY;CACnD,MAAM,eAAe,KAAK,aAAa,YAAY;AAEnD,yBAAwB,cAAc,WAAW;AAEjD,KAAI,WAAW,aAAa,CAC3B,yBAAwB,cAAc,WAAW;;;;;;;;AC9DnD,MAAM,cAAc;AACpB,MAAM,cAAc;;;;AAOpB,SAAgB,sBAAqC;CACpD,MAAM,WAAW,QAAQ;AAEzB,KAAI,SAAS,SAAS,aAAa,CAAE,QAAO;CAE5C,MAAM,SAA8D;EACnE;GACC,MAAM;GACN,YAAY;AACX,QAAI;AAIH,YAHe,SAAS,qCAAqC,EAC5D,UAAU,SACV,CAAC,CACY,SAAS,YAAY;YAC5B;AACP,YAAO;;;GAGT;EACD;GACC,MAAM;GACN,YAAY;AACX,QAAI;AAIH,YAHe,SAAS,sCAAsC,EAC7D,UAAU,SACV,CAAC,CACY,SAAS,YAAY;YAC5B;AACP,YAAO;;;GAGT;EACD;GACC,MAAM;GACN,YAAY;AACX,QAAI;AAIH,YAHe,SAAS,4BAA4B,EACnD,UAAU,SACV,CAAC,CACY,SAAS,YAAY;YAC5B;AACP,YAAO;;;GAGT;EACD;GACC,MAAM;GACN,YAAY;AACX,QAAI;AACH,cAAS,4CAA4C,EACpD,UAAU,SACV,CAAC;AACF,YAAO;YACA;AACP,YAAO;;;GAGT;EACD;AAED,KAAI,SAAS,SAAS,MAAM,EAE3B;MADc,OAAO,MAAM,MAAM,EAAE,SAAS,MAAM,EACvC,MAAM,CAAE,QAAO;;AAE3B,KAAI,SAAS,SAAS,OAAO,EAE5B;MADc,OAAO,MAAM,MAAM,EAAE,SAAS,OAAO,EACxC,MAAM,CAAE,QAAO;;AAE3B,KAAI,SAAS,SAAS,MAAM,EAE3B;MADc,OAAO,MAAM,MAAM,EAAE,SAAS,MAAM,EACvC,MAAM,CAAE,QAAO;;AAE3B,KAAI,SAAS,SAAS,SAAS,IAAI,SAAS,SAAS,WAAW,EAE/D;MADc,OAAO,MAAM,MAAM,EAAE,SAAS,OAAO,EACxC,MAAM,CAAE,QAAO;;AAG3B,MAAK,MAAM,SAAS,OACnB,KAAI,MAAM,MAAM,CAAE,QAAO,MAAM;AAGhC,QAAO;;;;;AAMR,SAAgB,oBAA4B;AAC3C,QAAO;;;;;AAMR,eAAsB,mBAAmB,QAAgD;CACxF,MAAM,gBAAgB,UAAU,qBAAqB;AAErD,KAAI;AACH,MAAI,kBAAkB,SAAS,kBAAkB,UAAU,kBAAkB,OAAO;GACnF,MAAM,WAAW,MAAM,MAAM,8BAA8B,YAAY,SAAS;AAChF,OAAI,CAAC,SAAS,GAAI,QAAO;GACzB,MAAM,OAAO,MAAM,SAAS,MAAM;GAClC,MAAM,SAAS,yBAAyB,UAAU,KAAK;AACvD,OAAI,CAAC,OAAO,QAAS,QAAO;AAC5B,UAAO,OAAO,KAAK,WAAW;;EAG/B,MAAM,WAAW,MAAM,MAAM,gCAAgC,YAAY,mBAAmB,EAC3F,SAAS;GACR,QAAQ;GACR,cAAc;GACd,EACD,CAAC;AACF,MAAI,CAAC,SAAS,GAAI,QAAO;EACzB,MAAM,OAAO,MAAM,SAAS,MAAM;AAKlC,UAHC,OAAO,SAAS,YAAY,SAAS,QAAQ,cAAc,OACxD,OAAO,KAAK,SAAS,GACrB,OACY,QAAQ,MAAM,GAAG,IAAI;SAC9B;AACP,SAAO;;;;;;AAOT,SAAgB,eAAe,QAAuB,SAAgC;AACrF,QAAO,IAAI,SAAS,SAAS,WAAW;EACvC,IAAI;EACJ,IAAI;AAEJ,UAAQ,QAAR;GACC,KAAK;AACJ,UAAM;AACN,WAAO,CAAC,MAAM,oDAAoD,QAAQ,OAAO;AACjF;GACD,KAAK;AACJ,UAAM;AACN,WAAO;KAAC;KAAW;KAAM,GAAG,YAAY,GAAG;KAAU;AACrD;GACD,KAAK;AACJ,UAAM;AACN,WAAO;KAAC;KAAW;KAAM,GAAG,YAAY,GAAG;KAAU;AACrD;GACD,KAAK;AACJ,UAAM;AACN,WAAO;KAAC;KAAW;KAAM,GAAG,YAAY,GAAG;KAAU;AACrD;GACD,KAAK;AACJ,UAAM;AACN,WAAO,CAAC,WAAW,WAAW;AAC9B;GACD;AACC,2BAAO,IAAI,MAAM,8CAA8C,CAAC;AAChE;;EAGF,MAAM,OAAO,MAAM,KAAK,MAAM,EAAE,OAAO,WAAW,CAAC;AACnD,OAAK,GAAG,UAAU,SAAS;AAC1B,OAAI,SAAS,EAAG,UAAS;OACpB,wBAAO,IAAI,MAAM,iCAAiC,OAAO,CAAC;IAC9D;AACF,OAAK,GAAG,SAAS,OAAO;GACvB;;;;;AAMH,SAAgB,iBAAiB,QAAsC;AACtE,QAAO,IAAI,SAAS,SAAS,WAAW;EACvC,IAAI;EACJ,IAAI;AAEJ,UAAQ,QAAR;GACC,KAAK;AACJ,QAAI;KACH,MAAM,UAAU,KAAK,SAAS,EAAE,UAAU,OAAO,KAAK;AACtD,SAAI,WAAW,QAAQ,CACtB,UAAS,UAAU,QAAQ,IAAI,EAAE,OAAO,WAAW,CAAC;AAErD,cAAS;aACD,KAAK;AACb,YAAO,IAAI;;AAEZ;GACD,KAAK;AACJ,UAAM;AACN,WAAO;KAAC;KAAa;KAAM;KAAY;AACvC;GACD,KAAK;AACJ,UAAM;AACN,WAAO;KAAC;KAAa;KAAM;KAAY;AACvC;GACD,KAAK;AACJ,UAAM;AACN,WAAO;KAAC;KAAU;KAAM;KAAY;AACpC;GACD,KAAK;AACJ,UAAM;AACN,WAAO,CAAC,aAAa,WAAW;AAChC;GACD;AACC,2BAAO,IAAI,MAAM,gDAAgD,CAAC;AAClE;;EAGF,MAAM,OAAO,MAAM,KAAK,MAAM,EAAE,OAAO,WAAW,CAAC;AACnD,OAAK,GAAG,UAAU,SAAS;AAC1B,OAAI,SAAS,EAAG,UAAS;OACpB,wBAAO,IAAI,MAAM,mCAAmC,OAAO,CAAC;IAChE;AACF,OAAK,GAAG,SAAS,OAAO;GACvB;;;;;AAMH,SAAgB,sBAAgC;CAC/C,MAAM,OAAO,SAAS;CACtB,MAAM,UAAoB,EAAE;AAW5B,MAAK,MAAM,QATQ;EAClB;EACA;EACA;EACA;EACA;EACA;EACA,EAE8B;EAC9B,MAAM,OAAO,KAAK,MAAM,KAAK;AAC7B,MAAI,WAAW,KAAK,CACnB,SAAQ,KAAK,KAAK;;AAIpB,QAAO;;;;;AAMR,SAAgB,iBAAiB,UAA2B;AAC3D,KAAI;EAEH,MAAM,QADU,aAAa,UAAU,QAAQ,CACzB,MAAM,KAAK;EACjC,MAAM,WAAqB,EAAE;EAC7B,IAAI,WAAW;AAEf,OAAK,MAAM,QAAQ,OAAO;GACzB,MAAM,UAAU,KAAK,MAAM;AAC3B,OACC,QAAQ,SAAS,aAAa,KAC7B,QAAQ,WAAW,eAAe,IAAI,QAAQ,WAAW,gBAAgB,GAE1E;QAAI,QAAQ,SAAS,aAAa,IAAI,YAAY,0CAAwC;AACzF,gBAAW;AACX;;;AAGF,YAAS,KAAK,KAAK;;AAGpB,MAAI,SACH,eAAc,UAAU,SAAS,KAAK,KAAK,EAAE,QAAQ;AAGtD,SAAO;SACA;AACP,SAAO"}
1
+ {"version":3,"file":"internal.mjs","names":[],"sources":["../src/agents-md.ts","../src/installation.ts"],"sourcesContent":["/**\n * AGENTS.md manipulation utilities\n *\n * Manages updating project AGENTS.md and agent-specific files with reference information.\n */\n\nimport { readFileSync, writeFileSync, existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\nconst referencesSectionRegex = /^## Project References\\n(?:.*\\n)*?(?=^## |$)/m;\n\nexport interface InstalledReference {\n\t/** Dependency name */\n\tdependency: string;\n\t/** Reference identifier (matches reference file name without .md) */\n\treference: string;\n\t/** Absolute path to reference file */\n\tpath: string;\n}\n\n/**\n * Generate single-line project reference guidance.\n *\n * @param _references - Installed references (unused; reserved for future context)\n * @returns Markdown string with one-line guidance\n */\nfunction generateReferencesTable(_references: InstalledReference[]): string {\n\tconst lines = [\n\t\t\"## Project References\",\n\t\t\"\",\n\t\t\"Use the Offworld CLI to find and read directly from local codebases for any repo in `.offworld/map.json` whenever the user asks about a specific open source project.\",\n\t\t\"\",\n\t];\n\n\treturn lines.join(\"\\n\");\n}\n\n/**\n * Update or append Project References section in a markdown file.\n * If the section exists, replaces its content. Otherwise, appends to end.\n *\n * @param filePath - Path to markdown file\n * @param references - Array of installed references\n */\nexport function appendReferencesSection(filePath: string, references: InstalledReference[]): void {\n\tconst content = existsSync(filePath) ? readFileSync(filePath, \"utf-8\") : \"\";\n\tconst referencesMarkdown = generateReferencesTable(references);\n\n\tconst match = content.match(referencesSectionRegex);\n\n\tlet updatedContent: string;\n\tif (match) {\n\t\tupdatedContent = content.replace(referencesSectionRegex, referencesMarkdown);\n\t} else {\n\t\tupdatedContent = content.trim() + \"\\n\\n\" + referencesMarkdown;\n\t}\n\n\twriteFileSync(filePath, updatedContent, \"utf-8\");\n}\n\n/**\n * Update AGENTS.md with project references if the section is missing.\n *\n * @param projectRoot - Project root directory\n * @param references - Array of installed references to document\n */\nexport function updateAgentFiles(projectRoot: string, references: InstalledReference[]): void {\n\tconst agentsMdPath = join(projectRoot, \"AGENTS.md\");\n\tconst referencesMarkdown = generateReferencesTable(references);\n\n\tif (!existsSync(agentsMdPath)) {\n\t\twriteFileSync(agentsMdPath, referencesMarkdown, \"utf-8\");\n\t\treturn;\n\t}\n\n\tconst content = readFileSync(agentsMdPath, \"utf-8\");\n\tif (referencesSectionRegex.test(content)) {\n\t\treturn;\n\t}\n\n\tconst separator = content.endsWith(\"\\n\\n\") ? \"\" : content.endsWith(\"\\n\") ? \"\\n\" : \"\\n\\n\";\n\tconst updatedContent =\n\t\tcontent.trim().length === 0\n\t\t\t? referencesMarkdown\n\t\t\t: `${content}${separator}${referencesMarkdown}`;\n\twriteFileSync(agentsMdPath, updatedContent, \"utf-8\");\n}\n","/**\n * Installation utilities for upgrade/uninstall commands\n */\n\nimport { execSync, spawn } from \"node:child_process\";\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { NpmPackageResponseSchema } from \"@offworld/types\";\nimport { VERSION } from \"./constants.js\";\n\nconst GITHUB_REPO = \"oscabriel/offworld\";\nconst NPM_PACKAGE = \"offworld\";\n\nexport type InstallMethod = \"curl\" | \"npm\" | \"pnpm\" | \"bun\" | \"brew\" | \"unknown\";\n\n/**\n * Detect how offworld was installed\n */\nexport function detectInstallMethod(): InstallMethod {\n\tconst execPath = process.execPath;\n\n\tif (execPath.includes(\".local/bin\")) return \"curl\";\n\n\tconst checks: Array<{ name: InstallMethod; test: () => boolean }> = [\n\t\t{\n\t\t\tname: \"npm\",\n\t\t\ttest: () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = execSync(\"npm list -g --depth=0 2>/dev/null\", {\n\t\t\t\t\t\tencoding: \"utf-8\",\n\t\t\t\t\t});\n\t\t\t\t\treturn result.includes(NPM_PACKAGE);\n\t\t\t\t} catch {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"pnpm\",\n\t\t\ttest: () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = execSync(\"pnpm list -g --depth=0 2>/dev/null\", {\n\t\t\t\t\t\tencoding: \"utf-8\",\n\t\t\t\t\t});\n\t\t\t\t\treturn result.includes(NPM_PACKAGE);\n\t\t\t\t} catch {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"bun\",\n\t\t\ttest: () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst result = execSync(\"bun pm ls -g 2>/dev/null\", {\n\t\t\t\t\t\tencoding: \"utf-8\",\n\t\t\t\t\t});\n\t\t\t\t\treturn result.includes(NPM_PACKAGE);\n\t\t\t\t} catch {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tname: \"brew\",\n\t\t\ttest: () => {\n\t\t\t\ttry {\n\t\t\t\t\texecSync(\"brew list --formula offworld 2>/dev/null\", {\n\t\t\t\t\t\tencoding: \"utf-8\",\n\t\t\t\t\t});\n\t\t\t\t\treturn true;\n\t\t\t\t} catch {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t];\n\n\tif (execPath.includes(\"npm\")) {\n\t\tconst check = checks.find((c) => c.name === \"npm\");\n\t\tif (check?.test()) return \"npm\";\n\t}\n\tif (execPath.includes(\"pnpm\")) {\n\t\tconst check = checks.find((c) => c.name === \"pnpm\");\n\t\tif (check?.test()) return \"pnpm\";\n\t}\n\tif (execPath.includes(\"bun\")) {\n\t\tconst check = checks.find((c) => c.name === \"bun\");\n\t\tif (check?.test()) return \"bun\";\n\t}\n\tif (execPath.includes(\"Cellar\") || execPath.includes(\"homebrew\")) {\n\t\tconst check = checks.find((c) => c.name === \"brew\");\n\t\tif (check?.test()) return \"brew\";\n\t}\n\n\tfor (const check of checks) {\n\t\tif (check.test()) return check.name;\n\t}\n\n\treturn \"unknown\";\n}\n\n/**\n * Get current installed version\n */\nexport function getCurrentVersion(): string {\n\treturn VERSION;\n}\n\n/**\n * Fetch latest version from appropriate source\n */\nexport async function fetchLatestVersion(method?: InstallMethod): Promise<string | null> {\n\tconst installMethod = method ?? detectInstallMethod();\n\n\ttry {\n\t\tif (installMethod === \"npm\" || installMethod === \"pnpm\" || installMethod === \"bun\") {\n\t\t\tconst response = await fetch(`https://registry.npmjs.org/${NPM_PACKAGE}/latest`);\n\t\t\tif (!response.ok) return null;\n\t\t\tconst json = await response.json();\n\t\t\tconst result = NpmPackageResponseSchema.safeParse(json);\n\t\t\tif (!result.success) return null;\n\t\t\treturn result.data.version ?? null;\n\t\t}\n\n\t\tconst response = await fetch(`https://api.github.com/repos/${GITHUB_REPO}/releases/latest`, {\n\t\t\theaders: {\n\t\t\t\tAccept: \"application/vnd.github.v3+json\",\n\t\t\t\t\"User-Agent\": \"offworld-cli\",\n\t\t\t},\n\t\t});\n\t\tif (!response.ok) return null;\n\t\tconst json = await response.json();\n\t\tconst tagName =\n\t\t\ttypeof json === \"object\" && json !== null && \"tag_name\" in json\n\t\t\t\t? String(json.tag_name)\n\t\t\t\t: null;\n\t\treturn tagName?.replace(/^v/, \"\") ?? null;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Execute upgrade for given method\n */\nexport function executeUpgrade(method: InstallMethod, version: string): Promise<void> {\n\treturn new Promise((resolve, reject) => {\n\t\tlet cmd: string;\n\t\tlet args: string[];\n\n\t\tswitch (method) {\n\t\t\tcase \"curl\":\n\t\t\t\tcmd = \"bash\";\n\t\t\t\targs = [\"-c\", `curl -fsSL https://offworld.sh/install | VERSION=${version} bash`];\n\t\t\t\tbreak;\n\t\t\tcase \"npm\":\n\t\t\t\tcmd = \"npm\";\n\t\t\t\targs = [\"install\", \"-g\", `${NPM_PACKAGE}@${version}`];\n\t\t\t\tbreak;\n\t\t\tcase \"pnpm\":\n\t\t\t\tcmd = \"pnpm\";\n\t\t\t\targs = [\"install\", \"-g\", `${NPM_PACKAGE}@${version}`];\n\t\t\t\tbreak;\n\t\t\tcase \"bun\":\n\t\t\t\tcmd = \"bun\";\n\t\t\t\targs = [\"install\", \"-g\", `${NPM_PACKAGE}@${version}`];\n\t\t\t\tbreak;\n\t\t\tcase \"brew\":\n\t\t\t\tcmd = \"brew\";\n\t\t\t\targs = [\"upgrade\", \"offworld\"];\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\treject(new Error(`Cannot upgrade: unknown installation method`));\n\t\t\t\treturn;\n\t\t}\n\n\t\tconst proc = spawn(cmd, args, { stdio: \"inherit\" });\n\t\tproc.on(\"close\", (code) => {\n\t\t\tif (code === 0) resolve();\n\t\t\telse reject(new Error(`Upgrade failed with exit code ${code}`));\n\t\t});\n\t\tproc.on(\"error\", reject);\n\t});\n}\n\n/**\n * Execute uninstall for given method\n */\nexport function executeUninstall(method: InstallMethod): Promise<void> {\n\treturn new Promise((resolve, reject) => {\n\t\tlet cmd: string;\n\t\tlet args: string[];\n\n\t\tswitch (method) {\n\t\t\tcase \"curl\":\n\t\t\t\ttry {\n\t\t\t\t\tconst binPath = join(homedir(), \".local\", \"bin\", \"ow\");\n\t\t\t\t\tif (existsSync(binPath)) {\n\t\t\t\t\t\texecSync(`rm -f \"${binPath}\"`, { stdio: \"inherit\" });\n\t\t\t\t\t}\n\t\t\t\t\tresolve();\n\t\t\t\t} catch (err) {\n\t\t\t\t\treject(err);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\tcase \"npm\":\n\t\t\t\tcmd = \"npm\";\n\t\t\t\targs = [\"uninstall\", \"-g\", NPM_PACKAGE];\n\t\t\t\tbreak;\n\t\t\tcase \"pnpm\":\n\t\t\t\tcmd = \"pnpm\";\n\t\t\t\targs = [\"uninstall\", \"-g\", NPM_PACKAGE];\n\t\t\t\tbreak;\n\t\t\tcase \"bun\":\n\t\t\t\tcmd = \"bun\";\n\t\t\t\targs = [\"remove\", \"-g\", NPM_PACKAGE];\n\t\t\t\tbreak;\n\t\t\tcase \"brew\":\n\t\t\t\tcmd = \"brew\";\n\t\t\t\targs = [\"uninstall\", \"offworld\"];\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\treject(new Error(`Cannot uninstall: unknown installation method`));\n\t\t\t\treturn;\n\t\t}\n\n\t\tconst proc = spawn(cmd, args, { stdio: \"inherit\" });\n\t\tproc.on(\"close\", (code) => {\n\t\t\tif (code === 0) resolve();\n\t\t\telse reject(new Error(`Uninstall failed with exit code ${code}`));\n\t\t});\n\t\tproc.on(\"error\", reject);\n\t});\n}\n\n/**\n * Get shell config files to clean\n */\nexport function getShellConfigFiles(): string[] {\n\tconst home = homedir();\n\tconst configs: string[] = [];\n\n\tconst candidates = [\n\t\t\".bashrc\",\n\t\t\".bash_profile\",\n\t\t\".profile\",\n\t\t\".zshrc\",\n\t\t\".zshenv\",\n\t\t\".config/fish/config.fish\",\n\t];\n\n\tfor (const file of candidates) {\n\t\tconst path = join(home, file);\n\t\tif (existsSync(path)) {\n\t\t\tconfigs.push(path);\n\t\t}\n\t}\n\n\treturn configs;\n}\n\n/**\n * Clean PATH entries from shell config\n */\nexport function cleanShellConfig(filePath: string): boolean {\n\ttry {\n\t\tconst content = readFileSync(filePath, \"utf-8\");\n\t\tconst lines = content.split(\"\\n\");\n\t\tconst filtered: string[] = [];\n\t\tlet modified = false;\n\n\t\tfor (const line of lines) {\n\t\t\tconst trimmed = line.trim();\n\t\t\tif (\n\t\t\t\ttrimmed.includes(\".local/bin\") &&\n\t\t\t\t(trimmed.startsWith(\"export PATH=\") || trimmed.startsWith(\"fish_add_path\"))\n\t\t\t) {\n\t\t\t\tif (trimmed.includes(\"# offworld\") || trimmed === 'export PATH=\"$HOME/.local/bin:$PATH\"') {\n\t\t\t\t\tmodified = true;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfiltered.push(line);\n\t\t}\n\n\t\tif (modified) {\n\t\t\twriteFileSync(filePath, filtered.join(\"\\n\"), \"utf-8\");\n\t\t}\n\n\t\treturn modified;\n\t} catch {\n\t\treturn false;\n\t}\n}\n"],"mappings":"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"}
@@ -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.3.5";
8
+ declare const VERSION = "0.3.7";
9
9
  /**
10
10
  * Default patterns to ignore when scanning repositories.
11
11
  * Includes directories, binary files, IDE configs, and build outputs.
@@ -658,4 +658,4 @@ declare function validateProviderModel(providerId: string, modelId: string): Pro
658
658
  }>;
659
659
  //#endregion
660
660
  export { installGlobalSkill as $, getMetaPath as $t, pruneRepos as A, removeRepo as At, getNpmKeywords as B, readGlobalMap as Bt, RepoStatusOptions as C, UpdateResult as Ct, discoverRepos as D, getCommitSha as Dt, UpdateAllResult as E, getCommitDistance as Et, matchDependenciesToReferences as F, SearchResult as Ft, detectManifestType as G, NotGitRepoError as Gt, resolveFromNpm as H, upsertGlobalMapEntry as Ht, matchDependenciesToReferencesWithRemoteCheck as I, getMapEntry as It, agents as J, getReferenceFileNameForSource as Jt, parseDependencies as K, PathNotFoundError as Kt, FALLBACK_MAPPINGS as L, getProjectMapPath as Lt, ReferenceMatch as M, GetMapEntryOptions as Mt, ReferenceStatus as N, MapEntry as Nt, gcRepos as O, isRepoCloned as Ot, isReferenceInstalled as P, SearchMapOptions as Pt, InstallReferenceMeta as Q, getConfigPath as Qt, ResolveDependencyRepoOptions as R, resolveRepoKey as Rt, PruneResult as S, UpdateOptions as St, UpdateAllOptions as T, getClonedRepoPath as Tt, Dependency as U, writeGlobalMap as Ut, resolveDependencyRepo as V, removeGlobalMapEntry as Vt, ManifestType as W, writeProjectMap as Wt, getAgentConfig as X, Paths as Xt, detectInstalledAgents as Y, parseRepoInput as Yt, getAllAgentConfigs as Z, expandTilde as Zt, DiscoverOptions as _, CloneOptions as _t, GlobalMap$1 as a, saveConfig as an, NotLoggedInError as at, GcResult as b, RepoExistsError as bt, ProjectMapRepoEntry$1 as c, toReferenceName as cn, getAuthPath as ct, ProviderInfo as d, getTokenOrNull as dt, getMetaRoot as en, installReference as et, ProviderWithModels as f, isLoggedIn as ft, validateProviderModel as g, CloneError as gt, listProvidersWithModels as h, saveAuthData as ht, FileRole as i, loadConfig as in, AuthStatus as it, updateAllRepos as j, updateRepo as jt, getRepoStatus as k, listRepos as kt, RepoSource$1 as l, DEFAULT_IGNORE_PATTERNS as ln, getAuthStatus as lt, listProviders as m, refreshAccessToken as mt, FileIndex as n, getRepoPath as nn, AuthData as nt, GlobalMapRepoEntry$1 as o, toMetaDirName as on, TokenExpiredError as ot, getProvider as p, loadAuthData as pt, AgentConfig as q, RepoSourceError as qt, FileIndexEntry as r, getRepoRoot as rn, AuthError as rt, ProjectMap$1 as s, toReferenceFileName as sn, clearAuthData as st, Config$1 as t, getReferencePath as tn, resolveReferenceKeywords as tt, ModelInfo as u, VERSION as un, getToken as ut, DiscoverResult as v, GitError as vt, RepoStatusSummary as w, cloneRepo as wt, PruneOptions as x, RepoNotFoundError as xt, GcOptions as y, RemoveOptions as yt, ResolvedDep as z, searchMap as zt };
661
- //# sourceMappingURL=public-DZZG1NQL.d.mts.map
661
+ //# sourceMappingURL=public-DkkNYpNL.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"public-DZZG1NQL.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/auth.ts","../src/reference.ts","../src/agents.ts","../src/manifest.ts","../src/dep-mappings.ts","../src/reference-matcher.ts","../src/repo-manager.ts","../src/models.ts"],"mappings":"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"}
1
+ {"version":3,"file":"public-DkkNYpNL.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/auth.ts","../src/reference.ts","../src/agents.ts","../src/manifest.ts","../src/dep-mappings.ts","../src/reference-matcher.ts","../src/repo-manager.ts","../src/models.ts"],"mappings":"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"}
@@ -12,7 +12,7 @@ import { z } from "zod";
12
12
  * SDK Constants
13
13
  */
14
14
  /** SDK version - must match package.json */
15
- const VERSION = "0.3.5";
15
+ const VERSION = "0.3.7";
16
16
  /**
17
17
  * Default patterns to ignore when scanning repositories.
18
18
  * Includes directories, binary files, IDE configs, and build outputs.
@@ -1034,7 +1034,7 @@ ow init --yes --agents "opencode,codex" --repo-root "~/ow" --model "anthropic/cl
1034
1034
  ## 4) Initialize current project
1035
1035
 
1036
1036
  \`\`\`bash
1037
- ow project init --yes --all --generate
1037
+ ow project init --yes --all
1038
1038
  \`\`\`
1039
1039
 
1040
1040
  ## 5) Verify
@@ -1890,4 +1890,4 @@ async function validateProviderModel(providerId, modelId) {
1890
1890
 
1891
1891
  //#endregion
1892
1892
  export { getAuthPath as A, resolveRepoKey as B, detectInstalledAgents as C, NotLoggedInError as D, AuthError as E, loadAuthData as F, getReferenceFileNameForSource as G, NotGitRepoError as H, refreshAccessToken as I, VERSION as J, parseRepoInput as K, saveAuthData as L, getToken as M, getTokenOrNull as N, TokenExpiredError as O, isLoggedIn as P, getMapEntry as R, agents as S, getAllAgentConfigs as T, PathNotFoundError as U, searchMap as V, RepoSourceError as W, resolveReferenceKeywords as _, discoverRepos as a, resolveDependencyRepo as b, pruneRepos as c, matchDependenciesToReferences as d, matchDependenciesToReferencesWithRemoteCheck as f, installReference as g, installGlobalSkill as h, validateProviderModel as i, getAuthStatus as j, clearAuthData as k, updateAllRepos as l, parseDependencies as m, listProviders as n, gcRepos as o, detectManifestType as p, DEFAULT_IGNORE_PATTERNS as q, listProvidersWithModels as r, getRepoStatus as s, getProvider as t, isReferenceInstalled as u, FALLBACK_MAPPINGS as v, getAgentConfig as w, resolveFromNpm as x, getNpmKeywords as y, getProjectMapPath as z };
1893
- //# sourceMappingURL=public-CWnhJJ9J.mjs.map
1893
+ //# sourceMappingURL=public-T9TZSuKw.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public-T9TZSuKw.mjs","names":["GlobalMapSchema","ProjectMapSchema"],"sources":["../src/constants.ts","../src/repo-source.ts","../src/map.ts","../src/auth.ts","../src/agents.ts","../src/dep-mappings.ts","../src/reference.ts","../src/manifest.ts","../src/reference-matcher.ts","../src/repo-manager.ts","../src/models.ts"],"sourcesContent":["/**\n * SDK Constants\n */\n\n/** SDK version - must match package.json */\nexport const VERSION = \"0.3.7\";\n\n/**\n * Default patterns to ignore when scanning repositories.\n * Includes directories, binary files, IDE configs, and build outputs.\n */\nexport const DEFAULT_IGNORE_PATTERNS = [\n\t\".git\",\n\t\".git/**\",\n\t\".svn\",\n\t\".hg\",\n\n\t\"node_modules\",\n\t\"node_modules/**\",\n\t\"vendor\",\n\t\"vendor/**\",\n\t\".pnpm\",\n\t\".yarn\",\n\n\t\"dist\",\n\t\"dist/**\",\n\t\"build\",\n\t\"build/**\",\n\t\"out\",\n\t\"out/**\",\n\t\".next\",\n\t\".nuxt\",\n\t\".output\",\n\t\"target\",\n\t\"__pycache__\",\n\t\"*.pyc\",\n\n\t\".vscode\",\n\t\".vscode/**\",\n\t\".idea\",\n\t\".idea/**\",\n\t\"*.swp\",\n\t\"*.swo\",\n\t\".DS_Store\",\n\n\t\"*.jpg\",\n\t\"*.jpeg\",\n\t\"*.png\",\n\t\"*.gif\",\n\t\"*.ico\",\n\t\"*.webp\",\n\t\"*.svg\",\n\t\"*.bmp\",\n\t\"*.tiff\",\n\t\"*.mp4\",\n\t\"*.webm\",\n\t\"*.mov\",\n\t\"*.avi\",\n\t\"*.mkv\",\n\t\"*.mp3\",\n\t\"*.wav\",\n\t\"*.flac\",\n\t\"*.ogg\",\n\t\"*.pdf\",\n\t\"*.zip\",\n\t\"*.tar\",\n\t\"*.gz\",\n\t\"*.rar\",\n\t\"*.7z\",\n\t\"*.exe\",\n\t\"*.dll\",\n\t\"*.so\",\n\t\"*.dylib\",\n\t\"*.bin\",\n\t\"*.wasm\",\n\t\"*.woff\",\n\t\"*.woff2\",\n\t\"*.ttf\",\n\t\"*.eot\",\n\t\"*.otf\",\n\n\t\"package-lock.json\",\n\t\"yarn.lock\",\n\t\"pnpm-lock.yaml\",\n\t\"bun.lockb\",\n\t\"Cargo.lock\",\n\t\"Gemfile.lock\",\n\t\"poetry.lock\",\n\t\"composer.lock\",\n\t\"go.sum\",\n\n\t\"coverage\",\n\t\"coverage/**\",\n\t\".nyc_output\",\n\t\".coverage\",\n\t\"htmlcov\",\n\n\t\"*.log\",\n\t\"logs\",\n\t\"tmp\",\n\t\"temp\",\n\t\".tmp\",\n\t\".temp\",\n\t\".cache\",\n\n\t\".env\",\n\t\".env.*\",\n\t\"*.pem\",\n\t\"*.key\",\n] as const;\n","/**\n * Repository source parsing utilities\n */\n\nimport { createHash } from \"node:crypto\";\nimport { existsSync, statSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { basename } from \"node:path\";\nimport type { GitProvider, LocalRepoSource, RemoteRepoSource, RepoSource } from \"@offworld/types\";\nimport { toReferenceFileName } from \"./config.js\";\nimport { expandTilde } from \"./paths.js\";\n\nexport class RepoSourceError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"RepoSourceError\";\n\t}\n}\n\nexport class PathNotFoundError extends RepoSourceError {\n\tconstructor(path: string) {\n\t\tsuper(`Path does not exist: ${path}`);\n\t\tthis.name = \"PathNotFoundError\";\n\t}\n}\n\nexport class NotGitRepoError extends RepoSourceError {\n\tconstructor(path: string) {\n\t\tsuper(`Directory is not a git repository: ${path}`);\n\t\tthis.name = \"NotGitRepoError\";\n\t}\n}\n\nconst PROVIDER_HOSTS: Record<string, GitProvider> = {\n\t\"github.com\": \"github\",\n\t\"gitlab.com\": \"gitlab\",\n\t\"bitbucket.org\": \"bitbucket\",\n};\n\nconst HTTPS_URL_REGEX =\n\t/^https?:\\/\\/(github\\.com|gitlab\\.com|bitbucket\\.org)\\/([^/]+)\\/([^/]+?)(?:\\.git)?$/;\nconst SSH_URL_REGEX = /^git@(github\\.com|gitlab\\.com|bitbucket\\.org):([^/]+)\\/([^/]+?)(?:\\.git)?$/;\nconst SHORT_FORMAT_REGEX = /^([^/:@]+)\\/([^/:@]+)$/;\n\n/**\n * Generates a short hash of a path for local repo identification\n */\nfunction hashPath(path: string): string {\n\treturn createHash(\"sha256\").update(path).digest(\"hex\").slice(0, 12);\n}\n\n/**\n * Builds a clone URL for a remote repository\n */\nfunction buildCloneUrl(provider: GitProvider, owner: string, repo: string): string {\n\tconst hosts: Record<GitProvider, string> = {\n\t\tgithub: \"github.com\",\n\t\tgitlab: \"gitlab.com\",\n\t\tbitbucket: \"bitbucket.org\",\n\t};\n\treturn `https://${hosts[provider]}/${owner}/${repo}.git`;\n}\n\n/**\n * Parses a remote repository from HTTPS URL format\n */\nfunction parseHttpsUrl(input: string): RemoteRepoSource | null {\n\tconst match = input.match(HTTPS_URL_REGEX);\n\tif (!match) return null;\n\n\tconst [, host, owner, repo] = match;\n\tif (!host || !owner || !repo) return null;\n\n\tconst provider = PROVIDER_HOSTS[host];\n\tif (!provider) return null;\n\n\tconst ownerLower = owner.toLowerCase();\n\tconst repoLower = repo.toLowerCase();\n\treturn {\n\t\ttype: \"remote\",\n\t\tprovider,\n\t\towner: ownerLower,\n\t\trepo: repoLower,\n\t\tfullName: `${ownerLower}/${repoLower}`,\n\t\tqualifiedName: `${host}:${ownerLower}/${repoLower}`,\n\t\tcloneUrl: buildCloneUrl(provider, ownerLower, repoLower),\n\t};\n}\n\n/**\n * Parses a remote repository from SSH URL format\n */\nfunction parseSshUrl(input: string): RemoteRepoSource | null {\n\tconst match = input.match(SSH_URL_REGEX);\n\tif (!match) return null;\n\n\tconst [, host, owner, repo] = match;\n\tif (!host || !owner || !repo) return null;\n\n\tconst provider = PROVIDER_HOSTS[host];\n\tif (!provider) return null;\n\n\tconst ownerLower = owner.toLowerCase();\n\tconst repoLower = repo.toLowerCase();\n\treturn {\n\t\ttype: \"remote\",\n\t\tprovider,\n\t\towner: ownerLower,\n\t\trepo: repoLower,\n\t\tfullName: `${ownerLower}/${repoLower}`,\n\t\tqualifiedName: `${host}:${ownerLower}/${repoLower}`,\n\t\tcloneUrl: buildCloneUrl(provider, ownerLower, repoLower),\n\t};\n}\n\n/**\n * Parses a remote repository from short format (owner/repo)\n * Defaults to GitHub as provider\n */\nfunction parseShortFormat(input: string): RemoteRepoSource | null {\n\tconst match = input.match(SHORT_FORMAT_REGEX);\n\tif (!match) return null;\n\n\tconst [, owner, repo] = match;\n\tif (!owner || !repo) return null;\n\n\tconst provider: GitProvider = \"github\";\n\tconst host = \"github.com\";\n\n\tconst ownerLower = owner.toLowerCase();\n\tconst repoLower = repo.toLowerCase();\n\treturn {\n\t\ttype: \"remote\",\n\t\tprovider,\n\t\towner: ownerLower,\n\t\trepo: repoLower,\n\t\tfullName: `${ownerLower}/${repoLower}`,\n\t\tqualifiedName: `${host}:${ownerLower}/${repoLower}`,\n\t\tcloneUrl: buildCloneUrl(provider, ownerLower, repoLower),\n\t};\n}\n\n/**\n * Parses a local repository path\n * Validates that the path exists and contains a .git directory\n */\nfunction parseLocalPath(input: string): LocalRepoSource {\n\tconst absolutePath = resolve(expandTilde(input));\n\n\tif (!existsSync(absolutePath)) {\n\t\tthrow new PathNotFoundError(absolutePath);\n\t}\n\n\tconst stats = statSync(absolutePath);\n\tif (!stats.isDirectory()) {\n\t\tthrow new RepoSourceError(`Path is not a directory: ${absolutePath}`);\n\t}\n\n\tconst gitPath = resolve(absolutePath, \".git\");\n\tif (!existsSync(gitPath)) {\n\t\tthrow new NotGitRepoError(absolutePath);\n\t}\n\n\tconst name = basename(absolutePath);\n\tconst hash = hashPath(absolutePath);\n\n\treturn {\n\t\ttype: \"local\",\n\t\tpath: absolutePath,\n\t\tname,\n\t\tqualifiedName: `local:${hash}`,\n\t};\n}\n\n/**\n * Determines if input looks like a local path\n */\nfunction isLocalPath(input: string): boolean {\n\treturn input.startsWith(\".\") || input.startsWith(\"/\") || input.startsWith(\"~\");\n}\n\n/**\n * Parses a repository input and returns a structured RepoSource\n *\n * Supported formats:\n * - owner/repo (short format, defaults to GitHub)\n * - https://github.com/owner/repo\n * - https://gitlab.com/owner/repo\n * - https://bitbucket.org/owner/repo\n * - git@github.com:owner/repo.git (SSH format)\n * - . (current directory as local repo)\n * - /absolute/path (local repo)\n *\n * @throws PathNotFoundError if local path doesn't exist\n * @throws NotGitRepoError if local path is not a git repository\n * @throws RepoSourceError for other parsing failures\n */\nexport function parseRepoInput(input: string): RepoSource {\n\tconst trimmed = input.trim();\n\n\tconst httpsResult = parseHttpsUrl(trimmed);\n\tif (httpsResult) return httpsResult;\n\n\tconst sshResult = parseSshUrl(trimmed);\n\tif (sshResult) return sshResult;\n\n\tif (isLocalPath(trimmed)) {\n\t\treturn parseLocalPath(trimmed);\n\t}\n\n\tconst shortResult = parseShortFormat(trimmed);\n\tif (shortResult) return shortResult;\n\n\tthrow new RepoSourceError(\n\t\t`Unable to parse repository input: ${input}. ` +\n\t\t\t\"Expected formats: owner/repo, https://github.com/owner/repo, git@github.com:owner/repo.git, or a local path\",\n\t);\n}\n\nexport function getReferenceFileNameForSource(source: RepoSource): string {\n\tif (source.type === \"remote\") {\n\t\treturn toReferenceFileName(source.fullName);\n\t}\n\treturn toReferenceFileName(source.name);\n}\n","/**\n * Map query helpers for fast routing without reading full map.json\n */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport type {\n\tGlobalMap,\n\tGlobalMapRepoEntry,\n\tProjectMap,\n\tProjectMapRepoEntry,\n} from \"@offworld/types\";\nimport { GlobalMapSchema, ProjectMapSchema } from \"@offworld/types/schemas\";\nimport { Paths } from \"./paths.js\";\n\nexport interface MapEntry {\n\tscope: \"project\" | \"global\";\n\tqualifiedName: string;\n\tentry: GlobalMapRepoEntry | ProjectMapRepoEntry;\n}\n\nexport interface SearchResult {\n\tqualifiedName: string;\n\tfullName: string;\n\tlocalPath: string;\n\tprimary: string;\n\tkeywords: string[];\n\tscore: number;\n}\n\nexport interface GetMapEntryOptions {\n\tpreferProject?: boolean;\n\tcwd?: string;\n}\n\nexport interface SearchMapOptions {\n\tlimit?: number;\n\tcwd?: string;\n}\n\nfunction readGlobalMapSafe(): GlobalMap | null {\n\tconst mapPath = Paths.offworldGlobalMapPath;\n\tif (!existsSync(mapPath)) return null;\n\n\ttry {\n\t\tconst content = readFileSync(mapPath, \"utf-8\");\n\t\treturn GlobalMapSchema.parse(JSON.parse(content));\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction readProjectMapSafe(cwd: string): ProjectMap | null {\n\tconst mapPath = resolve(cwd, \".offworld/map.json\");\n\tif (!existsSync(mapPath)) return null;\n\n\ttry {\n\t\tconst content = readFileSync(mapPath, \"utf-8\");\n\t\treturn ProjectMapSchema.parse(JSON.parse(content));\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Normalize input to match against repo keys.\n * Accepts: github.com:owner/repo, owner/repo, repo\n */\nfunction normalizeInput(input: string): { provider?: string; fullName: string; repoName: string } {\n\tconst trimmed = input.trim().toLowerCase();\n\n\tif (trimmed.includes(\":\")) {\n\t\tconst parts = trimmed.split(\":\", 2);\n\t\tconst provider = parts[0];\n\t\tconst fullName = parts[1] ?? \"\";\n\t\tconst repoName = fullName.split(\"/\").pop() ?? fullName;\n\t\treturn { provider, fullName, repoName };\n\t}\n\n\tif (trimmed.includes(\"/\")) {\n\t\tconst repoName = trimmed.split(\"/\").pop() ?? trimmed;\n\t\treturn { fullName: trimmed, repoName };\n\t}\n\n\treturn { fullName: trimmed, repoName: trimmed };\n}\n\n/**\n * Tokenize a string for search matching.\n * Lowercase, strip @, split on /_- and whitespace.\n */\nfunction tokenize(str: string): string[] {\n\treturn str\n\t\t.toLowerCase()\n\t\t.replace(/@/g, \"\")\n\t\t.split(/[/_\\-\\s]+/)\n\t\t.filter(Boolean);\n}\n\n/**\n * Resolve an input string to a qualified repo key in a map.\n *\n * @param input - Accepts github.com:owner/repo, owner/repo, or repo name\n * @param map - A global or project map\n * @returns The matching qualified name or null\n */\nexport function resolveRepoKey(input: string, map: GlobalMap | ProjectMap): string | null {\n\tconst { provider, fullName, repoName } = normalizeInput(input);\n\tconst keys = Object.keys(map.repos);\n\n\tif (provider) {\n\t\tconst qualifiedKey = `${provider}:${fullName}`;\n\t\tif (keys.includes(qualifiedKey)) {\n\t\t\treturn qualifiedKey;\n\t\t}\n\t}\n\n\tfor (const key of keys) {\n\t\tconst keyFullName = key.includes(\":\") ? key.split(\":\")[1] : key;\n\t\tif (keyFullName?.toLowerCase() === fullName) {\n\t\t\treturn key;\n\t\t}\n\t}\n\n\tfor (const key of keys) {\n\t\tconst keyRepoName = key.split(\"/\").pop()?.toLowerCase();\n\t\tif (keyRepoName === repoName) {\n\t\t\treturn key;\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Get a map entry for a repo, preferring project map if available.\n *\n * @param input - Repo identifier (github.com:owner/repo, owner/repo, or repo)\n * @param options - Options for lookup\n * @returns Entry with scope and qualified name, or null if not found\n */\nexport function getMapEntry(input: string, options: GetMapEntryOptions = {}): MapEntry | null {\n\tconst { preferProject = true, cwd = process.cwd() } = options;\n\n\tconst projectMap = preferProject ? readProjectMapSafe(cwd) : null;\n\tconst globalMap = readGlobalMapSafe();\n\n\tif (projectMap) {\n\t\tconst key = resolveRepoKey(input, projectMap);\n\t\tif (key && projectMap.repos[key]) {\n\t\t\treturn {\n\t\t\t\tscope: \"project\",\n\t\t\t\tqualifiedName: key,\n\t\t\t\tentry: projectMap.repos[key],\n\t\t\t};\n\t\t}\n\t}\n\n\tif (globalMap) {\n\t\tconst key = resolveRepoKey(input, globalMap);\n\t\tif (key && globalMap.repos[key]) {\n\t\t\treturn {\n\t\t\t\tscope: \"global\",\n\t\t\t\tqualifiedName: key,\n\t\t\t\tentry: globalMap.repos[key],\n\t\t\t};\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Search the map for repos matching a term.\n *\n * Scoring:\n * - Exact fullName match: 100\n * - Keyword hit: 50 per keyword\n * - Partial contains in fullName: 25\n * - Partial contains in keywords: 10\n *\n * @param term - Search term\n * @param options - Search options\n * @returns Sorted list of matches\n */\nexport function searchMap(term: string, options: SearchMapOptions = {}): SearchResult[] {\n\tconst { limit = 10 } = options;\n\n\tconst globalMap = readGlobalMapSafe();\n\tif (!globalMap) return [];\n\n\tconst termTokens = tokenize(term);\n\tconst termLower = term.toLowerCase();\n\tconst results: SearchResult[] = [];\n\n\tfor (const qualifiedName of Object.keys(globalMap.repos)) {\n\t\tconst entry = globalMap.repos[qualifiedName];\n\t\tif (!entry) continue;\n\n\t\tconst fullName = qualifiedName.includes(\":\")\n\t\t\t? (qualifiedName.split(\":\")[1] ?? qualifiedName)\n\t\t\t: qualifiedName;\n\t\tconst fullNameLower = fullName.toLowerCase();\n\t\tconst keywords = entry.keywords ?? [];\n\t\tconst keywordsLower = keywords.map((k) => k.toLowerCase());\n\n\t\tlet score = 0;\n\n\t\tif (fullNameLower === termLower) {\n\t\t\tscore += 100;\n\t\t}\n\n\t\tfor (const token of termTokens) {\n\t\t\tif (keywordsLower.includes(token)) {\n\t\t\t\tscore += 50;\n\t\t\t}\n\t\t}\n\n\t\tif (fullNameLower.includes(termLower) && score < 100) {\n\t\t\tscore += 25;\n\t\t}\n\n\t\tfor (const kw of keywordsLower) {\n\t\t\tif (kw.includes(termLower)) {\n\t\t\t\tscore += 10;\n\t\t\t}\n\t\t}\n\n\t\tconst fullNameTokens = tokenize(fullName);\n\t\tfor (const token of termTokens) {\n\t\t\tif (fullNameTokens.includes(token)) {\n\t\t\t\tscore += 30;\n\t\t\t}\n\t\t}\n\n\t\tif (score > 0) {\n\t\t\tresults.push({\n\t\t\t\tqualifiedName,\n\t\t\t\tfullName,\n\t\t\t\tlocalPath: entry.localPath,\n\t\t\t\tprimary: entry.primary,\n\t\t\t\tkeywords,\n\t\t\t\tscore,\n\t\t\t});\n\t\t}\n\t}\n\n\tresults.sort((a, b) => {\n\t\tif (b.score !== a.score) return b.score - a.score;\n\t\treturn a.fullName.localeCompare(b.fullName);\n\t});\n\n\treturn results.slice(0, limit);\n}\n\n/**\n * Get the project map path if it exists in cwd.\n */\nexport function getProjectMapPath(cwd: string = process.cwd()): string | null {\n\tconst mapPath = resolve(cwd, \".offworld/map.json\");\n\treturn existsSync(mapPath) ? mapPath : null;\n}\n","/**\n * Authentication utilities for offworld CLI\n */\n\nimport { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport { z } from \"zod\";\nimport { WorkOSTokenResponseSchema } from \"@offworld/types\";\nimport { Paths } from \"./paths\";\n\nconst AuthDataSchema = z.object({\n\ttoken: z.string(),\n\texpiresAt: z.string().optional(),\n\tworkosId: z.string().optional(),\n\trefreshToken: z.string().optional(),\n\temail: z.string().optional(),\n});\n\nexport interface AuthData {\n\ttoken: string;\n\texpiresAt?: string;\n\tworkosId?: string;\n\trefreshToken?: string;\n\temail?: string;\n}\n\n/** Authentication status */\nexport interface AuthStatus {\n\tisLoggedIn: boolean;\n\temail?: string;\n\tworkosId?: string;\n\texpiresAt?: string;\n}\n\nexport class AuthError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"AuthError\";\n\t}\n}\n\nexport class NotLoggedInError extends AuthError {\n\tconstructor(message = \"Not logged in. Please run 'ow auth login' first.\") {\n\t\tsuper(message);\n\t\tthis.name = \"NotLoggedInError\";\n\t}\n}\n\nexport class TokenExpiredError extends AuthError {\n\tconstructor(message = \"Session expired. Please run 'ow auth login' again.\") {\n\t\tsuper(message);\n\t\tthis.name = \"TokenExpiredError\";\n\t}\n}\n\nfunction extractJwtExpiration(token: string): string | undefined {\n\ttry {\n\t\tconst parts = token.split(\".\");\n\t\tif (parts.length !== 3) return undefined;\n\n\t\tconst payload = parts[1];\n\t\tif (!payload) return undefined;\n\n\t\tconst decoded = JSON.parse(Buffer.from(payload, \"base64\").toString(\"utf-8\"));\n\t\tif (typeof decoded.exp !== \"number\") return undefined;\n\n\t\treturn new Date(decoded.exp * 1000).toISOString();\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport function getAuthPath(): string {\n\treturn Paths.authFile;\n}\n\nexport function saveAuthData(data: AuthData): void {\n\tconst authPath = getAuthPath();\n\tconst authDir = dirname(authPath);\n\n\tif (!existsSync(authDir)) {\n\t\tmkdirSync(authDir, { recursive: true });\n\t}\n\n\twriteFileSync(authPath, JSON.stringify(data, null, 2), \"utf-8\");\n\tchmodSync(authPath, 0o600);\n}\n\n/**\n * Loads authentication data from ~/.local/share/offworld/auth.json\n * Returns null if file doesn't exist or is invalid\n */\nexport function loadAuthData(): AuthData | null {\n\tconst authPath = getAuthPath();\n\n\tif (!existsSync(authPath)) {\n\t\treturn null;\n\t}\n\n\ttry {\n\t\tconst content = readFileSync(authPath, \"utf-8\");\n\t\tconst json = JSON.parse(content);\n\t\tconst parsed = AuthDataSchema.safeParse(json);\n\n\t\tif (!parsed.success) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn parsed.data;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Clears stored authentication data\n * @returns true if auth file was deleted, false if it didn't exist\n */\nexport function clearAuthData(): boolean {\n\tconst authPath = getAuthPath();\n\n\tif (!existsSync(authPath)) {\n\t\treturn false;\n\t}\n\n\ttry {\n\t\tunlinkSync(authPath);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport async function getToken(): Promise<string> {\n\tconst data = loadAuthData();\n\n\tif (!data) {\n\t\tthrow new NotLoggedInError();\n\t}\n\n\tlet expiresAtStr = data.expiresAt;\n\tif (!expiresAtStr) {\n\t\texpiresAtStr = extractJwtExpiration(data.token);\n\t\tif (expiresAtStr) {\n\t\t\tdata.expiresAt = expiresAtStr;\n\t\t\tsaveAuthData(data);\n\t\t}\n\t}\n\n\tif (expiresAtStr) {\n\t\tconst expiresAt = new Date(expiresAtStr);\n\t\tconst now = new Date();\n\t\tconst oneMinute = 60 * 1000;\n\n\t\tif (expiresAt <= now) {\n\t\t\tif (data.refreshToken) {\n\t\t\t\ttry {\n\t\t\t\t\tconst refreshed = await refreshAccessToken();\n\t\t\t\t\treturn refreshed.token;\n\t\t\t\t} catch {\n\t\t\t\t\tthrow new TokenExpiredError();\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new TokenExpiredError();\n\t\t}\n\n\t\tif (expiresAt.getTime() - now.getTime() < oneMinute) {\n\t\t\tif (data.refreshToken) {\n\t\t\t\ttry {\n\t\t\t\t\tconst refreshed = await refreshAccessToken();\n\t\t\t\t\treturn refreshed.token;\n\t\t\t\t} catch {\n\t\t\t\t\treturn data.token;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn data.token;\n}\n\n/**\n * Gets the current authentication token, or null if not logged in\n * Does not throw errors\n */\nexport async function getTokenOrNull(): Promise<string | null> {\n\ttry {\n\t\treturn await getToken();\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nexport async function isLoggedIn(): Promise<boolean> {\n\treturn (await getTokenOrNull()) !== null;\n}\n\nexport async function getAuthStatus(): Promise<AuthStatus> {\n\tconst data = loadAuthData();\n\n\tif (!data) {\n\t\treturn { isLoggedIn: false };\n\t}\n\n\t// Extract expiration from JWT if not already saved (mirrors getToken() logic)\n\tlet expiresAtStr = data.expiresAt;\n\tif (!expiresAtStr) {\n\t\texpiresAtStr = extractJwtExpiration(data.token);\n\t\tif (expiresAtStr) {\n\t\t\tdata.expiresAt = expiresAtStr;\n\t\t\tsaveAuthData(data);\n\t\t}\n\t}\n\n\tif (expiresAtStr) {\n\t\tconst expiresAt = new Date(expiresAtStr);\n\t\tconst now = new Date();\n\t\tconst oneMinute = 60 * 1000;\n\n\t\t// Token already expired - attempt refresh\n\t\tif (expiresAt <= now) {\n\t\t\tif (data.refreshToken) {\n\t\t\t\ttry {\n\t\t\t\t\tconst refreshed = await refreshAccessToken();\n\t\t\t\t\treturn {\n\t\t\t\t\t\tisLoggedIn: true,\n\t\t\t\t\t\temail: refreshed.email,\n\t\t\t\t\t\tworkosId: refreshed.workosId,\n\t\t\t\t\t\texpiresAt: refreshed.expiresAt,\n\t\t\t\t\t};\n\t\t\t\t} catch {\n\t\t\t\t\treturn { isLoggedIn: false };\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn { isLoggedIn: false };\n\t\t}\n\n\t\t// Proactive refresh: token expires within 1 minute\n\t\tif (expiresAt.getTime() - now.getTime() < oneMinute) {\n\t\t\tif (data.refreshToken) {\n\t\t\t\ttry {\n\t\t\t\t\tconst refreshed = await refreshAccessToken();\n\t\t\t\t\treturn {\n\t\t\t\t\t\tisLoggedIn: true,\n\t\t\t\t\t\temail: refreshed.email,\n\t\t\t\t\t\tworkosId: refreshed.workosId,\n\t\t\t\t\t\texpiresAt: refreshed.expiresAt,\n\t\t\t\t\t};\n\t\t\t\t} catch {\n\t\t\t\t\t// Refresh failed, but token still valid - return current data\n\t\t\t\t\treturn {\n\t\t\t\t\t\tisLoggedIn: true,\n\t\t\t\t\t\temail: data.email,\n\t\t\t\t\t\tworkosId: data.workosId,\n\t\t\t\t\t\texpiresAt: expiresAtStr,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tisLoggedIn: true,\n\t\temail: data.email,\n\t\tworkosId: data.workosId,\n\t\texpiresAt: expiresAtStr,\n\t};\n}\n\nconst WORKOS_API = \"https://api.workos.com\";\n\n// Production WorkOS client ID - dev can override via WORKOS_CLIENT_ID env var\nconst PRODUCTION_WORKOS_CLIENT_ID = \"client_01KFAD76TNGN02AP96982HG35E\";\n\nfunction getWorkosClientId(): string {\n\treturn process.env.WORKOS_CLIENT_ID ?? PRODUCTION_WORKOS_CLIENT_ID;\n}\n\nexport async function refreshAccessToken(): Promise<AuthData> {\n\tconst data = loadAuthData();\n\n\tif (!data?.refreshToken) {\n\t\tthrow new AuthError(\"No refresh token available. Please log in again.\");\n\t}\n\n\ttry {\n\t\tconst response = await fetch(`${WORKOS_API}/user_management/authenticate`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n\t\t\tbody: new URLSearchParams({\n\t\t\t\tgrant_type: \"refresh_token\",\n\t\t\t\trefresh_token: data.refreshToken,\n\t\t\t\tclient_id: getWorkosClientId(),\n\t\t\t}),\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tconst error = await response.text();\n\t\t\tthrow new AuthError(`Token refresh failed: ${error}`);\n\t\t}\n\n\t\tconst json = await response.json();\n\t\tconst tokenData = WorkOSTokenResponseSchema.parse(json);\n\n\t\tconst newAuthData: AuthData = {\n\t\t\ttoken: tokenData.access_token,\n\t\t\temail: tokenData.user.email,\n\t\t\tworkosId: tokenData.user.id,\n\t\t\trefreshToken: tokenData.refresh_token,\n\t\t\texpiresAt: tokenData.expires_at\n\t\t\t\t? new Date(tokenData.expires_at * 1000).toISOString()\n\t\t\t\t: extractJwtExpiration(tokenData.access_token),\n\t\t};\n\n\t\tsaveAuthData(newAuthData);\n\t\treturn newAuthData;\n\t} catch (error) {\n\t\tif (error instanceof AuthError) throw error;\n\t\tthrow new AuthError(\n\t\t\t`Failed to refresh token: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n\t\t);\n\t}\n}\n","/**\n * Agent Registry & Auto-Detection\n *\n * Centralized registry of supported AI coding agents with their\n * skill directory locations and detection functions.\n */\n\nimport { existsSync } from \"node:fs\";\nimport type { Agent } from \"@offworld/types\";\nimport { expandTilde } from \"./paths\";\n\nexport interface AgentConfig {\n\t/** Agent identifier (matches AgentSchema enum) */\n\tname: Agent;\n\t/** Human-readable name for display */\n\tdisplayName: string;\n\t/** Project-level skill directory (relative path) */\n\tskillsDir: string;\n\t/** User-level skill directory (absolute with ~) */\n\tglobalSkillsDir: string;\n\t/** Check if this agent is installed on the system */\n\tdetectInstalled: () => boolean;\n}\n\nexport const agents: Record<Agent, AgentConfig> = {\n\topencode: {\n\t\tname: \"opencode\",\n\t\tdisplayName: \"OpenCode\",\n\t\tskillsDir: \".opencode/skills\",\n\t\tglobalSkillsDir: \"~/.config/opencode/skills\",\n\t\tdetectInstalled: () => existsSync(expandTilde(\"~/.config/opencode\")),\n\t},\n\t\"claude-code\": {\n\t\tname: \"claude-code\",\n\t\tdisplayName: \"Claude Code\",\n\t\tskillsDir: \".claude/skills\",\n\t\tglobalSkillsDir: \"~/.claude/skills\",\n\t\tdetectInstalled: () => existsSync(expandTilde(\"~/.claude\")),\n\t},\n\tcodex: {\n\t\tname: \"codex\",\n\t\tdisplayName: \"Codex (OpenAI)\",\n\t\tskillsDir: \".codex/skills\",\n\t\tglobalSkillsDir: \"~/.codex/skills\",\n\t\tdetectInstalled: () => existsSync(expandTilde(\"~/.codex\")),\n\t},\n\tamp: {\n\t\tname: \"amp\",\n\t\tdisplayName: \"Amp\",\n\t\tskillsDir: \".agents/skills\",\n\t\tglobalSkillsDir: \"~/.config/agents/skills\",\n\t\tdetectInstalled: () => existsSync(expandTilde(\"~/.config/amp\")),\n\t},\n\tantigravity: {\n\t\tname: \"antigravity\",\n\t\tdisplayName: \"Antigravity\",\n\t\tskillsDir: \".agent/skills\",\n\t\tglobalSkillsDir: \"~/.gemini/antigravity/skills\",\n\t\tdetectInstalled: () => existsSync(expandTilde(\"~/.gemini/antigravity\")),\n\t},\n\tcursor: {\n\t\tname: \"cursor\",\n\t\tdisplayName: \"Cursor\",\n\t\tskillsDir: \".cursor/skills\",\n\t\tglobalSkillsDir: \"~/.cursor/skills\",\n\t\tdetectInstalled: () => existsSync(expandTilde(\"~/.cursor\")),\n\t},\n};\n\n/**\n * Detect which agents are installed on the system.\n * Checks for the existence of each agent's config directory.\n *\n * @returns Array of installed agent identifiers\n */\nexport function detectInstalledAgents(): Agent[] {\n\tconst installed: Agent[] = [];\n\n\tfor (const config of Object.values(agents)) {\n\t\tif (config.detectInstalled()) {\n\t\t\tinstalled.push(config.name);\n\t\t}\n\t}\n\n\treturn installed;\n}\n\n/**\n * Get the configuration for a specific agent.\n *\n * @param type - Agent identifier\n * @returns AgentConfig for the specified agent\n */\nexport function getAgentConfig(type: Agent): AgentConfig {\n\treturn agents[type];\n}\n\n/**\n * Get all agent configurations as an array.\n *\n * @returns Array of all agent configurations\n */\nexport function getAllAgentConfigs(): AgentConfig[] {\n\treturn Object.values(agents);\n}\n","/**\n * Dependency name to GitHub repo resolution:\n * 1. Parse repo from dependency spec (git/https/github shorthand)\n * 2. Query npm registry for repository.url\n * 3. Fall back to FALLBACK_MAPPINGS for packages missing repository field\n * 4. Return unknown (caller handles)\n */\n\nimport { NpmPackageResponseSchema } from \"@offworld/types\";\n\nexport type ResolvedDep = {\n\tdep: string;\n\trepo: string | null;\n\tsource: \"spec\" | \"npm\" | \"fallback\" | \"unknown\";\n};\n\nexport interface ResolveDependencyRepoOptions {\n\tallowNpm?: boolean;\n\tnpmTimeoutMs?: number;\n}\n\nconst DEFAULT_NPM_FETCH_TIMEOUT_MS = 5000;\n\n/**\n * Fallback mappings for packages where npm registry doesn't have repository.url.\n * Only add packages here that genuinely don't have the field set.\n */\nexport const FALLBACK_MAPPINGS: Record<string, string> = {\n\t\"@convex-dev/react-query\": \"get-convex/convex-react-query\",\n\t\"@opencode-ai/sdk\": \"anomalyco/opencode-sdk-js\",\n};\n\n/**\n * Parse GitHub repo from various git URL formats.\n * Handles:\n * - git+https://github.com/owner/repo.git\n * - https://github.com/owner/repo\n * - git://github.com/owner/repo.git\n * - https://github.com/owner/repo/tree/main\n * - git@github.com:owner/repo.git\n * - github:owner/repo\n */\nfunction parseGitHubUrl(url: string): string | null {\n\tconst cleaned = url\n\t\t.trim()\n\t\t.replace(/^git\\+/, \"\")\n\t\t.split(\"#\")[0]\n\t\t?.split(\"?\")[0]\n\t\t?.trim();\n\n\tif (!cleaned) return null;\n\n\tconst patterns = [\n\t\t/github\\.com[/:]([\\w.-]+)\\/([\\w.-]+)(?:\\.git)?(?:[/?#].*)?$/,\n\t\t/^github:([\\w.-]+)\\/([\\w.-]+)(?:[/?#].*)?$/,\n\t];\n\n\tfor (const pattern of patterns) {\n\t\tconst match = cleaned.match(pattern);\n\t\tif (match) {\n\t\t\tconst owner = match[1];\n\t\t\tconst repo = match[2]?.replace(/\\.git$/i, \"\");\n\t\t\tif (!owner || !repo) return null;\n\t\t\treturn `${owner}/${repo}`;\n\t\t}\n\t}\n\n\treturn null;\n}\n\nfunction resolveFromSpec(spec?: string): string | null {\n\tif (!spec) return null;\n\n\tconst trimmed = spec.trim();\n\tif (!trimmed) return null;\n\n\tconst isGitSpec =\n\t\ttrimmed.startsWith(\"github:\") ||\n\t\ttrimmed.startsWith(\"git+\") ||\n\t\ttrimmed.startsWith(\"git://\") ||\n\t\ttrimmed.startsWith(\"https://\") ||\n\t\ttrimmed.startsWith(\"http://\") ||\n\t\ttrimmed.startsWith(\"ssh://\") ||\n\t\ttrimmed.startsWith(\"git@\");\n\n\tif (!isGitSpec) return null;\n\n\treturn parseGitHubUrl(trimmed);\n}\n\nasync function fetchNpmPackage(\n\tpackageName: string,\n\ttimeoutMs = DEFAULT_NPM_FETCH_TIMEOUT_MS,\n): Promise<{\n\trepository?: string | { url?: string };\n\tkeywords?: string[];\n} | null> {\n\tconst controller = new AbortController();\n\tconst timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n\n\ttry {\n\t\tconst res = await fetch(`https://registry.npmjs.org/${packageName}`, {\n\t\t\tsignal: controller.signal,\n\t\t});\n\t\tif (!res.ok) return null;\n\n\t\tconst json = await res.json();\n\t\tconst result = NpmPackageResponseSchema.safeParse(json);\n\t\tif (!result.success) return null;\n\n\t\treturn result.data;\n\t} catch {\n\t\treturn null;\n\t} finally {\n\t\tclearTimeout(timeoutId);\n\t}\n}\n\n/**\n * Fallback to npm registry to extract repository.url.\n * Returns null if package not found, no repo field, or not a GitHub repo.\n */\nexport async function resolveFromNpm(\n\tpackageName: string,\n\ttimeoutMs?: number,\n): Promise<string | null> {\n\tconst pkg = await fetchNpmPackage(packageName, timeoutMs);\n\tif (!pkg?.repository) return null;\n\n\tconst repoUrl = typeof pkg.repository === \"string\" ? pkg.repository : pkg.repository.url;\n\tif (!repoUrl) return null;\n\n\treturn parseGitHubUrl(repoUrl);\n}\n\nexport async function getNpmKeywords(packageName: string): Promise<string[]> {\n\tconst pkg = await fetchNpmPackage(packageName);\n\tif (!pkg?.keywords || pkg.keywords.length === 0) return [];\n\n\tconst seen = new Set<string>();\n\tfor (const keyword of pkg.keywords) {\n\t\tconst normalized = keyword.trim().toLowerCase();\n\t\tif (normalized.length < 2) continue;\n\t\tseen.add(normalized);\n\t}\n\n\treturn Array.from(seen);\n}\n\n/**\n * Resolution order:\n * 1. Parse repo from dependency spec (git/https/github shorthand)\n * 2. Query npm registry for repository.url\n * 3. Check FALLBACK_MAPPINGS for packages missing repository field\n * 4. Return unknown\n */\nexport async function resolveDependencyRepo(\n\tdep: string,\n\tspec?: string,\n\toptions: ResolveDependencyRepoOptions = {},\n): Promise<ResolvedDep> {\n\tconst { allowNpm = true, npmTimeoutMs } = options;\n\n\tconst specRepo = resolveFromSpec(spec);\n\tif (specRepo) {\n\t\treturn { dep, repo: specRepo, source: \"spec\" };\n\t}\n\n\tif (allowNpm) {\n\t\tconst npmRepo = await resolveFromNpm(dep, npmTimeoutMs);\n\t\tif (npmRepo) {\n\t\t\treturn { dep, repo: npmRepo, source: \"npm\" };\n\t\t}\n\n\t\tif (dep in FALLBACK_MAPPINGS) {\n\t\t\treturn { dep, repo: FALLBACK_MAPPINGS[dep] ?? null, source: \"fallback\" };\n\t\t}\n\t}\n\n\treturn { dep, repo: null, source: \"unknown\" };\n}\n","import {\n\tmkdirSync,\n\twriteFileSync,\n\treadFileSync,\n\tlstatSync,\n\tunlinkSync,\n\trmSync,\n\tsymlinkSync,\n\texistsSync,\n} from \"node:fs\";\nimport { join } from \"node:path\";\nimport { z } from \"zod\";\nimport { loadConfig, toMetaDirName, toReferenceFileName } from \"./config.js\";\nimport { agents } from \"./agents.js\";\nimport { expandTilde, Paths } from \"./paths.js\";\nimport { readGlobalMap, writeGlobalMap } from \"./index-manager.js\";\nimport { getNpmKeywords } from \"./dep-mappings.js\";\n\nconst PackageJsonNameSchema = z.object({\n\tname: z.string().optional(),\n});\n\nexport interface InstallReferenceMeta {\n\t/** ISO timestamp when the reference was generated */\n\treferenceUpdatedAt: string;\n\t/** Git commit SHA at time of generation */\n\tcommitSha: string;\n\t/** SDK version used for generation */\n\tversion: string;\n}\n\nfunction normalizeKeywords(values: string[]): string[] {\n\tconst seen = new Set<string>();\n\tfor (const value of values) {\n\t\tconst normalized = value.trim().toLowerCase();\n\t\tif (normalized.length < 2) continue;\n\t\tseen.add(normalized);\n\t}\n\treturn Array.from(seen);\n}\n\nfunction deriveMinimalKeywords(fullName: string): string[] {\n\tconst normalized = fullName.trim().toLowerCase();\n\tif (!normalized) return [];\n\n\tconst repoName = normalized.split(\"/\").pop() ?? normalized;\n\treturn normalizeKeywords([normalized, repoName]);\n}\n\nfunction getPackageName(localPath: string): string | null {\n\tconst packageJsonPath = join(localPath, \"package.json\");\n\tif (!existsSync(packageJsonPath)) return null;\n\n\ttry {\n\t\tconst content = readFileSync(packageJsonPath, \"utf-8\");\n\t\tconst json = JSON.parse(content);\n\t\tconst parsed = PackageJsonNameSchema.safeParse(json);\n\t\tif (!parsed.success || !parsed.data.name) return null;\n\t\treturn parsed.data.name;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Resolve keywords with npm-first strategy.\n * - npm package: package name + npm keywords\n * - non-npm package: minimal repo-derived keywords\n */\nexport async function resolveReferenceKeywords(\n\tfullName: string,\n\tlocalPath: string,\n): Promise<string[]> {\n\tconst packageName = getPackageName(localPath);\n\tif (!packageName) {\n\t\treturn deriveMinimalKeywords(fullName);\n\t}\n\n\tconst npmKeywords = await getNpmKeywords(packageName);\n\tif (npmKeywords.length > 0) {\n\t\treturn normalizeKeywords([packageName, ...npmKeywords]);\n\t}\n\n\treturn normalizeKeywords([packageName]);\n}\n\n/**\n * Ensure a symlink exists, removing any existing file/directory at the path\n */\nfunction ensureSymlink(target: string, linkPath: string): void {\n\ttry {\n\t\tconst stat = lstatSync(linkPath);\n\t\tif (stat.isSymbolicLink()) {\n\t\t\tunlinkSync(linkPath);\n\t\t} else if (stat.isDirectory()) {\n\t\t\trmSync(linkPath, { recursive: true });\n\t\t} else {\n\t\t\tunlinkSync(linkPath);\n\t\t}\n\t} catch {}\n\n\tconst linkDir = join(linkPath, \"..\");\n\tmkdirSync(linkDir, { recursive: true });\n\tsymlinkSync(target, linkPath, \"dir\");\n}\n\n/**\n * Static template for the global SKILL.md file.\n * This is the single routing skill that all agents see.\n */\nconst GLOBAL_SKILL_TEMPLATE = `---\nname: offworld\ndescription: Routes queries to Offworld reference files. Find and read per-repo references for dependency knowledge.\nallowed-tools: Bash(ow:*) Read\n---\n\n# Offworld Reference Router\n\nUse \\`ow\\` to locate and read Offworld reference files for dependencies.\n\n## What This Does\n\n- Finds references for libraries and repos\n- Returns paths for reference files and local clones\n- Helps you read the right context fast\n\n## When to Use\n\n- You need docs or patterns for a dependency\n- You want the verified reference instead of web search\n- You are about to work inside a repo clone\n\n## Installation and Setup\n\nIf Offworld CLI or opencode is missing, read \\`references/installation.md\\` in this skill directory and follow it.\n\n## Usage\n\n**Find a reference:**\n\\`\\`\\`bash\now map search <term> # search by name or keyword\now map show <repo> # get info for specific repo\n\\`\\`\\`\n\n**Get paths for tools:**\n\\`\\`\\`bash\now map show <repo> --ref # reference file path (use with Read)\now map show <repo> --path # clone directory path\n\\`\\`\\`\n\n**Example workflow:**\n\\`\\`\\`bash\n# 1. Find the repo\now map search zod\n\n# 2. Get reference path\now map show colinhacks/zod --ref\n# Output: /Users/.../.local/share/offworld/skill/offworld/references/colinhacks-zod.md\n\n# 3. Read the reference with the path from step 2\n\\`\\`\\`\n\n## If Reference Not Found\n\n\\`\\`\\`bash\now pull <owner/repo> # clone + generate reference\now project init # scan project deps, install references\n\\`\\`\\`\n\n## Notes\n\n- Project map (\\`.offworld/map.json\\`) takes precedence over global map when present\n- Reference files are markdown with API docs, patterns, best practices\n- Clone paths useful for exploring source code after reading reference\n\n## Additional Resources\n\n- Docs: https://offworld.sh/cli\n`;\n\nconst INSTALLATION_REFERENCE_TEMPLATE = `# Offworld Installation\n\nUse this when Offworld CLI or opencode is not installed.\n\n## 1) Check opencode\n\n\\`\\`\\`bash\nopencode --version\n\\`\\`\\`\n\nIf missing:\n\n\\`\\`\\`bash\ncurl -fsSL https://opencode.ai/install | bash\n\\`\\`\\`\n\n## 2) Check Offworld CLI\n\n\\`\\`\\`bash\now --version\n\\`\\`\\`\n\nIf missing:\n\n\\`\\`\\`bash\ncurl -fsSL https://offworld.sh/install | bash\n\\`\\`\\`\n\n## 3) Initialize Offworld (non-interactive)\n\n\\`\\`\\`bash\now init --yes --agents \"<agent-list>\" --repo-root \"<clone-dir>\" --model \"<provider/model>\"\n\\`\\`\\`\n\nExample:\n\n\\`\\`\\`bash\now init --yes --agents \"opencode,codex\" --repo-root \"~/ow\" --model \"anthropic/claude-sonnet-4-20250514\"\n\\`\\`\\`\n\n## 4) Initialize current project\n\n\\`\\`\\`bash\now project init --yes --all\n\\`\\`\\`\n\n## 5) Verify\n\n\\`\\`\\`bash\now config show\now list\n\\`\\`\\`\n`;\n\n/**\n * Ensures the global SKILL.md exists and symlinks the offworld/ directory to all agent skill directories.\n *\n * Creates:\n * - ~/.local/share/offworld/skill/offworld/SKILL.md (static routing template)\n * - ~/.local/share/offworld/skill/offworld/assets/ (for map.json)\n * - ~/.local/share/offworld/skill/offworld/references/ (for reference files)\n * - Symlinks entire offworld/ directory to each agent's skill directory\n */\nexport function installGlobalSkill(): void {\n\tconst config = loadConfig();\n\n\tmkdirSync(Paths.offworldSkillDir, { recursive: true });\n\tmkdirSync(Paths.offworldAssetsDir, { recursive: true });\n\tmkdirSync(Paths.offworldReferencesDir, { recursive: true });\n\n\tconst skillPath = join(Paths.offworldSkillDir, \"SKILL.md\");\n\tif (!existsSync(skillPath)) {\n\t\twriteFileSync(skillPath, GLOBAL_SKILL_TEMPLATE, \"utf-8\");\n\t}\n\n\tconst installationReferencePath = join(Paths.offworldReferencesDir, \"installation.md\");\n\tif (!existsSync(installationReferencePath)) {\n\t\twriteFileSync(installationReferencePath, INSTALLATION_REFERENCE_TEMPLATE, \"utf-8\");\n\t}\n\n\tconst configuredAgents = config.agents ?? [];\n\tfor (const agentName of configuredAgents) {\n\t\tconst agentConfig = agents[agentName];\n\t\tif (agentConfig) {\n\t\t\tconst agentSkillDir = expandTilde(join(agentConfig.globalSkillsDir, \"offworld\"));\n\t\t\tensureSymlink(Paths.offworldSkillDir, agentSkillDir);\n\t\t}\n\t}\n}\n\n/**\n * Install a reference file for a specific repository.\n *\n * Creates:\n * - ~/.local/share/offworld/skill/offworld/references/{owner-repo}.md\n * - ~/.local/share/offworld/meta/{owner-repo}/meta.json\n * - Updates global map with reference info\n *\n * @param qualifiedName - Qualified key for map storage (e.g., \"github.com:owner/repo\" or \"local:name\")\n * @param fullName - Full repo name for file naming (e.g., \"owner/repo\")\n * @param localPath - Absolute path to the cloned repository\n * @param referenceContent - The generated reference markdown content\n * @param meta - Metadata about the generation (referenceUpdatedAt, commitSha, version)\n * @param keywords - Optional array of keywords for search/routing\n */\nexport function installReference(\n\tqualifiedName: string,\n\tfullName: string,\n\tlocalPath: string,\n\treferenceContent: string,\n\tmeta: InstallReferenceMeta,\n\tkeywords?: string[],\n): void {\n\tinstallGlobalSkill();\n\n\tconst referenceFileName = toReferenceFileName(fullName);\n\tconst metaDirName = toMetaDirName(fullName);\n\n\tconst referencePath = join(Paths.offworldReferencesDir, referenceFileName);\n\tmkdirSync(Paths.offworldReferencesDir, { recursive: true });\n\twriteFileSync(referencePath, referenceContent, \"utf-8\");\n\n\tconst metaDir = join(Paths.metaDir, metaDirName);\n\tmkdirSync(metaDir, { recursive: true });\n\tconst metaJson = JSON.stringify(meta, null, 2);\n\twriteFileSync(join(metaDir, \"meta.json\"), metaJson, \"utf-8\");\n\n\tconst map = readGlobalMap();\n\tconst existingEntry = map.repos[qualifiedName];\n\tconst legacyProviderMap: Record<string, string> = {\n\t\t\"github.com\": \"github\",\n\t\t\"gitlab.com\": \"gitlab\",\n\t\t\"bitbucket.org\": \"bitbucket\",\n\t};\n\tconst [host] = qualifiedName.split(\":\");\n\tconst legacyProvider = host ? legacyProviderMap[host] : undefined;\n\tconst legacyQualifiedName = legacyProvider ? `${legacyProvider}:${fullName}` : undefined;\n\tconst legacyEntry = legacyQualifiedName ? map.repos[legacyQualifiedName] : undefined;\n\n\tconst references = [...(existingEntry?.references ?? []), ...(legacyEntry?.references ?? [])];\n\tif (!references.includes(referenceFileName)) {\n\t\treferences.push(referenceFileName);\n\t}\n\n\tconst derivedKeywords =\n\t\tkeywords && keywords.length > 0 ? keywords : deriveMinimalKeywords(fullName);\n\n\tmap.repos[qualifiedName] = {\n\t\tlocalPath,\n\t\treferences,\n\t\tprimary: referenceFileName,\n\t\tkeywords: normalizeKeywords(derivedKeywords),\n\t\tupdatedAt: new Date().toISOString(),\n\t};\n\n\tif (legacyQualifiedName && legacyQualifiedName in map.repos) {\n\t\tdelete map.repos[legacyQualifiedName];\n\t}\n\n\twriteGlobalMap(map);\n}\n","/**\n * Dependency manifest parsing for multiple package ecosystems\n */\n\nimport { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport type { Dirent } from \"node:fs\";\nimport { join } from \"node:path\";\n\nexport type ManifestType = \"npm\" | \"python\" | \"rust\" | \"go\" | \"unknown\";\n\nexport interface Dependency {\n\tname: string;\n\tversion?: string;\n\tdev: boolean;\n}\n\nconst DEFAULT_IGNORED_DIRS = new Set([\n\t\".git\",\n\t\".offworld\",\n\t\".turbo\",\n\t\"build\",\n\t\"dist\",\n\t\"node_modules\",\n\t\"out\",\n]);\n\n/**\n * Detects the manifest type in a directory\n */\nexport function detectManifestType(dir: string): ManifestType {\n\tif (existsSync(join(dir, \"package.json\"))) return \"npm\";\n\tif (existsSync(join(dir, \"pyproject.toml\"))) return \"python\";\n\tif (existsSync(join(dir, \"Cargo.toml\"))) return \"rust\";\n\tif (existsSync(join(dir, \"go.mod\"))) return \"go\";\n\tif (existsSync(join(dir, \"requirements.txt\"))) return \"python\";\n\treturn \"unknown\";\n}\n\n/**\n * Parses dependencies from manifest files\n */\nexport function parseDependencies(dir: string): Dependency[] {\n\tconst type = detectManifestType(dir);\n\n\tswitch (type) {\n\t\tcase \"npm\":\n\t\t\treturn parseNpmDependencies(dir);\n\t\tcase \"python\":\n\t\t\treturn existsSync(join(dir, \"pyproject.toml\"))\n\t\t\t\t? parsePyprojectToml(join(dir, \"pyproject.toml\"))\n\t\t\t\t: parseRequirementsTxt(join(dir, \"requirements.txt\"));\n\t\tcase \"rust\":\n\t\t\treturn parseCargoToml(join(dir, \"Cargo.toml\"));\n\t\tcase \"go\":\n\t\t\treturn parseGoMod(join(dir, \"go.mod\"));\n\t\tdefault:\n\t\t\treturn [];\n\t}\n}\n\nfunction parseNpmDependencies(dir: string): Dependency[] {\n\tconst rootPath = join(dir, \"package.json\");\n\tconst rootDeps = parsePackageJson(rootPath);\n\tconst workspaceDeps = parseWorkspaceDependencies(dir);\n\treturn mergeDependencies(rootDeps, workspaceDeps).sort((a, b) => a.name.localeCompare(b.name));\n}\n\nfunction parseWorkspaceDependencies(dir: string): Dependency[] {\n\tconst workspacePatterns = getWorkspacePatterns(dir);\n\tif (workspacePatterns.length === 0) return [];\n\n\tconst packageJsonPaths = resolveWorkspacePackageJsonPaths(dir, workspacePatterns);\n\tconst deps: Dependency[] = [];\n\tfor (const path of packageJsonPaths) {\n\t\tdeps.push(...parsePackageJson(path));\n\t}\n\n\treturn mergeDependencies([], deps);\n}\n\nfunction getWorkspacePatterns(dir: string): string[] {\n\tconst patterns = new Set<string>();\n\n\tconst packageJsonPath = join(dir, \"package.json\");\n\tif (existsSync(packageJsonPath)) {\n\t\tconst rootJson = readJson(packageJsonPath);\n\t\tconst workspaces = rootJson?.workspaces;\n\t\tif (Array.isArray(workspaces)) {\n\t\t\tfor (const pattern of workspaces) {\n\t\t\t\tif (typeof pattern === \"string\") patterns.add(pattern);\n\t\t\t}\n\t\t} else if (workspaces && typeof workspaces === \"object\") {\n\t\t\tconst packagesField = (workspaces as { packages?: unknown }).packages;\n\t\t\tif (Array.isArray(packagesField)) {\n\t\t\t\tfor (const pattern of packagesField) {\n\t\t\t\t\tif (typeof pattern === \"string\") patterns.add(pattern);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tconst pnpmWorkspacePath = existsSync(join(dir, \"pnpm-workspace.yaml\"))\n\t\t? join(dir, \"pnpm-workspace.yaml\")\n\t\t: existsSync(join(dir, \"pnpm-workspace.yml\"))\n\t\t\t? join(dir, \"pnpm-workspace.yml\")\n\t\t\t: null;\n\n\tif (pnpmWorkspacePath) {\n\t\tfor (const pattern of parsePnpmWorkspacePackages(pnpmWorkspacePath)) {\n\t\t\tpatterns.add(pattern);\n\t\t}\n\t}\n\n\treturn Array.from(patterns);\n}\n\nfunction resolveWorkspacePackageJsonPaths(dir: string, patterns: string[]): string[] {\n\tconst includePatterns = patterns.filter((pattern) => !pattern.startsWith(\"!\"));\n\tconst excludePatterns = patterns\n\t\t.filter((pattern) => pattern.startsWith(\"!\"))\n\t\t.map((pattern) => pattern.slice(1));\n\n\tif (includePatterns.length === 0) return [];\n\n\tconst includeRegexes = includePatterns.map(patternToRegex);\n\tconst excludeRegexes = excludePatterns.map(patternToRegex);\n\n\tconst matches: string[] = [];\n\tconst directories = walkDirectories(dir);\n\n\tfor (const relativePath of directories) {\n\t\tif (!includeRegexes.some((regex) => regex.test(relativePath))) continue;\n\t\tif (excludeRegexes.some((regex) => regex.test(relativePath))) continue;\n\n\t\tconst packageJsonPath = join(dir, relativePath, \"package.json\");\n\t\tif (existsSync(packageJsonPath)) {\n\t\t\tmatches.push(packageJsonPath);\n\t\t}\n\t}\n\n\treturn Array.from(new Set(matches));\n}\n\nfunction walkDirectories(root: string): string[] {\n\tconst results: string[] = [];\n\tconst stack: string[] = [\"\"];\n\n\twhile (stack.length > 0) {\n\t\tconst relativePath = stack.pop();\n\t\tconst currentPath = relativePath ? join(root, relativePath) : root;\n\n\t\tlet entries: Dirent[];\n\t\ttry {\n\t\t\tentries = readdirSync(currentPath, { withFileTypes: true }) as Dirent[];\n\t\t} catch {\n\t\t\tcontinue;\n\t\t}\n\n\t\tfor (const entry of entries) {\n\t\t\tif (!entry.isDirectory()) continue;\n\t\t\tif (DEFAULT_IGNORED_DIRS.has(entry.name)) continue;\n\n\t\t\tconst nextRelative = relativePath ? `${relativePath}/${entry.name}` : entry.name;\n\t\t\tresults.push(nextRelative);\n\t\t\tstack.push(nextRelative);\n\t\t}\n\t}\n\n\treturn results;\n}\n\nfunction patternToRegex(pattern: string): RegExp {\n\tlet normalized = pattern.trim().replace(/\\\\/g, \"/\");\n\tif (normalized.startsWith(\"./\")) normalized = normalized.slice(2);\n\tif (normalized.endsWith(\"/\")) normalized = normalized.slice(0, -1);\n\n\tconst escaped = normalized.replace(/[.+^${}()|[\\]\\\\*]/g, \"\\\\$&\");\n\tconst withGlob = escaped.replace(/\\\\\\*\\\\\\*/g, \".*\").replace(/\\\\\\*/g, \"[^/]+\");\n\n\treturn new RegExp(`^${withGlob}$`);\n}\n\nfunction parsePnpmWorkspacePackages(path: string): string[] {\n\ttry {\n\t\tconst content = readFileSync(path, \"utf-8\");\n\t\tconst lines = content.split(\"\\n\");\n\t\tconst patterns: string[] = [];\n\t\tlet inPackages = false;\n\n\t\tfor (const line of lines) {\n\t\t\tconst trimmed = line.trim();\n\t\t\tif (!trimmed || trimmed.startsWith(\"#\")) continue;\n\n\t\t\tif (/^packages\\s*:/.test(trimmed)) {\n\t\t\t\tinPackages = true;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (!inPackages) continue;\n\n\t\t\tconst entryMatch = trimmed.match(/^-\\s*(.+)$/);\n\t\t\tif (entryMatch?.[1]) {\n\t\t\t\tconst value = entryMatch[1].trim().replace(/^['\"]|['\"]$/g, \"\");\n\t\t\t\tif (value) patterns.push(value);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (!line.startsWith(\" \") && !line.startsWith(\"\\t\")) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn patterns;\n\t} catch {\n\t\treturn [];\n\t}\n}\n\nfunction readJson(path: string): Record<string, unknown> | null {\n\ttry {\n\t\tconst content = readFileSync(path, \"utf-8\");\n\t\treturn JSON.parse(content) as Record<string, unknown>;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction mergeDependencies(base: Dependency[], incoming: Dependency[]): Dependency[] {\n\tconst map = new Map<string, Dependency>();\n\n\tfor (const dep of [...base, ...incoming]) {\n\t\tconst existing = map.get(dep.name);\n\t\tif (!existing) {\n\t\t\tmap.set(dep.name, { ...dep });\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst dev = existing.dev && dep.dev;\n\t\tconst version = existing.version ?? dep.version;\n\t\tmap.set(dep.name, { name: dep.name, version, dev });\n\t}\n\n\treturn Array.from(map.values());\n}\n\n/**\n * Parse package.json dependencies\n */\nfunction parsePackageJson(path: string): Dependency[] {\n\ttry {\n\t\tconst content = readFileSync(path, \"utf-8\");\n\t\tconst pkg = JSON.parse(content);\n\t\tconst deps: Dependency[] = [];\n\n\t\tif (pkg.dependencies && typeof pkg.dependencies === \"object\") {\n\t\t\tfor (const [name, version] of Object.entries(pkg.dependencies)) {\n\t\t\t\tdeps.push({ name, version: version as string, dev: false });\n\t\t\t}\n\t\t}\n\n\t\tif (pkg.devDependencies && typeof pkg.devDependencies === \"object\") {\n\t\t\tfor (const [name, version] of Object.entries(pkg.devDependencies)) {\n\t\t\t\tdeps.push({ name, version: version as string, dev: true });\n\t\t\t}\n\t\t}\n\n\t\tif (pkg.peerDependencies && typeof pkg.peerDependencies === \"object\") {\n\t\t\tfor (const [name, version] of Object.entries(pkg.peerDependencies)) {\n\t\t\t\tdeps.push({ name, version: version as string, dev: false });\n\t\t\t}\n\t\t}\n\n\t\tif (pkg.optionalDependencies && typeof pkg.optionalDependencies === \"object\") {\n\t\t\tfor (const [name, version] of Object.entries(pkg.optionalDependencies)) {\n\t\t\t\tdeps.push({ name, version: version as string, dev: false });\n\t\t\t}\n\t\t}\n\n\t\treturn deps;\n\t} catch {\n\t\treturn [];\n\t}\n}\n\n/**\n * Parse pyproject.toml dependencies\n */\nfunction parsePyprojectToml(path: string): Dependency[] {\n\ttry {\n\t\tconst content = readFileSync(path, \"utf-8\");\n\t\tconst deps: Dependency[] = [];\n\n\t\tconst depsSection = content.match(/\\[project\\.dependencies\\]([\\s\\S]*?)(?=\\[|$)/);\n\t\tif (!depsSection?.[1]) return [];\n\n\t\tconst lines = depsSection[1].split(\"\\n\");\n\t\tfor (const line of lines) {\n\t\t\tconst match = line.match(/[\"']([a-zA-Z0-9_-]+)(?:[>=<~!]+([^\"']+))?[\"']/);\n\t\t\tif (match?.[1]) {\n\t\t\t\tdeps.push({\n\t\t\t\t\tname: match[1],\n\t\t\t\t\tversion: match[2]?.trim(),\n\t\t\t\t\tdev: false,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn deps;\n\t} catch {\n\t\treturn [];\n\t}\n}\n\n/**\n * Parse Cargo.toml dependencies\n */\nfunction parseCargoToml(path: string): Dependency[] {\n\ttry {\n\t\tconst content = readFileSync(path, \"utf-8\");\n\t\tconst deps: Dependency[] = [];\n\n\t\tconst depsSection = content.match(/\\[dependencies\\]([\\s\\S]*?)(?=\\[|$)/);\n\t\tif (!depsSection?.[1]) return [];\n\n\t\tconst lines = depsSection[1].split(\"\\n\");\n\t\tfor (const line of lines) {\n\t\t\tconst simpleMatch = line.match(/^([a-zA-Z0-9_-]+)\\s*=\\s*\"([^\"]+)\"/);\n\t\t\tconst tableMatch = line.match(/^([a-zA-Z0-9_-]+)\\s*=\\s*{.*version\\s*=\\s*\"([^\"]+)\"/);\n\n\t\t\tif (simpleMatch?.[1] && simpleMatch[2]) {\n\t\t\t\tdeps.push({ name: simpleMatch[1], version: simpleMatch[2], dev: false });\n\t\t\t} else if (tableMatch?.[1] && tableMatch[2]) {\n\t\t\t\tdeps.push({ name: tableMatch[1], version: tableMatch[2], dev: false });\n\t\t\t}\n\t\t}\n\n\t\treturn deps;\n\t} catch {\n\t\treturn [];\n\t}\n}\n\n/**\n * Parse go.mod dependencies\n */\nfunction parseGoMod(path: string): Dependency[] {\n\ttry {\n\t\tconst content = readFileSync(path, \"utf-8\");\n\t\tconst deps: Dependency[] = [];\n\n\t\tconst requireSection = content.match(/require\\s*\\(([\\s\\S]*?)\\)/);\n\t\tif (!requireSection?.[1]) {\n\t\t\tconst singleRequire = content.match(/require\\s+([^\\s]+)\\s+([^\\s]+)/);\n\t\t\tif (singleRequire?.[1] && singleRequire[2]) {\n\t\t\t\tdeps.push({\n\t\t\t\t\tname: singleRequire[1],\n\t\t\t\t\tversion: singleRequire[2],\n\t\t\t\t\tdev: false,\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn deps;\n\t\t}\n\n\t\tconst lines = requireSection[1].split(\"\\n\");\n\t\tfor (const line of lines) {\n\t\t\tconst match = line.match(/^\\s*([^\\s]+)\\s+([^\\s]+)/);\n\t\t\tif (match?.[1] && match[2]) {\n\t\t\t\tdeps.push({ name: match[1], version: match[2], dev: false });\n\t\t\t}\n\t\t}\n\n\t\treturn deps;\n\t} catch {\n\t\treturn [];\n\t}\n}\n\n/**\n * Parse requirements.txt dependencies\n */\nfunction parseRequirementsTxt(path: string): Dependency[] {\n\ttry {\n\t\tconst content = readFileSync(path, \"utf-8\");\n\t\tconst deps: Dependency[] = [];\n\n\t\tconst lines = content.split(\"\\n\");\n\t\tfor (const line of lines) {\n\t\t\tconst trimmed = line.trim();\n\t\t\tif (!trimmed || trimmed.startsWith(\"#\")) continue;\n\n\t\t\tconst match = trimmed.match(/^([a-zA-Z0-9_-]+)(?:[>=<~!]+(.+))?/);\n\t\t\tif (match?.[1]) {\n\t\t\t\tdeps.push({\n\t\t\t\t\tname: match[1],\n\t\t\t\t\tversion: match[2]?.trim(),\n\t\t\t\t\tdev: false,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn deps;\n\t} catch {\n\t\treturn [];\n\t}\n}\n","/**\n * Reference matching utilities for dependency resolution\n *\n * Maps dependencies to their reference status (installed, remote, generate, unknown)\n */\n\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { toReferenceFileName } from \"./config.js\";\nimport { Paths } from \"./paths.js\";\nimport type { ResolvedDep } from \"./dep-mappings.js\";\n\nexport type ReferenceStatus = \"installed\" | \"remote\" | \"generate\" | \"unknown\";\n\nexport interface ReferenceMatch {\n\t/** Dependency name */\n\tdep: string;\n\t/** GitHub repo (owner/repo) or null if unknown */\n\trepo: string | null;\n\t/** Reference availability status */\n\tstatus: ReferenceStatus;\n\t/** Resolution source: 'spec' | 'npm' | 'fallback' | 'unknown' */\n\tsource: \"spec\" | \"npm\" | \"fallback\" | \"unknown\";\n}\n\n/**\n * Check if a reference is installed locally.\n * A reference is considered installed if {owner-repo}.md exists in offworld/references/.\n *\n * @param repo - Repo name in owner/repo format\n * @returns true if reference is installed locally\n */\nexport function isReferenceInstalled(repo: string): boolean {\n\tconst referenceFileName = toReferenceFileName(repo);\n\tconst referencePath = join(Paths.offworldReferencesDir, referenceFileName);\n\treturn existsSync(referencePath);\n}\n\n/**\n * Match dependencies to their reference availability status.\n *\n * Status logic:\n * - installed: {owner-repo}.md exists in offworld/references/\n * - remote: Reference exists on offworld.sh (quick pull)\n * - generate: Has valid GitHub repo but needs AI generation (slow, uses tokens)\n * - unknown: No GitHub repo found\n *\n * @param resolvedDeps - Array of resolved dependencies with repo info\n * @returns Array of reference matches with status\n */\nexport function matchDependenciesToReferences(resolvedDeps: ResolvedDep[]): ReferenceMatch[] {\n\treturn resolvedDeps.map((dep) => {\n\t\tif (!dep.repo) {\n\t\t\treturn {\n\t\t\t\tdep: dep.dep,\n\t\t\t\trepo: null,\n\t\t\t\tstatus: \"unknown\",\n\t\t\t\tsource: dep.source,\n\t\t\t};\n\t\t}\n\n\t\tif (isReferenceInstalled(dep.repo)) {\n\t\t\treturn {\n\t\t\t\tdep: dep.dep,\n\t\t\t\trepo: dep.repo,\n\t\t\t\tstatus: \"installed\",\n\t\t\t\tsource: dep.source,\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tdep: dep.dep,\n\t\t\trepo: dep.repo,\n\t\t\tstatus: \"generate\",\n\t\t\tsource: dep.source,\n\t\t};\n\t});\n}\n\n/**\n * Match dependencies to their reference availability status with remote check.\n * This is async because it checks the remote server for each dependency.\n *\n * Status logic:\n * - installed: {owner-repo}.md exists in offworld/references/\n * - remote: Reference exists on offworld.sh (quick pull)\n * - generate: Has valid GitHub repo but needs AI generation (slow, uses tokens)\n * - unknown: No GitHub repo found\n *\n * @param resolvedDeps - Array of resolved dependencies with repo info\n * @returns Promise of array of reference matches with status\n */\nexport async function matchDependenciesToReferencesWithRemoteCheck(\n\tresolvedDeps: ResolvedDep[],\n): Promise<ReferenceMatch[]> {\n\tconst { checkRemote } = await import(\"./sync.js\");\n\tconst repoStatus = new Map<string, ReferenceStatus>();\n\n\tconst remoteChecks: Promise<void>[] = [];\n\tfor (const dep of resolvedDeps) {\n\t\tif (!dep.repo || repoStatus.has(dep.repo)) continue;\n\n\t\tif (isReferenceInstalled(dep.repo)) {\n\t\t\trepoStatus.set(dep.repo, \"installed\");\n\t\t\tcontinue;\n\t\t}\n\n\t\trepoStatus.set(dep.repo, \"generate\");\n\t\tremoteChecks.push(\n\t\t\t(async () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst remote = await checkRemote(dep.repo!);\n\t\t\t\t\tif (remote.exists) {\n\t\t\t\t\t\trepoStatus.set(dep.repo!, \"remote\");\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Network error - keep generate status\n\t\t\t\t}\n\t\t\t})(),\n\t\t);\n\t}\n\n\tawait Promise.all(remoteChecks);\n\n\treturn resolvedDeps.map((dep) => {\n\t\tif (!dep.repo) {\n\t\t\treturn {\n\t\t\t\tdep: dep.dep,\n\t\t\t\trepo: null,\n\t\t\t\tstatus: \"unknown\" as const,\n\t\t\t\tsource: dep.source,\n\t\t\t};\n\t\t}\n\n\t\tconst status = repoStatus.get(dep.repo) ?? \"generate\";\n\t\treturn {\n\t\t\tdep: dep.dep,\n\t\t\trepo: dep.repo,\n\t\t\tstatus,\n\t\t\tsource: dep.source,\n\t\t};\n\t});\n}\n","import { existsSync, statSync, readdirSync, rmSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { updateRepo, GitError } from \"./clone.js\";\nimport { readGlobalMap, removeGlobalMapEntry, upsertGlobalMapEntry } from \"./index-manager.js\";\nimport { loadConfig, getRepoRoot } from \"./config.js\";\nimport { Paths } from \"./paths.js\";\n\nexport interface RepoStatusSummary {\n\ttotal: number;\n\twithReference: number;\n\tmissing: number;\n\tdiskBytes: number;\n}\n\nexport interface RepoStatusOptions {\n\tonProgress?: (current: number, total: number, repo: string) => void;\n}\n\nexport interface UpdateAllOptions {\n\tpattern?: string;\n\tdryRun?: boolean;\n\tonProgress?: (\n\t\trepo: string,\n\t\tstatus: \"updating\" | \"updated\" | \"skipped\" | \"error\",\n\t\tmessage?: string,\n\t) => void;\n}\n\nexport interface UpdateAllResult {\n\tupdated: string[];\n\tskipped: string[];\n\terrors: Array<{ repo: string; error: string }>;\n}\n\nexport interface PruneOptions {\n\tdryRun?: boolean;\n\tonProgress?: (repo: string, reason: string) => void;\n}\n\nexport interface PruneResult {\n\tremovedFromIndex: string[];\n\torphanedDirs: string[];\n}\n\nexport interface GcOptions {\n\tolderThanDays?: number;\n\twithoutReference?: boolean;\n\tdryRun?: boolean;\n\tonProgress?: (repo: string, reason: string, sizeBytes?: number) => void;\n}\n\nexport interface GcResult {\n\tremoved: Array<{ repo: string; reason: string; sizeBytes: number }>;\n\tfreedBytes: number;\n}\n\nfunction getDirSize(dirPath: string): number {\n\tif (!existsSync(dirPath)) return 0;\n\n\tlet size = 0;\n\ttry {\n\t\tconst entries = readdirSync(dirPath, { withFileTypes: true });\n\t\tfor (const entry of entries) {\n\t\t\tconst fullPath = join(dirPath, entry.name);\n\t\t\tif (entry.isDirectory()) {\n\t\t\t\tsize += getDirSize(fullPath);\n\t\t\t} else if (entry.isFile()) {\n\t\t\t\ttry {\n\t\t\t\t\tsize += statSync(fullPath).size;\n\t\t\t\t} catch {}\n\t\t\t}\n\t\t}\n\t} catch {}\n\treturn size;\n}\n\nfunction getLastAccessTime(dirPath: string): Date | null {\n\tif (!existsSync(dirPath)) return null;\n\n\tlet latestTime: Date | null = null;\n\ttry {\n\t\tconst stat = statSync(dirPath);\n\t\tlatestTime = stat.mtime;\n\n\t\tconst fetchHead = join(dirPath, \".git\", \"FETCH_HEAD\");\n\t\tif (existsSync(fetchHead)) {\n\t\t\tconst fetchStat = statSync(fetchHead);\n\t\t\tif (!latestTime || fetchStat.mtime > latestTime) {\n\t\t\t\tlatestTime = fetchStat.mtime;\n\t\t\t}\n\t\t}\n\t} catch {}\n\treturn latestTime;\n}\n\nfunction matchesPattern(name: string, pattern: string): boolean {\n\tif (!pattern || pattern === \"*\") return true;\n\n\tconst regex = new RegExp(\n\t\t\"^\" +\n\t\t\tpattern\n\t\t\t\t.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\")\n\t\t\t\t.replace(/\\*/g, \".*\")\n\t\t\t\t.replace(/\\?/g, \".\") +\n\t\t\t\"$\",\n\t\t\"i\",\n\t);\n\treturn regex.test(name);\n}\n\nconst yieldToEventLoop = () => new Promise<void>((resolve) => setImmediate(resolve));\n\nexport async function getRepoStatus(options: RepoStatusOptions = {}): Promise<RepoStatusSummary> {\n\tconst { onProgress } = options;\n\tconst map = readGlobalMap();\n\tconst qualifiedNames = Object.keys(map.repos);\n\tconst total = qualifiedNames.length;\n\n\tlet withReference = 0;\n\tlet missing = 0;\n\tlet diskBytes = 0;\n\n\tfor (let i = 0; i < qualifiedNames.length; i++) {\n\t\tconst qualifiedName = qualifiedNames[i]!;\n\t\tconst entry = map.repos[qualifiedName]!;\n\t\tonProgress?.(i + 1, total, qualifiedName);\n\n\t\tawait yieldToEventLoop();\n\n\t\tconst exists = existsSync(entry.localPath);\n\n\t\tif (!exists) {\n\t\t\tmissing++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (entry.references.length > 0) {\n\t\t\twithReference++;\n\t\t}\n\n\t\tdiskBytes += getDirSize(entry.localPath);\n\t}\n\n\treturn {\n\t\ttotal,\n\t\twithReference,\n\t\tmissing,\n\t\tdiskBytes,\n\t};\n}\n\nexport async function updateAllRepos(options: UpdateAllOptions = {}): Promise<UpdateAllResult> {\n\tconst { pattern, dryRun = false, onProgress } = options;\n\n\tconst map = readGlobalMap();\n\tconst qualifiedNames = Object.keys(map.repos);\n\tconst updated: string[] = [];\n\tconst skipped: string[] = [];\n\tconst errors: Array<{ repo: string; error: string }> = [];\n\n\tfor (const qualifiedName of qualifiedNames) {\n\t\tconst entry = map.repos[qualifiedName]!;\n\n\t\tif (pattern && !matchesPattern(qualifiedName, pattern)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (!existsSync(entry.localPath)) {\n\t\t\tskipped.push(qualifiedName);\n\t\t\tonProgress?.(qualifiedName, \"skipped\", \"missing on disk\");\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (dryRun) {\n\t\t\tupdated.push(qualifiedName);\n\t\t\tonProgress?.(qualifiedName, \"updated\", \"would update\");\n\t\t\tcontinue;\n\t\t}\n\n\t\tonProgress?.(qualifiedName, \"updating\");\n\t\ttry {\n\t\t\tconst result = await updateRepo(qualifiedName);\n\t\t\tif (result.updated) {\n\t\t\t\tupdated.push(qualifiedName);\n\t\t\t\tonProgress?.(\n\t\t\t\t\tqualifiedName,\n\t\t\t\t\t\"updated\",\n\t\t\t\t\t`${result.previousSha.slice(0, 7)} → ${result.currentSha.slice(0, 7)}`,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tskipped.push(qualifiedName);\n\t\t\t\tonProgress?.(qualifiedName, \"skipped\", \"already up to date\");\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof GitError ? err.message : String(err);\n\t\t\terrors.push({ repo: qualifiedName, error: message });\n\t\t\tonProgress?.(qualifiedName, \"error\", message);\n\t\t}\n\t}\n\n\treturn { updated, skipped, errors };\n}\n\nexport async function pruneRepos(options: PruneOptions = {}): Promise<PruneResult> {\n\tconst { dryRun = false, onProgress } = options;\n\n\tconst map = readGlobalMap();\n\tconst qualifiedNames = Object.keys(map.repos);\n\tconst removedFromIndex: string[] = [];\n\tconst orphanedDirs: string[] = [];\n\n\tfor (const qualifiedName of qualifiedNames) {\n\t\tconst entry = map.repos[qualifiedName]!;\n\t\tawait yieldToEventLoop();\n\n\t\tif (!existsSync(entry.localPath)) {\n\t\t\tonProgress?.(qualifiedName, \"missing on disk\");\n\t\t\tremovedFromIndex.push(qualifiedName);\n\n\t\t\tif (!dryRun) {\n\t\t\t\tremoveGlobalMapEntry(qualifiedName);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst config = loadConfig();\n\tconst repoRoot = getRepoRoot(config);\n\n\tif (existsSync(repoRoot)) {\n\t\tconst indexedPaths = new Set(Object.values(map.repos).map((r) => r.localPath));\n\n\t\ttry {\n\t\t\tconst providers = readdirSync(repoRoot, { withFileTypes: true });\n\t\t\tfor (const provider of providers) {\n\t\t\t\tif (!provider.isDirectory()) continue;\n\t\t\t\tconst providerPath = join(repoRoot, provider.name);\n\n\t\t\t\tconst owners = readdirSync(providerPath, { withFileTypes: true });\n\t\t\t\tfor (const owner of owners) {\n\t\t\t\t\tif (!owner.isDirectory()) continue;\n\t\t\t\t\tconst ownerPath = join(providerPath, owner.name);\n\n\t\t\t\t\tconst repoNames = readdirSync(ownerPath, { withFileTypes: true });\n\t\t\t\t\tfor (const repoName of repoNames) {\n\t\t\t\t\t\tawait yieldToEventLoop();\n\n\t\t\t\t\t\tif (!repoName.isDirectory()) continue;\n\t\t\t\t\t\tconst repoPath = join(ownerPath, repoName.name);\n\n\t\t\t\t\t\tif (!existsSync(join(repoPath, \".git\"))) continue;\n\n\t\t\t\t\t\tif (!indexedPaths.has(repoPath)) {\n\t\t\t\t\t\t\tconst fullName = `${owner.name}/${repoName.name}`;\n\t\t\t\t\t\t\tonProgress?.(fullName, \"not in map\");\n\t\t\t\t\t\t\torphanedDirs.push(repoPath);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {}\n\t}\n\n\treturn { removedFromIndex, orphanedDirs };\n}\n\nexport async function gcRepos(options: GcOptions = {}): Promise<GcResult> {\n\tconst { olderThanDays, withoutReference = false, dryRun = false, onProgress } = options;\n\n\tconst map = readGlobalMap();\n\tconst qualifiedNames = Object.keys(map.repos);\n\tconst removed: Array<{ repo: string; reason: string; sizeBytes: number }> = [];\n\tlet freedBytes = 0;\n\n\tconst now = new Date();\n\tconst cutoffDate = olderThanDays\n\t\t? new Date(now.getTime() - olderThanDays * 24 * 60 * 60 * 1000)\n\t\t: null;\n\n\tfor (const qualifiedName of qualifiedNames) {\n\t\tconst entry = map.repos[qualifiedName]!;\n\t\tawait yieldToEventLoop();\n\n\t\tif (!existsSync(entry.localPath)) continue;\n\n\t\tlet shouldRemove = false;\n\t\tlet reason = \"\";\n\n\t\tif (cutoffDate) {\n\t\t\tconst lastAccess = getLastAccessTime(entry.localPath);\n\t\t\tif (lastAccess && lastAccess < cutoffDate) {\n\t\t\t\tshouldRemove = true;\n\t\t\t\treason = `not accessed in ${olderThanDays}+ days`;\n\t\t\t}\n\t\t}\n\n\t\tif (withoutReference && entry.references.length === 0) {\n\t\t\tshouldRemove = true;\n\t\t\treason = reason ? `${reason}, no reference` : \"no reference\";\n\t\t}\n\n\t\tif (!shouldRemove) continue;\n\n\t\tconst sizeBytes = getDirSize(entry.localPath);\n\t\tonProgress?.(qualifiedName, reason, sizeBytes);\n\n\t\tif (!dryRun) {\n\t\t\trmSync(entry.localPath, { recursive: true, force: true });\n\n\t\t\tfor (const refFile of entry.references) {\n\t\t\t\tconst refPath = join(Paths.offworldReferencesDir, refFile);\n\t\t\t\tif (existsSync(refPath)) {\n\t\t\t\t\trmSync(refPath, { force: true });\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (entry.primary) {\n\t\t\t\tconst metaDirName = entry.primary.replace(/\\.md$/, \"\");\n\t\t\t\tconst metaPath = join(Paths.metaDir, metaDirName);\n\t\t\t\tif (existsSync(metaPath)) {\n\t\t\t\t\trmSync(metaPath, { recursive: true, force: true });\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tremoveGlobalMapEntry(qualifiedName);\n\t\t}\n\n\t\tremoved.push({ repo: qualifiedName, reason, sizeBytes });\n\t\tfreedBytes += sizeBytes;\n\t}\n\n\treturn { removed, freedBytes };\n}\n\nexport interface DiscoverOptions {\n\trepoRoot?: string;\n\tdryRun?: boolean;\n\tonProgress?: (repo: string, provider: string) => void;\n}\n\nexport interface DiscoverResult {\n\tdiscovered: Array<{ fullName: string; qualifiedName: string; localPath: string }>;\n\talreadyIndexed: number;\n}\n\nexport async function discoverRepos(options: DiscoverOptions = {}): Promise<DiscoverResult> {\n\tconst { dryRun = false, onProgress } = options;\n\n\tconst config = loadConfig();\n\tconst repoRoot = options.repoRoot ?? getRepoRoot(config);\n\tconst discovered: Array<{ fullName: string; qualifiedName: string; localPath: string }> = [];\n\tlet alreadyIndexed = 0;\n\n\tif (!existsSync(repoRoot)) {\n\t\treturn { discovered, alreadyIndexed };\n\t}\n\n\tconst map = readGlobalMap();\n\tconst indexedPaths = new Set(Object.values(map.repos).map((r) => r.localPath));\n\n\ttry {\n\t\tconst providers = readdirSync(repoRoot, { withFileTypes: true });\n\t\tfor (const provider of providers) {\n\t\t\tif (!provider.isDirectory()) continue;\n\t\t\tconst providerPath = join(repoRoot, provider.name);\n\n\t\t\tconst providerHostMap: Record<string, string> = {\n\t\t\t\tgithub: \"github.com\",\n\t\t\t\tgitlab: \"gitlab.com\",\n\t\t\t\tbitbucket: \"bitbucket.org\",\n\t\t\t};\n\t\t\tconst providerHost = providerHostMap[provider.name] ?? provider.name;\n\n\t\t\tconst owners = readdirSync(providerPath, { withFileTypes: true });\n\t\t\tfor (const owner of owners) {\n\t\t\t\tif (!owner.isDirectory()) continue;\n\t\t\t\tconst ownerPath = join(providerPath, owner.name);\n\n\t\t\t\tconst repoNames = readdirSync(ownerPath, { withFileTypes: true });\n\t\t\t\tfor (const repoName of repoNames) {\n\t\t\t\t\tawait yieldToEventLoop();\n\n\t\t\t\t\tif (!repoName.isDirectory()) continue;\n\t\t\t\t\tconst repoPath = join(ownerPath, repoName.name);\n\n\t\t\t\t\tif (!existsSync(join(repoPath, \".git\"))) continue;\n\n\t\t\t\t\tif (indexedPaths.has(repoPath)) {\n\t\t\t\t\t\talreadyIndexed++;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst fullName = `${owner.name}/${repoName.name}`;\n\t\t\t\t\tconst qualifiedName = `${providerHost}:${fullName}`;\n\n\t\t\t\t\tonProgress?.(fullName, providerHost);\n\n\t\t\t\t\tif (!dryRun) {\n\t\t\t\t\t\tupsertGlobalMapEntry(qualifiedName, {\n\t\t\t\t\t\t\tlocalPath: repoPath,\n\t\t\t\t\t\t\treferences: [],\n\t\t\t\t\t\t\tprimary: \"\",\n\t\t\t\t\t\t\tkeywords: [],\n\t\t\t\t\t\t\tupdatedAt: new Date().toISOString(),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tdiscovered.push({ fullName, qualifiedName, localPath: repoPath });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} catch {}\n\n\treturn { discovered, alreadyIndexed };\n}\n","import { ModelsDevDataSchema, type ModelsDevProvider } from \"@offworld/types\";\n\nconst MODELS_DEV_URL = \"https://models.dev/api.json\";\n\n/**\n * Simplified provider info for CLI display\n */\nexport interface ProviderInfo {\n\tid: string;\n\tname: string;\n\tenv: string[];\n}\n\n/**\n * Simplified model info for CLI display\n */\nexport interface ModelInfo {\n\tid: string;\n\tname: string;\n\treasoning: boolean;\n\texperimental?: boolean;\n\tstatus?: \"alpha\" | \"beta\" | \"deprecated\";\n}\n\n/**\n * Full provider with models for CLI display\n */\nexport interface ProviderWithModels extends ProviderInfo {\n\tmodels: ModelInfo[];\n}\n\nlet cachedData: Record<string, ModelsDevProvider> | null = null;\nlet cacheTime = 0;\nconst CACHE_TTL_MS = 5 * 60 * 1000;\n\n/**\n * Fetch raw data from models.dev with caching\n */\nasync function fetchModelsDevData(): Promise<Record<string, ModelsDevProvider>> {\n\tconst now = Date.now();\n\tif (cachedData && now - cacheTime < CACHE_TTL_MS) {\n\t\treturn cachedData;\n\t}\n\n\tconst res = await fetch(MODELS_DEV_URL, {\n\t\tsignal: AbortSignal.timeout(10_000),\n\t});\n\n\tif (!res.ok) {\n\t\tthrow new Error(`Failed to fetch models.dev: ${res.status} ${res.statusText}`);\n\t}\n\n\tconst json = await res.json();\n\tconst parsed = ModelsDevDataSchema.safeParse(json);\n\tif (!parsed.success) {\n\t\tthrow new Error(`Invalid models.dev response: ${parsed.error.message}`);\n\t}\n\tcachedData = parsed.data;\n\tcacheTime = now;\n\treturn cachedData;\n}\n\n/**\n * List all available providers from models.dev\n */\nexport async function listProviders(): Promise<ProviderInfo[]> {\n\tconst data = await fetchModelsDevData();\n\n\treturn Object.values(data)\n\t\t.map((p) => ({\n\t\t\tid: p.id,\n\t\t\tname: p.name,\n\t\t\tenv: p.env ?? [],\n\t\t}))\n\t\t.sort((a, b) => a.name.localeCompare(b.name));\n}\n\n/**\n * Get a specific provider with all its models\n */\nexport async function getProvider(providerId: string): Promise<ProviderWithModels | null> {\n\tconst data = await fetchModelsDevData();\n\tconst provider = data[providerId];\n\n\tif (!provider) {\n\t\treturn null;\n\t}\n\n\treturn {\n\t\tid: provider.id,\n\t\tname: provider.name,\n\t\tenv: provider.env ?? [],\n\t\tmodels: Object.values(provider.models)\n\t\t\t.filter((m) => m.status !== \"deprecated\")\n\t\t\t.map((m) => ({\n\t\t\t\tid: m.id,\n\t\t\t\tname: m.name,\n\t\t\t\treasoning: m.reasoning ?? false,\n\t\t\t\texperimental: m.experimental,\n\t\t\t\tstatus: m.status,\n\t\t\t}))\n\t\t\t.sort((a, b) => a.name.localeCompare(b.name)),\n\t};\n}\n\n/**\n * Get all providers with their models\n */\nexport async function listProvidersWithModels(): Promise<ProviderWithModels[]> {\n\tconst data = await fetchModelsDevData();\n\n\treturn Object.values(data)\n\t\t.map((p) => ({\n\t\t\tid: p.id,\n\t\t\tname: p.name,\n\t\t\tenv: p.env ?? [],\n\t\t\tmodels: Object.values(p.models)\n\t\t\t\t.filter((m) => m.status !== \"deprecated\")\n\t\t\t\t.map((m) => ({\n\t\t\t\t\tid: m.id,\n\t\t\t\t\tname: m.name,\n\t\t\t\t\treasoning: m.reasoning ?? false,\n\t\t\t\t\texperimental: m.experimental,\n\t\t\t\t\tstatus: m.status,\n\t\t\t\t}))\n\t\t\t\t.sort((a, b) => a.name.localeCompare(b.name)),\n\t\t}))\n\t\t.sort((a, b) => a.name.localeCompare(b.name));\n}\n\n/**\n * Validate that a provider/model combination exists\n */\nexport async function validateProviderModel(\n\tproviderId: string,\n\tmodelId: string,\n): Promise<{ valid: boolean; error?: string }> {\n\tconst provider = await getProvider(providerId);\n\n\tif (!provider) {\n\t\tconst providers = await listProviders();\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\terror: `Provider \"${providerId}\" not found. Available: ${providers\n\t\t\t\t.slice(0, 10)\n\t\t\t\t.map((p) => p.id)\n\t\t\t\t.join(\", \")}${providers.length > 10 ? \"...\" : \"\"}`,\n\t\t};\n\t}\n\n\tconst model = provider.models.find((m) => m.id === modelId);\n\tif (!model) {\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\terror: `Model \"${modelId}\" not found for provider \"${providerId}\". Available: ${provider.models\n\t\t\t\t.slice(0, 10)\n\t\t\t\t.map((m) => m.id)\n\t\t\t\t.join(\", \")}${provider.models.length > 10 ? \"...\" : \"\"}`,\n\t\t};\n\t}\n\n\treturn { valid: true };\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@offworld/sdk",
3
- "version": "0.3.5",
3
+ "version": "0.3.7",
4
4
  "description": "Core SDK for Offworld - clone repos, generate references, sync with offworld.sh",
5
5
  "keywords": [
6
6
  "ai",
@@ -77,7 +77,7 @@
77
77
  "check": "oxlint && oxfmt --write"
78
78
  },
79
79
  "dependencies": {
80
- "@offworld/types": "0.3.0",
80
+ "@offworld/types": "0.3.5",
81
81
  "xdg-basedir": "^5.1.0",
82
82
  "zod": "^4.3.6"
83
83
  },
@@ -1 +0,0 @@
1
- {"version":3,"file":"public-CWnhJJ9J.mjs","names":["GlobalMapSchema","ProjectMapSchema"],"sources":["../src/constants.ts","../src/repo-source.ts","../src/map.ts","../src/auth.ts","../src/agents.ts","../src/dep-mappings.ts","../src/reference.ts","../src/manifest.ts","../src/reference-matcher.ts","../src/repo-manager.ts","../src/models.ts"],"sourcesContent":["/**\n * SDK Constants\n */\n\n/** SDK version - must match package.json */\nexport const VERSION = \"0.3.5\";\n\n/**\n * Default patterns to ignore when scanning repositories.\n * Includes directories, binary files, IDE configs, and build outputs.\n */\nexport const DEFAULT_IGNORE_PATTERNS = [\n\t\".git\",\n\t\".git/**\",\n\t\".svn\",\n\t\".hg\",\n\n\t\"node_modules\",\n\t\"node_modules/**\",\n\t\"vendor\",\n\t\"vendor/**\",\n\t\".pnpm\",\n\t\".yarn\",\n\n\t\"dist\",\n\t\"dist/**\",\n\t\"build\",\n\t\"build/**\",\n\t\"out\",\n\t\"out/**\",\n\t\".next\",\n\t\".nuxt\",\n\t\".output\",\n\t\"target\",\n\t\"__pycache__\",\n\t\"*.pyc\",\n\n\t\".vscode\",\n\t\".vscode/**\",\n\t\".idea\",\n\t\".idea/**\",\n\t\"*.swp\",\n\t\"*.swo\",\n\t\".DS_Store\",\n\n\t\"*.jpg\",\n\t\"*.jpeg\",\n\t\"*.png\",\n\t\"*.gif\",\n\t\"*.ico\",\n\t\"*.webp\",\n\t\"*.svg\",\n\t\"*.bmp\",\n\t\"*.tiff\",\n\t\"*.mp4\",\n\t\"*.webm\",\n\t\"*.mov\",\n\t\"*.avi\",\n\t\"*.mkv\",\n\t\"*.mp3\",\n\t\"*.wav\",\n\t\"*.flac\",\n\t\"*.ogg\",\n\t\"*.pdf\",\n\t\"*.zip\",\n\t\"*.tar\",\n\t\"*.gz\",\n\t\"*.rar\",\n\t\"*.7z\",\n\t\"*.exe\",\n\t\"*.dll\",\n\t\"*.so\",\n\t\"*.dylib\",\n\t\"*.bin\",\n\t\"*.wasm\",\n\t\"*.woff\",\n\t\"*.woff2\",\n\t\"*.ttf\",\n\t\"*.eot\",\n\t\"*.otf\",\n\n\t\"package-lock.json\",\n\t\"yarn.lock\",\n\t\"pnpm-lock.yaml\",\n\t\"bun.lockb\",\n\t\"Cargo.lock\",\n\t\"Gemfile.lock\",\n\t\"poetry.lock\",\n\t\"composer.lock\",\n\t\"go.sum\",\n\n\t\"coverage\",\n\t\"coverage/**\",\n\t\".nyc_output\",\n\t\".coverage\",\n\t\"htmlcov\",\n\n\t\"*.log\",\n\t\"logs\",\n\t\"tmp\",\n\t\"temp\",\n\t\".tmp\",\n\t\".temp\",\n\t\".cache\",\n\n\t\".env\",\n\t\".env.*\",\n\t\"*.pem\",\n\t\"*.key\",\n] as const;\n","/**\n * Repository source parsing utilities\n */\n\nimport { createHash } from \"node:crypto\";\nimport { existsSync, statSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport { basename } from \"node:path\";\nimport type { GitProvider, LocalRepoSource, RemoteRepoSource, RepoSource } from \"@offworld/types\";\nimport { toReferenceFileName } from \"./config.js\";\nimport { expandTilde } from \"./paths.js\";\n\nexport class RepoSourceError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"RepoSourceError\";\n\t}\n}\n\nexport class PathNotFoundError extends RepoSourceError {\n\tconstructor(path: string) {\n\t\tsuper(`Path does not exist: ${path}`);\n\t\tthis.name = \"PathNotFoundError\";\n\t}\n}\n\nexport class NotGitRepoError extends RepoSourceError {\n\tconstructor(path: string) {\n\t\tsuper(`Directory is not a git repository: ${path}`);\n\t\tthis.name = \"NotGitRepoError\";\n\t}\n}\n\nconst PROVIDER_HOSTS: Record<string, GitProvider> = {\n\t\"github.com\": \"github\",\n\t\"gitlab.com\": \"gitlab\",\n\t\"bitbucket.org\": \"bitbucket\",\n};\n\nconst HTTPS_URL_REGEX =\n\t/^https?:\\/\\/(github\\.com|gitlab\\.com|bitbucket\\.org)\\/([^/]+)\\/([^/]+?)(?:\\.git)?$/;\nconst SSH_URL_REGEX = /^git@(github\\.com|gitlab\\.com|bitbucket\\.org):([^/]+)\\/([^/]+?)(?:\\.git)?$/;\nconst SHORT_FORMAT_REGEX = /^([^/:@]+)\\/([^/:@]+)$/;\n\n/**\n * Generates a short hash of a path for local repo identification\n */\nfunction hashPath(path: string): string {\n\treturn createHash(\"sha256\").update(path).digest(\"hex\").slice(0, 12);\n}\n\n/**\n * Builds a clone URL for a remote repository\n */\nfunction buildCloneUrl(provider: GitProvider, owner: string, repo: string): string {\n\tconst hosts: Record<GitProvider, string> = {\n\t\tgithub: \"github.com\",\n\t\tgitlab: \"gitlab.com\",\n\t\tbitbucket: \"bitbucket.org\",\n\t};\n\treturn `https://${hosts[provider]}/${owner}/${repo}.git`;\n}\n\n/**\n * Parses a remote repository from HTTPS URL format\n */\nfunction parseHttpsUrl(input: string): RemoteRepoSource | null {\n\tconst match = input.match(HTTPS_URL_REGEX);\n\tif (!match) return null;\n\n\tconst [, host, owner, repo] = match;\n\tif (!host || !owner || !repo) return null;\n\n\tconst provider = PROVIDER_HOSTS[host];\n\tif (!provider) return null;\n\n\tconst ownerLower = owner.toLowerCase();\n\tconst repoLower = repo.toLowerCase();\n\treturn {\n\t\ttype: \"remote\",\n\t\tprovider,\n\t\towner: ownerLower,\n\t\trepo: repoLower,\n\t\tfullName: `${ownerLower}/${repoLower}`,\n\t\tqualifiedName: `${host}:${ownerLower}/${repoLower}`,\n\t\tcloneUrl: buildCloneUrl(provider, ownerLower, repoLower),\n\t};\n}\n\n/**\n * Parses a remote repository from SSH URL format\n */\nfunction parseSshUrl(input: string): RemoteRepoSource | null {\n\tconst match = input.match(SSH_URL_REGEX);\n\tif (!match) return null;\n\n\tconst [, host, owner, repo] = match;\n\tif (!host || !owner || !repo) return null;\n\n\tconst provider = PROVIDER_HOSTS[host];\n\tif (!provider) return null;\n\n\tconst ownerLower = owner.toLowerCase();\n\tconst repoLower = repo.toLowerCase();\n\treturn {\n\t\ttype: \"remote\",\n\t\tprovider,\n\t\towner: ownerLower,\n\t\trepo: repoLower,\n\t\tfullName: `${ownerLower}/${repoLower}`,\n\t\tqualifiedName: `${host}:${ownerLower}/${repoLower}`,\n\t\tcloneUrl: buildCloneUrl(provider, ownerLower, repoLower),\n\t};\n}\n\n/**\n * Parses a remote repository from short format (owner/repo)\n * Defaults to GitHub as provider\n */\nfunction parseShortFormat(input: string): RemoteRepoSource | null {\n\tconst match = input.match(SHORT_FORMAT_REGEX);\n\tif (!match) return null;\n\n\tconst [, owner, repo] = match;\n\tif (!owner || !repo) return null;\n\n\tconst provider: GitProvider = \"github\";\n\tconst host = \"github.com\";\n\n\tconst ownerLower = owner.toLowerCase();\n\tconst repoLower = repo.toLowerCase();\n\treturn {\n\t\ttype: \"remote\",\n\t\tprovider,\n\t\towner: ownerLower,\n\t\trepo: repoLower,\n\t\tfullName: `${ownerLower}/${repoLower}`,\n\t\tqualifiedName: `${host}:${ownerLower}/${repoLower}`,\n\t\tcloneUrl: buildCloneUrl(provider, ownerLower, repoLower),\n\t};\n}\n\n/**\n * Parses a local repository path\n * Validates that the path exists and contains a .git directory\n */\nfunction parseLocalPath(input: string): LocalRepoSource {\n\tconst absolutePath = resolve(expandTilde(input));\n\n\tif (!existsSync(absolutePath)) {\n\t\tthrow new PathNotFoundError(absolutePath);\n\t}\n\n\tconst stats = statSync(absolutePath);\n\tif (!stats.isDirectory()) {\n\t\tthrow new RepoSourceError(`Path is not a directory: ${absolutePath}`);\n\t}\n\n\tconst gitPath = resolve(absolutePath, \".git\");\n\tif (!existsSync(gitPath)) {\n\t\tthrow new NotGitRepoError(absolutePath);\n\t}\n\n\tconst name = basename(absolutePath);\n\tconst hash = hashPath(absolutePath);\n\n\treturn {\n\t\ttype: \"local\",\n\t\tpath: absolutePath,\n\t\tname,\n\t\tqualifiedName: `local:${hash}`,\n\t};\n}\n\n/**\n * Determines if input looks like a local path\n */\nfunction isLocalPath(input: string): boolean {\n\treturn input.startsWith(\".\") || input.startsWith(\"/\") || input.startsWith(\"~\");\n}\n\n/**\n * Parses a repository input and returns a structured RepoSource\n *\n * Supported formats:\n * - owner/repo (short format, defaults to GitHub)\n * - https://github.com/owner/repo\n * - https://gitlab.com/owner/repo\n * - https://bitbucket.org/owner/repo\n * - git@github.com:owner/repo.git (SSH format)\n * - . (current directory as local repo)\n * - /absolute/path (local repo)\n *\n * @throws PathNotFoundError if local path doesn't exist\n * @throws NotGitRepoError if local path is not a git repository\n * @throws RepoSourceError for other parsing failures\n */\nexport function parseRepoInput(input: string): RepoSource {\n\tconst trimmed = input.trim();\n\n\tconst httpsResult = parseHttpsUrl(trimmed);\n\tif (httpsResult) return httpsResult;\n\n\tconst sshResult = parseSshUrl(trimmed);\n\tif (sshResult) return sshResult;\n\n\tif (isLocalPath(trimmed)) {\n\t\treturn parseLocalPath(trimmed);\n\t}\n\n\tconst shortResult = parseShortFormat(trimmed);\n\tif (shortResult) return shortResult;\n\n\tthrow new RepoSourceError(\n\t\t`Unable to parse repository input: ${input}. ` +\n\t\t\t\"Expected formats: owner/repo, https://github.com/owner/repo, git@github.com:owner/repo.git, or a local path\",\n\t);\n}\n\nexport function getReferenceFileNameForSource(source: RepoSource): string {\n\tif (source.type === \"remote\") {\n\t\treturn toReferenceFileName(source.fullName);\n\t}\n\treturn toReferenceFileName(source.name);\n}\n","/**\n * Map query helpers for fast routing without reading full map.json\n */\n\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { resolve } from \"node:path\";\nimport type {\n\tGlobalMap,\n\tGlobalMapRepoEntry,\n\tProjectMap,\n\tProjectMapRepoEntry,\n} from \"@offworld/types\";\nimport { GlobalMapSchema, ProjectMapSchema } from \"@offworld/types/schemas\";\nimport { Paths } from \"./paths.js\";\n\nexport interface MapEntry {\n\tscope: \"project\" | \"global\";\n\tqualifiedName: string;\n\tentry: GlobalMapRepoEntry | ProjectMapRepoEntry;\n}\n\nexport interface SearchResult {\n\tqualifiedName: string;\n\tfullName: string;\n\tlocalPath: string;\n\tprimary: string;\n\tkeywords: string[];\n\tscore: number;\n}\n\nexport interface GetMapEntryOptions {\n\tpreferProject?: boolean;\n\tcwd?: string;\n}\n\nexport interface SearchMapOptions {\n\tlimit?: number;\n\tcwd?: string;\n}\n\nfunction readGlobalMapSafe(): GlobalMap | null {\n\tconst mapPath = Paths.offworldGlobalMapPath;\n\tif (!existsSync(mapPath)) return null;\n\n\ttry {\n\t\tconst content = readFileSync(mapPath, \"utf-8\");\n\t\treturn GlobalMapSchema.parse(JSON.parse(content));\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction readProjectMapSafe(cwd: string): ProjectMap | null {\n\tconst mapPath = resolve(cwd, \".offworld/map.json\");\n\tif (!existsSync(mapPath)) return null;\n\n\ttry {\n\t\tconst content = readFileSync(mapPath, \"utf-8\");\n\t\treturn ProjectMapSchema.parse(JSON.parse(content));\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Normalize input to match against repo keys.\n * Accepts: github.com:owner/repo, owner/repo, repo\n */\nfunction normalizeInput(input: string): { provider?: string; fullName: string; repoName: string } {\n\tconst trimmed = input.trim().toLowerCase();\n\n\tif (trimmed.includes(\":\")) {\n\t\tconst parts = trimmed.split(\":\", 2);\n\t\tconst provider = parts[0];\n\t\tconst fullName = parts[1] ?? \"\";\n\t\tconst repoName = fullName.split(\"/\").pop() ?? fullName;\n\t\treturn { provider, fullName, repoName };\n\t}\n\n\tif (trimmed.includes(\"/\")) {\n\t\tconst repoName = trimmed.split(\"/\").pop() ?? trimmed;\n\t\treturn { fullName: trimmed, repoName };\n\t}\n\n\treturn { fullName: trimmed, repoName: trimmed };\n}\n\n/**\n * Tokenize a string for search matching.\n * Lowercase, strip @, split on /_- and whitespace.\n */\nfunction tokenize(str: string): string[] {\n\treturn str\n\t\t.toLowerCase()\n\t\t.replace(/@/g, \"\")\n\t\t.split(/[/_\\-\\s]+/)\n\t\t.filter(Boolean);\n}\n\n/**\n * Resolve an input string to a qualified repo key in a map.\n *\n * @param input - Accepts github.com:owner/repo, owner/repo, or repo name\n * @param map - A global or project map\n * @returns The matching qualified name or null\n */\nexport function resolveRepoKey(input: string, map: GlobalMap | ProjectMap): string | null {\n\tconst { provider, fullName, repoName } = normalizeInput(input);\n\tconst keys = Object.keys(map.repos);\n\n\tif (provider) {\n\t\tconst qualifiedKey = `${provider}:${fullName}`;\n\t\tif (keys.includes(qualifiedKey)) {\n\t\t\treturn qualifiedKey;\n\t\t}\n\t}\n\n\tfor (const key of keys) {\n\t\tconst keyFullName = key.includes(\":\") ? key.split(\":\")[1] : key;\n\t\tif (keyFullName?.toLowerCase() === fullName) {\n\t\t\treturn key;\n\t\t}\n\t}\n\n\tfor (const key of keys) {\n\t\tconst keyRepoName = key.split(\"/\").pop()?.toLowerCase();\n\t\tif (keyRepoName === repoName) {\n\t\t\treturn key;\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Get a map entry for a repo, preferring project map if available.\n *\n * @param input - Repo identifier (github.com:owner/repo, owner/repo, or repo)\n * @param options - Options for lookup\n * @returns Entry with scope and qualified name, or null if not found\n */\nexport function getMapEntry(input: string, options: GetMapEntryOptions = {}): MapEntry | null {\n\tconst { preferProject = true, cwd = process.cwd() } = options;\n\n\tconst projectMap = preferProject ? readProjectMapSafe(cwd) : null;\n\tconst globalMap = readGlobalMapSafe();\n\n\tif (projectMap) {\n\t\tconst key = resolveRepoKey(input, projectMap);\n\t\tif (key && projectMap.repos[key]) {\n\t\t\treturn {\n\t\t\t\tscope: \"project\",\n\t\t\t\tqualifiedName: key,\n\t\t\t\tentry: projectMap.repos[key],\n\t\t\t};\n\t\t}\n\t}\n\n\tif (globalMap) {\n\t\tconst key = resolveRepoKey(input, globalMap);\n\t\tif (key && globalMap.repos[key]) {\n\t\t\treturn {\n\t\t\t\tscope: \"global\",\n\t\t\t\tqualifiedName: key,\n\t\t\t\tentry: globalMap.repos[key],\n\t\t\t};\n\t\t}\n\t}\n\n\treturn null;\n}\n\n/**\n * Search the map for repos matching a term.\n *\n * Scoring:\n * - Exact fullName match: 100\n * - Keyword hit: 50 per keyword\n * - Partial contains in fullName: 25\n * - Partial contains in keywords: 10\n *\n * @param term - Search term\n * @param options - Search options\n * @returns Sorted list of matches\n */\nexport function searchMap(term: string, options: SearchMapOptions = {}): SearchResult[] {\n\tconst { limit = 10 } = options;\n\n\tconst globalMap = readGlobalMapSafe();\n\tif (!globalMap) return [];\n\n\tconst termTokens = tokenize(term);\n\tconst termLower = term.toLowerCase();\n\tconst results: SearchResult[] = [];\n\n\tfor (const qualifiedName of Object.keys(globalMap.repos)) {\n\t\tconst entry = globalMap.repos[qualifiedName];\n\t\tif (!entry) continue;\n\n\t\tconst fullName = qualifiedName.includes(\":\")\n\t\t\t? (qualifiedName.split(\":\")[1] ?? qualifiedName)\n\t\t\t: qualifiedName;\n\t\tconst fullNameLower = fullName.toLowerCase();\n\t\tconst keywords = entry.keywords ?? [];\n\t\tconst keywordsLower = keywords.map((k) => k.toLowerCase());\n\n\t\tlet score = 0;\n\n\t\tif (fullNameLower === termLower) {\n\t\t\tscore += 100;\n\t\t}\n\n\t\tfor (const token of termTokens) {\n\t\t\tif (keywordsLower.includes(token)) {\n\t\t\t\tscore += 50;\n\t\t\t}\n\t\t}\n\n\t\tif (fullNameLower.includes(termLower) && score < 100) {\n\t\t\tscore += 25;\n\t\t}\n\n\t\tfor (const kw of keywordsLower) {\n\t\t\tif (kw.includes(termLower)) {\n\t\t\t\tscore += 10;\n\t\t\t}\n\t\t}\n\n\t\tconst fullNameTokens = tokenize(fullName);\n\t\tfor (const token of termTokens) {\n\t\t\tif (fullNameTokens.includes(token)) {\n\t\t\t\tscore += 30;\n\t\t\t}\n\t\t}\n\n\t\tif (score > 0) {\n\t\t\tresults.push({\n\t\t\t\tqualifiedName,\n\t\t\t\tfullName,\n\t\t\t\tlocalPath: entry.localPath,\n\t\t\t\tprimary: entry.primary,\n\t\t\t\tkeywords,\n\t\t\t\tscore,\n\t\t\t});\n\t\t}\n\t}\n\n\tresults.sort((a, b) => {\n\t\tif (b.score !== a.score) return b.score - a.score;\n\t\treturn a.fullName.localeCompare(b.fullName);\n\t});\n\n\treturn results.slice(0, limit);\n}\n\n/**\n * Get the project map path if it exists in cwd.\n */\nexport function getProjectMapPath(cwd: string = process.cwd()): string | null {\n\tconst mapPath = resolve(cwd, \".offworld/map.json\");\n\treturn existsSync(mapPath) ? mapPath : null;\n}\n","/**\n * Authentication utilities for offworld CLI\n */\n\nimport { chmodSync, existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync } from \"node:fs\";\nimport { dirname } from \"node:path\";\nimport { z } from \"zod\";\nimport { WorkOSTokenResponseSchema } from \"@offworld/types\";\nimport { Paths } from \"./paths\";\n\nconst AuthDataSchema = z.object({\n\ttoken: z.string(),\n\texpiresAt: z.string().optional(),\n\tworkosId: z.string().optional(),\n\trefreshToken: z.string().optional(),\n\temail: z.string().optional(),\n});\n\nexport interface AuthData {\n\ttoken: string;\n\texpiresAt?: string;\n\tworkosId?: string;\n\trefreshToken?: string;\n\temail?: string;\n}\n\n/** Authentication status */\nexport interface AuthStatus {\n\tisLoggedIn: boolean;\n\temail?: string;\n\tworkosId?: string;\n\texpiresAt?: string;\n}\n\nexport class AuthError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"AuthError\";\n\t}\n}\n\nexport class NotLoggedInError extends AuthError {\n\tconstructor(message = \"Not logged in. Please run 'ow auth login' first.\") {\n\t\tsuper(message);\n\t\tthis.name = \"NotLoggedInError\";\n\t}\n}\n\nexport class TokenExpiredError extends AuthError {\n\tconstructor(message = \"Session expired. Please run 'ow auth login' again.\") {\n\t\tsuper(message);\n\t\tthis.name = \"TokenExpiredError\";\n\t}\n}\n\nfunction extractJwtExpiration(token: string): string | undefined {\n\ttry {\n\t\tconst parts = token.split(\".\");\n\t\tif (parts.length !== 3) return undefined;\n\n\t\tconst payload = parts[1];\n\t\tif (!payload) return undefined;\n\n\t\tconst decoded = JSON.parse(Buffer.from(payload, \"base64\").toString(\"utf-8\"));\n\t\tif (typeof decoded.exp !== \"number\") return undefined;\n\n\t\treturn new Date(decoded.exp * 1000).toISOString();\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nexport function getAuthPath(): string {\n\treturn Paths.authFile;\n}\n\nexport function saveAuthData(data: AuthData): void {\n\tconst authPath = getAuthPath();\n\tconst authDir = dirname(authPath);\n\n\tif (!existsSync(authDir)) {\n\t\tmkdirSync(authDir, { recursive: true });\n\t}\n\n\twriteFileSync(authPath, JSON.stringify(data, null, 2), \"utf-8\");\n\tchmodSync(authPath, 0o600);\n}\n\n/**\n * Loads authentication data from ~/.local/share/offworld/auth.json\n * Returns null if file doesn't exist or is invalid\n */\nexport function loadAuthData(): AuthData | null {\n\tconst authPath = getAuthPath();\n\n\tif (!existsSync(authPath)) {\n\t\treturn null;\n\t}\n\n\ttry {\n\t\tconst content = readFileSync(authPath, \"utf-8\");\n\t\tconst json = JSON.parse(content);\n\t\tconst parsed = AuthDataSchema.safeParse(json);\n\n\t\tif (!parsed.success) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn parsed.data;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Clears stored authentication data\n * @returns true if auth file was deleted, false if it didn't exist\n */\nexport function clearAuthData(): boolean {\n\tconst authPath = getAuthPath();\n\n\tif (!existsSync(authPath)) {\n\t\treturn false;\n\t}\n\n\ttry {\n\t\tunlinkSync(authPath);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport async function getToken(): Promise<string> {\n\tconst data = loadAuthData();\n\n\tif (!data) {\n\t\tthrow new NotLoggedInError();\n\t}\n\n\tlet expiresAtStr = data.expiresAt;\n\tif (!expiresAtStr) {\n\t\texpiresAtStr = extractJwtExpiration(data.token);\n\t\tif (expiresAtStr) {\n\t\t\tdata.expiresAt = expiresAtStr;\n\t\t\tsaveAuthData(data);\n\t\t}\n\t}\n\n\tif (expiresAtStr) {\n\t\tconst expiresAt = new Date(expiresAtStr);\n\t\tconst now = new Date();\n\t\tconst oneMinute = 60 * 1000;\n\n\t\tif (expiresAt <= now) {\n\t\t\tif (data.refreshToken) {\n\t\t\t\ttry {\n\t\t\t\t\tconst refreshed = await refreshAccessToken();\n\t\t\t\t\treturn refreshed.token;\n\t\t\t\t} catch {\n\t\t\t\t\tthrow new TokenExpiredError();\n\t\t\t\t}\n\t\t\t}\n\t\t\tthrow new TokenExpiredError();\n\t\t}\n\n\t\tif (expiresAt.getTime() - now.getTime() < oneMinute) {\n\t\t\tif (data.refreshToken) {\n\t\t\t\ttry {\n\t\t\t\t\tconst refreshed = await refreshAccessToken();\n\t\t\t\t\treturn refreshed.token;\n\t\t\t\t} catch {\n\t\t\t\t\treturn data.token;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn data.token;\n}\n\n/**\n * Gets the current authentication token, or null if not logged in\n * Does not throw errors\n */\nexport async function getTokenOrNull(): Promise<string | null> {\n\ttry {\n\t\treturn await getToken();\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nexport async function isLoggedIn(): Promise<boolean> {\n\treturn (await getTokenOrNull()) !== null;\n}\n\nexport async function getAuthStatus(): Promise<AuthStatus> {\n\tconst data = loadAuthData();\n\n\tif (!data) {\n\t\treturn { isLoggedIn: false };\n\t}\n\n\t// Extract expiration from JWT if not already saved (mirrors getToken() logic)\n\tlet expiresAtStr = data.expiresAt;\n\tif (!expiresAtStr) {\n\t\texpiresAtStr = extractJwtExpiration(data.token);\n\t\tif (expiresAtStr) {\n\t\t\tdata.expiresAt = expiresAtStr;\n\t\t\tsaveAuthData(data);\n\t\t}\n\t}\n\n\tif (expiresAtStr) {\n\t\tconst expiresAt = new Date(expiresAtStr);\n\t\tconst now = new Date();\n\t\tconst oneMinute = 60 * 1000;\n\n\t\t// Token already expired - attempt refresh\n\t\tif (expiresAt <= now) {\n\t\t\tif (data.refreshToken) {\n\t\t\t\ttry {\n\t\t\t\t\tconst refreshed = await refreshAccessToken();\n\t\t\t\t\treturn {\n\t\t\t\t\t\tisLoggedIn: true,\n\t\t\t\t\t\temail: refreshed.email,\n\t\t\t\t\t\tworkosId: refreshed.workosId,\n\t\t\t\t\t\texpiresAt: refreshed.expiresAt,\n\t\t\t\t\t};\n\t\t\t\t} catch {\n\t\t\t\t\treturn { isLoggedIn: false };\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn { isLoggedIn: false };\n\t\t}\n\n\t\t// Proactive refresh: token expires within 1 minute\n\t\tif (expiresAt.getTime() - now.getTime() < oneMinute) {\n\t\t\tif (data.refreshToken) {\n\t\t\t\ttry {\n\t\t\t\t\tconst refreshed = await refreshAccessToken();\n\t\t\t\t\treturn {\n\t\t\t\t\t\tisLoggedIn: true,\n\t\t\t\t\t\temail: refreshed.email,\n\t\t\t\t\t\tworkosId: refreshed.workosId,\n\t\t\t\t\t\texpiresAt: refreshed.expiresAt,\n\t\t\t\t\t};\n\t\t\t\t} catch {\n\t\t\t\t\t// Refresh failed, but token still valid - return current data\n\t\t\t\t\treturn {\n\t\t\t\t\t\tisLoggedIn: true,\n\t\t\t\t\t\temail: data.email,\n\t\t\t\t\t\tworkosId: data.workosId,\n\t\t\t\t\t\texpiresAt: expiresAtStr,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn {\n\t\tisLoggedIn: true,\n\t\temail: data.email,\n\t\tworkosId: data.workosId,\n\t\texpiresAt: expiresAtStr,\n\t};\n}\n\nconst WORKOS_API = \"https://api.workos.com\";\n\n// Production WorkOS client ID - dev can override via WORKOS_CLIENT_ID env var\nconst PRODUCTION_WORKOS_CLIENT_ID = \"client_01KFAD76TNGN02AP96982HG35E\";\n\nfunction getWorkosClientId(): string {\n\treturn process.env.WORKOS_CLIENT_ID ?? PRODUCTION_WORKOS_CLIENT_ID;\n}\n\nexport async function refreshAccessToken(): Promise<AuthData> {\n\tconst data = loadAuthData();\n\n\tif (!data?.refreshToken) {\n\t\tthrow new AuthError(\"No refresh token available. Please log in again.\");\n\t}\n\n\ttry {\n\t\tconst response = await fetch(`${WORKOS_API}/user_management/authenticate`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { \"Content-Type\": \"application/x-www-form-urlencoded\" },\n\t\t\tbody: new URLSearchParams({\n\t\t\t\tgrant_type: \"refresh_token\",\n\t\t\t\trefresh_token: data.refreshToken,\n\t\t\t\tclient_id: getWorkosClientId(),\n\t\t\t}),\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tconst error = await response.text();\n\t\t\tthrow new AuthError(`Token refresh failed: ${error}`);\n\t\t}\n\n\t\tconst json = await response.json();\n\t\tconst tokenData = WorkOSTokenResponseSchema.parse(json);\n\n\t\tconst newAuthData: AuthData = {\n\t\t\ttoken: tokenData.access_token,\n\t\t\temail: tokenData.user.email,\n\t\t\tworkosId: tokenData.user.id,\n\t\t\trefreshToken: tokenData.refresh_token,\n\t\t\texpiresAt: tokenData.expires_at\n\t\t\t\t? new Date(tokenData.expires_at * 1000).toISOString()\n\t\t\t\t: extractJwtExpiration(tokenData.access_token),\n\t\t};\n\n\t\tsaveAuthData(newAuthData);\n\t\treturn newAuthData;\n\t} catch (error) {\n\t\tif (error instanceof AuthError) throw error;\n\t\tthrow new AuthError(\n\t\t\t`Failed to refresh token: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n\t\t);\n\t}\n}\n","/**\n * Agent Registry & Auto-Detection\n *\n * Centralized registry of supported AI coding agents with their\n * skill directory locations and detection functions.\n */\n\nimport { existsSync } from \"node:fs\";\nimport type { Agent } from \"@offworld/types\";\nimport { expandTilde } from \"./paths\";\n\nexport interface AgentConfig {\n\t/** Agent identifier (matches AgentSchema enum) */\n\tname: Agent;\n\t/** Human-readable name for display */\n\tdisplayName: string;\n\t/** Project-level skill directory (relative path) */\n\tskillsDir: string;\n\t/** User-level skill directory (absolute with ~) */\n\tglobalSkillsDir: string;\n\t/** Check if this agent is installed on the system */\n\tdetectInstalled: () => boolean;\n}\n\nexport const agents: Record<Agent, AgentConfig> = {\n\topencode: {\n\t\tname: \"opencode\",\n\t\tdisplayName: \"OpenCode\",\n\t\tskillsDir: \".opencode/skills\",\n\t\tglobalSkillsDir: \"~/.config/opencode/skills\",\n\t\tdetectInstalled: () => existsSync(expandTilde(\"~/.config/opencode\")),\n\t},\n\t\"claude-code\": {\n\t\tname: \"claude-code\",\n\t\tdisplayName: \"Claude Code\",\n\t\tskillsDir: \".claude/skills\",\n\t\tglobalSkillsDir: \"~/.claude/skills\",\n\t\tdetectInstalled: () => existsSync(expandTilde(\"~/.claude\")),\n\t},\n\tcodex: {\n\t\tname: \"codex\",\n\t\tdisplayName: \"Codex (OpenAI)\",\n\t\tskillsDir: \".codex/skills\",\n\t\tglobalSkillsDir: \"~/.codex/skills\",\n\t\tdetectInstalled: () => existsSync(expandTilde(\"~/.codex\")),\n\t},\n\tamp: {\n\t\tname: \"amp\",\n\t\tdisplayName: \"Amp\",\n\t\tskillsDir: \".agents/skills\",\n\t\tglobalSkillsDir: \"~/.config/agents/skills\",\n\t\tdetectInstalled: () => existsSync(expandTilde(\"~/.config/amp\")),\n\t},\n\tantigravity: {\n\t\tname: \"antigravity\",\n\t\tdisplayName: \"Antigravity\",\n\t\tskillsDir: \".agent/skills\",\n\t\tglobalSkillsDir: \"~/.gemini/antigravity/skills\",\n\t\tdetectInstalled: () => existsSync(expandTilde(\"~/.gemini/antigravity\")),\n\t},\n\tcursor: {\n\t\tname: \"cursor\",\n\t\tdisplayName: \"Cursor\",\n\t\tskillsDir: \".cursor/skills\",\n\t\tglobalSkillsDir: \"~/.cursor/skills\",\n\t\tdetectInstalled: () => existsSync(expandTilde(\"~/.cursor\")),\n\t},\n};\n\n/**\n * Detect which agents are installed on the system.\n * Checks for the existence of each agent's config directory.\n *\n * @returns Array of installed agent identifiers\n */\nexport function detectInstalledAgents(): Agent[] {\n\tconst installed: Agent[] = [];\n\n\tfor (const config of Object.values(agents)) {\n\t\tif (config.detectInstalled()) {\n\t\t\tinstalled.push(config.name);\n\t\t}\n\t}\n\n\treturn installed;\n}\n\n/**\n * Get the configuration for a specific agent.\n *\n * @param type - Agent identifier\n * @returns AgentConfig for the specified agent\n */\nexport function getAgentConfig(type: Agent): AgentConfig {\n\treturn agents[type];\n}\n\n/**\n * Get all agent configurations as an array.\n *\n * @returns Array of all agent configurations\n */\nexport function getAllAgentConfigs(): AgentConfig[] {\n\treturn Object.values(agents);\n}\n","/**\n * Dependency name to GitHub repo resolution:\n * 1. Parse repo from dependency spec (git/https/github shorthand)\n * 2. Query npm registry for repository.url\n * 3. Fall back to FALLBACK_MAPPINGS for packages missing repository field\n * 4. Return unknown (caller handles)\n */\n\nimport { NpmPackageResponseSchema } from \"@offworld/types\";\n\nexport type ResolvedDep = {\n\tdep: string;\n\trepo: string | null;\n\tsource: \"spec\" | \"npm\" | \"fallback\" | \"unknown\";\n};\n\nexport interface ResolveDependencyRepoOptions {\n\tallowNpm?: boolean;\n\tnpmTimeoutMs?: number;\n}\n\nconst DEFAULT_NPM_FETCH_TIMEOUT_MS = 5000;\n\n/**\n * Fallback mappings for packages where npm registry doesn't have repository.url.\n * Only add packages here that genuinely don't have the field set.\n */\nexport const FALLBACK_MAPPINGS: Record<string, string> = {\n\t\"@convex-dev/react-query\": \"get-convex/convex-react-query\",\n\t\"@opencode-ai/sdk\": \"anomalyco/opencode-sdk-js\",\n};\n\n/**\n * Parse GitHub repo from various git URL formats.\n * Handles:\n * - git+https://github.com/owner/repo.git\n * - https://github.com/owner/repo\n * - git://github.com/owner/repo.git\n * - https://github.com/owner/repo/tree/main\n * - git@github.com:owner/repo.git\n * - github:owner/repo\n */\nfunction parseGitHubUrl(url: string): string | null {\n\tconst cleaned = url\n\t\t.trim()\n\t\t.replace(/^git\\+/, \"\")\n\t\t.split(\"#\")[0]\n\t\t?.split(\"?\")[0]\n\t\t?.trim();\n\n\tif (!cleaned) return null;\n\n\tconst patterns = [\n\t\t/github\\.com[/:]([\\w.-]+)\\/([\\w.-]+)(?:\\.git)?(?:[/?#].*)?$/,\n\t\t/^github:([\\w.-]+)\\/([\\w.-]+)(?:[/?#].*)?$/,\n\t];\n\n\tfor (const pattern of patterns) {\n\t\tconst match = cleaned.match(pattern);\n\t\tif (match) {\n\t\t\tconst owner = match[1];\n\t\t\tconst repo = match[2]?.replace(/\\.git$/i, \"\");\n\t\t\tif (!owner || !repo) return null;\n\t\t\treturn `${owner}/${repo}`;\n\t\t}\n\t}\n\n\treturn null;\n}\n\nfunction resolveFromSpec(spec?: string): string | null {\n\tif (!spec) return null;\n\n\tconst trimmed = spec.trim();\n\tif (!trimmed) return null;\n\n\tconst isGitSpec =\n\t\ttrimmed.startsWith(\"github:\") ||\n\t\ttrimmed.startsWith(\"git+\") ||\n\t\ttrimmed.startsWith(\"git://\") ||\n\t\ttrimmed.startsWith(\"https://\") ||\n\t\ttrimmed.startsWith(\"http://\") ||\n\t\ttrimmed.startsWith(\"ssh://\") ||\n\t\ttrimmed.startsWith(\"git@\");\n\n\tif (!isGitSpec) return null;\n\n\treturn parseGitHubUrl(trimmed);\n}\n\nasync function fetchNpmPackage(\n\tpackageName: string,\n\ttimeoutMs = DEFAULT_NPM_FETCH_TIMEOUT_MS,\n): Promise<{\n\trepository?: string | { url?: string };\n\tkeywords?: string[];\n} | null> {\n\tconst controller = new AbortController();\n\tconst timeoutId = setTimeout(() => controller.abort(), timeoutMs);\n\n\ttry {\n\t\tconst res = await fetch(`https://registry.npmjs.org/${packageName}`, {\n\t\t\tsignal: controller.signal,\n\t\t});\n\t\tif (!res.ok) return null;\n\n\t\tconst json = await res.json();\n\t\tconst result = NpmPackageResponseSchema.safeParse(json);\n\t\tif (!result.success) return null;\n\n\t\treturn result.data;\n\t} catch {\n\t\treturn null;\n\t} finally {\n\t\tclearTimeout(timeoutId);\n\t}\n}\n\n/**\n * Fallback to npm registry to extract repository.url.\n * Returns null if package not found, no repo field, or not a GitHub repo.\n */\nexport async function resolveFromNpm(\n\tpackageName: string,\n\ttimeoutMs?: number,\n): Promise<string | null> {\n\tconst pkg = await fetchNpmPackage(packageName, timeoutMs);\n\tif (!pkg?.repository) return null;\n\n\tconst repoUrl = typeof pkg.repository === \"string\" ? pkg.repository : pkg.repository.url;\n\tif (!repoUrl) return null;\n\n\treturn parseGitHubUrl(repoUrl);\n}\n\nexport async function getNpmKeywords(packageName: string): Promise<string[]> {\n\tconst pkg = await fetchNpmPackage(packageName);\n\tif (!pkg?.keywords || pkg.keywords.length === 0) return [];\n\n\tconst seen = new Set<string>();\n\tfor (const keyword of pkg.keywords) {\n\t\tconst normalized = keyword.trim().toLowerCase();\n\t\tif (normalized.length < 2) continue;\n\t\tseen.add(normalized);\n\t}\n\n\treturn Array.from(seen);\n}\n\n/**\n * Resolution order:\n * 1. Parse repo from dependency spec (git/https/github shorthand)\n * 2. Query npm registry for repository.url\n * 3. Check FALLBACK_MAPPINGS for packages missing repository field\n * 4. Return unknown\n */\nexport async function resolveDependencyRepo(\n\tdep: string,\n\tspec?: string,\n\toptions: ResolveDependencyRepoOptions = {},\n): Promise<ResolvedDep> {\n\tconst { allowNpm = true, npmTimeoutMs } = options;\n\n\tconst specRepo = resolveFromSpec(spec);\n\tif (specRepo) {\n\t\treturn { dep, repo: specRepo, source: \"spec\" };\n\t}\n\n\tif (allowNpm) {\n\t\tconst npmRepo = await resolveFromNpm(dep, npmTimeoutMs);\n\t\tif (npmRepo) {\n\t\t\treturn { dep, repo: npmRepo, source: \"npm\" };\n\t\t}\n\n\t\tif (dep in FALLBACK_MAPPINGS) {\n\t\t\treturn { dep, repo: FALLBACK_MAPPINGS[dep] ?? null, source: \"fallback\" };\n\t\t}\n\t}\n\n\treturn { dep, repo: null, source: \"unknown\" };\n}\n","import {\n\tmkdirSync,\n\twriteFileSync,\n\treadFileSync,\n\tlstatSync,\n\tunlinkSync,\n\trmSync,\n\tsymlinkSync,\n\texistsSync,\n} from \"node:fs\";\nimport { join } from \"node:path\";\nimport { z } from \"zod\";\nimport { loadConfig, toMetaDirName, toReferenceFileName } from \"./config.js\";\nimport { agents } from \"./agents.js\";\nimport { expandTilde, Paths } from \"./paths.js\";\nimport { readGlobalMap, writeGlobalMap } from \"./index-manager.js\";\nimport { getNpmKeywords } from \"./dep-mappings.js\";\n\nconst PackageJsonNameSchema = z.object({\n\tname: z.string().optional(),\n});\n\nexport interface InstallReferenceMeta {\n\t/** ISO timestamp when the reference was generated */\n\treferenceUpdatedAt: string;\n\t/** Git commit SHA at time of generation */\n\tcommitSha: string;\n\t/** SDK version used for generation */\n\tversion: string;\n}\n\nfunction normalizeKeywords(values: string[]): string[] {\n\tconst seen = new Set<string>();\n\tfor (const value of values) {\n\t\tconst normalized = value.trim().toLowerCase();\n\t\tif (normalized.length < 2) continue;\n\t\tseen.add(normalized);\n\t}\n\treturn Array.from(seen);\n}\n\nfunction deriveMinimalKeywords(fullName: string): string[] {\n\tconst normalized = fullName.trim().toLowerCase();\n\tif (!normalized) return [];\n\n\tconst repoName = normalized.split(\"/\").pop() ?? normalized;\n\treturn normalizeKeywords([normalized, repoName]);\n}\n\nfunction getPackageName(localPath: string): string | null {\n\tconst packageJsonPath = join(localPath, \"package.json\");\n\tif (!existsSync(packageJsonPath)) return null;\n\n\ttry {\n\t\tconst content = readFileSync(packageJsonPath, \"utf-8\");\n\t\tconst json = JSON.parse(content);\n\t\tconst parsed = PackageJsonNameSchema.safeParse(json);\n\t\tif (!parsed.success || !parsed.data.name) return null;\n\t\treturn parsed.data.name;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Resolve keywords with npm-first strategy.\n * - npm package: package name + npm keywords\n * - non-npm package: minimal repo-derived keywords\n */\nexport async function resolveReferenceKeywords(\n\tfullName: string,\n\tlocalPath: string,\n): Promise<string[]> {\n\tconst packageName = getPackageName(localPath);\n\tif (!packageName) {\n\t\treturn deriveMinimalKeywords(fullName);\n\t}\n\n\tconst npmKeywords = await getNpmKeywords(packageName);\n\tif (npmKeywords.length > 0) {\n\t\treturn normalizeKeywords([packageName, ...npmKeywords]);\n\t}\n\n\treturn normalizeKeywords([packageName]);\n}\n\n/**\n * Ensure a symlink exists, removing any existing file/directory at the path\n */\nfunction ensureSymlink(target: string, linkPath: string): void {\n\ttry {\n\t\tconst stat = lstatSync(linkPath);\n\t\tif (stat.isSymbolicLink()) {\n\t\t\tunlinkSync(linkPath);\n\t\t} else if (stat.isDirectory()) {\n\t\t\trmSync(linkPath, { recursive: true });\n\t\t} else {\n\t\t\tunlinkSync(linkPath);\n\t\t}\n\t} catch {}\n\n\tconst linkDir = join(linkPath, \"..\");\n\tmkdirSync(linkDir, { recursive: true });\n\tsymlinkSync(target, linkPath, \"dir\");\n}\n\n/**\n * Static template for the global SKILL.md file.\n * This is the single routing skill that all agents see.\n */\nconst GLOBAL_SKILL_TEMPLATE = `---\nname: offworld\ndescription: Routes queries to Offworld reference files. Find and read per-repo references for dependency knowledge.\nallowed-tools: Bash(ow:*) Read\n---\n\n# Offworld Reference Router\n\nUse \\`ow\\` to locate and read Offworld reference files for dependencies.\n\n## What This Does\n\n- Finds references for libraries and repos\n- Returns paths for reference files and local clones\n- Helps you read the right context fast\n\n## When to Use\n\n- You need docs or patterns for a dependency\n- You want the verified reference instead of web search\n- You are about to work inside a repo clone\n\n## Installation and Setup\n\nIf Offworld CLI or opencode is missing, read \\`references/installation.md\\` in this skill directory and follow it.\n\n## Usage\n\n**Find a reference:**\n\\`\\`\\`bash\now map search <term> # search by name or keyword\now map show <repo> # get info for specific repo\n\\`\\`\\`\n\n**Get paths for tools:**\n\\`\\`\\`bash\now map show <repo> --ref # reference file path (use with Read)\now map show <repo> --path # clone directory path\n\\`\\`\\`\n\n**Example workflow:**\n\\`\\`\\`bash\n# 1. Find the repo\now map search zod\n\n# 2. Get reference path\now map show colinhacks/zod --ref\n# Output: /Users/.../.local/share/offworld/skill/offworld/references/colinhacks-zod.md\n\n# 3. Read the reference with the path from step 2\n\\`\\`\\`\n\n## If Reference Not Found\n\n\\`\\`\\`bash\now pull <owner/repo> # clone + generate reference\now project init # scan project deps, install references\n\\`\\`\\`\n\n## Notes\n\n- Project map (\\`.offworld/map.json\\`) takes precedence over global map when present\n- Reference files are markdown with API docs, patterns, best practices\n- Clone paths useful for exploring source code after reading reference\n\n## Additional Resources\n\n- Docs: https://offworld.sh/cli\n`;\n\nconst INSTALLATION_REFERENCE_TEMPLATE = `# Offworld Installation\n\nUse this when Offworld CLI or opencode is not installed.\n\n## 1) Check opencode\n\n\\`\\`\\`bash\nopencode --version\n\\`\\`\\`\n\nIf missing:\n\n\\`\\`\\`bash\ncurl -fsSL https://opencode.ai/install | bash\n\\`\\`\\`\n\n## 2) Check Offworld CLI\n\n\\`\\`\\`bash\now --version\n\\`\\`\\`\n\nIf missing:\n\n\\`\\`\\`bash\ncurl -fsSL https://offworld.sh/install | bash\n\\`\\`\\`\n\n## 3) Initialize Offworld (non-interactive)\n\n\\`\\`\\`bash\now init --yes --agents \"<agent-list>\" --repo-root \"<clone-dir>\" --model \"<provider/model>\"\n\\`\\`\\`\n\nExample:\n\n\\`\\`\\`bash\now init --yes --agents \"opencode,codex\" --repo-root \"~/ow\" --model \"anthropic/claude-sonnet-4-20250514\"\n\\`\\`\\`\n\n## 4) Initialize current project\n\n\\`\\`\\`bash\now project init --yes --all --generate\n\\`\\`\\`\n\n## 5) Verify\n\n\\`\\`\\`bash\now config show\now list\n\\`\\`\\`\n`;\n\n/**\n * Ensures the global SKILL.md exists and symlinks the offworld/ directory to all agent skill directories.\n *\n * Creates:\n * - ~/.local/share/offworld/skill/offworld/SKILL.md (static routing template)\n * - ~/.local/share/offworld/skill/offworld/assets/ (for map.json)\n * - ~/.local/share/offworld/skill/offworld/references/ (for reference files)\n * - Symlinks entire offworld/ directory to each agent's skill directory\n */\nexport function installGlobalSkill(): void {\n\tconst config = loadConfig();\n\n\tmkdirSync(Paths.offworldSkillDir, { recursive: true });\n\tmkdirSync(Paths.offworldAssetsDir, { recursive: true });\n\tmkdirSync(Paths.offworldReferencesDir, { recursive: true });\n\n\tconst skillPath = join(Paths.offworldSkillDir, \"SKILL.md\");\n\tif (!existsSync(skillPath)) {\n\t\twriteFileSync(skillPath, GLOBAL_SKILL_TEMPLATE, \"utf-8\");\n\t}\n\n\tconst installationReferencePath = join(Paths.offworldReferencesDir, \"installation.md\");\n\tif (!existsSync(installationReferencePath)) {\n\t\twriteFileSync(installationReferencePath, INSTALLATION_REFERENCE_TEMPLATE, \"utf-8\");\n\t}\n\n\tconst configuredAgents = config.agents ?? [];\n\tfor (const agentName of configuredAgents) {\n\t\tconst agentConfig = agents[agentName];\n\t\tif (agentConfig) {\n\t\t\tconst agentSkillDir = expandTilde(join(agentConfig.globalSkillsDir, \"offworld\"));\n\t\t\tensureSymlink(Paths.offworldSkillDir, agentSkillDir);\n\t\t}\n\t}\n}\n\n/**\n * Install a reference file for a specific repository.\n *\n * Creates:\n * - ~/.local/share/offworld/skill/offworld/references/{owner-repo}.md\n * - ~/.local/share/offworld/meta/{owner-repo}/meta.json\n * - Updates global map with reference info\n *\n * @param qualifiedName - Qualified key for map storage (e.g., \"github.com:owner/repo\" or \"local:name\")\n * @param fullName - Full repo name for file naming (e.g., \"owner/repo\")\n * @param localPath - Absolute path to the cloned repository\n * @param referenceContent - The generated reference markdown content\n * @param meta - Metadata about the generation (referenceUpdatedAt, commitSha, version)\n * @param keywords - Optional array of keywords for search/routing\n */\nexport function installReference(\n\tqualifiedName: string,\n\tfullName: string,\n\tlocalPath: string,\n\treferenceContent: string,\n\tmeta: InstallReferenceMeta,\n\tkeywords?: string[],\n): void {\n\tinstallGlobalSkill();\n\n\tconst referenceFileName = toReferenceFileName(fullName);\n\tconst metaDirName = toMetaDirName(fullName);\n\n\tconst referencePath = join(Paths.offworldReferencesDir, referenceFileName);\n\tmkdirSync(Paths.offworldReferencesDir, { recursive: true });\n\twriteFileSync(referencePath, referenceContent, \"utf-8\");\n\n\tconst metaDir = join(Paths.metaDir, metaDirName);\n\tmkdirSync(metaDir, { recursive: true });\n\tconst metaJson = JSON.stringify(meta, null, 2);\n\twriteFileSync(join(metaDir, \"meta.json\"), metaJson, \"utf-8\");\n\n\tconst map = readGlobalMap();\n\tconst existingEntry = map.repos[qualifiedName];\n\tconst legacyProviderMap: Record<string, string> = {\n\t\t\"github.com\": \"github\",\n\t\t\"gitlab.com\": \"gitlab\",\n\t\t\"bitbucket.org\": \"bitbucket\",\n\t};\n\tconst [host] = qualifiedName.split(\":\");\n\tconst legacyProvider = host ? legacyProviderMap[host] : undefined;\n\tconst legacyQualifiedName = legacyProvider ? `${legacyProvider}:${fullName}` : undefined;\n\tconst legacyEntry = legacyQualifiedName ? map.repos[legacyQualifiedName] : undefined;\n\n\tconst references = [...(existingEntry?.references ?? []), ...(legacyEntry?.references ?? [])];\n\tif (!references.includes(referenceFileName)) {\n\t\treferences.push(referenceFileName);\n\t}\n\n\tconst derivedKeywords =\n\t\tkeywords && keywords.length > 0 ? keywords : deriveMinimalKeywords(fullName);\n\n\tmap.repos[qualifiedName] = {\n\t\tlocalPath,\n\t\treferences,\n\t\tprimary: referenceFileName,\n\t\tkeywords: normalizeKeywords(derivedKeywords),\n\t\tupdatedAt: new Date().toISOString(),\n\t};\n\n\tif (legacyQualifiedName && legacyQualifiedName in map.repos) {\n\t\tdelete map.repos[legacyQualifiedName];\n\t}\n\n\twriteGlobalMap(map);\n}\n","/**\n * Dependency manifest parsing for multiple package ecosystems\n */\n\nimport { existsSync, readdirSync, readFileSync } from \"node:fs\";\nimport type { Dirent } from \"node:fs\";\nimport { join } from \"node:path\";\n\nexport type ManifestType = \"npm\" | \"python\" | \"rust\" | \"go\" | \"unknown\";\n\nexport interface Dependency {\n\tname: string;\n\tversion?: string;\n\tdev: boolean;\n}\n\nconst DEFAULT_IGNORED_DIRS = new Set([\n\t\".git\",\n\t\".offworld\",\n\t\".turbo\",\n\t\"build\",\n\t\"dist\",\n\t\"node_modules\",\n\t\"out\",\n]);\n\n/**\n * Detects the manifest type in a directory\n */\nexport function detectManifestType(dir: string): ManifestType {\n\tif (existsSync(join(dir, \"package.json\"))) return \"npm\";\n\tif (existsSync(join(dir, \"pyproject.toml\"))) return \"python\";\n\tif (existsSync(join(dir, \"Cargo.toml\"))) return \"rust\";\n\tif (existsSync(join(dir, \"go.mod\"))) return \"go\";\n\tif (existsSync(join(dir, \"requirements.txt\"))) return \"python\";\n\treturn \"unknown\";\n}\n\n/**\n * Parses dependencies from manifest files\n */\nexport function parseDependencies(dir: string): Dependency[] {\n\tconst type = detectManifestType(dir);\n\n\tswitch (type) {\n\t\tcase \"npm\":\n\t\t\treturn parseNpmDependencies(dir);\n\t\tcase \"python\":\n\t\t\treturn existsSync(join(dir, \"pyproject.toml\"))\n\t\t\t\t? parsePyprojectToml(join(dir, \"pyproject.toml\"))\n\t\t\t\t: parseRequirementsTxt(join(dir, \"requirements.txt\"));\n\t\tcase \"rust\":\n\t\t\treturn parseCargoToml(join(dir, \"Cargo.toml\"));\n\t\tcase \"go\":\n\t\t\treturn parseGoMod(join(dir, \"go.mod\"));\n\t\tdefault:\n\t\t\treturn [];\n\t}\n}\n\nfunction parseNpmDependencies(dir: string): Dependency[] {\n\tconst rootPath = join(dir, \"package.json\");\n\tconst rootDeps = parsePackageJson(rootPath);\n\tconst workspaceDeps = parseWorkspaceDependencies(dir);\n\treturn mergeDependencies(rootDeps, workspaceDeps).sort((a, b) => a.name.localeCompare(b.name));\n}\n\nfunction parseWorkspaceDependencies(dir: string): Dependency[] {\n\tconst workspacePatterns = getWorkspacePatterns(dir);\n\tif (workspacePatterns.length === 0) return [];\n\n\tconst packageJsonPaths = resolveWorkspacePackageJsonPaths(dir, workspacePatterns);\n\tconst deps: Dependency[] = [];\n\tfor (const path of packageJsonPaths) {\n\t\tdeps.push(...parsePackageJson(path));\n\t}\n\n\treturn mergeDependencies([], deps);\n}\n\nfunction getWorkspacePatterns(dir: string): string[] {\n\tconst patterns = new Set<string>();\n\n\tconst packageJsonPath = join(dir, \"package.json\");\n\tif (existsSync(packageJsonPath)) {\n\t\tconst rootJson = readJson(packageJsonPath);\n\t\tconst workspaces = rootJson?.workspaces;\n\t\tif (Array.isArray(workspaces)) {\n\t\t\tfor (const pattern of workspaces) {\n\t\t\t\tif (typeof pattern === \"string\") patterns.add(pattern);\n\t\t\t}\n\t\t} else if (workspaces && typeof workspaces === \"object\") {\n\t\t\tconst packagesField = (workspaces as { packages?: unknown }).packages;\n\t\t\tif (Array.isArray(packagesField)) {\n\t\t\t\tfor (const pattern of packagesField) {\n\t\t\t\t\tif (typeof pattern === \"string\") patterns.add(pattern);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tconst pnpmWorkspacePath = existsSync(join(dir, \"pnpm-workspace.yaml\"))\n\t\t? join(dir, \"pnpm-workspace.yaml\")\n\t\t: existsSync(join(dir, \"pnpm-workspace.yml\"))\n\t\t\t? join(dir, \"pnpm-workspace.yml\")\n\t\t\t: null;\n\n\tif (pnpmWorkspacePath) {\n\t\tfor (const pattern of parsePnpmWorkspacePackages(pnpmWorkspacePath)) {\n\t\t\tpatterns.add(pattern);\n\t\t}\n\t}\n\n\treturn Array.from(patterns);\n}\n\nfunction resolveWorkspacePackageJsonPaths(dir: string, patterns: string[]): string[] {\n\tconst includePatterns = patterns.filter((pattern) => !pattern.startsWith(\"!\"));\n\tconst excludePatterns = patterns\n\t\t.filter((pattern) => pattern.startsWith(\"!\"))\n\t\t.map((pattern) => pattern.slice(1));\n\n\tif (includePatterns.length === 0) return [];\n\n\tconst includeRegexes = includePatterns.map(patternToRegex);\n\tconst excludeRegexes = excludePatterns.map(patternToRegex);\n\n\tconst matches: string[] = [];\n\tconst directories = walkDirectories(dir);\n\n\tfor (const relativePath of directories) {\n\t\tif (!includeRegexes.some((regex) => regex.test(relativePath))) continue;\n\t\tif (excludeRegexes.some((regex) => regex.test(relativePath))) continue;\n\n\t\tconst packageJsonPath = join(dir, relativePath, \"package.json\");\n\t\tif (existsSync(packageJsonPath)) {\n\t\t\tmatches.push(packageJsonPath);\n\t\t}\n\t}\n\n\treturn Array.from(new Set(matches));\n}\n\nfunction walkDirectories(root: string): string[] {\n\tconst results: string[] = [];\n\tconst stack: string[] = [\"\"];\n\n\twhile (stack.length > 0) {\n\t\tconst relativePath = stack.pop();\n\t\tconst currentPath = relativePath ? join(root, relativePath) : root;\n\n\t\tlet entries: Dirent[];\n\t\ttry {\n\t\t\tentries = readdirSync(currentPath, { withFileTypes: true }) as Dirent[];\n\t\t} catch {\n\t\t\tcontinue;\n\t\t}\n\n\t\tfor (const entry of entries) {\n\t\t\tif (!entry.isDirectory()) continue;\n\t\t\tif (DEFAULT_IGNORED_DIRS.has(entry.name)) continue;\n\n\t\t\tconst nextRelative = relativePath ? `${relativePath}/${entry.name}` : entry.name;\n\t\t\tresults.push(nextRelative);\n\t\t\tstack.push(nextRelative);\n\t\t}\n\t}\n\n\treturn results;\n}\n\nfunction patternToRegex(pattern: string): RegExp {\n\tlet normalized = pattern.trim().replace(/\\\\/g, \"/\");\n\tif (normalized.startsWith(\"./\")) normalized = normalized.slice(2);\n\tif (normalized.endsWith(\"/\")) normalized = normalized.slice(0, -1);\n\n\tconst escaped = normalized.replace(/[.+^${}()|[\\]\\\\*]/g, \"\\\\$&\");\n\tconst withGlob = escaped.replace(/\\\\\\*\\\\\\*/g, \".*\").replace(/\\\\\\*/g, \"[^/]+\");\n\n\treturn new RegExp(`^${withGlob}$`);\n}\n\nfunction parsePnpmWorkspacePackages(path: string): string[] {\n\ttry {\n\t\tconst content = readFileSync(path, \"utf-8\");\n\t\tconst lines = content.split(\"\\n\");\n\t\tconst patterns: string[] = [];\n\t\tlet inPackages = false;\n\n\t\tfor (const line of lines) {\n\t\t\tconst trimmed = line.trim();\n\t\t\tif (!trimmed || trimmed.startsWith(\"#\")) continue;\n\n\t\t\tif (/^packages\\s*:/.test(trimmed)) {\n\t\t\t\tinPackages = true;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (!inPackages) continue;\n\n\t\t\tconst entryMatch = trimmed.match(/^-\\s*(.+)$/);\n\t\t\tif (entryMatch?.[1]) {\n\t\t\t\tconst value = entryMatch[1].trim().replace(/^['\"]|['\"]$/g, \"\");\n\t\t\t\tif (value) patterns.push(value);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (!line.startsWith(\" \") && !line.startsWith(\"\\t\")) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn patterns;\n\t} catch {\n\t\treturn [];\n\t}\n}\n\nfunction readJson(path: string): Record<string, unknown> | null {\n\ttry {\n\t\tconst content = readFileSync(path, \"utf-8\");\n\t\treturn JSON.parse(content) as Record<string, unknown>;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\nfunction mergeDependencies(base: Dependency[], incoming: Dependency[]): Dependency[] {\n\tconst map = new Map<string, Dependency>();\n\n\tfor (const dep of [...base, ...incoming]) {\n\t\tconst existing = map.get(dep.name);\n\t\tif (!existing) {\n\t\t\tmap.set(dep.name, { ...dep });\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst dev = existing.dev && dep.dev;\n\t\tconst version = existing.version ?? dep.version;\n\t\tmap.set(dep.name, { name: dep.name, version, dev });\n\t}\n\n\treturn Array.from(map.values());\n}\n\n/**\n * Parse package.json dependencies\n */\nfunction parsePackageJson(path: string): Dependency[] {\n\ttry {\n\t\tconst content = readFileSync(path, \"utf-8\");\n\t\tconst pkg = JSON.parse(content);\n\t\tconst deps: Dependency[] = [];\n\n\t\tif (pkg.dependencies && typeof pkg.dependencies === \"object\") {\n\t\t\tfor (const [name, version] of Object.entries(pkg.dependencies)) {\n\t\t\t\tdeps.push({ name, version: version as string, dev: false });\n\t\t\t}\n\t\t}\n\n\t\tif (pkg.devDependencies && typeof pkg.devDependencies === \"object\") {\n\t\t\tfor (const [name, version] of Object.entries(pkg.devDependencies)) {\n\t\t\t\tdeps.push({ name, version: version as string, dev: true });\n\t\t\t}\n\t\t}\n\n\t\tif (pkg.peerDependencies && typeof pkg.peerDependencies === \"object\") {\n\t\t\tfor (const [name, version] of Object.entries(pkg.peerDependencies)) {\n\t\t\t\tdeps.push({ name, version: version as string, dev: false });\n\t\t\t}\n\t\t}\n\n\t\tif (pkg.optionalDependencies && typeof pkg.optionalDependencies === \"object\") {\n\t\t\tfor (const [name, version] of Object.entries(pkg.optionalDependencies)) {\n\t\t\t\tdeps.push({ name, version: version as string, dev: false });\n\t\t\t}\n\t\t}\n\n\t\treturn deps;\n\t} catch {\n\t\treturn [];\n\t}\n}\n\n/**\n * Parse pyproject.toml dependencies\n */\nfunction parsePyprojectToml(path: string): Dependency[] {\n\ttry {\n\t\tconst content = readFileSync(path, \"utf-8\");\n\t\tconst deps: Dependency[] = [];\n\n\t\tconst depsSection = content.match(/\\[project\\.dependencies\\]([\\s\\S]*?)(?=\\[|$)/);\n\t\tif (!depsSection?.[1]) return [];\n\n\t\tconst lines = depsSection[1].split(\"\\n\");\n\t\tfor (const line of lines) {\n\t\t\tconst match = line.match(/[\"']([a-zA-Z0-9_-]+)(?:[>=<~!]+([^\"']+))?[\"']/);\n\t\t\tif (match?.[1]) {\n\t\t\t\tdeps.push({\n\t\t\t\t\tname: match[1],\n\t\t\t\t\tversion: match[2]?.trim(),\n\t\t\t\t\tdev: false,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn deps;\n\t} catch {\n\t\treturn [];\n\t}\n}\n\n/**\n * Parse Cargo.toml dependencies\n */\nfunction parseCargoToml(path: string): Dependency[] {\n\ttry {\n\t\tconst content = readFileSync(path, \"utf-8\");\n\t\tconst deps: Dependency[] = [];\n\n\t\tconst depsSection = content.match(/\\[dependencies\\]([\\s\\S]*?)(?=\\[|$)/);\n\t\tif (!depsSection?.[1]) return [];\n\n\t\tconst lines = depsSection[1].split(\"\\n\");\n\t\tfor (const line of lines) {\n\t\t\tconst simpleMatch = line.match(/^([a-zA-Z0-9_-]+)\\s*=\\s*\"([^\"]+)\"/);\n\t\t\tconst tableMatch = line.match(/^([a-zA-Z0-9_-]+)\\s*=\\s*{.*version\\s*=\\s*\"([^\"]+)\"/);\n\n\t\t\tif (simpleMatch?.[1] && simpleMatch[2]) {\n\t\t\t\tdeps.push({ name: simpleMatch[1], version: simpleMatch[2], dev: false });\n\t\t\t} else if (tableMatch?.[1] && tableMatch[2]) {\n\t\t\t\tdeps.push({ name: tableMatch[1], version: tableMatch[2], dev: false });\n\t\t\t}\n\t\t}\n\n\t\treturn deps;\n\t} catch {\n\t\treturn [];\n\t}\n}\n\n/**\n * Parse go.mod dependencies\n */\nfunction parseGoMod(path: string): Dependency[] {\n\ttry {\n\t\tconst content = readFileSync(path, \"utf-8\");\n\t\tconst deps: Dependency[] = [];\n\n\t\tconst requireSection = content.match(/require\\s*\\(([\\s\\S]*?)\\)/);\n\t\tif (!requireSection?.[1]) {\n\t\t\tconst singleRequire = content.match(/require\\s+([^\\s]+)\\s+([^\\s]+)/);\n\t\t\tif (singleRequire?.[1] && singleRequire[2]) {\n\t\t\t\tdeps.push({\n\t\t\t\t\tname: singleRequire[1],\n\t\t\t\t\tversion: singleRequire[2],\n\t\t\t\t\tdev: false,\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn deps;\n\t\t}\n\n\t\tconst lines = requireSection[1].split(\"\\n\");\n\t\tfor (const line of lines) {\n\t\t\tconst match = line.match(/^\\s*([^\\s]+)\\s+([^\\s]+)/);\n\t\t\tif (match?.[1] && match[2]) {\n\t\t\t\tdeps.push({ name: match[1], version: match[2], dev: false });\n\t\t\t}\n\t\t}\n\n\t\treturn deps;\n\t} catch {\n\t\treturn [];\n\t}\n}\n\n/**\n * Parse requirements.txt dependencies\n */\nfunction parseRequirementsTxt(path: string): Dependency[] {\n\ttry {\n\t\tconst content = readFileSync(path, \"utf-8\");\n\t\tconst deps: Dependency[] = [];\n\n\t\tconst lines = content.split(\"\\n\");\n\t\tfor (const line of lines) {\n\t\t\tconst trimmed = line.trim();\n\t\t\tif (!trimmed || trimmed.startsWith(\"#\")) continue;\n\n\t\t\tconst match = trimmed.match(/^([a-zA-Z0-9_-]+)(?:[>=<~!]+(.+))?/);\n\t\t\tif (match?.[1]) {\n\t\t\t\tdeps.push({\n\t\t\t\t\tname: match[1],\n\t\t\t\t\tversion: match[2]?.trim(),\n\t\t\t\t\tdev: false,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn deps;\n\t} catch {\n\t\treturn [];\n\t}\n}\n","/**\n * Reference matching utilities for dependency resolution\n *\n * Maps dependencies to their reference status (installed, remote, generate, unknown)\n */\n\nimport { existsSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { toReferenceFileName } from \"./config.js\";\nimport { Paths } from \"./paths.js\";\nimport type { ResolvedDep } from \"./dep-mappings.js\";\n\nexport type ReferenceStatus = \"installed\" | \"remote\" | \"generate\" | \"unknown\";\n\nexport interface ReferenceMatch {\n\t/** Dependency name */\n\tdep: string;\n\t/** GitHub repo (owner/repo) or null if unknown */\n\trepo: string | null;\n\t/** Reference availability status */\n\tstatus: ReferenceStatus;\n\t/** Resolution source: 'spec' | 'npm' | 'fallback' | 'unknown' */\n\tsource: \"spec\" | \"npm\" | \"fallback\" | \"unknown\";\n}\n\n/**\n * Check if a reference is installed locally.\n * A reference is considered installed if {owner-repo}.md exists in offworld/references/.\n *\n * @param repo - Repo name in owner/repo format\n * @returns true if reference is installed locally\n */\nexport function isReferenceInstalled(repo: string): boolean {\n\tconst referenceFileName = toReferenceFileName(repo);\n\tconst referencePath = join(Paths.offworldReferencesDir, referenceFileName);\n\treturn existsSync(referencePath);\n}\n\n/**\n * Match dependencies to their reference availability status.\n *\n * Status logic:\n * - installed: {owner-repo}.md exists in offworld/references/\n * - remote: Reference exists on offworld.sh (quick pull)\n * - generate: Has valid GitHub repo but needs AI generation (slow, uses tokens)\n * - unknown: No GitHub repo found\n *\n * @param resolvedDeps - Array of resolved dependencies with repo info\n * @returns Array of reference matches with status\n */\nexport function matchDependenciesToReferences(resolvedDeps: ResolvedDep[]): ReferenceMatch[] {\n\treturn resolvedDeps.map((dep) => {\n\t\tif (!dep.repo) {\n\t\t\treturn {\n\t\t\t\tdep: dep.dep,\n\t\t\t\trepo: null,\n\t\t\t\tstatus: \"unknown\",\n\t\t\t\tsource: dep.source,\n\t\t\t};\n\t\t}\n\n\t\tif (isReferenceInstalled(dep.repo)) {\n\t\t\treturn {\n\t\t\t\tdep: dep.dep,\n\t\t\t\trepo: dep.repo,\n\t\t\t\tstatus: \"installed\",\n\t\t\t\tsource: dep.source,\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tdep: dep.dep,\n\t\t\trepo: dep.repo,\n\t\t\tstatus: \"generate\",\n\t\t\tsource: dep.source,\n\t\t};\n\t});\n}\n\n/**\n * Match dependencies to their reference availability status with remote check.\n * This is async because it checks the remote server for each dependency.\n *\n * Status logic:\n * - installed: {owner-repo}.md exists in offworld/references/\n * - remote: Reference exists on offworld.sh (quick pull)\n * - generate: Has valid GitHub repo but needs AI generation (slow, uses tokens)\n * - unknown: No GitHub repo found\n *\n * @param resolvedDeps - Array of resolved dependencies with repo info\n * @returns Promise of array of reference matches with status\n */\nexport async function matchDependenciesToReferencesWithRemoteCheck(\n\tresolvedDeps: ResolvedDep[],\n): Promise<ReferenceMatch[]> {\n\tconst { checkRemote } = await import(\"./sync.js\");\n\tconst repoStatus = new Map<string, ReferenceStatus>();\n\n\tconst remoteChecks: Promise<void>[] = [];\n\tfor (const dep of resolvedDeps) {\n\t\tif (!dep.repo || repoStatus.has(dep.repo)) continue;\n\n\t\tif (isReferenceInstalled(dep.repo)) {\n\t\t\trepoStatus.set(dep.repo, \"installed\");\n\t\t\tcontinue;\n\t\t}\n\n\t\trepoStatus.set(dep.repo, \"generate\");\n\t\tremoteChecks.push(\n\t\t\t(async () => {\n\t\t\t\ttry {\n\t\t\t\t\tconst remote = await checkRemote(dep.repo!);\n\t\t\t\t\tif (remote.exists) {\n\t\t\t\t\t\trepoStatus.set(dep.repo!, \"remote\");\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Network error - keep generate status\n\t\t\t\t}\n\t\t\t})(),\n\t\t);\n\t}\n\n\tawait Promise.all(remoteChecks);\n\n\treturn resolvedDeps.map((dep) => {\n\t\tif (!dep.repo) {\n\t\t\treturn {\n\t\t\t\tdep: dep.dep,\n\t\t\t\trepo: null,\n\t\t\t\tstatus: \"unknown\" as const,\n\t\t\t\tsource: dep.source,\n\t\t\t};\n\t\t}\n\n\t\tconst status = repoStatus.get(dep.repo) ?? \"generate\";\n\t\treturn {\n\t\t\tdep: dep.dep,\n\t\t\trepo: dep.repo,\n\t\t\tstatus,\n\t\t\tsource: dep.source,\n\t\t};\n\t});\n}\n","import { existsSync, statSync, readdirSync, rmSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { updateRepo, GitError } from \"./clone.js\";\nimport { readGlobalMap, removeGlobalMapEntry, upsertGlobalMapEntry } from \"./index-manager.js\";\nimport { loadConfig, getRepoRoot } from \"./config.js\";\nimport { Paths } from \"./paths.js\";\n\nexport interface RepoStatusSummary {\n\ttotal: number;\n\twithReference: number;\n\tmissing: number;\n\tdiskBytes: number;\n}\n\nexport interface RepoStatusOptions {\n\tonProgress?: (current: number, total: number, repo: string) => void;\n}\n\nexport interface UpdateAllOptions {\n\tpattern?: string;\n\tdryRun?: boolean;\n\tonProgress?: (\n\t\trepo: string,\n\t\tstatus: \"updating\" | \"updated\" | \"skipped\" | \"error\",\n\t\tmessage?: string,\n\t) => void;\n}\n\nexport interface UpdateAllResult {\n\tupdated: string[];\n\tskipped: string[];\n\terrors: Array<{ repo: string; error: string }>;\n}\n\nexport interface PruneOptions {\n\tdryRun?: boolean;\n\tonProgress?: (repo: string, reason: string) => void;\n}\n\nexport interface PruneResult {\n\tremovedFromIndex: string[];\n\torphanedDirs: string[];\n}\n\nexport interface GcOptions {\n\tolderThanDays?: number;\n\twithoutReference?: boolean;\n\tdryRun?: boolean;\n\tonProgress?: (repo: string, reason: string, sizeBytes?: number) => void;\n}\n\nexport interface GcResult {\n\tremoved: Array<{ repo: string; reason: string; sizeBytes: number }>;\n\tfreedBytes: number;\n}\n\nfunction getDirSize(dirPath: string): number {\n\tif (!existsSync(dirPath)) return 0;\n\n\tlet size = 0;\n\ttry {\n\t\tconst entries = readdirSync(dirPath, { withFileTypes: true });\n\t\tfor (const entry of entries) {\n\t\t\tconst fullPath = join(dirPath, entry.name);\n\t\t\tif (entry.isDirectory()) {\n\t\t\t\tsize += getDirSize(fullPath);\n\t\t\t} else if (entry.isFile()) {\n\t\t\t\ttry {\n\t\t\t\t\tsize += statSync(fullPath).size;\n\t\t\t\t} catch {}\n\t\t\t}\n\t\t}\n\t} catch {}\n\treturn size;\n}\n\nfunction getLastAccessTime(dirPath: string): Date | null {\n\tif (!existsSync(dirPath)) return null;\n\n\tlet latestTime: Date | null = null;\n\ttry {\n\t\tconst stat = statSync(dirPath);\n\t\tlatestTime = stat.mtime;\n\n\t\tconst fetchHead = join(dirPath, \".git\", \"FETCH_HEAD\");\n\t\tif (existsSync(fetchHead)) {\n\t\t\tconst fetchStat = statSync(fetchHead);\n\t\t\tif (!latestTime || fetchStat.mtime > latestTime) {\n\t\t\t\tlatestTime = fetchStat.mtime;\n\t\t\t}\n\t\t}\n\t} catch {}\n\treturn latestTime;\n}\n\nfunction matchesPattern(name: string, pattern: string): boolean {\n\tif (!pattern || pattern === \"*\") return true;\n\n\tconst regex = new RegExp(\n\t\t\"^\" +\n\t\t\tpattern\n\t\t\t\t.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\")\n\t\t\t\t.replace(/\\*/g, \".*\")\n\t\t\t\t.replace(/\\?/g, \".\") +\n\t\t\t\"$\",\n\t\t\"i\",\n\t);\n\treturn regex.test(name);\n}\n\nconst yieldToEventLoop = () => new Promise<void>((resolve) => setImmediate(resolve));\n\nexport async function getRepoStatus(options: RepoStatusOptions = {}): Promise<RepoStatusSummary> {\n\tconst { onProgress } = options;\n\tconst map = readGlobalMap();\n\tconst qualifiedNames = Object.keys(map.repos);\n\tconst total = qualifiedNames.length;\n\n\tlet withReference = 0;\n\tlet missing = 0;\n\tlet diskBytes = 0;\n\n\tfor (let i = 0; i < qualifiedNames.length; i++) {\n\t\tconst qualifiedName = qualifiedNames[i]!;\n\t\tconst entry = map.repos[qualifiedName]!;\n\t\tonProgress?.(i + 1, total, qualifiedName);\n\n\t\tawait yieldToEventLoop();\n\n\t\tconst exists = existsSync(entry.localPath);\n\n\t\tif (!exists) {\n\t\t\tmissing++;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (entry.references.length > 0) {\n\t\t\twithReference++;\n\t\t}\n\n\t\tdiskBytes += getDirSize(entry.localPath);\n\t}\n\n\treturn {\n\t\ttotal,\n\t\twithReference,\n\t\tmissing,\n\t\tdiskBytes,\n\t};\n}\n\nexport async function updateAllRepos(options: UpdateAllOptions = {}): Promise<UpdateAllResult> {\n\tconst { pattern, dryRun = false, onProgress } = options;\n\n\tconst map = readGlobalMap();\n\tconst qualifiedNames = Object.keys(map.repos);\n\tconst updated: string[] = [];\n\tconst skipped: string[] = [];\n\tconst errors: Array<{ repo: string; error: string }> = [];\n\n\tfor (const qualifiedName of qualifiedNames) {\n\t\tconst entry = map.repos[qualifiedName]!;\n\n\t\tif (pattern && !matchesPattern(qualifiedName, pattern)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (!existsSync(entry.localPath)) {\n\t\t\tskipped.push(qualifiedName);\n\t\t\tonProgress?.(qualifiedName, \"skipped\", \"missing on disk\");\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (dryRun) {\n\t\t\tupdated.push(qualifiedName);\n\t\t\tonProgress?.(qualifiedName, \"updated\", \"would update\");\n\t\t\tcontinue;\n\t\t}\n\n\t\tonProgress?.(qualifiedName, \"updating\");\n\t\ttry {\n\t\t\tconst result = await updateRepo(qualifiedName);\n\t\t\tif (result.updated) {\n\t\t\t\tupdated.push(qualifiedName);\n\t\t\t\tonProgress?.(\n\t\t\t\t\tqualifiedName,\n\t\t\t\t\t\"updated\",\n\t\t\t\t\t`${result.previousSha.slice(0, 7)} → ${result.currentSha.slice(0, 7)}`,\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tskipped.push(qualifiedName);\n\t\t\t\tonProgress?.(qualifiedName, \"skipped\", \"already up to date\");\n\t\t\t}\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof GitError ? err.message : String(err);\n\t\t\terrors.push({ repo: qualifiedName, error: message });\n\t\t\tonProgress?.(qualifiedName, \"error\", message);\n\t\t}\n\t}\n\n\treturn { updated, skipped, errors };\n}\n\nexport async function pruneRepos(options: PruneOptions = {}): Promise<PruneResult> {\n\tconst { dryRun = false, onProgress } = options;\n\n\tconst map = readGlobalMap();\n\tconst qualifiedNames = Object.keys(map.repos);\n\tconst removedFromIndex: string[] = [];\n\tconst orphanedDirs: string[] = [];\n\n\tfor (const qualifiedName of qualifiedNames) {\n\t\tconst entry = map.repos[qualifiedName]!;\n\t\tawait yieldToEventLoop();\n\n\t\tif (!existsSync(entry.localPath)) {\n\t\t\tonProgress?.(qualifiedName, \"missing on disk\");\n\t\t\tremovedFromIndex.push(qualifiedName);\n\n\t\t\tif (!dryRun) {\n\t\t\t\tremoveGlobalMapEntry(qualifiedName);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst config = loadConfig();\n\tconst repoRoot = getRepoRoot(config);\n\n\tif (existsSync(repoRoot)) {\n\t\tconst indexedPaths = new Set(Object.values(map.repos).map((r) => r.localPath));\n\n\t\ttry {\n\t\t\tconst providers = readdirSync(repoRoot, { withFileTypes: true });\n\t\t\tfor (const provider of providers) {\n\t\t\t\tif (!provider.isDirectory()) continue;\n\t\t\t\tconst providerPath = join(repoRoot, provider.name);\n\n\t\t\t\tconst owners = readdirSync(providerPath, { withFileTypes: true });\n\t\t\t\tfor (const owner of owners) {\n\t\t\t\t\tif (!owner.isDirectory()) continue;\n\t\t\t\t\tconst ownerPath = join(providerPath, owner.name);\n\n\t\t\t\t\tconst repoNames = readdirSync(ownerPath, { withFileTypes: true });\n\t\t\t\t\tfor (const repoName of repoNames) {\n\t\t\t\t\t\tawait yieldToEventLoop();\n\n\t\t\t\t\t\tif (!repoName.isDirectory()) continue;\n\t\t\t\t\t\tconst repoPath = join(ownerPath, repoName.name);\n\n\t\t\t\t\t\tif (!existsSync(join(repoPath, \".git\"))) continue;\n\n\t\t\t\t\t\tif (!indexedPaths.has(repoPath)) {\n\t\t\t\t\t\t\tconst fullName = `${owner.name}/${repoName.name}`;\n\t\t\t\t\t\t\tonProgress?.(fullName, \"not in map\");\n\t\t\t\t\t\t\torphanedDirs.push(repoPath);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} catch {}\n\t}\n\n\treturn { removedFromIndex, orphanedDirs };\n}\n\nexport async function gcRepos(options: GcOptions = {}): Promise<GcResult> {\n\tconst { olderThanDays, withoutReference = false, dryRun = false, onProgress } = options;\n\n\tconst map = readGlobalMap();\n\tconst qualifiedNames = Object.keys(map.repos);\n\tconst removed: Array<{ repo: string; reason: string; sizeBytes: number }> = [];\n\tlet freedBytes = 0;\n\n\tconst now = new Date();\n\tconst cutoffDate = olderThanDays\n\t\t? new Date(now.getTime() - olderThanDays * 24 * 60 * 60 * 1000)\n\t\t: null;\n\n\tfor (const qualifiedName of qualifiedNames) {\n\t\tconst entry = map.repos[qualifiedName]!;\n\t\tawait yieldToEventLoop();\n\n\t\tif (!existsSync(entry.localPath)) continue;\n\n\t\tlet shouldRemove = false;\n\t\tlet reason = \"\";\n\n\t\tif (cutoffDate) {\n\t\t\tconst lastAccess = getLastAccessTime(entry.localPath);\n\t\t\tif (lastAccess && lastAccess < cutoffDate) {\n\t\t\t\tshouldRemove = true;\n\t\t\t\treason = `not accessed in ${olderThanDays}+ days`;\n\t\t\t}\n\t\t}\n\n\t\tif (withoutReference && entry.references.length === 0) {\n\t\t\tshouldRemove = true;\n\t\t\treason = reason ? `${reason}, no reference` : \"no reference\";\n\t\t}\n\n\t\tif (!shouldRemove) continue;\n\n\t\tconst sizeBytes = getDirSize(entry.localPath);\n\t\tonProgress?.(qualifiedName, reason, sizeBytes);\n\n\t\tif (!dryRun) {\n\t\t\trmSync(entry.localPath, { recursive: true, force: true });\n\n\t\t\tfor (const refFile of entry.references) {\n\t\t\t\tconst refPath = join(Paths.offworldReferencesDir, refFile);\n\t\t\t\tif (existsSync(refPath)) {\n\t\t\t\t\trmSync(refPath, { force: true });\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (entry.primary) {\n\t\t\t\tconst metaDirName = entry.primary.replace(/\\.md$/, \"\");\n\t\t\t\tconst metaPath = join(Paths.metaDir, metaDirName);\n\t\t\t\tif (existsSync(metaPath)) {\n\t\t\t\t\trmSync(metaPath, { recursive: true, force: true });\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tremoveGlobalMapEntry(qualifiedName);\n\t\t}\n\n\t\tremoved.push({ repo: qualifiedName, reason, sizeBytes });\n\t\tfreedBytes += sizeBytes;\n\t}\n\n\treturn { removed, freedBytes };\n}\n\nexport interface DiscoverOptions {\n\trepoRoot?: string;\n\tdryRun?: boolean;\n\tonProgress?: (repo: string, provider: string) => void;\n}\n\nexport interface DiscoverResult {\n\tdiscovered: Array<{ fullName: string; qualifiedName: string; localPath: string }>;\n\talreadyIndexed: number;\n}\n\nexport async function discoverRepos(options: DiscoverOptions = {}): Promise<DiscoverResult> {\n\tconst { dryRun = false, onProgress } = options;\n\n\tconst config = loadConfig();\n\tconst repoRoot = options.repoRoot ?? getRepoRoot(config);\n\tconst discovered: Array<{ fullName: string; qualifiedName: string; localPath: string }> = [];\n\tlet alreadyIndexed = 0;\n\n\tif (!existsSync(repoRoot)) {\n\t\treturn { discovered, alreadyIndexed };\n\t}\n\n\tconst map = readGlobalMap();\n\tconst indexedPaths = new Set(Object.values(map.repos).map((r) => r.localPath));\n\n\ttry {\n\t\tconst providers = readdirSync(repoRoot, { withFileTypes: true });\n\t\tfor (const provider of providers) {\n\t\t\tif (!provider.isDirectory()) continue;\n\t\t\tconst providerPath = join(repoRoot, provider.name);\n\n\t\t\tconst providerHostMap: Record<string, string> = {\n\t\t\t\tgithub: \"github.com\",\n\t\t\t\tgitlab: \"gitlab.com\",\n\t\t\t\tbitbucket: \"bitbucket.org\",\n\t\t\t};\n\t\t\tconst providerHost = providerHostMap[provider.name] ?? provider.name;\n\n\t\t\tconst owners = readdirSync(providerPath, { withFileTypes: true });\n\t\t\tfor (const owner of owners) {\n\t\t\t\tif (!owner.isDirectory()) continue;\n\t\t\t\tconst ownerPath = join(providerPath, owner.name);\n\n\t\t\t\tconst repoNames = readdirSync(ownerPath, { withFileTypes: true });\n\t\t\t\tfor (const repoName of repoNames) {\n\t\t\t\t\tawait yieldToEventLoop();\n\n\t\t\t\t\tif (!repoName.isDirectory()) continue;\n\t\t\t\t\tconst repoPath = join(ownerPath, repoName.name);\n\n\t\t\t\t\tif (!existsSync(join(repoPath, \".git\"))) continue;\n\n\t\t\t\t\tif (indexedPaths.has(repoPath)) {\n\t\t\t\t\t\talreadyIndexed++;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst fullName = `${owner.name}/${repoName.name}`;\n\t\t\t\t\tconst qualifiedName = `${providerHost}:${fullName}`;\n\n\t\t\t\t\tonProgress?.(fullName, providerHost);\n\n\t\t\t\t\tif (!dryRun) {\n\t\t\t\t\t\tupsertGlobalMapEntry(qualifiedName, {\n\t\t\t\t\t\t\tlocalPath: repoPath,\n\t\t\t\t\t\t\treferences: [],\n\t\t\t\t\t\t\tprimary: \"\",\n\t\t\t\t\t\t\tkeywords: [],\n\t\t\t\t\t\t\tupdatedAt: new Date().toISOString(),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tdiscovered.push({ fullName, qualifiedName, localPath: repoPath });\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} catch {}\n\n\treturn { discovered, alreadyIndexed };\n}\n","import { ModelsDevDataSchema, type ModelsDevProvider } from \"@offworld/types\";\n\nconst MODELS_DEV_URL = \"https://models.dev/api.json\";\n\n/**\n * Simplified provider info for CLI display\n */\nexport interface ProviderInfo {\n\tid: string;\n\tname: string;\n\tenv: string[];\n}\n\n/**\n * Simplified model info for CLI display\n */\nexport interface ModelInfo {\n\tid: string;\n\tname: string;\n\treasoning: boolean;\n\texperimental?: boolean;\n\tstatus?: \"alpha\" | \"beta\" | \"deprecated\";\n}\n\n/**\n * Full provider with models for CLI display\n */\nexport interface ProviderWithModels extends ProviderInfo {\n\tmodels: ModelInfo[];\n}\n\nlet cachedData: Record<string, ModelsDevProvider> | null = null;\nlet cacheTime = 0;\nconst CACHE_TTL_MS = 5 * 60 * 1000;\n\n/**\n * Fetch raw data from models.dev with caching\n */\nasync function fetchModelsDevData(): Promise<Record<string, ModelsDevProvider>> {\n\tconst now = Date.now();\n\tif (cachedData && now - cacheTime < CACHE_TTL_MS) {\n\t\treturn cachedData;\n\t}\n\n\tconst res = await fetch(MODELS_DEV_URL, {\n\t\tsignal: AbortSignal.timeout(10_000),\n\t});\n\n\tif (!res.ok) {\n\t\tthrow new Error(`Failed to fetch models.dev: ${res.status} ${res.statusText}`);\n\t}\n\n\tconst json = await res.json();\n\tconst parsed = ModelsDevDataSchema.safeParse(json);\n\tif (!parsed.success) {\n\t\tthrow new Error(`Invalid models.dev response: ${parsed.error.message}`);\n\t}\n\tcachedData = parsed.data;\n\tcacheTime = now;\n\treturn cachedData;\n}\n\n/**\n * List all available providers from models.dev\n */\nexport async function listProviders(): Promise<ProviderInfo[]> {\n\tconst data = await fetchModelsDevData();\n\n\treturn Object.values(data)\n\t\t.map((p) => ({\n\t\t\tid: p.id,\n\t\t\tname: p.name,\n\t\t\tenv: p.env ?? [],\n\t\t}))\n\t\t.sort((a, b) => a.name.localeCompare(b.name));\n}\n\n/**\n * Get a specific provider with all its models\n */\nexport async function getProvider(providerId: string): Promise<ProviderWithModels | null> {\n\tconst data = await fetchModelsDevData();\n\tconst provider = data[providerId];\n\n\tif (!provider) {\n\t\treturn null;\n\t}\n\n\treturn {\n\t\tid: provider.id,\n\t\tname: provider.name,\n\t\tenv: provider.env ?? [],\n\t\tmodels: Object.values(provider.models)\n\t\t\t.filter((m) => m.status !== \"deprecated\")\n\t\t\t.map((m) => ({\n\t\t\t\tid: m.id,\n\t\t\t\tname: m.name,\n\t\t\t\treasoning: m.reasoning ?? false,\n\t\t\t\texperimental: m.experimental,\n\t\t\t\tstatus: m.status,\n\t\t\t}))\n\t\t\t.sort((a, b) => a.name.localeCompare(b.name)),\n\t};\n}\n\n/**\n * Get all providers with their models\n */\nexport async function listProvidersWithModels(): Promise<ProviderWithModels[]> {\n\tconst data = await fetchModelsDevData();\n\n\treturn Object.values(data)\n\t\t.map((p) => ({\n\t\t\tid: p.id,\n\t\t\tname: p.name,\n\t\t\tenv: p.env ?? [],\n\t\t\tmodels: Object.values(p.models)\n\t\t\t\t.filter((m) => m.status !== \"deprecated\")\n\t\t\t\t.map((m) => ({\n\t\t\t\t\tid: m.id,\n\t\t\t\t\tname: m.name,\n\t\t\t\t\treasoning: m.reasoning ?? false,\n\t\t\t\t\texperimental: m.experimental,\n\t\t\t\t\tstatus: m.status,\n\t\t\t\t}))\n\t\t\t\t.sort((a, b) => a.name.localeCompare(b.name)),\n\t\t}))\n\t\t.sort((a, b) => a.name.localeCompare(b.name));\n}\n\n/**\n * Validate that a provider/model combination exists\n */\nexport async function validateProviderModel(\n\tproviderId: string,\n\tmodelId: string,\n): Promise<{ valid: boolean; error?: string }> {\n\tconst provider = await getProvider(providerId);\n\n\tif (!provider) {\n\t\tconst providers = await listProviders();\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\terror: `Provider \"${providerId}\" not found. Available: ${providers\n\t\t\t\t.slice(0, 10)\n\t\t\t\t.map((p) => p.id)\n\t\t\t\t.join(\", \")}${providers.length > 10 ? \"...\" : \"\"}`,\n\t\t};\n\t}\n\n\tconst model = provider.models.find((m) => m.id === modelId);\n\tif (!model) {\n\t\treturn {\n\t\t\tvalid: false,\n\t\t\terror: `Model \"${modelId}\" not found for provider \"${providerId}\". Available: ${provider.models\n\t\t\t\t.slice(0, 10)\n\t\t\t\t.map((m) => m.id)\n\t\t\t\t.join(\", \")}${provider.models.length > 10 ? \"...\" : \"\"}`,\n\t\t};\n\t}\n\n\treturn { valid: true };\n}\n"],"mappings":"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"}