@eigenpal/cli 0.5.5 → 0.5.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/CHANGELOG.md +1 -0
- package/dist/cli.js +642 -31
- package/dist/skill/reference/cli/git.md +2 -208
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -467,6 +467,7 @@ actual) { ... }` declaration around your statements. Parameter order is
|
|
|
467
467
|
|
|
468
468
|
- 71361fd: `workflow get-experiment-status --watch` now prints a per-example failure summary on stderr when the batch finishes with any failed/cancelled execution: example name, top-level error (truncated), and the exact `eigenpal execution get <exec-id>` command to drill into step-by-step detail. Removes the need for the agent to grep through a 1000-line JSON dump to find which example broke and why. `reference/debugging.md` documents the discovery path.
|
|
469
469
|
- 71361fd: `eigenpal workflow get-experiment-status --watch` now polls until every execution in the batch reaches a terminal state (`completed` / `failed` / `cancelled`), then exits non-zero if any execution failed or was cancelled. Removes the need for agent-side polling loops that didn't notice all-terminal-already and kept ticking. Renders a one-line `N/M terminal (counts)` progress summary on stderr (in-place rewrite when stderr is a TTY), dumps the full JSON on stdout when done. `--interval <s>` and `--max-wait <s>` are configurable; defaults are 5s/30min.
|
|
470
|
+
- 04e4018: Harden hidden Git materialization commands for package-ref installs, frozen lockfile replay, dependency materialization, and source authoring smoke flows.
|
|
470
471
|
- 71361fd: `install-skill`: multi-tool support via interactive multiselect.
|
|
471
472
|
- Opens a `@clack/prompts` multiselect picker over supported agent tools
|
|
472
473
|
(Claude Code, Cursor). Toggle on to install, toggle off to uninstall —
|
package/dist/cli.js
CHANGED
|
@@ -181601,7 +181601,7 @@ import { fileURLToPath as fileURLToPath6 } from "url";
|
|
|
181601
181601
|
// package.json
|
|
181602
181602
|
var package_default = {
|
|
181603
181603
|
name: "@eigenpal/cli",
|
|
181604
|
-
version: "0.5.
|
|
181604
|
+
version: "0.5.7",
|
|
181605
181605
|
description: "Eigenpal CLI — author and run document workflows from your terminal. Agent-ready.",
|
|
181606
181606
|
keywords: [
|
|
181607
181607
|
"eigenpal",
|
|
@@ -184102,7 +184102,20 @@ init_src();
|
|
|
184102
184102
|
init_zod();
|
|
184103
184103
|
var import_yaml2 = __toESM(require_dist(), 1);
|
|
184104
184104
|
import { spawnSync as spawnSync2 } from "node:child_process";
|
|
184105
|
-
import {
|
|
184105
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
184106
|
+
import {
|
|
184107
|
+
existsSync as existsSync3,
|
|
184108
|
+
mkdirSync as mkdirSync2,
|
|
184109
|
+
mkdtempSync,
|
|
184110
|
+
readdirSync,
|
|
184111
|
+
readFileSync as readFileSync3,
|
|
184112
|
+
realpathSync,
|
|
184113
|
+
rmSync,
|
|
184114
|
+
statSync,
|
|
184115
|
+
writeFileSync as writeFileSync2
|
|
184116
|
+
} from "node:fs";
|
|
184117
|
+
import { mkdtemp } from "node:fs/promises";
|
|
184118
|
+
import { tmpdir } from "node:os";
|
|
184106
184119
|
import path2 from "node:path";
|
|
184107
184120
|
var SourceRepositorySchema = exports_external.object({
|
|
184108
184121
|
gitRepositoryPath: exports_external.string(),
|
|
@@ -184122,12 +184135,28 @@ var ReleasesSchema = exports_external.object({
|
|
|
184122
184135
|
packagePath: exports_external.string(),
|
|
184123
184136
|
releases: exports_external.array(ReleaseSchema)
|
|
184124
184137
|
});
|
|
184138
|
+
var CommitShaSchema = exports_external.string().regex(/^[0-9a-f]{40}$/);
|
|
184139
|
+
var InstallLockPackageSchema = exports_external.lazy(() => exports_external.object({
|
|
184140
|
+
packagePath: SourcePackagePathSchema,
|
|
184141
|
+
requestedRef: SourceVersionRefSchema,
|
|
184142
|
+
resolvedRef: exports_external.string().min(1),
|
|
184143
|
+
resolvedTag: exports_external.string().min(1).optional(),
|
|
184144
|
+
commit: CommitShaSchema,
|
|
184145
|
+
dependencies: exports_external.array(InstallLockPackageSchema)
|
|
184146
|
+
}));
|
|
184147
|
+
var InstallLockfileSchema = exports_external.object({
|
|
184148
|
+
lockfileVersion: exports_external.literal(1),
|
|
184149
|
+
eigenpalVersion: exports_external.string().min(1),
|
|
184150
|
+
inputHash: exports_external.string().min(1),
|
|
184151
|
+
root: InstallLockPackageSchema
|
|
184152
|
+
});
|
|
184125
184153
|
var AuthCheckSchema = exports_external.object({
|
|
184126
184154
|
ok: exports_external.literal(true),
|
|
184127
184155
|
email: exports_external.string().email().nullable().optional(),
|
|
184128
184156
|
name: exports_external.string().nullable().optional(),
|
|
184129
184157
|
keyId: exports_external.string()
|
|
184130
184158
|
});
|
|
184159
|
+
var INSTALL_LOCKFILE_NAME = "eigenpal.lock";
|
|
184131
184160
|
function runGit(args, opts = {}) {
|
|
184132
184161
|
const env2 = opts.config ? gitAuthEnv(opts.config, opts.env, opts.gitRemoteUrl) : { ...getProcessEnv(), ...opts.env };
|
|
184133
184162
|
const result = spawnSync2("git", args, {
|
|
@@ -184187,6 +184216,11 @@ function sourcePathFromPackageRoot(gitRoot, packageRoot) {
|
|
|
184187
184216
|
function resolveGitRoot(dir) {
|
|
184188
184217
|
return gitOutput(["rev-parse", "--show-toplevel"], dir);
|
|
184189
184218
|
}
|
|
184219
|
+
function isOrganizationSourceGitRoot(gitRoot) {
|
|
184220
|
+
if (!gitRoot)
|
|
184221
|
+
return false;
|
|
184222
|
+
return Boolean(gitOutput(["remote", "get-url", "origin"], gitRoot)?.match(/\/orgs\/[^/]+\.git$/));
|
|
184223
|
+
}
|
|
184190
184224
|
function findNearestPackageRoot(startDir, gitRoot) {
|
|
184191
184225
|
let current = path2.resolve(startDir);
|
|
184192
184226
|
while (true) {
|
|
@@ -184238,6 +184272,250 @@ function releaseTagExists(gitRoot, packagePath, version2) {
|
|
|
184238
184272
|
const tag = formatReleaseTag(pathToDottedPackageName(packagePath), version2);
|
|
184239
184273
|
return gitOutput(["tag", "--list", tag], gitRoot) === tag;
|
|
184240
184274
|
}
|
|
184275
|
+
function readPackageManifest(packageRoot) {
|
|
184276
|
+
return SourcePackageManifestSchema.parse(readYamlFile(path2.join(packageRoot, "eigenpal.yaml")));
|
|
184277
|
+
}
|
|
184278
|
+
function parsePackageRef(input) {
|
|
184279
|
+
const [rawPackage, rawRef, extra] = input.split("@");
|
|
184280
|
+
if (!rawPackage || extra !== undefined) {
|
|
184281
|
+
throw new Error("Package ref must be <package>[@latest|main|version|range|commit].");
|
|
184282
|
+
}
|
|
184283
|
+
const packagePath = resolvePackagePath(rawPackage);
|
|
184284
|
+
const ref = SourceVersionRefSchema.parse(rawRef || "latest");
|
|
184285
|
+
return { packagePath, ref };
|
|
184286
|
+
}
|
|
184287
|
+
function versionMatchesRange(version2, range) {
|
|
184288
|
+
const parts = semverParts(version2);
|
|
184289
|
+
if (!parts)
|
|
184290
|
+
return false;
|
|
184291
|
+
const rangeParts = range.replace("*", "x").split(".");
|
|
184292
|
+
if (String(parts[0]) !== rangeParts[0])
|
|
184293
|
+
return false;
|
|
184294
|
+
if (rangeParts.length === 2)
|
|
184295
|
+
return rangeParts[1] === "x";
|
|
184296
|
+
if (rangeParts.length !== 3)
|
|
184297
|
+
return false;
|
|
184298
|
+
if (rangeParts[1] === "x")
|
|
184299
|
+
return true;
|
|
184300
|
+
return String(parts[1]) === rangeParts[1];
|
|
184301
|
+
}
|
|
184302
|
+
function listLocalPackageReleases(gitRoot, packagePath) {
|
|
184303
|
+
const tagPrefix = `${pathToDottedPackageName(packagePath)}@`;
|
|
184304
|
+
const output = gitOutput(["tag", "--list", `${tagPrefix}*`], gitRoot) ?? "";
|
|
184305
|
+
return output.split(`
|
|
184306
|
+
`).map((tag) => tag.trim()).filter(Boolean).map((tag) => {
|
|
184307
|
+
const parsed = parseReleaseTag(tag);
|
|
184308
|
+
const commit = gitOutput(["rev-list", "-n", "1", tag], gitRoot) ?? "";
|
|
184309
|
+
return { tag, version: parsed.version, commit };
|
|
184310
|
+
}).sort((left, right) => compareSemverDesc(left.version, right.version));
|
|
184311
|
+
}
|
|
184312
|
+
async function listPackageReleases(input) {
|
|
184313
|
+
if (input.gitRoot) {
|
|
184314
|
+
const local = listLocalPackageReleases(input.gitRoot, input.packagePath);
|
|
184315
|
+
if (local.length > 0)
|
|
184316
|
+
return local;
|
|
184317
|
+
}
|
|
184318
|
+
const client = new ApiClient(input.config);
|
|
184319
|
+
return ReleasesSchema.parse(await client.get("/api/v1/source/releases", { packagePath: input.packagePath })).releases;
|
|
184320
|
+
}
|
|
184321
|
+
function hostedArchiveRequest(input) {
|
|
184322
|
+
const match = input.repository.remoteUrl.match(/^(.*)\/orgs\/([^/]+)\.git$/);
|
|
184323
|
+
if (!match)
|
|
184324
|
+
return null;
|
|
184325
|
+
const [, baseUrl, gitRepositoryPath] = match;
|
|
184326
|
+
return `${baseUrl}/export/orgs/${encodeURIComponent(gitRepositoryPath)}/${encodeURIComponent(input.ref)}/${input.packagePath}`;
|
|
184327
|
+
}
|
|
184328
|
+
async function resolvePackageRef(input) {
|
|
184329
|
+
if (input.ref === "main" || /^[0-9a-f]{40}$/.test(input.ref)) {
|
|
184330
|
+
if (!input.gitRoot) {
|
|
184331
|
+
throw new Error(`Source ref ${input.ref} requires a cloned organization source repository.`);
|
|
184332
|
+
}
|
|
184333
|
+
const commit = gitOutput(["rev-parse", input.ref], input.gitRoot);
|
|
184334
|
+
if (!commit)
|
|
184335
|
+
throw new Error(`Source ref ${input.ref} does not exist.`);
|
|
184336
|
+
return { requestedRef: input.ref, resolvedRef: input.ref, commit };
|
|
184337
|
+
}
|
|
184338
|
+
const releases = await listPackageReleases({
|
|
184339
|
+
config: input.config,
|
|
184340
|
+
gitRoot: input.gitRoot,
|
|
184341
|
+
packagePath: input.packagePath
|
|
184342
|
+
});
|
|
184343
|
+
const release = input.ref === "latest" ? sortReleasesNewestFirst(releases)[0] : /^\d+\.\d+\.\d+$/.test(input.ref) ? releases.find((candidate) => candidate.version === input.ref) : sortReleasesNewestFirst(releases).find((candidate) => versionMatchesRange(candidate.version, input.ref));
|
|
184344
|
+
if (!release) {
|
|
184345
|
+
throw new Error(`No release found for ${input.packagePath}@${input.ref}.`);
|
|
184346
|
+
}
|
|
184347
|
+
return {
|
|
184348
|
+
requestedRef: input.ref,
|
|
184349
|
+
resolvedRef: release.version,
|
|
184350
|
+
resolvedTag: release.tag,
|
|
184351
|
+
commit: release.commit || (input.gitRoot ? gitOutput(["rev-list", "-n", "1", release.tag], input.gitRoot) ?? "" : "")
|
|
184352
|
+
};
|
|
184353
|
+
}
|
|
184354
|
+
function archivePackage(input) {
|
|
184355
|
+
rmSync(input.outDir, { recursive: true, force: true });
|
|
184356
|
+
mkdirSync2(input.outDir, { recursive: true });
|
|
184357
|
+
const tarPath = path2.join(mkdtempSyncCompat("eigenpal-source-archive-"), "package.tar");
|
|
184358
|
+
try {
|
|
184359
|
+
runGit(["archive", "--format=tar", `--output=${tarPath}`, input.ref, input.packagePath], {
|
|
184360
|
+
cwd: input.gitRoot
|
|
184361
|
+
});
|
|
184362
|
+
const extract2 = spawnSync2("tar", ["-xf", tarPath, "--strip-components", String(input.packagePath.split("/").length)], {
|
|
184363
|
+
cwd: input.outDir,
|
|
184364
|
+
encoding: "utf8"
|
|
184365
|
+
});
|
|
184366
|
+
if (extract2.status !== 0)
|
|
184367
|
+
throw new Error(extract2.stderr.trim() || "tar extraction failed");
|
|
184368
|
+
} finally {
|
|
184369
|
+
rmSync(path2.dirname(tarPath), { recursive: true, force: true });
|
|
184370
|
+
}
|
|
184371
|
+
}
|
|
184372
|
+
async function tryHostedArchive(input) {
|
|
184373
|
+
const repository = input.repository ?? (input.gitRoot ? {
|
|
184374
|
+
gitRepositoryPath: "",
|
|
184375
|
+
remoteUrl: gitOutput(["remote", "get-url", "origin"], input.gitRoot) ?? ""
|
|
184376
|
+
} : null);
|
|
184377
|
+
if (!repository)
|
|
184378
|
+
return false;
|
|
184379
|
+
const url2 = hostedArchiveRequest({
|
|
184380
|
+
repository,
|
|
184381
|
+
ref: input.ref,
|
|
184382
|
+
packagePath: input.packagePath
|
|
184383
|
+
});
|
|
184384
|
+
if (!url2)
|
|
184385
|
+
return false;
|
|
184386
|
+
const response = await fetch(url2, {
|
|
184387
|
+
headers: { authorization: `Bearer ${requireApiKey(input.config)}` }
|
|
184388
|
+
}).catch(() => null);
|
|
184389
|
+
if (!response?.ok)
|
|
184390
|
+
return false;
|
|
184391
|
+
rmSync(input.outDir, { recursive: true, force: true });
|
|
184392
|
+
mkdirSync2(input.outDir, { recursive: true });
|
|
184393
|
+
const tarPath = path2.join(mkdtempSyncCompat("eigenpal-hosted-source-"), "package.tar");
|
|
184394
|
+
try {
|
|
184395
|
+
writeFileSync2(tarPath, Buffer.from(await response.arrayBuffer()));
|
|
184396
|
+
const extract2 = spawnSync2("tar", ["-xf", tarPath, "--strip-components", String(input.packagePath.split("/").length)], {
|
|
184397
|
+
cwd: input.outDir,
|
|
184398
|
+
encoding: "utf8"
|
|
184399
|
+
});
|
|
184400
|
+
if (extract2.status !== 0)
|
|
184401
|
+
throw new Error(extract2.stderr.trim() || "tar extraction failed");
|
|
184402
|
+
return true;
|
|
184403
|
+
} finally {
|
|
184404
|
+
rmSync(path2.dirname(tarPath), { recursive: true, force: true });
|
|
184405
|
+
}
|
|
184406
|
+
}
|
|
184407
|
+
function mkdtempSyncCompat(prefix) {
|
|
184408
|
+
return mkdtempSync(path2.join(tmpdir(), prefix));
|
|
184409
|
+
}
|
|
184410
|
+
function dependencyInstallPath(parentRoot, packagePath) {
|
|
184411
|
+
const modulesRoot = path2.resolve(parentRoot, "eigenpal_modules");
|
|
184412
|
+
const destination = path2.resolve(modulesRoot, packagePath);
|
|
184413
|
+
if (destination !== modulesRoot && !destination.startsWith(`${modulesRoot}${path2.sep}`)) {
|
|
184414
|
+
throw new Error(`Dependency path escapes eigenpal_modules: ${packagePath}`);
|
|
184415
|
+
}
|
|
184416
|
+
return destination;
|
|
184417
|
+
}
|
|
184418
|
+
function lockfileInputHash(input) {
|
|
184419
|
+
return createHash2("sha256").update(JSON.stringify(input)).digest("hex");
|
|
184420
|
+
}
|
|
184421
|
+
async function resolvePackageGraph(input) {
|
|
184422
|
+
const seen = input.seen ?? [];
|
|
184423
|
+
const key = `${input.packagePath}@${input.ref}`;
|
|
184424
|
+
if (seen.includes(key)) {
|
|
184425
|
+
throw new Error(`Dependency cycle detected: ${[...seen, key].join(" -> ")}`);
|
|
184426
|
+
}
|
|
184427
|
+
const resolved = await resolvePackageRef(input);
|
|
184428
|
+
const tempDir = await mkdtemp(path2.join(tmpdir(), "eigenpal-install-resolve-"));
|
|
184429
|
+
try {
|
|
184430
|
+
const packageRoot = path2.join(tempDir, "package");
|
|
184431
|
+
const ref = resolved.resolvedTag ?? resolved.resolvedRef;
|
|
184432
|
+
if (input.gitRoot) {
|
|
184433
|
+
archivePackage({
|
|
184434
|
+
gitRoot: input.gitRoot,
|
|
184435
|
+
ref,
|
|
184436
|
+
packagePath: input.packagePath,
|
|
184437
|
+
outDir: packageRoot
|
|
184438
|
+
});
|
|
184439
|
+
} else if (!await tryHostedArchive({
|
|
184440
|
+
config: input.config,
|
|
184441
|
+
repository: input.repository,
|
|
184442
|
+
ref,
|
|
184443
|
+
packagePath: input.packagePath,
|
|
184444
|
+
outDir: packageRoot
|
|
184445
|
+
})) {
|
|
184446
|
+
throw new Error(`Hosted source export unavailable for ${input.packagePath}@${ref}.`);
|
|
184447
|
+
}
|
|
184448
|
+
const manifest = readPackageManifest(packageRoot);
|
|
184449
|
+
const dependencies = "dependencies" in manifest ? Object.entries(manifest.dependencies ?? {}) : [];
|
|
184450
|
+
return {
|
|
184451
|
+
packagePath: input.packagePath,
|
|
184452
|
+
requestedRef: input.ref,
|
|
184453
|
+
resolvedRef: resolved.resolvedRef,
|
|
184454
|
+
...resolved.resolvedTag ? { resolvedTag: resolved.resolvedTag } : {},
|
|
184455
|
+
commit: resolved.commit,
|
|
184456
|
+
dependencies: await Promise.all(dependencies.map(([dependencyName, version2]) => resolvePackageGraph({
|
|
184457
|
+
config: input.config,
|
|
184458
|
+
gitRoot: input.gitRoot,
|
|
184459
|
+
repository: input.repository,
|
|
184460
|
+
packagePath: workspaceDependencyNameToPackagePath(dependencyName),
|
|
184461
|
+
ref: SourceVersionRefSchema.parse(version2),
|
|
184462
|
+
seen: [...seen, key]
|
|
184463
|
+
})))
|
|
184464
|
+
};
|
|
184465
|
+
} finally {
|
|
184466
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
184467
|
+
}
|
|
184468
|
+
}
|
|
184469
|
+
async function materializeLockPackage(input) {
|
|
184470
|
+
const ref = input.lockPackage.resolvedTag ?? input.lockPackage.commit;
|
|
184471
|
+
const usedHostedArchive = await tryHostedArchive({
|
|
184472
|
+
config: input.config,
|
|
184473
|
+
gitRoot: input.gitRoot,
|
|
184474
|
+
repository: input.repository,
|
|
184475
|
+
ref,
|
|
184476
|
+
packagePath: input.lockPackage.packagePath,
|
|
184477
|
+
outDir: input.outDir
|
|
184478
|
+
});
|
|
184479
|
+
if (!usedHostedArchive) {
|
|
184480
|
+
if (!input.gitRoot) {
|
|
184481
|
+
throw new Error(`Hosted source export unavailable for ${input.lockPackage.packagePath}@${ref}.`);
|
|
184482
|
+
}
|
|
184483
|
+
warn(`Hosted source export unavailable for ${input.lockPackage.packagePath}; using local git archive.`);
|
|
184484
|
+
archivePackage({
|
|
184485
|
+
gitRoot: input.gitRoot,
|
|
184486
|
+
ref,
|
|
184487
|
+
packagePath: input.lockPackage.packagePath,
|
|
184488
|
+
outDir: input.outDir
|
|
184489
|
+
});
|
|
184490
|
+
}
|
|
184491
|
+
const occupied = new Set;
|
|
184492
|
+
for (const dependency of input.lockPackage.dependencies) {
|
|
184493
|
+
const dependencyPath = dependencyInstallPath(input.outDir, dependency.packagePath);
|
|
184494
|
+
if (occupied.has(dependencyPath)) {
|
|
184495
|
+
throw new Error(`Dependency conflict at ${dependencyPath}`);
|
|
184496
|
+
}
|
|
184497
|
+
occupied.add(dependencyPath);
|
|
184498
|
+
await materializeLockPackage({
|
|
184499
|
+
config: input.config,
|
|
184500
|
+
gitRoot: input.gitRoot,
|
|
184501
|
+
repository: input.repository,
|
|
184502
|
+
lockPackage: dependency,
|
|
184503
|
+
outDir: dependencyPath
|
|
184504
|
+
});
|
|
184505
|
+
}
|
|
184506
|
+
}
|
|
184507
|
+
function writeLockfile(lockfilePath, lockfile) {
|
|
184508
|
+
mkdirSync2(path2.dirname(lockfilePath), { recursive: true });
|
|
184509
|
+
writeFileSync2(lockfilePath, `${JSON.stringify(lockfile, null, 2)}
|
|
184510
|
+
`);
|
|
184511
|
+
}
|
|
184512
|
+
function readLockfile(lockfilePath) {
|
|
184513
|
+
const parsed = InstallLockfileSchema.safeParse(JSON.parse(readFileSync3(lockfilePath, "utf8")));
|
|
184514
|
+
if (!parsed.success) {
|
|
184515
|
+
throw new Error(`Invalid lockfile ${lockfilePath}: ${parsed.error.issues.map((issue2) => `${issue2.path.join(".")}: ${issue2.message}`).join("; ")}`);
|
|
184516
|
+
}
|
|
184517
|
+
return parsed.data;
|
|
184518
|
+
}
|
|
184241
184519
|
function validatePackageReferences(input) {
|
|
184242
184520
|
const errors3 = [];
|
|
184243
184521
|
const dependencies = "dependencies" in input.manifest ? Object.entries(input.manifest.dependencies ?? {}) : [];
|
|
@@ -184440,7 +184718,12 @@ function gitCommandCreatesObjects(args) {
|
|
|
184440
184718
|
"revert",
|
|
184441
184719
|
"tag"
|
|
184442
184720
|
]);
|
|
184443
|
-
|
|
184721
|
+
const command = gitSubcommandFromArgs(args);
|
|
184722
|
+
if (!command)
|
|
184723
|
+
return false;
|
|
184724
|
+
if (command === "tag" && args.some((arg) => arg === "-l" || arg === "--list"))
|
|
184725
|
+
return false;
|
|
184726
|
+
return objectCreatingCommands.has(command);
|
|
184444
184727
|
}
|
|
184445
184728
|
function gitCwdFromArgs(args) {
|
|
184446
184729
|
let cwd = process.cwd();
|
|
@@ -184452,6 +184735,25 @@ function gitCwdFromArgs(args) {
|
|
|
184452
184735
|
}
|
|
184453
184736
|
return cwd;
|
|
184454
184737
|
}
|
|
184738
|
+
function gitSubcommandFromArgs(args) {
|
|
184739
|
+
const optionsWithValue = new Set(["-C", "-c", "--git-dir", "--work-tree", "--namespace"]);
|
|
184740
|
+
for (let i = 0;i < args.length; i += 1) {
|
|
184741
|
+
const arg = args[i];
|
|
184742
|
+
if (arg === "--")
|
|
184743
|
+
continue;
|
|
184744
|
+
if (optionsWithValue.has(arg)) {
|
|
184745
|
+
i += 1;
|
|
184746
|
+
continue;
|
|
184747
|
+
}
|
|
184748
|
+
if (arg.startsWith("--git-dir=") || arg.startsWith("--work-tree=") || arg.startsWith("--namespace=")) {
|
|
184749
|
+
continue;
|
|
184750
|
+
}
|
|
184751
|
+
if (arg.startsWith("-"))
|
|
184752
|
+
continue;
|
|
184753
|
+
return arg;
|
|
184754
|
+
}
|
|
184755
|
+
return null;
|
|
184756
|
+
}
|
|
184455
184757
|
async function runGitPassthroughFromArgv(argv) {
|
|
184456
184758
|
const gitIndex = argv.indexOf("git");
|
|
184457
184759
|
const separatorIndex = argv.indexOf("--", gitIndex + 1);
|
|
@@ -184534,7 +184836,7 @@ function doctor(opts) {
|
|
|
184534
184836
|
});
|
|
184535
184837
|
}
|
|
184536
184838
|
}
|
|
184537
|
-
if (context.packageRoot) {
|
|
184839
|
+
if (context.packageRoot && context.packageRoot !== context.gitRoot) {
|
|
184538
184840
|
const result = validatePackage(context.packageRoot);
|
|
184539
184841
|
checks3.push({
|
|
184540
184842
|
check: "package structure",
|
|
@@ -184763,15 +185065,312 @@ async function release(versionOrBump, dir, opts) {
|
|
|
184763
185065
|
}
|
|
184764
185066
|
async function sync(target, opts) {
|
|
184765
185067
|
const context = resolveGitSourceContext({ dir: opts.dir });
|
|
185068
|
+
if (target?.includes("@")) {
|
|
185069
|
+
throw new Error("Sync always uses latest; do not pass a versioned target.");
|
|
185070
|
+
}
|
|
184766
185071
|
const packagePath = target ? resolvePackagePath(target) : context.packagePath;
|
|
184767
185072
|
if (!packagePath) {
|
|
184768
185073
|
throw new Error("Pass an automation target or run sync inside a source package.");
|
|
184769
185074
|
}
|
|
184770
|
-
if (target?.includes("@")) {
|
|
184771
|
-
throw new Error("Sync always uses latest; do not pass a versioned target.");
|
|
184772
|
-
}
|
|
184773
185075
|
await syncLatestAutomation(new ApiClient(resolveConfig(opts)), packagePath);
|
|
184774
185076
|
}
|
|
185077
|
+
async function install(packageRef, opts) {
|
|
185078
|
+
const config2 = resolveConfig(opts);
|
|
185079
|
+
const context = resolveGitSourceContext();
|
|
185080
|
+
const sourceGitRoot = isOrganizationSourceGitRoot(context.gitRoot) ? context.gitRoot : null;
|
|
185081
|
+
if (sourceGitRoot)
|
|
185082
|
+
checkRepoVersion(sourceGitRoot, false);
|
|
185083
|
+
const installFromLock = async (lockfilePath, packageDestination, explicitRef, repository, expectedPackagePath, explicitGitRoot) => {
|
|
185084
|
+
const lockfile2 = readLockfile(lockfilePath);
|
|
185085
|
+
if (expectedPackagePath && lockfile2.root.packagePath !== expectedPackagePath) {
|
|
185086
|
+
throw new Error(`Lockfile root package ${lockfile2.root.packagePath} does not match requested package ${expectedPackagePath}.`);
|
|
185087
|
+
}
|
|
185088
|
+
const destination = explicitRef ? path2.resolve(opts.out ?? path2.basename(lockfile2.root.packagePath)) : packageDestination;
|
|
185089
|
+
if (!destination)
|
|
185090
|
+
throw new Error("No package context found for lockfile install.");
|
|
185091
|
+
const lockInstallGitRoot = explicitRef ? explicitGitRoot ?? sourceGitRoot : context.gitRoot;
|
|
185092
|
+
if (explicitRef) {
|
|
185093
|
+
await materializeLockPackage({
|
|
185094
|
+
config: config2,
|
|
185095
|
+
gitRoot: lockInstallGitRoot,
|
|
185096
|
+
repository,
|
|
185097
|
+
lockPackage: lockfile2.root,
|
|
185098
|
+
outDir: destination
|
|
185099
|
+
});
|
|
185100
|
+
writeLockfile(path2.join(destination, ".eigenpal", INSTALL_LOCKFILE_NAME), lockfile2);
|
|
185101
|
+
} else {
|
|
185102
|
+
rmSync(path2.join(destination, "eigenpal_modules"), { recursive: true, force: true });
|
|
185103
|
+
for (const dependency of lockfile2.root.dependencies) {
|
|
185104
|
+
await materializeLockPackage({
|
|
185105
|
+
config: config2,
|
|
185106
|
+
gitRoot: lockInstallGitRoot,
|
|
185107
|
+
repository,
|
|
185108
|
+
lockPackage: dependency,
|
|
185109
|
+
outDir: dependencyInstallPath(destination, dependency.packagePath)
|
|
185110
|
+
});
|
|
185111
|
+
}
|
|
185112
|
+
}
|
|
185113
|
+
success2(`Installed from lockfile ${lockfilePath}.`);
|
|
185114
|
+
};
|
|
185115
|
+
if (opts.frozenLockfile) {
|
|
185116
|
+
const explicitRef = Boolean(packageRef);
|
|
185117
|
+
const expectedPackagePath = packageRef ? parsePackageRef(packageRef).packagePath : null;
|
|
185118
|
+
const explicitGitRoot = explicitRef && expectedPackagePath && context.gitRoot ? packageManifestExists(context.gitRoot, expectedPackagePath) ? context.gitRoot : sourceGitRoot : sourceGitRoot;
|
|
185119
|
+
const repository = explicitRef && !explicitGitRoot ? await getSourceRepository(config2) : null;
|
|
185120
|
+
const lockfilePath = opts.lockfile ?? path2.join(packageRef && opts.out ? path2.resolve(opts.out) : context.packageRoot ?? process.cwd(), ".eigenpal", INSTALL_LOCKFILE_NAME);
|
|
185121
|
+
await installFromLock(lockfilePath, context.packageRoot, explicitRef, repository, expectedPackagePath, explicitGitRoot);
|
|
185122
|
+
return;
|
|
185123
|
+
}
|
|
185124
|
+
if (packageRef) {
|
|
185125
|
+
const parsed = parsePackageRef(packageRef);
|
|
185126
|
+
const explicitGitRoot = context.gitRoot && packageManifestExists(context.gitRoot, parsed.packagePath) ? context.gitRoot : sourceGitRoot;
|
|
185127
|
+
const repository = explicitGitRoot ? null : await getSourceRepository(config2);
|
|
185128
|
+
if (parsed.ref === "main")
|
|
185129
|
+
warn("Installing @main uses draft source and is not reproducible.");
|
|
185130
|
+
const intendedLockfile2 = opts.lockfile ?? path2.join(path2.resolve(opts.out ?? path2.basename(parsed.packagePath)), ".eigenpal", INSTALL_LOCKFILE_NAME);
|
|
185131
|
+
const inputHash2 = lockfileInputHash({ packageRef });
|
|
185132
|
+
if (existsSync3(intendedLockfile2)) {
|
|
185133
|
+
const existing = readLockfile(intendedLockfile2);
|
|
185134
|
+
if (existing.inputHash !== inputHash2) {
|
|
185135
|
+
throw new Error(`Existing lockfile ${intendedLockfile2} does not match requested package ref.`);
|
|
185136
|
+
}
|
|
185137
|
+
await installFromLock(intendedLockfile2, null, true, repository, parsed.packagePath);
|
|
185138
|
+
return;
|
|
185139
|
+
}
|
|
185140
|
+
const lockRoot = await resolvePackageGraph({
|
|
185141
|
+
config: config2,
|
|
185142
|
+
gitRoot: explicitGitRoot,
|
|
185143
|
+
repository,
|
|
185144
|
+
packagePath: parsed.packagePath,
|
|
185145
|
+
ref: parsed.ref
|
|
185146
|
+
});
|
|
185147
|
+
const outDir = path2.resolve(opts.out ?? path2.basename(parsed.packagePath));
|
|
185148
|
+
await materializeLockPackage({
|
|
185149
|
+
config: config2,
|
|
185150
|
+
gitRoot: explicitGitRoot,
|
|
185151
|
+
repository,
|
|
185152
|
+
lockPackage: lockRoot,
|
|
185153
|
+
outDir
|
|
185154
|
+
});
|
|
185155
|
+
const lockfile2 = {
|
|
185156
|
+
lockfileVersion: 1,
|
|
185157
|
+
eigenpalVersion: "1.0.0",
|
|
185158
|
+
inputHash: inputHash2,
|
|
185159
|
+
root: lockRoot
|
|
185160
|
+
};
|
|
185161
|
+
writeLockfile(intendedLockfile2, lockfile2);
|
|
185162
|
+
success2(`Installed ${parsed.packagePath}@${lockRoot.resolvedRef} into ${outDir}.`);
|
|
185163
|
+
return;
|
|
185164
|
+
}
|
|
185165
|
+
if (!context.packageRoot || !context.packagePath) {
|
|
185166
|
+
throw new Error("Run git install inside a source package or pass a package ref.");
|
|
185167
|
+
}
|
|
185168
|
+
if (!context.gitRoot) {
|
|
185169
|
+
throw new Error("Run git install inside an organization source repository.");
|
|
185170
|
+
}
|
|
185171
|
+
const manifest = readPackageManifest(context.packageRoot);
|
|
185172
|
+
const dependencies = "dependencies" in manifest ? Object.entries(manifest.dependencies ?? {}) : [];
|
|
185173
|
+
const inputHash = lockfileInputHash({ packagePath: context.packagePath, dependencies });
|
|
185174
|
+
const intendedLockfile = opts.lockfile ?? path2.join(context.packageRoot, ".eigenpal", INSTALL_LOCKFILE_NAME);
|
|
185175
|
+
if (existsSync3(intendedLockfile)) {
|
|
185176
|
+
const existing = readLockfile(intendedLockfile);
|
|
185177
|
+
if (existing.inputHash !== inputHash) {
|
|
185178
|
+
throw new Error(`Existing lockfile ${intendedLockfile} does not match current package inputs.`);
|
|
185179
|
+
}
|
|
185180
|
+
await installFromLock(intendedLockfile, context.packageRoot, false);
|
|
185181
|
+
return;
|
|
185182
|
+
}
|
|
185183
|
+
const root = {
|
|
185184
|
+
packagePath: context.packagePath,
|
|
185185
|
+
requestedRef: "main",
|
|
185186
|
+
resolvedRef: "main",
|
|
185187
|
+
commit: gitOutput(["rev-parse", "HEAD"], context.gitRoot) ?? "",
|
|
185188
|
+
dependencies: await Promise.all(dependencies.map(([dependencyName, version2]) => resolvePackageGraph({
|
|
185189
|
+
config: config2,
|
|
185190
|
+
gitRoot: context.gitRoot,
|
|
185191
|
+
packagePath: workspaceDependencyNameToPackagePath(dependencyName),
|
|
185192
|
+
ref: SourceVersionRefSchema.parse(version2)
|
|
185193
|
+
})))
|
|
185194
|
+
};
|
|
185195
|
+
rmSync(path2.join(context.packageRoot, "eigenpal_modules"), { recursive: true, force: true });
|
|
185196
|
+
for (const dependency of root.dependencies) {
|
|
185197
|
+
await materializeLockPackage({
|
|
185198
|
+
config: config2,
|
|
185199
|
+
gitRoot: context.gitRoot,
|
|
185200
|
+
lockPackage: dependency,
|
|
185201
|
+
outDir: dependencyInstallPath(context.packageRoot, dependency.packagePath)
|
|
185202
|
+
});
|
|
185203
|
+
}
|
|
185204
|
+
const lockfile = {
|
|
185205
|
+
lockfileVersion: 1,
|
|
185206
|
+
eigenpalVersion: "1.0.0",
|
|
185207
|
+
inputHash,
|
|
185208
|
+
root
|
|
185209
|
+
};
|
|
185210
|
+
writeLockfile(intendedLockfile, lockfile);
|
|
185211
|
+
success2(`Installed ${root.dependencies.length} dependencies for ${context.packagePath}.`);
|
|
185212
|
+
}
|
|
185213
|
+
function slugifyPackageSegment(value) {
|
|
185214
|
+
return value.trim().toLowerCase().replace(/[^a-z0-9_-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
185215
|
+
}
|
|
185216
|
+
function packagePathForTemplate(template2, name) {
|
|
185217
|
+
const slug = slugifyPackageSegment(name);
|
|
185218
|
+
if (!slug)
|
|
185219
|
+
throw new Error("Package name must include at least one letter or number.");
|
|
185220
|
+
const rootByTemplate = {
|
|
185221
|
+
agent: "agents",
|
|
185222
|
+
workflow: "workflows",
|
|
185223
|
+
skill: "resources/skills",
|
|
185224
|
+
rule: "resources/rules",
|
|
185225
|
+
knowledge: "resources/knowledge",
|
|
185226
|
+
evaluator: "evaluators"
|
|
185227
|
+
};
|
|
185228
|
+
const root = rootByTemplate[template2];
|
|
185229
|
+
if (!root)
|
|
185230
|
+
throw new Error("Template must be agent, workflow, skill, rule, knowledge, or evaluator.");
|
|
185231
|
+
return SourcePackagePathSchema.parse(`${root}/${slug}`);
|
|
185232
|
+
}
|
|
185233
|
+
function writePackageScaffold(packageRoot, packagePath, name) {
|
|
185234
|
+
const [root, resourceKind] = packagePath.split("/");
|
|
185235
|
+
mkdirSync2(packageRoot, { recursive: true });
|
|
185236
|
+
const title = name.trim();
|
|
185237
|
+
writeFileSync2(path2.join(packageRoot, "eigenpal.yaml"), import_yaml2.default.stringify({ schemaVersion: 1, name: title || path2.basename(packagePath) }));
|
|
185238
|
+
if (root === "agents")
|
|
185239
|
+
writeFileSync2(path2.join(packageRoot, "AGENT.md"), `# ${title}
|
|
185240
|
+
|
|
185241
|
+
`);
|
|
185242
|
+
if (root === "evaluators") {
|
|
185243
|
+
writeFileSync2(path2.join(packageRoot, "evaluator.yaml"), import_yaml2.default.stringify({ schemaVersion: 1, type: "exact-diff", config: {} }));
|
|
185244
|
+
}
|
|
185245
|
+
if (root === "resources" && resourceKind === "skills") {
|
|
185246
|
+
writeFileSync2(path2.join(packageRoot, "SKILL.md"), `# ${title}
|
|
185247
|
+
|
|
185248
|
+
`);
|
|
185249
|
+
}
|
|
185250
|
+
if (root === "resources" && (resourceKind === "rules" || resourceKind === "knowledge")) {
|
|
185251
|
+
writeFileSync2(path2.join(packageRoot, "README.md"), `# ${title}
|
|
185252
|
+
|
|
185253
|
+
`);
|
|
185254
|
+
}
|
|
185255
|
+
}
|
|
185256
|
+
function initPackage(name, opts) {
|
|
185257
|
+
const startDir = path2.resolve(opts.dir ?? process.cwd());
|
|
185258
|
+
const gitRoot = resolveGitRoot(startDir) ?? startDir;
|
|
185259
|
+
mkdirSync2(gitRoot, { recursive: true });
|
|
185260
|
+
if (!existsSync3(path2.join(gitRoot, ".git")))
|
|
185261
|
+
runGit(["init", "-b", "main", gitRoot]);
|
|
185262
|
+
if (!existsSync3(path2.join(gitRoot, "eigenpal.yaml"))) {
|
|
185263
|
+
writeFileSync2(path2.join(gitRoot, "eigenpal.yaml"), `schemaVersion: 1
|
|
185264
|
+
eigenpalVersion: 1.0.0
|
|
185265
|
+
`);
|
|
185266
|
+
}
|
|
185267
|
+
const gitignorePath = path2.join(gitRoot, ".gitignore");
|
|
185268
|
+
const gitignore = existsSync3(gitignorePath) ? readFileSync3(gitignorePath, "utf8") : "";
|
|
185269
|
+
const additions = [".eigenpal/", "eigenpal_modules/"].filter((entry) => !gitignore.includes(entry));
|
|
185270
|
+
if (additions.length > 0)
|
|
185271
|
+
writeFileSync2(gitignorePath, `${gitignore}${gitignore.endsWith(`
|
|
185272
|
+
`) || !gitignore ? "" : `
|
|
185273
|
+
`}${additions.join(`
|
|
185274
|
+
`)}
|
|
185275
|
+
`);
|
|
185276
|
+
const packagePath = packagePathForTemplate(opts.template, name);
|
|
185277
|
+
const packageRoot = path2.join(gitRoot, packagePath);
|
|
185278
|
+
if (existsSync3(packageRoot))
|
|
185279
|
+
throw new Error(`Package already exists: ${packagePath}`);
|
|
185280
|
+
writePackageScaffold(packageRoot, packagePath, name);
|
|
185281
|
+
success2(`Created ${packagePath}.`);
|
|
185282
|
+
}
|
|
185283
|
+
async function pullSource(opts) {
|
|
185284
|
+
const config2 = resolveConfig(opts);
|
|
185285
|
+
const context = resolveGitSourceContext({ dir: opts.dir });
|
|
185286
|
+
if (!context.gitRoot)
|
|
185287
|
+
throw new Error("Not inside a Git repository.");
|
|
185288
|
+
const remoteUrl = gitOutput(["remote", "get-url", "origin"], context.gitRoot);
|
|
185289
|
+
runGit(["pull", "--ff-only", "origin", "main"], {
|
|
185290
|
+
cwd: context.gitRoot,
|
|
185291
|
+
config: config2,
|
|
185292
|
+
gitRemoteUrl: remoteUrl ?? undefined
|
|
185293
|
+
});
|
|
185294
|
+
}
|
|
185295
|
+
function dirtyPackagePaths(gitRoot) {
|
|
185296
|
+
const status = gitOutput(["status", "--porcelain", "--untracked-files=all"], gitRoot) ?? "";
|
|
185297
|
+
const packagePaths = new Set;
|
|
185298
|
+
for (const line of status.split(`
|
|
185299
|
+
`)) {
|
|
185300
|
+
const file2 = line.slice(2).trim().split(" -> ").pop().replace(/\\/g, "/");
|
|
185301
|
+
const parts = file2.split("/");
|
|
185302
|
+
for (let index = parts.length;index >= 2; index -= 1) {
|
|
185303
|
+
const candidate = parts.slice(0, index).join("/");
|
|
185304
|
+
if (SourcePackagePathSchema.safeParse(candidate).success && existsSync3(path2.join(gitRoot, candidate, "eigenpal.yaml"))) {
|
|
185305
|
+
packagePaths.add(candidate);
|
|
185306
|
+
break;
|
|
185307
|
+
}
|
|
185308
|
+
}
|
|
185309
|
+
}
|
|
185310
|
+
return [...packagePaths].sort();
|
|
185311
|
+
}
|
|
185312
|
+
async function commitSource(opts) {
|
|
185313
|
+
if (!opts.message)
|
|
185314
|
+
throw new Error("Commit requires -m <message>.");
|
|
185315
|
+
const config2 = resolveConfig(opts);
|
|
185316
|
+
const context = resolveGitSourceContext({ dir: opts.dir });
|
|
185317
|
+
if (!context.gitRoot)
|
|
185318
|
+
throw new Error("Not inside a Git repository.");
|
|
185319
|
+
checkRepoVersion(context.gitRoot, true);
|
|
185320
|
+
const packagePaths = dirtyPackagePaths(context.gitRoot);
|
|
185321
|
+
if (packagePaths.length === 0) {
|
|
185322
|
+
warn("No source package changes to commit.");
|
|
185323
|
+
return;
|
|
185324
|
+
}
|
|
185325
|
+
for (const packagePath of packagePaths) {
|
|
185326
|
+
const validation = validatePackage(path2.join(context.gitRoot, packagePath));
|
|
185327
|
+
if (!validation.valid) {
|
|
185328
|
+
throw new Error(`Package validation failed for ${packagePath}: ${validation.errors.join("; ")}`);
|
|
185329
|
+
}
|
|
185330
|
+
}
|
|
185331
|
+
const rootFiles = ["eigenpal.yaml", ".gitignore"].filter((file2) => existsSync3(path2.join(context.gitRoot, file2)));
|
|
185332
|
+
runGit(["add", ...rootFiles, ...packagePaths], { cwd: context.gitRoot });
|
|
185333
|
+
const authorEnv = await resolveGitAuthorEnv(config2);
|
|
185334
|
+
runGit(["commit", "-m", opts.message], { cwd: context.gitRoot, env: authorEnv });
|
|
185335
|
+
}
|
|
185336
|
+
async function pushSource(opts) {
|
|
185337
|
+
const config2 = resolveConfig(opts);
|
|
185338
|
+
const context = resolveGitSourceContext({ dir: opts.dir });
|
|
185339
|
+
if (!context.gitRoot)
|
|
185340
|
+
throw new Error("Not inside a Git repository.");
|
|
185341
|
+
const remoteUrl = gitOutput(["remote", "get-url", "origin"], context.gitRoot);
|
|
185342
|
+
runGit(["push", "origin", "main", "--follow-tags"], {
|
|
185343
|
+
cwd: context.gitRoot,
|
|
185344
|
+
config: config2,
|
|
185345
|
+
gitRemoteUrl: remoteUrl ?? undefined
|
|
185346
|
+
});
|
|
185347
|
+
}
|
|
185348
|
+
function upgradeSource(opts) {
|
|
185349
|
+
const context = resolveGitSourceContext({ dir: opts.dir });
|
|
185350
|
+
if (!context.gitRoot)
|
|
185351
|
+
throw new Error("Not inside a Git repository.");
|
|
185352
|
+
const manifestPath = path2.join(context.gitRoot, "eigenpal.yaml");
|
|
185353
|
+
const manifest = readRootManifest(context.gitRoot);
|
|
185354
|
+
if (!manifest.ok)
|
|
185355
|
+
throw new Error(manifest.error);
|
|
185356
|
+
if (manifest.version === "1.0.0") {
|
|
185357
|
+
success2("Repository source schema is already 1.0.0.");
|
|
185358
|
+
return;
|
|
185359
|
+
}
|
|
185360
|
+
if (opts.dryRun) {
|
|
185361
|
+
console.log(`Would upgrade repository source schema from ${manifest.version} to 1.0.0.`);
|
|
185362
|
+
return;
|
|
185363
|
+
}
|
|
185364
|
+
console.log("Source repository changelog:");
|
|
185365
|
+
console.log(`- ${manifest.version} -> 1.0.0: normalize root eigenpal.yaml schema version.`);
|
|
185366
|
+
writeFileSync2(manifestPath, `schemaVersion: 1
|
|
185367
|
+
eigenpalVersion: 1.0.0
|
|
185368
|
+
`);
|
|
185369
|
+
doctor({
|
|
185370
|
+
dir: context.packagePath && context.packageRoot ? context.packageRoot : context.gitRoot
|
|
185371
|
+
});
|
|
185372
|
+
success2(`Upgraded repository source schema from ${manifest.version} to 1.0.0.`);
|
|
185373
|
+
}
|
|
184775
185374
|
function parseReleaseVersion(value) {
|
|
184776
185375
|
if (!/^\d+\.\d+\.\d+$/.test(value) && !["patch", "minor", "major"].includes(value)) {
|
|
184777
185376
|
throw new InvalidArgumentError("version must be X.Y.Z, patch, minor, or major");
|
|
@@ -184783,9 +185382,21 @@ function parseType(value) {
|
|
|
184783
185382
|
throw new InvalidArgumentError("type must be agent or workflow");
|
|
184784
185383
|
return value;
|
|
184785
185384
|
}
|
|
185385
|
+
function parseTemplate(value) {
|
|
185386
|
+
if (!["agent", "workflow", "skill", "rule", "knowledge", "evaluator"].includes(value)) {
|
|
185387
|
+
throw new InvalidArgumentError("template must be agent, workflow, skill, rule, knowledge, or evaluator");
|
|
185388
|
+
}
|
|
185389
|
+
return value;
|
|
185390
|
+
}
|
|
184786
185391
|
function registerGitCommands(program2) {
|
|
184787
185392
|
const git = program2.command("git", { hidden: true }).description("Experimental Git-backed source commands.").allowUnknownOption(true).allowExcessArguments(true).argument("[gitArgs...]", "Git arguments after --").action(action(async (gitArgs, opts) => gitPassthrough(gitArgs ?? [], opts)));
|
|
184788
185393
|
withBaseUrl(git.command("clone")).description("Clone the organization source repository.").option("--out <dir>", "Output directory").action(action(cloneSource));
|
|
185394
|
+
withBaseUrl(git.command("install [packageRef]")).description("Materialize a source package and its workspace dependencies.").option("--out <dir>", "Output directory for an explicit package ref").option("--lockfile <path>", "Lockfile path").option("--frozen-lockfile", "Install exactly from the existing lockfile").action(action(install));
|
|
185395
|
+
git.command("init <name>").description("Create a new source package scaffold.").addOption(new Option("--template <template>", "Package template").argParser(parseTemplate).makeOptionMandatory()).option("--dir <dir>", "Repository directory").action(action(async (name, opts) => initPackage(name, opts)));
|
|
185396
|
+
withBaseUrl(git.command("pull")).description("Pull organization source from origin/main with --ff-only.").option("--dir <dir>", "Repository directory").action(action(pullSource));
|
|
185397
|
+
withBaseUrl(git.command("commit")).description("Validate changed source packages and commit them.").addOption(new Option("-m, --message <message>", "Commit message").makeOptionMandatory()).option("--dir <dir>", "Repository directory").action(action(commitSource));
|
|
185398
|
+
withBaseUrl(git.command("push")).description("Push organization source main and tags.").option("--dir <dir>", "Repository directory").action(action(pushSource));
|
|
185399
|
+
git.command("upgrade").description("Upgrade the source repository schema in place.").option("--dir <dir>", "Repository directory").option("--dry-run", "Print upgrade actions without changing files").action(action(async (opts) => upgradeSource(opts)));
|
|
184789
185400
|
addJsonFlag(git.command("doctor")).description("Check organization source repository health.").option("--dir <dir>", "Directory to inspect").action(action(async (opts) => doctor(opts)));
|
|
184790
185401
|
addJsonFlag(git.command("validate [dir]")).description("Validate the nearest source package.").action(action(async (dir, opts) => validate({ ...opts, dir })));
|
|
184791
185402
|
addJsonFlag(git.command("status")).description("Show source repo and package status.").option("--dir <dir>", "Directory to inspect").action(action(async (opts) => packageStatus(opts)));
|
|
@@ -184803,11 +185414,11 @@ init_dist4();
|
|
|
184803
185414
|
import {
|
|
184804
185415
|
copyFileSync,
|
|
184805
185416
|
existsSync as existsSync4,
|
|
184806
|
-
mkdirSync as
|
|
185417
|
+
mkdirSync as mkdirSync3,
|
|
184807
185418
|
readdirSync as readdirSync2,
|
|
184808
185419
|
readFileSync as readFileSync4,
|
|
184809
185420
|
statSync as statSync2,
|
|
184810
|
-
writeFileSync as
|
|
185421
|
+
writeFileSync as writeFileSync3
|
|
184811
185422
|
} from "node:fs";
|
|
184812
185423
|
import { dirname as dirname2, join as join2, relative, resolve } from "node:path";
|
|
184813
185424
|
import { fileURLToPath } from "node:url";
|
|
@@ -184901,10 +185512,10 @@ function copyTemplate(src, dst, projectName) {
|
|
|
184901
185512
|
stack.push(sourcePath);
|
|
184902
185513
|
continue;
|
|
184903
185514
|
}
|
|
184904
|
-
|
|
185515
|
+
mkdirSync3(dirname2(targetPath), { recursive: true });
|
|
184905
185516
|
if (isTextFile(sourcePath)) {
|
|
184906
185517
|
const text = readFileSync4(sourcePath, "utf-8").replaceAll(PLACEHOLDER, projectName);
|
|
184907
|
-
|
|
185518
|
+
writeFileSync3(targetPath, text);
|
|
184908
185519
|
} else {
|
|
184909
185520
|
copyFileSync(sourcePath, targetPath);
|
|
184910
185521
|
}
|
|
@@ -184935,17 +185546,17 @@ function isTextFile(path3) {
|
|
|
184935
185546
|
|
|
184936
185547
|
// src/commands/skill.ts
|
|
184937
185548
|
init_dist4();
|
|
184938
|
-
import { createHash as
|
|
185549
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
184939
185550
|
import {
|
|
184940
185551
|
existsSync as existsSync5,
|
|
184941
185552
|
lstatSync,
|
|
184942
|
-
mkdirSync as
|
|
185553
|
+
mkdirSync as mkdirSync4,
|
|
184943
185554
|
readFileSync as readFileSync5,
|
|
184944
185555
|
readdirSync as readdirSync3,
|
|
184945
|
-
rmSync,
|
|
185556
|
+
rmSync as rmSync2,
|
|
184946
185557
|
rmdirSync,
|
|
184947
185558
|
unlinkSync as unlinkSync2,
|
|
184948
|
-
writeFileSync as
|
|
185559
|
+
writeFileSync as writeFileSync4
|
|
184949
185560
|
} from "node:fs";
|
|
184950
185561
|
import { sep as PATH_SEP, dirname as dirname3, join as join3, relative as relative2, resolve as resolve2 } from "node:path";
|
|
184951
185562
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
@@ -185034,7 +185645,7 @@ function resolveSkillTarget(opts) {
|
|
|
185034
185645
|
return opts.target ?? defaultClaudeTarget();
|
|
185035
185646
|
}
|
|
185036
185647
|
function sha256(buffer) {
|
|
185037
|
-
return
|
|
185648
|
+
return createHash3("sha256").update(buffer).digest("hex");
|
|
185038
185649
|
}
|
|
185039
185650
|
var CLI_VERSION_PLACEHOLDER = "__CLI_VERSION__";
|
|
185040
185651
|
function templateSourceFile(relativePath, bytes, cliVersion) {
|
|
@@ -185061,8 +185672,8 @@ async function installSkill(opts) {
|
|
|
185061
185672
|
const sourceBytes = templateSourceFile(relativePath, readFileSync5(sourcePath), cliVersion);
|
|
185062
185673
|
const sourceHash = sha256(sourceBytes);
|
|
185063
185674
|
if (!existsSync5(targetPath)) {
|
|
185064
|
-
|
|
185065
|
-
|
|
185675
|
+
mkdirSync4(dirname3(targetPath), { recursive: true });
|
|
185676
|
+
writeFileSync4(targetPath, sourceBytes);
|
|
185066
185677
|
written += 1;
|
|
185067
185678
|
continue;
|
|
185068
185679
|
}
|
|
@@ -185075,7 +185686,7 @@ async function installSkill(opts) {
|
|
|
185075
185686
|
const previousEntry = existingManifest?.files.find((f) => f.path === relativePath);
|
|
185076
185687
|
const userEdited = previousEntry ? previousEntry.sha256 !== targetHash : true;
|
|
185077
185688
|
if (!userEdited || opts.force) {
|
|
185078
|
-
|
|
185689
|
+
writeFileSync4(targetPath, sourceBytes);
|
|
185079
185690
|
written += 1;
|
|
185080
185691
|
continue;
|
|
185081
185692
|
}
|
|
@@ -185086,7 +185697,7 @@ async function installSkill(opts) {
|
|
|
185086
185697
|
prompted += 1;
|
|
185087
185698
|
const choice = await promptThreeWay(targetPath, sourceBytes, targetBytes);
|
|
185088
185699
|
if (choice === "overwrite") {
|
|
185089
|
-
|
|
185700
|
+
writeFileSync4(targetPath, sourceBytes);
|
|
185090
185701
|
written += 1;
|
|
185091
185702
|
} else {
|
|
185092
185703
|
skipped += 1;
|
|
@@ -185104,7 +185715,7 @@ async function installSkill(opts) {
|
|
|
185104
185715
|
installedAt: new Date().toISOString(),
|
|
185105
185716
|
files: manifestEntries
|
|
185106
185717
|
};
|
|
185107
|
-
|
|
185718
|
+
writeFileSync4(join3(target, MANIFEST_NAME), `${JSON.stringify(manifest, null, 2)}
|
|
185108
185719
|
`);
|
|
185109
185720
|
const displayTarget = relative2(process.cwd(), target) || target;
|
|
185110
185721
|
success2(`Installed skill at ${ui.bold(displayTarget)} — ${written} written, ${skipped} unchanged${prompted > 0 ? `, ${prompted} prompted` : ""}.`);
|
|
@@ -185146,7 +185757,7 @@ async function uninstallSkill(opts) {
|
|
|
185146
185757
|
unlinkSync2(path3);
|
|
185147
185758
|
removed += 1;
|
|
185148
185759
|
}
|
|
185149
|
-
|
|
185760
|
+
rmSync2(join3(target, MANIFEST_NAME), { force: true });
|
|
185150
185761
|
pruneEmptyDirs(target);
|
|
185151
185762
|
const displayTarget = relative2(process.cwd(), target) || target;
|
|
185152
185763
|
success2(`Uninstalled skill from ${ui.bold(displayTarget)} — ${removed} removed${kept > 0 ? `, ${kept} user-edited kept` : ""}.`);
|
|
@@ -186303,7 +186914,7 @@ async function resolveWorkflowId(client, idOrSlug) {
|
|
|
186303
186914
|
}
|
|
186304
186915
|
|
|
186305
186916
|
// src/commands/clear.ts
|
|
186306
|
-
import { existsSync as existsSync8, readdirSync as readdirSync5, rmSync as
|
|
186917
|
+
import { existsSync as existsSync8, readdirSync as readdirSync5, rmSync as rmSync3, statSync as statSync4 } from "fs";
|
|
186307
186918
|
import { basename, join as join7 } from "path";
|
|
186308
186919
|
|
|
186309
186920
|
// src/lib/payload.ts
|
|
@@ -186420,7 +187031,7 @@ function removeDirEntriesWithRetention(path3, removeAll) {
|
|
|
186420
187031
|
for (const entry of entries) {
|
|
186421
187032
|
if (keepSet.has(entry))
|
|
186422
187033
|
continue;
|
|
186423
|
-
|
|
187034
|
+
rmSync3(join7(path3, entry), { recursive: true, force: true });
|
|
186424
187035
|
removed++;
|
|
186425
187036
|
}
|
|
186426
187037
|
return { removed, kept: keepSet.size, touched: entries.length };
|
|
@@ -186447,7 +187058,7 @@ function removeJudgeSummaryFilesWithRetention(exampleDir, removeAll) {
|
|
|
186447
187058
|
kept++;
|
|
186448
187059
|
continue;
|
|
186449
187060
|
}
|
|
186450
|
-
|
|
187061
|
+
rmSync3(join7(exampleDir, fileName), { force: true });
|
|
186451
187062
|
removed++;
|
|
186452
187063
|
}
|
|
186453
187064
|
return { removed, kept, touched: stampByFile.size };
|
|
@@ -186643,11 +187254,11 @@ async function watchExecution(opts) {
|
|
|
186643
187254
|
import { join as join11 } from "path";
|
|
186644
187255
|
|
|
186645
187256
|
// src/lib/execution-artifacts.ts
|
|
186646
|
-
import { existsSync as existsSync9, mkdirSync as
|
|
187257
|
+
import { existsSync as existsSync9, mkdirSync as mkdirSync5, readdirSync as readdirSync6, readFileSync as readFileSync9, writeFileSync as writeFileSync6 } from "fs";
|
|
186647
187258
|
import { join as join10 } from "path";
|
|
186648
187259
|
|
|
186649
187260
|
// src/lib/format.ts
|
|
186650
|
-
import { readFileSync as readFileSync8, writeFileSync as
|
|
187261
|
+
import { readFileSync as readFileSync8, writeFileSync as writeFileSync5 } from "fs";
|
|
186651
187262
|
import { extname as extname3, resolve as resolve5 } from "path";
|
|
186652
187263
|
var PRETTIER_EXTENSIONS = new Set([".json", ".yaml", ".yml"]);
|
|
186653
187264
|
async function formatFileIfAvailable(filepath) {
|
|
@@ -186660,7 +187271,7 @@ async function formatFileIfAvailable(filepath) {
|
|
|
186660
187271
|
filepath: resolve5(filepath)
|
|
186661
187272
|
});
|
|
186662
187273
|
if (formatted !== content) {
|
|
186663
|
-
|
|
187274
|
+
writeFileSync5(filepath, formatted, "utf-8");
|
|
186664
187275
|
}
|
|
186665
187276
|
} catch (err2) {
|
|
186666
187277
|
if (env.DEBUG?.includes("prettier")) {
|
|
@@ -186694,7 +187305,7 @@ async function writeExecutionArtifacts(client, exampleDir, payload) {
|
|
|
186694
187305
|
const folderName = timestampFolderName(payload);
|
|
186695
187306
|
const executionsDir = join10(exampleDir, "executions", folderName);
|
|
186696
187307
|
const filesDir = join10(executionsDir, "files");
|
|
186697
|
-
|
|
187308
|
+
mkdirSync5(filesDir, { recursive: true });
|
|
186698
187309
|
const generatedFiles = [];
|
|
186699
187310
|
const result = payload.result;
|
|
186700
187311
|
if (isWorkflowResult2(result) && result.files.length > 0) {
|
|
@@ -186711,7 +187322,7 @@ async function writeExecutionArtifacts(client, exampleDir, payload) {
|
|
|
186711
187322
|
const safe = safeFilename(filename, `file-${i5}${filename.includes(".") ? "" : ".bin"}`);
|
|
186712
187323
|
const destPath = join10(filesDir, safe);
|
|
186713
187324
|
const buf = Buffer.from(await res.arrayBuffer());
|
|
186714
|
-
|
|
187325
|
+
writeFileSync6(destPath, buf);
|
|
186715
187326
|
generatedFiles.push({ fileId, stepName, filename: safe });
|
|
186716
187327
|
} catch (err2) {
|
|
186717
187328
|
console.warn(` Warning: could not download file ${fileId}:`, err2);
|
|
@@ -186723,7 +187334,7 @@ async function writeExecutionArtifacts(client, exampleDir, payload) {
|
|
|
186723
187334
|
generatedFiles: generatedFiles.length > 0 ? generatedFiles : undefined
|
|
186724
187335
|
};
|
|
186725
187336
|
const outputPath = join10(executionsDir, "output.json");
|
|
186726
|
-
|
|
187337
|
+
writeFileSync6(outputPath, JSON.stringify(output, null, 2) + `
|
|
186727
187338
|
`, "utf-8");
|
|
186728
187339
|
await formatFileIfAvailable(outputPath);
|
|
186729
187340
|
return executionsDir;
|
|
@@ -2,212 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
Experimental Git-backed source commands.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Experimental.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
- [Commands](#commands)
|
|
9
|
-
- [Core](#core)
|
|
10
|
-
- [Details](#details)
|
|
11
|
-
- [`eigenpal git clone [options]`](#eigenpal-git-clone-options)
|
|
12
|
-
- [`eigenpal git doctor [options]`](#eigenpal-git-doctor-options)
|
|
13
|
-
- [`eigenpal git validate [options] [dir]`](#eigenpal-git-validate-options-dir)
|
|
14
|
-
- [`eigenpal git status [options]`](#eigenpal-git-status-options)
|
|
15
|
-
- [`eigenpal git deps [options]`](#eigenpal-git-deps-options)
|
|
16
|
-
- [`eigenpal git clean [options]`](#eigenpal-git-clean-options)
|
|
17
|
-
- [`eigenpal git list|ls [options]`](#eigenpal-git-listls-options)
|
|
18
|
-
- [`eigenpal git show [options] <automation>`](#eigenpal-git-show-options-automation)
|
|
19
|
-
- [`eigenpal git versions [options] <package>`](#eigenpal-git-versions-options-package)
|
|
20
|
-
- [`eigenpal git release [options] <version> [dir]`](#eigenpal-git-release-options-version-dir)
|
|
21
|
-
- [`eigenpal git sync [options] [automation]`](#eigenpal-git-sync-options-automation)
|
|
22
|
-
|
|
23
|
-
## Surface
|
|
24
|
-
|
|
25
|
-
```
|
|
26
|
-
git
|
|
27
|
-
├── clone
|
|
28
|
-
├── doctor
|
|
29
|
-
├── validate [dir]
|
|
30
|
-
├── status
|
|
31
|
-
├── deps
|
|
32
|
-
├── clean
|
|
33
|
-
├── list|ls
|
|
34
|
-
├── show <automation>
|
|
35
|
-
├── versions <package>
|
|
36
|
-
├── release <version> [dir]
|
|
37
|
-
└── sync [automation]
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
## Commands
|
|
41
|
-
|
|
42
|
-
### Core
|
|
43
|
-
|
|
44
|
-
| Command | Description |
|
|
45
|
-
| ------------------------------------------------ | ------------------------------------------------------ | ---------------------------- |
|
|
46
|
-
| `eigenpal git clone [options]` | Clone the organization source repository. |
|
|
47
|
-
| `eigenpal git doctor [options]` | Check organization source repository health. |
|
|
48
|
-
| `eigenpal git validate [options] [dir]` | Validate the nearest source package. |
|
|
49
|
-
| `eigenpal git status [options]` | Show source repo and package status. |
|
|
50
|
-
| `eigenpal git deps [options]` | List package workspace dependencies. |
|
|
51
|
-
| `eigenpal git clean [options]` | Require a clean source working tree. |
|
|
52
|
-
| `eigenpal git list | ls [options]` | List Git-backed automations. |
|
|
53
|
-
| `eigenpal git show [options] <automation>` | Show Git-backed automation details. |
|
|
54
|
-
| `eigenpal git versions [options] <package>` | List package release versions. |
|
|
55
|
-
| `eigenpal git release [options] <version> [dir]` | Create and push a package release tag. |
|
|
56
|
-
| `eigenpal git sync [options] [automation]` | Sync an automation from the latest Git source release. |
|
|
57
|
-
|
|
58
|
-
## Details
|
|
59
|
-
|
|
60
|
-
### `eigenpal git clone [options]`
|
|
61
|
-
|
|
62
|
-
Clone the organization source repository.
|
|
63
|
-
|
|
64
|
-
### Options
|
|
65
|
-
|
|
66
|
-
| Flag | Required | Default | Description |
|
|
67
|
-
| ------------------ | -------- | ------- | ---------------- |
|
|
68
|
-
| `--base-url <url>` | no | | Server base URL |
|
|
69
|
-
| `--out <dir>` | no | | Output directory |
|
|
70
|
-
|
|
71
|
-
### `eigenpal git doctor [options]`
|
|
72
|
-
|
|
73
|
-
Check organization source repository health.
|
|
74
|
-
|
|
75
|
-
### Options
|
|
76
|
-
|
|
77
|
-
| Flag | Required | Default | Description |
|
|
78
|
-
| ------------- | -------- | ------- | -------------------------------------- |
|
|
79
|
-
| `--json` | no | | Output the raw server response as JSON |
|
|
80
|
-
| `--dir <dir>` | no | | Directory to inspect |
|
|
81
|
-
|
|
82
|
-
### `eigenpal git validate [options] [dir]`
|
|
83
|
-
|
|
84
|
-
Validate the nearest source package.
|
|
85
|
-
|
|
86
|
-
### Arguments
|
|
87
|
-
|
|
88
|
-
| Name | Required | Variadic | Description |
|
|
89
|
-
| ----- | -------- | -------- | ----------- |
|
|
90
|
-
| `dir` | no | no | |
|
|
91
|
-
|
|
92
|
-
### Options
|
|
93
|
-
|
|
94
|
-
| Flag | Required | Default | Description |
|
|
95
|
-
| -------- | -------- | ------- | -------------------------------------- |
|
|
96
|
-
| `--json` | no | | Output the raw server response as JSON |
|
|
97
|
-
|
|
98
|
-
### `eigenpal git status [options]`
|
|
99
|
-
|
|
100
|
-
Show source repo and package status.
|
|
101
|
-
|
|
102
|
-
### Options
|
|
103
|
-
|
|
104
|
-
| Flag | Required | Default | Description |
|
|
105
|
-
| ------------- | -------- | ------- | -------------------------------------- |
|
|
106
|
-
| `--json` | no | | Output the raw server response as JSON |
|
|
107
|
-
| `--dir <dir>` | no | | Directory to inspect |
|
|
108
|
-
|
|
109
|
-
### `eigenpal git deps [options]`
|
|
110
|
-
|
|
111
|
-
List package workspace dependencies.
|
|
112
|
-
|
|
113
|
-
### Options
|
|
114
|
-
|
|
115
|
-
| Flag | Required | Default | Description |
|
|
116
|
-
| ------------- | -------- | ------- | -------------------------------------- |
|
|
117
|
-
| `--json` | no | | Output the raw server response as JSON |
|
|
118
|
-
| `--dir <dir>` | no | | Directory to inspect |
|
|
119
|
-
|
|
120
|
-
### `eigenpal git clean [options]`
|
|
121
|
-
|
|
122
|
-
Require a clean source working tree.
|
|
123
|
-
|
|
124
|
-
### Options
|
|
125
|
-
|
|
126
|
-
| Flag | Required | Default | Description |
|
|
127
|
-
| ------------- | -------- | ------- | -------------------- |
|
|
128
|
-
| `--dir <dir>` | no | | Directory to inspect |
|
|
129
|
-
|
|
130
|
-
### `eigenpal git list|ls [options]`
|
|
131
|
-
|
|
132
|
-
List Git-backed automations.
|
|
133
|
-
|
|
134
|
-
### Options
|
|
135
|
-
|
|
136
|
-
| Flag | Required | Default | Description |
|
|
137
|
-
| -------------------- | -------- | ------- | -------------------------------------- |
|
|
138
|
-
| `--base-url <url>` | no | | Server base URL |
|
|
139
|
-
| `--limit <n>` | no | `50` | Page size |
|
|
140
|
-
| `--offset <n>` | no | `0` | Page offset |
|
|
141
|
-
| `--json` | no | | Output the raw server response as JSON |
|
|
142
|
-
| `--type <type>` | no | | Filter by automation type |
|
|
143
|
-
| `--search <q>` | no | | Search by slug, name, or description |
|
|
144
|
-
| `--include-archived` | no | | Include archived automations |
|
|
145
|
-
|
|
146
|
-
### `eigenpal git show [options] <automation>`
|
|
147
|
-
|
|
148
|
-
Show Git-backed automation details.
|
|
149
|
-
|
|
150
|
-
### Arguments
|
|
151
|
-
|
|
152
|
-
| Name | Required | Variadic | Description |
|
|
153
|
-
| ------------ | -------- | -------- | ----------- |
|
|
154
|
-
| `automation` | yes | no | |
|
|
155
|
-
|
|
156
|
-
### Options
|
|
157
|
-
|
|
158
|
-
| Flag | Required | Default | Description |
|
|
159
|
-
| ------------------ | -------- | ------- | -------------------------------------- |
|
|
160
|
-
| `--base-url <url>` | no | | Server base URL |
|
|
161
|
-
| `--json` | no | | Output the raw server response as JSON |
|
|
162
|
-
|
|
163
|
-
### `eigenpal git versions [options] <package>`
|
|
164
|
-
|
|
165
|
-
List package release versions.
|
|
166
|
-
|
|
167
|
-
### Arguments
|
|
168
|
-
|
|
169
|
-
| Name | Required | Variadic | Description |
|
|
170
|
-
| --------- | -------- | -------- | ----------- |
|
|
171
|
-
| `package` | yes | no | |
|
|
172
|
-
|
|
173
|
-
### Options
|
|
174
|
-
|
|
175
|
-
| Flag | Required | Default | Description |
|
|
176
|
-
| ------------------ | -------- | ------- | -------------------------------------- |
|
|
177
|
-
| `--base-url <url>` | no | | Server base URL |
|
|
178
|
-
| `--json` | no | | Output the raw server response as JSON |
|
|
179
|
-
|
|
180
|
-
### `eigenpal git release [options] <version> [dir]`
|
|
181
|
-
|
|
182
|
-
Create and push a package release tag.
|
|
183
|
-
|
|
184
|
-
### Arguments
|
|
185
|
-
|
|
186
|
-
| Name | Required | Variadic | Description |
|
|
187
|
-
| --------- | -------- | -------- | --------------------- |
|
|
188
|
-
| `version` | yes | no | Version or bump level |
|
|
189
|
-
| `dir` | no | no | Package directory |
|
|
190
|
-
|
|
191
|
-
### Options
|
|
192
|
-
|
|
193
|
-
| Flag | Required | Default | Description |
|
|
194
|
-
| ------------------------- | -------- | ------- | --------------------- |
|
|
195
|
-
| `--base-url <url>` | no | | Server base URL |
|
|
196
|
-
| `-m, --message <message>` | yes | | Annotated tag message |
|
|
197
|
-
|
|
198
|
-
### `eigenpal git sync [options] [automation]`
|
|
199
|
-
|
|
200
|
-
Sync an automation from the latest Git source release.
|
|
201
|
-
|
|
202
|
-
### Arguments
|
|
203
|
-
|
|
204
|
-
| Name | Required | Variadic | Description |
|
|
205
|
-
| ------------ | -------- | -------- | ----------- |
|
|
206
|
-
| `automation` | no | no | |
|
|
207
|
-
|
|
208
|
-
### Options
|
|
209
|
-
|
|
210
|
-
| Flag | Required | Default | Description |
|
|
211
|
-
| ------------------ | -------- | ------- | -------------------- |
|
|
212
|
-
| `--base-url <url>` | no | | Server base URL |
|
|
213
|
-
| `--dir <dir>` | no | | Directory to inspect |
|
|
7
|
+
This command namespace is intentionally not documented in detail yet.
|