@outerlayer/cli 0.2.0 → 0.4.1
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 +132 -0
- package/README.md +229 -60
- package/dist/agent-setup-IFH3FB5X.js +197 -0
- package/dist/build-TZUUTRGH.js +9 -0
- package/dist/build-info.json +1 -1
- package/dist/check-7MFH6HNC.js +94 -0
- package/dist/chunk-3TFPDVTI.js +94 -0
- package/dist/{chunk-4TNZMO7V.js → chunk-4C4THABW.js} +5566 -754
- package/dist/{chunk-R5KBGVII.js → chunk-5QRP3MVS.js} +30 -14
- package/dist/chunk-5Y3QQRUH.js +300 -0
- package/dist/chunk-774HEQL6.js +178 -0
- package/dist/{work-pr-cmd-AZQPWH4H.js → chunk-7WERLFVR.js} +9 -26
- package/dist/chunk-ABIWDUMS.js +104 -0
- package/dist/chunk-AUFG23AA.js +534 -0
- package/dist/chunk-B2G7JHHB.js +42 -0
- package/dist/chunk-BCJNHMZT.js +34 -0
- package/dist/chunk-BCLJSQCV.js +56 -0
- package/dist/chunk-BFESLKPP.js +61 -0
- package/dist/chunk-BJ3KTMDH.js +63 -0
- package/dist/chunk-BKO6JEZI.js +47 -0
- package/dist/chunk-BOLTI6LR.js +37 -0
- package/dist/chunk-CBPPJSAR.js +89 -0
- package/dist/chunk-DM3VFDS3.js +1461 -0
- package/dist/{chunk-65WXAANR.js → chunk-DVDEBNQJ.js} +17 -2
- package/dist/{chunk-TFUIDMOB.js → chunk-EABW6AJQ.js} +12 -1
- package/dist/{chunk-KFYJV2ZG.js → chunk-EMY4I27X.js} +1 -1
- package/dist/{chunk-NTTPJV35.js → chunk-F47JBIAW.js} +3 -1
- package/dist/chunk-F6GFZXZ3.js +60 -0
- package/dist/{chunk-YOOSBOKS.js → chunk-F7CU5ABH.js} +1 -1
- package/dist/{emit-cmd-TWSYYEZI.js → chunk-H5NCNVDA.js} +68 -17
- package/dist/chunk-HZRNMGLF.js +2233 -0
- package/dist/chunk-LF6MLJCY.js +38 -0
- package/dist/{chunk-U32VSRLO.js → chunk-LT5TZHYH.js} +95 -634
- package/dist/chunk-LYCDNMOH.js +83 -0
- package/dist/chunk-M5POMKKW.js +1051 -0
- package/dist/{mcp-install-cmd-FDQH6SEN.js → chunk-MQ3IPHIZ.js} +35 -18
- package/dist/{chunk-D77LS3UI.js → chunk-N5FOE5PS.js} +33 -4
- package/dist/chunk-N6LURUEF.js +64 -0
- package/dist/chunk-OGFGZQA3.js +23 -0
- package/dist/chunk-QDQEUVUF.js +9 -0
- package/dist/chunk-QOZKPLVJ.js +226 -0
- package/dist/chunk-QY22NZUW.js +1764 -0
- package/dist/chunk-RA3O54FC.js +30 -0
- package/dist/chunk-RFUPN6KX.js +71 -0
- package/dist/chunk-SY4GK4SP.js +55 -0
- package/dist/chunk-TBT347UY.js +41 -0
- package/dist/chunk-TWNWNS2Q.js +1084 -0
- package/dist/{chunk-NXLLURA4.js → chunk-UFFXNXLQ.js} +115 -71
- package/dist/chunk-USO2DKBD.js +421 -0
- package/dist/chunk-W4SQCOZU.js +206 -0
- package/dist/{chunk-Q6CL5THG.js → chunk-W5FVUZXV.js} +208 -61
- package/dist/chunk-WFJ65NUD.js +383 -0
- package/dist/{chunk-A3WLZX2F.js → chunk-WIOZAJ2W.js} +15 -2
- package/dist/chunk-WO2BXCTQ.js +83 -0
- package/dist/{chunk-I3ETLSNE.js → chunk-XCCLFVXM.js} +120 -11
- package/dist/{context-materialize-6WKT3RBQ.js → chunk-XDDW4FRS.js} +134 -26
- package/dist/chunk-Y7KJLXYN.js +232 -0
- package/dist/chunk-YFHIIH4B.js +102 -0
- package/dist/chunk-YYYXRJUW.js +101 -0
- package/dist/chunk-ZM2IMMYN.js +76 -0
- package/dist/chunk-ZMYPLFG3.js +71 -0
- package/dist/chunk-ZNA27WEV.js +470 -0
- package/dist/{cli-G7DILYJY.js → cli-W62AFRSW.js} +616 -878
- package/dist/{paths-D2VGWWFI.js → cli-build-K56DK4DS.js} +1 -1
- package/dist/config-XVJYZ4IQ.js +9 -0
- package/dist/connect-cmd-ZTJONP37.js +16 -0
- package/dist/context-adopt-UMA4O5NY.js +105 -0
- package/dist/context-materialize-G2FUFC72.js +19 -0
- package/dist/dist-44CQVWGT.js +6 -0
- package/dist/docker-NEGDLU6D.js +7 -0
- package/dist/doctor-53F2PYY7.js +43 -0
- package/dist/doctor-ZLGZYMDK.js +426 -0
- package/dist/{emit-artifact-cmd-UQVT3OKW.js → emit-artifact-cmd-AKZP7TMF.js} +87 -23
- package/dist/emit-cmd-DCERAU27.js +9 -0
- package/dist/emit-criteria-cmd-7MXQVCKD.js +166 -0
- package/dist/{emit-finding-cmd-FDOU2OPD.js → emit-finding-cmd-N2FTGCVC.js} +34 -31
- package/dist/{emit-result-cmd-H2T4C2K3.js → emit-result-cmd-4CPDBMN2.js} +34 -62
- package/dist/exec-client-4XGXV3XN.js +8 -0
- package/dist/guest-init-GENRHNP7.js +8 -0
- package/dist/hook-fast-EYENPK6F.js +9 -0
- package/dist/{hook-wrap-fast-KXYNX3AD.js → hook-wrap-fast-NPLHJXFK.js} +2 -2
- package/dist/host-key-KDYZ5ECC.js +7 -0
- package/dist/import-capture-cmd-AVZ4VIVJ.js +68 -0
- package/dist/{import-ruler-cmd-7LH2QOMG.js → import-ruler-cmd-GUHL6IY5.js} +1 -1
- package/dist/index.js +4 -4
- package/dist/init-55Y4LHWF.js +36 -0
- package/dist/init-XXEKWZQP.js +221 -0
- package/dist/init-cmd-WLST2F7G.js +135 -0
- package/dist/install-cmd-7WXOIFDO.js +55 -0
- package/dist/lima-XN65D7GN.js +55 -0
- package/dist/login-browser-7XGSV7MA.js +10 -0
- package/dist/{config-POF7DEQW.js → logout-cmd-QAUFDJ6J.js} +3 -1
- package/dist/{logs-TRNPQM42.js → logs-7RYUH5A6.js} +1 -1
- package/dist/loop-JFIBP4B7.js +43 -0
- package/dist/machine-ZBPT2J3R.js +35 -0
- package/dist/mcp-install-cmd-RLK4SO3N.js +9 -0
- package/dist/{mcp-serve-cmd-57EZZOTL.js → mcp-serve-cmd-N6UD2KBX.js} +20 -9
- package/dist/paths-OYKMVYJP.js +6 -0
- package/dist/{pidfile-PTW76F56.js → pidfile-UZRH774M.js} +2 -3
- package/dist/real-deps-SU24ZA2K.js +21 -0
- package/dist/relay-L76HDX72.js +46 -0
- package/dist/settings-J2652U5N.js +7 -0
- package/dist/starter-pack-LIZYMKYQ.js +10 -0
- package/dist/{status-I27IST4L.js → status-UJXWZRN5.js} +30 -13
- package/dist/{statusline-fast-3C5OXHDD.js → statusline-fast-SVTMBMD7.js} +3 -2
- package/dist/sync-cmd-4G4A7EVN.js +28 -0
- package/dist/version-BWM6VLDI.js +6 -0
- package/dist/{watch-3DTPJETH.js → watch-7SKJKGAA.js} +19 -8
- package/dist/{work-claim-cmd-5AUNCLS2.js → work-claim-cmd-5F7VZ42N.js} +34 -21
- package/dist/work-cmd-QAUZ7MTD.js +17 -0
- package/dist/work-comment-cmd-BNCSBTLH.js +106 -0
- package/dist/{work-launch-LT663PB3.js → work-launch-YI4CJDAP.js} +1 -1
- package/dist/work-open-pr-cmd-VFYZHIIW.js +156 -0
- package/dist/work-pr-cmd-PV32ZLSI.js +16 -0
- package/package.json +13 -3
- package/skill-pack/maintained/amend/SKILL.md +104 -0
- package/skill-pack/maintained/emitting-evidence/SKILL.md +108 -0
- package/skill-pack/maintained/emitting-evidence/references/agents-snippet.md +20 -0
- package/skill-pack/maintained/outerlayer/SKILL.md +55 -0
- package/skill-pack/maintained/reporting-findings/SKILL.md +148 -0
- package/skill-pack/template/build/SKILL.md +193 -0
- package/skill-pack/template/build/references/agent-briefs.md +243 -0
- package/skill-pack/template/build/references/criteria-judge.md +91 -0
- package/skill-pack/template/build/references/evidence.md +42 -0
- package/skill-pack/template/build/references/release.md +74 -0
- package/skill-pack/template/build/references/review-briefs.md +275 -0
- package/skill-pack/template/build/references/review-loop.md +158 -0
- package/skill-pack/template/build/scripts/record-criteria.mjs +235 -0
- package/skill-pack/template/spec/SKILL.md +84 -0
- package/skill-pack/template/writing-specs/SKILL.md +134 -0
- package/dist/chunk-DCNOXRMV.js +0 -589
- package/dist/chunk-JJP7YLMN.js +0 -25
- package/dist/chunk-OZ7C3XUE.js +0 -34
- package/dist/chunk-WQ6VGRGZ.js +0 -150
- package/dist/hook-fast-J5LCDHUJ.js +0 -8
- package/dist/import-capture-cmd-EUMBGIV3.js +0 -176
- package/dist/init-PTBITAUO.js +0 -103
- package/dist/login-cmd-IRX6LZT7.js +0 -62
- package/dist/loop-ASZRX3CZ.js +0 -648
- package/dist/sync-cmd-BBAUZ5JD.js +0 -17
- package/dist/work-cmd-2P4BVX47.js +0 -18
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import { existsSync, readFileSync } from 'fs';
|
|
4
|
+
import { dirname, join } from 'path';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
|
|
7
|
+
createRequire(import.meta.url);
|
|
8
|
+
var FALLBACK_VERSION = "0.1.0";
|
|
9
|
+
function readJson(path) {
|
|
10
|
+
if (!existsSync(path)) return null;
|
|
11
|
+
try {
|
|
12
|
+
return JSON.parse(readFileSync(path, "utf8"));
|
|
13
|
+
} catch {
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function resolveVersion(entryPath = fileURLToPath(import.meta.url)) {
|
|
18
|
+
const distDir = dirname(entryPath);
|
|
19
|
+
const pkg = readJson(join(dirname(distDir), "package.json"));
|
|
20
|
+
const version = typeof pkg?.version === "string" ? pkg.version : FALLBACK_VERSION;
|
|
21
|
+
const buildInfo = readJson(join(distDir, "build-info.json"));
|
|
22
|
+
const buildId = typeof buildInfo?.id === "string" ? buildInfo.id : null;
|
|
23
|
+
return buildId ? `${version} (build ${buildId})` : version;
|
|
24
|
+
}
|
|
25
|
+
function resolvePackageVersion(entryPath = fileURLToPath(import.meta.url)) {
|
|
26
|
+
const pkg = readJson(join(dirname(dirname(entryPath)), "package.json"));
|
|
27
|
+
return typeof pkg?.version === "string" ? pkg.version : FALLBACK_VERSION;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export { resolvePackageVersion, resolveVersion };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import { isPlaceholderCommand } from './chunk-YFHIIH4B.js';
|
|
4
|
+
import { describeCallFailure } from './chunk-HZRNMGLF.js';
|
|
5
|
+
import { WorkCommandError, getJson } from './chunk-W5FVUZXV.js';
|
|
6
|
+
import { sanitizeTerminal } from './chunk-WFJ65NUD.js';
|
|
7
|
+
import { builtinKind } from './chunk-5Y3QQRUH.js';
|
|
8
|
+
import { claudeCredential, CLAUDE_CREDENTIAL_VARIABLES } from './chunk-AUFG23AA.js';
|
|
9
|
+
import { signerFor } from './chunk-M5POMKKW.js';
|
|
10
|
+
|
|
11
|
+
createRequire(import.meta.url);
|
|
12
|
+
|
|
13
|
+
// src/runner/host-setup.ts
|
|
14
|
+
function placeholderQueues(config) {
|
|
15
|
+
return config.queues.filter((queue) => {
|
|
16
|
+
const command = config.commands[queue];
|
|
17
|
+
return command !== void 0 && isPlaceholderCommand(command);
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
function placeholderProblem(queues) {
|
|
21
|
+
const keys = queues.map((queue) => `runner.commands.${queue}`).join(", ");
|
|
22
|
+
return `${keys} ${queues.length === 1 ? "is" : "are"} still the placeholder \`runner init\` wrote, which fails every item. Edit ${queues.length === 1 ? "it" : "them"} to start your agent on item $OUTERLAYER_WORK`;
|
|
23
|
+
}
|
|
24
|
+
function needsClaudeCredential(hooks) {
|
|
25
|
+
return builtinKind(hooks.provision) !== "own";
|
|
26
|
+
}
|
|
27
|
+
var CREDENTIAL_FIX = "Run `claude setup-token`, then start the runner with CLAUDE_CODE_OAUTH_TOKEN set to the token it prints (or ANTHROPIC_API_KEY set to an API key), for example with EnvironmentFile= in the runner's systemd unit";
|
|
28
|
+
function claudeCredentialCheck(env, options = {}) {
|
|
29
|
+
const name = "Claude credential";
|
|
30
|
+
const held = claudeCredential(env);
|
|
31
|
+
if (held === void 0) {
|
|
32
|
+
return {
|
|
33
|
+
name,
|
|
34
|
+
status: "fail",
|
|
35
|
+
detail: `neither ${CLAUDE_CREDENTIAL_VARIABLES.slice(0, 2).join(" nor ")} is set, so every build fails at provision as agent_credential_missing`,
|
|
36
|
+
fix: `${CREDENTIAL_FIX}.`
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
const sameVariables = options.shell === true ? "; the runner must be started with the same variable" : "";
|
|
40
|
+
return { name, status: "pass", detail: `${held.variable} is set${sameVariables}` };
|
|
41
|
+
}
|
|
42
|
+
function missingPermissionOf(err) {
|
|
43
|
+
if (!(err instanceof WorkCommandError) || err.status !== 403) return void 0;
|
|
44
|
+
const permission = /missing required permission '([^']+)'/i.exec(err.message)?.[1];
|
|
45
|
+
return permission === void 0 ? void 0 : sanitizeTerminal(permission);
|
|
46
|
+
}
|
|
47
|
+
function missingPermissionFix(permission) {
|
|
48
|
+
return `use a key that holds ${permission}: create one with the Runner preset on the factory's API keys page, then run \`outerlayer login\` with it`;
|
|
49
|
+
}
|
|
50
|
+
async function claimPermissionProblem(config, fetchImpl = fetch) {
|
|
51
|
+
const unverified = (what, err) => ({
|
|
52
|
+
status: "unverified",
|
|
53
|
+
reason: sanitizeTerminal(`${what}: ${err instanceof Error ? describeCallFailure(err) : String(err)}`)
|
|
54
|
+
});
|
|
55
|
+
let signer;
|
|
56
|
+
try {
|
|
57
|
+
signer = await signerFor(config.configPath);
|
|
58
|
+
} catch (err) {
|
|
59
|
+
return unverified("this host's key could not be read, so whether the runner key can claim work was not checked", err);
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
await getJson(config.url, "/v1/runner/host-key", config.apiKey, config.appId, fetchImpl, signer);
|
|
63
|
+
return { status: "ok" };
|
|
64
|
+
} catch (err) {
|
|
65
|
+
const permission = missingPermissionOf(err);
|
|
66
|
+
if (permission === void 0) return unverified("the host-key call did not say whether the runner key can claim work", err);
|
|
67
|
+
return { status: "lacks", problem: `the runner key lacks ${permission}, which a runner needs to claim work: ${missingPermissionFix(permission)}` };
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export { claimPermissionProblem, claudeCredentialCheck, missingPermissionFix, missingPermissionOf, needsClaudeCredential, placeholderProblem, placeholderQueues };
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import { sanitizeTerminal } from './chunk-WFJ65NUD.js';
|
|
4
|
+
import { DEFAULT_DASHBOARD } from './chunk-USO2DKBD.js';
|
|
5
|
+
import { readCloudConfig } from './chunk-EABW6AJQ.js';
|
|
6
|
+
|
|
7
|
+
createRequire(import.meta.url);
|
|
8
|
+
|
|
9
|
+
// src/repository-link.ts
|
|
10
|
+
var LINKS_TIMEOUT_MS = 15e3;
|
|
11
|
+
var GITHUB_PREFIX = "github.com/";
|
|
12
|
+
function isLinkedRepository(local, linked) {
|
|
13
|
+
if (linked.provider !== "github" || typeof linked.repository !== "string") return false;
|
|
14
|
+
return local.toLowerCase() === `${GITHUB_PREFIX}${linked.repository.toLowerCase()}`;
|
|
15
|
+
}
|
|
16
|
+
function ownerAndName(repository) {
|
|
17
|
+
return repository.toLowerCase().startsWith(GITHUB_PREFIX) ? repository.slice(GITHUB_PREFIX.length) : repository;
|
|
18
|
+
}
|
|
19
|
+
async function isRepositoryLinked(fetchImpl, gatewayUrl, token, appId, repository) {
|
|
20
|
+
if (!repository.toLowerCase().startsWith(GITHUB_PREFIX)) return null;
|
|
21
|
+
let res;
|
|
22
|
+
try {
|
|
23
|
+
res = await fetchImpl(`${gatewayUrl.replace(/\/+$/, "")}/v1/apps/${encodeURIComponent(appId)}/git/links`, {
|
|
24
|
+
method: "GET",
|
|
25
|
+
headers: { authorization: `Bearer ${token}`, "x-outerlayer-app-id": appId },
|
|
26
|
+
signal: AbortSignal.timeout(LINKS_TIMEOUT_MS)
|
|
27
|
+
});
|
|
28
|
+
} catch {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
if (!res.ok) return null;
|
|
32
|
+
const listed = (await res.json().catch(() => void 0))?.data;
|
|
33
|
+
if (!Array.isArray(listed)) return null;
|
|
34
|
+
return listed.some((entry) => isLinkedRepository(repository, entry ?? {}));
|
|
35
|
+
}
|
|
36
|
+
function dashboardBase(home) {
|
|
37
|
+
const saved = readCloudConfig(home).dashboard;
|
|
38
|
+
const base = typeof saved === "string" && saved.trim() !== "" ? saved : DEFAULT_DASHBOARD;
|
|
39
|
+
return base.replace(/\/+$/, "");
|
|
40
|
+
}
|
|
41
|
+
function workPageUrl(home, organization, factory) {
|
|
42
|
+
return `${dashboardBase(home)}/orgs/${encodeURIComponent(organization)}/factories/${encodeURIComponent(factory)}/work`;
|
|
43
|
+
}
|
|
44
|
+
function notLinkedText(factoryName, repository, url) {
|
|
45
|
+
const shown = sanitizeTerminal(repository);
|
|
46
|
+
const name = sanitizeTerminal(ownerAndName(repository));
|
|
47
|
+
return `${factoryName} has no link to ${shown} yet, so work from this repository cannot reach it.
|
|
48
|
+
Link it on the factory's Work page: ${url}
|
|
49
|
+
1. Connect GitHub repository, and grant the App access to ${name}.
|
|
50
|
+
2. Link repository, and pick ${name} and its default branch.
|
|
51
|
+
Then run \`outerlayer connect\` again.
|
|
52
|
+
`;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export { dashboardBase, isLinkedRepository, isRepositoryLinked, notLinkedText, workPageUrl };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
|
|
4
|
+
createRequire(import.meta.url);
|
|
5
|
+
|
|
6
|
+
// src/repo-filter.ts
|
|
7
|
+
function toMatcher(pattern) {
|
|
8
|
+
const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
|
|
9
|
+
return new RegExp(`^${escaped}$`, "i");
|
|
10
|
+
}
|
|
11
|
+
var RepoFilter = class {
|
|
12
|
+
constructor(config) {
|
|
13
|
+
/** Sessions dropped, keyed by repo (or "(no repo)") — for the sync summary. */
|
|
14
|
+
this.skipped = /* @__PURE__ */ new Map();
|
|
15
|
+
this.include = (config?.include ?? []).map(toMatcher);
|
|
16
|
+
this.exclude = (config?.exclude ?? []).map(toMatcher);
|
|
17
|
+
}
|
|
18
|
+
get active() {
|
|
19
|
+
return this.include.length > 0 || this.exclude.length > 0;
|
|
20
|
+
}
|
|
21
|
+
/** True when the session should sync. Records skips for reporting. */
|
|
22
|
+
allows(repo) {
|
|
23
|
+
const label = repo || "(no repo)";
|
|
24
|
+
if (repo && this.exclude.some((m) => m.test(repo))) {
|
|
25
|
+
this.skipped.set(label, (this.skipped.get(label) ?? 0) + 1);
|
|
26
|
+
return false;
|
|
27
|
+
}
|
|
28
|
+
if (this.include.length > 0 && !(repo && this.include.some((m) => m.test(repo)))) {
|
|
29
|
+
this.skipped.set(label, (this.skipped.get(label) ?? 0) + 1);
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
get skippedTotal() {
|
|
35
|
+
let n = 0;
|
|
36
|
+
for (const c of this.skipped.values()) n += c;
|
|
37
|
+
return n;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export { RepoFilter };
|