@outerlayer/cli 0.16.1 → 0.17.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.
Files changed (65) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +11 -11
  3. package/dist/{agent-setup-K3ABU5NL.js → agent-setup-T624CWPD.js} +2 -2
  4. package/dist/artifact-link-cmd-2F47LT7F.js +24 -0
  5. package/dist/build-info.json +1 -1
  6. package/dist/{check-CNTMSGOG.js → check-5XE7XMC4.js} +14 -14
  7. package/dist/{chunk-YDSMROTB.js → chunk-3NSNIIBE.js} +8 -4
  8. package/dist/{chunk-NPQWKGUA.js → chunk-6Y5RUTHO.js} +1 -1
  9. package/dist/{chunk-6JNURGOA.js → chunk-BWQ66M6N.js} +1 -1
  10. package/dist/{chunk-R4ZQQ7U2.js → chunk-G5NPRL2K.js} +7 -8
  11. package/dist/{chunk-W3EKCZSQ.js → chunk-HGECYFEI.js} +55 -5
  12. package/dist/{chunk-5FEK6PNE.js → chunk-KG5ECZGJ.js} +1 -1
  13. package/dist/{chunk-FWX735W7.js → chunk-LWSJQJC6.js} +3 -3
  14. package/dist/{chunk-EWORLJMO.js → chunk-MAK5LYRF.js} +16 -7
  15. package/dist/{chunk-ONRCEE6D.js → chunk-NNRTPG7X.js} +2 -2
  16. package/dist/{chunk-U3HXXRTY.js → chunk-NWQTTSBB.js} +1 -1
  17. package/dist/{chunk-RSPXEVDX.js → chunk-ONKJUM6R.js} +1 -1
  18. package/dist/{chunk-6QRMLNH3.js → chunk-S3NYLI2P.js} +3 -3
  19. package/dist/{chunk-CA3XMYFN.js → chunk-VQYBXPI7.js} +3 -3
  20. package/dist/{chunk-EHAAPRWY.js → chunk-WVUIRTWA.js} +7 -7
  21. package/dist/{chunk-JJEGKEFV.js → chunk-YU3VKZ5F.js} +1 -1
  22. package/dist/{chunk-JEHRUE3F.js → chunk-YZ5F4PIS.js} +91 -20
  23. package/dist/{cli-AEWH62UE.js → cli-A76AXELQ.js} +71 -63
  24. package/dist/{command-HHPBR6CS.js → command-R2QCVX55.js} +6 -6
  25. package/dist/{connect-cmd-JUAW6MU4.js → connect-cmd-JBKAQNSF.js} +1 -1
  26. package/dist/{context-adopt-VMMGFRUZ.js → context-adopt-NFHCLVUB.js} +1 -1
  27. package/dist/{context-materialize-2WXTS4CW.js → context-materialize-IV2TUUFO.js} +1 -1
  28. package/dist/{doctor-N6Y7HKK3.js → doctor-4TAIARIG.js} +10 -9
  29. package/dist/{emit-artifact-cmd-H5MH3AOP.js → emit-artifact-cmd-MPZVR56N.js} +4 -4
  30. package/dist/{emit-criteria-cmd-HBP6XS5C.js → emit-criteria-cmd-EFGYI23V.js} +2 -2
  31. package/dist/{emit-finding-cmd-ZXDRL6PG.js → emit-finding-cmd-5GF3V4LR.js} +2 -2
  32. package/dist/{emit-result-cmd-RFKALS5Z.js → emit-result-cmd-I4OADKMD.js} +4 -4
  33. package/dist/hidden-prompt-UXBFMQC5.js +68 -0
  34. package/dist/{hook-fast-D7HV4IXG.js → hook-fast-R4FVSZ2H.js} +1 -1
  35. package/dist/index.js +3 -3
  36. package/dist/{init-MYX7YMIH.js → init-6XPDRDTC.js} +7 -7
  37. package/dist/{init-FBCA4DRA.js → init-PWU5YVL7.js} +49 -25
  38. package/dist/{init-cmd-CAG572UE.js → init-cmd-XAVO7HYZ.js} +5 -5
  39. package/dist/{init-update-VDFF4K3B.js → init-update-CVCWD6VS.js} +3 -3
  40. package/dist/{loop-75J4YXLZ.js → loop-FK3LPMMZ.js} +14 -14
  41. package/dist/{machine-A6ZCTUGS.js → machine-SQXEBAM2.js} +6 -6
  42. package/dist/runner-key-6SLBI7PP.js +174 -0
  43. package/dist/{session-sender-24L5EW25.js → session-sender-FO3LCREV.js} +3 -3
  44. package/dist/{status-XHSGEYO5.js → status-7VNQN5PW.js} +9 -9
  45. package/dist/{sync-cmd-5G5EIEHD.js → sync-cmd-GVPPFZ3G.js} +2 -2
  46. package/dist/{watch-UTOXO4SE.js → watch-23HSAEI6.js} +2 -2
  47. package/dist/{work-claim-cmd-RKHYFE5Y.js → work-claim-cmd-LKL3GHFQ.js} +5 -5
  48. package/dist/{work-cmd-DJQJEZVB.js → work-cmd-Z2WXLZPH.js} +3 -3
  49. package/dist/{work-comment-cmd-A55CUSYE.js → work-comment-cmd-AWHP56M2.js} +3 -3
  50. package/dist/{work-open-pr-cmd-E6O53IJD.js → work-open-pr-cmd-IOM4AVQQ.js} +4 -4
  51. package/dist/{work-pr-cmd-L77K32WK.js → work-pr-cmd-HNEUIEN7.js} +3 -3
  52. package/package.json +1 -1
  53. package/skill-pack/maintained/outerlayer-amend/SKILL.md +2 -0
  54. package/skill-pack/maintained/outerlayer-cli/SKILL.md +2 -0
  55. package/skill-pack/maintained/outerlayer-evidence/SKILL.md +4 -2
  56. package/skill-pack/maintained/outerlayer-findings/SKILL.md +2 -0
  57. package/skill-pack/shipped.json +10 -3
  58. package/skill-pack/template/build/SKILL.md +2 -0
  59. package/skill-pack/template/build/references/release.md +13 -11
  60. package/skill-pack/template/build/scripts/criterion-citations.mjs +8 -3
  61. package/skill-pack/template/build/scripts/record-criteria.mjs +8 -2
  62. package/skill-pack/template/spec/SKILL.md +2 -0
  63. package/skill-pack/validators/acceptance-criteria.yaml +6 -5
  64. package/skill-pack/validators/code-review.yaml +6 -5
  65. package/dist/runner-key-W25ISHI3.js +0 -155
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { autoConnect } from './chunk-NPQWKGUA.js';
3
+ import { autoConnect } from './chunk-6Y5RUTHO.js';
4
4
  import { detectActiveSession } from './chunk-IP7BIBXJ.js';
5
5
  import { resolveRepoIdentity } from './chunk-JXYVA45C.js';
6
6
  import { C } from './chunk-YRYMNBGQ.js';
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire } from 'node:module';
3
- import { readPin, pinExists, readBuildHold, readContextManifest, manifestFilesPresent, writeDegraded, writeSourceCache, SOURCE_CACHE_TTL_RETRY_MS, SOURCE_CACHE_TTL_SUCCESS_MS, isLastCheckFresh, readDegraded, touchLastCheck, clearDegraded, writeContextManifest, writePinIfChanged, readSourceCache, isSourceCacheFresh } from './chunk-WTE3MQML.js';
3
+ import { readPin, pinExists, readBuildHold, readContextManifest, manifestFilesPresent, writeDegraded, writeSourceCache, SOURCE_CACHE_TTL_RETRY_MS, SOURCE_CACHE_TTL_SUCCESS_MS, touchLastCheck, isLastCheckFresh, readDegraded, clearDegraded, writeContextManifest, writePinIfChanged, readSourceCache, isSourceCacheFresh } from './chunk-WTE3MQML.js';
4
4
  import { removeRetiredSkills } from './chunk-C5Y5ZJJZ.js';
5
5
  import { appendContextProvenance } from './chunk-ZJSNLVCE.js';
6
6
  import { defaultFetch } from './chunk-YO4PSLVB.js';
@@ -209,6 +209,7 @@ async function materializeContext(deps) {
209
209
  let repository;
210
210
  let ref;
211
211
  let unverifiedIdentity;
212
+ let storedSha;
212
213
  let preFetched;
213
214
  let unreadableCandidates = [];
214
215
  if (designation.status === "candidates") {
@@ -273,9 +274,10 @@ async function materializeContext(deps) {
273
274
  repository = designation.repository;
274
275
  ref = designation.ref;
275
276
  unverifiedIdentity = designation.unverifiedIdentity;
277
+ storedSha = designation.sha;
276
278
  }
277
279
  const manifest = readContextManifest(gitCommonDir);
278
- const evidenced = hasGovernedEvidence(hasPin, manifest);
280
+ const evidenced = hasGovernedEvidence(hasPin, manifest) || storedSha !== void 0 && !unverifiedIdentity;
279
281
  const clearOrFlagIdentity = () => {
280
282
  if (unverifiedIdentity) {
281
283
  writeDegraded(gitCommonDir, {
@@ -295,7 +297,30 @@ async function materializeContext(deps) {
295
297
  sha = preFetched.sha;
296
298
  cacheRepoDir = preFetched.cacheRepoDir;
297
299
  } else {
298
- if (isLastCheckFresh(gitCommonDir, now()) && manifest !== void 0 && pin?.sha === manifest.sha && manifestFilesPresent(repoRoot, manifest)) {
300
+ if (storedSha !== void 0 && manifest !== void 0 && manifest.sha === storedSha && pin?.sha === storedSha && manifestFilesPresent(repoRoot, manifest)) {
301
+ touchLastCheck(gitCommonDir, now());
302
+ clearOrFlagIdentity();
303
+ ensureContextExcludes(gitCommonDir);
304
+ recordMaintainedOverlay(repoRoot, gitCommonDir, manifest);
305
+ const guardMessage2 = guardNotInstalledMessage(ensurePreCommitGuardHook(repoRoot, gitCommonDir));
306
+ writeSourceCache(gitCommonDir, {
307
+ checkedAt: new Date(now()).toISOString(),
308
+ status: "governed",
309
+ repository,
310
+ ref,
311
+ sha: storedSha,
312
+ ttlMs: SOURCE_CACHE_TTL_SUCCESS_MS
313
+ });
314
+ const verification = unverifiedIdentity ? "unverified" : "verified";
315
+ record(storedSha, verification, repository, ref);
316
+ return {
317
+ status: "debounced",
318
+ sha: storedSha,
319
+ verification,
320
+ ...guardMessage2 ? { message: guardMessage2 } : {}
321
+ };
322
+ }
323
+ if (storedSha === void 0 && isLastCheckFresh(gitCommonDir, now()) && manifest !== void 0 && pin?.sha === manifest.sha && manifestFilesPresent(repoRoot, manifest)) {
299
324
  const degraded = readDegraded(gitCommonDir);
300
325
  const verification = degraded ? "unverified" : "verified";
301
326
  ensureContextExcludes(gitCommonDir);
@@ -321,8 +346,8 @@ async function materializeContext(deps) {
321
346
  }
322
347
  const remoteUrl = deps.resolveControlPlaneUrl ? deps.resolveControlPlaneUrl(repository, ref, repoRoot) : buildControlPlaneUrl(git, repoRoot, repository);
323
348
  const cacheHost = parseRemoteHost(remoteUrl).host || "unknown-host";
324
- const lsRemote = git(["ls-remote", remoteUrl, ref], { cwd: repoRoot, timeoutMs: 2e3 });
325
- if (lsRemote.ok) {
349
+ const lsRemote = storedSha === void 0 ? git(["ls-remote", remoteUrl, ref], { cwd: repoRoot, timeoutMs: 2e3 }) : void 0;
350
+ if (lsRemote?.ok) {
326
351
  const remoteSha = parseLsRemoteSha(lsRemote.stdout.toString("utf8"));
327
352
  if (remoteSha && manifest !== void 0 && manifest.sha === remoteSha && pin?.sha === remoteSha && manifestFilesPresent(repoRoot, manifest)) {
328
353
  touchLastCheck(gitCommonDir, now());
@@ -341,13 +366,21 @@ async function materializeContext(deps) {
341
366
  }
342
367
  }
343
368
  cacheRepoDir = ensureBareCache(git, home, repository, cacheHost);
344
- const localRef = `refs/outerlayer/${sanitizeRefName(ref)}`;
345
- const fetchResult = git(["fetch", "--depth", "1", remoteUrl, `+${ref}:${localRef}`], { cwd: cacheRepoDir, timeoutMs: 1e4 });
369
+ const localRef = storedSha === void 0 ? `refs/outerlayer/${sanitizeRefName(ref)}` : `refs/outerlayer/sha-${sanitizeRefName(storedSha)}`;
370
+ const wanted = storedSha === void 0 ? `+${ref}:${localRef}` : `+${storedSha}:${localRef}`;
371
+ const access = storedSha === void 0 ? void 0 : await deps.controlPlaneAccess?.([{ repository, ref }]);
372
+ const token = access !== void 0 && normalizeRepoName(access.repository) === normalizeRepoName(repository) ? access.token : void 0;
373
+ const fetchResult = git(["fetch", "--depth", "1", remoteUrl, wanted], {
374
+ cwd: cacheRepoDir,
375
+ timeoutMs: 1e4,
376
+ ...token === void 0 ? {} : { env: (base) => withTokenHeader(base, remoteUrl, token) }
377
+ });
378
+ const commitNote = (message) => storedSha === void 0 ? message : `could not fetch commit \`${storedSha.slice(0, 7)}\` of ${repository}; ${message}`;
346
379
  if (!fetchResult.ok) {
347
380
  const kind = classifyGitFailure(fetchResult.stderr);
348
381
  const lastGood = manifest?.sha ?? null;
349
382
  const verification = lastGood ? "unverified" : "none";
350
- const doctorMessage = kind === "no-access" ? noAccessMessage(lastGood) : unreachableMessage(lastGood);
383
+ const doctorMessage = commitNote(kind === "no-access" ? noAccessMessage(lastGood) : unreachableMessage(lastGood));
351
384
  writeDegraded(gitCommonDir, { at: new Date(now()).toISOString(), kind, message: doctorMessage, repository, ref, lastGoodSha: lastGood ?? void 0 });
352
385
  if (evidenced) {
353
386
  record(lastGood, verification, repository, ref);
@@ -356,10 +389,10 @@ async function materializeContext(deps) {
356
389
  return { status: kind, sha: null, verification: "none" };
357
390
  }
358
391
  const fetchedSha = gitText(git, cacheRepoDir, ["rev-parse", localRef], 2e3);
359
- if (fetchedSha === void 0) {
392
+ if (fetchedSha === void 0 || storedSha !== void 0 && fetchedSha !== storedSha) {
360
393
  const lastGood = manifest?.sha ?? null;
361
394
  const verification = lastGood ? "unverified" : "none";
362
- const doctorMessage = unreachableMessage(lastGood);
395
+ const doctorMessage = commitNote(unreachableMessage(lastGood));
363
396
  writeDegraded(gitCommonDir, { at: new Date(now()).toISOString(), kind: "unreachable", message: doctorMessage, repository, ref, lastGoodSha: lastGood ?? void 0 });
364
397
  if (evidenced) {
365
398
  record(lastGood, verification, repository, ref);
@@ -368,10 +401,12 @@ async function materializeContext(deps) {
368
401
  return { status: "unreachable", sha: null, verification: "none" };
369
402
  }
370
403
  sha = fetchedSha;
371
- const configContent = readBlobAtPath(git, cacheRepoDir, sha, CONTEXT_SOURCE_CONFIG_PATH);
372
- const parsedGoverns = configContent === void 0 ? { governs: [] } : parseGoverns(configContent);
373
- const governsList = "error" in parsedGoverns ? [] : parsedGoverns.governs;
374
- const governed = governsList.some((r) => normalizeRepoName(r) === normalizeRepoName(ownRepoName));
404
+ const governed = storedSha !== void 0 || (() => {
405
+ const configContent = readBlobAtPath(git, cacheRepoDir, sha, CONTEXT_SOURCE_CONFIG_PATH);
406
+ const parsedGoverns = configContent === void 0 ? { governs: [] } : parseGoverns(configContent);
407
+ const governsList = "error" in parsedGoverns ? [] : parsedGoverns.governs;
408
+ return governsList.some((r) => normalizeRepoName(r) === normalizeRepoName(ownRepoName));
409
+ })();
375
410
  if (!governed) {
376
411
  writeSourceCache(gitCommonDir, { checkedAt: new Date(now()).toISOString(), status: "self", ttlMs: SOURCE_CACHE_TTL_SUCCESS_MS });
377
412
  if (hasPin) {
@@ -449,7 +484,14 @@ async function materializeContext(deps) {
449
484
  writePinIfChanged(repoRoot, sha);
450
485
  touchLastCheck(gitCommonDir, now());
451
486
  clearOrFlagIdentity();
452
- writeSourceCache(gitCommonDir, { checkedAt: new Date(now()).toISOString(), status: "governed", repository, ref, ttlMs: SOURCE_CACHE_TTL_SUCCESS_MS });
487
+ writeSourceCache(gitCommonDir, {
488
+ checkedAt: new Date(now()).toISOString(),
489
+ status: "governed",
490
+ repository,
491
+ ref,
492
+ ...storedSha === void 0 ? {} : { sha: storedSha },
493
+ ttlMs: SOURCE_CACHE_TTL_SUCCESS_MS
494
+ });
453
495
  record(sha, "verified", repository, ref);
454
496
  return {
455
497
  status: "materialized",
@@ -476,7 +518,7 @@ function recordMaintainedOverlay(repoRoot, gitCommonDir, manifest) {
476
518
  }
477
519
  async function resolveDesignation(ctx) {
478
520
  const cache = readSourceCache(ctx.gitCommonDir);
479
- if (cache && isSourceCacheFresh(cache, ctx.now())) {
521
+ if (cache && isSourceCacheFresh(cache, ctx.now()) && !(cache.status === "governed" && cache.sha !== void 0)) {
480
522
  return cache.status === "governed" && cache.repository && cache.ref ? { status: "governed", repository: cache.repository, ref: cache.ref } : { status: "self" };
481
523
  }
482
524
  let authRejected;
@@ -497,7 +539,18 @@ async function resolveDesignation(ctx) {
497
539
  if (lookup.kind === "rejected") authRejected = designationAuthRejectedMessage(destination.credential);
498
540
  if (lookup.kind === "failed") lookupFailure = lookup.failure;
499
541
  if (lookup.kind === "answered") {
500
- const sources = lookup.sources;
542
+ if (lookup.source !== void 0) {
543
+ if (lookup.source === null) {
544
+ writeSourceCache(ctx.gitCommonDir, {
545
+ checkedAt: new Date(ctx.now()).toISOString(),
546
+ status: "self",
547
+ ttlMs: SOURCE_CACHE_TTL_SUCCESS_MS
548
+ });
549
+ return { status: "self" };
550
+ }
551
+ return { status: "governed", repository: lookup.source.repository, ref: lookup.source.ref, sha: lookup.source.sha };
552
+ }
553
+ const sources = lookup.sources ?? [];
501
554
  if (sources.length === 0) {
502
555
  writeSourceCache(ctx.gitCommonDir, {
503
556
  checkedAt: new Date(ctx.now()).toISOString(),
@@ -510,7 +563,13 @@ async function resolveDesignation(ctx) {
510
563
  }
511
564
  }
512
565
  if (cache) {
513
- return cache.status === "governed" && cache.repository && cache.ref ? { status: "governed", repository: cache.repository, ref: cache.ref, unverifiedIdentity: true } : { status: "self" };
566
+ return cache.status === "governed" && cache.repository && cache.ref ? {
567
+ status: "governed",
568
+ repository: cache.repository,
569
+ ref: cache.ref,
570
+ unverifiedIdentity: true,
571
+ ...cache.sha === void 0 ? {} : { sha: cache.sha }
572
+ } : { status: "self" };
514
573
  }
515
574
  return { status: "unknown", authRejected, lookupFailure };
516
575
  }
@@ -541,8 +600,12 @@ async function askContextSource(url, config, fetchImpl, timeoutMs) {
541
600
  }
542
601
  if (!res.ok) return { kind: "failed", failure: { kind: "status", status: res.status } };
543
602
  const body = await res.json();
544
- if (body.data?.sources === void 0) return { kind: "failed", failure: { kind: "network", message: "the answer named no sources" } };
545
- return { kind: "answered", sources: body.data.sources };
603
+ const data = body.data;
604
+ const source = validSource(data?.source);
605
+ if (data === void 0 || data === null || source === void 0 && !Array.isArray(data.sources)) {
606
+ return { kind: "failed", failure: { kind: "network", message: "the answer named no sources" } };
607
+ }
608
+ return { kind: "answered", source, sources: data.sources };
546
609
  } catch (err) {
547
610
  return {
548
611
  kind: "failed",
@@ -552,6 +615,14 @@ async function askContextSource(url, config, fetchImpl, timeoutMs) {
552
615
  clearTimeout(timer);
553
616
  }
554
617
  }
618
+ function validSource(source) {
619
+ if (source === null) return null;
620
+ const candidate = source;
621
+ if (typeof candidate?.repository === "string" && typeof candidate.ref === "string" && typeof candidate.sha === "string") {
622
+ return { repository: candidate.repository, ref: candidate.ref, sha: candidate.sha };
623
+ }
624
+ return void 0;
625
+ }
555
626
  function resolveGitCommonDir(git, repoRoot) {
556
627
  const abs = gitText(git, repoRoot, ["rev-parse", "--path-format=absolute", "--git-common-dir"], 2e3);
557
628
  if (abs !== void 0) return abs;