@crewdhq/crewd-mcp 0.0.0-stage → 0.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +189 -2
  3. package/dist-mcp/cli.d.ts +3 -0
  4. package/dist-mcp/cli.d.ts.map +1 -0
  5. package/dist-mcp/cli.js +9 -0
  6. package/dist-mcp/cli.js.map +1 -0
  7. package/dist-mcp/core/adapters.d.ts +29 -0
  8. package/dist-mcp/core/adapters.d.ts.map +1 -0
  9. package/dist-mcp/core/adapters.js +306 -0
  10. package/dist-mcp/core/adapters.js.map +1 -0
  11. package/dist-mcp/core/installer.d.ts +42 -0
  12. package/dist-mcp/core/installer.d.ts.map +1 -0
  13. package/dist-mcp/core/installer.js +236 -0
  14. package/dist-mcp/core/installer.js.map +1 -0
  15. package/dist-mcp/core/manifest.d.ts +17 -0
  16. package/dist-mcp/core/manifest.d.ts.map +1 -0
  17. package/dist-mcp/core/manifest.js +128 -0
  18. package/dist-mcp/core/manifest.js.map +1 -0
  19. package/dist-mcp/core/project.d.ts +11 -0
  20. package/dist-mcp/core/project.d.ts.map +1 -0
  21. package/dist-mcp/core/project.js +57 -0
  22. package/dist-mcp/core/project.js.map +1 -0
  23. package/dist-mcp/core/registry.d.ts +36 -0
  24. package/dist-mcp/core/registry.d.ts.map +1 -0
  25. package/dist-mcp/core/registry.js +224 -0
  26. package/dist-mcp/core/registry.js.map +1 -0
  27. package/dist-mcp/core/tar.d.ts +23 -0
  28. package/dist-mcp/core/tar.d.ts.map +1 -0
  29. package/dist-mcp/core/tar.js +145 -0
  30. package/dist-mcp/core/tar.js.map +1 -0
  31. package/dist-mcp/core/token.d.ts +23 -0
  32. package/dist-mcp/core/token.d.ts.map +1 -0
  33. package/dist-mcp/core/token.js +70 -0
  34. package/dist-mcp/core/token.js.map +1 -0
  35. package/dist-mcp/server.d.ts +14 -0
  36. package/dist-mcp/server.d.ts.map +1 -0
  37. package/dist-mcp/server.js +429 -0
  38. package/dist-mcp/server.js.map +1 -0
  39. package/dist-mcp/types.d.ts +141 -0
  40. package/dist-mcp/types.d.ts.map +1 -0
  41. package/dist-mcp/types.js +43 -0
  42. package/dist-mcp/types.js.map +1 -0
  43. package/package.json +52 -4
@@ -0,0 +1,236 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.planHire = planHire;
7
+ exports.executeHire = executeHire;
8
+ const node_path_1 = __importDefault(require("node:path"));
9
+ const node_fs_1 = __importDefault(require("node:fs"));
10
+ const node_crypto_1 = __importDefault(require("node:crypto"));
11
+ const project_js_1 = require("./project.js");
12
+ const manifest_js_1 = require("./manifest.js");
13
+ const registry_js_1 = require("./registry.js");
14
+ const tar_js_1 = require("./tar.js");
15
+ const adapters_js_1 = require("./adapters.js");
16
+ const token_js_1 = require("./token.js");
17
+ const types_js_1 = require("../types.js");
18
+ function resolveTargetHosts(targets, existingManifest, repoRoot) {
19
+ if (targets && targets.length > 0) {
20
+ return targets.map((t) => types_js_1.HOST_MAP[t] || t);
21
+ }
22
+ if (existingManifest && existingManifest.hosts && existingManifest.hosts.length > 0) {
23
+ return existingManifest.hosts;
24
+ }
25
+ if (repoRoot) {
26
+ return (0, project_js_1.detectHosts)(repoRoot);
27
+ }
28
+ return ["claude-code"];
29
+ }
30
+ /**
31
+ * Plans a hire operation without writing anything to disk.
32
+ * Downloads tarball, verifies SHA-256 integrity, renders templates in memory,
33
+ * flags any executable scripts, and issues a short-lived confirm_token.
34
+ */
35
+ async function planHire(packageRef, targetHosts, client, customRoot) {
36
+ const repoRoot = customRoot || (0, project_js_1.findProjectRoot)();
37
+ const registryClient = client || new registry_js_1.RegistryClient();
38
+ const { fullName, namespace, name, versionRange } = (0, registry_js_1.parsePackageRef)(packageRef);
39
+ // Check package from registry
40
+ const pkgSummary = await registryClient.getPackage(namespace, name);
41
+ const isTeam = pkgSummary.type === "team";
42
+ const manifest = (0, manifest_js_1.readManifest)(repoRoot) || {
43
+ hosts: resolveTargetHosts(targetHosts, null, repoRoot),
44
+ crew: {},
45
+ };
46
+ const hosts = resolveTargetHosts(targetHosts, manifest, repoRoot);
47
+ // Prepare resolve payload
48
+ const existingCrew = Object.entries(manifest.crew || {}).map(([pkgName, entry]) => {
49
+ let range = "*";
50
+ let team = false;
51
+ if (typeof entry === "string") {
52
+ range = entry;
53
+ }
54
+ else if (typeof entry === "object" && entry) {
55
+ if ("team" in entry && typeof entry.team === "string") {
56
+ range = entry.team;
57
+ team = true;
58
+ }
59
+ else if ("version" in entry && typeof entry.version === "string") {
60
+ range = entry.version;
61
+ }
62
+ }
63
+ return { name: pkgName, range, isTeam: team };
64
+ });
65
+ // Add target package
66
+ const resolveList = [...existingCrew.filter((e) => e.name !== fullName), { name: fullName, range: versionRange, isTeam }];
67
+ const resolveRes = await registryClient.resolve(resolveList, hosts);
68
+ const resolvedPkgKey = Object.keys(resolveRes.packages).find((k) => k.startsWith(fullName + "@") || k === fullName);
69
+ if (!resolvedPkgKey || !resolveRes.packages[resolvedPkgKey]) {
70
+ throw new Error(`Registry failed to resolve package ${fullName}@${versionRange}`);
71
+ }
72
+ const resolvedPkg = resolveRes.packages[resolvedPkgKey];
73
+ // Download tarball to inspect files and scripts (in-memory only, no disk writes)
74
+ const tarballBuffer = await registryClient.downloadTarball(resolvedPkg.tarballUrl);
75
+ (0, tar_js_1.verifyTarballIntegrity)(tarballBuffer, resolvedPkg.integrity);
76
+ const files = await (0, tar_js_1.unpackTarballInMemory)(tarballBuffer);
77
+ const pkgManifest = (0, adapters_js_1.parsePackageManifestFromFiles)(files);
78
+ if (!pkgManifest) {
79
+ throw new Error(`Package ${fullName} is missing agent.yaml or skill.yaml in archive`);
80
+ }
81
+ // Detect and flag any executable scripts
82
+ const flaggedScripts = [];
83
+ const declaredScripts = pkgManifest.scripts || resolvedPkg.scripts || [];
84
+ for (const [filePath, file] of files.entries()) {
85
+ const isScript = filePath.endsWith(".sh") ||
86
+ filePath.startsWith("scripts/") ||
87
+ declaredScripts.includes(filePath) ||
88
+ filePath.endsWith(".bash");
89
+ if (isScript) {
90
+ const previewLines = file.content.toString("utf-8").split("\n").slice(0, 5).join("\n");
91
+ flaggedScripts.push({
92
+ path: filePath,
93
+ warning: "Executable script contained in package. Crewd MCP will install scripts as files only and will NEVER execute them.",
94
+ preview: (0, registry_js_1.sanitizeUntrustedText)(previewLines, 300),
95
+ });
96
+ }
97
+ }
98
+ // Compile files in memory
99
+ const generatedFiles = (0, adapters_js_1.compilePackageFiles)(fullName, resolvedPkg.version, pkgManifest, files, hosts, repoRoot);
100
+ const plannedFiles = [];
101
+ for (const gf of generatedFiles) {
102
+ const fullPath = node_path_1.default.join(repoRoot, gf.path);
103
+ const action = node_fs_1.default.existsSync(fullPath) ? "update" : "create";
104
+ const contentBuffer = typeof gf.content === "string" ? Buffer.from(gf.content, "utf-8") : gf.content;
105
+ const sha256 = node_crypto_1.default.createHash("sha256").update(contentBuffer).digest("hex");
106
+ plannedFiles.push({
107
+ path: gf.path,
108
+ action,
109
+ sha256,
110
+ });
111
+ }
112
+ // Generate single-use confirm token
113
+ const tokenData = (0, token_js_1.createConfirmToken)(fullName, resolvedPkg.version, plannedFiles.map((f) => f.path), resolvedPkg.integrity);
114
+ const summary = `Planned hire for ${fullName}@${resolvedPkg.version} into [${hosts.join(", ")}]. ${plannedFiles.length} files planned. ${flaggedScripts.length > 0 ? `WARNING: ${flaggedScripts.length} script(s) flagged.` : "No scripts flagged."}`;
115
+ return {
116
+ packageName: fullName,
117
+ requestedVersion: versionRange,
118
+ resolvedVersion: resolvedPkg.version,
119
+ packageType: resolvedPkg.type || pkgSummary.type,
120
+ targetHosts: hosts,
121
+ plannedFiles,
122
+ flaggedScripts,
123
+ confirmToken: tokenData.token,
124
+ expiresAt: new Date(tokenData.expiresAt).toISOString(),
125
+ summary,
126
+ };
127
+ }
128
+ /**
129
+ * Performs actual hire using a verified single-use confirm_token.
130
+ * Enforces security checks: valid token, directory safety, hash verification, file-only script installation.
131
+ */
132
+ async function executeHire(packageRef, confirmToken, version, targetHosts, client, customRoot) {
133
+ const repoRoot = customRoot || (0, project_js_1.findProjectRoot)();
134
+ const registryClient = client || new registry_js_1.RegistryClient();
135
+ const { fullName, namespace, name, versionRange } = (0, registry_js_1.parsePackageRef)(packageRef);
136
+ // Validate and consume the confirm token
137
+ const tokenData = (0, token_js_1.consumeConfirmToken)(confirmToken, fullName, version);
138
+ const pkgSummary = await registryClient.getPackage(namespace, name);
139
+ const isTeam = pkgSummary.type === "team";
140
+ // Read manifest or create default
141
+ let manifest = (0, manifest_js_1.readManifest)(repoRoot);
142
+ if (!manifest) {
143
+ manifest = {
144
+ $schema: "https://crewd.dev/schema/manifest/v1",
145
+ hosts: resolveTargetHosts(targetHosts, null, repoRoot),
146
+ crew: {},
147
+ };
148
+ }
149
+ const hosts = resolveTargetHosts(targetHosts, manifest, repoRoot);
150
+ manifest.hosts = hosts;
151
+ // Add to manifest
152
+ const targetVersion = version || tokenData.version || versionRange;
153
+ manifest.crew[fullName] = isTeam ? { team: targetVersion } : targetVersion;
154
+ // Resolve
155
+ const existingCrew = Object.entries(manifest.crew).map(([pkgName, entry]) => {
156
+ let range = "*";
157
+ let team = false;
158
+ if (typeof entry === "string") {
159
+ range = entry;
160
+ }
161
+ else if (typeof entry === "object" && entry) {
162
+ if ("team" in entry && typeof entry.team === "string") {
163
+ range = entry.team;
164
+ team = true;
165
+ }
166
+ else if ("version" in entry && typeof entry.version === "string") {
167
+ range = entry.version;
168
+ }
169
+ }
170
+ return { name: pkgName, range, isTeam: team };
171
+ });
172
+ const resolveRes = await registryClient.resolve(existingCrew, hosts);
173
+ const resolvedPkgKey = Object.keys(resolveRes.packages).find((k) => k.startsWith(fullName + "@") || k === fullName);
174
+ if (!resolvedPkgKey || !resolveRes.packages[resolvedPkgKey]) {
175
+ throw new Error(`Registry failed to resolve package ${fullName}`);
176
+ }
177
+ const resolvedPkg = resolveRes.packages[resolvedPkgKey];
178
+ // Download tarball and verify SHA-256 integrity
179
+ const tarballBuffer = await registryClient.downloadTarball(resolvedPkg.tarballUrl);
180
+ (0, tar_js_1.verifyTarballIntegrity)(tarballBuffer, resolvedPkg.integrity);
181
+ const files = await (0, tar_js_1.unpackTarballInMemory)(tarballBuffer);
182
+ const pkgManifest = (0, adapters_js_1.parsePackageManifestFromFiles)(files);
183
+ if (!pkgManifest) {
184
+ throw new Error(`Package ${fullName} is missing agent.yaml or skill.yaml`);
185
+ }
186
+ // Compile host adapters
187
+ const generatedFiles = (0, adapters_js_1.compilePackageFiles)(fullName, resolvedPkg.version, pkgManifest, files, hosts, repoRoot);
188
+ const installedFiles = [];
189
+ // Write native host files safely inside repoRoot
190
+ for (const gf of generatedFiles) {
191
+ const fullPath = (0, tar_js_1.validateSafePath)(gf.path, repoRoot);
192
+ node_fs_1.default.mkdirSync(node_path_1.default.dirname(fullPath), { recursive: true });
193
+ node_fs_1.default.writeFileSync(fullPath, gf.content);
194
+ installedFiles.push(gf.path);
195
+ }
196
+ // Update .gitignore
197
+ (0, adapters_js_1.updateGitignoreBlocks)(repoRoot, hosts);
198
+ // Read lockfile or create new
199
+ let lockfile = (0, manifest_js_1.readLockfile)(repoRoot);
200
+ if (!lockfile) {
201
+ lockfile = {
202
+ lockfileVersion: 1,
203
+ manifestHash: "",
204
+ adapterVersions: {},
205
+ packages: {},
206
+ };
207
+ }
208
+ for (const h of hosts) {
209
+ lockfile.adapterVersions = lockfile.adapterVersions || {};
210
+ lockfile.adapterVersions[h] = 1;
211
+ }
212
+ // Update lockfile package entry
213
+ const lockKey = `${fullName}@${resolvedPkg.version}`;
214
+ lockfile.packages[lockKey] = {
215
+ type: resolvedPkg.type || pkgSummary.type,
216
+ integrity: resolvedPkg.integrity,
217
+ skills: resolvedPkg.skills,
218
+ members: resolvedPkg.members,
219
+ via: resolvedPkg.via,
220
+ scripts: resolvedPkg.scripts,
221
+ };
222
+ // Compute updated manifest hash and record in lockfile
223
+ lockfile.manifestHash = (0, manifest_js_1.computeManifestHash)(manifest);
224
+ // Atomically write crewd.json and crewd.lock
225
+ (0, manifest_js_1.writeManifestAtomic)(repoRoot, manifest);
226
+ (0, manifest_js_1.writeLockfileAtomic)(repoRoot, lockfile);
227
+ return {
228
+ packageName: fullName,
229
+ version: resolvedPkg.version,
230
+ installedFiles,
231
+ manifestUpdated: true,
232
+ lockfileUpdated: true,
233
+ summary: `Successfully hired ${fullName}@${resolvedPkg.version} into ${repoRoot}. ${installedFiles.length} files installed. crewd.json and crewd.lock updated.`,
234
+ };
235
+ }
236
+ //# sourceMappingURL=installer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"installer.js","sourceRoot":"","sources":["../../src/core/installer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import { CrewdManifest, CrewdLockfile } from "../types.js";
2
+ export declare const DEFAULT_MANIFEST_SCHEMA = "https://crewd.dev/schema/manifest/v1";
3
+ export declare function readManifest(repoRoot: string): CrewdManifest | null;
4
+ export declare function readLockfile(repoRoot: string): CrewdLockfile | null;
5
+ /**
6
+ * Computes canonical deterministic SHA-256 hash matching Go CLI implementation.
7
+ */
8
+ export declare function computeManifestHash(m: CrewdManifest): string;
9
+ /**
10
+ * Writes crewd.json atomically.
11
+ */
12
+ export declare function writeManifestAtomic(repoRoot: string, manifest: CrewdManifest): void;
13
+ /**
14
+ * Writes crewd.lock atomically.
15
+ */
16
+ export declare function writeLockfileAtomic(repoRoot: string, lockfile: CrewdLockfile): void;
17
+ //# sourceMappingURL=manifest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/core/manifest.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE3D,eAAO,MAAM,uBAAuB,yCAAyC,CAAC;AAE9E,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAWnE;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAWnE;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,aAAa,GAAG,MAAM,CAmC5D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,GAAG,IAAI,CAkCnF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,GAAG,IAAI,CAenF"}
@@ -0,0 +1,128 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.DEFAULT_MANIFEST_SCHEMA = void 0;
7
+ exports.readManifest = readManifest;
8
+ exports.readLockfile = readLockfile;
9
+ exports.computeManifestHash = computeManifestHash;
10
+ exports.writeManifestAtomic = writeManifestAtomic;
11
+ exports.writeLockfileAtomic = writeLockfileAtomic;
12
+ const node_fs_1 = __importDefault(require("node:fs"));
13
+ const node_path_1 = __importDefault(require("node:path"));
14
+ const node_crypto_1 = __importDefault(require("node:crypto"));
15
+ const yaml_1 = __importDefault(require("yaml"));
16
+ exports.DEFAULT_MANIFEST_SCHEMA = "https://crewd.dev/schema/manifest/v1";
17
+ function readManifest(repoRoot) {
18
+ const filePath = node_path_1.default.join(repoRoot, "crewd.json");
19
+ if (!node_fs_1.default.existsSync(filePath)) {
20
+ return null;
21
+ }
22
+ try {
23
+ const raw = node_fs_1.default.readFileSync(filePath, "utf-8");
24
+ return JSON.parse(raw);
25
+ }
26
+ catch (err) {
27
+ throw new Error(`Failed to parse crewd.json: ${err instanceof Error ? err.message : String(err)}`);
28
+ }
29
+ }
30
+ function readLockfile(repoRoot) {
31
+ const filePath = node_path_1.default.join(repoRoot, "crewd.lock");
32
+ if (!node_fs_1.default.existsSync(filePath)) {
33
+ return null;
34
+ }
35
+ try {
36
+ const raw = node_fs_1.default.readFileSync(filePath, "utf-8");
37
+ return yaml_1.default.parse(raw);
38
+ }
39
+ catch (err) {
40
+ throw new Error(`Failed to parse crewd.lock: ${err instanceof Error ? err.message : String(err)}`);
41
+ }
42
+ }
43
+ /**
44
+ * Computes canonical deterministic SHA-256 hash matching Go CLI implementation.
45
+ */
46
+ function computeManifestHash(m) {
47
+ const sortedHosts = [...(m.hosts || [])].sort();
48
+ const sortedTeach = {};
49
+ if (m.teach) {
50
+ const teachKeys = Object.keys(m.teach).sort();
51
+ for (const k of teachKeys) {
52
+ sortedTeach[k] = [...m.teach[k]].sort();
53
+ }
54
+ }
55
+ // Sort crew entries by package name
56
+ const sortedCrew = {};
57
+ if (m.crew) {
58
+ const crewKeys = Object.keys(m.crew).sort();
59
+ for (const k of crewKeys) {
60
+ sortedCrew[k] = m.crew[k];
61
+ }
62
+ }
63
+ const ordered = {};
64
+ if (m.$schema) {
65
+ ordered["$schema"] = m.$schema;
66
+ }
67
+ ordered["hosts"] = sortedHosts;
68
+ ordered["crew"] = sortedCrew;
69
+ if (m.teach && Object.keys(m.teach).length > 0) {
70
+ ordered["teach"] = sortedTeach;
71
+ }
72
+ if (m.memory) {
73
+ ordered["memory"] = m.memory;
74
+ }
75
+ const jsonStr = JSON.stringify(ordered, null, " ") + "\n";
76
+ return node_crypto_1.default.createHash("sha256").update(jsonStr, "utf-8").digest("hex");
77
+ }
78
+ /**
79
+ * Writes crewd.json atomically.
80
+ */
81
+ function writeManifestAtomic(repoRoot, manifest) {
82
+ const targetPath = node_path_1.default.join(repoRoot, "crewd.json");
83
+ const tmpPath = node_path_1.default.join(repoRoot, `.crewd-manifest-${Date.now()}-${Math.random().toString(36).substring(2)}.tmp`);
84
+ // Ensure deterministic formatting
85
+ const sortedHosts = [...(manifest.hosts || [])].sort();
86
+ const sortedCrew = {};
87
+ if (manifest.crew) {
88
+ for (const k of Object.keys(manifest.crew).sort()) {
89
+ sortedCrew[k] = manifest.crew[k];
90
+ }
91
+ }
92
+ const ordered = {
93
+ $schema: manifest.$schema || exports.DEFAULT_MANIFEST_SCHEMA,
94
+ hosts: sortedHosts,
95
+ crew: sortedCrew,
96
+ };
97
+ if (manifest.teach && Object.keys(manifest.teach).length > 0) {
98
+ const sortedTeach = {};
99
+ for (const k of Object.keys(manifest.teach).sort()) {
100
+ sortedTeach[k] = [...manifest.teach[k]].sort();
101
+ }
102
+ ordered["teach"] = sortedTeach;
103
+ }
104
+ if (manifest.memory) {
105
+ ordered["memory"] = manifest.memory;
106
+ }
107
+ const content = JSON.stringify(ordered, null, " ") + "\n";
108
+ node_fs_1.default.writeFileSync(tmpPath, content, "utf-8");
109
+ node_fs_1.default.renameSync(tmpPath, targetPath);
110
+ }
111
+ /**
112
+ * Writes crewd.lock atomically.
113
+ */
114
+ function writeLockfileAtomic(repoRoot, lockfile) {
115
+ const targetPath = node_path_1.default.join(repoRoot, "crewd.lock");
116
+ const tmpPath = node_path_1.default.join(repoRoot, `.crewd-lock-${Date.now()}-${Math.random().toString(36).substring(2)}.tmp`);
117
+ // Format lockfile as clean YAML with 2 spaces
118
+ const doc = new yaml_1.default.Document({
119
+ lockfileVersion: lockfile.lockfileVersion || 1,
120
+ manifestHash: lockfile.manifestHash,
121
+ adapterVersions: lockfile.adapterVersions || {},
122
+ packages: lockfile.packages || {},
123
+ });
124
+ const content = doc.toString({ indent: 2 });
125
+ node_fs_1.default.writeFileSync(tmpPath, content, "utf-8");
126
+ node_fs_1.default.renameSync(tmpPath, targetPath);
127
+ }
128
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/core/manifest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { HostId } from "../types.js";
2
+ /**
3
+ * Finds the project root by searching upwards from startDir for crewd.json or .git.
4
+ * If neither is found, returns startDir (or process.cwd()).
5
+ */
6
+ export declare function findProjectRoot(startDir?: string): string;
7
+ /**
8
+ * Detects which host environments are present in the repo root.
9
+ */
10
+ export declare function detectHosts(repoRoot: string): HostId[];
11
+ //# sourceMappingURL=project.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../src/core/project.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAc,MAAM,aAAa,CAAC;AAEjD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAsBzD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CA6BtD"}
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.findProjectRoot = findProjectRoot;
7
+ exports.detectHosts = detectHosts;
8
+ const node_fs_1 = __importDefault(require("node:fs"));
9
+ const node_path_1 = __importDefault(require("node:path"));
10
+ /**
11
+ * Finds the project root by searching upwards from startDir for crewd.json or .git.
12
+ * If neither is found, returns startDir (or process.cwd()).
13
+ */
14
+ function findProjectRoot(startDir) {
15
+ let curr = node_path_1.default.resolve(startDir || process.cwd());
16
+ while (true) {
17
+ const crewdJson = node_path_1.default.join(curr, "crewd.json");
18
+ if (node_fs_1.default.existsSync(crewdJson)) {
19
+ return curr;
20
+ }
21
+ const gitDir = node_path_1.default.join(curr, ".git");
22
+ if (node_fs_1.default.existsSync(gitDir)) {
23
+ return curr;
24
+ }
25
+ const parent = node_path_1.default.dirname(curr);
26
+ if (parent === curr) {
27
+ break;
28
+ }
29
+ curr = parent;
30
+ }
31
+ return node_path_1.default.resolve(startDir || process.cwd());
32
+ }
33
+ /**
34
+ * Detects which host environments are present in the repo root.
35
+ */
36
+ function detectHosts(repoRoot) {
37
+ const detected = [];
38
+ // Claude Code
39
+ if (node_fs_1.default.existsSync(node_path_1.default.join(repoRoot, ".claude")) ||
40
+ node_fs_1.default.existsSync(node_path_1.default.join(repoRoot, "CLAUDE.md"))) {
41
+ detected.push("claude-code");
42
+ }
43
+ // Cursor
44
+ if (node_fs_1.default.existsSync(node_path_1.default.join(repoRoot, ".cursor"))) {
45
+ detected.push("cursor");
46
+ }
47
+ // Gemini CLI / Antigravity IDE
48
+ if (node_fs_1.default.existsSync(node_path_1.default.join(repoRoot, ".gemini")) ||
49
+ node_fs_1.default.existsSync(node_path_1.default.join(repoRoot, "GEMINI.md"))) {
50
+ detected.push("gemini-cli");
51
+ }
52
+ if (detected.length === 0) {
53
+ return ["claude-code"];
54
+ }
55
+ return detected;
56
+ }
57
+ //# sourceMappingURL=project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/core/project.ts"],"names":[],"mappings":";;;;;AAQA,0CAsBC;AAKD,kCA6BC;AAhED,sDAAyB;AACzB,0DAA6B;AAG7B;;;GAGG;AACH,SAAgB,eAAe,CAAC,QAAiB;IAC/C,IAAI,IAAI,GAAG,mBAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAEnD,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,SAAS,GAAG,mBAAI,CAAC,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;QAChD,IAAI,iBAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,MAAM,GAAG,mBAAI,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACvC,IAAI,iBAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,MAAM,GAAG,mBAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YACpB,MAAM;QACR,CAAC;QACD,IAAI,GAAG,MAAM,CAAC;IAChB,CAAC;IAED,OAAO,mBAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;AACjD,CAAC;AAED;;GAEG;AACH,SAAgB,WAAW,CAAC,QAAgB;IAC1C,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,cAAc;IACd,IACE,iBAAE,CAAC,UAAU,CAAC,mBAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC7C,iBAAE,CAAC,UAAU,CAAC,mBAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,EAC/C,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;IAC/B,CAAC;IAED,SAAS;IACT,IAAI,iBAAE,CAAC,UAAU,CAAC,mBAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC;QAClD,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1B,CAAC;IAED,+BAA+B;IAC/B,IACE,iBAAE,CAAC,UAAU,CAAC,mBAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QAC7C,iBAAE,CAAC,UAAU,CAAC,mBAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC,EAC/C,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC9B,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,aAAa,CAAC,CAAC;IACzB,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,36 @@
1
+ import { PackageSummary, VersionDetail, ResolveResponse } from "../types.js";
2
+ export declare const DEFAULT_REGISTRY_URL = "https://api.crewd.dev";
3
+ export declare function loadRegistryConfig(): {
4
+ registryUrl: string;
5
+ token?: string;
6
+ };
7
+ export declare function parsePackageRef(ref: string): {
8
+ fullName: string;
9
+ namespace: string;
10
+ name: string;
11
+ versionRange: string;
12
+ };
13
+ /**
14
+ * Sanitizes untrusted text from package manifests, readmes, and descriptions.
15
+ * Truncates overly long fields and strips control characters.
16
+ */
17
+ export declare function sanitizeUntrustedText(text: string | undefined | null, maxLen?: number): string;
18
+ export declare class RegistryClient {
19
+ private baseUrl;
20
+ private token?;
21
+ constructor(baseUrl?: string, token?: string);
22
+ private getHeaders;
23
+ searchPackages(query: string, kind?: string, limit?: number): Promise<{
24
+ packages: PackageSummary[];
25
+ total: number;
26
+ }>;
27
+ getPackage(namespace: string, name: string): Promise<PackageSummary>;
28
+ getVersion(namespace: string, name: string, version: string): Promise<VersionDetail>;
29
+ resolve(packages: Array<{
30
+ name: string;
31
+ range: string;
32
+ isTeam?: boolean;
33
+ }>, hosts?: string[]): Promise<ResolveResponse>;
34
+ downloadTarball(tarballUrl: string): Promise<Buffer>;
35
+ }
36
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/core/registry.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,eAAe,EAAmB,MAAM,aAAa,CAAC;AAE9F,eAAO,MAAM,oBAAoB,0BAA0B,CAAC;AAE5D,wBAAgB,kBAAkB,IAAI;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAgC5E;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAkBxH;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,EAAE,MAAM,SAAM,GAAG,MAAM,CAQ3F;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,KAAK,CAAC,CAAS;gBAEX,OAAO,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;IAM5C,OAAO,CAAC,UAAU;IAWZ,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,cAAc,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IA+BpH,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAyBpE,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IA2BpF,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,eAAe,CAAC;IAiCvH,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAmB3D"}