allagents 0.1.5 → 0.2.2
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/LICENSE +21 -21
- package/README.md +281 -281
- package/dist/index.js +403 -207
- package/dist/templates/default/.allagents/workspace.yaml +15 -15
- package/dist/templates/default/AGENTS.md +14 -14
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -1893,12 +1893,12 @@ var require_isexe = __commonJS((exports, module) => {
|
|
|
1893
1893
|
if (typeof Promise !== "function") {
|
|
1894
1894
|
throw new TypeError("callback not provided");
|
|
1895
1895
|
}
|
|
1896
|
-
return new Promise(function(
|
|
1896
|
+
return new Promise(function(resolve, reject) {
|
|
1897
1897
|
isexe(path, options2 || {}, function(er, is) {
|
|
1898
1898
|
if (er) {
|
|
1899
1899
|
reject(er);
|
|
1900
1900
|
} else {
|
|
1901
|
-
|
|
1901
|
+
resolve(is);
|
|
1902
1902
|
}
|
|
1903
1903
|
});
|
|
1904
1904
|
});
|
|
@@ -1960,27 +1960,27 @@ var require_which = __commonJS((exports, module) => {
|
|
|
1960
1960
|
opt = {};
|
|
1961
1961
|
const { pathEnv, pathExt, pathExtExe } = getPathInfo(cmd, opt);
|
|
1962
1962
|
const found = [];
|
|
1963
|
-
const step = (i2) => new Promise((
|
|
1963
|
+
const step = (i2) => new Promise((resolve, reject) => {
|
|
1964
1964
|
if (i2 === pathEnv.length)
|
|
1965
|
-
return opt.all && found.length ?
|
|
1965
|
+
return opt.all && found.length ? resolve(found) : reject(getNotFoundError(cmd));
|
|
1966
1966
|
const ppRaw = pathEnv[i2];
|
|
1967
1967
|
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
1968
1968
|
const pCmd = path.join(pathPart, cmd);
|
|
1969
1969
|
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
1970
|
-
|
|
1970
|
+
resolve(subStep(p, i2, 0));
|
|
1971
1971
|
});
|
|
1972
|
-
const subStep = (p, i2, ii) => new Promise((
|
|
1972
|
+
const subStep = (p, i2, ii) => new Promise((resolve, reject) => {
|
|
1973
1973
|
if (ii === pathExt.length)
|
|
1974
|
-
return
|
|
1974
|
+
return resolve(step(i2 + 1));
|
|
1975
1975
|
const ext = pathExt[ii];
|
|
1976
1976
|
isexe(p + ext, { pathExt: pathExtExe }, (er, is) => {
|
|
1977
1977
|
if (!er && is) {
|
|
1978
1978
|
if (opt.all)
|
|
1979
1979
|
found.push(p + ext);
|
|
1980
1980
|
else
|
|
1981
|
-
return
|
|
1981
|
+
return resolve(p + ext);
|
|
1982
1982
|
}
|
|
1983
|
-
return
|
|
1983
|
+
return resolve(subStep(p, i2, ii + 1));
|
|
1984
1984
|
});
|
|
1985
1985
|
});
|
|
1986
1986
|
return cb ? step(0).then((res) => cb(null, res), cb) : step(0);
|
|
@@ -11053,39 +11053,17 @@ var {
|
|
|
11053
11053
|
Help
|
|
11054
11054
|
} = import__.default;
|
|
11055
11055
|
|
|
11056
|
+
// src/cli/index.ts
|
|
11057
|
+
import { readFileSync as readFileSync2 } from "node:fs";
|
|
11058
|
+
import { dirname as dirname6, join as join11 } from "node:path";
|
|
11059
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
11060
|
+
|
|
11056
11061
|
// src/core/workspace.ts
|
|
11057
|
-
import { mkdir as mkdir5,
|
|
11062
|
+
import { mkdir as mkdir5, readFile as readFile6, writeFile as writeFile4, copyFile as copyFile2 } from "node:fs/promises";
|
|
11058
11063
|
import { existsSync as existsSync7 } from "node:fs";
|
|
11059
|
-
import { join as join8, resolve as resolve5, dirname as dirname5, relative as relative2, sep } from "node:path";
|
|
11064
|
+
import { join as join8, resolve as resolve5, dirname as dirname5, relative as relative2, sep, isAbsolute as isAbsolute2 } from "node:path";
|
|
11060
11065
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
11061
11066
|
|
|
11062
|
-
// src/core/sync.ts
|
|
11063
|
-
import { existsSync as existsSync6 } from "node:fs";
|
|
11064
|
-
import { rm, unlink, rmdir } from "node:fs/promises";
|
|
11065
|
-
import { join as join7, resolve as resolve4, dirname as dirname4, relative } from "node:path";
|
|
11066
|
-
|
|
11067
|
-
// src/constants.ts
|
|
11068
|
-
var CONFIG_DIR = ".allagents";
|
|
11069
|
-
var SYNC_STATE_FILE = "sync-state.json";
|
|
11070
|
-
var WORKSPACE_CONFIG_FILE = "workspace.yaml";
|
|
11071
|
-
var WORKSPACE_CONFIG_PATH = `${CONFIG_DIR}/${WORKSPACE_CONFIG_FILE}`;
|
|
11072
|
-
var WORKSPACE_RULES = `
|
|
11073
|
-
<!-- WORKSPACE-RULES:START -->
|
|
11074
|
-
# Workspace Rules
|
|
11075
|
-
|
|
11076
|
-
## Rule: Workspace Discovery
|
|
11077
|
-
TRIGGER: Any task
|
|
11078
|
-
ACTION: Read \`.allagents/workspace.yaml\` to get repository paths and project domains
|
|
11079
|
-
|
|
11080
|
-
## Rule: Correct Repository Paths
|
|
11081
|
-
TRIGGER: File operations (read, search, modify)
|
|
11082
|
-
ACTION: Use repository paths from \`.allagents/workspace.yaml\`, not assumptions
|
|
11083
|
-
<!-- WORKSPACE-RULES:END -->
|
|
11084
|
-
`;
|
|
11085
|
-
|
|
11086
|
-
// src/utils/workspace-parser.ts
|
|
11087
|
-
import { readFile } from "node:fs/promises";
|
|
11088
|
-
|
|
11089
11067
|
// node_modules/js-yaml/dist/js-yaml.mjs
|
|
11090
11068
|
/*! js-yaml 4.1.1 https://github.com/nodeca/js-yaml @license MIT */
|
|
11091
11069
|
function isNothing(subject) {
|
|
@@ -13733,6 +13711,32 @@ var safeLoad = renamed("safeLoad", "load");
|
|
|
13733
13711
|
var safeLoadAll = renamed("safeLoadAll", "loadAll");
|
|
13734
13712
|
var safeDump = renamed("safeDump", "dump");
|
|
13735
13713
|
|
|
13714
|
+
// src/core/sync.ts
|
|
13715
|
+
import { existsSync as existsSync6 } from "node:fs";
|
|
13716
|
+
import { rm, unlink, rmdir, copyFile } from "node:fs/promises";
|
|
13717
|
+
import { join as join7, resolve as resolve4, dirname as dirname4, relative } from "node:path";
|
|
13718
|
+
|
|
13719
|
+
// src/constants.ts
|
|
13720
|
+
var CONFIG_DIR = ".allagents";
|
|
13721
|
+
var SYNC_STATE_FILE = "sync-state.json";
|
|
13722
|
+
var WORKSPACE_CONFIG_FILE = "workspace.yaml";
|
|
13723
|
+
var WORKSPACE_CONFIG_PATH = `${CONFIG_DIR}/${WORKSPACE_CONFIG_FILE}`;
|
|
13724
|
+
var AGENT_FILES = ["AGENTS.md", "CLAUDE.md"];
|
|
13725
|
+
var WORKSPACE_RULES = `
|
|
13726
|
+
<!-- WORKSPACE-RULES:START -->
|
|
13727
|
+
## Rule: Workspace Discovery
|
|
13728
|
+
TRIGGER: Any task
|
|
13729
|
+
ACTION: Read \`.allagents/workspace.yaml\` to get repository paths and project domains
|
|
13730
|
+
|
|
13731
|
+
## Rule: Correct Repository Paths
|
|
13732
|
+
TRIGGER: File operations (read, search, modify)
|
|
13733
|
+
ACTION: Use repository paths from \`.allagents/workspace.yaml\`, not assumptions
|
|
13734
|
+
<!-- WORKSPACE-RULES:END -->
|
|
13735
|
+
`;
|
|
13736
|
+
|
|
13737
|
+
// src/utils/workspace-parser.ts
|
|
13738
|
+
import { readFile } from "node:fs/promises";
|
|
13739
|
+
|
|
13736
13740
|
// node_modules/zod/v3/external.js
|
|
13737
13741
|
var exports_external = {};
|
|
13738
13742
|
__export(exports_external, {
|
|
@@ -17779,122 +17783,6 @@ ${errors2.join(`
|
|
|
17779
17783
|
|
|
17780
17784
|
// src/utils/plugin-path.ts
|
|
17781
17785
|
import { resolve, isAbsolute } from "node:path";
|
|
17782
|
-
function isGitHubUrl(source) {
|
|
17783
|
-
const explicitPatterns = [
|
|
17784
|
-
/^https?:\/\/github\.com\//,
|
|
17785
|
-
/^https?:\/\/www\.github\.com\//,
|
|
17786
|
-
/^github\.com\//,
|
|
17787
|
-
/^gh:/
|
|
17788
|
-
];
|
|
17789
|
-
if (explicitPatterns.some((pattern) => pattern.test(source))) {
|
|
17790
|
-
return true;
|
|
17791
|
-
}
|
|
17792
|
-
if (!source.startsWith(".") && !source.startsWith("/") && !source.includes("\\") && !/^[a-zA-Z]:/.test(source) && source.includes("/")) {
|
|
17793
|
-
const parts = source.split("/");
|
|
17794
|
-
if (parts.length >= 2 && parts[0] && parts[1]) {
|
|
17795
|
-
const validOwnerRepo = /^[a-zA-Z0-9_-]+$/;
|
|
17796
|
-
if (validOwnerRepo.test(parts[0]) && validOwnerRepo.test(parts[1])) {
|
|
17797
|
-
return true;
|
|
17798
|
-
}
|
|
17799
|
-
}
|
|
17800
|
-
}
|
|
17801
|
-
return false;
|
|
17802
|
-
}
|
|
17803
|
-
function parseGitHubUrl(url) {
|
|
17804
|
-
let normalized = url;
|
|
17805
|
-
if (normalized.startsWith("gh:")) {
|
|
17806
|
-
normalized = normalized.replace(/^gh:/, "https://github.com/");
|
|
17807
|
-
}
|
|
17808
|
-
if (normalized.startsWith("github.com/")) {
|
|
17809
|
-
normalized = `https://${normalized}`;
|
|
17810
|
-
}
|
|
17811
|
-
if (!normalized.includes("://") && !normalized.startsWith("github.com")) {
|
|
17812
|
-
const parts = normalized.split("/");
|
|
17813
|
-
if (parts.length >= 2) {
|
|
17814
|
-
const owner = parts[0];
|
|
17815
|
-
const repo = parts[1];
|
|
17816
|
-
const validOwnerRepo = /^[a-zA-Z0-9_-]+$/;
|
|
17817
|
-
if (owner && repo && validOwnerRepo.test(owner) && validOwnerRepo.test(repo)) {
|
|
17818
|
-
if (parts.length > 2) {
|
|
17819
|
-
const subpath = parts.slice(2).join("/");
|
|
17820
|
-
return { owner, repo, subpath };
|
|
17821
|
-
}
|
|
17822
|
-
return { owner, repo };
|
|
17823
|
-
}
|
|
17824
|
-
}
|
|
17825
|
-
return null;
|
|
17826
|
-
}
|
|
17827
|
-
const subpathPattern = /^https?:\/\/(?:www\.)?github\.com\/([^/]+)\/([^/]+?)\/tree\/[^/]+\/(.+)$/;
|
|
17828
|
-
const subpathMatch = normalized.match(subpathPattern);
|
|
17829
|
-
if (subpathMatch) {
|
|
17830
|
-
const owner = subpathMatch[1];
|
|
17831
|
-
const repo = subpathMatch[2]?.replace(/\.git$/, "");
|
|
17832
|
-
const subpath = subpathMatch[3];
|
|
17833
|
-
if (owner && repo && subpath) {
|
|
17834
|
-
return { owner, repo, subpath };
|
|
17835
|
-
}
|
|
17836
|
-
}
|
|
17837
|
-
const basicPattern = /^https?:\/\/(?:www\.)?github\.com\/([^/]+)\/([^/]+?)(?:\.git)?(?:\/.*)?$/;
|
|
17838
|
-
const basicMatch = normalized.match(basicPattern);
|
|
17839
|
-
if (basicMatch) {
|
|
17840
|
-
const owner = basicMatch[1];
|
|
17841
|
-
const repo = basicMatch[2]?.replace(/\.git$/, "");
|
|
17842
|
-
if (owner && repo) {
|
|
17843
|
-
return { owner, repo };
|
|
17844
|
-
}
|
|
17845
|
-
}
|
|
17846
|
-
return null;
|
|
17847
|
-
}
|
|
17848
|
-
function normalizePluginPath(source, baseDir = process.cwd()) {
|
|
17849
|
-
if (isGitHubUrl(source)) {
|
|
17850
|
-
return source;
|
|
17851
|
-
}
|
|
17852
|
-
if (isAbsolute(source)) {
|
|
17853
|
-
return source;
|
|
17854
|
-
}
|
|
17855
|
-
return resolve(baseDir, source);
|
|
17856
|
-
}
|
|
17857
|
-
function parsePluginSource(source, baseDir = process.cwd()) {
|
|
17858
|
-
if (isGitHubUrl(source)) {
|
|
17859
|
-
const parsed = parseGitHubUrl(source);
|
|
17860
|
-
return {
|
|
17861
|
-
type: "github",
|
|
17862
|
-
original: source,
|
|
17863
|
-
normalized: source,
|
|
17864
|
-
...parsed?.owner && { owner: parsed.owner },
|
|
17865
|
-
...parsed?.repo && { repo: parsed.repo }
|
|
17866
|
-
};
|
|
17867
|
-
}
|
|
17868
|
-
return {
|
|
17869
|
-
type: "local",
|
|
17870
|
-
original: source,
|
|
17871
|
-
normalized: normalizePluginPath(source, baseDir)
|
|
17872
|
-
};
|
|
17873
|
-
}
|
|
17874
|
-
function getPluginCachePath(owner, repo) {
|
|
17875
|
-
const homeDir = process.env.HOME || process.env.USERPROFILE || "~";
|
|
17876
|
-
return resolve(homeDir, ".allagents", "plugins", "marketplaces", `${owner}-${repo}`);
|
|
17877
|
-
}
|
|
17878
|
-
function validatePluginSource(source) {
|
|
17879
|
-
if (!source || source.trim() === "") {
|
|
17880
|
-
return { valid: false, error: "Plugin source cannot be empty" };
|
|
17881
|
-
}
|
|
17882
|
-
if (isGitHubUrl(source)) {
|
|
17883
|
-
const parsed = parseGitHubUrl(source);
|
|
17884
|
-
if (!parsed) {
|
|
17885
|
-
return {
|
|
17886
|
-
valid: false,
|
|
17887
|
-
error: "Invalid GitHub URL format. Expected: https://github.com/owner/repo"
|
|
17888
|
-
};
|
|
17889
|
-
}
|
|
17890
|
-
}
|
|
17891
|
-
return { valid: true };
|
|
17892
|
-
}
|
|
17893
|
-
|
|
17894
|
-
// src/core/plugin.ts
|
|
17895
|
-
import { mkdir, readdir, stat } from "node:fs/promises";
|
|
17896
|
-
import { existsSync } from "node:fs";
|
|
17897
|
-
import { dirname, join, resolve as resolve2 } from "node:path";
|
|
17898
17786
|
|
|
17899
17787
|
// node_modules/execa/index.js
|
|
17900
17788
|
var import_cross_spawn = __toESM(require_cross_spawn(), 1);
|
|
@@ -18769,7 +18657,7 @@ var setupTimeout = (spawned, { timeout, killSignal = "SIGTERM" }, spawnedPromise
|
|
|
18769
18657
|
return spawnedPromise;
|
|
18770
18658
|
}
|
|
18771
18659
|
let timeoutId;
|
|
18772
|
-
const timeoutPromise = new Promise((
|
|
18660
|
+
const timeoutPromise = new Promise((resolve, reject) => {
|
|
18773
18661
|
timeoutId = setTimeout(() => {
|
|
18774
18662
|
timeoutKill(spawned, killSignal, reject);
|
|
18775
18663
|
}, timeout);
|
|
@@ -19133,9 +19021,9 @@ var mergePromise = (spawned, promise) => {
|
|
|
19133
19021
|
Reflect.defineProperty(spawned, property, { ...descriptor, value });
|
|
19134
19022
|
}
|
|
19135
19023
|
};
|
|
19136
|
-
var getSpawnedPromise = (spawned) => new Promise((
|
|
19024
|
+
var getSpawnedPromise = (spawned) => new Promise((resolve, reject) => {
|
|
19137
19025
|
spawned.on("exit", (exitCode, signal) => {
|
|
19138
|
-
|
|
19026
|
+
resolve({ exitCode, signal });
|
|
19139
19027
|
});
|
|
19140
19028
|
spawned.on("error", (error) => {
|
|
19141
19029
|
reject(error);
|
|
@@ -19431,7 +19319,188 @@ function create$(options2) {
|
|
|
19431
19319
|
}
|
|
19432
19320
|
var $ = create$();
|
|
19433
19321
|
|
|
19322
|
+
// src/utils/plugin-path.ts
|
|
19323
|
+
function isGitHubUrl(source) {
|
|
19324
|
+
const explicitPatterns = [
|
|
19325
|
+
/^https?:\/\/github\.com\//,
|
|
19326
|
+
/^https?:\/\/www\.github\.com\//,
|
|
19327
|
+
/^github\.com\//,
|
|
19328
|
+
/^gh:/
|
|
19329
|
+
];
|
|
19330
|
+
if (explicitPatterns.some((pattern) => pattern.test(source))) {
|
|
19331
|
+
return true;
|
|
19332
|
+
}
|
|
19333
|
+
if (!source.startsWith(".") && !source.startsWith("/") && !source.includes("\\") && !/^[a-zA-Z]:/.test(source) && source.includes("/")) {
|
|
19334
|
+
const parts = source.split("/");
|
|
19335
|
+
if (parts.length >= 2 && parts[0] && parts[1]) {
|
|
19336
|
+
const validOwnerRepo = /^[a-zA-Z0-9_.-]+$/;
|
|
19337
|
+
if (validOwnerRepo.test(parts[0]) && validOwnerRepo.test(parts[1])) {
|
|
19338
|
+
return true;
|
|
19339
|
+
}
|
|
19340
|
+
}
|
|
19341
|
+
}
|
|
19342
|
+
return false;
|
|
19343
|
+
}
|
|
19344
|
+
function parseGitHubUrl(url) {
|
|
19345
|
+
let normalized = url;
|
|
19346
|
+
if (normalized.startsWith("gh:")) {
|
|
19347
|
+
normalized = normalized.replace(/^gh:/, "https://github.com/");
|
|
19348
|
+
}
|
|
19349
|
+
if (normalized.startsWith("github.com/")) {
|
|
19350
|
+
normalized = `https://${normalized}`;
|
|
19351
|
+
}
|
|
19352
|
+
if (!normalized.includes("://") && !normalized.startsWith("github.com")) {
|
|
19353
|
+
const parts = normalized.split("/");
|
|
19354
|
+
if (parts.length >= 2) {
|
|
19355
|
+
const owner = parts[0];
|
|
19356
|
+
const repo = parts[1];
|
|
19357
|
+
const validOwnerRepo = /^[a-zA-Z0-9_.-]+$/;
|
|
19358
|
+
if (owner && repo && validOwnerRepo.test(owner) && validOwnerRepo.test(repo)) {
|
|
19359
|
+
if (parts.length > 2) {
|
|
19360
|
+
const subpath = parts.slice(2).join("/");
|
|
19361
|
+
return { owner, repo, subpath };
|
|
19362
|
+
}
|
|
19363
|
+
return { owner, repo };
|
|
19364
|
+
}
|
|
19365
|
+
}
|
|
19366
|
+
return null;
|
|
19367
|
+
}
|
|
19368
|
+
const subpathPattern = /^https?:\/\/(?:www\.)?github\.com\/([^/]+)\/([^/]+?)\/tree\/[^/]+\/(.+)$/;
|
|
19369
|
+
const subpathMatch = normalized.match(subpathPattern);
|
|
19370
|
+
if (subpathMatch) {
|
|
19371
|
+
const owner = subpathMatch[1];
|
|
19372
|
+
const repo = subpathMatch[2]?.replace(/\.git$/, "");
|
|
19373
|
+
const subpath = subpathMatch[3];
|
|
19374
|
+
if (owner && repo && subpath) {
|
|
19375
|
+
return { owner, repo, subpath };
|
|
19376
|
+
}
|
|
19377
|
+
}
|
|
19378
|
+
const basicPattern = /^https?:\/\/(?:www\.)?github\.com\/([^/]+)\/([^/]+?)(?:\.git)?(?:\/.*)?$/;
|
|
19379
|
+
const basicMatch = normalized.match(basicPattern);
|
|
19380
|
+
if (basicMatch) {
|
|
19381
|
+
const owner = basicMatch[1];
|
|
19382
|
+
const repo = basicMatch[2]?.replace(/\.git$/, "");
|
|
19383
|
+
if (owner && repo) {
|
|
19384
|
+
return { owner, repo };
|
|
19385
|
+
}
|
|
19386
|
+
}
|
|
19387
|
+
return null;
|
|
19388
|
+
}
|
|
19389
|
+
function normalizePluginPath(source, baseDir = process.cwd()) {
|
|
19390
|
+
if (isGitHubUrl(source)) {
|
|
19391
|
+
return source;
|
|
19392
|
+
}
|
|
19393
|
+
if (isAbsolute(source)) {
|
|
19394
|
+
return source;
|
|
19395
|
+
}
|
|
19396
|
+
return resolve(baseDir, source);
|
|
19397
|
+
}
|
|
19398
|
+
function parsePluginSource(source, baseDir = process.cwd()) {
|
|
19399
|
+
if (isGitHubUrl(source)) {
|
|
19400
|
+
const parsed = parseGitHubUrl(source);
|
|
19401
|
+
return {
|
|
19402
|
+
type: "github",
|
|
19403
|
+
original: source,
|
|
19404
|
+
normalized: source,
|
|
19405
|
+
...parsed?.owner && { owner: parsed.owner },
|
|
19406
|
+
...parsed?.repo && { repo: parsed.repo }
|
|
19407
|
+
};
|
|
19408
|
+
}
|
|
19409
|
+
return {
|
|
19410
|
+
type: "local",
|
|
19411
|
+
original: source,
|
|
19412
|
+
normalized: normalizePluginPath(source, baseDir)
|
|
19413
|
+
};
|
|
19414
|
+
}
|
|
19415
|
+
function getPluginCachePath(owner, repo) {
|
|
19416
|
+
const homeDir = process.env.HOME || process.env.USERPROFILE || "~";
|
|
19417
|
+
return resolve(homeDir, ".allagents", "plugins", "marketplaces", `${owner}-${repo}`);
|
|
19418
|
+
}
|
|
19419
|
+
function validatePluginSource(source) {
|
|
19420
|
+
if (!source || source.trim() === "") {
|
|
19421
|
+
return { valid: false, error: "Plugin source cannot be empty" };
|
|
19422
|
+
}
|
|
19423
|
+
if (isGitHubUrl(source)) {
|
|
19424
|
+
const parsed = parseGitHubUrl(source);
|
|
19425
|
+
if (!parsed) {
|
|
19426
|
+
return {
|
|
19427
|
+
valid: false,
|
|
19428
|
+
error: "Invalid GitHub URL format. Expected: https://github.com/owner/repo"
|
|
19429
|
+
};
|
|
19430
|
+
}
|
|
19431
|
+
}
|
|
19432
|
+
return { valid: true };
|
|
19433
|
+
}
|
|
19434
|
+
async function verifyGitHubUrlExists(source) {
|
|
19435
|
+
const parsed = parseGitHubUrl(source);
|
|
19436
|
+
if (!parsed) {
|
|
19437
|
+
return {
|
|
19438
|
+
exists: false,
|
|
19439
|
+
error: "Invalid GitHub URL format. Expected: https://github.com/owner/repo"
|
|
19440
|
+
};
|
|
19441
|
+
}
|
|
19442
|
+
const { owner, repo, subpath } = parsed;
|
|
19443
|
+
try {
|
|
19444
|
+
await execa("gh", ["--version"]);
|
|
19445
|
+
} catch {
|
|
19446
|
+
return {
|
|
19447
|
+
exists: false,
|
|
19448
|
+
error: "gh CLI not installed. Install from: https://cli.github.com"
|
|
19449
|
+
};
|
|
19450
|
+
}
|
|
19451
|
+
try {
|
|
19452
|
+
await execa("gh", ["repo", "view", `${owner}/${repo}`, "--json", "name"]);
|
|
19453
|
+
} catch (error) {
|
|
19454
|
+
if (error instanceof Error) {
|
|
19455
|
+
const errorMessage = error.message.toLowerCase();
|
|
19456
|
+
if (errorMessage.includes("not found") || errorMessage.includes("404") || errorMessage.includes("could not resolve to a repository")) {
|
|
19457
|
+
return {
|
|
19458
|
+
exists: false,
|
|
19459
|
+
error: `Repository not found: ${owner}/${repo}`
|
|
19460
|
+
};
|
|
19461
|
+
}
|
|
19462
|
+
if (errorMessage.includes("auth") || errorMessage.includes("authentication")) {
|
|
19463
|
+
return {
|
|
19464
|
+
exists: false,
|
|
19465
|
+
error: "GitHub authentication required. Run: gh auth login"
|
|
19466
|
+
};
|
|
19467
|
+
}
|
|
19468
|
+
}
|
|
19469
|
+
return {
|
|
19470
|
+
exists: false,
|
|
19471
|
+
error: `Failed to verify repository: ${error instanceof Error ? error.message : String(error)}`
|
|
19472
|
+
};
|
|
19473
|
+
}
|
|
19474
|
+
if (subpath) {
|
|
19475
|
+
try {
|
|
19476
|
+
await execa("gh", [
|
|
19477
|
+
"api",
|
|
19478
|
+
`repos/${owner}/${repo}/contents/${subpath}`,
|
|
19479
|
+
"--silent"
|
|
19480
|
+
]);
|
|
19481
|
+
} catch (error) {
|
|
19482
|
+
if (error instanceof Error) {
|
|
19483
|
+
const errorMessage = error.message.toLowerCase();
|
|
19484
|
+
if (errorMessage.includes("not found") || errorMessage.includes("404")) {
|
|
19485
|
+
return {
|
|
19486
|
+
exists: false,
|
|
19487
|
+
error: `Path not found in repository: ${owner}/${repo}/${subpath}`
|
|
19488
|
+
};
|
|
19489
|
+
}
|
|
19490
|
+
}
|
|
19491
|
+
return {
|
|
19492
|
+
exists: false,
|
|
19493
|
+
error: `Failed to verify path: ${error instanceof Error ? error.message : String(error)}`
|
|
19494
|
+
};
|
|
19495
|
+
}
|
|
19496
|
+
}
|
|
19497
|
+
return { exists: true };
|
|
19498
|
+
}
|
|
19499
|
+
|
|
19434
19500
|
// src/core/plugin.ts
|
|
19501
|
+
import { mkdir, readdir, stat } from "node:fs/promises";
|
|
19502
|
+
import { existsSync } from "node:fs";
|
|
19503
|
+
import { dirname, join, resolve as resolve2 } from "node:path";
|
|
19435
19504
|
async function fetchPlugin(url, options2 = {}) {
|
|
19436
19505
|
const { force = false } = options2;
|
|
19437
19506
|
const validation = validatePluginSource(url);
|
|
@@ -19579,7 +19648,6 @@ async function resolveGlobPatterns(sourceRoot, patterns) {
|
|
|
19579
19648
|
var CLIENT_MAPPINGS = {
|
|
19580
19649
|
claude: {
|
|
19581
19650
|
commandsPath: ".claude/commands/",
|
|
19582
|
-
commandsExt: ".md",
|
|
19583
19651
|
skillsPath: ".claude/skills/",
|
|
19584
19652
|
agentsPath: ".claude/agents/",
|
|
19585
19653
|
agentFile: "CLAUDE.md",
|
|
@@ -19587,46 +19655,32 @@ var CLIENT_MAPPINGS = {
|
|
|
19587
19655
|
hooksPath: ".claude/hooks/"
|
|
19588
19656
|
},
|
|
19589
19657
|
copilot: {
|
|
19590
|
-
commandsPath: ".github/prompts/",
|
|
19591
|
-
commandsExt: ".prompt.md",
|
|
19592
19658
|
skillsPath: ".github/skills/",
|
|
19593
19659
|
agentFile: "AGENTS.md"
|
|
19594
19660
|
},
|
|
19595
19661
|
codex: {
|
|
19596
|
-
commandsPath: ".codex/prompts/",
|
|
19597
|
-
commandsExt: ".md",
|
|
19598
19662
|
skillsPath: ".codex/skills/",
|
|
19599
19663
|
agentFile: "AGENTS.md"
|
|
19600
19664
|
},
|
|
19601
19665
|
cursor: {
|
|
19602
|
-
commandsPath: ".cursor/commands/",
|
|
19603
|
-
commandsExt: ".md",
|
|
19604
19666
|
skillsPath: ".cursor/skills/",
|
|
19605
19667
|
agentFile: "AGENTS.md"
|
|
19606
19668
|
},
|
|
19607
19669
|
opencode: {
|
|
19608
|
-
commandsPath: ".opencode/commands/",
|
|
19609
|
-
commandsExt: ".md",
|
|
19610
19670
|
skillsPath: ".opencode/skills/",
|
|
19611
19671
|
agentFile: "AGENTS.md"
|
|
19612
19672
|
},
|
|
19613
19673
|
gemini: {
|
|
19614
|
-
commandsPath: ".gemini/commands/",
|
|
19615
|
-
commandsExt: ".md",
|
|
19616
19674
|
skillsPath: ".gemini/skills/",
|
|
19617
19675
|
agentFile: "GEMINI.md",
|
|
19618
19676
|
agentFileFallback: "AGENTS.md"
|
|
19619
19677
|
},
|
|
19620
19678
|
factory: {
|
|
19621
|
-
commandsPath: ".factory/commands/",
|
|
19622
|
-
commandsExt: ".md",
|
|
19623
19679
|
skillsPath: ".factory/skills/",
|
|
19624
19680
|
agentFile: "AGENTS.md",
|
|
19625
19681
|
hooksPath: ".factory/hooks/"
|
|
19626
19682
|
},
|
|
19627
19683
|
ampcode: {
|
|
19628
|
-
commandsPath: "",
|
|
19629
|
-
commandsExt: ".md",
|
|
19630
19684
|
skillsPath: "",
|
|
19631
19685
|
agentFile: "AGENTS.md"
|
|
19632
19686
|
}
|
|
@@ -19698,20 +19752,28 @@ async function validateSkill(skillDir) {
|
|
|
19698
19752
|
}
|
|
19699
19753
|
|
|
19700
19754
|
// src/core/transform.ts
|
|
19701
|
-
|
|
19702
|
-
|
|
19755
|
+
var AGENT_FILES2 = ["AGENTS.md", "CLAUDE.md"];
|
|
19756
|
+
async function ensureWorkspaceRules(filePath, rules) {
|
|
19757
|
+
const rulesContent = rules ?? WORKSPACE_RULES;
|
|
19703
19758
|
const startMarker = "<!-- WORKSPACE-RULES:START -->";
|
|
19704
19759
|
const endMarker = "<!-- WORKSPACE-RULES:END -->";
|
|
19760
|
+
if (!existsSync3(filePath)) {
|
|
19761
|
+
await writeFile(filePath, `${rulesContent.trim()}
|
|
19762
|
+
`, "utf-8");
|
|
19763
|
+
return;
|
|
19764
|
+
}
|
|
19765
|
+
const content = await readFile3(filePath, "utf-8");
|
|
19705
19766
|
const startIndex = content.indexOf(startMarker);
|
|
19706
19767
|
const endIndex = content.indexOf(endMarker);
|
|
19707
19768
|
if (startIndex !== -1 && endIndex !== -1 && endIndex > startIndex) {
|
|
19708
19769
|
const before = content.substring(0, startIndex);
|
|
19709
19770
|
const after = content.substring(endIndex + endMarker.length);
|
|
19710
|
-
await writeFile(filePath, before +
|
|
19771
|
+
await writeFile(filePath, before + rulesContent.trim() + after, "utf-8");
|
|
19711
19772
|
} else {
|
|
19712
|
-
await writeFile(filePath, content +
|
|
19773
|
+
await writeFile(filePath, content + rulesContent, "utf-8");
|
|
19713
19774
|
}
|
|
19714
19775
|
}
|
|
19776
|
+
var injectWorkspaceRules = ensureWorkspaceRules;
|
|
19715
19777
|
async function copyCommands(pluginPath, workspacePath, client, options2 = {}) {
|
|
19716
19778
|
const { dryRun = false } = options2;
|
|
19717
19779
|
const mapping = CLIENT_MAPPINGS[client];
|
|
@@ -19731,11 +19793,7 @@ async function copyCommands(pluginPath, workspacePath, client, options2 = {}) {
|
|
|
19731
19793
|
const mdFiles = files.filter((f) => f.endsWith(".md"));
|
|
19732
19794
|
const copyPromises = mdFiles.map(async (file) => {
|
|
19733
19795
|
const sourcePath = join4(sourceDir, file);
|
|
19734
|
-
|
|
19735
|
-
if (mapping.commandsExt === ".prompt.md" && !file.endsWith(".prompt.md")) {
|
|
19736
|
-
destFileName = file.replace(/\.md$/, ".prompt.md");
|
|
19737
|
-
}
|
|
19738
|
-
const destPath = join4(destDir, destFileName);
|
|
19796
|
+
const destPath = join4(destDir, file);
|
|
19739
19797
|
if (dryRun) {
|
|
19740
19798
|
return { source: sourcePath, destination: destPath, action: "copied" };
|
|
19741
19799
|
}
|
|
@@ -19916,7 +19974,7 @@ async function copyWorkspaceFiles(sourcePath, workspacePath, files, options2 = {
|
|
|
19916
19974
|
}
|
|
19917
19975
|
if (dryRun) {
|
|
19918
19976
|
results.push({ source: resolved.sourcePath, destination: destPath, action: "copied" });
|
|
19919
|
-
if (
|
|
19977
|
+
if (AGENT_FILES2.includes(resolved.relativePath)) {
|
|
19920
19978
|
copiedAgentFiles.push(resolved.relativePath);
|
|
19921
19979
|
}
|
|
19922
19980
|
continue;
|
|
@@ -19926,7 +19984,7 @@ async function copyWorkspaceFiles(sourcePath, workspacePath, files, options2 = {
|
|
|
19926
19984
|
const content = await readFile3(resolved.sourcePath, "utf-8");
|
|
19927
19985
|
await writeFile(destPath, content, "utf-8");
|
|
19928
19986
|
results.push({ source: resolved.sourcePath, destination: destPath, action: "copied" });
|
|
19929
|
-
if (
|
|
19987
|
+
if (AGENT_FILES2.includes(resolved.relativePath)) {
|
|
19930
19988
|
copiedAgentFiles.push(resolved.relativePath);
|
|
19931
19989
|
}
|
|
19932
19990
|
} catch (error) {
|
|
@@ -19955,7 +20013,7 @@ async function copyWorkspaceFiles(sourcePath, workspacePath, files, options2 = {
|
|
|
19955
20013
|
}
|
|
19956
20014
|
if (dryRun) {
|
|
19957
20015
|
results.push({ source: srcPath, destination: destPath, action: "copied" });
|
|
19958
|
-
if (
|
|
20016
|
+
if (AGENT_FILES2.includes(destFilename)) {
|
|
19959
20017
|
copiedAgentFiles.push(destFilename);
|
|
19960
20018
|
}
|
|
19961
20019
|
continue;
|
|
@@ -19965,7 +20023,7 @@ async function copyWorkspaceFiles(sourcePath, workspacePath, files, options2 = {
|
|
|
19965
20023
|
const content = await readFile3(srcPath, "utf-8");
|
|
19966
20024
|
await writeFile(destPath, content, "utf-8");
|
|
19967
20025
|
results.push({ source: srcPath, destination: destPath, action: "copied" });
|
|
19968
|
-
if (
|
|
20026
|
+
if (AGENT_FILES2.includes(destFilename)) {
|
|
19969
20027
|
copiedAgentFiles.push(destFilename);
|
|
19970
20028
|
}
|
|
19971
20029
|
} catch (error) {
|
|
@@ -19977,19 +20035,19 @@ async function copyWorkspaceFiles(sourcePath, workspacePath, files, options2 = {
|
|
|
19977
20035
|
});
|
|
19978
20036
|
}
|
|
19979
20037
|
}
|
|
19980
|
-
|
|
19981
|
-
|
|
19982
|
-
|
|
19983
|
-
|
|
19984
|
-
|
|
19985
|
-
|
|
19986
|
-
|
|
19987
|
-
|
|
19988
|
-
|
|
19989
|
-
|
|
19990
|
-
|
|
19991
|
-
|
|
19992
|
-
}
|
|
20038
|
+
if (!dryRun) {
|
|
20039
|
+
for (const agentFile of copiedAgentFiles) {
|
|
20040
|
+
const targetPath = join4(workspacePath, agentFile);
|
|
20041
|
+
try {
|
|
20042
|
+
await injectWorkspaceRules(targetPath);
|
|
20043
|
+
} catch (error) {
|
|
20044
|
+
results.push({
|
|
20045
|
+
source: "WORKSPACE-RULES",
|
|
20046
|
+
destination: targetPath,
|
|
20047
|
+
action: "failed",
|
|
20048
|
+
error: error instanceof Error ? error.message : "Failed to inject WORKSPACE-RULES"
|
|
20049
|
+
});
|
|
20050
|
+
}
|
|
19993
20051
|
}
|
|
19994
20052
|
}
|
|
19995
20053
|
return results;
|
|
@@ -20488,7 +20546,7 @@ async function copyValidatedPlugin(validatedPlugin, workspacePath, clients, dryR
|
|
|
20488
20546
|
};
|
|
20489
20547
|
}
|
|
20490
20548
|
async function syncWorkspace(workspacePath = process.cwd(), options2 = {}) {
|
|
20491
|
-
const { force = false, dryRun = false } = options2;
|
|
20549
|
+
const { force = false, dryRun = false, workspaceSourceBase } = options2;
|
|
20492
20550
|
const configDir = join7(workspacePath, CONFIG_DIR);
|
|
20493
20551
|
const configPath = join7(configDir, WORKSPACE_CONFIG_FILE);
|
|
20494
20552
|
if (!existsSync6(configPath)) {
|
|
@@ -20520,7 +20578,8 @@ async function syncWorkspace(workspacePath = process.cwd(), options2 = {}) {
|
|
|
20520
20578
|
const validatedPlugins = await validateAllPlugins(config.plugins, workspacePath, force);
|
|
20521
20579
|
let validatedWorkspaceSource = null;
|
|
20522
20580
|
if (config.workspace?.source) {
|
|
20523
|
-
|
|
20581
|
+
const sourceBasePath = workspaceSourceBase ?? workspacePath;
|
|
20582
|
+
validatedWorkspaceSource = await validatePlugin(config.workspace.source, sourceBasePath, force);
|
|
20524
20583
|
if (!validatedWorkspaceSource.success) {
|
|
20525
20584
|
return {
|
|
20526
20585
|
success: false,
|
|
@@ -20565,7 +20624,23 @@ ${errors2}`
|
|
|
20565
20624
|
const pluginResults = await Promise.all(validatedPlugins.map((validatedPlugin) => copyValidatedPlugin(validatedPlugin, workspacePath, config.clients, dryRun)));
|
|
20566
20625
|
let workspaceFileResults = [];
|
|
20567
20626
|
if (config.workspace && validatedWorkspaceSource) {
|
|
20568
|
-
|
|
20627
|
+
const sourcePath = validatedWorkspaceSource.resolved;
|
|
20628
|
+
const filesToCopy = [...config.workspace.files];
|
|
20629
|
+
for (const agentFile of AGENT_FILES) {
|
|
20630
|
+
const agentPath = join7(sourcePath, agentFile);
|
|
20631
|
+
if (existsSync6(agentPath) && !filesToCopy.includes(agentFile)) {
|
|
20632
|
+
filesToCopy.push(agentFile);
|
|
20633
|
+
}
|
|
20634
|
+
}
|
|
20635
|
+
workspaceFileResults = await copyWorkspaceFiles(sourcePath, workspacePath, filesToCopy, { dryRun });
|
|
20636
|
+
if (!dryRun && config.clients.includes("claude")) {
|
|
20637
|
+
const claudePath = join7(workspacePath, "CLAUDE.md");
|
|
20638
|
+
const agentsPath = join7(workspacePath, "AGENTS.md");
|
|
20639
|
+
const claudeExistsInSource = existsSync6(join7(sourcePath, "CLAUDE.md"));
|
|
20640
|
+
if (!claudeExistsInSource && existsSync6(agentsPath) && !existsSync6(claudePath)) {
|
|
20641
|
+
await copyFile(agentsPath, claudePath);
|
|
20642
|
+
}
|
|
20643
|
+
}
|
|
20569
20644
|
}
|
|
20570
20645
|
let totalCopied = 0;
|
|
20571
20646
|
let totalFailed = 0;
|
|
@@ -20712,6 +20787,7 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
|
|
|
20712
20787
|
await mkdir5(absoluteTarget, { recursive: true });
|
|
20713
20788
|
await mkdir5(configDir, { recursive: true });
|
|
20714
20789
|
let workspaceYamlContent;
|
|
20790
|
+
let sourceDir;
|
|
20715
20791
|
if (options2.from) {
|
|
20716
20792
|
const fromPath = resolve5(options2.from);
|
|
20717
20793
|
if (!existsSync7(fromPath)) {
|
|
@@ -20725,16 +20801,35 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
|
|
|
20725
20801
|
const rootPath = join8(fromPath, WORKSPACE_CONFIG_FILE);
|
|
20726
20802
|
if (existsSync7(nestedPath)) {
|
|
20727
20803
|
sourceYamlPath = nestedPath;
|
|
20804
|
+
sourceDir = fromPath;
|
|
20728
20805
|
} else if (existsSync7(rootPath)) {
|
|
20729
20806
|
sourceYamlPath = rootPath;
|
|
20807
|
+
sourceDir = fromPath;
|
|
20730
20808
|
} else {
|
|
20731
20809
|
throw new Error(`No workspace.yaml found in: ${fromPath}
|
|
20732
20810
|
Expected at: ${nestedPath} or ${rootPath}`);
|
|
20733
20811
|
}
|
|
20734
20812
|
} else {
|
|
20735
20813
|
sourceYamlPath = fromPath;
|
|
20814
|
+
const parentDir = dirname5(fromPath);
|
|
20815
|
+
if (parentDir.endsWith(CONFIG_DIR)) {
|
|
20816
|
+
sourceDir = dirname5(parentDir);
|
|
20817
|
+
} else {
|
|
20818
|
+
sourceDir = parentDir;
|
|
20819
|
+
}
|
|
20736
20820
|
}
|
|
20737
20821
|
workspaceYamlContent = await readFile6(sourceYamlPath, "utf-8");
|
|
20822
|
+
if (sourceDir) {
|
|
20823
|
+
const parsed2 = load(workspaceYamlContent);
|
|
20824
|
+
const workspace = parsed2?.workspace;
|
|
20825
|
+
if (workspace?.source) {
|
|
20826
|
+
const source = workspace.source;
|
|
20827
|
+
if (!isGitHubUrl(source) && !isAbsolute2(source)) {
|
|
20828
|
+
workspace.source = resolve5(sourceDir, source);
|
|
20829
|
+
workspaceYamlContent = dump(parsed2, { lineWidth: -1 });
|
|
20830
|
+
}
|
|
20831
|
+
}
|
|
20832
|
+
}
|
|
20738
20833
|
console.log(`✓ Using workspace.yaml from: ${sourceYamlPath}`);
|
|
20739
20834
|
} else {
|
|
20740
20835
|
const defaultYamlPath = join8(defaultTemplatePath, CONFIG_DIR, WORKSPACE_CONFIG_FILE);
|
|
@@ -20744,15 +20839,37 @@ async function initWorkspace(targetPath = ".", options2 = {}) {
|
|
|
20744
20839
|
workspaceYamlContent = await readFile6(defaultYamlPath, "utf-8");
|
|
20745
20840
|
}
|
|
20746
20841
|
await writeFile4(configPath, workspaceYamlContent, "utf-8");
|
|
20747
|
-
const
|
|
20748
|
-
const
|
|
20749
|
-
|
|
20750
|
-
|
|
20842
|
+
const copiedAgentFiles = [];
|
|
20843
|
+
const effectiveSourceDir = sourceDir ?? defaultTemplatePath;
|
|
20844
|
+
for (const agentFile of AGENT_FILES) {
|
|
20845
|
+
const sourcePath = join8(effectiveSourceDir, agentFile);
|
|
20846
|
+
if (existsSync7(sourcePath)) {
|
|
20847
|
+
const content = await readFile6(sourcePath, "utf-8");
|
|
20848
|
+
await writeFile4(join8(absoluteTarget, agentFile), content, "utf-8");
|
|
20849
|
+
copiedAgentFiles.push(agentFile);
|
|
20850
|
+
}
|
|
20851
|
+
}
|
|
20852
|
+
if (copiedAgentFiles.length === 0) {
|
|
20853
|
+
await ensureWorkspaceRules(join8(absoluteTarget, "AGENTS.md"));
|
|
20854
|
+
copiedAgentFiles.push("AGENTS.md");
|
|
20855
|
+
} else {
|
|
20856
|
+
for (const agentFile of copiedAgentFiles) {
|
|
20857
|
+
await ensureWorkspaceRules(join8(absoluteTarget, agentFile));
|
|
20858
|
+
}
|
|
20859
|
+
}
|
|
20860
|
+
const parsed = load(workspaceYamlContent);
|
|
20861
|
+
const clients = parsed?.clients ?? [];
|
|
20862
|
+
if (clients.includes("claude") && !copiedAgentFiles.includes("CLAUDE.md") && copiedAgentFiles.includes("AGENTS.md")) {
|
|
20863
|
+
const agentsPath = join8(absoluteTarget, "AGENTS.md");
|
|
20864
|
+
const claudePath = join8(absoluteTarget, "CLAUDE.md");
|
|
20865
|
+
await copyFile2(agentsPath, claudePath);
|
|
20751
20866
|
}
|
|
20752
20867
|
console.log(`✓ Workspace created at: ${absoluteTarget}`);
|
|
20753
20868
|
console.log(`
|
|
20754
20869
|
Syncing plugins...`);
|
|
20755
|
-
const syncResult = await syncWorkspace(absoluteTarget
|
|
20870
|
+
const syncResult = await syncWorkspace(absoluteTarget, {
|
|
20871
|
+
...sourceDir && { workspaceSourceBase: sourceDir }
|
|
20872
|
+
});
|
|
20756
20873
|
if (!syncResult.success && syncResult.error) {
|
|
20757
20874
|
if (!syncResult.error.includes("Plugin validation failed")) {
|
|
20758
20875
|
console.log(` Note: ${syncResult.error}`);
|
|
@@ -20883,6 +21000,13 @@ async function addPlugin(plugin, workspacePath = process.cwd()) {
|
|
|
20883
21000
|
error: validation.error || "Invalid GitHub URL"
|
|
20884
21001
|
};
|
|
20885
21002
|
}
|
|
21003
|
+
const verifyResult = await verifyGitHubUrlExists(plugin);
|
|
21004
|
+
if (!verifyResult.exists) {
|
|
21005
|
+
return {
|
|
21006
|
+
success: false,
|
|
21007
|
+
error: verifyResult.error || `GitHub URL not found: ${plugin}`
|
|
21008
|
+
};
|
|
21009
|
+
}
|
|
20886
21010
|
} else {
|
|
20887
21011
|
const fullPath = join10(workspacePath, plugin);
|
|
20888
21012
|
if (!existsSync9(fullPath) && !existsSync9(plugin)) {
|
|
@@ -21332,9 +21456,81 @@ pluginCommand.command("validate <path>").description("Validate plugin structure
|
|
|
21332
21456
|
console.log("(validation not yet implemented)");
|
|
21333
21457
|
});
|
|
21334
21458
|
|
|
21459
|
+
// src/cli/commands/update.ts
|
|
21460
|
+
function detectPackageManagerFromPath(scriptPath) {
|
|
21461
|
+
if (scriptPath.includes(".bun")) {
|
|
21462
|
+
return "bun";
|
|
21463
|
+
}
|
|
21464
|
+
return "npm";
|
|
21465
|
+
}
|
|
21466
|
+
function detectPackageManager() {
|
|
21467
|
+
return detectPackageManagerFromPath(process.argv[1] ?? "");
|
|
21468
|
+
}
|
|
21469
|
+
async function getCurrentVersion() {
|
|
21470
|
+
try {
|
|
21471
|
+
const { createRequire: createRequire2 } = await import("node:module");
|
|
21472
|
+
const require2 = createRequire2(import.meta.url);
|
|
21473
|
+
const pkg = require2("../../../package.json");
|
|
21474
|
+
return pkg.version;
|
|
21475
|
+
} catch {
|
|
21476
|
+
return "unknown";
|
|
21477
|
+
}
|
|
21478
|
+
}
|
|
21479
|
+
var updateCommand = new Command("update").description("Update allagents to the latest version").option("--npm", "Force update using npm").option("--bun", "Force update using bun").action(async (options2) => {
|
|
21480
|
+
try {
|
|
21481
|
+
let packageManager;
|
|
21482
|
+
if (options2.npm && options2.bun) {
|
|
21483
|
+
console.error("Error: Cannot specify both --npm and --bun");
|
|
21484
|
+
process.exit(1);
|
|
21485
|
+
}
|
|
21486
|
+
if (options2.npm) {
|
|
21487
|
+
packageManager = "npm";
|
|
21488
|
+
} else if (options2.bun) {
|
|
21489
|
+
packageManager = "bun";
|
|
21490
|
+
} else {
|
|
21491
|
+
packageManager = detectPackageManager();
|
|
21492
|
+
}
|
|
21493
|
+
const currentVersion = await getCurrentVersion();
|
|
21494
|
+
console.log(`Current version: ${currentVersion}`);
|
|
21495
|
+
console.log(`Updating allagents using ${packageManager}...
|
|
21496
|
+
`);
|
|
21497
|
+
const args = packageManager === "npm" ? ["install", "-g", "allagents@latest"] : ["add", "-g", "allagents@latest"];
|
|
21498
|
+
const result = await execa(packageManager, args, {
|
|
21499
|
+
stdio: "inherit"
|
|
21500
|
+
});
|
|
21501
|
+
if (result.exitCode === 0) {
|
|
21502
|
+
try {
|
|
21503
|
+
const versionResult = await execa("allagents", ["--version"]);
|
|
21504
|
+
const newVersion = versionResult.stdout.trim();
|
|
21505
|
+
console.log(`
|
|
21506
|
+
Update complete: ${currentVersion} → ${newVersion}`);
|
|
21507
|
+
} catch {
|
|
21508
|
+
console.log(`
|
|
21509
|
+
Update complete.`);
|
|
21510
|
+
}
|
|
21511
|
+
}
|
|
21512
|
+
} catch (error) {
|
|
21513
|
+
if (error instanceof Error) {
|
|
21514
|
+
if (error.message.includes("ENOENT") || error.message.includes("not found")) {
|
|
21515
|
+
const detected = detectPackageManager();
|
|
21516
|
+
const alternative = detected === "npm" ? "bun" : "npm";
|
|
21517
|
+
console.error(`Error: ${detected} not found. Try using --${alternative} flag.`);
|
|
21518
|
+
} else {
|
|
21519
|
+
console.error(`Error: ${error.message}`);
|
|
21520
|
+
}
|
|
21521
|
+
process.exit(1);
|
|
21522
|
+
}
|
|
21523
|
+
throw error;
|
|
21524
|
+
}
|
|
21525
|
+
});
|
|
21526
|
+
|
|
21335
21527
|
// src/cli/index.ts
|
|
21528
|
+
var __dirname2 = dirname6(fileURLToPath3(import.meta.url));
|
|
21529
|
+
var packageJsonPath = join11(__dirname2, "..", "package.json");
|
|
21530
|
+
var packageJson = JSON.parse(readFileSync2(packageJsonPath, "utf-8"));
|
|
21336
21531
|
var program2 = new Command;
|
|
21337
|
-
program2.name("allagents").description("CLI tool for managing multi-repo AI agent workspaces with plugin synchronization").version(
|
|
21532
|
+
program2.name("allagents").description("CLI tool for managing multi-repo AI agent workspaces with plugin synchronization").version(packageJson.version);
|
|
21338
21533
|
program2.addCommand(workspaceCommand);
|
|
21339
21534
|
program2.addCommand(pluginCommand);
|
|
21535
|
+
program2.addCommand(updateCommand);
|
|
21340
21536
|
program2.parse();
|