allagents 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -0
- package/dist/index.js +212 -49
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -60,6 +60,9 @@ bunx allagents
|
|
|
60
60
|
allagents workspace init my-workspace
|
|
61
61
|
cd my-workspace
|
|
62
62
|
|
|
63
|
+
# Or initialize from a remote GitHub template
|
|
64
|
+
allagents workspace init my-workspace --from owner/repo/path/to/template
|
|
65
|
+
|
|
63
66
|
# Add a marketplace (or let auto-registration handle it)
|
|
64
67
|
allagents plugin marketplace add anthropics/claude-plugins-official
|
|
65
68
|
|
|
@@ -71,6 +74,23 @@ allagents workspace plugin add my-plugin@someuser/their-repo
|
|
|
71
74
|
allagents workspace sync
|
|
72
75
|
```
|
|
73
76
|
|
|
77
|
+
### Initialize from Remote Template
|
|
78
|
+
|
|
79
|
+
Start a new workspace instantly from any GitHub repository containing a `workspace.yaml`:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
# From GitHub URL
|
|
83
|
+
allagents workspace init ~/my-project --from https://github.com/myorg/templates/tree/main/nodejs
|
|
84
|
+
|
|
85
|
+
# From shorthand
|
|
86
|
+
allagents workspace init ~/my-project --from myorg/templates/nodejs
|
|
87
|
+
|
|
88
|
+
# From repo root (looks for .allagents/workspace.yaml or workspace.yaml)
|
|
89
|
+
allagents workspace init ~/my-project --from myorg/templates
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
This fetches the workspace configuration directly from GitHub - no cloning required.
|
|
93
|
+
|
|
74
94
|
## Commands
|
|
75
95
|
|
|
76
96
|
### Workspace Commands
|
|
@@ -78,6 +98,7 @@ allagents workspace sync
|
|
|
78
98
|
```bash
|
|
79
99
|
# Initialize a new workspace from template
|
|
80
100
|
allagents workspace init <path>
|
|
101
|
+
allagents workspace init <path> --from <source> # From local path or GitHub URL
|
|
81
102
|
|
|
82
103
|
# Sync all plugins to workspace (non-destructive)
|
|
83
104
|
allagents workspace sync [options]
|
package/dist/index.js
CHANGED
|
@@ -11054,9 +11054,9 @@ var {
|
|
|
11054
11054
|
} = import__.default;
|
|
11055
11055
|
|
|
11056
11056
|
// src/cli/index.ts
|
|
11057
|
-
import { readFileSync as
|
|
11058
|
-
import { dirname as
|
|
11059
|
-
import { fileURLToPath as
|
|
11057
|
+
import { readFileSync as readFileSync3 } from "node:fs";
|
|
11058
|
+
import { dirname as dirname7, join as join12 } from "node:path";
|
|
11059
|
+
import { fileURLToPath as fileURLToPath4 } from "node:url";
|
|
11060
11060
|
|
|
11061
11061
|
// src/core/workspace.ts
|
|
11062
11062
|
import { mkdir as mkdir5, readFile as readFile6, writeFile as writeFile4, copyFile as copyFile2 } from "node:fs/promises";
|
|
@@ -19365,14 +19365,25 @@ function parseGitHubUrl(url) {
|
|
|
19365
19365
|
}
|
|
19366
19366
|
return null;
|
|
19367
19367
|
}
|
|
19368
|
-
const subpathPattern = /^https?:\/\/(?:www\.)?github\.com\/([^/]+)\/([^/]+?)\/tree\/[^/]
|
|
19368
|
+
const subpathPattern = /^https?:\/\/(?:www\.)?github\.com\/([^/]+)\/([^/]+?)\/tree\/([^/]+)\/(.+)$/;
|
|
19369
19369
|
const subpathMatch = normalized.match(subpathPattern);
|
|
19370
19370
|
if (subpathMatch) {
|
|
19371
19371
|
const owner = subpathMatch[1];
|
|
19372
19372
|
const repo = subpathMatch[2]?.replace(/\.git$/, "");
|
|
19373
|
-
const
|
|
19374
|
-
|
|
19375
|
-
|
|
19373
|
+
const branch = subpathMatch[3];
|
|
19374
|
+
const subpath = subpathMatch[4];
|
|
19375
|
+
if (owner && repo && branch && subpath) {
|
|
19376
|
+
return { owner, repo, branch, subpath };
|
|
19377
|
+
}
|
|
19378
|
+
}
|
|
19379
|
+
const branchPattern = /^https?:\/\/(?:www\.)?github\.com\/([^/]+)\/([^/]+?)\/tree\/([^/]+)$/;
|
|
19380
|
+
const branchMatch = normalized.match(branchPattern);
|
|
19381
|
+
if (branchMatch) {
|
|
19382
|
+
const owner = branchMatch[1];
|
|
19383
|
+
const repo = branchMatch[2]?.replace(/\.git$/, "");
|
|
19384
|
+
const branch = branchMatch[3];
|
|
19385
|
+
if (owner && repo && branch) {
|
|
19386
|
+
return { owner, repo, branch };
|
|
19376
19387
|
}
|
|
19377
19388
|
}
|
|
19378
19389
|
const basicPattern = /^https?:\/\/(?:www\.)?github\.com\/([^/]+)\/([^/]+?)(?:\.git)?(?:\/.*)?$/;
|
|
@@ -19441,6 +19452,7 @@ function parseFileSource(source, baseDir = process.cwd()) {
|
|
|
19441
19452
|
normalized: source,
|
|
19442
19453
|
owner: parsed.owner,
|
|
19443
19454
|
repo: parsed.repo,
|
|
19455
|
+
...parsed.branch && { branch: parsed.branch },
|
|
19444
19456
|
...parsed.subpath && { filePath: parsed.subpath }
|
|
19445
19457
|
};
|
|
19446
19458
|
}
|
|
@@ -21060,6 +21072,130 @@ async function autoRegisterMarketplace(name) {
|
|
|
21060
21072
|
};
|
|
21061
21073
|
}
|
|
21062
21074
|
|
|
21075
|
+
// src/core/github-fetch.ts
|
|
21076
|
+
async function resolveBranchAndSubpath(owner, repo, pathAfterTree) {
|
|
21077
|
+
const parts = pathAfterTree.split("/");
|
|
21078
|
+
for (let i2 = parts.length - 1;i2 >= 1; i2--) {
|
|
21079
|
+
const branch = parts.slice(0, i2).join("/");
|
|
21080
|
+
const subpath = parts.slice(i2).join("/");
|
|
21081
|
+
try {
|
|
21082
|
+
await execa("gh", [
|
|
21083
|
+
"api",
|
|
21084
|
+
`repos/${owner}/${repo}/commits/${encodeURIComponent(branch)}`,
|
|
21085
|
+
"--silent"
|
|
21086
|
+
]);
|
|
21087
|
+
return { branch, ...subpath && { subpath } };
|
|
21088
|
+
} catch {}
|
|
21089
|
+
}
|
|
21090
|
+
return null;
|
|
21091
|
+
}
|
|
21092
|
+
async function fetchFileFromGitHub(owner, repo, path3, branch) {
|
|
21093
|
+
try {
|
|
21094
|
+
let endpoint = `repos/${owner}/${repo}/contents/${path3}`;
|
|
21095
|
+
if (branch) {
|
|
21096
|
+
endpoint += `?ref=${encodeURIComponent(branch)}`;
|
|
21097
|
+
}
|
|
21098
|
+
const result = await execa("gh", [
|
|
21099
|
+
"api",
|
|
21100
|
+
endpoint,
|
|
21101
|
+
"--jq",
|
|
21102
|
+
".content"
|
|
21103
|
+
]);
|
|
21104
|
+
if (result.stdout) {
|
|
21105
|
+
const content = Buffer.from(result.stdout, "base64").toString("utf-8");
|
|
21106
|
+
return content;
|
|
21107
|
+
}
|
|
21108
|
+
return null;
|
|
21109
|
+
} catch {
|
|
21110
|
+
return null;
|
|
21111
|
+
}
|
|
21112
|
+
}
|
|
21113
|
+
async function fetchWorkspaceFromGitHub(url) {
|
|
21114
|
+
const parsed = parseGitHubUrl(url);
|
|
21115
|
+
if (!parsed) {
|
|
21116
|
+
return {
|
|
21117
|
+
success: false,
|
|
21118
|
+
error: "Invalid GitHub URL format. Expected: https://github.com/owner/repo"
|
|
21119
|
+
};
|
|
21120
|
+
}
|
|
21121
|
+
const { owner, repo, branch, subpath } = parsed;
|
|
21122
|
+
try {
|
|
21123
|
+
await execa("gh", ["--version"]);
|
|
21124
|
+
} catch {
|
|
21125
|
+
return {
|
|
21126
|
+
success: false,
|
|
21127
|
+
error: "gh CLI not installed. Install from: https://cli.github.com"
|
|
21128
|
+
};
|
|
21129
|
+
}
|
|
21130
|
+
try {
|
|
21131
|
+
await execa("gh", ["repo", "view", `${owner}/${repo}`, "--json", "name"]);
|
|
21132
|
+
} catch (error) {
|
|
21133
|
+
if (error instanceof Error) {
|
|
21134
|
+
const errorMessage = error.message.toLowerCase();
|
|
21135
|
+
if (errorMessage.includes("not found") || errorMessage.includes("404") || errorMessage.includes("could not resolve to a repository")) {
|
|
21136
|
+
return {
|
|
21137
|
+
success: false,
|
|
21138
|
+
error: `Repository not found: ${owner}/${repo}`
|
|
21139
|
+
};
|
|
21140
|
+
}
|
|
21141
|
+
if (errorMessage.includes("auth") || errorMessage.includes("authentication")) {
|
|
21142
|
+
return {
|
|
21143
|
+
success: false,
|
|
21144
|
+
error: "GitHub authentication required. Run: gh auth login"
|
|
21145
|
+
};
|
|
21146
|
+
}
|
|
21147
|
+
}
|
|
21148
|
+
return {
|
|
21149
|
+
success: false,
|
|
21150
|
+
error: `Failed to access repository: ${error instanceof Error ? error.message : String(error)}`
|
|
21151
|
+
};
|
|
21152
|
+
}
|
|
21153
|
+
const basePath = subpath || "";
|
|
21154
|
+
const pathsToTry = basePath ? [
|
|
21155
|
+
`${basePath}/${CONFIG_DIR}/${WORKSPACE_CONFIG_FILE}`,
|
|
21156
|
+
`${basePath}/${WORKSPACE_CONFIG_FILE}`
|
|
21157
|
+
] : [
|
|
21158
|
+
`${CONFIG_DIR}/${WORKSPACE_CONFIG_FILE}`,
|
|
21159
|
+
WORKSPACE_CONFIG_FILE
|
|
21160
|
+
];
|
|
21161
|
+
for (const path3 of pathsToTry) {
|
|
21162
|
+
const content = await fetchFileFromGitHub(owner, repo, path3, branch);
|
|
21163
|
+
if (content) {
|
|
21164
|
+
return {
|
|
21165
|
+
success: true,
|
|
21166
|
+
content
|
|
21167
|
+
};
|
|
21168
|
+
}
|
|
21169
|
+
}
|
|
21170
|
+
if (branch && subpath && !branch.includes("/")) {
|
|
21171
|
+
const resolved = await resolveBranchAndSubpath(owner, repo, `${branch}/${subpath}`);
|
|
21172
|
+
if (resolved && resolved.branch !== branch) {
|
|
21173
|
+
const newBasePath = resolved.subpath || "";
|
|
21174
|
+
const newPathsToTry = newBasePath ? [
|
|
21175
|
+
`${newBasePath}/${CONFIG_DIR}/${WORKSPACE_CONFIG_FILE}`,
|
|
21176
|
+
`${newBasePath}/${WORKSPACE_CONFIG_FILE}`
|
|
21177
|
+
] : [
|
|
21178
|
+
`${CONFIG_DIR}/${WORKSPACE_CONFIG_FILE}`,
|
|
21179
|
+
WORKSPACE_CONFIG_FILE
|
|
21180
|
+
];
|
|
21181
|
+
for (const path3 of newPathsToTry) {
|
|
21182
|
+
const content = await fetchFileFromGitHub(owner, repo, path3, resolved.branch);
|
|
21183
|
+
if (content) {
|
|
21184
|
+
return {
|
|
21185
|
+
success: true,
|
|
21186
|
+
content
|
|
21187
|
+
};
|
|
21188
|
+
}
|
|
21189
|
+
}
|
|
21190
|
+
}
|
|
21191
|
+
}
|
|
21192
|
+
return {
|
|
21193
|
+
success: false,
|
|
21194
|
+
error: `No workspace.yaml found in: ${owner}/${repo}${branch ? `@${branch}` : ""}${subpath ? `/${subpath}` : ""}
|
|
21195
|
+
Expected at: ${pathsToTry.join(" or ")}`
|
|
21196
|
+
};
|
|
21197
|
+
}
|
|
21198
|
+
|
|
21063
21199
|
// src/core/workspace.ts
|
|
21064
21200
|
async function initWorkspace(targetPath = ".", options2 = {}) {
|
|
21065
21201
|
const absoluteTarget = resolve5(targetPath);
|
|
@@ -21079,48 +21215,72 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
|
|
|
21079
21215
|
let workspaceYamlContent;
|
|
21080
21216
|
let sourceDir;
|
|
21081
21217
|
if (options2.from) {
|
|
21082
|
-
|
|
21083
|
-
|
|
21084
|
-
|
|
21085
|
-
|
|
21086
|
-
const { stat: stat2 } = await import("node:fs/promises");
|
|
21087
|
-
const fromStat = await stat2(fromPath);
|
|
21088
|
-
let sourceYamlPath;
|
|
21089
|
-
if (fromStat.isDirectory()) {
|
|
21090
|
-
const nestedPath = join8(fromPath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
|
|
21091
|
-
const rootPath = join8(fromPath, WORKSPACE_CONFIG_FILE);
|
|
21092
|
-
if (existsSync7(nestedPath)) {
|
|
21093
|
-
sourceYamlPath = nestedPath;
|
|
21094
|
-
sourceDir = fromPath;
|
|
21095
|
-
} else if (existsSync7(rootPath)) {
|
|
21096
|
-
sourceYamlPath = rootPath;
|
|
21097
|
-
sourceDir = fromPath;
|
|
21098
|
-
} else {
|
|
21099
|
-
throw new Error(`No workspace.yaml found in: ${fromPath}
|
|
21100
|
-
Expected at: ${nestedPath} or ${rootPath}`);
|
|
21101
|
-
}
|
|
21102
|
-
} else {
|
|
21103
|
-
sourceYamlPath = fromPath;
|
|
21104
|
-
const parentDir = dirname5(fromPath);
|
|
21105
|
-
if (parentDir.endsWith(CONFIG_DIR)) {
|
|
21106
|
-
sourceDir = dirname5(parentDir);
|
|
21107
|
-
} else {
|
|
21108
|
-
sourceDir = parentDir;
|
|
21218
|
+
if (isGitHubUrl(options2.from)) {
|
|
21219
|
+
const fetchResult = await fetchWorkspaceFromGitHub(options2.from);
|
|
21220
|
+
if (!fetchResult.success || !fetchResult.content) {
|
|
21221
|
+
throw new Error(fetchResult.error || "Failed to fetch workspace from GitHub");
|
|
21109
21222
|
}
|
|
21110
|
-
|
|
21111
|
-
workspaceYamlContent = await readFile6(sourceYamlPath, "utf-8");
|
|
21112
|
-
if (sourceDir) {
|
|
21223
|
+
workspaceYamlContent = fetchResult.content;
|
|
21113
21224
|
const parsed2 = load(workspaceYamlContent);
|
|
21114
21225
|
const workspace = parsed2?.workspace;
|
|
21115
21226
|
if (workspace?.source) {
|
|
21116
21227
|
const source = workspace.source;
|
|
21117
21228
|
if (!isGitHubUrl(source) && !isAbsolute2(source)) {
|
|
21118
|
-
|
|
21119
|
-
|
|
21229
|
+
const parsedUrl = parseGitHubUrl(options2.from);
|
|
21230
|
+
if (parsedUrl) {
|
|
21231
|
+
const basePath = parsedUrl.subpath || "";
|
|
21232
|
+
const baseDir = basePath.replace(/\/?\.allagents\/workspace\.yaml$/, "").replace(/\/?workspace\.yaml$/, "");
|
|
21233
|
+
const sourcePath = baseDir ? `${baseDir}/${source}` : source;
|
|
21234
|
+
workspace.source = `https://github.com/${parsedUrl.owner}/${parsedUrl.repo}/tree/main/${sourcePath}`;
|
|
21235
|
+
workspaceYamlContent = dump(parsed2, { lineWidth: -1 });
|
|
21236
|
+
}
|
|
21237
|
+
}
|
|
21238
|
+
}
|
|
21239
|
+
console.log(`✓ Using workspace.yaml from: ${options2.from}`);
|
|
21240
|
+
} else {
|
|
21241
|
+
const fromPath = resolve5(options2.from);
|
|
21242
|
+
if (!existsSync7(fromPath)) {
|
|
21243
|
+
throw new Error(`Template not found: ${fromPath}`);
|
|
21244
|
+
}
|
|
21245
|
+
const { stat: stat2 } = await import("node:fs/promises");
|
|
21246
|
+
const fromStat = await stat2(fromPath);
|
|
21247
|
+
let sourceYamlPath;
|
|
21248
|
+
if (fromStat.isDirectory()) {
|
|
21249
|
+
const nestedPath = join8(fromPath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
|
|
21250
|
+
const rootPath = join8(fromPath, WORKSPACE_CONFIG_FILE);
|
|
21251
|
+
if (existsSync7(nestedPath)) {
|
|
21252
|
+
sourceYamlPath = nestedPath;
|
|
21253
|
+
sourceDir = fromPath;
|
|
21254
|
+
} else if (existsSync7(rootPath)) {
|
|
21255
|
+
sourceYamlPath = rootPath;
|
|
21256
|
+
sourceDir = fromPath;
|
|
21257
|
+
} else {
|
|
21258
|
+
throw new Error(`No workspace.yaml found in: ${fromPath}
|
|
21259
|
+
Expected at: ${nestedPath} or ${rootPath}`);
|
|
21260
|
+
}
|
|
21261
|
+
} else {
|
|
21262
|
+
sourceYamlPath = fromPath;
|
|
21263
|
+
const parentDir = dirname5(fromPath);
|
|
21264
|
+
if (parentDir.endsWith(CONFIG_DIR)) {
|
|
21265
|
+
sourceDir = dirname5(parentDir);
|
|
21266
|
+
} else {
|
|
21267
|
+
sourceDir = parentDir;
|
|
21120
21268
|
}
|
|
21121
21269
|
}
|
|
21270
|
+
workspaceYamlContent = await readFile6(sourceYamlPath, "utf-8");
|
|
21271
|
+
if (sourceDir) {
|
|
21272
|
+
const parsed2 = load(workspaceYamlContent);
|
|
21273
|
+
const workspace = parsed2?.workspace;
|
|
21274
|
+
if (workspace?.source) {
|
|
21275
|
+
const source = workspace.source;
|
|
21276
|
+
if (!isGitHubUrl(source) && !isAbsolute2(source)) {
|
|
21277
|
+
workspace.source = resolve5(sourceDir, source);
|
|
21278
|
+
workspaceYamlContent = dump(parsed2, { lineWidth: -1 });
|
|
21279
|
+
}
|
|
21280
|
+
}
|
|
21281
|
+
}
|
|
21282
|
+
console.log(`✓ Using workspace.yaml from: ${sourceYamlPath}`);
|
|
21122
21283
|
}
|
|
21123
|
-
console.log(`✓ Using workspace.yaml from: ${sourceYamlPath}`);
|
|
21124
21284
|
} else {
|
|
21125
21285
|
const defaultYamlPath = join8(defaultTemplatePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
|
|
21126
21286
|
if (!existsSync7(defaultYamlPath)) {
|
|
@@ -21747,6 +21907,9 @@ pluginCommand.command("validate <path>").description("Validate plugin structure
|
|
|
21747
21907
|
});
|
|
21748
21908
|
|
|
21749
21909
|
// src/cli/commands/update.ts
|
|
21910
|
+
import { readFileSync as readFileSync2 } from "node:fs";
|
|
21911
|
+
import { dirname as dirname6, join as join11 } from "node:path";
|
|
21912
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
21750
21913
|
function detectPackageManagerFromPath(scriptPath) {
|
|
21751
21914
|
if (scriptPath.includes(".bun")) {
|
|
21752
21915
|
return "bun";
|
|
@@ -21756,12 +21919,12 @@ function detectPackageManagerFromPath(scriptPath) {
|
|
|
21756
21919
|
function detectPackageManager() {
|
|
21757
21920
|
return detectPackageManagerFromPath(process.argv[1] ?? "");
|
|
21758
21921
|
}
|
|
21759
|
-
|
|
21922
|
+
function getCurrentVersion() {
|
|
21760
21923
|
try {
|
|
21761
|
-
const
|
|
21762
|
-
const
|
|
21763
|
-
const
|
|
21764
|
-
return
|
|
21924
|
+
const __dirname2 = dirname6(fileURLToPath3(import.meta.url));
|
|
21925
|
+
const packageJsonPath = join11(__dirname2, "..", "package.json");
|
|
21926
|
+
const packageJson = JSON.parse(readFileSync2(packageJsonPath, "utf-8"));
|
|
21927
|
+
return packageJson.version;
|
|
21765
21928
|
} catch {
|
|
21766
21929
|
return "unknown";
|
|
21767
21930
|
}
|
|
@@ -21780,7 +21943,7 @@ var updateCommand = new Command("update").description("Update allagents to the l
|
|
|
21780
21943
|
} else {
|
|
21781
21944
|
packageManager = detectPackageManager();
|
|
21782
21945
|
}
|
|
21783
|
-
const currentVersion =
|
|
21946
|
+
const currentVersion = getCurrentVersion();
|
|
21784
21947
|
console.log(`Current version: ${currentVersion}`);
|
|
21785
21948
|
console.log(`Updating allagents using ${packageManager}...
|
|
21786
21949
|
`);
|
|
@@ -21815,9 +21978,9 @@ Update complete.`);
|
|
|
21815
21978
|
});
|
|
21816
21979
|
|
|
21817
21980
|
// src/cli/index.ts
|
|
21818
|
-
var __dirname2 =
|
|
21819
|
-
var packageJsonPath =
|
|
21820
|
-
var packageJson = JSON.parse(
|
|
21981
|
+
var __dirname2 = dirname7(fileURLToPath4(import.meta.url));
|
|
21982
|
+
var packageJsonPath = join12(__dirname2, "..", "package.json");
|
|
21983
|
+
var packageJson = JSON.parse(readFileSync3(packageJsonPath, "utf-8"));
|
|
21821
21984
|
var program2 = new Command;
|
|
21822
21985
|
program2.name("allagents").description("CLI tool for managing multi-repo AI agent workspaces with plugin synchronization").version(packageJson.version);
|
|
21823
21986
|
program2.addCommand(workspaceCommand);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "allagents",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "CLI tool for managing multi-repo AI agent workspaces with plugin synchronization",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"docs:install": "bun install --cwd docs",
|
|
15
15
|
"docs:build": "bun run --cwd docs build",
|
|
16
16
|
"dev": "bun run src/cli/index.ts",
|
|
17
|
-
"test": "bun test tests/unit/validators tests/unit/utils tests/unit/models && bun test tests/unit/core/marketplace.test.ts tests/unit/core/sync.test.ts tests/unit/core/transform-glob.test.ts && bun test tests/unit/core/plugin.test.ts",
|
|
17
|
+
"test": "bun test tests/unit/validators tests/unit/utils tests/unit/models && bun test tests/unit/core/marketplace.test.ts tests/unit/core/sync.test.ts tests/unit/core/transform-glob.test.ts tests/unit/core/github-fetch.test.ts && bun test tests/unit/core/plugin.test.ts",
|
|
18
18
|
"test:watch": "bun test --watch",
|
|
19
19
|
"test:coverage": "bun test --coverage",
|
|
20
20
|
"test:integration": "bats tests/integration/*.bats",
|