@tablation/crew 0.1.7 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/cli.js +48 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -211,7 +211,7 @@ crew pause|resume [route] [R] pause everything, or one role
|
|
|
211
211
|
crew log [route] tail the log
|
|
212
212
|
crew inbox [--member NAME] your tickets across every workspace
|
|
213
213
|
crew connect WS[/PROJECT] resolve a workspace/project's ids into the state tree
|
|
214
|
-
crew repos add ROUTE PATH
|
|
214
|
+
crew repos add [ROUTE] [NAME] [PATH] attach a local checkout to a route in crew.yaml, creating its Repos row if missing (--dry-run previews)
|
|
215
215
|
crew repos list ROUTE the checkouts a route has, and the tracker Repos row each matches
|
|
216
216
|
crew install write and load this platform's scheduler unit
|
|
217
217
|
crew uninstall unload and remove it
|
package/dist/cli.js
CHANGED
|
@@ -7042,6 +7042,27 @@ function matchRepoName(origin, resolved) {
|
|
|
7042
7042
|
}
|
|
7043
7043
|
return void 0;
|
|
7044
7044
|
}
|
|
7045
|
+
function routeNamesOf(text) {
|
|
7046
|
+
const routes = parseDocument(text).get("routes", true);
|
|
7047
|
+
if (!isSeq(routes)) return [];
|
|
7048
|
+
return routes.items.flatMap((i) => isMap(i) && typeof i.get("route") === "string" ? [i.get("route")] : []);
|
|
7049
|
+
}
|
|
7050
|
+
function parseAddArgs(args, routes, isDir) {
|
|
7051
|
+
const rest = [...args];
|
|
7052
|
+
let route;
|
|
7053
|
+
if (rest.length > 0 && routes.includes(rest[0])) route = rest.shift();
|
|
7054
|
+
else if (rest.length > 0 && /^[^/\s]+\/[^/\s]+$/.test(rest[0]) && !isDir(rest[0])) {
|
|
7055
|
+
throw new ReposError(`no route "${rest[0]}" in the config (have: ${routes.join(", ") || "none"})`);
|
|
7056
|
+
}
|
|
7057
|
+
if (!route) {
|
|
7058
|
+
if (routes.length === 1) route = routes[0];
|
|
7059
|
+
else throw new ReposError(routes.length === 0 ? "the config has no routes \u2014 run `crew connect` first" : `several routes are configured; name one: ${routes.join(", ")}`);
|
|
7060
|
+
}
|
|
7061
|
+
if (rest.length > 2) throw new ReposError("too many arguments: expected [route] [name] [path]");
|
|
7062
|
+
if (rest.length === 2) return { route, name: rest[0], path: rest[1] };
|
|
7063
|
+
if (rest.length === 1) return isDir(rest[0]) ? { route, path: rest[0] } : { route, name: rest[0], path: "." };
|
|
7064
|
+
return { route, path: "." };
|
|
7065
|
+
}
|
|
7045
7066
|
function expandDir(p, base) {
|
|
7046
7067
|
const home = p === "~" ? homedir3() : p.startsWith("~/") ? `${homedir3()}/${p.slice(2)}` : p;
|
|
7047
7068
|
return resolve3(base, home);
|
|
@@ -7081,7 +7102,7 @@ function planRepoAdd(i) {
|
|
|
7081
7102
|
throw new ReposError(`${target} is already configured on route ${i.route}`);
|
|
7082
7103
|
}
|
|
7083
7104
|
const matched = matchRepoName(i.origin, i.resolved);
|
|
7084
|
-
const name = matched ?? i.name ?? basename5(target);
|
|
7105
|
+
const name = matched ?? i.name ?? normalizeRemote(i.origin)?.split("/").pop() ?? basename5(target);
|
|
7085
7106
|
let warning;
|
|
7086
7107
|
if (!matched) {
|
|
7087
7108
|
const known = Object.values(i.resolved?.repoNames ?? {});
|
|
@@ -8327,7 +8348,7 @@ function usage() {
|
|
|
8327
8348
|
crew agents sync [route] [--force] push crew's personas AND skill files into the workspace Agents/Agent Skills tables (--force overwrites even a diverged persona)
|
|
8328
8349
|
crew agents prompt R [route] print one persona's current prompt (e.g. R=pair, for a SessionStart hook)
|
|
8329
8350
|
crew skills sync [route] push only crew's skill files (e.g. grill-me) into the workspace Agent Skills table
|
|
8330
|
-
crew repos add ROUTE PATH
|
|
8351
|
+
crew repos add [ROUTE] [NAME] [PATH] attach a local checkout to a route in crew.yaml (--dry-run previews)
|
|
8331
8352
|
crew repos list ROUTE the checkouts a route has, with the tracker's Repos row each matches
|
|
8332
8353
|
crew logbook list [route] recent Agent Log entries, filterable by --role/--ticket
|
|
8333
8354
|
crew logbook show [route] ID [--prompt] one entry; --prompt reconstructs and verifies its prompt
|
|
@@ -9613,12 +9634,31 @@ ${changed2.map((c) => ` - ${c}
|
|
|
9613
9634
|
}
|
|
9614
9635
|
case "repos": {
|
|
9615
9636
|
const sub = positional[1];
|
|
9616
|
-
const routeName = positional[2];
|
|
9617
9637
|
const usage2 = () => {
|
|
9618
|
-
process.stderr.write("crew repos add
|
|
9638
|
+
process.stderr.write("crew repos add [workspace/project] [name] [path] [--name N] [--project P] [--dry-run] [--no-create]\ncrew repos list <workspace/project>\n");
|
|
9619
9639
|
process.exit(2);
|
|
9620
9640
|
};
|
|
9621
|
-
if (sub !== "add" && sub !== "list"
|
|
9641
|
+
if (sub !== "add" && sub !== "list") usage2();
|
|
9642
|
+
const configText = readFileSync12(cfg.configFile, "utf8");
|
|
9643
|
+
let routeName = positional[2];
|
|
9644
|
+
let addPath = ".";
|
|
9645
|
+
let addName;
|
|
9646
|
+
if (sub === "list" && !routeName) usage2();
|
|
9647
|
+
if (sub === "add") {
|
|
9648
|
+
try {
|
|
9649
|
+
const a = parseAddArgs(positional.slice(2), routeNamesOf(configText), (p) => existsSync18(resolvePath(p.replace(/^~(?=\/|$)/, homedir4()))));
|
|
9650
|
+
routeName = a.route;
|
|
9651
|
+
addPath = a.path;
|
|
9652
|
+
addName = a.name;
|
|
9653
|
+
} catch (e) {
|
|
9654
|
+
if (e instanceof ReposError) {
|
|
9655
|
+
process.stderr.write(`crew repos: ${e.message}
|
|
9656
|
+
`);
|
|
9657
|
+
process.exit(2);
|
|
9658
|
+
}
|
|
9659
|
+
throw e;
|
|
9660
|
+
}
|
|
9661
|
+
}
|
|
9622
9662
|
const resolvedFile = resolvedPathFor(cfg.ship.stateDir, routeName);
|
|
9623
9663
|
let resolvedRemotes;
|
|
9624
9664
|
if (existsSync18(resolvedFile)) {
|
|
@@ -9628,7 +9668,7 @@ ${changed2.map((c) => ` - ${c}
|
|
|
9628
9668
|
}
|
|
9629
9669
|
}
|
|
9630
9670
|
const originOf = (dir) => gitOk(dir, ["remote", "get-url", "origin"]) ?? void 0;
|
|
9631
|
-
const text =
|
|
9671
|
+
const text = configText;
|
|
9632
9672
|
const base = dirname9(cfg.configFile);
|
|
9633
9673
|
try {
|
|
9634
9674
|
if (sub === "list") {
|
|
@@ -9644,7 +9684,7 @@ ${changed2.map((c) => ` - ${c}
|
|
|
9644
9684
|
}
|
|
9645
9685
|
break;
|
|
9646
9686
|
}
|
|
9647
|
-
const target = resolvePath(
|
|
9687
|
+
const target = resolvePath(addPath.replace(/^~(?=\/|$)/, homedir4()));
|
|
9648
9688
|
const top = existsSync18(target) ? gitOk(target, ["rev-parse", "--show-toplevel"]) : null;
|
|
9649
9689
|
if (!top) throw new ReposError(`${target} is not a git checkout`);
|
|
9650
9690
|
const origin = originOf(top);
|
|
@@ -9655,7 +9695,7 @@ ${changed2.map((c) => ` - ${c}
|
|
|
9655
9695
|
path: top,
|
|
9656
9696
|
origin,
|
|
9657
9697
|
resolved: resolvedRemotes,
|
|
9658
|
-
name: value("name"),
|
|
9698
|
+
name: value("name") ?? addName,
|
|
9659
9699
|
nameForExisting: (d) => matchRepoName(originOf(d), resolvedRemotes)
|
|
9660
9700
|
});
|
|
9661
9701
|
let rowTracker;
|
package/package.json
CHANGED